Project

General

Profile

Statistics
| Revision:

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