From 18aa36f7b35d9334468c07c4c11706557468a507 Mon Sep 17 00:00:00 2001
From: Martin Nolte <mnolte@dune-project.org>
Date: Wed, 7 Apr 2010 07:36:52 +0000
Subject: [PATCH] add an allocator that can create object of arbitrary type
 (otherwise similar to STL)

This will need some further discussion, of course. It is intended for FS #766,
i.e., use an allocator to construct polymorphic objects in GenericGeometries.

[[Imported from SVN: r5954]]
---
 dune/common/Makefile.am      |  2 +-
 dune/common/polyallocator.hh | 38 ++++++++++++++++++++++++++++++++++++
 dune/common/smallobject.hh   | 33 ++++++++++++++++++++++++++++++-
 3 files changed, 71 insertions(+), 2 deletions(-)
 create mode 100644 dune/common/polyallocator.hh

diff --git a/dune/common/Makefile.am b/dune/common/Makefile.am
index 0ddb2f6a1..95b0e47c6 100644
--- a/dune/common/Makefile.am
+++ b/dune/common/Makefile.am
@@ -23,7 +23,7 @@ commoninclude_HEADERS = alignment.hh array.hh \
   static_assert.hh smallobject.hh version.hh \
   float_cmp.cc float_cmp.hh nullptr.hh \
   forloop.hh function.hh interfaces.hh \
-  gmpfield.hh mpiguard.hh
+  gmpfield.hh mpiguard.hh polyallocator.hh
 
 if EXPRESSIONTEMPLATES
 commoninclude_HEADERS += exprtmpl.hh exprtmpl/scalar.inc exprtmpl/exprexpr.inc
diff --git a/dune/common/polyallocator.hh b/dune/common/polyallocator.hh
new file mode 100644
index 000000000..f8c72b221
--- /dev/null
+++ b/dune/common/polyallocator.hh
@@ -0,0 +1,38 @@
+// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+// vi: set et ts=4 sw=2 sts=2:
+#ifndef DUNE_POLYALLOCATOR_HH
+#define DUNE_POLYALLOCATOR_HH
+
+namespace Dune
+{
+
+  // PolyAllocator
+  // -------------
+
+  struct PolyAllocator
+  {
+    template< class T >
+    T *allocate ( size_t n = 1 )
+    {
+      return static_cast< T * >( operator new( n * sizeof( T ) ) );
+    }
+
+    template< class T > void deallocate ( T *p )
+    {
+      operator delete( p );
+    }
+
+    template< class T > void construct ( T *p, const T &value )
+    {
+      new( p ) T( value );
+    }
+
+    template< class T > void destroy ( T *p )
+    {
+      p->~T();
+    }
+  };
+
+}
+
+#endif // #ifndef DUNE_POLYALLOCATOR_HH
diff --git a/dune/common/smallobject.hh b/dune/common/smallobject.hh
index 3f4d0b33c..a71d44540 100644
--- a/dune/common/smallobject.hh
+++ b/dune/common/smallobject.hh
@@ -156,6 +156,20 @@ namespace Dune
 
 
 
+  // SmallObjectPolyAllocator
+  // ------------------------
+
+  struct SmallObjectPolyAllocator
+  {
+    template< class T > T *allocate ( size_t n = 1 );
+    template< class T > void deallocate ( T *p );
+
+    template< class T > void construct ( T *p, const T &value ) { new( p ) T( value ); }
+    template< class T > void destroy ( T *p ) { p->~T(); }
+  };
+
+
+
   // Implementation of SmallObjectAllocator
   // --------------------------------------
 
@@ -163,7 +177,7 @@ namespace Dune
   inline typename SmallObjectAllocator< T >::pointer
   SmallObjectAllocator< T >::allocate ( size_type n, SmallObjectAllocator< void >::const_pointer hint )
   {
-    return reinterpret_cast< pointer >( SmallObjectPool::allocate( n * sizeof( T ) ) );
+    return static_cast< pointer >( SmallObjectPool::allocate( n * sizeof( T ) ) );
   }
 
 
@@ -188,6 +202,23 @@ namespace Dune
     return false;
   }
 
+
+
+  // Implementation of SmallObjectPolyAllocator
+  // ------------------------------------------
+
+  template< class T >
+  inline T *SmallObjectPolyAllocator::allocate ( size_t n )
+  {
+    return static_cast< T * >( SmallObjectPool::allocate( n * sizeof( T ) ) );
+  }
+
+  template< class T >
+  inline void SmallObjectPolyAllocator::deallocate ( T *p )
+  {
+    SmallObjectPool::free( p );
+  }
+
 }
 
 #endif // #ifndef DUNE_SMALLOBJECT_HH
-- 
GitLab