1 1.1.1.12 mrg // <experimental/optional> -*- C++ -*- 2 1.1 mrg 3 1.1.1.14 mrg // Copyright (C) 2013-2024 Free Software Foundation, Inc. 4 1.1 mrg // 5 1.1 mrg // This file is part of the GNU ISO C++ Library. This library is free 6 1.1 mrg // software; you can redistribute it and/or modify it under the 7 1.1 mrg // terms of the GNU General Public License as published by the 8 1.1 mrg // Free Software Foundation; either version 3, or (at your option) 9 1.1 mrg // any later version. 10 1.1 mrg 11 1.1 mrg // This library is distributed in the hope that it will be useful, 12 1.1 mrg // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 1.1 mrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 1.1 mrg // GNU General Public License for more details. 15 1.1 mrg 16 1.1 mrg // Under Section 7 of GPL version 3, you are granted additional 17 1.1 mrg // permissions described in the GCC Runtime Library Exception, version 18 1.1 mrg // 3.1, as published by the Free Software Foundation. 19 1.1 mrg 20 1.1 mrg // You should have received a copy of the GNU General Public License and 21 1.1 mrg // a copy of the GCC Runtime Library Exception along with this program; 22 1.1 mrg // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 1.1 mrg // <http://www.gnu.org/licenses/>. 24 1.1 mrg 25 1.1 mrg /** @file experimental/optional 26 1.1 mrg * This is a TS C++ Library header. 27 1.1.1.10 mrg * @ingroup libfund-ts 28 1.1 mrg */ 29 1.1 mrg 30 1.1 mrg #ifndef _GLIBCXX_EXPERIMENTAL_OPTIONAL 31 1.1 mrg #define _GLIBCXX_EXPERIMENTAL_OPTIONAL 1 32 1.1 mrg 33 1.1.1.14 mrg #include <bits/requires_hosted.h> // experimental is currently omitted 34 1.1.1.14 mrg 35 1.1.1.5 mrg #if __cplusplus >= 201402L 36 1.1 mrg 37 1.1 mrg #include <type_traits> 38 1.1 mrg #include <stdexcept> 39 1.1 mrg #include <new> 40 1.1 mrg #include <initializer_list> 41 1.1 mrg #include <bits/functexcept.h> 42 1.1 mrg #include <bits/functional_hash.h> 43 1.1 mrg #include <bits/enable_special_members.h> 44 1.1.1.13 mrg #include <bits/move.h> 45 1.1.1.4 mrg #include <experimental/bits/lfts_config.h> 46 1.1 mrg 47 1.1 mrg namespace std _GLIBCXX_VISIBILITY(default) 48 1.1 mrg { 49 1.1.1.8 mrg _GLIBCXX_BEGIN_NAMESPACE_VERSION 50 1.1.1.8 mrg 51 1.1 mrg namespace experimental 52 1.1 mrg { 53 1.1 mrg inline namespace fundamentals_v1 54 1.1 mrg { 55 1.1 mrg /** 56 1.1 mrg * @defgroup optional Optional values 57 1.1.1.10 mrg * @ingroup libfund-ts 58 1.1 mrg * 59 1.1 mrg * Class template for optional values and surrounding facilities, as 60 1.1 mrg * described in n3793 "A proposal to add a utility class to represent 61 1.1 mrg * optional objects (Revision 5)". 62 1.1 mrg * 63 1.1 mrg * @{ 64 1.1 mrg */ 65 1.1 mrg 66 1.1 mrg #define __cpp_lib_experimental_optional 201411 67 1.1 mrg 68 1.1 mrg // All subsequent [X.Y.n] references are against n3793. 69 1.1 mrg 70 1.1 mrg // [X.Y.4] 71 1.1 mrg template<typename _Tp> 72 1.1 mrg class optional; 73 1.1 mrg 74 1.1 mrg // [X.Y.5] 75 1.1 mrg /// Tag type for in-place construction. 76 1.1 mrg struct in_place_t { }; 77 1.1 mrg 78 1.1 mrg /// Tag for in-place construction. 79 1.1 mrg constexpr in_place_t in_place { }; 80 1.1 mrg 81 1.1 mrg // [X.Y.6] 82 1.1 mrg /// Tag type to disengage optional objects. 83 1.1 mrg struct nullopt_t 84 1.1 mrg { 85 1.1 mrg // Do not user-declare default constructor at all for 86 1.1 mrg // optional_value = {} syntax to work. 87 1.1 mrg // nullopt_t() = delete; 88 1.1 mrg 89 1.1 mrg // Used for constructing nullopt. 90 1.1 mrg enum class _Construct { _Token }; 91 1.1 mrg 92 1.1 mrg // Must be constexpr for nullopt_t to be literal. 93 1.1 mrg explicit constexpr nullopt_t(_Construct) { } 94 1.1 mrg }; 95 1.1 mrg 96 1.1 mrg // [X.Y.6] 97 1.1 mrg /// Tag to disengage optional objects. 98 1.1 mrg constexpr nullopt_t nullopt { nullopt_t::_Construct::_Token }; 99 1.1 mrg 100 1.1 mrg // [X.Y.7] 101 1.1 mrg /** 102 1.1 mrg * @brief Exception class thrown when a disengaged optional object is 103 1.1 mrg * dereferenced. 104 1.1 mrg * @ingroup exceptions 105 1.1 mrg */ 106 1.1 mrg class bad_optional_access : public logic_error 107 1.1 mrg { 108 1.1 mrg public: 109 1.1 mrg bad_optional_access() : logic_error("bad optional access") { } 110 1.1 mrg 111 1.1 mrg // XXX This constructor is non-standard. Should not be inline 112 1.1 mrg explicit bad_optional_access(const char* __arg) : logic_error(__arg) { } 113 1.1 mrg 114 1.1 mrg virtual ~bad_optional_access() noexcept = default; 115 1.1 mrg }; 116 1.1 mrg 117 1.1.1.10 mrg /// @cond undocumented 118 1.1.1.10 mrg 119 1.1 mrg // XXX Does not belong here. 120 1.1.1.13 mrg [[noreturn]] inline void 121 1.1 mrg __throw_bad_optional_access(const char* __s) 122 1.1 mrg { _GLIBCXX_THROW_OR_ABORT(bad_optional_access(__s)); } 123 1.1 mrg 124 1.1 mrg /** 125 1.1 mrg * @brief Class template that holds the necessary state for @ref optional 126 1.1 mrg * and that has the responsibility for construction and the special members. 127 1.1 mrg * 128 1.1 mrg * Such a separate base class template is necessary in order to 129 1.1 mrg * conditionally enable the special members (e.g. copy/move constructors). 130 1.1 mrg * Note that this means that @ref _Optional_base implements the 131 1.1 mrg * functionality for copy and move assignment, but not for converting 132 1.1 mrg * assignment. 133 1.1 mrg * 134 1.1 mrg * @see optional, _Enable_special_members 135 1.1 mrg */ 136 1.1 mrg template<typename _Tp, bool _ShouldProvideDestructor = 137 1.1 mrg !is_trivially_destructible<_Tp>::value> 138 1.1 mrg class _Optional_base 139 1.1 mrg { 140 1.1 mrg private: 141 1.1 mrg // Remove const to avoid prohibition of reusing object storage for 142 1.1 mrg // const-qualified types in [3.8/9]. This is strictly internal 143 1.1 mrg // and even optional itself is oblivious to it. 144 1.1 mrg using _Stored_type = remove_const_t<_Tp>; 145 1.1 mrg 146 1.1 mrg public: 147 1.1 mrg // [X.Y.4.1] Constructors. 148 1.1 mrg 149 1.1 mrg // Constructors for disengaged optionals. 150 1.1 mrg constexpr _Optional_base() noexcept 151 1.1 mrg : _M_empty{} { } 152 1.1 mrg 153 1.1 mrg constexpr _Optional_base(nullopt_t) noexcept 154 1.1 mrg : _Optional_base{} { } 155 1.1 mrg 156 1.1 mrg // Constructors for engaged optionals. 157 1.1 mrg template<typename... _Args> 158 1.1 mrg constexpr explicit _Optional_base(in_place_t, _Args&&... __args) 159 1.1 mrg : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true) { } 160 1.1 mrg 161 1.1 mrg template<typename _Up, typename... _Args, 162 1.1 mrg enable_if_t<is_constructible<_Tp, 163 1.1 mrg initializer_list<_Up>&, 164 1.1 mrg _Args&&...>::value, 165 1.1 mrg int>...> 166 1.1 mrg constexpr explicit _Optional_base(in_place_t, 167 1.1 mrg initializer_list<_Up> __il, 168 1.1 mrg _Args&&... __args) 169 1.1 mrg : _M_payload(__il, std::forward<_Args>(__args)...), 170 1.1 mrg _M_engaged(true) { } 171 1.1 mrg 172 1.1 mrg // Copy and move constructors. 173 1.1 mrg _Optional_base(const _Optional_base& __other) 174 1.1 mrg { 175 1.1 mrg if (__other._M_engaged) 176 1.1 mrg this->_M_construct(__other._M_get()); 177 1.1 mrg } 178 1.1 mrg 179 1.1 mrg _Optional_base(_Optional_base&& __other) 180 1.1 mrg noexcept(is_nothrow_move_constructible<_Tp>()) 181 1.1 mrg { 182 1.1 mrg if (__other._M_engaged) 183 1.1 mrg this->_M_construct(std::move(__other._M_get())); 184 1.1 mrg } 185 1.1 mrg 186 1.1 mrg // [X.Y.4.3] (partly) Assignment. 187 1.1 mrg _Optional_base& 188 1.1 mrg operator=(const _Optional_base& __other) 189 1.1 mrg { 190 1.1 mrg if (this->_M_engaged && __other._M_engaged) 191 1.1 mrg this->_M_get() = __other._M_get(); 192 1.1 mrg else 193 1.1 mrg { 194 1.1 mrg if (__other._M_engaged) 195 1.1 mrg this->_M_construct(__other._M_get()); 196 1.1 mrg else 197 1.1 mrg this->_M_reset(); 198 1.1 mrg } 199 1.1 mrg 200 1.1 mrg return *this; 201 1.1 mrg } 202 1.1 mrg 203 1.1 mrg _Optional_base& 204 1.1 mrg operator=(_Optional_base&& __other) 205 1.1 mrg noexcept(__and_<is_nothrow_move_constructible<_Tp>, 206 1.1 mrg is_nothrow_move_assignable<_Tp>>()) 207 1.1 mrg { 208 1.1 mrg if (this->_M_engaged && __other._M_engaged) 209 1.1 mrg this->_M_get() = std::move(__other._M_get()); 210 1.1 mrg else 211 1.1 mrg { 212 1.1 mrg if (__other._M_engaged) 213 1.1 mrg this->_M_construct(std::move(__other._M_get())); 214 1.1 mrg else 215 1.1 mrg this->_M_reset(); 216 1.1 mrg } 217 1.1 mrg return *this; 218 1.1 mrg } 219 1.1 mrg 220 1.1 mrg // [X.Y.4.2] Destructor. 221 1.1 mrg ~_Optional_base() 222 1.1 mrg { 223 1.1 mrg if (this->_M_engaged) 224 1.1 mrg this->_M_payload.~_Stored_type(); 225 1.1 mrg } 226 1.1 mrg 227 1.1 mrg // The following functionality is also needed by optional, hence the 228 1.1 mrg // protected accessibility. 229 1.1 mrg protected: 230 1.1 mrg constexpr bool _M_is_engaged() const noexcept 231 1.1 mrg { return this->_M_engaged; } 232 1.1 mrg 233 1.1 mrg // The _M_get operations have _M_engaged as a precondition. 234 1.1 mrg constexpr _Tp& 235 1.1 mrg _M_get() noexcept 236 1.1 mrg { return _M_payload; } 237 1.1 mrg 238 1.1 mrg constexpr const _Tp& 239 1.1 mrg _M_get() const noexcept 240 1.1 mrg { return _M_payload; } 241 1.1 mrg 242 1.1 mrg // The _M_construct operation has !_M_engaged as a precondition 243 1.1 mrg // while _M_destruct has _M_engaged as a precondition. 244 1.1 mrg template<typename... _Args> 245 1.1 mrg void 246 1.1 mrg _M_construct(_Args&&... __args) 247 1.1 mrg noexcept(is_nothrow_constructible<_Stored_type, _Args...>()) 248 1.1 mrg { 249 1.1 mrg ::new (std::__addressof(this->_M_payload)) 250 1.1 mrg _Stored_type(std::forward<_Args>(__args)...); 251 1.1 mrg this->_M_engaged = true; 252 1.1 mrg } 253 1.1 mrg 254 1.1 mrg void 255 1.1 mrg _M_destruct() 256 1.1 mrg { 257 1.1 mrg this->_M_engaged = false; 258 1.1 mrg this->_M_payload.~_Stored_type(); 259 1.1 mrg } 260 1.1 mrg 261 1.1 mrg // _M_reset is a 'safe' operation with no precondition. 262 1.1 mrg void 263 1.1 mrg _M_reset() 264 1.1 mrg { 265 1.1 mrg if (this->_M_engaged) 266 1.1 mrg this->_M_destruct(); 267 1.1 mrg } 268 1.1 mrg 269 1.1 mrg private: 270 1.1 mrg struct _Empty_byte { }; 271 1.1 mrg union { 272 1.1 mrg _Empty_byte _M_empty; 273 1.1 mrg _Stored_type _M_payload; 274 1.1 mrg }; 275 1.1 mrg bool _M_engaged = false; 276 1.1 mrg }; 277 1.1 mrg 278 1.1 mrg /// Partial specialization that is exactly identical to the primary template 279 1.1 mrg /// save for not providing a destructor, to fulfill triviality requirements. 280 1.1 mrg template<typename _Tp> 281 1.1 mrg class _Optional_base<_Tp, false> 282 1.1 mrg { 283 1.1 mrg private: 284 1.1 mrg using _Stored_type = remove_const_t<_Tp>; 285 1.1 mrg 286 1.1 mrg public: 287 1.1 mrg constexpr _Optional_base() noexcept 288 1.1 mrg : _M_empty{} { } 289 1.1 mrg 290 1.1 mrg constexpr _Optional_base(nullopt_t) noexcept 291 1.1 mrg : _Optional_base{} { } 292 1.1 mrg 293 1.1 mrg template<typename... _Args> 294 1.1 mrg constexpr explicit _Optional_base(in_place_t, _Args&&... __args) 295 1.1 mrg : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true) { } 296 1.1 mrg 297 1.1 mrg template<typename _Up, typename... _Args, 298 1.1 mrg enable_if_t<is_constructible<_Tp, 299 1.1 mrg initializer_list<_Up>&, 300 1.1 mrg _Args&&...>::value, 301 1.1 mrg int>...> 302 1.1 mrg constexpr explicit _Optional_base(in_place_t, 303 1.1 mrg initializer_list<_Up> __il, 304 1.1 mrg _Args&&... __args) 305 1.1 mrg : _M_payload(__il, std::forward<_Args>(__args)...), 306 1.1 mrg _M_engaged(true) { } 307 1.1 mrg 308 1.1 mrg _Optional_base(const _Optional_base& __other) 309 1.1 mrg { 310 1.1 mrg if (__other._M_engaged) 311 1.1 mrg this->_M_construct(__other._M_get()); 312 1.1 mrg } 313 1.1 mrg 314 1.1 mrg _Optional_base(_Optional_base&& __other) 315 1.1 mrg noexcept(is_nothrow_move_constructible<_Tp>()) 316 1.1 mrg { 317 1.1 mrg if (__other._M_engaged) 318 1.1 mrg this->_M_construct(std::move(__other._M_get())); 319 1.1 mrg } 320 1.1 mrg 321 1.1 mrg _Optional_base& 322 1.1 mrg operator=(const _Optional_base& __other) 323 1.1 mrg { 324 1.1 mrg if (this->_M_engaged && __other._M_engaged) 325 1.1 mrg this->_M_get() = __other._M_get(); 326 1.1 mrg else 327 1.1 mrg { 328 1.1 mrg if (__other._M_engaged) 329 1.1 mrg this->_M_construct(__other._M_get()); 330 1.1 mrg else 331 1.1 mrg this->_M_reset(); 332 1.1 mrg } 333 1.1 mrg return *this; 334 1.1 mrg } 335 1.1 mrg 336 1.1 mrg _Optional_base& 337 1.1 mrg operator=(_Optional_base&& __other) 338 1.1 mrg noexcept(__and_<is_nothrow_move_constructible<_Tp>, 339 1.1 mrg is_nothrow_move_assignable<_Tp>>()) 340 1.1 mrg { 341 1.1 mrg if (this->_M_engaged && __other._M_engaged) 342 1.1 mrg this->_M_get() = std::move(__other._M_get()); 343 1.1 mrg else 344 1.1 mrg { 345 1.1 mrg if (__other._M_engaged) 346 1.1 mrg this->_M_construct(std::move(__other._M_get())); 347 1.1 mrg else 348 1.1 mrg this->_M_reset(); 349 1.1 mrg } 350 1.1 mrg return *this; 351 1.1 mrg } 352 1.1 mrg 353 1.1 mrg // Sole difference 354 1.1 mrg // ~_Optional_base() noexcept = default; 355 1.1 mrg 356 1.1 mrg protected: 357 1.1 mrg constexpr bool _M_is_engaged() const noexcept 358 1.1 mrg { return this->_M_engaged; } 359 1.1 mrg 360 1.1 mrg _Tp& 361 1.1 mrg _M_get() noexcept 362 1.1 mrg { return _M_payload; } 363 1.1 mrg 364 1.1 mrg constexpr const _Tp& 365 1.1 mrg _M_get() const noexcept 366 1.1 mrg { return _M_payload; } 367 1.1 mrg 368 1.1 mrg template<typename... _Args> 369 1.1 mrg void 370 1.1 mrg _M_construct(_Args&&... __args) 371 1.1 mrg noexcept(is_nothrow_constructible<_Stored_type, _Args...>()) 372 1.1 mrg { 373 1.1 mrg ::new (std::__addressof(this->_M_payload)) 374 1.1 mrg _Stored_type(std::forward<_Args>(__args)...); 375 1.1 mrg this->_M_engaged = true; 376 1.1 mrg } 377 1.1 mrg 378 1.1 mrg void 379 1.1 mrg _M_destruct() 380 1.1 mrg { 381 1.1 mrg this->_M_engaged = false; 382 1.1 mrg this->_M_payload.~_Stored_type(); 383 1.1 mrg } 384 1.1 mrg 385 1.1 mrg void 386 1.1 mrg _M_reset() 387 1.1 mrg { 388 1.1 mrg if (this->_M_engaged) 389 1.1 mrg this->_M_destruct(); 390 1.1 mrg } 391 1.1 mrg 392 1.1 mrg private: 393 1.1 mrg struct _Empty_byte { }; 394 1.1 mrg union 395 1.1 mrg { 396 1.1 mrg _Empty_byte _M_empty; 397 1.1 mrg _Stored_type _M_payload; 398 1.1 mrg }; 399 1.1 mrg bool _M_engaged = false; 400 1.1 mrg }; 401 1.1 mrg 402 1.1.1.4 mrg template<typename _Tp, typename _Up> 403 1.1.1.4 mrg using __converts_from_optional = 404 1.1.1.4 mrg __or_<is_constructible<_Tp, const optional<_Up>&>, 405 1.1.1.4 mrg is_constructible<_Tp, optional<_Up>&>, 406 1.1.1.4 mrg is_constructible<_Tp, const optional<_Up>&&>, 407 1.1.1.4 mrg is_constructible<_Tp, optional<_Up>&&>, 408 1.1.1.4 mrg is_convertible<const optional<_Up>&, _Tp>, 409 1.1.1.4 mrg is_convertible<optional<_Up>&, _Tp>, 410 1.1.1.4 mrg is_convertible<const optional<_Up>&&, _Tp>, 411 1.1.1.4 mrg is_convertible<optional<_Up>&&, _Tp>>; 412 1.1.1.4 mrg 413 1.1.1.4 mrg template<typename _Tp, typename _Up> 414 1.1.1.4 mrg using __assigns_from_optional = 415 1.1.1.4 mrg __or_<is_assignable<_Tp&, const optional<_Up>&>, 416 1.1.1.4 mrg is_assignable<_Tp&, optional<_Up>&>, 417 1.1.1.4 mrg is_assignable<_Tp&, const optional<_Up>&&>, 418 1.1.1.4 mrg is_assignable<_Tp&, optional<_Up>&&>>; 419 1.1.1.4 mrg 420 1.1.1.10 mrg /// @endcond 421 1.1.1.10 mrg 422 1.1 mrg /** 423 1.1 mrg * @brief Class template for optional values. 424 1.1 mrg */ 425 1.1 mrg template<typename _Tp> 426 1.1 mrg class optional 427 1.1 mrg : private _Optional_base<_Tp>, 428 1.1 mrg private _Enable_copy_move< 429 1.1 mrg // Copy constructor. 430 1.1 mrg is_copy_constructible<_Tp>::value, 431 1.1 mrg // Copy assignment. 432 1.1 mrg __and_<is_copy_constructible<_Tp>, is_copy_assignable<_Tp>>::value, 433 1.1 mrg // Move constructor. 434 1.1 mrg is_move_constructible<_Tp>::value, 435 1.1 mrg // Move assignment. 436 1.1 mrg __and_<is_move_constructible<_Tp>, is_move_assignable<_Tp>>::value, 437 1.1 mrg // Unique tag type. 438 1.1 mrg optional<_Tp>> 439 1.1 mrg { 440 1.1 mrg static_assert(__and_<__not_<is_same<remove_cv_t<_Tp>, nullopt_t>>, 441 1.1 mrg __not_<is_same<remove_cv_t<_Tp>, in_place_t>>, 442 1.1 mrg __not_<is_reference<_Tp>>>(), 443 1.1 mrg "Invalid instantiation of optional<T>"); 444 1.1 mrg 445 1.1 mrg private: 446 1.1 mrg using _Base = _Optional_base<_Tp>; 447 1.1 mrg 448 1.1 mrg public: 449 1.1 mrg using value_type = _Tp; 450 1.1 mrg 451 1.1 mrg // _Optional_base has the responsibility for construction. 452 1.1 mrg using _Base::_Base; 453 1.1 mrg 454 1.1.1.4 mrg constexpr optional() = default; 455 1.1.1.4 mrg // Converting constructors for engaged optionals. 456 1.1.1.4 mrg template <typename _Up = _Tp, 457 1.1.1.4 mrg enable_if_t<__and_< 458 1.1.1.4 mrg __not_<is_same<optional<_Tp>, decay_t<_Up>>>, 459 1.1.1.4 mrg is_constructible<_Tp, _Up&&>, 460 1.1.1.4 mrg is_convertible<_Up&&, _Tp> 461 1.1.1.4 mrg >::value, bool> = true> 462 1.1.1.4 mrg constexpr optional(_Up&& __t) 463 1.1.1.4 mrg : _Base(in_place, std::forward<_Up>(__t)) { } 464 1.1.1.4 mrg 465 1.1.1.4 mrg template <typename _Up = _Tp, 466 1.1.1.4 mrg enable_if_t<__and_< 467 1.1.1.4 mrg __not_<is_same<optional<_Tp>, decay_t<_Up>>>, 468 1.1.1.4 mrg is_constructible<_Tp, _Up&&>, 469 1.1.1.4 mrg __not_<is_convertible<_Up&&, _Tp>> 470 1.1.1.4 mrg >::value, bool> = false> 471 1.1.1.4 mrg explicit constexpr optional(_Up&& __t) 472 1.1.1.4 mrg : _Base(in_place, std::forward<_Up>(__t)) { } 473 1.1.1.4 mrg 474 1.1.1.4 mrg template <typename _Up, 475 1.1.1.4 mrg enable_if_t<__and_< 476 1.1.1.4 mrg __not_<is_same<_Tp, _Up>>, 477 1.1.1.4 mrg is_constructible<_Tp, const _Up&>, 478 1.1.1.4 mrg is_convertible<const _Up&, _Tp>, 479 1.1.1.4 mrg __not_<__converts_from_optional<_Tp, _Up>> 480 1.1.1.4 mrg >::value, bool> = true> 481 1.1.1.4 mrg constexpr optional(const optional<_Up>& __t) 482 1.1.1.4 mrg { 483 1.1.1.4 mrg if (__t) 484 1.1.1.4 mrg emplace(*__t); 485 1.1.1.4 mrg } 486 1.1.1.4 mrg 487 1.1.1.4 mrg template <typename _Up, 488 1.1.1.4 mrg enable_if_t<__and_< 489 1.1.1.4 mrg __not_<is_same<_Tp, _Up>>, 490 1.1.1.4 mrg is_constructible<_Tp, const _Up&>, 491 1.1.1.4 mrg __not_<is_convertible<const _Up&, _Tp>>, 492 1.1.1.4 mrg __not_<__converts_from_optional<_Tp, _Up>> 493 1.1.1.4 mrg >::value, bool> = false> 494 1.1.1.4 mrg explicit constexpr optional(const optional<_Up>& __t) 495 1.1.1.4 mrg { 496 1.1.1.4 mrg if (__t) 497 1.1.1.4 mrg emplace(*__t); 498 1.1.1.4 mrg } 499 1.1.1.4 mrg 500 1.1.1.4 mrg template <typename _Up, 501 1.1.1.4 mrg enable_if_t<__and_< 502 1.1.1.4 mrg __not_<is_same<_Tp, _Up>>, 503 1.1.1.4 mrg is_constructible<_Tp, _Up&&>, 504 1.1.1.4 mrg is_convertible<_Up&&, _Tp>, 505 1.1.1.4 mrg __not_<__converts_from_optional<_Tp, _Up>> 506 1.1.1.4 mrg >::value, bool> = true> 507 1.1.1.4 mrg constexpr optional(optional<_Up>&& __t) 508 1.1.1.4 mrg { 509 1.1.1.4 mrg if (__t) 510 1.1.1.4 mrg emplace(std::move(*__t)); 511 1.1.1.4 mrg } 512 1.1.1.4 mrg 513 1.1.1.4 mrg template <typename _Up, 514 1.1.1.4 mrg enable_if_t<__and_< 515 1.1.1.4 mrg __not_<is_same<_Tp, _Up>>, 516 1.1.1.4 mrg is_constructible<_Tp, _Up&&>, 517 1.1.1.4 mrg __not_<is_convertible<_Up&&, _Tp>>, 518 1.1.1.4 mrg __not_<__converts_from_optional<_Tp, _Up>> 519 1.1.1.4 mrg >::value, bool> = false> 520 1.1.1.4 mrg explicit constexpr optional(optional<_Up>&& __t) 521 1.1.1.4 mrg { 522 1.1.1.4 mrg if (__t) 523 1.1.1.4 mrg emplace(std::move(*__t)); 524 1.1.1.4 mrg } 525 1.1.1.4 mrg 526 1.1 mrg // [X.Y.4.3] (partly) Assignment. 527 1.1 mrg optional& 528 1.1 mrg operator=(nullopt_t) noexcept 529 1.1 mrg { 530 1.1 mrg this->_M_reset(); 531 1.1 mrg return *this; 532 1.1 mrg } 533 1.1 mrg 534 1.1.1.4 mrg template<typename _Up = _Tp> 535 1.1.1.4 mrg enable_if_t<__and_< 536 1.1.1.4 mrg __not_<is_same<optional<_Tp>, decay_t<_Up>>>, 537 1.1.1.4 mrg is_constructible<_Tp, _Up>, 538 1.1.1.4 mrg __not_<__and_<is_scalar<_Tp>, 539 1.1.1.4 mrg is_same<_Tp, decay_t<_Up>>>>, 540 1.1.1.4 mrg is_assignable<_Tp&, _Up>>::value, 541 1.1.1.4 mrg optional&> 542 1.1 mrg operator=(_Up&& __u) 543 1.1 mrg { 544 1.1 mrg if (this->_M_is_engaged()) 545 1.1 mrg this->_M_get() = std::forward<_Up>(__u); 546 1.1 mrg else 547 1.1 mrg this->_M_construct(std::forward<_Up>(__u)); 548 1.1 mrg 549 1.1 mrg return *this; 550 1.1 mrg } 551 1.1 mrg 552 1.1.1.4 mrg template<typename _Up> 553 1.1.1.4 mrg enable_if_t<__and_< 554 1.1.1.4 mrg __not_<is_same<_Tp, _Up>>, 555 1.1.1.4 mrg is_constructible<_Tp, const _Up&>, 556 1.1.1.4 mrg is_assignable<_Tp&, _Up>, 557 1.1.1.4 mrg __not_<__converts_from_optional<_Tp, _Up>>, 558 1.1.1.4 mrg __not_<__assigns_from_optional<_Tp, _Up>> 559 1.1.1.4 mrg >::value, 560 1.1.1.4 mrg optional&> 561 1.1.1.4 mrg operator=(const optional<_Up>& __u) 562 1.1.1.4 mrg { 563 1.1.1.4 mrg if (__u) 564 1.1.1.4 mrg { 565 1.1.1.4 mrg if (this->_M_is_engaged()) 566 1.1.1.4 mrg this->_M_get() = *__u; 567 1.1.1.4 mrg else 568 1.1.1.4 mrg this->_M_construct(*__u); 569 1.1.1.4 mrg } 570 1.1.1.4 mrg else 571 1.1.1.4 mrg { 572 1.1.1.4 mrg this->_M_reset(); 573 1.1.1.4 mrg } 574 1.1.1.4 mrg return *this; 575 1.1.1.4 mrg } 576 1.1.1.4 mrg 577 1.1.1.4 mrg template<typename _Up> 578 1.1.1.4 mrg enable_if_t<__and_< 579 1.1.1.4 mrg __not_<is_same<_Tp, _Up>>, 580 1.1.1.4 mrg is_constructible<_Tp, _Up>, 581 1.1.1.4 mrg is_assignable<_Tp&, _Up>, 582 1.1.1.4 mrg __not_<__converts_from_optional<_Tp, _Up>>, 583 1.1.1.4 mrg __not_<__assigns_from_optional<_Tp, _Up>> 584 1.1.1.4 mrg >::value, 585 1.1.1.4 mrg optional&> 586 1.1.1.4 mrg operator=(optional<_Up>&& __u) 587 1.1.1.4 mrg { 588 1.1.1.4 mrg if (__u) 589 1.1.1.4 mrg { 590 1.1.1.4 mrg if (this->_M_is_engaged()) 591 1.1.1.4 mrg this->_M_get() = std::move(*__u); 592 1.1.1.4 mrg else 593 1.1.1.4 mrg this->_M_construct(std::move(*__u)); 594 1.1.1.4 mrg } 595 1.1.1.4 mrg else 596 1.1.1.4 mrg { 597 1.1.1.4 mrg this->_M_reset(); 598 1.1.1.4 mrg } 599 1.1.1.4 mrg 600 1.1.1.4 mrg return *this; 601 1.1.1.4 mrg } 602 1.1.1.4 mrg 603 1.1 mrg template<typename... _Args> 604 1.1.1.4 mrg enable_if_t<is_constructible<_Tp, _Args&&...>::value> 605 1.1 mrg emplace(_Args&&... __args) 606 1.1 mrg { 607 1.1 mrg this->_M_reset(); 608 1.1 mrg this->_M_construct(std::forward<_Args>(__args)...); 609 1.1 mrg } 610 1.1 mrg 611 1.1 mrg template<typename _Up, typename... _Args> 612 1.1.1.4 mrg enable_if_t<is_constructible<_Tp, initializer_list<_Up>&, 613 1.1 mrg _Args&&...>::value> 614 1.1 mrg emplace(initializer_list<_Up> __il, _Args&&... __args) 615 1.1 mrg { 616 1.1 mrg this->_M_reset(); 617 1.1 mrg this->_M_construct(__il, std::forward<_Args>(__args)...); 618 1.1 mrg } 619 1.1 mrg 620 1.1 mrg // [X.Y.4.2] Destructor is implicit, implemented in _Optional_base. 621 1.1 mrg 622 1.1 mrg // [X.Y.4.4] Swap. 623 1.1 mrg void 624 1.1 mrg swap(optional& __other) 625 1.1 mrg noexcept(is_nothrow_move_constructible<_Tp>() 626 1.1.1.8 mrg && __is_nothrow_swappable<_Tp>::value) 627 1.1 mrg { 628 1.1 mrg using std::swap; 629 1.1 mrg 630 1.1 mrg if (this->_M_is_engaged() && __other._M_is_engaged()) 631 1.1 mrg swap(this->_M_get(), __other._M_get()); 632 1.1 mrg else if (this->_M_is_engaged()) 633 1.1 mrg { 634 1.1 mrg __other._M_construct(std::move(this->_M_get())); 635 1.1 mrg this->_M_destruct(); 636 1.1 mrg } 637 1.1 mrg else if (__other._M_is_engaged()) 638 1.1 mrg { 639 1.1 mrg this->_M_construct(std::move(__other._M_get())); 640 1.1 mrg __other._M_destruct(); 641 1.1 mrg } 642 1.1 mrg } 643 1.1 mrg 644 1.1 mrg // [X.Y.4.5] Observers. 645 1.1 mrg constexpr const _Tp* 646 1.1 mrg operator->() const 647 1.1.1.10 mrg { return std::__addressof(this->_M_get()); } 648 1.1 mrg 649 1.1 mrg _Tp* 650 1.1 mrg operator->() 651 1.1 mrg { return std::__addressof(this->_M_get()); } 652 1.1 mrg 653 1.1 mrg constexpr const _Tp& 654 1.1 mrg operator*() const& 655 1.1 mrg { return this->_M_get(); } 656 1.1 mrg 657 1.1 mrg constexpr _Tp& 658 1.1 mrg operator*()& 659 1.1 mrg { return this->_M_get(); } 660 1.1 mrg 661 1.1 mrg constexpr _Tp&& 662 1.1 mrg operator*()&& 663 1.1 mrg { return std::move(this->_M_get()); } 664 1.1 mrg 665 1.1 mrg constexpr const _Tp&& 666 1.1 mrg operator*() const&& 667 1.1 mrg { return std::move(this->_M_get()); } 668 1.1 mrg 669 1.1 mrg constexpr explicit operator bool() const noexcept 670 1.1 mrg { return this->_M_is_engaged(); } 671 1.1 mrg 672 1.1 mrg constexpr const _Tp& 673 1.1 mrg value() const& 674 1.1 mrg { 675 1.1.1.13 mrg if (this->_M_is_engaged()) 676 1.1.1.13 mrg return this->_M_get(); 677 1.1.1.13 mrg __throw_bad_optional_access("Attempt to access value of a " 678 1.1.1.13 mrg "disengaged optional object"); 679 1.1 mrg } 680 1.1 mrg 681 1.1 mrg constexpr _Tp& 682 1.1 mrg value()& 683 1.1 mrg { 684 1.1.1.13 mrg if (this->_M_is_engaged()) 685 1.1.1.13 mrg return this->_M_get(); 686 1.1.1.13 mrg __throw_bad_optional_access("Attempt to access value of a " 687 1.1.1.13 mrg "disengaged optional object"); 688 1.1 mrg } 689 1.1 mrg 690 1.1 mrg constexpr _Tp&& 691 1.1 mrg value()&& 692 1.1 mrg { 693 1.1.1.13 mrg if (this->_M_is_engaged()) 694 1.1.1.13 mrg return std::move(this->_M_get()); 695 1.1.1.13 mrg __throw_bad_optional_access("Attempt to access value of a " 696 1.1.1.13 mrg "disengaged optional object"); 697 1.1 mrg } 698 1.1 mrg 699 1.1 mrg constexpr const _Tp&& 700 1.1 mrg value() const&& 701 1.1 mrg { 702 1.1.1.13 mrg if (this->_M_is_engaged()) 703 1.1.1.13 mrg return std::move(this->_M_get()); 704 1.1.1.13 mrg __throw_bad_optional_access("Attempt to access value of a " 705 1.1.1.13 mrg "disengaged optional object"); 706 1.1 mrg } 707 1.1 mrg 708 1.1 mrg template<typename _Up> 709 1.1 mrg constexpr _Tp 710 1.1 mrg value_or(_Up&& __u) const& 711 1.1 mrg { 712 1.1 mrg static_assert(__and_<is_copy_constructible<_Tp>, 713 1.1 mrg is_convertible<_Up&&, _Tp>>(), 714 1.1 mrg "Cannot return value"); 715 1.1 mrg 716 1.1.1.13 mrg if (this->_M_is_engaged()) 717 1.1.1.13 mrg return this->_M_get(); 718 1.1.1.13 mrg else 719 1.1.1.13 mrg return static_cast<_Tp>(std::forward<_Up>(__u)); 720 1.1 mrg } 721 1.1 mrg 722 1.1 mrg template<typename _Up> 723 1.1 mrg _Tp 724 1.1 mrg value_or(_Up&& __u) && 725 1.1 mrg { 726 1.1 mrg static_assert(__and_<is_move_constructible<_Tp>, 727 1.1 mrg is_convertible<_Up&&, _Tp>>(), 728 1.1 mrg "Cannot return value" ); 729 1.1 mrg 730 1.1.1.13 mrg if (this->_M_is_engaged()) 731 1.1.1.13 mrg return std::move(this->_M_get()); 732 1.1.1.13 mrg else 733 1.1.1.13 mrg return static_cast<_Tp>(std::forward<_Up>(__u)); 734 1.1 mrg } 735 1.1 mrg }; 736 1.1 mrg 737 1.1.1.10 mrg /// @relates experimental::optional @{ 738 1.1.1.10 mrg 739 1.1 mrg // [X.Y.8] Comparisons between optional values. 740 1.1 mrg template<typename _Tp> 741 1.1 mrg constexpr bool 742 1.1 mrg operator==(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs) 743 1.1 mrg { 744 1.1 mrg return static_cast<bool>(__lhs) == static_cast<bool>(__rhs) 745 1.1 mrg && (!__lhs || *__lhs == *__rhs); 746 1.1 mrg } 747 1.1 mrg 748 1.1 mrg template<typename _Tp> 749 1.1 mrg constexpr bool 750 1.1 mrg operator!=(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs) 751 1.1 mrg { return !(__lhs == __rhs); } 752 1.1 mrg 753 1.1 mrg template<typename _Tp> 754 1.1 mrg constexpr bool 755 1.1 mrg operator<(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs) 756 1.1 mrg { 757 1.1 mrg return static_cast<bool>(__rhs) && (!__lhs || *__lhs < *__rhs); 758 1.1 mrg } 759 1.1 mrg 760 1.1 mrg template<typename _Tp> 761 1.1 mrg constexpr bool 762 1.1 mrg operator>(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs) 763 1.1 mrg { return __rhs < __lhs; } 764 1.1 mrg 765 1.1 mrg template<typename _Tp> 766 1.1 mrg constexpr bool 767 1.1 mrg operator<=(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs) 768 1.1 mrg { return !(__rhs < __lhs); } 769 1.1 mrg 770 1.1 mrg template<typename _Tp> 771 1.1 mrg constexpr bool 772 1.1 mrg operator>=(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs) 773 1.1 mrg { return !(__lhs < __rhs); } 774 1.1 mrg 775 1.1 mrg // [X.Y.9] Comparisons with nullopt. 776 1.1 mrg template<typename _Tp> 777 1.1 mrg constexpr bool 778 1.1 mrg operator==(const optional<_Tp>& __lhs, nullopt_t) noexcept 779 1.1 mrg { return !__lhs; } 780 1.1 mrg 781 1.1 mrg template<typename _Tp> 782 1.1 mrg constexpr bool 783 1.1 mrg operator==(nullopt_t, const optional<_Tp>& __rhs) noexcept 784 1.1 mrg { return !__rhs; } 785 1.1 mrg 786 1.1 mrg template<typename _Tp> 787 1.1 mrg constexpr bool 788 1.1 mrg operator!=(const optional<_Tp>& __lhs, nullopt_t) noexcept 789 1.1 mrg { return static_cast<bool>(__lhs); } 790 1.1 mrg 791 1.1 mrg template<typename _Tp> 792 1.1 mrg constexpr bool 793 1.1 mrg operator!=(nullopt_t, const optional<_Tp>& __rhs) noexcept 794 1.1 mrg { return static_cast<bool>(__rhs); } 795 1.1 mrg 796 1.1 mrg template<typename _Tp> 797 1.1 mrg constexpr bool 798 1.1 mrg operator<(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept 799 1.1 mrg { return false; } 800 1.1 mrg 801 1.1 mrg template<typename _Tp> 802 1.1 mrg constexpr bool 803 1.1 mrg operator<(nullopt_t, const optional<_Tp>& __rhs) noexcept 804 1.1 mrg { return static_cast<bool>(__rhs); } 805 1.1 mrg 806 1.1 mrg template<typename _Tp> 807 1.1 mrg constexpr bool 808 1.1 mrg operator>(const optional<_Tp>& __lhs, nullopt_t) noexcept 809 1.1 mrg { return static_cast<bool>(__lhs); } 810 1.1 mrg 811 1.1 mrg template<typename _Tp> 812 1.1 mrg constexpr bool 813 1.1 mrg operator>(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept 814 1.1 mrg { return false; } 815 1.1 mrg 816 1.1 mrg template<typename _Tp> 817 1.1 mrg constexpr bool 818 1.1 mrg operator<=(const optional<_Tp>& __lhs, nullopt_t) noexcept 819 1.1 mrg { return !__lhs; } 820 1.1 mrg 821 1.1 mrg template<typename _Tp> 822 1.1 mrg constexpr bool 823 1.1 mrg operator<=(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept 824 1.1 mrg { return true; } 825 1.1 mrg 826 1.1 mrg template<typename _Tp> 827 1.1 mrg constexpr bool 828 1.1 mrg operator>=(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept 829 1.1 mrg { return true; } 830 1.1 mrg 831 1.1 mrg template<typename _Tp> 832 1.1 mrg constexpr bool 833 1.1 mrg operator>=(nullopt_t, const optional<_Tp>& __rhs) noexcept 834 1.1 mrg { return !__rhs; } 835 1.1 mrg 836 1.1 mrg // [X.Y.10] Comparisons with value type. 837 1.1 mrg template<typename _Tp> 838 1.1 mrg constexpr bool 839 1.1 mrg operator==(const optional<_Tp>& __lhs, const _Tp& __rhs) 840 1.1 mrg { return __lhs && *__lhs == __rhs; } 841 1.1 mrg 842 1.1 mrg template<typename _Tp> 843 1.1 mrg constexpr bool 844 1.1 mrg operator==(const _Tp& __lhs, const optional<_Tp>& __rhs) 845 1.1 mrg { return __rhs && __lhs == *__rhs; } 846 1.1 mrg 847 1.1 mrg template<typename _Tp> 848 1.1 mrg constexpr bool 849 1.1 mrg operator!=(const optional<_Tp>& __lhs, _Tp const& __rhs) 850 1.1 mrg { return !__lhs || !(*__lhs == __rhs); } 851 1.1 mrg 852 1.1 mrg template<typename _Tp> 853 1.1 mrg constexpr bool 854 1.1 mrg operator!=(const _Tp& __lhs, const optional<_Tp>& __rhs) 855 1.1 mrg { return !__rhs || !(__lhs == *__rhs); } 856 1.1 mrg 857 1.1 mrg template<typename _Tp> 858 1.1 mrg constexpr bool 859 1.1 mrg operator<(const optional<_Tp>& __lhs, const _Tp& __rhs) 860 1.1 mrg { return !__lhs || *__lhs < __rhs; } 861 1.1 mrg 862 1.1 mrg template<typename _Tp> 863 1.1 mrg constexpr bool 864 1.1 mrg operator<(const _Tp& __lhs, const optional<_Tp>& __rhs) 865 1.1 mrg { return __rhs && __lhs < *__rhs; } 866 1.1 mrg 867 1.1 mrg template<typename _Tp> 868 1.1 mrg constexpr bool 869 1.1 mrg operator>(const optional<_Tp>& __lhs, const _Tp& __rhs) 870 1.1 mrg { return __lhs && __rhs < *__lhs; } 871 1.1 mrg 872 1.1 mrg template<typename _Tp> 873 1.1 mrg constexpr bool 874 1.1 mrg operator>(const _Tp& __lhs, const optional<_Tp>& __rhs) 875 1.1 mrg { return !__rhs || *__rhs < __lhs; } 876 1.1 mrg 877 1.1 mrg template<typename _Tp> 878 1.1 mrg constexpr bool 879 1.1 mrg operator<=(const optional<_Tp>& __lhs, const _Tp& __rhs) 880 1.1 mrg { return !__lhs || !(__rhs < *__lhs); } 881 1.1 mrg 882 1.1 mrg template<typename _Tp> 883 1.1 mrg constexpr bool 884 1.1 mrg operator<=(const _Tp& __lhs, const optional<_Tp>& __rhs) 885 1.1 mrg { return __rhs && !(*__rhs < __lhs); } 886 1.1 mrg 887 1.1 mrg template<typename _Tp> 888 1.1 mrg constexpr bool 889 1.1 mrg operator>=(const optional<_Tp>& __lhs, const _Tp& __rhs) 890 1.1 mrg { return __lhs && !(*__lhs < __rhs); } 891 1.1 mrg 892 1.1 mrg template<typename _Tp> 893 1.1 mrg constexpr bool 894 1.1 mrg operator>=(const _Tp& __lhs, const optional<_Tp>& __rhs) 895 1.1 mrg { return !__rhs || !(__lhs < *__rhs); } 896 1.1 mrg 897 1.1 mrg // [X.Y.11] 898 1.1 mrg template<typename _Tp> 899 1.1 mrg inline void 900 1.1 mrg swap(optional<_Tp>& __lhs, optional<_Tp>& __rhs) 901 1.1 mrg noexcept(noexcept(__lhs.swap(__rhs))) 902 1.1 mrg { __lhs.swap(__rhs); } 903 1.1 mrg 904 1.1 mrg template<typename _Tp> 905 1.1 mrg constexpr optional<decay_t<_Tp>> 906 1.1 mrg make_optional(_Tp&& __t) 907 1.1 mrg { return optional<decay_t<_Tp>> { std::forward<_Tp>(__t) }; } 908 1.1 mrg 909 1.1.1.11 mrg /// @} relates experimental::optional 910 1.1.1.11 mrg /// @} group optional 911 1.1 mrg } // namespace fundamentals_v1 912 1.1.1.8 mrg } // namespace experimental 913 1.1 mrg 914 1.1 mrg // [X.Y.12] 915 1.1.1.10 mrg /// std::hash partial specialization for experimental::optional 916 1.1.1.10 mrg /// @relates experimental::optional 917 1.1 mrg template<typename _Tp> 918 1.1 mrg struct hash<experimental::optional<_Tp>> 919 1.1 mrg { 920 1.1 mrg using result_type = size_t; 921 1.1 mrg using argument_type = experimental::optional<_Tp>; 922 1.1 mrg 923 1.1 mrg size_t 924 1.1 mrg operator()(const experimental::optional<_Tp>& __t) const 925 1.1 mrg noexcept(noexcept(hash<_Tp> {}(*__t))) 926 1.1 mrg { 927 1.1 mrg // We pick an arbitrary hash for disengaged optionals which hopefully 928 1.1 mrg // usual values of _Tp won't typically hash to. 929 1.1 mrg constexpr size_t __magic_disengaged_hash = static_cast<size_t>(-3333); 930 1.1 mrg return __t ? hash<_Tp> {}(*__t) : __magic_disengaged_hash; 931 1.1 mrg } 932 1.1 mrg }; 933 1.1.1.8 mrg 934 1.1.1.8 mrg _GLIBCXX_END_NAMESPACE_VERSION 935 1.1.1.8 mrg } // namespace std 936 1.1 mrg 937 1.1 mrg #endif // C++14 938 1.1 mrg 939 1.1 mrg #endif // _GLIBCXX_EXPERIMENTAL_OPTIONAL 940