diff --git a/include/daw/daw_attributes.h b/include/daw/daw_attributes.h index e995596c9..723fbac8d 100644 --- a/include/daw/daw_attributes.h +++ b/include/daw/daw_attributes.h @@ -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 ) @@ -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 \ No newline at end of file diff --git a/include/daw/daw_ensure.h b/include/daw/daw_ensure.h index bd5340769..420c9646f 100644 --- a/include/daw/daw_ensure.h +++ b/include/daw/daw_ensure.h @@ -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 ) @@ -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( __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( __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 diff --git a/include/daw/daw_likely.h b/include/daw/daw_likely.h index 51a49ccd8..c2d72e101 100644 --- a/include/daw/daw_likely.h +++ b/include/daw/daw_likely.h @@ -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 ) diff --git a/include/daw/daw_string_view.h b/include/daw/daw_string_view.h index 1a12a5adf..46cd3abe3 100644 --- a/include/daw/daw_string_view.h +++ b/include/daw/daw_string_view.h @@ -56,12 +56,13 @@ #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, ... ) \ @@ -69,13 +70,14 @@ } while( false ) #endif -#if not defined( NDEBUG ) or defined( DEBUG ) -#define DAW_STRING_VIEW_DBG_ZERO_CHECK( ) \ - if( DAW_UNLIKELY( *( f + static_cast( 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( l ) ) != \ + CharT{ } ) ) { \ + DAW_THROW_OR_TERMINATE_NA( std::exception ); \ + } \ } while( false ) #else #define DAW_STRING_VIEW_DBG_ZERO_CHECK( ) \ @@ -83,19 +85,20 @@ } 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, ... ) \ @@ -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 @@ -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; } @@ -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 @@ -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 ); } diff --git a/tests/daw_ensure_test.cpp b/tests/daw_ensure_test.cpp index 798dedd62..3bef18b88 100644 --- a/tests/daw_ensure_test.cpp +++ b/tests/daw_ensure_test.cpp @@ -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 ); }