From 545f8933bc414779899f82c248cf3f09535f84ff Mon Sep 17 00:00:00 2001 From: Andrey Semashev Date: Sat, 18 Dec 2010 21:29:39 +0000 Subject: [PATCH] Merged changes from trunk: add namespace scope swap forward declaration to fix member swap copmilation. Swap implementation now uses Boost.Utility.Swap. Fixes #4987. [SVN r67307] --- include/boost/optional/optional.hpp | 143 +++++++++++++--------------- 1 file changed, 65 insertions(+), 78 deletions(-) diff --git a/include/boost/optional/optional.hpp b/include/boost/optional/optional.hpp index 2b066e9..ec9006e 100644 --- a/include/boost/optional/optional.hpp +++ b/include/boost/optional/optional.hpp @@ -18,24 +18,25 @@ #include #include -#include "boost/config.hpp" -#include "boost/assert.hpp" -#include "boost/type.hpp" -#include "boost/type_traits/alignment_of.hpp" -#include "boost/type_traits/has_nothrow_constructor.hpp" -#include "boost/type_traits/type_with_alignment.hpp" -#include "boost/type_traits/remove_reference.hpp" -#include "boost/type_traits/is_reference.hpp" -#include "boost/mpl/if.hpp" -#include "boost/mpl/bool.hpp" -#include "boost/mpl/not.hpp" -#include "boost/detail/reference_content.hpp" -#include "boost/none.hpp" -#include "boost/utility/addressof.hpp" -#include "boost/utility/compare_pointees.hpp" -#include "boost/utility/in_place_factory.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -#include "boost/optional/optional_fwd.hpp" +#include #if BOOST_WORKAROUND(BOOST_MSVC, == 1200) // VC6.0 has the following bug: @@ -98,7 +99,7 @@ namespace boost_optional_detail { template - void construct(Factory const& factory, void* address) + inline void construct(Factory const& factory, void* address) { factory.BOOST_NESTED_TEMPLATE apply(address); } @@ -110,6 +111,9 @@ 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" @@ -615,7 +619,7 @@ class optional : public optional_detail::optional_base void swap( optional & arg ) { // allow for Koenig lookup - using boost::swap ; + using boost::swap; swap(*this, arg); } @@ -914,79 +918,63 @@ inline bool operator >= ( none_t x, optional const& y ) { return !( x < y ) ; } -// -// The following swap implementation follows the GCC workaround as found in -// "boost/detail/compressed_pair.hpp" -// namespace optional_detail { -// GCC < 3.2 gets the using declaration at namespace scope (FLC, DWA) -#if BOOST_WORKAROUND(__GNUC__, < 3) \ - || BOOST_WORKAROUND(__GNUC__, == 3) && __GNUC_MINOR__ <= 2 - using std::swap; -#define BOOST_OPTIONAL_STD_SWAP_INTRODUCED_AT_NS_SCOPE -#endif +template struct swap_selector; - template struct swap_selector; - - template<> - struct swap_selector - { +template<> +struct swap_selector +{ template static void optional_swap ( optional& x, optional& y ) { - bool hasX = x; - bool hasY = y; + const bool hasX = !!x; + const bool hasY = !!y; - if ( !hasX && !hasY ) - return; + if ( !hasX && !hasY ) + return; - if( !hasX ) - x = boost::in_place(); - else if ( !hasY ) - y = boost::in_place(); + if( !hasX ) + x = boost::in_place(); + else if ( !hasY ) + y = boost::in_place(); - // GCC > 3.2 and all other compilers have the using declaration at function scope (FLC) -#ifndef BOOST_OPTIONAL_STD_SWAP_INTRODUCED_AT_NS_SCOPE - // allow for Koenig lookup - using std::swap ; -#endif - swap(*x,*y); + // 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 ; + if( !hasX ) + y = boost::none ; + else if( !hasY ) + x = boost::none ; } - }; +}; - template<> - struct swap_selector - { +template<> +struct swap_selector +{ template static void optional_swap ( optional& x, optional& y ) { - if ( !x && !!y ) - { - x = *y; - y = boost::none ; - } - else if ( !!x && !y ) - { - y = *x ; - x = boost::none ; - } - else if ( !!x && !!y ) - { - // GCC > 3.2 and all other compilers have the using declaration at function scope (FLC) - #ifndef BOOST_OPTIONAL_STD_SWAP_INTRODUCED_AT_NS_SCOPE - // allow for Koenig lookup - using std::swap ; - #endif - swap(*x,*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()); + } } - }; +}; } // namespace optional_detail @@ -995,10 +983,9 @@ struct optional_swap_should_use_default_constructor : has_nothrow_default_constr template inline void swap ( optional& x, optional& y ) { - optional_detail::swap_selector::value>::optional_swap(x, y); + optional_detail::swap_selector::value>::optional_swap(x, y); } } // namespace boost #endif -