diff options
Diffstat (limited to 'project2/common/instanceStore.h')
-rw-r--r-- | project2/common/instanceStore.h | 103 |
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 + |