* 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
+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
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
_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
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
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
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<>
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>
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
get(pair<_Tp, _Up>&& __p) noexcept
{ 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
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.
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));
}
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));
}
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));
}
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));
}
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));
}
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 }
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 }