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