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