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 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1289 // 4406. value_or return statement is inconsistent with Mandates
1290 template<typename _Up = remove_cv_t<_Tp>>
1291 constexpr remove_cv_t<_Tp>
1292 value_or(_Up&& __u) const&
1293 {
1294 using _Xp = remove_cv_t<_Tp>;
1295 static_assert(is_convertible_v<const _Tp&, _Xp>);
1296 static_assert(is_convertible_v<_Up, _Xp>);
1297
1298 if (this->_M_is_engaged())
1299 return this->_M_get();
1300 return std::forward<_Up>(__u);
1301 }
1302
1303 template<typename _Up = remove_cv_t<_Tp>>
1304 constexpr remove_cv_t<_Tp>
1305 value_or(_Up&& __u) &&
1306 {
1307 using _Xp = remove_cv_t<_Tp>;
1308 static_assert(is_convertible_v<_Tp, _Xp>);
1309 static_assert(is_convertible_v<_Up, _Xp>);
1310
1311 if (this->_M_is_engaged())
1312 return std::move(this->_M_get());
1313 return std::forward<_Up>(__u);
1314 }
1315
1316#if __cpp_lib_optional >= 202110L // C++23
1317 // [optional.monadic]
1318
1319 template<typename _Fn>
1320 constexpr auto
1321 and_then(_Fn&& __f) &
1322 {
1323 using _Up = remove_cvref_t<invoke_result_t<_Fn, _Tp&>>;
1324 static_assert(__is_optional_v<_Up>,
1325 "the function passed to std::optional<T>::and_then "
1326 "must return a std::optional");
1327 if (has_value())
1328 return std::__invoke(std::forward<_Fn>(__f), _M_get());
1329 else
1330 return _Up();
1331 }
1332
1333 template<typename _Fn>
1334 constexpr auto
1335 and_then(_Fn&& __f) const &
1336 {
1337 using _Up = remove_cvref_t<invoke_result_t<_Fn, const _Tp&>>;
1338 static_assert(__is_optional_v<_Up>,
1339 "the function passed to std::optional<T>::and_then "
1340 "must return a std::optional");
1341 if (has_value())
1342 return std::__invoke(std::forward<_Fn>(__f), _M_get());
1343 else
1344 return _Up();
1345 }
1346
1347 template<typename _Fn>
1348 constexpr auto
1349 and_then(_Fn&& __f) &&
1350 {
1351 using _Up = remove_cvref_t<invoke_result_t<_Fn, _Tp>>;
1352 static_assert(__is_optional_v<_Up>,
1353 "the function passed to std::optional<T>::and_then "
1354 "must return a std::optional");
1355 if (has_value())
1356 return std::__invoke(std::forward<_Fn>(__f), std::move(_M_get()));
1357 else
1358 return _Up();
1359 }
1360
1361 template<typename _Fn>
1362 constexpr auto
1363 and_then(_Fn&& __f) const &&
1364 {
1365 using _Up = remove_cvref_t<invoke_result_t<_Fn, const _Tp>>;
1366 static_assert(__is_optional_v<_Up>,
1367 "the function passed to std::optional<T>::and_then "
1368 "must return a std::optional");
1369 if (has_value())
1370 return std::__invoke(std::forward<_Fn>(__f), std::move(_M_get()));
1371 else
1372 return _Up();
1373 }
1374
1375 template<typename _Fn>
1376 constexpr auto
1377 transform(_Fn&& __f) &
1378 {
1379 using _Up = remove_cv_t<invoke_result_t<_Fn, _Tp&>>;
1380 if (has_value())
1381 return optional<_Up>(_Optional_func<_Fn>{__f}, _M_get());
1382 else
1383 return optional<_Up>();
1384 }
1385
1386 template<typename _Fn>
1387 constexpr auto
1388 transform(_Fn&& __f) const &
1389 {
1390 using _Up = remove_cv_t<invoke_result_t<_Fn, const _Tp&>>;
1391 if (has_value())
1392 return optional<_Up>(_Optional_func<_Fn>{__f}, _M_get());
1393 else
1394 return optional<_Up>();
1395 }
1396
1397 template<typename _Fn>
1398 constexpr auto
1399 transform(_Fn&& __f) &&
1400 {
1401 using _Up = remove_cv_t<invoke_result_t<_Fn, _Tp>>;
1402 if (has_value())
1403 return optional<_Up>(_Optional_func<_Fn>{__f}, std::move(_M_get()));
1404 else
1405 return optional<_Up>();
1406 }
1407
1408 template<typename _Fn>
1409 constexpr auto
1410 transform(_Fn&& __f) const &&
1411 {
1412 using _Up = remove_cv_t<invoke_result_t<_Fn, const _Tp>>;
1413 if (has_value())
1414 return optional<_Up>(_Optional_func<_Fn>{__f}, std::move(_M_get()));
1415 else
1416 return optional<_Up>();
1417 }
1418
1419 template<typename _Fn> requires invocable<_Fn> && copy_constructible<_Tp>
1420 constexpr optional
1421 or_else(_Fn&& __f) const&
1422 {
1423 using _Up = invoke_result_t<_Fn>;
1424 static_assert(is_same_v<remove_cvref_t<_Up>, optional>,
1425 "the function passed to std::optional<T>::or_else "
1426 "must return a std::optional<T>");
1427
1428 if (has_value())
1429 return *this;
1430 else
1431 return std::forward<_Fn>(__f)();
1432 }
1433
1434 template<typename _Fn> requires invocable<_Fn> && move_constructible<_Tp>
1435 constexpr optional
1436 or_else(_Fn&& __f) &&
1437 {
1438 using _Up = invoke_result_t<_Fn>;
1439 static_assert(is_same_v<remove_cvref_t<_Up>, optional>,
1440 "the function passed to std::optional<T>::or_else "
1441 "must return a std::optional<T>");
1442
1443 if (has_value())
1444 return std::move(*this);
1445 else
1446 return std::forward<_Fn>(__f)();
1447 }
1448#endif
1449
1450 _GLIBCXX20_CONSTEXPR void reset() noexcept { this->_M_reset(); }
1451
1452 private:
1453 using _Base::_M_get;
1454
1455 [[__gnu__::__always_inline__]]
1456 constexpr _Tp&
1457 _M_fwd() & noexcept
1458 { return _M_get(); }
1459
1460 [[__gnu__::__always_inline__]]
1461 constexpr _Tp&&
1462 _M_fwd() && noexcept
1463 { return std::move(_M_get()); }
1464
1465 [[__gnu__::__always_inline__]]
1466 constexpr const _Tp&
1467 _M_fwd() const& noexcept
1468 { return _M_get(); }
1469
1470 [[__gnu__::__always_inline__]]
1471 constexpr const _Tp&&
1472 _M_fwd() const&& noexcept
1473 { return std::move(_M_get()); }
1474
1475 template<typename _Up> friend class optional;
1476
1477#if __cpp_lib_optional >= 202110L // C++23
1478 template<typename _Fn, typename _Value>
1479 explicit constexpr
1480 optional(_Optional_func<_Fn> __f, _Value&& __v)
1481 {
1482 this->_M_payload._M_apply(__f, std::forward<_Value>(__v));
1483 }
1484#endif
1485 };
1486
1487#if __cpp_lib_optional >= 202506L // C++26
1488 template<typename _Tp>
1489 class optional<_Tp&>;
1490
1491 template<typename _Tp>
1492 constexpr bool __is_optional_ref_v = false;
1493
1494 template<typename _Tp>
1495 constexpr bool __is_optional_ref_v<optional<_Tp&>> = true;
1496
1497 template<typename _Tp>
1498 struct __optional_ref_base
1499 {};
1500
1501#ifdef __cpp_lib_optional_range_support // >= C++26
1502 template<typename _Tp>
1503 struct __optional_ref_base<_Tp[]>
1504 {};
1505
1506 template<typename _Tp>
1507 requires is_object_v<_Tp>
1508 struct __optional_ref_base<_Tp>
1509 {
1510 using iterator = __gnu_cxx::__normal_iterator<_Tp*, optional<_Tp&>>;
1511 };
1512#endif // __cpp_lib_optional_range_support
1513
1514 template<typename _Tp>
1515 class optional<_Tp&> : public __optional_ref_base<_Tp>
1516 {
1517 static_assert(__is_valid_contained_type_for_optional<_Tp&>);
1518
1519 public:
1520 using value_type = _Tp;
1521
1522 // Constructors.
1523 constexpr optional() noexcept = default;
1524 constexpr optional(nullopt_t) noexcept : optional() {}
1525 constexpr optional(const optional&) noexcept = default;
1526
1527 template<typename _Arg>
1528 requires is_constructible_v<_Tp&, _Arg>
1529 && (!reference_constructs_from_temporary_v<_Tp&, _Arg>)
1530 explicit constexpr
1531 optional(in_place_t, _Arg&& __arg)
1532 {
1533 __convert_ref_init_val(std::forward<_Arg>(__arg));
1534 }
1535
1536 template<typename _Up>
1537 requires (!is_same_v<remove_cvref_t<_Up>, optional>)
1538 && (!is_same_v<remove_cvref_t<_Up>, in_place_t>)
1539 && is_constructible_v<_Tp&, _Up>
1540 && (!reference_constructs_from_temporary_v<_Tp&, _Up>)
1541 explicit(!is_convertible_v<_Up, _Tp&>)
1542 constexpr
1543 optional(_Up&& __u)
1544 noexcept(is_nothrow_constructible_v<_Tp&, _Up>)
1545 {
1546 __convert_ref_init_val(std::forward<_Up>(__u));
1547 }
1548
1549 template<typename _Up>
1550 requires (!is_same_v<remove_cvref_t<_Up>, optional>)
1551 && (!is_same_v<remove_cvref_t<_Up>, in_place_t>)
1552 && is_constructible_v<_Tp&, _Up>
1553 && reference_constructs_from_temporary_v<_Tp&, _Up>
1554 explicit(!is_convertible_v<_Up, _Tp&>)
1555 constexpr
1556 optional(_Up&& __u) = delete;
1557
1558 // optional<U> &
1559 template<typename _Up>
1560 requires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)
1561 && (!is_same_v<_Tp&, _Up>)
1562 && is_constructible_v<_Tp&, _Up&>
1563 && (!reference_constructs_from_temporary_v<_Tp&, _Up&>)
1564 explicit(!is_convertible_v<_Up&, _Tp&>)
1565 constexpr
1566 optional(optional<_Up>& __rhs)
1567 noexcept(is_nothrow_constructible_v<_Tp&, _Up&>)
1568 {
1569 if (__rhs)
1570 __convert_ref_init_val(__rhs._M_fwd());
1571 }
1572
1573 template<typename _Up>
1574 requires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)
1575 && (!is_same_v<_Tp&, _Up>)
1576 && is_constructible_v<_Tp&, _Up&>
1577 && reference_constructs_from_temporary_v<_Tp&, _Up&>
1578 explicit(!is_convertible_v<_Up&, _Tp&>)
1579 constexpr
1580 optional(optional<_Up>& __rhs) = delete;
1581
1582 // const optional<U>&
1583 template<typename _Up>
1584 requires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)
1585 && (!is_same_v<_Tp&, _Up>)
1586 && is_constructible_v<_Tp&, const _Up&>
1587 && (!reference_constructs_from_temporary_v<_Tp&, const _Up&>)
1588 explicit(!is_convertible_v<const _Up&, _Tp&>)
1589 constexpr
1590 optional(const optional<_Up>& __rhs)
1591 noexcept(is_nothrow_constructible_v<_Tp&, _Up&>)
1592 {
1593 if (__rhs)
1594 __convert_ref_init_val(__rhs._M_fwd());
1595 }
1596
1597 template<typename _Up>
1598 requires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)
1599 && (!is_same_v<_Tp&, _Up>)
1600 && is_constructible_v<_Tp&, const _Up&>
1601 && reference_constructs_from_temporary_v<_Tp&, const _Up&>
1602 explicit(!is_convertible_v<const _Up&, _Tp&>)
1603 constexpr
1604 optional(const optional<_Up>& __rhs) = delete;
1605
1606 // optional<U>&&
1607 template<typename _Up>
1608 requires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)
1609 && (!is_same_v<_Tp&, _Up>)
1610 && is_constructible_v<_Tp&, _Up>
1611 && (!reference_constructs_from_temporary_v<_Tp&, _Up>)
1612 explicit(!is_convertible_v<_Up, _Tp&>)
1613 constexpr
1614 optional(optional<_Up>&& __rhs)
1615 noexcept(is_nothrow_constructible_v<_Tp&, _Up>)
1616 {
1617 if (__rhs)
1618 __convert_ref_init_val(std::move(__rhs)._M_fwd());
1619 }
1620
1621 template<typename _Up>
1622 requires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)
1623 && (!is_same_v<_Tp&, _Up>)
1624 && is_constructible_v<_Tp&, _Up>
1625 && reference_constructs_from_temporary_v<_Tp&, _Up>
1626 explicit(!is_convertible_v<_Up, _Tp&>)
1627 constexpr
1628 optional(optional<_Up>&& __rhs) = delete;
1629
1630 // const optional<U>&&
1631 template<typename _Up>
1632 requires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)
1633 && (!is_same_v<_Tp&, _Up>)
1634 && is_constructible_v<_Tp&, const _Up>
1635 && (!reference_constructs_from_temporary_v<_Tp&, _Up>)
1636 explicit(!is_convertible_v<const _Up, _Tp&>)
1637 constexpr
1638 optional(const optional<_Up>&& __rhs)
1639 noexcept(is_nothrow_constructible_v<_Tp&, const _Up>)
1640 {
1641 if (__rhs)
1642 __convert_ref_init_val(std::move(__rhs)._M_fwd());
1643 }
1644
1645 template<typename _Up>
1646 requires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)
1647 && (!is_same_v<_Tp&, _Up>)
1648 && is_constructible_v<_Tp&, const _Up>
1649 && reference_constructs_from_temporary_v<_Tp&, const _Up>
1650 explicit(!is_convertible_v<const _Up, _Tp&>)
1651 constexpr
1652 optional(const optional<_Up>&& __rhs) = delete;
1653
1654 constexpr ~optional() = default;
1655
1656 // Assignment.
1657 constexpr optional& operator=(nullopt_t) noexcept
1658 {
1659 _M_val = nullptr;
1660 return *this;
1661 }
1662
1663 constexpr optional& operator=(const optional&) noexcept = default;
1664
1665 template<typename _Up>
1666 requires is_constructible_v<_Tp&, _Up>
1667 && (!reference_constructs_from_temporary_v<_Tp&, _Up>)
1668 constexpr _Tp&
1669 emplace(_Up&& __u)
1670 noexcept(is_nothrow_constructible_v<_Tp&, _Up>)
1671 {
1672 __convert_ref_init_val(std::forward<_Up>(__u));
1673 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1674 // 4300. Missing Returns: element in optional<T&>::emplace
1675 return *_M_val;
1676 }
1677
1678 // Swap.
1679 constexpr void swap(optional& __rhs) noexcept
1680 { std::swap(_M_val, __rhs._M_val); }
1681
1682#ifdef __cpp_lib_optional_range_support // >= C++26
1683 // Iterator support.
1684 constexpr auto begin() const noexcept
1685 requires is_object_v<_Tp> && (!is_unbounded_array_v<_Tp>)
1686 { return __gnu_cxx::__normal_iterator<_Tp*, optional>(_M_val); }
1687
1688 constexpr auto end() const noexcept
1689 requires is_object_v<_Tp> && (!is_unbounded_array_v<_Tp>)
1690 { return begin() + has_value(); }
1691#endif // __cpp_lib_optional_range_support
1692
1693 // Observers.
1694 constexpr _Tp* operator->() const noexcept
1695 {
1696 __glibcxx_assert(_M_val); // hardened precondition
1697 return _M_val;
1698 }
1699
1700 constexpr _Tp& operator*() const noexcept
1701 {
1702 __glibcxx_assert(_M_val); // hardened precondition
1703 return *_M_val;
1704 }
1705
1706 constexpr explicit operator bool() const noexcept
1707 {
1708 return _M_val;
1709 }
1710
1711 constexpr bool has_value() const noexcept
1712 {
1713 return _M_val;
1714 }
1715
1716 constexpr _Tp& value() const
1717 {
1718 if (_M_val)
1719 return *_M_val;
1720 __throw_bad_optional_access();
1721 }
1722
1723 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1724 // 4304. std::optional<NonReturnable&> is ill-formed due to value_or
1725 template<typename _Up = remove_cv_t<_Tp>>
1726 requires is_object_v<_Tp> && (!is_array_v<_Tp>)
1727 constexpr decay_t<_Tp>
1728 value_or(_Up&& __u) const
1729 {
1730 using _Xp = remove_cv_t<_Tp>;
1731 static_assert(is_convertible_v<_Tp&, _Xp>);
1732 static_assert(is_convertible_v<_Up, _Xp>);
1733 if (_M_val)
1734 return *_M_val;
1735 return std::forward<_Up>(__u);
1736 }
1737
1738 // Monadic operations.
1739 template<typename _Fn>
1740 constexpr auto
1741 and_then(_Fn&& __f) const
1742 {
1743 using _Up = remove_cvref_t<invoke_result_t<_Fn, _Tp&>>;
1744 static_assert(__is_optional_v<_Up>,
1745 "the function passed to std::optional<T&>::and_then "
1746 "must return a std::optional");
1747 if (has_value())
1748 return std::__invoke(std::forward<_Fn>(__f), *_M_val);
1749 else
1750 return _Up();
1751 }
1752
1753 template<typename _Fn>
1754 constexpr
1755 optional<remove_cv_t<invoke_result_t<_Fn, _Tp&>>>
1756 transform(_Fn&& __f) const
1757 {
1758 using _Up = remove_cv_t<invoke_result_t<_Fn, _Tp&>>;
1759 if (has_value())
1760 return optional<_Up>(_Optional_func<_Fn>{__f}, *_M_val);
1761 else
1762 return optional<_Up>();
1763 }
1764
1765 template<typename _Fn>
1766 requires invocable<_Fn>
1767 constexpr
1768 optional
1769 or_else(_Fn&& __f) const
1770 {
1771 static_assert(is_same_v<remove_cvref_t<invoke_result_t<_Fn>>, optional>,
1772 "the function passed to std::optional<T&>::or_else "
1773 "must return a std::optional<T&>");
1774 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1775 // 4367. Improve optional<T&>::or_else
1776 if (has_value())
1777 return *this;
1778 else
1779 return std::forward<_Fn>(__f)();
1780 }
1781
1782 // Modifiers.
1783 constexpr void reset() noexcept
1784 {
1785 _M_val = nullptr;
1786 }
1787
1788 private:
1789 _Tp *_M_val = nullptr;
1790
1791 [[__gnu__::__always_inline__]]
1792 constexpr _Tp&
1793 _M_fwd() const noexcept
1794 { return *_M_val; }
1795
1796 template<typename _Up> friend class optional;
1797
1798 template<typename _Up>
1799 constexpr
1800 void
1801 __convert_ref_init_val(_Up&& __u)
1802 noexcept
1803 {
1804 _Tp& __r(std::forward<_Up>(__u));
1805 _M_val = std::addressof(__r);
1806 }
1807
1808 template<typename _Fn, typename _Value>
1809 explicit constexpr
1810 optional(_Optional_func<_Fn> __f, _Value&& __v)
1811 {
1812 _Tp& __r = std::__invoke(std::forward<_Fn>(__f._M_f), std::forward<_Value>(__v));
1813 _M_val = std::addressof(__r);
1814 }
1815 };
1816#endif // __cpp_lib_optional >= 202506L
1817
1818 template<typename _Tp>
1819 using __optional_relop_t =
1821
1822 template<typename _Tp, typename _Up>
1823 using __optional_eq_t = __optional_relop_t<
1825 >;
1826
1827 template<typename _Tp, typename _Up>
1828 using __optional_ne_t = __optional_relop_t<
1830 >;
1831
1832 template<typename _Tp, typename _Up>
1833 using __optional_lt_t = __optional_relop_t<
1835 >;
1836
1837 template<typename _Tp, typename _Up>
1838 using __optional_gt_t = __optional_relop_t<
1840 >;
1841
1842 template<typename _Tp, typename _Up>
1843 using __optional_le_t = __optional_relop_t<
1845 >;
1846
1847 template<typename _Tp, typename _Up>
1848 using __optional_ge_t = __optional_relop_t<
1850 >;
1851
1852 // Comparisons between optional values.
1853 template<typename _Tp, typename _Up>
1854 constexpr auto
1855 operator==(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1856 -> __optional_eq_t<_Tp, _Up>
1857 {
1858 return static_cast<bool>(__lhs) == static_cast<bool>(__rhs)
1859 && (!__lhs || *__lhs == *__rhs);
1860 }
1861
1862 template<typename _Tp, typename _Up>
1863 constexpr auto
1864 operator!=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1865 -> __optional_ne_t<_Tp, _Up>
1866 {
1867 return static_cast<bool>(__lhs) != static_cast<bool>(__rhs)
1868 || (static_cast<bool>(__lhs) && *__lhs != *__rhs);
1869 }
1870
1871 template<typename _Tp, typename _Up>
1872 constexpr auto
1873 operator<(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1874 -> __optional_lt_t<_Tp, _Up>
1875 {
1876 return static_cast<bool>(__rhs) && (!__lhs || *__lhs < *__rhs);
1877 }
1878
1879 template<typename _Tp, typename _Up>
1880 constexpr auto
1881 operator>(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1882 -> __optional_gt_t<_Tp, _Up>
1883 {
1884 return static_cast<bool>(__lhs) && (!__rhs || *__lhs > *__rhs);
1885 }
1886
1887 template<typename _Tp, typename _Up>
1888 constexpr auto
1889 operator<=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1890 -> __optional_le_t<_Tp, _Up>
1891 {
1892 return !__lhs || (static_cast<bool>(__rhs) && *__lhs <= *__rhs);
1893 }
1894
1895 template<typename _Tp, typename _Up>
1896 constexpr auto
1897 operator>=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1898 -> __optional_ge_t<_Tp, _Up>
1899 {
1900 return !__rhs || (static_cast<bool>(__lhs) && *__lhs >= *__rhs);
1901 }
1902
1903#ifdef __cpp_lib_three_way_comparison
1904 template<typename _Tp, three_way_comparable_with<_Tp> _Up>
1905 [[nodiscard]]
1907 operator<=>(const optional<_Tp>& __x, const optional<_Up>& __y)
1908 {
1909 return __x && __y ? *__x <=> *__y : bool(__x) <=> bool(__y);
1910 }
1911#endif
1912
1913 // Comparisons with nullopt.
1914 template<typename _Tp>
1915 [[nodiscard]]
1916 constexpr bool
1917 operator==(const optional<_Tp>& __lhs, nullopt_t) noexcept
1918 { return !__lhs; }
1919
1920#ifdef __cpp_lib_three_way_comparison
1921 template<typename _Tp>
1922 [[nodiscard]]
1923 constexpr strong_ordering
1924 operator<=>(const optional<_Tp>& __x, nullopt_t) noexcept
1925 { return bool(__x) <=> false; }
1926#else
1927 template<typename _Tp>
1928 constexpr bool
1929 operator==(nullopt_t, const optional<_Tp>& __rhs) noexcept
1930 { return !__rhs; }
1931
1932 template<typename _Tp>
1933 constexpr bool
1934 operator!=(const optional<_Tp>& __lhs, nullopt_t) noexcept
1935 { return static_cast<bool>(__lhs); }
1936
1937 template<typename _Tp>
1938 constexpr bool
1939 operator!=(nullopt_t, const optional<_Tp>& __rhs) noexcept
1940 { return static_cast<bool>(__rhs); }
1941
1942 template<typename _Tp>
1943 constexpr bool
1944 operator<(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept
1945 { return false; }
1946
1947 template<typename _Tp>
1948 constexpr bool
1949 operator<(nullopt_t, const optional<_Tp>& __rhs) noexcept
1950 { return static_cast<bool>(__rhs); }
1951
1952 template<typename _Tp>
1953 constexpr bool
1954 operator>(const optional<_Tp>& __lhs, nullopt_t) noexcept
1955 { return static_cast<bool>(__lhs); }
1956
1957 template<typename _Tp>
1958 constexpr bool
1959 operator>(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept
1960 { return false; }
1961
1962 template<typename _Tp>
1963 constexpr bool
1964 operator<=(const optional<_Tp>& __lhs, nullopt_t) noexcept
1965 { return !__lhs; }
1966
1967 template<typename _Tp>
1968 constexpr bool
1969 operator<=(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept
1970 { return true; }
1971
1972 template<typename _Tp>
1973 constexpr bool
1974 operator>=(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept
1975 { return true; }
1976
1977 template<typename _Tp>
1978 constexpr bool
1979 operator>=(nullopt_t, const optional<_Tp>& __rhs) noexcept
1980 { return !__rhs; }
1981#endif // three-way-comparison
1982
1983#if __cpp_lib_concepts
1984 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1985 // 4072. std::optional comparisons: constrain harder
1986# define _REQUIRES_NOT_OPTIONAL(T) requires (!__is_optional_v<T>)
1987#else
1988# define _REQUIRES_NOT_OPTIONAL(T)
1989#endif
1990
1991 // Comparisons with value type.
1992 template<typename _Tp, typename _Up>
1993 _REQUIRES_NOT_OPTIONAL(_Up)
1994 constexpr auto
1995 operator== [[nodiscard]] (const optional<_Tp>& __lhs, const _Up& __rhs)
1996 -> __optional_eq_t<_Tp, _Up>
1997 { return __lhs && *__lhs == __rhs; }
1998
1999 template<typename _Tp, typename _Up>
2000 _REQUIRES_NOT_OPTIONAL(_Tp)
2001 constexpr auto
2002 operator== [[nodiscard]] (const _Tp& __lhs, const optional<_Up>& __rhs)
2003 -> __optional_eq_t<_Tp, _Up>
2004 { return __rhs && __lhs == *__rhs; }
2005
2006 template<typename _Tp, typename _Up>
2007 _REQUIRES_NOT_OPTIONAL(_Up)
2008 constexpr auto
2009 operator!= [[nodiscard]] (const optional<_Tp>& __lhs, const _Up& __rhs)
2010 -> __optional_ne_t<_Tp, _Up>
2011 { return !__lhs || *__lhs != __rhs; }
2012
2013 template<typename _Tp, typename _Up>
2014 _REQUIRES_NOT_OPTIONAL(_Tp)
2015 constexpr auto
2016 operator!= [[nodiscard]] (const _Tp& __lhs, const optional<_Up>& __rhs)
2017 -> __optional_ne_t<_Tp, _Up>
2018 { return !__rhs || __lhs != *__rhs; }
2019
2020 template<typename _Tp, typename _Up>
2021 _REQUIRES_NOT_OPTIONAL(_Up)
2022 constexpr auto
2023 operator< [[nodiscard]] (const optional<_Tp>& __lhs, const _Up& __rhs)
2024 -> __optional_lt_t<_Tp, _Up>
2025 { return !__lhs || *__lhs < __rhs; }
2026
2027 template<typename _Tp, typename _Up>
2028 _REQUIRES_NOT_OPTIONAL(_Tp)
2029 constexpr auto
2030 operator< [[nodiscard]] (const _Tp& __lhs, const optional<_Up>& __rhs)
2031 -> __optional_lt_t<_Tp, _Up>
2032 { return __rhs && __lhs < *__rhs; }
2033
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_gt_t<_Tp, _Up>
2039 { return __lhs && *__lhs > __rhs; }
2040
2041 template<typename _Tp, typename _Up>
2042 _REQUIRES_NOT_OPTIONAL(_Tp)
2043 constexpr auto
2044 operator> [[nodiscard]] (const _Tp& __lhs, const optional<_Up>& __rhs)
2045 -> __optional_gt_t<_Tp, _Up>
2046 { return !__rhs || __lhs > *__rhs; }
2047
2048 template<typename _Tp, typename _Up>
2049 _REQUIRES_NOT_OPTIONAL(_Up)
2050 constexpr auto
2051 operator<= [[nodiscard]] (const optional<_Tp>& __lhs, const _Up& __rhs)
2052 -> __optional_le_t<_Tp, _Up>
2053 { return !__lhs || *__lhs <= __rhs; }
2054
2055 template<typename _Tp, typename _Up>
2056 _REQUIRES_NOT_OPTIONAL(_Tp)
2057 constexpr auto
2058 operator<= [[nodiscard]] (const _Tp& __lhs, const optional<_Up>& __rhs)
2059 -> __optional_le_t<_Tp, _Up>
2060 { return __rhs && __lhs <= *__rhs; }
2061
2062 template<typename _Tp, typename _Up>
2063 _REQUIRES_NOT_OPTIONAL(_Up)
2064 constexpr auto
2065 operator>= [[nodiscard]] (const optional<_Tp>& __lhs, const _Up& __rhs)
2066 -> __optional_ge_t<_Tp, _Up>
2067 { return __lhs && *__lhs >= __rhs; }
2068
2069 template<typename _Tp, typename _Up>
2070 _REQUIRES_NOT_OPTIONAL(_Tp)
2071 constexpr auto
2072 operator>= [[nodiscard]] (const _Tp& __lhs, const optional<_Up>& __rhs)
2073 -> __optional_ge_t<_Tp, _Up>
2074 { return !__rhs || __lhs >= *__rhs; }
2075
2076#ifdef __cpp_lib_three_way_comparison
2077 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2078 // 3746. optional's spaceship with U with a type derived from optional
2079 // causes infinite constraint meta-recursion
2080 template<typename _Tp>
2081 concept __is_derived_from_optional = requires (const _Tp& __t) {
2082 []<typename _Up>(const optional<_Up>&){ }(__t);
2083 };
2084
2085 template<typename _Tp, typename _Up>
2086 requires (!__is_derived_from_optional<_Up>)
2087 && requires { typename compare_three_way_result_t<_Tp, _Up>; }
2088 && three_way_comparable_with<_Tp, _Up>
2090 operator<=> [[nodiscard]] (const optional<_Tp>& __x, const _Up& __v)
2091 { return bool(__x) ? *__x <=> __v : strong_ordering::less; }
2092#endif
2093
2094 // Swap and creation functions.
2095
2096 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2097 // 2748. swappable traits for optionals
2098 template<typename _Tp>
2099 _GLIBCXX20_CONSTEXPR
2100 inline enable_if_t<is_move_constructible_v<_Tp> && is_swappable_v<_Tp>>
2101 swap(optional<_Tp>& __lhs, optional<_Tp>& __rhs)
2102 noexcept(noexcept(__lhs.swap(__rhs)))
2103 { __lhs.swap(__rhs); }
2104
2105#if __cpp_lib_optional >= 202506L
2106 // We deviate from standard, that do not declared separate swap overload
2107 // from optional<T&>.
2108 template<typename _Tp>
2109 constexpr void
2110 swap(optional<_Tp&>& __lhs, optional<_Tp&>& __rhs) noexcept
2111 { __lhs.swap(__rhs); }
2112#endif
2113
2114 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2115 // 2766. Swapping non-swappable types
2116 template<typename _Tp>
2117 enable_if_t<!(is_move_constructible_v<_Tp> && is_swappable_v<_Tp>)>
2118 swap(optional<_Tp>&, optional<_Tp>&) = delete;
2119
2120#if __cpp_lib_optional >= 202506L
2121 template<int = 0, typename _Tp>
2122#else
2123 template<typename _Tp>
2124#endif
2125 constexpr
2127 optional<decay_t<_Tp>>>
2128 make_optional(_Tp&& __t)
2129 noexcept(is_nothrow_constructible_v<optional<decay_t<_Tp>>, _Tp>)
2130 { return optional<decay_t<_Tp>>( std::forward<_Tp>(__t) ); }
2131
2132 template<typename _Tp, typename... _Args>
2133 constexpr
2134 enable_if_t<is_constructible_v<_Tp, _Args...>,
2135 optional<_Tp>>
2136 make_optional(_Args&&... __args)
2137 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
2138 { return optional<_Tp>( in_place, std::forward<_Args>(__args)... ); }
2139
2140 template<typename _Tp, typename _Up, typename... _Args>
2141 constexpr
2143 optional<_Tp>>
2144 make_optional(initializer_list<_Up> __il, _Args&&... __args)
2145 noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, _Args...>)
2146 { return optional<_Tp>( in_place, __il, std::forward<_Args>(__args)... ); }
2147
2148 // Hash.
2149
2150 template<typename _Tp, typename _Up = remove_const_t<_Tp>>
2151 struct __optional_hash
2152#if ! _GLIBCXX_INLINE_VERSION
2153 : public __hash_empty_base<_Up>
2154#endif
2155 {
2156#if __cplusplus < 202002L
2157 using result_type [[__deprecated__]] = size_t;
2158 using argument_type [[__deprecated__]] = optional<_Tp>;
2159#endif
2160
2161 size_t
2162 operator()(const optional<_Tp>& __t) const
2163 noexcept(noexcept(hash<_Up>{}(*__t)))
2164 {
2165 // We pick an arbitrary hash for disengaged optionals which hopefully
2166 // usual values of _Tp won't typically hash to.
2167 constexpr size_t __magic_disengaged_hash = static_cast<size_t>(-3333);
2168 return __t ? hash<_Up>{}(*__t) : __magic_disengaged_hash;
2169 }
2170 };
2171
2172 template<typename _Tp>
2173 struct hash<optional<_Tp>>
2174 // hash for optional<T&> is disabled because is_hash_enabled_for<T&> is false
2175 : public __conditional_t<__is_hash_enabled_for<remove_const_t<_Tp>>,
2176 __optional_hash<_Tp>,
2177 __hash_not_enabled<_Tp>>
2178 { };
2179
2180 template<typename _Tp>
2181 struct __is_fast_hash<hash<optional<_Tp>>> : __is_fast_hash<hash<_Tp>>
2182 { };
2183
2184 /// @}
2185
2186#if __cpp_deduction_guides >= 201606
2187 template <typename _Tp> optional(_Tp) -> optional<_Tp>;
2188#endif
2189
2190#ifdef __cpp_lib_optional_range_support // >= C++26
2191 template<typename _Tp>
2192 inline constexpr bool
2193 ranges::enable_view<optional<_Tp>> = true;
2194
2195#if __cpp_lib_optional >= 202506L // C++26
2196 template<typename _Tp>
2197 constexpr bool
2198 ranges::enable_borrowed_range<optional<_Tp&>> = true;
2199#endif
2200
2201 template<typename _Tp>
2202 inline constexpr range_format
2203 format_kind<optional<_Tp>> = range_format::disabled;
2204#endif // __cpp_lib_optional_range_support
2205
2206#undef _GLIBCXX_USE_CONSTRAINTS_FOR_OPTIONAL
2207
2208_GLIBCXX_END_NAMESPACE_VERSION
2209} // namespace std
2210
2211#endif // __cpp_lib_optional
2212
2213#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