File: ParentReq.cpp

package info (click to toggle)
storm-lang 0.7.4-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 52,004 kB
  • sloc: ansic: 261,462; cpp: 140,405; sh: 14,891; perl: 9,846; python: 2,525; lisp: 2,504; asm: 860; makefile: 678; pascal: 70; java: 52; xml: 37; awk: 12
file content (145 lines) | stat: -rw-r--r-- 3,372 bytes parent folder | download | duplicates (2)
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
#include "stdafx.h"
#include "ParentReq.h"
#include "Core/StrBuf.h"
#include "Utils/Bitwise.h"
#include <climits>

namespace storm {
	namespace syntax {
		namespace glr {

			static const Nat bitsPerEntry = CHAR_BIT * sizeof(Nat);

			ParentReq::ParentReq() : data(null) {}

			ParentReq::ParentReq(Engine &e, Nat elem) {
				data = runtime::allocArray<Nat>(e, &natArrayType, elem/bitsPerEntry + 1);
				data->v[elem / bitsPerEntry] = Nat(1) << (elem % bitsPerEntry);
			}

			ParentReq::ParentReq(GcArray<Nat> *data) : data(data) {}

			Nat ParentReq::count() const {
				if (!data)
					return 0;

				Nat result = 0;
				for (Nat i = 0; i < data->count; i++)
					result += setBitCount(data->v[i]);

				return result;
			}

			Nat ParentReq::max() const {
				if (data)
					return Nat(data->count) * bitsPerEntry;
				else
					return 0;
			}

			Bool ParentReq::get(Nat id) const {
				if (id >= max())
					return false;
				return (data->v[id / bitsPerEntry] >> (id % bitsPerEntry)) & 1;
			}

			ParentReq ParentReq::concat(Engine &e, ParentReq other) const {
				if (empty())
					return other;
				if (other.empty())
					return *this;

				// Now, we know that both are non-empty!
				GcArray<Nat> *srcSmall = data;
				GcArray<Nat> *srcLarge = other.data;
				if (srcSmall->count > srcLarge->count)
					swap(srcSmall, srcLarge);

				GcArray<Nat> *r = runtime::allocArray<Nat>(e, &natArrayType, srcLarge->count);
				memcpy(r->v, srcLarge->v, srcLarge->count * sizeof(Nat));
				for (Nat i = 0; i < srcSmall->count; i++)
					r->v[i] |= srcSmall->v[i];

				return ParentReq(r);
			}

			ParentReq ParentReq::remove(Engine &e, ParentReq other) const {
				if (empty() || other.empty())
					return *this;

				// Check size of the resulting structure...
				Nat count = 0;
				Nat to = Nat(::min(data->count, other.data->count));
				for (Nat i = 0; i < to; i++) {
					if (data->v[i] & ~other.data->v[i])
						count = i + 1;
				}

				// Empty?
				if (count == 0)
					return ParentReq();

				GcArray<Nat> *r = runtime::allocArray<Nat>(e, &natArrayType, count);
				for (Nat i = 0; i < count; i++)
					r->v[i] = data->v[i] & ~other.data->v[i];

				return ParentReq(r);
			}

			Bool ParentReq::has(ParentReq other) const {
				if (other.empty())
					return true;
				if (empty())
					return false;
				if (other.data->count > data->count)
					return false;

				Nat to = Nat(other.data->count);
				for (Nat i = 0; i < to; i++) {
					if ((data->v[i] & other.data->v[i]) != other.data->v[i])
						return false;
				}

				return true;
			}

			Bool ParentReq::operator ==(const ParentReq &o) const {
				if (data && o.data) {
					if (data->count != o.data->count)
						return false;

					return memcmp(data->v, o.data->v, data->count * sizeof(Nat)) == 0;
				} else {
					// At least one of them is null.
					return data == o.data;
				}
			}

			wostream &operator <<(wostream &to, const ParentReq &r) {
				if (r.empty()) {
					to << L"{}";
				} else {
					to << L"{";
					for (Nat i = 0; i < r.max(); i++)
						if (r.get(i))
							to << L" " << i;
					to << L" }";
				}
				return to;
			}

			void ParentReq::toS(StrBuf *to) const {
				if (empty()) {
					*to << S("{}");
				} else {
					*to << S("{");
					for (Nat i = 0; i < max(); i++)
						if (get(i))
							*to << S(" ") << i;
					*to << S(" }");
				}
			}

		}
	}
}