__tuple revision 227825
1227825Stheraven// -*- C++ -*-
2227825Stheraven//===----------------------------------------------------------------------===//
3227825Stheraven//
4227825Stheraven//                     The LLVM Compiler Infrastructure
5227825Stheraven//
6227825Stheraven// This file is dual licensed under the MIT and the University of Illinois Open
7227825Stheraven// Source Licenses. See LICENSE.TXT for details.
8227825Stheraven//
9227825Stheraven//===----------------------------------------------------------------------===//
10227825Stheraven
11227825Stheraven#ifndef _LIBCPP___TUPLE
12227825Stheraven#define _LIBCPP___TUPLE
13227825Stheraven
14227825Stheraven#include <__config>
15227825Stheraven#include <cstddef>
16227825Stheraven#include <type_traits>
17227825Stheraven
18227825Stheraven#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19227825Stheraven#pragma GCC system_header
20227825Stheraven#endif
21227825Stheraven
22227825Stheraven#ifdef _LIBCPP_HAS_NO_VARIADICS
23227825Stheraven
24227825Stheraven#include <__tuple_03>
25227825Stheraven
26227825Stheraven#else  // _LIBCPP_HAS_NO_VARIADICS
27227825Stheraven
28227825Stheraven_LIBCPP_BEGIN_NAMESPACE_STD
29227825Stheraven
30227825Stheraventemplate <class _Tp> class _LIBCPP_VISIBLE tuple_size;
31227825Stheraven
32227825Stheraventemplate <class _Tp>
33227825Stheravenclass _LIBCPP_VISIBLE tuple_size<const _Tp>
34227825Stheraven    : public tuple_size<_Tp> {};
35227825Stheraven
36227825Stheraventemplate <class _Tp>
37227825Stheravenclass _LIBCPP_VISIBLE tuple_size<volatile _Tp>
38227825Stheraven    : public tuple_size<_Tp> {};
39227825Stheraven
40227825Stheraventemplate <class _Tp>
41227825Stheravenclass _LIBCPP_VISIBLE tuple_size<const volatile _Tp>
42227825Stheraven    : public tuple_size<_Tp> {};
43227825Stheraven
44227825Stheraventemplate <size_t _Ip, class _Tp> class _LIBCPP_VISIBLE tuple_element;
45227825Stheraven
46227825Stheraventemplate <size_t _Ip, class _Tp>
47227825Stheravenclass _LIBCPP_VISIBLE tuple_element<_Ip, const _Tp>
48227825Stheraven{
49227825Stheravenpublic:
50227825Stheraven    typedef typename add_const<typename tuple_element<_Ip, _Tp>::type>::type type;
51227825Stheraven};
52227825Stheraven
53227825Stheraventemplate <size_t _Ip, class _Tp>
54227825Stheravenclass _LIBCPP_VISIBLE tuple_element<_Ip, volatile _Tp>
55227825Stheraven{
56227825Stheravenpublic:
57227825Stheraven    typedef typename add_volatile<typename tuple_element<_Ip, _Tp>::type>::type type;
58227825Stheraven};
59227825Stheraven
60227825Stheraventemplate <size_t _Ip, class _Tp>
61227825Stheravenclass _LIBCPP_VISIBLE tuple_element<_Ip, const volatile _Tp>
62227825Stheraven{
63227825Stheravenpublic:
64227825Stheraven    typedef typename add_cv<typename tuple_element<_Ip, _Tp>::type>::type type;
65227825Stheraven};
66227825Stheraven
67227825Stheraventemplate <class ..._Tp> class _LIBCPP_VISIBLE tuple;
68227825Stheraventemplate <class _T1, class _T2> class _LIBCPP_VISIBLE pair;
69227825Stheraventemplate <class _Tp, size_t _Size> struct _LIBCPP_VISIBLE array;
70227825Stheraven
71227825Stheraventemplate <class _Tp> struct __tuple_like : false_type {};
72227825Stheraven
73227825Stheraventemplate <class _Tp> struct __tuple_like<const _Tp> : public __tuple_like<_Tp> {};
74227825Stheraventemplate <class _Tp> struct __tuple_like<volatile _Tp> : public __tuple_like<_Tp> {};
75227825Stheraventemplate <class _Tp> struct __tuple_like<const volatile _Tp> : public __tuple_like<_Tp> {};
76227825Stheraven
77227825Stheraventemplate <class... _Tp> struct __tuple_like<tuple<_Tp...> > : true_type {};
78227825Stheraventemplate <class _T1, class _T2> struct __tuple_like<pair<_T1, _T2> > : true_type {};
79227825Stheraventemplate <class _Tp, size_t _Size> struct __tuple_like<array<_Tp, _Size> > : true_type {};
80227825Stheraven
81227825Stheraventemplate <size_t _Ip, class ..._Tp>
82227825Stheraventypename tuple_element<_Ip, tuple<_Tp...> >::type&
83227825Stheravenget(tuple<_Tp...>&) _NOEXCEPT;
84227825Stheraven
85227825Stheraventemplate <size_t _Ip, class ..._Tp>
86227825Stheravenconst typename tuple_element<_Ip, tuple<_Tp...> >::type&
87227825Stheravenget(const tuple<_Tp...>&) _NOEXCEPT;
88227825Stheraven
89227825Stheraventemplate <size_t _Ip, class ..._Tp>
90227825Stheraventypename tuple_element<_Ip, tuple<_Tp...> >::type&&
91227825Stheravenget(tuple<_Tp...>&&) _NOEXCEPT;
92227825Stheraven
93227825Stheraventemplate <size_t _Ip, class _T1, class _T2>
94227825Stheraventypename tuple_element<_Ip, pair<_T1, _T2> >::type&
95227825Stheravenget(pair<_T1, _T2>&) _NOEXCEPT;
96227825Stheraven
97227825Stheraventemplate <size_t _Ip, class _T1, class _T2>
98227825Stheravenconst typename tuple_element<_Ip, pair<_T1, _T2> >::type&
99227825Stheravenget(const pair<_T1, _T2>&) _NOEXCEPT;
100227825Stheraven
101227825Stheraventemplate <size_t _Ip, class _T1, class _T2>
102227825Stheraventypename tuple_element<_Ip, pair<_T1, _T2> >::type&&
103227825Stheravenget(pair<_T1, _T2>&&) _NOEXCEPT;
104227825Stheraven
105227825Stheraventemplate <size_t _Ip, class _Tp, size_t _Size>
106227825Stheraven_Tp&
107227825Stheravenget(array<_Tp, _Size>&) _NOEXCEPT;
108227825Stheraven
109227825Stheraventemplate <size_t _Ip, class _Tp, size_t _Size>
110227825Stheravenconst _Tp&
111227825Stheravenget(const array<_Tp, _Size>&) _NOEXCEPT;
112227825Stheraven
113227825Stheraventemplate <size_t _Ip, class _Tp, size_t _Size>
114227825Stheraven_Tp&&
115227825Stheravenget(array<_Tp, _Size>&&) _NOEXCEPT;
116227825Stheraven
117227825Stheraven// __make_tuple_indices
118227825Stheraven
119227825Stheraventemplate <size_t...> struct __tuple_indices {};
120227825Stheraven
121227825Stheraventemplate <size_t _Sp, class _IntTuple, size_t _Ep>
122227825Stheravenstruct __make_indices_imp;
123227825Stheraven
124227825Stheraventemplate <size_t _Sp, size_t ..._Indices, size_t _Ep>
125227825Stheravenstruct __make_indices_imp<_Sp, __tuple_indices<_Indices...>, _Ep>
126227825Stheraven{
127227825Stheraven    typedef typename __make_indices_imp<_Sp+1, __tuple_indices<_Indices..., _Sp>, _Ep>::type type;
128227825Stheraven};
129227825Stheraven
130227825Stheraventemplate <size_t _Ep, size_t ..._Indices>
131227825Stheravenstruct __make_indices_imp<_Ep, __tuple_indices<_Indices...>, _Ep>
132227825Stheraven{
133227825Stheraven    typedef __tuple_indices<_Indices...> type;
134227825Stheraven};
135227825Stheraven
136227825Stheraventemplate <size_t _Ep, size_t _Sp = 0>
137227825Stheravenstruct __make_tuple_indices
138227825Stheraven{
139227825Stheraven    static_assert(_Sp <= _Ep, "__make_tuple_indices input error");
140227825Stheraven    typedef typename __make_indices_imp<_Sp, __tuple_indices<>, _Ep>::type type;
141227825Stheraven};
142227825Stheraven
143227825Stheraven// __tuple_types
144227825Stheraven
145227825Stheraventemplate <class ..._Tp> struct __tuple_types {};
146227825Stheraven
147227825Stheraventemplate <size_t _Ip>
148227825Stheravenclass _LIBCPP_VISIBLE tuple_element<_Ip, __tuple_types<> >
149227825Stheraven{
150227825Stheravenpublic:
151227825Stheraven    static_assert(_Ip == 0, "tuple_element index out of range");
152227825Stheraven    static_assert(_Ip != 0, "tuple_element index out of range");
153227825Stheraven};
154227825Stheraven
155227825Stheraventemplate <class _Hp, class ..._Tp>
156227825Stheravenclass _LIBCPP_VISIBLE tuple_element<0, __tuple_types<_Hp, _Tp...> >
157227825Stheraven{
158227825Stheravenpublic:
159227825Stheraven    typedef _Hp type;
160227825Stheraven};
161227825Stheraven
162227825Stheraventemplate <size_t _Ip, class _Hp, class ..._Tp>
163227825Stheravenclass _LIBCPP_VISIBLE tuple_element<_Ip, __tuple_types<_Hp, _Tp...> >
164227825Stheraven{
165227825Stheravenpublic:
166227825Stheraven    typedef typename tuple_element<_Ip-1, __tuple_types<_Tp...> >::type type;
167227825Stheraven};
168227825Stheraven
169227825Stheraventemplate <class ..._Tp>
170227825Stheravenclass _LIBCPP_VISIBLE tuple_size<__tuple_types<_Tp...> >
171227825Stheraven    : public integral_constant<size_t, sizeof...(_Tp)>
172227825Stheraven{
173227825Stheraven};
174227825Stheraven
175227825Stheraventemplate <class... _Tp> struct __tuple_like<__tuple_types<_Tp...> > : true_type {};
176227825Stheraven
177227825Stheraven// __make_tuple_types
178227825Stheraven
179227825Stheraven// __make_tuple_types<_Tuple<_Types...>, _Ep, _Sp>::type is a
180227825Stheraven// __tuple_types<_Types...> using only those _Types in the range [_Sp, _Ep).
181227825Stheraven// _Sp defaults to 0 and _Ep defaults to tuple_size<_Tuple>.  If _Tuple is a
182227825Stheraven// lvalue_reference type, then __tuple_types<_Types&...> is the result.
183227825Stheraven
184227825Stheraventemplate <class _TupleTypes, class _Tp, size_t _Sp, size_t _Ep>
185227825Stheravenstruct __make_tuple_types_imp;
186227825Stheraven
187227825Stheraventemplate <class ..._Types, class _Tp, size_t _Sp, size_t _Ep>
188227825Stheravenstruct __make_tuple_types_imp<__tuple_types<_Types...>, _Tp, _Sp, _Ep>
189227825Stheraven{
190227825Stheraven    typedef typename remove_reference<_Tp>::type _Tpr;
191227825Stheraven    typedef typename __make_tuple_types_imp<__tuple_types<_Types...,
192227825Stheraven                                            typename conditional<is_lvalue_reference<_Tp>::value,
193227825Stheraven                                                typename tuple_element<_Sp, _Tpr>::type&,
194227825Stheraven                                                typename tuple_element<_Sp, _Tpr>::type>::type>,
195227825Stheraven                                            _Tp, _Sp+1, _Ep>::type type;
196227825Stheraven};
197227825Stheraven
198227825Stheraventemplate <class ..._Types, class _Tp, size_t _Ep>
199227825Stheravenstruct __make_tuple_types_imp<__tuple_types<_Types...>, _Tp, _Ep, _Ep>
200227825Stheraven{
201227825Stheraven    typedef __tuple_types<_Types...> type;
202227825Stheraven};
203227825Stheraven
204227825Stheraventemplate <class _Tp, size_t _Ep = tuple_size<typename remove_reference<_Tp>::type>::value, size_t _Sp = 0>
205227825Stheravenstruct __make_tuple_types
206227825Stheraven{
207227825Stheraven    static_assert(_Sp <= _Ep, "__make_tuple_types input error");
208227825Stheraven    typedef typename __make_tuple_types_imp<__tuple_types<>, _Tp, _Sp, _Ep>::type type;
209227825Stheraven};
210227825Stheraven
211227825Stheraven// __tuple_convertible
212227825Stheraven
213227825Stheraventemplate <bool, class _Tp, class _Up>
214227825Stheravenstruct __tuple_convertible_imp : public false_type {};
215227825Stheraven
216227825Stheraventemplate <class _Tp0, class ..._Tp, class _Up0, class ..._Up>
217227825Stheravenstruct __tuple_convertible_imp<true, __tuple_types<_Tp0, _Tp...>, __tuple_types<_Up0, _Up...> >
218227825Stheraven    : public integral_constant<bool,
219227825Stheraven                               is_constructible<_Up0, _Tp0>::value &&
220227825Stheraven                               __tuple_convertible_imp<true, __tuple_types<_Tp...>, __tuple_types<_Up...> >::value> {};
221227825Stheraven
222227825Stheraventemplate <>
223227825Stheravenstruct __tuple_convertible_imp<true, __tuple_types<>, __tuple_types<> >
224227825Stheraven    : public true_type {};
225227825Stheraven
226227825Stheraventemplate <class _Tp, class _Up, bool = __tuple_like<typename remove_reference<_Tp>::type>::value,
227227825Stheraven                                bool = __tuple_like<_Up>::value>
228227825Stheravenstruct __tuple_convertible
229227825Stheraven    : public false_type {};
230227825Stheraven
231227825Stheraventemplate <class _Tp, class _Up>
232227825Stheravenstruct __tuple_convertible<_Tp, _Up, true, true>
233227825Stheraven    : public __tuple_convertible_imp<tuple_size<typename remove_reference<_Tp>::type>::value ==
234227825Stheraven                                     tuple_size<_Up>::value,
235227825Stheraven             typename __make_tuple_types<_Tp>::type, typename __make_tuple_types<_Up>::type>
236227825Stheraven{};
237227825Stheraven
238227825Stheraven// __tuple_assignable
239227825Stheraven
240227825Stheraventemplate <bool, class _Tp, class _Up>
241227825Stheravenstruct __tuple_assignable_imp : public false_type {};
242227825Stheraven
243227825Stheraventemplate <class _Tp0, class ..._Tp, class _Up0, class ..._Up>
244227825Stheravenstruct __tuple_assignable_imp<true, __tuple_types<_Tp0, _Tp...>, __tuple_types<_Up0, _Up...> >
245227825Stheraven    : public integral_constant<bool,
246227825Stheraven                               is_assignable<_Up0&, _Tp0>::value &&
247227825Stheraven                               __tuple_assignable_imp<true, __tuple_types<_Tp...>, __tuple_types<_Up...> >::value> {};
248227825Stheraven
249227825Stheraventemplate <>
250227825Stheravenstruct __tuple_assignable_imp<true, __tuple_types<>, __tuple_types<> >
251227825Stheraven    : public true_type {};
252227825Stheraven
253227825Stheraventemplate <class _Tp, class _Up, bool = __tuple_like<typename remove_reference<_Tp>::type>::value,
254227825Stheraven                                bool = __tuple_like<_Up>::value>
255227825Stheravenstruct __tuple_assignable
256227825Stheraven    : public false_type {};
257227825Stheraven
258227825Stheraventemplate <class _Tp, class _Up>
259227825Stheravenstruct __tuple_assignable<_Tp, _Up, true, true>
260227825Stheraven    : public __tuple_assignable_imp<tuple_size<typename remove_reference<_Tp>::type>::value ==
261227825Stheraven                                    tuple_size<_Up>::value,
262227825Stheraven             typename __make_tuple_types<_Tp>::type, typename __make_tuple_types<_Up>::type>
263227825Stheraven{};
264227825Stheraven
265227825Stheraven_LIBCPP_END_NAMESPACE_STD
266227825Stheraven
267227825Stheraven#endif  // _LIBCPP_HAS_NO_VARIADICS
268227825Stheraven
269227825Stheraven#endif  // _LIBCPP___TUPLE
270