|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r54527 - in sandbox/monotonic: boost/heterogenous boost/heterogenous/detail libs/monotonic/test/clones
From: christian.schladetsch_at_[hidden]
Date: 2009-06-30 05:05:09
Author: cschladetsch
Date: 2009-06-30 05:05:07 EDT (Tue, 30 Jun 2009)
New Revision: 54527
URL: http://svn.boost.org/trac/boost/changeset/54527
Log:
made multiple inheritance work
Text files modified:
sandbox/monotonic/boost/heterogenous/abstract_cloneable.hpp | 37 ++++++++++++++++++++------
sandbox/monotonic/boost/heterogenous/adaptor.hpp | 4 +-
sandbox/monotonic/boost/heterogenous/allocator.hpp | 4 +-
sandbox/monotonic/boost/heterogenous/cloneable.hpp | 33 +++++++++++++----------
sandbox/monotonic/boost/heterogenous/detail/allocation.hpp | 52 ++++++++++++++++++++++++++++++++-----
sandbox/monotonic/boost/heterogenous/forward_declarations.hpp | 8 ++--
sandbox/monotonic/boost/heterogenous/map.hpp | 19 +++++++------
sandbox/monotonic/boost/heterogenous/vector.hpp | 15 ++++++----
sandbox/monotonic/libs/monotonic/test/clones/tests.cpp | 55 ++++++++++++++++++++++++++++++++-------
9 files changed, 163 insertions(+), 64 deletions(-)
Modified: sandbox/monotonic/boost/heterogenous/abstract_cloneable.hpp
==============================================================================
--- sandbox/monotonic/boost/heterogenous/abstract_cloneable.hpp (original)
+++ sandbox/monotonic/boost/heterogenous/abstract_cloneable.hpp 2009-06-30 05:05:07 EDT (Tue, 30 Jun 2009)
@@ -23,35 +23,54 @@
/// root structure for the heterogenous object system
template <class Base>
- struct abstract_cloneable : Base
+ struct abstract_cloneable : virtual Base
{
typedef Base base_type;
typedef abstract_cloneable<Base> this_type;
/// make storage for a new instance, but do not invoke any constructor
- virtual this_type *allocate(abstract_allocator &alloc) const = 0;
+ virtual this_type *allocate(abstract_allocator &) const = 0;
/// free memory associated with the given instance
- virtual void deallocate(base_type &, abstract_allocator &alloc) const = 0;
+ virtual void deallocate(abstract_allocator &) = 0;
/// create a new object of the derived type
- virtual this_type *create_new(abstract_allocator &alloc) const = 0;
+ virtual this_type *create_new(abstract_allocator &) const = 0;
/// create a clone using copy-constructor. this is implemented in cloneable<>, but can
/// be overriden by the user in the derived type if required.
- virtual this_type *copy_construct(const base_type &original, abstract_allocator &alloc) const = 0;
+ virtual this_type *copy_construct(abstract_allocator &) const = 0;
/// optional means to make a clone that does not use copy-construction.
/// user can overload this in their derived type to provide custom clone implementation.
- virtual this_type *clone(const base_type &original, abstract_allocator &alloc) const { return 0; }
+ virtual this_type *make_copy(abstract_allocator &) const { return 0; }
/// make a copy of the given instance. try the custom clone method first,
/// then default to using the copy-constructor method
- this_type *make_copy(const base_type &original, abstract_allocator &alloc) const
+ this_type *clone(abstract_allocator &alloc) const
{
- if (this_type *copy = clone(original, alloc))
+ if (this_type *copy = make_copy(alloc))
return copy;
- return copy_construct(original, alloc);
+ return copy_construct(alloc);
+ }
+
+ /// 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
+ {
+ const cloneable<Ty, Base> *ptr = dynamic_cast<const cloneable<Ty, Base> *>(this);
+ if (ptr == 0)
+ throw std::bad_cast();
+ return ptr->clone(alloc);
+ }
+
+ /// 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);
}
};
Modified: sandbox/monotonic/boost/heterogenous/adaptor.hpp
==============================================================================
--- sandbox/monotonic/boost/heterogenous/adaptor.hpp (original)
+++ sandbox/monotonic/boost/heterogenous/adaptor.hpp 2009-06-30 05:05:07 EDT (Tue, 30 Jun 2009)
@@ -18,8 +18,8 @@
/// 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, cloneable<adaptor<T, Base, AbstractBase>, Base, AbstractBase>
+ template <class T, class Base>//, class AbstractBase>
+ struct adaptor : T, cloneable<adaptor<T, Base/*, AbstractBase*/>, Base/*, AbstractBase*/>
{
adaptor() { }
Modified: sandbox/monotonic/boost/heterogenous/allocator.hpp
==============================================================================
--- sandbox/monotonic/boost/heterogenous/allocator.hpp (original)
+++ sandbox/monotonic/boost/heterogenous/allocator.hpp 2009-06-30 05:05:07 EDT (Tue, 30 Jun 2009)
@@ -30,7 +30,7 @@
template <class Base, class Alloc>
static Base* allocate_clone(const Base& object, Alloc &alloc )
{
- return object.make_copy(object, alloc);
+ return object.clone(alloc);
}
template <class Base, class Alloc>
@@ -38,7 +38,7 @@
{
if (!object)
return;
- object->deallocate(const_cast<Base &>(*object), alloc);
+ const_cast<Base &>(*object).deallocate(alloc);
}
};
Modified: sandbox/monotonic/boost/heterogenous/cloneable.hpp
==============================================================================
--- sandbox/monotonic/boost/heterogenous/cloneable.hpp (original)
+++ sandbox/monotonic/boost/heterogenous/cloneable.hpp 2009-06-30 05:05:07 EDT (Tue, 30 Jun 2009)
@@ -15,15 +15,16 @@
namespace heterogenous
{
/// base for the given derived type, using the given base class
- template <class Derived, class Base, class AbstractBase>
- struct cloneable : AbstractBase
+ template <class Derived, class Base>//, class AbstractBase>
+ struct cloneable : abstract_cloneable<Base>
{
typedef Derived derived_type;
typedef Base base_type;
- typedef AbstractBase abstract_base_type;
- typedef cloneable<Derived, Base, AbstractBase> this_type;
+ //typedef AbstractBase abstract_base_type;
+ typedef abstract_cloneable<Base> abstract_base_type;
+ typedef cloneable<Derived, Base/*, AbstractBase*/> this_type;
- private:
+ //private:
static size_t alignment; ///< required alignment for allocation
mutable derived_type *self_ptr; ///< pointer to derived object in this
@@ -38,30 +39,34 @@
return ptr;
}
- void deallocate(base_type &object, abstract_allocator &alloc) const
+ void deallocate(abstract_allocator &alloc)
{
- Derived *ptr = static_cast<Derived *>(&object);
+ Derived *ptr = dynamic_cast<Derived *>(this);
alloc.deallocate_bytes(reinterpret_cast<abstract_allocator::pointer>(ptr), alignment);
}
virtual this_type *create_new(abstract_allocator &alloc) const
{
- this_type *ptr = allocate(alloc);
- new (ptr->self_ptr) Derived();
+ abstract_allocator::pointer bytes = alloc.allocate_bytes(sizeof(derived_type), alignment);
+ Derived *ptr = reinterpret_cast<Derived *>(bytes);
+ ptr->this_type::self_ptr = ptr;
+ new (ptr->this_type::self_ptr) Derived();
return ptr;
}
- virtual this_type *copy_construct(const base_type &original, abstract_allocator &alloc) const
+ virtual this_type *copy_construct(abstract_allocator &alloc) const
{
- this_type *ptr = allocate(alloc);
- new (ptr->self_ptr) Derived(static_cast<const Derived &>(original));
+ abstract_allocator::pointer bytes = alloc.allocate_bytes(sizeof(derived_type), alignment);
+ Derived *ptr = reinterpret_cast<Derived *>(bytes);
+ ptr->this_type::self_ptr = ptr;
+ new (ptr->this_type::self_ptr) Derived(static_cast<const Derived &>(*this));
return ptr;
}
};
/// ensure correct alignment when allocating derived instances
- template <class Derived, class Base, class AbstractBase>
- size_t cloneable<Derived, Base, AbstractBase>::alignment = aligned_storage<sizeof(Derived)>::alignment;
+ template <class Derived, class Base/*, class AbstractBase*/>
+ size_t cloneable<Derived, Base/*, AbstractBase*/>::alignment = aligned_storage<sizeof(Derived)>::alignment;
} // namespace heterogenous
Modified: sandbox/monotonic/boost/heterogenous/detail/allocation.hpp
==============================================================================
--- sandbox/monotonic/boost/heterogenous/detail/allocation.hpp (original)
+++ sandbox/monotonic/boost/heterogenous/detail/allocation.hpp 2009-06-30 05:05:07 EDT (Tue, 30 Jun 2009)
@@ -7,6 +7,7 @@
#define BOOST_HETEROGENOUS_DETAIL_CONTAINER_BASE_HPP
#include <boost/heterogenous/detail/prefix.hpp>
+#include <boost/heterogenous/cloneable.hpp>
namespace boost
{
@@ -14,6 +15,40 @@
{
namespace detail
{
+ template <class U, class B>
+ struct pointer
+ {
+ typedef U derived_type;
+ typedef B base_type;
+ typedef cloneable<derived_type, base_type> ptr_type;
+ typedef typename cloneable<derived_type, base_type>::this_type cloneable_type;
+ typedef typename cloneable_type::abstract_base_type abstract_base_type;
+
+ private:
+ ptr_type *ptr;
+
+ public:
+ pointer(U *p = 0) : ptr(dynamic_cast<cloneable_type *>(p))
+ {
+ }
+ abstract_base_type *to_abstract() const
+ {
+ return ptr;
+ }
+ base_type *to_base() const
+ {
+ return ptr;
+ }
+ cloneable_type *to_cloneable() const
+ {
+ return ptr;
+ }
+ derived_type *to_derived() const
+ {
+ return ptr->cloneable_type::self_ptr;
+ }
+ };
+
template <class U, class Alloc>
U *allocate_type(Alloc &al)
{
@@ -23,8 +58,8 @@
// TODO: use variadic template arguments, or BOOST_PP
- template <class U, class Alloc>
- U *construct_type(Alloc &al)
+ template <class U, class Base, class Alloc>
+ pointer<U,Base> construct_type(Alloc &al)
{
typename Alloc::template rebind<U>::other alloc(al);
U *ptr = alloc.allocate(1);
@@ -32,24 +67,25 @@
return ptr;
}
- template <class U, class Alloc, class A0>
- U *construct_type(Alloc &al, A0 a0)
+
+ template <class U, class Base, class Alloc, class A0>
+ pointer<U,Base> construct_type(Alloc &al, A0 a0)
{
U *ptr = allocate_type<U>(al);
new (ptr) U(a0);
return ptr;
}
- template <class U, class Alloc, class A0, class A1>
- U *construct_type(Alloc &al, A0 a0, A1 a1)
+ template <class U, class Base, class Alloc, class A0, class A1>
+ pointer<U,Base> construct_type(Alloc &al, A0 a0, A1 a1)
{
U *ptr = allocate_type<U>(al);
new (ptr) U(a0, a1);
return ptr;
}
- template <class U, class Alloc, class A0, class A1, class A2>
- U *construct_type(Alloc &al, A0 a0, A1 a1, A2 a2)
+ template <class U, class Base, class Alloc, class A0, class A1, class A2>
+ pointer<U,Base> construct_type(Alloc &al, A0 a0, A1 a1, A2 a2)
{
U *ptr = allocate_type<U>(al);
new (ptr) U(a0, a1, a2);
Modified: sandbox/monotonic/boost/heterogenous/forward_declarations.hpp
==============================================================================
--- sandbox/monotonic/boost/heterogenous/forward_declarations.hpp (original)
+++ sandbox/monotonic/boost/heterogenous/forward_declarations.hpp 2009-06-30 05:05:07 EDT (Tue, 30 Jun 2009)
@@ -32,7 +32,7 @@
template <
class Derived
, class Base = default_base_type
- , class AbstractBase = abstract_cloneable<Base> >
+ >// this is too much uncessary customisation:, class AbstractBase = abstract_cloneable<Base> >
struct cloneable;
/// an adaptor for an existing class.
@@ -42,14 +42,14 @@
template <
class T
, class Base = default_base_type
- , class AbstractBase = abstract_cloneable<Base> >
+ >//, class AbstractBase = abstract_cloneable<Base> >
struct adaptor;
/// a heterogenous vector of objects
template <
class Base = default_base_type
, class Alloc = monotonic::allocator<int>
- , class AbstractBase = abstract_cloneable<Base> >
+ >//, class AbstractBase = abstract_cloneable<Base> >
struct vector;
/// a mapping of heterogenous objects to heterogenous objects
@@ -57,7 +57,7 @@
class Base = default_base_type
, class Pred = std::less<Base>
, class Alloc = monotonic::allocator<int>
- , class AbstractBase = abstract_cloneable<Base> >
+ >//, class AbstractBase = abstract_cloneable<Base> >
struct map;
} // namespace heterogenous
Modified: sandbox/monotonic/boost/heterogenous/map.hpp
==============================================================================
--- sandbox/monotonic/boost/heterogenous/map.hpp (original)
+++ sandbox/monotonic/boost/heterogenous/map.hpp 2009-06-30 05:05:07 EDT (Tue, 30 Jun 2009)
@@ -17,12 +17,13 @@
namespace heterogenous
{
/// a vector of heterogenous objects
- template <class Base, class Pred, class Alloc, class AbstractBase>
+ template <class Base, class Pred, class Alloc>//, class AbstractBase>
struct map
{
typedef typename make_clone_allocator<Alloc>::type allocator_type;
typedef Base base_type;
//typedef ptr_map<Base, Base, Pred, allocator, allocator_type> implementation;
+ typedef abstract_cloneable<Base> abstract_base_type;
typedef std::map<Base *, Base *, Pred, allocator_type> implementation;
@@ -33,7 +34,7 @@
typedef typename implementation::const_iterator const_iterator;
typedef typename implementation::key_type key_type;
typedef typename implementation::mapped_type mapped_type;
- typedef map<Base, Pred, Alloc, AbstractBase> this_type;
+ typedef map<Base, Pred, Alloc/*, AbstractBase*/> this_type;
private:
implementation impl;
@@ -64,7 +65,7 @@
template <class U>
this_type &value()
{
- U *val = detail::construct_type<U>(parent->get_allocator());
+ U *val = detail::construct_type<U,base_type>(parent->get_allocator()).to_derived();;
parent->insert(std::make_pair(key_instance, val));
return *parent;
}
@@ -73,14 +74,14 @@
template <class U, class A0>
this_type &value(A0 a0)
{
- U *val = detail::construct_type<U>(parent->get_allocator(), a0);
+ U *val = detail::construct_type<U,base_type>(parent->get_allocator(), a0).to_derived();;
parent->insert(std::make_pair(key_instance, val));
return *parent;
}
template <class U, class A0, class A1>
this_type &value(A0 a0, A1 a1)
{
- U *val = detail::construct_type<U>(parent->get_allocator(), a0, a1);
+ U *val = detail::construct_type<U,base_type>(parent->get_allocator(), a0, a1).to_derived();;
parent->insert(std::make_pair(key_instance, val));
return *parent;
}
@@ -90,7 +91,7 @@
template <class U>
value_adder key()
{
- U *key_instance = detail::construct_type<U>(get_allocator());
+ U *key_instance = detail::construct_type<U,base_type>(get_allocator()).to_derived();
return value_adder(*this, *key_instance);
}
@@ -98,19 +99,19 @@
template <class U, class A0>
value_adder key(A0 a0)
{
- U *key_instance = detail::construct_type<U>(get_allocator(), a0);
+ U *key_instance = detail::construct_type<U,base_type>(get_allocator(), a0).to_derived();
return value_adder(*this, *key_instance);
}
template <class U, class A0, class A1>
value_adder key(A0 a0, A1 a1)
{
- U *key_instance = detail::construct_type<U>(get_allocator(), a0, a1);
+ U *key_instance = detail::construct_type<U,base_type>(get_allocator(), a0, a1).to_derived();
return value_adder(*this, *key_instance);
}
template <class U, class A0, class A1, class A2>
value_adder key(A0 a0, A1 a1, A2 a2)
{
- U *key_instance = detail::construct_type<U>(get_allocator(), a0, a1, a2);
+ U *key_instance = detail::construct_type<U,base_type>(get_allocator(), a0, a1, a2).to_derived();
return value_adder(*this, *key_instance);
}
Modified: sandbox/monotonic/boost/heterogenous/vector.hpp
==============================================================================
--- sandbox/monotonic/boost/heterogenous/vector.hpp (original)
+++ sandbox/monotonic/boost/heterogenous/vector.hpp 2009-06-30 05:05:07 EDT (Tue, 30 Jun 2009)
@@ -20,12 +20,15 @@
namespace heterogenous
{
/// a vector of heterogenous objects
- template <class Base, class Alloc, class AbstractBase>
+ template <class Base, class Alloc>//, class AbstractBase>
struct vector
{
typedef Base base_type;
+ //typedef AbstractBase abstract_base_type;
+ typedef abstract_cloneable<Base> abstract_base_type;
typedef typename make_clone_allocator<Alloc>::type allocator_type;
- typedef ptr_vector<AbstractBase, allocator, allocator_type> implementation;
+ typedef ptr_vector<abstract_base_type, allocator, allocator_type> implementation;
+ //typedef ptr_vector<Base, allocator, allocator_type> implementation;
typedef typename implementation::value_type value_type;
typedef typename implementation::reference reference;
typedef typename implementation::const_reference const_reference;
@@ -175,22 +178,22 @@
template <class U>
void emplace_back()
{
- impl.push_back(detail::construct_type<U>(get_allocator()));
+ impl.push_back(detail::construct_type<U,base_type>(get_allocator()).to_abstract());
}
template <class U, class A0>
void emplace_back(A0 a0)
{
- impl.push_back(detail::construct_type<U>(get_allocator(), a0));
+ impl.push_back(detail::construct_type<U,base_type>(get_allocator(), a0).to_abstract());
}
template <class U, class A0, class A1>
void emplace_back(A0 a0, A1 a1)
{
- impl.push_back(detail::construct_type<U>(get_allocator(), a0,a1));
+ impl.push_back(detail::construct_type<U,base_type>(get_allocator(), a0,a1).to_abstract());
}
template <class U, class A0, class A1, class A2>
void emplace_back(A0 a0, A1 a1, A2 a2)
{
- impl.push_back(detail::construct_type<U>(get_allocator(), a0,a1,a2));
+ impl.push_back(detail::construct_type<U,base_type>(get_allocator(), a0,a1,a2).to_abstract());
}
typename implementation::allocator_type get_allocator()
Modified: sandbox/monotonic/libs/monotonic/test/clones/tests.cpp
==============================================================================
--- sandbox/monotonic/libs/monotonic/test/clones/tests.cpp (original)
+++ sandbox/monotonic/libs/monotonic/test/clones/tests.cpp 2009-06-30 05:05:07 EDT (Tue, 30 Jun 2009)
@@ -54,22 +54,56 @@
}
};
-// naive way of allowing reuse in derived types: factor out the implementation
-struct derived4_impl
+namespace mi_test
{
-};
-struct derived4 : derived4_impl, cloneable<derived4>
-{
-};
+ struct Q0 : cloneable<Q0>
+ {
+ int num;
+ Q0(int n = 0) : num(n) { }
+ };
+
+ struct Q1 : Q0, cloneable<Q1>
+ {
+ string s;
+ Q1() { }
+ Q1(string t) : s(t) { }
+ };
+
+}
-struct derived5 : derived4_impl, cloneable<derived5>
+void test_multiple_inheritance()
{
-};
+ using namespace mi_test;
+ typedef heterogenous::vector<> vec;
+ vec v;
+
+
+ Q0 *q0 = new Q0;
+ BOOST_ASSERT(typeid(*q0) == typeid(Q0));
+ Q0 *q0_c = dynamic_cast<Q0 *>(q0->clone(v.get_allocator()));
+ BOOST_ASSERT(typeid(*q0_c) == typeid(Q0));
+
+ Q1 *q1 = new Q1();
+ BOOST_ASSERT(typeid(*q1) == typeid(Q1));
+ //Q1 *q1_c = dynamic_cast<Q1 *>(q1->cloneable<Q1>::clone(v.get_allocator()));
+
+ Q0 *q1_c0 = dynamic_cast<Q0 *>(q1->cloneable<Q0>::abstract_base_type::clone(v.get_allocator()));
+ BOOST_ASSERT(typeid(*q1_c0) == typeid(Q0));
+
+ //Q1 *q1_c = dynamic_cast<Q1 *>(q1->cloneable<Q1>::abstract_base_type::clone(v.get_allocator()));
+ Q1 *q1_c = dynamic_cast<Q1 *>(q1->clone_as<Q1>(v.get_allocator()));
+ BOOST_ASSERT(typeid(*q1_c) == typeid(Q1));
+
+ v.emplace_back<Q0>(42);
+ v.emplace_back<Q1>("foo");
+
+ vec v2 = v;
+ BOOST_ASSERT(v2.ref_at<Q1>(1).s == "foo");
+}
void test_any();
void test_variant();
-
void test_map();
@@ -113,7 +147,8 @@
test_any();
test_variant();
- test_map();
+// test_map();
+ test_multiple_inheritance();
// a 'heterogenous' container of objects of any type that derives from common_base
typedef heterogenous::vector<my_base> vec;
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