diff options
-rw-r--r-- | indra/llcommon/CMakeLists.txt | 1 | ||||
-rw-r--r-- | indra/llcommon/llinstancetracker.cpp | 17 | ||||
-rw-r--r-- | indra/llcommon/llinstancetracker.h | 30 |
3 files changed, 33 insertions, 15 deletions
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index dc9f93df3b..4f7e2f4c0d 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -62,6 +62,7 @@ set(llcommon_SOURCE_FILES llformat.cpp llframetimer.cpp llheartbeat.cpp + llinstancetracker.cpp llliveappconfig.cpp lllivefile.cpp lllog.cpp diff --git a/indra/llcommon/llinstancetracker.cpp b/indra/llcommon/llinstancetracker.cpp index 89bc6cca39..f576204511 100644 --- a/indra/llcommon/llinstancetracker.cpp +++ b/indra/llcommon/llinstancetracker.cpp @@ -32,6 +32,17 @@ // external library headers // other Linden headers -// llinstancetracker.h is presently header-only. This file exists only because our CMake -// test macro ADD_BUILD_TEST requires it. -int dummy = 0; +//static +void * & LLInstanceTrackerBase::getInstances(std::type_info const & info) +{ + static std::map<std::string, void *> instances; + + std::string k = info.name(); + if(instances.find(k) == instances.end()) + { + instances[k] = NULL; + } + + return instances[k]; +} + diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h index 4945461d62..b971b2f914 100644 --- a/indra/llcommon/llinstancetracker.h +++ b/indra/llcommon/llinstancetracker.h @@ -37,14 +37,21 @@ #include <boost/iterator/transform_iterator.hpp> #include <boost/iterator/indirect_iterator.hpp> +class LL_COMMON_API LLInstanceTrackerBase : public boost::noncopyable +{ + protected: + static void * & getInstances(std::type_info const & info); +}; + /// 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 +class LLInstanceTracker : public LLInstanceTrackerBase { typedef typename std::map<KEY, T*> InstanceMap; + typedef LLInstanceTracker<T, KEY> MyT; typedef boost::function<const KEY&(typename InstanceMap::value_type&)> KeyGetter; typedef boost::function<T*(typename InstanceMap::value_type&)> InstancePtrGetter; public: @@ -99,25 +106,26 @@ private: static InstanceMap& getMap_() { - if (! sInstances) + void * & instances = getInstances(typeid(MyT)); + if (! instances) { - sInstances = new InstanceMap; + instances = new InstanceMap; } - return *sInstances; + return * static_cast<InstanceMap*>(instances); } private: KEY mKey; - static InstanceMap* sInstances; }; /// explicit specialization for default case where KEY is T* /// use a simple std::set<T*> template<typename T> -class LLInstanceTracker<T, T*> +class LLInstanceTracker<T, T*> : public LLInstanceTrackerBase { typedef typename std::set<T*> InstanceSet; + typedef LLInstanceTracker<T, T*> MyT; public: /// Dereferencing key_iter gives you a T* (since T* is the key) typedef typename InstanceSet::iterator key_iter; @@ -172,19 +180,17 @@ protected: static InstanceSet& getSet_() { - if (! sInstances) + void * & instances = getInstances(typeid(MyT)); + if (! instances) { - sInstances = new InstanceSet; + instances = new InstanceSet; } - return *sInstances; + return * static_cast<InstanceSet *>(instances); } - static InstanceSet* sInstances; static S32 sIterationNestDepth; }; -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; template <typename T> S32 LLInstanceTracker<T, T*>::sIterationNestDepth = 0; #endif |