|
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