[libcxx] r232492 - [libcxx] Move tuple_size and tuple_element overloads for pair and array out of !defined(_LIBCPP_HAS_NO_VARIADICS) block.

Eric Fiselier eric at efcs.ca
Tue Mar 17 08:08:03 PDT 2015


Author: ericwf
Date: Tue Mar 17 10:08:03 2015
New Revision: 232492

URL: http://llvm.org/viewvc/llvm-project?rev=232492&view=rev
Log:
[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

Removed:
    libcxx/trunk/include/__tuple_03
Modified:
    libcxx/trunk/include/__tuple
    libcxx/trunk/include/array
    libcxx/trunk/include/utility
    libcxx/trunk/test/std/containers/sequences/array/array.tuple/tuple_element.pass.cpp
    libcxx/trunk/test/std/containers/sequences/array/array.tuple/tuple_size.pass.cpp
    libcxx/trunk/test/std/utilities/utility/pairs/pair.astuple/tuple_element.pass.cpp
    libcxx/trunk/test/std/utilities/utility/pairs/pair.astuple/tuple_size.pass.cpp

Modified: libcxx/trunk/include/__tuple
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/__tuple?rev=232492&r1=232491&r2=232492&view=diff
==============================================================================
--- libcxx/trunk/include/__tuple (original)
+++ libcxx/trunk/include/__tuple Tue Mar 17 10:08:03 2015
@@ -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_CONSTE
 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_CONSTE
 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
                                     tuple_size<_Up>::value, _Tp, _Up>
 {};
 
-_LIBCPP_END_NAMESPACE_STD
-
 #endif  // _LIBCPP_HAS_NO_VARIADICS
 
+_LIBCPP_END_NAMESPACE_STD
+
 #endif  // _LIBCPP___TUPLE

Removed: libcxx/trunk/include/__tuple_03
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/__tuple_03?rev=232491&view=auto
==============================================================================
--- libcxx/trunk/include/__tuple_03 (original)
+++ libcxx/trunk/include/__tuple_03 (removed)
@@ -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

Modified: libcxx/trunk/include/array
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/array?rev=232492&r1=232491&r2=232492&view=diff
==============================================================================
--- libcxx/trunk/include/array (original)
+++ libcxx/trunk/include/array Tue Mar 17 10:08:03 2015
@@ -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> >
 {
@@ -300,13 +296,6 @@ public:
 };
 
 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

Modified: libcxx/trunk/include/utility
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/utility?rev=232492&r1=232491&r2=232492&view=diff
==============================================================================
--- libcxx/trunk/include/utility (original)
+++ libcxx/trunk/include/utility Tue Mar 17 10:08:03 2015
@@ -513,10 +513,6 @@ template <class _T1, class _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> >
 {
 public:
@@ -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 <>

Modified: libcxx/trunk/test/std/containers/sequences/array/array.tuple/tuple_element.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/sequences/array/array.tuple/tuple_element.pass.cpp?rev=232492&r1=232491&r2=232492&view=diff
==============================================================================
--- libcxx/trunk/test/std/containers/sequences/array/array.tuple/tuple_element.pass.cpp (original)
+++ libcxx/trunk/test/std/containers/sequences/array/array.tuple/tuple_element.pass.cpp Tue Mar 17 10:08:03 2015
@@ -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>();
+}

Modified: libcxx/trunk/test/std/containers/sequences/array/array.tuple/tuple_size.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/sequences/array/array.tuple/tuple_size.pass.cpp?rev=232492&r1=232491&r2=232492&view=diff
==============================================================================
--- libcxx/trunk/test/std/containers/sequences/array/array.tuple/tuple_size.pass.cpp (original)
+++ libcxx/trunk/test/std/containers/sequences/array/array.tuple/tuple_size.pass.cpp Tue Mar 17 10:08:03 2015
@@ -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>();
+}

Modified: libcxx/trunk/test/std/utilities/utility/pairs/pair.astuple/tuple_element.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/utility/pairs/pair.astuple/tuple_element.pass.cpp?rev=232492&r1=232491&r2=232492&view=diff
==============================================================================
--- libcxx/trunk/test/std/utilities/utility/pairs/pair.astuple/tuple_element.pass.cpp (original)
+++ libcxx/trunk/test/std/utilities/utility/pairs/pair.astuple/tuple_element.pass.cpp Tue Mar 17 10:08:03 2015
@@ -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>();
+}

Modified: libcxx/trunk/test/std/utilities/utility/pairs/pair.astuple/tuple_size.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/utility/pairs/pair.astuple/tuple_size.pass.cpp?rev=232492&r1=232491&r2=232492&view=diff
==============================================================================
--- libcxx/trunk/test/std/utilities/utility/pairs/pair.astuple/tuple_size.pass.cpp (original)
+++ libcxx/trunk/test/std/utilities/utility/pairs/pair.astuple/tuple_size.pass.cpp Tue Mar 17 10:08:03 2015
@@ -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), "");
+    }
 }





More information about the cfe-commits mailing list