libstdc++
optional
Go to the documentation of this file.
00001 // <optional> -*- C++ -*-
00002 
00003 // Copyright (C) 2013-2017 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the
00007 // terms of the GNU General Public License as published by the
00008 // Free Software Foundation; either version 3, or (at your option)
00009 // any later version.
00010 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 
00016 // Under Section 7 of GPL version 3, you are granted additional
00017 // permissions described in the GCC Runtime Library Exception, version
00018 // 3.1, as published by the Free Software Foundation.
00019 
00020 // You should have received a copy of the GNU General Public License and
00021 // a copy of the GCC Runtime Library Exception along with this program;
00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00023 // <http://www.gnu.org/licenses/>.
00024 
00025 /** @file experimental/optional
00026  *  This is a TS C++ Library header.
00027  */
00028 
00029 #ifndef _GLIBCXX_EXPERIMENTAL_OPTIONAL
00030 #define _GLIBCXX_EXPERIMENTAL_OPTIONAL 1
00031 
00032 /**
00033  * @defgroup experimental Experimental
00034  *
00035  * Components specified by various Technical Specifications.
00036  *
00037  * As indicated by the std::experimental namespace and the  header paths,
00038  * the contents of these Technical Specifications are experimental and not
00039  * part of the C++ standard. As such the interfaces and implementations may
00040  * change in the future, and there is <STRONG> no guarantee of compatibility
00041  * between different GCC releases </STRONG> for these features.
00042  */
00043 
00044 #if __cplusplus <= 201103L
00045 # include <bits/c++14_warning.h>
00046 #else
00047 
00048 #include <utility>
00049 #include <type_traits>
00050 #include <stdexcept>
00051 #include <new>
00052 #include <initializer_list>
00053 #include <bits/functexcept.h>
00054 #include <bits/functional_hash.h>
00055 #include <bits/enable_special_members.h>
00056 #include <experimental/bits/lfts_config.h>
00057 
00058 namespace std _GLIBCXX_VISIBILITY(default)
00059 {
00060 namespace experimental
00061 {
00062 inline namespace fundamentals_v1
00063 {
00064 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00065 
00066   /**
00067    * @defgroup optional Optional values
00068    * @ingroup experimental
00069    *
00070    * Class template for optional values and surrounding facilities, as
00071    * described in n3793 "A proposal to add a utility class to represent
00072    * optional objects (Revision 5)".
00073    *
00074    * @{
00075    */
00076 
00077 #define __cpp_lib_experimental_optional 201411
00078 
00079   // All subsequent [X.Y.n] references are against n3793.
00080 
00081   // [X.Y.4]
00082   template<typename _Tp>
00083     class optional;
00084 
00085   // [X.Y.5]
00086   /// Tag type for in-place construction.
00087   struct in_place_t { };
00088 
00089   /// Tag for in-place construction.
00090   constexpr in_place_t in_place { };
00091 
00092   // [X.Y.6]
00093   /// Tag type to disengage optional objects.
00094   struct nullopt_t
00095   {
00096     // Do not user-declare default constructor at all for
00097     // optional_value = {} syntax to work.
00098     // nullopt_t() = delete;
00099 
00100     // Used for constructing nullopt.
00101     enum class _Construct { _Token };
00102 
00103     // Must be constexpr for nullopt_t to be literal.
00104     explicit constexpr nullopt_t(_Construct) { }
00105   };
00106 
00107   // [X.Y.6]
00108   /// Tag to disengage optional objects.
00109   constexpr nullopt_t nullopt { nullopt_t::_Construct::_Token };
00110 
00111   // [X.Y.7]
00112   /**
00113    *  @brief Exception class thrown when a disengaged optional object is
00114    *  dereferenced.
00115    *  @ingroup exceptions
00116    */
00117   class bad_optional_access : public logic_error
00118   {
00119   public:
00120     bad_optional_access() : logic_error("bad optional access") { }
00121 
00122     // XXX This constructor is non-standard. Should not be inline
00123     explicit bad_optional_access(const char* __arg) : logic_error(__arg) { }
00124 
00125     virtual ~bad_optional_access() noexcept = default;
00126   };
00127 
00128   void
00129   __throw_bad_optional_access(const char*)
00130   __attribute__((__noreturn__));
00131 
00132   // XXX Does not belong here.
00133   inline void
00134   __throw_bad_optional_access(const char* __s)
00135   { _GLIBCXX_THROW_OR_ABORT(bad_optional_access(__s)); }
00136 
00137 #ifndef __cpp_lib_addressof_constexpr
00138   template<typename _Tp, typename = void>
00139     struct _Has_addressof_mem : std::false_type { };
00140 
00141   template<typename _Tp>
00142     struct _Has_addressof_mem<_Tp,
00143          __void_t<decltype( std::declval<const _Tp&>().operator&() )>
00144       >
00145     : std::true_type { };
00146 
00147   template<typename _Tp, typename = void>
00148     struct _Has_addressof_free : std::false_type { };
00149 
00150   template<typename _Tp>
00151     struct _Has_addressof_free<_Tp,
00152          __void_t<decltype( operator&(std::declval<const _Tp&>()) )>
00153       >
00154     : std::true_type { };
00155 
00156   /**
00157     * @brief Trait that detects the presence of an overloaded unary operator&.
00158     *
00159     * Practically speaking this detects the presence of such an operator when
00160     * called on a const-qualified lvalue (e.g.
00161     * declval<const _Tp&>().operator&()).
00162     */
00163   template<typename _Tp>
00164     struct _Has_addressof
00165     : std::__or_<_Has_addressof_mem<_Tp>, _Has_addressof_free<_Tp>>::type
00166     { };
00167 
00168   /**
00169     * @brief An overload that attempts to take the address of an lvalue as a
00170     * constant expression. Falls back to __addressof in the presence of an
00171     * overloaded addressof operator (unary operator&), in which case the call
00172     * will not be a constant expression.
00173     */
00174   template<typename _Tp>
00175     constexpr
00176     enable_if_t<!_Has_addressof<_Tp>::value, _Tp*>
00177     __constexpr_addressof(_Tp& __t)
00178     { return &__t; }
00179 
00180   /**
00181     * @brief Fallback overload that defers to __addressof.
00182     */
00183   template<typename _Tp>
00184     inline
00185     enable_if_t<_Has_addressof<_Tp>::value, _Tp*>
00186     __constexpr_addressof(_Tp& __t)
00187     { return std::__addressof(__t); }
00188 #endif // __cpp_lib_addressof_constexpr
00189 
00190   /**
00191     * @brief Class template that holds the necessary state for @ref optional
00192     * and that has the responsibility for construction and the special members.
00193     *
00194     * Such a separate base class template is necessary in order to
00195     * conditionally enable the special members (e.g. copy/move constructors).
00196     * Note that this means that @ref _Optional_base implements the
00197     * functionality for copy and move assignment, but not for converting
00198     * assignment.
00199     *
00200     * @see optional, _Enable_special_members
00201     */
00202   template<typename _Tp, bool _ShouldProvideDestructor =
00203            !is_trivially_destructible<_Tp>::value>
00204     class _Optional_base
00205     {
00206     private:
00207       // Remove const to avoid prohibition of reusing object storage for
00208       // const-qualified types in [3.8/9]. This is strictly internal
00209       // and even optional itself is oblivious to it.
00210       using _Stored_type = remove_const_t<_Tp>;
00211 
00212     public:
00213       // [X.Y.4.1] Constructors.
00214 
00215       // Constructors for disengaged optionals.
00216       constexpr _Optional_base() noexcept
00217       : _M_empty{} { }
00218 
00219       constexpr _Optional_base(nullopt_t) noexcept
00220       : _Optional_base{} { }
00221 
00222       // Constructors for engaged optionals.
00223       template<typename... _Args>
00224         constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
00225         : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true) { }
00226 
00227       template<typename _Up, typename... _Args,
00228                enable_if_t<is_constructible<_Tp,
00229                                             initializer_list<_Up>&,
00230                                             _Args&&...>::value,
00231                            int>...>
00232         constexpr explicit _Optional_base(in_place_t,
00233                                           initializer_list<_Up> __il,
00234                                           _Args&&... __args)
00235         : _M_payload(__il, std::forward<_Args>(__args)...),
00236           _M_engaged(true) { }
00237 
00238       // Copy and move constructors.
00239       _Optional_base(const _Optional_base& __other)
00240       {
00241         if (__other._M_engaged)
00242           this->_M_construct(__other._M_get());
00243       }
00244 
00245       _Optional_base(_Optional_base&& __other)
00246       noexcept(is_nothrow_move_constructible<_Tp>())
00247       {
00248         if (__other._M_engaged)
00249           this->_M_construct(std::move(__other._M_get()));
00250       }
00251 
00252       // [X.Y.4.3] (partly) Assignment.
00253       _Optional_base&
00254       operator=(const _Optional_base& __other)
00255       {
00256         if (this->_M_engaged && __other._M_engaged)
00257           this->_M_get() = __other._M_get();
00258         else
00259           {
00260             if (__other._M_engaged)
00261               this->_M_construct(__other._M_get());
00262             else
00263               this->_M_reset();
00264           }
00265 
00266         return *this;
00267       }
00268 
00269       _Optional_base&
00270       operator=(_Optional_base&& __other)
00271       noexcept(__and_<is_nothrow_move_constructible<_Tp>,
00272                       is_nothrow_move_assignable<_Tp>>())
00273       {
00274         if (this->_M_engaged && __other._M_engaged)
00275           this->_M_get() = std::move(__other._M_get());
00276         else
00277           {
00278             if (__other._M_engaged)
00279               this->_M_construct(std::move(__other._M_get()));
00280             else
00281               this->_M_reset();
00282           }
00283         return *this;
00284       }
00285 
00286       // [X.Y.4.2] Destructor.
00287       ~_Optional_base()
00288       {
00289         if (this->_M_engaged)
00290           this->_M_payload.~_Stored_type();
00291       }
00292 
00293       // The following functionality is also needed by optional, hence the
00294       // protected accessibility.
00295     protected:
00296       constexpr bool _M_is_engaged() const noexcept
00297       { return this->_M_engaged; }
00298 
00299       // The _M_get operations have _M_engaged as a precondition.
00300       constexpr _Tp&
00301       _M_get() noexcept
00302       { return _M_payload; }
00303 
00304       constexpr const _Tp&
00305       _M_get() const noexcept
00306       { return _M_payload; }
00307 
00308       // The _M_construct operation has !_M_engaged as a precondition
00309       // while _M_destruct has _M_engaged as a precondition.
00310       template<typename... _Args>
00311         void
00312         _M_construct(_Args&&... __args)
00313         noexcept(is_nothrow_constructible<_Stored_type, _Args...>())
00314         {
00315           ::new (std::__addressof(this->_M_payload))
00316             _Stored_type(std::forward<_Args>(__args)...);
00317           this->_M_engaged = true;
00318         }
00319 
00320       void
00321       _M_destruct()
00322       {
00323         this->_M_engaged = false;
00324         this->_M_payload.~_Stored_type();
00325       }
00326 
00327       // _M_reset is a 'safe' operation with no precondition.
00328       void
00329       _M_reset()
00330       {
00331         if (this->_M_engaged)
00332           this->_M_destruct();
00333       }
00334 
00335     private:
00336       struct _Empty_byte { };
00337       union {
00338           _Empty_byte _M_empty;
00339           _Stored_type _M_payload;
00340       };
00341       bool _M_engaged = false;
00342     };
00343 
00344   /// Partial specialization that is exactly identical to the primary template
00345   /// save for not providing a destructor, to fulfill triviality requirements.
00346   template<typename _Tp>
00347     class _Optional_base<_Tp, false>
00348     {
00349     private:
00350       using _Stored_type = remove_const_t<_Tp>;
00351 
00352     public:
00353       constexpr _Optional_base() noexcept
00354       : _M_empty{} { }
00355 
00356       constexpr _Optional_base(nullopt_t) noexcept
00357       : _Optional_base{} { }
00358 
00359       template<typename... _Args>
00360         constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
00361         : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true) { }
00362 
00363       template<typename _Up, typename... _Args,
00364                enable_if_t<is_constructible<_Tp,
00365                                             initializer_list<_Up>&,
00366                                             _Args&&...>::value,
00367                            int>...>
00368         constexpr explicit _Optional_base(in_place_t,
00369                                           initializer_list<_Up> __il,
00370                                           _Args&&... __args)
00371         : _M_payload(__il, std::forward<_Args>(__args)...),
00372           _M_engaged(true) { }
00373 
00374       _Optional_base(const _Optional_base& __other)
00375       {
00376         if (__other._M_engaged)
00377           this->_M_construct(__other._M_get());
00378       }
00379 
00380       _Optional_base(_Optional_base&& __other)
00381       noexcept(is_nothrow_move_constructible<_Tp>())
00382       {
00383         if (__other._M_engaged)
00384           this->_M_construct(std::move(__other._M_get()));
00385       }
00386 
00387       _Optional_base&
00388       operator=(const _Optional_base& __other)
00389       {
00390         if (this->_M_engaged && __other._M_engaged)
00391           this->_M_get() = __other._M_get();
00392         else
00393           {
00394             if (__other._M_engaged)
00395               this->_M_construct(__other._M_get());
00396             else
00397               this->_M_reset();
00398           }
00399         return *this;
00400       }
00401 
00402       _Optional_base&
00403       operator=(_Optional_base&& __other)
00404       noexcept(__and_<is_nothrow_move_constructible<_Tp>,
00405                       is_nothrow_move_assignable<_Tp>>())
00406       {
00407         if (this->_M_engaged && __other._M_engaged)
00408           this->_M_get() = std::move(__other._M_get());
00409         else
00410           {
00411             if (__other._M_engaged)
00412               this->_M_construct(std::move(__other._M_get()));
00413             else
00414               this->_M_reset();
00415           }
00416         return *this;
00417       }
00418 
00419       // Sole difference
00420       // ~_Optional_base() noexcept = default;
00421 
00422     protected:
00423       constexpr bool _M_is_engaged() const noexcept
00424       { return this->_M_engaged; }
00425 
00426       _Tp&
00427       _M_get() noexcept
00428       { return _M_payload; }
00429 
00430       constexpr const _Tp&
00431       _M_get() const noexcept
00432       { return _M_payload; }
00433 
00434       template<typename... _Args>
00435         void
00436         _M_construct(_Args&&... __args)
00437         noexcept(is_nothrow_constructible<_Stored_type, _Args...>())
00438         {
00439           ::new (std::__addressof(this->_M_payload))
00440             _Stored_type(std::forward<_Args>(__args)...);
00441           this->_M_engaged = true;
00442         }
00443 
00444       void
00445       _M_destruct()
00446       {
00447         this->_M_engaged = false;
00448         this->_M_payload.~_Stored_type();
00449       }
00450 
00451       void
00452       _M_reset()
00453       {
00454         if (this->_M_engaged)
00455           this->_M_destruct();
00456       }
00457 
00458     private:
00459       struct _Empty_byte { };
00460       union
00461       {
00462         _Empty_byte _M_empty;
00463         _Stored_type _M_payload;
00464       };
00465       bool _M_engaged = false;
00466     };
00467 
00468   template<typename _Tp>
00469   class optional;
00470 
00471   template<typename _Tp, typename _Up>
00472     using __converts_from_optional =
00473       __or_<is_constructible<_Tp, const optional<_Up>&>,
00474             is_constructible<_Tp, optional<_Up>&>,
00475             is_constructible<_Tp, const optional<_Up>&&>,
00476             is_constructible<_Tp, optional<_Up>&&>,
00477             is_convertible<const optional<_Up>&, _Tp>,
00478             is_convertible<optional<_Up>&, _Tp>,
00479             is_convertible<const optional<_Up>&&, _Tp>,
00480             is_convertible<optional<_Up>&&, _Tp>>;
00481 
00482   template<typename _Tp, typename _Up>
00483     using __assigns_from_optional =
00484       __or_<is_assignable<_Tp&, const optional<_Up>&>,
00485             is_assignable<_Tp&, optional<_Up>&>,
00486             is_assignable<_Tp&, const optional<_Up>&&>,
00487             is_assignable<_Tp&, optional<_Up>&&>>;
00488 
00489   /**
00490     * @brief Class template for optional values.
00491     */
00492   template<typename _Tp>
00493     class optional
00494     : private _Optional_base<_Tp>,
00495       private _Enable_copy_move<
00496         // Copy constructor.
00497         is_copy_constructible<_Tp>::value,
00498         // Copy assignment.
00499         __and_<is_copy_constructible<_Tp>, is_copy_assignable<_Tp>>::value,
00500         // Move constructor.
00501         is_move_constructible<_Tp>::value,
00502         // Move assignment.
00503         __and_<is_move_constructible<_Tp>, is_move_assignable<_Tp>>::value,
00504         // Unique tag type.
00505         optional<_Tp>>
00506     {
00507       static_assert(__and_<__not_<is_same<remove_cv_t<_Tp>, nullopt_t>>,
00508                            __not_<is_same<remove_cv_t<_Tp>, in_place_t>>,
00509                            __not_<is_reference<_Tp>>>(),
00510                     "Invalid instantiation of optional<T>");
00511 
00512     private:
00513       using _Base = _Optional_base<_Tp>;
00514 
00515     public:
00516       using value_type = _Tp;
00517 
00518       // _Optional_base has the responsibility for construction.
00519       using _Base::_Base;
00520 
00521       constexpr optional() = default;
00522       // Converting constructors for engaged optionals.
00523       template <typename _Up = _Tp,
00524                 enable_if_t<__and_<
00525                               __not_<is_same<optional<_Tp>, decay_t<_Up>>>,
00526                               is_constructible<_Tp, _Up&&>,
00527                               is_convertible<_Up&&, _Tp>
00528                               >::value, bool> = true>
00529       constexpr optional(_Up&& __t)
00530         : _Base(in_place, std::forward<_Up>(__t)) { }
00531 
00532       template <typename _Up = _Tp,
00533                 enable_if_t<__and_<
00534                               __not_<is_same<optional<_Tp>, decay_t<_Up>>>,
00535                               is_constructible<_Tp, _Up&&>,
00536                               __not_<is_convertible<_Up&&, _Tp>>
00537                               >::value, bool> = false>
00538       explicit constexpr optional(_Up&& __t)
00539         : _Base(in_place, std::forward<_Up>(__t)) { }
00540 
00541       template <typename _Up,
00542                 enable_if_t<__and_<
00543                             __not_<is_same<_Tp, _Up>>,
00544                             is_constructible<_Tp, const _Up&>,
00545                             is_convertible<const _Up&, _Tp>,
00546                             __not_<__converts_from_optional<_Tp, _Up>>
00547                             >::value, bool> = true>
00548       constexpr optional(const optional<_Up>& __t)
00549       {
00550         if (__t)
00551           emplace(*__t);
00552       }
00553 
00554       template <typename _Up,
00555                  enable_if_t<__and_<
00556                                __not_<is_same<_Tp, _Up>>,
00557                                is_constructible<_Tp, const _Up&>,
00558                                __not_<is_convertible<const _Up&, _Tp>>,
00559                                __not_<__converts_from_optional<_Tp, _Up>>
00560                                >::value, bool> = false>
00561       explicit constexpr optional(const optional<_Up>& __t)
00562       {
00563         if (__t)
00564           emplace(*__t);
00565       }
00566 
00567       template <typename _Up,
00568                 enable_if_t<__and_<
00569                               __not_<is_same<_Tp, _Up>>,
00570                               is_constructible<_Tp, _Up&&>,
00571                               is_convertible<_Up&&, _Tp>,
00572                               __not_<__converts_from_optional<_Tp, _Up>>
00573                               >::value, bool> = true>
00574       constexpr optional(optional<_Up>&& __t)
00575       {
00576         if (__t)
00577           emplace(std::move(*__t));
00578       }
00579 
00580       template <typename _Up,
00581                 enable_if_t<__and_<
00582                             __not_<is_same<_Tp, _Up>>,
00583                             is_constructible<_Tp, _Up&&>,
00584                             __not_<is_convertible<_Up&&, _Tp>>,
00585                             __not_<__converts_from_optional<_Tp, _Up>>
00586                             >::value, bool> = false>
00587       explicit constexpr optional(optional<_Up>&& __t)
00588       {
00589         if (__t)
00590           emplace(std::move(*__t));
00591       }
00592 
00593       // [X.Y.4.3] (partly) Assignment.
00594       optional&
00595       operator=(nullopt_t) noexcept
00596       {
00597         this->_M_reset();
00598         return *this;
00599       }
00600 
00601       template<typename _Up = _Tp>
00602         enable_if_t<__and_<
00603                       __not_<is_same<optional<_Tp>, decay_t<_Up>>>,
00604                       is_constructible<_Tp, _Up>,
00605                       __not_<__and_<is_scalar<_Tp>,
00606                                     is_same<_Tp, decay_t<_Up>>>>,
00607                       is_assignable<_Tp&, _Up>>::value,
00608                     optional&>
00609         operator=(_Up&& __u)
00610         {
00611           if (this->_M_is_engaged())
00612             this->_M_get() = std::forward<_Up>(__u);
00613           else
00614             this->_M_construct(std::forward<_Up>(__u));
00615 
00616           return *this;
00617         }
00618 
00619       template<typename _Up>
00620         enable_if_t<__and_<
00621                       __not_<is_same<_Tp, _Up>>,
00622                       is_constructible<_Tp, const _Up&>,
00623                       is_assignable<_Tp&, _Up>,
00624                       __not_<__converts_from_optional<_Tp, _Up>>,
00625                       __not_<__assigns_from_optional<_Tp, _Up>>
00626                       >::value,
00627                     optional&>
00628         operator=(const optional<_Up>& __u)
00629         {
00630           if (__u)
00631             {
00632               if (this->_M_is_engaged())
00633                 this->_M_get() = *__u;
00634               else
00635                 this->_M_construct(*__u);
00636             }
00637           else
00638             {
00639               this->_M_reset();
00640             }
00641           return *this;
00642         }
00643 
00644       template<typename _Up>
00645         enable_if_t<__and_<
00646                       __not_<is_same<_Tp, _Up>>,
00647                       is_constructible<_Tp, _Up>,
00648                       is_assignable<_Tp&, _Up>,
00649                       __not_<__converts_from_optional<_Tp, _Up>>,
00650                       __not_<__assigns_from_optional<_Tp, _Up>>
00651                       >::value,
00652                     optional&>
00653         operator=(optional<_Up>&& __u)
00654         {
00655           if (__u)
00656             {
00657               if (this->_M_is_engaged())
00658                 this->_M_get() = std::move(*__u);
00659               else
00660                 this->_M_construct(std::move(*__u));
00661             }
00662           else
00663             {
00664               this->_M_reset();
00665             }
00666 
00667           return *this;
00668         }
00669 
00670       template<typename... _Args>
00671         enable_if_t<is_constructible<_Tp, _Args&&...>::value>
00672         emplace(_Args&&... __args)
00673         {
00674           this->_M_reset();
00675           this->_M_construct(std::forward<_Args>(__args)...);
00676         }
00677 
00678       template<typename _Up, typename... _Args>
00679         enable_if_t<is_constructible<_Tp, initializer_list<_Up>&,
00680                                      _Args&&...>::value>
00681         emplace(initializer_list<_Up> __il, _Args&&... __args)
00682         {
00683           this->_M_reset();
00684           this->_M_construct(__il, std::forward<_Args>(__args)...);
00685         }
00686 
00687       // [X.Y.4.2] Destructor is implicit, implemented in _Optional_base.
00688 
00689       // [X.Y.4.4] Swap.
00690       void
00691       swap(optional& __other)
00692       noexcept(is_nothrow_move_constructible<_Tp>()
00693                && noexcept(swap(declval<_Tp&>(), declval<_Tp&>())))
00694       {
00695         using std::swap;
00696 
00697         if (this->_M_is_engaged() && __other._M_is_engaged())
00698           swap(this->_M_get(), __other._M_get());
00699         else if (this->_M_is_engaged())
00700           {
00701             __other._M_construct(std::move(this->_M_get()));
00702             this->_M_destruct();
00703           }
00704         else if (__other._M_is_engaged())
00705           {
00706             this->_M_construct(std::move(__other._M_get()));
00707             __other._M_destruct();
00708           }
00709       }
00710 
00711       // [X.Y.4.5] Observers.
00712       constexpr const _Tp*
00713       operator->() const
00714       {
00715 #ifndef __cpp_lib_addressof_constexpr
00716         return __constexpr_addressof(this->_M_get());
00717 #else
00718         return std::__addressof(this->_M_get());
00719 #endif
00720       }
00721 
00722       _Tp*
00723       operator->()
00724       { return std::__addressof(this->_M_get()); }
00725 
00726       constexpr const _Tp&
00727       operator*() const&
00728       { return this->_M_get(); }
00729 
00730       constexpr _Tp&
00731       operator*()&
00732       { return this->_M_get(); }
00733 
00734       constexpr _Tp&&
00735       operator*()&&
00736       { return std::move(this->_M_get()); }
00737 
00738       constexpr const _Tp&&
00739       operator*() const&&
00740       { return std::move(this->_M_get()); }
00741 
00742       constexpr explicit operator bool() const noexcept
00743       { return this->_M_is_engaged(); }
00744 
00745       constexpr const _Tp&
00746       value() const&
00747       {
00748         return this->_M_is_engaged()
00749           ?  this->_M_get()
00750           : (__throw_bad_optional_access("Attempt to access value of a "
00751                                          "disengaged optional object"),
00752              this->_M_get());
00753       }
00754 
00755       constexpr _Tp&
00756       value()&
00757       {
00758         return this->_M_is_engaged()
00759           ?  this->_M_get()
00760           : (__throw_bad_optional_access("Attempt to access value of a "
00761                                          "disengaged optional object"),
00762              this->_M_get());
00763       }
00764 
00765       constexpr _Tp&&
00766       value()&&
00767       {
00768         return this->_M_is_engaged()
00769           ?  std::move(this->_M_get())
00770           : (__throw_bad_optional_access("Attempt to access value of a "
00771                                          "disengaged optional object"),
00772              std::move(this->_M_get()));
00773       }
00774 
00775       constexpr const _Tp&&
00776       value() const&&
00777       {
00778         return this->_M_is_engaged()
00779           ?  std::move(this->_M_get())
00780           : (__throw_bad_optional_access("Attempt to access value of a "
00781                                          "disengaged optional object"),
00782              std::move(this->_M_get()));
00783       }
00784 
00785       template<typename _Up>
00786         constexpr _Tp
00787         value_or(_Up&& __u) const&
00788         {
00789           static_assert(__and_<is_copy_constructible<_Tp>,
00790                                is_convertible<_Up&&, _Tp>>(),
00791                         "Cannot return value");
00792 
00793           return this->_M_is_engaged()
00794             ? this->_M_get()
00795             : static_cast<_Tp>(std::forward<_Up>(__u));
00796         }
00797 
00798       template<typename _Up>
00799         _Tp
00800         value_or(_Up&& __u) &&
00801         {
00802           static_assert(__and_<is_move_constructible<_Tp>,
00803                                is_convertible<_Up&&, _Tp>>(),
00804                         "Cannot return value" );
00805 
00806           return this->_M_is_engaged()
00807             ? std::move(this->_M_get())
00808             : static_cast<_Tp>(std::forward<_Up>(__u));
00809         }
00810     };
00811 
00812   // [X.Y.8] Comparisons between optional values.
00813   template<typename _Tp>
00814     constexpr bool
00815     operator==(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs)
00816     {
00817       return static_cast<bool>(__lhs) == static_cast<bool>(__rhs)
00818              && (!__lhs || *__lhs == *__rhs);
00819     }
00820 
00821   template<typename _Tp>
00822     constexpr bool
00823     operator!=(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs)
00824     { return !(__lhs == __rhs); }
00825 
00826   template<typename _Tp>
00827     constexpr bool
00828     operator<(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs)
00829     {
00830       return static_cast<bool>(__rhs) && (!__lhs || *__lhs < *__rhs);
00831     }
00832 
00833   template<typename _Tp>
00834     constexpr bool
00835     operator>(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs)
00836     { return __rhs < __lhs; }
00837 
00838   template<typename _Tp>
00839     constexpr bool
00840     operator<=(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs)
00841     { return !(__rhs < __lhs); }
00842 
00843   template<typename _Tp>
00844     constexpr bool
00845     operator>=(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs)
00846     { return !(__lhs < __rhs); }
00847 
00848   // [X.Y.9] Comparisons with nullopt.
00849   template<typename _Tp>
00850     constexpr bool
00851     operator==(const optional<_Tp>& __lhs, nullopt_t) noexcept
00852     { return !__lhs; }
00853 
00854   template<typename _Tp>
00855     constexpr bool
00856     operator==(nullopt_t, const optional<_Tp>& __rhs) noexcept
00857     { return !__rhs; }
00858 
00859   template<typename _Tp>
00860     constexpr bool
00861     operator!=(const optional<_Tp>& __lhs, nullopt_t) noexcept
00862     { return static_cast<bool>(__lhs); }
00863 
00864   template<typename _Tp>
00865     constexpr bool
00866     operator!=(nullopt_t, const optional<_Tp>& __rhs) noexcept
00867     { return static_cast<bool>(__rhs); }
00868 
00869   template<typename _Tp>
00870     constexpr bool
00871     operator<(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept
00872     { return false; }
00873 
00874   template<typename _Tp>
00875     constexpr bool
00876     operator<(nullopt_t, const optional<_Tp>& __rhs) noexcept
00877     { return static_cast<bool>(__rhs); }
00878 
00879   template<typename _Tp>
00880     constexpr bool
00881     operator>(const optional<_Tp>& __lhs, nullopt_t) noexcept
00882     { return static_cast<bool>(__lhs); }
00883 
00884   template<typename _Tp>
00885     constexpr bool
00886     operator>(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept
00887     { return false; }
00888 
00889   template<typename _Tp>
00890     constexpr bool
00891     operator<=(const optional<_Tp>& __lhs, nullopt_t) noexcept
00892     { return !__lhs; }
00893 
00894   template<typename _Tp>
00895     constexpr bool
00896     operator<=(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept
00897     { return true; }
00898 
00899   template<typename _Tp>
00900     constexpr bool
00901     operator>=(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept
00902     { return true; }
00903 
00904   template<typename _Tp>
00905     constexpr bool
00906     operator>=(nullopt_t, const optional<_Tp>& __rhs) noexcept
00907     { return !__rhs; }
00908 
00909   // [X.Y.10] Comparisons with value type.
00910   template<typename _Tp>
00911     constexpr bool
00912     operator==(const optional<_Tp>& __lhs, const _Tp& __rhs)
00913     { return __lhs && *__lhs == __rhs; }
00914 
00915   template<typename _Tp>
00916     constexpr bool
00917     operator==(const _Tp& __lhs, const optional<_Tp>& __rhs)
00918     { return __rhs && __lhs == *__rhs; }
00919 
00920   template<typename _Tp>
00921     constexpr bool
00922     operator!=(const optional<_Tp>& __lhs, _Tp const& __rhs)
00923     { return !__lhs || !(*__lhs == __rhs); }
00924 
00925   template<typename _Tp>
00926     constexpr bool
00927     operator!=(const _Tp& __lhs, const optional<_Tp>& __rhs)
00928     { return !__rhs || !(__lhs == *__rhs); }
00929 
00930   template<typename _Tp>
00931     constexpr bool
00932     operator<(const optional<_Tp>& __lhs, const _Tp& __rhs)
00933     { return !__lhs || *__lhs < __rhs; }
00934 
00935   template<typename _Tp>
00936     constexpr bool
00937     operator<(const _Tp& __lhs, const optional<_Tp>& __rhs)
00938     { return __rhs && __lhs < *__rhs; }
00939 
00940   template<typename _Tp>
00941     constexpr bool
00942     operator>(const optional<_Tp>& __lhs, const _Tp& __rhs)
00943     { return __lhs && __rhs < *__lhs; }
00944 
00945   template<typename _Tp>
00946     constexpr bool
00947     operator>(const _Tp& __lhs, const optional<_Tp>& __rhs)
00948     { return !__rhs || *__rhs < __lhs; }
00949 
00950   template<typename _Tp>
00951     constexpr bool
00952     operator<=(const optional<_Tp>& __lhs, const _Tp& __rhs)
00953     { return !__lhs || !(__rhs < *__lhs); }
00954 
00955   template<typename _Tp>
00956     constexpr bool
00957     operator<=(const _Tp& __lhs, const optional<_Tp>& __rhs)
00958     { return __rhs && !(*__rhs < __lhs); }
00959 
00960   template<typename _Tp>
00961     constexpr bool
00962     operator>=(const optional<_Tp>& __lhs, const _Tp& __rhs)
00963     { return __lhs && !(*__lhs < __rhs); }
00964 
00965   template<typename _Tp>
00966     constexpr bool
00967     operator>=(const _Tp& __lhs, const optional<_Tp>& __rhs)
00968     { return !__rhs || !(__lhs < *__rhs); }
00969 
00970   // [X.Y.11]
00971   template<typename _Tp>
00972     inline void
00973     swap(optional<_Tp>& __lhs, optional<_Tp>& __rhs)
00974     noexcept(noexcept(__lhs.swap(__rhs)))
00975     { __lhs.swap(__rhs); }
00976 
00977   template<typename _Tp>
00978     constexpr optional<decay_t<_Tp>>
00979     make_optional(_Tp&& __t)
00980     { return optional<decay_t<_Tp>> { std::forward<_Tp>(__t) }; }
00981 
00982   // @} group optional
00983 _GLIBCXX_END_NAMESPACE_VERSION
00984 } // namespace fundamentals_v1
00985 }
00986 
00987   // [X.Y.12]
00988   template<typename _Tp>
00989     struct hash<experimental::optional<_Tp>>
00990     {
00991       using result_type = size_t;
00992       using argument_type = experimental::optional<_Tp>;
00993 
00994       size_t
00995       operator()(const experimental::optional<_Tp>& __t) const
00996       noexcept(noexcept(hash<_Tp> {}(*__t)))
00997       {
00998         // We pick an arbitrary hash for disengaged optionals which hopefully
00999         // usual values of _Tp won't typically hash to.
01000         constexpr size_t __magic_disengaged_hash = static_cast<size_t>(-3333);
01001         return __t ? hash<_Tp> {}(*__t) : __magic_disengaged_hash;
01002       }
01003     };
01004 }
01005 
01006 #endif // C++14
01007 
01008 #endif // _GLIBCXX_EXPERIMENTAL_OPTIONAL