9#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
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)
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) {
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_));
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) {
204 MoveAssign(std::move(other));
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>
264template <
bool is_copy_constructible>
271#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
273 CopyConstructible& operator=(CopyConstructible&&) {
return *
this; }
276 CONSTEXPR CopyConstructible(
const CopyConstructible&);
279template <
bool is_move_constructible>
287#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
290 CONSTEXPR MoveConstructible(MoveConstructible&&);
294template <
bool is_copy_assignable>
301#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
303 CopyAssignable& operator=(CopyAssignable&&) {
return *
this; }
306 CopyAssignable& operator=(
const CopyAssignable&);
309template <
bool is_move_assignable>
317#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
321 MoveAssignable& operator=(MoveAssignable&&);
325#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
327template <
typename T,
typename U>
328struct IsConvertibleFromOptional
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> {};
340template <
typename T,
typename U>
341struct IsAssignableFromOptional
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> {};
352namespace swappable_impl {
355struct IsSwappableImpl {
359 template <
typename T>
360 static auto Check(
int)
361 ->
decltype(
swap(std::declval<T>(), std::declval<T>()), std::true_type());
363 template <
typename T>
364 static std::false_type Check(...);
368struct IsSwappable : decltype(swappable_impl::IsSwappableImpl::Check<T&>(0)) {};
378#define OPTIONAL_DECLSPEC_EMPTY_BASES __declspec(empty_bases)
380#define OPTIONAL_DECLSPEC_EMPTY_BASES
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
429 template <
typename U>
432#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
435 template <
typename U>
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>
444 std::initializer_list<U> il,
446 : internal::OptionalBase<T>(
in_place, il, std::forward<Args>(args)...) {}
449 : internal::OptionalBase<T>(
in_place, _value) {}
454 : internal::OptionalBase<T>(
in_place, il, _value) {}
459#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
460 template <
typename U = value_type>
462 : internal::OptionalBase<T>(
in_place, std::forward<U>(value)) {}
464 template <
typename U>
466 : internal::OptionalBase<T>(
in_place, value) {}
473 if (&other ==
this) {
487 template <
typename U>
488#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
490 InitOrAssign(std::forward<U>(value));
501 template <
typename U>
507#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
509 template <
typename U>
511 MoveAssign(std::move(other));
517 return &storage_.value_;
521 return &storage_.value_;
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_; }
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));
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));
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_));
633 swap(**
this, *other);
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_;
655 storage_.Init(_value);
656 return storage_.value_;
661 storage_.Init(il, _value);
662 return storage_.value_;
672#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
682template <
class T,
class U>
691template <
class T,
class U>
700template <
class T,
class U>
709template <
class T,
class U>
718template <
class T,
class U>
727template <
class T,
class U>
796template <
class T,
class U>
798 return opt.
has_value() ? *opt == value :
false;
801template <
class T,
class U>
803 return opt.
has_value() ? value == *opt :
false;
806template <
class T,
class U>
808 return opt.
has_value() ? *opt != value :
true;
811template <
class T,
class U>
813 return opt.
has_value() ? value != *opt :
true;
816template <
class T,
class U>
818 return opt.
has_value() ? *opt < value :
true;
821template <
class T,
class U>
823 return opt.
has_value() ? value < *opt :
false;
826template <
class T,
class U>
828 return opt.
has_value() ? *opt <= value :
true;
831template <
class T,
class U>
833 return opt.
has_value() ? value <= *opt :
false;
836template <
class T,
class U>
838 return opt.
has_value() ? *opt > value :
false;
841template <
class T,
class U>
843 return opt.
has_value() ? value > *opt :
true;
846template <
class T,
class U>
848 return opt.
has_value() ? *opt >= value :
false;
851template <
class T,
class U>
853 return opt.
has_value() ? value >= *opt :
true;
856#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
857template <
class T,
class... Args>
858CONSTEXPR Optional<T> make_optional(Args&&... args) {
859 return Optional<T>(
in_place, std::forward<Args>(args)...);
862template <
class T,
class U,
class... Args>
863CONSTEXPR Optional<T> make_optional(std::initializer_list<U> il,
865 return Optional<T>(
in_place, il, std::forward<Args>(args)...);
880#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
883struct hash<
agora::Optional<T> > {
#define NOEXCEPT(Expr)
Definition: AgoraOptional.h:26
#define OPTIONAL_DECLSPEC_EMPTY_BASES
Definition: AgoraOptional.h:380
#define CONSTEXPR
Definition: AgoraOptional.h:18
Definition: AgoraOptional.h:413
CONSTEXPR T value_or(const U &default_value) const
Definition: AgoraOptional.h:559
Optional & operator=(nullopt_t)
Definition: AgoraOptional.h:481
T value_type
Definition: AgoraOptional.h:417
CONSTEXPR Optional(const U &value)
Definition: AgoraOptional.h:465
Optional & operator=(const U &value)
Definition: AgoraOptional.h:494
const T & operator*() const
Definition: AgoraOptional.h:524
T * operator->()
Definition: AgoraOptional.h:520
T & emplace(const U il[], const T &_value)
Definition: AgoraOptional.h:659
Optional & operator=(const Optional &other)
Definition: AgoraOptional.h:472
CONSTEXPR Optional(nullopt_t)
Definition: AgoraOptional.h:423
Optional & operator=(const Optional< U > &other)
Definition: AgoraOptional.h:502
CONSTEXPR Optional(in_place_t, const U il[], const T &_value)
Definition: AgoraOptional.h:451
void swap(Optional &other)
Definition: AgoraOptional.h:616
CONSTEXPR Optional()
Definition: AgoraOptional.h:420
void reset()
Definition: AgoraOptional.h:636
~Optional()
Definition: AgoraOptional.h:469
CONSTEXPR Optional(in_place_t, const T &_value)
Definition: AgoraOptional.h:448
T & operator*()
Definition: AgoraOptional.h:528
CONSTEXPR bool has_value() const
Definition: AgoraOptional.h:539
T & emplace(const T &_value)
Definition: AgoraOptional.h:653
CONSTEXPR Optional(const Optional &other)
Definition: AgoraOptional.h:421
Optional(const Optional< U > &other)
Definition: AgoraOptional.h:430
const T * operator->() const
Definition: AgoraOptional.h:516
const T & value() const
Definition: AgoraOptional.h:542
Definition: AgoraOptional.h:160
OptionalStorage< T > storage_
Definition: AgoraOptional.h:257
CONSTEXPR OptionalBase(in_place_t, const T &_value)
Definition: AgoraOptional.h:174
void FreeIfNeeded()
Definition: AgoraOptional.h:245
OptionalBase(const OptionalBase< U > &other)
Definition: AgoraOptional.h:180
void InitOrAssign(const U &value)
Definition: AgoraOptional.h:236
CONSTEXPR OptionalBase(const OptionalBase &other)
Definition: AgoraOptional.h:166
OptionalBase & operator=(const OptionalBase &other)
Definition: AgoraOptional.h:195
CONSTEXPR OptionalBase()
Definition: AgoraOptional.h:165
friend class OptionalBase
Definition: AgoraOptional.h:255
void CopyAssign(const OptionalBase< U > &other)
Definition: AgoraOptional.h:210
~OptionalBase()
Definition: AgoraOptional.h:193
Definition: AgoraBase.h:86
void swap(Optional< T > &lhs, Optional< T > &rhs)
Definition: AgoraOptional.h:874
bool operator!=(const Optional< T > &lhs, const Optional< U > &rhs)
Definition: AgoraOptional.h:692
const in_place_t in_place
Definition: AgoraOptional.h:44
bool operator==(const Optional< T > &lhs, const Optional< U > &rhs)
Definition: AgoraOptional.h:683
bool operator>=(const Optional< T > &lhs, const Optional< U > &rhs)
Definition: AgoraOptional.h:728
bool operator<(const Optional< T > &lhs, const Optional< U > &rhs)
Definition: AgoraOptional.h:701
bool operator<=(const Optional< T > &lhs, const Optional< U > &rhs)
Definition: AgoraOptional.h:710
const nullopt_t nullopt(0)
bool operator>(const Optional< T > &lhs, const Optional< U > &rhs)
Definition: AgoraOptional.h:719
Definition: AgoraOptional.h:34
CONSTEXPR CopyAssignable(const CopyAssignable &)
Definition: AgoraOptional.h:300
CONSTEXPR CopyAssignable()
Definition: AgoraOptional.h:299
Definition: AgoraOptional.h:295
CONSTEXPR CopyConstructible()
Definition: AgoraOptional.h:269
CopyConstructible & operator=(const CopyConstructible &)
Definition: AgoraOptional.h:270
Definition: AgoraOptional.h:265
MoveAssignable & operator=(const MoveAssignable &)
Definition: AgoraOptional.h:316
CONSTEXPR MoveAssignable()
Definition: AgoraOptional.h:314
CONSTEXPR MoveAssignable(const MoveAssignable &)
Definition: AgoraOptional.h:315
Definition: AgoraOptional.h:310
MoveConstructible & operator=(const MoveConstructible &)
Definition: AgoraOptional.h:286
CONSTEXPR MoveConstructible(const MoveConstructible &)
Definition: AgoraOptional.h:285
CONSTEXPR MoveConstructible()
Definition: AgoraOptional.h:284
Definition: AgoraOptional.h:280
Definition: AgoraOptional.h:57
char empty_
Definition: AgoraOptional.h:105
CONSTEXPR OptionalStorageBase(in_place_t, const T &_value)
Definition: AgoraOptional.h:67
~OptionalStorageBase()
Definition: AgoraOptional.h:81
void Init(const T &_value)
Definition: AgoraOptional.h:93
bool is_populated_
Definition: AgoraOptional.h:99
CONSTEXPR OptionalStorageBase()
Definition: AgoraOptional.h:60
T value_
Definition: AgoraOptional.h:106
Definition: AgoraOptional.h:118
CONSTEXPR OptionalStorage(in_place_t in_place, const T &_value)
Definition: AgoraOptional.h:136
OptionalStorage(const OptionalStorage &other)
Definition: AgoraOptional.h:144
OptionalStorage()
Definition: AgoraOptional.h:142
Definition: AgoraOptional.h:38
CONSTEXPR nullopt_t(int)
Definition: AgoraOptional.h:39