Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:49:46

0001 // Copyright (C) 2003, 2008 Fernando Luis Cacciola Carballal.
0002 // Copyright (C) 2014 - 2021 Andrzej Krzemienski.
0003 //
0004 // Use, modification, and distribution is subject to the Boost Software
0005 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0006 // http://www.boost.org/LICENSE_1_0.txt)
0007 //
0008 // See http://www.boost.org/libs/optional for documentation.
0009 //
0010 // You are welcome to contact the author at:
0011 //  fernando_cacciola@hotmail.com
0012 //
0013 // Revisions:
0014 // 27 Apr 2008 (improved swap) Fernando Cacciola, Niels Dekker, Thorsten Ottosen
0015 // 05 May 2014 (Added move semantics) Andrzej Krzemienski
0016 //
0017 #ifndef BOOST_OPTIONAL_OPTIONAL_FLC_19NOV2002_HPP
0018 #define BOOST_OPTIONAL_OPTIONAL_FLC_19NOV2002_HPP
0019 
0020 #include <new>
0021 #ifndef BOOST_NO_IOSTREAM
0022 #include <iosfwd>
0023 #endif // BOOST_NO_IOSTREAM
0024 
0025 #ifdef BOOST_OPTIONAL_DETAIL_USE_STD_TYPE_TRAITS
0026 #  include <type_traits>
0027 #endif
0028 
0029 #include <boost/assert.hpp>
0030 #include <boost/core/addressof.hpp>
0031 #include <boost/core/enable_if.hpp>
0032 #include <boost/core/explicit_operator_bool.hpp>
0033 #include <boost/core/invoke_swap.hpp>
0034 #include <boost/optional/bad_optional_access.hpp>
0035 #include <boost/static_assert.hpp>
0036 #include <boost/throw_exception.hpp>
0037 #include <boost/type.hpp>
0038 #include <boost/type_traits/alignment_of.hpp>
0039 #include <boost/type_traits/conditional.hpp>
0040 #include <boost/type_traits/conjunction.hpp>
0041 #include <boost/type_traits/disjunction.hpp>
0042 #include <boost/type_traits/has_nothrow_constructor.hpp>
0043 #include <boost/type_traits/type_with_alignment.hpp>
0044 #include <boost/type_traits/remove_const.hpp>
0045 #include <boost/type_traits/remove_reference.hpp>
0046 #include <boost/type_traits/decay.hpp>
0047 #include <boost/type_traits/is_assignable.hpp>
0048 #include <boost/type_traits/is_base_of.hpp>
0049 #include <boost/type_traits/is_const.hpp>
0050 #include <boost/type_traits/is_constructible.hpp>
0051 #include <boost/type_traits/is_convertible.hpp>
0052 #include <boost/type_traits/is_lvalue_reference.hpp>
0053 #include <boost/type_traits/is_nothrow_move_assignable.hpp>
0054 #include <boost/type_traits/is_nothrow_move_constructible.hpp>
0055 #include <boost/type_traits/is_rvalue_reference.hpp>
0056 #include <boost/type_traits/is_same.hpp>
0057 #include <boost/type_traits/is_volatile.hpp>
0058 #include <boost/type_traits/is_scalar.hpp>
0059 #include <boost/move/utility.hpp>
0060 #include <boost/none.hpp>
0061 #include <boost/utility/compare_pointees.hpp>
0062 #include <boost/utility/result_of.hpp>
0063 
0064 #include <boost/optional/optional_fwd.hpp>
0065 #include <boost/optional/detail/optional_config.hpp>
0066 #include <boost/optional/detail/optional_factory_support.hpp>
0067 #include <boost/optional/detail/optional_aligned_storage.hpp>
0068 #include <boost/optional/detail/optional_hash.hpp>
0069 
0070 namespace boost { namespace optional_detail {
0071 
0072 template <typename T>
0073 struct optional_value_type
0074 {
0075 };
0076 
0077 template <typename T>
0078 struct optional_value_type< ::boost::optional<T> >
0079 {
0080   typedef T type;
0081 };
0082 
0083 }} // namespace boost::optional_detail
0084 
0085 #ifdef BOOST_OPTIONAL_CONFIG_USE_OLD_IMPLEMENTATION_OF_OPTIONAL
0086 #include <boost/optional/detail/old_optional_implementation.hpp>
0087 #else
0088 namespace boost {
0089 
0090 namespace optional_ns {
0091 
0092 // a tag for in-place initialization of contained value
0093 struct in_place_init_t
0094 {
0095   struct init_tag{};
0096   explicit in_place_init_t(init_tag){}
0097 };
0098 const in_place_init_t in_place_init ((in_place_init_t::init_tag()));
0099 
0100 // a tag for conditional in-place initialization of contained value
0101 struct in_place_init_if_t
0102 {
0103   struct init_tag{};
0104   explicit in_place_init_if_t(init_tag){}
0105 };
0106 const in_place_init_if_t in_place_init_if ((in_place_init_if_t::init_tag()));
0107 
0108 } // namespace optional_ns
0109 
0110 using optional_ns::in_place_init_t;
0111 using optional_ns::in_place_init;
0112 using optional_ns::in_place_init_if_t;
0113 using optional_ns::in_place_init_if;
0114 
0115 namespace optional_detail {
0116 
0117 struct init_value_tag {};
0118 
0119 struct optional_tag {};
0120 
0121 
0122 template<class T>
0123 class optional_base : public optional_tag
0124 {
0125   private :
0126 
0127     typedef aligned_storage<T> storage_type ;
0128     typedef optional_base<T> this_type ;
0129 
0130   protected :
0131 
0132     typedef T value_type ;
0133     typedef typename boost::remove_const<T>::type unqualified_value_type;
0134 
0135   protected:
0136     typedef T &       reference_type ;
0137     typedef T const&  reference_const_type ;
0138 #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
0139     typedef T &&  rval_reference_type ;
0140     typedef T &&  reference_type_of_temporary_wrapper ;
0141 #endif
0142     typedef T *         pointer_type ;
0143     typedef T const*    pointer_const_type ;
0144     typedef T const&    argument_type ;
0145 
0146     // Creates an optional<T> uninitialized.
0147     // No-throw
0148     optional_base()
0149       :
0150       m_initialized(false) {}
0151 
0152     // Creates an optional<T> uninitialized.
0153     // No-throw
0154     optional_base ( none_t )
0155       :
0156       m_initialized(false) {}
0157 
0158     // Creates an optional<T> initialized with 'val'.
0159     // Can throw if T::T(T const&) does
0160     optional_base ( init_value_tag, argument_type val )
0161       :
0162       m_initialized(false)
0163     {
0164         construct(val);
0165     }
0166 
0167 #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
0168     // move-construct an optional<T> initialized from an rvalue-ref to 'val'.
0169     // Can throw if T::T(T&&) does
0170     optional_base ( init_value_tag, rval_reference_type val )
0171       :
0172       m_initialized(false)
0173     {
0174       construct( boost::move(val) );
0175     }
0176 #endif
0177 
0178     // Creates an optional<T> initialized with 'val' IFF cond is true, otherwise creates an uninitialized optional<T>.
0179     // Can throw if T::T(T const&) does
0180     optional_base ( bool cond, argument_type val )
0181       :
0182       m_initialized(false)
0183     {
0184       if ( cond )
0185         construct(val);
0186     }
0187 
0188 #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
0189     // Creates an optional<T> initialized with 'move(val)' IFF cond is true, otherwise creates an uninitialized optional<T>.
0190     // Can throw if T::T(T &&) does
0191     optional_base ( bool cond, rval_reference_type val )
0192       :
0193       m_initialized(false)
0194     {
0195       if ( cond )
0196         construct(boost::move(val));
0197     }
0198 #endif
0199 
0200     // Creates a deep copy of another optional<T>
0201     // Can throw if T::T(T const&) does
0202     optional_base ( optional_base const& rhs )
0203       :
0204       m_initialized(false)
0205     {
0206       if ( rhs.is_initialized() )
0207         construct(rhs.get_impl());
0208     }
0209 
0210 #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
0211     // Creates a deep move of another optional<T>
0212     // Can throw if T::T(T&&) does
0213     optional_base ( optional_base&& rhs )
0214     BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value)
0215       :
0216       m_initialized(false)
0217     {
0218       if ( rhs.is_initialized() )
0219         construct( boost::move(rhs.get_impl()) );
0220     }
0221 #endif
0222 
0223 #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
0224 
0225     template<class Expr, class PtrExpr>
0226     explicit optional_base ( Expr&& expr, PtrExpr const* tag )
0227       :
0228       m_initialized(false)
0229     {
0230       construct(boost::forward<Expr>(expr),tag);
0231     }
0232 
0233 #else
0234     // This is used for both converting and in-place constructions.
0235     // Derived classes use the 'tag' to select the appropriate
0236     // implementation (the correct 'construct()' overload)
0237     template<class Expr>
0238     explicit optional_base ( Expr const& expr, Expr const* tag )
0239       :
0240       m_initialized(false)
0241     {
0242       construct(expr,tag);
0243     }
0244 
0245 #endif
0246 
0247     optional_base& operator= ( optional_base const& rhs )
0248     {
0249       this->assign(rhs);
0250       return *this;
0251     }
0252 
0253 #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
0254     optional_base& operator= ( optional_base && rhs )
0255     BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value && ::boost::is_nothrow_move_assignable<T>::value)
0256     {
0257       this->assign(static_cast<optional_base&&>(rhs));
0258       return *this;
0259     }
0260 #endif
0261 
0262     // No-throw (assuming T::~T() doesn't)
0263     ~optional_base() { destroy() ; }
0264 
0265     // Assigns from another optional<T> (deep-copies the rhs value)
0266     void assign ( optional_base const& rhs )
0267     {
0268       if (is_initialized())
0269       {
0270         if ( rhs.is_initialized() )
0271              assign_value(rhs.get_impl());
0272         else destroy();
0273       }
0274       else
0275       {
0276         if ( rhs.is_initialized() )
0277           construct(rhs.get_impl());
0278       }
0279     }
0280 
0281 #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
0282     // Assigns from another optional<T> (deep-moves the rhs value)
0283     void assign ( optional_base&& rhs )
0284     {
0285       if (is_initialized())
0286       {
0287         if ( rhs.is_initialized() )
0288              assign_value( boost::move(rhs.get_impl()) );
0289         else destroy();
0290       }
0291       else
0292       {
0293         if ( rhs.is_initialized() )
0294           construct(boost::move(rhs.get_impl()));
0295       }
0296     }
0297 #endif
0298 
0299     // Assigns from another _convertible_ optional<U> (deep-copies the rhs value)
0300     template<class U>
0301     void assign ( optional<U> const& rhs )
0302     {
0303       if (is_initialized())
0304       {
0305         if ( rhs.is_initialized() )
0306 #ifndef BOOST_OPTIONAL_CONFIG_RESTORE_ASSIGNMENT_OF_NONCONVERTIBLE_TYPES
0307           assign_value( rhs.get() );
0308 #else
0309           assign_value( static_cast<value_type>(rhs.get()) );
0310 #endif
0311 
0312         else destroy();
0313       }
0314       else
0315       {
0316         if ( rhs.is_initialized() )
0317 #ifndef BOOST_OPTIONAL_CONFIG_RESTORE_ASSIGNMENT_OF_NONCONVERTIBLE_TYPES
0318           construct(rhs.get());
0319 #else
0320           construct(static_cast<value_type>(rhs.get()));
0321 #endif
0322       }
0323     }
0324 
0325 #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
0326     // move-assigns from another _convertible_ optional<U> (deep-moves from the rhs value)
0327     template<class U>
0328     void assign ( optional<U>&& rhs )
0329     {
0330       typedef BOOST_DEDUCED_TYPENAME optional<U>::rval_reference_type ref_type;
0331       if (is_initialized())
0332       {
0333         if ( rhs.is_initialized() )
0334              assign_value( static_cast<ref_type>(rhs.get()) );
0335         else destroy();
0336       }
0337       else
0338       {
0339         if ( rhs.is_initialized() )
0340           construct(static_cast<ref_type>(rhs.get()));
0341       }
0342     }
0343 #endif
0344 
0345     // Assigns from a T (deep-copies the rhs value)
0346     void assign ( argument_type val )
0347     {
0348       if (is_initialized())
0349            assign_value(val);
0350       else construct(val);
0351     }
0352 
0353 #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
0354     // Assigns from a T (deep-moves the rhs value)
0355     void assign ( rval_reference_type val )
0356     {
0357       if (is_initialized())
0358            assign_value( boost::move(val) );
0359       else construct( boost::move(val) );
0360     }
0361 #endif
0362 
0363     // Assigns from "none", destroying the current value, if any, leaving this UNINITIALIZED
0364     // No-throw (assuming T::~T() doesn't)
0365     void assign ( none_t ) BOOST_NOEXCEPT { destroy(); }
0366 
0367 #ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
0368 
0369 #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
0370     template<class Expr, class ExprPtr>
0371     void assign_expr ( Expr&& expr, ExprPtr const* tag )
0372     {
0373       if (is_initialized())
0374         assign_expr_to_initialized(boost::forward<Expr>(expr),tag);
0375       else construct(boost::forward<Expr>(expr),tag);
0376     }
0377 #else
0378     template<class Expr>
0379     void assign_expr ( Expr const& expr, Expr const* tag )
0380     {
0381       if (is_initialized())
0382         assign_expr_to_initialized(expr,tag);
0383       else construct(expr,tag);
0384     }
0385 #endif
0386 
0387 #endif
0388 
0389   public :
0390 
0391     // Destroys the current value, if any, leaving this UNINITIALIZED
0392     // No-throw (assuming T::~T() doesn't)
0393     void reset() BOOST_NOEXCEPT { destroy(); }
0394 
0395     // **DEPRECATED** Replaces the current value -if any- with 'val'
0396     void reset ( argument_type val ) { assign(val); }
0397 
0398     // Returns a pointer to the value if this is initialized, otherwise,
0399     // returns NULL.
0400     // No-throw
0401     pointer_const_type get_ptr() const { return m_initialized ? get_ptr_impl() : 0 ; }
0402     pointer_type       get_ptr()       { return m_initialized ? get_ptr_impl() : 0 ; }
0403 
0404     bool is_initialized() const BOOST_NOEXCEPT { return m_initialized ; }
0405 
0406   protected :
0407 
0408     void construct ( argument_type val )
0409      {
0410        ::new (m_storage.address()) unqualified_value_type(val) ;
0411        m_initialized = true ;
0412      }
0413 
0414 #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
0415     void construct ( rval_reference_type val )
0416      {
0417        ::new (m_storage.address()) unqualified_value_type( boost::move(val) ) ;
0418        m_initialized = true ;
0419      }
0420 #endif
0421 
0422 
0423 #if (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) && (!defined BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0424     // Constructs in-place
0425     // upon exception *this is always uninitialized
0426     template<class... Args>
0427     void construct ( in_place_init_t, Args&&... args )
0428     {
0429       ::new (m_storage.address()) unqualified_value_type( boost::forward<Args>(args)... ) ;
0430       m_initialized = true ;
0431     }
0432 
0433     template<class... Args>
0434     void emplace_assign ( Args&&... args )
0435     {
0436       destroy();
0437       construct(in_place_init, boost::forward<Args>(args)...);
0438     }
0439 
0440     template<class... Args>
0441     explicit optional_base ( in_place_init_t, Args&&... args )
0442       :
0443       m_initialized(false)
0444     {
0445       construct(in_place_init, boost::forward<Args>(args)...);
0446     }
0447 
0448     template<class... Args>
0449     explicit optional_base ( in_place_init_if_t, bool cond, Args&&... args )
0450       :
0451       m_initialized(false)
0452     {
0453       if ( cond )
0454         construct(in_place_init, boost::forward<Args>(args)...);
0455     }
0456 #elif (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
0457     template<class Arg>
0458     void construct ( in_place_init_t, Arg&& arg )
0459      {
0460        ::new (m_storage.address()) unqualified_value_type( boost::forward<Arg>(arg) );
0461        m_initialized = true ;
0462      }
0463 
0464     void construct ( in_place_init_t )
0465      {
0466        ::new (m_storage.address()) unqualified_value_type();
0467        m_initialized = true ;
0468      }
0469 
0470     template<class Arg>
0471     void emplace_assign ( Arg&& arg )
0472      {
0473        destroy();
0474        construct(in_place_init, boost::forward<Arg>(arg)) ;
0475      }
0476 
0477     void emplace_assign ()
0478      {
0479        destroy();
0480        construct(in_place_init) ;
0481      }
0482 
0483     template<class Arg>
0484     explicit optional_base ( in_place_init_t, Arg&& arg )
0485       :
0486       m_initialized(false)
0487     {
0488       construct(in_place_init, boost::forward<Arg>(arg));
0489     }
0490 
0491     explicit optional_base ( in_place_init_t )
0492       :
0493       m_initialized(false)
0494     {
0495       construct(in_place_init);
0496     }
0497 
0498     template<class Arg>
0499     explicit optional_base ( in_place_init_if_t, bool cond, Arg&& arg )
0500       :
0501       m_initialized(false)
0502     {
0503       if ( cond )
0504         construct(in_place_init, boost::forward<Arg>(arg));
0505     }
0506 
0507     explicit optional_base ( in_place_init_if_t, bool cond )
0508       :
0509       m_initialized(false)
0510     {
0511       if ( cond )
0512         construct(in_place_init);
0513     }
0514 
0515 #else
0516 
0517     template<class Arg>
0518     void construct ( in_place_init_t, const Arg& arg )
0519      {
0520        ::new (m_storage.address()) unqualified_value_type( arg );
0521        m_initialized = true ;
0522      }
0523 
0524     template<class Arg>
0525     void construct ( in_place_init_t, Arg& arg )
0526      {
0527        ::new (m_storage.address()) unqualified_value_type( arg );
0528        m_initialized = true ;
0529      }
0530 
0531     void construct ( in_place_init_t )
0532      {
0533        ::new (m_storage.address()) unqualified_value_type();
0534        m_initialized = true ;
0535      }
0536 
0537     template<class Arg>
0538     void emplace_assign ( const Arg& arg )
0539     {
0540       destroy();
0541       construct(in_place_init, arg);
0542     }
0543 
0544     template<class Arg>
0545     void emplace_assign ( Arg& arg )
0546     {
0547       destroy();
0548       construct(in_place_init, arg);
0549     }
0550 
0551     void emplace_assign ()
0552     {
0553       destroy();
0554       construct(in_place_init);
0555     }
0556 
0557     template<class Arg>
0558     explicit optional_base ( in_place_init_t, const Arg& arg )
0559       : m_initialized(false)
0560     {
0561       construct(in_place_init, arg);
0562     }
0563 
0564     template<class Arg>
0565     explicit optional_base ( in_place_init_t, Arg& arg )
0566       : m_initialized(false)
0567     {
0568       construct(in_place_init, arg);
0569     }
0570 
0571     explicit optional_base ( in_place_init_t )
0572       : m_initialized(false)
0573     {
0574       construct(in_place_init);
0575     }
0576 
0577     template<class Arg>
0578     explicit optional_base ( in_place_init_if_t, bool cond, const Arg& arg )
0579       : m_initialized(false)
0580     {
0581       if ( cond )
0582         construct(in_place_init, arg);
0583     }
0584 
0585     template<class Arg>
0586     explicit optional_base ( in_place_init_if_t, bool cond, Arg& arg )
0587       : m_initialized(false)
0588     {
0589       if ( cond )
0590         construct(in_place_init, arg);
0591     }
0592 
0593     explicit optional_base ( in_place_init_if_t, bool cond )
0594       : m_initialized(false)
0595     {
0596       if ( cond )
0597         construct(in_place_init);
0598     }
0599 #endif
0600 
0601 #ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
0602 
0603 #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
0604     // Constructs in-place using the given factory
0605     template<class Expr>
0606     void construct ( Expr&& factory, in_place_factory_base const* )
0607      {
0608        boost_optional_detail::construct<value_type>(factory, m_storage.address());
0609        m_initialized = true ;
0610      }
0611 
0612     // Constructs in-place using the given typed factory
0613     template<class Expr>
0614     void construct ( Expr&& factory, typed_in_place_factory_base const* )
0615      {
0616        factory.apply(m_storage.address()) ;
0617        m_initialized = true ;
0618      }
0619 
0620     template<class Expr>
0621     void assign_expr_to_initialized ( Expr&& factory, in_place_factory_base const* tag )
0622      {
0623        destroy();
0624        construct(factory,tag);
0625      }
0626 
0627     // Constructs in-place using the given typed factory
0628     template<class Expr>
0629     void assign_expr_to_initialized ( Expr&& factory, typed_in_place_factory_base const* tag )
0630      {
0631        destroy();
0632        construct(factory,tag);
0633      }
0634 
0635 #else
0636     // Constructs in-place using the given factory
0637     template<class Expr>
0638     void construct ( Expr const& factory, in_place_factory_base const* )
0639      {
0640        boost_optional_detail::construct<value_type>(factory, m_storage.address());
0641        m_initialized = true ;
0642      }
0643 
0644     // Constructs in-place using the given typed factory
0645     template<class Expr>
0646     void construct ( Expr const& factory, typed_in_place_factory_base const* )
0647      {
0648        factory.apply(m_storage.address()) ;
0649        m_initialized = true ;
0650      }
0651 
0652     template<class Expr>
0653     void assign_expr_to_initialized ( Expr const& factory, in_place_factory_base const* tag )
0654      {
0655        destroy();
0656        construct(factory,tag);
0657      }
0658 
0659     // Constructs in-place using the given typed factory
0660     template<class Expr>
0661     void assign_expr_to_initialized ( Expr const& factory, typed_in_place_factory_base const* tag )
0662      {
0663        destroy();
0664        construct(factory,tag);
0665      }
0666 #endif
0667 
0668 #endif
0669 
0670 #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
0671     // Constructs using any expression implicitly convertible to the single argument
0672     // of a one-argument T constructor.
0673     // Converting constructions of optional<T> from optional<U> uses this function with
0674     // 'Expr' being of type 'U' and relying on a converting constructor of T from U.
0675     template<class Expr>
0676     void construct ( Expr&& expr, void const* )
0677     {
0678       new (m_storage.address()) unqualified_value_type(boost::forward<Expr>(expr)) ;
0679       m_initialized = true ;
0680     }
0681 
0682     // Assigns using a form any expression implicitly convertible to the single argument
0683     // of a T's assignment operator.
0684     // Converting assignments of optional<T> from optional<U> uses this function with
0685     // 'Expr' being of type 'U' and relying on a converting assignment of T from U.
0686     template<class Expr>
0687     void assign_expr_to_initialized ( Expr&& expr, void const* )
0688     {
0689       assign_value( boost::forward<Expr>(expr) );
0690     }
0691 #else
0692     // Constructs using any expression implicitly convertible to the single argument
0693     // of a one-argument T constructor.
0694     // Converting constructions of optional<T> from optional<U> uses this function with
0695     // 'Expr' being of type 'U' and relying on a converting constructor of T from U.
0696     template<class Expr>
0697     void construct ( Expr const& expr, void const* )
0698      {
0699        new (m_storage.address()) unqualified_value_type(expr) ;
0700        m_initialized = true ;
0701      }
0702 
0703     // Assigns using a form any expression implicitly convertible to the single argument
0704     // of a T's assignment operator.
0705     // Converting assignments of optional<T> from optional<U> uses this function with
0706     // 'Expr' being of type 'U' and relying on a converting assignment of T from U.
0707     template<class Expr>
0708     void assign_expr_to_initialized ( Expr const& expr, void const* )
0709      {
0710        assign_value(expr);
0711      }
0712 
0713 #endif
0714 
0715 #ifdef BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION
0716     // BCB5.64 (and probably lower versions) workaround.
0717     //   The in-place factories are supported by means of catch-all constructors
0718     //   and assignment operators (the functions are parameterized in terms of
0719     //   an arbitrary 'Expr' type)
0720     //   This compiler incorrectly resolves the overload set and sinks optional<T> and optional<U>
0721     //   to the 'Expr'-taking functions even though explicit overloads are present for them.
0722     //   Thus, the following overload is needed to properly handle the case when the 'lhs'
0723     //   is another optional.
0724     //
0725     // For VC<=70 compilers this workaround doesn't work because the compiler issues and error
0726     // instead of choosing the wrong overload
0727     //
0728 #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
0729     // Notice that 'Expr' will be optional<T> or optional<U> (but not optional_base<..>)
0730     template<class Expr>
0731     void construct ( Expr&& expr, optional_tag const* )
0732      {
0733        if ( expr.is_initialized() )
0734        {
0735          // An exception can be thrown here.
0736          // It it happens, THIS will be left uninitialized.
0737          new (m_storage.address()) unqualified_value_type(boost::move(expr.get())) ;
0738          m_initialized = true ;
0739        }
0740      }
0741 #else
0742     // Notice that 'Expr' will be optional<T> or optional<U> (but not optional_base<..>)
0743     template<class Expr>
0744     void construct ( Expr const& expr, optional_tag const* )
0745      {
0746        if ( expr.is_initialized() )
0747        {
0748          // An exception can be thrown here.
0749          // It it happens, THIS will be left uninitialized.
0750          new (m_storage.address()) unqualified_value_type(expr.get()) ;
0751          m_initialized = true ;
0752        }
0753      }
0754 #endif
0755 #endif // defined BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION
0756 
0757     void assign_value ( argument_type val ) { get_impl() = val; }
0758 #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
0759     void assign_value ( rval_reference_type val ) { get_impl() = static_cast<rval_reference_type>(val); }
0760 #endif
0761 
0762     void destroy()
0763     {
0764       if ( m_initialized )
0765         destroy_impl() ;
0766     }
0767 
0768     reference_const_type get_impl() const { return m_storage.ref() ; }
0769     reference_type       get_impl()       { return m_storage.ref() ; }
0770 
0771     pointer_const_type get_ptr_impl() const { return m_storage.ptr_ref(); }
0772     pointer_type       get_ptr_impl()       { return m_storage.ptr_ref(); }
0773 
0774   private :
0775 
0776 #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1900))
0777     void destroy_impl ( ) { m_storage.ptr_ref()->~T() ; m_initialized = false ; }
0778 #else
0779     void destroy_impl ( ) { m_storage.ref().T::~T() ; m_initialized = false ; }
0780 #endif
0781 
0782     bool m_initialized ;
0783     storage_type m_storage ;
0784 } ;
0785 
0786 #include <boost/optional/detail/optional_trivially_copyable_base.hpp>
0787 
0788 // definition of metafunction is_optional_val_init_candidate
0789 template <typename U>
0790 struct is_optional_or_tag
0791   : boost::conditional< boost::is_base_of<optional_detail::optional_tag, BOOST_DEDUCED_TYPENAME boost::decay<U>::type>::value
0792                      || boost::is_same<BOOST_DEDUCED_TYPENAME boost::decay<U>::type, none_t>::value
0793                      || boost::is_same<BOOST_DEDUCED_TYPENAME boost::decay<U>::type, in_place_init_t>::value
0794                      || boost::is_same<BOOST_DEDUCED_TYPENAME boost::decay<U>::type, in_place_init_if_t>::value,
0795     boost::true_type, boost::false_type>::type
0796 {};
0797 
0798 template <typename T, typename U>
0799 struct has_dedicated_constructor
0800   : boost::disjunction<is_optional_or_tag<U>, boost::is_same<T, BOOST_DEDUCED_TYPENAME boost::decay<U>::type> >
0801 {};
0802 
0803 template <typename U>
0804 struct is_in_place_factory
0805   : boost::disjunction< boost::is_base_of<boost::in_place_factory_base, BOOST_DEDUCED_TYPENAME boost::decay<U>::type>,
0806                         boost::is_base_of<boost::typed_in_place_factory_base, BOOST_DEDUCED_TYPENAME boost::decay<U>::type> >
0807 {};
0808 
0809 #if !defined(BOOST_OPTIONAL_DETAIL_NO_IS_CONSTRUCTIBLE_TRAIT)
0810 
0811 template <typename T, typename U>
0812 struct is_factory_or_constructible_to_T
0813   : boost::disjunction< is_in_place_factory<U>, boost::is_constructible<T, U&&> >
0814 {};
0815 
0816 template <typename T, typename U>
0817 struct is_optional_constructible : boost::is_constructible<T, U>
0818 {};
0819 
0820 #else
0821 
0822 template <typename, typename>
0823 struct is_factory_or_constructible_to_T : boost::true_type
0824 {};
0825 
0826 template <typename T, typename U>
0827 struct is_optional_constructible : boost::true_type
0828 {};
0829 
0830 #endif // is_convertible condition
0831 
0832 #if !defined(BOOST_NO_CXX11_DECLTYPE) && !BOOST_WORKAROUND(BOOST_MSVC, < 1800)
0833 // for is_assignable
0834 
0835 #if (!defined BOOST_NO_CXX11_RVALUE_REFERENCES)
0836 // On some initial rvalue reference implementations GCC does it in a strange way,
0837 // preferring perfect-forwarding constructor to implicit copy constructor.
0838 
0839 template <typename T, typename U>
0840 struct is_opt_assignable
0841   : boost::conjunction<boost::is_convertible<U&&, T>, boost::is_assignable<T&, U&&> >
0842 {};
0843 
0844 #else
0845 
0846 template <typename T, typename U>
0847 struct is_opt_assignable
0848   : boost::conjunction<boost::is_convertible<U, T>, boost::is_assignable<T&, U> >
0849 {};
0850 
0851 #endif
0852 
0853 #else
0854 
0855 template <typename T, typename U>
0856 struct is_opt_assignable : boost::is_convertible<U, T>
0857 {};
0858 
0859 #endif
0860 
0861 template <typename T, typename U>
0862 struct is_factory_or_opt_assignable_to_T
0863   : boost::disjunction< is_in_place_factory<U>, is_opt_assignable<T, U> >
0864 {};
0865 
0866 template <typename T, typename U, bool = has_dedicated_constructor<T, U>::value>
0867 struct is_optional_val_init_candidate
0868   : boost::false_type
0869 {};
0870 
0871 template <typename T, typename U>
0872 struct is_optional_val_init_candidate<T, U, false>
0873   : is_factory_or_constructible_to_T<T, U>
0874 {};
0875 
0876 template <typename T, typename U, bool = has_dedicated_constructor<T, U>::value>
0877 struct is_optional_val_assign_candidate
0878   : boost::false_type
0879 {};
0880 
0881 template <typename T, typename U>
0882 struct is_optional_val_assign_candidate<T, U, false>
0883   : is_factory_or_opt_assignable_to_T<T, U>
0884 {};
0885 
0886 } // namespace optional_detail
0887 
0888 namespace optional_config {
0889 
0890 template <typename T>
0891 struct optional_uses_direct_storage_for
0892   : boost::conditional<(boost::is_scalar<T>::value && !boost::is_const<T>::value && !boost::is_volatile<T>::value)
0893                       , boost::true_type, boost::false_type>::type
0894 {};
0895 
0896 } // namespace optional_config
0897 
0898 
0899 #ifndef BOOST_OPTIONAL_DETAIL_NO_DIRECT_STORAGE_SPEC
0900 #  define BOOST_OPTIONAL_BASE_TYPE(T) boost::conditional< optional_config::optional_uses_direct_storage_for<T>::value, \
0901                                       optional_detail::tc_optional_base<T>, \
0902                                       optional_detail::optional_base<T> \
0903                                       >::type
0904 #else
0905 #  define BOOST_OPTIONAL_BASE_TYPE(T) optional_detail::optional_base<T>
0906 #endif
0907 
0908 template<class T>
0909 class optional
0910   : public BOOST_OPTIONAL_BASE_TYPE(T)
0911 {
0912     typedef typename BOOST_OPTIONAL_BASE_TYPE(T) base ;
0913 
0914   public :
0915 
0916     typedef optional<T> this_type ;
0917 
0918     typedef BOOST_DEDUCED_TYPENAME base::value_type           value_type ;
0919     typedef BOOST_DEDUCED_TYPENAME base::reference_type       reference_type ;
0920     typedef BOOST_DEDUCED_TYPENAME base::reference_const_type reference_const_type ;
0921 #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
0922     typedef BOOST_DEDUCED_TYPENAME base::rval_reference_type  rval_reference_type ;
0923     typedef BOOST_DEDUCED_TYPENAME base::reference_type_of_temporary_wrapper reference_type_of_temporary_wrapper ;
0924 #endif
0925     typedef BOOST_DEDUCED_TYPENAME base::pointer_type         pointer_type ;
0926     typedef BOOST_DEDUCED_TYPENAME base::pointer_const_type   pointer_const_type ;
0927     typedef BOOST_DEDUCED_TYPENAME base::argument_type        argument_type ;
0928 
0929     // Creates an optional<T> uninitialized.
0930     // No-throw
0931     optional() BOOST_NOEXCEPT : base() {}
0932 
0933     // Creates an optional<T> uninitialized.
0934     // No-throw
0935     optional( none_t none_ ) BOOST_NOEXCEPT : base(none_) {}
0936 
0937     // Creates an optional<T> initialized with 'val'.
0938     // Can throw if T::T(T const&) does
0939     optional ( argument_type val ) : base(optional_detail::init_value_tag(), val) {}
0940 
0941 #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
0942     // Creates an optional<T> initialized with 'move(val)'.
0943     // Can throw if T::T(T &&) does
0944     optional ( rval_reference_type val ) : base(optional_detail::init_value_tag(), boost::forward<T>(val))
0945       {}
0946 #endif
0947 
0948     // Creates an optional<T> initialized with 'val' IFF cond is true, otherwise creates an uninitialized optional.
0949     // Can throw if T::T(T const&) does
0950     optional ( bool cond, argument_type val ) : base(cond,val) {}
0951 
0952 #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
0953     /// Creates an optional<T> initialized with 'val' IFF cond is true, otherwise creates an uninitialized optional.
0954     // Can throw if T::T(T &&) does
0955     optional ( bool cond, rval_reference_type val ) : base( cond, boost::forward<T>(val) )
0956       {}
0957 #endif
0958 
0959     // NOTE: MSVC needs templated versions first
0960 
0961     // Creates a deep copy of another convertible optional<U>
0962     // Requires a valid conversion from U to T.
0963     // Can throw if T::T(U const&) does
0964     template<class U>
0965     explicit optional ( optional<U> const& rhs
0966 #ifndef BOOST_OPTIONAL_DETAIL_NO_SFINAE_FRIENDLY_CONSTRUCTORS
0967                         ,BOOST_DEDUCED_TYPENAME boost::enable_if< optional_detail::is_optional_constructible<T, U const&>, bool>::type = true
0968 #endif
0969                       )
0970       :
0971       base()
0972     {
0973       if ( rhs.is_initialized() )
0974         this->construct(rhs.get());
0975     }
0976 
0977 #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
0978     // Creates a deep move of another convertible optional<U>
0979     // Requires a valid conversion from U to T.
0980     // Can throw if T::T(U&&) does
0981     template<class U>
0982     explicit optional ( optional<U> && rhs
0983 #ifndef BOOST_OPTIONAL_DETAIL_NO_SFINAE_FRIENDLY_CONSTRUCTORS
0984                         ,BOOST_DEDUCED_TYPENAME boost::enable_if< optional_detail::is_optional_constructible<T, U>, bool>::type = true
0985 #endif
0986                       )
0987       :
0988       base()
0989     {
0990       if ( rhs.is_initialized() )
0991         this->construct( boost::move(rhs.get()) );
0992     }
0993 #endif
0994 
0995 #ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
0996     // Creates an optional<T> with an expression which can be either
0997     //  (a) An instance of InPlaceFactory (i.e. in_place(a,b,...,n);
0998     //  (b) An instance of TypedInPlaceFactory ( i.e. in_place<T>(a,b,...,n);
0999     //  (c) Any expression implicitly convertible to the single type
1000     //      of a one-argument T's constructor.
1001     //  (d*) Weak compilers (BCB) might also resolved Expr as optional<T> and optional<U>
1002     //       even though explicit overloads are present for these.
1003     // Depending on the above some T ctor is called.
1004     // Can throw if the resolved T ctor throws.
1005 #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
1006 
1007 
1008   template<class Expr>
1009   explicit optional ( Expr&& expr,
1010                       BOOST_DEDUCED_TYPENAME boost::enable_if< optional_detail::is_optional_val_init_candidate<T, Expr>, bool>::type = true
1011   )
1012     : base(boost::forward<Expr>(expr),boost::addressof(expr))
1013     {}
1014 
1015 #else
1016     template<class Expr>
1017     explicit optional ( Expr const& expr ) : base(expr,boost::addressof(expr)) {}
1018 #endif // !defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
1019 #endif // !defined BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
1020 
1021     // Creates a deep copy of another optional<T>
1022     // Can throw if T::T(T const&) does
1023 #ifndef BOOST_OPTIONAL_DETAIL_NO_DEFAULTED_MOVE_FUNCTIONS
1024     optional ( optional const& ) = default;
1025 #else
1026     optional ( optional const& rhs ) : base( static_cast<base const&>(rhs) ) {}
1027 #endif
1028 
1029 #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
1030     // Creates a deep move of another optional<T>
1031     // Can throw if T::T(T&&) does
1032 
1033 #ifndef BOOST_OPTIONAL_DETAIL_NO_DEFAULTED_MOVE_FUNCTIONS
1034     optional ( optional && ) = default;
1035 #else
1036     optional ( optional && rhs )
1037       BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value)
1038       : base( boost::move(rhs) )
1039     {}
1040 #endif
1041 
1042 #endif
1043 
1044 #if BOOST_WORKAROUND(_MSC_VER, <= 1600)
1045     //  On old MSVC compilers the implicitly declared dtor is not called
1046     ~optional() {}
1047 #endif
1048 
1049 
1050 #if !defined(BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT) && !defined(BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION)
1051     // Assigns from an expression. See corresponding constructor.
1052     // Basic Guarantee: If the resolved T ctor throws, this is left UNINITIALIZED
1053 #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
1054 
1055     template<class Expr>
1056     BOOST_DEDUCED_TYPENAME boost::enable_if<optional_detail::is_optional_val_assign_candidate<T, Expr>, optional&>::type
1057     operator= ( Expr&& expr )
1058       {
1059         this->assign_expr(boost::forward<Expr>(expr),boost::addressof(expr));
1060         return *this ;
1061       }
1062 
1063 #else
1064     template<class Expr>
1065     optional& operator= ( Expr const& expr )
1066       {
1067         this->assign_expr(expr,boost::addressof(expr));
1068         return *this ;
1069       }
1070 #endif // !defined  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
1071 #endif // !defined(BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT) && !defined(BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION)
1072 
1073     // Copy-assigns from another convertible optional<U> (converts && deep-copies the rhs value)
1074     // Requires a valid conversion from U to T.
1075     // Basic Guarantee: If T::T( U const& ) throws, this is left UNINITIALIZED
1076     template<class U>
1077     optional& operator= ( optional<U> const& rhs )
1078       {
1079         this->assign(rhs);
1080         return *this ;
1081       }
1082 
1083 #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
1084     // Move-assigns from another convertible optional<U> (converts && deep-moves the rhs value)
1085     // Requires a valid conversion from U to T.
1086     // Basic Guarantee: If T::T( U && ) throws, this is left UNINITIALIZED
1087     template<class U>
1088     optional& operator= ( optional<U> && rhs )
1089       {
1090         this->assign(boost::move(rhs));
1091         return *this ;
1092       }
1093 #endif
1094 
1095     // Assigns from another optional<T> (deep-copies the rhs value)
1096     // Basic Guarantee: If T::T( T const& ) throws, this is left UNINITIALIZED
1097     //  (NOTE: On BCB, this operator is not actually called and left is left UNMODIFIED in case of a throw)
1098 #ifndef BOOST_OPTIONAL_DETAIL_NO_DEFAULTED_MOVE_FUNCTIONS
1099     optional& operator= ( optional const& rhs ) = default;
1100 #else
1101     optional& operator= ( optional const& rhs )
1102       {
1103         this->assign( static_cast<base const&>(rhs) ) ;
1104         return *this ;
1105       }
1106 #endif
1107 
1108 #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
1109     // Assigns from another optional<T> (deep-moves the rhs value)
1110 #ifndef BOOST_OPTIONAL_DETAIL_NO_DEFAULTED_MOVE_FUNCTIONS
1111     optional& operator= ( optional && ) = default;
1112 #else
1113     optional& operator= ( optional && rhs )
1114       BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value && ::boost::is_nothrow_move_assignable<T>::value)
1115       {
1116         this->assign( static_cast<base &&>(rhs) ) ;
1117         return *this ;
1118       }
1119 #endif
1120 
1121 #endif // BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
1122 
1123 #ifndef BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX
1124 
1125     // Assigns from a T (deep-moves/copies the rhs value)
1126     template <typename T_>
1127     BOOST_DEDUCED_TYPENAME boost::enable_if<boost::is_same<T, BOOST_DEDUCED_TYPENAME boost::decay<T_>::type>, optional&>::type
1128     operator= ( T_&& val )
1129       {
1130         this->assign( boost::forward<T_>(val) ) ;
1131         return *this ;
1132       }
1133 
1134 #else
1135 
1136     // Assigns from a T (deep-copies the rhs value)
1137     // Basic Guarantee: If T::( T const& ) throws, this is left UNINITIALIZED
1138     optional& operator= ( argument_type val )
1139       {
1140         this->assign( val ) ;
1141         return *this ;
1142       }
1143 
1144 #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
1145     // Assigns from a T (deep-moves the rhs value)
1146     optional& operator= ( rval_reference_type val )
1147       {
1148         this->assign( boost::move(val) ) ;
1149         return *this ;
1150       }
1151 #endif
1152 
1153 #endif // BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX
1154 
1155     // Assigns from a "none"
1156     // Which destroys the current value, if any, leaving this UNINITIALIZED
1157     // No-throw (assuming T::~T() doesn't)
1158     optional& operator= ( none_t none_ ) BOOST_NOEXCEPT
1159       {
1160         this->assign( none_ ) ;
1161         return *this ;
1162       }
1163 
1164 #if (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) && (!defined BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1165     // Constructs in-place
1166     // upon exception *this is always uninitialized
1167     template<class... Args>
1168     void emplace ( Args&&... args )
1169     {
1170       this->emplace_assign( boost::forward<Args>(args)... );
1171     }
1172 
1173     template<class... Args>
1174     explicit optional ( in_place_init_t, Args&&... args )
1175     : base( in_place_init, boost::forward<Args>(args)... )
1176     {}
1177 
1178     template<class... Args>
1179     explicit optional ( in_place_init_if_t, bool cond, Args&&... args )
1180     : base( in_place_init_if, cond, boost::forward<Args>(args)... )
1181     {}
1182 
1183 #elif (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
1184     template<class Arg>
1185     void emplace ( Arg&& arg )
1186      {
1187        this->emplace_assign( boost::forward<Arg>(arg) );
1188      }
1189 
1190     void emplace ()
1191      {
1192        this->emplace_assign();
1193      }
1194 
1195     template<class Args>
1196     explicit optional ( in_place_init_t, Args&& args )
1197     : base( in_place_init, boost::forward<Args>(args) )
1198     {}
1199 
1200     explicit optional ( in_place_init_t )
1201     : base( in_place_init )
1202     {}
1203 
1204     template<class Args>
1205     explicit optional ( in_place_init_if_t, bool cond, Args&& args )
1206     : base( in_place_init_if, cond, boost::forward<Args>(args) )
1207     {}
1208 
1209     explicit optional ( in_place_init_if_t, bool cond )
1210     : base( in_place_init_if, cond )
1211     {}
1212 #else
1213     template<class Arg>
1214     void emplace ( const Arg& arg )
1215      {
1216        this->emplace_assign( arg );
1217      }
1218 
1219     template<class Arg>
1220     void emplace ( Arg& arg )
1221      {
1222        this->emplace_assign( arg );
1223      }
1224 
1225     void emplace ()
1226      {
1227        this->emplace_assign();
1228      }
1229 
1230     template<class Arg>
1231     explicit optional ( in_place_init_t, const Arg& arg )
1232     : base( in_place_init, arg )
1233     {}
1234 
1235     template<class Arg>
1236     explicit optional ( in_place_init_t, Arg& arg )
1237     : base( in_place_init, arg )
1238     {}
1239 
1240     explicit optional ( in_place_init_t )
1241     : base( in_place_init )
1242     {}
1243 
1244     template<class Arg>
1245     explicit optional ( in_place_init_if_t, bool cond, const Arg& arg )
1246     : base( in_place_init_if, cond, arg )
1247     {}
1248 
1249     template<class Arg>
1250     explicit optional ( in_place_init_if_t, bool cond, Arg& arg )
1251     : base( in_place_init_if, cond, arg )
1252     {}
1253 
1254     explicit optional ( in_place_init_if_t, bool cond )
1255     : base( in_place_init_if, cond )
1256     {}
1257 #endif
1258 
1259     void swap( optional & arg )
1260       BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value && ::boost::is_nothrow_move_assignable<T>::value)
1261       {
1262         // allow for Koenig lookup
1263         boost::core::invoke_swap(*this, arg);
1264       }
1265 
1266 
1267     // Returns a reference to the value if this is initialized, otherwise,
1268     // the behaviour is UNDEFINED
1269     // No-throw
1270     reference_const_type get() const { BOOST_ASSERT(this->is_initialized()) ; return this->get_impl(); }
1271     reference_type       get()       { BOOST_ASSERT(this->is_initialized()) ; return this->get_impl(); }
1272 
1273     // Returns a copy of the value if this is initialized, 'v' otherwise
1274     reference_const_type get_value_or ( reference_const_type v ) const { return this->is_initialized() ? get() : v ; }
1275     reference_type       get_value_or ( reference_type       v )       { return this->is_initialized() ? get() : v ; }
1276 
1277     // Returns a pointer to the value if this is initialized, otherwise,
1278     // the behaviour is UNDEFINED
1279     // No-throw
1280     pointer_const_type operator->() const { BOOST_ASSERT(this->is_initialized()) ; return this->get_ptr_impl() ; }
1281     pointer_type       operator->()       { BOOST_ASSERT(this->is_initialized()) ; return this->get_ptr_impl() ; }
1282 
1283     // Returns a reference to the value if this is initialized, otherwise,
1284     // the behaviour is UNDEFINED
1285     // No-throw
1286 #if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
1287     reference_const_type operator *() const& { return this->get() ; }
1288     reference_type       operator *() &      { return this->get() ; }
1289     reference_type_of_temporary_wrapper operator *() && { return boost::move(this->get()) ; }
1290 #else
1291     reference_const_type operator *() const { return this->get() ; }
1292     reference_type       operator *()       { return this->get() ; }
1293 #endif // !defined BOOST_NO_CXX11_REF_QUALIFIERS
1294 
1295 #if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
1296     reference_const_type value() const&
1297       {
1298         if (this->is_initialized())
1299           return this->get() ;
1300         else
1301           throw_exception(bad_optional_access());
1302       }
1303 
1304     reference_type value() &
1305       {
1306         if (this->is_initialized())
1307           return this->get() ;
1308         else
1309           throw_exception(bad_optional_access());
1310       }
1311 
1312     reference_type_of_temporary_wrapper value() &&
1313       {
1314         if (this->is_initialized())
1315           return boost::move(this->get()) ;
1316         else
1317           throw_exception(bad_optional_access());
1318       }
1319 
1320 #else
1321     reference_const_type value() const
1322       {
1323         if (this->is_initialized())
1324           return this->get() ;
1325         else
1326           throw_exception(bad_optional_access());
1327       }
1328 
1329     reference_type value()
1330       {
1331         if (this->is_initialized())
1332           return this->get() ;
1333         else
1334           throw_exception(bad_optional_access());
1335       }
1336 #endif
1337 
1338 
1339 #ifndef BOOST_NO_CXX11_REF_QUALIFIERS
1340     template <class U>
1341     value_type value_or ( U&& v ) const&
1342       {
1343         if (this->is_initialized())
1344           return get();
1345         else
1346           return boost::forward<U>(v);
1347       }
1348 
1349     template <class U>
1350     value_type value_or ( U&& v ) &&
1351       {
1352         if (this->is_initialized())
1353           return boost::move(get());
1354         else
1355           return boost::forward<U>(v);
1356       }
1357 #elif !defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
1358     template <class U>
1359     value_type value_or ( U&& v ) const
1360       {
1361         if (this->is_initialized())
1362           return get();
1363         else
1364           return boost::forward<U>(v);
1365       }
1366 #else
1367     template <class U>
1368     value_type value_or ( U const& v ) const
1369       {
1370         if (this->is_initialized())
1371           return get();
1372         else
1373           return v;
1374       }
1375 
1376     template <class U>
1377     value_type value_or ( U& v ) const
1378       {
1379         if (this->is_initialized())
1380           return get();
1381         else
1382           return v;
1383       }
1384 #endif
1385 
1386 
1387 #if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
1388     template <typename F>
1389     value_type value_or_eval ( F f ) const&
1390       {
1391         if (this->is_initialized())
1392           return get();
1393         else
1394           return f();
1395       }
1396 
1397     template <typename F>
1398     value_type value_or_eval ( F f ) &&
1399       {
1400         if (this->is_initialized())
1401           return boost::move(get());
1402         else
1403           return f();
1404       }
1405 
1406     template <typename F>
1407     optional<typename boost::result_of<F(reference_type)>::type> map(F f) &
1408       {
1409         if (this->has_value())
1410           return f(get());
1411         else
1412           return none;
1413       }
1414 
1415     template <typename F>
1416     optional<typename boost::result_of<F(reference_const_type)>::type> map(F f) const&
1417       {
1418         if (this->has_value())
1419           return f(get());
1420         else
1421           return none;
1422       }
1423 
1424     template <typename F>
1425     optional<typename boost::result_of<F(reference_type_of_temporary_wrapper)>::type> map(F f) &&
1426       {
1427         if (this->has_value())
1428           return f(boost::move(this->get()));
1429         else
1430           return none;
1431       }
1432 
1433     template <typename F>
1434     optional<typename optional_detail::optional_value_type<typename boost::result_of<F(reference_type)>::type>::type> flat_map(F f) &
1435       {
1436         if (this->has_value())
1437           return f(get());
1438         else
1439           return none;
1440       }
1441 
1442     template <typename F>
1443     optional<typename optional_detail::optional_value_type<typename boost::result_of<F(reference_const_type)>::type>::type> flat_map(F f) const&
1444       {
1445         if (this->has_value())
1446           return f(get());
1447         else
1448           return none;
1449       }
1450 
1451     template <typename F>
1452     optional<typename optional_detail::optional_value_type<typename boost::result_of<F(reference_type_of_temporary_wrapper)>::type>::type> flat_map(F f) &&
1453       {
1454         if (this->has_value())
1455           return f(boost::move(get()));
1456         else
1457           return none;
1458       }
1459 
1460 #else
1461     template <typename F>
1462     value_type value_or_eval ( F f ) const
1463       {
1464         if (this->is_initialized())
1465           return get();
1466         else
1467           return f();
1468       }
1469 
1470     template <typename F>
1471     optional<typename boost::result_of<F(reference_type)>::type> map(F f)
1472       {
1473         if (this->has_value())
1474           return f(get());
1475         else
1476           return none;
1477       }
1478 
1479     template <typename F>
1480     optional<typename boost::result_of<F(reference_const_type)>::type> map(F f) const
1481       {
1482         if (this->has_value())
1483           return f(get());
1484         else
1485           return none;
1486       }
1487 
1488     template <typename F>
1489     optional<typename optional_detail::optional_value_type<typename boost::result_of<F(reference_type)>::type>::type> flat_map(F f)
1490       {
1491         if (this->has_value())
1492           return f(get());
1493         else
1494           return none;
1495       }
1496 
1497     template <typename F>
1498     optional<typename optional_detail::optional_value_type<typename boost::result_of<F(reference_const_type)>::type>::type> flat_map(F f) const
1499       {
1500         if (this->has_value())
1501           return f(get());
1502         else
1503           return none;
1504       }
1505 
1506 #endif
1507 
1508     bool has_value() const BOOST_NOEXCEPT { return this->is_initialized() ; }
1509 
1510     bool operator!() const BOOST_NOEXCEPT { return !this->is_initialized() ; }
1511 
1512     BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
1513 } ;
1514 
1515 } // namespace boost
1516 
1517 #endif // BOOST_OPTIONAL_CONFIG_USE_OLD_IMPLEMENTATION_OF_OPTIONAL
1518 
1519 namespace boost {
1520 
1521 #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
1522 template<class T>
1523 class optional<T&&>
1524 {
1525   BOOST_STATIC_ASSERT_MSG(sizeof(T) == 0, "Optional rvalue references are illegal.");
1526 } ;
1527 #endif
1528 
1529 } // namespace boost
1530 
1531 #ifndef BOOST_OPTIONAL_CONFIG_DONT_SPECIALIZE_OPTIONAL_REFS
1532 # include <boost/optional/detail/optional_reference_spec.hpp>
1533 #endif
1534 
1535 namespace boost {
1536 
1537 #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
1538 
1539 template<class T>
1540 inline
1541 optional<BOOST_DEDUCED_TYPENAME boost::decay<T>::type> make_optional ( T && v  )
1542 {
1543   return optional<BOOST_DEDUCED_TYPENAME boost::decay<T>::type>(boost::forward<T>(v));
1544 }
1545 
1546 // Returns optional<T>(cond,v)
1547 template<class T>
1548 inline
1549 optional<BOOST_DEDUCED_TYPENAME boost::decay<T>::type> make_optional ( bool cond, T && v )
1550 {
1551   return optional<BOOST_DEDUCED_TYPENAME boost::decay<T>::type>(cond,boost::forward<T>(v));
1552 }
1553 
1554 #else
1555 
1556 // Returns optional<T>(v)
1557 template<class T>
1558 inline
1559 optional<T> make_optional ( T const& v  )
1560 {
1561   return optional<T>(v);
1562 }
1563 
1564 // Returns optional<T>(cond,v)
1565 template<class T>
1566 inline
1567 optional<T> make_optional ( bool cond, T const& v )
1568 {
1569   return optional<T>(cond,v);
1570 }
1571 
1572 #endif // BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
1573 
1574 // Returns a reference to the value if this is initialized, otherwise, the behaviour is UNDEFINED.
1575 // No-throw
1576 template<class T>
1577 inline
1578 BOOST_DEDUCED_TYPENAME optional<T>::reference_const_type
1579 get ( optional<T> const& opt )
1580 {
1581   return opt.get() ;
1582 }
1583 
1584 template<class T>
1585 inline
1586 BOOST_DEDUCED_TYPENAME optional<T>::reference_type
1587 get ( optional<T>& opt )
1588 {
1589   return opt.get() ;
1590 }
1591 
1592 // Returns a pointer to the value if this is initialized, otherwise, returns NULL.
1593 // No-throw
1594 template<class T>
1595 inline
1596 BOOST_DEDUCED_TYPENAME optional<T>::pointer_const_type
1597 get ( optional<T> const* opt )
1598 {
1599   return opt->get_ptr() ;
1600 }
1601 
1602 template<class T>
1603 inline
1604 BOOST_DEDUCED_TYPENAME optional<T>::pointer_type
1605 get ( optional<T>* opt )
1606 {
1607   return opt->get_ptr() ;
1608 }
1609 
1610 // Returns a reference to the value if this is initialized, otherwise, the behaviour is UNDEFINED.
1611 // No-throw
1612 template<class T>
1613 inline
1614 BOOST_DEDUCED_TYPENAME optional<T>::reference_const_type
1615 get_optional_value_or ( optional<T> const& opt, BOOST_DEDUCED_TYPENAME optional<T>::reference_const_type v )
1616 {
1617   return opt.get_value_or(v) ;
1618 }
1619 
1620 template<class T>
1621 inline
1622 BOOST_DEDUCED_TYPENAME optional<T>::reference_type
1623 get_optional_value_or ( optional<T>& opt, BOOST_DEDUCED_TYPENAME optional<T>::reference_type v )
1624 {
1625   return opt.get_value_or(v) ;
1626 }
1627 
1628 // Returns a pointer to the value if this is initialized, otherwise, returns NULL.
1629 // No-throw
1630 template<class T>
1631 inline
1632 BOOST_DEDUCED_TYPENAME optional<T>::pointer_const_type
1633 get_pointer ( optional<T> const& opt )
1634 {
1635   return opt.get_ptr() ;
1636 }
1637 
1638 template<class T>
1639 inline
1640 BOOST_DEDUCED_TYPENAME optional<T>::pointer_type
1641 get_pointer ( optional<T>& opt )
1642 {
1643   return opt.get_ptr() ;
1644 }
1645 
1646 } // namespace boost
1647 
1648 #ifndef BOOST_NO_IOSTREAM
1649 namespace boost {
1650 
1651 // The following declaration prevents a bug where operator safe-bool is used upon streaming optional object if you forget the IO header.
1652 template<class CharType, class CharTrait>
1653 std::basic_ostream<CharType, CharTrait>&
1654 operator<<(std::basic_ostream<CharType, CharTrait>& os, optional_detail::optional_tag const&)
1655 {
1656   BOOST_STATIC_ASSERT_MSG(sizeof(CharType) == 0, "If you want to output boost::optional, include header <boost/optional/optional_io.hpp>");
1657   return os;
1658 }
1659 
1660 } // namespace boost
1661 #endif // BOOST_NO_IOSTREAM
1662 
1663 #include <boost/optional/detail/optional_relops.hpp>
1664 #include <boost/optional/detail/optional_swap.hpp>
1665 
1666 #endif // header guard