change the path that i track from two separate paths to one.
[gem5.git] / base / range.hh
1 /*
2 * Copyright (c) 2003 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #ifndef __RANGE_HH__
30 #define __RANGE_HH__
31
32 #include <assert.h>
33
34 #include "base/intmath.hh"
35 #include "base/str.hh"
36
37 template<class T>
38 class Range
39 {
40 private:
41 bool valid;
42
43 public:
44 T start;
45 T end;
46
47 public:
48 Range() {}
49
50 Range(const Range &r) { operator=(r); }
51
52 Range(const T& s, const T& e)
53 : start(s), end(e)
54 {
55 valid = (start <= end);
56 }
57
58 Range(const std::string &s) { valid = parse(s); }
59
60 ~Range() {}
61
62 int compare(const T &p);
63 bool parse(const std::string &s);
64 const Range &operator=(const Range &r);
65
66 bool isValid() const { return valid; }
67 };
68
69
70 template<class T>
71 inline int
72 Range<T>::compare(const T &p)
73 {
74 assert(isValid());
75
76 if (p < start)
77 return -1;
78 else if (p > end)
79 return 1;
80 else
81 return 0;
82 }
83
84 // Parse a range string
85 //
86 // Ranges are in the following format:
87 // <range> := {<start_val>}:{<end>}
88 // <end> := <end_val> | +<delta>
89 template<class T>
90 inline bool
91 Range<T>::parse(const std::string &str)
92 {
93 std::vector<std::string> values;
94 tokenize(values, str, ':');
95
96 T thestart, theend;
97
98 if (values.size() != 2)
99 return false;
100
101 std::string s = values[0];
102 std::string e = values[1];
103
104 if (!to_number(s, thestart))
105 return false;
106
107 bool increment = (e[0] == '+');
108 if (increment)
109 e = e.substr(1);
110
111 if (!to_number(e, theend))
112 return false;
113
114 if (increment)
115 theend += thestart;
116
117 start = thestart;
118 end = theend;
119
120 if (start > end)
121 return false;
122
123 return true;
124 }
125
126
127 template<class T>
128 inline const Range<T> &
129 Range<T>::operator=(const Range<T> &r)
130 {
131 if (this != &r) {
132 start = r.start;
133 end = r.end;
134
135 valid = r.valid;
136 }
137 else {
138 valid = false;
139 }
140
141 return *this;
142 }
143
144 template<class T>
145 inline std::ostream &
146 operator<<(std::ostream &o, const Range<T> &r)
147 {
148 // don't currently support output of invalid ranges
149 assert(r.isValid());
150 o << r.start << ":" << r.end;
151 return o;
152 }
153
154 //////////////////////////////////////////
155 //
156 // Compare two ranges
157 //
158 template<class T>
159 inline bool
160 operator==(const Range<T> &l, const Range<T> &r)
161 {
162 // ranges must both be valid to be equal
163 return (l.isValid() && r.isValid() &&
164 (l.start == r.start) && (l.end == r.end));
165 }
166
167 template<class T>
168 inline bool
169 operator!=(const Range<T> &l, const Range<T> &r)
170 {
171 // for symmetry with ==, an invalid range is not equal to any other
172 return (!l.isValid() || !r.isValid() ||
173 (l.start != r.start) || (l.end != r.end));
174 }
175
176 //////////////////////////////////////////
177 //
178 // Compare position to a range
179 //
180 // - 'pos == range' indicates that position pos is within the given range.
181 // This test always returns false if the range is invalid.
182 //
183 // - 'pos < range' and 'pos > range' indicate that the position is
184 // before the start of or after the end of the range, respectively.
185 // The range must be valid for these comparisons to be made.
186 //
187 // All other comparisons do the obvious thing based on these definitions.
188 //
189 //
190
191 //
192 // Basic comparisons
193 //
194 template<class T>
195 inline bool
196 operator==(const T &pos, const Range<T> &range)
197 { return range.isValid() && pos >= range.start && pos <= range.end; }
198
199 template<class T>
200 inline bool
201 operator<(const T &pos, const Range<T> &range)
202 { assert(range.isValid()); return pos < range.start; }
203
204 template<class T>
205 inline bool
206 operator>(const T &pos, const Range<T> &range)
207 { assert(range.isValid()); return pos > range.end; }
208
209 //
210 // Derived comparisons
211 //
212 template<class T>
213 inline bool
214 operator<=(const T &pos, const Range<T> &range)
215 { assert(range.isValid()); return pos <= range.end; }
216
217 template<class T>
218 inline bool
219 operator>=(const T &pos, const Range<T> &range)
220 { assert(range.isValid()); return pos >= range.start; }
221
222 template<class T>
223 inline bool
224 operator!=(const T &pos, const Range<T> &range)
225 { return !(pos == range); }
226
227 //
228 // Define symmetric comparisons based on above
229 //
230 template<class T>
231 inline bool
232 operator>(const Range<T> &range, const T &pos)
233 { return pos < range; }
234
235 template<class T>
236 inline bool
237 operator<(const Range<T> &range, const T &pos)
238 { return pos > range; }
239
240 template<class T>
241 inline bool
242 operator<=(const Range<T> &range, const T &pos)
243 { return pos >= range; }
244
245 template<class T>
246 inline bool
247 operator>=(const Range<T> &range, const T &pos)
248 { return pos <= range; }
249
250 template<class T>
251 inline bool
252 operator==(const Range<T> &range, const T &pos)
253 { return (pos == range); }
254
255 template<class T>
256 inline bool
257 operator!=(const Range<T> &range, const T &pos)
258 { return (pos != range); }
259
260 #endif // __RANGE_HH__