17template<
typename K,
typename T,
bool is_map,
typename Allocator>
21 using mapped_type = T;
22 using value_type = std::conditional_t<is_map, std::pair<key_type, mapped_type>, key_type>;
23 using size_type = std::size_t;
24 using difference_type = std::ptrdiff_t;
25 using allocator_type = Allocator;
26 using reference = value_type&;
27 using const_reference =
const value_type&;
28 using pointer =
typename std::allocator_traits<allocator_type>::pointer;
29 using const_pointer =
typename std::allocator_traits<allocator_type>::const_pointer;
30 using iterator =
typename std::vector<value_type>::iterator;
31 using const_iterator =
typename std::vector<value_type>::const_iterator;
33 static_assert(
sizeof(key_type) <=
sizeof(std::size_t));
36 constexpr sparse_table() =
default;
41 constexpr sparse_table(sparse_table&& rhs)
noexcept =
default;
46 constexpr sparse_table(
const sparse_table& rhs) =
default;
52 constexpr auto operator=(sparse_table&& rhs)
noexcept -> sparse_table& =
default;
58 constexpr auto operator=(
const sparse_table& rhs) -> sparse_table& =
default;
61 constexpr ~sparse_table() =
default;
66 constexpr sparse_table(std::initializer_list<value_type> list) {
67 _dense.reserve(list.size());
68 for (
const auto& entry : list) {
76 constexpr auto begin() noexcept -> iterator {
77 return _dense.begin();
83 constexpr auto end() noexcept -> iterator {
90 constexpr auto begin() const noexcept -> const_iterator {
91 return _dense.begin();
97 constexpr auto end() const noexcept -> const_iterator {
104 constexpr auto cbegin() const noexcept -> const_iterator {
105 return _dense.cbegin();
111 constexpr auto cend() const noexcept -> const_iterator {
112 return _dense.cend();
118 [[nodiscard]]
constexpr auto size() const ->
std::
size_t {
125 [[nodiscard]]
constexpr auto capacity() const ->
std::
size_t {
126 return _sparse_capacity;
130 [[nodiscard]]
constexpr auto empty() const ->
bool {
135 constexpr void clear() noexcept {
143 constexpr void reserve_dense(std::size_t capacity) {
144 _dense.reserve(capacity);
150 constexpr void reserve_sparse(std::size_t capacity) {
151 if (capacity > _sparse_capacity) {
152 _sparse.resize(capacity);
153 _sparse_capacity = capacity;
163 constexpr auto find(key_type key)
const noexcept -> const_iterator {
164 return find_impl(*
this, key);
173 constexpr auto find(key_type key)
noexcept -> iterator {
174 return find_impl(*
this, key);
181 constexpr auto contains(key_type key)
const noexcept ->
bool {
182 return find(key) != end();
191 constexpr auto insert(
const value_type& entry) -> std::pair<iterator, bool> {
192 return emplace(get_key(entry), std::move(get_value(entry)));
203 template<
typename... Args>
204 constexpr auto emplace(key_type key, Args&&... args) -> std::pair<iterator, bool> {
206 return std::pair(_dense.begin() + _sparse[key],
false);
209 reserve_sparse(
static_cast<std::size_t
>(key) + 1);
211 if constexpr (is_map) {
212 _dense.emplace_back(std::piecewise_construct,
213 std::forward_as_tuple(key),
214 std::forward_as_tuple(std::forward<Args>(args)...));
216 _dense.emplace_back(key);
218 _sparse[key] = _size;
220 return std::pair(_dense.begin() + _sparse[key],
true);
229 constexpr auto at(
const key_type& key) -> mapped_type&
232 if (!contains(key)) {
233 throw std::out_of_range(
"Key is not in the BaseSparseSet");
235 return get_value(_dense[_sparse[key]]);
244 constexpr auto at(
const key_type& key)
const ->
const mapped_type&
247 if (!contains(key)) {
248 throw std::out_of_range(
"Key is not in the BaseSparseSet");
250 return get_value(_dense[_sparse[key]]);
258 constexpr auto operator[](
const key_type& key)
noexcept -> mapped_type&
261 auto [iter, _] = emplace(key);
262 mapped_type& value = get_value(*iter);
270 constexpr auto erase(key_type key)
noexcept -> std::size_t {
272 _dense[_sparse[key]] = std::move(_dense.back());
273 _sparse[get_key(_dense[_size - 1])] = _sparse[key];
282 constexpr static auto find_impl(
auto& self,
auto& key) ->
decltype(
auto) {
283 if (key < self._sparse_capacity && self._sparse[key] < self._size
284 && get_key(self._dense[self._sparse[key]]) == key) {
285 return self.begin() + self._sparse[key];
290 constexpr static auto get_key(
auto& entry) ->
auto& {
291 if constexpr (is_map) {
298 constexpr static auto get_value(
auto& entry) ->
auto& {
299 if constexpr (is_map) {
306 std::vector<value_type, Allocator> _dense;
307 std::vector<key_type> _sparse;
310 size_t _sparse_capacity{};
Definition component.hpp:17