diff options
| author | Eric Fiselier <eric@efcs.ca> | 2017-01-04 22:38:46 +0000 |
|---|---|---|
| committer | Eric Fiselier <eric@efcs.ca> | 2017-01-04 22:38:46 +0000 |
| commit | cb0d4df97490ec2d2b1cdf7574d26b1bc4063599 (patch) | |
| tree | fd4068a1365b0db24e75a05549721732569b05ee /libcxx/include/__tuple | |
| parent | b44f0bfb3a14fa757f49cba64cf452a2eee969b9 (diff) | |
| download | bcm5719-llvm-cb0d4df97490ec2d2b1cdf7574d26b1bc4063599.tar.gz bcm5719-llvm-cb0d4df97490ec2d2b1cdf7574d26b1bc4063599.zip | |
[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
llvm-svn: 291019
Diffstat (limited to 'libcxx/include/__tuple')
| -rw-r--r-- | libcxx/include/__tuple | 39 |
1 files changed, 22 insertions, 17 deletions
diff --git a/libcxx/include/__tuple b/libcxx/include/__tuple index 7aad0816366..ce45db380c6 100644 --- a/libcxx/include/__tuple +++ b/libcxx/include/__tuple @@ -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; |

