addr_range.hh revision 2665
1/*
2 * Copyright (c) 2002-2005 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 * Authors: Nathan Binkert
29 *          Steve Reinhardt
30 */
31
32#ifndef __BASE_RANGE_HH__
33#define __BASE_RANGE_HH__
34
35#include <cassert>
36#include <iostream>
37#include <string>
38
39/**
40 * @param s range string
41 * EndExclusive Ranges are in the following format:
42 * @verbatim
43 *    <range> := {<start_val>}:{<end>}
44 *    <start>   := <end_val> | +<delta>
45 * @endverbatim
46 */
47template <class T>
48bool __parse_range(const std::string &s, T &start, T &end);
49
50template <class T>
51struct Range
52{
53    T start;
54    T end;
55
56    Range() { invalidate(); }
57
58    template <class U>
59    Range(const std::pair<U, U> &r)
60        : start(r.first), end(r.second)
61    {}
62
63    template <class U>
64    Range(const Range<U> &r)
65        : start(r.start), end(r.end)
66    {}
67
68    Range(const std::string &s)
69    {
70        if (!__parse_range(s, start, end))
71            invalidate();
72    }
73
74    template <class U>
75    const Range<T> &operator=(const Range<U> &r)
76    {
77        start = r.start;
78        end = r.end;
79        return *this;
80    }
81
82    template <class U>
83    const Range<T> &operator=(const std::pair<U, U> &r)
84    {
85        start = r.first;
86        end = r.second;
87        return *this;
88    }
89
90    const Range &operator=(const std::string &s)
91    {
92        if (!__parse_range(s, start, end))
93            invalidate();
94        return *this;
95    }
96
97    void invalidate() { start = 1; end = 0; }
98    T size() const { return end - start + 1; }
99    bool valid() const { return start < end; }
100};
101
102template <class T>
103inline std::ostream &
104operator<<(std::ostream &o, const Range<T> &r)
105{
106    o << '[' << r.start << "," << r.end << ']';
107    return o;
108}
109
110template <class T>
111inline Range<T>
112RangeEx(T start, T end)
113{ return std::make_pair(start, end - 1); }
114
115template <class T>
116inline Range<T>
117RangeIn(T start, T end)
118{ return std::make_pair(start, end); }
119
120template <class T, class U>
121inline Range<T>
122RangeSize(T start, U size)
123{ return std::make_pair(start, start + size - 1); }
124
125////////////////////////////////////////////////////////////////////////
126//
127// Range to Range Comparisons
128//
129
130/**
131 * @param range1 is a range.
132 * @param range2 is a range.
133 * @return if range1 and range2 are identical.
134 */
135template <class T, class U>
136inline bool
137operator==(const Range<T> &range1, const Range<U> &range2)
138{
139    return range1.start == range2.start && range1.end == range2.end;
140}
141
142/**
143 * @param range1 is a range.
144 * @param range2 is a range.
145 * @return if range1 and range2 are not identical.
146 */
147template <class T, class U>
148inline bool
149operator!=(const Range<T> &range1, const Range<U> &range2)
150{
151    return range1.start != range2.start || range1.end != range2.end;
152}
153
154/**
155 * @param range1 is a range.
156 * @param range2 is a range.
157 * @return if range1 is less than range2 and does not overlap range1.
158 */
159template <class T, class U>
160inline bool
161operator<(const Range<T> &range1, const Range<U> &range2)
162{
163    return range1.start < range2.start;
164}
165
166/**
167 * @param range1 is a range.
168 * @param range2 is a range.
169 * @return if range1 is less than range2.  range1 may overlap range2,
170 * but not extend beyond the end of range2.
171 */
172template <class T, class U>
173inline bool
174operator<=(const Range<T> &range1, const Range<U> &range2)
175{
176    return range1.start <= range2.start;
177}
178
179/**
180 * @param range1 is a range.
181 * @param range2 is a range.
182 * @return if range1 is greater than range2 and does not overlap range2.
183 */
184template <class T, class U>
185inline bool
186operator>(const Range<T> &range1, const Range<U> &range2)
187{
188    return range1.start > range2.start;
189}
190
191/**
192 * @param range1 is a range.
193 * @param range2 is a range.
194 * @return if range1 is greater than range2.  range1 may overlap range2,
195 * but not extend beyond the beginning of range2.
196 */
197template <class T, class U>
198inline bool
199operator>=(const Range<T> &range1, const Range<U> &range2)
200{
201    return range1.start >= range2.start;
202}
203
204////////////////////////////////////////////////////////////////////////
205//
206// Position to Range Comparisons
207//
208
209/**
210 * @param pos position compared to the range.
211 * @param range range compared against.
212 * @return indicates that position pos is within the range.
213 */
214template <class T, class U>
215inline bool
216operator==(const T &pos, const Range<U> &range)
217{
218    return pos >= range.start && pos <= range.end;
219}
220
221/**
222 * @param pos position compared to the range.
223 * @param range range compared against.
224 * @return indicates that position pos is not within the range.
225 */
226template <class T, class U>
227inline bool
228operator!=(const T &pos, const Range<U> &range)
229{
230    return pos < range.start || pos > range.end;
231}
232
233/**
234 * @param pos position compared to the range.
235 * @param range range compared against.
236 * @return indicates that position pos is below the range.
237 */
238template <class T, class U>
239inline bool
240operator<(const T &pos, const Range<U> &range)
241{
242    return pos < range.start;
243}
244
245/**
246 * @param pos position compared to the range.
247 * @param range range compared against.
248 * @return indicates that position pos is below or in the range.
249 */
250template <class T, class U>
251inline bool
252operator<=(const T &pos, const Range<U> &range)
253{
254    return pos <= range.end;
255}
256
257/**
258 * @param pos position compared to the range.
259 * @param range range compared against.
260 * @return indicates that position pos is above the range.
261 */
262template <class T, class U>
263inline bool
264operator>(const T &pos, const Range<U> &range)
265{
266    return pos > range.end;
267}
268
269/**
270 * @param pos position compared to the range.
271 * @param range range compared against.
272 * @return indicates that position pos is above or in the range.
273 */
274template <class T, class U>
275inline bool
276operator>=(const T &pos, const Range<U> &range)
277{
278    return pos >= range.start;
279}
280
281////////////////////////////////////////////////////////////////////////
282//
283// Range to Position Comparisons (for symmetry)
284//
285
286/**
287 * @param range range compared against.
288 * @param pos position compared to the range.
289 * @return indicates that position pos is within the range.
290 */
291template <class T, class U>
292inline bool
293operator==(const Range<T> &range, const U &pos)
294{
295    return pos >= range.start && pos <= range.end;
296}
297
298/**
299 * @param range range compared against.
300 * @param pos position compared to the range.
301 * @return indicates that position pos is not within the range.
302 */
303template <class T, class U>
304inline bool
305operator!=(const Range<T> &range, const U &pos)
306{
307    return pos < range.start || pos > range.end;
308}
309
310/**
311 * @param range range compared against.
312 * @param pos position compared to the range.
313 * @return indicates that position pos is above the range.
314 */
315template <class T, class U>
316inline bool
317operator<(const Range<T> &range, const U &pos)
318{
319    return range.end < pos;
320}
321
322/**
323 * @param range range compared against.
324 * @param pos position compared to the range.
325 * @return indicates that position pos is above or in the range.
326 */
327template <class T, class U>
328inline bool
329operator<=(const Range<T> &range, const U &pos)
330{
331    return range.start <= pos;
332}
333
334/**
335 * @param range range compared against.
336 * @param pos position compared to the range.
337 * 'range > pos' indicates that position pos is below the range.
338 */
339template <class T, class U>
340inline bool
341operator>(const Range<T> &range, const U &pos)
342{
343    return range.start > pos;
344}
345
346/**
347 * @param range range compared against.
348 * @param pos position compared to the range.
349 * 'range >= pos' indicates that position pos is below or in the range.
350 */
351template <class T, class U>
352inline bool
353operator>=(const Range<T> &range, const U &pos)
354{
355    return range.end >= pos;
356}
357
358#endif // __BASE_RANGE_HH__
359