$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
From: daniel_james_at_[hidden]
Date: 2008-07-13 15:25:34
Author: danieljames
Date: 2008-07-13 15:25:33 EDT (Sun, 13 Jul 2008)
New Revision: 47395
URL: http://svn.boost.org/trac/boost/changeset/47395
Log:
Add David Abrahams's has_swap_overload.
Added:
   sandbox/move/boost/move/detail/has_swap_overload.hpp   (contents, props changed)
   sandbox/move/libs/move/test/has_swap_overload.cpp   (contents, props changed)
Text files modified: 
   sandbox/move/libs/move/test/Jamfile.v2 |     1 +                                       
   1 files changed, 1 insertions(+), 0 deletions(-)
Added: sandbox/move/boost/move/detail/has_swap_overload.hpp
==============================================================================
--- (empty file)
+++ sandbox/move/boost/move/detail/has_swap_overload.hpp	2008-07-13 15:25:33 EDT (Sun, 13 Jul 2008)
@@ -0,0 +1,156 @@
+// 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 <boost/type_traits/detail/template_arity_spec.hpp>
+# include <boost/type_traits/remove_cv.hpp>
+# include <boost/mpl/aux_/lambda_support.hpp>
+# include <boost/mpl/bool.hpp>
+# include <boost/detail/workaround.hpp>
+
+// Must be the last include
+# include <boost/type_traits/detail/bool_trait_def.hpp>
+
+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 <class T>
+  char stdIsAnAssociatedNamespace(T const&, int);
+
+  // Forward declare some known types that have a fast swap.  Also
+  // illegal last I checked.
+  template <class T, class A> class vector;
+  template <class T, class A> class deque;
+  template <class T, class A> class list;
+  template <class T, class A, class C> class set;
+  template <class T, class U, class C, class A> class map;
+}
+
+namespace boost { namespace detail { 
+
+// has_swap_overload<T> 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 <class T> 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 <class T>
+  yes check(T const&);
+  
+  template <class T>
+  no stdIsAnAssociatedNamespace(T const&, ...);
+
+  template <class T>
+  struct impl
+  {
+      static typename boost::remove_cv<T>::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<typename T> 
+struct has_swap_overload 
+BOOST_TT_AUX_BOOL_C_BASE(::boost::detail::has_swap_overload_::impl<T>::value)
+{ 
+    BOOST_TT_AUX_BOOL_TRAIT_VALUE_DECL(::boost::detail::has_swap_overload_::impl<T>::value)
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(1,has_swap_overload,(T))
+};
+
+
+template <class T, class A>
+struct has_swap_overload<std::vector<T,A> > : mpl::true_{};
+
+template <class T, class A>
+struct has_swap_overload<std::deque<T,A> > : mpl::true_{};
+
+template <class T, class A>
+struct has_swap_overload<std::list<T,A> > : mpl::true_{};
+
+template <class T, class A, class C>
+struct has_swap_overload<std::set<T,A,C> > : mpl::true_{};
+
+template <class K, class V, class C, class A>
+struct has_swap_overload<std::map<K,V,C,A> > : mpl::true_{};
+
+} // namespace detail
+
+BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(1, ::boost::detail::has_swap_overload)
+
+} // namespace boost
+
+# include <boost/type_traits/detail/bool_trait_undef.hpp>
+
+#endif // HAS_SWAP_OVERLOAD_DWA200415_HPP
Modified: sandbox/move/libs/move/test/Jamfile.v2
==============================================================================
--- sandbox/move/libs/move/test/Jamfile.v2	(original)
+++ sandbox/move/libs/move/test/Jamfile.v2	2008-07-13 15:25:33 EDT (Sun, 13 Jul 2008)
@@ -14,6 +14,7 @@
     [ run noncopyable.cpp ]
     [ run move_test.cpp ]
     [ run no_sfinae_test.cpp ]
+    [ run has_swap_overload.cpp ]
 ;
 
 test-suite "move-fail" :
Added: sandbox/move/libs/move/test/has_swap_overload.cpp
==============================================================================
--- (empty file)
+++ sandbox/move/libs/move/test/has_swap_overload.cpp	2008-07-13 15:25:33 EDT (Sun, 13 Jul 2008)
@@ -0,0 +1,39 @@
+// Copyright David Abrahams 2008. Distributed under 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)
+
+#include <boost/move/detail/has_swap_overload.hpp>
+#include <boost/mpl/assert.hpp>
+#include <complex>
+#include <vector>
+
+namespace my
+{
+  struct X
+  {
+      friend void swap(X&, X&) {}
+  };
+
+  struct Y {};
+
+  struct Z
+    : std::complex<double>
+  {
+      friend void swap(Z&, Z&) {}
+  };
+};
+
+int main()
+{
+    BOOST_MPL_ASSERT((boost::detail::has_swap_overload<my::X>));
+    BOOST_MPL_ASSERT_NOT((boost::detail::has_swap_overload<my::Y>));
+    
+    // Wrong answer expected here; std is an associated namespace so
+    // we have to be conservative
+    BOOST_MPL_ASSERT_NOT((boost::detail::has_swap_overload<my::Z>));
+    
+    BOOST_MPL_ASSERT_NOT((boost::detail::has_swap_overload<std::complex<double> >));
+
+    // The library has a specialization for this one.
+    BOOST_MPL_ASSERT((boost::detail::has_swap_overload<std::vector<int> >));
+}