|
1
|
1 #pragma once
|
|
|
2 #include "array.h"
|
|
|
3
|
|
|
4 namespace pfc {
|
|
|
5 template<typename T>
|
|
|
6 class bit_array_table_t : public bit_array
|
|
|
7 {
|
|
|
8 const T * data;
|
|
|
9 t_size count;
|
|
|
10 bool after;
|
|
|
11 public:
|
|
|
12 inline bit_array_table_t(const T * p_data,t_size p_count,bool p_after = false)
|
|
|
13 : data(p_data), count(p_count), after(p_after)
|
|
|
14 {
|
|
|
15 }
|
|
|
16
|
|
|
17 bool get(t_size n) const
|
|
|
18 {
|
|
|
19 if (n<count) return !!data[n];
|
|
|
20 else return after;
|
|
|
21 }
|
|
|
22 };
|
|
|
23
|
|
|
24 template<class T>
|
|
|
25 class bit_array_var_table_t : public bit_array_var
|
|
|
26 {
|
|
|
27 T * data;
|
|
|
28 t_size count;
|
|
|
29 bool after;
|
|
|
30 public:
|
|
|
31 inline bit_array_var_table_t(T * p_data,t_size p_count,bool p_after = false)
|
|
|
32 : data(p_data), count(p_count), after(p_after)
|
|
|
33 {
|
|
|
34 }
|
|
|
35
|
|
|
36 bool get(t_size n) const {
|
|
|
37 if (n<count) return !!data[n];
|
|
|
38 else return after;
|
|
|
39 }
|
|
|
40
|
|
|
41 void set(t_size n,bool val) {
|
|
|
42 if (n<count) data[n] = !!val;
|
|
|
43 }
|
|
|
44 };
|
|
|
45
|
|
|
46
|
|
|
47 typedef bit_array_table_t<bool> bit_array_table;
|
|
|
48 typedef bit_array_var_table_t<bool> bit_array_var_table;
|
|
|
49
|
|
|
50 class bit_array_range : public bit_array
|
|
|
51 {
|
|
|
52 t_size begin,end;
|
|
|
53 bool state;
|
|
|
54 public:
|
|
|
55 bit_array_range(t_size first,t_size count,bool p_state = true) : begin(first), end(first+count), state(p_state) {}
|
|
|
56
|
|
|
57 bool get(t_size n) const
|
|
|
58 {
|
|
|
59 bool rv = n>=begin && n<end;
|
|
|
60 if (!state) rv = !rv;
|
|
|
61 return rv;
|
|
|
62 }
|
|
|
63 };
|
|
|
64
|
|
|
65 //! Combines two arrays using the AND logical operator. \n
|
|
|
66 //! Valid index range is an intersection of valid index ranges of the parameter arrays.
|
|
|
67 class bit_array_and : public bit_array
|
|
|
68 {
|
|
|
69 const bit_array & a1, & a2;
|
|
|
70 public:
|
|
|
71 bit_array_and(const bit_array & p_a1, const bit_array & p_a2) : a1(p_a1), a2(p_a2) {}
|
|
|
72 bool get(t_size n) const {return a1.get(n) && a2.get(n);}
|
|
|
73 };
|
|
|
74
|
|
|
75 //! Combines two arrays using the OR logical operator. \n
|
|
|
76 //! Valid index range is an intersection of valid index ranges of the parameter arrays.
|
|
|
77 class bit_array_or : public bit_array
|
|
|
78 {
|
|
|
79 const bit_array & a1, & a2;
|
|
|
80 public:
|
|
|
81 bit_array_or(const bit_array & p_a1, const bit_array & p_a2) : a1(p_a1), a2(p_a2) {}
|
|
|
82 bool get(t_size n) const {return a1.get(n) || a2.get(n);}
|
|
|
83 };
|
|
|
84
|
|
|
85 //! Combines two arrays using the XOR logical operator. \n
|
|
|
86 //! Valid index range is an intersection of valid index ranges of the parameter arrays.
|
|
|
87 class bit_array_xor : public bit_array
|
|
|
88 {
|
|
|
89 const bit_array & a1, & a2;
|
|
|
90 public:
|
|
|
91 bit_array_xor(const bit_array & p_a1, const bit_array & p_a2) : a1(p_a1), a2(p_a2) {}
|
|
|
92 bool get(t_size n) const
|
|
|
93 {
|
|
|
94 bool v1 = a1.get(n), v2 = a2.get(n);
|
|
|
95 return (v1 && !v2) || (!v1 && v2);
|
|
|
96 }
|
|
|
97 };
|
|
|
98
|
|
|
99 //! Negation of another array. \n
|
|
|
100 //! Valid index range is the same as valid index range of the parameter array.
|
|
|
101 class bit_array_not : public bit_array
|
|
|
102 {
|
|
|
103 const bit_array & a1;
|
|
|
104 public:
|
|
|
105 bit_array_not(const bit_array & p_a1) : a1(p_a1) {}
|
|
|
106 bool get(t_size n) const {return !a1.get(n);}
|
|
|
107 t_size find(bool val,t_size start,t_ssize count) const
|
|
|
108 {return a1.find(!val,start,count);}
|
|
|
109
|
|
|
110 };
|
|
|
111
|
|
|
112 class bit_array_true : public bit_array
|
|
|
113 {
|
|
|
114 public:
|
|
|
115 bool get(t_size) const {return true;}
|
|
|
116 t_size find(bool val,t_size start,t_ssize count) const
|
|
|
117 {return val ? start : start+count;}
|
|
|
118 };
|
|
|
119
|
|
|
120 class bit_array_false : public bit_array
|
|
|
121 {
|
|
|
122 public:
|
|
|
123 bool get(t_size) const {return false;}
|
|
|
124 t_size find(bool val,t_size start,t_ssize count) const
|
|
|
125 {return val ? start+count : start;}
|
|
|
126 };
|
|
|
127
|
|
|
128 class bit_array_val : public bit_array
|
|
|
129 {
|
|
|
130 bool val;
|
|
|
131 public:
|
|
|
132 bit_array_val(bool v) : val(v) {}
|
|
|
133 bool get(t_size) const {return val;}
|
|
|
134 t_size find(bool p_val,t_size start,t_ssize count) const
|
|
|
135 {return val==p_val ? start : start+count;}
|
|
|
136 };
|
|
|
137
|
|
|
138 class bit_array_one : public bit_array
|
|
|
139 {
|
|
|
140 t_size val;
|
|
|
141 public:
|
|
|
142 bit_array_one(t_size p_val) : val(p_val) {}
|
|
|
143 virtual bool get(t_size n) const {return n==val;}
|
|
|
144
|
|
|
145 virtual t_size find(bool p_val, t_size start, t_ssize count) const;
|
|
|
146 };
|
|
|
147
|
|
|
148 //! Generic variable bit_array implementation. \n
|
|
|
149 //! Needs to be initialized with requested array size before use.
|
|
|
150 class bit_array_bittable : public bit_array_var
|
|
|
151 {
|
|
|
152 pfc::array_t<t_uint8> m_data;
|
|
|
153 t_size m_count;
|
|
|
154 public:
|
|
|
155 //helpers
|
|
|
156 template<typename t_array>
|
|
|
157 inline static bool g_get(const t_array & p_array,t_size idx)
|
|
|
158 {
|
|
|
159 return !! (p_array[idx>>3] & (1<<(idx&7)));
|
|
|
160 }
|
|
|
161
|
|
|
162 template<typename t_array>
|
|
|
163 inline static void g_set(t_array & p_array,t_size idx,bool val)
|
|
|
164 {
|
|
|
165 unsigned char & dst = p_array[idx>>3];
|
|
|
166 unsigned char mask = 1<<(idx&7);
|
|
|
167 dst = val ? dst|mask : dst&~mask;
|
|
|
168 }
|
|
|
169
|
|
|
170 inline static t_size g_estimate_size(t_size p_count) {return (p_count+7)>>3;}
|
|
|
171
|
|
|
172 void resize(t_size p_count);
|
|
|
173
|
|
|
174 bit_array_bittable(t_size p_count) : m_count(0) {resize(p_count);}
|
|
|
175 bit_array_bittable(const pfc::bit_array & in, size_t inSize);
|
|
|
176 bit_array_bittable() : m_count() {}
|
|
|
177
|
|
|
178
|
|
|
179 void set(t_size n, bool val);
|
|
|
180
|
|
|
181 bool get(t_size n) const;
|
|
|
182
|
|
|
183 size_t size() const {return m_count;}
|
|
|
184 };
|
|
|
185
|
|
|
186
|
|
|
187 //! Bit array that takes a permutation and signals indexes reordered by the permutation. \n
|
|
|
188 //! Valid index range same as length of the permutation.
|
|
|
189 class bit_array_order_changed : public bit_array {
|
|
|
190 public:
|
|
|
191 bit_array_order_changed(const t_size * p_order) : m_order(p_order) {}
|
|
|
192 bool get(t_size n) const
|
|
|
193 {
|
|
|
194 return m_order[n] != n;
|
|
|
195 }
|
|
|
196
|
|
|
197 private:
|
|
|
198 const t_size * m_order;
|
|
|
199 };
|
|
|
200 }
|
|
|
201 // #define for_each_bit_array(var,mask,val,start,count) for(var = mask.find(val,start,count);var<start+count;var=mask.find(val,var+1,count-(var+1-start)))
|