Commit 15d81a3c by Paolo Carlini Committed by Paolo Carlini

functional_hash.h (hash<string>, [...]): Move, per DR 1182 to...

2010-02-22  Paolo Carlini  <paolo.carlini@oracle.com>

	* include/bits/functional_hash.h (hash<string>, hash<wstring>,
	hash<u16string>, hash<u32string>, hash<error_code>): Move, per
	DR 1182 to...
	* include/bits/basic_string.h: ... here.
	* include/std/system_error: ... and here, respectively.
	* src/hash-aux.cc (hash<long double>::operator()(long double)):
	Move definition...
	* src/hash_c++0x.cc: ... here, new file.
	* src/hash_tr1.cc: ... and here, tweak includes.
	* src/compatibility-c++0x.cc (hash, _Fnv_hash): Remove.
	* src/Makefile.am: Adjust.
	* src/Makefile.in: Regenerate.
	* include/std/functional: Include <bits/functexcept.h>.
	* include/std/unordered_set: Remove redundant include.
	* include/std/unordered_map: Likewise.
	* include/tr1/functional_hash.h: Remove spurious trailing semicolon.
	* testsuite/20_util/weak_ptr/comparison/cmp_neg.cc: Remove
	dg-excess.

From-SVN: r156971
parent ea2edf88
2010-02-22 Paolo Carlini <paolo.carlini@oracle.com>
* include/bits/functional_hash.h (hash<string>, hash<wstring>,
hash<u16string>, hash<u32string>, hash<error_code>): Move, per
DR 1182 to...
* include/bits/basic_string.h: ... here.
* include/std/system_error: ... and here, respectively.
* src/hash-aux.cc (hash<long double>::operator()(long double)):
Move definition...
* src/hash_c++0x.cc: ... here, new file.
* src/hash_tr1.cc: ... and here, tweak includes.
* src/compatibility-c++0x.cc (hash, _Fnv_hash): Remove.
* src/Makefile.am: Adjust.
* src/Makefile.in: Regenerate.
* include/std/functional: Include <bits/functexcept.h>.
* include/std/unordered_set: Remove redundant include.
* include/std/unordered_map: Likewise.
* include/tr1/functional_hash.h: Remove spurious trailing semicolon.
* testsuite/20_util/weak_ptr/comparison/cmp_neg.cc: Remove
dg-excess.
2010-02-21 Paolo Carlini <paolo.carlini@oracle.com>
* include/std/complex (proj): Change return type per DR 1137.
......
......@@ -2869,6 +2869,73 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
_GLIBCXX_END_NAMESPACE
#endif /* __GXX_EXPERIMENTAL_CXX0X__ && _GLIBCXX_USE_C99 ... */
#ifdef __GXX_EXPERIMENTAL_CXX0X__
#include <bits/functional_hash.h>
_GLIBCXX_BEGIN_NAMESPACE(std)
// DR 1182.
#ifndef _GLIBCXX_COMPATIBILITY_CXX0X
/// std::hash specialization for string.
template<>
struct hash<string>
: public std::unary_function<string, size_t>
{
size_t
operator()(const string& __s) const
{ return _Fnv_hash<>::hash(__s.data(), __s.length()); }
};
#ifdef _GLIBCXX_USE_WCHAR_T
/// std::hash specialization for wstring.
template<>
struct hash<wstring>
: public std::unary_function<wstring, size_t>
{
size_t
operator()(const wstring& __s) const
{
const char* __p = reinterpret_cast<const char*>(__s.data());
return _Fnv_hash<>::hash(__p, __s.length() * sizeof(wchar_t));
}
};
#endif
#endif /* _GLIBCXX_COMPATIBILITY_CXX0X */
#ifdef _GLIBCXX_USE_C99_STDINT_TR1
/// std::hash specialization for u16string.
template<>
struct hash<u16string>
: public std::unary_function<u16string, size_t>
{
size_t
operator()(const u16string& __s) const
{
const char* __p = reinterpret_cast<const char*>(__s.data());
return _Fnv_hash<>::hash(__p, __s.length() * sizeof(char16_t));
}
};
/// std::hash specialization for u32string.
template<>
struct hash<u32string>
: public std::unary_function<u32string, size_t>
{
size_t
operator()(const u32string& __s) const
{
const char* __p = reinterpret_cast<const char*>(__s.data());
return _Fnv_hash<>::hash(__p, __s.length() * sizeof(char32_t));
}
};
#endif
_GLIBCXX_END_NAMESPACE
#endif /* __GXX_EXPERIMENTAL_CXX0X__ */
#endif /* _BASIC_STRING_H */
......@@ -32,8 +32,8 @@
#pragma GCC system_header
#include <string>
#include <system_error>
#include <cstddef>
#include <bits/stl_function.h>
namespace std
{
......@@ -44,10 +44,14 @@ namespace std
*
* @{
*/
/// Primary class template hash.
template<typename _Tp>
struct hash;
struct hash : public std::unary_function<_Tp, size_t>
{
size_t
operator()(_Tp __val) const;
};
/// Partial specializations for pointer types.
template<typename _Tp>
......@@ -59,14 +63,11 @@ namespace std
};
// Explicit specializations for integer types.
#define _Cxx_hashtable_define_trivial_hash(_Tp) \
template<> \
struct hash<_Tp> : public std::unary_function<_Tp, size_t> \
{ \
size_t \
operator()(_Tp __val) const \
{ return static_cast<size_t>(__val); } \
};
#define _Cxx_hashtable_define_trivial_hash(_Tp) \
template<> \
inline size_t \
hash<_Tp>::operator()(_Tp __val) const \
{ return static_cast<size_t>(__val); }
/// Explicit specialization for bool.
_Cxx_hashtable_define_trivial_hash(bool);
......@@ -83,13 +84,11 @@ namespace std
/// Explicit specialization for wchar_t.
_Cxx_hashtable_define_trivial_hash(wchar_t);
#ifdef _GLIBCXX_USE_C99_STDINT_TR1
/// Explicit specialization for char16_t.
_Cxx_hashtable_define_trivial_hash(char16_t);
/// Explicit specialization for char32_t.
_Cxx_hashtable_define_trivial_hash(char32_t);
#endif
/// Explicit specialization for short.
_Cxx_hashtable_define_trivial_hash(short);
......@@ -118,10 +117,13 @@ namespace std
#undef _Cxx_hashtable_define_trivial_hash
// Fowler / Noll / Vo (FNV) Hash (type FNV-1a)
// (Used by the next specializations of std::tr1::hash.)
// (Used by the next specializations of std::hash.)
// Dummy generic implementation (for sizeof(size_t) != 4, 8).
template<size_t = sizeof(size_t)>
struct _Fnv_hash;
// Dummy generic implementation (for sizeof(size_t) != 4, 8).
template<size_t>
struct _Fnv_hash
{
static size_t
......@@ -167,139 +169,39 @@ namespace std
}
};
/// Explicit specializations for float.
/// Specialization for float.
template<>
struct hash<float>
: public std::unary_function<float, size_t>
inline size_t
hash<float>::operator()(float __val) const
{
size_t
operator()(float __val) const
{
size_t __result = 0;
size_t __result = 0;
// 0 and -0 both hash to zero.
if (__val != 0.0f)
__result = _Fnv_hash<>::hash(reinterpret_cast<const char*>(&__val),
sizeof(__val));
return __result;
}
};
/// Explicit specializations for double.
template<>
struct hash<double>
: public std::unary_function<double, size_t>
{
size_t
operator()(double __val) const
{
size_t __result = 0;
// 0 and -0 both hash to zero.
if (__val != 0.0)
__result = _Fnv_hash<>::hash(reinterpret_cast<const char*>(&__val),
sizeof(__val));
return __result;
}
};
/// Explicit specializations for long double.
template<>
struct hash<long double>
: public std::unary_function<long double, size_t>
{
size_t
operator()(long double __val) const
{
size_t __result = 0;
int __exponent;
__val = __builtin_frexpl(__val, &__exponent);
__val = __val < 0.0l ? -(__val + 0.5l) : __val;
const long double __mult =
__gnu_cxx::__numeric_traits<size_t>::__max + 1.0l;
__val *= __mult;
// Try to use all the bits of the mantissa (really necessary only
// on 32-bit targets, at least for 80-bit floating point formats).
const size_t __hibits = (size_t)__val;
__val = (__val - (long double)__hibits) * __mult;
const size_t __coeff =
__gnu_cxx::__numeric_traits<size_t>::__max / __LDBL_MAX_EXP__;
__result = __hibits + (size_t)__val + __coeff * __exponent;
return __result;
}
};
/// Explicit specializations for string.
// 0 and -0 both hash to zero.
if (__val != 0.0f)
__result = _Fnv_hash<>::hash(reinterpret_cast<const char*>(&__val),
sizeof(__val));
return __result;
}
/// Specialization for double.
template<>
struct hash<string>
: public std::unary_function<string, size_t>
inline size_t
hash<double>::operator()(double __val) const
{
size_t
operator()(const string& __s) const
{ return _Fnv_hash<>::hash(__s.data(), __s.length()); }
};
size_t __result = 0;
#ifdef _GLIBCXX_USE_WCHAR_T
/// Explicit specializations for wstring.
template<>
struct hash<wstring>
: public std::unary_function<wstring, size_t>
{
size_t
operator()(const wstring& __s) const
{
const char* __p = reinterpret_cast<const char*>(__s.data());
return _Fnv_hash<>::hash(__p, __s.length() * sizeof(wchar_t));
}
};
#endif
// 0 and -0 both hash to zero.
if (__val != 0.0)
__result = _Fnv_hash<>::hash(reinterpret_cast<const char*>(&__val),
sizeof(__val));
return __result;
}
#ifdef _GLIBCXX_USE_C99_STDINT_TR1
/// Explicit specializations for u16string.
/// Specialization for long double.
template<>
struct hash<u16string>
: public std::unary_function<u16string, size_t>
{
size_t
operator()(const u16string& __s) const
{
const char* __p = reinterpret_cast<const char*>(__s.data());
return _Fnv_hash<>::hash(__p, __s.length() * sizeof(char16_t));
}
};
/// Explicit specializations for u32string.
template<>
struct hash<u32string>
: public std::unary_function<u32string, size_t>
{
size_t
operator()(const u32string& __s) const
{
const char* __p = reinterpret_cast<const char*>(__s.data());
return _Fnv_hash<>::hash(__p, __s.length() * sizeof(char32_t));
}
};
#endif
size_t
hash<long double>::operator()(long double __val) const;
/// Explicit specializations for error_code.
template<>
struct hash<error_code>
: public std::unary_function<error_code, size_t>
{
size_t
operator()(const error_code& __e) const
{
const char* __p = reinterpret_cast<const char*>(&__e);
return _Fnv_hash<>::hash(__p, sizeof(__e));
}
};
// @} group hashes
}
......
......@@ -55,6 +55,7 @@
#include <new>
#include <tuple>
#include <type_traits>
#include <bits/functexcept.h>
#include <bits/functional_hash.h>
namespace std
......
......@@ -335,6 +335,30 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
_GLIBCXX_END_NAMESPACE
#ifndef _GLIBCXX_COMPATIBILITY_CXX0X
#include <bits/functional_hash.h>
_GLIBCXX_BEGIN_NAMESPACE(std)
// DR 1182.
/// std::hash specialization for error_code.
template<>
struct hash<error_code>
: public std::unary_function<error_code, size_t>
{
size_t
operator()(const error_code& __e) const
{
const char* __p = reinterpret_cast<const char*>(&__e);
return _Fnv_hash<>::hash(__p, sizeof(__e));
}
};
_GLIBCXX_END_NAMESPACE
#endif // _GLIBCXX_COMPATIBILITY_CXX0X
#endif // __GXX_EXPERIMENTAL_CXX0X__
#endif // _GLIBCXX_SYSTEM_ERROR
......
......@@ -41,7 +41,6 @@
#include <bits/stl_algobase.h>
#include <bits/allocator.h>
#include <bits/stl_function.h> // equal_to, _Identity, _Select1st
#include <bits/stringfwd.h>
#include <bits/functional_hash.h>
#include <bits/hashtable.h>
#include <bits/unordered_map.h>
......
......@@ -41,7 +41,6 @@
#include <bits/stl_algobase.h>
#include <bits/allocator.h>
#include <bits/stl_function.h> // equal_to, _Identity, _Select1st
#include <bits/stringfwd.h>
#include <bits/functional_hash.h>
#include <bits/hashtable.h>
#include <bits/unordered_set.h>
......
......@@ -140,7 +140,7 @@ namespace tr1
__result = _Fnv_hash<>::hash(reinterpret_cast<const char*>(&__val),
sizeof(__val));
return __result;
};
}
/// Explicit specializations for double.
template<>
......@@ -154,7 +154,7 @@ namespace tr1
__result = _Fnv_hash<>::hash(reinterpret_cast<const char*>(&__val),
sizeof(__val));
return __result;
};
}
/// Explicit specializations for long double.
template<>
......
......@@ -148,10 +148,11 @@ sources = \
ctype.cc \
debug.cc \
functexcept.cc \
hash_tr1.cc \
globals_io.cc \
hashtable_tr1.cc \
hash_c++0x.cc \
hash_tr1.cc \
hashtable_c++0x.cc \
hashtable_tr1.cc \
ios.cc \
ios_failure.cc \
ios_init.cc \
......@@ -272,6 +273,11 @@ compatibility-c++0x.lo: compatibility-c++0x.cc
compatibility-c++0x.o: compatibility-c++0x.cc
$(CXXCOMPILE) -std=gnu++0x -c $<
hash_c++0x.lo: hash_c++0x.cc
$(LTCXXCOMPILE) -std=gnu++0x -c $<
hash_c++0x.o: hash_c++0x.cc
$(CXXCOMPILE) -std=gnu++0x -c $<
hashtable_c++0x.lo: hashtable_c++0x.cc
$(LTCXXCOMPILE) -std=gnu++0x -c $<
hashtable_c++0x.o: hashtable_c++0x.cc
......
......@@ -89,10 +89,10 @@ am__libstdc___la_SOURCES_DIST = atomic.cc bitmap_allocator.cc \
pool_allocator.cc mt_allocator.cc codecvt.cc compatibility.cc \
compatibility-c++0x.cc compatibility-debug_list.cc \
compatibility-list.cc complex_io.cc ctype.cc debug.cc \
functexcept.cc hash_tr1.cc globals_io.cc hashtable_tr1.cc \
hashtable_c++0x.cc ios.cc ios_failure.cc ios_init.cc \
ios_locale.cc limits.cc list.cc debug_list.cc locale.cc \
locale_init.cc locale_facets.cc localename.cc \
functexcept.cc globals_io.cc hash_c++0x.cc hash_tr1.cc \
hashtable_c++0x.cc hashtable_tr1.cc ios.cc ios_failure.cc \
ios_init.cc ios_locale.cc limits.cc list.cc debug_list.cc \
locale.cc locale_init.cc locale_facets.cc localename.cc \
math_stubs_float.cc math_stubs_long_double.cc stdexcept.cc \
strstream.cc system_error.cc tree.cc allocator-inst.cc \
concept-inst.cc fstream-inst.cc ext-inst.cc ios-inst.cc \
......@@ -119,10 +119,10 @@ am__objects_5 = atomic.lo bitmap_allocator.lo pool_allocator.lo \
mt_allocator.lo codecvt.lo compatibility.lo \
compatibility-c++0x.lo compatibility-debug_list.lo \
compatibility-list.lo complex_io.lo ctype.lo debug.lo \
functexcept.lo hash_tr1.lo globals_io.lo hashtable_tr1.lo \
hashtable_c++0x.lo ios.lo ios_failure.lo ios_init.lo \
ios_locale.lo limits.lo list.lo debug_list.lo locale.lo \
locale_init.lo locale_facets.lo localename.lo \
functexcept.lo globals_io.lo hash_c++0x.lo hash_tr1.lo \
hashtable_c++0x.lo hashtable_tr1.lo ios.lo ios_failure.lo \
ios_init.lo ios_locale.lo limits.lo list.lo debug_list.lo \
locale.lo locale_init.lo locale_facets.lo localename.lo \
math_stubs_float.lo math_stubs_long_double.lo stdexcept.lo \
strstream.lo system_error.lo tree.lo allocator-inst.lo \
concept-inst.lo fstream-inst.lo ext-inst.lo ios-inst.lo \
......@@ -394,10 +394,11 @@ sources = \
ctype.cc \
debug.cc \
functexcept.cc \
hash_tr1.cc \
globals_io.cc \
hashtable_tr1.cc \
hash_c++0x.cc \
hash_tr1.cc \
hashtable_c++0x.cc \
hashtable_tr1.cc \
ios.cc \
ios_failure.cc \
ios_init.cc \
......@@ -907,6 +908,11 @@ compatibility-c++0x.lo: compatibility-c++0x.cc
compatibility-c++0x.o: compatibility-c++0x.cc
$(CXXCOMPILE) -std=gnu++0x -c $<
hash_c++0x.lo: hash_c++0x.cc
$(LTCXXCOMPILE) -std=gnu++0x -c $<
hash_c++0x.o: hash_c++0x.cc
$(CXXCOMPILE) -std=gnu++0x -c $<
hashtable_c++0x.lo: hashtable_c++0x.cc
$(LTCXXCOMPILE) -std=gnu++0x -c $<
hashtable_c++0x.o: hashtable_c++0x.cc
......
......@@ -22,9 +22,8 @@
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
#include <cstddef>
#define _GLIBCXX_COMPATIBILITY_CXX0X
#include <string>
#include <cmath>
#include <system_error>
#ifndef __GXX_EXPERIMENTAL_CXX0X__
......@@ -50,59 +49,6 @@ namespace std
// We need these due to the symbols exported since GLIBCXX_3.4.10.
// See libstdc++/41662 for details.
template<typename _Tp>
struct hash : public std::unary_function<_Tp, size_t>
{
size_t
operator()(_Tp __val) const;
};
/// Dummy generic implementation (for sizeof(size_t) != 4, 8).
template<size_t = sizeof(size_t)>
struct _Fnv_hash
{
static size_t
hash(const char* __first, size_t __length)
{
size_t __result = 0;
for (; __length > 0; --__length)
__result = (__result * 131) + *__first++;
return __result;
}
};
template<>
struct _Fnv_hash<4>
{
static size_t
hash(const char* __first, size_t __length)
{
size_t __result = static_cast<size_t>(2166136261UL);
for (; __length > 0; --__length)
{
__result ^= static_cast<size_t>(*__first++);
__result *= static_cast<size_t>(16777619UL);
}
return __result;
}
};
template<>
struct _Fnv_hash<8>
{
static size_t
hash(const char* __first, size_t __length)
{
size_t __result =
static_cast<size_t>(14695981039346656037ULL);
for (; __length > 0; --__length)
{
__result ^= static_cast<size_t>(*__first++);
__result *= static_cast<size_t>(1099511628211ULL);
}
return __result;
}
};
#include "hash-aux.cc"
......
// std::hash and std::tr1::hash definitions -*- C++ -*-
// Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
// Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
......@@ -22,35 +22,6 @@
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
// For long double, careful with random padding bits (e.g., on x86,
// 10 bytes -> 12 bytes) and resort to frexp.
template<>
size_t
hash<long double>::operator()(long double __val) const
{
size_t __result = 0;
int __exponent;
__val = std::frexp(__val, &__exponent);
__val = __val < 0.0l ? -(__val + 0.5l) : __val;
const long double __mult =
__gnu_cxx::__numeric_traits<size_t>::__max + 1.0l;
__val *= __mult;
// Try to use all the bits of the mantissa (really necessary only
// on 32-bit targets, at least for 80-bit floating point formats).
const size_t __hibits = (size_t)__val;
__val = (__val - (long double)__hibits) * __mult;
const size_t __coeff =
__gnu_cxx::__numeric_traits<size_t>::__max / __LDBL_MAX_EXP__;
__result = __hibits + (size_t)__val + __coeff * __exponent;
return __result;
};
#ifndef _GLIBCXX_LONG_DOUBLE_COMPAT_IMPL
template<>
size_t
......@@ -79,4 +50,5 @@
return _Fnv_hash<>::hash(__p, __s.length() * sizeof(wchar_t));
}
#endif
#endif
// std::hash definitions -*- C++ -*-
// Copyright (C) 2010 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
#ifndef __GXX_EXPERIMENTAL_CXX0X__
# error "hash_c++0x.cc must be compiled with -std=gnu++0x"
#endif
#include <bits/functional_hash.h>
namespace std
{
/// std::hash specialization for long double.
template<>
size_t
hash<long double>::operator()(long double __val) const
{
size_t __result = 0;
int __exponent;
__val = __builtin_frexpl(__val, &__exponent);
__val = __val < 0.0l ? -(__val + 0.5l) : __val;
const long double __mult = __SIZE_MAX__ + 1.0l;
__val *= __mult;
// Try to use all the bits of the mantissa (really necessary only
// on 32-bit targets, at least for 80-bit floating point formats).
const size_t __hibits = (size_t)__val;
__val = (__val - (long double)__hibits) * __mult;
const size_t __coeff = __SIZE_MAX__ / __LDBL_MAX_EXP__;
__result = __hibits + (size_t)__val + __coeff * __exponent;
return __result;
}
}
// std::hash definitions -*- C++ -*-
// std::tr1::hash definitions -*- C++ -*-
// Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
//
......@@ -22,9 +22,7 @@
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
#include <cstddef>
#include <string>
#include <cmath>
#include <tr1/functional>
namespace std
......@@ -32,5 +30,32 @@ namespace std
namespace tr1
{
#include "hash-aux.cc"
// For long double, careful with random padding bits (e.g., on x86,
// 10 bytes -> 12 bytes) and resort to frexp.
template<>
size_t
hash<long double>::operator()(long double __val) const
{
size_t __result = 0;
int __exponent;
__val = __builtin_frexpl(__val, &__exponent);
__val = __val < 0.0l ? -(__val + 0.5l) : __val;
const long double __mult = __SIZE_MAX__ + 1.0l;
__val *= __mult;
// Try to use all the bits of the mantissa (really necessary only
// on 32-bit targets, at least for 80-bit floating point formats).
const size_t __hibits = (size_t)__val;
__val = (__val - (long double)__hibits) * __mult;
const size_t __coeff = __SIZE_MAX__ / __LDBL_MAX_EXP__;
__result = __hibits + (size_t)__val + __coeff * __exponent;
return __result;
}
}
}
......@@ -30,7 +30,6 @@ int
test01()
{
std::weak_ptr<A> p1;
// { dg-excess-errors "candidates are" }
p1 < p1; // { dg-error "no match" }
return 0;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment