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