-
Notifications
You must be signed in to change notification settings - Fork 47
/
__msvc_iter_core.hpp
executable file
·520 lines (417 loc) · 17.6 KB
/
__msvc_iter_core.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
// __msvc_iter_core.hpp internal header (core)
// Copyright (c) Microsoft Corporation.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#ifndef __MSVC_ITER_CORE_HPP
#define __MSVC_ITER_CORE_HPP
#include <yvals_core.h>
#if _STL_COMPILER_PREPROCESSOR
#include <utility>
#pragma pack(push, _CRT_PACKING)
#pragma warning(push, _STL_WARNING_LEVEL)
#pragma warning(disable : _STL_DISABLED_WARNINGS)
_STL_DISABLE_CLANG_WARNINGS
#pragma push_macro("new")
#undef new
_STD_BEGIN
template <class _Ty, class _Alloc, class = void>
struct _Has_allocator_type : false_type {}; // tests for suitable _Ty::allocator_type
template <class _Ty, class _Alloc>
struct _Has_allocator_type<_Ty, _Alloc, void_t<typename _Ty::allocator_type>>
: is_convertible<_Alloc, typename _Ty::allocator_type>::type {};
_EXPORT_STD struct allocator_arg_t { // tag type for added allocator argument
explicit allocator_arg_t() = default;
};
_EXPORT_STD _INLINE_VAR constexpr allocator_arg_t allocator_arg{};
_EXPORT_STD template <class _Ty, class _Alloc>
struct uses_allocator : _Has_allocator_type<_Ty, _Alloc>::type {};
_EXPORT_STD template <class _Ty, class _Alloc>
_INLINE_VAR constexpr bool uses_allocator_v = uses_allocator<_Ty, _Alloc>::value;
// from <iterator>
_EXPORT_STD struct input_iterator_tag {};
_EXPORT_STD struct output_iterator_tag {};
_EXPORT_STD struct forward_iterator_tag : input_iterator_tag {};
_EXPORT_STD struct bidirectional_iterator_tag : forward_iterator_tag {};
_EXPORT_STD struct random_access_iterator_tag : bidirectional_iterator_tag {};
#ifdef __cpp_lib_concepts
_EXPORT_STD struct contiguous_iterator_tag : random_access_iterator_tag {};
template <class _Ty>
concept _Dereferenceable = requires(_Ty& __t) {
{ *__t } -> _Can_reference;
};
template <class _Ty>
concept _Has_member_iterator_concept = requires { typename _Ty::iterator_concept; };
template <class _Ty>
concept _Has_member_iterator_category = requires { typename _Ty::iterator_category; };
template <class _Ty>
concept _Has_member_value_type = requires { typename _Ty::value_type; };
template <class _Ty>
concept _Has_member_element_type = requires { typename _Ty::element_type; };
template <class _Ty>
concept _Has_member_difference_type = requires { typename _Ty::difference_type; };
template <class _Ty>
concept _Has_member_pointer = requires { typename _Ty::pointer; };
template <class _Ty>
concept _Has_member_reference = requires { typename _Ty::reference; };
_EXPORT_STD template <class>
struct incrementable_traits {};
template <class _Ty>
requires is_object_v<_Ty>
struct incrementable_traits<_Ty*> {
using difference_type = ptrdiff_t;
};
template <class _Ty>
struct incrementable_traits<const _Ty> : incrementable_traits<_Ty> {};
template <_Has_member_difference_type _Ty>
struct incrementable_traits<_Ty> {
using difference_type = typename _Ty::difference_type;
};
template <class _Ty>
concept _Can_difference = requires(const _Ty& __a, const _Ty& __b) {
{ __a - __b } -> integral;
};
template <class _Ty>
requires (!_Has_member_difference_type<_Ty> && _Can_difference<_Ty>)
struct incrementable_traits<_Ty> {
using difference_type = make_signed_t<decltype(_STD declval<_Ty>() - _STD declval<_Ty>())>;
};
template <class _Ty>
concept _Is_from_primary = _Same_impl<typename _Ty::_From_primary, _Ty>;
_EXPORT_STD template <class>
struct iterator_traits;
_EXPORT_STD template <class _Ty>
using iter_difference_t = typename conditional_t<_Is_from_primary<iterator_traits<remove_cvref_t<_Ty>>>,
incrementable_traits<remove_cvref_t<_Ty>>, iterator_traits<remove_cvref_t<_Ty>>>::difference_type;
template <class>
struct _Cond_value_type {};
template <class _Ty>
requires is_object_v<_Ty>
struct _Cond_value_type<_Ty> {
using value_type = remove_cv_t<_Ty>;
};
_EXPORT_STD template <class>
struct indirectly_readable_traits {};
template <class _Ty>
struct indirectly_readable_traits<_Ty*> : _Cond_value_type<_Ty> {};
template <class _Ty>
requires is_array_v<_Ty>
struct indirectly_readable_traits<_Ty> {
using value_type = remove_cv_t<remove_extent_t<_Ty>>;
};
template <class _Ty>
struct indirectly_readable_traits<const _Ty> : indirectly_readable_traits<_Ty> {};
template <_Has_member_value_type _Ty>
struct indirectly_readable_traits<_Ty> : _Cond_value_type<typename _Ty::value_type> {};
template <_Has_member_element_type _Ty>
struct indirectly_readable_traits<_Ty> : _Cond_value_type<typename _Ty::element_type> {};
template <_Has_member_value_type _Ty>
requires _Has_member_element_type<_Ty>
struct indirectly_readable_traits<_Ty> {};
template <_Has_member_value_type _Ty>
requires _Has_member_element_type<_Ty>
&& same_as<remove_cv_t<typename _Ty::value_type>, remove_cv_t<typename _Ty::element_type>>
struct indirectly_readable_traits<_Ty> : _Cond_value_type<typename _Ty::value_type> {};
_EXPORT_STD template <class _Ty>
using iter_value_t = typename conditional_t<_Is_from_primary<iterator_traits<remove_cvref_t<_Ty>>>,
indirectly_readable_traits<remove_cvref_t<_Ty>>, iterator_traits<remove_cvref_t<_Ty>>>::value_type;
_EXPORT_STD template <_Dereferenceable _Ty>
using iter_reference_t = decltype(*_STD declval<_Ty&>());
template <class>
struct _Iterator_traits_base {};
template <class _It>
concept _Has_iter_types = _Has_member_difference_type<_It> && _Has_member_value_type<_It> && _Has_member_reference<_It>
&& _Has_member_iterator_category<_It>;
template <bool _Has_member_typedef>
struct _Old_iter_traits_pointer {
template <class _It>
using _Apply = typename _It::pointer;
};
template <>
struct _Old_iter_traits_pointer<false> {
template <class>
using _Apply = void;
};
template <_Has_iter_types _It>
struct _Iterator_traits_base<_It> {
using iterator_category = typename _It::iterator_category;
using value_type = typename _It::value_type;
using difference_type = typename _It::difference_type;
using pointer = typename _Old_iter_traits_pointer<_Has_member_pointer<_It>>::template _Apply<_It>;
using reference = typename _It::reference;
};
template <bool _Has_member_typedef>
struct _Iter_traits_difference {
template <class _It>
using _Apply = typename incrementable_traits<_It>::difference_type;
};
template <>
struct _Iter_traits_difference<false> {
template <class>
using _Apply = void;
};
// clang-format off
template <class _It>
concept _Cpp17_iterator =
requires(_It __i) {
{ *__i } -> _Can_reference;
{ ++__i } -> same_as<_It&>;
{ *__i++ } -> _Can_reference;
}
&& copyable<_It>;
template <class _It>
concept _Cpp17_input_iterator = _Cpp17_iterator<_It>
&& equality_comparable<_It>
&& _Has_member_difference_type<incrementable_traits<_It>>
&& _Has_member_value_type<indirectly_readable_traits<_It>>
&& requires(_It __i) {
typename common_reference_t<iter_reference_t<_It>&&, typename indirectly_readable_traits<_It>::value_type&>;
typename common_reference_t<decltype(*__i++)&&, typename indirectly_readable_traits<_It>::value_type&>;
requires signed_integral<typename incrementable_traits<_It>::difference_type>;
};
template <class _It>
requires (!_Has_iter_types<_It> && _Cpp17_iterator<_It> && !_Cpp17_input_iterator<_It>)
struct _Iterator_traits_base<_It> {
using iterator_category = output_iterator_tag;
using value_type = void;
using difference_type =
typename _Iter_traits_difference<_Has_member_difference_type<incrementable_traits<_It>>>::template _Apply<_It>;
using pointer = void;
using reference = void;
};
// clang-format on
enum class _Itraits_pointer_strategy { _Use_void, _Use_member, _Use_decltype };
template <_Itraits_pointer_strategy>
struct _Iter_traits_pointer;
template <>
struct _Iter_traits_pointer<_Itraits_pointer_strategy::_Use_void> {
template <class>
using _Apply = void;
};
template <>
struct _Iter_traits_pointer<_Itraits_pointer_strategy::_Use_member> {
template <class _It>
using _Apply = typename _It::pointer;
};
template <>
struct _Iter_traits_pointer<_Itraits_pointer_strategy::_Use_decltype> {
template <class _It>
using _Apply = decltype(_STD declval<_It&>().operator->());
};
template <class _Ty>
concept _Has_member_arrow = requires(_Ty&& __t) { static_cast<_Ty&&>(__t).operator->(); };
template <bool _Has_member_typedef>
struct _Iter_traits_reference {
template <class _It>
using _Apply = typename _It::reference;
};
template <>
struct _Iter_traits_reference<false> {
template <class _It>
using _Apply = iter_reference_t<_It>;
};
template <bool _Is_random>
struct _Iter_traits_category4 {
using type = random_access_iterator_tag;
};
template <>
struct _Iter_traits_category4<false> {
using type = bidirectional_iterator_tag;
};
// clang-format off
template <class _It>
concept _Cpp17_random_delta = totally_ordered<_It>
&& requires(_It __i, typename incrementable_traits<_It>::difference_type __n) {
{ __i += __n } -> same_as<_It&>;
{ __i -= __n } -> same_as<_It&>;
{ __i + __n } -> same_as<_It>;
{ __n + __i } -> same_as<_It>;
{ __i - __n } -> same_as<_It>;
{ __i - __i } -> same_as<decltype(__n)>;
{ __i[__n] } -> convertible_to<iter_reference_t<_It>>;
};
// clang-format on
template <bool _Is_bidi>
struct _Iter_traits_category3 {
template <class _It>
using _Apply = typename _Iter_traits_category4<_Cpp17_random_delta<_It>>::type;
};
template <>
struct _Iter_traits_category3<false> {
template <class>
using _Apply = forward_iterator_tag;
};
template <class _It>
concept _Cpp17_bidi_delta = requires(_It __i) {
{ --__i } -> same_as<_It&>;
{ __i-- } -> convertible_to<const _It&>;
requires same_as<decltype(*__i--), iter_reference_t<_It>>;
};
template <bool _Is_forward>
struct _Iter_traits_category2 {
template <class _It>
using _Apply = typename _Iter_traits_category3<_Cpp17_bidi_delta<_It>>::template _Apply<_It>;
};
template <>
struct _Iter_traits_category2<false> {
template <class>
using _Apply = input_iterator_tag;
};
// clang-format off
template <class _It>
concept _Cpp17_forward_delta = constructible_from<_It> && is_reference_v<iter_reference_t<_It>>
&& same_as<remove_cvref_t<iter_reference_t<_It>>, typename indirectly_readable_traits<_It>::value_type>
&& requires(_It __i) {
{ __i++ } -> convertible_to<const _It&>;
requires same_as<decltype(*__i++), iter_reference_t<_It>>;
};
// clang-format on
template <bool _Has_member_typedef>
struct _Iter_traits_category {
template <class _It>
using _Apply = typename _It::iterator_category;
};
template <>
struct _Iter_traits_category<false> {
template <class _It>
using _Apply = typename _Iter_traits_category2<_Cpp17_forward_delta<_It>>::template _Apply<_It>;
};
// clang-format off
template <class _It>
requires (!_Has_iter_types<_It> && _Cpp17_input_iterator<_It>)
struct _Iterator_traits_base<_It> {
using iterator_category = typename _Iter_traits_category<_Has_member_iterator_category<_It>>::template _Apply<_It>;
using value_type = typename indirectly_readable_traits<_It>::value_type;
using difference_type = typename incrementable_traits<_It>::difference_type;
using pointer = typename _Iter_traits_pointer<(
_Has_member_pointer<_It> ? _Itraits_pointer_strategy::_Use_member
: _Has_member_arrow<_It&> ? _Itraits_pointer_strategy::_Use_decltype
: _Itraits_pointer_strategy::_Use_void)>::template _Apply<_It>;
using reference = typename _Iter_traits_reference<_Has_member_reference<_It>>::template _Apply<_It>;
};
// clang-format on
_EXPORT_STD template <class _Ty>
struct iterator_traits : _Iterator_traits_base<_Ty> {
using _From_primary = iterator_traits;
};
template <class _Ty>
requires is_object_v<_Ty>
struct iterator_traits<_Ty*> {
using iterator_concept = contiguous_iterator_tag;
using iterator_category = random_access_iterator_tag;
using value_type = remove_cv_t<_Ty>;
using difference_type = ptrdiff_t;
using pointer = _Ty*;
using reference = _Ty&;
};
template <class _Ty>
inline constexpr bool _Integer_class = requires {
typename _Ty::_Signed_type;
typename _Ty::_Unsigned_type;
};
template <class _Ty>
concept _Integer_like = _Is_nonbool_integral<remove_cv_t<_Ty>> || _Integer_class<_Ty>;
template <class _Ty>
concept _Signed_integer_like = _Integer_like<_Ty> && static_cast<_Ty>(-1) < static_cast<_Ty>(0);
// clang-format off
_EXPORT_STD template <class _Ty>
concept weakly_incrementable = movable<_Ty>
&& requires(_Ty __i) {
typename iter_difference_t<_Ty>;
requires _Signed_integer_like<iter_difference_t<_Ty>>;
{ ++__i } -> same_as<_Ty&>;
__i++;
}
#ifdef __clang__ // TRANSITION, LLVM-48173
&& !same_as<_Ty, bool>
#endif // TRANSITION, LLVM-48173
;
_EXPORT_STD template <class _It>
concept input_or_output_iterator = requires(_It __i) { { *__i } -> _Can_reference; }
&& weakly_incrementable<_It>;
_EXPORT_STD template <class _Se, class _It>
concept sentinel_for = semiregular<_Se>
&& input_or_output_iterator<_It>
&& _Weakly_equality_comparable_with<_Se, _It>;
// clang-format on
_EXPORT_STD template <class _Se, class _It>
inline constexpr bool disable_sized_sentinel_for = false;
// clang-format off
_EXPORT_STD template <class _Se, class _It>
concept sized_sentinel_for = sentinel_for<_Se, _It>
&& !disable_sized_sentinel_for<remove_cv_t<_Se>, remove_cv_t<_It>>
&& requires(const _It& __i, const _Se& __s) {
{ __s - __i } -> same_as<iter_difference_t<_It>>;
{ __i - __s } -> same_as<iter_difference_t<_It>>;
};
// clang-format on
_EXPORT_STD struct default_sentinel_t {};
_EXPORT_STD inline constexpr default_sentinel_t default_sentinel{};
namespace ranges {
_EXPORT_STD enum class subrange_kind : bool { unsized, sized };
_EXPORT_STD template <input_or_output_iterator _It, sentinel_for<_It> _Se = _It,
subrange_kind _Ki = sized_sentinel_for<_Se, _It> ? subrange_kind::sized : subrange_kind::unsized>
requires (_Ki == subrange_kind::sized || !sized_sentinel_for<_Se, _It>)
class subrange;
_EXPORT_STD template <size_t _Idx, class _It, class _Se, subrange_kind _Ki>
requires ((_Idx == 0 && copyable<_It>) || _Idx == 1)
_NODISCARD constexpr auto get(const subrange<_It, _Se, _Ki>& _Val);
_EXPORT_STD template <size_t _Idx, class _It, class _Se, subrange_kind _Ki>
requires (_Idx < 2)
_NODISCARD constexpr auto get(subrange<_It, _Se, _Ki>&& _Val);
} // namespace ranges
_EXPORT_STD using ranges::get;
template <class _It, class _Se, ranges::subrange_kind _Ki>
inline constexpr bool _Is_subrange_v<ranges::subrange<_It, _Se, _Ki>> = true;
template <class _It, class _Se, ranges::subrange_kind _Ki>
struct tuple_size<ranges::subrange<_It, _Se, _Ki>> : integral_constant<size_t, 2> {};
template <class _It, class _Se, ranges::subrange_kind _Ki>
struct tuple_element<0, ranges::subrange<_It, _Se, _Ki>> {
using type = _It;
};
template <class _It, class _Se, ranges::subrange_kind _Ki>
struct tuple_element<1, ranges::subrange<_It, _Se, _Ki>> {
using type = _Se;
};
template <class _It, class _Se, ranges::subrange_kind _Ki>
struct tuple_element<0, const ranges::subrange<_It, _Se, _Ki>> {
using type = _It;
};
template <class _It, class _Se, ranges::subrange_kind _Ki>
struct tuple_element<1, const ranges::subrange<_It, _Se, _Ki>> {
using type = _Se;
};
#else // ^^^ defined(__cpp_lib_concepts) / !defined(__cpp_lib_concepts) vvv
template <class, class = void>
struct _Iterator_traits_base {}; // empty for non-iterators
template <class _Iter>
struct _Iterator_traits_base<_Iter,
void_t<typename _Iter::iterator_category, typename _Iter::value_type, typename _Iter::difference_type,
typename _Iter::pointer, typename _Iter::reference>> {
// defined if _Iter::* types exist
using iterator_category = typename _Iter::iterator_category;
using value_type = typename _Iter::value_type;
using difference_type = typename _Iter::difference_type;
using pointer = typename _Iter::pointer;
using reference = typename _Iter::reference;
};
template <class _Ty, bool = is_object_v<_Ty>>
struct _Iterator_traits_pointer_base { // iterator properties for pointers to object
using iterator_category = random_access_iterator_tag;
using value_type = remove_cv_t<_Ty>;
using difference_type = ptrdiff_t;
using pointer = _Ty*;
using reference = _Ty&;
};
template <class _Ty>
struct _Iterator_traits_pointer_base<_Ty, false> {}; // iterator non-properties for pointers to non-object
template <class _Iter>
struct iterator_traits : _Iterator_traits_base<_Iter> {}; // get traits from iterator _Iter, if possible
template <class _Ty>
struct iterator_traits<_Ty*> : _Iterator_traits_pointer_base<_Ty> {}; // get traits from pointer, if possible
#endif // ^^^ !defined(__cpp_lib_concepts) ^^^
_STD_END
#pragma pop_macro("new")
_STL_RESTORE_CLANG_WARNINGS
#pragma warning(pop)
#pragma pack(pop)
#endif // _STL_COMPILER_PREPROCESSOR
#endif // __MSVC_ITER_CORE_HPP