public inbox for libstdc++-cvs@sourceware.org
help / color / mirror / Atom feed
From: Jonathan Wakely <redi@gcc.gnu.org>
To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org
Subject: [gcc r13-2223] libstdc++: Simplify std::error_code and std::error_condition
Date: Fri, 26 Aug 2022 15:20:41 +0000 (GMT)	[thread overview]
Message-ID: <20220826152041.95D573851AB5@sourceware.org> (raw)

https://gcc.gnu.org/g:1c0288065b8184e0051d846b0940027b97ea0eb4

commit r13-2223-g1c0288065b8184e0051d846b0940027b97ea0eb4
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Fri Aug 26 12:55:02 2022 +0100

    libstdc++: Simplify std::error_code and std::error_condition
    
    This removes the redundant operator=(E) from std::error_code and
    std::error_condition. Without that overload, assignment from a custom
    type will use the templated constructor to create a temporary and then
    use the trivial copy assignment operator. With the overloaded
    assignment, we have to check the constraints twice as often, because
    that overload and its constraints are checked for simple copy
    assignments (including the one in the overloaded assignment operator
    itself!)
    
    Also add tests that ADL is used as per LWG 3629.
    
    libstdc++-v3/ChangeLog:
    
            * include/std/system_error (error_code::_Check): New alias
            template for constructor SFINAE constraint.
            (error_code::error_code(ErrorCodeEnum)): Use it.
            (error_code::operator=(ErrorCodeEnum)): Remove.
            (error_condition::_Check): New alias template for constraint.
            (error_condition::error_condition(ErrorConditionEnum)): Use it.
            (error_condition::operator=(ErrorConditionEnum)): Remove.
            * testsuite/19_diagnostics/error_code/cons/1.cc: Check
            constructor taking user-defined error enum.
            * testsuite/19_diagnostics/error_condition/cons/1.cc: Likewise.

Diff:
---
 libstdc++-v3/include/std/system_error              | 38 ++++++++++++----------
 .../testsuite/19_diagnostics/error_code/cons/1.cc  | 31 +++++++++++++++---
 .../19_diagnostics/error_condition/cons/1.cc       | 31 ++++++++++++++++--
 3 files changed, 75 insertions(+), 25 deletions(-)

diff --git a/libstdc++-v3/include/std/system_error b/libstdc++-v3/include/std/system_error
index 87cf720f6e3..050439427cc 100644
--- a/libstdc++-v3/include/std/system_error
+++ b/libstdc++-v3/include/std/system_error
@@ -216,6 +216,10 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
    */
   class error_code
   {
+    template<typename _ErrorCodeEnum>
+      using _Check
+	= __enable_if_t<is_error_code_enum<_ErrorCodeEnum>::value>;
+
   public:
     error_code() noexcept
     : _M_value(0), _M_cat(&system_category()) { }
@@ -223,11 +227,15 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
     error_code(int __v, const error_category& __cat) noexcept
     : _M_value(__v), _M_cat(&__cat) { }
 
-    template<typename _ErrorCodeEnum, typename = typename
-	     enable_if<is_error_code_enum<_ErrorCodeEnum>::value>::type>
+    /// Initialize with a user-defined type, by calling make_error_code.
+    template<typename _ErrorCodeEnum,
+	     typename = _Check<_ErrorCodeEnum>>
       error_code(_ErrorCodeEnum __e) noexcept
       { *this = make_error_code(__e); }
 
+    error_code(const error_code&) = default;
+    error_code& operator=(const error_code&) = default;
+
     void
     assign(int __v, const error_category& __cat) noexcept
     {
@@ -239,13 +247,6 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
     clear() noexcept
     { assign(0, system_category()); }
 
-    // DR 804.
-    template<typename _ErrorCodeEnum>
-      typename enable_if<is_error_code_enum<_ErrorCodeEnum>::value,
-			 error_code&>::type
-      operator=(_ErrorCodeEnum __e) noexcept
-      { return *this = make_error_code(__e); }
-
     /// The error value.
     [[__nodiscard__]]
     int
@@ -345,6 +346,10 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
    */
   class error_condition
   {
+    template<typename _ErrorConditionEnum>
+      using _Check
+	= __enable_if_t<is_error_condition_enum<_ErrorConditionEnum>::value>;
+
   public:
     /// Initialize with a zero (no error) value and the generic category.
     error_condition() noexcept
@@ -354,11 +359,15 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
     error_condition(int __v, const error_category& __cat) noexcept
     : _M_value(__v), _M_cat(&__cat) { }
 
-    template<typename _ErrorConditionEnum, typename = typename
-	 enable_if<is_error_condition_enum<_ErrorConditionEnum>::value>::type>
+    /// Initialize with a user-defined type, by calling make_error_condition.
+    template<typename _ErrorConditionEnum,
+	     typename = _Check<_ErrorConditionEnum>>
       error_condition(_ErrorConditionEnum __e) noexcept
       { *this = make_error_condition(__e); }
 
+    error_condition(const error_condition&) = default;
+    error_condition& operator=(const error_condition&) = default;
+
     /// Set the value and category.
     void
     assign(int __v, const error_category& __cat) noexcept
@@ -367,13 +376,6 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
       _M_cat = &__cat;
     }
 
-    // DR 804.
-    template<typename _ErrorConditionEnum>
-      typename enable_if<is_error_condition_enum
-			 <_ErrorConditionEnum>::value, error_condition&>::type
-      operator=(_ErrorConditionEnum __e) noexcept
-      { return *this = make_error_condition(__e); }
-
     /// Reset the value and category to the default-constructed state.
     void
     clear() noexcept
diff --git a/libstdc++-v3/testsuite/19_diagnostics/error_code/cons/1.cc b/libstdc++-v3/testsuite/19_diagnostics/error_code/cons/1.cc
index f454fc270d8..d48d5c1ffe8 100644
--- a/libstdc++-v3/testsuite/19_diagnostics/error_code/cons/1.cc
+++ b/libstdc++-v3/testsuite/19_diagnostics/error_code/cons/1.cc
@@ -22,23 +22,46 @@
 #include <system_error>
 #include <testsuite_error.h>
 
+namespace adl
+{
+  struct Error { };
+
+  const Error err;
+
+  struct category : std::error_category
+  {
+    const char* name() const noexcept override { return "adl"; }
+    std::string message(int) const { return ""; }
+  };
+
+  const category cat;
+
+  std::error_code
+  make_error_code(Error) { return std::error_code(999, cat); }
+}
+
+template<> struct std::is_error_code_enum<adl::Error> : std::true_type { };
+
 int main()
 {
-  // 1
+  // 1 error_code()
   std::error_code e1;
   VERIFY( e1.value() == 0 );
   VERIFY( e1.category() == std::system_category() );
 
-  // 2
+  // 2 error_code(int, const error_category&)
   const __gnu_test::test_category cat;
   std::error_code e2(e1.value(), cat);
   VERIFY( e2.value() == e1.value() );
   VERIFY( e2.category() == cat );
 
-  // 3
+  // 3 error_code(const error_code&)
   std::error_code e3(std::make_error_code(std::errc::operation_not_supported));
   VERIFY( e3.value() == int(std::errc::operation_not_supported) );
   VERIFY( e3.category() == std::generic_category() );
 
-  return 0;
+  // 4 error_code(ErrorCodeEnum)
+  std::error_code e4(adl::err);
+  VERIFY( e4.value() == 999 );
+  VERIFY( e4.category() == adl::cat );
 }
diff --git a/libstdc++-v3/testsuite/19_diagnostics/error_condition/cons/1.cc b/libstdc++-v3/testsuite/19_diagnostics/error_condition/cons/1.cc
index 1e039c45b1d..c353b0266ee 100644
--- a/libstdc++-v3/testsuite/19_diagnostics/error_condition/cons/1.cc
+++ b/libstdc++-v3/testsuite/19_diagnostics/error_condition/cons/1.cc
@@ -21,23 +21,48 @@
 #include <system_error>
 #include <testsuite_error.h>
 
+namespace adl
+{
+  struct Error { };
+
+  const Error err;
+
+  struct category : std::error_category
+  {
+    const char* name() const noexcept override { return "adl"; }
+    std::string message(int) const { return ""; }
+  };
+
+  const category cat;
+
+  std::error_condition
+  make_error_condition(Error) { return std::error_condition(999, cat); }
+}
+
+template<> struct std::is_error_condition_enum<adl::Error> : std::true_type { };
+
 void test01()
 {
-  // 1
+  // 1 error_condition()
   std::error_condition e1;
   VERIFY( e1.value() == 0 );
   VERIFY( e1.category() == std::generic_category() );
 
-  // 2
+  // 2 error_condition(int, const error_category&)
   const __gnu_test::test_category cat;
   std::error_condition e2(e1.value(), cat);
   VERIFY( e2.value() == e1.value() );
   VERIFY( e2.category() == cat );
 
-  // 3
+  // 3 error_condition(const error_condition&)
   std::error_condition e3(std::errc::operation_not_supported);
   VERIFY( e3.value() == int(std::errc::operation_not_supported) );
   VERIFY( e3.category() == std::generic_category() );
+
+  // 4 error_condition(ErrorConditionEnum)
+  std::error_condition e4(adl::err);
+  VERIFY( e4.value() == 999 );
+  VERIFY( e4.category() == adl::cat );
 }
 
 int main()

                 reply	other threads:[~2022-08-26 15:20 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220826152041.95D573851AB5@sourceware.org \
    --to=redi@gcc.gnu.org \
    --cc=gcc-cvs@gcc.gnu.org \
    --cc=libstdc++-cvs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).