libstdc++
|
00001 // <optional> -*- C++ -*- 00002 00003 // Copyright (C) 2013-2017 Free Software Foundation, Inc. 00004 // 00005 // This file is part of the GNU ISO C++ Library. This library is free 00006 // software; you can redistribute it and/or modify it under the 00007 // terms of the GNU General Public License as published by the 00008 // Free Software Foundation; either version 3, or (at your option) 00009 // any later version. 00010 00011 // This library is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 00016 // Under Section 7 of GPL version 3, you are granted additional 00017 // permissions described in the GCC Runtime Library Exception, version 00018 // 3.1, as published by the Free Software Foundation. 00019 00020 // You should have received a copy of the GNU General Public License and 00021 // a copy of the GCC Runtime Library Exception along with this program; 00022 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00023 // <http://www.gnu.org/licenses/>. 00024 00025 /** @file experimental/optional 00026 * This is a TS C++ Library header. 00027 */ 00028 00029 #ifndef _GLIBCXX_EXPERIMENTAL_OPTIONAL 00030 #define _GLIBCXX_EXPERIMENTAL_OPTIONAL 1 00031 00032 /** 00033 * @defgroup experimental Experimental 00034 * 00035 * Components specified by various Technical Specifications. 00036 * 00037 * As indicated by the std::experimental namespace and the header paths, 00038 * the contents of these Technical Specifications are experimental and not 00039 * part of the C++ standard. As such the interfaces and implementations may 00040 * change in the future, and there is <STRONG> no guarantee of compatibility 00041 * between different GCC releases </STRONG> for these features. 00042 */ 00043 00044 #if __cplusplus <= 201103L 00045 # include <bits/c++14_warning.h> 00046 #else 00047 00048 #include <utility> 00049 #include <type_traits> 00050 #include <stdexcept> 00051 #include <new> 00052 #include <initializer_list> 00053 #include <bits/functexcept.h> 00054 #include <bits/functional_hash.h> 00055 #include <bits/enable_special_members.h> 00056 #include <experimental/bits/lfts_config.h> 00057 00058 namespace std _GLIBCXX_VISIBILITY(default) 00059 { 00060 namespace experimental 00061 { 00062 inline namespace fundamentals_v1 00063 { 00064 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00065 00066 /** 00067 * @defgroup optional Optional values 00068 * @ingroup experimental 00069 * 00070 * Class template for optional values and surrounding facilities, as 00071 * described in n3793 "A proposal to add a utility class to represent 00072 * optional objects (Revision 5)". 00073 * 00074 * @{ 00075 */ 00076 00077 #define __cpp_lib_experimental_optional 201411 00078 00079 // All subsequent [X.Y.n] references are against n3793. 00080 00081 // [X.Y.4] 00082 template<typename _Tp> 00083 class optional; 00084 00085 // [X.Y.5] 00086 /// Tag type for in-place construction. 00087 struct in_place_t { }; 00088 00089 /// Tag for in-place construction. 00090 constexpr in_place_t in_place { }; 00091 00092 // [X.Y.6] 00093 /// Tag type to disengage optional objects. 00094 struct nullopt_t 00095 { 00096 // Do not user-declare default constructor at all for 00097 // optional_value = {} syntax to work. 00098 // nullopt_t() = delete; 00099 00100 // Used for constructing nullopt. 00101 enum class _Construct { _Token }; 00102 00103 // Must be constexpr for nullopt_t to be literal. 00104 explicit constexpr nullopt_t(_Construct) { } 00105 }; 00106 00107 // [X.Y.6] 00108 /// Tag to disengage optional objects. 00109 constexpr nullopt_t nullopt { nullopt_t::_Construct::_Token }; 00110 00111 // [X.Y.7] 00112 /** 00113 * @brief Exception class thrown when a disengaged optional object is 00114 * dereferenced. 00115 * @ingroup exceptions 00116 */ 00117 class bad_optional_access : public logic_error 00118 { 00119 public: 00120 bad_optional_access() : logic_error("bad optional access") { } 00121 00122 // XXX This constructor is non-standard. Should not be inline 00123 explicit bad_optional_access(const char* __arg) : logic_error(__arg) { } 00124 00125 virtual ~bad_optional_access() noexcept = default; 00126 }; 00127 00128 void 00129 __throw_bad_optional_access(const char*) 00130 __attribute__((__noreturn__)); 00131 00132 // XXX Does not belong here. 00133 inline void 00134 __throw_bad_optional_access(const char* __s) 00135 { _GLIBCXX_THROW_OR_ABORT(bad_optional_access(__s)); } 00136 00137 #ifndef __cpp_lib_addressof_constexpr 00138 template<typename _Tp, typename = void> 00139 struct _Has_addressof_mem : std::false_type { }; 00140 00141 template<typename _Tp> 00142 struct _Has_addressof_mem<_Tp, 00143 __void_t<decltype( std::declval<const _Tp&>().operator&() )> 00144 > 00145 : std::true_type { }; 00146 00147 template<typename _Tp, typename = void> 00148 struct _Has_addressof_free : std::false_type { }; 00149 00150 template<typename _Tp> 00151 struct _Has_addressof_free<_Tp, 00152 __void_t<decltype( operator&(std::declval<const _Tp&>()) )> 00153 > 00154 : std::true_type { }; 00155 00156 /** 00157 * @brief Trait that detects the presence of an overloaded unary operator&. 00158 * 00159 * Practically speaking this detects the presence of such an operator when 00160 * called on a const-qualified lvalue (e.g. 00161 * declval<const _Tp&>().operator&()). 00162 */ 00163 template<typename _Tp> 00164 struct _Has_addressof 00165 : std::__or_<_Has_addressof_mem<_Tp>, _Has_addressof_free<_Tp>>::type 00166 { }; 00167 00168 /** 00169 * @brief An overload that attempts to take the address of an lvalue as a 00170 * constant expression. Falls back to __addressof in the presence of an 00171 * overloaded addressof operator (unary operator&), in which case the call 00172 * will not be a constant expression. 00173 */ 00174 template<typename _Tp> 00175 constexpr 00176 enable_if_t<!_Has_addressof<_Tp>::value, _Tp*> 00177 __constexpr_addressof(_Tp& __t) 00178 { return &__t; } 00179 00180 /** 00181 * @brief Fallback overload that defers to __addressof. 00182 */ 00183 template<typename _Tp> 00184 inline 00185 enable_if_t<_Has_addressof<_Tp>::value, _Tp*> 00186 __constexpr_addressof(_Tp& __t) 00187 { return std::__addressof(__t); } 00188 #endif // __cpp_lib_addressof_constexpr 00189 00190 /** 00191 * @brief Class template that holds the necessary state for @ref optional 00192 * and that has the responsibility for construction and the special members. 00193 * 00194 * Such a separate base class template is necessary in order to 00195 * conditionally enable the special members (e.g. copy/move constructors). 00196 * Note that this means that @ref _Optional_base implements the 00197 * functionality for copy and move assignment, but not for converting 00198 * assignment. 00199 * 00200 * @see optional, _Enable_special_members 00201 */ 00202 template<typename _Tp, bool _ShouldProvideDestructor = 00203 !is_trivially_destructible<_Tp>::value> 00204 class _Optional_base 00205 { 00206 private: 00207 // Remove const to avoid prohibition of reusing object storage for 00208 // const-qualified types in [3.8/9]. This is strictly internal 00209 // and even optional itself is oblivious to it. 00210 using _Stored_type = remove_const_t<_Tp>; 00211 00212 public: 00213 // [X.Y.4.1] Constructors. 00214 00215 // Constructors for disengaged optionals. 00216 constexpr _Optional_base() noexcept 00217 : _M_empty{} { } 00218 00219 constexpr _Optional_base(nullopt_t) noexcept 00220 : _Optional_base{} { } 00221 00222 // Constructors for engaged optionals. 00223 template<typename... _Args> 00224 constexpr explicit _Optional_base(in_place_t, _Args&&... __args) 00225 : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true) { } 00226 00227 template<typename _Up, typename... _Args, 00228 enable_if_t<is_constructible<_Tp, 00229 initializer_list<_Up>&, 00230 _Args&&...>::value, 00231 int>...> 00232 constexpr explicit _Optional_base(in_place_t, 00233 initializer_list<_Up> __il, 00234 _Args&&... __args) 00235 : _M_payload(__il, std::forward<_Args>(__args)...), 00236 _M_engaged(true) { } 00237 00238 // Copy and move constructors. 00239 _Optional_base(const _Optional_base& __other) 00240 { 00241 if (__other._M_engaged) 00242 this->_M_construct(__other._M_get()); 00243 } 00244 00245 _Optional_base(_Optional_base&& __other) 00246 noexcept(is_nothrow_move_constructible<_Tp>()) 00247 { 00248 if (__other._M_engaged) 00249 this->_M_construct(std::move(__other._M_get())); 00250 } 00251 00252 // [X.Y.4.3] (partly) Assignment. 00253 _Optional_base& 00254 operator=(const _Optional_base& __other) 00255 { 00256 if (this->_M_engaged && __other._M_engaged) 00257 this->_M_get() = __other._M_get(); 00258 else 00259 { 00260 if (__other._M_engaged) 00261 this->_M_construct(__other._M_get()); 00262 else 00263 this->_M_reset(); 00264 } 00265 00266 return *this; 00267 } 00268 00269 _Optional_base& 00270 operator=(_Optional_base&& __other) 00271 noexcept(__and_<is_nothrow_move_constructible<_Tp>, 00272 is_nothrow_move_assignable<_Tp>>()) 00273 { 00274 if (this->_M_engaged && __other._M_engaged) 00275 this->_M_get() = std::move(__other._M_get()); 00276 else 00277 { 00278 if (__other._M_engaged) 00279 this->_M_construct(std::move(__other._M_get())); 00280 else 00281 this->_M_reset(); 00282 } 00283 return *this; 00284 } 00285 00286 // [X.Y.4.2] Destructor. 00287 ~_Optional_base() 00288 { 00289 if (this->_M_engaged) 00290 this->_M_payload.~_Stored_type(); 00291 } 00292 00293 // The following functionality is also needed by optional, hence the 00294 // protected accessibility. 00295 protected: 00296 constexpr bool _M_is_engaged() const noexcept 00297 { return this->_M_engaged; } 00298 00299 // The _M_get operations have _M_engaged as a precondition. 00300 constexpr _Tp& 00301 _M_get() noexcept 00302 { return _M_payload; } 00303 00304 constexpr const _Tp& 00305 _M_get() const noexcept 00306 { return _M_payload; } 00307 00308 // The _M_construct operation has !_M_engaged as a precondition 00309 // while _M_destruct has _M_engaged as a precondition. 00310 template<typename... _Args> 00311 void 00312 _M_construct(_Args&&... __args) 00313 noexcept(is_nothrow_constructible<_Stored_type, _Args...>()) 00314 { 00315 ::new (std::__addressof(this->_M_payload)) 00316 _Stored_type(std::forward<_Args>(__args)...); 00317 this->_M_engaged = true; 00318 } 00319 00320 void 00321 _M_destruct() 00322 { 00323 this->_M_engaged = false; 00324 this->_M_payload.~_Stored_type(); 00325 } 00326 00327 // _M_reset is a 'safe' operation with no precondition. 00328 void 00329 _M_reset() 00330 { 00331 if (this->_M_engaged) 00332 this->_M_destruct(); 00333 } 00334 00335 private: 00336 struct _Empty_byte { }; 00337 union { 00338 _Empty_byte _M_empty; 00339 _Stored_type _M_payload; 00340 }; 00341 bool _M_engaged = false; 00342 }; 00343 00344 /// Partial specialization that is exactly identical to the primary template 00345 /// save for not providing a destructor, to fulfill triviality requirements. 00346 template<typename _Tp> 00347 class _Optional_base<_Tp, false> 00348 { 00349 private: 00350 using _Stored_type = remove_const_t<_Tp>; 00351 00352 public: 00353 constexpr _Optional_base() noexcept 00354 : _M_empty{} { } 00355 00356 constexpr _Optional_base(nullopt_t) noexcept 00357 : _Optional_base{} { } 00358 00359 template<typename... _Args> 00360 constexpr explicit _Optional_base(in_place_t, _Args&&... __args) 00361 : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true) { } 00362 00363 template<typename _Up, typename... _Args, 00364 enable_if_t<is_constructible<_Tp, 00365 initializer_list<_Up>&, 00366 _Args&&...>::value, 00367 int>...> 00368 constexpr explicit _Optional_base(in_place_t, 00369 initializer_list<_Up> __il, 00370 _Args&&... __args) 00371 : _M_payload(__il, std::forward<_Args>(__args)...), 00372 _M_engaged(true) { } 00373 00374 _Optional_base(const _Optional_base& __other) 00375 { 00376 if (__other._M_engaged) 00377 this->_M_construct(__other._M_get()); 00378 } 00379 00380 _Optional_base(_Optional_base&& __other) 00381 noexcept(is_nothrow_move_constructible<_Tp>()) 00382 { 00383 if (__other._M_engaged) 00384 this->_M_construct(std::move(__other._M_get())); 00385 } 00386 00387 _Optional_base& 00388 operator=(const _Optional_base& __other) 00389 { 00390 if (this->_M_engaged && __other._M_engaged) 00391 this->_M_get() = __other._M_get(); 00392 else 00393 { 00394 if (__other._M_engaged) 00395 this->_M_construct(__other._M_get()); 00396 else 00397 this->_M_reset(); 00398 } 00399 return *this; 00400 } 00401 00402 _Optional_base& 00403 operator=(_Optional_base&& __other) 00404 noexcept(__and_<is_nothrow_move_constructible<_Tp>, 00405 is_nothrow_move_assignable<_Tp>>()) 00406 { 00407 if (this->_M_engaged && __other._M_engaged) 00408 this->_M_get() = std::move(__other._M_get()); 00409 else 00410 { 00411 if (__other._M_engaged) 00412 this->_M_construct(std::move(__other._M_get())); 00413 else 00414 this->_M_reset(); 00415 } 00416 return *this; 00417 } 00418 00419 // Sole difference 00420 // ~_Optional_base() noexcept = default; 00421 00422 protected: 00423 constexpr bool _M_is_engaged() const noexcept 00424 { return this->_M_engaged; } 00425 00426 _Tp& 00427 _M_get() noexcept 00428 { return _M_payload; } 00429 00430 constexpr const _Tp& 00431 _M_get() const noexcept 00432 { return _M_payload; } 00433 00434 template<typename... _Args> 00435 void 00436 _M_construct(_Args&&... __args) 00437 noexcept(is_nothrow_constructible<_Stored_type, _Args...>()) 00438 { 00439 ::new (std::__addressof(this->_M_payload)) 00440 _Stored_type(std::forward<_Args>(__args)...); 00441 this->_M_engaged = true; 00442 } 00443 00444 void 00445 _M_destruct() 00446 { 00447 this->_M_engaged = false; 00448 this->_M_payload.~_Stored_type(); 00449 } 00450 00451 void 00452 _M_reset() 00453 { 00454 if (this->_M_engaged) 00455 this->_M_destruct(); 00456 } 00457 00458 private: 00459 struct _Empty_byte { }; 00460 union 00461 { 00462 _Empty_byte _M_empty; 00463 _Stored_type _M_payload; 00464 }; 00465 bool _M_engaged = false; 00466 }; 00467 00468 template<typename _Tp> 00469 class optional; 00470 00471 template<typename _Tp, typename _Up> 00472 using __converts_from_optional = 00473 __or_<is_constructible<_Tp, const optional<_Up>&>, 00474 is_constructible<_Tp, optional<_Up>&>, 00475 is_constructible<_Tp, const optional<_Up>&&>, 00476 is_constructible<_Tp, optional<_Up>&&>, 00477 is_convertible<const optional<_Up>&, _Tp>, 00478 is_convertible<optional<_Up>&, _Tp>, 00479 is_convertible<const optional<_Up>&&, _Tp>, 00480 is_convertible<optional<_Up>&&, _Tp>>; 00481 00482 template<typename _Tp, typename _Up> 00483 using __assigns_from_optional = 00484 __or_<is_assignable<_Tp&, const optional<_Up>&>, 00485 is_assignable<_Tp&, optional<_Up>&>, 00486 is_assignable<_Tp&, const optional<_Up>&&>, 00487 is_assignable<_Tp&, optional<_Up>&&>>; 00488 00489 /** 00490 * @brief Class template for optional values. 00491 */ 00492 template<typename _Tp> 00493 class optional 00494 : private _Optional_base<_Tp>, 00495 private _Enable_copy_move< 00496 // Copy constructor. 00497 is_copy_constructible<_Tp>::value, 00498 // Copy assignment. 00499 __and_<is_copy_constructible<_Tp>, is_copy_assignable<_Tp>>::value, 00500 // Move constructor. 00501 is_move_constructible<_Tp>::value, 00502 // Move assignment. 00503 __and_<is_move_constructible<_Tp>, is_move_assignable<_Tp>>::value, 00504 // Unique tag type. 00505 optional<_Tp>> 00506 { 00507 static_assert(__and_<__not_<is_same<remove_cv_t<_Tp>, nullopt_t>>, 00508 __not_<is_same<remove_cv_t<_Tp>, in_place_t>>, 00509 __not_<is_reference<_Tp>>>(), 00510 "Invalid instantiation of optional<T>"); 00511 00512 private: 00513 using _Base = _Optional_base<_Tp>; 00514 00515 public: 00516 using value_type = _Tp; 00517 00518 // _Optional_base has the responsibility for construction. 00519 using _Base::_Base; 00520 00521 constexpr optional() = default; 00522 // Converting constructors for engaged optionals. 00523 template <typename _Up = _Tp, 00524 enable_if_t<__and_< 00525 __not_<is_same<optional<_Tp>, decay_t<_Up>>>, 00526 is_constructible<_Tp, _Up&&>, 00527 is_convertible<_Up&&, _Tp> 00528 >::value, bool> = true> 00529 constexpr optional(_Up&& __t) 00530 : _Base(in_place, std::forward<_Up>(__t)) { } 00531 00532 template <typename _Up = _Tp, 00533 enable_if_t<__and_< 00534 __not_<is_same<optional<_Tp>, decay_t<_Up>>>, 00535 is_constructible<_Tp, _Up&&>, 00536 __not_<is_convertible<_Up&&, _Tp>> 00537 >::value, bool> = false> 00538 explicit constexpr optional(_Up&& __t) 00539 : _Base(in_place, std::forward<_Up>(__t)) { } 00540 00541 template <typename _Up, 00542 enable_if_t<__and_< 00543 __not_<is_same<_Tp, _Up>>, 00544 is_constructible<_Tp, const _Up&>, 00545 is_convertible<const _Up&, _Tp>, 00546 __not_<__converts_from_optional<_Tp, _Up>> 00547 >::value, bool> = true> 00548 constexpr optional(const optional<_Up>& __t) 00549 { 00550 if (__t) 00551 emplace(*__t); 00552 } 00553 00554 template <typename _Up, 00555 enable_if_t<__and_< 00556 __not_<is_same<_Tp, _Up>>, 00557 is_constructible<_Tp, const _Up&>, 00558 __not_<is_convertible<const _Up&, _Tp>>, 00559 __not_<__converts_from_optional<_Tp, _Up>> 00560 >::value, bool> = false> 00561 explicit constexpr optional(const optional<_Up>& __t) 00562 { 00563 if (__t) 00564 emplace(*__t); 00565 } 00566 00567 template <typename _Up, 00568 enable_if_t<__and_< 00569 __not_<is_same<_Tp, _Up>>, 00570 is_constructible<_Tp, _Up&&>, 00571 is_convertible<_Up&&, _Tp>, 00572 __not_<__converts_from_optional<_Tp, _Up>> 00573 >::value, bool> = true> 00574 constexpr optional(optional<_Up>&& __t) 00575 { 00576 if (__t) 00577 emplace(std::move(*__t)); 00578 } 00579 00580 template <typename _Up, 00581 enable_if_t<__and_< 00582 __not_<is_same<_Tp, _Up>>, 00583 is_constructible<_Tp, _Up&&>, 00584 __not_<is_convertible<_Up&&, _Tp>>, 00585 __not_<__converts_from_optional<_Tp, _Up>> 00586 >::value, bool> = false> 00587 explicit constexpr optional(optional<_Up>&& __t) 00588 { 00589 if (__t) 00590 emplace(std::move(*__t)); 00591 } 00592 00593 // [X.Y.4.3] (partly) Assignment. 00594 optional& 00595 operator=(nullopt_t) noexcept 00596 { 00597 this->_M_reset(); 00598 return *this; 00599 } 00600 00601 template<typename _Up = _Tp> 00602 enable_if_t<__and_< 00603 __not_<is_same<optional<_Tp>, decay_t<_Up>>>, 00604 is_constructible<_Tp, _Up>, 00605 __not_<__and_<is_scalar<_Tp>, 00606 is_same<_Tp, decay_t<_Up>>>>, 00607 is_assignable<_Tp&, _Up>>::value, 00608 optional&> 00609 operator=(_Up&& __u) 00610 { 00611 if (this->_M_is_engaged()) 00612 this->_M_get() = std::forward<_Up>(__u); 00613 else 00614 this->_M_construct(std::forward<_Up>(__u)); 00615 00616 return *this; 00617 } 00618 00619 template<typename _Up> 00620 enable_if_t<__and_< 00621 __not_<is_same<_Tp, _Up>>, 00622 is_constructible<_Tp, const _Up&>, 00623 is_assignable<_Tp&, _Up>, 00624 __not_<__converts_from_optional<_Tp, _Up>>, 00625 __not_<__assigns_from_optional<_Tp, _Up>> 00626 >::value, 00627 optional&> 00628 operator=(const optional<_Up>& __u) 00629 { 00630 if (__u) 00631 { 00632 if (this->_M_is_engaged()) 00633 this->_M_get() = *__u; 00634 else 00635 this->_M_construct(*__u); 00636 } 00637 else 00638 { 00639 this->_M_reset(); 00640 } 00641 return *this; 00642 } 00643 00644 template<typename _Up> 00645 enable_if_t<__and_< 00646 __not_<is_same<_Tp, _Up>>, 00647 is_constructible<_Tp, _Up>, 00648 is_assignable<_Tp&, _Up>, 00649 __not_<__converts_from_optional<_Tp, _Up>>, 00650 __not_<__assigns_from_optional<_Tp, _Up>> 00651 >::value, 00652 optional&> 00653 operator=(optional<_Up>&& __u) 00654 { 00655 if (__u) 00656 { 00657 if (this->_M_is_engaged()) 00658 this->_M_get() = std::move(*__u); 00659 else 00660 this->_M_construct(std::move(*__u)); 00661 } 00662 else 00663 { 00664 this->_M_reset(); 00665 } 00666 00667 return *this; 00668 } 00669 00670 template<typename... _Args> 00671 enable_if_t<is_constructible<_Tp, _Args&&...>::value> 00672 emplace(_Args&&... __args) 00673 { 00674 this->_M_reset(); 00675 this->_M_construct(std::forward<_Args>(__args)...); 00676 } 00677 00678 template<typename _Up, typename... _Args> 00679 enable_if_t<is_constructible<_Tp, initializer_list<_Up>&, 00680 _Args&&...>::value> 00681 emplace(initializer_list<_Up> __il, _Args&&... __args) 00682 { 00683 this->_M_reset(); 00684 this->_M_construct(__il, std::forward<_Args>(__args)...); 00685 } 00686 00687 // [X.Y.4.2] Destructor is implicit, implemented in _Optional_base. 00688 00689 // [X.Y.4.4] Swap. 00690 void 00691 swap(optional& __other) 00692 noexcept(is_nothrow_move_constructible<_Tp>() 00693 && noexcept(swap(declval<_Tp&>(), declval<_Tp&>()))) 00694 { 00695 using std::swap; 00696 00697 if (this->_M_is_engaged() && __other._M_is_engaged()) 00698 swap(this->_M_get(), __other._M_get()); 00699 else if (this->_M_is_engaged()) 00700 { 00701 __other._M_construct(std::move(this->_M_get())); 00702 this->_M_destruct(); 00703 } 00704 else if (__other._M_is_engaged()) 00705 { 00706 this->_M_construct(std::move(__other._M_get())); 00707 __other._M_destruct(); 00708 } 00709 } 00710 00711 // [X.Y.4.5] Observers. 00712 constexpr const _Tp* 00713 operator->() const 00714 { 00715 #ifndef __cpp_lib_addressof_constexpr 00716 return __constexpr_addressof(this->_M_get()); 00717 #else 00718 return std::__addressof(this->_M_get()); 00719 #endif 00720 } 00721 00722 _Tp* 00723 operator->() 00724 { return std::__addressof(this->_M_get()); } 00725 00726 constexpr const _Tp& 00727 operator*() const& 00728 { return this->_M_get(); } 00729 00730 constexpr _Tp& 00731 operator*()& 00732 { return this->_M_get(); } 00733 00734 constexpr _Tp&& 00735 operator*()&& 00736 { return std::move(this->_M_get()); } 00737 00738 constexpr const _Tp&& 00739 operator*() const&& 00740 { return std::move(this->_M_get()); } 00741 00742 constexpr explicit operator bool() const noexcept 00743 { return this->_M_is_engaged(); } 00744 00745 constexpr const _Tp& 00746 value() const& 00747 { 00748 return this->_M_is_engaged() 00749 ? this->_M_get() 00750 : (__throw_bad_optional_access("Attempt to access value of a " 00751 "disengaged optional object"), 00752 this->_M_get()); 00753 } 00754 00755 constexpr _Tp& 00756 value()& 00757 { 00758 return this->_M_is_engaged() 00759 ? this->_M_get() 00760 : (__throw_bad_optional_access("Attempt to access value of a " 00761 "disengaged optional object"), 00762 this->_M_get()); 00763 } 00764 00765 constexpr _Tp&& 00766 value()&& 00767 { 00768 return this->_M_is_engaged() 00769 ? std::move(this->_M_get()) 00770 : (__throw_bad_optional_access("Attempt to access value of a " 00771 "disengaged optional object"), 00772 std::move(this->_M_get())); 00773 } 00774 00775 constexpr const _Tp&& 00776 value() const&& 00777 { 00778 return this->_M_is_engaged() 00779 ? std::move(this->_M_get()) 00780 : (__throw_bad_optional_access("Attempt to access value of a " 00781 "disengaged optional object"), 00782 std::move(this->_M_get())); 00783 } 00784 00785 template<typename _Up> 00786 constexpr _Tp 00787 value_or(_Up&& __u) const& 00788 { 00789 static_assert(__and_<is_copy_constructible<_Tp>, 00790 is_convertible<_Up&&, _Tp>>(), 00791 "Cannot return value"); 00792 00793 return this->_M_is_engaged() 00794 ? this->_M_get() 00795 : static_cast<_Tp>(std::forward<_Up>(__u)); 00796 } 00797 00798 template<typename _Up> 00799 _Tp 00800 value_or(_Up&& __u) && 00801 { 00802 static_assert(__and_<is_move_constructible<_Tp>, 00803 is_convertible<_Up&&, _Tp>>(), 00804 "Cannot return value" ); 00805 00806 return this->_M_is_engaged() 00807 ? std::move(this->_M_get()) 00808 : static_cast<_Tp>(std::forward<_Up>(__u)); 00809 } 00810 }; 00811 00812 // [X.Y.8] Comparisons between optional values. 00813 template<typename _Tp> 00814 constexpr bool 00815 operator==(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs) 00816 { 00817 return static_cast<bool>(__lhs) == static_cast<bool>(__rhs) 00818 && (!__lhs || *__lhs == *__rhs); 00819 } 00820 00821 template<typename _Tp> 00822 constexpr bool 00823 operator!=(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs) 00824 { return !(__lhs == __rhs); } 00825 00826 template<typename _Tp> 00827 constexpr bool 00828 operator<(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs) 00829 { 00830 return static_cast<bool>(__rhs) && (!__lhs || *__lhs < *__rhs); 00831 } 00832 00833 template<typename _Tp> 00834 constexpr bool 00835 operator>(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs) 00836 { return __rhs < __lhs; } 00837 00838 template<typename _Tp> 00839 constexpr bool 00840 operator<=(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs) 00841 { return !(__rhs < __lhs); } 00842 00843 template<typename _Tp> 00844 constexpr bool 00845 operator>=(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs) 00846 { return !(__lhs < __rhs); } 00847 00848 // [X.Y.9] Comparisons with nullopt. 00849 template<typename _Tp> 00850 constexpr bool 00851 operator==(const optional<_Tp>& __lhs, nullopt_t) noexcept 00852 { return !__lhs; } 00853 00854 template<typename _Tp> 00855 constexpr bool 00856 operator==(nullopt_t, const optional<_Tp>& __rhs) noexcept 00857 { return !__rhs; } 00858 00859 template<typename _Tp> 00860 constexpr bool 00861 operator!=(const optional<_Tp>& __lhs, nullopt_t) noexcept 00862 { return static_cast<bool>(__lhs); } 00863 00864 template<typename _Tp> 00865 constexpr bool 00866 operator!=(nullopt_t, const optional<_Tp>& __rhs) noexcept 00867 { return static_cast<bool>(__rhs); } 00868 00869 template<typename _Tp> 00870 constexpr bool 00871 operator<(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept 00872 { return false; } 00873 00874 template<typename _Tp> 00875 constexpr bool 00876 operator<(nullopt_t, const optional<_Tp>& __rhs) noexcept 00877 { return static_cast<bool>(__rhs); } 00878 00879 template<typename _Tp> 00880 constexpr bool 00881 operator>(const optional<_Tp>& __lhs, nullopt_t) noexcept 00882 { return static_cast<bool>(__lhs); } 00883 00884 template<typename _Tp> 00885 constexpr bool 00886 operator>(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept 00887 { return false; } 00888 00889 template<typename _Tp> 00890 constexpr bool 00891 operator<=(const optional<_Tp>& __lhs, nullopt_t) noexcept 00892 { return !__lhs; } 00893 00894 template<typename _Tp> 00895 constexpr bool 00896 operator<=(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept 00897 { return true; } 00898 00899 template<typename _Tp> 00900 constexpr bool 00901 operator>=(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept 00902 { return true; } 00903 00904 template<typename _Tp> 00905 constexpr bool 00906 operator>=(nullopt_t, const optional<_Tp>& __rhs) noexcept 00907 { return !__rhs; } 00908 00909 // [X.Y.10] Comparisons with value type. 00910 template<typename _Tp> 00911 constexpr bool 00912 operator==(const optional<_Tp>& __lhs, const _Tp& __rhs) 00913 { return __lhs && *__lhs == __rhs; } 00914 00915 template<typename _Tp> 00916 constexpr bool 00917 operator==(const _Tp& __lhs, const optional<_Tp>& __rhs) 00918 { return __rhs && __lhs == *__rhs; } 00919 00920 template<typename _Tp> 00921 constexpr bool 00922 operator!=(const optional<_Tp>& __lhs, _Tp const& __rhs) 00923 { return !__lhs || !(*__lhs == __rhs); } 00924 00925 template<typename _Tp> 00926 constexpr bool 00927 operator!=(const _Tp& __lhs, const optional<_Tp>& __rhs) 00928 { return !__rhs || !(__lhs == *__rhs); } 00929 00930 template<typename _Tp> 00931 constexpr bool 00932 operator<(const optional<_Tp>& __lhs, const _Tp& __rhs) 00933 { return !__lhs || *__lhs < __rhs; } 00934 00935 template<typename _Tp> 00936 constexpr bool 00937 operator<(const _Tp& __lhs, const optional<_Tp>& __rhs) 00938 { return __rhs && __lhs < *__rhs; } 00939 00940 template<typename _Tp> 00941 constexpr bool 00942 operator>(const optional<_Tp>& __lhs, const _Tp& __rhs) 00943 { return __lhs && __rhs < *__lhs; } 00944 00945 template<typename _Tp> 00946 constexpr bool 00947 operator>(const _Tp& __lhs, const optional<_Tp>& __rhs) 00948 { return !__rhs || *__rhs < __lhs; } 00949 00950 template<typename _Tp> 00951 constexpr bool 00952 operator<=(const optional<_Tp>& __lhs, const _Tp& __rhs) 00953 { return !__lhs || !(__rhs < *__lhs); } 00954 00955 template<typename _Tp> 00956 constexpr bool 00957 operator<=(const _Tp& __lhs, const optional<_Tp>& __rhs) 00958 { return __rhs && !(*__rhs < __lhs); } 00959 00960 template<typename _Tp> 00961 constexpr bool 00962 operator>=(const optional<_Tp>& __lhs, const _Tp& __rhs) 00963 { return __lhs && !(*__lhs < __rhs); } 00964 00965 template<typename _Tp> 00966 constexpr bool 00967 operator>=(const _Tp& __lhs, const optional<_Tp>& __rhs) 00968 { return !__rhs || !(__lhs < *__rhs); } 00969 00970 // [X.Y.11] 00971 template<typename _Tp> 00972 inline void 00973 swap(optional<_Tp>& __lhs, optional<_Tp>& __rhs) 00974 noexcept(noexcept(__lhs.swap(__rhs))) 00975 { __lhs.swap(__rhs); } 00976 00977 template<typename _Tp> 00978 constexpr optional<decay_t<_Tp>> 00979 make_optional(_Tp&& __t) 00980 { return optional<decay_t<_Tp>> { std::forward<_Tp>(__t) }; } 00981 00982 // @} group optional 00983 _GLIBCXX_END_NAMESPACE_VERSION 00984 } // namespace fundamentals_v1 00985 } 00986 00987 // [X.Y.12] 00988 template<typename _Tp> 00989 struct hash<experimental::optional<_Tp>> 00990 { 00991 using result_type = size_t; 00992 using argument_type = experimental::optional<_Tp>; 00993 00994 size_t 00995 operator()(const experimental::optional<_Tp>& __t) const 00996 noexcept(noexcept(hash<_Tp> {}(*__t))) 00997 { 00998 // We pick an arbitrary hash for disengaged optionals which hopefully 00999 // usual values of _Tp won't typically hash to. 01000 constexpr size_t __magic_disengaged_hash = static_cast<size_t>(-3333); 01001 return __t ? hash<_Tp> {}(*__t) : __magic_disengaged_hash; 01002 } 01003 }; 01004 } 01005 01006 #endif // C++14 01007 01008 #endif // _GLIBCXX_EXPERIMENTAL_OPTIONAL