co_ecs 0.9.0
Cobalt ECS
Loading...
Searching...
No Matches
dynamic_bitset.hpp
Go to the documentation of this file.
1#pragma once
2
4
5#include <algorithm>
6#include <climits>
7#include <cstdint>
8#include <ranges>
9#include <vector>
10
11namespace co_ecs::detail {
12
18template<typename T = std::uint64_t, typename A = std::allocator<T>>
19class dynamic_bitset {
20public:
21 using block_type = T;
22 using allocator_type = A;
23 using storage_type = std::vector<block_type, allocator_type>;
24
28 explicit dynamic_bitset(std::size_t initial_blocks = 1) {
29 _blocks.resize(initial_blocks);
30 }
31
37 [[nodiscard]] inline auto test(std::size_t pos) const noexcept -> bool {
38 const auto [block_index, bit_pos] = block_and_bit(pos);
39 if (block_index < _blocks.size()) {
40 return _blocks[block_index] & (block_type{ 1 } << bit_pos);
41 }
42 return false;
43 }
44
50 inline auto set(std::size_t pos, bool value = true) -> dynamic_bitset& {
51 const auto [block_index, bit_pos] = block_and_bit(pos);
52 if (block_index >= _blocks.size()) {
53 _blocks.resize(block_index + 1);
54 }
55 if (value) {
56 _blocks[block_index] |= (block_type{ 1 } << bit_pos);
57 } else {
58 _blocks[block_index] &= ~(block_type{ 1 } << bit_pos);
59
60 std::size_t i = _blocks.size() - 1;
61 while (!_blocks[i] && i != 0) {
62 i--;
63 }
64 _blocks.resize(i + 1);
65 }
66 return *this;
67 }
68
70 inline void clear() noexcept {
71 _blocks.resize(1);
72 _blocks[0] = 0;
73 }
74
80 auto operator==(const dynamic_bitset& rhs) const noexcept -> bool {
81 return std::ranges::equal(_blocks, rhs._blocks);
82 }
83
84private:
85 friend struct std::hash<dynamic_bitset>;
86
87 static inline auto block_and_bit(std::size_t pos) -> std::pair<std::size_t, std::size_t> {
88 const auto bit_pos = pos % (sizeof(block_type) * CHAR_BIT);
89 const auto block_index = pos / (sizeof(block_type) * CHAR_BIT);
90 return std::make_pair(block_index, bit_pos);
91 }
92
93 storage_type _blocks;
94};
95
96} // namespace co_ecs::detail
97
98namespace std {
99
101template<typename A>
102struct hash<co_ecs::detail::dynamic_bitset<A>> {
103 auto operator()(const co_ecs::detail::dynamic_bitset<A>& bitset) const -> std::size_t {
104 std::size_t hash = 0;
105 for (auto block : bitset._blocks) {
106 hash ^= block;
107 }
108 return hash;
109 }
110};
111
112} // namespace std
Definition component.hpp:17
Definition archetype.hpp:11
STL namespace.
constexpr bool operator==(const co_ecs::detail::temp_allocator< T > &, const co_ecs::detail::temp_allocator< U > &) noexcept
Definition temp_allocator.hpp:60