$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
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() { }