Boost logo

Boost-Commit :

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>
     {


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk