libstdc++: optional Source File

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