addr_range.hh revision 2665
112863Sgabeblack@google.com/*
212863Sgabeblack@google.com * Copyright (c) 2002-2005 The Regents of The University of Michigan
312863Sgabeblack@google.com * All rights reserved.
412863Sgabeblack@google.com *
512863Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without
612863Sgabeblack@google.com * modification, are permitted provided that the following conditions are
712863Sgabeblack@google.com * met: redistributions of source code must retain the above copyright
812863Sgabeblack@google.com * notice, this list of conditions and the following disclaimer;
912863Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright
1012863Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the
1112863Sgabeblack@google.com * documentation and/or other materials provided with the distribution;
1212863Sgabeblack@google.com * neither the name of the copyright holders nor the names of its
1312863Sgabeblack@google.com * contributors may be used to endorse or promote products derived from
1412863Sgabeblack@google.com * this software without specific prior written permission.
1512863Sgabeblack@google.com *
1612863Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1712863Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1812863Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1912863Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2012863Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2112863Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2212863Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2312863Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2412863Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2512863Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2612863Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2712863Sgabeblack@google.com *
2812863Sgabeblack@google.com * Authors: Nathan Binkert
2912863Sgabeblack@google.com *          Steve Reinhardt
3012863Sgabeblack@google.com */
3112863Sgabeblack@google.com
3212950Sgabeblack@google.com#ifndef __BASE_RANGE_HH__
3312863Sgabeblack@google.com#define __BASE_RANGE_HH__
3412863Sgabeblack@google.com
3513191Sgabeblack@google.com#include <cassert>
3613091Sgabeblack@google.com#include <iostream>
3713079Sgabeblack@google.com#include <string>
3812863Sgabeblack@google.com
3912950Sgabeblack@google.com/**
4012863Sgabeblack@google.com * @param s range string
4112863Sgabeblack@google.com * EndExclusive Ranges are in the following format:
4212863Sgabeblack@google.com * @verbatim
4312863Sgabeblack@google.com *    <range> := {<start_val>}:{<end>}
4412863Sgabeblack@google.com *    <start>   := <end_val> | +<delta>
4512863Sgabeblack@google.com * @endverbatim
4612950Sgabeblack@google.com */
4712863Sgabeblack@google.comtemplate <class T>
4813045Sgabeblack@google.combool __parse_range(const std::string &s, T &start, T &end);
4913045Sgabeblack@google.com
5012863Sgabeblack@google.comtemplate <class T>
5112863Sgabeblack@google.comstruct Range
5213191Sgabeblack@google.com{
5313191Sgabeblack@google.com    T start;
5413191Sgabeblack@google.com    T end;
5512950Sgabeblack@google.com
5612950Sgabeblack@google.com    Range() { invalidate(); }
5712950Sgabeblack@google.com
5812950Sgabeblack@google.com    template <class U>
5912950Sgabeblack@google.com    Range(const std::pair<U, U> &r)
6013079Sgabeblack@google.com        : start(r.first), end(r.second)
6113079Sgabeblack@google.com    {}
6213079Sgabeblack@google.com
6313079Sgabeblack@google.com    template <class U>
6413079Sgabeblack@google.com    Range(const Range<U> &r)
6513079Sgabeblack@google.com        : start(r.start), end(r.end)
6613079Sgabeblack@google.com    {}
6713079Sgabeblack@google.com
6812982Sgabeblack@google.com    Range(const std::string &s)
6912863Sgabeblack@google.com    {
7012950Sgabeblack@google.com        if (!__parse_range(s, start, end))
7112863Sgabeblack@google.com            invalidate();
7212950Sgabeblack@google.com    }
7312950Sgabeblack@google.com
7412863Sgabeblack@google.com    template <class U>
7512950Sgabeblack@google.com    const Range<T> &operator=(const Range<U> &r)
7612982Sgabeblack@google.com    {
7712982Sgabeblack@google.com        start = r.start;
7812982Sgabeblack@google.com        end = r.end;
7913046Sgabeblack@google.com        return *this;
8012863Sgabeblack@google.com    }
8112863Sgabeblack@google.com
8212863Sgabeblack@google.com    template <class U>
8312863Sgabeblack@google.com    const Range<T> &operator=(const std::pair<U, U> &r)
8412863Sgabeblack@google.com    {
8512950Sgabeblack@google.com        start = r.first;
8612863Sgabeblack@google.com        end = r.second;
8712863Sgabeblack@google.com        return *this;
8812950Sgabeblack@google.com    }
8912950Sgabeblack@google.com
9012863Sgabeblack@google.com    const Range &operator=(const std::string &s)
9112863Sgabeblack@google.com    {
9213091Sgabeblack@google.com        if (!__parse_range(s, start, end))
9313091Sgabeblack@google.com            invalidate();
9413091Sgabeblack@google.com        return *this;
9513091Sgabeblack@google.com    }
9613091Sgabeblack@google.com
9713091Sgabeblack@google.com    void invalidate() { start = 1; end = 0; }
9813091Sgabeblack@google.com    T size() const { return end - start + 1; }
9913091Sgabeblack@google.com    bool valid() const { return start < end; }
10013091Sgabeblack@google.com};
10113091Sgabeblack@google.com
10213091Sgabeblack@google.comtemplate <class T>
10313091Sgabeblack@google.cominline std::ostream &
10413091Sgabeblack@google.comoperator<<(std::ostream &o, const Range<T> &r)
10513091Sgabeblack@google.com{
10613091Sgabeblack@google.com    o << '[' << r.start << "," << r.end << ']';
10713091Sgabeblack@google.com    return o;
10813091Sgabeblack@google.com}
10913091Sgabeblack@google.com
11013091Sgabeblack@google.comtemplate <class T>
11113191Sgabeblack@google.cominline Range<T>
11213191Sgabeblack@google.comRangeEx(T start, T end)
11313191Sgabeblack@google.com{ return std::make_pair(start, end - 1); }
11413191Sgabeblack@google.com
11513191Sgabeblack@google.comtemplate <class T>
11613191Sgabeblack@google.cominline Range<T>
11713191Sgabeblack@google.comRangeIn(T start, T end)
11813191Sgabeblack@google.com{ return std::make_pair(start, end); }
11913191Sgabeblack@google.com
12013191Sgabeblack@google.comtemplate <class T, class U>
12113191Sgabeblack@google.cominline Range<T>
12213191Sgabeblack@google.comRangeSize(T start, U size)
12313191Sgabeblack@google.com{ return std::make_pair(start, start + size - 1); }
12413191Sgabeblack@google.com
12513191Sgabeblack@google.com////////////////////////////////////////////////////////////////////////
12613191Sgabeblack@google.com//
12713191Sgabeblack@google.com// Range to Range Comparisons
12813191Sgabeblack@google.com//
12913191Sgabeblack@google.com
13013191Sgabeblack@google.com/**
13113191Sgabeblack@google.com * @param range1 is a range.
13213191Sgabeblack@google.com * @param range2 is a range.
13313191Sgabeblack@google.com * @return if range1 and range2 are identical.
13413191Sgabeblack@google.com */
13513191Sgabeblack@google.comtemplate <class T, class U>
13613191Sgabeblack@google.cominline bool
13713191Sgabeblack@google.comoperator==(const Range<T> &range1, const Range<U> &range2)
13813191Sgabeblack@google.com{
13913191Sgabeblack@google.com    return range1.start == range2.start && range1.end == range2.end;
14013191Sgabeblack@google.com}
14113191Sgabeblack@google.com
14213191Sgabeblack@google.com/**
14313191Sgabeblack@google.com * @param range1 is a range.
14413191Sgabeblack@google.com * @param range2 is a range.
14513191Sgabeblack@google.com * @return if range1 and range2 are not identical.
14613191Sgabeblack@google.com */
14713191Sgabeblack@google.comtemplate <class T, class U>
14813191Sgabeblack@google.cominline bool
14913191Sgabeblack@google.comoperator!=(const Range<T> &range1, const Range<U> &range2)
15013191Sgabeblack@google.com{
15113191Sgabeblack@google.com    return range1.start != range2.start || range1.end != range2.end;
15213191Sgabeblack@google.com}
15313191Sgabeblack@google.com
15413191Sgabeblack@google.com/**
15513191Sgabeblack@google.com * @param range1 is a range.
15613191Sgabeblack@google.com * @param range2 is a range.
15713191Sgabeblack@google.com * @return if range1 is less than range2 and does not overlap range1.
15813191Sgabeblack@google.com */
15913191Sgabeblack@google.comtemplate <class T, class U>
16013191Sgabeblack@google.cominline bool
16113191Sgabeblack@google.comoperator<(const Range<T> &range1, const Range<U> &range2)
16213191Sgabeblack@google.com{
16313191Sgabeblack@google.com    return range1.start < range2.start;
16413191Sgabeblack@google.com}
16512863Sgabeblack@google.com
16612950Sgabeblack@google.com/**
16712863Sgabeblack@google.com * @param range1 is a range.
16812950Sgabeblack@google.com * @param range2 is a range.
16912950Sgabeblack@google.com * @return if range1 is less than range2.  range1 may overlap range2,
17012950Sgabeblack@google.com * but not extend beyond the end of range2.
17112863Sgabeblack@google.com */
17212863Sgabeblack@google.comtemplate <class T, class U>
17312950Sgabeblack@google.cominline bool
17413079Sgabeblack@google.comoperator<=(const Range<T> &range1, const Range<U> &range2)
17513079Sgabeblack@google.com{
17613079Sgabeblack@google.com    return range1.start <= range2.start;
17713079Sgabeblack@google.com}
17813079Sgabeblack@google.com
17913079Sgabeblack@google.com/**
18013079Sgabeblack@google.com * @param range1 is a range.
18113079Sgabeblack@google.com * @param range2 is a range.
18213079Sgabeblack@google.com * @return if range1 is greater than range2 and does not overlap range2.
18313079Sgabeblack@google.com */
18413079Sgabeblack@google.comtemplate <class T, class U>
18512950Sgabeblack@google.cominline bool
18612950Sgabeblack@google.comoperator>(const Range<T> &range1, const Range<U> &range2)
18712950Sgabeblack@google.com{
18812950Sgabeblack@google.com    return range1.start > range2.start;
18912950Sgabeblack@google.com}
19013045Sgabeblack@google.com
19113045Sgabeblack@google.com/**
19213045Sgabeblack@google.com * @param range1 is a range.
19313046Sgabeblack@google.com * @param range2 is a range.
19412982Sgabeblack@google.com * @return if range1 is greater than range2.  range1 may overlap range2,
19512950Sgabeblack@google.com * 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