summaryrefslogtreecommitdiff
path: root/src/util/range.h
blob: 9a9cf03b455b559c3b6c7bdac03835cccb165284 (plain)
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
#ifndef _RE2C_UTIL_RANGE_
#define _RE2C_UTIL_RANGE_

#include "src/util/c99_stdint.h"
#include <assert.h>
#include <stddef.h> // NULL

#include "src/test/range/test.h"
#include "src/util/forbid_copy.h"
#include "src/util/free_list.h"

namespace re2c
{

class Range
{
public:
	static free_list<Range*> vFreeList;

private:
	Range * nx;
	// [lb,ub)
	uint32_t lb;
	uint32_t ub;

public:
	static Range * sym (uint32_t c)
	{
		return new Range (NULL, c, c + 1);
	}
	static Range * ran (uint32_t l, uint32_t u)
	{
		return new Range (NULL, l, u);
	}
	~Range ()
	{
		vFreeList.erase (this);
	}
	Range * next () const { return nx; }
	uint32_t lower () const { return lb; }
	uint32_t upper () const { return ub; }
	static Range * add (const Range * r1, const Range * r2);
	static Range * sub (const Range * r1, const Range * r2);

private:
	Range (Range * n, uint32_t l, uint32_t u)
		: nx (n)
		, lb (l)
		, ub (u)
	{
		assert (lb < ub);
		vFreeList.insert (this);
	}
	static void append_overlapping (Range * & head, Range * & tail, const Range * r);
	static void append (Range ** & ptail, uint32_t l, uint32_t u);

	// test addition and subtraction
	template <uint8_t> friend Range * re2c_test::range (uint32_t n);

	FORBID_COPY (Range);
};

} // namespace re2c

#endif // _RE2C_UTIL_RANGE_