BVB Source Codes

mars Show optional.hpp Source code

Return Download mars: download optional.hpp Source code - Download mars Source code - Type:.hpp
  1. // Copyright (C) 2003, 2008 Fernando Luis Cacciola Carballal.
  2. // Copyright (C) 2014, 2015 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. #include <boost/config.hpp>
  24. #include <boost/assert.hpp>
  25. #include <boost/core/addressof.hpp>
  26. #include <boost/core/enable_if.hpp>
  27. #include <boost/core/explicit_operator_bool.hpp>
  28. #include <boost/core/swap.hpp>
  29. #include <boost/optional/bad_optional_access.hpp>
  30. #include <boost/static_assert.hpp>
  31. #include <boost/throw_exception.hpp>
  32. #include <boost/type.hpp>
  33. #include <boost/type_traits/alignment_of.hpp>
  34. #include <boost/type_traits/has_nothrow_constructor.hpp>
  35. #include <boost/type_traits/type_with_alignment.hpp>
  36. #include <boost/type_traits/remove_const.hpp>
  37. #include <boost/type_traits/remove_reference.hpp>
  38. #include <boost/type_traits/decay.hpp>
  39. #include <boost/type_traits/is_base_of.hpp>
  40. #include <boost/type_traits/is_lvalue_reference.hpp>
  41. #include <boost/type_traits/is_nothrow_move_assignable.hpp>
  42. #include <boost/type_traits/is_nothrow_move_constructible.hpp>
  43. #include <boost/type_traits/is_reference.hpp>
  44. #include <boost/type_traits/is_rvalue_reference.hpp>
  45. #include <boost/type_traits/is_same.hpp>
  46. #include <boost/mpl/if.hpp>
  47. #include <boost/mpl/bool.hpp>
  48. #include <boost/mpl/not.hpp>
  49. #include <boost/detail/reference_content.hpp>
  50. #include <boost/move/utility.hpp>
  51. #include <boost/none.hpp>
  52. #include <boost/utility/compare_pointees.hpp>
  53.  
  54. #include <boost/optional/optional_fwd.hpp>
  55.  
  56. #if (defined BOOST_NO_CXX11_RVALUE_REFERENCES) || (defined BOOST_OPTIONAL_CONFIG_NO_RVALUE_REFERENCES)
  57. #define BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
  58. #endif
  59.  
  60. #if BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION,<=700)
  61. // AFAICT only Intel 7 correctly resolves the overload set
  62. // that includes the in-place factory taking functions,
  63. // so for the other icc versions, in-place factory support
  64. // is disabled
  65. #define BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
  66. #endif
  67.  
  68. #if BOOST_WORKAROUND(__BORLANDC__, <= 0x551)
  69. // BCB (5.5.1) cannot parse the nested template struct in an inplace factory.
  70. #define BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
  71. #endif
  72.  
  73. #if !defined(BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT) \
  74.     && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581) )
  75. // BCB (up to 5.64) has the following bug:
  76. //   If there is a member function/operator template of the form
  77. //     template<class Expr> mfunc( Expr expr ) ;
  78. //   some calls are resolved to this even if there are other better matches.
  79. //   The effect of this bug is that calls to converting ctors and assignments
  80. //   are incrorrectly sink to this general catch-all member function template as shown above.
  81. #define BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION
  82. #endif
  83.  
  84. #if defined(__GNUC__) && !defined(__INTEL_COMPILER)
  85. // GCC since 3.3 has may_alias attribute that helps to alleviate optimizer issues with
  86. // regard to violation of the strict aliasing rules. The optional< T > storage type is marked
  87. // with this attribute in order to let the compiler know that it will alias objects of type T
  88. // and silence compilation warnings.
  89. #define BOOST_OPTIONAL_DETAIL_USE_ATTRIBUTE_MAY_ALIAS
  90. #endif
  91.  
  92. // Daniel Wallin discovered that bind/apply.hpp badly interacts with the apply<>
  93. // member template of a factory as used in the optional<> implementation.
  94. // He proposed this simple fix which is to move the call to apply<> outside
  95. // namespace mars_boost.
  96. namespace mars_boost_optional_detail
  97. {
  98.   template <class T, class Factory>
  99.   inline void construct(Factory const& factory, void* address)
  100.   {
  101.     factory.BOOST_NESTED_TEMPLATE apply<T>(address);
  102.   }
  103. }
  104.  
  105.  
  106. namespace mars_boost {} namespace boost = mars_boost; namespace mars_boost {
  107.  
  108. class in_place_factory_base ;
  109. class typed_in_place_factory_base ;
  110.  
  111. // This forward is needed to refer to namespace scope swap from the member swap
  112. template<class T> void swap ( optional<T>& x, optional<T>& y );
  113.  
  114. namespace optional_detail {
  115. // This local class is used instead of that in "aligned_storage.hpp"
  116. // because I've found the 'official' class to ICE BCB5.5
  117. // when some types are used with optional<>
  118. // (due to sizeof() passed down as a non-type template parameter)
  119. template <class T>
  120. class aligned_storage
  121. {
  122.     // Borland ICEs if unnamed unions are used for this!
  123.     union
  124.     // This works around GCC warnings about breaking strict aliasing rules when casting storage address to T*
  125. #if defined(BOOST_OPTIONAL_DETAIL_USE_ATTRIBUTE_MAY_ALIAS)
  126.     __attribute__((__may_alias__))
  127. #endif
  128.     dummy_u
  129.     {
  130.         char data[ sizeof(T) ];
  131.         BOOST_DEDUCED_TYPENAME type_with_alignment<
  132.           ::mars_boost::alignment_of<T>::value >::type aligner_;
  133.     } dummy_ ;
  134.  
  135.   public:
  136.  
  137. #if defined(BOOST_OPTIONAL_DETAIL_USE_ATTRIBUTE_MAY_ALIAS)
  138.     void const* address() const { return &dummy_; }
  139.     void      * address()       { return &dummy_; }
  140. #else
  141.     void const* address() const { return dummy_.data; }
  142.     void      * address()       { return dummy_.data; }
  143. #endif
  144. } ;
  145.  
  146. template<class T>
  147. struct types_when_isnt_ref
  148. {
  149.   typedef T const& reference_const_type ;
  150.   typedef T &      reference_type ;
  151. #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
  152.   typedef T &&     rval_reference_type ;
  153.   typedef T &&     reference_type_of_temporary_wrapper;
  154. #ifdef BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
  155.   // GCC 4.4 has support for an early draft of rvalue references. The conforming version below
  156.   // causes warnings about returning references to a temporary.
  157.   static T&& move(T&& r) { return r; }
  158. #else
  159.   static rval_reference_type move(reference_type r) { return mars_boost::move(r); }
  160. #endif
  161. #endif
  162.   typedef T const* pointer_const_type ;
  163.   typedef T *      pointer_type ;
  164.   typedef T const& argument_type ;
  165. } ;
  166.  
  167. template<class T>
  168. struct types_when_is_ref
  169. {
  170.   typedef BOOST_DEDUCED_TYPENAME remove_reference<T>::type raw_type ;
  171.  
  172.   typedef raw_type&  reference_const_type ;
  173.   typedef raw_type&  reference_type ;
  174. #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
  175.   typedef BOOST_DEDUCED_TYPENAME remove_const<raw_type>::type&& rval_reference_type ;
  176.   typedef raw_type&  reference_type_of_temporary_wrapper;
  177.   static reference_type move(reference_type r) { return r; }
  178. #endif
  179.   typedef raw_type*  pointer_const_type ;
  180.   typedef raw_type*  pointer_type ;
  181.   typedef raw_type&  argument_type ;
  182. } ;
  183.  
  184. template <class To, class From>
  185. void prevent_binding_rvalue_ref_to_optional_lvalue_ref()
  186. {
  187. #ifndef BOOST_OPTIONAL_CONFIG_ALLOW_BINDING_TO_RVALUES
  188.   BOOST_STATIC_ASSERT_MSG(
  189.     !mars_boost::is_lvalue_reference<To>::value || !mars_boost::is_rvalue_reference<From>::value,
  190.     "binding rvalue references to optional lvalue references is disallowed");
  191. #endif    
  192. }
  193.  
  194. struct optional_tag {} ;
  195.  
  196. template<class T>
  197. class optional_base : public optional_tag
  198. {
  199.   private :
  200.  
  201.     typedef
  202. #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
  203.     BOOST_DEDUCED_TYPENAME
  204. #endif
  205.     ::mars_boost::detail::make_reference_content<T>::type internal_type ;
  206.  
  207.     typedef aligned_storage<internal_type> storage_type ;
  208.  
  209.     typedef types_when_isnt_ref<T> types_when_not_ref ;
  210.     typedef types_when_is_ref<T>   types_when_ref   ;
  211.  
  212.     typedef optional_base<T> this_type ;
  213.  
  214.   protected :
  215.  
  216.     typedef T value_type ;
  217.  
  218.     typedef mpl::true_  is_reference_tag ;
  219.     typedef mpl::false_ is_not_reference_tag ;
  220.  
  221.     typedef BOOST_DEDUCED_TYPENAME is_reference<T>::type is_reference_predicate ;
  222.  
  223.   public:
  224.     typedef BOOST_DEDUCED_TYPENAME mpl::if_<is_reference_predicate,types_when_ref,types_when_not_ref>::type types ;
  225.  
  226.   protected:
  227.     typedef BOOST_DEDUCED_TYPENAME types::reference_type       reference_type ;
  228.     typedef BOOST_DEDUCED_TYPENAME types::reference_const_type reference_const_type ;
  229. #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
  230.     typedef BOOST_DEDUCED_TYPENAME types::rval_reference_type  rval_reference_type ;
  231.     typedef BOOST_DEDUCED_TYPENAME types::reference_type_of_temporary_wrapper reference_type_of_temporary_wrapper ;
  232. #endif
  233.     typedef BOOST_DEDUCED_TYPENAME types::pointer_type         pointer_type ;
  234.     typedef BOOST_DEDUCED_TYPENAME types::pointer_const_type   pointer_const_type ;
  235.     typedef BOOST_DEDUCED_TYPENAME types::argument_type        argument_type ;
  236.  
  237.     // Creates an optional<T> uninitialized.
  238.     // No-throw
  239.     optional_base()
  240.       :
  241.       m_initialized(false) {}
  242.  
  243.     // Creates an optional<T> uninitialized.
  244.     // No-throw
  245.     optional_base ( none_t )
  246.       :
  247.       m_initialized(false) {}
  248.  
  249.     // Creates an optional<T> initialized with 'val'.
  250.     // Can throw if T::T(T const&) does
  251.     optional_base ( argument_type val )
  252.       :
  253.       m_initialized(false)
  254.     {
  255.       construct(val);
  256.     }
  257.  
  258. #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
  259.     // move-construct an optional<T> initialized from an rvalue-ref to 'val'.
  260.     // Can throw if T::T(T&&) does
  261.     optional_base ( rval_reference_type val )
  262.       :
  263.       m_initialized(false)
  264.     {
  265.       construct( mars_boost::move(val) );
  266.     }
  267. #endif
  268.  
  269.     // Creates an optional<T> initialized with 'val' IFF cond is true, otherwise creates an uninitialzed optional<T>.
  270.     // Can throw if T::T(T const&) does
  271.     optional_base ( bool cond, argument_type val )
  272.       :
  273.       m_initialized(false)
  274.     {
  275.       if ( cond )
  276.         construct(val);
  277.     }
  278.  
  279.     // Creates a deep copy of another optional<T>
  280.     // Can throw if T::T(T const&) does
  281.     optional_base ( optional_base const& rhs )
  282.       :
  283.       m_initialized(false)
  284.     {
  285.       if ( rhs.is_initialized() )
  286.         construct(rhs.get_impl());
  287.     }
  288.  
  289. #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
  290.     // Creates a deep move of another optional<T>
  291.     // Can throw if T::T(T&&) does
  292.     optional_base ( optional_base&& rhs )
  293.       :
  294.       m_initialized(false)
  295.     {
  296.       if ( rhs.is_initialized() )
  297.         construct( mars_boost::move(rhs.get_impl()) );
  298.     }
  299. #endif
  300.  
  301. #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
  302.  
  303.     template<class Expr, class PtrExpr>
  304.     explicit optional_base ( Expr&& expr, PtrExpr const* tag )
  305.       :
  306.       m_initialized(false)
  307.     {
  308.       construct(mars_boost::forward<Expr>(expr),tag);
  309.     }
  310.  
  311. #else
  312.     // This is used for both converting and in-place constructions.
  313.     // Derived classes use the 'tag' to select the appropriate
  314.     // implementation (the correct 'construct()' overload)
  315.     template<class Expr>
  316.     explicit optional_base ( Expr const& expr, Expr const* tag )
  317.       :
  318.       m_initialized(false)
  319.     {
  320.       construct(expr,tag);
  321.     }
  322.  
  323. #endif
  324.  
  325.  
  326.     // No-throw (assuming T::~T() doesn't)
  327.     ~optional_base() { destroy() ; }
  328.  
  329.     // Assigns from another optional<T> (deep-copies the rhs value)
  330.     void assign ( optional_base const& rhs )
  331.     {
  332.       if (is_initialized())
  333.       {
  334.         if ( rhs.is_initialized() )
  335.              assign_value(rhs.get_impl(), is_reference_predicate() );
  336.         else destroy();
  337.       }
  338.       else
  339.       {
  340.         if ( rhs.is_initialized() )
  341.           construct(rhs.get_impl());
  342.       }
  343.     }
  344.    
  345. #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
  346.     // Assigns from another optional<T> (deep-moves the rhs value)
  347.     void assign ( optional_base&& rhs )
  348.     {
  349.       if (is_initialized())
  350.       {
  351.         if ( rhs.is_initialized() )
  352.              assign_value(mars_boost::move(rhs.get_impl()), is_reference_predicate() );
  353.         else destroy();
  354.       }
  355.       else
  356.       {
  357.         if ( rhs.is_initialized() )
  358.           construct(mars_boost::move(rhs.get_impl()));
  359.       }
  360.     }
  361. #endif
  362.  
  363.     // Assigns from another _convertible_ optional<U> (deep-copies the rhs value)
  364.     template<class U>
  365.     void assign ( optional<U> const& rhs )
  366.     {
  367.       if (is_initialized())
  368.       {
  369.         if ( rhs.is_initialized() )
  370. #ifndef BOOST_OPTIONAL_CONFIG_RESTORE_ASSIGNMENT_OF_NONCONVERTIBLE_TYPES
  371.           assign_value(rhs.get(), is_reference_predicate() );
  372. #else
  373.           assign_value(static_cast<value_type>(rhs.get()), is_reference_predicate() );
  374. #endif
  375.          
  376.         else destroy();
  377.       }
  378.       else
  379.       {
  380.         if ( rhs.is_initialized() )
  381. #ifndef BOOST_OPTIONAL_CONFIG_RESTORE_ASSIGNMENT_OF_NONCONVERTIBLE_TYPES
  382.           construct(rhs.get());
  383. #else
  384.           construct(static_cast<value_type>(rhs.get()));
  385. #endif
  386.       }
  387.     }
  388.  
  389. #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
  390.     // move-assigns from another _convertible_ optional<U> (deep-moves from the rhs value)
  391.     template<class U>
  392.     void assign ( optional<U>&& rhs )
  393.     {
  394.       typedef BOOST_DEDUCED_TYPENAME optional<U>::rval_reference_type ref_type;
  395.       if (is_initialized())
  396.       {
  397.         if ( rhs.is_initialized() )
  398.              assign_value(static_cast<ref_type>(rhs.get()), is_reference_predicate() );
  399.         else destroy();
  400.       }
  401.       else
  402.       {
  403.         if ( rhs.is_initialized() )
  404.           construct(static_cast<ref_type>(rhs.get()));
  405.       }
  406.     }
  407. #endif
  408.    
  409.     // Assigns from a T (deep-copies the rhs value)
  410.     void assign ( argument_type val )
  411.     {
  412.       if (is_initialized())
  413.            assign_value(val, is_reference_predicate() );
  414.       else construct(val);
  415.     }
  416.    
  417. #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
  418.     // Assigns from a T (deep-moves the rhs value)
  419.     void assign ( rval_reference_type val )
  420.     {
  421.       if (is_initialized())
  422.            assign_value( mars_boost::move(val), is_reference_predicate() );
  423.       else construct( mars_boost::move(val) );
  424.     }
  425. #endif
  426.  
  427.     // Assigns from "none", destroying the current value, if any, leaving this UNINITIALIZED
  428.     // No-throw (assuming T::~T() doesn't)
  429.     void assign ( none_t ) BOOST_NOEXCEPT { destroy(); }
  430.  
  431. #ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
  432.  
  433. #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
  434.     template<class Expr, class ExprPtr>
  435.     void assign_expr ( Expr&& expr, ExprPtr const* tag )
  436.     {
  437.       if (is_initialized())
  438.         assign_expr_to_initialized(mars_boost::forward<Expr>(expr),tag);
  439.       else construct(mars_boost::forward<Expr>(expr),tag);
  440.     }
  441. #else
  442.     template<class Expr>
  443.     void assign_expr ( Expr const& expr, Expr const* tag )
  444.     {
  445.       if (is_initialized())
  446.         assign_expr_to_initialized(expr,tag);
  447.       else construct(expr,tag);
  448.     }
  449. #endif
  450.  
  451. #endif
  452.  
  453.   public :
  454.  
  455.     // **DEPPRECATED** Destroys the current value, if any, leaving this UNINITIALIZED
  456.     // No-throw (assuming T::~T() doesn't)
  457.     void reset() BOOST_NOEXCEPT { destroy(); }
  458.  
  459.     // **DEPPRECATED** Replaces the current value -if any- with 'val'
  460.     void reset ( argument_type val ) { assign(val); }
  461.  
  462.     // Returns a pointer to the value if this is initialized, otherwise,
  463.     // returns NULL.
  464.     // No-throw
  465.     pointer_const_type get_ptr() const { return m_initialized ? get_ptr_impl() : 0 ; }
  466.     pointer_type       get_ptr()       { return m_initialized ? get_ptr_impl() : 0 ; }
  467.  
  468.     bool is_initialized() const { return m_initialized ; }
  469.  
  470.   protected :
  471.  
  472.     void construct ( argument_type val )
  473.      {
  474.        ::new (m_storage.address()) internal_type(val) ;
  475.        m_initialized = true ;
  476.      }
  477.      
  478. #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
  479.     void construct ( rval_reference_type val )
  480.      {
  481.        ::new (m_storage.address()) internal_type( types::move(val) ) ;
  482.        m_initialized = true ;
  483.      }
  484. #endif
  485.  
  486.  
  487. #if (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) && (!defined BOOST_NO_CXX11_VARIADIC_TEMPLATES)
  488.     // Constructs in-place
  489.     // upon exception *this is always uninitialized
  490.     template<class... Args>
  491.     void emplace_assign ( Args&&... args )
  492.      {
  493.        destroy();
  494.        ::new (m_storage.address()) internal_type( mars_boost::forward<Args>(args)... );
  495.        m_initialized = true ;
  496.      }
  497. #elif (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
  498.     template<class Arg>
  499.     void emplace_assign ( Arg&& arg )
  500.      {
  501.        destroy();
  502.        ::new (m_storage.address()) internal_type( mars_boost::forward<Arg>(arg) );
  503.        m_initialized = true ;
  504.      }
  505.      
  506.     void emplace_assign ()
  507.      {
  508.        destroy();
  509.        ::new (m_storage.address()) internal_type();
  510.        m_initialized = true ;
  511.      }
  512. #else
  513.     template<class Arg>
  514.     void emplace_assign ( const Arg& arg )
  515.      {
  516.        destroy();
  517.        ::new (m_storage.address()) internal_type( arg );
  518.        m_initialized = true ;
  519.      }
  520.      
  521.     template<class Arg>
  522.     void emplace_assign ( Arg& arg )
  523.      {
  524.        destroy();
  525.        ::new (m_storage.address()) internal_type( arg );
  526.        m_initialized = true ;
  527.      }
  528.      
  529.     void emplace_assign ()
  530.      {
  531.        destroy();
  532.        ::new (m_storage.address()) internal_type();
  533.        m_initialized = true ;
  534.      }
  535. #endif
  536.  
  537. #ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
  538.  
  539. #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
  540.     // Constructs in-place using the given factory
  541.     template<class Expr>
  542.     void construct ( Expr&& factory, in_place_factory_base const* )
  543.      {
  544.        BOOST_STATIC_ASSERT ( ::mars_boost::mpl::not_<is_reference_predicate>::value ) ;
  545.        mars_boost_optional_detail::construct<value_type>(factory, m_storage.address());
  546.        m_initialized = true ;
  547.      }
  548.  
  549.     // Constructs in-place using the given typed factory
  550.     template<class Expr>
  551.     void construct ( Expr&& factory, typed_in_place_factory_base const* )
  552.      {
  553.        BOOST_STATIC_ASSERT ( ::mars_boost::mpl::not_<is_reference_predicate>::value ) ;
  554.        factory.apply(m_storage.address()) ;
  555.        m_initialized = true ;
  556.      }
  557.  
  558.     template<class Expr>
  559.     void assign_expr_to_initialized ( Expr&& factory, in_place_factory_base const* tag )
  560.      {
  561.        destroy();
  562.        construct(factory,tag);
  563.      }
  564.  
  565.     // Constructs in-place using the given typed factory
  566.     template<class Expr>
  567.     void assign_expr_to_initialized ( Expr&& factory, typed_in_place_factory_base const* tag )
  568.      {
  569.        destroy();
  570.        construct(factory,tag);
  571.      }
  572.  
  573. #else
  574.     // Constructs in-place using the given factory
  575.     template<class Expr>
  576.     void construct ( Expr const& factory, in_place_factory_base const* )
  577.      {
  578.        BOOST_STATIC_ASSERT ( ::mars_boost::mpl::not_<is_reference_predicate>::value ) ;
  579.        mars_boost_optional_detail::construct<value_type>(factory, m_storage.address());
  580.        m_initialized = true ;
  581.      }
  582.  
  583.     // Constructs in-place using the given typed factory
  584.     template<class Expr>
  585.     void construct ( Expr const& factory, typed_in_place_factory_base const* )
  586.      {
  587.        BOOST_STATIC_ASSERT ( ::mars_boost::mpl::not_<is_reference_predicate>::value ) ;
  588.        factory.apply(m_storage.address()) ;
  589.        m_initialized = true ;
  590.      }
  591.  
  592.     template<class Expr>
  593.     void assign_expr_to_initialized ( Expr const& factory, in_place_factory_base const* tag )
  594.      {
  595.        destroy();
  596.        construct(factory,tag);
  597.      }
  598.  
  599.     // Constructs in-place using the given typed factory
  600.     template<class Expr>
  601.     void assign_expr_to_initialized ( Expr const& factory, typed_in_place_factory_base const* tag )
  602.      {
  603.        destroy();
  604.        construct(factory,tag);
  605.      }
  606. #endif
  607.  
  608. #endif
  609.  
  610. #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
  611.     // Constructs using any expression implicitly convertible to the single argument
  612.     // of a one-argument T constructor.
  613.     // Converting constructions of optional<T> from optional<U> uses this function with
  614.     // 'Expr' being of type 'U' and relying on a converting constructor of T from U.
  615.     template<class Expr>
  616.     void construct ( Expr&& expr, void const* )
  617.     {
  618.       new (m_storage.address()) internal_type(mars_boost::forward<Expr>(expr)) ;
  619.       m_initialized = true ;
  620.     }
  621.  
  622.     // Assigns using a form any expression implicitly convertible to the single argument
  623.     // of a T's assignment operator.
  624.     // Converting assignments of optional<T> from optional<U> uses this function with
  625.     // 'Expr' being of type 'U' and relying on a converting assignment of T from U.
  626.     template<class Expr>
  627.     void assign_expr_to_initialized ( Expr&& expr, void const* )
  628.     {
  629.       assign_value(mars_boost::forward<Expr>(expr), is_reference_predicate());
  630.     }
  631. #else
  632.     // Constructs using any expression implicitly convertible to the single argument
  633.     // of a one-argument T constructor.
  634.     // Converting constructions of optional<T> from optional<U> uses this function with
  635.     // 'Expr' being of type 'U' and relying on a converting constructor of T from U.
  636.     template<class Expr>
  637.     void construct ( Expr const& expr, void const* )
  638.      {
  639.        new (m_storage.address()) internal_type(expr) ;
  640.        m_initialized = true ;
  641.      }
  642.  
  643.     // Assigns using a form any expression implicitly convertible to the single argument
  644.     // of a T's assignment operator.
  645.     // Converting assignments of optional<T> from optional<U> uses this function with
  646.     // 'Expr' being of type 'U' and relying on a converting assignment of T from U.
  647.     template<class Expr>
  648.     void assign_expr_to_initialized ( Expr const& expr, void const* )
  649.      {
  650.        assign_value(expr, is_reference_predicate());
  651.      }
  652.  
  653. #endif
  654.  
  655. #ifdef BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION
  656.     // BCB5.64 (and probably lower versions) workaround.
  657.     //   The in-place factories are supported by means of catch-all constructors
  658.     //   and assignment operators (the functions are parameterized in terms of
  659.     //   an arbitrary 'Expr' type)
  660.     //   This compiler incorrectly resolves the overload set and sinks optional<T> and optional<U>
  661.     //   to the 'Expr'-taking functions even though explicit overloads are present for them.
  662.     //   Thus, the following overload is needed to properly handle the case when the 'lhs'
  663.     //   is another optional.
  664.     //
  665.     // For VC<=70 compilers this workaround dosen't work becasue the comnpiler issues and error
  666.     // instead of choosing the wrong overload
  667.     //
  668. #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
  669.     // Notice that 'Expr' will be optional<T> or optional<U> (but not optional_base<..>)
  670.     template<class Expr>
  671.     void construct ( Expr&& expr, optional_tag const* )
  672.      {
  673.        if ( expr.is_initialized() )
  674.        {
  675.          // An exception can be thrown here.
  676.          // It it happens, THIS will be left uninitialized.
  677.          new (m_storage.address()) internal_type(types::move(expr.get())) ;
  678.          m_initialized = true ;
  679.        }
  680.      }
  681. #else
  682.     // Notice that 'Expr' will be optional<T> or optional<U> (but not optional_base<..>)
  683.     template<class Expr>
  684.     void construct ( Expr const& expr, optional_tag const* )
  685.      {
  686.        if ( expr.is_initialized() )
  687.        {
  688.          // An exception can be thrown here.
  689.          // It it happens, THIS will be left uninitialized.
  690.          new (m_storage.address()) internal_type(expr.get()) ;
  691.          m_initialized = true ;
  692.        }
  693.      }
  694. #endif
  695. #endif // defined BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION
  696.  
  697.     void assign_value ( argument_type val, is_not_reference_tag ) { get_impl() = val; }
  698.     void assign_value ( argument_type val, is_reference_tag     ) { construct(val); }
  699. #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
  700.     void assign_value ( rval_reference_type val, is_not_reference_tag ) { get_impl() = static_cast<rval_reference_type>(val); }
  701.     void assign_value ( rval_reference_type val, is_reference_tag     ) { construct( static_cast<rval_reference_type>(val) ); }
  702. #endif
  703.  
  704.     void destroy()
  705.     {
  706.       if ( m_initialized )
  707.         destroy_impl(is_reference_predicate()) ;
  708.     }
  709.  
  710.     reference_const_type get_impl() const { return dereference(get_object(), is_reference_predicate() ) ; }
  711.     reference_type       get_impl()       { return dereference(get_object(), is_reference_predicate() ) ; }
  712.  
  713.     pointer_const_type get_ptr_impl() const { return cast_ptr(get_object(), is_reference_predicate() ) ; }
  714.     pointer_type       get_ptr_impl()       { return cast_ptr(get_object(), is_reference_predicate() ) ; }
  715.  
  716.   private :
  717.  
  718.     // internal_type can be either T or reference_content<T>
  719. #if defined(BOOST_OPTIONAL_DETAIL_USE_ATTRIBUTE_MAY_ALIAS)
  720.     // This workaround is supposed to silence GCC warnings about broken strict aliasing rules
  721.     internal_type const* get_object() const
  722.     {
  723.         union { void const* ap_pvoid; internal_type const* as_ptype; } caster = { m_storage.address() };
  724.         return caster.as_ptype;
  725.     }
  726.     internal_type *      get_object()
  727.     {
  728.         union { void* ap_pvoid; internal_type* as_ptype; } caster = { m_storage.address() };
  729.         return caster.as_ptype;
  730.     }
  731. #else
  732.     internal_type const* get_object() const { return static_cast<internal_type const*>(m_storage.address()); }
  733.     internal_type *      get_object()       { return static_cast<internal_type *>     (m_storage.address()); }
  734. #endif
  735.  
  736.     // reference_content<T> lacks an implicit conversion to T&, so the following is needed to obtain a proper reference.
  737.     reference_const_type dereference( internal_type const* p, is_not_reference_tag ) const { return *p ; }
  738.     reference_type       dereference( internal_type*       p, is_not_reference_tag )       { return *p ; }
  739.     reference_const_type dereference( internal_type const* p, is_reference_tag     ) const { return p->get() ; }
  740.     reference_type       dereference( internal_type*       p, is_reference_tag     )       { return p->get() ; }
  741.  
  742. #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581))
  743.     void destroy_impl ( is_not_reference_tag ) { get_ptr_impl()->internal_type::~internal_type() ; m_initialized = false ; }
  744. #else
  745.     void destroy_impl ( is_not_reference_tag ) { get_ptr_impl()->~T() ; m_initialized = false ; }
  746. #endif
  747.  
  748.     void destroy_impl ( is_reference_tag     ) { m_initialized = false ; }
  749.  
  750.     // If T is of reference type, trying to get a pointer to the held value must result in a compile-time error.
  751.     // Decent compilers should disallow conversions from reference_content<T>* to T*, but just in case,
  752.     // the following olverloads are used to filter out the case and guarantee an error in case of T being a reference.
  753.     pointer_const_type cast_ptr( internal_type const* p, is_not_reference_tag ) const { return p ; }
  754.     pointer_type       cast_ptr( internal_type *      p, is_not_reference_tag )       { return p ; }
  755.     pointer_const_type cast_ptr( internal_type const* p, is_reference_tag     ) const { return &p->get() ; }
  756.     pointer_type       cast_ptr( internal_type *      p, is_reference_tag     )       { return &p->get() ; }
  757.  
  758.     bool m_initialized ;
  759.     storage_type m_storage ;
  760. } ;
  761.  
  762. } // namespace optional_detail
  763.  
  764. template<class T>
  765. class optional : public optional_detail::optional_base<T>
  766. {
  767.     typedef optional_detail::optional_base<T> base ;
  768.  
  769.   public :
  770.  
  771.     typedef optional<T> this_type ;
  772.  
  773.     typedef BOOST_DEDUCED_TYPENAME base::value_type           value_type ;
  774.     typedef BOOST_DEDUCED_TYPENAME base::reference_type       reference_type ;
  775.     typedef BOOST_DEDUCED_TYPENAME base::reference_const_type reference_const_type ;
  776. #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
  777.     typedef BOOST_DEDUCED_TYPENAME base::rval_reference_type  rval_reference_type ;
  778.     typedef BOOST_DEDUCED_TYPENAME base::reference_type_of_temporary_wrapper reference_type_of_temporary_wrapper ;
  779. #endif
  780.     typedef BOOST_DEDUCED_TYPENAME base::pointer_type         pointer_type ;
  781.     typedef BOOST_DEDUCED_TYPENAME base::pointer_const_type   pointer_const_type ;
  782.     typedef BOOST_DEDUCED_TYPENAME base::argument_type        argument_type ;
  783.  
  784.     // Creates an optional<T> uninitialized.
  785.     // No-throw
  786.     optional() BOOST_NOEXCEPT : base() {}
  787.  
  788.     // Creates an optional<T> uninitialized.
  789.     // No-throw
  790.     optional( none_t none_ ) BOOST_NOEXCEPT : base(none_) {}
  791.  
  792.     // Creates an optional<T> initialized with 'val'.
  793.     // Can throw if T::T(T const&) does
  794.     optional ( argument_type val ) : base(val) {}
  795.  
  796. #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
  797.     // Creates an optional<T> initialized with 'move(val)'.
  798.     // Can throw if T::T(T &&) does
  799.     optional ( rval_reference_type val ) : base( mars_boost::forward<T>(val) )
  800.       {optional_detail::prevent_binding_rvalue_ref_to_optional_lvalue_ref<T, rval_reference_type>();}
  801. #endif
  802.  
  803.     // Creates an optional<T> initialized with 'val' IFF cond is true, otherwise creates an uninitialized optional.
  804.     // Can throw if T::T(T const&) does
  805.     optional ( bool cond, argument_type val ) : base(cond,val) {}
  806.  
  807.     // NOTE: MSVC needs templated versions first
  808.  
  809.     // Creates a deep copy of another convertible optional<U>
  810.     // Requires a valid conversion from U to T.
  811.     // Can throw if T::T(U const&) does
  812.     template<class U>
  813.     explicit optional ( optional<U> const& rhs )
  814.       :
  815.       base()
  816.     {
  817.       if ( rhs.is_initialized() )
  818.         this->construct(rhs.get());
  819.     }
  820.    
  821. #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
  822.     // Creates a deep move of another convertible optional<U>
  823.     // Requires a valid conversion from U to T.
  824.     // Can throw if T::T(U&&) does
  825.     template<class U>
  826.     explicit optional ( optional<U> && rhs )
  827.       :
  828.       base()
  829.     {
  830.       if ( rhs.is_initialized() )
  831.         this->construct( mars_boost::move(rhs.get()) );
  832.     }
  833. #endif
  834.  
  835. #ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
  836.     // Creates an optional<T> with an expression which can be either
  837.     //  (a) An instance of InPlaceFactory (i.e. in_place(a,b,...,n);
  838.     //  (b) An instance of TypedInPlaceFactory ( i.e. in_place<T>(a,b,...,n);
  839.     //  (c) Any expression implicitly convertible to the single type
  840.     //      of a one-argument T's constructor.
  841.     //  (d*) Weak compilers (BCB) might also resolved Expr as optional<T> and optional<U>
  842.     //       even though explicit overloads are present for these.
  843.     // Depending on the above some T ctor is called.
  844.     // Can throw if the resolved T ctor throws.
  845. #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
  846.  
  847.  
  848.   template<class Expr>
  849.   explicit optional ( Expr&& expr,
  850.                       BOOST_DEDUCED_TYPENAME mars_boost::disable_if_c<
  851.                         (mars_boost::is_base_of<optional_detail::optional_tag, BOOST_DEDUCED_TYPENAME mars_boost::decay<Expr>::type>::value) ||
  852.                         mars_boost::is_same<BOOST_DEDUCED_TYPENAME mars_boost::decay<Expr>::type, none_t>::value >::type* = 0
  853.   )
  854.     : base(mars_boost::forward<Expr>(expr),mars_boost::addressof(expr))
  855.     {optional_detail::prevent_binding_rvalue_ref_to_optional_lvalue_ref<T, Expr&&>();}
  856.  
  857. #else
  858.     template<class Expr>
  859.     explicit optional ( Expr const& expr ) : base(expr,mars_boost::addressof(expr)) {}
  860. #endif // !defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
  861. #endif // !defined BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
  862.  
  863.     // Creates a deep copy of another optional<T>
  864.     // Can throw if T::T(T const&) does
  865.     optional ( optional const& rhs ) : base( static_cast<base const&>(rhs) ) {}
  866.  
  867. #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
  868.         // Creates a deep move of another optional<T>
  869.         // Can throw if T::T(T&&) does
  870.         optional ( optional && rhs )
  871.           BOOST_NOEXCEPT_IF(::mars_boost::is_nothrow_move_constructible<T>::value)
  872.           : base( mars_boost::move(rhs) )
  873.         {}
  874.  
  875. #endif
  876.    // No-throw (assuming T::~T() doesn't)
  877.     ~optional() {}
  878.  
  879. #if !defined(BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT) && !defined(BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION)
  880.     // Assigns from an expression. See corresponding constructor.
  881.     // Basic Guarantee: If the resolved T ctor throws, this is left UNINITIALIZED
  882. #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
  883.  
  884.     template<class Expr>
  885.     BOOST_DEDUCED_TYPENAME mars_boost::disable_if_c<
  886.       mars_boost::is_base_of<optional_detail::optional_tag, BOOST_DEDUCED_TYPENAME mars_boost::decay<Expr>::type>::value ||
  887.         mars_boost::is_same<BOOST_DEDUCED_TYPENAME mars_boost::decay<Expr>::type, none_t>::value,
  888.       optional&
  889.     >::type
  890.     operator= ( Expr&& expr )
  891.       {
  892.         optional_detail::prevent_binding_rvalue_ref_to_optional_lvalue_ref<T, Expr&&>();
  893.         this->assign_expr(mars_boost::forward<Expr>(expr),mars_boost::addressof(expr));
  894.         return *this ;
  895.       }
  896.  
  897. #else
  898.     template<class Expr>
  899.     optional& operator= ( Expr const& expr )
  900.       {
  901.         this->assign_expr(expr,mars_boost::addressof(expr));
  902.         return *this ;
  903.       }
  904. #endif // !defined  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
  905. #endif // !defined(BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT) && !defined(BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION)
  906.  
  907.     // Copy-assigns from another convertible optional<U> (converts && deep-copies the rhs value)
  908.     // Requires a valid conversion from U to T.
  909.     // Basic Guarantee: If T::T( U const& ) throws, this is left UNINITIALIZED
  910.     template<class U>
  911.     optional& operator= ( optional<U> const& rhs )
  912.       {
  913.         this->assign(rhs);
  914.         return *this ;
  915.       }
  916.      
  917. #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
  918.     // Move-assigns from another convertible optional<U> (converts && deep-moves the rhs value)
  919.     // Requires a valid conversion from U to T.
  920.     // Basic Guarantee: If T::T( U && ) throws, this is left UNINITIALIZED
  921.     template<class U>
  922.     optional& operator= ( optional<U> && rhs )
  923.       {
  924.         this->assign(mars_boost::move(rhs));
  925.         return *this ;
  926.       }
  927. #endif
  928.  
  929.     // Assigns from another optional<T> (deep-copies the rhs value)
  930.     // Basic Guarantee: If T::T( T const& ) throws, this is left UNINITIALIZED
  931.     //  (NOTE: On BCB, this operator is not actually called and left is left UNMODIFIED in case of a throw)
  932.     optional& operator= ( optional const& rhs )
  933.       {
  934.         this->assign( static_cast<base const&>(rhs) ) ;
  935.         return *this ;
  936.       }
  937.  
  938. #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
  939.     // Assigns from another optional<T> (deep-moves the rhs value)
  940.     optional& operator= ( optional && rhs )
  941.           BOOST_NOEXCEPT_IF(::mars_boost::is_nothrow_move_constructible<T>::value && ::mars_boost::is_nothrow_move_assignable<T>::value)
  942.       {
  943.         this->assign( static_cast<base &&>(rhs) ) ;
  944.         return *this ;
  945.       }
  946. #endif
  947.  
  948.     // Assigns from a T (deep-copies the rhs value)
  949.     // Basic Guarantee: If T::( T const& ) throws, this is left UNINITIALIZED
  950.     optional& operator= ( argument_type val )
  951.       {
  952.         this->assign( val ) ;
  953.         return *this ;
  954.       }
  955.  
  956. #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
  957.     // Assigns from a T (deep-moves the rhs value)
  958.     optional& operator= ( rval_reference_type val )
  959.       {
  960.         optional_detail::prevent_binding_rvalue_ref_to_optional_lvalue_ref<T, rval_reference_type>();
  961.         this->assign( mars_boost::move(val) ) ;
  962.         return *this ;
  963.       }
  964. #endif
  965.  
  966.     // Assigns from a "none"
  967.     // Which destroys the current value, if any, leaving this UNINITIALIZED
  968.     // No-throw (assuming T::~T() doesn't)
  969.     optional& operator= ( none_t none_ ) BOOST_NOEXCEPT
  970.       {
  971.         this->assign( none_ ) ;
  972.         return *this ;
  973.       }
  974.      
  975. #if (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) && (!defined BOOST_NO_CXX11_VARIADIC_TEMPLATES)
  976.     // Constructs in-place
  977.     // upon exception *this is always uninitialized
  978.     template<class... Args>
  979.     void emplace ( Args&&... args )
  980.      {
  981.        this->emplace_assign( mars_boost::forward<Args>(args)... );
  982.      }
  983. #elif (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
  984.     template<class Arg>
  985.     void emplace ( Arg&& arg )
  986.      {
  987.        this->emplace_assign( mars_boost::forward<Arg>(arg) );
  988.      }
  989.      
  990.     void emplace ()
  991.      {
  992.        this->emplace_assign();
  993.      }
  994. #else
  995.     template<class Arg>
  996.     void emplace ( const Arg& arg )
  997.      {
  998.        this->emplace_assign( arg );
  999.      }
  1000.      
  1001.     template<class Arg>
  1002.     void emplace ( Arg& arg )
  1003.      {
  1004.        this->emplace_assign( arg );
  1005.      }
  1006.      
  1007.     void emplace ()
  1008.      {
  1009.        this->emplace_assign();
  1010.      }
  1011. #endif
  1012.  
  1013.     void swap( optional & arg )
  1014.           BOOST_NOEXCEPT_IF(::mars_boost::is_nothrow_move_constructible<T>::value && ::mars_boost::is_nothrow_move_assignable<T>::value)
  1015.       {
  1016.         // allow for Koenig lookup
  1017.         mars_boost::swap(*this, arg);
  1018.       }
  1019.  
  1020.  
  1021.     // Returns a reference to the value if this is initialized, otherwise,
  1022.     // the behaviour is UNDEFINED
  1023.     // No-throw
  1024.     reference_const_type get() const { BOOST_ASSERT(this->is_initialized()) ; return this->get_impl(); }
  1025.     reference_type       get()       { BOOST_ASSERT(this->is_initialized()) ; return this->get_impl(); }
  1026.  
  1027.     // Returns a copy of the value if this is initialized, 'v' otherwise
  1028.     reference_const_type get_value_or ( reference_const_type v ) const { return this->is_initialized() ? get() : v ; }
  1029.     reference_type       get_value_or ( reference_type       v )       { return this->is_initialized() ? get() : v ; }
  1030.  
  1031.     // Returns a pointer to the value if this is initialized, otherwise,
  1032.     // the behaviour is UNDEFINED
  1033.     // No-throw
  1034.     pointer_const_type operator->() const { BOOST_ASSERT(this->is_initialized()) ; return this->get_ptr_impl() ; }
  1035.     pointer_type       operator->()       { BOOST_ASSERT(this->is_initialized()) ; return this->get_ptr_impl() ; }
  1036.  
  1037.     // Returns a reference to the value if this is initialized, otherwise,
  1038.     // the behaviour is UNDEFINED
  1039.     // No-throw
  1040. #if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
  1041.     reference_const_type operator *() const& { return this->get() ; }
  1042.     reference_type       operator *() &      { return this->get() ; }
  1043.     reference_type_of_temporary_wrapper operator *() && { return base::types::move(this->get()) ; }
  1044. #else
  1045.     reference_const_type operator *() const { return this->get() ; }
  1046.     reference_type       operator *()       { return this->get() ; }
  1047. #endif // !defined BOOST_NO_CXX11_REF_QUALIFIERS
  1048.  
  1049. #if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
  1050.     reference_const_type value() const&
  1051.       {
  1052.         if (this->is_initialized())
  1053.           return this->get() ;
  1054.         else
  1055.           throw_exception(bad_optional_access());
  1056.       }
  1057.      
  1058.     reference_type value() &
  1059.       {
  1060.         if (this->is_initialized())
  1061.           return this->get() ;
  1062.         else
  1063.           throw_exception(bad_optional_access());
  1064.       }
  1065.      
  1066.     reference_type_of_temporary_wrapper value() &&
  1067.       {
  1068.         if (this->is_initialized())
  1069.           return base::types::move(this->get()) ;
  1070.         else
  1071.           throw_exception(bad_optional_access());
  1072.       }
  1073.  
  1074. #else
  1075.     reference_const_type value() const
  1076.       {
  1077.         if (this->is_initialized())
  1078.           return this->get() ;
  1079.         else
  1080.           throw_exception(bad_optional_access());
  1081.       }
  1082.      
  1083.     reference_type value()
  1084.       {
  1085.         if (this->is_initialized())
  1086.           return this->get() ;
  1087.         else
  1088.           throw_exception(bad_optional_access());
  1089.       }
  1090. #endif
  1091.  
  1092.  
  1093. #ifndef BOOST_NO_CXX11_REF_QUALIFIERS
  1094.     template <class U>
  1095.     value_type value_or ( U&& v ) const&
  1096.       {
  1097.         if (this->is_initialized())
  1098.           return get();
  1099.         else
  1100.           return mars_boost::forward<U>(v);
  1101.       }
  1102.    
  1103.     template <class U>
  1104.     value_type value_or ( U&& v ) &&
  1105.       {
  1106.         if (this->is_initialized())
  1107.           return base::types::move(get());
  1108.         else
  1109.           return mars_boost::forward<U>(v);
  1110.       }
  1111. #elif !defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
  1112.     template <class U>
  1113.     value_type value_or ( U&& v ) const
  1114.       {
  1115.         if (this->is_initialized())
  1116.           return get();
  1117.         else
  1118.           return mars_boost::forward<U>(v);
  1119.       }
  1120. #else
  1121.     template <class U>
  1122.     value_type value_or ( U const& v ) const
  1123.       {
  1124.         if (this->is_initialized())
  1125.           return get();
  1126.         else
  1127.           return v;
  1128.       }
  1129.      
  1130.     template <class U>
  1131.     value_type value_or ( U& v ) const
  1132.       {
  1133.         if (this->is_initialized())
  1134.           return get();
  1135.         else
  1136.           return v;
  1137.       }
  1138. #endif
  1139.  
  1140.  
  1141. #ifndef BOOST_NO_CXX11_REF_QUALIFIERS
  1142.     template <typename F>
  1143.     value_type value_or_eval ( F f ) const&
  1144.       {
  1145.         if (this->is_initialized())
  1146.           return get();
  1147.         else
  1148.           return f();
  1149.       }
  1150.      
  1151.     template <typename F>
  1152.     value_type value_or_eval ( F f ) &&
  1153.       {
  1154.         if (this->is_initialized())
  1155.           return base::types::move(get());
  1156.         else
  1157.           return f();
  1158.       }
  1159. #else
  1160.     template <typename F>
  1161.     value_type value_or_eval ( F f ) const
  1162.       {
  1163.         if (this->is_initialized())
  1164.           return get();
  1165.         else
  1166.           return f();
  1167.       }
  1168. #endif
  1169.      
  1170.     bool operator!() const BOOST_NOEXCEPT { return !this->is_initialized() ; }
  1171.    
  1172.     BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
  1173. } ;
  1174.  
  1175. #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
  1176. template<class T>
  1177. class optional<T&&>
  1178. {
  1179.   BOOST_STATIC_ASSERT_MSG(sizeof(T) == 0, "Optional rvalue references are illegal.");
  1180. } ;
  1181. #endif
  1182.  
  1183. // Returns optional<T>(v)
  1184. template<class T>
  1185. inline
  1186. optional<T> make_optional ( T const& v  )
  1187. {
  1188.   return optional<T>(v);
  1189. }
  1190.  
  1191. // Returns optional<T>(cond,v)
  1192. template<class T>
  1193. inline
  1194. optional<T> make_optional ( bool cond, T const& v )
  1195. {
  1196.   return optional<T>(cond,v);
  1197. }
  1198.  
  1199. // Returns a reference to the value if this is initialized, otherwise, the behaviour is UNDEFINED.
  1200. // No-throw
  1201. template<class T>
  1202. inline
  1203. BOOST_DEDUCED_TYPENAME optional<T>::reference_const_type
  1204. get ( optional<T> const& opt )
  1205. {
  1206.   return opt.get() ;
  1207. }
  1208.  
  1209. template<class T>
  1210. inline
  1211. BOOST_DEDUCED_TYPENAME optional<T>::reference_type
  1212. get ( optional<T>& opt )
  1213. {
  1214.   return opt.get() ;
  1215. }
  1216.  
  1217. // Returns a pointer to the value if this is initialized, otherwise, returns NULL.
  1218. // No-throw
  1219. template<class T>
  1220. inline
  1221. BOOST_DEDUCED_TYPENAME optional<T>::pointer_const_type
  1222. get ( optional<T> const* opt )
  1223. {
  1224.   return opt->get_ptr() ;
  1225. }
  1226.  
  1227. template<class T>
  1228. inline
  1229. BOOST_DEDUCED_TYPENAME optional<T>::pointer_type
  1230. get ( optional<T>* opt )
  1231. {
  1232.   return opt->get_ptr() ;
  1233. }
  1234.  
  1235. // Returns a reference to the value if this is initialized, otherwise, the behaviour is UNDEFINED.
  1236. // No-throw
  1237. template<class T>
  1238. inline
  1239. BOOST_DEDUCED_TYPENAME optional<T>::reference_const_type
  1240. get_optional_value_or ( optional<T> const& opt, BOOST_DEDUCED_TYPENAME optional<T>::reference_const_type v )
  1241. {
  1242.   return opt.get_value_or(v) ;
  1243. }
  1244.  
  1245. template<class T>
  1246. inline
  1247. BOOST_DEDUCED_TYPENAME optional<T>::reference_type
  1248. get_optional_value_or ( optional<T>& opt, BOOST_DEDUCED_TYPENAME optional<T>::reference_type v )
  1249. {
  1250.   return opt.get_value_or(v) ;
  1251. }
  1252.  
  1253. // Returns a pointer to the value if this is initialized, otherwise, returns NULL.
  1254. // No-throw
  1255. template<class T>
  1256. inline
  1257. BOOST_DEDUCED_TYPENAME optional<T>::pointer_const_type
  1258. get_pointer ( optional<T> const& opt )
  1259. {
  1260.   return opt.get_ptr() ;
  1261. }
  1262.  
  1263. template<class T>
  1264. inline
  1265. BOOST_DEDUCED_TYPENAME optional<T>::pointer_type
  1266. get_pointer ( optional<T>& opt )
  1267. {
  1268.   return opt.get_ptr() ;
  1269. }
  1270.  
  1271. // The following declaration prevents a bug where operator safe-bool is used upon streaming optional object if you forget the IO header.
  1272. template<class CharType, class CharTrait>
  1273. std::basic_ostream<CharType, CharTrait>&
  1274. operator<<(std::basic_ostream<CharType, CharTrait>& os, optional_detail::optional_tag const&)
  1275. {
  1276.   BOOST_STATIC_ASSERT_MSG(sizeof(CharType) == 0, "If you want to output mars_boost::optional, include header <boost/optional/optional_io.hpp>");
  1277.   return os;  
  1278. }
  1279.  
  1280. // optional's relational operators ( ==, !=, <, >, <=, >= ) have deep-semantics (compare values).
  1281. // WARNING: This is UNLIKE pointers. Use equal_pointees()/less_pointess() in generic code instead.
  1282.  
  1283.  
  1284. //
  1285. // optional<T> vs optional<T> cases
  1286. //
  1287.  
  1288. template<class T>
  1289. inline
  1290. bool operator == ( optional<T> const& x, optional<T> const& y )
  1291. { return equal_pointees(x,y); }
  1292.  
  1293. template<class T>
  1294. inline
  1295. bool operator < ( optional<T> const& x, optional<T> const& y )
  1296. { return less_pointees(x,y); }
  1297.  
  1298. template<class T>
  1299. inline
  1300. bool operator != ( optional<T> const& x, optional<T> const& y )
  1301. { return !( x == y ) ; }
  1302.  
  1303. template<class T>
  1304. inline
  1305. bool operator > ( optional<T> const& x, optional<T> const& y )
  1306. { return y < x ; }
  1307.  
  1308. template<class T>
  1309. inline
  1310. bool operator <= ( optional<T> const& x, optional<T> const& y )
  1311. { return !( y < x ) ; }
  1312.  
  1313. template<class T>
  1314. inline
  1315. bool operator >= ( optional<T> const& x, optional<T> const& y )
  1316. { return !( x < y ) ; }
  1317.  
  1318.  
  1319. //
  1320. // optional<T> vs T cases
  1321. //
  1322. template<class T>
  1323. inline
  1324. bool operator == ( optional<T> const& x, T const& y )
  1325. { return equal_pointees(x, optional<T>(y)); }
  1326.  
  1327. template<class T>
  1328. inline
  1329. bool operator < ( optional<T> const& x, T const& y )
  1330. { return less_pointees(x, optional<T>(y)); }
  1331.  
  1332. template<class T>
  1333. inline
  1334. bool operator != ( optional<T> const& x, T const& y )
  1335. { return !( x == y ) ; }
  1336.  
  1337. template<class T>
  1338. inline
  1339. bool operator > ( optional<T> const& x, T const& y )
  1340. { return y < x ; }
  1341.  
  1342. template<class T>
  1343. inline
  1344. bool operator <= ( optional<T> const& x, T const& y )
  1345. { return !( y < x ) ; }
  1346.  
  1347. template<class T>
  1348. inline
  1349. bool operator >= ( optional<T> const& x, T const& y )
  1350. { return !( x < y ) ; }
  1351.  
  1352. //
  1353. // T vs optional<T> cases
  1354. //
  1355.  
  1356. template<class T>
  1357. inline
  1358. bool operator == ( T const& x, optional<T> const& y )
  1359. { return equal_pointees( optional<T>(x), y ); }
  1360.  
  1361. template<class T>
  1362. inline
  1363. bool operator < ( T const& x, optional<T> const& y )
  1364. { return less_pointees( optional<T>(x), y ); }
  1365.  
  1366. template<class T>
  1367. inline
  1368. bool operator != ( T const& x, optional<T> const& y )
  1369. { return !( x == y ) ; }
  1370.  
  1371. template<class T>
  1372. inline
  1373. bool operator > ( T const& x, optional<T> const& y )
  1374. { return y < x ; }
  1375.  
  1376. template<class T>
  1377. inline
  1378. bool operator <= ( T const& x, optional<T> const& y )
  1379. { return !( y < x ) ; }
  1380.  
  1381. template<class T>
  1382. inline
  1383. bool operator >= ( T const& x, optional<T> const& y )
  1384. { return !( x < y ) ; }
  1385.  
  1386.  
  1387. //
  1388. // optional<T> vs none cases
  1389. //
  1390.  
  1391. template<class T>
  1392. inline
  1393. bool operator == ( optional<T> const& x, none_t ) BOOST_NOEXCEPT
  1394. { return !x; }
  1395.  
  1396. template<class T>
  1397. inline
  1398. bool operator < ( optional<T> const& x, none_t )
  1399. { return less_pointees(x,optional<T>() ); }
  1400.  
  1401. template<class T>
  1402. inline
  1403. bool operator != ( optional<T> const& x, none_t ) BOOST_NOEXCEPT
  1404. { return bool(x); }
  1405.  
  1406. template<class T>
  1407. inline
  1408. bool operator > ( optional<T> const& x, none_t y )
  1409. { return y < x ; }
  1410.  
  1411. template<class T>
  1412. inline
  1413. bool operator <= ( optional<T> const& x, none_t y )
  1414. { return !( y < x ) ; }
  1415.  
  1416. template<class T>
  1417. inline
  1418. bool operator >= ( optional<T> const& x, none_t y )
  1419. { return !( x < y ) ; }
  1420.  
  1421. //
  1422. // none vs optional<T> cases
  1423. //
  1424.  
  1425. template<class T>
  1426. inline
  1427. bool operator == ( none_t , optional<T> const& y ) BOOST_NOEXCEPT
  1428. { return !y; }
  1429.  
  1430. template<class T>
  1431. inline
  1432. bool operator < ( none_t , optional<T> const& y )
  1433. { return less_pointees(optional<T>() ,y); }
  1434.  
  1435. template<class T>
  1436. inline
  1437. bool operator != ( none_t, optional<T> const& y ) BOOST_NOEXCEPT
  1438. { return bool(y); }
  1439.  
  1440. template<class T>
  1441. inline
  1442. bool operator > ( none_t x, optional<T> const& y )
  1443. { return y < x ; }
  1444.  
  1445. template<class T>
  1446. inline
  1447. bool operator <= ( none_t x, optional<T> const& y )
  1448. { return !( y < x ) ; }
  1449.  
  1450. template<class T>
  1451. inline
  1452. bool operator >= ( none_t x, optional<T> const& y )
  1453. { return !( x < y ) ; }
  1454.  
  1455. namespace optional_detail {
  1456.  
  1457. template<bool use_default_constructor> struct swap_selector;
  1458.  
  1459. template<>
  1460. struct swap_selector<true>
  1461. {
  1462.     template<class T>
  1463.     static void optional_swap ( optional<T>& x, optional<T>& y )
  1464.     {
  1465.         const bool hasX = !!x;
  1466.         const bool hasY = !!y;
  1467.  
  1468.         if ( !hasX && !hasY )
  1469.             return;
  1470.  
  1471.         if( !hasX )
  1472.             x.emplace();
  1473.         else if ( !hasY )
  1474.             y.emplace();
  1475.  
  1476.         // Boost.Utility.Swap will take care of ADL and workarounds for broken compilers
  1477.         mars_boost::swap(x.get(),y.get());
  1478.  
  1479.         if( !hasX )
  1480.             y = mars_boost::none ;
  1481.         else if( !hasY )
  1482.             x = mars_boost::none ;
  1483.     }
  1484. };
  1485.  
  1486. #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
  1487. template<>
  1488. struct swap_selector<false>
  1489. {
  1490.     template<class T>
  1491.     static void optional_swap ( optional<T>& x, optional<T>& y )
  1492.     //BOOST_NOEXCEPT_IF(::mars_boost::is_nothrow_move_constructible<T>::value && BOOST_NOEXCEPT_EXPR(mars_boost::swap(*x, *y)))
  1493.     {
  1494.         if(x)
  1495.         {
  1496.             if (y)
  1497.             {
  1498.                 mars_boost::swap(*x, *y);
  1499.             }
  1500.             else
  1501.             {
  1502.                 y = mars_boost::move(*x);
  1503.                 x = mars_boost::none;
  1504.             }
  1505.         }
  1506.         else
  1507.         {
  1508.             if (y)
  1509.             {
  1510.                 x = mars_boost::move(*y);
  1511.                 y = mars_boost::none;
  1512.             }
  1513.         }
  1514.     }
  1515. };
  1516. #else
  1517. template<>
  1518. struct swap_selector<false>
  1519. {
  1520.     template<class T>
  1521.     static void optional_swap ( optional<T>& x, optional<T>& y )
  1522.     {
  1523.         const bool hasX = !!x;
  1524.         const bool hasY = !!y;
  1525.  
  1526.         if ( !hasX && hasY )
  1527.         {
  1528.             x = y.get();
  1529.             y = mars_boost::none ;
  1530.         }
  1531.         else if ( hasX && !hasY )
  1532.         {
  1533.             y = x.get();
  1534.             x = mars_boost::none ;
  1535.         }
  1536.         else if ( hasX && hasY )
  1537.         {
  1538.             // Boost.Utility.Swap will take care of ADL and workarounds for broken compilers
  1539.             mars_boost::swap(x.get(),y.get());
  1540.         }
  1541.     }
  1542. };
  1543. #endif // !defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
  1544.  
  1545. } // namespace optional_detail
  1546.  
  1547. #if (!defined BOOST_NO_CXX11_RVALUE_REFERENCES) && (!defined BOOST_CONFIG_RESTORE_OBSOLETE_SWAP_IMPLEMENTATION)
  1548.  
  1549. template<class T>
  1550. struct optional_swap_should_use_default_constructor : mars_boost::false_type {} ;
  1551.  
  1552. #else
  1553.  
  1554. template<class T>
  1555. struct optional_swap_should_use_default_constructor : has_nothrow_default_constructor<T> {} ;
  1556.  
  1557. #endif //BOOST_NO_CXX11_RVALUE_REFERENCES
  1558.  
  1559. template<class T> inline void swap ( optional<T>& x, optional<T>& y )
  1560.   //BOOST_NOEXCEPT_IF(::mars_boost::is_nothrow_move_constructible<T>::value && BOOST_NOEXCEPT_EXPR(mars_boost::swap(*x, *y)))
  1561. {
  1562.     optional_detail::swap_selector<optional_swap_should_use_default_constructor<T>::value>::optional_swap(x, y);
  1563. }
  1564.  
  1565. } // namespace mars_boost
  1566.  
  1567. #endif
  1568.  
downloadoptional.hpp Source code - Download mars Source code
Related Source Codes/Software:
Hero - Elegant transition library for iOS & tvOS 2017-06-09
deep-photo-styletransfer - Code and data for paper "Deep Photo Style Transfer... 2017-06-09
mastodon - A GNU Social-compatible microblogging server ... 2017-06-09
plyr - A simple HTML5, YouTube and Vimeo player ... 2017-06-08
prepack - Prepack is a partial evaluator for JavaScript. Pre... 2017-06-08
Public-APIs - 2017-06-09
lottie-ios - An iOS library to natively render After Effects ve... 2017-06-09
Awesome-Hacking - A collection of various awesome lists for hackers,... 2017-06-09
algorithms - Minimal examples of data structures and algorithms... 2017-06-10
lectures - Oxford Deep NLP 2017 course 2017-06-10
CRYENGINE - CRYENGINE is a powerful real-time game development... 2017-06-11
postal - 2017-06-11
reactide - Reactide is the first dedicated IDE for React web ... 2017-06-11
rkt - rkt is a pod-native container engine for Linux. It... 2017-06-11
uWebSockets - Tiny WebSockets https://for... 2017-06-11
realworld - TodoMVC for the RealWorld - Exemplary fullstack Me... 2017-06-11
goreplay - GoReplay is an open-source tool for capturing and ... 2017-06-10
pyenv - Simple Python version management 2017-06-10
redux-saga - An alternative side effect model for Redux apps ... 2017-06-10
angular-starter - 2017-06-10

 Back to top