00001
00002
00003
00004
00005
00006
00007
00008
00009 #pragma once
00010
00011 #ifndef NONSTD_OPTIONAL_LITE_HPP
00012 #define NONSTD_OPTIONAL_LITE_HPP
00013
00014 #define optional_lite_VERSION "3.1.0"
00015
00016
00017
00018
00019 #ifndef optional_CPLUSPLUS
00020 # ifdef _MSVC_LANG
00021 # define optional_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG )
00022 # else
00023 # define optional_CPLUSPLUS __cplusplus
00024 # endif
00025 #endif
00026
00027 #define optional_CPP98_OR_GREATER ( optional_CPLUSPLUS >= 199711L )
00028 #define optional_CPP11_OR_GREATER ( optional_CPLUSPLUS >= 201103L )
00029 #define optional_CPP14_OR_GREATER ( optional_CPLUSPLUS >= 201402L )
00030 #define optional_CPP17_OR_GREATER ( optional_CPLUSPLUS >= 201703L )
00031 #define optional_CPP20_OR_GREATER ( optional_CPLUSPLUS >= 202000L )
00032
00033
00034
00035 #define optional_CPLUSPLUS_V ( optional_CPLUSPLUS / 100 - (optional_CPLUSPLUS > 200000 ? 2000 : 1994) )
00036
00037
00038
00039 #if defined( __has_include )
00040 # define optional_HAS_INCLUDE( arg ) __has_include( arg )
00041 #else
00042 # define optional_HAS_INCLUDE( arg ) 0
00043 #endif
00044
00045 #define optional_HAVE_STD_OPTIONAL ( optional_CPP17_OR_GREATER && optional_HAS_INCLUDE( <optional> ) )
00046
00047 #if optional_HAVE_STD_OPTIONAL
00048
00049 #include <optional>
00050
00051 namespace nonstd {
00052
00053 using std::optional;
00054 using std::bad_optional_access;
00055 using std::hash;
00056
00057 using std::nullopt;
00058 using std::nullopt_t;
00059 using std::in_place;
00060 using std::in_place_type;
00061 using std::in_place_index;
00062 using std::in_place_t;
00063 using std::in_place_type_t;
00064 using std::in_place_index_t;
00065
00066 using std::operator==;
00067 using std::operator!=;
00068 using std::operator<;
00069 using std::operator<=;
00070 using std::operator>;
00071 using std::operator>=;
00072 using std::make_optional;
00073 using std::swap;
00074 }
00075
00076 #else // C++17 std::optional
00077
00078 #include <cassert>
00079 #include <stdexcept>
00080 #include <utility>
00081
00082
00083
00084 #ifndef optional_CONFIG_MAX_ALIGN_HACK
00085 # define optional_CONFIG_MAX_ALIGN_HACK 0
00086 #endif
00087
00088 #ifndef optional_CONFIG_ALIGN_AS
00089
00090 #endif
00091
00092 #ifndef optional_CONFIG_ALIGN_AS_FALLBACK
00093 # define optional_CONFIG_ALIGN_AS_FALLBACK double
00094 #endif
00095
00096
00097
00098 #ifdef __clang__
00099 # pragma clang diagnostic push
00100 # pragma clang diagnostic ignored "-Wundef"
00101 #elif defined __GNUC__
00102 # pragma GCC diagnostic push
00103 # pragma GCC diagnostic ignored "-Wundef"
00104 #endif
00105
00106
00107 #define optional_BETWEEN( v, lo, hi ) ( lo <= v && v < hi )
00108
00109 #if defined(_MSC_VER) && !defined(__clang__)
00110 # define optional_COMPILER_MSVC_VERSION (_MSC_VER / 10 - 10 * ( 5 + (_MSC_VER < 1900)) )
00111 #else
00112 # define optional_COMPILER_MSVC_VERSION 0
00113 #endif
00114
00115 #define optional_COMPILER_VERSION( major, minor, patch ) ( 10 * (10 * major + minor ) + patch )
00116
00117 #if defined __GNUC__
00118 # define optional_COMPILER_GNUC_VERSION optional_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
00119 #else
00120 # define optional_COMPILER_GNUC_VERSION 0
00121 #endif
00122
00123 #if defined __clang__
00124 # define optional_COMPILER_CLANG_VERSION optional_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__)
00125 #else
00126 # define optional_COMPILER_CLANG_VERSION 0
00127 #endif
00128
00129 #if optional_BETWEEN(optional_COMPILER_MSVC_VERSION, 70, 140 )
00130 # pragma warning( push )
00131 # pragma warning( disable: 4345 ) // initialization behavior changed
00132 #endif
00133
00134 #if optional_BETWEEN(optional_COMPILER_MSVC_VERSION, 70, 150 )
00135 # pragma warning( push )
00136 # pragma warning( disable: 4814 ) // in C++14 'constexpr' will not imply 'const'
00137 #endif
00138
00139
00140
00141 #define optional_HAVE(FEATURE) ( optional_HAVE_##FEATURE )
00142
00143
00144
00145 #if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 100
00146 # define optional_HAVE_AUTO 1
00147 # define optional_HAVE_NULLPTR 1
00148 # define optional_HAVE_STATIC_ASSERT 1
00149 #endif
00150
00151 #if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 120
00152 # define optional_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG 1
00153 # define optional_HAVE_INITIALIZER_LIST 1
00154 #endif
00155
00156 #if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 140
00157 # define optional_HAVE_ALIAS_TEMPLATE 1
00158 # define optional_HAVE_CONSTEXPR_11 1
00159 # define optional_HAVE_ENUM_CLASS 1
00160 # define optional_HAVE_EXPLICIT_CONVERSION 1
00161 # define optional_HAVE_IS_DEFAULT 1
00162 # define optional_HAVE_IS_DELETE 1
00163 # define optional_HAVE_NOEXCEPT 1
00164 # define optional_HAVE_REF_QUALIFIER 1
00165 #endif
00166
00167
00168
00169 #if optional_CPP14_OR_GREATER
00170 # define optional_HAVE_CONSTEXPR_14 1
00171 #endif
00172
00173
00174
00175 #if optional_CPP17_OR_GREATER
00176 # define optional_HAVE_ENUM_CLASS_CONSTRUCTION_FROM_UNDERLYING_TYPE 1
00177 #endif
00178
00179
00180
00181 #if optional_COMPILER_GNUC_VERSION
00182 # define optional_HAVE_TR1_TYPE_TRAITS 1
00183 # define optional_HAVE_TR1_ADD_POINTER 1
00184 #endif
00185
00186 #if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 90
00187 # define optional_HAVE_TYPE_TRAITS 1
00188 # define optional_HAVE_STD_ADD_POINTER 1
00189 #endif
00190
00191 #if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 110
00192 # define optional_HAVE_ARRAY 1
00193 #endif
00194
00195 #if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 120
00196 # define optional_HAVE_CONDITIONAL 1
00197 #endif
00198
00199 #if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 140 || (optional_COMPILER_MSVC_VERSION >= 90 && _HAS_CPP0X)
00200 # define optional_HAVE_CONTAINER_DATA_METHOD 1
00201 #endif
00202
00203 #if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 120
00204 # define optional_HAVE_REMOVE_CV 1
00205 #endif
00206
00207 #if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 140
00208 # define optional_HAVE_SIZED_TYPES 1
00209 #endif
00210
00211
00212
00213 #if optional_COMPILER_MSVC_VERSION >= 140
00214 # undef optional_CPP11_OR_GREATER
00215 # define optional_CPP11_OR_GREATER 1
00216 #endif
00217
00218
00219
00220 #if optional_HAVE( CONSTEXPR_11 )
00221 # define optional_constexpr constexpr
00222 #else
00223 # define optional_constexpr
00224 #endif
00225
00226 #if optional_HAVE( CONSTEXPR_14 )
00227 # define optional_constexpr14 constexpr
00228 #else
00229 # define optional_constexpr14
00230 #endif
00231
00232 #if optional_HAVE( NOEXCEPT )
00233 # define optional_noexcept noexcept
00234 #else
00235 # define optional_noexcept
00236 #endif
00237
00238 #if optional_HAVE( NULLPTR )
00239 # define optional_nullptr nullptr
00240 #else
00241 # define optional_nullptr NULL
00242 #endif
00243
00244 #if optional_HAVE( REF_QUALIFIER )
00245 # define optional_ref_qual &
00246 # define optional_refref_qual &&
00247 #else
00248 # define optional_ref_qual
00249 # define optional_refref_qual
00250 #endif
00251
00252
00253
00254 #if optional_CPP11_OR_GREATER
00255 # include <functional>
00256 #endif
00257
00258 #if optional_HAVE( INITIALIZER_LIST )
00259 # include <initializer_list>
00260 #endif
00261
00262 #if optional_HAVE( TYPE_TRAITS )
00263 # include <type_traits>
00264 #elif optional_HAVE( TR1_TYPE_TRAITS )
00265 # include <tr1/type_traits>
00266 #endif
00267
00268
00269
00270 namespace BT { namespace optional_lite { namespace detail {
00271
00272 #if optional_HAVE( CONDITIONAL )
00273 using std::conditional;
00274 #else
00275 template< bool B, typename T, typename F > struct conditional { typedef T type; };
00276 template< typename T, typename F > struct conditional<false, T, F> { typedef F type; };
00277 #endif // optional_HAVE_CONDITIONAL
00278
00279 }}}
00280
00281
00282
00283
00284
00285 #ifndef nonstd_lite_HAVE_IN_PLACE_TYPES
00286
00287 namespace BT {
00288
00289 namespace detail {
00290
00291 template< class T >
00292 struct in_place_type_tag {};
00293
00294 template< std::size_t I >
00295 struct in_place_index_tag {};
00296
00297 }
00298
00299 struct in_place_t {};
00300
00301 template< class T >
00302 inline in_place_t in_place( detail::in_place_type_tag<T> = detail::in_place_type_tag<T>() )
00303 {
00304 return in_place_t();
00305 }
00306
00307 template< std::size_t I >
00308 inline in_place_t in_place( detail::in_place_index_tag<I> = detail::in_place_index_tag<I>() )
00309 {
00310 return in_place_t();
00311 }
00312
00313 template< class T >
00314 inline in_place_t in_place_type( detail::in_place_type_tag<T> = detail::in_place_type_tag<T>() )
00315 {
00316 return in_place_t();
00317 }
00318
00319 template< std::size_t I >
00320 inline in_place_t in_place_index( detail::in_place_index_tag<I> = detail::in_place_index_tag<I>() )
00321 {
00322 return in_place_t();
00323 }
00324
00325
00326
00327 #define nonstd_lite_in_place_type_t( T) BT::in_place_t(&)( BT::detail::in_place_type_tag<T> )
00328 #define nonstd_lite_in_place_index_t(T) BT::in_place_t(&)( BT::detail::in_place_index_tag<I> )
00329
00330 #define nonstd_lite_HAVE_IN_PLACE_TYPES 1
00331
00332 }
00333
00334 #endif // nonstd_lite_HAVE_IN_PLACE_TYPES
00335
00336
00337
00338
00339
00340 namespace BT { namespace optional_lite {
00341
00343
00344 template< typename T >
00345 class optional;
00346
00347 namespace detail {
00348
00349
00350
00351 struct nulltype{};
00352
00353 template< typename Head, typename Tail >
00354 struct typelist
00355 {
00356 typedef Head head;
00357 typedef Tail tail;
00358 };
00359
00360 #if optional_CONFIG_MAX_ALIGN_HACK
00361
00362
00363
00364 #define optional_UNIQUE( name ) optional_UNIQUE2( name, __LINE__ )
00365 #define optional_UNIQUE2( name, line ) optional_UNIQUE3( name, line )
00366 #define optional_UNIQUE3( name, line ) name ## line
00367
00368 #define optional_ALIGN_TYPE( type ) \
00369 type optional_UNIQUE( _t ); struct_t< type > optional_UNIQUE( _st )
00370
00371 template< typename T >
00372 struct struct_t { T _; };
00373
00374 union max_align_t
00375 {
00376 optional_ALIGN_TYPE( char );
00377 optional_ALIGN_TYPE( short int );
00378 optional_ALIGN_TYPE( int );
00379 optional_ALIGN_TYPE( long int );
00380 optional_ALIGN_TYPE( float );
00381 optional_ALIGN_TYPE( double );
00382 optional_ALIGN_TYPE( long double );
00383 optional_ALIGN_TYPE( char * );
00384 optional_ALIGN_TYPE( short int * );
00385 optional_ALIGN_TYPE( int * );
00386 optional_ALIGN_TYPE( long int * );
00387 optional_ALIGN_TYPE( float * );
00388 optional_ALIGN_TYPE( double * );
00389 optional_ALIGN_TYPE( long double * );
00390 optional_ALIGN_TYPE( void * );
00391
00392 #ifdef HAVE_LONG_LONG
00393 optional_ALIGN_TYPE( long long );
00394 #endif
00395
00396 struct Unknown;
00397
00398 Unknown ( * optional_UNIQUE(_) )( Unknown );
00399 Unknown * Unknown::* optional_UNIQUE(_);
00400 Unknown ( Unknown::* optional_UNIQUE(_) )( Unknown );
00401
00402 struct_t< Unknown ( * )( Unknown) > optional_UNIQUE(_);
00403 struct_t< Unknown * Unknown::* > optional_UNIQUE(_);
00404 struct_t< Unknown ( Unknown::* )(Unknown) > optional_UNIQUE(_);
00405 };
00406
00407 #undef optional_UNIQUE
00408 #undef optional_UNIQUE2
00409 #undef optional_UNIQUE3
00410
00411 #undef optional_ALIGN_TYPE
00412
00413 #elif defined( optional_CONFIG_ALIGN_AS ) // optional_CONFIG_MAX_ALIGN_HACK
00414
00415
00416
00417 #define optional_ALIGN_AS( unused ) \
00418 optional_CONFIG_ALIGN_AS
00419
00420 #else // optional_CONFIG_MAX_ALIGN_HACK
00421
00422
00423
00424 #define optional_ALIGN_AS( to_align ) \
00425 typename type_of_size< alignment_types, alignment_of< to_align >::value >::type
00426
00427 template <typename T>
00428 struct alignment_of;
00429
00430 template <typename T>
00431 struct alignment_of_hack
00432 {
00433 char c;
00434 T t;
00435 alignment_of_hack();
00436 };
00437
00438 template <unsigned A, unsigned S>
00439 struct alignment_logic
00440 {
00441 enum { value = A < S ? A : S };
00442 };
00443
00444 template< typename T >
00445 struct alignment_of
00446 {
00447 enum { value = alignment_logic<
00448 sizeof( alignment_of_hack<T> ) - sizeof(T), sizeof(T) >::value, };
00449 };
00450
00451 template< typename List, size_t N >
00452 struct type_of_size
00453 {
00454 typedef typename conditional<
00455 N == sizeof( typename List::head ),
00456 typename List::head,
00457 typename type_of_size<typename List::tail, N >::type >::type type;
00458 };
00459
00460 template< size_t N >
00461 struct type_of_size< nulltype, N >
00462 {
00463 typedef optional_CONFIG_ALIGN_AS_FALLBACK type;
00464 };
00465
00466 template< typename T>
00467 struct struct_t { T _; };
00468
00469 #define optional_ALIGN_TYPE( type ) \
00470 typelist< type , typelist< struct_t< type >
00471
00472 struct Unknown;
00473
00474 typedef
00475 optional_ALIGN_TYPE( char ),
00476 optional_ALIGN_TYPE( short ),
00477 optional_ALIGN_TYPE( int ),
00478 optional_ALIGN_TYPE( long ),
00479 optional_ALIGN_TYPE( float ),
00480 optional_ALIGN_TYPE( double ),
00481 optional_ALIGN_TYPE( long double ),
00482
00483 optional_ALIGN_TYPE( char *),
00484 optional_ALIGN_TYPE( short * ),
00485 optional_ALIGN_TYPE( int * ),
00486 optional_ALIGN_TYPE( long * ),
00487 optional_ALIGN_TYPE( float * ),
00488 optional_ALIGN_TYPE( double * ),
00489 optional_ALIGN_TYPE( long double * ),
00490
00491 optional_ALIGN_TYPE( Unknown ( * )( Unknown ) ),
00492 optional_ALIGN_TYPE( Unknown * Unknown::* ),
00493 optional_ALIGN_TYPE( Unknown ( Unknown::* )( Unknown ) ),
00494
00495 nulltype
00496 > > > > > > > > > > > > > >
00497 > > > > > > > > > > > > > >
00498 > > > > > >
00499 alignment_types;
00500
00501 #undef optional_ALIGN_TYPE
00502
00503 #endif // optional_CONFIG_MAX_ALIGN_HACK
00504
00506
00507 template< typename T >
00508 union storage_t
00509 {
00510 private:
00511 friend class optional<T>;
00512
00513 typedef T value_type;
00514
00515 storage_t() {}
00516
00517 storage_t( value_type const & v )
00518 {
00519 construct_value( v );
00520 }
00521
00522 void construct_value( value_type const & v )
00523 {
00524 ::new( value_ptr() ) value_type( v );
00525 }
00526
00527 #if optional_CPP11_OR_GREATER
00528
00529 storage_t( value_type && v )
00530 {
00531 construct_value( std::move( v ) );
00532 }
00533
00534 void construct_value( value_type && v )
00535 {
00536 ::new( value_ptr() ) value_type( std::move( v ) );
00537 }
00538
00539 template< class... Args >
00540 void emplace( Args&&... args )
00541 {
00542 ::new( value_ptr() ) value_type( std::forward<Args>(args)... );
00543 }
00544
00545 template< class U, class... Args >
00546 void emplace( std::initializer_list<U> il, Args&&... args )
00547 {
00548 ::new( value_ptr() ) value_type( il, std::forward<Args>(args)... );
00549 }
00550
00551 #endif
00552
00553 void destruct_value()
00554 {
00555 value_ptr()->~T();
00556 }
00557
00558 value_type const * value_ptr() const
00559 {
00560 return as<value_type>();
00561 }
00562
00563 value_type * value_ptr()
00564 {
00565 return as<value_type>();
00566 }
00567
00568 value_type const & value() const optional_ref_qual
00569 {
00570 return * value_ptr();
00571 }
00572
00573 value_type & value() optional_ref_qual
00574 {
00575 return * value_ptr();
00576 }
00577
00578 #if optional_CPP11_OR_GREATER
00579
00580 value_type const && value() const optional_refref_qual
00581 {
00582 return std::move( value() );
00583 }
00584
00585 value_type && value() optional_refref_qual
00586 {
00587 return std::move( value() );
00588 }
00589
00590 #endif
00591
00592 #if optional_CPP11_OR_GREATER
00593
00594 using aligned_storage_t = typename std::aligned_storage< sizeof(value_type), alignof(value_type) >::type;
00595 aligned_storage_t data;
00596
00597 #elif optional_CONFIG_MAX_ALIGN_HACK
00598
00599 typedef struct { unsigned char data[ sizeof(value_type) ]; } aligned_storage_t;
00600
00601 max_align_t hack;
00602 aligned_storage_t data;
00603
00604 #else
00605 typedef optional_ALIGN_AS(value_type) align_as_type;
00606
00607 typedef struct { align_as_type data[ 1 + ( sizeof(value_type) - 1 ) / sizeof(align_as_type) ]; } aligned_storage_t;
00608 aligned_storage_t data;
00609
00610 # undef optional_ALIGN_AS
00611
00612 #endif // optional_CONFIG_MAX_ALIGN_HACK
00613
00614 void * ptr() optional_noexcept
00615 {
00616 return &data;
00617 }
00618
00619 void const * ptr() const optional_noexcept
00620 {
00621 return &data;
00622 }
00623
00624 template <typename U>
00625 U * as()
00626 {
00627 return reinterpret_cast<U*>( ptr() );
00628 }
00629
00630 template <typename U>
00631 U const * as() const
00632 {
00633 return reinterpret_cast<U const *>( ptr() );
00634 }
00635 };
00636
00637 }
00638
00640
00641 struct nullopt_t
00642 {
00643 struct init{};
00644 optional_constexpr nullopt_t( init ) {}
00645 };
00646
00647 #if optional_HAVE( CONSTEXPR_11 )
00648 constexpr nullopt_t nullopt{ nullopt_t::init{} };
00649 #else
00650
00651 const nullopt_t nullopt(( nullopt_t::init() ));
00652 #endif
00653
00655
00656 class bad_optional_access : public std::logic_error
00657 {
00658 public:
00659 explicit bad_optional_access()
00660 : logic_error( "bad optional access" ) {}
00661 };
00662
00664
00665 template< typename T>
00666 class optional
00667 {
00668 private:
00669 typedef void (optional::*safe_bool)() const;
00670
00671 public:
00672 typedef T value_type;
00673
00674 optional_constexpr optional() optional_noexcept
00675 : has_value_( false )
00676 , contained()
00677 {}
00678
00679 optional_constexpr optional( nullopt_t ) optional_noexcept
00680 : has_value_( false )
00681 , contained()
00682 {}
00683
00684 optional( optional const & rhs )
00685 : has_value_( rhs.has_value() )
00686 {
00687 if ( rhs.has_value() )
00688 contained.construct_value( rhs.contained.value() );
00689 }
00690
00691 #if optional_CPP11_OR_GREATER
00692 optional_constexpr14 optional( optional && rhs ) noexcept( std::is_nothrow_move_constructible<T>::value )
00693 : has_value_( rhs.has_value() )
00694 {
00695 if ( rhs.has_value() )
00696 contained.construct_value( std::move( rhs.contained.value() ) );
00697 }
00698 #endif
00699
00700 optional_constexpr optional( value_type const & value )
00701 : has_value_( true )
00702 , contained( value )
00703 {}
00704
00705 #if optional_CPP11_OR_GREATER
00706
00707 optional_constexpr optional( value_type && value )
00708 : has_value_( true )
00709 , contained( std::move( value ) )
00710 {}
00711
00712 template< class... Args >
00713 optional_constexpr explicit optional( nonstd_lite_in_place_type_t(T), Args&&... args )
00714 : has_value_( true )
00715 , contained( T( std::forward<Args>(args)...) )
00716 {}
00717
00718 template< class U, class... Args >
00719 optional_constexpr explicit optional( nonstd_lite_in_place_type_t(T), std::initializer_list<U> il, Args&&... args )
00720 : has_value_( true )
00721 , contained( T( il, std::forward<Args>(args)...) )
00722 {}
00723
00724 #endif // optional_CPP11_OR_GREATER
00725
00726 ~optional()
00727 {
00728 if ( has_value() )
00729 contained.destruct_value();
00730 }
00731
00732
00733
00734 optional & operator=( nullopt_t ) optional_noexcept
00735 {
00736 reset();
00737 return *this;
00738 }
00739
00740 optional & operator=( optional const & rhs )
00741 #if optional_CPP11_OR_GREATER
00742 noexcept( std::is_nothrow_move_assignable<T>::value && std::is_nothrow_move_constructible<T>::value )
00743 #endif
00744 {
00745 if ( has_value() == true && rhs.has_value() == false ) reset();
00746 else if ( has_value() == false && rhs.has_value() == true ) initialize( *rhs );
00747 else if ( has_value() == true && rhs.has_value() == true ) contained.value() = *rhs;
00748 return *this;
00749 }
00750
00751 #if optional_CPP11_OR_GREATER
00752
00753 optional & operator=( optional && rhs ) noexcept
00754 {
00755 if ( has_value() == true && rhs.has_value() == false ) reset();
00756 else if ( has_value() == false && rhs.has_value() == true ) initialize( std::move( *rhs ) );
00757 else if ( has_value() == true && rhs.has_value() == true ) contained.value() = std::move( *rhs );
00758 return *this;
00759 }
00760
00761 template< class U,
00762 typename = typename std::enable_if< std::is_same< typename std::decay<U>::type, T>::value >::type >
00763 optional & operator=( U && v )
00764 {
00765 if ( has_value() ) contained.value() = std::forward<U>( v );
00766 else initialize( T( std::forward<U>( v ) ) );
00767 return *this;
00768 }
00769
00770 template< class... Args >
00771 void emplace( Args&&... args )
00772 {
00773 *this = nullopt;
00774 contained.emplace( std::forward<Args>(args)... );
00775 has_value_ = true;
00776 }
00777
00778
00779 template< class U, class... Args >
00780 void emplace( std::initializer_list<U> il, Args&&... args )
00781 {
00782 *this = nullopt;
00783 contained.emplace( il, std::forward<Args>(args)... );
00784 has_value_ = true;
00785 }
00786
00787 #endif // optional_CPP11_OR_GREATER
00788
00789
00790
00791 void swap( optional & rhs )
00792 #if optional_CPP11_OR_GREATER
00793 noexcept( std::is_nothrow_move_constructible<T>::value && noexcept( std::swap( std::declval<T&>(), std::declval<T&>() ) ) )
00794 #endif
00795 {
00796 using std::swap;
00797 if ( has_value() == true && rhs.has_value() == true ) { swap( **this, *rhs ); }
00798 else if ( has_value() == false && rhs.has_value() == true ) { initialize( *rhs ); rhs.reset(); }
00799 else if ( has_value() == true && rhs.has_value() == false ) { rhs.initialize( **this ); reset(); }
00800 }
00801
00802
00803
00804 optional_constexpr value_type const * operator ->() const
00805 {
00806 return assert( has_value() ),
00807 contained.value_ptr();
00808 }
00809
00810 optional_constexpr14 value_type * operator ->()
00811 {
00812 return assert( has_value() ),
00813 contained.value_ptr();
00814 }
00815
00816 optional_constexpr value_type const & operator *() const optional_ref_qual
00817 {
00818 return assert( has_value() ),
00819 contained.value();
00820 }
00821
00822 optional_constexpr14 value_type & operator *() optional_ref_qual
00823 {
00824 return assert( has_value() ),
00825 contained.value();
00826 }
00827
00828 #if optional_CPP11_OR_GREATER
00829
00830 optional_constexpr value_type const && operator *() const optional_refref_qual
00831 {
00832 return std::move( **this );
00833 }
00834
00835 optional_constexpr14 value_type && operator *() optional_refref_qual
00836 {
00837 return std::move( **this );
00838 }
00839
00840 #endif
00841
00842 #if optional_CPP11_OR_GREATER
00843 optional_constexpr explicit operator bool() const optional_noexcept
00844 {
00845 return has_value();
00846 }
00847 #else
00848 optional_constexpr operator safe_bool() const optional_noexcept
00849 {
00850 return has_value() ? &optional::this_type_does_not_support_comparisons : 0;
00851 }
00852 #endif
00853
00854 optional_constexpr bool has_value() const optional_noexcept
00855 {
00856 return has_value_;
00857 }
00858
00859 optional_constexpr14 value_type const & value() const optional_ref_qual
00860 {
00861 if ( ! has_value() )
00862 throw bad_optional_access();
00863
00864 return contained.value();
00865 }
00866
00867 optional_constexpr14 value_type & value() optional_ref_qual
00868 {
00869 if ( ! has_value() )
00870 throw bad_optional_access();
00871
00872 return contained.value();
00873 }
00874
00875 #if optional_HAVE( REF_QUALIFIER )
00876
00877 optional_constexpr14 value_type const && value() const optional_refref_qual
00878 {
00879 return std::move( value() );
00880 }
00881
00882 optional_constexpr14 value_type && value() optional_refref_qual
00883 {
00884 return std::move( value() );
00885 }
00886
00887 #endif
00888
00889 #if optional_CPP11_OR_GREATER
00890
00891 template< class U >
00892 optional_constexpr value_type value_or( U && v ) const optional_ref_qual
00893 {
00894 return has_value() ? contained.value() : static_cast<T>(std::forward<U>( v ) );
00895 }
00896
00897 template< class U >
00898 optional_constexpr value_type value_or( U && v ) const optional_refref_qual
00899 {
00900 return has_value() ? std::move( contained.value() ) : static_cast<T>(std::forward<U>( v ) );
00901 }
00902
00903 #else
00904
00905 template< class U >
00906 optional_constexpr value_type value_or( U const & v ) const
00907 {
00908 return has_value() ? contained.value() : static_cast<value_type>( v );
00909 }
00910
00911 #endif // optional_CPP11_OR_GREATER
00912
00913
00914
00915 void reset() optional_noexcept
00916 {
00917 if ( has_value() )
00918 contained.destruct_value();
00919
00920 has_value_ = false;
00921 }
00922
00923 private:
00924 void this_type_does_not_support_comparisons() const {}
00925
00926 template< typename V >
00927 void initialize( V const & value )
00928 {
00929 assert( ! has_value() );
00930 contained.construct_value( value );
00931 has_value_ = true;
00932 }
00933
00934 #if optional_CPP11_OR_GREATER
00935 template< typename V >
00936 void initialize( V && value )
00937 {
00938 assert( ! has_value() );
00939 contained.construct_value( std::move( value ) );
00940 has_value_ = true;
00941 }
00942
00943 #endif
00944
00945 private:
00946 bool has_value_;
00947 detail::storage_t< value_type > contained;
00948
00949 };
00950
00951
00952
00953 template< typename T, typename U >
00954 inline optional_constexpr bool operator==( optional<T> const & x, optional<U> const & y )
00955 {
00956 return bool(x) != bool(y) ? false : !bool( x ) ? true : *x == *y;
00957 }
00958
00959 template< typename T, typename U >
00960 inline optional_constexpr bool operator!=( optional<T> const & x, optional<U> const & y )
00961 {
00962 return !(x == y);
00963 }
00964
00965 template< typename T, typename U >
00966 inline optional_constexpr bool operator<( optional<T> const & x, optional<U> const & y )
00967 {
00968 return (!y) ? false : (!x) ? true : *x < *y;
00969 }
00970
00971 template< typename T, typename U >
00972 inline optional_constexpr bool operator>( optional<T> const & x, optional<U> const & y )
00973 {
00974 return (y < x);
00975 }
00976
00977 template< typename T, typename U >
00978 inline optional_constexpr bool operator<=( optional<T> const & x, optional<U> const & y )
00979 {
00980 return !(y < x);
00981 }
00982
00983 template< typename T, typename U >
00984 inline optional_constexpr bool operator>=( optional<T> const & x, optional<U> const & y )
00985 {
00986 return !(x < y);
00987 }
00988
00989
00990
00991 template< typename T >
00992 inline optional_constexpr bool operator==( optional<T> const & x, nullopt_t ) optional_noexcept
00993 {
00994 return (!x);
00995 }
00996
00997 template< typename T >
00998 inline optional_constexpr bool operator==( nullopt_t, optional<T> const & x ) optional_noexcept
00999 {
01000 return (!x);
01001 }
01002
01003 template< typename T >
01004 inline optional_constexpr bool operator!=( optional<T> const & x, nullopt_t ) optional_noexcept
01005 {
01006 return bool(x);
01007 }
01008
01009 template< typename T >
01010 inline optional_constexpr bool operator!=( nullopt_t, optional<T> const & x ) optional_noexcept
01011 {
01012 return bool(x);
01013 }
01014
01015 template< typename T >
01016 inline optional_constexpr bool operator<( optional<T> const &, nullopt_t ) optional_noexcept
01017 {
01018 return false;
01019 }
01020
01021 template< typename T >
01022 inline optional_constexpr bool operator<( nullopt_t, optional<T> const & x ) optional_noexcept
01023 {
01024 return bool(x);
01025 }
01026
01027 template< typename T >
01028 inline optional_constexpr bool operator<=( optional<T> const & x, nullopt_t ) optional_noexcept
01029 {
01030 return (!x);
01031 }
01032
01033 template< typename T >
01034 inline optional_constexpr bool operator<=( nullopt_t, optional<T> const & ) optional_noexcept
01035 {
01036 return true;
01037 }
01038
01039 template< typename T >
01040 inline optional_constexpr bool operator>( optional<T> const & x, nullopt_t ) optional_noexcept
01041 {
01042 return bool(x);
01043 }
01044
01045 template< typename T >
01046 inline optional_constexpr bool operator>( nullopt_t, optional<T> const & ) optional_noexcept
01047 {
01048 return false;
01049 }
01050
01051 template< typename T >
01052 inline optional_constexpr bool operator>=( optional<T> const &, nullopt_t ) optional_noexcept
01053 {
01054 return true;
01055 }
01056
01057 template< typename T >
01058 inline optional_constexpr bool operator>=( nullopt_t, optional<T> const & x ) optional_noexcept
01059 {
01060 return (!x);
01061 }
01062
01063
01064
01065 template< typename T, typename U >
01066 inline optional_constexpr bool operator==( optional<T> const & x, U const & v )
01067 {
01068 return bool(x) ? *x == v : false;
01069 }
01070
01071 template< typename T, typename U >
01072 inline optional_constexpr bool operator==( U const & v, optional<T> const & x )
01073 {
01074 return bool(x) ? v == *x : false;
01075 }
01076
01077 template< typename T, typename U >
01078 inline optional_constexpr bool operator!=( optional<T> const & x, U const & v )
01079 {
01080 return bool(x) ? *x != v : true;
01081 }
01082
01083 template< typename T, typename U >
01084 inline optional_constexpr bool operator!=( U const & v, optional<T> const & x )
01085 {
01086 return bool(x) ? v != *x : true;
01087 }
01088
01089 template< typename T, typename U >
01090 inline optional_constexpr bool operator<( optional<T> const & x, U const & v )
01091 {
01092 return bool(x) ? *x < v : true;
01093 }
01094
01095 template< typename T, typename U >
01096 inline optional_constexpr bool operator<( U const & v, optional<T> const & x )
01097 {
01098 return bool(x) ? v < *x : false;
01099 }
01100
01101 template< typename T, typename U >
01102 inline optional_constexpr bool operator<=( optional<T> const & x, U const & v )
01103 {
01104 return bool(x) ? *x <= v : true;
01105 }
01106
01107 template< typename T, typename U >
01108 inline optional_constexpr bool operator<=( U const & v, optional<T> const & x )
01109 {
01110 return bool(x) ? v <= *x : false;
01111 }
01112
01113 template< typename T, typename U >
01114 inline optional_constexpr bool operator>( optional<T> const & x, U const & v )
01115 {
01116 return bool(x) ? *x > v : false;
01117 }
01118
01119 template< typename T, typename U >
01120 inline optional_constexpr bool operator>( U const & v, optional<T> const & x )
01121 {
01122 return bool(x) ? v > *x : true;
01123 }
01124
01125 template< typename T, typename U >
01126 inline optional_constexpr bool operator>=( optional<T> const & x, U const & v )
01127 {
01128 return bool(x) ? *x >= v : false;
01129 }
01130
01131 template< typename T, typename U >
01132 inline optional_constexpr bool operator>=( U const & v, optional<T> const & x )
01133 {
01134 return bool(x) ? v >= *x : true;
01135 }
01136
01137
01138
01139 template< typename T >
01140 void swap( optional<T> & x, optional<T> & y )
01141 #if optional_CPP11_OR_GREATER
01142 noexcept( noexcept( x.swap(y) ) )
01143 #endif
01144 {
01145 x.swap( y );
01146 }
01147
01148 #if optional_CPP11_OR_GREATER
01149
01150 template< class T >
01151 optional_constexpr optional< typename std::decay<T>::type > make_optional( T && v )
01152 {
01153 return optional< typename std::decay<T>::type >( std::forward<T>( v ) );
01154 }
01155
01156 template< class T, class...Args >
01157 optional_constexpr optional<T> make_optional( Args&&... args )
01158 {
01159 return optional<T>( in_place, std::forward<Args>(args)...);
01160 }
01161
01162 template< class T, class U, class... Args >
01163 optional_constexpr optional<T> make_optional( std::initializer_list<U> il, Args&&... args )
01164 {
01165 return optional<T>( in_place, il, std::forward<Args>(args)...);
01166 }
01167
01168 #else
01169
01170 template< typename T >
01171 optional<T> make_optional( T const & v )
01172 {
01173 return optional<T>( v );
01174 }
01175
01176 #endif // optional_CPP11_OR_GREATER
01177
01178 }
01179
01180 using namespace optional_lite;
01181
01182 }
01183
01184 #if optional_CPP11_OR_GREATER
01185
01186
01187
01188 namespace std {
01189
01190 template< class T >
01191 struct hash< BT::optional<T> >
01192 {
01193 public:
01194 std::size_t operator()( BT::optional<T> const & v ) const optional_noexcept
01195 {
01196 return bool( v ) ? hash<T>()( *v ) : 0;
01197 }
01198 };
01199
01200 }
01201
01202 #endif // optional_CPP11_OR_GREATER
01203
01204 #ifdef __clang__
01205 # pragma clang diagnostic pop
01206 #elif defined __GNUC__
01207 # pragma GCC diagnostic pop
01208 #endif
01209
01210 #endif // have C++17 std::optional
01211
01212 #endif // NONSTD_OPTIONAL_LITE_HPP