diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2017-05-12 15:43:11 +0100 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2017-05-12 15:43:11 +0100 |
commit | f859f912e4df1a6dad3ab6f61e8b8ce0dd77e16d (patch) | |
tree | 3b942f21fa3f0a2e06f599a1823b14fb74877d8f | |
parent | 48ac9454faa6494df3a8bd1bacf4c924b1e848dc (diff) | |
download | gcc-f859f912e4df1a6dad3ab6f61e8b8ce0dd77e16d.zip gcc-f859f912e4df1a6dad3ab6f61e8b8ce0dd77e16d.tar.gz gcc-f859f912e4df1a6dad3ab6f61e8b8ce0dd77e16d.tar.bz2 |
PR libstdc++/78939 make tuple_size<cv T> depend on tuple_size<T>
PR libstdc++/78939
* include/std/utility (tuple_size<cv T>): Only define partial
specializations when tuple_size<T>::value is valid.
* testsuite/20_util/tuple/78939.cc: New.
* testsuite/20_util/tuple/cv_tuple_size_neg.cc: New.
From-SVN: r247973
-rw-r--r-- | libstdc++-v3/ChangeLog | 8 | ||||
-rw-r--r-- | libstdc++-v3/include/std/utility | 22 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/tuple/78939.cc | 49 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/tuple/cv_tuple_size_neg.cc | 35 |
4 files changed, 104 insertions, 10 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 1aea9ca..afe7a54 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,11 @@ +2017-05-12 Jonathan Wakely <jwakely@redhat.com> + + PR libstdc++/78939 + * include/std/utility (tuple_size<cv T>): Only define partial + specializations when tuple_size<T>::value is valid. + * testsuite/20_util/tuple/78939.cc: New. + * testsuite/20_util/tuple/cv_tuple_size_neg.cc: New. + 2017-05-11 François Dumont <fdumont@gcc.gnu.org> * include/bits/stl_tree.h [_GLIBCXX_INLINE_VERSION] diff --git a/libstdc++-v3/include/std/utility b/libstdc++-v3/include/std/utility index 188fcc2..c18bcb6 100644 --- a/libstdc++-v3/include/std/utility +++ b/libstdc++-v3/include/std/utility @@ -88,24 +88,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct tuple_size; // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2313. tuple_size should always derive from integral_constant<size_t, N> // 2770. tuple_size<const T> specialization is not SFINAE compatible - template<typename _Tp, typename = void> - struct __tuple_size_cv_impl { }; - template<typename _Tp> - struct __tuple_size_cv_impl<_Tp, __void_t<decltype(tuple_size<_Tp>::value)>> - : integral_constant<size_t, tuple_size<_Tp>::value> { }; + template<typename _Tp, + typename _Up = typename remove_cv<_Tp>::type, + typename = typename enable_if<is_same<_Tp, _Up>::value>::type, + size_t = tuple_size<_Tp>::value> + using __enable_if_has_tuple_size = _Tp; - // _GLIBCXX_RESOLVE_LIB_DEFECTS - // 2313. tuple_size should always derive from integral_constant<size_t, N> template<typename _Tp> - struct tuple_size<const _Tp> : __tuple_size_cv_impl<_Tp> { }; + struct tuple_size<const __enable_if_has_tuple_size<_Tp>> + : public tuple_size<_Tp> { }; template<typename _Tp> - struct tuple_size<volatile _Tp> : __tuple_size_cv_impl<_Tp> { }; + struct tuple_size<volatile __enable_if_has_tuple_size<_Tp>> + : public tuple_size<_Tp> { }; template<typename _Tp> - struct tuple_size<const volatile _Tp> : __tuple_size_cv_impl<_Tp> { }; + struct tuple_size<const volatile __enable_if_has_tuple_size<_Tp>> + : public tuple_size<_Tp> { }; /// Gives the type of the ith element of a given tuple type. template<std::size_t __i, typename _Tp> diff --git a/libstdc++-v3/testsuite/20_util/tuple/78939.cc b/libstdc++-v3/testsuite/20_util/tuple/78939.cc new file mode 100644 index 0000000..bab143b --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/tuple/78939.cc @@ -0,0 +1,49 @@ +// Copyright (C) 2017 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-options "-std=gnu++17" } +// { dg-do compile { target c++1z } } + +// PR libstdc++/78939 + +#include <utility> + +struct A { int i, j; }; + +int +test01() +{ + A a{}; + const auto [i, j] = a; + return i + j; +} + +int +test02() +{ + A a{}; + volatile auto [i, j] = a; + return i + j; +} + +int +test03() +{ + A a{}; + const volatile auto [i, j] = a; + return i + j; +} diff --git a/libstdc++-v3/testsuite/20_util/tuple/cv_tuple_size_neg.cc b/libstdc++-v3/testsuite/20_util/tuple/cv_tuple_size_neg.cc new file mode 100644 index 0000000..450ed89 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/tuple/cv_tuple_size_neg.cc @@ -0,0 +1,35 @@ +// Copyright (C) 2017 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++11 } } + +#include <tuple> + +// PR libstdc++/78939 + +std::tuple_size<const int> ic; // { dg-error "incomplete" } +std::tuple_size<volatile int> iv; // { dg-error "incomplete" } +std::tuple_size<const volatile int> icv; // { dg-error "incomplete" } + +struct A { }; +std::tuple_size<const A> ac; // { dg-error "incomplete" } +std::tuple_size<volatile A> av; // { dg-error "incomplete" } +std::tuple_size<const volatile A> acv; // { dg-error "incomplete" } + +std::tuple_size<const void> vc; // { dg-error "incomplete" } +std::tuple_size<volatile void> vv; // { dg-error "incomplete" } +std::tuple_size<const volatile void> vcv; // { dg-error "incomplete" } |