Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r54982 - sandbox/fmhess/boost/smart_ptr
From: fmhess_at_[hidden]
Date: 2009-07-16 16:10:34


Author: fmhess
Date: 2009-07-16 16:10:34 EDT (Thu, 16 Jul 2009)
New Revision: 54982
URL: http://svn.boost.org/trac/boost/changeset/54982

Log:
Fixed static/const/dynamic_pointer cast for generic pointer types.

Text files modified:
   sandbox/fmhess/boost/smart_ptr/generic_shared.hpp | 51 ++++++++++++++++++++++++++++++++++-----
   sandbox/fmhess/boost/smart_ptr/shared_ptr.hpp | 7 +++--
   2 files changed, 48 insertions(+), 10 deletions(-)

Modified: sandbox/fmhess/boost/smart_ptr/generic_shared.hpp
==============================================================================
--- sandbox/fmhess/boost/smart_ptr/generic_shared.hpp (original)
+++ sandbox/fmhess/boost/smart_ptr/generic_shared.hpp 2009-07-16 16:10:34 EDT (Thu, 16 Jul 2009)
@@ -21,8 +21,8 @@
 // value_type/reference/pointer member typedefs (or specialization of boost::smart_pointer_traits)
 // is_null_pointer() free function findable by ADL
 // (in)equality comparison
-
-// FIXME: how to make boost::static/const/dynamic_pointer_cast support more types?
+// adl_static/const/dynamic_pointer_cast findable by ADL if you want support for
+// boost::static/const/dynamic_pointer_cast
 
 #include <boost/config.hpp> // for broken compiler workarounds
 
@@ -39,6 +39,7 @@
 #include <boost/assert.hpp>
 #include <boost/checked_delete.hpp>
 #include <boost/get_pointer.hpp>
+#include <boost/mpl/identity.hpp>
 #include <boost/pointer_cast.hpp>
 #include <boost/throw_exception.hpp>
 #include <boost/smart_ptr/detail/shared_count.hpp>
@@ -241,21 +242,21 @@
 
     template<class Y>
     generic_shared(generic_shared<Y> const & r, boost::gs_detail::static_cast_tag):
- px(static_pointer_cast<value_type>(r.px)),
+ px(adl_static_pointer_cast(r.px, boost::mpl::identity<pointer>())),
         pn(r.pn)
     {
     }
 
     template<class Y>
     generic_shared(generic_shared<Y> const & r, boost::gs_detail::const_cast_tag):
- px(const_pointer_cast<value_type>(r.px)),
+ px(adl_const_pointer_cast(r.px, boost::mpl::identity<pointer>())),
         pn(r.pn)
     {
     }
 
     template<class Y>
     generic_shared(generic_shared<Y> const & r, boost::gs_detail::dynamic_cast_tag):
- px(dynamic_pointer_cast<value_type>(r.px)),
+ px(adl_dynamic_pointer_cast(r.px, boost::mpl::identity<pointer>())),
         pn(r.pn)
     {
         using boost::is_null_pointer;
@@ -566,19 +567,55 @@
 
 template<class T, class U> generic_shared<T> static_pointer_cast(generic_shared<U> const & r)
 {
- return generic_shared<T>(r, boost::gs_detail::static_cast_tag());
+ return adl_static_pointer_cast(r, boost::mpl::identity<generic_shared<T> >());
 }
 
 template<class T, class U> generic_shared<T> const_pointer_cast(generic_shared<U> const & r)
 {
- return generic_shared<T>(r, boost::gs_detail::const_cast_tag());
+ return adl_const_pointer_cast(r, boost::mpl::identity<generic_shared<T> >());
 }
 
 template<class T, class U> generic_shared<T> dynamic_pointer_cast(generic_shared<U> const & r)
 {
+ return adl_dynamic_pointer_cast(r, boost::mpl::identity<generic_shared<T> >());
+}
+
+template<typename T, typename U>
+generic_shared<T> adl_static_pointer_cast(generic_shared<U> const & r, boost::mpl::identity<generic_shared<T> >)
+{
+ return generic_shared<T>(r, boost::gs_detail::static_cast_tag());
+}
+
+template<typename T, typename U>
+generic_shared<T> adl_const_pointer_cast(generic_shared<U> const & r, boost::mpl::identity<generic_shared<T> >)
+{
+ return generic_shared<T>(r, boost::gs_detail::const_cast_tag());
+}
+
+template<typename T, typename U>
+generic_shared<T> adl_dynamic_pointer_cast(generic_shared<U> const & r, boost::mpl::identity<generic_shared<T> >)
+{
     return generic_shared<T>(r, boost::gs_detail::dynamic_cast_tag());
 }
 
+template<typename T, typename U>
+T* adl_static_pointer_cast(U *r, boost::mpl::identity<T*>)
+{
+ return static_cast<T*>(r);
+}
+
+template<typename T, typename U>
+T* adl_const_pointer_cast(U *r, boost::mpl::identity<T*>)
+{
+ return const_cast<T*>(r);
+}
+
+template<typename T, typename U>
+T* adl_dynamic_pointer_cast(U *r, boost::mpl::identity<T*>)
+{
+ return dynamic_cast<T*>(r);
+}
+
 // get_pointer() enables boost::mem_fn to recognize generic_shared
 template<class T> inline T get_pointer(generic_shared<T> const & p)
 {

Modified: sandbox/fmhess/boost/smart_ptr/shared_ptr.hpp
==============================================================================
--- sandbox/fmhess/boost/smart_ptr/shared_ptr.hpp (original)
+++ sandbox/fmhess/boost/smart_ptr/shared_ptr.hpp 2009-07-16 16:10:34 EDT (Thu, 16 Jul 2009)
@@ -98,19 +98,20 @@
                         base_type::reset(static_cast<generic_shared<Y*> const &>(r), p);
                 }
         };
+
         template<class T, class U> shared_ptr<T> static_pointer_cast(shared_ptr<U> const & r)
         {
- return shared_ptr<T>(static_pointer_cast<generic_shared<U*> const &>(r));
+ return static_pointer_cast<T*>(static_cast<generic_shared<U*> const &>(r));
         }
 
         template<class T, class U> shared_ptr<T> const_pointer_cast(shared_ptr<U> const & r)
         {
- return shared_ptr<T>(const_pointer_cast<generic_shared<U*> const &>(r));
+ return const_pointer_cast<T*>(static_cast<generic_shared<U*> const &>(r));
         }
 
         template<class T, class U> shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const & r)
         {
- return shared_ptr<T>(dynamic_pointer_cast<generic_shared<U*> const &>(r));
+ return dynamic_pointer_cast<T*>(static_cast<generic_shared<U*> const &>(r));
         }
 }
 


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