12 #ifndef NONSTD_SCOPE_LITE_HPP 13 #define NONSTD_SCOPE_LITE_HPP 15 #define scope_lite_MAJOR 0 16 #define scope_lite_MINOR 2 17 #define scope_lite_PATCH 0 19 #define scope_lite_VERSION scope_STRINGIFY(scope_lite_MAJOR) "." scope_STRINGIFY(scope_lite_MINOR) "." scope_STRINGIFY(scope_lite_PATCH) 21 #define scope_STRINGIFY( x ) scope_STRINGIFY_( x ) 22 #define scope_STRINGIFY_( x ) #x 26 #define scope_SCOPE_DEFAULT 0 27 #define scope_SCOPE_NONSTD 1 28 #define scope_SCOPE_STD 2 33 # if __has_include(<nonstd/scope.tweak.hpp>) 34 # include <nonstd/scope.tweak.hpp> 36 #define scope_HAVE_TWEAK_HEADER 1 38 #define scope_HAVE_TWEAK_HEADER 0 44 #if !defined( scope_CONFIG_SELECT_SCOPE ) 45 # define scope_CONFIG_SELECT_SCOPE ( scope_HAVE_STD_SCOPE ? scope_SCOPE_STD : scope_SCOPE_NONSTD ) 55 #ifndef scope_CPLUSPLUS 56 # if defined(_MSVC_LANG ) && !defined(__clang__) 57 # define scope_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG ) 59 # define scope_CPLUSPLUS __cplusplus 63 #define scope_CPP98_OR_GREATER ( scope_CPLUSPLUS >= 199711L ) 64 #define scope_CPP11_OR_GREATER ( scope_CPLUSPLUS >= 201103L ) 65 #define scope_CPP14_OR_GREATER ( scope_CPLUSPLUS >= 201402L ) 66 #define scope_CPP17_OR_GREATER ( scope_CPLUSPLUS >= 201703L ) 67 #define scope_CPP20_OR_GREATER ( scope_CPLUSPLUS >= 202000L ) 71 #if scope_CPP20_OR_GREATER && defined(__has_include ) 72 # if __has_include( <scope> ) 73 # define scope_HAVE_STD_SCOPE 1 75 # define scope_HAVE_STD_SCOPE 0 78 # define scope_HAVE_STD_SCOPE 0 81 #define scope_USES_STD_SCOPE ( (scope_CONFIG_SELECT_SCOPE == scope_SCOPE_STD) || ((scope_CONFIG_SELECT_SCOPE == scope_SCOPE_DEFAULT) && scope_HAVE_STD_SCOPE) ) 87 #if scope_USES_STD_SCOPE 93 using std::scope_exit;
94 using std::scope_fail;
95 using std::scope_success;
96 using std::unique_resource;
104 #else // scope_USES_STD_SCOPE 107 #define scope_BETWEEN( v, lo, hi ) ( (lo) <= (v) && (v) < (hi) ) 123 #if defined(_MSC_VER ) && !defined(__clang__) 124 # define scope_COMPILER_MSVC_VER (_MSC_VER ) 125 # define scope_COMPILER_MSVC_VERSION (_MSC_VER / 10 - 10 * ( 5 + (_MSC_VER < 1900 ) ) ) 127 # define scope_COMPILER_MSVC_VER 0 128 # define scope_COMPILER_MSVC_VERSION 0 151 #define scope_COMPILER_VERSION( major, minor, patch ) ( 10 * ( 10 * (major) + (minor) ) + (patch) ) 153 #if defined( __apple_build_version__ ) 154 # define scope_COMPILER_APPLECLANG_VERSION scope_COMPILER_VERSION( __clang_major__, __clang_minor__, __clang_patchlevel__ ) 155 # define scope_COMPILER_CLANG_VERSION 0 156 #elif defined( __clang__ ) 157 # define scope_COMPILER_APPLECLANG_VERSION 0 158 # define scope_COMPILER_CLANG_VERSION scope_COMPILER_VERSION( __clang_major__, __clang_minor__, __clang_patchlevel__ ) 160 # define scope_COMPILER_APPLECLANG_VERSION 0 161 # define scope_COMPILER_CLANG_VERSION 0 164 #if defined(__GNUC__) && !defined(__clang__) 165 # define scope_COMPILER_GNUC_VERSION scope_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) 167 # define scope_COMPILER_GNUC_VERSION 0 172 #define scope_HAVE( feature ) ( scope_HAVE_##feature ) 175 # define scope_HAS_CPP0X _HAS_CPP0X 177 # define scope_HAS_CPP0X 0 180 #define scope_CPP11_90 (scope_CPP11_OR_GREATER || scope_COMPILER_MSVC_VER >= 1500) 181 #define scope_CPP11_100 (scope_CPP11_OR_GREATER || scope_COMPILER_MSVC_VER >= 1600) 182 #define scope_CPP11_110 (scope_CPP11_OR_GREATER || scope_COMPILER_MSVC_VER >= 1700) 183 #define scope_CPP11_120 (scope_CPP11_OR_GREATER || scope_COMPILER_MSVC_VER >= 1800) 184 #define scope_CPP11_140 (scope_CPP11_OR_GREATER || scope_COMPILER_MSVC_VER >= 1900) 186 #define scope_CPP14_000 (scope_CPP14_OR_GREATER) 188 #define scope_CPP17_000 (scope_CPP17_OR_GREATER) 189 #define scope_CPP17_140 (scope_CPP17_OR_GREATER || scope_COMPILER_MSVC_VER >= 1900) 193 #define scope_HAVE_CONSTEXPR_11 scope_CPP11_140 195 #define scope_HAVE_IS_DEFAULT scope_CPP11_120 196 #define scope_HAVE_IS_DELETE scope_CPP11_120 197 #define scope_HAVE_NOEXCEPT scope_CPP11_140 198 #define scope_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG scope_CPP11_120 199 #define scope_HAVE_STATIC_ASSERT scope_CPP11_90 200 #define scope_HAVE_TRAILING_RETURN_TYPE scope_CPP11_120 201 #define scope_HAVE_VALUE_INITIALIZATION scope_CPP11_120 205 #define scope_HAVE_CONSTEXPR_14 scope_CPP14_000 209 #define scope_HAVE_DEDUCTION_GUIDES scope_CPP17_000 210 #define scope_HAVE_NODISCARD scope_CPP17_000 214 #define scope_HAVE_IS_TRIVIAL scope_CPP11_110 215 #define scope_HAVE_IS_TRIVIALLY_COPYABLE scope_CPP11_110 && !scope_BETWEEN(scope_COMPILER_GNUC_VERSION, 1, 500) // GCC >= 5 216 #define scope_HAVE_IS_CONSTRUCTIBLE scope_CPP11_110 217 #define scope_HAVE_IS_COPY_CONSTRUCTIBLE scope_CPP11_110 218 #define scope_HAVE_IS_MOVE_CONSTRUCTIBLE scope_CPP11_110 219 #define scope_HAVE_IS_NOTHROW_CONSTRUCTIBLE scope_CPP11_110 220 #define scope_HAVE_IS_NOTHROW_COPY_CONSTRUCTIBLE scope_CPP11_110 221 #define scope_HAVE_IS_NOTHROW_MOVE_CONSTRUCTIBLE scope_CPP11_110 222 #define scope_HAVE_IS_COPY_ASSIGNABLE scope_CPP11_110 223 #define scope_HAVE_IS_NOTHROW_ASSIGNABLE scope_CPP11_110 224 #define scope_HAVE_IS_NOTHROW_MOVE_ASSIGNABLE scope_CPP11_110 226 #define scope_HAVE_REFERENCE_WRAPPER scope_CPP11_110 228 #define scope_HAVE_REMOVE_CV scope_CPP11_90 229 #define scope_HAVE_REMOVE_REFERENCE scope_CPP11_90 231 #define scope_HAVE_TYPE_TRAITS scope_CPP11_110 232 #define scope_HAVE_TR1_TYPE_TRAITS ((!! scope_COMPILER_GNUC_VERSION ) && scope_CPP11_OR_GREATER) 234 #define scope_HAVE_DECAY scope_CPP11_110 235 #define scope_HAVE_DECAY_TR1 scope_HAVE_TR1_TYPE_TRAITS 237 #define scope_HAVE_IS_SAME scope_HAVE_TYPE_TRAITS 238 #define scope_HAVE_IS_SAME_TR1 scope_HAVE_TR1_TYPE_TRAITS 246 #define scope_HAVE_UNCAUGHT_EXCEPTIONS scope_CPP17_140 250 #if scope_HAVE_CONSTEXPR_11 251 # define scope_constexpr constexpr 253 # define scope_constexpr 256 #if scope_HAVE_CONSTEXPR_14 257 # define scope_constexpr14 constexpr 259 # define scope_constexpr14 262 #if scope_HAVE( IS_DELETE ) 263 # define scope_is_delete = delete 264 # define scope_is_delete_access public 266 # define scope_is_delete 267 # define scope_is_delete_access private 270 #if scope_HAVE_NOEXCEPT 271 # define scope_noexcept noexcept 272 # define scope_noexcept_op(expr) noexcept(expr) 274 # define scope_noexcept 275 # define scope_noexcept_op(expr) 278 #if scope_HAVE_NODISCARD 279 # define scope_nodiscard [[nodiscard]] 281 # define scope_nodiscard 284 #if scope_HAVE_STATIC_ASSERT 285 # define scope_static_assert(expr, msg) static_assert((expr), msg) 287 # define scope_static_assert(expr, msg) 292 #define scope_USE_POST_CPP98_VERSION scope_CPP11_100 300 #if scope_HAVE_TYPE_TRAITS 301 # include <type_traits> 302 #elif scope_HAVE_TR1_TYPE_TRAITS 303 # include <tr1/type_traits> 308 #if scope_HAVE( TYPE_TRAITS ) 309 # define scope_ENABLE_IF_R_(VA, R) typename std::enable_if< (VA), R >::type 311 # define scope_ENABLE_IF_R_(VA, R) R 316 #if scope_HAVE( TYPE_TRAITS ) && scope_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG ) 318 # if !scope_BETWEEN( scope_COMPILER_MSVC_VERSION, 1, 140 ) 319 # define scope_ENABLE_IF_(VA) , typename std::enable_if< ( VA ), int >::type = 0 321 # define scope_ENABLE_IF_(VA) , typename = typename std::enable_if< ( VA ), ::nonstd::scope::enabler >::type 324 # define scope_ENABLE_IF_(VA) 329 #if !scope_HAVE( UNCAUGHT_EXCEPTIONS ) 330 # if scope_COMPILER_MSVC_VERSION // libstl :) 331 namespace nonstd {
namespace scope {
extern "C" char * __cdecl _getptd(); }}
332 # elif scope_COMPILER_CLANG_VERSION || scope_COMPILER_GNUC_VERSION || scope_COMPILER_APPLECLANG_VERSION 333 # if defined(__GLIBCXX__) || defined(__GLIBCPP__) // libstdc++: prototype from cxxabi.h 335 # elif !defined(BOOST_CORE_UNCAUGHT_EXCEPTIONS_HPP_INCLUDED_) // libc++: prototype from Boost? 336 # if defined(__FreeBSD__) || defined(__OpenBSD__) 337 namespace __cxxabiv1 {
struct __cxa_eh_globals;
extern "C" __cxa_eh_globals * __cxa_get_globals(); }
339 namespace __cxxabiv1 {
struct __cxa_eh_globals;
extern "C" __cxa_eh_globals * __cxa_get_globals()
scope_noexcept; }
342 namespace nonstd {
namespace scope { using ::__cxxabiv1::__cxa_get_globals; }}
343 # endif // scope_COMPILER_MSVC_VERSION 344 #endif // !scope_HAVE( UNCAUGHT_EXCEPTIONS ) 368 template <
class T>
struct is_reference<T&&> : true_type {};
377 template<
bool B,
class T,
class F>
380 template<
class T,
class F>
383 #if scope_HAVE( DECAY ) 385 #elif scope_HAVE( DECAY_TR1 ) 386 using std::tr1::decay;
391 #if scope_HAVE( IS_TRIVIAL ) 392 using std::is_trivial;
397 #if scope_HAVE( IS_TRIVIALLY_COPYABLE ) 398 using std::is_trivially_copyable;
403 #if scope_HAVE( IS_CONSTRUCTIBLE ) 404 using std::is_constructible;
409 #if scope_HAVE( IS_COPY_CONSTRUCTIBLE ) 410 using std::is_copy_constructible;
415 #if scope_HAVE( IS_MOVE_CONSTRUCTIBLE ) 416 using std::is_move_constructible;
421 #if scope_HAVE( IS_NOTHROW_CONSTRUCTIBLE ) 422 using std::is_nothrow_constructible;
427 #if scope_HAVE( IS_NOTHROW_COPY_CONSTRUCTIBLE ) 428 using std::is_nothrow_copy_constructible;
433 #if scope_HAVE( IS_NOTHROW_MOVE_CONSTRUCTIBLE ) 434 using std::is_nothrow_move_constructible;
439 #if scope_HAVE( IS_COPY_ASSIGNABLE ) 440 using std::is_copy_assignable;
445 #if scope_HAVE( IS_NOTHROW_ASSIGNABLE ) 446 using std::is_nothrow_assignable;
451 #if scope_HAVE( IS_NOTHROW_MOVE_ASSIGNABLE ) 452 using std::is_nothrow_move_assignable;
457 #if scope_HAVE( IS_SAME ) 459 #elif scope_HAVE( IS_SAME_TR1 ) 460 using std::tr1::is_same;
465 #if scope_HAVE( REMOVE_CV ) 466 using std::remove_cv;
471 #if scope_HAVE( REMOVE_REFERENCE ) 472 using std::remove_reference;
477 #if scope_HAVE( REFERENCE_WRAPPER ) 478 using std::reference_wrapper;
490 #if scope_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG ) 491 template<
class T,
class U = T >
493 template<
class T,
class U >
498 obj = std::forward<U>( new_value );
511 template<
typename T >
514 return static_cast<int>( x );
517 #if scope_HAVE( UNCAUGHT_EXCEPTIONS ) 521 return to_int( std::uncaught_exceptions() );
524 #elif scope_COMPILER_MSVC_VERSION 528 return to_int( *reinterpret_cast<const unsigned*>(_getptd() + (
sizeof(
void*) == 8 ? 0x100 : 0x90) ) );
531 #elif scope_COMPILER_CLANG_VERSION || scope_COMPILER_GNUC_VERSION || scope_COMPILER_APPLECLANG_VERSION 535 return to_int( *reinterpret_cast<const unsigned*>(
536 reinterpret_cast<const unsigned char*>(__cxa_get_globals()) +
sizeof(
void*) ) );
539 #endif // scope_HAVE( UNCAUGHT_EXCEPTIONS ) 553 template<
class T,
class U >
576 template<
class R,
class D>
581 template<
class R,
class D,
class S=R>
584 noexcept(is_nothrow_constructible_v<decay_t<R>, R> && is_nothrow_constructible_v<decay_t<D>, D>);
602 #if scope_USE_POST_CPP98_VERSION 608 template<
typename T >
611 return std::forward<T>( t );
614 template<
typename T >
620 template<
typename T >
626 template<
typename T >
657 conditional_forward<Fn>( std::forward<Fn>(fn)
659 , execute_on_destruction(
true )
668 : exit_function( std::forward<EF>( other.exit_function ) )
669 , execute_on_destruction( other.execute_on_destruction )
676 if ( execute_on_destruction )
682 execute_on_destruction =
false;
693 bool execute_on_destruction;
715 conditional_forward<Fn>( std::forward<Fn>(fn)
717 , uncaught_on_creation( std17::uncaught_exceptions() )
726 : exit_function( std::forward<EF>( other.exit_function ) )
727 , uncaught_on_creation( other.uncaught_on_creation )
734 if ( uncaught_on_creation < std17::uncaught_exceptions() )
740 uncaught_on_creation = std::numeric_limits<int>::max();
751 int uncaught_on_creation;
773 conditional_forward<Fn>( std::forward<Fn>(fn)
775 , uncaught_on_creation( std17::uncaught_exceptions() )
784 : exit_function( std::forward<EF>( other.exit_function ) )
785 , uncaught_on_creation( other.uncaught_on_creation )
792 if ( uncaught_on_creation >= std17::uncaught_exceptions() )
798 uncaught_on_creation = -1;
809 int uncaught_on_creation;
812 #if scope_HAVE( DEDUCTION_GUIDES ) 843 template<
class R,
class D >
850 ,
"resource must be nothrow_move_constructible or copy_constructible" 856 ,
"deleter must be nothrow_move_constructible or copy_constructible" 871 #if scope_HAVE( VALUE_INITIALIZATION ) 874 , execute_on_reset{
false }
878 , execute_on_reset(
false )
884 template<
class RR,
class DD
885 #if scope_BETWEEN( scope_COMPILER_MSVC_VERSION, 120, 130 ) 906 :
resource( conditional_forward<RR>( std::forward<RR>(r)
908 , deleter( ( conditional_forward<DD>( std::forward<DD>(d)
910 , execute_on_reset( execute )
936 , execute_on_reset( std14::exchange( other.execute_on_reset,
false ) )
942 other.get_deleter()( this->
get() );
964 deleter = other.deleter;
976 deleter = other.deleter;
987 ,
"The resource must be nothrow-move assignable, or copy assignable" 992 ,
"The deleter must be nothrow-move assignable, or copy assignable");
994 if ( &other !=
this )
1002 execute_on_reset = std14::exchange( other.execute_on_reset,
false );
1010 if ( execute_on_reset )
1012 execute_on_reset =
false;
1013 get_deleter()(
get() );
1017 template<
class RR >
1018 void reset( RR && r )
1024 resource = conditional_forward<RR>( std::forward<RR>(r)
1026 execute_on_reset =
true;
1028 #else // scope_CPP11_110 1032 resource = conditional_forward<RR>( std::forward<RR>(r)
1034 execute_on_reset =
true;
1038 this->get_deleter()(r);
1040 #endif // scope_CPP11_110 1044 execute_on_reset =
false;
1054 #if scope_HAVE( TRAILING_RETURN_TYPE ) && !scope_BETWEEN( scope_COMPILER_MSVC_VERSION, 120, 130 ) 1055 template<
class RR=R >
1059 ,
typename std::add_lvalue_reference<
typename std::remove_pointer<R>::type>::
type 1062 typename std::add_lvalue_reference<typename std::remove_pointer<R>::type>::type
1071 #if scope_HAVE( TRAILING_RETURN_TYPE ) && !scope_BETWEEN( scope_COMPILER_MSVC_VERSION, 120, 130 ) 1072 template<
class RR=R >
1093 bool execute_on_reset;
1096 #if scope_HAVE( DEDUCTION_GUIDES ) 1097 template<
typename R,
typename D >
1103 #if scope_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG 1105 template< class R, class D, class S = typename std11::decay<R>::type >
1120 std::forward<R>(
resource ), std::forward<D>( deleter ), !bool(
resource == invalid ) );
1123 #else // scope_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG 1127 template<
class R,
class D >
1130 typename std11::decay<R>::type
1141 std::forward<R>(
resource ), std::forward<D>( deleter ), !bool(
resource == invalid ) );
1144 template<
class R,
class D,
class S >
1147 typename std11::decay<R>::type
1158 std::forward<R>(
resource ), std::forward<D>( deleter ), !bool(
resource == invalid ) );
1161 #endif // scope_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG 1163 #else // #if scope_USE_POST_CPP98_VERSION 1178 : invoke_( other.invoke_ )
1199 : ucount_( std17::uncaught_exceptions() )
1203 : ucount_( other.ucount_ )
1205 other.
ucount_ = std::numeric_limits<int>::max();
1210 ucount_ = std::numeric_limits<int>::max();
1215 return ucount_ < std17::uncaught_exceptions();
1224 : ucount_( std17::uncaught_exceptions() )
1228 : ucount_( other.ucount_ )
1240 return ucount_ >= std17::uncaught_exceptions();
1244 template<
typename Policy,
typename Action >
1255 , action_( other.action_ )
1260 if ( this->perform() )
1271 template<
typename Fn =
void(*)() >
1278 template<
typename Fn =
void(*)() >
1285 template<
typename Fn =
void(*)() >
1294 template<
class R,
class D >
1301 , execute_on_reset( false )
1304 template<
class RR,
class DD >
1308 , execute_on_reset( execute )
1315 , deleter( other.deleter )
1316 , execute_on_reset( other.execute_on_reset )
1318 other.execute_on_reset =
false;
1332 deleter = other.deleter;
1333 execute_on_reset = other.execute_on_reset;
1334 other.execute_on_reset =
false;
1341 if ( execute_on_reset )
1343 execute_on_reset =
false;
1344 get_deleter()(
get() );
1348 template<
class RR >
1354 execute_on_reset =
true;
1358 this->get_deleter()( r );
1363 execute_on_reset =
false;
1366 R
const &
get()
const 1392 mutable bool execute_on_reset;
1395 template<
class EF >
1401 template<
class EF >
1407 template<
class EF >
1413 template<
class R,
class D,
class S >
1416 typename std11::decay<R>::type
1422 resource,deleter, !bool( resource == invalid ) );
1425 #endif // #if scope_USE_POST_CPP98_VERSION 1446 #endif // scope_USES_STD_SCOPE 1448 #endif // NONSTD_SCOPE_LITE_HPP
std11::remove_cv< typename std11::remove_reference< T >::type >::type type
#define scope_ENABLE_IF_(VA)
bool invalid(value code)
Test whether a close code is invalid on the wire.
scope_guard(Action action)
unique_resource< typename std11::decay< R >::type, typename std11::decay< D >::type > make_unique_resource_checked(R const &resource, S const &invalid, D const &deleter)
#define scope_is_delete_access
scope_exit< EF > make_scope_exit(EF action)
#define scope_constexpr14
scope_success< EF > make_scope_success(EF action)
#define scope_static_assert(expr, msg)
on_exit_policy(on_exit_policy const &other)
#define scope_ENABLE_IF_R_(VA, R)
std11::remove_pointer< R >::type & operator*() const
scope_fail< EF > make_scope_fail(EF action)
unique_resource & operator=(unique_resource const &other)
unique_resource(RR const &r, DD const &d, bool execute=true)
bool_constant< false > false_type
scope_guard(scope_guard const &other)
bool_constant< true > true_type
on_success_policy(on_success_policy const &other)
on_fail_policy(on_fail_policy const &other)
int to_int(T x) scope_noexcept
unique_resource(unique_resource const &other)
#define scope_noexcept_op(expr)
D const & get_deleter() const