forked from boostorg/optional
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]
This commit is contained in:
@ -18,24 +18,25 @@
|
|||||||
#include <new>
|
#include <new>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include "boost/config.hpp"
|
#include <boost/config.hpp>
|
||||||
#include "boost/assert.hpp"
|
#include <boost/assert.hpp>
|
||||||
#include "boost/type.hpp"
|
#include <boost/type.hpp>
|
||||||
#include "boost/type_traits/alignment_of.hpp"
|
#include <boost/type_traits/alignment_of.hpp>
|
||||||
#include "boost/type_traits/has_nothrow_constructor.hpp"
|
#include <boost/type_traits/has_nothrow_constructor.hpp>
|
||||||
#include "boost/type_traits/type_with_alignment.hpp"
|
#include <boost/type_traits/type_with_alignment.hpp>
|
||||||
#include "boost/type_traits/remove_reference.hpp"
|
#include <boost/type_traits/remove_reference.hpp>
|
||||||
#include "boost/type_traits/is_reference.hpp"
|
#include <boost/type_traits/is_reference.hpp>
|
||||||
#include "boost/mpl/if.hpp"
|
#include <boost/mpl/if.hpp>
|
||||||
#include "boost/mpl/bool.hpp"
|
#include <boost/mpl/bool.hpp>
|
||||||
#include "boost/mpl/not.hpp"
|
#include <boost/mpl/not.hpp>
|
||||||
#include "boost/detail/reference_content.hpp"
|
#include <boost/detail/reference_content.hpp>
|
||||||
#include "boost/none.hpp"
|
#include <boost/none.hpp>
|
||||||
#include "boost/utility/addressof.hpp"
|
#include <boost/utility/swap.hpp>
|
||||||
#include "boost/utility/compare_pointees.hpp"
|
#include <boost/utility/addressof.hpp>
|
||||||
#include "boost/utility/in_place_factory.hpp"
|
#include <boost/utility/compare_pointees.hpp>
|
||||||
|
#include <boost/utility/in_place_factory.hpp>
|
||||||
|
|
||||||
#include "boost/optional/optional_fwd.hpp"
|
#include <boost/optional/optional_fwd.hpp>
|
||||||
|
|
||||||
#if BOOST_WORKAROUND(BOOST_MSVC, == 1200)
|
#if BOOST_WORKAROUND(BOOST_MSVC, == 1200)
|
||||||
// VC6.0 has the following bug:
|
// VC6.0 has the following bug:
|
||||||
@ -98,7 +99,7 @@
|
|||||||
namespace boost_optional_detail
|
namespace boost_optional_detail
|
||||||
{
|
{
|
||||||
template <class T, class Factory>
|
template <class T, class Factory>
|
||||||
void construct(Factory const& factory, void* address)
|
inline void construct(Factory const& factory, void* address)
|
||||||
{
|
{
|
||||||
factory.BOOST_NESTED_TEMPLATE apply<T>(address);
|
factory.BOOST_NESTED_TEMPLATE apply<T>(address);
|
||||||
}
|
}
|
||||||
@ -110,6 +111,9 @@ namespace boost {
|
|||||||
class in_place_factory_base ;
|
class in_place_factory_base ;
|
||||||
class typed_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<class T> void swap ( optional<T>& x, optional<T>& y );
|
||||||
|
|
||||||
namespace optional_detail {
|
namespace optional_detail {
|
||||||
|
|
||||||
// This local class is used instead of that in "aligned_storage.hpp"
|
// This local class is used instead of that in "aligned_storage.hpp"
|
||||||
@ -615,7 +619,7 @@ class optional : public optional_detail::optional_base<T>
|
|||||||
void swap( optional & arg )
|
void swap( optional & arg )
|
||||||
{
|
{
|
||||||
// allow for Koenig lookup
|
// allow for Koenig lookup
|
||||||
using boost::swap ;
|
using boost::swap;
|
||||||
swap(*this, arg);
|
swap(*this, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -914,79 +918,63 @@ inline
|
|||||||
bool operator >= ( none_t x, optional<T> const& y )
|
bool operator >= ( none_t x, optional<T> const& y )
|
||||||
{ return !( x < y ) ; }
|
{ return !( x < y ) ; }
|
||||||
|
|
||||||
//
|
|
||||||
// The following swap implementation follows the GCC workaround as found in
|
|
||||||
// "boost/detail/compressed_pair.hpp"
|
|
||||||
//
|
|
||||||
namespace optional_detail {
|
namespace optional_detail {
|
||||||
|
|
||||||
// GCC < 3.2 gets the using declaration at namespace scope (FLC, DWA)
|
template<bool use_default_constructor> struct swap_selector;
|
||||||
#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<bool use_default_constructor> struct swap_selector;
|
template<>
|
||||||
|
struct swap_selector<true>
|
||||||
template<>
|
{
|
||||||
struct swap_selector<true>
|
|
||||||
{
|
|
||||||
template<class T>
|
template<class T>
|
||||||
static void optional_swap ( optional<T>& x, optional<T>& y )
|
static void optional_swap ( optional<T>& x, optional<T>& y )
|
||||||
{
|
{
|
||||||
bool hasX = x;
|
const bool hasX = !!x;
|
||||||
bool hasY = y;
|
const bool hasY = !!y;
|
||||||
|
|
||||||
if ( !hasX && !hasY )
|
if ( !hasX && !hasY )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if( !hasX )
|
if( !hasX )
|
||||||
x = boost::in_place();
|
x = boost::in_place();
|
||||||
else if ( !hasY )
|
else if ( !hasY )
|
||||||
y = boost::in_place();
|
y = boost::in_place();
|
||||||
|
|
||||||
// GCC > 3.2 and all other compilers have the using declaration at function scope (FLC)
|
// Boost.Utility.Swap will take care of ADL and workarounds for broken compilers
|
||||||
#ifndef BOOST_OPTIONAL_STD_SWAP_INTRODUCED_AT_NS_SCOPE
|
boost::swap(x.get(),y.get());
|
||||||
// allow for Koenig lookup
|
|
||||||
using std::swap ;
|
|
||||||
#endif
|
|
||||||
swap(*x,*y);
|
|
||||||
|
|
||||||
if( !hasX )
|
if( !hasX )
|
||||||
y = boost::none ;
|
y = boost::none ;
|
||||||
else if( !hasY )
|
else if( !hasY )
|
||||||
x = boost::none ;
|
x = boost::none ;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
struct swap_selector<false>
|
struct swap_selector<false>
|
||||||
{
|
{
|
||||||
template<class T>
|
template<class T>
|
||||||
static void optional_swap ( optional<T>& x, optional<T>& y )
|
static void optional_swap ( optional<T>& x, optional<T>& y )
|
||||||
{
|
{
|
||||||
if ( !x && !!y )
|
const bool hasX = !!x;
|
||||||
{
|
const bool hasY = !!y;
|
||||||
x = *y;
|
|
||||||
y = boost::none ;
|
if ( !hasX && hasY )
|
||||||
}
|
{
|
||||||
else if ( !!x && !y )
|
x = y.get();
|
||||||
{
|
y = boost::none ;
|
||||||
y = *x ;
|
}
|
||||||
x = boost::none ;
|
else if ( hasX && !hasY )
|
||||||
}
|
{
|
||||||
else if ( !!x && !!y )
|
y = x.get();
|
||||||
{
|
x = boost::none ;
|
||||||
// GCC > 3.2 and all other compilers have the using declaration at function scope (FLC)
|
}
|
||||||
#ifndef BOOST_OPTIONAL_STD_SWAP_INTRODUCED_AT_NS_SCOPE
|
else if ( hasX && hasY )
|
||||||
// allow for Koenig lookup
|
{
|
||||||
using std::swap ;
|
// Boost.Utility.Swap will take care of ADL and workarounds for broken compilers
|
||||||
#endif
|
boost::swap(x.get(),y.get());
|
||||||
swap(*x,*y);
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace optional_detail
|
} // namespace optional_detail
|
||||||
|
|
||||||
@ -995,10 +983,9 @@ struct optional_swap_should_use_default_constructor : has_nothrow_default_constr
|
|||||||
|
|
||||||
template<class T> inline void swap ( optional<T>& x, optional<T>& y )
|
template<class T> inline void swap ( optional<T>& x, optional<T>& y )
|
||||||
{
|
{
|
||||||
optional_detail::swap_selector<optional_swap_should_use_default_constructor<T>::value>::optional_swap(x, y);
|
optional_detail::swap_selector<optional_swap_should_use_default_constructor<T>::value>::optional_swap(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user