9 #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
10 #include <type_traits>
15 #if __cplusplus >= 201103L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201103L)
16 #define CONSTEXPR constexpr
23 #if __cplusplus >= 201103L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201103L)
24 #define NOEXCEPT(Expr) noexcept(Expr)
26 #define NOEXCEPT(Expr)
62 #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
63 template <
class... Args>
86 #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
87 template <
class... Args>
88 void Init(Args&&... args) {
89 ::new (&
value_) T(std::forward<Args>(args)...);
93 void Init(
const T& _value) {
117 template <
typename T>
131 #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
132 template <
class... Args>
149 #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
151 if (other.is_populated_)
152 Init(std::move(other.value_));
159 template <
typename T>
167 #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
170 template <
class... Args>
179 template <
typename U>
185 #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
186 template <
typename U>
188 if (other.storage_.is_populated_)
189 storage_.Init(std::move(other.storage_.value_));
200 #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
202 std::is_nothrow_move_assignable<T>::value &&
203 std::is_nothrow_move_constructible<T>::value) {
209 template <
typename U>
217 #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
218 template <
typename U>
220 if (other.storage_.is_populated_)
227 template <
typename U>
228 #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
231 storage_.value_ = std::forward<U>(value);
233 storage_.Init(std::forward<U>(value));
254 template <
typename U>
264 template <
bool is_copy_constructible>
271 #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
279 template <
bool is_move_constructible>
287 #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
294 template <
bool is_copy_assignable>
301 #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
309 template <
bool is_move_assignable>
317 #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
325 #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
327 template <
typename T,
typename U>
329 : std::integral_constant<
331 std::is_constructible<T, Optional<U>&>::value ||
332 std::is_constructible<T, const Optional<U>&>::value ||
333 std::is_constructible<T, Optional<U>&&>::value ||
334 std::is_constructible<T, const Optional<U>&&>::value ||
335 std::is_convertible<Optional<U>&, T>::value ||
336 std::is_convertible<const Optional<U>&, T>::value ||
337 std::is_convertible<Optional<U>&&, T>::value ||
338 std::is_convertible<const Optional<U>&&, T>::value> {};
340 template <
typename T,
typename U>
342 : std::integral_constant<
344 IsConvertibleFromOptional<T, U>::value ||
345 std::is_assignable<T&, Optional<U>&>::value ||
346 std::is_assignable<T&, const Optional<U>&>::value ||
347 std::is_assignable<T&, Optional<U>&&>::value ||
348 std::is_assignable<T&, const Optional<U>&&>::value> {};
352 namespace swappable_impl {
359 template <
typename T>
361 -> decltype(swap(std::declval<T>(), std::declval<T>()), std::true_type());
363 template <
typename T>
367 template <
typename T>
368 struct IsSwappable : decltype(swappable_impl::IsSwappableImpl::Check<T&>(0)) {};
378 #define OPTIONAL_DECLSPEC_EMPTY_BASES __declspec(empty_bases)
380 #define OPTIONAL_DECLSPEC_EMPTY_BASES
402 template <
typename T>
403 class OPTIONAL_DECLSPEC_EMPTY_BASES
Optional
405 #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
409 std::is_copy_assignable<T>::value>,
411 std::is_move_assignable<T>::value>
415 #undef OPTIONAL_DECLSPEC_EMPTY_BASES
417 typedef T value_type;
421 CONSTEXPR Optional(
const Optional& other) : internal::OptionalBase<T>(other) {}
423 CONSTEXPR Optional(nullopt_t) {}
429 template <
typename U>
430 Optional(
const Optional<U>& other) : internal::OptionalBase<T>(other) {}
432 #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
435 template <
typename U>
436 Optional(Optional<U>&& other) : internal::OptionalBase<T>(
std::move(other)) {}
438 template <
class... Args>
439 CONSTEXPR
explicit Optional(in_place_t, Args&&... args)
440 : internal::OptionalBase<T>(
in_place,
std::forward<Args>(args)...) {}
442 template <
class U,
class... Args>
443 CONSTEXPR
explicit Optional(in_place_t,
444 std::initializer_list<U> il,
446 : internal::OptionalBase<T>(
in_place, il,
std::forward<Args>(args)...) {}
448 CONSTEXPR
explicit Optional(in_place_t,
const T& _value)
449 : internal::OptionalBase<T>(
in_place, _value) {}
451 CONSTEXPR
explicit Optional(in_place_t,
454 : internal::OptionalBase<T>(
in_place, il, _value) {}
459 #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
460 template <
typename U = value_type>
461 CONSTEXPR Optional(U&& value)
462 : internal::OptionalBase<T>(
in_place,
std::forward<U>(value)) {}
464 template <
typename U>
465 CONSTEXPR Optional(
const U& value)
466 : internal::OptionalBase<T>(
in_place, value) {}
472 Optional& operator=(
const Optional& other) {
473 if (&other ==
this) {
481 Optional& operator=(nullopt_t) {
487 template <
typename U>
488 #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
489 Optional& operator=(U&& value) {
490 InitOrAssign(std::forward<U>(value));
494 Optional& operator=(
const U& value) {
501 template <
typename U>
502 Optional& operator=(
const Optional<U>& other) {
507 #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
509 template <
typename U>
510 Optional& operator=(Optional<U>&& other) {
511 MoveAssign(std::move(other));
516 const T* operator->()
const {
517 return &storage_.value_;
521 return &storage_.value_;
524 const T& operator*()
const {
525 return storage_.value_;
529 return storage_.value_;
533 #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
534 CONSTEXPR
explicit operator bool()
const {
return storage_.is_populated_; }
536 CONSTEXPR
operator bool()
const {
return storage_.is_populated_; }
539 CONSTEXPR
bool has_value()
const {
return storage_.is_populated_; }
542 const T& value()
const {
543 return storage_.value_;
547 #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
548 CONSTEXPR T value_or(U&& default_value)
const {
552 static_assert(std::is_convertible<U, T>::value,
553 "U must be convertible to T");
554 return storage_.is_populated_
556 : static_cast<T>(
std::forward<U>(default_value));
559 CONSTEXPR T value_or(
const U& default_value)
const {
560 return storage_.is_populated_
562 : static_cast<T>(default_value);
566 const T& value() const & {
567 return storage_.value_;
570 #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
571 const T&& value() const && {
572 return std::move(storage_.value_);
577 #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
578 CONSTEXPR T value_or(U&& default_value)
const & {
582 static_assert(std::is_convertible<U, T>::value,
583 "U must be convertible to T");
584 return storage_.is_populated_
586 : static_cast<T>(
std::forward<U>(default_value));
589 CONSTEXPR T value_or(
const U& default_value)
const & {
593 static_assert(std::is_convertible<U, T>::value,
594 "U must be convertible to T");
595 return storage_.is_populated_
597 : static_cast<T>(default_value);
602 #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
603 CONSTEXPR T value_or(U&& default_value)
const && {
607 static_assert(std::is_convertible<U, T>::value,
608 "U must be convertible to T");
609 return storage_.is_populated_
611 : static_cast<T>(
std::forward<U>(default_value));
616 void swap(Optional& other) {
617 if (!storage_.is_populated_ && !other.storage_.is_populated_)
620 #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
621 if (storage_.is_populated_ != other.storage_.is_populated_) {
622 if (storage_.is_populated_) {
623 other.storage_.Init(std::move(storage_.value_));
626 storage_.Init(std::move(other.storage_.value_));
627 other.FreeIfNeeded();
633 swap(**
this, *other);
636 void reset() { FreeIfNeeded(); }
638 #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
639 template <
class... Args>
640 T& emplace(Args&&... args) {
642 storage_.Init(std::forward<Args>(args)...);
643 return storage_.value_;
646 template <
class U,
class... Args>
647 T& emplace(std::initializer_list<U> il, Args&&... args) {
649 storage_.Init(il, std::forward<Args>(args)...);
650 return storage_.value_;
653 T& emplace(
const T& _value) {
655 storage_.Init(_value);
656 return storage_.value_;
659 T& emplace(
const U il[],
const T& _value) {
661 storage_.Init(il, _value);
662 return storage_.value_;
672 #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
682 template <
class T,
class U>
683 bool operator==(
const Optional<T>& lhs,
const Optional<U>& rhs) {
684 if (lhs.has_value() != rhs.has_value())
686 if (!lhs.has_value())
691 template <
class T,
class U>
692 bool operator!=(
const Optional<T>& lhs,
const Optional<U>& rhs) {
693 if (lhs.has_value() != rhs.has_value())
695 if (!lhs.has_value())
700 template <
class T,
class U>
701 bool operator<(
const Optional<T>& lhs,
const Optional<U>& rhs) {
702 if (!rhs.has_value())
704 if (!lhs.has_value())
709 template <
class T,
class U>
710 bool operator<=(
const Optional<T>& lhs,
const Optional<U>& rhs) {
711 if (!lhs.has_value())
713 if (!rhs.has_value())
718 template <
class T,
class U>
719 bool operator>(
const Optional<T>& lhs,
const Optional<U>& rhs) {
720 if (!lhs.has_value())
722 if (!rhs.has_value())
727 template <
class T,
class U>
728 bool operator>=(
const Optional<T>& lhs,
const Optional<U>& rhs) {
729 if (!rhs.has_value())
731 if (!lhs.has_value())
737 CONSTEXPR
bool operator==(
const Optional<T>& opt, nullopt_t) {
742 CONSTEXPR
bool operator==(nullopt_t,
const Optional<T>& opt) {
747 CONSTEXPR
bool operator!=(
const Optional<T>& opt, nullopt_t) {
748 return opt.has_value();
752 CONSTEXPR
bool operator!=(nullopt_t,
const Optional<T>& opt) {
753 return opt.has_value();
757 CONSTEXPR
bool operator<(
const Optional<T>& opt, nullopt_t) {
762 CONSTEXPR
bool operator<(nullopt_t,
const Optional<T>& opt) {
763 return opt.has_value();
767 CONSTEXPR
bool operator<=(
const Optional<T>& opt, nullopt_t) {
772 CONSTEXPR
bool operator<=(nullopt_t,
const Optional<T>& opt) {
777 CONSTEXPR
bool operator>(
const Optional<T>& opt, nullopt_t) {
778 return opt.has_value();
782 CONSTEXPR
bool operator>(nullopt_t,
const Optional<T>& opt) {
787 CONSTEXPR
bool operator>=(
const Optional<T>& opt, nullopt_t) {
792 CONSTEXPR
bool operator>=(nullopt_t,
const Optional<T>& opt) {
796 template <
class T,
class U>
797 CONSTEXPR
bool operator==(
const Optional<T>& opt,
const U& value) {
798 return opt.has_value() ? *opt == value :
false;
801 template <
class T,
class U>
802 CONSTEXPR
bool operator==(
const U& value,
const Optional<T>& opt) {
803 return opt.has_value() ? value == *opt :
false;
806 template <
class T,
class U>
807 CONSTEXPR
bool operator!=(
const Optional<T>& opt,
const U& value) {
808 return opt.has_value() ? *opt != value :
true;
811 template <
class T,
class U>
812 CONSTEXPR
bool operator!=(
const U& value,
const Optional<T>& opt) {
813 return opt.has_value() ? value != *opt :
true;
816 template <
class T,
class U>
817 CONSTEXPR
bool operator<(
const Optional<T>& opt,
const U& value) {
818 return opt.has_value() ? *opt < value :
true;
821 template <
class T,
class U>
822 CONSTEXPR
bool operator<(
const U& value,
const Optional<T>& opt) {
823 return opt.has_value() ? value < *opt :
false;
826 template <
class T,
class U>
827 CONSTEXPR
bool operator<=(
const Optional<T>& opt,
const U& value) {
828 return opt.has_value() ? *opt <= value :
true;
831 template <
class T,
class U>
832 CONSTEXPR
bool operator<=(
const U& value,
const Optional<T>& opt) {
833 return opt.has_value() ? value <= *opt :
false;
836 template <
class T,
class U>
837 CONSTEXPR
bool operator>(
const Optional<T>& opt,
const U& value) {
838 return opt.has_value() ? *opt > value :
false;
841 template <
class T,
class U>
842 CONSTEXPR
bool operator>(
const U& value,
const Optional<T>& opt) {
843 return opt.has_value() ? value > *opt :
true;
846 template <
class T,
class U>
847 CONSTEXPR
bool operator>=(
const Optional<T>& opt,
const U& value) {
848 return opt.has_value() ? *opt >= value :
false;
851 template <
class T,
class U>
852 CONSTEXPR
bool operator>=(
const U& value,
const Optional<T>& opt) {
853 return opt.has_value() ? value >= *opt :
true;
856 #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
857 template <
class T,
class... Args>
858 CONSTEXPR Optional<T> make_optional(Args&&... args) {
859 return Optional<T>(
in_place, std::forward<Args>(args)...);
862 template <
class T,
class U,
class... Args>
863 CONSTEXPR Optional<T> make_optional(std::initializer_list<U> il,
865 return Optional<T>(
in_place, il, std::forward<Args>(args)...);
874 void swap(Optional<T>& lhs, Optional<T>& rhs) {
880 #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)