Skip to content
Snippets Groups Projects
Commit c0318d1b authored by Nat Goodspeed's avatar Nat Goodspeed
Browse files

Make LLInstanceTracker<T, T*>::getInstance(T*) validate passed T*.

For the T* specialization (no string, or whatever, key), the original
getInstance() method simply returned the passed-in T* value. It was defined,
as the comments noted, for completeness of the analogy with the keyed
LLInstanceTracker specialization.
It turns out, though, that getInstance(T*) can still be useful to ask whether
the T* you have in hand still references a valid T instance. Support that
usage.
parent b022ebf1
No related branches found
No related tags found
No related merge requests found
...@@ -167,8 +167,9 @@ class LLInstanceTracker : public LLInstanceTrackerBase ...@@ -167,8 +167,9 @@ class LLInstanceTracker : public LLInstanceTrackerBase
static T* getInstance(const KEY& k) static T* getInstance(const KEY& k)
{ {
typename InstanceMap::const_iterator found = getMap_().find(k); const InstanceMap& map(getMap_());
return (found == getMap_().end()) ? NULL : found->second; typename InstanceMap::const_iterator found = map.find(k);
return (found == map.end()) ? NULL : found->second;
} }
static instance_iter beginInstances() static instance_iter beginInstances()
...@@ -239,8 +240,20 @@ class LLInstanceTracker<T, T*> : public LLInstanceTrackerBase ...@@ -239,8 +240,20 @@ class LLInstanceTracker<T, T*> : public LLInstanceTrackerBase
public: public:
/// for completeness of analogy with the generic implementation /**
static T* getInstance(T* k) { return k; } * Does a particular instance still exist? Of course, if you already have
* a T* in hand, you need not call getInstance() to @em locate the
* instance -- unlike the case where getInstance() accepts some kind of
* key. Nonetheless this method is still useful to @em validate a
* particular T*, since each instance's destructor removes itself from the
* underlying set.
*/
static T* getInstance(T* k)
{
const InstanceSet& set(getSet_());
typename InstanceSet::const_iterator found = set.find(k);
return (found == set.end())? NULL : *found;
}
static S32 instanceCount() { return getSet_().size(); } static S32 instanceCount() { return getSet_().size(); }
class instance_iter : public boost::iterator_facade<instance_iter, T, boost::forward_traversal_tag> class instance_iter : public boost::iterator_facade<instance_iter, T, boost::forward_traversal_tag>
......
...@@ -95,6 +95,7 @@ namespace tut ...@@ -95,6 +95,7 @@ namespace tut
void object::test<2>() void object::test<2>()
{ {
ensure_equals(Unkeyed::instanceCount(), 0); ensure_equals(Unkeyed::instanceCount(), 0);
Unkeyed* dangling = NULL;
{ {
Unkeyed one; Unkeyed one;
ensure_equals(Unkeyed::instanceCount(), 1); ensure_equals(Unkeyed::instanceCount(), 1);
...@@ -107,7 +108,11 @@ namespace tut ...@@ -107,7 +108,11 @@ namespace tut
ensure_equals(found, two.get()); ensure_equals(found, two.get());
} }
ensure_equals(Unkeyed::instanceCount(), 1); ensure_equals(Unkeyed::instanceCount(), 1);
} // store an unwise pointer to a temp Unkeyed instance
dangling = &one;
} // make that instance vanish
// check the now-invalid pointer to the destroyed instance
ensure("getInstance(T*) failed to track destruction", ! Unkeyed::getInstance(dangling));
ensure_equals(Unkeyed::instanceCount(), 0); ensure_equals(Unkeyed::instanceCount(), 0);
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment