From 53541b81347ef65263083a92497da966cbfe0d6b Mon Sep 17 00:00:00 2001
From: Martin Nolte <mnolte@dune-project.org>
Date: Tue, 7 Aug 2012 14:20:10 +0000
Subject: [PATCH] add capacity manager for adaptive simulations (will also
 shrink the array)

[[Imported from SVN: r6889]]
---
 dune/common/container/dynamicarray.hh         | 75 +++++++++++++++++++
 .../common/container/test/dynamicarraytest.cc |  7 ++
 2 files changed, 82 insertions(+)

diff --git a/dune/common/container/dynamicarray.hh b/dune/common/container/dynamicarray.hh
index 8dce874e9..d59f3db8d 100644
--- a/dune/common/container/dynamicarray.hh
+++ b/dune/common/container/dynamicarray.hh
@@ -4,6 +4,7 @@
 #define DUNE_DYNAMICARRAY_HH
 
 #include <cassert>
+#include <cmath>
 #include <memory>
 
 #include <dune/common/exceptions.hh>
@@ -105,6 +106,80 @@ namespace Dune
 
 
 
+  // AdaptiveCapacityManager
+  // -----------------------
+
+  template< class sz_t = std::size_t >
+  class AdaptiveCapacityManager
+  {
+    typedef AdaptiveCapacityManager< sz_t > This;
+
+  public:
+    typedef sz_t size_type;
+
+    template< class _sz_t >
+    struct rebind { typedef AdaptiveCapacityManager< _sz_t > other; };
+
+    AdaptiveCapacityManager ( const double factor = 1.125 )
+      : capacity_( 0 ), factor_( factor )
+    {
+      assert( factor_ >= 1.0 );
+    }
+
+    template< class _sz_t >
+    AdaptiveCapacityManager ( const AdaptiveCapacityManager< _sz_t > &other )
+      : capacity_( 0 ), factor_( other.factor_ )
+    {}
+
+    AdaptiveCapacityManager ( const This &other )
+      : capacity_( 0 ), factor_( other.factor_ )
+    {}
+
+    template< class _sz_t >
+    const This &operator= ( const AdaptiveCapacityManager< _sz_t > &other )
+    {
+      capacity_ = 0;
+      factor_ = other.factor_;
+      return *this;
+    }
+
+    const This &operator= ( const This &other )
+    {
+      capacity_ = 0;
+      factor_ = other.factor_;
+      return *this;
+    }
+
+    size_type capacity ( size_type current_size ) const { return capacity_; }
+
+    std::pair< size_type, size_type >
+    reserve ( size_type current_size, size_type desired_capacity )
+    {
+      const size_type current_capacity = capacity_;
+      if( capacity_ < desired_capacity )
+        capacity_  = (size_type) std::ceil( factor_ * desired_capacity );
+      return std::make_pair( current_capacity, capacity_ );
+    }
+
+    std::pair< size_type, size_type >
+    resize ( size_type current_size, size_type desired_size )
+    {
+      const size_type overEstimate = (size_type) std::ceil( factor_ * desired_size );
+      if( (desired_size <= capacity_) && (overEstimate >= capacity_) )
+        return std::make_pair( capacity_, capacity_ );
+
+      const size_type current_capacity = capacity_;
+      capacity_ = overEstimate;
+      return std::make_pair( current_capacity, capacity_ );
+    }
+
+  private:
+    size_type capacity_;
+    double factor_;
+  };
+
+
+
   // DynamicArray
   // ------------
 
diff --git a/dune/common/container/test/dynamicarraytest.cc b/dune/common/container/test/dynamicarraytest.cc
index d1ff86fcf..ffd1229fd 100644
--- a/dune/common/container/test/dynamicarraytest.cc
+++ b/dune/common/container/test/dynamicarraytest.cc
@@ -15,6 +15,9 @@ int main ( int argc, char **argv )
   std::cout << "sizeof( Dune::DynamicArray< int, Dune::StaticCapacityManager<> > ) = "
             << sizeof( Dune::DynamicArray< int, Dune::StaticCapacityManager<> > ) << std::endl;
 
+  std::cout << "sizeof( Dune::DynamicArray< int, Dune::AdaptiveCapacityManager<> > ) = "
+            << sizeof( Dune::DynamicArray< int, Dune::AdaptiveCapacityManager<> > ) << std::endl;
+
   Dune::DynamicArray< int > a( 4 );
   for( int i = 0; i < 4; ++i )
     a[ i ] = i+20;
@@ -23,5 +26,9 @@ int main ( int argc, char **argv )
   for( int i = 0; i < 4; ++i )
     b[ i ] = a[ i ] + 20;
 
+  Dune::DynamicArray< int, Dune::AdaptiveCapacityManager<> > c( 4 );
+  for( int i = 0; i < 4; ++i )
+    c[ i ] = b[ i ] + 20;
+
   return 0;
 }
-- 
GitLab