1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #ifndef PANDA_VERIFICATION_UTIL_RANGE_H_
17 #define PANDA_VERIFICATION_UTIL_RANGE_H_
18
19 #include <limits>
20 #include <string>
21 #include <algorithm>
22 #include <iterator>
23
24 namespace panda::verifier {
25
26 template <typename... T>
27 class Range;
28
29 template <typename Int>
30 class Range<Int> {
31 public:
32 class Iterator {
33 public:
34 typedef Int value_type;
35 typedef Int *pointer;
36 typedef Int &reference;
37 typedef std::make_signed_t<Int> difference_type;
38 typedef std::forward_iterator_tag iterator_category;
39
Iterator(const Int val)40 Iterator(const Int val) : Val_ {val} {}
41 Iterator() = default;
42 Iterator(const Iterator &) = default;
43 Iterator(Iterator &&) = default;
44 Iterator &operator=(const Iterator &) = default;
45 Iterator &operator=(Iterator &&) = default;
46 ~Iterator() = default;
47
48 Iterator operator++(int)
49 {
50 Iterator old {*this};
51 ++Val_;
52 return old;
53 }
54
55 Iterator &operator++()
56 {
57 ++Val_;
58 return *this;
59 }
60
61 Iterator operator--(int)
62 {
63 Iterator old {*this};
64 --Val_;
65 return old;
66 }
67
68 Iterator &operator--()
69 {
70 --Val_;
71 return *this;
72 }
73
74 bool operator==(const Iterator &rhs)
75 {
76 return Val_ == rhs.Val_;
77 }
78
79 bool operator!=(const Iterator &rhs)
80 {
81 return Val_ != rhs.Val_;
82 }
83
84 Int operator*()
85 {
86 return Val_;
87 }
88
89 private:
90 Int Val_ = std::numeric_limits<Int>::min();
91 };
92
93 template <typename Container>
Range(const Container & cont)94 Range(const Container &cont) : From_ {0}, To_ {cont.size() - 1}
95 {
96 }
97
Range(const Int from,const Int to)98 Range(const Int from, const Int to) : From_ {std::min(from, to)}, To_ {std::max(from, to)} {}
99 Range() = default;
100 ~Range() = default;
101
begin()102 Iterator begin() const
103 {
104 return {From_};
105 }
106
cbegin()107 Iterator cbegin() const
108 {
109 return {From_};
110 }
111
end()112 Iterator end() const
113 {
114 return {To_ + 1};
115 }
116
cend()117 Iterator cend() const
118 {
119 return {To_ + 1};
120 }
121
BasedAt(Int point)122 Range BasedAt(Int point) const
123 {
124 return Range {point, point + To_ - From_};
125 }
126
Contains(Int point)127 bool Contains(Int point) const
128 {
129 return point >= From_ && point <= To_;
130 }
131
PutInBounds(Int point)132 Int PutInBounds(Int point) const
133 {
134 if (point < From_) {
135 return From_;
136 }
137 if (point > To_) {
138 return To_;
139 }
140 return point;
141 }
142
Length()143 size_t Length() const
144 {
145 return To_ - From_ + 1;
146 }
147
OffsetOf(Int val)148 Int OffsetOf(Int val) const
149 {
150 return val - From_;
151 }
152
IndexOf(Int offset)153 Int IndexOf(Int offset) const
154 {
155 return offset + From_;
156 }
157
Start()158 Int Start() const
159 {
160 return From_;
161 }
162
End()163 Int End() const
164 {
165 return To_;
166 }
167
168 bool operator==(const Range &rhs) const
169 {
170 return From_ == rhs.From_ && To_ == rhs.To_;
171 }
172
173 private:
174 Int From_;
175 Int To_;
176 };
177
178 template <typename Int>
179 Range(Int, Int, typename std::enable_if<std::is_integral<Int>::value, bool>::type b = true)->Range<Int>;
180
181 } // namespace panda::verifier
182
183 namespace std {
184
185 template <typename Int>
to_string(const panda::verifier::Range<Int> & range)186 string to_string(const panda::verifier::Range<Int> &range)
187 {
188 return string {"[ "} + to_string(range.Start()) + " .. " + to_string(range.End()) + " ]";
189 }
190
191 } // namespace std
192
193 #endif // PANDA_VERIFICATION_UTIL_RANGE_H_
194