Compare commits

...

5 Commits

7 changed files with 120 additions and 72 deletions

2
.vscode/tasks.json vendored
View File

@ -3,7 +3,7 @@
{ {
"label": "build", "label": "build",
"type": "shell", "type": "shell",
"command": "cmake -S. -B./build -G Ninja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ && cmake --build build", "command": "cmake -S. -B./build -G Ninja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DIA_BUILD_SAMPLES=ON && cmake --build build",
"group": { "group": {
"kind": "build", "kind": "build",
"isDefault": true "isDefault": true

View File

@ -9,4 +9,7 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
project(IACore) project(IACore)
add_subdirectory(Src/IACore) add_subdirectory(Src/IACore)
add_subdirectory(Src/IACoreTest)
if(IA_BUILD_SAMPLES)
add_subdirectory(Src/IACoreTest)
endif()

View File

@ -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) // Copyright (C) 2024 IAS (ias@iasoft.dev)
// //
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (at your option) any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
@ -20,18 +20,23 @@
namespace ia namespace ia
{ {
template<typename _type> template<typename _type>
concept hashable_type = std::derived_from<_type, IIHashable>; concept hashable_type = std::derived_from<_type, IIHashable>;
INLINE UINT64 IIHashable::fnv_1a(IN PCUINT8 data, IN SIZE_T dataLength) template<typename T>
{ concept comparible_type = requires(T a, T b) {
// Implemented as described at http://isthe.com/chongo/tech/comp/fnv/#google_vignette { a == b } -> std::same_as<bool>;
UINT64 hash = 14695981039346656037llu; };
for(SIZE_T i = 0; i < dataLength; i++)
INLINE UINT64 IIHashable::fnv_1a(IN PCUINT8 data, IN SIZE_T dataLength)
{ {
hash = hash ^ data[i]; // Implemented as described at http://isthe.com/chongo/tech/comp/fnv/#google_vignette
hash = hash * 1099511628211ul; UINT64 hash = 14695981039346656037llu;
for (SIZE_T i = 0; i < dataLength; i++)
{
hash = hash ^ data[i];
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

@ -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) // Copyright (C) 2024 IAS (ias@iasoft.dev)
// //
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (at your option) any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
@ -18,66 +18,77 @@
#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
{ {
define_member_function(, Map, ) 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))
{ {
if(static_cast<KeyValuePair>(*it).Key == key) m_buckets.resize(BUCKET_COUNT);
return &(*it)->Value;
} }
return nullptr;
}
define_const_member_function(BOOL, contains, IN CONST key_type& key) define_member_function(, ~Map, )
{
auto& bucket = getBucket(key);
for(auto it = bucket.first(); it; it = bucket.next(it))
{ {
if(static_cast<KeyValuePair>(*it).Key == key)
return true;
} }
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(VOID, set, IN CONST key_type &key, IN value_type &&value)
{ {
return m_buckets[key.hash() % BUCKET_COUNT]; const auto listEntry = getBucket(key).append({key, IA_MOVE(value)});
} m_insertedOrder.pushBack(*listEntry);
}
define_const_member_function(CONST List<typename __ia_identifier::KeyValuePair>&, getBucket, IN CONST key_type& key) define_const_member_function(CONST _value_type *, get, IN CONST key_type &key)
{ {
return m_buckets[key.hash() % BUCKET_COUNT]; auto &bucket = getBucket(key);
} for (auto it = bucket.first(); it; it = bucket.next(it))
} {
if (static_cast<KeyValuePair>(*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<KeyValuePair>(*it).Key == key)
return true;
}
return false;
}
} // namespace ia
namespace ia
{
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];
}
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];
}
} // namespace ia
#undef __template #undef __template
#undef __ia_identifier #undef __ia_identifier

View File

@ -16,7 +16,7 @@
#pragma once #pragma once
#include <IACore/String.hpp> #include <IACore/Logger.hpp>
namespace ia { namespace ia {
enum class ExceptionKind { enum class ExceptionKind {
@ -131,7 +131,9 @@ private:
DO(SECURITY_BYPASS) DO(SECURITY_BYPASS)
#define DEFINE_THROWER(name) \ #define DEFINE_THROWER(name) \
template <typename... Args> NORETURN VOID THROW_##name(Args... args) { \ template <typename... Args> NORETURN VOID THROW_##name(Args... args) { \
throw RuntimeException(ExceptionKind::name, BuildString(args...)); \ const auto msg = BuildString(args...); \
Logger::Error("EXCEPT", "(", #name, "): ", msg); \
throw RuntimeException(ExceptionKind::name, msg); \
} }
FOR_EACH_RUNTIME_EXCEPT_TYPE(DEFINE_THROWER); FOR_EACH_RUNTIME_EXCEPT_TYPE(DEFINE_THROWER);
#undef DEFINE_THROWER #undef DEFINE_THROWER

View File

@ -18,6 +18,10 @@
#include <IACore/String.hpp> #include <IACore/String.hpp>
#ifdef __ANDROID__
#include <android/log.h>
#endif
namespace ia namespace ia
{ {
class Logger class Logger
@ -27,21 +31,44 @@ namespace ia
{ {
StringStream ss; StringStream ss;
UNUSED((ss << ... << args)); UNUSED((ss << ... << args));
printf("\033[32m[INFO]: [%s] %s\033[39m\n", tag, ss.str().c_str()); #ifdef __ANDROID__
__android_log_print(ANDROID_LOG_DEBUG, "IAApp", ss.str().c_str());
#else
printf("\033[0;37m[INFO]: [%s] %s\033[39m\n", tag, ss.str().c_str());
#endif
}
template<typename... Args> STATIC VOID Success(PCCHAR tag, Args... args)
{
StringStream ss;
UNUSED((ss << ... << args));
#ifdef __ANDROID__
__android_log_print(ANDROID_LOG_INFO, "IAApp", ss.str().c_str());
#else
printf("\033[32m[SUCCESS]: [%s] %s\033[39m\n", tag, ss.str().c_str());
#endif
} }
template<typename... Args> STATIC VOID Warn(PCCHAR tag, Args... args) template<typename... Args> STATIC VOID Warn(PCCHAR tag, Args... args)
{ {
StringStream ss; StringStream ss;
UNUSED((ss << ... << args)); UNUSED((ss << ... << args));
#ifdef __ANDROID__
__android_log_print(ANDROID_LOG_DEBUG, "IAApp", ss.str().c_str());
#else
printf("\033[33m[WARN]: [%s] %s\033[39m\n", tag, ss.str().c_str()); printf("\033[33m[WARN]: [%s] %s\033[39m\n", tag, ss.str().c_str());
#endif
} }
template<typename... Args> STATIC VOID Error(PCCHAR tag, Args... args) template<typename... Args> STATIC VOID Error(PCCHAR tag, Args... args)
{ {
StringStream ss; StringStream ss;
UNUSED((ss << ... << args)); UNUSED((ss << ... << args));
#ifdef __ANDROID__
__android_log_print(ANDROID_LOG_ERROR, "IAApp", ss.str().c_str());
#else
printf("\033[31m[ERROR]: [%s] %s\033[39m\n", tag, ss.str().c_str()); printf("\033[31m[ERROR]: [%s] %s\033[39m\n", tag, ss.str().c_str());
#endif
} }
private: private: