1 1.1 mrg // <optional> -*- C++ -*- 2 1.1 mrg 3 1.1.1.5 mrg // Copyright (C) 2013-2022 Free Software Foundation, Inc. 4 1.1.1.5 mrg // Copyright The GNU Toolchain Authors. 5 1.1 mrg // 6 1.1 mrg // This file is part of the GNU ISO C++ Library. This library is free 7 1.1 mrg // software; you can redistribute it and/or modify it under the 8 1.1 mrg // terms of the GNU General Public License as published by the 9 1.1 mrg // Free Software Foundation; either version 3, or (at your option) 10 1.1 mrg // any later version. 11 1.1 mrg 12 1.1 mrg // This library is distributed in the hope that it will be useful, 13 1.1 mrg // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 1.1 mrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 1.1 mrg // GNU General Public License for more details. 16 1.1 mrg 17 1.1 mrg // Under Section 7 of GPL version 3, you are granted additional 18 1.1 mrg // permissions described in the GCC Runtime Library Exception, version 19 1.1 mrg // 3.1, as published by the Free Software Foundation. 20 1.1 mrg 21 1.1 mrg // You should have received a copy of the GNU General Public License and 22 1.1 mrg // a copy of the GCC Runtime Library Exception along with this program; 23 1.1 mrg // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 24 1.1 mrg // <http://www.gnu.org/licenses/>. 25 1.1 mrg 26 1.1 mrg /** @file include/optional 27 1.1 mrg * This is a Standard C++ Library header. 28 1.1 mrg */ 29 1.1 mrg 30 1.1 mrg #ifndef _GLIBCXX_OPTIONAL 31 1.1 mrg #define _GLIBCXX_OPTIONAL 1 32 1.1 mrg 33 1.1 mrg #pragma GCC system_header 34 1.1 mrg 35 1.1 mrg #if __cplusplus >= 201703L 36 1.1 mrg 37 1.1 mrg #include <type_traits> 38 1.1.1.4 mrg #include <exception> 39 1.1 mrg #include <new> 40 1.1 mrg #include <initializer_list> 41 1.1.1.5 mrg #include <bits/enable_special_members.h> 42 1.1.1.4 mrg #include <bits/exception_defines.h> 43 1.1 mrg #include <bits/functional_hash.h> 44 1.1.1.5 mrg #include <bits/stl_construct.h> // _Construct 45 1.1.1.5 mrg #include <bits/utility.h> // in_place_t 46 1.1.1.4 mrg #if __cplusplus > 201703L 47 1.1.1.4 mrg # include <compare> 48 1.1.1.5 mrg # include <bits/invoke.h> // std::__invoke 49 1.1.1.5 mrg #endif 50 1.1.1.5 mrg #if __cplusplus > 202002L 51 1.1.1.5 mrg # include <concepts> 52 1.1.1.4 mrg #endif 53 1.1 mrg 54 1.1 mrg namespace std _GLIBCXX_VISIBILITY(default) 55 1.1 mrg { 56 1.1 mrg _GLIBCXX_BEGIN_NAMESPACE_VERSION 57 1.1 mrg 58 1.1 mrg /** 59 1.1 mrg * @addtogroup utilities 60 1.1 mrg * @{ 61 1.1 mrg */ 62 1.1 mrg 63 1.1.1.5 mrg #if __cplusplus > 202002L && __cpp_lib_concepts 64 1.1.1.5 mrg # define __cpp_lib_optional 202110L 65 1.1.1.5 mrg #elif __cplusplus >= 202002L 66 1.1.1.5 mrg # define __cpp_lib_optional 202106L 67 1.1.1.5 mrg #else 68 1.1.1.5 mrg # define __cpp_lib_optional 201606L 69 1.1.1.5 mrg #endif 70 1.1 mrg 71 1.1 mrg template<typename _Tp> 72 1.1 mrg class optional; 73 1.1 mrg 74 1.1 mrg /// Tag type to disengage optional objects. 75 1.1 mrg struct nullopt_t 76 1.1 mrg { 77 1.1 mrg // Do not user-declare default constructor at all for 78 1.1 mrg // optional_value = {} syntax to work. 79 1.1 mrg // nullopt_t() = delete; 80 1.1 mrg 81 1.1 mrg // Used for constructing nullopt. 82 1.1 mrg enum class _Construct { _Token }; 83 1.1 mrg 84 1.1 mrg // Must be constexpr for nullopt_t to be literal. 85 1.1.1.5 mrg explicit constexpr nullopt_t(_Construct) noexcept { } 86 1.1 mrg }; 87 1.1 mrg 88 1.1 mrg /// Tag to disengage optional objects. 89 1.1 mrg inline constexpr nullopt_t nullopt { nullopt_t::_Construct::_Token }; 90 1.1 mrg 91 1.1.1.5 mrg template<typename _Fn> struct _Optional_func { _Fn& _M_f; }; 92 1.1.1.5 mrg 93 1.1 mrg /** 94 1.1 mrg * @brief Exception class thrown when a disengaged optional object is 95 1.1 mrg * dereferenced. 96 1.1 mrg * @ingroup exceptions 97 1.1 mrg */ 98 1.1 mrg class bad_optional_access : public exception 99 1.1 mrg { 100 1.1 mrg public: 101 1.1.1.4 mrg bad_optional_access() = default; 102 1.1.1.4 mrg virtual ~bad_optional_access() = default; 103 1.1.1.2 mrg 104 1.1.1.4 mrg const char* what() const noexcept override 105 1.1.1.2 mrg { return "bad optional access"; } 106 1.1 mrg }; 107 1.1 mrg 108 1.1 mrg // XXX Does not belong here. 109 1.1.1.5 mrg [[__noreturn__]] inline void 110 1.1 mrg __throw_bad_optional_access() 111 1.1 mrg { _GLIBCXX_THROW_OR_ABORT(bad_optional_access()); } 112 1.1 mrg 113 1.1.1.3 mrg // This class template manages construction/destruction of 114 1.1.1.3 mrg // the contained value for a std::optional. 115 1.1.1.3 mrg template <typename _Tp> 116 1.1.1.3 mrg struct _Optional_payload_base 117 1.1 mrg { 118 1.1.1.3 mrg using _Stored_type = remove_const_t<_Tp>; 119 1.1.1.3 mrg 120 1.1.1.3 mrg _Optional_payload_base() = default; 121 1.1.1.3 mrg ~_Optional_payload_base() = default; 122 1.1 mrg 123 1.1.1.3 mrg template<typename... _Args> 124 1.1.1.2 mrg constexpr 125 1.1.1.3 mrg _Optional_payload_base(in_place_t __tag, _Args&&... __args) 126 1.1.1.3 mrg : _M_payload(__tag, std::forward<_Args>(__args)...), 127 1.1.1.3 mrg _M_engaged(true) 128 1.1.1.3 mrg { } 129 1.1 mrg 130 1.1 mrg template<typename _Up, typename... _Args> 131 1.1.1.2 mrg constexpr 132 1.1.1.3 mrg _Optional_payload_base(std::initializer_list<_Up> __il, 133 1.1.1.3 mrg _Args&&... __args) 134 1.1 mrg : _M_payload(__il, std::forward<_Args>(__args)...), 135 1.1.1.2 mrg _M_engaged(true) 136 1.1.1.2 mrg { } 137 1.1 mrg 138 1.1.1.3 mrg // Constructor used by _Optional_base copy constructor when the 139 1.1.1.3 mrg // contained value is not trivially copy constructible. 140 1.1.1.2 mrg constexpr 141 1.1.1.3 mrg _Optional_payload_base(bool __engaged, 142 1.1.1.3 mrg const _Optional_payload_base& __other) 143 1.1.1.2 mrg { 144 1.1.1.2 mrg if (__other._M_engaged) 145 1.1.1.3 mrg this->_M_construct(__other._M_get()); 146 1.1.1.2 mrg } 147 1.1 mrg 148 1.1.1.3 mrg // Constructor used by _Optional_base move constructor when the 149 1.1.1.3 mrg // contained value is not trivially move constructible. 150 1.1.1.2 mrg constexpr 151 1.1.1.3 mrg _Optional_payload_base(bool __engaged, 152 1.1.1.3 mrg _Optional_payload_base&& __other) 153 1.1.1.2 mrg { 154 1.1.1.2 mrg if (__other._M_engaged) 155 1.1.1.3 mrg this->_M_construct(std::move(__other._M_get())); 156 1.1.1.2 mrg } 157 1.1 mrg 158 1.1.1.3 mrg // Copy constructor is only used to when the contained value is 159 1.1.1.3 mrg // trivially copy constructible. 160 1.1.1.3 mrg _Optional_payload_base(const _Optional_payload_base&) = default; 161 1.1.1.3 mrg 162 1.1.1.3 mrg // Move constructor is only used to when the contained value is 163 1.1.1.3 mrg // trivially copy constructible. 164 1.1.1.3 mrg _Optional_payload_base(_Optional_payload_base&&) = default; 165 1.1.1.3 mrg 166 1.1.1.3 mrg _Optional_payload_base& 167 1.1.1.3 mrg operator=(const _Optional_payload_base&) = default; 168 1.1.1.3 mrg 169 1.1.1.3 mrg _Optional_payload_base& 170 1.1.1.3 mrg operator=(_Optional_payload_base&&) = default; 171 1.1.1.3 mrg 172 1.1.1.3 mrg // used to perform non-trivial copy assignment. 173 1.1.1.3 mrg constexpr void 174 1.1.1.3 mrg _M_copy_assign(const _Optional_payload_base& __other) 175 1.1.1.2 mrg { 176 1.1.1.5 mrg if (this->_M_engaged && __other._M_engaged) 177 1.1.1.5 mrg this->_M_get() = __other._M_get(); 178 1.1.1.5 mrg else 179 1.1.1.2 mrg { 180 1.1.1.2 mrg if (__other._M_engaged) 181 1.1.1.2 mrg this->_M_construct(__other._M_get()); 182 1.1.1.2 mrg else 183 1.1.1.2 mrg this->_M_reset(); 184 1.1.1.2 mrg } 185 1.1.1.2 mrg } 186 1.1.1.2 mrg 187 1.1.1.3 mrg // used to perform non-trivial move assignment. 188 1.1.1.3 mrg constexpr void 189 1.1.1.3 mrg _M_move_assign(_Optional_payload_base&& __other) 190 1.1.1.3 mrg noexcept(__and_v<is_nothrow_move_constructible<_Tp>, 191 1.1.1.3 mrg is_nothrow_move_assignable<_Tp>>) 192 1.1.1.2 mrg { 193 1.1.1.2 mrg if (this->_M_engaged && __other._M_engaged) 194 1.1.1.2 mrg this->_M_get() = std::move(__other._M_get()); 195 1.1.1.2 mrg else 196 1.1.1.2 mrg { 197 1.1.1.2 mrg if (__other._M_engaged) 198 1.1.1.2 mrg this->_M_construct(std::move(__other._M_get())); 199 1.1.1.2 mrg else 200 1.1.1.2 mrg this->_M_reset(); 201 1.1.1.2 mrg } 202 1.1.1.2 mrg } 203 1.1 mrg 204 1.1 mrg struct _Empty_byte { }; 205 1.1.1.2 mrg 206 1.1.1.3 mrg template<typename _Up, bool = is_trivially_destructible_v<_Up>> 207 1.1.1.3 mrg union _Storage 208 1.1.1.3 mrg { 209 1.1.1.3 mrg constexpr _Storage() noexcept : _M_empty() { } 210 1.1.1.2 mrg 211 1.1.1.3 mrg template<typename... _Args> 212 1.1.1.3 mrg constexpr 213 1.1.1.3 mrg _Storage(in_place_t, _Args&&... __args) 214 1.1.1.3 mrg : _M_value(std::forward<_Args>(__args)...) 215 1.1.1.3 mrg { } 216 1.1.1.3 mrg 217 1.1.1.3 mrg template<typename _Vp, typename... _Args> 218 1.1.1.3 mrg constexpr 219 1.1.1.3 mrg _Storage(std::initializer_list<_Vp> __il, _Args&&... __args) 220 1.1.1.3 mrg : _M_value(__il, std::forward<_Args>(__args)...) 221 1.1.1.3 mrg { } 222 1.1.1.3 mrg 223 1.1.1.5 mrg #if __cplusplus >= 202002L 224 1.1.1.5 mrg template<typename _Fn, typename _Arg> 225 1.1.1.5 mrg constexpr 226 1.1.1.5 mrg _Storage(_Optional_func<_Fn> __f, _Arg&& __arg) 227 1.1.1.5 mrg : _M_value(std::__invoke(std::forward<_Fn>(__f._M_f), 228 1.1.1.5 mrg std::forward<_Arg>(__arg))) 229 1.1.1.5 mrg { } 230 1.1.1.5 mrg #endif 231 1.1.1.5 mrg 232 1.1.1.3 mrg _Empty_byte _M_empty; 233 1.1.1.5 mrg _Up _M_value; 234 1.1.1.3 mrg }; 235 1.1.1.3 mrg 236 1.1.1.3 mrg template<typename _Up> 237 1.1.1.3 mrg union _Storage<_Up, false> 238 1.1.1.3 mrg { 239 1.1.1.3 mrg constexpr _Storage() noexcept : _M_empty() { } 240 1.1.1.3 mrg 241 1.1.1.3 mrg template<typename... _Args> 242 1.1.1.3 mrg constexpr 243 1.1.1.3 mrg _Storage(in_place_t, _Args&&... __args) 244 1.1.1.3 mrg : _M_value(std::forward<_Args>(__args)...) 245 1.1.1.3 mrg { } 246 1.1.1.3 mrg 247 1.1.1.3 mrg template<typename _Vp, typename... _Args> 248 1.1.1.3 mrg constexpr 249 1.1.1.3 mrg _Storage(std::initializer_list<_Vp> __il, _Args&&... __args) 250 1.1.1.3 mrg : _M_value(__il, std::forward<_Args>(__args)...) 251 1.1.1.3 mrg { } 252 1.1.1.3 mrg 253 1.1.1.5 mrg #if __cplusplus >= 202002L 254 1.1.1.5 mrg template<typename _Fn, typename _Arg> 255 1.1.1.5 mrg constexpr 256 1.1.1.5 mrg _Storage(_Optional_func<_Fn> __f, _Arg&& __arg) 257 1.1.1.5 mrg : _M_value(std::__invoke(std::forward<_Fn>(__f._M_f), 258 1.1.1.5 mrg std::forward<_Arg>(__arg))) 259 1.1.1.5 mrg { } 260 1.1.1.5 mrg #endif 261 1.1.1.5 mrg 262 1.1.1.3 mrg // User-provided destructor is needed when _Up has non-trivial dtor. 263 1.1.1.5 mrg _GLIBCXX20_CONSTEXPR ~_Storage() { } 264 1.1.1.3 mrg 265 1.1.1.3 mrg _Empty_byte _M_empty; 266 1.1.1.5 mrg _Up _M_value; 267 1.1.1.3 mrg }; 268 1.1.1.3 mrg 269 1.1.1.3 mrg _Storage<_Stored_type> _M_payload; 270 1.1.1.3 mrg 271 1.1.1.3 mrg bool _M_engaged = false; 272 1.1.1.2 mrg 273 1.1.1.2 mrg template<typename... _Args> 274 1.1.1.5 mrg constexpr void 275 1.1.1.5 mrg _M_construct(_Args&&... __args) 276 1.1.1.5 mrg noexcept(is_nothrow_constructible_v<_Stored_type, _Args...>) 277 1.1.1.5 mrg { 278 1.1.1.5 mrg std::_Construct(std::__addressof(this->_M_payload._M_value), 279 1.1.1.5 mrg std::forward<_Args>(__args)...); 280 1.1.1.5 mrg this->_M_engaged = true; 281 1.1.1.5 mrg } 282 1.1.1.2 mrg 283 1.1.1.3 mrg constexpr void 284 1.1.1.3 mrg _M_destroy() noexcept 285 1.1.1.3 mrg { 286 1.1.1.3 mrg _M_engaged = false; 287 1.1.1.3 mrg _M_payload._M_value.~_Stored_type(); 288 1.1.1.3 mrg } 289 1.1.1.3 mrg 290 1.1.1.5 mrg #if __cplusplus >= 202002L 291 1.1.1.5 mrg template<typename _Fn, typename _Up> 292 1.1.1.5 mrg constexpr void 293 1.1.1.5 mrg _M_apply(_Optional_func<_Fn> __f, _Up&& __x) 294 1.1.1.5 mrg { 295 1.1.1.5 mrg std::construct_at(std::__addressof(this->_M_payload), 296 1.1.1.5 mrg __f, std::forward<_Up>(__x)); 297 1.1.1.5 mrg _M_engaged = true; 298 1.1.1.5 mrg } 299 1.1.1.5 mrg #endif 300 1.1.1.5 mrg 301 1.1.1.3 mrg // The _M_get() operations have _M_engaged as a precondition. 302 1.1.1.3 mrg // They exist to access the contained value with the appropriate 303 1.1.1.3 mrg // const-qualification, because _M_payload has had the const removed. 304 1.1.1.3 mrg 305 1.1.1.2 mrg constexpr _Tp& 306 1.1.1.2 mrg _M_get() noexcept 307 1.1.1.3 mrg { return this->_M_payload._M_value; } 308 1.1.1.2 mrg 309 1.1.1.2 mrg constexpr const _Tp& 310 1.1.1.2 mrg _M_get() const noexcept 311 1.1.1.3 mrg { return this->_M_payload._M_value; } 312 1.1.1.2 mrg 313 1.1.1.2 mrg // _M_reset is a 'safe' operation with no precondition. 314 1.1.1.3 mrg constexpr void 315 1.1.1.2 mrg _M_reset() noexcept 316 1.1.1.2 mrg { 317 1.1.1.2 mrg if (this->_M_engaged) 318 1.1.1.3 mrg _M_destroy(); 319 1.1.1.2 mrg } 320 1.1 mrg }; 321 1.1 mrg 322 1.1.1.3 mrg // Class template that manages the payload for optionals. 323 1.1.1.3 mrg template <typename _Tp, 324 1.1.1.3 mrg bool /*_HasTrivialDestructor*/ = 325 1.1.1.3 mrg is_trivially_destructible_v<_Tp>, 326 1.1.1.3 mrg bool /*_HasTrivialCopy */ = 327 1.1.1.3 mrg is_trivially_copy_assignable_v<_Tp> 328 1.1.1.3 mrg && is_trivially_copy_constructible_v<_Tp>, 329 1.1.1.3 mrg bool /*_HasTrivialMove */ = 330 1.1.1.3 mrg is_trivially_move_assignable_v<_Tp> 331 1.1.1.3 mrg && is_trivially_move_constructible_v<_Tp>> 332 1.1.1.3 mrg struct _Optional_payload; 333 1.1.1.3 mrg 334 1.1.1.3 mrg // Payload for potentially-constexpr optionals (trivial copy/move/destroy). 335 1.1 mrg template <typename _Tp> 336 1.1.1.2 mrg struct _Optional_payload<_Tp, true, true, true> 337 1.1.1.3 mrg : _Optional_payload_base<_Tp> 338 1.1 mrg { 339 1.1.1.3 mrg using _Optional_payload_base<_Tp>::_Optional_payload_base; 340 1.1.1.2 mrg 341 1.1.1.3 mrg _Optional_payload() = default; 342 1.1.1.2 mrg }; 343 1.1.1.2 mrg 344 1.1.1.3 mrg // Payload for optionals with non-trivial copy construction/assignment. 345 1.1.1.2 mrg template <typename _Tp> 346 1.1.1.2 mrg struct _Optional_payload<_Tp, true, false, true> 347 1.1.1.3 mrg : _Optional_payload_base<_Tp> 348 1.1.1.2 mrg { 349 1.1.1.3 mrg using _Optional_payload_base<_Tp>::_Optional_payload_base; 350 1.1 mrg 351 1.1.1.3 mrg _Optional_payload() = default; 352 1.1.1.3 mrg ~_Optional_payload() = default; 353 1.1.1.2 mrg _Optional_payload(const _Optional_payload&) = default; 354 1.1.1.2 mrg _Optional_payload(_Optional_payload&&) = default; 355 1.1.1.3 mrg _Optional_payload& operator=(_Optional_payload&&) = default; 356 1.1.1.2 mrg 357 1.1.1.3 mrg // Non-trivial copy assignment. 358 1.1.1.2 mrg constexpr 359 1.1.1.2 mrg _Optional_payload& 360 1.1.1.2 mrg operator=(const _Optional_payload& __other) 361 1.1.1.2 mrg { 362 1.1.1.3 mrg this->_M_copy_assign(__other); 363 1.1.1.2 mrg return *this; 364 1.1.1.2 mrg } 365 1.1.1.2 mrg }; 366 1.1.1.2 mrg 367 1.1.1.3 mrg // Payload for optionals with non-trivial move construction/assignment. 368 1.1.1.2 mrg template <typename _Tp> 369 1.1.1.2 mrg struct _Optional_payload<_Tp, true, true, false> 370 1.1.1.3 mrg : _Optional_payload_base<_Tp> 371 1.1.1.2 mrg { 372 1.1.1.3 mrg using _Optional_payload_base<_Tp>::_Optional_payload_base; 373 1.1 mrg 374 1.1.1.3 mrg _Optional_payload() = default; 375 1.1.1.3 mrg ~_Optional_payload() = default; 376 1.1.1.2 mrg _Optional_payload(const _Optional_payload&) = default; 377 1.1.1.2 mrg _Optional_payload(_Optional_payload&&) = default; 378 1.1.1.3 mrg _Optional_payload& operator=(const _Optional_payload&) = default; 379 1.1.1.2 mrg 380 1.1.1.3 mrg // Non-trivial move assignment. 381 1.1.1.2 mrg constexpr 382 1.1.1.2 mrg _Optional_payload& 383 1.1.1.2 mrg operator=(_Optional_payload&& __other) 384 1.1.1.3 mrg noexcept(__and_v<is_nothrow_move_constructible<_Tp>, 385 1.1.1.3 mrg is_nothrow_move_assignable<_Tp>>) 386 1.1.1.2 mrg { 387 1.1.1.3 mrg this->_M_move_assign(std::move(__other)); 388 1.1.1.2 mrg return *this; 389 1.1.1.2 mrg } 390 1.1 mrg }; 391 1.1 mrg 392 1.1.1.2 mrg // Payload for optionals with non-trivial copy and move assignment. 393 1.1 mrg template <typename _Tp> 394 1.1.1.2 mrg struct _Optional_payload<_Tp, true, false, false> 395 1.1.1.3 mrg : _Optional_payload_base<_Tp> 396 1.1 mrg { 397 1.1.1.3 mrg using _Optional_payload_base<_Tp>::_Optional_payload_base; 398 1.1.1.2 mrg 399 1.1.1.3 mrg _Optional_payload() = default; 400 1.1.1.3 mrg ~_Optional_payload() = default; 401 1.1.1.2 mrg _Optional_payload(const _Optional_payload&) = default; 402 1.1.1.2 mrg _Optional_payload(_Optional_payload&&) = default; 403 1.1 mrg 404 1.1.1.3 mrg // Non-trivial copy assignment. 405 1.1.1.2 mrg constexpr 406 1.1.1.2 mrg _Optional_payload& 407 1.1.1.2 mrg operator=(const _Optional_payload& __other) 408 1.1 mrg { 409 1.1.1.3 mrg this->_M_copy_assign(__other); 410 1.1.1.2 mrg return *this; 411 1.1 mrg } 412 1.1 mrg 413 1.1.1.3 mrg // Non-trivial move assignment. 414 1.1.1.2 mrg constexpr 415 1.1.1.2 mrg _Optional_payload& 416 1.1.1.2 mrg operator=(_Optional_payload&& __other) 417 1.1.1.3 mrg noexcept(__and_v<is_nothrow_move_constructible<_Tp>, 418 1.1.1.3 mrg is_nothrow_move_assignable<_Tp>>) 419 1.1 mrg { 420 1.1.1.3 mrg this->_M_move_assign(std::move(__other)); 421 1.1.1.2 mrg return *this; 422 1.1 mrg } 423 1.1.1.3 mrg }; 424 1.1 mrg 425 1.1.1.3 mrg // Payload for optionals with non-trivial destructors. 426 1.1.1.3 mrg template <typename _Tp, bool _Copy, bool _Move> 427 1.1.1.3 mrg struct _Optional_payload<_Tp, false, _Copy, _Move> 428 1.1.1.3 mrg : _Optional_payload<_Tp, true, false, false> 429 1.1.1.3 mrg { 430 1.1.1.3 mrg // Base class implements all the constructors and assignment operators: 431 1.1.1.3 mrg using _Optional_payload<_Tp, true, false, false>::_Optional_payload; 432 1.1.1.3 mrg _Optional_payload() = default; 433 1.1.1.3 mrg _Optional_payload(const _Optional_payload&) = default; 434 1.1.1.3 mrg _Optional_payload(_Optional_payload&&) = default; 435 1.1.1.3 mrg _Optional_payload& operator=(const _Optional_payload&) = default; 436 1.1.1.3 mrg _Optional_payload& operator=(_Optional_payload&&) = default; 437 1.1.1.2 mrg 438 1.1.1.3 mrg // Destructor needs to destroy the contained value: 439 1.1.1.5 mrg _GLIBCXX20_CONSTEXPR ~_Optional_payload() { this->_M_reset(); } 440 1.1 mrg }; 441 1.1 mrg 442 1.1.1.3 mrg // Common base class for _Optional_base<T> to avoid repeating these 443 1.1.1.3 mrg // member functions in each specialization. 444 1.1.1.2 mrg template<typename _Tp, typename _Dp> 445 1.1.1.2 mrg class _Optional_base_impl 446 1.1.1.2 mrg { 447 1.1.1.2 mrg protected: 448 1.1.1.2 mrg using _Stored_type = remove_const_t<_Tp>; 449 1.1.1.3 mrg 450 1.1.1.2 mrg // The _M_construct operation has !_M_engaged as a precondition 451 1.1.1.2 mrg // while _M_destruct has _M_engaged as a precondition. 452 1.1.1.2 mrg template<typename... _Args> 453 1.1.1.5 mrg constexpr void 454 1.1.1.2 mrg _M_construct(_Args&&... __args) 455 1.1.1.3 mrg noexcept(is_nothrow_constructible_v<_Stored_type, _Args...>) 456 1.1.1.2 mrg { 457 1.1.1.5 mrg static_cast<_Dp*>(this)->_M_payload._M_construct( 458 1.1.1.5 mrg std::forward<_Args>(__args)...); 459 1.1.1.2 mrg } 460 1.1.1.3 mrg 461 1.1.1.5 mrg constexpr void 462 1.1.1.2 mrg _M_destruct() noexcept 463 1.1.1.3 mrg { static_cast<_Dp*>(this)->_M_payload._M_destroy(); } 464 1.1.1.3 mrg 465 1.1.1.2 mrg // _M_reset is a 'safe' operation with no precondition. 466 1.1.1.3 mrg constexpr void 467 1.1.1.2 mrg _M_reset() noexcept 468 1.1.1.3 mrg { static_cast<_Dp*>(this)->_M_payload._M_reset(); } 469 1.1.1.3 mrg 470 1.1.1.3 mrg constexpr bool _M_is_engaged() const noexcept 471 1.1.1.3 mrg { return static_cast<const _Dp*>(this)->_M_payload._M_engaged; } 472 1.1.1.3 mrg 473 1.1.1.3 mrg // The _M_get operations have _M_engaged as a precondition. 474 1.1.1.3 mrg constexpr _Tp& 475 1.1.1.3 mrg _M_get() noexcept 476 1.1.1.2 mrg { 477 1.1.1.3 mrg __glibcxx_assert(this->_M_is_engaged()); 478 1.1.1.3 mrg return static_cast<_Dp*>(this)->_M_payload._M_get(); 479 1.1.1.2 mrg } 480 1.1.1.3 mrg 481 1.1.1.3 mrg constexpr const _Tp& 482 1.1.1.3 mrg _M_get() const noexcept 483 1.1.1.3 mrg { 484 1.1.1.3 mrg __glibcxx_assert(this->_M_is_engaged()); 485 1.1.1.3 mrg return static_cast<const _Dp*>(this)->_M_payload._M_get(); 486 1.1.1.3 mrg } 487 1.1.1.3 mrg }; 488 1.1.1.2 mrg 489 1.1 mrg /** 490 1.1.1.3 mrg * @brief Class template that provides copy/move constructors of optional. 491 1.1 mrg * 492 1.1 mrg * Such a separate base class template is necessary in order to 493 1.1.1.2 mrg * conditionally make copy/move constructors trivial. 494 1.1.1.3 mrg * 495 1.1.1.4 mrg * When the contained value is trivially copy/move constructible, 496 1.1.1.3 mrg * the copy/move constructors of _Optional_base will invoke the 497 1.1.1.3 mrg * trivial copy/move constructor of _Optional_payload. Otherwise, 498 1.1.1.3 mrg * they will invoke _Optional_payload(bool, const _Optional_payload&) 499 1.1.1.3 mrg * or _Optional_payload(bool, _Optional_payload&&) to initialize 500 1.1.1.3 mrg * the contained value, if copying/moving an engaged optional. 501 1.1.1.3 mrg * 502 1.1.1.3 mrg * Whether the other special members are trivial is determined by the 503 1.1.1.3 mrg * _Optional_payload<_Tp> specialization used for the _M_payload member. 504 1.1.1.3 mrg * 505 1.1 mrg * @see optional, _Enable_special_members 506 1.1 mrg */ 507 1.1.1.2 mrg template<typename _Tp, 508 1.1.1.2 mrg bool = is_trivially_copy_constructible_v<_Tp>, 509 1.1.1.2 mrg bool = is_trivially_move_constructible_v<_Tp>> 510 1.1.1.3 mrg struct _Optional_base 511 1.1.1.5 mrg : _Optional_base_impl<_Tp, _Optional_base<_Tp>> 512 1.1 mrg { 513 1.1 mrg // Constructors for disengaged optionals. 514 1.1.1.2 mrg constexpr _Optional_base() = default; 515 1.1 mrg 516 1.1 mrg // Constructors for engaged optionals. 517 1.1 mrg template<typename... _Args, 518 1.1.1.5 mrg enable_if_t<is_constructible_v<_Tp, _Args...>, bool> = false> 519 1.1.1.5 mrg constexpr explicit 520 1.1.1.5 mrg _Optional_base(in_place_t, _Args&&... __args) 521 1.1.1.5 mrg : _M_payload(in_place, std::forward<_Args>(__args)...) 522 1.1.1.5 mrg { } 523 1.1 mrg 524 1.1 mrg template<typename _Up, typename... _Args, 525 1.1.1.5 mrg enable_if_t<is_constructible_v<_Tp, 526 1.1 mrg initializer_list<_Up>&, 527 1.1.1.5 mrg _Args...>, bool> = false> 528 1.1.1.5 mrg constexpr explicit 529 1.1.1.5 mrg _Optional_base(in_place_t, 530 1.1.1.5 mrg initializer_list<_Up> __il, 531 1.1.1.5 mrg _Args&&... __args) 532 1.1.1.5 mrg : _M_payload(in_place, __il, std::forward<_Args>(__args)...) 533 1.1.1.5 mrg { } 534 1.1 mrg 535 1.1 mrg // Copy and move constructors. 536 1.1.1.5 mrg constexpr 537 1.1.1.5 mrg _Optional_base(const _Optional_base& __other) 538 1.1.1.5 mrg : _M_payload(__other._M_payload._M_engaged, __other._M_payload) 539 1.1 mrg { } 540 1.1 mrg 541 1.1.1.5 mrg constexpr 542 1.1.1.5 mrg _Optional_base(_Optional_base&& __other) 543 1.1.1.3 mrg noexcept(is_nothrow_move_constructible_v<_Tp>) 544 1.1.1.5 mrg : _M_payload(__other._M_payload._M_engaged, 545 1.1.1.5 mrg std::move(__other._M_payload)) 546 1.1 mrg { } 547 1.1 mrg 548 1.1 mrg // Assignment operators. 549 1.1.1.2 mrg _Optional_base& operator=(const _Optional_base&) = default; 550 1.1.1.2 mrg _Optional_base& operator=(_Optional_base&&) = default; 551 1.1.1.2 mrg 552 1.1.1.2 mrg _Optional_payload<_Tp> _M_payload; 553 1.1.1.2 mrg }; 554 1.1.1.2 mrg 555 1.1.1.2 mrg template<typename _Tp> 556 1.1.1.3 mrg struct _Optional_base<_Tp, false, true> 557 1.1.1.5 mrg : _Optional_base_impl<_Tp, _Optional_base<_Tp>> 558 1.1.1.2 mrg { 559 1.1.1.2 mrg // Constructors for disengaged optionals. 560 1.1.1.2 mrg constexpr _Optional_base() = default; 561 1.1.1.2 mrg 562 1.1.1.2 mrg // Constructors for engaged optionals. 563 1.1.1.2 mrg template<typename... _Args, 564 1.1.1.5 mrg enable_if_t<is_constructible_v<_Tp, _Args...>, bool> = false> 565 1.1.1.5 mrg constexpr explicit 566 1.1.1.5 mrg _Optional_base(in_place_t, _Args&&... __args) 567 1.1.1.5 mrg : _M_payload(in_place, std::forward<_Args>(__args)...) 568 1.1.1.5 mrg { } 569 1.1.1.2 mrg 570 1.1.1.2 mrg template<typename _Up, typename... _Args, 571 1.1.1.5 mrg enable_if_t<is_constructible_v<_Tp, 572 1.1.1.2 mrg initializer_list<_Up>&, 573 1.1.1.5 mrg _Args...>, bool> = false> 574 1.1.1.5 mrg constexpr explicit 575 1.1.1.5 mrg _Optional_base(in_place_t, 576 1.1.1.5 mrg initializer_list<_Up> __il, 577 1.1.1.5 mrg _Args... __args) 578 1.1.1.5 mrg : _M_payload(in_place, __il, std::forward<_Args>(__args)...) 579 1.1.1.5 mrg { } 580 1.1.1.2 mrg 581 1.1.1.2 mrg // Copy and move constructors. 582 1.1.1.2 mrg constexpr _Optional_base(const _Optional_base& __other) 583 1.1.1.5 mrg : _M_payload(__other._M_payload._M_engaged, __other._M_payload) 584 1.1.1.2 mrg { } 585 1.1.1.2 mrg 586 1.1.1.2 mrg constexpr _Optional_base(_Optional_base&& __other) = default; 587 1.1.1.2 mrg 588 1.1.1.2 mrg // Assignment operators. 589 1.1.1.2 mrg _Optional_base& operator=(const _Optional_base&) = default; 590 1.1.1.2 mrg _Optional_base& operator=(_Optional_base&&) = default; 591 1.1.1.2 mrg 592 1.1.1.2 mrg _Optional_payload<_Tp> _M_payload; 593 1.1.1.2 mrg }; 594 1.1.1.2 mrg 595 1.1.1.2 mrg template<typename _Tp> 596 1.1.1.3 mrg struct _Optional_base<_Tp, true, false> 597 1.1.1.5 mrg : _Optional_base_impl<_Tp, _Optional_base<_Tp>> 598 1.1.1.2 mrg { 599 1.1.1.2 mrg // Constructors for disengaged optionals. 600 1.1.1.2 mrg constexpr _Optional_base() = default; 601 1.1.1.2 mrg 602 1.1.1.2 mrg // Constructors for engaged optionals. 603 1.1.1.2 mrg template<typename... _Args, 604 1.1.1.5 mrg enable_if_t<is_constructible_v<_Tp, _Args...>, bool> = false> 605 1.1.1.5 mrg constexpr explicit 606 1.1.1.5 mrg _Optional_base(in_place_t, _Args&&... __args) 607 1.1.1.5 mrg : _M_payload(in_place, std::forward<_Args>(__args)...) 608 1.1.1.5 mrg { } 609 1.1.1.2 mrg 610 1.1.1.2 mrg template<typename _Up, typename... _Args, 611 1.1.1.5 mrg enable_if_t<is_constructible_v<_Tp, 612 1.1.1.2 mrg initializer_list<_Up>&, 613 1.1.1.5 mrg _Args...>, bool> = false> 614 1.1.1.5 mrg constexpr explicit 615 1.1.1.5 mrg _Optional_base(in_place_t, 616 1.1.1.5 mrg initializer_list<_Up> __il, 617 1.1.1.5 mrg _Args&&... __args) 618 1.1.1.5 mrg : _M_payload(in_place, __il, std::forward<_Args>(__args)...) 619 1.1.1.5 mrg { } 620 1.1.1.2 mrg 621 1.1.1.2 mrg // Copy and move constructors. 622 1.1.1.2 mrg constexpr _Optional_base(const _Optional_base& __other) = default; 623 1.1.1.2 mrg 624 1.1.1.5 mrg constexpr 625 1.1.1.5 mrg _Optional_base(_Optional_base&& __other) 626 1.1.1.3 mrg noexcept(is_nothrow_move_constructible_v<_Tp>) 627 1.1.1.5 mrg : _M_payload(__other._M_payload._M_engaged, 628 1.1.1.5 mrg std::move(__other._M_payload)) 629 1.1.1.2 mrg { } 630 1.1.1.2 mrg 631 1.1.1.2 mrg // Assignment operators. 632 1.1.1.2 mrg _Optional_base& operator=(const _Optional_base&) = default; 633 1.1.1.2 mrg _Optional_base& operator=(_Optional_base&&) = default; 634 1.1.1.2 mrg 635 1.1.1.2 mrg _Optional_payload<_Tp> _M_payload; 636 1.1.1.2 mrg }; 637 1.1 mrg 638 1.1.1.2 mrg template<typename _Tp> 639 1.1.1.3 mrg struct _Optional_base<_Tp, true, true> 640 1.1.1.5 mrg : _Optional_base_impl<_Tp, _Optional_base<_Tp>> 641 1.1.1.2 mrg { 642 1.1.1.2 mrg // Constructors for disengaged optionals. 643 1.1.1.2 mrg constexpr _Optional_base() = default; 644 1.1.1.2 mrg 645 1.1.1.2 mrg // Constructors for engaged optionals. 646 1.1.1.2 mrg template<typename... _Args, 647 1.1.1.5 mrg enable_if_t<is_constructible_v<_Tp, _Args...>, bool> = false> 648 1.1.1.5 mrg constexpr explicit 649 1.1.1.5 mrg _Optional_base(in_place_t, _Args&&... __args) 650 1.1.1.5 mrg : _M_payload(in_place, std::forward<_Args>(__args)...) 651 1.1.1.5 mrg { } 652 1.1.1.2 mrg 653 1.1.1.2 mrg template<typename _Up, typename... _Args, 654 1.1.1.5 mrg enable_if_t<is_constructible_v<_Tp, 655 1.1.1.2 mrg initializer_list<_Up>&, 656 1.1.1.5 mrg _Args...>, bool> = false> 657 1.1.1.5 mrg constexpr explicit 658 1.1.1.5 mrg _Optional_base(in_place_t, 659 1.1.1.5 mrg initializer_list<_Up> __il, 660 1.1.1.5 mrg _Args&&... __args) 661 1.1.1.5 mrg : _M_payload(in_place, __il, std::forward<_Args>(__args)...) 662 1.1.1.5 mrg { } 663 1.1.1.2 mrg 664 1.1.1.2 mrg // Copy and move constructors. 665 1.1.1.2 mrg constexpr _Optional_base(const _Optional_base& __other) = default; 666 1.1.1.2 mrg constexpr _Optional_base(_Optional_base&& __other) = default; 667 1.1.1.2 mrg 668 1.1.1.2 mrg // Assignment operators. 669 1.1.1.2 mrg _Optional_base& operator=(const _Optional_base&) = default; 670 1.1.1.2 mrg _Optional_base& operator=(_Optional_base&&) = default; 671 1.1.1.2 mrg 672 1.1 mrg _Optional_payload<_Tp> _M_payload; 673 1.1 mrg }; 674 1.1 mrg 675 1.1 mrg template<typename _Tp> 676 1.1 mrg class optional; 677 1.1 mrg 678 1.1.1.5 mrg template<typename _Tp> 679 1.1.1.5 mrg inline constexpr bool __is_optional_v = false; 680 1.1.1.5 mrg template<typename _Tp> 681 1.1.1.5 mrg inline constexpr bool __is_optional_v<optional<_Tp>> = true; 682 1.1.1.5 mrg 683 1.1 mrg template<typename _Tp, typename _Up> 684 1.1 mrg using __converts_from_optional = 685 1.1 mrg __or_<is_constructible<_Tp, const optional<_Up>&>, 686 1.1 mrg is_constructible<_Tp, optional<_Up>&>, 687 1.1 mrg is_constructible<_Tp, const optional<_Up>&&>, 688 1.1 mrg is_constructible<_Tp, optional<_Up>&&>, 689 1.1 mrg is_convertible<const optional<_Up>&, _Tp>, 690 1.1 mrg is_convertible<optional<_Up>&, _Tp>, 691 1.1 mrg is_convertible<const optional<_Up>&&, _Tp>, 692 1.1 mrg is_convertible<optional<_Up>&&, _Tp>>; 693 1.1 mrg 694 1.1 mrg template<typename _Tp, typename _Up> 695 1.1 mrg using __assigns_from_optional = 696 1.1 mrg __or_<is_assignable<_Tp&, const optional<_Up>&>, 697 1.1 mrg is_assignable<_Tp&, optional<_Up>&>, 698 1.1 mrg is_assignable<_Tp&, const optional<_Up>&&>, 699 1.1 mrg is_assignable<_Tp&, optional<_Up>&&>>; 700 1.1 mrg 701 1.1 mrg /** 702 1.1 mrg * @brief Class template for optional values. 703 1.1 mrg */ 704 1.1 mrg template<typename _Tp> 705 1.1 mrg class optional 706 1.1 mrg : private _Optional_base<_Tp>, 707 1.1 mrg private _Enable_copy_move< 708 1.1.1.3 mrg // Copy constructor. 709 1.1.1.3 mrg is_copy_constructible_v<_Tp>, 710 1.1.1.3 mrg // Copy assignment. 711 1.1.1.3 mrg __and_v<is_copy_constructible<_Tp>, is_copy_assignable<_Tp>>, 712 1.1.1.3 mrg // Move constructor. 713 1.1.1.3 mrg is_move_constructible_v<_Tp>, 714 1.1.1.3 mrg // Move assignment. 715 1.1.1.3 mrg __and_v<is_move_constructible<_Tp>, is_move_assignable<_Tp>>, 716 1.1.1.3 mrg // Unique tag type. 717 1.1.1.3 mrg optional<_Tp>> 718 1.1 mrg { 719 1.1.1.2 mrg static_assert(!is_same_v<remove_cv_t<_Tp>, nullopt_t>); 720 1.1.1.2 mrg static_assert(!is_same_v<remove_cv_t<_Tp>, in_place_t>); 721 1.1.1.2 mrg static_assert(!is_reference_v<_Tp>); 722 1.1 mrg 723 1.1 mrg private: 724 1.1 mrg using _Base = _Optional_base<_Tp>; 725 1.1 mrg 726 1.1.1.3 mrg // SFINAE helpers 727 1.1.1.3 mrg template<typename _Up> 728 1.1.1.3 mrg using __not_self = __not_<is_same<optional, __remove_cvref_t<_Up>>>; 729 1.1.1.3 mrg template<typename _Up> 730 1.1.1.3 mrg using __not_tag = __not_<is_same<in_place_t, __remove_cvref_t<_Up>>>; 731 1.1.1.3 mrg template<typename... _Cond> 732 1.1.1.3 mrg using _Requires = enable_if_t<__and_v<_Cond...>, bool>; 733 1.1.1.3 mrg 734 1.1 mrg public: 735 1.1 mrg using value_type = _Tp; 736 1.1 mrg 737 1.1.1.5 mrg constexpr optional() noexcept { } 738 1.1 mrg 739 1.1.1.2 mrg constexpr optional(nullopt_t) noexcept { } 740 1.1 mrg 741 1.1 mrg // Converting constructors for engaged optionals. 742 1.1.1.3 mrg template<typename _Up = _Tp, 743 1.1.1.3 mrg _Requires<__not_self<_Up>, __not_tag<_Up>, 744 1.1.1.5 mrg is_constructible<_Tp, _Up>, 745 1.1.1.5 mrg is_convertible<_Up, _Tp>> = true> 746 1.1.1.3 mrg constexpr 747 1.1.1.3 mrg optional(_Up&& __t) 748 1.1.1.5 mrg noexcept(is_nothrow_constructible_v<_Tp, _Up>) 749 1.1.1.3 mrg : _Base(std::in_place, std::forward<_Up>(__t)) { } 750 1.1 mrg 751 1.1.1.3 mrg template<typename _Up = _Tp, 752 1.1.1.3 mrg _Requires<__not_self<_Up>, __not_tag<_Up>, 753 1.1.1.5 mrg is_constructible<_Tp, _Up>, 754 1.1.1.5 mrg __not_<is_convertible<_Up, _Tp>>> = false> 755 1.1.1.3 mrg explicit constexpr 756 1.1.1.3 mrg optional(_Up&& __t) 757 1.1.1.5 mrg noexcept(is_nothrow_constructible_v<_Tp, _Up>) 758 1.1.1.5 mrg : _Base(std::in_place, std::forward<_Up>(__t)) { } 759 1.1 mrg 760 1.1.1.3 mrg template<typename _Up, 761 1.1.1.3 mrg _Requires<__not_<is_same<_Tp, _Up>>, 762 1.1.1.3 mrg is_constructible<_Tp, const _Up&>, 763 1.1.1.3 mrg is_convertible<const _Up&, _Tp>, 764 1.1.1.3 mrg __not_<__converts_from_optional<_Tp, _Up>>> = true> 765 1.1.1.3 mrg constexpr 766 1.1.1.3 mrg optional(const optional<_Up>& __t) 767 1.1.1.5 mrg noexcept(is_nothrow_constructible_v<_Tp, const _Up&>) 768 1.1.1.3 mrg { 769 1.1.1.3 mrg if (__t) 770 1.1.1.3 mrg emplace(*__t); 771 1.1.1.3 mrg } 772 1.1 mrg 773 1.1.1.3 mrg template<typename _Up, 774 1.1.1.3 mrg _Requires<__not_<is_same<_Tp, _Up>>, 775 1.1.1.3 mrg is_constructible<_Tp, const _Up&>, 776 1.1.1.3 mrg __not_<is_convertible<const _Up&, _Tp>>, 777 1.1.1.3 mrg __not_<__converts_from_optional<_Tp, _Up>>> = false> 778 1.1.1.3 mrg explicit constexpr 779 1.1.1.3 mrg optional(const optional<_Up>& __t) 780 1.1.1.5 mrg noexcept(is_nothrow_constructible_v<_Tp, const _Up&>) 781 1.1.1.3 mrg { 782 1.1.1.3 mrg if (__t) 783 1.1.1.3 mrg emplace(*__t); 784 1.1.1.3 mrg } 785 1.1 mrg 786 1.1.1.5 mrg template<typename _Up, 787 1.1.1.5 mrg _Requires<__not_<is_same<_Tp, _Up>>, 788 1.1.1.5 mrg is_constructible<_Tp, _Up>, 789 1.1.1.5 mrg is_convertible<_Up, _Tp>, 790 1.1.1.5 mrg __not_<__converts_from_optional<_Tp, _Up>>> = true> 791 1.1.1.3 mrg constexpr 792 1.1.1.3 mrg optional(optional<_Up>&& __t) 793 1.1.1.5 mrg noexcept(is_nothrow_constructible_v<_Tp, _Up>) 794 1.1.1.3 mrg { 795 1.1.1.3 mrg if (__t) 796 1.1.1.3 mrg emplace(std::move(*__t)); 797 1.1.1.3 mrg } 798 1.1 mrg 799 1.1.1.5 mrg template<typename _Up, 800 1.1.1.5 mrg _Requires<__not_<is_same<_Tp, _Up>>, 801 1.1.1.5 mrg is_constructible<_Tp, _Up>, 802 1.1.1.5 mrg __not_<is_convertible<_Up, _Tp>>, 803 1.1.1.5 mrg __not_<__converts_from_optional<_Tp, _Up>>> = false> 804 1.1.1.3 mrg explicit constexpr 805 1.1.1.3 mrg optional(optional<_Up>&& __t) 806 1.1.1.5 mrg noexcept(is_nothrow_constructible_v<_Tp, _Up>) 807 1.1.1.3 mrg { 808 1.1.1.3 mrg if (__t) 809 1.1.1.3 mrg emplace(std::move(*__t)); 810 1.1.1.3 mrg } 811 1.1 mrg 812 1.1 mrg template<typename... _Args, 813 1.1.1.5 mrg _Requires<is_constructible<_Tp, _Args...>> = false> 814 1.1.1.3 mrg explicit constexpr 815 1.1.1.3 mrg optional(in_place_t, _Args&&... __args) 816 1.1.1.5 mrg noexcept(is_nothrow_constructible_v<_Tp, _Args...>) 817 1.1.1.3 mrg : _Base(std::in_place, std::forward<_Args>(__args)...) { } 818 1.1 mrg 819 1.1 mrg template<typename _Up, typename... _Args, 820 1.1.1.3 mrg _Requires<is_constructible<_Tp, 821 1.1.1.3 mrg initializer_list<_Up>&, 822 1.1.1.5 mrg _Args...>> = false> 823 1.1.1.3 mrg explicit constexpr 824 1.1.1.3 mrg optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args) 825 1.1.1.5 mrg noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, 826 1.1.1.5 mrg _Args...>) 827 1.1.1.3 mrg : _Base(std::in_place, __il, std::forward<_Args>(__args)...) { } 828 1.1 mrg 829 1.1.1.5 mrg 830 1.1 mrg // Assignment operators. 831 1.1.1.5 mrg _GLIBCXX20_CONSTEXPR optional& 832 1.1 mrg operator=(nullopt_t) noexcept 833 1.1 mrg { 834 1.1.1.3 mrg this->_M_reset(); 835 1.1.1.3 mrg return *this; 836 1.1 mrg } 837 1.1 mrg 838 1.1 mrg template<typename _Up = _Tp> 839 1.1.1.5 mrg _GLIBCXX20_CONSTEXPR 840 1.1.1.3 mrg enable_if_t<__and_v<__not_self<_Up>, 841 1.1.1.3 mrg __not_<__and_<is_scalar<_Tp>, 842 1.1.1.3 mrg is_same<_Tp, decay_t<_Up>>>>, 843 1.1.1.3 mrg is_constructible<_Tp, _Up>, 844 1.1.1.3 mrg is_assignable<_Tp&, _Up>>, 845 1.1 mrg optional&> 846 1.1.1.3 mrg operator=(_Up&& __u) 847 1.1.1.5 mrg noexcept(__and_v<is_nothrow_constructible<_Tp, _Up>, 848 1.1.1.5 mrg is_nothrow_assignable<_Tp&, _Up>>) 849 1.1.1.3 mrg { 850 1.1.1.3 mrg if (this->_M_is_engaged()) 851 1.1.1.3 mrg this->_M_get() = std::forward<_Up>(__u); 852 1.1.1.3 mrg else 853 1.1.1.3 mrg this->_M_construct(std::forward<_Up>(__u)); 854 1.1 mrg 855 1.1.1.3 mrg return *this; 856 1.1.1.3 mrg } 857 1.1 mrg 858 1.1 mrg template<typename _Up> 859 1.1.1.5 mrg _GLIBCXX20_CONSTEXPR 860 1.1.1.3 mrg enable_if_t<__and_v<__not_<is_same<_Tp, _Up>>, 861 1.1.1.3 mrg is_constructible<_Tp, const _Up&>, 862 1.1.1.4 mrg is_assignable<_Tp&, const _Up&>, 863 1.1.1.3 mrg __not_<__converts_from_optional<_Tp, _Up>>, 864 1.1.1.3 mrg __not_<__assigns_from_optional<_Tp, _Up>>>, 865 1.1 mrg optional&> 866 1.1.1.3 mrg operator=(const optional<_Up>& __u) 867 1.1.1.5 mrg noexcept(__and_v<is_nothrow_constructible<_Tp, const _Up&>, 868 1.1.1.5 mrg is_nothrow_assignable<_Tp&, const _Up&>>) 869 1.1.1.3 mrg { 870 1.1.1.3 mrg if (__u) 871 1.1.1.3 mrg { 872 1.1.1.3 mrg if (this->_M_is_engaged()) 873 1.1.1.3 mrg this->_M_get() = *__u; 874 1.1.1.3 mrg else 875 1.1.1.3 mrg this->_M_construct(*__u); 876 1.1.1.3 mrg } 877 1.1.1.3 mrg else 878 1.1.1.3 mrg { 879 1.1.1.3 mrg this->_M_reset(); 880 1.1.1.3 mrg } 881 1.1.1.3 mrg return *this; 882 1.1.1.3 mrg } 883 1.1 mrg 884 1.1 mrg template<typename _Up> 885 1.1.1.5 mrg _GLIBCXX20_CONSTEXPR 886 1.1.1.5 mrg enable_if_t<__and_v<__not_<is_same<_Tp, _Up>>, 887 1.1.1.3 mrg is_constructible<_Tp, _Up>, 888 1.1.1.3 mrg is_assignable<_Tp&, _Up>, 889 1.1.1.3 mrg __not_<__converts_from_optional<_Tp, _Up>>, 890 1.1.1.3 mrg __not_<__assigns_from_optional<_Tp, _Up>>>, 891 1.1 mrg optional&> 892 1.1.1.3 mrg operator=(optional<_Up>&& __u) 893 1.1.1.5 mrg noexcept(__and_v<is_nothrow_constructible<_Tp, _Up>, 894 1.1.1.5 mrg is_nothrow_assignable<_Tp&, _Up>>) 895 1.1.1.3 mrg { 896 1.1.1.3 mrg if (__u) 897 1.1.1.3 mrg { 898 1.1.1.3 mrg if (this->_M_is_engaged()) 899 1.1.1.3 mrg this->_M_get() = std::move(*__u); 900 1.1.1.3 mrg else 901 1.1.1.3 mrg this->_M_construct(std::move(*__u)); 902 1.1.1.3 mrg } 903 1.1.1.3 mrg else 904 1.1.1.3 mrg { 905 1.1.1.3 mrg this->_M_reset(); 906 1.1.1.3 mrg } 907 1.1 mrg 908 1.1.1.3 mrg return *this; 909 1.1.1.3 mrg } 910 1.1 mrg 911 1.1 mrg template<typename... _Args> 912 1.1.1.5 mrg _GLIBCXX20_CONSTEXPR 913 1.1.1.5 mrg enable_if_t<is_constructible_v<_Tp, _Args...>, _Tp&> 914 1.1 mrg emplace(_Args&&... __args) 915 1.1.1.5 mrg noexcept(is_nothrow_constructible_v<_Tp, _Args...>) 916 1.1 mrg { 917 1.1 mrg this->_M_reset(); 918 1.1 mrg this->_M_construct(std::forward<_Args>(__args)...); 919 1.1 mrg return this->_M_get(); 920 1.1 mrg } 921 1.1 mrg 922 1.1 mrg template<typename _Up, typename... _Args> 923 1.1.1.5 mrg _GLIBCXX20_CONSTEXPR 924 1.1.1.5 mrg enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>, 925 1.1.1.5 mrg _Tp&> 926 1.1 mrg emplace(initializer_list<_Up> __il, _Args&&... __args) 927 1.1.1.5 mrg noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, 928 1.1.1.5 mrg _Args...>) 929 1.1 mrg { 930 1.1 mrg this->_M_reset(); 931 1.1 mrg this->_M_construct(__il, std::forward<_Args>(__args)...); 932 1.1 mrg return this->_M_get(); 933 1.1 mrg } 934 1.1 mrg 935 1.1 mrg // Destructor is implicit, implemented in _Optional_base. 936 1.1 mrg 937 1.1 mrg // Swap. 938 1.1.1.5 mrg _GLIBCXX20_CONSTEXPR void 939 1.1 mrg swap(optional& __other) 940 1.1.1.3 mrg noexcept(is_nothrow_move_constructible_v<_Tp> 941 1.1.1.3 mrg && is_nothrow_swappable_v<_Tp>) 942 1.1 mrg { 943 1.1.1.3 mrg using std::swap; 944 1.1 mrg 945 1.1.1.3 mrg if (this->_M_is_engaged() && __other._M_is_engaged()) 946 1.1.1.3 mrg swap(this->_M_get(), __other._M_get()); 947 1.1.1.3 mrg else if (this->_M_is_engaged()) 948 1.1 mrg { 949 1.1 mrg __other._M_construct(std::move(this->_M_get())); 950 1.1 mrg this->_M_destruct(); 951 1.1 mrg } 952 1.1.1.3 mrg else if (__other._M_is_engaged()) 953 1.1 mrg { 954 1.1 mrg this->_M_construct(std::move(__other._M_get())); 955 1.1 mrg __other._M_destruct(); 956 1.1 mrg } 957 1.1 mrg } 958 1.1 mrg 959 1.1 mrg // Observers. 960 1.1 mrg constexpr const _Tp* 961 1.1.1.5 mrg operator->() const noexcept 962 1.1 mrg { return std::__addressof(this->_M_get()); } 963 1.1 mrg 964 1.1.1.4 mrg constexpr _Tp* 965 1.1.1.5 mrg operator->() noexcept 966 1.1 mrg { return std::__addressof(this->_M_get()); } 967 1.1 mrg 968 1.1 mrg constexpr const _Tp& 969 1.1.1.5 mrg operator*() const& noexcept 970 1.1 mrg { return this->_M_get(); } 971 1.1 mrg 972 1.1 mrg constexpr _Tp& 973 1.1.1.5 mrg operator*()& noexcept 974 1.1 mrg { return this->_M_get(); } 975 1.1 mrg 976 1.1 mrg constexpr _Tp&& 977 1.1.1.5 mrg operator*()&& noexcept 978 1.1 mrg { return std::move(this->_M_get()); } 979 1.1 mrg 980 1.1 mrg constexpr const _Tp&& 981 1.1.1.5 mrg operator*() const&& noexcept 982 1.1 mrg { return std::move(this->_M_get()); } 983 1.1 mrg 984 1.1 mrg constexpr explicit operator bool() const noexcept 985 1.1 mrg { return this->_M_is_engaged(); } 986 1.1 mrg 987 1.1 mrg constexpr bool has_value() const noexcept 988 1.1 mrg { return this->_M_is_engaged(); } 989 1.1 mrg 990 1.1 mrg constexpr const _Tp& 991 1.1 mrg value() const& 992 1.1 mrg { 993 1.1.1.5 mrg if (this->_M_is_engaged()) 994 1.1.1.5 mrg return this->_M_get(); 995 1.1.1.5 mrg __throw_bad_optional_access(); 996 1.1 mrg } 997 1.1 mrg 998 1.1 mrg constexpr _Tp& 999 1.1 mrg value()& 1000 1.1 mrg { 1001 1.1.1.5 mrg if (this->_M_is_engaged()) 1002 1.1.1.5 mrg return this->_M_get(); 1003 1.1.1.5 mrg __throw_bad_optional_access(); 1004 1.1 mrg } 1005 1.1 mrg 1006 1.1 mrg constexpr _Tp&& 1007 1.1 mrg value()&& 1008 1.1 mrg { 1009 1.1.1.5 mrg if (this->_M_is_engaged()) 1010 1.1.1.5 mrg return std::move(this->_M_get()); 1011 1.1.1.5 mrg __throw_bad_optional_access(); 1012 1.1 mrg } 1013 1.1 mrg 1014 1.1 mrg constexpr const _Tp&& 1015 1.1 mrg value() const&& 1016 1.1 mrg { 1017 1.1.1.5 mrg if (this->_M_is_engaged()) 1018 1.1.1.5 mrg return std::move(this->_M_get()); 1019 1.1.1.5 mrg __throw_bad_optional_access(); 1020 1.1 mrg } 1021 1.1 mrg 1022 1.1 mrg template<typename _Up> 1023 1.1 mrg constexpr _Tp 1024 1.1 mrg value_or(_Up&& __u) const& 1025 1.1 mrg { 1026 1.1.1.2 mrg static_assert(is_copy_constructible_v<_Tp>); 1027 1.1.1.2 mrg static_assert(is_convertible_v<_Up&&, _Tp>); 1028 1.1 mrg 1029 1.1.1.5 mrg if (this->_M_is_engaged()) 1030 1.1.1.5 mrg return this->_M_get(); 1031 1.1.1.5 mrg else 1032 1.1.1.5 mrg return static_cast<_Tp>(std::forward<_Up>(__u)); 1033 1.1 mrg } 1034 1.1 mrg 1035 1.1 mrg template<typename _Up> 1036 1.1.1.2 mrg constexpr _Tp 1037 1.1 mrg value_or(_Up&& __u) && 1038 1.1 mrg { 1039 1.1.1.2 mrg static_assert(is_move_constructible_v<_Tp>); 1040 1.1.1.2 mrg static_assert(is_convertible_v<_Up&&, _Tp>); 1041 1.1 mrg 1042 1.1.1.5 mrg if (this->_M_is_engaged()) 1043 1.1.1.5 mrg return std::move(this->_M_get()); 1044 1.1.1.5 mrg else 1045 1.1.1.5 mrg return static_cast<_Tp>(std::forward<_Up>(__u)); 1046 1.1.1.5 mrg } 1047 1.1.1.5 mrg 1048 1.1.1.5 mrg #if __cpp_lib_optional >= 202110L 1049 1.1.1.5 mrg // [optional.monadic] 1050 1.1.1.5 mrg 1051 1.1.1.5 mrg template<typename _Fn> 1052 1.1.1.5 mrg constexpr auto 1053 1.1.1.5 mrg and_then(_Fn&& __f) & 1054 1.1.1.5 mrg { 1055 1.1.1.5 mrg using _Up = remove_cvref_t<invoke_result_t<_Fn, _Tp&>>; 1056 1.1.1.5 mrg static_assert(__is_optional_v<remove_cvref_t<_Up>>); 1057 1.1.1.5 mrg if (has_value()) 1058 1.1.1.5 mrg return std::__invoke(std::forward<_Fn>(__f), **this); 1059 1.1.1.5 mrg else 1060 1.1.1.5 mrg return _Up(); 1061 1.1 mrg } 1062 1.1.1.3 mrg 1063 1.1.1.5 mrg template<typename _Fn> 1064 1.1.1.5 mrg constexpr auto 1065 1.1.1.5 mrg and_then(_Fn&& __f) const & 1066 1.1.1.5 mrg { 1067 1.1.1.5 mrg using _Up = remove_cvref_t<invoke_result_t<_Fn, const _Tp&>>; 1068 1.1.1.5 mrg static_assert(__is_optional_v<_Up>); 1069 1.1.1.5 mrg if (has_value()) 1070 1.1.1.5 mrg return std::__invoke(std::forward<_Fn>(__f), **this); 1071 1.1.1.5 mrg else 1072 1.1.1.5 mrg return _Up(); 1073 1.1.1.5 mrg } 1074 1.1.1.5 mrg 1075 1.1.1.5 mrg template<typename _Fn> 1076 1.1.1.5 mrg constexpr auto 1077 1.1.1.5 mrg and_then(_Fn&& __f) && 1078 1.1.1.5 mrg { 1079 1.1.1.5 mrg using _Up = remove_cvref_t<invoke_result_t<_Fn, _Tp>>; 1080 1.1.1.5 mrg static_assert(__is_optional_v<remove_cvref_t<_Up>>); 1081 1.1.1.5 mrg if (has_value()) 1082 1.1.1.5 mrg return std::__invoke(std::forward<_Fn>(__f), std::move(**this)); 1083 1.1.1.5 mrg else 1084 1.1.1.5 mrg return _Up(); 1085 1.1.1.5 mrg } 1086 1.1.1.5 mrg 1087 1.1.1.5 mrg template<typename _Fn> 1088 1.1.1.5 mrg constexpr auto 1089 1.1.1.5 mrg and_then(_Fn&& __f) const && 1090 1.1.1.5 mrg { 1091 1.1.1.5 mrg using _Up = remove_cvref_t<invoke_result_t<_Fn, const _Tp>>; 1092 1.1.1.5 mrg static_assert(__is_optional_v<remove_cvref_t<_Up>>); 1093 1.1.1.5 mrg if (has_value()) 1094 1.1.1.5 mrg return std::__invoke(std::forward<_Fn>(__f), std::move(**this)); 1095 1.1.1.5 mrg else 1096 1.1.1.5 mrg return _Up(); 1097 1.1.1.5 mrg } 1098 1.1.1.5 mrg 1099 1.1.1.5 mrg template<typename _Fn> 1100 1.1.1.5 mrg constexpr auto 1101 1.1.1.5 mrg transform(_Fn&& __f) & 1102 1.1.1.5 mrg { 1103 1.1.1.5 mrg using _Up = remove_cv_t<invoke_result_t<_Fn, _Tp&>>; 1104 1.1.1.5 mrg if (has_value()) 1105 1.1.1.5 mrg return optional<_Up>(_Optional_func<_Fn>{__f}, **this); 1106 1.1.1.5 mrg else 1107 1.1.1.5 mrg return optional<_Up>(); 1108 1.1.1.5 mrg } 1109 1.1.1.5 mrg 1110 1.1.1.5 mrg template<typename _Fn> 1111 1.1.1.5 mrg constexpr auto 1112 1.1.1.5 mrg transform(_Fn&& __f) const & 1113 1.1.1.5 mrg { 1114 1.1.1.5 mrg using _Up = remove_cv_t<invoke_result_t<_Fn, const _Tp&>>; 1115 1.1.1.5 mrg if (has_value()) 1116 1.1.1.5 mrg return optional<_Up>(_Optional_func<_Fn>{__f}, **this); 1117 1.1.1.5 mrg else 1118 1.1.1.5 mrg return optional<_Up>(); 1119 1.1.1.5 mrg } 1120 1.1.1.5 mrg 1121 1.1.1.5 mrg template<typename _Fn> 1122 1.1.1.5 mrg constexpr auto 1123 1.1.1.5 mrg transform(_Fn&& __f) && 1124 1.1.1.5 mrg { 1125 1.1.1.5 mrg using _Up = remove_cv_t<invoke_result_t<_Fn, _Tp>>; 1126 1.1.1.5 mrg if (has_value()) 1127 1.1.1.5 mrg return optional<_Up>(_Optional_func<_Fn>{__f}, std::move(**this)); 1128 1.1.1.5 mrg else 1129 1.1.1.5 mrg return optional<_Up>(); 1130 1.1.1.5 mrg } 1131 1.1.1.5 mrg 1132 1.1.1.5 mrg template<typename _Fn> 1133 1.1.1.5 mrg constexpr auto 1134 1.1.1.5 mrg transform(_Fn&& __f) const && 1135 1.1.1.5 mrg { 1136 1.1.1.5 mrg using _Up = remove_cv_t<invoke_result_t<_Fn, const _Tp>>; 1137 1.1.1.5 mrg if (has_value()) 1138 1.1.1.5 mrg return optional<_Up>(_Optional_func<_Fn>{__f}, std::move(**this)); 1139 1.1.1.5 mrg else 1140 1.1.1.5 mrg return optional<_Up>(); 1141 1.1.1.5 mrg } 1142 1.1.1.5 mrg 1143 1.1.1.5 mrg template<typename _Fn> requires invocable<_Fn> && copy_constructible<_Tp> 1144 1.1.1.5 mrg constexpr optional 1145 1.1.1.5 mrg or_else(_Fn&& __f) const& 1146 1.1.1.5 mrg { 1147 1.1.1.5 mrg using _Up = invoke_result_t<_Fn>; 1148 1.1.1.5 mrg static_assert( is_same_v<remove_cvref_t<_Up>, optional> ); 1149 1.1.1.5 mrg 1150 1.1.1.5 mrg if (has_value()) 1151 1.1.1.5 mrg return *this; 1152 1.1.1.5 mrg else 1153 1.1.1.5 mrg return std::forward<_Fn>(__f)(); 1154 1.1.1.5 mrg } 1155 1.1.1.5 mrg 1156 1.1.1.5 mrg template<typename _Fn> requires invocable<_Fn> && move_constructible<_Tp> 1157 1.1.1.5 mrg constexpr optional 1158 1.1.1.5 mrg or_else(_Fn&& __f) && 1159 1.1.1.5 mrg { 1160 1.1.1.5 mrg using _Up = invoke_result_t<_Fn>; 1161 1.1.1.5 mrg static_assert( is_same_v<remove_cvref_t<_Up>, optional> ); 1162 1.1.1.5 mrg 1163 1.1.1.5 mrg if (has_value()) 1164 1.1.1.5 mrg return std::move(*this); 1165 1.1.1.5 mrg else 1166 1.1.1.5 mrg return std::forward<_Fn>(__f)(); 1167 1.1.1.5 mrg } 1168 1.1.1.5 mrg #endif 1169 1.1.1.5 mrg 1170 1.1.1.5 mrg _GLIBCXX20_CONSTEXPR void reset() noexcept { this->_M_reset(); } 1171 1.1.1.5 mrg 1172 1.1.1.5 mrg private: 1173 1.1.1.5 mrg #if __cplusplus >= 202002L 1174 1.1.1.5 mrg template<typename _Up> friend class optional; 1175 1.1.1.5 mrg 1176 1.1.1.5 mrg template<typename _Fn, typename _Value> 1177 1.1.1.5 mrg explicit constexpr 1178 1.1.1.5 mrg optional(_Optional_func<_Fn> __f, _Value&& __v) 1179 1.1.1.5 mrg { 1180 1.1.1.5 mrg this->_M_payload._M_apply(__f, std::forward<_Value>(__v)); 1181 1.1.1.5 mrg } 1182 1.1.1.5 mrg #endif 1183 1.1 mrg }; 1184 1.1 mrg 1185 1.1 mrg template<typename _Tp> 1186 1.1 mrg using __optional_relop_t = 1187 1.1.1.3 mrg enable_if_t<is_convertible<_Tp, bool>::value, bool>; 1188 1.1 mrg 1189 1.1.1.4 mrg template<typename _Tp, typename _Up> 1190 1.1.1.4 mrg using __optional_eq_t = __optional_relop_t< 1191 1.1.1.4 mrg decltype(std::declval<const _Tp&>() == std::declval<const _Up&>()) 1192 1.1.1.4 mrg >; 1193 1.1.1.4 mrg 1194 1.1.1.4 mrg template<typename _Tp, typename _Up> 1195 1.1.1.4 mrg using __optional_ne_t = __optional_relop_t< 1196 1.1.1.4 mrg decltype(std::declval<const _Tp&>() != std::declval<const _Up&>()) 1197 1.1.1.4 mrg >; 1198 1.1.1.4 mrg 1199 1.1.1.4 mrg template<typename _Tp, typename _Up> 1200 1.1.1.4 mrg using __optional_lt_t = __optional_relop_t< 1201 1.1.1.4 mrg decltype(std::declval<const _Tp&>() < std::declval<const _Up&>()) 1202 1.1.1.4 mrg >; 1203 1.1.1.4 mrg 1204 1.1.1.4 mrg template<typename _Tp, typename _Up> 1205 1.1.1.4 mrg using __optional_gt_t = __optional_relop_t< 1206 1.1.1.4 mrg decltype(std::declval<const _Tp&>() > std::declval<const _Up&>()) 1207 1.1.1.4 mrg >; 1208 1.1.1.4 mrg 1209 1.1.1.4 mrg template<typename _Tp, typename _Up> 1210 1.1.1.4 mrg using __optional_le_t = __optional_relop_t< 1211 1.1.1.4 mrg decltype(std::declval<const _Tp&>() <= std::declval<const _Up&>()) 1212 1.1.1.4 mrg >; 1213 1.1.1.4 mrg 1214 1.1.1.4 mrg template<typename _Tp, typename _Up> 1215 1.1.1.4 mrg using __optional_ge_t = __optional_relop_t< 1216 1.1.1.4 mrg decltype(std::declval<const _Tp&>() >= std::declval<const _Up&>()) 1217 1.1.1.4 mrg >; 1218 1.1.1.4 mrg 1219 1.1 mrg // Comparisons between optional values. 1220 1.1 mrg template<typename _Tp, typename _Up> 1221 1.1 mrg constexpr auto 1222 1.1 mrg operator==(const optional<_Tp>& __lhs, const optional<_Up>& __rhs) 1223 1.1.1.4 mrg -> __optional_eq_t<_Tp, _Up> 1224 1.1 mrg { 1225 1.1 mrg return static_cast<bool>(__lhs) == static_cast<bool>(__rhs) 1226 1.1 mrg && (!__lhs || *__lhs == *__rhs); 1227 1.1 mrg } 1228 1.1 mrg 1229 1.1 mrg template<typename _Tp, typename _Up> 1230 1.1 mrg constexpr auto 1231 1.1 mrg operator!=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs) 1232 1.1.1.4 mrg -> __optional_ne_t<_Tp, _Up> 1233 1.1 mrg { 1234 1.1 mrg return static_cast<bool>(__lhs) != static_cast<bool>(__rhs) 1235 1.1 mrg || (static_cast<bool>(__lhs) && *__lhs != *__rhs); 1236 1.1 mrg } 1237 1.1 mrg 1238 1.1 mrg template<typename _Tp, typename _Up> 1239 1.1 mrg constexpr auto 1240 1.1 mrg operator<(const optional<_Tp>& __lhs, const optional<_Up>& __rhs) 1241 1.1.1.4 mrg -> __optional_lt_t<_Tp, _Up> 1242 1.1 mrg { 1243 1.1 mrg return static_cast<bool>(__rhs) && (!__lhs || *__lhs < *__rhs); 1244 1.1 mrg } 1245 1.1 mrg 1246 1.1 mrg template<typename _Tp, typename _Up> 1247 1.1 mrg constexpr auto 1248 1.1 mrg operator>(const optional<_Tp>& __lhs, const optional<_Up>& __rhs) 1249 1.1.1.4 mrg -> __optional_gt_t<_Tp, _Up> 1250 1.1 mrg { 1251 1.1 mrg return static_cast<bool>(__lhs) && (!__rhs || *__lhs > *__rhs); 1252 1.1 mrg } 1253 1.1 mrg 1254 1.1 mrg template<typename _Tp, typename _Up> 1255 1.1 mrg constexpr auto 1256 1.1 mrg operator<=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs) 1257 1.1.1.4 mrg -> __optional_le_t<_Tp, _Up> 1258 1.1 mrg { 1259 1.1 mrg return !__lhs || (static_cast<bool>(__rhs) && *__lhs <= *__rhs); 1260 1.1 mrg } 1261 1.1 mrg 1262 1.1 mrg template<typename _Tp, typename _Up> 1263 1.1 mrg constexpr auto 1264 1.1 mrg operator>=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs) 1265 1.1.1.4 mrg -> __optional_ge_t<_Tp, _Up> 1266 1.1 mrg { 1267 1.1 mrg return !__rhs || (static_cast<bool>(__lhs) && *__lhs >= *__rhs); 1268 1.1 mrg } 1269 1.1 mrg 1270 1.1.1.4 mrg #ifdef __cpp_lib_three_way_comparison 1271 1.1.1.4 mrg template<typename _Tp, three_way_comparable_with<_Tp> _Up> 1272 1.1.1.4 mrg constexpr compare_three_way_result_t<_Tp, _Up> 1273 1.1.1.4 mrg operator<=>(const optional<_Tp>& __x, const optional<_Up>& __y) 1274 1.1.1.4 mrg { 1275 1.1.1.4 mrg return __x && __y ? *__x <=> *__y : bool(__x) <=> bool(__y); 1276 1.1.1.4 mrg } 1277 1.1.1.4 mrg #endif 1278 1.1.1.4 mrg 1279 1.1 mrg // Comparisons with nullopt. 1280 1.1 mrg template<typename _Tp> 1281 1.1 mrg constexpr bool 1282 1.1 mrg operator==(const optional<_Tp>& __lhs, nullopt_t) noexcept 1283 1.1 mrg { return !__lhs; } 1284 1.1 mrg 1285 1.1.1.4 mrg #ifdef __cpp_lib_three_way_comparison 1286 1.1.1.4 mrg template<typename _Tp> 1287 1.1.1.4 mrg constexpr strong_ordering 1288 1.1.1.4 mrg operator<=>(const optional<_Tp>& __x, nullopt_t) noexcept 1289 1.1.1.4 mrg { return bool(__x) <=> false; } 1290 1.1.1.4 mrg #else 1291 1.1 mrg template<typename _Tp> 1292 1.1 mrg constexpr bool 1293 1.1 mrg operator==(nullopt_t, const optional<_Tp>& __rhs) noexcept 1294 1.1 mrg { return !__rhs; } 1295 1.1 mrg 1296 1.1 mrg template<typename _Tp> 1297 1.1 mrg constexpr bool 1298 1.1 mrg operator!=(const optional<_Tp>& __lhs, nullopt_t) noexcept 1299 1.1 mrg { return static_cast<bool>(__lhs); } 1300 1.1 mrg 1301 1.1 mrg template<typename _Tp> 1302 1.1 mrg constexpr bool 1303 1.1 mrg operator!=(nullopt_t, const optional<_Tp>& __rhs) noexcept 1304 1.1 mrg { return static_cast<bool>(__rhs); } 1305 1.1 mrg 1306 1.1 mrg template<typename _Tp> 1307 1.1 mrg constexpr bool 1308 1.1 mrg operator<(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept 1309 1.1 mrg { return false; } 1310 1.1 mrg 1311 1.1 mrg template<typename _Tp> 1312 1.1 mrg constexpr bool 1313 1.1 mrg operator<(nullopt_t, const optional<_Tp>& __rhs) noexcept 1314 1.1 mrg { return static_cast<bool>(__rhs); } 1315 1.1 mrg 1316 1.1 mrg template<typename _Tp> 1317 1.1 mrg constexpr bool 1318 1.1 mrg operator>(const optional<_Tp>& __lhs, nullopt_t) noexcept 1319 1.1 mrg { return static_cast<bool>(__lhs); } 1320 1.1 mrg 1321 1.1 mrg template<typename _Tp> 1322 1.1 mrg constexpr bool 1323 1.1 mrg operator>(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept 1324 1.1 mrg { return false; } 1325 1.1 mrg 1326 1.1 mrg template<typename _Tp> 1327 1.1 mrg constexpr bool 1328 1.1 mrg operator<=(const optional<_Tp>& __lhs, nullopt_t) noexcept 1329 1.1 mrg { return !__lhs; } 1330 1.1 mrg 1331 1.1 mrg template<typename _Tp> 1332 1.1 mrg constexpr bool 1333 1.1 mrg operator<=(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept 1334 1.1 mrg { return true; } 1335 1.1 mrg 1336 1.1 mrg template<typename _Tp> 1337 1.1 mrg constexpr bool 1338 1.1 mrg operator>=(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept 1339 1.1 mrg { return true; } 1340 1.1 mrg 1341 1.1 mrg template<typename _Tp> 1342 1.1 mrg constexpr bool 1343 1.1 mrg operator>=(nullopt_t, const optional<_Tp>& __rhs) noexcept 1344 1.1 mrg { return !__rhs; } 1345 1.1.1.4 mrg #endif // three-way-comparison 1346 1.1 mrg 1347 1.1 mrg // Comparisons with value type. 1348 1.1 mrg template<typename _Tp, typename _Up> 1349 1.1 mrg constexpr auto 1350 1.1 mrg operator==(const optional<_Tp>& __lhs, const _Up& __rhs) 1351 1.1.1.4 mrg -> __optional_eq_t<_Tp, _Up> 1352 1.1 mrg { return __lhs && *__lhs == __rhs; } 1353 1.1 mrg 1354 1.1 mrg template<typename _Tp, typename _Up> 1355 1.1 mrg constexpr auto 1356 1.1 mrg operator==(const _Up& __lhs, const optional<_Tp>& __rhs) 1357 1.1.1.4 mrg -> __optional_eq_t<_Up, _Tp> 1358 1.1 mrg { return __rhs && __lhs == *__rhs; } 1359 1.1 mrg 1360 1.1 mrg template<typename _Tp, typename _Up> 1361 1.1 mrg constexpr auto 1362 1.1 mrg operator!=(const optional<_Tp>& __lhs, const _Up& __rhs) 1363 1.1.1.4 mrg -> __optional_ne_t<_Tp, _Up> 1364 1.1 mrg { return !__lhs || *__lhs != __rhs; } 1365 1.1 mrg 1366 1.1 mrg template<typename _Tp, typename _Up> 1367 1.1 mrg constexpr auto 1368 1.1 mrg operator!=(const _Up& __lhs, const optional<_Tp>& __rhs) 1369 1.1.1.4 mrg -> __optional_ne_t<_Up, _Tp> 1370 1.1 mrg { return !__rhs || __lhs != *__rhs; } 1371 1.1 mrg 1372 1.1 mrg template<typename _Tp, typename _Up> 1373 1.1 mrg constexpr auto 1374 1.1 mrg operator<(const optional<_Tp>& __lhs, const _Up& __rhs) 1375 1.1.1.4 mrg -> __optional_lt_t<_Tp, _Up> 1376 1.1 mrg { return !__lhs || *__lhs < __rhs; } 1377 1.1 mrg 1378 1.1 mrg template<typename _Tp, typename _Up> 1379 1.1 mrg constexpr auto 1380 1.1 mrg operator<(const _Up& __lhs, const optional<_Tp>& __rhs) 1381 1.1.1.4 mrg -> __optional_lt_t<_Up, _Tp> 1382 1.1 mrg { return __rhs && __lhs < *__rhs; } 1383 1.1 mrg 1384 1.1 mrg template<typename _Tp, typename _Up> 1385 1.1 mrg constexpr auto 1386 1.1 mrg operator>(const optional<_Tp>& __lhs, const _Up& __rhs) 1387 1.1.1.4 mrg -> __optional_gt_t<_Tp, _Up> 1388 1.1 mrg { return __lhs && *__lhs > __rhs; } 1389 1.1 mrg 1390 1.1 mrg template<typename _Tp, typename _Up> 1391 1.1 mrg constexpr auto 1392 1.1 mrg operator>(const _Up& __lhs, const optional<_Tp>& __rhs) 1393 1.1.1.4 mrg -> __optional_gt_t<_Up, _Tp> 1394 1.1 mrg { return !__rhs || __lhs > *__rhs; } 1395 1.1 mrg 1396 1.1 mrg template<typename _Tp, typename _Up> 1397 1.1 mrg constexpr auto 1398 1.1 mrg operator<=(const optional<_Tp>& __lhs, const _Up& __rhs) 1399 1.1.1.4 mrg -> __optional_le_t<_Tp, _Up> 1400 1.1 mrg { return !__lhs || *__lhs <= __rhs; } 1401 1.1 mrg 1402 1.1 mrg template<typename _Tp, typename _Up> 1403 1.1 mrg constexpr auto 1404 1.1 mrg operator<=(const _Up& __lhs, const optional<_Tp>& __rhs) 1405 1.1.1.4 mrg -> __optional_le_t<_Up, _Tp> 1406 1.1 mrg { return __rhs && __lhs <= *__rhs; } 1407 1.1 mrg 1408 1.1 mrg template<typename _Tp, typename _Up> 1409 1.1 mrg constexpr auto 1410 1.1 mrg operator>=(const optional<_Tp>& __lhs, const _Up& __rhs) 1411 1.1.1.4 mrg -> __optional_ge_t<_Tp, _Up> 1412 1.1 mrg { return __lhs && *__lhs >= __rhs; } 1413 1.1 mrg 1414 1.1 mrg template<typename _Tp, typename _Up> 1415 1.1 mrg constexpr auto 1416 1.1 mrg operator>=(const _Up& __lhs, const optional<_Tp>& __rhs) 1417 1.1.1.4 mrg -> __optional_ge_t<_Up, _Tp> 1418 1.1 mrg { return !__rhs || __lhs >= *__rhs; } 1419 1.1 mrg 1420 1.1.1.4 mrg #ifdef __cpp_lib_three_way_comparison 1421 1.1.1.4 mrg template<typename _Tp, typename _Up> 1422 1.1.1.4 mrg requires (!__is_optional_v<_Up>) 1423 1.1.1.5 mrg && three_way_comparable_with<_Up, _Tp> 1424 1.1.1.4 mrg constexpr compare_three_way_result_t<_Tp, _Up> 1425 1.1.1.4 mrg operator<=>(const optional<_Tp>& __x, const _Up& __v) 1426 1.1.1.4 mrg { return bool(__x) ? *__x <=> __v : strong_ordering::less; } 1427 1.1.1.4 mrg #endif 1428 1.1.1.4 mrg 1429 1.1 mrg // Swap and creation functions. 1430 1.1 mrg 1431 1.1 mrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 1432 1.1 mrg // 2748. swappable traits for optionals 1433 1.1 mrg template<typename _Tp> 1434 1.1.1.5 mrg _GLIBCXX20_CONSTEXPR 1435 1.1 mrg inline enable_if_t<is_move_constructible_v<_Tp> && is_swappable_v<_Tp>> 1436 1.1 mrg swap(optional<_Tp>& __lhs, optional<_Tp>& __rhs) 1437 1.1 mrg noexcept(noexcept(__lhs.swap(__rhs))) 1438 1.1 mrg { __lhs.swap(__rhs); } 1439 1.1 mrg 1440 1.1 mrg template<typename _Tp> 1441 1.1 mrg enable_if_t<!(is_move_constructible_v<_Tp> && is_swappable_v<_Tp>)> 1442 1.1 mrg swap(optional<_Tp>&, optional<_Tp>&) = delete; 1443 1.1 mrg 1444 1.1 mrg template<typename _Tp> 1445 1.1.1.5 mrg constexpr 1446 1.1.1.5 mrg enable_if_t<is_constructible_v<decay_t<_Tp>, _Tp>, 1447 1.1.1.5 mrg optional<decay_t<_Tp>>> 1448 1.1 mrg make_optional(_Tp&& __t) 1449 1.1.1.5 mrg noexcept(is_nothrow_constructible_v<optional<decay_t<_Tp>>, _Tp>) 1450 1.1.1.5 mrg { return optional<decay_t<_Tp>>{ std::forward<_Tp>(__t) }; } 1451 1.1 mrg 1452 1.1.1.5 mrg template<typename _Tp, typename... _Args> 1453 1.1.1.5 mrg constexpr 1454 1.1.1.5 mrg enable_if_t<is_constructible_v<_Tp, _Args...>, 1455 1.1.1.5 mrg optional<_Tp>> 1456 1.1 mrg make_optional(_Args&&... __args) 1457 1.1.1.5 mrg noexcept(is_nothrow_constructible_v<_Tp, _Args...>) 1458 1.1.1.5 mrg { return optional<_Tp>{ in_place, std::forward<_Args>(__args)... }; } 1459 1.1 mrg 1460 1.1.1.5 mrg template<typename _Tp, typename _Up, typename... _Args> 1461 1.1.1.5 mrg constexpr 1462 1.1.1.5 mrg enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>, 1463 1.1.1.5 mrg optional<_Tp>> 1464 1.1 mrg make_optional(initializer_list<_Up> __il, _Args&&... __args) 1465 1.1.1.5 mrg noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, _Args...>) 1466 1.1.1.5 mrg { return optional<_Tp>{ in_place, __il, std::forward<_Args>(__args)... }; } 1467 1.1 mrg 1468 1.1 mrg // Hash. 1469 1.1 mrg 1470 1.1 mrg template<typename _Tp, typename _Up = remove_const_t<_Tp>, 1471 1.1.1.5 mrg bool = __poison_hash<_Up>::__enable_hash_call> 1472 1.1 mrg struct __optional_hash_call_base 1473 1.1 mrg { 1474 1.1 mrg size_t 1475 1.1 mrg operator()(const optional<_Tp>& __t) const 1476 1.1 mrg noexcept(noexcept(hash<_Up>{}(*__t))) 1477 1.1 mrg { 1478 1.1.1.5 mrg // We pick an arbitrary hash for disengaged optionals which hopefully 1479 1.1.1.5 mrg // usual values of _Tp won't typically hash to. 1480 1.1.1.5 mrg constexpr size_t __magic_disengaged_hash = static_cast<size_t>(-3333); 1481 1.1.1.5 mrg return __t ? hash<_Up>{}(*__t) : __magic_disengaged_hash; 1482 1.1 mrg } 1483 1.1 mrg }; 1484 1.1 mrg 1485 1.1 mrg template<typename _Tp, typename _Up> 1486 1.1 mrg struct __optional_hash_call_base<_Tp, _Up, false> {}; 1487 1.1 mrg 1488 1.1 mrg template<typename _Tp> 1489 1.1 mrg struct hash<optional<_Tp>> 1490 1.1 mrg : private __poison_hash<remove_const_t<_Tp>>, 1491 1.1 mrg public __optional_hash_call_base<_Tp> 1492 1.1 mrg { 1493 1.1.1.2 mrg using result_type [[__deprecated__]] = size_t; 1494 1.1.1.2 mrg using argument_type [[__deprecated__]] = optional<_Tp>; 1495 1.1 mrg }; 1496 1.1 mrg 1497 1.1.1.2 mrg template<typename _Tp> 1498 1.1.1.2 mrg struct __is_fast_hash<hash<optional<_Tp>>> : __is_fast_hash<hash<_Tp>> 1499 1.1.1.2 mrg { }; 1500 1.1.1.2 mrg 1501 1.1 mrg /// @} 1502 1.1 mrg 1503 1.1 mrg #if __cpp_deduction_guides >= 201606 1504 1.1 mrg template <typename _Tp> optional(_Tp) -> optional<_Tp>; 1505 1.1 mrg #endif 1506 1.1 mrg 1507 1.1 mrg _GLIBCXX_END_NAMESPACE_VERSION 1508 1.1 mrg } // namespace std 1509 1.1 mrg 1510 1.1 mrg #endif // C++17 1511 1.1 mrg 1512 1.1 mrg #endif // _GLIBCXX_OPTIONAL 1513