[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<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. 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
This commit is contained in:
parent
061244c8fb
commit
8e706d2c3e
@ -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 @@ public:
|
||||
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 @@ template <size_t _Ip, class ..._Tp>
|
||||
_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 @@ _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 <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 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
||||
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 @@ 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
|
||||
|
@ -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
|
@ -288,10 +288,6 @@ template <class _Tp, size_t _Size>
|
||||
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> >
|
||||
{
|
||||
@ -299,13 +295,6 @@ public:
|
||||
typedef _Tp type;
|
||||
};
|
||||
|
||||
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&
|
||||
|
@ -512,10 +512,6 @@ template <class _T1, class _T2>
|
||||
class _LIBCPP_TYPE_VIS_ONLY tuple_size<pair<_T1, _T2> >
|
||||
: 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> >
|
||||
{
|
||||
@ -530,20 +526,6 @@ public:
|
||||
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 <>
|
||||
|
@ -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 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 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 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>();
|
||||
}
|
||||
|
@ -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 double T;
|
||||
typedef std::array<T, 0> C;
|
||||
static_assert((std::tuple_size<C>::value == 0), "");
|
||||
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 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>();
|
||||
}
|
||||
|
@ -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 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 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 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>();
|
||||
}
|
||||
|
@ -21,4 +21,16 @@ int main()
|
||||
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), "");
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user