Do not derive __gnu_cxx::hash<T> from std::hash<T>.

Instead, define explicit specializations for the basic types listed in
the SGI documentation. This solves two problems:

 1) Helps avoid silent ODR violations caused by the absence of a
    user-supplied __gnu_cxx::hash specialization in cases where a std::hash
    specialization exists (e.g. for std::string).

 2) __gnu_cxx::hash semantics are slightly different to those of
    std::hash (for example, the former may dereference a pointer argument)
    so it is inappropriate for __gnu_cxx::hash to receive std::hash
    specializations by default.

Differential Revision: http://llvm-reviews.chandlerc.com/D2747

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@203070 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Peter Collingbourne
2014-03-06 04:11:10 +00:00
parent 48c74700ec
commit 9d3d032c7d
4 changed files with 149 additions and 2 deletions

View File

@@ -0,0 +1,17 @@
//===----------------------------------------------------------------------===//
//
// 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.
//
//===----------------------------------------------------------------------===//
#include <assert.h>
#include <ext/hash_map>
#include <string>
int main()
{
assert(__gnu_cxx::hash<std::string>()(std::string()) == 0); // error
}

View File

@@ -0,0 +1,29 @@
//===----------------------------------------------------------------------===//
//
// 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.
//
//===----------------------------------------------------------------------===//
#include <assert.h>
#include <ext/hash_map>
#include <string>
int main()
{
char str[] = "test";
assert(__gnu_cxx::hash<const char *>()("test") ==
std::hash<std::string>()("test"));
assert(__gnu_cxx::hash<char *>()(str) == std::hash<std::string>()("test"));
assert(__gnu_cxx::hash<char>()(42) == 42);
assert(__gnu_cxx::hash<signed char>()(42) == 42);
assert(__gnu_cxx::hash<unsigned char>()(42) == 42);
assert(__gnu_cxx::hash<short>()(42) == 42);
assert(__gnu_cxx::hash<unsigned short>()(42) == 42);
assert(__gnu_cxx::hash<int>()(42) == 42);
assert(__gnu_cxx::hash<unsigned int>()(42) == 42);
assert(__gnu_cxx::hash<long>()(42) == 42);
assert(__gnu_cxx::hash<unsigned long>()(42) == 42);
}

View File

@@ -0,0 +1,12 @@
//===----------------------------------------------------------------------===//
//
// 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.
//
//===----------------------------------------------------------------------===//
int main()
{
}