summaryrefslogtreecommitdiffstats
path: root/libcxx/include/__tuple
diff options
context:
space:
mode:
authorEric Fiselier <eric@efcs.ca>2017-01-04 22:38:46 +0000
committerEric Fiselier <eric@efcs.ca>2017-01-04 22:38:46 +0000
commitcb0d4df97490ec2d2b1cdf7574d26b1bc4063599 (patch)
treefd4068a1365b0db24e75a05549721732569b05ee /libcxx/include/__tuple
parentb44f0bfb3a14fa757f49cba64cf452a2eee969b9 (diff)
downloadbcm5719-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/__tuple39
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;
OpenPOWER on IntegriCloud