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