diff mbox series

Define std::remove_cvref and std::remove_cvref_t for C++2a

Message ID 20180503115942.GA9687@redhat.com
State New
Headers show
Series Define std::remove_cvref and std::remove_cvref_t for C++2a | expand

Commit Message

Jonathan Wakely May 3, 2018, 11:59 a.m. UTC
Also define __remove_cvref_t for internal use before C++2a.

	* include/std/any (any_cast): Use __remove_cvref_t.
	* include/std/tuple (__make_tuple): Likewise.
	* include/std/type_traits (__remove_cvref_t): Define.
	(__result_of_memobj, __result_of_memfun): Use __remove_cvref_t.
	[__cplusplus > 201703L] (remove_cvref, remove_cvref_t): Define.
	* include/std/variant (__erased_hash): Use __remove_cvref_t.

Tested powerpc64le-linux, committed to trunk.
commit 03ac1d02135a920114e4f6241fbc85689400b867
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Thu May 3 12:22:59 2018 +0100

    Define std::remove_cvref and std::remove_cvref_t for C++2a
    
    Also define __remove_cvref_t for internal use before C++2a.
    
            * include/std/any (any_cast): Use __remove_cvref_t.
            * include/std/tuple (__make_tuple): Likewise.
            * include/std/type_traits (__remove_cvref_t): Define.
            (__result_of_memobj, __result_of_memfun): Use __remove_cvref_t.
            [__cplusplus > 201703L] (remove_cvref, remove_cvref_t): Define.
            * include/std/variant (__erased_hash): Use __remove_cvref_t.

Comments

Jonathan Wakely May 3, 2018, 5:01 p.m. UTC | #1
On 03/05/18 12:59 +0100, Jonathan Wakely wrote:
>Also define __remove_cvref_t for internal use before C++2a.
>
>	* include/std/any (any_cast): Use __remove_cvref_t.
>	* include/std/tuple (__make_tuple): Likewise.
>	* include/std/type_traits (__remove_cvref_t): Define.
>	(__result_of_memobj, __result_of_memfun): Use __remove_cvref_t.
>	[__cplusplus > 201703L] (remove_cvref, remove_cvref_t): Define.
>	* include/std/variant (__erased_hash): Use __remove_cvref_t.

I forgot to add the tests, here they are.

Tested powerpc64le-linux, committed to trunk.
commit d559efa0a4605f54e72ce016668921b57fc6438b
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Thu May 3 14:36:28 2018 +0100

    Add tests for std::remove_cvref
    
            * testsuite/20_util/remove_cvref/requirements/alias_decl.cc: New.
            * testsuite/20_util/remove_cvref/requirements/explicit_instantiation.cc:
            New.
            * testsuite/20_util/remove_cvref/value.cc: New.
            * testsuite/20_util/remove_cvref/value_ext.cc: New.

diff --git a/libstdc++-v3/testsuite/20_util/remove_cvref/requirements/alias_decl.cc b/libstdc++-v3/testsuite/20_util/remove_cvref/requirements/alias_decl.cc
new file mode 100644
index 00000000000..1b2f67f75f6
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/remove_cvref/requirements/alias_decl.cc
@@ -0,0 +1,37 @@
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+// Copyright (C) 2018 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/>.
+
+// NB: This file is for testing type_traits with NO OTHER INCLUDES.
+
+#include <type_traits>
+
+using namespace std;
+
+static_assert (is_same<typename remove_cvref<int>::type,
+	               remove_cvref_t<int>>(),
+               "remove_cvref_t" );
+
+static_assert (is_same<typename remove_cvref<const volatile long&>::type,
+                       remove_cvref_t<const volatile long&>>(),
+	       "remove_cvref_t" );
+
+static_assert (is_same<typename remove_cvref<const short&&>::type,
+                       remove_cvref_t<const short&&>>(),
+	       "remove_cvref_t" );
diff --git a/libstdc++-v3/testsuite/20_util/remove_cvref/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/20_util/remove_cvref/requirements/explicit_instantiation.cc
new file mode 100644
index 00000000000..5dac5c7e33b
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/remove_cvref/requirements/explicit_instantiation.cc
@@ -0,0 +1,29 @@
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+// Copyright (C) 2018 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/>.
+
+// NB: This file is for testing type_traits with NO OTHER INCLUDES.
+
+#include <type_traits>
+
+namespace std
+{
+  typedef short test_type;
+  template struct remove_cvref<test_type>;
+}
diff --git a/libstdc++-v3/testsuite/20_util/remove_cvref/value.cc b/libstdc++-v3/testsuite/20_util/remove_cvref/value.cc
new file mode 100644
index 00000000000..534464c4333
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/remove_cvref/value.cc
@@ -0,0 +1,50 @@
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+// Copyright (C) 2018 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/>.
+
+#include <type_traits>
+#include <testsuite_tr1.h>
+
+void test01()
+{
+  using std::remove_cvref;
+  using std::is_same;
+  using namespace __gnu_test;
+
+  static_assert(is_same<remove_cvref<const volatile int>::type,
+			int>::value, "");
+  static_assert(is_same<remove_cvref<const volatile int*>::type,
+			const volatile int*>::value, "");
+  static_assert(is_same<typename remove_cvref<const volatile int&>::type,
+			int>::value, "");
+  static_assert(is_same<typename remove_cvref<const volatile int&&>::type,
+			int>::value, "");
+  static_assert(is_same<remove_cvref<const volatile ClassType>::type,
+			ClassType>::value, "");
+  static_assert(is_same<remove_cvref<const volatile ClassType*>::type,
+			const volatile ClassType*>::value, "");
+  static_assert(is_same<typename remove_cvref<const volatile ClassType&>::type,
+			ClassType>::value, "");
+  static_assert(is_same<typename remove_cvref<const volatile ClassType&&>::type,
+			ClassType>::value, "");
+  static_assert(is_same<typename remove_cvref<const int(&)[3]>::type,
+			int[3]>::value, "");
+  static_assert(is_same<typename remove_cvref<const int(&)()>::type,
+			const int()>::value, "");
+}
diff --git a/libstdc++-v3/testsuite/20_util/remove_cvref/value_ext.cc b/libstdc++-v3/testsuite/20_util/remove_cvref/value_ext.cc
new file mode 100644
index 00000000000..9790b95dc91
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/remove_cvref/value_ext.cc
@@ -0,0 +1,49 @@
+// { dg-do compile { target c++11 } }
+
+// Copyright (C) 2018 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/>.
+
+#include <type_traits>
+#include <testsuite_tr1.h>
+
+void test01()
+{
+  using std::__remove_cvref_t;
+  using std::is_same;
+  using namespace __gnu_test;
+
+  static_assert(is_same<__remove_cvref_t<const volatile int>,
+			int>::value, "");
+  static_assert(is_same<__remove_cvref_t<const volatile int*>,
+			const volatile int*>::value, "");
+  static_assert(is_same<__remove_cvref_t<const volatile int&>,
+			int>::value, "");
+  static_assert(is_same<__remove_cvref_t<const volatile int&&>,
+			int>::value, "");
+  static_assert(is_same<__remove_cvref_t<const volatile ClassType>,
+			ClassType>::value, "");
+  static_assert(is_same<__remove_cvref_t<const volatile ClassType*>,
+			const volatile ClassType*>::value, "");
+  static_assert(is_same<__remove_cvref_t<const volatile ClassType&>,
+			ClassType>::value, "");
+  static_assert(is_same<__remove_cvref_t<const volatile ClassType&&>,
+			ClassType>::value, "");
+  static_assert(is_same<__remove_cvref_t<const int(&)[3]>,
+			int[3]>::value, "");
+  static_assert(is_same<__remove_cvref_t<const int(&)()>,
+			const int()>::value, "");
+}
diff mbox series

Patch

diff --git a/libstdc++-v3/include/std/any b/libstdc++-v3/include/std/any
index a37eb38d665..11b59d6d575 100644
--- a/libstdc++-v3/include/std/any
+++ b/libstdc++-v3/include/std/any
@@ -451,7 +451,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename _ValueType>
     inline _ValueType any_cast(const any& __any)
     {
-      using _Up = remove_cv_t<remove_reference_t<_ValueType>>;
+      using _Up = __remove_cvref_t<_ValueType>;
       static_assert(any::__is_valid_cast<_ValueType>(),
 	  "Template argument must be a reference or CopyConstructible type");
       static_assert(is_constructible_v<_ValueType, const _Up&>,
@@ -477,7 +477,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename _ValueType>
     inline _ValueType any_cast(any& __any)
     {
-      using _Up = remove_cv_t<remove_reference_t<_ValueType>>;
+      using _Up = __remove_cvref_t<_ValueType>;
       static_assert(any::__is_valid_cast<_ValueType>(),
 	  "Template argument must be a reference or CopyConstructible type");
       static_assert(is_constructible_v<_ValueType, _Up&>,
@@ -491,7 +491,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename _ValueType>
     inline _ValueType any_cast(any&& __any)
     {
-      using _Up = remove_cv_t<remove_reference_t<_ValueType>>;
+      using _Up = __remove_cvref_t<_ValueType>;
       static_assert(any::__is_valid_cast<_ValueType>(),
 	  "Template argument must be a reference or CopyConstructible type");
       static_assert(is_constructible_v<_ValueType, _Up>,
diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple
index 1d0074129b1..16f69220abb 100644
--- a/libstdc++-v3/include/std/tuple
+++ b/libstdc++-v3/include/std/tuple
@@ -1499,8 +1499,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // Returns the std::tuple equivalent of a tuple-like type.
   template<typename _Tuple>
     struct __make_tuple
-    : public __do_make_tuple<typename std::remove_cv
-            <typename std::remove_reference<_Tuple>::type>::type>
+    : public __do_make_tuple<__remove_cvref_t<_Tuple>>
     { };
 
   // Combines several std::tuple's into a single one.
diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index 711d6c50dd1..7c0ba727511 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -2092,6 +2092,11 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       return __declval<_Tp>(0);
     }
 
+  // __remove_cvref_t (std::remove_cvref_t for C++11).
+  template<typename _Tp>
+    using __remove_cvref_t
+     = typename remove_cv<typename remove_reference<_Tp>::type>::type;
+
   /// result_of
   template<typename _Signature>
     class result_of;
@@ -2193,8 +2198,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename _Res, typename _Class, typename _Arg>
     struct __result_of_memobj<_Res _Class::*, _Arg>
     {
-      typedef typename remove_cv<typename remove_reference<
-        _Arg>::type>::type _Argval;
+      typedef __remove_cvref_t<_Arg> _Argval;
       typedef _Res _Class::* _MemPtr;
       typedef typename conditional<__or_<is_same<_Argval, _Class>,
         is_base_of<_Class, _Argval>>::value,
@@ -2209,8 +2213,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename _Res, typename _Class, typename _Arg, typename... _Args>
     struct __result_of_memfun<_Res _Class::*, _Arg, _Args...>
     {
-      typedef typename remove_cv<typename remove_reference<
-        _Arg>::type>::type _Argval;
+      typedef __remove_cvref_t<_Arg> _Argval;
       typedef _Res _Class::* _MemPtr;
       typedef typename conditional<__or_<is_same<_Argval, _Class>,
         is_base_of<_Class, _Argval>>::value,
@@ -2399,8 +2402,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // Internal type trait that allows us to sfinae-protect tuple_cat.
   template<typename _Tp>
     struct __is_tuple_like
-    : public __is_tuple_like_impl<typename remove_cv<
-      typename remove_reference<_Tp>::type>::type>::type
+    : public __is_tuple_like_impl<__remove_cvref_t<_Tp>>::type
     { };
 
   template<typename _Tp>
@@ -2942,6 +2944,17 @@  template <typename _From, typename _To>
     big    = __ORDER_BIG_ENDIAN__,
     native = __BYTE_ORDER__
   };
+
+  /// Remove references and cv-qualifiers.
+  template<typename _Tp>
+    struct remove_cvref
+    {
+      using type = __remove_cvref_t<_Tp>;
+    };
+
+  template<typename _Tp>
+    using remove_cvref_t = __remove_cvref_t<_Tp>;
+
 #endif // C++2a
 
 _GLIBCXX_END_NAMESPACE_VERSION
diff --git a/libstdc++-v3/include/std/variant b/libstdc++-v3/include/std/variant
index 48bec528406..f64c037a514 100644
--- a/libstdc++-v3/include/std/variant
+++ b/libstdc++-v3/include/std/variant
@@ -289,7 +289,7 @@  namespace __variant
     size_t
     __erased_hash(void* __t)
     {
-      return std::hash<remove_cv_t<remove_reference_t<_Tp>>>{}(
+      return std::hash<__remove_cvref_t<_Tp>>{}(
 	  __variant::__ref_cast<_Tp>(__t));
     }