1 | //===- iterator_range.h - A range adaptor for iterators ---------*- C++ -*-===// |
2 | // |
3 | // The LLVM Compiler Infrastructure |
4 | // |
5 | // This file is distributed under the University of Illinois Open Source |
6 | // License. See LICENSE.TXT for details. |
7 | // |
8 | //===----------------------------------------------------------------------===// |
9 | /// \file |
10 | /// This provides a very simple, boring adaptor for a begin and end iterator |
11 | /// into a range type. This should be used to build range views that work well |
12 | /// with range based for loops and range based constructors. |
13 | /// |
14 | /// Note that code here follows more standards-based coding conventions as it |
15 | /// is mirroring proposed interfaces for standardization. |
16 | /// |
17 | //===----------------------------------------------------------------------===// |
18 | |
19 | #ifndef LLVM_ADT_ITERATOR_RANGE_H |
20 | #define LLVM_ADT_ITERATOR_RANGE_H |
21 | |
22 | #include <iterator> |
23 | #include <utility> |
24 | |
25 | namespace llvm { |
26 | |
27 | /// A range adaptor for a pair of iterators. |
28 | /// |
29 | /// This just wraps two iterators into a range-compatible interface. Nothing |
30 | /// fancy at all. |
31 | template <typename IteratorT> |
32 | class iterator_range { |
33 | IteratorT begin_iterator, end_iterator; |
34 | |
35 | public: |
36 | //TODO: Add SFINAE to test that the Container's iterators match the range's |
37 | // iterators. |
38 | template <typename Container> |
39 | iterator_range(Container &&c) |
40 | //TODO: Consider ADL/non-member begin/end calls. |
41 | : begin_iterator(c.begin()), end_iterator(c.end()) {} |
42 | iterator_range(IteratorT begin_iterator, IteratorT end_iterator) |
43 | : begin_iterator(std::move(begin_iterator)), |
44 | end_iterator(std::move(end_iterator)) {} |
45 | |
46 | IteratorT begin() const { return begin_iterator; } |
47 | IteratorT end() const { return end_iterator; } |
48 | }; |
49 | |
50 | /// Convenience function for iterating over sub-ranges. |
51 | /// |
52 | /// This provides a bit of syntactic sugar to make using sub-ranges |
53 | /// in for loops a bit easier. Analogous to std::make_pair(). |
54 | template <class T> iterator_range<T> make_range(T x, T y) { |
55 | return iterator_range<T>(std::move(x), std::move(y)); |
56 | } |
57 | |
58 | template <typename T> iterator_range<T> make_range(std::pair<T, T> p) { |
59 | return iterator_range<T>(std::move(p.first), std::move(p.second)); |
60 | } |
61 | |
62 | template <typename T> |
63 | iterator_range<decltype(adl_begin(std::declval<T>()))> drop_begin(T &&t, |
64 | int n) { |
65 | return make_range(std::next(adl_begin(t), n), adl_end(t)); |
66 | } |
67 | } |
68 | |
69 | #endif |
70 | |