libstdc++
optional
Go to the documentation of this file.
00001 // <optional> -*- C++ -*-
00002 
00003 // Copyright (C) 2013-2016 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 
00057 namespace std _GLIBCXX_VISIBILITY(default)
00058 {
00059 namespace experimental
00060 {
00061 inline namespace fundamentals_v1
00062 {
00063 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00064 
00065   /**
00066    * @defgroup optional Optional values
00067    * @ingroup experimental
00068    *
00069    * Class template for optional values and surrounding facilities, as
00070    * described in n3793 "A proposal to add a utility class to represent
00071    * optional objects (Revision 5)".
00072    *
00073    * @{
00074    */
00075 
00076 #define __cpp_lib_experimental_optional 201411
00077 
00078   // All subsequent [X.Y.n] references are against n3793.
00079 
00080   // [X.Y.4]
00081   template<typename _Tp>
00082     class optional;
00083 
00084   // [X.Y.5]
00085   /// Tag type for in-place construction.
00086   struct in_place_t { };
00087 
00088   /// Tag for in-place construction.
00089   constexpr in_place_t in_place { };
00090 
00091   // [X.Y.6]
00092   /// Tag type to disengage optional objects.
00093   struct nullopt_t
00094   {
00095     // Do not user-declare default constructor at all for
00096     // optional_value = {} syntax to work.
00097     // nullopt_t() = delete;
00098 
00099     // Used for constructing nullopt.
00100     enum class _Construct { _Token };
00101 
00102     // Must be constexpr for nullopt_t to be literal.
00103     explicit constexpr nullopt_t(_Construct) { }
00104   };
00105 
00106   // [X.Y.6]
00107   /// Tag to disengage optional objects.
00108   constexpr nullopt_t nullopt { nullopt_t::_Construct::_Token };
00109 
00110   // [X.Y.7]
00111   /**
00112    *  @brief Exception class thrown when a disengaged optional object is
00113    *  dereferenced.
00114    *  @ingroup exceptions
00115    */
00116   class bad_optional_access : public logic_error
00117   {
00118   public:
00119     bad_optional_access() : logic_error("bad optional access") { }
00120 
00121     // XXX This constructor is non-standard. Should not be inline
00122     explicit bad_optional_access(const char* __arg) : logic_error(__arg) { }
00123 
00124     virtual ~bad_optional_access() noexcept = default;
00125   };
00126 
00127   void
00128   __throw_bad_optional_access(const char*)
00129   __attribute__((__noreturn__));
00130 
00131   // XXX Does not belong here.
00132   inline void
00133   __throw_bad_optional_access(const char* __s)
00134   { _GLIBCXX_THROW_OR_ABORT(bad_optional_access(__s)); }
00135 
00136   template<typename _Tp, typename = void>
00137     struct _Has_addressof_mem : std::false_type { };
00138 
00139   template<typename _Tp>
00140     struct _Has_addressof_mem<_Tp,
00141          __void_t<decltype( std::declval<const _Tp&>().operator&() )>
00142       >
00143     : std::true_type { };
00144 
00145   template<typename _Tp, typename = void>
00146     struct _Has_addressof_free : std::false_type { };
00147 
00148   template<typename _Tp>
00149     struct _Has_addressof_free<_Tp,
00150          __void_t<decltype( operator&(std::declval<const _Tp&>()) )>
00151       >
00152     : std::true_type { };
00153 
00154   /**
00155     * @brief Trait that detects the presence of an overloaded unary operator&.
00156     *
00157     * Practically speaking this detects the presence of such an operator when
00158     * called on a const-qualified lvalue (i.e.
00159     * declval<_Tp * const&>().operator&()).
00160     */
00161   template<typename _Tp>
00162     struct _Has_addressof
00163     : std::__or_<_Has_addressof_mem<_Tp>, _Has_addressof_free<_Tp>>::type
00164     { };
00165 
00166   /**
00167     * @brief An overload that attempts to take the address of an lvalue as a
00168     * constant expression. Falls back to __addressof in the presence of an
00169     * overloaded addressof operator (unary operator&), in which case the call
00170     * will not be a constant expression.
00171     */
00172   template<typename _Tp, enable_if_t<!_Has_addressof<_Tp>::value, int>...>
00173     constexpr _Tp* __constexpr_addressof(_Tp& __t)
00174     { return &__t; }
00175 
00176   /**
00177     * @brief Fallback overload that defers to __addressof.
00178     */
00179   template<typename _Tp, enable_if_t<_Has_addressof<_Tp>::value, int>...>
00180     inline _Tp* __constexpr_addressof(_Tp& __t)
00181     { return std::__addressof(__t); }
00182 
00183   /**
00184     * @brief Class template that holds the necessary state for @ref optional
00185     * and that has the responsibility for construction and the special members.
00186     *
00187     * Such a separate base class template is necessary in order to
00188     * conditionally enable the special members (e.g. copy/move constructors).
00189     * Note that this means that @ref _Optional_base implements the
00190     * functionality for copy and move assignment, but not for converting
00191     * assignment.
00192     *
00193     * @see optional, _Enable_special_members
00194     */
00195   template<typename _Tp, bool _ShouldProvideDestructor =
00196            !is_trivially_destructible<_Tp>::value>
00197     class _Optional_base
00198     {
00199     private:
00200       // Remove const to avoid prohibition of reusing object storage for
00201       // const-qualified types in [3.8/9]. This is strictly internal
00202       // and even optional itself is oblivious to it.
00203       using _Stored_type = remove_const_t<_Tp>;
00204 
00205     public:
00206       // [X.Y.4.1] Constructors.
00207 
00208       // Constructors for disengaged optionals.
00209       constexpr _Optional_base() noexcept
00210       : _M_empty{} { }
00211 
00212       constexpr _Optional_base(nullopt_t) noexcept
00213       : _Optional_base{} { }
00214 
00215       // Constructors for engaged optionals.
00216       constexpr _Optional_base(const _Tp& __t)
00217       : _M_payload(__t), _M_engaged(true) { }
00218 
00219       constexpr _Optional_base(_Tp&& __t)
00220       : _M_payload(std::move(__t)), _M_engaged(true) { }
00221 
00222       template<typename... _Args>
00223         constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
00224         : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true) { }
00225 
00226       template<typename _Up, typename... _Args,
00227                enable_if_t<is_constructible<_Tp,
00228                                             initializer_list<_Up>&,
00229                                             _Args&&...>::value,
00230                            int>...>
00231         constexpr explicit _Optional_base(in_place_t,
00232                                           initializer_list<_Up> __il,
00233                                           _Args&&... __args)
00234         : _M_payload(__il, std::forward<_Args>(__args)...),
00235           _M_engaged(true) { }
00236 
00237       // Copy and move constructors.
00238       _Optional_base(const _Optional_base& __other)
00239       {
00240         if (__other._M_engaged)
00241           this->_M_construct(__other._M_get());
00242       }
00243 
00244       _Optional_base(_Optional_base&& __other)
00245       noexcept(is_nothrow_move_constructible<_Tp>())
00246       {
00247         if (__other._M_engaged)
00248           this->_M_construct(std::move(__other._M_get()));
00249       }
00250 
00251       // [X.Y.4.3] (partly) Assignment.
00252       _Optional_base&
00253       operator=(const _Optional_base& __other)
00254       {
00255         if (this->_M_engaged && __other._M_engaged)
00256           this->_M_get() = __other._M_get();
00257         else
00258           {
00259             if (__other._M_engaged)
00260               this->_M_construct(__other._M_get());
00261             else
00262               this->_M_reset();
00263           }
00264 
00265         return *this;
00266       }
00267 
00268       _Optional_base&
00269       operator=(_Optional_base&& __other)
00270       noexcept(__and_<is_nothrow_move_constructible<_Tp>,
00271                       is_nothrow_move_assignable<_Tp>>())
00272       {
00273         if (this->_M_engaged && __other._M_engaged)
00274           this->_M_get() = std::move(__other._M_get());
00275         else
00276           {
00277             if (__other._M_engaged)
00278               this->_M_construct(std::move(__other._M_get()));
00279             else
00280               this->_M_reset();
00281           }
00282         return *this;
00283       }
00284 
00285       // [X.Y.4.2] Destructor.
00286       ~_Optional_base()
00287       {
00288         if (this->_M_engaged)
00289           this->_M_payload.~_Stored_type();
00290       }
00291 
00292       // The following functionality is also needed by optional, hence the
00293       // protected accessibility.
00294     protected:
00295       constexpr bool _M_is_engaged() const noexcept
00296       { return this->_M_engaged; }
00297 
00298       // The _M_get operations have _M_engaged as a precondition.
00299       constexpr _Tp&
00300       _M_get() noexcept
00301       { return _M_payload; }
00302 
00303       constexpr const _Tp&
00304       _M_get() const noexcept
00305       { return _M_payload; }
00306 
00307       // The _M_construct operation has !_M_engaged as a precondition
00308       // while _M_destruct has _M_engaged as a precondition.
00309       template<typename... _Args>
00310         void
00311         _M_construct(_Args&&... __args)
00312         noexcept(is_nothrow_constructible<_Stored_type, _Args...>())
00313         {
00314           ::new (std::__addressof(this->_M_payload))
00315             _Stored_type(std::forward<_Args>(__args)...);
00316           this->_M_engaged = true;
00317         }
00318 
00319       void
00320       _M_destruct()
00321       {
00322         this->_M_engaged = false;
00323         this->_M_payload.~_Stored_type();
00324       }
00325 
00326       // _M_reset is a 'safe' operation with no precondition.
00327       void
00328       _M_reset()
00329       {
00330         if (this->_M_engaged)
00331           this->_M_destruct();
00332       }
00333 
00334     private:
00335       struct _Empty_byte { };
00336       union {
00337           _Empty_byte _M_empty;
00338           _Stored_type _M_payload;
00339       };
00340       bool _M_engaged = false;
00341     };
00342 
00343   /// Partial specialization that is exactly identical to the primary template
00344   /// save for not providing a destructor, to fulfill triviality requirements.
00345   template<typename _Tp>
00346     class _Optional_base<_Tp, false>
00347     {
00348     private:
00349       using _Stored_type = remove_const_t<_Tp>;
00350 
00351     public:
00352       constexpr _Optional_base() noexcept
00353       : _M_empty{} { }
00354 
00355       constexpr _Optional_base(nullopt_t) noexcept
00356       : _Optional_base{} { }
00357 
00358       constexpr _Optional_base(const _Tp& __t)
00359       : _M_payload(__t), _M_engaged(true) { }
00360 
00361       constexpr _Optional_base(_Tp&& __t)
00362       : _M_payload(std::move(__t)), _M_engaged(true) { }
00363 
00364       template<typename... _Args>
00365         constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
00366         : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true) { }
00367 
00368       template<typename _Up, typename... _Args,
00369                enable_if_t<is_constructible<_Tp,
00370                                             initializer_list<_Up>&,
00371                                             _Args&&...>::value,
00372                            int>...>
00373         constexpr explicit _Optional_base(in_place_t,
00374                                           initializer_list<_Up> __il,
00375                                           _Args&&... __args)
00376         : _M_payload(__il, std::forward<_Args>(__args)...),
00377           _M_engaged(true) { }
00378 
00379       _Optional_base(const _Optional_base& __other)
00380       {
00381         if (__other._M_engaged)
00382           this->_M_construct(__other._M_get());
00383       }
00384 
00385       _Optional_base(_Optional_base&& __other)
00386       noexcept(is_nothrow_move_constructible<_Tp>())
00387       {
00388         if (__other._M_engaged)
00389           this->_M_construct(std::move(__other._M_get()));
00390       }
00391 
00392       _Optional_base&
00393       operator=(const _Optional_base& __other)
00394       {
00395         if (this->_M_engaged && __other._M_engaged)
00396           this->_M_get() = __other._M_get();
00397         else
00398           {
00399             if (__other._M_engaged)
00400               this->_M_construct(__other._M_get());
00401             else
00402               this->_M_reset();
00403           }
00404         return *this;
00405       }
00406 
00407       _Optional_base&
00408       operator=(_Optional_base&& __other)
00409       noexcept(__and_<is_nothrow_move_constructible<_Tp>,
00410                       is_nothrow_move_assignable<_Tp>>())
00411       {
00412         if (this->_M_engaged && __other._M_engaged)
00413           this->_M_get() = std::move(__other._M_get());
00414         else
00415           {
00416             if (__other._M_engaged)
00417               this->_M_construct(std::move(__other._M_get()));
00418             else
00419               this->_M_reset();
00420           }
00421         return *this;
00422       }
00423 
00424       // Sole difference
00425       // ~_Optional_base() noexcept = default;
00426 
00427     protected:
00428       constexpr bool _M_is_engaged() const noexcept
00429       { return this->_M_engaged; }
00430 
00431       _Tp&
00432       _M_get() noexcept
00433       { return _M_payload; }
00434 
00435       constexpr const _Tp&
00436       _M_get() const noexcept
00437       { return _M_payload; }
00438 
00439       template<typename... _Args>
00440         void
00441         _M_construct(_Args&&... __args)
00442         noexcept(is_nothrow_constructible<_Stored_type, _Args...>())
00443         {
00444           ::new (std::__addressof(this->_M_payload))
00445             _Stored_type(std::forward<_Args>(__args)...);
00446           this->_M_engaged = true;
00447         }
00448 
00449       void
00450       _M_destruct()
00451       {
00452         this->_M_engaged = false;
00453         this->_M_payload.~_Stored_type();
00454       }
00455 
00456       void
00457       _M_reset()
00458       {
00459         if (this->_M_engaged)
00460           this->_M_destruct();
00461       }
00462 
00463     private:
00464       struct _Empty_byte { };
00465       union
00466       {
00467         _Empty_byte _M_empty;
00468         _Stored_type _M_payload;
00469       };
00470       bool _M_engaged = false;
00471     };
00472 
00473   template<typename _Tp>
00474   class optional;
00475 
00476   template<typename>
00477     struct __is_optional_impl : false_type
00478     { };
00479 
00480   template<typename _Tp>
00481   struct __is_optional_impl<optional<_Tp>> : true_type
00482     { };
00483 
00484   template<typename _Tp>
00485     struct __is_optional
00486     : public __is_optional_impl<std::remove_cv_t<std::remove_reference_t<_Tp>>>
00487     { };
00488 
00489 
00490   /**
00491     * @brief Class template for optional values.
00492     */
00493   template<typename _Tp>
00494     class optional
00495     : private _Optional_base<_Tp>,
00496       private _Enable_copy_move<
00497         // Copy constructor.
00498         is_copy_constructible<_Tp>::value,
00499         // Copy assignment.
00500         __and_<is_copy_constructible<_Tp>, is_copy_assignable<_Tp>>::value,
00501         // Move constructor.
00502         is_move_constructible<_Tp>::value,
00503         // Move assignment.
00504         __and_<is_move_constructible<_Tp>, is_move_assignable<_Tp>>::value,
00505         // Unique tag type.
00506         optional<_Tp>>
00507     {
00508       static_assert(__and_<__not_<is_same<remove_cv_t<_Tp>, nullopt_t>>,
00509                            __not_<is_same<remove_cv_t<_Tp>, in_place_t>>,
00510                            __not_<is_reference<_Tp>>>(),
00511                     "Invalid instantiation of optional<T>");
00512 
00513     private:
00514       using _Base = _Optional_base<_Tp>;
00515 
00516     public:
00517       using value_type = _Tp;
00518 
00519       // _Optional_base has the responsibility for construction.
00520       using _Base::_Base;
00521 
00522       constexpr optional() = default;
00523       // Converting constructors for engaged optionals.
00524       template <typename _Up,
00525                 enable_if_t<__and_<
00526                               __not_<is_same<_Tp, _Up>>,
00527                               is_constructible<_Tp, _Up&&>,
00528                               is_convertible<_Up&&, _Tp>
00529                               >::value, bool> = true>
00530       constexpr optional(_Up&& __t)
00531         : _Base(_Tp(std::forward<_Up>(__t))) { }
00532 
00533       template <typename _Up,
00534                 enable_if_t<__and_<
00535                             __not_<is_same<_Tp, _Up>>,
00536                             is_constructible<_Tp, _Up&&>,
00537                             __not_<is_convertible<_Up&&, _Tp>>
00538                             >::value, bool> = false>
00539       explicit constexpr optional(_Up&& __t)
00540         : _Base(_Tp(std::forward<_Up>(__t))) { }
00541 
00542       template <typename _Up,
00543                 enable_if_t<__and_<
00544                             __not_<is_same<_Tp, _Up>>,
00545                             __not_<is_constructible<
00546                               _Tp, const optional<_Up>&>>,
00547                             __not_<is_convertible<
00548                               const optional<_Up>&, _Tp>>,
00549                             is_constructible<_Tp, const _Up&>,
00550                             is_convertible<const _Up&, _Tp>
00551                             >::value, bool> = true>
00552       constexpr optional(const optional<_Up>& __t)
00553         : _Base(__t ? optional<_Tp>(*__t) : optional<_Tp>()) { }
00554 
00555       template <typename _Up,
00556                  enable_if_t<__and_<
00557                                __not_<is_same<_Tp, _Up>>,
00558                                __not_<is_constructible<
00559                                         _Tp, const optional<_Up>&>>,
00560                                __not_<is_convertible<
00561                                  const optional<_Up>&, _Tp>>,
00562                                is_constructible<_Tp, const _Up&>,
00563                                __not_<is_convertible<const _Up&, _Tp>>
00564                                >::value, bool> = false>
00565       explicit constexpr optional(const optional<_Up>& __t)
00566         : _Base(__t ? optional<_Tp>(*__t) : optional<_Tp>()) { }
00567 
00568       template <typename _Up,
00569                 enable_if_t<__and_<
00570                               __not_<is_same<_Tp, _Up>>,
00571                               __not_<is_constructible<
00572                                        _Tp, optional<_Up>&&>>,
00573                               __not_<is_convertible<
00574                                        optional<_Up>&&, _Tp>>,
00575                               is_constructible<_Tp, _Up&&>,
00576                               is_convertible<_Up&&, _Tp>
00577                               >::value, bool> = true>
00578       constexpr optional(optional<_Up>&& __t)
00579         : _Base(__t ? optional<_Tp>(std::move(*__t)) : optional<_Tp>()) { }
00580 
00581       template <typename _Up,
00582                 enable_if_t<__and_<
00583                             __not_<is_same<_Tp, _Up>>,
00584                             __not_<is_constructible<
00585                                      _Tp, optional<_Up>&&>>,
00586                             __not_<is_convertible<
00587                                      optional<_Up>&&, _Tp>>,
00588                             is_constructible<_Tp, _Up&&>,
00589                             __not_<is_convertible<_Up&&, _Tp>>
00590                             >::value, bool> = false>
00591       explicit constexpr optional(optional<_Up>&& __t)
00592         : _Base(__t ? optional<_Tp>(std::move(*__t)) : optional<_Tp>()) { }
00593 
00594       // [X.Y.4.3] (partly) Assignment.
00595       optional&
00596       operator=(nullopt_t) noexcept
00597       {
00598         this->_M_reset();
00599         return *this;
00600       }
00601 
00602       template<typename _Up,
00603                enable_if_t<__and_<
00604                            __not_<is_same<_Up, nullopt_t>>,
00605                            __not_<__is_optional<_Up>>>::value,
00606                          bool> = true>
00607         optional&
00608         operator=(_Up&& __u)
00609         {
00610           static_assert(__and_<is_constructible<_Tp, _Up>,
00611                                is_assignable<_Tp&, _Up>>(),
00612                         "Cannot assign to value type from argument");
00613 
00614           if (this->_M_is_engaged())
00615             this->_M_get() = std::forward<_Up>(__u);
00616           else
00617             this->_M_construct(std::forward<_Up>(__u));
00618 
00619           return *this;
00620         }
00621 
00622       template<typename _Up,
00623                enable_if_t<__and_<
00624                  __not_<is_same<_Tp, _Up>>>::value,
00625                            bool> = true>
00626         optional&
00627         operator=(const optional<_Up>& __u)
00628         {
00629           static_assert(__and_<is_constructible<_Tp, _Up>,
00630                                is_assignable<_Tp&, _Up>>(),
00631                         "Cannot assign to value type from argument");
00632 
00633           if (__u)
00634             {
00635               if (this->_M_is_engaged())
00636                 this->_M_get() = *__u;
00637               else
00638                 this->_M_construct(*__u);
00639             }
00640           else
00641             {
00642               this->_M_reset();
00643             }
00644           return *this;
00645         }
00646 
00647       template<typename _Up,
00648                enable_if_t<__and_<
00649                  __not_<is_same<_Tp, _Up>>>::value,
00650                            bool> = true>
00651         optional&
00652         operator=(optional<_Up>&& __u)
00653         {
00654           static_assert(__and_<is_constructible<_Tp, _Up>,
00655                                is_assignable<_Tp&, _Up>>(),
00656                         "Cannot assign to value type from argument");
00657 
00658           if (__u)
00659             {
00660               if (this->_M_is_engaged())
00661                 this->_M_get() = std::move(*__u);
00662               else
00663                 this->_M_construct(std::move(*__u));
00664             }
00665           else
00666             {
00667               this->_M_reset();
00668             }
00669 
00670           return *this;
00671         }
00672 
00673       template<typename... _Args>
00674         void
00675         emplace(_Args&&... __args)
00676         {
00677           static_assert(is_constructible<_Tp, _Args&&...>(),
00678                         "Cannot emplace value type from arguments");
00679 
00680           this->_M_reset();
00681           this->_M_construct(std::forward<_Args>(__args)...);
00682         }
00683 
00684       template<typename _Up, typename... _Args>
00685         enable_if_t<is_constructible<_Tp, initializer_list<_Up>&,
00686                                      _Args&&...>::value>
00687         emplace(initializer_list<_Up> __il, _Args&&... __args)
00688         {
00689           this->_M_reset();
00690           this->_M_construct(__il, std::forward<_Args>(__args)...);
00691         }
00692 
00693       // [X.Y.4.2] Destructor is implicit, implemented in _Optional_base.
00694 
00695       // [X.Y.4.4] Swap.
00696       void
00697       swap(optional& __other)
00698       noexcept(is_nothrow_move_constructible<_Tp>()
00699                && noexcept(swap(declval<_Tp&>(), declval<_Tp&>())))
00700       {
00701         using std::swap;
00702 
00703         if (this->_M_is_engaged() && __other._M_is_engaged())
00704           swap(this->_M_get(), __other._M_get());
00705         else if (this->_M_is_engaged())
00706           {
00707             __other._M_construct(std::move(this->_M_get()));
00708             this->_M_destruct();
00709           }
00710         else if (__other._M_is_engaged())
00711           {
00712             this->_M_construct(std::move(__other._M_get()));
00713             __other._M_destruct();
00714           }
00715       }
00716 
00717       // [X.Y.4.5] Observers.
00718       constexpr const _Tp*
00719       operator->() const
00720       { return __constexpr_addressof(this->_M_get()); }
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