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.
36 bool __parse_range(const std::string &s, T &start, T &end);
43 * @param s range string
44 * Ranges are in the following format:
45 * <range> := {<start_val>}:{<end>}
46 * <end> := <end_val> | +<delta>
49 parse(const std::string &s)
51 if (!__parse_range(s, start, end))
65 Range(T first, T second)
66 : start(first), end(second)
70 Range(const Range<U> &r)
71 : start(r.start), end(r.end)
75 Range(const std::pair<U, U> &r)
76 : start(r.first), end(r.second)
79 Range(const std::string &s)
85 const Range<T> &operator=(const Range<U> &r)
93 const Range<T> &operator=(const std::pair<U, U> &r)
100 const Range &operator=(const std::string &s)
106 void invalidate() { start = 0; end = 0; }
107 T size() const { return end - start; }
108 bool valid() const { return start < end; }
113 make_range(T start, T end)
115 return Range<T>(start, end);
119 inline std::ostream &
120 operator<<(std::ostream &o, const Range<T> &r)
122 // don't currently support output of invalid ranges
124 o << r.start << ":" << r.end;
128 ////////////////////////////////////////////////////////////////////////
130 // Range to Range Comparisons
134 * @param range1 is a range.
135 * @param range2 is a range.
136 * @return if range1 and range2 are identical.
138 template <class T, class U>
140 operator==(const Range<T> &range1, const Range<U> &range2)
142 assert(range1.valid() && range2.valid());
143 return range1.start == range2.start && range1.end == range2.end;
147 * @param range1 is a range.
148 * @param range2 is a range.
149 * @return if range1 and range2 are not identical.
151 template <class T, class U>
153 operator!=(const Range<T> &range1, const Range<U> &range2)
155 assert(range1.valid() && range2.valid());
156 return range1.start != range2.start || range1.end != range2.end;
160 * @param range1 is a range.
161 * @param range2 is a range.
162 * @return if range1 is less than range2 and does not overlap range1.
164 template <class T, class U>
166 operator<(const Range<T> &range1, const Range<U> &range2)
168 assert(range1.valid() && range2.valid());
169 return range1.end <= range2.start;
173 * @param range1 is a range.
174 * @param range2 is a range.
175 * @return if range1 is less than range2. range1 may overlap range2,
176 * but not extend beyond the end of range2.
178 template <class T, class U>
180 operator<=(const Range<T> &range1, const Range<U> &range2)
182 assert(range1.valid() && range2.valid());
183 return range1.start <= range2.start && range1.end <= range2.end;
187 * @param range1 is a range.
188 * @param range2 is a range.
189 * @return if range1 is greater than range2 and does not overlap range2.
191 template <class T, class U>
193 operator>(const Range<T> &range1, const Range<U> &range2)
195 assert(range1.valid() && range2.valid());
196 return range1.start >= range2.end;
200 * @param range1 is a range.
201 * @param range2 is a range.
202 * @return if range1 is greater than range2. range1 may overlap range2,
203 * but not extend beyond the beginning of range2.
205 template <class T, class U>
207 operator>=(const Range<T> &range1, const Range<U> &range2)
209 assert(range1.valid() && range2.valid());
210 return range1.start >= range2.start && range1.end >= range2.end;
213 ////////////////////////////////////////////////////////////////////////
215 // Position to Range Comparisons
219 * @param pos position compared to the range.
220 * @param range range compared against.
221 * @return indicates that position pos is within the range.
223 template <class T, class U>
225 operator==(const T &pos, const Range<U> &range)
227 assert(range.valid());
228 return pos >= range.start && pos < range.end;
232 * @param pos position compared to the range.
233 * @param range range compared against.
234 * @return indicates that position pos is not within the range.
236 template <class T, class U>
238 operator!=(const T &pos, const Range<U> &range)
240 assert(range.valid());
241 return pos < range.start || pos >= range.end;
245 * @param pos position compared to the range.
246 * @param range range compared against.
247 * @return indicates that position pos is below the range.
249 template <class T, class U>
251 operator<(const T &pos, const Range<U> &range)
253 assert(range.valid());
254 return pos < range.start;
258 * @param pos position compared to the range.
259 * @param range range compared against.
260 * @return indicates that position pos is below or in the range.
262 template <class T, class U>
264 operator<=(const T &pos, const Range<U> &range)
266 assert(range.valid());
267 return pos < range.end;
271 * @param pos position compared to the range.
272 * @param range range compared against.
273 * @return indicates that position pos is above the range.
275 template <class T, class U>
277 operator>(const T &pos, const Range<U> &range)
279 assert(range.valid());
280 return pos >= range.end;
284 * @param pos position compared to the range.
285 * @param range range compared against.
286 * @return indicates that position pos is above or in the range.
288 template <class T, class U>
290 operator>=(const T &pos, const Range<U> &range)
292 assert(range.valid());
293 return pos >= range.start;
296 ////////////////////////////////////////////////////////////////////////
298 // Range to Position Comparisons (for symmetry)
302 * @param range range compared against.
303 * @param pos position compared to the range.
304 * @return indicates that position pos is within the range.
306 template <class T, class U>
308 operator==(const Range<T> &range, const U &pos)
310 assert(range.valid());
311 return pos >= range.start && pos < range.end;
315 * @param range range compared against.
316 * @param pos position compared to the range.
317 * @return indicates that position pos is not within the range.
319 template <class T, class U>
321 operator!=(const Range<T> &range, const U &pos)
323 assert(range.valid());
324 return pos < range.start || pos >= range.end;
328 * @param range range compared against.
329 * @param pos position compared to the range.
330 * @return indicates that position pos is above the range.
332 template <class T, class U>
334 operator<(const Range<T> &range, const U &pos)
336 assert(range.valid());
337 return range.end <= pos;
341 * @param range range compared against.
342 * @param pos position compared to the range.
343 * @return indicates that position pos is above or in the range.
345 template <class T, class U>
347 operator<=(const Range<T> &range, const U &pos)
349 assert(range.valid());
350 return range.start <= pos;
354 * @param range range compared against.
355 * @param pos position compared to the range.
356 * 'range > pos' indicates that position pos is below the range.
358 template <class T, class U>
360 operator>(const Range<T> &range, const U &pos)
362 assert(range.valid());
363 return range.start > pos;
367 * @param range range compared against.
368 * @param pos position compared to the range.
369 * 'range >= pos' indicates that position pos is below or in the range.
371 template <class T, class U>
373 operator>=(const Range<T> &range, const U &pos)
375 assert(range.valid());
376 return range.end > pos;
379 #endif // __RANGE_HH__