1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
|
/* $Id$
*
* RangeSet defines operation for a Range and sets of ranges, like checking if
* one range is a subset of another.
*
* Copyright (C) 2008-2009 FAUmachine Team <info@faumachine.org>.
* This program is free software. You can redistribute it and/or modify it
* under the terms of the GNU General Public License, either version 2 of
* the License, or (at your option) any later version. See COPYING.
*/
#ifndef __RANGE_SET_HPP_INCLUDED
#define __RANGE_SET_HPP_INCLUDED
#include <list>
#include <iostream>
#include "frontend/ast/Types.hpp"
#include "frontend/ast/DiscreteRange.hpp"
namespace ast {
//! operation on ranges / sets of ranges.
/** The class RangeSet is useful to determine subsets of ranges and
* being able to iterate over those.
*/
class RangeSet {
public:
//! c'tor
/** @param l left bound of the RangeSet.
* @param r right bound of the RangeSet.
* l <= r must be true.
*/
RangeSet(universal_integer l, universal_integer r);
//! alternate c'tor
/** construct from DiscreteRange.
* @param dr source discrete range. Must not be a NULL range.
*/
RangeSet(const DiscreteRange &dr);
/** substract a range from l to r from the current range.
* @param l left bound of the range to substract.
* @param r right bound of the range to substract.
* @return true, if [l, r] is a subset of this Range, false
* otherwise.
* l <= r must be true.
*/
bool minus(universal_integer l, universal_integer r);
/** substract a range from the current range.
* Does the same as the other minus, just for a DiscreteRange.
* @param dr range to substract. Must not be a null range.
* @return true if [l, r] is a subset of this Range, false
* otherwise.
*/
bool minus(const DiscreteRange &dr);
/** unify with given Range.
* @param dr DiscreteRange to unify with.
*/
void plus(const DiscreteRange &dr);
/** unify with a range from l to r.
* @param l left bound of the range.
* @param r right bound of the range.
* l <= r must be true.
*/
void plus(universal_integer l, universal_integer r);
/** is the range set empty?
* @return true, if there are no ranges in the set.
*/
bool empty(void) const;
/** clear all elements from the RangeSet. */
void clear(void);
/** put a textual representation of the RangeSet to stream.
* @param stream target stream to put RangeSet to.
*/
void put(std::ostream &stream) const;
/** return the upper bound.
* Must not be called, when empty is true.
* @return highest number still part of the Range.
*/
universal_integer getUpperBound(void) const;
/** return the lower bound.
* Must not be called, when empty is true.
* @return lowest number still part of the Range.
*/
universal_integer getLowerBound(void) const;
/** is value part of the RangeSet? */
bool contains(universal_integer value) const;
private:
/** a single range. */
class Range {
public:
/** c'tor.
* The following must be true: l <= r
* @param l left bound of the range (part of the range).
* @param r right bound of the range (part of the range).
*/
Range(universal_integer l, universal_integer r);
/** calculate the distance from this to other.
* @param number of empty fields between this and other.
* Negative numbers mean that other is left of
* this, positive numbers mean that it is right
* of this. 0 means that the ranges are adjacent or
* overlap.
*/
universal_integer distance(const Range &other) const;
/** is this a subset of other?
* @param other check if this is a subset other.
* @return true, if it is a subset, false if not. It will
* also return true, other is equal to this
* (non-true subset).
*/
bool isSubset(const Range &other) const;
/** is the value inside the Range?
* @param value value to check if inside the Range.
* @return true if value is inside the Range, false otherwise.
*/
bool contains(universal_integer value) const;
/** is this equal to other?
* @param other range to check for equality.
* @return true, if both bounds match, false otherwise.
*/
bool operator ==(const Range &other) const;
/** is this Range left of the other range?
* @param other other range to check.
* @return true, if this Range is left of the other
* Range. In particular an overlapping Range is
* not considered left of.
*/
bool operator <(const Range &other) const;
/** is this Range right of the other range?
* @param other other range to check.
* @return true, if this Range is right of the other
* Range. In particular an overlapping Range is
* not considered right of.
*/
bool operator >(const Range &other) const;
/** substract other from this range.
* @param other range to substract from this range.
* @return list containing 0, 1 or 2 ranges (depending
* if is equal to this, has one common boundary or
* is a true subset of this with no common boundary.
*/
std::list<Range> operator -(const Range &other) const;
/** put a textual representation of the Range to stream.
* @param stream target stream to put Range to.
*/
void put(std::ostream &stream) const;
/** left bound of the range. */
universal_integer left;
/** right bound of the range. */
universal_integer right;
};
//! list of different ranges forming this RangeSet.
std::list<Range> ranges;
};
//! overloaded << operator to easily output a RangeSet
/** @param stream stream to put a rs to.
* @param rs put rs to stream.
* @return modified stream.
*/
std::ostream &
operator <<(std::ostream &stream, const RangeSet &rs);
}; /* namespace ast */
#endif /* __RANGE_SET_HPP_INCLUDED */
|