On 15/05/14 11:38 +0100, Jonathan Wakely wrote:
On 15/05/14 07:36 +0200, Daniel Krügler wrote:
Looking at the definition of the new alias
__cv_tuple_size
you might want to apply LWG 2313
http://cplusplus.github.io/LWG/lwg-defects.html#2313
and simplify its definition even further.
I forgot about that. With that resolution the __cv_tuple_size alias
doesn't seem worth using, it's simple enough anyway. Thanks!
Tested x86_64-linux, committed to trunk.
Here's a simpler patch for the 4.9 branch, just fixing the bug and
implementing the DR, committed.
commit b6ae8cc2cd135241ae2a3bd539f9c87b7ad6fe87
Author: Jonathan Wakely <jwak...@redhat.com>
Date: Fri Jun 13 12:33:32 2014 +0100
* include/std/tuple (tuple_size<cv _Tp>): Implement LWG 2313.
(get<_Tp>(tuple<_Types...>&&)): Use forward instead of move.
* testsuite/20_util/tuple/element_access/get_by_type.cc: Test rvalues.
diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple
index 03d87d7..103c99e 100644
--- a/libstdc++-v3/include/std/tuple
+++ b/libstdc++-v3/include/std/tuple
@@ -719,23 +719,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Tp>
struct tuple_size;
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 2313. tuple_size should always derive from integral_constant<size_t, N>
template<typename _Tp>
struct tuple_size<const _Tp>
- : public integral_constant<
- typename remove_cv<decltype(tuple_size<_Tp>::value)>::type,
- tuple_size<_Tp>::value> { };
+ : public integral_constant<size_t, tuple_size<_Tp>::value> { };
template<typename _Tp>
struct tuple_size<volatile _Tp>
- : public integral_constant<
- typename remove_cv<decltype(tuple_size<_Tp>::value)>::type,
- tuple_size<_Tp>::value> { };
+ : public integral_constant<size_t, tuple_size<_Tp>::value> { };
template<typename _Tp>
struct tuple_size<const volatile _Tp>
- : public integral_constant<
- typename remove_cv<decltype(tuple_size<_Tp>::value)>::type,
- tuple_size<_Tp>::value> { };
+ : public integral_constant<size_t, tuple_size<_Tp>::value> { };
/// class tuple_size
template<typename... _Elements>
@@ -752,9 +748,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
{ return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
- // Return a reference (const reference, rvalue reference) to the ith element
- // of a tuple. Any const or non-const ref elements are returned with their
- // original type.
+ /// Return a reference to the ith element of a tuple.
template<std::size_t __i, typename... _Elements>
constexpr typename __add_ref<
typename tuple_element<__i, tuple<_Elements...>>::type
@@ -762,6 +756,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
get(tuple<_Elements...>& __t) noexcept
{ return std::__get_helper<__i>(__t); }
+ /// Return a const reference to the ith element of a const tuple.
template<std::size_t __i, typename... _Elements>
constexpr typename __add_c_ref<
typename tuple_element<__i, tuple<_Elements...>>::type
@@ -769,6 +764,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
get(const tuple<_Elements...>& __t) noexcept
{ return std::__get_helper<__i>(__t); }
+ /// Return an rvalue reference to the ith element of a tuple rvalue.
template<std::size_t __i, typename... _Elements>
constexpr typename __add_r_ref<
typename tuple_element<__i, tuple<_Elements...>>::type
@@ -788,22 +784,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__get_helper2(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
{ return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
+ /// Return a reference to the unique element of type _Tp of a tuple.
template <typename _Tp, typename... _Types>
constexpr _Tp&
get(tuple<_Types...>& __t) noexcept
{ return std::__get_helper2<_Tp>(__t); }
+ /// Return a reference to the unique element of type _Tp of a tuple rvalue.
template <typename _Tp, typename... _Types>
constexpr _Tp&&
get(tuple<_Types...>&& __t) noexcept
- { return std::move(std::__get_helper2<_Tp>(__t)); }
+ { return std::forward<_Tp&&>(std::__get_helper2<_Tp>(__t)); }
+ /// Return a const reference to the unique element of type _Tp of a tuple.
template <typename _Tp, typename... _Types>
constexpr const _Tp&
get(const tuple<_Types...>& __t) noexcept
{ return std::__get_helper2<_Tp>(__t); }
#endif
+
// This class helps construct the various comparison operations on tuples
template<std::size_t __check_equal_size, std::size_t __i, std::size_t __j,
typename _Tp, typename _Up>
diff --git a/libstdc++-v3/testsuite/20_util/tuple/element_access/get_by_type.cc b/libstdc++-v3/testsuite/20_util/tuple/element_access/get_by_type.cc
index 226e9e4..042f214 100644
--- a/libstdc++-v3/testsuite/20_util/tuple/element_access/get_by_type.cc
+++ b/libstdc++-v3/testsuite/20_util/tuple/element_access/get_by_type.cc
@@ -41,4 +41,8 @@ main()
get<1>(b)=5;
VERIFY(get<int>(b)==1 && get<int&>(b)==5 && get<const int&>(b)==2);
VERIFY(j==5);
+ // test rvalue overload:
+ VERIFY(get<int>(std::move(b))==1);
+ VERIFY(get<int&>(std::move(b))==5);
+ VERIFY(get<const int&>(std::move(b))==2);
}