root / lab4 / .minix-src / include / c++ / __tuple
History | View | Annotate | Download (12 KB)
1 |
// -*- C++ -*- |
---|---|
2 |
//===----------------------------------------------------------------------===// |
3 |
// |
4 |
// The LLVM Compiler Infrastructure |
5 |
// |
6 |
// This file is dual licensed under the MIT and the University of Illinois Open |
7 |
// Source Licenses. See LICENSE.TXT for details. |
8 |
// |
9 |
//===----------------------------------------------------------------------===// |
10 |
|
11 |
#ifndef _LIBCPP___TUPLE |
12 |
#define _LIBCPP___TUPLE |
13 |
|
14 |
#include <__config> |
15 |
#include <cstddef> |
16 |
#include <type_traits> |
17 |
|
18 |
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
19 |
#pragma GCC system_header |
20 |
#endif |
21 |
|
22 |
|
23 |
_LIBCPP_BEGIN_NAMESPACE_STD |
24 |
|
25 |
template <class _Tp> class _LIBCPP_TYPE_VIS_ONLY tuple_size; |
26 |
|
27 |
template <class _Tp> |
28 |
class _LIBCPP_TYPE_VIS_ONLY tuple_size<const _Tp> |
29 |
: public tuple_size<_Tp> {}; |
30 |
|
31 |
template <class _Tp> |
32 |
class _LIBCPP_TYPE_VIS_ONLY tuple_size<volatile _Tp> |
33 |
: public tuple_size<_Tp> {}; |
34 |
|
35 |
template <class _Tp> |
36 |
class _LIBCPP_TYPE_VIS_ONLY tuple_size<const volatile _Tp> |
37 |
: public tuple_size<_Tp> {}; |
38 |
|
39 |
template <size_t _Ip, class _Tp> class _LIBCPP_TYPE_VIS_ONLY tuple_element; |
40 |
|
41 |
template <size_t _Ip, class _Tp> |
42 |
class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, const _Tp> |
43 |
{ |
44 |
public: |
45 |
typedef typename add_const<typename tuple_element<_Ip, _Tp>::type>::type type; |
46 |
}; |
47 |
|
48 |
template <size_t _Ip, class _Tp> |
49 |
class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, volatile _Tp> |
50 |
{ |
51 |
public: |
52 |
typedef typename add_volatile<typename tuple_element<_Ip, _Tp>::type>::type type; |
53 |
}; |
54 |
|
55 |
template <size_t _Ip, class _Tp> |
56 |
class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, const volatile _Tp> |
57 |
{ |
58 |
public: |
59 |
typedef typename add_cv<typename tuple_element<_Ip, _Tp>::type>::type type; |
60 |
}; |
61 |
|
62 |
template <class _Tp> struct __tuple_like : false_type {}; |
63 |
|
64 |
template <class _Tp> struct __tuple_like<const _Tp> : public __tuple_like<_Tp> {}; |
65 |
template <class _Tp> struct __tuple_like<volatile _Tp> : public __tuple_like<_Tp> {}; |
66 |
template <class _Tp> struct __tuple_like<const volatile _Tp> : public __tuple_like<_Tp> {}; |
67 |
|
68 |
// tuple specializations |
69 |
|
70 |
#if !defined(_LIBCPP_HAS_NO_VARIADICS) |
71 |
template <class ..._Tp> class _LIBCPP_TYPE_VIS_ONLY tuple; |
72 |
|
73 |
template <class... _Tp> struct __tuple_like<tuple<_Tp...> > : true_type {}; |
74 |
|
75 |
template <size_t _Ip, class ..._Tp> |
76 |
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
77 |
typename tuple_element<_Ip, tuple<_Tp...> >::type& |
78 |
get(tuple<_Tp...>&) _NOEXCEPT; |
79 |
|
80 |
template <size_t _Ip, class ..._Tp> |
81 |
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
82 |
const typename tuple_element<_Ip, tuple<_Tp...> >::type& |
83 |
get(const tuple<_Tp...>&) _NOEXCEPT; |
84 |
|
85 |
template <size_t _Ip, class ..._Tp> |
86 |
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
87 |
typename tuple_element<_Ip, tuple<_Tp...> >::type&& |
88 |
get(tuple<_Tp...>&&) _NOEXCEPT; |
89 |
#endif |
90 |
|
91 |
// pair specializations |
92 |
|
93 |
template <class _T1, class _T2> struct _LIBCPP_TYPE_VIS_ONLY pair; |
94 |
|
95 |
template <class _T1, class _T2> struct __tuple_like<pair<_T1, _T2> > : true_type {}; |
96 |
|
97 |
template <size_t _Ip, class _T1, class _T2> |
98 |
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
99 |
typename tuple_element<_Ip, pair<_T1, _T2> >::type& |
100 |
get(pair<_T1, _T2>&) _NOEXCEPT; |
101 |
|
102 |
template <size_t _Ip, class _T1, class _T2> |
103 |
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
104 |
const typename tuple_element<_Ip, pair<_T1, _T2> >::type& |
105 |
get(const pair<_T1, _T2>&) _NOEXCEPT; |
106 |
|
107 |
#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) |
108 |
template <size_t _Ip, class _T1, class _T2> |
109 |
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
110 |
typename tuple_element<_Ip, pair<_T1, _T2> >::type&& |
111 |
get(pair<_T1, _T2>&&) _NOEXCEPT; |
112 |
#endif |
113 |
|
114 |
// array specializations |
115 |
|
116 |
template <class _Tp, size_t _Size> struct _LIBCPP_TYPE_VIS_ONLY array; |
117 |
|
118 |
template <class _Tp, size_t _Size> struct __tuple_like<array<_Tp, _Size> > : true_type {}; |
119 |
|
120 |
template <size_t _Ip, class _Tp, size_t _Size> |
121 |
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
122 |
_Tp& |
123 |
get(array<_Tp, _Size>&) _NOEXCEPT; |
124 |
|
125 |
template <size_t _Ip, class _Tp, size_t _Size> |
126 |
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
127 |
const _Tp& |
128 |
get(const array<_Tp, _Size>&) _NOEXCEPT; |
129 |
|
130 |
#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) |
131 |
template <size_t _Ip, class _Tp, size_t _Size> |
132 |
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
133 |
_Tp&& |
134 |
get(array<_Tp, _Size>&&) _NOEXCEPT; |
135 |
#endif |
136 |
|
137 |
#if !defined(_LIBCPP_HAS_NO_VARIADICS) |
138 |
|
139 |
// __lazy_and |
140 |
|
141 |
template <bool _Last, class ..._Preds> |
142 |
struct __lazy_and_impl; |
143 |
|
144 |
template <class ..._Preds> |
145 |
struct __lazy_and_impl<false, _Preds...> : false_type {}; |
146 |
|
147 |
template <> |
148 |
struct __lazy_and_impl<true> : true_type {}; |
149 |
|
150 |
template <class _Pred> |
151 |
struct __lazy_and_impl<true, _Pred> : integral_constant<bool, _Pred::type::value> {}; |
152 |
|
153 |
template <class _Hp, class ..._Tp> |
154 |
struct __lazy_and_impl<true, _Hp, _Tp...> : __lazy_and_impl<_Hp::type::value, _Tp...> {}; |
155 |
|
156 |
template <class _P1, class ..._Pr> |
157 |
struct __lazy_and : __lazy_and_impl<_P1::type::value, _Pr...> {}; |
158 |
|
159 |
// __lazy_not |
160 |
|
161 |
template <class _Pred> |
162 |
struct __lazy_not : integral_constant<bool, !_Pred::type::value> {}; |
163 |
|
164 |
// __make_tuple_indices |
165 |
|
166 |
template <size_t...> struct __tuple_indices {}; |
167 |
|
168 |
template <size_t _Sp, class _IntTuple, size_t _Ep> |
169 |
struct __make_indices_imp; |
170 |
|
171 |
template <size_t _Sp, size_t ..._Indices, size_t _Ep> |
172 |
struct __make_indices_imp<_Sp, __tuple_indices<_Indices...>, _Ep> |
173 |
{ |
174 |
typedef typename __make_indices_imp<_Sp+1, __tuple_indices<_Indices..., _Sp>, _Ep>::type type; |
175 |
}; |
176 |
|
177 |
template <size_t _Ep, size_t ..._Indices> |
178 |
struct __make_indices_imp<_Ep, __tuple_indices<_Indices...>, _Ep> |
179 |
{ |
180 |
typedef __tuple_indices<_Indices...> type; |
181 |
}; |
182 |
|
183 |
template <size_t _Ep, size_t _Sp = 0> |
184 |
struct __make_tuple_indices |
185 |
{ |
186 |
static_assert(_Sp <= _Ep, "__make_tuple_indices input error"); |
187 |
typedef typename __make_indices_imp<_Sp, __tuple_indices<>, _Ep>::type type; |
188 |
}; |
189 |
|
190 |
// __tuple_types |
191 |
|
192 |
template <class ..._Tp> struct __tuple_types {}; |
193 |
|
194 |
template <size_t _Ip> |
195 |
class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, __tuple_types<> > |
196 |
{ |
197 |
public: |
198 |
static_assert(_Ip == 0, "tuple_element index out of range"); |
199 |
static_assert(_Ip != 0, "tuple_element index out of range"); |
200 |
}; |
201 |
|
202 |
template <class _Hp, class ..._Tp> |
203 |
class _LIBCPP_TYPE_VIS_ONLY tuple_element<0, __tuple_types<_Hp, _Tp...> > |
204 |
{ |
205 |
public: |
206 |
typedef _Hp type; |
207 |
}; |
208 |
|
209 |
template <size_t _Ip, class _Hp, class ..._Tp> |
210 |
class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, __tuple_types<_Hp, _Tp...> > |
211 |
{ |
212 |
public: |
213 |
typedef typename tuple_element<_Ip-1, __tuple_types<_Tp...> >::type type; |
214 |
}; |
215 |
|
216 |
template <class ..._Tp> |
217 |
class _LIBCPP_TYPE_VIS_ONLY tuple_size<__tuple_types<_Tp...> > |
218 |
: public integral_constant<size_t, sizeof...(_Tp)> |
219 |
{ |
220 |
}; |
221 |
|
222 |
template <class... _Tp> struct __tuple_like<__tuple_types<_Tp...> > : true_type {}; |
223 |
|
224 |
// __make_tuple_types |
225 |
|
226 |
// __make_tuple_types<_Tuple<_Types...>, _Ep, _Sp>::type is a |
227 |
// __tuple_types<_Types...> using only those _Types in the range [_Sp, _Ep). |
228 |
// _Sp defaults to 0 and _Ep defaults to tuple_size<_Tuple>. If _Tuple is a |
229 |
// lvalue_reference type, then __tuple_types<_Types&...> is the result. |
230 |
|
231 |
template <class _TupleTypes, class _Tp, size_t _Sp, size_t _Ep> |
232 |
struct __make_tuple_types_imp; |
233 |
|
234 |
template <class ..._Types, class _Tp, size_t _Sp, size_t _Ep> |
235 |
struct __make_tuple_types_imp<__tuple_types<_Types...>, _Tp, _Sp, _Ep> |
236 |
{ |
237 |
typedef typename remove_reference<_Tp>::type _Tpr; |
238 |
typedef typename __make_tuple_types_imp<__tuple_types<_Types..., |
239 |
typename conditional<is_lvalue_reference<_Tp>::value, |
240 |
typename tuple_element<_Sp, _Tpr>::type&, |
241 |
typename tuple_element<_Sp, _Tpr>::type>::type>, |
242 |
_Tp, _Sp+1, _Ep>::type type; |
243 |
}; |
244 |
|
245 |
template <class ..._Types, class _Tp, size_t _Ep> |
246 |
struct __make_tuple_types_imp<__tuple_types<_Types...>, _Tp, _Ep, _Ep> |
247 |
{ |
248 |
typedef __tuple_types<_Types...> type; |
249 |
}; |
250 |
|
251 |
template <class _Tp, size_t _Ep = tuple_size<typename remove_reference<_Tp>::type>::value, size_t _Sp = 0> |
252 |
struct __make_tuple_types |
253 |
{ |
254 |
static_assert(_Sp <= _Ep, "__make_tuple_types input error"); |
255 |
typedef typename __make_tuple_types_imp<__tuple_types<>, _Tp, _Sp, _Ep>::type type; |
256 |
}; |
257 |
|
258 |
// __tuple_convertible |
259 |
|
260 |
template <class, class> |
261 |
struct __tuple_convertible_imp : public false_type {}; |
262 |
|
263 |
template <class _Tp0, class ..._Tp, class _Up0, class ..._Up> |
264 |
struct __tuple_convertible_imp<__tuple_types<_Tp0, _Tp...>, __tuple_types<_Up0, _Up...> > |
265 |
: public integral_constant<bool, |
266 |
is_convertible<_Tp0, _Up0>::value && |
267 |
__tuple_convertible_imp<__tuple_types<_Tp...>, __tuple_types<_Up...> >::value> {}; |
268 |
|
269 |
template <> |
270 |
struct __tuple_convertible_imp<__tuple_types<>, __tuple_types<> > |
271 |
: public true_type {}; |
272 |
|
273 |
template <bool, class, class> |
274 |
struct __tuple_convertible_apply : public false_type {}; |
275 |
|
276 |
template <class _Tp, class _Up> |
277 |
struct __tuple_convertible_apply<true, _Tp, _Up> |
278 |
: public __tuple_convertible_imp< |
279 |
typename __make_tuple_types<_Tp>::type |
280 |
, typename __make_tuple_types<_Up>::type |
281 |
> |
282 |
{}; |
283 |
|
284 |
template <class _Tp, class _Up, bool = __tuple_like<typename remove_reference<_Tp>::type>::value, |
285 |
bool = __tuple_like<_Up>::value> |
286 |
struct __tuple_convertible |
287 |
: public false_type {}; |
288 |
|
289 |
template <class _Tp, class _Up> |
290 |
struct __tuple_convertible<_Tp, _Up, true, true> |
291 |
: public __tuple_convertible_apply<tuple_size<typename remove_reference<_Tp>::type>::value == |
292 |
tuple_size<_Up>::value, _Tp, _Up> |
293 |
{}; |
294 |
|
295 |
// __tuple_constructible |
296 |
|
297 |
template <class, class> |
298 |
struct __tuple_constructible_imp : public false_type {}; |
299 |
|
300 |
template <class _Tp0, class ..._Tp, class _Up0, class ..._Up> |
301 |
struct __tuple_constructible_imp<__tuple_types<_Tp0, _Tp...>, __tuple_types<_Up0, _Up...> > |
302 |
: public integral_constant<bool, |
303 |
is_constructible<_Up0, _Tp0>::value && |
304 |
__tuple_constructible_imp<__tuple_types<_Tp...>, __tuple_types<_Up...> >::value> {}; |
305 |
|
306 |
template <> |
307 |
struct __tuple_constructible_imp<__tuple_types<>, __tuple_types<> > |
308 |
: public true_type {}; |
309 |
|
310 |
template <bool _SameSize, class, class> |
311 |
struct __tuple_constructible_apply : public false_type {}; |
312 |
|
313 |
template <class _Tp, class _Up> |
314 |
struct __tuple_constructible_apply<true, _Tp, _Up> |
315 |
: public __tuple_constructible_imp< |
316 |
typename __make_tuple_types<_Tp>::type |
317 |
, typename __make_tuple_types<_Up>::type |
318 |
> |
319 |
{}; |
320 |
|
321 |
template <class _Tp, class _Up, bool = __tuple_like<typename remove_reference<_Tp>::type>::value, |
322 |
bool = __tuple_like<_Up>::value> |
323 |
struct __tuple_constructible |
324 |
: public false_type {}; |
325 |
|
326 |
template <class _Tp, class _Up> |
327 |
struct __tuple_constructible<_Tp, _Up, true, true> |
328 |
: public __tuple_constructible_apply<tuple_size<typename remove_reference<_Tp>::type>::value == |
329 |
tuple_size<_Up>::value, _Tp, _Up> |
330 |
{}; |
331 |
|
332 |
// __tuple_assignable |
333 |
|
334 |
template <class, class> |
335 |
struct __tuple_assignable_imp : public false_type {}; |
336 |
|
337 |
template <class _Tp0, class ..._Tp, class _Up0, class ..._Up> |
338 |
struct __tuple_assignable_imp<__tuple_types<_Tp0, _Tp...>, __tuple_types<_Up0, _Up...> > |
339 |
: public integral_constant<bool, |
340 |
is_assignable<_Up0&, _Tp0>::value && |
341 |
__tuple_assignable_imp<__tuple_types<_Tp...>, __tuple_types<_Up...> >::value> {}; |
342 |
|
343 |
template <> |
344 |
struct __tuple_assignable_imp<__tuple_types<>, __tuple_types<> > |
345 |
: public true_type {}; |
346 |
|
347 |
template <bool, class, class> |
348 |
struct __tuple_assignable_apply : public false_type {}; |
349 |
|
350 |
template <class _Tp, class _Up> |
351 |
struct __tuple_assignable_apply<true, _Tp, _Up> |
352 |
: __tuple_assignable_imp< |
353 |
typename __make_tuple_types<_Tp>::type |
354 |
, typename __make_tuple_types<_Up>::type |
355 |
> |
356 |
{}; |
357 |
|
358 |
template <class _Tp, class _Up, bool = __tuple_like<typename remove_reference<_Tp>::type>::value, |
359 |
bool = __tuple_like<_Up>::value> |
360 |
struct __tuple_assignable |
361 |
: public false_type {}; |
362 |
|
363 |
template <class _Tp, class _Up> |
364 |
struct __tuple_assignable<_Tp, _Up, true, true> |
365 |
: public __tuple_assignable_apply<tuple_size<typename remove_reference<_Tp>::type>::value == |
366 |
tuple_size<_Up>::value, _Tp, _Up> |
367 |
{}; |
368 |
|
369 |
#endif // _LIBCPP_HAS_NO_VARIADICS |
370 |
|
371 |
_LIBCPP_END_NAMESPACE_STD |
372 |
|
373 |
#endif // _LIBCPP___TUPLE |