2 * Copyright (c) 2003 The Regents of The University of Michigan
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.
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.
34 #include "base/intmath.hh"
35 #include "base/str.hh"
50 Range(const Range &r) { operator=(r); }
52 Range(const T &s, const T &e)
55 valid = (start <= end);
58 Range(const std::string &s) { valid = parse(s); }
62 int compare(const T &p);
63 bool parse(const std::string &s);
64 const Range &operator=(const Range &r);
66 bool isValid() const { return valid; }
72 Range<T>::compare(const T &p)
84 // Parse a range string
86 // Ranges are in the following format:
87 // <range> := {<start_val>}:{<end>}
88 // <end> := <end_val> | +<delta>
91 Range<T>::parse(const std::string &str)
93 std::vector<std::string> values;
94 tokenize(values, str, ':');
98 if (values.size() != 2)
101 std::string s = values[0];
102 std::string e = values[1];
104 if (!to_number(s, thestart))
107 bool increment = (e[0] == '+');
111 if (!to_number(e, theend))
128 inline const Range<T> &
129 Range<T>::operator=(const Range<T> &r)
145 inline std::ostream &
146 operator<<(std::ostream &o, const Range<T> &r)
148 // don't currently support output of invalid ranges
150 o << r.start << ":" << r.end;
154 //////////////////////////////////////////
156 // Compare two ranges
160 operator==(const Range<T> &l, const Range<T> &r)
162 // ranges must both be valid to be equal
163 return (l.isValid() && r.isValid() &&
164 (l.start == r.start) && (l.end == r.end));
169 operator!=(const Range<T> &l, const Range<T> &r)
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));
176 //////////////////////////////////////////
178 // Compare position to a range
180 // - 'pos == range' indicates that position pos is within the given range.
181 // This test always returns false if the range is invalid.
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.
187 // All other comparisons do the obvious thing based on these definitions.
196 operator==(const T &pos, const Range<T> &range)
197 { return range.isValid() && pos >= range.start && pos <= range.end; }
201 operator<(const T &pos, const Range<T> &range)
202 { assert(range.isValid()); return pos < range.start; }
206 operator>(const T &pos, const Range<T> &range)
207 { assert(range.isValid()); return pos > range.end; }
210 // Derived comparisons
214 operator<=(const T &pos, const Range<T> &range)
215 { assert(range.isValid()); return pos <= range.end; }
219 operator>=(const T &pos, const Range<T> &range)
220 { assert(range.isValid()); return pos >= range.start; }
224 operator!=(const T &pos, const Range<T> &range)
225 { return !(pos == range); }
228 // Define symmetric comparisons based on above
232 operator>(const Range<T> &range, const T &pos)
233 { return pos < range; }
237 operator<(const Range<T> &range, const T &pos)
238 { return pos > range; }
242 operator<=(const Range<T> &range, const T &pos)
243 { return pos >= range; }
247 operator>=(const Range<T> &range, const T &pos)
248 { return pos <= range; }
252 operator==(const Range<T> &range, const T &pos)
253 { return (pos == range); }
257 operator!=(const Range<T> &range, const T &pos)
258 { return (pos != range); }
260 #endif // __RANGE_HH__