addr_range.hh revision 2
112027Sjungma@eit.uni-kl.de/* 212027Sjungma@eit.uni-kl.de * Copyright (c) 2003 The Regents of The University of Michigan 312027Sjungma@eit.uni-kl.de * All rights reserved. 412027Sjungma@eit.uni-kl.de * 512027Sjungma@eit.uni-kl.de * Redistribution and use in source and binary forms, with or without 612027Sjungma@eit.uni-kl.de * modification, are permitted provided that the following conditions are 712027Sjungma@eit.uni-kl.de * met: redistributions of source code must retain the above copyright 812027Sjungma@eit.uni-kl.de * notice, this list of conditions and the following disclaimer; 912027Sjungma@eit.uni-kl.de * redistributions in binary form must reproduce the above copyright 1012027Sjungma@eit.uni-kl.de * notice, this list of conditions and the following disclaimer in the 1112027Sjungma@eit.uni-kl.de * documentation and/or other materials provided with the distribution; 1212027Sjungma@eit.uni-kl.de * neither the name of the copyright holders nor the names of its 1312027Sjungma@eit.uni-kl.de * contributors may be used to endorse or promote products derived from 1412027Sjungma@eit.uni-kl.de * this software without specific prior written permission. 1512027Sjungma@eit.uni-kl.de * 1612027Sjungma@eit.uni-kl.de * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1712027Sjungma@eit.uni-kl.de * "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 "str.hh" 35#include "intmath.h" 36 37template<class T> 38class 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 70template<class T> 71inline int 72Range<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> 89template<class T> 90inline bool 91Range<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 127template<class T> 128inline const Range<T> & 129Range<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 144template<class T> 145inline std::ostream & 146operator<<(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// 158template<class T> 159inline bool 160operator==(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 167template<class T> 168inline bool 169operator!=(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// 194template<class T> 195inline bool 196operator==(const T &pos, const Range<T> &range) 197{ return range.isValid() && pos >= range.start && pos <= range.end; } 198 199template<class T> 200inline bool 201operator<(const T &pos, const Range<T> &range) 202{ assert(range.isValid()); return pos < range.start; } 203 204template<class T> 205inline bool 206operator>(const T &pos, const Range<T> &range) 207{ assert(range.isValid()); return pos > range.end; } 208 209// 210// Derived comparisons 211// 212template<class T> 213inline bool 214operator<=(const T &pos, const Range<T> &range) 215{ assert(range.isValid()); return pos <= range.end; } 216 217template<class T> 218inline bool 219operator>=(const T &pos, const Range<T> &range) 220{ assert(range.isValid()); return pos >= range.start; } 221 222template<class T> 223inline bool 224operator!=(const T &pos, const Range<T> &range) 225{ return !(pos == range); } 226 227// 228// Define symmetric comparisons based on above 229// 230template<class T> 231inline bool 232operator>(const Range<T> &range, const T &pos) 233{ return pos < range; } 234 235template<class T> 236inline bool 237operator<(const Range<T> &range, const T &pos) 238{ return pos > range; } 239 240template<class T> 241inline bool 242operator<=(const Range<T> &range, const T &pos) 243{ return pos >= range; } 244 245template<class T> 246inline bool 247operator>=(const Range<T> &range, const T &pos) 248{ return pos <= range; } 249 250template<class T> 251inline bool 252operator==(const Range<T> &range, const T &pos) 253{ return (pos == range); } 254 255template<class T> 256inline bool 257operator!=(const Range<T> &range, const T &pos) 258{ return (pos != range); } 259 260#endif // __RANGE_HH__ 261