Fix a bug with Map

This commit is contained in:
Isuru Samarathunga
2025-10-06 00:28:06 +05:30
parent 1815ceb21d
commit af084e0b94
3 changed files with 83 additions and 67 deletions

View File

@ -23,15 +23,20 @@ namespace ia
template<typename _type> template<typename _type>
concept hashable_type = std::derived_from<_type, IIHashable>; concept hashable_type = std::derived_from<_type, IIHashable>;
template<typename T>
concept comparible_type = requires(T a, T b) {
{ a == b } -> std::same_as<bool>;
};
INLINE UINT64 IIHashable::fnv_1a(IN PCUINT8 data, IN SIZE_T dataLength) INLINE UINT64 IIHashable::fnv_1a(IN PCUINT8 data, IN SIZE_T dataLength)
{ {
// Implemented as described at http://isthe.com/chongo/tech/comp/fnv/#google_vignette // Implemented as described at http://isthe.com/chongo/tech/comp/fnv/#google_vignette
UINT64 hash = 14695981039346656037llu; UINT64 hash = 14695981039346656037llu;
for(SIZE_T i = 0; i < dataLength; i++) for (SIZE_T i = 0; i < dataLength; i++)
{ {
hash = hash ^ data[i]; hash = hash ^ data[i];
hash = hash * 1099511628211ul; hash = hash * 1099511628211ul;
} }
return hash; return hash;
} }
} } // namespace ia

View File

@ -23,7 +23,7 @@
namespace ia namespace ia
{ {
template<typename _key_type, typename _value_type, typename _allocator_type = GeneralAllocator<_value_type>, CONST SIZE_T _alignment = 1> template<typename _key_type, typename _value_type, typename _allocator_type = GeneralAllocator<_value_type>, CONST SIZE_T _alignment = 1>
requires hashable_type<_key_type> && valid_allocator_type<_allocator_type, _value_type> requires (hashable_type<_key_type> || std::is_integral_v<_key_type>) && valid_allocator_type<_allocator_type, _value_type>
class Map class Map
{ {
STATIC CONSTEXPR SIZE_T BUCKET_COUNT = 1000; STATIC CONSTEXPR SIZE_T BUCKET_COUNT = 1000;

View File

@ -18,10 +18,14 @@
#include "interface/map.interface.inl" #include "interface/map.interface.inl"
#define __template template<typename _key_type, typename _value_type, typename _allocator_type, CONST SIZE_T _alignment> requires hashable_type<_key_type> && valid_allocator_type<_allocator_type, _value_type> #define __template \
template<typename _key_type, typename _value_type, typename _allocator_type, CONST SIZE_T _alignment> \
requires(hashable_type<_key_type> || std::is_integral_v<_key_type>) && \
valid_allocator_type<_allocator_type, _value_type>
#define __ia_identifier Map<_key_type, _value_type, _allocator_type, _alignment> #define __ia_identifier Map<_key_type, _value_type, _allocator_type, _alignment>
#define define_member_function(return_type, name, ...) __template return_type __ia_identifier::name(__VA_ARGS__) #define define_member_function(return_type, name, ...) __template return_type __ia_identifier::name(__VA_ARGS__)
#define define_const_member_function(return_type, name, ...) __template return_type __ia_identifier::name(__VA_ARGS__) CONST #define define_const_member_function(return_type, name, ...) \
__template return_type __ia_identifier::name(__VA_ARGS__) CONST
namespace ia namespace ia
{ {
@ -33,51 +37,58 @@ namespace ia
define_member_function(, ~Map, ) define_member_function(, ~Map, )
{ {
} }
} } // namespace ia
namespace ia namespace ia
{ {
define_member_function(VOID, set, IN CONST key_type& key, IN value_type&& value) define_member_function(VOID, set, IN CONST key_type &key, IN value_type &&value)
{ {
const auto listEntry = getBucket(key).append({ key, IA_MOVE(value) }); const auto listEntry = getBucket(key).append({key, IA_MOVE(value)});
m_insertedOrder.pushBack(*listEntry); m_insertedOrder.pushBack(*listEntry);
} }
define_const_member_function(CONST _value_type*, get, IN CONST key_type& key) define_const_member_function(CONST _value_type *, get, IN CONST key_type &key)
{ {
auto& bucket = getBucket(key); auto &bucket = getBucket(key);
for(auto it = bucket.first(); it; it = bucket.next(it)) for (auto it = bucket.first(); it; it = bucket.next(it))
{ {
if(static_cast<KeyValuePair>(*it).Key == key) if (static_cast<KeyValuePair>(*it).Key == key)
return &(*it)->Value; return &(*it)->Value;
} }
return nullptr; return nullptr;
} }
define_const_member_function(BOOL, contains, IN CONST key_type& key) define_const_member_function(BOOL, contains, IN CONST key_type &key)
{ {
auto& bucket = getBucket(key); auto &bucket = getBucket(key);
for(auto it = bucket.first(); it; it = bucket.next(it)) for (auto it = bucket.first(); it; it = bucket.next(it))
{ {
if(static_cast<KeyValuePair>(*it).Key == key) if (static_cast<KeyValuePair>(*it).Key == key)
return true; return true;
} }
return false; return false;
} }
} } // namespace ia
namespace ia namespace ia
{ {
define_member_function(List<typename __ia_identifier::KeyValuePair>&, getBucket, IN CONST key_type& key) define_member_function(List<typename __ia_identifier::KeyValuePair> &, getBucket, IN CONST key_type &key)
{ {
if constexpr (std::is_integral_v<key_type>)
return m_buckets[key % BUCKET_COUNT];
else
return m_buckets[key.hash() % BUCKET_COUNT]; return m_buckets[key.hash() % BUCKET_COUNT];
} }
define_const_member_function(CONST List<typename __ia_identifier::KeyValuePair>&, getBucket, IN CONST key_type& key) define_const_member_function(CONST List<typename __ia_identifier::KeyValuePair> &, getBucket,
IN CONST key_type &key)
{ {
if constexpr (std::is_integral_v<key_type>)
return m_buckets[key % BUCKET_COUNT];
else
return m_buckets[key.hash() % BUCKET_COUNT]; return m_buckets[key.hash() % BUCKET_COUNT];
} }
} } // namespace ia
#undef __template #undef __template
#undef __ia_identifier #undef __ia_identifier