File: test_iterators.hpp

package info (click to toggle)
range-v3 0.12.0-1.1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 5,620 kB
  • sloc: cpp: 76,839; xml: 226; sh: 89; python: 34; makefile: 16; perl: 15
file content (447 lines) | stat: -rw-r--r-- 14,123 bytes parent folder | download | duplicates (3)
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
//===----------------------------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef RANGES_TEST_ITERATORS_HPP
#define RANGES_TEST_ITERATORS_HPP

#include <iterator>
#include <range/v3/range/dangling.hpp>

template<class It, bool Sized = false>
class Sentinel;

template<class It>
class OutputIterator;

template<class It, bool Sized = false>
class InputIterator;

template<class It, bool Sized = false>
class ForwardIterator;

template<class It, bool Sized = false>
class BidirectionalIterator;

template<class It>
class RandomAccessIterator;


template<class Iter, bool Sized>
constexpr /*c++14*/ Iter base(Sentinel<Iter, Sized> i) { return i.base(); }

template<class Iter>
constexpr /*c++14*/ Iter base(OutputIterator<Iter> i) { return i.base(); }

template<class Iter, bool Sized>
constexpr /*c++14*/ Iter base(InputIterator<Iter, Sized> i) { return i.base(); }

template<class Iter, bool Sized>
constexpr /*c++14*/ Iter base(ForwardIterator<Iter, Sized> i) { return i.base(); }

template<class Iter, bool Sized>
constexpr /*c++14*/ Iter base(BidirectionalIterator<Iter, Sized> i) { return i.base(); }

template<class Iter>
constexpr /*c++14*/ Iter base(RandomAccessIterator<Iter> i) { return i.base(); }

template<class Iter>    // everything else
constexpr /*c++14*/ Iter base(Iter i) { return i; }


template<class It, bool Sized>
class Sentinel
{
    It it_;
public:
    constexpr /*c++14*/ Sentinel() : it_() {}
    constexpr /*c++14*/ explicit Sentinel(It it) : it_(it) {}
    constexpr /*c++14*/ It base() const { return it_; }
    constexpr /*c++14*/ friend bool operator==(const Sentinel& x, const Sentinel& y)
    {
        RANGES_ENSURE(x.it_ == y.it_);
        return true;
    }
    constexpr /*c++14*/ friend bool operator!=(const Sentinel& x, const Sentinel& y)
    {
        RANGES_ENSURE(x.it_ == y.it_);
        return false;
    }
    template<typename I>
    constexpr /*c++14*/ friend bool operator==(const I& x, const Sentinel& y)
    {
        using ::base;
        return base(x) == y.it_;
    }
    template<typename I>
    constexpr /*c++14*/ friend bool operator!=(const I& x, const Sentinel& y)
    {
        return !(x == y);
    }
    template<typename I>
    constexpr /*c++14*/ friend bool operator==(const Sentinel& x, const I& y)
    {
        using ::base;
        return x.it_ == base(y);
    }
    template<typename I>
    constexpr /*c++14*/ friend bool operator!=(const Sentinel& x, const I& y)
    {
        return !(x == y);
    }
};

// For making sized iterator ranges:
template<template<typename> class I, typename It>
constexpr /*c++14*/
auto CPP_auto_fun(operator-)(Sentinel<It, true> last, I<It> first)
(
    return base(last) - base(first)
)
template<template<typename> class I, typename It>
constexpr /*c++14*/
auto CPP_auto_fun(operator-)(I<It> first, Sentinel<It, true> last)
(
    return base(first) - base(last)
)

template<class It>
class OutputIterator
{
    It it_;

    template<class U> friend class OutputIterator;
public:
    typedef          std::output_iterator_tag                  iterator_category;
    typedef void                                               value_type;
    typedef typename std::iterator_traits<It>::difference_type difference_type;
    typedef It                                                 pointer;
    typedef typename std::iterator_traits<It>::reference       reference;

    constexpr /*c++14*/ It base() const {return it_;}

    constexpr /*c++14*/ OutputIterator () {}
    constexpr /*c++14*/ explicit OutputIterator(It it) : it_(it) {}
    template<class U, class = typename std::enable_if<std::is_convertible<U, It>{}>::type>
    constexpr /*c++14*/
    OutputIterator(const OutputIterator<U>& u) :it_(u.it_) {}

    constexpr /*c++14*/ reference operator*() const {return *it_;}

    constexpr /*c++14*/ OutputIterator& operator++() {++it_; return *this;}
    constexpr /*c++14*/ OutputIterator operator++(int)
    {OutputIterator tmp(*this); ++(*this); return tmp;}
};

template<class It, bool Sized>
class InputIterator
{
    It it_;

    template<class, bool> friend class InputIterator;
public:
    typedef          std::input_iterator_tag                   iterator_category;
    typedef typename std::iterator_traits<It>::value_type      value_type;
    typedef typename std::iterator_traits<It>::difference_type difference_type;
    typedef It                                                 pointer;
    typedef typename std::iterator_traits<It>::reference       reference;

    constexpr /*c++14*/ It base() const {return it_;}

    constexpr /*c++14*/ InputIterator() : it_() {}
    constexpr /*c++14*/ explicit InputIterator(It it) : it_(it) {}
    template<class U, bool USized>
    constexpr /*c++14*/ CPP_ctor(InputIterator)(const InputIterator<U, USized>& u)(
        requires (std::is_convertible<U, It>::value)) :it_(u.it_) {}

    constexpr /*c++14*/ reference operator*() const {return *it_;}
    constexpr /*c++14*/ pointer operator->() const {return it_;}

    constexpr /*c++14*/ InputIterator& operator++() {++it_; return *this;}
    constexpr /*c++14*/ InputIterator operator++(int)
        {InputIterator tmp(*this); ++(*this); return tmp;}

    constexpr /*c++14*/
    friend bool operator==(const InputIterator& x, const InputIterator& y)
        {return x.it_ == y.it_;}
    constexpr /*c++14*/
    friend bool operator!=(const InputIterator& x, const InputIterator& y)
        {return !(x == y);}

    template<bool B = Sized, meta::if_c<B, int> = 42>
    constexpr /*c++14*/
    friend difference_type operator-(const InputIterator& x, const InputIterator& y)
        {return x.it_ - y.it_;}
};

template<class T, bool TSized, class U, bool USized>
constexpr /*c++14*/
bool
operator==(const InputIterator<T, TSized>& x, const InputIterator<U, USized>& y)
{
    return x.base() == y.base();
}

template<class T, bool TSized, class U, bool USized>
constexpr /*c++14*/
bool
operator!=(const InputIterator<T, TSized>& x, const InputIterator<U, USized>& y)
{
    return !(x == y);
}

template<class It, bool Sized>
class ForwardIterator
{
    It it_;

    template<class, bool> friend class ForwardIterator;
public:
    typedef          std::forward_iterator_tag                 iterator_category;
    typedef typename std::iterator_traits<It>::value_type      value_type;
    typedef typename std::iterator_traits<It>::difference_type difference_type;
    typedef It                                                 pointer;
    typedef typename std::iterator_traits<It>::reference       reference;

    constexpr /*c++14*/ It base() const {return it_;}

    constexpr /*c++14*/ ForwardIterator() : it_() {}
    constexpr /*c++14*/ explicit ForwardIterator(It it) : it_(it) {}
    template<class U, bool USized>
    constexpr /*c++14*/ CPP_ctor(ForwardIterator)(const ForwardIterator<U, USized>& u)(
        requires (std::is_convertible<U, It>::value)) :it_(u.it_) {}

    constexpr /*c++14*/ reference operator*() const {return *it_;}
    constexpr /*c++14*/ pointer operator->() const {return it_;}

    constexpr /*c++14*/ ForwardIterator& operator++() {++it_; return *this;}
    constexpr /*c++14*/ ForwardIterator operator++(int)
    {ForwardIterator tmp(*this); ++(*this); return tmp;}

    constexpr /*c++14*/
    friend bool operator==(const ForwardIterator& x, const ForwardIterator& y)
    {return x.it_ == y.it_;}
    constexpr /*c++14*/
    friend bool operator!=(const ForwardIterator& x, const ForwardIterator& y)
    {return !(x == y);}
};

template<class T, bool TSized, class U, bool USized>
constexpr /*c++14*/
bool
operator==(const ForwardIterator<T, TSized>& x, const ForwardIterator<U, USized>& y)
{
    return x.base() == y.base();
}

template<class T, bool TSized, class U, bool USized>
constexpr /*c++14*/
bool
operator!=(const ForwardIterator<T, TSized>& x, const ForwardIterator<U, USized>& y)
{
    return !(x == y);
}

template<class It, bool Sized>
class BidirectionalIterator
{
    It it_;

    template<class, bool> friend class BidirectionalIterator;
public:
    typedef          std::bidirectional_iterator_tag           iterator_category;
    typedef typename std::iterator_traits<It>::value_type      value_type;
    typedef typename std::iterator_traits<It>::difference_type difference_type;
    typedef It                                                 pointer;
    typedef typename std::iterator_traits<It>::reference       reference;

    constexpr /*c++14*/ It base() const {return it_;}

    constexpr /*c++14*/ BidirectionalIterator() : it_() {}
    constexpr /*c++14*/ explicit BidirectionalIterator(It it) : it_(it) {}
    template<class U, bool USized>
    constexpr /*c++14*/ CPP_ctor(BidirectionalIterator)(const BidirectionalIterator<U, USized>& u)(
        requires (std::is_convertible<U, It>::value)) :it_(u.it_) {}

    constexpr /*c++14*/ reference operator*() const {return *it_;}
    constexpr /*c++14*/ pointer operator->() const {return it_;}

    constexpr /*c++14*/ BidirectionalIterator& operator++() {++it_; return *this;}
    constexpr /*c++14*/ BidirectionalIterator operator++(int)
    {BidirectionalIterator tmp(*this); ++(*this); return tmp;}

    constexpr /*c++14*/ BidirectionalIterator& operator--() {--it_; return *this;}
    constexpr /*c++14*/ BidirectionalIterator operator--(int)
    {BidirectionalIterator tmp(*this); --(*this); return tmp;}
};

template<class T, bool TSized, class U, bool USized>
constexpr /*c++14*/
bool
operator==(const BidirectionalIterator<T, TSized>& x, const BidirectionalIterator<U, USized>& y)
{
    return x.base() == y.base();
}

template<class T, bool TSized, class U, bool USized>
constexpr /*c++14*/
bool
operator!=(const BidirectionalIterator<T, TSized>& x, const BidirectionalIterator<U, USized>& y)
{
    return !(x == y);
}

template<class It>
class RandomAccessIterator
{
    It it_;

    template<class U> friend class RandomAccessIterator;
public:
    typedef          std::random_access_iterator_tag           iterator_category;
    typedef typename std::iterator_traits<It>::value_type      value_type;
    typedef typename std::iterator_traits<It>::difference_type difference_type;
    typedef It                                                 pointer;
    typedef typename std::iterator_traits<It>::reference       reference;

    constexpr /*c++14*/ It base() const {return it_;}

    constexpr /*c++14*/ RandomAccessIterator() : it_() {}
    constexpr /*c++14*/ explicit RandomAccessIterator(It it) : it_(it) {}
    template<class U>
    constexpr /*c++14*/ CPP_ctor(RandomAccessIterator)(const RandomAccessIterator<U>& u)(
        requires (std::is_convertible<U, It>::value)) :it_(u.it_) {}

    constexpr /*c++14*/ reference operator*() const {return *it_;}
    constexpr /*c++14*/ pointer operator->() const {return it_;}

    constexpr /*c++14*/ RandomAccessIterator& operator++() {++it_; return *this;}
    constexpr /*c++14*/ RandomAccessIterator operator++(int)
    {RandomAccessIterator tmp(*this); ++(*this); return tmp;}

    constexpr /*c++14*/ RandomAccessIterator& operator--() {--it_; return *this;}
    constexpr /*c++14*/ RandomAccessIterator operator--(int)
    {RandomAccessIterator tmp(*this); --(*this); return tmp;}

    constexpr /*c++14*/
    RandomAccessIterator& operator+=(difference_type n) {it_ += n; return *this;}
    constexpr /*c++14*/
    RandomAccessIterator operator+(difference_type n) const
    {RandomAccessIterator tmp(*this); tmp += n; return tmp;}
    constexpr /*c++14*/
    friend RandomAccessIterator operator+(difference_type n, RandomAccessIterator x)
    {x += n; return x;}
    constexpr /*c++14*/
    RandomAccessIterator& operator-=(difference_type n) {return *this += -n;}
    constexpr /*c++14*/
    RandomAccessIterator operator-(difference_type n) const
    {RandomAccessIterator tmp(*this); tmp -= n; return tmp;}

    constexpr /*c++14*/
    reference operator[](difference_type n) const {return it_[n];}
};

template<class T, class U>
constexpr /*c++14*/
bool
operator==(const RandomAccessIterator<T>& x, const RandomAccessIterator<U>& y)
{
    return x.base() == y.base();
}

template<class T, class U>
constexpr /*c++14*/
bool
operator!=(const RandomAccessIterator<T>& x, const RandomAccessIterator<U>& y)
{
    return !(x == y);
}

template<class T, class U>
constexpr /*c++14*/
bool
operator<(const RandomAccessIterator<T>& x, const RandomAccessIterator<U>& y)
{
    return x.base() < y.base();
}

template<class T, class U>
constexpr /*c++14*/
bool
operator<=(const RandomAccessIterator<T>& x, const RandomAccessIterator<U>& y)
{
    return !(y < x);
}

template<class T, class U>
constexpr /*c++14*/
bool
operator>(const RandomAccessIterator<T>& x, const RandomAccessIterator<U>& y)
{
    return y < x;
}

template<class T, class U>
constexpr /*c++14*/
bool
operator>=(const RandomAccessIterator<T>& x, const RandomAccessIterator<U>& y)
{
    return !(x < y);
}

template<class T, class U>
constexpr /*c++14*/
auto CPP_auto_fun(operator-)(const RandomAccessIterator<T>& x, const RandomAccessIterator<U>& y)
(
    return x.base() - y.base()
)

template<typename It, bool Sized = false>
struct sentinel_type
{
    using type = It;
};

template<typename T, bool Sized>
struct sentinel_type<T*, Sized>
{
    using type = Sentinel<T*, Sized>;
};

template<template<typename> class I, typename It, bool Sized>
struct sentinel_type<I<It>, Sized>
{
    using type = Sentinel<It, Sized>;
};

template<class I, class S>
struct TestRange
{
    I first;
    S second;
    constexpr I begin() const { return first; }
    constexpr S end() const { return second; }
};

template<class I, class S>
TestRange<I, S> MakeTestRange(I i, S s)
{
    return {i, s};
}

template<typename T>
constexpr bool is_dangling(T)
{
    return false;
}
constexpr bool is_dangling(::ranges::dangling)
{
    return true;
}

#endif  // RANGES_TEST_ITERATORS_HPP