/Users/deen/code/yugabyte-db/src/yb/util/range.h
Line | Count | Source |
1 | | // Copyright (c) YugaByte, Inc. |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
4 | | // in compliance with the License. You may obtain a copy of the License at |
5 | | // |
6 | | // http://www.apache.org/licenses/LICENSE-2.0 |
7 | | // |
8 | | // Unless required by applicable law or agreed to in writing, software distributed under the License |
9 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
10 | | // or implied. See the License for the specific language governing permissions and limitations |
11 | | // under the License. |
12 | | // |
13 | | |
14 | | #ifndef YB_UTIL_RANGE_H |
15 | | #define YB_UTIL_RANGE_H |
16 | | |
17 | | namespace yb { |
18 | | |
19 | | template <class It, class Container> |
20 | | class ContainerRangeIterator { |
21 | | public: |
22 | | ContainerRangeIterator(It iterator, const Container& container) |
23 | | : iterator_(iterator), container_(&container) {} |
24 | | |
25 | | auto& operator*() const { |
26 | | return (*container_)[*iterator_]; |
27 | | } |
28 | | |
29 | | ContainerRangeIterator& operator++() { |
30 | | ++iterator_; |
31 | | return *this; |
32 | | } |
33 | | |
34 | | ContainerRangeIterator operator++(int) { |
35 | | ContainerRangeIterator result = *this; |
36 | | ++iterator_; |
37 | | return result; |
38 | | } |
39 | | |
40 | | private: |
41 | | friend bool operator==(const ContainerRangeIterator<It, Container>& lhs, |
42 | | const ContainerRangeIterator<It, Container>& rhs) { |
43 | | return lhs.iterator_ == rhs.iterator_; |
44 | | } |
45 | | |
46 | | friend bool operator!=(const ContainerRangeIterator<It, Container>& lhs, |
47 | | const ContainerRangeIterator<It, Container>& rhs) { |
48 | | return lhs.iterator_ != rhs.iterator_; |
49 | | } |
50 | | |
51 | | It iterator_; |
52 | | const Container* container_; |
53 | | }; |
54 | | |
55 | | template <class Range, class Container> |
56 | | class ContainerRangeObject { |
57 | | public: |
58 | | ContainerRangeObject(const Range& range, const Container& container) |
59 | | : range_(range), container_(&container) {} |
60 | | |
61 | | using const_iterator = ContainerRangeIterator<typename Range::const_iterator, Container>; |
62 | | |
63 | | const_iterator begin() const { |
64 | | return const_iterator(range_.begin(), *container_); |
65 | | } |
66 | | |
67 | | const_iterator end() const { |
68 | | return const_iterator(range_.end(), *container_); |
69 | | } |
70 | | |
71 | | private: |
72 | | Range range_; |
73 | | const Container* container_; |
74 | | }; |
75 | | |
76 | | template <class Int> |
77 | | class RangeIterator : public std::iterator<std::random_access_iterator_tag, Int> { |
78 | | public: |
79 | 10.1M | RangeIterator(Int pos, Int step) : pos_(pos), step_(step) {} |
80 | | |
81 | 6.48M | Int operator*() const { |
82 | 6.48M | return pos_; |
83 | 6.48M | } |
84 | | |
85 | 1.41M | RangeIterator& operator++() { |
86 | 1.41M | pos_ += step_; |
87 | 1.41M | return *this; |
88 | 1.41M | } |
89 | | |
90 | | RangeIterator operator++(int) { |
91 | | RangeIterator result = *this; |
92 | | pos_ += step_; |
93 | | return result; |
94 | | } |
95 | | |
96 | | private: |
97 | | friend bool operator==(const RangeIterator<Int>& lhs, const RangeIterator<Int>& rhs) { |
98 | | return lhs.pos_ == rhs.pos_; |
99 | | } |
100 | | |
101 | 6.48M | friend bool operator!=(const RangeIterator<Int>& lhs, const RangeIterator<Int>& rhs) { |
102 | 6.48M | return lhs.pos_ != rhs.pos_; |
103 | 6.48M | } |
104 | | |
105 | | Int pos_; |
106 | | Int step_; |
107 | | }; |
108 | | |
109 | | template <class Int> |
110 | | class RangeObject { |
111 | | public: |
112 | | using const_iterator = RangeIterator<Int>; |
113 | | |
114 | | RangeObject(Int start, Int stop, Int step) |
115 | 5.07M | : start_(start), stop_(start + (stop - start + step - 1) / step * step), step_(step) {} |
116 | | |
117 | 5.07M | const_iterator begin() const { |
118 | 5.07M | return const_iterator(start_, step_); |
119 | 5.07M | } |
120 | | |
121 | 5.07M | const_iterator end() const { |
122 | 5.07M | return const_iterator(stop_, step_); |
123 | 5.07M | } |
124 | | |
125 | | template <class T> |
126 | | auto operator[](const T& container) const { |
127 | | return ContainerRangeObject<RangeObject<Int>, T>(*this, container); |
128 | | } |
129 | | |
130 | | private: |
131 | | Int start_; |
132 | | Int stop_; |
133 | | Int step_; |
134 | | }; |
135 | | |
136 | | // Useful to iterate over range of ints. Especially if we should repeat this iteration several |
137 | | // times like we do in tests. |
138 | | template<class Int> |
139 | 5.07M | RangeObject<Int> Range(Int stop) { |
140 | 5.07M | return RangeObject<Int>(0, stop, 1); |
141 | 5.07M | } |
142 | | |
143 | | template<class Int> |
144 | | RangeObject<Int> Range(Int start, Int stop, Int step = 1) { |
145 | | return RangeObject<Int>(start, stop, step); |
146 | | } |
147 | | |
148 | | template<class Int> |
149 | | RangeObject<Int> RangeOfSize(Int start, Int size, Int step = 1) { |
150 | | return RangeObject<Int>(start, start + size, step); |
151 | | } |
152 | | |
153 | | } // namespace yb |
154 | | |
155 | | #endif // YB_UTIL_RANGE_H |