From 8e706d2c3efc5d5c2110553eefec3bc588b5c150 Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Tue, 17 Mar 2015 15:08:03 +0000 Subject: [PATCH] [libcxx] Move tuple_size and tuple_element overloads for pair and array out of !defined(_LIBCPP_HAS_NO_VARIADICS) block. Summary: There is no reason to guard `tuple_size`, `tuple_element` and `get(...)` 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 int main() { static_assert((std::tuple_size volatile>::value == 10), ""); } ``` This patch lifts the non-variadic parts of `tuple_size`, `tuple_types`, and `get(...)` 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. Reviewers: danalbert, K-ballo, mclow.lists Reviewed By: mclow.lists Subscribers: cfe-commits Differential Revision: http://reviews.llvm.org/D7774 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@232492 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/__tuple | 90 +++++++++++-------- include/__tuple_03 | 27 ------ include/array | 11 --- include/utility | 18 ---- .../array/array.tuple/tuple_element.pass.cpp | 43 ++++++--- .../array/array.tuple/tuple_size.pass.cpp | 28 ++++-- .../pairs/pair.astuple/tuple_element.pass.cpp | 39 ++++++-- .../pairs/pair.astuple/tuple_size.pass.cpp | 12 +++ 8 files changed, 148 insertions(+), 120 deletions(-) delete mode 100644 include/__tuple_03 diff --git a/include/__tuple b/include/__tuple index bffb95cb..2837ce70 100644 --- a/include/__tuple +++ b/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 -struct __lazy_and_impl; - -template -struct __lazy_and_impl : false_type {}; - -template <> -struct __lazy_and_impl : true_type {}; - -template -struct __lazy_and_impl : integral_constant {}; - -template -struct __lazy_and_impl : __lazy_and_impl<_Hp::type::value, _Tp...> {}; - -template -struct __lazy_and : __lazy_and_impl<_P1::type::value, _Pr...> {}; - -// __lazy_not - -template -struct __lazy_not : integral_constant {}; - - template class _LIBCPP_TYPE_VIS_ONLY tuple_size; template @@ -90,19 +59,18 @@ public: typedef typename add_cv::type>::type type; }; -template class _LIBCPP_TYPE_VIS_ONLY tuple; -template struct _LIBCPP_TYPE_VIS_ONLY pair; -template struct _LIBCPP_TYPE_VIS_ONLY array; - template struct __tuple_like : false_type {}; template struct __tuple_like : public __tuple_like<_Tp> {}; template struct __tuple_like : public __tuple_like<_Tp> {}; template struct __tuple_like : public __tuple_like<_Tp> {}; +// tuple specializations + +#if !defined(_LIBCPP_HAS_NO_VARIADICS) +template class _LIBCPP_TYPE_VIS_ONLY tuple; + template struct __tuple_like > : true_type {}; -template struct __tuple_like > : true_type {}; -template struct __tuple_like > : true_type {}; template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 @@ -118,6 +86,13 @@ template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 typename tuple_element<_Ip, tuple<_Tp...> >::type&& get(tuple<_Tp...>&&) _NOEXCEPT; +#endif + +// pair specializations + +template struct _LIBCPP_TYPE_VIS_ONLY pair; + +template struct __tuple_like > : true_type {}; template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 @@ -129,10 +104,18 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const typename tuple_element<_Ip, pair<_T1, _T2> >::type& get(const pair<_T1, _T2>&) _NOEXCEPT; +#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 typename tuple_element<_Ip, pair<_T1, _T2> >::type&& get(pair<_T1, _T2>&&) _NOEXCEPT; +#endif + +// array specializations + +template struct _LIBCPP_TYPE_VIS_ONLY array; + +template struct __tuple_like > : true_type {}; template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 @@ -144,10 +127,39 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Tp& get(const array<_Tp, _Size>&) _NOEXCEPT; +#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 _Tp&& get(array<_Tp, _Size>&&) _NOEXCEPT; +#endif + +#if !defined(_LIBCPP_HAS_NO_VARIADICS) + +// __lazy_and + +template +struct __lazy_and_impl; + +template +struct __lazy_and_impl : false_type {}; + +template <> +struct __lazy_and_impl : true_type {}; + +template +struct __lazy_and_impl : integral_constant {}; + +template +struct __lazy_and_impl : __lazy_and_impl<_Hp::type::value, _Tp...> {}; + +template +struct __lazy_and : __lazy_and_impl<_P1::type::value, _Pr...> {}; + +// __lazy_not + +template +struct __lazy_not : integral_constant {}; // __make_tuple_indices @@ -354,8 +366,8 @@ struct __tuple_assignable<_Tp, _Up, true, true> tuple_size<_Up>::value, _Tp, _Up> {}; -_LIBCPP_END_NAMESPACE_STD - #endif // _LIBCPP_HAS_NO_VARIADICS +_LIBCPP_END_NAMESPACE_STD + #endif // _LIBCPP___TUPLE diff --git a/include/__tuple_03 b/include/__tuple_03 deleted file mode 100644 index b91c2cd4..00000000 --- a/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 _LIBCPP_TYPE_VIS_ONLY tuple_size; -template class _LIBCPP_TYPE_VIS_ONLY tuple_element; - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP___TUPLE_03 diff --git a/include/array b/include/array index d37075da..2e02a43e 100644 --- a/include/array +++ b/include/array @@ -288,10 +288,6 @@ template class _LIBCPP_TYPE_VIS_ONLY tuple_size > : public integral_constant {}; -template -class _LIBCPP_TYPE_VIS_ONLY tuple_size > - : public integral_constant {}; - template class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, array<_Tp, _Size> > { @@ -299,13 +295,6 @@ public: typedef _Tp type; }; -template -class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, const array<_Tp, _Size> > -{ -public: - typedef const _Tp type; -}; - template inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 _Tp& diff --git a/include/utility b/include/utility index 96db60a6..54cfc8bc 100644 --- a/include/utility +++ b/include/utility @@ -512,10 +512,6 @@ template class _LIBCPP_TYPE_VIS_ONLY tuple_size > : public integral_constant {}; -template - class _LIBCPP_TYPE_VIS_ONLY tuple_size > - : public integral_constant {}; - template class _LIBCPP_TYPE_VIS_ONLY tuple_element<0, pair<_T1, _T2> > { @@ -530,20 +526,6 @@ public: typedef _T2 type; }; -template -class _LIBCPP_TYPE_VIS_ONLY tuple_element<0, const pair<_T1, _T2> > -{ -public: - typedef const _T1 type; -}; - -template -class _LIBCPP_TYPE_VIS_ONLY tuple_element<1, const pair<_T1, _T2> > -{ -public: - typedef const _T2 type; -}; - template struct __get_pair; template <> diff --git a/test/std/containers/sequences/array/array.tuple/tuple_element.pass.cpp b/test/std/containers/sequences/array/array.tuple/tuple_element.pass.cpp index cd1dad60..91d6b4e5 100644 --- a/test/std/containers/sequences/array/array.tuple/tuple_element.pass.cpp +++ b/test/std/containers/sequences/array/array.tuple/tuple_element.pass.cpp @@ -14,20 +14,41 @@ #include #include -int main() +template +void test() { { - typedef double T; - typedef std::array C; - static_assert((std::is_same::type, T>::value), ""); - static_assert((std::is_same::type, T>::value), ""); - static_assert((std::is_same::type, T>::value), ""); + typedef T Exp; + typedef std::array C; + static_assert((std::is_same::type, Exp>::value), ""); + static_assert((std::is_same::type, Exp>::value), ""); + static_assert((std::is_same::type, Exp>::value), ""); } { - typedef int T; - typedef std::array C; - static_assert((std::is_same::type, T>::value), ""); - static_assert((std::is_same::type, T>::value), ""); - static_assert((std::is_same::type, T>::value), ""); + typedef T const Exp; + typedef std::array const C; + static_assert((std::is_same::type, Exp>::value), ""); + static_assert((std::is_same::type, Exp>::value), ""); + static_assert((std::is_same::type, Exp>::value), ""); + } + { + typedef T volatile Exp; + typedef std::array volatile C; + static_assert((std::is_same::type, Exp>::value), ""); + static_assert((std::is_same::type, Exp>::value), ""); + static_assert((std::is_same::type, Exp>::value), ""); + } + { + typedef T const volatile Exp; + typedef std::array const volatile C; + static_assert((std::is_same::type, Exp>::value), ""); + static_assert((std::is_same::type, Exp>::value), ""); + static_assert((std::is_same::type, Exp>::value), ""); } } + +int main() +{ + test(); + test(); +} diff --git a/test/std/containers/sequences/array/array.tuple/tuple_size.pass.cpp b/test/std/containers/sequences/array/array.tuple/tuple_size.pass.cpp index 83394b1e..1e565d19 100644 --- a/test/std/containers/sequences/array/array.tuple/tuple_size.pass.cpp +++ b/test/std/containers/sequences/array/array.tuple/tuple_size.pass.cpp @@ -13,16 +13,30 @@ #include -int main() +template +void test() { { - typedef double T; - typedef std::array C; - static_assert((std::tuple_size::value == 3), ""); + typedef std::array C; + static_assert((std::tuple_size::value == N), ""); } { - typedef double T; - typedef std::array C; - static_assert((std::tuple_size::value == 0), ""); + typedef std::array C; + static_assert((std::tuple_size::value == N), ""); + } + { + typedef std::array C; + static_assert((std::tuple_size::value == N), ""); + } + { + typedef std::array C; + static_assert((std::tuple_size::value == N), ""); } } + +int main() +{ + test(); + test(); + test(); +} diff --git a/test/std/utilities/utility/pairs/pair.astuple/tuple_element.pass.cpp b/test/std/utilities/utility/pairs/pair.astuple/tuple_element.pass.cpp index 9a303bae..5ac838b3 100644 --- a/test/std/utilities/utility/pairs/pair.astuple/tuple_element.pass.cpp +++ b/test/std/utilities/utility/pairs/pair.astuple/tuple_element.pass.cpp @@ -15,16 +15,41 @@ #include -int main() +template +void test() { { - typedef std::pair P1; - static_assert((std::is_same::type, int>::value), ""); - static_assert((std::is_same::type, short>::value), ""); + typedef T1 Exp1; + typedef T2 Exp2; + typedef std::pair P; + static_assert((std::is_same::type, Exp1>::value), ""); + static_assert((std::is_same::type, Exp2>::value), ""); } { - typedef std::pair P1; - static_assert((std::is_same::type, int*>::value), ""); - static_assert((std::is_same::type, char>::value), ""); + typedef T1 const Exp1; + typedef T2 const Exp2; + typedef std::pair const P; + static_assert((std::is_same::type, Exp1>::value), ""); + static_assert((std::is_same::type, Exp2>::value), ""); + } + { + typedef T1 volatile Exp1; + typedef T2 volatile Exp2; + typedef std::pair volatile P; + static_assert((std::is_same::type, Exp1>::value), ""); + static_assert((std::is_same::type, Exp2>::value), ""); + } + { + typedef T1 const volatile Exp1; + typedef T2 const volatile Exp2; + typedef std::pair const volatile P; + static_assert((std::is_same::type, Exp1>::value), ""); + static_assert((std::is_same::type, Exp2>::value), ""); } } + +int main() +{ + test(); + test(); +} diff --git a/test/std/utilities/utility/pairs/pair.astuple/tuple_size.pass.cpp b/test/std/utilities/utility/pairs/pair.astuple/tuple_size.pass.cpp index 2be694e8..3756e963 100644 --- a/test/std/utilities/utility/pairs/pair.astuple/tuple_size.pass.cpp +++ b/test/std/utilities/utility/pairs/pair.astuple/tuple_size.pass.cpp @@ -21,4 +21,16 @@ int main() typedef std::pair P1; static_assert((std::tuple_size::value == 2), ""); } + { + typedef std::pair const P1; + static_assert((std::tuple_size::value == 2), ""); + } + { + typedef std::pair volatile P1; + static_assert((std::tuple_size::value == 2), ""); + } + { + typedef std::pair const volatile P1; + static_assert((std::tuple_size::value == 2), ""); + } }