mirror of
https://github.com/llvm-mirror/libcxx.git
synced 2025-10-21 15:10:37 +08:00
Implement P0599: 'noexcept for hash functions'. Fix a couple of hash functions (optional<T> and unique_ptr<T>) which were mistakenly marked as 'noexcept'. Reviewed as https://reviews.llvm.org/D31234
git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@298573 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -3037,7 +3037,7 @@ struct _LIBCPP_TEMPLATE_VIS hash<__enable_hash_helper<
|
|||||||
typedef unique_ptr<_Tp, _Dp> argument_type;
|
typedef unique_ptr<_Tp, _Dp> argument_type;
|
||||||
typedef size_t result_type;
|
typedef size_t result_type;
|
||||||
_LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_INLINE_VISIBILITY
|
||||||
result_type operator()(const argument_type& __ptr) const _NOEXCEPT
|
result_type operator()(const argument_type& __ptr) const
|
||||||
{
|
{
|
||||||
typedef typename argument_type::pointer pointer;
|
typedef typename argument_type::pointer pointer;
|
||||||
return hash<pointer>()(__ptr.get());
|
return hash<pointer>()(__ptr.get());
|
||||||
|
@@ -1301,7 +1301,7 @@ struct _LIBCPP_TEMPLATE_VIS hash<
|
|||||||
typedef size_t result_type;
|
typedef size_t result_type;
|
||||||
|
|
||||||
_LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_INLINE_VISIBILITY
|
||||||
result_type operator()(const argument_type& __opt) const _NOEXCEPT
|
result_type operator()(const argument_type& __opt) const
|
||||||
{
|
{
|
||||||
return static_cast<bool>(__opt) ? hash<remove_const_t<_Tp>>()(*__opt) : 0;
|
return static_cast<bool>(__opt) ? hash<remove_const_t<_Tp>>()(*__opt) : 0;
|
||||||
}
|
}
|
||||||
|
@@ -261,7 +261,7 @@ struct _LIBCPP_TEMPLATE_VIS hash<__thread_id>
|
|||||||
: public unary_function<__thread_id, size_t>
|
: public unary_function<__thread_id, size_t>
|
||||||
{
|
{
|
||||||
_LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_INLINE_VISIBILITY
|
||||||
size_t operator()(__thread_id __v) const
|
size_t operator()(__thread_id __v) const _NOEXCEPT
|
||||||
{
|
{
|
||||||
return hash<__libcpp_thread_id>()(__v.__id_);
|
return hash<__libcpp_thread_id>()(__v.__id_);
|
||||||
}
|
}
|
||||||
|
@@ -1562,7 +1562,7 @@ struct _LIBCPP_TEMPLATE_VIS hash<monostate> {
|
|||||||
using result_type = size_t;
|
using result_type = size_t;
|
||||||
|
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
inline _LIBCPP_INLINE_VISIBILITY
|
||||||
result_type operator()(const argument_type&) const {
|
result_type operator()(const argument_type&) const _NOEXCEPT {
|
||||||
return 66740831; // return a fundamentally attractive random value.
|
return 66740831; // return a fundamentally attractive random value.
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -31,7 +31,8 @@ int main()
|
|||||||
typedef std::hash<T> H;
|
typedef std::hash<T> H;
|
||||||
static_assert((std::is_same<H::argument_type, T>::value), "" );
|
static_assert((std::is_same<H::argument_type, T>::value), "" );
|
||||||
static_assert((std::is_same<H::result_type, std::size_t>::value), "" );
|
static_assert((std::is_same<H::result_type, std::size_t>::value), "" );
|
||||||
|
ASSERT_NOEXCEPT(H()(T()));
|
||||||
|
|
||||||
bool ba[] = {true, false, true, true, false};
|
bool ba[] = {true, false, true, true, false};
|
||||||
T vb(std::begin(ba), std::end(ba));
|
T vb(std::begin(ba), std::end(ba));
|
||||||
H h;
|
H h;
|
||||||
@@ -43,6 +44,7 @@ int main()
|
|||||||
typedef std::hash<T> H;
|
typedef std::hash<T> H;
|
||||||
static_assert((std::is_same<H::argument_type, T>::value), "" );
|
static_assert((std::is_same<H::argument_type, T>::value), "" );
|
||||||
static_assert((std::is_same<H::result_type, std::size_t>::value), "" );
|
static_assert((std::is_same<H::result_type, std::size_t>::value), "" );
|
||||||
|
ASSERT_NOEXCEPT(H()(T()));
|
||||||
bool ba[] = {true, false, true, true, false};
|
bool ba[] = {true, false, true, true, false};
|
||||||
T vb(std::begin(ba), std::end(ba));
|
T vb(std::begin(ba), std::end(ba));
|
||||||
H h;
|
H h;
|
||||||
|
@@ -29,6 +29,7 @@ test(int i)
|
|||||||
typedef std::hash<T> H;
|
typedef std::hash<T> H;
|
||||||
static_assert((std::is_same<H::argument_type, T>::value), "" );
|
static_assert((std::is_same<H::argument_type, T>::value), "" );
|
||||||
static_assert((std::is_same<H::result_type, std::size_t>::value), "" );
|
static_assert((std::is_same<H::result_type, std::size_t>::value), "" );
|
||||||
|
ASSERT_NOEXCEPT(H()(T()));
|
||||||
H h;
|
H h;
|
||||||
T ec(i, std::system_category());
|
T ec(i, std::system_category());
|
||||||
const std::size_t result = h(ec);
|
const std::size_t result = h(ec);
|
||||||
|
@@ -29,6 +29,7 @@ test(int i)
|
|||||||
typedef std::hash<T> H;
|
typedef std::hash<T> H;
|
||||||
static_assert((std::is_same<H::argument_type, T>::value), "" );
|
static_assert((std::is_same<H::argument_type, T>::value), "" );
|
||||||
static_assert((std::is_same<H::result_type, std::size_t>::value), "" );
|
static_assert((std::is_same<H::result_type, std::size_t>::value), "" );
|
||||||
|
ASSERT_NOEXCEPT(H()(T()));
|
||||||
H h;
|
H h;
|
||||||
T ec(i, std::system_category());
|
T ec(i, std::system_category());
|
||||||
const std::size_t result = h(ec);
|
const std::size_t result = h(ec);
|
||||||
|
@@ -22,6 +22,8 @@
|
|||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
|
#include "test_macros.h"
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void
|
void
|
||||||
test()
|
test()
|
||||||
@@ -29,6 +31,8 @@ test()
|
|||||||
typedef std::hash<T> H;
|
typedef std::hash<T> H;
|
||||||
static_assert((std::is_same<typename H::argument_type, T>::value), "" );
|
static_assert((std::is_same<typename H::argument_type, T>::value), "" );
|
||||||
static_assert((std::is_same<typename H::result_type, std::size_t>::value), "" );
|
static_assert((std::is_same<typename H::result_type, std::size_t>::value), "" );
|
||||||
|
ASSERT_NOEXCEPT(H()(T()));
|
||||||
|
|
||||||
H h;
|
H h;
|
||||||
std::string g1 = "1234567890";
|
std::string g1 = "1234567890";
|
||||||
std::string g2 = "1234567891";
|
std::string g2 = "1234567891";
|
||||||
|
@@ -23,6 +23,8 @@
|
|||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
|
#include "test_macros.h"
|
||||||
|
|
||||||
using std::string_view;
|
using std::string_view;
|
||||||
|
|
||||||
template <class SV>
|
template <class SV>
|
||||||
@@ -36,6 +38,7 @@ test()
|
|||||||
typedef typename SV::value_type char_type;
|
typedef typename SV::value_type char_type;
|
||||||
typedef std::basic_string<char_type> String;
|
typedef std::basic_string<char_type> String;
|
||||||
typedef std::hash<String> SH;
|
typedef std::hash<String> SH;
|
||||||
|
ASSERT_NOEXCEPT(H()(SV()));
|
||||||
|
|
||||||
char_type g1 [ 10 ];
|
char_type g1 [ 10 ];
|
||||||
char_type g2 [ 10 ];
|
char_type g2 [ 10 ];
|
||||||
|
@@ -23,6 +23,8 @@
|
|||||||
#include <thread>
|
#include <thread>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
|
#include "test_macros.h"
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
std::thread::id id1;
|
std::thread::id id1;
|
||||||
@@ -30,6 +32,7 @@ int main()
|
|||||||
typedef std::hash<std::thread::id> H;
|
typedef std::hash<std::thread::id> H;
|
||||||
static_assert((std::is_same<typename H::argument_type, std::thread::id>::value), "" );
|
static_assert((std::is_same<typename H::argument_type, std::thread::id>::value), "" );
|
||||||
static_assert((std::is_same<typename H::result_type, std::size_t>::value), "" );
|
static_assert((std::is_same<typename H::result_type, std::size_t>::value), "" );
|
||||||
|
ASSERT_NOEXCEPT(H()(id2));
|
||||||
H h;
|
H h;
|
||||||
assert(h(id1) != h(id2));
|
assert(h(id1) != h(id2));
|
||||||
}
|
}
|
||||||
|
@@ -36,6 +36,7 @@ test()
|
|||||||
typedef std::hash<T> H;
|
typedef std::hash<T> H;
|
||||||
static_assert((std::is_same<typename H::argument_type, T>::value), "" );
|
static_assert((std::is_same<typename H::argument_type, T>::value), "" );
|
||||||
static_assert((std::is_same<typename H::result_type, std::size_t>::value), "" );
|
static_assert((std::is_same<typename H::result_type, std::size_t>::value), "" );
|
||||||
|
ASSERT_NOEXCEPT(H()(T()));
|
||||||
typedef typename std::underlying_type<T>::type under_type;
|
typedef typename std::underlying_type<T>::type under_type;
|
||||||
|
|
||||||
H h1;
|
H h1;
|
||||||
|
@@ -24,6 +24,8 @@
|
|||||||
#include <limits>
|
#include <limits>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
|
#include "test_macros.h"
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void
|
void
|
||||||
test()
|
test()
|
||||||
@@ -31,6 +33,7 @@ test()
|
|||||||
typedef std::hash<T> H;
|
typedef std::hash<T> H;
|
||||||
static_assert((std::is_same<typename H::argument_type, T>::value), "" );
|
static_assert((std::is_same<typename H::argument_type, T>::value), "" );
|
||||||
static_assert((std::is_same<typename H::result_type, std::size_t>::value), "" );
|
static_assert((std::is_same<typename H::result_type, std::size_t>::value), "" );
|
||||||
|
ASSERT_NOEXCEPT(H()(T()));
|
||||||
H h;
|
H h;
|
||||||
|
|
||||||
std::size_t t0 = h(0.);
|
std::size_t t0 = h(0.);
|
||||||
|
@@ -31,6 +31,7 @@ test()
|
|||||||
typedef std::hash<T> H;
|
typedef std::hash<T> H;
|
||||||
static_assert((std::is_same<typename H::argument_type, T>::value), "" );
|
static_assert((std::is_same<typename H::argument_type, T>::value), "" );
|
||||||
static_assert((std::is_same<typename H::result_type, std::size_t>::value), "" );
|
static_assert((std::is_same<typename H::result_type, std::size_t>::value), "" );
|
||||||
|
ASSERT_NOEXCEPT(H()(T()));
|
||||||
H h;
|
H h;
|
||||||
|
|
||||||
for (int i = 0; i <= 5; ++i)
|
for (int i = 0; i <= 5; ++i)
|
||||||
@@ -64,42 +65,42 @@ int main()
|
|||||||
test<long long>();
|
test<long long>();
|
||||||
test<unsigned long long>();
|
test<unsigned long long>();
|
||||||
|
|
||||||
// LWG #2119
|
// LWG #2119
|
||||||
test<std::ptrdiff_t>();
|
test<std::ptrdiff_t>();
|
||||||
test<size_t>();
|
test<size_t>();
|
||||||
|
|
||||||
test<int8_t>();
|
test<int8_t>();
|
||||||
test<int16_t>();
|
test<int16_t>();
|
||||||
test<int32_t>();
|
test<int32_t>();
|
||||||
test<int64_t>();
|
test<int64_t>();
|
||||||
|
|
||||||
test<int_fast8_t>();
|
test<int_fast8_t>();
|
||||||
test<int_fast16_t>();
|
test<int_fast16_t>();
|
||||||
test<int_fast32_t>();
|
test<int_fast32_t>();
|
||||||
test<int_fast64_t>();
|
test<int_fast64_t>();
|
||||||
|
|
||||||
test<int_least8_t>();
|
test<int_least8_t>();
|
||||||
test<int_least16_t>();
|
test<int_least16_t>();
|
||||||
test<int_least32_t>();
|
test<int_least32_t>();
|
||||||
test<int_least64_t>();
|
test<int_least64_t>();
|
||||||
|
|
||||||
test<intmax_t>();
|
test<intmax_t>();
|
||||||
test<intptr_t>();
|
test<intptr_t>();
|
||||||
|
|
||||||
test<uint8_t>();
|
test<uint8_t>();
|
||||||
test<uint16_t>();
|
test<uint16_t>();
|
||||||
test<uint32_t>();
|
test<uint32_t>();
|
||||||
test<uint64_t>();
|
test<uint64_t>();
|
||||||
|
|
||||||
test<uint_fast8_t>();
|
test<uint_fast8_t>();
|
||||||
test<uint_fast16_t>();
|
test<uint_fast16_t>();
|
||||||
test<uint_fast32_t>();
|
test<uint_fast32_t>();
|
||||||
test<uint_fast64_t>();
|
test<uint_fast64_t>();
|
||||||
|
|
||||||
test<uint_least8_t>();
|
test<uint_least8_t>();
|
||||||
test<uint_least16_t>();
|
test<uint_least16_t>();
|
||||||
test<uint_least32_t>();
|
test<uint_least32_t>();
|
||||||
test<uint_least64_t>();
|
test<uint_least64_t>();
|
||||||
|
|
||||||
test<uintmax_t>();
|
test<uintmax_t>();
|
||||||
test<uintptr_t>();
|
test<uintptr_t>();
|
||||||
|
@@ -23,6 +23,8 @@
|
|||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
|
#include "test_macros.h"
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void
|
void
|
||||||
test()
|
test()
|
||||||
@@ -30,6 +32,7 @@ test()
|
|||||||
typedef std::hash<T> H;
|
typedef std::hash<T> H;
|
||||||
static_assert((std::is_same<typename H::argument_type, T>::value), "" );
|
static_assert((std::is_same<typename H::argument_type, T>::value), "" );
|
||||||
static_assert((std::is_same<typename H::result_type, std::size_t>::value), "" );
|
static_assert((std::is_same<typename H::result_type, std::size_t>::value), "" );
|
||||||
|
ASSERT_NOEXCEPT(H()(T()));
|
||||||
H h;
|
H h;
|
||||||
|
|
||||||
typedef typename std::remove_pointer<T>::type type;
|
typedef typename std::remove_pointer<T>::type type;
|
||||||
@@ -38,7 +41,17 @@ test()
|
|||||||
assert(h(&i) != h(&j));
|
assert(h(&i) != h(&j));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_nullptr()
|
||||||
|
{
|
||||||
|
typedef std::nullptr_t T;
|
||||||
|
typedef std::hash<T> H;
|
||||||
|
static_assert((std::is_same<typename H::argument_type, T>::value), "" );
|
||||||
|
static_assert((std::is_same<typename H::result_type, std::size_t>::value), "" );
|
||||||
|
ASSERT_NOEXCEPT(H()(T()));
|
||||||
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
test<int*>();
|
test<int*>();
|
||||||
|
test_nullptr();
|
||||||
}
|
}
|
||||||
|
@@ -67,6 +67,7 @@ int main()
|
|||||||
int* ptr = new int;
|
int* ptr = new int;
|
||||||
std::unique_ptr<int> p(ptr);
|
std::unique_ptr<int> p(ptr);
|
||||||
std::hash<std::unique_ptr<int> > f;
|
std::hash<std::unique_ptr<int> > f;
|
||||||
|
ASSERT_NOT_NOEXCEPT(f(p));
|
||||||
std::size_t h = f(p);
|
std::size_t h = f(p);
|
||||||
assert(h == std::hash<int*>()(ptr));
|
assert(h == std::hash<int*>()(ptr));
|
||||||
}
|
}
|
||||||
|
@@ -36,6 +36,7 @@ int main()
|
|||||||
{
|
{
|
||||||
typedef int T;
|
typedef int T;
|
||||||
optional<T> opt;
|
optional<T> opt;
|
||||||
|
ASSERT_NOT_NOEXCEPT(std::hash<optional<T>>()(opt));
|
||||||
assert(std::hash<optional<T>>{}(opt) == nullopt_hash);
|
assert(std::hash<optional<T>>{}(opt) == nullopt_hash);
|
||||||
opt = 2;
|
opt = 2;
|
||||||
assert(std::hash<optional<T>>{}(opt) == std::hash<T>{}(*opt));
|
assert(std::hash<optional<T>>{}(opt) == std::hash<T>{}(*opt));
|
||||||
@@ -43,6 +44,7 @@ int main()
|
|||||||
{
|
{
|
||||||
typedef std::string T;
|
typedef std::string T;
|
||||||
optional<T> opt;
|
optional<T> opt;
|
||||||
|
ASSERT_NOT_NOEXCEPT(std::hash<optional<T>>()(opt));
|
||||||
assert(std::hash<optional<T>>{}(opt) == nullopt_hash);
|
assert(std::hash<optional<T>>{}(opt) == nullopt_hash);
|
||||||
opt = std::string("123");
|
opt = std::string("123");
|
||||||
assert(std::hash<optional<T>>{}(opt) == std::hash<T>{}(*opt));
|
assert(std::hash<optional<T>>{}(opt) == std::hash<T>{}(*opt));
|
||||||
@@ -50,6 +52,7 @@ int main()
|
|||||||
{
|
{
|
||||||
typedef std::unique_ptr<int> T;
|
typedef std::unique_ptr<int> T;
|
||||||
optional<T> opt;
|
optional<T> opt;
|
||||||
|
ASSERT_NOT_NOEXCEPT(std::hash<optional<T>>()(opt));
|
||||||
assert(std::hash<optional<T>>{}(opt) == nullopt_hash);
|
assert(std::hash<optional<T>>{}(opt) == nullopt_hash);
|
||||||
opt = std::unique_ptr<int>(new int(3));
|
opt = std::unique_ptr<int>(new int(3));
|
||||||
assert(std::hash<optional<T>>{}(opt) == std::hash<T>{}(*opt));
|
assert(std::hash<optional<T>>{}(opt) == std::hash<T>{}(*opt));
|
||||||
|
@@ -30,6 +30,8 @@ test()
|
|||||||
typedef std::hash<T> H;
|
typedef std::hash<T> H;
|
||||||
static_assert((std::is_same<typename H::argument_type, T>::value), "" );
|
static_assert((std::is_same<typename H::argument_type, T>::value), "" );
|
||||||
static_assert((std::is_same<typename H::result_type, std::size_t>::value), "" );
|
static_assert((std::is_same<typename H::result_type, std::size_t>::value), "" );
|
||||||
|
ASSERT_NOEXCEPT(H()(T()));
|
||||||
|
|
||||||
H h;
|
H h;
|
||||||
T bs(static_cast<unsigned long long>(N));
|
T bs(static_cast<unsigned long long>(N));
|
||||||
const std::size_t result = h(bs);
|
const std::size_t result = h(bs);
|
||||||
|
@@ -102,6 +102,7 @@ void test_hash_monostate() {
|
|||||||
assert(h(m1) == h(m2));
|
assert(h(m1) == h(m2));
|
||||||
{
|
{
|
||||||
ASSERT_SAME_TYPE(decltype(h(m1)), std::size_t);
|
ASSERT_SAME_TYPE(decltype(h(m1)), std::size_t);
|
||||||
|
ASSERT_NOEXCEPT(h(m1));
|
||||||
static_assert(std::is_copy_constructible<H>::value, "");
|
static_assert(std::is_copy_constructible<H>::value, "");
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user