|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r54623 - in sandbox/cloneable: boost/cloneable boost/cloneable/detail libs/cloneable/test
From: christian.schladetsch_at_[hidden]
Date: 2009-07-03 21:45:20
Author: cschladetsch
Date: 2009-07-03 21:45:19 EDT (Fri, 03 Jul 2009)
New Revision: 54623
URL: http://svn.boost.org/trac/boost/changeset/54623
Log:
moved is_derived to detail::
should be renamed to detail::derived<>
Added:
sandbox/cloneable/boost/cloneable/detail/create_new.hpp (contents, props changed)
sandbox/cloneable/boost/cloneable/detail/is_derived.hpp (contents, props changed)
Text files modified:
sandbox/cloneable/boost/cloneable/abstract_base.hpp | 8
sandbox/cloneable/boost/cloneable/base.hpp | 166 ++++++++++++---------------------------
sandbox/cloneable/boost/cloneable/detail/container_base.hpp | 26 ++++-
sandbox/cloneable/boost/cloneable/forward_declarations.hpp | 46 +++++-----
sandbox/cloneable/boost/cloneable/instance.hpp | 2
sandbox/cloneable/boost/cloneable/list.hpp | 1
sandbox/cloneable/libs/cloneable/test/cloneable.vcproj | 8 +
sandbox/cloneable/libs/cloneable/test/tests.cpp | 87 +++++++++++++++-----
8 files changed, 170 insertions(+), 174 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-07-03 21:45:19 EDT (Fri, 03 Jul 2009)
@@ -46,13 +46,13 @@
/// default base type used for object hierarchies. the user can supply their own when using
/// cloneable<Derived, Base>.
/// this will be used as a base by default.
- struct default_base_type : abstract_object<default_base_type>
+ struct base_type : abstract_object<base_type>
{
- virtual ~default_base_type() { }
+ virtual ~base_type() { }
- std::string to_string() const { return "default_base_type"; }
+ std::string to_string() const { return "base_type"; }
size_t hash_value() const { return 0; }
- bool less(const default_base_type &other) const { return false; }
+ bool less(const base_type &other) const { return false; }
};
/// root structure for the cloneable object system
Modified: sandbox/cloneable/boost/cloneable/base.hpp
==============================================================================
--- sandbox/cloneable/boost/cloneable/base.hpp (original)
+++ sandbox/cloneable/boost/cloneable/base.hpp 2009-07-03 21:45:19 EDT (Fri, 03 Jul 2009)
@@ -8,140 +8,78 @@
#include <boost/aligned_storage.hpp>
#include <boost/cloneable/detail/prefix.hpp>
-#include <boost/cloneable/abstract_base.hpp>
+#include <boost/cloneable/detail/is_derived.hpp>
+#include <boost/cloneable/detail/create_new.hpp>
namespace boost
{
namespace cloneable
{
- namespace detail
+ namespace impl
{
- template <class Derived, class HasDefaultCtor>
- struct create_new
- {
- template <class Self, class Alloc>
- static Derived *given(Self *self, Alloc &alloc, size_t alignment)
- {
- abstract_allocator::pointer bytes = alloc.allocate_bytes(sizeof(Derived), alignment);
- Derived *ptr = reinterpret_cast<Derived *>(bytes);
- ptr->Self::self_ptr = ptr;
- new (ptr->Self::self_ptr) Derived();
- return ptr;
- }
- };
- template <class Derived>
- struct create_new<Derived, no_default_construction>
- {
- template <class Self, class Alloc>
- static Derived *given(Self *self, Alloc &alloc, size_t alignment)
+ using mpl::bool_;
+ using mpl::if_;
+ using mpl::or_;
+
+ template <class Derived, class Base, class DefaultCtorTag>
+ struct base
+ : detail::is_derived<Derived, Base>
+ , virtual is_cloneable_tag
+ , virtual DefaultCtorTag
+ {
+ typedef Derived derived_type;
+ typedef Base base_type;
+ typedef DefaultCtorTag default_constructable_type;
+ typedef base<derived_type, base_type, default_constructable_type> this_type;
+
+ virtual this_type *create_new(abstract_allocator &alloc) const
{
- throw no_default_construction();
+ return detail::create_new<Derived, DefaultCtorTag>::given(this, alloc, alignment);
}
};
- } // namespace impl
-
- template <class Derived, class Base>
- struct is_derived
- : abstract_base<Base>
- {
- typedef Derived derived_type;
- typedef Base base_type;
- typedef abstract_base<base_type> abstract_base_type;
- typedef is_derived<derived_type, base_type> this_type;
- using abstract_base_type::clone;
+ template <class T>
+ struct is_nil : is_same<T,nil> { };
- mutable Derived *self_ptr; ///< pointer to derived object in this
-
- is_derived()
+ template <class D, class A, class B>
+ struct make_base
{
- self_ptr = static_cast<derived_type *>(this);
- }
+ template <class T>
+ struct get_base_type : if_<is_nil<T>, base_type, T> { };
- /// 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
- {
- const is_derived<Ty,Base> *ptr = dynamic_cast<const is_derived<Ty,Base> *>(this);
- if (ptr == 0)
- throw std::bad_cast();
- abstract_base_type *cloned = ptr->clone(alloc);
- return dynamic_cast<Ty *>(cloned);
- }
-
- /// make a copy of this instance using default allocator,
- /// selecting sub-object to clone
- template <class Ty>
- Ty *clone_as() const
- {
- make_clone_allocator<default_allocator>::type alloc;
- return clone_as<Ty>(alloc);
- }
- };
-
- /// base for the given derived type, using the given base class and default construction tag
- template <class Derived, class Base, class DefaultCtorTag>
- struct base
- : is_derived<Derived, Base>
- , virtual is_cloneable_tag
- , virtual DefaultCtorTag
- {
- typedef Derived derived_type;
- typedef Base base_type;
- typedef DefaultCtorTag default_constructable_type;
+ template <class T>
+ struct get_default_construction_tag : if_<is_nil<T>, default_construction, T> { };
- typedef base<derived_type, base_type, default_constructable_type> this_type;
- typedef is_derived<Derived,Base> is_derived_type;
+ typedef is_convertible<A *, detail::ctag *> a_is_tag;
+ typedef is_convertible<B *, detail::ctag *> b_is_tag;
- static const size_t alignment; ///< required alignment for allocation
+ typedef typename if_<
+ is_nil<A>
+ , base<D, typename get_base_type<A>::type, typename get_default_construction_tag<B>::type>
+ , base<D, typename get_base_type<B>::type, typename get_default_construction_tag<A>::type>
+ >::type type1;
- public:
- base()
- {
- }
-
- const std::type_info &get_type() const
- {
- return typeid(derived_type);
- }
-
- virtual this_type *allocate(abstract_allocator &alloc) const
- {
- abstract_allocator::pointer bytes = alloc.allocate_bytes(sizeof(derived_type), alignment);
- Derived *ptr = reinterpret_cast<Derived *>(bytes);
- ptr->is_derived_type::self_ptr = ptr;
- return ptr;
- }
-
- void deallocate(abstract_allocator &alloc)
- {
- Derived *ptr = is_derived_type::self_ptr;
- alloc.deallocate_bytes(reinterpret_cast<abstract_allocator::pointer>(ptr), alignment);
- }
-
- virtual this_type *create_new(abstract_allocator &alloc) const
- {
- return detail::create_new<Derived, DefaultCtorTag>::given(this, alloc, alignment);
- }
-
- virtual this_type *copy_construct(abstract_allocator &alloc) const
- {
- abstract_allocator::pointer bytes = alloc.allocate_bytes(sizeof(derived_type), alignment);
- Derived *ptr = reinterpret_cast<Derived *>(bytes);
- ptr->is_derived_type::self_ptr = ptr;
- new (ptr->is_derived_type::self_ptr) Derived(static_cast<const Derived &>(*this));
- return ptr;
- }
+ typedef base<D, typename get_base_type<A>::type, typename get_default_construction_tag<B>::type> type;
+ };
+ }
+ /// base for the given derived type, using the given base class and default construction tag
+ template <class D, class A, class B>
+ struct base : impl::make_base<D,A,B>::type
+ {
+ typedef typename impl::make_base<D,A,B>::type parent_type;
+ typedef base<D,A,B> this_type;
+ typedef typename parent_type::base_type base_type;
+ BOOST_STATIC_ASSERT(is_cloneable<this_type>::value);
};
- /// ensure correct alignment when allocating derived instances
- template <class Derived, class Base, class DefaultCtor>
- const size_t base<Derived, Base, DefaultCtor>::alignment = aligned_storage<sizeof(Derived)>::alignment;
-
+ /*
+ template <class Derived, class A, class B>
+ struct base : impl::base<Derived,A,B>
+ {
+ };
+ */
} // namespace cloneable
} // namespace boost
Modified: sandbox/cloneable/boost/cloneable/detail/container_base.hpp
==============================================================================
--- sandbox/cloneable/boost/cloneable/detail/container_base.hpp (original)
+++ sandbox/cloneable/boost/cloneable/detail/container_base.hpp 2009-07-03 21:45:19 EDT (Fri, 03 Jul 2009)
@@ -11,6 +11,13 @@
#include <boost/cloneable/instance.hpp>
#include <boost/cloneable/traits.hpp>
+#define BOOST_CLONEABLE_SCOPE_EXIT(locals) \
+ this_type *self = this; \
+ BOOST_SCOPE_EXIT(locals(self))
+
+#define BOOST_CLONEABLE_SCOPE_EXIT_END \
+ BOOST_SCOPE_EXIT_END
+
namespace boost
{
namespace cloneable
@@ -38,7 +45,10 @@
template <class T>
struct validate
{
- // can only add cloneable things to a heterogenous container
+ // can only add cloneable things to a heterogenous container.
+ // to make a type T cloneable, derive from cloneable::base<T>,
+ // or provide your own base-type Base and derive from cloneable::base<T,Base>.
+ // there is no restriction on the Base type.
BOOST_STATIC_ASSERT(is_cloneable<T>::value);
// you must ensure that base-types for objects that you add to a container
@@ -49,12 +59,17 @@
typedef T type;
};
- /// an instance of the given derived type U suitable for this container
+ /// an instance of the given derived type suitable for this container
template <class Derived>
struct instance
- : cloneable::instance<Derived, Base, Alloc, typename traits<Derived>::construction_tag>
+ : cloneable::instance<
+ typename validate<Derived>::type
+ , Base
+ , Alloc
+ , typename traits<typename validate<Derived>::type>::construction_tag>
{
- typedef cloneable::instance<Derived, Base, Alloc, typename traits<Derived>::construction_tag> parent_type;
+ typedef typename validate<Derived>::type derived_type;
+ typedef cloneable::instance<derived_type, Base, Alloc, typename traits<derived_type>::construction_tag> parent_type;
instance(allocator_type &a) : parent_type(a) { }
@@ -94,7 +109,7 @@
}
public:
- container_base()
+ container_base()
{
}
container_base(allocator_type &a)
@@ -110,7 +125,6 @@
{
return alloc;
}
-
};
} // namespace detail
Added: sandbox/cloneable/boost/cloneable/detail/create_new.hpp
==============================================================================
--- (empty file)
+++ sandbox/cloneable/boost/cloneable/detail/create_new.hpp 2009-07-03 21:45:19 EDT (Fri, 03 Jul 2009)
@@ -0,0 +1,51 @@
+// Copyright (C) 2009 Christian Schladetsch
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_CLONEABLE_DETAIL_CREATE_NEW_HPP
+#define BOOST_CLONEABLE_DETAIL_CREATE_NEW_HPP
+
+#include <boost/cloneable/detail/prefix.hpp>
+#include <boost/cloneable/allocator.hpp>
+
+namespace boost
+{
+ namespace cloneable
+ {
+ namespace detail
+ {
+ template <class Derived, class HasDefaultCtor>
+ struct create_new
+ {
+ template <class Self, class Alloc>
+ static Derived *given(Self *self, Alloc &alloc, size_t alignment)
+ {
+ abstract_allocator::pointer bytes = alloc.allocate_bytes(sizeof(Derived), alignment);
+ Derived *ptr = reinterpret_cast<Derived *>(bytes);
+ ptr->Self::self_ptr = ptr;
+ new (ptr->Self::self_ptr) Derived();
+ return ptr;
+ }
+ };
+ template <class Derived>
+ struct create_new<Derived, no_default_construction>
+ {
+ template <class Self, class Alloc>
+ static Derived *given(Self *self, Alloc &alloc, size_t alignment)
+ {
+ throw no_default_construction();
+ }
+ };
+
+ } // namespace detail
+
+ } // namespace cloneable
+
+} // namespace boost
+
+#include <boost/cloneable/detail/suffix.hpp>
+
+#endif // BOOST_CLONEABLE_DETAIL_CREATE_NEW_HPP
+
+//EOF
Added: sandbox/cloneable/boost/cloneable/detail/is_derived.hpp
==============================================================================
--- (empty file)
+++ sandbox/cloneable/boost/cloneable/detail/is_derived.hpp 2009-07-03 21:45:19 EDT (Fri, 03 Jul 2009)
@@ -0,0 +1,121 @@
+// Copyright (C) 2009 Christian Schladetsch
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_CLONEABLE_IS_DERIVED_HPP
+#define BOOST_CLONEABLE_IS_DERIVED_HPP
+
+#include <boost/aligned_storage.hpp>
+#include <boost/cloneable/detail/prefix.hpp>
+#include <boost/cloneable/abstract_base.hpp>
+
+namespace boost
+{
+ namespace cloneable
+ {
+ namespace detail
+ {
+ // mixin structure between base<> and abstract_base<> that supplies
+ // an interface to allow casting, cloning and creation of sub-objects
+ // of different types and default-constructableness
+ template <class Derived, class Base>
+ struct is_derived
+ : abstract_base<Base>
+ {
+ typedef Derived derived_type;
+ typedef Base base_type;
+ typedef abstract_base<base_type> abstract_base_type;
+ typedef is_derived<derived_type, base_type> this_type;
+
+ mutable Derived *self_ptr; ///< pointer to derived object in this
+ static const size_t alignment; ///< required alignment for allocation
+
+ is_derived()
+ {
+ self_ptr = static_cast<derived_type *>(this);
+ }
+
+ const std::type_info &get_type() const
+ {
+ return typeid(derived_type);
+ }
+
+ virtual this_type *allocate(abstract_allocator &alloc) const
+ {
+ abstract_allocator::pointer bytes = alloc.allocate_bytes(sizeof(derived_type), alignment);
+ Derived *ptr = reinterpret_cast<Derived *>(bytes);
+ ptr->this_type::self_ptr = ptr;
+ return ptr;
+ }
+
+ void deallocate(abstract_allocator &alloc)
+ {
+ Derived *ptr = self_ptr;
+ alloc.deallocate_bytes(reinterpret_cast<abstract_allocator::pointer>(ptr), alignment);
+ }
+
+ virtual this_type *copy_construct(abstract_allocator &alloc) const
+ {
+ 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;
+ }
+ /// 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
+ {
+ const is_derived<Ty,Base> *ptr = dynamic_cast<const is_derived<Ty,Base> *>(this);
+ if (ptr == 0)
+ throw std::bad_cast();
+ abstract_base_type *cloned = ptr->clone(alloc);
+ return dynamic_cast<Ty *>(cloned);
+ }
+
+ /// make a copy of this instance using default allocator,
+ /// selecting sub-object to clone
+ template <class Ty>
+ Ty *clone_as() const
+ {
+ make_clone_allocator<default_allocator>::type alloc;
+ return clone_as<Ty>(alloc);
+ }
+
+ template <class Ty>
+ Ty *create_as(abstract_allocator &alloc) const
+ {
+ typedef is_derived<Ty, Base> Embedded;
+ const Embedded *cross_cast = dynamic_cast<const Embedded *>(this);
+ if (cross_cast == 0)
+ throw std::bad_cast();
+ abstract_base_type *base = cross_cast->create_new(alloc);
+ return static_cast<Ty *>(static_cast<Embedded *>(base));
+ }
+
+ template <class Ty>
+ Ty *create_as() const
+ {
+ make_clone_allocator<default_allocator>::type alloc;
+ return create_as<Ty>(alloc);
+ }
+ };
+
+ /// ensure correct alignment when allocating derived instances
+ template <class Derived, class Base>
+ const size_t is_derived<Derived, Base>::alignment = aligned_storage<sizeof(Derived)>::alignment;
+
+ } // namespace detail
+
+ } // namespace cloneable
+
+} // namespace boost
+
+#include <boost/cloneable/detail/suffix.hpp>
+
+#endif // BOOST_CLONEABLE_IS_DERIVED_HPP
+
+//EOF
Modified: sandbox/cloneable/boost/cloneable/forward_declarations.hpp
==============================================================================
--- sandbox/cloneable/boost/cloneable/forward_declarations.hpp (original)
+++ sandbox/cloneable/boost/cloneable/forward_declarations.hpp 2009-07-03 21:45:19 EDT (Fri, 03 Jul 2009)
@@ -13,18 +13,11 @@
#include <boost/pointee.hpp>
#include <boost/cloneable/detail/prefix.hpp>
-#define BOOST_CLONEABLE_SCOPE_EXIT(locals) \
- this_type *self = this; \
- BOOST_SCOPE_EXIT(locals(self))
-
-#define BOOST_CLONEABLE_SCOPE_EXIT_END \
- BOOST_SCOPE_EXIT_END
-
namespace boost
{
-
namespace cloneable
{
+ /// allocator to use for clone or create operations when no allocator is provided
typedef std::allocator<char> default_allocator;
/// an abstract interface for an allocator that can allocate and de-allocate
@@ -33,27 +26,34 @@
/// empty structure with a virtual destructor used if the user does not
/// wish to use a custom base type
- struct default_base_type;
+ struct base_type;
- struct default_construction : mpl::true_ {};
- struct no_default_construction : mpl::false_ {};
- struct unknown_construction {};
+ namespace detail { struct ctag { }; }
+
+ /// {@ tags to inform about default-constructability
+ struct default_construction : detail::ctag, mpl::true_ {};
+ struct no_default_construction : detail::ctag, mpl::false_ {};
+ struct unknown_construction : detail::ctag {};
+ /// @}
/// provides a set of pure-virtual methods for allocation, de-allocation, and cloning
- template <class Base = default_base_type>
+ template <class Base = base_type>
struct abstract_base;
struct is_cloneable_tag { };
- template <class Derived, class Base = default_base_type>
- struct is_derived ;
+ struct nil { };
/// a structure derived from this, with type Derived, is correctly
/// cloneable from a base pointer, given an abstract_allocator.
+ /// TODO: allow Ctor and Base to be given in any order
template <
class Derived
- , class Base = default_base_type
- , class Ctor = default_construction>
+ , class Base = base_type
+ , class DefaultConstructionTag = default_construction
+ //, class Base = nil//base_type
+ //, class DefaultConstructionTag = nil//default_construction
+ >
struct base;
/// an adaptor for an existing class.
@@ -62,15 +62,14 @@
/// of effective type T, where T does not inherit from heterogenous::base.
template <
class T
- , class Base = default_base_type
- >//, class AbstractBase = abstract_cloneable<Base> >
+ , class Base = base_type>
struct adaptor;
// TODO: move to boost/heterogenous/foward
/// a heterogenous vector of objects
template
<
- class Base = default_base_type
+ class Base = base_type
, class Alloc = monotonic::allocator<int>
>
struct vector;
@@ -78,11 +77,12 @@
/// a heterogenous list of objects
template
<
- class Base = default_base_type
+ class Base = base_type
, class Alloc = monotonic::allocator<int>
>
struct list;
+ // TODO: use ptr_container::detail::indirect_fun<>
template <class Fun>
struct indirect
{
@@ -103,7 +103,7 @@
/// a mapping of heterogenous objects to heterogenous objects
template
<
- class Base = default_base_type
+ class Base = base_type
, class Pred = indirect<std::less<Base> >
, class Alloc = monotonic::allocator<int>
>
@@ -112,7 +112,7 @@
/// a set of heterogenous objects
template
<
- class Base = default_base_type
+ class Base = base_type
, class Pred = std::less<Base>
, class Alloc = monotonic::allocator<int>
>
Modified: sandbox/cloneable/boost/cloneable/instance.hpp
==============================================================================
--- sandbox/cloneable/boost/cloneable/instance.hpp (original)
+++ sandbox/cloneable/boost/cloneable/instance.hpp 2009-07-03 21:45:19 EDT (Fri, 03 Jul 2009)
@@ -58,7 +58,7 @@
typedef Abstract abstract_type;
typedef Derived derived_type;
- typedef is_derived<derived_type, base_type> is_derived_type;
+ typedef detail::is_derived<derived_type, base_type> is_derived_type;
protected:
derived_type *ptr;
Modified: sandbox/cloneable/boost/cloneable/list.hpp
==============================================================================
--- sandbox/cloneable/boost/cloneable/list.hpp (original)
+++ sandbox/cloneable/boost/cloneable/list.hpp 2009-07-03 21:45:19 EDT (Fri, 03 Jul 2009)
@@ -36,6 +36,7 @@
, Base
, Alloc>
parent_type;
+
using parent_type::base_type;
using parent_type::abstract_base_type;
using parent_type::allocator_type;
Modified: sandbox/cloneable/libs/cloneable/test/cloneable.vcproj
==============================================================================
--- sandbox/cloneable/libs/cloneable/test/cloneable.vcproj (original)
+++ sandbox/cloneable/libs/cloneable/test/cloneable.vcproj 2009-07-03 21:45:19 EDT (Fri, 03 Jul 2009)
@@ -296,11 +296,15 @@
>
</File>
<File
- RelativePath="..\..\..\boost\cloneable\detail\make_clone_allocator.hpp"
+ RelativePath="..\..\..\boost\cloneable\detail\create_new.hpp"
>
</File>
<File
- RelativePath="..\..\..\boost\cloneable\detail\pointer.hpp"
+ RelativePath="..\..\..\boost\cloneable\detail\is_derived.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\boost\cloneable\detail\make_clone_allocator.hpp"
>
</File>
<File
Modified: sandbox/cloneable/libs/cloneable/test/tests.cpp
==============================================================================
--- sandbox/cloneable/libs/cloneable/test/tests.cpp (original)
+++ sandbox/cloneable/libs/cloneable/test/tests.cpp 2009-07-03 21:45:19 EDT (Fri, 03 Jul 2009)
@@ -108,30 +108,16 @@
Q1(const char * t) : str(t) { }
};
- struct my_region { };
-}
-
-
-BOOST_AUTO_TEST_CASE(test_multiple_inheritance_vector)
-{
- using namespace mulitple_inheritance_test;
- typedef cloneable::vector<> vec;
-
- vec v;
- v.push_back<Q0>(42);
- v.push_back<Q1>("foo");
+ struct W : base<W> { };
- Q0 &q0 = v.as<Q0>(0);
- Q1 &q1 = v.as<Q1>(1);
+ struct Q2 : W, Q1, base<Q2>
+ {
+ };
- // ensure duplication of types with multiple cloneable sub-objects works correctly
- vec v2 = v;
-
- BOOST_ASSERT(v2.as<Q0>(0).num == 42);
- BOOST_ASSERT(v2.as<Q1>(1).str == "foo");
+ struct my_region { };
}
-BOOST_AUTO_TEST_CASE(test_clones)
+BOOST_AUTO_TEST_CASE(test_multiple_inheritance)
{
using namespace mulitple_inheritance_test;
@@ -155,8 +141,35 @@
Q1 *q1_c1 = q1->clone_as<Q1>(alloc);
BOOST_ASSERT(typeid(*q1_c1) == typeid(Q1));
+
+ // create new sub-objects
+ Q2 *q2 = create<Q2>(alloc);
+ Q0 *q2_0 = q2->create_as<Q0>(alloc);
+ Q1 *q2_1 = q2->create_as<Q1>(alloc);
+ W *q2_w = q2->create_as<W>(alloc);
+ BOOST_ASSERT(q2_0 && q2_1 && q2_w);
}
+
+BOOST_AUTO_TEST_CASE(test_multiple_inheritance_vector)
+{
+ using namespace mulitple_inheritance_test;
+ typedef cloneable::vector<> vec;
+
+ vec v;
+ v.push_back<Q0>(42);
+ v.push_back<Q1>("foo");
+
+ Q0 &q0 = v.as<Q0>(0);
+ Q1 &q1 = v.as<Q1>(1);
+
+ // ensure duplication of types with multiple cloneable sub-objects works correctly
+ vec v2 = v;
+
+ BOOST_ASSERT(v2.as<Q0>(0).num == 42);
+ BOOST_ASSERT(v2.as<Q1>(1).str == "foo");
+}
+
namespace custom_clone_test
{
struct T0 : base<T0>
@@ -186,10 +199,14 @@
namespace no_default_ctor_test
{
- struct T0 : base<T0, default_base_type, no_default_construction>
+ struct T0 : base<T0, base_type, no_default_construction>
{
T0(int) { }
};
+ struct T1 : T0, base<T1>
+ {
+ T1() : T0(4) { }
+ };
}
BOOST_AUTO_TEST_CASE(test_no_default_ctor)
@@ -206,14 +223,36 @@
bool caught = false;
try
{
- default_base_type *r = p->create();
+ base_type *r = p->create();
}
catch (no_default_construction)
{
caught = true;
}
BOOST_ASSERT(caught);
+
+ T1 *p1 = new T1();
+ // ensure we can clone a type that is derived from a type that is not
+ // default constructable
+ T1 *p1_clone = p1->clone_as<T1>();
+ BOOST_ASSERT(p1_clone);
+
+ // ensure that if we try to make a new sub-object that is not
+ // default-constructable, we throw
+ caught = false;
+ try
+ {
+ p1_clone->create_as<T0>();
+ }
+ catch (no_default_construction)
+ {
+ caught = true;
+ }
+ BOOST_ASSERT(caught);
+
delete p;
+ delete p1;
+ delete p1_clone;
}
struct my_base
@@ -248,7 +287,7 @@
namespace traits_test
{
struct T0 : base<T0> { };
- struct T1 : base<T1, default_base_type, no_default_construction> { };
+ struct T1 : base<T1, base_type, no_default_construction> { };
struct T2 { };
}
@@ -374,7 +413,7 @@
// does a deep copy, preserving concrete types
vec copy = bases;
- // each object in the container can be retrieved generically as a default_base_type
+ // each object in the container can be retrieved generically as a base_type
my_base &generic0 = copy[0];
my_base &generic1 = copy[1];
my_base &generic2 = copy[2];
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