DUNE-FEM (unstable)

singletonlist.hh
1#ifndef DUNE_FEM_SINGLETONLIST_HH
2#define DUNE_FEM_SINGLETONLIST_HH
3
4//- System includes
5#include <cassert>
6#include <vector>
7#include <string>
8#include <list>
9#include <iostream>
10#include <type_traits>
11#include <utility>
12
13//- dune-fem includes
14#include <dune/fem/misc/mpimanager.hh>
15#include <dune/fem/storage/singleton.hh>
16
17namespace Dune
18{
19
20 namespace Fem
21 {
22
23 template< class Key, class Object >
24 struct DefaultSingletonFactory
25 {
26 static Object *createObject ( const Key &key )
27 {
28 return new Object( key );
29 }
30
31 static void deleteObject ( Object *object )
32 {
33 delete object;
34 }
35 };
36
37
50 template< class Key, class Object,
51 class Factory = DefaultSingletonFactory< Key, Object > >
53 {
55
56 public:
57 typedef Key KeyType;
58 typedef Object ObjectType;
59 typedef Factory FactoryType;
60
61 typedef std :: pair< ObjectType * , unsigned int * > ValueType;
62 typedef std :: pair< KeyType, ValueType > ListObjType;
63
64 struct Deleter
65 {
66 void operator() ( ObjectType *p ) const { ThisType::removeObject( *p ); }
67 };
68
69 private:
70 typedef std :: list< ListObjType > ListType;
71 typedef typename ListType :: iterator ListIteratorType;
72
73 class SingletonListStorage;
74
75 public:
76 SingletonList () = delete;
77 SingletonList ( const ThisType& ) = delete;
78
81 static ListType &singletonList ()
82 {
83 //static SingletonListStorage s;
84 SingletonListStorage& s = Singleton< SingletonListStorage >::instance();
85
87 return s.singletonList();
88 }
89
93 template< class... Args >
94 static auto getObject( const KeyType &key, Args &&... args )
95 -> std::enable_if_t< std::is_same< decltype( FactoryType::createObject( key, std::forward< Args >( args )... ) ), ObjectType * >::value, ObjectType & >
96 {
97 ValueType objValue = getObjFromList( key );
98
99 // if object exists, increase reference count and return it
100 if( objValue.first )
101 {
102 ++( *(objValue.second) );
103 return *(objValue.first);
104 }
105
106 // make sure this part is only called in single thread mode
107 if( ! Fem :: MPIManager :: singleThreadMode() )
108 {
109 DUNE_THROW(SingleThreadModeError, "SingletonList::getObject: only call in single thread mode!");
110 }
111
112 // object does not exist. Create it with reference count of 1
113 ObjectType *object = FactoryType::createObject( key, std::forward< Args >( args )... );
114 assert( object );
115 ValueType value( object, new unsigned int( 1 ) );
116 ListObjType tmp( key, value );
117 singletonList().push_back( tmp );
118 return *object;
119 }
120
123 inline static void removeObject ( const ObjectType &object )
124 {
125 // make sure this method is only called in single thread mode
126 if( ! Fem :: MPIManager :: singleThreadMode() )
127 {
128 DUNE_THROW(SingleThreadModeError, "SingletonList::removeObject: only call in single thread mode!");
129 }
130
131 ListIteratorType end = singletonList().end();
132 for( ListIteratorType it = singletonList().begin(); it != end; ++it )
133 {
134 if( (*it).second.first == &object )
135 {
136 eraseItem( it );
137 return;
138 }
139 }
140
141 std :: cerr << "Object could not be deleted, "
142 << "because it is not in the list anymore!" << std :: endl;
143 }
144
145 // return pair < Object * , refCounter *>
146 inline static ValueType getObjFromList( const KeyType &key )
147 {
148 ListIteratorType endit = singletonList().end();
149 for(ListIteratorType it = singletonList().begin(); it!=endit; ++it)
150 {
151 if( (*it).first == key )
152 {
153 return (*it).second;
154 }
155 }
156 return ValueType( (ObjectType *)0, (unsigned int *)0 );
157 }
158
159 protected:
160 static void eraseItem( ListIteratorType &it )
161 {
162 ValueType value = (*it).second;
163 unsigned int &refCount = *(value.second);
164
165 assert( refCount > 0 );
166 if( (--refCount) == 0 )
167 deleteItem( it );
168 }
169
170 private:
171 static void deleteItem(ListIteratorType & it)
172 {
173 ValueType val = (*it).second;
174 // remove from list
175 singletonList().erase( it );
176 // delete objects
177 FactoryType :: deleteObject( val.first );
178 delete val.second;
179 }
180 }; // end SingletonList
181
182
183 template< class Key, class Object, class Factory >
184 class SingletonList< Key, Object, Factory > :: SingletonListStorage
185 {
186 typedef SingletonListStorage ThisType;
187
188 protected:
189 ListType singletonList_;
190
191 public:
192 inline SingletonListStorage ()
193 : singletonList_()
194 {}
195
196 inline ~SingletonListStorage ()
197 {
198 while( !singletonList().empty() )
199 deleteItem( singletonList().begin() );
200 }
201
202 ListType &singletonList ()
203 {
204 return singletonList_;
205 }
206
207 void deleteItem ( const ListIteratorType &it )
208 {
209 ValueType val = (*it).second;
210 // remove from list
211 singletonList().erase( it );
212 // delete objects
213 FactoryType :: deleteObject( val.first );
214 delete val.second;
215 }
216 };
217
218 } // namespace Fem
219
220} // namespace Dune
221
222#endif // #ifndef DUNE_FEM_SINGLETONLIST_HH
Exception thrown when a code segment that is supposed to be only accessed in single thread mode is ac...
Definition: mpimanager.hh:43
Singleton list for key/object pairs.
Definition: singletonlist.hh:53
static void removeObject(const ObjectType &object)
Definition: singletonlist.hh:123
static ListType & singletonList()
Definition: singletonlist.hh:81
static auto getObject(const KeyType &key, Args &&... args) -> std::enable_if_t< std::is_same< decltype(FactoryType::createObject(key, std::forward< Args >(args)...)), ObjectType * >::value, ObjectType & >
Definition: singletonlist.hh:94
static DUNE_EXPORT Object & instance(Args &&... args)
return singleton instance of given Object type.
Definition: singleton.hh:123
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
Dune namespace.
Definition: alignedallocator.hh:13
constexpr std::bool_constant<(sizeof...(II)==0)> empty(std::integer_sequence< T, II... >)
Checks whether the sequence is empty.
Definition: integersequence.hh:80
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Nov 21, 23:30, 2024)