mirror of git://gcc.gnu.org/git/gcc.git
re PR libstdc++/51558 (Declaration of unspecialized std::hash<_Tp>::operator()(_Tp) turns compile-time errors into link-time errors)
2011-12-15 Paolo Carlini <paolo.carlini@oracle.com> Jonathan Wakely <jwakely.gcc@gmail.com> PR libstdc++/51558 * include/bits/functional_hash.h (struct hash): Add static_assert. * src/compatibility-c++0x.cc: Adjust compatibility definitions. * testsuite/23_containers/unordered_map/erase/51142.cc: Adjust. * testsuite/23_containers/unordered_set/erase/51142.cc: Likewise. * testsuite/23_containers/unordered_multimap/erase/51142.cc: Likewise. * testsuite/23_containers/unordered_multiset/erase/51142.cc: Likewise. Co-Authored-By: Jonathan Wakely <jwakely.gcc@gmail.com> From-SVN: r182392
This commit is contained in:
parent
5058651d63
commit
92637e93ed
|
@ -1,3 +1,14 @@
|
||||||
|
2011-12-15 Paolo Carlini <paolo.carlini@oracle.com>
|
||||||
|
Jonathan Wakely <jwakely.gcc@gmail.com>
|
||||||
|
|
||||||
|
PR libstdc++/51558
|
||||||
|
* include/bits/functional_hash.h (struct hash): Add static_assert.
|
||||||
|
* src/compatibility-c++0x.cc: Adjust compatibility definitions.
|
||||||
|
* testsuite/23_containers/unordered_map/erase/51142.cc: Adjust.
|
||||||
|
* testsuite/23_containers/unordered_set/erase/51142.cc: Likewise.
|
||||||
|
* testsuite/23_containers/unordered_multimap/erase/51142.cc: Likewise.
|
||||||
|
* testsuite/23_containers/unordered_multiset/erase/51142.cc: Likewise.
|
||||||
|
|
||||||
2011-12-15 Benjamin Kosnik <bkoz@redhat.com>
|
2011-12-15 Benjamin Kosnik <bkoz@redhat.com>
|
||||||
|
|
||||||
* testsuite/22_locale/num_put/put/char/9780-2.cc: Add test for "C"
|
* testsuite/22_locale/num_put/put/char/9780-2.cc: Add test for "C"
|
||||||
|
|
|
@ -57,8 +57,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
template<typename _Tp>
|
template<typename _Tp>
|
||||||
struct hash : public __hash_base<size_t, _Tp>
|
struct hash : public __hash_base<size_t, _Tp>
|
||||||
{
|
{
|
||||||
size_t
|
static_assert(sizeof(_Tp) < 0,
|
||||||
operator()(_Tp __val) const;
|
"std::hash is not specialized for this type");
|
||||||
|
size_t operator()(const _Tp&) const noexcept;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Partial specializations for pointer types.
|
/// Partial specializations for pointer types.
|
||||||
|
|
|
@ -52,36 +52,60 @@ namespace std _GLIBCXX_VISIBILITY(default)
|
||||||
|
|
||||||
#ifndef _GLIBCXX_LONG_DOUBLE_COMPAT_IMPL
|
#ifndef _GLIBCXX_LONG_DOUBLE_COMPAT_IMPL
|
||||||
template<>
|
template<>
|
||||||
size_t
|
struct hash<string>
|
||||||
hash<string>::operator()(string __s) const
|
{
|
||||||
{ return _Hash_impl::hash(__s.data(), __s.length()); }
|
size_t operator()(string) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
size_t
|
||||||
|
hash<string>::operator()(string __s) const
|
||||||
|
{ return _Hash_impl::hash(__s.data(), __s.length()); }
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
size_t
|
struct hash<const string&>
|
||||||
hash<const string&>::operator()(const string& __s) const
|
{
|
||||||
{ return _Hash_impl::hash(__s.data(), __s.length()); }
|
size_t operator()(const string&) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
size_t
|
||||||
|
hash<const string&>::operator()(const string& __s) const
|
||||||
|
{ return _Hash_impl::hash(__s.data(), __s.length()); }
|
||||||
|
|
||||||
#ifdef _GLIBCXX_USE_WCHAR_T
|
#ifdef _GLIBCXX_USE_WCHAR_T
|
||||||
template<>
|
template<>
|
||||||
size_t
|
struct hash<wstring>
|
||||||
hash<wstring>::operator()(wstring __s) const
|
{
|
||||||
{ return _Hash_impl::hash(__s.data(), __s.length() * sizeof(wchar_t)); }
|
size_t operator()(wstring) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
size_t
|
||||||
|
hash<wstring>::operator()(wstring __s) const
|
||||||
|
{ return _Hash_impl::hash(__s.data(), __s.length() * sizeof(wchar_t)); }
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
size_t
|
struct hash<const wstring&>
|
||||||
hash<const wstring&>::operator()(const wstring& __s) const
|
|
||||||
{ return _Hash_impl::hash(__s.data(), __s.length() * sizeof(wchar_t)); }
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template<>
|
|
||||||
size_t
|
|
||||||
hash<error_code>::operator()(error_code __e) const
|
|
||||||
{
|
{
|
||||||
const size_t __tmp = std::_Hash_impl::hash(__e._M_value);
|
size_t operator()(const wstring&) const;
|
||||||
return std::_Hash_impl::__hash_combine(__e._M_cat, __tmp);
|
};
|
||||||
}
|
|
||||||
|
|
||||||
|
size_t
|
||||||
|
hash<const wstring&>::operator()(const wstring& __s) const
|
||||||
|
{ return _Hash_impl::hash(__s.data(), __s.length() * sizeof(wchar_t)); }
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct hash<error_code>
|
||||||
|
{
|
||||||
|
size_t operator()(error_code) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
size_t
|
||||||
|
hash<error_code>::operator()(error_code __e) const
|
||||||
|
{
|
||||||
|
const size_t __tmp = std::_Hash_impl::hash(__e._M_value);
|
||||||
|
return std::_Hash_impl::__hash_combine(__e._M_cat, __tmp);
|
||||||
|
}
|
||||||
|
|
||||||
// gcc-4.7.0
|
// gcc-4.7.0
|
||||||
// <chrono> changes is_monotonic to is_steady.
|
// <chrono> changes is_monotonic to is_steady.
|
||||||
|
|
|
@ -27,12 +27,15 @@ struct X
|
||||||
X(T&) {}
|
X(T&) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct X_hash
|
||||||
|
{ std::size_t operator()(const X&) const { return 0; } };
|
||||||
|
|
||||||
bool operator==(const X&, const X&) { return false; }
|
bool operator==(const X&, const X&) { return false; }
|
||||||
|
|
||||||
// LWG 2059.
|
// LWG 2059.
|
||||||
void erasor(std::unordered_map<X, int>& s, X x)
|
void erasor(std::unordered_map<X, int, X_hash>& s, X x)
|
||||||
{
|
{
|
||||||
std::unordered_map<X, int>::iterator it = s.find(x);
|
std::unordered_map<X, int, X_hash>::iterator it = s.find(x);
|
||||||
if (it != s.end())
|
if (it != s.end())
|
||||||
s.erase(it);
|
s.erase(it);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,12 +27,15 @@ struct X
|
||||||
X(T&) {}
|
X(T&) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct X_hash
|
||||||
|
{ std::size_t operator()(const X&) const { return 0; } };
|
||||||
|
|
||||||
bool operator==(const X&, const X&) { return false; }
|
bool operator==(const X&, const X&) { return false; }
|
||||||
|
|
||||||
// LWG 2059.
|
// LWG 2059.
|
||||||
void erasor(std::unordered_multimap<X, int>& s, X x)
|
void erasor(std::unordered_multimap<X, int, X_hash>& s, X x)
|
||||||
{
|
{
|
||||||
std::unordered_multimap<X, int>::iterator it = s.find(x);
|
std::unordered_multimap<X, int, X_hash>::iterator it = s.find(x);
|
||||||
if (it != s.end())
|
if (it != s.end())
|
||||||
s.erase(it);
|
s.erase(it);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,12 +27,15 @@ struct X
|
||||||
X(T&) {}
|
X(T&) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct X_hash
|
||||||
|
{ std::size_t operator()(const X&) const { return 0; } };
|
||||||
|
|
||||||
bool operator==(const X&, const X&) { return false; }
|
bool operator==(const X&, const X&) { return false; }
|
||||||
|
|
||||||
// LWG 2059.
|
// LWG 2059.
|
||||||
void erasor(std::unordered_multiset<X>& s, X x)
|
void erasor(std::unordered_multiset<X, X_hash>& s, X x)
|
||||||
{
|
{
|
||||||
std::unordered_multiset<X>::iterator it = s.find(x);
|
std::unordered_multiset<X, X_hash>::iterator it = s.find(x);
|
||||||
if (it != s.end())
|
if (it != s.end())
|
||||||
s.erase(it);
|
s.erase(it);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,12 +27,15 @@ struct X
|
||||||
X(T&) {}
|
X(T&) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct X_hash
|
||||||
|
{ std::size_t operator()(const X&) const { return 0; } };
|
||||||
|
|
||||||
bool operator==(const X&, const X&) { return false; }
|
bool operator==(const X&, const X&) { return false; }
|
||||||
|
|
||||||
// LWG 2059.
|
// LWG 2059.
|
||||||
void erasor(std::unordered_set<X>& s, X x)
|
void erasor(std::unordered_set<X, X_hash>& s, X x)
|
||||||
{
|
{
|
||||||
std::unordered_set<X>::iterator it = s.find(x);
|
std::unordered_set<X, X_hash>::iterator it = s.find(x);
|
||||||
if (it != s.end())
|
if (it != s.end())
|
||||||
s.erase(it);
|
s.erase(it);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue