DUNE-FEM (unstable)

objectstack.hh
1 #ifndef DUNE_FEM_OBJECTSTACK_HH
2 #define DUNE_FEM_OBJECTSTACK_HH
3 
4 #include <dune/fem/storage/referencecounter.hh>
5 #include <dune/fem/misc/threads/threadsafevalue.hh>
6 
7 namespace Dune
8 {
9 
10  namespace Fem
11  {
12 
13  template< class ObjectFactoryImp >
14  class ObjectStack;
15 
16  template< class ObjectFactoryImp >
17  class ObjectStackEntry;
18 
19 
20  template< class ObjectFactoryImp >
21  struct ObjectStackEntryTraits
22  {
23  typedef ObjectStackEntry< ObjectFactoryImp > ReferenceCounterType;
24 
25  typedef typename ObjectFactoryImp :: ObjectType ObjectType;
26  };
27 
28 
29  template< class ObjectFactoryImp >
30  class ObjectStackEntry
31  : public ReferenceCounterDefault< ObjectStackEntryTraits< ObjectFactoryImp > >
32  {
33  public:
34  typedef ObjectFactoryImp ObjectFactoryType;
35 
36  typedef ObjectStackEntryTraits< ObjectFactoryType > Traits;
37 
38  private:
39  typedef ObjectStackEntry< ObjectFactoryType > ThisType;
40  typedef ReferenceCounterDefault< Traits > BaseType;
41 
42  friend class ObjectStack< ObjectFactoryType >;
43 
44  protected:
45  typedef ObjectStack< ObjectFactoryType > ObjectStackType;
46 
47  public:
48  typedef typename ObjectFactoryType :: ObjectType ObjectType;
49 
50  protected:
51  // reference to the stack
52  ObjectStackType &stack_;
53 
54  // pointer to the actual object
55  ObjectType *const object_;
56 
57  // next object on the stack
58  ThisType *next_;
59 
60  inline explicit ObjectStackEntry ( ObjectStackType &stack )
61  : BaseType( 0 ),
62  stack_( stack ),
63  object_( stack_.factory().newObject() )
64  {
65  }
66 
67  public:
68  ObjectStackEntry ( const ThisType& ) = delete;
69 
70  inline ~ObjectStackEntry ()
71  {
72  delete object_;
73  }
74 
75  ThisType& operator= ( const ThisType& ) = delete;
76 
77  inline operator const ObjectType& () const
78  {
79  return *object_;
80  }
81 
82  inline operator ObjectType& ()
83  {
84  return *object_;
85  }
86 
87  inline void deleteObject ()
88  {
89  stack_.push( this );
90  }
91 
92  inline const ObjectType &getObject () const
93  {
94  return *object_;
95  }
96 
97  inline ObjectType &getObject ()
98  {
99  return *object_;
100  }
101  };
102 
103 
104 
108  template< class ObjectFactoryImp >
110  {
111  typedef ObjectFactoryImp ObjectFactoryType;
112 
113  private:
115 
116  friend class ObjectStackEntry< ObjectFactoryType >;
117 
118  public:
120  typedef typename ObjectFactoryType :: ObjectType ObjectType;
121 
123  typedef ObjectStackEntry< ObjectFactoryType > StackEntryType;
124 
127 
128  protected:
129  const ObjectFactoryType &factory_;
130 
131  // store stack such that entries are thread safe
132  typedef StackEntryType* StackEntryPtrType;
134 
135  // thread safe stack entries (in multi thread mode a vector)
136  ThreadSafeValuesType stackEntries_;
137  public:
139  ObjectStack ( const ObjectFactoryType &factory )
140  : factory_( factory ),
141  stackEntries_( StackEntryPtrType(0) )
142  {
143  }
144 
145  ObjectStack ( const ThisType& ) = delete;
146 
149  {
150  // make sure this is only called in single thread mode
151  // because the master thread is taking care of all object delete
152  assert( MPIManager::singleThreadMode() );
153  const size_t threadSize = stackEntries_.size();
154  for( size_t i=0; i<threadSize; ++i )
155  {
156  StackEntryPtrType& stackEntry = stackEntries_[ i ];
157  while ( stackEntry != 0 )
158  {
159  StackEntryType *obj = stackEntry;
160  stackEntry = obj->next_;
161  delete obj;
162  }
163  }
164  }
165 
166  ThisType& operator= ( const ThisType& ) = delete;
167 
170  {
171  return PointerType( pop() );
172  }
173 
174  protected:
175  inline const ObjectFactoryType &factory() const
176  {
177  return factory_;
178  }
179 
180  // push storage object to the stack
181  inline void push ( StackEntryType *obj )
182  {
183  // get thread private value
184  push( obj, *stackEntries_ );
185  }
186 
187  // pop a storage object from the stack
188  inline StackEntryType *pop ()
189  {
190  // get thread private value
191  return pop( *stackEntries_ );
192  }
193 
194  private:
195  // push storage object to the stack
196  inline void push ( StackEntryType *obj, StackEntryPtrType& stackEntry )
197  {
198  obj->next_ = stackEntry;
199  stackEntry = obj;
200  }
201 
202  // pop a storage object from the stack
203  inline StackEntryType *pop ( StackEntryPtrType& stackEntry )
204  {
205  StackEntryType *ptr = stackEntry;
206  if( ptr != 0 )
207  stackEntry = stackEntry->next_;
208  else
209  ptr = new StackEntryType( *this );
210  return ptr;
211  }
212  };
213 
214  } // namespace Fem
215 
216 } // namespace Dune
217 
218 #endif // #ifndef DUNE_FEM_OBJECTSTACK_HH
models a pointer to a reference countable object
Definition: referencecounter.hh:224
Definition: objectstack.hh:110
~ObjectStack()
delete all objects on stack
Definition: objectstack.hh:148
ObjectStack(const ObjectFactoryType &factory)
constructor
Definition: objectstack.hh:139
ObjectFactoryType ::ObjectType ObjectType
type of the stored objects
Definition: objectstack.hh:120
ObjectStackEntry< ObjectFactoryType > StackEntryType
type of the storage objects
Definition: objectstack.hh:123
PointerType getObject()
get an object pointer to a storage object
Definition: objectstack.hh:169
ObjectPointer< StackEntryType > PointerType
type of object pointers
Definition: objectstack.hh:126
size_t size() const
return number of threads
Definition: threadsafevalue.hh:48
Dune namespace.
Definition: alignedallocator.hh:13
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 15, 22:30, 2024)