[cfe-commits] [libcxx] r136539 - in /libcxx/trunk/include: ext/__hash ext/hash_map ext/hash_set string

Howard Hinnant hhinnant at apple.com
Sat Jul 30 08:38:57 PDT 2011


Approved.  But this is a significant enough change that I would like to see discussion first.

libc++ was never meant to be a drop-in replacement for libstdc++ or sgi.  This change creates a situation where more things will hash to the same value but not compare equal.  This isn't necessarily an improvement, even though it may make the behavior compatible with the past.

Howard

On Jul 29, 2011, at 7:31 PM, Sean Hunt wrote:

> Author: coppro
> Date: Fri Jul 29 18:31:56 2011
> New Revision: 136539
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=136539&view=rev
> Log:
> 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.
> 
> Added:
>    libcxx/trunk/include/ext/__hash
> Modified:
>    libcxx/trunk/include/ext/hash_map
>    libcxx/trunk/include/ext/hash_set
>    libcxx/trunk/include/string
> 
> Added: libcxx/trunk/include/ext/__hash
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/ext/__hash?rev=136539&view=auto
> ==============================================================================
> --- libcxx/trunk/include/ext/__hash (added)
> +++ libcxx/trunk/include/ext/__hash Fri Jul 29 18:31:56 2011
> @@ -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
> 
> Modified: libcxx/trunk/include/ext/hash_map
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/ext/hash_map?rev=136539&r1=136538&r2=136539&view=diff
> ==============================================================================
> --- libcxx/trunk/include/ext/hash_map (original)
> +++ libcxx/trunk/include/ext/hash_map Fri Jul 29 18:31:56 2011
> @@ -203,6 +203,7 @@
> #include <__hash_table>
> #include <functional>
> #include <stdexcept>
> +#include <ext/__hash>
> 
> #if __DEPRECATED
> #warning Use of the header <ext/hash_map> is deprecated.  Migrate to <unordered_map>
> 
> Modified: libcxx/trunk/include/ext/hash_set
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/ext/hash_set?rev=136539&r1=136538&r2=136539&view=diff
> ==============================================================================
> --- libcxx/trunk/include/ext/hash_set (original)
> +++ libcxx/trunk/include/ext/hash_set Fri Jul 29 18:31:56 2011
> @@ -196,6 +196,7 @@
> #include <__config>
> #include <__hash_table>
> #include <functional>
> +#include <ext/__hash>
> 
> #if __DEPRECATED
> #warning Use of the header <ext/hash_set> is deprecated.  Migrate to <unordered_set>
> @@ -205,7 +206,7 @@
> 
> 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 _LIBCPP_VISIBLE hash_set
> {
> 
> Modified: libcxx/trunk/include/string
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/string?rev=136539&r1=136538&r2=136539&view=diff
> ==============================================================================
> --- libcxx/trunk/include/string (original)
> +++ libcxx/trunk/include/string Fri Jul 29 18:31:56 2011
> @@ -3857,6 +3857,21 @@
>     const typename basic_string<_CharT, _Traits, _Allocator>::size_type
>                    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>
> struct _LIBCPP_VISIBLE hash<basic_string<_CharT, _Traits, _Allocator> >
>     : public unary_function<basic_string<_CharT, _Traits, _Allocator>, size_t>
> @@ -3870,20 +3885,7 @@
> hash<basic_string<_CharT, _Traits, _Allocator> >::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<class _CharT, class _Traits, class _Allocator>
> 
> 
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits




More information about the cfe-commits mailing list