1// <optional> -*- C++ -*-
3// Copyright (C) 2013-2025 Free Software Foundation, Inc.
4// Copyright The GNU Toolchain Authors.
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)
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.
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.
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/>.
26/** @file include/optional
27 * This is a Standard C++ Library header.
30#ifndef _GLIBCXX_OPTIONAL
31#define _GLIBCXX_OPTIONAL 1
34#pragma GCC system_header
37#define __glibcxx_want_freestanding_optional
38#define __glibcxx_want_optional
39#define __glibcxx_want_optional_range_support
40#define __glibcxx_want_constrained_equality
41#include <bits/version.h>
43#ifdef __cpp_lib_optional // C++ >= 17
48#include <initializer_list>
49#include <bits/enable_special_members.h>
50#include <bits/exception_defines.h>
51#include <bits/functional_hash.h>
52#include <bits/stl_construct.h> // _Construct
53#include <bits/utility.h> // in_place_t
54#if __cplusplus > 201703L
56# include <bits/invoke.h> // std::__invoke
58#if __cplusplus > 202002L
61#ifdef __cpp_lib_optional_range_support // C++ >= 26
62# include <bits/formatfwd.h>
63# include <bits/ranges_base.h>
64# include <bits/stl_iterator.h>
67namespace std _GLIBCXX_VISIBILITY(default)
69_GLIBCXX_BEGIN_NAMESPACE_VERSION
72 * @addtogroup utilities
76 template<typename _Tp>
79 /// Tag type to disengage optional objects.
82 // Do not user-declare default constructor at all for
83 // optional_value = {} syntax to work.
84 // nullopt_t() = delete;
86 // Used for constructing nullopt.
87 enum class _Construct { _Token };
89 // Must be constexpr for nullopt_t to be literal.
90 explicit constexpr nullopt_t(_Construct) noexcept { }
93 /// Tag to disengage optional objects.
94 inline constexpr nullopt_t nullopt { nullopt_t::_Construct::_Token };
96 template<typename _Fn> struct _Optional_func { _Fn& _M_f; };
99 * @brief Exception class thrown when a disengaged optional object is
101 * @ingroup exceptions
103 class bad_optional_access : public exception
106 bad_optional_access() = default;
107 virtual ~bad_optional_access() = default;
109 const char* what() const noexcept override
110 { return "bad optional access"; }
113 // XXX Does not belong here.
114 [[__noreturn__]] inline void
115 __throw_bad_optional_access()
116 { _GLIBCXX_THROW_OR_ABORT(bad_optional_access()); }
118 // This class template manages construction/destruction of
119 // the contained value for a std::optional.
120 template <typename _Tp>
121 struct _Optional_payload_base
123 using _Stored_type = remove_const_t<_Tp>;
125 _Optional_payload_base() = default;
126 ~_Optional_payload_base() = default;
128 template<typename... _Args>
130 _Optional_payload_base(in_place_t __tag, _Args&&... __args)
131 : _M_payload(__tag, std::forward<_Args>(__args)...),
135 template<typename _Up, typename... _Args>
137 _Optional_payload_base(std::initializer_list<_Up> __il,
139 : _M_payload(__il, std::forward<_Args>(__args)...),
143 // Constructor used by _Optional_base copy constructor when the
144 // contained value is not trivially copy constructible.
146 _Optional_payload_base(bool /* __engaged */,
147 const _Optional_payload_base& __other)
149 if (__other._M_engaged)
150 this->_M_construct(__other._M_get());
153 // Constructor used by _Optional_base move constructor when the
154 // contained value is not trivially move constructible.
156 _Optional_payload_base(bool /* __engaged */,
157 _Optional_payload_base&& __other)
159 if (__other._M_engaged)
160 this->_M_construct(std::move(__other._M_get()));
163 // Copy constructor is only used to when the contained value is
164 // trivially copy constructible.
165 _Optional_payload_base(const _Optional_payload_base&) = default;
167 // Move constructor is only used to when the contained value is
168 // trivially copy constructible.
169 _Optional_payload_base(_Optional_payload_base&&) = default;
171 _Optional_payload_base&
172 operator=(const _Optional_payload_base&) = default;
174 _Optional_payload_base&
175 operator=(_Optional_payload_base&&) = default;
177 // used to perform non-trivial copy assignment.
179 _M_copy_assign(const _Optional_payload_base& __other)
181 if (this->_M_engaged && __other._M_engaged)
182 this->_M_get() = __other._M_get();
185 if (__other._M_engaged)
186 this->_M_construct(__other._M_get());
192 // used to perform non-trivial move assignment.
194 _M_move_assign(_Optional_payload_base&& __other)
195 noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
196 is_nothrow_move_assignable<_Tp>>)
198 if (this->_M_engaged && __other._M_engaged)
199 this->_M_get() = std::move(__other._M_get());
202 if (__other._M_engaged)
203 this->_M_construct(std::move(__other._M_get()));
209 struct _Empty_byte { };
211 template<typename _Up, bool = is_trivially_destructible_v<_Up>>
214 constexpr _Storage() noexcept : _M_empty() { }
216 template<typename... _Args>
218 _Storage(in_place_t, _Args&&... __args)
219 : _M_value(std::forward<_Args>(__args)...)
222 template<typename _Vp, typename... _Args>
224 _Storage(std::initializer_list<_Vp> __il, _Args&&... __args)
225 : _M_value(__il, std::forward<_Args>(__args)...)
228#if __cplusplus >= 202002L
229 template<typename _Fn, typename _Arg>
231 _Storage(_Optional_func<_Fn> __f, _Arg&& __arg)
232 : _M_value(std::__invoke(std::forward<_Fn>(__f._M_f),
233 std::forward<_Arg>(__arg)))
237#if __cpp_concepts >= 202002L // Conditionally trivial special member functions
238 ~_Storage() = default;
240 // User-provided destructor is needed when _Up has non-trivial dtor.
242 ~_Storage() requires (!is_trivially_destructible_v<_Up>)
245 _Storage(const _Storage&) = default;
246 _Storage(_Storage&&) = default;
247 _Storage& operator=(const _Storage&) = default;
248 _Storage& operator=(_Storage&&) = default;
251 _Empty_byte _M_empty;
255#if __cpp_concepts < 202002L
256 template<typename _Up>
257 union _Storage<_Up, false>
259 constexpr _Storage() noexcept : _M_empty() { }
261 template<typename... _Args>
263 _Storage(in_place_t, _Args&&... __args)
264 : _M_value(std::forward<_Args>(__args)...)
267 template<typename _Vp, typename... _Args>
269 _Storage(std::initializer_list<_Vp> __il, _Args&&... __args)
270 : _M_value(__il, std::forward<_Args>(__args)...)
273#if __cplusplus >= 202002L
274 template<typename _Fn, typename _Arg>
276 _Storage(_Optional_func<_Fn> __f, _Arg&& __arg)
277 : _M_value(std::__invoke(std::forward<_Fn>(__f._M_f),
278 std::forward<_Arg>(__arg)))
282 // User-provided destructor is needed when _Up has non-trivial dtor.
283 _GLIBCXX20_CONSTEXPR ~_Storage() { }
285 _Storage(const _Storage&) = default;
286 _Storage(_Storage&&) = default;
287 _Storage& operator=(const _Storage&) = default;
288 _Storage& operator=(_Storage&&) = default;
290 _Empty_byte _M_empty;
295 _Storage<_Stored_type> _M_payload;
297 bool _M_engaged = false;
299 template<typename... _Args>
301 _M_construct(_Args&&... __args)
302 noexcept(is_nothrow_constructible_v<_Stored_type, _Args...>)
304 std::_Construct(std::__addressof(this->_M_payload._M_value),
305 std::forward<_Args>(__args)...);
306 this->_M_engaged = true;
310 _M_destroy() noexcept
313 _M_payload._M_value.~_Stored_type();
316#if __cplusplus >= 202002L
317 template<typename _Fn, typename _Up>
319 _M_apply(_Optional_func<_Fn> __f, _Up&& __x)
321 std::construct_at(std::__addressof(this->_M_payload),
322 __f, std::forward<_Up>(__x));
327 // The _M_get() operations have _M_engaged as a precondition.
328 // They exist to access the contained value with the appropriate
329 // const-qualification, because _M_payload has had the const removed.
333 { return this->_M_payload._M_value; }
336 _M_get() const noexcept
337 { return this->_M_payload._M_value; }
339 // _M_reset is a 'safe' operation with no precondition.
343 if (this->_M_engaged)
345 else // This seems redundant but improves codegen, see PR 112480.
346 this->_M_engaged = false;
350 // Class template that manages the payload for optionals.
351 template <typename _Tp,
352 bool /*_HasTrivialDestructor*/ =
353 is_trivially_destructible_v<_Tp>,
354 bool /*_HasTrivialCopy */ =
355 is_trivially_copy_assignable_v<_Tp>
356 && is_trivially_copy_constructible_v<_Tp>,
357 bool /*_HasTrivialMove */ =
358 is_trivially_move_assignable_v<_Tp>
359 && is_trivially_move_constructible_v<_Tp>>
360 struct _Optional_payload;
362 // Payload for potentially-constexpr optionals (trivial copy/move/destroy).
363 template <typename _Tp>
364 struct _Optional_payload<_Tp, true, true, true>
365 : _Optional_payload_base<_Tp>
367 using _Optional_payload_base<_Tp>::_Optional_payload_base;
369 _Optional_payload() = default;
372 // Payload for optionals with non-trivial copy construction/assignment.
373 template <typename _Tp>
374 struct _Optional_payload<_Tp, true, false, true>
375 : _Optional_payload_base<_Tp>
377 using _Optional_payload_base<_Tp>::_Optional_payload_base;
379 _Optional_payload() = default;
380 ~_Optional_payload() = default;
381 _Optional_payload(const _Optional_payload&) = default;
382 _Optional_payload(_Optional_payload&&) = default;
383 _Optional_payload& operator=(_Optional_payload&&) = default;
385 // Non-trivial copy assignment.
388 operator=(const _Optional_payload& __other)
390 this->_M_copy_assign(__other);
395 // Payload for optionals with non-trivial move construction/assignment.
396 template <typename _Tp>
397 struct _Optional_payload<_Tp, true, true, false>
398 : _Optional_payload_base<_Tp>
400 using _Optional_payload_base<_Tp>::_Optional_payload_base;
402 _Optional_payload() = default;
403 ~_Optional_payload() = default;
404 _Optional_payload(const _Optional_payload&) = default;
405 _Optional_payload(_Optional_payload&&) = default;
406 _Optional_payload& operator=(const _Optional_payload&) = default;
408 // Non-trivial move assignment.
411 operator=(_Optional_payload&& __other)
412 noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
413 is_nothrow_move_assignable<_Tp>>)
415 this->_M_move_assign(std::move(__other));
420 // Payload for optionals with non-trivial copy and move assignment.
421 template <typename _Tp>
422 struct _Optional_payload<_Tp, true, false, false>
423 : _Optional_payload_base<_Tp>
425 using _Optional_payload_base<_Tp>::_Optional_payload_base;
427 _Optional_payload() = default;
428 ~_Optional_payload() = default;
429 _Optional_payload(const _Optional_payload&) = default;
430 _Optional_payload(_Optional_payload&&) = default;
432 // Non-trivial copy assignment.
435 operator=(const _Optional_payload& __other)
437 this->_M_copy_assign(__other);
441 // Non-trivial move assignment.
444 operator=(_Optional_payload&& __other)
445 noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
446 is_nothrow_move_assignable<_Tp>>)
448 this->_M_move_assign(std::move(__other));
453 // Payload for optionals with non-trivial destructors.
454 template <typename _Tp, bool _Copy, bool _Move>
455 struct _Optional_payload<_Tp, false, _Copy, _Move>
456 : _Optional_payload<_Tp, true, false, false>
458 // Base class implements all the constructors and assignment operators:
459 using _Optional_payload<_Tp, true, false, false>::_Optional_payload;
460 _Optional_payload() = default;
461 _Optional_payload(const _Optional_payload&) = default;
462 _Optional_payload(_Optional_payload&&) = default;
463 _Optional_payload& operator=(const _Optional_payload&) = default;
464 _Optional_payload& operator=(_Optional_payload&&) = default;
466 // Destructor needs to destroy the contained value:
467 _GLIBCXX20_CONSTEXPR ~_Optional_payload() { this->_M_reset(); }
471 * @brief Class template that provides copy/move constructors of optional.
473 * Such a separate base class template is necessary in order to
474 * conditionally make copy/move constructors trivial.
476 * When the contained value is trivially copy/move constructible,
477 * the copy/move constructors of _Optional_base will invoke the
478 * trivial copy/move constructor of _Optional_payload. Otherwise,
479 * they will invoke _Optional_payload(bool, const _Optional_payload&)
480 * or _Optional_payload(bool, _Optional_payload&&) to initialize
481 * the contained value, if copying/moving an engaged optional.
483 * Whether the other special members are trivial is determined by the
484 * _Optional_payload<_Tp> specialization used for the _M_payload member.
486 * @see optional, _Enable_special_members
488 template<typename _Tp,
489 bool = is_trivially_copy_constructible_v<_Tp>,
490 bool = is_trivially_move_constructible_v<_Tp>>
491 struct _Optional_base
493 // Constructors for disengaged optionals.
494 constexpr _Optional_base() = default;
496 // Constructors for engaged optionals.
497 template<typename... _Args,
498 enable_if_t<is_constructible_v<_Tp, _Args...>, bool> = false>
500 _Optional_base(in_place_t, _Args&&... __args)
501 : _M_payload(in_place, std::forward<_Args>(__args)...)
504 template<typename _Up, typename... _Args,
505 enable_if_t<is_constructible_v<_Tp,
506 initializer_list<_Up>&,
507 _Args...>, bool> = false>
509 _Optional_base(in_place_t,
510 initializer_list<_Up> __il,
512 : _M_payload(in_place, __il, std::forward<_Args>(__args)...)
515 // Copy and move constructors.
517 _Optional_base(const _Optional_base& __other)
518 noexcept(is_nothrow_copy_constructible_v<_Tp>)
519 : _M_payload(__other._M_payload._M_engaged, __other._M_payload)
523 _Optional_base(_Optional_base&& __other)
524 noexcept(is_nothrow_move_constructible_v<_Tp>)
525 : _M_payload(__other._M_payload._M_engaged,
526 std::move(__other._M_payload))
529#if __cpp_concepts >= 202002L // Conditionally trivial special member functions
530 // Define these in the primary template if possible, so that we don't
531 // need to use partial specializations of this class template.
532 constexpr _Optional_base(const _Optional_base&)
533 requires is_trivially_copy_constructible_v<_Tp> = default;
535 constexpr _Optional_base(_Optional_base&&)
536 requires is_trivially_move_constructible_v<_Tp> = default;
539 // Assignment operators.
540 _Optional_base& operator=(const _Optional_base&) = default;
541 _Optional_base& operator=(_Optional_base&&) = default;
543 _Optional_payload<_Tp> _M_payload;
546 // For the primary template, we define these functions here.
547 using _Stored_type = remove_const_t<_Tp>;
549 // The _M_construct operation has !_M_engaged as a precondition
550 // while _M_destruct has _M_engaged as a precondition.
551 template<typename... _Args>
553 _M_construct(_Args&&... __args)
554 noexcept(is_nothrow_constructible_v<_Stored_type, _Args...>)
556 _M_payload._M_construct(std::forward<_Args>(__args)...);
560 _M_destruct() noexcept
561 { _M_payload._M_destroy(); }
563 // _M_reset is a 'safe' operation with no precondition.
566 { _M_payload._M_reset(); }
568 constexpr bool _M_is_engaged() const noexcept
569 { return _M_payload._M_engaged; }
571 // The _M_get operations have _M_engaged as a precondition.
574 { return _M_payload._M_get(); }
577 _M_get() const noexcept
578 { return _M_payload._M_get(); }
581#if __cpp_concepts < 202002L
582 // If P0848R3 "Conditionally Trivial Special Member Functions" is not
583 // supported (as determined from the __cpp_concepts macro value), the
584 // _Optional_base primary template only has non-trivial copy and move
585 // constructors. Use partial specializations of _Optional_base<T, C, M>
586 // that have a trivial copy and/or move constructor.
588 // Common base class for _Optional_base<T> to avoid repeating these
589 // member functions in each partial specialization.
590 // Only used if P0848R3 "Conditionally Trivial Special Member Functions"
591 // is not supported, as indicated by the __cpp_concepts value.
592 template<typename _Tp, typename _Dp>
593 class _Optional_base_impl
596 using _Stored_type = remove_const_t<_Tp>;
598 // The _M_construct operation has !_M_engaged as a precondition
599 // while _M_destruct has _M_engaged as a precondition.
600 template<typename... _Args>
602 _M_construct(_Args&&... __args)
603 noexcept(is_nothrow_constructible_v<_Stored_type, _Args...>)
605 static_cast<_Dp*>(this)->_M_payload._M_construct(
606 std::forward<_Args>(__args)...);
610 _M_destruct() noexcept
611 { static_cast<_Dp*>(this)->_M_payload._M_destroy(); }
613 // _M_reset is a 'safe' operation with no precondition.
616 { static_cast<_Dp*>(this)->_M_payload._M_reset(); }
618 constexpr bool _M_is_engaged() const noexcept
619 { return static_cast<const _Dp*>(this)->_M_payload._M_engaged; }
621 // The _M_get operations have _M_engaged as a precondition.
624 { return static_cast<_Dp*>(this)->_M_payload._M_get(); }
627 _M_get() const noexcept
628 { return static_cast<const _Dp*>(this)->_M_payload._M_get(); }
631 template<typename _Tp>
632 struct _Optional_base<_Tp, false, true> // trivial move ctor
633 : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
635 // Constructors for disengaged optionals.
636 constexpr _Optional_base() = default;
638 // Constructors for engaged optionals.
639 template<typename... _Args,
640 enable_if_t<is_constructible_v<_Tp, _Args...>, bool> = false>
642 _Optional_base(in_place_t, _Args&&... __args)
643 : _M_payload(in_place, std::forward<_Args>(__args)...)
646 template<typename _Up, typename... _Args,
647 enable_if_t<is_constructible_v<_Tp,
648 initializer_list<_Up>&,
649 _Args...>, bool> = false>
651 _Optional_base(in_place_t,
652 initializer_list<_Up> __il,
654 : _M_payload(in_place, __il, std::forward<_Args>(__args)...)
657 // Copy and move constructors.
658 constexpr _Optional_base(const _Optional_base& __other)
659 : _M_payload(__other._M_payload._M_engaged, __other._M_payload)
662 constexpr _Optional_base(_Optional_base&& __other) = default;
664 // Assignment operators.
665 _Optional_base& operator=(const _Optional_base&) = default;
666 _Optional_base& operator=(_Optional_base&&) = default;
668 _Optional_payload<_Tp> _M_payload;
671 template<typename _Tp>
672 struct _Optional_base<_Tp, true, false> // trivial copy ctor
673 : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
675 // Constructors for disengaged optionals.
676 constexpr _Optional_base() = default;
678 // Constructors for engaged optionals.
679 template<typename... _Args,
680 enable_if_t<is_constructible_v<_Tp, _Args...>, bool> = false>
682 _Optional_base(in_place_t, _Args&&... __args)
683 : _M_payload(in_place, std::forward<_Args>(__args)...)
686 template<typename _Up, typename... _Args,
687 enable_if_t<is_constructible_v<_Tp,
688 initializer_list<_Up>&,
689 _Args...>, bool> = false>
691 _Optional_base(in_place_t,
692 initializer_list<_Up> __il,
694 : _M_payload(in_place, __il, std::forward<_Args>(__args)...)
697 // Copy and move constructors.
698 constexpr _Optional_base(const _Optional_base& __other) = default;
701 _Optional_base(_Optional_base&& __other)
702 noexcept(is_nothrow_move_constructible_v<_Tp>)
703 : _M_payload(__other._M_payload._M_engaged,
704 std::move(__other._M_payload))
707 // Assignment operators.
708 _Optional_base& operator=(const _Optional_base&) = default;
709 _Optional_base& operator=(_Optional_base&&) = default;
711 _Optional_payload<_Tp> _M_payload;
714 template<typename _Tp>
715 struct _Optional_base<_Tp, true, true> // trivial copy and move ctors
716 : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
718 // Constructors for disengaged optionals.
719 constexpr _Optional_base() = default;
721 // Constructors for engaged optionals.
722 template<typename... _Args,
723 enable_if_t<is_constructible_v<_Tp, _Args...>, bool> = false>
725 _Optional_base(in_place_t, _Args&&... __args)
726 : _M_payload(in_place, std::forward<_Args>(__args)...)
729 template<typename _Up, typename... _Args,
730 enable_if_t<is_constructible_v<_Tp,
731 initializer_list<_Up>&,
732 _Args...>, bool> = false>
734 _Optional_base(in_place_t,
735 initializer_list<_Up> __il,
737 : _M_payload(in_place, __il, std::forward<_Args>(__args)...)
740 // Copy and move constructors.
741 constexpr _Optional_base(const _Optional_base& __other) = default;
742 constexpr _Optional_base(_Optional_base&& __other) = default;
744 // Assignment operators.
745 _Optional_base& operator=(const _Optional_base&) = default;
746 _Optional_base& operator=(_Optional_base&&) = default;
748 _Optional_payload<_Tp> _M_payload;
750#endif // __cpp_concepts
752 template<typename _Tp>
753 inline constexpr bool __is_optional_v = false;
754 template<typename _Tp>
755 inline constexpr bool __is_optional_v<optional<_Tp>> = true;
757 template<typename _Tp, typename _Wp>
758 using __converts_from_any_cvref = __or_<
759 is_constructible<_Tp, _Wp&>, is_convertible<_Wp&, _Tp>,
760 is_constructible<_Tp, _Wp>, is_convertible<_Wp, _Tp>,
761 is_constructible<_Tp, const _Wp&>, is_convertible<const _Wp&, _Tp>,
762 is_constructible<_Tp, const _Wp>, is_convertible<const _Wp, _Tp>
765 template<typename _Tp, typename _Up>
766 using __converts_from_optional
767 = __converts_from_any_cvref<_Tp, optional<_Up>>;
769 template<typename _Tp, typename _Up>
770 using __assigns_from_optional =
771 __or_<is_assignable<_Tp&, const optional<_Up>&>,
772 is_assignable<_Tp&, optional<_Up>&>,
773 is_assignable<_Tp&, const optional<_Up>&&>,
774 is_assignable<_Tp&, optional<_Up>&&>>;
776#if __cpp_concepts && __cpp_conditional_explicit && __glibcxx_remove_cvref
777# define _GLIBCXX_USE_CONSTRAINTS_FOR_OPTIONAL 1
780 template<typename _Tp>
781 inline constexpr bool __is_valid_contained_type_for_optional =
783#if __cpp_lib_optional >= 202506L
784 is_lvalue_reference_v<_Tp> ||
786 (is_object_v<_Tp> && is_destructible_v<_Tp> && !is_array_v<_Tp>)
788 && !is_same_v<remove_cv_t<remove_reference_t<_Tp>>, nullopt_t>
789 && !is_same_v<remove_cv_t<remove_reference_t<_Tp>>, in_place_t>;
792 * @brief Class template for optional values.
794 template<typename _Tp>
796 : private _Optional_base<_Tp>,
797 private _Enable_copy_move<
799 is_copy_constructible_v<_Tp>,
801 __and_v<is_copy_constructible<_Tp>, is_copy_assignable<_Tp>>,
803 is_move_constructible_v<_Tp>,
805 __and_v<is_move_constructible<_Tp>, is_move_assignable<_Tp>>,
809 static_assert(__is_valid_contained_type_for_optional<_Tp>);
812 using _Base = _Optional_base<_Tp>;
816 // _GLIBCXX_RESOLVE_LIB_DEFECTS
817 // 3836. std::expected<bool, E1> conversion constructor
818 // expected(const expected<U, G>&) should take precedence over
819 // expected(U&&) with operator bool
820#ifdef _GLIBCXX_USE_CONSTRAINTS_FOR_OPTIONAL
821 template<typename _From, typename = remove_cv_t<_Tp>>
822 static constexpr bool __not_constructing_bool_from_optional
825 // If T is cv bool, remove_cvref_t<U> is not a specialization of optional
826 // i.e. do not initialize a bool from optional<U>::operator bool().
827 template<typename _From>
828 static constexpr bool
829 __not_constructing_bool_from_optional<_From, bool>
830 = !__is_optional_v<remove_cvref_t<_From>>;
832 // If T is not cv bool, converts-from-any-cvref<T, optional<U>> is false.
833 // The constructor that converts from optional<U> is disabled if the
834 // contained value can be initialized from optional<U>, so that the
835 // optional(U&&) constructor can be used instead.
836 template<typename _From, typename = remove_cv_t<_Tp>>
837 static constexpr bool __construct_from_contained_value
838 = !__converts_from_optional<_Tp, _From>::value;
840 // However, optional<U> can always be converted to bool, so don't apply
841 // this constraint when T is cv bool.
842 template<typename _From>
843 static constexpr bool __construct_from_contained_value<_From, bool>
846 template<typename _From, typename = remove_cv_t<_Tp>>
847 struct __not_constructing_bool_from_optional
851 template<typename _From>
852 struct __not_constructing_bool_from_optional<_From, bool>
853 : bool_constant<!__is_optional_v<__remove_cvref_t<_From>>>
856 template<typename _From, typename = remove_cv_t<_Tp>>
857 struct __construct_from_contained_value
858 : __not_<__converts_from_optional<_Tp, _From>>
861 template<typename _From>
862 struct __construct_from_contained_value<_From, bool>
866 template<typename _Up>
867 using __not_self = __not_<is_same<optional, __remove_cvref_t<_Up>>>;
868 template<typename _Up>
869 using __not_tag = __not_<is_same<in_place_t, __remove_cvref_t<_Up>>>;
870 template<typename... _Cond>
871 using _Requires = enable_if_t<__and_v<_Cond...>, bool>;
875 using value_type = _Tp;
876#ifdef __cpp_lib_optional_range_support // >= C++26
877 using iterator = __gnu_cxx::__normal_iterator<_Tp*, optional>;
878 using const_iterator = __gnu_cxx::__normal_iterator<const _Tp*, optional>;
881 constexpr optional() noexcept { }
883 constexpr optional(nullopt_t) noexcept { }
885 // Converting constructors for engaged optionals.
886#ifdef _GLIBCXX_USE_CONSTRAINTS_FOR_OPTIONAL
887 template<typename _Up = remove_cv_t<_Tp>>
888 requires (!is_same_v<optional, remove_cvref_t<_Up>>)
889 && (!is_same_v<in_place_t, remove_cvref_t<_Up>>)
890 && is_constructible_v<_Tp, _Up>
891 && __not_constructing_bool_from_optional<_Up>
892 constexpr explicit(!is_convertible_v<_Up, _Tp>)
894 noexcept(is_nothrow_constructible_v<_Tp, _Up>)
895 : _Base(std::in_place, std::forward<_Up>(__t)) { }
897 template<typename _Up>
898 requires (!is_same_v<_Tp, _Up>)
899 && is_constructible_v<_Tp, const _Up&>
900 && __construct_from_contained_value<_Up>
901 constexpr explicit(!is_convertible_v<const _Up&, _Tp>)
902 optional(const optional<_Up>& __t)
903 noexcept(is_nothrow_constructible_v<_Tp, const _Up&>)
906 emplace(__t._M_fwd());
909 template<typename _Up>
910 requires (!is_same_v<_Tp, _Up>)
911 && is_constructible_v<_Tp, _Up>
912 && __construct_from_contained_value<_Up>
913 constexpr explicit(!is_convertible_v<_Up, _Tp>)
914 optional(optional<_Up>&& __t)
915 noexcept(is_nothrow_constructible_v<_Tp, _Up>)
918 emplace(std::move(__t)._M_fwd());
921 template<typename... _Args>
922 requires is_constructible_v<_Tp, _Args...>
924 optional(in_place_t, _Args&&... __args)
925 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
926 : _Base(std::in_place, std::forward<_Args>(__args)...)
929 template<typename _Up, typename... _Args>
930 requires is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>
932 optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
933 noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&,
935 : _Base(std::in_place, __il, std::forward<_Args>(__args)...)
938 template<typename _Up = remove_cv_t<_Tp>,
939 _Requires<__not_self<_Up>, __not_tag<_Up>,
940 is_constructible<_Tp, _Up>,
941 is_convertible<_Up, _Tp>,
942 __not_constructing_bool_from_optional<_Up>> = true>
945 noexcept(is_nothrow_constructible_v<_Tp, _Up>)
946 : _Base(std::in_place, std::forward<_Up>(__t)) { }
948 template<typename _Up = remove_cv_t<_Tp>,
949 _Requires<__not_self<_Up>, __not_tag<_Up>,
950 is_constructible<_Tp, _Up>,
951 __not_<is_convertible<_Up, _Tp>>,
952 __not_constructing_bool_from_optional<_Up>> = false>
955 noexcept(is_nothrow_constructible_v<_Tp, _Up>)
956 : _Base(std::in_place, std::forward<_Up>(__t)) { }
958 template<typename _Up,
959 _Requires<__not_<is_same<_Tp, _Up>>,
960 is_constructible<_Tp, const _Up&>,
961 is_convertible<const _Up&, _Tp>,
962 __construct_from_contained_value<_Up>> = true>
964 optional(const optional<_Up>& __t)
965 noexcept(is_nothrow_constructible_v<_Tp, const _Up&>)
968 emplace(__t._M_fwd());
971 template<typename _Up,
972 _Requires<__not_<is_same<_Tp, _Up>>,
973 is_constructible<_Tp, const _Up&>,
974 __not_<is_convertible<const _Up&, _Tp>>,
975 __construct_from_contained_value<_Up>> = false>
977 optional(const optional<_Up>& __t)
978 noexcept(is_nothrow_constructible_v<_Tp, const _Up&>)
981 emplace(__t._M_fwd());
984 template<typename _Up,
985 _Requires<__not_<is_same<_Tp, _Up>>,
986 is_constructible<_Tp, _Up>,
987 is_convertible<_Up, _Tp>,
988 __construct_from_contained_value<_Up>> = true>
990 optional(optional<_Up>&& __t)
991 noexcept(is_nothrow_constructible_v<_Tp, _Up>)
994 emplace(std::move(__t)._M_fwd());
997 template<typename _Up,
998 _Requires<__not_<is_same<_Tp, _Up>>,
999 is_constructible<_Tp, _Up>,
1000 __not_<is_convertible<_Up, _Tp>>,
1001 __construct_from_contained_value<_Up>> = false>
1003 optional(optional<_Up>&& __t)
1004 noexcept(is_nothrow_constructible_v<_Tp, _Up>)
1007 emplace(std::move(__t)._M_fwd());
1010 template<typename... _Args,
1011 _Requires<is_constructible<_Tp, _Args...>> = false>
1013 optional(in_place_t, _Args&&... __args)
1014 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
1015 : _Base(std::in_place, std::forward<_Args>(__args)...) { }
1017 template<typename _Up, typename... _Args,
1018 _Requires<is_constructible<_Tp,
1019 initializer_list<_Up>&,
1022 optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
1023 noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&,
1025 : _Base(std::in_place, __il, std::forward<_Args>(__args)...) { }
1028 // Assignment operators.
1029 _GLIBCXX20_CONSTEXPR optional&
1030 operator=(nullopt_t) noexcept
1036 template<typename _Up = remove_cv_t<_Tp>>
1037#ifdef _GLIBCXX_USE_CONSTRAINTS_FOR_OPTIONAL
1038 requires (!is_same_v<optional, remove_cvref_t<_Up>>)
1039 && (!(is_scalar_v<_Tp> && is_same_v<_Tp, decay_t<_Up>>))
1040 && is_constructible_v<_Tp, _Up>
1041 && is_assignable_v<_Tp&, _Up>
1044 enable_if_t<__and_v<__not_self<_Up>,
1045 __not_<__and_<is_scalar<_Tp>,
1046 is_same<_Tp, decay_t<_Up>>>>,
1047 is_constructible<_Tp, _Up>,
1048 is_assignable<_Tp&, _Up>>,
1051 operator=(_Up&& __u)
1052 noexcept(__and_v<is_nothrow_constructible<_Tp, _Up>,
1053 is_nothrow_assignable<_Tp&, _Up>>)
1055 if (this->_M_is_engaged())
1056 this->_M_get() = std::forward<_Up>(__u);
1058 this->_M_construct(std::forward<_Up>(__u));
1063 template<typename _Up>
1064#ifdef _GLIBCXX_USE_CONSTRAINTS_FOR_OPTIONAL
1065 requires (!is_same_v<_Tp, _Up>)
1066 && is_constructible_v<_Tp, const _Up&>
1067 && is_assignable_v<_Tp&, const _Up&>
1068 && (!__converts_from_optional<_Tp, _Up>::value)
1069 && (!__assigns_from_optional<_Tp, _Up>::value)
1072 enable_if_t<__and_v<__not_<is_same<_Tp, _Up>>,
1073 is_constructible<_Tp, const _Up&>,
1074 is_assignable<_Tp&, const _Up&>,
1075 __not_<__converts_from_optional<_Tp, _Up>>,
1076 __not_<__assigns_from_optional<_Tp, _Up>>>,
1079 operator=(const optional<_Up>& __u)
1080 noexcept(__and_v<is_nothrow_constructible<_Tp, const _Up&>,
1081 is_nothrow_assignable<_Tp&, const _Up&>>)
1085 if (this->_M_is_engaged())
1086 this->_M_get() = __u._M_fwd();
1088 this->_M_construct(__u._M_fwd());
1097 template<typename _Up>
1098#ifdef _GLIBCXX_USE_CONSTRAINTS_FOR_OPTIONAL
1099 requires (!is_same_v<_Tp, _Up>)
1100 && is_constructible_v<_Tp, _Up>
1101 && is_assignable_v<_Tp&, _Up>
1102 && (!__converts_from_optional<_Tp, _Up>::value)
1103 && (!__assigns_from_optional<_Tp, _Up>::value)
1106 enable_if_t<__and_v<__not_<is_same<_Tp, _Up>>,
1107 is_constructible<_Tp, _Up>,
1108 is_assignable<_Tp&, _Up>,
1109 __not_<__converts_from_optional<_Tp, _Up>>,
1110 __not_<__assigns_from_optional<_Tp, _Up>>>,
1113 operator=(optional<_Up>&& __u)
1114 noexcept(__and_v<is_nothrow_constructible<_Tp, _Up>,
1115 is_nothrow_assignable<_Tp&, _Up>>)
1119 if (this->_M_is_engaged())
1120 this->_M_get() = std::move(__u)._M_fwd();
1122 this->_M_construct(std::move(__u)._M_fwd());
1132 template<typename... _Args>
1133 _GLIBCXX20_CONSTEXPR
1134 enable_if_t<is_constructible_v<_Tp, _Args...>, _Tp&>
1135 emplace(_Args&&... __args)
1136 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
1139 this->_M_construct(std::forward<_Args>(__args)...);
1140 return this->_M_get();
1143 template<typename _Up, typename... _Args>
1144 _GLIBCXX20_CONSTEXPR
1145 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>,
1147 emplace(initializer_list<_Up> __il, _Args&&... __args)
1148 noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&,
1152 this->_M_construct(__il, std::forward<_Args>(__args)...);
1153 return this->_M_get();
1156 // Destructor is implicit, implemented in _Optional_base.
1159 _GLIBCXX20_CONSTEXPR void
1160 swap(optional& __other)
1161 noexcept(is_nothrow_move_constructible_v<_Tp>
1162 && is_nothrow_swappable_v<_Tp>)
1166 if (this->_M_is_engaged() && __other._M_is_engaged())
1167 swap(this->_M_get(), __other._M_get());
1168 else if (this->_M_is_engaged())
1170 __other._M_construct(std::move(this->_M_get()));
1171 this->_M_destruct();
1173 else if (__other._M_is_engaged())
1175 this->_M_construct(std::move(__other._M_get()));
1176 __other._M_destruct();
1180#ifdef __cpp_lib_optional_range_support // >= C++26
1181 // Iterator support.
1182 constexpr iterator begin() noexcept
1185 this->_M_is_engaged() ? std::addressof(this->_M_get()) : nullptr
1189 constexpr const_iterator begin() const noexcept
1191 return const_iterator(
1192 this->_M_is_engaged() ? std::addressof(this->_M_get()) : nullptr
1196 constexpr iterator end() noexcept
1198 return begin() + has_value();
1201 constexpr const_iterator end() const noexcept
1203 return begin() + has_value();
1205#endif // __cpp_lib_optional_range_support
1208 constexpr const _Tp*
1209 operator->() const noexcept
1211 __glibcxx_assert(this->_M_is_engaged());
1212 return std::__addressof(this->_M_get());
1216 operator->() noexcept
1218 __glibcxx_assert(this->_M_is_engaged());
1219 return std::__addressof(this->_M_get());
1222 constexpr const _Tp&
1223 operator*() const& noexcept
1225 __glibcxx_assert(this->_M_is_engaged());
1226 return this->_M_get();
1230 operator*()& noexcept
1232 __glibcxx_assert(this->_M_is_engaged());
1233 return this->_M_get();
1237 operator*()&& noexcept
1239 __glibcxx_assert(this->_M_is_engaged());
1240 return std::move(this->_M_get());
1243 constexpr const _Tp&&
1244 operator*() const&& noexcept
1246 __glibcxx_assert(this->_M_is_engaged());
1247 return std::move(this->_M_get());
1250 constexpr explicit operator bool() const noexcept
1251 { return this->_M_is_engaged(); }
1253 constexpr bool has_value() const noexcept
1254 { return this->_M_is_engaged(); }
1256 constexpr const _Tp&
1259 if (this->_M_is_engaged())
1260 return this->_M_get();
1261 __throw_bad_optional_access();
1267 if (this->_M_is_engaged())
1268 return this->_M_get();
1269 __throw_bad_optional_access();
1275 if (this->_M_is_engaged())
1276 return std::move(this->_M_get());
1277 __throw_bad_optional_access();
1280 constexpr const _Tp&&
1283 if (this->_M_is_engaged())
1284 return std::move(this->_M_get());
1285 __throw_bad_optional_access();
1288 template<typename _Up = remove_cv_t<_Tp>>
1290 value_or(_Up&& __u) const&
1292 static_assert(is_copy_constructible_v<_Tp>);
1293 static_assert(is_convertible_v<_Up&&, _Tp>);
1295 if (this->_M_is_engaged())
1296 return this->_M_get();
1298 return static_cast<_Tp>(std::forward<_Up>(__u));
1301 template<typename _Up = remove_cv_t<_Tp>>
1303 value_or(_Up&& __u) &&
1305 static_assert(is_move_constructible_v<_Tp>);
1306 static_assert(is_convertible_v<_Up&&, _Tp>);
1308 if (this->_M_is_engaged())
1309 return std::move(this->_M_get());
1311 return static_cast<_Tp>(std::forward<_Up>(__u));
1314#if __cpp_lib_optional >= 202110L // C++23
1315 // [optional.monadic]
1317 template<typename _Fn>
1319 and_then(_Fn&& __f) &
1321 using _Up = remove_cvref_t<invoke_result_t<_Fn, _Tp&>>;
1322 static_assert(__is_optional_v<_Up>,
1323 "the function passed to std::optional<T>::and_then "
1324 "must return a std::optional");
1326 return std::__invoke(std::forward<_Fn>(__f), _M_get());
1331 template<typename _Fn>
1333 and_then(_Fn&& __f) const &
1335 using _Up = remove_cvref_t<invoke_result_t<_Fn, const _Tp&>>;
1336 static_assert(__is_optional_v<_Up>,
1337 "the function passed to std::optional<T>::and_then "
1338 "must return a std::optional");
1340 return std::__invoke(std::forward<_Fn>(__f), _M_get());
1345 template<typename _Fn>
1347 and_then(_Fn&& __f) &&
1349 using _Up = remove_cvref_t<invoke_result_t<_Fn, _Tp>>;
1350 static_assert(__is_optional_v<_Up>,
1351 "the function passed to std::optional<T>::and_then "
1352 "must return a std::optional");
1354 return std::__invoke(std::forward<_Fn>(__f), std::move(_M_get()));
1359 template<typename _Fn>
1361 and_then(_Fn&& __f) const &&
1363 using _Up = remove_cvref_t<invoke_result_t<_Fn, const _Tp>>;
1364 static_assert(__is_optional_v<_Up>,
1365 "the function passed to std::optional<T>::and_then "
1366 "must return a std::optional");
1368 return std::__invoke(std::forward<_Fn>(__f), std::move(_M_get()));
1373 template<typename _Fn>
1375 transform(_Fn&& __f) &
1377 using _Up = remove_cv_t<invoke_result_t<_Fn, _Tp&>>;
1379 return optional<_Up>(_Optional_func<_Fn>{__f}, _M_get());
1381 return optional<_Up>();
1384 template<typename _Fn>
1386 transform(_Fn&& __f) const &
1388 using _Up = remove_cv_t<invoke_result_t<_Fn, const _Tp&>>;
1390 return optional<_Up>(_Optional_func<_Fn>{__f}, _M_get());
1392 return optional<_Up>();
1395 template<typename _Fn>
1397 transform(_Fn&& __f) &&
1399 using _Up = remove_cv_t<invoke_result_t<_Fn, _Tp>>;
1401 return optional<_Up>(_Optional_func<_Fn>{__f}, std::move(_M_get()));
1403 return optional<_Up>();
1406 template<typename _Fn>
1408 transform(_Fn&& __f) const &&
1410 using _Up = remove_cv_t<invoke_result_t<_Fn, const _Tp>>;
1412 return optional<_Up>(_Optional_func<_Fn>{__f}, std::move(_M_get()));
1414 return optional<_Up>();
1417 template<typename _Fn> requires invocable<_Fn> && copy_constructible<_Tp>
1419 or_else(_Fn&& __f) const&
1421 using _Up = invoke_result_t<_Fn>;
1422 static_assert(is_same_v<remove_cvref_t<_Up>, optional>,
1423 "the function passed to std::optional<T>::or_else "
1424 "must return a std::optional<T>");
1429 return std::forward<_Fn>(__f)();
1432 template<typename _Fn> requires invocable<_Fn> && move_constructible<_Tp>
1434 or_else(_Fn&& __f) &&
1436 using _Up = invoke_result_t<_Fn>;
1437 static_assert(is_same_v<remove_cvref_t<_Up>, optional>,
1438 "the function passed to std::optional<T>::or_else "
1439 "must return a std::optional<T>");
1442 return std::move(*this);
1444 return std::forward<_Fn>(__f)();
1448 _GLIBCXX20_CONSTEXPR void reset() noexcept { this->_M_reset(); }
1451 using _Base::_M_get;
1453 [[__gnu__::__always_inline__]]
1456 { return _M_get(); }
1458 [[__gnu__::__always_inline__]]
1460 _M_fwd() && noexcept
1461 { return std::move(_M_get()); }
1463 [[__gnu__::__always_inline__]]
1464 constexpr const _Tp&
1465 _M_fwd() const& noexcept
1466 { return _M_get(); }
1468 [[__gnu__::__always_inline__]]
1469 constexpr const _Tp&&
1470 _M_fwd() const&& noexcept
1471 { return std::move(_M_get()); }
1473 template<typename _Up> friend class optional;
1475#if __cpp_lib_optional >= 202110L // C++23
1476 template<typename _Fn, typename _Value>
1478 optional(_Optional_func<_Fn> __f, _Value&& __v)
1480 this->_M_payload._M_apply(__f, std::forward<_Value>(__v));
1485#if __cpp_lib_optional >= 202506L // C++26
1486 template<typename _Tp>
1487 class optional<_Tp&>
1489 static_assert(__is_valid_contained_type_for_optional<_Tp&>);
1492 using value_type = _Tp;
1493 using iterator = __gnu_cxx::__normal_iterator<_Tp*, optional>;
1496 constexpr optional() noexcept = default;
1497 constexpr optional(nullopt_t) noexcept : optional() {}
1498 constexpr optional(const optional&) noexcept = default;
1500 template<typename _Arg>
1501 requires is_constructible_v<_Tp&, _Arg>
1502 && (!reference_constructs_from_temporary_v<_Tp&, _Arg>)
1504 optional(in_place_t, _Arg&& __arg)
1506 __convert_ref_init_val(std::forward<_Arg>(__arg));
1509 template<typename _Up>
1510 requires (!is_same_v<remove_cvref_t<_Up>, optional>)
1511 && (!is_same_v<remove_cvref_t<_Up>, in_place_t>)
1512 && is_constructible_v<_Tp&, _Up>
1513 && (!reference_constructs_from_temporary_v<_Tp&, _Up>)
1514 explicit(!is_convertible_v<_Up, _Tp&>)
1517 noexcept(is_nothrow_constructible_v<_Tp&, _Up>)
1519 __convert_ref_init_val(std::forward<_Up>(__u));
1522 template<typename _Up>
1523 requires (!is_same_v<remove_cvref_t<_Up>, optional>)
1524 && (!is_same_v<remove_cvref_t<_Up>, in_place_t>)
1525 && is_constructible_v<_Tp&, _Up>
1526 && reference_constructs_from_temporary_v<_Tp&, _Up>
1527 explicit(!is_convertible_v<_Up, _Tp&>)
1529 optional(_Up&& __u) = delete;
1532 template<typename _Up>
1533 requires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)
1534 && (!is_same_v<_Tp&, _Up>)
1535 && is_constructible_v<_Tp&, _Up&>
1536 && (!reference_constructs_from_temporary_v<_Tp&, _Up&>)
1537 explicit(!is_convertible_v<_Up&, _Tp&>)
1539 optional(optional<_Up>& __rhs)
1540 noexcept(is_nothrow_constructible_v<_Tp&, _Up&>)
1543 __convert_ref_init_val(__rhs._M_fwd());
1546 template<typename _Up>
1547 requires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)
1548 && (!is_same_v<_Tp&, _Up>)
1549 && is_constructible_v<_Tp&, _Up&>
1550 && reference_constructs_from_temporary_v<_Tp&, _Up&>
1551 explicit(!is_convertible_v<_Up&, _Tp&>)
1553 optional(optional<_Up>& __rhs) = delete;
1555 // const optional<U>&
1556 template<typename _Up>
1557 requires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)
1558 && (!is_same_v<_Tp&, _Up>)
1559 && is_constructible_v<_Tp&, const _Up&>
1560 && (!reference_constructs_from_temporary_v<_Tp&, const _Up&>)
1561 explicit(!is_convertible_v<const _Up&, _Tp&>)
1563 optional(const optional<_Up>& __rhs)
1564 noexcept(is_nothrow_constructible_v<_Tp&, _Up&>)
1567 __convert_ref_init_val(__rhs._M_fwd());
1570 template<typename _Up>
1571 requires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)
1572 && (!is_same_v<_Tp&, _Up>)
1573 && is_constructible_v<_Tp&, const _Up&>
1574 && reference_constructs_from_temporary_v<_Tp&, const _Up&>
1575 explicit(!is_convertible_v<const _Up&, _Tp&>)
1577 optional(const optional<_Up>& __rhs) = delete;
1580 template<typename _Up>
1581 requires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)
1582 && (!is_same_v<_Tp&, _Up>)
1583 && is_constructible_v<_Tp&, _Up>
1584 && (!reference_constructs_from_temporary_v<_Tp&, _Up>)
1585 explicit(!is_convertible_v<_Up, _Tp&>)
1587 optional(optional<_Up>&& __rhs)
1588 noexcept(is_nothrow_constructible_v<_Tp&, _Up>)
1591 __convert_ref_init_val(std::move(__rhs)._M_fwd());
1594 template<typename _Up>
1595 requires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)
1596 && (!is_same_v<_Tp&, _Up>)
1597 && is_constructible_v<_Tp&, _Up>
1598 && reference_constructs_from_temporary_v<_Tp&, _Up>
1599 explicit(!is_convertible_v<_Up, _Tp&>)
1601 optional(optional<_Up>&& __rhs) = delete;
1603 // const optional<U>&&
1604 template<typename _Up>
1605 requires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)
1606 && (!is_same_v<_Tp&, _Up>)
1607 && is_constructible_v<_Tp&, const _Up>
1608 && (!reference_constructs_from_temporary_v<_Tp&, _Up>)
1609 explicit(!is_convertible_v<const _Up, _Tp&>)
1611 optional(const optional<_Up>&& __rhs)
1612 noexcept(is_nothrow_constructible_v<_Tp&, const _Up>)
1615 __convert_ref_init_val(std::move(__rhs)._M_fwd());
1618 template<typename _Up>
1619 requires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)
1620 && (!is_same_v<_Tp&, _Up>)
1621 && is_constructible_v<_Tp&, const _Up>
1622 && reference_constructs_from_temporary_v<_Tp&, const _Up>
1623 explicit(!is_convertible_v<const _Up, _Tp&>)
1625 optional(const optional<_Up>&& __rhs) = delete;
1627 constexpr ~optional() = default;
1630 constexpr optional& operator=(nullopt_t) noexcept
1636 constexpr optional& operator=(const optional&) noexcept = default;
1638 template<typename _Up>
1639 requires is_constructible_v<_Tp&, _Up>
1640 && (!reference_constructs_from_temporary_v<_Tp&, _Up>)
1643 noexcept(is_nothrow_constructible_v<_Tp&, _Up>)
1645 __convert_ref_init_val(std::forward<_Up>(__u));
1646 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1647 // 4300. Missing Returns: element in optional<T&>::emplace
1652 constexpr void swap(optional& __rhs) noexcept
1653 { std::swap(_M_val, __rhs._M_val); }
1655 // Iterator support.
1656 constexpr iterator begin() const noexcept
1658 return iterator(_M_val);
1661 constexpr iterator end() const noexcept
1663 return begin() + has_value();
1667 constexpr _Tp* operator->() const noexcept
1669 __glibcxx_assert(_M_val); // hardened precondition
1673 constexpr _Tp& operator*() const noexcept
1675 __glibcxx_assert(_M_val); // hardened precondition
1679 constexpr explicit operator bool() const noexcept
1684 constexpr bool has_value() const noexcept
1689 constexpr _Tp& value() const
1693 __throw_bad_optional_access();
1696 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1697 // 4304. std::optional<NonReturnable&> is ill-formed due to value_or
1698 template<typename _Up = remove_cv_t<_Tp>>
1699 requires is_object_v<_Tp> && (!is_array_v<_Tp>)
1700 constexpr decay_t<_Tp>
1701 value_or(_Up&& __u) const
1703 using _Xp = remove_cv_t<_Tp>;
1704 static_assert(is_constructible_v<_Xp, _Tp&>);
1705 static_assert(is_convertible_v<_Up, _Xp>);
1706 return _M_val ? *_M_val : static_cast<_Xp>(std::forward<_Up>(__u));
1709 // Monadic operations.
1710 template<typename _Fn>
1712 and_then(_Fn&& __f) const
1714 using _Up = remove_cvref_t<invoke_result_t<_Fn, _Tp&>>;
1715 static_assert(__is_optional_v<_Up>,
1716 "the function passed to std::optional<T&>::and_then "
1717 "must return a std::optional");
1719 return std::__invoke(std::forward<_Fn>(__f), *_M_val);
1724 template<typename _Fn>
1726 optional<remove_cv_t<invoke_result_t<_Fn, _Tp&>>>
1727 transform(_Fn&& __f) const
1729 using _Up = remove_cv_t<invoke_result_t<_Fn, _Tp&>>;
1731 return optional<_Up>(_Optional_func<_Fn>{__f}, *_M_val);
1733 return optional<_Up>();
1736 template<typename _Fn>
1737 requires invocable<_Fn>
1740 or_else(_Fn&& __f) const
1742 static_assert(is_same_v<remove_cvref_t<invoke_result_t<_Fn>>, optional>,
1743 "the function passed to std::optional<T&>::or_else "
1744 "must return a std::optional<T&>");
1745 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1746 // 4367. Improve optional<T&>::or_else
1750 return std::forward<_Fn>(__f)();
1754 constexpr void reset() noexcept
1760 _Tp *_M_val = nullptr;
1762 [[__gnu__::__always_inline__]]
1764 _M_fwd() const noexcept
1767 template<typename _Up> friend class optional;
1769 template<typename _Up>
1772 __convert_ref_init_val(_Up&& __u)
1775 _Tp& __r(std::forward<_Up>(__u));
1776 _M_val = std::addressof(__r);
1779 template<typename _Fn, typename _Value>
1781 optional(_Optional_func<_Fn> __f, _Value&& __v)
1783 _Tp& __r = std::__invoke(std::forward<_Fn>(__f._M_f), std::forward<_Value>(__v));
1784 _M_val = std::addressof(__r);
1787#endif // __cpp_lib_optional >= 202506L
1789 template<typename _Tp>
1790 using __optional_relop_t =
1791 enable_if_t<is_convertible_v<_Tp, bool>, bool>;
1793 template<typename _Tp, typename _Up>
1794 using __optional_eq_t = __optional_relop_t<
1795 decltype(std::declval<const _Tp&>() == std::declval<const _Up&>())
1798 template<typename _Tp, typename _Up>
1799 using __optional_ne_t = __optional_relop_t<
1800 decltype(std::declval<const _Tp&>() != std::declval<const _Up&>())
1803 template<typename _Tp, typename _Up>
1804 using __optional_lt_t = __optional_relop_t<
1805 decltype(std::declval<const _Tp&>() < std::declval<const _Up&>())
1808 template<typename _Tp, typename _Up>
1809 using __optional_gt_t = __optional_relop_t<
1810 decltype(std::declval<const _Tp&>() > std::declval<const _Up&>())
1813 template<typename _Tp, typename _Up>
1814 using __optional_le_t = __optional_relop_t<
1815 decltype(std::declval<const _Tp&>() <= std::declval<const _Up&>())
1818 template<typename _Tp, typename _Up>
1819 using __optional_ge_t = __optional_relop_t<
1820 decltype(std::declval<const _Tp&>() >= std::declval<const _Up&>())
1823 // Comparisons between optional values.
1824 template<typename _Tp, typename _Up>
1826 operator==(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1827 -> __optional_eq_t<_Tp, _Up>
1829 return static_cast<bool>(__lhs) == static_cast<bool>(__rhs)
1830 && (!__lhs || *__lhs == *__rhs);
1833 template<typename _Tp, typename _Up>
1835 operator!=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1836 -> __optional_ne_t<_Tp, _Up>
1838 return static_cast<bool>(__lhs) != static_cast<bool>(__rhs)
1839 || (static_cast<bool>(__lhs) && *__lhs != *__rhs);
1842 template<typename _Tp, typename _Up>
1844 operator<(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1845 -> __optional_lt_t<_Tp, _Up>
1847 return static_cast<bool>(__rhs) && (!__lhs || *__lhs < *__rhs);
1850 template<typename _Tp, typename _Up>
1852 operator>(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1853 -> __optional_gt_t<_Tp, _Up>
1855 return static_cast<bool>(__lhs) && (!__rhs || *__lhs > *__rhs);
1858 template<typename _Tp, typename _Up>
1860 operator<=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1861 -> __optional_le_t<_Tp, _Up>
1863 return !__lhs || (static_cast<bool>(__rhs) && *__lhs <= *__rhs);
1866 template<typename _Tp, typename _Up>
1868 operator>=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1869 -> __optional_ge_t<_Tp, _Up>
1871 return !__rhs || (static_cast<bool>(__lhs) && *__lhs >= *__rhs);
1874#ifdef __cpp_lib_three_way_comparison
1875 template<typename _Tp, three_way_comparable_with<_Tp> _Up>
1877 constexpr compare_three_way_result_t<_Tp, _Up>
1878 operator<=>(const optional<_Tp>& __x, const optional<_Up>& __y)
1880 return __x && __y ? *__x <=> *__y : bool(__x) <=> bool(__y);
1884 // Comparisons with nullopt.
1885 template<typename _Tp>
1888 operator==(const optional<_Tp>& __lhs, nullopt_t) noexcept
1891#ifdef __cpp_lib_three_way_comparison
1892 template<typename _Tp>
1894 constexpr strong_ordering
1895 operator<=>(const optional<_Tp>& __x, nullopt_t) noexcept
1896 { return bool(__x) <=> false; }
1898 template<typename _Tp>
1900 operator==(nullopt_t, const optional<_Tp>& __rhs) noexcept
1903 template<typename _Tp>
1905 operator!=(const optional<_Tp>& __lhs, nullopt_t) noexcept
1906 { return static_cast<bool>(__lhs); }
1908 template<typename _Tp>
1910 operator!=(nullopt_t, const optional<_Tp>& __rhs) noexcept
1911 { return static_cast<bool>(__rhs); }
1913 template<typename _Tp>
1915 operator<(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept
1918 template<typename _Tp>
1920 operator<(nullopt_t, const optional<_Tp>& __rhs) noexcept
1921 { return static_cast<bool>(__rhs); }
1923 template<typename _Tp>
1925 operator>(const optional<_Tp>& __lhs, nullopt_t) noexcept
1926 { return static_cast<bool>(__lhs); }
1928 template<typename _Tp>
1930 operator>(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept
1933 template<typename _Tp>
1935 operator<=(const optional<_Tp>& __lhs, nullopt_t) noexcept
1938 template<typename _Tp>
1940 operator<=(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept
1943 template<typename _Tp>
1945 operator>=(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept
1948 template<typename _Tp>
1950 operator>=(nullopt_t, const optional<_Tp>& __rhs) noexcept
1952#endif // three-way-comparison
1954#if __cpp_lib_concepts
1955 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1956 // 4072. std::optional comparisons: constrain harder
1957# define _REQUIRES_NOT_OPTIONAL(T) requires (!__is_optional_v<T>)
1959# define _REQUIRES_NOT_OPTIONAL(T)
1962 // Comparisons with value type.
1963 template<typename _Tp, typename _Up>
1964 _REQUIRES_NOT_OPTIONAL(_Up)
1966 operator== [[nodiscard]] (const optional<_Tp>& __lhs, const _Up& __rhs)
1967 -> __optional_eq_t<_Tp, _Up>
1968 { return __lhs && *__lhs == __rhs; }
1970 template<typename _Tp, typename _Up>
1971 _REQUIRES_NOT_OPTIONAL(_Tp)
1973 operator== [[nodiscard]] (const _Tp& __lhs, const optional<_Up>& __rhs)
1974 -> __optional_eq_t<_Tp, _Up>
1975 { return __rhs && __lhs == *__rhs; }
1977 template<typename _Tp, typename _Up>
1978 _REQUIRES_NOT_OPTIONAL(_Up)
1980 operator!= [[nodiscard]] (const optional<_Tp>& __lhs, const _Up& __rhs)
1981 -> __optional_ne_t<_Tp, _Up>
1982 { return !__lhs || *__lhs != __rhs; }
1984 template<typename _Tp, typename _Up>
1985 _REQUIRES_NOT_OPTIONAL(_Tp)
1987 operator!= [[nodiscard]] (const _Tp& __lhs, const optional<_Up>& __rhs)
1988 -> __optional_ne_t<_Tp, _Up>
1989 { return !__rhs || __lhs != *__rhs; }
1991 template<typename _Tp, typename _Up>
1992 _REQUIRES_NOT_OPTIONAL(_Up)
1994 operator< [[nodiscard]] (const optional<_Tp>& __lhs, const _Up& __rhs)
1995 -> __optional_lt_t<_Tp, _Up>
1996 { return !__lhs || *__lhs < __rhs; }
1998 template<typename _Tp, typename _Up>
1999 _REQUIRES_NOT_OPTIONAL(_Tp)
2001 operator< [[nodiscard]] (const _Tp& __lhs, const optional<_Up>& __rhs)
2002 -> __optional_lt_t<_Tp, _Up>
2003 { return __rhs && __lhs < *__rhs; }
2005 template<typename _Tp, typename _Up>
2006 _REQUIRES_NOT_OPTIONAL(_Up)
2008 operator> [[nodiscard]] (const optional<_Tp>& __lhs, const _Up& __rhs)
2009 -> __optional_gt_t<_Tp, _Up>
2010 { return __lhs && *__lhs > __rhs; }
2012 template<typename _Tp, typename _Up>
2013 _REQUIRES_NOT_OPTIONAL(_Tp)
2015 operator> [[nodiscard]] (const _Tp& __lhs, const optional<_Up>& __rhs)
2016 -> __optional_gt_t<_Tp, _Up>
2017 { return !__rhs || __lhs > *__rhs; }
2019 template<typename _Tp, typename _Up>
2020 _REQUIRES_NOT_OPTIONAL(_Up)
2022 operator<= [[nodiscard]] (const optional<_Tp>& __lhs, const _Up& __rhs)
2023 -> __optional_le_t<_Tp, _Up>
2024 { return !__lhs || *__lhs <= __rhs; }
2026 template<typename _Tp, typename _Up>
2027 _REQUIRES_NOT_OPTIONAL(_Tp)
2029 operator<= [[nodiscard]] (const _Tp& __lhs, const optional<_Up>& __rhs)
2030 -> __optional_le_t<_Tp, _Up>
2031 { return __rhs && __lhs <= *__rhs; }
2033 template<typename _Tp, typename _Up>
2034 _REQUIRES_NOT_OPTIONAL(_Up)
2036 operator>= [[nodiscard]] (const optional<_Tp>& __lhs, const _Up& __rhs)
2037 -> __optional_ge_t<_Tp, _Up>
2038 { return __lhs && *__lhs >= __rhs; }
2040 template<typename _Tp, typename _Up>
2041 _REQUIRES_NOT_OPTIONAL(_Tp)
2043 operator>= [[nodiscard]] (const _Tp& __lhs, const optional<_Up>& __rhs)
2044 -> __optional_ge_t<_Tp, _Up>
2045 { return !__rhs || __lhs >= *__rhs; }
2047#ifdef __cpp_lib_three_way_comparison
2048 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2049 // 3746. optional's spaceship with U with a type derived from optional
2050 // causes infinite constraint meta-recursion
2051 template<typename _Tp>
2052 concept __is_derived_from_optional = requires (const _Tp& __t) {
2053 []<typename _Up>(const optional<_Up>&){ }(__t);
2056 template<typename _Tp, typename _Up>
2057 requires (!__is_derived_from_optional<_Up>)
2058 && requires { typename compare_three_way_result_t<_Tp, _Up>; }
2059 && three_way_comparable_with<_Tp, _Up>
2060 constexpr compare_three_way_result_t<_Tp, _Up>
2061 operator<=> [[nodiscard]] (const optional<_Tp>& __x, const _Up& __v)
2062 { return bool(__x) ? *__x <=> __v : strong_ordering::less; }
2065 // Swap and creation functions.
2067 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2068 // 2748. swappable traits for optionals
2069 template<typename _Tp>
2070 _GLIBCXX20_CONSTEXPR
2071 inline enable_if_t<is_move_constructible_v<_Tp> && is_swappable_v<_Tp>>
2072 swap(optional<_Tp>& __lhs, optional<_Tp>& __rhs)
2073 noexcept(noexcept(__lhs.swap(__rhs)))
2074 { __lhs.swap(__rhs); }
2076#if __cpp_lib_optional >= 202506L
2077 // We deviate from standard, that do not declared separate swap overload
2078 // from optional<T&>.
2079 template<typename _Tp>
2081 swap(optional<_Tp&>& __lhs, optional<_Tp&>& __rhs) noexcept
2082 { __lhs.swap(__rhs); }
2085 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2086 // 2766. Swapping non-swappable types
2087 template<typename _Tp>
2088 enable_if_t<!(is_move_constructible_v<_Tp> && is_swappable_v<_Tp>)>
2089 swap(optional<_Tp>&, optional<_Tp>&) = delete;
2091#if __cpp_lib_optional >= 202506L
2092 template<int = 0, typename _Tp>
2094 template<typename _Tp>
2097 enable_if_t<is_constructible_v<decay_t<_Tp>, _Tp>,
2098 optional<decay_t<_Tp>>>
2099 make_optional(_Tp&& __t)
2100 noexcept(is_nothrow_constructible_v<optional<decay_t<_Tp>>, _Tp>)
2101 { return optional<decay_t<_Tp>>( std::forward<_Tp>(__t) ); }
2103 template<typename _Tp, typename... _Args>
2105 enable_if_t<is_constructible_v<_Tp, _Args...>,
2107 make_optional(_Args&&... __args)
2108 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
2109 { return optional<_Tp>( in_place, std::forward<_Args>(__args)... ); }
2111 template<typename _Tp, typename _Up, typename... _Args>
2113 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>,
2115 make_optional(initializer_list<_Up> __il, _Args&&... __args)
2116 noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, _Args...>)
2117 { return optional<_Tp>( in_place, __il, std::forward<_Args>(__args)... ); }
2121 template<typename _Tp, typename _Up = remove_const_t<_Tp>>
2122 struct __optional_hash
2123#if ! _GLIBCXX_INLINE_VERSION
2124 : public __hash_empty_base<_Up>
2127#if __cplusplus < 202002L
2128 using result_type [[__deprecated__]] = size_t;
2129 using argument_type [[__deprecated__]] = optional<_Tp>;
2133 operator()(const optional<_Tp>& __t) const
2134 noexcept(noexcept(hash<_Up>{}(*__t)))
2136 // We pick an arbitrary hash for disengaged optionals which hopefully
2137 // usual values of _Tp won't typically hash to.
2138 constexpr size_t __magic_disengaged_hash = static_cast<size_t>(-3333);
2139 return __t ? hash<_Up>{}(*__t) : __magic_disengaged_hash;
2143 template<typename _Tp>
2144 struct hash<optional<_Tp>>
2145 // hash for optional<T&> is disabled because is_hash_enabled_for<T&> is false
2146 : public __conditional_t<__is_hash_enabled_for<remove_const_t<_Tp>>,
2147 __optional_hash<_Tp>,
2148 __hash_not_enabled<_Tp>>
2151 template<typename _Tp>
2152 struct __is_fast_hash<hash<optional<_Tp>>> : __is_fast_hash<hash<_Tp>>
2157#if __cpp_deduction_guides >= 201606
2158 template <typename _Tp> optional(_Tp) -> optional<_Tp>;
2161#ifdef __cpp_lib_optional_range_support // >= C++26
2162 template<typename _Tp>
2163 inline constexpr bool
2164 ranges::enable_view<optional<_Tp>> = true;
2166 template<typename _Tp>
2167 inline constexpr range_format
2168 format_kind<optional<_Tp>> = range_format::disabled;
2169#endif // __cpp_lib_optional_range_support
2171#undef _GLIBCXX_USE_CONSTRAINTS_FOR_OPTIONAL
2173_GLIBCXX_END_NAMESPACE_VERSION
2176#endif // __cpp_lib_optional
2178#endif // _GLIBCXX_OPTIONAL