libstdc++: optional Source File

libstdc++

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