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