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