Boost logo

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