Commit ccbbf8df by Ville Voutilainen Committed by Ville Voutilainen

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
parent 198a8e3c
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> 2017-10-27 Jonathan Wakely <jwakely@redhat.com>
* include/bits/node_handle.h (_Node_insert_return::get): Avoid * include/bits/node_handle.h (_Node_insert_return::get): Avoid
......
...@@ -306,6 +306,14 @@ namespace __debug ...@@ -306,6 +306,14 @@ namespace __debug
return _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>:: return _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>::
_S_ref(__arr._M_elems, _Int); _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 } // namespace __debug
_GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_BEGIN_NAMESPACE_VERSION
......
...@@ -328,6 +328,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER ...@@ -328,6 +328,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
_S_ref(__arr._M_elems, _Int); _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 _GLIBCXX_END_NAMESPACE_CONTAINER
} // namespace std } // namespace std
......
...@@ -1329,6 +1329,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -1329,6 +1329,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return std::forward<__element_type&&>(std::get<__i>(__t)); 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 #if __cplusplus > 201103L
#define __cpp_lib_tuples_by_type 201304 #define __cpp_lib_tuples_by_type 201304
...@@ -1360,6 +1369,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -1360,6 +1369,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
constexpr const _Tp& constexpr const _Tp&
get(const tuple<_Types...>& __t) noexcept get(const tuple<_Types...>& __t) noexcept
{ return std::__get_helper2<_Tp>(__t); } { 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 #endif
// This class performs the comparison operations on tuples // This class performs the comparison operations on tuples
......
...@@ -184,6 +184,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -184,6 +184,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
static constexpr const _Tp1& static constexpr const _Tp1&
__const_get(const std::pair<_Tp1, _Tp2>& __pair) noexcept __const_get(const std::pair<_Tp1, _Tp2>& __pair) noexcept
{ return __pair.first; } { 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<> template<>
...@@ -203,6 +208,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -203,6 +208,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
static constexpr const _Tp2& static constexpr const _Tp2&
__const_get(const std::pair<_Tp1, _Tp2>& __pair) noexcept __const_get(const std::pair<_Tp1, _Tp2>& __pair) noexcept
{ return __pair.second; } { 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> template<std::size_t _Int, class _Tp1, class _Tp2>
...@@ -220,6 +230,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -220,6 +230,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
get(const std::pair<_Tp1, _Tp2>& __in) noexcept get(const std::pair<_Tp1, _Tp2>& __in) noexcept
{ return __pair_get<_Int>::__const_get(__in); } { 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 #if __cplusplus > 201103L
#define __cpp_lib_tuples_by_type 201304 #define __cpp_lib_tuples_by_type 201304
...@@ -240,6 +255,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -240,6 +255,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return std::move(__p.first); } { return std::move(__p.first); }
template <typename _Tp, typename _Up> 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& constexpr _Tp&
get(pair<_Up, _Tp>& __p) noexcept get(pair<_Up, _Tp>& __p) noexcept
{ return __p.second; } { return __p.second; }
...@@ -254,6 +274,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -254,6 +274,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
get(pair<_Up, _Tp>&& __p) noexcept get(pair<_Up, _Tp>&& __p) noexcept
{ return std::move(__p.second); } { 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 #define __cpp_lib_exchange_function 201304
/// Assign @p __new_val to @p __obj and return its previous value. /// Assign @p __new_val to @p __obj and return its previous value.
......
...@@ -27,4 +27,9 @@ void test01() ...@@ -27,4 +27,9 @@ void test01()
float&& pfirst __attribute__((unused)) = std::get<0>(std::move(p)); float&& pfirst __attribute__((unused)) = std::get<0>(std::move(p));
int&& psecond __attribute__((unused)) = std::get<1>(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));
} }
...@@ -25,4 +25,11 @@ void test01() ...@@ -25,4 +25,11 @@ void test01()
float&& pfirst __attribute__((unused)) = std::get<float>(std::move(p)); float&& pfirst __attribute__((unused)) = std::get<float>(std::move(p));
int&& psecond __attribute__((unused)) = std::get<int>(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));
} }
...@@ -37,4 +37,19 @@ void test01() ...@@ -37,4 +37,19 @@ void test01()
short&& t3one __attribute__((unused)) = std::get<0>(std::move(t3)); short&& t3one __attribute__((unused)) = std::get<0>(std::move(t3));
int&& t3two __attribute__((unused)) = std::get<1>(std::move(t3)); int&& t3two __attribute__((unused)) = std::get<1>(std::move(t3));
double&& t3thr __attribute__((unused)) = std::get<2>(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));
} }
...@@ -35,4 +35,22 @@ void test01() ...@@ -35,4 +35,22 @@ void test01()
short&& t3one __attribute__((unused)) = std::get<short>(std::move(t3)); short&& t3one __attribute__((unused)) = std::get<short>(std::move(t3));
int&& t3two __attribute__((unused)) = std::get<int>(std::move(t3)); int&& t3two __attribute__((unused)) = std::get<int>(std::move(t3));
double&& t3thr __attribute__((unused)) = std::get<double>(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));
} }
...@@ -27,4 +27,9 @@ void test01() ...@@ -27,4 +27,9 @@ void test01()
int&& aone __attribute__((unused)) = std::get<0>(std::move(a)); int&& aone __attribute__((unused)) = std::get<0>(std::move(a));
int&& atwo __attribute__((unused)) = std::get<1>(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));
} }
...@@ -22,4 +22,4 @@ ...@@ -22,4 +22,4 @@
typedef std::tuple_element<1, std::array<int, 1>>::type type; 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 }
...@@ -22,4 +22,4 @@ ...@@ -22,4 +22,4 @@
typedef std::tuple_element<1, std::array<int, 1>>::type type; 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 }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment