From: Roland McGrath Date: Mon, 12 Oct 2009 09:59:57 +0000 (-0700) Subject: Fix container hashers. X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=2bc79b79f372cf7a5083597efb61543a874c244a;p=thirdparty%2Felfutils.git Fix container hashers. --- diff --git a/libdw/c++/subr.hh b/libdw/c++/subr.hh index d8daa80ff..42da3282c 100644 --- a/libdw/c++/subr.hh +++ b/libdw/c++/subr.hh @@ -52,6 +52,12 @@ namespace elfutils hash_combine (seed, v.second); } + inline void + string_hash_combine (size_t &hash, const std::string::value_type &c) + { + hash = hash * 33 + c; + } + template struct base_hasher : public std::unary_function { @@ -106,24 +112,29 @@ namespace elfutils } }; - template - struct container_hasher : public std::unary_function + template, + size_t initial_hash = 0> + class container_hasher + : public std::unary_function { + private: struct hasher { - size_t _m_hash; - inline hasher (size_t init = 0) : _m_hash (init) {} + size_t &_m_hash; + inline explicit hasher (size_t &hash) : _m_hash (hash) {} inline void operator () (const typename T::value_type &x) { - hash_combine (_m_hash, hash_this (x)); + return (*combiner) (_m_hash, x); } }; - + public: inline size_t operator () (const T &x) const { - hasher h; - for_each (x, h); - return h._m_hash; + size_t hash = initial_hash; + for_each (x, hasher (hash)); + return hash; } }; @@ -135,24 +146,8 @@ namespace elfutils template<> struct hash - : public container_hasher + : public container_hasher { - private: - struct hasher : public container_hasher::hasher - { - inline hasher () : container_hasher::hasher (5381) {} - inline void operator () (std::string::value_type c) - { - _m_hash = _m_hash * 33 + c; - } - }; - public: - inline size_t operator () (const std::string &x) const - { - hasher h; - for_each (x, h); - return h._m_hash; - } }; template @@ -510,16 +505,7 @@ namespace elfutils inline void set_hash () { - struct hashit - { - size_t &_m_hash; - hashit (size_t &h) : _m_hash (h) {} - inline void operator () (const elt_type &p) - { - hash_combine (_m_hash, p); - } - }; - for_each (static_cast<_base &> (*this), hashit (_m_hash)); + _m_hash = container_hasher () (*this); } public: @@ -528,14 +514,14 @@ namespace elfutils template hashed_container (iterator first, iterator last) - : _base (first, last), _m_hash (0) + : _base (first, last) { set_hash (); } template hashed_container (const other_container &other) - : _base (other.begin (), other.end ()), _m_hash (0) + : _base (other.begin (), other.end ()) { set_hash (); }