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 
17 namespace 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:
183  ListType singletonList_;
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