|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r54550 - in sandbox/cloneable: boost/cloneable libs/cloneable/test
From: christian.schladetsch_at_[hidden]
Date: 2009-06-30 19:14:17
Author: cschladetsch
Date: 2009-06-30 19:14:16 EDT (Tue, 30 Jun 2009)
New Revision: 54550
URL: http://svn.boost.org/trac/boost/changeset/54550
Log:
added no_default_construction tag
Text files modified:
sandbox/cloneable/boost/cloneable/abstract_base.hpp | 8 +++---
sandbox/cloneable/boost/cloneable/base.hpp | 44 ++++++++++++++++++++++++++++++----------
sandbox/cloneable/boost/cloneable/forward_declarations.hpp | 7 ++++-
sandbox/cloneable/libs/cloneable/test/tests.cpp | 34 ++++++++++++++++++++++++++++--
4 files changed, 73 insertions(+), 20 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 19:14:16 EDT (Tue, 30 Jun 2009)
@@ -25,11 +25,11 @@
};
/// root structure for the cloneable object system
- template <class Base>
+ template <class Base, class DefaultCtor>
struct abstract_base : virtual Base
{
typedef Base base_type;
- typedef abstract_base<Base> this_type;
+ typedef abstract_base<Base,DefaultCtor> this_type;
/// make storage for a new instance, but do not invoke any constructor
virtual this_type *allocate(abstract_allocator &) const = 0;
@@ -64,7 +64,7 @@
template <class Ty>
Ty *clone_as(abstract_allocator &alloc) const
{
- const base<Ty, Base> *ptr = dynamic_cast<const base<Ty, Base> *>(this);
+ const base<Ty, Base, DefaultCtor> *ptr = dynamic_cast<const base<Ty, Base,DefaultCtor> *>(this);
if (ptr == 0)
throw std::bad_cast();
this_type *cloned = ptr->clone(alloc);
@@ -86,7 +86,7 @@
}
/// non-virtual method that creates a new instance of derived type using default allocator
- this_type *create_new() const
+ this_type *create() const
{
make_clone_allocator<default_allocator>::type alloc;
return create_new(alloc);
Modified: sandbox/cloneable/boost/cloneable/base.hpp
==============================================================================
--- sandbox/cloneable/boost/cloneable/base.hpp (original)
+++ sandbox/cloneable/boost/cloneable/base.hpp 2009-06-30 19:14:16 EDT (Tue, 30 Jun 2009)
@@ -14,14 +14,40 @@
{
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 Ty, class Alloc>
+ static Derived *given(Ty *self, Alloc &alloc, size_t alignment)
+ {
+ throw no_default_construction();
+ }
+ };
+ }
+
/// base for the given derived type, using the given base class
- template <class Derived, class Base>
- struct base : abstract_base<Base>
+ template <class Derived, class Base, class HasDefaultCtor>
+ struct base : abstract_base<Base,HasDefaultCtor>
{
typedef Derived derived_type;
typedef Base base_type;
- typedef abstract_base<Base> abstract_base_type;
- typedef base<Derived, Base> this_type;
+ typedef abstract_base<Base,HasDefaultCtor> abstract_base_type;
+ typedef base<Derived, Base,HasDefaultCtor> this_type;
static const size_t alignment; ///< required alignment for allocation
mutable derived_type *self_ptr; ///< pointer to derived object in this
@@ -48,11 +74,7 @@
virtual this_type *create_new(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();
- return ptr;
+ return detail::create_new<Derived,HasDefaultCtor>::given(this, alloc, alignment);
}
virtual this_type *copy_construct(abstract_allocator &alloc) const
@@ -66,8 +88,8 @@
};
/// ensure correct alignment when allocating derived instances
- template <class Derived, class Base/*, class AbstractBase*/>
- const size_t base<Derived, Base/*, AbstractBase*/>::alignment = aligned_storage<sizeof(Derived)>::alignment;
+ template <class Derived, class Base, class HasDefaultCtor>
+ const size_t base<Derived, Base, HasDefaultCtor>::alignment = aligned_storage<sizeof(Derived)>::alignment;
} // namespace cloneable
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 19:14:16 EDT (Tue, 30 Jun 2009)
@@ -24,8 +24,11 @@
/// wish to use a custom base type
struct default_base_type;
+ struct default_construction {};
+ struct no_default_construction {};
+
/// provides a set of pure-virtual methods for allocation, de-allocation, and cloning
- template <class Base>
+ template <class Base = default_base_type, class DefaultCtor = default_construction>
struct abstract_base;
/// a structure derived from this, with type Derived, is correctly
@@ -33,7 +36,7 @@
template <
class Derived
, class Base = default_base_type
- >// this is too much uncessary customisation:, class AbstractBase = abstract_cloneable<Base> >
+ , class Ctor = default_construction>
struct base;
/// an adaptor for an existing class.
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 19:14:16 EDT (Tue, 30 Jun 2009)
@@ -139,10 +139,10 @@
bool custom_cloned;
T0() : custom_cloned(false) { }
- /// override the means to create a copy from abstract_base<>
+ /// override the means to create a copy of this
T0 *make_copy(abstract_allocator &alloc) const
{
- T0 *ptr = create<T0>(alloc);
+ T0 *ptr = cloneable::create<T0>(alloc);
ptr->custom_cloned = true;
return ptr;
}
@@ -152,13 +152,41 @@
BOOST_AUTO_TEST_CASE(test_custom_clone)
{
using namespace custom_clone_test;
- T0 *p = new T0;
+ abstract_base<> *p = new T0();
T0 *q = p->clone_as<T0>();
BOOST_ASSERT(q && q->custom_cloned);
delete p;
delete q;
}
+namespace no_default_ctor_test
+{
+ struct T0 : base<T0, default_base_type, no_default_construction>
+ {
+ T0(int) { }
+ };
+}
+
+BOOST_AUTO_TEST_CASE(test_no_default_ctor)
+{
+ using namespace no_default_ctor_test;
+ T0 *p = new T0(10);
+ T0 *q = p->clone_as<T0>();
+ BOOST_ASSERT(q && typeid(*q) == typeid(T0));
+ delete q;
+ bool caught = false;
+ try
+ {
+ T0 *r = dynamic_cast<T0 *>(p->create());
+ }
+ catch (no_default_construction)
+ {
+ caught = true;
+ }
+ BOOST_ASSERT(caught);
+ delete p;
+}
+
struct my_base
{
virtual ~my_base() { }
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