libstdc++
optional
Go to the documentation of this file.
1// <optional> -*- C++ -*-
2
3// Copyright (C) 2013-2026 Free Software Foundation, Inc.
4// Copyright The GNU Toolchain Authors.
5//
6// This file is part of the GNU ISO C++ Library. This library is free
7// software; you can redistribute it and/or modify it under the
8// terms of the GNU General Public License as published by the
9// Free Software Foundation; either version 3, or (at your option)
10// any later version.
11
12// This library is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15// GNU General Public License for more details.
16
17// Under Section 7 of GPL version 3, you are granted additional
18// permissions described in the GCC Runtime Library Exception, version
19// 3.1, as published by the Free Software Foundation.
20
21// You should have received a copy of the GNU General Public License and
22// a copy of the GCC Runtime Library Exception along with this program;
23// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24// <http://www.gnu.org/licenses/>.
25
26/** @file include/optional
27 * This is a Standard C++ Library header.
28 */
29
30#ifndef _GLIBCXX_OPTIONAL
31#define _GLIBCXX_OPTIONAL 1
32
33#ifdef _GLIBCXX_SYSHDR
34#pragma GCC system_header
35#endif
36
37#define __glibcxx_want_freestanding_optional
38#define __glibcxx_want_optional
39#define __glibcxx_want_optional_range_support
40#define __glibcxx_want_constrained_equality
41#define __glibcxx_want_constexpr_exceptions
42#define __glibcxx_want_hardened_optional
43#include <bits/version.h>
44
45#ifdef __cpp_lib_optional // C++ >= 17
46
47#include <type_traits>
48#include <exception>
49#include <new>
50#include <initializer_list>
54#include <bits/optional_ref.h> // nullopt_t, optional<_Tp&>
55#include <bits/stl_construct.h> // _Construct
56#include <bits/utility.h> // in_place_t
57#if __cplusplus > 201703L
58# include <compare>
59# include <bits/invoke.h> // std::__invoke
60#endif
61#if __cplusplus > 202002L
62# include <concepts>
63#endif
64#ifdef __cpp_lib_optional_range_support // C++ >= 26
65# if _GLIBCXX_HOSTED
66# include <bits/formatfwd.h>
67# endif
68# include <bits/ranges_base.h>
69# include <bits/range_access.h>
70#endif
71
72namespace std _GLIBCXX_VISIBILITY(default)
73{
74_GLIBCXX_BEGIN_NAMESPACE_VERSION
75
76 /**
77 * @addtogroup utilities
78 * @{
79 */
80
81 /**
82 * @brief Exception class thrown when a disengaged optional object is
83 * dereferenced.
84 * @ingroup exceptions
85 */
86 class bad_optional_access : public exception
87 {
88 public:
89 bad_optional_access() = default;
90 virtual ~bad_optional_access() = default;
91
92#if __cpp_lib_constexpr_exceptions >= 202502L
93 constexpr
94#endif
95 const char* what() const noexcept override
96 { return "bad optional access"; }
97 };
98
99 // XXX Does not belong here.
100 [[__noreturn__]]
101#if __cpp_lib_constexpr_exceptions >= 202502L
102 constexpr
103#else
104 inline
105#endif
106 void
107 __throw_bad_optional_access()
108 { _GLIBCXX_THROW_OR_ABORT(bad_optional_access()); }
109
110 // This class template manages construction/destruction of
111 // the contained value for a std::optional.
112 template <typename _Tp>
113 struct _Optional_payload_base
114 {
115 using _Stored_type = remove_const_t<_Tp>;
116
117 _Optional_payload_base() = default;
118 ~_Optional_payload_base() = default;
119
120 template<typename... _Args>
121 constexpr
122 _Optional_payload_base(in_place_t __tag, _Args&&... __args)
123 : _M_payload(__tag, std::forward<_Args>(__args)...),
124 _M_engaged(true)
125 { }
126
127 template<typename _Up, typename... _Args>
128 constexpr
129 _Optional_payload_base(std::initializer_list<_Up> __il,
130 _Args&&... __args)
131 : _M_payload(__il, std::forward<_Args>(__args)...),
132 _M_engaged(true)
133 { }
134
135 // Constructor used by _Optional_base copy constructor when the
136 // contained value is not trivially copy constructible.
137 constexpr
138 _Optional_payload_base(bool /* __engaged */,
139 const _Optional_payload_base& __other)
140 {
141 if (__other._M_engaged)
142 this->_M_construct(__other._M_get());
143 }
144
145 // Constructor used by _Optional_base move constructor when the
146 // contained value is not trivially move constructible.
147 constexpr
148 _Optional_payload_base(bool /* __engaged */,
149 _Optional_payload_base&& __other)
150 {
151 if (__other._M_engaged)
152 this->_M_construct(std::move(__other._M_get()));
153 }
154
155 // Copy constructor is only used to when the contained value is
156 // trivially copy constructible.
157 _Optional_payload_base(const _Optional_payload_base&) = default;
158
159 // Move constructor is only used to when the contained value is
160 // trivially copy constructible.
161 _Optional_payload_base(_Optional_payload_base&&) = default;
162
163 _Optional_payload_base&
164 operator=(const _Optional_payload_base&) = default;
165
166 _Optional_payload_base&
167 operator=(_Optional_payload_base&&) = default;
168
169 // used to perform non-trivial copy assignment.
170 constexpr void
171 _M_copy_assign(const _Optional_payload_base& __other)
172 {
173 if (this->_M_engaged && __other._M_engaged)
174 this->_M_get() = __other._M_get();
175 else
176 {
177 if (__other._M_engaged)
178 this->_M_construct(__other._M_get());
179 else
180 this->_M_reset();
181 }
182 }
183
184 // used to perform non-trivial move assignment.
185 constexpr void
186 _M_move_assign(_Optional_payload_base&& __other)
187 noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
188 is_nothrow_move_assignable<_Tp>>)
189 {
190 if (this->_M_engaged && __other._M_engaged)
191 this->_M_get() = std::move(__other._M_get());
192 else
193 {
194 if (__other._M_engaged)
195 this->_M_construct(std::move(__other._M_get()));
196 else
197 this->_M_reset();
198 }
199 }
200
201 struct _Empty_byte { };
202
203 template<typename _Up, bool = is_trivially_destructible_v<_Up>>
204 union _Storage
205 {
206 constexpr _Storage() noexcept : _M_empty() { }
207
208 template<typename... _Args>
209 constexpr
210 _Storage(in_place_t, _Args&&... __args)
211 : _M_value(std::forward<_Args>(__args)...)
212 { }
213
214 template<typename _Vp, typename... _Args>
215 constexpr
216 _Storage(std::initializer_list<_Vp> __il, _Args&&... __args)
217 : _M_value(__il, std::forward<_Args>(__args)...)
218 { }
219
220#if __cplusplus >= 202002L
221 template<typename _Fn, typename _Arg>
222 constexpr
223 _Storage(_Optional_func<_Fn> __f, _Arg&& __arg)
224 : _M_value(std::__invoke(std::forward<_Fn>(__f._M_f),
225 std::forward<_Arg>(__arg)))
226 { }
227#endif
228
229#if __cpp_concepts >= 202002L // Conditionally trivial special member functions
230 ~_Storage() = default;
231
232 // User-provided destructor is needed when _Up has non-trivial dtor.
233 _GLIBCXX20_CONSTEXPR
234 ~_Storage() requires (!is_trivially_destructible_v<_Up>)
235 { }
236
237 _Storage(const _Storage&) = default;
238 _Storage(_Storage&&) = default;
239 _Storage& operator=(const _Storage&) = default;
240 _Storage& operator=(_Storage&&) = default;
241#endif
242
243 _Empty_byte _M_empty;
244 _Up _M_value;
245 };
246
247#if __cpp_concepts < 202002L
248 template<typename _Up>
249 union _Storage<_Up, false>
250 {
251 constexpr _Storage() noexcept : _M_empty() { }
252
253 template<typename... _Args>
254 constexpr
255 _Storage(in_place_t, _Args&&... __args)
256 : _M_value(std::forward<_Args>(__args)...)
257 { }
258
259 template<typename _Vp, typename... _Args>
260 constexpr
261 _Storage(std::initializer_list<_Vp> __il, _Args&&... __args)
262 : _M_value(__il, std::forward<_Args>(__args)...)
263 { }
264
265#if __cplusplus >= 202002L
266 template<typename _Fn, typename _Arg>
267 constexpr
268 _Storage(_Optional_func<_Fn> __f, _Arg&& __arg)
269 : _M_value(std::__invoke(std::forward<_Fn>(__f._M_f),
270 std::forward<_Arg>(__arg)))
271 { }
272#endif
273
274 // User-provided destructor is needed when _Up has non-trivial dtor.
275 _GLIBCXX20_CONSTEXPR ~_Storage() { }
276
277 _Storage(const _Storage&) = default;
278 _Storage(_Storage&&) = default;
279 _Storage& operator=(const _Storage&) = default;
280 _Storage& operator=(_Storage&&) = default;
281
282 _Empty_byte _M_empty;
283 _Up _M_value;
284 };
285#endif
286
287 _Storage<_Stored_type> _M_payload;
288
289 bool _M_engaged = false;
290
291 template<typename... _Args>
292 constexpr void
293 _M_construct(_Args&&... __args)
294 noexcept(is_nothrow_constructible_v<_Stored_type, _Args...>)
295 {
296 std::_Construct(std::__addressof(this->_M_payload._M_value),
297 std::forward<_Args>(__args)...);
298 this->_M_engaged = true;
299 }
300
301 constexpr void
302 _M_destroy() noexcept
303 {
304 _M_engaged = false;
305 _M_payload._M_value.~_Stored_type();
306 // After the destructor, _M_engaged should always be false, see PR 127005.
307 if (_M_engaged)
308 __builtin_unreachable();
309#if defined(__clang__) && __cpp_lib_optional >= 202106L // full constexpr support
310 if (std::is_constant_evaluated())
311 // Work around PR124910 for Clang.
312 std::construct_at(std::__addressof(_M_payload._M_empty));
313#endif
314 }
315
316#if __cplusplus >= 202002L
317 template<typename _Fn, typename _Up>
318 constexpr void
319 _M_apply(_Optional_func<_Fn> __f, _Up&& __x)
320 {
321 std::construct_at(std::__addressof(this->_M_payload),
322 __f, std::forward<_Up>(__x));
323 _M_engaged = true;
324 }
325#endif
326
327 // The _M_get() operations have _M_engaged as a precondition.
328 // They exist to access the contained value with the appropriate
329 // const-qualification, because _M_payload has had the const removed.
330
331 constexpr _Tp&
332 _M_get() noexcept
333 { return this->_M_payload._M_value; }
334
335 constexpr const _Tp&
336 _M_get() const noexcept
337 { return this->_M_payload._M_value; }
338
339 // _M_reset is a 'safe' operation with no precondition.
340 constexpr void
341 _M_reset() noexcept
342 {
343 if (this->_M_engaged)
344 _M_destroy();
345 else // This seems redundant but improves codegen, see PR 112480.
346 this->_M_engaged = false;
347 }
348 };
349
350 // Class template that manages the payload for optionals.
351 template <typename _Tp,
352 bool /*_HasTrivialDestructor*/ =
353 is_trivially_destructible_v<_Tp>,
354 bool /*_HasTrivialCopy */ =
355 is_trivially_copy_assignable_v<_Tp>
356 && is_trivially_copy_constructible_v<_Tp>,
357 bool /*_HasTrivialMove */ =
358 is_trivially_move_assignable_v<_Tp>
359 && is_trivially_move_constructible_v<_Tp>>
360 struct _Optional_payload;
361
362 // Payload for potentially-constexpr optionals (trivial copy/move/destroy).
363 template <typename _Tp>
364 struct _Optional_payload<_Tp, true, true, true>
365 : _Optional_payload_base<_Tp>
366 {
367 using _Optional_payload_base<_Tp>::_Optional_payload_base;
368
369 _Optional_payload() = default;
370 };
371
372 // Payload for optionals with non-trivial copy construction/assignment.
373 template <typename _Tp>
374 struct _Optional_payload<_Tp, true, false, true>
375 : _Optional_payload_base<_Tp>
376 {
377 using _Optional_payload_base<_Tp>::_Optional_payload_base;
378
379 _Optional_payload() = default;
380 ~_Optional_payload() = default;
381 _Optional_payload(const _Optional_payload&) = default;
382 _Optional_payload(_Optional_payload&&) = default;
383 _Optional_payload& operator=(_Optional_payload&&) = default;
384
385 // Non-trivial copy assignment.
386 constexpr
387 _Optional_payload&
388 operator=(const _Optional_payload& __other)
389 {
390 this->_M_copy_assign(__other);
391 return *this;
392 }
393 };
394
395 // Payload for optionals with non-trivial move construction/assignment.
396 template <typename _Tp>
397 struct _Optional_payload<_Tp, true, true, false>
398 : _Optional_payload_base<_Tp>
399 {
400 using _Optional_payload_base<_Tp>::_Optional_payload_base;
401
402 _Optional_payload() = default;
403 ~_Optional_payload() = default;
404 _Optional_payload(const _Optional_payload&) = default;
405 _Optional_payload(_Optional_payload&&) = default;
406 _Optional_payload& operator=(const _Optional_payload&) = default;
407
408 // Non-trivial move assignment.
409 constexpr
410 _Optional_payload&
411 operator=(_Optional_payload&& __other)
412 noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
413 is_nothrow_move_assignable<_Tp>>)
414 {
415 this->_M_move_assign(std::move(__other));
416 return *this;
417 }
418 };
419
420 // Payload for optionals with non-trivial copy and move assignment.
421 template <typename _Tp>
422 struct _Optional_payload<_Tp, true, false, false>
423 : _Optional_payload_base<_Tp>
424 {
425 using _Optional_payload_base<_Tp>::_Optional_payload_base;
426
427 _Optional_payload() = default;
428 ~_Optional_payload() = default;
429 _Optional_payload(const _Optional_payload&) = default;
430 _Optional_payload(_Optional_payload&&) = default;
431
432 // Non-trivial copy assignment.
433 constexpr
434 _Optional_payload&
435 operator=(const _Optional_payload& __other)
436 {
437 this->_M_copy_assign(__other);
438 return *this;
439 }
440
441 // Non-trivial move assignment.
442 constexpr
443 _Optional_payload&
444 operator=(_Optional_payload&& __other)
445 noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
446 is_nothrow_move_assignable<_Tp>>)
447 {
448 this->_M_move_assign(std::move(__other));
449 return *this;
450 }
451 };
452
453 // Payload for optionals with non-trivial destructors.
454 template <typename _Tp, bool _Copy, bool _Move>
455 struct _Optional_payload<_Tp, false, _Copy, _Move>
456 : _Optional_payload<_Tp, true, false, false>
457 {
458 // Base class implements all the constructors and assignment operators:
459 using _Optional_payload<_Tp, true, false, false>::_Optional_payload;
460 _Optional_payload() = default;
461 _Optional_payload(const _Optional_payload&) = default;
462 _Optional_payload(_Optional_payload&&) = default;
463 _Optional_payload& operator=(const _Optional_payload&) = default;
464 _Optional_payload& operator=(_Optional_payload&&) = default;
465
466 // Destructor needs to destroy the contained value:
467 _GLIBCXX20_CONSTEXPR ~_Optional_payload() { this->_M_reset(); }
468 };
469
470 /**
471 * @brief Class template that provides copy/move constructors of optional.
472 *
473 * Such a separate base class template is necessary in order to
474 * conditionally make copy/move constructors trivial.
475 *
476 * When the contained value is trivially copy/move constructible,
477 * the copy/move constructors of _Optional_base will invoke the
478 * trivial copy/move constructor of _Optional_payload. Otherwise,
479 * they will invoke _Optional_payload(bool, const _Optional_payload&)
480 * or _Optional_payload(bool, _Optional_payload&&) to initialize
481 * the contained value, if copying/moving an engaged optional.
482 *
483 * Whether the other special members are trivial is determined by the
484 * _Optional_payload<_Tp> specialization used for the _M_payload member.
485 *
486 * @see optional, _Enable_special_members
487 */
488 template<typename _Tp,
489 bool = is_trivially_copy_constructible_v<_Tp>,
490 bool = is_trivially_move_constructible_v<_Tp>>
491 struct _Optional_base
492 {
493 // Constructors for disengaged optionals.
494 constexpr _Optional_base() = default;
495
496 // Constructors for engaged optionals.
497 template<typename... _Args,
498 enable_if_t<is_constructible_v<_Tp, _Args...>, bool> = false>
499 constexpr explicit
500 _Optional_base(in_place_t, _Args&&... __args)
501 : _M_payload(in_place, std::forward<_Args>(__args)...)
502 { }
503
504 template<typename _Up, typename... _Args,
505 enable_if_t<is_constructible_v<_Tp,
506 initializer_list<_Up>&,
507 _Args...>, bool> = false>
508 constexpr explicit
509 _Optional_base(in_place_t,
510 initializer_list<_Up> __il,
511 _Args&&... __args)
512 : _M_payload(in_place, __il, std::forward<_Args>(__args)...)
513 { }
514
515 // Copy and move constructors.
516 constexpr
517 _Optional_base(const _Optional_base& __other)
518 noexcept(is_nothrow_copy_constructible_v<_Tp>)
519 : _M_payload(__other._M_payload._M_engaged, __other._M_payload)
520 { }
521
522 constexpr
523 _Optional_base(_Optional_base&& __other)
524 noexcept(is_nothrow_move_constructible_v<_Tp>)
525 : _M_payload(__other._M_payload._M_engaged,
526 std::move(__other._M_payload))
527 { }
528
529#if __cpp_concepts >= 202002L // Conditionally trivial special member functions
530 // Define these in the primary template if possible, so that we don't
531 // need to use partial specializations of this class template.
532 constexpr _Optional_base(const _Optional_base&)
533 requires is_trivially_copy_constructible_v<_Tp> = default;
534
535 constexpr _Optional_base(_Optional_base&&)
536 requires is_trivially_move_constructible_v<_Tp> = default;
537#endif
538
539 // Assignment operators.
540 _Optional_base& operator=(const _Optional_base&) = default;
541 _Optional_base& operator=(_Optional_base&&) = default;
542
543 _Optional_payload<_Tp> _M_payload;
544
545 protected:
546 // For the primary template, we define these functions here.
547 using _Stored_type = remove_const_t<_Tp>;
548
549 // The _M_construct operation has !_M_engaged as a precondition
550 // while _M_destruct has _M_engaged as a precondition.
551 template<typename... _Args>
552 constexpr void
553 _M_construct(_Args&&... __args)
554 noexcept(is_nothrow_constructible_v<_Stored_type, _Args...>)
555 {
556 _M_payload._M_construct(std::forward<_Args>(__args)...);
557 }
558
559 constexpr void
560 _M_destruct() noexcept
561 { _M_payload._M_destroy(); }
562
563 // _M_reset is a 'safe' operation with no precondition.
564 constexpr void
565 _M_reset() noexcept
566 { _M_payload._M_reset(); }
567
568 constexpr bool _M_is_engaged() const noexcept
569 { return _M_payload._M_engaged; }
570
571 // The _M_get operations have _M_engaged as a precondition.
572 constexpr _Tp&
573 _M_get() noexcept
574 { return _M_payload._M_get(); }
575
576 constexpr const _Tp&
577 _M_get() const noexcept
578 { return _M_payload._M_get(); }
579 };
580
581#if __cpp_concepts < 202002L
582 // If P0848R3 "Conditionally Trivial Special Member Functions" is not
583 // supported (as determined from the __cpp_concepts macro value), the
584 // _Optional_base primary template only has non-trivial copy and move
585 // constructors. Use partial specializations of _Optional_base<T, C, M>
586 // that have a trivial copy and/or move constructor.
587
588 // Common base class for _Optional_base<T> to avoid repeating these
589 // member functions in each partial specialization.
590 // Only used if P0848R3 "Conditionally Trivial Special Member Functions"
591 // is not supported, as indicated by the __cpp_concepts value.
592 template<typename _Tp, typename _Dp>
593 class _Optional_base_impl
594 {
595 protected:
596 using _Stored_type = remove_const_t<_Tp>;
597
598 // The _M_construct operation has !_M_engaged as a precondition
599 // while _M_destruct has _M_engaged as a precondition.
600 template<typename... _Args>
601 constexpr void
602 _M_construct(_Args&&... __args)
603 noexcept(is_nothrow_constructible_v<_Stored_type, _Args...>)
604 {
605 static_cast<_Dp*>(this)->_M_payload._M_construct(
606 std::forward<_Args>(__args)...);
607 }
608
609 constexpr void
610 _M_destruct() noexcept
611 { static_cast<_Dp*>(this)->_M_payload._M_destroy(); }
612
613 // _M_reset is a 'safe' operation with no precondition.
614 constexpr void
615 _M_reset() noexcept
616 { static_cast<_Dp*>(this)->_M_payload._M_reset(); }
617
618 constexpr bool _M_is_engaged() const noexcept
619 { return static_cast<const _Dp*>(this)->_M_payload._M_engaged; }
620
621 // The _M_get operations have _M_engaged as a precondition.
622 constexpr _Tp&
623 _M_get() noexcept
624 { return static_cast<_Dp*>(this)->_M_payload._M_get(); }
625
626 constexpr const _Tp&
627 _M_get() const noexcept
628 { return static_cast<const _Dp*>(this)->_M_payload._M_get(); }
629 };
630
631 template<typename _Tp>
632 struct _Optional_base<_Tp, false, true> // trivial move ctor
633 : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
634 {
635 // Constructors for disengaged optionals.
636 constexpr _Optional_base() = default;
637
638 // Constructors for engaged optionals.
639 template<typename... _Args,
640 enable_if_t<is_constructible_v<_Tp, _Args...>, bool> = false>
641 constexpr explicit
642 _Optional_base(in_place_t, _Args&&... __args)
643 : _M_payload(in_place, std::forward<_Args>(__args)...)
644 { }
645
646 template<typename _Up, typename... _Args,
647 enable_if_t<is_constructible_v<_Tp,
648 initializer_list<_Up>&,
649 _Args...>, bool> = false>
650 constexpr explicit
651 _Optional_base(in_place_t,
652 initializer_list<_Up> __il,
653 _Args... __args)
654 : _M_payload(in_place, __il, std::forward<_Args>(__args)...)
655 { }
656
657 // Copy and move constructors.
658 constexpr _Optional_base(const _Optional_base& __other)
659 : _M_payload(__other._M_payload._M_engaged, __other._M_payload)
660 { }
661
662 constexpr _Optional_base(_Optional_base&& __other) = default;
663
664 // Assignment operators.
665 _Optional_base& operator=(const _Optional_base&) = default;
666 _Optional_base& operator=(_Optional_base&&) = default;
667
668 _Optional_payload<_Tp> _M_payload;
669 };
670
671 template<typename _Tp>
672 struct _Optional_base<_Tp, true, false> // trivial copy ctor
673 : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
674 {
675 // Constructors for disengaged optionals.
676 constexpr _Optional_base() = default;
677
678 // Constructors for engaged optionals.
679 template<typename... _Args,
680 enable_if_t<is_constructible_v<_Tp, _Args...>, bool> = false>
681 constexpr explicit
682 _Optional_base(in_place_t, _Args&&... __args)
683 : _M_payload(in_place, std::forward<_Args>(__args)...)
684 { }
685
686 template<typename _Up, typename... _Args,
687 enable_if_t<is_constructible_v<_Tp,
689 _Args...>, bool> = false>
690 constexpr explicit
691 _Optional_base(in_place_t,
693 _Args&&... __args)
694 : _M_payload(in_place, __il, std::forward<_Args>(__args)...)
695 { }
696
697 // Copy and move constructors.
698 constexpr _Optional_base(const _Optional_base& __other) = default;
699
700 constexpr
701 _Optional_base(_Optional_base&& __other)
702 noexcept(is_nothrow_move_constructible_v<_Tp>)
703 : _M_payload(__other._M_payload._M_engaged,
704 std::move(__other._M_payload))
705 { }
706
707 // Assignment operators.
708 _Optional_base& operator=(const _Optional_base&) = default;
709 _Optional_base& operator=(_Optional_base&&) = default;
710
711 _Optional_payload<_Tp> _M_payload;
712 };
713
714 template<typename _Tp>
715 struct _Optional_base<_Tp, true, true> // trivial copy and move ctors
716 : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
717 {
718 // Constructors for disengaged optionals.
719 constexpr _Optional_base() = default;
720
721 // Constructors for engaged optionals.
722 template<typename... _Args,
723 enable_if_t<is_constructible_v<_Tp, _Args...>, bool> = false>
724 constexpr explicit
725 _Optional_base(in_place_t, _Args&&... __args)
726 : _M_payload(in_place, std::forward<_Args>(__args)...)
727 { }
728
729 template<typename _Up, typename... _Args,
730 enable_if_t<is_constructible_v<_Tp,
732 _Args...>, bool> = false>
733 constexpr explicit
734 _Optional_base(in_place_t,
736 _Args&&... __args)
737 : _M_payload(in_place, __il, std::forward<_Args>(__args)...)
738 { }
739
740 // Copy and move constructors.
741 constexpr _Optional_base(const _Optional_base& __other) = default;
742 constexpr _Optional_base(_Optional_base&& __other) = default;
743
744 // Assignment operators.
745 _Optional_base& operator=(const _Optional_base&) = default;
746 _Optional_base& operator=(_Optional_base&&) = default;
747
748 _Optional_payload<_Tp> _M_payload;
749 };
750#endif // __cpp_concepts
751
752 template<typename _Tp>
753 inline constexpr bool __is_optional_v = false;
754 template<typename _Tp>
755 inline constexpr bool __is_optional_v<optional<_Tp>> = true;
756
757 template<typename _Tp, typename _Wp>
758 using __converts_from_any_cvref = __or_<
759 is_constructible<_Tp, _Wp&>, is_convertible<_Wp&, _Tp>,
760 is_constructible<_Tp, _Wp>, is_convertible<_Wp, _Tp>,
761 is_constructible<_Tp, const _Wp&>, is_convertible<const _Wp&, _Tp>,
762 is_constructible<_Tp, const _Wp>, is_convertible<const _Wp, _Tp>
763 >;
764
765 template<typename _Tp, typename _Up>
766 using __converts_from_optional
767 = __converts_from_any_cvref<_Tp, optional<_Up>>;
768
769 template<typename _Tp, typename _Up>
770 using __assigns_from_optional =
771 __or_<is_assignable<_Tp&, const optional<_Up>&>,
775
776#if __cpp_concepts && __cpp_conditional_explicit && __glibcxx_remove_cvref
777# define _GLIBCXX_USE_CONSTRAINTS_FOR_OPTIONAL 1
778#endif
779
780 /**
781 * @brief Class template for optional values.
782 */
783 template<typename _Tp>
784 class optional
785 : private _Optional_base<_Tp>,
786 private _Enable_copy_move<
787 // Copy constructor.
788 is_copy_constructible_v<_Tp>,
789 // Copy assignment.
790 __and_v<is_copy_constructible<_Tp>, is_copy_assignable<_Tp>>,
791 // Move constructor.
792 is_move_constructible_v<_Tp>,
793 // Move assignment.
794 __and_v<is_move_constructible<_Tp>, is_move_assignable<_Tp>>,
795 // Unique tag type.
796 optional<_Tp>>
797 {
798 static_assert(__is_valid_contained_type_for_optional<_Tp>);
799
800 private:
801 using _Base = _Optional_base<_Tp>;
802
803 // SFINAE helpers
804
805 // _GLIBCXX_RESOLVE_LIB_DEFECTS
806 // 3836. std::expected<bool, E1> conversion constructor
807 // expected(const expected<U, G>&) should take precedence over
808 // expected(U&&) with operator bool
809#ifdef _GLIBCXX_USE_CONSTRAINTS_FOR_OPTIONAL
810 template<typename _From, typename = remove_cv_t<_Tp>>
811 static constexpr bool __not_constructing_bool_from_optional
812 = true;
813
814 // If T is cv bool, remove_cvref_t<U> is not a specialization of optional
815 // i.e. do not initialize a bool from optional<U>::operator bool().
816 template<typename _From>
817 static constexpr bool
818 __not_constructing_bool_from_optional<_From, bool>
819 = !__is_optional_v<remove_cvref_t<_From>>;
820
821 // If T is not cv bool, converts-from-any-cvref<T, optional<U>> is false.
822 // The constructor that converts from optional<U> is disabled if the
823 // contained value can be initialized from optional<U>, so that the
824 // optional(U&&) constructor can be used instead.
825 template<typename _From, typename = remove_cv_t<_Tp>>
826 static constexpr bool __construct_from_contained_value
827 = !__converts_from_optional<_Tp, _From>::value;
828
829 // However, optional<U> can always be converted to bool, so don't apply
830 // this constraint when T is cv bool.
831 template<typename _From>
832 static constexpr bool __construct_from_contained_value<_From, bool>
833 = true;
834#else
835 template<typename _From, typename = remove_cv_t<_Tp>>
836 struct __not_constructing_bool_from_optional
837 : true_type
838 { };
839
840 template<typename _From>
841 struct __not_constructing_bool_from_optional<_From, bool>
842 : bool_constant<!__is_optional_v<__remove_cvref_t<_From>>>
843 { };
844
845 template<typename _From, typename = remove_cv_t<_Tp>>
846 struct __construct_from_contained_value
847 : __not_<__converts_from_optional<_Tp, _From>>
848 { };
849
850 template<typename _From>
851 struct __construct_from_contained_value<_From, bool>
852 : true_type
853 { };
854
855 template<typename _Up>
856 using __not_self = __not_<is_same<optional, __remove_cvref_t<_Up>>>;
857 template<typename _Up>
858 using __not_tag = __not_<is_same<in_place_t, __remove_cvref_t<_Up>>>;
859 template<typename... _Cond>
860 using _Requires = enable_if_t<__and_v<_Cond...>, bool>;
861#endif
862
863 public:
864 using value_type = _Tp;
865#ifdef __cpp_lib_optional_range_support // >= C++26
866 using iterator = __gnu_cxx::__normal_iterator<_Tp*, optional>;
867 using const_iterator = __gnu_cxx::__normal_iterator<const _Tp*, optional>;
868#endif
869
870 constexpr optional() noexcept { }
871
872 constexpr optional(nullopt_t) noexcept { }
873
874 // Converting constructors for engaged optionals.
875#ifdef _GLIBCXX_USE_CONSTRAINTS_FOR_OPTIONAL
876 template<typename _Up = remove_cv_t<_Tp>>
877 requires (!is_same_v<optional, remove_cvref_t<_Up>>)
878 && (!is_same_v<in_place_t, remove_cvref_t<_Up>>)
879 && is_constructible_v<_Tp, _Up>
880 && __not_constructing_bool_from_optional<_Up>
881 constexpr explicit(!is_convertible_v<_Up, _Tp>)
882 optional(_Up&& __t)
883 noexcept(is_nothrow_constructible_v<_Tp, _Up>)
884 : _Base(std::in_place, std::forward<_Up>(__t)) { }
885
886 template<typename _Up>
887 requires (!is_same_v<_Tp, _Up>)
888 && is_constructible_v<_Tp, const _Up&>
889 && __construct_from_contained_value<_Up>
890 constexpr explicit(!is_convertible_v<const _Up&, _Tp>)
891 optional(const optional<_Up>& __t)
892 noexcept(is_nothrow_constructible_v<_Tp, const _Up&>)
893 {
894 if (__t)
895 emplace(__t._M_fwd());
896 }
897
898 template<typename _Up>
899 requires (!is_same_v<_Tp, _Up>)
900 && is_constructible_v<_Tp, _Up>
901 && __construct_from_contained_value<_Up>
902 constexpr explicit(!is_convertible_v<_Up, _Tp>)
903 optional(optional<_Up>&& __t)
904 noexcept(is_nothrow_constructible_v<_Tp, _Up>)
905 {
906 if (__t)
907 emplace(std::move(__t)._M_fwd());
908 }
909
910 template<typename... _Args>
911 requires is_constructible_v<_Tp, _Args...>
912 explicit constexpr
913 optional(in_place_t, _Args&&... __args)
914 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
915 : _Base(std::in_place, std::forward<_Args>(__args)...)
916 { }
917
918 template<typename _Up, typename... _Args>
919 requires is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>
920 explicit constexpr
921 optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
922 noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&,
923 _Args...>)
924 : _Base(std::in_place, __il, std::forward<_Args>(__args)...)
925 { }
926#else
927 template<typename _Up = remove_cv_t<_Tp>,
928 _Requires<__not_self<_Up>, __not_tag<_Up>,
929 is_constructible<_Tp, _Up>,
930 is_convertible<_Up, _Tp>,
931 __not_constructing_bool_from_optional<_Up>> = true>
932 constexpr
933 optional(_Up&& __t)
934 noexcept(is_nothrow_constructible_v<_Tp, _Up>)
935 : _Base(std::in_place, std::forward<_Up>(__t)) { }
936
937 template<typename _Up = remove_cv_t<_Tp>,
938 _Requires<__not_self<_Up>, __not_tag<_Up>,
939 is_constructible<_Tp, _Up>,
940 __not_<is_convertible<_Up, _Tp>>,
941 __not_constructing_bool_from_optional<_Up>> = false>
942 explicit constexpr
943 optional(_Up&& __t)
944 noexcept(is_nothrow_constructible_v<_Tp, _Up>)
945 : _Base(std::in_place, std::forward<_Up>(__t)) { }
946
947 template<typename _Up,
948 _Requires<__not_<is_same<_Tp, _Up>>,
949 is_constructible<_Tp, const _Up&>,
950 is_convertible<const _Up&, _Tp>,
951 __construct_from_contained_value<_Up>> = true>
952 constexpr
953 optional(const optional<_Up>& __t)
954 noexcept(is_nothrow_constructible_v<_Tp, const _Up&>)
955 {
956 if (__t)
957 emplace(__t._M_fwd());
958 }
959
960 template<typename _Up,
961 _Requires<__not_<is_same<_Tp, _Up>>,
962 is_constructible<_Tp, const _Up&>,
963 __not_<is_convertible<const _Up&, _Tp>>,
964 __construct_from_contained_value<_Up>> = false>
965 explicit constexpr
966 optional(const optional<_Up>& __t)
967 noexcept(is_nothrow_constructible_v<_Tp, const _Up&>)
968 {
969 if (__t)
970 emplace(__t._M_fwd());
971 }
972
973 template<typename _Up,
974 _Requires<__not_<is_same<_Tp, _Up>>,
975 is_constructible<_Tp, _Up>,
976 is_convertible<_Up, _Tp>,
977 __construct_from_contained_value<_Up>> = true>
978 constexpr
979 optional(optional<_Up>&& __t)
980 noexcept(is_nothrow_constructible_v<_Tp, _Up>)
981 {
982 if (__t)
983 emplace(std::move(__t)._M_fwd());
984 }
985
986 template<typename _Up,
987 _Requires<__not_<is_same<_Tp, _Up>>,
988 is_constructible<_Tp, _Up>,
989 __not_<is_convertible<_Up, _Tp>>,
990 __construct_from_contained_value<_Up>> = false>
991 explicit constexpr
992 optional(optional<_Up>&& __t)
993 noexcept(is_nothrow_constructible_v<_Tp, _Up>)
994 {
995 if (__t)
996 emplace(std::move(__t)._M_fwd());
997 }
998
999 template<typename... _Args,
1000 _Requires<is_constructible<_Tp, _Args...>> = false>
1001 explicit constexpr
1002 optional(in_place_t, _Args&&... __args)
1003 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
1004 : _Base(std::in_place, std::forward<_Args>(__args)...) { }
1005
1006 template<typename _Up, typename... _Args,
1007 _Requires<is_constructible<_Tp,
1008 initializer_list<_Up>&,
1009 _Args...>> = false>
1010 explicit constexpr
1011 optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
1012 noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&,
1013 _Args...>)
1014 : _Base(std::in_place, __il, std::forward<_Args>(__args)...) { }
1015#endif
1016
1017 // Assignment operators.
1018 _GLIBCXX20_CONSTEXPR optional&
1019 operator=(nullopt_t) noexcept
1020 {
1021 this->_M_reset();
1022 return *this;
1023 }
1024
1025 template<typename _Up = remove_cv_t<_Tp>>
1026#ifdef _GLIBCXX_USE_CONSTRAINTS_FOR_OPTIONAL
1027 requires (!is_same_v<optional, remove_cvref_t<_Up>>)
1028 && (!(is_scalar_v<_Tp> && is_same_v<_Tp, decay_t<_Up>>))
1029 && is_constructible_v<_Tp, _Up>
1030 && is_assignable_v<_Tp&, _Up>
1031 constexpr optional&
1032#else
1034 __not_<__and_<is_scalar<_Tp>,
1035 is_same<_Tp, decay_t<_Up>>>>,
1036 is_constructible<_Tp, _Up>,
1037 is_assignable<_Tp&, _Up>>,
1038 optional&>
1039#endif
1040 operator=(_Up&& __u)
1041 noexcept(__and_v<is_nothrow_constructible<_Tp, _Up>,
1042 is_nothrow_assignable<_Tp&, _Up>>)
1043 {
1044 if (this->_M_is_engaged())
1045 this->_M_get() = std::forward<_Up>(__u);
1046 else
1047 this->_M_construct(std::forward<_Up>(__u));
1048
1049 return *this;
1050 }
1051
1052 template<typename _Up>
1053#ifdef _GLIBCXX_USE_CONSTRAINTS_FOR_OPTIONAL
1054 requires (!is_same_v<_Tp, _Up>)
1055 && is_constructible_v<_Tp, const _Up&>
1056 && is_assignable_v<_Tp&, const _Up&>
1057 && (!__converts_from_optional<_Tp, _Up>::value)
1058 && (!__assigns_from_optional<_Tp, _Up>::value)
1059 constexpr optional&
1060#else
1061 enable_if_t<__and_v<__not_<is_same<_Tp, _Up>>,
1062 is_constructible<_Tp, const _Up&>,
1063 is_assignable<_Tp&, const _Up&>,
1064 __not_<__converts_from_optional<_Tp, _Up>>,
1065 __not_<__assigns_from_optional<_Tp, _Up>>>,
1066 optional&>
1067#endif
1068 operator=(const optional<_Up>& __u)
1069 noexcept(__and_v<is_nothrow_constructible<_Tp, const _Up&>,
1070 is_nothrow_assignable<_Tp&, const _Up&>>)
1071 {
1072 if (__u)
1073 {
1074 if (this->_M_is_engaged())
1075 this->_M_get() = __u._M_fwd();
1076 else
1077 this->_M_construct(__u._M_fwd());
1078 }
1079 else
1080 {
1081 this->_M_reset();
1082 }
1083 return *this;
1084 }
1085
1086 template<typename _Up>
1087#ifdef _GLIBCXX_USE_CONSTRAINTS_FOR_OPTIONAL
1088 requires (!is_same_v<_Tp, _Up>)
1089 && is_constructible_v<_Tp, _Up>
1090 && is_assignable_v<_Tp&, _Up>
1091 && (!__converts_from_optional<_Tp, _Up>::value)
1092 && (!__assigns_from_optional<_Tp, _Up>::value)
1093 constexpr optional&
1094#else
1095 enable_if_t<__and_v<__not_<is_same<_Tp, _Up>>,
1096 is_constructible<_Tp, _Up>,
1097 is_assignable<_Tp&, _Up>,
1098 __not_<__converts_from_optional<_Tp, _Up>>,
1099 __not_<__assigns_from_optional<_Tp, _Up>>>,
1100 optional&>
1101#endif
1102 operator=(optional<_Up>&& __u)
1103 noexcept(__and_v<is_nothrow_constructible<_Tp, _Up>,
1104 is_nothrow_assignable<_Tp&, _Up>>)
1105 {
1106 if (__u)
1107 {
1108 if (this->_M_is_engaged())
1109 this->_M_get() = std::move(__u)._M_fwd();
1110 else
1111 this->_M_construct(std::move(__u)._M_fwd());
1112 }
1113 else
1114 {
1115 this->_M_reset();
1116 }
1117
1118 return *this;
1119 }
1120
1121 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1122 // 2746. Inconsistency between requirements for emplace between optional and variant
1123 template<typename... _Args>
1124 _GLIBCXX20_CONSTEXPR
1125 enable_if_t<is_constructible_v<_Tp, _Args...>, _Tp&>
1126 emplace(_Args&&... __args)
1127 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
1128 {
1129 this->_M_reset();
1130 this->_M_construct(std::forward<_Args>(__args)...);
1131 return this->_M_get();
1132 }
1133
1134 template<typename _Up, typename... _Args>
1135 _GLIBCXX20_CONSTEXPR
1137 _Tp&>
1138 emplace(initializer_list<_Up> __il, _Args&&... __args)
1139 noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&,
1140 _Args...>)
1141 {
1142 this->_M_reset();
1143 this->_M_construct(__il, std::forward<_Args>(__args)...);
1144 return this->_M_get();
1145 }
1146
1147 // Destructor is implicit, implemented in _Optional_base.
1148
1149 // Swap.
1150 _GLIBCXX20_CONSTEXPR void
1151 swap(optional& __other)
1152 noexcept(is_nothrow_move_constructible_v<_Tp>
1153 && is_nothrow_swappable_v<_Tp>)
1154 {
1155 using std::swap;
1156
1157 if (this->_M_is_engaged() && __other._M_is_engaged())
1158 swap(this->_M_get(), __other._M_get());
1159 else if (this->_M_is_engaged())
1160 {
1161 __other._M_construct(std::move(this->_M_get()));
1162 this->_M_destruct();
1163 }
1164 else if (__other._M_is_engaged())
1165 {
1166 this->_M_construct(std::move(__other._M_get()));
1167 __other._M_destruct();
1168 }
1169 }
1170
1171#ifdef __cpp_lib_optional_range_support // >= C++26
1172 // Iterator support.
1173 constexpr iterator begin() noexcept
1174 {
1175 return iterator(
1176 this->_M_is_engaged() ? std::addressof(this->_M_get()) : nullptr
1177 );
1178 }
1179
1180 constexpr const_iterator begin() const noexcept
1181 {
1182 return const_iterator(
1183 this->_M_is_engaged() ? std::addressof(this->_M_get()) : nullptr
1184 );
1185 }
1186
1187 constexpr iterator end() noexcept
1188 {
1189 return begin() + has_value();
1190 }
1191
1192 constexpr const_iterator end() const noexcept
1193 {
1194 return begin() + has_value();
1195 }
1196#endif // __cpp_lib_optional_range_support
1197
1198 // Observers.
1199 constexpr const _Tp*
1200 operator->() const noexcept
1201 {
1202 __glibcxx_assert(this->_M_is_engaged());
1203 return std::__addressof(this->_M_get());
1204 }
1205
1206 constexpr _Tp*
1207 operator->() noexcept
1208 {
1209 __glibcxx_assert(this->_M_is_engaged());
1210 return std::__addressof(this->_M_get());
1211 }
1212
1213 constexpr const _Tp&
1214 operator*() const& noexcept
1215 {
1216 __glibcxx_assert(this->_M_is_engaged());
1217 return this->_M_get();
1218 }
1219
1220 constexpr _Tp&
1221 operator*()& noexcept
1222 {
1223 __glibcxx_assert(this->_M_is_engaged());
1224 return this->_M_get();
1225 }
1226
1227 constexpr _Tp&&
1228 operator*()&& noexcept
1229 {
1230 __glibcxx_assert(this->_M_is_engaged());
1231 return std::move(this->_M_get());
1232 }
1233
1234 constexpr const _Tp&&
1235 operator*() const&& noexcept
1236 {
1237 __glibcxx_assert(this->_M_is_engaged());
1238 return std::move(this->_M_get());
1239 }
1240
1241 constexpr explicit operator bool() const noexcept
1242 { return this->_M_is_engaged(); }
1243
1244 constexpr bool has_value() const noexcept
1245 { return this->_M_is_engaged(); }
1246
1247 constexpr const _Tp&
1248 value() const&
1249 {
1250 if (this->_M_is_engaged())
1251 return this->_M_get();
1252 __throw_bad_optional_access();
1253 }
1254
1255 constexpr _Tp&
1256 value()&
1257 {
1258 if (this->_M_is_engaged())
1259 return this->_M_get();
1260 __throw_bad_optional_access();
1261 }
1262
1263 constexpr _Tp&&
1264 value()&&
1265 {
1266 if (this->_M_is_engaged())
1267 return std::move(this->_M_get());
1268 __throw_bad_optional_access();
1269 }
1270
1271 constexpr const _Tp&&
1272 value() const&&
1273 {
1274 if (this->_M_is_engaged())
1275 return std::move(this->_M_get());
1276 __throw_bad_optional_access();
1277 }
1278
1279 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1280 // 4406. value_or return statement is inconsistent with Mandates
1281 template<typename _Up = remove_cv_t<_Tp>>
1282 constexpr remove_cv_t<_Tp>
1283 value_or(_Up&& __u) const&
1284 {
1285 using _Xp = remove_cv_t<_Tp>;
1286 static_assert(is_convertible_v<const _Tp&, _Xp>);
1287 static_assert(is_convertible_v<_Up, _Xp>);
1288
1289 if (this->_M_is_engaged())
1290 return this->_M_get();
1291 return std::forward<_Up>(__u);
1292 }
1293
1294 template<typename _Up = remove_cv_t<_Tp>>
1295 constexpr remove_cv_t<_Tp>
1296 value_or(_Up&& __u) &&
1297 {
1298 using _Xp = remove_cv_t<_Tp>;
1299 static_assert(is_convertible_v<_Tp, _Xp>);
1300 static_assert(is_convertible_v<_Up, _Xp>);
1301
1302 if (this->_M_is_engaged())
1303 return std::move(this->_M_get());
1304 return std::forward<_Up>(__u);
1305 }
1306
1307#if __cpp_lib_optional >= 202110L // C++23
1308 // [optional.monadic]
1309
1310 template<typename _Fn>
1311 constexpr auto
1312 and_then(_Fn&& __f) &
1313 {
1314 using _Up = remove_cvref_t<invoke_result_t<_Fn, _Tp&>>;
1315 static_assert(__is_optional_v<_Up>,
1316 "the function passed to std::optional<T>::and_then "
1317 "must return a std::optional");
1318 if (has_value())
1319 return std::__invoke(std::forward<_Fn>(__f), _M_get());
1320 else
1321 return _Up();
1322 }
1323
1324 template<typename _Fn>
1325 constexpr auto
1326 and_then(_Fn&& __f) const &
1327 {
1328 using _Up = remove_cvref_t<invoke_result_t<_Fn, const _Tp&>>;
1329 static_assert(__is_optional_v<_Up>,
1330 "the function passed to std::optional<T>::and_then "
1331 "must return a std::optional");
1332 if (has_value())
1333 return std::__invoke(std::forward<_Fn>(__f), _M_get());
1334 else
1335 return _Up();
1336 }
1337
1338 template<typename _Fn>
1339 constexpr auto
1340 and_then(_Fn&& __f) &&
1341 {
1342 using _Up = remove_cvref_t<invoke_result_t<_Fn, _Tp>>;
1343 static_assert(__is_optional_v<_Up>,
1344 "the function passed to std::optional<T>::and_then "
1345 "must return a std::optional");
1346 if (has_value())
1347 return std::__invoke(std::forward<_Fn>(__f), std::move(_M_get()));
1348 else
1349 return _Up();
1350 }
1351
1352 template<typename _Fn>
1353 constexpr auto
1354 and_then(_Fn&& __f) const &&
1355 {
1356 using _Up = remove_cvref_t<invoke_result_t<_Fn, const _Tp>>;
1357 static_assert(__is_optional_v<_Up>,
1358 "the function passed to std::optional<T>::and_then "
1359 "must return a std::optional");
1360 if (has_value())
1361 return std::__invoke(std::forward<_Fn>(__f), std::move(_M_get()));
1362 else
1363 return _Up();
1364 }
1365
1366 template<typename _Fn>
1367 constexpr auto
1368 transform(_Fn&& __f) &
1369 {
1370 using _Up = remove_cv_t<invoke_result_t<_Fn, _Tp&>>;
1371 if (has_value())
1372 return optional<_Up>(_Optional_func<_Fn>{__f}, _M_get());
1373 else
1374 return optional<_Up>();
1375 }
1376
1377 template<typename _Fn>
1378 constexpr auto
1379 transform(_Fn&& __f) const &
1380 {
1381 using _Up = remove_cv_t<invoke_result_t<_Fn, const _Tp&>>;
1382 if (has_value())
1383 return optional<_Up>(_Optional_func<_Fn>{__f}, _M_get());
1384 else
1385 return optional<_Up>();
1386 }
1387
1388 template<typename _Fn>
1389 constexpr auto
1390 transform(_Fn&& __f) &&
1391 {
1392 using _Up = remove_cv_t<invoke_result_t<_Fn, _Tp>>;
1393 if (has_value())
1394 return optional<_Up>(_Optional_func<_Fn>{__f}, std::move(_M_get()));
1395 else
1396 return optional<_Up>();
1397 }
1398
1399 template<typename _Fn>
1400 constexpr auto
1401 transform(_Fn&& __f) const &&
1402 {
1403 using _Up = remove_cv_t<invoke_result_t<_Fn, const _Tp>>;
1404 if (has_value())
1405 return optional<_Up>(_Optional_func<_Fn>{__f}, std::move(_M_get()));
1406 else
1407 return optional<_Up>();
1408 }
1409
1410 template<typename _Fn> requires invocable<_Fn> && copy_constructible<_Tp>
1411 constexpr optional
1412 or_else(_Fn&& __f) const&
1413 {
1414 using _Up = invoke_result_t<_Fn>;
1415 static_assert(is_same_v<remove_cvref_t<_Up>, optional>,
1416 "the function passed to std::optional<T>::or_else "
1417 "must return a std::optional<T>");
1418
1419 if (has_value())
1420 return *this;
1421 else
1422 return std::forward<_Fn>(__f)();
1423 }
1424
1425 template<typename _Fn> requires invocable<_Fn> && move_constructible<_Tp>
1426 constexpr optional
1427 or_else(_Fn&& __f) &&
1428 {
1429 using _Up = invoke_result_t<_Fn>;
1430 static_assert(is_same_v<remove_cvref_t<_Up>, optional>,
1431 "the function passed to std::optional<T>::or_else "
1432 "must return a std::optional<T>");
1433
1434 if (has_value())
1435 return std::move(*this);
1436 else
1437 return std::forward<_Fn>(__f)();
1438 }
1439#endif
1440
1441 _GLIBCXX20_CONSTEXPR void reset() noexcept { this->_M_reset(); }
1442
1443 private:
1444 using _Base::_M_get;
1445
1446 [[__gnu__::__always_inline__]]
1447 constexpr _Tp&
1448 _M_fwd() & noexcept
1449 { return _M_get(); }
1450
1451 [[__gnu__::__always_inline__]]
1452 constexpr _Tp&&
1453 _M_fwd() && noexcept
1454 { return std::move(_M_get()); }
1455
1456 [[__gnu__::__always_inline__]]
1457 constexpr const _Tp&
1458 _M_fwd() const& noexcept
1459 { return _M_get(); }
1460
1461 [[__gnu__::__always_inline__]]
1462 constexpr const _Tp&&
1463 _M_fwd() const&& noexcept
1464 { return std::move(_M_get()); }
1465
1466 template<typename _Up> friend class optional;
1467
1468#if __cpp_lib_optional >= 202110L // C++23
1469 template<typename _Fn, typename _Value>
1470 explicit constexpr
1471 optional(_Optional_func<_Fn> __f, _Value&& __v)
1472 {
1473 this->_M_payload._M_apply(__f, std::forward<_Value>(__v));
1474 }
1475#endif
1476 };
1477
1478#if __cpp_lib_optional >= 202506L // C++26
1479#ifdef __cpp_lib_optional_range_support
1480 template<typename _Tp>
1481 constexpr auto
1482 optional<_Tp&>::begin() const noexcept
1483 requires is_object_v<_Tp> && (!is_unbounded_array_v<_Tp>)
1484 { return __gnu_cxx::__normal_iterator<_Tp*, optional>(_M_val); }
1485
1486 template<typename _Tp>
1487 constexpr auto
1488 optional<_Tp&>::end() const noexcept
1489 requires is_object_v<_Tp> && (!is_unbounded_array_v<_Tp>)
1490 { return begin() + has_value(); }
1491#endif // __cpp_lib_optional_range_support
1492
1493 template<typename _Tp>
1494 constexpr _Tp&
1495 optional<_Tp&>::value() const
1496 {
1497 if (_M_val)
1498 return *_M_val;
1499 __throw_bad_optional_access();
1500 }
1501
1502 template<typename _Tp>
1503 template<typename _Up>
1504 requires is_object_v<_Tp> && (!is_array_v<_Tp>)
1505 constexpr decay_t<_Tp>
1506 optional<_Tp&>::value_or(_Up&& __u) const
1507 {
1508 using _Xp = remove_cv_t<_Tp>;
1509 static_assert(is_convertible_v<_Tp&, _Xp>);
1510 static_assert(is_convertible_v<_Up, _Xp>);
1511 if (_M_val)
1512 return *_M_val;
1513 return std::forward<_Up>(__u);
1514 }
1515
1516 template<typename _Tp>
1517 template<typename _Fn>
1518 constexpr auto
1519 optional<_Tp&>::and_then(_Fn&& __f) const
1520 {
1521 using _Up = remove_cvref_t<invoke_result_t<_Fn, _Tp&>>;
1522 static_assert(__is_optional_v<_Up>,
1523 "the function passed to std::optional<T&>::and_then "
1524 "must return a std::optional");
1525 if (has_value())
1526 return std::__invoke(std::forward<_Fn>(__f), *_M_val);
1527 else
1528 return _Up();
1529 }
1530
1531 template<typename _Tp>
1532 template<typename _Fn>
1533 constexpr optional<remove_cv_t<invoke_result_t<_Fn, _Tp&>>>
1534 optional<_Tp&>::transform(_Fn&& __f) const
1535 {
1536 using _Up = remove_cv_t<invoke_result_t<_Fn, _Tp&>>;
1537 if (has_value())
1538 return optional<_Up>(_Optional_func<_Fn>{__f}, *_M_val);
1539 else
1540 return optional<_Up>();
1541 }
1542
1543 template<typename _Tp>
1544 template<typename _Fn>
1545 requires is_invocable_v<_Fn>
1546 constexpr optional<_Tp&>
1547 optional<_Tp&>::or_else(_Fn&& __f) const
1548 {
1549 static_assert(is_same_v<remove_cvref_t<invoke_result_t<_Fn>>, optional>,
1550 "the function passed to std::optional<T&>::or_else "
1551 "must return a std::optional<T&>");
1552 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1553 // 4367. Improve optional<T&>::or_else
1554 if (has_value())
1555 return *this;
1556 else
1557 return std::forward<_Fn>(__f)();
1558 }
1559
1560 template<typename _Tp>
1561 template<typename _Fn, typename _Value>
1562 constexpr
1563 optional<_Tp&>::optional(_Optional_func<_Fn> __f, _Value&& __v)
1564 {
1565 _Tp& __r = std::__invoke(std::forward<_Fn>(__f._M_f), std::forward<_Value>(__v));
1566 _M_val = std::addressof(__r);
1567 }
1568#endif // __cpp_lib_optional >= 202506L
1569
1570 template<typename _Tp>
1571 using __optional_relop_t =
1573
1574 template<typename _Tp, typename _Up>
1575 using __optional_eq_t = __optional_relop_t<
1577 >;
1578
1579 template<typename _Tp, typename _Up>
1580 using __optional_ne_t = __optional_relop_t<
1582 >;
1583
1584 template<typename _Tp, typename _Up>
1585 using __optional_lt_t = __optional_relop_t<
1587 >;
1588
1589 template<typename _Tp, typename _Up>
1590 using __optional_gt_t = __optional_relop_t<
1592 >;
1593
1594 template<typename _Tp, typename _Up>
1595 using __optional_le_t = __optional_relop_t<
1597 >;
1598
1599 template<typename _Tp, typename _Up>
1600 using __optional_ge_t = __optional_relop_t<
1602 >;
1603
1604 // Comparisons between optional values.
1605 template<typename _Tp, typename _Up>
1606 constexpr auto
1607 operator==(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1608 -> __optional_eq_t<_Tp, _Up>
1609 {
1610 if (__lhs.has_value() != __rhs.has_value())
1611 return false;
1612 if (!__lhs.has_value())
1613 return true;
1614 return *__lhs == *__rhs;
1615 }
1616
1617 template<typename _Tp, typename _Up>
1618 constexpr auto
1619 operator!=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1620 -> __optional_ne_t<_Tp, _Up>
1621 {
1622 if (__lhs.has_value() != __rhs.has_value())
1623 return true;
1624 if (!__lhs.has_value())
1625 return false;
1626 return *__lhs != *__rhs;
1627 }
1628
1629 template<typename _Tp, typename _Up>
1630 constexpr auto
1631 operator<(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1632 -> __optional_lt_t<_Tp, _Up>
1633 {
1634 if (!__rhs.has_value())
1635 return false;
1636 if (!__lhs.has_value())
1637 return true;
1638 return *__lhs < *__rhs;
1639 }
1640
1641 template<typename _Tp, typename _Up>
1642 constexpr auto
1643 operator>(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1644 -> __optional_gt_t<_Tp, _Up>
1645 {
1646 if (!__lhs.has_value())
1647 return false;
1648 if (!__rhs.has_value())
1649 return true;
1650 return *__lhs > *__rhs;
1651 }
1652
1653 template<typename _Tp, typename _Up>
1654 constexpr auto
1655 operator<=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1656 -> __optional_le_t<_Tp, _Up>
1657 {
1658 if (!__lhs.has_value())
1659 return true;
1660 if (!__rhs.has_value())
1661 return false;
1662 return *__lhs <= *__rhs;
1663 }
1664
1665 template<typename _Tp, typename _Up>
1666 constexpr auto
1667 operator>=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1668 -> __optional_ge_t<_Tp, _Up>
1669 {
1670 if (!__rhs.has_value())
1671 return true;
1672 if (!__lhs.has_value())
1673 return false;
1674 return *__lhs >= *__rhs;
1675 }
1676
1677#ifdef __cpp_lib_three_way_comparison
1678 template<typename _Tp, three_way_comparable_with<_Tp> _Up>
1679 [[nodiscard]]
1681 operator<=>(const optional<_Tp>& __x, const optional<_Up>& __y)
1682 {
1683 return __x && __y ? *__x <=> *__y : bool(__x) <=> bool(__y);
1684 }
1685#endif
1686
1687 // Comparisons with nullopt.
1688 template<typename _Tp>
1689 [[nodiscard]]
1690 constexpr bool
1691 operator==(const optional<_Tp>& __lhs, nullopt_t) noexcept
1692 { return !__lhs; }
1693
1694#ifdef __cpp_lib_three_way_comparison
1695 template<typename _Tp>
1696 [[nodiscard]]
1697 constexpr strong_ordering
1698 operator<=>(const optional<_Tp>& __x, nullopt_t) noexcept
1699 { return bool(__x) <=> false; }
1700#else
1701 template<typename _Tp>
1702 constexpr bool
1703 operator==(nullopt_t, const optional<_Tp>& __rhs) noexcept
1704 { return !__rhs; }
1705
1706 template<typename _Tp>
1707 constexpr bool
1708 operator!=(const optional<_Tp>& __lhs, nullopt_t) noexcept
1709 { return static_cast<bool>(__lhs); }
1710
1711 template<typename _Tp>
1712 constexpr bool
1713 operator!=(nullopt_t, const optional<_Tp>& __rhs) noexcept
1714 { return static_cast<bool>(__rhs); }
1715
1716 template<typename _Tp>
1717 constexpr bool
1718 operator<(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept
1719 { return false; }
1720
1721 template<typename _Tp>
1722 constexpr bool
1723 operator<(nullopt_t, const optional<_Tp>& __rhs) noexcept
1724 { return static_cast<bool>(__rhs); }
1725
1726 template<typename _Tp>
1727 constexpr bool
1728 operator>(const optional<_Tp>& __lhs, nullopt_t) noexcept
1729 { return static_cast<bool>(__lhs); }
1730
1731 template<typename _Tp>
1732 constexpr bool
1733 operator>(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept
1734 { return false; }
1735
1736 template<typename _Tp>
1737 constexpr bool
1738 operator<=(const optional<_Tp>& __lhs, nullopt_t) noexcept
1739 { return !__lhs; }
1740
1741 template<typename _Tp>
1742 constexpr bool
1743 operator<=(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept
1744 { return true; }
1745
1746 template<typename _Tp>
1747 constexpr bool
1748 operator>=(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept
1749 { return true; }
1750
1751 template<typename _Tp>
1752 constexpr bool
1753 operator>=(nullopt_t, const optional<_Tp>& __rhs) noexcept
1754 { return !__rhs; }
1755#endif // three-way-comparison
1756
1757#if __cpp_lib_concepts
1758 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1759 // 4072. std::optional comparisons: constrain harder
1760# define _REQUIRES_NOT_OPTIONAL(T) requires (!__is_optional_v<T>)
1761#else
1762# define _REQUIRES_NOT_OPTIONAL(T)
1763#endif
1764
1765 // Comparisons with value type.
1766 template<typename _Tp, typename _Up>
1767 _REQUIRES_NOT_OPTIONAL(_Up)
1768 constexpr auto
1769 operator== [[nodiscard]] (const optional<_Tp>& __lhs, const _Up& __rhs)
1770 -> __optional_eq_t<_Tp, _Up>
1771 {
1772 if (__lhs.has_value())
1773 return *__lhs == __rhs;
1774 return false;
1775 }
1776
1777 template<typename _Tp, typename _Up>
1778 _REQUIRES_NOT_OPTIONAL(_Tp)
1779 constexpr auto
1780 operator== [[nodiscard]] (const _Tp& __lhs, const optional<_Up>& __rhs)
1781 -> __optional_eq_t<_Tp, _Up>
1782 {
1783 if (__rhs.has_value())
1784 return __lhs == *__rhs;
1785 return false;
1786 }
1787
1788 template<typename _Tp, typename _Up>
1789 _REQUIRES_NOT_OPTIONAL(_Up)
1790 constexpr auto
1791 operator!= [[nodiscard]] (const optional<_Tp>& __lhs, const _Up& __rhs)
1792 -> __optional_ne_t<_Tp, _Up>
1793 {
1794 if (__lhs.has_value())
1795 return *__lhs != __rhs;
1796 return true;
1797 }
1798
1799 template<typename _Tp, typename _Up>
1800 _REQUIRES_NOT_OPTIONAL(_Tp)
1801 constexpr auto
1802 operator!= [[nodiscard]] (const _Tp& __lhs, const optional<_Up>& __rhs)
1803 -> __optional_ne_t<_Tp, _Up>
1804 {
1805 if (__rhs.has_value())
1806 return __lhs != *__rhs;
1807 return true;
1808 }
1809
1810 template<typename _Tp, typename _Up>
1811 _REQUIRES_NOT_OPTIONAL(_Up)
1812 constexpr auto
1813 operator< [[nodiscard]] (const optional<_Tp>& __lhs, const _Up& __rhs)
1814 -> __optional_lt_t<_Tp, _Up>
1815 {
1816 if (__lhs.has_value())
1817 return *__lhs < __rhs;
1818 return true;
1819 }
1820
1821 template<typename _Tp, typename _Up>
1822 _REQUIRES_NOT_OPTIONAL(_Tp)
1823 constexpr auto
1824 operator< [[nodiscard]] (const _Tp& __lhs, const optional<_Up>& __rhs)
1825 -> __optional_lt_t<_Tp, _Up>
1826 {
1827 if (__rhs.has_value())
1828 return __lhs < *__rhs;
1829 return false;
1830 }
1831
1832 template<typename _Tp, typename _Up>
1833 _REQUIRES_NOT_OPTIONAL(_Up)
1834 constexpr auto
1835 operator> [[nodiscard]] (const optional<_Tp>& __lhs, const _Up& __rhs)
1836 -> __optional_gt_t<_Tp, _Up>
1837 {
1838 if (__lhs.has_value())
1839 return *__lhs > __rhs;
1840 return false;
1841 }
1842
1843 template<typename _Tp, typename _Up>
1844 _REQUIRES_NOT_OPTIONAL(_Tp)
1845 constexpr auto
1846 operator> [[nodiscard]] (const _Tp& __lhs, const optional<_Up>& __rhs)
1847 -> __optional_gt_t<_Tp, _Up>
1848 {
1849 if (__rhs.has_value())
1850 return __lhs > *__rhs;
1851 return true;
1852 }
1853
1854 template<typename _Tp, typename _Up>
1855 _REQUIRES_NOT_OPTIONAL(_Up)
1856 constexpr auto
1857 operator<= [[nodiscard]] (const optional<_Tp>& __lhs, const _Up& __rhs)
1858 -> __optional_le_t<_Tp, _Up>
1859 {
1860 if (__lhs.has_value())
1861 return *__lhs <= __rhs;
1862 return true;
1863 }
1864
1865 template<typename _Tp, typename _Up>
1866 _REQUIRES_NOT_OPTIONAL(_Tp)
1867 constexpr auto
1868 operator<= [[nodiscard]] (const _Tp& __lhs, const optional<_Up>& __rhs)
1869 -> __optional_le_t<_Tp, _Up>
1870 {
1871 if (__rhs.has_value())
1872 return __lhs <= *__rhs;
1873 return false;
1874 }
1875
1876 template<typename _Tp, typename _Up>
1877 _REQUIRES_NOT_OPTIONAL(_Up)
1878 constexpr auto
1879 operator>= [[nodiscard]] (const optional<_Tp>& __lhs, const _Up& __rhs)
1880 -> __optional_ge_t<_Tp, _Up>
1881 {
1882 if (__lhs.has_value())
1883 return *__lhs >= __rhs;
1884 return false;
1885 }
1886
1887 template<typename _Tp, typename _Up>
1888 _REQUIRES_NOT_OPTIONAL(_Tp)
1889 constexpr auto
1890 operator>= [[nodiscard]] (const _Tp& __lhs, const optional<_Up>& __rhs)
1891 -> __optional_ge_t<_Tp, _Up>
1892 {
1893 if (__rhs.has_value())
1894 return __lhs >= *__rhs;
1895 return true;
1896 }
1897
1898#ifdef __cpp_lib_three_way_comparison
1899 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1900 // 3746. optional's spaceship with U with a type derived from optional
1901 // causes infinite constraint meta-recursion
1902 template<typename _Tp>
1903 concept __is_derived_from_optional = requires (const _Tp& __t) {
1904 []<typename _Up>(const optional<_Up>&){ }(__t);
1905 };
1906
1907 template<typename _Tp, typename _Up>
1908 requires (!__is_derived_from_optional<_Up>)
1909 && requires { typename compare_three_way_result_t<_Tp, _Up>; }
1910 && three_way_comparable_with<_Tp, _Up>
1912 operator<=> [[nodiscard]] (const optional<_Tp>& __x, const _Up& __v)
1913 { return bool(__x) ? *__x <=> __v : strong_ordering::less; }
1914#endif
1915
1916 // Swap and creation functions.
1917
1918 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1919 // 2748. swappable traits for optionals
1920 template<typename _Tp>
1921 _GLIBCXX20_CONSTEXPR
1922 inline enable_if_t<is_move_constructible_v<_Tp> && is_swappable_v<_Tp>>
1923 swap(optional<_Tp>& __lhs, optional<_Tp>& __rhs)
1924 noexcept(noexcept(__lhs.swap(__rhs)))
1925 { __lhs.swap(__rhs); }
1926
1927#if __cpp_lib_optional >= 202506L
1928 // We deviate from standard, that do not declared separate swap overload
1929 // from optional<T&>.
1930 template<typename _Tp>
1931 constexpr void
1932 swap(optional<_Tp&>& __lhs, optional<_Tp&>& __rhs) noexcept
1933 { __lhs.swap(__rhs); }
1934#endif
1935
1936 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1937 // 2766. Swapping non-swappable types
1938 template<typename _Tp>
1939 enable_if_t<!(is_move_constructible_v<_Tp> && is_swappable_v<_Tp>)>
1940 swap(optional<_Tp>&, optional<_Tp>&) = delete;
1941
1942#if __cpp_lib_optional >= 202506L
1943 template<int = 0, typename _Tp>
1944#else
1945 template<typename _Tp>
1946#endif
1947 constexpr
1949 optional<decay_t<_Tp>>>
1950 make_optional(_Tp&& __t)
1951 noexcept(is_nothrow_constructible_v<optional<decay_t<_Tp>>, _Tp>)
1952 { return optional<decay_t<_Tp>>( std::forward<_Tp>(__t) ); }
1953
1954 template<typename _Tp, typename... _Args>
1955 constexpr
1956 enable_if_t<is_constructible_v<_Tp, _Args...>,
1957 optional<_Tp>>
1958 make_optional(_Args&&... __args)
1959 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
1960 { return optional<_Tp>( in_place, std::forward<_Args>(__args)... ); }
1961
1962 template<typename _Tp, typename _Up, typename... _Args>
1963 constexpr
1965 optional<_Tp>>
1966 make_optional(initializer_list<_Up> __il, _Args&&... __args)
1967 noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, _Args...>)
1968 { return optional<_Tp>( in_place, __il, std::forward<_Args>(__args)... ); }
1969
1970 // Hash.
1971
1972 template<typename _Tp, typename _Up = remove_const_t<_Tp>>
1973 struct __optional_hash
1974#if ! _GLIBCXX_INLINE_VERSION
1975 : public __hash_empty_base<_Up>
1976#endif
1977 {
1978#if __cplusplus < 202002L
1979 using result_type [[__deprecated__]] = size_t;
1980 using argument_type [[__deprecated__]] = optional<_Tp>;
1981#endif
1982
1983 size_t
1984 operator()(const optional<_Tp>& __t) const
1985 noexcept(noexcept(hash<_Up>{}(*__t)))
1986 {
1987 // We pick an arbitrary hash for disengaged optionals which hopefully
1988 // usual values of _Tp won't typically hash to.
1989 constexpr size_t __magic_disengaged_hash = static_cast<size_t>(-3333);
1990 return __t ? hash<_Up>{}(*__t) : __magic_disengaged_hash;
1991 }
1992 };
1993
1994 template<typename _Tp>
1995 struct hash<optional<_Tp>>
1996 // hash for optional<T&> is disabled because is_hash_enabled_for<T&> is false
1997 : public __conditional_t<__is_hash_enabled_for<remove_const_t<_Tp>>,
1998 __optional_hash<_Tp>,
1999 __hash_not_enabled<_Tp>>
2000 { };
2001
2002 template<typename _Tp>
2003 struct __is_fast_hash<hash<optional<_Tp>>> : __is_fast_hash<hash<_Tp>>
2004 { };
2005
2006 /// @}
2007
2008#if __cpp_deduction_guides >= 201606
2009 template <typename _Tp> optional(_Tp) -> optional<_Tp>;
2010#endif
2011
2012#ifdef __cpp_lib_optional_range_support // >= C++26
2013 template<typename _Tp>
2014 inline constexpr bool
2016
2017#if __cpp_lib_optional >= 202506L // C++26
2018 template<typename _Tp>
2019 constexpr bool
2020 ranges::enable_borrowed_range<optional<_Tp&>> = true;
2021#endif
2022
2023#if _GLIBCXX_HOSTED
2024 template<typename _Tp>
2025 inline constexpr range_format
2026 format_kind<optional<_Tp>> = range_format::disabled;
2027#endif
2028#endif // __cpp_lib_optional_range_support
2029
2030#undef _GLIBCXX_USE_CONSTRAINTS_FOR_OPTIONAL
2031
2032_GLIBCXX_END_NAMESPACE_VERSION
2033} // namespace std
2034
2035#endif // __cpp_lib_optional
2036
2037#endif // _GLIBCXX_OPTIONAL
constexpr bool enable_view
[range.view] The ranges::enable_view boolean.
constexpr complex< _Tp > operator*(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x times y.
Definition complex:434
__bool_constant< true > true_type
The type used as a compile-time boolean with true value.
Definition type_traits:120
typename enable_if< _Cond, _Tp >::type enable_if_t
Alias template for enable_if.
Definition type_traits:2970
typename decay< _Tp >::type decay_t
Alias template for decay.
Definition type_traits:2966
auto declval() noexcept -> decltype(__declval< _Tp >(0))
Definition type_traits:2742
constexpr _Tp * addressof(_Tp &__r) noexcept
Returns the actual address of the object or function referenced by r, even in the presence of an over...
Definition move.h:176
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
Definition move.h:138
constexpr __invoke_result< _Callable, _Args... >::type __invoke(_Callable &&__fn, _Args &&... __args) noexcept(__is_nothrow_invocable< _Callable, _Args... >::value)
Invoke a callable object.
Definition invoke.h:92
constexpr _Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.
Definition move.h:52
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
Definition move.h:72
ISO C++ entities toplevel namespace is std.
constexpr auto end(_Container &__cont) noexcept(noexcept(__cont.end())) -> decltype(__cont.end())
Return an iterator pointing to one past the last element of the container.
typename __detail::__cmp3way_res_impl< _Tp, _Up >::type compare_three_way_result_t
[cmp.result], result of three-way comparison
Definition compare:547
constexpr void _Construct(_Tp *__p, _Args &&... __args)
constexpr auto begin(_Container &__cont) noexcept(noexcept(__cont.begin())) -> decltype(__cont.begin())
Return an iterator pointing to the first element of the container.
initializer_list
Primary class template hash.
is_constructible
Definition type_traits:1266
is_assignable
Definition type_traits:1385
Base class for all library exceptions.
Definition exception.h:62