This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Implement LWG 2686, hash<error_condition>


On 12/03/17 13:16 +0100, Daniel Krügler wrote:
The following is an *untested* patch suggestion, please verify.

Notes: My interpretation is that hash<error_condition> should be
defined outside of the _GLIBCXX_COMPATIBILITY_CXX0X block, please
double-check that course of action.

That's right.

I noticed that the preexisting hash<error_code> did directly refer to
the private members of error_code albeit those have public access
functions. For consistency I mimicked that existing style when
implementing hash<error_condition>.

I see no reason for that, so I've removed the friend declaration and
used the public member functions.

Although this is a DR, I'm treating it as a new C++17 feature, so I've
adjusted the patch to only add the new specialization for C++17 mode.
We're too close to the GCC 7 release to be adding new things to the
default mode, even minor things like this. After GCC 7 is released we
can revisit it and decide if we want to enable it for all modes.

Here's what I've tested and will be committing.


commit 90ca0fd91f5c65af370beb20af06bdca257aaf63
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Thu Mar 23 11:47:39 2017 +0000

    Implement LWG 2686, std::hash<error_condition>, for C++17
    
    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>.

diff --git a/libstdc++-v3/include/std/system_error b/libstdc++-v3/include/std/system_error
index 6775a6e..ec7d25f 100644
--- a/libstdc++-v3/include/std/system_error
+++ b/libstdc++-v3/include/std/system_error
@@ -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
diff --git a/libstdc++-v3/testsuite/20_util/hash/operators/size_t.cc b/libstdc++-v3/testsuite/20_util/hash/operators/size_t.cc
index ad02843..cc191d6 100644
--- a/libstdc++-v3/testsuite/20_util/hash/operators/size_t.cc
+++ b/libstdc++-v3/testsuite/20_util/hash/operators/size_t.cc
@@ -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()
diff --git a/libstdc++-v3/testsuite/20_util/hash/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/20_util/hash/requirements/explicit_instantiation.cc
index e9e5ea1..d01829a 100644
--- a/libstdc++-v3/testsuite/20_util/hash/requirements/explicit_instantiation.cc
+++ b/libstdc++-v3/testsuite/20_util/hash/requirements/explicit_instantiation.cc
@@ -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>;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]