From af084e0b94ead81afb68303c30783d6088959d25 Mon Sep 17 00:00:00 2001 From: Isuru Samarathunga Date: Mon, 6 Oct 2025 00:28:06 +0530 Subject: [PATCH] Fix a bug with Map --- .../imp/inl/IACore/hashable/iihashable.inl | 37 +++--- .../IACore/map/interface/map.interface.inl | 2 +- Src/IACore/imp/inl/IACore/map/map.inl | 111 ++++++++++-------- 3 files changed, 83 insertions(+), 67 deletions(-) diff --git a/Src/IACore/imp/inl/IACore/hashable/iihashable.inl b/Src/IACore/imp/inl/IACore/hashable/iihashable.inl index e5bc2fc..c1a3a11 100644 --- a/Src/IACore/imp/inl/IACore/hashable/iihashable.inl +++ b/Src/IACore/imp/inl/IACore/hashable/iihashable.inl @@ -1,16 +1,16 @@ -// IACore-OSS; The Core Library for All IA Open Source Projects +// IACore-OSS; The Core Library for All IA Open Source Projects // Copyright (C) 2024 IAS (ias@iasoft.dev) -// +// // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// +// // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. -// +// // You should have received a copy of the GNU General Public License // along with this program. If not, see . @@ -20,18 +20,23 @@ namespace ia { - template - concept hashable_type = std::derived_from<_type, IIHashable>; + template + concept hashable_type = std::derived_from<_type, IIHashable>; - 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 - UINT64 hash = 14695981039346656037llu; - for(SIZE_T i = 0; i < dataLength; i++) + template + concept comparible_type = requires(T a, T b) { + { a == b } -> std::same_as; + }; + + INLINE UINT64 IIHashable::fnv_1a(IN PCUINT8 data, IN SIZE_T dataLength) { - hash = hash ^ data[i]; - hash = hash * 1099511628211ul; + // Implemented as described at http://isthe.com/chongo/tech/comp/fnv/#google_vignette + UINT64 hash = 14695981039346656037llu; + for (SIZE_T i = 0; i < dataLength; i++) + { + hash = hash ^ data[i]; + hash = hash * 1099511628211ul; + } + return hash; } - return hash; - } -} \ No newline at end of file +} // namespace ia \ No newline at end of file diff --git a/Src/IACore/imp/inl/IACore/map/interface/map.interface.inl b/Src/IACore/imp/inl/IACore/map/interface/map.interface.inl index 3ce3472..f47b08d 100644 --- a/Src/IACore/imp/inl/IACore/map/interface/map.interface.inl +++ b/Src/IACore/imp/inl/IACore/map/interface/map.interface.inl @@ -23,7 +23,7 @@ namespace ia { template, 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 { STATIC CONSTEXPR SIZE_T BUCKET_COUNT = 1000; diff --git a/Src/IACore/imp/inl/IACore/map/map.inl b/Src/IACore/imp/inl/IACore/map/map.inl index a64c7b7..1739d0c 100644 --- a/Src/IACore/imp/inl/IACore/map/map.inl +++ b/Src/IACore/imp/inl/IACore/map/map.inl @@ -1,16 +1,16 @@ -// IACore-OSS; The Core Library for All IA Open Source Projects +// IACore-OSS; The Core Library for All IA Open Source Projects // Copyright (C) 2024 IAS (ias@iasoft.dev) -// +// // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// +// // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. -// +// // You should have received a copy of the GNU General Public License // along with this program. If not, see . @@ -18,66 +18,77 @@ #include "interface/map.interface.inl" -#define __template template requires hashable_type<_key_type> && valid_allocator_type<_allocator_type, _value_type> +#define __template \ + template \ + 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 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 { - define_member_function(, Map, ) - { - m_buckets.resize(BUCKET_COUNT); - } - - define_member_function(, ~Map, ) - { - } -} - -namespace ia -{ - define_member_function(VOID, set, IN CONST key_type& key, IN value_type&& value) - { - const auto listEntry = getBucket(key).append({ key, IA_MOVE(value) }); - m_insertedOrder.pushBack(*listEntry); - } - - define_const_member_function(CONST _value_type*, get, IN CONST key_type& key) - { - auto& bucket = getBucket(key); - for(auto it = bucket.first(); it; it = bucket.next(it)) + define_member_function(, Map, ) { - if(static_cast(*it).Key == key) - return &(*it)->Value; + m_buckets.resize(BUCKET_COUNT); } - return nullptr; - } - define_const_member_function(BOOL, contains, IN CONST key_type& key) - { - auto& bucket = getBucket(key); - for(auto it = bucket.first(); it; it = bucket.next(it)) + define_member_function(, ~Map, ) { - if(static_cast(*it).Key == key) - return true; } - return false; - } -} +} // namespace ia namespace ia { - define_member_function(List&, getBucket, IN CONST key_type& key) - { - return m_buckets[key.hash() % BUCKET_COUNT]; - } + define_member_function(VOID, set, IN CONST key_type &key, IN value_type &&value) + { + const auto listEntry = getBucket(key).append({key, IA_MOVE(value)}); + m_insertedOrder.pushBack(*listEntry); + } - define_const_member_function(CONST List&, getBucket, IN CONST key_type& key) - { - return m_buckets[key.hash() % BUCKET_COUNT]; - } -} + define_const_member_function(CONST _value_type *, get, IN CONST key_type &key) + { + auto &bucket = getBucket(key); + for (auto it = bucket.first(); it; it = bucket.next(it)) + { + if (static_cast(*it).Key == key) + return &(*it)->Value; + } + return nullptr; + } + + define_const_member_function(BOOL, contains, IN CONST key_type &key) + { + auto &bucket = getBucket(key); + for (auto it = bucket.first(); it; it = bucket.next(it)) + { + if (static_cast(*it).Key == key) + return true; + } + return false; + } +} // namespace ia + +namespace ia +{ + define_member_function(List &, getBucket, IN CONST key_type &key) + { + if constexpr (std::is_integral_v) + return m_buckets[key % BUCKET_COUNT]; + else + return m_buckets[key.hash() % BUCKET_COUNT]; + } + + define_const_member_function(CONST List &, getBucket, + IN CONST key_type &key) + { + if constexpr (std::is_integral_v) + return m_buckets[key % BUCKET_COUNT]; + else + return m_buckets[key.hash() % BUCKET_COUNT]; + } +} // namespace ia #undef __template #undef __ia_identifier