Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions include/daw/daw_attributes.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@
#ifdef __has_cpp_attribute
#define DAW_HAS_ATTRIBUTE( Attrib ) __has_cpp_attribute( Attrib )
#else
#define DAW_HAS_ATTRIBUTE( Attrib ) false
#define DAW_HAS_ATTRIBUTE( Attrib ) 0
#defien __has_cpp_attribute( Attrib ) 0
#endif

#ifndef __has_attribute
#define __has_attribute( Attrib ) 0
#endif

#if DAW_HAS_ATTRIBUTE( clang::lifetimebound )
Expand Down Expand Up @@ -148,6 +153,7 @@

#if defined( DAW_HAS_CLANG )
#if __has_attribute( enable_if )
#define DAW_ATTRIB_ENABLE_IF(...) __attribute__((enable_if(__VA_ARGS__)))
#define DAW_ATTRIB_ENABLE_IF( ... ) \
__attribute__( ( enable_if( __VA_ARGS__ ) ) )
#endif
#endif
104 changes: 38 additions & 66 deletions include/daw/daw_ensure.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,10 @@ namespace daw::ensure {
}
#endif

#if defined( DAW_HAS_GCC_LIKE )
#if __has_attribute( error )
[[gnu::error( "Ensure check failed at compile time" )]]
extern void ensure_compile_error( bool );
#endif

struct daw_ensure_exception {
std::string_view msg;
};
} // namespace daw::ensure

#if defined( DAW_HAS_IS_CONSTANT_EVALUATED )
Expand All @@ -55,80 +51,56 @@ namespace daw::ensure {
#define DAW_ENSURE_IS_CONSTANT_EVAL( ) false
#endif

#if not defined( DAW_NO_OPT_TIME_ENSURE ) and defined( DAW_HAS_GCC_LIKE )
#define daw_ensure( ... ) \
do { \
if( DAW_ENSURE_IS_CONSTANT_EVAL( ) ) { \
if( not( __VA_ARGS__ ) ) { \
throw ::daw::ensure::daw_ensure_exception{ "" #__VA_ARGS__ }; \
} \
} else { \
if( auto daw_ensure_bool_test = static_cast<bool>( __VA_ARGS__ ); \
__builtin_constant_p( daw_ensure_bool_test ) ) { \
if( not( daw_ensure_bool_test ) ) { \
::daw::ensure::ensure_compile_error( not( __VA_ARGS__ ) ); \
} \
} else { \
if( not( daw_ensure_bool_test ) ) { \
::daw::ensure::ensure_error( not( __VA_ARGS__ ) ); \
} \
} \
} \
} while( false )

#if not defined( NDEBUG )
#define daw_dbg_ensure( ... ) daw_ensure( __VA_ARGS__ )
#else
#define daw_dbg_ensure( ... ) \
#if not defined( DAW_NO_OPT_TIME_ENSURE ) and __has_attribute( error )
#define daw_ensure( ... ) \
do { \
if( DAW_ENSURE_IS_CONSTANT_EVAL( ) ) { \
if( not( __VA_ARGS__ ) ) { \
throw ::daw::ensure::daw_ensure_exception{ "" #__VA_ARGS__ }; \
if( auto daw_ensure_bool_test = static_cast<bool>( __VA_ARGS__ ); \
__builtin_constant_p( daw_ensure_bool_test ) ) { \
if( not( daw_ensure_bool_test ) ) { \
::daw::ensure::ensure_compile_error( not( __VA_ARGS__ ) ); \
} \
} else { \
if( __builtin_constant_p( __VA_ARGS__ ) ) { \
if( not( __VA_ARGS__ ) ) { \
::daw::ensure::ensure_compile_error( not( __VA_ARGS__ ) ); \
} \
if( not( daw_ensure_bool_test ) ) { \
::daw::ensure::ensure_error( not( __VA_ARGS__ ) ); \
} \
} \
} while( false )

#if not defined( NDEBUG )
#define daw_dbg_ensure( ... ) daw_ensure( __VA_ARGS__ )
#else
#define daw_dbg_ensure( ... ) \
do { \
if( __builtin_constant_p( __VA_ARGS__ ) ) { \
if( not( __VA_ARGS__ ) ) { \
::daw::ensure::ensure_compile_error( not( __VA_ARGS__ ) ); \
} \
} \
} while( false )
#endif
#else
#define daw_ensure( ... ) \
do { \
if( DAW_ENSURE_IS_CONSTANT_EVAL( ) ) { \
if( not( __VA_ARGS__ ) ) { \
throw ::daw::ensure::daw_ensure_exception{ "" #__VA_ARGS__ }; \
} \
} else { \
if( not( __VA_ARGS__ ) ) { \
::daw::ensure::ensure_error( not( __VA_ARGS__ ) ); \
} \
} \
#define daw_ensure( ... ) \
do { \
if( not( __VA_ARGS__ ) ) { \
::daw::ensure::ensure_error( not( __VA_ARGS__ ) ); \
} \
} while( false )

#if not defined( NDEBUG )
#define daw_dbg_ensure( ... ) \
do { \
if( DAW_ENSURE_IS_CONSTANT_EVAL( ) ) { \
if( not( __VA_ARGS__ ) ) { \
throw ::daw::ensure::daw_ensure_exception{ "" #__VA_ARGS__ }; \
} \
} else { \
if( not( __VA_ARGS__ ) ) { \
::daw::ensure::ensure_error( not( __VA_ARGS__ ) ); \
} \
} \
#define daw_dbg_ensure( ... ) \
do { \
if( not( __VA_ARGS__ ) ) { \
::daw::ensure::ensure_error( not( __VA_ARGS__ ) ); \
} \
} while( false )
#else
#define daw_dbg_ensure( ... ) \
do { \
if( DAW_ENSURE_IS_CONSTANT_EVAL( ) ) { \
if( not( __VA_ARGS__ ) ) { \
throw ::daw::ensure::daw_ensure_exception{ "" #__VA_ARGS__ }; \
} \
} \
#define daw_dbg_ensure( ... ) \
do { \
if( DAW_ENSURE_IS_CONSTANT_EVAL( ) ) { \
if( not( __VA_ARGS__ ) ) { \
::daw::ensure::ensure_error( not( __VA_ARGS__ ) ); \
} \
} \
} while( false )
#endif
#endif
6 changes: 3 additions & 3 deletions include/daw/daw_likely.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@

#include "daw_cpp_feature_check.h"

#if DAW_HAS_BUILTIN( __builtin_expect )
#if not defined( DAW_NO_LIKELY ) and DAW_HAS_BUILTIN( __builtin_expect )

#define DAW_LIKELY( ... ) ( __builtin_expect( !!( __VA_ARGS__ ), 1 ) )
#define DAW_UNLIKELY( ... ) ( __builtin_expect( !!( __VA_ARGS__ ), 0 ) )

#else

#define DAW_LIKELY( ... ) !!( __VA_ARGS__ )
#define DAW_UNLIKELY( ... ) !!( __VA_ARGS__ )
#define DAW_LIKELY( ... ) __VA_ARGS__
#define DAW_UNLIKELY( ... ) __VA_ARGS__

#endif
#if __has_cpp_attribute( likely )
Expand Down
69 changes: 37 additions & 32 deletions include/daw/daw_string_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,46 +56,49 @@
#define DAW_STRING_VIEW_DBG_RNG_CHECK( Bool, ... ) \
do { \
} while( false )
#elif not defined( NDEBUG ) or defined( DEBUG )
#define DAW_STRING_VIEW_DBG_RNG_CHECK( Bool, ... ) \
if( DAW_UNLIKELY( not( Bool ) ) ) { \
DAW_THROW_OR_TERMINATE( std::out_of_range, __VA_ARGS__ ); \
} \
do { \
#elif not defined( DAW_NO_SV_CHECKS ) and not defined( NDEBUG ) or \
defined( DEBUG )
#define DAW_STRING_VIEW_DBG_RNG_CHECK( Bool, ... ) \
do { \
if( DAW_UNLIKELY( not( Bool ) ) ) { \
DAW_THROW_OR_TERMINATE( std::out_of_range, __VA_ARGS__ ); \
} \
} while( false )
#else
#define DAW_STRING_VIEW_DBG_RNG_CHECK( Bool, ... ) \
do { \
} while( false )
#endif

#if not defined( NDEBUG ) or defined( DEBUG )
#define DAW_STRING_VIEW_DBG_ZERO_CHECK( ) \
if( DAW_UNLIKELY( *( f + static_cast<std::ptrdiff_t>( l ) ) != \
CharT{ } ) ) { \
DAW_THROW_OR_TERMINATE_NA( std::exception ); \
} \
do { \
#if not defined( DAW_NO_SV_CHECKS ) and not defined( NDEBUG ) or \
defined( DEBUG )
#define DAW_STRING_VIEW_DBG_ZERO_CHECK( ) \
do { \
if( DAW_UNLIKELY( *( f + static_cast<std::ptrdiff_t>( l ) ) != \
CharT{ } ) ) { \
DAW_THROW_OR_TERMINATE_NA( std::exception ); \
} \
} while( false )
#else
#define DAW_STRING_VIEW_DBG_ZERO_CHECK( ) \
do { \
} while( false )
#endif

#if not defined( DAW_NO_STRING_VIEW_PRECOND_CHECKS )
#if not defined( DAW_NO_SV_CHECKS ) and \
not defined( DAW_NO_STRING_VIEW_PRECOND_CHECKS )
#define DAW_STRING_VIEW_PRECOND_CHECK( Bool, ... ) \
if( DAW_UNLIKELY( not( Bool ) ) ) { \
std::terminate( ); \
} \
do { \
if( DAW_UNLIKELY( not( Bool ) ) ) { \
std::terminate( ); \
} \
} while( false )

#define DAW_STRING_VIEW_RNG_CHECK( Bool, ... ) \
if( DAW_UNLIKELY( not( Bool ) ) ) { \
DAW_THROW_OR_TERMINATE( std::out_of_range, __VA_ARGS__ ); \
} \
do { \
#define DAW_STRING_VIEW_RNG_CHECK( Bool, ... ) \
do { \
if( DAW_UNLIKELY( not( Bool ) ) ) { \
DAW_THROW_OR_TERMINATE( std::out_of_range, __VA_ARGS__ ); \
} \
} while( false )
#else
#define DAW_STRING_VIEW_PRECOND_CHECK( Bool, ... ) \
Expand All @@ -107,16 +110,16 @@
} while( false )
#endif

#if not defined( NDEBUG )
#if not defined( DAW_NO_SV_CHECKS ) and not defined( NDEBUG )
#define DAW_DBG_STRING_VIEW_PRECOND_CHECK( Bool, ... ) \
if( DAW_UNLIKELY( not( Bool ) ) ) { \
std::terminate( ); \
} \
do { \
do { \
if( DAW_UNLIKELY( not( Bool ) ) ) { \
std::terminate( ); \
} \
} while( false )
#else
#define DAW_DBG_STRING_VIEW_PRECOND_CHECK( Bool, ... ) \
do { \
do { \
} while( false )
#endif

Expand Down Expand Up @@ -687,8 +690,8 @@ namespace daw {
/// string_view
DAW_ATTRIB_INLINE constexpr basic_string_view( std::nullptr_t,
size_type n ) {
DAW_DBG_STRING_VIEW_PRECOND_CHECK( n == 0,
"nullptr can only form an empty range" );
DAW_DBG_STRING_VIEW_PRECOND_CHECK(
n == 0, "nullptr can only form an empty range" );
(void)n;
}

Expand All @@ -703,7 +706,8 @@ namespace daw {
const_pointer s DAW_LIFETIME_BOUND, size_type count ) noexcept
: m_first( s )
, m_last( count ) {
DAW_DBG_STRING_VIEW_PRECOND_CHECK( s != nullptr or count == 0, "When s is null, count must be zero" );
DAW_DBG_STRING_VIEW_PRECOND_CHECK(
s != nullptr or count == 0, "When s is null, count must be zero" );
}

/// @brief Construct a zero terminated string_view
Expand All @@ -718,7 +722,8 @@ namespace daw {
zero_terminated_t ) noexcept
: m_first( s )
, m_last( count ) {
DAW_DBG_PRECONDITION_CHECK( s != nullptr or count == 0, "[s, s+counbt) must be a valid range" );
DAW_DBG_PRECONDITION_CHECK( s != nullptr or count == 0,
"[s, s+counbt) must be a valid range" );
m_last = set_zero_terminated( m_first, m_last );
}

Expand Down
12 changes: 0 additions & 12 deletions tests/daw_ensure_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,6 @@ namespace {

static_assert( constant_evaluation_success( ) );

#if defined( __cpp_constexpr_exceptions ) and \
__cpp_constexpr_exceptions >= 202411L
constexpr bool constant_evaluation_failure( bool condition ) {
try {
daw_ensure( condition );
} catch( ... ) { return true; }
return false;
}

static_assert( constant_evaluation_failure( false ) );
#endif

DAW_ATTRIB_NOINLINE void runtime_check( bool condition ) {
daw_ensure( condition );
}
Expand Down
Loading