11 #ifndef NONSTD_OPTIONAL_LITE_HPP 12 #define NONSTD_OPTIONAL_LITE_HPP 14 #define optional_lite_VERSION "3.1.0" 19 #ifndef optional_CPLUSPLUS 21 # define optional_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG ) 23 # define optional_CPLUSPLUS __cplusplus 27 #define optional_CPP98_OR_GREATER ( optional_CPLUSPLUS >= 199711L ) 28 #define optional_CPP11_OR_GREATER ( optional_CPLUSPLUS >= 201103L ) 29 #define optional_CPP14_OR_GREATER ( optional_CPLUSPLUS >= 201402L ) 30 #define optional_CPP17_OR_GREATER ( optional_CPLUSPLUS >= 201703L ) 31 #define optional_CPP20_OR_GREATER ( optional_CPLUSPLUS >= 202000L ) 35 #define optional_CPLUSPLUS_V ( optional_CPLUSPLUS / 100 - (optional_CPLUSPLUS > 200000 ? 2000 : 1994) ) 39 #if defined( __has_include ) 40 # define optional_HAS_INCLUDE( arg ) __has_include( arg ) 42 # define optional_HAS_INCLUDE( arg ) 0 45 #define optional_HAVE_STD_OPTIONAL ( optional_CPP17_OR_GREATER && optional_HAS_INCLUDE( <optional> ) ) 47 #if optional_HAVE_STD_OPTIONAL 54 using std::bad_optional_access;
62 using std::in_place_t;
63 using std::in_place_type_t;
64 using std::in_place_index_t;
66 using std::operator==;
67 using std::operator!=;
69 using std::operator<=;
71 using std::operator>=;
76 #else // C++17 std::optional 84 #ifndef optional_CONFIG_MAX_ALIGN_HACK 85 # define optional_CONFIG_MAX_ALIGN_HACK 0 88 #ifndef optional_CONFIG_ALIGN_AS 92 #ifndef optional_CONFIG_ALIGN_AS_FALLBACK 93 # define optional_CONFIG_ALIGN_AS_FALLBACK double 99 # pragma clang diagnostic push 100 # pragma clang diagnostic ignored "-Wundef" 101 #elif defined __GNUC__ 102 # pragma GCC diagnostic push 103 # pragma GCC diagnostic ignored "-Wundef" 107 #define optional_BETWEEN( v, lo, hi ) ( lo <= v && v < hi ) 109 #if defined(_MSC_VER) && !defined(__clang__) 110 # define optional_COMPILER_MSVC_VERSION (_MSC_VER / 10 - 10 * ( 5 + (_MSC_VER < 1900)) ) 112 # define optional_COMPILER_MSVC_VERSION 0 115 #define optional_COMPILER_VERSION( major, minor, patch ) ( 10 * (10 * major + minor ) + patch ) 118 # define optional_COMPILER_GNUC_VERSION optional_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) 120 # define optional_COMPILER_GNUC_VERSION 0 123 #if defined __clang__ 124 # define optional_COMPILER_CLANG_VERSION optional_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__) 126 # define optional_COMPILER_CLANG_VERSION 0 129 #if optional_BETWEEN(optional_COMPILER_MSVC_VERSION, 70, 140 ) 130 # pragma warning( push ) 131 # pragma warning( disable: 4345 ) // initialization behavior changed 134 #if optional_BETWEEN(optional_COMPILER_MSVC_VERSION, 70, 150 ) 135 # pragma warning( push ) 136 # pragma warning( disable: 4814 ) // in C++14 'constexpr' will not imply 'const' 141 #define optional_HAVE(FEATURE) ( optional_HAVE_##FEATURE ) 145 #if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 100 146 # define optional_HAVE_AUTO 1 147 # define optional_HAVE_NULLPTR 1 148 # define optional_HAVE_STATIC_ASSERT 1 151 #if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 120 152 # define optional_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG 1 153 # define optional_HAVE_INITIALIZER_LIST 1 156 #if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 140 157 # define optional_HAVE_ALIAS_TEMPLATE 1 158 # define optional_HAVE_CONSTEXPR_11 1 159 # define optional_HAVE_ENUM_CLASS 1 160 # define optional_HAVE_EXPLICIT_CONVERSION 1 161 # define optional_HAVE_IS_DEFAULT 1 162 # define optional_HAVE_IS_DELETE 1 163 # define optional_HAVE_NOEXCEPT 1 164 # define optional_HAVE_REF_QUALIFIER 1 169 #if optional_CPP14_OR_GREATER 170 # define optional_HAVE_CONSTEXPR_14 1 175 #if optional_CPP17_OR_GREATER 176 # define optional_HAVE_ENUM_CLASS_CONSTRUCTION_FROM_UNDERLYING_TYPE 1 181 #if optional_COMPILER_GNUC_VERSION 182 # define optional_HAVE_TR1_TYPE_TRAITS 1 183 # define optional_HAVE_TR1_ADD_POINTER 1 186 #if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 90 187 # define optional_HAVE_TYPE_TRAITS 1 188 # define optional_HAVE_STD_ADD_POINTER 1 191 #if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 110 192 # define optional_HAVE_ARRAY 1 195 #if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 120 196 # define optional_HAVE_CONDITIONAL 1 199 #if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 140 || (optional_COMPILER_MSVC_VERSION >= 90 && _HAS_CPP0X) 200 # define optional_HAVE_CONTAINER_DATA_METHOD 1 203 #if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 120 204 # define optional_HAVE_REMOVE_CV 1 207 #if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 140 208 # define optional_HAVE_SIZED_TYPES 1 213 #if optional_COMPILER_MSVC_VERSION >= 140 214 # undef optional_CPP11_OR_GREATER 215 # define optional_CPP11_OR_GREATER 1 220 #if optional_HAVE( CONSTEXPR_11 ) 221 # define optional_constexpr constexpr 223 # define optional_constexpr 226 #if optional_HAVE( CONSTEXPR_14 ) 227 # define optional_constexpr14 constexpr 229 # define optional_constexpr14 232 #if optional_HAVE( NOEXCEPT ) 233 # define optional_noexcept noexcept 235 # define optional_noexcept 238 #if optional_HAVE( NULLPTR ) 239 # define optional_nullptr nullptr 241 # define optional_nullptr NULL 244 #if optional_HAVE( REF_QUALIFIER ) 245 # define optional_ref_qual & 246 # define optional_refref_qual && 248 # define optional_ref_qual 249 # define optional_refref_qual 254 #if optional_CPP11_OR_GREATER 255 # include <functional> 258 #if optional_HAVE( INITIALIZER_LIST ) 259 # include <initializer_list> 262 #if optional_HAVE( TYPE_TRAITS ) 263 # include <type_traits> 264 #elif optional_HAVE( TR1_TYPE_TRAITS ) 265 # include <tr1/type_traits> 270 namespace BT {
namespace optional_lite {
namespace detail {
272 #if optional_HAVE( CONDITIONAL ) 273 using std::conditional;
276 template<
typename T,
typename F >
struct conditional<false, T, F> {
typedef F
type; };
277 #endif // optional_HAVE_CONDITIONAL 285 #ifndef nonstd_lite_HAVE_IN_PLACE_TYPES 294 template< std::
size_t I >
307 template< std::
size_t I >
319 template< std::
size_t I >
327 #define nonstd_lite_in_place_type_t( T) BT::in_place_t(&)( BT::detail::in_place_type_tag<T> ) 328 #define nonstd_lite_in_place_index_t(T) BT::in_place_t(&)( BT::detail::in_place_index_tag<I> ) 330 #define nonstd_lite_HAVE_IN_PLACE_TYPES 1 334 #endif // nonstd_lite_HAVE_IN_PLACE_TYPES 340 namespace BT {
namespace optional_lite {
344 template<
typename T >
353 template<
typename Head,
typename Tail >
360 #if optional_CONFIG_MAX_ALIGN_HACK 364 #define optional_UNIQUE( name ) optional_UNIQUE2( name, __LINE__ ) 365 #define optional_UNIQUE2( name, line ) optional_UNIQUE3( name, line ) 366 #define optional_UNIQUE3( name, line ) name ## line 368 #define optional_ALIGN_TYPE( type ) \ 369 type optional_UNIQUE( _t ); struct_t< type > optional_UNIQUE( _st ) 371 template<
typename T >
392 #ifdef HAVE_LONG_LONG 398 Unknown ( * optional_UNIQUE(_) )( Unknown );
399 Unknown * Unknown::* optional_UNIQUE(_);
400 Unknown ( Unknown::* optional_UNIQUE(_) )( Unknown );
407 #undef optional_UNIQUE 408 #undef optional_UNIQUE2 409 #undef optional_UNIQUE3 411 #undef optional_ALIGN_TYPE 413 #elif defined( optional_CONFIG_ALIGN_AS ) // optional_CONFIG_MAX_ALIGN_HACK 417 #define optional_ALIGN_AS( unused ) \ 418 optional_CONFIG_ALIGN_AS 420 #else // optional_CONFIG_MAX_ALIGN_HACK 424 #define optional_ALIGN_AS( to_align ) \ 425 typename type_of_size< alignment_types, alignment_of< to_align >::value >::type 427 template <
typename T>
430 template <
typename T>
438 template <
unsigned A,
unsigned S>
441 enum { value = A < S ? A : S };
444 template<
typename T >
451 template<
typename List,
size_t N >
455 N ==
sizeof(
typename List::head ),
466 template<
typename T>
469 #define optional_ALIGN_TYPE( type ) \ 470 typelist< type , typelist< struct_t< type > 496 > > > > > > > > > > > > > >
497 > > > > > > > > > > > > > >
501 #undef optional_ALIGN_TYPE 503 #endif // optional_CONFIG_MAX_ALIGN_HACK 507 template<
typename T >
519 construct_value( v );
524 ::new( value_ptr() ) value_type( v );
527 #if optional_CPP11_OR_GREATER 531 construct_value( std::move( v ) );
534 void construct_value( value_type && v )
536 ::new( value_ptr() ) value_type( std::move( v ) );
539 template<
class... Args >
540 void emplace( Args&&... args )
542 ::new( value_ptr() ) value_type( std::forward<Args>(args)... );
545 template<
class U,
class... Args >
546 void emplace( std::initializer_list<U> il, Args&&... args )
548 ::new( value_ptr() ) value_type( il, std::forward<Args>(args)... );
560 return as<value_type>();
565 return as<value_type>();
570 return * value_ptr();
575 return * value_ptr();
578 #if optional_CPP11_OR_GREATER 582 return std::move( value() );
587 return std::move( value() );
592 #if optional_CPP11_OR_GREATER 594 using aligned_storage_t =
typename std::aligned_storage< sizeof(value_type), alignof(value_type) >::type;
595 aligned_storage_t
data;
597 #elif optional_CONFIG_MAX_ALIGN_HACK 599 typedef struct {
unsigned char data[
sizeof(value_type) ]; } aligned_storage_t;
602 aligned_storage_t
data;
607 typedef struct { align_as_type data[ 1 + (
sizeof(value_type) - 1 ) /
sizeof(align_as_type) ]; } aligned_storage_t;
610 # undef optional_ALIGN_AS 612 #endif // optional_CONFIG_MAX_ALIGN_HACK 624 template <
typename U>
627 return reinterpret_cast<U*
>( ptr() );
630 template <
typename U>
633 return reinterpret_cast<U
const *
>( ptr() );
647 #if optional_HAVE( CONSTEXPR_11 ) 660 : logic_error(
"bad optional access" ) {}
665 template<
typename T>
675 : has_value_( false )
680 : has_value_( false )
685 : has_value_( rhs.has_value() )
691 #if optional_CPP11_OR_GREATER 693 : has_value_( rhs.has_value() )
695 if ( rhs.has_value() )
696 contained.construct_value( std::move( rhs.contained.value() ) );
705 #if optional_CPP11_OR_GREATER 709 , contained( std::move( value ) )
712 template<
class... Args >
715 , contained( T( std::forward<Args>(args)...) )
718 template<
class U,
class... Args >
721 , contained( T( il, std::forward<Args>(args)...) )
724 #endif // optional_CPP11_OR_GREATER 729 contained.destruct_value();
741 #if optional_CPP11_OR_GREATER 742 noexcept( std::is_nothrow_move_assignable<T>::value && std::is_nothrow_move_constructible<T>::value )
745 if ( has_value() ==
true && rhs.
has_value() == false ) reset();
746 else if ( has_value() ==
false && rhs.
has_value() == true ) initialize( *rhs );
747 else if ( has_value() ==
true && rhs.
has_value() == true ) contained.
value() = *rhs;
751 #if optional_CPP11_OR_GREATER 753 optional & operator=( optional && rhs ) noexcept
755 if ( has_value() ==
true && rhs.
has_value() == false ) reset();
756 else if ( has_value() ==
false && rhs.
has_value() == true ) initialize( std::move( *rhs ) );
757 else if ( has_value() ==
true && rhs.
has_value() == true ) contained.
value() = std::move( *rhs );
762 typename =
typename std::enable_if< std::is_same< typename std::decay<U>::type, T>::value >::type >
763 optional & operator=( U && v )
765 if ( has_value() ) contained.value() = std::forward<U>( v );
766 else initialize( T( std::forward<U>( v ) ) );
770 template<
class... Args >
771 void emplace( Args&&... args )
774 contained.emplace( std::forward<Args>(args)... );
779 template<
class U,
class... Args >
780 void emplace( std::initializer_list<U> il, Args&&... args )
783 contained.emplace( il, std::forward<Args>(args)... );
787 #endif // optional_CPP11_OR_GREATER 792 #if optional_CPP11_OR_GREATER 793 noexcept( std::is_nothrow_move_constructible<T>::value && noexcept(
std::swap( std::declval<T&>(), std::declval<T&>() ) ) )
797 if ( has_value() ==
true && rhs.
has_value() == true ) {
swap( **
this, *rhs ); }
798 else if ( has_value() ==
false && rhs.
has_value() == true ) { initialize( *rhs ); rhs.
reset(); }
799 else if ( has_value() ==
true && rhs.
has_value() == false ) { rhs.
initialize( **
this ); reset(); }
806 return assert( has_value() ),
807 contained.value_ptr();
812 return assert( has_value() ),
813 contained.value_ptr();
818 return assert( has_value() ),
824 return assert( has_value() ),
828 #if optional_CPP11_OR_GREATER 832 return std::move( **
this );
837 return std::move( **
this );
842 #if optional_CPP11_OR_GREATER 850 return has_value() ? &optional::this_type_does_not_support_comparisons : 0;
864 return contained.value();
872 return contained.value();
875 #if optional_HAVE( REF_QUALIFIER ) 879 return std::move( value() );
884 return std::move( value() );
889 #if optional_CPP11_OR_GREATER 894 return has_value() ? contained.value() :
static_cast<T
>(std::forward<U>( v ) );
900 return has_value() ? std::move( contained.value() ) : static_cast<T>(std::forward<U>( v ) );
908 return has_value() ? contained.value() :
static_cast<value_type
>( v );
911 #endif // optional_CPP11_OR_GREATER 918 contained.destruct_value();
926 template<
typename V >
929 assert( ! has_value() );
930 contained.construct_value( value );
934 #if optional_CPP11_OR_GREATER 935 template<
typename V >
936 void initialize( V && value )
938 assert( ! has_value() );
939 contained.construct_value( std::move( value ) );
953 template<
typename T,
typename U >
956 return bool(x) != bool(y) ?
false : !bool( x ) ?
true : *x == *y;
959 template<
typename T,
typename U >
965 template<
typename T,
typename U >
968 return (!y) ?
false : (!x) ?
true : *x < *y;
971 template<
typename T,
typename U >
977 template<
typename T,
typename U >
983 template<
typename T,
typename U >
991 template<
typename T >
997 template<
typename T >
1003 template<
typename T >
1009 template<
typename T >
1015 template<
typename T >
1021 template<
typename T >
1027 template<
typename T >
1033 template<
typename T >
1039 template<
typename T >
1045 template<
typename T >
1051 template<
typename T >
1057 template<
typename T >
1065 template<
typename T,
typename U >
1068 return bool(x) ? *x == v :
false;
1071 template<
typename T,
typename U >
1074 return bool(x) ? v == *x :
false;
1077 template<
typename T,
typename U >
1080 return bool(x) ? *x != v :
true;
1083 template<
typename T,
typename U >
1086 return bool(x) ? v != *x :
true;
1089 template<
typename T,
typename U >
1092 return bool(x) ? *x < v :
true;
1095 template<
typename T,
typename U >
1098 return bool(x) ? v < *x :
false;
1101 template<
typename T,
typename U >
1104 return bool(x) ? *x <= v :
true;
1107 template<
typename T,
typename U >
1110 return bool(x) ? v <= *x :
false;
1113 template<
typename T,
typename U >
1116 return bool(x) ? *x > v :
false;
1119 template<
typename T,
typename U >
1122 return bool(x) ? v > *x :
true;
1125 template<
typename T,
typename U >
1128 return bool(x) ? *x >= v :
false;
1131 template<
typename T,
typename U >
1134 return bool(x) ? v >= *x :
true;
1139 template<
typename T >
1141 #if optional_CPP11_OR_GREATER 1142 noexcept( noexcept( x.
swap(y) ) )
1148 #if optional_CPP11_OR_GREATER 1156 template<
class T,
class...Args >
1162 template<
class T,
class U,
class... Args >
1170 template<
typename T >
1176 #endif // optional_CPP11_OR_GREATER 1180 using namespace optional_lite;
1184 #if optional_CPP11_OR_GREATER 1191 struct hash< BT::optional<T> >
1196 return bool( v ) ? hash<T>()( *v ) : 0;
1202 #endif // optional_CPP11_OR_GREATER 1205 # pragma clang diagnostic pop 1206 #elif defined __GNUC__ 1207 # pragma GCC diagnostic pop 1210 #endif // have C++17 std::optional 1212 #endif // NONSTD_OPTIONAL_LITE_HPP
const T * data(const std::vector< T, Alloc > &v)
optional_constexpr bool operator>(U const &v, optional< T > const &x)
void * ptr() optional_noexcept
void const * ptr() const optional_noexcept
void swap(optional< T > &x, optional< T > &y)
in_place_t in_place_type(detail::in_place_type_tag< T >=detail::in_place_type_tag< T >())
#define optional_noexcept
#define optional_ref_qual
optional_constexpr nullopt_t(init)
optional_constexpr14 value_type const & value() const optional_ref_qual
optional & operator=(nullopt_t) optional_noexcept
optional_CONFIG_ALIGN_AS_FALLBACK type
void swap(linb::any &lhs, linb::any &rhs) noexcept
C++03 constructed union to hold value.
void this_type_does_not_support_comparisons() const
optional< T > make_optional(T const &v)
conditional< N==sizeof(typename List::head), typename List::head, typename type_of_size< typename List::tail, N >::type >::type type
optional_constexpr optional() optional_noexcept
optional & operator=(optional const &rhs)
value_type const & value() const optional_ref_qual
void initialize(V const &value)
optional(optional const &rhs)
#define nonstd_lite_in_place_type_t(T)
const nullopt_t nullopt((nullopt_t::init()))
optional_constexpr value_type value_or(U const &v) const
storage_t(value_type const &v)
in_place_t in_place(detail::in_place_index_tag< I >=detail::in_place_index_tag< I >())
#define optional_CONFIG_ALIGN_AS_FALLBACK
#define optional_refref_qual
optional_constexpr14 value_type & value() optional_ref_qual
optional_constexpr bool operator==(U const &v, optional< T > const &x)
optional_constexpr optional(nullopt_t) optional_noexcept
value_type & value() optional_ref_qual
#define optional_ALIGN_TYPE(type)
#define optional_constexpr14
void construct_value(value_type const &v)
optional_constexpr bool operator!=(U const &v, optional< T > const &x)
optional_constexpr bool has_value() const optional_noexcept
in_place_t in_place_index(detail::in_place_index_tag< I >=detail::in_place_index_tag< I >())
value_type const * value_ptr() const
void reset() optional_noexcept
optional_constexpr bool operator>=(U const &v, optional< T > const &x)
detail::storage_t< value_type > contained
#define optional_ALIGN_AS(to_align)
optional_constexpr optional(value_type const &value)
#define optional_constexpr