@@ -2261,43 +2261,68 @@ template <typename... Refs> struct enumerator_result<std::size_t, Refs...> {
2261
2261
mutable range_reference_tuple Storage;
2262
2262
};
2263
2263
2264
- // / Infinite stream of increasing 0-based `size_t` indices.
2265
- struct index_stream {
2266
- struct iterator : iterator_facade_base<iterator , std::forward_iterator_tag ,
2267
- const iterator > {
2268
- iterator & operator ++( ) {
2269
- assert (Index != std::numeric_limits<std:: size_t >:: max () &&
2270
- " Attempting to increment end iterator " );
2271
- ++Index ;
2272
- return *this ;
2273
- }
2264
+ struct index_iterator
2265
+ : llvm::iterator_facade_base<index_iterator,
2266
+ std::random_access_iterator_tag , std::size_t ,
2267
+ std:: ptrdiff_t > {
2268
+ index_iterator (std:: size_t Index) : Index(Index ) {}
2269
+
2270
+ index_iterator & operator +=(std:: ptrdiff_t N) {
2271
+ Index += N ;
2272
+ return *this ;
2273
+ }
2274
2274
2275
- // Note: This dereference operator returns a value instead of a reference
2276
- // and does not strictly conform to the C++17's definition of forward
2277
- // iterator. However, it satisfies all the forward_iterator requirements
2278
- // that the `zip_common` depends on and fully conforms to the C++20
2279
- // definition of forward iterator.
2280
- std::size_t operator *() const { return Index; }
2275
+ index_iterator &operator -=(std::ptrdiff_t N) {
2276
+ Index -= N;
2277
+ return *this ;
2278
+ }
2281
2279
2282
- friend bool operator == (const iterator &Lhs, const iterator &Rhs) {
2283
- return Lhs. Index == Rhs .Index ;
2284
- }
2280
+ std:: ptrdiff_t operator - (const index_iterator &R) const {
2281
+ return Index - R .Index ;
2282
+ }
2285
2283
2286
- std::size_t Index = 0 ;
2287
- };
2284
+ // Note: This dereference operator returns a value instead of a reference
2285
+ // and does not strictly conform to the C++17's definition of forward
2286
+ // iterator. However, it satisfies all the forward_iterator requirements
2287
+ // that the `zip_common` depends on and fully conforms to the C++20
2288
+ // definition of forward iterator.
2289
+ std::size_t operator *() const { return Index; }
2288
2290
2289
- iterator begin () const { return {}; }
2290
- iterator end () const {
2291
+ friend bool operator ==(const index_iterator &Lhs, const index_iterator &Rhs) {
2292
+ return Lhs.Index == Rhs.Index ;
2293
+ }
2294
+
2295
+ friend bool operator <(const index_iterator &Lhs, const index_iterator &Rhs) {
2296
+ return Lhs.Index < Rhs.Index ;
2297
+ }
2298
+
2299
+ private:
2300
+ std::size_t Index;
2301
+ };
2302
+
2303
+ // / Infinite stream of increasing 0-based `size_t` indices.
2304
+ struct index_stream {
2305
+ index_iterator begin () const { return {0 }; }
2306
+ index_iterator end () const {
2291
2307
// We approximate 'infinity' with the max size_t value, which should be good
2292
2308
// enough to index over any container.
2293
- iterator It;
2294
- It.Index = std::numeric_limits<std::size_t >::max ();
2295
- return It;
2309
+ return index_iterator{std::numeric_limits<std::size_t >::max ()};
2296
2310
}
2297
2311
};
2298
2312
2299
2313
} // end namespace detail
2300
2314
2315
+ // / Increasing range of `size_t` indices.
2316
+ class index_range {
2317
+ std::size_t Begin;
2318
+ std::size_t End;
2319
+
2320
+ public:
2321
+ index_range (std::size_t Begin, std::size_t End) : Begin(Begin), End(End) {}
2322
+ detail::index_iterator begin () const { return {Begin}; }
2323
+ detail::index_iterator end () const { return {End}; }
2324
+ };
2325
+
2301
2326
// / Given two or more input ranges, returns a new range whose values are are
2302
2327
// / tuples (A, B, C, ...), such that A is the 0-based index of the item in the
2303
2328
// / sequence, and B, C, ..., are the values from the original input ranges. All
0 commit comments