summaryrefslogtreecommitdiff
path: root/indra/llcommon/llinstancetracker.h
diff options
context:
space:
mode:
authorDmitry Zaporozhan <dzaporozhan@productengine.com>2009-11-12 19:29:05 +0200
committerDmitry Zaporozhan <dzaporozhan@productengine.com>2009-11-12 19:29:05 +0200
commitd149b28173c2b255bd1bf1db902368dfbdf3064a (patch)
treed433c57f07aad0959519f8b88ccd1ed8447af7bf /indra/llcommon/llinstancetracker.h
parent38115eb90b1760025ee299a167f6a9a2311f59ab (diff)
parent3b7ed8a4e9fdff83f89b49760d281ee5c13c8155 (diff)
Merge
--HG-- branch : product-engine
Diffstat (limited to 'indra/llcommon/llinstancetracker.h')
-rw-r--r--indra/llcommon/llinstancetracker.h112
1 files changed, 75 insertions, 37 deletions
diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h
index ea50acbbc5..11fe523651 100644
--- a/indra/llcommon/llinstancetracker.h
+++ b/indra/llcommon/llinstancetracker.h
@@ -38,42 +38,73 @@
#include "string_table.h"
#include <boost/utility.hpp>
-
-// This mix-in class adds support for tracking all instances of the specified class parameter T
-// The (optional) key associates a value of type KEY with a given instance of T, for quick lookup
-// If KEY is not provided, then instances are stored in a simple set
-// *NOTE: see explicit specialization below for default KEY==T* case
+#include <boost/function.hpp>
+#include <boost/bind.hpp>
+#include <boost/iterator/transform_iterator.hpp>
+#include <boost/iterator/indirect_iterator.hpp>
+
+/// This mix-in class adds support for tracking all instances of the specified class parameter T
+/// The (optional) key associates a value of type KEY with a given instance of T, for quick lookup
+/// If KEY is not provided, then instances are stored in a simple set
+/// @NOTE: see explicit specialization below for default KEY==T* case
template<typename T, typename KEY = T*>
class LLInstanceTracker : boost::noncopyable
{
+ typedef typename std::map<KEY, T*> InstanceMap;
+ typedef boost::function<const KEY&(typename InstanceMap::value_type&)> KeyGetter;
+ typedef boost::function<T*(typename InstanceMap::value_type&)> InstancePtrGetter;
public:
- typedef typename std::map<KEY, T*>::iterator instance_iter;
- typedef typename std::map<KEY, T*>::const_iterator instance_const_iter;
-
- static T* getInstance(const KEY& k) { instance_iter found = getMap().find(k); return (found == getMap().end()) ? NULL : found->second; }
+ /// Dereferencing key_iter gives you a const KEY&
+ typedef boost::transform_iterator<KeyGetter, typename InstanceMap::iterator> key_iter;
+ /// Dereferencing instance_iter gives you a T&
+ typedef boost::indirect_iterator< boost::transform_iterator<InstancePtrGetter, typename InstanceMap::iterator> > instance_iter;
+
+ static T* getInstance(const KEY& k)
+ {
+ typename InstanceMap::const_iterator found = getMap_().find(k);
+ return (found == getMap_().end()) ? NULL : found->second;
+ }
- static instance_iter beginInstances() { return getMap().begin(); }
- static instance_iter endInstances() { return getMap().end(); }
- static S32 instanceCount() { return getMap().size(); }
+ static key_iter beginKeys()
+ {
+ return boost::make_transform_iterator(getMap_().begin(),
+ boost::bind(&InstanceMap::value_type::first, _1));
+ }
+ static key_iter endKeys()
+ {
+ return boost::make_transform_iterator(getMap_().end(),
+ boost::bind(&InstanceMap::value_type::first, _1));
+ }
+ static instance_iter beginInstances()
+ {
+ return instance_iter(boost::make_transform_iterator(getMap_().begin(),
+ boost::bind(&InstanceMap::value_type::second, _1)));
+ }
+ static instance_iter endInstances()
+ {
+ return instance_iter(boost::make_transform_iterator(getMap_().end(),
+ boost::bind(&InstanceMap::value_type::second, _1)));
+ }
+ static S32 instanceCount() { return getMap_().size(); }
protected:
- LLInstanceTracker(KEY key) { add(key); }
- virtual ~LLInstanceTracker() { remove(); }
- virtual void setKey(KEY key) { remove(); add(key); }
+ LLInstanceTracker(KEY key) { add_(key); }
+ virtual ~LLInstanceTracker() { remove_(); }
+ virtual void setKey(KEY key) { remove_(); add_(key); }
virtual const KEY& getKey() const { return mKey; }
private:
- void add(KEY key)
+ void add_(KEY key)
{
mKey = key;
- getMap()[key] = static_cast<T*>(this);
+ getMap_()[key] = static_cast<T*>(this);
}
- void remove() { getMap().erase(mKey); }
+ void remove_() { getMap_().erase(mKey); }
- static std::map<KEY, T*>& getMap()
+ static InstanceMap& getMap_()
{
if (! sInstances)
{
- sInstances = new std::map<KEY, T*>;
+ sInstances = new InstanceMap;
}
return *sInstances;
}
@@ -81,41 +112,48 @@ private:
private:
KEY mKey;
- static std::map<KEY, T*>* sInstances;
+ static InstanceMap* sInstances;
};
-// explicit specialization for default case where KEY is T*
-// use a simple std::set<T*>
+/// explicit specialization for default case where KEY is T*
+/// use a simple std::set<T*>
template<typename T>
class LLInstanceTracker<T, T*>
{
+ typedef typename std::set<T*> InstanceSet;
public:
- typedef typename std::set<T*>::iterator instance_iter;
- typedef typename std::set<T*>::const_iterator instance_const_iter;
-
- static instance_iter beginInstances() { return getSet().begin(); }
- static instance_iter endInstances() { return getSet().end(); }
- static S32 instanceCount() { return getSet().size(); }
+ /// Dereferencing key_iter gives you a T* (since T* is the key)
+ typedef typename InstanceSet::iterator key_iter;
+ /// Dereferencing instance_iter gives you a T&
+ typedef boost::indirect_iterator<key_iter> instance_iter;
+
+ /// for completeness of analogy with the generic implementation
+ static T* getInstance(T* k) { return k; }
+ static key_iter beginKeys() { return getSet_().begin(); }
+ static key_iter endKeys() { return getSet_().end(); }
+ static instance_iter beginInstances() { return instance_iter(getSet_().begin()); }
+ static instance_iter endInstances() { return instance_iter(getSet_().end()); }
+ static S32 instanceCount() { return getSet_().size(); }
protected:
- LLInstanceTracker() { getSet().insert(static_cast<T*>(this)); }
- virtual ~LLInstanceTracker() { getSet().erase(static_cast<T*>(this)); }
+ LLInstanceTracker() { getSet_().insert(static_cast<T*>(this)); }
+ virtual ~LLInstanceTracker() { getSet_().erase(static_cast<T*>(this)); }
- LLInstanceTracker(const LLInstanceTracker& other) { getSet().insert(static_cast<T*>(this)); }
+ LLInstanceTracker(const LLInstanceTracker& other) { getSet_().insert(static_cast<T*>(this)); }
- static std::set<T*>& getSet() // called after getReady() but before go()
+ static InstanceSet& getSet_() // called after getReady() but before go()
{
if (! sInstances)
{
- sInstances = new std::set<T*>;
+ sInstances = new InstanceSet;
}
return *sInstances;
}
- static std::set<T*>* sInstances;
+ static InstanceSet* sInstances;
};
-template <typename T, typename KEY> std::map<KEY, T*>* LLInstanceTracker<T, KEY>::sInstances = NULL;
-template <typename T> std::set<T*>* LLInstanceTracker<T, T*>::sInstances = NULL;
+template <typename T, typename KEY> typename LLInstanceTracker<T, KEY>::InstanceMap* LLInstanceTracker<T, KEY>::sInstances = NULL;
+template <typename T> typename LLInstanceTracker<T, T*>::InstanceSet* LLInstanceTracker<T, T*>::sInstances = NULL;
#endif