Message ID | 20180503115942.GA9687@redhat.com |
---|---|
State | New |
Headers | show |
Series | Define std::remove_cvref and std::remove_cvref_t for C++2a | expand |
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 --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)); }