48 class BufferAllocator<bool, 0, true, t_index_type, false>
52 using index_type = t_index_type;
65 std::swap(allocator.m_buffer, m_buffer);
66 std::swap(allocator.m_filled_size, m_filled_size);
67 std::swap(allocator.m_allocated_size, m_allocated_size);
71 if (m_allocated_size != 0)
74 template<
bool t_managed>
77 m_filled_size += size;
80 template<
bool t_managed>
81 void createSpace(t_index_type location, t_index_type size)
84 bitmove(
begin() + location + size,
begin() + location, m_filled_size - (size + location));
100 lib_assert(location <= m_filled_size,
"Out of bounds add all");
102 bitmove(
begin() + location + 1,
begin() + location, (m_filled_size - location - 1));
106 lib_assert(location <= m_filled_size,
"Out of bounds add all");
107 bitmove(
begin() + location,
begin() + location + 1, (m_filled_size - location));
112 t_index_type min_size = bitset_wrd(
getMin(allocator.filledSize(), filledSize()));
116 sint04 compare(
const BufferAllocator& allocator, t_index_type start, t_index_type end)
const
118 sint04 cmp_value = memcmp(&(m_buffer[start]), &(allocator.m_buffer[start]),
getMin(allocator.filledSize(), filledSize(), end));
121 void swap(t_index_type index_a, t_index_type index_b)
123 std::swap(m_buffer[index_a], m_buffer[index_b]);
129 void setSize(t_index_type size)
131 m_filled_size = size;
136 lib_assert(index < m_filled_size,
"Array out of bounds");
137 return BitReference(m_buffer[bitset_wrd(index)], bitset_idx(index));
139 bool get(t_index_type index)
const
141 lib_assert(index < m_filled_size,
"Array out of bounds");
142 return m_buffer[bitset_wrd(index)][bitset_idx(index)];
159 return m_allocated_size;
171 return BitIterator(m_buffer, m_filled_size - index);
185 if (m_filled_size == 0)
187 return bitset_wrd(m_filled_size - 1) + 1;
189 void setAll(
const bool&
object, t_index_type offset, t_index_type size)
194 t_index_type first_word = bitset_wrd(offset);
195 t_index_type last_word = bitset_wrd(offset + size - 1);
196 t_index_type foffset = bitset_idx(offset);
197 t_index_type loffset = bitset_idx(offset + size - 1);
199 if (first_word == last_word)
201 uint01 mask = bitmask(size) << foffset;
203 m_buffer[first_word] |=
BitFlag(mask);
205 m_buffer[first_word] &=
BitFlag(~mask);
211 m_buffer[first_word] |=
BitFlag(~bitmask(foffset));
213 m_buffer[first_word] &=
BitFlag(bitmask(foffset));
214 memset(m_buffer + first_word + 1,
object ? 0xFF : 0, last_word - (first_word + 1));
217 m_buffer[last_word] |=
BitFlag(bitmask(loffset + 1));
219 m_buffer[last_word] &=
BitFlag(~bitmask(loffset + 1));
222 for (
uint04 i = 0; i < size; i++)
223 lib_assert(
get(i + offset) ==
object,
"Bad optimized set");
226 template<
bool is_primitive>
227 void setAll(
const bool* src, t_index_type offset, t_index_type size)
229 for (t_index_type i = 0; i < size; i++)
231 get(i + offset) = src[i];
235 template<
bool is_primitive>
236 void setAll(
const BufferAllocator& allocator, t_index_type offset, t_index_type other_offset, t_index_type size)
238 if(bitset_idx(offset) == 0 && bitset_idx(other_offset) == 0)
240 t_index_type new_size = bitset_wrd(size);
241 t_index_type new_offset = bitset_wrd(offset);
242 t_index_type new_other_offset = bitset_wrd(other_offset);
243 memmove(m_buffer + new_offset, allocator.m_buffer + new_other_offset, new_size);
244 for (t_index_type i = 8 * new_size; i < size; i++)
246 get(i + offset) = allocator.get(i + other_offset);
249 for (t_index_type i = 0; i < size; i++)
251 get(i + offset) = allocator.get(i + other_offset);
254 template<
class t_other_allocator>
255 void setAllFromSource(
const t_other_allocator& allocator, t_index_type offset, t_index_type other_offset, t_index_type size)
257 for (t_index_type i = 0; i < size; i++)
258 get(i + offset) = allocator.get(i + other_offset);
260 template<
bool is_primitive>
264 for (t_index_type i = 0; i < size; i++)
266 get(i + offset) = iterator;
270 template<
bool t_managed>
273 if ((t_managed && m_filled_size > m_allocated_size) || m_filled_size == m_allocated_size + 1)
275 lib_assert(
cast<uint08>((t_managed ? m_filled_size : m_allocated_size) * 3) / 2 <
cast<uint08>(Constant<uint04>::Max),
"Buffer overflow");
278 else if (m_filled_size > m_allocated_size)
285 if (end == m_filled_size)
287 m_filled_size = start;
291 bitmove(
begin() + start,
begin() + end, (m_filled_size - end));
292 m_filled_size -= (end - start);
298 return m_filled_size;
300 t_index_type
count(
const bool& value)
const
303 for (
uint04 i = 0; i < m_filled_size; i++)
311 template<
class t_comparable_type>
312 bool contains(
const t_comparable_type& value, t_index_type start, t_index_type size)
const
314 bool bool_val = value;
315 t_index_type end = start + size;
317 t_index_type byte_start = (start + 7) & ~7;
318 for (t_index_type i = start; i < byte_start && i < end; ++i)
320 if (
get(i) == bool_val)
325 t_index_type byte_end = end & ~7;
326 for (t_index_type i = byte_end; i < end; ++i)
328 if (
get(i) == bool_val)
332 t_index_type byte_begin = byte_start / 8;
333 t_index_type byte_finish = byte_end / 8;
338 for (t_index_type i = byte_begin; i < byte_finish; ++i)
340 if (m_buffer[i] != off)
346 for (t_index_type i = byte_begin; i < byte_finish; ++i)
348 if (m_buffer[i] != on)
354 inline BufferAllocator&
operator=(BufferAllocator&& value)
noexcept
356 std::swap(value.m_buffer, m_buffer);
357 std::swap(value.m_filled_size, m_filled_size);
358 std::swap(value.m_allocated_size, m_allocated_size);
364 t_index_type byte_size = new_size == 0 ? 0 : bitset_wrd(new_size - 1) + 1;
367 if (m_allocated_size != 0)
373 if (m_allocated_size == 0)
377 lib_assert(m_buffer !=
nullptr,
"Unable to allocate buffer");
379 m_allocated_size = 8 * byte_size;
383 t_index_type numSet()
const
385 static const t_index_type BitsSetTable256[256] =
387 # define NDV_B2(n) n, n+1, n+1, n+2
388 # define NDV_B4(n) NDV_B2(n), NDV_B2(n+1), NDV_B2(n+1), NDV_B2(n+2)
389 # define NDV_B6(n) NDV_B4(n), NDV_B4(n+1), NDV_B4(n+1), NDV_B4(n+2)
390 NDV_B6(0), NDV_B6(1), NDV_B6(1), NDV_B6(2)
392 t_index_type flag_size = bitset_wrd(
filledSize());
393 t_index_type num_set = 0;
395 flag_size = flag_size ^ ((flag_size ^
filledSize()) & *mask);
397 for (t_index_type i = 0; i < flag_size; i++)
399 num_set += BitsSetTable256[m_buffer[i]];
404 for (t_index_type i = 0; i < size_mod_8; i++)
406 num_set += m_buffer[flag_size][i] ? 1 : 0;
421 for (t_index_type i = 0; i < size; i++)
430 for (t_index_type i = size - 1;
IsValid(i); i--)
432 *(dst + i) = *(src + i);
436 void setFlag(
const t_index_type index,
const bool value)
438 m_buffer[bitset_wrd(index)](index & 7, value);
444 const t_index_type byte_size =
memSize();
445 for (t_index_type i = 0; i < byte_size; i++)
447 m_buffer[i] = ~m_buffer[i];
450 void inverseAndEquals(
const BufferAllocator<bool, 0, true, t_index_type>& buffer)
452 lib_assert(
memSize() == buffer.
memSize(),
"Cannot ^= two buffers of different length");
453 const t_index_type byte_size =
memSize();
454 for (t_index_type i = 0; i < byte_size; i++)
455 m_buffer[i] &= (~buffer.
m_buffer[i]);
457 void operator^=(
const BufferAllocator<bool, 0, true, t_index_type>& buffer)
459 lib_assert(
memSize() == buffer.
memSize(),
"Cannot ^= two buffers of different length");
460 const t_index_type byte_size =
memSize();
461 for (t_index_type i = 0; i < byte_size; i++)
464 void operator|=(
const BufferAllocator<bool, 0, true, t_index_type>& buffer)
466 lib_assert(
memSize() == buffer.
memSize(),
"Cannot |= two buffers of different length");
467 const t_index_type byte_size =
memSize();
468 for (t_index_type i = 0; i < byte_size; i++)
471 void operator&=(
const BufferAllocator<bool, 0, true, t_index_type>& buffer)
473 lib_assert(
memSize() == buffer.
memSize(),
"Cannot &= two buffers of different length");
474 const t_index_type byte_size =
memSize();
475 for (t_index_type i = 0; i < byte_size; i++)
480 t_index_type m_filled_size;
481 t_index_type m_allocated_size;