52#ifndef FASTLED_HASHMAP_INLINED_COUNT
53#define FASTLED_HASHMAP_INLINED_COUNT 8
56template <
typename Key,
typename T,
typename Hash = Hash<Key>,
57 typename KeyEqual = EqualTo<Key>,
58 int INLINED_COUNT = FASTLED_HASHMAP_INLINED_COUNT>
85 for (fl::size i = 0; i < other._buckets.size(); ++i) {
86 if (other.is_occupied(i)) {
87 insert(other._buckets[i].key, other._buckets[i].value);
100 other._tombstones = 0;
104 template<
typename InputIt>
126 if (
this != &other) {
131 if (
_buckets.size() != other._buckets.size()) {
133 _buckets.assign(other._buckets.size(), Entry{});
137 _deleted.resize(other._buckets.size());
141 for (fl::size i = 0; i < other._buckets.size(); ++i) {
142 if (other.is_occupied(i)) {
158 if (
this != &other) {
170 other._tombstones = 0;
225 return _map == o._map &&
_idx == o._idx;
232 fl::size cap =
_map->_buckets.size();
281 return _map == o._map &&
_idx == o._idx;
288 fl::size cap =
_map->_buckets.size();
306 return const_iterator(
this,
_buckets.size());
313 u32 lhs = (
size + tombstones) << 8;
347 FASTLED_ASSERT(idx !=
npos(),
"unordered_map::insert: invalid index");
350 return {iterator(
this, idx), is_new};
377 FASTLED_ASSERT(idx !=
npos(),
"unordered_map::insert: invalid index");
380 return {iterator(
this, idx), is_new};
386 return insert(kv.first, kv.second);
397 template<
typename InputIt>
399 for (; first != last; ++first) {
407 for (
const auto& kv :
init) {
434 FASTLED_ASSERT(idx !=
npos(),
"unordered_map::insert_or_assign: invalid index");
437 return {iterator(
this, idx), is_new};
461 FASTLED_ASSERT(idx !=
npos(),
"unordered_map::insert_or_assign: invalid index");
464 return {iterator(
this, idx), is_new};
469 template<
typename... Args>
479 template<
typename... Args>
487 template<
typename... Args>
510 return {iterator(
this, idx), is_new};
514 template<
typename... Args>
537 return {iterator(
this, idx), is_new};
555 if (it ==
end() || it._map !=
this) {
566 it.advance_to_occupied();
572 if (first._map !=
this || last._map !=
this) {
578 iterator current(
this, first._idx);
579 current.advance_to_occupied();
581 while (current !=
end() && current._idx < last._idx) {
582 fl::size idx_to_erase = current._idx;
584 current.advance_to_occupied();
628 return idx ==
npos() ?
end() : iterator(
this, idx);
633 return idx ==
npos() ?
end() : const_iterator(
this, idx);
638 return idx !=
npos();
644 FASTLED_ASSERT(
value !=
nullptr,
"unordered_map::at: key not found");
650 FASTLED_ASSERT(
value !=
nullptr,
"unordered_map::at: key not found");
661 iterator it =
find(key);
671 const_iterator it =
find(key);
675 const_iterator next = it;
713 static T default_value{};
714 FASTLED_ASSERT(
false,
"unordered_map::operator[]: Failed to allocate after rehash");
715 return default_value;
736 return static_cast<fl::size
>(-1) /
sizeof(Entry);
752 return static_cast<float>(
_size) /
static_cast<float>(
_buckets.size());
774 fl::size min_buckets =
_size;
775 if (n < min_buckets) {
790 if (max_lf <= 0.0f) {
794 fl::size required_buckets =
static_cast<fl::size
>(
795 static_cast<float>(n) / max_lf + 0.999999f
797 if (required_buckets >
_buckets.size()) {
804 return static_cast<fl::size
>(-1);
849 const fl::size cap =
_buckets.size();
850 const fl::size mask = cap - 1;
851 const fl::size h =
_hash(key) & mask;
852 fl::size first_tomb =
npos();
858 for (fl::size i = 0; i < cap; ++i) {
862 return {first_tomb !=
npos() ? first_tomb : idx,
true};
864 if (first_tomb ==
npos())
871 return {
npos(),
false};
882 const fl::size cap =
_buckets.size();
883 const fl::size mask = cap - 1;
884 const fl::size h =
_hash(key) & mask;
887 for (fl::size i = 0; i < cap; ++i) {
899 const Key &key,
const fl::bitset<1024> &occupied_set)
const FL_NO_EXCEPT {
900 const fl::size cap =
_buckets.size();
901 const fl::size mask = cap - 1;
902 const fl::size h =
_hash(key) & mask;
905 for (fl::size i = 0; i < cap; ++i) {
907 if (!occupied_set.test(idx)) {
917 fl::bitset<1024> old_occupied =
_occupied;
930 for (fl::size i = 0; i < old.
size(); i++) {
931 if (old_occupied.test(i))
944 for (fl::size i = 0; i < cap; ++i) {
957 fl::bitset<1024> occupied;
962 for (fl::size i = 0; i <
_size; ++i) {
963 const bool already_finished = occupied.test(i);
964 if (already_finished) {
976 false,
"unordered_map::rehash_inline_no_resize: invalid index");
981 "unordered_map::rehash_inline_no_resize: invalid tmp");
990 while (!tmp.
empty()) {
993 auto key = tmp.
ptr()->key;
996 if (new_idx ==
npos()) {
1000 "unordered_map::rehash_inline_no_resize: invalid index");
1003 occupied.set(new_idx);
1004 if (new_idx <
_size) {
1017 "unordered_map::rehash_inline_no_resize: invalid occupied");
1019 tmp.
empty(),
"unordered_map::rehash_inline_no_resize: invalid tmp");
1029 if (
size() != other.size())
return false;
1030 for (
const auto& kv : *
this) {
1031 auto it = other.find(kv.first);
1032 if (it == other.end() || it->second != kv.second)
return false;
1039 return !(*
this == other);
1059template <
typename Key,
typename T,
typename Hash = Hash<Key>,
1060 typename KeyEqual = equal_to<Key>>
Alignment macros and utilities for FastLED.
void reset() FL_NO_EXCEPT
bool empty() const FL_NO_EXCEPT
Polymorphic memory resource base class (PMR-style).
iterator find(const Key &key) FL_NO_EXCEPT
void reserve(fl::size n) FL_NO_EXCEPT
bool erase(const Key &key) FL_NO_EXCEPT
iterator emplace_hint(const_iterator hint, Args &&... args) FL_NO_EXCEPT
unordered_map & operator=(fl::initializer_list< pair< Key, T > > init) FL_NO_EXCEPT
const T * find_value(const Key &key) const FL_NO_EXCEPT
Hash< vec2< u16 > > _hash
fl::bitset< 1024 > _occupied
unordered_map(InputIt first, InputIt last) FL_NO_EXCEPT
bool is_occupied(fl::size idx) const FL_NO_EXCEPT
fl::size max_size() const FL_NO_EXCEPT
unordered_map(fl::size n, const Hash &hf, const KeyEqual &eq) FL_NO_EXCEPT
const_iterator find(const Key &key) const FL_NO_EXCEPT
bool operator!=(const unordered_map &other) const FL_NO_EXCEPT
Inequality comparison.
bool is_deleted(fl::size idx) const FL_NO_EXCEPT
Hash hash_function() const FL_NO_EXCEPT
fl::size size() const FL_NO_EXCEPT
void swap(unordered_map &other) FL_NO_EXCEPT
unordered_map & operator=(unordered_map &&other) FL_NO_EXCEPT
bool contains(const Key &key) const FL_NO_EXCEPT
unordered_map() FL_NO_EXCEPT
unordered_map & operator=(const unordered_map &other) FL_NO_EXCEPT
bool remove(const Key &key) FL_NO_EXCEPT
void rehash_internal(fl::size new_cap) FL_NO_EXCEPT
void clear() FL_NO_EXCEPT
pair< iterator, iterator > equal_range(const Key &key) FL_NO_EXCEPT
pair< iterator, bool > insert_or_assign(const Key &key, T &&value) FL_NO_EXCEPT
bool needs_rehash() const FL_NO_EXCEPT
EqualTo< vec2< u16 > > _equal
float max_load_factor() const FL_NO_EXCEPT
static fl::size npos() FL_NO_EXCEPT
static bool NeedsRehash(fl::size size, fl::size bucket_size, fl::size tombstones, u8 load_factor) FL_NO_EXCEPT
fl::vector_inlined< Entry, FASTLED_HASHMAP_INLINED_COUNT > _buckets
float load_factor() const FL_NO_EXCEPT
pair< iterator, bool > insert(const vec2< u16 > &key, const u8 &value) FL_NO_EXCEPT
const T & at(const Key &key) const FL_NO_EXCEPT
pair< iterator, bool > insert(const pair< Key, T > &kv) FL_NO_EXCEPT
void insert(InputIt first, InputIt last) FL_NO_EXCEPT
void mark_occupied(fl::size idx) FL_NO_EXCEPT
pair< iterator, bool > emplace(Args &&... args) FL_NO_EXCEPT
iterator end() FL_NO_EXCEPT
KeyEqual key_eq() const FL_NO_EXCEPT
pair< iterator, bool > insert_or_assign(Key &&key, T &&value) FL_NO_EXCEPT
bool empty() const FL_NO_EXCEPT
const_iterator cend() const FL_NO_EXCEPT
unordered_map(fl::size initial_capacity, float max_load) FL_NO_EXCEPT
pair< iterator, bool > insert(pair< Key, T > &&kv) FL_NO_EXCEPT
iterator erase(iterator it) FL_NO_EXCEPT
unordered_map(memory_resource *resource) FL_NO_EXCEPT
pair< iterator, bool > try_emplace(const Key &k, Args &&... args) FL_NO_EXCEPT
void mark_empty(fl::size idx) FL_NO_EXCEPT
FL_DISABLE_WARNING_PUSH FL_DISABLE_WARNING_NULL_DEREFERENCE void rehash_inline_no_resize() FL_NO_EXCEPT
bool operator==(const unordered_map &other) const FL_NO_EXCEPT
Equality comparison (map equality: same key-value pairs, order-independent)
bool is_empty(fl::size idx) const FL_NO_EXCEPT
T * find_value(const Key &key) FL_NO_EXCEPT
struct FL_ALIGN_AS_T(EntryAlign::value) Entry
void mark_deleted(fl::size idx) FL_NO_EXCEPT
void setLoadFactor(float f) FL_NO_EXCEPT
void max_load_factor(float ml) FL_NO_EXCEPT
memory_resource * get_memory_resource() const FL_NO_EXCEPT
fl::size find_unoccupied_index_using_bitset(const Key &key, const fl::bitset< 1024 > &occupied_set) const FL_NO_EXCEPT
unordered_map(fl::initializer_list< pair< Key, T > > init) FL_NO_EXCEPT
max_align< vec2< u16 >, u8 > EntryAlign
const_iterator begin() const FL_NO_EXCEPT
const_iterator cbegin() const FL_NO_EXCEPT
iterator begin() FL_NO_EXCEPT
pair< iterator, bool > insert(Key &&key, T &&value) FL_NO_EXCEPT
fl::size bucket_count() const FL_NO_EXCEPT
pair< fl::size, bool > find_slot(const vec2< u16 > &key) const FL_NO_EXCEPT
void insert(fl::initializer_list< pair< Key, T > > init) FL_NO_EXCEPT
pair< iterator, bool > try_emplace(Key &&k, Args &&... args) FL_NO_EXCEPT
T & at(const Key &key) FL_NO_EXCEPT
void rehash(fl::size n) FL_NO_EXCEPT
T & operator[](const Key &key) FL_NO_EXCEPT
pair< const_iterator, const_iterator > equal_range(const Key &key) const FL_NO_EXCEPT
fl::size capacity() const FL_NO_EXCEPT
iterator erase(const_iterator first, const_iterator last) FL_NO_EXCEPT
fl::bitset< 1024 > _deleted
unordered_map(const unordered_map &other) FL_NO_EXCEPT
static fl::size next_power_of_two(fl::size n) FL_NO_EXCEPT
fl::size find_index(const vec2< u16 > &key) const FL_NO_EXCEPT
const_iterator end() const FL_NO_EXCEPT
unordered_map(fl::size initial_capacity) FL_NO_EXCEPT
unordered_map(unordered_map &&other) FL_NO_EXCEPT
fl::size count(const Key &key) const FL_NO_EXCEPT
fl::size size() const FL_NO_EXCEPT
#define FL_DISABLE_WARNING_PUSH
#define FL_DISABLE_WARNING_SHORTEN_64_TO_32
#define FL_DISABLE_WARNING_NULL_DEREFERENCE
#define FL_DISABLE_WARNING_POP
PMR-style polymorphic memory resource for type-erased allocation.
constexpr remove_reference< T >::type && move(T &&t) FL_NO_EXCEPT
constexpr T && forward(typename remove_reference< T >::type &t) FL_NO_EXCEPT
@ kUnorderedMapQuadraticProbingTries
@ kUnorderedMapLinearProbeOnlyThreshold
FL_NO_INLINE fl::size unordered_map_probe_idx(fl::size h, fl::size i, fl::size mask, fl::size cap) FL_NO_EXCEPT
void swap(array< T, N > &lhs, array< T, N > &rhs) FL_NO_EXCEPT
u8 u8 fract8 blur_amount FL_NO_EXCEPT
constexpr int type_rank< T >::value
unordered_map< Key, T, Hash, KeyEqual > hash_map
constexpr enable_if< is_fixed_point< T >::value, T >::type clamp(T x, T lo, T hi) FL_NO_EXCEPT
FASTLED_FORCE_INLINE U map_range(T value, T in_min, T in_max, U out_min, U out_max) FL_NO_EXCEPT
void init(Context &ctx, int w, int h) FL_NO_EXCEPT
To bit_cast(const From &from) FL_NO_EXCEPT
VectorN< T, INLINED_SIZE > vector_inlined
Base definition for an LED controller.
bool operator()(const T &a, const T &b) const FL_NO_EXCEPT
void advance_to_occupied() FL_NO_EXCEPT
pair< const Key, T > value_type
const value_type & reference
fl::forward_iterator_tag iterator_category
const_iterator(const unordered_map *m, fl::size idx) FL_NO_EXCEPT
reference operator*() const FL_NO_EXCEPT
bool operator!=(const const_iterator &o) const FL_NO_EXCEPT
bool operator==(const const_iterator &o) const FL_NO_EXCEPT
const value_type * pointer
pointer operator->() const FL_NO_EXCEPT
friend class unordered_map
const_iterator() FL_NO_EXCEPT
const_iterator(const iterator &it) FL_NO_EXCEPT
const unordered_map * _map
const_iterator & operator++() FL_NO_EXCEPT
const_iterator operator++(int) FL_NO_EXCEPT
iterator & operator++() FL_NO_EXCEPT
bool operator==(const iterator &o) const FL_NO_EXCEPT
fl::forward_iterator_tag iterator_category
pointer operator->() const FL_NO_EXCEPT
iterator operator++(int) FL_NO_EXCEPT
reference operator*() const FL_NO_EXCEPT
friend class unordered_map
bool operator!=(const iterator &o) const FL_NO_EXCEPT
void advance_to_occupied() FL_NO_EXCEPT
pair< const Key, T > value_type
iterator(unordered_map *m, fl::size idx) FL_NO_EXCEPT
#define FASTLED_HASHMAP_INLINED_COUNT