Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r54547 - in sandbox/cloneable: boost/cloneable boost/cloneable/detail libs/cloneable/test
From: christian.schladetsch_at_[hidden]
Date: 2009-06-30 17:53:51


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

Log:
added more tests

Text files modified:
   sandbox/cloneable/boost/cloneable/abstract_base.hpp | 18 +++-
   sandbox/cloneable/boost/cloneable/detail/make_clone_allocator.hpp | 4
   sandbox/cloneable/boost/cloneable/forward_declarations.hpp | 3
   sandbox/cloneable/boost/cloneable/map.hpp | 2
   sandbox/cloneable/libs/cloneable/test/cloneable.vcproj | 16 ++--
   sandbox/cloneable/libs/cloneable/test/tests.cpp | 136 +++++++++++++++++++++++++++++----------
   6 files changed, 127 insertions(+), 52 deletions(-)

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 17:53:50 EDT (Tue, 30 Jun 2009)
@@ -10,6 +10,7 @@
 #include <boost/functional/hash_fwd.hpp>
 #include <boost/cloneable/detail/prefix.hpp>
 #include <boost/cloneable/abstract_allocator.hpp>
+#include <boost/cloneable/detail/make_clone_allocator.hpp>
 
 namespace boost
 {
@@ -58,21 +59,26 @@
 
                         /// for use with types that use multiple inheritance - select which sub-object to clone
                         template <class Ty>
- this_type *clone_as(abstract_allocator &alloc) const
+ Ty *clone_as(abstract_allocator &alloc) const
                         {
                                 const base<Ty, Base> *ptr = dynamic_cast<const base<Ty, Base> *>(this);
                                 if (ptr == 0)
                                         throw std::bad_cast();
- return ptr->clone(alloc);
+ this_type *cloned = ptr->clone(alloc);
+ return dynamic_cast<Ty *>(cloned);
                         }
 
                         /// make a copy of the given instance using the heap. caller should call delete
                         this_type *clone() const
                         {
- return 0;
- //if (this_type *copy = clone(original, alloc))
- // return copy;
- //return copy_construct(original, alloc);
+ make_clone_allocator<default_allocator>::type alloc;
+ return clone(alloc);
+ }
+ template <class Ty>
+ Ty *clone_as() const
+ {
+ make_clone_allocator<default_allocator>::type alloc;
+ return clone_as<Ty>(alloc);
                         }
 
                         /// overridable hash function

Modified: sandbox/cloneable/boost/cloneable/detail/make_clone_allocator.hpp
==============================================================================
--- sandbox/cloneable/boost/cloneable/detail/make_clone_allocator.hpp (original)
+++ sandbox/cloneable/boost/cloneable/detail/make_clone_allocator.hpp 2009-06-30 17:53:50 EDT (Tue, 30 Jun 2009)
@@ -56,7 +56,7 @@
                                         void deallocate_bytes(abstract_allocator::pointer ptr, size_t /*alignment*/)
                                         {
                                                 CharAlloc alloc(*this);
- alloc.deallocate(ptr);
+ alloc.deallocate(ptr, 1);
                                                 
                                                 // TODO: retreive the originally allocated pointer
 
@@ -89,6 +89,8 @@
 
                 } // namespace detail
 
+ using detail::make_clone_allocator;
+
         } // namespace cloneable
 
 } // namespace boost

Modified: sandbox/cloneable/boost/cloneable/forward_declarations.hpp
==============================================================================
--- sandbox/cloneable/boost/cloneable/forward_declarations.hpp (original)
+++ sandbox/cloneable/boost/cloneable/forward_declarations.hpp 2009-06-30 17:53:50 EDT (Tue, 30 Jun 2009)
@@ -7,12 +7,15 @@
 #define BOOST_CLONEABLE_FORWARD_DECLARATIONS_HPP
 
 #include <functional>
+#include <memory>
 #include <boost/cloneable/detail/prefix.hpp>
 
 namespace boost
 {
         namespace cloneable
         {
+ typedef std::allocator<char> default_allocator;
+
                 /// an abstract interface for an allocator that can allocate and de-allocate
                 /// byte sequences
                 struct abstract_allocator;

Modified: sandbox/cloneable/boost/cloneable/map.hpp
==============================================================================
--- sandbox/cloneable/boost/cloneable/map.hpp (original)
+++ sandbox/cloneable/boost/cloneable/map.hpp 2009-06-30 17:53:50 EDT (Tue, 30 Jun 2009)
@@ -206,7 +206,7 @@
 
 } // namespace boost
 
-#include <boost/heterogenous/detail/suffix.hpp>
+#include <boost/cloneable/detail/suffix.hpp>
 
 #endif // BOOST_HETEROGENOUS_MAP_HPP
 

Modified: sandbox/cloneable/libs/cloneable/test/cloneable.vcproj
==============================================================================
--- sandbox/cloneable/libs/cloneable/test/cloneable.vcproj (original)
+++ sandbox/cloneable/libs/cloneable/test/cloneable.vcproj 2009-06-30 17:53:50 EDT (Tue, 30 Jun 2009)
@@ -198,14 +198,6 @@
                                         RelativePath="..\..\..\boost\cloneable\forward_declarations.hpp"
>
                                 </File>
- <File
- RelativePath="..\..\..\boost\cloneable\map.hpp"
- >
- </File>
- <File
- RelativePath="..\..\..\boost\cloneable\vector.hpp"
- >
- </File>
                                 <Filter
                                         Name="detail"
>
@@ -233,6 +225,14 @@
                                 <Filter
                                         Name="containers"
>
+ <File
+ RelativePath="..\..\..\boost\cloneable\map.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\boost\cloneable\vector.hpp"
+ >
+ </File>
                                 </Filter>
                         </Filter>
                 </Filter>

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 17:53:50 EDT (Tue, 30 Jun 2009)
@@ -32,6 +32,61 @@
 using namespace boost;
 using namespace cloneable;
 
+namespace basic_test
+{
+ struct my_base { virtual ~my_base() { } };
+ struct T0 : cloneable::base<T0, my_base> {};
+ struct T1 : cloneable::base<T1, my_base> {};
+ struct T2 : cloneable::base<T2, my_base> {};
+ struct T3 : cloneable::base<T3, my_base> {};
+
+ template <class T>
+ T *clone(const my_base &base)
+ {
+ return dynamic_cast<const abstract_base<my_base> &>(base).clone_as<T>();
+ }
+}
+
+template <class T, class Base>
+T *clone(const cloneable::abstract_base<Base> &base)
+{
+ return base.clone_as<T>();
+}
+
+BOOST_AUTO_TEST_CASE(test_basic)
+{
+ using namespace basic_test;
+
+ // basic cloning
+ T0 *t0 = new T0();
+ T0 *t0_clone = dynamic_cast<T0 *>(t0->clone());
+ BOOST_ASSERT(typeid(*t0_clone) == typeid(T0));
+
+ // cloning from an abstract_base_type, and also using clone_as
+ T1::abstract_base_type *t1_base = new T1();
+ T1 *t1_clone = t1_base->clone_as<T1>();
+ BOOST_ASSERT(typeid(*t1_clone) == typeid(T1));
+
+ // use a free-function from a generalised abstract_base
+ T2 *t2 = new T2;
+ T2 *t2_clone = clone<T2>(*t2);
+ BOOST_ASSERT(typeid(*t2_clone) == typeid(T2));
+
+ // use a free-function from a specific base
+ my_base *t3 = new T3;
+ T3 *t3_clone = basic_test::clone<T3>(*t3);
+ BOOST_ASSERT(typeid(*t3_clone) == typeid(T3));
+
+ delete t0;
+ delete t0_clone;
+ delete t1_base;
+ delete t1_clone;
+ delete t2;
+ delete t2_clone;
+ delete t3;
+ delete t3_clone;
+}
+
 namespace mulitple_inheritance_test
 {
         struct Q0 : base<Q0>
@@ -54,43 +109,74 @@
 BOOST_AUTO_TEST_CASE(test_clones)
 {
         using namespace mulitple_inheritance_test;
+
+ // just for spice, use a regionalised monotonic allocator for creating
+ // originals, and producing clones.
+ // at least this way we don't have to free anything...
         monotonic::local<my_region> local;
         monotonic::allocator<int,my_region> alloc = local.make_allocator<int>();
 
         Q0 *q0 = create<Q0>(alloc);
         BOOST_ASSERT(typeid(*q0) == typeid(Q0));
 
- Q0 *q0_c = dynamic_cast<Q0 *>(q0->clone(alloc));
+ Q0 *q0_c = q0->clone_as<Q0>(alloc);
         BOOST_ASSERT(typeid(*q0_c) == typeid(Q0));
 
         Q1 *q1 = create<Q1>(alloc);
         BOOST_ASSERT(typeid(*q1) == typeid(Q1));
 
- Q0 *q1_c0 = dynamic_cast<Q0 *>(q1->clone_as<Q0>(alloc));
+ Q0 *q1_c0 = q1->clone_as<Q0>(alloc);
         BOOST_ASSERT(typeid(*q1_c0) == typeid(Q0));
 
- Q1 *q1_c1 = dynamic_cast<Q1 *>(q1->clone_as<Q1>(alloc));
+ Q1 *q1_c1 = q1->clone_as<Q1>(alloc);
         BOOST_ASSERT(typeid(*q1_c1) == typeid(Q1));
 }
 
+struct my_base
+{
+ virtual ~my_base() { }
+};
 
-BOOST_AUTO_TEST_CASE(test_multiple_inheritance)
+/// some external type that we cannot change
+struct external_type
+{
+ std::string text;
+ external_type() { }
+ external_type(const char *T) : text(T) { }
+};
+
+/// make an adaptor type, which makes `external_type` cloneable
+typedef cloneable::adaptor<external_type, my_base> cloneable_external_type;
+
+BOOST_AUTO_TEST_CASE(test_external_types)
+{
+ // for spice, use stack for storage
+ monotonic::storage<> storage;
+ monotonic::allocator<int> alloc(storage);
+
+ cloneable_external_type *ext = create<cloneable_external_type>(alloc);
+ BOOST_ASSERT(typeid(*ext) == typeid(cloneable_external_type));
+
+ cloneable_external_type *clone = ext->clone_as<cloneable_external_type>(alloc);
+ BOOST_ASSERT(typeid(*clone) == typeid(cloneable_external_type));
+
+}
+BOOST_AUTO_TEST_CASE(test_multiple_inheritance_vector)
 {
         using namespace mulitple_inheritance_test;
         typedef cloneable::vector<> vec;
+
         vec v;
         v.emplace_back<Q0>(42);
         v.emplace_back<Q1>("foo");
+
+ // ensure duplication of types with multiple cloneable sub-objects works correctly
         vec v2 = v;
+
         BOOST_ASSERT(v2.ref_at<Q0>(0).num == 42);
         BOOST_ASSERT(v2.ref_at<Q1>(1).str == "foo");
 }
 
-struct my_base
-{
- virtual ~my_base() { }
-};
-
 struct T0 : base<T0, my_base>
 {
         int num;
@@ -121,30 +207,6 @@
         }
 };
 
-/// some external type that we cannot change
-struct ExternalType
-{
- std::string text;
- ExternalType() { }
- ExternalType(const char *T) : text(T) { }
-};
-
-/// make an adaptor type, which makes `ExternalType` cloneable
-typedef cloneable::adaptor<ExternalType, my_base> ExternalType_;
-
-BOOST_AUTO_TEST_CASE(test_external_types)
-{
- monotonic::local<> local;
- monotonic::allocator<int> alloc = local.make_allocator<int>();
-
- ExternalType_ *ext = create<ExternalType_>(alloc);
- BOOST_ASSERT(typeid(*ext) == typeid(ExternalType_));
-
- ExternalType_ *clone = dynamic_cast<ExternalType_ *>(ext->clone(alloc));
- BOOST_ASSERT(typeid(*clone) == typeid(ExternalType_));
-
-}
-
 BOOST_AUTO_TEST_CASE(test_vector)
 {
         // this uses the base type for the contained elements as a region tag for a monotonic allocator.
@@ -162,7 +224,7 @@
                 bases.emplace_back<T0>(42);
                 bases.emplace_back<T1>("foo");
                 bases.emplace_back<T2>(3.14f, -123, "spam");
- bases.emplace_back<ExternalType_>("external");
+ bases.emplace_back<cloneable_external_type>("external");
 
                 // perform functor on each contained object of the given type
                 bases.for_each<T2>(boost::bind(&T2::print, _1));
@@ -187,8 +249,10 @@
                 
                 BOOST_ASSERT(p1.num == 42);
                 BOOST_ASSERT(p2->str == "foo");
- BOOST_ASSERT(p3->real == 3.14f);BOOST_ASSERT(p3->num == -123);BOOST_ASSERT(p3->str == "spam");
- BOOST_ASSERT(copy.ref_at<ExternalType_>(3).text == "external");
+ BOOST_ASSERT(p3->real == 3.14f);
+ BOOST_ASSERT(p3->num == -123);
+ BOOST_ASSERT(p3->str == "spam");
+ BOOST_ASSERT(copy.ref_at<cloneable_external_type>(3).text == "external");
 
                 bool caught = false;
                 try


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