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