summaryrefslogtreecommitdiff
path: root/project2/common/instanceStore.h
diff options
context:
space:
mode:
authorrandomdan <randomdan@localhost>2013-09-15 12:43:27 +0000
committerrandomdan <randomdan@localhost>2013-09-15 12:43:27 +0000
commitd022256a4136234d742e3178d31948b5f88bc0f6 (patch)
tree34182eca80cc6a92a7a4a4c9d19836f0da2e0981 /project2/common/instanceStore.h
parentAdd a module for preloading libraries, which supersedes that in daemon (diff)
downloadproject2-d022256a4136234d742e3178d31948b5f88bc0f6.tar.bz2
project2-d022256a4136234d742e3178d31948b5f88bc0f6.tar.xz
project2-d022256a4136234d742e3178d31948b5f88bc0f6.zip
Allow instance registration to occur with different key types
Diffstat (limited to 'project2/common/instanceStore.h')
-rw-r--r--project2/common/instanceStore.h103
1 files changed, 103 insertions, 0 deletions
diff --git a/project2/common/instanceStore.h b/project2/common/instanceStore.h
new file mode 100644
index 0000000..c61ccfe
--- /dev/null
+++ b/project2/common/instanceStore.h
@@ -0,0 +1,103 @@
+#ifndef INSTANCESTORE_H
+#define INSTANCESTORE_H
+
+#include <boost/foreach.hpp>
+#include <boost/function.hpp>
+#include <set>
+#include <map>
+#include <safeMapFind.h>
+
+/// A static collection of any type, specifically with automatically cleaned up storage of a function static variable
+// which makes it safe to use in constructor functions.
+template <class Type, class StoreType>
+class InstanceStore {
+ public:
+ static const StoreType & GetAll()
+ {
+ return *getInstances();
+ }
+
+ static void Add(const typename StoreType::value_type & p)
+ {
+ getInstances()->insert(p);
+ }
+
+ template <typename EraseByType>
+ static void Remove(const EraseByType & p)
+ {
+ getInstances()->erase(p);
+ prune();
+ }
+
+ static void OnEach(const boost::function<void(typename StoreType::value_type &)> & func)
+ {
+ BOOST_FOREACH(const auto & l, GetAll()) {
+ try {
+ func(l.get());
+ }
+ catch (...) {
+ }
+ }
+ prune();
+ }
+
+ static void OnAll(const boost::function<void(Type *)> & func)
+ {
+ BOOST_FOREACH(const auto & l, GetAll()) {
+ try {
+ func(l.get());
+ }
+ catch (...) {
+ }
+ }
+ prune();
+ }
+
+ private:
+ static void prune()
+ {
+ auto & ps = getInstances();
+ if (ps->empty()) {
+ delete ps;
+ ps = NULL;
+ }
+ }
+
+ static StoreType * & getInstances()
+ {
+ static StoreType * instances = NULL;
+ if (!instances) {
+ instances = new StoreType();
+ }
+ return instances;
+ }
+};
+
+/// Keyed collection of instances
+template <class Type, class KeyType>
+class InstanceMap : public InstanceStore<Type, std::map<KeyType, boost::shared_ptr<Type>>> {
+ public:
+ typedef std::map<KeyType, boost::shared_ptr<Type>> Store;
+ typedef typename Store::value_type Value;
+
+ static void Add(const KeyType & k, Type * p) {
+ InstanceStore<Type, Store>::Add(Value(k, boost::shared_ptr<Type>(p)));
+ }
+
+ static void Add(const KeyType & k, const boost::shared_ptr<Type> & p) {
+ InstanceStore<Type, Store>::Add(Value(k, p));
+ }
+
+ template <class E> static boost::shared_ptr<Type> Get(const KeyType & n)
+ {
+ return safeMapLookup<E>(InstanceStore<Type, Store>::GetAll(), n);
+ }
+};
+
+/// Anonymous collection of instances
+template <class Type>
+class InstanceSet : public InstanceStore<Type, std::set<boost::shared_ptr<Type>>> {
+};
+
+#endif
+