10 # ifndef ___OPTIONAL_HPP___ 11 # define ___OPTIONAL_HPP___ 14 # include <type_traits> 15 # include <initializer_list> 17 # include <functional> 23 # define TR2_OPTIONAL_REQUIRES(...) typename enable_if<__VA_ARGS__::value, bool>::type = false 25 # if defined __GNUC__ // NOTE: GNUC is also defined for Clang 26 # if (__GNUC__ == 4) && (__GNUC_MINOR__ >= 8) 27 # define TR2_OPTIONAL_GCC_4_8_AND_HIGHER___ 29 # define TR2_OPTIONAL_GCC_4_8_AND_HIGHER___ 32 # if (__GNUC__ == 4) && (__GNUC_MINOR__ >= 7) 33 # define TR2_OPTIONAL_GCC_4_7_AND_HIGHER___ 35 # define TR2_OPTIONAL_GCC_4_7_AND_HIGHER___ 38 # if (__GNUC__ == 4) && (__GNUC_MINOR__ == 8) && (__GNUC_PATCHLEVEL__ >= 1) 39 # define TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___ 40 # elif (__GNUC__ == 4) && (__GNUC_MINOR__ >= 9) 41 # define TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___ 43 # define TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___ 47 # if defined __clang_major__ 48 # if (__clang_major__ == 3 && __clang_minor__ >= 5) 49 # define TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_ 50 # elif (__clang_major__ > 3) 51 # define TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_ 53 # if defined TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_ 54 # define TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_ 55 # elif (__clang_major__ == 3 && __clang_minor__ == 4 && __clang_patchlevel__ >= 2) 56 # define TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_ 61 # if (_MSC_VER >= 1900) 62 # define TR2_OPTIONAL_MSVC_2015_AND_HIGHER___ 66 # if defined __clang__ 67 # if (__clang_major__ > 2) || (__clang_major__ == 2) && (__clang_minor__ >= 9) 68 # define OPTIONAL_HAS_THIS_RVALUE_REFS 1 70 # define OPTIONAL_HAS_THIS_RVALUE_REFS 0 72 # elif defined TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___ 73 # define OPTIONAL_HAS_THIS_RVALUE_REFS 1 74 # elif defined TR2_OPTIONAL_MSVC_2015_AND_HIGHER___ 75 # define OPTIONAL_HAS_THIS_RVALUE_REFS 1 77 # define OPTIONAL_HAS_THIS_RVALUE_REFS 0 81 # if defined TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___ 82 # define OPTIONAL_HAS_CONSTEXPR_INIT_LIST 1 83 # define OPTIONAL_CONSTEXPR_INIT_LIST constexpr 85 # define OPTIONAL_HAS_CONSTEXPR_INIT_LIST 0 86 # define OPTIONAL_CONSTEXPR_INIT_LIST 89 # if defined TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_ && (defined __cplusplus) && (__cplusplus != 201103L) 90 # define OPTIONAL_HAS_MOVE_ACCESSORS 1 92 # define OPTIONAL_HAS_MOVE_ACCESSORS 0 95 # // In C++11 constexpr implies const, so we need to make non-const members also non-constexpr 96 # if (defined __cplusplus) && (__cplusplus == 201103L) 97 # define OPTIONAL_MUTABLE_CONSTEXPR 99 # define OPTIONAL_MUTABLE_CONSTEXPR constexpr 104 namespace experimental{
107 # if defined TR2_OPTIONAL_GCC_4_8_AND_HIGHER___ 109 # elif defined TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_ 111 # elif defined TR2_OPTIONAL_MSVC_2015_AND_HIGHER___ 113 # elif defined TR2_OPTIONAL_DISABLE_EMULATION_OF_TYPE_TRAITS 116 template <
typename T>
117 using is_trivially_destructible = std::has_trivial_destructor<T>;
121 # if (defined TR2_OPTIONAL_GCC_4_7_AND_HIGHER___) 123 # elif defined TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_ 125 # elif defined TR2_OPTIONAL_MSVC_2015_AND_HIGHER___ 127 # elif defined TR2_OPTIONAL_DISABLE_EMULATION_OF_TYPE_TRAITS 136 constexpr
static bool value = std::is_nothrow_constructible<T, T&&>::value;
140 template <
class T,
class U>
143 template <
class X,
class Y>
144 constexpr
static bool has_assign(...) {
return false; }
146 template <
class X,
class Y,
size_t S = sizeof((std::declval<X>() = std::declval<Y>(), true)) >
148 constexpr
static bool has_assign(
bool) {
return true; }
150 constexpr
static bool value = has_assign<T, U>(
true);
157 template <
class X,
bool has_any_move_assign>
159 constexpr
static bool value =
false;
164 constexpr
static bool value = noexcept( std::declval<X&>() = std::declval<X&&>() );
180 template <
class T>
class optional<T&>;
184 template <
class T>
inline constexpr T&& constexpr_forward(
typename std::remove_reference<T>::type& t) noexcept
186 return static_cast<T&&
>(t);
189 template <
class T>
inline constexpr T&& constexpr_forward(
typename std::remove_reference<T>::type&& t) noexcept
191 static_assert(!std::is_lvalue_reference<T>::value,
"!!");
192 return static_cast<T&&
>(t);
195 template <
class T>
inline constexpr
typename std::remove_reference<T>::type&& constexpr_move(T&& t) noexcept
197 return static_cast<typename std::remove_reference<T>::type&&
>(t);
202 # define TR2_OPTIONAL_ASSERTED_EXPRESSION(CHECK, EXPR) (EXPR) 204 # define TR2_OPTIONAL_ASSERTED_EXPRESSION(CHECK, EXPR) ((CHECK) ? (EXPR) : ([]{assert(!#CHECK);}(), (EXPR))) 212 template <
typename T>
216 constexpr
static bool has_overload(...) {
return false; }
218 template <
class X,
size_t S = sizeof(std::declval<X&>().operator&()) >
219 constexpr
static bool has_overload(
bool) {
return true; }
221 constexpr
static bool value = has_overload<T>(
true);
224 template <
typename T, TR2_OPTIONAL_REQUIRES(!has_overloaded_addressof<T>)>
225 constexpr T* static_addressof(T& ref)
230 template <
typename T, TR2_OPTIONAL_REQUIRES(has_overloaded_addressof<T>)>
231 T* static_addressof(T& ref)
233 return std::addressof(ref);
239 constexpr U convert(U v) {
return v; }
271 unsigned char dummy_;
276 template <
class... Args>
277 constexpr
storage_t( Args&&... args ) : value_(constexpr_forward<Args>(args)...) {}
286 unsigned char dummy_;
291 template <
class... Args>
292 constexpr
constexpr_storage_t( Args&&... args ) : value_(constexpr_forward<Args>(args)...) {}
294 ~constexpr_storage_t() =
default;
304 constexpr
optional_base() noexcept : init_(
false), storage_(trivial_init) {};
306 explicit constexpr
optional_base(
const T& v) : init_(
true), storage_(v) {}
308 explicit constexpr optional_base(T&& v) : init_(
true), storage_(constexpr_move(v)) {}
310 template <
class... Args>
explicit optional_base(
in_place_t, Args&&... args)
311 : init_(
true), storage_(constexpr_forward<Args>(args)...) {}
313 template <
class U,
class... Args, TR2_OPTIONAL_REQUIRES(is_constructible<T, std::initializer_list<U>>)>
314 explicit optional_base(
in_place_t, std::initializer_list<U> il, Args&&... args)
315 : init_(
true), storage_(il, std::forward<Args>(args)...) {}
317 ~optional_base() {
if (init_) storage_.value_.T::~T(); }
331 explicit constexpr constexpr_optional_base(T&& v) : init_(
true), storage_(constexpr_move(v)) {}
333 template <
class... Args>
explicit constexpr constexpr_optional_base(
in_place_t, Args&&... args)
334 : init_(
true), storage_(constexpr_forward<Args>(args)...) {}
336 template <
class U,
class... Args, TR2_OPTIONAL_REQUIRES(is_constructible<T, std::initializer_list<U>>)>
337 OPTIONAL_CONSTEXPR_INIT_LIST
explicit constexpr_optional_base(
in_place_t, std::initializer_list<U> il, Args&&... args)
338 : init_(
true), storage_(il, std::forward<Args>(args)...) {}
340 ~constexpr_optional_base() =
default;
344 using OptionalBase =
typename std::conditional<
345 is_trivially_destructible<T>::value,
353 class optional :
private OptionalBase<T>
355 static_assert( !std::is_same<
typename std::decay<T>::type,
nullopt_t>::value,
"bad T" );
356 static_assert( !std::is_same<
typename std::decay<T>::type,
in_place_t>::value,
"bad T" );
359 constexpr
bool initialized()
const noexcept {
return OptionalBase<T>::init_; }
360 typename std::remove_const<T>::type* dataptr() {
return std::addressof(OptionalBase<T>::storage_.value_); }
361 constexpr
const T* dataptr()
const {
return detail_::static_addressof(OptionalBase<T>::storage_.value_); }
363 # if OPTIONAL_HAS_THIS_RVALUE_REFS == 1 364 constexpr
const T& contained_val()
const& {
return OptionalBase<T>::storage_.value_; }
365 # if OPTIONAL_HAS_MOVE_ACCESSORS == 1 366 OPTIONAL_MUTABLE_CONSTEXPR T&& contained_val() && {
return std::move(OptionalBase<T>::storage_.value_); }
367 OPTIONAL_MUTABLE_CONSTEXPR T& contained_val() & {
return OptionalBase<T>::storage_.value_; }
369 T& contained_val() & {
return OptionalBase<T>::storage_.value_; }
370 T&& contained_val() && {
return std::move(OptionalBase<T>::storage_.value_); }
373 constexpr
const T& contained_val()
const {
return OptionalBase<T>::storage_.value_; }
374 T& contained_val() {
return OptionalBase<T>::storage_.value_; }
377 void clear() noexcept {
378 if (initialized()) dataptr()->T::~T();
379 OptionalBase<T>::init_ =
false;
382 template <
class... Args>
383 void initialize(Args&&... args) noexcept(noexcept(T(std::forward<Args>(args)...)))
385 assert(!OptionalBase<T>::init_);
386 ::new (static_cast<void*>(dataptr())) T(std::forward<Args>(args)...);
387 OptionalBase<T>::init_ =
true;
390 template <
class U,
class... Args>
391 void initialize(std::initializer_list<U> il, Args&&... args) noexcept(noexcept(T(il, std::forward<Args>(args)...)))
393 assert(!OptionalBase<T>::init_);
394 ::new (static_cast<void*>(dataptr())) T(il, std::forward<Args>(args)...);
395 OptionalBase<T>::init_ =
true;
399 typedef T value_type;
402 constexpr
optional() noexcept : OptionalBase<T>() {};
408 if (rhs.initialized()) {
409 ::new (static_cast<void*>(dataptr())) T(*rhs);
410 OptionalBase<T>::init_ =
true;
417 if (rhs.initialized()) {
418 ::new (static_cast<void*>(dataptr())) T(std::move(*rhs));
419 OptionalBase<T>::init_ =
true;
423 constexpr
optional(
const T& v) : OptionalBase<T>(v) {}
425 constexpr optional(T&& v) : OptionalBase<T>(constexpr_move(v)) {}
427 template <
class... Args>
428 explicit constexpr optional(
in_place_t, Args&&... args)
429 : OptionalBase<T>(
in_place_t{}, constexpr_forward<Args>(args)...) {}
431 template <
class U,
class... Args, TR2_OPTIONAL_REQUIRES(is_constructible<T, std::initializer_list<U>>)>
432 OPTIONAL_CONSTEXPR_INIT_LIST
explicit optional(
in_place_t, std::initializer_list<U> il, Args&&... args)
433 : OptionalBase<T>(
in_place_t{}, il, constexpr_forward<Args>(args)...) {}
436 ~optional() =
default;
445 optional& operator=(
const optional& rhs)
447 if (initialized() ==
true && rhs.initialized() ==
false) clear();
448 else if (initialized() ==
false && rhs.initialized() ==
true) initialize(*rhs);
449 else if (initialized() ==
true && rhs.initialized() ==
true) contained_val() = *rhs;
453 optional& operator=(optional&& rhs)
456 if (initialized() ==
true && rhs.initialized() ==
false) clear();
457 else if (initialized() ==
false && rhs.initialized() ==
true) initialize(std::move(*rhs));
458 else if (initialized() ==
true && rhs.initialized() ==
true) contained_val() = std::move(*rhs);
463 auto operator=(U&& v)
464 ->
typename enable_if
466 is_same<typename decay<U>::type, T>::value,
470 if (initialized()) { contained_val() = std::forward<U>(v); }
471 else { initialize(std::forward<U>(v)); }
476 template <
class... Args>
477 void emplace(Args&&... args)
480 initialize(std::forward<Args>(args)...);
483 template <
class U,
class... Args>
484 void emplace(initializer_list<U> il, Args&&... args)
487 initialize<U, Args...>(il, std::forward<Args>(args)...);
493 if (initialized() ==
true && rhs.initialized() ==
false) { rhs.initialize(std::move(**
this)); clear(); }
494 else if (initialized() ==
false && rhs.initialized() ==
true) { initialize(std::move(*rhs)); rhs.clear(); }
495 else if (initialized() ==
true && rhs.initialized() ==
true) {
using std::swap; swap(**
this, *rhs); }
500 explicit constexpr
operator bool()
const noexcept {
return initialized(); }
502 constexpr T
const* operator ->()
const {
503 return TR2_OPTIONAL_ASSERTED_EXPRESSION(initialized(), dataptr());
506 # if OPTIONAL_HAS_MOVE_ACCESSORS == 1 508 OPTIONAL_MUTABLE_CONSTEXPR T* operator ->() {
509 assert (initialized());
513 constexpr T
const& operator *()
const& {
514 return TR2_OPTIONAL_ASSERTED_EXPRESSION(initialized(), contained_val());
517 OPTIONAL_MUTABLE_CONSTEXPR T& operator *() & {
518 assert (initialized());
519 return contained_val();
522 OPTIONAL_MUTABLE_CONSTEXPR T&& operator *() && {
523 assert (initialized());
524 return constexpr_move(contained_val());
527 constexpr T
const& value()
const& {
528 return initialized() ? contained_val() : (
throw bad_optional_access(
"bad optional access"), contained_val());
531 OPTIONAL_MUTABLE_CONSTEXPR T& value() & {
532 return initialized() ? contained_val() : (
throw bad_optional_access(
"bad optional access"), contained_val());
535 OPTIONAL_MUTABLE_CONSTEXPR T&& value() && {
537 return std::move(contained_val());
543 assert (initialized());
547 constexpr T
const& operator *()
const {
548 return TR2_OPTIONAL_ASSERTED_EXPRESSION(initialized(), contained_val());
552 assert (initialized());
553 return contained_val();
556 constexpr T
const& value()
const {
557 return initialized() ? contained_val() : (
throw bad_optional_access(
"bad optional access"), contained_val());
561 return initialized() ? contained_val() : (
throw bad_optional_access(
"bad optional access"), contained_val());
566 # if OPTIONAL_HAS_THIS_RVALUE_REFS == 1 569 constexpr T value_or(V&& v)
const&
571 return *
this ? **this : detail_::convert<T>(constexpr_forward<V>(v));
574 # if OPTIONAL_HAS_MOVE_ACCESSORS == 1 577 OPTIONAL_MUTABLE_CONSTEXPR T value_or(V&& v) &&
579 return *
this ? constexpr_move(
const_cast<optional<T>&
>(*this).contained_val()) : detail_::convert<T>(constexpr_forward<V>(v));
587 return *
this ? constexpr_move(
const_cast<optional<T>&
>(*this).contained_val()) : detail_::convert<T>(constexpr_forward<V>(v));
595 constexpr T value_or(V&& v)
const 597 return *
this ? **this : detail_::convert<T>(constexpr_forward<V>(v));
608 static_assert( !std::is_same<T, nullopt_t>::value,
"bad T" );
609 static_assert( !std::is_same<T, in_place_t>::value,
"bad T" );
615 constexpr
optional() noexcept : ref(
nullptr) {}
619 constexpr
optional(T& v) noexcept : ref(detail_::static_addressof(v)) {}
625 explicit constexpr
optional(
in_place_t, T& v) noexcept : ref(detail_::static_addressof(v)) {}
637 friend ostream& operator<<(ostream& os, const optional<T>& o) {
641 return os <<
"Some(" << o.value() <<
")";
655 template <
typename U>
656 auto operator=(U&& rhs) noexcept
657 ->
typename enable_if
667 template <
typename U>
668 auto operator=(U&& rhs) noexcept
669 ->
typename enable_if
676 void emplace(T& v) noexcept {
677 ref = detail_::static_addressof(v);
680 void emplace(T&&) =
delete;
685 std::swap(ref, rhs.ref);
689 constexpr T* operator->()
const {
690 return TR2_OPTIONAL_ASSERTED_EXPRESSION(ref, ref);
693 constexpr T& operator*()
const {
694 return TR2_OPTIONAL_ASSERTED_EXPRESSION(ref, *ref);
697 constexpr T& value()
const {
701 explicit constexpr
operator bool()
const noexcept {
702 return ref !=
nullptr;
706 constexpr
typename decay<T>::type value_or(V&& v)
const 708 return *
this ? **this : detail_::convert<typename decay<T>::type>(constexpr_forward<V>(v));
716 static_assert(
sizeof(T) == 0,
"optional rvalue references disallowed" );
723 return bool(x) != bool(y) ? false : bool(x) ==
false ? true : *x == *y;
731 template <
class T> constexpr
bool operator<(const optional<T>& x,
const optional<T>& y)
733 return (!y) ? false : (!x) ?
true : *x < *y;
741 template <
class T> constexpr
bool operator<=(const optional<T>& x,
const optional<T>& y)
773 template <
class T> constexpr
bool operator<(const optional<T>&,
nullopt_t) noexcept
778 template <
class T> constexpr
bool operator<(nullopt_t, const optional<T>& x) noexcept
783 template <
class T> constexpr
bool operator<=(const optional<T>& x,
nullopt_t) noexcept
788 template <
class T> constexpr
bool operator<=(nullopt_t, const optional<T>&) noexcept
816 template <
class T> constexpr
bool operator==(
const optional<T>& x,
const T& v)
818 return bool(x) ? *x == v :
false;
821 template <
class T> constexpr
bool operator==(
const T& v,
const optional<T>& x)
823 return bool(x) ? v == *x :
false;
826 template <
class T> constexpr
bool operator!=(
const optional<T>& x,
const T& v)
828 return bool(x) ? *x != v :
true;
831 template <
class T> constexpr
bool operator!=(
const T& v,
const optional<T>& x)
833 return bool(x) ? v != *x :
true;
836 template <
class T> constexpr
bool operator<(const optional<T>& x,
const T& v)
838 return bool(x) ? *x < v :
true;
841 template <
class T> constexpr
bool operator>(
const T& v,
const optional<T>& x)
843 return bool(x) ? v > *x :
true;
846 template <
class T> constexpr
bool operator>(
const optional<T>& x,
const T& v)
848 return bool(x) ? *x > v :
false;
851 template <
class T> constexpr
bool operator<(const T& v, const optional<T>& x)
853 return bool(x) ? v < *x :
false;
856 template <
class T> constexpr
bool operator>=(
const optional<T>& x,
const T& v)
858 return bool(x) ? *x >= v :
false;
861 template <
class T> constexpr
bool operator<=(const T& v, const optional<T>& x)
863 return bool(x) ? v <= *x :
false;
866 template <
class T> constexpr
bool operator<=(const optional<T>& x,
const T& v)
868 return bool(x) ? *x <= v :
true;
871 template <
class T> constexpr
bool operator>=(
const T& v,
const optional<T>& x)
873 return bool(x) ? v >= *x :
true;
878 template <
class T> constexpr
bool operator==(
const optional<T&>& x,
const T& v)
880 return bool(x) ? *x == v :
false;
883 template <
class T> constexpr
bool operator==(
const T& v,
const optional<T&>& x)
885 return bool(x) ? v == *x :
false;
888 template <
class T> constexpr
bool operator!=(
const optional<T&>& x,
const T& v)
890 return bool(x) ? *x != v :
true;
893 template <
class T> constexpr
bool operator!=(
const T& v,
const optional<T&>& x)
895 return bool(x) ? v != *x :
true;
898 template <
class T> constexpr
bool operator<(const optional<T&>& x,
const T& v)
900 return bool(x) ? *x < v :
true;
903 template <
class T> constexpr
bool operator>(
const T& v,
const optional<T&>& x)
905 return bool(x) ? v > *x :
true;
908 template <
class T> constexpr
bool operator>(
const optional<T&>& x,
const T& v)
910 return bool(x) ? *x > v :
false;
913 template <
class T> constexpr
bool operator<(const T& v, const optional<T&>& x)
915 return bool(x) ? v < *x :
false;
918 template <
class T> constexpr
bool operator>=(
const optional<T&>& x,
const T& v)
920 return bool(x) ? *x >= v :
false;
923 template <
class T> constexpr
bool operator<=(const T& v, const optional<T&>& x)
925 return bool(x) ? v <= *x :
false;
928 template <
class T> constexpr
bool operator<=(const optional<T&>& x,
const T& v)
930 return bool(x) ? *x <= v :
true;
933 template <
class T> constexpr
bool operator>=(
const T& v,
const optional<T&>& x)
935 return bool(x) ? v >= *x :
true;
941 return bool(x) ? *x == v :
false;
946 return bool(x) ? v == *x :
false;
951 return bool(x) ? *x != v :
true;
956 return bool(x) ? v != *x :
true;
959 template <
class T> constexpr
bool operator<(const optional<const T&>& x,
const T& v)
961 return bool(x) ? *x < v :
true;
966 return bool(x) ? v > *x :
true;
971 return bool(x) ? *x > v :
false;
974 template <
class T> constexpr
bool operator<(const T& v, const optional<const T&>& x)
976 return bool(x) ? v < *x :
false;
981 return bool(x) ? *x >= v :
false;
984 template <
class T> constexpr
bool operator<=(const T& v, const optional<const T&>& x)
986 return bool(x) ? v <= *x :
false;
989 template <
class T> constexpr
bool operator<=(const optional<const T&>& x,
const T& v)
991 return bool(x) ? *x <= v :
true;
996 return bool(x) ? v >= *x :
true;
1014 constexpr
optional<X&> make_optional(reference_wrapper<X> v)
1025 template <
typename T>
1028 typedef typename hash<T>::result_type result_type;
1031 constexpr result_type operator()(argument_type
const& arg)
const {
1032 return arg ? std::hash<T>{}(*arg) : result_type{};
1036 template <
typename T>
1039 typedef typename hash<T>::result_type result_type;
1042 constexpr result_type operator()(argument_type
const& arg)
const {
1043 return arg ? std::hash<T>{}(*arg) : result_type{};
1050 template <
typename T>
1055 # undef TR2_OPTIONAL_REQUIRES 1056 # undef TR2_OPTIONAL_ASSERTED_EXPRESSION 1058 # endif //___OPTIONAL_HPP___ Definition: optional.hpp:269
Definition: optional.hpp:284
Definition: optional.hpp:252
Definition: optional.hpp:158
Definition: BitcoinLikeFeePolicy.hpp:29
Definition: optional.hpp:254
Definition: optional.hpp:213
Definition: optional.hpp:141
Definition: optional.hpp:248
Definition: optional.hpp:322
Definition: optional.hpp:155
Definition: Account.cpp:8
Definition: optional.hpp:244
Definition: optional.hpp:299
Definition: optional.hpp:261
Definition: optional.hpp:177
Definition: optional.hpp:134
Definition: optional.hpp:606