diff options
author | Ville Voutilainen <ville.voutilainen@gmail.com> | 2017-10-30 16:31:04 +0200 |
---|---|---|
committer | Ville Voutilainen <ville@gcc.gnu.org> | 2017-10-30 16:31:04 +0200 |
commit | ccbbf8df05abc41ef86565706976c5ad403291e7 (patch) | |
tree | d9ab403161f04d2276aeaef0e7aa163807d1e15a | |
parent | 198a8e3cc5176e9234343060fe95de4035d23ac3 (diff) | |
download | gcc-ccbbf8df05abc41ef86565706976c5ad403291e7.zip gcc-ccbbf8df05abc41ef86565706976c5ad403291e7.tar.gz gcc-ccbbf8df05abc41ef86565706976c5ad403291e7.tar.bz2 |
Implement LWG 2485
* include/debug/array (get(const array<_Tp, _Nm>&&)): New.
* include/std/array (get(const array<_Tp, _Nm>&&)): Likewise.
* include/std/tuple (get(const tuple<_Elements...>&&)): Likewise.
(get(const tuple<_Types...>&&)): Likewise.
* include/std/utility
(__pair_get::__const_move_get(const std::pair<_Tp1, _Tp2>&&)):
Likewise.
(get(const std::pair<_Tp1, _Tp2>&&)): Likewise.
(get(const pair<_Tp, _Up>&&)): Likewise.
(get(const pair<_Up, _Tp>&&)): Likewise.
* testsuite/20_util/pair/astuple/get.cc: Add tests for
new overloads.
* testsuite/20_util/pair/astuple/get_by_type.cc: Likewise.
* testsuite/20_util/tuple/element_access/get2.cc: Likewise.
* testsuite/20_util/tuple/element_access/get2_by_type.cc: Likewise.
* testsuite/23_containers/array/tuple_interface/get.cc: Likewise.
* testsuite/23_containers/array/tuple_interface/tuple_element_debug_neg.cc:
Adjust.
* testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc:
Likewise.
From-SVN: r254222
12 files changed, 133 insertions, 2 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 796e32c..994eca8 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,27 @@ +2017-10-30 Ville Voutilainen <ville.voutilainen@gmail.com> + + Implement LWG 2485 + * include/debug/array (get(const array<_Tp, _Nm>&&)): New. + * include/std/array (get(const array<_Tp, _Nm>&&)): Likewise. + * include/std/tuple (get(const tuple<_Elements...>&&)): Likewise. + (get(const tuple<_Types...>&&)): Likewise. + * include/std/utility + (__pair_get::__const_move_get(const std::pair<_Tp1, _Tp2>&&)): + Likewise. + (get(const std::pair<_Tp1, _Tp2>&&)): Likewise. + (get(const pair<_Tp, _Up>&&)): Likewise. + (get(const pair<_Up, _Tp>&&)): Likewise. + * testsuite/20_util/pair/astuple/get.cc: Add tests for + new overloads. + * testsuite/20_util/pair/astuple/get_by_type.cc: Likewise. + * testsuite/20_util/tuple/element_access/get2.cc: Likewise. + * testsuite/20_util/tuple/element_access/get2_by_type.cc: Likewise. + * testsuite/23_containers/array/tuple_interface/get.cc: Likewise. + * testsuite/23_containers/array/tuple_interface/tuple_element_debug_neg.cc: + Adjust. + * testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc: + Likewise. + 2017-10-27 Jonathan Wakely <jwakely@redhat.com> * include/bits/node_handle.h (_Node_insert_return::get): Avoid diff --git a/libstdc++-v3/include/debug/array b/libstdc++-v3/include/debug/array index 9c27922..95edc84 100644 --- a/libstdc++-v3/include/debug/array +++ b/libstdc++-v3/include/debug/array @@ -306,6 +306,14 @@ namespace __debug return _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>:: _S_ref(__arr._M_elems, _Int); } + + template<std::size_t _Int, typename _Tp, std::size_t _Nm> + constexpr const _Tp&& + get(const array<_Tp, _Nm>&& __arr) noexcept + { + static_assert(_Int < _Nm, "index is out of bounds"); + return std::move(__debug::get<_Int>(__arr)); + } } // namespace __debug _GLIBCXX_BEGIN_NAMESPACE_VERSION diff --git a/libstdc++-v3/include/std/array b/libstdc++-v3/include/std/array index f058c06..01f7100 100644 --- a/libstdc++-v3/include/std/array +++ b/libstdc++-v3/include/std/array @@ -328,6 +328,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _S_ref(__arr._M_elems, _Int); } + template<std::size_t _Int, typename _Tp, std::size_t _Nm> + constexpr const _Tp&& + get(const array<_Tp, _Nm>&& __arr) noexcept + { + static_assert(_Int < _Nm, "array index is within bounds"); + return std::move(_GLIBCXX_STD_C::get<_Int>(__arr)); + } + _GLIBCXX_END_NAMESPACE_CONTAINER } // namespace std diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple index 1f5365a..ac03c9e 100644 --- a/libstdc++-v3/include/std/tuple +++ b/libstdc++-v3/include/std/tuple @@ -1329,6 +1329,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return std::forward<__element_type&&>(std::get<__i>(__t)); } + /// Return a const rvalue reference to the ith element of a const tuple rvalue. + template<std::size_t __i, typename... _Elements> + constexpr const __tuple_element_t<__i, tuple<_Elements...>>&& + get(const tuple<_Elements...>&& __t) noexcept + { + typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type; + return std::forward<const __element_type&&>(std::get<__i>(__t)); + } + #if __cplusplus > 201103L #define __cpp_lib_tuples_by_type 201304 @@ -1360,6 +1369,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr const _Tp& get(const tuple<_Types...>& __t) noexcept { return std::__get_helper2<_Tp>(__t); } + + /// Return a const reference to the unique element of type _Tp of + /// a const tuple rvalue. + template <typename _Tp, typename... _Types> + constexpr const _Tp&& + get(const tuple<_Types...>&& __t) noexcept + { return std::forward<const _Tp&&>(std::__get_helper2<_Tp>(__t)); } #endif // This class performs the comparison operations on tuples diff --git a/libstdc++-v3/include/std/utility b/libstdc++-v3/include/std/utility index 29a6260..e738632 100644 --- a/libstdc++-v3/include/std/utility +++ b/libstdc++-v3/include/std/utility @@ -184,6 +184,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION static constexpr const _Tp1& __const_get(const std::pair<_Tp1, _Tp2>& __pair) noexcept { return __pair.first; } + + template<typename _Tp1, typename _Tp2> + static constexpr const _Tp1&& + __const_move_get(const std::pair<_Tp1, _Tp2>&& __pair) noexcept + { return std::forward<const _Tp1>(__pair.first); } }; template<> @@ -203,6 +208,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION static constexpr const _Tp2& __const_get(const std::pair<_Tp1, _Tp2>& __pair) noexcept { return __pair.second; } + + template<typename _Tp1, typename _Tp2> + static constexpr const _Tp2&& + __const_move_get(const std::pair<_Tp1, _Tp2>&& __pair) noexcept + { return std::forward<const _Tp2>(__pair.second); } }; template<std::size_t _Int, class _Tp1, class _Tp2> @@ -220,6 +230,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION get(const std::pair<_Tp1, _Tp2>& __in) noexcept { return __pair_get<_Int>::__const_get(__in); } + template<std::size_t _Int, class _Tp1, class _Tp2> + constexpr const typename tuple_element<_Int, std::pair<_Tp1, _Tp2>>::type&& + get(const std::pair<_Tp1, _Tp2>&& __in) noexcept + { return __pair_get<_Int>::__const_move_get(std::move(__in)); } + #if __cplusplus > 201103L #define __cpp_lib_tuples_by_type 201304 @@ -240,6 +255,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return std::move(__p.first); } template <typename _Tp, typename _Up> + constexpr const _Tp&& + get(const pair<_Tp, _Up>&& __p) noexcept + { return std::move(__p.first); } + + template <typename _Tp, typename _Up> constexpr _Tp& get(pair<_Up, _Tp>& __p) noexcept { return __p.second; } @@ -254,6 +274,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION get(pair<_Up, _Tp>&& __p) noexcept { return std::move(__p.second); } + template <typename _Tp, typename _Up> + constexpr const _Tp&& + get(const pair<_Up, _Tp>&& __p) noexcept + { return std::move(__p.second); } + #define __cpp_lib_exchange_function 201304 /// Assign @p __new_val to @p __obj and return its previous value. diff --git a/libstdc++-v3/testsuite/20_util/pair/astuple/get.cc b/libstdc++-v3/testsuite/20_util/pair/astuple/get.cc index 8093974..e81af3b 100644 --- a/libstdc++-v3/testsuite/20_util/pair/astuple/get.cc +++ b/libstdc++-v3/testsuite/20_util/pair/astuple/get.cc @@ -27,4 +27,9 @@ void test01() float&& pfirst __attribute__((unused)) = std::get<0>(std::move(p)); int&& psecond __attribute__((unused)) = std::get<1>(std::move(p)); + + const std::pair<float, int> cp; + + const float&& cpfirst __attribute__((unused)) = std::get<0>(std::move(cp)); + const int&& cpsecond __attribute__((unused)) = std::get<1>(std::move(cp)); } diff --git a/libstdc++-v3/testsuite/20_util/pair/astuple/get_by_type.cc b/libstdc++-v3/testsuite/20_util/pair/astuple/get_by_type.cc index 8d8bf0e..1e70fbc 100644 --- a/libstdc++-v3/testsuite/20_util/pair/astuple/get_by_type.cc +++ b/libstdc++-v3/testsuite/20_util/pair/astuple/get_by_type.cc @@ -25,4 +25,11 @@ void test01() float&& pfirst __attribute__((unused)) = std::get<float>(std::move(p)); int&& psecond __attribute__((unused)) = std::get<int>(std::move(p)); + + const std::pair<float, int> cp; + + const float&& cpfirst __attribute__((unused)) = + std::get<float>(std::move(cp)); + const int&& cpsecond __attribute__((unused)) = + std::get<int>(std::move(cp)); } diff --git a/libstdc++-v3/testsuite/20_util/tuple/element_access/get2.cc b/libstdc++-v3/testsuite/20_util/tuple/element_access/get2.cc index 14bdb0c..bc0f1bc 100644 --- a/libstdc++-v3/testsuite/20_util/tuple/element_access/get2.cc +++ b/libstdc++-v3/testsuite/20_util/tuple/element_access/get2.cc @@ -37,4 +37,19 @@ void test01() short&& t3one __attribute__((unused)) = std::get<0>(std::move(t3)); int&& t3two __attribute__((unused)) = std::get<1>(std::move(t3)); double&& t3thr __attribute__((unused)) = std::get<2>(std::move(t3)); + + const std::tuple<int> ct1; + + const int&& ct1one __attribute__((unused)) = std::get<0>(std::move(ct1)); + + const std::tuple<float, int> ct2; + + const float&& ct2one __attribute__((unused)) = std::get<0>(std::move(ct2)); + const int&& ct2two __attribute__((unused)) = std::get<1>(std::move(ct2)); + + const std::tuple<short, int, double> ct3; + + const short&& ct3one __attribute__((unused)) = std::get<0>(std::move(ct3)); + const int&& ct3two __attribute__((unused)) = std::get<1>(std::move(ct3)); + const double&& ct3thr __attribute__((unused)) = std::get<2>(std::move(ct3)); } diff --git a/libstdc++-v3/testsuite/20_util/tuple/element_access/get2_by_type.cc b/libstdc++-v3/testsuite/20_util/tuple/element_access/get2_by_type.cc index 337934d..cdc1030 100644 --- a/libstdc++-v3/testsuite/20_util/tuple/element_access/get2_by_type.cc +++ b/libstdc++-v3/testsuite/20_util/tuple/element_access/get2_by_type.cc @@ -35,4 +35,22 @@ void test01() short&& t3one __attribute__((unused)) = std::get<short>(std::move(t3)); int&& t3two __attribute__((unused)) = std::get<int>(std::move(t3)); double&& t3thr __attribute__((unused)) = std::get<double>(std::move(t3)); + + const std::tuple<int> ct1; + + const int&& ct1one __attribute__((unused)) = std::get<int>(std::move(ct1)); + + const std::tuple<float, int> ct2; + + const float&& ct2one __attribute__((unused)) = std::get<0>(std::move(ct2)); + const int&& ct2two __attribute__((unused)) = std::get<int>(std::move(ct2)); + + const std::tuple<short, int, double> ct3; + + const short&& ct3one __attribute__((unused)) = + std::get<short>(std::move(ct3)); + const int&& ct3two __attribute__((unused)) = + std::get<int>(std::move(ct3)); + const double&& ct3thr __attribute__((unused)) = + std::get<double>(std::move(ct3)); } diff --git a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get.cc b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get.cc index a8c403c..8bc0afb0 100644 --- a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get.cc +++ b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get.cc @@ -27,4 +27,9 @@ void test01() int&& aone __attribute__((unused)) = std::get<0>(std::move(a)); int&& atwo __attribute__((unused)) = std::get<1>(std::move(a)); + + const std::array<int, 2> ca{}; + + const int&& caone __attribute__((unused)) = std::get<0>(std::move(ca)); + const int&& catwo __attribute__((unused)) = std::get<1>(std::move(ca)); } diff --git a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_debug_neg.cc b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_debug_neg.cc index e433c6e..8e8ef0d 100644 --- a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_debug_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_debug_neg.cc @@ -22,4 +22,4 @@ typedef std::tuple_element<1, std::array<int, 1>>::type type; -// { dg-error "static assertion failed" "" { target *-*-* } 323 } +// { dg-error "static assertion failed" "" { target *-*-* } 331 } diff --git a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc index 493449a..4e8eb32 100644 --- a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc @@ -22,4 +22,4 @@ typedef std::tuple_element<1, std::array<int, 1>>::type type; -// { dg-error "static assertion failed" "" { target *-*-* } 357 } +// { dg-error "static assertion failed" "" { target *-*-* } 365 } |