summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNat Goodspeed <nat@lindenlab.com>2012-07-16 21:05:23 -0400
committerNat Goodspeed <nat@lindenlab.com>2012-07-16 21:05:23 -0400
commit55a7bdf8d3f59b0d1973d1ec22d3c8770a077723 (patch)
tree5fe552032836e0599c8b24b5a184deca9eabda8c
parent79a171209f41189adfeb1ba8e70c8570d380cdc5 (diff)
MAINT-1175: Pass boost::unordered_map hash/equals functors for char*.
boost::unordered_map<const char*, ...> does NOT, by default, "do the right thing." Give it hash and equality functors that do.
-rw-r--r--indra/llcommon/lltypeinfolookup.h44
1 files changed, 43 insertions, 1 deletions
diff --git a/indra/llcommon/lltypeinfolookup.h b/indra/llcommon/lltypeinfolookup.h
index 5267e3d2fb..0b6862444e 100644
--- a/indra/llcommon/lltypeinfolookup.h
+++ b/indra/llcommon/lltypeinfolookup.h
@@ -13,10 +13,49 @@
#define LL_LLTYPEINFOLOOKUP_H
#include <boost/unordered_map.hpp>
+#include <boost/functional/hash.hpp>
#include <boost/optional.hpp>
+#include <functional> // std::binary_function
#include <typeinfo>
/**
+ * The following helper classes are based on the Boost.Unordered documentation:
+ * http://www.boost.org/doc/libs/1_45_0/doc/html/unordered/hash_equality.html
+ */
+
+/**
+ * Compute hash for a string passed as const char*
+ */
+struct const_char_star_hash: public std::unary_function<const char*, std::size_t>
+{
+ std::size_t operator()(const char* str) const
+ {
+ std::size_t seed = 0;
+ for ( ; *str; ++str)
+ {
+ boost::hash_combine(seed, *str);
+ }
+ return seed;
+ }
+};
+
+/**
+ * Compute equality for strings passed as const char*
+ *
+ * I (nat) suspect that this is where the default behavior breaks for the
+ * const char* values returned from std::type_info::name(). If you compare the
+ * two const char* pointer values, as a naive, unspecialized implementation
+ * will surely do, they'll compare unequal.
+ */
+struct const_char_star_equal: public std::binary_function<const char*, const char*, bool>
+{
+ bool operator()(const char* lhs, const char* rhs) const
+ {
+ return strcmp(lhs, rhs) == 0;
+ }
+};
+
+/**
* LLTypeInfoLookup is specifically designed for use cases for which you might
* consider std::map<std::type_info*, VALUE>. We have several such data
* structures in the viewer. The trouble with them is that at least on Linux,
@@ -40,7 +79,10 @@ class LLTypeInfoLookup
// std::type_info::name() string. This is one of the rare cases in which I
// dare use const char* directly, rather than std::string, because I'm
// sure that every value returned by std::type_info::name() is static.
- typedef boost::unordered_map<const char*, VALUE> impl_map_type;
+ // HOWEVER, specify our own hash + equality functors: naively comparing
+ // distinct const char* values won't work.
+ typedef boost::unordered_map<const char*, VALUE,
+ const_char_star_hash, const_char_star_equal> impl_map_type;
public:
typedef VALUE value_type;