diff --git a/doc/91_relnotes.qbk b/doc/91_relnotes.qbk index eb2b310..297a360 100644 --- a/doc/91_relnotes.qbk +++ b/doc/91_relnotes.qbk @@ -11,6 +11,11 @@ [section:relnotes Release Notes] +[heading Boost Release X.XX] + +* Changed the implementation of `boost::none`: now it is a constant with internal linkage. This addresses [@https://svn.boost.org/trac/boost/ticket/11203 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. + [heading Boost Release 1.59] * For C++03 compilers, added 0-argument overload for member function `emplace()`, and therewith removed the dependency on ``. diff --git a/doc/html/boost_optional/relnotes.html b/doc/html/boost_optional/relnotes.html index 445eaa8..bac08cc 100644 --- a/doc/html/boost_optional/relnotes.html +++ b/doc/html/boost_optional/relnotes.html @@ -28,6 +28,23 @@

+ Boost + Release X.XX +

+
+

+ Boost Release 1.59

@@ -36,7 +53,7 @@ and therewith removed the dependency on <boost/utility/in_place_factory.hpp>.

- + Boost Release 1.58

@@ -72,7 +89,7 @@

- + Boost Release 1.57

@@ -82,7 +99,7 @@ to fix C++03 compile error on logic_error("...")".

- + Boost Release 1.56

diff --git a/doc/html/index.html b/doc/html/index.html index 833a9f6..558d7e2 100644 --- a/doc/html/index.html +++ b/doc/html/index.html @@ -146,7 +146,7 @@ - +

Last revised: October 01, 2015 at 13:19:55 GMT

Last revised: October 05, 2015 at 14:34:49 GMT


diff --git a/include/boost/optional/detail/optional_config.hpp b/include/boost/optional/detail/optional_config.hpp new file mode 100644 index 0000000..c069c0d --- /dev/null +++ b/include/boost/optional/detail/optional_config.hpp @@ -0,0 +1,55 @@ +// Copyright (C) 2003, 2008 Fernando Luis Cacciola Carballal. +// Copyright (C) 2015 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: +// akrzemi1@gmail.com + +#ifndef BOOST_OPTIONAL_DETAIL_OPTIONAL_CONFIG_AJK_28JAN2015_HPP +#define BOOST_OPTIONAL_DETAIL_OPTIONAL_CONFIG_AJK_28JAN2015_HPP + +#include +#include + +#if (defined BOOST_NO_CXX11_RVALUE_REFERENCES) || (defined BOOST_OPTIONAL_CONFIG_NO_RVALUE_REFERENCES) +# define BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES +#endif + +#if BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION,<=700) +// AFAICT only Intel 7 correctly resolves the overload set +// that includes the in-place factory taking functions, +// so for the other icc versions, in-place factory support +// is disabled +# define BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT +#endif + +#if BOOST_WORKAROUND(__BORLANDC__, <= 0x551) +// BCB (5.5.1) cannot parse the nested template struct in an inplace factory. +# define BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT +#endif + +#if !defined(BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT) \ + && defined BOOST_BCB_PARTIAL_SPECIALIZATION_BUG +// BCB (up to 5.64) has the following bug: +// If there is a member function/operator template of the form +// template mfunc( Expr expr ) ; +// some calls are resolved to this even if there are other better matches. +// The effect of this bug is that calls to converting ctors and assignments +// are incorrectly sink to this general catch-all member function template as shown above. +# define BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION +#endif + +#if defined(__GNUC__) && !defined(__INTEL_COMPILER) +// GCC since 3.3 has may_alias attribute that helps to alleviate optimizer issues with +// regard to violation of the strict aliasing rules. The optional< T > storage type is marked +// with this attribute in order to let the compiler know that it will alias objects of type T +// and silence compilation warnings. +# define BOOST_OPTIONAL_DETAIL_USE_ATTRIBUTE_MAY_ALIAS +#endif + +#endif // header guard diff --git a/include/boost/optional/detail/optional_reference_spec.hpp b/include/boost/optional/detail/optional_reference_spec.hpp new file mode 100644 index 0000000..5a76a68 --- /dev/null +++ b/include/boost/optional/detail/optional_reference_spec.hpp @@ -0,0 +1,164 @@ +// Copyright (C) 2015 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: +// akrzemi1@gmail.com + +#ifndef BOOST_OPTIONAL_DETAIL_OPTIONAL_REFERENCE_SPEC_AJK_03OCT2015_HPP +#define BOOST_OPTIONAL_DETAIL_OPTIONAL_REFERENCE_SPEC_AJK_03OCT2015_HPP + +# if 1 + +namespace boost { + +namespace detail { + +template +void prevent_binding_rvalue() +{ +#ifndef BOOST_OPTIONAL_CONFIG_ALLOW_BINDING_TO_RVALUES + BOOST_STATIC_ASSERT_MSG(boost::is_lvalue_reference::value, + "binding rvalue references to optional lvalue references is disallowed"); +#endif +} + +template +typename boost::remove_reference::type& forward_reference(T&& r) +{ + BOOST_STATIC_ASSERT_MSG(boost::is_lvalue_reference::value, + "binding rvalue references to optional lvalue references is disallowed"); + return boost::forward(r); +} + +template +struct is_optional_ +{ + static const bool value = false; +}; + +template +struct is_optional_<::boost::optional> +{ + static const bool value = true; +}; + +template +struct is_no_optional +{ + static const bool value = !is_optional_::type>::value; +}; + +} // namespace detail + +template +class optional : public optional_detail::optional_tag +{ + T* ptr_; + +public: + typedef T& value_type; + typedef T& reference_type; + typedef T& reference_const_type; + typedef T* pointer_type; + typedef T* pointer_const_type; + + optional() BOOST_NOEXCEPT : ptr_() {} + optional(none_t) BOOST_NOEXCEPT : ptr_() {} + + template + explicit optional(const optional& rhs) BOOST_NOEXCEPT : ptr_(rhs.ptr_) {} + optional(const optional& rhs) BOOST_NOEXCEPT : ptr_(rhs.ptr_) {} + + + optional& operator=(const optional& rhs) BOOST_NOEXCEPT { ptr_ = rhs.ptr_; return *this; } + template + optional& operator=(const optional& rhs) BOOST_NOEXCEPT { ptr_ = rhs.ptr_; return *this; } + optional& operator=(none_t) BOOST_NOEXCEPT { ptr_ = 0; return *this; } + + + void swap(optional& rhs) BOOST_NOEXCEPT { std::swap(ptr_, rhs.ptr_); } + T& get() const { BOOST_ASSERT(ptr_); return *ptr_; } + + T* get_ptr() const BOOST_NOEXCEPT { return ptr_; } + T* operator->() const { BOOST_ASSERT(ptr_); return ptr_; } + T& operator*() const { BOOST_ASSERT(ptr_); return *ptr_; } + T& value() const { return ptr_ ? *ptr_ : (throw_exception(bad_optional_access()), *ptr_); } + + + template + T& value_or_eval(F f) const { return ptr_ ? *ptr_ : detail::forward_reference(f()); } + + bool operator!() const BOOST_NOEXCEPT { return ptr_ == 0; } + BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT() + + void reset() BOOST_NOEXCEPT { ptr_ = 0; } + + bool is_initialized() const BOOST_NOEXCEPT { return ptr_ != 0; } + +#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES + + template + optional(R&& r, BOOST_DEDUCED_TYPENAME boost::enable_if >::type* = 0) BOOST_NOEXCEPT + : ptr_(boost::addressof(r)) { detail::prevent_binding_rvalue(); } + + template + optional(bool cond, R&& r, BOOST_DEDUCED_TYPENAME boost::enable_if >::type* = 0) BOOST_NOEXCEPT + : ptr_(cond ? boost::addressof(r) : 0) { detail::prevent_binding_rvalue(); } + + template + BOOST_DEDUCED_TYPENAME boost::enable_if, optional&>::type + operator=(R&& r) BOOST_NOEXCEPT { detail::prevent_binding_rvalue(); ptr_ = boost::addressof(r); return *this; } + + template + void emplace(R&& r, BOOST_DEDUCED_TYPENAME boost::enable_if >::type* = 0) BOOST_NOEXCEPT + { detail::prevent_binding_rvalue(); ptr_ = boost::addressof(r); } + + template + T& get_value_or(R&& r, BOOST_DEDUCED_TYPENAME boost::enable_if >::type* = 0) const BOOST_NOEXCEPT + { detail::prevent_binding_rvalue(); return ptr_ ? *ptr_ : r; } + + template + T& value_or(R&& r, BOOST_DEDUCED_TYPENAME boost::enable_if >::type* = 0) const BOOST_NOEXCEPT + { detail::prevent_binding_rvalue(); return ptr_ ? *ptr_ : r; } + + template + void reset(R&& r, BOOST_DEDUCED_TYPENAME boost::enable_if >::type* = 0) BOOST_NOEXCEPT + { detail::prevent_binding_rvalue(); ptr_ = boost::addressof(r); } + +#else // BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES + + template + optional(const U& v) BOOST_NOEXCEPT : ptr_(boost::addressof(v)) { } + + template + optional(bool cond, const U& v) BOOST_NOEXCEPT : ptr_(cond ? boost::addressof(v) : 0) {} + + template + optional operator=(const U& v) BOOST_NOEXCEPT { ptr_ = boost::addressof(v); return *this; } + + template + void emplace(const U& v) BOOST_NOEXCEPT { ptr_ = boost::addressof(v); } + + template + T& get_value_or(const U& v) const BOOST_NOEXCEPT { return ptr_ ? *ptr_ : v; } + + template + T& value_or(const U& v) const BOOST_NOEXCEPT { return ptr_ ? *ptr_ : v; } + + template + void reset(const U& v) BOOST_NOEXCEPT { ptr_ = boost::addressof(v); } + +#endif // BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES +}; + +// TODO: what if no rvalue refs +} // namespace boost + +#endif // 0 + +#endif // header guard diff --git a/include/boost/optional/detail/optional_relops.hpp b/include/boost/optional/detail/optional_relops.hpp new file mode 100644 index 0000000..f3ebae0 --- /dev/null +++ b/include/boost/optional/detail/optional_relops.hpp @@ -0,0 +1,195 @@ +// Copyright (C) 2003, 2008 Fernando Luis Cacciola Carballal. +// Copyright (C) 2015 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: +// akrzemi1@gmail.com + +#ifndef BOOST_OPTIONAL_DETAIL_OPTIONAL_RELOPS_AJK_03OCT2015_HPP +#define BOOST_OPTIONAL_DETAIL_OPTIONAL_RELOPS_AJK_03OCT2015_HPP + +namespace boost { + +// optional's relational operators ( ==, !=, <, >, <=, >= ) have deep-semantics (compare values). +// WARNING: This is UNLIKE pointers. Use equal_pointees()/less_pointess() in generic code instead. + + +// +// optional vs optional cases +// + +template +inline +bool operator == ( optional const& x, optional const& y ) +{ return equal_pointees(x,y); } + +template +inline +bool operator < ( optional const& x, optional const& y ) +{ return less_pointees(x,y); } + +template +inline +bool operator != ( optional const& x, optional const& y ) +{ return !( x == y ) ; } + +template +inline +bool operator > ( optional const& x, optional const& y ) +{ return y < x ; } + +template +inline +bool operator <= ( optional const& x, optional const& y ) +{ return !( y < x ) ; } + +template +inline +bool operator >= ( optional const& x, optional const& y ) +{ return !( x < y ) ; } + + +// +// optional vs T cases +// +template +inline +bool operator == ( optional const& x, T const& y ) +{ return equal_pointees(x, optional(y)); } + +template +inline +bool operator < ( optional const& x, T const& y ) +{ return less_pointees(x, optional(y)); } + +template +inline +bool operator != ( optional const& x, T const& y ) +{ return !( x == y ) ; } + +template +inline +bool operator > ( optional const& x, T const& y ) +{ return y < x ; } + +template +inline +bool operator <= ( optional const& x, T const& y ) +{ return !( y < x ) ; } + +template +inline +bool operator >= ( optional const& x, T const& y ) +{ return !( x < y ) ; } + +// +// T vs optional cases +// + +template +inline +bool operator == ( T const& x, optional const& y ) +{ return equal_pointees( optional(x), y ); } + +template +inline +bool operator < ( T const& x, optional const& y ) +{ return less_pointees( optional(x), y ); } + +template +inline +bool operator != ( T const& x, optional const& y ) +{ return !( x == y ) ; } + +template +inline +bool operator > ( T const& x, optional const& y ) +{ return y < x ; } + +template +inline +bool operator <= ( T const& x, optional const& y ) +{ return !( y < x ) ; } + +template +inline +bool operator >= ( T const& x, optional const& y ) +{ return !( x < y ) ; } + + +// +// optional vs none cases +// + +template +inline +bool operator == ( optional const& x, none_t ) BOOST_NOEXCEPT +{ return !x; } + +template +inline +bool operator < ( optional const& x, none_t ) +{ return less_pointees(x,optional() ); } + +template +inline +bool operator != ( optional const& x, none_t ) BOOST_NOEXCEPT +{ return bool(x); } + +template +inline +bool operator > ( optional const& x, none_t y ) +{ return y < x ; } + +template +inline +bool operator <= ( optional const& x, none_t y ) +{ return !( y < x ) ; } + +template +inline +bool operator >= ( optional const& x, none_t y ) +{ return !( x < y ) ; } + +// +// none vs optional cases +// + +template +inline +bool operator == ( none_t , optional const& y ) BOOST_NOEXCEPT +{ return !y; } + +template +inline +bool operator < ( none_t , optional const& y ) +{ return less_pointees(optional() ,y); } + +template +inline +bool operator != ( none_t, optional const& y ) BOOST_NOEXCEPT +{ return bool(y); } + +template +inline +bool operator > ( none_t x, optional const& y ) +{ return y < x ; } + +template +inline +bool operator <= ( none_t x, optional const& y ) +{ return !( y < x ) ; } + +template +inline +bool operator >= ( none_t x, optional const& y ) +{ return !( x < y ) ; } + +} // namespace boost + +#endif // header guard \ No newline at end of file diff --git a/include/boost/optional/detail/optional_swap.hpp b/include/boost/optional/detail/optional_swap.hpp new file mode 100644 index 0000000..2a7059e --- /dev/null +++ b/include/boost/optional/detail/optional_swap.hpp @@ -0,0 +1,117 @@ +// Copyright (C) 2003, 2008 Fernando Luis Cacciola Carballal. +// Copyright (C) 2015 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: +// akrzemi1@gmail.com + +#ifndef BOOST_OPTIONAL_DETAIL_OPTIONAL_SWAP_AJK_28JAN2015_HPP +#define BOOST_OPTIONAL_DETAIL_OPTIONAL_SWAP_AJK_28JAN2015_HPP + +#include +#include + +namespace boost { + +namespace optional_detail { + +template struct swap_selector; + +template <> +struct swap_selector +{ + template + static void optional_swap ( optional& x, optional& y ) + { + const bool hasX = !!x; + const bool hasY = !!y; + + if ( !hasX && !hasY ) + return; + + if( !hasX ) + x.emplace(); + else if ( !hasY ) + y.emplace(); + + // Boost.Utility.Swap will take care of ADL and workarounds for broken compilers + boost::swap(x.get(), y.get()); + + if( !hasX ) + y = boost::none ; + else if( !hasY ) + x = boost::none ; + } +}; + +#ifdef BOOST_OPTIONAL_DETAIL_MOVE +# undef BOOST_OPTIONAL_DETAIL_MOVE +#endif + +#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES +# define BOOST_OPTIONAL_DETAIL_MOVE(EXPR_) boost::move(EXPR_) +#else +# define BOOST_OPTIONAL_DETAIL_MOVE(EXPR_) EXPR_ +#endif + +template <> +struct swap_selector +{ + template + static void optional_swap ( optional& x, optional& y ) + //BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible::value && BOOST_NOEXCEPT_EXPR(boost::swap(*x, *y))) + { + if (x) + { + if (y) + { + boost::swap(*x, *y); + } + else + { + y = BOOST_OPTIONAL_DETAIL_MOVE(*x); + x = boost::none; + } + } + else + { + if (y) + { + x = BOOST_OPTIONAL_DETAIL_MOVE(*y); + y = boost::none; + } + } + } +}; + +} // namespace optional_detail + +#if (!defined BOOST_NO_CXX11_RVALUE_REFERENCES) && (!defined BOOST_CONFIG_RESTORE_OBSOLETE_SWAP_IMPLEMENTATION) + +template +struct optional_swap_should_use_default_constructor : boost::false_type {} ; + +#else + +template +struct optional_swap_should_use_default_constructor : has_nothrow_default_constructor {} ; + +#endif + +template +inline void swap ( optional& x, optional& y ) +//BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible::value && BOOST_NOEXCEPT_EXPR(boost::swap(*x, *y))) +{ + optional_detail::swap_selector::value>::optional_swap(x, y); +} + +} // namespace boost + +#undef BOOST_OPTIONAL_DETAIL_MOVE + +#endif // header guard diff --git a/include/boost/optional/optional.hpp b/include/boost/optional/optional.hpp index 9def94e..9cdc7ea 100644 --- a/include/boost/optional/optional.hpp +++ b/include/boost/optional/optional.hpp @@ -20,7 +20,6 @@ #include #include -#include #include #include #include @@ -52,42 +51,7 @@ #include #include - -#if (defined BOOST_NO_CXX11_RVALUE_REFERENCES) || (defined BOOST_OPTIONAL_CONFIG_NO_RVALUE_REFERENCES) -#define BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES -#endif - -#if BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION,<=700) -// AFAICT only Intel 7 correctly resolves the overload set -// that includes the in-place factory taking functions, -// so for the other icc versions, in-place factory support -// is disabled -#define BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT -#endif - -#if BOOST_WORKAROUND(__BORLANDC__, <= 0x551) -// BCB (5.5.1) cannot parse the nested template struct in an inplace factory. -#define BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT -#endif - -#if !defined(BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT) \ - && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581) ) -// BCB (up to 5.64) has the following bug: -// If there is a member function/operator template of the form -// template mfunc( Expr expr ) ; -// some calls are resolved to this even if there are other better matches. -// The effect of this bug is that calls to converting ctors and assignments -// are incrorrectly sink to this general catch-all member function template as shown above. -#define BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION -#endif - -#if defined(__GNUC__) && !defined(__INTEL_COMPILER) -// GCC since 3.3 has may_alias attribute that helps to alleviate optimizer issues with -// regard to violation of the strict aliasing rules. The optional< T > storage type is marked -// with this attribute in order to let the compiler know that it will alias objects of type T -// and silence compilation warnings. -#define BOOST_OPTIONAL_DETAIL_USE_ATTRIBUTE_MAY_ALIAS -#endif +#include // Daniel Wallin discovered that bind/apply.hpp badly interacts with the apply<> // member template of a factory as used in the optional<> implementation. @@ -102,7 +66,6 @@ namespace boost_optional_detail } } - namespace boost { class in_place_factory_base ; @@ -252,7 +215,7 @@ class optional_base : public optional_tag : m_initialized(false) { - construct(val); + construct(val); } #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES @@ -1180,6 +1143,14 @@ class optional } ; #endif +} // namespace boost + +#ifndef BOOST_OPTIONAL_CONFIG_DONT_SPECIALIZE_OPTIONAL_REFS +# include +#endif + +namespace boost { + // Returns optional(v) template inline @@ -1277,291 +1248,9 @@ operator<<(std::basic_ostream& os, optional_detail::optiona return os; } -// optional's relational operators ( ==, !=, <, >, <=, >= ) have deep-semantics (compare values). -// WARNING: This is UNLIKE pointers. Use equal_pointees()/less_pointess() in generic code instead. - - -// -// optional vs optional cases -// - -template -inline -bool operator == ( optional const& x, optional const& y ) -{ return equal_pointees(x,y); } - -template -inline -bool operator < ( optional const& x, optional const& y ) -{ return less_pointees(x,y); } - -template -inline -bool operator != ( optional const& x, optional const& y ) -{ return !( x == y ) ; } - -template -inline -bool operator > ( optional const& x, optional const& y ) -{ return y < x ; } - -template -inline -bool operator <= ( optional const& x, optional const& y ) -{ return !( y < x ) ; } - -template -inline -bool operator >= ( optional const& x, optional const& y ) -{ return !( x < y ) ; } - - -// -// optional vs T cases -// -template -inline -bool operator == ( optional const& x, T const& y ) -{ return equal_pointees(x, optional(y)); } - -template -inline -bool operator < ( optional const& x, T const& y ) -{ return less_pointees(x, optional(y)); } - -template -inline -bool operator != ( optional const& x, T const& y ) -{ return !( x == y ) ; } - -template -inline -bool operator > ( optional const& x, T const& y ) -{ return y < x ; } - -template -inline -bool operator <= ( optional const& x, T const& y ) -{ return !( y < x ) ; } - -template -inline -bool operator >= ( optional const& x, T const& y ) -{ return !( x < y ) ; } - -// -// T vs optional cases -// - -template -inline -bool operator == ( T const& x, optional const& y ) -{ return equal_pointees( optional(x), y ); } - -template -inline -bool operator < ( T const& x, optional const& y ) -{ return less_pointees( optional(x), y ); } - -template -inline -bool operator != ( T const& x, optional const& y ) -{ return !( x == y ) ; } - -template -inline -bool operator > ( T const& x, optional const& y ) -{ return y < x ; } - -template -inline -bool operator <= ( T const& x, optional const& y ) -{ return !( y < x ) ; } - -template -inline -bool operator >= ( T const& x, optional const& y ) -{ return !( x < y ) ; } - - -// -// optional vs none cases -// - -template -inline -bool operator == ( optional const& x, none_t ) BOOST_NOEXCEPT -{ return !x; } - -template -inline -bool operator < ( optional const& x, none_t ) -{ return less_pointees(x,optional() ); } - -template -inline -bool operator != ( optional const& x, none_t ) BOOST_NOEXCEPT -{ return bool(x); } - -template -inline -bool operator > ( optional const& x, none_t y ) -{ return y < x ; } - -template -inline -bool operator <= ( optional const& x, none_t y ) -{ return !( y < x ) ; } - -template -inline -bool operator >= ( optional const& x, none_t y ) -{ return !( x < y ) ; } - -// -// none vs optional cases -// - -template -inline -bool operator == ( none_t , optional const& y ) BOOST_NOEXCEPT -{ return !y; } - -template -inline -bool operator < ( none_t , optional const& y ) -{ return less_pointees(optional() ,y); } - -template -inline -bool operator != ( none_t, optional const& y ) BOOST_NOEXCEPT -{ return bool(y); } - -template -inline -bool operator > ( none_t x, optional const& y ) -{ return y < x ; } - -template -inline -bool operator <= ( none_t x, optional const& y ) -{ return !( y < x ) ; } - -template -inline -bool operator >= ( none_t x, optional const& y ) -{ return !( x < y ) ; } - -namespace optional_detail { - -template struct swap_selector; - -template<> -struct swap_selector -{ - template - static void optional_swap ( optional& x, optional& y ) - { - const bool hasX = !!x; - const bool hasY = !!y; - - if ( !hasX && !hasY ) - return; - - if( !hasX ) - x.emplace(); - else if ( !hasY ) - y.emplace(); - - // Boost.Utility.Swap will take care of ADL and workarounds for broken compilers - boost::swap(x.get(),y.get()); - - if( !hasX ) - y = boost::none ; - else if( !hasY ) - x = boost::none ; - } -}; - -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES -template<> -struct swap_selector -{ - template - static void optional_swap ( optional& x, optional& y ) - //BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible::value && BOOST_NOEXCEPT_EXPR(boost::swap(*x, *y))) - { - if(x) - { - if (y) - { - boost::swap(*x, *y); - } - else - { - y = boost::move(*x); - x = boost::none; - } - } - else - { - if (y) - { - x = boost::move(*y); - y = boost::none; - } - } - } -}; -#else -template<> -struct swap_selector -{ - template - static void optional_swap ( optional& x, optional& y ) - { - const bool hasX = !!x; - const bool hasY = !!y; - - if ( !hasX && hasY ) - { - x = y.get(); - y = boost::none ; - } - else if ( hasX && !hasY ) - { - y = x.get(); - x = boost::none ; - } - else if ( hasX && hasY ) - { - // Boost.Utility.Swap will take care of ADL and workarounds for broken compilers - boost::swap(x.get(),y.get()); - } - } -}; -#endif // !defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES - -} // namespace optional_detail - -#if (!defined BOOST_NO_CXX11_RVALUE_REFERENCES) && (!defined BOOST_CONFIG_RESTORE_OBSOLETE_SWAP_IMPLEMENTATION) - -template -struct optional_swap_should_use_default_constructor : boost::false_type {} ; - -#else - -template -struct optional_swap_should_use_default_constructor : has_nothrow_default_constructor {} ; - -#endif //BOOST_NO_CXX11_RVALUE_REFERENCES - -template inline void swap ( optional& x, optional& y ) - //BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible::value && BOOST_NOEXCEPT_EXPR(boost::swap(*x, *y))) -{ - optional_detail::swap_selector::value>::optional_swap(x, y); -} - } // namespace boost -#endif +#include +#include + +#endif // header guard