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