10# ifndef ___OPTIONAL_HPP___
11# define ___OPTIONAL_HPP___
14# include <type_traits>
15# include <initializer_list>
21# define TR2_OPTIONAL_REQUIRES(...) typename enable_if<__VA_ARGS__::value, bool>::type = false
24# if (__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)
25# define TR2_OPTIONAL_GCC_4_8_AND_HIGHER___
27# define TR2_OPTIONAL_GCC_4_8_AND_HIGHER___
30# if (__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)
31# define TR2_OPTIONAL_GCC_4_7_AND_HIGHER___
33# define TR2_OPTIONAL_GCC_4_7_AND_HIGHER___
36# if (__GNUC__ == 4) && (__GNUC_MINOR__ == 8) && (__GNUC_PATCHLEVEL__ >= 1)
37# define TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___
38# elif (__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)
39# define TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___
41# define TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___
45# if defined __clang_major__
46# if (__clang_major__ == 3 && __clang_minor__ >= 5)
47# define TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_
48# elif (__clang_major__ > 3)
49# define TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_
51# if defined TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_
52# define TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_
53# elif (__clang_major__ == 3 && __clang_minor__ == 4 && __clang_patchlevel__ >= 2)
54# define TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_
59# if (_MSC_VER >= 1900)
60# define TR2_OPTIONAL_MSVC_2015_AND_HIGHER___
65# if (__clang_major__ > 2) || (__clang_major__ == 2) && (__clang_minor__ >= 9)
66# define OPTIONAL_HAS_THIS_RVALUE_REFS 1
68# define OPTIONAL_HAS_THIS_RVALUE_REFS 0
70# elif defined TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___
71# define OPTIONAL_HAS_THIS_RVALUE_REFS 1
72# elif defined TR2_OPTIONAL_MSVC_2015_AND_HIGHER___
73# define OPTIONAL_HAS_THIS_RVALUE_REFS 1
75# define OPTIONAL_HAS_THIS_RVALUE_REFS 0
79# if defined TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___
80# define OPTIONAL_HAS_CONSTEXPR_INIT_LIST 1
81# define OPTIONAL_CONSTEXPR_INIT_LIST constexpr
83# define OPTIONAL_HAS_CONSTEXPR_INIT_LIST 0
84# define OPTIONAL_CONSTEXPR_INIT_LIST
87# if defined TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_ && (defined __cplusplus) && (__cplusplus != 201103L)
88# define OPTIONAL_HAS_MOVE_ACCESSORS 1
90# define OPTIONAL_HAS_MOVE_ACCESSORS 0
94# if (defined __cplusplus) && (__cplusplus == 201103L)
95# define OPTIONAL_MUTABLE_CONSTEXPR
97# define OPTIONAL_MUTABLE_CONSTEXPR constexpr
102namespace experimental{
105# if defined TR2_OPTIONAL_GCC_4_8_AND_HIGHER___
107# elif defined TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_
109# elif defined TR2_OPTIONAL_MSVC_2015_AND_HIGHER___
111# elif defined TR2_OPTIONAL_DISABLE_EMULATION_OF_TYPE_TRAITS
114 template <
typename T>
119# if (defined TR2_OPTIONAL_GCC_4_7_AND_HIGHER___)
121# elif defined TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_
123# elif defined TR2_OPTIONAL_MSVC_2015_AND_HIGHER___
125# elif defined TR2_OPTIONAL_DISABLE_EMULATION_OF_TYPE_TRAITS
134 constexpr static bool value = std::is_nothrow_constructible<T, T&&>::value;
138template <
class T,
class U>
141 template <
class X,
class Y>
144 template <class X, class Y, size_t S = sizeof((std::declval<X>() = std::declval<Y>(),
true)) >
148 constexpr static bool value = has_assign<T, U>(
true);
155 template <
class X,
bool has_any_move_assign>
157 constexpr static bool value =
false;
162 constexpr static bool value =
noexcept( std::declval<X&>() = std::declval<X&&>() );
182template <
class T>
inline constexpr T&&
constexpr_forward(
typename std::remove_reference<T>::type& t)
noexcept
184 return static_cast<T&&
>(t);
187template <
class T>
inline constexpr T&&
constexpr_forward(
typename std::remove_reference<T>::type&& t)
noexcept
189 static_assert(!std::is_lvalue_reference<T>::value,
"!!");
190 return static_cast<T&&
>(t);
193template <
class T>
inline constexpr typename std::remove_reference<T>::type&&
constexpr_move(T&& t)
noexcept
195 return static_cast<typename std::remove_reference<T>::type&&
>(t);
200# define TR2_OPTIONAL_ASSERTED_EXPRESSION(CHECK, EXPR) (EXPR)
202# define TR2_OPTIONAL_ASSERTED_EXPRESSION(CHECK, EXPR) ((CHECK) ? (EXPR) : ([]{assert(!#CHECK);}(), (EXPR)))
216 template <class X, size_t S = sizeof(std::declval<X&>().operator&()) >
219 constexpr static bool value = has_overload<T>(
true);
222template <
typename T, TR2_OPTIONAL_REQUIRES(!has_overloaded_addressof<T>)>
228template <
typename T, TR2_OPTIONAL_REQUIRES(has_overloaded_addressof<T>)>
231 return std::addressof(ref);
287 template <
class... Args>
302 template <
class... Args>
324 template <
class U,
class... Args,
TR2_OPTIONAL_REQUIRES(is_constructible<T, std::initializer_list<U>>)>
347 template <
class U,
class... Args,
TR2_OPTIONAL_REQUIRES(is_constructible<T, std::initializer_list<U>>)>
366 static_assert( !std::is_same<typename std::decay<T>::type,
nullopt_t>
::value,
"bad T" );
367 static_assert( !std::is_same<typename std::decay<T>::type,
in_place_t>
::value,
"bad T" );
374# if OPTIONAL_HAS_THIS_RVALUE_REFS == 1
376# if OPTIONAL_HAS_MOVE_ACCESSORS == 1
381 T&&
contained_val() && {
return std::move(OptionalBase<T>::storage_.value_); }
393 template <
class... Args>
394 void initialize(Args&&... args)
noexcept(
noexcept(
T(std::forward<Args>(args)...)))
397 ::new (
static_cast<void*
>(
dataptr()))
T(std::forward<Args>(args)...);
401 template <
class U,
class... Args>
402 void initialize(std::initializer_list<U> il, Args&&... args)
noexcept(
noexcept(
T(il, std::forward<Args>(args)...)))
405 ::new (
static_cast<void*
>(
dataptr()))
T(il, std::forward<Args>(args)...);
420 ::new (
static_cast<void*
>(
dataptr()))
T(*rhs);
428 if (rhs.initialized()) {
429 ::new (
static_cast<void*
>(
dataptr()))
T(std::move(*rhs));
438 template <
class... Args>
442 template <
class U,
class... Args,
TR2_OPTIONAL_REQUIRES(is_constructible<T, std::initializer_list<U>>)>
475 ->
typename enable_if
477 is_same<typename decay<U>::type,
T>
::value,
487 template <
class... Args>
494 template <
class U,
class... Args>
495 void emplace(initializer_list<U> il, Args&&... args)
498 initialize<U, Args...>(il, std::forward<Args>(args)...);
505 if (
initialized() ==
true && rhs.initialized() ==
false) { rhs.initialize(std::move(**
this));
clear(); }
506 else if (
initialized() ==
false && rhs.initialized() ==
true) {
initialize(std::move(*rhs)); rhs.clear(); }
507 else if (
initialized() ==
true && rhs.initialized() ==
true) {
using std::swap;
swap(**
this, *rhs); }
512 explicit constexpr operator bool() const noexcept {
return initialized(); }
519# if OPTIONAL_HAS_MOVE_ACCESSORS == 1
540 constexpr T const&
value() const& {
549 if (!
initialized())
throw bad_optional_access(
"bad optional access");
579# if OPTIONAL_HAS_THIS_RVALUE_REFS == 1
584 return *
this ? **this : detail_::convert<T>(constexpr_forward<V>(v));
587# if OPTIONAL_HAS_MOVE_ACCESSORS == 1
610 return *
this ? **this : detail_::convert<T>(constexpr_forward<V>(
v));
623 static_assert( !std::is_same<T, nullopt_t>::value,
"bad T" );
624 static_assert( !std::is_same<T, in_place_t>::value,
"bad T" );
662 template <
typename U>
664 ->
typename enable_if
674 template <
typename U>
676 ->
typename enable_if
692 std::swap(ref, rhs.ref);
708 explicit constexpr operator bool() const noexcept {
709 return ref !=
nullptr;
713 return ref !=
nullptr;
717 constexpr typename decay<T>::type
value_or(V&& v)
const
719 return *
this ? **this : detail_::convert<typename decay<T>::type>(constexpr_forward<V>(
v));
723 void reset() noexcept { ref =
nullptr; }
730 static_assert(
sizeof(
T) == 0,
"optional rvalue references disallowed" );
737 return bool(
x) != bool(
y) ? false : bool(
x) ==
false ? true : *
x == *
y;
747 return (!
y) ? false : (!
x) ?
true : *
x < *
y;
832 return bool(
x) ? *
x ==
v :
false;
837 return bool(
x) ?
v == *
x :
false;
842 return bool(
x) ? *
x !=
v :
true;
847 return bool(
x) ?
v != *
x :
true;
852 return bool(
x) ? *
x <
v :
true;
857 return bool(
x) ?
v > *
x :
true;
862 return bool(
x) ? *
x >
v :
false;
867 return bool(
x) ?
v < *
x :
false;
872 return bool(
x) ? *
x >=
v :
false;
877 return bool(
x) ?
v <= *
x :
false;
882 return bool(
x) ? *
x <=
v :
true;
887 return bool(
x) ?
v >= *
x :
true;
894 return bool(
x) ? *
x ==
v :
false;
899 return bool(
x) ?
v == *
x :
false;
904 return bool(
x) ? *
x !=
v :
true;
909 return bool(
x) ?
v != *
x :
true;
914 return bool(
x) ? *
x <
v :
true;
919 return bool(
x) ?
v > *
x :
true;
924 return bool(
x) ? *
x >
v :
false;
929 return bool(
x) ?
v < *
x :
false;
934 return bool(
x) ? *
x >=
v :
false;
939 return bool(
x) ?
v <= *
x :
false;
944 return bool(
x) ? *
x <=
v :
true;
949 return bool(
x) ?
v >= *
x :
true;
955 return bool(
x) ? *
x ==
v :
false;
960 return bool(
x) ?
v == *
x :
false;
965 return bool(
x) ? *
x !=
v :
true;
970 return bool(
x) ?
v != *
x :
true;
975 return bool(
x) ? *
x <
v :
true;
980 return bool(
x) ?
v > *
x :
true;
985 return bool(
x) ? *
x >
v :
false;
990 return bool(
x) ?
v < *
x :
false;
995 return bool(
x) ? *
x >=
v :
false;
1000 return bool(
x) ?
v <= *
x :
false;
1005 return bool(
x) ? *
x <=
v :
true;
1010 return bool(
x) ?
v >= *
x :
true;
1040 template <
typename T>
1047 return arg ? std::hash<T>{}(*arg) :
result_type{};
1051 template <
typename T>
1058 return arg ? std::hash<T>{}(*arg) :
result_type{};
1063# undef TR2_OPTIONAL_REQUIRES
1064# undef TR2_OPTIONAL_ASSERTED_EXPRESSION
bad_optional_access(const string &what_arg)
bad_optional_access(const char *what_arg)
constexpr decay< T >::type value_or(V &&v) const
constexpr optional(T &v) noexcept
void emplace(T &v) noexcept
auto operator=(U &&rhs) noexcept -> typename enable_if< !is_same< typename decay< U >::type, optional< T & > >::value, optional & >::type=delete
void emplace(T &&)=delete
constexpr optional(in_place_t, T &v) noexcept
constexpr T & value() const
void swap(optional< T & > &rhs) noexcept
constexpr optional(nullopt_t) noexcept
optional & operator=(nullopt_t) noexcept
constexpr bool has_value() const noexcept
constexpr T * operator->() const
constexpr T & operator*() const
optional(in_place_t, T &&)=delete
constexpr optional(const optional &rhs) noexcept
constexpr optional() noexcept
auto operator=(U &&rhs) noexcept -> typename enable_if< is_same< typename decay< U >::type, optional< T & > >::value, optional & >::type
optional(const optional &rhs)
constexpr const T & contained_val() const
constexpr T const & value() const
constexpr optional(T &&v)
constexpr optional() noexcept
void emplace(initializer_list< U > il, Args &&... args)
constexpr const T * dataptr() const
constexpr optional(nullopt_t) noexcept
OPTIONAL_CONSTEXPR_INIT_LIST optional(in_place_t, std::initializer_list< U > il, Args &&... args)
void initialize(std::initializer_list< U > il, Args &&... args) noexcept(noexcept(T(il, std::forward< Args >(args)...)))
void emplace(Args &&... args)
constexpr T value_or(V &&v) const
optional & operator=(nullopt_t) noexcept
void swap(optional< T > &rhs) noexcept(is_nothrow_move_constructible< T >::value &&noexcept(detail_::swap_ns::adl_swap(declval< T & >(), declval< T & >())))
optional & operator=(optional &&rhs) noexcept(is_nothrow_move_assignable< T >::value &&is_nothrow_move_constructible< T >::value)
constexpr T const * operator->() const
optional & operator=(const optional &rhs)
constexpr bool has_value() const noexcept
constexpr T const & operator*() const
constexpr optional(in_place_t, Args &&... args)
void initialize(Args &&... args) noexcept(noexcept(T(std::forward< Args >(args)...)))
constexpr bool initialized() const noexcept
constexpr optional(const T &v)
std::remove_const< T >::type * dataptr()
optional(optional &&rhs) noexcept(is_nothrow_move_constructible< T >::value)
auto operator=(U &&v) -> typename enable_if< is_same< typename decay< U >::type, T >::value, optional & >::type
void swap(RDirectoryEntry &e1, RDirectoryEntry &e2) noexcept
void convert(AxisAngle const &from, EulerAngles &to)
void forward(const LAYERDATA &prevLayerData, LAYERDATA &currLayerData)
void adl_swap(T &t, T &u) noexcept(noexcept(swap(t, u)))
constexpr T * static_addressof(T &ref)
constexpr bool operator==(const optional< T > &x, const optional< T > &y)
constexpr bool operator>(const optional< T > &x, const optional< T > &y)
constexpr bool operator<(const optional< T > &x, const optional< T > &y)
constexpr bool operator>=(const optional< T > &x, const optional< T > &y)
constexpr T && constexpr_forward(typename std::remove_reference< T >::type &t) noexcept
typename std::conditional< is_trivially_destructible< T >::value, constexpr_optional_base< typename std::remove_const< T >::type >, optional_base< typename std::remove_const< T >::type > >::type OptionalBase
std::has_trivial_destructor< T > is_trivially_destructible
constexpr optional< typename decay< T >::type > make_optional(T &&v)
constexpr struct std::experimental::trivial_init_t trivial_init
constexpr std::remove_reference< T >::type && constexpr_move(T &&t) noexcept
constexpr bool operator!=(const optional< T > &x, const optional< T > &y)
constexpr struct std::experimental::in_place_t in_place
constexpr nullopt_t nullopt
constexpr bool operator<=(const optional< T > &x, const optional< T > &y)
#define TR2_OPTIONAL_REQUIRES(...)
#define OPTIONAL_CONSTEXPR_INIT_LIST
#define TR2_OPTIONAL_ASSERTED_EXPRESSION(CHECK, EXPR)
#define OPTIONAL_MUTABLE_CONSTEXPR
constexpr constexpr_optional_base(in_place_t, Args &&... args)
constexpr constexpr_optional_base(const T &v)
constexpr_storage_t< T > storage_
constexpr constexpr_optional_base() noexcept
constexpr constexpr_optional_base(T &&v)
~constexpr_optional_base()=default
OPTIONAL_CONSTEXPR_INIT_LIST constexpr_optional_base(in_place_t, std::initializer_list< U > il, Args &&... args)
static constexpr bool has_overload(bool)
static constexpr bool has_overload(...)
static constexpr bool value
static constexpr bool value
static constexpr bool has_assign(bool)
static constexpr bool has_assign(...)
static constexpr bool value
static constexpr bool value
static constexpr bool value
constexpr nullopt_t(init)
constexpr optional_base() noexcept
optional_base(in_place_t, Args &&... args)
constexpr optional_base(T &&v)
optional_base(in_place_t, std::initializer_list< U > il, Args &&... args)
constexpr optional_base(const T &v)
hash< T >::result_type result_type
constexpr result_type operator()(argument_type const &arg) const
std::experimental::optional< T > argument_type
constexpr result_type operator()(argument_type const &arg) const
std::experimental::optional< T & > argument_type
hash< T >::result_type result_type
constexpr constexpr_storage_t(trivial_init_t) noexcept
constexpr constexpr_storage_t(Args &&... args)
~constexpr_storage_t()=default
constexpr storage_t(trivial_init_t) noexcept
constexpr storage_t(Args &&... args)