diff --git a/doc/html/boost_optional/relnotes.html b/doc/html/boost_optional/relnotes.html
index bac08cc..fa36621 100644
--- a/doc/html/boost_optional/relnotes.html
+++ b/doc/html/boost_optional/relnotes.html
@@ -31,29 +31,38 @@
Boost
Release X.XX
-
--
- Changed the implementation of
boost::none
:
- now it is a constant with internal linkage. This addresses Trac
- #11203.
-
--
+
-
Now
boost::optional
is specialized for reference
parameters. This way the sizeof
of optional reference is that of a pointer, and a number of bugs is avoided.
-
-
+
-
- For C++03 compilers, added 0-argument overload for member function
emplace()
,
- and therewith removed the dependency on <boost/utility/in_place_factory.hpp>
.
+ Changed the implementation of boost::none
+ again. Now it is a const object with internal linkage (as any other tag).
+ This fixes Trac
+ #11203.
+
+-
+ For C++03 compilers, added 0-argument overload for member function
emplace()
,
+ and therewith removed the dependency on <boost/utility/in_place_factory.hpp>
.
+
+-
+ Fixed Trac #11241.
+
+
+
@@ -89,7 +98,7 @@
@@ -99,7 +108,7 @@
to fix C++03 compile error on logic_error("...")
".
diff --git a/doc/html/index.html b/doc/html/index.html
index 558d7e2..3939641 100644
--- a/doc/html/index.html
+++ b/doc/html/index.html
@@ -146,7 +146,7 @@
-Last revised: October 05, 2015 at 14:34:49 GMT |
+Last revised: February 12, 2016 at 21:19:23 GMT |
|
diff --git a/include/boost/none_t.hpp b/include/boost/none_t.hpp
index fa73654..a05d303 100644
--- a/include/boost/none_t.hpp
+++ b/include/boost/none_t.hpp
@@ -29,7 +29,7 @@ class none_t {};
struct none_t
{
struct init_tag{};
- explicit none_t(init_tag){} // to prevent default constructor
+ explicit none_t(init_tag){} // to disable default constructor
};
#endif // old implementation workarounds
diff --git a/include/boost/optional/detail/old_optional_implementation.hpp b/include/boost/optional/detail/old_optional_implementation.hpp
new file mode 100644
index 0000000..f2e6718
--- /dev/null
+++ b/include/boost/optional/detail/old_optional_implementation.hpp
@@ -0,0 +1,1059 @@
+// Copyright (C) 2003, 2008 Fernando Luis Cacciola Carballal.
+// Copyright (C) 2014-2016 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)
+//
+// See http://www.boost.org/libs/optional for documentation.
+//
+// You are welcome to contact the maintainer at:
+// akrzemi1@gmail.com
+
+#ifndef BOOST_OPTIONAL_DETAIL_OLD_OPTIONAL_IMPLEMENTATION_AJK_28JAN2015_HPP
+#define BOOST_OPTIONAL_DETAIL_OLD_OPTIONAL_IMPLEMENTATION_AJK_28JAN2015_HPP
+
+#include
+#include
+#include
+#include
+#include
+
+namespace boost {
+
+namespace optional_detail {
+
+
+template
+struct types_when_isnt_ref
+{
+ typedef T const& reference_const_type ;
+ typedef T & reference_type ;
+#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+ typedef T && rval_reference_type ;
+ typedef T && reference_type_of_temporary_wrapper;
+#ifdef BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
+ // GCC 4.4 has support for an early draft of rvalue references. The conforming version below
+ // causes warnings about returning references to a temporary.
+ static T&& move(T&& r) { return r; }
+#else
+ static rval_reference_type move(reference_type r) { return boost::move(r); }
+#endif
+#endif
+ typedef T const* pointer_const_type ;
+ typedef T * pointer_type ;
+ typedef T const& argument_type ;
+} ;
+
+template
+struct types_when_is_ref
+{
+ typedef BOOST_DEDUCED_TYPENAME remove_reference::type raw_type ;
+
+ typedef raw_type& reference_const_type ;
+ typedef raw_type& reference_type ;
+#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+ typedef BOOST_DEDUCED_TYPENAME remove_const::type&& rval_reference_type ;
+ typedef raw_type& reference_type_of_temporary_wrapper;
+ static reference_type move(reference_type r) { return r; }
+#endif
+ typedef raw_type* pointer_const_type ;
+ typedef raw_type* pointer_type ;
+ typedef raw_type& argument_type ;
+} ;
+
+template
+void prevent_binding_rvalue_ref_to_optional_lvalue_ref()
+{
+#ifndef BOOST_OPTIONAL_CONFIG_ALLOW_BINDING_TO_RVALUES
+ BOOST_STATIC_ASSERT_MSG(
+ !boost::is_lvalue_reference::value || !boost::is_rvalue_reference::value,
+ "binding rvalue references to optional lvalue references is disallowed");
+#endif
+}
+
+struct optional_tag {} ;
+
+template
+class optional_base : public optional_tag
+{
+ private :
+
+ typedef
+#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+ BOOST_DEDUCED_TYPENAME
+#endif
+ ::boost::detail::make_reference_content::type internal_type ;
+
+ typedef aligned_storage storage_type ;
+
+ typedef types_when_isnt_ref types_when_not_ref ;
+ typedef types_when_is_ref types_when_ref ;
+
+ typedef optional_base this_type ;
+
+ protected :
+
+ typedef T value_type ;
+
+ typedef mpl::true_ is_reference_tag ;
+ typedef mpl::false_ is_not_reference_tag ;
+
+ typedef BOOST_DEDUCED_TYPENAME is_reference::type is_reference_predicate ;
+
+ public:
+ typedef BOOST_DEDUCED_TYPENAME mpl::if_::type types ;
+
+ protected:
+ typedef BOOST_DEDUCED_TYPENAME types::reference_type reference_type ;
+ typedef BOOST_DEDUCED_TYPENAME types::reference_const_type reference_const_type ;
+#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+ typedef BOOST_DEDUCED_TYPENAME types::rval_reference_type rval_reference_type ;
+ typedef BOOST_DEDUCED_TYPENAME types::reference_type_of_temporary_wrapper reference_type_of_temporary_wrapper ;
+#endif
+ typedef BOOST_DEDUCED_TYPENAME types::pointer_type pointer_type ;
+ typedef BOOST_DEDUCED_TYPENAME types::pointer_const_type pointer_const_type ;
+ typedef BOOST_DEDUCED_TYPENAME types::argument_type argument_type ;
+
+ // Creates an optional uninitialized.
+ // No-throw
+ optional_base()
+ :
+ m_initialized(false) {}
+
+ // Creates an optional uninitialized.
+ // No-throw
+ optional_base ( none_t )
+ :
+ m_initialized(false) {}
+
+ // Creates an optional initialized with 'val'.
+ // Can throw if T::T(T const&) does
+ optional_base ( argument_type val )
+ :
+ m_initialized(false)
+ {
+ construct(val);
+ }
+
+#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+ // move-construct an optional initialized from an rvalue-ref to 'val'.
+ // Can throw if T::T(T&&) does
+ optional_base ( rval_reference_type val )
+ :
+ m_initialized(false)
+ {
+ construct( boost::move(val) );
+ }
+#endif
+
+ // Creates an optional initialized with 'val' IFF cond is true, otherwise creates an uninitialzed optional.
+ // Can throw if T::T(T const&) does
+ optional_base ( bool cond, argument_type val )
+ :
+ m_initialized(false)
+ {
+ if ( cond )
+ construct(val);
+ }
+
+ // Creates a deep copy of another optional
+ // Can throw if T::T(T const&) does
+ optional_base ( optional_base const& rhs )
+ :
+ m_initialized(false)
+ {
+ if ( rhs.is_initialized() )
+ construct(rhs.get_impl());
+ }
+
+#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+ // Creates a deep move of another optional
+ // Can throw if T::T(T&&) does
+ optional_base ( optional_base&& rhs )
+ :
+ m_initialized(false)
+ {
+ if ( rhs.is_initialized() )
+ construct( boost::move(rhs.get_impl()) );
+ }
+#endif
+
+#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+
+ template
+ explicit optional_base ( Expr&& expr, PtrExpr const* tag )
+ :
+ m_initialized(false)
+ {
+ construct(boost::forward(expr),tag);
+ }
+
+#else
+ // This is used for both converting and in-place constructions.
+ // Derived classes use the 'tag' to select the appropriate
+ // implementation (the correct 'construct()' overload)
+ template
+ explicit optional_base ( Expr const& expr, Expr const* tag )
+ :
+ m_initialized(false)
+ {
+ construct(expr,tag);
+ }
+
+#endif
+
+
+ // No-throw (assuming T::~T() doesn't)
+ ~optional_base() { destroy() ; }
+
+ // Assigns from another optional (deep-copies the rhs value)
+ void assign ( optional_base const& rhs )
+ {
+ if (is_initialized())
+ {
+ if ( rhs.is_initialized() )
+ assign_value(rhs.get_impl(), is_reference_predicate() );
+ else destroy();
+ }
+ else
+ {
+ if ( rhs.is_initialized() )
+ construct(rhs.get_impl());
+ }
+ }
+
+#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+ // Assigns from another optional (deep-moves the rhs value)
+ void assign ( optional_base&& rhs )
+ {
+ if (is_initialized())
+ {
+ if ( rhs.is_initialized() )
+ assign_value(boost::move(rhs.get_impl()), is_reference_predicate() );
+ else destroy();
+ }
+ else
+ {
+ if ( rhs.is_initialized() )
+ construct(boost::move(rhs.get_impl()));
+ }
+ }
+#endif
+
+ // Assigns from another _convertible_ optional (deep-copies the rhs value)
+ template
+ void assign ( optional const& rhs )
+ {
+ if (is_initialized())
+ {
+ if ( rhs.is_initialized() )
+#ifndef BOOST_OPTIONAL_CONFIG_RESTORE_ASSIGNMENT_OF_NONCONVERTIBLE_TYPES
+ assign_value(rhs.get(), is_reference_predicate() );
+#else
+ assign_value(static_cast(rhs.get()), is_reference_predicate() );
+#endif
+
+ else destroy();
+ }
+ else
+ {
+ if ( rhs.is_initialized() )
+#ifndef BOOST_OPTIONAL_CONFIG_RESTORE_ASSIGNMENT_OF_NONCONVERTIBLE_TYPES
+ construct(rhs.get());
+#else
+ construct(static_cast(rhs.get()));
+#endif
+ }
+ }
+
+#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+ // move-assigns from another _convertible_ optional (deep-moves from the rhs value)
+ template
+ void assign ( optional&& rhs )
+ {
+ typedef BOOST_DEDUCED_TYPENAME optional::rval_reference_type ref_type;
+ if (is_initialized())
+ {
+ if ( rhs.is_initialized() )
+ assign_value(static_cast(rhs.get()), is_reference_predicate() );
+ else destroy();
+ }
+ else
+ {
+ if ( rhs.is_initialized() )
+ construct(static_cast(rhs.get()));
+ }
+ }
+#endif
+
+ // Assigns from a T (deep-copies the rhs value)
+ void assign ( argument_type val )
+ {
+ if (is_initialized())
+ assign_value(val, is_reference_predicate() );
+ else construct(val);
+ }
+
+#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+ // Assigns from a T (deep-moves the rhs value)
+ void assign ( rval_reference_type val )
+ {
+ if (is_initialized())
+ assign_value( boost::move(val), is_reference_predicate() );
+ else construct( boost::move(val) );
+ }
+#endif
+
+ // Assigns from "none", destroying the current value, if any, leaving this UNINITIALIZED
+ // No-throw (assuming T::~T() doesn't)
+ void assign ( none_t ) BOOST_NOEXCEPT { destroy(); }
+
+#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
+
+#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+ template
+ void assign_expr ( Expr&& expr, ExprPtr const* tag )
+ {
+ if (is_initialized())
+ assign_expr_to_initialized(boost::forward(expr),tag);
+ else construct(boost::forward(expr),tag);
+ }
+#else
+ template
+ void assign_expr ( Expr const& expr, Expr const* tag )
+ {
+ if (is_initialized())
+ assign_expr_to_initialized(expr,tag);
+ else construct(expr,tag);
+ }
+#endif
+
+#endif
+
+ public :
+
+ // **DEPPRECATED** Destroys the current value, if any, leaving this UNINITIALIZED
+ // No-throw (assuming T::~T() doesn't)
+ void reset() BOOST_NOEXCEPT { destroy(); }
+
+ // **DEPPRECATED** Replaces the current value -if any- with 'val'
+ void reset ( argument_type val ) { assign(val); }
+
+ // Returns a pointer to the value if this is initialized, otherwise,
+ // returns NULL.
+ // No-throw
+ pointer_const_type get_ptr() const { return m_initialized ? get_ptr_impl() : 0 ; }
+ pointer_type get_ptr() { return m_initialized ? get_ptr_impl() : 0 ; }
+
+ bool is_initialized() const { return m_initialized ; }
+
+ protected :
+
+ void construct ( argument_type val )
+ {
+ ::new (m_storage.address()) internal_type(val) ;
+ m_initialized = true ;
+ }
+
+#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+ void construct ( rval_reference_type val )
+ {
+ ::new (m_storage.address()) internal_type( types::move(val) ) ;
+ m_initialized = true ;
+ }
+#endif
+
+
+#if (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) && (!defined BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ // Constructs in-place
+ // upon exception *this is always uninitialized
+ template
+ void emplace_assign ( Args&&... args )
+ {
+ destroy();
+ ::new (m_storage.address()) internal_type( boost::forward(args)... );
+ m_initialized = true ;
+ }
+#elif (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
+ template
+ void emplace_assign ( Arg&& arg )
+ {
+ destroy();
+ ::new (m_storage.address()) internal_type( boost::forward(arg) );
+ m_initialized = true ;
+ }
+
+ void emplace_assign ()
+ {
+ destroy();
+ ::new (m_storage.address()) internal_type();
+ m_initialized = true ;
+ }
+#else
+ template
+ void emplace_assign ( const Arg& arg )
+ {
+ destroy();
+ ::new (m_storage.address()) internal_type( arg );
+ m_initialized = true ;
+ }
+
+ template
+ void emplace_assign ( Arg& arg )
+ {
+ destroy();
+ ::new (m_storage.address()) internal_type( arg );
+ m_initialized = true ;
+ }
+
+ void emplace_assign ()
+ {
+ destroy();
+ ::new (m_storage.address()) internal_type();
+ m_initialized = true ;
+ }
+#endif
+
+#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
+
+#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+ // Constructs in-place using the given factory
+ template
+ void construct ( Expr&& factory, in_place_factory_base const* )
+ {
+ BOOST_STATIC_ASSERT ( ::boost::mpl::not_::value ) ;
+ boost_optional_detail::construct(factory, m_storage.address());
+ m_initialized = true ;
+ }
+
+ // Constructs in-place using the given typed factory
+ template
+ void construct ( Expr&& factory, typed_in_place_factory_base const* )
+ {
+ BOOST_STATIC_ASSERT ( ::boost::mpl::not_::value ) ;
+ factory.apply(m_storage.address()) ;
+ m_initialized = true ;
+ }
+
+ template
+ void assign_expr_to_initialized ( Expr&& factory, in_place_factory_base const* tag )
+ {
+ destroy();
+ construct(factory,tag);
+ }
+
+ // Constructs in-place using the given typed factory
+ template
+ void assign_expr_to_initialized ( Expr&& factory, typed_in_place_factory_base const* tag )
+ {
+ destroy();
+ construct(factory,tag);
+ }
+
+#else
+ // Constructs in-place using the given factory
+ template
+ void construct ( Expr const& factory, in_place_factory_base const* )
+ {
+ BOOST_STATIC_ASSERT ( ::boost::mpl::not_::value ) ;
+ boost_optional_detail::construct(factory, m_storage.address());
+ m_initialized = true ;
+ }
+
+ // Constructs in-place using the given typed factory
+ template
+ void construct ( Expr const& factory, typed_in_place_factory_base const* )
+ {
+ BOOST_STATIC_ASSERT ( ::boost::mpl::not_::value ) ;
+ factory.apply(m_storage.address()) ;
+ m_initialized = true ;
+ }
+
+ template
+ void assign_expr_to_initialized ( Expr const& factory, in_place_factory_base const* tag )
+ {
+ destroy();
+ construct(factory,tag);
+ }
+
+ // Constructs in-place using the given typed factory
+ template
+ void assign_expr_to_initialized ( Expr const& factory, typed_in_place_factory_base const* tag )
+ {
+ destroy();
+ construct(factory,tag);
+ }
+#endif
+
+#endif
+
+#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+ // Constructs using any expression implicitly convertible to the single argument
+ // of a one-argument T constructor.
+ // Converting constructions of optional from optional uses this function with
+ // 'Expr' being of type 'U' and relying on a converting constructor of T from U.
+ template
+ void construct ( Expr&& expr, void const* )
+ {
+ new (m_storage.address()) internal_type(boost::forward(expr)) ;
+ m_initialized = true ;
+ }
+
+ // Assigns using a form any expression implicitly convertible to the single argument
+ // of a T's assignment operator.
+ // Converting assignments of optional from optional uses this function with
+ // 'Expr' being of type 'U' and relying on a converting assignment of T from U.
+ template
+ void assign_expr_to_initialized ( Expr&& expr, void const* )
+ {
+ assign_value(boost::forward(expr), is_reference_predicate());
+ }
+#else
+ // Constructs using any expression implicitly convertible to the single argument
+ // of a one-argument T constructor.
+ // Converting constructions of optional from optional uses this function with
+ // 'Expr' being of type 'U' and relying on a converting constructor of T from U.
+ template
+ void construct ( Expr const& expr, void const* )
+ {
+ new (m_storage.address()) internal_type(expr) ;
+ m_initialized = true ;
+ }
+
+ // Assigns using a form any expression implicitly convertible to the single argument
+ // of a T's assignment operator.
+ // Converting assignments of optional from optional uses this function with
+ // 'Expr' being of type 'U' and relying on a converting assignment of T from U.
+ template
+ void assign_expr_to_initialized ( Expr const& expr, void const* )
+ {
+ assign_value(expr, is_reference_predicate());
+ }
+
+#endif
+
+#ifdef BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION
+ // BCB5.64 (and probably lower versions) workaround.
+ // The in-place factories are supported by means of catch-all constructors
+ // and assignment operators (the functions are parameterized in terms of
+ // an arbitrary 'Expr' type)
+ // This compiler incorrectly resolves the overload set and sinks optional and optional
+ // to the 'Expr'-taking functions even though explicit overloads are present for them.
+ // Thus, the following overload is needed to properly handle the case when the 'lhs'
+ // is another optional.
+ //
+ // For VC<=70 compilers this workaround dosen't work becasue the comnpiler issues and error
+ // instead of choosing the wrong overload
+ //
+#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+ // Notice that 'Expr' will be optional or optional (but not optional_base<..>)
+ template
+ void construct ( Expr&& expr, optional_tag const* )
+ {
+ if ( expr.is_initialized() )
+ {
+ // An exception can be thrown here.
+ // It it happens, THIS will be left uninitialized.
+ new (m_storage.address()) internal_type(types::move(expr.get())) ;
+ m_initialized = true ;
+ }
+ }
+#else
+ // Notice that 'Expr' will be optional or optional (but not optional_base<..>)
+ template
+ void construct ( Expr const& expr, optional_tag const* )
+ {
+ if ( expr.is_initialized() )
+ {
+ // An exception can be thrown here.
+ // It it happens, THIS will be left uninitialized.
+ new (m_storage.address()) internal_type(expr.get()) ;
+ m_initialized = true ;
+ }
+ }
+#endif
+#endif // defined BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION
+
+ void assign_value ( argument_type val, is_not_reference_tag ) { get_impl() = val; }
+ void assign_value ( argument_type val, is_reference_tag ) { construct(val); }
+#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+ void assign_value ( rval_reference_type val, is_not_reference_tag ) { get_impl() = static_cast(val); }
+ void assign_value ( rval_reference_type val, is_reference_tag ) { construct( static_cast(val) ); }
+#endif
+
+ void destroy()
+ {
+ if ( m_initialized )
+ destroy_impl(is_reference_predicate()) ;
+ }
+
+ reference_const_type get_impl() const { return dereference(get_object(), is_reference_predicate() ) ; }
+ reference_type get_impl() { return dereference(get_object(), is_reference_predicate() ) ; }
+
+ pointer_const_type get_ptr_impl() const { return cast_ptr(get_object(), is_reference_predicate() ) ; }
+ pointer_type get_ptr_impl() { return cast_ptr(get_object(), is_reference_predicate() ) ; }
+
+ private :
+
+ // internal_type can be either T or reference_content
+#if defined(BOOST_OPTIONAL_DETAIL_USE_ATTRIBUTE_MAY_ALIAS)
+ // This workaround is supposed to silence GCC warnings about broken strict aliasing rules
+ internal_type const* get_object() const
+ {
+ union { void const* ap_pvoid; internal_type const* as_ptype; } caster = { m_storage.address() };
+ return caster.as_ptype;
+ }
+ internal_type * get_object()
+ {
+ union { void* ap_pvoid; internal_type* as_ptype; } caster = { m_storage.address() };
+ return caster.as_ptype;
+ }
+#else
+ internal_type const* get_object() const { return static_cast(m_storage.address()); }
+ internal_type * get_object() { return static_cast (m_storage.address()); }
+#endif
+
+ // reference_content lacks an implicit conversion to T&, so the following is needed to obtain a proper reference.
+ reference_const_type dereference( internal_type const* p, is_not_reference_tag ) const { return *p ; }
+ reference_type dereference( internal_type* p, is_not_reference_tag ) { return *p ; }
+ reference_const_type dereference( internal_type const* p, is_reference_tag ) const { return p->get() ; }
+ reference_type dereference( internal_type* p, is_reference_tag ) { return p->get() ; }
+
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581))
+ void destroy_impl ( is_not_reference_tag ) { get_ptr_impl()->internal_type::~internal_type() ; m_initialized = false ; }
+#else
+ void destroy_impl ( is_not_reference_tag ) { get_ptr_impl()->~T() ; m_initialized = false ; }
+#endif
+
+ void destroy_impl ( is_reference_tag ) { m_initialized = false ; }
+
+ // If T is of reference type, trying to get a pointer to the held value must result in a compile-time error.
+ // Decent compilers should disallow conversions from reference_content* to T*, but just in case,
+ // the following olverloads are used to filter out the case and guarantee an error in case of T being a reference.
+ pointer_const_type cast_ptr( internal_type const* p, is_not_reference_tag ) const { return p ; }
+ pointer_type cast_ptr( internal_type * p, is_not_reference_tag ) { return p ; }
+ pointer_const_type cast_ptr( internal_type const* p, is_reference_tag ) const { return &p->get() ; }
+ pointer_type cast_ptr( internal_type * p, is_reference_tag ) { return &p->get() ; }
+
+ bool m_initialized ;
+ storage_type m_storage ;
+} ;
+
+} // namespace optional_detail
+
+template
+class optional : public optional_detail::optional_base
+{
+ typedef optional_detail::optional_base base ;
+
+ public :
+
+ typedef optional this_type ;
+
+ typedef BOOST_DEDUCED_TYPENAME base::value_type value_type ;
+ typedef BOOST_DEDUCED_TYPENAME base::reference_type reference_type ;
+ typedef BOOST_DEDUCED_TYPENAME base::reference_const_type reference_const_type ;
+#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+ typedef BOOST_DEDUCED_TYPENAME base::rval_reference_type rval_reference_type ;
+ typedef BOOST_DEDUCED_TYPENAME base::reference_type_of_temporary_wrapper reference_type_of_temporary_wrapper ;
+#endif
+ typedef BOOST_DEDUCED_TYPENAME base::pointer_type pointer_type ;
+ typedef BOOST_DEDUCED_TYPENAME base::pointer_const_type pointer_const_type ;
+ typedef BOOST_DEDUCED_TYPENAME base::argument_type argument_type ;
+
+ // Creates an optional uninitialized.
+ // No-throw
+ optional() BOOST_NOEXCEPT : base() {}
+
+ // Creates an optional uninitialized.
+ // No-throw
+ optional( none_t none_ ) BOOST_NOEXCEPT : base(none_) {}
+
+ // Creates an optional initialized with 'val'.
+ // Can throw if T::T(T const&) does
+ optional ( argument_type val ) : base(val) {}
+
+#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+ // Creates an optional initialized with 'move(val)'.
+ // Can throw if T::T(T &&) does
+ optional ( rval_reference_type val ) : base( boost::forward(val) )
+ {optional_detail::prevent_binding_rvalue_ref_to_optional_lvalue_ref();}
+#endif
+
+ // Creates an optional 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) {}
+
+ // NOTE: MSVC needs templated versions first
+
+ // Creates a deep copy of another convertible optional
+ // Requires a valid conversion from U to T.
+ // Can throw if T::T(U const&) does
+ template
+ explicit optional ( optional const& rhs )
+ :
+ base()
+ {
+ if ( rhs.is_initialized() )
+ this->construct(rhs.get());
+ }
+
+#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+ // Creates a deep move of another convertible optional
+ // Requires a valid conversion from U to T.
+ // Can throw if T::T(U&&) does
+ template
+ explicit optional ( optional && rhs )
+ :
+ base()
+ {
+ if ( rhs.is_initialized() )
+ this->construct( boost::move(rhs.get()) );
+ }
+#endif
+
+#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
+ // Creates an optional with an expression which can be either
+ // (a) An instance of InPlaceFactory (i.e. in_place(a,b,...,n);
+ // (b) An instance of TypedInPlaceFactory ( i.e. in_place(a,b,...,n);
+ // (c) Any expression implicitly convertible to the single type
+ // of a one-argument T's constructor.
+ // (d*) Weak compilers (BCB) might also resolved Expr as optional and optional
+ // even though explicit overloads are present for these.
+ // Depending on the above some T ctor is called.
+ // Can throw if the resolved T ctor throws.
+#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+
+
+ template
+ explicit optional ( Expr&& expr,
+ BOOST_DEDUCED_TYPENAME boost::disable_if_c<
+ (boost::is_base_of::type>::value) ||
+ boost::is_same::type, none_t>::value >::type* = 0
+ )
+ : base(boost::forward(expr),boost::addressof(expr))
+ {optional_detail::prevent_binding_rvalue_ref_to_optional_lvalue_ref();}
+
+#else
+ template
+ explicit optional ( Expr const& expr ) : base(expr,boost::addressof(expr)) {}
+#endif // !defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+#endif // !defined BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
+
+ // Creates a deep copy of another optional
+ // Can throw if T::T(T const&) does
+ optional ( optional const& rhs ) : base( static_cast(rhs) ) {}
+
+#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+ // Creates a deep move of another optional
+ // Can throw if T::T(T&&) does
+ optional ( optional && rhs )
+ BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible::value)
+ : base( boost::move(rhs) )
+ {}
+
+#endif
+ // No-throw (assuming T::~T() doesn't)
+ ~optional() {}
+
+#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
+
+ template
+ BOOST_DEDUCED_TYPENAME boost::disable_if_c<
+ boost::is_base_of::type>::value ||
+ boost::is_same::type, none_t>::value,
+ optional&
+ >::type
+ operator= ( Expr&& expr )
+ {
+ optional_detail::prevent_binding_rvalue_ref_to_optional_lvalue_ref();
+ this->assign_expr(boost::forward(expr),boost::addressof(expr));
+ return *this ;
+ }
+
+#else
+ template
+ optional& operator= ( Expr const& expr )
+ {
+ this->assign_expr(expr,boost::addressof(expr));
+ return *this ;
+ }
+#endif // !defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+#endif // !defined(BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT) && !defined(BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION)
+
+ // Copy-assigns from another convertible optional (converts && deep-copies the rhs value)
+ // Requires a valid conversion from U to T.
+ // Basic Guarantee: If T::T( U const& ) throws, this is left UNINITIALIZED
+ template
+ optional& operator= ( optional const& rhs )
+ {
+ this->assign(rhs);
+ return *this ;
+ }
+
+#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+ // Move-assigns from another convertible optional (converts && deep-moves the rhs value)
+ // Requires a valid conversion from U to T.
+ // Basic Guarantee: If T::T( U && ) throws, this is left UNINITIALIZED
+ template
+ optional& operator= ( optional && rhs )
+ {
+ this->assign(boost::move(rhs));
+ return *this ;
+ }
+#endif
+
+ // Assigns from another optional (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)
+ optional& operator= ( optional const& rhs )
+ {
+ this->assign( static_cast(rhs) ) ;
+ return *this ;
+ }
+
+#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+ // Assigns from another optional (deep-moves the rhs value)
+ optional& operator= ( optional && rhs )
+ BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible::value && ::boost::is_nothrow_move_assignable::value)
+ {
+ this->assign( static_cast(rhs) ) ;
+ return *this ;
+ }
+#endif
+
+ // Assigns from a T (deep-copies the rhs value)
+ // Basic Guarantee: If T::( T const& ) throws, this is left UNINITIALIZED
+ optional& operator= ( argument_type val )
+ {
+ this->assign( val ) ;
+ return *this ;
+ }
+
+#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+ // Assigns from a T (deep-moves the rhs value)
+ optional& operator= ( rval_reference_type val )
+ {
+ optional_detail::prevent_binding_rvalue_ref_to_optional_lvalue_ref();
+ this->assign( boost::move(val) ) ;
+ return *this ;
+ }
+#endif
+
+ // Assigns from a "none"
+ // Which destroys the current value, if any, leaving this UNINITIALIZED
+ // No-throw (assuming T::~T() doesn't)
+ optional& operator= ( none_t none_ ) BOOST_NOEXCEPT
+ {
+ this->assign( none_ ) ;
+ return *this ;
+ }
+
+#if (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) && (!defined BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ // Constructs in-place
+ // upon exception *this is always uninitialized
+ template
+ void emplace ( Args&&... args )
+ {
+ this->emplace_assign( boost::forward(args)... );
+ }
+#elif (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
+ template
+ void emplace ( Arg&& arg )
+ {
+ this->emplace_assign( boost::forward(arg) );
+ }
+
+ void emplace ()
+ {
+ this->emplace_assign();
+ }
+#else
+ template
+ void emplace ( const Arg& arg )
+ {
+ this->emplace_assign( arg );
+ }
+
+ template
+ void emplace ( Arg& arg )
+ {
+ this->emplace_assign( arg );
+ }
+
+ void emplace ()
+ {
+ this->emplace_assign();
+ }
+#endif
+
+ void swap( optional & arg )
+ BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible::value && ::boost::is_nothrow_move_assignable::value)
+ {
+ // allow for Koenig lookup
+ boost::swap(*this, arg);
+ }
+
+
+ // Returns a reference to the value if this is initialized, otherwise,
+ // the behaviour is UNDEFINED
+ // No-throw
+ reference_const_type get() const { BOOST_ASSERT(this->is_initialized()) ; return this->get_impl(); }
+ reference_type get() { BOOST_ASSERT(this->is_initialized()) ; return this->get_impl(); }
+
+ // Returns a copy of the value if this is initialized, 'v' otherwise
+ reference_const_type get_value_or ( reference_const_type v ) const { return this->is_initialized() ? get() : v ; }
+ reference_type get_value_or ( reference_type v ) { return this->is_initialized() ? get() : v ; }
+
+ // Returns a pointer to the value if this is initialized, otherwise,
+ // the behaviour is UNDEFINED
+ // No-throw
+ pointer_const_type operator->() const { BOOST_ASSERT(this->is_initialized()) ; return this->get_ptr_impl() ; }
+ pointer_type operator->() { BOOST_ASSERT(this->is_initialized()) ; return this->get_ptr_impl() ; }
+
+ // Returns a reference to the value if this is initialized, otherwise,
+ // the behaviour is UNDEFINED
+ // No-throw
+#if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
+ reference_const_type operator *() const& { return this->get() ; }
+ reference_type operator *() & { return this->get() ; }
+ reference_type_of_temporary_wrapper operator *() && { return base::types::move(this->get()) ; }
+#else
+ reference_const_type operator *() const { return this->get() ; }
+ reference_type operator *() { return this->get() ; }
+#endif // !defined BOOST_NO_CXX11_REF_QUALIFIERS
+
+#if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
+ reference_const_type value() const&
+ {
+ if (this->is_initialized())
+ return this->get() ;
+ else
+ throw_exception(bad_optional_access());
+ }
+
+ reference_type value() &
+ {
+ if (this->is_initialized())
+ return this->get() ;
+ else
+ throw_exception(bad_optional_access());
+ }
+
+ reference_type_of_temporary_wrapper value() &&
+ {
+ if (this->is_initialized())
+ return base::types::move(this->get()) ;
+ else
+ throw_exception(bad_optional_access());
+ }
+
+#else
+ reference_const_type value() const
+ {
+ if (this->is_initialized())
+ return this->get() ;
+ else
+ throw_exception(bad_optional_access());
+ }
+
+ reference_type value()
+ {
+ if (this->is_initialized())
+ return this->get() ;
+ else
+ throw_exception(bad_optional_access());
+ }
+#endif
+
+
+#ifndef BOOST_NO_CXX11_REF_QUALIFIERS
+ template
+ value_type value_or ( U&& v ) const&
+ {
+ if (this->is_initialized())
+ return get();
+ else
+ return boost::forward(v);
+ }
+
+ template
+ value_type value_or ( U&& v ) &&
+ {
+ if (this->is_initialized())
+ return base::types::move(get());
+ else
+ return boost::forward(v);
+ }
+#elif !defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+ template
+ value_type value_or ( U&& v ) const
+ {
+ if (this->is_initialized())
+ return get();
+ else
+ return boost::forward(v);
+ }
+#else
+ template
+ value_type value_or ( U const& v ) const
+ {
+ if (this->is_initialized())
+ return get();
+ else
+ return v;
+ }
+
+ template
+ value_type value_or ( U& v ) const
+ {
+ if (this->is_initialized())
+ return get();
+ else
+ return v;
+ }
+#endif
+
+
+#ifndef BOOST_NO_CXX11_REF_QUALIFIERS
+ template
+ value_type value_or_eval ( F f ) const&
+ {
+ if (this->is_initialized())
+ return get();
+ else
+ return f();
+ }
+
+ template
+ value_type value_or_eval ( F f ) &&
+ {
+ if (this->is_initialized())
+ return base::types::move(get());
+ else
+ return f();
+ }
+#else
+ template
+ value_type value_or_eval ( F f ) const
+ {
+ if (this->is_initialized())
+ return get();
+ else
+ return f();
+ }
+#endif
+
+ bool operator!() const BOOST_NOEXCEPT { return !this->is_initialized() ; }
+
+ BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
+} ;
+
+} // namespace boost
+
+
+#endif // header guard
diff --git a/include/boost/optional/detail/optional_aligned_storage.hpp b/include/boost/optional/detail/optional_aligned_storage.hpp
new file mode 100644
index 0000000..c0ad272
--- /dev/null
+++ b/include/boost/optional/detail/optional_aligned_storage.hpp
@@ -0,0 +1,54 @@
+// Copyright (C) 2003, 2008 Fernando Luis Cacciola Carballal.
+// Copyright (C) 2016 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)
+//
+// See http://www.boost.org/libs/optional for documentation.
+//
+// You are welcome to contact the author at:
+// fernando_cacciola@hotmail.com
+// akrzemi1@gmail.com
+
+#ifndef BOOST_OPTIONAL_OPTIONAL_DETAIL_OPTIONAL_ALIGNED_STORAGE_AJK_12FEB2016_HPP
+#define BOOST_OPTIONAL_OPTIONAL_DETAIL_OPTIONAL_ALIGNED_STORAGE_AJK_12FEB2016_HPP
+
+namespace boost {
+
+namespace optional_detail {
+// This local class is used instead of that in "aligned_storage.hpp"
+// because I've found the 'official' class to ICE BCB5.5
+// when some types are used with optional<>
+// (due to sizeof() passed down as a non-type template parameter)
+template
+class aligned_storage
+{
+ // Borland ICEs if unnamed unions are used for this!
+ union
+ // This works around GCC warnings about breaking strict aliasing rules when casting storage address to T*
+#if defined(BOOST_OPTIONAL_DETAIL_USE_ATTRIBUTE_MAY_ALIAS)
+ __attribute__((__may_alias__))
+#endif
+ dummy_u
+ {
+ char data[ sizeof(T) ];
+ BOOST_DEDUCED_TYPENAME type_with_alignment<
+ ::boost::alignment_of::value >::type aligner_;
+ } dummy_ ;
+
+ public:
+
+#if defined(BOOST_OPTIONAL_DETAIL_USE_ATTRIBUTE_MAY_ALIAS)
+ void const* address() const { return &dummy_; }
+ void * address() { return &dummy_; }
+#else
+ void const* address() const { return dummy_.data; }
+ void * address() { return dummy_.data; }
+#endif
+} ;
+
+} // namespace optional_detail
+} // namespace boost
+
+#endif // header guard
diff --git a/include/boost/optional/detail/optional_factory_support.hpp b/include/boost/optional/detail/optional_factory_support.hpp
new file mode 100644
index 0000000..efff92a
--- /dev/null
+++ b/include/boost/optional/detail/optional_factory_support.hpp
@@ -0,0 +1,36 @@
+// Copyright (C) 2003, 2008 Fernando Luis Cacciola Carballal.
+// Copyright (C) 2016 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)
+//
+// See http://www.boost.org/libs/optional for documentation.
+//
+// You are welcome to contact the author at:
+// fernando_cacciola@hotmail.com
+// akrzemi1@gmail.com
+
+#ifndef BOOST_OPTIONAL_OPTIONAL_DETAIL_OPTIONAL_FACTORY_SUPPORT_AJK_12FEB2016_HPP
+#define BOOST_OPTIONAL_OPTIONAL_DETAIL_OPTIONAL_FACTORY_SUPPORT_AJK_12FEB2016_HPP
+
+// Daniel Wallin discovered that bind/apply.hpp badly interacts with the apply<>
+// member template of a factory as used in the optional<> implementation.
+// He proposed this simple fix which is to move the call to apply<> outside
+// namespace boost.
+namespace boost_optional_detail
+{
+ template
+ inline void construct(Factory const& factory, void* address)
+ {
+ factory.BOOST_NESTED_TEMPLATE apply(address);
+ }
+}
+
+namespace boost
+{
+ class in_place_factory_base ;
+ class typed_in_place_factory_base ;
+}
+
+#endif // header guard
diff --git a/include/boost/optional/detail/optional_reference_spec.hpp b/include/boost/optional/detail/optional_reference_spec.hpp
index 79d1869..ecf9869 100644
--- a/include/boost/optional/detail/optional_reference_spec.hpp
+++ b/include/boost/optional/detail/optional_reference_spec.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2015 Andrzej Krzemienski.
+// Copyright (C) 2015-2016 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
@@ -167,9 +167,8 @@ public:
#endif // BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
};
-// TODO: what if no rvalue refs
} // namespace boost
-#endif // 0
+#endif // 1/0
#endif // header guard
diff --git a/include/boost/optional/optional.hpp b/include/boost/optional/optional.hpp
index 9cdc7ea..d73bd62 100644
--- a/include/boost/optional/optional.hpp
+++ b/include/boost/optional/optional.hpp
@@ -39,163 +39,50 @@
#include
#include
#include
-#include
#include
#include
-#include
-#include
-#include
-#include
#include
#include
#include
#include
#include
+#include
+#include
-// Daniel Wallin discovered that bind/apply.hpp badly interacts with the apply<>
-// member template of a factory as used in the optional<> implementation.
-// He proposed this simple fix which is to move the call to apply<> outside
-// namespace boost.
-namespace boost_optional_detail
-{
- template
- inline void construct(Factory const& factory, void* address)
- {
- factory.BOOST_NESTED_TEMPLATE apply(address);
- }
-}
-
+#ifdef BOOST_OPTIONAL_CONFIG_USE_OLD_IMPLEMENTATION_OF_OPTIONAL
+#include
+#else
namespace boost {
-class in_place_factory_base ;
-class typed_in_place_factory_base ;
-
-// This forward is needed to refer to namespace scope swap from the member swap
-template void swap ( optional& x, optional& y );
-
namespace optional_detail {
-// This local class is used instead of that in "aligned_storage.hpp"
-// because I've found the 'official' class to ICE BCB5.5
-// when some types are used with optional<>
-// (due to sizeof() passed down as a non-type template parameter)
-template
-class aligned_storage
-{
- // Borland ICEs if unnamed unions are used for this!
- union
- // This works around GCC warnings about breaking strict aliasing rules when casting storage address to T*
-#if defined(BOOST_OPTIONAL_DETAIL_USE_ATTRIBUTE_MAY_ALIAS)
- __attribute__((__may_alias__))
-#endif
- dummy_u
- {
- char data[ sizeof(T) ];
- BOOST_DEDUCED_TYPENAME type_with_alignment<
- ::boost::alignment_of::value >::type aligner_;
- } dummy_ ;
-
- public:
-
-#if defined(BOOST_OPTIONAL_DETAIL_USE_ATTRIBUTE_MAY_ALIAS)
- void const* address() const { return &dummy_; }
- void * address() { return &dummy_; }
-#else
- void const* address() const { return dummy_.data; }
- void * address() { return dummy_.data; }
-#endif
-} ;
-
-template
-struct types_when_isnt_ref
-{
- typedef T const& reference_const_type ;
- typedef T & reference_type ;
-#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
- typedef T && rval_reference_type ;
- typedef T && reference_type_of_temporary_wrapper;
-#ifdef BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
- // GCC 4.4 has support for an early draft of rvalue references. The conforming version below
- // causes warnings about returning references to a temporary.
- static T&& move(T&& r) { return r; }
-#else
- static rval_reference_type move(reference_type r) { return boost::move(r); }
-#endif
-#endif
- typedef T const* pointer_const_type ;
- typedef T * pointer_type ;
- typedef T const& argument_type ;
-} ;
-
-template
-struct types_when_is_ref
-{
- typedef BOOST_DEDUCED_TYPENAME remove_reference::type raw_type ;
-
- typedef raw_type& reference_const_type ;
- typedef raw_type& reference_type ;
-#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
- typedef BOOST_DEDUCED_TYPENAME remove_const::type&& rval_reference_type ;
- typedef raw_type& reference_type_of_temporary_wrapper;
- static reference_type move(reference_type r) { return r; }
-#endif
- typedef raw_type* pointer_const_type ;
- typedef raw_type* pointer_type ;
- typedef raw_type& argument_type ;
-} ;
-
-template
-void prevent_binding_rvalue_ref_to_optional_lvalue_ref()
-{
-#ifndef BOOST_OPTIONAL_CONFIG_ALLOW_BINDING_TO_RVALUES
- BOOST_STATIC_ASSERT_MSG(
- !boost::is_lvalue_reference::value || !boost::is_rvalue_reference::value,
- "binding rvalue references to optional lvalue references is disallowed");
-#endif
-}
struct optional_tag {} ;
+
template
class optional_base : public optional_tag
{
private :
- typedef
-#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
- BOOST_DEDUCED_TYPENAME
-#endif
- ::boost::detail::make_reference_content::type internal_type ;
-
+ typedef T internal_type ;
typedef aligned_storage storage_type ;
-
- typedef types_when_isnt_ref types_when_not_ref ;
- typedef types_when_is_ref types_when_ref ;
-
typedef optional_base this_type ;
protected :
typedef T value_type ;
- typedef mpl::true_ is_reference_tag ;
- typedef mpl::false_ is_not_reference_tag ;
-
- typedef BOOST_DEDUCED_TYPENAME is_reference::type is_reference_predicate ;
-
- public:
- typedef BOOST_DEDUCED_TYPENAME mpl::if_::type types ;
-
protected:
- typedef BOOST_DEDUCED_TYPENAME types::reference_type reference_type ;
- typedef BOOST_DEDUCED_TYPENAME types::reference_const_type reference_const_type ;
+ typedef T & reference_type ;
+ typedef T const& reference_const_type ;
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
- typedef BOOST_DEDUCED_TYPENAME types::rval_reference_type rval_reference_type ;
- typedef BOOST_DEDUCED_TYPENAME types::reference_type_of_temporary_wrapper reference_type_of_temporary_wrapper ;
+ typedef T && rval_reference_type ;
+ typedef T && reference_type_of_temporary_wrapper ;
#endif
- typedef BOOST_DEDUCED_TYPENAME types::pointer_type pointer_type ;
- typedef BOOST_DEDUCED_TYPENAME types::pointer_const_type pointer_const_type ;
- typedef BOOST_DEDUCED_TYPENAME types::argument_type argument_type ;
+ typedef T * pointer_type ;
+ typedef T const* pointer_const_type ;
+ typedef T const& argument_type ;
// Creates an optional uninitialized.
// No-throw
@@ -295,7 +182,7 @@ class optional_base : public optional_tag
if (is_initialized())
{
if ( rhs.is_initialized() )
- assign_value(rhs.get_impl(), is_reference_predicate() );
+ assign_value(rhs.get_impl());
else destroy();
}
else
@@ -312,7 +199,7 @@ class optional_base : public optional_tag
if (is_initialized())
{
if ( rhs.is_initialized() )
- assign_value(boost::move(rhs.get_impl()), is_reference_predicate() );
+ assign_value( boost::move(rhs.get_impl()) );
else destroy();
}
else
@@ -331,9 +218,9 @@ class optional_base : public optional_tag
{
if ( rhs.is_initialized() )
#ifndef BOOST_OPTIONAL_CONFIG_RESTORE_ASSIGNMENT_OF_NONCONVERTIBLE_TYPES
- assign_value(rhs.get(), is_reference_predicate() );
+ assign_value( rhs.get() );
#else
- assign_value(static_cast(rhs.get()), is_reference_predicate() );
+ assign_value( static_cast(rhs.get()) );
#endif
else destroy();
@@ -358,7 +245,7 @@ class optional_base : public optional_tag
if (is_initialized())
{
if ( rhs.is_initialized() )
- assign_value(static_cast(rhs.get()), is_reference_predicate() );
+ assign_value( static_cast(rhs.get()) );
else destroy();
}
else
@@ -373,7 +260,7 @@ class optional_base : public optional_tag
void assign ( argument_type val )
{
if (is_initialized())
- assign_value(val, is_reference_predicate() );
+ assign_value(val);
else construct(val);
}
@@ -382,7 +269,7 @@ class optional_base : public optional_tag
void assign ( rval_reference_type val )
{
if (is_initialized())
- assign_value( boost::move(val), is_reference_predicate() );
+ assign_value( boost::move(val) );
else construct( boost::move(val) );
}
#endif
@@ -441,7 +328,7 @@ class optional_base : public optional_tag
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
void construct ( rval_reference_type val )
{
- ::new (m_storage.address()) internal_type( types::move(val) ) ;
+ ::new (m_storage.address()) internal_type( boost::move(val) ) ;
m_initialized = true ;
}
#endif
@@ -504,7 +391,6 @@ class optional_base : public optional_tag
template
void construct ( Expr&& factory, in_place_factory_base const* )
{
- BOOST_STATIC_ASSERT ( ::boost::mpl::not_::value ) ;
boost_optional_detail::construct(factory, m_storage.address());
m_initialized = true ;
}
@@ -513,7 +399,6 @@ class optional_base : public optional_tag
template
void construct ( Expr&& factory, typed_in_place_factory_base const* )
{
- BOOST_STATIC_ASSERT ( ::boost::mpl::not_::value ) ;
factory.apply(m_storage.address()) ;
m_initialized = true ;
}
@@ -538,7 +423,6 @@ class optional_base : public optional_tag
template
void construct ( Expr const& factory, in_place_factory_base const* )
{
- BOOST_STATIC_ASSERT ( ::boost::mpl::not_::value ) ;
boost_optional_detail::construct(factory, m_storage.address());
m_initialized = true ;
}
@@ -547,7 +431,6 @@ class optional_base : public optional_tag
template
void construct ( Expr const& factory, typed_in_place_factory_base const* )
{
- BOOST_STATIC_ASSERT ( ::boost::mpl::not_::value ) ;
factory.apply(m_storage.address()) ;
m_initialized = true ;
}
@@ -589,7 +472,7 @@ class optional_base : public optional_tag
template
void assign_expr_to_initialized ( Expr&& expr, void const* )
{
- assign_value(boost::forward(expr), is_reference_predicate());
+ assign_value( boost::forward(expr) );
}
#else
// Constructs using any expression implicitly convertible to the single argument
@@ -610,7 +493,7 @@ class optional_base : public optional_tag
template
void assign_expr_to_initialized ( Expr const& expr, void const* )
{
- assign_value(expr, is_reference_predicate());
+ assign_value(expr);
}
#endif
@@ -637,7 +520,7 @@ class optional_base : public optional_tag
{
// An exception can be thrown here.
// It it happens, THIS will be left uninitialized.
- new (m_storage.address()) internal_type(types::move(expr.get())) ;
+ new (m_storage.address()) internal_type(boost::move(expr.get())) ;
m_initialized = true ;
}
}
@@ -657,24 +540,22 @@ class optional_base : public optional_tag
#endif
#endif // defined BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION
- void assign_value ( argument_type val, is_not_reference_tag ) { get_impl() = val; }
- void assign_value ( argument_type val, is_reference_tag ) { construct(val); }
+ void assign_value ( argument_type val ) { get_impl() = val; }
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
- void assign_value ( rval_reference_type val, is_not_reference_tag ) { get_impl() = static_cast(val); }
- void assign_value ( rval_reference_type val, is_reference_tag ) { construct( static_cast(val) ); }
+ void assign_value ( rval_reference_type val ) { get_impl() = static_cast(val); }
#endif
void destroy()
{
if ( m_initialized )
- destroy_impl(is_reference_predicate()) ;
+ destroy_impl() ;
}
- reference_const_type get_impl() const { return dereference(get_object(), is_reference_predicate() ) ; }
- reference_type get_impl() { return dereference(get_object(), is_reference_predicate() ) ; }
+ reference_const_type get_impl() const { return dereference(get_object()) ; }
+ reference_type get_impl() { return dereference(get_object()) ; }
- pointer_const_type get_ptr_impl() const { return cast_ptr(get_object(), is_reference_predicate() ) ; }
- pointer_type get_ptr_impl() { return cast_ptr(get_object(), is_reference_predicate() ) ; }
+ pointer_const_type get_ptr_impl() const { return cast_ptr(get_object()) ; }
+ pointer_type get_ptr_impl() { return cast_ptr(get_object()) ; }
private :
@@ -697,26 +578,21 @@ class optional_base : public optional_tag
#endif
// reference_content lacks an implicit conversion to T&, so the following is needed to obtain a proper reference.
- reference_const_type dereference( internal_type const* p, is_not_reference_tag ) const { return *p ; }
- reference_type dereference( internal_type* p, is_not_reference_tag ) { return *p ; }
- reference_const_type dereference( internal_type const* p, is_reference_tag ) const { return p->get() ; }
- reference_type dereference( internal_type* p, is_reference_tag ) { return p->get() ; }
+ reference_const_type dereference( internal_type const* p ) const { return *p ; }
+ reference_type dereference( internal_type* p ) { return *p ; }
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581))
- void destroy_impl ( is_not_reference_tag ) { get_ptr_impl()->internal_type::~internal_type() ; m_initialized = false ; }
+ void destroy_impl ( ) { get_ptr_impl()->internal_type::~internal_type() ; m_initialized = false ; }
#else
- void destroy_impl ( is_not_reference_tag ) { get_ptr_impl()->~T() ; m_initialized = false ; }
+ void destroy_impl ( ) { get_ptr_impl()->~T() ; m_initialized = false ; }
#endif
- void destroy_impl ( is_reference_tag ) { m_initialized = false ; }
// If T is of reference type, trying to get a pointer to the held value must result in a compile-time error.
// Decent compilers should disallow conversions from reference_content* to T*, but just in case,
// the following olverloads are used to filter out the case and guarantee an error in case of T being a reference.
- pointer_const_type cast_ptr( internal_type const* p, is_not_reference_tag ) const { return p ; }
- pointer_type cast_ptr( internal_type * p, is_not_reference_tag ) { return p ; }
- pointer_const_type cast_ptr( internal_type const* p, is_reference_tag ) const { return &p->get() ; }
- pointer_type cast_ptr( internal_type * p, is_reference_tag ) { return &p->get() ; }
+ pointer_const_type cast_ptr( internal_type const* p ) const { return p ; }
+ pointer_type cast_ptr( internal_type * p ) { return p ; }
bool m_initialized ;
storage_type m_storage ;
@@ -760,7 +636,7 @@ class optional : public optional_detail::optional_base
// Creates an optional initialized with 'move(val)'.
// Can throw if T::T(T &&) does
optional ( rval_reference_type val ) : base( boost::forward(val) )
- {optional_detail::prevent_binding_rvalue_ref_to_optional_lvalue_ref();}
+ {}
#endif
// Creates an optional initialized with 'val' IFF cond is true, otherwise creates an uninitialized optional.
@@ -815,7 +691,7 @@ class optional : public optional_detail::optional_base
boost::is_same::type, none_t>::value >::type* = 0
)
: base(boost::forward(expr),boost::addressof(expr))
- {optional_detail::prevent_binding_rvalue_ref_to_optional_lvalue_ref();}
+ {}
#else
template
@@ -852,7 +728,6 @@ class optional : public optional_detail::optional_base
>::type
operator= ( Expr&& expr )
{
- optional_detail::prevent_binding_rvalue_ref_to_optional_lvalue_ref();
this->assign_expr(boost::forward(expr),boost::addressof(expr));
return *this ;
}
@@ -920,7 +795,6 @@ class optional : public optional_detail::optional_base
// Assigns from a T (deep-moves the rhs value)
optional& operator= ( rval_reference_type val )
{
- optional_detail::prevent_binding_rvalue_ref_to_optional_lvalue_ref();
this->assign( boost::move(val) ) ;
return *this ;
}
@@ -1003,7 +877,7 @@ class optional : public optional_detail::optional_base
#if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
reference_const_type operator *() const& { return this->get() ; }
reference_type operator *() & { return this->get() ; }
- reference_type_of_temporary_wrapper operator *() && { return base::types::move(this->get()) ; }
+ reference_type_of_temporary_wrapper operator *() && { return boost::move(this->get()) ; }
#else
reference_const_type operator *() const { return this->get() ; }
reference_type operator *() { return this->get() ; }
@@ -1029,7 +903,7 @@ class optional : public optional_detail::optional_base
reference_type_of_temporary_wrapper value() &&
{
if (this->is_initialized())
- return base::types::move(this->get()) ;
+ return boost::move(this->get()) ;
else
throw_exception(bad_optional_access());
}
@@ -1067,7 +941,7 @@ class optional : public optional_detail::optional_base
value_type value_or ( U&& v ) &&
{
if (this->is_initialized())
- return base::types::move(get());
+ return boost::move(get());
else
return boost::forward(v);
}
@@ -1115,7 +989,7 @@ class optional : public optional_detail::optional_base
value_type value_or_eval ( F f ) &&
{
if (this->is_initialized())
- return base::types::move(get());
+ return boost::move(get());
else
return f();
}
@@ -1135,6 +1009,12 @@ class optional : public optional_detail::optional_base
BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
} ;
+} // namespace boost
+
+#endif // BOOST_OPTIONAL_CONFIG_USE_OLD_IMPLEMENTATION_OF_OPTIONAL
+
+namespace boost {
+
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
template
class optional