00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #ifndef ABSL_TYPES_OPTIONAL_H_
00036 #define ABSL_TYPES_OPTIONAL_H_
00037
00038 #include "absl/base/config.h"
00039 #include "absl/utility/utility.h"
00040
00041 #ifdef ABSL_HAVE_STD_OPTIONAL
00042
00043 #include <optional>
00044
00045 namespace absl {
00046 using std::bad_optional_access;
00047 using std::optional;
00048 using std::make_optional;
00049 using std::nullopt_t;
00050 using std::nullopt;
00051 }
00052
00053 #else // ABSL_HAVE_STD_OPTIONAL
00054
00055 #include <cassert>
00056 #include <functional>
00057 #include <initializer_list>
00058 #include <type_traits>
00059 #include <utility>
00060
00061 #include "absl/base/attributes.h"
00062 #include "absl/base/internal/inline_variable.h"
00063 #include "absl/meta/type_traits.h"
00064 #include "absl/types/bad_optional_access.h"
00065 #include "absl/types/internal/optional.h"
00066
00067 namespace absl {
00068
00069
00070
00071
00072
00073 struct nullopt_t {
00074
00075 explicit constexpr nullopt_t(optional_internal::init_t) noexcept {}
00076 };
00077
00078
00079
00080
00081
00082 ABSL_INTERNAL_INLINE_CONSTEXPR(nullopt_t, nullopt,
00083 nullopt_t(optional_internal::init_t()));
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115 template <typename T>
00116 class optional : private optional_internal::optional_data<T>,
00117 private optional_internal::optional_ctor_base<
00118 optional_internal::ctor_copy_traits<T>::traits>,
00119 private optional_internal::optional_assign_base<
00120 optional_internal::assign_copy_traits<T>::traits> {
00121 using data_base = optional_internal::optional_data<T>;
00122
00123 public:
00124 typedef T value_type;
00125
00126
00127
00128
00129
00130 constexpr optional() noexcept {}
00131
00132
00133 constexpr optional(nullopt_t) noexcept {}
00134
00135
00136 optional(const optional& src) = default;
00137
00138
00139 optional(optional&& src) = default;
00140
00141
00142
00143
00144
00145 template <typename InPlaceT, typename... Args,
00146 absl::enable_if_t<absl::conjunction<
00147 std::is_same<InPlaceT, in_place_t>,
00148 std::is_constructible<T, Args&&...> >::value>* = nullptr>
00149 constexpr explicit optional(InPlaceT, Args&&... args)
00150 : data_base(in_place_t(), absl::forward<Args>(args)...) {}
00151
00152
00153
00154
00155
00156 template <typename U, typename... Args,
00157 typename = typename std::enable_if<std::is_constructible<
00158 T, std::initializer_list<U>&, Args&&...>::value>::type>
00159 constexpr explicit optional(in_place_t, std::initializer_list<U> il,
00160 Args&&... args)
00161 : data_base(in_place_t(), il, absl::forward<Args>(args)...) {
00162 }
00163
00164
00165 template <
00166 typename U = T,
00167 typename std::enable_if<
00168 absl::conjunction<absl::negation<std::is_same<
00169 in_place_t, typename std::decay<U>::type> >,
00170 absl::negation<std::is_same<
00171 optional<T>, typename std::decay<U>::type> >,
00172 std::is_convertible<U&&, T>,
00173 std::is_constructible<T, U&&> >::value,
00174 bool>::type = false>
00175 constexpr optional(U&& v) : data_base(in_place_t(), absl::forward<U>(v)) {}
00176
00177
00178 template <
00179 typename U = T,
00180 typename std::enable_if<
00181 absl::conjunction<absl::negation<std::is_same<
00182 in_place_t, typename std::decay<U>::type>>,
00183 absl::negation<std::is_same<
00184 optional<T>, typename std::decay<U>::type>>,
00185 absl::negation<std::is_convertible<U&&, T>>,
00186 std::is_constructible<T, U&&>>::value,
00187 bool>::type = false>
00188 explicit constexpr optional(U&& v)
00189 : data_base(in_place_t(), absl::forward<U>(v)) {}
00190
00191
00192 template <typename U,
00193 typename std::enable_if<
00194 absl::conjunction<
00195 absl::negation<std::is_same<T, U> >,
00196 std::is_constructible<T, const U&>,
00197 absl::negation<
00198 optional_internal::
00199 is_constructible_convertible_from_optional<T, U> >,
00200 std::is_convertible<const U&, T> >::value,
00201 bool>::type = false>
00202 optional(const optional<U>& rhs) {
00203 if (rhs) {
00204 this->construct(*rhs);
00205 }
00206 }
00207
00208
00209 template <typename U,
00210 typename std::enable_if<
00211 absl::conjunction<
00212 absl::negation<std::is_same<T, U>>,
00213 std::is_constructible<T, const U&>,
00214 absl::negation<
00215 optional_internal::
00216 is_constructible_convertible_from_optional<T, U>>,
00217 absl::negation<std::is_convertible<const U&, T>>>::value,
00218 bool>::type = false>
00219 explicit optional(const optional<U>& rhs) {
00220 if (rhs) {
00221 this->construct(*rhs);
00222 }
00223 }
00224
00225
00226 template <typename U,
00227 typename std::enable_if<
00228 absl::conjunction<
00229 absl::negation<std::is_same<T, U> >,
00230 std::is_constructible<T, U&&>,
00231 absl::negation<
00232 optional_internal::
00233 is_constructible_convertible_from_optional<T, U> >,
00234 std::is_convertible<U&&, T> >::value,
00235 bool>::type = false>
00236 optional(optional<U>&& rhs) {
00237 if (rhs) {
00238 this->construct(std::move(*rhs));
00239 }
00240 }
00241
00242
00243 template <
00244 typename U,
00245 typename std::enable_if<
00246 absl::conjunction<
00247 absl::negation<std::is_same<T, U>>, std::is_constructible<T, U&&>,
00248 absl::negation<
00249 optional_internal::is_constructible_convertible_from_optional<
00250 T, U>>,
00251 absl::negation<std::is_convertible<U&&, T>>>::value,
00252 bool>::type = false>
00253 explicit optional(optional<U>&& rhs) {
00254 if (rhs) {
00255 this->construct(std::move(*rhs));
00256 }
00257 }
00258
00259
00260 ~optional() = default;
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270 optional& operator=(nullopt_t) noexcept {
00271 this->destruct();
00272 return *this;
00273 }
00274
00275
00276 optional& operator=(const optional& src) = default;
00277
00278
00279 optional& operator=(optional&& src) = default;
00280
00281
00282 template <
00283 typename U = T,
00284 typename = typename std::enable_if<absl::conjunction<
00285 absl::negation<
00286 std::is_same<optional<T>, typename std::decay<U>::type>>,
00287 absl::negation<
00288 absl::conjunction<std::is_scalar<T>,
00289 std::is_same<T, typename std::decay<U>::type>>>,
00290 std::is_constructible<T, U>, std::is_assignable<T&, U>>::value>::type>
00291 optional& operator=(U&& v) {
00292 this->assign(std::forward<U>(v));
00293 return *this;
00294 }
00295
00296 template <
00297 typename U,
00298 typename = typename std::enable_if<absl::conjunction<
00299 absl::negation<std::is_same<T, U>>,
00300 std::is_constructible<T, const U&>, std::is_assignable<T&, const U&>,
00301 absl::negation<
00302 optional_internal::
00303 is_constructible_convertible_assignable_from_optional<
00304 T, U>>>::value>::type>
00305 optional& operator=(const optional<U>& rhs) {
00306 if (rhs) {
00307 this->assign(*rhs);
00308 } else {
00309 this->destruct();
00310 }
00311 return *this;
00312 }
00313
00314 template <typename U,
00315 typename = typename std::enable_if<absl::conjunction<
00316 absl::negation<std::is_same<T, U>>, std::is_constructible<T, U>,
00317 std::is_assignable<T&, U>,
00318 absl::negation<
00319 optional_internal::
00320 is_constructible_convertible_assignable_from_optional<
00321 T, U>>>::value>::type>
00322 optional& operator=(optional<U>&& rhs) {
00323 if (rhs) {
00324 this->assign(std::move(*rhs));
00325 } else {
00326 this->destruct();
00327 }
00328 return *this;
00329 }
00330
00331
00332
00333
00334
00335
00336 ABSL_ATTRIBUTE_REINITIALIZES void reset() noexcept { this->destruct(); }
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351 template <typename... Args,
00352 typename = typename std::enable_if<
00353 std::is_constructible<T, Args&&...>::value>::type>
00354 T& emplace(Args&&... args) {
00355 this->destruct();
00356 this->construct(std::forward<Args>(args)...);
00357 return reference();
00358 }
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371 template <typename U, typename... Args,
00372 typename = typename std::enable_if<std::is_constructible<
00373 T, std::initializer_list<U>&, Args&&...>::value>::type>
00374 T& emplace(std::initializer_list<U> il, Args&&... args) {
00375 this->destruct();
00376 this->construct(il, std::forward<Args>(args)...);
00377 return reference();
00378 }
00379
00380
00381
00382
00383 void swap(optional& rhs) noexcept(
00384 std::is_nothrow_move_constructible<T>::value&&
00385 type_traits_internal::IsNothrowSwappable<T>::value) {
00386 if (*this) {
00387 if (rhs) {
00388 type_traits_internal::Swap(**this, *rhs);
00389 } else {
00390 rhs.construct(std::move(**this));
00391 this->destruct();
00392 }
00393 } else {
00394 if (rhs) {
00395 this->construct(std::move(*rhs));
00396 rhs.destruct();
00397 } else {
00398
00399 }
00400 }
00401 }
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411 const T* operator->() const {
00412 assert(this->engaged_);
00413 return std::addressof(this->data_);
00414 }
00415 T* operator->() {
00416 assert(this->engaged_);
00417 return std::addressof(this->data_);
00418 }
00419
00420
00421
00422
00423
00424 constexpr const T& operator*() const& {
00425 return ABSL_ASSERT(this->engaged_), reference();
00426 }
00427 T& operator*() & {
00428 assert(this->engaged_);
00429 return reference();
00430 }
00431 constexpr const T&& operator*() const && {
00432 return absl::move(reference());
00433 }
00434 T&& operator*() && {
00435 assert(this->engaged_);
00436 return std::move(reference());
00437 }
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449 constexpr explicit operator bool() const noexcept { return this->engaged_; }
00450
00451
00452
00453
00454
00455 constexpr bool has_value() const noexcept { return this->engaged_; }
00456
00457
00458
00459 #ifdef _MSC_VER
00460 #pragma warning(push)
00461 #pragma warning(disable : 4702)
00462 #endif // _MSC_VER
00463
00464
00465
00466
00467
00468
00469 constexpr const T& value() const & {
00470 return static_cast<bool>(*this)
00471 ? reference()
00472 : (optional_internal::throw_bad_optional_access(), reference());
00473 }
00474 T& value() & {
00475 return static_cast<bool>(*this)
00476 ? reference()
00477 : (optional_internal::throw_bad_optional_access(), reference());
00478 }
00479 T&& value() && {
00480 return std::move(
00481 static_cast<bool>(*this)
00482 ? reference()
00483 : (optional_internal::throw_bad_optional_access(), reference()));
00484 }
00485 constexpr const T&& value() const && {
00486 return absl::move(
00487 static_cast<bool>(*this)
00488 ? reference()
00489 : (optional_internal::throw_bad_optional_access(), reference()));
00490 }
00491 #ifdef _MSC_VER
00492 #pragma warning(pop)
00493 #endif // _MSC_VER
00494
00495
00496
00497
00498
00499 template <typename U>
00500 constexpr T value_or(U&& v) const& {
00501 static_assert(std::is_copy_constructible<value_type>::value,
00502 "optional<T>::value_or: T must by copy constructible");
00503 static_assert(std::is_convertible<U&&, value_type>::value,
00504 "optional<T>::value_or: U must be convertible to T");
00505 return static_cast<bool>(*this)
00506 ? **this
00507 : static_cast<T>(absl::forward<U>(v));
00508 }
00509 template <typename U>
00510 T value_or(U&& v) && {
00511 static_assert(std::is_move_constructible<value_type>::value,
00512 "optional<T>::value_or: T must by move constructible");
00513 static_assert(std::is_convertible<U&&, value_type>::value,
00514 "optional<T>::value_or: U must be convertible to T");
00515 return static_cast<bool>(*this) ? std::move(**this)
00516 : static_cast<T>(std::forward<U>(v));
00517 }
00518
00519 private:
00520
00521 constexpr const T& reference() const { return this->data_; }
00522 T& reference() { return this->data_; }
00523
00524
00525
00526 static_assert(
00527 !std::is_same<nullopt_t, typename std::remove_cv<T>::type>::value,
00528 "optional<nullopt_t> is not allowed.");
00529 static_assert(
00530 !std::is_same<in_place_t, typename std::remove_cv<T>::type>::value,
00531 "optional<in_place_t> is not allowed.");
00532 static_assert(!std::is_reference<T>::value,
00533 "optional<reference> is not allowed.");
00534 };
00535
00536
00537
00538
00539
00540
00541
00542 template <typename T, typename std::enable_if<
00543 std::is_move_constructible<T>::value &&
00544 type_traits_internal::IsSwappable<T>::value,
00545 bool>::type = false>
00546 void swap(optional<T>& a, optional<T>& b) noexcept(noexcept(a.swap(b))) {
00547 a.swap(b);
00548 }
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565 template <typename T>
00566 constexpr optional<typename std::decay<T>::type> make_optional(T&& v) {
00567 return optional<typename std::decay<T>::type>(absl::forward<T>(v));
00568 }
00569
00570 template <typename T, typename... Args>
00571 constexpr optional<T> make_optional(Args&&... args) {
00572 return optional<T>(in_place_t(), absl::forward<Args>(args)...);
00573 }
00574
00575 template <typename T, typename U, typename... Args>
00576 constexpr optional<T> make_optional(std::initializer_list<U> il,
00577 Args&&... args) {
00578 return optional<T>(in_place_t(), il,
00579 absl::forward<Args>(args)...);
00580 }
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596 template <typename T, typename U>
00597 constexpr auto operator==(const optional<T>& x, const optional<U>& y)
00598 -> decltype(optional_internal::convertible_to_bool(*x == *y)) {
00599 return static_cast<bool>(x) != static_cast<bool>(y)
00600 ? false
00601 : static_cast<bool>(x) == false ? true
00602 : static_cast<bool>(*x == *y);
00603 }
00604
00605
00606
00607 template <typename T, typename U>
00608 constexpr auto operator!=(const optional<T>& x, const optional<U>& y)
00609 -> decltype(optional_internal::convertible_to_bool(*x != *y)) {
00610 return static_cast<bool>(x) != static_cast<bool>(y)
00611 ? true
00612 : static_cast<bool>(x) == false ? false
00613 : static_cast<bool>(*x != *y);
00614 }
00615
00616 template <typename T, typename U>
00617 constexpr auto operator<(const optional<T>& x, const optional<U>& y)
00618 -> decltype(optional_internal::convertible_to_bool(*x < *y)) {
00619 return !y ? false : !x ? true : static_cast<bool>(*x < *y);
00620 }
00621
00622 template <typename T, typename U>
00623 constexpr auto operator>(const optional<T>& x, const optional<U>& y)
00624 -> decltype(optional_internal::convertible_to_bool(*x > *y)) {
00625 return !x ? false : !y ? true : static_cast<bool>(*x > *y);
00626 }
00627
00628 template <typename T, typename U>
00629 constexpr auto operator<=(const optional<T>& x, const optional<U>& y)
00630 -> decltype(optional_internal::convertible_to_bool(*x <= *y)) {
00631 return !x ? true : !y ? false : static_cast<bool>(*x <= *y);
00632 }
00633
00634 template <typename T, typename U>
00635 constexpr auto operator>=(const optional<T>& x, const optional<U>& y)
00636 -> decltype(optional_internal::convertible_to_bool(*x >= *y)) {
00637 return !y ? true : !x ? false : static_cast<bool>(*x >= *y);
00638 }
00639
00640
00641
00642 template <typename T>
00643 constexpr bool operator==(const optional<T>& x, nullopt_t) noexcept {
00644 return !x;
00645 }
00646 template <typename T>
00647 constexpr bool operator==(nullopt_t, const optional<T>& x) noexcept {
00648 return !x;
00649 }
00650 template <typename T>
00651 constexpr bool operator!=(const optional<T>& x, nullopt_t) noexcept {
00652 return static_cast<bool>(x);
00653 }
00654 template <typename T>
00655 constexpr bool operator!=(nullopt_t, const optional<T>& x) noexcept {
00656 return static_cast<bool>(x);
00657 }
00658 template <typename T>
00659 constexpr bool operator<(const optional<T>&, nullopt_t) noexcept {
00660 return false;
00661 }
00662 template <typename T>
00663 constexpr bool operator<(nullopt_t, const optional<T>& x) noexcept {
00664 return static_cast<bool>(x);
00665 }
00666 template <typename T>
00667 constexpr bool operator<=(const optional<T>& x, nullopt_t) noexcept {
00668 return !x;
00669 }
00670 template <typename T>
00671 constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept {
00672 return true;
00673 }
00674 template <typename T>
00675 constexpr bool operator>(const optional<T>& x, nullopt_t) noexcept {
00676 return static_cast<bool>(x);
00677 }
00678 template <typename T>
00679 constexpr bool operator>(nullopt_t, const optional<T>&) noexcept {
00680 return false;
00681 }
00682 template <typename T>
00683 constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept {
00684 return true;
00685 }
00686 template <typename T>
00687 constexpr bool operator>=(nullopt_t, const optional<T>& x) noexcept {
00688 return !x;
00689 }
00690
00691
00692
00693
00694
00695
00696 template <typename T, typename U>
00697 constexpr auto operator==(const optional<T>& x, const U& v)
00698 -> decltype(optional_internal::convertible_to_bool(*x == v)) {
00699 return static_cast<bool>(x) ? static_cast<bool>(*x == v) : false;
00700 }
00701 template <typename T, typename U>
00702 constexpr auto operator==(const U& v, const optional<T>& x)
00703 -> decltype(optional_internal::convertible_to_bool(v == *x)) {
00704 return static_cast<bool>(x) ? static_cast<bool>(v == *x) : false;
00705 }
00706 template <typename T, typename U>
00707 constexpr auto operator!=(const optional<T>& x, const U& v)
00708 -> decltype(optional_internal::convertible_to_bool(*x != v)) {
00709 return static_cast<bool>(x) ? static_cast<bool>(*x != v) : true;
00710 }
00711 template <typename T, typename U>
00712 constexpr auto operator!=(const U& v, const optional<T>& x)
00713 -> decltype(optional_internal::convertible_to_bool(v != *x)) {
00714 return static_cast<bool>(x) ? static_cast<bool>(v != *x) : true;
00715 }
00716 template <typename T, typename U>
00717 constexpr auto operator<(const optional<T>& x, const U& v)
00718 -> decltype(optional_internal::convertible_to_bool(*x < v)) {
00719 return static_cast<bool>(x) ? static_cast<bool>(*x < v) : true;
00720 }
00721 template <typename T, typename U>
00722 constexpr auto operator<(const U& v, const optional<T>& x)
00723 -> decltype(optional_internal::convertible_to_bool(v < *x)) {
00724 return static_cast<bool>(x) ? static_cast<bool>(v < *x) : false;
00725 }
00726 template <typename T, typename U>
00727 constexpr auto operator<=(const optional<T>& x, const U& v)
00728 -> decltype(optional_internal::convertible_to_bool(*x <= v)) {
00729 return static_cast<bool>(x) ? static_cast<bool>(*x <= v) : true;
00730 }
00731 template <typename T, typename U>
00732 constexpr auto operator<=(const U& v, const optional<T>& x)
00733 -> decltype(optional_internal::convertible_to_bool(v <= *x)) {
00734 return static_cast<bool>(x) ? static_cast<bool>(v <= *x) : false;
00735 }
00736 template <typename T, typename U>
00737 constexpr auto operator>(const optional<T>& x, const U& v)
00738 -> decltype(optional_internal::convertible_to_bool(*x > v)) {
00739 return static_cast<bool>(x) ? static_cast<bool>(*x > v) : false;
00740 }
00741 template <typename T, typename U>
00742 constexpr auto operator>(const U& v, const optional<T>& x)
00743 -> decltype(optional_internal::convertible_to_bool(v > *x)) {
00744 return static_cast<bool>(x) ? static_cast<bool>(v > *x) : true;
00745 }
00746 template <typename T, typename U>
00747 constexpr auto operator>=(const optional<T>& x, const U& v)
00748 -> decltype(optional_internal::convertible_to_bool(*x >= v)) {
00749 return static_cast<bool>(x) ? static_cast<bool>(*x >= v) : false;
00750 }
00751 template <typename T, typename U>
00752 constexpr auto operator>=(const U& v, const optional<T>& x)
00753 -> decltype(optional_internal::convertible_to_bool(v >= *x)) {
00754 return static_cast<bool>(x) ? static_cast<bool>(v >= *x) : true;
00755 }
00756
00757 }
00758
00759 namespace std {
00760
00761
00762 template <typename T>
00763 struct hash<absl::optional<T> >
00764 : absl::optional_internal::optional_hash_base<T> {};
00765
00766 }
00767
00768 #undef ABSL_MSVC_CONSTEXPR_BUG_IN_UNION_LIKE_CLASS
00769
00770 #endif // ABSL_HAVE_STD_OPTIONAL
00771
00772 #endif // ABSL_TYPES_OPTIONAL_H_