Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r55317 - in sandbox/fmhess: boost/generic_ptr libs/generic_ptr/test
From: fmhess_at_[hidden]
Date: 2009-07-31 15:04:14


Author: fmhess
Date: 2009-07-31 15:04:13 EDT (Fri, 31 Jul 2009)
New Revision: 55317
URL: http://svn.boost.org/trac/boost/changeset/55317

Log:
Made cloning always apply new_clone to all wrapping generic
pointer types (cloning_monitor_test passes now). Added
new_clone overload for monitor, which locks its mutex before
making clone.

Text files modified:
   sandbox/fmhess/boost/generic_ptr/cloning.hpp | 169 ++++++++++++++++++++++++---------------
   sandbox/fmhess/boost/generic_ptr/monitor.hpp | 11 ++
   sandbox/fmhess/libs/generic_ptr/test/Jamfile.v2 | 2
   sandbox/fmhess/libs/generic_ptr/test/cloning_monitor_test.cpp | 3
   4 files changed, 116 insertions(+), 69 deletions(-)

Modified: sandbox/fmhess/boost/generic_ptr/cloning.hpp
==============================================================================
--- sandbox/fmhess/boost/generic_ptr/cloning.hpp (original)
+++ sandbox/fmhess/boost/generic_ptr/cloning.hpp 2009-07-31 15:04:13 EDT (Fri, 31 Jul 2009)
@@ -41,40 +41,25 @@
     {
       return GenericPointer(new_clone(get_pointer(p)));
     }
+ //FIXME: add similar delete_clone functions
 
     namespace detail
     {
+ template<typename GenericVoidPointer>
       class clone_factory_impl_base
       {
       public:
         virtual ~clone_factory_impl_base() {}
- //FIXME: this isn't adequate. We need to return a generic pointer to void instead
- virtual void * get_pointer() = 0;
+ virtual GenericVoidPointer get_pointer() = 0;
         virtual clone_factory_impl_base* make_clone() = 0;
       };
 
- template<typename T>
- class clone_factory_impl: public clone_factory_impl_base
- {
- public:
- explicit clone_factory_impl(T *p): px(p)
- {}
- ~clone_factory_impl()
- {
- delete_clone(px);
- }
- virtual void * get_pointer() { return px; }
- virtual clone_factory_impl* make_clone()
- {
- if(px == 0) return new clone_factory_impl(0);
- return new clone_factory_impl(new_clone(px));
- }
- private:
- T * px;
- };
-
       template<typename GenericPointer, typename Deleter, typename Cloner>
- class clone_factory_pdc_impl: public clone_factory_impl_base
+ class clone_factory_pdc_impl: public
+ clone_factory_impl_base
+ <
+ typename rebind<GenericPointer, void>::other
+ >
       {
       public:
         clone_factory_pdc_impl(GenericPointer p, Deleter d, Cloner c): px(p), deleter(d), cloner(c)
@@ -83,7 +68,11 @@
         {
           deleter(px);
         }
- virtual void * get_pointer() { return get_plain_old_pointer(px); }
+ virtual typename rebind<GenericPointer, void>::other get_pointer()
+ {
+ //FIXME: remove const from px's value_type
+ return px;
+ }
         virtual clone_factory_pdc_impl* make_clone()
         {
           return new clone_factory_pdc_impl(cloner(px), deleter, cloner);
@@ -94,14 +83,12 @@
         Cloner cloner;
       };
 
+ template<typename GenericVoidPointer>
       class clone_factory
       {
       public:
         clone_factory(): _impl()
         {}
- template<typename T>
- explicit clone_factory(T * p): _impl(new clone_factory_impl<T>(p))
- {}
         template<typename T, typename Deleter, typename Cloner>
         clone_factory(T p, Deleter d, Cloner c): _impl(new clone_factory_pdc_impl<T, Deleter, Cloner>(p, d, c))
         {}
@@ -113,9 +100,9 @@
           swap(other);
         }
 #endif
- void * get_pointer()
+ GenericVoidPointer get_pointer()
         {
- if(_impl.get() == 0) return 0;
+ if(_impl.get() == 0) return GenericVoidPointer();
           return _impl->get_pointer();
         }
         void swap(clone_factory &other)
@@ -125,9 +112,10 @@
       private:
         clone_factory& operator=(const clone_factory &); // could be implemented and made public if we needed it
 
- scoped_ptr<clone_factory_impl_base> _impl;
+ scoped_ptr<clone_factory_impl_base<GenericVoidPointer> > _impl;
       };
- void swap(clone_factory &a, clone_factory &b)
+ template<typename T>
+ void swap(clone_factory<T> &a, clone_factory<T> &b)
       {
         a.swap(b);
       }
@@ -160,6 +148,7 @@
       typedef cloning this_type; // for detail/operator_bool.hpp
       template<typename U>
       friend class cloning;
+ typedef detail::clone_factory<typename generic_ptr::rebind<T, void>::other> clone_factory_type;
     public:
       typedef typename pointer_traits<T>::value_type value_type;
       typedef T pointer;
@@ -171,104 +160,150 @@
         typedef cloning<typename generic_ptr::rebind<pointer, ValueType>::other> other;
       };
 
- cloning(): _cloner(), px()
+ cloning(): _clone_factory(), px()
       {}
       template<typename U>
- cloning( U p ): _cloner(get_plain_old_pointer(p)), px( p )
+ cloning( U p ):
+ _clone_factory
+ (
+ typename generic_ptr::rebind<T, typename pointer_traits<U>::value_type>::other(p),
+ default_cloning_deleter(),
+ default_cloner()
+ ),
+ px
+ (
+ static_pointer_cast
+ <
+ typename pointer_traits<U>::value_type
+ >(_clone_factory.get_pointer())
+ )
       {}
- template<typename U, typename Deleter, typename Cloner = default_cloner>
- cloning(U p, Deleter d, Cloner c = default_cloner()): _cloner(p, d, c), px( p )
+ template<typename U, typename Deleter>
+ cloning(U p, Deleter d):
+ _clone_factory
+ (
+ typename generic_ptr::rebind<T, typename pointer_traits<U>::value_type>::other(p),
+ d,
+ default_cloner()
+ ),
+ px
+ (
+ static_pointer_cast
+ <
+ typename pointer_traits<U>::value_type
+ >(_clone_factory.get_pointer())
+ )
+ {}
+ template<typename U, typename Deleter, typename Cloner>
+ cloning(U p, Deleter d, Cloner c):
+ _clone_factory
+ (
+ typename generic_ptr::rebind<T, typename pointer_traits<U>::value_type>::other(p),
+ d,
+ c
+ ),
+ px
+ (
+ static_pointer_cast
+ <
+ typename pointer_traits<U>::value_type
+ >(_clone_factory.get_pointer())
+ )
       {}
       cloning(const cloning & other):
- _cloner(other._cloner),
+ _clone_factory(other._clone_factory),
         px
         (
- static_cast<value_type *>(_cloner.get_pointer())
+ static_pointer_cast<value_type>(_clone_factory.get_pointer())
         )
       {}
       template<typename U>
       cloning(const cloning<U> & other):
- _cloner(other._cloner),
+ _clone_factory(other._clone_factory),
         px
         (
- static_cast
+ static_pointer_cast
           <
- typename pointer_traits<U>::value_type *
- >(_cloner.get_pointer())
+ typename pointer_traits<U>::value_type
+ >(_clone_factory.get_pointer())
         )
       {}
 
       // casts
       template<typename U>
       cloning(const cloning<U> & other, detail::static_cast_tag):
- _cloner(other._cloner),
+ _clone_factory(other._clone_factory),
         px
         (
- static_cast
+ static_pointer_cast
           <
- value_type *
+ value_type
>
           (
- static_cast
+ static_pointer_cast
             <
- typename pointer_traits<U>::value_type *
- >(_cloner.get_pointer())
+ typename pointer_traits<U>::value_type
+ >(_clone_factory.get_pointer())
           )
         )
       {}
       template<typename U>
       cloning(const cloning<U> & other, detail::const_cast_tag):
- _cloner(other._cloner),
+ _clone_factory(other._clone_factory),
         px
         (
- const_cast
+ const_pointer_cast
           <
- value_type *
+ value_type
>
           (
- static_cast
+ static_pointer_cast
             <
- typename pointer_traits<U>::value_type *
- >(_cloner.get_pointer())
+ typename pointer_traits<U>::value_type
+ >(_clone_factory.get_pointer())
           )
         )
       {}
       template<typename U>
       cloning(const cloning<U> & other, detail::dynamic_cast_tag):
- _cloner(other._cloner),
+ _clone_factory(other._clone_factory),
         px
         (
- dynamic_cast
+ dynamic_pointer_cast
           <
- value_type *
+ value_type
>
           (
- static_cast
+ static_pointer_cast
             <
- typename pointer_traits<U>::value_type *
- >(_cloner.get_pointer())
+ typename pointer_traits<U>::value_type
+ >(_clone_factory.get_pointer())
           )
         )
       {
- // reset _cloner if dynamic cast failed
+ // reset _clone_factory if dynamic cast failed
         if(get_plain_old_pointer(px) == 0)
         {
- detail::clone_factory().swap(_cloner);
+ clone_factory_type().swap(_clone_factory);
         }
       }
 
 #ifndef BOOST_NO_RVALUE_REFERENCES
- cloning(cloning && other): _cloner(std::move(other._cloner)), px(std::move(other.px))
- {}
+ cloning(cloning && other): _clone_factory(std::move(other._clone_factory)), px(std::move(other.px))
+ {
+ detail::set_plain_old_pointer_to_null(other.px);
+ }
       template<typename U>
- cloning(cloning<U> && other): _cloner(std::move(other._cloner)), px(std::move(other.px))
- {}
+ cloning(cloning<U> && other): _clone_factory(std::move(other._clone_factory)), px(std::move(other.px))
+ {
+ detail::set_plain_old_pointer_to_null(other.px);
+ }
 #endif
 
       void swap(cloning & other)
       {
         boost::swap(px, other.px);
- boost::swap(_cloner, other._cloner);
+ boost::swap(_clone_factory, other._clone_factory);
       }
 
       cloning & operator=(const cloning & other)
@@ -321,7 +356,7 @@
       }
 
     private:
- detail::clone_factory _cloner;
+ clone_factory_type _clone_factory;
       pointer px;
     };
 

Modified: sandbox/fmhess/boost/generic_ptr/monitor.hpp
==============================================================================
--- sandbox/fmhess/boost/generic_ptr/monitor.hpp (original)
+++ sandbox/fmhess/boost/generic_ptr/monitor.hpp 2009-07-31 15:04:13 EDT (Fri, 31 Jul 2009)
@@ -212,6 +212,17 @@
     {
       return std::less<typename monitor<T, Mutex>::pointer>()(a.get(), b.get());
     }
+
+ // new_clone overload for safe (mutex locked) use with generic_ptr::cloning
+ template<typename GenericPointer, typename Mutex>
+ monitor<GenericPointer, Mutex> new_clone(const monitor<GenericPointer, Mutex> &p)
+ {
+ if(get_plain_old_pointer(p) == 0) return p;
+ monitor_unique_lock<monitor<GenericPointer, Mutex> > lock(p);
+ using boost::generic_ptr::new_clone;
+ return monitor<GenericPointer, Mutex>(new_clone(p.get()));
+ }
+ // FIXME: add similar delete_clone overload
   } // namespace generic_ptr
 } // namespace boost
 

Modified: sandbox/fmhess/libs/generic_ptr/test/Jamfile.v2
==============================================================================
--- sandbox/fmhess/libs/generic_ptr/test/Jamfile.v2 (original)
+++ sandbox/fmhess/libs/generic_ptr/test/Jamfile.v2 2009-07-31 15:04:13 EDT (Fri, 31 Jul 2009)
@@ -23,7 +23,7 @@
     test-suite "generic_ptr"
         : [ thread-run basic_generic_pointer_test.cpp ]
           [ run cloning_test.cpp ]
- [ run cloning_monitor_test.cpp ]
+ [ thread-run cloning_monitor_test.cpp ]
           [ run throwing_test.cpp ]
         ;
 }

Modified: sandbox/fmhess/libs/generic_ptr/test/cloning_monitor_test.cpp
==============================================================================
--- sandbox/fmhess/libs/generic_ptr/test/cloning_monitor_test.cpp (original)
+++ sandbox/fmhess/libs/generic_ptr/test/cloning_monitor_test.cpp 2009-07-31 15:04:13 EDT (Fri, 31 Jul 2009)
@@ -42,7 +42,8 @@
 
 void clone_test()
 {
- typedef boost::generic_ptr::cloning<boost::generic_ptr::monitor<int*, event_counting_mutex> > cloning_monitor_type;
+ typedef boost::generic_ptr::monitor<int*, event_counting_mutex> monitor_type;
+ typedef boost::generic_ptr::cloning<monitor_type> cloning_monitor_type;
   cloning_monitor_type p0(new int());
   BOOST_TEST(p0.get().get_mutex_ref().lock_count == 0);
   BOOST_TEST(p0.get().get_mutex_ref().unlock_count == 0);


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