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 return std::move( contained.value() );
00728 }
00729
00730 optional_constexpr14 value_type && operator *() optional_refref_qual
00731 {
00732 assert( has_value() );
00733 return std::move( contained.value() );
00734 }
00735
00736 #endif
00737
00738 #if optional_CPP11_OR_GREATER
00739 optional_constexpr explicit operator bool() const optional_noexcept
00740 {
00741 return has_value();
00742 }
00743 #else
00744 optional_constexpr operator safe_bool() const optional_noexcept
00745 {
00746 return has_value() ? &optional::this_type_does_not_support_comparisons : 0;
00747 }
00748 #endif
00749
00750 optional_constexpr bool has_value() const optional_noexcept
00751 {
00752 return has_value_;
00753 }
00754
00755 optional_constexpr14 value_type const & value() const optional_ref_qual
00756 {
00757 if ( ! has_value() )
00758 throw bad_optional_access();
00759
00760 return contained.value();
00761 }
00762
00763 optional_constexpr14 value_type & value() optional_ref_qual
00764 {
00765 if ( ! has_value() )
00766 throw bad_optional_access();
00767
00768 return contained.value();
00769 }
00770
00771 #if optional_HAVE_REF_QUALIFIER
00772
00773 optional_constexpr14 value_type const && value() const optional_refref_qual
00774 {
00775 if ( ! has_value() )
00776 throw bad_optional_access();
00777
00778 return std::move( contained.value() );
00779 }
00780
00781 optional_constexpr14 value_type && value() optional_refref_qual
00782 {
00783 if ( ! has_value() )
00784 throw bad_optional_access();
00785
00786 return std::move( contained.value() );
00787 }
00788
00789 #endif
00790
00791 #if optional_CPP11_OR_GREATER
00792
00793 template< class U >
00794 optional_constexpr value_type value_or( U && v ) const optional_ref_qual
00795 {
00796 return has_value() ? contained.value() : static_cast<T>(std::forward<U>( v ) );
00797 }
00798
00799 template< class U >
00800 optional_constexpr value_type value_or( U && v ) const optional_refref_qual
00801 {
00802 return has_value() ? std::move( contained.value() ) : static_cast<T>(std::forward<U>( v ) );
00803 }
00804
00805 #else
00806
00807 template< class U >
00808 optional_constexpr value_type value_or( U const & v ) const
00809 {
00810 return has_value() ? contained.value() : static_cast<value_type>( v );
00811 }
00812
00813 #endif // optional_CPP11_OR_GREATER
00814
00815
00816
00817 void reset() optional_noexcept
00818 {
00819 if ( has_value() )
00820 contained.destruct_value();
00821
00822 has_value_ = false;
00823 }
00824
00825 private:
00826 void this_type_does_not_support_comparisons() const {}
00827
00828 template< typename V >
00829 void initialize( V const & value )
00830 {
00831 assert( ! has_value() );
00832 contained.construct_value( value );
00833 has_value_ = true;
00834 }
00835
00836 #if optional_CPP11_OR_GREATER
00837 template< typename V >
00838 void initialize( V && value )
00839 {
00840 assert( ! has_value() );
00841 contained.construct_value( std::move( value ) );
00842 has_value_ = true;
00843 }
00844 #endif
00845
00846 private:
00847 bool has_value_;
00848 detail::storage_t< value_type > contained;
00849
00850 };
00851
00852
00853
00854 template< typename T > bool operator==( optional<T> const & x, optional<T> const & y )
00855 {
00856 return bool(x) != bool(y) ? false : bool(x) == false ? true : *x == *y;
00857 }
00858
00859 template< typename T > bool operator!=( optional<T> const & x, optional<T> const & y )
00860 {
00861 return !(x == y);
00862 }
00863
00864 template< typename T > bool operator<( optional<T> const & x, optional<T> const & y )
00865 {
00866 return (!y) ? false : (!x) ? true : *x < *y;
00867 }
00868
00869 template< typename T > bool operator>( optional<T> const & x, optional<T> const & y )
00870 {
00871 return (y < x);
00872 }
00873
00874 template< typename T > bool operator<=( optional<T> const & x, optional<T> const & y )
00875 {
00876 return !(y < x);
00877 }
00878
00879 template< typename T > bool operator>=( optional<T> const & x, optional<T> const & y )
00880 {
00881 return !(x < y);
00882 }
00883
00884
00885
00886 template< typename T > bool operator==( optional<T> const & x, nullopt_t ) optional_noexcept
00887 {
00888 return (!x);
00889 }
00890
00891 template< typename T > bool operator==( nullopt_t, optional<T> const & x ) optional_noexcept
00892 {
00893 return (!x);
00894 }
00895
00896 template< typename T > bool operator!=( optional<T> const & x, nullopt_t ) optional_noexcept
00897 {
00898 return bool(x);
00899 }
00900
00901 template< typename T > bool operator!=( nullopt_t, optional<T> const & x ) optional_noexcept
00902 {
00903 return bool(x);
00904 }
00905
00906 template< typename T > bool operator<( optional<T> const &, nullopt_t ) optional_noexcept
00907 {
00908 return false;
00909 }
00910
00911 template< typename T > bool operator<( nullopt_t, optional<T> const & x ) optional_noexcept
00912 {
00913 return bool(x);
00914 }
00915
00916 template< typename T > bool operator<=( optional<T> const & x, nullopt_t ) optional_noexcept
00917 {
00918 return (!x);
00919 }
00920
00921 template< typename T > bool operator<=( nullopt_t, optional<T> const & ) optional_noexcept
00922 {
00923 return true;
00924 }
00925
00926 template< typename T > bool operator>( optional<T> const & x, nullopt_t ) optional_noexcept
00927 {
00928 return bool(x);
00929 }
00930
00931 template< typename T > bool operator>( nullopt_t, optional<T> const & ) optional_noexcept
00932 {
00933 return false;
00934 }
00935
00936 template< typename T > bool operator>=( optional<T> const &, nullopt_t )
00937 {
00938 return true;
00939 }
00940
00941 template< typename T > bool operator>=( nullopt_t, optional<T> const & x )
00942 {
00943 return (!x);
00944 }
00945
00946
00947
00948 template< typename T > bool operator==( optional<T> const & x, const T& v )
00949 {
00950 return bool(x) ? *x == v : false;
00951 }
00952
00953 template< typename T > bool operator==( T const & v, optional<T> const & x )
00954 {
00955 return bool(x) ? v == *x : false;
00956 }
00957
00958 template< typename T > bool operator!=( optional<T> const & x, const T& v )
00959 {
00960 return bool(x) ? *x != v : true;
00961 }
00962
00963 template< typename T > bool operator!=( T const & v, optional<T> const & x )
00964 {
00965 return bool(x) ? v != *x : true;
00966 }
00967
00968 template< typename T > bool operator<( optional<T> const & x, const T& v )
00969 {
00970 return bool(x) ? *x < v : true;
00971 }
00972
00973 template< typename T > bool operator<( T const & v, optional<T> const & x )
00974 {
00975 return bool(x) ? v < *x : false;
00976 }
00977
00978 template< typename T > bool operator<=( optional<T> const & x, const T& v )
00979 {
00980 return bool(x) ? *x <= v : true;
00981 }
00982
00983 template< typename T > bool operator<=( T const & v, optional<T> const & x )
00984 {
00985 return bool(x) ? v <= *x : false;
00986 }
00987
00988 template< typename T > bool operator>( optional<T> const & x, const T& v )
00989 {
00990 return bool(x) ? *x > v : false;
00991 }
00992
00993 template< typename T > bool operator>( T const & v, optional<T> const & x )
00994 {
00995 return bool(x) ? v > *x : true;
00996 }
00997
00998 template< typename T > bool operator>=( optional<T> const & x, const T& v )
00999 {
01000 return bool(x) ? *x >= v : false;
01001 }
01002
01003 template< typename T > bool operator>=( T const & v, optional<T> const & x )
01004 {
01005 return bool(x) ? v >= *x : true;
01006 }
01007
01008
01009
01010 template< typename T >
01011 void swap( optional<T> & x, optional<T> & y )
01012 #if optional_CPP11_OR_GREATER
01013 noexcept( noexcept( x.swap(y) ) )
01014 #endif
01015 {
01016 x.swap( y );
01017 }
01018
01019 #if optional_CPP11_OR_GREATER
01020
01021 template< class T >
01022 optional_constexpr optional< typename std::decay<T>::type > make_optional( T && v )
01023 {
01024 return optional< typename std::decay<T>::type >( std::forward<T>( v ) );
01025 }
01026
01027 template< class T, class...Args >
01028 optional_constexpr optional<T> make_optional( Args&&... args )
01029 {
01030 return optional<T>( in_place, std::forward<Args>(args)...);
01031 }
01032
01033 template< class T, class U, class... Args >
01034 optional_constexpr optional<T> make_optional( std::initializer_list<U> il, Args&&... args )
01035 {
01036 return optional<T>( in_place, il, std::forward<Args>(args)...);
01037 }
01038
01039 #else
01040
01041 template< typename T >
01042 optional<T> make_optional( T const & v )
01043 {
01044 return optional<T>( v );
01045 }
01046
01047 #endif // optional_CPP11_OR_GREATER
01048
01049 }
01050
01051 using namespace optional_lite;
01052
01053 }
01054
01055 #if optional_CPP11_OR_GREATER
01056
01057
01058
01059 namespace std {
01060
01061 template< class T >
01062 class hash< nonstd::optional<T> >
01063 {
01064 public:
01065 std::size_t operator()( nonstd::optional<T> const & v ) const optional_noexcept
01066 {
01067 return bool( v ) ? hash<T>()( *v ) : 0;
01068 }
01069 };
01070
01071 }
01072
01073 #endif // optional_CPP11_OR_GREATER
01074
01075 #endif // NONSTD_OPTIONAL_LITE_HPP