File: RangeSet.hpp

package info (click to toggle)
fauhdlc 20180504-2
  • links: PTS
  • area: main
  • in suites: buster
  • size: 2,956 kB
  • sloc: cpp: 23,188; ansic: 6,077; yacc: 3,764; lex: 763; makefile: 605; sh: 494; xml: 403
file content (189 lines) | stat: -rw-r--r-- 5,812 bytes parent folder | download | duplicates (3)
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 */