Implement LWG 2686, std::hash<error_condition>, for C++17
authorDaniel Kruegler <daniel.kruegler@gmail.com>
Thu, 23 Mar 2017 19:40:16 +0000 (19:40 +0000)
committerJonathan Wakely <redi@gcc.gnu.org>
Thu, 23 Mar 2017 19:40:16 +0000 (19:40 +0000)
2017-03-23  Daniel Kruegler  <daniel.kruegler@gmail.com>

Implement LWG 2686, Why is std::hash specialized for error_code,
but not error_condition?
* include/std/system_error (hash<error_condition>): Define for C++17.
* testsuite/20_util/hash/operators/size_t.cc (hash<error_condition>):
Instantiate test for error_condition.
* testsuite/20_util/hash/requirements/explicit_instantiation.cc
(hash<error_condition>): Instantiate hash<error_condition>.

From-SVN: r246424

libstdc++-v3/ChangeLog
libstdc++-v3/include/std/system_error
libstdc++-v3/testsuite/20_util/hash/operators/size_t.cc
libstdc++-v3/testsuite/20_util/hash/requirements/explicit_instantiation.cc

index b3e3fe2ba561b921de2f707fd9a537a2f48356bb..1425d28f7f2970e209a700cd559658ecdcde6247 100644 (file)
@@ -1,5 +1,13 @@
 2017-03-23  Daniel Kruegler  <daniel.kruegler@gmail.com>
 
+       Implement LWG 2686, Why is std::hash specialized for error_code,
+       but not error_condition?
+       * include/std/system_error (hash<error_condition>): Define for C++17.
+       * testsuite/20_util/hash/operators/size_t.cc (hash<error_condition>):
+       Instantiate test for error_condition.
+       * testsuite/20_util/hash/requirements/explicit_instantiation.cc
+       (hash<error_condition>): Instantiate hash<error_condition>.
+
        * include/bits/c++config (_GLIBCXX17_INLINE): Define.
        * include/bits/regex_constants.h (All std::regex_constants constants):
        Add _GLIBCXX17_INLINE as per P0607R0.
index 6775a6ea757e2b13a9670dd09114b49bdb751176..ec7d25f25f7966618c408f598a754d376ae6fe56 100644 (file)
@@ -373,14 +373,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
 
-#ifndef _GLIBCXX_COMPATIBILITY_CXX0X
-
 #include <bits/functional_hash.h>
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
+#ifndef _GLIBCXX_COMPATIBILITY_CXX0X
   // DR 1182.
   /// std::hash specialization for error_code.
   template<>
@@ -394,12 +393,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        return std::_Hash_impl::__hash_combine(__e._M_cat, __tmp);
       }
     };
+#endif // _GLIBCXX_COMPATIBILITY_CXX0X
+
+#if __cplusplus > 201402L
+  // DR 2686.
+  /// std::hash specialization for error_condition.
+  template<>
+    struct hash<error_condition>
+    : public __hash_base<size_t, error_condition>
+    {
+      size_t
+      operator()(const error_condition& __e) const noexcept
+      {
+       const size_t __tmp = std::_Hash_impl::hash(__e.value());
+       return std::_Hash_impl::__hash_combine(__e.category(), __tmp);
+      }
+    };
+#endif
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
 
-#endif // _GLIBCXX_COMPATIBILITY_CXX0X
-
 #endif // C++11
 
 #endif // _GLIBCXX_SYSTEM_ERROR
index ad028436889410d9dd7bb2babd52723d7f0da65a..cc191d6f9a7458828905a2f6aa57ce4f25450d9b 100644 (file)
@@ -43,6 +43,9 @@ template<typename T>
 void test01()
 {
   do_test<std::error_code>();
+#if __cplusplus > 201402L
+  do_test<std::error_condition>();
+#endif
 }
 
 int main()
index e9e5ea1ef2bc542fc6b724be05dfc06b54ed1341..d01829af56f38e6ead6f13a18b349f93e3be6bba 100644 (file)
@@ -40,6 +40,9 @@ template class std::hash<long double>;
 template class std::hash<void*>;
 template class std::hash<std::string>;
 template class std::hash<std::error_code>;
+#if __cplusplus > 201402L
+template class std::hash<std::error_condition>;
+#endif
 
 #ifdef _GLIBCXX_USE_WCHAR_T
 template class std::hash<wchar_t>;