LCOV - code coverage report
Current view: top level - /usr/include/c++/14 - optional (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 29.4 % 17 5
Test Date: 2026-02-27 05:14:50 Functions: 55.6 % 9 5
Legend: Lines:     hit not hit

            Line data    Source code
       1              : // <optional> -*- C++ -*-
       2              : 
       3              : // Copyright (C) 2013-2024 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              : #pragma GCC system_header
      34              : 
      35              : #define __glibcxx_want_freestanding_optional
      36              : #define __glibcxx_want_optional
      37              : #include <bits/version.h>
      38              : 
      39              : #ifdef __cpp_lib_optional // C++ >= 17
      40              : 
      41              : #include <type_traits>
      42              : #include <exception>
      43              : #include <new>
      44              : #include <initializer_list>
      45              : #include <bits/enable_special_members.h>
      46              : #include <bits/exception_defines.h>
      47              : #include <bits/functional_hash.h>
      48              : #include <bits/stl_construct.h> // _Construct
      49              : #include <bits/utility.h> // in_place_t
      50              : #if __cplusplus > 201703L
      51              : # include <compare>
      52              : # include <bits/invoke.h> // std::__invoke
      53              : #endif
      54              : #if __cplusplus > 202002L
      55              : # include <concepts>
      56              : #endif
      57              : 
      58              : namespace std _GLIBCXX_VISIBILITY(default)
      59              : {
      60              : _GLIBCXX_BEGIN_NAMESPACE_VERSION
      61              : 
      62              :   /**
      63              :    *  @addtogroup utilities
      64              :    *  @{
      65              :    */
      66              : 
      67              :   template<typename _Tp>
      68              :     class optional;
      69              : 
      70              :   /// Tag type to disengage optional objects.
      71              :   struct nullopt_t
      72              :   {
      73              :     // Do not user-declare default constructor at all for
      74              :     // optional_value = {} syntax to work.
      75              :     // nullopt_t() = delete;
      76              : 
      77              :     // Used for constructing nullopt.
      78              :     enum class _Construct { _Token };
      79              : 
      80              :     // Must be constexpr for nullopt_t to be literal.
      81              :     explicit constexpr nullopt_t(_Construct) noexcept { }
      82              :   };
      83              : 
      84              :   /// Tag to disengage optional objects.
      85              :   inline constexpr nullopt_t nullopt { nullopt_t::_Construct::_Token };
      86              : 
      87              :   template<typename _Fn> struct _Optional_func { _Fn& _M_f; };
      88              : 
      89              :   /**
      90              :    *  @brief Exception class thrown when a disengaged optional object is
      91              :    *  dereferenced.
      92              :    *  @ingroup exceptions
      93              :    */
      94              :   class bad_optional_access : public exception
      95              :   {
      96              :   public:
      97              :     bad_optional_access() = default;
      98              :     virtual ~bad_optional_access() = default;
      99              : 
     100              :     const char* what() const noexcept override
     101              :     { return "bad optional access"; }
     102              :   };
     103              : 
     104              :   // XXX Does not belong here.
     105              :   [[__noreturn__]] inline void
     106              :   __throw_bad_optional_access()
     107              :   { _GLIBCXX_THROW_OR_ABORT(bad_optional_access()); }
     108              : 
     109              :   // This class template manages construction/destruction of
     110              :   // the contained value for a std::optional.
     111              :   template <typename _Tp>
     112              :     struct _Optional_payload_base
     113              :     {
     114              :       using _Stored_type = remove_const_t<_Tp>;
     115              : 
     116           45 :       _Optional_payload_base() = default;
     117              :       ~_Optional_payload_base() = default;
     118              : 
     119              :       template<typename... _Args>
     120              :     constexpr
     121            0 :     _Optional_payload_base(in_place_t __tag, _Args&&... __args)
     122            0 :     : _M_payload(__tag, std::forward<_Args>(__args)...),
     123            0 :       _M_engaged(true)
     124            0 :     { }
     125              : 
     126              :       template<typename _Up, typename... _Args>
     127              :     constexpr
     128              :     _Optional_payload_base(std::initializer_list<_Up> __il,
     129              :                    _Args&&... __args)
     130              :     : _M_payload(__il, std::forward<_Args>(__args)...),
     131              :       _M_engaged(true)
     132              :     { }
     133              : 
     134              :       // Constructor used by _Optional_base copy constructor when the
     135              :       // contained value is not trivially copy constructible.
     136              :       constexpr
     137              :       _Optional_payload_base(bool /* __engaged */,
     138              :                  const _Optional_payload_base& __other)
     139              :       {
     140              :     if (__other._M_engaged)
     141              :       this->_M_construct(__other._M_get());
     142              :       }
     143              : 
     144              :       // Constructor used by _Optional_base move constructor when the
     145              :       // contained value is not trivially move constructible.
     146              :       constexpr
     147              :       _Optional_payload_base(bool /* __engaged */,
     148              :                  _Optional_payload_base&& __other)
     149              :       {
     150              :     if (__other._M_engaged)
     151              :       this->_M_construct(std::move(__other._M_get()));
     152              :       }
     153              : 
     154              :       // Copy constructor is only used to when the contained value is
     155              :       // trivially copy constructible.
     156              :       _Optional_payload_base(const _Optional_payload_base&) = default;
     157              : 
     158              :       // Move constructor is only used to when the contained value is
     159              :       // trivially copy constructible.
     160              :       _Optional_payload_base(_Optional_payload_base&&) = default;
     161              : 
     162              :       _Optional_payload_base&
     163              :       operator=(const _Optional_payload_base&) = default;
     164              : 
     165              :       _Optional_payload_base&
     166              :       operator=(_Optional_payload_base&&) = default;
     167              : 
     168              :       // used to perform non-trivial copy assignment.
     169              :       constexpr void
     170              :       _M_copy_assign(const _Optional_payload_base& __other)
     171              :       {
     172              :     if (this->_M_engaged && __other._M_engaged)
     173              :       this->_M_get() = __other._M_get();
     174              :     else
     175              :       {
     176              :         if (__other._M_engaged)
     177              :           this->_M_construct(__other._M_get());
     178              :         else
     179              :           this->_M_reset();
     180              :       }
     181              :       }
     182              : 
     183              :       // used to perform non-trivial move assignment.
     184              :       constexpr void
     185              :       _M_move_assign(_Optional_payload_base&& __other)
     186              :       noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
     187              :                is_nothrow_move_assignable<_Tp>>)
     188              :       {
     189              :     if (this->_M_engaged && __other._M_engaged)
     190              :       this->_M_get() = std::move(__other._M_get());
     191              :     else
     192              :       {
     193              :         if (__other._M_engaged)
     194              :           this->_M_construct(std::move(__other._M_get()));
     195              :         else
     196              :           this->_M_reset();
     197              :       }
     198              :       }
     199              : 
     200              :       struct _Empty_byte { };
     201              : 
     202              :       template<typename _Up, bool = is_trivially_destructible_v<_Up>>
     203              :     union _Storage
     204              :     {
     205           45 :       constexpr _Storage() noexcept : _M_empty() { }
     206              : 
     207              :       template<typename... _Args>
     208              :         constexpr
     209            0 :         _Storage(in_place_t, _Args&&... __args)
     210            0 :         : _M_value(std::forward<_Args>(__args)...)
     211            0 :         { }
     212              : 
     213              :       template<typename _Vp, typename... _Args>
     214              :         constexpr
     215              :         _Storage(std::initializer_list<_Vp> __il, _Args&&... __args)
     216              :         : _M_value(__il, std::forward<_Args>(__args)...)
     217              :         { }
     218              : 
     219              : #if __cplusplus >= 202002L
     220              :       template<typename _Fn, typename _Arg>
     221              :         constexpr
     222              :         _Storage(_Optional_func<_Fn> __f, _Arg&& __arg)
     223              :         : _M_value(std::__invoke(std::forward<_Fn>(__f._M_f),
     224              :                      std::forward<_Arg>(__arg)))
     225              :         { }
     226              : #endif
     227              : 
     228              :       _Empty_byte _M_empty;
     229              :       _Up _M_value;
     230              :     };
     231              : 
     232              :       template<typename _Up>
     233              :     union _Storage<_Up, false>
     234              :     {
     235              :       constexpr _Storage() noexcept : _M_empty() { }
     236              : 
     237              :       template<typename... _Args>
     238              :         constexpr
     239              :         _Storage(in_place_t, _Args&&... __args)
     240              :         : _M_value(std::forward<_Args>(__args)...)
     241              :         { }
     242              : 
     243              :       template<typename _Vp, typename... _Args>
     244              :         constexpr
     245              :         _Storage(std::initializer_list<_Vp> __il, _Args&&... __args)
     246              :         : _M_value(__il, std::forward<_Args>(__args)...)
     247              :         { }
     248              : 
     249              : #if __cplusplus >= 202002L
     250              :       template<typename _Fn, typename _Arg>
     251              :         constexpr
     252              :         _Storage(_Optional_func<_Fn> __f, _Arg&& __arg)
     253              :         : _M_value(std::__invoke(std::forward<_Fn>(__f._M_f),
     254              :                      std::forward<_Arg>(__arg)))
     255              :         { }
     256              : #endif
     257              : 
     258              :       // User-provided destructor is needed when _Up has non-trivial dtor.
     259              :       _GLIBCXX20_CONSTEXPR ~_Storage() { }
     260              : 
     261              :       _Empty_byte _M_empty;
     262              :       _Up _M_value;
     263              :     };
     264              : 
     265              :       _Storage<_Stored_type> _M_payload;
     266              : 
     267              :       bool _M_engaged = false;
     268              : 
     269              :       template<typename... _Args>
     270              :     constexpr void
     271              :     _M_construct(_Args&&... __args)
     272              :     noexcept(is_nothrow_constructible_v<_Stored_type, _Args...>)
     273              :     {
     274              :       std::_Construct(std::__addressof(this->_M_payload._M_value),
     275              :               std::forward<_Args>(__args)...);
     276              :       this->_M_engaged = true;
     277              :     }
     278              : 
     279              :       constexpr void
     280              :       _M_destroy() noexcept
     281              :       {
     282              :     _M_engaged = false;
     283              :     _M_payload._M_value.~_Stored_type();
     284              :       }
     285              : 
     286              : #if __cplusplus >= 202002L
     287              :       template<typename _Fn, typename _Up>
     288              :     constexpr void
     289              :     _M_apply(_Optional_func<_Fn> __f, _Up&& __x)
     290              :     {
     291              :       std::construct_at(std::__addressof(this->_M_payload),
     292              :                 __f, std::forward<_Up>(__x));
     293              :       _M_engaged = true;
     294              :     }
     295              : #endif
     296              : 
     297              :       // The _M_get() operations have _M_engaged as a precondition.
     298              :       // They exist to access the contained value with the appropriate
     299              :       // const-qualification, because _M_payload has had the const removed.
     300              : 
     301              :       constexpr _Tp&
     302              :       _M_get() noexcept
     303              :       { return this->_M_payload._M_value; }
     304              : 
     305              :       constexpr const _Tp&
     306              :       _M_get() const noexcept
     307              :       { return this->_M_payload._M_value; }
     308              : 
     309              :       // _M_reset is a 'safe' operation with no precondition.
     310              :       constexpr void
     311              :       _M_reset() noexcept
     312              :       {
     313              :     if (this->_M_engaged)
     314              :       _M_destroy();
     315              :     else // This seems redundant but improves codegen, see PR 112480.
     316              :       this->_M_engaged = false;
     317              :       }
     318              :     };
     319              : 
     320              :   // Class template that manages the payload for optionals.
     321              :   template <typename _Tp,
     322              :         bool /*_HasTrivialDestructor*/ =
     323              :           is_trivially_destructible_v<_Tp>,
     324              :         bool /*_HasTrivialCopy */ =
     325              :           is_trivially_copy_assignable_v<_Tp>
     326              :           && is_trivially_copy_constructible_v<_Tp>,
     327              :         bool /*_HasTrivialMove */ =
     328              :           is_trivially_move_assignable_v<_Tp>
     329              :           && is_trivially_move_constructible_v<_Tp>>
     330              :     struct _Optional_payload;
     331              : 
     332              :   // Payload for potentially-constexpr optionals (trivial copy/move/destroy).
     333              :   template <typename _Tp>
     334              :     struct _Optional_payload<_Tp, true, true, true>
     335              :     : _Optional_payload_base<_Tp>
     336              :     {
     337              :       using _Optional_payload_base<_Tp>::_Optional_payload_base;
     338              : 
     339           45 :       _Optional_payload() = default;
     340              :     };
     341              : 
     342              :   // Payload for optionals with non-trivial copy construction/assignment.
     343              :   template <typename _Tp>
     344              :     struct _Optional_payload<_Tp, true, false, true>
     345              :     : _Optional_payload_base<_Tp>
     346              :     {
     347              :       using _Optional_payload_base<_Tp>::_Optional_payload_base;
     348              : 
     349              :       _Optional_payload() = default;
     350              :       ~_Optional_payload() = default;
     351              :       _Optional_payload(const _Optional_payload&) = default;
     352              :       _Optional_payload(_Optional_payload&&) = default;
     353              :       _Optional_payload& operator=(_Optional_payload&&) = default;
     354              : 
     355              :       // Non-trivial copy assignment.
     356              :       constexpr
     357              :       _Optional_payload&
     358              :       operator=(const _Optional_payload& __other)
     359              :       {
     360              :     this->_M_copy_assign(__other);
     361              :     return *this;
     362              :       }
     363              :     };
     364              : 
     365              :   // Payload for optionals with non-trivial move construction/assignment.
     366              :   template <typename _Tp>
     367              :     struct _Optional_payload<_Tp, true, true, false>
     368              :     : _Optional_payload_base<_Tp>
     369              :     {
     370              :       using _Optional_payload_base<_Tp>::_Optional_payload_base;
     371              : 
     372              :       _Optional_payload() = default;
     373              :       ~_Optional_payload() = default;
     374              :       _Optional_payload(const _Optional_payload&) = default;
     375              :       _Optional_payload(_Optional_payload&&) = default;
     376              :       _Optional_payload& operator=(const _Optional_payload&) = default;
     377              : 
     378              :       // Non-trivial move assignment.
     379              :       constexpr
     380              :       _Optional_payload&
     381              :       operator=(_Optional_payload&& __other)
     382              :       noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
     383              :                is_nothrow_move_assignable<_Tp>>)
     384              :       {
     385              :     this->_M_move_assign(std::move(__other));
     386              :     return *this;
     387              :       }
     388              :     };
     389              : 
     390              :   // Payload for optionals with non-trivial copy and move assignment.
     391              :   template <typename _Tp>
     392              :     struct _Optional_payload<_Tp, true, false, false>
     393              :     : _Optional_payload_base<_Tp>
     394              :     {
     395              :       using _Optional_payload_base<_Tp>::_Optional_payload_base;
     396              : 
     397              :       _Optional_payload() = default;
     398              :       ~_Optional_payload() = default;
     399              :       _Optional_payload(const _Optional_payload&) = default;
     400              :       _Optional_payload(_Optional_payload&&) = default;
     401              : 
     402              :       // Non-trivial copy assignment.
     403              :       constexpr
     404              :       _Optional_payload&
     405              :       operator=(const _Optional_payload& __other)
     406              :       {
     407              :     this->_M_copy_assign(__other);
     408              :     return *this;
     409              :       }
     410              : 
     411              :       // Non-trivial move assignment.
     412              :       constexpr
     413              :       _Optional_payload&
     414              :       operator=(_Optional_payload&& __other)
     415              :       noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
     416              :                is_nothrow_move_assignable<_Tp>>)
     417              :       {
     418              :     this->_M_move_assign(std::move(__other));
     419              :     return *this;
     420              :       }
     421              :     };
     422              : 
     423              :   // Payload for optionals with non-trivial destructors.
     424              :   template <typename _Tp, bool _Copy, bool _Move>
     425              :     struct _Optional_payload<_Tp, false, _Copy, _Move>
     426              :     : _Optional_payload<_Tp, true, false, false>
     427              :     {
     428              :       // Base class implements all the constructors and assignment operators:
     429              :       using _Optional_payload<_Tp, true, false, false>::_Optional_payload;
     430              :       _Optional_payload() = default;
     431              :       _Optional_payload(const _Optional_payload&) = default;
     432              :       _Optional_payload(_Optional_payload&&) = default;
     433              :       _Optional_payload& operator=(const _Optional_payload&) = default;
     434              :       _Optional_payload& operator=(_Optional_payload&&) = default;
     435              : 
     436              :       // Destructor needs to destroy the contained value:
     437              :       _GLIBCXX20_CONSTEXPR ~_Optional_payload() { this->_M_reset(); }
     438              :     };
     439              : 
     440              :   // Common base class for _Optional_base<T> to avoid repeating these
     441              :   // member functions in each specialization.
     442              :   template<typename _Tp, typename _Dp>
     443              :     class _Optional_base_impl
     444              :     {
     445              :     protected:
     446              :       using _Stored_type = remove_const_t<_Tp>;
     447              : 
     448              :       // The _M_construct operation has !_M_engaged as a precondition
     449              :       // while _M_destruct has _M_engaged as a precondition.
     450              :       template<typename... _Args>
     451              :     constexpr void
     452              :     _M_construct(_Args&&... __args)
     453              :     noexcept(is_nothrow_constructible_v<_Stored_type, _Args...>)
     454              :     {
     455              :       static_cast<_Dp*>(this)->_M_payload._M_construct(
     456              :         std::forward<_Args>(__args)...);
     457              :     }
     458              : 
     459              :       constexpr void
     460              :       _M_destruct() noexcept
     461              :       { static_cast<_Dp*>(this)->_M_payload._M_destroy(); }
     462              : 
     463              :       // _M_reset is a 'safe' operation with no precondition.
     464              :       constexpr void
     465              :       _M_reset() noexcept
     466              :       { static_cast<_Dp*>(this)->_M_payload._M_reset(); }
     467              : 
     468              :       constexpr bool _M_is_engaged() const noexcept
     469              :       { return static_cast<const _Dp*>(this)->_M_payload._M_engaged; }
     470              : 
     471              :       // The _M_get operations have _M_engaged as a precondition.
     472              :       constexpr _Tp&
     473              :       _M_get() noexcept
     474              :       {
     475              :     __glibcxx_assert(this->_M_is_engaged());
     476              :     return static_cast<_Dp*>(this)->_M_payload._M_get();
     477              :       }
     478              : 
     479              :       constexpr const _Tp&
     480              :       _M_get() const noexcept
     481              :       {
     482              :     __glibcxx_assert(this->_M_is_engaged());
     483              :     return static_cast<const _Dp*>(this)->_M_payload._M_get();
     484              :       }
     485              :     };
     486              : 
     487              :   /**
     488              :     * @brief Class template that provides copy/move constructors of optional.
     489              :     *
     490              :     * Such a separate base class template is necessary in order to
     491              :     * conditionally make copy/move constructors trivial.
     492              :     *
     493              :     * When the contained value is trivially copy/move constructible,
     494              :     * the copy/move constructors of _Optional_base will invoke the
     495              :     * trivial copy/move constructor of _Optional_payload. Otherwise,
     496              :     * they will invoke _Optional_payload(bool, const _Optional_payload&)
     497              :     * or _Optional_payload(bool, _Optional_payload&&) to initialize
     498              :     * the contained value, if copying/moving an engaged optional.
     499              :     *
     500              :     * Whether the other special members are trivial is determined by the
     501              :     * _Optional_payload<_Tp> specialization used for the _M_payload member.
     502              :     *
     503              :     * @see optional, _Enable_special_members
     504              :     */
     505              :   template<typename _Tp,
     506              :        bool = is_trivially_copy_constructible_v<_Tp>,
     507              :        bool = is_trivially_move_constructible_v<_Tp>>
     508              :     struct _Optional_base
     509              :     : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
     510              :     {
     511              :       // Constructors for disengaged optionals.
     512              :       constexpr _Optional_base() = default;
     513              : 
     514              :       // Constructors for engaged optionals.
     515              :       template<typename... _Args,
     516              :            enable_if_t<is_constructible_v<_Tp, _Args...>, bool> = false>
     517              :     constexpr explicit
     518              :     _Optional_base(in_place_t, _Args&&... __args)
     519              :     : _M_payload(in_place, std::forward<_Args>(__args)...)
     520              :     { }
     521              : 
     522              :       template<typename _Up, typename... _Args,
     523              :            enable_if_t<is_constructible_v<_Tp,
     524              :                           initializer_list<_Up>&,
     525              :                           _Args...>, bool> = false>
     526              :     constexpr explicit
     527              :     _Optional_base(in_place_t,
     528              :                initializer_list<_Up> __il,
     529              :                _Args&&... __args)
     530              :     : _M_payload(in_place, __il, std::forward<_Args>(__args)...)
     531              :     { }
     532              : 
     533              :       // Copy and move constructors.
     534              :       constexpr
     535              :       _Optional_base(const _Optional_base& __other)
     536              :       : _M_payload(__other._M_payload._M_engaged, __other._M_payload)
     537              :       { }
     538              : 
     539              :       constexpr
     540              :       _Optional_base(_Optional_base&& __other)
     541              :       noexcept(is_nothrow_move_constructible_v<_Tp>)
     542              :       : _M_payload(__other._M_payload._M_engaged,
     543              :            std::move(__other._M_payload))
     544              :       { }
     545              : 
     546              :       // Assignment operators.
     547              :       _Optional_base& operator=(const _Optional_base&) = default;
     548              :       _Optional_base& operator=(_Optional_base&&) = default;
     549              : 
     550              :       _Optional_payload<_Tp> _M_payload;
     551              :     };
     552              : 
     553              :   template<typename _Tp>
     554              :     struct _Optional_base<_Tp, false, true>
     555              :     : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
     556              :     {
     557              :       // Constructors for disengaged optionals.
     558              :       constexpr _Optional_base() = default;
     559              : 
     560              :       // Constructors for engaged optionals.
     561              :       template<typename... _Args,
     562              :            enable_if_t<is_constructible_v<_Tp, _Args...>, bool> = false>
     563              :     constexpr explicit
     564              :     _Optional_base(in_place_t, _Args&&... __args)
     565              :     : _M_payload(in_place, std::forward<_Args>(__args)...)
     566              :     { }
     567              : 
     568              :       template<typename _Up, typename... _Args,
     569              :            enable_if_t<is_constructible_v<_Tp,
     570              :                           initializer_list<_Up>&,
     571              :                           _Args...>, bool> = false>
     572              :     constexpr explicit
     573              :     _Optional_base(in_place_t,
     574              :                initializer_list<_Up> __il,
     575              :                _Args... __args)
     576              :     : _M_payload(in_place, __il, std::forward<_Args>(__args)...)
     577              :     { }
     578              : 
     579              :       // Copy and move constructors.
     580              :       constexpr _Optional_base(const _Optional_base& __other)
     581              :       : _M_payload(__other._M_payload._M_engaged, __other._M_payload)
     582              :       { }
     583              : 
     584              :       constexpr _Optional_base(_Optional_base&& __other) = default;
     585              : 
     586              :       // Assignment operators.
     587              :       _Optional_base& operator=(const _Optional_base&) = default;
     588              :       _Optional_base& operator=(_Optional_base&&) = default;
     589              : 
     590              :       _Optional_payload<_Tp> _M_payload;
     591              :     };
     592              : 
     593              :   template<typename _Tp>
     594              :     struct _Optional_base<_Tp, true, false>
     595              :     : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
     596              :     {
     597              :       // Constructors for disengaged optionals.
     598              :       constexpr _Optional_base() = default;
     599              : 
     600              :       // Constructors for engaged optionals.
     601              :       template<typename... _Args,
     602              :            enable_if_t<is_constructible_v<_Tp, _Args...>, bool> = false>
     603              :     constexpr explicit
     604              :     _Optional_base(in_place_t, _Args&&... __args)
     605              :     : _M_payload(in_place, std::forward<_Args>(__args)...)
     606              :     { }
     607              : 
     608              :       template<typename _Up, typename... _Args,
     609              :            enable_if_t<is_constructible_v<_Tp,
     610              :                           initializer_list<_Up>&,
     611              :                           _Args...>, bool> = false>
     612              :     constexpr explicit
     613              :     _Optional_base(in_place_t,
     614              :                initializer_list<_Up> __il,
     615              :                _Args&&... __args)
     616              :     : _M_payload(in_place, __il, std::forward<_Args>(__args)...)
     617              :     { }
     618              : 
     619              :       // Copy and move constructors.
     620              :       constexpr _Optional_base(const _Optional_base& __other) = default;
     621              : 
     622              :       constexpr
     623              :       _Optional_base(_Optional_base&& __other)
     624              :       noexcept(is_nothrow_move_constructible_v<_Tp>)
     625              :       : _M_payload(__other._M_payload._M_engaged,
     626              :            std::move(__other._M_payload))
     627              :       { }
     628              : 
     629              :       // Assignment operators.
     630              :       _Optional_base& operator=(const _Optional_base&) = default;
     631              :       _Optional_base& operator=(_Optional_base&&) = default;
     632              : 
     633              :       _Optional_payload<_Tp> _M_payload;
     634              :     };
     635              : 
     636              :   template<typename _Tp>
     637              :     struct _Optional_base<_Tp, true, true>
     638              :     : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
     639              :     {
     640              :       // Constructors for disengaged optionals.
     641           45 :       constexpr _Optional_base() = default;
     642              : 
     643              :       // Constructors for engaged optionals.
     644              :       template<typename... _Args,
     645              :            enable_if_t<is_constructible_v<_Tp, _Args...>, bool> = false>
     646              :     constexpr explicit
     647            0 :     _Optional_base(in_place_t, _Args&&... __args)
     648            0 :     : _M_payload(in_place, std::forward<_Args>(__args)...)
     649            0 :     { }
     650              : 
     651              :       template<typename _Up, typename... _Args,
     652              :            enable_if_t<is_constructible_v<_Tp,
     653              :                           initializer_list<_Up>&,
     654              :                           _Args...>, bool> = false>
     655              :     constexpr explicit
     656              :     _Optional_base(in_place_t,
     657              :                initializer_list<_Up> __il,
     658              :                _Args&&... __args)
     659              :     : _M_payload(in_place, __il, std::forward<_Args>(__args)...)
     660              :     { }
     661              : 
     662              :       // Copy and move constructors.
     663              :       constexpr _Optional_base(const _Optional_base& __other) = default;
     664              :       constexpr _Optional_base(_Optional_base&& __other) = default;
     665              : 
     666              :       // Assignment operators.
     667              :       _Optional_base& operator=(const _Optional_base&) = default;
     668              :       _Optional_base& operator=(_Optional_base&&) = default;
     669              : 
     670              :       _Optional_payload<_Tp> _M_payload;
     671              :     };
     672              : 
     673              :   template<typename _Tp>
     674              :   class optional;
     675              : 
     676              :   template<typename _Tp>
     677              :     inline constexpr bool __is_optional_v = false;
     678              :   template<typename _Tp>
     679              :     inline constexpr bool __is_optional_v<optional<_Tp>> = true;
     680              : 
     681              :   template<typename _Tp, typename _Up>
     682              :     using __converts_from_optional =
     683              :       __or_<is_constructible<_Tp, const optional<_Up>&>,
     684              :         is_constructible<_Tp, optional<_Up>&>,
     685              :         is_constructible<_Tp, const optional<_Up>&&>,
     686              :         is_constructible<_Tp, optional<_Up>&&>,
     687              :         is_convertible<const optional<_Up>&, _Tp>,
     688              :         is_convertible<optional<_Up>&, _Tp>,
     689              :         is_convertible<const optional<_Up>&&, _Tp>,
     690              :         is_convertible<optional<_Up>&&, _Tp>>;
     691              : 
     692              :   template<typename _Tp, typename _Up>
     693              :     using __assigns_from_optional =
     694              :       __or_<is_assignable<_Tp&, const optional<_Up>&>,
     695              :         is_assignable<_Tp&, optional<_Up>&>,
     696              :         is_assignable<_Tp&, const optional<_Up>&&>,
     697              :         is_assignable<_Tp&, optional<_Up>&&>>;
     698              : 
     699              :   /**
     700              :     * @brief Class template for optional values.
     701              :     */
     702              :   template<typename _Tp>
     703              :     class optional
     704              :     : private _Optional_base<_Tp>,
     705              :       private _Enable_copy_move<
     706              :     // Copy constructor.
     707              :     is_copy_constructible_v<_Tp>,
     708              :     // Copy assignment.
     709              :     __and_v<is_copy_constructible<_Tp>, is_copy_assignable<_Tp>>,
     710              :     // Move constructor.
     711              :     is_move_constructible_v<_Tp>,
     712              :     // Move assignment.
     713              :     __and_v<is_move_constructible<_Tp>, is_move_assignable<_Tp>>,
     714              :     // Unique tag type.
     715              :     optional<_Tp>>
     716              :     {
     717              :       static_assert(!is_same_v<remove_cv_t<_Tp>, nullopt_t>);
     718              :       static_assert(!is_same_v<remove_cv_t<_Tp>, in_place_t>);
     719              :       static_assert(is_object_v<_Tp> && !is_array_v<_Tp>);
     720              : 
     721              :     private:
     722              :       using _Base = _Optional_base<_Tp>;
     723              : 
     724              :       // SFINAE helpers
     725              :       template<typename _Up>
     726              :     using __not_self = __not_<is_same<optional, __remove_cvref_t<_Up>>>;
     727              :       template<typename _Up>
     728              :     using __not_tag = __not_<is_same<in_place_t, __remove_cvref_t<_Up>>>;
     729              :       template<typename... _Cond>
     730              :     using _Requires = enable_if_t<__and_v<_Cond...>, bool>;
     731              : 
     732              :     public:
     733              :       using value_type = _Tp;
     734              : 
     735              :       constexpr optional() noexcept { }
     736              : 
     737           45 :       constexpr optional(nullopt_t) noexcept { }
     738              : 
     739              :       // Converting constructors for engaged optionals.
     740              :       template<typename _Up = _Tp,
     741              :            _Requires<__not_self<_Up>, __not_tag<_Up>,
     742              :              is_constructible<_Tp, _Up>,
     743              :              is_convertible<_Up, _Tp>> = true>
     744              :     constexpr
     745              :     optional(_Up&& __t)
     746              :     noexcept(is_nothrow_constructible_v<_Tp, _Up>)
     747              :     : _Base(std::in_place, std::forward<_Up>(__t)) { }
     748              : 
     749              :       template<typename _Up = _Tp,
     750              :            _Requires<__not_self<_Up>, __not_tag<_Up>,
     751              :              is_constructible<_Tp, _Up>,
     752              :              __not_<is_convertible<_Up, _Tp>>> = false>
     753              :     explicit constexpr
     754              :     optional(_Up&& __t)
     755              :     noexcept(is_nothrow_constructible_v<_Tp, _Up>)
     756              :     : _Base(std::in_place, std::forward<_Up>(__t)) { }
     757              : 
     758              :       template<typename _Up,
     759              :            _Requires<__not_<is_same<_Tp, _Up>>,
     760              :              is_constructible<_Tp, const _Up&>,
     761              :              is_convertible<const _Up&, _Tp>,
     762              :              __not_<__converts_from_optional<_Tp, _Up>>> = true>
     763              :     constexpr
     764              :     optional(const optional<_Up>& __t)
     765              :     noexcept(is_nothrow_constructible_v<_Tp, const _Up&>)
     766              :     {
     767              :       if (__t)
     768              :         emplace(*__t);
     769              :     }
     770              : 
     771              :       template<typename _Up,
     772              :            _Requires<__not_<is_same<_Tp, _Up>>,
     773              :              is_constructible<_Tp, const _Up&>,
     774              :              __not_<is_convertible<const _Up&, _Tp>>,
     775              :              __not_<__converts_from_optional<_Tp, _Up>>> = false>
     776              :     explicit constexpr
     777              :     optional(const optional<_Up>& __t)
     778              :     noexcept(is_nothrow_constructible_v<_Tp, const _Up&>)
     779              :     {
     780              :       if (__t)
     781              :         emplace(*__t);
     782              :     }
     783              : 
     784              :       template<typename _Up,
     785              :            _Requires<__not_<is_same<_Tp, _Up>>,
     786              :              is_constructible<_Tp, _Up>,
     787              :              is_convertible<_Up, _Tp>,
     788              :              __not_<__converts_from_optional<_Tp, _Up>>> = true>
     789              :     constexpr
     790              :     optional(optional<_Up>&& __t)
     791              :     noexcept(is_nothrow_constructible_v<_Tp, _Up>)
     792              :     {
     793              :       if (__t)
     794              :         emplace(std::move(*__t));
     795              :     }
     796              : 
     797              :       template<typename _Up,
     798              :            _Requires<__not_<is_same<_Tp, _Up>>,
     799              :              is_constructible<_Tp, _Up>,
     800              :              __not_<is_convertible<_Up, _Tp>>,
     801              :              __not_<__converts_from_optional<_Tp, _Up>>> = false>
     802              :     explicit constexpr
     803              :     optional(optional<_Up>&& __t)
     804              :     noexcept(is_nothrow_constructible_v<_Tp, _Up>)
     805              :     {
     806              :       if (__t)
     807              :         emplace(std::move(*__t));
     808              :     }
     809              : 
     810              :       template<typename... _Args,
     811              :            _Requires<is_constructible<_Tp, _Args...>> = false>
     812              :     explicit constexpr
     813            0 :     optional(in_place_t, _Args&&... __args)
     814              :     noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
     815            0 :     : _Base(std::in_place, std::forward<_Args>(__args)...) { }
     816              : 
     817              :       template<typename _Up, typename... _Args,
     818              :            _Requires<is_constructible<_Tp,
     819              :                       initializer_list<_Up>&,
     820              :                       _Args...>> = false>
     821              :     explicit constexpr
     822              :     optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
     823              :     noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&,
     824              :                         _Args...>)
     825              :     : _Base(std::in_place, __il, std::forward<_Args>(__args)...) { }
     826              : 
     827              : 
     828              :       // Assignment operators.
     829              :       _GLIBCXX20_CONSTEXPR optional&
     830              :       operator=(nullopt_t) noexcept
     831              :       {
     832              :     this->_M_reset();
     833              :     return *this;
     834              :       }
     835              : 
     836              :       template<typename _Up = _Tp>
     837              :     _GLIBCXX20_CONSTEXPR
     838              :     enable_if_t<__and_v<__not_self<_Up>,
     839              :                 __not_<__and_<is_scalar<_Tp>,
     840              :                       is_same<_Tp, decay_t<_Up>>>>,
     841              :                 is_constructible<_Tp, _Up>,
     842              :                 is_assignable<_Tp&, _Up>>,
     843              :             optional&>
     844              :     operator=(_Up&& __u)
     845              :     noexcept(__and_v<is_nothrow_constructible<_Tp, _Up>,
     846              :              is_nothrow_assignable<_Tp&, _Up>>)
     847              :     {
     848              :       if (this->_M_is_engaged())
     849              :         this->_M_get() = std::forward<_Up>(__u);
     850              :       else
     851              :         this->_M_construct(std::forward<_Up>(__u));
     852              : 
     853              :       return *this;
     854              :     }
     855              : 
     856              :       template<typename _Up>
     857              :     _GLIBCXX20_CONSTEXPR
     858              :     enable_if_t<__and_v<__not_<is_same<_Tp, _Up>>,
     859              :                 is_constructible<_Tp, const _Up&>,
     860              :                 is_assignable<_Tp&, const _Up&>,
     861              :                 __not_<__converts_from_optional<_Tp, _Up>>,
     862              :                 __not_<__assigns_from_optional<_Tp, _Up>>>,
     863              :             optional&>
     864              :     operator=(const optional<_Up>& __u)
     865              :     noexcept(__and_v<is_nothrow_constructible<_Tp, const _Up&>,
     866              :              is_nothrow_assignable<_Tp&, const _Up&>>)
     867              :     {
     868              :       if (__u)
     869              :         {
     870              :           if (this->_M_is_engaged())
     871              :         this->_M_get() = *__u;
     872              :           else
     873              :         this->_M_construct(*__u);
     874              :         }
     875              :       else
     876              :         {
     877              :           this->_M_reset();
     878              :         }
     879              :       return *this;
     880              :     }
     881              : 
     882              :       template<typename _Up>
     883              :     _GLIBCXX20_CONSTEXPR
     884              :     enable_if_t<__and_v<__not_<is_same<_Tp, _Up>>,
     885              :                 is_constructible<_Tp, _Up>,
     886              :                 is_assignable<_Tp&, _Up>,
     887              :                 __not_<__converts_from_optional<_Tp, _Up>>,
     888              :                 __not_<__assigns_from_optional<_Tp, _Up>>>,
     889              :             optional&>
     890              :     operator=(optional<_Up>&& __u)
     891              :     noexcept(__and_v<is_nothrow_constructible<_Tp, _Up>,
     892              :              is_nothrow_assignable<_Tp&, _Up>>)
     893              :     {
     894              :       if (__u)
     895              :         {
     896              :           if (this->_M_is_engaged())
     897              :         this->_M_get() = std::move(*__u);
     898              :           else
     899              :         this->_M_construct(std::move(*__u));
     900              :         }
     901              :       else
     902              :         {
     903              :           this->_M_reset();
     904              :         }
     905              : 
     906              :       return *this;
     907              :     }
     908              : 
     909              :       template<typename... _Args>
     910              :     _GLIBCXX20_CONSTEXPR
     911              :     enable_if_t<is_constructible_v<_Tp, _Args...>, _Tp&>
     912              :     emplace(_Args&&... __args)
     913              :     noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
     914              :     {
     915              :       this->_M_reset();
     916              :       this->_M_construct(std::forward<_Args>(__args)...);
     917              :       return this->_M_get();
     918              :     }
     919              : 
     920              :       template<typename _Up, typename... _Args>
     921              :     _GLIBCXX20_CONSTEXPR
     922              :     enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>,
     923              :             _Tp&>
     924              :     emplace(initializer_list<_Up> __il, _Args&&... __args)
     925              :     noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&,
     926              :                         _Args...>)
     927              :     {
     928              :       this->_M_reset();
     929              :       this->_M_construct(__il, std::forward<_Args>(__args)...);
     930              :       return this->_M_get();
     931              :     }
     932              : 
     933              :       // Destructor is implicit, implemented in _Optional_base.
     934              : 
     935              :       // Swap.
     936              :       _GLIBCXX20_CONSTEXPR void
     937              :       swap(optional& __other)
     938              :       noexcept(is_nothrow_move_constructible_v<_Tp>
     939              :            && is_nothrow_swappable_v<_Tp>)
     940              :       {
     941              :     using std::swap;
     942              : 
     943              :     if (this->_M_is_engaged() && __other._M_is_engaged())
     944              :       swap(this->_M_get(), __other._M_get());
     945              :     else if (this->_M_is_engaged())
     946              :       {
     947              :         __other._M_construct(std::move(this->_M_get()));
     948              :         this->_M_destruct();
     949              :       }
     950              :     else if (__other._M_is_engaged())
     951              :       {
     952              :         this->_M_construct(std::move(__other._M_get()));
     953              :         __other._M_destruct();
     954              :       }
     955              :       }
     956              : 
     957              :       // Observers.
     958              :       constexpr const _Tp*
     959              :       operator->() const noexcept
     960              :       { return std::__addressof(this->_M_get()); }
     961              : 
     962              :       constexpr _Tp*
     963              :       operator->() noexcept
     964              :       { return std::__addressof(this->_M_get()); }
     965              : 
     966              :       constexpr const _Tp&
     967              :       operator*() const& noexcept
     968              :       { return this->_M_get(); }
     969              : 
     970              :       constexpr _Tp&
     971              :       operator*()& noexcept
     972              :       { return this->_M_get(); }
     973              : 
     974              :       constexpr _Tp&&
     975              :       operator*()&& noexcept
     976              :       { return std::move(this->_M_get()); }
     977              : 
     978              :       constexpr const _Tp&&
     979              :       operator*() const&& noexcept
     980              :       { return std::move(this->_M_get()); }
     981              : 
     982              :       constexpr explicit operator bool() const noexcept
     983              :       { return this->_M_is_engaged(); }
     984              : 
     985              :       constexpr bool has_value() const noexcept
     986              :       { return this->_M_is_engaged(); }
     987              : 
     988              :       constexpr const _Tp&
     989              :       value() const&
     990              :       {
     991              :     if (this->_M_is_engaged())
     992              :       return this->_M_get();
     993              :     __throw_bad_optional_access();
     994              :       }
     995              : 
     996              :       constexpr _Tp&
     997              :       value()&
     998              :       {
     999              :     if (this->_M_is_engaged())
    1000              :       return this->_M_get();
    1001              :     __throw_bad_optional_access();
    1002              :       }
    1003              : 
    1004              :       constexpr _Tp&&
    1005              :       value()&&
    1006              :       {
    1007              :     if (this->_M_is_engaged())
    1008              :       return std::move(this->_M_get());
    1009              :     __throw_bad_optional_access();
    1010              :       }
    1011              : 
    1012              :       constexpr const _Tp&&
    1013              :       value() const&&
    1014              :       {
    1015              :     if (this->_M_is_engaged())
    1016              :       return std::move(this->_M_get());
    1017              :     __throw_bad_optional_access();
    1018              :       }
    1019              : 
    1020              :       template<typename _Up>
    1021              :     constexpr _Tp
    1022              :     value_or(_Up&& __u) const&
    1023              :     {
    1024              :       static_assert(is_copy_constructible_v<_Tp>);
    1025              :       static_assert(is_convertible_v<_Up&&, _Tp>);
    1026              : 
    1027              :       if (this->_M_is_engaged())
    1028              :         return this->_M_get();
    1029              :       else
    1030              :         return static_cast<_Tp>(std::forward<_Up>(__u));
    1031              :     }
    1032              : 
    1033              :       template<typename _Up>
    1034              :     constexpr _Tp
    1035              :     value_or(_Up&& __u) &&
    1036              :     {
    1037              :       static_assert(is_move_constructible_v<_Tp>);
    1038              :       static_assert(is_convertible_v<_Up&&, _Tp>);
    1039              : 
    1040              :       if (this->_M_is_engaged())
    1041              :         return std::move(this->_M_get());
    1042              :       else
    1043              :         return static_cast<_Tp>(std::forward<_Up>(__u));
    1044              :     }
    1045              : 
    1046              : #if __cpp_lib_optional >= 202110L
    1047              :       // [optional.monadic]
    1048              : 
    1049              :       template<typename _Fn>
    1050              :     constexpr auto
    1051              :     and_then(_Fn&& __f) &
    1052              :     {
    1053              :       using _Up = remove_cvref_t<invoke_result_t<_Fn, _Tp&>>;
    1054              :       static_assert(__is_optional_v<remove_cvref_t<_Up>>,
    1055              :             "the function passed to std::optional<T>::and_then "
    1056              :             "must return a std::optional");
    1057              :       if (has_value())
    1058              :         return std::__invoke(std::forward<_Fn>(__f), **this);
    1059              :       else
    1060              :         return _Up();
    1061              :     }
    1062              : 
    1063              :       template<typename _Fn>
    1064              :     constexpr auto
    1065              :     and_then(_Fn&& __f) const &
    1066              :     {
    1067              :       using _Up = remove_cvref_t<invoke_result_t<_Fn, const _Tp&>>;
    1068              :       static_assert(__is_optional_v<_Up>,
    1069              :             "the function passed to std::optional<T>::and_then "
    1070              :             "must return a std::optional");
    1071              :       if (has_value())
    1072              :         return std::__invoke(std::forward<_Fn>(__f), **this);
    1073              :       else
    1074              :         return _Up();
    1075              :     }
    1076              : 
    1077              :       template<typename _Fn>
    1078              :     constexpr auto
    1079              :     and_then(_Fn&& __f) &&
    1080              :     {
    1081              :       using _Up = remove_cvref_t<invoke_result_t<_Fn, _Tp>>;
    1082              :       static_assert(__is_optional_v<remove_cvref_t<_Up>>,
    1083              :             "the function passed to std::optional<T>::and_then "
    1084              :             "must return a std::optional");
    1085              :       if (has_value())
    1086              :         return std::__invoke(std::forward<_Fn>(__f), std::move(**this));
    1087              :       else
    1088              :         return _Up();
    1089              :     }
    1090              : 
    1091              :       template<typename _Fn>
    1092              :     constexpr auto
    1093              :     and_then(_Fn&& __f) const &&
    1094              :     {
    1095              :       using _Up = remove_cvref_t<invoke_result_t<_Fn, const _Tp>>;
    1096              :       static_assert(__is_optional_v<remove_cvref_t<_Up>>,
    1097              :             "the function passed to std::optional<T>::and_then "
    1098              :             "must return a std::optional");
    1099              :       if (has_value())
    1100              :         return std::__invoke(std::forward<_Fn>(__f), std::move(**this));
    1101              :       else
    1102              :         return _Up();
    1103              :     }
    1104              : 
    1105              :       template<typename _Fn>
    1106              :     constexpr auto
    1107              :     transform(_Fn&& __f) &
    1108              :     {
    1109              :       using _Up = remove_cv_t<invoke_result_t<_Fn, _Tp&>>;
    1110              :       if (has_value())
    1111              :         return optional<_Up>(_Optional_func<_Fn>{__f}, **this);
    1112              :       else
    1113              :         return optional<_Up>();
    1114              :     }
    1115              : 
    1116              :       template<typename _Fn>
    1117              :     constexpr auto
    1118              :     transform(_Fn&& __f) const &
    1119              :     {
    1120              :       using _Up = remove_cv_t<invoke_result_t<_Fn, const _Tp&>>;
    1121              :       if (has_value())
    1122              :         return optional<_Up>(_Optional_func<_Fn>{__f}, **this);
    1123              :       else
    1124              :         return optional<_Up>();
    1125              :     }
    1126              : 
    1127              :       template<typename _Fn>
    1128              :     constexpr auto
    1129              :     transform(_Fn&& __f) &&
    1130              :     {
    1131              :       using _Up = remove_cv_t<invoke_result_t<_Fn, _Tp>>;
    1132              :       if (has_value())
    1133              :         return optional<_Up>(_Optional_func<_Fn>{__f}, std::move(**this));
    1134              :       else
    1135              :         return optional<_Up>();
    1136              :     }
    1137              : 
    1138              :       template<typename _Fn>
    1139              :     constexpr auto
    1140              :     transform(_Fn&& __f) const &&
    1141              :     {
    1142              :       using _Up = remove_cv_t<invoke_result_t<_Fn, const _Tp>>;
    1143              :       if (has_value())
    1144              :         return optional<_Up>(_Optional_func<_Fn>{__f}, std::move(**this));
    1145              :       else
    1146              :         return optional<_Up>();
    1147              :     }
    1148              : 
    1149              :       template<typename _Fn> requires invocable<_Fn> && copy_constructible<_Tp>
    1150              :     constexpr optional
    1151              :     or_else(_Fn&& __f) const&
    1152              :     {
    1153              :       using _Up = invoke_result_t<_Fn>;
    1154              :       static_assert(is_same_v<remove_cvref_t<_Up>, optional>,
    1155              :             "the function passed to std::optional<T>::or_else "
    1156              :             "must return a std::optional<T>");
    1157              : 
    1158              :       if (has_value())
    1159              :         return *this;
    1160              :       else
    1161              :         return std::forward<_Fn>(__f)();
    1162              :     }
    1163              : 
    1164              :       template<typename _Fn> requires invocable<_Fn> && move_constructible<_Tp>
    1165              :     constexpr optional
    1166              :     or_else(_Fn&& __f) &&
    1167              :     {
    1168              :       using _Up = invoke_result_t<_Fn>;
    1169              :       static_assert(is_same_v<remove_cvref_t<_Up>, optional>,
    1170              :             "the function passed to std::optional<T>::or_else "
    1171              :             "must return a std::optional<T>");
    1172              : 
    1173              :       if (has_value())
    1174              :         return std::move(*this);
    1175              :       else
    1176              :         return std::forward<_Fn>(__f)();
    1177              :     }
    1178              : #endif
    1179              : 
    1180              :       _GLIBCXX20_CONSTEXPR void reset() noexcept { this->_M_reset(); }
    1181              : 
    1182              :     private:
    1183              : #if __cplusplus >= 202002L
    1184              :       template<typename _Up> friend class optional;
    1185              : 
    1186              :       template<typename _Fn, typename _Value>
    1187              :     explicit constexpr
    1188              :     optional(_Optional_func<_Fn> __f, _Value&& __v)
    1189              :     {
    1190              :       this->_M_payload._M_apply(__f, std::forward<_Value>(__v));
    1191              :     }
    1192              : #endif
    1193              :     };
    1194              : 
    1195              :   template<typename _Tp>
    1196              :     using __optional_relop_t =
    1197              :       enable_if_t<is_convertible<_Tp, bool>::value, bool>;
    1198              : 
    1199              :   template<typename _Tp, typename _Up>
    1200              :     using __optional_eq_t = __optional_relop_t<
    1201              :       decltype(std::declval<const _Tp&>() == std::declval<const _Up&>())
    1202              :       >;
    1203              : 
    1204              :   template<typename _Tp, typename _Up>
    1205              :     using __optional_ne_t = __optional_relop_t<
    1206              :       decltype(std::declval<const _Tp&>() != std::declval<const _Up&>())
    1207              :       >;
    1208              : 
    1209              :   template<typename _Tp, typename _Up>
    1210              :     using __optional_lt_t = __optional_relop_t<
    1211              :       decltype(std::declval<const _Tp&>() < std::declval<const _Up&>())
    1212              :       >;
    1213              : 
    1214              :   template<typename _Tp, typename _Up>
    1215              :     using __optional_gt_t = __optional_relop_t<
    1216              :       decltype(std::declval<const _Tp&>() > std::declval<const _Up&>())
    1217              :       >;
    1218              : 
    1219              :   template<typename _Tp, typename _Up>
    1220              :     using __optional_le_t = __optional_relop_t<
    1221              :       decltype(std::declval<const _Tp&>() <= std::declval<const _Up&>())
    1222              :       >;
    1223              : 
    1224              :   template<typename _Tp, typename _Up>
    1225              :     using __optional_ge_t = __optional_relop_t<
    1226              :       decltype(std::declval<const _Tp&>() >= std::declval<const _Up&>())
    1227              :       >;
    1228              : 
    1229              :   // Comparisons between optional values.
    1230              :   template<typename _Tp, typename _Up>
    1231              :     constexpr auto
    1232              :     operator==(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
    1233              :     -> __optional_eq_t<_Tp, _Up>
    1234              :     {
    1235              :       return static_cast<bool>(__lhs) == static_cast<bool>(__rhs)
    1236              :          && (!__lhs || *__lhs == *__rhs);
    1237              :     }
    1238              : 
    1239              :   template<typename _Tp, typename _Up>
    1240              :     constexpr auto
    1241              :     operator!=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
    1242              :     -> __optional_ne_t<_Tp, _Up>
    1243              :     {
    1244              :       return static_cast<bool>(__lhs) != static_cast<bool>(__rhs)
    1245              :     || (static_cast<bool>(__lhs) && *__lhs != *__rhs);
    1246              :     }
    1247              : 
    1248              :   template<typename _Tp, typename _Up>
    1249              :     constexpr auto
    1250              :     operator<(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
    1251              :     -> __optional_lt_t<_Tp, _Up>
    1252              :     {
    1253              :       return static_cast<bool>(__rhs) && (!__lhs || *__lhs < *__rhs);
    1254              :     }
    1255              : 
    1256              :   template<typename _Tp, typename _Up>
    1257              :     constexpr auto
    1258              :     operator>(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
    1259              :     -> __optional_gt_t<_Tp, _Up>
    1260              :     {
    1261              :       return static_cast<bool>(__lhs) && (!__rhs || *__lhs > *__rhs);
    1262              :     }
    1263              : 
    1264              :   template<typename _Tp, typename _Up>
    1265              :     constexpr auto
    1266              :     operator<=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
    1267              :     -> __optional_le_t<_Tp, _Up>
    1268              :     {
    1269              :       return !__lhs || (static_cast<bool>(__rhs) && *__lhs <= *__rhs);
    1270              :     }
    1271              : 
    1272              :   template<typename _Tp, typename _Up>
    1273              :     constexpr auto
    1274              :     operator>=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
    1275              :     -> __optional_ge_t<_Tp, _Up>
    1276              :     {
    1277              :       return !__rhs || (static_cast<bool>(__lhs) && *__lhs >= *__rhs);
    1278              :     }
    1279              : 
    1280              : #ifdef __cpp_lib_three_way_comparison
    1281              :   template<typename _Tp, three_way_comparable_with<_Tp> _Up>
    1282              :     constexpr compare_three_way_result_t<_Tp, _Up>
    1283              :     operator<=>(const optional<_Tp>& __x, const optional<_Up>& __y)
    1284              :     {
    1285              :       return __x && __y ? *__x <=> *__y : bool(__x) <=> bool(__y);
    1286              :     }
    1287              : #endif
    1288              : 
    1289              :   // Comparisons with nullopt.
    1290              :   template<typename _Tp>
    1291              :     constexpr bool
    1292              :     operator==(const optional<_Tp>& __lhs, nullopt_t) noexcept
    1293              :     { return !__lhs; }
    1294              : 
    1295              : #ifdef __cpp_lib_three_way_comparison
    1296              :   template<typename _Tp>
    1297              :     constexpr strong_ordering
    1298              :     operator<=>(const optional<_Tp>& __x, nullopt_t) noexcept
    1299              :     { return bool(__x) <=> false; }
    1300              : #else
    1301              :   template<typename _Tp>
    1302              :     constexpr bool
    1303              :     operator==(nullopt_t, const optional<_Tp>& __rhs) noexcept
    1304              :     { return !__rhs; }
    1305              : 
    1306              :   template<typename _Tp>
    1307              :     constexpr bool
    1308              :     operator!=(const optional<_Tp>& __lhs, nullopt_t) noexcept
    1309              :     { return static_cast<bool>(__lhs); }
    1310              : 
    1311              :   template<typename _Tp>
    1312              :     constexpr bool
    1313              :     operator!=(nullopt_t, const optional<_Tp>& __rhs) noexcept
    1314              :     { return static_cast<bool>(__rhs); }
    1315              : 
    1316              :   template<typename _Tp>
    1317              :     constexpr bool
    1318              :     operator<(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept
    1319              :     { return false; }
    1320              : 
    1321              :   template<typename _Tp>
    1322              :     constexpr bool
    1323              :     operator<(nullopt_t, const optional<_Tp>& __rhs) noexcept
    1324              :     { return static_cast<bool>(__rhs); }
    1325              : 
    1326              :   template<typename _Tp>
    1327              :     constexpr bool
    1328              :     operator>(const optional<_Tp>& __lhs, nullopt_t) noexcept
    1329              :     { return static_cast<bool>(__lhs); }
    1330              : 
    1331              :   template<typename _Tp>
    1332              :     constexpr bool
    1333              :     operator>(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept
    1334              :     { return false; }
    1335              : 
    1336              :   template<typename _Tp>
    1337              :     constexpr bool
    1338              :     operator<=(const optional<_Tp>& __lhs, nullopt_t) noexcept
    1339              :     { return !__lhs; }
    1340              : 
    1341              :   template<typename _Tp>
    1342              :     constexpr bool
    1343              :     operator<=(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept
    1344              :     { return true; }
    1345              : 
    1346              :   template<typename _Tp>
    1347              :     constexpr bool
    1348              :     operator>=(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept
    1349              :     { return true; }
    1350              : 
    1351              :   template<typename _Tp>
    1352              :     constexpr bool
    1353              :     operator>=(nullopt_t, const optional<_Tp>& __rhs) noexcept
    1354              :     { return !__rhs; }
    1355              : #endif // three-way-comparison
    1356              : 
    1357              :   // Comparisons with value type.
    1358              :   template<typename _Tp, typename _Up>
    1359              :     constexpr auto
    1360              :     operator==(const optional<_Tp>& __lhs, const _Up& __rhs)
    1361              :     -> __optional_eq_t<_Tp, _Up>
    1362              :     { return __lhs && *__lhs == __rhs; }
    1363              : 
    1364              :   template<typename _Tp, typename _Up>
    1365              :     constexpr auto
    1366              :     operator==(const _Up& __lhs, const optional<_Tp>& __rhs)
    1367              :     -> __optional_eq_t<_Up, _Tp>
    1368              :     { return __rhs && __lhs == *__rhs; }
    1369              : 
    1370              :   template<typename _Tp, typename _Up>
    1371              :     constexpr auto
    1372              :     operator!=(const optional<_Tp>& __lhs, const _Up& __rhs)
    1373              :     -> __optional_ne_t<_Tp, _Up>
    1374              :     { return !__lhs || *__lhs != __rhs; }
    1375              : 
    1376              :   template<typename _Tp, typename _Up>
    1377              :     constexpr auto
    1378              :     operator!=(const _Up& __lhs, const optional<_Tp>& __rhs)
    1379              :     -> __optional_ne_t<_Up, _Tp>
    1380              :     { return !__rhs || __lhs != *__rhs; }
    1381              : 
    1382              :   template<typename _Tp, typename _Up>
    1383              :     constexpr auto
    1384              :     operator<(const optional<_Tp>& __lhs, const _Up& __rhs)
    1385              :     -> __optional_lt_t<_Tp, _Up>
    1386              :     { return !__lhs || *__lhs < __rhs; }
    1387              : 
    1388              :   template<typename _Tp, typename _Up>
    1389              :     constexpr auto
    1390              :     operator<(const _Up& __lhs, const optional<_Tp>& __rhs)
    1391              :     -> __optional_lt_t<_Up, _Tp>
    1392              :     { return __rhs && __lhs < *__rhs; }
    1393              : 
    1394              :   template<typename _Tp, typename _Up>
    1395              :     constexpr auto
    1396              :     operator>(const optional<_Tp>& __lhs, const _Up& __rhs)
    1397              :     -> __optional_gt_t<_Tp, _Up>
    1398              :     { return __lhs && *__lhs > __rhs; }
    1399              : 
    1400              :   template<typename _Tp, typename _Up>
    1401              :     constexpr auto
    1402              :     operator>(const _Up& __lhs, const optional<_Tp>& __rhs)
    1403              :     -> __optional_gt_t<_Up, _Tp>
    1404              :     { return !__rhs || __lhs > *__rhs; }
    1405              : 
    1406              :   template<typename _Tp, typename _Up>
    1407              :     constexpr auto
    1408              :     operator<=(const optional<_Tp>& __lhs, const _Up& __rhs)
    1409              :     -> __optional_le_t<_Tp, _Up>
    1410              :     { return !__lhs || *__lhs <= __rhs; }
    1411              : 
    1412              :   template<typename _Tp, typename _Up>
    1413              :     constexpr auto
    1414              :     operator<=(const _Up& __lhs, const optional<_Tp>& __rhs)
    1415              :     -> __optional_le_t<_Up, _Tp>
    1416              :     { return __rhs && __lhs <= *__rhs; }
    1417              : 
    1418              :   template<typename _Tp, typename _Up>
    1419              :     constexpr auto
    1420              :     operator>=(const optional<_Tp>& __lhs, const _Up& __rhs)
    1421              :     -> __optional_ge_t<_Tp, _Up>
    1422              :     { return __lhs && *__lhs >= __rhs; }
    1423              : 
    1424              :   template<typename _Tp, typename _Up>
    1425              :     constexpr auto
    1426              :     operator>=(const _Up& __lhs, const optional<_Tp>& __rhs)
    1427              :     -> __optional_ge_t<_Up, _Tp>
    1428              :     { return !__rhs || __lhs >= *__rhs; }
    1429              : 
    1430              : #ifdef __cpp_lib_three_way_comparison
    1431              :   template<typename _Tp, typename _Up>
    1432              :     requires (!__is_optional_v<_Up>)
    1433              :       && three_way_comparable_with<_Up, _Tp>
    1434              :     constexpr compare_three_way_result_t<_Tp, _Up>
    1435              :     operator<=>(const optional<_Tp>& __x, const _Up& __v)
    1436              :     { return bool(__x) ? *__x <=> __v : strong_ordering::less; }
    1437              : #endif
    1438              : 
    1439              :   // Swap and creation functions.
    1440              : 
    1441              :   // _GLIBCXX_RESOLVE_LIB_DEFECTS
    1442              :   // 2748. swappable traits for optionals
    1443              :   template<typename _Tp>
    1444              :     _GLIBCXX20_CONSTEXPR
    1445              :     inline enable_if_t<is_move_constructible_v<_Tp> && is_swappable_v<_Tp>>
    1446              :     swap(optional<_Tp>& __lhs, optional<_Tp>& __rhs)
    1447              :     noexcept(noexcept(__lhs.swap(__rhs)))
    1448              :     { __lhs.swap(__rhs); }
    1449              : 
    1450              :   template<typename _Tp>
    1451              :     enable_if_t<!(is_move_constructible_v<_Tp> && is_swappable_v<_Tp>)>
    1452              :     swap(optional<_Tp>&, optional<_Tp>&) = delete;
    1453              : 
    1454              :   template<typename _Tp>
    1455              :     constexpr
    1456              :     enable_if_t<is_constructible_v<decay_t<_Tp>, _Tp>,
    1457              :         optional<decay_t<_Tp>>>
    1458              :     make_optional(_Tp&& __t)
    1459              :     noexcept(is_nothrow_constructible_v<optional<decay_t<_Tp>>, _Tp>)
    1460              :     { return optional<decay_t<_Tp>>{ std::forward<_Tp>(__t) }; }
    1461              : 
    1462              :   template<typename _Tp, typename... _Args>
    1463              :     constexpr
    1464              :     enable_if_t<is_constructible_v<_Tp, _Args...>,
    1465              :         optional<_Tp>>
    1466              :     make_optional(_Args&&... __args)
    1467              :     noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
    1468              :     { return optional<_Tp>{ in_place, std::forward<_Args>(__args)... }; }
    1469              : 
    1470              :   template<typename _Tp, typename _Up, typename... _Args>
    1471              :     constexpr
    1472              :     enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>,
    1473              :         optional<_Tp>>
    1474              :     make_optional(initializer_list<_Up> __il, _Args&&... __args)
    1475              :     noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, _Args...>)
    1476              :     { return optional<_Tp>{ in_place, __il, std::forward<_Args>(__args)... }; }
    1477              : 
    1478              :   // Hash.
    1479              : 
    1480              :   template<typename _Tp, typename _Up = remove_const_t<_Tp>,
    1481              :        bool = __poison_hash<_Up>::__enable_hash_call>
    1482              :     struct __optional_hash_call_base
    1483              :     {
    1484              :       size_t
    1485              :       operator()(const optional<_Tp>& __t) const
    1486              :       noexcept(noexcept(hash<_Up>{}(*__t)))
    1487              :       {
    1488              :     // We pick an arbitrary hash for disengaged optionals which hopefully
    1489              :     // usual values of _Tp won't typically hash to.
    1490              :     constexpr size_t __magic_disengaged_hash = static_cast<size_t>(-3333);
    1491              :     return __t ? hash<_Up>{}(*__t) : __magic_disengaged_hash;
    1492              :       }
    1493              :     };
    1494              : 
    1495              :   template<typename _Tp, typename _Up>
    1496              :     struct __optional_hash_call_base<_Tp, _Up, false> {};
    1497              : 
    1498              :   template<typename _Tp>
    1499              :     struct hash<optional<_Tp>>
    1500              :     : private __poison_hash<remove_const_t<_Tp>>,
    1501              :       public __optional_hash_call_base<_Tp>
    1502              :     {
    1503              :       using result_type [[__deprecated__]] = size_t;
    1504              :       using argument_type [[__deprecated__]] = optional<_Tp>;
    1505              :     };
    1506              : 
    1507              :   template<typename _Tp>
    1508              :     struct __is_fast_hash<hash<optional<_Tp>>> : __is_fast_hash<hash<_Tp>>
    1509              :     { };
    1510              : 
    1511              :   /// @}
    1512              : 
    1513              : #if __cpp_deduction_guides >= 201606
    1514              :   template <typename _Tp> optional(_Tp) -> optional<_Tp>;
    1515              : #endif
    1516              : 
    1517              : _GLIBCXX_END_NAMESPACE_VERSION
    1518              : } // namespace std
    1519              : 
    1520              : #endif // __cpp_lib_optional
    1521              : 
    1522              : #endif // _GLIBCXX_OPTIONAL
        

Generated by: LCOV version 2.0-1