LCOV - code coverage report
Current view: top level - usr/include/boost/optional - optional.hpp (source / functions) Hit Total Coverage
Test: ROSE Lines: 0 73 0.0 %
Date: 2022-12-08 13:48:47 Functions: 0 2 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Copyright (C) 2003, 2008 Fernando Luis Cacciola Carballal.
       2             : // Copyright (C) 2014 - 2018 Andrzej Krzemienski.
       3             : //
       4             : // Use, modification, and distribution is subject to the Boost Software
       5             : // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
       6             : // http://www.boost.org/LICENSE_1_0.txt)
       7             : //
       8             : // See http://www.boost.org/libs/optional for documentation.
       9             : //
      10             : // You are welcome to contact the author at:
      11             : //  fernando_cacciola@hotmail.com
      12             : //
      13             : // Revisions:
      14             : // 27 Apr 2008 (improved swap) Fernando Cacciola, Niels Dekker, Thorsten Ottosen
      15             : // 05 May 2014 (Added move semantics) Andrzej Krzemienski
      16             : //
      17             : #ifndef BOOST_OPTIONAL_OPTIONAL_FLC_19NOV2002_HPP
      18             : #define BOOST_OPTIONAL_OPTIONAL_FLC_19NOV2002_HPP
      19             : 
      20             : #include <new>
      21             : #include <iosfwd>
      22             : 
      23             : #ifdef BOOST_OPTIONAL_DETAIL_USE_STD_TYPE_TRAITS
      24             : #  include <type_traits>
      25             : #endif
      26             : 
      27             : #include <boost/assert.hpp>
      28             : #include <boost/core/addressof.hpp>
      29             : #include <boost/core/enable_if.hpp>
      30             : #include <boost/core/explicit_operator_bool.hpp>
      31             : #include <boost/core/swap.hpp>
      32             : #include <boost/optional/bad_optional_access.hpp>
      33             : #include <boost/static_assert.hpp>
      34             : #include <boost/throw_exception.hpp>
      35             : #include <boost/type.hpp>
      36             : #include <boost/type_traits/alignment_of.hpp>
      37             : #include <boost/type_traits/conditional.hpp>
      38             : #include <boost/type_traits/has_nothrow_constructor.hpp>
      39             : #include <boost/type_traits/type_with_alignment.hpp>
      40             : #include <boost/type_traits/remove_const.hpp>
      41             : #include <boost/type_traits/remove_reference.hpp>
      42             : #include <boost/type_traits/decay.hpp>
      43             : #include <boost/type_traits/is_base_of.hpp>
      44             : #include <boost/type_traits/is_const.hpp>
      45             : #include <boost/type_traits/is_constructible.hpp>
      46             : #include <boost/type_traits/is_lvalue_reference.hpp>
      47             : #include <boost/type_traits/is_nothrow_move_assignable.hpp>
      48             : #include <boost/type_traits/is_nothrow_move_constructible.hpp>
      49             : #include <boost/type_traits/is_rvalue_reference.hpp>
      50             : #include <boost/type_traits/is_same.hpp>
      51             : #include <boost/type_traits/is_volatile.hpp>
      52             : #include <boost/type_traits/is_scalar.hpp>
      53             : #include <boost/move/utility.hpp>
      54             : #include <boost/none.hpp>
      55             : #include <boost/utility/compare_pointees.hpp>
      56             : #include <boost/utility/result_of.hpp>
      57             : 
      58             : #include <boost/optional/optional_fwd.hpp>
      59             : #include <boost/optional/detail/optional_config.hpp>
      60             : #include <boost/optional/detail/optional_factory_support.hpp>
      61             : #include <boost/optional/detail/optional_aligned_storage.hpp>
      62             : 
      63             : namespace boost { namespace optional_detail {
      64             : 
      65             : template <typename T>
      66             : struct optional_value_type
      67             : {
      68             : };
      69             : 
      70             : template <typename T>
      71             : struct optional_value_type< ::boost::optional<T> >
      72             : {
      73             :   typedef T type;
      74             : };
      75             : 
      76             : }} // namespace boost::optional_detail
      77             : 
      78             : #ifdef BOOST_OPTIONAL_CONFIG_USE_OLD_IMPLEMENTATION_OF_OPTIONAL
      79             : #include <boost/optional/detail/old_optional_implementation.hpp>
      80             : #else
      81             : namespace boost {
      82             : 
      83             : namespace optional_ns {
      84             : 
      85             : // a tag for in-place initialization of contained value
      86             : struct in_place_init_t
      87             : {
      88             :   struct init_tag{};
      89             :   explicit in_place_init_t(init_tag){}
      90             : };
      91             : const in_place_init_t in_place_init ((in_place_init_t::init_tag()));
      92             : 
      93             : // a tag for conditional in-place initialization of contained value
      94             : struct in_place_init_if_t
      95             : {
      96             :   struct init_tag{};
      97             :   explicit in_place_init_if_t(init_tag){}
      98             : };
      99             : const in_place_init_if_t in_place_init_if ((in_place_init_if_t::init_tag()));
     100             : 
     101             : } // namespace optional_ns
     102             : 
     103             : using optional_ns::in_place_init_t;
     104             : using optional_ns::in_place_init;
     105             : using optional_ns::in_place_init_if_t;
     106             : using optional_ns::in_place_init_if;
     107             : 
     108             : namespace optional_detail {
     109             : 
     110             : struct init_value_tag {};
     111             : 
     112             : struct optional_tag {};
     113             : 
     114             : 
     115             : template<class T>
     116             : class optional_base : public optional_tag
     117             : {
     118             :   private :
     119             : 
     120             :     typedef aligned_storage<T> storage_type ;
     121             :     typedef optional_base<T> this_type ;
     122             : 
     123             :   protected :
     124             : 
     125             :     typedef T value_type ;
     126             : 
     127             :   protected:
     128             :     typedef T &       reference_type ;
     129             :     typedef T const&  reference_const_type ;
     130             : #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
     131             :     typedef T &&  rval_reference_type ;
     132             :     typedef T &&  reference_type_of_temporary_wrapper ;
     133             : #endif
     134             :     typedef T *         pointer_type ;
     135             :     typedef T const*    pointer_const_type ;
     136             :     typedef T const&    argument_type ;
     137             : 
     138             :     // Creates an optional<T> uninitialized.
     139             :     // No-throw
     140           0 :     optional_base()
     141             :       :
     142           0 :       m_initialized(false) {}
     143             : 
     144             :     // Creates an optional<T> uninitialized.
     145             :     // No-throw
     146             :     optional_base ( none_t )
     147             :       :
     148             :       m_initialized(false) {}
     149             : 
     150             :     // Creates an optional<T> initialized with 'val'.
     151             :     // Can throw if T::T(T const&) does
     152           0 :     optional_base ( init_value_tag, argument_type val )
     153             :       :
     154           0 :       m_initialized(false)
     155             :     {
     156           0 :         construct(val);
     157             :     }
     158             : 
     159             : #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
     160             :     // move-construct an optional<T> initialized from an rvalue-ref to 'val'.
     161             :     // Can throw if T::T(T&&) does
     162             :     optional_base ( init_value_tag, rval_reference_type val )
     163             :       :
     164             :       m_initialized(false)
     165             :     {
     166             :       construct( boost::move(val) );
     167             :     }
     168             : #endif
     169             : 
     170             :     // Creates an optional<T> initialized with 'val' IFF cond is true, otherwise creates an uninitialized optional<T>.
     171             :     // Can throw if T::T(T const&) does
     172             :     optional_base ( bool cond, argument_type val )
     173             :       :
     174             :       m_initialized(false)
     175             :     {
     176             :       if ( cond )
     177             :         construct(val);
     178             :     }
     179             : 
     180             : #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
     181             :     // Creates an optional<T> initialized with 'move(val)' IFF cond is true, otherwise creates an uninitialized optional<T>.
     182             :     // Can throw if T::T(T &&) does
     183             :     optional_base ( bool cond, rval_reference_type val )
     184             :       :
     185             :       m_initialized(false)
     186             :     {
     187             :       if ( cond )
     188             :         construct(boost::move(val));
     189             :     }
     190             : #endif
     191             : 
     192             :     // Creates a deep copy of another optional<T>
     193             :     // Can throw if T::T(T const&) does
     194           0 :     optional_base ( optional_base const& rhs )
     195             :       :
     196           0 :       m_initialized(false)
     197             :     {
     198           0 :       if ( rhs.is_initialized() )
     199           0 :         construct(rhs.get_impl());
     200             :     }
     201             : 
     202             : #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
     203             :     // Creates a deep move of another optional<T>
     204             :     // Can throw if T::T(T&&) does
     205           0 :     optional_base ( optional_base&& rhs )
     206             :     BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value)
     207             :       :
     208           0 :       m_initialized(false)
     209             :     {
     210           0 :       if ( rhs.is_initialized() )
     211           0 :         construct( boost::move(rhs.get_impl()) );
     212             :     }
     213             : #endif
     214             : 
     215             : #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
     216             : 
     217             :     template<class Expr, class PtrExpr>
     218             :     explicit optional_base ( Expr&& expr, PtrExpr const* tag )
     219             :       :
     220             :       m_initialized(false)
     221             :     {
     222             :       construct(boost::forward<Expr>(expr),tag);
     223             :     }
     224             : 
     225             : #else
     226             :     // This is used for both converting and in-place constructions.
     227             :     // Derived classes use the 'tag' to select the appropriate
     228             :     // implementation (the correct 'construct()' overload)
     229             :     template<class Expr>
     230             :     explicit optional_base ( Expr const& expr, Expr const* tag )
     231             :       :
     232             :       m_initialized(false)
     233             :     {
     234             :       construct(expr,tag);
     235             :     }
     236             : 
     237             : #endif
     238             : 
     239           0 :     optional_base& operator= ( optional_base const& rhs )
     240             :     {
     241           0 :       this->assign(rhs);
     242             :       return *this;
     243             :     }
     244             : 
     245             : #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
     246             :     optional_base& operator= ( optional_base && rhs )
     247             :     BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value && ::boost::is_nothrow_move_assignable<T>::value)
     248             :     {
     249             :       this->assign(static_cast<optional_base&&>(rhs));
     250             :       return *this;
     251             :     }
     252             : #endif
     253             : 
     254             :     // No-throw (assuming T::~T() doesn't)
     255           0 :     ~optional_base() { destroy() ; }
     256             : 
     257             :     // Assigns from another optional<T> (deep-copies the rhs value)
     258           0 :     void assign ( optional_base const& rhs )
     259             :     {
     260           0 :       if (is_initialized())
     261             :       {
     262           0 :         if ( rhs.is_initialized() )
     263           0 :              assign_value(rhs.get_impl());
     264           0 :         else destroy();
     265             :       }
     266             :       else
     267             :       {
     268           0 :         if ( rhs.is_initialized() )
     269           0 :           construct(rhs.get_impl());
     270             :       }
     271           0 :     }
     272             : 
     273             : #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
     274             :     // Assigns from another optional<T> (deep-moves the rhs value)
     275           0 :     void assign ( optional_base&& rhs )
     276             :     {
     277           0 :       if (is_initialized())
     278             :       {
     279           0 :         if ( rhs.is_initialized() )
     280           0 :              assign_value( boost::move(rhs.get_impl()) );
     281           0 :         else destroy();
     282             :       }
     283             :       else
     284             :       {
     285           0 :         if ( rhs.is_initialized() )
     286           0 :           construct(boost::move(rhs.get_impl()));
     287             :       }
     288           0 :     }
     289             : #endif
     290             : 
     291             :     // Assigns from another _convertible_ optional<U> (deep-copies the rhs value)
     292             :     template<class U>
     293             :     void assign ( optional<U> const& rhs )
     294             :     {
     295             :       if (is_initialized())
     296             :       {
     297             :         if ( rhs.is_initialized() )
     298             : #ifndef BOOST_OPTIONAL_CONFIG_RESTORE_ASSIGNMENT_OF_NONCONVERTIBLE_TYPES
     299             :           assign_value( rhs.get() );
     300             : #else
     301             :           assign_value( static_cast<value_type>(rhs.get()) );
     302             : #endif
     303             : 
     304             :         else destroy();
     305             :       }
     306             :       else
     307             :       {
     308             :         if ( rhs.is_initialized() )
     309             : #ifndef BOOST_OPTIONAL_CONFIG_RESTORE_ASSIGNMENT_OF_NONCONVERTIBLE_TYPES
     310             :           construct(rhs.get());
     311             : #else
     312             :           construct(static_cast<value_type>(rhs.get()));
     313             : #endif
     314             :       }
     315             :     }
     316             : 
     317             : #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
     318             :     // move-assigns from another _convertible_ optional<U> (deep-moves from the rhs value)
     319             :     template<class U>
     320             :     void assign ( optional<U>&& rhs )
     321             :     {
     322             :       typedef BOOST_DEDUCED_TYPENAME optional<U>::rval_reference_type ref_type;
     323             :       if (is_initialized())
     324             :       {
     325             :         if ( rhs.is_initialized() )
     326             :              assign_value( static_cast<ref_type>(rhs.get()) );
     327             :         else destroy();
     328             :       }
     329             :       else
     330             :       {
     331             :         if ( rhs.is_initialized() )
     332             :           construct(static_cast<ref_type>(rhs.get()));
     333             :       }
     334             :     }
     335             : #endif
     336             : 
     337             :     // Assigns from a T (deep-copies the rhs value)
     338             :     void assign ( argument_type val )
     339             :     {
     340             :       if (is_initialized())
     341             :            assign_value(val);
     342             :       else construct(val);
     343             :     }
     344             : 
     345             : #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
     346             :     // Assigns from a T (deep-moves the rhs value)
     347           0 :     void assign ( rval_reference_type val )
     348             :     {
     349           0 :       if (is_initialized())
     350           0 :            assign_value( boost::move(val) );
     351           0 :       else construct( boost::move(val) );
     352             :     }
     353             : #endif
     354             : 
     355             :     // Assigns from "none", destroying the current value, if any, leaving this UNINITIALIZED
     356             :     // No-throw (assuming T::~T() doesn't)
     357             :     void assign ( none_t ) BOOST_NOEXCEPT { destroy(); }
     358             : 
     359             : #ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
     360             : 
     361             : #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
     362             :     template<class Expr, class ExprPtr>
     363             :     void assign_expr ( Expr&& expr, ExprPtr const* tag )
     364             :     {
     365             :       if (is_initialized())
     366             :         assign_expr_to_initialized(boost::forward<Expr>(expr),tag);
     367             :       else construct(boost::forward<Expr>(expr),tag);
     368             :     }
     369             : #else
     370             :     template<class Expr>
     371             :     void assign_expr ( Expr const& expr, Expr const* tag )
     372             :     {
     373             :       if (is_initialized())
     374             :         assign_expr_to_initialized(expr,tag);
     375             :       else construct(expr,tag);
     376             :     }
     377             : #endif
     378             : 
     379             : #endif
     380             : 
     381             :   public :
     382             : 
     383             :     // Destroys the current value, if any, leaving this UNINITIALIZED
     384             :     // No-throw (assuming T::~T() doesn't)
     385             :     void reset() BOOST_NOEXCEPT { destroy(); }
     386             : 
     387             :     // **DEPPRECATED** Replaces the current value -if any- with 'val'
     388             :     void reset ( argument_type val ) { assign(val); }
     389             : 
     390             :     // Returns a pointer to the value if this is initialized, otherwise,
     391             :     // returns NULL.
     392             :     // No-throw
     393             :     pointer_const_type get_ptr() const { return m_initialized ? get_ptr_impl() : 0 ; }
     394           0 :     pointer_type       get_ptr()       { return m_initialized ? get_ptr_impl() : 0 ; }
     395             : 
     396           0 :     bool is_initialized() const BOOST_NOEXCEPT { return m_initialized ; }
     397             : 
     398             :   protected :
     399             : 
     400           0 :     void construct ( argument_type val )
     401             :      {
     402           0 :        ::new (m_storage.address()) value_type(val) ;
     403           0 :        m_initialized = true ;
     404           0 :      }
     405             : 
     406             : #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
     407           0 :     void construct ( rval_reference_type val )
     408             :      {
     409           0 :        ::new (m_storage.address()) value_type( boost::move(val) ) ;
     410           0 :        m_initialized = true ;
     411           0 :      }
     412             : #endif
     413             : 
     414             : 
     415             : #if (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) && (!defined BOOST_NO_CXX11_VARIADIC_TEMPLATES)
     416             :     // Constructs in-place
     417             :     // upon exception *this is always uninitialized
     418             :     template<class... Args>
     419             :     void construct ( in_place_init_t, Args&&... args )
     420             :     {
     421             :       ::new (m_storage.address()) value_type( boost::forward<Args>(args)... ) ;
     422             :       m_initialized = true ;
     423             :     }
     424             : 
     425             :     template<class... Args>
     426             :     void emplace_assign ( Args&&... args )
     427             :     {
     428             :       destroy();
     429             :       construct(in_place_init, boost::forward<Args>(args)...);
     430             :     }
     431             : 
     432             :     template<class... Args>
     433             :     explicit optional_base ( in_place_init_t, Args&&... args )
     434             :       :
     435             :       m_initialized(false)
     436             :     {
     437             :       construct(in_place_init, boost::forward<Args>(args)...);
     438             :     }
     439             : 
     440             :     template<class... Args>
     441             :     explicit optional_base ( in_place_init_if_t, bool cond, Args&&... args )
     442             :       :
     443             :       m_initialized(false)
     444             :     {
     445             :       if ( cond )
     446             :         construct(in_place_init, boost::forward<Args>(args)...);
     447             :     }
     448             : #elif (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
     449             :     template<class Arg>
     450             :     void construct ( in_place_init_t, Arg&& arg )
     451             :      {
     452             :        ::new (m_storage.address()) value_type( boost::forward<Arg>(arg) );
     453             :        m_initialized = true ;
     454             :      }
     455             : 
     456             :     void construct ( in_place_init_t )
     457             :      {
     458             :        ::new (m_storage.address()) value_type();
     459             :        m_initialized = true ;
     460             :      }
     461             : 
     462             :     template<class Arg>
     463             :     void emplace_assign ( Arg&& arg )
     464             :      {
     465             :        destroy();
     466             :        construct(in_place_init, boost::forward<Arg>(arg)) ;
     467             :      }
     468             : 
     469             :     void emplace_assign ()
     470             :      {
     471             :        destroy();
     472             :        construct(in_place_init) ;
     473             :      }
     474             : 
     475             :     template<class Arg>
     476             :     explicit optional_base ( in_place_init_t, Arg&& arg )
     477             :       :
     478             :       m_initialized(false)
     479             :     {
     480             :       construct(in_place_init, boost::forward<Arg>(arg));
     481             :     }
     482             : 
     483             :     explicit optional_base ( in_place_init_t )
     484             :       :
     485             :       m_initialized(false)
     486             :     {
     487             :       construct(in_place_init);
     488             :     }
     489             : 
     490             :     template<class Arg>
     491             :     explicit optional_base ( in_place_init_if_t, bool cond, Arg&& arg )
     492             :       :
     493             :       m_initialized(false)
     494             :     {
     495             :       if ( cond )
     496             :         construct(in_place_init, boost::forward<Arg>(arg));
     497             :     }
     498             : 
     499             :     explicit optional_base ( in_place_init_if_t, bool cond )
     500             :       :
     501             :       m_initialized(false)
     502             :     {
     503             :       if ( cond )
     504             :         construct(in_place_init);
     505             :     }
     506             : 
     507             : #else
     508             : 
     509             :     template<class Arg>
     510             :     void construct ( in_place_init_t, const Arg& arg )
     511             :      {
     512             :        ::new (m_storage.address()) value_type( arg );
     513             :        m_initialized = true ;
     514             :      }
     515             : 
     516             :     template<class Arg>
     517             :     void construct ( in_place_init_t, Arg& arg )
     518             :      {
     519             :        ::new (m_storage.address()) value_type( arg );
     520             :        m_initialized = true ;
     521             :      }
     522             : 
     523             :     void construct ( in_place_init_t )
     524             :      {
     525             :        ::new (m_storage.address()) value_type();
     526             :        m_initialized = true ;
     527             :      }
     528             : 
     529             :     template<class Arg>
     530             :     void emplace_assign ( const Arg& arg )
     531             :     {
     532             :       destroy();
     533             :       construct(in_place_init, arg);
     534             :     }
     535             : 
     536             :     template<class Arg>
     537             :     void emplace_assign ( Arg& arg )
     538             :     {
     539             :       destroy();
     540             :       construct(in_place_init, arg);
     541             :     }
     542             : 
     543             :     void emplace_assign ()
     544             :     {
     545             :       destroy();
     546             :       construct(in_place_init);
     547             :     }
     548             : 
     549             :     template<class Arg>
     550             :     explicit optional_base ( in_place_init_t, const Arg& arg )
     551             :       : m_initialized(false)
     552             :     {
     553             :       construct(in_place_init, arg);
     554             :     }
     555             : 
     556             :     template<class Arg>
     557             :     explicit optional_base ( in_place_init_t, Arg& arg )
     558             :       : m_initialized(false)
     559             :     {
     560             :       construct(in_place_init, arg);
     561             :     }
     562             : 
     563             :     explicit optional_base ( in_place_init_t )
     564             :       : m_initialized(false)
     565             :     {
     566             :       construct(in_place_init);
     567             :     }
     568             : 
     569             :     template<class Arg>
     570             :     explicit optional_base ( in_place_init_if_t, bool cond, const Arg& arg )
     571             :       : m_initialized(false)
     572             :     {
     573             :       if ( cond )
     574             :         construct(in_place_init, arg);
     575             :     }
     576             : 
     577             :     template<class Arg>
     578             :     explicit optional_base ( in_place_init_if_t, bool cond, Arg& arg )
     579             :       : m_initialized(false)
     580             :     {
     581             :       if ( cond )
     582             :         construct(in_place_init, arg);
     583             :     }
     584             : 
     585             :     explicit optional_base ( in_place_init_if_t, bool cond )
     586             :       : m_initialized(false)
     587             :     {
     588             :       if ( cond )
     589             :         construct(in_place_init);
     590             :     }
     591             : #endif
     592             : 
     593             : #ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
     594             : 
     595             : #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
     596             :     // Constructs in-place using the given factory
     597             :     template<class Expr>
     598             :     void construct ( Expr&& factory, in_place_factory_base const* )
     599             :      {
     600             :        boost_optional_detail::construct<value_type>(factory, m_storage.address());
     601             :        m_initialized = true ;
     602             :      }
     603             : 
     604             :     // Constructs in-place using the given typed factory
     605             :     template<class Expr>
     606             :     void construct ( Expr&& factory, typed_in_place_factory_base const* )
     607             :      {
     608             :        factory.apply(m_storage.address()) ;
     609             :        m_initialized = true ;
     610             :      }
     611             : 
     612             :     template<class Expr>
     613             :     void assign_expr_to_initialized ( Expr&& factory, in_place_factory_base const* tag )
     614             :      {
     615             :        destroy();
     616             :        construct(factory,tag);
     617             :      }
     618             : 
     619             :     // Constructs in-place using the given typed factory
     620             :     template<class Expr>
     621             :     void assign_expr_to_initialized ( Expr&& factory, typed_in_place_factory_base const* tag )
     622             :      {
     623             :        destroy();
     624             :        construct(factory,tag);
     625             :      }
     626             : 
     627             : #else
     628             :     // Constructs in-place using the given factory
     629             :     template<class Expr>
     630             :     void construct ( Expr const& factory, in_place_factory_base const* )
     631             :      {
     632             :        boost_optional_detail::construct<value_type>(factory, m_storage.address());
     633             :        m_initialized = true ;
     634             :      }
     635             : 
     636             :     // Constructs in-place using the given typed factory
     637             :     template<class Expr>
     638             :     void construct ( Expr const& factory, typed_in_place_factory_base const* )
     639             :      {
     640             :        factory.apply(m_storage.address()) ;
     641             :        m_initialized = true ;
     642             :      }
     643             : 
     644             :     template<class Expr>
     645             :     void assign_expr_to_initialized ( Expr const& factory, in_place_factory_base const* tag )
     646             :      {
     647             :        destroy();
     648             :        construct(factory,tag);
     649             :      }
     650             : 
     651             :     // Constructs in-place using the given typed factory
     652             :     template<class Expr>
     653             :     void assign_expr_to_initialized ( Expr const& factory, typed_in_place_factory_base const* tag )
     654             :      {
     655             :        destroy();
     656             :        construct(factory,tag);
     657             :      }
     658             : #endif
     659             : 
     660             : #endif
     661             : 
     662             : #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
     663             :     // Constructs using any expression implicitly convertible to the single argument
     664             :     // of a one-argument T constructor.
     665             :     // Converting constructions of optional<T> from optional<U> uses this function with
     666             :     // 'Expr' being of type 'U' and relying on a converting constructor of T from U.
     667             :     template<class Expr>
     668             :     void construct ( Expr&& expr, void const* )
     669             :     {
     670             :       new (m_storage.address()) value_type(boost::forward<Expr>(expr)) ;
     671             :       m_initialized = true ;
     672             :     }
     673             : 
     674             :     // Assigns using a form any expression implicitly convertible to the single argument
     675             :     // of a T's assignment operator.
     676             :     // Converting assignments of optional<T> from optional<U> uses this function with
     677             :     // 'Expr' being of type 'U' and relying on a converting assignment of T from U.
     678             :     template<class Expr>
     679             :     void assign_expr_to_initialized ( Expr&& expr, void const* )
     680             :     {
     681             :       assign_value( boost::forward<Expr>(expr) );
     682             :     }
     683             : #else
     684             :     // Constructs using any expression implicitly convertible to the single argument
     685             :     // of a one-argument T constructor.
     686             :     // Converting constructions of optional<T> from optional<U> uses this function with
     687             :     // 'Expr' being of type 'U' and relying on a converting constructor of T from U.
     688             :     template<class Expr>
     689             :     void construct ( Expr const& expr, void const* )
     690             :      {
     691             :        new (m_storage.address()) value_type(expr) ;
     692             :        m_initialized = true ;
     693             :      }
     694             : 
     695             :     // Assigns using a form any expression implicitly convertible to the single argument
     696             :     // of a T's assignment operator.
     697             :     // Converting assignments of optional<T> from optional<U> uses this function with
     698             :     // 'Expr' being of type 'U' and relying on a converting assignment of T from U.
     699             :     template<class Expr>
     700             :     void assign_expr_to_initialized ( Expr const& expr, void const* )
     701             :      {
     702             :        assign_value(expr);
     703             :      }
     704             : 
     705             : #endif
     706             : 
     707             : #ifdef BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION
     708             :     // BCB5.64 (and probably lower versions) workaround.
     709             :     //   The in-place factories are supported by means of catch-all constructors
     710             :     //   and assignment operators (the functions are parameterized in terms of
     711             :     //   an arbitrary 'Expr' type)
     712             :     //   This compiler incorrectly resolves the overload set and sinks optional<T> and optional<U>
     713             :     //   to the 'Expr'-taking functions even though explicit overloads are present for them.
     714             :     //   Thus, the following overload is needed to properly handle the case when the 'lhs'
     715             :     //   is another optional.
     716             :     //
     717             :     // For VC<=70 compilers this workaround dosen't work becasue the comnpiler issues and error
     718             :     // instead of choosing the wrong overload
     719             :     //
     720             : #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
     721             :     // Notice that 'Expr' will be optional<T> or optional<U> (but not optional_base<..>)
     722             :     template<class Expr>
     723             :     void construct ( Expr&& expr, optional_tag const* )
     724             :      {
     725             :        if ( expr.is_initialized() )
     726             :        {
     727             :          // An exception can be thrown here.
     728             :          // It it happens, THIS will be left uninitialized.
     729             :          new (m_storage.address()) value_type(boost::move(expr.get())) ;
     730             :          m_initialized = true ;
     731             :        }
     732             :      }
     733             : #else
     734             :     // Notice that 'Expr' will be optional<T> or optional<U> (but not optional_base<..>)
     735             :     template<class Expr>
     736             :     void construct ( Expr const& expr, optional_tag const* )
     737             :      {
     738             :        if ( expr.is_initialized() )
     739             :        {
     740             :          // An exception can be thrown here.
     741             :          // It it happens, THIS will be left uninitialized.
     742             :          new (m_storage.address()) value_type(expr.get()) ;
     743             :          m_initialized = true ;
     744             :        }
     745             :      }
     746             : #endif
     747             : #endif // defined BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION
     748             : 
     749           0 :     void assign_value ( argument_type val ) { get_impl() = val; }
     750             : #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
     751           0 :     void assign_value ( rval_reference_type val ) { get_impl() = static_cast<rval_reference_type>(val); }
     752             : #endif
     753             : 
     754           0 :     void destroy()
     755             :     {
     756           0 :       if ( m_initialized )
     757           0 :         destroy_impl() ;
     758           0 :     }
     759             : 
     760           0 :     reference_const_type get_impl() const { return m_storage.ref() ; }
     761           0 :     reference_type       get_impl()       { return m_storage.ref() ; }
     762             : 
     763           0 :     pointer_const_type get_ptr_impl() const { return m_storage.ptr_ref(); }
     764           0 :     pointer_type       get_ptr_impl()       { return m_storage.ptr_ref(); }
     765             : 
     766             :   private :
     767             : 
     768             : #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1900))
     769             :     void destroy_impl ( ) { m_storage.ptr_ref()->~T() ; m_initialized = false ; }
     770             : #else
     771           0 :     void destroy_impl ( ) { m_storage.ref().T::~T() ; m_initialized = false ; }
     772             : #endif
     773             : 
     774             :     bool m_initialized ;
     775             :     storage_type m_storage ;
     776             : } ;
     777             : 
     778             : #include <boost/optional/detail/optional_trivially_copyable_base.hpp>
     779             : 
     780             : // definition of metafunciton is_optional_val_init_candidate
     781             : template <typename U>
     782             : struct is_optional_related
     783             :   : boost::conditional< boost::is_base_of<optional_detail::optional_tag, BOOST_DEDUCED_TYPENAME boost::decay<U>::type>::value
     784             :                      || boost::is_same<BOOST_DEDUCED_TYPENAME boost::decay<U>::type, none_t>::value
     785             :                      || boost::is_same<BOOST_DEDUCED_TYPENAME boost::decay<U>::type, in_place_init_t>::value
     786             :                      || boost::is_same<BOOST_DEDUCED_TYPENAME boost::decay<U>::type, in_place_init_if_t>::value,
     787             :     boost::true_type, boost::false_type>::type
     788             : {};
     789             : 
     790             : #if !defined(BOOST_OPTIONAL_DETAIL_NO_IS_CONSTRUCTIBLE_TRAIT)
     791             : 
     792             : template <typename T, typename U>
     793             : struct is_convertible_to_T_or_factory
     794             :   : boost::conditional< boost::is_base_of<boost::in_place_factory_base, BOOST_DEDUCED_TYPENAME boost::decay<U>::type>::value
     795             :                      || boost::is_base_of<boost::typed_in_place_factory_base, BOOST_DEDUCED_TYPENAME boost::decay<U>::type>::value
     796             :                      || (boost::is_constructible<T, U&&>::value && !boost::is_same<T, BOOST_DEDUCED_TYPENAME boost::decay<U>::type>::value)
     797             :                       , boost::true_type, boost::false_type>::type
     798             : {};
     799             : 
     800             : template <typename T, typename U>
     801             : struct is_optional_constructible : boost::is_constructible<T, U>
     802             : {};
     803             : 
     804             : #else
     805             : 
     806             : template <typename, typename>
     807             : struct is_convertible_to_T_or_factory : boost::true_type
     808             : {};
     809             : 
     810             : template <typename T, typename U>
     811             : struct is_optional_constructible : boost::true_type
     812             : {};
     813             : 
     814             : #endif // is_convertible condition
     815             : 
     816             : template <typename T, typename U>
     817             : struct is_optional_val_init_candidate
     818             :   : boost::conditional< !is_optional_related<U>::value && is_convertible_to_T_or_factory<T, U>::value
     819             :                       , boost::true_type, boost::false_type>::type
     820             : {};
     821             : 
     822             : } // namespace optional_detail
     823             : 
     824             : namespace optional_config {
     825             : 
     826             : template <typename T>
     827             : struct optional_uses_direct_storage_for
     828             :   : boost::conditional<(boost::is_scalar<T>::value && !boost::is_const<T>::value && !boost::is_volatile<T>::value)
     829             :                       , boost::true_type, boost::false_type>::type
     830             : {};
     831             : 
     832             : } // namespace optional_config
     833             : 
     834             : 
     835             : #ifndef BOOST_OPTIONAL_DETAIL_NO_DIRECT_STORAGE_SPEC
     836             : #  define BOOST_OPTIONAL_BASE_TYPE(T) boost::conditional< optional_config::optional_uses_direct_storage_for<T>::value, \
     837             :                                       optional_detail::tc_optional_base<T>, \
     838             :                                       optional_detail::optional_base<T> \
     839             :                                       >::type
     840             : #else
     841             : #  define BOOST_OPTIONAL_BASE_TYPE(T) optional_detail::optional_base<T>
     842             : #endif
     843             : 
     844             : template<class T>
     845           0 : class optional
     846             :   : public BOOST_OPTIONAL_BASE_TYPE(T)
     847             : {
     848             :     typedef typename BOOST_OPTIONAL_BASE_TYPE(T) base ;
     849             : 
     850             :   public :
     851             : 
     852             :     typedef optional<T> this_type ;
     853             : 
     854             :     typedef BOOST_DEDUCED_TYPENAME base::value_type           value_type ;
     855             :     typedef BOOST_DEDUCED_TYPENAME base::reference_type       reference_type ;
     856             :     typedef BOOST_DEDUCED_TYPENAME base::reference_const_type reference_const_type ;
     857             : #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
     858             :     typedef BOOST_DEDUCED_TYPENAME base::rval_reference_type  rval_reference_type ;
     859             :     typedef BOOST_DEDUCED_TYPENAME base::reference_type_of_temporary_wrapper reference_type_of_temporary_wrapper ;
     860             : #endif
     861             :     typedef BOOST_DEDUCED_TYPENAME base::pointer_type         pointer_type ;
     862             :     typedef BOOST_DEDUCED_TYPENAME base::pointer_const_type   pointer_const_type ;
     863             :     typedef BOOST_DEDUCED_TYPENAME base::argument_type        argument_type ;
     864             : 
     865             :     // Creates an optional<T> uninitialized.
     866             :     // No-throw
     867           0 :     optional() BOOST_NOEXCEPT : base() {}
     868             : 
     869             :     // Creates an optional<T> uninitialized.
     870             :     // No-throw
     871             :     optional( none_t none_ ) BOOST_NOEXCEPT : base(none_) {}
     872             : 
     873             :     // Creates an optional<T> initialized with 'val'.
     874             :     // Can throw if T::T(T const&) does
     875           0 :     optional ( argument_type val ) : base(optional_detail::init_value_tag(), val) {}
     876             : 
     877             : #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
     878             :     // Creates an optional<T> initialized with 'move(val)'.
     879             :     // Can throw if T::T(T &&) does
     880             :     optional ( rval_reference_type val ) : base(optional_detail::init_value_tag(), boost::forward<T>(val))
     881             :       {}
     882             : #endif
     883             : 
     884             :     // Creates an optional<T> initialized with 'val' IFF cond is true, otherwise creates an uninitialized optional.
     885             :     // Can throw if T::T(T const&) does
     886             :     optional ( bool cond, argument_type val ) : base(cond,val) {}
     887             : 
     888             : #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
     889             :     /// Creates an optional<T> initialized with 'val' IFF cond is true, otherwise creates an uninitialized optional.
     890             :     // Can throw if T::T(T &&) does
     891             :     optional ( bool cond, rval_reference_type val ) : base( cond, boost::forward<T>(val) )
     892             :       {}
     893             : #endif
     894             : 
     895             :     // NOTE: MSVC needs templated versions first
     896             : 
     897             :     // Creates a deep copy of another convertible optional<U>
     898             :     // Requires a valid conversion from U to T.
     899             :     // Can throw if T::T(U const&) does
     900             :     template<class U>
     901             :     explicit optional ( optional<U> const& rhs
     902             : #ifndef BOOST_OPTIONAL_DETAIL_NO_SFINAE_FRIENDLY_CONSTRUCTORS
     903             :                         ,BOOST_DEDUCED_TYPENAME boost::enable_if< optional_detail::is_optional_constructible<T, U const&>, bool>::type = true
     904             : #endif
     905             :                       )
     906             :       :
     907             :       base()
     908             :     {
     909             :       if ( rhs.is_initialized() )
     910             :         this->construct(rhs.get());
     911             :     }
     912             : 
     913             : #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
     914             :     // Creates a deep move of another convertible optional<U>
     915             :     // Requires a valid conversion from U to T.
     916             :     // Can throw if T::T(U&&) does
     917             :     template<class U>
     918             :     explicit optional ( optional<U> && rhs
     919             : #ifndef BOOST_OPTIONAL_DETAIL_NO_SFINAE_FRIENDLY_CONSTRUCTORS
     920             :                         ,BOOST_DEDUCED_TYPENAME boost::enable_if< optional_detail::is_optional_constructible<T, U>, bool>::type = true
     921             : #endif
     922             :                       )
     923             :       :
     924             :       base()
     925             :     {
     926             :       if ( rhs.is_initialized() )
     927             :         this->construct( boost::move(rhs.get()) );
     928             :     }
     929             : #endif
     930             : 
     931             : #ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
     932             :     // Creates an optional<T> with an expression which can be either
     933             :     //  (a) An instance of InPlaceFactory (i.e. in_place(a,b,...,n);
     934             :     //  (b) An instance of TypedInPlaceFactory ( i.e. in_place<T>(a,b,...,n);
     935             :     //  (c) Any expression implicitly convertible to the single type
     936             :     //      of a one-argument T's constructor.
     937             :     //  (d*) Weak compilers (BCB) might also resolved Expr as optional<T> and optional<U>
     938             :     //       even though explicit overloads are present for these.
     939             :     // Depending on the above some T ctor is called.
     940             :     // Can throw if the resolved T ctor throws.
     941             : #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
     942             : 
     943             : 
     944             :   template<class Expr>
     945             :   explicit optional ( Expr&& expr,
     946             :                       BOOST_DEDUCED_TYPENAME boost::enable_if< optional_detail::is_optional_val_init_candidate<T, Expr>, bool>::type = true
     947             :   )
     948             :     : base(boost::forward<Expr>(expr),boost::addressof(expr))
     949             :     {}
     950             : 
     951             : #else
     952             :     template<class Expr>
     953             :     explicit optional ( Expr const& expr ) : base(expr,boost::addressof(expr)) {}
     954             : #endif // !defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
     955             : #endif // !defined BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
     956             : 
     957             :     // Creates a deep copy of another optional<T>
     958             :     // Can throw if T::T(T const&) does
     959             : #ifndef BOOST_OPTIONAL_DETAIL_NO_DEFAULTED_MOVE_FUNCTIONS
     960           0 :     optional ( optional const& ) = default;
     961             : #else
     962             :     optional ( optional const& rhs ) : base( static_cast<base const&>(rhs) ) {}
     963             : #endif
     964             : 
     965             : #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
     966             :     // Creates a deep move of another optional<T>
     967             :     // Can throw if T::T(T&&) does
     968             : 
     969             : #ifndef BOOST_OPTIONAL_DETAIL_NO_DEFAULTED_MOVE_FUNCTIONS
     970           0 :     optional ( optional && rhs ) = default;
     971             : #else
     972             :     optional ( optional && rhs )
     973             :       BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value)
     974             :       : base( boost::move(rhs) )
     975             :     {}
     976             : #endif
     977             : 
     978             : #endif
     979             : 
     980             : #if BOOST_WORKAROUND(_MSC_VER, <= 1600)
     981             :     //  On old MSVC compilers the implicitly declared dtor is not called
     982             :     ~optional() {}
     983             : #endif
     984             : 
     985             : 
     986             : #if !defined(BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT) && !defined(BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION)
     987             :     // Assigns from an expression. See corresponding constructor.
     988             :     // Basic Guarantee: If the resolved T ctor throws, this is left UNINITIALIZED
     989             : #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
     990             : 
     991             :     template<class Expr>
     992             :     BOOST_DEDUCED_TYPENAME boost::enable_if<optional_detail::is_optional_val_init_candidate<T, Expr>, optional&>::type
     993             :     operator= ( Expr&& expr )
     994             :       {
     995             :         this->assign_expr(boost::forward<Expr>(expr),boost::addressof(expr));
     996             :         return *this ;
     997             :       }
     998             : 
     999             : #else
    1000             :     template<class Expr>
    1001             :     optional& operator= ( Expr const& expr )
    1002             :       {
    1003             :         this->assign_expr(expr,boost::addressof(expr));
    1004             :         return *this ;
    1005             :       }
    1006             : #endif // !defined  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
    1007             : #endif // !defined(BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT) && !defined(BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION)
    1008             : 
    1009             :     // Copy-assigns from another convertible optional<U> (converts && deep-copies the rhs value)
    1010             :     // Requires a valid conversion from U to T.
    1011             :     // Basic Guarantee: If T::T( U const& ) throws, this is left UNINITIALIZED
    1012             :     template<class U>
    1013             :     optional& operator= ( optional<U> const& rhs )
    1014             :       {
    1015             :         this->assign(rhs);
    1016             :         return *this ;
    1017             :       }
    1018             : 
    1019             : #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
    1020             :     // Move-assigns from another convertible optional<U> (converts && deep-moves the rhs value)
    1021             :     // Requires a valid conversion from U to T.
    1022             :     // Basic Guarantee: If T::T( U && ) throws, this is left UNINITIALIZED
    1023             :     template<class U>
    1024             :     optional& operator= ( optional<U> && rhs )
    1025             :       {
    1026             :         this->assign(boost::move(rhs));
    1027             :         return *this ;
    1028             :       }
    1029             : #endif
    1030             : 
    1031             :     // Assigns from another optional<T> (deep-copies the rhs value)
    1032             :     // Basic Guarantee: If T::T( T const& ) throws, this is left UNINITIALIZED
    1033             :     //  (NOTE: On BCB, this operator is not actually called and left is left UNMODIFIED in case of a throw)
    1034             : #ifndef BOOST_OPTIONAL_DETAIL_NO_DEFAULTED_MOVE_FUNCTIONS
    1035             :     optional& operator= ( optional const& rhs ) = default;
    1036             : #else
    1037             :     optional& operator= ( optional const& rhs )
    1038             :       {
    1039             :         this->assign( static_cast<base const&>(rhs) ) ;
    1040             :         return *this ;
    1041             :       }
    1042             : #endif
    1043             : 
    1044             : #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
    1045             :     // Assigns from another optional<T> (deep-moves the rhs value)
    1046             : #ifndef BOOST_OPTIONAL_DETAIL_NO_DEFAULTED_MOVE_FUNCTIONS
    1047             :     optional& operator= ( optional && ) = default;
    1048             : #else
    1049             :     optional& operator= ( optional && rhs )
    1050             :       BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value && ::boost::is_nothrow_move_assignable<T>::value)
    1051             :       {
    1052             :         this->assign( static_cast<base &&>(rhs) ) ;
    1053             :         return *this ;
    1054             :       }
    1055             : #endif
    1056             : 
    1057             : #endif // BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
    1058             : 
    1059             : #ifndef BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX
    1060             : 
    1061             :     // Assigns from a T (deep-moves/copies the rhs value)
    1062             :     template <typename T_>
    1063             :     BOOST_DEDUCED_TYPENAME boost::enable_if<boost::is_same<T, BOOST_DEDUCED_TYPENAME boost::decay<T_>::type>, optional&>::type
    1064           0 :     operator= ( T_&& val )
    1065             :       {
    1066           0 :         this->assign( boost::forward<T_>(val) ) ;
    1067             :         return *this ;
    1068             :       }
    1069             : 
    1070             : #else
    1071             : 
    1072             :     // Assigns from a T (deep-copies the rhs value)
    1073             :     // Basic Guarantee: If T::( T const& ) throws, this is left UNINITIALIZED
    1074             :     optional& operator= ( argument_type val )
    1075             :       {
    1076             :         this->assign( val ) ;
    1077             :         return *this ;
    1078             :       }
    1079             : 
    1080             : #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
    1081             :     // Assigns from a T (deep-moves the rhs value)
    1082             :     optional& operator= ( rval_reference_type val )
    1083             :       {
    1084             :         this->assign( boost::move(val) ) ;
    1085             :         return *this ;
    1086             :       }
    1087             : #endif
    1088             : 
    1089             : #endif // BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX
    1090             : 
    1091             :     // Assigns from a "none"
    1092             :     // Which destroys the current value, if any, leaving this UNINITIALIZED
    1093             :     // No-throw (assuming T::~T() doesn't)
    1094             :     optional& operator= ( none_t none_ ) BOOST_NOEXCEPT
    1095             :       {
    1096             :         this->assign( none_ ) ;
    1097             :         return *this ;
    1098             :       }
    1099             : 
    1100             : #if (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) && (!defined BOOST_NO_CXX11_VARIADIC_TEMPLATES)
    1101             :     // Constructs in-place
    1102             :     // upon exception *this is always uninitialized
    1103             :     template<class... Args>
    1104             :     void emplace ( Args&&... args )
    1105             :     {
    1106             :       this->emplace_assign( boost::forward<Args>(args)... );
    1107             :     }
    1108             : 
    1109             :     template<class... Args>
    1110             :     explicit optional ( in_place_init_t, Args&&... args )
    1111             :     : base( in_place_init, boost::forward<Args>(args)... )
    1112             :     {}
    1113             : 
    1114             :     template<class... Args>
    1115             :     explicit optional ( in_place_init_if_t, bool cond, Args&&... args )
    1116             :     : base( in_place_init_if, cond, boost::forward<Args>(args)... )
    1117             :     {}
    1118             : 
    1119             : #elif (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
    1120             :     template<class Arg>
    1121             :     void emplace ( Arg&& arg )
    1122             :      {
    1123             :        this->emplace_assign( boost::forward<Arg>(arg) );
    1124             :      }
    1125             : 
    1126             :     void emplace ()
    1127             :      {
    1128             :        this->emplace_assign();
    1129             :      }
    1130             : 
    1131             :     template<class Args>
    1132             :     explicit optional ( in_place_init_t, Args&& args )
    1133             :     : base( in_place_init, boost::forward<Args>(args) )
    1134             :     {}
    1135             : 
    1136             :     explicit optional ( in_place_init_t )
    1137             :     : base( in_place_init )
    1138             :     {}
    1139             : 
    1140             :     template<class Args>
    1141             :     explicit optional ( in_place_init_if_t, bool cond, Args&& args )
    1142             :     : base( in_place_init_if, cond, boost::forward<Args>(args) )
    1143             :     {}
    1144             : 
    1145             :     explicit optional ( in_place_init_if_t, bool cond )
    1146             :     : base( in_place_init_if, cond )
    1147             :     {}
    1148             : #else
    1149             :     template<class Arg>
    1150             :     void emplace ( const Arg& arg )
    1151             :      {
    1152             :        this->emplace_assign( arg );
    1153             :      }
    1154             : 
    1155             :     template<class Arg>
    1156             :     void emplace ( Arg& arg )
    1157             :      {
    1158             :        this->emplace_assign( arg );
    1159             :      }
    1160             : 
    1161             :     void emplace ()
    1162             :      {
    1163             :        this->emplace_assign();
    1164             :      }
    1165             : 
    1166             :     template<class Arg>
    1167             :     explicit optional ( in_place_init_t, const Arg& arg )
    1168             :     : base( in_place_init, arg )
    1169             :     {}
    1170             : 
    1171             :     template<class Arg>
    1172             :     explicit optional ( in_place_init_t, Arg& arg )
    1173             :     : base( in_place_init, arg )
    1174             :     {}
    1175             : 
    1176             :     explicit optional ( in_place_init_t )
    1177             :     : base( in_place_init )
    1178             :     {}
    1179             : 
    1180             :     template<class Arg>
    1181             :     explicit optional ( in_place_init_if_t, bool cond, const Arg& arg )
    1182             :     : base( in_place_init_if, cond, arg )
    1183             :     {}
    1184             : 
    1185             :     template<class Arg>
    1186             :     explicit optional ( in_place_init_if_t, bool cond, Arg& arg )
    1187             :     : base( in_place_init_if, cond, arg )
    1188             :     {}
    1189             : 
    1190             :     explicit optional ( in_place_init_if_t, bool cond )
    1191             :     : base( in_place_init_if, cond )
    1192             :     {}
    1193             : #endif
    1194             : 
    1195             :     void swap( optional & arg )
    1196             :       BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value && ::boost::is_nothrow_move_assignable<T>::value)
    1197             :       {
    1198             :         // allow for Koenig lookup
    1199             :         boost::swap(*this, arg);
    1200             :       }
    1201             : 
    1202             : 
    1203             :     // Returns a reference to the value if this is initialized, otherwise,
    1204             :     // the behaviour is UNDEFINED
    1205             :     // No-throw
    1206           0 :     reference_const_type get() const { BOOST_ASSERT(this->is_initialized()) ; return this->get_impl(); }
    1207           0 :     reference_type       get()       { BOOST_ASSERT(this->is_initialized()) ; return this->get_impl(); }
    1208             : 
    1209             :     // Returns a copy of the value if this is initialized, 'v' otherwise
    1210             :     reference_const_type get_value_or ( reference_const_type v ) const { return this->is_initialized() ? get() : v ; }
    1211             :     reference_type       get_value_or ( reference_type       v )       { return this->is_initialized() ? get() : v ; }
    1212             : 
    1213             :     // Returns a pointer to the value if this is initialized, otherwise,
    1214             :     // the behaviour is UNDEFINED
    1215             :     // No-throw
    1216           0 :     pointer_const_type operator->() const { BOOST_ASSERT(this->is_initialized()) ; return this->get_ptr_impl() ; }
    1217           0 :     pointer_type       operator->()       { BOOST_ASSERT(this->is_initialized()) ; return this->get_ptr_impl() ; }
    1218             : 
    1219             :     // Returns a reference to the value if this is initialized, otherwise,
    1220             :     // the behaviour is UNDEFINED
    1221             :     // No-throw
    1222             : #if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
    1223           0 :     reference_const_type operator *() const& { return this->get() ; }
    1224             :     reference_type       operator *() &      { return this->get() ; }
    1225             :     reference_type_of_temporary_wrapper operator *() && { return boost::move(this->get()) ; }
    1226             : #else
    1227             :     reference_const_type operator *() const { return this->get() ; }
    1228             :     reference_type       operator *()       { return this->get() ; }
    1229             : #endif // !defined BOOST_NO_CXX11_REF_QUALIFIERS
    1230             : 
    1231             : #if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
    1232             :     reference_const_type value() const&
    1233             :       {
    1234             :         if (this->is_initialized())
    1235             :           return this->get() ;
    1236             :         else
    1237             :           throw_exception(bad_optional_access());
    1238             :       }
    1239             : 
    1240             :     reference_type value() &
    1241             :       {
    1242             :         if (this->is_initialized())
    1243             :           return this->get() ;
    1244             :         else
    1245             :           throw_exception(bad_optional_access());
    1246             :       }
    1247             : 
    1248             :     reference_type_of_temporary_wrapper value() &&
    1249             :       {
    1250             :         if (this->is_initialized())
    1251             :           return boost::move(this->get()) ;
    1252             :         else
    1253             :           throw_exception(bad_optional_access());
    1254             :       }
    1255             : 
    1256             : #else
    1257             :     reference_const_type value() const
    1258             :       {
    1259             :         if (this->is_initialized())
    1260             :           return this->get() ;
    1261             :         else
    1262             :           throw_exception(bad_optional_access());
    1263             :       }
    1264             : 
    1265             :     reference_type value()
    1266             :       {
    1267             :         if (this->is_initialized())
    1268             :           return this->get() ;
    1269             :         else
    1270             :           throw_exception(bad_optional_access());
    1271             :       }
    1272             : #endif
    1273             : 
    1274             : 
    1275             : #ifndef BOOST_NO_CXX11_REF_QUALIFIERS
    1276             :     template <class U>
    1277             :     value_type value_or ( U&& v ) const&
    1278             :       {
    1279             :         if (this->is_initialized())
    1280             :           return get();
    1281             :         else
    1282             :           return boost::forward<U>(v);
    1283             :       }
    1284             : 
    1285             :     template <class U>
    1286             :     value_type value_or ( U&& v ) &&
    1287             :       {
    1288             :         if (this->is_initialized())
    1289             :           return boost::move(get());
    1290             :         else
    1291             :           return boost::forward<U>(v);
    1292             :       }
    1293             : #elif !defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
    1294             :     template <class U>
    1295             :     value_type value_or ( U&& v ) const
    1296             :       {
    1297             :         if (this->is_initialized())
    1298             :           return get();
    1299             :         else
    1300             :           return boost::forward<U>(v);
    1301             :       }
    1302             : #else
    1303             :     template <class U>
    1304             :     value_type value_or ( U const& v ) const
    1305             :       {
    1306             :         if (this->is_initialized())
    1307             :           return get();
    1308             :         else
    1309             :           return v;
    1310             :       }
    1311             : 
    1312             :     template <class U>
    1313             :     value_type value_or ( U& v ) const
    1314             :       {
    1315             :         if (this->is_initialized())
    1316             :           return get();
    1317             :         else
    1318             :           return v;
    1319             :       }
    1320             : #endif
    1321             : 
    1322             : 
    1323             : #if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
    1324             :     template <typename F>
    1325             :     value_type value_or_eval ( F f ) const&
    1326             :       {
    1327             :         if (this->is_initialized())
    1328             :           return get();
    1329             :         else
    1330             :           return f();
    1331             :       }
    1332             : 
    1333             :     template <typename F>
    1334             :     value_type value_or_eval ( F f ) &&
    1335             :       {
    1336             :         if (this->is_initialized())
    1337             :           return boost::move(get());
    1338             :         else
    1339             :           return f();
    1340             :       }
    1341             : 
    1342             :     template <typename F>
    1343             :     optional<typename boost::result_of<F(reference_type)>::type> map(F f) &
    1344             :       {
    1345             :         if (this->has_value())
    1346             :           return f(get());
    1347             :         else
    1348             :           return none;
    1349             :       }
    1350             : 
    1351             :     template <typename F>
    1352             :     optional<typename boost::result_of<F(reference_const_type)>::type> map(F f) const&
    1353             :       {
    1354             :         if (this->has_value())
    1355             :           return f(get());
    1356             :         else
    1357             :           return none;
    1358             :       }
    1359             : 
    1360             :     template <typename F>
    1361             :     optional<typename boost::result_of<F(reference_type_of_temporary_wrapper)>::type> map(F f) &&
    1362             :       {
    1363             :         if (this->has_value())
    1364             :           return f(boost::move(this->get()));
    1365             :         else
    1366             :           return none;
    1367             :       }
    1368             : 
    1369             :     template <typename F>
    1370             :     optional<typename optional_detail::optional_value_type<typename boost::result_of<F(reference_type)>::type>::type> flat_map(F f) &
    1371             :       {
    1372             :         if (this->has_value())
    1373             :           return f(get());
    1374             :         else
    1375             :           return none;
    1376             :       }
    1377             : 
    1378             :     template <typename F>
    1379             :     optional<typename optional_detail::optional_value_type<typename boost::result_of<F(reference_const_type)>::type>::type> flat_map(F f) const&
    1380             :       {
    1381             :         if (this->has_value())
    1382             :           return f(get());
    1383             :         else
    1384             :           return none;
    1385             :       }
    1386             : 
    1387             :     template <typename F>
    1388             :     optional<typename optional_detail::optional_value_type<typename boost::result_of<F(reference_type_of_temporary_wrapper)>::type>::type> flat_map(F f) &&
    1389             :       {
    1390             :         if (this->has_value())
    1391             :           return f(boost::move(get()));
    1392             :         else
    1393             :           return none;
    1394             :       }
    1395             : 
    1396             : #else
    1397             :     template <typename F>
    1398             :     value_type value_or_eval ( F f ) const
    1399             :       {
    1400             :         if (this->is_initialized())
    1401             :           return 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 optional_detail::optional_value_type<typename boost::result_of<F(reference_type)>::type>::type> flat_map(F f)
    1426             :       {
    1427             :         if (this->has_value())
    1428             :           return f(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_const_type)>::type>::type> flat_map(F f) const
    1435             :       {
    1436             :         if (this->has_value())
    1437             :           return f(get());
    1438             :         else
    1439             :           return none;
    1440             :       }
    1441             : 
    1442             : #endif
    1443             : 
    1444             :     bool has_value() const BOOST_NOEXCEPT { return this->is_initialized() ; }
    1445             : 
    1446           0 :     bool operator!() const BOOST_NOEXCEPT { return !this->is_initialized() ; }
    1447             : 
    1448           0 :     BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
    1449             : } ;
    1450             : 
    1451             : } // namespace boost
    1452             : 
    1453             : #endif // BOOST_OPTIONAL_CONFIG_USE_OLD_IMPLEMENTATION_OF_OPTIONAL
    1454             : 
    1455             : namespace boost {
    1456             : 
    1457             : #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
    1458             : template<class T>
    1459             : class optional<T&&>
    1460             : {
    1461             :   BOOST_STATIC_ASSERT_MSG(sizeof(T) == 0, "Optional rvalue references are illegal.");
    1462             : } ;
    1463             : #endif
    1464             : 
    1465             : } // namespace boost
    1466             : 
    1467             : #ifndef BOOST_OPTIONAL_CONFIG_DONT_SPECIALIZE_OPTIONAL_REFS
    1468             : # include <boost/optional/detail/optional_reference_spec.hpp>
    1469             : #endif
    1470             : 
    1471             : namespace boost {
    1472             : 
    1473             : #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
    1474             : 
    1475             : template<class T>
    1476             : inline
    1477             : optional<BOOST_DEDUCED_TYPENAME boost::decay<T>::type> make_optional ( T && v  )
    1478             : {
    1479             :   return optional<BOOST_DEDUCED_TYPENAME boost::decay<T>::type>(boost::forward<T>(v));
    1480             : }
    1481             : 
    1482             : // Returns optional<T>(cond,v)
    1483             : template<class T>
    1484             : inline
    1485             : optional<BOOST_DEDUCED_TYPENAME boost::decay<T>::type> make_optional ( bool cond, T && v )
    1486             : {
    1487             :   return optional<BOOST_DEDUCED_TYPENAME boost::decay<T>::type>(cond,boost::forward<T>(v));
    1488             : }
    1489             : 
    1490             : #else
    1491             : 
    1492             : // Returns optional<T>(v)
    1493             : template<class T>
    1494             : inline
    1495             : optional<T> make_optional ( T const& v  )
    1496             : {
    1497             :   return optional<T>(v);
    1498             : }
    1499             : 
    1500             : // Returns optional<T>(cond,v)
    1501             : template<class T>
    1502             : inline
    1503             : optional<T> make_optional ( bool cond, T const& v )
    1504             : {
    1505             :   return optional<T>(cond,v);
    1506             : }
    1507             : 
    1508             : #endif // BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
    1509             : 
    1510             : // Returns a reference to the value if this is initialized, otherwise, the behaviour is UNDEFINED.
    1511             : // No-throw
    1512             : template<class T>
    1513             : inline
    1514             : BOOST_DEDUCED_TYPENAME optional<T>::reference_const_type
    1515             : get ( optional<T> const& opt )
    1516             : {
    1517             :   return opt.get() ;
    1518             : }
    1519             : 
    1520             : template<class T>
    1521             : inline
    1522             : BOOST_DEDUCED_TYPENAME optional<T>::reference_type
    1523             : get ( optional<T>& opt )
    1524             : {
    1525             :   return opt.get() ;
    1526             : }
    1527             : 
    1528             : // Returns a pointer to the value if this is initialized, otherwise, returns NULL.
    1529             : // No-throw
    1530             : template<class T>
    1531             : inline
    1532             : BOOST_DEDUCED_TYPENAME optional<T>::pointer_const_type
    1533             : get ( optional<T> const* opt )
    1534             : {
    1535             :   return opt->get_ptr() ;
    1536             : }
    1537             : 
    1538             : template<class T>
    1539             : inline
    1540             : BOOST_DEDUCED_TYPENAME optional<T>::pointer_type
    1541             : get ( optional<T>* opt )
    1542             : {
    1543             :   return opt->get_ptr() ;
    1544             : }
    1545             : 
    1546             : // Returns a reference to the value if this is initialized, otherwise, the behaviour is UNDEFINED.
    1547             : // No-throw
    1548             : template<class T>
    1549             : inline
    1550             : BOOST_DEDUCED_TYPENAME optional<T>::reference_const_type
    1551             : get_optional_value_or ( optional<T> const& opt, BOOST_DEDUCED_TYPENAME optional<T>::reference_const_type v )
    1552             : {
    1553             :   return opt.get_value_or(v) ;
    1554             : }
    1555             : 
    1556             : template<class T>
    1557             : inline
    1558             : BOOST_DEDUCED_TYPENAME optional<T>::reference_type
    1559             : get_optional_value_or ( optional<T>& opt, BOOST_DEDUCED_TYPENAME optional<T>::reference_type v )
    1560             : {
    1561             :   return opt.get_value_or(v) ;
    1562             : }
    1563             : 
    1564             : // Returns a pointer to the value if this is initialized, otherwise, returns NULL.
    1565             : // No-throw
    1566             : template<class T>
    1567             : inline
    1568             : BOOST_DEDUCED_TYPENAME optional<T>::pointer_const_type
    1569             : get_pointer ( optional<T> const& opt )
    1570             : {
    1571             :   return opt.get_ptr() ;
    1572             : }
    1573             : 
    1574             : template<class T>
    1575             : inline
    1576             : BOOST_DEDUCED_TYPENAME optional<T>::pointer_type
    1577           0 : get_pointer ( optional<T>& opt )
    1578             : {
    1579           0 :   return opt.get_ptr() ;
    1580             : }
    1581             : 
    1582             : } // namespace boost
    1583             : 
    1584             : namespace boost {
    1585             : 
    1586             : // The following declaration prevents a bug where operator safe-bool is used upon streaming optional object if you forget the IO header.
    1587             : template<class CharType, class CharTrait>
    1588             : std::basic_ostream<CharType, CharTrait>&
    1589             : operator<<(std::basic_ostream<CharType, CharTrait>& os, optional_detail::optional_tag const&)
    1590             : {
    1591             :   BOOST_STATIC_ASSERT_MSG(sizeof(CharType) == 0, "If you want to output boost::optional, include header <boost/optional/optional_io.hpp>");
    1592             :   return os;
    1593             : }
    1594             : 
    1595             : } // namespace boost
    1596             : 
    1597             : #include <boost/optional/detail/optional_relops.hpp>
    1598             : #include <boost/optional/detail/optional_swap.hpp>
    1599             : 
    1600             : #endif // header guard

Generated by: LCOV version 1.14