src/cxx_supportlib/vendor-modified/boost/optional/optional.hpp in passenger-5.3.3 vs src/cxx_supportlib/vendor-modified/boost/optional/optional.hpp in passenger-5.3.4

- old
+ new

@@ -1,7 +1,7 @@ // Copyright (C) 2003, 2008 Fernando Luis Cacciola Carballal. -// Copyright (C) 2014 - 2016 Andrzej Krzemienski. +// Copyright (C) 2014 - 2017 Andrzej Krzemienski. // // Use, modification, and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // @@ -18,10 +18,14 @@ #define BOOST_OPTIONAL_OPTIONAL_FLC_19NOV2002_HPP #include <new> #include <iosfwd> +#ifdef BOOST_OPTIONAL_DETAIL_USE_STD_TYPE_TRAITS +# include <type_traits> +#endif + #include <boost/assert.hpp> #include <boost/core/addressof.hpp> #include <boost/core/enable_if.hpp> #include <boost/core/explicit_operator_bool.hpp> #include <boost/core/swap.hpp> @@ -35,16 +39,19 @@ #include <boost/type_traits/type_with_alignment.hpp> #include <boost/type_traits/remove_const.hpp> #include <boost/type_traits/remove_reference.hpp> #include <boost/type_traits/decay.hpp> #include <boost/type_traits/is_base_of.hpp> +#include <boost/type_traits/is_const.hpp> #include <boost/type_traits/is_constructible.hpp> #include <boost/type_traits/is_lvalue_reference.hpp> #include <boost/type_traits/is_nothrow_move_assignable.hpp> #include <boost/type_traits/is_nothrow_move_constructible.hpp> #include <boost/type_traits/is_rvalue_reference.hpp> #include <boost/type_traits/is_same.hpp> +#include <boost/type_traits/is_volatile.hpp> +#include <boost/type_traits/is_scalar.hpp> #include <boost/move/utility.hpp> #include <boost/none.hpp> #include <boost/utility/compare_pointees.hpp> #include <boost/optional/optional_fwd.hpp> @@ -65,11 +72,11 @@ struct init_tag{}; explicit in_place_init_t(init_tag){} }; const in_place_init_t in_place_init ((in_place_init_t::init_tag())); -// a tag for conditional in-place initialization of contained value +// a tag for conditional in-place initialization of contained value struct in_place_init_if_t { struct init_tag{}; explicit in_place_init_if_t(init_tag){} }; @@ -140,20 +147,32 @@ { construct( boost::move(val) ); } #endif - // Creates an optional<T> initialized with 'val' IFF cond is true, otherwise creates an uninitialzed optional<T>. + // Creates an optional<T> initialized with 'val' IFF cond is true, otherwise creates an uninitialized optional<T>. // Can throw if T::T(T const&) does optional_base ( bool cond, argument_type val ) : m_initialized(false) { if ( cond ) construct(val); } +#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES + // Creates an optional<T> initialized with 'move(val)' IFF cond is true, otherwise creates an uninitialized optional<T>. + // Can throw if T::T(T &&) does + optional_base ( bool cond, rval_reference_type val ) + : + m_initialized(false) + { + if ( cond ) + construct(boost::move(val)); + } +#endif + // Creates a deep copy of another optional<T> // Can throw if T::T(T const&) does optional_base ( optional_base const& rhs ) : m_initialized(false) @@ -164,10 +183,11 @@ #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES // Creates a deep move of another optional<T> // Can throw if T::T(T&&) does optional_base ( optional_base&& rhs ) + BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value) : m_initialized(false) { if ( rhs.is_initialized() ) construct( boost::move(rhs.get_impl()) ); @@ -196,11 +216,25 @@ construct(expr,tag); } #endif + optional_base& operator= ( optional_base const& rhs ) + { + this->assign(rhs); + return *this; + } +#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES + optional_base& operator= ( optional_base && rhs ) + BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value && ::boost::is_nothrow_move_assignable<T>::value) + { + this->assign(static_cast<optional_base&&>(rhs)); + return *this; + } +#endif + // No-throw (assuming T::~T() doesn't) ~optional_base() { destroy() ; } // Assigns from another optional<T> (deep-copies the rhs value) void assign ( optional_base const& rhs ) @@ -711,20 +745,24 @@ pointer_const_type get_ptr_impl() const { return m_storage.ptr_ref(); } pointer_type get_ptr_impl() { return m_storage.ptr_ref(); } private : -#if BOOST_WORKAROUND(BOOST_MSVC, <= 1600) +#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1900)) void destroy_impl ( ) { m_storage.ptr_ref()->~T() ; m_initialized = false ; } #else void destroy_impl ( ) { m_storage.ref().T::~T() ; m_initialized = false ; } #endif bool m_initialized ; storage_type m_storage ; } ; + + +#include <boost/optional/detail/optional_trivially_copyable_base.hpp> + // definition of metafunciton is_optional_val_init_candidate template <typename U> struct is_optional_related : boost::conditional< boost::is_base_of<optional_detail::optional_tag, BOOST_DEDUCED_TYPENAME boost::decay<U>::type>::value || boost::is_same<BOOST_DEDUCED_TYPENAME boost::decay<U>::type, none_t>::value @@ -762,17 +800,38 @@ template <typename T, typename U> struct is_optional_val_init_candidate : boost::conditional< !is_optional_related<U>::value && is_convertible_to_T_or_factory<T, U>::value , boost::true_type, boost::false_type>::type {}; - + } // namespace optional_detail +namespace optional_config { + +template <typename T> +struct optional_uses_direct_storage_for + : boost::conditional<(boost::is_scalar<T>::value && !boost::is_const<T>::value && !boost::is_volatile<T>::value) + , boost::true_type, boost::false_type>::type +{}; + +} // namespace optional_config + + +#ifndef BOOST_OPTIONAL_DETAIL_NO_DIRECT_STORAGE_SPEC +# define BOOST_OPTIONAL_BASE_TYPE(T) boost::conditional< optional_config::optional_uses_direct_storage_for<T>::value, \ + optional_detail::tc_optional_base<T>, \ + optional_detail::optional_base<T> \ + >::type +#else +# define BOOST_OPTIONAL_BASE_TYPE(T) optional_detail::optional_base<T> +#endif + template<class T> -class optional : public optional_detail::optional_base<T> +class optional + : public BOOST_OPTIONAL_BASE_TYPE(T) { - typedef optional_detail::optional_base<T> base ; + typedef typename BOOST_OPTIONAL_BASE_TYPE(T) base ; public : typedef optional<T> this_type ; @@ -808,24 +867,31 @@ // Creates an optional<T> initialized with 'val' IFF cond is true, otherwise creates an uninitialized optional. // Can throw if T::T(T const&) does optional ( bool cond, argument_type val ) : base(cond,val) {} +#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES + /// Creates an optional<T> initialized with 'val' IFF cond is true, otherwise creates an uninitialized optional. + // Can throw if T::T(T &&) does + optional ( bool cond, rval_reference_type val ) : base( cond, boost::forward<T>(val) ) + {} +#endif + // NOTE: MSVC needs templated versions first // Creates a deep copy of another convertible optional<U> // Requires a valid conversion from U to T. // Can throw if T::T(U const&) does template<class U> explicit optional ( optional<U> const& rhs #ifndef BOOST_OPTIONAL_DETAIL_NO_SFINAE_FRIENDLY_CONSTRUCTORS - ,typename boost::enable_if< optional_detail::is_optional_constructible<T, U const&> >::type* = 0 + ,BOOST_DEDUCED_TYPENAME boost::enable_if< optional_detail::is_optional_constructible<T, U const&>, bool>::type = true #endif ) : base() - { + { if ( rhs.is_initialized() ) this->construct(rhs.get()); } #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES @@ -833,11 +899,11 @@ // Requires a valid conversion from U to T. // Can throw if T::T(U&&) does template<class U> explicit optional ( optional<U> && rhs #ifndef BOOST_OPTIONAL_DETAIL_NO_SFINAE_FRIENDLY_CONSTRUCTORS - ,typename boost::enable_if< optional_detail::is_optional_constructible<T, U> >::type* = 0 + ,BOOST_DEDUCED_TYPENAME boost::enable_if< optional_detail::is_optional_constructible<T, U>, bool>::type = true #endif ) : base() { @@ -859,11 +925,11 @@ #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES template<class Expr> explicit optional ( Expr&& expr, - BOOST_DEDUCED_TYPENAME boost::enable_if< optional_detail::is_optional_val_init_candidate<T, Expr> >::type* = 0 + BOOST_DEDUCED_TYPENAME boost::enable_if< optional_detail::is_optional_val_init_candidate<T, Expr>, bool>::type = true ) : base(boost::forward<Expr>(expr),boost::addressof(expr)) {} #else @@ -872,28 +938,37 @@ #endif // !defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES #endif // !defined BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT // Creates a deep copy of another optional<T> // Can throw if T::T(T const&) does +#ifndef BOOST_OPTIONAL_DETAIL_NO_DEFAULTED_MOVE_FUNCTIONS + optional ( optional const& ) = default; +#else optional ( optional const& rhs ) : base( static_cast<base const&>(rhs) ) {} +#endif #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES - // Creates a deep move of another optional<T> - // Can throw if T::T(T&&) does - optional ( optional && rhs ) - BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value) - : base( boost::move(rhs) ) - {} + // Creates a deep move of another optional<T> + // Can throw if T::T(T&&) does +#ifndef BOOST_OPTIONAL_DETAIL_NO_DEFAULTED_MOVE_FUNCTIONS + optional ( optional && rhs ) = default; +#else + optional ( optional && rhs ) + BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value) + : base( boost::move(rhs) ) + {} #endif +#endif + #if BOOST_WORKAROUND(_MSC_VER, <= 1600) // On old MSVC compilers the implicitly declared dtor is not called ~optional() {} #endif - + #if !defined(BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT) && !defined(BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION) // Assigns from an expression. See corresponding constructor. // Basic Guarantee: If the resolved T ctor throws, this is left UNINITIALIZED #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES @@ -938,25 +1013,34 @@ #endif // Assigns from another optional<T> (deep-copies the rhs value) // Basic Guarantee: If T::T( T const& ) throws, this is left UNINITIALIZED // (NOTE: On BCB, this operator is not actually called and left is left UNMODIFIED in case of a throw) +#ifndef BOOST_OPTIONAL_DETAIL_NO_DEFAULTED_MOVE_FUNCTIONS + optional& operator= ( optional const& rhs ) = default; +#else optional& operator= ( optional const& rhs ) { this->assign( static_cast<base const&>(rhs) ) ; return *this ; } +#endif #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES // Assigns from another optional<T> (deep-moves the rhs value) +#ifndef BOOST_OPTIONAL_DETAIL_NO_DEFAULTED_MOVE_FUNCTIONS + optional& operator= ( optional && ) = default; +#else optional& operator= ( optional && rhs ) - BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value && ::boost::is_nothrow_move_assignable<T>::value) + BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value && ::boost::is_nothrow_move_assignable<T>::value) { this->assign( static_cast<base &&>(rhs) ) ; return *this ; } -#endif +#endif + +#endif // BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES #ifndef BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX // Assigns from a T (deep-moves/copies the rhs value) template <typename T_> @@ -1091,11 +1175,11 @@ : base( in_place_init_if, cond ) {} #endif void swap( optional & arg ) - BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value && ::boost::is_nothrow_move_assignable<T>::value) + BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value && ::boost::is_nothrow_move_assignable<T>::value) { // allow for Koenig lookup boost::swap(*this, arg); } @@ -1274,10 +1358,29 @@ # include <boost/optional/detail/optional_reference_spec.hpp> #endif namespace boost { +#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES + +template<class T> +inline +optional<BOOST_DEDUCED_TYPENAME boost::decay<T>::type> make_optional ( T && v ) +{ + return optional<BOOST_DEDUCED_TYPENAME boost::decay<T>::type>(boost::forward<T>(v)); +} + +// Returns optional<T>(cond,v) +template<class T> +inline +optional<BOOST_DEDUCED_TYPENAME boost::decay<T>::type> make_optional ( bool cond, T && v ) +{ + return optional<BOOST_DEDUCED_TYPENAME boost::decay<T>::type>(cond,boost::forward<T>(v)); +} + +#else + // Returns optional<T>(v) template<class T> inline optional<T> make_optional ( T const& v ) { @@ -1289,9 +1392,11 @@ inline optional<T> make_optional ( bool cond, T const& v ) { return optional<T>(cond,v); } + +#endif // BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES // Returns a reference to the value if this is initialized, otherwise, the behaviour is UNDEFINED. // No-throw template<class T> inline