Implement P0599: 'noexcept for hash functions'. Fix a couple of hash functions (optio...
authorMarshall Clow <mclow.lists@gmail.com>
Thu, 23 Mar 2017 02:40:28 +0000 (02:40 +0000)
committerMarshall Clow <mclow.lists@gmail.com>
Thu, 23 Mar 2017 02:40:28 +0000 (02:40 +0000)
llvm-svn: 298573

18 files changed:
libcxx/include/memory
libcxx/include/optional
libcxx/include/thread
libcxx/include/variant
libcxx/test/std/containers/sequences/vector.bool/vector_bool.pass.cpp
libcxx/test/std/diagnostics/syserr/syserr.hash/error_code.pass.cpp
libcxx/test/std/diagnostics/syserr/syserr.hash/error_condition.pass.cpp
libcxx/test/std/strings/basic.string.hash/strings.pass.cpp
libcxx/test/std/strings/string.view/string.view.hash/string_view.pass.cpp
libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/thread_id.pass.cpp
libcxx/test/std/utilities/function.objects/unord.hash/enum.pass.cpp
libcxx/test/std/utilities/function.objects/unord.hash/floating.pass.cpp
libcxx/test/std/utilities/function.objects/unord.hash/integral.pass.cpp
libcxx/test/std/utilities/function.objects/unord.hash/pointer.pass.cpp
libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.hash/hash_unique_ptr.pass.cpp
libcxx/test/std/utilities/optional/optional.hash/hash.pass.cpp
libcxx/test/std/utilities/template.bitset/bitset.hash/bitset.pass.cpp
libcxx/test/std/utilities/variant/variant.hash/hash.pass.cpp

index c7f540b..8ef4588 100644 (file)
@@ -3037,7 +3037,7 @@ struct _LIBCPP_TEMPLATE_VIS hash<__enable_hash_helper<
     typedef unique_ptr<_Tp, _Dp> argument_type;
     typedef size_t               result_type;
     _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;
         return hash<pointer>()(__ptr.get());
index 180f63f..002842f 100644 (file)
@@ -1301,7 +1301,7 @@ struct _LIBCPP_TEMPLATE_VIS hash<
     typedef size_t        result_type;
 
     _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;
     }
index 94c77e0..874ce3e 100644 (file)
@@ -261,7 +261,7 @@ struct _LIBCPP_TEMPLATE_VIS hash<__thread_id>
     : public unary_function<__thread_id, size_t>
 {
     _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_);
     }
index 099e6c3..33f88e0 100644 (file)
@@ -1562,7 +1562,7 @@ struct _LIBCPP_TEMPLATE_VIS hash<monostate> {
   using result_type = size_t;
 
   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.
   }
 };
index 4f82792..64104a4 100644 (file)
@@ -31,7 +31,8 @@ int main()
     typedef std::hash<T> H;
     static_assert((std::is_same<H::argument_type, 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};
     T vb(std::begin(ba), std::end(ba));
     H h;
@@ -43,6 +44,7 @@ int main()
     typedef std::hash<T> H;
     static_assert((std::is_same<H::argument_type, 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};
     T vb(std::begin(ba), std::end(ba));
     H h;
index 4091f44..dac13bd 100644 (file)
@@ -29,6 +29,7 @@ test(int i)
     typedef std::hash<T> H;
     static_assert((std::is_same<H::argument_type, T>::value), "" );
     static_assert((std::is_same<H::result_type, std::size_t>::value), "" );
+    ASSERT_NOEXCEPT(H()(T()));
     H h;
     T ec(i, std::system_category());
     const std::size_t result = h(ec);
index d455210..eef37c6 100644 (file)
@@ -29,6 +29,7 @@ test(int i)
     typedef std::hash<T> H;
     static_assert((std::is_same<H::argument_type, T>::value), "" );
     static_assert((std::is_same<H::result_type, std::size_t>::value), "" );
+    ASSERT_NOEXCEPT(H()(T()));
     H h;
     T ec(i, std::system_category());
     const std::size_t result = h(ec);
index 5fc32c0..d74e485 100644 (file)
@@ -22,6 +22,8 @@
 #include <cassert>
 #include <type_traits>
 
+#include "test_macros.h"
+
 template <class T>
 void
 test()
@@ -29,6 +31,8 @@ test()
     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()));
+
     H h;
     std::string g1 = "1234567890";
     std::string g2 = "1234567891";
index d076648..53c3d26 100644 (file)
@@ -23,6 +23,8 @@
 #include <cassert>
 #include <type_traits>
 
+#include "test_macros.h"
+
 using std::string_view;
 
 template <class SV>
@@ -36,6 +38,7 @@ test()
     typedef typename SV::value_type char_type;
     typedef std::basic_string<char_type> String;
     typedef std::hash<String> SH;
+    ASSERT_NOEXCEPT(H()(SV()));
 
     char_type g1 [ 10 ];
     char_type g2 [ 10 ];
index f7d4deb..4f1491d 100644 (file)
@@ -23,6 +23,8 @@
 #include <thread>
 #include <cassert>
 
+#include "test_macros.h"
+
 int main()
 {
     std::thread::id id1;
@@ -30,6 +32,7 @@ int main()
     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::result_type, std::size_t>::value), "" );
+    ASSERT_NOEXCEPT(H()(id2));
     H h;
     assert(h(id1) != h(id2));
 }
index 09ea034..a7ddd9a 100644 (file)
@@ -36,6 +36,7 @@ test()
     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()));
     typedef typename std::underlying_type<T>::type under_type;
 
     H h1;
index 643e2d8..e67aa01 100644 (file)
@@ -24,6 +24,8 @@
 #include <limits>
 #include <cmath>
 
+#include "test_macros.h"
+
 template <class T>
 void
 test()
@@ -31,6 +33,7 @@ test()
     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()));
     H h;
 
     std::size_t t0 = h(0.);
index 08a2a8c..ce87f59 100644 (file)
@@ -31,6 +31,7 @@ test()
     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()));
     H h;
 
     for (int i = 0; i <= 5; ++i)
@@ -64,42 +65,42 @@ int main()
     test<long long>();
     test<unsigned long long>();
 
-//     LWG #2119
+//  LWG #2119
     test<std::ptrdiff_t>();
     test<size_t>();
 
-       test<int8_t>();
-       test<int16_t>();
-       test<int32_t>();
-       test<int64_t>();
+    test<int8_t>();
+    test<int16_t>();
+    test<int32_t>();
+    test<int64_t>();
 
-       test<int_fast8_t>();
-       test<int_fast16_t>();
-       test<int_fast32_t>();
-       test<int_fast64_t>();
+    test<int_fast8_t>();
+    test<int_fast16_t>();
+    test<int_fast32_t>();
+    test<int_fast64_t>();
 
-       test<int_least8_t>();
-       test<int_least16_t>();
-       test<int_least32_t>();
-       test<int_least64_t>();
+    test<int_least8_t>();
+    test<int_least16_t>();
+    test<int_least32_t>();
+    test<int_least64_t>();
 
     test<intmax_t>();
     test<intptr_t>();
 
-       test<uint8_t>();
-       test<uint16_t>();
-       test<uint32_t>();
-       test<uint64_t>();
+    test<uint8_t>();
+    test<uint16_t>();
+    test<uint32_t>();
+    test<uint64_t>();
 
-       test<uint_fast8_t>();
-       test<uint_fast16_t>();
-       test<uint_fast32_t>();
-       test<uint_fast64_t>();
+    test<uint_fast8_t>();
+    test<uint_fast16_t>();
+    test<uint_fast32_t>();
+    test<uint_fast64_t>();
 
-       test<uint_least8_t>();
-       test<uint_least16_t>();
-       test<uint_least32_t>();
-       test<uint_least64_t>();
+    test<uint_least8_t>();
+    test<uint_least16_t>();
+    test<uint_least32_t>();
+    test<uint_least64_t>();
 
     test<uintmax_t>();
     test<uintptr_t>();
index a483944..d71514b 100644 (file)
@@ -23,6 +23,8 @@
 #include <type_traits>
 #include <limits>
 
+#include "test_macros.h"
+
 template <class T>
 void
 test()
@@ -30,6 +32,7 @@ test()
     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()));
     H h;
 
     typedef typename std::remove_pointer<T>::type type;
@@ -38,7 +41,17 @@ test()
     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()
 {
     test<int*>();
+    test_nullptr();
 }
index 879ea40..b539e63 100644 (file)
@@ -67,6 +67,7 @@ int main()
     int* ptr = new int;
     std::unique_ptr<int> p(ptr);
     std::hash<std::unique_ptr<int> > f;
+    ASSERT_NOT_NOEXCEPT(f(p));
     std::size_t h = f(p);
     assert(h == std::hash<int*>()(ptr));
   }
index ea89dc3..8f94d6b 100644 (file)
@@ -36,6 +36,7 @@ int main()
     {
         typedef int T;
         optional<T> opt;
+        ASSERT_NOT_NOEXCEPT(std::hash<optional<T>>()(opt));
         assert(std::hash<optional<T>>{}(opt) == nullopt_hash);
         opt = 2;
         assert(std::hash<optional<T>>{}(opt) == std::hash<T>{}(*opt));
@@ -43,6 +44,7 @@ int main()
     {
         typedef std::string T;
         optional<T> opt;
+        ASSERT_NOT_NOEXCEPT(std::hash<optional<T>>()(opt));
         assert(std::hash<optional<T>>{}(opt) == nullopt_hash);
         opt = std::string("123");
         assert(std::hash<optional<T>>{}(opt) == std::hash<T>{}(*opt));
@@ -50,6 +52,7 @@ int main()
     {
         typedef std::unique_ptr<int> T;
         optional<T> opt;
+        ASSERT_NOT_NOEXCEPT(std::hash<optional<T>>()(opt));
         assert(std::hash<optional<T>>{}(opt) == nullopt_hash);
         opt = std::unique_ptr<int>(new int(3));
         assert(std::hash<optional<T>>{}(opt) == std::hash<T>{}(*opt));
index bc65078..8eab082 100644 (file)
@@ -30,6 +30,8 @@ test()
     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()));
+    
     H h;
     T bs(static_cast<unsigned long long>(N));
     const std::size_t result = h(bs);
index 96ef967..840084f 100644 (file)
@@ -102,6 +102,7 @@ void test_hash_monostate() {
   assert(h(m1) == h(m2));
   {
     ASSERT_SAME_TYPE(decltype(h(m1)), std::size_t);
+    ASSERT_NOEXCEPT(h(m1));
     static_assert(std::is_copy_constructible<H>::value, "");
   }
   {