dune-fem 2.8-git
singletonlist.hh
Go to the documentation of this file.
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
16
17namespace Dune
18{
19
20 namespace Fem
21 {
22
23 template< class Key, class Object >
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 // make sure this method is only called in single thread mode
98 assert( Fem :: ThreadManager :: singleThreadMode() );
99
100 ValueType objValue = getObjFromList( key );
101
102 // if object exists, increase reference count and return it
103 if( objValue.first )
104 {
105 ++( *(objValue.second) );
106 return *(objValue.first);
107 }
108
109 // object does not exist. Create it with reference count of 1
110 ObjectType *object = FactoryType::createObject( key, std::forward< Args >( args )... );
111 assert( object );
112 ValueType value( object, new unsigned int( 1 ) );
113 ListObjType tmp( key, value );
114 singletonList().push_back( tmp );
115 return *object;
116 }
117
120 inline static void removeObject ( const ObjectType &object )
121 {
122 // make sure this method is only called in single thread mode
123 assert( Fem :: ThreadManager :: singleThreadMode() );
124
125 ListIteratorType end = singletonList().end();
126 for( ListIteratorType it = singletonList().begin(); it != end; ++it )
127 {
128 if( (*it).second.first == &object )
129 {
130 eraseItem( it );
131 return;
132 }
133 }
134
135 std :: cerr << "Object could not be deleted, "
136 << "because it is not in the list anymore!" << std :: endl;
137 }
138
139 // return pair < Object * , refCounter *>
140 inline static ValueType getObjFromList( const KeyType &key )
141 {
142 ListIteratorType endit = singletonList().end();
143 for(ListIteratorType it = singletonList().begin(); it!=endit; ++it)
144 {
145 if( (*it).first == key )
146 {
147 return (*it).second;
148 }
149 }
150 return ValueType( (ObjectType *)0, (unsigned int *)0 );
151 }
152
153 protected:
154 static void eraseItem( ListIteratorType &it )
155 {
156 ValueType value = (*it).second;
157 unsigned int &refCount = *(value.second);
158
159 assert( refCount > 0 );
160 if( (--refCount) == 0 )
161 deleteItem( it );
162 }
163
164 private:
165 static void deleteItem(ListIteratorType & it)
166 {
167 ValueType val = (*it).second;
168 // remove from list
169 singletonList().erase( it );
170 // delete objects
171 FactoryType :: deleteObject( val.first );
172 delete val.second;
173 }
174 }; // end SingletonList
175
176
177 template< class Key, class Object, class Factory >
178 class SingletonList< Key, Object, Factory > :: SingletonListStorage
179 {
181
182 protected:
184
185 public:
187 : singletonList_()
188 {}
189
191 {
192 while( !singletonList().empty() )
193 deleteItem( singletonList().begin() );
194 }
195
196 ListType &singletonList ()
197 {
198 return singletonList_;
199 }
200
201 void deleteItem ( const ListIteratorType &it )
202 {
203 ValueType val = (*it).second;
204 // remove from list
205 singletonList().erase( it );
206 // delete objects
207 FactoryType :: deleteObject( val.first );
208 delete val.second;
209 }
210 };
211
212 } // namespace Fem
213
214} // namespace Dune
215
216#endif // #ifndef DUNE_FEM_SINGLETONLIST_HH
Definition: bindguard.hh:11
static Object & instance(Args &&... args)
return singleton instance of given Object type.
Definition: singleton.hh:101
Definition: singletonlist.hh:25
static void deleteObject(Object *object)
Definition: singletonlist.hh:31
static Object * createObject(const Key &key)
Definition: singletonlist.hh:26
Singleton list for key/object pairs.
Definition: singletonlist.hh:53
Key KeyType
Definition: singletonlist.hh:57
static void removeObject(const ObjectType &object)
Definition: singletonlist.hh:120
static ListType & singletonList()
Definition: singletonlist.hh:81
static ValueType getObjFromList(const KeyType &key)
Definition: singletonlist.hh:140
Object ObjectType
Definition: singletonlist.hh:58
static void eraseItem(ListIteratorType &it)
Definition: singletonlist.hh:154
std ::pair< KeyType, ValueType > ListObjType
Definition: singletonlist.hh:62
std ::pair< ObjectType *, unsigned int * > ValueType
Definition: singletonlist.hh:61
Factory FactoryType
Definition: singletonlist.hh:59
SingletonList(const ThisType &)=delete
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
Definition: singletonlist.hh:65
void operator()(ObjectType *p) const
Definition: singletonlist.hh:66
Definition: singletonlist.hh:179
SingletonListStorage()
Definition: singletonlist.hh:186
ListType singletonList_
Definition: singletonlist.hh:183
void deleteItem(const ListIteratorType &it)
Definition: singletonlist.hh:201
~SingletonListStorage()
Definition: singletonlist.hh:190
ListType & singletonList()
Definition: singletonlist.hh:196