dune-fem 2.8-git
singleton.hh
Go to the documentation of this file.
1#ifndef DUNE_FEM_SINGLETON_HH
2#define DUNE_FEM_SINGLETON_HH
3
4//- System includes
5#include <cassert>
6#include <algorithm>
7#include <memory>
8#include <typeindex>
9#include <unordered_map>
10#include <vector>
11
12//- dune-fem includes
14
15namespace Dune
16{
17 namespace Fem
18 {
19 namespace detail
20 {
21 class SingletonStorage
22 {
23 protected:
24 // item to be stored in storage list
25 struct Item { virtual ~Item() {} };
26
27 typedef std::shared_ptr< Item > WeakPointerType;
28 typedef std::unique_ptr< Item > PointerType;
29 typedef std::type_index KeyType;
30
31 typedef std::pair< std::unordered_map< KeyType, std::shared_ptr< Item > >, std::vector<PointerType> > StorageType;
32
33 // delete for singletons deleting each singleton object
34 // in reverse order of creation
35 struct SingletonDeleter
36 {
37 void operator()(StorageType* storage) const
38 {
39 // delete singletons in reverse order
40 std::for_each(storage->second.rbegin(), storage->second.rend(),
41 [](PointerType& item) { item.reset(); });
42
43 storage->second.clear();
44 storage->first.clear();
45 }
46 };
47
48 public:
49 typedef std::unique_ptr<StorageType, SingletonDeleter> StoragePointer;
50
51 private:
52 static StoragePointer storage_;
53
54 protected:
55 static StorageType& getStorage()
56 {
57 if(! storage_ )
58 {
59 storage_.reset( new StorageType() );
60 }
61
62 return *storage_;
63 }
64 };
65 } // end namespace detail
66
69 template< class Object >
70 class Singleton : public detail::SingletonStorage
71 {
72 typedef detail::SingletonStorage BaseType;
73 typedef typename BaseType::StorageType StorageType;
74 typedef typename BaseType::Item Item;
75 typedef typename BaseType::PointerType PointerType;
76 typedef typename BaseType::WeakPointerType WeakPointerType;
77
78 using BaseType::getStorage;
79
80 // item to be created containing the correct object
81 struct ItemWrapper : public Item
82 {
83 Object obj_;
84 template <class... Args>
85 ItemWrapper(Args &&... args) : obj_(std::forward< Args >( args )...)
86 {}
87 };
88 typedef ItemWrapper ItemWrapperType;
89
90 // null delete for shared_ptr hash map
91 struct NullDeleter
92 {
93 void operator()(Item *p) const {}
94 };
95
96 public:
100 template <class... Args>
101 static Object& instance(Args &&... args)
102 {
103 // capture reference as static variable to avoid map search later on
104 static Object& inst = getObject(std::forward< Args >( args )...);
105 return inst;
106 }
107
108 protected:
109 // placing variables as static inside functions only works with gcc
110 static const bool placeStaticVariableInline = false ;
111
114 template <class... Args>
115 static Object& getObject(Args &&... args)
116 {
117 // this way of creating static variables only works with gcc, not with clang
118 if constexpr ( placeStaticVariableInline )
119 {
120 static Object obj( std::forward< Args >( args )...);
121 return obj;
122 }
123 else
124 {
125 // get storage reference (see base class)
126 StorageType& storage = getStorage();
127
128 // get pointer of singleton objects belonging to hash id
129 auto& ptr = storage.first[ std::type_index(typeid(Object)) ];
130 // if pointer has not been set, create object and set pointer
131 if( ! ptr )
132 {
134
135 // create object in vector for later correct deletion order
136 storage.second.emplace_back( PointerType(new ItemWrapperType(std::forward< Args >( args )...) ) );
137
138 // create pointer to object in hash map for later use
139 ptr = WeakPointerType( storage.second.back().operator->(), NullDeleter() );
140 }
141
142 // return object reference
143 assert( dynamic_cast< ItemWrapperType* > (ptr.operator->()) );
144 return static_cast< ItemWrapperType& > (*ptr).obj_;
145 }
146 }
147
148 };
149
150 } // namespace Fem
151
152} // namespace Dune
153
154#endif // #ifndef DUNE_FEM_SINGLETONLIST_HH
Definition: bindguard.hh:11
static bool singleThreadMode()
returns true if program is operating on one thread currently
Definition: threadmanager.hh:74
return singleton instance of given Object type.
Definition: singleton.hh:71
static Object & getObject(Args &&... args)
return singleton instance of given Object type.
Definition: singleton.hh:115
static Object & instance(Args &&... args)
return singleton instance of given Object type.
Definition: singleton.hh:101
static const bool placeStaticVariableInline
Definition: singleton.hh:110