$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r55270 - sandbox/fmhess/boost/generic_ptr
From: fmhess_at_[hidden]
Date: 2009-07-30 14:44:59
Author: fmhess
Date: 2009-07-29 15:15:05 EDT (Wed, 29 Jul 2009)
New Revision: 55270
URL: http://svn.boost.org/trac/boost/changeset/55270
Log:
Made generic_ptr::pointer_traits useable with SFINAE.  If pointer_traits
template type is not a plain old pointer, and does not have the appropriate
member typedefs, and does not have a pointer_traits specialization, then
its pointer_traits is now empty (instead of generating a compile error).
Text files modified: 
   sandbox/fmhess/boost/generic_ptr/pointer_traits.hpp |    50 ++++++++++++++++++++++++++++++--------- 
   1 files changed, 38 insertions(+), 12 deletions(-)
Modified: sandbox/fmhess/boost/generic_ptr/pointer_traits.hpp
==============================================================================
--- sandbox/fmhess/boost/generic_ptr/pointer_traits.hpp	(original)
+++ sandbox/fmhess/boost/generic_ptr/pointer_traits.hpp	2009-07-29 15:15:05 EDT (Wed, 29 Jul 2009)
@@ -14,47 +14,76 @@
 #define BOOST_GENERIC_PTR_POINTER_TRAITS_HPP_INCLUDED
 
 #include <boost/get_pointer.hpp>
+#include <boost/mpl/and.hpp>
+#include <boost/mpl/has_xxx.hpp>
 #include <boost/mpl/identity.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/or.hpp>
+#include <boost/type_traits/is_pointer.hpp>
 
 namespace boost
 {
   namespace generic_ptr
   {
-    template<typename T> struct pointer_traits
+    namespace detail
     {
-      typedef typename T::value_type value_type;
-      typedef typename T::pointer pointer;
-      typedef typename T::reference reference;
-    };
+      BOOST_MPL_HAS_XXX_TRAIT_DEF(value_type) // defines has_value_type metafunction
+      BOOST_MPL_HAS_XXX_TRAIT_DEF(pointer) // defines has_pointer metafunction
+      BOOST_MPL_HAS_XXX_TRAIT_DEF(reference) // defines has_reference metafunction
+      template<typename T>
+      class has_member_pointer_traits: public
+        mpl::and_
+        <
+          has_value_type<T>,
+          has_pointer<T>,
+          has_reference<T>
+        >::type
+      {};
+
+      template<typename T> struct builtin_pointer_traits
+      {
+        typedef typename T::value_type value_type;
+        typedef typename T::pointer pointer;
+        typedef typename T::reference reference;
+      };
+
+      struct empty_pointer_traits
+      {};
+    }
 
+    template <typename T>
+    struct pointer_traits : public
+      mpl::if_
+      <
+        detail::has_member_pointer_traits<T>,
+        detail::builtin_pointer_traits<T>,
+        detail::empty_pointer_traits
+      >::type
+    {};
     template<typename T> struct pointer_traits<T*>
     {
       typedef T value_type;
       typedef T * pointer;
       typedef T & reference;
     };
-
     template<> struct pointer_traits<void*>
     {
       typedef void value_type;
       typedef void * pointer;
       typedef void reference;
     };
-
     template<> struct pointer_traits<const void*>
     {
       typedef void value_type;
       typedef const void * pointer;
       typedef void reference;
     };
-
     template<> struct pointer_traits<volatile void*>
     {
       typedef void value_type;
       typedef volatile void * pointer;
       typedef void reference;
     };
-
     template<> struct pointer_traits<const volatile void*>
     {
       typedef void value_type;
@@ -82,13 +111,11 @@
     {
       return static_cast<T*>(r);
     }
-
     template<typename T, typename U>
     T* const_pointer_cast(U *r, boost::mpl::identity<T>)
     {
       return const_cast<T*>(r);
     }
-
     template<typename T, typename U>
     T* dynamic_pointer_cast(U *r, boost::mpl::identity<T>)
     {
@@ -100,7 +127,6 @@
     {
       typedef typename GenericPtr::template rebind<ValueType>::other other;
     };
-
     template<typename T, typename ValueType>
     struct rebind<T*, ValueType>
     {