annotate foosdk/sdk/pfc/bit_array.cpp @ 1:20d02a178406 default tip

*: check in everything else yay
author Paper <paper@tflc.us>
date Mon, 05 Jan 2026 02:15:46 -0500
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1 #include "pfc-lite.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
2 #include "bit_array.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
3 #include "bit_array_impl.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
4 #include "bit_array_impl_part2.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
5 #include "sort.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
6
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
7 namespace pfc {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
8 void bit_array::for_each(bool value, size_t base, size_t max, std::function<void(size_t)> f) const {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
9 for( size_t idx = find_first(value, base, max); idx < max; idx = find_next(value, idx, max) ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
10 f(idx);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
11 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
12 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
13 t_size bit_array::find(bool val, t_size start, t_ssize count) const
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
14 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
15 t_ssize d, todo, ptr = start;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
16 if (count == 0) return start;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
17 else if (count<0) { d = -1; todo = -count; }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
18 else { d = 1; todo = count; }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
19 while (todo>0 && get(ptr) != val) { ptr += d;todo--; }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
20 return ptr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
21 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
22
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
23 t_size bit_array::calc_count(bool val, t_size start, t_size count, t_size count_max) const
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
24 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
25 t_size found = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
26 t_size max = start + count;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
27 t_size ptr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
28 for (ptr = find(val, start, count);found<count_max && ptr<max;ptr = find(val, ptr + 1, max - ptr - 1)) found++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
29 return found;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
30 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
31 t_size bit_array::find_first(bool val, t_size start, t_size max) const {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
32 return find(val, start, max - start);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
33 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
34 t_size bit_array::find_next(bool val, t_size previous, t_size max) const {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
35 return find(val, previous + 1, max - (previous + 1));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
36 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
37 void bit_array::walk(size_t to, std::function< void ( size_t ) > f, bool val ) const {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
38 for ( size_t w = find_first(val, 0, to ); w < to; w = find_next(val, w, to) ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
39 f(w);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
40 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
41 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
42 void bit_array::walkBack(size_t from, std::function<void (size_t) > f, bool val) const {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
43 t_ssize walk = from;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
44 if ( walk == 0 ) return;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
45 for( ;; ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
46 walk = find(val, walk-1, - walk );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
47 if ( walk < 0 ) return;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
48 f ( walk );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
49 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
50 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
51
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
52 bit_array_var_impl::bit_array_var_impl( const bit_array & source, size_t sourceCount) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
53 for(size_t w = source.find_first( true, 0, sourceCount); w < sourceCount; w = source.find_next( true, w, sourceCount ) ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
54 set(w, true);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
55 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
56 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
57
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
58 bool bit_array_var_impl::get(t_size n) const {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
59 return m_data.have_item(n);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
60 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
61 t_size bit_array_var_impl::find(bool val,t_size start,t_ssize count) const {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
62 if (!val) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
63 return bit_array::find(false, start, count); //optimizeme.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
64 } else if (count > 0) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
65 const t_size * v = m_data.find_nearest_item<true, true>(start);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
66 if (v == NULL || *v > start+count) return start + count;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
67 return *v;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
68 } else if (count < 0) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
69 const t_size * v = m_data.find_nearest_item<true, false>(start);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
70 if (v == NULL || *v < start+count) return start + count;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
71 return *v;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
72 } else return start;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
73 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
74
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
75 void bit_array_var_impl::set(t_size n,bool val) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
76 if (val) m_data += n;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
77 else m_data -= n;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
78 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
79
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
80
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
81 bit_array_flatIndexList::bit_array_flatIndexList() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
82 m_content.prealloc( 1024 );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
83 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
84
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
85 void bit_array_flatIndexList::add( size_t n ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
86 m_content.append_single_val( n );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
87 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
88
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
89 bool bit_array_flatIndexList::get(t_size n) const {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
90 size_t dummy;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
91 return _find( n, dummy );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
92 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
93 t_size bit_array_flatIndexList::find(bool val,t_size start,t_ssize count) const {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
94 if (val == false) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
95 // unoptimized but not really used
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
96 return bit_array::find(val, start, count);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
97 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
98
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
99 if (count==0) return start;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
100 else if (count<0) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
101 size_t idx;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
102 if (!_findNearestDown( start, idx ) || (t_ssize)m_content[idx] < (t_ssize)start+count) return start + count;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
103 return m_content[idx];
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
104 } else { // count > 0
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
105 size_t idx;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
106 if (!_findNearestUp( start, idx ) || m_content[idx] > start+count) return start + count;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
107 return m_content[idx];
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
108 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
109 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
110
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
111 bool bit_array_flatIndexList::_findNearestUp( size_t val, size_t & outIdx ) const {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
112 size_t idx;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
113 if (_find( val, idx )) { outIdx = idx; return true; }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
114 // we have a valid outIdx at where the bsearch gave up
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
115 PFC_ASSERT ( idx == 0 || m_content [ idx - 1 ] < val );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
116 PFC_ASSERT ( idx == m_content.get_size() || m_content[ idx ] > val );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
117 if (idx == m_content.get_size()) return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
118 outIdx = idx;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
119 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
120 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
121 bool bit_array_flatIndexList::_findNearestDown( size_t val, size_t & outIdx ) const {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
122 size_t idx;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
123 if (_find( val, idx )) { outIdx = idx; return true; }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
124 // we have a valid outIdx at where the bsearch gave up
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
125 PFC_ASSERT ( idx == 0 || m_content [ idx - 1 ] < val );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
126 PFC_ASSERT ( idx == m_content.get_size() || m_content[ idx ] > val );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
127 if (idx == 0) return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
128 outIdx = idx - 1;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
129 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
130 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
131
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
132 void bit_array_flatIndexList::presort() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
133 pfc::sort_t( m_content, pfc::compare_t< size_t, size_t >, m_content.get_size( ) );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
134 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
135
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
136
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
137 bit_array_bittable::bit_array_bittable(const pfc::bit_array & in, size_t inSize) : m_count() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
138 resize(inSize);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
139 for (size_t w = in.find_first(true, 0, inSize); w < inSize; w = in.find_next(true, w, inSize)) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
140 set(w, true);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
141 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
142 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
143
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
144 void bit_array_bittable::resize(t_size p_count)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
145 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
146 t_size old_bytes = g_estimate_size(m_count);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
147 m_count = p_count;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
148 t_size bytes = g_estimate_size(m_count);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
149 m_data.set_size(bytes);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
150 if (bytes > old_bytes) pfc::memset_null_t(m_data.get_ptr() + old_bytes, bytes - old_bytes);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
151 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
152
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
153 void bit_array_bittable::set(t_size n, bool val)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
154 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
155 if (n<m_count)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
156 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
157 g_set(m_data, n, val);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
158 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
159 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
160
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
161 bool bit_array_bittable::get(t_size n) const
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
162 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
163 bool rv = false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
164 if (n<m_count) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
165 rv = g_get(m_data, n);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
166 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
167 return rv;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
168 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
169
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
170 t_size bit_array_one::find(bool p_val, t_size start, t_ssize count) const
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
171 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
172 if (count == 0) return start;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
173 else if (p_val)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
174 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
175 if (count>0)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
176 return (val >= start && (t_ssize)val < (t_ssize)start + count) ? val : start + count;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
177 else
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
178 return (val <= start && (t_ssize)val > (t_ssize)start + count) ? val : start + count;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
179 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
180 else
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
181 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
182 if (start == val) return count>0 ? start + 1 : start - 1;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
183 else return start;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
184 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
185 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
186 } // namespace pfc