$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r54426 - in sandbox/monotonic: boost boost/monotonic boost/ptr_container/detail libs/monotonic/test libs/monotonic/test/clones
From: christian.schladetsch_at_[hidden]
Date: 2009-06-28 01:19:59
Author: cschladetsch
Date: 2009-06-28 01:19:57 EDT (Sun, 28 Jun 2009)
New Revision: 54426
URL: http://svn.boost.org/trac/boost/changeset/54426
Log:
added boost/abstract_allocator.hpp
Added:
   sandbox/monotonic/boost/abstract_allocator.hpp   (contents, props changed)
Text files modified: 
   sandbox/monotonic/boost/monotonic/allocator_base.hpp                      |    16 ++                                      
   sandbox/monotonic/boost/ptr_container/detail/reversible_ptr_container.hpp |    39 ++++++-                                 
   sandbox/monotonic/boost/ptr_container/detail/scoped_deleter.hpp           |     6                                         
   sandbox/monotonic/libs/monotonic/test/clones/clones.vcproj                |   196 ++++++++++++++++++++++++++++++++++++--- 
   sandbox/monotonic/libs/monotonic/test/clones/main.cpp                     |    85 ++++++++++++++---                       
   sandbox/monotonic/libs/monotonic/test/monotonic.vcproj                    |     4                                         
   6 files changed, 303 insertions(+), 43 deletions(-)
Added: sandbox/monotonic/boost/abstract_allocator.hpp
==============================================================================
--- (empty file)
+++ sandbox/monotonic/boost/abstract_allocator.hpp	2009-06-28 01:19:57 EDT (Sun, 28 Jun 2009)
@@ -0,0 +1,27 @@
+// 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_ABSTRACT_ALLOCATOR_HPP
+#define BOOST_ABSTRACT_ALLOCATOR_HPP
+
+#include <memory>
+
+namespace boost
+{
+	/// base class for (wrapped) allocators that may be used with cloneable::base
+	struct abstract_allocator
+	{
+		typedef char *pointer;
+
+		virtual pointer allocate_bytes(size_t num_bytes, size_t alignment) = 0;
+
+		virtual void deallocate_bytes(pointer) = 0;
+	};
+
+} // namespace boost
+
+#endif // BOOST_ABSTRACT_ALLOCATOR_HPP
+
+//EOF
Modified: sandbox/monotonic/boost/monotonic/allocator_base.hpp
==============================================================================
--- sandbox/monotonic/boost/monotonic/allocator_base.hpp	(original)
+++ sandbox/monotonic/boost/monotonic/allocator_base.hpp	2009-06-28 01:19:57 EDT (Sun, 28 Jun 2009)
@@ -6,6 +6,7 @@
 #ifndef BOOST_MONOTONIC_ALLOCATOR_BASE_HPP
 #define BOOST_MONOTONIC_ALLOCATOR_BASE_HPP
 
+#include <boost/abstract_allocator.hpp>
 #include <boost/assert.hpp>
 #include <boost/monotonic/detail/prefix.hpp>
 #include <boost/type_traits/has_trivial_constructor.hpp>
@@ -27,7 +28,7 @@
         {
                 /// common to other monotonic allocators for type T of type Derived
                 template <class T, class Derived>
-		struct allocator_base
+		struct allocator_base : abstract_allocator
                 {
                         typedef size_t size_type;
                         typedef ptrdiff_t difference_type;
@@ -41,12 +42,23 @@
 //			typedef mpl::integral_c<unsigned, 2> version;
                         //typedef boost::interprocess::version_type<allocator_base, 2>   version;
 
-
                         BOOST_STATIC_CONSTANT(size_t, alignment = boost::aligned_storage<sizeof(T)>::alignment);
 
                 //private:
                         storage_base *storage;
 
+			// override for abstract_allocator
+			virtual abstract_allocator::pointer allocate_bytes(size_t num_bytes, size_t alignment)
+			{
+				void *ptr = storage->allocate(num_bytes, alignment);
+				return reinterpret_cast<abstract_allocator::pointer>(ptr);
+			}
+
+			virtual void deallocate_bytes(char * /*bytes*/)
+			{
+				// do nothing
+			}
+
                 public:
                         allocator_base(storage_base &store) throw() 
                                 : storage(&store) { }
Modified: sandbox/monotonic/boost/ptr_container/detail/reversible_ptr_container.hpp
==============================================================================
--- sandbox/monotonic/boost/ptr_container/detail/reversible_ptr_container.hpp	(original)
+++ sandbox/monotonic/boost/ptr_container/detail/reversible_ptr_container.hpp	2009-06-28 01:19:57 EDT (Sun, 28 Jun 2009)
@@ -115,6 +115,33 @@
                 return res;
             }
             
+			template< class Iter, class Alloc >
+			static Ty_* allocate_clone_from_iterator( Iter i, Alloc &alloc )
+			{ 
+				return allocate_clone( Config::get_const_pointer( i ), alloc );
+			}
+
+			template <class Alloc>
+			static Ty_* allocate_clone( const Ty_* x, Alloc &alloc )
+			{
+				if( allow_null_values )
+				{
+					if( x == 0 )
+						return 0;
+				}
+				else
+				{
+					BOOST_ASSERT( x != 0 && "Cannot insert clone of null!" );
+				}
+
+				Ty_* res = CloneAllocator::allocate_clone( *x, alloc );
+				BOOST_ASSERT( typeid(*res) == typeid(*x) &&
+					"CloneAllocator::allocate_clone() does not clone the "
+					"object properly. Check that new_clone() is implemented"
+					" correctly" );
+				return res;
+			}
+
             static void deallocate_clone( const Ty_* x )
             {
                 if( allow_null_values )
@@ -195,12 +222,12 @@
             sd.release(); 
         }
         
-        template< class ForwardIterator >
+        template< class ForwardIterator, class Alloc >
         void clone_assign( ForwardIterator first, 
-                           ForwardIterator last ) // strong 
+                           ForwardIterator last, Alloc &alloc ) // strong 
         {
             BOOST_ASSERT( first != last );
-            scoped_deleter sd( first, last );      // strong
+            scoped_deleter sd( first, last, alloc );      // strong
             copy_clones_and_release( sd );         // nothrow
         }
 
@@ -209,7 +236,7 @@
                                 ForwardIterator last )
         {
             BOOST_ASSERT( first != last );
-            scoped_deleter sd( first, last );
+            scoped_deleter sd( first, last, get_allocator() );
             insert_clones_and_release( sd, end() );
         }
         
@@ -280,11 +307,11 @@
         }        
 
         template< class I >
-        void constructor_impl( I first, I last, std::input_iterator_tag ) // basic
+        void constructor_impl( I first, I last, std::input_iterator_tag) // basic
         {
             while( first != last )
             {
-                insert( end(), null_cloner_type::allocate_clone_from_iterator(first) );
+                insert( end(), null_cloner_type::allocate_clone_from_iterator(first, get_allocator()) );
                 ++first;
             }
         }
Modified: sandbox/monotonic/boost/ptr_container/detail/scoped_deleter.hpp
==============================================================================
--- sandbox/monotonic/boost/ptr_container/detail/scoped_deleter.hpp	(original)
+++ sandbox/monotonic/boost/ptr_container/detail/scoped_deleter.hpp	2009-06-28 01:19:57 EDT (Sun, 28 Jun 2009)
@@ -60,14 +60,14 @@
 
 
             
-            template< class InputIterator >
-            scoped_deleter ( InputIterator first, InputIterator last  ) // strong
+            template< class InputIterator, class Alloc >
+            scoped_deleter ( InputIterator first, InputIterator last,  Alloc &alloc ) // strong
                 : ptrs_( new T*[ std::distance(first,last) ] ),
                   stored_(0),
                   released_( false )
             {
                 for( ; first != last; ++first )
-                    add( CloneAllocator::allocate_clone_from_iterator( first ) );
+                    add( CloneAllocator::allocate_clone_from_iterator( first, alloc ) );
                 BOOST_ASSERT( stored_ > 0 );
             }
 
Modified: sandbox/monotonic/libs/monotonic/test/clones/clones.vcproj
==============================================================================
--- sandbox/monotonic/libs/monotonic/test/clones/clones.vcproj	(original)
+++ sandbox/monotonic/libs/monotonic/test/clones/clones.vcproj	2009-06-28 01:19:57 EDT (Sun, 28 Jun 2009)
@@ -167,27 +167,191 @@
         </References>
         <Files>
                 <Filter
-			Name="Source Files"
-			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
-			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
-			>
-			<File
-				RelativePath=".\main.cpp"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="Header Files"
+			Name="boost"
                         Filter="h;hpp;hxx;hm;inl;inc;xsd"
                         UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
 			>
+			<Filter
+				Name="ptr_container"
+				>
+				<File
+					RelativePath="..\..\..\..\boost\ptr_container\clone_allocator.hpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\ptr_container\exception.hpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\ptr_container\indirect_fun.hpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\ptr_container\nullable.hpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\ptr_container\ptr_array.hpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\ptr_container\ptr_circular_buffer.hpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\ptr_container\ptr_container.hpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\ptr_container\ptr_deque.hpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\ptr_container\ptr_inserter.hpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\ptr_container\ptr_list.hpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\ptr_container\ptr_map.hpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\ptr_container\ptr_map_adapter.hpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\ptr_container\ptr_sequence_adapter.hpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\ptr_container\ptr_set.hpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\ptr_container\ptr_set_adapter.hpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\ptr_container\ptr_unordered_map.hpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\ptr_container\ptr_unordered_set.hpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\ptr_container\ptr_vector.hpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\ptr_container\serialize_ptr_array.hpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\ptr_container\serialize_ptr_circular_buffer.hpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\ptr_container\serialize_ptr_container.hpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\ptr_container\serialize_ptr_deque.hpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\ptr_container\serialize_ptr_list.hpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\ptr_container\serialize_ptr_map.hpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\ptr_container\serialize_ptr_set.hpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\ptr_container\serialize_ptr_unordered_map.hpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\ptr_container\serialize_ptr_unordered_set.hpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\ptr_container\serialize_ptr_vector.hpp"
+					>
+				</File>
+				<Filter
+					Name="detail"
+					>
+					<File
+						RelativePath="..\..\..\..\boost\ptr_container\detail\associative_ptr_container.hpp"
+						>
+					</File>
+					<File
+						RelativePath="..\..\..\..\boost\ptr_container\detail\default_deleter.hpp"
+						>
+					</File>
+					<File
+						RelativePath="..\..\..\..\boost\ptr_container\detail\is_convertible.hpp"
+						>
+					</File>
+					<File
+						RelativePath="..\..\..\..\boost\ptr_container\detail\map_iterator.hpp"
+						>
+					</File>
+					<File
+						RelativePath="..\..\..\..\boost\ptr_container\detail\meta_functions.hpp"
+						>
+					</File>
+					<File
+						RelativePath="..\..\..\..\boost\ptr_container\detail\move.hpp"
+						>
+					</File>
+					<File
+						RelativePath="..\..\..\..\boost\ptr_container\detail\reversible_ptr_container.hpp"
+						>
+					</File>
+					<File
+						RelativePath="..\..\..\..\boost\ptr_container\detail\scoped_deleter.hpp"
+						>
+					</File>
+					<File
+						RelativePath="..\..\..\..\boost\ptr_container\detail\serialize_ptr_map_adapter.hpp"
+						>
+					</File>
+					<File
+						RelativePath="..\..\..\..\boost\ptr_container\detail\serialize_reversible_cont.hpp"
+						>
+					</File>
+					<File
+						RelativePath="..\..\..\..\boost\ptr_container\detail\serialize_xml_names.hpp"
+						>
+					</File>
+					<File
+						RelativePath="..\..\..\..\boost\ptr_container\detail\static_move_ptr.hpp"
+						>
+					</File>
+					<File
+						RelativePath="..\..\..\..\boost\ptr_container\detail\throw_exception.hpp"
+						>
+					</File>
+					<File
+						RelativePath="..\..\..\..\boost\ptr_container\detail\void_ptr_iterator.hpp"
+						>
+					</File>
+				</Filter>
+			</Filter>
                 </Filter>
-		<Filter
-			Name="Resource Files"
-			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
-			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+		<File
+			RelativePath=".\main.cpp"
 			>
-		</Filter>
+		</File>
         </Files>
         <Globals>
         </Globals>
Modified: sandbox/monotonic/libs/monotonic/test/clones/main.cpp
==============================================================================
--- sandbox/monotonic/libs/monotonic/test/clones/main.cpp	(original)
+++ sandbox/monotonic/libs/monotonic/test/clones/main.cpp	2009-06-28 01:19:57 EDT (Sun, 28 Jun 2009)
@@ -4,6 +4,7 @@
 
 #include <iostream>
 #include <boost/ptr_container/ptr_vector.hpp>
+#include <boost/abstract_allocator.hpp>
 #include <boost/monotonic/allocator.hpp>
 
 using namespace std;
@@ -15,6 +16,22 @@
 
         namespace cloneable 
         {
+		struct allocator;
+
+		struct dyn_alloc_base
+		{
+
+		};
+
+		template <class Derived>
+		struct dyn_alloc : dyn_alloc_base
+		{
+			template <class Base, class Alloc>
+			static void *alloc(Base *ptr, Alloc &a)
+			{
+				return new Derived();
+			}
+		};
 
                 // common base for all base types for hierachies
                 struct base_base
@@ -22,27 +39,59 @@
                         virtual ~base_base() { }
 
                         // this can't work because it doesnt have an allocator :/
-			virtual base_base *clone() const = 0;
+			virtual base_base *clone() const { return 0; }
+
+			virtual base_base *allocate(boost::abstract_allocator &alloc) const = 0;
+			virtual base_base *create(boost::abstract_allocator &alloc) const = 0;
+			virtual base_base *copy_construct(const base_base &original, boost::abstract_allocator &alloc) const = 0;
+
                 };
 
                 template <class Derived>
                 struct base : base_base
                 {
                         typedef Derived derived_type;
+			typedef base<derived_type> this_type;
+
+		private:
+			static size_t alignment;
+			mutable derived_type *self_ptr;
 
-			// idea: pass the allocator to a non-virtual clone_with(alloc) method in the base.
-			template <class Alloc>
-			static derived_type *clone_with(Alloc &alloc)
-			{
-				derived_type *copy = alloc.allocate(1);
-				// passing ctor args is an outstanding issue; can be helped by:
-				//	1. over-riding clone_with in derived
-				//  2. using super-set allocators with variadic template args for construct method
-				alloc.construct(copy);	
-				return copy;
+			derived_type *&self(derived_type *ptr) const
+			{
+				return ptr->this_type::self_ptr;
+			}
+
+		public:
+			base() : self_ptr(0) { }
+
+			virtual base<Derived> *allocate(boost::abstract_allocator &alloc) const 
+			{
+				boost::abstract_allocator::pointer bytes = alloc.allocate_bytes(sizeof(derived_type), alignment);
+				Derived *ptr = reinterpret_cast<Derived *>(bytes);
+				self(ptr) = ptr;
+				return ptr;
+			}
+
+			virtual base<Derived> *create(boost::abstract_allocator &alloc) const 
+			{
+				base<Derived> *ptr = allocate(alloc);
+				//new (ptr) this_type();
+				new (ptr->self_ptr) Derived();
+				return ptr;
+			}
+
+			virtual base<Derived> *copy_construct(const base_base &original, boost::abstract_allocator &alloc) const 
+			{ 
+				base<Derived> *ptr = allocate(alloc);
+				//new (ptr) this_type();
+				new (ptr->self_ptr) Derived(static_cast<const Derived &>(original));
+				return ptr;
                         }
                 };
-		
+		template <class D>
+		size_t base<D>::alignment = boost::aligned_storage<sizeof(D)>::alignment;
+
                 struct allocator
                 {
                         template< class U >
@@ -71,8 +120,8 @@
                         template< class U, class Alloc >
                         static U* allocate_clone( const U& r, Alloc &alloc )
                         {
-				typedef typename Alloc::template rebind<U>::other my_alloc(alloc);
-				return r.clone_with(my_alloc);
+				U *ptr = r.copy_construct(r, alloc);
+				return ptr;
                         }
 
                         // idea: this is not even needed? 
@@ -80,7 +129,7 @@
                         template< class U, class Alloc >
                         static U* deallocate_clone( const U* r, Alloc &alloc )
                         {
-				typedef typename Alloc::template rebind<U>::other my_alloc(alloc);
+				typename Alloc::template rebind<U>::other my_alloc(alloc);
                                 my_alloc.deallocate(const_cast<U *>(r));
                         }
                 };
@@ -162,7 +211,11 @@
                 //! ...
                 //! bases.push_back<derivedN>(ctor_args...);
 
-		// ...promptly breaks everything by using the heap to make the clones in copy :/
+		// this now works properly; after small changes to:
+		//		ptr_container/detail/scoped_ptr.hpp
+		//		ptr_container/detail/reversible_ptr_container.hpp
+		// and by introducing boost::abstract_allocator
+
                 vec copy = bases;
 
                 // idea: could be fixed by using base<derived>::clone_with(orig, rebind<derived>(alloc)) in the ptr_container...
Modified: sandbox/monotonic/libs/monotonic/test/monotonic.vcproj
==============================================================================
--- sandbox/monotonic/libs/monotonic/test/monotonic.vcproj	(original)
+++ sandbox/monotonic/libs/monotonic/test/monotonic.vcproj	2009-06-28 01:19:57 EDT (Sun, 28 Jun 2009)
@@ -251,6 +251,10 @@
                 <Filter
                         Name="boost"
 			>
+			<File
+				RelativePath="..\..\..\boost\abstract_allocator.hpp"
+				>
+			</File>
                         <Filter
                                 Name="monotonic"
 				>