forked from OSchip/llvm-project
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
This commit is contained in:
parent
fe473ae277
commit
8d2ed56644
|
@ -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 <string>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
namespace __gnu_cxx {
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
template <typename T> struct _LIBCPP_VISIBLE hash : public std::hash<T>
|
||||||
|
{ };
|
||||||
|
|
||||||
|
template <> struct _LIBCPP_VISIBLE hash<const char*>
|
||||||
|
: public unary_function<const char*, size_t>
|
||||||
|
{
|
||||||
|
_LIBCPP_INLINE_VISIBILITY
|
||||||
|
size_t operator()(const char *__c) const _NOEXCEPT
|
||||||
|
{
|
||||||
|
return __do_string_hash(__c, __c + strlen(__c));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <> struct _LIBCPP_VISIBLE hash<char *>
|
||||||
|
: public unary_function<char*, size_t>
|
||||||
|
{
|
||||||
|
_LIBCPP_INLINE_VISIBILITY
|
||||||
|
size_t operator()(char *__c) const _NOEXCEPT
|
||||||
|
{
|
||||||
|
return __do_string_hash<const char *>(__c, __c + strlen(__c));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif _LIBCPP_EXT_HASH
|
|
@ -203,6 +203,7 @@ template <class Key, class T, class Hash, class Pred, class Alloc>
|
||||||
#include <__hash_table>
|
#include <__hash_table>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <ext/__hash>
|
||||||
|
|
||||||
#if __DEPRECATED
|
#if __DEPRECATED
|
||||||
#warning Use of the header <ext/hash_map> is deprecated. Migrate to <unordered_map>
|
#warning Use of the header <ext/hash_map> is deprecated. Migrate to <unordered_map>
|
||||||
|
|
|
@ -196,6 +196,7 @@ template <class Value, class Hash, class Pred, class Alloc>
|
||||||
#include <__config>
|
#include <__config>
|
||||||
#include <__hash_table>
|
#include <__hash_table>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <ext/__hash>
|
||||||
|
|
||||||
#if __DEPRECATED
|
#if __DEPRECATED
|
||||||
#warning Use of the header <ext/hash_set> is deprecated. Migrate to <unordered_set>
|
#warning Use of the header <ext/hash_set> is deprecated. Migrate to <unordered_set>
|
||||||
|
@ -205,7 +206,7 @@ namespace __gnu_cxx {
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
template <class _Value, class _Hash = std::hash<_Value>, class _Pred = equal_to<_Value>,
|
template <class _Value, class _Hash = hash<_Value>, class _Pred = equal_to<_Value>,
|
||||||
class _Alloc = allocator<_Value> >
|
class _Alloc = allocator<_Value> >
|
||||||
class _LIBCPP_VISIBLE hash_set
|
class _LIBCPP_VISIBLE hash_set
|
||||||
{
|
{
|
||||||
|
|
|
@ -3857,6 +3857,21 @@ template<class _CharT, class _Traits, class _Allocator>
|
||||||
const typename basic_string<_CharT, _Traits, _Allocator>::size_type
|
const typename basic_string<_CharT, _Traits, _Allocator>::size_type
|
||||||
basic_string<_CharT, _Traits, _Allocator>::npos;
|
basic_string<_CharT, _Traits, _Allocator>::npos;
|
||||||
|
|
||||||
|
template<class _Ptr>
|
||||||
|
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<class _CharT, class _Traits, class _Allocator>
|
template<class _CharT, class _Traits, class _Allocator>
|
||||||
struct _LIBCPP_VISIBLE hash<basic_string<_CharT, _Traits, _Allocator> >
|
struct _LIBCPP_VISIBLE hash<basic_string<_CharT, _Traits, _Allocator> >
|
||||||
: public unary_function<basic_string<_CharT, _Traits, _Allocator>, size_t>
|
: public unary_function<basic_string<_CharT, _Traits, _Allocator>, size_t>
|
||||||
|
@ -3870,20 +3885,7 @@ size_t
|
||||||
hash<basic_string<_CharT, _Traits, _Allocator> >::operator()(
|
hash<basic_string<_CharT, _Traits, _Allocator> >::operator()(
|
||||||
const basic_string<_CharT, _Traits, _Allocator>& __val) const _NOEXCEPT
|
const basic_string<_CharT, _Traits, _Allocator>& __val) const _NOEXCEPT
|
||||||
{
|
{
|
||||||
typedef basic_string<_CharT, _Traits, _Allocator> S;
|
return __do_string_hash(__val.data(), __val.data() + __val.size());
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class _CharT, class _Traits, class _Allocator>
|
template<class _CharT, class _Traits, class _Allocator>
|
||||||
|
|
Loading…
Reference in New Issue