diff options
author | Nat Goodspeed <nat@lindenlab.com> | 2012-07-16 21:05:23 -0400 |
---|---|---|
committer | Nat Goodspeed <nat@lindenlab.com> | 2012-07-16 21:05:23 -0400 |
commit | 55a7bdf8d3f59b0d1973d1ec22d3c8770a077723 (patch) | |
tree | 5fe552032836e0599c8b24b5a184deca9eabda8c | |
parent | 79a171209f41189adfeb1ba8e70c8570d380cdc5 (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.h | 44 |
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; |