--- /dev/null
+
+/*] Copyright (c) 2009-2010, Charles McGarvey [**************************
+**] All rights reserved.
+*
+* vi:ts=4 sw=4 tw=75
+*
+* Distributable under the terms and conditions of the 2-clause BSD license;
+* see the file COPYING for a complete text of the license.
+*
+**************************************************************************/
+
+#ifndef _MOOF_MANAGER_HH_
+#define _MOOF_MANAGER_HH_
+
+/**
+ * \file manager.hh
+ * A manager is a collection of named objects of the same type. Libraries
+ * use reference counting to automagically delete objects which no longer
+ * have any interested code.
+ */
+
+#include <string>
+
+#include <boost/shared_ptr.hpp>
+
+#include <moof/hash.hh>
+
+
+namespace moof {
+
+
+template <class T>
+class manager
+{
+public:
+
+ manager() :
+ retain_count_(1) {}
+
+ const std::string& name() const
+ {
+ return name_;
+ }
+
+ static boost::shared_ptr<T> instance(const std::string& name)
+ {
+ return boost::shared_ptr<T>(retain(name), &release);
+ }
+
+
+private:
+
+ typedef stlplus::hash<std::string,T*,hash_function> ptr_lookup;
+
+ static T* retain(const std::string& name)
+ {
+ typename ptr_lookup::iterator it = ptr_lookup_.find(name);
+
+ if (it != ptr_lookup_.end())
+ {
+ ++((*it).second->retain_count_);
+ return (*it).second;
+ }
+ else
+ {
+ T* new_object(new T);
+ if (new_object)
+ {
+ new_object->name_ = name;
+ new_object->init(name);
+ ptr_lookup_.insert(std::make_pair(name, new_object));
+ }
+ return new_object;
+ }
+ }
+
+ static void release(T* obj)
+ {
+ if (--(obj->retain_count_) == 0)
+ {
+ ptr_lookup_.erase(obj->name_);
+ delete obj;
+ }
+ }
+
+
+ static ptr_lookup ptr_lookup_;
+ std::string name_;
+ unsigned retain_count_;
+};
+
+template <class T>
+hash<std::string,T*,hash_function> manager<T>::ptr_lookup_;
+
+
+} // namespace moof
+
+#endif // _MOOF_MANAGER_HH_
+