[libcxx] Re-implement LWG 2770 again: Fix tuple_size to work with structured bindings
Summary: This patch attempts to re-implement a fix for LWG 2770, but not the actual specified PR. The PR for 2770 specifies tuple_size<T const> as only conditionally providing a `::value` member. However C++17 structured bindings require `tuple_size<T const>` to be complete only if `tuple_size<T>` is also complete. Therefore this patch implements only provides the specialization `tuple_size<T CV>` iff `tuple_size<T>` is a complete type. This fixes http://llvm.org/PR31513. Reviewers: mclow.lists, rsmith, mpark Subscribers: mpark, cfe-commits Differential Revision: https://reviews.llvm.org/D28222 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@291019 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -24,30 +24,35 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Tp> class _LIBCPP_TYPE_VIS_ONLY tuple_size;
|
||||
|
||||
struct __empty_tuple_size_base {};
|
||||
|
||||
template <class _Tp, class = void>
|
||||
struct __tuple_size_base_type {
|
||||
typedef __empty_tuple_size_base type;
|
||||
};
|
||||
#if !defined(_LIBCPP_CXX03_LANG)
|
||||
template <class _Tp, class...>
|
||||
using __enable_if_tuple_size_imp = _Tp;
|
||||
|
||||
template <class _Tp>
|
||||
struct __tuple_size_base_type<_Tp, typename __void_t<decltype(tuple_size<_Tp>::value)>::type>
|
||||
{
|
||||
typedef integral_constant<size_t, tuple_size<_Tp>::value> type;
|
||||
};
|
||||
class _LIBCPP_TYPE_VIS_ONLY tuple_size<__enable_if_tuple_size_imp<
|
||||
const _Tp,
|
||||
typename enable_if<!is_volatile<_Tp>::value>::type,
|
||||
integral_constant<size_t, sizeof(tuple_size<_Tp>)>>>
|
||||
: public integral_constant<size_t, tuple_size<_Tp>::value> {};
|
||||
|
||||
template <class _Tp>
|
||||
class _LIBCPP_TYPE_VIS_ONLY tuple_size<const _Tp>
|
||||
: public __tuple_size_base_type<_Tp>::type {};
|
||||
class _LIBCPP_TYPE_VIS_ONLY tuple_size<__enable_if_tuple_size_imp<
|
||||
volatile _Tp,
|
||||
typename enable_if<!is_const<_Tp>::value>::type,
|
||||
integral_constant<size_t, sizeof(tuple_size<_Tp>)>>>
|
||||
: public integral_constant<size_t, tuple_size<_Tp>::value> {};
|
||||
|
||||
template <class _Tp>
|
||||
class _LIBCPP_TYPE_VIS_ONLY tuple_size<volatile _Tp>
|
||||
: public __tuple_size_base_type<_Tp>::type {};
|
||||
class _LIBCPP_TYPE_VIS_ONLY tuple_size<__enable_if_tuple_size_imp<
|
||||
const volatile _Tp,
|
||||
integral_constant<size_t, sizeof(tuple_size<_Tp>)>>>
|
||||
: public integral_constant<size_t, tuple_size<_Tp>::value> {};
|
||||
|
||||
template <class _Tp>
|
||||
class _LIBCPP_TYPE_VIS_ONLY tuple_size<const volatile _Tp>
|
||||
: public __tuple_size_base_type<_Tp>::type {};
|
||||
#else
|
||||
template <class _Tp> class _LIBCPP_TYPE_VIS_ONLY tuple_size<const _Tp> : tuple_size<_Tp> {};
|
||||
template <class _Tp> class _LIBCPP_TYPE_VIS_ONLY tuple_size<volatile _Tp> : tuple_size<_Tp> {};
|
||||
template <class _Tp> class _LIBCPP_TYPE_VIS_ONLY tuple_size<const volatile _Tp> : tuple_size<_Tp> {};
|
||||
#endif
|
||||
|
||||
template <size_t _Ip, class _Tp> class _LIBCPP_TYPE_VIS_ONLY tuple_element;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user