Home | History | Annotate | Line # | Download | only in experimental
      1  1.1.1.12  mrg // <experimental/optional> -*- C++ -*-
      2       1.1  mrg 
      3  1.1.1.14  mrg // Copyright (C) 2013-2024 Free Software Foundation, Inc.
      4       1.1  mrg //
      5       1.1  mrg // This file is part of the GNU ISO C++ Library.  This library is free
      6       1.1  mrg // software; you can redistribute it and/or modify it under the
      7       1.1  mrg // terms of the GNU General Public License as published by the
      8       1.1  mrg // Free Software Foundation; either version 3, or (at your option)
      9       1.1  mrg // any later version.
     10       1.1  mrg 
     11       1.1  mrg // This library is distributed in the hope that it will be useful,
     12       1.1  mrg // but WITHOUT ANY WARRANTY; without even the implied warranty of
     13       1.1  mrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14       1.1  mrg // GNU General Public License for more details.
     15       1.1  mrg 
     16       1.1  mrg // Under Section 7 of GPL version 3, you are granted additional
     17       1.1  mrg // permissions described in the GCC Runtime Library Exception, version
     18       1.1  mrg // 3.1, as published by the Free Software Foundation.
     19       1.1  mrg 
     20       1.1  mrg // You should have received a copy of the GNU General Public License and
     21       1.1  mrg // a copy of the GCC Runtime Library Exception along with this program;
     22       1.1  mrg // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     23       1.1  mrg // <http://www.gnu.org/licenses/>.
     24       1.1  mrg 
     25       1.1  mrg /** @file experimental/optional
     26       1.1  mrg  *  This is a TS C++ Library header.
     27  1.1.1.10  mrg  *  @ingroup libfund-ts
     28       1.1  mrg  */
     29       1.1  mrg 
     30       1.1  mrg #ifndef _GLIBCXX_EXPERIMENTAL_OPTIONAL
     31       1.1  mrg #define _GLIBCXX_EXPERIMENTAL_OPTIONAL 1
     32       1.1  mrg 
     33  1.1.1.14  mrg #include <bits/requires_hosted.h> // experimental is currently omitted
     34  1.1.1.14  mrg 
     35   1.1.1.5  mrg #if __cplusplus >= 201402L
     36       1.1  mrg 
     37       1.1  mrg #include <type_traits>
     38       1.1  mrg #include <stdexcept>
     39       1.1  mrg #include <new>
     40       1.1  mrg #include <initializer_list>
     41       1.1  mrg #include <bits/functexcept.h>
     42       1.1  mrg #include <bits/functional_hash.h>
     43       1.1  mrg #include <bits/enable_special_members.h>
     44  1.1.1.13  mrg #include <bits/move.h>
     45   1.1.1.4  mrg #include <experimental/bits/lfts_config.h>
     46       1.1  mrg 
     47       1.1  mrg namespace std _GLIBCXX_VISIBILITY(default)
     48       1.1  mrg {
     49   1.1.1.8  mrg _GLIBCXX_BEGIN_NAMESPACE_VERSION
     50   1.1.1.8  mrg 
     51       1.1  mrg namespace experimental
     52       1.1  mrg {
     53       1.1  mrg inline namespace fundamentals_v1
     54       1.1  mrg {
     55       1.1  mrg   /**
     56       1.1  mrg    * @defgroup optional Optional values
     57  1.1.1.10  mrg    * @ingroup libfund-ts
     58       1.1  mrg    *
     59       1.1  mrg    * Class template for optional values and surrounding facilities, as
     60       1.1  mrg    * described in n3793 "A proposal to add a utility class to represent
     61       1.1  mrg    * optional objects (Revision 5)".
     62       1.1  mrg    *
     63       1.1  mrg    * @{
     64       1.1  mrg    */
     65       1.1  mrg 
     66       1.1  mrg #define __cpp_lib_experimental_optional 201411
     67       1.1  mrg 
     68       1.1  mrg   // All subsequent [X.Y.n] references are against n3793.
     69       1.1  mrg 
     70       1.1  mrg   // [X.Y.4]
     71       1.1  mrg   template<typename _Tp>
     72       1.1  mrg     class optional;
     73       1.1  mrg 
     74       1.1  mrg   // [X.Y.5]
     75       1.1  mrg   /// Tag type for in-place construction.
     76       1.1  mrg   struct in_place_t { };
     77       1.1  mrg 
     78       1.1  mrg   /// Tag for in-place construction.
     79       1.1  mrg   constexpr in_place_t in_place { };
     80       1.1  mrg 
     81       1.1  mrg   // [X.Y.6]
     82       1.1  mrg   /// Tag type to disengage optional objects.
     83       1.1  mrg   struct nullopt_t
     84       1.1  mrg   {
     85       1.1  mrg     // Do not user-declare default constructor at all for
     86       1.1  mrg     // optional_value = {} syntax to work.
     87       1.1  mrg     // nullopt_t() = delete;
     88       1.1  mrg 
     89       1.1  mrg     // Used for constructing nullopt.
     90       1.1  mrg     enum class _Construct { _Token };
     91       1.1  mrg 
     92       1.1  mrg     // Must be constexpr for nullopt_t to be literal.
     93       1.1  mrg     explicit constexpr nullopt_t(_Construct) { }
     94       1.1  mrg   };
     95       1.1  mrg 
     96       1.1  mrg   // [X.Y.6]
     97       1.1  mrg   /// Tag to disengage optional objects.
     98       1.1  mrg   constexpr nullopt_t nullopt { nullopt_t::_Construct::_Token };
     99       1.1  mrg 
    100       1.1  mrg   // [X.Y.7]
    101       1.1  mrg   /**
    102       1.1  mrg    *  @brief Exception class thrown when a disengaged optional object is
    103       1.1  mrg    *  dereferenced.
    104       1.1  mrg    *  @ingroup exceptions
    105       1.1  mrg    */
    106       1.1  mrg   class bad_optional_access : public logic_error
    107       1.1  mrg   {
    108       1.1  mrg   public:
    109       1.1  mrg     bad_optional_access() : logic_error("bad optional access") { }
    110       1.1  mrg 
    111       1.1  mrg     // XXX This constructor is non-standard. Should not be inline
    112       1.1  mrg     explicit bad_optional_access(const char* __arg) : logic_error(__arg) { }
    113       1.1  mrg 
    114       1.1  mrg     virtual ~bad_optional_access() noexcept = default;
    115       1.1  mrg   };
    116       1.1  mrg 
    117  1.1.1.10  mrg   /// @cond undocumented
    118  1.1.1.10  mrg 
    119       1.1  mrg   // XXX Does not belong here.
    120  1.1.1.13  mrg   [[noreturn]] inline void
    121       1.1  mrg   __throw_bad_optional_access(const char* __s)
    122       1.1  mrg   { _GLIBCXX_THROW_OR_ABORT(bad_optional_access(__s)); }
    123       1.1  mrg 
    124       1.1  mrg   /**
    125       1.1  mrg     * @brief Class template that holds the necessary state for @ref optional
    126       1.1  mrg     * and that has the responsibility for construction and the special members.
    127       1.1  mrg     *
    128       1.1  mrg     * Such a separate base class template is necessary in order to
    129       1.1  mrg     * conditionally enable the special members (e.g. copy/move constructors).
    130       1.1  mrg     * Note that this means that @ref _Optional_base implements the
    131       1.1  mrg     * functionality for copy and move assignment, but not for converting
    132       1.1  mrg     * assignment.
    133       1.1  mrg     *
    134       1.1  mrg     * @see optional, _Enable_special_members
    135       1.1  mrg     */
    136       1.1  mrg   template<typename _Tp, bool _ShouldProvideDestructor =
    137       1.1  mrg 	   !is_trivially_destructible<_Tp>::value>
    138       1.1  mrg     class _Optional_base
    139       1.1  mrg     {
    140       1.1  mrg     private:
    141       1.1  mrg       // Remove const to avoid prohibition of reusing object storage for
    142       1.1  mrg       // const-qualified types in [3.8/9]. This is strictly internal
    143       1.1  mrg       // and even optional itself is oblivious to it.
    144       1.1  mrg       using _Stored_type = remove_const_t<_Tp>;
    145       1.1  mrg 
    146       1.1  mrg     public:
    147       1.1  mrg       // [X.Y.4.1] Constructors.
    148       1.1  mrg 
    149       1.1  mrg       // Constructors for disengaged optionals.
    150       1.1  mrg       constexpr _Optional_base() noexcept
    151       1.1  mrg       : _M_empty{} { }
    152       1.1  mrg 
    153       1.1  mrg       constexpr _Optional_base(nullopt_t) noexcept
    154       1.1  mrg       : _Optional_base{} { }
    155       1.1  mrg 
    156       1.1  mrg       // Constructors for engaged optionals.
    157       1.1  mrg       template<typename... _Args>
    158       1.1  mrg         constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
    159       1.1  mrg         : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true) { }
    160       1.1  mrg 
    161       1.1  mrg       template<typename _Up, typename... _Args,
    162       1.1  mrg                enable_if_t<is_constructible<_Tp,
    163       1.1  mrg                                             initializer_list<_Up>&,
    164       1.1  mrg                                             _Args&&...>::value,
    165       1.1  mrg                            int>...>
    166       1.1  mrg         constexpr explicit _Optional_base(in_place_t,
    167       1.1  mrg                                           initializer_list<_Up> __il,
    168       1.1  mrg                                           _Args&&... __args)
    169       1.1  mrg         : _M_payload(__il, std::forward<_Args>(__args)...),
    170       1.1  mrg           _M_engaged(true) { }
    171       1.1  mrg 
    172       1.1  mrg       // Copy and move constructors.
    173       1.1  mrg       _Optional_base(const _Optional_base& __other)
    174       1.1  mrg       {
    175       1.1  mrg         if (__other._M_engaged)
    176       1.1  mrg           this->_M_construct(__other._M_get());
    177       1.1  mrg       }
    178       1.1  mrg 
    179       1.1  mrg       _Optional_base(_Optional_base&& __other)
    180       1.1  mrg       noexcept(is_nothrow_move_constructible<_Tp>())
    181       1.1  mrg       {
    182       1.1  mrg         if (__other._M_engaged)
    183       1.1  mrg           this->_M_construct(std::move(__other._M_get()));
    184       1.1  mrg       }
    185       1.1  mrg 
    186       1.1  mrg       // [X.Y.4.3] (partly) Assignment.
    187       1.1  mrg       _Optional_base&
    188       1.1  mrg       operator=(const _Optional_base& __other)
    189       1.1  mrg       {
    190       1.1  mrg         if (this->_M_engaged && __other._M_engaged)
    191       1.1  mrg           this->_M_get() = __other._M_get();
    192       1.1  mrg         else
    193       1.1  mrg 	  {
    194       1.1  mrg 	    if (__other._M_engaged)
    195       1.1  mrg 	      this->_M_construct(__other._M_get());
    196       1.1  mrg 	    else
    197       1.1  mrg 	      this->_M_reset();
    198       1.1  mrg 	  }
    199       1.1  mrg 
    200       1.1  mrg         return *this;
    201       1.1  mrg       }
    202       1.1  mrg 
    203       1.1  mrg       _Optional_base&
    204       1.1  mrg       operator=(_Optional_base&& __other)
    205       1.1  mrg       noexcept(__and_<is_nothrow_move_constructible<_Tp>,
    206       1.1  mrg 		      is_nothrow_move_assignable<_Tp>>())
    207       1.1  mrg       {
    208       1.1  mrg 	if (this->_M_engaged && __other._M_engaged)
    209       1.1  mrg 	  this->_M_get() = std::move(__other._M_get());
    210       1.1  mrg 	else
    211       1.1  mrg 	  {
    212       1.1  mrg 	    if (__other._M_engaged)
    213       1.1  mrg 	      this->_M_construct(std::move(__other._M_get()));
    214       1.1  mrg 	    else
    215       1.1  mrg 	      this->_M_reset();
    216       1.1  mrg 	  }
    217       1.1  mrg 	return *this;
    218       1.1  mrg       }
    219       1.1  mrg 
    220       1.1  mrg       // [X.Y.4.2] Destructor.
    221       1.1  mrg       ~_Optional_base()
    222       1.1  mrg       {
    223       1.1  mrg         if (this->_M_engaged)
    224       1.1  mrg           this->_M_payload.~_Stored_type();
    225       1.1  mrg       }
    226       1.1  mrg 
    227       1.1  mrg       // The following functionality is also needed by optional, hence the
    228       1.1  mrg       // protected accessibility.
    229       1.1  mrg     protected:
    230       1.1  mrg       constexpr bool _M_is_engaged() const noexcept
    231       1.1  mrg       { return this->_M_engaged; }
    232       1.1  mrg 
    233       1.1  mrg       // The _M_get operations have _M_engaged as a precondition.
    234       1.1  mrg       constexpr _Tp&
    235       1.1  mrg       _M_get() noexcept
    236       1.1  mrg       { return _M_payload; }
    237       1.1  mrg 
    238       1.1  mrg       constexpr const _Tp&
    239       1.1  mrg       _M_get() const noexcept
    240       1.1  mrg       { return _M_payload; }
    241       1.1  mrg 
    242       1.1  mrg       // The _M_construct operation has !_M_engaged as a precondition
    243       1.1  mrg       // while _M_destruct has _M_engaged as a precondition.
    244       1.1  mrg       template<typename... _Args>
    245       1.1  mrg         void
    246       1.1  mrg         _M_construct(_Args&&... __args)
    247       1.1  mrg         noexcept(is_nothrow_constructible<_Stored_type, _Args...>())
    248       1.1  mrg         {
    249       1.1  mrg           ::new (std::__addressof(this->_M_payload))
    250       1.1  mrg             _Stored_type(std::forward<_Args>(__args)...);
    251       1.1  mrg           this->_M_engaged = true;
    252       1.1  mrg         }
    253       1.1  mrg 
    254       1.1  mrg       void
    255       1.1  mrg       _M_destruct()
    256       1.1  mrg       {
    257       1.1  mrg         this->_M_engaged = false;
    258       1.1  mrg         this->_M_payload.~_Stored_type();
    259       1.1  mrg       }
    260       1.1  mrg 
    261       1.1  mrg       // _M_reset is a 'safe' operation with no precondition.
    262       1.1  mrg       void
    263       1.1  mrg       _M_reset()
    264       1.1  mrg       {
    265       1.1  mrg         if (this->_M_engaged)
    266       1.1  mrg           this->_M_destruct();
    267       1.1  mrg       }
    268       1.1  mrg 
    269       1.1  mrg     private:
    270       1.1  mrg       struct _Empty_byte { };
    271       1.1  mrg       union {
    272       1.1  mrg           _Empty_byte _M_empty;
    273       1.1  mrg           _Stored_type _M_payload;
    274       1.1  mrg       };
    275       1.1  mrg       bool _M_engaged = false;
    276       1.1  mrg     };
    277       1.1  mrg 
    278       1.1  mrg   /// Partial specialization that is exactly identical to the primary template
    279       1.1  mrg   /// save for not providing a destructor, to fulfill triviality requirements.
    280       1.1  mrg   template<typename _Tp>
    281       1.1  mrg     class _Optional_base<_Tp, false>
    282       1.1  mrg     {
    283       1.1  mrg     private:
    284       1.1  mrg       using _Stored_type = remove_const_t<_Tp>;
    285       1.1  mrg 
    286       1.1  mrg     public:
    287       1.1  mrg       constexpr _Optional_base() noexcept
    288       1.1  mrg       : _M_empty{} { }
    289       1.1  mrg 
    290       1.1  mrg       constexpr _Optional_base(nullopt_t) noexcept
    291       1.1  mrg       : _Optional_base{} { }
    292       1.1  mrg 
    293       1.1  mrg       template<typename... _Args>
    294       1.1  mrg         constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
    295       1.1  mrg         : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true) { }
    296       1.1  mrg 
    297       1.1  mrg       template<typename _Up, typename... _Args,
    298       1.1  mrg                enable_if_t<is_constructible<_Tp,
    299       1.1  mrg                                             initializer_list<_Up>&,
    300       1.1  mrg                                             _Args&&...>::value,
    301       1.1  mrg 			   int>...>
    302       1.1  mrg         constexpr explicit _Optional_base(in_place_t,
    303       1.1  mrg                                           initializer_list<_Up> __il,
    304       1.1  mrg                                           _Args&&... __args)
    305       1.1  mrg         : _M_payload(__il, std::forward<_Args>(__args)...),
    306       1.1  mrg           _M_engaged(true) { }
    307       1.1  mrg 
    308       1.1  mrg       _Optional_base(const _Optional_base& __other)
    309       1.1  mrg       {
    310       1.1  mrg         if (__other._M_engaged)
    311       1.1  mrg           this->_M_construct(__other._M_get());
    312       1.1  mrg       }
    313       1.1  mrg 
    314       1.1  mrg       _Optional_base(_Optional_base&& __other)
    315       1.1  mrg       noexcept(is_nothrow_move_constructible<_Tp>())
    316       1.1  mrg       {
    317       1.1  mrg         if (__other._M_engaged)
    318       1.1  mrg           this->_M_construct(std::move(__other._M_get()));
    319       1.1  mrg       }
    320       1.1  mrg 
    321       1.1  mrg       _Optional_base&
    322       1.1  mrg       operator=(const _Optional_base& __other)
    323       1.1  mrg       {
    324       1.1  mrg 	if (this->_M_engaged && __other._M_engaged)
    325       1.1  mrg 	  this->_M_get() = __other._M_get();
    326       1.1  mrg 	else
    327       1.1  mrg 	  {
    328       1.1  mrg 	    if (__other._M_engaged)
    329       1.1  mrg 	      this->_M_construct(__other._M_get());
    330       1.1  mrg 	    else
    331       1.1  mrg 	      this->_M_reset();
    332       1.1  mrg 	  }
    333       1.1  mrg 	return *this;
    334       1.1  mrg       }
    335       1.1  mrg 
    336       1.1  mrg       _Optional_base&
    337       1.1  mrg       operator=(_Optional_base&& __other)
    338       1.1  mrg       noexcept(__and_<is_nothrow_move_constructible<_Tp>,
    339       1.1  mrg 		      is_nothrow_move_assignable<_Tp>>())
    340       1.1  mrg       {
    341       1.1  mrg 	if (this->_M_engaged && __other._M_engaged)
    342       1.1  mrg 	  this->_M_get() = std::move(__other._M_get());
    343       1.1  mrg 	else
    344       1.1  mrg 	  {
    345       1.1  mrg 	    if (__other._M_engaged)
    346       1.1  mrg 	      this->_M_construct(std::move(__other._M_get()));
    347       1.1  mrg 	    else
    348       1.1  mrg 	      this->_M_reset();
    349       1.1  mrg 	  }
    350       1.1  mrg 	return *this;
    351       1.1  mrg       }
    352       1.1  mrg 
    353       1.1  mrg       // Sole difference
    354       1.1  mrg       // ~_Optional_base() noexcept = default;
    355       1.1  mrg 
    356       1.1  mrg     protected:
    357       1.1  mrg       constexpr bool _M_is_engaged() const noexcept
    358       1.1  mrg       { return this->_M_engaged; }
    359       1.1  mrg 
    360       1.1  mrg       _Tp&
    361       1.1  mrg       _M_get() noexcept
    362       1.1  mrg       { return _M_payload; }
    363       1.1  mrg 
    364       1.1  mrg       constexpr const _Tp&
    365       1.1  mrg       _M_get() const noexcept
    366       1.1  mrg       { return _M_payload; }
    367       1.1  mrg 
    368       1.1  mrg       template<typename... _Args>
    369       1.1  mrg         void
    370       1.1  mrg         _M_construct(_Args&&... __args)
    371       1.1  mrg         noexcept(is_nothrow_constructible<_Stored_type, _Args...>())
    372       1.1  mrg         {
    373       1.1  mrg           ::new (std::__addressof(this->_M_payload))
    374       1.1  mrg             _Stored_type(std::forward<_Args>(__args)...);
    375       1.1  mrg           this->_M_engaged = true;
    376       1.1  mrg         }
    377       1.1  mrg 
    378       1.1  mrg       void
    379       1.1  mrg       _M_destruct()
    380       1.1  mrg       {
    381       1.1  mrg         this->_M_engaged = false;
    382       1.1  mrg         this->_M_payload.~_Stored_type();
    383       1.1  mrg       }
    384       1.1  mrg 
    385       1.1  mrg       void
    386       1.1  mrg       _M_reset()
    387       1.1  mrg       {
    388       1.1  mrg         if (this->_M_engaged)
    389       1.1  mrg           this->_M_destruct();
    390       1.1  mrg       }
    391       1.1  mrg 
    392       1.1  mrg     private:
    393       1.1  mrg       struct _Empty_byte { };
    394       1.1  mrg       union
    395       1.1  mrg       {
    396       1.1  mrg 	_Empty_byte _M_empty;
    397       1.1  mrg 	_Stored_type _M_payload;
    398       1.1  mrg       };
    399       1.1  mrg       bool _M_engaged = false;
    400       1.1  mrg     };
    401       1.1  mrg 
    402   1.1.1.4  mrg   template<typename _Tp, typename _Up>
    403   1.1.1.4  mrg     using __converts_from_optional =
    404   1.1.1.4  mrg       __or_<is_constructible<_Tp, const optional<_Up>&>,
    405   1.1.1.4  mrg 	    is_constructible<_Tp, optional<_Up>&>,
    406   1.1.1.4  mrg 	    is_constructible<_Tp, const optional<_Up>&&>,
    407   1.1.1.4  mrg 	    is_constructible<_Tp, optional<_Up>&&>,
    408   1.1.1.4  mrg 	    is_convertible<const optional<_Up>&, _Tp>,
    409   1.1.1.4  mrg 	    is_convertible<optional<_Up>&, _Tp>,
    410   1.1.1.4  mrg 	    is_convertible<const optional<_Up>&&, _Tp>,
    411   1.1.1.4  mrg 	    is_convertible<optional<_Up>&&, _Tp>>;
    412   1.1.1.4  mrg 
    413   1.1.1.4  mrg   template<typename _Tp, typename _Up>
    414   1.1.1.4  mrg     using __assigns_from_optional =
    415   1.1.1.4  mrg       __or_<is_assignable<_Tp&, const optional<_Up>&>,
    416   1.1.1.4  mrg 	    is_assignable<_Tp&, optional<_Up>&>,
    417   1.1.1.4  mrg 	    is_assignable<_Tp&, const optional<_Up>&&>,
    418   1.1.1.4  mrg 	    is_assignable<_Tp&, optional<_Up>&&>>;
    419   1.1.1.4  mrg 
    420  1.1.1.10  mrg   /// @endcond
    421  1.1.1.10  mrg 
    422       1.1  mrg   /**
    423       1.1  mrg     * @brief Class template for optional values.
    424       1.1  mrg     */
    425       1.1  mrg   template<typename _Tp>
    426       1.1  mrg     class optional
    427       1.1  mrg     : private _Optional_base<_Tp>,
    428       1.1  mrg       private _Enable_copy_move<
    429       1.1  mrg         // Copy constructor.
    430       1.1  mrg         is_copy_constructible<_Tp>::value,
    431       1.1  mrg         // Copy assignment.
    432       1.1  mrg         __and_<is_copy_constructible<_Tp>, is_copy_assignable<_Tp>>::value,
    433       1.1  mrg         // Move constructor.
    434       1.1  mrg         is_move_constructible<_Tp>::value,
    435       1.1  mrg         // Move assignment.
    436       1.1  mrg         __and_<is_move_constructible<_Tp>, is_move_assignable<_Tp>>::value,
    437       1.1  mrg         // Unique tag type.
    438       1.1  mrg         optional<_Tp>>
    439       1.1  mrg     {
    440       1.1  mrg       static_assert(__and_<__not_<is_same<remove_cv_t<_Tp>, nullopt_t>>,
    441       1.1  mrg 			   __not_<is_same<remove_cv_t<_Tp>, in_place_t>>,
    442       1.1  mrg 			   __not_<is_reference<_Tp>>>(),
    443       1.1  mrg                     "Invalid instantiation of optional<T>");
    444       1.1  mrg 
    445       1.1  mrg     private:
    446       1.1  mrg       using _Base = _Optional_base<_Tp>;
    447       1.1  mrg 
    448       1.1  mrg     public:
    449       1.1  mrg       using value_type = _Tp;
    450       1.1  mrg 
    451       1.1  mrg       // _Optional_base has the responsibility for construction.
    452       1.1  mrg       using _Base::_Base;
    453       1.1  mrg 
    454   1.1.1.4  mrg       constexpr optional() = default;
    455   1.1.1.4  mrg       // Converting constructors for engaged optionals.
    456   1.1.1.4  mrg       template <typename _Up = _Tp,
    457   1.1.1.4  mrg                 enable_if_t<__and_<
    458   1.1.1.4  mrg 			      __not_<is_same<optional<_Tp>, decay_t<_Up>>>,
    459   1.1.1.4  mrg 			      is_constructible<_Tp, _Up&&>,
    460   1.1.1.4  mrg 			      is_convertible<_Up&&, _Tp>
    461   1.1.1.4  mrg 			      >::value, bool> = true>
    462   1.1.1.4  mrg       constexpr optional(_Up&& __t)
    463   1.1.1.4  mrg         : _Base(in_place, std::forward<_Up>(__t)) { }
    464   1.1.1.4  mrg 
    465   1.1.1.4  mrg       template <typename _Up = _Tp,
    466   1.1.1.4  mrg                 enable_if_t<__and_<
    467   1.1.1.4  mrg 			      __not_<is_same<optional<_Tp>, decay_t<_Up>>>,
    468   1.1.1.4  mrg 			      is_constructible<_Tp, _Up&&>,
    469   1.1.1.4  mrg 			      __not_<is_convertible<_Up&&, _Tp>>
    470   1.1.1.4  mrg 			      >::value, bool> = false>
    471   1.1.1.4  mrg       explicit constexpr optional(_Up&& __t)
    472   1.1.1.4  mrg         : _Base(in_place, std::forward<_Up>(__t)) { }
    473   1.1.1.4  mrg 
    474   1.1.1.4  mrg       template <typename _Up,
    475   1.1.1.4  mrg                 enable_if_t<__and_<
    476   1.1.1.4  mrg 			    __not_<is_same<_Tp, _Up>>,
    477   1.1.1.4  mrg 			    is_constructible<_Tp, const _Up&>,
    478   1.1.1.4  mrg 			    is_convertible<const _Up&, _Tp>,
    479   1.1.1.4  mrg 			    __not_<__converts_from_optional<_Tp, _Up>>
    480   1.1.1.4  mrg 			    >::value, bool> = true>
    481   1.1.1.4  mrg       constexpr optional(const optional<_Up>& __t)
    482   1.1.1.4  mrg       {
    483   1.1.1.4  mrg 	if (__t)
    484   1.1.1.4  mrg 	  emplace(*__t);
    485   1.1.1.4  mrg       }
    486   1.1.1.4  mrg 
    487   1.1.1.4  mrg       template <typename _Up,
    488   1.1.1.4  mrg                  enable_if_t<__and_<
    489   1.1.1.4  mrg 			       __not_<is_same<_Tp, _Up>>,
    490   1.1.1.4  mrg 			       is_constructible<_Tp, const _Up&>,
    491   1.1.1.4  mrg 			       __not_<is_convertible<const _Up&, _Tp>>,
    492   1.1.1.4  mrg 			       __not_<__converts_from_optional<_Tp, _Up>>
    493   1.1.1.4  mrg 			       >::value, bool> = false>
    494   1.1.1.4  mrg       explicit constexpr optional(const optional<_Up>& __t)
    495   1.1.1.4  mrg       {
    496   1.1.1.4  mrg 	if (__t)
    497   1.1.1.4  mrg 	  emplace(*__t);
    498   1.1.1.4  mrg       }
    499   1.1.1.4  mrg 
    500   1.1.1.4  mrg       template <typename _Up,
    501   1.1.1.4  mrg                 enable_if_t<__and_<
    502   1.1.1.4  mrg 			      __not_<is_same<_Tp, _Up>>,
    503   1.1.1.4  mrg 			      is_constructible<_Tp, _Up&&>,
    504   1.1.1.4  mrg 			      is_convertible<_Up&&, _Tp>,
    505   1.1.1.4  mrg 			      __not_<__converts_from_optional<_Tp, _Up>>
    506   1.1.1.4  mrg 			      >::value, bool> = true>
    507   1.1.1.4  mrg       constexpr optional(optional<_Up>&& __t)
    508   1.1.1.4  mrg       {
    509   1.1.1.4  mrg 	if (__t)
    510   1.1.1.4  mrg 	  emplace(std::move(*__t));
    511   1.1.1.4  mrg       }
    512   1.1.1.4  mrg 
    513   1.1.1.4  mrg       template <typename _Up,
    514   1.1.1.4  mrg                 enable_if_t<__and_<
    515   1.1.1.4  mrg 			    __not_<is_same<_Tp, _Up>>,
    516   1.1.1.4  mrg 			    is_constructible<_Tp, _Up&&>,
    517   1.1.1.4  mrg 			    __not_<is_convertible<_Up&&, _Tp>>,
    518   1.1.1.4  mrg 			    __not_<__converts_from_optional<_Tp, _Up>>
    519   1.1.1.4  mrg 			    >::value, bool> = false>
    520   1.1.1.4  mrg       explicit constexpr optional(optional<_Up>&& __t)
    521   1.1.1.4  mrg       {
    522   1.1.1.4  mrg 	if (__t)
    523   1.1.1.4  mrg 	  emplace(std::move(*__t));
    524   1.1.1.4  mrg       }
    525   1.1.1.4  mrg 
    526       1.1  mrg       // [X.Y.4.3] (partly) Assignment.
    527       1.1  mrg       optional&
    528       1.1  mrg       operator=(nullopt_t) noexcept
    529       1.1  mrg       {
    530       1.1  mrg         this->_M_reset();
    531       1.1  mrg         return *this;
    532       1.1  mrg       }
    533       1.1  mrg 
    534   1.1.1.4  mrg       template<typename _Up = _Tp>
    535   1.1.1.4  mrg         enable_if_t<__and_<
    536   1.1.1.4  mrg 		      __not_<is_same<optional<_Tp>, decay_t<_Up>>>,
    537   1.1.1.4  mrg 		      is_constructible<_Tp, _Up>,
    538   1.1.1.4  mrg 		      __not_<__and_<is_scalar<_Tp>,
    539   1.1.1.4  mrg 				    is_same<_Tp, decay_t<_Up>>>>,
    540   1.1.1.4  mrg 		      is_assignable<_Tp&, _Up>>::value,
    541   1.1.1.4  mrg 		    optional&>
    542       1.1  mrg         operator=(_Up&& __u)
    543       1.1  mrg         {
    544       1.1  mrg           if (this->_M_is_engaged())
    545       1.1  mrg             this->_M_get() = std::forward<_Up>(__u);
    546       1.1  mrg           else
    547       1.1  mrg             this->_M_construct(std::forward<_Up>(__u));
    548       1.1  mrg 
    549       1.1  mrg           return *this;
    550       1.1  mrg         }
    551       1.1  mrg 
    552   1.1.1.4  mrg       template<typename _Up>
    553   1.1.1.4  mrg 	enable_if_t<__and_<
    554   1.1.1.4  mrg 		      __not_<is_same<_Tp, _Up>>,
    555   1.1.1.4  mrg 		      is_constructible<_Tp, const _Up&>,
    556   1.1.1.4  mrg 		      is_assignable<_Tp&, _Up>,
    557   1.1.1.4  mrg 		      __not_<__converts_from_optional<_Tp, _Up>>,
    558   1.1.1.4  mrg 		      __not_<__assigns_from_optional<_Tp, _Up>>
    559   1.1.1.4  mrg 		      >::value,
    560   1.1.1.4  mrg 		    optional&>
    561   1.1.1.4  mrg         operator=(const optional<_Up>& __u)
    562   1.1.1.4  mrg         {
    563   1.1.1.4  mrg           if (__u)
    564   1.1.1.4  mrg             {
    565   1.1.1.4  mrg               if (this->_M_is_engaged())
    566   1.1.1.4  mrg                 this->_M_get() = *__u;
    567   1.1.1.4  mrg               else
    568   1.1.1.4  mrg                 this->_M_construct(*__u);
    569   1.1.1.4  mrg             }
    570   1.1.1.4  mrg           else
    571   1.1.1.4  mrg             {
    572   1.1.1.4  mrg               this->_M_reset();
    573   1.1.1.4  mrg             }
    574   1.1.1.4  mrg           return *this;
    575   1.1.1.4  mrg         }
    576   1.1.1.4  mrg 
    577   1.1.1.4  mrg       template<typename _Up>
    578   1.1.1.4  mrg 	enable_if_t<__and_<
    579   1.1.1.4  mrg 		      __not_<is_same<_Tp, _Up>>,
    580   1.1.1.4  mrg 		      is_constructible<_Tp, _Up>,
    581   1.1.1.4  mrg 		      is_assignable<_Tp&, _Up>,
    582   1.1.1.4  mrg 		      __not_<__converts_from_optional<_Tp, _Up>>,
    583   1.1.1.4  mrg 		      __not_<__assigns_from_optional<_Tp, _Up>>
    584   1.1.1.4  mrg 		      >::value,
    585   1.1.1.4  mrg 		    optional&>
    586   1.1.1.4  mrg         operator=(optional<_Up>&& __u)
    587   1.1.1.4  mrg         {
    588   1.1.1.4  mrg           if (__u)
    589   1.1.1.4  mrg             {
    590   1.1.1.4  mrg               if (this->_M_is_engaged())
    591   1.1.1.4  mrg                 this->_M_get() = std::move(*__u);
    592   1.1.1.4  mrg               else
    593   1.1.1.4  mrg                 this->_M_construct(std::move(*__u));
    594   1.1.1.4  mrg             }
    595   1.1.1.4  mrg           else
    596   1.1.1.4  mrg             {
    597   1.1.1.4  mrg               this->_M_reset();
    598   1.1.1.4  mrg             }
    599   1.1.1.4  mrg 
    600   1.1.1.4  mrg           return *this;
    601   1.1.1.4  mrg         }
    602   1.1.1.4  mrg 
    603       1.1  mrg       template<typename... _Args>
    604   1.1.1.4  mrg 	enable_if_t<is_constructible<_Tp, _Args&&...>::value>
    605       1.1  mrg 	emplace(_Args&&... __args)
    606       1.1  mrg 	{
    607       1.1  mrg 	  this->_M_reset();
    608       1.1  mrg 	  this->_M_construct(std::forward<_Args>(__args)...);
    609       1.1  mrg 	}
    610       1.1  mrg 
    611       1.1  mrg       template<typename _Up, typename... _Args>
    612   1.1.1.4  mrg 	enable_if_t<is_constructible<_Tp, initializer_list<_Up>&,
    613       1.1  mrg 				     _Args&&...>::value>
    614       1.1  mrg 	emplace(initializer_list<_Up> __il, _Args&&... __args)
    615       1.1  mrg 	{
    616       1.1  mrg 	  this->_M_reset();
    617       1.1  mrg 	  this->_M_construct(__il, std::forward<_Args>(__args)...);
    618       1.1  mrg 	}
    619       1.1  mrg 
    620       1.1  mrg       // [X.Y.4.2] Destructor is implicit, implemented in _Optional_base.
    621       1.1  mrg 
    622       1.1  mrg       // [X.Y.4.4] Swap.
    623       1.1  mrg       void
    624       1.1  mrg       swap(optional& __other)
    625       1.1  mrg       noexcept(is_nothrow_move_constructible<_Tp>()
    626   1.1.1.8  mrg                && __is_nothrow_swappable<_Tp>::value)
    627       1.1  mrg       {
    628       1.1  mrg         using std::swap;
    629       1.1  mrg 
    630       1.1  mrg         if (this->_M_is_engaged() && __other._M_is_engaged())
    631       1.1  mrg           swap(this->_M_get(), __other._M_get());
    632       1.1  mrg         else if (this->_M_is_engaged())
    633       1.1  mrg 	  {
    634       1.1  mrg 	    __other._M_construct(std::move(this->_M_get()));
    635       1.1  mrg 	    this->_M_destruct();
    636       1.1  mrg 	  }
    637       1.1  mrg         else if (__other._M_is_engaged())
    638       1.1  mrg 	  {
    639       1.1  mrg 	    this->_M_construct(std::move(__other._M_get()));
    640       1.1  mrg 	    __other._M_destruct();
    641       1.1  mrg 	  }
    642       1.1  mrg       }
    643       1.1  mrg 
    644       1.1  mrg       // [X.Y.4.5] Observers.
    645       1.1  mrg       constexpr const _Tp*
    646       1.1  mrg       operator->() const
    647  1.1.1.10  mrg       { return std::__addressof(this->_M_get()); }
    648       1.1  mrg 
    649       1.1  mrg       _Tp*
    650       1.1  mrg       operator->()
    651       1.1  mrg       { return std::__addressof(this->_M_get()); }
    652       1.1  mrg 
    653       1.1  mrg       constexpr const _Tp&
    654       1.1  mrg       operator*() const&
    655       1.1  mrg       { return this->_M_get(); }
    656       1.1  mrg 
    657       1.1  mrg       constexpr _Tp&
    658       1.1  mrg       operator*()&
    659       1.1  mrg       { return this->_M_get(); }
    660       1.1  mrg 
    661       1.1  mrg       constexpr _Tp&&
    662       1.1  mrg       operator*()&&
    663       1.1  mrg       { return std::move(this->_M_get()); }
    664       1.1  mrg 
    665       1.1  mrg       constexpr const _Tp&&
    666       1.1  mrg       operator*() const&&
    667       1.1  mrg       { return std::move(this->_M_get()); }
    668       1.1  mrg 
    669       1.1  mrg       constexpr explicit operator bool() const noexcept
    670       1.1  mrg       { return this->_M_is_engaged(); }
    671       1.1  mrg 
    672       1.1  mrg       constexpr const _Tp&
    673       1.1  mrg       value() const&
    674       1.1  mrg       {
    675  1.1.1.13  mrg 	if (this->_M_is_engaged())
    676  1.1.1.13  mrg 	  return this->_M_get();
    677  1.1.1.13  mrg 	__throw_bad_optional_access("Attempt to access value of a "
    678  1.1.1.13  mrg 				    "disengaged optional object");
    679       1.1  mrg       }
    680       1.1  mrg 
    681       1.1  mrg       constexpr _Tp&
    682       1.1  mrg       value()&
    683       1.1  mrg       {
    684  1.1.1.13  mrg 	if (this->_M_is_engaged())
    685  1.1.1.13  mrg 	  return this->_M_get();
    686  1.1.1.13  mrg 	__throw_bad_optional_access("Attempt to access value of a "
    687  1.1.1.13  mrg 				    "disengaged optional object");
    688       1.1  mrg       }
    689       1.1  mrg 
    690       1.1  mrg       constexpr _Tp&&
    691       1.1  mrg       value()&&
    692       1.1  mrg       {
    693  1.1.1.13  mrg 	if (this->_M_is_engaged())
    694  1.1.1.13  mrg 	  return std::move(this->_M_get());
    695  1.1.1.13  mrg 	__throw_bad_optional_access("Attempt to access value of a "
    696  1.1.1.13  mrg 				    "disengaged optional object");
    697       1.1  mrg       }
    698       1.1  mrg 
    699       1.1  mrg       constexpr const _Tp&&
    700       1.1  mrg       value() const&&
    701       1.1  mrg       {
    702  1.1.1.13  mrg 	if (this->_M_is_engaged())
    703  1.1.1.13  mrg 	  return std::move(this->_M_get());
    704  1.1.1.13  mrg 	__throw_bad_optional_access("Attempt to access value of a "
    705  1.1.1.13  mrg 				    "disengaged optional object");
    706       1.1  mrg       }
    707       1.1  mrg 
    708       1.1  mrg       template<typename _Up>
    709       1.1  mrg 	constexpr _Tp
    710       1.1  mrg 	value_or(_Up&& __u) const&
    711       1.1  mrg 	{
    712       1.1  mrg 	  static_assert(__and_<is_copy_constructible<_Tp>,
    713       1.1  mrg 			       is_convertible<_Up&&, _Tp>>(),
    714       1.1  mrg 			"Cannot return value");
    715       1.1  mrg 
    716  1.1.1.13  mrg 	  if (this->_M_is_engaged())
    717  1.1.1.13  mrg 	    return this->_M_get();
    718  1.1.1.13  mrg 	  else
    719  1.1.1.13  mrg 	    return static_cast<_Tp>(std::forward<_Up>(__u));
    720       1.1  mrg 	}
    721       1.1  mrg 
    722       1.1  mrg       template<typename _Up>
    723       1.1  mrg 	_Tp
    724       1.1  mrg 	value_or(_Up&& __u) &&
    725       1.1  mrg 	{
    726       1.1  mrg 	  static_assert(__and_<is_move_constructible<_Tp>,
    727       1.1  mrg 			       is_convertible<_Up&&, _Tp>>(),
    728       1.1  mrg 			"Cannot return value" );
    729       1.1  mrg 
    730  1.1.1.13  mrg 	  if (this->_M_is_engaged())
    731  1.1.1.13  mrg 	    return std::move(this->_M_get());
    732  1.1.1.13  mrg 	  else
    733  1.1.1.13  mrg 	    return static_cast<_Tp>(std::forward<_Up>(__u));
    734       1.1  mrg 	}
    735       1.1  mrg     };
    736       1.1  mrg 
    737  1.1.1.10  mrg   /// @relates experimental::optional @{
    738  1.1.1.10  mrg 
    739       1.1  mrg   // [X.Y.8] Comparisons between optional values.
    740       1.1  mrg   template<typename _Tp>
    741       1.1  mrg     constexpr bool
    742       1.1  mrg     operator==(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs)
    743       1.1  mrg     {
    744       1.1  mrg       return static_cast<bool>(__lhs) == static_cast<bool>(__rhs)
    745       1.1  mrg 	     && (!__lhs || *__lhs == *__rhs);
    746       1.1  mrg     }
    747       1.1  mrg 
    748       1.1  mrg   template<typename _Tp>
    749       1.1  mrg     constexpr bool
    750       1.1  mrg     operator!=(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs)
    751       1.1  mrg     { return !(__lhs == __rhs); }
    752       1.1  mrg 
    753       1.1  mrg   template<typename _Tp>
    754       1.1  mrg     constexpr bool
    755       1.1  mrg     operator<(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs)
    756       1.1  mrg     {
    757       1.1  mrg       return static_cast<bool>(__rhs) && (!__lhs || *__lhs < *__rhs);
    758       1.1  mrg     }
    759       1.1  mrg 
    760       1.1  mrg   template<typename _Tp>
    761       1.1  mrg     constexpr bool
    762       1.1  mrg     operator>(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs)
    763       1.1  mrg     { return __rhs < __lhs; }
    764       1.1  mrg 
    765       1.1  mrg   template<typename _Tp>
    766       1.1  mrg     constexpr bool
    767       1.1  mrg     operator<=(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs)
    768       1.1  mrg     { return !(__rhs < __lhs); }
    769       1.1  mrg 
    770       1.1  mrg   template<typename _Tp>
    771       1.1  mrg     constexpr bool
    772       1.1  mrg     operator>=(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs)
    773       1.1  mrg     { return !(__lhs < __rhs); }
    774       1.1  mrg 
    775       1.1  mrg   // [X.Y.9] Comparisons with nullopt.
    776       1.1  mrg   template<typename _Tp>
    777       1.1  mrg     constexpr bool
    778       1.1  mrg     operator==(const optional<_Tp>& __lhs, nullopt_t) noexcept
    779       1.1  mrg     { return !__lhs; }
    780       1.1  mrg 
    781       1.1  mrg   template<typename _Tp>
    782       1.1  mrg     constexpr bool
    783       1.1  mrg     operator==(nullopt_t, const optional<_Tp>& __rhs) noexcept
    784       1.1  mrg     { return !__rhs; }
    785       1.1  mrg 
    786       1.1  mrg   template<typename _Tp>
    787       1.1  mrg     constexpr bool
    788       1.1  mrg     operator!=(const optional<_Tp>& __lhs, nullopt_t) noexcept
    789       1.1  mrg     { return static_cast<bool>(__lhs); }
    790       1.1  mrg 
    791       1.1  mrg   template<typename _Tp>
    792       1.1  mrg     constexpr bool
    793       1.1  mrg     operator!=(nullopt_t, const optional<_Tp>& __rhs) noexcept
    794       1.1  mrg     { return static_cast<bool>(__rhs); }
    795       1.1  mrg 
    796       1.1  mrg   template<typename _Tp>
    797       1.1  mrg     constexpr bool
    798       1.1  mrg     operator<(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept
    799       1.1  mrg     { return false; }
    800       1.1  mrg 
    801       1.1  mrg   template<typename _Tp>
    802       1.1  mrg     constexpr bool
    803       1.1  mrg     operator<(nullopt_t, const optional<_Tp>& __rhs) noexcept
    804       1.1  mrg     { return static_cast<bool>(__rhs); }
    805       1.1  mrg 
    806       1.1  mrg   template<typename _Tp>
    807       1.1  mrg     constexpr bool
    808       1.1  mrg     operator>(const optional<_Tp>& __lhs, nullopt_t) noexcept
    809       1.1  mrg     { return static_cast<bool>(__lhs); }
    810       1.1  mrg 
    811       1.1  mrg   template<typename _Tp>
    812       1.1  mrg     constexpr bool
    813       1.1  mrg     operator>(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept
    814       1.1  mrg     { return false; }
    815       1.1  mrg 
    816       1.1  mrg   template<typename _Tp>
    817       1.1  mrg     constexpr bool
    818       1.1  mrg     operator<=(const optional<_Tp>& __lhs, nullopt_t) noexcept
    819       1.1  mrg     { return !__lhs; }
    820       1.1  mrg 
    821       1.1  mrg   template<typename _Tp>
    822       1.1  mrg     constexpr bool
    823       1.1  mrg     operator<=(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept
    824       1.1  mrg     { return true; }
    825       1.1  mrg 
    826       1.1  mrg   template<typename _Tp>
    827       1.1  mrg     constexpr bool
    828       1.1  mrg     operator>=(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept
    829       1.1  mrg     { return true; }
    830       1.1  mrg 
    831       1.1  mrg   template<typename _Tp>
    832       1.1  mrg     constexpr bool
    833       1.1  mrg     operator>=(nullopt_t, const optional<_Tp>& __rhs) noexcept
    834       1.1  mrg     { return !__rhs; }
    835       1.1  mrg 
    836       1.1  mrg   // [X.Y.10] Comparisons with value type.
    837       1.1  mrg   template<typename _Tp>
    838       1.1  mrg     constexpr bool
    839       1.1  mrg     operator==(const optional<_Tp>& __lhs, const _Tp& __rhs)
    840       1.1  mrg     { return __lhs && *__lhs == __rhs; }
    841       1.1  mrg 
    842       1.1  mrg   template<typename _Tp>
    843       1.1  mrg     constexpr bool
    844       1.1  mrg     operator==(const _Tp& __lhs, const optional<_Tp>& __rhs)
    845       1.1  mrg     { return __rhs && __lhs == *__rhs; }
    846       1.1  mrg 
    847       1.1  mrg   template<typename _Tp>
    848       1.1  mrg     constexpr bool
    849       1.1  mrg     operator!=(const optional<_Tp>& __lhs, _Tp const& __rhs)
    850       1.1  mrg     { return !__lhs || !(*__lhs == __rhs); }
    851       1.1  mrg 
    852       1.1  mrg   template<typename _Tp>
    853       1.1  mrg     constexpr bool
    854       1.1  mrg     operator!=(const _Tp& __lhs, const optional<_Tp>& __rhs)
    855       1.1  mrg     { return !__rhs || !(__lhs == *__rhs); }
    856       1.1  mrg 
    857       1.1  mrg   template<typename _Tp>
    858       1.1  mrg     constexpr bool
    859       1.1  mrg     operator<(const optional<_Tp>& __lhs, const _Tp& __rhs)
    860       1.1  mrg     { return !__lhs || *__lhs < __rhs; }
    861       1.1  mrg 
    862       1.1  mrg   template<typename _Tp>
    863       1.1  mrg     constexpr bool
    864       1.1  mrg     operator<(const _Tp& __lhs, const optional<_Tp>& __rhs)
    865       1.1  mrg     { return __rhs && __lhs < *__rhs; }
    866       1.1  mrg 
    867       1.1  mrg   template<typename _Tp>
    868       1.1  mrg     constexpr bool
    869       1.1  mrg     operator>(const optional<_Tp>& __lhs, const _Tp& __rhs)
    870       1.1  mrg     { return __lhs && __rhs < *__lhs; }
    871       1.1  mrg 
    872       1.1  mrg   template<typename _Tp>
    873       1.1  mrg     constexpr bool
    874       1.1  mrg     operator>(const _Tp& __lhs, const optional<_Tp>& __rhs)
    875       1.1  mrg     { return !__rhs || *__rhs < __lhs; }
    876       1.1  mrg 
    877       1.1  mrg   template<typename _Tp>
    878       1.1  mrg     constexpr bool
    879       1.1  mrg     operator<=(const optional<_Tp>& __lhs, const _Tp& __rhs)
    880       1.1  mrg     { return !__lhs || !(__rhs < *__lhs); }
    881       1.1  mrg 
    882       1.1  mrg   template<typename _Tp>
    883       1.1  mrg     constexpr bool
    884       1.1  mrg     operator<=(const _Tp& __lhs, const optional<_Tp>& __rhs)
    885       1.1  mrg     { return __rhs && !(*__rhs < __lhs); }
    886       1.1  mrg 
    887       1.1  mrg   template<typename _Tp>
    888       1.1  mrg     constexpr bool
    889       1.1  mrg     operator>=(const optional<_Tp>& __lhs, const _Tp& __rhs)
    890       1.1  mrg     { return __lhs && !(*__lhs < __rhs); }
    891       1.1  mrg 
    892       1.1  mrg   template<typename _Tp>
    893       1.1  mrg     constexpr bool
    894       1.1  mrg     operator>=(const _Tp& __lhs, const optional<_Tp>& __rhs)
    895       1.1  mrg     { return !__rhs || !(__lhs < *__rhs); }
    896       1.1  mrg 
    897       1.1  mrg   // [X.Y.11]
    898       1.1  mrg   template<typename _Tp>
    899       1.1  mrg     inline void
    900       1.1  mrg     swap(optional<_Tp>& __lhs, optional<_Tp>& __rhs)
    901       1.1  mrg     noexcept(noexcept(__lhs.swap(__rhs)))
    902       1.1  mrg     { __lhs.swap(__rhs); }
    903       1.1  mrg 
    904       1.1  mrg   template<typename _Tp>
    905       1.1  mrg     constexpr optional<decay_t<_Tp>>
    906       1.1  mrg     make_optional(_Tp&& __t)
    907       1.1  mrg     { return optional<decay_t<_Tp>> { std::forward<_Tp>(__t) }; }
    908       1.1  mrg 
    909  1.1.1.11  mrg   /// @} relates experimental::optional
    910  1.1.1.11  mrg   /// @} group optional
    911       1.1  mrg } // namespace fundamentals_v1
    912   1.1.1.8  mrg } // namespace experimental
    913       1.1  mrg 
    914       1.1  mrg   // [X.Y.12]
    915  1.1.1.10  mrg   /// std::hash partial specialization for experimental::optional
    916  1.1.1.10  mrg   /// @relates experimental::optional
    917       1.1  mrg   template<typename _Tp>
    918       1.1  mrg     struct hash<experimental::optional<_Tp>>
    919       1.1  mrg     {
    920       1.1  mrg       using result_type = size_t;
    921       1.1  mrg       using argument_type = experimental::optional<_Tp>;
    922       1.1  mrg 
    923       1.1  mrg       size_t
    924       1.1  mrg       operator()(const experimental::optional<_Tp>& __t) const
    925       1.1  mrg       noexcept(noexcept(hash<_Tp> {}(*__t)))
    926       1.1  mrg       {
    927       1.1  mrg         // We pick an arbitrary hash for disengaged optionals which hopefully
    928       1.1  mrg         // usual values of _Tp won't typically hash to.
    929       1.1  mrg         constexpr size_t __magic_disengaged_hash = static_cast<size_t>(-3333);
    930       1.1  mrg         return __t ? hash<_Tp> {}(*__t) : __magic_disengaged_hash;
    931       1.1  mrg       }
    932       1.1  mrg     };
    933   1.1.1.8  mrg 
    934   1.1.1.8  mrg _GLIBCXX_END_NAMESPACE_VERSION
    935   1.1.1.8  mrg } // namespace std
    936       1.1  mrg 
    937       1.1  mrg #endif // C++14
    938       1.1  mrg 
    939       1.1  mrg #endif // _GLIBCXX_EXPERIMENTAL_OPTIONAL
    940