aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVille Voutilainen <ville.voutilainen@gmail.com>2017-10-30 16:31:04 +0200
committerVille Voutilainen <ville@gcc.gnu.org>2017-10-30 16:31:04 +0200
commitccbbf8df05abc41ef86565706976c5ad403291e7 (patch)
treed9ab403161f04d2276aeaef0e7aa163807d1e15a
parent198a8e3cc5176e9234343060fe95de4035d23ac3 (diff)
downloadgcc-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
-rw-r--r--libstdc++-v3/ChangeLog24
-rw-r--r--libstdc++-v3/include/debug/array8
-rw-r--r--libstdc++-v3/include/std/array8
-rw-r--r--libstdc++-v3/include/std/tuple16
-rw-r--r--libstdc++-v3/include/std/utility25
-rw-r--r--libstdc++-v3/testsuite/20_util/pair/astuple/get.cc5
-rw-r--r--libstdc++-v3/testsuite/20_util/pair/astuple/get_by_type.cc7
-rw-r--r--libstdc++-v3/testsuite/20_util/tuple/element_access/get2.cc15
-rw-r--r--libstdc++-v3/testsuite/20_util/tuple/element_access/get2_by_type.cc18
-rw-r--r--libstdc++-v3/testsuite/23_containers/array/tuple_interface/get.cc5
-rw-r--r--libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_debug_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc2
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 }