1 /**
2 * Copyright (c) 2021-2022 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_VERIFIER_UTIL_RANGE_HPP_
17 #define PANDA_VERIFIER_UTIL_RANGE_HPP_
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 Iterator operator++(int)
48 {
49 Iterator old {*this};
50 ++Val_;
51 return old;
52 }
53 Iterator &operator++()
54 {
55 ++Val_;
56 return *this;
57 }
58 Iterator operator--(int)
59 {
60 Iterator old {*this};
61 --Val_;
62 return old;
63 }
64 Iterator &operator--()
65 {
66 --Val_;
67 return *this;
68 }
69 bool operator==(const Iterator &rhs)
70 {
71 return Val_ == rhs.Val_;
72 }
73 bool operator!=(const Iterator &rhs)
74 {
75 return Val_ != rhs.Val_;
76 }
77 Int operator*()
78 {
79 return Val_;
80 }
81
82 private:
83 Int Val_ = std::numeric_limits<Int>::min();
84 };
85 template <typename Container>
Range(const Container & cont)86 Range(const Container &cont) : From_ {0}, To_ {cont.size() - 1}
87 {
88 }
Range(const Int from,const Int to)89 Range(const Int from, const Int to) : From_ {std::min(from, to)}, To_ {std::max(from, to)} {}
90 Range() = default;
91 ~Range() = default;
begin()92 Iterator begin() const
93 {
94 return {From_};
95 }
cbegin()96 Iterator cbegin() const
97 {
98 return {From_};
99 }
end()100 Iterator end() const
101 {
102 return {To_ + 1};
103 }
cend()104 Iterator cend() const
105 {
106 return {To_ + 1};
107 }
BasedAt(Int point)108 Range BasedAt(Int point) const
109 {
110 return Range {point, point + To_ - From_};
111 }
Contains(Int point)112 bool Contains(Int point) const
113 {
114 return point >= From_ && point <= To_;
115 }
PutInBounds(Int point)116 Int PutInBounds(Int point) const
117 {
118 if (point < From_) {
119 return From_;
120 }
121 if (point > To_) {
122 return To_;
123 }
124 return point;
125 }
Length()126 size_t Length() const
127 {
128 return To_ - From_ + 1;
129 }
OffsetOf(Int val)130 Int OffsetOf(Int val) const
131 {
132 return val - From_;
133 }
IndexOf(Int offset)134 Int IndexOf(Int offset) const
135 {
136 return offset + From_;
137 }
Start()138 Int Start() const
139 {
140 return From_;
141 }
End()142 Int End() const
143 {
144 return To_;
145 }
146 bool operator==(const Range &rhs) const
147 {
148 return From_ == rhs.From_ && To_ == rhs.To_;
149 }
150
151 private:
152 Int From_;
153 Int To_;
154 };
155
156 template <typename Int>
157 Range(Int, Int, typename std::enable_if<std::is_integral<Int>::value, bool>::type b = true)->Range<Int>;
158 } // namespace panda::verifier
159
160 namespace std {
161 template <typename Int>
to_string(const panda::verifier::Range<Int> & range)162 string to_string(const panda::verifier::Range<Int> &range)
163 {
164 return string {"[ "} + to_string(range.Start()) + " .. " + to_string(range.End()) + " ]";
165 }
166 } // namespace std
167
168 #endif // !PANDA_VERIFIER_UTIL_RANGE_HPP_
169