Hi mclow.lists, danalbert, K-ballo,
There is no reason to guard `tuple_size`, `tuple_element` and `get<I>(...)` for
pair and array inside of `<__tuple>` so that they are only available when we
have variadic templates.
This requires there be redundant declarations and definitions. It also makes it
easy to get things wrong.
For example the following code should compile (and does in c++11).
```
#define _LIBCPP_HAS_NO_VARIADICS
#include <array>
int main()
{
static_assert((std::tuple_size<std::array<int, 10> volatile>::value == 10),
"");
}
```
This patch lifts the non-variadic parts of `tuple_size`, `tuple_types`, and
`get<I>(...)` to the top of `<__tuple>` where they don't require variadic
templates. This patch also removes `<__tuple_03>` because there is no longer a
need for it.
http://reviews.llvm.org/D7774
Files:
include/__tuple
include/__tuple_03
include/array
include/utility
test/std/containers/sequences/array/array.tuple/tuple_element.pass.cpp
test/std/containers/sequences/array/array.tuple/tuple_size.pass.cpp
test/std/utilities/utility/pairs/pair.astuple/tuple_element.pass.cpp
test/std/utilities/utility/pairs/pair.astuple/tuple_size.pass.cpp
EMAIL PREFERENCES
http://reviews.llvm.org/settings/panel/emailpreferences/
Index: include/__tuple
===================================================================
--- include/__tuple
+++ include/__tuple
@@ -19,40 +19,9 @@
#pragma GCC system_header
#endif
-#ifdef _LIBCPP_HAS_NO_VARIADICS
-
-#include <__tuple_03>
-
-#else // _LIBCPP_HAS_NO_VARIADICS
_LIBCPP_BEGIN_NAMESPACE_STD
-// __lazy_and
-
-template <bool _Last, class ..._Preds>
-struct __lazy_and_impl;
-
-template <class ..._Preds>
-struct __lazy_and_impl<false, _Preds...> : false_type {};
-
-template <>
-struct __lazy_and_impl<true> : true_type {};
-
-template <class _Pred>
-struct __lazy_and_impl<true, _Pred> : integral_constant<bool, _Pred::type::value> {};
-
-template <class _Hp, class ..._Tp>
-struct __lazy_and_impl<true, _Hp, _Tp...> : __lazy_and_impl<_Hp::type::value, _Tp...> {};
-
-template <class _P1, class ..._Pr>
-struct __lazy_and : __lazy_and_impl<_P1::type::value, _Pr...> {};
-
-// __lazy_not
-
-template <class _Pred>
-struct __lazy_not : integral_constant<bool, !_Pred::type::value> {};
-
-
template <class _Tp> class _LIBCPP_TYPE_VIS_ONLY tuple_size;
template <class _Tp>
@@ -90,19 +59,18 @@
typedef typename add_cv<typename tuple_element<_Ip, _Tp>::type>::type type;
};
-template <class ..._Tp> class _LIBCPP_TYPE_VIS_ONLY tuple;
-template <class _T1, class _T2> struct _LIBCPP_TYPE_VIS_ONLY pair;
-template <class _Tp, size_t _Size> struct _LIBCPP_TYPE_VIS_ONLY array;
-
template <class _Tp> struct __tuple_like : false_type {};
template <class _Tp> struct __tuple_like<const _Tp> : public __tuple_like<_Tp> {};
template <class _Tp> struct __tuple_like<volatile _Tp> : public __tuple_like<_Tp> {};
template <class _Tp> struct __tuple_like<const volatile _Tp> : public __tuple_like<_Tp> {};
+// tuple specializations
+
+#if !defined(_LIBCPP_HAS_NO_VARIADICS)
+template <class ..._Tp> class _LIBCPP_TYPE_VIS_ONLY tuple;
+
template <class... _Tp> struct __tuple_like<tuple<_Tp...> > : true_type {};
-template <class _T1, class _T2> struct __tuple_like<pair<_T1, _T2> > : true_type {};
-template <class _Tp, size_t _Size> struct __tuple_like<array<_Tp, _Size> > : true_type {};
template <size_t _Ip, class ..._Tp>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
@@ -118,6 +86,13 @@
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
typename tuple_element<_Ip, tuple<_Tp...> >::type&&
get(tuple<_Tp...>&&) _NOEXCEPT;
+#endif
+
+// pair specializations
+
+template <class _T1, class _T2> struct _LIBCPP_TYPE_VIS_ONLY pair;
+
+template <class _T1, class _T2> struct __tuple_like<pair<_T1, _T2> > : true_type {};
template <size_t _Ip, class _T1, class _T2>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
@@ -129,10 +104,18 @@
const typename tuple_element<_Ip, pair<_T1, _T2> >::type&
get(const pair<_T1, _T2>&) _NOEXCEPT;
+#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
template <size_t _Ip, class _T1, class _T2>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
typename tuple_element<_Ip, pair<_T1, _T2> >::type&&
get(pair<_T1, _T2>&&) _NOEXCEPT;
+#endif
+
+// array specializations
+
+template <class _Tp, size_t _Size> struct _LIBCPP_TYPE_VIS_ONLY array;
+
+template <class _Tp, size_t _Size> struct __tuple_like<array<_Tp, _Size> > : true_type {};
template <size_t _Ip, class _Tp, size_t _Size>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
@@ -144,10 +127,39 @@
const _Tp&
get(const array<_Tp, _Size>&) _NOEXCEPT;
+#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
template <size_t _Ip, class _Tp, size_t _Size>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
_Tp&&
get(array<_Tp, _Size>&&) _NOEXCEPT;
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_VARIADICS)
+
+// __lazy_and
+
+template <bool _Last, class ..._Preds>
+struct __lazy_and_impl;
+
+template <class ..._Preds>
+struct __lazy_and_impl<false, _Preds...> : false_type {};
+
+template <>
+struct __lazy_and_impl<true> : true_type {};
+
+template <class _Pred>
+struct __lazy_and_impl<true, _Pred> : integral_constant<bool, _Pred::type::value> {};
+
+template <class _Hp, class ..._Tp>
+struct __lazy_and_impl<true, _Hp, _Tp...> : __lazy_and_impl<_Hp::type::value, _Tp...> {};
+
+template <class _P1, class ..._Pr>
+struct __lazy_and : __lazy_and_impl<_P1::type::value, _Pr...> {};
+
+// __lazy_not
+
+template <class _Pred>
+struct __lazy_not : integral_constant<bool, !_Pred::type::value> {};
// __make_tuple_indices
@@ -354,8 +366,8 @@
tuple_size<_Up>::value, _Tp, _Up>
{};
-_LIBCPP_END_NAMESPACE_STD
-
#endif // _LIBCPP_HAS_NO_VARIADICS
+_LIBCPP_END_NAMESPACE_STD
+
#endif // _LIBCPP___TUPLE
Index: include/__tuple_03
===================================================================
--- include/__tuple_03
+++ /dev/null
@@ -1,27 +0,0 @@
-// -*- C++ -*-
-//===----------------------------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___TUPLE_03
-#define _LIBCPP___TUPLE_03
-
-#include <__config>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
-#endif
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-template <class _Tp> class _LIBCPP_TYPE_VIS_ONLY tuple_size;
-template <size_t _Ip, class _Tp> class _LIBCPP_TYPE_VIS_ONLY tuple_element;
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // _LIBCPP___TUPLE_03
Index: include/array
===================================================================
--- include/array
+++ include/array
@@ -288,10 +288,6 @@
class _LIBCPP_TYPE_VIS_ONLY tuple_size<array<_Tp, _Size> >
: public integral_constant<size_t, _Size> {};
-template <class _Tp, size_t _Size>
-class _LIBCPP_TYPE_VIS_ONLY tuple_size<const array<_Tp, _Size> >
- : public integral_constant<size_t, _Size> {};
-
template <size_t _Ip, class _Tp, size_t _Size>
class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, array<_Tp, _Size> >
{
@@ -300,13 +296,6 @@
};
template <size_t _Ip, class _Tp, size_t _Size>
-class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, const array<_Tp, _Size> >
-{
-public:
- typedef const _Tp type;
-};
-
-template <size_t _Ip, class _Tp, size_t _Size>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
_Tp&
get(array<_Tp, _Size>& __a) _NOEXCEPT
Index: include/utility
===================================================================
--- include/utility
+++ include/utility
@@ -512,10 +512,6 @@
: public integral_constant<size_t, 2> {};
template <class _T1, class _T2>
- class _LIBCPP_TYPE_VIS_ONLY tuple_size<const pair<_T1, _T2> >
- : public integral_constant<size_t, 2> {};
-
-template <class _T1, class _T2>
class _LIBCPP_TYPE_VIS_ONLY tuple_element<0, pair<_T1, _T2> >
{
public:
@@ -529,20 +525,6 @@
typedef _T2 type;
};
-template <class _T1, class _T2>
-class _LIBCPP_TYPE_VIS_ONLY tuple_element<0, const pair<_T1, _T2> >
-{
-public:
- typedef const _T1 type;
-};
-
-template <class _T1, class _T2>
-class _LIBCPP_TYPE_VIS_ONLY tuple_element<1, const pair<_T1, _T2> >
-{
-public:
- typedef const _T2 type;
-};
-
template <size_t _Ip> struct __get_pair;
template <>
Index: test/std/containers/sequences/array/array.tuple/tuple_element.pass.cpp
===================================================================
--- test/std/containers/sequences/array/array.tuple/tuple_element.pass.cpp
+++ test/std/containers/sequences/array/array.tuple/tuple_element.pass.cpp
@@ -14,20 +14,41 @@
#include <array>
#include <type_traits>
-int main()
+template <class T>
+void test()
{
{
- typedef double T;
- typedef std::array<T, 3> C;
- static_assert((std::is_same<std::tuple_element<0, C>::type, T>::value), "");
- static_assert((std::is_same<std::tuple_element<1, C>::type, T>::value), "");
- static_assert((std::is_same<std::tuple_element<2, C>::type, T>::value), "");
+ typedef T Exp;
+ typedef std::array<T, 3> C;
+ static_assert((std::is_same<typename std::tuple_element<0, C>::type, Exp>::value), "");
+ static_assert((std::is_same<typename std::tuple_element<1, C>::type, Exp>::value), "");
+ static_assert((std::is_same<typename std::tuple_element<2, C>::type, Exp>::value), "");
+ }
+ {
+ typedef T const Exp;
+ typedef std::array<T, 3> const C;
+ static_assert((std::is_same<typename std::tuple_element<0, C>::type, Exp>::value), "");
+ static_assert((std::is_same<typename std::tuple_element<1, C>::type, Exp>::value), "");
+ static_assert((std::is_same<typename std::tuple_element<2, C>::type, Exp>::value), "");
+ }
+ {
+ typedef T volatile Exp;
+ typedef std::array<T, 3> volatile C;
+ static_assert((std::is_same<typename std::tuple_element<0, C>::type, Exp>::value), "");
+ static_assert((std::is_same<typename std::tuple_element<1, C>::type, Exp>::value), "");
+ static_assert((std::is_same<typename std::tuple_element<2, C>::type, Exp>::value), "");
}
{
- typedef int T;
- typedef std::array<T, 3> C;
- static_assert((std::is_same<std::tuple_element<0, C>::type, T>::value), "");
- static_assert((std::is_same<std::tuple_element<1, C>::type, T>::value), "");
- static_assert((std::is_same<std::tuple_element<2, C>::type, T>::value), "");
+ typedef T const volatile Exp;
+ typedef std::array<T, 3> const volatile C;
+ static_assert((std::is_same<typename std::tuple_element<0, C>::type, Exp>::value), "");
+ static_assert((std::is_same<typename std::tuple_element<1, C>::type, Exp>::value), "");
+ static_assert((std::is_same<typename std::tuple_element<2, C>::type, Exp>::value), "");
}
}
+
+int main()
+{
+ test<double>();
+ test<int>();
+}
Index: test/std/containers/sequences/array/array.tuple/tuple_size.pass.cpp
===================================================================
--- test/std/containers/sequences/array/array.tuple/tuple_size.pass.cpp
+++ test/std/containers/sequences/array/array.tuple/tuple_size.pass.cpp
@@ -13,16 +13,30 @@
#include <array>
-int main()
+template <class T, std::size_t N>
+void test()
{
{
- typedef double T;
- typedef std::array<T, 3> C;
- static_assert((std::tuple_size<C>::value == 3), "");
+ typedef std::array<T, N> C;
+ static_assert((std::tuple_size<C>::value == N), "");
+ }
+ {
+ typedef std::array<T const, N> C;
+ static_assert((std::tuple_size<C>::value == N), "");
+ }
+ {
+ typedef std::array<T volatile, N> C;
+ static_assert((std::tuple_size<C>::value == N), "");
}
{
- typedef double T;
- typedef std::array<T, 0> C;
- static_assert((std::tuple_size<C>::value == 0), "");
+ typedef std::array<T const volatile, N> C;
+ static_assert((std::tuple_size<C>::value == N), "");
}
}
+
+int main()
+{
+ test<double, 0>();
+ test<double, 3>();
+ test<double, 5>();
+}
Index: test/std/utilities/utility/pairs/pair.astuple/tuple_element.pass.cpp
===================================================================
--- test/std/utilities/utility/pairs/pair.astuple/tuple_element.pass.cpp
+++ test/std/utilities/utility/pairs/pair.astuple/tuple_element.pass.cpp
@@ -15,16 +15,41 @@
#include <utility>
-int main()
+template <class T1, class T2>
+void test()
{
{
- typedef std::pair<int, short> P1;
- static_assert((std::is_same<std::tuple_element<0, P1>::type, int>::value), "");
- static_assert((std::is_same<std::tuple_element<1, P1>::type, short>::value), "");
+ typedef T1 Exp1;
+ typedef T2 Exp2;
+ typedef std::pair<T1, T2> P;
+ static_assert((std::is_same<typename std::tuple_element<0, P>::type, Exp1>::value), "");
+ static_assert((std::is_same<typename std::tuple_element<1, P>::type, Exp2>::value), "");
+ }
+ {
+ typedef T1 const Exp1;
+ typedef T2 const Exp2;
+ typedef std::pair<T1, T2> const P;
+ static_assert((std::is_same<typename std::tuple_element<0, P>::type, Exp1>::value), "");
+ static_assert((std::is_same<typename std::tuple_element<1, P>::type, Exp2>::value), "");
+ }
+ {
+ typedef T1 volatile Exp1;
+ typedef T2 volatile Exp2;
+ typedef std::pair<T1, T2> volatile P;
+ static_assert((std::is_same<typename std::tuple_element<0, P>::type, Exp1>::value), "");
+ static_assert((std::is_same<typename std::tuple_element<1, P>::type, Exp2>::value), "");
}
{
- typedef std::pair<int*, char> P1;
- static_assert((std::is_same<std::tuple_element<0, P1>::type, int*>::value), "");
- static_assert((std::is_same<std::tuple_element<1, P1>::type, char>::value), "");
+ typedef T1 const volatile Exp1;
+ typedef T2 const volatile Exp2;
+ typedef std::pair<T1, T2> const volatile P;
+ static_assert((std::is_same<typename std::tuple_element<0, P>::type, Exp1>::value), "");
+ static_assert((std::is_same<typename std::tuple_element<1, P>::type, Exp2>::value), "");
}
}
+
+int main()
+{
+ test<int, short>();
+ test<int*, char>();
+}
Index: test/std/utilities/utility/pairs/pair.astuple/tuple_size.pass.cpp
===================================================================
--- test/std/utilities/utility/pairs/pair.astuple/tuple_size.pass.cpp
+++ test/std/utilities/utility/pairs/pair.astuple/tuple_size.pass.cpp
@@ -21,4 +21,16 @@
typedef std::pair<int, short> P1;
static_assert((std::tuple_size<P1>::value == 2), "");
}
+ {
+ typedef std::pair<int, short> const P1;
+ static_assert((std::tuple_size<P1>::value == 2), "");
+ }
+ {
+ typedef std::pair<int, short> volatile P1;
+ static_assert((std::tuple_size<P1>::value == 2), "");
+ }
+ {
+ typedef std::pair<int, short> const volatile P1;
+ static_assert((std::tuple_size<P1>::value == 2), "");
+ }
}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits