Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r54549 - in sandbox/cloneable: boost/cloneable boost/cloneable/detail libs/cloneable/test
From: christian.schladetsch_at_[hidden]
Date: 2009-06-30 18:39:55


Author: cschladetsch
Date: 2009-06-30 18:39:53 EDT (Tue, 30 Jun 2009)
New Revision: 54549
URL: http://svn.boost.org/trac/boost/changeset/54549

Log:
added more tests

Text files modified:
   sandbox/cloneable/boost/cloneable/abstract_allocator.hpp | 18 +++++++++++++++
   sandbox/cloneable/boost/cloneable/abstract_base.hpp | 47 +++++++++++++++++++++++++++++++++++----
   sandbox/cloneable/boost/cloneable/adaptor.hpp | 10 ++-----
   sandbox/cloneable/boost/cloneable/allocator.hpp | 38 ++++++++++++++++++++++++++++++-
   sandbox/cloneable/boost/cloneable/base.hpp | 12 +++++----
   sandbox/cloneable/boost/cloneable/detail/pointer.hpp | 4 +++
   sandbox/cloneable/libs/cloneable/test/tests.cpp | 46 ++++++++++++++++++++++++++++++++++++++
   7 files changed, 155 insertions(+), 20 deletions(-)

Modified: sandbox/cloneable/boost/cloneable/abstract_allocator.hpp
==============================================================================
--- sandbox/cloneable/boost/cloneable/abstract_allocator.hpp (original)
+++ sandbox/cloneable/boost/cloneable/abstract_allocator.hpp 2009-06-30 18:39:53 EDT (Tue, 30 Jun 2009)
@@ -8,6 +8,7 @@
 
 #include <boost/cloneable/detail/prefix.hpp>
 #include <boost/cloneable/forward_declarations.hpp>
+//#include <boost/cloneable/allocation.hpp>
 
 namespace boost
 {
@@ -31,6 +32,23 @@
                                         extra = alignment - extra;
                                 return extra;
                         }
+
+ // TODO
+ //template <class T>
+ //T *create()
+ //{
+ // return cloneable::create<T>(*this);
+ //}
+ //template <class T, class A0>
+ //T *create(A0 a0)
+ //{
+ // return cloneable::create<T>(*this, a0);
+ //}
+ //template <class T, class A0, class A1>
+ //T *create(A0 a0, A1 a1)
+ //{
+ // return cloneable::create<T>(*this, a0, a1);
+ //}
                 };
 
         } // namespace cloneable

Modified: sandbox/cloneable/boost/cloneable/abstract_base.hpp
==============================================================================
--- sandbox/cloneable/boost/cloneable/abstract_base.hpp (original)
+++ sandbox/cloneable/boost/cloneable/abstract_base.hpp 2009-06-30 18:39:53 EDT (Tue, 30 Jun 2009)
@@ -34,7 +34,8 @@
                         /// make storage for a new instance, but do not invoke any constructor
                         virtual this_type *allocate(abstract_allocator &) const = 0;
 
- /// free memory associated with the given instance
+ /// free memory associated with this instance.
+ /// this is effectively 'delete this', but without a call to the destructor
                         virtual void deallocate(abstract_allocator &) = 0;
 
                         /// create a new object of the derived type
@@ -57,7 +58,9 @@
                                 return copy_construct(alloc);
                         }
 
- /// for use with types that use multiple inheritance - select which sub-object to clone
+ /// for use with types that use multiple inheritance - select which sub-object to clone.
+ /// can also be used when there is just one cloneable sub-object to avoid having to
+ /// dynamic cast the result.
                         template <class Ty>
                         Ty *clone_as(abstract_allocator &alloc) const
                         {
@@ -68,12 +71,44 @@
                                 return dynamic_cast<Ty *>(cloned);
                         }
 
- /// make a copy of the given instance using the heap. caller should call delete
+ /// non-virtual method that allocates using default allocator
+ this_type *allocate() const
+ {
+ make_clone_allocator<default_allocator>::type alloc;
+ return allocate(alloc);
+ }
+
+ /// non-virtual method that deallocates using default allocator
+ void deallocate() const
+ {
+ make_clone_allocator<default_allocator>::type alloc;
+ return deallocate(alloc);
+ }
+
+ /// non-virtual method that creates a new instance of derived type using default allocator
+ this_type *create_new() const
+ {
+ make_clone_allocator<default_allocator>::type alloc;
+ return create_new(alloc);
+ }
+
+ /// non-virtual method that creates a new instance of derived type from this instance,
+ /// using copy-constructor and default allocator
+ this_type *copy_construct() const
+ {
+ make_clone_allocator<default_allocator>::type alloc;
+ return copy_construct(alloc);
+ }
+
+ /// make a copy of this instance using default allocator
                         this_type *clone() const
                         {
                                 make_clone_allocator<default_allocator>::type alloc;
                                 return clone(alloc);
                         }
+
+ /// make a copy of this instance using default allocator,
+ /// selecting sub-object to clone
                         template <class Ty>
                         Ty *clone_as() const
                         {
@@ -81,7 +116,10 @@
                                 return clone_as<Ty>(alloc);
                         }
 
- /// overridable hash function
+ /// overridable to-string function, for utility
+ virtual std::string to_string() const { return "cloneable"; }
+
+ /// overridable hash function, for utility
                         virtual size_t hash_value() const { return 0; }
 
                         /// return a hash value for the object. try the virtual method first, otherwise just use pointer value
@@ -92,7 +130,6 @@
                                 return ptrdiff_t(reinterpret_cast<const char *>(this) - 0);
                         }
 
- virtual std::string to_string() const { return "cloneable"; }
                 };
 
         } // namespace cloneable

Modified: sandbox/cloneable/boost/cloneable/adaptor.hpp
==============================================================================
--- sandbox/cloneable/boost/cloneable/adaptor.hpp (original)
+++ sandbox/cloneable/boost/cloneable/adaptor.hpp 2009-06-30 18:39:53 EDT (Tue, 30 Jun 2009)
@@ -13,13 +13,9 @@
 {
         namespace cloneable
         {
- /// an adaptor for an existing class
- ///
- /// this is a type that can be used in an homogenous container
- ///
- /// ...this may or may not be a good idea...
- template <class T, class Base>//, class AbstractBase>
- struct adaptor : T, base<adaptor<T, Base/*, AbstractBase*/>, Base/*, AbstractBase*/>
+ /// an adaptor for an existing class T, making it cloneable
+ template <class T, class Base>
+ struct adaptor : T, base<adaptor<T, Base>, Base>
                 {
                         adaptor() { }
 

Modified: sandbox/cloneable/boost/cloneable/allocator.hpp
==============================================================================
--- sandbox/cloneable/boost/cloneable/allocator.hpp (original)
+++ sandbox/cloneable/boost/cloneable/allocator.hpp 2009-06-30 18:39:53 EDT (Tue, 30 Jun 2009)
@@ -19,13 +19,17 @@
                         template <class Base>
                         static Base* allocate_clone( const Base& object )
                         {
- throw;
+ // use default allocator
+ return object.clone();
                         }
 
                         template <class Base>
                         static void deallocate_clone( const Base* clone )
                         {
- throw;
+ if (!object)
+ return;
+ // use default allocator
+ return const_cast<Base *>(object->deallocate());
                         }
 
                         template <class Base, class Alloc>
@@ -52,6 +56,28 @@
                         return ptr;
                 }
 
+ template <class T>
+ T *create(abstract_allocator &alloc)
+ {
+ abstract_allocator::pointer ptr = alloc.allocate_bytes(sizeof(T), aligned_storage<sizeof(T)>::alignment);
+ new (ptr) T();
+ return reinterpret_cast<T *>(ptr);
+ }
+ template <class T, class A0>
+ T *create(abstract_allocator &alloc, A0 a0)
+ {
+ abstract_allocator::pointer ptr = alloc.allocate_bytes(sizeof(T), aligned_storage<sizeof(T)>::alignment);
+ new (ptr) T(a0);
+ return reinterpret_cast<T *>(ptr);
+ }
+ template <class T, class A0, class A1>
+ T *create(abstract_allocator &alloc, A0 a0, A1 a1)
+ {
+ abstract_allocator::pointer ptr = alloc.allocate_bytes(sizeof(T), aligned_storage<sizeof(T)>::alignment);
+ new (ptr) T(a0, a1);
+ return reinterpret_cast<T *>(ptr);
+ }
+
                 template <class T, class Alloc, class A0>
                 T *create(Alloc &alloc, A0 a0)
                 {
@@ -60,6 +86,14 @@
                         new (ptr) T(a0);
                         return ptr;
                 }
+ template <class T, class Alloc, class A0, class A1>
+ T *create(Alloc &alloc, A0 a0, A1 a1)
+ {
+ typename Alloc::template rebind<T>::other al(alloc);
+ T *ptr = al.allocate(1);
+ new (ptr) T(a0, a1);
+ return ptr;
+ }
                 template <class T, class Alloc>
                 void release(T *ptr, Alloc &alloc)
                 {

Modified: sandbox/cloneable/boost/cloneable/base.hpp
==============================================================================
--- sandbox/cloneable/boost/cloneable/base.hpp (original)
+++ sandbox/cloneable/boost/cloneable/base.hpp 2009-06-30 18:39:53 EDT (Tue, 30 Jun 2009)
@@ -15,20 +15,22 @@
         namespace cloneable
         {
                 /// base for the given derived type, using the given base class
- template <class Derived, class Base>//, class AbstractBase>
+ template <class Derived, class Base>
                 struct base : abstract_base<Base>
                 {
                         typedef Derived derived_type;
                         typedef Base base_type;
- //typedef AbstractBase abstract_base_type;
                         typedef abstract_base<Base> abstract_base_type;
- typedef base<Derived, Base/*, AbstractBase*/> this_type;
+ typedef base<Derived, Base> this_type;
 
- static const size_t alignment; ///< required alignment for allocation
+ static const size_t alignment; ///< required alignment for allocation
                         mutable derived_type *self_ptr; ///< pointer to derived object in this
 
                 public:
- base() { self_ptr = static_cast<Derived *>(this); }
+ base()
+ {
+ self_ptr = static_cast<Derived *>(this);
+ }
 
                         virtual this_type *allocate(abstract_allocator &alloc) const
                         {

Modified: sandbox/cloneable/boost/cloneable/detail/pointer.hpp
==============================================================================
--- sandbox/cloneable/boost/cloneable/detail/pointer.hpp (original)
+++ sandbox/cloneable/boost/cloneable/detail/pointer.hpp 2009-06-30 18:39:53 EDT (Tue, 30 Jun 2009)
@@ -15,6 +15,8 @@
         {
                 namespace detail
                 {
+ /// a pointer store that can retrieve pointers from up and down
+ /// the inheritance tree.
                         template <class U, class B>
                         struct pointer
                         {
@@ -44,6 +46,8 @@
                                 }
                                 derived_type *to_derived() const
                                 {
+ if (!ptr)
+ return 0;
                                         return ptr->cloneable_type::self_ptr;
                                 }
                         };

Modified: sandbox/cloneable/libs/cloneable/test/tests.cpp
==============================================================================
--- sandbox/cloneable/libs/cloneable/test/tests.cpp (original)
+++ sandbox/cloneable/libs/cloneable/test/tests.cpp 2009-06-30 18:39:53 EDT (Tue, 30 Jun 2009)
@@ -132,6 +132,33 @@
         BOOST_ASSERT(typeid(*q1_c1) == typeid(Q1));
 }
 
+namespace custom_clone_test
+{
+ struct T0 : base<T0>
+ {
+ bool custom_cloned;
+ T0() : custom_cloned(false) { }
+
+ /// override the means to create a copy from abstract_base<>
+ T0 *make_copy(abstract_allocator &alloc) const
+ {
+ T0 *ptr = create<T0>(alloc);
+ ptr->custom_cloned = true;
+ return ptr;
+ }
+ };
+}
+
+BOOST_AUTO_TEST_CASE(test_custom_clone)
+{
+ using namespace custom_clone_test;
+ T0 *p = new T0;
+ T0 *q = p->clone_as<T0>();
+ BOOST_ASSERT(q && q->custom_cloned);
+ delete p;
+ delete q;
+}
+
 struct my_base
 {
         virtual ~my_base() { }
@@ -159,8 +186,25 @@
 
         cloneable_external_type *clone = ext->clone_as<cloneable_external_type>(alloc);
         BOOST_ASSERT(typeid(*clone) == typeid(cloneable_external_type));
-
 }
+
+//struct custom_external_cloneable : adaptor<external_type, my_base>
+//{
+// custom_external_cloneable *clone(abstract_allocator &alloc) const
+// {
+// custom_external_cloneable *ptr = create<custom_external_cloneable>(alloc);
+// ptr->text = "custom_cloned";
+// return ptr;
+// }
+//};
+//
+//BOOST_AUTO_TEST_CASE(test_custom_external_clone)
+//{
+// custom_external_cloneable *p = new custom_external_cloneable;
+// custom_external_cloneable *q = p->clone_as<custom_external_cloneable>();
+// BOOST_ASSERT(typeid(*q) == typeid(custom_external_cloneable));
+//}
+
 BOOST_AUTO_TEST_CASE(test_multiple_inheritance_vector)
 {
         using namespace mulitple_inheritance_test;


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