srecord 1.65.0
Loading...
Searching...
No Matches
interval.h
Go to the documentation of this file.
1//
2// srecord - manipulate eprom load files
3// Copyright (C) 1998-2000, 2002-2010 Peter Miller
4//
5// This program is free software; you can redistribute it and/or modify
6// it under the terms of the GNU Lesser General Public License as published by
7// the Free Software Foundation; either version 3 of the License, or
8// (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU Lesser General Public License for more details.
14//
15// You should have received a copy of the GNU Lesser General Public License
16// along with this program. If not, see
17// <http://www.gnu.org/licenses/>.
18//
19
20#ifndef SRECORD_INTERVAL_H
21#define SRECORD_INTERVAL_H
22
23#include <cstddef>
24#include <stdint.h>
25#include <iostream>
26
27namespace srecord
28{
29
30/**
31 * The interval class is used to represent a set of integer values,
32 * usually composed of runs of adjacent value. Set arithmetic is
33 * implemented on these intervals.
34 */
36{
37public:
38 /**
39 * The destructor. It isn't virtual, so don't derive from this class.
40 */
42
43 /**
44 * The data_t type is used to parameterize the integr type used in
45 * the interval.
46 */
47 typedef uint32_t data_t;
48 typedef uint64_t long_data_t;
49
50 /**
51 * The default constructor. The interval is empty.
52 */
54
55 /**
56 * The constructor. The interval contains the single integer supplied.
57 *
58 * \param val
59 * The interval is constructed to contain the single interger
60 * value supplied.
61 */
63
64 /**
65 * The constructor. The interval contains all values >= lo and < hi.
66 *
67 * \param lo
68 * The lower bound of the integers in the initial interval.
69 * \param hi
70 * The upper bound of the integers in the initial interval;
71 * this value is not included.
72 */
74
75 /**
76 * The copy constructor.
77 */
79
80 /**
81 * The assignment operator.
82 */
84
85 /**
86 * The union_ class method is used to calculate the set union of
87 * two intervals.
88 */
89 static interval union_(const interval &, const interval &);
90
91 /**
92 * The intersection class method is used to calculate the set
93 * intersection of two intervals.
94 */
95 static interval intersection(const interval &, const interval &);
96
97 /**
98 * The difference class method is used to calculate the set
99 * difference of two intervals.
100 */
101 static interval difference(const interval &, const interval &);
102
103 /**
104 * The equal class method is used to test the equality of two
105 * intervals.
106 */
107 static bool equal(const interval &, const interval &);
108
109 /**
110 * The member method is used to test whether a given value is a
111 * member of the interval.
112 *
113 * \param val
114 * The value to test for membership
115 * \returns
116 * True if the given value is a member of the interval,
117 * false if it is not.
118 */
119 bool member(data_t val) const;
120
121 /**
122 * The empty method is used to test whether the interval is empty.
123 *
124 * \returns
125 * True if the interval is empty,
126 * false if the interval is not empty.
127 */
128 bool empty() const;
129
130 /**
131 * The first_interval_only method is used to crop the interval to the
132 * first (numerically least) run of consecutive integers in the set.
133 */
135
136 /**
137 * The interval_scan_begin method is used to start traversing every
138 * integer value in the interval.
139 */
141
142 /**
143 * The interval_scan_next method is used to traverse every integer
144 * value in the interval.
145 */
147
148 /**
149 * The interval_scan_end method is used to finish traversing every
150 * integer value in the interval.
151 */
152 void scan_end();
153
154 /**
155 * The get_lowest method is used to obtain the lower bound of
156 * the interval. It is inclusive.
157 */
159
160 /**
161 * The get_highest method is used to obtain the upper bound of
162 * the interval. It is exclusive (i.e. one beyond the highest
163 * integer in the set).
164 */
166
167 /**
168 * The print method is used to print an interval on an output stream.
169 */
170 void print(std::ostream &) const;
171
172 /**
173 * The pad method is used to expand an interval by padding each
174 * sub-interval. For each sub-interval the minimum is rounded
175 * down to a multiple of x, and the upper bound is rounded up to a
176 * multiple of x.
177 *
178 * @param x
179 * The multiple to expand to. No action is taken if x < 2.
180 * @returns
181 * new padded interval.
182 */
183 interval pad(int x) const;
184
185 /**
186 * The representation method is used to manufacture a textural
187 * representation of this interval.
188 */
189 std::string representation() const;
190
191 /**
192 * The flatten method is used to convert an interval with holes
193 * in it to a simple interval with no holes in it, by using the
194 * mimimum and maximum values.
195 */
197
198 /**
199 * The coverage method is used to obtain the size of the interval
200 * in bytes.
201 *
202 * @returns
203 * The number of bytes cobered by the interval, NOT including
204 * holes. Because the result could be 2**32, the 64-bit result
205 * is used so that this is representable.
206 */
208
209private:
210 /**
211 * The length instance variable is used to remember the length of
212 * the data instance variable. This is almost always even, because
213 * the internal is a series of [lo, hi) sub-intervals.
214 */
215 size_t length;
216
217 /**
218 * The size instance variable is used to remember the maximum size
219 * of the data instance variable. The length can go up and down
220 * depending on the calculation, but the size only ever rises.
221 */
222 size_t size;
223
224 /**
225 * The scan_index instance variable is used to remember where the
226 * scan us up to. Used by the scan_next method, et al.
227 */
228 size_t scan_index;
229
230 /**
231 * The scan_next_datum instance variable is used to remember where
232 * the scan us up to. Used by the scan_next method, et al.
233 */
234 data_t scan_next_datum;
235
236 /**
237 * The data instance variable is used to remember a pointer to
238 * the base of an array of interger values. They come in [lo, hi)
239 * pairs. As a sanity check, there is an extra item, wich contains
240 * the same value as the length instance variable.
241 */
242 data_t *data;
243
244 /**
245 * The valid method is used to test whether the interval is
246 * internally self-consistent. Principally of use when debugging.
247 */
248 bool valid() const;
249
250 /**
251 * The append method is used to append another value to the end
252 * of an interval under construction. This breaks the "length is
253 * even" assertion which usually applies; for this reason it is
254 * only to be used by the arithmetic operator implementations when
255 * calculating their results.
256 */
257 void append(data_t);
258};
259
260/**
261 * The equality operator is used to determine if two intervals are the
262 * same.
263 */
264inline bool
265operator == (const interval &lhs, const interval &rhs)
266{
267 return interval::equal(lhs, rhs);
268}
269
270/**
271 * The inequality operator is used to determine if two intervals are
272 * different.
273 */
274inline bool
275operator != (const interval &lhs, const interval &rhs)
276{
277 return !interval::equal(lhs, rhs);
278}
279
280/**
281 * The binary star operator is used to calculate the intersection of
282 * two intervals.
283 */
284inline interval
285operator * (const interval &lhs, const interval &rhs)
286{
287 return interval::intersection(lhs, rhs);
288}
289
290/**
291 * The star-and-replace operator is used to calculate the intersection
292 * of two intervals, and assign the result to the left-hand-side.
293 */
294inline interval &
296{
297 lhs = interval::intersection(lhs, rhs);
298 return lhs;
299}
300
301/**
302 * The binary plus operator is used to calculate the union of two
303 * intervals.
304 */
305inline interval
306operator + (const interval &lhs, const interval &rhs)
307{
308 return interval::union_(lhs, rhs);
309}
310
311/**
312 * The plus-and-replace operator is used to calculate the union of two
313 * intervals, and assign the result to the left-hand-side.
314 */
315inline interval &
317{
318 lhs = interval::union_(lhs, rhs);
319 return lhs;
320}
321
322/**
323 * The binary minus operator is used to calculate the difference of two
324 * intervals.
325 */
326inline interval
327operator - (const interval &lhs, const interval &rhs)
328{
329 return interval::difference(lhs, rhs);
330}
331
332/**
333 * The minus-and-replace operator is used to calculate the difference
334 * of two intervals, and assign the result to the left-hand-side.
335 */
336inline interval &
338{
339 lhs = interval::difference(lhs, rhs);
340 return lhs;
341}
342
343/**
344 * The unary minus operator is used to calculate the logical complement
345 * (inverse, negative) of an interval.
346 */
347inline interval
349{
350 return (interval(0, 0) - arg);
351}
352
353/**
354 * The binary left-shift operator is used to print an interval on an
355 * output stream.
356 */
357inline std::ostream &
358operator << (std::ostream &os, const interval &val)
359{
360 val.print(os);
361 return os;
362}
363
364};
365
366#endif // SRECORD_INTERVAL_H
The interval class is used to represent a set of integer values, usually composed of runs of adjacent...
Definition interval.h:36
interval(const interval &)
The copy constructor.
void print(std::ostream &) const
The print method is used to print an interval on an output stream.
static bool equal(const interval &, const interval &)
The equal class method is used to test the equality of two intervals.
long_data_t coverage() const
The coverage method is used to obtain the size of the interval in bytes.
static interval difference(const interval &, const interval &)
The difference class method is used to calculate the set difference of two intervals.
void first_interval_only()
The first_interval_only method is used to crop the interval to the first (numerically least) run of c...
uint32_t data_t
The data_t type is used to parameterize the integr type used in the interval.
Definition interval.h:47
interval pad(int x) const
The pad method is used to expand an interval by padding each sub-interval.
data_t get_lowest() const
The get_lowest method is used to obtain the lower bound of the interval.
void scan_begin()
The interval_scan_begin method is used to start traversing every integer value in the interval.
~interval()
The destructor.
interval flatten() const
The flatten method is used to convert an interval with holes in it to a simple interval with no holes...
bool empty() const
The empty method is used to test whether the interval is empty.
interval & operator=(const interval &)
The assignment operator.
data_t get_highest() const
The get_highest method is used to obtain the upper bound of the interval.
static interval union_(const interval &, const interval &)
The union_ class method is used to calculate the set union of two intervals.
interval()
The default constructor.
interval(data_t lo, data_t hi)
The constructor.
interval(data_t val)
The constructor.
std::string representation() const
The representation method is used to manufacture a textural representation of this interval.
bool scan_next(data_t &)
The interval_scan_next method is used to traverse every integer value in the interval.
void scan_end()
The interval_scan_end method is used to finish traversing every integer value in the interval.
uint64_t long_data_t
Definition interval.h:48
bool member(data_t val) const
The member method is used to test whether a given value is a member of the interval.
static interval intersection(const interval &, const interval &)
The intersection class method is used to calculate the set intersection of two intervals.
interval operator*(const interval &lhs, const interval &rhs)
The binary star operator is used to calculate the intersection of two intervals.
Definition interval.h:285
interval operator+(const interval &lhs, const interval &rhs)
The binary plus operator is used to calculate the union of two intervals.
Definition interval.h:306
interval & operator+=(interval &lhs, const interval &rhs)
The plus-and-replace operator is used to calculate the union of two intervals, and assign the result ...
Definition interval.h:316
interval & operator*=(interval &lhs, const interval &rhs)
The star-and-replace operator is used to calculate the intersection of two intervals,...
Definition interval.h:295
interval & operator-=(interval &lhs, const interval &rhs)
The minus-and-replace operator is used to calculate the difference of two intervals,...
Definition interval.h:337
interval operator-(const interval &lhs, const interval &rhs)
The binary minus operator is used to calculate the difference of two intervals.
Definition interval.h:327
bool operator==(const interval &lhs, const interval &rhs)
The equality operator is used to determine if two intervals are the same.
Definition interval.h:265
bool operator!=(const interval &lhs, const interval &rhs)
The inequality operator is used to determine if two intervals are different.
Definition interval.h:275
std::ostream & operator<<(std::ostream &os, const interval &val)
The binary left-shift operator is used to print an interval on an output stream.
Definition interval.h:358