From 8d2ed56644047c08e2646aa8c981bebd84347b4a Mon Sep 17 00:00:00 2001 From: Alexis Hunt Date: Fri, 29 Jul 2011 23:31:56 +0000 Subject: [PATCH] Add a new hash class in __gnu_ext for the extension containers. There are two motivations for this. First, this allows users who are specializing __gnu_ext::hash to continue doing so without changing their code. Second, SGI specifies hash overloads for char* and const char* that perform a hash of the string, not of the pointer. In order to support this, the hashing code for string is factored out. llvm-svn: 136539 --- libcxx/include/ext/__hash | 46 +++++++++++++++++++++++++++++++++++++ libcxx/include/ext/hash_map | 1 + libcxx/include/ext/hash_set | 3 ++- libcxx/include/string | 30 +++++++++++++----------- 4 files changed, 65 insertions(+), 15 deletions(-) create mode 100644 libcxx/include/ext/__hash diff --git a/libcxx/include/ext/__hash b/libcxx/include/ext/__hash new file mode 100644 index 000000000000..8e9635d07f57 --- /dev/null +++ b/libcxx/include/ext/__hash @@ -0,0 +1,46 @@ +// -*- C++ -*- +//===------------------------- hash_set ------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_EXT_HASH +#define _LIBCPP_EXT_HASH + +#pragma GCC system_header + +#include +#include + +namespace __gnu_cxx { +using namespace std; + +template struct _LIBCPP_VISIBLE hash : public std::hash + { }; + +template <> struct _LIBCPP_VISIBLE hash + : public unary_function +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(const char *__c) const _NOEXCEPT + { + return __do_string_hash(__c, __c + strlen(__c)); + } +}; + +template <> struct _LIBCPP_VISIBLE hash + : public unary_function +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(char *__c) const _NOEXCEPT + { + return __do_string_hash(__c, __c + strlen(__c)); + } +}; +} + +#endif _LIBCPP_EXT_HASH diff --git a/libcxx/include/ext/hash_map b/libcxx/include/ext/hash_map index 21ce3be8a18c..9e62e7a777d6 100644 --- a/libcxx/include/ext/hash_map +++ b/libcxx/include/ext/hash_map @@ -203,6 +203,7 @@ template #include <__hash_table> #include #include +#include #if __DEPRECATED #warning Use of the header is deprecated. Migrate to diff --git a/libcxx/include/ext/hash_set b/libcxx/include/ext/hash_set index daad847afb35..14daf7bc29e4 100644 --- a/libcxx/include/ext/hash_set +++ b/libcxx/include/ext/hash_set @@ -196,6 +196,7 @@ template #include <__config> #include <__hash_table> #include +#include #if __DEPRECATED #warning Use of the header is deprecated. Migrate to @@ -205,7 +206,7 @@ namespace __gnu_cxx { using namespace std; -template , class _Pred = equal_to<_Value>, +template , class _Pred = equal_to<_Value>, class _Alloc = allocator<_Value> > class _LIBCPP_VISIBLE hash_set { diff --git a/libcxx/include/string b/libcxx/include/string index d1b9a5ea59ac..8d48e0af7d2f 100644 --- a/libcxx/include/string +++ b/libcxx/include/string @@ -3857,6 +3857,21 @@ template const typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::npos; +template +size_t _LIBCPP_INLINE_VISIBILITY __do_string_hash(_Ptr __p, _Ptr __e) +{ + size_t __r = 0; + const size_t __sr = __CHAR_BIT__ * sizeof(size_t) - 8; + const size_t __m = size_t(0xF) << (__sr + 4); + for (; __p != __e; ++__p) + { + __r = (__r << 4) + *__p; + size_t __g = __r & __m; + __r ^= __g | (__g >> __sr); + } + return __r; +} + template struct _LIBCPP_VISIBLE hash > : public unary_function, size_t> @@ -3870,20 +3885,7 @@ size_t hash >::operator()( const basic_string<_CharT, _Traits, _Allocator>& __val) const _NOEXCEPT { - typedef basic_string<_CharT, _Traits, _Allocator> S; - typedef typename S::const_pointer const_pointer; - size_t __r = 0; - const size_t __sr = __CHAR_BIT__ * sizeof(size_t) - 8; - const size_t __m = size_t(0xF) << (__sr + 4); - const_pointer __p = __val.data(); - const_pointer __e = __p + __val.size(); - for (; __p != __e; ++__p) - { - __r = (__r << 4) + *__p; - size_t __g = __r & __m; - __r ^= __g | (__g >> __sr); - } - return __r; + return __do_string_hash(__val.data(), __val.data() + __val.size()); } template