diff mbox series

[committed,1/3] libstdc++ Simplify definition of net::socket_base constants

Message ID YILEYqgzz48mIuxg@redhat.com
State New
Headers show
Series [committed,1/3] libstdc++ Simplify definition of net::socket_base constants | expand

Commit Message

Jonathan Wakely April 23, 2021, 12:58 p.m. UTC
libstdc++-v3/ChangeLog:

	* include/experimental/socket (socket_base::shutdown_type):
	(socket_base::wait_type, socket_base::message_flags):
	Remove enumerators. Initialize constants directly with desired
	values.
	(socket_base::message_flags): Make all operators constexpr and
	noexcept.
	* testsuite/util/testsuite_common_types.h (test_bitmask_values):
	New test utility.
	* testsuite/experimental/net/socket/socket_base.cc: New test.

Tested powerpc64le-linux and sparc-solaris. Committed to trunk.
commit a752a43073dc49909c017fd52feacd7526ed31c0
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Fri Apr 23 13:25:56 2021

    libstdc++ Simplify definition of net::socket_base constants
    
    libstdc++-v3/ChangeLog:
    
            * include/experimental/socket (socket_base::shutdown_type):
            (socket_base::wait_type, socket_base::message_flags):
            Remove enumerators. Initialize constants directly with desired
            values.
            (socket_base::message_flags): Make all operators constexpr and
            noexcept.
            * testsuite/util/testsuite_common_types.h (test_bitmask_values):
            New test utility.
            * testsuite/experimental/net/socket/socket_base.cc: New test.

Comments

Jonathan Wakely April 26, 2021, 8:20 p.m. UTC | #1
On 23/04/21 13:58 +0100, Jonathan Wakely wrote:
>libstdc++-v3/ChangeLog:
>
>	* include/experimental/socket (socket_base::shutdown_type):
>	(socket_base::wait_type, socket_base::message_flags):
>	Remove enumerators. Initialize constants directly with desired
>	values.
>	(socket_base::message_flags): Make all operators constexpr and
>	noexcept.
>	* testsuite/util/testsuite_common_types.h (test_bitmask_values):
>	New test utility.
>	* testsuite/experimental/net/socket/socket_base.cc: New test.

And similarly for the constants in net::ip_resolver_base.

Tested powerpc64le-linux and powerpc-aix. Committed to trunk.
diff mbox series

Patch

diff --git a/libstdc++-v3/include/experimental/socket b/libstdc++-v3/include/experimental/socket
index a5a23ed3c06..ec4ed9d95e2 100644
--- a/libstdc++-v3/include/experimental/socket
+++ b/libstdc++-v3/include/experimental/socket
@@ -250,37 +250,29 @@  inline namespace v1
       static const int _S_name = SO_SNDLOWAT;
     };
 
-    enum shutdown_type : int
-    {
-      __shutdown_receive	= SHUT_RD,
-      __shutdown_send		= SHUT_WR,
-      __shutdown_both		= SHUT_RDWR
-    };
-    static constexpr shutdown_type shutdown_receive	= __shutdown_receive;
-    static constexpr shutdown_type shutdown_send	= __shutdown_send;
-    static constexpr shutdown_type shutdown_both	= __shutdown_both;
+    enum shutdown_type : int { };
+    static constexpr shutdown_type shutdown_receive = (shutdown_type)SHUT_RD;
+    static constexpr shutdown_type shutdown_send    = (shutdown_type)SHUT_WR;
+    static constexpr shutdown_type shutdown_both    = (shutdown_type)SHUT_RDWR;
 
+    enum wait_type : int { };
 #ifdef _GLIBCXX_HAVE_POLL_H
-    enum wait_type : int
-    {
-      __wait_read		= POLLIN,
-      __wait_write		= POLLOUT,
-      __wait_error		= POLLERR
-    };
-    static constexpr wait_type wait_read		= __wait_read;
-    static constexpr wait_type wait_write		= __wait_write;
-    static constexpr wait_type wait_error		= __wait_error;
+    static constexpr wait_type wait_read  = (wait_type)POLLIN;
+    static constexpr wait_type wait_write = (wait_type)POLLOUT;
+    static constexpr wait_type wait_error = (wait_type)POLLERR;
+#else
+    static constexpr wait_type wait_read  = (wait_type)1;
+    static constexpr wait_type wait_write = (wait_type)2;
+    static constexpr wait_type wait_error = (wait_type)4;
 #endif
 
-    enum message_flags : int
-    {
-      __message_peek		= MSG_PEEK,
-      __message_oob		= MSG_OOB,
-      __message_dontroute	= MSG_DONTROUTE
-    };
-    static constexpr message_flags message_peek		= __message_peek;
-    static constexpr message_flags message_out_of_band	= __message_oob;
-    static constexpr message_flags message_do_not_route	= __message_dontroute;
+    enum message_flags : int { };
+    static constexpr message_flags message_peek
+      = (message_flags)MSG_PEEK;
+    static constexpr message_flags message_out_of_band
+      = (message_flags)MSG_OOB;
+    static constexpr message_flags message_do_not_route
+      = (message_flags)MSG_DONTROUTE;
 
     static const int max_listen_connections = SOMAXCONN;
 #endif
@@ -350,30 +342,37 @@  inline namespace v1
 
   constexpr socket_base::message_flags
   operator&(socket_base::message_flags __f1, socket_base::message_flags __f2)
+    noexcept
   { return socket_base::message_flags( int(__f1) & int(__f2) ); }
 
   constexpr socket_base::message_flags
   operator|(socket_base::message_flags __f1, socket_base::message_flags __f2)
+    noexcept
   { return socket_base::message_flags( int(__f1) | int(__f2) ); }
 
   constexpr socket_base::message_flags
   operator^(socket_base::message_flags __f1, socket_base::message_flags __f2)
+    noexcept
   { return socket_base::message_flags( int(__f1) ^ int(__f2) ); }
 
   constexpr socket_base::message_flags
   operator~(socket_base::message_flags __f)
+    noexcept
   { return socket_base::message_flags( ~int(__f) ); }
 
-  inline socket_base::message_flags&
+  constexpr socket_base::message_flags&
   operator&=(socket_base::message_flags& __f1, socket_base::message_flags __f2)
+    noexcept
   { return __f1 = (__f1 & __f2); }
 
-  inline socket_base::message_flags&
+  constexpr socket_base::message_flags&
   operator|=(socket_base::message_flags& __f1, socket_base::message_flags __f2)
+    noexcept
   { return __f1 = (__f1 | __f2); }
 
-  inline socket_base::message_flags&
+  constexpr socket_base::message_flags&
   operator^=(socket_base::message_flags& __f1, socket_base::message_flags __f2)
+    noexcept
   { return __f1 = (__f1 ^ __f2); }
 
 #if _GLIBCXX_HAVE_UNISTD_H
diff --git a/libstdc++-v3/testsuite/experimental/net/socket/socket_base.cc b/libstdc++-v3/testsuite/experimental/net/socket/socket_base.cc
new file mode 100644
index 00000000000..b0b02b4e560
--- /dev/null
+++ b/libstdc++-v3/testsuite/experimental/net/socket/socket_base.cc
@@ -0,0 +1,45 @@ 
+// Copyright (C) 2020-2021 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do compile { target c++14 } }
+
+#include <experimental/socket>
+#include <testsuite_common_types.h>
+
+using S = std::experimental::net::socket_base;
+using namespace std;
+
+void test_constants()
+{
+  static_assert( is_enum<S::shutdown_type>::value, "" );
+  static_assert( S::shutdown_receive != S::shutdown_send, "" );
+  static_assert( S::shutdown_receive != S::shutdown_both, "" );
+  static_assert( S::shutdown_send != S::shutdown_both, "" );
+
+  static_assert( is_enum<S::wait_type>::value, "" );
+  static_assert( S::wait_read != S::wait_write, "");
+  static_assert( S::wait_read != S::wait_error, "");
+  static_assert( S::wait_write != S::wait_error, "");
+
+  static_assert( __gnu_test::test_bitmask_values(
+	{S::message_peek, S::message_out_of_band, S::message_do_not_route}
+	), "each bitmask element is distinct" );
+
+  auto m = &S::max_listen_connections;
+  static_assert( is_same<decltype(m), const int*>::value, "" );
+}
+
diff --git a/libstdc++-v3/testsuite/util/testsuite_common_types.h b/libstdc++-v3/testsuite/util/testsuite_common_types.h
index a87aa0f8f9a..a9a44df9664 100644
--- a/libstdc++-v3/testsuite/util/testsuite_common_types.h
+++ b/libstdc++-v3/testsuite/util/testsuite_common_types.h
@@ -952,5 +952,104 @@  namespace __gnu_test
       }
   };
 #endif
+
+#if __cplusplus >= 201402L
+  // Check that bitmask type T supports all the required operators,
+  // with the required semantics. Check that each bitmask element
+  // has a distinct, nonzero value, and that each bitmask constant
+  // has no bits set which do not correspond to a bitmask element.
+  template<typename T>
+    constexpr bool
+    test_bitmask_values(std::initializer_list<T> elements,
+			std::initializer_list<T> constants = {})
+    {
+      const T t0{};
+
+      if (!(t0 == t0))
+	return false;
+      if (t0 != t0)
+	return false;
+
+      if (t0 & t0)
+	return false;
+      if (t0 | t0)
+	return false;
+      if (t0 ^ t0)
+	return false;
+
+      T all = t0;
+
+      for (auto t : elements)
+	{
+	  // Each bitmask element has a distinct value.
+	  if (t & all)
+	    return false;
+
+	  // Each bitmask element has a nonzero value.
+	  if (!bool(t))
+	    return false;
+
+	  // Check operators
+
+	  if (!(t == t))
+	    return false;
+	  if (t != t)
+	    return false;
+	  if (t == t0)
+	    return false;
+	  if (t == all)
+	    return false;
+
+	  if (t & t0)
+	    return false;
+	  if ((t | t0) != t)
+	    return false;
+	  if ((t ^ t0) != t)
+	    return false;
+
+	  if ((t & t) != t)
+	    return false;
+	  if ((t | t) != t)
+	    return false;
+	  if (t ^ t)
+	    return false;
+
+	  T t1 = t;
+	  if ((t1 &= t) != t)
+	    return false;
+	  if ((t1 |= t) != t)
+	    return false;
+	  if (t1 ^= t)
+	    return false;
+
+	  t1 = all;
+	  if ((t1 &= t) != (all & t))
+	    return false;
+	  t1 = all;
+	  if ((t1 |= t) != (all | t))
+	    return false;
+	  t1 = all;
+	  if ((t1 ^= t) != (all ^ t))
+	    return false;
+
+	  all |= t;
+	  if (!(all & t))
+	    return false;
+	}
+
+      for (auto t : constants)
+	{
+	  // Check that bitmask constants are composed of the bitmask elements.
+	  if ((t & all) != t)
+	    return false;
+	  if ((t | all) != all)
+	    return false;
+	}
+
+      return true;
+    }
+#endif // C++14
+
+
 } // namespace __gnu_test
 #endif