// Copyright David Abrahams 2004. 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) #ifndef HAS_SWAP_OVERLOAD_DWA200415_HPP # define HAS_SWAP_OVERLOAD_DWA200415_HPP # include # include # include # include # include // Must be the last include # include namespace std { // Defining names in std is illegal; so sue me // // This allows us to test whether std is an associated namespace of // the type in question. If it is, we have to assume any swap // overload we detect is std::swap and that there is no // type-specific swap overload. This is the conservative default. // We'll specialize has_swap_overload for such known-swappables as // std::vector. template char stdIsAnAssociatedNamespace(T const&, int); // Forward declare some known types that have a fast swap. Also // illegal last I checked. template class vector; template class deque; template class list; template class set; template class map; } namespace boost { namespace detail { // has_swap_overload metafunction // // Requires: Given x of type T&, if the expression swap(x,x) is // well-formed it must have complete type or void result; otherwise, // it must neither be ambiguous nor violate access. // This namespace ensures that ADL doesn't mess things up. namespace has_swap_overload_ { // a type returned from swap() when no increment is found in the // type's own namespace struct tag {}; // any soaks up implicit conversions and makes the following // swap less-preferred than any other such function that // might be found via ADL. struct any { template any(T const&); }; // This is a last-resort swap() for when none other is found # if BOOST_WORKAROUND(__GNUC__, == 4) && __GNUC_MINOR__ == 0 && __GNUC_PATCHLEVEL__ == 2 } namespace has_swap_overload_2 { has_swap_overload_::tag swap(has_swap_overload_::any const&, has_swap_overload_::any const&); } using namespace has_swap_overload_2; namespace has_swap_overload_ { # else tag swap(any const&, any const&); # endif # if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3202)) \ || BOOST_WORKAROUND(BOOST_MSVC, <= 1300) # define BOOST_comma(a,b) (a) # else // In case a swap() is found that returns void (likely), we'll use swap(x,x),0 tag operator,(tag,int); # define BOOST_comma(a,b) (a,b) # endif # if defined(BOOST_MSVC) # pragma warning(push) # pragma warning(disable:4913) // Warning about operator, # endif typedef char yes; typedef char (&no)[2]; // two check overloads help us identify which swap was picked no check(tag); template yes check(T const&); template no stdIsAnAssociatedNamespace(T const&, ...); template struct impl { static typename boost::remove_cv::type& x; BOOST_STATIC_CONSTANT( bool , value = sizeof(stdIsAnAssociatedNamespace(x, 1)) == sizeof(no) && sizeof(has_swap_overload_::check(BOOST_comma(swap(x,x),0))) == sizeof(yes) ); }; # if defined(BOOST_MSVC) # pragma warning(pop) # endif } # undef BOOST_comma template struct has_swap_overload BOOST_TT_AUX_BOOL_C_BASE(::boost::detail::has_swap_overload_::impl::value) { BOOST_TT_AUX_BOOL_TRAIT_VALUE_DECL(::boost::detail::has_swap_overload_::impl::value) BOOST_MPL_AUX_LAMBDA_SUPPORT(1,has_swap_overload,(T)) }; template struct has_swap_overload > : mpl::true_{}; template struct has_swap_overload > : mpl::true_{}; template struct has_swap_overload > : mpl::true_{}; template struct has_swap_overload > : mpl::true_{}; template struct has_swap_overload > : mpl::true_{}; } // namespace detail BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(1, ::boost::detail::has_swap_overload) } // namespace boost # include #endif // HAS_SWAP_OVERLOAD_DWA200415_HPP