Project

General

Profile

Statistics
| Revision:

root / lab4 / .minix-src / include / c++ / __tuple

History | View | Annotate | Download (12 KB)

1 13 up20180614
// -*- 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