summaryrefslogtreecommitdiff
path: root/indra/llcommon/llinstancetracker.h
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcommon/llinstancetracker.h')
-rw-r--r--indra/llcommon/llinstancetracker.h90
1 files changed, 64 insertions, 26 deletions
diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h
index ea50acbbc5..039d68faef 100644
--- a/indra/llcommon/llinstancetracker.h
+++ b/indra/llcommon/llinstancetracker.h
@@ -38,22 +38,53 @@
#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 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); }
@@ -69,11 +100,11 @@ private:
}
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,20 +112,27 @@ 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(); }
+ /// 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:
@@ -103,19 +141,19 @@ protected:
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