11 #ifndef NONSTD_OPTIONAL_LITE_HPP
12 #define NONSTD_OPTIONAL_LITE_HPP
14 #define optional_lite_MAJOR 3
15 #define optional_lite_MINOR 2
16 #define optional_lite_PATCH 0
18 #define optional_lite_VERSION optional_STRINGIFY(optional_lite_MAJOR) "." optional_STRINGIFY(optional_lite_MINOR) "." optional_STRINGIFY(optional_lite_PATCH)
20 #define optional_STRINGIFY( x ) optional_STRINGIFY_( x )
21 #define optional_STRINGIFY_( x ) #x
25 #define optional_OPTIONAL_DEFAULT 0
26 #define optional_OPTIONAL_NONSTD 1
27 #define optional_OPTIONAL_STD 2
29 #if !defined( optional_CONFIG_SELECT_OPTIONAL )
30 # define optional_CONFIG_SELECT_OPTIONAL ( optional_HAVE_STD_OPTIONAL ? optional_OPTIONAL_STD : optional_OPTIONAL_NONSTD )
35 #ifndef optional_CONFIG_NO_EXCEPTIONS
36 # if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)
37 # define optional_CONFIG_NO_EXCEPTIONS 0
39 # define optional_CONFIG_NO_EXCEPTIONS 1
46 #ifndef optional_CPLUSPLUS
47 # if defined(_MSVC_LANG ) && !defined(__clang__)
48 # define optional_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG )
50 # define optional_CPLUSPLUS __cplusplus
54 #define optional_CPP98_OR_GREATER ( optional_CPLUSPLUS >= 199711L )
55 #define optional_CPP11_OR_GREATER ( optional_CPLUSPLUS >= 201103L )
56 #define optional_CPP11_OR_GREATER_ ( optional_CPLUSPLUS >= 201103L )
57 #define optional_CPP14_OR_GREATER ( optional_CPLUSPLUS >= 201402L )
58 #define optional_CPP17_OR_GREATER ( optional_CPLUSPLUS >= 201703L )
59 #define optional_CPP20_OR_GREATER ( optional_CPLUSPLUS >= 202000L )
63 #define optional_CPLUSPLUS_V ( optional_CPLUSPLUS / 100 - (optional_CPLUSPLUS > 200000 ? 2000 : 1994) )
67 #if optional_CPP17_OR_GREATER && defined(__has_include )
68 # if __has_include( <optional> )
69 # define optional_HAVE_STD_OPTIONAL 1
71 # define optional_HAVE_STD_OPTIONAL 0
74 # define optional_HAVE_STD_OPTIONAL 0
77 #define optional_USES_STD_OPTIONAL ( (optional_CONFIG_SELECT_OPTIONAL == optional_OPTIONAL_STD) || ((optional_CONFIG_SELECT_OPTIONAL == optional_OPTIONAL_DEFAULT) && optional_HAVE_STD_OPTIONAL) )
83 #ifndef nonstd_lite_HAVE_IN_PLACE_TYPES
84 #define nonstd_lite_HAVE_IN_PLACE_TYPES 1
88 #if optional_CPP17_OR_GREATER
95 using std::in_place_type;
96 using std::in_place_index;
97 using std::in_place_t;
98 using std::in_place_type_t;
99 using std::in_place_index_t;
101 #define nonstd_lite_in_place_t( T) std::in_place_t
102 #define nonstd_lite_in_place_type_t( T) std::in_place_type_t<T>
103 #define nonstd_lite_in_place_index_t(K) std::in_place_index_t<K>
105 #define nonstd_lite_in_place( T) std::in_place_t{}
106 #define nonstd_lite_in_place_type( T) std::in_place_type_t<T>{}
107 #define nonstd_lite_in_place_index(K) std::in_place_index_t<K>{}
111 #else // optional_CPP17_OR_GREATER
121 template< std::
size_t K >
134 template< std::
size_t K >
135 inline in_place_t in_place( detail::in_place_index_tag<K> = detail::in_place_index_tag<K>() )
141 inline in_place_t in_place_type( detail::in_place_type_tag<T> = detail::in_place_type_tag<T>() )
146 template< std::
size_t K >
147 inline in_place_t in_place_index( detail::in_place_index_tag<K> = detail::in_place_index_tag<K>() )
154 #define nonstd_lite_in_place_t( T) nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag<T> )
155 #define nonstd_lite_in_place_type_t( T) nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag<T> )
156 #define nonstd_lite_in_place_index_t(K) nonstd::in_place_t(&)( nonstd::detail::in_place_index_tag<K> )
158 #define nonstd_lite_in_place( T) nonstd::in_place_type<T>
159 #define nonstd_lite_in_place_type( T) nonstd::in_place_type<T>
160 #define nonstd_lite_in_place_index(K) nonstd::in_place_index<K>
164 #endif // optional_CPP17_OR_GREATER
165 #endif // nonstd_lite_HAVE_IN_PLACE_TYPES
171 #if optional_USES_STD_OPTIONAL
178 using std::bad_optional_access;
182 using std::nullopt_t;
184 using std::operator==;
185 using std::operator!=;
186 using std::operator<;
187 using std::operator<=;
188 using std::operator>;
189 using std::operator>=;
190 using std::make_optional;
194 #else // optional_USES_STD_OPTIONAL
201 #ifndef optional_CONFIG_MAX_ALIGN_HACK
202 # define optional_CONFIG_MAX_ALIGN_HACK 0
205 #ifndef optional_CONFIG_ALIGN_AS
209 #ifndef optional_CONFIG_ALIGN_AS_FALLBACK
210 # define optional_CONFIG_ALIGN_AS_FALLBACK double
215 #if defined(__clang__)
216 # pragma clang diagnostic push
217 # pragma clang diagnostic ignored "-Wundef"
218 #elif defined(__GNUC__)
219 # pragma GCC diagnostic push
220 # pragma GCC diagnostic ignored "-Wundef"
221 #elif defined(_MSC_VER )
222 # pragma warning( push )
226 #define optional_BETWEEN( v, lo, hi ) ( (lo) <= (v) && (v) < (hi) )
242 #if defined(_MSC_VER ) && !defined(__clang__)
243 # define optional_COMPILER_MSVC_VER (_MSC_VER )
244 # define optional_COMPILER_MSVC_VERSION (_MSC_VER / 10 - 10 * ( 5 + (_MSC_VER < 1900 ) ) )
246 # define optional_COMPILER_MSVC_VER 0
247 # define optional_COMPILER_MSVC_VERSION 0
250 #define optional_COMPILER_VERSION( major, minor, patch ) ( 10 * (10 * (major) + (minor) ) + (patch) )
252 #if defined(__GNUC__) && !defined(__clang__)
253 # define optional_COMPILER_GNUC_VERSION optional_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
255 # define optional_COMPILER_GNUC_VERSION 0
258 #if defined(__clang__)
259 # define optional_COMPILER_CLANG_VERSION optional_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__)
261 # define optional_COMPILER_CLANG_VERSION 0
264 #if optional_BETWEEN(optional_COMPILER_MSVC_VERSION, 70, 140 )
265 # pragma warning( disable: 4345 ) // initialization behavior changed
268 #if optional_BETWEEN(optional_COMPILER_MSVC_VERSION, 70, 150 )
269 # pragma warning( disable: 4814 ) // in C++14 'constexpr' will not imply 'const'
274 #define optional_HAVE(FEATURE) ( optional_HAVE_##FEATURE )
277 # define optional_HAS_CPP0X _HAS_CPP0X
279 # define optional_HAS_CPP0X 0
284 #if optional_COMPILER_MSVC_VER >= 1900
285 # undef optional_CPP11_OR_GREATER
286 # define optional_CPP11_OR_GREATER 1
289 #define optional_CPP11_90 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1500)
290 #define optional_CPP11_100 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1600)
291 #define optional_CPP11_110 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1700)
292 #define optional_CPP11_120 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1800)
293 #define optional_CPP11_140 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1900)
294 #define optional_CPP11_141 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1910)
296 #define optional_CPP11_140_490 ((optional_CPP11_OR_GREATER_ && optional_COMPILER_GNUC_VERSION >= 490) || (optional_COMPILER_MSVC_VER >= 1910))
298 #define optional_CPP14_000 (optional_CPP14_OR_GREATER)
299 #define optional_CPP17_000 (optional_CPP17_OR_GREATER)
303 #define optional_HAVE_CONSTEXPR_11 optional_CPP11_140
304 #define optional_HAVE_IS_DEFAULT optional_CPP11_140
305 #define optional_HAVE_NOEXCEPT optional_CPP11_140
306 #define optional_HAVE_NULLPTR optional_CPP11_100
307 #define optional_HAVE_REF_QUALIFIER optional_CPP11_140_490
308 #define optional_HAVE_INITIALIZER_LIST optional_CPP11_140
312 #define optional_HAVE_CONSTEXPR_14 optional_CPP14_000
316 #define optional_HAVE_NODISCARD optional_CPP17_000
320 #define optional_HAVE_CONDITIONAL optional_CPP11_120
321 #define optional_HAVE_REMOVE_CV optional_CPP11_120
322 #define optional_HAVE_TYPE_TRAITS optional_CPP11_90
324 #define optional_HAVE_TR1_TYPE_TRAITS (!! optional_COMPILER_GNUC_VERSION )
325 #define optional_HAVE_TR1_ADD_POINTER (!! optional_COMPILER_GNUC_VERSION )
329 #if optional_HAVE( CONSTEXPR_11 )
330 # define optional_constexpr constexpr
332 # define optional_constexpr
335 #if optional_HAVE( IS_DEFAULT )
336 # define optional_is_default = default;
338 # define optional_is_default {}
341 #if optional_HAVE( CONSTEXPR_14 )
342 # define optional_constexpr14 constexpr
344 # define optional_constexpr14
347 #if optional_HAVE( NODISCARD )
348 # define optional_nodiscard [[nodiscard]]
350 # define optional_nodiscard
353 #if optional_HAVE( NOEXCEPT )
354 # define optional_noexcept noexcept
356 # define optional_noexcept
359 #if optional_HAVE( NULLPTR )
360 # define optional_nullptr nullptr
362 # define optional_nullptr NULL
365 #if optional_HAVE( REF_QUALIFIER )
367 # define optional_ref_qual &
368 # define optional_refref_qual &&
370 # define optional_ref_qual
371 # define optional_refref_qual
376 #if optional_CONFIG_NO_EXCEPTIONS
379 # include <stdexcept>
382 #if optional_CPP11_OR_GREATER
383 # include <functional>
386 #if optional_HAVE( INITIALIZER_LIST )
387 # include <initializer_list>
390 #if optional_HAVE( TYPE_TRAITS )
391 # include <type_traits>
392 #elif optional_HAVE( TR1_TYPE_TRAITS )
393 # include <tr1/type_traits>
398 #if optional_CPP11_OR_GREATER
400 #define optional_REQUIRES_0(...) \
401 template< bool B = (__VA_ARGS__), typename std::enable_if<B, int>::type = 0 >
403 #define optional_REQUIRES_T(...) \
404 , typename std::enable_if< (__VA_ARGS__), int >::type = 0
406 #define optional_REQUIRES_R(R, ...) \
407 typename std::enable_if< (__VA_ARGS__), R>::type
409 #define optional_REQUIRES_A(...) \
410 , typename std::enable_if< (__VA_ARGS__), void*>::type = nullptr
418 namespace nonstd {
namespace optional_lite {
422 #if optional_CPP11_OR_GREATER
425 template<
typename T > T & move( T & t ) {
return t; }
428 #if optional_HAVE( CONDITIONAL )
429 using std::conditional;
431 template<
bool B,
typename T,
typename F >
struct conditional {
typedef T type; };
432 template<
typename T,
typename F >
struct conditional<false, T, F> {
typedef F type; };
433 #endif // optional_HAVE_CONDITIONAL
436 #if optional_CPP11_OR_GREATER
437 #if optional_BETWEEN( optional_COMPILER_GNUC_VERSION, 1, 500 )
438 template<
typename T >
struct is_trivially_copy_constructible : std::true_type{};
439 template<
typename T >
struct is_trivially_move_constructible : std::true_type{};
441 using std::is_trivially_copy_constructible;
442 using std::is_trivially_move_constructible;
447 #if optional_CPP11_OR_GREATER
453 #if optional_CPP17_OR_GREATER
455 using std::is_swappable;
456 using std::is_nothrow_swappable;
458 #elif optional_CPP11_OR_GREATER
466 template< typename T, typename = decltype( swap( std::declval<T&>(), std::declval<T&>() ) ) >
467 static std::true_type test(
int );
470 static std::false_type test(...);
473 struct is_nothrow_swappable
477 template<
typename T >
478 static constexpr
bool satisfies()
480 return noexcept( swap( std::declval<T&>(), std::declval<T&>() ) );
483 template<
typename T >
484 static auto test(
int ) -> std::integral_constant<bool, satisfies<T>()>{}
487 static auto test(...) -> std::false_type;
494 template<
typename T >
495 struct is_swappable : decltype( detail::is_swappable::test<T>(0) ){};
497 template<
typename T >
498 struct is_nothrow_swappable : decltype( detail::is_nothrow_swappable::test<T>(0) ){};
500 #endif // optional_CPP17_OR_GREATER
508 template<
typename T >
511 typedef typename std::remove_cv< typename std::remove_reference<T>::type >::type type;
516 #endif // optional_CPP11_OR_GREATER
520 template<
typename T >
529 template<
typename Head,
typename Tail >
536 #if optional_CONFIG_MAX_ALIGN_HACK
540 #define optional_UNIQUE( name ) optional_UNIQUE2( name, __LINE__ )
541 #define optional_UNIQUE2( name, line ) optional_UNIQUE3( name, line )
542 #define optional_UNIQUE3( name, line ) name ## line
544 #define optional_ALIGN_TYPE( type ) \
545 type optional_UNIQUE( _t ); struct_t< type > optional_UNIQUE( _st )
547 template<
typename T >
552 optional_ALIGN_TYPE(
char );
553 optional_ALIGN_TYPE(
short int );
554 optional_ALIGN_TYPE(
int );
555 optional_ALIGN_TYPE(
long int );
556 optional_ALIGN_TYPE(
float );
557 optional_ALIGN_TYPE(
double );
558 optional_ALIGN_TYPE(
long double );
559 optional_ALIGN_TYPE(
char * );
560 optional_ALIGN_TYPE(
short int * );
561 optional_ALIGN_TYPE(
int * );
562 optional_ALIGN_TYPE(
long int * );
563 optional_ALIGN_TYPE(
float * );
564 optional_ALIGN_TYPE(
double * );
565 optional_ALIGN_TYPE(
long double * );
566 optional_ALIGN_TYPE(
void * );
568 #ifdef HAVE_LONG_LONG
569 optional_ALIGN_TYPE(
long long );
574 Unknown ( * optional_UNIQUE(_) )( Unknown );
575 Unknown * Unknown::* optional_UNIQUE(_);
576 Unknown ( Unknown::* optional_UNIQUE(_) )( Unknown );
578 struct_t< Unknown ( * )( Unknown) > optional_UNIQUE(_);
579 struct_t< Unknown * Unknown::* > optional_UNIQUE(_);
580 struct_t< Unknown ( Unknown::* )(Unknown) > optional_UNIQUE(_);
583 #undef optional_UNIQUE
584 #undef optional_UNIQUE2
585 #undef optional_UNIQUE3
587 #undef optional_ALIGN_TYPE
589 #elif defined( optional_CONFIG_ALIGN_AS ) // optional_CONFIG_MAX_ALIGN_HACK
593 #define optional_ALIGN_AS( unused ) \
594 optional_CONFIG_ALIGN_AS
596 #else // optional_CONFIG_MAX_ALIGN_HACK
600 #define optional_ALIGN_AS( to_align ) \
601 typename type_of_size< alignment_types, alignment_of< to_align >::value >::type
603 template<
typename T >
606 template<
typename T >
614 template<
size_t A,
size_t S >
617 enum { value = A < S ? A : S };
620 template<
typename T >
627 template<
typename List,
size_t N >
631 N ==
sizeof(
typename List::head ),
633 typename type_of_size<typename List::tail, N >::type >::type type;
639 typedef optional_CONFIG_ALIGN_AS_FALLBACK type;
642 template<
typename T>
645 #define optional_ALIGN_TYPE( type ) \
646 typelist< type , typelist< struct_t< type >
651 optional_ALIGN_TYPE(
char ),
652 optional_ALIGN_TYPE(
short ),
653 optional_ALIGN_TYPE(
int ),
654 optional_ALIGN_TYPE(
long ),
655 optional_ALIGN_TYPE(
float ),
656 optional_ALIGN_TYPE(
double ),
657 optional_ALIGN_TYPE(
long double ),
659 optional_ALIGN_TYPE(
char *),
660 optional_ALIGN_TYPE(
short * ),
661 optional_ALIGN_TYPE(
int * ),
662 optional_ALIGN_TYPE(
long * ),
663 optional_ALIGN_TYPE(
float * ),
664 optional_ALIGN_TYPE(
double * ),
665 optional_ALIGN_TYPE(
long double * ),
667 optional_ALIGN_TYPE( Unknown ( * )( Unknown ) ),
668 optional_ALIGN_TYPE( Unknown * Unknown::* ),
669 optional_ALIGN_TYPE( Unknown ( Unknown::* )( Unknown ) ),
672 > > > > > > > > > > > > > >
673 > > > > > > > > > > > > > >
677 #undef optional_ALIGN_TYPE
679 #endif // optional_CONFIG_MAX_ALIGN_HACK
683 template<
typename T >
689 typedef T value_type;
693 explicit storage_t( value_type
const & v )
695 construct_value( v );
698 void construct_value( value_type
const & v )
700 ::new( value_ptr() ) value_type( v );
703 #if optional_CPP11_OR_GREATER
707 construct_value( std::move( v ) );
710 void construct_value( value_type && v )
712 ::new( value_ptr() ) value_type( std::move( v ) );
715 template<
class... Args >
716 void emplace( Args&&... args )
718 ::new( value_ptr() ) value_type( std::forward<Args>(args)... );
721 template<
class U,
class... Args >
722 void emplace( std::initializer_list<U> il, Args&&... args )
724 ::new( value_ptr() ) value_type( il, std::forward<Args>(args)... );
729 void destruct_value()
734 optional_nodiscard value_type
const * value_ptr()
const
736 return as<value_type>();
739 value_type * value_ptr()
741 return as<value_type>();
744 optional_nodiscard value_type
const & value()
const optional_ref_qual
746 return * value_ptr();
749 value_type & value() optional_ref_qual
751 return * value_ptr();
754 #if optional_HAVE( REF_QUALIFIER )
756 optional_nodiscard value_type
const && value()
const optional_refref_qual
758 return std::move( value() );
761 value_type && value() optional_refref_qual
763 return std::move( value() );
768 #if optional_CPP11_OR_GREATER
770 using aligned_storage_t =
typename std::aligned_storage<
sizeof(value_type),
alignof(value_type) >::type;
773 #elif optional_CONFIG_MAX_ALIGN_HACK
781 typedef optional_ALIGN_AS(value_type) align_as_type;
783 typedef struct { align_as_type data[ 1 + (
sizeof(value_type) - 1 ) /
sizeof(align_as_type) ]; }
aligned_storage_t;
786 # undef optional_ALIGN_AS
788 #endif // optional_CONFIG_MAX_ALIGN_HACK
790 optional_nodiscard
void * ptr() optional_noexcept
795 optional_nodiscard
void const * ptr() const optional_noexcept
800 template <
typename U>
801 optional_nodiscard U * as()
803 return reinterpret_cast<U*
>( ptr() );
806 template <
typename U>
807 optional_nodiscard U
const * as()
const
809 return reinterpret_cast<U
const *
>( ptr() );
820 explicit optional_constexpr
nullopt_t(
init ) optional_noexcept {}
823 #if optional_HAVE( CONSTEXPR_11 )
827 const nullopt_t nullopt(( nullopt_t::init() ));
832 #if ! optional_CONFIG_NO_EXCEPTIONS
834 class bad_optional_access :
public std::logic_error
837 explicit bad_optional_access()
838 : logic_error(
"bad optional access" ) {}
841 #endif //optional_CONFIG_NO_EXCEPTIONS
845 template<
typename T>
849 template<
typename >
friend class optional;
851 typedef void (optional::*safe_bool)()
const;
854 typedef T value_type;
859 optional_constexpr optional() optional_noexcept
860 : has_value_( false )
866 optional_constexpr optional( nullopt_t ) optional_noexcept
867 : has_value_(
false )
872 #if optional_CPP11_OR_GREATER
880 optional_constexpr14 optional( optional
const & other )
881 : has_value_( other.has_value() )
883 if ( other.has_value() )
885 contained.construct_value( other.contained.value() );
889 #if optional_CPP11_OR_GREATER
892 template<
typename U = T
894 std::is_move_constructible<U>::value
895 || std11::is_trivially_move_constructible<U>::value
898 optional_constexpr14 optional( optional && other )
900 noexcept( std::is_nothrow_move_constructible<T>::value )
901 : has_value_( other.has_value() )
903 if ( other.has_value() )
905 contained.construct_value( std::move( other.contained.value() ) );
912 std::is_constructible<T, U const &>::value
913 && !std::is_constructible<T, optional<U> & >::value
914 && !std::is_constructible<T, optional<U> && >::value
915 && !std::is_constructible<T, optional<U>
const & >::value
916 && !std::is_constructible<T, optional<U>
const && >::value
917 && !std::is_convertible< optional<U> & , T>::value
918 && !std::is_convertible< optional<U> && , T>::value
919 && !std::is_convertible< optional<U>
const & , T>::value
920 && !std::is_convertible< optional<U>
const &&, T>::value
921 && !std::is_convertible< U const & , T>::value
924 explicit optional( optional<U>
const & other )
925 : has_value_( other.has_value() )
927 if ( other.has_value() )
929 contained.construct_value( T{ other.contained.value() } );
932 #endif // optional_CPP11_OR_GREATER
936 #if optional_CPP11_OR_GREATER
938 std::is_constructible<T, U const &>::value
939 && !std::is_constructible<T, optional<U> & >::value
940 && !std::is_constructible<T, optional<U> && >::value
941 && !std::is_constructible<T, optional<U>
const & >::value
942 && !std::is_constructible<T, optional<U>
const && >::value
943 && !std::is_convertible< optional<U> & , T>::value
944 && !std::is_convertible< optional<U> && , T>::value
945 && !std::is_convertible< optional<U>
const & , T>::value
946 && !std::is_convertible< optional<U>
const &&, T>::value
947 && std::is_convertible< U const & , T>::value
949 #endif // optional_CPP11_OR_GREATER
952 optional( optional<U>
const & other )
953 : has_value_( other.has_value() )
955 if ( other.has_value() )
957 contained.construct_value( other.contained.value() );
961 #if optional_CPP11_OR_GREATER
966 std::is_constructible<T, U &&>::value
967 && !std::is_constructible<T, optional<U> & >::value
968 && !std::is_constructible<T, optional<U> && >::value
969 && !std::is_constructible<T, optional<U>
const & >::value
970 && !std::is_constructible<T, optional<U>
const && >::value
971 && !std::is_convertible< optional<U> & , T>::value
972 && !std::is_convertible< optional<U> && , T>::value
973 && !std::is_convertible< optional<U>
const & , T>::value
974 && !std::is_convertible< optional<U>
const &&, T>::value
975 && !std::is_convertible< U &&, T>::value
978 explicit optional( optional<U> && other
980 : has_value_( other.has_value() )
982 if ( other.has_value() )
984 contained.construct_value( T{ std::move( other.contained.value() ) } );
991 std::is_constructible<T, U &&>::value
992 && !std::is_constructible<T, optional<U> & >::value
993 && !std::is_constructible<T, optional<U> && >::value
994 && !std::is_constructible<T, optional<U>
const & >::value
995 && !std::is_constructible<T, optional<U>
const && >::value
996 && !std::is_convertible< optional<U> & , T>::value
997 && !std::is_convertible< optional<U> && , T>::value
998 && !std::is_convertible< optional<U>
const & , T>::value
999 && !std::is_convertible< optional<U>
const &&, T>::value
1000 && std::is_convertible< U &&, T>::value
1004 optional( optional<U> && other )
1005 : has_value_( other.has_value() )
1007 if ( other.has_value() )
1009 contained.construct_value( std::move( other.contained.value() ) );
1014 template<
typename... Args
1015 optional_REQUIRES_T(
1016 std::is_constructible<T, Args&&...>::value
1019 optional_constexpr
explicit optional( nonstd_lite_in_place_t(T), Args&&... args )
1020 : has_value_( true )
1021 , contained( T( std::forward<Args>(args)...) )
1025 template<
typename U,
typename... Args
1026 optional_REQUIRES_T(
1027 std::is_constructible<T, std::initializer_list<U>&, Args&&...>::value
1030 optional_constexpr
explicit optional( nonstd_lite_in_place_t(T), std::initializer_list<U> il, Args&&... args )
1031 : has_value_( true )
1032 , contained( T( il, std::forward<Args>(args)...) )
1036 template<
typename U = T
1037 optional_REQUIRES_T(
1038 std::is_constructible<T, U&&>::value
1039 && !std::is_same<
typename std20::remove_cvref<U>::type, nonstd_lite_in_place_t(U)>::value
1040 && !std::is_same<
typename std20::remove_cvref<U>::type, optional<T>>::value
1041 && !std::is_convertible<U&&, T>::value
1044 optional_constexpr
explicit optional( U && value )
1045 : has_value_( true )
1046 , contained( T{ std::forward<U>( value ) } )
1050 template<
typename U = T
1051 optional_REQUIRES_T(
1052 std::is_constructible<T, U&&>::value
1053 && !std::is_same<
typename std20::remove_cvref<U>::type, nonstd_lite_in_place_t(U)>::value
1054 && !std::is_same<
typename std20::remove_cvref<U>::type, optional<T>>::value
1055 && std::is_convertible<U&&, T>::value
1059 optional_constexpr optional( U && value )
1060 : has_value_( true )
1061 , contained( std::forward<U>( value ) )
1064 #else // optional_CPP11_OR_GREATER
1067 optional( value_type
const & value )
1068 : has_value_( true )
1069 , contained( value )
1072 #endif // optional_CPP11_OR_GREATER
1080 contained.destruct_value();
1087 optional & operator=( nullopt_t ) optional_noexcept
1094 #if optional_CPP11_OR_GREATER
1096 optional_REQUIRES_R(
1102 operator=( optional const & other )
1104 std::is_nothrow_move_assignable<T>::value
1105 && std::is_nothrow_move_constructible<T>::value
1108 optional & operator=( optional
const & other )
1111 if ( (has_value() ==
true ) && (other.has_value() ==
false) ) { reset(); }
1112 else if ( (has_value() ==
false) && (other.has_value() ==
true ) ) { initialize( *other ); }
1113 else if ( (has_value() ==
true ) && (other.has_value() ==
true ) ) { contained.value() = *other; }
1117 #if optional_CPP11_OR_GREATER
1121 optional_REQUIRES_R(
1127 operator=( optional && other ) noexcept
1129 if ( (has_value() ==
true ) && (other.has_value() ==
false) ) { reset(); }
1130 else if ( (has_value() ==
false) && (other.has_value() ==
true ) ) { initialize( std::move( *other ) ); }
1131 else if ( (has_value() ==
true ) && (other.has_value() ==
true ) ) { contained.value() = std::move( *other ); }
1136 template<
typename U = T >
1138 optional_REQUIRES_R(
1140 std::is_constructible<T , U>::value
1141 && std::is_assignable<T&, U>::value
1142 && !std::is_same<
typename std20::remove_cvref<U>::type, nonstd_lite_in_place_t(U)>::value
1143 && !std::is_same<
typename std20::remove_cvref<U>::type, optional<T>>::value
1144 && !(std::is_scalar<T>::value && std::is_same<T,
typename std::decay<U>::type>::value)
1146 operator=( U && value )
1150 contained.value() = std::forward<U>( value );
1154 initialize( T( std::forward<U>( value ) ) );
1159 #else // optional_CPP11_OR_GREATER
1162 template<
typename U >
1163 optional & operator=( U
const & value )
1165 if ( has_value() ) contained.value() = value;
1166 else initialize( T( value ) );
1170 #endif // optional_CPP11_OR_GREATER
1173 template<
typename U >
1174 #if optional_CPP11_OR_GREATER
1176 optional_REQUIRES_R(
1178 std::is_constructible< T , U const &>::value
1179 && std::is_assignable< T&, U const &>::value
1180 && !std::is_constructible<T, optional<U> & >::value
1181 && !std::is_constructible<T, optional<U> && >::value
1182 && !std::is_constructible<T, optional<U>
const & >::value
1183 && !std::is_constructible<T, optional<U>
const && >::value
1184 && !std::is_convertible< optional<U> & , T>::value
1185 && !std::is_convertible< optional<U> && , T>::value
1186 && !std::is_convertible< optional<U>
const & , T>::value
1187 && !std::is_convertible< optional<U>
const &&, T>::value
1188 && !std::is_assignable< T&, optional<U> & >::value
1189 && !std::is_assignable< T&, optional<U> && >::value
1190 && !std::is_assignable< T&, optional<U>
const & >::value
1191 && !std::is_assignable< T&, optional<U>
const && >::value
1195 #endif // optional_CPP11_OR_GREATER
1196 operator=( optional<U>
const & other )
1198 return *
this = optional( other );
1201 #if optional_CPP11_OR_GREATER
1204 template<
typename U >
1206 optional_REQUIRES_R(
1208 std::is_constructible< T , U>::value
1209 && std::is_assignable< T&, U>::value
1210 && !std::is_constructible<T, optional<U> & >::value
1211 && !std::is_constructible<T, optional<U> && >::value
1212 && !std::is_constructible<T, optional<U>
const & >::value
1213 && !std::is_constructible<T, optional<U>
const && >::value
1214 && !std::is_convertible< optional<U> & , T>::value
1215 && !std::is_convertible< optional<U> && , T>::value
1216 && !std::is_convertible< optional<U>
const & , T>::value
1217 && !std::is_convertible< optional<U>
const &&, T>::value
1218 && !std::is_assignable< T&, optional<U> & >::value
1219 && !std::is_assignable< T&, optional<U> && >::value
1220 && !std::is_assignable< T&, optional<U>
const & >::value
1221 && !std::is_assignable< T&, optional<U>
const && >::value
1223 operator=( optional<U> && other )
1225 return *
this = optional( std::move( other ) );
1229 template<
typename... Args
1230 optional_REQUIRES_T(
1231 std::is_constructible<T, Args&&...>::value
1234 T& emplace( Args&&... args )
1237 contained.emplace( std::forward<Args>(args)... );
1239 return contained.value();
1243 template<
typename U,
typename... Args
1244 optional_REQUIRES_T(
1245 std::is_constructible<T, std::initializer_list<U>&, Args&&...>::value
1248 T& emplace( std::initializer_list<U> il, Args&&... args )
1251 contained.emplace( il, std::forward<Args>(args)... );
1253 return contained.value();
1256 #endif // optional_CPP11_OR_GREATER
1260 void swap( optional & other )
1261 #if optional_CPP11_OR_GREATER
1263 std::is_nothrow_move_constructible<T>::value
1264 && std17::is_nothrow_swappable<T>::value
1269 if ( (has_value() ==
true ) && (other.has_value() ==
true ) ) { swap( **
this, *other ); }
1270 else if ( (has_value() ==
false) && (other.has_value() ==
true ) ) { initialize( std11::move(*other) ); other.reset(); }
1271 else if ( (has_value() ==
true ) && (other.has_value() ==
false) ) { other.initialize( std11::move(**
this) ); reset(); }
1276 optional_constexpr value_type
const * operator ->()
const
1278 return assert( has_value() ),
1279 contained.value_ptr();
1282 optional_constexpr14 value_type * operator ->()
1284 return assert( has_value() ),
1285 contained.value_ptr();
1288 optional_constexpr value_type
const & operator *() const optional_ref_qual
1290 return assert( has_value() ),
1294 optional_constexpr14 value_type & operator *() optional_ref_qual
1296 return assert( has_value() ),
1300 #if optional_HAVE( REF_QUALIFIER )
1302 optional_constexpr value_type
const && operator *() const optional_refref_qual
1304 return std::move( **
this );
1307 optional_constexpr14 value_type && operator *() optional_refref_qual
1309 return std::move( **
this );
1314 #if optional_CPP11_OR_GREATER
1315 optional_constexpr
explicit operator bool() const optional_noexcept
1320 optional_constexpr
operator safe_bool() const optional_noexcept
1322 return has_value() ? &optional::this_type_does_not_support_comparisons : 0;
1327 optional_constexpr
bool has_value() const optional_noexcept
1333 optional_constexpr14 value_type
const & value() const optional_ref_qual
1335 #if optional_CONFIG_NO_EXCEPTIONS
1336 assert( has_value() );
1338 if ( ! has_value() )
1340 throw bad_optional_access();
1343 return contained.value();
1346 optional_constexpr14 value_type & value() optional_ref_qual
1348 #if optional_CONFIG_NO_EXCEPTIONS
1349 assert( has_value() );
1351 if ( ! has_value() )
1353 throw bad_optional_access();
1356 return contained.value();
1359 #if optional_HAVE( REF_QUALIFIER ) && ( !optional_COMPILER_GNUC_VERSION || optional_COMPILER_GNUC_VERSION >= 490 )
1362 optional_constexpr value_type
const && value() const optional_refref_qual
1364 return std::move( value() );
1367 optional_constexpr14 value_type && value() optional_refref_qual
1369 return std::move( value() );
1374 #if optional_CPP11_OR_GREATER
1376 template<
typename U >
1377 optional_constexpr value_type value_or( U && v )
const optional_ref_qual
1379 return has_value() ? contained.value() :
static_cast<T
>(std::forward<U>( v ) );
1382 template<
typename U >
1383 optional_constexpr14 value_type value_or( U && v ) optional_refref_qual
1385 return has_value() ? std::move( contained.value() ) : static_cast<T>(std::forward<U>( v ) );
1390 template<
typename U >
1391 optional_constexpr value_type value_or( U
const & v )
const
1393 return has_value() ? contained.value() :
static_cast<value_type
>( v );
1396 #endif // optional_CPP11_OR_GREATER
1400 void reset() optional_noexcept
1404 contained.destruct_value();
1411 void this_type_does_not_support_comparisons()
const {}
1413 template<
typename V >
1414 void initialize( V
const & value )
1416 assert( ! has_value() );
1417 contained.construct_value( value );
1421 #if optional_CPP11_OR_GREATER
1422 template<
typename V >
1423 void initialize( V && value )
1425 assert( ! has_value() );
1426 contained.construct_value( std::move( value ) );
1434 detail::storage_t< value_type > contained;
1440 template<
typename T,
typename U >
1441 inline optional_constexpr
bool operator==( optional<T>
const & x, optional<U>
const & y )
1443 return bool(x) != bool(y) ? false : !bool( x ) ? true : *x == *y;
1446 template<
typename T,
typename U >
1447 inline optional_constexpr
bool operator!=( optional<T>
const & x, optional<U>
const & y )
1452 template<
typename T,
typename U >
1453 inline optional_constexpr
bool operator<( optional<T>
const & x, optional<U>
const & y )
1455 return (!y) ? false : (!x) ?
true : *x < *y;
1458 template<
typename T,
typename U >
1459 inline optional_constexpr
bool operator>( optional<T>
const & x, optional<U>
const & y )
1464 template<
typename T,
typename U >
1465 inline optional_constexpr
bool operator<=( optional<T>
const & x, optional<U>
const & y )
1470 template<
typename T,
typename U >
1471 inline optional_constexpr
bool operator>=( optional<T>
const & x, optional<U>
const & y )
1478 template<
typename T >
1479 inline optional_constexpr
bool operator==( optional<T>
const & x, nullopt_t ) optional_noexcept
1484 template<
typename T >
1485 inline optional_constexpr
bool operator==( nullopt_t , optional<T>
const & x ) optional_noexcept
1490 template<
typename T >
1491 inline optional_constexpr
bool operator!=( optional<T>
const & x, nullopt_t ) optional_noexcept
1496 template<
typename T >
1497 inline optional_constexpr
bool operator!=( nullopt_t , optional<T>
const & x ) optional_noexcept
1502 template<
typename T >
1503 inline optional_constexpr
bool operator<( optional<T>
const & , nullopt_t ) optional_noexcept
1508 template<
typename T >
1509 inline optional_constexpr
bool operator<( nullopt_t , optional<T>
const & x ) optional_noexcept
1514 template<
typename T >
1515 inline optional_constexpr
bool operator<=( optional<T>
const & x, nullopt_t ) optional_noexcept
1520 template<
typename T >
1521 inline optional_constexpr
bool operator<=( nullopt_t , optional<T>
const & ) optional_noexcept
1526 template<
typename T >
1527 inline optional_constexpr
bool operator>( optional<T>
const & x, nullopt_t ) optional_noexcept
1532 template<
typename T >
1533 inline optional_constexpr
bool operator>( nullopt_t , optional<T>
const & ) optional_noexcept
1538 template<
typename T >
1539 inline optional_constexpr
bool operator>=( optional<T>
const & , nullopt_t ) optional_noexcept
1544 template<
typename T >
1545 inline optional_constexpr
bool operator>=( nullopt_t , optional<T>
const & x ) optional_noexcept
1552 template<
typename T,
typename U >
1553 inline optional_constexpr
bool operator==( optional<T>
const & x, U
const & v )
1555 return bool(x) ? *x == v :
false;
1558 template<
typename T,
typename U >
1559 inline optional_constexpr
bool operator==( U
const & v, optional<T>
const & x )
1561 return bool(x) ? v == *x :
false;
1564 template<
typename T,
typename U >
1565 inline optional_constexpr
bool operator!=( optional<T>
const & x, U
const & v )
1567 return bool(x) ? *x != v :
true;
1570 template<
typename T,
typename U >
1571 inline optional_constexpr
bool operator!=( U
const & v, optional<T>
const & x )
1573 return bool(x) ? v != *x :
true;
1576 template<
typename T,
typename U >
1577 inline optional_constexpr
bool operator<( optional<T>
const & x, U
const & v )
1579 return bool(x) ? *x < v :
true;
1582 template<
typename T,
typename U >
1583 inline optional_constexpr
bool operator<( U
const & v, optional<T>
const & x )
1585 return bool(x) ? v < *x :
false;
1588 template<
typename T,
typename U >
1589 inline optional_constexpr
bool operator<=( optional<T>
const & x, U
const & v )
1591 return bool(x) ? *x <= v :
true;
1594 template<
typename T,
typename U >
1595 inline optional_constexpr
bool operator<=( U
const & v, optional<T>
const & x )
1597 return bool(x) ? v <= *x :
false;
1600 template<
typename T,
typename U >
1601 inline optional_constexpr
bool operator>( optional<T>
const & x, U
const & v )
1603 return bool(x) ? *x > v :
false;
1606 template<
typename T,
typename U >
1607 inline optional_constexpr
bool operator>( U
const & v, optional<T>
const & x )
1609 return bool(x) ? v > *x :
true;
1612 template<
typename T,
typename U >
1613 inline optional_constexpr
bool operator>=( optional<T>
const & x, U
const & v )
1615 return bool(x) ? *x >= v :
false;
1618 template<
typename T,
typename U >
1619 inline optional_constexpr
bool operator>=( U
const & v, optional<T>
const & x )
1621 return bool(x) ? v >= *x :
true;
1626 template<
typename T
1627 #if optional_CPP11_OR_GREATER
1628 optional_REQUIRES_T(
1629 std::is_move_constructible<T>::value
1630 && std17::is_swappable<T>::value )
1633 void swap( optional<T> & x, optional<T> & y )
1634 #if optional_CPP11_OR_GREATER
1635 noexcept( noexcept( x.swap(y) ) )
1641 #if optional_CPP11_OR_GREATER
1643 template<
typename T >
1644 optional_constexpr optional< typename std::decay<T>::type > make_optional( T && value )
1646 return optional< typename std::decay<T>::type >( std::forward<T>( value ) );
1649 template<
typename T,
typename...Args >
1650 optional_constexpr optional<T> make_optional( Args&&... args )
1652 return optional<T>( nonstd_lite_in_place(T), std::forward<Args>(args)...);
1655 template<
typename T,
typename U,
typename... Args >
1656 optional_constexpr optional<T> make_optional( std::initializer_list<U> il, Args&&... args )
1658 return optional<T>( nonstd_lite_in_place(T), il, std::forward<Args>(args)...);
1663 template<
typename T >
1664 optional<T> make_optional( T
const & value )
1666 return optional<T>( value );
1669 #endif // optional_CPP11_OR_GREATER
1673 using optional_lite::optional;
1674 using optional_lite::nullopt_t;
1675 using optional_lite::nullopt;
1677 #if ! optional_CONFIG_NO_EXCEPTIONS
1678 using optional_lite::bad_optional_access;
1681 using optional_lite::make_optional;
1685 #if optional_CPP11_OR_GREATER
1692 struct hash< nonstd::optional<T> >
1697 return bool( v ) ? std::hash<T>{}( *v ) : 0;
1703 #endif // optional_CPP11_OR_GREATER
1705 #if defined(__clang__)
1706 # pragma clang diagnostic pop
1707 #elif defined(__GNUC__)
1708 # pragma GCC diagnostic pop
1709 #elif defined(_MSC_VER )
1710 # pragma warning( pop )
1713 #endif // optional_USES_STD_OPTIONAL
1715 #endif // NONSTD_OPTIONAL_LITE_HPP