From 878becff2e68ef6566a84fd1c2910d2a1be108bd Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Mon, 17 Nov 2025 21:09:59 +1300 Subject: [PATCH 01/53] chore: refactor and tidying tests --- .gitmodules | 3 - CMakeLists.txt | 8 +- external/acutest | 1 - include/Application.h | 4 +- include/{ => gui}/GuiManager.h | 0 include/{ => gui}/LogWindow.h | 0 include/{ => scripting}/ScriptBindings.h | 0 include/{ => scripting}/ScriptEngine.h | 0 src/Application.cpp | 2 +- src/{ => gui}/GuiManager.cpp | 2 +- src/{ => gui}/LogWindow.cpp | 2 +- src/{ => scripting}/ScriptBindings.cpp | 4 +- src/{ => scripting}/ScriptEngine.cpp | 6 +- tests/CMakeLists.txt | 8 +- tests/acutest.h | 1994 ++++++++++++++++++++++ tests/acutest_main.c | 3 - tests/{unit_tests.cpp => hot_reload.cpp} | 22 +- tests/hot_reload.h | 5 + tests/test.cpp | 8 + 19 files changed, 2029 insertions(+), 43 deletions(-) delete mode 160000 external/acutest rename include/{ => gui}/GuiManager.h (100%) rename include/{ => gui}/LogWindow.h (100%) rename include/{ => scripting}/ScriptBindings.h (100%) rename include/{ => scripting}/ScriptEngine.h (100%) rename src/{ => gui}/GuiManager.cpp (99%) rename src/{ => gui}/LogWindow.cpp (98%) rename src/{ => scripting}/ScriptBindings.cpp (98%) rename src/{ => scripting}/ScriptEngine.cpp (98%) create mode 100644 tests/acutest.h delete mode 100644 tests/acutest_main.c rename tests/{unit_tests.cpp => hot_reload.cpp} (83%) create mode 100644 tests/hot_reload.h create mode 100644 tests/test.cpp diff --git a/.gitmodules b/.gitmodules index cd4f90d..a62c29d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,9 +4,6 @@ [submodule "external/angelscript"] path = external/angelscript url = https://github.com/anjo76/angelscript.git -[submodule "external/acutest"] - path = external/acutest - url = https://github.com/mity/acutest [submodule "external/imgui"] path = external/imgui url = https://github.com/ocornut/imgui.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 77b91d5..c273520 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,11 +74,11 @@ target_include_directories(scriptbuilder add_executable(simian main.cpp src/Application.cpp - src/ScriptEngine.cpp - src/ScriptBindings.cpp + src/scripting/ScriptEngine.cpp + src/scripting/ScriptBindings.cpp src/HotReload.cpp - src/GuiManager.cpp - src/LogWindow.cpp + src/gui/GuiManager.cpp + src/gui/LogWindow.cpp src/log/log.c ) diff --git a/external/acutest b/external/acutest deleted file mode 160000 index 31751b4..0000000 --- a/external/acutest +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 31751b4089c93b46a9fd8a8183a695f772de66de diff --git a/include/Application.h b/include/Application.h index 9defe7d..61de32d 100644 --- a/include/Application.h +++ b/include/Application.h @@ -1,7 +1,7 @@ #pragma once -#include "ScriptEngine.h" +#include "scripting/ScriptEngine.h" #include "HotReload.h" -#include "GuiManager.h" +#include "gui/GuiManager.h" #include "raylib.h" class Application { diff --git a/include/GuiManager.h b/include/gui/GuiManager.h similarity index 100% rename from include/GuiManager.h rename to include/gui/GuiManager.h diff --git a/include/LogWindow.h b/include/gui/LogWindow.h similarity index 100% rename from include/LogWindow.h rename to include/gui/LogWindow.h diff --git a/include/ScriptBindings.h b/include/scripting/ScriptBindings.h similarity index 100% rename from include/ScriptBindings.h rename to include/scripting/ScriptBindings.h diff --git a/include/ScriptEngine.h b/include/scripting/ScriptEngine.h similarity index 100% rename from include/ScriptEngine.h rename to include/scripting/ScriptEngine.h diff --git a/src/Application.cpp b/src/Application.cpp index be4ba14..789af40 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -10,7 +10,7 @@ #include "imgui.h" #include "extras/IconsFontAwesome6.h" #include "gui/ImGuiNotify.hpp" -#include "GuiManager.h" +#include "gui/GuiManager.h" #include "gui/Toast.h" #ifdef _WIN32 diff --git a/src/GuiManager.cpp b/src/gui/GuiManager.cpp similarity index 99% rename from src/GuiManager.cpp rename to src/gui/GuiManager.cpp index 3823a64..8784221 100644 --- a/src/GuiManager.cpp +++ b/src/gui/GuiManager.cpp @@ -1,4 +1,4 @@ -#include "GuiManager.h" +#include "gui/GuiManager.h" #include "raylib.h" #include // Add this to fix the incomplete type error #include diff --git a/src/LogWindow.cpp b/src/gui/LogWindow.cpp similarity index 98% rename from src/LogWindow.cpp rename to src/gui/LogWindow.cpp index 1f93770..a8aeca4 100644 --- a/src/LogWindow.cpp +++ b/src/gui/LogWindow.cpp @@ -1,4 +1,4 @@ -#include "LogWindow.h" +#include "gui/LogWindow.h" #include "log.h" void LogWindow::Initialize() diff --git a/src/ScriptBindings.cpp b/src/scripting/ScriptBindings.cpp similarity index 98% rename from src/ScriptBindings.cpp rename to src/scripting/ScriptBindings.cpp index 5d149c0..0c5ab1d 100644 --- a/src/ScriptBindings.cpp +++ b/src/scripting/ScriptBindings.cpp @@ -1,8 +1,8 @@ -#include "ScriptBindings.h" +#include "scripting/ScriptBindings.h" #include "raylib.h" #include #include -#include "log/log.h" +#include "../log/log.h" #include "gui/Toast.h" // Expose log level constants to AngelScript diff --git a/src/ScriptEngine.cpp b/src/scripting/ScriptEngine.cpp similarity index 98% rename from src/ScriptEngine.cpp rename to src/scripting/ScriptEngine.cpp index 9863604..63d50f6 100644 --- a/src/ScriptEngine.cpp +++ b/src/scripting/ScriptEngine.cpp @@ -1,12 +1,12 @@ -#include "ScriptEngine.h" -#include "ScriptBindings.h" +#include "scripting/ScriptEngine.h" +#include "scripting/ScriptBindings.h" #include "scriptstdstring.h" #include "scriptbuilder.h" #include #include #include #include -#include "log/log.h" +#include "../log/log.h" #include #include diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 3dd2033..f933790 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -2,14 +2,16 @@ cmake_minimum_required(VERSION 3.16) # Simple unit test executable that compiles acutest.c directly add_executable(unit_tests - unit_tests.cpp + test.cpp + hot_reload.cpp ${CMAKE_SOURCE_DIR}/src/HotReload.cpp - ${CMAKE_SOURCE_DIR}/src/ScriptEngine.cpp - ${CMAKE_SOURCE_DIR}/src/ScriptBindings.cpp + ${CMAKE_SOURCE_DIR}/src/scripting/ScriptEngine.cpp + ${CMAKE_SOURCE_DIR}/src/scripting/ScriptBindings.cpp ${CMAKE_SOURCE_DIR}/src/log/log.c ) target_include_directories(unit_tests PRIVATE + ${CMAKE_SOURCE_DIR}/tests ${CMAKE_SOURCE_DIR}/external/acutest/include ${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/src/log diff --git a/tests/acutest.h b/tests/acutest.h new file mode 100644 index 0000000..ce5956e --- /dev/null +++ b/tests/acutest.h @@ -0,0 +1,1994 @@ +/* + * Acutest -- Another C/C++ Unit Test facility + * + * + * Copyright 2013-2023 Martin Mitáš + * Copyright 2019 Garrett D'Amore + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef ACUTEST_H +#define ACUTEST_H + + +/* Try to auto-detect whether we need to disable C++ exception handling. + * If the detection fails, you may always define TEST_NO_EXCEPTIONS before + * including "acutest.h" manually. */ +#ifdef __cplusplus + #if (__cplusplus >= 199711L && !defined __cpp_exceptions) || \ + ((defined(__GNUC__) || defined(__clang__)) && !defined __EXCEPTIONS) + #ifndef TEST_NO_EXCEPTIONS + #define TEST_NO_EXCEPTIONS + #endif + #endif +#endif + + +/************************ + *** Public interface *** + ************************/ + +/* By default, "acutest.h" provides the main program entry point (function + * main()). However, if the test suite is composed of multiple source files + * which include "acutest.h", then this causes a problem of multiple main() + * definitions. To avoid this problem, #define macro TEST_NO_MAIN in all + * compilation units but one. + */ + +/* Macro to specify list of unit tests in the suite. + * The unit test implementation MUST provide list of unit tests it implements + * with this macro: + * + * TEST_LIST = { + * { "test1_name", test1_func_ptr }, + * { "test2_name", test2_func_ptr }, + * ... + * { NULL, NULL } // zeroed record marking the end of the list + * }; + * + * The list specifies names of each test (must be unique) and pointer to + * a function implementing it. The function does not take any arguments + * and has no return values, i.e. every test function has to be compatible + * with this prototype: + * + * void test_func(void); + * + * Note the list has to be ended with a zeroed record. + */ +#define TEST_LIST const struct acutest_test_ acutest_list_[] + + +/* Macros for testing whether an unit test succeeds or fails. These macros + * can be used arbitrarily in functions implementing the unit tests. + * + * If any condition fails throughout execution of a test, the test fails. + * + * TEST_CHECK takes only one argument (the condition), TEST_CHECK_ allows + * also to specify an error message to print out if the condition fails. + * (It expects printf-like format string and its parameters). The macros + * return non-zero (condition passes) or 0 (condition fails). + * + * That can be useful when more conditions should be checked only if some + * preceding condition passes, as illustrated in this code snippet: + * + * SomeStruct* ptr = allocate_some_struct(); + * if(TEST_CHECK(ptr != NULL)) { + * TEST_CHECK(ptr->member1 < 100); + * TEST_CHECK(ptr->member2 > 200); + * } + */ +#define TEST_CHECK_(cond,...) \ + acutest_check_(!!(cond), __FILE__, __LINE__, __VA_ARGS__) +#define TEST_CHECK(cond) \ + acutest_check_(!!(cond), __FILE__, __LINE__, "%s", #cond) + + +/* These macros are the same as TEST_CHECK_ and TEST_CHECK except that if the + * condition fails, the currently executed unit test is immediately aborted. + * + * That is done either by calling abort() if the unit test is executed as a + * child process; or via longjmp() if the unit test is executed within the + * main Acutest process. + * + * As a side effect of such abortion, your unit tests may cause memory leaks, + * unflushed file descriptors, and other phenomena caused by the abortion. + * + * Therefore you should not use these as a general replacement for TEST_CHECK. + * Use it with some caution, especially if your test causes some other side + * effects to the outside world (e.g. communicating with some server, inserting + * into a database etc.). + */ +#define TEST_ASSERT_(cond,...) \ + do { \ + if(!acutest_check_(!!(cond), __FILE__, __LINE__, __VA_ARGS__)) \ + acutest_abort_(); \ + } while(0) +#define TEST_ASSERT(cond) \ + do { \ + if(!acutest_check_(!!(cond), __FILE__, __LINE__, "%s", #cond)) \ + acutest_abort_(); \ + } while(0) + + +#ifdef __cplusplus +#ifndef TEST_NO_EXCEPTIONS +/* Macros to verify that the code (the 1st argument) throws exception of given + * type (the 2nd argument). (Note these macros are only available in C++.) + * + * TEST_EXCEPTION_ is like TEST_EXCEPTION but accepts custom printf-like + * message. + * + * For example: + * + * TEST_EXCEPTION(function_that_throw(), ExpectedExceptionType); + * + * If the function_that_throw() throws ExpectedExceptionType, the check passes. + * If the function throws anything incompatible with ExpectedExceptionType + * (or if it does not thrown an exception at all), the check fails. + */ +#define TEST_EXCEPTION(code, exctype) \ + do { \ + bool exc_ok_ = false; \ + const char *msg_ = NULL; \ + try { \ + code; \ + msg_ = "No exception thrown."; \ + } catch(exctype const&) { \ + exc_ok_= true; \ + } catch(...) { \ + msg_ = "Unexpected exception thrown."; \ + } \ + acutest_check_(exc_ok_, __FILE__, __LINE__, #code " throws " #exctype);\ + if(msg_ != NULL) \ + acutest_message_("%s", msg_); \ + } while(0) +#define TEST_EXCEPTION_(code, exctype, ...) \ + do { \ + bool exc_ok_ = false; \ + const char *msg_ = NULL; \ + try { \ + code; \ + msg_ = "No exception thrown."; \ + } catch(exctype const&) { \ + exc_ok_= true; \ + } catch(...) { \ + msg_ = "Unexpected exception thrown."; \ + } \ + acutest_check_(exc_ok_, __FILE__, __LINE__, __VA_ARGS__); \ + if(msg_ != NULL) \ + acutest_message_("%s", msg_); \ + } while(0) +#endif /* #ifndef TEST_NO_EXCEPTIONS */ +#endif /* #ifdef __cplusplus */ + + +/* Sometimes it is useful to split execution of more complex unit tests to some + * smaller parts and associate those parts with some names. + * + * This is especially handy if the given unit test is implemented as a loop + * over some vector of multiple testing inputs. Using these macros allow to use + * sort of subtitle for each iteration of the loop (e.g. outputting the input + * itself or a name associated to it), so that if any TEST_CHECK condition + * fails in the loop, it can be easily seen which iteration triggers the + * failure, without the need to manually output the iteration-specific data in + * every single TEST_CHECK inside the loop body. + * + * TEST_CASE allows to specify only single string as the name of the case, + * TEST_CASE_ provides all the power of printf-like string formatting. + * + * Note that the test cases cannot be nested. Starting a new test case ends + * implicitly the previous one. To end the test case explicitly (e.g. to end + * the last test case after exiting the loop), you may use TEST_CASE(NULL). + */ +#define TEST_CASE_(...) acutest_case_(__VA_ARGS__) +#define TEST_CASE(name) acutest_case_("%s", name) + + +/* Maximal output per TEST_CASE call. Longer messages are cut. + * You may define another limit prior including "acutest.h" + */ +#ifndef TEST_CASE_MAXSIZE + #define TEST_CASE_MAXSIZE 64 +#endif + + +/* printf-like macro for outputting an extra information about a failure. + * + * Intended use is to output some computed output versus the expected value, + * e.g. like this: + * + * if(!TEST_CHECK(produced == expected)) { + * TEST_MSG("Expected: %d", expected); + * TEST_MSG("Produced: %d", produced); + * } + * + * Note the message is only written down if the most recent use of any checking + * macro (like e.g. TEST_CHECK or TEST_EXCEPTION) in the current test failed. + * This means the above is equivalent to just this: + * + * TEST_CHECK(produced == expected); + * TEST_MSG("Expected: %d", expected); + * TEST_MSG("Produced: %d", produced); + * + * The macro can deal with multi-line output fairly well. It also automatically + * adds a final new-line if there is none present. + */ +#define TEST_MSG(...) acutest_message_(__VA_ARGS__) + + +/* Maximal output per TEST_MSG call. Longer messages are cut. + * You may define another limit prior including "acutest.h" + */ +#ifndef TEST_MSG_MAXSIZE + #define TEST_MSG_MAXSIZE 1024 +#endif + + +/* Macro for dumping a block of memory. + * + * Its intended use is very similar to what TEST_MSG is for, but instead of + * generating any printf-like message, this is for dumping raw block of a + * memory in a hexadecimal form: + * + * TEST_CHECK(size_produced == size_expected && + * memcmp(addr_produced, addr_expected, size_produced) == 0); + * TEST_DUMP("Expected:", addr_expected, size_expected); + * TEST_DUMP("Produced:", addr_produced, size_produced); + */ +#define TEST_DUMP(title, addr, size) acutest_dump_(title, addr, size) + +/* Maximal output per TEST_DUMP call (in bytes to dump). Longer blocks are cut. + * You may define another limit prior including "acutest.h" + */ +#ifndef TEST_DUMP_MAXSIZE + #define TEST_DUMP_MAXSIZE 1024 +#endif + + +/* Macros for marking the test as SKIPPED. + * Note it can only be used at the beginning of a test, before any other + * checking. + * + * Once used, the best practice is to return from the test routine as soon + * as possible. + */ +#define TEST_SKIP(...) acutest_skip_(__FILE__, __LINE__, __VA_ARGS__) + + +/* Common test initialisation/clean-up + * + * In some test suites, it may be needed to perform some sort of the same + * initialization and/or clean-up in all the tests. + * + * Such test suites may use macros TEST_INIT and/or TEST_FINI prior including + * this header. The expansion of the macro is then used as a body of helper + * function called just before executing every single (TEST_INIT) or just after + * it ends (TEST_FINI). + * + * Examples of various ways how to use the macro TEST_INIT: + * + * #define TEST_INIT my_init_func(); + * #define TEST_INIT my_init_func() // Works even without the semicolon + * #define TEST_INIT setlocale(LC_ALL, NULL); + * #define TEST_INIT { setlocale(LC_ALL, NULL); my_init_func(); } + * + * TEST_FINI is to be used in the same way. + */ + + +/********************** + *** Implementation *** + **********************/ + +/* The unit test files should not rely on anything below. */ + +#include + +/* Enable the use of the non-standard keyword __attribute__ to silence warnings under some compilers */ +#if defined(__GNUC__) || defined(__clang__) + #define ACUTEST_ATTRIBUTE_(attr) __attribute__((attr)) +#else + #define ACUTEST_ATTRIBUTE_(attr) +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +enum acutest_state_ { + ACUTEST_STATE_INITIAL = -4, + ACUTEST_STATE_SELECTED = -3, + ACUTEST_STATE_NEEDTORUN = -2, + + /* By the end all tests should be in one of the following: */ + ACUTEST_STATE_EXCLUDED = -1, + ACUTEST_STATE_SUCCESS = 0, + ACUTEST_STATE_FAILED = 1, + ACUTEST_STATE_SKIPPED = 2 +}; + +int acutest_check_(int cond, const char* file, int line, const char* fmt, ...); +void acutest_case_(const char* fmt, ...); +void acutest_message_(const char* fmt, ...); +void acutest_dump_(const char* title, const void* addr, size_t size); +void acutest_abort_(void) ACUTEST_ATTRIBUTE_(noreturn); +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#ifndef TEST_NO_MAIN + +#include +#include +#include +#include +#include + +#if defined(unix) || defined(__unix__) || defined(__unix) || defined(__APPLE__) + #define ACUTEST_UNIX_ 1 + #include + #include + #include + #include + #include + #include + #include + + #if defined CLOCK_PROCESS_CPUTIME_ID && defined CLOCK_MONOTONIC + #define ACUTEST_HAS_POSIX_TIMER_ 1 + #endif +#endif + +#if defined(_gnu_linux_) || defined(__linux__) + #define ACUTEST_LINUX_ 1 + #include + #include +#endif + +#if defined(_WIN32) || defined(__WIN32__) || defined(__WINDOWS__) + #define ACUTEST_WIN_ 1 + #include + #include +#endif + +#if defined(__APPLE__) + #define ACUTEST_MACOS_ + #include + #include + #include + #include + #include +#endif + +#ifdef __cplusplus +#ifndef TEST_NO_EXCEPTIONS + #include +#endif +#endif + +#ifdef __has_include + #if __has_include() + #include + #endif +#endif + +/* Note our global private identifiers end with '_' to mitigate risk of clash + * with the unit tests implementation. */ + +#ifdef __cplusplus + extern "C" { +#endif + +#ifdef _MSC_VER + /* In the multi-platform code like ours, we cannot use the non-standard + * "safe" functions from Microsoft C lib like e.g. sprintf_s() instead of + * standard sprintf(). Hence, lets disable the warning C4996. */ + #pragma warning(push) + #pragma warning(disable: 4996) +#endif + + +struct acutest_test_ { + const char* name; + void (*func)(void); +}; + +struct acutest_test_data_ { + enum acutest_state_ state; + double duration; +}; + + +extern const struct acutest_test_ acutest_list_[]; + + +static char* acutest_argv0_ = NULL; +static int acutest_list_size_ = 0; +static struct acutest_test_data_* acutest_test_data_ = NULL; +static int acutest_no_exec_ = -1; +static int acutest_no_summary_ = 0; +static int acutest_tap_ = 0; +static int acutest_exclude_mode_ = 0; +static int acutest_worker_ = 0; +static int acutest_worker_index_ = 0; +static int acutest_cond_failed_ = 0; +static FILE *acutest_xml_output_ = NULL; + +static const struct acutest_test_* acutest_current_test_ = NULL; +static int acutest_current_index_ = 0; +static char acutest_case_name_[TEST_CASE_MAXSIZE] = ""; +static int acutest_test_check_count_ = 0; +static int acutest_test_skip_count_ = 0; +static char acutest_test_skip_reason_[256] = ""; +static int acutest_test_already_logged_ = 0; +static int acutest_case_already_logged_ = 0; +static int acutest_verbose_level_ = 2; +static int acutest_test_failures_ = 0; +static int acutest_colorize_ = 0; +static int acutest_timer_ = 0; + +static int acutest_abort_has_jmp_buf_ = 0; +static jmp_buf acutest_abort_jmp_buf_; + +static int +acutest_count_(enum acutest_state_ state) +{ + int i, n; + + for(i = 0, n = 0; i < acutest_list_size_; i++) { + if(acutest_test_data_[i].state == state) + n++; + } + + return n; +} + +static void +acutest_cleanup_(void) +{ + free((void*) acutest_test_data_); +} + +static void ACUTEST_ATTRIBUTE_(noreturn) +acutest_exit_(int exit_code) +{ + acutest_cleanup_(); + exit(exit_code); +} + + +#if defined ACUTEST_WIN_ + typedef LARGE_INTEGER acutest_timer_type_; + static LARGE_INTEGER acutest_timer_freq_; + static acutest_timer_type_ acutest_timer_start_; + static acutest_timer_type_ acutest_timer_end_; + + static void + acutest_timer_init_(void) + { + QueryPerformanceFrequency(´st_timer_freq_); + } + + static void + acutest_timer_get_time_(LARGE_INTEGER* ts) + { + QueryPerformanceCounter(ts); + } + + static double + acutest_timer_diff_(LARGE_INTEGER start, LARGE_INTEGER end) + { + double duration = (double)(end.QuadPart - start.QuadPart); + duration /= (double)acutest_timer_freq_.QuadPart; + return duration; + } + + static void + acutest_timer_print_diff_(void) + { + printf("%.6lf secs", acutest_timer_diff_(acutest_timer_start_, acutest_timer_end_)); + } +#elif defined ACUTEST_HAS_POSIX_TIMER_ + static clockid_t acutest_timer_id_; + typedef struct timespec acutest_timer_type_; + static acutest_timer_type_ acutest_timer_start_; + static acutest_timer_type_ acutest_timer_end_; + + static void + acutest_timer_init_(void) + { + if(acutest_timer_ == 1) + acutest_timer_id_ = CLOCK_MONOTONIC; + else if(acutest_timer_ == 2) + acutest_timer_id_ = CLOCK_PROCESS_CPUTIME_ID; + } + + static void + acutest_timer_get_time_(struct timespec* ts) + { + clock_gettime(acutest_timer_id_, ts); + } + + static double + acutest_timer_diff_(struct timespec start, struct timespec end) + { + return (double)(end.tv_sec - start.tv_sec) + (double)(end.tv_nsec - start.tv_nsec) / 1e9; + } + + static void + acutest_timer_print_diff_(void) + { + printf("%.6lf secs", + acutest_timer_diff_(acutest_timer_start_, acutest_timer_end_)); + } +#else + typedef int acutest_timer_type_; + static acutest_timer_type_ acutest_timer_start_; + static acutest_timer_type_ acutest_timer_end_; + + void + acutest_timer_init_(void) + {} + + static void + acutest_timer_get_time_(int* ts) + { + (void) ts; + } + + static double + acutest_timer_diff_(int start, int end) + { + (void) start; + (void) end; + return 0.0; + } + + static void + acutest_timer_print_diff_(void) + {} +#endif + +#define ACUTEST_COLOR_DEFAULT_ 0 +#define ACUTEST_COLOR_RED_ 1 +#define ACUTEST_COLOR_GREEN_ 2 +#define ACUTEST_COLOR_YELLOW_ 3 +#define ACUTEST_COLOR_DEFAULT_INTENSIVE_ 10 +#define ACUTEST_COLOR_RED_INTENSIVE_ 11 +#define ACUTEST_COLOR_GREEN_INTENSIVE_ 12 +#define ACUTEST_COLOR_YELLOW_INTENSIVE_ 13 + +static int ACUTEST_ATTRIBUTE_(format (printf, 2, 3)) +acutest_colored_printf_(int color, const char* fmt, ...) +{ + va_list args; + char buffer[256]; + int n; + + va_start(args, fmt); + vsnprintf(buffer, sizeof(buffer), fmt, args); + va_end(args); + buffer[sizeof(buffer)-1] = '\0'; + + if(!acutest_colorize_) { + return printf("%s", buffer); + } + +#if defined ACUTEST_UNIX_ + { + const char* col_str; + switch(color) { + case ACUTEST_COLOR_RED_: col_str = "\033[0;31m"; break; + case ACUTEST_COLOR_GREEN_: col_str = "\033[0;32m"; break; + case ACUTEST_COLOR_YELLOW_: col_str = "\033[0;33m"; break; + case ACUTEST_COLOR_RED_INTENSIVE_: col_str = "\033[1;31m"; break; + case ACUTEST_COLOR_GREEN_INTENSIVE_: col_str = "\033[1;32m"; break; + case ACUTEST_COLOR_YELLOW_INTENSIVE_: col_str = "\033[1;33m"; break; + case ACUTEST_COLOR_DEFAULT_INTENSIVE_: col_str = "\033[1m"; break; + default: col_str = "\033[0m"; break; + } + printf("%s", col_str); + n = printf("%s", buffer); + printf("\033[0m"); + return n; + } +#elif defined ACUTEST_WIN_ + { + HANDLE h; + CONSOLE_SCREEN_BUFFER_INFO info; + WORD attr; + + h = GetStdHandle(STD_OUTPUT_HANDLE); + GetConsoleScreenBufferInfo(h, &info); + + switch(color) { + case ACUTEST_COLOR_RED_: attr = FOREGROUND_RED; break; + case ACUTEST_COLOR_GREEN_: attr = FOREGROUND_GREEN; break; + case ACUTEST_COLOR_YELLOW_: attr = FOREGROUND_RED | FOREGROUND_GREEN; break; + case ACUTEST_COLOR_RED_INTENSIVE_: attr = FOREGROUND_RED | FOREGROUND_INTENSITY; break; + case ACUTEST_COLOR_GREEN_INTENSIVE_: attr = FOREGROUND_GREEN | FOREGROUND_INTENSITY; break; + case ACUTEST_COLOR_DEFAULT_INTENSIVE_: attr = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY; break; + case ACUTEST_COLOR_YELLOW_INTENSIVE_: attr = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY; break; + default: attr = 0; break; + } + if(attr != 0) + SetConsoleTextAttribute(h, attr); + n = printf("%s", buffer); + SetConsoleTextAttribute(h, info.wAttributes); + return n; + } +#else + n = printf("%s", buffer); + return n; +#endif +} + +static const char* +acutest_basename_(const char* path) +{ + const char* name; + + name = strrchr(path, '/'); + if(name != NULL) + name++; + else + name = path; + +#ifdef ACUTEST_WIN_ + { + const char* alt_name; + + alt_name = strrchr(path, '\\'); + if(alt_name != NULL) + alt_name++; + else + alt_name = path; + + if(alt_name > name) + name = alt_name; + } +#endif + + return name; +} + +static void +acutest_begin_test_line_(const struct acutest_test_* test) +{ + if(!acutest_tap_) { + if(acutest_verbose_level_ >= 3) { + acutest_colored_printf_(ACUTEST_COLOR_DEFAULT_INTENSIVE_, "Test %s:\n", test->name); + acutest_test_already_logged_++; + } else if(acutest_verbose_level_ >= 1) { + int n; + char spaces[48]; + + n = acutest_colored_printf_(ACUTEST_COLOR_DEFAULT_INTENSIVE_, "Test %s... ", test->name); + memset(spaces, ' ', sizeof(spaces)); + if(n < (int) sizeof(spaces)) + printf("%.*s", (int) sizeof(spaces) - n, spaces); + } else { + acutest_test_already_logged_ = 1; + } + } +} + +static void +acutest_finish_test_line_(enum acutest_state_ state) +{ + if(acutest_tap_) { + printf("%s %d - %s%s\n", + (state == ACUTEST_STATE_SUCCESS || state == ACUTEST_STATE_SKIPPED) ? "ok" : "not ok", + acutest_current_index_ + 1, + acutest_current_test_->name, + (state == ACUTEST_STATE_SKIPPED) ? " # SKIP" : ""); + + if(state == ACUTEST_STATE_SUCCESS && acutest_timer_) { + printf("# Duration: "); + acutest_timer_print_diff_(); + printf("\n"); + } + } else { + int color; + const char* str; + + switch(state) { + case ACUTEST_STATE_SUCCESS: color = ACUTEST_COLOR_GREEN_INTENSIVE_; str = "OK"; break; + case ACUTEST_STATE_SKIPPED: color = ACUTEST_COLOR_YELLOW_INTENSIVE_; str = "SKIPPED"; break; + case ACUTEST_STATE_FAILED: /* Fall through. */ + default: color = ACUTEST_COLOR_RED_INTENSIVE_; str = "FAILED"; break; + } + + printf("[ "); + acutest_colored_printf_(color, "%s", str); + printf(" ]"); + + if(state == ACUTEST_STATE_SUCCESS && acutest_timer_) { + printf(" "); + acutest_timer_print_diff_(); + } + + printf("\n"); + } +} + +static void +acutest_line_indent_(int level) +{ + static const char spaces[] = " "; + int n = level * 2; + + if(acutest_tap_ && n > 0) { + n--; + printf("#"); + } + + while(n > 16) { + printf("%s", spaces); + n -= 16; + } + printf("%.*s", n, spaces); +} + +void ACUTEST_ATTRIBUTE_(format (printf, 3, 4)) +acutest_skip_(const char* file, int line, const char* fmt, ...) +{ + va_list args; + size_t reason_len; + + va_start(args, fmt); + vsnprintf(acutest_test_skip_reason_, sizeof(acutest_test_skip_reason_), fmt, args); + va_end(args); + acutest_test_skip_reason_[sizeof(acutest_test_skip_reason_)-1] = '\0'; + + /* Remove final dot, if provided; that collides with our other logic. */ + reason_len = strlen(acutest_test_skip_reason_); + if(acutest_test_skip_reason_[reason_len-1] == '.') + acutest_test_skip_reason_[reason_len-1] = '\0'; + + if(acutest_test_check_count_ > 0) { + acutest_check_(0, file, line, "Cannot skip, already performed some checks"); + return; + } + + if(acutest_verbose_level_ >= 2) { + const char *result_str = "skipped"; + int result_color = ACUTEST_COLOR_YELLOW_; + + if(!acutest_test_already_logged_ && acutest_current_test_ != NULL) + acutest_finish_test_line_(ACUTEST_STATE_SKIPPED); + acutest_test_already_logged_++; + + acutest_line_indent_(1); + + if(file != NULL) { + file = acutest_basename_(file); + printf("%s:%d: ", file, line); + } + + printf("%s... ", acutest_test_skip_reason_); + acutest_colored_printf_(result_color, "%s", result_str); + printf("\n"); + acutest_test_already_logged_++; + } + + acutest_test_skip_count_++; +} + +int ACUTEST_ATTRIBUTE_(format (printf, 4, 5)) +acutest_check_(int cond, const char* file, int line, const char* fmt, ...) +{ + const char *result_str; + int result_color; + int verbose_level; + + if(acutest_test_skip_count_) { + /* We've skipped the test. We shouldn't be here: The test implementation + * should have already return before. So lets suppress the following + * output. */ + cond = 1; + goto skip_check; + } + + if(cond) { + result_str = "ok"; + result_color = ACUTEST_COLOR_GREEN_; + verbose_level = 3; + } else { + if(!acutest_test_already_logged_ && acutest_current_test_ != NULL) + acutest_finish_test_line_(ACUTEST_STATE_FAILED); + + acutest_test_failures_++; + acutest_test_already_logged_++; + + result_str = "failed"; + result_color = ACUTEST_COLOR_RED_; + verbose_level = 2; + } + + if(acutest_verbose_level_ >= verbose_level) { + va_list args; + + if(!acutest_case_already_logged_ && acutest_case_name_[0]) { + acutest_line_indent_(1); + acutest_colored_printf_(ACUTEST_COLOR_DEFAULT_INTENSIVE_, "Case %s:\n", acutest_case_name_); + acutest_test_already_logged_++; + acutest_case_already_logged_++; + } + + acutest_line_indent_(acutest_case_name_[0] ? 2 : 1); + if(file != NULL) { + file = acutest_basename_(file); + printf("%s:%d: ", file, line); + } + + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); + + printf("... "); + acutest_colored_printf_(result_color, "%s", result_str); + printf("\n"); + acutest_test_already_logged_++; + } + + acutest_test_check_count_++; + +skip_check: + acutest_cond_failed_ = (cond == 0); + return !acutest_cond_failed_; +} + +void ACUTEST_ATTRIBUTE_(format (printf, 1, 2)) +acutest_case_(const char* fmt, ...) +{ + va_list args; + + if(acutest_verbose_level_ < 2) + return; + + if(acutest_case_name_[0]) { + acutest_case_already_logged_ = 0; + acutest_case_name_[0] = '\0'; + } + + if(fmt == NULL) + return; + + va_start(args, fmt); + vsnprintf(acutest_case_name_, sizeof(acutest_case_name_) - 1, fmt, args); + va_end(args); + acutest_case_name_[sizeof(acutest_case_name_) - 1] = '\0'; + + if(acutest_verbose_level_ >= 3) { + acutest_line_indent_(1); + acutest_colored_printf_(ACUTEST_COLOR_DEFAULT_INTENSIVE_, "Case %s:\n", acutest_case_name_); + acutest_test_already_logged_++; + acutest_case_already_logged_++; + } +} + +void ACUTEST_ATTRIBUTE_(format (printf, 1, 2)) +acutest_message_(const char* fmt, ...) +{ + char buffer[TEST_MSG_MAXSIZE]; + char* line_beg; + char* line_end; + va_list args; + + if(acutest_verbose_level_ < 2) + return; + + /* We allow extra message only when something is already wrong in the + * current test. */ + if(acutest_current_test_ == NULL || !acutest_cond_failed_) + return; + + va_start(args, fmt); + vsnprintf(buffer, TEST_MSG_MAXSIZE, fmt, args); + va_end(args); + buffer[TEST_MSG_MAXSIZE-1] = '\0'; + + line_beg = buffer; + while(1) { + line_end = strchr(line_beg, '\n'); + if(line_end == NULL) + break; + acutest_line_indent_(acutest_case_name_[0] ? 3 : 2); + printf("%.*s\n", (int)(line_end - line_beg), line_beg); + line_beg = line_end + 1; + } + if(line_beg[0] != '\0') { + acutest_line_indent_(acutest_case_name_[0] ? 3 : 2); + printf("%s\n", line_beg); + } +} + +void +acutest_dump_(const char* title, const void* addr, size_t size) +{ + static const size_t BYTES_PER_LINE = 16; + size_t line_beg; + size_t truncate = 0; + + if(acutest_verbose_level_ < 2) + return; + + /* We allow extra message only when something is already wrong in the + * current test. */ + if(acutest_current_test_ == NULL || !acutest_cond_failed_) + return; + + if(size > TEST_DUMP_MAXSIZE) { + truncate = size - TEST_DUMP_MAXSIZE; + size = TEST_DUMP_MAXSIZE; + } + + acutest_line_indent_(acutest_case_name_[0] ? 3 : 2); + printf((title[strlen(title)-1] == ':') ? "%s\n" : "%s:\n", title); + + for(line_beg = 0; line_beg < size; line_beg += BYTES_PER_LINE) { + size_t line_end = line_beg + BYTES_PER_LINE; + size_t off; + + acutest_line_indent_(acutest_case_name_[0] ? 4 : 3); + printf("%08lx: ", (unsigned long)line_beg); + for(off = line_beg; off < line_end; off++) { + if(off < size) + printf(" %02x", ((const unsigned char*)addr)[off]); + else + printf(" "); + } + + printf(" "); + for(off = line_beg; off < line_end; off++) { + unsigned char byte = ((const unsigned char*)addr)[off]; + if(off < size) + printf("%c", (iscntrl(byte) ? '.' : byte)); + else + break; + } + + printf("\n"); + } + + if(truncate > 0) { + acutest_line_indent_(acutest_case_name_[0] ? 4 : 3); + printf(" ... (and more %u bytes)\n", (unsigned) truncate); + } +} + +/* This is called just before each test */ +static void +acutest_init_(const char *test_name) +{ +#ifdef TEST_INIT + TEST_INIT + ; /* Allow for a single unterminated function call */ +#endif + + /* Suppress any warnings about unused variable. */ + (void) test_name; +} + +/* This is called after each test */ +static void +acutest_fini_(const char *test_name) +{ +#ifdef TEST_FINI + TEST_FINI + ; /* Allow for a single unterminated function call */ +#endif + + /* Suppress any warnings about unused variable. */ + (void) test_name; +} + +void +acutest_abort_(void) +{ + if(acutest_abort_has_jmp_buf_) { + longjmp(acutest_abort_jmp_buf_, 1); + } else { + if(acutest_current_test_ != NULL) + acutest_fini_(acutest_current_test_->name); + fflush(stdout); + fflush(stderr); + acutest_exit_(ACUTEST_STATE_FAILED); + } +} + +static void +acutest_list_names_(void) +{ + const struct acutest_test_* test; + + printf("Unit tests:\n"); + for(test = ´st_list_[0]; test->func != NULL; test++) + printf(" %s\n", test->name); +} + +static int +acutest_name_contains_word_(const char* name, const char* pattern) +{ + static const char word_delim[] = " \t-_/.,:;"; + const char* substr; + size_t pattern_len; + + pattern_len = strlen(pattern); + + substr = strstr(name, pattern); + while(substr != NULL) { + int starts_on_word_boundary = (substr == name || strchr(word_delim, substr[-1]) != NULL); + int ends_on_word_boundary = (substr[pattern_len] == '\0' || strchr(word_delim, substr[pattern_len]) != NULL); + + if(starts_on_word_boundary && ends_on_word_boundary) + return 1; + + substr = strstr(substr+1, pattern); + } + + return 0; +} + +static int +acutest_select_(const char* pattern) +{ + int i; + int n = 0; + + /* Try exact match. */ + for(i = 0; i < acutest_list_size_; i++) { + if(strcmp(acutest_list_[i].name, pattern) == 0) { + acutest_test_data_[i].state = ACUTEST_STATE_SELECTED; + n++; + break; + } + } + if(n > 0) + return n; + + /* Try word match. */ + for(i = 0; i < acutest_list_size_; i++) { + if(acutest_name_contains_word_(acutest_list_[i].name, pattern)) { + acutest_test_data_[i].state = ACUTEST_STATE_SELECTED; + n++; + } + } + if(n > 0) + return n; + + /* Try relaxed match. */ + for(i = 0; i < acutest_list_size_; i++) { + if(strstr(acutest_list_[i].name, pattern) != NULL) { + acutest_test_data_[i].state = ACUTEST_STATE_SELECTED; + n++; + } + } + + return n; +} + + +/* Called if anything goes bad in Acutest, or if the unit test ends in other + * way then by normal returning from its function (e.g. exception or some + * abnormal child process termination). */ +static void ACUTEST_ATTRIBUTE_(format (printf, 1, 2)) +acutest_error_(const char* fmt, ...) +{ + if(acutest_verbose_level_ == 0) + return; + + if(acutest_verbose_level_ >= 2) { + va_list args; + + acutest_line_indent_(1); + if(acutest_verbose_level_ >= 3) + acutest_colored_printf_(ACUTEST_COLOR_RED_INTENSIVE_, "ERROR: "); + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); + printf("\n"); + } + + if(acutest_verbose_level_ >= 3) { + printf("\n"); + } +} + +/* Call directly the given test unit function. */ +static enum acutest_state_ +acutest_do_run_(const struct acutest_test_* test, int index) +{ + enum acutest_state_ state = ACUTEST_STATE_FAILED; + + acutest_current_test_ = test; + acutest_current_index_ = index; + acutest_test_failures_ = 0; + acutest_test_already_logged_ = 0; + acutest_test_check_count_ = 0; + acutest_test_skip_count_ = 0; + acutest_cond_failed_ = 0; + +#ifdef __cplusplus +#ifndef TEST_NO_EXCEPTIONS + try { +#endif +#endif + acutest_init_(test->name); + acutest_begin_test_line_(test); + + /* This is good to do in case the test unit crashes. */ + fflush(stdout); + fflush(stderr); + + if(!acutest_worker_) { + acutest_abort_has_jmp_buf_ = 1; + if(setjmp(acutest_abort_jmp_buf_) != 0) + goto aborted; + } + + acutest_timer_get_time_(´st_timer_start_); + test->func(); + +aborted: + acutest_abort_has_jmp_buf_ = 0; + acutest_timer_get_time_(´st_timer_end_); + + if(acutest_test_failures_ > 0) + state = ACUTEST_STATE_FAILED; + else if(acutest_test_skip_count_ > 0) + state = ACUTEST_STATE_SKIPPED; + else + state = ACUTEST_STATE_SUCCESS; + + if(!acutest_test_already_logged_) + acutest_finish_test_line_(state); + + if(acutest_verbose_level_ >= 3) { + acutest_line_indent_(1); + switch(state) { + case ACUTEST_STATE_SUCCESS: + acutest_colored_printf_(ACUTEST_COLOR_GREEN_INTENSIVE_, "SUCCESS: "); + printf("All conditions have passed.\n"); + + if(acutest_timer_) { + acutest_line_indent_(1); + printf("Duration: "); + acutest_timer_print_diff_(); + printf("\n"); + } + break; + + case ACUTEST_STATE_SKIPPED: + acutest_colored_printf_(ACUTEST_COLOR_YELLOW_INTENSIVE_, "SKIPPED: "); + printf("%s.\n", acutest_test_skip_reason_); + break; + + default: + acutest_colored_printf_(ACUTEST_COLOR_RED_INTENSIVE_, "FAILED: "); + printf("%d condition%s %s failed.\n", + acutest_test_failures_, + (acutest_test_failures_ == 1) ? "" : "s", + (acutest_test_failures_ == 1) ? "has" : "have"); + break; + } + printf("\n"); + } + +#ifdef __cplusplus +#ifndef TEST_NO_EXCEPTIONS + } catch(std::exception& e) { + const char* what = e.what(); + acutest_check_(0, NULL, 0, "Threw std::exception"); + if(what != NULL) + acutest_message_("std::exception::what(): %s", what); + + if(acutest_verbose_level_ >= 3) { + acutest_line_indent_(1); + acutest_colored_printf_(ACUTEST_COLOR_RED_INTENSIVE_, "FAILED: "); + printf("C++ exception.\n\n"); + } + } catch(...) { + acutest_check_(0, NULL, 0, "Threw an exception"); + + if(acutest_verbose_level_ >= 3) { + acutest_line_indent_(1); + acutest_colored_printf_(ACUTEST_COLOR_RED_INTENSIVE_, "FAILED: "); + printf("C++ exception.\n\n"); + } + } +#endif +#endif + + acutest_fini_(test->name); + acutest_case_(NULL); + acutest_current_test_ = NULL; + + return state; +} + +/* Trigger the unit test. If possible (and not suppressed) it starts a child + * process who calls acutest_do_run_(), otherwise it calls acutest_do_run_() + * directly. */ +static void +acutest_run_(const struct acutest_test_* test, int index, int master_index) +{ + enum acutest_state_ state = ACUTEST_STATE_FAILED; + acutest_timer_type_ start, end; + + acutest_current_test_ = test; + acutest_test_already_logged_ = 0; + acutest_timer_get_time_(&start); + + if(!acutest_no_exec_) { + +#if defined(ACUTEST_UNIX_) + + pid_t pid; + int exit_code; + + /* Make sure the child starts with empty I/O buffers. */ + fflush(stdout); + fflush(stderr); + + pid = fork(); + if(pid == (pid_t)-1) { + acutest_error_("Cannot fork. %s [%d]", strerror(errno), errno); + } else if(pid == 0) { + /* Child: Do the test. */ + acutest_worker_ = 1; + state = acutest_do_run_(test, index); + acutest_exit_((int) state); + } else { + /* Parent: Wait until child terminates and analyze its exit code. */ + waitpid(pid, &exit_code, 0); + if(WIFEXITED(exit_code)) { + state = (enum acutest_state_) WEXITSTATUS(exit_code); + } else if(WIFSIGNALED(exit_code)) { + char tmp[32]; + const char* signame; + switch(WTERMSIG(exit_code)) { + case SIGINT: signame = "SIGINT"; break; + case SIGHUP: signame = "SIGHUP"; break; + case SIGQUIT: signame = "SIGQUIT"; break; + case SIGABRT: signame = "SIGABRT"; break; + case SIGKILL: signame = "SIGKILL"; break; + case SIGSEGV: signame = "SIGSEGV"; break; + case SIGILL: signame = "SIGILL"; break; + case SIGTERM: signame = "SIGTERM"; break; + default: snprintf(tmp, sizeof(tmp), "signal %d", WTERMSIG(exit_code)); signame = tmp; break; + } + acutest_error_("Test interrupted by %s.", signame); + } else { + acutest_error_("Test ended in an unexpected way [%d].", exit_code); + } + } + +#elif defined(ACUTEST_WIN_) + + char buffer[512] = {0}; + STARTUPINFOA startupInfo; + PROCESS_INFORMATION processInfo; + DWORD exitCode; + + /* Windows has no fork(). So we propagate all info into the child + * through a command line arguments. */ + snprintf(buffer, sizeof(buffer), + "%s --worker=%d %s --no-exec --no-summary %s --verbose=%d --color=%s -- \"%s\"", + acutest_argv0_, index, acutest_timer_ ? "--time" : "", + acutest_tap_ ? "--tap" : "", acutest_verbose_level_, + acutest_colorize_ ? "always" : "never", + test->name); + memset(&startupInfo, 0, sizeof(startupInfo)); + startupInfo.cb = sizeof(STARTUPINFO); + if(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInfo)) { + WaitForSingleObject(processInfo.hProcess, INFINITE); + GetExitCodeProcess(processInfo.hProcess, &exitCode); + CloseHandle(processInfo.hThread); + CloseHandle(processInfo.hProcess); + switch(exitCode) { + case 0: state = ACUTEST_STATE_SUCCESS; break; + case 1: state = ACUTEST_STATE_FAILED; break; + case 2: state = ACUTEST_STATE_SKIPPED; break; + case 3: acutest_error_("Aborted."); break; + case 0xC0000005: acutest_error_("Access violation."); break; + default: acutest_error_("Test ended in an unexpected way [%lu].", exitCode); break; + } + } else { + acutest_error_("Cannot create unit test subprocess [%ld].", GetLastError()); + } + +#else + + /* A platform where we don't know how to run child process. */ + state = acutest_do_run_(test, index); + +#endif + + } else { + /* Child processes suppressed through --no-exec. */ + state = acutest_do_run_(test, index); + } + acutest_timer_get_time_(&end); + + acutest_current_test_ = NULL; + + acutest_test_data_[master_index].state = state; + acutest_test_data_[master_index].duration = acutest_timer_diff_(start, end); +} + +#if defined(ACUTEST_WIN_) +/* Callback for SEH events. */ +static LONG CALLBACK +acutest_seh_exception_filter_(EXCEPTION_POINTERS *ptrs) +{ + acutest_check_(0, NULL, 0, "Unhandled SEH exception"); + acutest_message_("Exception code: 0x%08lx", ptrs->ExceptionRecord->ExceptionCode); + acutest_message_("Exception address: 0x%p", ptrs->ExceptionRecord->ExceptionAddress); + + fflush(stdout); + fflush(stderr); + + return EXCEPTION_EXECUTE_HANDLER; +} +#endif + + +#define ACUTEST_CMDLINE_OPTFLAG_OPTIONALARG_ 0x0001 +#define ACUTEST_CMDLINE_OPTFLAG_REQUIREDARG_ 0x0002 + +#define ACUTEST_CMDLINE_OPTID_NONE_ 0 +#define ACUTEST_CMDLINE_OPTID_UNKNOWN_ (-0x7fffffff + 0) +#define ACUTEST_CMDLINE_OPTID_MISSINGARG_ (-0x7fffffff + 1) +#define ACUTEST_CMDLINE_OPTID_BOGUSARG_ (-0x7fffffff + 2) + +typedef struct acutest_test_CMDLINE_OPTION_ { + char shortname; + const char* longname; + int id; + unsigned flags; +} ACUTEST_CMDLINE_OPTION_; + +static int +acutest_cmdline_handle_short_opt_group_(const ACUTEST_CMDLINE_OPTION_* options, + const char* arggroup, + int (*callback)(int /*optval*/, const char* /*arg*/)) +{ + const ACUTEST_CMDLINE_OPTION_* opt; + int i; + int ret = 0; + + for(i = 0; arggroup[i] != '\0'; i++) { + for(opt = options; opt->id != 0; opt++) { + if(arggroup[i] == opt->shortname) + break; + } + + if(opt->id != 0 && !(opt->flags & ACUTEST_CMDLINE_OPTFLAG_REQUIREDARG_)) { + ret = callback(opt->id, NULL); + } else { + /* Unknown option. */ + char badoptname[3]; + badoptname[0] = '-'; + badoptname[1] = arggroup[i]; + badoptname[2] = '\0'; + ret = callback((opt->id != 0 ? ACUTEST_CMDLINE_OPTID_MISSINGARG_ : ACUTEST_CMDLINE_OPTID_UNKNOWN_), + badoptname); + } + + if(ret != 0) + break; + } + + return ret; +} + +#define ACUTEST_CMDLINE_AUXBUF_SIZE_ 32 + +static int +acutest_cmdline_read_(const ACUTEST_CMDLINE_OPTION_* options, int argc, char** argv, + int (*callback)(int /*optval*/, const char* /*arg*/)) +{ + + const ACUTEST_CMDLINE_OPTION_* opt; + char auxbuf[ACUTEST_CMDLINE_AUXBUF_SIZE_+1]; + int after_doubledash = 0; + int i = 1; + int ret = 0; + + auxbuf[ACUTEST_CMDLINE_AUXBUF_SIZE_] = '\0'; + + while(i < argc) { + if(after_doubledash || strcmp(argv[i], "-") == 0) { + /* Non-option argument. */ + ret = callback(ACUTEST_CMDLINE_OPTID_NONE_, argv[i]); + } else if(strcmp(argv[i], "--") == 0) { + /* End of options. All the remaining members are non-option arguments. */ + after_doubledash = 1; + } else if(argv[i][0] != '-') { + /* Non-option argument. */ + ret = callback(ACUTEST_CMDLINE_OPTID_NONE_, argv[i]); + } else { + for(opt = options; opt->id != 0; opt++) { + if(opt->longname != NULL && strncmp(argv[i], "--", 2) == 0) { + size_t len = strlen(opt->longname); + if(strncmp(argv[i]+2, opt->longname, len) == 0) { + /* Regular long option. */ + if(argv[i][2+len] == '\0') { + /* with no argument provided. */ + if(!(opt->flags & ACUTEST_CMDLINE_OPTFLAG_REQUIREDARG_)) + ret = callback(opt->id, NULL); + else + ret = callback(ACUTEST_CMDLINE_OPTID_MISSINGARG_, argv[i]); + break; + } else if(argv[i][2+len] == '=') { + /* with an argument provided. */ + if(opt->flags & (ACUTEST_CMDLINE_OPTFLAG_OPTIONALARG_ | ACUTEST_CMDLINE_OPTFLAG_REQUIREDARG_)) { + ret = callback(opt->id, argv[i]+2+len+1); + } else { + snprintf(auxbuf, sizeof(auxbuf), "--%s", opt->longname); + ret = callback(ACUTEST_CMDLINE_OPTID_BOGUSARG_, auxbuf); + } + break; + } else { + continue; + } + } + } else if(opt->shortname != '\0' && argv[i][0] == '-') { + if(argv[i][1] == opt->shortname) { + /* Regular short option. */ + if(opt->flags & ACUTEST_CMDLINE_OPTFLAG_REQUIREDARG_) { + if(argv[i][2] != '\0') + ret = callback(opt->id, argv[i]+2); + else if(i+1 < argc) + ret = callback(opt->id, argv[++i]); + else + ret = callback(ACUTEST_CMDLINE_OPTID_MISSINGARG_, argv[i]); + break; + } else { + ret = callback(opt->id, NULL); + + /* There might be more (argument-less) short options + * grouped together. */ + if(ret == 0 && argv[i][2] != '\0') + ret = acutest_cmdline_handle_short_opt_group_(options, argv[i]+2, callback); + break; + } + } + } + } + + if(opt->id == 0) { /* still not handled? */ + if(argv[i][0] != '-') { + /* Non-option argument. */ + ret = callback(ACUTEST_CMDLINE_OPTID_NONE_, argv[i]); + } else { + /* Unknown option. */ + char* badoptname = argv[i]; + + if(strncmp(badoptname, "--", 2) == 0) { + /* Strip any argument from the long option. */ + char* assignment = strchr(badoptname, '='); + if(assignment != NULL) { + size_t len = (size_t)(assignment - badoptname); + if(len > ACUTEST_CMDLINE_AUXBUF_SIZE_) + len = ACUTEST_CMDLINE_AUXBUF_SIZE_; + strncpy(auxbuf, badoptname, len); + auxbuf[len] = '\0'; + badoptname = auxbuf; + } + } + + ret = callback(ACUTEST_CMDLINE_OPTID_UNKNOWN_, badoptname); + } + } + } + + if(ret != 0) + return ret; + i++; + } + + return ret; +} + +static void +acutest_help_(void) +{ + printf("Usage: %s [options] [test...]\n", acutest_argv0_); + printf("\n"); + printf("Run the specified unit tests; or if the option '--exclude' is used, run all\n"); + printf("tests in the suite but those listed. By default, if no tests are specified\n"); + printf("on the command line, all unit tests in the suite are run.\n"); + printf("\n"); + printf("Options:\n"); + printf(" -X, --exclude Execute all unit tests but the listed ones\n"); + printf(" --exec[=WHEN] If supported, execute unit tests as child processes\n"); + printf(" (WHEN is one of 'auto', 'always', 'never')\n"); + printf(" -E, --no-exec Same as --exec=never\n"); +#if defined ACUTEST_WIN_ + printf(" -t, --time Measure test duration\n"); +#elif defined ACUTEST_HAS_POSIX_TIMER_ + printf(" -t, --time Measure test duration (real time)\n"); + printf(" --time=TIMER Measure test duration, using given timer\n"); + printf(" (TIMER is one of 'real', 'cpu')\n"); +#endif + printf(" --no-summary Suppress printing of test results summary\n"); + printf(" --tap Produce TAP-compliant output\n"); + printf(" (See https://testanything.org/)\n"); + printf(" -x, --xml-output=FILE Enable XUnit output to the given file\n"); + printf(" -l, --list List unit tests in the suite and exit\n"); + printf(" -v, --verbose Make output more verbose\n"); + printf(" --verbose=LEVEL Set verbose level to LEVEL:\n"); + printf(" 0 ... Be silent\n"); + printf(" 1 ... Output one line per test (and summary)\n"); + printf(" 2 ... As 1 and failed conditions (this is default)\n"); + printf(" 3 ... As 1 and all conditions (and extended summary)\n"); + printf(" -q, --quiet Same as --verbose=0\n"); + printf(" --color[=WHEN] Enable colorized output\n"); + printf(" (WHEN is one of 'auto', 'always', 'never')\n"); + printf(" --no-color Same as --color=never\n"); + printf(" -h, --help Display this help and exit\n"); + + if(acutest_list_size_ < 16) { + printf("\n"); + acutest_list_names_(); + } +} + +static const ACUTEST_CMDLINE_OPTION_ acutest_cmdline_options_[] = { + { 'X', "exclude", 'X', 0 }, + { 's', "skip", 'X', 0 }, /* kept for compatibility, use --exclude instead */ + { 0, "exec", 'e', ACUTEST_CMDLINE_OPTFLAG_OPTIONALARG_ }, + { 'E', "no-exec", 'E', 0 }, +#if defined ACUTEST_WIN_ + { 't', "time", 't', 0 }, + { 0, "timer", 't', 0 }, /* kept for compatibility */ +#elif defined ACUTEST_HAS_POSIX_TIMER_ + { 't', "time", 't', ACUTEST_CMDLINE_OPTFLAG_OPTIONALARG_ }, + { 0, "timer", 't', ACUTEST_CMDLINE_OPTFLAG_OPTIONALARG_ }, /* kept for compatibility */ +#endif + { 0, "no-summary", 'S', 0 }, + { 0, "tap", 'T', 0 }, + { 'l', "list", 'l', 0 }, + { 'v', "verbose", 'v', ACUTEST_CMDLINE_OPTFLAG_OPTIONALARG_ }, + { 'q', "quiet", 'q', 0 }, + { 0, "color", 'c', ACUTEST_CMDLINE_OPTFLAG_OPTIONALARG_ }, + { 0, "no-color", 'C', 0 }, + { 'h', "help", 'h', 0 }, + { 0, "worker", 'w', ACUTEST_CMDLINE_OPTFLAG_REQUIREDARG_ }, /* internal */ + { 'x', "xml-output", 'x', ACUTEST_CMDLINE_OPTFLAG_REQUIREDARG_ }, + { 0, NULL, 0, 0 } +}; + +static int +acutest_cmdline_callback_(int id, const char* arg) +{ + switch(id) { + case 'X': + acutest_exclude_mode_ = 1; + break; + + case 'e': + if(arg == NULL || strcmp(arg, "always") == 0) { + acutest_no_exec_ = 0; + } else if(strcmp(arg, "never") == 0) { + acutest_no_exec_ = 1; + } else if(strcmp(arg, "auto") == 0) { + /*noop*/ + } else { + fprintf(stderr, "%s: Unrecognized argument '%s' for option --exec.\n", acutest_argv0_, arg); + fprintf(stderr, "Try '%s --help' for more information.\n", acutest_argv0_); + acutest_exit_(2); + } + break; + + case 'E': + acutest_no_exec_ = 1; + break; + + case 't': +#if defined ACUTEST_WIN_ || defined ACUTEST_HAS_POSIX_TIMER_ + if(arg == NULL || strcmp(arg, "real") == 0) { + acutest_timer_ = 1; + #ifndef ACUTEST_WIN_ + } else if(strcmp(arg, "cpu") == 0) { + acutest_timer_ = 2; + #endif + } else { + fprintf(stderr, "%s: Unrecognized argument '%s' for option --time.\n", acutest_argv0_, arg); + fprintf(stderr, "Try '%s --help' for more information.\n", acutest_argv0_); + acutest_exit_(2); + } +#endif + break; + + case 'S': + acutest_no_summary_ = 1; + break; + + case 'T': + acutest_tap_ = 1; + break; + + case 'l': + acutest_list_names_(); + acutest_exit_(0); + break; + + case 'v': + acutest_verbose_level_ = (arg != NULL ? atoi(arg) : acutest_verbose_level_+1); + break; + + case 'q': + acutest_verbose_level_ = 0; + break; + + case 'c': + if(arg == NULL || strcmp(arg, "always") == 0) { + acutest_colorize_ = 1; + } else if(strcmp(arg, "never") == 0) { + acutest_colorize_ = 0; + } else if(strcmp(arg, "auto") == 0) { + /*noop*/ + } else { + fprintf(stderr, "%s: Unrecognized argument '%s' for option --color.\n", acutest_argv0_, arg); + fprintf(stderr, "Try '%s --help' for more information.\n", acutest_argv0_); + acutest_exit_(2); + } + break; + + case 'C': + acutest_colorize_ = 0; + break; + + case 'h': + acutest_help_(); + acutest_exit_(0); + break; + + case 'w': + acutest_worker_ = 1; + acutest_worker_index_ = atoi(arg); + break; + case 'x': + acutest_xml_output_ = fopen(arg, "w"); + if (!acutest_xml_output_) { + fprintf(stderr, "Unable to open '%s': %s\n", arg, strerror(errno)); + acutest_exit_(2); + } + break; + + case 0: + if(acutest_select_(arg) == 0) { + fprintf(stderr, "%s: Unrecognized unit test '%s'\n", acutest_argv0_, arg); + fprintf(stderr, "Try '%s --list' for list of unit tests.\n", acutest_argv0_); + acutest_exit_(2); + } + break; + + case ACUTEST_CMDLINE_OPTID_UNKNOWN_: + fprintf(stderr, "Unrecognized command line option '%s'.\n", arg); + fprintf(stderr, "Try '%s --help' for more information.\n", acutest_argv0_); + acutest_exit_(2); + break; + + case ACUTEST_CMDLINE_OPTID_MISSINGARG_: + fprintf(stderr, "The command line option '%s' requires an argument.\n", arg); + fprintf(stderr, "Try '%s --help' for more information.\n", acutest_argv0_); + acutest_exit_(2); + break; + + case ACUTEST_CMDLINE_OPTID_BOGUSARG_: + fprintf(stderr, "The command line option '%s' does not expect an argument.\n", arg); + fprintf(stderr, "Try '%s --help' for more information.\n", acutest_argv0_); + acutest_exit_(2); + break; + } + + return 0; +} + +static int +acutest_under_debugger_(void) +{ +#ifdef ACUTEST_LINUX_ + /* Scan /proc/self/status for line "TracerPid: [PID]". If such line exists + * and the PID is non-zero, we're being debugged. */ + { + static const int OVERLAP = 32; + int fd; + char buf[512]; + size_t n_read; + pid_t tracer_pid = 0; + + /* Little trick so that we can treat the 1st line the same as any other + * and detect line start easily. */ + buf[0] = '\n'; + n_read = 1; + + fd = open("/proc/self/status", O_RDONLY); + if(fd != -1) { + while(1) { + static const char pattern[] = "\nTracerPid:"; + const char* field; + + while(n_read < sizeof(buf) - 1) { + ssize_t n; + + n = read(fd, buf + n_read, sizeof(buf) - 1 - n_read); + if(n <= 0) + break; + n_read += (size_t)n; + } + buf[n_read] = '\0'; + + field = strstr(buf, pattern); + if(field != NULL && field < buf + sizeof(buf) - OVERLAP) { + tracer_pid = (pid_t) atoi(field + sizeof(pattern) - 1); + break; + } + + if(n_read == sizeof(buf) - 1) { + /* Move the tail with the potentially incomplete line we're + * be looking for to the beginning of the buffer. + * (The OVERLAP must be large enough so the searched line + * can fit in completely.) */ + memmove(buf, buf + sizeof(buf) - 1 - OVERLAP, OVERLAP); + n_read = OVERLAP; + } else { + break; + } + } + + close(fd); + + if(tracer_pid != 0) + return 1; + } + } +#endif + +#ifdef ACUTEST_MACOS_ + /* See https://developer.apple.com/library/archive/qa/qa1361/_index.html */ + { + int mib[4]; + struct kinfo_proc info; + size_t size; + + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_PID; + mib[3] = getpid(); + + size = sizeof(info); + info.kp_proc.p_flag = 0; + sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, NULL, 0); + + if(info.kp_proc.p_flag & P_TRACED) + return 1; + } +#endif + +#ifdef ACUTEST_WIN_ + if(IsDebuggerPresent()) + return 1; +#endif + +#ifdef RUNNING_ON_VALGRIND + /* We treat Valgrind as a debugger of sorts. + * (Macro RUNNING_ON_VALGRIND is provided by , if available.) */ + if(RUNNING_ON_VALGRIND) + return 1; +#endif + + return 0; +} + +int +main(int argc, char** argv) +{ + int i, index; + int exit_code = 1; + + acutest_argv0_ = argv[0]; + +#if defined ACUTEST_UNIX_ + acutest_colorize_ = isatty(STDOUT_FILENO); +#elif defined ACUTEST_WIN_ + #if defined _BORLANDC_ + acutest_colorize_ = isatty(_fileno(stdout)); + #else + acutest_colorize_ = _isatty(_fileno(stdout)); + #endif +#else + acutest_colorize_ = 0; +#endif + + /* Count all test units */ + acutest_list_size_ = 0; + for(i = 0; acutest_list_[i].func != NULL; i++) + acutest_list_size_++; + + acutest_test_data_ = (struct acutest_test_data_*)calloc(acutest_list_size_, sizeof(struct acutest_test_data_)); + if(acutest_test_data_ == NULL) { + fprintf(stderr, "Out of memory.\n"); + acutest_exit_(2); + } + + /* Parse options */ + acutest_cmdline_read_(acutest_cmdline_options_, argc, argv, acutest_cmdline_callback_); + + /* Initialize the proper timer. */ + acutest_timer_init_(); + +#if defined(ACUTEST_WIN_) + SetUnhandledExceptionFilter(acutest_seh_exception_filter_); +#ifdef _MSC_VER + _set_abort_behavior(0, _WRITE_ABORT_MSG); +#endif +#endif + + /* Determine what to run. */ + if(acutest_count_(ACUTEST_STATE_SELECTED) > 0) { + enum acutest_state_ if_selected; + enum acutest_state_ if_unselected; + + if(!acutest_exclude_mode_) { + if_selected = ACUTEST_STATE_NEEDTORUN; + if_unselected = ACUTEST_STATE_EXCLUDED; + } else { + if_selected = ACUTEST_STATE_EXCLUDED; + if_unselected = ACUTEST_STATE_NEEDTORUN; + } + + for(i = 0; acutest_list_[i].func != NULL; i++) { + if(acutest_test_data_[i].state == ACUTEST_STATE_SELECTED) + acutest_test_data_[i].state = if_selected; + else + acutest_test_data_[i].state = if_unselected; + } + } else { + /* By default, we want to run all tests. */ + for(i = 0; acutest_list_[i].func != NULL; i++) + acutest_test_data_[i].state = ACUTEST_STATE_NEEDTORUN; + } + + /* By default, we want to suppress running tests as child processes if we + * run just one test, or if we're under debugger: Debugging tests is then + * so much easier. */ + if(acutest_no_exec_ < 0) { + if(acutest_count_(ACUTEST_STATE_NEEDTORUN) <= 1 || acutest_under_debugger_()) + acutest_no_exec_ = 1; + else + acutest_no_exec_ = 0; + } + + if(acutest_tap_) { + /* TAP requires we know test result ("ok", "not ok") before we output + * anything about the test, and this gets problematic for larger verbose + * levels. */ + if(acutest_verbose_level_ > 2) + acutest_verbose_level_ = 2; + + /* TAP harness should provide some summary. */ + acutest_no_summary_ = 1; + + if(!acutest_worker_) + printf("1..%d\n", acutest_count_(ACUTEST_STATE_NEEDTORUN)); + } + + index = acutest_worker_index_; + for(i = 0; acutest_list_[i].func != NULL; i++) { + if(acutest_test_data_[i].state == ACUTEST_STATE_NEEDTORUN) + acutest_run_(´st_list_[i], index++, i); + } + + /* Write a summary */ + if(!acutest_no_summary_ && acutest_verbose_level_ >= 1) { + int n_run, n_success, n_failed ; + + n_run = acutest_list_size_ - acutest_count_(ACUTEST_STATE_EXCLUDED); + n_success = acutest_count_(ACUTEST_STATE_SUCCESS); + n_failed = acutest_count_(ACUTEST_STATE_FAILED); + + if(acutest_verbose_level_ >= 3) { + acutest_colored_printf_(ACUTEST_COLOR_DEFAULT_INTENSIVE_, "Summary:\n"); + + printf(" Count of run unit tests: %4d\n", n_run); + printf(" Count of successful unit tests: %4d\n", n_success); + printf(" Count of failed unit tests: %4d\n", n_failed); + } + + if(n_failed == 0) { + acutest_colored_printf_(ACUTEST_COLOR_GREEN_INTENSIVE_, "SUCCESS:"); + printf(" No unit tests have failed.\n"); + } else { + acutest_colored_printf_(ACUTEST_COLOR_RED_INTENSIVE_, "FAILED:"); + printf(" %d of %d unit tests %s failed.\n", + n_failed, n_run, (n_failed == 1) ? "has" : "have"); + } + + if(acutest_verbose_level_ >= 3) + printf("\n"); + } + + if (acutest_xml_output_) { + const char* suite_name = acutest_basename_(argv[0]); + fprintf(acutest_xml_output_, "\n"); + fprintf(acutest_xml_output_, "\n", + suite_name, + (int)acutest_list_size_, + acutest_count_(ACUTEST_STATE_FAILED), + acutest_count_(ACUTEST_STATE_SKIPPED) + acutest_count_(ACUTEST_STATE_EXCLUDED)); + for(i = 0; acutest_list_[i].func != NULL; i++) { + struct acutest_test_data_ *details = ´st_test_data_[i]; + const char* str_state; + fprintf(acutest_xml_output_, " \n", acutest_list_[i].name, details->duration); + + switch(details->state) { + case ACUTEST_STATE_SUCCESS: str_state = NULL; break; + case ACUTEST_STATE_EXCLUDED: /* Fall through. */ + case ACUTEST_STATE_SKIPPED: str_state = ""; break; + case ACUTEST_STATE_FAILED: /* Fall through. */ + default: str_state = ""; break; + } + + if(str_state != NULL) + fprintf(acutest_xml_output_, " %s\n", str_state); + fprintf(acutest_xml_output_, " \n"); + } + fprintf(acutest_xml_output_, "\n"); + fclose(acutest_xml_output_); + } + + if(acutest_worker_ && acutest_count_(ACUTEST_STATE_EXCLUDED)+1 == acutest_list_size_) { + /* If we are the child process, we need to propagate the test state + * without any moderation. */ + for(i = 0; acutest_list_[i].func != NULL; i++) { + if(acutest_test_data_[i].state != ACUTEST_STATE_EXCLUDED) { + exit_code = (int) acutest_test_data_[i].state; + break; + } + } + } else { + if(acutest_count_(ACUTEST_STATE_FAILED) > 0) + exit_code = 1; + else + exit_code = 0; + } + + acutest_cleanup_(); + return exit_code; +} + +#ifdef __cplusplus + } /* extern "C" */ +#endif +#endif /* #ifndef TEST_NO_MAIN */ + +#ifdef _MSC_VER + #pragma warning(pop) +#endif + + + +#endif /* #ifndef ACUTEST_H */ diff --git a/tests/acutest_main.c b/tests/acutest_main.c deleted file mode 100644 index 8797732..0000000 --- a/tests/acutest_main.c +++ /dev/null @@ -1,3 +0,0 @@ -#include "../external/acutest/include/acutest.h" - -// This translation unit provides the single main() for Acutest. diff --git a/tests/unit_tests.cpp b/tests/hot_reload.cpp similarity index 83% rename from tests/unit_tests.cpp rename to tests/hot_reload.cpp index b211542..13baa98 100644 --- a/tests/unit_tests.cpp +++ b/tests/hot_reload.cpp @@ -1,23 +1,15 @@ -#include "../external/acutest/include/acutest.h" +#define TEST_NO_MAIN +#include "acutest.h" #include #include #include #include #include #include "../include/HotReload.h" -#include "../include/ScriptEngine.h" +#include "../include/scripting/ScriptEngine.h" using namespace std::chrono_literals; -/* simple sanity test */ -void test_one(void) { - TEST_CHECK(1 + 1 == 2); -} - -void test_str(void) { - TEST_CHECK(strcmp("foo","foo") == 0); -} - void test_hotreload_directory_watch(void) { std::filesystem::path tmpDir = std::filesystem::current_path() / "tmp_watch"; std::filesystem::create_directories(tmpDir); @@ -93,11 +85,3 @@ void test_scriptengine_include(void) { std::filesystem::remove(tmpDir); } -TEST_LIST = { - { "one", test_one }, - { "str", test_str }, - { "hotreload_dir", test_hotreload_directory_watch }, - { "script_compile", test_scriptengine_compile_and_call }, - { "script_include", test_scriptengine_include }, - { NULL, NULL } -}; diff --git a/tests/hot_reload.h b/tests/hot_reload.h new file mode 100644 index 0000000..7ca749c --- /dev/null +++ b/tests/hot_reload.h @@ -0,0 +1,5 @@ +#pragma once + +void test_hotreload_directory_watch(void); +void test_scriptengine_compile_and_call(void); +void test_scriptengine_include(void); \ No newline at end of file diff --git a/tests/test.cpp b/tests/test.cpp new file mode 100644 index 0000000..69296b9 --- /dev/null +++ b/tests/test.cpp @@ -0,0 +1,8 @@ +#include "../external/acutest/include/acutest.h" +#include "hot_reload.h" +TEST_LIST = { + { "hotreload_dir", test_hotreload_directory_watch }, + { "script_compile", test_scriptengine_compile_and_call }, + { "script_include", test_scriptengine_include }, + { NULL, NULL } +}; From adb57e65e04e69acc53101dd62833550bea1b2c6 Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Mon, 17 Nov 2025 21:11:59 +1300 Subject: [PATCH 02/53] chore: remove reference to external acutest --- tests/test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test.cpp b/tests/test.cpp index 69296b9..a93dc03 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -1,4 +1,4 @@ -#include "../external/acutest/include/acutest.h" +#include "acutest.h" #include "hot_reload.h" TEST_LIST = { { "hotreload_dir", test_hotreload_directory_watch }, From d49650b9a76fb9300587a45a8a2143fb516b1a14 Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Mon, 17 Nov 2025 21:26:11 +1300 Subject: [PATCH 03/53] chore: refactor out binding --- CMakeLists.txt | 7 +- include/scripting/DrawBindings.h | 4 + include/scripting/LogBindings.h | 4 + include/scripting/ToastBindings.h | 4 + src/scripting/DrawBindings.cpp | 30 +++++ src/scripting/LogBindings.cpp | 122 ++++++++++++++++++++ src/scripting/ScriptBindings.cpp | 179 ++---------------------------- src/scripting/ToastBindings.cpp | 45 ++++++++ tests/CMakeLists.txt | 4 +- 9 files changed, 225 insertions(+), 174 deletions(-) create mode 100644 include/scripting/DrawBindings.h create mode 100644 include/scripting/LogBindings.h create mode 100644 include/scripting/ToastBindings.h create mode 100644 src/scripting/DrawBindings.cpp create mode 100644 src/scripting/LogBindings.cpp create mode 100644 src/scripting/ToastBindings.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index c273520..a517061 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -76,6 +76,9 @@ add_executable(simian src/Application.cpp src/scripting/ScriptEngine.cpp src/scripting/ScriptBindings.cpp + src/scripting/ToastBindings.cpp + src/scripting/LogBindings.cpp + src/scripting/DrawBindings.cpp src/HotReload.cpp src/gui/GuiManager.cpp src/gui/LogWindow.cpp @@ -84,12 +87,14 @@ add_executable(simian target_include_directories(simian PUBLIC include + include/scripting + include/gui src/log external/raylib/src external/angelscript/sdk/angelscript/include external/angelscript/sdk/add_on/scriptstdstring external/angelscript/sdk/add_on/scriptbuilder - external/imgui + external/imgui ) target_link_libraries(simian PRIVATE diff --git a/include/scripting/DrawBindings.h b/include/scripting/DrawBindings.h new file mode 100644 index 0000000..51a4879 --- /dev/null +++ b/include/scripting/DrawBindings.h @@ -0,0 +1,4 @@ +#pragma once +#include + +void RegisterDrawBindings(asIScriptEngine *engine); diff --git a/include/scripting/LogBindings.h b/include/scripting/LogBindings.h new file mode 100644 index 0000000..d11d0fb --- /dev/null +++ b/include/scripting/LogBindings.h @@ -0,0 +1,4 @@ +#pragma once +#include + +void RegisterLogBindings(asIScriptEngine *engine); diff --git a/include/scripting/ToastBindings.h b/include/scripting/ToastBindings.h new file mode 100644 index 0000000..ba7950d --- /dev/null +++ b/include/scripting/ToastBindings.h @@ -0,0 +1,4 @@ +#pragma once +#include + +void RegisterToastBindings(asIScriptEngine *engine); diff --git a/src/scripting/DrawBindings.cpp b/src/scripting/DrawBindings.cpp new file mode 100644 index 0000000..89342bb --- /dev/null +++ b/src/scripting/DrawBindings.cpp @@ -0,0 +1,30 @@ +#include "scripting/DrawBindings.h" +#include "raylib.h" +#include +#include +#include + +Color ColorFromUInt(unsigned int c) +{ + Color col; + col.r = (c >> 24) & 0xFF; + col.g = (c >> 16) & 0xFF; + col.b = (c >> 8) & 0xFF; + col.a = c & 0xFF; + return col; +} + +void AS_DrawText(const std::string &text, int x, int y, int fontSize, unsigned int color) +{ + DrawText(text.c_str(), x, y, fontSize, ColorFromUInt(color)); +} + +void RegisterDrawBindings(asIScriptEngine *engine) +{ + int r; + + // Register DrawText function + r = engine->RegisterGlobalFunction("void DrawText(const string &in, int, int, int, uint)", + asFUNCTION(AS_DrawText), asCALL_CDECL); + assert(r >= 0); +} diff --git a/src/scripting/LogBindings.cpp b/src/scripting/LogBindings.cpp new file mode 100644 index 0000000..12beb5d --- /dev/null +++ b/src/scripting/LogBindings.cpp @@ -0,0 +1,122 @@ +#include "scripting/LogBindings.h" +#include "../log/log.h" +#include +#include +#include + +// Log level constants +static int AS_LOG_TRACE = 1; +static int AS_LOG_DEBUG = 2; +static int AS_LOG_INFO = 3; +static int AS_LOG_WARNING = 4; +static int AS_LOG_ERROR = 5; +static int AS_LOG_FATAL = 6; + +void Print(asIScriptGeneric *gen) +{ + // Get the message parameter + std::string *msg = static_cast(gen->GetArgObject(0)); + + // Get the active context to retrieve script file and line number + asIScriptContext *ctx = asGetActiveContext(); + + if (ctx) + { + const char *section = nullptr; + int line = 0; + + // Get the current line number and script section + line = ctx->GetLineNumber(0, nullptr, §ion); + + if (section && line > 0) + { + // Log with script file and line number + log_log(LOG_INFO, section, line, "%s", msg->c_str()); + } + else + { + // Fallback if we can't get the info + log_info("%s", msg->c_str()); + } + } + else + { + // No context available, just log normally + log_info("%s", msg->c_str()); + } +} + +void Log(asIScriptGeneric *gen) +{ + // arg0: int level, arg1: string message + int level = gen->GetArgDWord(0); + std::string *msg = static_cast(gen->GetArgObject(1)); + + // Obtain script context to fetch file/line + asIScriptContext *ctx = asGetActiveContext(); + if (ctx) + { + const char *section = nullptr; + int line = 0; + line = ctx->GetLineNumber(0, nullptr, §ion); + if (section && line > 0) + { + // Use the library's log_log to preserve filename/line info + log_log(level, section, line, "%s", msg ? msg->c_str() : ""); + return; + } + } + + // Fallback: log without script location + switch (level) + { + case LOG_TRACE: + log_trace("%s", msg ? msg->c_str() : ""); + break; + case LOG_DEBUG: + log_debug("%s", msg ? msg->c_str() : ""); + break; + case LOG_WARNING: + log_warn("%s", msg ? msg->c_str() : ""); + break; + case LOG_ERROR: + log_error("%s", msg ? msg->c_str() : ""); + break; + case LOG_FATAL: + log_fatal("%s", msg ? msg->c_str() : ""); + break; + case LOG_INFO: + default: + log_info("%s", msg ? msg->c_str() : ""); + break; + } +} + +void RegisterLogBindings(asIScriptEngine *engine) +{ + int r; + + // Register Print function + r = engine->RegisterGlobalFunction("void Print(const string &in)", + asFUNCTION(Print), asCALL_GENERIC); + assert(r >= 0); + + // Register log level constants + r = engine->RegisterGlobalProperty("int LOG_TRACE", (void *)&AS_LOG_TRACE); + assert(r >= 0); + r = engine->RegisterGlobalProperty("int LOG_DEBUG", (void *)&AS_LOG_DEBUG); + assert(r >= 0); + r = engine->RegisterGlobalProperty("int LOG_INFO", (void *)&AS_LOG_INFO); + assert(r >= 0); + r = engine->RegisterGlobalProperty("int LOG_WARNING", (void *)&AS_LOG_WARNING); + assert(r >= 0); + r = engine->RegisterGlobalProperty("int LOG_ERROR", (void *)&AS_LOG_ERROR); + assert(r >= 0); + r = engine->RegisterGlobalProperty("int LOG_FATAL", (void *)&AS_LOG_FATAL); + assert(r >= 0); + + // Register Log function + r = engine->RegisterGlobalFunction("void Log(int, const string &in)", + asFUNCTION(Log), asCALL_GENERIC); + assert(r >= 0); +} diff --git a/src/scripting/ScriptBindings.cpp b/src/scripting/ScriptBindings.cpp index 0c5ab1d..61876f5 100644 --- a/src/scripting/ScriptBindings.cpp +++ b/src/scripting/ScriptBindings.cpp @@ -1,177 +1,12 @@ #include "scripting/ScriptBindings.h" -#include "raylib.h" -#include -#include -#include "../log/log.h" -#include "gui/Toast.h" +#include "scripting/ToastBindings.h" +#include "scripting/LogBindings.h" +#include "scripting/DrawBindings.h" -// Expose log level constants to AngelScript -static int AS_LOG_TRACE = 1; -static int AS_LOG_DEBUG = 2; -static int AS_LOG_INFO = 3; -static int AS_LOG_WARNING = 4; -static int AS_LOG_ERROR = 5; -static int AS_LOG_FATAL = 6; - -static void AS_ToastInfo(const std::string& message) -{ - Toast::Info(message); -} - -static void AS_ToastWarning(const std::string& message) -{ - Toast::Warning(message); -} - -static void AS_ToastError(const std::string& message) -{ - Toast::Error(message); -} - -static void AS_ToastSuccess(const std::string& message) -{ - Toast::Success(message); -} void ScriptBindings::RegisterAll(asIScriptEngine *engine) { - // Register Print function with generic calling convention to access context - [[maybe_unused]] int r = engine->RegisterGlobalFunction("void Print(const string &in)", - asFUNCTION(Print), asCALL_GENERIC); - assert(r >= 0); - - // Register log level constants so scripts can refer to LOG_INFO, LOG_ERROR, etc. - r = engine->RegisterGlobalProperty("int LOG_TRACE", (void *)&AS_LOG_TRACE); - assert(r >= 0); - r = engine->RegisterGlobalProperty("int LOG_DEBUG", (void *)&AS_LOG_DEBUG); - assert(r >= 0); - r = engine->RegisterGlobalProperty("int LOG_INFO", (void *)&AS_LOG_INFO); - assert(r >= 0); - r = engine->RegisterGlobalProperty("int LOG_WARNING", (void *)&AS_LOG_WARNING); - assert(r >= 0); - r = engine->RegisterGlobalProperty("int LOG_ERROR", (void *)&AS_LOG_ERROR); - assert(r >= 0); - r = engine->RegisterGlobalProperty("int LOG_FATAL", (void *)&AS_LOG_FATAL); - assert(r >= 0); - - // Register Log(level, message) to allow scripts to log at different levels - r = engine->RegisterGlobalFunction("void Log(int, const string &in)", - asFUNCTION(Log), asCALL_GENERIC); - assert(r >= 0); - - // Toast functions - engine->SetDefaultNamespace("Toast"); - r = engine->RegisterGlobalFunction("void Info(const string &in)", - asFUNCTION(AS_ToastInfo), asCALL_CDECL); - assert(r >= 0); - r = engine->RegisterGlobalFunction("void Warning(const string &in)", - asFUNCTION(AS_ToastWarning), asCALL_CDECL); - assert(r >= 0); - r = engine->RegisterGlobalFunction("void Error(const string &in)", - asFUNCTION(AS_ToastError), asCALL_CDECL); - assert(r >= 0); - r = engine->RegisterGlobalFunction("void Success(const string &in)", - asFUNCTION(AS_ToastSuccess), asCALL_CDECL); - assert(r >= 0); - engine->SetDefaultNamespace(""); - - - // Register DrawText function - r = engine->RegisterGlobalFunction("void DrawText(const string &in, int, int, int, uint)", - asFUNCTION(AS_DrawText), asCALL_CDECL); - assert(r >= 0); -} - -void ScriptBindings::Print(asIScriptGeneric *gen) -{ - // Get the message parameter - std::string *msg = static_cast(gen->GetArgObject(0)); - - // Get the active context to retrieve script file and line number - asIScriptContext *ctx = asGetActiveContext(); - - if (ctx) - { - const char *section = nullptr; - int line = 0; - - // Get the current line number and script section - line = ctx->GetLineNumber(0, nullptr, §ion); - - if (section && line > 0) - { - // Log with script file and line number - log_log(LOG_INFO, section, line, "%s", msg->c_str()); - } - else - { - // Fallback if we can't get the info - log_info("%s", msg->c_str()); - } - } - else - { - // No context available, just log normally - log_info("%s", msg->c_str()); - } -} - -void ScriptBindings::Log(asIScriptGeneric *gen) -{ - // arg0: int level, arg1: string message - int level = gen->GetArgDWord(0); - std::string *msg = static_cast(gen->GetArgObject(1)); - - // Obtain script context to fetch file/line - asIScriptContext *ctx = asGetActiveContext(); - if (ctx) - { - const char *section = nullptr; - int line = 0; - line = ctx->GetLineNumber(0, nullptr, §ion); - if (section && line > 0) - { - // Use the library's log_log to preserve filename/line info - log_log(level, section, line, "%s", msg ? msg->c_str() : ""); - return; - } - } - - // Fallback: log without script location - switch (level) - { - case LOG_TRACE: - log_trace("%s", msg ? msg->c_str() : ""); - break; - case LOG_DEBUG: - log_debug("%s", msg ? msg->c_str() : ""); - break; - case LOG_WARNING: - log_warn("%s", msg ? msg->c_str() : ""); - break; - case LOG_ERROR: - log_error("%s", msg ? msg->c_str() : ""); - break; - case LOG_FATAL: - log_fatal("%s", msg ? msg->c_str() : ""); - break; - case LOG_INFO: - default: - log_info("%s", msg ? msg->c_str() : ""); - break; - } -} - -Color ColorFromUInt(unsigned int c) -{ - Color col; - col.r = (c >> 24) & 0xFF; - col.g = (c >> 16) & 0xFF; - col.b = (c >> 8) & 0xFF; - col.a = c & 0xFF; - return col; -} - -void ScriptBindings::AS_DrawText(const std::string &text, int x, int y, int fontSize, unsigned int color) -{ - DrawText(text.c_str(), x, y, fontSize, ColorFromUInt(color)); + // Delegate to separate binding files + RegisterToastBindings(engine); + RegisterLogBindings(engine); + RegisterDrawBindings(engine); } \ No newline at end of file diff --git a/src/scripting/ToastBindings.cpp b/src/scripting/ToastBindings.cpp new file mode 100644 index 0000000..2cb658c --- /dev/null +++ b/src/scripting/ToastBindings.cpp @@ -0,0 +1,45 @@ +#include "scripting/ToastBindings.h" +#include "gui/Toast.h" +#include +#include + +// Toast binding functions +static void AS_ToastInfo(const std::string& message) +{ + Toast::Info(message); +} + +static void AS_ToastWarning(const std::string& message) +{ + Toast::Warning(message); +} + +static void AS_ToastError(const std::string& message) +{ + Toast::Error(message); +} + +static void AS_ToastSuccess(const std::string& message) +{ + Toast::Success(message); +} + +void RegisterToastBindings(asIScriptEngine *engine) +{ + int r; + + engine->SetDefaultNamespace("Toast"); + r = engine->RegisterGlobalFunction("void Info(const string &in)", + asFUNCTION(AS_ToastInfo), asCALL_CDECL); + assert(r >= 0); + r = engine->RegisterGlobalFunction("void Warning(const string &in)", + asFUNCTION(AS_ToastWarning), asCALL_CDECL); + assert(r >= 0); + r = engine->RegisterGlobalFunction("void Error(const string &in)", + asFUNCTION(AS_ToastError), asCALL_CDECL); + assert(r >= 0); + r = engine->RegisterGlobalFunction("void Success(const string &in)", + asFUNCTION(AS_ToastSuccess), asCALL_CDECL); + assert(r >= 0); + engine->SetDefaultNamespace(""); +} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index f933790..b3d77ee 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -7,12 +7,14 @@ add_executable(unit_tests ${CMAKE_SOURCE_DIR}/src/HotReload.cpp ${CMAKE_SOURCE_DIR}/src/scripting/ScriptEngine.cpp ${CMAKE_SOURCE_DIR}/src/scripting/ScriptBindings.cpp + ${CMAKE_SOURCE_DIR}/src/scripting/ToastBindings.cpp + ${CMAKE_SOURCE_DIR}/src/scripting/LogBindings.cpp + ${CMAKE_SOURCE_DIR}/src/scripting/DrawBindings.cpp ${CMAKE_SOURCE_DIR}/src/log/log.c ) target_include_directories(unit_tests PRIVATE ${CMAKE_SOURCE_DIR}/tests - ${CMAKE_SOURCE_DIR}/external/acutest/include ${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/src/log ${CMAKE_SOURCE_DIR}/external/angelscript/sdk/angelscript/include From 35589b9620f87e5b456faf3211e6ac68f73b6261 Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Mon, 17 Nov 2025 22:20:21 +1300 Subject: [PATCH 04/53] feat: adding some drawing and image functions --- CMakeLists.txt | 1 + assets/raylib_96x96.png | Bin 0 -> 714 bytes imgui.ini | 2 +- include/scripting/ImageBindings.h | 4 +++ include/scripting/ScriptEngine.h | 4 +++ scripts/as.predefined | 27 +++++++++++++++++-- scripts/game.as | 6 ++++- scripts/update.as | 22 +++++++++++++--- src/Application.cpp | 2 +- src/scripting/DrawBindings.cpp | 42 ++++++++++++++++++++++++++++-- src/scripting/ImageBindings.cpp | 29 +++++++++++++++++++++ src/scripting/ScriptBindings.cpp | 2 ++ src/scripting/ScriptEngine.cpp | 7 ++++- tests/CMakeLists.txt | 1 + 14 files changed, 138 insertions(+), 11 deletions(-) create mode 100644 assets/raylib_96x96.png create mode 100644 include/scripting/ImageBindings.h create mode 100644 src/scripting/ImageBindings.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index a517061..33a8298 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -79,6 +79,7 @@ add_executable(simian src/scripting/ToastBindings.cpp src/scripting/LogBindings.cpp src/scripting/DrawBindings.cpp + src/scripting/ImageBindings.cpp src/HotReload.cpp src/gui/GuiManager.cpp src/gui/LogWindow.cpp diff --git a/assets/raylib_96x96.png b/assets/raylib_96x96.png new file mode 100644 index 0000000000000000000000000000000000000000..1d897dbabf41e82830cdca9578bcbb806322503f GIT binary patch literal 714 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1SE5RJ;(=A>LsobB`&GO$wiq3C7Jno3`L2R zIhjcc`DtmH$(e~c3OV`d`Bn;+W)+rZm3T zKfe#z?|Y(p|9k?I`)@Tl^%LIv<{xC~`{w(D<=Ush2o*uwtf-=p1U_XOYjZ2QUR{aKSvPMNojZ$F}X?F9B^;6sX%KAV3ZqJ2i&Ya~7wZ(hi z<+5}p_v(b-HMeH%d5)nl`_nuuCfa9znuKsl=B%^lXYF}XZS0!_^x>gx|L<7>?bc6d zyCLvb3&d(r6?56&#VM1k3gk_lao}PYP+>ICBT#_{yVkwl^{=77-+%eP4S7dARo(&< OCxfS}pUXO@geCybZ%Z2h literal 0 HcmV?d00001 diff --git a/imgui.ini b/imgui.ini index 074a4e9..4a5a372 100644 --- a/imgui.ini +++ b/imgui.ini @@ -26,7 +26,7 @@ Size=250,65 Collapsed=0 [Window][##TOAST1] -Pos=1010,543 +Pos=1010,560 Size=250,65 Collapsed=0 diff --git a/include/scripting/ImageBindings.h b/include/scripting/ImageBindings.h new file mode 100644 index 0000000..2c98785 --- /dev/null +++ b/include/scripting/ImageBindings.h @@ -0,0 +1,4 @@ +#pragma once +#include + +void RegisterImageBindings(asIScriptEngine *engine); \ No newline at end of file diff --git a/include/scripting/ScriptEngine.h b/include/scripting/ScriptEngine.h index a1ec2c6..cb20b77 100644 --- a/include/scripting/ScriptEngine.h +++ b/include/scripting/ScriptEngine.h @@ -26,11 +26,15 @@ public: asIScriptEngine* GetEngine() const { return engine; } asIScriptFunction* GetUpdateFunction() const { return updateFunc; } asIScriptFunction* GetDrawFunction() const { return drawFunc; } + asIScriptFunction* GetInitFunction() const { return initFunc; } + asIScriptFunction* GetShutdownFunction() const { return shutdownFunc; } private: asIScriptEngine* engine; asIScriptFunction* updateFunc; asIScriptFunction* drawFunc; + asIScriptFunction* initFunc; + asIScriptFunction* shutdownFunc; asIScriptModule* currentModule; bool hasValidScript; std::vector includePaths; diff --git a/scripts/as.predefined b/scripts/as.predefined index 1b40eb8..d5921f1 100644 --- a/scripts/as.predefined +++ b/scripts/as.predefined @@ -1,7 +1,9 @@ typedef void string; +string format(const string&in fmt, const ?&in ...); + +// Logging functions void Print(const string&in); void Log(int level, const string&in); -void DrawText(const string&in, int x, int y, int fontSize, int color); int LOG_TRACE; int LOG_DEBUG; int LOG_INFO; @@ -9,9 +11,30 @@ int LOG_WARNING; int LOG_ERROR; int LOG_FATAL; +// Toast notification functions namespace Toast { - void Info(const string&in); + void Info(const string&in msg); void Warning(const string&in); void Error(const string&in); void Success(const string&in); } + +// Drawing functions +namespace Draw { + void Pixel(int x, int y, int color); + void Line(int startX, int startY, int endX, int endY, int color); + void Circle(int centerX, int centerY, float radius, int color); + void Text(const string&in text, int x, int y, int fontSize, int color); + void Rectangle(int x, int y, int width, int height, int color); +} + +namespace Image { + class Image { + int width; + int height; + int mipmaps; + int format; + }; + Image@ Load(const string&in path); + void Unload(const Image@&in image); +} diff --git a/scripts/game.as b/scripts/game.as index 734eb8f..8b3fbf4 100644 --- a/scripts/game.as +++ b/scripts/game.as @@ -1,5 +1,9 @@ #include "update.as" void Draw() { - DrawText("Hello from AngelScript - Working perfectly!", int(x), int(y), 20, 0xFF0000FF); + Draw::Text(format("Hello from AngelScript - at x {} and y {}", int(x), int(y)), int(x), int(y), 20, 0xFF0000FF); + Draw::Rectangle(300, 200, 200, 100, 0x00FF00FF); + Draw::Pixel(250, 200, 0x0000FFFF); + Draw::Line(int(x), int(y), 400, 300, 0xFFFF00FF); + Draw::Circle(600, 400, 50.0f, 0xFF00FFFF); } \ No newline at end of file diff --git a/scripts/update.as b/scripts/update.as index 237741a..c310d87 100644 --- a/scripts/update.as +++ b/scripts/update.as @@ -1,12 +1,28 @@ float x = 50; float y = 100; +Image::Image img; + +void Init() { + Print("Initialization complete!"); + Log(LOG_INFO, "Log INFO: Initialization complete!"); + Toast::Success("Script initialized successfully!"); + img = Image::Load("assets/raylib_96x96.png"); + Toast::Info("Image loaded successfully."); +} + +void Shutdown() { + Image::Unload(img); + Print("Shutdown complete!"); + Log(LOG_INFO, "Log INFO: Shutdown complete!"); + Toast::Info("Script has been shut down."); +} void Update(float dt) { x += 64 * dt; if (x > 800) { x = 0; - Print("X position reset!"); - Log(LOG_INFO, "Log INFO: reset happened"); - Toast::Info("X position has been reset."); + Print(format("X position reset! {}", x)); + Log(LOG_INFO, format("Log INFO: reset happened at position {}", x)); + Toast::Info(format("X position has been reset to {}", x)); } } diff --git a/src/Application.cpp b/src/Application.cpp index 789af40..a0cf996 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -94,7 +94,7 @@ bool Application::Initialize(int argc, char *argv[]) void Application::Run() { - + scriptEngine.CallScriptFunction(scriptEngine.GetInitFunction()); while (!WindowShouldClose()) { float deltaTime = GetFrameTime(); diff --git a/src/scripting/DrawBindings.cpp b/src/scripting/DrawBindings.cpp index 89342bb..1d8d105 100644 --- a/src/scripting/DrawBindings.cpp +++ b/src/scripting/DrawBindings.cpp @@ -14,17 +14,55 @@ Color ColorFromUInt(unsigned int c) return col; } +void AS_DrawPixel(int x, int y, unsigned int color) +{ + DrawPixel(x, y, ColorFromUInt(color)); +} + +void AS_DrawLine(int startX, int startY, int endX, int endY, unsigned int color) +{ + DrawLine(startX, startY, endX, endY, ColorFromUInt(color)); +} + +void AS_DrawCircle(int centerX, int centerY, float radius, unsigned int color) +{ + DrawCircle(centerX, centerY, radius, ColorFromUInt(color)); +} void AS_DrawText(const std::string &text, int x, int y, int fontSize, unsigned int color) { DrawText(text.c_str(), x, y, fontSize, ColorFromUInt(color)); } +void AS_DrawRectangle(int x, int y, int width, int height, unsigned int color) +{ + DrawRectangle(x, y, width, height, ColorFromUInt(color)); +} + void RegisterDrawBindings(asIScriptEngine *engine) { int r; - // Register DrawText function - r = engine->RegisterGlobalFunction("void DrawText(const string &in, int, int, int, uint)", + engine->SetDefaultNamespace("Draw"); + + r = engine->RegisterGlobalFunction("void Pixel(int, int, uint)", + asFUNCTION(AS_DrawPixel), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void Line(int, int, int, int, uint)", + asFUNCTION(AS_DrawLine), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void Circle(int, int, float, uint)", + asFUNCTION(AS_DrawCircle), asCALL_CDECL); + assert(r >= 0); + r = engine->RegisterGlobalFunction("void Text(const string &in, int, int, int, uint)", asFUNCTION(AS_DrawText), asCALL_CDECL); assert(r >= 0); + r = engine->RegisterGlobalFunction("void Rectangle(int, int, int, int, uint)", + asFUNCTION(AS_DrawRectangle), asCALL_CDECL); + assert(r >= 0); + + + + engine->SetDefaultNamespace(""); } diff --git a/src/scripting/ImageBindings.cpp b/src/scripting/ImageBindings.cpp new file mode 100644 index 0000000..e12bd41 --- /dev/null +++ b/src/scripting/ImageBindings.cpp @@ -0,0 +1,29 @@ +#include "scripting/ImageBindings.h" +#include +#include +#include + +Image AS_LoadImage(const std::string &filename) +{ + return LoadImage(filename.c_str()); +} + +void RegisterImageBindings(asIScriptEngine *engine) +{ + int r; + + engine->SetDefaultNamespace("Image"); + + // Register the Image type + r = engine->RegisterObjectType("Image", sizeof(Image), asOBJ_VALUE | asOBJ_POD | asGetTypeTraits()); + assert(r >= 0); + + + // Register Image functions (example: LoadImage and UnloadImage) + r = engine->RegisterGlobalFunction("Image Load(const string &in)", asFUNCTION(AS_LoadImage), asCALL_CDECL); + assert(r >= 0); + r = engine->RegisterGlobalFunction("void Unload(Image &in)", asFUNCTION(UnloadImage), asCALL_CDECL); + assert(r >= 0); + + engine->SetDefaultNamespace(""); +} \ No newline at end of file diff --git a/src/scripting/ScriptBindings.cpp b/src/scripting/ScriptBindings.cpp index 61876f5..018c83a 100644 --- a/src/scripting/ScriptBindings.cpp +++ b/src/scripting/ScriptBindings.cpp @@ -2,6 +2,7 @@ #include "scripting/ToastBindings.h" #include "scripting/LogBindings.h" #include "scripting/DrawBindings.h" +#include "scripting/ImageBindings.h" void ScriptBindings::RegisterAll(asIScriptEngine *engine) { @@ -9,4 +10,5 @@ void ScriptBindings::RegisterAll(asIScriptEngine *engine) RegisterToastBindings(engine); RegisterLogBindings(engine); RegisterDrawBindings(engine); + RegisterImageBindings(engine); } \ No newline at end of file diff --git a/src/scripting/ScriptEngine.cpp b/src/scripting/ScriptEngine.cpp index 63d50f6..6e7f0d4 100644 --- a/src/scripting/ScriptEngine.cpp +++ b/src/scripting/ScriptEngine.cpp @@ -11,7 +11,7 @@ #include #include -ScriptEngine::ScriptEngine() : engine(nullptr), updateFunc(nullptr), drawFunc(nullptr), currentModule(nullptr), hasValidScript(false) { +ScriptEngine::ScriptEngine() : engine(nullptr), updateFunc(nullptr), drawFunc(nullptr), initFunc(nullptr), shutdownFunc(nullptr),currentModule(nullptr), hasValidScript(false) { } ScriptEngine::~ScriptEngine() { @@ -91,6 +91,9 @@ void ScriptEngine::RestoreScriptState(const std::string &state) { } void ScriptEngine::Shutdown() { + if (shutdownFunc) { + CallScriptFunction(shutdownFunc); + } ClearCachedFunctions(); if (engine) { engine->ShutDownAndRelease(); @@ -159,8 +162,10 @@ bool ScriptEngine::CompileScript(const std::string& filename) { currentModule = engine->GetModule("main"); // Cache new functions + initFunc = currentModule->GetFunctionByName("Init"); updateFunc = currentModule->GetFunctionByName("Update"); drawFunc = currentModule->GetFunctionByName("Draw"); + shutdownFunc = currentModule->GetFunctionByName("Shutdown"); hasValidScript = true; log_info("Script compiled and cached: %s", filename.c_str()); return true; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index b3d77ee..5e96c8f 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -10,6 +10,7 @@ add_executable(unit_tests ${CMAKE_SOURCE_DIR}/src/scripting/ToastBindings.cpp ${CMAKE_SOURCE_DIR}/src/scripting/LogBindings.cpp ${CMAKE_SOURCE_DIR}/src/scripting/DrawBindings.cpp + ${CMAKE_SOURCE_DIR}/src/scripting/ImageBindings.cpp ${CMAKE_SOURCE_DIR}/src/log/log.c ) From 31bc53be8d33b615d35e15cca495eaa5cdab7615 Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Mon, 17 Nov 2025 22:23:33 +1300 Subject: [PATCH 05/53] feat: added FPS display --- imgui.ini | 4 ++-- scripts/as.predefined | 1 + scripts/game.as | 1 + src/scripting/DrawBindings.cpp | 4 ++++ 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/imgui.ini b/imgui.ini index 4a5a372..055af34 100644 --- a/imgui.ini +++ b/imgui.ini @@ -21,8 +21,8 @@ Collapsed=0 DockId=0x00000002,0 [Window][##TOAST0] -Pos=1010,635 -Size=250,65 +Pos=910,635 +Size=350,65 Collapsed=0 [Window][##TOAST1] diff --git a/scripts/as.predefined b/scripts/as.predefined index d5921f1..b2d64f8 100644 --- a/scripts/as.predefined +++ b/scripts/as.predefined @@ -26,6 +26,7 @@ namespace Draw { void Circle(int centerX, int centerY, float radius, int color); void Text(const string&in text, int x, int y, int fontSize, int color); void Rectangle(int x, int y, int width, int height, int color); + void FPS(int x, int y); } namespace Image { diff --git a/scripts/game.as b/scripts/game.as index 8b3fbf4..5c115e5 100644 --- a/scripts/game.as +++ b/scripts/game.as @@ -1,6 +1,7 @@ #include "update.as" void Draw() { + Draw::FPS(10, 10); Draw::Text(format("Hello from AngelScript - at x {} and y {}", int(x), int(y)), int(x), int(y), 20, 0xFF0000FF); Draw::Rectangle(300, 200, 200, 100, 0x00FF00FF); Draw::Pixel(250, 200, 0x0000FFFF); diff --git a/src/scripting/DrawBindings.cpp b/src/scripting/DrawBindings.cpp index 1d8d105..6fc14a9 100644 --- a/src/scripting/DrawBindings.cpp +++ b/src/scripting/DrawBindings.cpp @@ -58,6 +58,10 @@ void RegisterDrawBindings(asIScriptEngine *engine) r = engine->RegisterGlobalFunction("void Text(const string &in, int, int, int, uint)", asFUNCTION(AS_DrawText), asCALL_CDECL); assert(r >= 0); + + r = engine->RegisterGlobalFunction("void FPS(int, int)", + asFUNCTION(DrawFPS), asCALL_CDECL); + assert(r >= 0); r = engine->RegisterGlobalFunction("void Rectangle(int, int, int, int, uint)", asFUNCTION(AS_DrawRectangle), asCALL_CDECL); assert(r >= 0); From f3fd90785303e85f4a01f4fac9822272dc1a90ab Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Wed, 19 Nov 2025 14:53:49 +1300 Subject: [PATCH 06/53] fix: request shutdown instead of force shutdown --- imgui.ini | 14 +++++++------- include/Application.h | 2 ++ scripts/update.as | 10 +++------- src/Application.cpp | 2 +- src/gui/GuiManager.cpp | 2 +- 5 files changed, 14 insertions(+), 16 deletions(-) diff --git a/imgui.ini b/imgui.ini index 055af34..e0f356d 100644 --- a/imgui.ini +++ b/imgui.ini @@ -9,8 +9,8 @@ Size=400,400 Collapsed=0 [Window][Game Window] -Pos=8,29 -Size=1264,513 +Pos=8,25 +Size=1264,517 Collapsed=0 DockId=0x00000001,0 @@ -21,13 +21,13 @@ Collapsed=0 DockId=0x00000002,0 [Window][##TOAST0] -Pos=910,635 -Size=350,65 +Pos=1020,643 +Size=240,57 Collapsed=0 [Window][##TOAST1] -Pos=1010,560 -Size=250,65 +Pos=1062,576 +Size=198,57 Collapsed=0 [Window][##TOAST2] @@ -36,7 +36,7 @@ Size=278,65 Collapsed=0 [Docking][Data] -DockSpace ID=0x9076BACA Window=0x34F970D7 Pos=8,29 Size=1264,683 Split=Y Selected=0x27A02DAA +DockSpace ID=0x9076BACA Window=0x34F970D7 Pos=8,25 Size=1264,687 Split=Y Selected=0x27A02DAA DockNode ID=0x00000001 Parent=0x9076BACA SizeRef=1264,513 CentralNode=1 Selected=0x27A02DAA DockNode ID=0x00000002 Parent=0x9076BACA SizeRef=1264,168 Selected=0xBEDDA0C1 diff --git a/include/Application.h b/include/Application.h index 61de32d..4ea9f3d 100644 --- a/include/Application.h +++ b/include/Application.h @@ -12,6 +12,7 @@ public: bool Initialize(int argc, char* argv[]); void Run(); void Shutdown(); + void RequestShutdown() { queueShutdown = true; } bool IsEditorEnabled() const { return enableEditor; } bool HasScriptCompilationError() const { return scriptCompilationError; } @@ -23,6 +24,7 @@ private: FILE* logFile; GuiManager guiManager; bool enableEditor; + bool queueShutdown = false; RenderTexture2D renderTexture; // renderTexture for Raylib rendering static const int WINDOW_WIDTH = 1280; diff --git a/scripts/update.as b/scripts/update.as index c310d87..eddc1d2 100644 --- a/scripts/update.as +++ b/scripts/update.as @@ -3,8 +3,7 @@ float y = 100; Image::Image img; void Init() { - Print("Initialization complete!"); - Log(LOG_INFO, "Log INFO: Initialization complete!"); + Log(LOG_TRACE, "Initialization complete!"); Toast::Success("Script initialized successfully!"); img = Image::Load("assets/raylib_96x96.png"); Toast::Info("Image loaded successfully."); @@ -12,17 +11,14 @@ void Init() { void Shutdown() { Image::Unload(img); - Print("Shutdown complete!"); - Log(LOG_INFO, "Log INFO: Shutdown complete!"); - Toast::Info("Script has been shut down."); + Log(LOG_TRACE, "Shutdown complete!"); } void Update(float dt) { x += 64 * dt; if (x > 800) { + Log(LOG_TRACE, format("Reset happened at position {}", x)); x = 0; - Print(format("X position reset! {}", x)); - Log(LOG_INFO, format("Log INFO: reset happened at position {}", x)); Toast::Info(format("X position has been reset to {}", x)); } } diff --git a/src/Application.cpp b/src/Application.cpp index a0cf996..f808d98 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -95,7 +95,7 @@ bool Application::Initialize(int argc, char *argv[]) void Application::Run() { scriptEngine.CallScriptFunction(scriptEngine.GetInitFunction()); - while (!WindowShouldClose()) + while (!WindowShouldClose() && !queueShutdown) { float deltaTime = GetFrameTime(); diff --git a/src/gui/GuiManager.cpp b/src/gui/GuiManager.cpp index 8784221..c2788db 100644 --- a/src/gui/GuiManager.cpp +++ b/src/gui/GuiManager.cpp @@ -82,7 +82,7 @@ void GuiManager::SetupDockspace(RenderTexture2D &renderTexture) { if (ImGui::MenuItem("Quit", "Ctrl + Q")) { // Handle quit here - app->Shutdown(); + app->RequestShutdown(); } ImGui::EndMenu(); } From 4a431605375df39691f0bc685b5e335a2393c9d5 Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Wed, 19 Nov 2025 15:49:03 +1300 Subject: [PATCH 07/53] feat: math and texture functions. update tests --- .gitignore | 47 ++++++++++++++++++++- CMakeLists.txt | 2 + imgui.ini | 12 +++--- include/scripting/DrawBindings.h | 1 + include/scripting/MathBindings.h | 4 ++ include/scripting/TextureBindings.h | 4 ++ scripts/as.predefined | 34 +++++++++++++++- scripts/game.as | 1 + scripts/update.as | 17 ++++++-- src/scripting/ImageBindings.cpp | 4 +- src/scripting/MathBindings.cpp | 52 ++++++++++++++++++++++++ src/scripting/ScriptBindings.cpp | 4 ++ src/scripting/TextureBindings.cpp | 39 ++++++++++++++++++ tests/CMakeLists.txt | 4 ++ tests/hot_reload.cpp | 52 ------------------------ tests/hot_reload.h | 4 +- tests/math_bindings_tests.cpp | 63 +++++++++++++++++++++++++++++ tests/math_bindings_tests.h | 3 ++ tests/script_engine_tests.cpp | 58 ++++++++++++++++++++++++++ tests/script_engine_tests.h | 4 ++ tests/test.cpp | 3 ++ 21 files changed, 342 insertions(+), 70 deletions(-) create mode 100644 include/scripting/MathBindings.h create mode 100644 include/scripting/TextureBindings.h create mode 100644 src/scripting/MathBindings.cpp create mode 100644 src/scripting/TextureBindings.cpp create mode 100644 tests/math_bindings_tests.cpp create mode 100644 tests/math_bindings_tests.h create mode 100644 tests/script_engine_tests.cpp create mode 100644 tests/script_engine_tests.h diff --git a/.gitignore b/.gitignore index 27ba0d8..6c3fdb2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,45 @@ -build/ -log.txt \ No newline at end of file +/build/ +/log.txt + +# CMake build folders +/build/ +*/CMakeFiles/ +*/CMakeCache.txt +*/Makefile +*/cmake_install.cmake +*/CPackConfig.cmake +*/CPackSourceConfig.cmake +*/CTestTestfile.cmake + +# Root-level CMake artifacts +/Makefile +/cmake_install.cmake +/CPackConfig.cmake +/CPackSourceConfig.cmake +/CTestTestfile.cmake +/cmake/ + +# Intermediate objects, libraries, executables +*.o +*.obj +*.lo +*.a +*.la +*.so +*.dylib +*.dll +*.exe +*.out +*.pdb +*.mod +*.dir/ + +# Optional: extra CMake junk in source tree +CMakeScripts/ +CMakeFiles/ +CMakeCache.txt +Testing/ + +# Editor state files +.ned-agent-history.json +.undo-redo-ned.json \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 33a8298..79f42d4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -80,6 +80,8 @@ add_executable(simian src/scripting/LogBindings.cpp src/scripting/DrawBindings.cpp src/scripting/ImageBindings.cpp + src/scripting/TextureBindings.cpp + src/scripting/MathBindings.cpp src/HotReload.cpp src/gui/GuiManager.cpp src/gui/LogWindow.cpp diff --git a/imgui.ini b/imgui.ini index e0f356d..cd9473b 100644 --- a/imgui.ini +++ b/imgui.ini @@ -21,18 +21,18 @@ Collapsed=0 DockId=0x00000002,0 [Window][##TOAST0] -Pos=1020,643 -Size=240,57 +Pos=984,643 +Size=276,57 Collapsed=0 [Window][##TOAST1] -Pos=1062,576 -Size=198,57 +Pos=1048,576 +Size=212,57 Collapsed=0 [Window][##TOAST2] -Pos=982,485 -Size=278,65 +Pos=1048,509 +Size=212,57 Collapsed=0 [Docking][Data] diff --git a/include/scripting/DrawBindings.h b/include/scripting/DrawBindings.h index 51a4879..6482130 100644 --- a/include/scripting/DrawBindings.h +++ b/include/scripting/DrawBindings.h @@ -2,3 +2,4 @@ #include void RegisterDrawBindings(asIScriptEngine *engine); + diff --git a/include/scripting/MathBindings.h b/include/scripting/MathBindings.h new file mode 100644 index 0000000..d7a809f --- /dev/null +++ b/include/scripting/MathBindings.h @@ -0,0 +1,4 @@ +#pragma once +#include + +void RegisterMathBindings(asIScriptEngine *engine); \ No newline at end of file diff --git a/include/scripting/TextureBindings.h b/include/scripting/TextureBindings.h new file mode 100644 index 0000000..77ba37d --- /dev/null +++ b/include/scripting/TextureBindings.h @@ -0,0 +1,4 @@ +#pragma once +#include + +void RegisterTextureBindings(asIScriptEngine *engine); diff --git a/scripts/as.predefined b/scripts/as.predefined index b2d64f8..18beee9 100644 --- a/scripts/as.predefined +++ b/scripts/as.predefined @@ -29,13 +29,43 @@ namespace Draw { void FPS(int x, int y); } -namespace Image { +namespace Texture { class Image { int width; int height; int mipmaps; int format; }; - Image@ Load(const string&in path); + Image@ LoadImage(const string&in path); void Unload(const Image@&in image); + class Texture2D { + int id; + int width; + int height; + int mipmaps; + int format; + }; + Texture2D@ LoadTexture(const string&in path); + Texture2D@ LoadFromImage(const Image@&in image); + void Draw(const Texture2D@&in texture, int x, int y, int color); + void Unload(const Texture2D@&in texture); } + +namespace Math { + float Sin(float angle); + float Cos(float angle); + float Tan(float angle); + float ASin(float value); + float ACos(float value); + float ATan(float value); + float ATan2(float y, float x); + float Sqrt(float value); + float Pow(float base, float exponent); + float Log(float value); + float Log10(float value); + float Exp(float exponent); + float Floor(float value); + float Ceil(float value); + float Modf(float x, float y); + float Abs(float value); +} \ No newline at end of file diff --git a/scripts/game.as b/scripts/game.as index 5c115e5..5dfa215 100644 --- a/scripts/game.as +++ b/scripts/game.as @@ -7,4 +7,5 @@ void Draw() { Draw::Pixel(250, 200, 0x0000FFFF); Draw::Line(int(x), int(y), 400, 300, 0xFFFF00FF); Draw::Circle(600, 400, 50.0f, 0xFF00FFFF); + Texture::Draw(tex, int(ix), int(iy), 0xFFFFFFFF); } \ No newline at end of file diff --git a/scripts/update.as b/scripts/update.as index eddc1d2..159db1c 100644 --- a/scripts/update.as +++ b/scripts/update.as @@ -1,21 +1,32 @@ float x = 50; float y = 100; -Image::Image img; +float r = 100.0f; +float theta = 0.0f; +float ix = 0.0f; +float iy = 0.0f; +Texture::Image img; +Texture::Texture2D tex; void Init() { Log(LOG_TRACE, "Initialization complete!"); Toast::Success("Script initialized successfully!"); - img = Image::Load("assets/raylib_96x96.png"); + img = Texture::LoadImage("assets/raylib_96x96.png"); Toast::Info("Image loaded successfully."); + tex = Texture::LoadTexture("assets/raylib_96x96.png"); + Toast::Info("Texture loaded successfully."); } void Shutdown() { - Image::Unload(img); + Texture::Unload(img); + Texture::Unload(tex); Log(LOG_TRACE, "Shutdown complete!"); } void Update(float dt) { x += 64 * dt; + theta += 1.0f * dt; + ix = 100+ r * Math::Cos(theta); + iy = 100+r * Math::Sin(theta); if (x > 800) { Log(LOG_TRACE, format("Reset happened at position {}", x)); x = 0; diff --git a/src/scripting/ImageBindings.cpp b/src/scripting/ImageBindings.cpp index e12bd41..01a8451 100644 --- a/src/scripting/ImageBindings.cpp +++ b/src/scripting/ImageBindings.cpp @@ -12,7 +12,7 @@ void RegisterImageBindings(asIScriptEngine *engine) { int r; - engine->SetDefaultNamespace("Image"); + engine->SetDefaultNamespace("Texture"); // Register the Image type r = engine->RegisterObjectType("Image", sizeof(Image), asOBJ_VALUE | asOBJ_POD | asGetTypeTraits()); @@ -20,7 +20,7 @@ void RegisterImageBindings(asIScriptEngine *engine) // Register Image functions (example: LoadImage and UnloadImage) - r = engine->RegisterGlobalFunction("Image Load(const string &in)", asFUNCTION(AS_LoadImage), asCALL_CDECL); + r = engine->RegisterGlobalFunction("Image LoadImage(const string &in)", asFUNCTION(AS_LoadImage), asCALL_CDECL); assert(r >= 0); r = engine->RegisterGlobalFunction("void Unload(Image &in)", asFUNCTION(UnloadImage), asCALL_CDECL); assert(r >= 0); diff --git a/src/scripting/MathBindings.cpp b/src/scripting/MathBindings.cpp new file mode 100644 index 0000000..1657399 --- /dev/null +++ b/src/scripting/MathBindings.cpp @@ -0,0 +1,52 @@ +#include "scripting/MathBindings.h" +#include +#include + +void RegisterMathBindings(asIScriptEngine *engine) +{ + int r; + + engine->SetDefaultNamespace("Math"); + + r = engine->RegisterGlobalFunction("float Cos(float)", asFUNCTION(cosf), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("float Sin(float)", asFUNCTION(sinf), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("float Tan(float)", asFUNCTION(tanf), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("float Acos(float)", asFUNCTION(acosf), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("float Asin(float)", asFUNCTION(asinf), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("float Atan(float)", asFUNCTION(atanf), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("float Sqrt(float)", asFUNCTION(sqrtf), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("float Pow(float, float)", asFUNCTION(powf), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("float Abs(float)", asFUNCTION(fabsf), asCALL_CDECL); + assert(r >= 0); + r = engine->RegisterGlobalFunction("float Log(float)", asFUNCTION(logf), asCALL_CDECL); + assert(r >= 0); + r = engine->RegisterGlobalFunction("float Log10(float)", asFUNCTION(log10f), asCALL_CDECL); + assert(r >= 0); + r = engine->RegisterGlobalFunction("float Exp(float)", asFUNCTION(expf), asCALL_CDECL); + assert(r >= 0); + r = engine->RegisterGlobalFunction("float Floor(float)", asFUNCTION(floorf), asCALL_CDECL); + assert(r >= 0); + r = engine->RegisterGlobalFunction("float Ceil(float)", asFUNCTION(ceilf), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("float Mod(float, float)", asFUNCTION(fmodf), asCALL_CDECL); + assert(r >= 0); + + engine->SetDefaultNamespace(""); +} \ No newline at end of file diff --git a/src/scripting/ScriptBindings.cpp b/src/scripting/ScriptBindings.cpp index 018c83a..d61fa91 100644 --- a/src/scripting/ScriptBindings.cpp +++ b/src/scripting/ScriptBindings.cpp @@ -3,6 +3,8 @@ #include "scripting/LogBindings.h" #include "scripting/DrawBindings.h" #include "scripting/ImageBindings.h" +#include "scripting/TextureBindings.h" +#include "scripting/MathBindings.h" void ScriptBindings::RegisterAll(asIScriptEngine *engine) { @@ -11,4 +13,6 @@ void ScriptBindings::RegisterAll(asIScriptEngine *engine) RegisterLogBindings(engine); RegisterDrawBindings(engine); RegisterImageBindings(engine); + RegisterTextureBindings(engine); + RegisterMathBindings(engine); } \ No newline at end of file diff --git a/src/scripting/TextureBindings.cpp b/src/scripting/TextureBindings.cpp new file mode 100644 index 0000000..48f6b0e --- /dev/null +++ b/src/scripting/TextureBindings.cpp @@ -0,0 +1,39 @@ +#include "scripting/TextureBindings.h" +#include +#include +#include + +Color ColorFromUInt(unsigned int c); + +Texture2D AS_LoadTexture(const std::string &filename) +{ + return LoadTexture(filename.c_str()); +} + +void AS_DrawTexture(const Texture2D &texture, float x, float y, int tint) +{ + DrawTexture(texture, static_cast(x), static_cast(y), ColorFromUInt(tint)); +} + +void RegisterTextureBindings(asIScriptEngine *engine) +{ + int r; + + engine->SetDefaultNamespace("Texture"); + + // Register the Texture2D type + r = engine->RegisterObjectType("Texture2D", sizeof(Texture2D), asOBJ_VALUE | asOBJ_POD | asGetTypeTraits()); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("Texture2D LoadTexture(const string &in)", asFUNCTION(AS_LoadTexture), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void Unload(Texture2D &in)", asFUNCTION(UnloadTexture), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("Texture2D LoadFromImage(const Image &in)", asFUNCTION(LoadTextureFromImage), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void Draw(const Texture2D &in, float x, float y, int tint)", asFUNCTION(AS_DrawTexture), asCALL_CDECL); + assert(r >= 0); +} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 5e96c8f..155b313 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -4,6 +4,8 @@ cmake_minimum_required(VERSION 3.16) add_executable(unit_tests test.cpp hot_reload.cpp + script_engine_tests.cpp + math_bindings_tests.cpp ${CMAKE_SOURCE_DIR}/src/HotReload.cpp ${CMAKE_SOURCE_DIR}/src/scripting/ScriptEngine.cpp ${CMAKE_SOURCE_DIR}/src/scripting/ScriptBindings.cpp @@ -11,6 +13,8 @@ add_executable(unit_tests ${CMAKE_SOURCE_DIR}/src/scripting/LogBindings.cpp ${CMAKE_SOURCE_DIR}/src/scripting/DrawBindings.cpp ${CMAKE_SOURCE_DIR}/src/scripting/ImageBindings.cpp + ${CMAKE_SOURCE_DIR}/src/scripting/TextureBindings.cpp + ${CMAKE_SOURCE_DIR}/src/scripting/MathBindings.cpp ${CMAKE_SOURCE_DIR}/src/log/log.c ) diff --git a/tests/hot_reload.cpp b/tests/hot_reload.cpp index 13baa98..b4eb150 100644 --- a/tests/hot_reload.cpp +++ b/tests/hot_reload.cpp @@ -6,7 +6,6 @@ #include #include #include "../include/HotReload.h" -#include "../include/scripting/ScriptEngine.h" using namespace std::chrono_literals; @@ -33,55 +32,4 @@ void test_hotreload_directory_watch(void) { std::filesystem::remove(tmpDir); } -void test_scriptengine_compile_and_call(void) { - // Create a simple script file that defines Update(float) and a global - std::filesystem::path tmpDir = std::filesystem::current_path() / "tmp_script"; - std::filesystem::create_directories(tmpDir); - std::filesystem::path script = tmpDir / "simple.as"; - std::ofstream ofs(script); - ofs << "float g_x = 0;\n"; - ofs << "void Update(float dt) { g_x += dt * 10.0f; }\n"; - ofs.close(); - - ScriptEngine se; - TEST_CHECK(se.Initialize() == true); - bool ok = se.CompileScript(script.string()); - TEST_CHECK(ok == true); - asIScriptFunction* upd = se.GetUpdateFunction(); - TEST_CHECK(upd != nullptr); - - // Call Update with dt=0.1 - se.CallScriptFunction(upd, 0.1f); - - se.Shutdown(); - - std::filesystem::remove(script); - std::filesystem::remove(tmpDir); -} - -void test_scriptengine_include(void) { - std::filesystem::path tmpDir = std::filesystem::current_path() / "tmp_include"; - std::filesystem::create_directories(tmpDir); - std::filesystem::path inc = tmpDir / "inc.as"; - std::ofstream ofsinc(inc); - ofsinc << "void Included() { Print(\"Included called\"); }\n"; - ofsinc.close(); - - std::filesystem::path main = tmpDir / "main.as"; - std::ofstream ofsmain(main); - ofsmain << "#include \"inc.as\"\n"; - ofsmain << "void Update(float dt) { Included(); }\n"; - ofsmain.close(); - - ScriptEngine se; - TEST_CHECK(se.Initialize() == true); - // Compile should succeed and include callback should resolve inc.as - bool ok = se.CompileScript(main.string()); - TEST_CHECK(ok == true); - se.Shutdown(); - - std::filesystem::remove(inc); - std::filesystem::remove(main); - std::filesystem::remove(tmpDir); -} diff --git a/tests/hot_reload.h b/tests/hot_reload.h index 7ca749c..1feedfd 100644 --- a/tests/hot_reload.h +++ b/tests/hot_reload.h @@ -1,5 +1,3 @@ #pragma once -void test_hotreload_directory_watch(void); -void test_scriptengine_compile_and_call(void); -void test_scriptengine_include(void); \ No newline at end of file +void test_hotreload_directory_watch(void); \ No newline at end of file diff --git a/tests/math_bindings_tests.cpp b/tests/math_bindings_tests.cpp new file mode 100644 index 0000000..5f4b55b --- /dev/null +++ b/tests/math_bindings_tests.cpp @@ -0,0 +1,63 @@ +#define TEST_NO_MAIN +#include "acutest.h" +#include +#include +#include +#include "../include/scripting/ScriptEngine.h" + +void test_math_bindings(void) { + std::filesystem::path tmpDir = std::filesystem::current_path() / "tmp_math"; + std::filesystem::create_directories(tmpDir); + std::filesystem::path scriptPath = tmpDir / "math_test.as"; + + { + std::ofstream script(scriptPath); + script << "float testSin = Math::Sin(1.57079632679f);\n"; + script << "float testCos = Math::Cos(0.0f);\n"; + script << "float testTan = Math::Tan(0.78539816339f);\n"; + script << "float testSqrt = Math::Sqrt(25.0f);\n"; + script << "float testPow = Math::Pow(2.0f, 8.0f);\n"; + script << "float testAbs = Math::Abs(-42.5f);\n"; + } + + ScriptEngine se; + TEST_CHECK(se.Initialize() == true); + bool compiled = se.CompileScript(scriptPath.string()); + TEST_CHECK(compiled == true); + + asIScriptEngine* engine = se.GetEngine(); + TEST_CHECK(engine != nullptr); + asIScriptModule* module = engine ? engine->GetModule("main") : nullptr; + TEST_CHECK(module != nullptr); + + auto fetchValue = [module](const char* name) -> float { + int idx = module->GetGlobalVarIndexByName(name); + TEST_CHECK_(idx >= 0, "Global '%s' not found", name); + if (idx < 0) + return 0.0f; + void* address = module->GetAddressOfGlobalVar(idx); + TEST_CHECK_(address != nullptr, "Global '%s' address null", name); + if (!address) + return 0.0f; + return *static_cast(address); + }; + + const float sinVal = fetchValue("testSin"); + const float cosVal = fetchValue("testCos"); + const float tanVal = fetchValue("testTan"); + const float sqrtVal = fetchValue("testSqrt"); + const float powVal = fetchValue("testPow"); + const float absVal = fetchValue("testAbs"); + + TEST_CHECK(std::fabs(sinVal - 1.0f) < 1e-4f); + TEST_CHECK(std::fabs(cosVal - 1.0f) < 1e-4f); + TEST_CHECK(std::fabs(tanVal - 1.0f) < 1e-3f); + TEST_CHECK(std::fabs(sqrtVal - 5.0f) < 1e-4f); + TEST_CHECK(std::fabs(powVal - 256.0f) < 1e-3f); + TEST_CHECK(std::fabs(absVal - 42.5f) < 1e-4f); + + se.Shutdown(); + + std::filesystem::remove(scriptPath); + std::filesystem::remove(tmpDir); +} diff --git a/tests/math_bindings_tests.h b/tests/math_bindings_tests.h new file mode 100644 index 0000000..c8d1b08 --- /dev/null +++ b/tests/math_bindings_tests.h @@ -0,0 +1,3 @@ +#pragma once + +void test_math_bindings(void); diff --git a/tests/script_engine_tests.cpp b/tests/script_engine_tests.cpp new file mode 100644 index 0000000..207822f --- /dev/null +++ b/tests/script_engine_tests.cpp @@ -0,0 +1,58 @@ +#define TEST_NO_MAIN +#include "acutest.h" +#include +#include +#include "../include/scripting/ScriptEngine.h" + +void test_scriptengine_compile_and_call(void) { + std::filesystem::path tmpDir = std::filesystem::current_path() / "tmp_script"; + std::filesystem::create_directories(tmpDir); + std::filesystem::path script = tmpDir / "simple.as"; + { + std::ofstream ofs(script); + ofs << "float g_x = 0;\n"; + ofs << "void Update(float dt) { g_x += dt * 10.0f; }\n"; + } + + ScriptEngine se; + TEST_CHECK(se.Initialize() == true); + bool ok = se.CompileScript(script.string()); + TEST_CHECK(ok == true); + asIScriptFunction* upd = se.GetUpdateFunction(); + TEST_CHECK(upd != nullptr); + + se.CallScriptFunction(upd, 0.1f); + + se.Shutdown(); + + std::filesystem::remove(script); + std::filesystem::remove(tmpDir); +} + +void test_scriptengine_include(void) { + std::filesystem::path tmpDir = std::filesystem::current_path() / "tmp_include"; + std::filesystem::create_directories(tmpDir); + + std::filesystem::path inc = tmpDir / "inc.as"; + { + std::ofstream ofsinc(inc); + ofsinc << "void Included() { Print(\"Included called\"); }\n"; + } + + std::filesystem::path main = tmpDir / "main.as"; + { + std::ofstream ofsmain(main); + ofsmain << "#include \"inc.as\"\n"; + ofsmain << "void Update(float dt) { Included(); }\n"; + } + + ScriptEngine se; + TEST_CHECK(se.Initialize() == true); + bool ok = se.CompileScript(main.string()); + TEST_CHECK(ok == true); + se.Shutdown(); + + std::filesystem::remove(inc); + std::filesystem::remove(main); + std::filesystem::remove(tmpDir); +} diff --git a/tests/script_engine_tests.h b/tests/script_engine_tests.h new file mode 100644 index 0000000..641f395 --- /dev/null +++ b/tests/script_engine_tests.h @@ -0,0 +1,4 @@ +#pragma once + +void test_scriptengine_compile_and_call(void); +void test_scriptengine_include(void); diff --git a/tests/test.cpp b/tests/test.cpp index a93dc03..a2cbc99 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -1,8 +1,11 @@ #include "acutest.h" #include "hot_reload.h" +#include "script_engine_tests.h" +#include "math_bindings_tests.h" TEST_LIST = { { "hotreload_dir", test_hotreload_directory_watch }, { "script_compile", test_scriptengine_compile_and_call }, { "script_include", test_scriptengine_include }, + { "math_bindings", test_math_bindings }, { NULL, NULL } }; From 4f6efceb986ee18a3657c7de4d065512f5612e5b Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Fri, 21 Nov 2025 10:11:53 +1300 Subject: [PATCH 08/53] feat: re-init on hot reload. --- imgui.ini | 16 +++++++++++++--- scripts/update.as | 4 ++-- src/Application.cpp | 6 +++--- src/HotReload.cpp | 2 +- src/log/log.h | 2 +- src/scripting/ScriptEngine.cpp | 18 +++++++++--------- 6 files changed, 29 insertions(+), 19 deletions(-) diff --git a/imgui.ini b/imgui.ini index cd9473b..d23f659 100644 --- a/imgui.ini +++ b/imgui.ini @@ -21,8 +21,8 @@ Collapsed=0 DockId=0x00000002,0 [Window][##TOAST0] -Pos=984,643 -Size=276,57 +Pos=1062,643 +Size=198,57 Collapsed=0 [Window][##TOAST1] @@ -31,7 +31,17 @@ Size=212,57 Collapsed=0 [Window][##TOAST2] -Pos=1048,509 +Pos=1062,509 +Size=198,57 +Collapsed=0 + +[Window][##TOAST3] +Pos=1048,442 +Size=212,57 +Collapsed=0 + +[Window][##TOAST4] +Pos=1048,375 Size=212,57 Collapsed=0 diff --git a/scripts/update.as b/scripts/update.as index 159db1c..b96e620 100644 --- a/scripts/update.as +++ b/scripts/update.as @@ -1,6 +1,6 @@ float x = 50; float y = 100; -float r = 100.0f; +float r = 40.0f; float theta = 0.0f; float ix = 0.0f; float iy = 0.0f; @@ -24,7 +24,7 @@ void Shutdown() { void Update(float dt) { x += 64 * dt; - theta += 1.0f * dt; + theta += 2.0f * dt; ix = 100+ r * Math::Cos(theta); iy = 100+r * Math::Sin(theta); if (x > 800) { diff --git a/src/Application.cpp b/src/Application.cpp index f808d98..8ab04be 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -8,8 +8,6 @@ #include "rlImGui.h" #include "imgui.h" -#include "extras/IconsFontAwesome6.h" -#include "gui/ImGuiNotify.hpp" #include "gui/GuiManager.h" #include "gui/Toast.h" @@ -120,6 +118,8 @@ void Application::Update(float deltaTime) Toast::Warning("Script compilation failed - check console for details."); } else { Toast::Success("Script reloaded successfully."); + //Should call init function again or things don't work + scriptEngine.CallScriptFunction(scriptEngine.GetInitFunction()); } } @@ -207,4 +207,4 @@ void Application::Shutdown() fclose(logFile); logFile = nullptr; } -} \ No newline at end of file +} diff --git a/src/HotReload.cpp b/src/HotReload.cpp index ca96ae9..ebc44b5 100644 --- a/src/HotReload.cpp +++ b/src/HotReload.cpp @@ -53,4 +53,4 @@ std::time_t HotReload::GetLatestWriteTimeInPath() { // fall through } return 0; -} \ No newline at end of file +} diff --git a/src/log/log.h b/src/log/log.h index b02be28..d0f134e 100644 --- a/src/log/log.h +++ b/src/log/log.h @@ -58,4 +58,4 @@ void raylib_log(int msgType, const char *text, va_list args); } #endif -#endif \ No newline at end of file +#endif diff --git a/src/scripting/ScriptEngine.cpp b/src/scripting/ScriptEngine.cpp index 6e7f0d4..c64195b 100644 --- a/src/scripting/ScriptEngine.cpp +++ b/src/scripting/ScriptEngine.cpp @@ -109,7 +109,7 @@ bool ScriptEngine::CompileScript(const std::string& filename) { // Try to compile in a temporary module first using CScriptBuilder CScriptBuilder tempBuilder; tempBuilder.SetIncludeCallback(IncludeCallback, nullptr); - + int r = tempBuilder.StartNewModule(engine, "temp"); if (r < 0) { log_error("Failed to start new temp module"); @@ -135,11 +135,11 @@ bool ScriptEngine::CompileScript(const std::string& filename) { if (currentModule) { engine->DiscardModule("main"); } - + // Create new main module with the working code using CScriptBuilder CScriptBuilder mainBuilder; mainBuilder.SetIncludeCallback(IncludeCallback, nullptr); - + r = mainBuilder.StartNewModule(engine, "main"); if (r >= 0) { r = mainBuilder.AddSectionFromFile(filename.c_str()); @@ -147,10 +147,10 @@ bool ScriptEngine::CompileScript(const std::string& filename) { if (r >= 0) { r = mainBuilder.BuildModule(); } - + // Clean up temp module engine->DiscardModule("temp"); - + if (r < 0) { // This shouldn't happen since we already tested compilation log_error("Unexpected error when creating main module"); @@ -160,7 +160,7 @@ bool ScriptEngine::CompileScript(const std::string& filename) { // Get the newly created module currentModule = engine->GetModule("main"); - + // Cache new functions initFunc = currentModule->GetFunctionByName("Init"); updateFunc = currentModule->GetFunctionByName("Update"); @@ -231,10 +231,10 @@ int ScriptEngine::IncludeCallback(const char* include, const char* from, CScript fromFile = lastSep + 1; } } - + // Log the include request with clean filenames log_info("Including: %s (from: %s)", include, fromFile ? fromFile : "main"); - + // Build the full path candidates: relative to 'from' and any include paths std::vector candidates; @@ -273,4 +273,4 @@ std::string ScriptEngine::ReadFile(const std::string& filename) { std::stringstream ss; ss << file.rdbuf(); return ss.str(); -} \ No newline at end of file +} From c48acecd7cab6d56da1d03dcf5c1a6d759d8cd71 Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Fri, 21 Nov 2025 11:16:14 +1300 Subject: [PATCH 09/53] feat: add some more theme elements --- imgui.ini | 4 ++-- src/gui/GuiManager.cpp | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/imgui.ini b/imgui.ini index d23f659..bcf75aa 100644 --- a/imgui.ini +++ b/imgui.ini @@ -31,8 +31,8 @@ Size=212,57 Collapsed=0 [Window][##TOAST2] -Pos=1062,509 -Size=198,57 +Pos=1048,509 +Size=212,57 Collapsed=0 [Window][##TOAST3] diff --git a/src/gui/GuiManager.cpp b/src/gui/GuiManager.cpp index c2788db..da7152d 100644 --- a/src/gui/GuiManager.cpp +++ b/src/gui/GuiManager.cpp @@ -80,7 +80,8 @@ void GuiManager::SetupDockspace(RenderTexture2D &renderTexture) { if (ImGui::BeginMenu("Game")) { - if (ImGui::MenuItem("Quit", "Ctrl + Q")) { + if (ImGui::MenuItem("Quit", "Ctrl + Q")) + { // Handle quit here app->RequestShutdown(); } @@ -141,7 +142,6 @@ void GuiManager::RenderNotifications() ImGui::PopStyleVar(2); ImGui::PopStyleColor(1); } - void GuiManager::SetTheme() { @@ -184,8 +184,8 @@ void GuiManager::SetTheme() colors[ImGuiCol_TabActive] = ImVec4(0.20f, 0.20f, 0.20f, 0.36f); colors[ImGuiCol_TabUnfocused] = ImVec4(0.00f, 0.00f, 0.00f, 0.52f); colors[ImGuiCol_TabUnfocusedActive] = ImVec4(0.14f, 0.14f, 0.14f, 1.00f); - // colors[ImGuiCol_DockingPreview] = ImVec4(0.33f, 0.67f, 0.86f, 1.00f); - // colors[ImGuiCol_DockingEmptyBg] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); + colors[ImGuiCol_DockingPreview] = ImVec4(0.33f, 0.67f, 0.86f, 1.00f); + colors[ImGuiCol_DockingEmptyBg] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); colors[ImGuiCol_PlotLines] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); colors[ImGuiCol_PlotHistogram] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); From 72f5648aac8b0df2dd219ee0d78c54875c953542 Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Fri, 21 Nov 2025 11:58:11 +1300 Subject: [PATCH 10/53] feat: add nicer GUI fonts --- .../Application.cpp.8776A52D61132E96.idx | Bin 0 -> 4346 bytes .../index/Application.h.858A603E426F648A.idx | Bin 0 -> 1898 bytes .../DrawBindings.cpp.D3B812DF8CB26330.idx | Bin 0 -> 2058 bytes .../index/DrawBindings.h.CC7314AB1A121981.idx | Bin 0 -> 328 bytes ...A6FreeSolidFontData.h.FC535BAFFB56AA07.idx | Bin 0 -> 396 bytes .../index/GuiManager.cpp.673B708E1204267E.idx | Bin 0 -> 7990 bytes .../index/GuiManager.h.BF6B9FB11B7598EE.idx | Bin 0 -> 1230 bytes .../index/HotReload.cpp.F47033D97042FC77.idx | Bin 0 -> 2104 bytes .../index/HotReload.h.E78A1E604B731DD0.idx | Bin 0 -> 784 bytes .../IconsFontAwesome6.h.4F690858433DCB54.idx | Bin 0 -> 34674 bytes .../ImGuiNotify.hpp.EE306DC3E81DBD8B.idx | Bin 0 -> 10922 bytes .../ImageBindings.cpp.106301A4847C5051.idx | Bin 0 -> 1266 bytes .../ImageBindings.h.67795D26AAFCD1E4.idx | Bin 0 -> 328 bytes .../LogBindings.cpp.F216E8762748E2D1.idx | Bin 0 -> 2692 bytes .../index/LogBindings.h.03A2A0BF520F958E.idx | Bin 0 -> 336 bytes .../index/LogWindow.cpp.EAFA4FFD61920E45.idx | Bin 0 -> 1840 bytes .../index/LogWindow.h.739C84098534FA87.idx | Bin 0 -> 848 bytes .../MathBindings.cpp.A3EA272C10D858CA.idx | Bin 0 -> 2180 bytes .../index/MathBindings.h.4EB245298CE82877.idx | Bin 0 -> 328 bytes .../ScriptBindings.cpp.E23B554865E2DC43.idx | Bin 0 -> 886 bytes .../ScriptBindings.h.1767B8F57F307012.idx | Bin 0 -> 620 bytes .../ScriptEngine.cpp.7ACDEA59EB4DE303.idx | Bin 0 -> 6452 bytes .../index/ScriptEngine.h.E0931BF4ECAC1BB0.idx | Bin 0 -> 2434 bytes .../TextureBindings.cpp.ED92828A1ED5C540.idx | Bin 0 -> 1632 bytes .../TextureBindings.h.4E98F904F8826D78.idx | Bin 0 -> 336 bytes .../clangd/index/Toast.h.7992F998C96CE2CA.idx | Bin 0 -> 1536 bytes .../ToastBindings.cpp.02CE1E8043BDE66D.idx | Bin 0 -> 1658 bytes .../ToastBindings.h.61AE191277D79513.idx | Bin 0 -> 328 bytes .../index/acutest.h.0D2F8C30EC1B66E0.idx | Bin 0 -> 1706 bytes .../index/angelscript.h.AC475AED505975DD.idx | Bin 0 -> 88740 bytes .../index/as_array.h.B06B657A6FAA5011.idx | Bin 0 -> 7174 bytes .../index/as_atomic.cpp.D441A68A9330007D.idx | Bin 0 -> 1572 bytes .../index/as_atomic.h.98FF439E721B3419.idx | Bin 0 -> 792 bytes .../index/as_builder.cpp.5B991AB7F848169A.idx | Bin 0 -> 130256 bytes .../index/as_builder.h.00D1D5DB84CC6772.idx | Bin 0 -> 16652 bytes .../as_bytecode.cpp.71E2F83E289CB227.idx | Bin 0 -> 57550 bytes .../index/as_bytecode.h.CA7F431C9B25F8E1.idx | Bin 0 -> 8278 bytes .../as_callfunc.cpp.C0CF031BC9B3F5F4.idx | Bin 0 -> 11706 bytes .../index/as_callfunc.h.B7EBA57BCC1841B1.idx | Bin 0 -> 5008 bytes .../as_callfunc_mips.cpp.F43F7C77711AC923.idx | Bin 0 -> 400 bytes ..._callfunc_x64_gcc.cpp.2B9B6E753A40B5C5.idx | Bin 0 -> 4062 bytes ...allfunc_x64_mingw.cpp.02C3DF7B496086F1.idx | Bin 0 -> 430 bytes ...callfunc_x64_msvc.cpp.1A0494FBF3190501.idx | Bin 0 -> 430 bytes .../as_callfunc_x86.cpp.A0DEAD74858CF856.idx | Bin 0 -> 402 bytes .../as_compiler.cpp.FB22BDBD390751F2.idx | Bin 0 -> 392708 bytes .../index/as_compiler.h.113AEE4326224489.idx | Bin 0 -> 31558 bytes .../index/as_config.h.0D6663DCAC5041EA.idx | Bin 0 -> 1278 bytes .../as_configgroup.cpp.1978D5FE841E12B2.idx | Bin 0 -> 5002 bytes .../as_configgroup.h.47769F873BE0B41A.idx | Bin 0 -> 1762 bytes .../index/as_context.cpp.E3B08CC2931C1E25.idx | Bin 0 -> 102884 bytes .../index/as_context.h.47F3D2D0DA8CC748.idx | Bin 0 -> 13512 bytes .../as_criticalsection.h.130F097169824D1C.idx | Bin 0 -> 1670 bytes .../as_datatype.cpp.E0A62FE00E11D0A1.idx | Bin 0 -> 13664 bytes .../index/as_datatype.h.31D59544BB09D8E7.idx | Bin 0 -> 5650 bytes .../index/as_debug.h.527CACBD7491503F.idx | Bin 0 -> 236 bytes .../index/as_gc.cpp.AC20E1A61B2CBCFB.idx | Bin 0 -> 14920 bytes .../clangd/index/as_gc.h.99128ED2E571142C.idx | Bin 0 -> 5554 bytes .../index/as_generic.cpp.C80CCE51026AAE64.idx | Bin 0 -> 13658 bytes .../index/as_generic.h.53B17A96528B62ED.idx | Bin 0 -> 5052 bytes ...as_globalproperty.cpp.E4E70F1E3BDD257D.idx | Bin 0 -> 2400 bytes .../index/as_map.h.A3AD2B90FEEB726F.idx | Bin 0 -> 12744 bytes .../index/as_memory.cpp.552DF5AD14ECC4B5.idx | Bin 0 -> 3236 bytes .../index/as_memory.h.C6EFA7F35F05C98D.idx | Bin 0 -> 1454 bytes .../index/as_module.cpp.0B1C5EFB053A59F6.idx | Bin 0 -> 32476 bytes .../index/as_module.h.D7D335828B947862.idx | Bin 0 -> 10070 bytes .../index/as_namespace.h.F7B71193DB11DB1A.idx | Bin 0 -> 1336 bytes .../as_objecttype.cpp.F06C6FB1C9AED6FA.idx | Bin 0 -> 14898 bytes .../as_objecttype.h.785FD4622CEC3E36.idx | Bin 0 -> 5812 bytes .../as_outputbuffer.cpp.B6366FB27E3B19A7.idx | Bin 0 -> 2232 bytes .../as_outputbuffer.h.ACD41D21BD4DC007.idx | Bin 0 -> 1398 bytes .../index/as_parser.cpp.BD2BBF497B7C08D9.idx | Bin 0 -> 72676 bytes .../index/as_parser.h.835A6072918E81C2.idx | Bin 0 -> 9106 bytes .../index/as_property.h.B4B9AAB7616A0D6B.idx | Bin 0 -> 3702 bytes .../index/as_restore.cpp.914EC6C72AA277A3.idx | Bin 0 -> 97400 bytes .../index/as_restore.h.C7B523ACCDD6860D.idx | Bin 0 -> 11704 bytes .../as_scriptcode.cpp.785735990E5C292F.idx | Bin 0 -> 1992 bytes .../as_scriptcode.h.A66639055A43BA36.idx | Bin 0 -> 1282 bytes .../as_scriptengine.cpp.811C05404051D15E.idx | Bin 0 -> 129850 bytes .../as_scriptengine.h.04C2C814432DD8AF.idx | Bin 0 -> 29368 bytes ...as_scriptfunction.cpp.F9B4DD1EC0FC8DDF.idx | Bin 0 -> 40308 bytes .../as_scriptfunction.h.98772B58CB0B667F.idx | Bin 0 -> 17836 bytes .../as_scriptnode.cpp.FE66C402D41629AC.idx | Bin 0 -> 2644 bytes .../as_scriptnode.h.46E65245C1B8E45F.idx | Bin 0 -> 5056 bytes .../as_scriptobject.cpp.74A647D3C5D1F2CA.idx | Bin 0 -> 19206 bytes .../as_scriptobject.h.9025F12F2C738108.idx | Bin 0 -> 5262 bytes .../index/as_string.cpp.5255D8D36DAECD5C.idx | Bin 0 -> 8526 bytes .../index/as_string.h.D36854A487979607.idx | Bin 0 -> 4404 bytes .../as_string_util.cpp.ED3BDC32F8DD540E.idx | Bin 0 -> 1790 bytes .../as_string_util.h.9A317F1475C17B9C.idx | Bin 0 -> 942 bytes .../as_symboltable.h.C39A118BD2A60C0C.idx | Bin 0 -> 10144 bytes .../index/as_texts.h.A2EC1EC85F68DC9C.idx | Bin 0 -> 8440 bytes .../index/as_thread.cpp.16533C75DDD387A2.idx | Bin 0 -> 5794 bytes .../index/as_thread.h.6E3159A81260B7DC.idx | Bin 0 -> 1666 bytes .../index/as_tokendef.h.DA624DCE97276FDA.idx | Bin 0 -> 13164 bytes .../as_tokenizer.cpp.061A182A21E94D51.idx | Bin 0 -> 4426 bytes .../index/as_tokenizer.h.854B9CD5479ED89E.idx | Bin 0 -> 1820 bytes .../as_typeinfo.cpp.8CEF89F6C7B86D66.idx | Bin 0 -> 8880 bytes .../index/as_typeinfo.h.A4B06C7A534C616F.idx | Bin 0 -> 9638 bytes .../as_variablescope.cpp.A21DCD03EB5BCAC2.idx | Bin 0 -> 2148 bytes .../as_variablescope.h.333E3E56495AE2F3.idx | Bin 0 -> 1668 bytes .../clangd/index/cgltf.h.13D0453510CF284B.idx | Bin 0 -> 146694 bytes .../index/config.h.03B8421B881A1B3F.idx | Bin 0 -> 2792 bytes .../index/context.c.EDA476931D1F952E.idx | Bin 0 -> 13504 bytes .../index/dr_mp3.h.251364C12EEB63EE.idx | Bin 0 -> 79250 bytes .../index/dr_wav.h.57B96FF54B7B9AA9.idx | Bin 0 -> 159032 bytes .../index/egl_context.c.2879CBBF04434D06.idx | Bin 0 -> 21116 bytes .../index/fa-solid-900.h.DCA613D0F857190A.idx | Bin 0 -> 436 bytes .../clangd/index/glad.h.D7F215BB4A184C68.idx | Bin 0 -> 454934 bytes .../clangd/index/glfw3.h.4A7AA4589B3A7536.idx | Bin 0 -> 57902 bytes .../index/glfw3native.h.014FFEC0ED3EC0CE.idx | Bin 0 -> 3184 bytes .../index/glx_context.c.F619386CB1A90A48.idx | Bin 0 -> 17940 bytes .../index/hot_reload.cpp.438F77C33B0F3987.idx | Bin 0 -> 1324 bytes .../index/hot_reload.h.EBF600E71D50BA1D.idx | Bin 0 -> 234 bytes .../index/imconfig.h.D0F566EA74959128.idx | Bin 0 -> 152 bytes .../index/imgui.cpp.13AB39A0FB035459.idx | Bin 0 -> 617416 bytes .../clangd/index/imgui.h.B7C59F8F3DC0FD23.idx | Bin 0 -> 246116 bytes .../index/imgui_draw.cpp.7992492567CA8F61.idx | Bin 0 -> 147620 bytes .../imgui_impl_raylib.h.F2883BD4DF99D0AA.idx | Bin 0 -> 700 bytes .../imgui_internal.h.84DDA470F673C97A.idx | Bin 0 -> 282620 bytes .../imgui_tables.cpp.425F22EB42415313.idx | Bin 0 -> 112400 bytes .../imgui_widgets.cpp.04F11CC794B17899.idx | Bin 0 -> 264624 bytes .../imstb_rectpack.h.C5897263BE31F96A.idx | Bin 0 -> 8220 bytes .../imstb_textedit.h.7F8427DC7CF4AEBF.idx | Bin 0 -> 18656 bytes .../imstb_truetype.h.3094409E29ACB5DB.idx | Bin 0 -> 67882 bytes .../clangd/index/init.c.DD5A48A85530AE07.idx | Bin 0 -> 12136 bytes .../clangd/index/input.c.DFC3C828DE1E8852.idx | Bin 0 -> 40158 bytes .../index/internal.h.6CB304F22674393A.idx | Bin 0 -> 52852 bytes .../index/jar_mod.h.CCA482DB947C5FCB.idx | Bin 0 -> 22620 bytes .../index/jar_xm.h.8D41367F0ED13D7A.idx | Bin 0 -> 59118 bytes .../linux_joystick.c.31625443FFAB8C8B.idx | Bin 0 -> 7656 bytes .../linux_joystick.h.C8553F75C24E036B.idx | Bin 0 -> 1970 bytes .../clangd/index/log.c.CA61F35B04D42E37.idx | Bin 0 -> 4894 bytes .../clangd/index/log.h.032C30DFDD3DB212.idx | Bin 0 -> 2042 bytes .../clangd/index/m3d.h.4DC2D9ED5C203922.idx | Bin 0 -> 92638 bytes .../index/main.cpp.C941A06453C00054.idx | Bin 0 -> 778 bytes .../index/mappings.h.4BEBC502A0B05FF6.idx | Bin 0 -> 822 bytes ...th_bindings_tests.cpp.D7C83C93D7E83F9C.idx | Bin 0 -> 1756 bytes ...math_bindings_tests.h.991FEE567F64F8D3.idx | Bin 0 -> 228 bytes .../index/miniaudio.h.0A39D8158432017C.idx | Bin 0 -> 793908 bytes .../index/monitor.c.3469985774081EC8.idx | Bin 0 -> 13876 bytes .../index/msf_gif.h.65FFB47C06B3BA6A.idx | Bin 0 -> 12132 bytes .../index/null_init.c.E38F9C95980E7054.idx | Bin 0 -> 16508 bytes .../null_joystick.c.3827883193D34A5A.idx | Bin 0 -> 1474 bytes .../null_joystick.h.7ADCE9E49835732C.idx | Bin 0 -> 1144 bytes .../index/null_monitor.c.34BD3DBD2B22C4F5.idx | Bin 0 -> 3378 bytes .../null_platform.h.7A0422E28E0FB8E5.idx | Bin 0 -> 12754 bytes .../index/null_window.c.FB322F091A96B762.idx | Bin 0 -> 15686 bytes .../osmesa_context.c.2BA66DA2FB27F750.idx | Bin 0 -> 8638 bytes .../index/par_shapes.h.7393F928DA3A6201.idx | Bin 0 -> 31278 bytes .../index/platform.c.FA48B8A9BC845731.idx | Bin 0 -> 3054 bytes .../index/platform.h.BF727383B031E461.idx | Bin 0 -> 1272 bytes .../index/posix_module.c.CE3721E5E9F44037.idx | Bin 0 -> 944 bytes .../index/posix_poll.c.63C3DBF0634C78B9.idx | Bin 0 -> 1164 bytes .../index/posix_poll.h.761D8493A7E79417.idx | Bin 0 -> 404 bytes .../index/posix_thread.c.8FB200A08AA28F36.idx | Bin 0 -> 2482 bytes .../index/posix_thread.h.C5A22A3F1C04EBDA.idx | Bin 0 -> 898 bytes .../index/posix_time.c.EB737AF6C0A11311.idx | Bin 0 -> 1428 bytes .../index/posix_time.h.1D027F288CF45AAB.idx | Bin 0 -> 656 bytes .../clangd/index/qoa.h.8814EBDB08EED1F1.idx | Bin 0 -> 7722 bytes .../index/qoaplay.c.88D0F007DC759AB0.idx | Bin 0 -> 4808 bytes .../clangd/index/qoi.h.AADB9CA1D27BDEE2.idx | Bin 0 -> 6262 bytes .../index/raudio.c.67BD55980473245D.idx | Bin 0 -> 54264 bytes .../index/raylib.h.29612B7258BE815F.idx | Bin 0 -> 120656 bytes .../index/raymath.h.2370950AA6487104.idx | Bin 0 -> 66286 bytes .../index/rcamera.h.C158CEF4110F1CE8.idx | Bin 0 -> 7898 bytes .../clangd/index/rcore.c.636D60F9ED989DDC.idx | Bin 0 -> 90196 bytes .../rcore_desktop_glfw.c.D1400F1522C61D29.idx | Bin 0 -> 50650 bytes .../index/rgestures.h.1ED1EE8399665915.idx | Bin 0 -> 12942 bytes .../index/rlImGui.cpp.A1A91F5C2EC33896.idx | Bin 0 -> 27828 bytes .../index/rlImGui.h.38EE9B31246D52A1.idx | Bin 0 -> 2784 bytes .../index/rl_gputex.h.5F186F0D984189E0.idx | Bin 0 -> 4204 bytes .../clangd/index/rlgl.h.EE8C9BD4F86A9217.idx | Bin 0 -> 31254 bytes .../index/rmodels.c.E2077C168069643D.idx | Bin 0 -> 148200 bytes .../index/rprand.h.A9F7B76391CEC0D4.idx | Bin 0 -> 2838 bytes .../index/rshapes.c.F9C87CED8A5C502A.idx | Bin 0 -> 58474 bytes .../clangd/index/rtext.c.6F870283BFAE90A6.idx | Bin 0 -> 28470 bytes .../index/rtextures.c.A0FBFE53B2EC34A3.idx | Bin 0 -> 95810 bytes ...ript_engine_tests.cpp.FA7D29E2927285AC.idx | Bin 0 -> 1624 bytes ...script_engine_tests.h.3AFD5906B4BAFB23.idx | Bin 0 -> 304 bytes .../scriptbuilder.cpp.4174B604021EDCA8.idx | Bin 0 -> 21350 bytes .../scriptbuilder.h.01A4572D6A536522.idx | Bin 0 -> 6380 bytes .../scriptstdstring.cpp.C8D72FED91DBFBC6.idx | Bin 0 -> 39170 bytes .../scriptstdstring.h.0BCD3B6B171D685C.idx | Bin 0 -> 578 bytes .../clangd/index/sdefl.h.C0C0E9AFD8034531.idx | Bin 0 -> 12070 bytes .../clangd/index/sinfl.h.62097C66CA8991F5.idx | Bin 0 -> 5026 bytes .../index/stb_image.h.181F33D2B7AF82DE.idx | Bin 0 -> 98606 bytes .../stb_image_resize2.h.CD8FAB1902B73085.idx | Bin 0 -> 182872 bytes .../stb_image_write.h.E67C86A994AE4948.idx | Bin 0 -> 14006 bytes .../index/stb_perlin.h.00622C51F350CC49.idx | Bin 0 -> 2788 bytes .../stb_rect_pack.h.D251B0730CD219ED.idx | Bin 0 -> 8468 bytes .../index/stb_truetype.h.07A6482B66454C43.idx | Bin 0 -> 69396 bytes .../index/stb_vorbis.c.3F18A71DA2EB018C.idx | Bin 0 -> 77724 bytes .../index/test.cpp.9DF026EB2D4E3520.idx | Bin 0 -> 728 bytes .../tinyobj_loader_c.h.CCE1E6C571F96984.idx | Bin 0 -> 20890 bytes .../clangd/index/utils.c.9E0AC1AFB528EC97.idx | Bin 0 -> 6666 bytes .../clangd/index/utils.h.B2A9FDFBB6793C09.idx | Bin 0 -> 244 bytes .../index/vox_loader.h.9A8296C333F5F41B.idx | Bin 0 -> 9440 bytes .../index/vulkan.c.EF7A63E0933C6FE4.idx | Bin 0 -> 7146 bytes .../index/window.c.0CB305403CB68121.idx | Bin 0 -> 43112 bytes .../index/x11_init.c.87FCA90C32F5E445.idx | Bin 0 -> 69682 bytes .../index/x11_monitor.c.4A77A94C2FF11C1D.idx | Bin 0 -> 16796 bytes .../index/x11_platform.h.91FEF7ED090E8205.idx | Bin 0 -> 63788 bytes .../index/x11_window.c.DCD2EDB15A9C6D96.idx | Bin 0 -> 83022 bytes .../index/xkb_unicode.c.D2CF3715482DBC0B.idx | Bin 0 -> 988 bytes .../index/xkb_unicode.h.73350CFC11A68654.idx | Bin 0 -> 326 bytes fonts/Inter-Regular.ttf | Bin 0 -> 342680 bytes fonts/JetBrainsMono-Regular.ttf | Bin 0 -> 273900 bytes fonts/fa-regular-400.ttf | Bin 0 -> 68064 bytes fonts/fa-solid-900.ttf | Bin 0 -> 426112 bytes imgui.ini | 18 +++++------ src/gui/GuiManager.cpp | 30 ++++++++++++------ src/gui/LogWindow.cpp | 3 ++ 212 files changed, 32 insertions(+), 19 deletions(-) create mode 100644 .cache/clangd/index/Application.cpp.8776A52D61132E96.idx create mode 100644 .cache/clangd/index/Application.h.858A603E426F648A.idx create mode 100644 .cache/clangd/index/DrawBindings.cpp.D3B812DF8CB26330.idx create mode 100644 .cache/clangd/index/DrawBindings.h.CC7314AB1A121981.idx create mode 100644 .cache/clangd/index/FA6FreeSolidFontData.h.FC535BAFFB56AA07.idx create mode 100644 .cache/clangd/index/GuiManager.cpp.673B708E1204267E.idx create mode 100644 .cache/clangd/index/GuiManager.h.BF6B9FB11B7598EE.idx create mode 100644 .cache/clangd/index/HotReload.cpp.F47033D97042FC77.idx create mode 100644 .cache/clangd/index/HotReload.h.E78A1E604B731DD0.idx create mode 100644 .cache/clangd/index/IconsFontAwesome6.h.4F690858433DCB54.idx create mode 100644 .cache/clangd/index/ImGuiNotify.hpp.EE306DC3E81DBD8B.idx create mode 100644 .cache/clangd/index/ImageBindings.cpp.106301A4847C5051.idx create mode 100644 .cache/clangd/index/ImageBindings.h.67795D26AAFCD1E4.idx create mode 100644 .cache/clangd/index/LogBindings.cpp.F216E8762748E2D1.idx create mode 100644 .cache/clangd/index/LogBindings.h.03A2A0BF520F958E.idx create mode 100644 .cache/clangd/index/LogWindow.cpp.EAFA4FFD61920E45.idx create mode 100644 .cache/clangd/index/LogWindow.h.739C84098534FA87.idx create mode 100644 .cache/clangd/index/MathBindings.cpp.A3EA272C10D858CA.idx create mode 100644 .cache/clangd/index/MathBindings.h.4EB245298CE82877.idx create mode 100644 .cache/clangd/index/ScriptBindings.cpp.E23B554865E2DC43.idx create mode 100644 .cache/clangd/index/ScriptBindings.h.1767B8F57F307012.idx create mode 100644 .cache/clangd/index/ScriptEngine.cpp.7ACDEA59EB4DE303.idx create mode 100644 .cache/clangd/index/ScriptEngine.h.E0931BF4ECAC1BB0.idx create mode 100644 .cache/clangd/index/TextureBindings.cpp.ED92828A1ED5C540.idx create mode 100644 .cache/clangd/index/TextureBindings.h.4E98F904F8826D78.idx create mode 100644 .cache/clangd/index/Toast.h.7992F998C96CE2CA.idx create mode 100644 .cache/clangd/index/ToastBindings.cpp.02CE1E8043BDE66D.idx create mode 100644 .cache/clangd/index/ToastBindings.h.61AE191277D79513.idx create mode 100644 .cache/clangd/index/acutest.h.0D2F8C30EC1B66E0.idx create mode 100644 .cache/clangd/index/angelscript.h.AC475AED505975DD.idx create mode 100644 .cache/clangd/index/as_array.h.B06B657A6FAA5011.idx create mode 100644 .cache/clangd/index/as_atomic.cpp.D441A68A9330007D.idx create mode 100644 .cache/clangd/index/as_atomic.h.98FF439E721B3419.idx create mode 100644 .cache/clangd/index/as_builder.cpp.5B991AB7F848169A.idx create mode 100644 .cache/clangd/index/as_builder.h.00D1D5DB84CC6772.idx create mode 100644 .cache/clangd/index/as_bytecode.cpp.71E2F83E289CB227.idx create mode 100644 .cache/clangd/index/as_bytecode.h.CA7F431C9B25F8E1.idx create mode 100644 .cache/clangd/index/as_callfunc.cpp.C0CF031BC9B3F5F4.idx create mode 100644 .cache/clangd/index/as_callfunc.h.B7EBA57BCC1841B1.idx create mode 100644 .cache/clangd/index/as_callfunc_mips.cpp.F43F7C77711AC923.idx create mode 100644 .cache/clangd/index/as_callfunc_x64_gcc.cpp.2B9B6E753A40B5C5.idx create mode 100644 .cache/clangd/index/as_callfunc_x64_mingw.cpp.02C3DF7B496086F1.idx create mode 100644 .cache/clangd/index/as_callfunc_x64_msvc.cpp.1A0494FBF3190501.idx create mode 100644 .cache/clangd/index/as_callfunc_x86.cpp.A0DEAD74858CF856.idx create mode 100644 .cache/clangd/index/as_compiler.cpp.FB22BDBD390751F2.idx create mode 100644 .cache/clangd/index/as_compiler.h.113AEE4326224489.idx create mode 100644 .cache/clangd/index/as_config.h.0D6663DCAC5041EA.idx create mode 100644 .cache/clangd/index/as_configgroup.cpp.1978D5FE841E12B2.idx create mode 100644 .cache/clangd/index/as_configgroup.h.47769F873BE0B41A.idx create mode 100644 .cache/clangd/index/as_context.cpp.E3B08CC2931C1E25.idx create mode 100644 .cache/clangd/index/as_context.h.47F3D2D0DA8CC748.idx create mode 100644 .cache/clangd/index/as_criticalsection.h.130F097169824D1C.idx create mode 100644 .cache/clangd/index/as_datatype.cpp.E0A62FE00E11D0A1.idx create mode 100644 .cache/clangd/index/as_datatype.h.31D59544BB09D8E7.idx create mode 100644 .cache/clangd/index/as_debug.h.527CACBD7491503F.idx create mode 100644 .cache/clangd/index/as_gc.cpp.AC20E1A61B2CBCFB.idx create mode 100644 .cache/clangd/index/as_gc.h.99128ED2E571142C.idx create mode 100644 .cache/clangd/index/as_generic.cpp.C80CCE51026AAE64.idx create mode 100644 .cache/clangd/index/as_generic.h.53B17A96528B62ED.idx create mode 100644 .cache/clangd/index/as_globalproperty.cpp.E4E70F1E3BDD257D.idx create mode 100644 .cache/clangd/index/as_map.h.A3AD2B90FEEB726F.idx create mode 100644 .cache/clangd/index/as_memory.cpp.552DF5AD14ECC4B5.idx create mode 100644 .cache/clangd/index/as_memory.h.C6EFA7F35F05C98D.idx create mode 100644 .cache/clangd/index/as_module.cpp.0B1C5EFB053A59F6.idx create mode 100644 .cache/clangd/index/as_module.h.D7D335828B947862.idx create mode 100644 .cache/clangd/index/as_namespace.h.F7B71193DB11DB1A.idx create mode 100644 .cache/clangd/index/as_objecttype.cpp.F06C6FB1C9AED6FA.idx create mode 100644 .cache/clangd/index/as_objecttype.h.785FD4622CEC3E36.idx create mode 100644 .cache/clangd/index/as_outputbuffer.cpp.B6366FB27E3B19A7.idx create mode 100644 .cache/clangd/index/as_outputbuffer.h.ACD41D21BD4DC007.idx create mode 100644 .cache/clangd/index/as_parser.cpp.BD2BBF497B7C08D9.idx create mode 100644 .cache/clangd/index/as_parser.h.835A6072918E81C2.idx create mode 100644 .cache/clangd/index/as_property.h.B4B9AAB7616A0D6B.idx create mode 100644 .cache/clangd/index/as_restore.cpp.914EC6C72AA277A3.idx create mode 100644 .cache/clangd/index/as_restore.h.C7B523ACCDD6860D.idx create mode 100644 .cache/clangd/index/as_scriptcode.cpp.785735990E5C292F.idx create mode 100644 .cache/clangd/index/as_scriptcode.h.A66639055A43BA36.idx create mode 100644 .cache/clangd/index/as_scriptengine.cpp.811C05404051D15E.idx create mode 100644 .cache/clangd/index/as_scriptengine.h.04C2C814432DD8AF.idx create mode 100644 .cache/clangd/index/as_scriptfunction.cpp.F9B4DD1EC0FC8DDF.idx create mode 100644 .cache/clangd/index/as_scriptfunction.h.98772B58CB0B667F.idx create mode 100644 .cache/clangd/index/as_scriptnode.cpp.FE66C402D41629AC.idx create mode 100644 .cache/clangd/index/as_scriptnode.h.46E65245C1B8E45F.idx create mode 100644 .cache/clangd/index/as_scriptobject.cpp.74A647D3C5D1F2CA.idx create mode 100644 .cache/clangd/index/as_scriptobject.h.9025F12F2C738108.idx create mode 100644 .cache/clangd/index/as_string.cpp.5255D8D36DAECD5C.idx create mode 100644 .cache/clangd/index/as_string.h.D36854A487979607.idx create mode 100644 .cache/clangd/index/as_string_util.cpp.ED3BDC32F8DD540E.idx create mode 100644 .cache/clangd/index/as_string_util.h.9A317F1475C17B9C.idx create mode 100644 .cache/clangd/index/as_symboltable.h.C39A118BD2A60C0C.idx create mode 100644 .cache/clangd/index/as_texts.h.A2EC1EC85F68DC9C.idx create mode 100644 .cache/clangd/index/as_thread.cpp.16533C75DDD387A2.idx create mode 100644 .cache/clangd/index/as_thread.h.6E3159A81260B7DC.idx create mode 100644 .cache/clangd/index/as_tokendef.h.DA624DCE97276FDA.idx create mode 100644 .cache/clangd/index/as_tokenizer.cpp.061A182A21E94D51.idx create mode 100644 .cache/clangd/index/as_tokenizer.h.854B9CD5479ED89E.idx create mode 100644 .cache/clangd/index/as_typeinfo.cpp.8CEF89F6C7B86D66.idx create mode 100644 .cache/clangd/index/as_typeinfo.h.A4B06C7A534C616F.idx create mode 100644 .cache/clangd/index/as_variablescope.cpp.A21DCD03EB5BCAC2.idx create mode 100644 .cache/clangd/index/as_variablescope.h.333E3E56495AE2F3.idx create mode 100644 .cache/clangd/index/cgltf.h.13D0453510CF284B.idx create mode 100644 .cache/clangd/index/config.h.03B8421B881A1B3F.idx create mode 100644 .cache/clangd/index/context.c.EDA476931D1F952E.idx create mode 100644 .cache/clangd/index/dr_mp3.h.251364C12EEB63EE.idx create mode 100644 .cache/clangd/index/dr_wav.h.57B96FF54B7B9AA9.idx create mode 100644 .cache/clangd/index/egl_context.c.2879CBBF04434D06.idx create mode 100644 .cache/clangd/index/fa-solid-900.h.DCA613D0F857190A.idx create mode 100644 .cache/clangd/index/glad.h.D7F215BB4A184C68.idx create mode 100644 .cache/clangd/index/glfw3.h.4A7AA4589B3A7536.idx create mode 100644 .cache/clangd/index/glfw3native.h.014FFEC0ED3EC0CE.idx create mode 100644 .cache/clangd/index/glx_context.c.F619386CB1A90A48.idx create mode 100644 .cache/clangd/index/hot_reload.cpp.438F77C33B0F3987.idx create mode 100644 .cache/clangd/index/hot_reload.h.EBF600E71D50BA1D.idx create mode 100644 .cache/clangd/index/imconfig.h.D0F566EA74959128.idx create mode 100644 .cache/clangd/index/imgui.cpp.13AB39A0FB035459.idx create mode 100644 .cache/clangd/index/imgui.h.B7C59F8F3DC0FD23.idx create mode 100644 .cache/clangd/index/imgui_draw.cpp.7992492567CA8F61.idx create mode 100644 .cache/clangd/index/imgui_impl_raylib.h.F2883BD4DF99D0AA.idx create mode 100644 .cache/clangd/index/imgui_internal.h.84DDA470F673C97A.idx create mode 100644 .cache/clangd/index/imgui_tables.cpp.425F22EB42415313.idx create mode 100644 .cache/clangd/index/imgui_widgets.cpp.04F11CC794B17899.idx create mode 100644 .cache/clangd/index/imstb_rectpack.h.C5897263BE31F96A.idx create mode 100644 .cache/clangd/index/imstb_textedit.h.7F8427DC7CF4AEBF.idx create mode 100644 .cache/clangd/index/imstb_truetype.h.3094409E29ACB5DB.idx create mode 100644 .cache/clangd/index/init.c.DD5A48A85530AE07.idx create mode 100644 .cache/clangd/index/input.c.DFC3C828DE1E8852.idx create mode 100644 .cache/clangd/index/internal.h.6CB304F22674393A.idx create mode 100644 .cache/clangd/index/jar_mod.h.CCA482DB947C5FCB.idx create mode 100644 .cache/clangd/index/jar_xm.h.8D41367F0ED13D7A.idx create mode 100644 .cache/clangd/index/linux_joystick.c.31625443FFAB8C8B.idx create mode 100644 .cache/clangd/index/linux_joystick.h.C8553F75C24E036B.idx create mode 100644 .cache/clangd/index/log.c.CA61F35B04D42E37.idx create mode 100644 .cache/clangd/index/log.h.032C30DFDD3DB212.idx create mode 100644 .cache/clangd/index/m3d.h.4DC2D9ED5C203922.idx create mode 100644 .cache/clangd/index/main.cpp.C941A06453C00054.idx create mode 100644 .cache/clangd/index/mappings.h.4BEBC502A0B05FF6.idx create mode 100644 .cache/clangd/index/math_bindings_tests.cpp.D7C83C93D7E83F9C.idx create mode 100644 .cache/clangd/index/math_bindings_tests.h.991FEE567F64F8D3.idx create mode 100644 .cache/clangd/index/miniaudio.h.0A39D8158432017C.idx create mode 100644 .cache/clangd/index/monitor.c.3469985774081EC8.idx create mode 100644 .cache/clangd/index/msf_gif.h.65FFB47C06B3BA6A.idx create mode 100644 .cache/clangd/index/null_init.c.E38F9C95980E7054.idx create mode 100644 .cache/clangd/index/null_joystick.c.3827883193D34A5A.idx create mode 100644 .cache/clangd/index/null_joystick.h.7ADCE9E49835732C.idx create mode 100644 .cache/clangd/index/null_monitor.c.34BD3DBD2B22C4F5.idx create mode 100644 .cache/clangd/index/null_platform.h.7A0422E28E0FB8E5.idx create mode 100644 .cache/clangd/index/null_window.c.FB322F091A96B762.idx create mode 100644 .cache/clangd/index/osmesa_context.c.2BA66DA2FB27F750.idx create mode 100644 .cache/clangd/index/par_shapes.h.7393F928DA3A6201.idx create mode 100644 .cache/clangd/index/platform.c.FA48B8A9BC845731.idx create mode 100644 .cache/clangd/index/platform.h.BF727383B031E461.idx create mode 100644 .cache/clangd/index/posix_module.c.CE3721E5E9F44037.idx create mode 100644 .cache/clangd/index/posix_poll.c.63C3DBF0634C78B9.idx create mode 100644 .cache/clangd/index/posix_poll.h.761D8493A7E79417.idx create mode 100644 .cache/clangd/index/posix_thread.c.8FB200A08AA28F36.idx create mode 100644 .cache/clangd/index/posix_thread.h.C5A22A3F1C04EBDA.idx create mode 100644 .cache/clangd/index/posix_time.c.EB737AF6C0A11311.idx create mode 100644 .cache/clangd/index/posix_time.h.1D027F288CF45AAB.idx create mode 100644 .cache/clangd/index/qoa.h.8814EBDB08EED1F1.idx create mode 100644 .cache/clangd/index/qoaplay.c.88D0F007DC759AB0.idx create mode 100644 .cache/clangd/index/qoi.h.AADB9CA1D27BDEE2.idx create mode 100644 .cache/clangd/index/raudio.c.67BD55980473245D.idx create mode 100644 .cache/clangd/index/raylib.h.29612B7258BE815F.idx create mode 100644 .cache/clangd/index/raymath.h.2370950AA6487104.idx create mode 100644 .cache/clangd/index/rcamera.h.C158CEF4110F1CE8.idx create mode 100644 .cache/clangd/index/rcore.c.636D60F9ED989DDC.idx create mode 100644 .cache/clangd/index/rcore_desktop_glfw.c.D1400F1522C61D29.idx create mode 100644 .cache/clangd/index/rgestures.h.1ED1EE8399665915.idx create mode 100644 .cache/clangd/index/rlImGui.cpp.A1A91F5C2EC33896.idx create mode 100644 .cache/clangd/index/rlImGui.h.38EE9B31246D52A1.idx create mode 100644 .cache/clangd/index/rl_gputex.h.5F186F0D984189E0.idx create mode 100644 .cache/clangd/index/rlgl.h.EE8C9BD4F86A9217.idx create mode 100644 .cache/clangd/index/rmodels.c.E2077C168069643D.idx create mode 100644 .cache/clangd/index/rprand.h.A9F7B76391CEC0D4.idx create mode 100644 .cache/clangd/index/rshapes.c.F9C87CED8A5C502A.idx create mode 100644 .cache/clangd/index/rtext.c.6F870283BFAE90A6.idx create mode 100644 .cache/clangd/index/rtextures.c.A0FBFE53B2EC34A3.idx create mode 100644 .cache/clangd/index/script_engine_tests.cpp.FA7D29E2927285AC.idx create mode 100644 .cache/clangd/index/script_engine_tests.h.3AFD5906B4BAFB23.idx create mode 100644 .cache/clangd/index/scriptbuilder.cpp.4174B604021EDCA8.idx create mode 100644 .cache/clangd/index/scriptbuilder.h.01A4572D6A536522.idx create mode 100644 .cache/clangd/index/scriptstdstring.cpp.C8D72FED91DBFBC6.idx create mode 100644 .cache/clangd/index/scriptstdstring.h.0BCD3B6B171D685C.idx create mode 100644 .cache/clangd/index/sdefl.h.C0C0E9AFD8034531.idx create mode 100644 .cache/clangd/index/sinfl.h.62097C66CA8991F5.idx create mode 100644 .cache/clangd/index/stb_image.h.181F33D2B7AF82DE.idx create mode 100644 .cache/clangd/index/stb_image_resize2.h.CD8FAB1902B73085.idx create mode 100644 .cache/clangd/index/stb_image_write.h.E67C86A994AE4948.idx create mode 100644 .cache/clangd/index/stb_perlin.h.00622C51F350CC49.idx create mode 100644 .cache/clangd/index/stb_rect_pack.h.D251B0730CD219ED.idx create mode 100644 .cache/clangd/index/stb_truetype.h.07A6482B66454C43.idx create mode 100644 .cache/clangd/index/stb_vorbis.c.3F18A71DA2EB018C.idx create mode 100644 .cache/clangd/index/test.cpp.9DF026EB2D4E3520.idx create mode 100644 .cache/clangd/index/tinyobj_loader_c.h.CCE1E6C571F96984.idx create mode 100644 .cache/clangd/index/utils.c.9E0AC1AFB528EC97.idx create mode 100644 .cache/clangd/index/utils.h.B2A9FDFBB6793C09.idx create mode 100644 .cache/clangd/index/vox_loader.h.9A8296C333F5F41B.idx create mode 100644 .cache/clangd/index/vulkan.c.EF7A63E0933C6FE4.idx create mode 100644 .cache/clangd/index/window.c.0CB305403CB68121.idx create mode 100644 .cache/clangd/index/x11_init.c.87FCA90C32F5E445.idx create mode 100644 .cache/clangd/index/x11_monitor.c.4A77A94C2FF11C1D.idx create mode 100644 .cache/clangd/index/x11_platform.h.91FEF7ED090E8205.idx create mode 100644 .cache/clangd/index/x11_window.c.DCD2EDB15A9C6D96.idx create mode 100644 .cache/clangd/index/xkb_unicode.c.D2CF3715482DBC0B.idx create mode 100644 .cache/clangd/index/xkb_unicode.h.73350CFC11A68654.idx create mode 100644 fonts/Inter-Regular.ttf create mode 100644 fonts/JetBrainsMono-Regular.ttf create mode 100644 fonts/fa-regular-400.ttf create mode 100644 fonts/fa-solid-900.ttf diff --git a/.cache/clangd/index/Application.cpp.8776A52D61132E96.idx b/.cache/clangd/index/Application.cpp.8776A52D61132E96.idx new file mode 100644 index 0000000000000000000000000000000000000000..d6ce93da900a407009dd49a54914976cb801012c GIT binary patch literal 4346 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 xOos5db2Ft$dOa@h8tFkRg-1*JO8&bHHJ literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/DrawBindings.cpp.D3B812DF8CB26330.idx b/.cache/clangd/index/DrawBindings.cpp.D3B812DF8CB26330.idx new file mode 100644 index 0000000000000000000000000000000000000000..048ef0beecae9345bee104588d8531d7facfcb3b GIT binary patch literal 2058 zcmY+E3s4hR6o!|uSrS+vgdh?Z2to)+7J>;TkdTl-4WObWYL%)`6gn*hM1rUlK`JkY zYBdNHgo3CAXFw5r3l^oLqxcxLGGna@_()+83)rzZK6;bsP14NdOICVbDvBTo3w-r?xnDa{5X9aALAEq>EPu4&_fW>0rmpgYjB>;3p;RW* zm7lU3^QW9wYOhEy^`F?+*qMLt!<)4`PS*W=w8Ssz+M}6^g~kj1vJFMp+OZaDcW$lg zCc&vK)5*k#U$U>=j5?OR%Q!sz*+l8z;{FAqtWy=T*|+=uQH_ZVp?eHTk?$gZ3TSjm z{-Zpl>{+{YE*(f(+(VNFx;JwlMrYoXUCMQMP-UE2*NgEa z@$)OLu344f@oA&ubC+|)PggfL@U;DjU4p|Smy_?e4xAh4_-(XkTgRkMvLa_=LhXg? z_33%SzBdEjQ#1ec@D*xwnD9n-PH_q&~!2L)dV zIvW=nnhN6;f7ySu-|xD8uX;{7JN9txSj&A!l|etH{C+g4p4(;2=PSuX<%OuW`!7Z2SvflT1EoTo)XAweu!RigLs1BH?ba5%^IsF z3u4}Cy%b%6+bZ&wyqH_2md_ll=CuJS37f{vZd$7#IDR2#^YDscgO86 z=$(32-8%KWX;Q(<^#1m}q4%37!^O?^t;&lsL)DX-h>~{w)~t08P1Eu5RJ8!k(2oJb}s6k#rd#b$`LZ{dvq98jV^=aC6r~Kr_ zeK-;b0x%47Hyil=#LD{0V)w8?9N_>ro62UI4Rj;9>0j#g;0hR|t;LV;1lrl*B%Ma5 z!(9c#NAf3sjdj6rG87GUgs$p+YCgW0Y5<@U+=Sdn$vz*@D`_4eSPALMXCs4u# z_8$%jNMM=}*hqquh$WT;ZbRygE%TZc6oMpi(ii3>NG-0lP;B|`6yvicYd`{(SQP<- z$bh@-%_+Ci!DBAUb%Rp}e?eZ;=vnh>#F}XME}TISWEwzgkVq_2!JuXI1-)76j6Fat zAHruYl;x5$`Zm1zaUIC(iF)F&&hfWjjJJl39|VJAQVVX0o7J+CNi8dx)UuLEEi0MS zf&`Cb$2Q*x_;_Vv`fBy2lkFHmhA=_`VH81%8DblfGNd*X!HBRSB|~XLYKGcEJx^%D z%1@4-1LZr>oGfx5GLB?ARH)B`@|h^p8FmuhAB_FK+X#YKOg|U|I>z^u!j6G?;S*9g zFJShCoN(A=pec_V2DOASKrYjThUF8aOe~9nRrh|36pzoVp9BZvFgc!ZC))m|x~Oc= zX;21E!!2c;E#z_hyU7`oTpCdV+yuy_mMpfCELyh2N^-T_#;1x@#aVrt1)4-iiic~; zLN7PWfSf_>AU=Ey{(CZ0O^4U#uGhz!7QrTC{@9VPa`-sbG-9k{h(t0 zQmwj(rB;j7JtejW#+x6RcB9+q>H-hMX{(|KA>2ZZsNIMufFQnbBzJsvl#Ow z4_Gy%^*bJu6S!TInIv4*efj>Xf6JdTSEPUTn~`^J%|hkXaZCIXE;1BX<|Ziu-6`{E zqR8jwbIW-cn1MVHU}I)wmSo^$Vq{=vVPs=vC`wH$)&q*eR5D6JRDcyTFj(J?X)`!9 s=O-f%8?zL%CQMaPYEB|ZMR8Gbu{emq3L+qYEoNPG-;MUvPDWM+0LWr(H~;_u literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/FA6FreeSolidFontData.h.FC535BAFFB56AA07.idx b/.cache/clangd/index/FA6FreeSolidFontData.h.FC535BAFFB56AA07.idx new file mode 100644 index 0000000000000000000000000000000000000000..930455e0847ccfb40fb82c21d69dcc8b2d8e7d9c GIT binary patch literal 396 zcmWIYbaQKAWMFVk@vO*AElFfyU|=bKJZBb!qMQ#HQ?ewk@91~J zzt$HLOdPI7JQaaw-c+6VYqzgwi@;4zlm6Li%KLO>eUoZud7qyAlP!Nyidu1HZjv3) zZ>4RCOSE_1*5PGfV_@K5mSQ#o6AYX{IaVfyo6U_&@}?yB@G`IirJ1Cd%)kVLBm)B@ z3o}DeYFe=#k|~T_5Zyo_5P<0h3WKyl1Q~$3auPx8;-chYZV-c`t}yS^hxM*NQvoM3 Bjg|la literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/GuiManager.cpp.673B708E1204267E.idx b/.cache/clangd/index/GuiManager.cpp.673B708E1204267E.idx new file mode 100644 index 0000000000000000000000000000000000000000..f728696824f36c7e3351394d80652606f1c1788b GIT binary patch literal 7990 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 QrYa+2Go_V@Ik2Mt0}O`lw*UYD literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/GuiManager.h.BF6B9FB11B7598EE.idx b/.cache/clangd/index/GuiManager.h.BF6B9FB11B7598EE.idx new file mode 100644 index 0000000000000000000000000000000000000000..0f8ba16ded65e14d315af2ed3f844e36e44bcb85 GIT binary patch literal 1230 zcmY+Cc}Nsd9LL|x9`3BOZ{F0n>+Xu0T2i5z5Lx{ZuBEK0d5{@_*QQ;Huqz%(*g^i0 zSD8YhWhO;Q#~*n>ra?)PS)mDv5J8!g;6bsPq|%$UpVou<&Exz1y<@(gNwh{rzEUC- zam-qjo0XqIr%0lYBj0{suy1H;ty1dS4p-HPmwR_@3#~ zUADlC!mCsLH#)y34P4}BdY!3n>QYYB6iqg~aXw94^hwwl_~HEHo`c@AZc#U;b~uW2 zGwT?HUg-UY-v^Z<%&ub*He<8FRgi`zLdWw1qm!jcDGXtiG#+_i!Vv-N`nkC!=kgNP zvkch0lE+{>2djcY=e>e3tEHQpM3dwyVB0Dtx;AW$3?i%oRtuc49_%wso(b0X`ZU6- zz}9nm6WIIg1*dBl#Zv}W0$ZolslZNeXq$|hogN@82e!zGBG}o6{A)8ms^1b;1GdCT z2Cy#&yp=pM@BMURX+~J9))H4ioGSwctG>BEZ*39d7YM6{^&Xsu7p#BKy*J`QR`74k zuBTsa+m7<1%60V6}lWtX>Y;v$7o>|IlHyE-G*4@lG6IkxecCOj4szvmhG(XSDxBf5S!ve6{{b*)w+sQg0RkgpIed_DiDF`)Z=p@W zVU1cNxHPNfr|6|mBsWSk%aP8y-i5@f(gyJdVJ+p}^qtgf22TVdRTM?JykN?RwTc48LPZ%*6l?!5{f+KSvipwzd+&SS+l>ef4tBRjkieAC z9K9}kz6F9HZ1Bs<&Rn>Ij38cC2$HkEGJ5v6f4DQ=XzJ?S+I@c%i8KO2fOp&ZK}A_0gKn1si@|>2t}iZf}Bm=Is-8kG|`b zHEDIJiNPD4TMm4rj>(BR$r9Z!OPu%nCV^!gW!zQoZiB_Mg2)+(^VIy^ne%N2RQ8o^ z%m=lZ@5QSYH~;eK=7n>y!B1oAe~R!CRFw}iwR^AkZCMgEw|Y^+_U_b5r;_DK8AopQ z|1BWDIaR|o<~=|7Vs+lZ-#P~)(itDO3_i@%lG?c!pP%n|SLp0Nlc}WZcgbu+(%05s zq-4a)#XFj}RF_BUsbNpX4(5I&HF;IXw1i(?wkdr0Rn0iuaP<|vkoRZYJqJ7Qt&Qbg z&l257!j?7F2-*)!NY?RuS|`V=Bky|UpL=-PN~c{pw7DSHW!9|23Z z%s=(D0W&;}*Ju-_<*zv|o!U4sCnDU1v!U0xbf>yR9%=2cye}$O5FO~%nuCZA&e+qm zqP$Vl-qPQb-zup(ar;blKw>a?dTE8VfpoX(ROOC+Vg9a@+AR6wrw(@aJ2jM!bQxO% zUrjCKJt%b?yEQ52eUo;bt@E6|p{y5tT@mJX{jH-hkMq~6+yq)Qab?{ZL-=9(k@{&p z{Uvrw&Qg0mHas2*?{GEhWzFv0@l&=xT~>cDVCU!6oc#n!b}EJDo1Ik5T5QBJbbWf(t=nD zSuu)+AOyvRg8u)EycxXZd!ylKDuXNmr@1_?Tn-?_@U-S+XQ+7b@MbPq3c^%6l`W@P z&}>b$od86p?)$6+@S?@W3zkfM-qW;shCBq$(OyF;s^e&f-^86{~H z^s7Omgp?)y+$u^q%bY)J<5B!1gmUPq9u$|NQU*jy>Cr{$+;|&IB6#CIuopOWuym$< zg*`>mre4(R7+cApu9)fqvrvMo;rhX|u?nx`B^9z#z+RvbXrS9*H+aUdt>P4L;}Li? zbO-s-9ELBJRhgFKi>cRM%BUnau5GpemBOg8=1O!HT@3daB~WXWW42fpEC;wgYYV$ z2Wapme0P|nP+$_4AN{^bTLM=>cb74=rAt=u5@f3b)Io6S3{FO-|I3iKAe%p(9|g1F zm@NTmgi14${!#;!piyadX3|V5(+-jbLZDm@ghL4lD&fGI;5(Bx-}J@G%1q9ZnjYk) zztM|Cd@$MsvM_88S?-FsLN|gW>r>K1z!W$-k|`Ecdj|%SZf#|0V@pHrxHyZA@kAUx HNr?Ohc*XsG literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/HotReload.h.E78A1E604B731DD0.idx b/.cache/clangd/index/HotReload.h.E78A1E604B731DD0.idx new file mode 100644 index 0000000000000000000000000000000000000000..4a7cac9295353fe2cd47123eb841c4b626843277 GIT binary patch literal 784 zcmWIYbaUfiW?*nm@vO*AElFfyU|-At{Z7baxwoG)hYgNUQKa+yC{;g8|R#vJ$v@d*@;pm0VgBO^0_{pYU2oh!%L|3A$B z^U!i&>fGK+V|t2q&vJNn_txFdUW%f%Tb+VTwv?`A}%p6>mz5U#R*~-;p2H#bbKg+(o%$*At z?hbqG^o zDt_<3|5L4;_DFffdTjP%z>gX64?;Q&*97|9KuBjGof-KLsyC|*RP1SlkSBpW$>e`< zZ_}Cm#wj)k$`VkP4EzVenHToo6on!rGLXn{FkSx9mXX#K2>KGxmkj&&iV7c9wcfK= z@mOdVLAz+wKj?eCVe`?|>k!l>pf2IQmF>YR52JnVA$*g-H+n05+shZ3$9@R$B8V4p z7dYWaTij-o-v~c>@RP@VxTf~5D|w2u`7EdiK}9&`--kzM1}hvrcL%{v2zEm5rboS< z`zB|qCPFnIs`*3yz2c&Yc-P>Rdjb{;q);Fo`VTBtPMEjgsV{=90Bi-^Tix3@NVw`u z6oRJ^Jn1u(9vPWVAM+F87Tn^lVrod(#WDN3u(?hGbrSA**Yq%nJFtGVkc9#X6iB$M z7&q!5fBfBP2!%o@6!!o3o%YE_spadhNAQ(`ue9$!uq-)s)24bGf-`_KO#BC{SMSM~ ztaSsSN(5CR?z$h1n>6LNwHiW`0Gb5cW9k*zdG}I{7Q#mnd=znAq1p9dM*1Q%1S<(x zNyh*C49)xtH~NM(B77CYS21_x*SnZweG2-DSSVtkh~b{!TeW3#6X)+nh~YyFpX=*k zV`Mr;>1ZMN^TD6by_G~Y^h&=@TLeET_({2M73AEi)KnIT;4TDrA@>>ghMR0(>U2%a zLcIX$=>h{cj;oq`{4RnUfE!HxcOCxW@zZDXoe@4t;iHuMaQX8qvi?k*En%UH2VFew zd5rHaD%C65hENAk2jl*|)zOWv1y+Z5A=C?@UO4(6tc)LR-Enq5LbM2?MbrKP-!j>7 z!_(skZ+Y;R$MwT@U6~g`Ki9ti@D^yGEhvlF@~|G^r2t+ExUYL>)7?4o$x6UN2tWvM zJ=Z6Fc`u7Oeh4l+aG}qT1(8S5kN-7!>V4j>(jMP~ zg*FMaNw|-;e|@e}bMtkCOd(_nIXGg|Z=}s~O@vYrlu~3nZzMT!ex)6PF@Q1MSNG*6 zzXSP>2!&!O6mz$)*O4)+Mr64mBuXKXf=k+<)1fw(nVu|ENT7noQf^+MN|;O^gj6Y{ zO1bVl>v=<+(dd2%uLba0F!{z6A0mWB+~G_}Zyy$(_S`u@J$B2$~e1XbfATr8fpa4?qvN?r)#- zDC3mpYy?jpc=EUa=25ZXoaUet2tNhzQ^4J+cu~Ka7YBn7tVLig;+{r=NMZ3N=Nbfk zG3blAZ*^1My0kl7rZ)@r0xW*kSu~^ z5qCqD4N|@_M4XP$A%G46_Zg$Fi_gj|ZbJCYz;Aj?O6tAr%lD0tWucx2^*n9@I_2@W zOvUXmLa_vjCERFT?YevO9r0C!A|4d+xM3-@I9whw${RtM0cB>wzX$8NbX7|5&JlfB zXb?gJ&B*-6?!z2CrXzGopo>xt-{jx-9BNk}R7s$U2Ie`V)mPRZJAe?(KrnrV^h3hT zB}Y>c9HrnW<>FfIl;rlk&cePd)bpX9&voga&7aOs9Xb*rSOCES?gGpGKQ~=+QUCi2 zfO>i!1IN10ynRatp;Z8_H0!5buz!^n>V#k^0ZR!tYs55foYtJ?hHwZDaoTNqEc}+hZ_3#|rnFC5AGRDpTL9YB3wxW&@2eT=hY-U+3g=0C76}HjpdkSbN`rLn9+2SOJg5HQaP@Ho6LA-z7@(NufKhE%PkJnLRSE~G-dTwS-&~$ z;h3Q;JQu@rnrSA_e>!V>^=gDX5#&*}>b@XN^<4EKgmgZn({)_AUg0t^EC<0`0^Srw z2FvujxArS<7z+jr7*I6y*VLYH`}78cUn2M=;)4BsOv{4Q%moe~qRF7W>bpoiP^zWUwhuX@1yGF3^ zNdTW{V!T>9M0VwX;|S40h^Fqd*u9^@G^4-JDTYqE@`kmBsnU8=e1$rII>?ob}gZ zZ|B+~bc>-|%+35;H{JQO^Y@gIEEEW#K*-HCm#mU{J@(v#kRyg1F*lDN%iOneear)d zS}D}hnnoO*c_;I%CW0v+OsR_|g|AihYxPI?BZ5C7Zs2T=Uuvx06@*|W1~W1D;oAfD z*ql8diI4%10o*gse7g7L&z_xs---u+C>Z~D{<>c9k|CqmSClhQ&Tx_8)V5MHd5c8| z$pFa|8Afay7#uKQGlISp^riFuO^qo{^>62I*^W>phAQd|vO98Y7IcRo_(;J=%H0x& zf+oqua{g!*48&j{=Dx1X?dEo?-~kBj5@@I1{- ziEfE*dP(sflX8Tmu#}r3WX$I4wDedtj&1G|K^HAn*DYB+<7@OjgeDO*Q4+XkRYJ_v zpQ;FBU<~(0KFjiF?#)!k=3jjH#pgP-&F%EadGb{VSqx+`+zoWn&t25sn?Iffe+K+% zqMJSKU2z|qUI-aN$e^p;p2Y4g+@W6-1b?12( z?p%7Jb#EfR6%St1cT(KAI45OE48lrS$<3J4j<{TKllh9x))KImaJk6!>H2~WOlnS6!z{T69jbDSl`Q#%+h#-RMK~Za7 zZ=RW2iD1uwJ;S|XZtrmO7A^V7EKGqZT(f)l{-gfJj@aD6gAU3Qnq9sOpKcV4ki~;6 zTF{SHJp197c@%=D6g=t94p}sCW!T~vgcu>jP>(Io-Z6Hu;VF$uuSj>&P z`aR4YSz8Ni?iN8eP1Qq+-G1obdyk+e20bdsT#5^9T>U8$;SSv4?o&aAT)O?wOl*G7 zznW(On^+_y8fX3E(?`XXH8>4R|vW^9d-pDZO%V5 z2SEow2e|U7Ks(6paMlKdSSiF(ACH`EEw4TBI6|WY8YNs^ZeW01%+!XP2);t_rCQ+` z|E$)lM{gmNilLMikQ#m8xmCw&BD65j!f=b!kr5O7&YjqR@Dku9&0%M^mS6F{xqUhd zBVYsmwYl-oO%KwMFJ_bB0F@!E~Ye20l`TGPBgF9eqU?z z-su^Fk`$DrTzZ*kwn@}G@C8BxKm%}JcBMS`phhdWq1}E*B^s^>J_7I&aBo$7X6?B#t(geHJP4)*$gr{TR&N!D&t#!c0EM*3 z86Vra=ZYuB?WBfKXgycEMrx*=PAMrIADS%>fg;0G1IKi^kUob&b+f(ai? zXoaPi+;-qeL<+(ODSV)8yJLi<&6TEh1aBdDQE3#KD}t*ST&Zxi)w1~0RAn0k9RcVFxSP0jPHYb-e2-wy1ACg*D}r=9M%(q8%R+$| z3MdV4NYJnj=)VO)13-hq%L}#KobBhHBbbT6jLH%<)guyJKZPOW@*tPTjixyfyBUnknO3KZbMQ%zKAG04LBnlvr!dT3+{rdhXQ3%cg zaHe(NmkaHy#&stkykg)Lt#~gh)g(P%E?K}rsSrwqTu{n8z0c2S{#Arp3DnZG)lW7g zHg>Q+g1Z>pX~{CpCZO5R^Dm@HA&v5*F30iX``314_)Kf9oZe9jmqU+foqBq+mv~Y!f5X@}V^q!CMU8Vs7p~`ea29 zpYLZEv7jpjT`8B8CMthZxzk~SU?T<_F_)b68dRaP-!u{-jt6m6Ro-~I-=-yNqYw%N zP(UGHvFx*FkD)Ucvrqz1LgPbaaNh2U_E`uXLhzt*ZoO>IS&!;92yqgKqs5wxO<=e5 z{96P^9yn5UE?9G$V|sAEB`oZQ-CQv4UcBrqOka%6SKtaa*JzB~Ti(z7BsO;gbW@*7 zTX%1aqRSAZ8b5-O$5iEINNndy8m}zm_$NWNwW+0j-x_k3{F5Gh;zl?=8fHvTU*}T&>rNxy; z5fnj@>w^VnGL&ETF~jCXu!t)c)DDk+IX>nqHoxJ+8`_Mpia5G@`i*aYfd_AR+@REe z_d_x+*CE(Q!G^kj@dCx>NptHFj=?eR5lvAT(>UYydO5av7!2b+xO;D}Iqqq@u(^?e zMp{!o*Et{GDlEhWDdV8K)brXp^WPVs%zw_n~< z5P~ESB;i&*rU5rj7>wA8P$PyKTFJ;IUv=yr6pf%I0xhbM{-NY6gsSev)88zEKzu>x*^ zP*8EHVA7@at61m~LYI)+%c*l5GP?Jz4G7^P2p28*7nyyQ1Z|w&R}aBX40g1*bMS4s z*P&m7U?c(~x>L)tZhcU0u3ycsUyTKmz5e z3z*#HJ9o}O@CWdx2o=45*)jWf#}Gn!5K5Q#bFbE;XW0e_xgfk1z*}0)EIFCJVC$Sc z8(CNf>$oJq^_HUGYP&l&2k{_?rje908?K(JX+dxkf}4=5JrwL*xxi0$`z97%iQpAw zw*B|*%*OkM#vOF zCJp15N6N?NTcjd<0r)~SyfQ)E^O2z+5XyN_PP0tN{3BU$UKI#oJP6})E0fpeM_#CY zZ$>bZfD!G0$nR1(e_yHV?`MeM3mv=YdKeMSSp9`+2~^V*r&d3tX48amTiLgIDTJ4l zc|ESqI5)#| z2Xfqmb>O4r;&O!;Z2lsJFLYpL!}wk2s;6foxC+6QRsh$}pHl7&_zMj@XrPSqkcVh@ zvC5=v>?j zQ`r`wSPI2bZavnR_2Sqpe>;RQ5rm1j=e_^JoU>c+IwM$!!9vUx(-Nmxv<-3%M(~n= zmxP;kliW*P!**sPv;edK_pPee_d2yFX2uQ{iX>1Z;l|(Q&IP&Y^JXE~2*HLr!t^JN zj|QARhEO1a0@~}VQK+9L^m>4xCj>oO=leNLEUH@d0zr!pT2wOdD@xQ;$V@>I-PmZ2b zMX&&{pb1FPd_>5l)t(4B0?47s!Tjvy1z$S75I#!aBbDP*hv*fBh@+77@LbL4s`9l6B@!s1aPg%m@x9F@ErkBipPNQY z1KwzzZB4=Ecpk*_rvJ-!RAp-G`#&y4_$-9a6r=qm%X>|1nYxFC4k2_CdqA%s(KiaS#xvYvR^E%+)n2Qm;y8Fx-d z5=^5HFI>BDzD|K0j)CPEVrnrNeHPe1h$+clOWY=doF zAU@JMcHg82d$8G01b#G!r>#+x^Gq~ENEJgW)y$$xXT>s~O%O6fkU^7Nutmt}em{c| zl=z@TRh{UjA;tOXix04{6}EDVW?r}Y!|3{L*enHF=Z@(R9XfRX2sZl(!H-h+t3g99 zZJIG-go-LAr=gzU?Al>&M8wt z)Q8iX5R&+iL<@?n@kN~*a!Q# z#hu^XpKT}4Pr~MFaE)6umyC!wB`OKSW^)OcQ{Ci3m*(B2&m$3(d7w4 z@RWt{foa*lRW4sam@Zk^L@TZebJl0iSevAbtJ~;8Yl1fwB zvk?8e1_&k+FrhQ}jXR^;@)uIuNY+U`>Igws!e*-G|)>vtSli zQdzRG(|7&FcgNZ0SP8_^>|HZs_w|dDBM>|RJgF+xU{LJ$TB8KvwFq9*GJAfz%h>$j z3WQt%1%!Nnd>X{dW>ncLM?OF(6F?b7&5k`ghmIYfgy19wC+cdc zF|}*H*SjHfNT7q3n-v!PvR|Sw1WP_x^0^^X9=Pe0XGJYSq!=P;H_;+={CABf(vvL2 z@*$Qg?x%Kbm2DAwBV2{6+)~h_wC;DH8B>1kD|cX>@k2(|#W^jKXK44Xf# zopFi(QjM#E_CA?+}pAN1$cWo&*0 z@QRM7KiyvWWDm~^!A}ByG+_4pl9O5{-8;jAF%OLChRnTiuybdN7DAE)l4tO- zXl8?;CjdPGHz-YHlLz+7_=HdjP)eKWD>gaaR*CzKkj8^Fifh+ArK4YO7A zI1lH!6^7Pgt2H|(&$_@izhvMg<&M!6+N*W%xFD2EpqwJ}igPof(rm&JoTT7Hr;G+l zgAXrsDne)!LL;So{i9z7EV(Rqkp&|LjOc{KtpS10wk+6%;3xn`Dqq}mU#>r~Wj{g@ zABt!paWg7ACbypwf`$|{Xy>XlM^C{t=_P`-5Ui;lSCkg^J7&f^gk%XMOSk~(t9a;{ z%w%r_B_1eI$Eol0tM*EU55j6#&Go>$N`1%7HA}?iOK^#M5^^VNwA9l+VzYw?94Im; zO&>GCew_Fc3wlz}qbKnoHlm?#-ED+?A>`BYDWObWCr|ziR7bS|D^v zpi{yv>MT#)m|Zz06yY?S<{oNC)~H<_v-y|V<|Z*TQI&e@sHd`KXYV8If?eFmKJ}fy z`jVY7Hb*cJK}%V^u#8E?n&t?a640cZcO!aI^0lM{gk%PiX++$6j1a)+8U(TIVroD9;!V4+9pw79nxGgLIxi)C>pHPA2rO1iAAuNfIY>iG0t)J zjNV6tNC`yJ{8F>OZvO4Zc?fn=u%mDFcI>a2{cg7)q)8x+Y5@iIJ`(m96Y?zNN+6ex zDO)`6YmC2xm^4CLuHfG*f=C-TeBI z;U9_-oF(8)*WrDtSCsDwxXFSGA6zKQF;=#J6TEvpLWvkkD2k|Pm+t7BwhbYW2Z20p z<;`3he9Q2W7Q#t5$)&roO6C>513zPP0v{4+F?3K#^@W9V-&-ua62L23UhCM@Y+5E0 zk6RlwUr_On;GI}4}Wt&y_ph7AB?eWWG%k+mJ z190Foy*51{*t;-ynlX#HC3{iouZj#-6b;)2BN6AcXKBgl2lh&av~h-^fLX zlR})7n?NgbJJ;6^?n3x3h40j9%nNn1pZoQCz=9DUjA*b7+4j`VfAMpKw<35;{ZGX- z_JiwmQ-oF?v{D)>ow#yx(7m4s_Cm0yQ+`fmuiGxS&V9&2xfsf69o9PQk+oY zc5Y5G3V8O(@6={&F6Kco?d@GpbK7YA_!NQ&DB7&K9=`ZtZyju|VxWowmtfb@+lJF3 z5ZZ*$MhgPTn3dNvFNzgeuw=lJ_Qbw!_%SF}b_&7^F}$D^ao(IY3CrK?_zOIELFL<4 zt)Kh$J~)7&CjmW*%$r>L6fE;}LHGmkhXU76**4#m&qENx1Q154uKnD;>tZ*{JYwOC z1isK)we&i4P4xsH;hPk`(J|Mm@uhi%qeTcAQpljkdc|BTY0a))2(ApcQpr$g6{K+Z z+$@AQ0B>kozwl-7=HI%@5JLG7O2?Zv&YU5Y5uQN!2JnrJx`ZSOLWhicijcsA1R4U5 zf;6*q9?L&wL0b&kGz3n3U3LG^?oNaXDOAu|o?&s5yiaUh@`MF_KIqd@cHoh+(|bnl zMCjx}Cw+$evzD(Sqf-dlBG49bW zO0xH2`%zC>I0xsrtR-;hs)xGei?O*-1cf4Qs@k}8YD~G$b_540IM7u%4)YEB`rrnF ziU?FhTnH97jh(gD&K1EPz@GMhl^w>b?=Ad=;3)=A+EV2Uhs7K@*@X}zh8U{#9h?(r zcUiT^e=O{Uz1%f~zZmDcYUyHZb`yXbW!i}&FX}r_x{6T2g9;i;Hs=mb?%kq>kRyQ{ z%7kax)ywT1t%DFEfDlS&=EuL;KSst2p_&KPH1G|br+*9m8I16o2fyhv7QU_@o4st^ zGZq5G5J0)tqx_GPPr4pKh!a5^)oD}LKhb@ZatFa!0>-o-Xd_55tg62E_pSI4KyfN} zK!)YB)y4=RA_$=st8(SYjFXms!5qMxI>I;|$2?t@_r$SO% zW$(_{X+xA*@Zy6Pt-J>*UXp9D*pE;ufl|uPtE+lv4L$ZBLaG2#DLE-Up#HRbzAA#F z2plQfey1`i&sP04f}053Xlw+^9***kD*F2hF*s8EESUSJqeD%q!oH#gpoXeBcP4F< zTefQ|!a`Wc&6Yh*RleU+v=f^(7|@`D@7s2)2#(Fah)}{n37uZf*Ur5dV4jWO#s@b( zH#VZjUQzzh-hj{u&`7sX8nO7;R>O_YS-1?Bxq)A2)Uy*xID3n5&{t&CGP1=}qC zqxcu35Kht7wbQfPZ1zipauJl%#(tS&V@SyA_Xq_H6wnG_YV29vJtspD8U)Zl2MfDT z`BroxNBX!?*sLlARVi1@EGgX~zqnQvA%%eynlm0)$E#g>REMA`22C2qrVso- zIJDOzd=LNaA48_Rc%;fgx)jpscV^Si8)WT1po;L54?n4Mjwrjf#<1TuH5Qcl zpiE#Rd!bj;>t_hhMetn2Z9d01UTRJ8>_Yg=z-LP3#^qlf67qJLItw#lCfB3#=0>MR z^^C*jk3#q;L{LFz zDJGr@Uc+1yXs}=-02@kRk0hJ!S?RG4Arc^xg3&sEq4k7=XAsN)%%}!=X`I3K_%I8E zIv&(flC0D8rF`2+@kgaU-pxqg?cDvhf{1)3~;;lUT`g}bXgZ0c~iL$xgkr3{o()%o#?SmtExIxQC7i{L$F2{Q^c8EAI5 zPC~HbgB_ig?azPWb4xi3p^Fb)^q?O24o+~jtpEENQgEilyvexK|8h3|K^O<)xILoY z%VLU$)yL_u%^d(8)TWw^k)`i zzYjH7q9D;@;gb+PQ99muCv?J|+~Ei=5^$khWayK3Zqq`yA~f=#kg0^pd75_t2Ti_4{7aL+w~jSr;Wr}IArByr(z*H4 zPBp)eYmHcF;Xw=iSgg-3@t%cy6cAzoV(Aq-5A1w2#o-k~qyQr6XPs}x>i1MVV~?OG z0zLX6==TvD51*WvhVYdKUum@;e=9q-vQE#K1%Dp+(_eC_d>Cpt_x(;27Ak~LLEDl& zx;-BhDPBP+5kUzhbfu4$`iIMEAbbb-PRqjUuk~~jRI(6qgpfmTHE(ixb9&JvQx?*B zkWS-iTyN`;lY8Y5en{a5oh0daJo4(;>W2vaBJdY+XA6>23)|byzd)#xLKTI*Q3njA zmDzd-VxZFtw!3cUXI?kJ=1x9zQm!y#VEy6t(vJw5QqZKI&s>~rmiFbpbcF9>_)eMq z*?@jsDFZVQx+Ty}$Ab>_>Rj1%Pi)4*XC8c}oxYIiQH_0q1|yjAz?AmoPmNhUZ{nf7 z2zdez>Ew%bbNTLij?5+EP1DjhV&`M{rtm}hq4)ZMRm<*w`#Nf8D5jR>6#bW*kEM*ne_e3$lk&B9t(%jIp4?rV%RQyPWM@5S(* z@`U=3d*5kKE+*8I^ zykp=UEh=^_e%!e!+z#P6AD&Zikvd1ZznJQa@QHy>lycZ;`t&$2FCQVF2l+IY`GhYy^D%$A1-=yzK2iR;BRd|pWY0i|6G9x#ms+>(xBYm$4dDa8 z2P!R9_^mkjY`+zPt_XCgM7HYK)$@ms*do{p!Irj#wzkCVC{A`qFynz4b>}_ern4K) z`6FaVAcLm&pJx8^Hh%q#kST^tdLH%-%i_jt5?Zp*3D8OB6|;ExPNIOD2u=cUqIf&F zr@g|_8?Fd>Qplst&p#hN--=2aWW_?X0HSHveC{%n9&6O6A(Zi;j2`U_YNrn~TLz zOtqa)OJs^xbs-CpyV1sI`PD(TY_lI9 z{3xD__7rd5DL)jUTnOc~vFsk$CfEG%8G^4Ed}(SB)r>mWcl9TP7ZP|u@qANu?AU`* zKM@|l18%MV+3owR%ZtX@vCSC_WKbbE{>J8`v5Kn^j74Bf>u^tHXWssT^$1>4@S?=* z$iS#^dF7W7=E7XA9y#;m)ncay&#^gI2)Pu?CxrU?{!%bSxC?i=AI2p+j`2R@?1s(1 zMev(`BE88>QA1@|D#Cj{yr;Wlkaj8DuAz@T3pzs3p(*-BD3jH5@lu3$e0WDs?u@B@ z@^8O82)_jIi>if(R0lZA$ZI0_3c#1L=YxVi>$chVa$q4z2ubv_f;lbo2k&X=i_pwK zGgUb5Z@15$x@|T>s}Nf0P~x?s^fe2&&qYY)Lo!W0UnHk1BP8+&Kg94u%oQen^;mJI zzk4!5z8Lapz#Q_Bd$?Qg1A;aWv?-+4{yuP>xy3lL5G#aO+KTvOwN5^3{78ft5yXhN z)o7nZo&#oguSNJIf=_h1%r^VXwyxg_2n7HIwCnYD%i~oaG))lFC6G?l`lDC(7_5&e zLa38M9nE~|yNkYObo6`6LXZH0C>xG*6b{VO8ie2h;6d4!bc)V_84JcDR0^Szu0wI+ z&E>w|w;)9EAd2Fk{J!-U-pq1B&=G+SrLc2`bu7O=%>^M>1i93qt@N)JR5j%x)G$y( z=NN{oTsit*Nio6@7{XN~Q#aII_+ok6iEW+@v$<({p55<;%f~9PxtoD*iXU4w^A0R~ zw8WW(NAQSSC2Ay1nACD|B{s)05X*4C1W+3yKS_JTQ3OW`IMUgWcE5dD>50Y&NdQR{ zfT#HJ{cKI$5Nvs1OWhzVsYiXEmN0}8A(YTUE%DtH_6H5=2!&E8lyc`^qx0%J-gYE-gOr6QM~0O%%ME?u?CUIn#|0C4wjl^V0J33X-4mTv@Q^ zgFS7hf3mR|ylKfQ1QiLW(417b-8p(P|1d%fKn$f0yze7-{A#;_U?Btx8n1;LeGC@& z8STcxe3;Lj4+$#>VoD6gVspL#@&(-VcI9^Sm+jM5A|wkSnQCBPMRgW6O7{_h0D`Cl zToO3=Nk&isLNgDV>G}CxIJ3pn^xNN8@F9qb{>6*>y{Yi2Mrhze1C>@n?4l={jFWX| z!IuGFI++!>|M+#ogUb=JM36;=57FY7w>O4bB3LnCMQMA>qo&cfN&*ow1du_?$Fr)V z9T&HL{rgs8$fBRaYrE_#=ySggp+x{Kl;7*nupHa`Em1cR93H=5PswOSq@8XIS4g z>z2*)WWk&V=9D_*Hus%cb8ZE~3qHJ{{k~}P)F0c{TtWzuK!{}4zk=Py<=<5gKe~&c z!+;K@ym2+tVwz_szQeZ?!V9{*tW#?BSB#I!B_GWfx=cnwpszP`tgm-lCXV#HQ z`((Fj1WyTgQodGaz4NYZ-V`qussvC)!_2nw>9u_E5`;<#RMJlg^_9NoS$JJRNaI5q z{iwiq_KMmQPNfKwU=nvKVbm?hnwtsJz1e0}9;j0NL_K3%@UV;L5V8TXso!qu9IDpV zP>ArF53i|v^4IF6{<>6;@J9fDD9|r(*j=)6w7m}ty`UHO^rrL=jBK%u!sf34Uul2P zOd()J<>(>4EJR8nlBN>Ve)AslJ^T>rMNm&!Li8)|*H)3?2>xR5r@i*`M^3r@P#*jq zKSKmxsb>AvuQ^F+{vre&G3d}94xlAp7rwFzSRgW0&t-NGm8#CntN!-Nd#Rn z=u&C=*3*_aPtUUmc|ypeY$x05;d7Ld)yK*DKCoz1Y({h@AcLxRcIe?(efHqYyZSF0eSp8ZP;kN*O(_4Am5&BJ<(mQ~K zIw90i4i+_P$@iAUgAfAw5J>${f8Nf>YmfIJ#7iNbrl9?MK2N`K`zk`V5VGm5nnz7N zxG?Y)LahL5=_lwv6uWi~lZ!;q5`q@}nCW9xs?w>k(FjEVMKn6rnM~%Fb~PbHiy@lU ziB-HC_j3|91hSwi0adD29JxKj+dIPp!CM60RB-*dvf840ZWO{NK769{R&SEN&KOkq z3&CFk{t~XFv`L_}ULrLKV!?n91~f75)!sJnUg9f+L>?s4@4MutM!$R9`wc>X5CZ6@ zn$FXX$W9&k4Pia3=N2tNbIwE^{W>a`ZO)ZKF5TM=6+YLE9?n2eV?d2oKVFS$)6EQ) zAlOO3j((S-CeOb#@zQ}Lga82q(0u8nRdca=(aKO3ba+LuD*nvX`h71@|bo*q|!#1z|D1x^Xys3z|cK^@; zzOzpu%!7GcX>3U8a=FVjcd^-043=UJ?CwPd>&b}1S$N5VmlQ>E%#}UYtsIVEECyp* z&s=~1d++?dBM^#(P)t>t6Bn|#w`nRPB#0q_qTyhJ0J{+fBM|yRUv5G@UT4|)=v~(vnhl(MTY8x@nuAS6TIf_upgG&0UE@OSg)7(!XXbM1+b~H-f zv|qoa6oBB&181uH4K};iGe0s6K^H)mcH3V**!AIfd<25I0L&?N=15;DsImJgEPUj_ zN2;Mq3wO$SgiMTNp-c>AlxR6>oYP(~az28$0K93|xRRZ+u9w#ugbp!u(9E-;0br!{NT*tTN_H_u{i=Df|e8>{HpYTTi+1E0K#ZRw!u7nT~6cLC>ER;aH4L* zV_x=%e4UB#Mg(tYMqZJBadU0w*=QC_L|{VuEQRL7r0x}V2wPwaS1>4iT%a?3WA7Mz zBO$z@39jdxVcCANqY#F}a4v6o*{`?D&0A-%xl#a?6tY{&sutOdxQU=804)L64f;pU zDeF>xflw=gTG|CT_e4Qy`dD8CD*;$h0cy>wLZzPrLl8dl;Uk~h5^C;vBG>0hHG--D zROz9*57V6ODEk8;Q4ERn?C$T`d%)CuRV)iHrSOt|tnyW+d3Ji`284GKct`6#-bkew zlM#Ukb^vztka%y-&&t%vLkJf@I9>UgeeX^^H5?Jg!T=b+jS9`z8BW)xT)}2nDY#NL z^)>Eyh01VU1T8UW(U;B8QnK7Ev_O~u6S%c&k2TAyU)5Vd%6-75%|Qm~}mtE*zuGqYxDBSiBcn$8vGEnhWk^HE;}RWYd2SiN>> z!&u+E6A3JIG0;Up-Uuusx-)bUwE3V-k-7C$t>TiSUI^Jz$foOdo3r*o-LXsrKLPmB z=#IHOP}lTvCqjY{5~%Y0g12pWN_@XW78*s+NM(|1AC%AYk;2;JE%2dD45O>a+eicEF0X_QRs4lNZcVNUFgf|SlVYr&v zjx?JuI_K382Eib%QW3erWcrPyTx>QKgDIW&_RSj+Xj>_p#KIof!~Ofck7-sPes~X? zpG)C6bm!#ZG_iCcujHn{IZba1rE^&Uj*=lZeXUIQuM}Ue-H{KP)LW))WOX!UReS}{U_(ciU{c)qj{u5+#}Er4no_!iN2HLW)`rLgc^0?%pRz~aEF#vjWZ5Sm5MOkJn) zY{^iM?S%-%0w|^fOfH5eZVdW3K9z-XK9p11x4X;S_`y*f1XTc4iU<+A!f(!2@J(YO zlLwhp7E7@Es^~I57$HdnN%TjAccx~{8&JXicM;et2WY2yNVEU1BcFZNBiQl4j`lYv z_FkkFKKB5EwHU0$T;OgQxzJ^x#zBM)uz?E}p+gNjbin|dE%;zT+4;1#*HJT@!w^Ck z2%#0g$8A5w&zdR`O8HPqLuQt^$Y$P6nU5@F@*$Jf?2RjjC2h`^L$DWvJ)O|{vii98 z%pPkH^hKagi=u^VHSReYtws1Oh0pYxj%fk28|Iw6_7?y?)4gSq`!}|m79#}kAb|d& z&ZzzaHSW%v_=$xm2BH}5C-GZDMl72<+8g1m5Z=4F2D(2rF+u36x zLbe35={)5Hqr8ji1q%=k!{I4hcD_M5xqZqKZ2m5U@03!PCq@JmSFA!v5km@Pcb2vF zGe38oMtCKJSO2r3C9=G(n>BLloPyvKecnRLE z=PEN|P9_T;eDI*Ej(&4?qd9wl<2Lz5Boc%VmrLt>oZ>Fno6g(2p<{vNX0a}%=z1NbDtr6<-=DB7jtWL>=+LxgeX2lQ3s9N zK59YvXi*jm-$d|D#7&EBplr# zW~uY~BfR9pOS-smaxaHkEEt5)Duz}HVBh?I<-XlN`!4{rQX(Gde(y_(`CNn?5#&%o z_h67+h>g#7gc3fK&|0^nrT2i65IY2226U;?J9+x}r-`;*2K@92C)dItZ zXY{*ihwwoFA1HtoO#Ntg+N%=b89d{v4vYF6voze>jm@5X@Z@uo&)RX0n>-uXzwF2! ztQEsgdPD-VL&x)~vJgxFOlX3eeB<%t8ZB`?3uRI$qqTI#ld>L(t)mg#`QXmyiYi_X zpXVn?fo{WfQ6wj zl)JpK3M;0217L)Y6jnoZSFd;bAj`2p&YxLOZdu;Ln1YHVD3a z@TFf&=5+kwOMILV@ z)@cwnmq?+6W`K(86EnT~k3%RDLlO1zWWVO?i4W%^REnUI0*mpI+UT(t4kCm}A&h=z zmVD*jsNDY^B4`Rhlj@4TgTJ=yE7C@&) zDwJ>x3J!W^cfKEjx)9X=r>^+Q=2W(LID#qzs`P8{2XhidL*(@l92szAxF>k+&TF3m zU9JcVU;#Jub59GNzSR;Hv&|t=2%!UaL&vOZNQhsA@QnxG=uTO!Xf*!5>Nvs=27b^m zQ}dmWCO7H~LXi-PXx-<$(5QIZ*qaFXQpl&zF#Nxw?mZr=v=0EdnK?7_o7vh#wYn^# z`=<8Y+9KUZOBAa@F5A9p+qAk!SJk$kb(zYg5C$!x%pf((TL_bgPLnuSmfgwj8WT*vc;TcioXK{%*h$*$Y2O#k@V5{LWw z&`*&|YiX6rGshhvl@F=ZlC}J0xiw?1-^9X8KD?xt%>BMhN0+O)5TQ^2g>;3)6f~E_ zN9;nV=0P=;LEFq7PFV+BMF`_T7zIIl^Hj3h!0QMK9w-Q0983jO7B>+RxsXUPLW2Fs z&d{Ip5!}E{z2aMMG|KBxmg8_67ux9W8#rB^UOd=>a3A14&1~^selR(2Y~9R4E(5u= zC1>2rKl2_Zjlz2lyr+C=qEkhUrs^af(IJ8ky4YOW(tkQ~%pV~ZAeK4@%1vv-J;E~) zTE);x71;BQI{S=gRU=gKpo%iZxC*19hOG?<>yc<^|&N||Y5Y2~Z+9%;-o|SYV=@vq^2(oFXOOMRYKkwo_gnS0_ zDb2B(%G7$zY(UOw=1%Cj4dN}!M{>C|Bsb9CUPzz8?5!kiKevizp zJP>q2S6yPhQ~9uXkNt5RZWls3J<9gfEJ|@xKOAA0fnh2lPO{Da;ncuYgy#ZyPJz~( z8#i5=%d1;Pod`ZnX{Y_!Z{F5?dwG`vuZ5c z_aH=YA%Z^KG^oaYwf-T5RDe|46?$Abt$j?@DTH+DrJr5lbssXC$!(W?9ODo-XB1i-v zp_~6=`i4g3kOUzdAe@fy(=Jo^o+v_S256=SgL)$}D{7NJBD@g83(DLdcm*$hvw(fO zq?ls}hUzKo)4QVuD~tp<+%14^`o@i?k9+Oipox$xfLvO7IkUBYEJ*kYAxH#4G2eYTtdv zO$Z@e2%*KnP>X$!czr9vM?QR{IepE;L1*W40|-h1D5+QL<0kpTLCXGLscgRiAcOAL zOXJ4wbahyYP$+~#YCEkoGBei5K8SFG12-rD^w~bXt2I*lJq!1RaG$E&4mOkIcX&n! z31Uc~JiKE;ME2TQwg_?tp2S9l7cf`JN}cUEqVc1<=aLFf`f7wt@2*x&q( z%hP`lDuqxCkX$lBs1raPT~!vdyO*cEa6-rsK?YTC<*F$ybK4RSWMYufse(2|KUif| zir^~-UkWqF_C;6SiD^a%1PG*@rZUCs!ruCQJuIjMprTM#_mzH#m6r@*KFn7?K=n00 zNai@kpqCwP6hb4Fa4tAUZCV=Ti=gC!k{TZU2Oqwz?K_Pi2atn$rTJuYZI7wxz0o5? zprq{bx%^$jmi{LQ!9ob8Z(}%R$3$#0y+??1yD`9Tdk^|%#gWj z^|4SQf)bHB1e|uq_Q{GYJA_yP#L|;FR;3n(5k;2}dPUGnGu4TpZ9{o)cq$g&is3EY zXvyp9oLA4)K`3CLfRf=8-h0Z6oo67N=EG?!C3eh_Ts|=EdxRV@k%47&`2BlFUj}Wuj4n40uLH#-*=15Ls+|o`++?oK?n)7 zgGvdR{`d_xS9^UORF4 zDhIC8oN(x1D4#Pa3*j>tKGSA}Tm0O;ZJ|{Nm3*kA-0$0O7Opqfd4zDA3%99mrty=8 zwD5crf>a1nD)|^V$6c8s>l{55KqX}~U$)JkciQaNe)fnQA>`16q_@O#OxLYL2txuG zqNdntt+^?^dKm~kT(9EXpUyKO6**Tyb=0&&`*)VMy;~Vx~@tD2?r!pv|}Ef z^;Z7YfRMq349cukdIl5bC|@F!iJ^?veFOV3_LlWs2yza{=~NoZqGHD#8iOpP@F9i1 zk6nLej(lmn20q)aa`});YmLQ$!CxKRULmw_poM<(8Jg2vl)t=2 z2o*snWthKh)^4|M??gxxKq6I%7sM{{NUPTWh^OL03)Os0TACfr{LK*(g^)Hj zucO|n>tJol6a6r^|nPC zN7HS0TO$~QvAQ7D+|9Udix0rzyF$22?>7weiPoIFOopJ~gMx1UwI}*iH3L})QU;_{ zsoG%rdb9Yh5@A>f!}J<#=49fU$GNx>DMDf3LuiIhMEDYL8pa! zpIK<(LkorEC#N-a9+DnIsO3W~)g=WUPkMHy)gxRH!4;9ZDN$!|cH$e27YO%+aF4c6 tE}fg{uC)4qP$PsI`pvy}>~_bN#sTl`2fn~RaQ4@~H8~pf_P-h${{nlkwdMc- literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/ImGuiNotify.hpp.EE306DC3E81DBD8B.idx b/.cache/clangd/index/ImGuiNotify.hpp.EE306DC3E81DBD8B.idx new file mode 100644 index 0000000000000000000000000000000000000000..4a66abf6a13f7dc33b6e6bfc2831f6b5f108cbe7 GIT binary patch literal 10922 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 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/LogBindings.cpp.F216E8762748E2D1.idx b/.cache/clangd/index/LogBindings.cpp.F216E8762748E2D1.idx new file mode 100644 index 0000000000000000000000000000000000000000..624fc453be3e5e7a763155ccb7826030c9bd1102 GIT binary patch literal 2692 zcmY*a3se(V8lHrS&LopC!I2Odm5>^ugloWPT*Vri~ z$s4WIm^%Nh)x%rsBLDfzzNOb=)NNn?xisp#ZDT7&T;tPDh?f>#XWz}JrEmWyI?Eb1 zvdMM2?4UsHO&NdxrzsaVE@+?j-*aq3SWk^fX%&m&&i*xGYgI$e&Q53N`Bz*o%0Ew) zw4C1PFKqkKc%?M6mUSO?ZR62sWUd;$enz--uiU&y-T~>GaojGHMq;%&Gydyj_*cn!2kGCr^3?L z>)0bW7#l75=6=awb$8sWO6iJ@_DQb{CGA-E^5z!*wgK9~uCFrNuC~lw(X=#Cy7R%b znmC6!`LI9swI|M`lb}t!K|Xt=sJQpnd+#ivuWupNr&@}3k!xG}wyJL5H_a;X5|wu? z=Wbr^2cJC8tA69}cbsZJGVN)UP5ILfBVWO}oj1&s6#AyPZ zNOQEIqVKrmycBy0I*gT!RRj%MzwY}QyZ?ayM=3T1(qf5N88nE-ysqWGE_iBChlCSG zb%q7CNwqUk64U;@x5j@WT}DvAg}dN6{OzGYDPGD$EASOORF0SPPz7GWLsfVc5BYE( z57psy96|yK#iN9wfH%dv5M^hWGkl;-a4TL&febPu0#$?q3t^EXq_ke0nQ!_^C!jzU zkwv2tt{sy<_~Y^%06*sud2;l*_(bzW^DpU1Viu?<)i@+212mL|2_YS!qY+|(i875t z;h0gu8DJx9Tq;a3gOF!7k*9;06aU+9vLi@w13JgBli3QFirxB%!P5=xS7=PqMfwGh`E?nh>sjpYLeyW1u z?4+G1F28GwI-_Iy)3*7bla;jcocL|ugn#L2^Qh`Y6i_iL7Nv-f(i8`LO(~F1=5uP` zfUm~O2P5hZd@o%EV`h?>T;=#Eag(~6X^)CrGlm5vbcqI4&Vn+!jECH`n}_2hSe3*#azQ!P(#;ns3%)8OWtwv+b}9P0cb51oPZDtXpYc@>N$$W z{^@6hOfYej1rtmhp_^wmPPX>O{{V9eTtH|oy07812QF*$nF1v#CET>5TN^qBuI!ML z$Lz7A0F9?_?@8#d8GzL>EW-)G0wZhWT7Tq4a?)U8n?G=a%~s7rYOz2QqnQ#yI#$OM z-!#``LfWywqPA#5$fmaOP*!YKT!_n7XY;r`bsi5D#1?R#tphQZ?Sr2_fSTr#xx91A zzx3wzFK*Nye{Tf#&!Kc^QPuDt%e^en5TCc$mmYYT9x%T>@#qD^61Z0ZxcK|2p0zUb zc9AY2e!3phaTKNxy%v`{-IF1lIB_yA8Z%ZtE`pJYNrDQO$ml3`eB=bBMiCu03Hv{2 CRVcIo literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/LogBindings.h.03A2A0BF520F958E.idx b/.cache/clangd/index/LogBindings.h.03A2A0BF520F958E.idx new file mode 100644 index 0000000000000000000000000000000000000000..647214fbfbe86534bf57d7ce067f83a8d573598b GIT binary patch literal 336 zcmWIYbaV4yWMFVk@vO*AElFfyU|W0l{W(VH%OJC$>Lx>R zWp0up(7h{_Cj6W)VbQ_Ez|6qF9>*Fd!N$zWEWyCZ#K^$G!pO$TP?VZhtcRqMQ4*p8 zCq>- COK}4L literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/LogWindow.cpp.EAFA4FFD61920E45.idx b/.cache/clangd/index/LogWindow.cpp.EAFA4FFD61920E45.idx new file mode 100644 index 0000000000000000000000000000000000000000..3b3992cc1cdb61f66f1c02f40ec0f35f42404573 GIT binary patch literal 1840 zcmY+E3s4hB7{@Q<0Y{G9g(HEy2uU_11R~+31<``GX{pu$L>a~+MMRK-3Q;FK1Rbgo zp-2U3L0gd`@~~8;l}=T#PpN3NID!=fsxn$de1IU0KZ zXw=$c*y6Pj=8WXci7X7mT;SidIct401H&5F7-l~BWz4%9ZyBg()8W5WOhn>E%-Ra$ zPIc|ghkpJO)Vj=(&Sj_M9qr}OI^F`1egu@B9~*dnsYGAr5?viOZRqTlNL>qel+7D^ z22L+IN=|_#V=LzV9h7hc~b#hy~Ue@r#~yTq<0F-&-Y!+sT#cKJ}Qr`D)So2 zD;j$Hk%Ifm_kPHtDP7Xd^fsyy3}Xpt#Im@^mN3bdnxzP;giN2UmrZge~itK zy~7{a_TxWx+j169#<=q>d$w*2UWxUzPL`jn?C|l^D&mBFXUYWP;j~-X=k6V-i4r^B zrtklhbIGe{zJMCIvVFKGEoMjmvWH(yNuPEl`Y)YRqaU}h=S)S8@kOpJB4Sr>ZCC#5 zrRz19SBmbE!gjMV<)x{%`JFJDncf+mJGJza{?WFz+0FKmKip`y_gr09nigF-5c#;f zV(go!9N+eSqw0jQcR;bKUdk9hHXd;==n8fP zWv7H@oWg}F9?m0?8OusuXR3m2;=AdE+3$^dnn3_kL2A&lg5_>Qm%4^z5G!>`J&NVN z_(&%+H(t(=0yfEZK`{h|JUgDoxaSSk8eHRy)YESkaQa5a4G?p*9ABjFaDL$Fq}>x{ zF9jN@Mv2r?pp|NEW?m96#eX)PyAJ#}^OkzsD1D?pHZ#3IFG0$WMibrE2-x9l0x;Q3 z9*TefI2-4oTnQj!%XnxB0pu*Xlg&&cH=r4M+eraO!0|xt#52`FdzDZA5w6S5PjVmt zU;#(81|E$~vc&(AC4g|O%Q8w?JO>4wQZ>0pvZ>U3-{uq=ohv+n~z^{%7a*k>s%0C z6dfOY%RADF)s$L*aNWWZ(7#+#z;FS83n+xIQtAueGr4=AnpV)BC_r?K4Dn1GqjN-N zh^_65@WrQxhAn&92Vj;;mU6aG7u=aAmWI@R4zVlgDnpAiKCGAB_P_iE#A2>^w&bmu zF&At071uEdz-F;+`hqXx&wc|0Fpvfj3O?xfpYxkiwl~1w<@4mB2nW}VCG2jVY=9dG zJ%s^iUrAf2qa`q~5n>TnL?awEbm6tUfcMW^Pau$GY{)v*u5zHi!)>gri-2I}C3f{tIFb zi!=Mlo}CW$AMvYx0x=y*ha=yWgB}r|j+_{Sk@(;~vt41?RZ`90p7$K8ZEuOX2l~b) z$HP-r%q0cL$;X37ANVjJC!F93#k7l?tGhtNkYfJ=<`tqX literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/LogWindow.h.739C84098534FA87.idx b/.cache/clangd/index/LogWindow.h.739C84098534FA87.idx new file mode 100644 index 0000000000000000000000000000000000000000..af936e590f446e9a0ce8e2e2b45a865896e6e2ef GIT binary patch literal 848 zcmWIYbaV4yW?*nm@vO*AElFfyU|8l`&lr z?S9m;KtTNY=UH*d#g;o_uKxP6O=Q(LJ4a3!$^->JQmAOfOfUfU-mne}W%Ie6@#LB?H#m&ae4<;BmfpQECj9jcY zIxkgsb_a$FF)^`$#TdBw1^A^II3S$M0;;DDGIRIyF>$akaB*;R2!IKgbaUmZ38kFM z{Q^vkFx|YIyuvW)inynO%R^bG2r#k3r1?1c_+iqU3q#HP`JSK#J98TcUZUYKhU}SGW@DAzZRwDB!Y}7E=n%8 k1~It8ZLIE><^Zt9quiSe;ym6?se7o+{F)$SEGqd?keBdikOW@KKxAb-nGAyzFB{0%7dhuYZ$b%YQ%PT+@lq6;q4O_$M4#`E_YgoTcM*+#bqLHQH{hIC{MAlC&sm>G(^# z#;$L80?rxa35&R`th`5%JE;0HQr6@Ul*J%zEHDaS6_Zs-++ZAS&MiVm(Li=q`d!=u%f)8 zl@2+=h(IN%#vqo6HAqO12#M8;3=+gsI@|kPf*}6Nd1D%WZbn5Ip{MoZxq+rT{)JE5 z9bw^eA`}gkF;l*K!CRbI{}GIAsxaBM!OMeGo_fIHgmEW zT7eoz@hi~j1zYLfqgrOi3R;oPP1mxMe%aUyBAGIoN#=0nh})_2cMacR55fqkT#9pL zjIhaVymoILcY0`-*TIZcI+XlMTxXH?-KFEM&HiV9_LmG>>SlUVPAZSlEU0}{jrB!~@25F3ynHXuQ4K!VtS1hD~ens;(pyZV-~iP^D{Hu3>&S!CQ~KcIQz{H)>zLryb{R?REx%OW#-#oR>EFAuV<#0VqZx1@Bb%; zdqG4*-N?39dUHyW*bqY^2EGBASw5=_XQQ IDUL$^1JWp9>;M1& literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/MathBindings.h.4EB245298CE82877.idx b/.cache/clangd/index/MathBindings.h.4EB245298CE82877.idx new file mode 100644 index 0000000000000000000000000000000000000000..7e5aaaae75c54c03c71a36025db0ff25e65757d4 GIT binary patch literal 328 zcmWIYbaQiHWMFVk@vO*AElFfyU|G% z#Z`;gR0z22S5TQ{hGkZRpJZz5>6IZ<|Ziu-MKoO zFE%K)(Vd5Z8OQ?xHfC04Nd`_PMh12kMmAQ4qSUlvJ)k&DC8H!n1z0fygZ1s0HiJWR selqf~F-tLP!c-Nd<|Kkt6c;5Ii-Q=fAOZr|JboX)bktkRijkE80MBe`DgXcg literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/ScriptBindings.cpp.E23B554865E2DC43.idx b/.cache/clangd/index/ScriptBindings.cpp.E23B554865E2DC43.idx new file mode 100644 index 0000000000000000000000000000000000000000..4bbef71a137de22db382ede87d5d92cd34e20c49 GIT binary patch literal 886 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 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/ScriptEngine.h.E0931BF4ECAC1BB0.idx b/.cache/clangd/index/ScriptEngine.h.E0931BF4ECAC1BB0.idx new file mode 100644 index 0000000000000000000000000000000000000000..8ac4879d4025916dffc2c36202461337dceed723 GIT binary patch literal 2434 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 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/TextureBindings.h.4E98F904F8826D78.idx b/.cache/clangd/index/TextureBindings.h.4E98F904F8826D78.idx new file mode 100644 index 0000000000000000000000000000000000000000..5225cb0c23ec08a79b70873182ba67eea8d90b9d GIT binary patch literal 336 zcmWIYbaV4yWMFVk@vO*AElFfyU|G% z#TAR#R0w}%ciQB8ecA0vzTHayb}v<0vEahx4V%x*4!rqi+cmc`cj=YB(cg|(L_b*Z zJtoyYZl~1(bx#TZ3eVUhyc?CjEn4#~)REDYVTy0>ffVf<$Dj3>abCH;bjdmmhZSmv z4VD;g;!L=aJYgf(kx+T_jl6RYm*9T+lwo6LWtL&!WMX9CU}0oqWhhEbE7n6&$tVd? z0TcoO>)SDH28ZVSWaMFEmSxs~nOBsWlL(S7E=n#I2Qk>vEDztP>I?bB$jZP95`X{z D!k2M4 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/Toast.h.7992F998C96CE2CA.idx b/.cache/clangd/index/Toast.h.7992F998C96CE2CA.idx new file mode 100644 index 0000000000000000000000000000000000000000..027e8d20b4e701596f4cd7f5cbf85a7038bcc400 GIT binary patch literal 1536 zcmWIYbaVT`%D~{9;#rZKT9U}Zz`!5^#Kk2=nQMS_H6sH<#hkel4ssoG;Bon$ZgXqF zy(*EADnZACi>JKJlYX1$HEHda_qtq1C$lP^QO$QsJJUDw#+y#(mCHKjow1C3?Q*8o z>tg@2oja$=7+yP;{JMxCL&KsYL%twsm-T9<#E34n_l^b$l8lRUgP$(&<8ZZ5v6-|; ze$%qo|7<`1Q_EJX7Ml01Y~#H?=GD9r7r8R~gr2^4v0oY8|IV^q?WkDkjKjYSpWXP$ zebBSsw74=iX%EoN=T5PmvtanlCB($U#=xm2t|kj67&w4(K#)@0I`w*^ikT1-3s72K zKwcb7z@$|g^F=iKW`_tdF#@F}1tdkm1WbDEw#HAnxkl;iOu$g%K*t2h3<0PH6{eH<&+UI2D}~Jz$=e z0tW@m6MNU|vOe#8A;cuZsV}3i0yABP(?rlj62>#JJ;HUPGD?IA=oCX^bC@s>r-`YF zHH-%{pHT`Nm@o@qjsOaSLJ}r?)a~Mt3%3K3*nr*$;15UgMzClUk~adSBVZ-~y%DS! z1+xa|UN?PTnB_qCMw%qRcyB&9X%zIWNMaV@)DqSbg9(dp>PhIyA$W%3hEgzI8OL|_ z&o0%;EI{}0^D82`hhJ0?$vyniib(F^S5$<#2j($GE=XzsCk6(FTVnhFRoN?40mIis z(L@zyoeZa`nyD6ycPW07i_v1)I$%`u8}pmPEQis+paUf$m<`YFyY#gle%i(;!f7mL z43Dy4PS?G;sRDhhJe+C*YH&~UaB4|t!9C5xsVArhPfI+UhBAgqFjw$!no5|$Rmv=1 zzT!i{zNtVrNgGRBz&s5L3ZR=nDHrCZ#n*TFtIg|J3bdS8idPlpavn}$Sz!&B9v)6f zX-PGhNj#kLvho_R-~&2ZSxpb-lvDqhrP(<9R{$*+H5Rpk8KAIs>S?iS2{(YkipGjo zFugn6rdF(Tczy#IAg02maG(1-O>4H^r}u~j7^=$rh6p!_DvKJzj0E~lS=tccCPigM zLzuaH|JxY7F`V@gls7E&ZDEcB#-z7N0E|~7&Rjc_`QJC1B;=yhoJ3GUDlSSc4hAuJ qKm-Ip%Q6s$4=MztxDZUvdN*-flRqK{*f_X(__%l(coA~k2qplx;NTSi literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/ToastBindings.cpp.02CE1E8043BDE66D.idx b/.cache/clangd/index/ToastBindings.cpp.02CE1E8043BDE66D.idx new file mode 100644 index 0000000000000000000000000000000000000000..a6684d319a2e734636dda493cd582a3580a1fe6c GIT binary patch literal 1658 zcmWIYbaN|WV_*jK!s;B2Khg@Ip8UD%Kl-YUHqdo7xSIeh`zpr<% zeK*<1V(ZGJV2$SYb`ReDD?Ym}PB3<}!UE;Fw-#}GX%_~3snXdYf41#qa?$jshfPi{ z&-_zraxOpL^Ml17x#yb;jU;Qm*#r$QeJuEAFxU6fZ;RhX^Oxy(B&2$?EIuL?lwQAJ zh0T=njq6`M722aEYTjV4UDB5QV41_)@|}&-vmXRKyLMpS<`q+?z0iAgIs8(%-^@q* z_sU&7#S!bhXUXZa2cxFc^a`|{wKVS2>W-S5_2kFqFzye2b8=QrE-G<5u=nOp1^#Du zh3#}NbeomvKRuXq|KdAkcMgZ>OLdQ;E>BmmI>*%HYIC}Y*DFuUb&GR;wz|QDQ@njK z?YFqJI^zr5KX9vNNUfbE?(z7_pHtJd_jexB_`~75xLjt(!llbZB}JCK`?|<~jrYFY zrf-+rRLEYQ;yM(Z4#a zFJJkY=VbkPfyu+W?tCj9@?H6LXD2SSIeXdONbOhjHkI_+2Jih6$M+PJdQDkec*oiD z{GY8=bDq3eyG<^}^lolrb^kigs_dyL^^Du23iyjFbCc!*<6e6DTA`yC?G1Pslo=Sb zxOupx!30nS47%Bvnm&X+&*WiH07?t+2uOkns4T++oli#+U&&YTFsK5hrC6n;G?`hM zr5HGw7#Vcb7&Tc>`4`Ck>112L!=MOMz{bNS0VZJjFWpU>ds%P)PaXy(ptLBDs5F>> zNi!6srWJcL1En4=E&F)HosWe_OOZv93ntH_rNW|u#8YQcN8)L*Xu)|c^Nlx5W>_J` zBBG_Bu3!jrw}_Uqx-t?^OU+9=fT2>NeU%=WVDoxlpSHlr4+YLz22x|#wepD z&Mhtk^PS)Whr&gM3#^%BwB&f? zDVXgdT0(+C60k@S(GnLHmx9@%(wHxz**7}`Xt@x#kN`~4+HH-Wa&wK+fkDT?!odkM zmq&}2g_jd%E{~QFix4MF3y+pKi#R9DT$m`(=b-q9g}scHnvt44%r7vSQ3{+2V2YlY z{pDCA>Q@JJ69+d3Kg{xAPS?G;sRDgKH?gU(X~Befw7Au|brEh7P!-UI+0LUSsxGPv za}!Jl&`qE;1+z{@OTkFN4(66OzY^XoH+i!VXbULLVTyRbagN}D;vB&P#W{@EeDqj7 z^RBB)fUf7|<`sfDEIcqZ+M#sI8WtHXc>#Gfm~}E*N&-qqJXHZzB%X$V2AsE}PF+EH zv(8VD!yFZSVFmyl=As;c;Hf#O`5}0kE}C#T>)SDH28ZVSWaQD3l9tkfDT0L#FjPQU z3FZwMElnd$cp3%fshmWRRB=&qu{DUH2_hgs9mZf_(1tS^wPM0DRd(FV&0*2hP}gSA ufXgr>=ceSy1G%!Y@+_=u?1I8VBD`Fj96bEod;$_OqGD2#D&o@2atr{&E-c9a literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/ToastBindings.h.61AE191277D79513.idx b/.cache/clangd/index/ToastBindings.h.61AE191277D79513.idx new file mode 100644 index 0000000000000000000000000000000000000000..2d9e0c04d9ad5019ee2283beffb29284a5047212 GIT binary patch literal 328 zcmWIYbaQiHWMFVk@vO*AElFfyU|G% z#TAR#R0w}%ciQB6ec9|wzTHayb}v=B(ai3D`i()po9OA|VbYd!a@}+96)PM&%C-Er zPUy$OT30!lJ&(Pc)bm7kqcY#3HF8sycStd;x}sokQ>rg^*P^pbXKQtLewS;JGUBO_ z=FCx&;FCzzVk-RVBYgXY^`C#atLmfd8p_M=aBjY+oa6E23U^~#;_2eb+$2SyJ0IwL zI+FNGzKVx|8OQ?xHfC04DF#j^Mh12kMmAQ4qSUlvJ)k&DC8H!n1z0fygZ1s0HiJWR selqf~F-tRR!BiEc<|Kkt6c;5Ii-Qlq8!#hIT9!yML?hw#43~#WGZbrqrNMm!)8V=wH{8jS8Qqm-LmwloUH#m zlq1)67-h0GFT#rru+hKt7RRY zlGu#+u9Tb}>DWuXQJVKv)8l!?5zdYiZWlX><3h>~}rQ;$^-eREm(mWTr8=q~0S zrU~+!;8I}1CxEpT!SGL~mYG$FM;vHif@mG&)j=yR00scsQiMe2@sA6|)(U4DEI}eI z=`55SZ|I zY(2_IrzPVhjEb7K&wR^hm{$f3C{#@i0D}!H98+Q81ihEobPx)Id_~7ERm=R@~fbb3-clX&F%s27UOmdh21D6E84{{8H3HyM@wBRP*G4`eV44ZCnZUOUy3&Rl-?@Co z7=e2Pb&q(1s~k*cdxk%BbQd5nMo?pfH3sYbmRBB~$fXgGlG24l&h9@8x)S^?2#V1` zR~=lBPXk+vV6dgQOkZv8GHtGJwMB`V2(pR5W&lYY2lt%~^jU^L8l=+TLQU9$2(bRc zCxvZ?0P8sn9$V~9P4;K@Adm&gEVxkaHt&|m@5^iC2*i{A3de{ul369LYZ95^ItxaGa>lO(i55E-+xBUSv4-w=Lf#(NcpCiD!8}ER< zjR0$G45mu5j+gdMw?YAP9a7h!4c7voP_q&}d=LNcyR>B0qY8cx%8)~lIfMuU>;ZHN z+$3-W&jEUabwAz{M+8{o<5aqz&Lq3Kn@k}fC*=mO=#KWE((If@%Nl~z5Mr#y^ML?6 i6*x1RiOAqNl}fo^H7{q{qnr}1q+hckBtU}S2jG9iK=#)F literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/angelscript.h.AC475AED505975DD.idx b/.cache/clangd/index/angelscript.h.AC475AED505975DD.idx new file mode 100644 index 0000000000000000000000000000000000000000..2a84ba2fcddff118603c524e19b81d0d75d40b43 GIT binary patch literal 88740 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 z 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 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/as_array.h.B06B657A6FAA5011.idx b/.cache/clangd/index/as_array.h.B06B657A6FAA5011.idx new file mode 100644 index 0000000000000000000000000000000000000000..e5c4537c17a054501cb77374f0adad6fefb1ac90 GIT binary patch literal 7174 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 IftJ7j2fyw|pa1{> literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/as_atomic.cpp.D441A68A9330007D.idx b/.cache/clangd/index/as_atomic.cpp.D441A68A9330007D.idx new file mode 100644 index 0000000000000000000000000000000000000000..a2e325a45c0fda4d288c45c0e6b48ddc4833927c GIT binary patch literal 1572 zcmWIYbaRtoV_A0(qhD{6#xtc(x!AbD|NE~y#p-5^ zg0bsUm#$sY5*m6$fS<4NNOkuiTkprQ{7PSHvd>vxU|iFEVetk*H38Wx9GVN5rYBwC zQY_<`ers8D#KP?vMH;ys8X|WTTF$91KGx8C|LE22Olx~PS=IvC3wu}aHf<{i6!~B`KR0vLU8#Nri;Ow!=^|ATi}{o1ZQOs-Is4M< z6-x~S3b;RXT+!R=k|+}?lF)HH;STSw8m2c7&aS^1BfK*I`XQA+wI}%G^4oPzztC8} zGUA$btNPoLQ=2wlUfuoq^!lTlVq(Id-xrUcc74ejz0>_V+Lh0%o`jtijj#CLoWOGL zeyZZKWe**{M@95)pV+3tBfia5nB$8;Wx(pazYFAbt2a8$d;WN#tdXbUX_eEnTq8HE zNu8NI^Z0{F(`RVD^`GZ(qF33h;zdWwKVebx5T#Br&9@q>?yk3*_jL0gS@T`@vVMH* z5zHvPbjxJ!IlB$hzl5siUg@@pKXPE3s-DxBnv=IFsE>W7l84^5>F$|!>5ndcKNx(@`@AGDUb0}FK_w=Ubzwb)2*@i|{r*$s;=U)=}^*TdwWp2__ zU~20&kyw^KUsjEWL6m_(wx5xupOIhY2#eGa7F7mGW+p}jDMlIAeU7V~+Y3%;3oyxx zGsx-+>x#*la+>lmZ~zSe0{if~rMC{+TM95K0;SCa%!K94IL+YFWpVD;|GKt#@PLxH z>=Z_pDL^ZZvPc~TTEWT8!~nM9%3Sr$lIFW&1ehd&X4nhc%g9-BS_&~pFfa%MtvI)6 zi}3R9(&J)GVnAsPZVeGRV@6{xm$hva43d6KWLBk*9Vi35SU|t=> zsHMrmBdg1x%Z_l7nTVM*!VUHe_Utetcw{{oJlJ9Oz;rN5fg?>rSmhk^1gRHsxgQQG zD}C2xLQN08D*ykWba7b0$ZC5^4-;;CKQ_!6F4{3@Dyq#=vX^3WMSoCJdw5 zcw{vgG&o_JfjlI=!0_YH6@-NbkE|K186Q&kao7vO+zt#s4i7srb*b2Hj>Ey`j>|L+_SN-Ok8AgjYxxUPO7PL9y;qF+25VQ23 z*B8n0tGfEfzp`r1&)6-WC4KDY0a=C~O{0$GoO+gbXLLE$yxS7;+@bc1#)1Arkp>K> z4mfK5-r4Z&a=xFbF!QU@(l?p&womVo*3#(w>>SJ!)3Yr){twfg_?gYcmAOf`f$kJ~ z!S`(v7rzQ06Audmhdrk~ADCd^0LlTuKF3wg?FA>a1(>*47}#}%b;USLIZb(B()QtX zOK%;tw-jLF21=U=mkXhYhCFj0O$^HUoYz!N3V}Hv=OFD??FgTCp=wDa?FoS@? zprC;X!%PGUgMtJmT=-t+j$hQeBt{+%Ck7`0uvdV@=2T8$w59< zo6eaW0jkzx&=Z0Q!@?D4HYhw{X2YBf6b6MOOc+KpaY4clY6=gEUSL?}B!Xm$i;|1Q XK@5%=@zb9Na7DT@azcX~B+38)m37t} literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/as_builder.cpp.5B991AB7F848169A.idx b/.cache/clangd/index/as_builder.cpp.5B991AB7F848169A.idx new file mode 100644 index 0000000000000000000000000000000000000000..92055c7806f79690b2c28e3ae1e583076c0b64ff GIT binary patch literal 130256 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 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/as_builder.h.00D1D5DB84CC6772.idx b/.cache/clangd/index/as_builder.h.00D1D5DB84CC6772.idx new file mode 100644 index 0000000000000000000000000000000000000000..8de502aeeee9e0696f7190f4de0581ddbb77136e GIT binary patch literal 16652 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

Wd9K}7w}Nip%Hh<0ac6x%dn&)FGK zIfLIvlbG6s(;=^lsaG*)NQoH|Dlb!NlPMvOcwb5BE1~zBCD~b!pi5TUNTF;A^#{39 zOs<6Dvy¨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 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/as_callfunc.cpp.C0CF031BC9B3F5F4.idx b/.cache/clangd/index/as_callfunc.cpp.C0CF031BC9B3F5F4.idx new file mode 100644 index 0000000000000000000000000000000000000000..b226e01d51d4e3a98f2931f8cbdd767edbdc3900 GIT binary patch literal 11706 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 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/as_callfunc.h.B7EBA57BCC1841B1.idx b/.cache/clangd/index/as_callfunc.h.B7EBA57BCC1841B1.idx new file mode 100644 index 0000000000000000000000000000000000000000..f7285f2aa635fcd8a22e1e0b916be47a44f57190 GIT binary patch literal 5008 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 HA@=h>u4-p0 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/as_callfunc_mips.cpp.F43F7C77711AC923.idx b/.cache/clangd/index/as_callfunc_mips.cpp.F43F7C77711AC923.idx new file mode 100644 index 0000000000000000000000000000000000000000..a0db172c3844176db5bed4ac09d9bc1b91cf5f11 GIT binary patch literal 400 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 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/as_callfunc_x64_mingw.cpp.02C3DF7B496086F1.idx b/.cache/clangd/index/as_callfunc_x64_mingw.cpp.02C3DF7B496086F1.idx new file mode 100644 index 0000000000000000000000000000000000000000..d6a28fb0173a77fd561f9f5fb9db0db578b3c006 GIT binary patch literal 430 zcmWIYbaPwA$iU#7;#rZKT9U}Zz`!5^#Kk2=nMOcyQDz2)iaC3O0{ssw2t505a{T7e zjHFHMYcHG3ymiL*hnqw|+u{oj7hkTQo_6_+y11~fUV%(`&G%XvMg<0=8RDV~J_q@h z1`6!hw`c#{v+}E5@9Nxqv$8Tmr+C8I*V;^`>uQ%@klc7s?MJ$5TgP4LBZ^yf-7ZVM z3&>>`mDzq`ZkSnD!Y{_fcWSJ^&%e6pv2^Q{zO*?TJhhmb9By9`W%NBD%%Sy5q=hN- z(3b_QS$j`d6rOE9RIYk4t>ehnQ|J5E-O0}hx-@Ct0@Ky8Eb6K!eNV3}Td8rXxQJ(c zs8N{Q)XFJL)?O!+Ps`-Yo|ABUbMQ6E)?2La^!Dgv;mMpExJ7eB`y8Hd91OszGT>eSt=OVth zb&?CJ|5n(~wioZ-6xDUp`|Fm7Wea9ZH|Oz++1+;`Yv;jJyTd0rA9%-mNMJTw^ShGV ziDk@{(b8*jz12L{|7L8yRb%~q{?$#Z&0FU5FI#I8D9C(r!OBxjj;9Y8eh`WIGRYy+ z-ZraIT3y&L;`+P~b46yc2)>?nY4hUMe6wdfv3Z`J@g+%}D*JYTbHW zD{HaeDI3p5Th%qq9x^_{YejZ<7hh~$`()F5$zu-+m+JQI|0M0(-M-~s=Hx3DryhAa zizIE4w|dZLy7Cv-$NLul73Xd4&HMR_J1OM5LH-Oi$K5608MA&$IWZJh<|Y9HkfA6w ztr$Y*B!cMTqU2&_5JM0|K!6a8!N4eR_?Gai%R&-fOhSST$+;;x0zf$)K0YR97FG^! Lc20gaE=FDez^tkc literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/as_callfunc_x86.cpp.A0DEAD74858CF856.idx b/.cache/clangd/index/as_callfunc_x86.cpp.A0DEAD74858CF856.idx new file mode 100644 index 0000000000000000000000000000000000000000..cb6f92d3ff7cbed1b6a024f6c4c2a59138eb18ea GIT binary patch literal 402 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%0DAYjX+M+xSS{r0tccz4@89^a5T#AXw+l`PDHt$ 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

_?cD6y0vF+Eq6?~@a5ZmSMIMlc&nx@X+B+R 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 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/as_configgroup.h.47769F873BE0B41A.idx b/.cache/clangd/index/as_configgroup.h.47769F873BE0B41A.idx new file mode 100644 index 0000000000000000000000000000000000000000..d860bb94604945bc6a2f1e4f904998c06064484c GIT binary patch literal 1762 zcmYjQ3rt&O6#nmDTH4FKmkXBHn$--Z0R&b|Nr6^aOMw>W<&`NeR>D)oq0r8`X%Gx$ z;tXsu#61WE-Nu{)1qX}sk-_FR=A)aEINjE4af)O#s3Xu#g8uj78Q!F)_nz;Z^PT_v z-zl=^k$o z?`!}3jBh-&e|XQEPy2mqeO1k_v^!}-b8|BuQ|gKSv12Xn%N_IfyW{hoU&?yU&-Gl3 z?kOl;Z1J}DR(`TS{nJNH{yz(g_SI;V@6@zSTW;lte3LO`zUJ8F9d$gTxc`W(sd#6= zj4#UjKw=Uui4SD*!5OWlDZ>s1i&d&3I;eSSXn!<_T^q4 zV}Q*H^S!ZDqZV%UYggana0ubHYwdB8f$Rq#X|=`<_Fv#|D1og(R<&dR_HPVXT6(|Z z5|0C*xREo40~|AuaTljH-Qe(jBs*K4%}NH~uAG22zeoEIj{_k)O`gU8?5wJGrIWqs z$Muu#YjOf9hPBgn4Rj20lGDpFS{4anSaCQ2GHeP?;a9#)VWt?kYKG0D^CID9L3~t{ zBsxd|(NVM{HgKOkdHC6cM!t(V#uz7BvU%g@&x>4LAQNmNRTF zm8$|OhP6>P6-bI4nzF0l(4=Q7PX#>_a!ODEIh>2Ih|&d?`q_l5!luD;(rO_p_181LQzNPA_U6O70LQ(xN}!UQbF|DJu;kfh-a&t^h=X z`bl4+>cI_dlW0-$;0Cpm=>K0NsGJI6MRh|ov`wN#Rf8MGMQV$Z2KVkLLHB#-OG7e- z&0Lik2UkuepfSfoDTcLZEb(xYUk80g$F+_QlS;A5*hrXOMbU;=hQHIFArn}K)`fx_ zCPAXbT>)NL6Vj!)9^jTW?rAz#S@IKU$4D6&h$0Q>Et${&(FUCx2HJp)A_U?(K_%EE xLLhDsxSds-%f!}P&I*@Nd literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/as_context.cpp.E3B08CC2931C1E25.idx b/.cache/clangd/index/as_context.cpp.E3B08CC2931C1E25.idx new file mode 100644 index 0000000000000000000000000000000000000000..c5208d5f200273b34b89869a9c45e435331bcff4 GIT binary patch literal 102884 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%0DBjBS%Pb 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 b`1nt1T1LIX$Z~RpTBp*i7AUnc!*l;10&qkW literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/as_context.h.47F3D2D0DA8CC748.idx b/.cache/clangd/index/as_context.h.47F3D2D0DA8CC748.idx new file mode 100644 index 0000000000000000000000000000000000000000..0017c617ac81e37a6e092522a8f1e6da2b41edd5 GIT binary patch literal 13512 zcmY+K2UrwI6Na}M*d?yB%OXh-41fd$1QByiD1s3aVn7iER8TQsfHfh>oHK}u0nx*7 zXAUPPDqHW$4sBpMo%JHFGwV@TP_dvi!N;?Jn=otmiAqpey1G^-B%6l7jdn=+1x$m zCfyD-xnp;Z?Qrv6{r&wL)AqiH9{TRxr>Do`B74rdUA)ZgKZ>+0ZE0i037r*1GxFH1ql4n&I&@>GHaEwa-KLCHqNd zcSsoQ>Hc#6xq1#% zFs0j^cV%x`yQtxpxmrWiZfghP|!bv&kQJJn#whow9m}OKzp}`X+P!T6|!7!C!|%UWRX);%n|4<#YXd zG}0f9tgF zo$pQddz`wy(jwhGc<^OqUzz__`}K`f)i36^(`i1*yI}l~i0if=v!k=0_Lx=jNRgG5 zk+kk+#*@gK_lis2`IMKNJdL}hw8>0w+hj%2!cRSl9IC@-o^csd)&H})w|iBJ>8PbT zqYpk@Y1`T1q=E0dmKiq2|4d&ns^p86)8$aVkSnekS4;ZlSHH zX8tAjH$PhK{8Dmznrmjwn}y95ZkhJC)1Z{oFW0z@_S#@jc`dHX`M^nWGh?ofX!9uQ zM%b#t&n^}j-?lDm^FS68^hd=Bb!lb5?&w^P;%diQyR-ObcWp>!sK}ogAw%rSwDk5|y@0)n#{Wv4HUE^}`owMv-n{@%`ZN@Ci`rDx4{ZK@dH zYL}nXtAY1v$L!&E8#nk8EW4NEJSeH#oKEeQT$yM1eRc0MuXl`bP8Px)Bh2mFwf-}A zlJxA**5fNL^tje8>C%6*hPbN3HwRceN|G%$9kb_Pt?9ilt@?%zEip;IW0|?{V9?bQ z4`vmYczdY+>e4Uf(6`Y;2N%YqZfM17t2{rS^p$Krzca`pXz}bdz0Q`t`r-H@>22Oe zsQs%Wn{v^6Y}z!lor7D>|7!V1)mceILz7m~vm?f4nMx!VZ^!R*&~=jtEP93{0d6@e zZaF%rVUlW6Gl_*nvJCiY3sR?m;{2x)IZJ{W5;Z&l)f3<%v6Sd@3IA7{6c=~Y#GeVw z7bE4#lzB3HHH9$?tO-iK zxeMRio2p?M=q&@Qx*p|>vQhjqC|+M+3RLY96uX4RYB&hegJ6NG71-}BW4tW0*7h+J zm>sIBjD#v9b2W5PbkS%u&sJ2}=tp4GO=E$%qUN#O^s$^rnyQ-Gq^`9;1sE|Z?2LcQI56tR==eW8CnJv9lW1f@&=^tb4dA+rpD~o!Vq3ut-!D z8VQB?aNQK$em&f~M^C?69Dc?%wy4>tCv4Q?4|fdoj%f{3bam)^iyrOG1vUj$mznZ1 zvr$6=$Pz$_?M>rj`Q7Ex?mkYZtppZ^qW@fl|6F;`BUO=&QDVs@?>jdgyx+;!Mqo;m zylAF)(Tq=kOps+w>W7dXNNRHa1+dK0-pn7Nh<%8bPMxYLkcACJ$FN z(m36Zl5O{7=Q;1x7igIH3e{;H(O={fsD%vlas@lOVf z?}CXM)_}npFeKHsuhC0hcRLqiESZZ>xXMd^l~+AA#54VPR!?G}2a=hZCk&{zZ*cZt z&{!FZk?_sYTk0){|Cbo>x5sx+{_S1b{A&JtssDI6+okDOC8#QK7KWaH zP&r$#QN4u*Z=t0c#FA7m5A=K2?!uc1a+ao1<%3y1@VO_Jq*@ew#^%PPcM}CR2_KPf zmGSy~wEXn^njHW=-_ zlj6M-e<}Mwx=&0=dh#b+F`=N)Xp$SI?KTm6}L-pvnUmHHale@(=E?G1Vh3USJj&snAVP z=*G9~C{LoOIiTkivl4{k^W6KwAG*6MU)f&}hP+Z2(KrBhMps#A# zqOkKTV~eGrD8&@0m!j9NJYr~%W@~y3s@f^A&Zv3B zl#ehCRD(<{rh%HicWQa+ev`rp=>ltus*h6BkGS!TFc?vn;(aVB7^Rb|&JdU*N*>CT z4`uv=7;7-rj{39LVqDe3&lC0ttUgNiOBMU2Je&Lzqb=_W{eZwsQFYHzanF&z;k_W;%ir+NOd}-jeehV1 zoI?U@jiQY*{Ye33LS% zS8yQ{OHxfq+rb7lTa_!Y4jAYYYxs$|t6?Fi7Q(Mjc*fq|N0;cnIWA}WG_eZ7tPmFi zv7}fNEea*pBNv|%SbvOFYa-N|Sg4_=qUWz!d9L*&-*aP5oszTtnn-8B^bCFlVo8zm zUvKgn5S;s`oUPKRu7c_+?m%Kms+$QDpT=*tJuNT~Z10V{;Tt($4yLK5{aVJ7 z#ZmEja<*2}qw}CVkE@DUQjeTJMvk0&di*tk$uUxen^57#7uIbc-S%t6*ZqriaH~J= zroci_bk0yXXUN~(VAbza74>$~-y!$~}RZqo&wRQS9cZhRLeQzc%1EQQx|kZyI>NK8r!k z2{1l^3F&I!ml2LYFa9|>>jf>IQk8pOU?WkqQD4}Ihh~47zh)sc;*wR>VdgLHClm{8 z2uc<*VIkw`e;a8Vle%$Sch>A()%{(?a<)zLWEEgkf#*fBq$hi_*tpM5L+=uS1!ANe zL6IZyz5Fmp5C6)wvy!&u`{&K(A_EkiGZM}jnW>?xqHEpK)%syUjO*8)r2=b(k_4G5 z0l&AA1|#dfw}x$Ijca_(woJ};YdUlfjP4-}5liY&wt3m?3p1Wn2&@4HN@0o=TugU? zbeGm*GSJfS=#2yBl>#$E)j}7=LKnUQ>;dT>Fr!cb-4mNxT+4VUux=>IZefw#f`68= zs@PxO+u)!!ZP&-1ek8CFsM%~NY{o5fkZe%hmU$)NdY7|fVxI`C8A@_Ig&a>VNd>)B zt>rz};-2-ej(>BN5315-rs+5UqYXy?f;b1~tuw6Y@=Rc3P_oHD*o5giQYy%k!>WNyj< zXp_xe32Zp3GCfq89{lN#gW+*47~;5B5|(hju-Zgoj5+vsF#L|`fLJ1&XgXh$6LqVV z4&3(&-kC@SqwWhBegQt?#1eJWMP1ai-la*MZ+;Y5du%mVN66LTn`$EHC2E}~N7?jp z+jPeBi@=;w^{0pMrw8AjQa~?7JSk~*Okr^MgWEGxzY0u+s-;efrA~ajGC-OE0=?wh z|7+;m?c3Au0_%vPba!RCJD&*)%ok{0@^U;=OQwfTh<;c97qi1H96=qOK#0?UA+b5~ z5Szmq2;|64Ko0Fl;mH2)v<0ReR`%6n#vF6m_HRN2jNguc5i&{w2-abBkD&{vPPaQp*Q+3TlLXI#-Agw zVW30t&#BCBN5Lq4+HLu5BJXt~2W2!7xG9OJ&Pk9B#2UCs%_M3jt2+v#L8)ezzZvY* z%#jR4_OQ<)&ZC}rwZCLoG<&!Tc+`9_%m;yvdBpj!4#GXEL2M80BG4lb@jUd15RW_r z@z8_hj_gG4&@SRS@(`}Wu@n&lVE|?+e?B~{Dp4Rexb?GJQ=)cYVo#`AtD)KelslQ#w7U7w3(ZBX`9x; z#B~r!Op(Vq2A0Rbj@}tJ2(up#VH~JR`L*E#X2HW zB@aD6))7G}dFV0GBf?Yi5IePh^=M>^o{oH` z^|I<^N2g4F>#y{;pbU`T_E+||poN^@2ABp|YOM-^rh%4POYs2H0hYvgxOkvypcNfo z`0XIGLDrP+@Y}(v!B&(Y^V=b2L#&A(@Y|v0Lv4r!@!P2|RYv;^znx|`&4JDY{C0Yy z=}ts^_-(XZv;%<;ej8&QV^4{1$zzw=>y^jN`M3G@Lv{!!Z&f zaIzBt#~LE_CJ#|>;Fw+{-Q=OwA7lN*+dunD3LPE|!S+wHgm+Us?U8^RI67YgDl$x~ zb}jQCerPN{(N-qe%IfM83&$Rc{F~|!|3;6^s73vZvmkUQr#s zGtAgP4W3d@bFH4Q1)gLmDHr4YTMKq;!9&Zi4qC2*ZnS-I1^-phI#>c)mTjQi294?b z&Ls!I@*p@<-pdV#!0HgV5cuVWtH3WMp$cxu1AZw9oN_}Y@JmSp#0}4YUrO2&3E1N( zh>)J1mKIYS1tjxiCo+#UL>f;XqVZTmMDXMx1dkr%?qpx$pXb{sd-gPZqs724LzmG&8$BZJCJ)hW^oWF;JVdzBBT{Yh5Y@(> zi71;qw7#Q9#Mk7ZwGg9;#F{*`;-g2T)Z{Tz+CAu~cVIJm9Q7UX5B)U%D6ha)5LuI+ zh&9?pOidm-prQxSG}#GFqaArP*@;J^U4+o&AqI_o61g*Zh&y8)gw13p*o=0OFq4M} zGkQd-0-=Yd}WK}}-LI4B}#CMhLq*f_#vvJ+g!8X{084*_MY zAyQ=W&^ZR{h~St!1dg!|(qgg`EXEolASMs3y66$1FnK5e#8^mz$zD2QfnCezZfA}7 z(|5A$Qb1 z6SNE~pw9{z@mm(>oCIyPvbZD|lmww#hGgiS48tj{JLS`KUCzv)^E$k_1SUyfGCB@v z49Wy%`J2HmfjN?a(pnr5YwEv#&(9s4xNVKU&=e_=B9Y>rh!Xb(o9TP=ENu(R~h_^{kbQ}9B z5^eGj(Z(7g#wHJ8Z1f zCF0xIC6Q@UAY$6sfC#e5LmV4DBD^LK9fHt<#G34MfRj0_`H2CJ&Km^dOEV zyOU{?8#-xL&v3}kfWaC5hekhtWkg3xtbufzY7m`9yNIO8b8EbLSxmu`mpD}2p}Rn6 zf!|&PehI`n=*z?qBCw_qglEtrLTd6nteiG~ZT{!*Ce^0-6fg zVUcfBhufBpT;hIV%O@P!_RwCSw2e-RSVLspRD)1AdPKfWo?`u7l82XXe8r)u)F}8579=_`mXh4*4?;qyV%|9RJ^|&tEGR>HS}>NqeD_iiRYP<(r!aA)r83^`CQLJjjG>OD3QfOa!8 z??+?O54b3RR*Kcf_Ps4`^-q1EP56Jy$8C8ts?Z#0_w~&GSm@MMumGCrK2t3wvTsKk z1D(U#wGNxrE333IP(s*o>xovYM(=h68l29ZoX1tTG zE7z3)OFw+-4g?GqH5P&r(pn7$dP!?)R;HNt>pT?b_)JGl35{*Sv~59FOFjn!EiC!t zj8k1U+K&UumWJiV?G6Zu7!UL{-$|<}Kh)q`I1rp(Znb~jtRW90fFNB?>Ay>dm-MK5vEnmFYlRXVk)PCr^7$}Dvbu1!Ve;P{y zI&5^mmv%VkqEi|W|JrwBSVoJ~TN{8D)DcrUsw^#2HUgbBD_Z6sz4~V57N9Sp_xY5K ziBBcl>K4(56$@8i+xl`B&~H1;I={c~b8L4e&?i2x(N}w~2f$?Uuy~}{|r1d>7ey9m3t*ArzAJ=#-+i~f06%a@~{jt=b%vtvp5LKC0 z;*qyUKl9b@Xz|@Rc<9YJ8UxAegfNl- literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/as_criticalsection.h.130F097169824D1C.idx b/.cache/clangd/index/as_criticalsection.h.130F097169824D1C.idx new file mode 100644 index 0000000000000000000000000000000000000000..bd7cddf858a99f76a98a757ee1191ba19f5d5f06 GIT binary patch literal 1670 zcmY+D4^We39LJyc*?jj3FWWPw8~@IwV$-N|B0&ZTb8Ors;BMp3x!_{JfW;8lxR_E{ zXW0o#WKQl#IVV!xI?VKn;5zWq>hLU1BQ1~QbcPogWm0j+_2+p6?+lWub zzwyKHL`vQh>4xT;gU`;rTS#Vndu5}4%pZMWZtuw1^$iWT&yM-OPrRF6xN|Z!vAATj zy5@`C%e^Pw)SDDfj`+X4p0K;{M7{i2a%#Lk@s+mm!-@M$eZlIwlIi!pEzOzH+&-l9 z4){)?;~f$snYn2T4W-2Kp^Mg?&*)>Nl3xZsNjfg$b-$Y*>6Tudf4}w8cD^>JJ>dU( zcyU~%Vp@rB*q>+E7MRqRUYWYnF}ue#sTsSWS@;tLJ4ZdpyQ{uJMQ6*XP`ZjH+A+bh zC^{~Eh?8~3B5rBZ+kY>8*O7YpEuof-c++zPbCBM}y3}BvTadJ`o}OwTco~?h*ecO{tEFM2v}gZ|ax9NT#ICff z!V5${Pnymzj?Q&zuqtw?U1DQw7|a8|O1eE0iGDSX0JD{`ilcQpZ)rcjkkLahhT1i3 zjS8Zf{B?gnzG?q4f*CMZvXx?MXF6}>E3V$BW(g!OVv8an`h({2+|XMEeHy$1q8*Gw zY%TV;*>Ou_pkIa~=&=^C1*^i#gJZRS^Y(0gS?ZV?^AKOolxrY;_MKptaijh_f~8Qs zm@O8opT1bC8?IX&B6vBNOV|=QL9Iiisd*&b)Hz-qp|=PB)ME(aA1Uw4$#A}$SfM@1h}J}2)scOh@y8Rzy{v@|N7#I4cp?t_4HHK z+FZZ(9XhIx(zjUUl=+>BcZ7h7q4diR;HQZCTD zNkU1{;LVdflqc?hbvogHQ31xOEU*oI^*yGKJBT$?w1KVMR&f+So_Y(YgZG-!^9wI$ z>ZYl8CYLErvArw5y1(D}BbBqbEK!CJgC-F^2spiiW!-BJtsA^Yy|cM&@zz(Fvy=#R(N?}=gh)08QPgK(aRw$7IRD}Kk5F*HT literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/as_datatype.cpp.E0A62FE00E11D0A1.idx b/.cache/clangd/index/as_datatype.cpp.E0A62FE00E11D0A1.idx new file mode 100644 index 0000000000000000000000000000000000000000..c4fd413e946efd064f8680266d82e397f7b2ff30 GIT binary patch literal 13664 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 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/as_debug.h.527CACBD7491503F.idx b/.cache/clangd/index/as_debug.h.527CACBD7491503F.idx new file mode 100644 index 0000000000000000000000000000000000000000..8c7d77bbf29817edb94b301c4662543ee35a1202 GIT binary patch literal 236 zcmWIYbaQ*cz`)>~;#rZKT9U{DWQzcCaY<2TGLSw7#1(V4o;}Fhpuoc#AbzR7oXgxG zqC0GX1XpKXzKvDG@$#y<(@!Wj*s8a2vHGaW`&^yy?q1esIW^BYP3up&#YtDT5rPM5 zrlg1zx@0CEk$HfklFF+oo`4D|7#U(%g4cgGoSk|7P#?bjX6BjWcYbFaH}c6RhxB)G z8TR_fxihD{{|a_-aWV4$X21X5Ti1b$%X;GCGI#Bs=Ss6K#2Rk@w{_v#uC33yeTLQ) zbn)H2en{1xC$bXVdSor0F?DzAiFcY8E;zU$as8<0w$f8A8->2+2))$*U|2?@y+qvbjtuOvD`D)EGIX#EWz8to5 zJbA3|i!bcom0s(P%Feu*(mKCWSYgfXKOb15gT5a&V%ghobsKG8GOJ?lj-SUJntmv_ zKIGHsdmi7ieO*${l7PsOkuw$zzq8m~8@YYMlcO%~*?j8x%+!k5Htoq(i7-Dbe?!&A zoi`@O-uwCOmhn3;6t4NA@5jltzUj}N?zQx8;-~R*yX;u>hvn;0-)8?b<@{SSss~QV z4%qNP+SGe}{P)_{Onv>W(}AnMiMtrTDfVmQdxyuo`&(vS_ZeABH{8uR^~I)L`p^lN zZX~XqIPSMGPrlr8X6)m^8&)Pyai4j*>PpUow5*G*p^H~0JfECcGGVRdR9f2N{O3H} z2i8p;Ftz*P)D!j%^KWiWvHo3oc+>a%ZMm{xI~{teW>G zO_=V!GJ+g1$x}wvnXyonLw_ z+yH~QxExx_VGr93!wj2faAEu6-#)Xu{L281yg@!p$cLkBZyDYS6AfPe&xfUZFIoQO z54-XP!%V}>wtk==6ym>@jUC%7F?O;6`g8FXn6QQSpJtfm>|eM&=-;0%c>Zkz4B`z= zLd!`QZJTMBsf!VgEZ>lHC+qwQ0}SL1T5wyOcr#iwNH%u)rRC}QUmBnfZ;*@w zlW~-7s$r`06Z<^wm$#+rYYfoD8*F0zHnG9B&w=H0;B3-Ac~DiK=6h=mFoZWbhXT)` z0k$EoL!!h-7XFrh?m)uj^#*9=4N9P;gm2Vz!*u6H^}1d?cTUp_B?cJ48)QODCXBQV za2;S0Bh2~yM$Ma_eR0qL{dj{y5LgHzZT(&Qn?(b|QG>_j{B;!u=*t@%VU{DTi*2Cm zKxc!AiQff1`Ml|@0e0dI_A$#oX0v4iOD1s6;z(|%Iazt$=MB)zo1}rjG|<^L$aRo& z7LDOUs&)rlxMY9^-k=c%Ho_>|8-_QWJ25S<{Cxkhzg{yy3vW;hEw!+x?QO%`kz$%I z?@f7Q_EUYN<^jt;YPWaiypx+N@ARrDERVW-brXX|y$Sg@p+K>>M*SAD-a;V)Z;1YP z(B;oRa|fE9&f?SA)8eEp2{+P$&xLp(tGO~h>|!5M&`g+p)6KC2M*1FPf45$BXVI6iTA>g zy)aT}pH=@EhWyMG>yg=7^|LVKEQ}OJWYt@tu@wf3Q?}}vsBX2(0>I zY+Q_kg$Y^pb-43793yc72`wO9z;_sOEcPv0ySQo<`FKc0pf$<|H5$Up{ zrq_`88q!~M)bupkKaCEOcq7#}(nyI9(D(yXY2QfuHqrr7{*cB$l=4Hb*>@c)sWm`N z|AG4aKy9+&ZpwC3i@*)Rdl%%t^KT!l>EpYP?P zkc1s%uo$NN(zc$4{o~F2dn<^~3KAj&n*If0Ul6Ct-hU#^#V7Xze{K!ekai7ui>){6 zo3Zz1>?^*o<-MshYfc#g`G_^tr-p{h5nCy1r2zs*O`J1n*4SZz+-ypKR|yCf%C#!= zH=ycU?(s`783`5PE2B7vrF zg62&s-UiLvV5so)n!X*Hx2t#$H1C0-LWecI44TVSTmj7$FjVL?-+E}SRB;tFSHV!B zn!G>>An4W zE9f9F9|T>+*EGExn9Eh%0$B^RNX0yW{12cgiH{)vBP!0oEJIF0)2p$6HI5RK()26X z|BA!|zl$$)d;RT5u1(Fzs~N?1qzx`EQ&z7{%*bu(0<2uH4m6|9K&Wobu@t1NVktH)#a-mAR$#V5&U)>=LF4b` z7COFALJ~^IP@()U7yRi-|8k2mYkDuxOOt!LAK?AKTTDdL?_l>k*d)4X`dy6fVlRoa z3Cbo4UO~_b6_*iQM!aSF3W6$B`E`P?tMV3tT2%Q`ikDKQ|2B%ZsrUzqexSDe?E1d@sG6#%(0%uzK)E zFg=3(MEj)7rw!}-KN3>q~e040b>dC+>8JLA@w(4h~*BNLQuFa}vP@fDMD2~ypmou%L8Aak} z)oYn|E%O)0G`+vu=2v_4>dDQd6?wIy&Q9Y!SezT0`DIVS&BU))gxtpcz;8c@kY>`3 zSvz)qPt#X1zf~+kd|%UZnP0BN!t(`adW=hqpBz?oteQT|WtgAHy*M%t>nb{G`e;1b zUo4*|0RX1~e;IiS0WJjoa(bDNWWoTE4QagoaLI>$G7{xOTR!Y7@fPT^1^UTIv<2F> zz`hcfKvDt&WF#twq#Ona53lj^gPeo`;y5&({*qc4AR|j7#EsBjXokiM1$++q%X3f0 zI2rp3W!8ALf?Ke^+|EtRWfSug*%FVWjQ_+-ypNH6EI=H$#)|-QgawG>?zX6;?`J=N zIGz_@CWgzznJrm)Hf2epJ;jH(-cU=q#D{+T`tH5v|MunPJi6cLC*=OOqJ&oTq?~^Z z!8OE345R5^QT!EE@BxYssJM}mM(QiuKcx7fl)v-im0$XO?$?hSNDJ|4Axctqo3Pu& znUuAjo%rzwA8mIuEF->Uq_Z6H5MhT%kihvbEHLM7nl~VXZw=3}NGBoC^b3StAj(v# zNpLmkBIPxtYYpiwaV;^{s{Lz8SS{%;<;}#{tjZq}_D~%^nZ_oo`Dh9?rch-*DKspF zD&y^<#$Bp>KV|#Xtt+FQ%4n4Q{sG$c09EFDjGB(oP$@q~!;jHuiL0rxS{=WhvU+v= ztJLEvHOux5G_-+slem#aHPSv3H&IiQ`n@I^-lTr7nVOna`CZEHs^5D+J3Ua>^N@CZ zsIDi288eu&Ul}YcgE{x>rMJdE{>G-|13GDX3PCBvRZeUXF)SiVWKSglsU%p+Gl+MF z%)d2#8zI|>yObXx=!iOAH8E7HjOH&9PG-bSizls2R31=LWW_TNR(E~>1*jQW;Q#itygmILa+AEV?LRn}Wg zQMKB?f%-MbYC_W+X;7njkWG{{sr{QNZdTX#fcidAzyFY09;)BZU^s&*`*D)dlgvZ- zFik(r&}rr>@kK^2O1Z^j1UxZkQlcwQnn9cr_}1jz&?6Ga1) zDNa^%%RGwnRD6QL6HJpQc7eeQ5})?7?j8EvhM|1voLN*-@-Ly^moP*I@B0+rmnrSL zgTMT?*SUR;ZcC}}QmP~!D=1qbD|Sb28hDm<7vFD)J8t9qyNPtU&j+iYqgOrL!E@ke91MlB-dMMNQMs)@N;#S5u3P(g zr^+|6r#7*P!Ui?{1T&ss;X)&L@Mp#g5{rBgS{@PBBK@@LStuwAbr)Vi=nnAxhqxBa z%3U8c;o3D595!x93KuqB^Wk5kADF(Gz_XNW;*+g%KFbMPuEd-!*WS8tCvGCo)9Q$4 zoeWM^-A+C2G8kAn@u{UV=Lt=!M0Z@Kyfl$B2G4`%oz6wmvjE5f-cnWbp(!8gVx7DU zhoBI8OS}b|wm@Cxy~Pj|LvM+*5Y9qM#dHb5OUNJ7wP-6OxKN&F;FROpD{JS! z%uTm~_*4+ZbdM8uT&8Q9ew-PPvo7MG#00SA(M^EZajSj_1zti?Vg^<{4+rJp?jn=6 z>V+hzP^M@8$BSP1u=s^nIML96CN!XzL`RKt&c02^Eb%Sme+vakY{z5lc$^p*TuY5E z4DxxEFJ(3IUyV8o)zI`k*nbc1EE;NhDl@0bQfO9l_v$e(Zh4jKNIi3@X9i(@3-g!u zOZX^y3cz|Xb1PcF6$#;6=gs2Zx`yC2 zvw8csbE#^l~$rtm4(2i(Bhd2}kAsOe-2ETePF_b`&9TG4552`^cs3 z!9Diio)VYhh*Fi1sl*YLDlQ^@iby}PbVoiNx=r=y%uVr1#NMuNz0_{p{$*Zxh{Qw*|m+0Wb-d%vB2p+=ZcH ze>dKK!~KI}Fq<1lJ@l=I!J>5kVD8Sf#?_Ouxt2B{&jvI=7+=K8-!A{}SIv$d+la?D zS^Q>h{h+$rz5dHF4}*v{$S~~SLs>KO6g%vog;=YK?bywZy~Pf{6z7gd_Q+YzmvWi( zy-bG4HK)bwSvdNp~@!ZQCHZWnc=PaSzeHnh{eb~;?(p)*^i|FZXD z4*$YR6ueSZzaMe%k2qFLMbj5B^8)6)&JhFfHO?S2oPo}&p8(nk$w6E7TY%gG;Uf9A zJi3JyPGPvy&QeYIuVbqrczvU_}gtkH$A;OkXFNU^a z7$KsBQ7?sFrO;c@HAek7^g0f`1zlt0>>2;D3Fl|jFF>yg&|Bg@76)b2+fctY zlpwI!6~6kJWTryOodw!id97mAZvb)wnC0p_u9(H@g@1<*4f5SaoNSuq(N(i(D89=t zB04UZgju|u;);`v4B0Yi;9dur>rr=c(pDZ< zOvSjHn7UOjA^}CDhnT_tnf{pGE1>IU{>4djQn2tz{4x>{JFp6T(5Gg?vbR6AbNjwc z*=?DT^O}VDW-^5}%3=OFEJlo9p8Th4$>^a)RMS62>{ApX{G_IDLH=7%4~h4qp#7+q z#49mdi9^K1IWvm=PvRaDpT|MxaW8?l&x!d@=a&C`#~JRi?qd~GYDDghG8^L>fjn+X z!qm!%a*x|8F2bHg@<#1zG!I^W|LYxme|7@vPI=MfxT71q3yc#s+5NLKx6?nmw3F}9 zb>e$nWg2e~c0<}E&seEng-kKRQ#yVAN!-jIyfi%lBq%!hs_Uyp8D(C_uNx$qgXbt{ z3!qzoub2tH{RD73@RIlnKv&e8slNdHOO-c4_a0KNmeFM$ow1Hn*W*VN?!0vJE{eaXaeUjs{6w ziu;%1$HW&MPZ46$RkJUoF@@CW23lThbbIXC5l6W0))MzxS>|v?hPtQ7vec>{qaMd3 zqhi&Ys7I5EGnjh@b8^siEgRFLY!i;~O2AQ{3pe@TUN$Jd|M3yP;~n!ZWYE`{L|pMm~7E{h<;*&FC{76wav z4#IQLOX3R<^0=*H^92|#aXk#FhfyL(X*|flU!j-8t&p`sKdCL5C@>R62rTS?>s!Z* zDxq&#(|@1aw7sn&RMUHco=irgv2d)b+}-hDJd-GiBzZ`bja;*lm-v!HZ)q;lB(@{U zeYV7PD6$SkOFgYeUiHW*aU+6_$W`K-2;D?(65mGXwu;+OSR0Cz@^*yURe2F6Mc6~y zK{56$mRGHsUW#cc)}*`=(@GVm6P&Ix=S9R&L=;c7gODA>Lj)T~=1)pge3`gjR`0~? z2&q%$b%ZCj&Scc_B*-^SMp@2kP*O;h@$Hn@{})Ht)hmp0>RYb%PiHutDNJ}ev!%;m zdF7VRbKPG5w(=i4R10->dER}RxBi5mrcZO7rbK~dz_1KhrDZJ#jAyhG9|e&|L7eb# z{GAF2y$HHXTn((%po_#Uz}NypCC-6;a^PdqGK*mV&xl2Or}4L6K0m`?kG#3!R0(n#N zw5e;R$N%j*!IO>NI^`z&x8Y8aoKK%hG~VgCJllu*prR0|9j^{u}uJ4Rj%& zQ2g!<1W%mg*ga%``$qeOrdTEhKM$E!@y z{_%#*ONPb7p7%8B^Uyr!-MCRt0U$+Ix<>v=3$6raF^*AR3&2{nIM@o%R(W@B)awAM zQ}N#b{w=E*BY(vOHmSwLb_lks#Y7ndWoj`|2|=Y=Ok9NEqFPK`h2W|zCf@J9Eo=Y& zljnIjzYo!UXpn9&6S-v~CE>|J(OIa!ly5{q8&yiA0MP=ZIQU&CaF@)v`GY@1evsut zhWXNSlgBK)XyFh1x{U886)zhN%2u#rNvYI8;k)Czxg?Snsl17Kg z@d|0TLh3AK`1fg?U1nAM9UC27PMr_89B+Jkr8DOR^DDZK=d`4+E^^)_mBpqq=S$E* zrAg-&m6cumhs-dolvSsu|A}ut?llMMo7P*m?6B_&{O5&r?`zSOE4{hZH2mgtZ_#E^;r#=t5z)61? zB|NxQ&!r)`vY6oy5}Dst{w(~_d-ttBCq@1^J*=L;J$00q!W4{;%1g1HQ*ZAyU_4r2?Of8Q4+US z{QwO;K%K8KxU;5Vjnodi+TdZG@ElvZ1h2GygX5;vf+4Jwh` zgtR8L|1IQm>wmp~)~3qa(BL*SOpe!%qT5kViSw~nzT`F>Co;m0pO#*r7$+91wat&% z`$siKm*Ut`+*`J<#Icnswi7SAEO9hWNDL_=k4vlGO1f_)u@dhfF*}Gt)0U8!5{cU< zzYcPC=l;qI^dVqKCz(WFr?J=R7%@zE(t$h4gCnnT;@&}U3H{O@5nK{?5L^;>5L^;> z5L^;>5L^;>5L^=1{X=jGeCm4Z+^F9RuDM(F@owV-g*|XHLSDI&9O1Wg$jh$ccI446 z?~u3|W3N(4j#&9yaj!}hrxPt*y=UD)Ja?$KfF;DUM8$>Fvryg&iiC{&t9=0P13|)2 zEsy>=hHx~amW+9$pkUZ_Po87()IlthKbiR_b&$9tb&$9tb&$9tb&$9tb&$9tb&$9t zb&$9tb&$9tb&$9tb&$9tb&$9tbr5*=;2PIk!;bvMm8uTKa1K{mM;q$OIb4DFec|%w z*clOjaJA|UdMgx0Il$%WTak3^o-SD>ULs?(R5h}bn4H8$X*B1t>v=UaS7TDG%CBH@ zMdFPYr~9A18rRHu&Eamto%FZkb)RVy3lrX$b8ZZ5VV)BIZ~4zFZ5FYQ^%R+>$BT*I zmqc{?ljqY50A2vxg}!R~Lg29w_(;4O1g%yd@E0S$Vx+u{X+XmoRHtUg{q6GKHq`(1 zd0FPI_S^hJBLYT*37&$#D)1QTBzHA^6d2{?Ff{!;M!u7Gn>>wYZd;kJTw6JV<;+8@ zC2_>OMIVp$`kQajO@eO9Y+B)Vh;I@G3$cP*F=$nB5d%d`k(V)0rsAUv9F=&|7;iS>@P;;?mW&M> z8!Pv|5rs9PSfP^Kp<-JRjuX0+KX%spBYU8ST$jhWjdP|H{GlyyTP3r3{%@*gyyBSp z?Dt-qJ>2n2gyVl5e{A9x7Z>LPUl*51`L|u1zXJW{2P-SC4E$mY>0*oM9O?4f%-3f) UuBJ6FFNiR4^<{9 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/as_gc.h.99128ED2E571142C.idx b/.cache/clangd/index/as_gc.h.99128ED2E571142C.idx new file mode 100644 index 0000000000000000000000000000000000000000..e133f83c3b4805e21fc47acad973b65ca09e9ee4 GIT binary patch literal 5554 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 Q=Zk-EoR9ubsgdsWf2~jw0RR91 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/as_generic.cpp.C80CCE51026AAE64.idx b/.cache/clangd/index/as_generic.cpp.C80CCE51026AAE64.idx new file mode 100644 index 0000000000000000000000000000000000000000..2683a3ec4288f6d2557dc10b6f69e8647553adeb GIT binary patch literal 13658 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 M4nby?VJ9K~2UojaG5`Po literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/as_generic.h.53B17A96528B62ED.idx b/.cache/clangd/index/as_generic.h.53B17A96528B62ED.idx new file mode 100644 index 0000000000000000000000000000000000000000..0fb377ede9bb1632a297c965b9d82ca0fbc97a44 GIT binary patch literal 5052 zcmY*c2~<>N8@}HanYqJdxZ=#P%m9LV*)&K^NfZzmV2DK&(}I#s3LRt_*@UAgMv}Ov zW@4IpD$QU2OtV}NJu0}7=7Jl7C`ZAC)RN53@&7LPT>3f3%i(#y@BQBWeVk;9h}b)j zVZt&@#o06Fq*^fyqoMySbMmv^A`H{NAHx*a>|1qaHv1-TeDU?@(n5`DM`G1f!6ZI{JUAv#V)Wwx`&p*BO?<-A5eh=L9%r4!aZ(=MZ*=cL78Rnh2A3fQ8`-q*u z+IrBS(jPI0%h58*-ajr{wqDD!yKbjr-3Ij{ViHNRfq2=0Z+|g$PSXgi6>jHpxdS2o z=&hC3v7) znrS?>9k)ZdP}%lZQ&VdFK8+3%SSN@lbCVr$yRA~asMu{(u$uLvu4QtW_B|hn%fchf z+qRU42&@8cFC^-P#DD{vhcpLgRBxIfu>EmhHaA-XackFz?>1-cG7793;yf--Hg0Cy zd_~pc#t4DsVVsdO%C~K|*G)_E`R5&hB@jn*(X#DcU%tBVVEepj0;_{KkxO*K+s1?X zZ%_7{{(-=Uo7*zVTX2Q-a%JT$r4aS;;S!Rs=RLq16U)6c;61{-SuD&6=i^Wz=tor*Knb zzeiLh7rKOgwNlM`Q_Is;>AIc|ET83Vf5PL=*|h@eh}#pni4G7qY|4GS{*m~Nz`8&j z&&A7c2XCm$yYu_>odT`fC)dffYIX>2oT!g?IutK^6zSELhO-v*oP7+Q6|2 z(!YYpt|dG@))~_N-Fbo4;(ja_D~lig$J5v3^YXHeb;o@(G0Pd(4d8Z^*-mK^SZj#$ zxqLY=9koN6{ol-|VtXhb$Bnax=h#?F!bNVZ5!&$}ACq3b>! zKe!*lg~;l!ZLm#Fj&|x4SOdffT!O6rzOrkEuB71sEhrdQ#1+YLKeF??%s{(QFV(E8 z2P2jfuAB^b{R{5hJKa*UpsMU8jU65c=fdUp^JipQ&e0Y0Byaw}pp`NG`|)BJ2~(g2 zc`@E0-UU_9i+LnZfr+`Z=!#*~mh09;C3-47C8E&tQ!}G6e(|cmY^`|FNQ_DhP+m-M zOmKs{yqHNcl^E^3XdxCQ5`jfYoO%`{B8&w|VQDd9XJIi?SXziUjfF^!leQsFV-eER z(gFmG-&U&L#rN73{{LR$#bi~otce%1JhF!2x#pBHrIUz{w+$~&@R;C@cHzZv60SrF zcrn%~b`V;D7biMSbi=%%PraX%3Lkkfoun%X?s+lVDcTKO zfEROgIflNB zQb>vbHbSGPF%L%cPF*ztK@fyHr6AJh8890O? zP6ZN=!Fhy%!V-VMX>>S+CEfxUyoJINUx5g6M^{ioUbmtEi{^sdB7a2HFO!V(t&j0r0a z+p_2SPxd3Ik%}~Cir4PkQ3Qqgqs=}0rtBvH1m14ju-&C>WY}1OIf|eVMBv_X*Ds#N ztPUaYfVoi8`Km4@j36hY9cGmkCR>FQ>{~1;f0=EP_D#y(CGtTlO_ zVM8JM1hafdNpn-t#Y5i{Y!oObD6+jjY?{4iamqe|Znzz^dwf;i?R(_^b0IH#VC8ASi>b&Z&_lruIJwW|v{3Ht^`r mYyKvf;wTG((P7C?xAbhYp_pX!zZ*-&o^ExmOUxicng0QHzPXwJ literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/as_globalproperty.cpp.E4E70F1E3BDD257D.idx b/.cache/clangd/index/as_globalproperty.cpp.E4E70F1E3BDD257D.idx new file mode 100644 index 0000000000000000000000000000000000000000..4be4530f463a1916304cb77539cdea2a40c8625e GIT binary patch literal 2400 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 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/as_memory.h.C6EFA7F35F05C98D.idx b/.cache/clangd/index/as_memory.h.C6EFA7F35F05C98D.idx new file mode 100644 index 0000000000000000000000000000000000000000..3511338f3c31833963c82db26453ad26387b6b3a GIT binary patch literal 1454 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 J-;y+9{67MDBF+E+ literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/as_module.h.D7D335828B947862.idx b/.cache/clangd/index/as_module.h.D7D335828B947862.idx new file mode 100644 index 0000000000000000000000000000000000000000..1023055381e851c66e3a8217f3049372f2d2456d GIT binary patch literal 10070 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 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/as_namespace.h.F7B71193DB11DB1A.idx b/.cache/clangd/index/as_namespace.h.F7B71193DB11DB1A.idx new file mode 100644 index 0000000000000000000000000000000000000000..fe9f7520c12577483b4af79445762ff7d90907cf GIT binary patch literal 1336 zcmY*Xe@GK?6u-Oq-R60?Io+nVYNqJ0Qa5*un=((wNh6b5qF8GF7D)*=34dUcrKXid zBm}7l1zD!KvO>wCh^S2SpTxo>DaiWAKO*`ggT8n6oE_Zf?tS0)z4v*a_uQ_`%p^n* z&T>~nZAE=a06`F8`1RI%s(bL4BMG9R@BaC8`dN}%@J98wjOAU-P#K+l<7HP}S6ok* zmg=wR7AKome=Kw3%iUcaZ6_BWHnh%dZ7To6JvjEIJ(bAfLX@2mO*1O`ov}7<_~^Of zzHqdX??QS$qS`lD5WmpkXewgWgCDO8HFx@Nq~+d@pI*>3&vs1|?D17jJ-YdO|JR~9 z%Ja$FSX*kxjP5-dZQ0%Cwgpp)00LRGmIw(5C1#8t--(&3p9YnnrfBT8>22F30QcGX z;v<^8$!r}Z!)_~S)k*;F0lIS{{Y~LPH5G{6PPsE!0&r)&{I&0ZR#PRXFcB21hz*s1 z2$V{b2(`Xg)?7%NJEf+AaJ)nA2$lfijb}cGt}R>|Sg+2KtQLs??$PK{a%FyLKu*bU z`b0(I776_6*M{?wTZUq9;od0%nSx9z2_Qbvo=OBcd%p)$N?hHnHR~k+x2K}g8;&!B zf=XIa4yrPUb+frZkwJFKE(bNSrLu?mE#ANzp;rd+@qB{c5)uRp=*S=;MMwi{$X1;h z_WH7oq>)i+)JdXk8X2jPMg@FeRAi(yA~=R*__jD7IPUh)|Yir;eR9Xo*;gPb~NJV**X;rWQW1tNtNp8nR`;2gnx`6xabV$0lFO?PLl z&#|;IM2rTc&6~{+|B#e3jc*Idf)#Rus6n)}lYZjXNUH%xjoWasdqD^WaTFKeC(fz3 z5WmIKJOfnl3hMZ9za`KD1BLMlY6bl!%OGsqWSNAG_B|CfC1Mv|PnlOQ{>VjGe^6X| Ms;qH@&mrZ+Ux8_hU;qFB literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/as_objecttype.cpp.F06C6FB1C9AED6FA.idx b/.cache/clangd/index/as_objecttype.cpp.F06C6FB1C9AED6FA.idx new file mode 100644 index 0000000000000000000000000000000000000000..44393c03430a791ddd61f7281a39581341c7623f GIT binary patch literal 14898 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 PCX_ijJL)4G49Mj_^G<&i literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/as_objecttype.h.785FD4622CEC3E36.idx b/.cache/clangd/index/as_objecttype.h.785FD4622CEC3E36.idx new file mode 100644 index 0000000000000000000000000000000000000000..85c75fb3164b2fe71b6445d08abba3b2cc614a54 GIT binary patch literal 5812 zcmY*d30PIt7QSoiy_b7E9uL>cBr*$#qKD}rrl^QRH~`KRiA)B92wWxwec(WtDaDYY zVveb$ndbZ)Glvw@tV|GdNK2`lN}uIWZ=ZYlxjw$nePI7n^SCH%Nplaf7UanzwGrV56cp3C3Vb>ptjU2Y#Na4~H;vE{WPafDqe$cKK!ZX9p(S z7+Ct6eyA#MR#x&+txA=Wy_Yq{hhb>Yc!%^xe$vglq|5U8^-J-RVSUaRPmo#(94hAFC zU1qtR-)k>1EevKGXL|uY@ZG7UQ*5dnCDs{mp|P+V;JUc!%w~Uf7m>Z<`y;}@5zN$qSNR63RN zL$aE7W`38w-z`#P-aPzB^+?e?!2i;v6{oAy#to5}4Z@cgOS%L8VtZH^`zc_!$b7kX zv^rX69smzHfBZm0%fTpn=E30*3b8d0fERD7pH%VB_E?D-5WL7()Rz0e2>)qIyR9E9 zF*V>~W3ey1SFfphaX7eWoWvO5bYps(cQ?QCtkX%xID6&>_(P%(NrZpp7|-~Cy7O@o z6JbzbENHv?hEb2QH0v7UMdrhEPw153Y#!h}&$;E?q`|*)*o9y02juVp`L%vv;?`@V z|DOxrnj*6P+@z9RE6Ka{1CwOutoIu|1|>r+3Duh^!lrP)E*n zyud6Un6&G^v|&;1sT7IXB7(_i@&x=!a>_@8zc;-pF$r+KF~4n-Nl#AuJDF~B*a>hs zY0AkK{(GZ-2|TeqDnnupFqmeX<_`FDQ%SK)(YP#$bpbq|H1o*`2H)fteSB2^M}dZU z@cIkV2054qYyAZs-`8;KwNK_q%pMUkjhWU2f3DOO}EY0CP8WfCI z)lWGzS7iU<;m51T8_WZ|XWRX=a%;@ea*1i+Jr6xc5Z$MA1CJ zyGQce!Ue}1YDE^z;YsRAcIE-_g}DA#7CAlS@F0HotH@y$`L=#w(%JJ=%Cp?jbrQ3~ z`WeOySHQpicd>6y*M!v~>%k+`kZTPuQOgG=vm$rq+S*NBBeHOAvV>fh@B*`ZU~+Fq zhlb5DQ?`n%J5O_zdX&LD05+7)UET3f^e&Ng$h`RaE6A{d>{>sFu-ohHxbTCAnk6P6LY6VBt<3ku z1lq3Ldh><@8w|LNsEio=7rh9Iy>rW>MPfP_Krd2VGsXMUAf2Y6>2v)kUl!e1i9wVyQI6In0r{i^y^!92h_GGzLeJ5fF_UTSou zRNB_&OjF;?`$KQ#adK+qZ%_mHn*$1OV;a281UZsLI--^9&Fqb54fZCznYA$u*5YNXIOjKJVLISX?mJuo*16voCh7@JQkOpR%qJ)1u(47lw` zg1nx@_0$yrD4cJ=!ruTu+#Im5Hh>=z`;?5O9)3JjQ8g7UC$JcJobP848`QzNABEDf zAFw$$8p4JctVRm4!w8(tH=%GjR>oJOw{W=1@*~K~bpsS+UY2Fl$@+H{>8r>A8x?p5 zpc)d<90b|Iim-vCIsRzaf@~s_7UU<$dER+F z(FO#$kP5Y^1b$8KMLxJBL7v%jW*|ylkY~{>E!wys7k4l24b>sYB~+rtP6c^(x7j^V zbONsleKkoa638HaX#H7#jrCR)MTA4cEOjx9AWS1OewK>(!C4{=KCOrzOhfeWX+`W{ z`pKNg%s#gsjMEA7WSXqQvlQe6O3*>c2)wh?64IgR3tWs)CF!731pWl5igeaesV1r> z9d;@3rcJe^Lq8X|6rnoOL8S6z+6yZJlFrPF(@w%D2fZ4K%V@`DRK)31f|8N zEiw!C$eRNeaRmV7#N#V!3e&mw{jWs7zAc%*+|8ugOj7FuQegu;kVRa<1NFrNDWVF~ z5LJ9y5mT6knBvnG5d~n>mrq8Iu`{HRPEOV)cgC{sUNT+1pRqQb=Tl4iT5`t0;^FW> zir7LJh%G*C5m^A%-lDqNI));}0ScT8X$9GWCh;`+ zGKvzzB1x@EjMw;3HdI12>&Uu_^8*vXobqSUY&UN`qu#2I`c&bV&`i+HKeDLM_lkZ9a! zFdO_*w^q~|j8N{pdMqjpOQ7TNl@(crX>?w0ZxLev@Gd!EkzfF(M)fRTar5zJeqhC+ z#gS+YP-Z;4SJ*2rZC?>-$nHI-=zu%51v}d5N3 zn)lWhL`YZoF{M$O0HPP!-IKv?6eE(4cSbt7uyILep~JP!{^qB`NY2zI65Bx=Yt5|7G6LkP3>i zZfF(hSCJi_9_pAc^0F3EnWj!p`iTE8<@t9GJBGNsYYD`!I~sV%|4dgW!kIViJ$~Sg zRa@K$hxys*dqXobmwOQ^dIH9v9SK^p?U&jvLNvNq$8-4w^^$OWd zD5U&3ug3m8=K3Cj-kvb-Z`<4*+YS+Al*>$)ZI8o~j}z#@lzkvOU3c(2p@@?g8;!8i1C3-aRiO1(dD_w4 W%bOE>ZD=3RJ1|HUU`2XcfBhe@5Q?TL9?VDItZ!TQoNf2_{a?TT>zg`Nq4>%R z!xmanD~b!t@;opMW5bWNtaNz}j$t@FsAxK-PG3ZeWj4Ra+TMB0YeUFT_bGYz{)z8@ z*`8kXP3Kihs$_4-(}@FZ%ADF)vUv~g4<3#CYi2Jm=D^W+!_NgBT$cT~vbTL;b=;+^ zk^0{^m&YD6pKiGA0lKP)s1sXPc(v8*4Hb`NcAuZ;cb)G))c0wyFzRAf@(p@T-xbUH zhesx2S|=Lb`MXXS+!--a#T`-xaPS?yhhE=8I_R=wvhvxY`28Jo-rSc_xn?_UQ~evY zef{lQjg4M|)~h|$u@zC>{nup!#fvlxW^S3a;hMZCr9vCAaw2JgzkO;?p?zr}V_1|m z_|~P$w)6-0#yFYn1*$u@9`8C_6B)tqKbLDO>$&*q%_h~Y6V&t6@uoxpX7BFVS!?=k zEvtgIjx67ZS=SWj?}k-w&Y@jsWPOstB$xphkO5f;cOE&9fx(72o+pP7Ro0J^OSnWJ z6pQ>tEN%jxKp?TP&RUaO(pkqO{GnJ3#KBxCDfK~Oud<;lQJGzROo9c)8lVa1CXq>O zBp$qcrGNZ+=?IhXgW^n($>%1Li4+oJrG-V-L=wZIIymd9azDhUQ9y)={17LISfVf_ zq=48{%tnMLAoG;5QF0W>^vq_0X_(8M9GBBw z?&N%V1VXlpmAYpkbc)6Yk}ydmGT{SNxJrnk@PRf=8;PRiXr~gYX;IMx1r&jbP~?dM zdQ$I;lx)J3hr^p2V+cM-qo=Wu5+A62)B(sZ>m+%g1B@vAC?MfULQ!xE#FOz17m`v^ zx6&lyiQX<*8lL8joKrv*teSzGQ$S6q>28Rtp6)_f9$AzNX?faE#2n_q)bm`(z%;la zBh%=HOiYs-GBeFiG&=W8(1<~l3|k=~C6tS>id4A=Cbbj_RZxBAC+nZ%$vEsD4UXY| z56TV?dO6@|VnouVHGN|lnXn78=`tbGqJWOjF_B9&Y&h%X^dnpG2WiA)-D`Q!HieVI zbJ-e6qc^gB`(D(w3|)IZq_Z4b&O~%-_tnKGR0#`l4=0A;kE6baMWFgB8+ArYHNNV+t4q24`DP1>vB^;;|&k zEa>IlqQv;12rnX01}l~f-MKsCc!L)k#53akkOwx9vZWjsQcqWhqETQ2Jx?Eq9I%0b zXK+JCp3x1NcqTVw=9!&{D(Y#q%^^R738jM6AXh>r(nLqjo8SBPxasNHeQ-k(>4^b| z4atBbcMf*lU|??N1SYd88Kr!%R6BgH4z#yI^Jk|R(GSg*Y3!Np2~39ngpgWr1Zy> z;^zE7)e)QzEIyWCbc}xC_&Tmo)Tsh>TBZH0_(vE?hzVI}UT)oQc|S6I@gSTo#}1&P z3_tMCo^5G6i?jbXbitP0D@N^2=NxpCG+GpDaaYL%jW~Y+R#qROk4DFQU=A}oZ?VR~ zO(%lx*8K+Q=KJIekP<39r0clS5nZ}&O93|gXJu_)`-j@@Rj|LhZt)6n&a`R>&I`Cg)WuBur*3ts2 z$nnB+eEs`y(F=xyU6cLMr^~k_&^TNk#&HU;f?~@`$L>-L20`=i^zxbJ%_ix%?>`hR BFHisg literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/as_outputbuffer.h.ACD41D21BD4DC007.idx b/.cache/clangd/index/as_outputbuffer.h.ACD41D21BD4DC007.idx new file mode 100644 index 0000000000000000000000000000000000000000..f2684080b39776f0235c25771da16e110e18a17a GIT binary patch literal 1398 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 auU`N4@4^5Bp^)hDO3W`SfApzB@c#pR)+bs3 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/as_parser.h.835A6072918E81C2.idx b/.cache/clangd/index/as_parser.h.835A6072918E81C2.idx new file mode 100644 index 0000000000000000000000000000000000000000..4880846b959212c389bd33c79d26ad4d73c9ba6a GIT binary patch literal 9106 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 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/as_property.h.B4B9AAB7616A0D6B.idx b/.cache/clangd/index/as_property.h.B4B9AAB7616A0D6B.idx new file mode 100644 index 0000000000000000000000000000000000000000..d25db2c6668da3037bb815686f9502291f2195cd GIT binary patch literal 3702 zcmYjU30PFu6@K@E%rL%r4#T`*69R|?5K|=3c>^dK7Z3#m21Khtgi%)Mu(=>a6O+0{ zq!1IM)oK;3F_;>ns7;Dms)ogYK}ChouZYC2(Hb?07H!YFdWMs+4*%HoYEM<(jj;U2yt|d5%}veQi;wlyNQbJt z+)C_^ExYL37TegE(H|L{?dADaX=mLt_m$gbY;B)?=<1M@vU@PDX|kIXlIvA1$d_4VxJ9H0Kt=i8o5b~Cj;^-yPgvSQQWyL&9T6MZI(OW1VlcEKMm zY`VH;FTFd|Hm&u{kGo5UGB!r$ho9>A&Kvg3JLq%oo7zha=J@u1{yA?aVa4`JYWM8-DU#W&d;X?+bN5a3!k?m-a!8F9tuf44j)l1v*y4iPO~6 zT$$mN&yQJdR0lsj!)<|t4tte>o&JeC<;|K_RcN5%-JF#>gm)3bD0 zW0^s?`;9k#QpWh}G}Mph#1e-Rffk0iX;z&_0K&`6Q?>v zXs8n5bcb{&ggeXYQwn!XSfrq%A*uq00ykzx3gcJ(c#m>?ZN7$5T%V{&w8lQ)-q-K* z=KokUbQHo1bPHa=?W3z^hMshPS}ss0h&@sr>B0=c!yaQgoCRH_o{j<7Knz-D5MFpS zSa|TPqsoN_;pVXQ4JjrEv?X3crk-8dE)Y?{bz4~Do{^Y9j%Vm zGlTHrNGYg4rK>@pZg5{xb*Xx05N>MKbiEeXeoUa=054H5ab^bLyxxG5e>CaOKxhD` z=u%vnLAc@m^lSSr_g&Ob1tvDfVU8N%xRB91YfglFqs-BL9vRH^k#|*-q@d1A1 zX49<~4V8$b6=j2P#<1u0$KU_ZtDs}xwuL!_xiB+w+itYX_|Tj`^qoL`Ah-;5##m-> zeX{fEH{VHr&@a$e;PfJ0kvlU8fAC+APREBU|0Pf_h<&Phsw*=HZ#;ftmVcmeP@n;@ zd8Rs3#|*+;*Vzt!RoVlAz6x;e=v-%J5YE_q_REj^JRd<}05<7NuFN1@*ZH{crfKg} zc%=ZF9nH?nAY5!-R`R}Lgyrmc(NISWdkH=PUXIFx>U@VRo<;R5}FUHbX=aEsF zvdj%xkQd90WpOw{W|d=_Vu-hiX+4p)TVs&(CDMNDSjG4kW7=)*NZk1QU(|#bGfAcr zJBhRmWso@;!@;A8meDYB9MUjxWAux&k$%A~(=NJuml!INNl+l=#V8V`L>A^nGchZ% z+vt^(^EZUpB)43$*p$0es=|?qu{S1$>D@cV7*$zhj6-FFc?g!sWSlF-> zj;rFTG%we4b1(iJpCoFRQ%5mW5$cR?UQ8otYP^}%*NXe@=k3d}>^4HBrQt}CjDN*C8O_Wt1Zw7BQdIww|Oyzq^OW8aYtAy>kqC){gM0Q zV(_u)PrNiA>jYPCp_Gjy6;mke53V5YOqtM)%0!$*S&{HKR3wPP_OYN6fm>D}oQ;`4 ziEP^jBT0%H2}hPDJa_d+A8Ffy8V^863dR)#V-ufkSyr&EZ)-hVfO1{A9`8T)5#E6; zU^pAKOD@U^!%9pM&g~@94eJYpaW9butz#8aIE)1E9y~o+-Y_RrHgLt@ub`ZF%bQm~_ zoSlk^8+MHsEg_a)V~D(1?o#fFjYi>0kQc%XQ?}{{u~HVQT;Y literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/as_restore.cpp.914EC6C72AA277A3.idx b/.cache/clangd/index/as_restore.cpp.914EC6C72AA277A3.idx new file mode 100644 index 0000000000000000000000000000000000000000..22e1c15c7d7ff186477dbf54eed33cd76342f97b GIT binary patch literal 97400 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 Ky4QIqnOwN$317enHVLySF@a5^J&( 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 NeejD;*W3Q<{{z+qVjutj literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/as_scriptcode.cpp.785735990E5C292F.idx b/.cache/clangd/index/as_scriptcode.cpp.785735990E5C292F.idx new file mode 100644 index 0000000000000000000000000000000000000000..131233941bf239c36ac75dd439967a0c6193b711 GIT binary patch literal 1992 zcmYjR4NOy46n^*h2WTJkwSC+c?D&x?2n7mMK!#2R?I>uWC?eFNP-}-%CTeibh*h&WB!Y@M-Q1>bY)+jMv&*IDq-no*&OP`0zH`ni z(d%@*0R)k|RKLn@ZLH!F1i_%Mqp_i;2oS_h4neHi`IYfjVV|1rd9hz<`+G7qzNe|6 zYWYu3Z<{V`KDKf0mQOVQHILL~{LG~1$j_{exnS=3^5O8TC~lzGFthNj=7ir5=_OHR zvUfAa&c>UDwB?s0+n!m&)?Ax>n!DMu!nr{=8X~ksPKlg3Ue~{=l-b$v0Y7)X*aj0E((ZleJ85PW1Afw1=nx+m4AMU_~Pa9iampm z2JV`Mls$#5StZ=-0}EGuUHRHC_4n1+x4V^p%uuA=$cjsJy&2(c zy_rAI;uVe@Anx@M@>6}@)RUf=?x`2k;Pq`QYZj+=RZTgss_r=Usb*|{@3DZP?rX;{ zj^FRyVYrjrw)Dj4sRdcX4I*tPxv+H7v(MgJ-r=g5*DpQPW}4Tv?s)9Je>%>croAKe z2X4o@FB$3y$7*}^DdcZNg6;{>5ur3Gk`mCuSfuJ6r->UFfI@&%i?E= zae`pl?sY>Yb@yMD&ynVY%hGx26XieWWfbo^BL5eX5_DcAQYmDqATmrr#Yi)=U-0AV3Wi6)9Bob^zL|oH_=_kOSz;}T_y~n4 zN4daMEW?LYE|7{b&I92ujT^jsFl;l$AMDP0aQ22<9Lk|!5=ata5frpZZLi@o6l??G zZ9s`}LB4rerMET`P_S4~9EJ&D|Irmb^YImp_v?msDhriB0X=}{0Tia>PRxINr~P9! zM*&SDlMI(pK=U+n3X3X5l@qbuUS9OD@o_$?Wh9M(ILT|+&naCJRE`K4f(+7E<3JGg z4^_VyDh^kp$6Eoh70@`aw$qb2qb1P_xG(c@89X6C@^U<|0HOQoQS}Gi%K!uOsJvjD z?dZMN^5M$!4pe-3}aC{NN5Kt zjQJ-Ho?J6Kw^KmDWRT2b`;*S3%Q0UHX407qi?obZj_FWPN9!0C8At=4MMeA~0gH@5 z#tC&4TtF`H%k+R?4-jKYihza~Qx^I2FvTT6l!b~z#g!OQtj?{^85_U6?f+|84%o^g` zI2@#)hR_7#0tnHX*VtG#H(QKn6)hMyXQFo$wD2qv?7eS=crGBpYLpJC?(yV>x40Bk z1GV3-%pvFaZDlE0>WADw>;{u?39JJ7HY;$J2(t)>zSjw6C{C`f*s%BQhe)Ccm_qOw z3YsUG<5*M)D*a+sp4E@IowoaJuY>Q9vZ9-5AqN6_0T1*G`-kj_u1S<|(AEzPo>OV0IkrHm|_K)8iyVf=g8X{>M5 zCvje&A<2cgF}PBLwYJJf#L-}J#GqdQPpG%O;Cw3{B|~LIDCS5IGWM^f2`&38> Q$>H(>g#kefUjTyt2R$Ew(*OVf literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/as_scriptcode.h.A66639055A43BA36.idx b/.cache/clangd/index/as_scriptcode.h.A66639055A43BA36.idx new file mode 100644 index 0000000000000000000000000000000000000000..a20f59b2c1446babd12be25634055551c3811211 GIT binary patch literal 1282 zcmYjPYe*DP6uxtHS7(~Wb#&JiMANJ`%Os!MwywJ3iej5>25R)fHN$+j>yK8+AWP6B z)A|u48kRpSY|V@eOYo7QW{G8~1cHVZMM?;!n006Llml~S?)RN@?sU6ymAY|v~k8!KOblK!r?Y5dw)LVTV5TlKhGN$Kl>DEpux?8wm7 zXEzJ$bQLL`CI?h*bnLZVe)08+MV++lQuEBcs6i?DqBwm?o?LRjyFjuq(E4FAm|FE5 zSzKQ+_710Bvjy$0ZocT(+0{Ix?=sb!^BXgY+N$>SRMxpTa$gl&@8mYz=XzA0I&hqHkyBwC1 zyCeBXg=l~_Do564R!cfLyp7P&e6(CNK+iTLSNRtD4se(ww3gQ@L<98HY>Q_dE1hz} zWUF+LG{{Xfh!*>%Xo!* z2QWgRk^RhsE!|zp(%}cgBcLRfR(q;_V6iN%;WbJaH92`}{QsYHl+Fn{WobR5mqFza zPkD-hfO&x+C`J?lz#s(TEeHVM2QzSQ~ry=*bh5et5=?~2Wjze*>4XGgn za-m#lK_-x-!Z>)yug!Ljcxx#w1B-z#CLU3KS#*FsOyVf>Z#`G$oa^zX|Op zxdTxk50$_j#9L4fc*EC$*$~U7J4*}O0g|OdaEJ?>V7Mfcpdo-^SEP7BHUPtbh_|2_ zfSFCX5LnO(z`Mrp{Y>)cSR$~>S>*x6gL+8rt#w(l@-hS$t0mLAQ}|&7v+>ZDo?mJ5 N2leIHnE{mv%wN0VY|{V$ literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/as_scriptengine.cpp.811C05404051D15E.idx b/.cache/clangd/index/as_scriptengine.cpp.811C05404051D15E.idx new file mode 100644 index 0000000000000000000000000000000000000000..9bd13c33123dc0614bce4f2b79911b001f00092e GIT binary patch literal 129850 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 A8UO$Q literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/as_scriptengine.h.04C2C814432DD8AF.idx b/.cache/clangd/index/as_scriptengine.h.04C2C814432DD8AF.idx new file mode 100644 index 0000000000000000000000000000000000000000..5aa26086a5adcfd4cb2c878bb0cbb0f74f2457d4 GIT binary patch literal 29368 zcmY*i1zZ(N`#v*!1P)i0RcTO4v0Jgb6)`ZeML)Z{z(Brf z96@YF(QD^7DN9_JonshiNq$jTQU9 zY15~UF*nm_sFOxBd;8gboo3}UEPbilmcq1Q?LXy?m}CF=;V8@L>bn4=WBI(^#1wupU34ci+j6-n6#(Ix~2mb>})-=h>$1Zgz2bX#b+P za_8!Ezs>$!Vqb;SJB1fc_O5Vh^1Xx7q@6J@TIJNuad3BNv}In2HNj0PjJuUPrvCd^ zW0eW9K7$@CUb?bqc24}=+y_TYCb#e}C_hQpY{}W42M0ZE+P}!o-}2MYbq9SlU(D;y zuUX{awCTF_>Q$$bKQyyD@3_m=bZ}zrV;|RKcD|DoJ-5sK4-39*<$xruRRr}3>((@Xw?I+d)JQ{s$7~7`Co%!FxjDso|{)o5mj>7jt^X z+B07&Tzl}*@@U`LF+0y5-sqP%Z9uuD<3}H<($W5UUXS9ppIuuOraerp->csA@HSQJ z?rq-v?3uhZPL1D}PIu|j^g>{ZLf2`M{k3&nJ*Hg#u*j=zZ1q7`%kC=KG;Y9P-+eci zmX))oeBG9_r(p8HaZay3eEDT^+tuIm_TXvP^6HPhd%EzDlX-n--!pf&?zDY2+AJuq zwZ#x_hLj{TF2XbZhml;f5((qyD~J~ zW&WwE)k253yiVxnF~I{?uUq|K^{hQl&yDhG+x2;hMiL;r@r4*xnNPuoNl4DgGbc-K%_hM$n2&L zck(9g9X%lXh5P36tJ5 ztzm8FFOLblYh{(-T3T7)UU}1;4v*SZt5JH&>Wza7XD@Ag{nhP54F@m#x6_wr^K=)} z>pMPG0$RF<|FbRLyXEa+0S$I_GXIf81J0*T&w2M`%GUf(9^s49%udCcj%>GJ$EE7~ zoX4#U_V*mTeNk&aFHDMh#*t9QMbTFySNct^!*;m$o)`MFJgva;O351U4P_DjBfuD5?k&<8oJ z_mZ%XD(5UW`h;5RC)1FJ$1AqUeb@GO-Sk_%scvS)>5X>zL|F8E+jIEyEp8ssOR_Xu zO0FvRD9qvO{66(=lrD4j^ivPh4gr;H8r5;#dAMxsj}aYrR9`vLt+V|$rrzl_%&e#LyxfzOmj0-@srNtjh2QEZ_Xo%mii-{}$w?6I0kZxu> z>wdkqslvN%H8wV#HMZ8T;#J?rO~|-#rH| zNCTGy{~S1_S)DdT_2}t&BPVB6Ynifq$my^fHeGCYPinNdx68md5AT2-8BNTxecpR` zB_#Mg-W9p_9ZB?Ud!R~}1N~>}ibrJHovTu3fmc+-)OOeX!uy&n>wT`c%|9F59jE{A zZH;Gf?ynjoj5}SsU!~F=o6orOA#+A}gX+`chOBQGndIoYDd$Ha{aEK&kpIp92HWIL zXqM#fW9PeT)Z`bp-d3y-*!jrVHJ87QJdy3x+thLT_fr;^Mm4rP@%+Xw&zT2au1UEa za?Rqt)+RS0Z*q3aaod|a`kd`LChcv7@o`_Sbh;g|cGHHTy(?Z_wX)LN{BbciubEG| z^rJ!0=+vV%tC%)hG9c#aD)TWl=9Mj*^vZrlKerdx=C*&@I;CB^O1AZD`rj*8>{>KQ z>9u_N%pN_$;#@d{Mec-H~{k-14k18lN zB+4tLcEH4OFOChmS7G(H;R_Ze?XF(Y>YvFUSJ{{^xKK0H(KpXIas2SjrwgT?O%?>y zDcNS(q_VY7Tsn1c?auuJ+U1k_@2lHhZ?s~qUOQ^r<>JY^ya)7~71-Q2w}Hd2`CA@r z@t7fJCmp&{$Kl#mU1W)`%A^(hhfiM9p-cM9#MQ^TE$cMHV)^blPUBnj+aDGCeDeCf zqvjsGoVVs;#cMCSm%q?taKkN^Y%G1h3@$TlQbuBFpZjADY+2i_e&g7h@56@G`RaN9 zz1f;|_FXn;pH?cjEGe?o%Kc{((_W1nw#JZ>G?yybJWZhEyBY2O#rZ2dZK!uv^ot8c~+vb(kIQqtE^Us9^ zyRwH4U4F3ONy~uqANx*wzu)!a%{K!l9qN3hb<(JS>p7Qykwa5LrcRqPVR%SYjV3i` z;-)q!J2VOnBZml^DzN|bq>pQ#ni@7=;Q#I0=bpRp@KxsFq&oZ{CO?Q1T$+33hh_Gv zKoz>yD9CvtpC{Gevmo%oj%%O$NeZp4hB-m4PS9p>F**NkUr4WUlC1fc944$9-z42P z$sH-&s_e^%T~V26W%{0%rYFIYU9jYa6mHd@{u+03J}Dv7)57hZ7%16mIY5 zrO#{8V~4Ic|6mEU};-CDgp;HuEU5%7X*bm)F1e(XOd~~Iwo39=sg$0G6mdR< zYrj5PbDz2G6>dMN^H0helStwAR`cZ3hkFCc$eRB|3w|f*-bt={B2u`y-2X8pDyP6o z)*KLSYqh$y+H!g#Qn-bVN|~0pe2}$F{}qK6Q1=4Lp14R2Zj&n5j6S5bRj7%2kIB?3 znHnC$nqR5Cw*B|RR;K60ySpXX-;yfpiAWLYSNEk?cgbz-6e_EcUJ=t*#2GGYUtIn7 ztk))cg?3k6CfZFjJWyS^{Elnh>|zc^F~BgH^+cp_E0K`5X!+8A$|V}J)cX?3azO|I!>*Q)0S|tZoAI6UAqKlnXVIcS}NHsm0a{hq;T_m z{HuM%FU?$JO`3QLi?q5$TGrc%6mGXtS9Q7@^2A-CUTT4xiNj`62`(?!KifXHQdJLy zwpLw+DZ@PAF#SlYy#stgJ!DOiDC)bU`!3n*iAdo#dGEEr(f@O(sL-xzob9yac4}xP zlaDwYxLM^^C51YwE{BNAA<_a-u3AE6@@M~dTlAxB!xP_XU(dph0`e@2rU(~&-tcfR4{GDV;t+S*qNa6Om>Fcmkaj{ip8Ymw48L8|U zJ|Kt`ZqtURH!%qxR!yO0)w+jJlMq@8E>5BOSAUtv)fGBgbx9<0A~B4bWs6dZ#`z^z z=k4S;ualmQP`sUp6p_-cpB-D$sa6e{hKM@psk@%mXKue!xRv+1fAMO!yc!DatQHtX z9Kwh@T+$zUuN?e+LQRDZP+iVatFzSbY3453ur1{L(weg782vrIzLs>arLuY=QbbxX zW<-0xl5cCv^q{EICau#Zt*4%d6mC(2N3HT~9bZSGerka$iOou480u2z9Z!z`lv796 ztPur%l60SVfg(kus*?3)mxfhOq^cti|?ymE25?Tp}x z4P}}x8uufq+#{)qo`@8Y{)?aEnf4*Rp+ardNC$|^0a6_q;R{ja#6)M0TUW4bgR(=ilSCg)bN}uR_$?V`~AC3WX*o@fPP83U;K@U6ru8` zl%15^sbf=xh8TqkA=V+JGJFord}cqteW_-$ra*)W)#^gEtX3k0+ti5{Ll2*O)9kPD zqKKFlspCb?%Qg+WI3zchHP=L>)mq(ZEvuAB5vkGT^}2ffO0-aDH}y#+5jlxC!ewAT ztIthsTC|YqE%D6PYo+zt5_%$1xHhywy!>H{KR-x zU~{#=K~96}!oluPR<(uA3R}pU6{7vWkaRD2hbmIIW#-==IyR|ZD}^pHdYXHw$zEz` zQ0_OhL5sG&WIkH8tYgIG7^#CW8{Q1LeAD9>bLptM^swk*=#?idY7#fKn`Ik?won}g zIt{Fc2>+0+x#dSpZ?Dj)s)MhSuc3$%E&k`T_G>0{*kn}G?iSq*W%wW5n^E_DL3^1l z5p6L}DjUbA(;`JlO#_S4ibqFxQ0Qi(Kv#(66}1a(a4N?2$=;j}G7S@7-)w6UIu z6rm;@?QwCFzfVVnvf%|Y+*oQAt9E>2b94`W)qcQSJXDt@wA2!{;SaKZH?gzj+%7VG zC|>yo>imJ$(-V=RupeW0R;`;6)x~w2JE7UM^kDh<_(|=wsnH~^ttBAT3@sUiVh~)EekJZzKeti@= zUX2t*T%y$Otihw`HI@1lG8b3XWfO7Oq^=+?n*DsK)o<%7YhuLX`6B7Q@Ts9lQJCg# z38%riVf{=rE5%FAmCSM_8$A&z+&qS-bayQLub)EOs|9W+PTSQw{nF06S9?PB{t68@ zdheHrxBNLP#cxBBPd zu|a#7PpFYkD6tMDhN+yZ#o<1S9^Yj?%Z+?uiDRtl)9^yKd5PNk0~EU6$j7Ucm!Tcr z?Rh)Px5w}SvgV|Cif<*|Ti)4=6qW8g{^e;pa^oO{8pYW_OKhO_a9MpLZp4lR{UDic z7BBxUb-&ABzDVI#H_7y}yXSw*Em*i^Quj<+hb^Lir*K={y!dfSm#u>pI#_*>2dLEn zY8YHvG&nG!?F`2u3Z1RGjIkSInCmz`$(o+jzt>QO_Ea4XQmcdNC;uvC;6pjvd6-O} z^BdEXos#2DsWwv7=HRo5C+F%e4VUR2QR#54NjM)2L<+a8mSyD{^UL}vw2oR}B(;iE zD{bR5r*rJ586yee=k5uSb)#Ws?JxyFu(1u?JLXbGb@@U}zmT$sQft-QXMra!Fqg@yi@%M(VaZ=(k$I<)mcPdGDf*vf zQ|tSDihf_>DdLRYBzwoXmKrb9FXG--OLnXI){aQw=H%oYa&vdyc!fHs#T_Ir2Z<+K z<_7F4ZGLzB1cf$KU3OBFozxC4HOzMGymz6>M45gQg&mYCAC#KviAdpg*U4q`-ODv6 zDzt_gDS^ld>NbS`j!Bkd2aRGb^Hi597E=sg+KFnHUwH@YXAZ+vhgHO8mHL!TW`19` z{^qSo3JvD9`O^(wC6-r7EmUQMiAULQ-|9_K=or-{jFt#f=Lv2h`f|x%+fI=+vEsFd zXmuf4)-#F}kt%ix$!q&IeY!#`sF4=aQj66=vqO!?Br7>(rmXoPA}!PEmhlE8Qbh8Y zaq;qtSxslj^b|S4zoPR}$@6?ON2GAu+xu|L%tpC$WV&8_MOoB6i#B9ywBIS*Qc6!M zJXSDpE?+hs@w_Lt#5-Hr8-pcR0H>a4ntriojC0gAQt+Sqp6mByIPhEBO$hUb4 z4N&hgm{Vf-nOFsR`BGp$TbuHD^&ZZn7N37SWYdzZz)pyM+dK#cmo$9ijnk=VQh~jR!`suE1p$ldDR5b1*lJyaZy*-h_ zt;5t!hjUN0TO!jq;g%yg=J4s7NZ}UqyoTI1U; z8?{E1?$511d})7Wg+hm@QT7qLed-b<@LRZ7pT$E~$#j=^;_0+>I%Ta%q=@8pwDExC z=?hmWbcxZYw}+bSQMV#?w`;knOKsg6SyL=-?SrKIAh8xFQiRG3phaEQv|Xdnc50>i zy7o0p$m~Ad{I$;QGIMCEI&7lM(K^$)+%&|QFS_5bTUk`FFjf?xc>yt zbqcMh28pLu@zl`a#%=K}RoCV~h)g&9X|&WmgOA7=zf;sV#5!>0;(ld9P3S7&mLQoW z@NI38!ma+?nj>!B>bODH6p6cEsnxCIn@}Q!Tl%}*n;hMp?5}e7XNgy8rl+NTi5Vw4}sx+jh@4nrMPVySy)%-IuKSc)?S+T^)XT@0o{X z!W3$u7WkQ%ekO*Q^u@JisG%29WqT2^~shTv-yUXNKv1lt;b%?TQMX;*1Q!jH%O}s(mLpgNa5!8E%?Li z@=GEVI!rBaFR|OJesA78+*j{)+r?b!sV?h@^?G8Mx$YdLTM>Kb26Jhvy7(!6hKbwv zxYpGcbqU_9Pha#ut@1+PrC`LV5f6GwxoZmY1ku+aSSnZvM^|dgf9}b$L%r->WmA z(F0aj+1q5&L51$*h5ZThgp_!qzSWTa?MgpyU-d8_+>Y|WEmLyK$FANNKZtHdwPDiR#?pwKG7zcHR4_9B{Mx=iHQ_$yL#4oRwt$xi?&<1J*L$j)8=|2 zQn&@%d)IolVMeqm+v?-Tl`TzLvaW&ue~s?HZ}M@OJ`we~MN8kJ>}X7+sL!iVn=R&c^N;fv z`)32%EsMX{EQzOZtJwVL)RQqAS+qs;_f#oaDw!;m(G!uv&9h~Pjx*~=vU-hE>$QTK ztWalpTN@ua{7+i16Eb}y>h*&<|KPh7B1NRgR%>cEJ%5F{?GP^~NU{r(DzGp6cM7*M zcd`d7p%r5l+Dk2PEtS`*8~VwbH|Z}H)<30CAJrw5TBfSQR{!YJB|BB_e_ElHRhKww z6{n8s9>w*N8xKilF8->^QQ~rx7`Dvr-EMiZB{7dzSTi(yMm;Th8b-(GU)n!tYTtu7 z7_GA35z}|-D%)@8EbZOf7tbiPmKr05TE$SqxoD$4js^ZwnB*^rNcomx@yG;_`E&rXuEm;cr+UoY} z1cjDXBYh;MAJs0TpTFDpWlJN@%5<@KTc@P5r=&`HB2q*O2{P-ysicyq&^c{j|h>YS`xYOq=5q zaqjX(nI?*QKad?#2X2h z?8EsMy+{$~@V5as65_~Zg)TL^v1Qa`87&Q;Ii-9(w>Buje5$Esog?x&Vi+3JXD^@8 z>$`30Urpo#G5w%6k&r!G9WE26>Vj)tvc{dsIC8_6$G=(lui|c67(Xh^<>51i^Od{81`dAdVM{?T3 z$rB<)oSe$Kl!U-m=?X2c##uy5EmF6mXqpT&k!pr>NB_wg1d*;(a7^)Tnfs zZWHY>U9wN->iQA?dKQQT~Wg-XUKG!a62uPJuNlR6OqDg!;%lvZ1WFh$eI`8 z7M5#u%e8iTB2u^=EOpFsPO?QNADN^1lq+9y%jZu_q;Q)`R$d>za9k#vcZiWWMJk!X zrzawXoBnPGea#jAnF=kZKG;xd5~{AdW9v*TQ!^kkOQG(nOCT*3sFE?Rw;5is>gf|% zGQBAt>jueg18<=sMPWT!_Z(k1@-&OIk-PorF0T>GYwA(MjpvCATupV^e;p34rX^OZ z9Zz9m(1bL{!`b{h|FfggI+uUvxe`xN+N}9zwh@!|-B)M{wXg_k5}|&2&7zu*%(2^- zBWpg3N4`d@TcdT-6OkfP(+MT~e|El}qtLo)q`4Mz4O7Omwt-8!wttW#(~aT{=TY}O z+LA4key51D@Qr_}!|VomHf(A7d$yD)(L_ns6OqC#-TL_Ry;Fwe$@G$Vnm1|bo0L6G zk-}})ov7l=flD9A^n!3ZE;$|N4_%~i+i>+>BlBdMuh2?re8FGyl()q6tvXLR`mjS#-D9Z*vgW&ZpewYx z6}0TXcz_+iyIS=^^n*H*1|XYuQnmND*mq zF?Wgm=45$VqJ_p__K+V|wIhwz4&zEK~-wKv&2FD_gCRH43VVbRnoTJ0I_ z0(M-CG8y_zrkljwJ)rIn_(7mZQP{K=d1mk0q`r`8xN!SUoxjr>jK1`RqF!$R^B0^i@f2<@&9kdCY!v;ULcP^` z?WQKXsbO(6FM5&R;Y<79%d}9m^2L(fVu^L?B1NRujV5;f_CJd+3SGwC{&Z3?#4$$Q z6`1uPGU8IV1z%*kRJ@mXscgK&wthv5Q1cp8SpK!~rLQKM)uP0F$t<5wTSW@DzS{DQ zd%w>8CTsSJClRRC1!`UNM5J(gne%Tz+<;Br71~#=R|K((P*=$Q-gQn4O?vrVrk6#5 zQIb;>?-E3cNHgxN{n(@Kke{;VhA8ldr2D~#5Rt;I`hU~n6JPE5DbrAKm)X=kn{RN7 z6mBQ#?@60nVcsu=PFL$S&TgFHWJ@!32gHSbAf=KOU%K@1p-DcM+6xc z2uQdb5xiR<;N5aWP;G&LYD*a+*tI~|jo*{Z?@2ZY3%V_@tYF!~6)anh2y!hDkZXCt zf=>(NUpggYt!sPJ60DqL%C6F(f2ftrkU||(Xf?3bm?4WQS=1Hh8qDyXn!l%x*mYut zFVyl2b-}hj*t)z%f~1Rb@m@J1sJTEu&E<6!Y+N8<<8nk0aDjk;%cBY2Es*UaZ*&U^ z{cJ&4-9~jD)dMsq@Ns!8LB&N5P;hxH!Mp_m<}F7!;TCofZn>TFY+(n_mX{%@wLn0v z<%nR@0s)(rBZ5E+q+YWN=2>%mt@xdsCZ4BBQyiRvTFdhYHZAgiP0JBMpfwKxbkU?7-Y-bBJeuInB9Gb01IK69dTM9N@+_k4 zvc$5085UD^S>jxd8J19XS%SL441ttgmY85NLzKiWOLSw*5G|QUOLkZRF~f0*U6z>p zROvr+$dn#!?0KCNNc9BL6la@Y_3}D%GB0WjGB39a4lfXJc=?kNv|S)O_PuQ~C(Of< zXgQUQUDjZ_fzZqI2o5jufWynn5zJj6VD9off~*S!WL=&|aCCuyqs#LMdM=I=K+ENM z1REE5yuVLNrH!^Y^JkMu%`>Sr$O_=;@@RsZi#(v_azwCkfq;$6%Mm18ARys#gmZ6U z2ltl85_DT2pxg2sf@Nz!{;+I0BFMEs@`g5;*OOGKEVH}m-l4lUcw6jekJddpfhop* z`i}FR3fdR@IXr<3KTj~RVTLg?$1DKZg8dvDO2%#>ScEgf)N)fRV5gP+3?aG@qJSRw z+fXHh)HX6Ckg^G+JQ^PJC?wMg$y`j8nBfr#V*j^}fJ4blCnR>6q0eK6c!^zRm|37# z<_|(Ji18r6ApZS|ev^lRfHcez!57BF9z0==2x>6$fEvup5sY9UU<7kS5P^Y|{X+!i z(FFGwd*R^z{ziV&eUS%rUmi`ce1U-F%Mn5D1p;y}k0$uMK)~nah@kKS0fm=G6U<#8 zVD9off~*TTvlR}ZLGb0}2wpFu zRsF;3<%pp30s);!;Se|J6XLbweu8$vw2*n6paV|O(MEPi4!fD*0X2U>ZLwlxh9YWSL~X%NWQJmDUQBJVwapAWCG(w@?AYk)6f^!W7?}FzMOlu%uTJt=DTnz-BCC?)$)j&Y0=6M8*8VFd_ zJdYqx0|9xO=Mj8qAmB^$Jc1?-1T<-$M=+y-fEmpZL52nbGBl6IInc0!1I=>?+A|Q) zo_P*Ib_N2nGe-o+83;x$j&N!-?4UMtJ7+Y*j-id)IguH542ay$>C3PmC}@+trc-u% z-n-=xIfvK-0kN6ihu|^;d0O|n!=r&UJGiqv19Sr{ajd|84y-@03980^4$}>@!~}r- z9A0^NO{1Z9f^LE(rqv9cSbbt$%*)u%09}A3n8obpLQ-KNsfxV}W(Xv@Kw^pW6J}US zDlH{7z&T`wl|;9aSfbBohE=4}DpCX7G-lXLbeoAKCNIpeg;d=_YU2!m8BUXKr%7*2 zwwWP;G*2LHjfV5Hq}*9j9%ll~<1DFrmNfdy(B&-Y@t0xvSu*-B!_2c}zL6n`I3*D` zG*}iiiBw7=HH-|eB>GA+!_dGyiX>Vjnc1 znqg;|8G^JlNNWau1T(DA(iK`W?AtNJ8ZBL;HN(y*GpyCpwOTW*LYQHlmafy9ff>aN z!CD%uH3L198A7x)L~91(9+>gGWePq#+8OxpyafshJP>rNJda?$1HtlvBZBY_1cY}U zO>o?SfaA{d2xdDFv_Fn;LObjrv~#=Qu>%2*otGl0>p(zV=Xp3|9dJU(W|l_7f-jQH7fEF>m;AJ#&A0}SihU|DB#f31qt(F6WQJpOz%lBFvsGq@ zrk$c`52Fz`mU_j~UU+59BbLsKWy~`pO9o{Fo6cxdyGt39S_hUj%acjjrNa`18FDDQ zbU3kLhCIqH9roIpK~LGG!=#fL9#D4ajE2f*l(j1zni=ybqU_TBHFmP$Q)e`GzNc*4 zLua(-@qx0|q(kFkF}_oF>99A;3_mElbYL(r!%xaC9kv0OVUffx9UeC`ESA`%!W>1W{(VC$US1?I~u+me{2O6N?#gBzEb*yJUtuiCsEy$C%-P z#4a7qu$iGiVwVoQZ@dovNeOKQS}?Q~ylo3f1rSIoI3ko3K%k`H(S&#c2*eY78&2pY zfc&nsd7fm4N<%=w!wcO6T%nubh)_!afm(tiLL>pCt9hv&Ra@@vuVv*NAi4v@9y2dy zh#|TdVvlWSW{4$~V@V?jBA8({Ewh@s<75nq3to)SS)dr`EI1<66+jS-BSKRF1eywt za3uxoP*U)xD8v&$l&yoFFSMUAfKMn+6WwWIgTWKB3LZIgcg;6hQF7b3|w+ zfIu_BqY0@55Uk!g!W9y*W8J{*LKp!A9|$GG&(q&Ig$x zm9onM#Hil}w^Ulg$Pgp3oox$jbTf}M$vjQ6LH~gdnm-Al-9X(jIpBzpYXDhyZ>s*y z*xjS;S+oM;RzT`{P4K?AZCk)mW_Uteo{-vLA~Hh}X=(SNY8h~4&D!23i&E zn;EuHc9q6vJu^g5y9intXU@#9hdS<|)j-5%hGVqWG1| F3x#qNp#{Q_SNyWmoCH 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 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/as_scriptfunction.cpp.F9B4DD1EC0FC8DDF.idx b/.cache/clangd/index/as_scriptfunction.cpp.F9B4DD1EC0FC8DDF.idx new file mode 100644 index 0000000000000000000000000000000000000000..183a80e02c5dab3ed50a89c8f6040e24c97bc4b2 GIT binary patch literal 40308 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 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/as_scriptfunction.h.98772B58CB0B667F.idx b/.cache/clangd/index/as_scriptfunction.h.98772B58CB0B667F.idx new file mode 100644 index 0000000000000000000000000000000000000000..f9e568e8c273a5604c0b4b18afd958312954d810 GIT binary patch literal 17836 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 YmNi+UV*)7@tjI~sxk#NoBr=fy13AU;nE(I) literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/as_scriptnode.h.46E65245C1B8E45F.idx b/.cache/clangd/index/as_scriptnode.h.46E65245C1B8E45F.idx new file mode 100644 index 0000000000000000000000000000000000000000..e85c249eae498c82f6456e5b42ddca413de3753b GIT binary patch literal 5056 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 Bri=gp literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/as_scriptobject.cpp.74A647D3C5D1F2CA.idx b/.cache/clangd/index/as_scriptobject.cpp.74A647D3C5D1F2CA.idx new file mode 100644 index 0000000000000000000000000000000000000000..62333ca5bb728966eee6d4548f2093331da5bcf6 GIT binary patch literal 19206 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 aSCE-Bw{Cr+dCdj}FadZ)3=`P@@BaWF+(JnJ literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/as_string.cpp.5255D8D36DAECD5C.idx b/.cache/clangd/index/as_string.cpp.5255D8D36DAECD5C.idx new file mode 100644 index 0000000000000000000000000000000000000000..0efa7085a1edb6e0dacf335de1c9adeaea7189fe GIT binary patch literal 8526 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 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/as_string.h.D36854A487979607.idx b/.cache/clangd/index/as_string.h.D36854A487979607.idx new file mode 100644 index 0000000000000000000000000000000000000000..84a2d8f4a1bc8ea6059324f26b2d45ba2f210dbe GIT binary patch literal 4404 zcmY*c2~ZSQ8t!f!=HSgRoCAW75s*v7Q4WD{ghNEGMZlm~N)0lCgux&vuuu`u1m%jF z^;(b8jd8Wqike_tSBx>>0rA|`HEK5E>MEMVCE{iawcNjZ=I`lr72W*D``>&2_5G7K zJ1s5LiD6PoXV;rewZ?G_!??m=;(Rr`_@(Q*nP_jo0dipuV2!O(WAg_OCvCey#kIuZJH$ zId=Kj<4YYUDrac*#qk9{YgaqXjCN6GYN)PXzAJC$_(A_d4PpFoeU+-pnNf~o8Q1Z!zJ-KN``ww78Z8&# zVbP#X_DvdG|6@%5r#CaAU9_AE&1cK935ri-#rk#K-3#Ji6z9qF98vswW*g(QvrZ?u z++=pLc)4ZuTcZ9H@X$+QJV%xz8V~F#_S$@R)dVf4K;zMhXe}DAZm#0;`?`EIoVN!< zTUm80>uUX=%Il-%l1KB``x3?vZ(lAe2k+V2S-khpg!IVUCZAv}7l>OJh`|-tFS>eU z-MT-_i}^VqwvDj=Z0pEIE?ydN+Mq-E0df(D`>E5)o?BoxP!c=2lYJo_S)1%E7%b2>=5YWr$;;l+3|j0?j+VzeKv{Z6s+ zN`d6=;cU2gcjFZAgWfZJ-;tP4APJ)R{*t3L^OWD3B%#fcWr?A6SU+~m@WJOxBz{jJ zDdOrAmuBlPe(_0_Bx}toGh{8qO~~5MOwHG(^;`!9F|Z}F5^xTrwNMrx=3I>NJ$cb#}wivhcPRcTR`FS;?*xy?3YecO8+#B)M zg6ibc-IDVslVtJyqY+P^?>4u8B=KDY8zK6x^GMy@$**ER)^chLO@<;vthwDw7GA$_ zwH3r#6c;E8JTb6m14ry`1~_k))Lgzg-wnlUn%@)-C9K^hIe9HxE1vxCj#Cc3ZQrz0 z%Mmo5E=yPA>V4l&3K=Y3v|Hl&N>wFz9{P>o`T5HZnH>!=KZLRbwh23b=+iJAIgSuxWDFqXZD?I?>q@51x4M$s#{nW z>jzc#uPwfjACP`l!}vnoERZiC!VAS~X1#E94l6q+@qLsk$_2%Rm*;!jHWUmJCIDMP zg{(r7Ifb9U_mdrW^_rxi=E`%$u2VBM^7C7l*qd;F%$o*9gLwaTH}&OJ+AX)VTo8&I z?Hk3=mdE{g{IjmWyOO*~C8=WGT`;xRa$xLuK?DqTj?AT77-X7L+&gi`~ zhct2h(I?lE$N<>>V8T}uaF0A{aI48i6l{6z361;V1L}pUo~6^_`aD{ zH-qmjAM{>>yh*-epkqR3bA{7|n5ekhULV-4qOvsLi?^E4sC~|coG}1HD2OB-1 z(N57i1Rg?ToMSw&&k`ET#>z4O361lM3r2qsnnaWQ(fx#`xutnwtbp=M3zkq3X|Xmc zgUyg*KOi)R=J+Ej5}N0d=ZWVhG~XkiV(k-Jz!u1{Q4qSqZ$&V+EJ7RD207*_f$Cvf zSUDCJLNd6Chhp>xZVGH3f{~4$05%W3$VTX8RaU^oARyp^w*{cJh74gA*gU+V8T2|> z=V2Au2&-V7$5dn^oPstFqqrr)C}{H-irNUDu%!T-){|f`!3YnQsEuF=+B`@i8~3nR zS-{b1giyYtq7b|f$Y7&*7_m`}y2e0k3WPSfHw9q+BEZ5?cwogn5m@0UJfI?b?zTP0 zk9}P~DvTwe@iacrMkTNbDs(QPiEN?@`yrvpY_bY59jFP(0X8ayO;Mpg2~A~FRoKO$ zve`71t(LQ0vc0hl5o**K^&%WnV~8=_MwRGF^yqa$OF~M*ZB(hQRF934P?OH27h!>x zO)3k+%qFyaQh69w9HABN6+R-m(Td=T={Bm8sZ@&4PAk1C{cV()F)J}K2sHxzn9wS(Dt`$TRyD&$t#n@Lg)G zsX$wr57;|_&CgJ%jja*b{Op8m?4MwppP7)2GZSb_D;sAeVDmE)YNPAGh%g&j>jIGh zwE2k$wK3?RElfgIZJdLE&Cfrmjcppr+%o)NC&8%)1pLT@`Z(>trqW8l$b)rZy0LDG zvkhqTGYuL+tN=DY%ixySw!jEK!ytP`Uzw>pG3Yi+XqY?v)?)Qe*fS1|K0!VcfNDIHaR=bC;;HNXH#5w z@WDVi000GjLxr2m#^1KAN_u=0vR9N-&oEp3q zEi|$gO}3uBM(;};w!-N|+fG%Xmyd8gm? z;56J9da#3c`eq#vrjUFDBp+^@M|C~>^piW(-RhsJAEjS1+T~-u(rjZ{l_Nh{(|cs1 zPesvU;(gxr;>-tW+~a!v_RHdCr#I~L=Xb?=47_!|8g<&v+F7R{IC)tc_cih9i1{l2 z(&zYEmm)(BA%-pNennUtfBjs!8x8(BmzN+)*tCr-e^I~uN!nnJNmF-=K#OCr%f;N4 zT4U z!I7^<(+fU4aL#UsziKzpT(zCz!uNOUpZ3s`oLbX)c+&mQw_a1s;K_;ychA_E0?d;2$j82Z?;JTs%?x4k)CZzf-Vd?V|n z9KSIlgRMq;BK)|6WdAJh{YMF7I-ymf@kWEFn!K&*)yI`e%5|-Nt`+#0u8aB<^!wrW z&(GaFKy=;GY+&u3tdeV)`>ZTyRVzK0p35KNUFVJZ_x+tFGwa~mpFXe4Hj}IEaYC+Mtj=c1Dr2(L0JRnX{V)oLboj6pe zf1-ad^KRkVEn&9gyhxki*|2Ic$^B}sulkXqeV@mygAS|T3Tw`3d1>`*PW=VPRX)7B zc$91YgZUZMPo!}R^oTDc3n4xr#^6yGmk%zR{n8*_OsLN4#vg2qY>npgo7Y0 zw~BCZCLyg`$JkuA(`;R%W@9WAIkS0-h-b>P`qnU7$!aO&V3Dbh zZccXJT5SOlroO5^9g93}`A}=r-^>MvFrPy6r_cuDBg`b6WfE>RhB3v^$`<6pB49e9 zjs=l0N7Or$7ao3wAw3)MzIt%r%8uIb3YkCW- zjzMi^2~;V8M66kCM{Agu7)ykGhaN8oi#Y^dy!e`St7fz`7GSAi$Kj$2C;74IZ*ba7 z2a literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/as_string_util.h.9A317F1475C17B9C.idx b/.cache/clangd/index/as_string_util.h.9A317F1475C17B9C.idx new file mode 100644 index 0000000000000000000000000000000000000000..d2da63091830b6f8871734c7736dd7e84a0c2980 GIT binary patch literal 942 zcmWIYbaPwA%)sEB;#rZKT9U}Zz`!5^#Kk2=nHh`>3_E~w6?3*ujP*ZcAkq3gxawf* zgv`S#N8SWoY&mj-UnOqRrM8--^;^gP4zl+rr*7*B*`tH@uA)ywT7J1qGw-qhu z+~Up0n`tMSX2X?XQ|d3JGF3TMCaI@TkNZH=MbWyDPrNHG?)YJI{aA0eskVfmgdLBD zqlKCh^SYHu+0CV!vg*87Ya}cZ=ZikIsr!%o`W63<9g;eB*S4?f1Mj~bz9q$#xk<-> z;eOFae2Y(i8Y2$_FOUZUVmcf;QVg7Ij11yJjAE>HTx_>xHXP*VVc>?yGl;2is7Wwz zvNJ&x7_BP$GwrdV4-W$$Oo1MUo-_j|7b`?TR>t&8Ri_eSc^LR%3bZ-2fmXm2OgnkW z_T(hHJ{|@Em;wzB4WI%}76uVvpc@Y6xqL~U#=DY-K@g@ulS31zfPwz%kboM?01GIfb>IMkio=2j zC=3o3sBqzXojZO}>ym(OHefJ-1q=hsMxbhN7(rFTtOg2$Lk23G9OP5A>724oJ0_(xG1?;9K;X>5fC7DE4A|DC+>uIjG_zx!d4%8 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/as_symboltable.h.C39A118BD2A60C0C.idx b/.cache/clangd/index/as_symboltable.h.C39A118BD2A60C0C.idx new file mode 100644 index 0000000000000000000000000000000000000000..7d60d92b0cbfdc322661c528fa6d3ddf930dc748 GIT binary patch literal 10144 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 N#h>lOpAq8E{{`~UHl+Xn literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/as_texts.h.A2EC1EC85F68DC9C.idx b/.cache/clangd/index/as_texts.h.A2EC1EC85F68DC9C.idx new file mode 100644 index 0000000000000000000000000000000000000000..2498251bf40d05744b0e5d67ce4c1a38e5caa4e1 GIT binary patch literal 8440 zcmYkB2{_fu|HseFal0Rt_EjoTX|aWAXsR=%*ooq!Bj#Z5DX)K z_6~Nt50U@A7C7)ufKiCo7V5q&fcD^RrNy2xEX&0_6M!aCXx1QW}VhY3yaI71VVv8 z;)HP238CEo{}V_OjuDdhOJHZQ)4s2)K+xKgu)M^6r2zGn$i$F|Wym-F`)qQ~mv_zx zLIgx0h(L-Wknl4#T&p{lf@}=gn6~-fXYjdmx>?;3eF%7q;4PBLh-8_cW&Rm`tEilZAP-Fzfp-ID4%Dz7D@ni!1SgQZ2-w(m_0*r2>q|g1f@m~d z1O!fXUIqo5C^(AYC}vOiR;!f9dtB~MfV&Xfg=}~^R<%;^Oa@C4@EpN&Bqw^6-?3#% z^5+~Vum^huk&MmfyqsJhHGs&cF`UK|MZi}z|Jp%c2MSEUgiS`5Ug8jY=fwkw{2IY) z#6~?Lt;T+mp4}h=#O+Wa3Kh4*geXkhJ|#q_#O-h) z3KzE{geXGXjufIuaXU(gqQvcJA&M5aV}vM1+>RBZSaJKb5SRHbcyT*H zh!Vu@L?KEPx08e@N!(5rqGWM9MTk3|j<kAug#}m+up&7GC-1z5qXKj-|1)Uf=v9#!kU2R8F zrz;0jkc%M~v+llmeR#*zwkir7z+sH&`;M)~(Xzk1Wr>`MAQj1qfa=RBR?mhQd0%|b#FG;U&<1Um5hdjg2cDKTlq2#wST|Pm8j12b&4yR|$P>91LoH_CU%5qi zagl8m1@mAY>*h*x-%DjOVH1gb62nQJVj}iREUC~#lL%+b9t50mBD8P1L7j!PzcFQ|?b8AOt}OpYAOK?54yldQL$yhGaZW^n}fp zs^$#WMNT&XG(rQ&ywkJ%;yKR@5t{$iZf5Qkaa@Nay(Zr3+$4FWn5bRsrWg>f2B)vAjrc#YvT))cj2 zmUF^$)z~TuA}~Z?RtqlLz7!;ebW(5u!v)L=V@F@*dco*{ngsMB=;eh`Qfd6DteeOCtYSt3|*w1kVr)FSCM&e*PUdC@WHG{ za)rSrOVo-fXhYD3SV+!|wOWA}06ibEC8ASf zDFFcp0=N&xuPXhRzhfo^fd~STx@a<7E<2s}ew@3E04uO!PS8`PsaEf>YdMk6BRG#( zT$rvKT2;Eyc?AJo7`k{i%P|X`QK7YPB>{S%$HpA&v~P>nBc)YDuEtQ!$NXuzhUAR) zd8-Mi!cfJXCIID(-q>MF!6O8Zc+)n2OV1uQ&~yy}8)4%}(Fle|pKMo%TC|qPe-QlP zW1cs7jhR>RQ3~!MxW{*dr`1<4x={Rqf_e<~Jc?3p8m?QQK5HETu?S)jOI&T)w+u9^ z)>BZ7p_r#?S?w#wM?|9a1SBCyLb9S>#ZUhJqoi!|e*i-guU>ljQ#VDKDN|66pqzKN z{{#C0cdDo86R;Q-Yl&XeqGVcdYLA@(k!``2m7Cozse#5{wG4@T0>cTOpFTZ17d2IG z2?ZqxO1Rqxwb?DO>>9b5fIV zz;y)I5%cdp3n~@bt`(RN5RD-ktB59}{l@d&2WI-)378M_SuSg6o69S7lAKN4>F;S=5zbX?jhhX9A=&U>^))j z`xJha+E2iH1n-fo$eS!tU z>Z&*ra1O&c?jLJ%f9@JRW{(pAj^M}~b5VV0Lt1?{m6H)9BX*oSH7hjYSaKc(ffxe$ zPRPq(yqsO!u7d>3gqf@m+*Y?-yV_!qGm(EH_{ppF#Y0v%ALbh!A|MMv7I&Jwg66NE z!;&fRN8ryFC^Ki|0&CUjhY5(p5XsBK%_5hjG*Qrmp@~OD`0DqjzJss35uggH?2uUheap*RLp=$|Mv%>i_j=pR)v64&Eo`=A}Hmx^oFm2&fe}=3j8qm@eJ<0|G^RO_&p~G zc#7dEFKHXpbK_OEpY|c(2!s7&64%-op3A zhMm&E1YALIg|A!JkdmkyZ|+gB8dkFrFLO52?`$XxA@XMopLsf|seQezB~&_;06zqN zJmOBOrmUJ~QWH)<2Z9bBqe+L&(x*Y2x;G zmT#%-49=_u*&H&G%97n2Nn~YEW)jpI>;j>dpHUoWXF0m+*qyn(G?mdnvF3yV0U()8EnPA8wi(PvkoY z?(i4kl+m%mK<@+sE+DwTZq=rE(pDIvza=B`fz2YS2w5;4y~B+y$PTGu)&ktD8Z< zDFml@*0b;XFgZ-$;Q|4QpvaC1dxwQ-xy_z;k;v+x&QeuNtJ5;IhTq248t>iccSWBFyF(<{VD;q z2x|FeLXa_hvh@((ECOC4c*)o8p8dMmK20;S3D^UB*ws*Q)q%ty{|YL52*HEjt8S6e z1DDla*9rKB;2U3OiM2^80rz|~+atQd0;4|OYwbZ-$Elvoa;1hyR95iiDd!sIq zL4hX*PrjhGvxd)!3aF#tE{40@`{u6qQ9Ji>-z@^dFof}Ha-^yK%nrj#6dXlxlxMO% zZW%$+`j06%i{UKaKCZ}i=<*cy%_ZOv9Aeu|%lImvH}~IC*&NJSjLwC~0;37$c|`WY z;KfhJ{kBRLrx|2Z@B_mS%)Gmw&DV+o^VzovsK8LccMUp=yRW%!DWxDCLpo0ntHYEP zzIn;!6W{_aES)(2Rp6mzy_w20UqG1G^{dojE1k_^~OKH^XMuoB0L0b!F{- zRDOlv6?YivF5{M++2s`cK=6Zm_xO|Znr!78DQLye%6qirgWQ6H21^SF2*41)4@Ls7 zg|%g;OenaG;5LtkX{m{q6lMQ@K!6#Tv3R~eSLs!}Tsf8hg@0M#&JFjJRexvth{&HX ze8TLa^xmD(>m9baQ(yoFY-m!R7wq3^%yfC8wm{%Z?lVn1FW}-tjDHq^oNv z6E>%ifQ7J-ZImU4rfeSTf2@eeXAzv`Mbb^?m+s{EV~PoAK+wPkc0%u}NnKtw1x8@R zPKegZ3s7|brO${Qj3F4aYB)4kH)Bmt6a_0`C3D`*ndhI4m(wmGau|Xz9%*~-G`081 zpI=HqJc4+BMHTnm$WVT3Aq7PUiukIzNxNRmnLe|O03}djJB;B=4(-_=KAXy0VJoXV zqMyBp{J-D4L`C)Atc>4TuFJ~_*aq8VMY8p|TDNHT2r6rV7CX6F8-!?o98^r@n+R@l z=epZGV1?dK?Uw|kBS=Rq72a*MOqelIrh))haAi3-VOM#urj_L@A~#}a!AAri(Qwf$1+-@7YwH}U zBcKdH89!WaO7Hr3BYj>y0bU5ac)_#yv7qK};{k68c!c2*o+WzKa)_GUwRkWEn_v@j z`2!c^z}d-~%25cSc&#n9$r_Yoq|!jZD-5rA_BvX*)vNPoVj}^W2r{{Ew+;%;`EGOe z9RUvzJm9|9v9{v+=2Z`x2zZF$AwNjej_jQ4eOd5(ucmDj&mej5lq0 zPp44(Z^>o?-eP#m3v0hCyC)gmRcs;PARJ_8?(o@KPQ@v6T8Z3^p_?D*mj4N^ef+lJ zGXd8yT;tv`eE*ezio}R71XzFto2CByf*joXB~iH)Ln)7cbH_BV%0!EA1pG$uo1Yjm z_s#!0-s=_x_b}Y!Id9qP*o|L{zEH3Xma+Z(UstNiWb&%piTnh?6TS|P(n=$`dp=U& z1WwE?J5!(USCyIjgUBy1yx^(Lrt9KJ?-F+kt|7R_cVXT#(x&bC@f3W=@Ey}1&j0%i zYD)TJGIxFl0lJ{eLb39^fot-l?Nm;|kizFES9|47=P~&d)M2ROo6=HEpYGH}Qa=gE zN084wqjXG#V&L65zX&h|Q#Py08;a)so%W5&dtooTF0;|mZ~A`VU?-8!V>r*V@J5-G zcHgN!6jUIn;K_4C!^`IK!I{4aSOu$C`rj28qj5g&7L_$Yll@K+lJhlpbIJ5SM2^A` zg;^EJH9z>bX?GR{@fhOy3C6L*{+M}p8wH*SJo%i)PH7FfveKZ3fX4_P^B!%s`{?%m zT{Z>BF&yVPV7vX9XU`{~UILCFIKt=1&SH-#T@HJ@9rpkINGy@Iu+8~Zj>>(3;Qs&- C!ALLw literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/as_thread.cpp.16533C75DDD387A2.idx b/.cache/clangd/index/as_thread.cpp.16533C75DDD387A2.idx new file mode 100644 index 0000000000000000000000000000000000000000..436221aa58d3f69b931ac8cefdbb19f799e4cb6e GIT binary patch literal 5794 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 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/as_tokendef.h.DA624DCE97276FDA.idx b/.cache/clangd/index/as_tokendef.h.DA624DCE97276FDA.idx new file mode 100644 index 0000000000000000000000000000000000000000..c93042ed4273115694b007daa722f678f5d2250c GIT binary patch literal 13164 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

&I2(DuHYItR{5`{HkZreYBdN=P1Ztna+Gt6( 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 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/as_tokenizer.h.854B9CD5479ED89E.idx b/.cache/clangd/index/as_tokenizer.h.854B9CD5479ED89E.idx new file mode 100644 index 0000000000000000000000000000000000000000..8caa5b5259638f479b32f06f320de2f3cffa065a GIT binary patch literal 1820 zcmY*Ze@t6d6u$2QufSg0*K(;4Bf|~GfK4E&VAs;0bo^KaVInwWV;ytTK@i$5O#Waa z5@l`7Pj!U&C?=X{V?b7i}WBH0rBT)rU zcmMhG#P6jXbF#;I=JT=i3ulfFG~d`VG};_3)mTTy4rS`2uhFJ!57>btskRmn|5 z=9V{DliPYFb@9}?i;v#B(Yk?~Nqc<6R`*NgUfJGhd;Qd~Yd++wf#IR5D%XR-{^fSv zmag7I55CU6B3<4twj(mf6VBMhqIemP zR{^bKb#kCj-!H@;JXaRZV-e69Yz6`P$5)R|JW|OL6<7?kno)~^{$|u&*MF~D&Eo)| zm7LPMTXy-gHK(@DWb-%(Xg#Z!!tOq2_`cck{jW)|RDwuOL{60F2K1ipnAxen)%$tO z!0s$I%PXv+{N{xe@v%l8vp^eI0}s0cW>MU6XW211#z3c%)F*-7v19av;oRZA$FKru z4Wq$8D;|D?4XZW%JPrlg%$nB#eXjG`VtY*cH6DimZDfsJVLhLY^fW|I-WFjo?M4cl zBKO=-h^HkC395D;$tZMRoR#2ks@y^>(ViQmuS;w`eO+3=z~f*@Z(>c}o>?1T((EBw zcX`YKt(9scVK=JT{j%-D0N-RVk)DZws$e20EKCBx%JkvTpAKvzJV%uA$|PtljkL-P zU!;9XtAqkLqBUu=eUUCsw-K^)M5oaieUUy!p8)f~5xq*U^F@YOLn5@3BZf@|y)QDx z7!%-ibHu1J>U@zY&a@HU6-P`OlhGHM)6D76MUI#)<^qUda#Y2>rkn&3 zRm>q`7o$Nf*$wPVk$|nIKa2^xtaU7%s z$I+7nrvVI-C@eS(U~m|P1!n<#mh0-BZ+N?f=3XDXUI9loN9HEqYIU5a<*FpACtx*4 zazr@_s0Uoh$cW%ZSOlG;CkZYDcvpetb=MEdVJa>OCCTBW$vMR>*Xm9;g)JhB47>)d zph*O;LK1iegsyn>zbxGUI>QkS)<|F}WTXlO>jDhjr3VOZ1sGaEVZo&UQ?XWp3o`+?S4GCXf%4$D!ur4 zN`-Pu+PAKOEkz@=`DM+E(mTdoyOR9-lSH?Y#_6A|88o~lo8^S`y0|O0*JsNH{tz_3 zr$Mp!$CP0SOPk-0O-Q?^PrE&~I#Zf|=;Hl{G5c!Z-Hcr$67yCFuXPJN-6bn>pn}@-3T4IJ)^O?o6pQCds2>g?7TePkm`{- zYRxb2zHnE6Kg;tw{mMwE8@=Ds&zN&RId;&bElHPSzbP4iICX1w*%tBHq~Csub^k|) z+SdktuxL?i!}U&0laeMD#j2lt{KdS8Q>rg6RejJqq5ehbxkYUBn zbohqfrc?RrSoRcC&9ZvqVW+!$yJrUV__X+U)AqMIEg5w6*M`0s+Uix(_tBGvsP`Ij znuaM3t>3NqdGgx{ZUrOCCmyJZ?Yr&w2^m|Tz3t=a60{=myRfl4#*K@<+3xJ1;Wsii z$IMFH|L2xFg&)n@Uw`Gbl*!XnV|{mZSoY?)cOF)+YhWMqJ)JMTnOSk#L$$U~x3@F9 zIIcfhqDlP6S8I|dc^3W9;N!WjsS4*&4=6UHA%|AzZvR-J(F|IqtT`i3Ojlf8Y z{ViwzJ0T^ytB!R*8Ee69E%;ehgVSozTlMIKQa08Ouyl{T-&M3GwUp0v`Dm=|fvYcn z{WoQ#HXoc8FADC+vXN;wGV`kkv79-ODcpAr?JWv!$g+*8w=thr4`MOxNtvjKm^)U- zd{CFW;CB}deog<{OM|t@^=SN%%?&^NHd)7l(4ITo_YM!YJOaZb2%y7rn;h@6K49v* zI_BG1km{MCo`qP>f%+Wy5sR2z*jYK_A+mVmHjQ9x#BKWP`}-3^&-O3+Cb&JDqhpcC zFwS+Hmu0A8s7T98wpOoCYi@YogT>%-xH{a+QUp*0BKb5T(A56kaxn=5sH-5Y;qGfN zfUbe#H93GzCOCe*J7i|Ej)kI(YH+OvZ_8-?=(e*hDB0r|p1V=$I!;C}#R%X106@j$eYCRZ2WcnUmmR4|W1(RjAdUl&7Jb8w(PBr3+j?XaBlIKMLhxRA?dfM7n`=E;Z)6yz9;UHu1m}&QA_+6c>@6vdnfP4C z+9N|H(^oQY%U9s|6=+D&843y76PbVl!MI4H_3q{w* z5t$S37ksARqSOgGDP$pippQZpQU%H?5D9#ZJ5~vP|5>C0lXQl=oZ;RCy7Xiw={Seu zTt^t@{R)XMCA|CG%W3S@O;sOGX!TQxP9|wH1Z;+ILNb$-3jw(hPUmEjPOyLzES%2X zB$cw*Qr1(ZZ!psh7DC};k{Xy>12Ykln54(d_?QJ!9{jnw-O}Yfv}zEg9Dp1=kXOHL z{G+c@=a#9_rlX)f3Lb>d+h<%Du{PzY^^FP;D!_@7JKiFNIz|206&I3uR5Fhy8=-wY655iEuq}{$0<%lNe$k((87FL zn3?RL0>!*vRws%HleB@GH}DR$rCAu@fH30Ij5 z`BB6a)Ldmo5+EWPJJmBi`Bg+L5g#y5(nmz#aCpwN1SW&eo%9$v?MeVD-pWE-SqEC6 z!ihexR!vfTjA6v$9-H%nkw2H|bD5cZb>r>0WuqXxJwp$G&;m|!B)7tDXoWnWq@TU= zPW0`NYwZ=H6bX^8axBL~ysI3`3CaX70wYlx?>yc}B}0^!I4HkqNTf;z# zQKx_lfA0@U4`)Ar(Nr0S8gFF6My76S7^HOOozB9D)}3DCxp-4pH%C!Q0`DXUrM*OH z3z)V*JDJ`I-aGBrbHFnPf+*`nX+IeELx@Zlf@h(;-fP?^yRMe>>h55YBK48(bkZg% zN*`rM#p~nU>D*0HPkqles_>&X78Gsl7?0VW&*SrXf5JmD1)X4PgeXNRQEKsonk)TaPs8g0Q zjZ9x>aGg2HDO%5jdgf@Kl2H#>G^OP9PtX6l@X@~qBD7EE(_KhkQCh~A*->?j*ReJ_ z@tSk(U!7|Qp<|jLpb0F5L_ZZ2ee}9Y9D{+E&wcWF5P7UmM~BNx8pn^p=-3Z@KfEkn z*3Cqz5TH;-SZWZ_gSPIF0?&BzxbqIxkny-@GWSj9k%V3je*LpfZ@V%9MepOfecXrk z6s05F=?K>o{p*gfd}G|vf*9vFMP461A#WN6&^<2P z<85)WCi8v&|22%BjtiAsTggqNBLy~EZMzCkF-pF?;AT_e&Uf*RTpp7vXD7|M`#t%jrXUgD$m6Cw9!^>js^c5hs{-*qe9FHFsIQ&N42WEO3%F5I8>F28JHeIc z#NB0C!P*6jFm~%8st)4lNC}fru=SEbg4aXViLUdGe~bs#4Z5j_OOyt~U=?AND4hhw zNzhOyDoUro`4s47x{yO5SCJ9V{g01YUlsQ$o`FqUIoEC45?y-e@$&=6e_n%(Uo-vJ z%tWYWJ>}pk)`3o$A{Y~D6^B(^M;8|FS2v=W;v0^aeEzj}PlsM35^8pBK*;X`U7Tcl z`awS@*`69u)PM{5MwD)Y@-}E>I*lvRxC`wnO4VFZ&0Q!E*1y>7JhSfp2Bj$7V6Hcq zj|_pe%(0f~WV()tb<9JiZ!x%K-__>4H(LJ_W-%jYXxgUIb}<-+Mf(>e#h3 zT&QB2Di%No`_88qE&nc6q+|RY;&6y7Nt7s+b4589Nk0)=dv=C9%X9^Y3a*stI0C9ir1AMy4~sB}1;J z2I&;joMKw4h6e0^0?SyCJ>9j8#mRIzGnX@enZ`J&Wv&z&1_|S&j(HOO#)T}mP_urE z+FHiFHiJJYBBG*>sH;q;Lj>w7(;2`~SDDTP$OLDZ&H~7?r*pw87yRY6AP*e#KqJ!! zAn<^E1G2USUMFNj5Db_j`hpCzHi8|>SXY@o%it_?CVJzHTjtVJJ+@-Z+HO3w(R&Yl z;}>p>-iA4z#Pvzsm(tIAiO_A}K19RtkiTL(uiJqVk^quq@LLq77+d|#vYi-ZD?wNZ zT8h&h%a0tJ{Nlp5DEcf@on>yMj7hr1#9Pdry#D$I)xihm;9V%8kh>RhKMF^}8*G4W z(-8t3V!$}F%|xgap7`&>UPi1%^}LMKDUCi=u3^ z6B0$~jtjPl2^Ahv0?}?a6LvEV-BLtpFZ15Z+R5|^F09}hGDAcwTvu>22@nxR6>GQ~ zxmd)RiNkiTr-I)_IB;<6<%j#wf$3b8ZhtnHx#}|ar8K0D0adk4Zb;Ql#^IeB(iR^; zsJ9p`?I`W671Nx{JCGZfrkAcuOd9l~gF(U=%mXb&he5&^JOB|gjkws%jN}^wUP$#V z%#CQemZ2iH`4HuQW?XP^>b~KHh&WLYWq04{2|e5HJEAnjaf$~OV^Nx|ob5$@n<&k9 zo^PZJmk{gRGg}>o13R2#xEFCVSwgNu1#I&t@-=mXxL}<+kzQY3`IrBeM#V7{l*e^> z+=~QVduzFW^u4HJT)4@Fo7|P+nB@WMOSV%qW3bu=S9A!|M-BV% z#|ts1@QrptJ3W=*uID~T_~t~}X>8X@SzsxPq4cokvJP=grpuWcag69U%0r*me=xEX zTD!d66)5cqXrF)= zwNJDi_kJ~HBcI{4hQnsAp|CYcmpEMF8j8jxv#)el<_tZHL6^n?(pWg9kh0i>${U|RASrLc z!1Qln?dfpT3EPHf?_9$1l{DCWu$dB}sd(4irJtr;_7bHI(7~?$_JUq^^>?s(up7N% zz18ZIz)MEb3mH|?vz5-3zF-8@RaF7&=%US*8!^oB{dV+D1-7I zXz1c(9S#|rz)Y5kQVCO)FdZG2HJZFj?JGqYQI4Pl5Vt>cPy z_H9@?XX#u?r;Xhuhb`PmrZc%RlWQpRMCmkFoR-@*QM%08W&4)lDu=7wiK6Ar+HE6- z)c&sqL2kVF_#g^elQiFZeh>vMIST{AHm#+Apl6UMg$v_b` ztN=Ia%0!$UJ6#05JbS1HhicHup>_k<4N%+D<{J<$(|5u3E|}y{Yy`0pJmpYq0c8ug zQ5CSxHXK?(OX+N#9Qki#5i%ZN+p&#>$@h=lEO0lAlIv$a3(RLx@|C=pDT?hwy^<*^ znU308YgrqS%O?;XQYFWsOgI|i5OY3c?}RF*sA4MF zdsVDk6^obYd=B~Ck-S;+^`>tZ_t9NP2))CFJKTk=p>V_Gw0$R`{JC4*>wk~>N8iLZ z>X=U*3!|D7{KvoMTVP}@R)|=LwaeN8FrY0@DJOBjWBs~9LJfbbZHB+qwiVJxMg6nu zZ{ddJEU27C63F%2);(YI!Qcj5Xl4P;ER^a(PLI=ZF72Zq;1%CCx1!uKyqa4Pefzih zpX}-D@eprnYawDSbdm8s141((N~W_QI13_VIvdQ{5K4kJO!_h?C8X#vs$%P-sUJ9V zdsO_`)$A$u10@Vfm@_R{TNB9RcJw|D`(zq!KK|x%-K1ye%{uU}g9tfalesQgZs9H0 zCa&&uV*4}P`Ys4}K}(5DM~)|G`%Xp9o;tSvWV?vk=lI4!?tW07y-|?jmj`<^#Sb@s z%Ru~oHG8Vnj)e=RFSLHn7A)4kY`^aG4?*bG_D_%o1O=}=zu2LQce8XCroZ>jZ0n3j S)MyxYP$*rToZ}o-p#DE)mrMl! literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/as_typeinfo.h.A4B06C7A534C616F.idx b/.cache/clangd/index/as_typeinfo.h.A4B06C7A534C616F.idx new file mode 100644 index 0000000000000000000000000000000000000000..921afceeb3e11562cdcc45b987e6712de2da1f15 GIT binary patch literal 9638 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 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/cgltf.h.13D0453510CF284B.idx b/.cache/clangd/index/cgltf.h.13D0453510CF284B.idx new file mode 100644 index 0000000000000000000000000000000000000000..4d9691a12d95180c69e8051c8d6181e895713b55 GIT binary patch literal 146694 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

s&_+765LqE*R2FR*KrLcIe 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�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 Qtfo%!C)lb8$7^!_52)W;djJ3c literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/dr_mp3.h.251364C12EEB63EE.idx b/.cache/clangd/index/dr_mp3.h.251364C12EEB63EE.idx new file mode 100644 index 0000000000000000000000000000000000000000..9f0f41ab2cc3660e09d1b9400d48674095bbd0ad GIT binary patch literal 79250 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 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/dr_wav.h.57B96FF54B7B9AA9.idx b/.cache/clangd/index/dr_wav.h.57B96FF54B7B9AA9.idx new file mode 100644 index 0000000000000000000000000000000000000000..d0b0007015b14bcce79e25b5e407de7fbcc193cc GIT binary patch literal 159032 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⪚v*2IkmW^oTj8y}3e1B11p(T<_f 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 gb{uh>bewSbjri6%yqXfzQ8Q4tXk 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 NDqEjcc1nB2{{R6(`knv) literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/fa-solid-900.h.DCA613D0F857190A.idx b/.cache/clangd/index/fa-solid-900.h.DCA613D0F857190A.idx new file mode 100644 index 0000000000000000000000000000000000000000..db262168bb51e3652aba26460e6f37e38e64aec3 GIT binary patch literal 436 zcmWIYbaPw7$iU#7;#rZKT9U}Zz`!5^#Kk2=nLmN_Y@l4loVgQr`!PH6xNd)@y^UKz z^&ImAk8Tea!A`k_7Y!cYG`+bsJegl$-#k_>ho-h;M>oE^cy+DWm500LIcVE9C7#}N z{+?8)z(>xqLn)IwrMG|G_43J2uN#|6CIl{h(!iCe@`{W7W&1=eH;=kimjdU+oqKM) z*<@w^`Dvf8W<}b|@O*vp;#cZ~9EsP97VoZ8`1bRG&zVvJXRXWp0uKFa&HL>81vMh@0q--l%%Ta_>HGOz;`FiA0)fe8jl1_nkJW`?5Fv|>FZ ua~QcG`hh|q0MiW=25E%|G5~euB!bw*Majk7AO@%YUCw(GUrb-fzyJU!tD#f? literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/glad.h.D7F215BB4A184C68.idx b/.cache/clangd/index/glad.h.D7F215BB4A184C68.idx new file mode 100644 index 0000000000000000000000000000000000000000..819ecfdd7bcae3caef8c6551c8116d10499d7a65 GIT binary patch literal 454934 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 xzT@+mo8~OD!(~G(Wk=&}klGN4OsweR1;0 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

4eX- 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%0A?|6!D%SV^uYAFq#3+Vxig#5^+r&rC>a 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%0AbM^cAO`}3q*(E;SiAU-&_}S;tpc!BK#7(6 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

RGA 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 Mv23$!x71tyA9VFVod5s; literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/glfw3.h.4A7AA4589B3A7536.idx b/.cache/clangd/index/glfw3.h.4A7AA4589B3A7536.idx new file mode 100644 index 0000000000000000000000000000000000000000..4f86c8496a32fa5e82be6c9ae4f4770e53ece947 GIT binary patch literal 57902 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 NaVQrQ0=R$V@BcS}TsZ&$ literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/glfw3native.h.014FFEC0ED3EC0CE.idx b/.cache/clangd/index/glfw3native.h.014FFEC0ED3EC0CE.idx new file mode 100644 index 0000000000000000000000000000000000000000..b61a8436016eedf02a77a95f7d742be58b0813d9 GIT binary patch literal 3184 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 NX)e?0$t?OB`ai>5gb4ru literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/glx_context.c.F619386CB1A90A48.idx b/.cache/clangd/index/glx_context.c.F619386CB1A90A48.idx new file mode 100644 index 0000000000000000000000000000000000000000..d90d98f95520ca5c5cfac4b29ac50f3c2a8ce36a GIT binary patch literal 17940 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

CpU4qb$8|nL-^E=^ZN4RY{SGbi0aldjb}v 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 z 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 ?h5L=E69*7&IHgFMB9Qm!JIbz5yT1RwCS3u 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%0AGRt7 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

APB8hFYpp%jT2J2d()7SV>B7$d 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

LnW0OSDkBM&lBP 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 Yqs2_4qpj~q~EETjxA{qnCa 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%0DJv?_xkH-;O)Ks?*p*U-*+EPV!yxd{(phD_tTmj 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 z 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 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/imstb_textedit.h.7F8427DC7CF4AEBF.idx b/.cache/clangd/index/imstb_textedit.h.7F8427DC7CF4AEBF.idx new file mode 100644 index 0000000000000000000000000000000000000000..a4981882a9ab8cfade0e5782a64aed1620672348 GIT binary patch literal 18656 zcmb_@d0bV+`~UHtIm^sBTrP51E?o9i#0>@a{iwNRsbyJKT54&UTV`2`qLPRkDvF|r z8zQ)GAfQ&Lgo3yPsNe>viKZwT3g~yP_YO1tKEK!Z^Us&ptJl-pdG5@aXP#}InHk!@ zZ{O0lIIi~>{bx-YJ7YB9IL?Uwn?7UOS7idn&BkC>V$S=czPT1*{PW;k!7C;l#{Dqq zh|A}E+@$iG(UbdJI{vjQ7`e@FPt(+u!@u5pZ|;rEZC~_1vTA1kW88l2`q{dl^rx0> z`f*mb4I@sp`(g6^!0h*`rZ{Qu)aOe7RIl#-;_;Z7&z?uef&uqG`T5M5&!2Cu@b8xN z=fWxV{ylsq|Je3Y;NzhQ{SHiCYTxBW-fR1y&fUID=(>LE*suEBtSX)}a+2qnc0%1J zUAOFiFFDa|L|rH2r9(njVqsjc3jea%H5GFFM0L!(8MaK%~us`2LAjoYSpgcJ-=;zyv4y`b3O`x^zFSF zJ%UrRch~>a;^BdtpSwMH`0W?p4cXeF%dxcuT?-BkdLDUcYNgl6EkE^+ET|~GeZ&|yS#<%_Z zVv}KqKAha&clYc$9mZYiSGQqMhlY1Uvu8$(*c6sHsO6m54KrU&cvW}SWWVsXUFEQp z&4<2>ANXfRtFMO*IQ~wTl9t~LxK;XRRmbxKH=anEI&s!m_q`d1nlJeDin~)m<VpZu<2h5c6yYCpQzd2~PDjTxRVbEn-1O1SP>k)L<9 zZ$wA)fJ13Z^&?lm^m1AoS(l#X;Bx5W4{rHiZXH(VmOHF}#EXiQwQIkrt^cFdqdRk- z3~Y8QFS?KO)s;(I^*fVdwh!vDF^+H9=Jv;{1LBty)N*DIkEa0_NB&&j5VIw3(tCb2 z3tN6$+GWYD%fCwDy?a&-twhC#?Z5ncv)bGP4ShOb(^rnY$2~;{J8t;)yx-{bEANbT zm_PB!l(MtWr$`sBd%BNV>b$XL>8SnA;y1%5Z#3_%h3@kgv;eoo2L}c(Y9`PB^Wdr= zmlL1le$aAH%T}k4csDq7pI(1sUt(O|uvTZbp33R-$*;nz@_*Vng^p@pz4FCpZ3f0{ zcbMRnAe)SBvtmO}UR}A3zuft5&ko1H7ZaL|$%LIZzW-!n-=k8y4vYIgoPOW$tH>Xm zCU+Y<|Js!M%5&e^0W%&y7!;l2x%5nB3!jT~woH!9>vj2XnD=sF-1y{aJwNciQJ*#= z!>~XeP;$%&Z%@)XnilBC4|P0w%l)^zP7fyKeDkbR(;goN4ICApx5iIImm^9}#kc9y zHFf*Apg)0j}&W(uqG^$$LmVWTa>Umxc*%M>EcFjiHQ+7@-={3cF!ra)O6YWhM#}_T@ z;{BdJY+3U6@5@QQ1pN>xj+^*?@K2*avEzm>8p3-IE8P>)-03<$@o4kvIa2#e@$Xj@ zociXo&}DwJR*!KB7?3=4|4FwVO_uyv_H=ISkFDR`IcCWH&d0WAjB*+=;oOabBj1Ak z&S$N4DL>oMJw9^eiaw8G7j^P1ygh0~ae3AArZLbLrN(b*wpF%|*yPVCcLr4*#M+vxD_1XVrT^ej_4MEo9~V~Gx!nydoq1m$^JVUtxLMzO zm0q28ZJGM8>a6zN@Y!E2J+#kZa_ZRZy6PA6(sF~+k5&xkVh=jEw{uJHJ7vMgk+-_; z7~lKTy`8Qu^K)AKRb6qf=6j^QuFq@ZLQLNj+-fkNn15vWJBwGid<^S9SWr>A^pChx zt$sW*u4?amSN#I|1AY>}`aTalF8Pn+M!?8d0*tq;eB*H;;Jr z5$|auoXJ`6w{+7R9QFU~r_bE=Tsz#&0v;~lO*TThsrLBohpKwurE)*uZej#AMhLVK z&SX|PTDoa<`T3YrBkTfH?rY5R1gKAdmyK{HSGk*o$MLs4(OHf=f>dra=BbC?^{}mt zaM0I*>lDFVnCBM$*Gw*0&%KSmCKWiQ0+Wr9uW8vP;>M-+Wx*;p3HS06s4qb?8{te% zn{>B~ls0RiC(*AlZl*Xf??9BqWdt7Q56!7R@|8sIrx&%K2Qs@6GF>%47*47BF> z@bfPp*NoJ212D^Dox@|D*+vM<^BLYwBgX#pk;;w71Fb;n3S`offSLqMmO1sa%;__( z^TQH!d6deH!92TpWjF6_Bb><{{W!QicRRRaNUHtCPxM@L6D+A$*LUoAZW6 zIp>igdan zo!&->fNRs2AM74^^-De16-)1t&f$?R&_>8e=Z44mtUuj;lAfE3Kc-Lz3-K~p31OLg z<14xKj<+$(LW^Wl089bMMhMToo_p&<1Ln@qb3-x9B3@dA6~amgOK8N(ijQBN#w?31 z-7Mtw3;CutLU=kid%57cDSD=!8-_plsm|dkRy`{rEN>|ROV{LF!7Rhyu(&_f`C%3d zAuLT!kN)z|y%BR2t`(L{8qlQyy^Rpbn2tCYGkbj$sd7^>%U+=F1pzj~nY{FUECTLO zePfR9$&&dhHx2WoLNyio*@$Hk{46}`eTU*pnLQWixz2b_r*)pEbs;uFzNW2tpgL`M z(Lz147Hn%BR$bMJi*3dC4{A{A8V;s9c?QE}oW^kfAbm zxitTvjRR&`Wci#Z9!BwsjS!x32ZHWSTo`gv&;4xSNdZaanT+(xcFiVBbp#p2El@OL+y7>MY9>bUDxlb@lnNBLhPRU9L%ar-goE}}D zdPU{F!jno?)MUI2R$__rBj2cny{l?Sf45BKW?-KEqPkx++X!cJ5rZu}JuVz5918L< z&u5sY5;|AHHa5aR9|IQ_&J9_$ziz|yugg_#B4()-lv=^vMl9ADfP=@av91#mUJt&l zax$`&XwbdzPBs&-1}HGH9ARyQ}9G zSeEiPo%e6pRagn(xs;-<4cQ`Asodvys8~gfwTKU>$rdd(NpFUF-`OLpzUybzdaf_- zCKX7jINDhW=_YEG9elSix>n^T<8Dqv^)!xCR>ENy+0!E7s@}CeZR>~Esoa;CrxK`@ zz|%%7;u~V&nKpLZbiO0a-I}=BGPc5nB|rTVHSE&rDXHa?_goXP{ufHlg;KaRgWxz- zJ1?2eOC2a)Av>>-nf8^kX{FrQekA!}N%n+a^iBZBf1lla1W645PVT%O@$E?72e3Qy zi~?u>hQ}8IlZ4JBRsgJm=31c*(N6rmVo;RWg{UIH zj>|JaY)gC^z?$!|Uknp$MgefDu}VO!!ptXL35-{m`Q#{`IZ9ii z*CeIpku8xXOQ&ktK+OhC$;4Hy6u?qoPjD$W_`4g98w?`Sa&&SI4&$~z73(bjo6eKs zTpgdw;!`^Q6pN#fOB4#D{0orF0*c#p%|)f(k2DIZmI3=`z#)xUmUbNWIu75WxCnk< z1m`wtw^jZ4tyRf;Z8Mh-)QFw-z1ufvR>;Cm+-WP+^?Y`JdDE zq&N+_q``I+=RqY822)%L{YqgEimRZx3St|z{;Ap_q>Tp%+MsbA{ULkd+xKeVclw1fVk`Uc&TQl+@X01*T>jXby@@6es;wwK(JvhXRSOQ?+8`QH%nK zuT!Ao>RF)U3v_N2 zM~S1N#2FMPh$9oksT60xDH$-j3H^s6_)C)_SjzlMJ(TJp=)o*;Q>X&+p|OsIz#^i_du@aXYFO3&dDpB#}zh_5*%D za3Dg#DWe2asD7#1-xBv^??VPMYX^aH5crUe%-S8G+yOo$ zWSO-jaY&Llmg-xUY|N5FsJ@lUrgFIz#gF9{kLBJ3lM;bDvK0pCj34oxAMu0e45L7& zC@_%DFbPB?fqqm!H-m`HpdZ!GWY9Ai45j+G1q5sX5maBdf?iv}Fsh%GpmQY{L?)(U zAJydv7)+d&iVd;vOE7|1ri#6CP>j%lxM>w{NP<=i9f(&}ajfo@Bn%^7S;gsg*dw8L zVDjZwZ)>eSo9(vj>D0Nwurvu!_C@G5$$AgJ`(ehCs{bN)_}wY1I#g9+x(B z#yRa`$-G#KATu^CoC4=?`1n@PuJZ7C3!0yF8@tYrW(1DL6modV)17XL1(ze`L2 zTq3JWXaKZdlr=^#&w59+%s_t4yOV)bEgs16z?}?aahCRZz?Tf9YS$#=H7SVBXrpZ0 zC^I-oHYQO_%5`4IR-~ih;uVix@g_R(bAX-$6E&ZOg55$I(p7D}V7Fc{Q*+rN*zFL^ z)LiNXyL!P)%_CN{ixtg8%T#TfXxJut5iL`-G|`a8;@?HX@1hr-SfOYrWO1ozC}r_& z(Quo^4@AQQ7AHxDB#G%STMEdQ+R^^YB*!wkLfD+;z$lqX2sX=(o9T+-1VJ{OkeU7p zWkVs0i)BMGi*Lw=8!Wyj8}6~VS~gU(xL!8Yvv?6SEP~8xn6 z9grfd4%tetbm7w#l&&}tMq<{u3T`dH5{GWq@PHyp%xTpBQ+bjv)CsawWhcVg;ybscz0EM zh2SgXO7RZGxI^(H>O%_S_Liwx%HecsN1@>;b@G-C+=m(POXB2Jts2@@Lvv#>M|%z( zo8G4gzj zT2Ne#)N16;VxMZ%n&NGWaT}dDnFm&XYptJ5+^ju-;sfYKCSun9f#N?D@A?`#bwAa0 zJTPllc*iSzFi~%_b{#le2Z2Ou&DuH1?VQA;QpzwHPy0xFmN9XBU8XTTNrp6hEW}=gkhDi8<~NMcWLeFVGk<$IK;;xdn(#u z#1|ubA}Vr(fqjql{DS(PGzFz8UPO74+y@Ei9TrT)f&3mHevj`@L}3YgsZH`gP7@*w zRm%rM^1(l+C7FY6u*GJFJLIes}Wj_j8r)5kn=j^O>q$ti;#ihGUQT*e2DOHAX3CA z#X#{^#kf`RBr+o>JGk^>J=LKT%>il-u%i+x1F#GrimwCpI@_Kty_+o!rA{kK9vUSN zBN*aRZsMAeQ*pXhB6^jGjeB9Ec3bDUs5OYD23p=C2U1Ou?HGzq?FcU%VFN=puV(X3R9#N-cBgn}ic5LtQr?T= zdwjq>z9q$f@eY6SZWLGX4pl5Z4UDIO2Nhi&n2-mivv@65&&~f*PeVR1QH}y&R{)$T zz5tX9G<2z22{4whBb=2y&$4-4rQ})3;-#|ZQW}BC!JL3>r*TwNhk5;BzA2sBue|A3 z-h<+7;F1m8>4%j9V<~VYn4IP{LAEnIV!PxF?@fc{5H958fzH)g_*vKbq(bdPr@ zL*WDhe3u87Gztlqfk5+o(4CBB*3xCibUG=sb`rHdi8q$E(_ypr47GknW06^lQw(v6 zKiMLhwM4~`sQ8mDAvr_DiG}q5kqTum2;2+8$iS+$LxMXbC!(>c_E3TkDJFc_w_A@H zNk_OkBf(6XHJY_Z8Aj49k$700o9)n%{_rm3??SgmFJU`_#HwyRfFz7K2ZA1lU^D7| zjzPa;uocBw&^HUVr1%{4I0u_i-+c-CU4pGBz6^aY!_u@A3@U=H z>CzOzp+)c`ier&eEb^pFbrRX1WJRBk+T^27RP@h~{WDgy4X8~6>O@3Ij+$}4U_D@_ zqO9TdHSAt62IymeiEcs@MV~}5l4GmA>=`ECi2KcK@?v=;srJ-C`G6g8OhSAS~+qqN8S`KP{ajnlCWJdZl_5C zSy}9?t+xP(pvaQqV-M>E0MbAX{&8AiJ@qFIDn4)L&*=>0EMCPYtx_d4HhMDc735z* z1J%-1h+oA{r3CRMs4<`Ee(~tAtn>#dvQaDL14?;~gbSl~gLl5chf`b*Jj+2>;*5>j zP0@T)Y%IYWwM5Ayks7>FE0Ej@Bqj}6F1szKX^2tFk-O!{qllK~z2mj`Kz#pH-l*-D zJ@?BUNP|(UlTCGUW8KQAt$?N#uo35fr%c^6A}w83wIe$Dh|Zs?Yk@AXK-Y`nbZAb8 zjpvw_-CGpittBz_=tr>WBiNGu;yG;j95&XMag_vxrJ=WJ`wk^=htfC#xr<>ywi_69 z)fOOe0dl0Pl89UrQ2&spr8Y&9mQEFEDLp~I2(m$ zqh1uBK&BJyX+$n+m5aL2_S;CjjU1^$S0L946hQG^1n(keiXS5NAu>^1i(1v9E(DXZ z6!z}cdnQB>X6>@5UKRt%;^NCSqWXlz^^#gIG3_s9_)_*G{Qjoka=(y0`>=0H(a9+~ zZ?Y8l$W$lqq?jZjxQ=4I#X`SevnXz+l`c2iWf#&;49gAKZnlsHODf=Sh~1eShOUR9 zH;o_1pvy6Khn)qTv!Ew!KMwtm!%!B7ABSC8Jn=Z3PVqVDaE^6i1<a=wA*) zX?r;wSPq9#`~o(8!Q@!lI)v7-sY?P<5?GzjL=KtAM0K(ZDP^oqmLpV7Qx_8cuqauE>vGb1I3ZZE)p^AKO?)JDJEwf_ztM`b`lxE zti_08jOaJ>M@;r;0Q(TC=3Q;JK2ilQ9tZEzO zkc~86k}Gd-E|^-byV0p;0yUGZIQ$CWuWUu45Hr(uaxd=97SnPYj-)Z<3{Jt9HQro> zBO{o#yCS?Rwj}C}OV6TOCpN0PSz95gDM~%U zYmyDTvw=TdlTzSON{@ZXwZ9R_cG-`JQpLr2RL6E)&wJPNfpnk--m`)Cr#KGy#ersY z;57iPVLv1f^vVNo(GST3BlEy#6h8ol2f&#g)BX+ge*+_nef|bP6h{jFkwOSPwvEC! zQ-x59*9ms(1V<9^@wt**?3*MGBA!;&Hj8aHiybLW7MmxFZ7AL%w%Q_wQ@m9)Y!#g;-YK@) z$+oA8ty9Ga+P+IP>|*(gMVDgHgJ?J|9Er{)qM5}5OT>36z9~B16iqCC>!$cN#Z{uA zik|9V`G}4+EPsvIt44f_@;8Wv2A01;?A{>uq3y3k|5sw;{Q-Qj#G2<_mdM}px zQ~o%~5XZW&IH^aR)R(relKfXmOn;js!zPwLQ;Nu>SwD78l4Bk_-tSWQ@9agL0;z9- zG>G>9hvfT*6ijikq#O|`Gi8Su*)c|D=DS1=Um`c| zQt&k!x$knB8Go(pyH;k#Une`SlbP`oWtT*m8Gn;(-b5=*Sl{K4Z8Gyc*|JME%bz1h z;aK79nU+zWu&&tkc*$@6hHvB>3 z58kTEhH@6)l?``U{8%3#? z_FDm&->-!JDlaT{z8Nb+5PN111Ou&FkgEkx>gk^deourJ6xRqIH9`=<__D4by%apijRkyJSM*F0+YwI; zv`eDhC9!cQ2()t1uAE|3`%5(bC3;dtye~T5XFc_OanOD7ecE0ndRI|TiN9C0tETGi19Ax^o6vu56b}F+RPl&5XqYbe394sQh^#` zlBiD-O=O`}ZI6QX&~oIMscB8Lo;N1=s-uP z=TSZHOn!Amkp1Af|0Gb%!dp{Q>ZP076Oo z|IhRtUa_v=HE8`BbfKpE8hrQ~jHNhIXcx(v_I#oDe1UNlQGy|gy&M!P_{It?iD~2e z6oSt(p#{au1-s>fiQxY<{dI!JI-waceSDWr@JSF_5d5F6V7p+qT`>J`rf>H|F#TVd z`hPRk|7M#1uW148-=+k#|86?of5@S%=@_oFF*rr>Oi@CJ>TiFz_}I+*r%Lb@gJ*z$ z2HeT5F0+;_ipioUQGK(Pi^N>^ZeJ}DYw6uS(jh+2vcA(H`xmozSm6&V?&P*1`7&G^ zvA)?MjHFDAd$2y#Aq{3+H+Fsn+mH$+al^O=>vJ8#NHTHUgY}UPX)tRi6m&ufAU7Nd z#XVS`>JUb&qO{VAcvmSU{6oH`@aq(oP=k;G($o)ebfAY^hr|o7I*}j^z>) z3!>!iQS^3#swK;g$uiTvOF_G+%V~W6gKTep$QP*Ed?e0C3Xu|a+DP1l6j}z^gbbUI z6U8Udpp)obigQt5E?Y*)M}he)E<{d+$c^$>BC!%FL}a+yj|`Q_iQ;Ey@G~@&;#w3~ z%a%bJP+$X#=P6F}6gR>zcQDp9fAH`=KEb&KIb8?i5?2JH^)MPO&vQQ*4dS6kDS)#nxy{u{D}fY&Cg`ttL;gHChr(&bYD8 zTAz3kjWBC9fUlt@?PhxkM%u{>FnkJv*9GJ+)_kFU%K6)uG_KBzW`U?-AI;pl- zU1aL`=JlIbT@+hibx~}6)kU%ORTst9S6viaUv*Jzebq&=^;H+e)>mB=TVHiiY<<;5 zvGr9K#nx9{6kA_)QEYwHMX~i&7sb|BT@+hibx~}6)kU%ORTsgeM2j7!^;sX$0JC-! zsYhu|mZS?t?3>>_@uQ6OfUgHmBp)zqTLp2e;7a1HSz9FXi$o{ln$6lR5#ACT?>pj0 z2O_+~;%B1zjHb%?+JponsVd>}wxq^T_i5JFNN^3?zEOf3S)3uk3>KG4YAO5s*Ajfq zwy&4f_0;{EwKKAMhQ%*r_=2jYS&M=&3NrIq2H`RmCqS4$F@6jA^=OOur%(HQx?=es Qt$n{X8>&4Xp69s#0Z|xal>h($ literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/imstb_truetype.h.3094409E29ACB5DB.idx b/.cache/clangd/index/imstb_truetype.h.3094409E29ACB5DB.idx new file mode 100644 index 0000000000000000000000000000000000000000..34f5f6a6ed7b91d13138d515f55027ed8af37ffa GIT binary patch literal 67882 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 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/init.c.DD5A48A85530AE07.idx b/.cache/clangd/index/init.c.DD5A48A85530AE07.idx new file mode 100644 index 0000000000000000000000000000000000000000..3125efe74a1a1bf6b5d849e586a07da9632f308d GIT binary patch literal 12136 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 Bc%c9Q literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/input.c.DFC3C828DE1E8852.idx b/.cache/clangd/index/input.c.DFC3C828DE1E8852.idx new file mode 100644 index 0000000000000000000000000000000000000000..5e16233ba42df8605a432e68d51e51ba40083d1e GIT binary patch literal 40158 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
`sZ@TO23o$Z^`^ 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 Pci)~+!M*eMH{Sn0QJ`|s literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/internal.h.6CB304F22674393A.idx b/.cache/clangd/index/internal.h.6CB304F22674393A.idx new file mode 100644 index 0000000000000000000000000000000000000000..92c95503e4d75e3e16d882a9c0e4fccc76a2a30e GIT binary patch literal 52852 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%0APR1A!f02cV#|V90*utNLU!D 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 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/jar_mod.h.CCA482DB947C5FCB.idx b/.cache/clangd/index/jar_mod.h.CCA482DB947C5FCB.idx new file mode 100644 index 0000000000000000000000000000000000000000..ed76b049115f09ef228eca73c650f592e6d501b3 GIT binary patch literal 22620 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 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/jar_xm.h.8D41367F0ED13D7A.idx b/.cache/clangd/index/jar_xm.h.8D41367F0ED13D7A.idx new file mode 100644 index 0000000000000000000000000000000000000000..5b925bddfd15bbfcc3d23d5d40d92b68ac3cb226 GIT binary patch literal 59118 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 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/linux_joystick.h.C8553F75C24E036B.idx b/.cache/clangd/index/linux_joystick.h.C8553F75C24E036B.idx new file mode 100644 index 0000000000000000000000000000000000000000..20d311285c64d28f7f1917c949ba6f954eca4d7a GIT binary patch literal 1970 zcmYLJ3s6*L6h6x?w98&DA)tWw?t^7t;35c13oeU-SP;Tk$rz^cbToB_fDm+4h7+Z@sjtvgs;QDz4C;f0*9+ zwfEjh^Z$_*^mddMZ&0kU%lqpGEaP3@$8>pKY5Aggb8w78Rl2R}#(K?4X7lns`|h2g zJ^I^R?T;PJw*%(;SS{TZwvMzEdtLHV`Gnv0^4#9B;pGt0PwuJwbg)o)_1eYw%2re0GxdSPgKy36bvuz?ygIX&+1{OKLrLAOWY40yhz1AeCSOf|^FVlenZX_@^(YFN631&(xUIjw>Mc6X$e_$+Fg z6UhSM=Vx#;)D$pXb4xz!lCEJk18*XEG!q>_$^E8)ZIh_m-%B0KfCr|dWKk-bcJTqz zK7)GJjRP4h=m~i^7jC40?QlHv)opjl>U>^gMa5SsTssx!t1Z3~t;6sbE zZRf3jF87pkFv z-GBU=#BRA4e1}ZV0I!Tz#!|ra)*}}4;GVG&Ik*w>2&V{73IaL#e}Kdr15IiBo1e?+ z*+EW0Uc3N!w&(+KPkR61zg=keboc2hUI6TdyqsnEBJpcQi(ILaaiayFj2<<*jyQ`L z-Y7TvpmI^*q*_onR!QpF36-~l1m#V_RMw6#%9@Y}nnsdm3CpstXZ)E- z=GJTUfw&H;oKy=E$Lg|SQ|qZG%8#8G-k>qOswNi~U<|@uv;Y}^O5YJj=@Uvp_elBK z*1ChKTk{Jg3?D8DXK+l0H%rV6j=}Iz5GBRU7~Tq2DayHI<;};5BWueDuR^L&;}mEm z5*B=fcZnV$!%=TI%8`tOsV5xa>kY>*#Y^uu3b$j@n~@u>LbwH=AUA%Ku;34@e)oR* z@l&(v?Sv#u5+=ucK*x}3!7g|oXay1$e1Ifq0TQOtcf_%agsJ2m;VZMv6Qz&(|073Q uRaO&jN1U)KLnz75%gUcFyeI^C`Ka&(K>7NWANp&zHfGI75n_c>1^)xVlPiD# literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/log.c.CA61F35B04D42E37.idx b/.cache/clangd/index/log.c.CA61F35B04D42E37.idx new file mode 100644 index 0000000000000000000000000000000000000000..e3f53b5153b7db3796ef502550ae2e98386571e6 GIT binary patch literal 4894 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 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/log.h.032C30DFDD3DB212.idx b/.cache/clangd/index/log.h.032C30DFDD3DB212.idx new file mode 100644 index 0000000000000000000000000000000000000000..5ddbf402c9274ca1822c08a2e0c157307b13192e GIT binary patch literal 2042 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 M#hTyYALY-#0hMxn(*OVf literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/main.cpp.C941A06453C00054.idx b/.cache/clangd/index/main.cpp.C941A06453C00054.idx new file mode 100644 index 0000000000000000000000000000000000000000..829a2af2fce4e6e5a0f495352e7aafba5537660d GIT binary patch literal 778 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 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/math_bindings_tests.h.991FEE567F64F8D3.idx b/.cache/clangd/index/math_bindings_tests.h.991FEE567F64F8D3.idx new file mode 100644 index 0000000000000000000000000000000000000000..f13145980a0eb7c84ce537447ceecc0e527f507a GIT binary patch literal 228 zcmWIYbaT7Iz`)>~;#rZKT9U{DWQzcCaY<2TERaqI;)*$;ClB&ADDXI3>|4zKcCO}~ z1_hCoTq@fp?bv&8_VW3A_z!d3GwG6j$aZDFSVfn3WTEB%x#%4+F@45MX9vWfEuL zWMpJuWnyGzWhhEbD;5We!&EX#LR5ei1Bs&4oJ0`2xG1@p8^mC)x_2aP)*lfq1_l6N C8bQ=UJ81`QI}9hQ6Lx-Cn7`Mx z8Q$e>a+yv)AmYtO$#u3^0k&sZlU2*S$bum)ZgDg-8Cp{Uoa82Nu17HOS@toX!hco< zBmgpf!Sj#lVr}MU&~RafmzT3M1LdT6g*dsuVS6uLD;!?{(hZQ&#p z2gz9u6V<4iGD6KnYcoBVCk!KB%D`$FmO|Y)Nk^Ai-6U6Lpk^hS#Lef+I)-b5!*o%X zNtOL|omZxlo9ldf4UccGvnoq2=$kYAr z03l*Xu)#_; zKAeL0S+lN+KvGpaIUtWqj@d-ns$|0wd5?FXU(k#;_*nfSZ!V=<}5EtLlslA z9SzQbKrYJ}+!S?)yhaFAhLr0d`Ki2t9Xh5N2qhoY*X4RKQ#<$)$Gm_O1Xl)-W}=@$ z>A$Sy0GlOg@^q2^jZkH-vW7_h4BA(jL1@Mu6kj&Ub@~xr-X_cSqA_4$(l7|EFfYK*hAN%0{785@*0G!*!z09u>Yuro@U>#Rg<&?+v|>VqX@ zqmy}r0L%FdkQmvLdNm&ZYwbXoqYXqTZALly5<=`~J6eVLpzwEgJga6Z|mrb>Hf zGV*6a!1=IknorU-pN$yyn(KjG+IQ(3F1-1Afs>=n4u`{R_ zdGL_?&lHNiQwAtW>)T>_U6n<-t{q1Rq;@8} zURHzn3x$Q&Ea0AdOUw4aEMEka;v8tT0drM0&2mDutopm7*R*oj!9nuYuxiO_k=`P* zctA)$mTSW=!tpR$=FQKir`&e7HpJo+x1zhO)cEXKOFp{HP}-xF&Sw1= zw4u3YKOY?(pPeQ7JgL`H_{f~s@9~-{;pQ+aT$}64Ajps}d~#!WmqE9-y&g8*u|&1Z zq7><(eYVuqi?lMl{Sdcx4wq_LWaa>xUM{odCNrE_IjJSk%NB-8RkvdR{iPX@+@8TY8vY`mWyGJ@1vK=3k*{hN zAn-mSc>(%blvl~ZEa`%Uho&-P)lFdWu1x0z6BZ;VqtOeI8R#iY#lKOJ2wY|?ytC#; zU6%aZ5UzQCWNTYLFn(B~n0jb6=;c6`*!bZ0?uD zZe`{kzPi>3PyWMfDcG`Ri;T<-Z_zZl%9=^`$)MGAFrg7oaKw`-boSsOO#4G&Zt-il z$&oO6^NMV6v+Yt|bcYR(r|DXZlcIAiJeHQ*&^}-QwfT71!XO7Xitxzs)$y>Gw6G_V z^aKHJLZ0q*1P7gIqv`DDY3_sU1N>(3 znF*xQNaXYO8Omw%0Sv%B_KJW|Y>qR!!Mxte1*?0gy)F z1u$<>z@Qc|Sd&GEy}U|mT60)#WF5?Ap(_yfnYa8T70P|qLa}PYJXr)FUYM<~VymSf z!DX=m6^7+G`8FzxOeu=f0@*Lu++1{qL>A`iS*9zPIkX2}NY;7m7&b!*@EcOf&QoOR z+}A9=@^0il@dhHL1#nL3G;eNE*l7%bPR+XuhES7K?{=TN*YpSx9*X<}fyQSlmuKtZ z)P2zu>aFHryQ}jB=mM-2g+&FTNd)A=uSdNf&odok9M z660C6vDw?e5P~)*d2)~dJpW^Rs)NQ)pM6V8Jy!2nMPANyJ#WmN_W_uS(j1C9E3CH9 z9FcXk0^tyiI-gKBEEV4Xee(PbUkGOp1t>t4>5U9L%XO1|G8j3ezbxxA#TGNMy?itP zQTR7)nuA1I=ax+|ch0(4l!liB4bRKtckhpn4$qHY9wa~0y+eHa#B4OPzo)2mLpfa$ zb=EmL{?Bqo%=BNUAS3~uYf8gA%*3`Mh-J1s{0z<&eP9-LwaCpzGQ&mmU$~J$lLrrp zQ^uXn(14MZPr3m&*A?88b+KBkudYDHTLJa4w2{bAIi0R6 zWI}gT8K|-0<^hEL1y%3Qu zWV~9Hz|1eoa)nTqMjY-z@DYF5jbQ<87$}r(42xUk1LXDd_dg%YAp3{+ePWuwIy^l) zR&u*HSF;sS#5X8`)eG*Enhq?U>&r!2e2BhI9stb~A_{^u%+U0F^wZ&+H^--wH*en@ zKP2*WW4QY?4$J(S;X$e0tmqn>BEK*~i!1S^4U?4=HUZr5d~V=ME||zT==FDI0UnzL z&^_Y0H7tmXyQ>M(OB6)lZk5+~y3IQWfay-_0^0Ka>0TReWszpkngef_TIE0=gplNz zb4uIojx>T)i*)XZEz5;cRhf~7jcmMOSD#nwOty4ugk!KP)LW>Y;32Xj%r7NmXhC{Y z`?T700K}T_*^q=ctXUEh6707o^a3FIKDN@Qx#hCzHmR3#DyA9BurT`(nFZvk0m@|d z0_cv1sGewMVga(c5jhDpJ~84Ou+b%&=FYM#IW*Uh1vP3-e-zGq(;i|jh&3+20Dm-u zHoaVAB492s>`k)@MBGtn zWHs_x5G^5$Sip*H3P3ZLFbf9*-z?J^$P;)(lu zJYWo$RepuyT#`I{2vBAv*j8&ZsEml=9Q8%T6h=Eu(Y;0~HE=vPX+fJAcZ}$hGEfWx zZv|SsG{3rTXbM&UaJn@+k1s~YMwo`32ktqb+0Bpu@aB4e0%1%C{ZRPMoV18WTzyP> z#Eby~E-b0x5tu6@cWy&KwfMF~MGSRX8|pmCC|Fp>e%97FEbx#2zxsEX_amxif98R<>g@X90Q6f-B@3M7o4yhN-N zhRS{=4l!yMFpCySHyRKe7UKExf@CG8%`E!x^qeTnL~FoU2~2Im;)F1~6LfCXzJ!rOQRY7*MrsHKJx z1Re=`t0+SrUA52`-JLC-n{`8m-fIvCiTkjr(*oieDHRpp0&$9 zHK5R93dqX9`fInhEFswb%o(U&g8Dx`m~;g~8TR;imd#O{iq-v(cu5+y!wo8blFlp$4+d6+6Fz zTygmBWNhfM;jfZn{Fod5Lx`0(Y)n;##JLw`2*>dF^} z%XtNC#DA&IK5k*>n4w7McEkplFXNBqWKjnm4?EqLR)-@v~Ww<8)b z*$Jj#2L?{DW|cYdyQoFGNpsMh2)}PQ$T|l(gg6AtU<0Y2k{khU&~umy@qr*W`BI|z zVBz5fgN~ zE~%1XNcyeEA!;@9h~c1hK#~q4VOYp1TVT?W;VEoGy(XvS(!QsRc71<#CV82 zh$_i|*BF@|&7E4dJ`*oG@Nqn%$0yMA;$TlopjTCfngp{W7Wox0B}*jVUn*Vbk9bd# z8kAfP%sQ?Nv0-0{I8vO%L4I^OJ67N+yj)*hq3aOY1I*ro`_51^M-hNQ*S{^RNqc3H z6<0>u5%~>=HCFDAGO%I|J{PEBNR5~Y(;-s=*sGUIVDVFwKk0TnUQZV}c-^LpD{kj%BFlGxe58bQ@;5Lqo^+G=kb;=vH! z3>8%3@PtZ;n^J6KRxi7|P0SlP`m_*!7lvO>D}~=H&@q6TA)Drx=Ht$9!-nKJbsMwqg3s6K>L^`lq>4T!7zmQT@`{71;LMiO91%(?I3@NX z-6?MhRwi2;)KB@1D% zsm~3JCuZg|lmVRsMn{mI!JIIJkIVVojC%1wp|B=4lQdypR(Nk^DQYE97oY^uHG8>$ zoMK*0n52<3R;$>A6KnZ|`&mnO6KS zSk;zsmLzmC;P5i{3>;(+zMdOvJZD+Q>`BxFuB!6NtZ8y-@cDs>W8u7H(V{1gJD>r~ zZfqI}IG-_TzR?=c8o=AqrE>8@1Uj*TUg=`g3>k!0OT3hvIm_ z*9?;*F}=VMsf{QwwJf2pCkY~JSzU@AxTWJgJzXjo2S{OhwJ0ym`mmoY`E{m^)l|&# zkNM1SJtL*n2nD72vtqUI2!Z;3wul2WuV8MzKeN7(!5ok`JawtNH!=S9M-w-J=$bT zj0nHr@8A#-g$3egp9(<+{V8AL9k2zdbSBqUb-RTMSPoxCaTnTG`8QCt{#?|kY;C*v z%Z-vwtFo>ses8r91q1Nt;(EgCZ|#ORX35ZY#YX@MY>ZeVQIJ)rFWkMT$+N!)Jipe1 zAo*mj}x)Z}8r1tq~UaUWD1>fuB z-Fi`Hv6-yk1x>}w7wN-0HiaY)thUu)j8QpGUYwE5^RSpzWp1!#JNaLSNB>uJCVv5| zi9GM?qz$_@le)l3v^!BR{*HbG0BlEeAwnKJf7t2-Up(hd-eisGW4vu=(#hL1w_&_a z06+FQNU(R9$ssR#dnT!U@pr*@^6ge<(appl;OzA8$7ijXfK6u+bn*a55HV9v|L`vl z`#R8_{F+_LSqx5mcA47e(CWd*JWY<5WR1^?jXkJN-hiMg&vYk+d(qy))>Q}2Np{)Q z;b$WC9)ryKKjCs9wmVNrK4Jz5LhP>A=;9=d5wK0n+~i&qmh%|)MH&_#fGM-=u+Le6 zr~_AGJ(^NnR3S39h$uEIOH-|NOgxuJKjfdYX=><`0Q z7!=}aWE^-R#HYPu4#@ULUSKtf1C~AVl3`>Chi$XB+96nY(ASMK@L=Ek3x; zudcW10X~39JYfF%;ieDFuLZh-4(&l0_d6||+QMgzp{9^UCc1~Uj;?Mb0HVE%U$UOW z`qWu=n@-J_R_YW&AXe=-HRy7rVZRlopyZgUBc1~>(9$u9ceoG{-u8dN19JWh;xt>^ zp`8i&(?R_lI_$o)?ilq!a+;+dttu@;wrl17|^VstQ6xogNq%zhu>AS!d)7p`AJG zf&r6^oi?{C(3U|Yy48P>Vuk%f#m%P--~`%J{~v9?z@XT<_r0d5$LSOLq2a zr7Uv2p>xo>$p5;|6lSW~SFFofrMbDKE^qBFl#E4&@GeE8uELu@N4qF7$oay z21g(S2EXC#Sp}S5u-b&Z@w>3crn)^`H|5zXy(zl8{59}CC#70yJ_Mgj+QaB55t;ui z&6eQO*j|i;6AYkvg4N;R?l?|9WZ8-`6mnt#J2bbIImJK&W^k2IVQEHM&d4v3(my3j z^bT(;O(kzZTWublf}5cZk#{@Oo=TzhoCu*}gj-4bpa#!!pqNc|RaTA-0=e6*F}F&l z+$>~>>gyEl8XV#ow*}Kjiryy?B~%*nOq?Gpue5pqSU>X~98V6mW}hApW%s@7+OFw& z2`)ul|2!>5XVb0k_1(stPV%yz@ET2IjV9^x64O_?mWRLS6_PbS^x6%9T$hVdgYSZT zX4*OELm*pk&<$gL=d~LG*{~61HPb5?hy31aH+0Msvwx+FzA+nVojVu;8Fk7NNFkT? zj`=mTdoRs~KrXcG(2YRs9B!j$=mK`*r^5R|Ds5FPJR`Hd{|W z3>ehrfxR?<`bV|h!0=>EF3q88O7L~td0?p2d9eY`HW(waIBCjBy~>OnQSFK`0(5Tp z_h;aAslRIt~-D0?Y@+g^x15+howAx_VV4` zFh&D2;wawyoy$0IV2642t`E%bn2rS(YfB}tr4aSOcCk|F+#n8hA^WMSg z2vg8{Qg|qIbCz1rxTiI8Cl~PTgr1|d$cfqr)kw@|AV89cZvl6U){i}j8ZD9}>c>>p0^P$Kt_?nw-RcWqYJZW+PrFdLBKr>T|OY! zM2SwT2F@a%XOv*t26c(vk5Q=1EMi}=Rv>7}fw-d40*|P=UUL*eS4N+-%cX|W$y6>u zpi6CVp)5l|6d12;a^mgI4Uu5*4>6Z9q)TLf>uYcrV6#l%XDFjwyCk%dj4JRVy12NQ zD)&11^7{>8TWCfj$C)Q%_Mnl#tt~^c%m@^go*671krMex4|OAs?t~#fauy?O zMob@hHhjN3OJ6;KNHPFL3E-)Xwz$m zHV1Wb_DP4KprzWSRedG(5;QJ7Y$X<361xf%%(HrulK2*A#+afx1nVT(=Uig|K0+`2 zl$CW9uQ^XKxK{SQOihT`pZ;t%J8jg!%ViusbY3Z~SLCVGdQ84WqyPFIBO@`bX?gWM z|4rxWpUqzn?V~EYf_xE`i~EH47}f=^G-5K-q|Y?3AITw*8=+g#D_ zpLto(|1qG@MWI_Zu)c`YHIA<>t8D(>kNS2>-;Vb}S-akIj_S_$Hc!^(@%6`EKsbWG zu9|ggEiWE`z`Sbj#~B72E22Y%5q#fbjyxu(mx{cD2PKCXm^q4EG%24*cN&DeNc^G$ zp`Y@(4xX?(o^07&u_+EYm^1I zVLDC&Tg}<`hI1L#Bx$@^gHhvho%=yNK=-H|&`f2TQVG+_szIU9@}Wsq)Mlv8kHCd3 zN!}Y|_|WSast%bg8b!McSsE$#IB!zE_$54^*Tmy^A{gl)riu^ZCkGrVm=GvVAv^#2 zS-Yi;nEfGfZ(YG2q4z%|&%b^0xV2V*YrU7U@;y^4YrJdK;9T z){)~pCe;W>3sS-z;UBqpha|0L=|c?_7}ARtM@lsw>}NI-G4bLdN2tuKB|n8br+RK? zWD-W@Ciah*C@&@ou(Eq-6o1yAR5K9hk4Ob|Nx2g|7D3+*(1WDy?5^P>nVx=^u~#m0 zW4p$St0&_ZdqE7eeAk4?`+-?hz!I)eEbq9+cvmkri=1Ha_=4{h(tk`xrac7h5tqcE z>YR&|a50248!~S$N&*P(Dfci-?}v==(MakWFh*xj^3^Naf;la*~%z z3O@FCLUeM3cPo_Qa%4rkyJzJTz2{RKSsx>D@LcEHV`q1_@XR!%$wcms){|zNOHXsxairk+FDKCRvUr5RFxN z!`1jWt9Y8QHFB(TVCPW%0pn$t`P9hx*G5`wdETiY_;5VYkv!m12oJ-8u_DxRJ6q>R zv&7oz)Ru1=%Yet23gI!!fuF0V@~U9!$cM`0!u?Cg@lJ~ULduqEnfdicvB z9E&hG|K*VjJ)VJ#4RIk#T(ISA=jfabmF29{MA~rCS;NMYO#&$N$8;gdXMkpxxC1ol?Pt6tO0U)jhGbCq~>VM4f8#nw^6vXZHcIdZXB}eamHsr?; z7nBMxH5Mkas`46Bm|QLLW{NJ=v$f41ivwirQuPSK?H7sXB$O!t)tp!q6gEqOn%e6 zT5#g&F%>wbawu&mludB7%w{>|#W&Nv<$MX?_6(GRa=4+Crcx!TLdp0AS7u_fo=UKr znl&=$eH{9LHyK`PE=Pcu5ysXl6+RBL6F|fTmCiQAa|K2=$?30}d7h}6=iX2#?@ zlI=_Nq z@;fG)+|BaAME+uxc#yV^U^NGu?a996mw2tmg5{>`33kOL*D7lG`IW7a(Rnu|+abSOhF#;sQ@Iz--( z7;yo^315i_A>LF@CF*%+dG-Rc&CMD%f1@=(mX0%8s%E4sMr|r?mFLf&K6&CI(p4fVC+`#TD= zCsK?S=J>?(@Zscp*gt%0M<+0d>|*T;-bE;)L2x!PGgwV!Rh8g5!8a~tgiEn3hV?0- zyN~P^{>>NSNzZ67wzT-ui!WM*yJJend+mm)Y8ehVBhRwY~c+Y}PfR+-Ha zh!*X#F%(5l&fqMHFi-(?Z#*X0ISSQwbdB8(&g7$IkyI6Cmj!_lmsIDb)Pe?NCY_OO ziflqWS6d^_5@LrcLHj$xx{8#>?m<>?;=c{O*6XFkN5HT)M_IKvYj}WKsc$E|)(~Ys z;l;gBaqXq^{OtPD%nAHFk-A)n7eSh%8z=7?txxdxYRxJA3u_C-D!y|}POmhGyg-Ds zqI_3nXHaW#n$4*G^9zKgy;K8_T+4_vj&KFNYKqnjBAl#e!<7}pv8@Z%b@;x&R5ZgP zuhpsAa$Thyr$#cbSd_s$*j@!)A@SrmhfoZcan0r+XpcvG&FSa|%^Zn`C9AxAJ%Qpv$s^0jitczonDEp{W-NLM>vLLM=)WyEjVnHXgO%|X*Bfp5s zRv|&2vI!P#C1=Mf2^uiSk;eg^TbG5`4vw9ir)I$0E%wek47!4%j=`MxWPv`?4o+kU zTN=`O$#}jBs7w6%nZ^D~%KP*(Bd-cas9)H~`Bo4<=ZZ4#`6E@2(wm00ytg?MR~u$k zVU+<^!~u{<^Ab zmDe`DTBM^T@a`CavI$CJHM&2{_Gi;{V)6QIudrCGL9kF30p8s0&_I`hI#+!VSg#^F zS$4>~%xrE6;i{GG-n-pf^>tu#U^k+CrZQmUj_WC+p#ZXP1+Yu+s#FZ`6eV)XhXM6R z$%95^Qx;iEQiTMGxAR8Vc}+>@U#SYFcxkt?n!s?ZhmTf?crl=&@)43wiA`t&T0tl@ ziLfMw^6rHQg<)C~E-(fwWs}`|gL4g3Hhi5D!tEkkGeb0i>RX*H9y4q|a1NDuKMNnyYn!W)0P zj{pPS?%)*qu1uX=ELdRfF@_9r0d;dYR#>T*EkmyEAmyTI^2cUT(%RivEc=VA3~_^$ zhg6(P5j64oWTNpnCEOQ8gQ-58UVN0Dx%yM5EG(B-Fc~@xO?ibRfMxIW6S$e#&FI)) zOyBeGlUFCF=g03SZ{NQ>et&VmGGA*0=f#8P<0SHl%V#2fRIF4zdD*e&JXfHZat70B ziU1=gFRfip*Z^nXb!wadOQ@Z448Ny4kgQIvqZ)L8N#wCMpQc=9JeHVw?o9Ji&0_2) z3$mqOIWB}@`9Fhd4yuAX5dI_!f=h@mmsuHn7fRnbZm)=G!Jc-WPuN*RX>cN!l;C7q3t5Ol3 zog-Us!DkIrcJuCuqgaqFS3pJj=1x_ecbmC0`nxmKo_WW-)$|nWH`dY}8+4fzsDd8k zq!uC!Lrq_oGhY{J*l`03)mHGHoFAfiYbz7*iwS%|f6jdMLD&XEscKRcI2$pGj>Jtk z`NlTJ5plrr?i^gm_7G) zK3|kr2XpH&DID8vb{|Arsd z1+?DRDr=7@%v9!}((2J1US{=&rd;Xmk`-Kwmt(^k-=igr zKS#B{=;GPKEleIxg(-;ba_qD!Jniy2WBEeVAYuj*vL(5Mw$za|m4jm5Y+_FAZ*BZs z;xC9gL9bXn6{U)#MMJ59r&Mq;**2?Ui7c>D8Pul+o2?5Iq!>4)pWSHLalEx83Z6pl zYOH_WnCngJ=JiszO~#g6KRR8M>7Jue=e+D7WPTB&=(sh6>AK>$AZW)JYOOzVaa?jx zm~h&_RLtan&ZOtmMfFd3XC8BgE$YWR$KaWTo-=H}hjBar#+5)%s2Tfq(I&efyPxe! zK?=PA3^d$V#RuB>SbZ0}m$(&LMs}$OD&^Qlo*X5HHILsxs82I|hSG%v;D;m2P|+l> zWFqGnR9Jb#fxvj9(12d>36|@HXbMJBxO+ttj@WPuWHf|8NPU5!lsD?ZBaY z%%>XyIfe|Bjq~3AIgHb4YRS9CiIJ*X-DFVjSmHKV+l|QDgA{i6bUY|O1=c2Z!o_}u6POeuu0%7-L>H*(nRI+N>vsShy(Oh4u1Lv?dO8# zMjp6zI4{YNZQ7ALveM4s3-Towr^2XD0^AWjesyro@v?vq(%243u4_=d84g8+xp&9! zPu{+qoSppN$CHyclh-GwrzdB}M{nP}Je!=p{dIDBcz*om=s&<0Vl?zS^Z#eZ?|(Tw zKl$bOV(dFQ27B_N?R2LF*Fhd~FtS1ZaEMtQ^5kng?DZ?I7&dbx-@JfJo6XGaY|3A8 zkU;XWs=Qp+O_A007< zQYNjx)vh(deUapz%gs!T3MYYh=!@^@99?A#%=W_Octg7VI1F;>=StnH3Q|Wx#H?X0 zNL5;vb)@Qglvp|BaH|I(6pcqJN!!DA$PPJ>g70Hmvm@z2@^i5Oe-D^24h@xI>B9Hl zR8e}ESyR}?aNpDtI3`@L;&u;4XSVhO=o}@F-qR;7cOjq%U>294Nxf23MtD`$6glV0 zNMP_?Pn8D=JmMew8a$7n??R zE%MuwG>oIPw#i^uP|F_I#Yo!k77!qupbA~iSvjBQczWAe2qdjBGDs(qpYgE1Ev641 zx@bg|lmISyP{^Edil*;~*NM<khcod?Dm3(KIR;~Ciet_y1w}*$G^n#N^P4kmXhR1YN@V7s1l>x z@_->k0CQw!Yed&p=2PdpjHFw|dYQ{41gflCxE`aH!;RH3kY*Zovao~yzsup|@-Bg)aCB`3SIC?1c@F>c@#Ex2skr7`Ou#jUSPcw;b(uRKFpO)Ygo!g;w3U`ZDZDFniS2pc$} zWVdoL@+D_h%*dG_dDsrDvSXG*$#XEP8T_VKDa7j1&1{=Wh8LG(!R+(Xw?9r!kAFEn zoxD7L@$-+k*?*QOf?0OC=6cpYldZ}=C7vBLE0~^#k_IWIg|(UGARUtQLM_97Pu{$G zi`||$X(U~^O4?!1SI)7YwU-d(bD7z6tH=uE5P?G+vV=2qP5jrx_is+#(A0lTG1SdZ z7e}T>W~nLZ%M37Du0ZPIX;E1N5)w_fOWL!BDT0eLtH_o)7-;V=B%ncS%FdAkg;mP9G=-GPz02MF4je{1C}~5bo~DP+xG|=iJ)5>2j2yv z!L(6%AoXbHnDK^_Y}D(^nle~{P;!ZuJ?H3#eOOSvV+^y@^eE8PTC!IHTKKN5uZ}w- zY*jWi=5_vwy;qzP$N4%^$^jSxIItkUi!QXzZ4<@%kL3aq3mM_N!AwmKUuKDtwwA?w zWP=*{TS`n~c7$2rr)FGlR8X1=K*P`%5bv+6vMATJLqCw?xAQp~bX;Ha)|?C`^2# z663<%^mtxnYJg9lJo)dU|Dhx|HmYugNqAD6BYW$mD*u#35KpVJu17((A9|`1{!kaS zP3b}x8t|LkIVPvZL_Mx^QlU%BQM4sJ0<~P0eSo!=+C%_lkzWC)N_Bq5E`ktKWv!UX zF~YDhlER$!*bVKZXBsG6fU5em=RHYoY8fSa68Ukxa%qc${8+Lu?z&;BW`jPpLBmfW zLjhBW8N@^r1q5p~GNZ!GMB2L%q1n`QsFi`4lWxbac|&V}RyKr=ea;{)DMJ_md*VBC z`j!~V{YTbEtH$=4Bf@}rp=wJ#`NBAH)}Qj?&qxG2@@5$bE_01*eXdNw+N}m-0@GS- zEqRu$HrM&}f z>Ux`aLoQ(5iFGcqf~nyFfEZVliv@CZ)EL}rx6L%2UT63*8Jb`@=H{1+*eKJ>WIn6P#Jzv9A zOGi@NhiBs*)>ph%MJ5#N3$8u{*DrcO%n5 zMU(8Rhk~u1l}+ImubuSpVncbG08tFd)+e-FiL3yo-IodIl4mGvkTRwIvN+i39OH#QKYvY_3F?32PG;lP}*- zz(&{1TOzK)9R%mrWoo@x#gwe#SF>WTWc_O7iZ@u}6caL0OXP(?7?~nf5+E|tNhL`r zFfx_$l4JwB=+|IfFpXm?Jk^>Yr&x6(=R5sWlK497#KmqDBXFo}F>~xI<@pVlm*}ezq=!Y>#dYWfEE+Z$&Ayl} z@u(ZIPG^WpXh}m4$QqAaIVHS{Q^;s@o{&2iUf#C7>hMYZ}Q+ zA*tO_Dw)kHxKxpNGn*E0bs~#)hl|#}q1vUm3`WXjJ32-R)pKhSsNmsM=a^NFx=5Fi zWBNNlj!)Ncpx!w5j+%CdzhOe(vm9JAu~roEb!Ff%k{4L)6P?;o!lB74-U`A8a?sgK zF#)=Azv86GUUuHNx5VnW#QeuRmSXdR&!^w1=qT2HmDvr(=RBJq8wUxv5#Jp zkK;_puPLL_(yYvMg(A8M_zPPQ$(+-T`NWxE#1Cq#SMX}L*^E)2p`69!dSsUXP8ERN zvQ(Z<*#e_`CU@Q!Kfii){C;xu_UAX}oU7C&801pD)fEhh9M?*$aINtnRhQD0U&1o% z_rhZ6LK1_HEY^A{9IA4;G~h6dF)nr@YX|V=5FAlV({@q< znh{eiQpgfQXjcIeE<$qcIwp>p)&ZW^R3FC!CyBqu*1_6b91Z&aAcb&|VQe)^zz6D8 zS&eJ~Y!y-&iiL1&a#DfHDMtTbH-ItP(B0)gN&3pHhE=kqN5B>}QvHD3Lpdz9^P=0= zkusOQ^b@5i)(LSADJ@ZHX*HN4dd^%Tbj-JN?x=2Fk4S-$`Wqf7F%@IBq}WMt9zo`q zA5E0OufIWmG}z;|47#Jy#9>7`0b>JM@=`D{+kio^S-6yKo_4=p=ae)rQnvsvPX0LpdYHS)D-t9%Rg2ur zx*pm!nvRGu(~g9Qf0Pp;fQybD@!-Y|J>$qM)E^D1rqiFFI(TbFhl*d3Gw$|+@8 z!guLJ?n6TT>pH`D0%aB1RP35+j=+aGFnyBtUnMk&IjLFAn|>+z|6S=5Gik4XmxL+W zyZg>yyN^fd7V|o|7R$$LAM)Qo5<7Fo2lGE5H#3{g$$DdxBNA9~V{Cw7%SmWamV-bc zvQcTJv?OTLwm~bTZgw84=yu@DyWT0lOysNdGG7>>A(L`0@gOq1y+G4Mrf&AW$Cw}; z7DEwQ_Abkdk@C|YOBxR*q^K(mJQ_$v&ozwlPdSu9!z4Lj*cKKFA}y88+6!B>!s5~6 zKrZ%6x=L0aE_m${1X=b>;|a=MsmwlDGE4FGh(}%;8^zXzpSB-KODjtO2lElJKN8EX z28n{64OADdjosz+`CAvZ%5yG-pplA$9)@G=4*F@NXI{BLL+vIJ5Swqx zbknq`o@{3fPsZ6g;~1xvAQv9++R|3KnuBPSik0240kj&)IIxBp=9lujqQ4Z^c!}u% zEOK@we7|pU=UH2o-vXEDIZaYk6f_F}jaDW2+q;+2d^`OHy) z08euj^Wq9eN&4tud?P)+BpjbUE_zZxr9%TI7z0`#goZt9Besl&wBQ*KEEP+~5{gQs zrjA2TWwl6+#b`D-(xJ`TBPZFVHFDfNV9dh8v%W`{4}mSZaFdXasq$}VHI^U`i1;jL z>!}NCbRNc7!aD$fb!8rsowPm&3oesr}&^fGTdTXm_FhrM> zoeXbA60cIoL@?s$GwB%#KBZwHn&ep!CF!#^ANrC!UbbwwqiD`w%IXqQ&CpzG$I!47 z5ctn6^CopVgSxq#e59`+`S!ZLmY7+NRmP%)c8iVhZuiRd0b}s`-Pd2%d^dB%JkleQ zA+Zn+RpM!36AlBql2ti{2x(Euw{7m~D4^GTnSz}-0ncXW07^i$zZ&Xg7`eAkr@7rF zNPuIv-|9#6>g9_bKpXUXtuZH_K7*2W%Z~YjMigxPFCC zZz58~X_+MoHaySZ9z4_X#=#GFrs({e$}odzBhff5tA10CF7W(Zg!vH3Yv3wtI<}T` z2v}FEl9LgW`(*Q%FE+lPL7TzZw_A{Pfm~D{CNIT z@-NBL3!R|HnwLjZI2B`4KnX?czO9vqwl`NsS3J38|5sB3BEYufK^CY zMbgZLPvhC=tHnjPBA9gbAWmfh+B*1qdhNWltN;U}lycB0s$h4tDyG-TYPy^dXi$o> z!BlLHAj)#yUt$^7qFBUXIB$x)0QW;9R;(9kMHyK*^_=)1isRZIWI8JD8J8)iwlcZB zo>b*75W@n&ZOo?2^T`Qho_&4%=KT1jz3WF&cT!X~*lMk=$l>K}W6>j82NunFH9&O> zrW$bxlqfsBOGFdCD9aB}fsl(cc?9vh){9hjT|J(F_%YXlZo&G)X;?f%lSeM${e@}jek)wxfU;@_)QhO^c^BMRA zK%K52!wCNS`|oL{lCqG8rddu5Dda%X^J|-iF}B#z(hLW`x0zB#%E(M@vPxHwk@Nk3 zg~8WYGZCNIfXf3vC&TY=rZC*-n(`*)@^N_UbNgUU@qfRwnVS8%)l8}V?|G)%7=871 zhml$=%u{(w-&ok9R_!92Nf-!Bxs(HqCPj*l!75lm64sPWzByKeY(lDUE1H7V6V~9i zm{OAUidgNznug)ij_~oYHMm$I7P`)rPB%d&1tXMWD;~=d;9K$lZ2x~`Bi}#1xVcT(mQMB-R?H4vmb5J*{k?D zuYx>e!K*0!sS0gbyF?!nKgMih+XB=Dxz0c>)VOGZ`XD(*=lpWHG7MK?g&mYS(R+_; z{n&J}UwGV}+5buMNAuP|4*kNF)fSo;2I5!5c`A?oz(|A=|%b2aM$2`Dv(N!WV-~z zA1FWQj5l1&<7klrwSVJSPROIk+oi@hbk0GFsuYz}_^~zbOewD;dc;_q8)O+0_JL}` zJM)|K#e^u%^s+7&Yv8SoZ1(AH(W5p)I$0Sp%K^#sI=LwBF`T|Qk6LA8UVKHVhXz5? z?S^Ui&qLigWfi^5Y<}1$$%8sK;^s7ah`l~d9)Kc+zj}xnZ#+5?wOw3Dtq8U%0Ww*S zNm((TV9|9482Td00j?<+BAUWr%=ZxgCI<`K?%Psfg(|31FdBUfY!m0G8@UN>4&pfX zuUneLl=J5GDUWU?xx$C88{0I2)7HBJWip_3ep340e1SXSv@90 zj3&%M{)fVR%%N_wB8e&ONIvD{INrKYP3BpgtpIOauG!o&A4!xF=xiiAosa>mOjHT# z!xXxPLi4^%P8t$GQ!~_Q>h}K_vZuf^bAFu{$^%oEc6%U4%)=BH0=_!}Y2p zi$bANh6(ocX0p~i8>FJYFbfIC8?xzR|CDFR)k7$-9}#=Z6fo)5M1z<>3y24>5O6vR zvv_QQDXU<2A|I8{vebIxEy&B4S|^;`C2!cSAndE*xBudWR>gu{$OdJr4*QUm`k9Tt z*(c9T0$q(#;T`L&!p>~^H_YiKXAtH{5fhlY9hg1}#UYvMI$Nv^Gu`A@64G_};?U;) zlMq?SJqAwwYfQl`HB+0)97|Z@zm%6XGoLse8a1gdE9Y$t0{_>~lFPiYPDuW!s`fV! z1S}tQs;47QSXX7fd;vm$RVTHdYz_0h9W{ks{yo9Hbb^!K7UmaJs-jjjlzisH5PXuD zFEb;V)~X=+t9A@LY)fuu>n54i3Hf@K|0x1$wO^A)!$o&~%a{y|gOE7zAhZJDv*>3d zd$Lc{%*)Z?(#LF_jEX|hF_B~i&wb3N=_CofCu zRKbU~=K7tW_D*MAF=6&J*s}!tSAt``E$&h9;IKe2bXK7THazrOoC~PQkj`c~>32ZW zCz%UstDnW;1!5$+&lGumZFl!qu8^NB1{<&EReFW$U8j_7AYBOR6;UnyKr$A?q)KFa zkZtjt+pyMy%?qj6)F#aO2{0cT)Z5$>#3r#LAJ9Gum|WS?I$Vw~FCLreOtBu;tV%r! zh+scVnG5YsvVOA+biU1P;Fg_|}-h9-`wt}J?rv=XR2 zPy>0`e<-_itR+1;)@*7u=V}*ZQzPGBpz5WUQO%&(*0AtaoU%5+V?jB1FOr$5+`Lo! zPJ@?{uzO1n9hW7&dVt;87EO=l4Hi=HA={kjE<5{fPD>)RL0JasXQ*?5eAzBjV80Ar zLM?%$>m}#;kH5qe_nQYaTD_*FY9mXsVn)`QT`zpsnMktO^HAgFC?b@MaRmx>nrq(l zmQ6vu8)Xv&Q0%rtH)=$jk;GMLm;o8se7yUyfP&4;;Yc;7%Eo3u1N`vIwEj@5#D=Id zRP~vB7i!TS86pEt*LA}T$&&RFwe=dtSZ|wBY-AA?6d@qZPaN1?m~bd%@eypc&guUx zUB^9c|Gsjx?J}?SgnJ2rl31_-R*aK&Bs!(1T>L@e<)SPequ>AB7hlT?2M5aQ$6kO0 z(PH<7Yy)@_Vps_c0bQ16e7t8}k7wmR3 ze%uF~u*#MFK~+`(Biqqd9q5Sd#@tU#haZQW^suY3CR%qMmcH_gzXL$E#j) zy)0W*5X!*Tl$ahF%3uQ7r*zt2p#&N{IPYIUY5D))>XZ5jGeMIKJFPp#*+hE&vZD(d~j!RaW7Vgcf|!jY9t$n-}vlu{`-s7V1q zJ=GE=LNaLP1zB*|aKO_27cE^rpJ8+Xa@9iMewsFk)vQBoLpICP>ekwoFp!JWbTv1n zU-HDNY6_Pc9;_nk6`ic$egg{@opGp3ZYxf=u1E}vVC_Z@m&YM(!)3W7RM2hchY=Pj z5O(V_rRw&uv^rnoSeyrtbFZRH_tvn-hH>Voc&-Fm8}S#6oQvBLXIz_QB)EC>DH9id zP*Y%ZILM!19EE9OP!QS7u!sQ{!eBX1m)P*#{oP7g?;hIMgjU?>lq?E{@g)VIbNEkS zE)+8iX>+3BxKt#n6QIlvMfI}>HfM#`Emks z*mH5r3IEBt6$O8TxN5z!W<88b#oAOo*>sS+Q~LMCV&q{51k^gnFjRYm(CK3-puKKN z5W}XT$&qpd;`n7Y;OIkMAO`)82#eP+3Q?wLb}}g5P24d?myl?hH#Qz?WJ_U5X;HX` zn7d*sIu^5DxQ^dGrV`C|x^C?OhpA z56kM+gX&TZxLjTyUltSK$%c$RXz=rbd16)Tl9RJSLJdy2A7su9nPfb)7qC|>6kW~< zDjciobyT8@E7&3PAi;j^ofpsLMc$mmFqoa$d%f$M`G7n)Q{wDwUyd;~bG*9BSRB)5 z#1&^EHKmKAki|!|)+0wO43cu2iqOkSo1A$khy&hGtV@%t(hx7E~@z&)NlkI`v!C1`=LD%J3pfUYxxo zuY#hn**hag%Zay-FmmRRK7|2+>OD!L!3QZ|-Mn0)l+dNYg4-df8rj+@Qle6?3NJ`- z2jJd9x(z(vOEa=*b7n-38KK0Z#{P!04!P#dvb@X}E^BGcl@MX+$%PuGYD-fI%xpH| zZGf&(?9Y#Pz_dhlCuxOYxet;fn*>$Z8PwhB00UU9w`ZOY@#wIaRp7VmQ~N5zglh=N zBcxv_XJ&owYESEbnR)&CbzP{2qWThGVL4J!bpcxlv7_~OuApZz)1-(DsW^FRFhUKP z;eBkzfJ5!oZV_sC4!EgJ?uuI z*1lV1rL++47-PPT(7ck;7NwMBCQNaCJI+!7Ze7yd$x92BW?Y-wXli?J+a8jSdD@Rg zn91QZT8EDVVB5=7vUq4sOLbae6)zt~06UqWNnfEmZP1%;E zNSPlc0&-xE=55ZsfT`32m5v$ArPlK28mXc(%% zo=#D9;+qVGsJa7X_FR*()J2?{*h7Jcn=>uyjoZ-th;gYbNJxclD+P*;O-cQjqAf3E zlj0^|uF4GbEy+D@Z1$Se${tC7tr(KjlBO4AA(reTmZuoEkO;T8$c@P4l2K!IeOqIw zhR_TkjuFKznHT#h2h>1->qJ@R(j4sAf@BdZj*Y9!=oduMK=s027Gli7;` zJtn|TDnwL>f|`iUr@#^9R)Jzkl%;AN1eMVa2KbtC7py!38<`+sLMJcBBdYZ&n^wj> z$Wj-_^tp$n7PYtdM?D&ABIvBtSxYoE(`AR~F#loKz;qc9&zDKZrymcFKe^yOgRC{f;8(z!)duRi)wipD$} zIE1u5_liLCY4D0HrXx9vL1{!WwOGo`+lyr9)JDyD)h#vNof`+RW0wX~UU@Uox*Q~L zIsGGs#d_fKS`uB|*t)U$UP#f(^VaTSjLYLM+P9kI2}WtkJRqgW6#OfI8Bpn$n=;7T z%NaB%uTuP;8*-8Po2zvv2KU@ZRdUm&Jlw~OGKmggtyT+fa7^jpgp*HR2qm?JZmF^i z1%?5hQ6>!lHmI&J(jVw*l0^wSr$&5_Yz||8kc#qhc2X)Q;KugE9|RsZ;nqVZ{EH+zIdp1H>*Y>RvK{N=r+<2!)g;cS(6FG%}}KU4}oUaz{zXq z#M!`2@zXh%8b!%kvcwgJs}p!EbwEllH=*P~_go*^ z6QWjfj0!YTK9Ty&YOJ*`m&w(WNR4;BFGSa8`BGUx8m4$r-SMDS34ZJtbBrx7; zo0M;#6If78=nzrRvKR;{Tv@?QZ83kGeKJHJ^R(S^1i9O=kX?4&@&@RpM19KJgl3%g3#f%3eJvXOoGD}1Gy zGEx;N(KtX~;*>D9e_SK56`>UiRTz=w6E>C-0@IX6!IV6EiMK8sJ?8U{p~aD|OItSt z0O-=NURefUlAP+6;>W0{fD%E~+Ok5bcF-owH3ymMR%F+l?BKvc;4 z+;Cx%6NFq`%%}sraNPv8WX>4qZ2-_2oR)M%WDp}&YX_&#@=z}OnQA$n))Wib&KgtS@Wl|OQtT7-oe1j+qvu?9&wAakFU@iE)>u?}S z-H(3C!Tzrz`j8gih0&RT_ro}}c(L@I*UC%b*FX@R6c&`n`IowuxP#Ht$Dy^oN zN;s!yHq#pv57(Sriz_MrgoKu+mr9g{GMOUt2YGb49ub%>%`R_k@m@TSN09ywv=D02 zh`tH!*U5xg$qD|tVXA7#Tz@COnp}Wyjql(lH@LCW_^#wL$*}el$*Tu-B5_QJKKuY%}CB7rOK@vyu+rFSfjTN zDtSS*SA_F$M%K#rz`%_P46WI7VD}0mFj1AvMm}3IvBN!zWDTI;?BWBei|e#PR~^C0 zto&TTUvEm(XARsvhuVENx5+=*iB0w0kr)fbn-ZgcHO!Em40Iwb8qRK$Yq ze=eZ=TB5hSC$$mAaByFYe#Iy+iAd-U-zQNPOAy;=dH5V|P88|Q4E|DHPB0dH0!4|< zm2JIIF$jzqquLzV)itniHq$%;M2+ys0|VYY4;~(L!{$_WRF(7P;rZd@@R!4r)5901 zSUI+!Er%*lEA&VekVSgc7U-cwGr42d@*Ud;JMcpB)opkuOVN8%~CyaGTfupp?xgps+Pe_Cd;SKzD+*yIQZu+ z_sc(1X-zYl)eSf2qLtT0?V5Hwr<0y*>aG1Vx44oen;o$qL1>!!gD2-2m^Ux!udTp?tkVmg z8<;o8#bEG5#=SQ8(;uG0x7MTn?YiOB!EAPLTHYPKCe0PRi}WlTwqzHCtycd((G<9r~pPU zjOeCED1J|7e-FjeP>_27cv+SUv*l*xQMtNxJ8{>3s%-8zf1k~F_~LFmV<^l48)PV` zj(uWp1CgElPa#i^D%I@WVM=<5E#C9*R6hMj62kl$1^^Gdaj44+Ipx@BzxmF-$Eyqe zXpc4j>pI1o^WQq&b!_8Z=_Bs+oqOHOx0CBET}>A0Ex0p0TK!~xo#Kz};4v>m05p@e z6%@LM5yn9Ltl)6Gc=syy=2_3H)&K@I+Q({dIWD(cJAF8OUAke!SEYA2_k_8vJG|3p zTO5r}NZa6lOZ0C&s||oGQRf>uuis=hE%4&f@JLmUJq(vO*677>E;IJ|NzuAExEWp? z{QB#DAdcgYLy`C2$op^2=V#aE+FfMlaQEMFsP&zP*%nNGt3g;iS)Y~s(*!HJE|ngl zw~O8t?bhA$bz0} zP8k!?)KI1h)#MJnl_9KlcPGU*y=^>B8=CLoEbYAZ-KQvMH~0t*f7{utgcB7~Ra>P2=H*Q?nU$HmOHxI<^}AyTiuH*7MnyA7LS5T-hmutVF0 z+T5f=$t*4M;>x;SeZ)e6=8Ip5QS&wlJ(HAFG5d+9QGPybsNa0%p>7z?^UpjSZegEW z-Us%JwTOH(Z18{h%!BW+g6(_d4eiAD=D+c`_i`_6=(b-8*76+2rt+i36_bnn8JeKq zr%mRDp{nvsR#iF2s9^W(9X%S@Kl(7aQFMHStKO1E^~)DspMo8kU90Y8NrFzy2mh-V? zuYbfp_%pF=QE~c#AGKt;j_>Yc2ZSTqs%Q6pFh|x4Z!jm;3nj{dZJOtGUSDSm)Eyei z8)M9*#YQ%wv*8|=>kh-TOLk`%gO_OooajOg7#*qxe~RcB&6}q^ukK|*cIxu39}Yin zJ+Ou^V>gWW64KO8<5PRqJ?jBy>z>RX+m1`G#tt8DgZk}GPw#N<33FR_c&E>{+WULJ z|CZ?ISq-yV>;yh`uAIB!JuI;WZW{g@{CDf_y(WX#ZxhtPtGEeJ6xo|+4W&a<@PuGb zSI}(8-`h352PNcI{p~>w8TNM{8}UvE@7|iNmVb#`ZguYpWBBUz!-=oj=FxQ${Y5vQwYVpCcegI@`r#G_au4io4~+N{_D=0t z&#TR6>z>%%ZO5foV}}p7LH%~8r<>hf+z-3kdm4N3w&Q18?fpIAe@palJ*y3XhVjis z*-Wo{XePbic)U8A?O~hjI6%Abclv(ta`!@sF4U%RLFUxiKo9G7Thr(rJnZwThG0`} zS;Q21^uDjx4c||flj;(fr?yTWVr2U!53e_Fx_GNS?75vr=kT)o*Ms+4ACTyF+c2nM zyzXZcxjvh$)h!Z6smu&RhDYhB%TID7M?|U%qc7r*bLGTAJ;2>zxRon(8E*XMpcjkU=(K1*>)zAq2P?rh6 zIORXxFh6F~ujjbY7HAEBS1JQ(`0{1G{gA}kc>*`-VR5xExPG6`^0bisBP|T=jJA00 zw*ceZ&ZFqCxoUK6BA0z__i>bV*$h3$NHrRMhBiVTetp%U}`c3`w z&)ZF}32*$A- zkM&D$hlOl$tJpaB)i?3c-(^HS=%6oFX>ng2Y{0k04KNP%Z#0N`I#u#Yf9DbCXZ+s`+Bbjb-Zy{jM!>f^XvvQOgxCKAUN6g{oMfNOPJq0n(xNDj<&jQZ)PdIO@ZIgEm}T43am?2oGSX8!AXT z4+FoBoCeaYv=4oJCJd*Arx425y-)`8L;aJ6l515yH3aIu4`bNVknOkIsR=H3erQ;3 z@VNIj(K0Vy>gR&;W%|i`E(=;g4YK(>gbc|aU+0AfnxCeh{Km1xyiyV!Jz10EEO&XL6bg7U1{Xr3HhZnf}4~{xGeg zk|u2`J#*&dZ~a-7UHLyDL7{%~Q33Sxo_*buP3<{BGizj*q?_{%Ij!!NXD+kbGL|(e z@e@Y%ww+McLjQ|nc-H^fhQw4(&S87%qfdRW>`KWabIh^omm@8b7YS=$%(elxPgt}M zw)o(--B_n)j^ZV3U}5?%+Vk?>cg}7Y`1^(4fyZGVM{vqFO9YwrjfKTe+7pyJqhn@W zkoE?s11Vk2BWU2@qX-)88w-S=v`0@bI!E6HX>Wi!(9qR9f`)ZB9@cFz>rPCpH_V_L z*gj!(;G_G44vc{6tpg+UD&!+OFk;^H&LR$MpRjr`68|8A5w=5p?0I9M(34iL8&mT2 zHwv$cS^3H^t6P5Csl3?XdoPvDkngR|)|VK%5{zySx(9Gf@4$$JN(LQ$_2xqy)K;@- zp>o`l1XbOi9Xi-zX}18=x59m3_OsBNd)Ui*w=({UfGxR*IKg6=%Eh)1=O6$t{RG0x zXfD3s=`fDIN9!GhC!+sh^HmlxM5-MrmGG4ScqGo#q8(Wpa8~ ze(`R-sIx85pa(+^?RBz+x z=H1j&Po`$2dP%}0H9epmP(lGLAea1gRh-(kfk#2BfZ+;39#P@o5aKr;M6c226Bdpi zOJ&pF=jP9lR_bgvJdT$g175jt-p2@9eb6YF@Pv-R`|tT)`_u~>N)bIUp_)4buI({_ z^hZ-$ABa2HX~;mDe2OLKzg%$Fq}CQk4;f1`cyYy-i^II}Lzf@R#I zyxun*Unx(*A;S{Ws+reGvE{e1<&4M+?qvjiPj1P+CcfzC*U}jNonJU(=yy~IyX~<6 zd?>uB&$8@;r{o<7Hv8}nO6i>x3}-lmrHbVQ5}X%TTYc=c0A6QZRaw#OvL>w-`-Jtz z5U;xf!V+k#bbeg+I*?o#PeRFwhZeMhjQ!Ji2a+9*kuks?H|7-)X+!Hjrq8&xH z27bK_N_r^T#*gCErsFd{o_?JOt0jXqsn1J1f3&HbaRy#(Jec=Q1E{_@-;s8h-dV*} z=N3T1wXjAlnryL<7U$;g4ym0E&Y*aY{(RB<7=CPUdr1$C@2GbB$2kZUzq~rzkNDx` zeZDV?)}QD`@`(?I}Z|6l+&{Muq~iQ&68-JGKVo=0mY=nLi~+mHi!#) zQ#L2Xbg_mK3vbqo#d%gO^CI10PK~EYAELkOf(pbLDYqrzo$}*5bBSkl?Te6IaN}A} z)72URHOj?ejs(K|;Z|0Axv#u8j#3z;UPCGPD*Nji{QN@S^3DOZ2+v7DO+0ZVdV6~9 zK4VvwGDea)ZPmZeb4gz(MUz!Uy7(Nug;HWaENgAq_|3Yg^Q$78CAep*?Bg&Bc>lc9 z5W!*CJ=hW)dOD)qPO;fwE~Y(9S=&Yylgc^QEg zwVP@U#5}Hln09F&>WJ>aGo-Y}&{2qFKQhA>J(yPXdP@NPpL(%DMLaTSAb%0Pp?$#u zZdCmpM!%8$k|W{7(ijBD6+4F2{6EeyjU^Ph?Q_$>Dw>8x|{pq@|-5*_C%X>FIGXYi+6pvd$5`{k?Tz7nwcp zo3v`)`Z3V`qu9UW;M}Yw+{mxszxp{X<&8+<-j~kC$YtEkvrx?@1$6LP3 zs=S7WJDEADdp!IyvRC9d9<*0q_v7k#niJ)W^GcYv5RKJIzpv%UVo>w4Z=zOCv? z51L0W1ZjpdYGwhpwlGQ3^EnKcLBu#t3xvzdy( z`ex^Y|A%gobjPW*&Tjmc>pQ#m(U;w~l3dkb>dNpw&Gj;|f9-Qbdxhnlgz3654Bacx z(U=SC_Vab*oxi_+?tYa5qw-m^J$KLQ=wP-Uv6H&Vcc!A>?w5+ji4*JUQR9RJJvyKj| zw`C~JbQCd-yxE7wtiQtTo9xC*U$^0df|_sHI>c>$)Czg)1Jg1n#vAWn?Ck5OE5DcD zVMlJRjXk%^r|x4bbV1!QKDGG)wQ~xC9Py9zUg*ZDj+8+ZWXX9EpO1CQA5U^X2wWyOv!rfP6cM=Uyop+~Geyw7mNRHyfH z#8hZN->U5Ah-pxFI%1e&$U8gciA$VnAAO2E8E`VqXg)=r4E@rZnOWZY*>lw@<`&Sd zFuf0kVCunTXPVFHOmiFgB3$LKJ65^#J0m!2H<=+7kvBEl$BGQ@ z;B!ad4j5QGRrHQvqM^LQ3YGI!eb;d~T3Ie;PDc|naDrEGhfQOvj&_Pa9?-*}BH-P% zdcvEmHO#ox)-!V2xL!N9!v%Ol-JVeT=lpN}c`WhVmRHed`XG=8(>z~fffrNQ97LJ4 zm@Tq|{W*@E7q~l#-(5iW zFNL>CG%v$y%Xh|i04=T!;=%uW&xZt90)J$#IxFVmc1&PUwz< z+&|7$$mNPtGfp7trj?~}rIQg59b4Z2k62Y2k49gN73JBhd?c7%md#guwIg+MUwyuYI;5aqibi5S`jQr{<`LmZ$P z9>z1P4{IOleIi*Ab_LYRl&~A1X!e9{K;1*KgTc;;8yfE80vOaqyd6AZyzL)ga6{bd z+*me(<}H_|R@@khz_B2SdmrM^W6=xY^G(uf8#-4S^5%q_rzrR^7NOgRs_fX=l3u8y zfSW$J2TmgDRi>YY`|i;yvLM#^%B6A{2CeK0&FK3m>IK{TLA?G#?4x9jzW?B>(vSGYFxKVigz~c z+I~Y?_wTz+rilBqLHz!V4+G5w1HXt-s4evERB13MIJn$Uu@K%b%0?Chvu+&9-+NiL zjo>w+&rIXpzO92VIR!-^s;rZYW#e3m1=vHyCNWwW>QGlS6Cjv#i})IBhl z$^?8|fE$xHE<+w>X*Kgw)XBqGouSUWq+fSe6WUObXX`QepnBb`LiW&R1>uw+-EVAf z^kTBAa)?sAP2>-M)@HoZ52|R5`!Fk->XuBd_$OqV;!~(2V}3s)fhW7gva31dOWcg- z@L%Z8(n8`&9UYv^qiS@*yxT)B;qpWeNC8oxX6-LsG< z+5qmf2i$2lxK%ut$g@@xU$?uAW}a<9Z~KG|lfpf|@FcP%eH0BO)uYaR5uQEMRZ~vm z55oah**x@%7eDQ|Upz$)3~;Z%6BvE+TY^kKt0+EUis+5g{m-|7D!w784^e*mhjdK&8gPk{6Zr)uD7L z_x5>ATGZp|(sOZjb^Roo2VR^_^F{V9ZLY&J)0css^Ko})px>#-zNB*-lfP}>;|;t- zD~7!O)zgMU9t4+XE5&{f2*lp5mtr>KlMCjp9}~` zM>f)d-I~Yn%k#S11xTmc*0vy2#!}oEy%|df0v8pNb>bU{RqbvizI96RqJ_d?iH3G_ zM6$RD?B}70xjm||g=VB$UvvH>_x)!|Lf0{?zlCh)_6Ict#lO=7^G5ZFV|ggwr4Glt6CA;1d-+6fxxc3b?(Rq z9qYHf+lQ=f$Nc~J`xtJhruxHf!)i@_z|dkk^MEPyt6_IlINfqUU0B>c)3=Kmk4^HA zeUtpQYjOTZHxYUIBsz+dkhFK`KmE5m>pp!j?OT74-m`<-j8!>Me6)-Hj|u%>I~fSl z0i1QRAG?AN6BCeRLmxqv1>mo)X<0uDpk9R$6*ce}}BKH@2hIs zBuX%@q+ofHeOhJHCX)@ykE?98NT-=qpL{Fq=4OFZ}V(1i+#LikB^oj$UF@2CmAB4dh0Oo(MPEL%xp>i*}p( zh{20|>zdIrnB^TOZmB^e_1DR)@nP%9i-$emvq;C;cXaMT#gyLf+yOuB)MY zwwU^b@1f$iY4}DxgYw|sSAGH$mAhnED}NymKbpG=l{09Kq84NRtv+}51-R=rFR+n$9#yhR)07(5yI{-j?g)OnxS+m+yK+07lk=uAsH z1WK3sddRm*H{Ck{OfC81-K*f?v-s1npH1)YutbB$uyyl6XpMf^LTXp9d&R@R9(HIv zY%KC&M);Q|wc!%icrcN~q!kAJQX$LbSRJefrF5T>(v z(}AGB$K9JN7DnC+w~w-KY`i;p>z&`0V~DmILg5C$9zyR1fC*{X;OYC058Jo8!&cb< zG;Trm8Qsu$ygm5PH0;9w*+upnOIF2KU zqW)aJ!q`2)&NQa0y0RbJJNGPbvNE03xs$I=XH`w#!9Y;jvaKmuQcHF|<^cD%Uqd;8c!#xNKopBdDhOFyq0d^PECM{ zWF=lowGZGRuFe{?VkiZVx~cFM4uRcBP=A5|v&k~_*l5S0-b7lNFcIMWD&>jhfEDbq z9^*4u(sK^Y!+v^nfn1~#b(VG^kdHDVv5&>rrZRF%>q2eg1+3YuMswr6X8Z@E3jc_9 z`kkbKkRMVXuEo66ha_cDLj;EymmvZ}EUqsobQB_Z;+R8rt%@<4{i}ShEWIS=kgATy z_A9$P6Z&Ol5BQdc9H6(2LG{8+w^cxY$O zKB#0hJP$jQ53If+eV3K2ibG0Pu@Mlfg`J3p_QAdDa8MNv%yKklr%dKO_ZOnNx-?I* ze`D^PnSEmoX`WbIzn(jiXWn7r3NYw#G?%aQvQmhOBomKi9|Us1&TBUTrmJhP1pD`l z9doi@oFTm;64mb%@w9tIs4pjZe>ssmDoG9^+P_;2uS~Xw#49Ac{b|lbzN)=b5dqLA zA_J2i($RJh&UTr#8nAAg(A&YY#*C8#@$HQ-qf#r?8EHa3Qv_{Vp6PP9G zk`#J}agxfyPxGP4>!SRr}jeAV~8EM-{!Km zTf%(djHAUvFpJleDI~0>?Uzlfzf~f&-(?2>4`@zm{p{M>BW7KdRgyi4rfT)Wg=2tC zG)P^XXG*60Px zs&6U9Y8fah9dDHzpk3;afyxa|f9w}U#wP10dv-{aNoxz9 z$Nd6&IBEi`U`~D=6qoB>eg|e3R!DCYw{p}}_{0L`=FN4wMPOWxnW+263`@rlx#dxI zz)vg?W2u0Xt6V)l80LzJx_`{DJPeUro-JFTtrKs{6=@sK85{dWk;8(qWMR=@M;#Uo zq0X*5$es1P)gSvsk@=zpWNy)vs`h~e5@jxB-sKIW6YtEV)tQhx2F2huI=jWv7ovM& z84XD&D|-r+p}crbp1`JRq^PPo$^7Q0jj>FnxSma2vL?XYWbvjw@ z*GPejsMg+lS8hniMO8yZGN?J+8y8b+-{pl1*jM@FbJ07UpZ%@RpBdt{eFyVrk^v3l zqJ-7z^uz8wjN)hgBi%i}OPIyyv_3=?Og9ovAPmtjOw`+i&>#YI0rUF_gbB1+BO z;AVKRsm8X}ytaak%_aX5w)Xy12-J^9b|R0dzQ;$tbE3v>p6}f)d-xur$1pyfIB>@< zmva^vVL|BXm6irj!urz7HYtDK3Sw8_c72og-+}^z8zy2H z@w_Y-Sv08nB7KGo$e2(_?~bKQU>9?rkr?}%ZIea$IQXt!O}THLYuGEp_nr8RT$fd8 zo`(6VZFUZln$OgXYhq?}s8kNdpSA)K7kMUGxm_zxt?8+76?!(-p`9`XBitMFX;Rf$ zqt#&7H#cCcyqDI9^(Mo%PPd6ACb`noviy~dNdyk-hL=Nq14g2J~(>qBg{slroKhuu& z-+fJ^d#B}DD)gtW&jUoJ&&xqExQ1}0I_EhJ!jSiM(t#yMoZ8jqAZp`Ra{zUliE_@J z(McnC95x86$$g}BiwbX=;mO8oappNot?^gOeS@V`r9Jt@mDjG2!rF&wJo1jJ0 z`6rAPHXrOL>7ax+m9EixN=g&KTU`Ats(quI$`74J_s8ikAV2=QNQ0po68kSySyifi zoQmpF^}AGk3=c7s67*Z7CVH6>g2c8_NSMPM1~YPFn+N#wYp{isnW=FX2oegzV+OtLsEWf^35hI zhp;xw*rB*=2uHSFq8fB}bV(PB+riSvUEx zo))DKJE7BktUA#4^3DiG??;^B?U*4@p3JJ|^RSp3SqM2p$hko+dhlwEd!Q)S->XV& z-e$!X94%gLi{dV8)_Iu@&g(|2*?Ke(3>%oNa1t}K8MmI^h@~fMTO->ui~0WBylQR)} z2Sh$EC06HxU7je(m*l;3B^ZTigmPQ9`LfLBvQeAtp=+u*{94^1EA~$2R957f%8S!p zF7e9qK3Uvjz45asmAfCx{FiNZe(GN8peEdE4*KcS`KcQ{JVsa_P8aGV#k=-=kz6>8 zuON_^LD8ZS9GlrPu$b*%@?y)|jJ{(A)a*<5p6NAji`@}>ZEOZD10QC1Y(-(p7gf@4vC1Z|&!iy~Jq=QcI8?4NhpydKLn0wJPu~ zoD@tlaa&wVMm035=oDfVm2I5Owejq}ogxrRUo_9`E!3#GpKUi{T{wfyh!}{^UxcZF z|MG>{6FI&yGyF?ak!lH>ck{J4Y-M@rpv%K)QPtU(O7PGn={=)9JYPg;-#=miE`<=Y zS*^$BYoCO-_uNdt5Cr=e8+Fs<^I!cm!d{0p$6lvd4ohK?r4QMhZ05|qFhm|O11$eP z^yO}k47AJ&?<|~q@8Ei~vF9D^;dgbz3)%UTkZskST0e^_H3t^C_1lrLm&^>x`C3q6 z63)qc5;Nr&!&=BPS<__mkfSjsA(CkLT0#hXL3fBgeQ}jNYR>|3vQiQap`qo>PpGMP zBp%hO2P6j&@gqDt?x6Do-KhlcFT9|w7+yQwfMDXUcfSb1a5+G05J&a<*N^3Km>j)5 zM3xMbzB@ydc0K6I5RGw|5+5C+#7BOKhxJYpai4BUq933xbQk> zCZF#;`z&7FC0!By!()LOA$ zns#cbiup9qGASHb2Zj6Bp`3Tv5_hxgdz>cfB6U9%o4H0|vT$6$f%5aY^ca=@-He6` z$4a&Ig6?rJyzOa^gb5LdmuWdKva$T>CGalVKCkbqf{P?VW>lFAb{wIqgCcv#3eUbk zs}Wwme!XW*Wh;~<4=Fl@O*X0EkT%+wU@*hWtZmb!tsd_NVO1gz_WEG(n$An6ppe&2 zI}s-S9vc#d%K`Q!^x2WM^Onf|)n$1ETU3>^KL?bg)EygC65%jqf9n2a*G5h6{L+ipp3Ob+zi@7xIcDYjdI8SGBeVV<%(Zie z!zSQ(eE7obtwV{yiKwGQd4iC*_8FWFF|cj7Gq4)&VCu&r)?%*3ZGY4V;jrhEhLXCn zKfPzQM|67kYUk+weXM~D4soSwh=EBr%?qZ%KE^x=fK+`Ph|QNRf|787lC!ijN5Qzs z`0_P6u*=5cec@tsw-#JfCC%=>^)4zUvY_6h_*`@~l@XNe_BY3^Ni zMz0v-#R#cyN);muJP^hRwG{}RwuX>;S4&k)=NYw^^nZ`hPI8qWc@MG5XK{eO3HzXGt6jvK|jsx|4a z+`27a#~q!oyWTQ;L49{Ir8PDcbi2f8Exo#@=1H>07t>=!FyLXeor~4?cG)~{vY9l3 zJBHf|TjX*^&OiEDR5i5yPI2=1Gg?*r5v__mp*18G^47rc7`yPd&l?Pnu>*hmFv1XO zdWO_X%s)ub9TWPW?IS3g6k`GbGqz#~7ro8S%jKAS4~g3QP}>1kvHq9BhGgUrW47xp zx-$NQo;$bPFak%dD_e!cLo~hd6a#T^VoLx z^jrq9(|96;m@9$uJ|GK34ic8sO%8U{&tv^z#g~ofLFS1!MV^(L=2@OV;3r(CHbca2 zn*V_bzF=Hz@-_C6JNT8LtrTo$W`kt*DwpZs+{b?eC@+1`ZT672M&GwJh9)*}@1T0@ z(7k;N6X`N9L~obg(gsAGrFA+JmF@xu_pZPQq|->*88NK$;luHBo8hEC=Ui1$D0*eF zjiTS*n5AspxeV7;wOK*0a(9zMO{`gJA1-e@&gB)pIL57)Yr6H}P~b%GtVov*L+cl^ zs}~j3@&e8=9pIXDPY2<4fGU=+DxNF60OXe8r<=34%++%NJ|e4eJpKhA|ALKQGuH=w ztmiMsbEf04iwxNCq`qr6ku($H}BoEKE-zQr;^JOvqsOGg&NV|aa3~u+gW1_e&x^_DdmkG; z8CQ)A`Q}XO1dx~fzNZMW{XHf)5j5`yii~9)uRR00eQkS!t<$~*Sr>Iohd@ExsbdzhEMpt~FQJ-iPLvVQGC{4X;QqS8WVgiOVx2Q^X{7K=MD9~NhTPnJ$bddo{*BI&3Kb;hl&5Xgqn zIV|}i_m%CLjeig_WissFwGQH_i`M^)eE)sl?oSw~&$P&wU}$liGF~xIb7UB_uV;}Ud#etT-?qzct*yN)OID*r4*>W?#VB?2d+V z-igny=PF#@sRhizng2ryw0jDjd-o16lrP-3hc#q#7iPdsWbkZloLq$dDmeC>r;CBr z{Ey6wqj=aM;h-pe^-L9kbl>B=OT)afFeqKNCL*2Df<0yC;LLZ_XjGq0^`o{_JF1x6 zSYf7jRxL%B9>$-dz3LTgA&syP*S@BlaYS0Z zIk>Am3r95W%cO%_i#DG^s@U`^zio1tpab?nb_Hp&x=3f4+*hv6i|OlZT{X`Mo^a{A z3)kkjiz8a3d9iJ>Yvok0GaFsG=!>iOMO+>#KXGNJit*LAOed!7a^U#rn?ua{; z-O{ynUW&2y8I~LM=@ITlfmu-oG0%Bc%)KaEbs9&vsUmDkZ()%dup`D{0w>fy6FgY# zVgiHP+b{=A1ZqSFd0#8_WB32QKzO z|NW}#P2?81Jl$-Vx)di7t`{TMyN{8oc|{d@K5GH+*DQKV&7ZQJorSy78F z`D?DtSFdifO_OI2SvyY0tL-{1$1o3r0&1)uMuNvIs>OJ-%Ert5AuH9L547NX{i|+| zTQF9adxT$eEBvbKaQa-%R!vprf5)xpuelyyy}GDi>zt0YF#hZAo*&Pqum1Bt{}Y6t zY%Buf>i%y+RviECA#XO@w7_HOar@kEvi0xBc{_ewrJH|i$J;iWk2lqLwrxS8`@1~9 z9;Ya`z8>GL1Zj?Bi)}H^%keC2Gl-ovg574GSL3tui^*5x`xH1G-<-EXJbZ>1YsU8( z7=a53zj%I?)^$_WO%4ybEviP;s~rDrzLA$lUjLeV!>_pMq4BMDXKd6vzvk-v)mP}d zw48r^leXu$-h^xuE32YXc2$wnlJqK>eWq_euk=?{P%CQ`O<%&xYs5&zg6Sj|Nh4u z5&Y`w5p>zF{@K~+`ZxM^Jo?{Xe?2}yrTO??8>2nuo7LEw-OaN_4%c<=pYgy;yUUg4 zoUbK|OTl8C7LVz33;J@PD^dZV&+@tB|0Djt-3al z%gXIKYouO%JUSjP!KY3>8)r>ZH3(VZfg(l%gWM%_U0~S4T_b%&Cm)aZ>06NkkW0h5 zG5X%zRI-Rgo|PLX!nQ>BVi;4IWjHYxji^B{?xxvha5DhTA2PTWEsBJ6RVjk`JQFot z6ytwcR}b00=(H;^#+F#9rTYRZ0$U_UuE!rv&##l?i;L?|$;t7}-G|#r^6qB<#F1Cm zSCcq)`t$T|a%u1<*H?FwtGndx=bK4#dHwNx5Gjq5+4;%w-TC!ZgyLp0 zIr+)p&aZAh+$A@+lj-D6WbN|g`u22k%cI{gM+PWHOyjPI-cl*XJh_ zk(bNM4_AH;8N!>%?b-G1Jo!a&rCt>fGTbt2OyBJ$^q)j<2q+KL{q5q6T;h zfw~n%JNcPMPmj+gcM;sj$xr7e7lP*Q`0m5h(5RFzj&Co0*mQa>h(&&q;}fW@^LOVL z=Y)Mgc6I#m{5{rI^8Um5sZ$>TG28qu)tv`_e|+gPyquh#AA7K?>$@0dib^IQCqWVp z!R`6g`#U-+R84mDjwnSkJ%4{CMwMU*#Na|#PLkzjym_v(_O$_{6**jnY_kmkZ{f`i zOZyR_)2waL(0P+BtLFK5eGd~$41KvRHu){MMT=3$%d2q4_IR8(H%0n9fbw0j%{Jgy zXcyY!qtlyi`qONYiVWXXQ}Es@=DTj{?d)d{w@*{o{jgNUMy3RL)VOa$MZ#=l>UDOJ zH!Zk4%j(yW82Y*fA4AY$PhEjG=d#lL$LXx8#0EPpjE5}f$nVH9-j3HGA_&Rw;T4@D<3o%)_#h5VbwOHY^*{aMzXnG$14U-djFTkbd z>+wmo1~-9VK!nlc5?@#Kwn&>X`rHFC(bZUm^5uEv-g z-q?B2lv@S+$>j6|_k#17T z+QSBn5`h9o!R4`%=91IN)%oNU0jH<8069CpJimaAz+E!^aC38gd#CUhx0B=3pFudk znw)sR$)81LrWA61CB&c!LT=8H+nEq+Wu&`gBEQ}ppZrODB6@Ol{O)3+z^6JpI(R9* zg;1q~H|IC@`}X?o`sDgTho_UtpYZ#`^k?`zfl9hitWSOt^7Z5*IsWkHoAwhPIf3LZLH2^&1(^%-=41`}YjPsioylzgzL=cd1;E?$_dhw%vs4gvPyQsoKf>!i!D5^><9=GqOG<?d10Q!`;N8`0o$rE*Fu<>kqdg(&h1$ST=7(C!S2O8pN`Ab|$<3aB5M2)5*{% z(>u|pFT1HPu8&WLXUC@=kR2OkNOo>OU$a{RHp-9$Kqm32FRtH<`R1dTWlksWKD>89 zre|5u`PJFA3;A?>d!>5R#r5?K{9aBjVNC0Jih23N zGAaohf;i^Gl~dB`Psg_tnXw>_tWF000VQ~h-~Ah$mlycXThiFUq8cs;7?Nr zg7pA%8G@b6h%KtvzvGDtZ1(bUjtUL2*Go&e$&}iiv}h~m;6*7HFcxmx(CNh3`aKyd zuavM!b?$OOxB@?$)p{*9YNM-6-oRLkylhgn#Y3+<0wnf7MIrX#m+5D*liH$!LEXrx z=io(eoG>Sb$}2e+*5=Qe~X&@5Uvl(LJVe9 zATsE|q7&U~9Vy%q&*zzF@pfC+RkM*JRCEexpj>KNQL75=ZnT{cxrTxEyY}~TAgL}U zMogPaRS|Y3#iEs7vR;or!GR)lVH{tNtE_aCvN*c1ca`w+%J?4CSyJ->V@HjCo!C09 zl~x!vnu0zR;|}ZsAiCDwlBaDjB(Istq`p1+`aYNQ$V@3gbI{1a5o%kN&~c|)7pC;i zqGN-nBy>H4xA7N7T`Z|LneFw{jmS$imhTCQ@SVu{XKaCGRf+Nx^YJ^8{+(!pISjV( zPk5p&XS*EKp4lJAtIekVbm2|R5 zJ4UYcQ3)Gck%{tV>1?GB{?*!~Vh9k-#bR>5&+J->L%=YHCQ{kN1n@x_)&GEdyQ;RL zQ{5{Cr{K|UXDi8>uBY~dL+0eMYT%ely-*{v{SB}O9lU6X8uWQ$k@;4->Va1r)Mx;r z2I^ivGleG}sp(O&FF>UQ+V|fkVt+cG z9^ag+Ub}Is3)jUaoq?KN^!8b6$xWk*b!|JtK7s0W=yK3zDX5Ge#b8{?Q=?{E!mOC; z22}~ow^)|@?GhB$W62y+$^K2udCP1g)#%~E8J&LN!in^*n-4ij5zMM zc_Aw2lTxyaM5GZ6B0<#-PXmF9TEw=7GHEN7@mNxvdXW~D!q8Jus=+L!rHO_q=tV=4 zEUWRqEE5s+Bf35O7p*XN_4`6HnW<5qB+&6T?(@A(-Ek2TY!KmWEqQa@SR9`C_|Bs%YPq1{K0V)VqN0E*czht^?PM85_+~x zu=FV`x`&XT& z=xx6T3Q6}CBfWiqzX&+{>fv|)Iz38|=Ir5j_*7aQr-VQ9!O5mJa{zQHn54l!S~vv zlyIAY>P(F76W!@X6M-Yoo2rE%$Y}D%${#4-s~=^RrFzhIQ!N%}xFv;pgOv>b ze1m`A;$JPnVE_c15xz(`Qkxy!E9co01Jb1lF{TX8qlYpyh5gBhxLX>@6;1t2%Iz8) z+o&Lp2t8&jh)^i8SOuUp&5O~auD7E{);adbd6Y_rZgR0KjHI8@(Y%4}wfGUa5CuVb zb2Q%yx~JQBqimGn1F$Dl6Y@!H4ATY(+mU)g5!zA>KLx?TLqVbk$g9;O^E~M&d&)#> z>fX5+ExtX1|HmWngoA(n_~y-N((5Ar{^k3lzy9TizmAl|ryb*uj6Z($B_hL|CTIK6q7m$1-9QKX za-~=_SqAzCxqbJ7S1{jd&{WEe3$sWq)e;7C{D>$@#P>RVr&WhW2Ou+X1&hn^#q`*x z(#sG>rbM<=y+X7UdIJjjTUaa<7?o2T8#!0s7&RgSFHYX$uU3Ft1&2rIO2|#N;P#tH zsJEIie6WL}NJbjx_z3yq^d0_8g9nF4a-*nz)Pl7Xt6SZw!0MA&5m%s5pO;zNiqH1M z7hVNSh%y^lY1VZJ!kdf(-|7O5Rv^6TlF&4c*!modg@!m=BNShqk0}!lBXb@kMi<( z{s4!jqP1o=bS~;7FQFY3TsA2HVW6rrhG~|4zNvBq*W1lWDkg6+z-UOMvt4I%0y6Td zgx%n|=14LDd*n<=_06-<;4#pPtd!8wY@jYRVM+E>8gS~$hZ?M;B^|s8UQzZ?HcZr! zxxQZl-7asH-MILgpj;;k-ol&FSlssd5r@Eu+6m_^xF8VAVYOYZL})4%@Z#%E-F?Ks z2T&GHWoo)<^s!ZC|b~CRYRe}(Kup>aoDhW2(66R_}(YhJ1 zDj$PY>Un~x?$M90`7qlB4LHLkPlWVT1-C?QB%e%fzjT{~7}GR*|5;?^aOHRBa zv4YOYn&$>_&C?*Y=D|to2y`8V=vVKurDZ6>6IcOB7)K`(na5Tw9En{xWLOnrB2Pek z@cHSes2A|RnokQmpB835E$nbfL?t%)0Q>&uEk)k^!-bY6^KBfeuEQ-6HRl0FGg0M&q zTHWi8p|@qNM_Y{Kp_1nl>-Dw_OURJcS%Z?QSpT{S!7682<{n49?%{_;^QX-^gqEck zC-QxR5GmGcX~~pGXSGT%&_!6L5BX9ar!2Sm+$%#s9%*(;$j{^opXsUWP)3zZW55kHttB4RBgJ*n3{aZR{5-u$7tI&M0a+jC`|&7nu_rc zt3Muj;TxxN*(6~(pN(RNVi9-(LYPRee(t8AjaJvivpT#?gc;6RD)97{um?b$V*2CI#Okl5@Wo`!OViKAB*MkLaPP&x1w{mTJgC*KipN1E&)?rk|2uU>e0cJF^p3u6yeq*#XK=_+U7X94KC(x^`e7Od@CXY^SKGMmthjg>N^}Efsx8H1g zJI*%RbGGrWvyJziZM5@j<|u|7^JqB%iMg0DaX%C?b_0DB_q{^;lF;Jq8sN z)L_EuF{rS51S+f^0d%WJTBUhmFQSB*jRgf7X4Yglvrct5h|v#A-3E3XQzs5utX!&f8N*5*%yWWchx8%M3pl!=st=z?+ENK7 zzK+Bvlsf+&LN+h1b|=7OPXTHP!4l_~7j%lI(1Xblq-+9)#*x)E zh#YOVh7iKb_WI)f%2)FFVF?G%9En|U#$spTu~o63?!sATK0NTPEI zQC!~o(~Pi`U>x^GW6I!}kzg{SFKyUQrL%P)a1n%t<;@QQag<^K@Q;6Vz{c>C0;RDf zfha@3wP()kh5z#Q`@d2cp7N4#xs@s`9fot;)`hfArt59dhS_UN5Ac|_X`MR|WewrL z@^UQ;h1W6cSAqtHG#sAT4iaS6zOxd z-EbH@k9OhuMAkxi9$pr(yVdHb5fA4rPMb>6z&*XXYI`^< zWpNjNKh7;dHkns?J4(^*p(&ryRl*nQ%kJxi`Z?0Si9FH|TAbY1af7z*0Two7~i0I>RUG1N#ytb+RVsHxV8Htm)|#-J$cyeRTEgL?yQXCz7}quQd{ zNdEOmIO*N!vdF8jZUoso(5OGb>(}Hyj!Rji4N*_I6FEVvnCehaWr}=`zaoL)ZeSdh zfD6<_wMZ9<>OwJ^nwTwhkSPxYT_oG`a|xzD9VF@oa!9g~TZQOFz7Cv}+xqH_(3>9K zMW9-fy*0?jwQE}bB*$Y&!%PYtM0$$gNu((Qy|5D{m2MyUX?wF4uQ_%?3d#8CX$V~s z@9&)vqGjP?bdH5sr0B?qMd%s?bOI*!Qt~`lEo&h{RZS0psERm+Dn%l#fcr@Xa?*=! zFPS_Q?(uk<)PHwX&0sc8gNv=IkE7y_E$(dJ4jCHP7HT zi6(8CTZff~Iq@}&^3gCRu9}Geq&}6sxcyWDpbSX;g9-dDEvxc*U2R)%?NgP%@5d96 z^uFT8NtFMUgy;o4uMh#mXCPty3Axgi0_!(_GIf~Ub|MoydBjPy=A?tfcBd$f)&WVO zZ%B+bFF)I8gJLKL6Y)4pYfY<9`|+AalvI&OeNzM#)?z^5*I_`=mwa#i`Segbq$c`u z=#tAc`r`C8P(VMhd4hgRz=@kvp9+lqJrL%yqmoswA{74klKXnUW+c>aWC>+iS`BKQ zx1C7AHh*#`T8jq*Ik8fe)wcCW^i_n!IL>njHge#gw>VTAgJDUTqH7{@8WENh)TX!! z1Q^&)RSOD%$0RU`ol+nox&w((hV`!DLCq^ftnL{!t$o-+U>?{-)2^kITsx8h)rTNj zJ#xiHO0udt5T&%&z_qEkO(ip9&y6$)Tqt*-kKx!od z45Z#ECt6nEh+SLnPMRTg7PbB!O5Ry(QG4*g)IHa zaYG-;3p8f-REzyvHrJ{{q8g9H@N|bU3a!&*@T@{JN=MF17#d#V87J)KrhA!6y1O#E zD03QQU?55`Y>+}cc2NAh&G35vNDEZEoI_#<) z^6ZOzbj;8uPS=qZY&?Wuoa4Qv9)_h-)o^fUi^mc`x8jfu+Szv|&NYbIG^qujViTykQ5^=pdp`9UuOalWn&jUrUTTDYPwAi zyQusbp@Y;K8pf!!ePIl*%?b^EAvWx~20>OQ&7n!8JzM0CuS>EZk*E z);9-|_&KJ#4Skfy;pk38p<||`6dzp|2~DJPcP@2`#xG51#^YerDNZkew4#BQ+JW?O zAhBxZII-V%BK^kNW%T59SQZE74d+yOt{kTdM;6z6`JStpnh{S-OgS1H;ypAtrWqRK zkFO8}P`2GzBpk;>0Z;e_eOv6$&4<%}Y?w3)0ObkKjK)Jy;{hHs63Jx| z*}x;N4cWIo`_^Yq#{~LeG+$Z@lizVEEsozIjw>ui(cK)yWK}hvl@D=pGNQ37A%+#| zV8)THJv=(&wI_Jm!FE5TejeQd|X#fqYZW9!DyqGA`3*DFkX4G6PcQ*95Xo z!E>K}Mx_In%7#c&CAADY}}%QTvWkURsAxt-+9(hw4b zeSo9!7l)8W-oJN<%;v=Jsbtw=k?ppvv3M+233)!oEI0%vllO*#1bV%@$>gnnZYpd$ zrmO(xPFdDahnZBUl@5o-2M@e(P#OjGild-@9r;tG@(L4l0Rq>WOc&wz2Lk6J$Wa#x zMG(OYG6e)+P(E&D)l0ue>vOkq>7Cz+isy4ShVYm({?`N5R35 zS-=B@UbIOPx5V#q{hcR5U|yH0J$w_?wx?0 ziVVc|4fWa<`II812}JfvUHF)os$cfJ=tUMbkHtN3y-T6Gryr8>d^ z>($i(diiu!WEx5o&l==tn=~+J6g>ugLRm-dPCSN-MW#?tDp`@x1DR_LK73t&%Yn&7 zIv-{45crtK^g)8R>qMKP+Rd%btM>Tl`fao!-0De#Lf>;E4F_bT;z>9l(;ggch>|?j zxSZf4b>@TgTpBicmq2n@O_p_w^JI33a9Qx`8HoeI0KP(q62ljna?*<*Nva;gG60hl zhMKI%)DgV|*y@vET~7-!5afJ^LrQN<^mQUxOWK2&djnB9Qe5b{krW=k{vy2*7{dl- z&7ym(N>znmU#}-m3NuTH0=7C)8Io3UI^?jFmTqB(*WMwPx9`wTI!aaQ`H!`JsnCAW z`@X9A^)+SpQ9~bKT0}t^8zvv4ZI=i<5F{0j=j0{H8vQ67-x;GwXMR>x(#ds;k9fd5 z0efeHM!(!{RcR3HJLTIDA+Ggcu^O;FdO2GpTiN#LH$ZL9vHxfV07W=3I2%BVO>=hO zf~Ad)hHHB-`}UVYX!VhECl72g?R$utRKDRg*V$<`Ty<5NI|b73A=^4z*#}UZP*P;_ z!WscJ`XahiUdXRDNgtk$^mm!blE8P{W)iNR=A_>d#|-`}o*~HeOal)(y@MgE37?Uf2d>qL6GfG1`2uZw*f)E2;)iNl4P8q`o)djR8N zJ4x_037B{-@>pGiEVeZ$QgaX_wWi#Ftm1A!R<0Y672^hE#kv7mF>XLs)D6fg>IP)h z=>{Z%wRI8gNv<1^mForsAGT-B+>-l0YWV|n9J1m%8C^c1P@u`#^<8(E+{^JRKNU*U0%UyBR+kU=%jMTBPYgR){8}LM1T|Vw8oi5Uk@8KZ9<+LEB+VPtJPf10FSgkR7W5s-lk{j_ z_r=kRB&Z1BfnvEPcE;Gkt3R+UkG7H~HQG+WyAlhlI^Tib0(XMZ$aWZ~q2y4j$RA$# zkoVc6bXxDj67J-B|ZDy%PM-x~q-dmxV{M}MVZB>|HlHA-^8`Yc$z!=jE90EQB%Vd@a+b~(Jm`Ra_B6<(Q%v$2f(*r?snT1;p#F}iY79CG zB6Sc`3_2J(8&#fS&;f)~Mb)Pm?4Z!&B1+LZXshEeAX?$RVz7{k!9pnp3)BR!6*w0Mp;-;WnmFj78ae#!U$H^YFt@ZxXQx9RTdUXSy;rCg@_94 z@+cq)>XPe;i~_Ns3dAC+KrA{Hh!L!H; zUrcpzQ7QLW{dHDfXYIu+&#gOF8(BEoNc;LGNChf=^_eVEIVaO_Vh&UgDurJ4=|l)c z1N5mWq{Osr^&1!waFRY`je1X(LlcE0i{8T9HEL<)2w*M9Ds#DgE%wb%=EF3e4Usc< z3DnDr4Fx2mj!Bpyb9u=yA(I!Qt4FbVRf_~GvaB|<75R$H6$%*vm|`ku(Ax=|ba(~z zBC~y5;iBCc003u zmM;}3Jt-VD+t;KcDECF_7!es4F%t5!bc`hO-fuU#_bPNZvG;zpB35R0dcz$;?Q_x$ zE-X96npc+@oNoiokZ7ruLD?tK86*}LaPDmq1@XMCxR3;2gxcg_XQ+j2k3tkV*)VWr z?Y_Y`FZif<7lK1t2WT2$FFKG@D)C#w3k#HkLe2BG1B+w8XYP6RgNNv09$=!oglMD~ zqax*K6AiJbRYf`*I7&lwuofQc0cuWAPD)u9G%+Z98Mf)lys z$5YUmlc%7EhCBu7P%#R>Gbm&|qFth?<%RTQC^eOKUjjEkNq<3XA~u8rGV&-(@QvvpB$1sL~55F zt5HJ}^NQ0IXOred7fnz7lC3vG(dFqULcT*8Iuh=vQ2=QXh($_!4+hEje_^OtS1t@4 ztvIU})8EOx*!Gq)7gncAAlAMUt@X`Go3HQs5gXk#h}X#fjhlAuVfWu|aj(-zXfhOJ$S4Rnvf@{P_{pJDz$+6F-)EM^f)N;zv>M80sBC{P^h|J-uUx9XWmDMqZ4S zU;3Jx6^dN2@zbK=#&w<_!65u7pte=_qC==pOy#ebNXS!q{BavCPkjkQyF~WD0dulF z)&>z2v%OdAq*Sv<(MlQ5;`E^gj}+UtIYpb5&j!`CMFl}$s37;`V3a$fag8Qlg;5Cb zstaL$W3;q`{BIh(x5} zL0ys7>5yLtE|z4_I!Y5CR-n?I+FnzNpIKUDK7}nyghHgLD%2;C7}7NifGHip1*Ic6 zS~`<*0EqJEI|acp{B4&ofH;4)Ll7Lp->)Bj^b=f+KVLtpb7kr0Bl8ilZ;&`XY?p8Z z2F48*Ol%t@(2dDjHb_*|upx%lZO@}yi?db@GE4*j5q65)pfm+85ClW*TZ93lHAB`s zphvbC4P1ev^`Xv!)!{b@Ch2`!73#VPg*RDYQ>Y&2>Q_pJP4?hfvKXzW^^`VOx^)GS zRxu7p1*EVCmnHS-i*)6oRegxD=YDXUUSve;4@BAls_1yiEh-O{9#TWQ{?Mjhiu*!n zljb9EZHUON00*DCJVsw0QsyM+S3tS?WzbTOU!+ToU+Pm5RW}-@juH&e--K`*5O(vy zZ#=?H2eaYmkmX}?d{l<-kl%^y?#k^EnVrh(zN{X|>5e4s9A>ELL4K-*CM}lWr+Ej^yX`$7 zLc9a?M3xqtoh0U3UMH0_e(R<&jonSA?MOR`oNgR?b`(HmDkr~;qg-WYqo6p}v!*F4 zA833OH1M1^o^d$qdei>W$SWKuVoP7+WZlGxRm^ou=}w0P=`%DGta>#C84r<;XR|h2 zr}e6mzNAdR3}P2T>})N9IGYN9Yy>+LeHcrweO0*-O1eq~P#>q*kQkG*V%sY5ioo$x z){hY5P@;3Do;FvtmzT0piY%+m2Ti%C%o{E8AlZc^W}Wlk)+~Q1x=gI>!w)-&(y}0;z$Z!naRgmsvBgJ5s4v&WPCvaN^SN`QZ3C~)aer{iD z*w%A->n{`4UsU(RvH_^5Z4%O~;320N1y)xVL4bt5mP*T*jRON&F{DJO%Ce8thE}3G zr!KSE3XHE@5WXnkvv94&ERH5;?#;vV^)tz zor>`aPd7hzV9_c^)^#@#k(qla&BKN3^l30DQ^gU|ZZcYpgDAU+#BMLI=6#9cD%)RL zN!DA^hU>_dB#vo^v}NnHC0_6BCa0~`T}p>~7tY;e+TkHQI5~{8n@G3nfE?;J>n}G_ z4&^w2#O&faX!$wD5^N%1G_LHgd!*~FQTv9wPlINJy?0bp$@2$#nHhnBAzYFI26E0S z2$*xu+0`{?U0u`a>I#COAXyLvK@>$0Q86Iq00s=8f(cZV3ZDiaw^H&?0 zCT4u|S+jN2gPL8Prdrl~!{37KQtcmYx-`?MziTH=yDjm)_tOF$-mdvGxU}E27PW2C z)egGyor}iJzO}f|!}&$Nc$j-}i}H?=iZ_NhU3`Yu{r&Xh z6^8?d-@U%UqyLHyBW`{f@sDnQ)dJ6{hM~F|VTyKI_YN&vcp~))(zc-{#yT`t*4(0nS@lEx< zldGPa_SqQuhqu-DGYbf0gg#iCU%G6g*ZbOz8~w`m{(fQAP^44u9^=-;;LK;A8c@*7VuG?~4Bjy%aWQb7N)PA8(#+Zhd{; z>GS6HYjS&fHC6u5e7kP?%FFM{o8NsK)N5_h=C|c7FV_8W{&=sox$g%4{HxHnCG38h zyGp3T#Jk=ro=(Q?`J(a(R{F75jrE)Uo?dsX z=~?fOl}Ar}UBiX9Q_}JEmBdd|Y0&OqHf+z4hx04PC|qlfdOS1Q{QUm)+h5o8TDHUN zXWq&x?$%2Arc3!{b9_hT%hD2i&g{MV&xSEaHf9H1JsA@cc_fS9_}7>o1F!G{Kb3@E z_t|l%)9vF=yb}{bG(siM%LcY7u%2l#c!_?=ggsj8yN>8F=h>EbJ2uYlYxcz}tLy!T z%j)uuUB1xr{+O4=Mg3)`zpZW@eZxxY+1ui+-y83IduZ>htTVamRAU+M<8P@IrMCj|mJX3jzB#mX*S@uXJ4;6#DOdh7B)&Q|WncaJW%G*WDm9&UR$X}ArRk~r zrmn@^|8ab=`MUJ9#lUT29`=@fuP$AB_(XnC!Cn4rl!yA-%$hAzzHTu2d*-Igh0?l| ztRBZt{74Gh{Akz3nv*Z?$CXst_V4!XOx0(#^xwK{S!sC2}Ztx2Kq&hYLhU!PHFu)1E-iYvP|j99sE_RzsQ<~FE?xmbp+ zw+*Z=OP^q`va#m&)Qv}c8y3!(vq7e%ss4;5+vyy?=}^@4Jji)PU#-h&W!uL- zHd9UhG;79R&b5lvQKP$kOxn`zZ;Lhyj~#rF;B)S(^~V&i0QZEU3tDf^p7V_hPEqf9 zZ*0)h@zzso4sLmvymZ6g`#HBxb}NpIoIHMo+Md^CTNj?2R?+m^^`vR9)Ku?A&Ra9K z{B)yd^u5+s(;jq*Td+GPb>q#Cg->tnEHdog#=XtBO5J6+Md~Gwc}|6)9G2N z+f?Z~Gs1s%#<<7}E-TdAJW*O|qhoeqnSo2Ad_h54cj>gSG`%75gTs^?mw6vjjM}+% zPx{x++P}@~HSq1IDO3A-=M{KX2RiTEYSP!KeDaMC_SIJ#E!TVcXXR~BOzD<-_|uWd z>-mQ1d%iYAHC@`NJ8;5`@xwlT8$0#E_zL|m-6uvrad~pP)3){I`d!`(n^3jvkon8` znf->(vfYxXaZ3C1Fh$9s$syyu>m@aYulYwMc*2A|L!T6dT=uZuwcyWjCM~fc=~b2u zYs{7%&V3?#HK2>C^I!IDdg>+^#W~bm(=4}5{pzmkqo}RSy`nehyu%&y>JvFjvmIRu z()uVTKK;9H%%~?JUv}wk}@ampsha-1hc5_~QYrEFGmsUNm{PY-H^0TPs`3L*SjxG*W-9GNU zy=(ju&woCD_@4TGi__3c)A+-AZxtWrl%_mVS@JBr>*|+r;}u#BUlxtOtm0>LwN&^` zeB-1-vt)}$S9&@>yOwgt;O2d~*F61Kv-1XS-gxh%(;QXrG0u9O4;#1q+>x{0splB2 zyvMB*UIZ&<%v5%E@pE}oJIposP5i_=kI#OJ>ALW={prJ3+jc2Dy=UW~)9nncJl+&r zZ62qeo7%(VOn;~N{@lmB)mx`U+@2PZJMGK9>jyXHD=E2btX=eYTgB-4>(A-Tb9O7T zP8opj=uBNJjml6+dPp;~!(EIoNiTOg{ca0>a(m#gbKg$=Hfl846ncdAP4U&6+hOw< zn>tOGkzCMw&iGtwo!P7@rK?_N#Pu>#>}?$55L9jc>SBU)v{Ov`*gsRMu8cny`lGvw z$&1R6zrOwD^mMNM>hA;hT{_~Se6ZvCKc}CM*jJoc7#*jZu~?_S^D>LK>lZY*jE`&o zg|=L9VRX8=(O6ml0Tb~ zuR8X-i@EmYW8He*>E111&ZS#_#dp*i^J>n@Cerv}3tWusRqJNa)+?d^MNrpcD7#yNC8 z4mLf)f|9&aLBXnk$xOHKtW^H>uEA@xQ`1y~WgHm68zx8rJ=iko_ zu2joA{4v>Z)5d3^rA(h5*Lfdt@ zufMbYy>at{xV7KoyR0@CX4LLWm{-X6L1WB+atA`bN&S_KbT@h=M|SOl6MU}KcevOg1_9K{Grv!bj;1)FFyXj ztMzzwV?@69=nkG9D#6p|*YL@IgmyHoJ3QmY(2HSd=1B|nf1Ii2br#R)Xu5s;sRb)v z4tQ|ABsOeSm-okmo^HKa|KPdn+EV4f6z6o;v+7^m<{mvaJ^WOqyUViNW!&NCVN<3J z;%iMV<_|5_8Cf*?bLMl*i4D>VzQVdVcG3;>lZ-WP8 z>=w)K@!28Uwj5k?wtHly)546k7i0IIFtT!r?%ycildHaTyz0EcT=c2iIpt0(2ENu% z>ToP=NwR;@56u~WyG;6Cq?X|~?%Z=Dlb2tgl-^T)5o5Rg_n#%z{ni@BFYm8BTHj$* zj7M#|1?F?JMl|eLpj>L-L2~#=%!XZj&;BP`R(5|LW5UgCaCO-KY4FnG`JGNy&Txnv zTVIs+m-ggN184t{d9VD{+POPUm7e;VlvmZbpt)%9l+@duOn;_2o0f$XwoK1HwyVhM za@$poXKRl~{8o`vJUHR_GTG)iV?H0YnEK_2Mbx0i-|tSV{#)WBlpg=3riR{>eaSZy|9$5H@&{JbZ`1m-Kr8kyUn>(>zB1>cj|R*xKN8kZEj9$9~ET}V@{JxPE#A=z;1(%8fUg2FMHXj5bz*i`t!^~$F-h;1|fAq@Pcr`k==_6(Vr zVorStUV5Qq0vg<+%{Vr2>BJ=M$-^I@kAdxkKE7OT^l~}ILy?moP)m|= zXAH4EeS5l(QW;i)rf->swS}lpF9V-m7z{<$^iHh<4-ZX!gXP|#DJXnkB70z>&yX~m zsRea8A@^^+=u`=H@65@7&)TS+wJ~VXrpVNJESl$NakCa;$LPG|)GHZ)Ff)u}qGJO8 z82(ewT1ks*&=6YwW+MA$qQj81e4ry*eiwFk?cB|_N}AjQbF$XQy!4IUbz-G{YLoUD?#%i9nn^3{B?qo0%ZRm z$H`;VcFL&zjUZHlZ56I5Ps<1_w&(z_i5rP~6e2B0qg zah&{?`VDbY&(QPJ$^#>sD}2Fu8f9OK2$%O2XNA*gYAZ#YaG11iH8oeE#bd+FC z$u9n8E%|26!}JLXJ$#BS!S#3Rt9N~>sYJnjAWNTeK*kP?XR-aSIHdjzJEA~Vx~YwznP zPq`1B$H}7a4OQYnW-Z!fE_|7b87Kd$`dM7`ak9|y3Y!Wto+iO}W_jpjc^ENdJp@1ZhHU$BkjM-m}4G|c-zY_CO&(9d8G<6sXH zhD;|u z<+V%D<}UfEdMtSE2WdYN<61+d3J~@(<2d;p#T9XHq`M_}_I;27=^MnP9_CA|K)qYE z8OO;VEAELVW$yjWvc>HRhE{7vOuEWOx5}nti#A0zw0;$r47BFlhFAh$Y=|D$xoOt9 zA<9u?Vm?VPAB29+#|(TTp5#Pl$%)SJcNE#^_jb!@8|zvQWf|JZf?Is)(f*|emWU!# zmfqd2AgiQ8m?Scg6Za)N2y%?$3|r(sq^~rHd0u>YZ+^whj}Xr=66Q2}F`vB{J$!A> zzcz2r$#U<-&+WbJ>PaBuNIg8?!)Tw-?jPD^%J$pJ4GfIKFe!&%ICdkyOQ+t z$|)%i>eZsnI8J_9<)RYZ#m2W9-|g~BmLVpSM5NYKR%?pbO;Kbrej z<1w^;gzk;ZZd#e$;6^C2)|U+Fk=BrL0b&srWHNtRtNparZPBL4#JY}9b__gz5n|E& z4q?rMd*}rB5P}y$CRXw7QulMjW(GX zG?^KH&{eD3XmQ_3(iLeci!?)_KJ@DwwK;*FY^{{ zicIY3qnKqaG3T*B-${T<`=F!%nY3s#jxCbs`Jj=!*&`@y5WU_A&8iU{u;K)n!a0xE zubK2lOIee6MfSC`gY#6 zP+7rMkd(MCRjL3Xb!HqVk5xpAp}|D6ZuyEIiy&Q2mOP+Ei3h>j7{|#4k4kN``S%Z@ zHRu0Ef6tqeoqf-dzvqZvP-J~Q+Tn(^ze_sA#1yN@LbJ#Mi%pS<`HgY7IAQV|h#jPR zvB^uX$*VKAEI}sLt++1PGOt|dBH3hDmK$AJj+~t$C;y=KPCWgDr%W{Rud9GUKhs@; zcTDlrN%2HLUqPt&K1nw`FgVQ++>3 z9w(E2H&n`lAX{zCS6g@DP6?HCzB$o9Z^y)jnaw#$cU-#8l>F>7q39$YvQrKkI?@b@3^Y*!B%Zm zO)i!0?p!auTraB@ZHjE*`95V=jj#8H%6r5zA_Js62vIY~iqElf;N-W}Z?>VPoAn^0 z`Q+F?p;ENTtrnVF1)HSER356E@v~jPT8M3f`Bqgw(J+$!uE?#ua0aqIq?ZY05(Nkgbl5?0*r5X_&sW?Kx1)ut z1=l6@EMz~C&0BL>ssr*yHA3V#`49E)ZMZ8!`u%Q-;;){7$Rf;?$n zh^mT>T%9{c=HQVT_s9%;lOiXayYSx`^EMtH{?2kO?i1M}!S1qP;gm#C@Uh_<^=&cn zzZFb4(MV%VcR!xl=R8Jpg!HeaANCFAsY_9x8nLDTRMvLPc4*zv($#p1fq|+1ZtQqVKg%p{>oR2D6^R8K{AweJ+ z;CoZqds9eJ6bAm7W`MFQwLQOocT`hwZ-_0Qnbr2pEaV#$QTtdT<0H^mXFf5 zIjd=MnKX{K*l4!cU@|GPmQP=pwj(sIFIx5`vlC+{i?Ks^rYN-hOrx~}rd+G%_VWW; zhC|;D(*r_8z3HKG(*vHEBGY%ESg&Kd(h2BbBJo@o9!Yr+yj-gz-|A@3$zRD|h#u+X z&xQVTQ&vHx=n_6#Yks!I{-MZJns&?Fd}r!rsEj1G!_H&Bp3HX0gT#|rS%0O!@6I>^ z=__Q0K9oufKnTB#`?YGJ^tpcLb}kcLc+JNM5$mX@@=;GUhO7&(t<2WVH@XY4YFcH; zwpPowM%qu2iAknq&bvJO5!$XNc5yL4$rv;U8%^Ypkttp))3m?*xK-=Sh>yaInvq(e ze@{#Qo~ScWWJ)(Fx9jDq-wdTE$bc$dNsK@^!ZMDN$0>FzbEky@WZ;7(PWB!$b>v6X zbEkOerFgj`1QTRRQ$MdYb2_Q6uFlnvyet((U(f)Y-$jmjued1%eR{WOsw=qfWKSkn zEAb#yq8P`?!_-2=V^s5P8_$Ju14x$>zkL3Sga^S)?pg5nED*4xR3k*c>@!f-aP{*% zb(kLM!+v|&etX0iih}7q(r7Wlm?l|&YCh|<0%N*C$F$c=Z?6~pCq*_U=?UeA2O9*j zbJXIqto5_3aRQ;p#BNT$-5B2#2(jI?auDqykM=+vh$0h9-Z8@;%I*wqHlRph0XBR%kYNlqR7PNyWZGT=v#xC+)8r$J0`L_ zLOGctSxJ)HH+#1$dY)4Yxik{53P#8ZM!;!OByuV3FyR}&$EcNd{sOr;V#n3)vTAoY z1&YGT#B0O~wY;C3U#~ZIYsSD&{Lg_$$s?rH;O$?0S+u!USAm+cc4Rwjwj-mIkBq`* zqsT@RF|)9BZ>b@~#FE;{dL<1I2E;ffx;LtQsO}{Nyc&VT={j;dxdw@-q-EM zGDu$`lesHGssLe{w%I7Q*_hyxLoHn_WlwPQ?@(L19v$#ABV~hpPer~bPJk3y2V}f) z!NW_wP`QWfh;1bjT@ZZN`Qf_fhr1%5QoSwVu4qSUbC>socAVSw3}io&=364A+922l zC@(Lnt!Ou%fu7<2yfZ4W#j8hwQAC@*qqX;}8ku4dQeiz5XiJ@Y+HR)CXw% zxZ$C3!viNWifjsE9Luj>IJ8PoN+Mx$oKyjV(iB@oimeqKsQPQMmY>(>`rY;N15lYn zOAg^SYT-8OE!q^BO3%uthHqA8U^HLIXo6lSnSh31yNMhdQS#DyXRYEqD11x9|Iu#k zj&?&*Ns%cW_NM7clj$QU+<~otW4xs#(o)WlDa$Du8{+0tkCA*J3l!sG9OHteq=-Vh z+DRF82)o}OR^0M$qlscF(f6rY!h_&y7{|#!t9%lZKAUGMQ62KsG&MP2no^uY#T$e( zE8|#4S4G~N@i9&pqNiz9E!SQx*B)j^k%@I!wrqmWM+>z7fGp&(U>OgBi$6P(KRXha z4O>CR9lI8D ze?*&9*Ft*ehV;OpgCd*zvQIZhr&vZo>=dnMoU+k5WrHD6WMZDjBrCV{i^7PGnh4Wg z(!rvngCj#W8p(|LTdc?KLk}xR59{)zJP1d;3(ounXB_b^t6ywGjjnN;!Nu)u^3iY= zO=&Xfl{$dnzZl0Fx6;3o+jd$$8vjDv(s4{DXfO^XBF8!qczVVR4c`JNJwZovF-EEm zLWP2HOzFJTB;DEO?}UL<+dSc(cZ zD0+l;gR(~YylbPS;8IAglvOP;0O6#=xL=b$>v;cV$EJH}{Tpa9Ei^MN5QZtTF6dT- z$7@aU*3#nMljs^dLKZs$QWVM16O0iIZ?2C@Uza!wjYpHlcUDRiAT0S&2gT9|1h8(NaA{;SKtVkRAIL8l4ACd?ggu^2U7j|cy_%lwp zu!~d)7Y(%csn%ZIkL}XJ?jXK1vP8)Rgo-!g*gDNLz3lK~WD>OAApBg$C$In3nh8}xD;+3CfOl47BRMUnMz{K>SrYJFyFv2CbD~?q#7W& zS;lelYSl{d{1o}q!S&VXgW6i$Ns>614r9cpuk;I$VL z1qc@Uc(~&6a73(fwK8!oEA}r~u&d${WV4Cv+q+T?5WHuzvqrNs&aI~unaVxGEO4{< z>X^N2T>S&gfDb*~r*>APc7{u&$Y#LxFN-!$uhc@U*_8O16FoFf^gzs_$i)73?J%zC zZ7qg#g0x)ZE-MmJI*P(@j?>}T#+!{Ols2J@;bgP7`bl{ZJmNkpexDUQ;y%>`G4IX% z6h6IOv<|Pyy)-3@^uj~$g|J8zS=&R?SM(kBUJqj8IWOH=Gu;{IJc>-rr`IsQP;*0w z<(nQcfRo!jQgio6xI&6dOigp4hEK97#KfRhW1&`KfuKf_i4A%xEtogliPz%3lA3#f zsVu-0=>|n&W~An>H^qPE*Bc9Ycy;1nT7#5$5LTLTqJtq7LG1+{%QCdK@ao(h5`fYy zBxyq16oqLF5(1F=x$#GDp9?_aUx=yQ?;^Y31^FvQ()ed#FU&PfSfzDrCmO#>RwV%Y z5QHqDe7K@qNci#;xne+>YQFkU+vj^Bn@Uo+79S}O!pXYIlCQGF$@+}^l$dMmZy(4iHqR8gR$UCvtC8-W7zmTn%^jgY;kQg%#S)t;ncr&}GDzGVY z+aMivZVPcQ$B{jOa1do2+q~PRPfpyTHd05E+p0tCqRxY_^T0-<$eMqvxml^d*BBiw z?jCWhEv~W_S2$LR!esu`^c4<(_d`0>ZjE26gQSp56T1rk^-|nd-YQ;-&x=3#Os2mR zYCjRR+f8NLO)(~l|E+wrTa5el$ScrVLe?_(lf(dol|O1>aMXeoM2n4nXmKkG^cU}T zEP?EObPMbKQi%t_4Kt3D`>FVf7kVcq`&*>dzsC6EXuAK%Q|*x_jE^E4|0>JXOMg4| z8A?x)74^eb1EF3XXvGIw*>Unr`EhYYt0v43+H~O?2314`wbf0w)eUw+QJAY>EizZe zSM<&62W#u1f=F_JsxYYn1Q%0lt*Eu`$jL9NpBKYr)0o^VTa^rSHMubAVnQs9Lo6Xm zk@eHvwfCDvo+c3cPE&*wIR;AQ4$eH*D3RBo3lK-k0wtQ7~Wap(I( z{#`s}JPMp1?P28(*#xplw&K(bLS$harx76!lhT(}M!zMuI3$nIRp)jS>)Vas1{w(W zAacz5rWjkfB^Lb-y*XqCzP&?mdnd$U#{HTEELP618TRKoNM{h~`Y@?32+41qwQij? zlHUWWNfPdG`(iEbj8r4Kg!>D!CyB3!3RdDlsCP5&S6^{{szHfsViczBjTxz!UH8zu z?g1}AkxkhG?t{UBxC;==qPH+n-g;5q$OR}evGA(PF235g(RMu9t7!$emMjoz?VlX^ zPmZXy7t5cC#`0Ej`ZtduMUXu~#&jeAK`eP*iRqIRG@}^J zAEMzs)=VST47N&#VRZN@^gq&N$ZomMz`;Hm1+fLsgm# z|HQ1eCxpT$MNVF&S|JARAL`34SiAW{awl1&y@#X<5Tep;JH>4~JScpip5JB#sSQ6* zIGi)aHBe8B%O%@7)m@hAJ^~?@pwQ3D8kdE#+V__>s&5*iAo!LHzrkMCVBfh#o1!3i zQ=>{Bf)j$$EEi{|VdM>@bzeA15OOfaF*D`1U*0)IFCG0%BwNLIpOONE1!Wwn*lMA& zXbsZU37ay~$CQ4=T%DrTtq5n02xmlaifo=fWZyQsRjICzN+m6I9Czz|+-($mG(je2 zH+iM%;b>!hRIth33&7q3Vec`H(}ZH>b6a(KHVOWcg%0LU2+94MJ=YIX25lEBovG@qQ!prjsyybaC6G zi;>k7nzt=9M^+Q6z5_>AqwiW=_@y01+ckn9d4`05{9QP#?-J6Lcw0W+)&g!#^@5n1 z-nnot>(s;j2AW(cb!+MN2I=+?rO3?YmHCoIbGIi$Wh8M_iT+X^1ZT0|ir;UAdUb+o zyr@!nZ>W=pXEs!db=&i&r0O7qLB=t)-TQ^%eg6dmJo+ToU1K7vF@aa3NJdVKdsce; zv1udnpz;d!{Sn@J5#C4uC^B_J!}!PT&08UsL2C&+d$ix#17Z}J*k3n4uRfb-)b`)< zRp=X~b|4%E7{^4fCN&InPBCh$&g~*onFKcl8jj3Q5hgS?=YCR#41u?vY=k*qsXzryxDVb z(5O6lJ5BB}UBGHDy=vhB5Jjd?E2c2F?KR_exELZfe!Wp*0K(p394C)fj}p@|*TQR0 zDlA>vX>nJG^&B;o9TgH-ih^$p(jw;5QKf!!wAE>}?oV4!@U}?sMwq9_S|4YWXQc0X z4PsmAF|E>ruk?UbP-J3l&!%`=)EBi==kkf0Ip!)k=8CL|qR=cN8rR^s^rrrWIw;Gd z%hzgS*lHsjmk2Utt$TZvNjJ7YEW{#8sP(6fQcD}9!H|iy1Xs<^o@{G~4M4Z)4m*B_ z9SZmqnb<3}lBX&eo)9}p8{K8Axl4EqOp%GLt}pvJYRYg!Wa%VHXm~5-LAbqV+^?m~ zXw~~auO*E()Z#vp0375l3vx%(6v+yc%jP&P?8zw`e?xWd717!_LcdXXj6soELP)#J zA6AWf(RL_tc(0yGc~Bo1tjPWP8f#ED>8BwksTfcy9e21LA8rS`p~walvC(0ALWj2y zyGC!m(!BK2ykIsInOJ#o*d`C_Mu>f;H;I0|bp3>19Z+Oq1`bQKV|K`maDpUziDGu78-&`6OCdXMk|PT??p zTANvpMtFft_I<3aB-R!OVv1~XcCE_y-`Up{E$=0a@vG zIBaCQu#s41icBneNaW1*YV{b$H?rlAVWWfK5E;kDQuK4tv`-gQj5WEtbWM`H^pd>b z=qNIUJ&j5oi;9tvvldcKyto)@`a!{xq!Epy|hc^Rv7nMjOL3^S1wn;@`I zWKI8*J!tQ-Q9aOfjR|?x_Px8__wJ}PQDjZqs@J}lozxFvl{8fhvQ-Nbb_+!&mee;{ z+cKyumFn2qB1Zzdlp5 zba{EdY|Ii!`;#Q3b!pqyrFhOjk(0kyeJdvGUZ%hA51JGV$dYO3JTY*v@gc4S{6<;otu>4eg z#XMBD_^VRXks?g|S$d>%mqfX1A-g2VCf@FN^8CJaMQHdWZP?#i&)*x{l_G1nX6Ea0 zU6Ws-;a$X2_~c7@5MtX0NB)B&inTTJDluJrruxSH?-gGm`;v6B4maf>xcLGLzQ6*> zOt@;O*vT7ut9zt8ZbI{)=mGqweY>Ofm{5wW`SZ`s`mXo1ZjT?#n3DU|eWQ%`jl%R$ zWMaDS58mi^VNiSA1(G4}PL`U1hTpx?f}`q4G6x*9lQdnjk#k3GA#H*x3+?je0{H?ulWk7PsM>&h~PR z^7eSoLFRKO(k~FIBaCCFJf&`U^4OLNXx&c+6pkwr5Mm1Be%*0b+SPt>GW!DQ1EddU znk5DxoO~IF8#1+G@raaK~(6MaoO2x$;8kMN!r z;XRQCQDpO(`1_))?5|xrD7eE!+1GFx55oTVHj@7~(ws9)R_s@{BX!=2)`8!iP4a+j zCJAd_8abKJP13k)rxNw9yh*Lc_ljLjI_?4 zpRATcYZbA(FZPlzf@h$}G>*M-xh(M6UyzC?8vQJF{47n79}pC#J5ZSJM3)y$%EhS= z%OYaM9W07FVEa&H%BIea)@xo}gz>geZ*?0LR!96ty zn~ZTx^y<_6htq}_cSM1a=K5PK)wftGTC^!LG2{80`uEFm>xd`VWX~QqksUX|cA!YQ zN1nNK-}LpLqS+ImE{5Kaf3?>9YK__kMW$}{-2KaLjhxs~!4;7;j>j5ET-i9A4`LF_MQjXVq&k~Go?HT*&X9>w<^CVI+v{xdwZ6jS=v#ZJ57>_z4b~q zAmj*)V{_T1G%=~i(zVd*N0#qsj#L)}KbY>Qo9^hs847PW`d`ov*XG*1t-IS}au$Xq zUVLO(sAUNW4@EYt&Cji3*Sz?F#-9>9`&pu70z%`AV~yK9n>gCQ-My10_mpNb`CfYY z!f!DsGKJpDHw+znZ$Kw4u8G{FoHdc16%sOv|4sYnPdyD(H!SXi?3;|`1IiR2cZBER ziqhfkocylhs_4-JLhZ+ARNjDWGYKj_gM7|pD~xGU&}^&6?{HxkJx zMKN7i6c{HNcTg2QVOl1+KI@s0(i87Li{#DyX_D5}7lYi?1<;@ax5YjisF_kAO z9+j-nwS}k{$g}O+WeeMtA`>h482R zPkQPG={+5U+|j23b6Fu=A~EjQx$LSGmKF24FQl)L#6G!L%7fs0PmbVEj%d#r9#kAq z4ny$`KhFNKDLDC@-k<32U3%^cv@i-3ewIa%^>^0OxcrMZ|1{C!wvgSC*F~1s1v5pF z%oMrqGF{`Lx#03z6TB-T8E2lUBv1Gq3`Mp)UxK>1o;V$d9>x&cIF9oZs6WoDPJE?P ze-!f6v&8DP>Th3nt-Sdh9gODvJ7VzhcAD{aFiwiBgIx3a>L1sNAtpYCJ!`Ld)*gmI zk%|3n_2Xk!V+q8H>0N4Tcg@!BsC7_eVmn6~m1iw4LkAC$;%Rh%QaccWBI97{s(IpX z7{2ZOY_Ev_0O?a?c@81P1z~v@_v`W;YOwAejO+>l_kUiBgv&$4E0oRS78Y#$M{0^} zi|*ibFTHf(EJBfWxZ4rFUUjmbsXA9mT!Ie*4yXq#MC91qf6QBCTRzzU&0isN|DZ-< z0P2R{xrp4aWz=mavh_>nnV4#E(Zo($++{892z(TUeYr;B}By4?&YJxG)`xXT*c5rilTN|QAb1f@kud#5=E zEQituL~w7o5)Z<}o^a()xZ?7(S+z;5-Q}yj+c^B-I?O;FnSn@*8-&b+acl;9&)Cq> zbLvfKEhSq2-|iZ>$bH1h_}P$k+VMfbq$~J0Kw-mj*~YiK8jxNyiL%!sMvBW zR{?cAPb}4+SmG>7kuBG(O=UwCM^!>;IN2s8_yrmWj`^uG|I`^rgJiY+Vnu7%wUvvD z6W>GjIB~k6wMsll$WTS@*Lv@^Nm(-vymT?s;!221YwaX!?S#Nckxaoc;lg#qn0wbQ zbRTGjt1H^kkT*)YAoxhevCfWOdTX@b)Inx=he&4N$`h#qgaYnaC&gJO6mS#d@uIn| z?iXEL)^ifn`qDUGVWClB0Y^cRsSGHYRUP%7c(gGw#=4Zf-ySbIY7( zfslSm7AzEI0D{RTx$;S_-8gxOO0ak_YZadPZe3IyWZ#h!Li#}^9t4wR+^@&jfgdmk*%O}|4hxOI!m7*h>G1Go({apidyeg)Z#i*}JnjrWX#8$ow`aw37OkCMssTl}aO0lh3v27pD@Uq%jSqMGX%^N?^HK}Tv zxjI))(&45N`b|Pviz3?&8`|CIHG4}4RPG}VAr|2Rgi>g$6W{983wPA&$Hh4~?sRRY z;&dWpbII)H=1a^$=xSvb^U5y$#P@zVZQpBg?cz2KIj|!M^Ho3}d&G{^j1|f<6xm$m zJ$HC%y7VYI`IB@q!CI1Ft%e04$U3>&@YZU%?MXCznKb;hOo;~}lVcnVM*dUG&UW;V za6dKiB6MCS4*8;$7J;>G;Q^hA%i!EG)6eT4kn&FH!C2$>=qaoP7b-A2{)w@`4g zWWskN`hh&KNu2l!Cp?$D_@ARI=GiWtXQ9r0C7b`!DX9d6lO*HVXwJSqf2fbf z3N&6pk4OPMwF7#hd_$2nKJF<0O{?c7H2#+Cr6c&+0tjam#&PmWMY;F`hW!=x`v(1U z2+~PpBKKEI6d*W>;|_}B|F^1l$baz8eKQY3wuKC?2B<6r3>u&hO4-o@a9fQ(3%rmMn7iByM26qa@e~@5u{}%td=Le~8bj*Xa zFR`Wgi&7qheHZ7z$2p)Z^ho|dw2|kR4mYm4_YfU;K+SW{NXuzv)E$ zXA3RvI_bb+ciCZggkOrn;$Niq$BnHoUOXJCZ;4xWZSny8nWyG6Pb@w~rf;0iH9xm# zH%l!pgUtU6ci9Vf%qK-b-yxdlZtXOARP~<&EKyMXpJ~E>Zzp`tHJiFChM;xv0am`1 zX1?$xAd0N@JnOrQyjx~K=@H^;p87}?AZ*GCOGSmH5#B7zPl&F3)BATXdxy@0O7RwF z>&W(7N21b2k*RF?ZM?fzrzKFio9v>j9ZFUpxN^q*`Z0}(deY=u2HPMVM5HgzX?J-J zj=dB)d5}t=5_gYBfQmU-Xg=iqSu~$d1Jw4Bn%hU>L`#u1f1&G^Ay&U#fY?`h2EBzd zCRxw=m~UaF;F5_~ zh(Un~1ZT{+Uw69Mz)yPHAK6>sdjRwzWSbqo%?=xlBJ1dmgNln4{iZ_cGh**Pcm@kX z;6CNVpK`*}f+&>;F=Ec|U-U62XCY*(Ne7PQN{vCDDCLVBXShY-qa3P1g65HLPV2oM z{e>Qgk5C?%t35EsR8eF-s0ufJJco;en3%gAvs6DOco=O8Bj#wE&1Gs+4lMv6>K<{Qj8-^<0UpC9ILP3TioAI%8 z)e|P_+{S<}ljOE=x}tEpG13WwoIF6`FD9TzdSCsTeyISG@g!greNo~;I9M_cCl`61 z=mgzt%XHtE68GRnkPm7<=+Y?X&YEAzMz|%jf9^ zpQpprD2mw$d2F+F;#!{>FVFpCh6CWPpqZ;n2Z2IBWS^(T*MFw%>d6o{G)Co9%;@<_BT3QDj|c*sN{y z+Xy+7-XVS?1RoLuVRJB!liyU&6)S?n(nn9bs%8c0qa^1nJD|ja;N}>|$#<$nifccA z$nNgrE1e--NE~e>emeq!=Vsimmnd-)e;R}|xL@a0s}5PXSL7~2@5;zLonPMe{BqbFMNa-!wN|W5xfuLBcC<3a26a2K z8iI2Eq|x4*2>+C%7xsRB5Qfis~@u5xrfm5F5(U&en@x_ zmVLJ+zgu_${ao#-IOB=+3B%5exrQO{By)J%Q*vAQ1|UVD?W4jI#H>{l8!ja@q2)L9 zlNCoi^^OQ%x1q>dR*Xw8+mmEqtHoU)BPlhJm71VHO;OMmMW3ss_3bj-S=-DO1p#tq zyc{Rh0AYI4Y&Ftskz{78W{K0|?te3~{n?R_Jwv+KgpX)}aCj)|%a`?aO{T z+0tD}=wty|pAUE?4MIZ9I8MGr#Ya4h%csqMdbvIsdhe1gpJXFR625Ink?9PMS)`Y} zGX*nWLt5W%CfhEY!zdD|D&gBmQxc;+Z#SPq+n0%4&`$hNW~UVK<*p5X*9O(+8>%_t z6dgP{rMTk9bqu_Ke)%Y(hi*g<_(FVZpFwW~*+4f?umxc?8TV_3)VU~U*3dsb zLGKHqHxZW!Ah;#QF}?mOE@R?e$m~$4Cr0|iMD|0-HYpM*Qm}Ta>p1zHg`OQgibiZH z+*K0pihfdL+BP|-&Xuh1WcP2C{I$LAYkTZoifoeV-R9djGz_pq044$B!BYOgQb<*q z^Ht{fwnnh}cJZ`2YVpj;jC0d@bMIrG9jKh7N;;Hx}i{b+g&xYg`L;5wbjr3XV(q|#4P~_x= zst?7w^0e$hRx@tBK=V=b*RO9JP2V`8uM}DH&mLXq@9y#*3RB3wxDta;k;Mpa5*UY@ zE7gnQ&WQWIa^S{^D)#DJ6p>EA4hP{LnQ_cKIy?R_Ikv&r9-D)7^ge#d1j2HDa@P3d z+?F%Eu6U`up8S;Q|9_V1_M0^S1(yV|Fna1gWnp~E0&$Nb8&Tctwz}iT z*g-6d=20gtj80l0=22u~GjD1H+i&%R*jXypY_8sHu7MnmAQS6$zfHrHAKfwHlVp4C z!*K@G8{SRi*oaM&eAEmgCSk-;#5&@eBs>VV9%ISJSi;t;R4T+&^ZS9o!G&)Y+G}wK z$W}}>k);ZsS*1ucl7rtruZB~oqZW%#_y|87+?gA?^Qhzy##KwqE($9N!b&oZjcd(<#J2-X zZa}hvtYnn4B+6L@as-9g)~rCJbl`U0d!P9fV!>piH`q!VgfFsDWXkR@$y{pQL)czL89wa+GEI_F(2!4=pocx~Z9Wh#d z8KvL$W2~VAK3z(3zJ>>Q-1k6=;L_;GH#&Aj@RvUoGrnG9Hue8;vJ+%4kX{5HmTG`{ z;NnW;@G}^Bwv>J0Gz!^SLf6!(+ zxnxtnuz!o`qF4uY?f^;7PVZ2XfDj28$0pbDSzbfK)!onpw9ZWjV|AI;N+Amci?~@O53V z`V`sp=ueBb$ei;KjmDBj<6)d2Y&yoVh94bye>Lv$Qw;eyS(}hn2@isoy=}?gw#09w z9;+3KYjfqW?Rw4ORgf(s7WxKHszBIG`4)V>1vXQXdZHMN#uxm^?b!GZ9etxsew=gJ zL-(==_A*7*(e#?HUpp4nLuD9g{>gU<4?;L%9Nu)PREfL(>z*zJ=RD0F)wycoOVZ#$ zKq!(hjty(Y4(qIP-M)@mTop+zj(3qA?}F@X zJwC>mX~dYp=xpc?<{Y7 zXE_2kMOcSwmFU0@?avBKYP}B0eZ-bpaC!k@Ee}}o2ZZ?XUgfQ5N$xApznZK26!wuw zc5k|gEZqb{qDa<~#t&zUF+l+zpfi-{JdTgLfl&U~YH6?)KRPkYRy!{X)Cdv2>NciO ze`?-6-s#_WF;6TspIBg26xry%bqU#+leW%D!95~ND&Y%P6v=?dCrIH z?uFbQGVlx&S%wL$lj45^uWy-Dv;1lbnoXq1myfrekMLz2imX{z*EHi5@#zq|Nc~YI z-e!PcM2usiN8bFUH1Wy_h>9PHsdY1|70#d(nV7rnZ%0C1EHQ9}@+kWyZnH zC=$hV?$(vdrv{|uL1_&=*jBrFSGyqyQ)Eh8dbNzqUYif4HDnpL;35Om50`vMJVF2G zBBQW+*!94UZy}va^7or~XamAQ{mF2}6X6%4?x51fuu}Nl0Y#=V{YIyZuemu;d5O$TG~Qu?upz64E2@U$ zQP*unjyN}3dIn10r0$ zD_W`zLQ3=42LB_axu$wWLcidXkmnTSKi}2`$4laq!p$V%!WZ-?k`+Rdc5C>tyO}%aCF7 z`a*0sb+5jjysszD85EgVu||1q$dqB|Uj!LT6n>Qpf(bK@^)dKM$ozozGoeuY5zZq= z%}0(XxKm^b7s=Z0zvB|>f^XsxldLt7)tVrIp-7a`1g6ca*P|pmG2|HPR-5qhs!4EH z_?K{a$gcK8G^6YugH`s9%ZAn*k{QO@%VO;@7>YvRy{BLFF?<1nEurH)(^-YBBqi1QHckkpujk!kg8wBGnPhW{;7nu zDz3uMw8*dH3q0BvctDsU8^7E50S>cXYP#ZSJaNMfi}{Adu=g@^zRVnT?f+ux`Eg&Z zKU=ql!dmKNa@?$P+z_fMGKCL)M;Yn)dqH6;QMhYXyIr%e+!TNP?CPnL0pquv^M>R} z;^R{AQWk_MWgMz}@>((3eitx(=-;zfp!ongo_Y_RdJi1iD6;1D15=)DXx#*{pJwDE zTm^1M1#Z}w6q(qZt})|J?@oi5_(7a%8=Y$5gE$nK*c-R0Mej|Hx~g+mN!b1ABKhf} zhO;+8VI5(G+)@82VKmz{usUwovS8>7=yeTganjvtb@fN7gv9+I)|2z(+|Es^w4=IeCMAcYq_0D?2`dA zpSUTw24V@VrT7|1sqhquah&|PB14RJlVek!Eh&8mrQ!j8hlTMD;Q&vODgEc5dboeQ zRc9Pyh#`jUlPW-PdyM1cKI%Wkbt$gMoU~SHa%W90g|171BVXVMgP_QiD)sK38DRQ5 zls+O${TNFP^2FPh;fiA6lQz2)J4MI8T6J_y>zO%Fd6V9b?)1>y>7j?m@&uX6scRN( z_geo4ROS+ug)fwhK|PTJiyU6R{6CDn2UJwa6E8f>jKpE^Dqwa2iGrX=5D;@(6)@+V za}K+@y9SbE!9Y?J42TFSA}C@26iF(GiUC9cQ4A~e=w%pS{%y*6bno6RS-T`U8$=shl4kQfAcL!ShB-u(^M4uke)nUwAZ|74@F8b zD^@9DpVr;W>t!{0Z=)NYU^iR-v43d^+h=lT0ot`F^(N#95Kr%WE zEJcgHyoJwWOfh2{c104lc!Gj8+|gw0TzY`8tq1(_!6=am@7<@#krjrkdmcCHY>hZu zYR!f?Xom2o#uPK5|Gpa?7~I_eLIcV4z7#Ft0O0dA<$O(XgCSq-e!HP$?A%G|f8^es ze%5NDdcx}qRR9gG;t3+@GwR z0bj%%06TF;A=FRlh_Hd#G|^?&pmIkP|Cp$(h<@UTewefr^D1i*^z+jvgZC_|+Xk5r z@qggD48^swP(Jxi;CL=@Jhm^fDlwAI#G$o%S;jD@Uhd%CO(xF$WC;hDhO9aQg(Xa- zQ0URdRn7M2T_eElO}>46nOGYD-#w!cT93zTf_jl%oKw3-lWny(t+72J+g&dksh15# z9>t`m$X(D~_U_k|CT5^nhsbA*vel2Wh2o-^^=QOCALqTxU!(AF(yW_5#Cm{%@Gb}x zGW9Bb5MD*0R5!?s3o?Uw`MbZS zZS8c|t-cw&Im8Kds7%5E@Ff@}Qi+j83yOYhvDJj7BYWH6)+hP8jW*&&-W^0S|8MCxRfbn5v1F*zp7KT^YrMa(4%+?mv?Q)^M7u zCC^qhkB^t3n6Vv;(I~ll|2`VjNIq4-K?M!~jlw9AN|REfFb8tKM|~OL^w>s2R7nQa zc`NC8D-=#K-%F9y$>SZlvd=Q@k6>&iQ|qU$^rtR%K@^kbkYsQfM*qfiO|L=m1!Uno zS%+75>Ua;rb$#x-K7ZPx>?K&4nf?_6U5gcMaimJssh@@1&jM=##jHhtG;H|et&K9+ zKG6)baSobs4q&60v0YX;>gw&U2{z#Zc11sVML&ESiW!^clAlVm?+pXn4;nUi#98%- zvljM!1T(fxf8{71cXzQxCN|PBG5KN+098_B#no8BsdrR0To}Yp^q(v(u%2y;=jlkB zOKQbp0Aw{yxxw|^NAvf`y}B2 zj%c$$!M~$?SLjEX(}|p;vtqzqOSlh~BFkwhe@lo_Z6`*r=&XU&(b=eN0zIsQ2k=-8 z?{&v7p;&Ei1sn{|v#EpJSEOA(>%|-ZeUPKi<>;di4k;fH>ToNt-vm1!%>innmqeM> z^^n)~z>-5TlepTyb?}o`;{iAyAZ2^6?CHG{YMf$Gmn*U)#bX*C`mj}!#1pIHmCXle zhz^ta`@=^1!v@O;#r()Drv~MDalfV=K7+tmL)Q2YI?@mP-5-ic$z&5|X8Z1_+wL(a zJC6vAdnxV;z*d@32pmmGVfWH|J&r*eYp&tNWn#?t>taV#em^@$>Vms_u5Y zT~6G-w`}FNY@xX*W^5a8-g}aoZv?i-bV)3**DSEdHj!e+HXwG~_Nw=Lz!pO1*b@`^ z6BEpEiW!^Yi9eQoTelZ%pQr`9zf3_BfU(Ia#wvPhI_!~SSb-ST)=;|k@Q}t{!zU=bkZAQsy3$9y-A6G$c!D+V@oA)0 z-99TRpMGYiCi+H95KkB$fN?m55hylv^Budaw?0sZ3OpeSu>6vQ0}Mdga8vG{DPs74 zU#^q{U~M<{YP~=Qeh8~+4RN8mO)xA z{N+`OnaHZ(vz<=HI6$N;5gCN|X#n^b)%FvWoT#7eWHQuVO>~Extc4njLyhr?C}w>$ za*Xa6wQ-YCbSRxOL4)*y2H~qy%!+;#pEqp%%qd_y){A7A^mf$tcEsSNn6bq@iCiDv z`ZsErN@|#d#QOk+bL=P{+X zYD#ZxStw>~w^z@+<58G~vcHqE)9y+*037B=Ex4l=$iuCE`HKr!u-cPvC)I#^w^3L0EeJ)%d&f9RMPz9Q!_r;mfQ-(e?1Mf*P zh+iC$v5ZipqL3W(@=k);rt9W zEFxp9>YIWLfb9vRkf~HHj@{NaG2eZ!=EXooQ6TBYFc+mT7pOmqSpO6u|*HXHd z4{oNo&4{&4Np^j9sTD2xK_=iQs44&!?+6Pn!UC83f2*n=PG2s3sPEv2&>_-}LkFZB z0J`FW3wOZzv>Y#Fvpe$B&8e-5q#0lk}C5!02 z9{TtA4CNHF@->{deNQXf0Ey{DVv46k8(<5KCQ!(GqUJAr#~rP1CehEgJK|s zuFE|;%rJ`C7s|S|wU?uE6pFq;cZ5*Yk>uDNzl37NC;k(^t=u3M0`F5l%UgTRxAv$d z#Z2JS6x9PEtxq5@hX~vaF#rdgE(#PAn6R{|ox}7O;4CIz=z@{>f)VBy#r$V~K{mo? zlSj|pqBjUpp=9{pdn)b-z@g!jQ5~O*LZCMP#@opKTKn3I4g?zx*|J~|c#Fvb5qeP~ z1HkyqGnM6;A_VP*N~#b+GtPQ^h=t>jLBH&~i~915ynRP8YtPR|wyJTOQ^1x>U0X*T zI~?WX9VupP(~rEJJ=%2%O1?pAd9n#ly)^N6Nf`ydtZK91VHwfAZ+dFWZg3})4_*@} zQ3pVmGfJd#To$27V{DS6-;d6W_eB+i2OZN)JErkw8^x>&JKWr*qx1X*AyAq0=VJ@; zV+;5mDdzigrAQ=F?>KJPkf{BGG(_hJSAmnXzzGFYOuh|y$D~Z#{z=B<2uO1yc5NWO z9soWtMzQbcr4X65srdmK(?mE^b0snWy6BFD?2ZNQm!zxR5=Ld2mE*R*l^>%ig7-11 zzdWixnnE#aN{^I*CEHe(K;#F~n;)Jb!Ot^Z@B5G8{Kp^QN)Lqx^)Rm=zszdvNuYoP8+z04ciaxB>^j1Y;D`fa-q1 z1rQQ$;I+u=2!#4|AZcP7k4n@480U;)f;V2)o%MR&F|fMolWd_W4%#WaJA-1z7B|GG zpnq)~*n}XM(~ccZ^Fc5aGq%x7cJ`h*HWO@b>EiU|i-H;e_64ID>-oMnr}i3GjuyQl zv!P{ix0b~ymty46RL&REr@hZ~PRdkTp)dre3Pe%ge=q3*u!0{`pzvO~Ql^3^L;Hh< z$mM#UF+VTKhp363lc9dgNPNpk4I2r9S+~zywRV)Zi`Ec?Ine#;DSORRybG6NR>=|J zKOavX+YLpZAVq(~<6Hn3R<7opt2u7Wzg8&~rnlJ9@1>EAE(*>f%lGqs;^+Mk$VD+L z*vaLhs=*Q6AsV6sPpC*7lmSwk`5BGK7q`~Mi=c&ra97*8vhXRn!Ok42ASR>6jc zPmt%SKPu=>mZw|TincjZ5egS|X&8Yvmez9=*&a+xB;QmN7aKjmi9$*9F(9ss^F1Fp;f z7QtzylY;xxZ&r$Z@4#;mnM=2Ldj@Oo8O#q3f|R$$8SWwJ_7KJS@THbR5*o51Mdkoa}@V5^sW^4_EJu8e=-B5Nm*%>@R^a}uo zpr6LeKJka3uT)431w(Y+wIK@A00(TZcSf;D zrB?Ne6#2E_ABztEx~gH2H>w(}Pn?k-Z52QAu~`(es$Owgxj#SYFxUcUe8p$m4xf3S zCB=+w(gJ%e(@ob=ZZgrG0r0;7&~iq#)twzfHgxSYqy*gIq?U(HDsTY!#~9W2Cg|w( z`Ik~xl!7~i_7m>T&;}SPsCaJu*~&WGJj8KBRg2sb1)>{R^_LDD5`}?;En% zeB7tN0r1Td`f>?<@y*`L-YIS--|YSfXQvLm9ET(Dj-G2IJ7^|5K&w#9I<1qIVNK)X z;Sd=_s(KSaT>$8_x4pTyy$wZO9;rQSH;;&1;<~EpOX%SKW{jKq;{rP+7{On9=+U9yp0;@_j8 zm~YD=jnn+AO4`c0O37=jM*MQQKC?7>#=Bf8W@Ya@TGIH~bOhMq=viNSyhIIvW;2Sh zUO94MFt>dgs#!?9JTDP;-WnRVu~VgK)IP>KC?tgx`${-BXRpOBdVfc1<~ zjMY1>(6D;QMX*NblO>{VpuBD%WKzu7E|>&7m>SZEs)mrN?zu1F00Xf`2vpnjqxKO7 zhw`qdjD$ywe$s39n%C@M5K+v84n2_cJTFOWB-F(J(Ie)s;wxlBn)bcXY1J+Za7W++ z;)D(n&H&7&NCPgCw+_B2RSSLf=;q*Z(Iq=npn>ibt{bRdH^5GTVpf3U!COsq$$Ol41BM}t!i)7}T~4V=DYD#v0f17IRBigAwp zqPbS3`UuLuLNst|DIQrY20P*SlVZY0o*&!&d|AIf%hFML0qOiBbGsdxiy%OX+gihFcX0!3 zP9Zq`Nj+l_7XyGL!>G3PJb(3{u%YV<(f*%A?S-KIfRX4`fnx3Nk#um%eDzX%(w}rp zU$9lVU<>yp#q5)McZoC^w&fj)KTF0`>PGFMZFoE-$+G6 zvn1^S7*EG6@Q3k~qn6c~`7I5`Zo66<^5w&UEyTzsk!{AId-%Zv+8Cq&;PRQ z@f5HX(rKD+ubFQTJxMWR>%ZLWg30q)DET?nym)%9rINp1j$cBx-QPGi>6Se?Iv+xV zspGoDR9<2VW0GPfblSXii=|~N!S;e9dZ&J%di_AmJc=3HYvY&&2Kl*QtDsd(wAW1J zeQFdlwjGDg-1#``HQ$xwtKWy#1z^ynm~$!SNTwC3a*Vl_dQ6)m-%vIR*MrDM+U=## z8!!m|H-Tb9?q;cC)%4+SQTTqkL-*6~=Ep}IQp^g^S+l?72VQEp! z*m|oR^9)|PXf$3~B%k~3Pq7$)ufix+?ro0&26tVTjn)voBdVs}R9er!2SYKxd}Y%2 zVB+3wmJXS}1tssJ#+&zm4&DQ>ouinQJaxtQ+tX$p1l#@gY~u#@ z2=B2jVl>X!h;iMzUm^owlzSM%bsJ6JXpv*NECs}}!r@G018sZkZ{pc%`% zsVHV_>7KnViFM1tR!ZHrMRxKcI}BQi8Qa3W)1oyeR)H;n8Xv(9n!yg}8j2a)mJ(71*_5Bvucu~wmu77pvR^$%TG0@T^`Dwb2G@ZXwO)(h`Bm`60 zU-V zi`k!eEtWK;u9vv37q}?qyJipX!!OZVxUb>L@IMhHKzi^XZWjWe4|DaoTt4_JNO`}o ztErcVDP>(9g_4B~#Gei1pAAq!ido5j{F~|YZ1`l99749>A8f=Q_%J$(`I0a5B_CO| zvfg&s6i6$f%E7h2s%w8J2a1_ARnv+Hx1N8axh+K1y!Djm0fs;q3KX0PN-u>N#-yzB4R%94!5u?Z z>T0Bd1E6q5wKXYbYHjk`_;)0#aDdMINQVxQ{N{{eR)w=yLkFjL-a_{jk`HqyULpoy z)G~_AsQ`shH!gKk82j5Xju-0U$dlptB@`2yA$vG3vqTJ5VZT+_Bvu2U0~p0vC-%uP zdoj;wERvxTi~2gU%mAR~8PzsW%pj-0B~z&n1PgDGhZ$*x@o$k+%!JP2;>;7h=0a#N z>8YV_Bbm^dW?#e6RST8c{%|w{20~tXrib|qdtGn56JZNRv3j_yZLbOrZ$rbkFG(_*o?!Zk?>ZXUKj$%?aae(XeZ12#?VJIY4k*OZzsn7|4 zT?C_$K0x+HI4x66oaLpqY2G;OPKeZcU2#31Q;TBOB83yS)z{mtgUnDeMX%v_7=Y5_ zUATA`K9)l@TG($#^(>kjuzV|c-H1u`%3mS_!0u%fQVl3S7cMmAWEVcqow8%xFYEN2 zf&82SJ}JfQ!^eI}J)$?s6^&0IYTZ{?>Z=RQNinG=*}|;v_;2>i7B3WDO1l2rSqTTg zm}eAntt&qhlxOX>fe+K7Gr^rl441obVgd%hFE(EGaXf;-4#)z99m2+iGr}##6r-aa zlV$hm7X>kZgB>kUth0I)c8O6Be}^W0r{npGk^G902G%QrS(BdIPd7BMP#LcwdO(`= zv!C>5KQx?TUL^}}l4@O!KK!-2+4x_VDN+sPsfJL>6f=1#1N+|by)+Q=3dl(QVI}=x zg^5WqsoZ`3p7+cD`gC-7##$&;;Uvm&KW#sH`v1U$O|J;E~-&3V569^xw^$?l`eG$ zn{ZC~)JXo+2%3Xp#`f>yRbehCg248a78>+bK@NZ?hEa_5zvkAz?!0`8ZuB6ZB}GS? z!mAjHNjDNRY`D_Wx?ufEh|JO;*Ij*WRebp^D8)=%Uz3u4*&*GN(*zh0=jWZeFeF}5xgv#PFdcoE;%Z>tkRJxTF5ZKOACFn}oL z2c)mYG2T(OXW{gO%85~sCs;f0_2uvNF&imn@*Fd_Y{|YK1GbBFyOw6Jna2C_C}wQ> z8?IIT>6VSQydiB#_$rnGu$<-T%kuP*HYY;uh;SgjcyVFjTFoMeyh2x>FbB;r2aGd{ znaH$+^{-VHCaW(b%5&r(LdG8{$?_h5DYSU2xA{ z^PWBWlwwxju$MP`eY*P*J?~G(T%nG%kTRI6cI)P%C*y|y>#QLv zAz$;juJpJr4$>*+=aKN>sJ^Fd+Vl{Q-@WO5P(clV-eeRj-Cu9xKM(eLg0-GHyei0eep5+ z@hDlQl5@oz07o_%kqR6Dhc;fSo`Nwk$#`cFSN<54d`JUKPFr?5Z3(NCVphq;vb*WC zKNmshT~c)RS}uDnGzi5al>nKaA`Nss=2X!%YH2xoCyn$@sID|r7jg6yxA{0rOE+fw z{oTZiB#PS$Hy0e?DsFq9J-j`m@DK+QKjU6q8;j%f8pDtZmlsS4%N_f{U8y4AHQ=*UNUVhaRSwed}j83KP8B%|T1Th&9&qMJxm0 z^9Ae6g7uLjAWkJ#(8B-R&bN8Fa~&l5l2-e|tpR}Zmr+dWpAnagw@Knr#duo9GSkjw zrm)y4W>xI@M)_*;#z$a#s(Z3KESN%b^+I!e6p9&JM)&Jooo!1{$6%sUUA+`I0D6#7 zI7n6dBJ5ShgrsUXtQj@|--d8|FX-sK02_cKy*eK0rB9C#XOcH`EH;%Vt-mv6!Y|9D z)k)s!gsDw2EB>v-`)EvGR_>>g0icVd2>*(jx@hJKbQTtWMi~zvi zhfyMxr>ai`Z=lJ)y?gbP7lONpR5ZO#ECZnU8~U;v{MsL?7A&m&d9zx+jC3eR1PG5a24ux9c^#O;yo z&lM~a0L(Q;u~FCFXG7z4ovGkVA`QFWL;pUXAemyuRcbW<#f#dt6Mv<4$+Ya6$={Er zm{n3qzF2*`M-YVNkcn}@RD6MtYo?e9%kLZ5IA*~CaMcroEEZD&fGNQ!#(8{C?3J_c zZ=liDR7r;@bc_$-cd=K;b-X$bhs*r!)?s8|{`>W5q_|%Lq=wL`>!Bdt?ZHQy;g?WM zs()F@-!aY&kb0X)J%Jmb09bIY{W#Zt2q6A_12lX?*rCpbjo_^$EsBi6hChbi^D+u& z@k(*Rf`4Mv_iNJH#))`&g|sZ)Mw)H|)k-n1h5f0idFsrvtT!bcCt-1>Cz5Xmc6`eR ztx(MRbLo_J19c2^C*f%Xq6C|)q)k>B8WfZE5GA;Hi_M-G&J^O@sRj-SQD_gq^2jJA z(pOY`sIc9TNyv;#M80`0<^V9DqQ-JjW08c#UDZ{(faw2jy=zzOd%kdzn&=eiC_fi1 zKNoDcDQ4X{OZu&>+nnX#dP5qWg3k%C$KFDq80Y@8A@od*WBG3014J=n`?vXNjbdsv*xu5cNlz^up7M!?C}wP{0*RY%#VcK8sskJz4*l;lP}-K_c%*t>Kk0M z0>JV@)QWP1Fp8P5Nqv@2v+q1;GET*bHhTjd z25`b*qd+06sO+Jj&4z`%sh&}{5Zu?uBz%S!TmVoQ$H#NW$Bz_s`KH#;PC~At^|Srs zi$VD^@ZKeo&j;cW>p%re!gu|+cm43xd$RInp+EIToA&yvr#qVToVb*V^h8B`Mj(ns zyyqDIIk-|3U6)9o_}A$6G-L!0cd@NTo*Yv#>r+J*Rc-<;@4+eojn;PcOtW z0JiyO$IH%+?W5}^)?8S=o#o=d07MPI23DYufB z^B2)6W}kJO`Nm1d-|hulwJv$1XbmVR*3ng;(dwFe(!Zv=p0%_zni=>7im=h4p7V78JmQfMSDG=k5DVt#H$@Ts~Z zKAw*IXUF7e2o)o25AkLo09FB`+FIZpzZu+oog4%1O!Aqo;^86yIzG{fOLXGHpnjz@ zc-Bx@?=UGAbrlZd3r*yOCQ!u`vwBAS@VsZc@D@aVCf~>HvV;S`++&nTB~9t3u$q3; z%PudDC`YS2Np*v;oB;lWb4#Guh`R7{(CR>oYRGLR6FJjOp&J0oj#0uRVq~i=QCA(6 zUHk*w2Z%aJM;;CUX5S%w?vOq%1s+$55bE&S_QtwqpSS+DP)R-swpKbwOM0o7 z^nxRoV#YRdw)^TCi{hpu9RO93Fb&U_C=A887bw=N7D4wa3SBNhU=_70(v3CK`Gu2W zCNO*UikFQs>1fP7qI61e9}|F`2BYwRn6i(cA>Su>4+{*)LGdM|Ltp-(`SK6!uqb9l zze%>JO%KaM(JyH>iQBf_Zrh@NC}u^U>=`_NasCt1Gvr=FfuX#BPZC8jW3x6m8R0WR zaRy%1C7O7^ji^fB+QpqP|N{H;?%((eze8#DtUe`Hy` zc1VE(Kp8R$SuJHBg$JX$e{Ic+89Eb%3ukY)5Tpmdh-4J2fYXWx%Lk8}1=dR4IR2LI zS?BI&ogtTE#@1=`A6lVxt5DBdr2JSLX{-&b4~lu!kwPC}l6Sd2!oANrRJ4Y4;&EKN z1Hkch#DY6w0ms)pwOnBxdNsn=ujjUH;C({oc`G6(0I>85#>)!$$ce|YTw$X>{^wK| zPHzu*&yWF8bVNZ1FcAGNP$HFjwc2*n3Dxtu!^X}_T+yn-bdWzYl|SQeK~caAj8-aFzUt zz$v8@f;#x4NbT1B?mcG0z$ahzq>l8Y4!rji|Ng3>|INsGYiK+Z7wSl(4j79M@Hx&X z=6f}aSIDLxLW0unjz-Zp$Xu+Nt6jyvr$TYtcW3^2p)G%Yf6B~X=iz1g@-ja2D8;PZ zcQ3CrI&f$f%B2s^oV3+HX$$>MF&pWf+9jRM^!*!Lhlu(qHWwH3PcKo-xOTpsV1K=j zJKB1NEa(?)q!(>4ekkVKP^nG=OxL)^Z;p!bMBRkzTxm55asa*xqgee69~@eo@JBpk z29SP9*OjL8NlYmwCHwP~zXcQ(#jNnf!xsc7 zbgcy2S<050C{Y8TI~m1TYu|K=sv9?A7M$T^LKdBoZ~)AmYe9I8JxGGtld6&;1dN`a zKE%MObriVk$l%SnF6jV3s~FYx>U`+Q81cjrOJ}KzqR6{I4@wj|0x&=r#ede58rR$V zw-=4+d~I#>`c<>=lo}c9mvp3;bTBI@CY?nz*p8W3>K5JHGz%USJ#u2?XRG4J>rIMT zyBsV%PAxa{1lxVOGYE0)5aNiTiXRC?I$v8QU(E&h@GK!58t;N;W-o;~P=I`-q36#(T~IbK#d9$U9! z?z zYs<$$(}$0CqnNSXKiA&Qd-Uho8lrDxzhA2(t<}N70>z}YWWR5k)?2J&(*SWdIWo|i z+!f>ixCR)-M9$-)w-0p@&-tY;<1OUz7EqTIGqyL^I`y*|)NT$&5&0^uxMu-?Lb~0X zyWJZHycd+?#a3jdr{)CB?5`__NWsLt`bD8DKnKn!fns7$8zrR$nrnl#hWZrqzbJG9 z;L9+Iu`WDjlYXOC8#TxxsyOnKSO$R4?6R5c^8da7xkF)WZN^HoIXGD-`>~%^(w|ls z#T1i%BHp0f)!l5hLoHE!3SA>p4CE<%)E338XoId3mTq@miK1i3K&yu50RVxKCR`-{ zI4jAGL3Y(KP(@zwN9$IV35 zjeqBWVpe>}&T~nlibEjsII$-V;K&hx(ZQ&;Ht>_+z6bpDGQsUfX60*Fi5_4OG8PIH zZV)Mli$y+~6&j*}=NI&Ru4OtG$-l|WthJHW+Q3^$F|Xr}(HD>hwm5EGrxJ z-e~gW%W!QB08PWFw$VIKCL8_}^C)93o@yq2bp{#?0Cx$am7^d3v?(QWwhj|*J zSkhOIoTQJOFh?jRGKn+)T5;bF(R;_w`<3eI-4}%}0GL#aVxP3Iyh`RY#R;tCdPIdq zI4VXsqU{tjw)yLFxR_ zGp0>#K0a|j*uK(S;;rrqY5*CIPXvmw=FD7her(-obdVb{0|If*3^2zDm?76nzF-ac&|)TNbA2u3lh=<}%-$K{6Kz?M&!j0^Uf7wq96rcmCID&|mu?^fS>n8CenzfU|^1 z3oi24RS2T)0<#VMdd%Mskzc3^t20)uGX^WgOypR%Q?YZdhd|^TvH*Wwq5X9QbRxw_ zGa*YAHaW|NCMw;rIRVZ*GTgtoNjU(FR7N4cwMv6vu=Ks`8CN$h4&2X(QFjsn!2nEP zMzswMF57HX7r3#WuPluzPjt{sbU*bi&`IXHr>@kKKOv_0_guGK zJT|Pjf6oQTD@C`#>9+E8{tY{dnYi5(_URSv)Lnor9%<2Y-0K3^z}Y2GxTLF;EsW3) zgVs6UUSt8GG1L;Mx7Vzah*Wlh>i_ zk3=25L*4}dtQkhNRfiikJhbVy@;HQErpuwbnYz0fmTiieP-Xw8Z|2D^LZ~-!W7MqG zu2~EFoMODHq554o-5X%nL1%ky*#ZqwIO)l=I?}Ve|CD0Vlf*C{KgZoi7W^F&tH_8; z#N(*|c%>MH$K3FYDm}qZs2Ww(Tbo;mT${9-o@VNvW@tObteUH?EdT1UQhTAAXfLT| zgq}D;4=!Gc**s637u!1MQ&$KRjFlEAd5aVLaTGIQy*FByZoa0o5R;Oulm3`!0BB)G zVWXvVQMk(I@z1o=L;m?2LWQ8TYlsX6U}-E{i z)(q}>9X*WO)(Nk^+`dtpBLQ0h zy?6DjU-xJHQwJ0?HruZuO_Q9sMH-@HGU`t2N>B541;xBgBfJu;aePlwZbOGf*p`sR zGAK|Y17NxIG?sZ9Bg{TdHC7nPTf06~e5_!NvOm)VcHx5z!UsXoQq0O$u-o!H>EX&n zYNBhzqBw$O1>g+dk3g|DJ3Oy{w|eI;2oy5LrX&3V0E&iDOsJQ|Wvc@pJy6d|vclC} z6>|Vv*weTg2Czlk0p1>eiFYAOaLe`Um>G7H_k;Z+SwKpV3KxK}$|&R+RIV3xaes(B zW4}F$1@|ptv7Exg5CDv!RlJ#xh-$WArL4wenYjBQTe>g92thAze$Pcw%3TdVq8!wpL@W7`!U5>Q~^4K^Vs z;7LdAlYCA1K_)7_LXJ!?IP+DrFOiXE%7S%{O;Op zk(mmS!r9wCN3DJQ*&D@7QORSkJ_J1G3NGX2Pe|biqCAb7m6!HaRqX9tEF$y8assVyEYu-E{Rq8f% z$**97WXrC}d@upUtOEa8+#MOcemdCRQN!Yjz2+5rtm_mrww5>lSwGl24{U-*u*p>3 z#CrrOW^5Dx$zHZ)+KMG=qA#S1el}u1oAz*05X^?}%ubbK!Uk-CFu}hXi&u655XUGc zaLdx-JLi6epv{3~@y}b-Id2gfK`|0KDE&v(R;BJg>lz0~LFRs{*pC$}Z~(|;)GwK{ zU%sro7z3GkM7bx|inRe4`+}&#CR|qq*r1ODs;w$49dW!u<#rRe50jPs#6t-OfUWYq5BI$f zqHJy}rL)`JbJeEq*g1PC9vvpr%qv{d9RRn+Nt5m;O@;`2$h?k48ln|H)(%or+zH-H zqGI=c7RvxQC%9rJyJCiD$b8vd!CtziuXIx>Y4=iu_EIAx%~qbq2QO00`fK&luPbu? zas%6YYNvfPR{dy<^@w7|mK?3Wal(K+u-&3LVZ$vug!4WniW%FrT{~(!7`80MZ5g6r z4&eb7z;K)k2^8zlQw~ll3ql>1VK+()w3^T2_5c_ljKXT6Tqvd&Ylok%`uO?prOSS$ zSUhZ^de{VGk78E5WdG^0BjwAM;UWYXp>bByI4dky6qBOKgJ$=4#%ETS{)fWflCOCd zmt+C3(2^{;B;JtCP)ieR_;EW%to13}jiPVRITU8E8D zQLHa5;-CLJ+bIIgaV5jp-A{o7V9S=;mrL!7^IcxUwI^#p`MS~L@+HU7MaPM~^2J8_ zh0nM`F~0`Bq5Jy(T750NQ!{x+vRFpzNTYRNOHoXUCMMdhpN7M#L;qZkL>r{f6Oefm zfYmC}NET_-4bK9rd=n!1bfTBk_xW=tc=r(A1Gq>JfXY5&q<+Q-=LEkm(*O70)d%Zh z_btcSEnQOT>^1A`QB#UpFLBD>uVohbg6$CXiJo%oaLN&;B*lzvU(7(WOsxp83C_FI z=Iu|LW0+IS*sk?$vG>~%g$h=a2&j9HB^&?~H^iI^F~`I`t#VS>V%$EVHrb)%B6yRD zk#KK8=X(p#6pDq>`>s6#uCo_P@6LFVwj6=7WQxDg>+nJk#stNDpNI2D8R6f%I;HN& zKpk`G5ISbBdCVT$Rf<_1!xqmC*kV|Wa(&6F@(8!90gxAOCX4_7`MWx%EsV%^S|Jyu z(&5%)M#jv`w01|+(r9nR+H1!0nUE-EO)IUEd*>9ouh0;kBy;1Ijr0~D zPew7{_xou)nO659zG+`0QF=OQRW{5W0H)hhWBmP(xnrrYVn}$mQ{asvpFZn=R0hB& zxa1}~r*O7n?t5~^t1UfO{&FHG7|Ij)(`AZT1%e+tN0w#Ug6*KL ze`gQiyB@R_#e|RC#T#{a&y&TU9--JfG;`Wd+YUc% zG1)0*#lEq;xGz-t7~+bk%fV9W$tNN9B$yu;LK5QsOE3QwKdyD9ny8Vi7W*(20mERr z3KSb^gX&w{wQClvQWNbaHB7<312BCV#W+)Rloj?3a$hAA@oV){^DkMYC<-9fPOhC&t{rv(6thZhR_*Giv#<`r?ok!@y_eee zUg|Kl2xh__%*ktY=)Q0@VxWjB`uGlco8Ixtg;5B7Ry`!x*MCV@d#%h^z8V`!df1p{ zrAST&Zp~^9Q8v+7M{T4>`NfoC{_EUUPvNs{&1g}tF&g|27(bDw z)S60bO)TceMP&$m`)^~wUM5+!G4Zno-vii5_ImS`j&I|KzlOC zSNsHZ1%SFLHpbuosH;vBr(b@s&j+o!MqBe9Mh5^Nl2NQh?-u%d4p0b%*!#pJzknxL z0QiiIf-;bu6`~5&nsQwy*2hDzaBLmgUmnV5A*GlJ9sf~7b;;2Tum$Updxed*nvJ|a zjAF*N$zgeeo#ggvWbY+I__&k!xD#eK#q4{pTBrEm@xixI!xExTk9tcw1E2sCj5;S6 zA(pUJt+gFe;nr%14$b{hvnab5z4?Q5QmL-Aln)`Lm`EfMr12hQW1sveM+Jo!GOH~e zs`F6C_|fFKVRgaie6+3*Sxk{^I9~8V&Og&aWWV8 zPgfoLR~|UO5l)}AoqX0}Tv3eM8OmRTcW+C-&v^21**$RHAe_Y>5)J^VFAceuhA`|r zmE8r$#{^ru_N%HyYx&c7k`k}URPXP_Kb926WmEbXDwXpWU4#}l(Yw6QZWh< zbILWs)0wA66_{pkaRzre8Mbe{5w7dahhtskRtut?|PS9%EkR{-bA#64FfP(7}eI&)PL$y zY&@`2|&(%@Pnv}3{ZGiEgI$%3P75hymt($z@ImL`^&{8M2 zs=3BsYwbl$oV|m!_728gj$+0p9y+S6hnt(QronbO$V=A#01z91|}<4TTIY z)yAsT#u(`ovl=elzPn<=)O}zRlIFfJmA~MV=2FbqJWtXZ2i0GTpxcj6zwP_YfW{qLLaPp)d}z2GH^PN5+uKD{{~KH)XRtmvycPxkJe`W;2zBhw_~C9X@p zliPbrwSxlNM|KK1a1(3eCLMa4=u07e_5 z5QnH-AxzsjTE_2YSNN=l%Y;<7-cVf6FO?MYVml_o*C%`wWG;nq+9k=}&&m`;~tIv8{mv$;J?O~=u|`6(p&kq;VQ|D zCPs-=E-IfFs=4FU%PCd2UV^)fRMXc-!U5nrxNXGU=G`DKl%5G|L55}6(}g!aq5K@e z`?-ha=N{O=Q_MH%1n)Z-+&ncsH(kB~+X*@;_d96rcfgWCF&ioS6fV8nr_^}^&eO<} z5sU1Y0C<@h)%H%eb<4z%O*1Su;Ds*om2T)rZ}15ZC?;(uE})2Sj<>5{4S>`}(ntBo z;|hRgWmH?G-XU}6n|IE`P}Mqm*!_Vc0N`u78gZ^haI=;wl?cz{m^{+l*j{oCB85Pu0PT> z8vw`n3j^&J25^k0sHRGHt4C_S(GXcQ-I7dJdW%-Ia4-1m{ckMgZ+Lev#jI6_&nM=t zIsO4`0d&RiFj4g|!4{2T#-`@sK3bmm$42bE$cEe67)wU)dgS;j9dRLCPpriDB=rn7v9H z1lG?q<<#B*9rg~ux2Kq~HUDg=SlWNWMm13j`B2yJc>s>ECIpIos3ng>GwhV6Y}61P zCCkxU8|hm#F%Pc$O% z`#|pdK)4tvW^9KS_gy<_&Q^4gFR|l_5Vi?G2Q~KL8j&qr<(W#6;H;Uwt$SjW*dM&^ z#Oe)P*C}uvOiqg7nN|HJrD;ohZVnrFc*1@(`z9Ik=WN91_*A$Q^NmTvXcTQ7yCBWn zI1y|Ii2nF!F8*i^y-6|ane(qF$R;0qfu6}GdZSK9TF2i$q?mA#XvBN_Gy8r>EkpIL zlfK@!u+zSUkVY|r_LV;h=KIMali{7SR5l?DvOO`$n{5@FZ6T6k);IEq9>>)0nrwn! zzX!hr<=l~I17J5X3JalZkFdC%UJ$4?yU7|tg}|gheR&{%!J1+wG-1f$o2&C2!B$J} zaGb{O8GtdyD8}m9qupo8caB`xDRLpc z9>r}tQmd*cX6KFoa6TjQqH%2ofTfpFZO^g7&&~1aopl(c`|9xhd0kh0UAF_ntSy(L zlKRF3MWBNcsFhOV#ML-q-KUs!&I{}0*j|RWz$RQ>J#XIqyg9xN#f)uOYR$B6+tR`2 zsZX2*9s@di48Uxmn6bI_`jE6Fw&P|##d@$7>K10#A!0m$Cx#a$SZ~%4?I9}dftB=u6~+X`gp0TimH#{EJ=SO+np8`* z>2aKL0>H{B)~xZqRn39iHB{7_SOwRD6*K@CyNp7r3^mVoqUSvhwHI}sy8GXH=S&EG zPs5weJ7}KgGqX|5gysdm`PL)*F4%<7p@iP@1m4=Dn6Wv(Sb8ftJ(5)sM&v|{}wtBIxM5L{1BdCRQiWmeD! z6f>bqx^{BeH%)a5bUuBppmw0Vb|7XW#f)v@M`woz-&D6C4<}L2J}4W2vKb{(_f&D0 zh~9L1rXdQ7OTHZwZ36D2M5`Xk$J4|4yq#IohpXv>K=ewL3PG#xo%yO$!#uMsxbIKC z{2`nb0|w!cQ=r(FUnBkWpJP$KE$}~)_7_-53-~WjF+Y0))yb!?mN{2wzUYVI>&U?K zyN>%3*CiNuVP;&I83taeQi`zV1%0(kdDqz*yoqG8zgx|{TaEcq*^8^}g`)>wHE-eQ z@^9k~3J>27Mo&GUXJeNfJ6z)L3sB5@s>g~)t5zKz3$`Cr!97AYLIBheqZq6GkyYyL zjVFRNm!`G~v{eb@^)SVZt>L)Gh(S3A&_k6(vAbgF1pEmDN}yN|b$^?>>7w#sH0BHG zp=(7F82|=$vbikTTn{OpRE`Lyc=d|mldc#X0dGC&q->?&GrAPpa+1>!6;T)>kcDFOxSf2AIX!b;yfK`9)Hb@Vp36Ja8nL&rq@oqZh$alvLo5nHL0Dhw%|t*5Qc>@Bt;OAXcFKMd4=@OjWF zWO$X+-v)2Ry$` zy}CT~FzVP$W}PSE836F$T{n|mH$!rY4Al&22jV%}A-?O=>=p)*RrHI#g{cR?Mx0Sh z?52cQRqp$aL2M$?j;XjE4Zxscl?qpKsyA9tA+R>l(kPMlpi;~#tex2X z&4V7d!S=B|iHi!hQw+94NHfKZ?eASbhf;!~hH|MzQ`6H}qY-`fD?4 z8Bc0?2EnobEc1*Ksg$d{7Ha9V`QN`ZHi@>$MH%!6#Ru7@01(V5R)yV$8;7-|_t=IA z6f$1(O2je%zSz_8vZv#5RQO5tqcFC2Z>Z~juu2!asbmB;Bjg@{u3}VMCtC7f4f|d{ z=?(68d0B!)I*azHy3pY zlLag4ld&>)>77|0cdZ6*95E+u_)9tiV0M%kbuQr#A1&e}x-GRqfga z2N;>Gr;VkjjbRm0OiF*$1KuiSuTs-X9X-*QtF-sM^}BlOW3NRqYs}eyQbs&7^hVJU zr0Dpk5*YwRmzv8;%~5ocTB6`y+5OM9^O}2nz?(>Tui~jG0KR9knJn218mK^)CD<`# z8*_(kwTVXY-)I0(`4*gX&_9H`v0G`h#D1B#i*?se%&bz8l+!(b#M^1H6| zyDn--G2fVn>dl%MIu#phlmkEbqA_8l)xij|0>D?mDApL?7i<3*Y?lqr%Y^gBVTl-k zQN}37nLqngjKPW=)bRv8z50qoegIeljAHeCcSL{b!F7dbdLYq9m+{mF0LxLB0T*U~ z<)~7rLhzF;GVN$w^SBrl_(u9Y4yF=d41%)+idDe1-ty?_o3)Voi0H0^AMx1zM?Nf` zQMf0qlq+=U*kp~smC0Iv;a(BZ^;rib2*u#J83liVN|Ing1e!k{zht=GUvkkAsyN;c z?EHQpx|U+ruzwU5cKvjC)n6K-N@5Zm(Ul(IUl*sC{{TXszJT~SCd0RRp!5f%uKPbp zH~_o_jB5L6ZGz|U0lQCxf;*8osjfd4cLKmBsr>&K`|hYJkFMXt;Yd4&0|&7;dXXlG zpdgmSmMChBE%y3qOpL}DdqFzV1O!n5Q4m2Cq@##pK@b5I5d;+x6bm9&ETG=s%si9u zuKRs=-L=@~xBuAeDbLKFJ$u>&?3x@X>UBf4Txm9SNR`GHoYK4*4cRK%g}>oc8witk z&UK!seO+1hbN{+y$nb8O;p=*m>%@m)NNbk*Fs8#74jt~81g&i}2aSzN3J_dE&UKE| z&3U>1Qd!w?NVif?v-tyFkNiMFMlX#NFR_cSUcyV{Kd;nxRrw1WiJP9F9$S5hNOB)tYJ!c(3+$S z_04#Oo_VifE;?Z@=vNH+w;H7~GjYr)v&}HyR9X64B?SnbigP0M>*{5~Q1^by;!#Ee ztv73lYN>RwgQS>5-Wk%0sv)PRcY1d}ott3?IX7CNSM(%TNQE-|w?bp8{^N4?r@{8wFVTGybKw#iU;mpNjo12s~~ z6pSHPx3O`Le(cDZD02g~Ip31-1Va)zcgQ&m?;7>OIQ+{PH>Y{FvmkwtHB!uN_S_&* zkyloVS5`QB_gKAAsGmiBuH~iuw0Sea-Ly-;GwJ@$1kHmX`7|_w-tyhLs7RIF5DTZ( z_`;yy3j>V53~71r1v}hdTlP?nL#d;v)MEp+#|H428B(bOq_SgHFDMP1T82_Lu=(jR z=kCXx(I6P|Qm1Xt3>)?J9?EfzmbwVnu!DZW9!r747^s>lJc;P-Jx1-?#5c&|YwE0e z!bJs*!y!t6LDCrA!b4 z(&>|XrB8MgUbmqyW`>U6&=?&)XbY;5_J#~33Bpu`b3AdKuOBoAzHx%q{j`s@A5xZq zAjvtLaFMzR1N(w*chh@%kK95I$%T@rNBwYFJ=u89kY_a|Y3j9K&yIxB-7KrOlzUvI zZ*00*_i!U`Y|{P5-rWyqi!6_?_FY>xA6ZSN8K^K6SCA`D81ihsT2yd;##Rq#d`Qhv z%R_N@5VFa+&gST+olWYB;N6h+rDOJ6Z>1g}R2ApoQp=izi^fN}j+O11co2m;uSJ); zV+Zz*9f-l3Aum+fW_{0{%U&U)_vi=`i!ciaN;$_fYqxEbbD!nnt#VN<3nVigUZ zQE`S`p+iS6>k)?zY{gwZwB)xI^}Izka5C(?fzxQ}g8{j_qM$IF?KMny(oJ`QLWW#n z`GULM8!sk9;bmIwXV5}G=xAw^d!-0TF&OWb~rjs=nyG89&jp0V+SSVmBc$ z1A^J&99R4FtyRma?av{4fQcqT6a-(6b6oWP;JY`@r!*r6uc$MUiwlQ92%HC5DuOI= z56DH;0%0(Yy0*OhVV5r3aETCYC2iP|077trbDa+)|J-oN-&}z8yMM(j|8awAYk6Zm8`_9Qxp9Sec+V#sql@uVDu@+lJ3t8!} zkyZ=SS;iz@lcP};PMCTw2MQjWScGeAc#^M!2o&`yE zYM(#1wQs|aL`$`Apk&`bJ-B)lY1{us<`c`m>3zPP)@A!YbIwvb(^BGOGUV#M!))cvzN~Ul9pbf^`aaA8}c<-=N z2?WoMb2u`uUM%c1T{LRvntkookoKn5AqI1P5bB3>B6YG0p1n)-#jG`QL%IESspt)@ zOLy335F#0zNyy&@Ak?OIvhw z?eLQo*^?n0OIu0mVWsXMICz{B_43v5mh9D}vq{@){!6a+{RI^fZ%FTW!^-(vu?UGh7*QdEY5Z5&qZYg z5WC1)VXC7d)e#+lAs2gk_s3mV#$AC}gLWOU({6)p-3B{zAj+#ectyrBmq_fyGzCc67fP}2;F zx9CsyTRd!z{&~qcLx>%xO(%P(ID06*977_84lerTg;n)~4Nf~?G-(xPg(z!+5H9jF z)ATdLs(Y1crSQt)k2!HsTP;0zz+~#v^+1oIDjq{&X&Ca7e6u}yCI53URJPI1>xXzL z2n{j9MiF6yEh%ZTRADcxOM64mMj}=xaJYiXZJ zg7E;sU~`U3rfl`_`>3C}15Zv-o!JhOY!WhNND3apLdMAlT^@(buSR)pvAIr=i%yUW zj2A;*p8UrjBgZ7XM9S{8Z|_0QK$t{xj;E|@v!gJ|({QI;RKh%#I49jWazP?Pt}wyF z>ym7d8N`G|asQz@{$x>{As2fdba>6CUu<^DL>bhbJ&DUUK^RaI%{3FvF`&|WPUx+v zf1Rj*zHWrwP8DIp%%kC|kA`bwWs@S$pQj@3zFN~yNH|D`UZzuRF0Uq`B!)a;>uU?@ zCU5!~VwahP*ga6OdmtuG47r$%EIZ&t^E~7)l=hRmxQ-BnnvO71L>OU1O_b^Z!AHp% zQ>n4<>{6(F%xWgfNjHm}8)3**&Qeusa%Hy=@+EoG_yeRi{|@`rW3 z;zCF+nJK9^m)D!ajx*#chrRjJZK38ts60#uw7a*E%Uk4r`&-{BZheQLgxu5p1GS(! z^CNfN=r{`5_tZ{&3B&o{F!D5V)Zji*gYi(1r_5bN^sZN%mgwQ85yKvpo`Y-{ZDl^5 z$_fxd1&2)(hfT1x^sw3?VVbUHUAF8)`UPZlkKtFcnQgzL=6-V16hod>i`FZt(^9WM zoJ&XNOJ`T&eat`d;MSzKTFbcmZ&l*C56A=)iNVA)zIlAgN~CTr$@MAqML`Uz5pXwl!B ziQkjU{TcGMuI#ueC9`z_a(I&3i)dF#v@6CqhE(c!e~b;%A%Qk(Ny*6JSNhElhbzfI z#9j=RWe-LxZqs-tj10XK(_0$ra-h?b8p|SmNfCMVh#}QU$D0}Eho}7g^&E7*q@HLS zLO38a<5nX@E4gPsLT#_mHY7HoRn_j7Ap4n4UuqsGD?n&Roa?;z-~MV;)bb_eD0?-t zZ5So8X&@E9l;h>!+0>!j?aF85^*ybnr}~noVzmJEk5B;bwu$K&kIib6$!rc^e!b*(_VOc|Sma?a~+YgY< zryn36t2Q9GSez57e^7rfIC`7wj~q1Kxen5G)Ge%9+OujY!eb2KMyOpEv*Xhl10(KSfAjJEz7eQ^zWM};B(Oj=pdGZ$smLduJNrZ4v} z9k@rvY0h!U8iy@Gd#rTb$;5?*Rq~uQ@|2X6&5fN{5-=9WygL z8cO%k+WzJs{zf)GGvo^UC5T=0j^{vOGaD~GhG=<^y~+%^vLE74EHhvK%pKc$=|_n} zLj%F9?hj@7;>d&`umsMuzUrjcj!mCTdFJrp-X%}@A`V+I6WN-gO>FUT87buAq=sqw~{DBJ4{<-+*dANI;B4( z&(op(GM-Zfp-3$@nl1b})eUru<1nv`MQ;kHc>Hq^;H#PTS2Osn40%Q^&d9WjhOC6j zSentKP>BKr>&`jEepGJ>{zAjMM``ls8=zDO5Tu#N(@c;)L$35>o!6s^UVacOV>N%u zSboYFg=fgc5?-&JWwDuv37eoY1C;uLU=KLQMSFhlk=DQG0f?5f^(Q~0-hO0VkRcaq z@E_Bq@=FCulSnJ*t($Up5QbmQ;b4P$hOhuKWl_qp7bfo^eTkO+L6DLHgvq>{t-{R~ zTc7`ZxFKq;%k5v&Iv|@yO_%RCu>u6yVq-1!#!(Cqdge1*#WPzRUdvU>7DlBhr*zlc znQH8bGaxj_C(Xns&9ty=M3FcA?c;9dKbdJtq^L$e^f}OY)Rw?;$z3NFPU?Ty!Ba~V zM$KEbo}`*Y_8C$s8uvK!tTj&Ty3i93bg?;XJ;GxkSXj>SPp~#=-hFZLLKLTwTH;4@ z4IjZnn%P_ZlD)>)LhK=Pkk32mo+pp9G2~)>|GNBlMNK1e_>#5` z4?If_`W_)}oYn^6b+ms^Yv0*zG&gjExfjm;(DqT23*RD_cyydYpHsgj3M zpFQi2Z$9s`0=dj%6_x0un@HwZ40$elC)@SNsqlx`K0_Mbju|MAA!|Aex!Adjw?6rA zs6}C3(fag4eS%P*S*TCYf7Pd5d6w_V$uFSvGh4N9g#!daL*^V;e0zR^YvBZCZ@j@x z8%GS@90eidP-3AdvB0{;8P!~&8|QC}*$`W!>5Y?T2J}o~t6lF_vNxY0S6Nx>oUUrR z3@YFKue+8!)!l{A+@-VumWBN`LfW6U<=YM7?jUp!&UJP_RK2%5-RR*5=|i;cy|8Z& zgi)4rBFzx>U}bhONbT(WlcCzXk>MH^JAL7#`+_|D&X8x=B>eQOnkli~@a?E8a1aaS zpwZYkC2;(s?woq4RJJaS6pby1w22iJZRCm-{8CP&eo$?{V4UoWe3ZAi6hQhV9Y{Yu z#G|4Q$%d>;u8K>pSONc}{y}KeGuBDP2aSs%n@$VniGqPpFwTiI!_~u-*5bBLy#hVo%7y!=UXq5UBLASBdhim7*D~I%LnvXQBnS;<4IVVytRV@*|^7QVx z`kVZ3qtcpL!@cIDdyQPJ!H`$l*vO^Rv+g~BSi61zIT?SzMSj2qlW&Gx?8uKbiT#GX zLE6t~xlZBE3=nE;pS5BinJXr$CkXkp@u@y`_-`#AJe5k#bT*7LXgH=g0>{5YWbBDm zqt`iOOWt{w$CFOFC&>;nhCFdS`?=?yd5wpd5Et}@2L;0T%sDPvtv9Bd|D*X3jc40y zgRJF2B-+Z5i!EL`v36+05{R{F)8k$R7F`R-Wk?LU*v(tFe5V_^`N%}~s6jijtlyDk zXm<>85szBASQKd#p)I=m=Yh%fdA?BS!=^QPrqVp}#tuWS(7~p?cif=MP?$wOcq;bn zfYA3i*Ew!Gt;g@%#I=P`dY3uMp_4U2C!;V7xzbj%EN#uVO~kj!fhdN= z;`x#QUE{zd-p|LCK-(iW*7=)j_?u%~V#u{=#Xau#n{&Mn?mDGIak7~tnM`*X(l6IW zf}E+6FHatZ*P|$x=y(|3h|RQ(p+@d0j7s76T7v5QXU-1k&uTZmh)IoBT zTztWhc3ABl%B%bjOulV>*)RZfv7UUF_+WOLXth$XQvz00!K zE=vq;47pg=uSaYfl~a&*GaWNBa3?wlCcDy7r_$0A_qVH_Qkq1axt}DC8|-8yD9-^p z7(8>3JR?U(7?Lk|ke!2hG%)Do!Kv4wbQk^9ewYe_&@8@~D87(0*o~?W1rzmT`{{|x zMHNu`lvYx-z9gEQ9%V?B3bXd9?@}GIbH#qx+s+CUVyY2B9&TaC3)JUn-_eOW3P0?# zrDITKp|S!5UpCxE5pDxtHeGf~Xp&yj{~oW_r3X}2vS4hei%zHu%Fd9hycyZ5oIhfP zpO&bZT7XsyNvj1MUWO!#yV#u$XL>CvyOHM&eZsDzmqVQO>-B{(d+j zM)d_)iUTY$fndm+?7Z1sW`8`8ih`ujg4Dw?1fj=pPSlH>oAJ`jBA%hyFrB5ghi)S6 zMz-OpX}EUNaEv(&dD?wD4t;n(M0>ZU=os~mnindX7m|KJk)~bV(??rW@MuT(j~aTr z@k$Q;glWd&G-Ej940#?06!%NmbghH7e7K zcJSS>P9OxFIL9kg8f_Bews8Y;Swkzd>YdmCgkh6&BJ~ipU|~JEeZbygo4B2j_M=VY zI{YmV#!k+4_P5ehMSoi-dLgsIu7MJGk|21JoZ}f*`99?0$+#$FIENb62xJ%pFN$+K z!}`CN{jApI2(oaEjuh3adsnZ@Mc6)WL_{U4w-koESD!!SDI`Z7&X3PGQ?i9 zSVh(_dDbutK@7RrmYqFD>hGC?v=7tH{utXkL9o|Hj1@)`_b@zzpp3~MTV-q-R@W7{5cjXh+Mj3H0DPgv5t5nd-CCX6qIcBX}7d|}ANN}Zp7U3%#z#G2VB z@-Wx%Acu7sa}8BRzWPCm3L2wk`x3#k8@m9ecj)GE>XRYaNLfjKdod2UH`K?C8fS`6ETmJK!0TZ((gS zq)kZ|go@-GPhP*MXYufecTk&4tNhsmB?SoWlXGyx)ysvcN7;hU-Ck9Ff#PUGdSEbq zm|pxa#N8NjrLnH<)uV1|1x0B;I` z(04e;)y^6^V9M(O>xn4)=8fj^Mstj747r%AqKl`!sxQP6*kt>olkP|IW<5hLHpz7L z`Ms0UkjXfjNk3!~gqcjbxh&lr&s^oHofaN-F>>~?S-2$!D!mPB$@Yrp=WAe8H>$R*FY zq{>bTj>O`t=ePg8Lpun^E?Ajstq0UvBa;ld%HsMz3J0Hegcx_~jpe(I(fxN*`@=FveX8mr16q{_L@lRW95DML@x{|%+_ ztiC&(bUR3Zi6K`SJ=;>}@wt8frv2Vj{+^`Gkc(Z4uR8u)<*6WSTcB=1M?bBOevo3w zM{a{liQ0!9vV!n(ES=3?wU=BaM-~}UDSBdYS844$gP;;5dXqWH!7e(%F6hz>d7?X# zrmJo2`2q#5qjtF|P@(|AE*DN#6cW4Krv6TO6zv1Dk{JoR2b%=Lgi^cQ)++7^!lZha zQO{jQIN_3|ktJczldM0b_-^OBp^$w-WnbXBIS~A|2rET|)i6=74rxahbGqm}=jNdA z9YdWU>re9#h!gW57|8cliudH9qkoS=&3eWsM4I2gK@(CpXDx&5d-^dON|d!hus?Y=_`~=}J&0`Lhac3vk@a}{Z;;KSCNQWH z*Th$n;o;p_#k;WsM7^%4UsfJW^>%68S>`C)87vpYu=6v1!xVnQ;14t8Ra^1bj?r~f z-5@4BR+v0kJDJ>$#E^@v`}%2s(cd1yQqf^rqTN%v?Vf`2Fyx>8ton|S3q3rMzq7QC z>aijO!W4jWBK51PMZ##G^jdS$^mHFm^8Ypd=dJE3oUIj=y8OQ5w?;_crS_lz_5g$e z<(SKI$nKHH(ni5(O=&p$q5BY(J&3+A*ZJ8iB@K`cETO>hf}Lnn*LCvI*n@}AsEc2z zC#fW(4?|ioI*$&29kTg=wl-A0Wp*$;$r>i;AZU<{%8Y*ub$92ZWm~gqUCxZkWh#kd-5bT+FE< z`OBEK>-HctPMc9EZrKN6+3L8Z?D&7*=Q{sLn;~06tFji4@`2EuPMXV3l9lI& z(g#9SIuDq1Z0rb+J$NRPx{mSpmGnUHvpB~;ex_~vdacXh$Y_azp2UioERUHC$C@F} zX!wNSjsd&(Bk^*Y_@i)T83Y zAXl5pt4TPGAVo_SYL8jAMr7UodO77KYfh+Zf6B4JbR<%%ZP4Y zM!+I7Ou`PDxcD>8Vjq41#*zQegt}iO}La;JT`}xHo+82l5^DrdI zu0p)6wNWKEah+WVxz2(fG4_Q8NIOCNF8IO2>^k0BTH zxc%YIw9n2VxLlHc7as$Oj{%&1h9u2cBYO7jQ;p%3zm~W_-&JjT517};?p`BdGZ}Jy zqq_FpZkPQ7^d(Y@QQ<17AlErCq>Y9?6|_jnXv3KqQ&HB#)CSiWi)%2zX)`40x{=`G zca|T!t(fB%S7+e^A9~29YhWfGVjZ0vfO7f#&3o^ zhuPj6whihy1C>{4iBr%LL73s*Hj~{p!}*4PTVjLVjr{Ga&OxPcK~J=SJlX(G5JRpq zaLVP&mw&$lmFcuF*WHyBASCT+qVObZNr|cng83_2=T^L|;vQ5AF^F@f8s|(=a)w-G z-B!PQb4y>Le$LQ>$2y2(9pL;iB=u83&NV8B5evTTlQA<6iPhy>7nKe?JJSEA2Z8mOr>W?r(?(yPn=&q zCv5DNP%Y67sq?qqIxoLaISNZtxqq<#+0T6Wb`sSkDfS8C2<%G4?~{ODS1sM+oKbq^d&WR z@i>(M!ny(HI-km@J>qIzx-}yVYjE@%1>1>(?J(*}QUgyH{#&y>H&>ul|$fmjCJ$V>$m)bX>KW4`C zo-sosAF`o(o6K3q>f?U3M+%k%1aV$U-_pUM7tlcPIQY z==xqQ(LJiK#6eQx0B?#R?LPE~XKtzQ#nCgWq3#Ux3m=#dcwmm+!;q_67jb%)|Dbw^ z1+bXfhvAwZhQp#V=O*>JUA4k-po~gaAv6v`XW$&RILHnQGul;Ihfn<3zXzn>&@RzX ztSkrNW5(Oa<881ITP`i_B06e_`N+gqGrXjOdWU0dqSL(F1~|Zq2|q)=c`v*59)%z9WcBK#?omHoD{HqEC~c^fB#^1zQIcY#omH1x1ni3)yoO(Q$HwbfCe=+u>z1 z!}0P5wV7Y^BwzGkSsBugPUHQ4P4^9z@|UCBx#-Pk6#a}!`oRh^G!!Qp?ZXw!$(8;M?=gU81m{_bLs5J z1txbOCS3oTY-^Nki)rUBV-9Ej%(zEL{h_z6I8VHX7g#AIBmpg0)ke~b>8Qw z^sHjcSliu@uAyB->?d7xPLiYS40*jaCjWk-WWrNa!V_8vL8t@}vdcMM3AbIG zHc$Jp6$&3RPrhSB_l^-5sTgvF-TIFzfBe8^AFh?6C3=dB7eQztXRQ@yN!yH7j}hXd z?x)61Yx>J>-#-Q{BS1+5gi)V!ThL=k9nIxo`>;ded(j@kj57KWq@op@?X_#wQ8e?=z|N zTv=A_LMRk=XEd8@HJfAR#E>hjeCs*r)9j^Cm`TT~7VOXlp`)KQ$KQYL(0*=n;?-!+ z)sU^CviI7hA#=qcb4(^4NgIR@8I{>v>5%0bBwxllNUW1?EP1JuAy0nSy7h}j zXL&*8L0X$1;5WivYxamrcu6mc>ca+PzB zopSnF>;6962|^p(8-2+eeHcuJv|Ugi(?;uf{?^Kmko!hId6~VW%pS8HhE$Hm?-qnk zxOi!ZC=#PN&0@e?u>yo{bk<05)(G7wSS?W4<1mt_u>XAUK;og!B{eA=t?L-ms( zmc?4eSts4IxK0eI z9CbA^ei_j7j>}$D;9=?!y~7SZ5NyzAYsF`4*q|e7u|f|!cks;Iad#sidzz;0j;S07 zsdEmdS{9=sqGw9_ZC@1r{z5XT9=2HY$W;3gnT<2#1&XRS+0gA|CY1V8r7cT)wk*Zh zW(XUkvXh+;S?q{gOwRLg3?dd<~0GY7R zYd>#0>fCmO5oXBCG;qeyq@pkDk$5y!cy?0Hvy%`6VJK3+qt+-Eg()I&7JJLzP*FNGzb zOt0uD?S)YqG!bDmf#YR5yx)9Ql-|&Ta#1d`M@g=VByv4JL!P|ZkT7 z{GzfB2!1Z-I35wr#xaM}-qk9E{UaTE_gsV7L|h2d(O^=}d#uhn>6 z%!g{eVlTO3k9NY4W|IyEF;8Pp-oL*d85R7^Z$|QOM({To@{C684GLX3Z0|v-sD_sO zILZrxRpJ~k`POrv&5dItp)kHc)RYeR$58A#^RvAo1gTtW;2LoPLR*twod zXBMIgzfg0Pe-yXcA0=@M&f(4#4L4y_+2UxRxU#Jj()qL>`#uqO2Vwb$bDh`hoSgTK zYC3WsMXF^RGxto^-9sXn40)0IwfwxwaN8q%nL0XO3DcK^k@MmVX-26LSrio9H6`K& z3Uq@u&1{pd*(PYh42j7MAePmju*~hcTqEkA-G8ZeHmPLyA48t%k(_c-Z9=~&JQPTs z1AiZ-o*)#3b6AU!HL8f{vvpHzqgQsdcZ!mV4${gD!B%My+)>W)3O&C3{b-ark^zZhFAf@X!XWk@rI06F&a_A z2mLW@*!kc8*ofR#ux|MfJDx!BJvhg6Y#Tj&@Y8u7P@6_AV-SwZfG}p&4^q?*(qr!* zET+qLamRk$=OFil>`f}$d|yccg2CmSNWE5irwh)k)nd)6b?Ulgy;NjEh#~u1YWQ1X zV#JVVpquIl3-trHAeO@p0RR6cgN)|`7bS}JOw(oZbJPsl^&3`x`XBu#&n-on2onO;FY53#c%r_D4^ zo59F2y|J`9Na-_|aVU(HwKcuNobK zPuNl)R9E@!2>g(0{5$M`ooWaP;WFeo%-4>bd?FwT8nda!s#UV8Rj8E)Ls^4iFDxra zJq5>gvA?;>w7)YTd4XCtFWf2xg6GP)&OxKk#qxQFb8}Ik%hVpd3R4z?;A3-+=ir*p z+(Q3^)2O3M^bvf?#2e+Grjn*Z*FZ zmI+=;htG`dk2U5Tl8gLVx5$K%1EFJZj%VTG{N$%evo}C(8nvCbamN%0U*YW!inl*t zv$v;)yX0qT+Ru zf-q&|T<06L=T1Fe@TBz=r1Pk)=eL7*z9)RY`aa>F@bu6>7nM)RLD90cI>;RcfkW_z zmd%hCYt0W^*6g@g1*I`GtNRZr$w1hJ$~jT55RDK?1iOqUf5)afnGdR=^$s(OX^!$V zM`&fpwWhRD7n`FyXzk_agCHhsJw9e6KW2n!2SYCQ zVD?itmx^H!%VQUGhdFA7ky~vTaRk#fnb%I<{-lqF61_En3r`?IoY>vAu&KZ4~9CQ9L$U)c2a!l2|zJ zbo{>>k26j2WM4SvMC$djYM}#d$b2!gSb2S{rsyPH-g;J}+z$k=k8@NreF&xgw*~9= zbqSA^idw0yI|Azt8it$-9F>K++q84I{=%ORBM-6vt6TB!@iNsd$3lN9ISsw;G{1#WA+M&`Rfnp+7B)ax4b9}cS4v_K zJ`U%&!hXBfEx5Gj2`V(5+W2Y*Ni{hp%8;1uG-l)Hyqa+F+11g9acMHO9`6E`Wgyf& z=WsQY#x=owdroO688l!KRuwO?5i8YIkxJ$x40%4wQv&Wi%~=Yicc`5$#zGGWN|ViH z$z;Dyy|hlS;4yoTjk-U5{b4EYJSHQ;T~qO0Q-tFf^7458XK0m~V&`E^Q3Cyx7jgI! z1PjACQl2TluvH%^@oLk^JUwG&~>;0t_k~~O6gdrEp z2oQ~NaK3}I1F8MGi0A7;s58!Wt}~-oOM^O^9z*GFc0s`-Bl#opL<&Q$w7uZBLSL_T zD1Ar^82yAzeqiz$0u~1ECA#nalG2d&`>A z>$pjK7oRwyB|1T!jT}8mjvk4IP^4XeF4rG$c;>rgzfv3qIa>3@_2TXzgg7|Yx#oLs zh>AaYdlsZyXfODBR-yn+z?>KRXFwA~y~w_q6fHU~FZi%*WOnU5yakp-ZA+GeB#YcM z#gO!_PU5 zxkXOrF(hg;nIZakJ@>`q;eW?TMQPMGirb|u2I0$cj@yE!9Rp?_{Np+#kJFt94X(W# zT;akncH1w$%D!`(~H&ORPkq!lk0ons~~#Z{3)Od3Pp zQnnW!|Ld-#Aq1g+3B^HAq$2p#`pOp5yrw9Y8q$&ibs&(|MVEUrSz zcWDE=+6*tFnY@h5Ig$E(S*74*TD0sJey3_%(K6I|+{zq^3KQJL?D7Ap90BJYGY4hF8~N8iF2KI zw?~FF%uXFY`zU5Wv>ETWknATn2QnlLq*Rk$9a#FXdjE#%*++4`Cku{Wa?-s-_VhF4 z<#&#lyW#!VKOmOE!n2i*eJdR?b~5B*zYH#(^rQFMqj(>T)_s*#pDHVif(&^Jwu)P* z8+d0oit?Hk`u0a$2=I}NL7c-vgmkYk5^pJZaxqTCDt z&&z5Th1f=Xi1}ZAmfc4-g$L;o1jB@j>vWIVaK# zP~WYLHy2~HMV`mp`>U*Y3F%KXyL(sn+`AgdGsGk4D%(V-w4!mZxtfXXvdT}W^wV@C zIG`^%ppQ<(kW{*GXmy@p%I^qsBp}>R)8`ie{9jiA(2X~{rw{$CT`WuZXVCm;EdNN3 zATZ>G`enc2f|g0zP+IP3MsJQ(2@1|3_LghEs z-yd1YACbT-L$30~%bB4YrcHs$N>=iB;_iFji815FFXeC zjGodvdI|;uhCH(oZL6*ocN~V8@QC+YJLk9L5pRZEZ2p+Kx0~7%Ar`?lZ$BL_e@afo zGUQ_SdN>}9Xh?#XKU+R}liVPoErztdsjG5)T4D6W?Y)jkMFlkNCR=fnE#@f<`FB~^vf@Krtl2RP zm9%xZVJ8L%t)tys(Qb~5|8_~g38lI4aggiTUxp%s!eNC-GwnzcrDMo5IJ@fR-%}fB zLuEL%ANgg<3J~0b7Ar-I6(Sr(s)fSn`_*XPkpEPzhinryv!5~d0l_A54o4O=iiEjO z;pV!#D_b`n(-bAqQL|{FqG%z!9)_fEMrobU+pjIkSU+#)i+KUaDSs8vSRO*2{RpAR zbGmM3;2pRA=aG6k&1nn{On@->bFOoMqq|+z=*eYGsL&Le*DnSdUkr5Mb5Z0KTC*gq z$XWIlNuOo@M1ZqyfHN!&L!Pv2kz@9-0bl>E%XWhS?FJZL7;>@sSGM+*jQj?%K-Pji zC-?N6jJC#*i|t@48 z$i-ATd}2z{h9n}KMU7Al&K`p>1aPkNVo9B%$!S;i5Gaje&y3!+liwwq85we=kvCP} z`@h@-u_Nq2jOQ?g=P+0+hFomoy}3^fDmFtbn=J?X820xuM1dJ{vGXt94O{6J0I@12 z7HX;yYKm>HF07 z`JPmkfzWWzgeuEGXu1#8?h9^pn}@h`)~J1uK1wGeo|WRBAbja#-}gNBy_Kj}tVWE) z_DGKhTB4(Iqny91J%H>MYtf@`{v$N}M<52lkZ1R7+Xd~c69tKQz>}KOHW*P5TnWzc zRyN_5!F~DY!bC06XFB*4*-MJZy?qR+6kQaoXg@zKaAzSB7COQOWBCQr5g77>dyX6O zdC&8kC`%n}+NbcaJqX>9b2yZ!S}Szg@YP}Bv*)Ui%>bIs7!z@f2_oSPc^0L|UF_e# zeTOW5r9=K>eaU0u{WBz;wVv&$j@dUPyyH%MFFb-r&OnG3gjp)WEV0I3t$tfr zPbj+eu5`{a(ob*BW13x)4h1snUbb@tE^-5)tQI z=PL`p-(MGJW)zTwP#SZfik)b-8uWR<$fr=N0r`$R|#;R7%q7+iJ!;XC}M4};h!#YCzJh@88HLm&HFV#_9M-1IQEN!P_dlDSS~vu zWOvGFkJ`&-9mqfxn`K0q%A?51e1<#&A15xB=FE{E|0i%8K14g51a28}v8URXzdk(D z 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

+A`V`on!%KnchCu~C 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

uDgN!)I`Oe}!X1w5eKmiZLvj_rrhG*N%Oi|N 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 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/monitor.c.3469985774081EC8.idx b/.cache/clangd/index/monitor.c.3469985774081EC8.idx new file mode 100644 index 0000000000000000000000000000000000000000..e85c491674d75d42ebb62ec9a83ff677f0d63193 GIT binary patch literal 13876 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∈}OL~ zxDWh&dJ+9|?EMP|^^%K8Aghs9#_~ly_gg`0eUwfK@t-G~Cyna$Ef<@dN9&8`hafzp ztDLc&{dn7dPl!S?@X55zuiIu+m-GrMB|;co7B@s>nf0Bm!v&^!hhvq9$*elyB{j_aF?B^o)FI%dK zIT?gxn%k2uDp>)R`87m{0zQiF=CfBi-c%j!T}OmO;1lT>x6u9Ddwscm0}<>&u%|C{s`I}wKPB!#>&P@%av)1*##4qe?{{(;IC2t*DfVD%T}&# zBtjeTZFC(=7~gf1`4Br%SS4E}Ef5=a6_ka}8PQD4f5`rj#?zID4flk3CZgFFcwZX7 z-6SEfHqgGAbm@-%JEV2#UGc^zHEufZiGLOFRkX!MC#GtgzBW@7vOvh9$*Xp$HB@ff z-$H~25E|(6-(Fl4(A~*j6fS^pflkKFecFxY_L%*F2!G1{l)6W=b*o)*a@AV1E{n983vt+ZR zbPSCS)%u_{_A@b;0bfQZ)t4Q|PG8&XCJNagWYa)qTD{Y!-?;XLq}zx$lHNcykGI^e z|8?UF@$UqolU8-TwTa%XiG|;6$cM82)*AAw2SS4NOiH$#tqLVO&JK}1aQ1-M0XPTD zj=(u$b^^``^9kTiU_J@lNzBf`Ib(JK&IPk8aITo$fOEs_4xBq?58ym7p91a_W>4Te zF`owRG-fa0yfAwM=Z)D1I3LVsfIEZvEO2Krp9Ah3=JUXv$LtH7FXjutUBK)IoF8U? z;QTQM02hEc5V%0hLBIuJz6jh!%)!6~W4;93CCrzByNo#mxDd=&fV+bEDsWdZUjyzM z=Ig*+#~cb=DCQf$-M}0MTo~q?z}>`r3%FaD!+{IO906Pe=G(yC#vBP;B<3jKqA*7T z7mYavxERc_z{O&Y11=8p9pLU@jt4Fta{_P)m=l3Z#GC|N66R#!k};;9g=b2Cf)$32-HtOMxrJ{0g{Nn9G1G!(0wrIpzxBDlk_9SBbd_ zxGK!AfqRX)8n|lAHNe$iegoVa%x{5vi@6rKTFiC8)nTp&t{!s(a1EH>0rw7bBXEtF zn}BP=+zebZ=J&w8$J_#33+4~NeZc$?xR01yfosLw23#BFPr!Y`+zwnj<__RGFn0pi ziTN9-d;|11ExyB;?=V3={{0p&KEKUxF8L**<{sG|=^IGJ`^LRXG`&T0DF~%>%l}BH z&u?m49pA|YVVC+Y>16CS%zv`&->N@|zopDlI_^6sGlj)U%YP8>6$4gCySMHethdxp zxG#F&2jM=w>*_iA#{wTO>z_n;0Q>`bHu-2|b?2o;z9>|HP(e2!7khWybqJmQ4-v{h zD5Djfbn{6^>!H-EZ%?+j#_xTY{tEvC9zr|7 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/null_joystick.c.3827883193D34A5A.idx b/.cache/clangd/index/null_joystick.c.3827883193D34A5A.idx new file mode 100644 index 0000000000000000000000000000000000000000..bb784a32fcd957326c47e040765c04072f6ea6c0 GIT binary patch literal 1474 zcmX|>eKeDM0LOpJnDG=duft~8%&fdzW|cU|;)EgA+r5<;qew<&Ok8r0w_Ti@^0Fu| zsp~Bj?W#>kx~NGxE+TKYLW<}{H@Ew6&+hM>=RD_p&gc7_@Ar@26X3;UwkQMO&h?6q z3XKa!0syq(CpL~B(WL~yVKe~o;-;XZ(T0vtD=%5iSvwp%?c2CBGQ1hG64Mv*&a_>; zlK34rlV|nJ%W-Y-6MOl@y!yLrkyDp%$ud!6tj)Pcd(~{!%tObzGznMME4LmyCs|DL zW{$Q`_0K4ommDP`YnXhWSOKn} z!1ZH7^*}h6-Zn+>&~A7>ystV>D~`m5wPqtdJB6U*6et>$#n zu{W5Mf0$cq<9cY9^wTG+WPca29t}u#=!zekV6arS_m@CvLXgvMVXS_kR!n>7i8mwH zY66LTh!ZS6Kn)VVpD{q3CEu@=rD?U)*Zh(6X9qtJW^FI-CfW1^rRvQBa#z=@OTSDl zYS5ByeLdf7>x+8v@luqgOD^+NlO3kKVc#Ad5YTLZZz49mP{W+=^Cn6#TTbMbLTe=+OMj zrtNo}C!eX(tMhkJU)k$l$k*lepu!p3?9(ep#t$9G+eECeAe^&#wm74~zC0cim5j8t zmJo(gDjK9svXFSwNJe0ez-=+tigP)jqTJv!#XX$wy*q@{PLZedGWb8cxP4eUnT%ZS zJ80K?(Yxb_p0K@bP35xPur2C#LZ9H_6R^ zxe}6t*F;#;@P%nB6@25v7Ip4q>l3BbsuGVC z(&M6>#F7H*;{gl|C)qtoGUypl_gC)PLiFC zY94*H?0N_o!2%IYBv|0kI07(GQZm31VIgLJee+zDj`yT^&|Z=lj3GAE6ScG({L*85z9p#PUO8_24&x u?37dbBX%f`g&+ZvA`L)D6gP5xyDnBArK+Zm#%$iArK1U9%{8=D^uWJ8S43z4 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/null_joystick.h.7ADCE9E49835732C.idx b/.cache/clangd/index/null_joystick.h.7ADCE9E49835732C.idx new file mode 100644 index 0000000000000000000000000000000000000000..fdf043ecbc825812df3997d93eab36e7557a9f16 GIT binary patch literal 1144 zcmWIYbaN|UVPJ4h@vO*AElC728AO1%xTGla0TTnmb5;h1iaBdTZu{MK5cs-zf0En; z4ULUEL)K1-yVA8vL)6u#;a7**?#C60`tRbBbdKbIW&f2tw~#~RpmLZ{?z5t2XJ&pB z%ioswJ$?Fd_51a)KNZz<*C&40y62nl`dh-XSfb-G zzDoJSkzf3ux`fx)Pckqkf`=VwoTVE3~?Q(dPm&K>M0$(=yesFtt;NZP`yI&r> z_pjPQC`?-U!ISs%>l*qq)|6>25Q;Zbv74?sXSH>KTdtNdfp78Q&Nk;Art3UC{x17yuel$&i;q@0(Yr}k-8Jz;^k`&ZTurO*QzRj@7Y<2&pxvSJ7#dq+k48W@Ug;^ zt)KTgZrx(z_sRH8EsKV}@oo2|3%=i6A=qXyxrNcwM~C%oD#S=KRd2BB1c-I$Tm33w&;~I|ZB5ECZ)81C8_={956FROpp|w7eeN}zL+VArW zOhmUQ-QbYB@JlrD!?rudGT$eLr~8)b{Mx{DWF|xW>s=Z@wnbFrcX`*j_Z$9IF@$7~Y zdsie+=r_}|i;@xDb0_9xX!M#rVMpzg?7rv~SLPz7`TBv5D=7R zl~!QjWM*a%;%D%fsCd;P{k#zm0|!KwK~R=QRv9cUz{}t`kIVJKny_^|44g1&DNZSQ z21#aSHg-OS!tiz5uBQd=;9=l`Ny~7`$T4uTFfst817hMrXTE=Vl81o@CN0M*C(ppi z$^^2Tp(r)2cs)=C=0-+Ih})owVQvEogWUubZtkAFDy+M>jEP53ib0A4?nFTu1{n^R zi(sNaygPf->?lIxx*ZcjqL6loS^w T7lT7pu%h{1RI=)o#S9DpIo856 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/null_monitor.c.34BD3DBD2B22C4F5.idx b/.cache/clangd/index/null_monitor.c.34BD3DBD2B22C4F5.idx new file mode 100644 index 0000000000000000000000000000000000000000..e51e0e929c7ce37ba98f42aa1b2d1fc8a3512a5d GIT binary patch literal 3378 zcmY+G2~<;88pq$Ki4u6omPisp0)!h-+RQ*iHh>F zB#4NNIb|y{i#NPAc{`P8Jq_~XFt54{d{t1V( zK(?Qi9C`k3@}uu#ejK>lJUAot>knQ3bFJ-|o7hp3SfAcj@w~qBRPVjc^Y5Lyj*IR; zPU7sH-+RFRqoL~--8HGte_i!3((__bT6CCI`MPJht9=s>3x-_IeZ!ACbkO4c%Z>Fn z&#*gdch7ohTXCwpg?GDZmh6+*;x7`j2hXP5dt3U`x?hGqWIP>`>>sX4^^sR?SO)tl~uT^r7*rtIE!C@glB*OrNSmV?nJ=TB@&PMI0E*sm+F>t)`tS#!6Y z@c&+LB80KCuJGHK_b@?hU%Gtj=Q^sn{2oQH43=*9-dot67ePrft z+4|YLdRHB=h*)!BeaO<#O4q6FWQV|C^x+}-@y@>L_8-!oY(4n?Ox^H4NoUV{7q@CF z=fvAb(#wn2zgT(Bp{(ZdfSs!>-?HB##^XO(N3*vt(cC$CC&hN_-?yCV?>u=s(c?-? zy>6j%X3CIugG)+cP4>)zruavlem9bKYWLKq!S%t z%O_23Zz%lRgGu^Fb}RG`lUF?3VSPdM^gwFLr>E;%uTR}s-}29_q=>!uvUk_?_g{RS zF?g8J4s_05k}MQ2-5eTbYy0G8x=qt>Ep<|@?ItUy{!sP6eqvYN&=1LPe*Nr^gyxRb z&{kKHemdq!dcUM`Nc!rALS$ehZ*Nk6vokpZutU zPp6Y4RVpfVqTN(Zsbn~B=Vx)R zqbGvF0@QXj{kH1lTqqC1A#HP`PY2NYj(EE%Rj)n6Vq3%)oD#P(Ic8%1g z(Z|c!D_S;pD<7G|bf`-dZeYt3=a`-u}*k;?8w@yqKxt5@1N;Nvd9->6uohaD~!&X6tq%d<^H1v>_NVh18B*)iD@I}lO1 zWG){kC87$*0zQu3Vc(bYKJ$Ijiq2KWky&HwcpEu4JtwjA!8KbGy)WzbnYuutMDK*r zYq&Kw@rw)dzCx8Lv?w(FA2o83)JCw_2xF`Z^v?(zbUQvyL{*qoIO39tC^fLuAi!Kd za3dk1{p1x?j~d|C&>M#0?*7UJ{e8&0oFnJrSSNM0w1*cJ-$Z&POGzL4Vkf0alsbTx ztASe$d~E;b-qvai{4Fq9Rn3=JVhl%u;LV|sSZxIZp8lqWp0)z literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/null_platform.h.7A0422E28E0FB8E5.idx b/.cache/clangd/index/null_platform.h.7A0422E28E0FB8E5.idx new file mode 100644 index 0000000000000000000000000000000000000000..20ffdbe89e243ae212a32f42c069dfbe1292dc3f GIT binary patch literal 12754 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 WEOdI9K>j0EeS`mVKfifQ8}vWUeCWLZ literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/null_window.c.FB322F091A96B762.idx b/.cache/clangd/index/null_window.c.FB322F091A96B762.idx new file mode 100644 index 0000000000000000000000000000000000000000..9eb6b635663f504f6d180da7639c79ae5100ac82 GIT binary patch literal 15686 zcmZ7-2UHZvaypFe!VK<8&N&Mr3I@zMi=udkIbk^UPVvl%APA@+ib_zyQv^>?Pf_H| z;S7ih0&*x~KrxF66bXNN_xJ4V?R)ZGS5;S6S65f)DaQ;MIIw3AhUqtR$npiVmQ2G8 z!x#wvLY6F^YuSonZW=Sp^3>e%Rlh#)Rg`^h*6HzOn$PrKhLrKVe_H6a6MeRo9lba6 z*H$A&`x*}|8SHj!%$IdlAERat-LZhb&P}j8?`IWvEpFM8+BYfI*JkhByKqj%rHhQK zwGFdv+2v1!^|%SokI+p z1LDIRTn-%WK0l=S)r;3pl7c&|(`#M#?(H-(n_W_tS+JhHFs5Z&N4V?rfR&HO9U3 z-|u(iuey7vY`gpR&TD?jUKe*gs3?rBY3E=X{#1J*ViAs7?eU}} z@a^wE%{{iqY55kfaXo@N4cV}@|BB(JE_+rDH{F=5v%@`{9UpVB$L3#mJwNO>@2mN{ zccHK9A28W5E4F5}x>xZk{b2g`;CDVuwWY#5!yvo!ybo?K&$sh^z9^0_OHQg87Pq>% z`{RSn;DgV}TzRuqdAN_wF9W>gKd-Z|y}dgkA+dCJsb%W{0heMc(1LGUx34ue**ncx z|J%u7HoYwqU%NaU{cX#ooa9plg9r8Aa%t^=k*n^Gu9}*$<;biG7maNWF zzAJ7#^6c5v<(ApYhwj_-^x7P|Z&ldc^uTlfLv};#h6Kd?HD|QH(V&XBky{-dLNFx zcA8HA?8K0bZpwZRnL%tnuY}<_*J^Kl^Zy_Z?03Z_;b_;3igVpf`sP2|aABrNz{iW9 z*Y4NlV{K0Bwmlo)WxC4*qvY4hvcmGSFPyLa@vP|At&=zQ*{5ILF6(KVZ%sdJR_?yj zzE=0|UdcAoZpRPJ8+`fmjo(jI{B!%4)nSh&zCG}7tYUPam+z@-izC7_jftrTb~*+Y0<>%9{y?D+u20+e<N&pc z-0qge=byLMOzdRb)v?83YzlLkdbCf(`uD5l0|Y}@4dMURcLpPV=|KWkK%89PTkKKrFZmgl{Ri35*bJoxha z4&#J}i`(yUs57uhz0lY1+UepxV89g5Cqbv5U!LFQL9pS2h30;fE?fHBFJA9kxo~6Z zLGP$5-lgqc#ZOk;O85Wv=J2fX4NJ@F?#F!Tx#YsBx_OnZz}k86(A>6Xe#+@K_GG#D zo0-El_dW9}wmJ5$?Y-goU}$De=!oRf+TG{6uKE_!>s0+GFuL@`y;gr8?`%41=H<+g z?bcIu*S#3kfBxkiPnJyZU$lDIZ=)Qu_pLwL^;2`twC=N?J6VCAt3H4HG-LOJkN-Yi zet7Sw+Pugqu-BYboli0;5$|T_rG4;mGppJ+Xz>8khkPgBus{1B58Avue*HIYXw9FA z{X*`6nI~4RdGOEo*JD1OAK`!h)6FxUuim?vUgUKmQ%;v!E=#f8)hhtB>!FBHI+(Xx z{t~e;$X_8atA2@f^Rhb(KRkeA))HQM zfXySSDFtjPQB6k!k=NA|qk@@~c_TSy4WZnM*saJq1-u08OJL2&on<0rf88T~eJ@-U zC?^ogM9d~)foC&dn+Z>QEK(l)NjKMj$H7q?GmTK@V8a~TAq7N2!${acrS36mE&di~ zup}g9@)(X;uiD5C#O^@ODc}`gUjb*W)i2$utbBj}bRfrssz~=Db}teX`3A6Wh$7o7 z#O1$!kFdJ!dwV>`%p%L5V(}?f5HuX(a3~1c-I7TI>f`P?^5?s+Wr06)%=?PPvB>LD-(Sy}%=s{zV^$K%{fOO9EaEL--~PuU7-zUd=S8;#9228j zwH(RI3F#*w|3pZI8~FcwmA-DANsk8s0%fds-!A%J?`AIUWbc@ib&huz{mL<` z3FRilZbAZO4Pa}4Kq;~9LtZw^<~=>VoMUFHctUnJ6eueJTS+K8v=wEUcy7 z-8&mN<|jfKkLB^$DFrkEc@uDA_udn0zLxvBQVwS zcrEQZY@glOHJW3#sMPor$)A#=`2yr$v=zQ*-M>kT@0M@km@pNkN;_sLpd7H}z>JZ1 zF%|dzrtR&StCFrHaLjzNyvhy*%KL!5Pbj_hMani+=W4Ph^i1TK%_^o}q5LbfO##n< z{28#7TE>W;qmK1F?3Tm7Iih|lL)$4k!{pxg%nM^3d zkUR{zq=4r@{v5bS;J2MFGy4chnqI5-?j2TEKmj$$_uRg0_&RsVxT+*`Z97`NDsbsc|%3q zT#r*66Qx=`8?o7B@9zQop6p!`>jsToV7|t*OCHBWs7PZW8%tFG0I&~;>N^>Vn;)|D zqTjvC0jD`;kBYP-*U=;ukiX3Te|-K|%Q4O8&T-5NB47(*Taa+#4S;PRC+?vq^4ebi zDRg11&UKC%Pbj0YJQ@q`xe>@4iF+(AR4mK(4CQYH4|6=?0+()I%WMEj#)$~YY&*G-`sDVw4ap4H~s*0UD8cBeE0ES-7gWO&B(!2KuPLbmid*6IzpH zK4bnf76TtmD2Zt5WRi-u`SI$7XO<=Dv=QbkYqQLh!iC{F<8`)@VJI*T6^!HmKLH;J zj3c!G8-ejgEx;zAzX^yjOPF#SI^Bj|5*}61wn{J$4b#Waj;>xu3bGuH~(2%ZWim`;!mtAS-Tuoa_- zU|GQXE$|g1P^xgb3_k!<37`pjHbHMK!|-g;0yHA;M&zqy7*1i>jT#0m63FqZD+IcA zYk>kPW7?e5z*av|LclQPm1`j@O}IBMxmks`M1**jU&&i)o?YHcdM^NHo#Y zx~H3%l?lnYbw4*TZ5Q$xt6{DZJuR|cX*a2EY@s!+|?#X=7; zppdN5J`s9~sics6LEGK1otQn5P-}YtwiDwoNm?B)!uDb&OY$I#8_-!yj!4#R@c=rD zsW|aBmT#ep=!8?9XS)ft z6Ei|m>DX*V?qd0q3U(lu9jK#Nl90e{lZ@QOXr2o8BI~`#O{_#nZfvt3xr+&ND#%8r z*~meR)+A~;{)N26P(p&3=}F`uMmCbfnO#JVVrG{LE+c#ywUGeIkxe;r7nAK&P>Jj+ zk%t(`Qo&PX^Ax#@IUfmt=Jm))aw%Gnc?)u)mqM_h4cKA>b{1<9Qg50hVSBL%CB?7T zaqK5n#Hrvq>vWy%Kr3I0AeTg4C(}!Eg(+XZ$!U!~un_DL%g$h9TKir%`_t1jZAMRg=pdbxg>dZdTpw>5YvapU?nLjW8wfWR_3X@G9)F?R|2;QZurf zG>p@*9xXtWZ47#>d{b;r=G&I1tPxmfxh|HrV;&sO&{ijs&xX<+o@s<^%if z_1Y5SM6}x(cQ&Kv@zh3CT zj5Ftq#NyBDo*p(WG07%De(y^5Ukb#Xdup_M?d)>;9=#${6*j+Llr5I%_iJJ*PkpPUTZ3yIt zfZ`A^reX?!OF(f67*jC?Kp{{RY5|IYqF4*?3MgIyV@aTF28w22EQyO*&^-%!OM+Y( zG$@1S63st_22Y{6MDs<+s0dk7ryeN#xmWX_1)a&!?_l{Ingd?fr1QnSG_Nbctg>Cz zg&OChc#EUE`i<#E;7>6BL}Q#i#%|7Qz5Hc&aw7tI1@x1sXM+2L_H=l;u+8cd=kt0% z;iyWWtVClu0^l)}J%-j)+=Kb|GNSmRzGSUkEWb-5-Dl7Ge>Uj-F@Rvgfm1l>M&+Za z2)S13*G7toJsdW*wrlP{GH12zYH>&LE85Baz}*Isn;#4KSl~?0@$KYp)92?T4I(=l z?l9b&Zb29>c3dpF0%xDcpO)_`8A=$RW{pm>*7V`;$uWMZpJCe(1k;H5Mvbys51m_( z>wjE`k0ZgMBV+31c9=FEF16=Th0Np94$Zrlodc;Vs?d4R;UGN zgu0DTAxV^)pl*{Epc(2mYXMrIZi^Nm56SWnFUeT)kt|;ea23g}BAyzzAbJ66Q-BO4 zfLjRPLUIY90_j#Dg(RnGK#B%rD9KnFk)lxx5Q=dqmP=BYFpR^r0BN{Q8a9wP+;oi7 zv0MVkz`7Y&K|Qb_>1kH?G^?P7Lz6#pN#cPl9*9}Fa8l~WX?jx2?$5LNX=Bb9Vq<54 z^;zIfos7riUl+c}w+SGIt$O{nrLJRngiFtoUxEUNVcRL}3?;$Kp`AkqI@DjW%x7$u zvnmGbfpR@?rN*|{H}1~|e;JIG3k>{}e#R0vI>m5`x#XgJ2iD(#qa?Wxg`GlSH!6uR zKLQ#?KywKo9$Lji2T8WS3tH`h4w7ttAGF>F9VOX*3+&qh2UGJJ%lVx=6yPzIs3Z>P z$7wD}KiSR8mxiW}B`S%6vM6Xl*Uc(FRCXb@bs(uFvw?m#u+cJj{TwYo0n{&mHd+R+ zU#JDhL;88hM$1_B^R)n1k^WU=BQeDSWLAKjC4gI~%`Idh0aPHP3S>`>mFEBC_Nu=^ zP@CA8Q;?o@wmgt1pb+zgnmi%r-W(5QNTmw%81s)c31N7Mk6m(5=y;-;4$J3gxKV>d!W`+R4nfqd5O0P0)K~;S62wVRpBhWmp{0Mcx{^Pc$Wesc zi;yo>Cw)X9a;U$NP&ty_TL19WN7MQWbGkTmagi8zSBI|BVK=UuLW1?<{G`Ki2IEX5 zHzCjbV_#B!_C~BahMvLM-RK6F!Ytk3fR8R{Q zwa`EUsE7LX&{*<%(Fk1|p$GMv!m>@!wMh%m3|*W51L)BV`$(p=K-U&6iWb=A$&*Ml;-Zm4@+7haaa)i=@+7hiaodoBW;B9esYpK+8B1P3(h--A6x0I>6h{zu z1SupB9_J8u4k;uK_&QQvM~3wJ6D1@4Dr8J+4gpY&^sAAv)V+B) zgGAPD%5Fvy_cGaVvKeI{VC#WZJ+RlhB8H*ROzTD%hHC-hpk*Ai)3SHVozPCpysgrp zy~LWEVc%vrh#ok7rXfyK{k@nvP5Q7#FzWBa6hmt&Qp`y|1Pi`;2axRmW;Ce~0Hr`y zs#VNAgWNMHR*qCqvWWV_F8dspudH5Ic|xeicn0AdPFAH~QV^(SOHhsIHYQGYR} z7`k18QGX$(n75%rPC2vj3&=XPKvoOPsh^`K1BE%#ufzi3Qu$JIx=9*T32XHiW6Jve z^2gC*=1*8iY@!77CD@5#=*=K=)ZdON1|IXflNodLH+7n>mkru#Wi5I+T7UwmR{+~e z{7xa%E7SrsLS-W~q}vw+X@bfoEkH9=HfsS|pt3~^kcag0P+Q5x%SU?oT7aua?<#65 zxrqhHumG7#0Jo6NEu<#_R3K#qGNdOa2-bj%8jzXR)ii3<0)%3nP^_nQHFd(Y0BP7T z4V%&v5tyc9opjB!ngGba$_#9%m8L6CvxYPyvYJ(LCuF$gB2vZ8P|lFv&Mat{1+64e zU<*=iL1y$Qt9swsj>5VuB6buBWs%T|-doEgThjwENxu^_IK=XYG+B_P{;iRxitUyX zj1Tr{LtR67Y|5d)*pQ_P0ltV?B%`J#48KC=E0jrGegkA0piFYWVTcJsGKqJNLcUR` zr^GvNLcW_&Pb#>;bSv`Nih4-A^A6Nw2O2X!G7*!BWb|`}04PUH zIg&}vvl20tNG5T{PZ9GJ$t2D=8Z*&Yru7!d#ABJ{E%E}(TwrDNTQ+rKs+*?jqoB8D z(@uFAd1Y#`uQ5~JN7~C_%1i=SCC^#0$h@&?%H!`%~ku?!7Is8&sNTs=4z?P zBo$d}1t(=XGNHj~_vHJaL(cA%WVJM4o~9}0{Yth(=XmR`As9bvKSz3?Grv0}rW&1J zL#n^txVJg=pu%u49&ApZp{QAs4enR9f6xu4=GM6!LK>A%SU{HY2+oAp) zyFR!Mw{s0A>(6qYB|gy{dX}QQWmUQg9_$+2iMlrGIf#o>cacy|f@H;rD@Jzo%2v76 z#*7-fGJ>$a$acQS4x-0G&x=T{ZZM%tCVXoyiNaBlDyfYFq*Y{)dyps{T>=Scu!Oobg)XsphLhohxMNX7taq4yr+JXMZdjepkLb0L==>#=y@WP2 z*%AOBq3k2Hp{W$LNwNcVI}2ssHRw_E$tlmH3Hu7nS6~~8dENKP+B?l_V~Anh1^6y7 zr#Uu_A7nfK0PY`POEChV0>~U4o z&P_$Pte9DeyU32(8@9Ki<*G3B^6>Jd!<23ZH_YqbD~XVKC_GFlTo`(Kc#32+qa(7Z zyO5}CqsL_YF=WimR3gE5%zxKdFKtO8bJXofbWTmht)DODPTfo9tY`W4niD!xy7e!; zjH@b48q23?Ff?irZt9jL%8kYef>F09QA~D~LDviR-Txr#oWUk%up7lR4V*o@%kabd z$<1A`<;`u{_`C*nntkFT`@O%7_ z@Ol+yvdd%-%KSs7J!{dbUv?{D#!Tf*X~=&L&7MPh>NW&?4K%FLB(DPCJv4d`t*IXo z0JYGt7FtOF_0Xgq+EVkZ`?m8z{8pVDBHkXB-=h&P|K;}75sQ3On6H@ss?iFKLu9k+ zjxV}ddd&z%-Qh(sMLLb68oSjTBkK$>9bio(OjGixpVF@nKh6vAxw>=7f45Qngke1B z7!SHj00)5X0U)I)0oEl#>)QW+!jyZ^_8t_?LI9LNmlB~5S3^+?ZELkCK0?=zTAe6| zknSNQUF8TeKZ3+Bu>#XlWLGMDq}DLqjCD6->68Slo1g)VO4~m0RwwflWbel@a~$i_ z56YHnZvR%DTzG;U^3Sz**epEY_D$oM3fN zux%(n=5W_yN6#g>M2tdKw~%$EK8)71BtUEjvh6^uB?N$Qd-nos>ehsVRX5~OuC&x6 zN3QO_qZqDzHuSzQOX%Ma?gUUq0Vm3YUOe*HCT+nJ2>oUL;xm*mECaGK&12D$N!|{X z9hRRXJ9vTl7aEhKIXIC*-ML4lIJ;`W?9Xw7&XYMeFn>c6FzaHy%4MT3ULcq{%-3mr zou|iL*JUY7FA_{X?v#%QP;PIWd(Dq)9D9XeqLDHhnbDgczwXc1o#vKZC76vYzfp6M zwz2t(EBe4QAEovEGll_pw=NQDq65+F{1X4FswKr+P1(2SPaG=CskQ1?C3xtRrl@8i6< zLZZ1M%ok~%cxhEe=BPU$>6}kCs~?`W>3o~axrO;#nmIJ{Cv()TkaW)RTi6k z?Pqcb)19V^*@iIO4UBgKD{5Mn`*L^3DQDFY7E@fOh(!^_lZ}$bTe?mEmmBv6j4P@q zjPpR>JTQ!YAQu2J*f9osQa|?;G%hI22>C`x?K;|Zp^2F=bm;Fegbo*GuAO81d{P5( ze$$oHrG;<_Fcki46m>QN{s>YYK_)bS34n7*c@CLSpCSORBctn@nnVCpBa>=mO-n4= zD@?Yf?h~dPqd617sQZE`rWjscbNA+iALL737uPP*uF!F&M{4g=)G&zggKSUmdG%BIj9#`7$g9 zlf|>)47@7fTKwr8|Nu8J9T z`S@Cm{tE+%I_}gWm(eGe96Y+cIS{^?n`c<+_QlJvz-N0$lqt_R=UWj$6Aw{K5t@OZoH)y--7HdWgsKiO=_>>2bpc52+8!PYBdC;r@(CRy|K z)O&g}rR(S3y*v>3a-mUXDg-n<}AN(#uSE3L50Du_?pSM_Xoj(TyGFg5VR ztP^hU&M9dAubW=uqZ_|ViN287@xhaCoTk3*m7eprnd*UQ|N_wKQ}2BSy)nYK1TNxyp> zxSCvE_fA~&soUlEe#^JJ_FMA_`Q?=w#(veMI}@6YzU#Xw{>0^zk_9%KKAOBxVtl|` zBF&q1DtdO1d-9hhU7OFw9gptyy&yA;9TwN%Ic(AbQO?r0<~PmecAOe@YIkBmgV*@l z)w!rk?}<}({d@bKEK7NBTKvt2k)e)`W($%YMdZ5dpKj9bntJ$TMfF0pxq0j-YxP}b z?~NUneoI;rJ-Tmo$5$&?jFF|iza#JPA<>>&gBJVCeuzOw4#%h4I!FG^d~ffQhKqNPigzu{bKSN1uZZBaFE>9_X-6XLG!-+eFs zv0lf8F9oBL<>iV@&9N!h9a9c`_+@?j-EWHQFP)JViR^l6D?hE<_oO%b{SqI|l%UB8 zIfE-!Z3u}y-&580_zlhYBZsFNyq{h2NbHyt6Kdo$)kt-W^ITA4|FOnF^6?gSd0L=R zNo8ZjTXlN#v)*3+_{9hjxAjba!&?U<+{YMHMZ}ZPTQ1! zv7%_?#^$f|^CRt(l=|)GB4_ILC+^K9Qb6eLd|8zZ(YF}odh%AV^=_?Tm zcTK#KU0xUYZ9-XH`ef14Iopi8%B~pYo&U9FTvFKl#-d~Mo=*$y>wV=9>Ykzx_a3jwddvUEg@4|S zn!k5d=;oMbx8iz>R&5y0?H4UQB>eVNRkc$@z?zXRtj(n)6+|q z#@|doHsj0d{zgA+`qOu#+_`bt3yL!@k znf&PUkmnh{3px$^8YH);TfH!ilA_9vV~Waq$Imw0J+yUnXhxl8X;5HjY=ZN;1SX(k z+vz1MVrFFl!!$^ed;eau(vW3b8HSrRe3s*@FMR*J`WP?nys#^z$%ti?SPo``?OuHm zIWMnco-F8uHOq{~aw%d8jhj=L zh@j$Fmhr=lqSrx%Y_9ClaI2D8aFzF*fZFo7XtQ$)*=HWe`QfqyYsYX zCzFq{j5lsHY2+m5S6^fz-xr!$ANeZJu*?`N+q3pgufB*p_wxYjcVsV{S;h&=F`^i$ zs?9*uW*}uO_4KS>85%q1^Cf=P4C80C?#)i?t%6}JSBV6b$c~J`au<={BF&GH;4#lF zZ+_zU^0coISgsfxi(wp@G^5~)yMfk~TA=_O3wVJz0T zJlD{O<>m~ZBjMMx6~tS?lII^l`~%HRAa0`hF_=CE8@~NoWV#knycLPJB5J%!WM7Hg z`1S{p_#mwxLEGqeA_%f|`B5^0r#oyO=NY3dQA(pELK|Podds*zT!agJ+ zPD~C2-X`s7AnTEFxyUvbd6RCgH%gcF)x9$UkGBU2_8>#jkmZ_?powSCibd-yHt#nv zWI205GUheI8x$XqN}fdmyutUHXDtt*f-&%YzV??|k3 zZSHqu{X25z`4JL4LSkYf%RNHYkB~FrI;M5?X6JZQv5fO){jJFoW!x4JZUGD8Su(By zgcUS5g0K-R$TDTzLtr0*HP5RNyBblPj)dt**WTb`ZAHd<}%xXub}@>oj)(+Xd!)|88KrX}$;SJ(_!f?VKNmc4+LI8xw$lyyAC~AHZIa_#%~j>g#9qqEwNo&4^vy${ql09?3(q69p zIR}~LAP3UE^^Ixz^Q`<8!&y%4s~%6{#Rz20zaca z!1E7K^Aq*J#2yGF+>yK?dBTsG3T*N{u($^}A`g8Iemr5C|AIglES!WWskmm5u^VZKSp(dm-QgrGf6`@e8;q!YML-FV@3|^G@lKjcL0n368HmehE(dWr&AULn zi{@$=Q4MCgT!yOw=NfS5Spy?9ye{BcLD&j9_ZM)_fPDte#03Q02E=aQkB5M(LZT{U zL%b8;c1YBQY>0R6QM%;(@m`@T_N6v3Z3DZ1e2jU!)Hf}9dVva`=~Bd$A_F3@IEiA; z(A+Dl-q4ScHA=W`si0{RFonQVx@MCiZjTASg8&AZhc5i&R~hcEn&4= zjUVoq1twXb;MerOZ|}sUF~9i7rHmD@oWIQ9gWr=1kX8Vd&1jHRLuV@;NZP@(+%-+= zSzF|fEouO#2HqmqRC!E%$(1*;Py~)ed^V@h>z|o-=fRu!ZvOZ2%>k1fdXIO4`A&Y1 zP1_bLSA1SO5s!BbOs|16S+S2Ivh1Us|Cxk^iSmiA1cK6QxWxIp$#vDM>1BfH- zSsZ+&tu#MH(x*Ic+Pn7C-mz8Mj{A_qK7v{5<|3vdW>c6H~;&BaZ{lgdR!k*Cbl zf!DlbUKDxDyeU$9sMUN+Uk_i3LZl(K{B=4-HDxqUVbU;43zvpd6yX@575hvEGRxp&_O-sU!zRPVhmXQBTj*>=HtOF|2s@hP#Q$?l z60Qd$^5nHKNw|^b6kt=pgxAwRlm;Vs&HzCMhZ2U2GeGc5&=g5ux3r=UjiwFA|ia*ZHuBwJxSQlYCu>6a&ic7O*uH`hW@D(y!0Y4DWX$= zaxgFFQ-IeqKKGI5fATqhZ42&r11xUPapV@rZh<3t94z-YSp3cFdGn`9R{G^{!^WI~ zQK$G9m&12!#*Z$p+=fSV4W_jdHA+&oGirE_f4UBebW@)Bg?vCe_%Ij|&?`ebG= zNbtCtg@s6 zem&q?&?_v$4Tn-ZG6MTg22I%NY`~MXi6PrZu-tl(tOsk};WvV0Bh4vbnL=-T8knci z=P(nzGr^DVpAFvGH0OeMF3tJiolkQico)*V9lW>GyaT*<&|D3YYOp3A!eWn6)xc<; zH6YROI{6(}6e>Yj$uHdMpIR!}5%rRzjz)(zm*B0>0%aDwLo5n!w|e&HCxN(3jI&Gc zYcPR4MV3oOs$}FxIOOiQWwTeEF2@c30E<6BMg;Av?ZkWhJ8!opm`SXSJ%FbgdT$|X zc#$_XdPn_~AN6py1L8!G5& z@3%v^{;A}Yxcp0o2^$qgoys*JTmvkxYQRY8!I6S~ z_1D&pO^Ruc-38{m_^V<|_n@kNQ|%E092-EG$qTq>48m-hb3vF(b3O?3X)Xj|AiM*+ZZ< zb~Tc%rZ*}bNz;)h8R*$z)&9AM8c$)!SjGkSJw*;C8ijRq*5{ zcXQ@RC09}8Y38Y`tl~nLnHNRgX5JL3UDO;uim!_=MIpu^79{-Ri%&6yDj|m%hf!L% zaX3X0))5YTzewXqN{cd%qNoKNT0luQQu}UUJiym@weJ?jiF^%L>)6JrG-n_-1DW#u zGZC9fa~5K=XwF7#HqAMR&7m3JgA zD3f%g+oCU9G>J?*AMM z*TM8UpB5c~jq6S=a391%9@ypa=ElxhFjG71lGx9djMM&)?gTT8Zde9z!I^z|!pXlu wpz`$cV08B{!+2>s4Sha~nY}>!cP?vFo8jyTv5~}Nq`9S;v4xwd)KJF!H&#sHY5)KL literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/par_shapes.h.7393F928DA3A6201.idx b/.cache/clangd/index/par_shapes.h.7393F928DA3A6201.idx new file mode 100644 index 0000000000000000000000000000000000000000..992d44360f7da4d7939f36ff841fbe2f26b861b3 GIT binary patch literal 31278 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 CZjc!O literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/posix_thread.c.8FB200A08AA28F36.idx b/.cache/clangd/index/posix_thread.c.8FB200A08AA28F36.idx new file mode 100644 index 0000000000000000000000000000000000000000..e1ad9e797d19fd7b9e5e32ca9cef58dc47c78487 GIT binary patch literal 2482 zcmYjSYgAKL7Cvb1CBZAfK%OLo5J>LHLxfBzFw&$$1C5aZ!NvrI1Vb`nL2K{#r4X4Q>(Q4ebWp0GLY z#DRX@)ux`k4TXwD`hN@7t=_h#y{Fl&{HCnz;KZ1$XisIYVzYg8sMhdH>ga{Gx>L3H zxH~!?-#>il63JKP{=X?a%3Meb{$??B+Y8Zc~Hx=dSP6YspQJSkZUo=+Pf`UjO#_PdoaTILP0( zZm+PvRJcEWeX0FojQzwC-@4-dSB`x2-F4k+OL0f`my(@dEqm#2x8J%K^-XM1#Qvj~ zhqmdSUEuq%!d7v2|G;nf%Tmstovb{bQmEv5Y~u|DiG6~ulm%7uSlUlJ7FvGT*U#~v zi(0wK&~mfkuY+6X{`sAjVbNA?8-FBs-=4O9ZR@P?`IVQx-%gFMF;0@hxshyYo}<4* z`P%FGd)^-<{_xfO-)(#$)?eqX6ldwY7rh_MFQEoM6D)O{(6EO@>J3|x54kEXa2EHU zU9hq@Lp>a0`-0xi`o%w*{>6$r{^}LyRQ`j$sqW~F=H(A(N9JB^Ik#hE$^ZiswJCe2f+xIIePyuj z2KQgjl^RaBM_+cymK zS!9-&9w*6hQVcl644_X8qls@f-iUm+sMkdS1)`J?C9(7rNlcNkfWry{Iu)XH%xyjD zZ)sjZ0V$$bI2HvxL2@QY#WW>02~h?gS|XC8sXY`>B8r=E%jo)WqCQ;4sKB#-+%hGW zbx|M=QEY@Qj-DimNivS12v=)f*PMU(I0a;gqUNaO^dpkVDPB z7bqY{lr$nuNOra#AB1ls-G17px9u z#AhTi$QWhh2k!!!5>1dn<|s2CC#GPIEGGe@x3AZ&I=Nw21Phg+gnIO{_pcxA$&DnD01HMiBqPfhg3K&)2(q%QA;`&ch9D2i6GS~=sQxY0 ztI;#0P|wy2u@O?3&(0U(mZ_&&4!yhZX*@Dm%hpOT$+Y>|Gnq9_88axT7wNT3Vfmu` zAljnev14GR*+ih~1yGLnQZSX9Dq>K2bhLBS$kQOKH|YmW)`GjymNS_V0JPGRs-L6_W>$RH2TBMd$j z=v8=C7>Tbfe}2eJEJJsl2lJAd#15S!l@WI(xwMR&SMAkf0fX~a&D%d+FG1Il$;ynt zj!0oKt2hD+T-kWz-lf8srN~lsyqacAOp~RBv}>j$GXV=wFiVn^fX$;|wm4gXEya}} zO9O)gTZ)TE;lQxK;d5JWevrmH?L)obU^`^ErjCiF#rD@0twl9iMOFpgj4T%wg&;fM z9*4J3&?#~%aCQoML>>k9p|Sb>PFr*JdemBKpk^~iv;Yemi{BMbCd6t=8p0?jqhx4g z{rWX0mFE9%NW2SG=wi79I02SM=Lt+U%)VUExlP~MeHayPNwDa!HU({R8)Ql?mKLiR zR3a@=VOe>#~hR;FdT7~iQW13y}b*&!cpJHrY7Pr1r4(dfj|1`kAg;}QO6*& z(j0<{5{p8Hhcn4JmtlI6JV7LTwf~j>?7nymS*O)$=P{(bl)Ps!!iJ(U0|Od|t#?*6 z>vy-EMg6N)Yc-ff!3?tXo$8wXNw0{Uy2*FUu>! zX5n3k9T@PKJwUG<`0a4{ZNxUsGR5Ic{}^n1aO{muVWS0D@x+0C!b+B_FMbq9tt3 VEGmK*$&D7wnH{5!;)jdD{{f&v9ftq_ literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/posix_thread.h.C5A22A3F1C04EBDA.idx b/.cache/clangd/index/posix_thread.h.C5A22A3F1C04EBDA.idx new file mode 100644 index 0000000000000000000000000000000000000000..a127e5dd260cb4ddde29bf1e8cf5c8b78df4c3b1 GIT binary patch literal 898 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

{59M^k!tV|J*f#fi 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 DZXh*c literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/raylib.h.29612B7258BE815F.idx b/.cache/clangd/index/raylib.h.29612B7258BE815F.idx new file mode 100644 index 0000000000000000000000000000000000000000..1d701272354f2eaa6a2542fc8508d86973946ae0 GIT binary patch literal 120656 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

@9WOt)bCbEx8JZanVB7VfyW@XGF` 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

+tTzbZFsio*zbI5D=@ZjcgkVfIQywyy%;`d-L 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 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/raymath.h.2370950AA6487104.idx b/.cache/clangd/index/raymath.h.2370950AA6487104.idx new file mode 100644 index 0000000000000000000000000000000000000000..e8d81c637d3c28041a1968862033c1d683b588f4 GIT binary patch literal 66286 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⩔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 R4UOamCg!HojLmc`{|7ADGw}cb literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/rlImGui.h.38EE9B31246D52A1.idx b/.cache/clangd/index/rlImGui.h.38EE9B31246D52A1.idx new file mode 100644 index 0000000000000000000000000000000000000000..5618253e79f6e4057fdd397d387e61f14e68b8e2 GIT binary patch literal 2784 zcmYk82|QHm8^_;wWE&@j?3A&LWnvOV6v~9ilDRhx{v>Nrwh<~7g?mw1u0+{#jkY_b zWV`;2C`(tCNS2Wzlr>tYaJ$De=iWJ=&&=oip67es_dL(H z5eHTQ0Ho0mBO?5exgY>|833YlU(#QNaEu7^W#5yj9lw;!{=rh3_lkxuipQ5a#cf}B zISJ}H%kE3wwCk^%?o+2AD^=j zrO^Jh_N}^wVvyh3fzXSgj3$e!`p{_2@Cs8aZ=934nM9(`ZDnJRJfHdFdJjhLc8!_P z=jNott}1H`{COh1>S^loz`5nR1~TK+?4`cd{eFQY6S_xscGqIke2W>!wUpz0!O;J8 zj`uOvm#?!fj2^xtSl`E8`K@jfBikFOycWN>bugmzohc+SA zoyF-N+kH{DL-hL;RkTcaD6QkMdfLI@I=_Ps@|$Y>8{-@w9nTKk)}44FMpr+^zsA0853Uo>3T|8sJA!AvwGTT;uv{?dnh*>}_%K(MCt1CM4fiQW#S_b#gkS9y^BC-FIN7+-)}b!Suj0uVk$UnhUa4fX zU2@lA>HlQgRB_XKio!o%(=Szh<6~7#k!5}KC#Zf?0(S8pyDL7w8T6zd3hP#;*0rB% zcH1RkdARh>#=krVB#YFJ^gX`aVySDjl&|&ide-8%*`w{TLju!5MUhL}-?A92b`E_}!##)VFYgpeu~B`y7DHS6%> zLQ#$k8H*b2$%$|GX{Hidx_0qQ(0;D|gD=i=lV4||o$hkdK>D~&b*0E^tK_eA7hjJx z=~P%d#w;jMc3f6?7gN1sY1+54J)q1@)YekbAXq3{epWDbP2d%`gr@!Zbwks~HL{yto^L%obxvK;rITT_$L9*(tgbcic7cblz(p# zZNSlf^|zNtdP%xWwHLWwt>L`40lrZ^Xm}#*ve{F|-tkRd+2>_H<-~0O8Klc9ETr)B+@WZp#p1S+ zxC4sOTLbsK9be(rApm9kI{#un5|~g2D6GaQbCI^uA?roy8!8Ae!jKe5NP$G4 zASJBCMb`T*hzYCjCm~=xhR_H!WuPD?rp^TdOLlzxwZgz00mc}R2??1{6(|q{6}iY* zbZbN_tz{1awqS@o!5&=$fofdfQJ!tuF3Em31ejoeC&5!?WfNI0;Iy>bdO5P$7Xi8$ z5J`wcw~)bWaDhgN*u+oU+CmXP!2mjeuDG&-Di^S;v@C3ONvuGCJ_f`=LL5ZjLSmHy z7YUrCUMR#9su7@vApwK{(#jfgTwu@o@02sj4>}RB0Rw^w!RjjjkqbO&s>q3{x;uz~ zjTlf41pOd7sjRm4Rfb}7sh4)4RgKcg)!&RFxPQj81owq^L*wdFqhE;*IiyX?9!pEPRn2a zFNC1HdK@HU3m|Blv{E1i>)T2jv@_ubtg4l2wF)2ws}>=bL;Z4S{O>HFZL(lPYphK^ z)n9gucj9W%elnpx6PjU8A*h3fEVvyz+Ss(AFUp-V-i!7gJkw9KlNyk~lQ)ZOmf}SL zLbeC?=-;j%7eb~18lR#AI-l|co_s0*1n{X~5X`3{K_s7wgCGv_=@bZ3_;n@(nf$r{ zf&zZcgn-GfSrD-JH5&r8a?c3&VW_X%=&XGGxX33+iHW$}Du~n80oqs;fPVnL``C5> literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/rl_gputex.h.5F186F0D984189E0.idx b/.cache/clangd/index/rl_gputex.h.5F186F0D984189E0.idx new file mode 100644 index 0000000000000000000000000000000000000000..2b83b6599c2a0c6ddde1fc694d5f0f356344cda0 GIT binary patch literal 4204 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 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/rlgl.h.EE8C9BD4F86A9217.idx b/.cache/clangd/index/rlgl.h.EE8C9BD4F86A9217.idx new file mode 100644 index 0000000000000000000000000000000000000000..6269794a7c0cf574cf0d2f8749fca51c695d4918 GIT binary patch literal 31254 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 z zI3SoCjuAo(hf&JqNZ}YjgbEHm-+2Z&h6w!|5X}0<2w{8!f{ET3AvABu^MIpxlRSji z4L+F8jUmN|ThFuI>%GCJQ6y~?zN>`g&H3=;ZtO#--Qa`i+!!HjZa^@D8zY3i4bd=b z8zY3X4G5-cV`Ozyq2>Wv-xuEEcVhWF@dykcLg9uyn6`}}!r6vsn5vDD7EIIzAD){{ zR%gP^1|Lkx#y;dq6A((oo_BYGQ0(dw^-^e%yGiU1_X1ku@9kO z1A=MS7$KZ%XaS~LV}$Um!3T4zF+zydfM7B;MhKG{5X_#&2%$~`g6Y!4r|{I9Im=Im z0@5Oqwg@W|VNnBunbX*Z(53;wRB4P5rZga!9gPt}jfS3LMl?p2ipshdADDXwe7wX` zFJVLpQyP3QK^prIdNla(jA*hOAdG16!9-~6Luk<8gQ?FLA-res!E|Sg5VAA)V1hG7 z2)h}4FsT_MgwYHLCNg8BqWt@USD${wz#HEvR%;aY7P@cG0>TrW$rq3iouSp3-;8|-yBQEn zYQ_kmGy{T}%p?!yF+(2AUB(C@E`tx|D`VuqflY@)N~QO}$CH+NvUGU-kMNiQ!Q5qx z5aKc*n5>Ku!c>Mln4pXiLQe(+vyw4FD9I2F(~vRZ@GT^==JBHYfLMv8R^r|mK%rZ% z+{(Fkm_vfa(qQ4fY@hY@Hkr>qa)^=C=5yhY=B}FuYqLmae42n@w+-1;RB}FWQVwDte42n}y#4{*fNs+*y1SLfxgA$b# z_ZW0fNs+{$Bqc>MgOZgL_Zf6wNs-E+R3*g&20c(xq%kN>N%4?D50w<@3`$p0JZI2z zB}E2@tQ%el@xgl z%2QIjVbB{TMFE2floW*wDpXQ@V9*C8MG=FFloTHs^ifGs%%EZ=MJaCB-=j zIw$$}`(h$NCQ6F)5_DckaY2GEC@IV&$V^FLE3JVFcP*PY*kfoC1k_25+Qe2jx z%Ss9d335ZOnz1k-3085=$QmSIVTg4x-_jI_yI#>HxuobQmFJbPx@f z&S8Yq&2eqx%jGaaisb-#$=AqXWNP-tF1Cv!-f*oJOP>mdVr_?YfAh>uA zBcyN+5L_>Z5mGG&2riN%2riKW1Xspkgw(|Wg3IABLTcfl)wuo*BlVIZG)^|A5RhA9 z=`G=hWl|Ogh#yxHhg}eRLh9YX2bZ~FA5!B62rg~I2q|oX zXtnjX zG{}R?&@e)Z&;Y@;XBZ)sXMo^>GmLcoKIeAXvqDLDfKSDImDXGzu6y3c*TKpuCo)Lr;#+gYJu|6+V%IUqTr);S`5?1D&b8X&kH z4MU_D4G>&_h7nSI1_-V=!w4xigSO!+GmMZLGw{K6Wf&nvW#EHr$uL4H$p8uG3&=1s zAbr}A?R#HUanZ!mhr-MX{P0%0?5VUGR^?Y>=_~Qyo|2L?h=wc8a5Pe82GRJ+GIBvf zD$4-D)nwR*l#)R-TtS8rQa%Oy(?U>?!3Rua8RAvFKBgzSXv>pn$(Sf53Uu%(XM{q(6dM3 zieG>{7E2!s*W9Fp4BCb($FL8n8v_KFi(!Nmivfab#4wWiy=?UxgV09EV=9)K3S&TO z#{j|gV%Ucii$OG8BSxa(0x|HxMPV5EZ%gAgeU$QtdvYS_XOT7rkm-q^i=JN{+yXv+ pVyT}%Qevyf_HF{RL&jSUab*hZs@W-_-L$tMxuQE1V*f+_{SQGGZ`J?+ literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/rmodels.c.E2077C168069643D.idx b/.cache/clangd/index/rmodels.c.E2077C168069643D.idx new file mode 100644 index 0000000000000000000000000000000000000000..93d22eba5330cafbea109fae65c6f88ae3cfc083 GIT binary patch literal 148200 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 z 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 S`T5shjtYPJ@3()v^8Wznjv&DR literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/rprand.h.A9F7B76391CEC0D4.idx b/.cache/clangd/index/rprand.h.A9F7B76391CEC0D4.idx new file mode 100644 index 0000000000000000000000000000000000000000..a3cdbcf91a3b7f58eb931c3dd10c0e3768f63dcf GIT binary patch literal 2838 zcmY*b2~<;88ou}OfDj*qJ>(H&iBuE?0T-5{a-_&oa0hV&1VKiH>aYYs#By{1!zP4H z)C!{50SO6W(J6|^uqe>fmQ5CmCPG25P%L$6?K~itr1zYhcfR+1x&QtrJ3ZXoG?oCc zCDh|YWLQiv4gk=lKG88zhj~f>Owa&0acRi+AIApP>-Iz^HOE^BmmPO)kF8l{kP>XT z{@UK;;4!NQYYg&Ego;YtvzbBr-ZcDD78>r;d%$|Kop3P||Cu<-{-Js7R$aHZBqA-Z zHd7p)?miHwlQ7HWo^c*(aI#dnQ18I_!!KlD%0|>X>wdp*K*{cDNnwFrSb`)svo-2u z)#$b(tnfmK<(kTlmYJk${KmJ=_Sr86et90M`{k+gAC12M>ciPS3GF*xdiF=B(n25e zrZ=Z*yt~}9?n_$St!GB05~n}%90vQ_o_WsvjSx3Hmu5xJp=CL?bP~ zIq$Q)Vda)uwrM)$p3WWzy&#tj2Xg~nZ)dqtUi ztZlyiL;S?K)E5(yzSPohu16(I1$wtv6bJF1j&>&|tg{aH^ZRi;y*-1B(fC#HNc6bn z__^90q_>p?gmwE3Ywh0&2Xk>9MeVz;gU%Rg!3= zVQcx@p?~|F^y?Ie#alZQT@K9Js2$rb9el*73R=5iwC>&Y>Bs4@PmVM_@QO*>ws&YS z{f9elq?ThXQBirearg4OQj_BP-5sTqevR&)y!*zSO#=^h&an*Ov zxxD!{U31p}ujFLMg|>rv4BO`~tqj%gJ6u)&F)?(F^63e6`hkbxHv6lalinAynN6m# zCZV4*89z^+dlojVpE7X5bzazv}AUTOo*NZ&MaTH{rv zL)y_Bd!{$^rT)(|IzBSQ4g$bl`mS*{;>J#OUj|lq3i)z0BEgXf@$&ir%40G zg#`G7l4M|N85ol+ftn?7DPXCns4r&%Rnw8r6HotkfdIyo@nx6u7y6R9>!{727QJJU`|O!q4FpdO#&mq z9I$AZ&PoID#nraz>*fAZ0+>;Puc7kSlo2k2OBq?BOi+SE+K}4o5Y7kzOenz=WKO{q zvIk(PLJcZd5EXVPdPW(5fTpV>FVEMiLxOCFcsrz)+rrswm>>A;Vw{B%o2-LobZWL=P544OxskR}6WymHZPl)>+!mxvCw&MXJ@lF&xqz!C zM{yud0mXxO1(X017EyHlPgg&)cIQ%=>4wJLkShAZSuxw`XsmWE4WpC(gg=$bg+q{I z5FdjKgfBn-F!Q{Fn?ZTGnYLLUy|!w$B+Ex$=PDCa)T;TAfzm)wy`)+S87RuREa+4~ zLwObi7!Y7IIWNR;Ax0pKS{!Gg#+I3!E1+f_Tq-Z17#fS=YE&>%HV?={^d6J7zwA9J zn+YUCc2!tt2o~)Lps4`bBFEWeH8iV+c5*C)rb0zt1kFTpo|MfNGQ>$P{_~Dr*LAAP z+n|0MH0BRz~2+C2sS`iB&E>y%Kh>H|) z7G|A=IibuGWH!dk#yE1EgW)-trXptMDDt@&o~y{`V$57co{!;tMV^l_`HFlVhUY2r zc^ETKkuSjT0!6+E!;AioR}^9EkbibY_h;T}yVO#NUT9^sii}QucU)TBSxb#{1JrGR z1}L=zISv`)PzT}C+STr70`@(nM#Gozr54)4A!LO^_(5;7tH$q=A!;-NX@QFi0hy!f zIlu2@a#FSg(YH~#DB1khTa+!VLL@_5P>DplPsXsxER3CnS)s7mWD%xcgjpa=zd68GbKLptXX-!ZY lVQTkB1kZu!sDsh-Tg`Bhn)?w#hukHII6*k}L(Gr`{tu>Y0*(Lx literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/rshapes.c.F9C87CED8A5C502A.idx b/.cache/clangd/index/rshapes.c.F9C87CED8A5C502A.idx new file mode 100644 index 0000000000000000000000000000000000000000..4529a5a37a22201aafe0ede42a046b7b699ec2ea GIT binary patch literal 58474 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 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/rtext.c.6F870283BFAE90A6.idx b/.cache/clangd/index/rtext.c.6F870283BFAE90A6.idx new file mode 100644 index 0000000000000000000000000000000000000000..0641571816d1de55bc51b4c30ca6857ef350d602 GIT binary patch literal 28470 zcmchfhg%g#*TC=Y-Mw3Hr}wU4L&c6ATVgM<_nuf1dyEB85v4>C1r)HLQbYp^SU^z( z6a)lOQN#i&7(q~q3bt?d-VDsXf53O2_kDuDJ#%*E%$a_6CXO0Dyz^>_Way$%n^rDf zH=mG5BnIIBYuBw=zC~Hicg`{cY{bl>JA)btpWN_jyA9f{#yMSA-pTxOC>Z znd!ggA!b8b}uF9-|cm^xXs|b^*P4vy7weIdp^y&X3VEtYhL+jp3Q}D z$M>I~ZzzPXZ;iI`FzH)$ld#II}v|v|J`9y?6l4g`xS&t zUt#+-W!L-Ef7+D|DIc>V;{fet_hiqayef@P>4IU)826xEPa98v3t#=@(x#F%1*=PX zFAZqi>=*fu_u`&oi?g! zb+UhLQo)pa@e|6nXH0mO)F+oUi^>Ww@tCn_#^`QVfBhDC)4efMee+D!gH9RK@=H^D zOdmRC7c7WIX+98y5;)Zu=H<#>`u-qf6!rc%&(`L z*#&Q}E6#*?);=9oa&@MxUwj-HIj$vZ{J=diE7uO)Wtp-<)8+Q>@@DO%>V5G=)8Y*H zjNC=@1E#LH{B-=%uw9Gykkx7TZjU}RWx`g?&s}b9ESfwbEG)Nw;;N2bEwSMqTarUs zCQfoSU9kA<&gv(3PAYyoyYFzf#1UN_-yZa+&6+aQ@vLLJ-=w|N|E&DA)8~X|f0+ET zbLftoVHqKIwUh7t@+v8#+HlmZ{VQ(GD(PaVT(5fbrNhMs*qlS(?FLMmJMC$&vnw7r zO|p)^T=QpIrxN+NPBR^sJ-7I!^L4k$f!kJ;?wiWG@47KO&gIC(j?ZQ*p8WOt{4X6= z9&1?`asB$5HCKi|q!ea!$4u@?vfJwD>J!P=yE(2;9sKEYW99o6>!l-ZrrxZ+kb0*2 zz@6fT)NfluFAW%IAwRdOb8X-_pC4wkXH!ove4kvfX`r^K>U(m~53fPdUoH%rS~V=F zu}AN@p-qEhW-XpyI{b{%MBMduQ80+ zeP&gR#{l`2g#I}WstIGsCu+~VVQ&jNO}yy#l`^J1cG zS)obYkKC8r*c+EUJx+d6D;9oPd-39vC-1J-+TSJqt$QaM)Z@Er&fdCf+`~R!E~%EM zJD)H6f z#od;A{yez({h-wB>)oere|)J=^QU)@^K;&Ndi@gBjK94T<^1=6?)ww=&Dzc6*A6b} z`sBpab)98XXw{>0p?$Ajb6hjhde1Q5owp3ne;sVLt#I>sMruCqYx=Ozp3_3}_mfpW z+yB|mEN%CvX73#T)coJeR57Ew-e|Az=$@bLXQ435xhy$<%Vo>F3wHTg7Uu_M`?}&; z37wv=T&`ZQ^2o*F%=%xvHYlcdVz5)rS9^8-XLvhm@$d7M6Sw-9G3#u`Z{&<_ZYb+9 zbz|w7WXD=faLTqHGRECCukS&uGVaB^u`hN^$V`6X)vfRSO)2wi22Gy4(0s#U z;@sIyMqW*WwhT*6l+F3Xe3l*^hznk7GWl~3Wmyg^H%-J>?_ShO$NcF39y#7`sVr=K1aerz{*HE{+dmgQi@hTqZH{-TVi)UX)*|;vHMJJa( zwF&kPbNH!XnOAb=gfVF;cEruR#pjdrw|SRQIVXF4J5^D~nm(>sx%me7QkuCn!Pq(H zh3%=KQ6b%4F1;;%(6wj$!ZRK>+`ZyDH>Ul1#?xX%VCDD_#evTSOYi-JPnqC9SXsRH z20thvuxsO(?6U7E|Ei}hp5)Z6dh9Z@?PkU=c79F#>4Hy)Gh;;5h9u8r!*U!w`mDOTt!!LM^-sT-|GJO} zj5r_f8FPBP#c2b{@p%^6kCgNC#u4)mvOihQTZ!EtLJr}L4?q3B-qpmSd;f#O%q}GE zmb@BVPYs#uSS=s@ZeLczl`ba&-Yf_lCD{;Qyr|taxmW1uuuBtb9JYU+L;Q@Saz%;Ztu--B%d!bb9te z_3*+Qdwfr5{wN%#2w%}*x~<=o#g*yf8)oj9wV+Rx^xRofJJqD`iHYmCoVwG;1zWXg zGG5?n@Ym`+nIUWU|M4{|t}ZGu`1;K8vm40CvxueZ<}UQVb$@*RoVcL@2A}&+?vcd% z|BJa_)iliCd)1lUoV|2nr(+unmqiy&SzH+9nV`+OF}J|Ys^%}Zy)TYx7H&WIDmgYO zH?_+@zS5J&j+}j`2pk=@|KU=Z(f1FV<_(b^IwX6(b7@)9>p6Q?o^2d4 z-P5^z=fh?HoZgnaV%hPUZ@yiXD_l-i_SoSZHFJ~oUIWf!;PI97v?JRmcE8krU|sMB zKbMvHIe9(C*+xsxe!Dtn^~So{4J+0exjabxISGH(^1bqX#$MY+)?H+;V=pQ$FysD? zxxV50yF+_TG^!=Xb`HNhv1oFqpG~IB3A=`@=C)x+chEH7e{tqa;~Vu zl$BerxD&Iuc@N@aH!t>|HR^c6%&ZMJ<7#EzO#6`sDwii3^6zd;3)q{STeX7r@#=21 zrmx@AMWxM(wHvdpZ}nznVJ`zbeEz8P++$UjIQ6RgxH+coPG9Z^X~vkWFD$IieV@GZ zz>a=CTR`3mQ!kfGdiS{Yc4%kc^?1OWp+mCe@?V>~Y#JG2n({JQX5u)CcXP7#2p_jR zWrHSlZ|T_8y#GOK**uSp9kUH8r)?_gVVjB9yjdvcVyu1}HLG*(w7P$0wqMlsw-D3m z3lIL1lJ;fJ$8u@&gPw2vK5rTp^7x-^3)0gnrhm;1-m^IP${$Y4@4oXk$Z|@Wl*Yxa zO*?nL7I5c3$lZaZM({Ce3IQ6+y8`HHsV@toV(O0_N=(u*2*>A2_mN>7z z^Qaa}-DhJ~Qy6VAWX&#_+sJqLGutaOnU`fP(R2G2&R?)hyg45(r|#`GYrr$50 z?YUk|Ns`UF_d4ozxjwARGS8{@r_GM_x{`V9_^8??G2`A}+m{{s*Ye-TKCqJqbWrB( z>Et>3k#*{3eDI>ROD6jl1ub_ES~qb1Eosf;cc1gt{qgagg?ZP0Jwy19i+x`wSw3G7 zYgl%#e?W*Tr1;qEir0=)WA4fBW;Mfuv0$j06~sPBK55A^!+<@%OU=Lf#8-g=acU*VfrX_)@4&lSm4 zrOl6Dxqq{UTu%KF$-DNjZv4`vv47^);5XG4n;(u^UF!W~y0!C*OM5n9?vA6YUiM3? zzI?N;s*AtzKQlg5m(`8ak_nHx3`^IJ!DgTRcek*48e^OIiko$$oWO z`{&99GgyhFrZ)ZXu9_m8m+Z$Rk|r#OV}m%O2J8u^dcs*qOuJB9gR!R=)_{@EkB*)3 zkdW7=HpYZ^FVbJ`6LLs3el( zfJ=^<9dw*o`9#i3?(4-=f(8<?xzm!X zH)k91l0`z%ud4W~D)R=ciqlkawi44Zj(^l(FLgOEF`FB+{&z1Rxk8YPV#p{)-hdTy zTp_2Gn2xYn2J<@lrN_*lYTugik^{Q;`^aTJa)Sn}k>eXVGl}Uy6Cdm?_DZLR)sDb)?w503xA8B0vvjdr!lCWfRZE?)NCikD>QWE*+Dk+*2T8aPb@ zXD7%eVlcO7%zwL4lC{&Gm!#=rpDKu_3ZVB3$9@s?4l!T%4Xe~;Vd2ANXPj4S3B?QYBq*UK8I4~~4;66eHAGIg>K<+6uzlLqV~$A9FkB&LH* z&$ni`@1`|hH!&qIIH&q~swfaD+^b%M=`;ujVim4U*iOrl^fujV zWmz^YiFMr+{dmbqooEG4R^Y%BZgSjB!4vwZk3g+~AI$&USvU=d=IcbO6|!ofTwgi< ztG--&TFYe>yEp8!`Rf6^s(fY-d^xOalrbmxm(z4rC-AzAD+^-x~2Qt-vM z4EdG;4Yru$iiHO2N-u@J7<@Uej6OpR<0X4_TK`oM|Eg3C*ei~G#TiLVJuJO3SPQ{? z<3^vk3n%iD7@cgKl#G)CwOJgOC8+JjM#6$wY9=nYLJpkHOa9i0MsREdXV!p~ajG)T zM(8rOC1B5Wl`vv=z}%`=V`uS_--Ns#WXOXI@PfM>cUSO&u}&9Ti=}dCu4FqG0MQ(s zRxh6L;(@umc-Bi_37)N)oqy-uxOVSb7V(lhI@$e7*?y&_0sGGJ-#HV(Yd6CRTSFK0 zGT&CTf|p#=iGGsHKFNU%K5_gf!3KlPLRxF#YUI#H3)I^aQILm8}eJwbPhvkk|ONB-b+mJe=WjilP*U9GcWG)YiU&nEELh(l# zE_{Mj>FR3a%*AKTHHUWal1)MeLS?d08E9HL9G?T47SmfLIfOmaN#0Pr-&!yI1SCuJ zN^w3Hw`{@=WBg&vQt0CE0WSHnBrJdA@*Y0C7fL!uJ$dK@B!oX1Pg&FDpC6V0PIr)x%p;;g=3DmzBCrfZ` z1D3&Y8Jwxaw0-*x|8*#t!KVksTA$d*OU~#dtCX@TC8$hY{e#N<$u6a}GH1tlS#Gqs zb%d9!6<*mwku4M`c^=2*2_<*I*T5`(Tm0?g^=qmKUgD?I8ml5=g>mpD$G#Lq-Hm)( zD>L%lix0mVZvwKXbh5PsS1a^>w>kA~!AL*bAH@!0XNJ!)UJ|5}-LK*H zYcx%m{=cyF5B~bY$T}_wNS)A0MQZp+jS-jyV0;j;5va*UL!d2FssY0YKI;;G`-@trW9WCP$yeXk>wPqr(BN9 z73!%gQ`Fj(Y*zMs;~62j%1fejvOX%(M+IcdIj&rg9cC4QeaBww^3b#9M@pYDTY&6M zo$N`u?4%rIw~6DMgkE~6#f8>d{Sdt^%*=5}CNKG2sMRutEMtHb?s42b!3rIuzrrSJ z&&s;gJ+8>%CFgWnqgf)F1+DoJ$37BT^Kk34t+lE>sG4iG_dp>p3DC)YRuiAqU|6l> z*h*no^|0L8D!cM})y|$1Cw|~1`*gAmEYZM%+?H}|sgT<))OOgR2hQHo_pQ526E8{9 zi5_Rk<1BEN5{@eooMl|QORWYolAQT^p+o17ykwP7FmIOh7DVrJ+GXs>5QPMC~n z!m_36Y^en-0{}Tvd5+Ws0r#c+eW@`5%B9M3sTl&Qr3TefYXr1N`?W}iLjY&#!f2$Q zp~Dt@?98tg+qX4HaUNumq7PCUSWF$TJV>>JAbI8J`4-yWNel4gJ;uDpl&y31ChQ~D z=OZ={0U1)W45hw7E-+saFTXENe^iq z9GbA#^t#vdW(2&^40xmQfL;cQ|5l@Zt1%V<$G4ge2&mHxtJC}p!O<}p-FkjKL1G~7 zS<3V*W#9V#J1Zxzo70aLo*ZU69A>&gAA$=z2ljs#b3im2qoXk`;uvQ!;;hJZ&SAtk z5%9-pe;iG+59jyc#)yt^oCwEJ_Y22e!|{HILa0;hS ziC!Cx)6pUjgVQl05R22XA`pkuaUu|po5kaf$Xk+dK1o!TWSmbHfh#zDMWiDYr&C2B z4X4vYARVXE{|EF>$44Ts&BTdJkv%eTn@qd|B9V=c$;PK4AP+am!|huqYfV@lJ~$5_ zjevaIE+6lNfC8K^z>N`b7w7MaKp{>P;z~rK2q%g};2uug6M<5kE5(iAL@VoJPOM6v z$6yvsSc29*LF)=#chC*DgyGk7Ssr+uexQI33V?o~K!ARrK!ARrK!ARrK!ARrK!ARr zK!ARrK!ARrK!ARrK!ARrK!ARrfB@D9ZrZv9^4}xSmFxFLplHU6nIp6l#_)n=e6_r< z)(~38CsI0+xZ;UFU)l*$iEE4WYqS=DbT!K}hvBtbNSAtD$au8)DJeoqOC z9-a5bW4&ywu^@VqG&xCjgkvNCmr0Auq$>n)$4M}>ezyrKS+&DzqkAQ0E*Sb9N4x`j za{v7n+B}fF1`7eV#DpjM?J)Rc(fOS=k2mC5JAtgF<5uaSVImKonupIqda!W9IGkvm zzkwu$M7u(wW9wd16IMi+7ZElHxJkO*B>TV`07-6>F1N`p2q+@$ipX{dcud+o7J*XI zu2ck`kakZ*pp3LD6M+w;-3Jk9A>CWZ!N^;_knUeZ;49hxD>(#_NRSyN$jqU2LDmyw zV-jQ&5s)aeNt8Jvpi1UeCF_F#Ps+tpG+XkfI(xUxxPj80)L%O(PYg-3lR5xsD2n{3 zPJUE3M8==$>@QODH)Z#C+XNQqjil@&srE>cqm=zo5s0HY#fg-jp*o)tDNUd{Cy2m# zs@r+dJS~X|!;+{-G_OfiB0wo9dQA;|O^s|_m;$HQn#XHxU_T_7R%@Qn1`bVo|7z6g zLAD*ilRAv4!xV6E0N^9m@gvq10q1b*bGQQnGNo3TZ5<*=k}d6+E$s?>NC0xA?Q^7^ z5O81G>%P<-0WYNXFQl#OFOZ~MI=fuD0FkJc&aaj(K|qVNLyOcE0Y9Y752-=~jDNJP ze}K}*Wc$ZtC&cHfNy}=|4gm==iv*c1QjH0+NeQxP2uPGUC5k5X`7%YmOp8d|lPT_r zK#8nJi42|PSIO+EWUb2|kg+OR-zwQaM29!!=1rlVy^|WgllmEv*a=)=r`Q$zsP2AL zZ$##As{P+oCj^90&LLE11VmEKks=UBb&nJ2I8XIH-?l^rc}=3GCQ-8x9ZA$h0Mk$p z%%rR`kqJKV07{!fnIMS@D31ba6aoq<$3n^l0VnA$Cuuii3G$j=`kG#WfH#^>Z#3Ny zxBge7{#Rop0uKLboDoo`ajVnxfnaBm{|S%p1MG#)J&K~E+Hwd_DoF4oKyDZyw}Yb@ z06}u&Ah`nq%H)P+ayxho0VK-h#^rJc2*5C)Kk0zO06g4~1JO&2@)BbTM<@WUv&!qN zDIAbMTK&-nObaB+c*8Q@8tzO2kSJFr%FW=e0RTyIb&}j10jYAQRJkhxn&p~ixdq%; z07+Wp1}$qonjyntS}8$*dySPLj6c#4tHLFgs;lbS7i-%xr#@g&GU)r z<){KX58l#2-qI1sSRN;Jh?6=ajWu0Lq)QnHK#~^eq890L2!P{-FhmH$z?lh<2w^lK zj1dC#t49PJVXTiZb`Ss^QOuAiW&|=pNMhzBF$~jCCj$Fv^?nfuqSZknaDY}H5P@J?9V`L|Y4t%7I7F)t zi9iUg4iSM+S{*6^VYE6-1P;^c!y<5mRv!_8a9SNM0ui)2LIfgdb)*O+(dr}-NT$`v zB9KC>Q$*k*t-dG%muUA(^iag=mudB7kwg})&JuxaTAeKdIkaI8ZGq^xL#ywIBnoMD zp$HVw>LL-iN2~9NzysRwfk7FKG1(5vZWm6(aDGR=*U1SG4+-2)w4%uSMWrTK%sGyrtD|MWBXO*NDJ(TK!!F ze$eV4BH+oWJsGqCc`<4)5!k_~cZk4FM!i!6K63O&P6@UVqFC`{fzG`Mz9o+QCIgQ^^pOj1qPs5!c$AJM1{&A_u)o3`55-N>TsQ zDT#4I`kz9^t&r)5fHJ0Y8PfwQ)Adk;%9s%dc*WSfV%j0#Ez|Wa(;MlrzBApvGkp-? z&5reEr@$TzC=FqIhp+GORB1R@h zW(+Yh;~1HZ2n>vojYL2LLo_gQ#11VC(INs7oFsx{T2GRju%jGtl#?UCN6Y)P?SO!s z?$+|VMc|-TeNbx#`+6X8P}}FAb_fEZv=&iXM+jg{g5Xs8cm(KF*YI7J2Mz4tDlC+J zN!ph*f{qA-6NGhmJYg13IKovRP@<1ifJ)#4LG-v(d0c7>LlA(dK2QOQ9{DuGe`MzL z?t&BhNqIl11st+-%r5?%G5%C{2auCh^eQWu0{pX*bFJitBj7D(`IhUBfLg9cE%!45 zz|m>FNTP}B)Wi)%Bp&m|kNHjrDCLbx`Hl#9&1+us?M0ybYkm|0KJvyNMLIt5MxR7F zzVZ%V`MyY!y>jEda`d%+aw9)E`dUAQv7Z8!@K+f5D^Q6Lg>#5vAfhx$VVopNlB_UF z79~knSfneuAxYjTjNgfp)GCZ>MM>%vmh}qM$ev1LPbHc$FQt)}63y5yrR6Rqn&g1e z_<$%$u+k`4lq5pw5TQg3l%Oo*L#4|<(dwFOQ;l=t`AD9M)_YfdW5=m8dihx3W zL=aSX@Oh05F2B=X$i#7}-EnC*SVKwYx+XSne%@aOiu3_vK42=Oi}xZJFG7WM;7`c* zPefZ$??}scqyy~HfR4v9_OVQj*r{5huGW~qei8;F31!v?BEc+v)JEp7HF+{f$YLUG zl}Nk50>Zvt3Z4`)szSyV4y{0mK12yB0TLmsDulI#qaX}Z65gi|QG%kT;ykI)ODg>Z{X!uI9nk(j;I~X&M*iXXe|Sfj#iPljZS91{k-`c#Ou>gK zG|0;Bs6usAVT6EsC0(ynzzt%MkcW@S!zUqItp&JA0d9qWB3xC38zI1-VEjdA$omQTenJZkAygG1 z4-tV-LLMptVT3$P1i}e8ZTw>fwDt3(jU+>9?z-L-XH?L00y>p8# z_?R_^Z35)vF+21zI|>1%Z2wYrC<1=4>L09eYuE}nq~g?G9146nD__n5kvPPu4sk{> z;sLxRSjz-!m9TdL;IvkKT8o~EM{Cv5A`qih$B00zRvjw>@mh7f2qb9L32mU=`G)4V zCJUwtgHeSO<>Ol zlK4sO{G`qZ@F7fn2sBvb4qT>QGO0L%<2T;|aPu z(iTrMrl%PjWL25M$Ws^tq?LVVOujSLNTZ5pP2*V`WO;X$wYvM&{xSXNO88sZ>MpK`Qye2r# z7eIQW_%SHR<=W?R;InxB59H$xM}Q9+5YVh7nw2Q51NLrgJIGn2p7_aNW&)}XE{u}9Hu8y%lp`N``DgHl|`{c6sv6wPi(?o zvQ97A9<5E{-IGNPi*BtJsw@q+O2eIyt|5#t4kKE_7ZLEd z-?p&?l2npoDn&`ENV_Ugk}A@pN|fX++50Uy2vJ&1cBv+NA>aX+-9Mnui^pX9Vx|LP ziTg~y`^-=T9A@ngvmFrA9AWz%VTU5%F>C*r?a*o(VZ@#An4OM*Sgm<%TWsl1TGR)s!@ANncxVY-@D%(Fv@FW|TXXA#5xA;p9{iT-3F!7L3 zKO{_%Q6Ye_4q)2B(f}RTw3=&edrGjbghHHS=yQw)cK*Od`UriP5g_r3p5wh4?g z%=Z-1HsN#=ZVW3^2Rb$3?g(hc>E5r90rM;<;1PU!&H zA*FXnwMbTv62#HAbsvx@B>2L%)f52t3HpAUWdL|hb$U(phVd5w_%MVIqeN=A2@E1_ z!LvZ(i>Cb-O?T*K03>UP%U4 zM!7^g=w_hK^xw|FI-@rqK4(yVV~60YnWSYV=?IlTg9yQa|9w33Um~I6bzjv$B}+TZ zSa;D@vQy|zZp%z>%dB7y&c4{_aQe@NT|%%^1g?s}4UjG{8aIf>O%M=+8^nk}EN&1h z0&%!OoCw6@PVu-4q9X}6Ny04VAnW&V z)jiw*0RaRPK%i$A!Qfwn8rcarPFNi$>=2Mk^vfj%!ioS&i--Y5#1I5j5}HcF2w9Rh zfbViBQ)JekL(k8l7eglkI&$bga_IFU;053=bga*z4+0d1qGD!jF*6bN>_ATw=#fNw zP9GVIk0Q{*ShX;AaF_r|T9`2{%mf5{VXVH0B)%}?zA%#ziNoyJ!|X(43Q@{Bl(OyN zfC7{r=ak1eEnK7ma8Sz})XHI_03b@MjuM@;#A^q~Ylk5c3EF-M+JPc4IYB!O0{Awe zahzwh=i635z_0b6fkD5Hm}35i+xsIvO7PxunCcvc`js!i_!5Rl1^+`Z{}6^qecmSI zw?!j*F0mw+Sc6DBr+;})FF>lVftlIBEJaM#$V_Ww79pUC>D$B%N5Ds>-$!Ny0$P~9 zEh32)W_b&<9+CLMxPM_riomKb%w_}}&@uz2%VBX z00KS%Kp*b_!ICYR9irLZy9Lo?Vrw$72SY58L0V>z&am%+Z9s^q)qg?T#kTrx9>SDmf%2 z;NCfq2$d3{QW^nqQc0YYK-}uQlsGS?5fDvCq6q@AT`WPw5;OuT2z3Qv2#pBdQbVa~ zL>mk(lu-+1hB#glqe>F(7L+mSGR6>27=ezrjPYB>9Ptrv*2J5&Kw9%<*61>82HO`% z(!gpOSR+_d00eQyL7X|VeHOu)M{w3idymvmks8#7Hl{Uic`D$76>nj}PJ9HO#8l04H`J=3&9z#EOp8%^u( z0{k?UV}!tc^ovxG@k z_&bCV;==V5Ur!k!L*G@Fxyou0=L*!)fo&}pWbBfbzSIWx=T!`mzh4=^f+weNt5c#d z>-~iBeo<8QHPY&u=u@vo*^)-tZ*UqTXs700q81_G0lnw}y&P#mKUni0tPSGrUYxlX zhXP-&y)V}ZkvOe2Ki#&FfISH-bhEloePIm&Up_BYotL(Lt|mA)p?XAEL6ZScN14}A z&d_84oM!0Lj1gQF0&tGeo?~ngkis~owC%(LiFlTdXN};N6#(a1+w*J}1f*(}sai|e z$ZW%NF4R956ew&(ucz0W!wiFeUQn1`5S>=%D6DhZ4!Gg5k}#&|zgC86CpS%qs9bV$ zpRg40#&~bc20j5G6yrlh;26dq6M@G#{}{KC{P$~i9J46s%GUjsAZ;zi)M9ePQNLp@ z-?7dJ@W!3J@lFWXfjjRI0dJ|sTWW;3@^>loT@=M~lk9tw8~{f$@Y>s?>uu5v0Yzl{ zqPA})fW%wU@-2xjV_V1}E#z<{$rp0S7ZLbM4*g1wKqN|JY>7;P_~%Zl<4(~hfIGn# zI6J|ZhR7sQu1S=e2pk1*yiur3Hf57dIUq8(D4Sa%aGSEZEds?x_oF`9sy9V=~DkcU{<|m9(2vG+9^Jt z_~i$MZTxJU$OgB_{PzRES8C@gbwPl?l=qhkH+|}UK;j`mKP136=52uN`jG5{fIYG< zdt|*3;3t#&$qW$?DWfB0sE$UNNu$gLk+?*uFHz{Q6GiurqK6?80gO=qgNE7!GE5+& zMkH=)=-V3fEs0t_QHz!(O-rX~QHg6>=9;!u$Ns>ZLwcvXg$T>HP(~5T7{HCW;F-Nv zeQ=!~ss`T}>um_z1^{{+!lnR#-i8R!+Yok9K;og!hR|yP(Ay9JdK)4@Z$s#QAc@|F z2+-RQ0eTxkUjj+=Hbj8lh6vEx5V{UXqPHOe^fp9*-i8qPJJn6k4^Idc0{miei&#ZiGWnDZbRN4tzbAon)rWx&5Z~QrB#tGrc0g^w^Ha=y(_&x&b-tVMfiG183AGd{5 zJpk${lX}V#PD1Rx4u893c>k0Nv?%=y8`duX`WZF?^fPP(=x5l_@*s(RhK&II3>#_t z`WZGX1W2NvVZ%*S0Q56#1n6hja7PqK=x5k)f&zekhK&II3>)ry0}1^M8v*(mHmn*T zp`T$x;M(J;bNib7(}Ls2;1)3=$4|y>l0}YRDYdB-IsPY^%_ouL@1+d(iu^p5GKdv{ z9Qw~3(bxPf%=8v!26X)3^`)my?!O)?JjS3Ing(jiDTLn7LkP+^7bB3nH z3u#W$CMVlYVIRGSpE~rK%~>;0ytA03I3FLyk3yH6)A{M>KO1qr5l2BH!6yB`Fo9`_;Cmc{+l3QGo+aaeNS#ql^ zxdQ^q6(;2hEBGZBNOE1Hx!x8{2*6#9(cQMg9RNx+nvymN*iY!ZUv~u%%t&|3YYm?@ zgOfC%aqExoq4xoxKfXtR{`em0x%9{Pu#tfz`r~^9=#TFapg+Dxfd2R%9x?zO`r~`p z`vRapzK2c#fd2R%0s7;67*+`+^vCxI&>!C;y`TR09)3d)lIV}`k={>#d=J0B2NL?@ zd+1q~TMK@FbvQrC6?j%OW)+RK);j?EaJzjtx_eQCn-<}g(Ck3s9&UUON0*vS_zrO3 zv>ROdqyGUJZ>gEL6rDClN(~~VXb^7(VU$6bAxW|c<7@&|TS=Hz5~z+U!lH_>L6ZC+ zOnwj+2-rm$>>|;(944I(ljuUDh;%I?TaSoAPK(K@#pFyxMMoSv6kpO>SD>R06^ zS4Bx4$+eF}Zz+|xFBJvozma!(BX7Mz2IS+N-1?nJ=>VgQ|RjTfaK#kJ4Mu|GzX^qKg4QikijX{d0 z)umu#7k0+=*Nnj&g0AZWMSp19G&|Gl^q_&5<0WBu_SVwgZ5y9y&*=_+9=;}ct+YiYdgOH5)bGg@PE;%TO-r6k?9X-TtFs9 zYaXMugV}|{mXKZjO>Z!}ML*S4|Lvj45aPJcaVF

aB;xzQp4ZVhuj4=h;2v}v{Gi)hM%-67 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 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/imgui.h.B7C59F8F3DC0FD23.idx b/.cache/clangd/index/imgui.h.B7C59F8F3DC0FD23.idx new file mode 100644 index 0000000000000000000000000000000000000000..1870af137d3f36790ff47aa7956c4412932ba6f3 GIT binary patch literal 246116 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 X+JzYW4N3Zc_YM9IHTXM%{`>y`MeFv6 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/imgui_draw.cpp.7992492567CA8F61.idx b/.cache/clangd/index/imgui_draw.cpp.7992492567CA8F61.idx new file mode 100644 index 0000000000000000000000000000000000000000..246a7db04f74b18ae3ce5c746d6a3e6b417b7574 GIT binary patch literal 147620 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 F7yvEWnc@Hd literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/imgui_impl_raylib.h.F2883BD4DF99D0AA.idx b/.cache/clangd/index/imgui_impl_raylib.h.F2883BD4DF99D0AA.idx new file mode 100644 index 0000000000000000000000000000000000000000..2df90c7c420371652088a8d91b557fd7d74dcf46 GIT binary patch literal 700 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

y6xuwQPmU-W763%SJ$(U-_o za_cI&Bb?xZByZ&X-^hnTVBUVk@qr&2ZwmWu^_Zp}>j7;Jz#~fgNOWCQ6m1ek_k#ln zkf_m^)oA*|Lcjw9p%D5z=wKm|@6RomB0ZlYctJ5~QcQM(<^!OTG^uO@aJx}ZqQ9LE zD%mss%9Q6ht8)dP4wqVmOI_g6N$BaI`}-@S@`NXQ7{wl@^>pL$Tt~AZYkC$4K9!C; zrQ>d}e1a0fI-F>|mH>bv!oG;;iuhE#);?a_6_yVMt_WGvUxo*>_F`WbYdj(Kp#s?C z9Y(yv82B0hyri_3R1V!9fHmf9`GuK}w7mrFtOV@> zSgh?=ckDgd%d||Wyl~tsTy$Cxj*kl$U0&r+X#GXU2mZt$e_|9;idsTaOE5@X{UC@R zgd72}q){vgAA`4Mg6#%!a4h)~0zze0p`sfi$|-|#$`XzMAg4i`B#2{>yNTK5E{haY!389w@{(43;A zbd=NxHnd&0Mt2<=KKq%F<~qe+r`k@drrY%Ov6xpbq{)$)=Ey8ztxeky5NP)#uw3Y3 z_GA2h(S+|a&VLrI9s)FcfCils9?|ee+Cbo>;mfysU3)8Jz)#x2PdX5`t8YV#CCLjD zYlJ6t98t%CJH++BR|y^+z51rV6Y4h;S7nM~Nc^P>{H4D_B|zdh!5kL_bDSfXbA%dc zi^+t0GU0)MTw-c2F&6<3i8&96B?x#$XkHO!$g1xtJ^m>@4QZTL8KP>$YPN!Fjh1y%+l299g>@S?f)NI?y*qHUL)9 z;$HVosEmhw5Gt>b=L>la3fT;sz8}mP3IxbJ5eucHE zSvua!YHD4x&@0ztOugs|L~nxeZVP7v5@lrjGSSVKwWMXO=s5I|jC~|iLG2*PBZ_@Q zp&*J@M9~I_H=m?`I!TX5z-!tY+$rgccGIsk#;-K3hlxOKjYeJ5w$-T`bvyi%T~3Q& zR{d2V&`5g@^gCnyyskxP zX0Czh)4&XZt_?&=*`G_L4$p_@`PsrbmZGU6nPSo9-g9ncY@BkN-zX$g*HDWDTGxh~s)$|E`b@>_8u>}0D z_4gk6`wQ}S3-Wg}^7lvN@6X8J4Q+ofT)Ak4u-2Kao;P9Qr0H{}PM$Jt){I*0mzm?| F{vTCzYiR%g literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/rtextures.c.A0FBFE53B2EC34A3.idx b/.cache/clangd/index/rtextures.c.A0FBFE53B2EC34A3.idx new file mode 100644 index 0000000000000000000000000000000000000000..73da652db5ebf623ac2b67dcbd12a5f4050a5680 GIT binary patch literal 95810 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

=d1Kc4}cewVK>{XSYUni}|~?u-#(* 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 GVE_QlO%{d# literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/scriptstdstring.h.0BCD3B6B171D685C.idx b/.cache/clangd/index/scriptstdstring.h.0BCD3B6B171D685C.idx new file mode 100644 index 0000000000000000000000000000000000000000..7df16541be1a708ec1ef313c5e4791cfbb44069f GIT binary patch literal 578 zcmWIYbaS&}VqkDi@vO*AElFfyU|b5q_(M!RYTL?>A?>`+k66q~ zy#GE}v{ushs$B7;20LCe-gy@PRoWf=rg%n8op_jq!7sG)KnmB5pRanHd>@Gdn^Cj zny7ZVG+bc)gP*-w+M8Z6hA6Fh!cbh9o8$uYgEYUJgjGU#Mt#& z^~D%CnHU+kSQ*(_pGv#0*c~aI$in~%01#j|U^S3NC@4xzE4~X9hMC1E2{8ezmVp7L zA1Dmg2Nf=SuXD#QYF!c|54#bAkpNVbL3rhgx6k8O_c3y@%X7$!!-UW2K0I`&KXWBe zSc^l;04AIq*YEB|ZM{!Ydu`-CkzU|A*34gxG TW-@VbGH`%IAb=CbU|;|Mhv=xd literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/sdefl.h.C0C0E9AFD8034531.idx b/.cache/clangd/index/sdefl.h.C0C0E9AFD8034531.idx new file mode 100644 index 0000000000000000000000000000000000000000..06a90537c4a1e7a8ed29f03c470daca1d65f1922 GIT binary patch literal 12070 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 oEqb#vLGf{O~L^z6Y{;%`-e~ZbA+5i9m literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/stb_image.h.181F33D2B7AF82DE.idx b/.cache/clangd/index/stb_image.h.181F33D2B7AF82DE.idx new file mode 100644 index 0000000000000000000000000000000000000000..9245188a0931b43f0d83a7385f73dd2c2866069e GIT binary patch literal 98606 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⁣1r z7mUk=?6xkMQ`6Y=@=u=Y1!wrQp#%Wh3<3acP zZ_0NdiPn65D+M0qf9+BJw~=P3EUYgJI}lhJW|oFIr1z-{Gj(B(()%#2VGgNzmPD8( z5e}(&nj%b7gd?pD9)Et+H=mk^wne#Z)M?qFsOeA?AHmfmxSE8UY@HyFnnd54MAjw| zz=9OBAjJ_oJ~BZoQ&%R~oH{<76>`oB3GxX^=(z#V3^U>8)MhweAD*utNNi=Hn6-NC zT753EmEEXkHtIP9HtV^~dN%?!dVh_+4+6D%N3GtEz+HX#u6`g{RYEDF4BAnKT(YVJ zFvCzd!|*Bsl?G#_!HGbJLDylhqnqN_4a{`|hrlBP^T@!F^$28IlA|rj$;~>9f;0OZ zV`+{Pf$|(}c}^~|riCQsIf?R|XAzi^!%WHH5U9v8R^&Jln3gqStH6-il9uzUIXIHwuN(N}iWw?(S?&FAC1pp&_%m^PxJWm4{X^I3%xX=KSz9m%0tdjdw$%Bz1 z^l`G!0wgrAm<9uCm6=M2J*J zit+luc>Msfa)q&^CzfPJKtlpZ>fmuRK_k`2o#ISRaSlRN{nT0bsq-ZS%3aBF*C4d1 zS;@Or@*bo*IKVp&@I2Y&z|)lqj#2@GJ!1boVv4BUdgnj0YwJ7Qi;AlDkU@LMU?TAp zfAi*s=*quHFB+k$=kj#t^6<@rPf+e;=U*l}|AjupD(5h`|2!Jse=c+NEpw&uw{h84 zs%tmq_kSBQc;{y?DyGdPy>%tMIT9b~%MS|vexbbiW#yOR-n!!67BayQ69T2BRrCb= zRIA?;1(Z}DK404qZQBqB*`$&wS((o=@jo-NAle$WwyM@AM6IS+C}bjls-g?6+J#mx z851GxZmVs#HHyG_tKq!WM>fSEQEqdT+v21T0@z}6Y*7I@3e!SynJ}ViaUUC*kBv6s z$Pdy^H8N9;Hgbaqz(OOl&}bvZUjX(RnY~6E2_*(#Lm{)F&_*060oYy0>@KvC`$A-J zQr=7^IH_9xr?TNwIggymkWi&xSe<_nrZgj|oJx*N8AhhS15n11HjMNsX;dnNz}S>9 zHYFjjI;CHo${}MPLrpXxiO%e zqhw;Gs!w;UfIn7{CTe?lGc5(47FDqi;Cumpo|3p+;JK_ykikLuc9{UHYVM5&bECn9 z^cfEg=7$CsSwBGTjYe~$(S`IGkBsI=Mi0|4oPMg=FBeSi9Uk_aaFG4 z^#pK5ALLV>|CA4)!EiMnSk1=~Si`&4@O}h}1V@n|qTzC);F>7-5hxQpWkNmzlZ3BK z5?)8(l;Aieh-7h?4Im3O%mj_iR1rSaQfI%V&i-f|S>a5spw!2go&7FT64#u`Ym`JY z?`T%_SdeKm|7qf4uU4IL0C2bH6Z@`66^K z`rPYc+`5=G8{iODNil8{1-8Y6Z7~m$I2^Mdj^&X97I=4EF-KR-iNO6>{{2{l0t4>H zk_Z&VxuUogffaG{3e|+JYHe@-^>25+s>IPfrq>@+uebp?uGb%@zzMzn1O-N$^`p%k zvATgIWoEWawaWo;D8L*F=+V*VqwJ6^pi37Pf8S|+WO z1XxxSC7Gbg>XUU^xK4{ej<86GWksu=39GD%cKOX+)b-9T|MOk`H^~tN3A?O}ikVQ$ zYT6n`SHo~*Muj%Nh0$$cIAZ$-U>l>`#^7z(6fTQ4+Txx zNU|_H279*zP1%@ppvnpMz8W-<$h9OwwX&GcM5R_AYNwUkX$_ENl2Re7?XWc;feAL- z1Y15?CV|8pn`4eGiogn+cZID#0*y9bqb-TRN|$$~t3TO~?iy=%j}Fwnp(sr6_txF- z?ab6iS*}cBbyHXjN}T!@Xc?P;J~5gbf=4yu5}23Ov0CLXw&``A=? zY$}0rUz-xvrhH^o2Dx8I*)F791dtHo$}P=I*l;zoE6MPcq)blvA??LpqzB$fr;$W)fvdP6I~s#TX@R@6AnS^O1SeNsRVE<0TK+E4v`e&-sU6au z7Tu>s9|CQnqfNxd`e#Jj8PQ23NKkX-ge()tJd-<23+E!bbCImq3IH2q?FQLP?v0Z9 zLK$x}vCY-A)kbf%u|HY-L+(9M&@%!W68c;jL^I*e)u-Amns$p8Qbl;GcG1-?dI%r^ z(Un;!69ipNTjBFn`1)e?ijQgWS&2J4$n2?a@KfI_#3B$tnZK~i{~9@Y2Jmr!`8Z%D zr^s!a=Y2nZZP>fY2Y4Xq9#EE7!+pYVAKpA~@!7Wc0^~6vvs$0G*4GDtQGUZHfA*>` z3EQsBZ<$c-8CiJW_2P5&;;ZDjiAGR48_xu5S4D3bOt%aPq7sC(B}PMuF-B$+027Ud ziN+Y2O~|cz<>O@nx~rLOH=4H_z2y2n6xS2_oje4I_pU4uGBMsWKamLU%KVmz>Yn)p z-o%+CdnRc`o#kBmr{~hYL0zG!fG;Y*9z}`^q~Zc>3|ms*Dk;EDNX8U+#uP+Q9;F3= z(tVU@S7qiZ1+K}uYqA5`D(#Ok`zcGLgE8B|SoV58WO^v(IHX?S2hbF=Hc_TY%`s~; z1EsEQVC{P@?7gJz#+&-ED zW8(TT@$A+DiX9s_jg8}H86P)|r@(}`X#xc%#!V9`P!>0pQJ^OAR!!mqa;h;So+GUez#SuV$B03vk?Ews1QRpCge59XOeFY`j-6l)jf#F;s9Eb%nOJWXM+wSe7PkiGh%4Acc| zEd@#kF{OjDNz$gvx85xO&i9pt@wAX>S_s>{pNX(%B1SS!KxP%u+zRTHYj-rgTRo@+ zi9J!{7R2)EzUL9R#4+!1rusWWuHd*@?9ONAbc@I+H6bp`G0fSo6RVzy5>7YW}MDI2+gg}#+YEo~c5-(E9SG~m8 zFM*49^{ejJ+V^X-pzqa*9ew|H?|tP|p@n5zAoTn59nWo8e*72un;#VZYR%6-P#&{7 zmRB9a8<6!eZat;I*&O3GQ(#*xe_Jd_E+vFy+d578ZSbpM-1=lT1w7s=ob62)<@ zm{Q=ZjGI@g3Y^{d_W2*$*M6X^U3Vo-yOP<)3lDQ8$zDnN$YKM)xioh!Et7Qt*%>OY zXiBe~DZTolS9B?8x)e+h&_CJ#o$p)oeyD5!RwT76k{0p{RIwrztw;?(yNSJNZg1K} ziUEmzY2QAzTmTK}J`L#tB+-=iHBl0+X-{i9pGYKseCaP^ubus&6&~WYj=8PVlS3;2 zw>ah&rzcx8086aQ604qUUX|yzvgfQ2Tl?zKANzSF`t~-7*(T}9*%*L>5_3?}6YU9r z%Mx>0(i6iw0JD9}Y@ePissYULF>@$T9$?A?da`5&iRA(P@&Jdx#56mR(n6J`*)j^0 zr`d7}tWPuR(|YnAAk*yy?Dhf^*>?aKGl&^8NKf3y5ru&AQOkSfl=sS>dqE3n2$~v# z+0l$tOj&jp1&l=j+;%1ht&@WgndHcozrC=)@WJcb_ixxX<;TjY&*vL3Q+ms+~5PP8)qhgAT>C8M!ufIK5t3^}&J9-~VY(_p(&S@Km%m z#;v7#)5aLLkpkOd+%^gvj_D7_jHvT;#vGmh*1h=qF*lMJ73W4#-D`Q=yj<;GtA1!| z|JT&7{D-0vE7od@wRphq(rLSNxuhXZ|Mb?_XTI_KFGT0(=SIn^p48W5$^ z&TtuLxFph>;GL}yj4K2Q*~H!ua&8C#qTqYxh4aG*^i z{EJ7w^mKj%nSHEdKh_B(=nH^}I(ee*`E0oP#;5BBtw_`E# zt{`nm+*A_JYMWP{oAGM@j@N#!=##2re02;jJ!)cH4fScZ#rkiH4Wx#`*kRR^m(r}_ z+-T}ctcsggsb2yl)(rNq85|_Xi~!aT&Raj&MZh0?X6EKcfB(4~ep$jqmN0P?Xka@N z-OgmUh9Gf}kq+K@NJrXeWEzcH(sx0k%@}GkM$sF4WMm#0wd6PqBu1G6qfBA+3QG%nl@{vA z`4~t{D)db%454>AyRg^nLLE6U1BvRw{OUrPykuf!mJ5w+Xvi`&gx49xq29$I<7EK{+7K&zsTD$00kc2t@j%}1ro zk2>a45?i9SEmSF6qtaF?No|y`jY=qw9ntiT=nx9LvLpHi0z0G9PAZT3XutYs8cFPn z=Ix7m5Gay8MRN9ikVdBr_a|A?Nj7WE0Db#1%Uou27ry;;#gq4c^fz)mtxO{IjIExD zk^u_R))~1vV|G@VvtZ=IX8+*-Qbx#GA!b&{Ohn;hR^%HiRI?uOCx;{dIx+XZ6rELx zm|G&^)zlu5-y@1>IoB-qZ&pw2AhQ;6NQ?Lqk~k}R&#K1yAaPD~oKy9DeIMQWjq$JZ z|4UilPUj5Mx$HIuL@#jq3tSFaGXOYcDLiF)ndoM@fj?RFgHKw%c&c#`-MC10(ge}< z5ySdO_5~0GKl;Xv5AXfvmx_|M zU8if;WpjmM9_zJ_^&#{&rx~=<3>YjnY8M-`;HA~~#|=LHKfhGI@9Ly+b<#`HLb9Buwf`^8@>%ejw5$H!t;6w0j^`_+qs(0kq|_S;8+{bIlU6lf6pHBjJy z*zW)ZnnX{Nx>_%I?aj?|N-qCWQ70~m!5>~uE{jE$#nNc1*b^(*6Z@n7?q$5(3lACxAYPBjNZt&jg@}aB6j*7|th8W> z%NEUL3f!}3?onW*RWs6xliaXrZrCs=@o7qY7?k@o>6@?R<4>r>YBDTJ`i{DY_5%I0llWn#<%U>}>ekCoBA?gwn%16D@C zdTLFBYfZ0H7ro!!8vi*_=a5rhrMV3=8;6;*&Ih2m)km%M>X1loQ7B!c!)xmB;*n>k z#O#!E(Ng@d#2l7#$x@v39VKi{m(SPb%WhJjm|OnDE&p@mU=cu~9vPn1vLmOWEpDUUH5DN%p4ndsB7%V>m za_@0?huUn9e>(ztl^5D<^S|`lcc5mgS@^@l`8w9Oj_rdgvXS*{q}uyVHn5ZJhw9$J zdOO${T2^(jd>0!=9iUX}E7kTP4H0TMR_hz9?L(R>fN@&iIBg%YNd!=)mCCdUaySH_ zTq~7p6U0Ibz$C3SNt-}--Y09N$=U?D;tmqiwbFELA{$81R31{Y}85{wF$B(1h7dP+N2#oc8vfwYo*QF1aW8q;HJ)dQx_w<835Px z1=sXnA$BkTMi~l58NNbJU;vymFy{;ww5q&eU~U*JXjM7d$c#2x$N>x_8E<698!hAj z2EY^}GsS2j7IOe9jZCG{aOHtG;M~3>0 z3_XWd%B7(|X{aAL_=HlXhM1`#3vu27pee*Og)Bth2VhBMwg@p*^tyXuU8a?wJvnQ3qO`6jvwXWWfY^Y)J}Rk`dH_b|oXbk}0BH z1BpXP&mroR`+8Emo{STxF(5G~CC^C}ppo@{Ds(?JfQ+ml@o9no(}KRJ6BZBh6c3V7 zH=Q>~m^UbbdgX$_!h*pO)YT6SaUU8IC3drr>HQ&|`$Obcyhl2=7yM~6fT@Md)Itl| zV=XOYmKIvbmI@@+7c%P$EyUy$z}7-$YoR5wH+c1G=cm5~P*=#*6dY6`Qf(s9f`I{xAeeyHep#)yV7qKSw?t~*83PB8~9 zHFt^pF42uZy%?+)^AXr52KP~5zZl$4fd(klhGRMzX`Mfk&_8$@;k6^mrEsNbww8NlP7 z5>2Pn{mJuFej5Ao+UGv%c{AEEq8`1O9inLm^=9hCXdU$sbz-uP+8@=6j(V!NeWGI@ z1@?=M{S;^r9Ssy{6;rKZ0eLfI>{qOFuj%uy>C>c!uuQpNFkLWYRV)Ce84c5nG8xGM zR2dCbMwyJ{0BVhfTBA$`ZqFx?`Khl={78uavfZrPZpO>>>G_W7`FPV+neV8i!0dd- zYzoZHcg&^0!hFX<3RLGiswuEM-?5wmPosgS(f;Hq;gb!O14CsDhRK0p6c{cChErf` zLfD$fZkQpD+JsO`fo%z48wGYI;yV-Bn*v0Cr!1GBYK>2|K2jlghtqYs={hfQ@CM*| zNOwKtB`wqw`RGemTNnIZS-&0N3HgG-L#LIyY~`*XvP``0 zWv_dkWC0I(bb9rjUV#8Is3_XsZpPZJ4g^rMd4=YAh51Cc0}oSOXsT961~SMiX(wqd zlOR}h<{yaG%f@;+t3id#P7cwYRPPIrWt(ydpaafpC|$;R19RSxOO_>&_NIZkX~-qZ z5&-Q+rrnrJmIDB$7c$cebIF(qV0j_4yfBwM-r(AAYU-Oe{;x9LwK80*`j}Au6q9v| zDNgDRvAJ)Z@Vxm)rC0CdY&*HEl?%MQtJc0(tp(&90>CwE`aScw}`v zvU-sb-C|pCv3flL@~GhT6;%AQO8%ot{?F(}&}=?`Hs6N;vMW(GZW{u|4T0?74bNQ~ z%qdmX{(bU}njUm*{iD*FDw4(u>ey#ZN?4;t7J!PJPub3=oM-|(pGurh4M5;Rs{e&l zngXv}NWD$~@%F6Ltln*@cW2L^pl03PP`CFb((qEvb)kEArv6E}pg!4doNUMK{HUEh zYR99=F*|#V0>|y_aSEKUvnMEU%Fdpmz-c>sngUIBwuu7GcD9)UZFaVe0%z>(848@W zvu7#LZfDz7@QpuD{&1`9@Sl{%G&gCQo5T*aNtrws zn_`PiLr6z}w98DXWu~tUTJK%|{$$6_zkAp8HxC~07eybp-*4UT&#n|J!6IKl#G83)6o8@n4>ShA^!#XByR4mlftLQ~T;)KKNeO=dX?Vi_(bpdrbR1 zSwl2Pd&BFw;T=dC(YfC?&3pgX)BmEJYW28mCzb#3qhWt&`SsiXPkF3LCa03YCsW-f zOSj2RHUbwO%xF2-@{_+REpbK&{;~=g$h9#PZVdG!gEN3f`GH6IadO=WKy^4=9qxyg z)jPt`9pM3JS=}5CHHZ748_0_yo<)&-w9Y;e@tufZKNsUgfE*W0e^{baQOV6?$D z+TbTUMWSU@(jMiEN4e}k52AH0dz~vnPQ(E0b=mi-fM}$Z4{?#@FS1$n4^;6w>%Gnn zBy$0=d{zeO$-QzWQ^(nj!JNimHtmL@|D4fh{NMkstm9gIo)%yB+zWEO?T_8|r%1~K zuqNPN6NnT24}kJutUQ<^x*KvgR%zG8K1;C=t4wNqrW&7>oEk&g@qY7ozl~U4N;`LI zgqPO;Q)#SQJeDnLI4*b-2gK(NsNS%jeZSWH<>zkyQ>k-Rh^Y$Ykj4tRE)Fq^LpjJ? zV_Aq8t1W)}Hv6V!inA8Rp?L*;RSLH@~{zyYlabD#v=eIoob7 zYbF83bh)@LSBQKp0E+~6k>DnWl>ioqsRiOU$N~~Tr}_~6V;S981}mTzFq#F7 z7JZS0jAkJP7BiZ~6j;J&mQY|NqghFT8b(t?fh~+?3k9|@nr#%=&S;OrXHTUYdy%DC?yuqd<8tO*sW7 z_tH$Jz?5E^DHPbR)$G^esyFB~4LS^(b(&@hoG@rk7_h_{gXRncIt-c)3fwnn?o*)1 zs3|hyJjNO|V<|AnsF_583Ztfi0&|U;xfG}~YU(J^VAM2F;J8t9oC0k|O&bL|jG7J# zJTPh=P+*ivGs=XkKEoK6G-(!6V5v#7lmg34nq?GN7}P8b;!@TJHR~x* z6V%jDpdqMfpg?0#(@23!LCqx!jEHDPL~tpiBbw0^C@IvG6k>@9dW;H~TYD&6c~4OdnHp9s27C>K7L1?y!YyURNN zouXs&34vN`xYpVafjw5w9`%YCl+t4LwOD1ccLi|48n|GM zBXG(3wM*7F5x8o7>8kY`2;8>@?pyI~{INE9tZg9K|3apdY|yr%;a-t z@*X5Hi;vFY2Ouz;A2OT&DgrzCf}QH^QYdy8pWem4K+YHd)bWLN{MQiJ%@^*bz#hKu z9yKyIB-zXN-AjRed~6?|M0p(H14sBc0!{o6n)sg~(9Hj!nF1~R>n;3ukVHHGN;{to zfDOf7apqc>apqc>apqh~B0m*hia-#+4CCPS4a+8A`kXYoi zEb{SWI{{#&FS^n<0D-lB-&(&++#`d;27jLo{sIIx`NNz1{Sc`2^R=o+Wk}NGcQ^S% zWCsM`sz2|lUqaxzU%c**AaKVYzT@wQK(~KDH+3{$83mIQK_ zPzUeJ0)b`f#tV{s8sI+-1W=N?fK(TV5{(u}><@(Z2l^q<5E#%9cn*Q)fVVjiM!vUO z0+E(Le*{_suGWAbfwq9NE#O07VyN%L&>(Vr2E|?uIWLENWOoIiBlKKH=qm_Z4}J4` z=v@RlL;lWC41s$g_q|XEfs%Y%NxmC_;&5JZSR%>;D5X8jw}%5nH2~m7M7j})k`p%o zw<3{Sk^TsDMh108UP7QNGN_9J-I3xibw?(A3CY}zeEDwVn+V*CeEnYJEd=gIzJ8wq z4z|E21$ZF*6#SsX7#gOsk@OtD=LD#Jp&Hp6Xx_ zB<4q7o*#V;Nvw^EYpGJ!MfS+&0#luvlN2Bsl z>S-TD#RrtcNI7q$oHaCrL5B|93xE#X3xE#X3xE#X3xE#X3xE#X3xE#X3xE#X3xE#X z3xE#X3xE#X3xE#X3xE#X3xE#X3xE#X3xE#X3xE#X3xE#X3xE#X3xE#X3xE#X3xE#X z3+>}r(tIqLhi+n=OeRkz3lV5cCL1Zxo{Y68lStxRGIovvx01G7NjEuxhGOaPzyRp* zzyRp*zyRp*zyRp*zyRp*zyRp*zyRp*zyRp*zyRp*zyRp*!0>{)hZwqt)crc)3#)XG2}4p)NmJ=7VUNiz{=5$SGFUM_XTcvVZAFMb~w< zm+ow@tPTHrzdE+<+y7iO(g>N9iCme86_a;G@vexkQ{5BAdla}YiuWlnOcIAt7p{g& z;&2L#ki-!bsFcJ?3e1$mnG~p!#3~9bklYK@TU-`?bKA=$Z;nz-IX_`?KA|+#n_2y4 z){LzFwwi2PO?k*ps?}s}{kPal=G!JKQEr0*Z-m)A!fZuWE+uAHiP=NII}aDW`mK+S zj8e8{^OMf`$*f`+(zYepwxp4?VRGw0`DWvE#&J3y`eqAtx`jIL@uheEHSE;IDYHL# zWAgBWZx<;~wK%3-9K#n4kHqvx)Qh-K%-xvdu6kt{z`A(;Ix5E7#(4fl3S5pyF2`{= zw&{t;bTzix;a~T!`(V}RBBjkdu<0JyvgH#Ux^ik+uC+f=e}J(aV6qJl-urPQcifmgKK|{Afya+6er>ek2W+O! zJX44J`8l)aoVgFWdO1-DO%$@uq~N_D5#2|`1W`}}xD;|-3dv|;Rupy?squtBq9yKV ziHAwuw+pwIpV0newDRtjv&Q9=W0O5BzlY67hKc*we*4%V2y8VC+-iCOb=qAfewQg9 zfjX17&LktS*TnCoBZIBJtG5f$?)7I!XF9KKd99Q%5NDulb_J?kK_s!#_0yHE|DeGCu5|qofpso%9hJu>S6~yBN3APb>ylBD23M%T zm5;zlm;0ouEr6O{aETYFOs~7d>lC={5^lTPD33cX?;V$jK&Q*wNr5g`y3197Bp$fz z4_poeM)BTJyhyYKP>&+sTSS3k{)J-xMI=$edrK&ZF}!CC??n=&yuXx+iZ`Cm8_zqD z#8f^smCr|D8XuZQf$2OyUG-}U72D49+bKtJs|D|BK_smYB(@3eZGwlm&r*^IzU_h^ zft`YPrywG*OK|U^l3WpjSA-DR`a>R9g~U}lc!`kLp$4r0iIHMxq?nI_msE&sg{UPX z2uREmee*;=0t-ZL0p;#xk!V;X8j-{j(Y{1cw8q+pqZ?|)C0f|DsQLlS04*qE?F z@>NiI%#(z9l*D|=H=mMNCIy#KnXZt6D=4r=vaOMD+~>8DZ7l`XN$z!0)^iWMu^ke- zL((D(-a`_5NYWC;4@fjg&L+u4P96cYO14%h7lAg()<%IdlIx7bBZ(^#dqvU`<Zb{6dP&T?M0JNdqW2DUZ*7L;ogv}i+VdpuJPNFn#C1~EVihtyBe~D0 zN7De#hHPg;PO>He@L9IFjOtXzWC^AIkJ})OVV?9oZE1H$}rpq9y8Yp}>`>?F#iQH>38OQ5*+*zU-PW zdx@VAs92rsu9JPpYUXfUe>k2))_EXtG_F5Nfs=9D$v6(;+@5f?C%h!dz9AL$_j>=h zMA>LO%{4w%BbO4hEyZf)e#&w`m9>V2b=IB&^PU19vC0B4Zjg4|Ac0tAC6*ui{tJCZ zmgYjPtv>j}J@||-aK@KF4h%2&A{TrEkORXjKF<|jm|Sdxr|R+%gISFr#*^~Ik0 zQpAb{K$*W!nST(u*9c&xpI_+@5-l@;7hYQ&9MtK|6V80FDH;M}l_p&H%IpwQWH=d1nARg4&LtoxHR3JEdP+HtUDu{tr%b zUwM3VG@}_gUJo_9VRPTGWlgal*Q2@Sqq(kgkDk-pgoC#L9LqHyqrmZ8^KlBC$Tgp! zz{yyqCPGjQLx|Yk{r1Cg<^N0^DpR(;U0P!oWlKIx zXBeiFh`BkWg&pc>orK&)jMmAcbuS<=L1&ntlZYkiFj2=&)VT?0mHAtL zcz0^KVz_z3Bi!&rkg-;$$Jyx#5fG`3`sZn`mn-)HriZlCLwL~Yj&R)(I~vZrBYnFg zNeaB!9r-E+zSSN14h4SN9r*OW3RE3MJDTch7Y5@(`$XQ({NWplY~L(|G+*)~~rB5+dHpOkZm?d4lLzW2TVVr-KX zWmqj|tL5<0t=MTScIF|q&Brdo$1Vq2pnbxdKjB?yJvLS_j}=^KBw8=9>jf*?H{B5o zchn$2-+KAf&;R@8UneO|wa8~G^5JoAv(L2IXCViW@Pa(G=8-2lzz61g#exbx4B$+*PxJXxX^5;{Oc0bx}8STbn#Xj-5ed4#s zLX0R9718-R^L$F>vpXkmcTR-duqAi?z6YWQOzs0Ftk9@38>`F?a-|O%@hr1rmRUkz zwb{7Z>>yYAKw^!VTVv)CsI){XEdz)i10<>})+&n|fms%5mPJP3YM%CLo|PyzAj#)> zhR^ft2voc5)#}b3Bv!h9vC{QBvXKX{$z|U}Nz}T8TGe_JBpO_K4K5!_a=~S}K*jvJ z?y_8`z-^c5wkr=M>2gK7RDB9$TEufjRLrjuo-3ii7(Qo=+8`mxR6cJi?;|Y~z%)K@ z8U?2F#_7BRN$lcvyVU&vB&p}M^}LldY5*sB;UphI;52VI&D#-Z;e{4TV!L45uI~LI zk6nU!m*6DY0RR(2hKV6NI{595IJ+Z$(%V7eZp40<@)!FcVt+t^hY|Zj3OtIq9;t3i zlv1L;iR$_nKv~pRMuGCEubcvNqQN=QKByiSW$i`TO0G#l9-qnD&nU1jrrj6Ix`qdd zeKBcYOeR`f0OvqK8<)sZ6~Otp<2(f}#2ptXa53(^7>}SNH{+q3@xBN=h=X4m9|FS@ zj^PPhN@*g$G|>-9tV#&05+MXWO$eV-V0A)RO@Xxu-`YeBC0Uo$u1i|Ul}~teeT12y9GhH&U7IP1^P*J>=Rblv1Cx)l*O}>Y~iKO`i6<4`2scob(ZAs>|BwZ*;Ytqu1 z6cA`j=Cn}~i&Lh>sXTHw2a4U6vTaj?djP0QNp&e1NgPiJ$5SB$Hl;0_)Eg*}q%rMk zRF|ayo}}}hql?oN^y>eaYJ=HnJf|DaWsiAab}Hxc$~o*qV-6?H;qb-2Tb%b6mz{$kNhim3 za@nOdfG*D0#bp&M0J=G6H$!#CVH5{@=h0<1Mcs1^q^g zZ=(g5veA;>Xn6ri?6(;9TkwuzlQp=>nm`hptj}(;zKpiyNpU8|=?+u;XXgV1Ijq{e6^Vqg~ucCD~{nw9)<&CGqWz_8%ay$u4f9 zl5DaM-ekw;Bb)5+Y_flVl5Dn%o2ew5?ayweDz@4F&Sok}ja{svlGNA-*HER@*x#w4 zl5DYyTc{*k?9XnYO4(w6XN#I-(GTDIymZ>rX?pl#M}2umec2;(_(1JGPrEOIlmego zT%Y@bNC(gm@HVKXR*+;_u=lc{g=`xE>!xqay@*jE)fKF*-t^$LI)w9-|`!dW?<`=rKA%pvUM4fgYnH1bU2)5a=;FLZHX! z2!S4>BLsSkju7ZEIzphw=m>!xqay@*jE)fKF*-t^$LI)w9-|`!ddz_k=rIREpvN2t zfgW=p1bWPY5a=-nLZHVS2!S4RAOw2Mfe`312ST979EgC_Gs(3>`Bk4Nw~p&MuAamF zWQ@~3#>u1oZne`}O~q2*<+SgjBrZC=7b%G{USG!Nklh4v@uFN3Yc@HXO<2*oS}?B` zc(OHy<;ga|xQ*Hp>=ev91wOk+;FoQE@A|+>WeD3~Vm6rY#nGh#x0E`cJR${;NCVNi z&xHtgLERgW)w{BZZI_Mha(3en6}c@NZ_8fd_GJB&k%v!yd+1C>eKM9Jtx%8Xo((jTL6oBCcj^R}NjgJfXkJVM!l#hyk@V8}4zR3N!PkY>lzsOX- zb*f)Ps^1DfSK;>{aM7Q8k-FSl9At}wxkQgk{8TC<^Cap@8+5A=4I_e;N=xLnIdN{X+;1k zowiD~jR4r}v~8w9lhf8jfxAxIT@{qPeDUz*ic3|>UE-Cx;7VOqCr6B;m9Kc*Z#=Hv zdxm1B26LtcBjinxlLbZRzeP4~p+5Kl*>FJikQ=&?_PDG&E(=6U^ygVqXI}r+cV;UQ zaJF-{?Udtz7OSDfY9se7po$A@&IME`(&aXJxorTsX8{r?ZSIq{AOe?d!ev_kfoZ&c z+P^s-2v_obNxyyo8xgjPX&=%9TQ3hJ) zWB&885ZUWP`R8M)^RYn)+>GVkq@vH=jD>Hi>H$cyHqNb$+sGapz=k-tfdYr(rbCn& zSXmB^cw;87l%67Ee25rH*>xiy1r#5L0}=FQiZE&gP#;s&5dt1Z&v zk?D?3dq?Larv&h(I`y_reSqAU{{r;w)W3j0x8BgL7ZA9o*Wc6g2#hn>#u)-c(GPiy zGxQy2cmaV42Ezn{fIyi+UuNJDm?WDgQ74>JWb+gXd?H&vk^MwB{ozaHAB_50uldSx z<>P0V$IoP)9o&6mux`vhXU|u(_Y2vag_Mok@`z!1Bo}!sSQl}ui--s`MQu%#lDs8q zYoS1E^sB9uL)^2`m(E7NK~!Gw{O6*D=b~Rj;9~UIi_w=6xEi%xr82!1&A%4yizGUt zU+ajzi9m%Mt&j(h=Z8`%<<~0ZcMzzOzgZ=}i@+?InN=uY^h5b&vQ#GbCAkwn5z6GUBW&Ce&hENl2t6Bh zo{eVDNZvYKSFhPWXrWS((>mj69p2ox>X=qtgq&aXBHm|7a|6)heU`Kx06pGkiC;c) z2}P+$bJ*A%#;d4~sJ%lCy!}dd`+&M{{P!Yd57p$;H&G4~*7}WW{Z4dlJSWJ`3EId3 z=7;uw^_@2V-Xf&|-hYO<|4jB0J~=f|=KBhtvBH;C-N2ie7SK(jt`@Bh=vGr;O+dGX z0%bvKSumf>%#cTU&|0nn5(!c9jdj`LyllyCFF|yfHD{R`P7lBltN(~KjV@1Kv|2A( z^T~t^5_4^#xwdD??7A=Xhy1!3{1RoaJ}qRQ7RoMOparx=*tSRxYNIEk+(~M>X^iGJ zQtiAo+P9T5!nhsfZ%4CwYsmC=^#3dGyrZKyvPQqAO;4Wg37VPi$w3n|0t^!bMmAvM zgx6u$>$Q#TU9aukwb!3_*BidwZ^LJd1quX{4H6)tgit^dNFad_!Uz#1qEP^WL>5UP zBr72Cs;#f4Z~44)-uvtQ^Ee#N_~)wX>gtO3-n!R!kFcoN6ks=ry%?p~6tHaycyY(W zx@TdlG8j@0hM-ODtS~(*Y{E&<+g%GQuZ3+`Fu1~9Fm2Qee<}Fh9yX*d`hl)no=OBN zP7fQ?!xmf^s>t%NYKxUZD495YmGOSz~)&Ni+Vd{UN9@m~0y`EyLDWUV8u`ABl z;mdT`l^u3FwxgQ%=Jxyv)0+!Mpb;?au@oC*BQWf-6oY4Xz7RM2`5zSu=a?>ow95b; zgRC?fR~loc1n8|QjmAm>G#QOe1n4mudkAoaS6vZrJ~Qdk@?R)FEEI;u7mrB4c*KE^ z0DV8snlUYXT#*EQiR*gZb-g=u>l)MD^ox54bm(;*1h}Es-5|hCz3wIfzOcl7VTs4D ziON`NH7>P6&F(U*ahV7{n4G%q$lzB+LSHG9D$1lW$rH+3qLG$pY+z_~XcQe9CmtFv zta@x{&fL94f^6odN_|rW6^NZGb*BirX1zWyec_m5A?a#Ly_$m3+*YNwRT+oRdi14# zCiTiE6bqZhr3|~2IAUI9n5&Eq-e%Wum?2jGfcKuO0cv`lg zL{I}~Gn#Bd(7e<*eyMR1KG2{#ml&s%7@r5A!8oLO-H%_{DlC3Ej3kG!)yXkhbBtcl675E7I{~^mx|^`(`I5JO z$$POfF=XA{)vKMd?J?nEhm@+9Dtp|wHox-7)9Ws;QZ3B>=0`^eQ#8?`+mP%aXqwLS>YzUFGT^0Yc^K zWB_)mshw&i0Cj4vPVK^aaa6`BHFZj@1fYnM6>(Y|xCy1$%E`78UDLgC)xdw7cncH-iPq2=v5L zJ@HCx+=##uuX2ePBN~BhuPocE#g}Ih==D;)UM1eQAkgSnHu~f6x{AO(zw#adasyOu zK#7+?lwwnW+C+f70F_683qjw7;A8mMfU?{Ss%{1i0BlTjZA=UTke~QWe&WjjbcN`y z5Cbmy^@XUukP?8rD3upgVz+JRDVw9zW&-3#seA$yqW_AX1+N#b)xww+pNqsLl=1K%(`{vm{1I*SZ~&?C%{HCyU`pIAE6XwW>c9NUU#W9 zD=UdYYs_p7k)^?GY9O+dS=cg5tkBb^yLLWTw0WB_wd5sO^Acd`RS8U0f*zd2Hw2{{ zf-3xRQH4r_Y$22VmY zty632)UePkoO=rwJNcj##hksEi=99asNh@`98}dFmt2+!oVSp)$&C3FWq!FT3x-W97CmD5Kh`tad{ASH4@B?!0vjPWT-FoblVw_+fWw^d~kFetz%y$KCTsL6!vp zc0m9Rpv(Z18Gzk#ZNRuzyxWOBLvA3D8-U$mQy{R30C|Bx9sy1T?56^-Vy6P}rvgxw ze<~0>6@Vx8jltl?AOtx zP7{tp>%#21aIE*Cebw~{dp!~}$MAo&Y7OmuqfFRwHPg~&T7|<59bEj+e>}TrQ`z^s zabCJw)S;pZoZ}Ve_*ml_$q1n_e#~!h*hE3p&ljO6rwhT*nwXcc)BF@Qw0#F zHicPSN9ed)Xk?X*tPy|~Hm-$r0C1kA&$Ai;?y$-`tPu+{ z&{H~DeJ5)N;4VwwWiRel2tBn(^Jg>q1$ESbB)n0FbVcr)%O`bLk!0_q%IQ ziVO{%q0s(zKd1tp&?NP>T6lX16$WV~23qE;37t%y6jgHtTkqV`q9)ShZPKO@Km+y3i6^Nl}VYi>}lHvuw5Kwu+$l z_1DhIYyMRsbh{=>+eCyH%~dkF;x&O&zkPAq2c{=0X*5LcnGN^M9&mE*wD6r4KTvzz zweWWdaL>ZuBS4ph?;=3AMb~X{;xZ0VIqNsq|EW?KOdFJ{4NBN$bCls6<_dQr1M-l?*w2jKV>fe0sv?DxHG&J3qVib`NyjFrf;qk&gr#`wwAcl ze$B*O6WwW{(sOw_mzQH@Edn{VpXb=7V~dc#9r{!9d-Go3DMT;c5K?X+#7=X<^qjB? zh>S8KvWy4|bfj}4!8ws}04$EMi$xg{dfb|bZVjPl&5h`C39vn)-X4hqW!#N$cSZ9z zRL15gyE$sayKn^hqT0SFhj-x!tWIK9CmHaT8V7z5wAXzT6@3$9-Ud*2+mbBVl5E6Y z%n_(dme(coIIaT%^~v)3WFE(Lm{7gw#G|W!zH6y4Y0sn#Gby-5$f2Y;6oVc7qnhMU z2|3hQ0CFj5F2&#}S$G>tx|w3If){~&N}5kG*f%=@#gw#|Vz3nXdk`$9#sRR48nufG zgBUUgsnG|i2nhGmO8Hu;(KwDXD&rRAyG4x#0WR)PiFc?Fes7ebh^C5YIlh>WKnYEi z(DG2I>4`N5mi!2TQkp8I+wX;SIKlWmVTFl7RIe$oU1Q+i|S(Y)>GDdC~ zY@GV`mZ$p>_?n@jrT@FO^Lr4gXC5cOGxf}m3Gh}u^Bw>V4AsEMvH2Y;qk-`^ zFk=W1ZD5`t!1E2vD*!YxTodB}LegHw(#yC3n8nhwSk=+w*0#y-O%NfOR_SI-LjK2tz40>Zpx6IRI@sOPekx;6^E~ z7$jE=YJ7D9folfpnn4c04wG^Rv5?H=t#kR<-2s$k7cbextFe&}0yR8c!>a)3=cWBT zgXNqkML+ND=SLAB+|N%Wz*GJF3jjRiB@cP^A6Hg2ny1hI87ku;Z-2;p2{7s*A11)0 zhy1euq?sjYW;MPkgUU!V`_jy#2@pv$CllbgH1o?CAT`FY-~|Iz#v-$1ky&lrX!_No z{hHqIfq#*C3<08x%uf*D`9iIonu7tVN3mH_ zY*t@+>DuS|j%mK{fxp;1h5*rG^AiMkzS#T<2B;px5+MMFB|-oUZyx~|-aY~_EHlCY z)#IR9a?q^C8@=zrsDtJ(0VWm&&i>fd{ z^{BE)sw`^kcm8`2tg?(Fz=SHxWCFZcW%(%phb`{ImINGV0hMvsl62VeBmrJHY!C zXt%QMRwDoxt?WetT(Yv42#{f;GHmi+&3Ulq{I%EW&|??bB#Ufn>^$syU|(eO5+Grb zZ7cvwZHlEfEda}HlI4V_fifFiW>ev97NE!a<#I$h*JzN8R7p4L?RHE;)3U96Y$C z-sY6GIazF7hf)kU)dS8r00y1PL8lIYG#8uZGJ-4T87?ZrB?n-Ri<(1#WvP{t>-W0N05rJS2DcHI-yd`9 zkGahNoOQEj-A1fNL1mnC>(9B(0Cc$74!02-=%W-j-1-}CGXV2F?0k z9(hE0?e5EqUw;#UT#qD|h(%H5QB`^LQ^G$^e=mLB9h73PC%D%$?q|=Ls7>=^LVN7> zJiga61%NZ2@EOlUtlvQ?&UvVF9ytJ4J*ul7JpkW%G~an*q1#ZFnep_@coj(TWjy^Q z0aD`W6cL~)csL9h&Vs;j7%~8c!;k?m9EJ>l;V@(X42K~DU^omJ2B@ax@v`!G7<_Si zylguGcErne5TGJnRzZLV@sB--Pr~{xROk#ZHNz_hV76B|+p7a0&l}G3P6V-N3cXaJ zR}MgncU+5i0@j(KLR-C5t5*)d1+VmimjR%_M-}+wz|^bQCo3kxL{|Egm4tQJPPCE} zpvuQo`3#_pLq6ppBE=aWb;c*hx;s>{MjzEkfFi%Gi0}|n<7aC829RaHU%#KQn)%jm z{?;FhpN_u%aCkVJ1%cu4Z~zR4hXY_ZJRAn7Vk?8x%Ag!5fK~^o)dV;jl%EyDTcf88 zN0h@^5Ezaq2f%PdIRJ(u%3**Wdn}PYmI(DuClX~R5?PSqWTNaO0kT3=R!ELxfC*I( zQ7c1o^|yr==bzv53Igjw)Vh%T;pURue(HE=HUeMR7W+*yV`x zG6Axq`fS2BKQ}r)H#!N3h{~gMc~k{NMBAhEb^`2((mM!nAgVhMEQisjBwcxC z{V#S2hBIxHrj3dz=#XUUp@Mm+@I2wv|Cejmjqi|jYnD6#hCXf&q>L zF8JcfRq1n8vB?ZIYN|(_>M`R>B?zQ>)M*5`=QG~(dGJmGrRee*y9jXKue>ihFheOa z0(3?|hqI)7I`xr+;O0HTnz}<8*dZN@zZ4G1D<~1RD%4vQF~t`u*fWT_JB*@Hm|6$pfx+znzj(BMhds9%?NSs4hERku8Rydq4mEkArM#3P= z_K0sg(f?{Aky;{X=BXDlCMrzVWxE{ErguO$LM$w~*-PJ>FchYD) zX^diHP`vjd~DWfhW>_(RvpIc^p0VhQjS!R5HnejsaN{z3U8h=WFk4uf8 z0I=Bf++x!UcsGN}SZsQKvFSqqzU1S+f zp93k{ZKK+4W3WV~`0uan?7PyrPtdBC(ymf^0`6TXZ#B(V(_?`W>j+IBp{>9f*#ONC z&|~pZg`JW;iZ*fOw6dIz*_EKiJWNxEX#>uSntPX0xl0LCoKVsylpNN)j0unTk9%Zh zt)RRv4oQkb&ErdW66- zr+k@Hk1wer(BhJ`xHQ<=;5#XYKa2bqvtRI_*!-xpSqvJ0n&`fax-Wy_H|NW#`Em#@ zsHh7n2nJQ!K~-#vipp4_rdFt7igLBKTn$sSuv7~RQ!I5*OC1m#@z6&+aPM@*LtP=J z+e7inL-EjJ?_#|2A^|$$nU46FEhDN}iI*zz!lxYaQiljo?xV|n@Ud$Ws5J>N%en+= zoe1!-6Snyk61GCLk4McuL*|+xgD&$^lT@imF(vkAf4#Dy;9sNm3qBKaXk(5T=o?kF zmZNJ4KeDx4pq3jA`h6WIuOsZX+qhsG3J`U>^{qLhxO7xT4`=A%%m55<)&b51z)haJ z$=k3+0?KmS_VjVv^LQ{JaN5S7w%GwFv&WU$c>r4NajkY9@6=G1FTKC|()$}AdztM` zp6#6izyhykf!6>)fp<)SHw=U^wcatc-Y~uah6+9Bjhyp74rDL+zA^c}Fp!&c`Is)^ zrs{p4?!M22cL=DAL7#JwaDg|&KYoV)36Nrzf9x#cF41Yf{j@)}F%jCs|I}&!b0EvA zz@JtH{sw03?7*M11Ahl#LqM}3U;toWAZ}lP$2(V4Xk&t`F+q)w9SF1}$XW=nDQMpm zjJb(IDe{7JUQhv+fxMtOPxL*7Qsf8a`NVzHreLTkI38p<8%#bMoC3g|pyN(39)KB% zjv0v%6ed~=6I~$1kwo(magUE4dpyy4oJesp(Rng47B4_}xx{B$5~qPOE+i^05Ym~_ z3EI*LMtr2gT4uorc`>70OsrFP8P#1z12nO{4AV>8aGAxLX0aBanyqBzm8=>Yiecr4 zP~Nol*J zOvG1>5V)h{?kIf|#&<8xE%CM?(4{nYDFXm>D=pp11OQT0<`h)`*dNSQS>~z|09dH9 zE>s0ENbPR_-8%Ze4+vYD42Lnp0XK}x9rEQ4OYR|8;)d4WX zazm^Km@qzMr4Lyh1~Y3fOn$oeQ4~lSEm%Iq3?H=eo#mru`Qo=YOA;Tm=1xM=+3i00 zb}>FXwrLauC2KW`wVIf1H)@EbM*UJ_5N`(&C^1?~jA0ClSN-vwADs;!a-iq#WVAb( z*t&>bGne(|vSWb7=q6USiPZv-$1-`W34k(IUdHM`%T%$NDwYRe4=dZlY5_RL%8n7> z6stZ(7@4-RbSuk%EH_#CO`>&gvGQ94=wj(EmI3WQz{&^2=0-2~fR#TWzzhvNL&M+? zf>NYv&_e!hJUd~QS6DCHlse37e6X5emqt$VNs8;8(Se^ zR}j0gL8)X=8i$W(sIbm}qEi%cHJy3wV&K)64-0W)Iwee}B=#5t`Xx+10ZODyi8Pi1 z%bbMgE|suL#pj~O91AFpiH|{belSt;U}79LZp<9ht$gjmm?Lp$9As1IFFcm!QVF@# zL|}ASMUASWo_y_=El`XB70Xg2WGP_PS1W9*6=T4=98m<0C>{q@Z&278 z6k`Bbrc7L>d;+}7uH^V#$x-kw)ycN%?Jxmx|7&Z@3nDz#b^fak9x6mdi)dh!o~G0TAD?}8LN)d)`{VQPzxR4 zv8x2mQ-9B?S0rG>|{2-kE3xe7L0`UcNf4OrU@IJ8J8Q$)E5`ZeFx61h#0DGMD9w!SxkJH%WbONh`Y&V_l zX0ZnYRG}^I(OcZ(fiAz;%@n&i07~83Qnv+weeTiw+~a|Azt+vvBIoxYx}wMjGG_L zt8WmN;c|v4C(Of-8WWEi$KsU>Rp_QMa?|)Y01Hit3r%BzWTT8Tm2p;JKt79)o5l0s z?6rh9EfEdKaeD|;$bv`J3m%QB3D6Xh>sIHwV*pJd6>fQjJNR|L^ik2k`~CL);>~LWjz_)6qwuy|b2Qi-eFFE?jsL9d zxjwGxxFD~am7tiF5W7l%Dw3NxHaBq+-peDfDRJy30^}u*%_G3(#Ic)2;4|dDylLj8 z6N0>^iqTdPH@{c0{3;@B)_Rs%&&GjOf51Qw7?gOqdFqpW*$>O!KP6N(L#@wHL#11Z z+FhcK;48tXs-s-CGH;P3_($g4caNZ)XaMPqF{I&E*L_eL_^6p%f?e^hpAo z($l91a9U5FCP1T}ZX`gHo^B#Qvz~4yK#QJkAwa91ZY98ZJ$;@47xeT60<`JrHUeDM zQcHJPq zZeW3l>UG0o*9}nuOuTNG0>Gew9u&Va>ar`1{*}hjVEk1Y{gni0GWwec&|~!X5Fn4I z^LQn=QPIY;ZM*>pL)v*|JFmq6i_e68$Z412v@15KP=lnn6)A2P_NWqh`slx>zG3)w z_^!UZomS(!`g1@1^tl;%o<-tS2bpx5k|&p54G9@ zZ;s`8s5}p|`6s{o&xrPOVat;5q4Ei^I9{~aPQ>TWQy8w?B1?6(>EHlqUI2&+HBn(@B-*wY>7ru{_MBnYZcJJ{0>xbWU|sBSt; zz?o~OL)Pig1JLJ?_c`J~gqMB?-S5xbo8z=%kt#}& z=al7%GFAj?T&^0|C}0S;*CpHQ(gQHtP0w~~a3A^f?7XbsKmI|J;B4i(Iqtf65JjNF z9M>TNd@(`jd95;Ks|-$S`3gE;;lOuFaFkg=P~0$4(J(Q#6rlcZlg#1m)PH~WYFzJ#jwWGT=cv^=>X^nBz3*nVY%_6{IbSWy zCqRK(RzQG4wXBc;MQT|Q0k)`RTL@6BmK77AL@g^JK&e_*N`S3u*;WE=1Wbh6dq5!Nn zDc2J*6`OgwS)9J6O&GN-G~+Mdm%cG1*+^&`&W7l-gtqZoNPaEE0A2R=Q22Ui0sxmH z{3TJT{N&;8t95g3v`EoHSFYEW>#caTKw!IGznuU(^!gnHsL<;x2vDilR}x^SUcZw7 zyY%{91gO&Mt3)uaV%gum`u9MK;2>yd1T{1wCdK2q_iESlRh$(rPi|pUTNpTvE;0I+ z7z1D(DKVO4Hf`9+lmREk?=RYsl&J;89V!~y6ktSHA83#`5TQtTkqH`fs zkz$Run7DX)RWtgkCIZg$*EIY!(ftt0a$OU5T~xOs@W7ybVBkPEdteAYFpML>)CYza z3GnU%!-p7X6aPs++V;}(eiWf52s)h>xz@Dw3DCCaRb#tbre`<-KN zeKv@$q@nveI>j|z?D9DJAj6{zFUbfDk1ha)M;8FYqYHrH(FMTp=mKDPbOA6tx-h`= zfY7NMLW+h^Yyn0ub1x*l7cyZh7X(rwiWJc>u(-bHC1%RlOTzd&#Bhg*o8dzSddMKh zeFweWa-(Uv(E^6s4x?!Y0nQjrX9#fLXu2DrHnb9_g!5*@c>>I^8fS>d29)IstMLm0%(NP35@3bZutM~#RD4o zfJO(T!I_*alhfk05tY7*o4$(s0D!d|yH<>#^!W;8aP?y1_m3-Ol%))e9JkQuTquf# zQDKLS&O-#4Z*tBzxquXAfQuX84ERf+EN!;YZKAQr{!fBq6AC`LCiIaMha`otKqzs@ zN{HxRWe&Q`p#t}KW;->rohE!rc>5jh>|dVw`!!(;lA>3n=wr)S@wZQ&Tt9H)y6~7; z4t5rCekpXw3LSb-YK0?GLEIn8a3*Frlkj8yk&!*Pog=4;4^}!9{B)>|wT zmCbTHb|Zl5eqOFQFOQ|b>x+;#Q^ID7ss)sHQ0f|#LIab`pei#MTb!pVEBwbtdv6N+ z$%BmKATgTKjH)!zO*|SJn~aW4gk!+HM%7*-#U-QT5|LsyN6+SzU^J(4@>Gr`fH{?O z5+E^^8wWrdr%xk7pQm&BbP*hW@}chU2@N*|x$G83zJ-BSQ%jAnEG67LmKfhGF-`~D zhX&)@4aRo?xMlp+E#n6OEa12W#D0DOH)(;mpYQqU$8X=x-Fr(|ab`ZMn)ztV7cTl# zX+Bk&F9z_XFG06Z<%z5EzvDqdz+Y}Q+qk60}jb3L;0*@^)1qw{?DTO9m zp$S@4RG9)*M2fv8`(6{QN0Uj{WQy(h&{JAWx)uTqndCzzsAEaxUP%UW*YT5c);-*C}yxJdx)<0AXGCjqGC zl54qV0NBqZ?gqv*bNREZQevSZ3M{RLm7NB$g-G^F6QCu=kwNlJ|-kXUv4Y! z-^#-#yun*<5Gii*zMK4GpwOds?NNJdDi!*=U3--Pn;h&WBIakY!(Z%xPbqUc%A7H4 z6;#F!=cpadD0oVx(_86;gRt7kRTJu(W~aGX46A|4=x`c3oH3~a0=J#E+fLZEyPV!G zqR<}a*dFKO;IXS*?p4ILbA!vi!38^izDt+yg1xZNw=%*oXd311vQ?nE@P|90p4YyXY@i3?6}uF z#%ms!;-=^Eo1UjZmfM~eZ+m_QzX27(NzT4@BeJS{~w@?gZ@beiMKuG zw;dx2J>d_WAl|m$Z|f&gqy!8p0oY|uhEyj*v10=2GT(+m--h7Sb|w@$Lx8qWLR$z< z!tJ4ib^_cDY43^x8dPY{M0w9dxJu1W*3D0bV|#tFZoLQ|8634}{HPswgfrjfkYqC< zI?fFHGsC06^}DRFC5s5xzACI<71n_iEfH-Cah0?+qHPrccJwR=S(;UbW>xI-qaE(5 zK-{W807y(*5|u5Yy(vmD6lI3Q%bf^(ouv9Y$%zfKx857^k@dIJJB9mrX(KghBjJ0m zW2kkEdi(aaU(8*cor;?33)b-k8w9qZOIYg?)(^m1&F|J~{tCpfJ(^$iXg-E#-Vl`; zQm3@Pf2UA8N$`Z!9=5cHeON$E8c++CX= z3#d@(L$SCS5BUcV~U`*Jb6;|K_gb|Cz)n z(`v{Rg*({Mkx{Fqt-nR0$tqHgx@KH-h+NM*s>0&c8N_yXFy>Cs#Nms3( zdzb(4^LuL4-i3_3kWqk9U1%IvXbgeVK#?(2B-$vV=Dltlcb!PlVGMN;DVn*sW#WL=^7%%w@%%+P9rc9I_ET;bMgROax#|)=OukkLm!dis7rp-r3T8= zdY8T4GYmYc^`L)d0hkizw{#$FcAU0GUpmNtrK2GlWYweDIGOk$UQ5_E6x68i9Q zT5()7CqqfE($rO2hYjwq&9)!}sG&49gxK?@+;CGKJ7S=`LvrPi-1YqO-?Mk$pRIcB zCmn=WI>0eTIiSwk3SEH(aoDRDe5G5)f|_!}@FP8z44Btk13Fa-|~krWP^3=U#lFyW6Ou%jYJh` zqNyfYiv9ZvHIvg<iak;~KK!q5D}VOK z@AT-s8zrhnN$k9e@@7iqnNmaR`wJhNJoJ_WfwfZkTB!lZr#4CDo1}(Q1zn$i(Rg_o zN|7%^A#>ufuS5iP%IrI3LF_9Lfh@H-OYH*&PSv*2)waj+T7gpRwmWy*N8#&+2pq9H zj@T2ywd*T(*A@F{9IpVS*z7iJcDwMHL7>`gsCK*Xm_eY~ZD@A8@DM?uGi2`!1%W~+ zEn-fK_<;T^J>p6i@3NvS84-I%BnVQpMeS|TAin;FQe26;uZZ{IuN+h z0=0I(LesB^0qjvt=zojMnnmW=4i%Mp*!K8g+pD;RbRBc!n|^=3R}ks7nGJ1(H`^|A zT$gB)(R}mmk9Dt4>k~w4`xxy$CiZnvM;y|qhBSIS@DX^ZQ9sng0kA?Fw}S8hoTW8o z5itu_YK<$kHjt%2t18gKLJPI(LM<%x8*SV-M4`1>Q!P>GLj(QLpu+05tO0!}G;MaD zFx-klk|JWCmmXH86Jdsygy|(=1=!Xt3(J=g!Hm8R%f2RJ7aff-N5#lQct<3tyD~#e zW(aELQo@E5A`sH7aBx<5EO^}3FuyhIz`H2asO@2Gd)R~l_B<)P%rZu~jM3s@j*_Oa zacQg>?BZ%zwuW#(eSuY7AZ`!rH@Wtk{CE;WWgIlQ4vIi^depn0JoVmyphDR;Qo3y< zoOe!+oO*I(?0ET9|I|^6KYTMFL^-IC@)c4zXH`m>N~sZ76b)DAY1&?{gyWm*W_#r_W`d|e0U_|U|^6&oZXRmj> zG$d?RmV4~WJ+L*edg!Yj84$8w^C+%))BvQ!b1Cr_09Jarm0kj#$=d%bM0R|i0!m+te*04VV33J5n)7ku;u zpA0XJsPC)@XjcT{@KFeX%z!LYjK_jNZh*}V=s=3xfGt-HaEMn1q5T)D;})x9(j3$g zvIBA1fgsL{8Fk_epI=8MD>UrBP!6pdq!*@Q8i-s Ph+QKpN1%u95!3%KLW13F literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/stb_image_resize2.h.CD8FAB1902B73085.idx b/.cache/clangd/index/stb_image_resize2.h.CD8FAB1902B73085.idx new file mode 100644 index 0000000000000000000000000000000000000000..62bb7e2852fb76c2df9b6191dbf3a0ee7a1a76c2 GIT binary patch literal 182872 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

R0odo*{OAKLsUnJMBqf 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 J=Tz^=^S{K>OQrw- literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/stb_image_write.h.E67C86A994AE4948.idx b/.cache/clangd/index/stb_image_write.h.E67C86A994AE4948.idx new file mode 100644 index 0000000000000000000000000000000000000000..c24e6d1a838670472006207cb55727190c6afa54 GIT binary patch literal 14006 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 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/stb_perlin.h.00622C51F350CC49.idx b/.cache/clangd/index/stb_perlin.h.00622C51F350CC49.idx new file mode 100644 index 0000000000000000000000000000000000000000..cde4ce7ac417c31dbd896a4c20fcd2943abfc1cd GIT binary patch literal 2788 zcmYk73se+U7{~AZ!ewW6CRSvC-5C%N0u+l1QA$m;w_kR5Aj;rCZH8;)% z+w&hK1mJ?kruNm2oheMjjjuf9)87o!hBdB<2{Zak@NgGOLJyrz&&_Cft@-4*2YG8}>~8<6 zD|&Y8iRisC-a9BFbII}rYxA!U%TCOib7$J5CA;QNImj&9dgT2l zpNdWCC5u|04~ur`S?awbL-%ajwo4E7Q=VP6S@r9zGWdFW#|3jnlP;B)ZYAx=`+45 zRBf3z0{_SFYyac+@=ra@Y5AjSPO-aI@9Z0$wW+OR#LfNHRsTG;PEt11MS8j1tux=h znURpZ?@D85e^SCz#qU$Me}Hn4vOvIBgFA>frwE(V-xI8$&Bl{kTsDm zR$<$wsJ}Gk?}JxYamY^=Yyiau@DgJASYO2O!)$`yklV++`TP5MPzNBbI$^zc`^8tDCW(0}&^*V08=4tytaaWD;t5zrg@I)@dD4C$Av^AI_36J7ze+ zh(#kFKjcZlghdn0W-OX%wqVghvlWY0n!B;sO>++xduZ;(VlU0@AhyH!p->AQAa>BK z2T@ORCy1Ri8$dMB+y!D6%|;N7G@C#)IhmySa4ku0hhrq!F{}}5iDM+$F|3JZGiJ>+ zTQF;(*@{^!&E1&ornv{RJv8@XwwLC1VB0}U93#n&VLNEn1FNUG6WC6g4Zs>`?gF-p zW+SjhnoYo(oJ@*aPOQO_9!e~Gos+~OB`(Vb3wuaruXZ9^7?iSdV`|N3a=zDssurkx zuLE@*_z@u|)PuU7=7*qu=w#9{+*o_3aIE8mHmq#JB8e6!Ji*E*GsnG&g{<0YnlFPIv^$M>IErvXSN{P&U!r0!#}?&h@Rpw9@<-n8!4?0n_GW zYgF*hpI<1yGM9sbcex+ifn@qvf>i(Odv*0Z?Ub0mcFv z;zvoa0%N7Q8<=jIdw}Vo`6(!$g12*hA1M219sqX0S!U#Dan+IoW$2IBVy+hZI}Lw; zxd$}YVXltmD&VTX-?{NM;I7ep9k}aGmQSo@Nw&RmRxHl(vi%V5CWcHH|8UZ5?1?;W H5A4_f>cYq= literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/stb_rect_pack.h.D251B0730CD219ED.idx b/.cache/clangd/index/stb_rect_pack.h.D251B0730CD219ED.idx new file mode 100644 index 0000000000000000000000000000000000000000..46378617bf59601598d12b1b72514e815b52e8ce GIT binary patch literal 8468 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 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/stb_truetype.h.07A6482B66454C43.idx b/.cache/clangd/index/stb_truetype.h.07A6482B66454C43.idx new file mode 100644 index 0000000000000000000000000000000000000000..e6899045daccdff2586996ff8ffbe8a1e66d520a GIT binary patch literal 69396 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 b4DOd#(&D(z1cTR@ZU7;}btH8_E(`zwso&FV literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/stb_vorbis.c.3F18A71DA2EB018C.idx b/.cache/clangd/index/stb_vorbis.c.3F18A71DA2EB018C.idx new file mode 100644 index 0000000000000000000000000000000000000000..0fd0df8968f976930989753c698296127a99646a GIT binary patch literal 77724 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 NM(p}y?7Bg}{x8=80yzKx literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/test.cpp.9DF026EB2D4E3520.idx b/.cache/clangd/index/test.cpp.9DF026EB2D4E3520.idx new file mode 100644 index 0000000000000000000000000000000000000000..6daec03d0881a0ccc2e6bf2a51d2c46d7f5b4a92 GIT binary patch literal 728 zcmWIYbaT7F#K7R3;#rZKT9U}Zz`!5^#Kk2=nWc;j4C1T|3>9`Whtv1e#vUpm1?sTKGhUyfr<#rb@-tv-} zGM8`Rh|Lt@=ZSD*N}I4t^u-<>sADs8jpe%NNKYP}%$ z_F?W9&FUs^6*P4g^6l;QQ+_aB2%uB*{I?RNtE0-OBY1uHvO{#m|oPff)7*`=G+ zEku`fI;{5&^0L(MeN(dQ{F2_)&!VEI|hs*nf)jV@%6)iW}$FSvifuM9y z>FzC?8ZEC(J6(OnlwZ_)Tk0#T^RsT)&L~bcFj;C;VgD@Z?B|j#9&b&31^6$nD0sN+ zcVX;|$WP2EzSnaYiYs%IfRVsZl$ut23`lc$UHEWR^(!AEi!=)Z3+I&XI@|UCj6}b` z3g&hDcv^r_Mw(Te)f6TSqZygNszC;UKo(!phD%dRB7v&eCD;vNstU55n&+&!F%2lp zCc$O}6Hd=NHZ>-Te<33eiXpPK=L(+8I=h95N1Bt3lM7-p0|Su9!zlpcNzBTLJCabc z3uq*VIEN<8$fDGoM39o=qU2(05JMb9fB~bl_t~k@7ykb}%OWlzCCMNGlVD(wL@=cg j%;emZ9FQUrF)=1)7Cs(cb~aWnPHqkXVL=&wAx2REhM@^E literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/tinyobj_loader_c.h.CCE1E6C571F96984.idx b/.cache/clangd/index/tinyobj_loader_c.h.CCE1E6C571F96984.idx new file mode 100644 index 0000000000000000000000000000000000000000..263684ba43fdef777201bc17508f501ddd936559 GIT binary patch literal 20890 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 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/utils.c.9E0AC1AFB528EC97.idx b/.cache/clangd/index/utils.c.9E0AC1AFB528EC97.idx new file mode 100644 index 0000000000000000000000000000000000000000..a5c9c2ccb53b048745a819c38efe62fda4d5c2a6 GIT binary patch literal 6666 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 XfPsUCedS<3c<2bnc|(TVjimkuNQQ;( literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/utils.h.B2A9FDFBB6793C09.idx b/.cache/clangd/index/utils.h.B2A9FDFBB6793C09.idx new file mode 100644 index 0000000000000000000000000000000000000000..486205cbc8ac232699c377ab11b30f80deba3952 GIT binary patch literal 244 zcmWIYbaQ*dz`)>~;#rZKT9U{DWQzcCaY<3850Lf%;)*$}2QTtADDbd4h+X>rUSu7^ zl9nuP&uF2W_jX^2c)@gGxe(iR@$F~Zvn)#FBf?EUwH=0vg9ql$ur?1Ek;8J-Yp^ptzQihf#?~Nd_bZ0)K=<+rIN;PG#g`ROV3z zIR*^AJaNAw|L*+(ps+NDG(Svu&zq-x8Ve-v0);gMG$didMX5Q7Aa-$4axpiE!MOGO Mo3q(Usmu%v0L#Bg7XSbN literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/vox_loader.h.9A8296C333F5F41B.idx b/.cache/clangd/index/vox_loader.h.9A8296C333F5F41B.idx new file mode 100644 index 0000000000000000000000000000000000000000..0e60c48441dcbdf871a37463c9b9ad30fd7328e8 GIT binary patch literal 9440 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 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/vulkan.c.EF7A63E0933C6FE4.idx b/.cache/clangd/index/vulkan.c.EF7A63E0933C6FE4.idx new file mode 100644 index 0000000000000000000000000000000000000000..217a2a7d9fec0abe4f1efa4530fa83072845f024 GIT binary patch literal 7146 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 J)Z|Gx{{=YrD{cS) literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/window.c.0CB305403CB68121.idx b/.cache/clangd/index/window.c.0CB305403CB68121.idx new file mode 100644 index 0000000000000000000000000000000000000000..4a4454277b271f78a10e6ebc82821dddcbe9c9ea GIT binary patch literal 43112 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 XpMUk`8Lz!Q^QBn_gjZ%yee?eTalGzU literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/x11_init.c.87FCA90C32F5E445.idx b/.cache/clangd/index/x11_init.c.87FCA90C32F5E445.idx new file mode 100644 index 0000000000000000000000000000000000000000..a793cdff971d1c6ea93daac957117cb52c991419 GIT binary patch literal 69682 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 D?iU~1 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/x11_monitor.c.4A77A94C2FF11C1D.idx b/.cache/clangd/index/x11_monitor.c.4A77A94C2FF11C1D.idx new file mode 100644 index 0000000000000000000000000000000000000000..6334e1ce722fb77d08ec550ba24ab1a6776e53dd GIT binary patch literal 16796 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 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/x11_platform.h.91FEF7ED090E8205.idx b/.cache/clangd/index/x11_platform.h.91FEF7ED090E8205.idx new file mode 100644 index 0000000000000000000000000000000000000000..cd805f1d434f924dfd721abc1f064ecac002a608 GIT binary patch literal 63788 zcmYhD1y~ea7sqFJXJ)}&cM%7X5HSH2JHYOGZLqt$TT~FGQ$Pho0YOx{1QY}bX=y

P+^JdTP-%3$4w#_@WfBUh`G(}My`rpxG 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 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/x11_window.c.DCD2EDB15A9C6D96.idx b/.cache/clangd/index/x11_window.c.DCD2EDB15A9C6D96.idx new file mode 100644 index 0000000000000000000000000000000000000000..018a76175b9ab7d9eb65e2c891f9ca12cad3ee6f GIT binary patch literal 83022 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 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/xkb_unicode.c.D2CF3715482DBC0B.idx b/.cache/clangd/index/xkb_unicode.c.D2CF3715482DBC0B.idx new file mode 100644 index 0000000000000000000000000000000000000000..aea8bbcd8b2b84b5727893a68f2a249df457fad4 GIT binary patch literal 988 zcmWIYbaT7H%)sEB;#rZKT9U}Zz`!5^#Kk2=nF|;h7}9|P6?3*uvCqG4AaL~k;*1v) zc&>!L6JeB#QrGKQl5ydRhgstyze`s|GC%lBZ+%g&pQ`RAT=L-o6Vv+-CBGhioG377 z@6XUF7c1WJm`cu`kel)4@rU0s=l&_qZx&F{TYY-<)8AjuUVruO^RLs7vV!dH>AYXv zzKCJtp?iESZCBay=l*rms*rJe=$sS%#b$#^g!?t#OUVl9OWf4m&weeoJTW(~enI&w zj~Cf7zdng}_g>n#aPr5pd+(NB%T#^7X7=X|SJzl{m`RD=kh(bG(xsCt?R|1{PfeLK zq0gCL$??|ht4eE+sd4v(3IuKbl4B+Ca-)JwrSx2-iyLPDe`#ntnqcbkRB_qcy|Y6Z z|1mr$oVK~RGB;^1FuvX_PfFd{tjEO5puoT&>&E294JLpxU@(1#VUFIcq9!&5Nuac| zh_eisfJqm;IIruGuyigTgS-@jtc#$FIGBJ*JNzwmZvSbrl8-?VDD5ifDgq{8(zjTZ zWvBC8`OCu~4m7-nowJ8sMoxxPMutI>iBU{Rf`OqZHLX}3n3`a&WaUC}9gl23yJ$bV z9NZw;h3q^F*+mij#q5HM*`*NtW$ePs*kxe+#$X$nSbrx!MjqK!?A)u^6=5!ed7Fs~ z#k(N;4EotEVESR+XXXNX8>Wi~=nUzF?20gDJhF?~6&ACr!T7LX0h$g96NI*9>`Ken zRbk4w)_gc?Gwa_opzC_r8G6_`U=lEzQ3@JpFlPh9D<=`eDK1Jb28JmEqijt;NaoI6 qv)CDB7-Zne7?N{Sazue#VPR1gR(1|HJ}z#4Azn@aX&yml5e5LNyJ+tK literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/xkb_unicode.h.73350CFC11A68654.idx b/.cache/clangd/index/xkb_unicode.h.73350CFC11A68654.idx new file mode 100644 index 0000000000000000000000000000000000000000..86810c29b70222677d558a7cb506082c050199d2 GIT binary patch literal 326 zcmWIYbaS&~WMFVk@vO*AElFfyU|_TekG^NIT=dI`qfJT_(Pu@imP{aaMH_HCBf zm9+D?#Fg{+e)j7uoBq>!!)%51@_cK3J}_}B+kYso%uSL9y6YCJvg~x8D}Q+yn1MVH zV3pyNkzwFuVq{Jh#UUjJRtY4y)_gc?Gwa_oMjlof p1{n^RX)u~m5@H%mc~NRkB8XjFlw8aWVz6%hb3;?(6|W@&0|3g7Z3+MY literal 0 HcmV?d00001 diff --git a/fonts/Inter-Regular.ttf b/fonts/Inter-Regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..ce097c8256a78e54c70e401c670a7fab0a138621 GIT binary patch literal 342680 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

=(yz@O*K8Sz}a-+D&3^4H!)XVVw(P>=y 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

lQ(+UtMG^Q0I@Rc#`D+JaW)7BzTWE@ju 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 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/script_engine_tests.cpp.FA7D29E2927285AC.idx b/.cache/clangd/index/script_engine_tests.cpp.FA7D29E2927285AC.idx new file mode 100644 index 0000000000000000000000000000000000000000..d60e8b37beeb667d8556145ed04dbdb394543a05 GIT binary patch literal 1624 zcmY+C3rtg27{_l*UyNJm&6ZBDX@ zVwq+H0|*qEj%_f9Fl2KCwCG?2n43|M0n<1Y2f;ZyK_@e?TawduH@WAY-#P#9|K0O_ zCn;w4?gR#c?8=R)EY2&}(hvl}$hWLqS8$esAW3utsWfyakC)6VI19h5<|ZW1)==pO zOZj8U`l$%Rj_{K?&4I!X;}V}O$4#i}b{$SHK&US4kiRa?vOcd)TAF@sbxNauQlau# ztymk%e>@YM@m>C{qMLGKkK1ffqkqfT=;ZB(&-J&rU3BtqJ$gNmFogHU5@$@0nYGTt zhWuj%#+px$-xI8)M!q$`D9M-#ubhrz{msgZeJD4C4tDfMZk{>iF~Pai_h;2-m)BEM z7ClW8kHNTp#fxJJdl!aIMmGm_eG`7Vy?-uzCA+*Mt95$1`o3;L7dBYfDpZby<^L>> z)@{T^m(_&Qt;bCUCOashMggXmD;{kmJp>H@xT= zU`8<$p$G%^a{FK_iKE0xFa!eaaLAX3F0n-sc$x~WFlnwV@v1?x}rlWv~GcCR-u*dCf zNQ{dC^hJRLm)MXDmsw~^s6W-*e!7ILFPFx3ggG(5r}1qFr{OlFq$wStIR*k~0T#Ma z{dWIm?bQnM2s|#&4cZYv#Z|e%5V%TK%zW42HT&{T`j6sUbB$CKaA+J3RG~mYQ*dA` zPdn_3b(i;(30OGG8;S_vfqQsE5lzcYS=`9DOp2IlW|&nZR*S=+Xg;G#9I)hPq@Vz! zVK@|RcQZ{CGPEYLASjC39GZ=?ZOF^Xiwm7FAm_+=R`TQcS?KOS%;a6qBTvi)@#4v0 z7P26oDjyg!M{zGs_dovJ4h0Tu2g|RZK+2ZlP=o?swy%Z8jV*^Xq4w+KH8A%L))3w5 zo0ZIcvy!=QRxeZ9nBGCGa2-k>>XGfKG)5ON5TICF9S0~ literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/script_engine_tests.h.3AFD5906B4BAFB23.idx b/.cache/clangd/index/script_engine_tests.h.3AFD5906B4BAFB23.idx new file mode 100644 index 0000000000000000000000000000000000000000..0a106290f3b6e359610416f52000067f5183e0ea GIT binary patch literal 304 zcmWIYbaT^SWMFVk@vO*AElFfyU|4-{GIdd!mo4M zznHa)WDHdJ4l#D#XVyJFFKm{iuFbpyciB8QmvmTMQOYvTR>FJyWyTja(nHw%W#K4!8E#g(~9 zPC$FJ_>wkUnpzUc!@vsUfdDfzE3+H}CnF;R8xtclYeBYC^PDv|rtvUa}kHtBNPe|&BGTm}XJ D)u~v6 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/scriptbuilder.cpp.4174B604021EDCA8.idx b/.cache/clangd/index/scriptbuilder.cpp.4174B604021EDCA8.idx new file mode 100644 index 0000000000000000000000000000000000000000..9862c862beccc586cf18c61f34ca4eab7d7a9180 GIT binary patch literal 21350 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 Km!cw9m;VEpf!EUj literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/scriptbuilder.h.01A4572D6A536522.idx b/.cache/clangd/index/scriptbuilder.h.01A4572D6A536522.idx new file mode 100644 index 0000000000000000000000000000000000000000..0cb04bcb31ae3cd6b3340ce03e196acd90b9a469 GIT binary patch literal 6380 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 literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/scriptstdstring.cpp.C8D72FED91DBFBC6.idx b/.cache/clangd/index/scriptstdstring.cpp.C8D72FED91DBFBC6.idx new file mode 100644 index 0000000000000000000000000000000000000000..b5f5287ae7e58790b3e566f291b64738e5a55e58 GIT binary patch literal 39170 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 z

EEToLXFWwNs|a3YS9g5P8vgq_@4oHbUi==#Tjs{NaLc#%Wvpj^p78*S8IS)oMb(kC$$8?xr6Oe<}VB&6G zhlolLQ;46wa0p{p#E@7$@n!y4TF7P#rKyX6jMI;4FZH9N>P#GW{sY9-rz$i$I?> zHeVD%&K}S^*ztqQKAYw~F{QzXM#ju+MD9Or31yeNCx`{ae zvvdG`yXa?$)|99>A1WrbF)&S`a~djNq;&W>@i+^IQ+zOi4Qd$l&PEJb*sv%h`uu=t z4(v(xAuHEn{uA+6H0y>qSUk#f?il5e5?5GnF&=401S>M)QV=u<<&!X>u}L$^9qfc> z5HZY#9fTPLB&V}WnH*+kcCtP?tx=Y#@k_tE&QDB}7^ok7(=fh=nC6~wqp{iL$}}3i z?&MS71^2w}I%1vIUH4MD$7?X=W*`U}aDj*3$9H1>jEH&ch}aTsuz<(So*mH_m^+** zR|NuTY3A@J$9!tjhUipWjV=Y+bj44V`t{lKG;59&*yIkwCbu0iWVPtgS0AZqsjfmd zV^5kZ*_yz3U1>%-9EXT_)gqk%HoFG496^cYWvtAbYCx4N>c|&@tho zmdesjhk-Dt`q(i4Z&8Pss3A>-%tV|E-00|Eg4kXgg8R&}{-=;?qmL?qno;#U?i?Hv z2*kyi!VJQsav&}i3&(XPpwLQCkH$sLyPHx(s3?*8nM4QPN3z5Exf48EToSeNP4l>`wcpb#f0 zG~Hpxo-eCz8wFL`#$E;jCp&{|JuZwSki;+ND8>j|uy<;UD_CcAtIz!T&l~>yXWqf< zWd{f+>N0($>~8~q!~dz$Xekmcw-3EE$_#2T8|7a??gH`dEM(j4*SJp}I2%)tVvdAf z^f#qWN=CyrSVlk(BUoDxS?%P@0B#lY0ZvIjUQ*DfLI$FRVxUv5Op!7y|kFhJ}|M~nUIX!ScEs&&>T03(kr(m8Xbxq z`r6buOK~zCr8?yZps{EdS&(a?UqW)Yb~=r>CO_ZjLz+sm9mh3GkT2j1VKd9g7BjcCWDTH|4l0BBd|^!E-1R_F~xwaQqE+9RCjSS2yGPemTx{>dDKKH6ifQi&8z?s@eSQaM zk7vg7X$4|PJ0UDgt0R&X3E(_~Uc`RBvosMwa^iGN$st$m)IMG3r_K8tdrn<${B~@U zZZ}>@TX*2Pf#?oBAh&EjKc<9O2uSH%Wh#shox6KWRddR4;*V2{-al&IkAQ5ZrDj8uQJDn`{wsH<=E1ax&Ugdy+i}BTr&U z(rZj`heIF&4fq1dC!T*d=JEhKa=5XeIa7Op(AZ@kaz%Lop5V zrLJz9NLCV?PCue-k1UCZM<)uKl$6syYP%QG{{8pk?Ovio)ebsTfR{v89w{M=Ai^Rl z!%E!{XGJXt_=;8*PG`Ci%4#q+K^}UhYL89FQ{p=l&EF41r(kkm5@UQwr}qqocnK$( z6P(?sfZFh6R7jUbg}A3pvn`m%ACeEwPJMLuQ-;r=k73NnFn+EML{8>g(`^mVqeq}e zQys#PAqzObj;1VmPIl1ZCz52XLY#9wE8|yS*QRrj`;RDAiXye3FTshhR?kqVKb(9R z`qDR`i#nO*tI3H8OjJWgBPoLfSQ0Zhe5}Y@dDEF|Hs?CkG_hskPO;_Ip)a5a7X(hz zeH&gGRojPNp>UTNo*eMRcShPXTySJBT(gj+8XU|)nnjA#EL=*BM{=h?*l!L`u`JK{ zLvOvcd$-}Zu3il9{-WWo*b*CV5AXtBI7`RCz6iV&vj~4ltY+vt`~sy_X2J3|N&Oo5 zBa@R7G1@qYt}GxK^m0KHZiu-Yt$(Hw7g;2xj3Ve1z^sW@X!E$tf)QAV&g2M)s`168 zoc;~KeoFbv>BR4=d+-%&pCAR1(FdtSpi&)=^n3?a3)Xu|5(NZEJ~gL4I9;1gghrU? zN<>%yuGf%B>pcpJM_Xl6@a#4WjKAI9Zb%uwe|J1o+G?KyY;yASd8`BLZ8g!<>2yG< z(I53LrykCH;(u8{@~K2t87ZTH9=RSFaz?NrBWDSsIZOduYzChdB&N`c45Y{vN$dx{ zd@M(}^F8V>bYq+Hfz#K*!uDuDvK)LHFeDg>?;MM*{eSgYr?1qXWqkEirqO1adRDK| zVb-68YGUUjP6swcxQyV#)&zGXAEJmMDjw}5Vvq%tVLiaWpdgceENzNhCRF=9)Un3Q zFC7{>^|_}p^}C+o2PY>UM5-Z}=_KJ#j)`oS4&tRU2Ot^_MAk|Jp%7j?LZM+Zuz83eqGZ;%}KQ4@&BM|cI zk28Gc`@4SkyWLNXZ;n0g7wXUGanpE`cW$0EIXV6V@U1UOzU3Xi2;&PWB@{cH$Z$Di~7UQqwG!N5u)l6Q_1h7jaKYlD1d|Y__*1A;kZDO3?-2OdmH?f(FW<0n}M=1d+RAI5R;u|LC>s?-8Y;2r91u%RrTvY{aG1oR2U zrP~)5ZbNaA4aEbiVU0871gEDko3|#uELIN0lNqm%^9$fQE*Q945uy!eAi94!@5vv z)EWojzhZ~AC&b%^35&X2*gqZUGBU%?3HQ9PE8}lq@Bg+!ZA+<-11h&?XT(zQ(QXcD zcskPs_vK`iBCP4=FlRVs1FnN<4A8jsiG^))Xdizpl}y2@>LRiF^o4{@b&;zeA)&y< zAKRx~a{AizJv`YClW>}yr|lry*~j^Q5WpVwEqj{L=uS}I#`Bnhc(22d|DrZDb@`4w2<`0J0Y=6$zOL$GZlrml?q25Yd7gb+UfE!>E>;kqZNC zCYjZyheJ&_u%X5#>}T_t)wto}T@$az#eRLK^qg?kvQ@CLtsdn=Rb|u6YLz80s~IZZ zjs}3)E&t_$t=Mew>{&(@wyP{VS5-8dVN^S>cOIjfGX6MhiEjcAVb;dFDTBAWrMUtH ziT*}x9VHP;w2T2Q#EO@~R zSt+|La!EE%P69C}LdQ*1#ys2!1C}#k4D|*SmqmyqXc(zHDcvoSc~bJu6lBVwWeFmG zHO;M|FU=tm5*icwi;BEn6zeH1qRLAM+41Ik^(qT<+5j_P1N2j+J^89JQ_~Wd-{cD| zOU*&K%ewuZAT={3{rtYTjt$fopr!EsZ$%lf4yl_oNmUJT@3jS%DjwC5vP9(+LEQPl{ zhVh}HapRtQjZLS%(<*7@y6Yw$gx};igv==!*a7~|j7e=hEWL+oJ3|%33mk3gFF9A3LRd+t2_9iUTCIZz&pa$toa>eR` z@Z9G~w*&QRjmgDQk(?$Mhy1X8m`@dBZSFCtnhN=z*mJM>vX0JouZp5scTlZZN#eXV z-!iV?|F?1Igz`CE6&?by1UouUz1*gg%N*m-Wqudw=&|`A^q$@OHxFu~IzWglN>SQ9 zzI)g2f4_V8_{g4n4aZ?n8jhhB8Ubi{U|jQ-h5Nz?Y-)0 zlJixJIZ8+9>3KHY9;;AusV_{o*Fn)1WE?zu4CUjWXpb1q8-IR}gz67}h+Caga6zy5 z8}Rj*hA;S3NVoS+d|AWWqfxx20Pf|eO7gjgb!C4qGS97~R#1WYT4sjV&3rHkRFuf1 zTadCU;fmW$zBg(mmMAQ{@iR*tPDyqu(EPEe>*zAnY#V!D*P+#RAF`ABR`sEl4FFoc zY)MyVTT4TIb!8wWpZ@t%T;#|jv>-1-si|(mEB;d}kAX&jN+2&0uei^EIetcO%PFYJ z^X9nSIo`bLV6ZknJ2%yxo1I@13|8l%WnjhHp5|b+KMQB%=H%BD1Z!}HJiDquyK*S) z&3M#5kr@hQ&U}Rn(M@RPLHgUP{wy|2(!K(};`zv!Ivz=ALAw$vY61aTn*++?LE?}J zZ8uE^Q6NTvls#tW=!$kNY@={#am)aWvk3nk#D`+u0@N#JB*Qest`w+w|2{57zQ8}HinE4o;j}ykud;wgjS(!_F7In0>HaAkn zbx{b#C37?Tvihi9SWHr(WS40o5|WTWz_BExIHXS}@`*FbP^Ui_rROD0!75O;+nt@| z2gT2%avZJdm{-!OA&i5Xn|tC>KaIR~xrOL>J9{XSkb<7)NpMHnsZcBNk}wbkeb8pG zE2!2AhH@>U5DZjGO)=PaS;@1HNgR}46t)Gm)tpczDXFU=cBR2)2OTf?(!od(XInOJ z8d|qzpr5!2GAEkqYb(o(p{$`sM4A&dKG}A@oxHd~AUvemLo}OSJY#tuj0TM7^o#kG zd0AO5t6dl}+|u}eS7so_ZvIu)L(8e^_4ND#uae+U47r)oar3M_6v~R9p7`(6rYimi z`VMJPEr$K!P52&?Ss>zbz~TU@6A>aaj1I{xIY-)$!sI}RCTZ~+URW~m5-A-{ui5N% z@*i;Tu=?qJ=W{nDl>rUHZhb?%gYHRq*7)D>tcUO{Y3J~!%TjpyBWK$=vRSr#q;bY0 z&2idr5Il4?0Ii~VO4n6=>OW?|^I7$kDW&M0iB90b$$rWI${#^xtbJOCYl^0j?10+- zAcGJA!boGKcwjbykQgup6p$~1v7BlPjLkk7eR8yuflZt{7(ugC^!t(RHDH27F9@DP zP4Gf;y`yQHo^^-?k7`el#7(BrqK2aUP*!ee?b`0*#-czd(^nu;)CyPkFSAQZvkQDJ zEgb{&tuV(p;78mk{OND&{UE!ruRo(@P9~IRV6Alm46!^b68#H{ayi1*D76w5^cmVG zqx5QQ$dHX$0vd-P3L1gY2`IsWGGHT!c13D4sxG5|g00ntaFX^YH=KP72P*5G^$vrP zVE1Cq`g#|y>R#2>(%e{EU0RGb*oZrE!paCVb@46=f}VyZ%FZM_h4oMis?4SZNyBD4 zElUNuG8OhfIF^yns->?WjdDxX;_9N}%$<h215kE#<{E`HjnMb9S!WhuoHorTja3 z1Itsia)RELmcsTReQm3;UpHSjOQgO0&=(k+*3uGwmA7>rO78pE@Zo=Gf!q|^_ff$Z z1tWMoz&?fX38T8dPI1J=ZLBfJOKp&KvEuv-+mh2)pfE79|1?0sAs+xMH% zE*0`to(pe5+V{iZI8jQ9RzN0lVrPk9HRKTc#=|*9zB~^JRMiC#u5w6p!Uj{&v}A2X zYEBl3TvDJ)#Tm6hjUOhz4f#6ox+N#i6VITQG!+(x;}4KTK!M2QRpaV<_6Gk7e~8tv ztF&$A|N3^$S#%T6%0OX7gy(`fYj_Q9=Nfg!ui@y%F@4h>j_$t;*p=U)!Jl>Sy;Y~B z5%!Nr!a3*(v>7#~WaBd0dmC7?Eg5O}Xwzajn8J}oe{G^2?PC%Cf;ah;W zFIK)q#@SgxOuZ*OxV|xVJsNk7y{{WYBGGFF;-{52^|< zTeNwfft(9q3eR=Nld~rCYNVZ(lb!GVJdrmqNagAIf%JHSj{iQ3+T(xB3x`G6KQ;Us4^M>l6| zGl*y<>Bmf#Pqp!>HOKh-=?m76@1T$3{h0Q77&PvKzs+N55q(GEPR^G!w3YlCK*w5 z6A?fZ?x%s2>Pbad=UIc{r~n+yc@nfJhy-Q}e-@n@o;?akeH@imghUE9~C*8YU;7u$u6&G!ibP!eGfZ2 z#7*@@P2K3VSXWdY^!tN0@tXS0P=(fDu_-kp`x!qmtIn}B?|&F(N>D2R%e3&%Qk z?b_9Hv<2_<(Qyl*Z27M3@Le-B9PLh)lr9~qG}__-kG z<9MNT7fE-Q1*P|3l(}c%$}4edSp7bJh7bDr$<6!-`-Ctl#rl1I%r8_dxKFO^Qi?Ei z;C80tj4D0E?)GEtZm5~TZ%4k^k8rJ-70au0LC?5cOEI{Be93WcKng#k8(|SCe!TcH zz@~nh0KA=UsofSZ9u;?D&i?@O=Al@9i>dK07*2iELJf-RC$CaaAP}@(BjGH>_K$%M z;sbs*Bh+1hjb05L!P<6@!-HK4vV#e`6alQn#ix?YBoliPtNK`WAdrpMxc(`w&&$pU z1ah+TqMtx9_T7)*`C0P$A^CJldBDS^k53{D?H;u!D*6-SBVyGTkd5WXYwGs6=Q454 zq*rk+VBR(ZIeJvW^D$hzabefO@1uTf_sD+zTA?=M+DGKIW>zgnquZ}% zq>s!u_Y~qrH+_5GrbFuA@kV#n;F{bl3MQYFu?!kb#}XX?b<~Bc;Ns&+Ytlu*$&-ZJ zT)=ZZ;4v{Bw~+Co+#Rf4^Z!EMKx6}w5+wPBsd0!|&HeD|qgz)E(DVDr$vVfq;C8~j zaKpF+2iz-V>R!MtjpjbO)3y)eUj6+Vj%&r(u?CF%cd?HOgB+B0wD6lA75 z(H*i-|57Dxh}N8merj;v2`~L0KwAZJju63xxsK1K!SJGlCrJm}7Hselac6HY#(fEB zuR&?V-qcUm_nx5EY91mQ2Fnhuaf(x-Y#nr_&WfbbFM^y*(|#C?P=y#6gZ=qaB#JZ` zE!z>*H_ht3)rr1=T?G}+LUB#I%aPg<3i#3x(Foo39l&s&z8-^e6qy=tqtpsKTk;oF z=XNF=5IrCVfhy)kywpe6AKJwIc#}&|A5V{RV2Y>6edQWFCq9Tmazt|={GS7tU8x*+ z>n;4u_+&bNee$@t8MWHuaUsWg0B{O6NZ>;40t%pZrQsK>hM7NTxPauH;*a7&LC&YH z5d1zf(A!kOU+)O?4wTUF0rN*DOD3}r%aRaX|MHP%;;nihzO4BglXa7wke5OvX6i|5Ezi^y zW;gk*-ZC^bMMYFTaRbkT6^ML8?_FCx0dS7lK!q>L#AyU)!iI z$q{=eZq{&{Hu;IkPk_$PE-x8zy_&{b+tnxcDdMz>>ml1*Ca&i%Ll!Wbc51Q>j=hd! zhvczcv150MYdGy6X4CH2vESp^L-N?3*s+_$H6mFa+Z#J}A3s%gjM_`zfy{}kxXZ2Ca#y#K_p4}vbt zrc0y8qO=Xw;u0VQ@|jWv`RoC?-bx}1m(3O`mnl`z)gArR=JF#-CFHUbcy4aw%re=W z@|aR7r9Vi3p#Nn`G32p_K^LA#>YQseCWk4-Q8^6PY&`Qdw6;n9(yxL1g=-#>*Fffu zELis9xY2aEi|(kyk&Am?k9(R34`-C0aGQA9iS7}Vo#O9tM!AXbK*Q2yCfp+?GbusH z5f4LVLRXyy%1bmebIM9eaE7d;LRNZJ(pc3Q>%z~a1;o$)oV+|HBdPPrNJ<69_5ft0 zZU0Yd^DSI9QYxY{QS_7ed9AVp@ZJP^*7`rsD;IHHCQ_DYGLhn&tWjQoJk$N}k%u@H zK#iA$$`XCO0~JkZ8SZOOwWoFz<#{u7SqLP!wo}3?!F>9Cwrk3nBs1 z@6m94N=zBS9wt_Tdmt7lFD1_idjr?BLA}nNTDxHh#PzD8!b&CBF`$tk;qwx})}WlG zeIw!}xe78MY1z7Th+9SlO$D;mQyrHbQcgeryyR1pS>pD|&nZhlyDb_{Q>2h{0Lx6k z)Q4Pf0k?t^2f56{jvmvbDKwmRNok5CDZMF1;PvceS8rpbxV^)btP4}|veeo5VZ3ZJ zw+t18Ty~X|%RFqsJRSAN^#(dpIy;lD9TV7MEInRknvVycNmlCrswO7&o^V5qPo0vM zG&xCW)ylKXCq!xGS*GNue@TYw)PTU0N+C)x5}y!cfN6&0JeOcK7=iC7UbfPv2#j_? za+O*OdGj#j%?0yby;;Say!V|r)=O(@vK9CK&{=p13W!L1D)g%-!AeM0QmP;;JpkF^ zqfyy`y{=S3Ryu)WH^z?Lr4&O}dKkw(7CZKP9D7I}`*`fwO-eCjB|7gDv11qFyjSG0 zo8~xnbL`krB?uXauDvC8?4(d3E4_+ix5kbgRVr{E!Tia%V@q)CCLFs>JBF3|JY=-v zkiE_zN5XMnu!`{0Lve`x2PE!PL1UR8VjA5k6^EyB~4=h(`GlKS&@bDXz5yV&-6*%^bXPj%K9zt`U zJQ(r7uY%$eaP7O2vz^&^W|BYO3KQM5{oa%$rsMCPGHX`2qol@a3HaiM(rS04w}gC- zjD+eL_^gF}T%?`jb5Z)al@JqZyQ)C-aUHskfs30 zXH0%ye+D`hqRuZpL)$EYXF{}cIi49Uq$S;{dWC{n&jao1&%5=?(aY5J^E~f4p;RAqRzwtXNfm+*#LSO(aIXOiahYcWEdK5@QwDKgP<HHjvB2G5N0SCp7pIDegevd&+Ce@tTD$P3WzSDx?aT@FUl(=HO6=)*1>=2&-gd;%3~Le9#S{y%aEu){&~;gdDD3%k>443rF314 zEPz+Wo%lX^<;hA*Qs-J}$*O=ZpiTwdno;%=gf2Vhrcy+P$?Y7v=%Ui#$1}3`-Fxr8Lf^3rFW)Q9 zofw}e4#jk+3H6D!>-9r{wK(@h@Yfd3i81W!E*%04%%O+ zWjZ2YuokJuhH03>J`AQ6vVm%jDJN5=*E;OTKc>QR&V;xYsx>Y|W7kw8UJwum6a>Zu z&~?DMYv5OZKIemWw-GV-mflTcc8|$sOyD0w55SS$i3joVvbV=m*^$Lvu#pGxJ!_>; z{UhN_Vbzl-M1isg7z?m!))ncfE|8gJ7z&!c8F!Ic2FesSQ|m4!bEMcX*ouj*;H(Ta zp!~VstW;E$L|?^Bo zFn5tGs_znYZjg;Z6HNohSi(#6Krmb_IOV!z-P2ipx z{vah3q9|i_30hvG=P*iUx&u)Yh^B6a*FJeaxBll3{p4Wk4=?hCR`DxWsimv3q?f6# zFta{K`fAormJqC{#)g}N;4VU#82w8_evdqaH`x01?}#12U)phjNRyEMU4h+>>Zx*r z73Y3~E!Dq+8)0+QjwASr`}OY%YvC38cLOWsd-U%{wuXOF|88Q%{4M>v87*Dh`gaRU z5f|#;t!$aNUjLrJs>M(A?{-#A1^6U94xXok_3w$S9x|dljzJU}Zq&bX)K~bL{#~$g z!>{!33QIF4EZRGA=+LgMzODQB9XfpQ$kxNV_U~J?cmJVnqtgy`9^AiY+dkj6^N)<| zJ>=WFYsbjpBL}w~S~Wr^ZW%e~+s+oT{pj_-#Kw~cL;*LScZ_}qzO2j!WC^1g@hoI|V$?Zhka zq+RliBWw#R$5s2;c{n=zDRUi*KDTI&^QWL%1!#5vj=g~RAVyP;@Y_mOi*_K(Fb;a3 zIil!&%Mgwpf9>our=H@Qaqc=?Nn_rH5$%(hoO-SgBR-78lM#uX{lE!flJH#!M}HL{ zY{07)uP`bP)Ui>#wy?QI`OiVROU}gzo_829j^O^=fOW#o9vs^b$mX8sLxAWYUimF~dmTY)<)|0l0n zB;h(F@3|GvrWLKtIMD)e1#LypdHZpehR^xVB0jSpRH5N>8#^EO7{Qgqb!b+0$T1R~ zZNsru_$zwHE%;8evz=r>`EPO?7Qen%Xh*bn(+}~P&%TeX9bv#oN`PF$E$n-c&umCw zuyY67!V}q-c@o-oI5C8;u#fQ+7Gwo%f=!~TDH=XtulWP&n51C=Z{r@G&YnUNUnbAu zUY^aK<~cl_@zX{g}7%Hr~!7yo2rFo$M!k z5%1!Qc{lIjOZZa0jQ8^8?Bl$T-Oo;d3H}i*rjGaX6?}lz^Ofv1HqKY^)qD+Ki^$S- zd_CU)gG~c_fe*2tvYmV*dy#MA=kRm+FyG8a_!hpEkMeDNI|{TnvL?Qh@8Y|$TQ;L+ z@mqW^`#L|5@8kRV0gh}@eh|42hxlQBgkQifB z+kTuK|9VtxF}{41=V-_K7#wtav<$RFY-`B&L*vDK~Q z5A(0_NBDp8N7+RnzKi+S`8U`H_+$KW{sjLf{}#KHf16#xpXC3=zr(-FzsH~A-{(*B zXZW-1GyDhaGWGzN#@pCh*YfB15BZPSI{st!Iy=pu=RaZB^B359{!{)Ue~JH$ZD5z9 z+e<-g^x@z?nq{CE8K{15z1NG5}9i2o1&BY&I! ziETuGr~l#aut)iy`Cs_|B4g}t>>U1g_B;L${w{xypW@^EG@sxqpM-N2E=^bu48n*u zb!cCW1PGf*K&M6rI$|Y>WZ^{iuS=u~w@5>LcDl$AnIa2O$k`%Cktl`?S1QWTMY=*%iYiepYD6u1n%9f4Xb_F)7~Cvc&`YijT^=Ls)9g;sAv(n( z(Ipm(ZqXx_pg-X<(JPh#Q|}?I4BN@!{UgzKwKy;5*Le0#0SKs;xci$ zxI&DH4~i?rRpM$y_FOBj6CV=SiyOp;#ZmDQ@lkQ3_?Y-OMEjc{o8KaC6`vHhiQC1e z#4&M)__VlF{D(L$J|pfDpA~nDd&K9&=fxMq7sb8eKJg{-W$_hpzc?Wt5D$un#7Xg0 z@v!)sctrfCcvO5{d_z1Y9v4rDZ;Ee;Z;L0ze~Isi?~3nnlFMc9k5I+?!ikHOC#LvYq#LMEB;#cC=;y2>I#Vg`f@muklcwM|9ekXn}{vh5I zZ;AgAe-v+vKZ$q5pT%Fq|BAngzlpz#e~5R*d*YNB7pK`VF(Fhj39~c#qEMp)egzY{ zO;{AGVp9?nyW&t1l_Ul6PD+a6Qc@MSlBRf+bR|Q{RI(JWlC9(@xr$HmD|t#l$yb6( zff7;*l_I5BDN#z5GNoLpP%4!wr5YuAYn3{sUI{CR;Z&NGW~Bu_-ZrIOi6|XPr?N=t zQWh)SN{_NcS*k2kdZm2tM$ZBdONXwJ344TBS+4Xc{mKeuKv}7*QdTQ#l(ot_WxcXN z8B~UpjmjqF9OYbPSlO(MC|i`R%Ku^QUEr%as{Qf(oSeMQD7@9%H&*)wacS+i!%n&+OGGkbyAVJ^7H} zJ!Y@jXMW7=Hn_n;= zG{0zWGQWho)Ha(B;e_Ca%q`}Z&8_BF@RpLN-LB2WyGo<^u=!PUoB1_!yZLo$8xv?sJDweOj`&F^a8(spTwv>#%B*4A>& z$IQLvFU{x8e>G2nf|-8f(>9N?1v&)~d7Wtp;m?b+vU3K6!Yp^&zX#YOP|8-1&HuH61H>|EZnV_G4o4IqeFpB7aePQ2T=RO>GCJ8%^2+*3H%o>lW))EaPmo zW@=lshqP~Ko2`#nv#fuyW?LV%Znx&(+C-1`tkrJKv*ue1tPX3TwaDtUx~#?49agus z#Okqntv>5xR=>5>8n6bfW!7?Qg>|R3()zfy%KC)0+PceHW8H17weGR*wLWRxXMM_A zXMNgQZ+*tP-}-R6taH{Mtyir-S+7}t*1m7O zZvCfq-uf@=4eKw~1?#WYo7P*_MeA?Y+tzE?e(l)kU`r+r&?_Y+Kk_w#UxK z=WufEJUid^+CJNF2kf9-U>D*Jmm+((U2K=wAv zWskA1va9W}c8xvG9&dlZj@VHowRH1I=dd9MV??^ZC`^AfnIBW$ZoWo>}I>g zo@lq)ZT5BcB>Q@Mvi)IuihYAU)xOc5X5VB_w{Ny**tgiX+PB#=?T^^_h>tzn{-}Ms zJ;$DFx7+jV`St?4!(M1FvODcAd$E0o-EA+id+c7j&;FR*Z!fh6>_K~(z1&`5-)XP3 zKW?wGKVh%7@3Pm}ciU_2d+dAdPulm{pR(84pSIWApRw<^KWlHWKWA^WKW{%^f5Cpx z{-V9f{*t}fe#qWpf7#w@f5m>-{;Ivr{+hkr{<^)x{)YXC{Y`tP{VjW!{cZbE`#bh- z`@8lY`!Rd3{kXl)e!_mz{+_+x{=R*{{(*hae#$;%|Ij{c|HwXKKW#r_|JZ)k{)v6m z{;7S;{+a!p{d4=c{R{hq{Y(3K`(N#o_OI+0?0>UQ*}ukWVz#zUyHEQJzNdD-c8~p{ z{Tm#=I;X9*U($})zqL=>zq8NSzqenu|6spj|GRzG{tx?{{YU#%`%m_3_Mh$7?f!@2QZYi5iE>dPt`H-|m12|_EhV!F6l%n-MTTg7c+ruc}MCH_Us79SP2i#cMhXczOue6c`uh=pR2 z=oDRIvA9EYizT8*^ol<5G0`uUiUBbwmWkzJg}76!6dxC>#3#gRahF&l?iOpsJ>p*R zNpYX}lvpP|E!Kj(;xVyTJTCT$C&ZKDdt$%%zBnL$AP$PB#3AuRaajCF91%~8XT*=iv*IV>sQ9Tk zCVnQK6F(Qn#V^DO@k{Z%_*ZdK{7Sqa{!N?`zZNfw--xDp{T<6XvIcv)qODD>%5Sb^ zKf->D{e<)*(Uyq{Zz3G=S{UbeP4$d7vCndvVp&Z~+UNK8_GC5nF6!;+xFf5nwSE5J zKu2!N{I34_gG&~6cdW>1SuA>xluS+W_MMa{qSk84R>DDAH z_2o`V^N8zRwrycswA5!^LoQWe(^bagN2$eo;ysieni#T2rRn3BqIBpPqFrXWo* zRRv9T1tpSZYtJHaqbu2ooSBK7>4|KYiClCO9lLQ6wzS$ecJ}u7C{s;jrCXg?%r%j% z-Wtijv2(CzQG5U3lJ54wfvg)jYh<0)rraBsVg?>xtqSumIkyx}z+~Ue}E9b4X*1jd3msS?o#ujOH^2T{;ZOy+WBQLjb zUT#svWZ%-?1>@dAg(YrNYTuStJNvc;T^(5U?OG~sTh!matRwd$=|E*p)TED45Tj)K zNG#6QZL1fvNNmomRHYKPji0|PQkSdJBiQdslnCBb%FIh?5G+0{z4|;Vk9aL1;wE^} zTG8$@SyP)*skx5*DEo2tlhQ}a=Ynq{94+7J2{>L;gW_*$W}oFW#k1PkobBA!+B=j9 z=clcdGe4d01ys(WgOn53xH>Qe?)pR!zKYI!T*>966|-CA`!f) zqGVoICw+$`Ih`~qTOV*Yb_x~?rPm;&fuoUJ)h-xzl#WJ}(n%>K8WDF&FPeKN)c}J1 zt_nm1@10H+BUHwZwo+Nhh>nucCgNkrAWB@tD9QX;~>nt38zbxMh- z8g&y9C!U%xB%-R3C)6AX{A$=rL{;aNh^Wph5vA@3;SR2bxkOaWsS;7@kRu64&lsl@ zWBp=|e#{?Zy<)6ajP;1IUNM?tK_2T9apZIQG1f1}dPN*QM{g&;PCBe_gyly#y$Gih zVL35JKTa>g`ZqW}%g6hN9AXmcJtvZA=5kT*JHVNb2ZIC;0tq$UjU?2>5VJD1nZaJbP{ap z1nZS#{sillV7(HoM}qZAus#XaC+W!N^b@RKg7xAVTO#S`?c~=QmfZYmyoDiAGa3ek2m#KCGC`< zctawqwQp$`W>3~E1evV}p3w=&x*l)i_J`a1`r7e2x@6vhcH@RYW9pzWvkR|#UGi<- znAT-Z@9ed2?pm~@-JH=rn01R1WlrntGF$LWTiT_PX==!!^apx-dY9&LiiCKOA_3Vl zK^4yO6~ZzJ$+>Y!2Ts|L5XtTgB0gqvaFu9FTMp@;ZiDd_+51Q8?RGN8Jmk|}B#mJ& z=;$73&+1@PtVDn*0|&?yUD6bHkSV&!6iR+`i_tS^tmw+>RrWCZJ9|0hn7x#YG616t zvQheAkokCk+PyL#*;1~`jD#HJ18zhGvj{?bj5zFtLvR&?RU#yZQd1yhT(NLw3GpDa z1StL0L_ZQ&6My)%Ih1`eUJh9dAZ7~690ZHOXl(-~AA`|}$#}i;s5Qr;k(fd;2bX~@ z%A2S>YJuQUXhI1{L@6+#A|~PrqsASJMw1Gqwhfe1QNti`mei!URH6x$XoAC9RahH& zN$SL6(O5#ED$%4$G|5DjCRQ$F7Vs)Up2}vjL18Mvq)ITU5=^QDlPbZaO0ZUCvQ}lX zR;5>~(yLYJ)vEMrReH55y;_xCtxB&}rB~aWy|Safcf52w1Iv45Vbpt;cC8>FyQizC zgP@#_u0@@4!X9nNUf8uv64eAC7O7VTh}2WB2Aq09_|)scSB8(&Q!fTwSw2!vy%})o zRpB=%RTlL0F7aTUZ#)4~Ckf;XbmB#p!0d&+gZ&IiRftcjOnghRGTEa*rL&}}j1WZG z?HOFsPiYV!(~tnCAwiXff@B)RC(|H4l?H(-4Pqo?Nk}$>SfoykZjoj+Dn**r=n!dU zyVS8=a1WZ|XS>v~UFz5_bq%sFhkasH5{$@MLzKF2X*ojj9a|~Pu?S&aQcfBm%_>z* zv!*b`nnGzHf%3$u60dV7UZ)agwd6wb=OP9O7SG5P>Lr}R$H-BC)K1@@?se7l=anIA{L3(W_PTZkDdu{x+)|- z(Tm!MH&`sAbhIz%;Nn%2nOG#=mNUN>BOu<2mv)5vI{LeM7szF3EbA?xg`AeA85CCZ z-eEG4wl+1TfKNkztWH&)SY55^;OgpB-qgSd8)Fk=J?24BG`E+mVkQZC~v$xrdpCga)*q` z44H@5O_&4y#+)=rB0`yrSfXl&3KZnyAh{?YQ!8NH%@fX~&2fkMIjp;5=~5Cf%te@! zq82f=9jifV6^)pSNzv|(g{-oKD4_B^0yyh#3tX9IQ?=+lcuL>JqgW}OU^>vTK!`~1 zX~#ktbVtX4QkX3^%uP&Xm{J9+l7p5p59Qsps7Ix$s^%Q!5ve4D{u$#Jd>CJ6X}>UQT)_e=BPF!OSs5Ict3JFdV%83NF0W* zikEg^P9_`moD@X5k4&NIfHXubK`wV!nU2UH4Q&enCsZB;ClSNllsRe53!O~6OQRq~ zB!x*pQHtgOL@sx*Iqw1}JS{4nW_kNkw9Kxhcg%SgKyikp$Zmrcq^N4yi@J?;otx9w z-Y+{-Zd)a;kW}?2>ER(ET-8;|t}s{DT~t>Q6uZby=1EG(6_5rgXmlE%^PV7aMcy;$ z??f2pijcOmTaUpW3^GgS_x5*C3Zq;R(m_LPSU`qO6%s`(&7@@p`c+_BgCZBfRq29? z>@Ho7N&%D*M|BB!H#yB+sQBig=W-EK=$tgM%#~gAhI7&=$q%LRp+QCNCPd6wS&KH5 zy2-9gQXma|b!vGgR>$*$I<;&AT)ijMsnvSmb=mDb7&yB-y7*hMKMZj{^_9E=Y`tZ9>te%U83p&OHA5$w>u~?)fM^&!0 zO>5asJOhmJj4-D5v!OEEnrDu&)>t+~EFGM;w1Z2#KI!RL(l>A?2sz!oi@LClgAJW* z27CMSy5y{NX$Spc$%fr<Y{!JNX$R6|rvaN|6ojjLlNC}}Q1b%X*q z>)hncuxLlczsWUW4l$DDlva!|# z^I*(SY9^Yqp{|_Mx2xBfm^#9MI9!No(GiNVp|}uZT&S@IuJR4FUb+2(<~`Uw(AC#{ zC)=eVN0Ixw2bX5G_xJZMAMB%`XhU5N;WX7`Qhhd&7W6Jxbt>A>peS+{z&y2zGOu@_ zQ$d4$3mk4$!=hZuQMP)Ntsdo4jIu$ZoXIGcc9i>rs9H(I*$>tJqTKOC)rp{3w536* zj+ei|zI>(fyl%=!o`cCeq!6io3Xz(tyr|vmSX8ap!smV|qH0l`JJLF?RdsCiIxd7d z&R<=dDy+ITRcq?nR6mmBwU#8WwIs3DvY=-kjt$&F=_h%uCCO_o$@)5*L;GA@oO+V$ zY?6DoWc|df?u9PCdR0Y|^{U+_(R=j|xWXHhmdOUCWwL>_58p1syiISqtt^zHEWXmNubkp2{kB-AQ#gDV9{Lj_5;JnHJT#BzY)E zwzTG;+4amD?C$1{G0AN*sSbxAg?g-UA$Y;O-W4hlZuLp7FG=oQl3cz?F5e{25|TW7 zNMg2tH?H<$q%;_wV4b3Ib3aaBHyeJuTmvroL`>uCF2gx z`HOQ4p84k|zsEo?j(-K9uCiMKZySN9}YWKdf(z>1vZ2c4D08 zMM+-UOx8Jc)&C`VVwkMs`o{fXlIKtIn-J8->zsUXIjT)-*pG3wSsTM{fa2%=G^sYN zVMms)HhICvIL{xGYDW}wE+3wECDl$N>M!f7b~I6M9X_ttJONIsO>F4Jc2}F^z&Sm& zGl_H@yE%L;Pi>lmpYvVId}=um>9QU?A5HQMD#Jz+jxlTWH0R?t~)lx(Yqi6QLm5inIM?Gimrq>n(8l6ypE$SYINLGKdc?UN#@SwRPAAU##?{U!Dq3B!>RFZ*j|d6X$js=k_0GJI2|rac)O( zu4i#>pK%_+;%v`2*Q+@9W4I23^-*?=b32Q3{fTqG8RzyA=lT)n`V{B(ALsrl&h0Yp zEa!4NjB|a7bH5ko{ulQ)sPvuk;(8J1b{6OQ9_Mx*=kkwpy^C|d9Ow2Q=lUJz_8#Yc zJcWF&i#9w`^z}@^R>L3T+8#XS{@(kxc{u<`dp_Doy6+mwL!e@_w+8upt`67 zZ=pC^*zKox{yr=cGeIor>cP2gfme{;o&}WSC`*jWb$Ki+F2O?ag4}r>-Q66AxDwn? z#_OB&=eOh4(g_`gLr!x1?U>$y+ZB4;apK(P#<|VLdCZA(TZu zGMeAv&Tt_nLmfAFV9^e{yiWFfc-L6c*3q$mqYPWr-#gehlq-y5k6kNaoA&M*?U-`4 z%Y|W%p=xw}gWcIXxKzEi;B2s>^7w}vtQc4Q8$NqLcvPK?h(*;Qn^>I3hj>e?uNzyI zF1m_dmo`U4mt&wx75`ThAkav?;p5v;Uw%g;ruu&6=bTb zxC8R-aiD7et%jM3mfqPjzZ2&xVASgubUS2aHlD~w>zfMET@DOYw*>Et19Dm5U1jBM zUn1W>v0Nb6qNoreu{P?I;MWzawW*AScUrU>CfC&G@XD231t#hU7xmq7Mx@f3lY-O| zo=mzbMN5aKp)_AfnlHV^Ny-P?2Zk;e7N?n05Q!R@LepuaAz~>^v!oO9$>mD5#Y9ZQ z(|AUP3nV?gzeBvk9GbIRL)1K?I-6pQxRXF{3Q_8z7{x9^MxsF{AgynqLvpY4dL=Q< zQTS-NVsFu75Rt8|1?g9*F(lTV1IAOfEM=KH} zDd>cx_drslbb29&OR2*c2`F@e+{BbFPN1tUr(`){>10YB(hy%22U*4?Xt;~uHbkMD zj!H+di`_&PPXVfn;q6?>L{uNKr){ES5}w`!E+ZzcH!Q)WUyy>Gtt=87${=MFQ9cDZ z>INK4Hc6MBvJLSwgzCo4cqPa#bO#PzWo-N_5krWj#GWQ*WUPE>V49E8R|ZXQW+_9cj=-J6qI5iWBM7?4?dlA|a2Lrf zA>^W`K~iF58h7P5BOfY#b;91&DGqZLD2bvyvapNlVovX$)$$ugt$MSG@EZzzo;0W( zl1Pk?P4f;7aC#$-@WB@Nb=h=~e}3(cik-;s?CrgyeO~V}%#KnrX+~TKB&acrCe(i!^uM~~dN=4-uM`zl0rr2|N4}j{8-WBKf3>ix3$~z(GA|@8ZCz?=*qZ97@QLL8%YrP%>m2Y{eco z`?R_QoZ4h-MEzs}KGW4nNZ@fV|B?~qDZ5jDms5?HU`@Sc$`teFX)PLVj@0q}3m<&k z45{u3)6W3D0hEv8nS&djbZsU6b!`=HG|;tA<5%8s2AX#!d*`~?s+-`_htPLaQ~>k z3ir=CP!_hRBM zrtxs2MlIZWqXF*K1~kMiOdo{XXtcqdgzx<7xOeGBxHlO$!@b48UBmLWCAhe43GN)+ z9I6}bMmya3#sattjfHT#j2^gs#vt4~jXU9f-1s4+@F{~f%|jw7n&|_!hpNW-Uau^HY|x- zCr-fqll>>Sf42XO&r9PL2+hDP3U_HHZa~-p_i^zwT--Z=GLn}8YxriKrpd4IHUiI0 z-Kg-{)U5}&^8jUULJBT?#Vrb3H6KZVRY6^XTNu8A*tnDocN2}m9sf4&a!cSAv^Lxl zW=w3GGD9oHVnh$__A!>U_urv4F1cgL9k{b>1!CaK6^OZ-{k6D57v+W;g@g!N2TVch zp@X{3PNqb6>?2k}^EAzBtjp&v>C=RxVKu*;%e~2q7(22{Oh=1XqgPvP!{?*?JVG+Rtk3%?kX}y;7j3v9SfkX zkR@Qz5kWk~c*@vrcOg5{`o(0o$op6`xAc7JtEF$2Ucz%8|A0mqBRojs{Y%9{so<(! z+>NnJv#D&nxPjtn+`fdbdX_#r1-hx~4*5O9DJ?J-P>o1~z=*3NKhSo=|`(wB%txfBv_P7-HoGsA?sC^Am`&xz@ z%O2F0Q%m_cwUkxVQa(W~Wi_>wyKwQNR*LTd(lZ#g@(cr)s z4Xz9NUvZBk#%TSd9HaH$$T3>~ogAa}Gjfd9|6PvJ`dK+f>*r)E*3ZlP6ZQX+_b2Lq zkt4PKS2xT6tcG;V3c7!8RSqj5tc#%SEoh%p*> zG-8a#EsYqXaZ@A4Xx!F_F&g(ZVvI(r7^87pBgSal(}*z|cQs;+#(j+#qmeeoXx!R} zF&Z~FVvL3!7^886BgSal+=ww6GX{*&xVsT!wDBQ1MjMTCj5eC&7;QAmG1_RAJ&$pn z9CI@}+6-1xY@Zmx7A%>Ap0LrJQnT#ivtH zI<-`&)KA4IsdV^C3R6(XfztUX@i??_hLqBYsE3?O38@$aNqLZjyh$43%=qDwYPIKgyPE$4*LOYDKpAA2UG+-Bo`u{G3ku=R$ypiIrNYU{9AP&9Pfx?(K zF>SpAg^@1D-Q>`U(IYV*`XvQPJ_R}X0G^VUrb(z6y$wQPD~6Dx_lGD3`aN7pU*YgM z^8TLH!l*S|Cncn6Qzmpu+FtTW$qJH^QC}oY)fWlL5>$LB+ccko!YL`?hzymQ7VmQ) zM^oTZ@*xU+791$a(rLv9Qc#*Ep~DoKNuwB<@`lz)r{=g*Q~JqtOY2LoEuC0888vK1 z3R?JXsQ7s|Ep$%CC_d%TichDYR~#su3YBT77$ucXXi1?1g{L}D@v9CbX`IG+hgSS% z3cBP#B}NJgIgm_E=1k@-yw9;l3UX-$4l0@dyZzEJRBe)}W!jn3UFc3jm9!K0@6}Vp zqP8z%NT|ds%ShJU6twU?pi>S_#*p@tHP)e(6gtp*$@}{;!YRomh9jjUljTMbknA=605Ag!pKr`ua8-q1=zVf4r)mmMgS<3J@f4kT$Mw-R59RuXeU zOHjs2N;+;DDv=haG+a{9IyhaKYo$R-O35^bCiUZVXFIf#c`2yVfn52JZw4wgym2e2 z6q>5PF!k3GcG;x@7)l!{4Wyuz4pf>BP0>o$q(Wuhkc03gnFhBHq`?rzllO;0Meb15 zQbMH;Ei^I(jd7sxtM7(nx*Yd{6B>Hkfx>wXT}3vEt? zKAeJfNXdAnmF#k$@V%6pEGb!nx0V7b*^`2v{Cg0^r5Hn?c_igvD(;aKbku>;F-nf7 zXzNi@+bNePQ_zbJYKr%HM6FfnO7A|(6ba|wq_p-C<&7>5mfm6rd4gLMN zl#iD)rKtW-(p3LP5OS26hHOWQ28c@<5cRQ$c`39C?z1F$Sqe(i0EPBaXa-HiAUbME zXv6;kLM;hxpnOmdEVWX7vDE7Qq0ob=Q0UBjTcPQ8N^@HZdL#wy2lPCJKAM8kG(eoA z44R4|^~xQhw;WC-G6hv*6XlaOAsHCZuC!x>{@4mGM30t!hvZax-F?=wTwNNezZ&``;)u|in` zZ6JI~Y7mxCB&AD6epR|ITh)U18c7W|BZe3LBuD48_MlExF&(KC1F5M$mF`fQV;32! z{?d}uHqFe3;&YXPffQ-x8}4_cgjYC_YBN+5sf9{N($t>{m2jFS+qC*i&w|3M9U5ve z&qiEvD-gd@a-?bLo*_+3r;!Pz`xli;Iy60-b3yB2YwGLLd}%1WQOSTVH7ST{oWx{G z$iXH^fHl-#y61A!oLstSsXo?~8hS$Ym!?Tb<;Z0N)G*Y#_iK%Zp%1k|r}W+L=ZY3a zjdeob4{~bLyZO@c-W^wJ_3qU&Cx%M*-IBwovD}Ubl2&+kx*4>TUD6gx&x_Ngm9BLz zK3A=KkNHNbq{FYM(m=W?n(TLZ9+sM4rD^Y3pVOMkwx#+j(A1yQiXoILLmu#7)XR3j*cOH+xKDnFy&H-~0+?$L_xE8rt2KM$Z zpTwsMq&pVwv3IcNd-*r-B#9#7lkZ?3{_-&-16a9cHsHt20NlTl`!{k=vO7_7n%Mcr z_dfp!_tz$N^)K(H&@*Nqh3i0(9eF9mx90WB7s!1J-+`B*+dv;qoNti(7RQotPs_YtK1S}7WP#J<9#hsJ`bi1v z^RauW9V+uGbPg zgW!)aMbRZ^ttDqTm+ZhzvOEM>udn36u zHJ=bW*9^PUTxb^{1ZlUUONVulXM3<$ILYXo^+E@@4%TNwMyr&_?Ov+fTBF zG?IpADfBriiyCsrlB*Mclr$ep{5KJ$hHO|vWmH3U_&J5%p=?OCor$48dch zRrQes-=_2=xQcjci1JHnb3cMxR?xiw_%D8XZtOL3zlGfHrR=m~$j6zLw2~D;H!!AYO*=zQIduyM=RD#)ma?tQF#`}+M|ta$1zEJpS)k(enp;5 zvtF1#e@UPH47sOp`DWC532w}K8E)J<2RC884mW9CfLm+54Y$tL;MU{Y$hi92&cm-p zB6bjN)Gme_v&-Nn>``!&b~W5uI|8@Pu7z7~Ujw(nZkCtP*^}g5y7ttCxMj;eE-&S` zXOKIK+_~f~B)6N~esWikyBfa->ahz4%=L77`aGLGD?Dr9ZuYG6Y=pbbvomk5XOCyU zx6yOhbJTOfa|-ww&pFR|&&6yl+v9D__GcHvt;inZZG<1mu7}&0Jt=!y_RQ?L*`0Y~ z^2TKMWv_s{CVO4>#_Y}6+p>4&pUU2oy+3bm_TlWK*(b730Y8&{E?@fRvoGdoIi4JU zPH|2}&X}A?4kYF@=1j`(%bAulGiPp2XMS-`U(Sl0H96~YHs);3*@lpvIeXyl&pDiP zH0K1MQ#r^x{Bt?y;a<$uay_~J+~VAd+%dV4+-KZf+-N+j9GI zSLCkAU6;EtcQde^xqGDcx%+bu!#$dNBKK7889?W9&%?c#r{#I_{CUNB72t~G)#uI4 zYs{MjcUs;|xO4M5^ZN4E<*mqD19x5C#=OmW+wyki?aAApcR258-ub)}d8hKuok^FjZV}4`)B)HS^XM!>}zZ33?{57!By8MlBH|KAIyEA_e z-2M57^N;4A0CXn*T>km|i{AZS&Fk^{y~W-NuPmF07ZSabywkihy>q>t-ahXN?;7tq z??!NL_HOg;^zH$4*n8A_!h6bl#(U0t-h0uf`8+`N8{>=k>V1vANxo^mnZCKc zPG6sIg>Q{-oo}OWvu~Skr*DsMzwfZ`sPBaDl<$o1obSBvqF?iS{Cm`r|ET|H;JE*U z|CIlX|D6B4|6)K3cmn=FaiAhFCJ+hK2O0yD0@DIB19JnNfxf_sz?#6iz{bGlz_!3n z?-Wh*KA_I_d0&!e`+Q^M**@QZJlp3xEYJ4&^W@n+|4ezd&%Z;S?em|P{hhv-T-7sw zpJ2Q{fc^t=50d*7xrfO8A-RXi{SmoG$bFjJXUP3AxzCdO6LOD|`%`jhrmFvp;4hOa z-~MzR?_+SkLhjed-A3-i2`wlL7bv$!MV-r@u}*mIK4STyA9t@{U}cFEx^Zy7vmeW@*~LuI2Cy( z&J?ZD?$JJp?>c@4C;B#O58!Kno3$-C+xInm^YI(_D&V)YNAa!Q$FzO;KI8Xs&hLlX zk8q;$sP;2_<@XobFSV2S^6YQ$)ve#-d$MP>SMf#O|HS#>ziMx3f5Qplcko4Gfv*tf zr;Bojma2($QZoo;UYxO34?Y9lz`JJrapijehd}rVb zzBBcI!S{OS;!C{?@Ri<9e4V!&U*zr6`|%y#W%vf~N}O_9t*_D7;%wo4`Z|1P_kMi? zzN7m9Sy-=-r%Yk(5zpZSDtzn%$gx!S9$m3?kir9{ z?3XdUg7J~;k7Bx<0V4gt7{*y{phn?1A3@>8CpcW5&z1ZYj1Q6LbM*15a3AN}YcalF z#m|46{fmn3e_i2dZDbce=8Q5O{{_a`PJV}<r_-o8J?;r9hz5hWzyxUnG-m;{g`9(@D`Xz1ps4Vg66P zWB&mTU&is}*?po&CK8x|$jNh*C{E-UJ-O4!Er`!jazmfTy z8UH8iH|(I2KkP8e{|EWaTdVkUF0%h7$E#;OCop~uPH5xd_!}I~?Z(IU&mF14 zv$wLpMe*eZ8Q;k9POzNk6`u1phc9D)faz?n?8S_8{<7yXAKTIQAj{jt@;5Wi>HAn8 z-@`0tJICj7!ncw6AK>uy9G=6zhvlwfzSYdPSm7S-7d@{rUnldi-o9?edpNw0@qUE| zxqO2>KKK@J_(J7-oP2P;ecX?@_*8lRAJg>>a5`*vPyKuAm(BL@l(D{CUxPE5pK;%< zjB|hEo5lESPUm*zXL0`>Admp!ZU$sgn@SKtxIPnkDC3%5;%)g)c3t2Cxoes%IU@Pf2aYN~IGyP{-r8Ib0-PVTFEx%&Vn3*S>rM7A zC_iwP!z1k1D?k5bvX9|E=0C&GYXO6y9{(DK*7;TcV)@?=Ob+A)%INoABjpSN??NVi zohI-;=M8N!I^wNmu?q=oES%t^QwRh5w1NO8<$nM*I_HmHiWCmH!iERs0iWUGZMBsHwrx zv0|W`njUOM&DMjpS{!eLhqWl&1Lmitt6|?Qu+Kzqf}R~?bYM5$_4U9`trPBc6TMF` zPeUIO6dFeQpk{s^^o`nlxa-X=(ltDA?=`S;9$0OBU%J|@a93dUKo9hr-;k~mgWGM$ zw7Lyw5?E-Ue+VqZ+JYXKYi^US{QYiVmXQnhLG2@OXHe)=tsU?rxhE1>rOkr7%=|js zYqVS7*6J8P0<|)Cfe6~J9;h~#OBZVvdSH~+0k_P2Sh}Q7v4(yq5Y$VgOA_+Te!LC6 zY&-$?gz-4&n*2?$|B$g4?gaz=rN0k-hK@I1{3aUjok+1@nsohdyz>XZ6VXrT1&Mdi zlliBhU(qq{7aAror>lGKLPn$;2#B!84t;o^h1aTeS8POKN9{v z;C=A-f`0)1F7UU(-wC`2K1#T#89quP*a;tL7Egr_*+Iy=0_pfR1Mb$0;OyW6xbyIf z+T$oo10x3@aU7wyYKH&KA`fU&G{fux%|Oj|LMI{gbg&V$YY}=U#kfW@hMmD&&Irax z-sfOn#P_ug!>|2SUUhagRc>_Q}WHi%8-FoCrSGdXs?1cEq^~~XNYz!;?{!J zmM`s8BWWgTXaFhtk9l7LZ3WR#ivvBd_={L!G6D;T)(aZ!P;BK7fHsY29|P@L&B$Lc z>=0-P(8kMr_;-Oe!!M<718p49mVq|0_!`h)KT$*Z4S|*z9z$F|Xx9-s9YMc9h~tr&dA&5h8-i+t32^FXtR zhQ1mt*2sHq7$l$%khVf=^+UhmC-P8cq~CE-2|lEo_vkR#6mQOw?+VaPBi&JXTR}TX z@-Slf4glMmhqClRZ=|~(wB6tnd8XxvvGGkx$yMMAH0kBJT6Dbz@dRAn`Lk0eFgHoM0*w3%em{| zo&oK+c@N^k&bccJU|BEOSzHBO7K7G_vDfg=m3#stiuVQ3W){FM-sgxm1+-l#^X}Y9 zplu`CXwWvHmc5wg2km~MRe`n^aYx}T&%jJy%KHFlJ)ji^(2BhaK#P%nuyd{zK;7`p z1T9LmshW{t4G-;P>h!57x-;{k6?t_xg#E2+4viIjd0NO^-ZY91=z&2zHor<~tVHR& zojnt@KH}Q}zGdK>l-~ndH~1bVzJAc^^B05G3EEePCOH;nkAb^@;$prgIkJoM=YfX$ zY_0~Mk$<~p;P>Uv079Q&i9V6&=RuETC;TXL|0_iQFwysbUXeY@cMa(BMwH{Cj_BJ# z_xozH3qjumdXr2U@*mVpUnzFaEzs8y|8Y56#(TDz_l)PfAGY(~OZ3Uazg9CnFL^I` z&VarQ^cgH?0QBd)uXv>Xol1_Vg`7Un5Be8+4uigc>61X82l}I)J>G+$-%9il$)5rG zR?jvsYNme@(fvek1O0x_M((LYG^ zQqX66=6X@Wem~J~Bf3{Jy|X=2JkvnOn>0%08gHV zm%Ge|d7*p6X_-73dfp zblaw<~P5+u<?ZTZZMV_1Gpi{z#eJ=?u2;^H&i^1`zfB#pVYsHyD7e}AJBiGAJm`H59vSD59>dY zw@nqipp6P#bWRuq_5}6^4hN0~P6UnM>cFXBUT}J#J6IGP8SDx4<21sV;P}Amz`5X& z;Do@v!M5Pb1(Sn2gL4Dx1LuS2i?MoE>9W|0bM$%ffcS!VP<&Br5?{gzq=&>7u~mEpH!^J#UlZHKH^d|2n>dy9EwM{{TRbYh zBX*1LipRu3@sv0uekcx$ABiL4X|$V>+Er$w+4N7B`-1iXT+H;G_?hlS3&y~&fBv7I z#xd<`ssY6vJ0b?!#H%yfA1Y^wup*7OA@%|1ND>QH;M8Wz8;Mvl( z&|3kHq35G89eo~f%<$miZ1ymWe{#PA?}_rQQLZlO=&j}ZxgMO0XEAsN;G@S1uEcY% z!iTK^j5&XBBXCKBkJh9IF)tbRApGrk9>wz{p2K*K;W>#gncj=ce+K?$;OI5w%17{R zv~5epFL?$&WEB|jci`Eh!V1ub7Zl?`z6y~40*t!_jR@a{2k8ylk4MHmf#)SW=Mav( z4TJmwShfJ~k_8x(37-mhCZ2hCy74T-vj)$4JjerP=X$|TJbUpR#Pcj3$Sr{W1+Us?QxYv|mv@E%`WFg$Xk~MJGmtf{tvZDku-I7E2t+7#Zs^lEpH$n#1Ci3u$ zZoOg`9^}0OI)*}cD)FGyL&&dO4GN(=L&#^S2hU18_u)Z#g^_yW0eWbth}~zTID>VmqMNyURS1- zA3^-vhdm$OK=CJ0dzX41B7D46g7C>j+rz5}AIsrmsdq5Uu`;}9SrJCeAw;7)`o+O%kU>rzJB6QQ2f2a z=7qhC%kbTWyYTy6l`k1T2s`93F2lDJJR;Xzk=_K>Ay9u(2P-uQEhOikHVYMsJ>Ba;cgg(9uWMuA)lINkJvV1_o(fo_KrHD*`+lF z&xH1l*fZh~=!ZufA9Y~Vu~9E-_LZeqR*yP8>h)2VL4Rh%^P`Q?!O@t1hc*->LR&_h z9Pu*fuZ(zObZB(-=m~%?ggZxHJ9_Hq+X25Bo;rHo=>E}b!N07a6gA*tnb7PqPg&9E zm7~{>-U7I|ta9|jqj!%+x@BX^YDXU#{rqUiEUPbT8+~^4o0USdDsw7BW8bdH)2y;< z%cfLTR7P+^TP*lo=*6;WfD+-=1zXByAarKg!pf1AF+hvUR#etkPD1F&(D>kvvQ?n1 zDcevvu~PCqP`0gdR^?(qJIW51?X5)b6RIwIG88O(22f$BBDksSC_>1D)?H*D5zvqUWl7 zwA`vZSos|IjNqiuo^lT$E3`Lwwj4PMi6G*a`vDaOpAS7;UWh)dxV*A*SLFdf)s=@s zd6g#sjlbe(>v7 zX7-rH)elzh(Cn*v93%S}6Kz?JI@Z{! z**)Z6q3cOBE`8>X}X16QeJ)#*P^`cWnK*e#s|$ z*EAn`N+}O=5yPrFFt(!V=-3GJu@o7DnP)_Vr`r;w%=bm{9N_f>I+&{)q~@Ws_j*~eG97J7^`WbYFE{hzPTvVJ8p~;~p8ezIu!I@VLzgvvD8c zk3}g~DqAFGykxv)yon_YIa1liuZ=(A9p-;bte#-*^}6vE`hVyoS9GA+wV)apjZr6Q z^$M6AB~Wjf3NC?D*@ZZlJsc;qOSJ59G3eGaZvD6|<0g;0b=iksSD7(0ZXU9q zl@i>y)k<93u04We7wbJZO(DaVi#t(8J}&PoMr;pGfoJKtu-`@_VbscXBCHb9Jkc74 zcOA@!k&~0gX=p5UGf_9uCP;6?K7{%#rOJ`_AZo%<{W5Zjg$uYg-4%V4F#vd*+_RQ^ zq@9ktbXOqPD+TlyYs7lEdjw{2xL5ZF%(p>o0lrl{40oH@4)+`4yKo;9kHI~NH}AAO zc{lG0+|4WH`AJ>@$txpySes(~G}7-N>Gv1X?*i_$9MImD`sroh!wxj^@elZCrcjIp+sv}Z*+qB^ShwRvK&#ib`6cra?1;+MciUWTZZp4TZYQ|M{J8l!+Vi!| z9p)bMG1?Qht*gZdQAVr!!dz>9%6!oLBCVGTb5KkdH;Y@uzaV~=Sz$h8e%t&G_IBlp zeYV+X-fMo+`~ud;E3ii>cR+K@K69nHN)(7%ajp1}kiS1WuH~6a%>nZh=H2FJ@XNG% zF+ofbQ^idP@tNJ`5_7q^0{d5m*n^2;zcneY789`pD|a$V%zMoH%uman$J}Io-P~z@ z%X}1jPQ$Ucb%huydn0ib_AF!Ad%PZdjdEAR&^#DP&@G$IC^4N{fI&4ji)w6;YV0to zu@zKfaoWV}H9uzdo9oQ==4Nx3@MF)eScI@6S1QWIXi+Ju#8~kG{HiXFmGuu|9lb@g ziOJ%_*bAN^Zo^KD+@CRU`ifdVRx~bXw(LvLqZDDS!$a@F`P3@}QD0YR!(|=SDr7Cy zMxvfB*G3t4p|)bD3(!g9SE#f9W}HHw_M-6{^mD&OuQS%H!AKiH?~}loiuW#zR;_r? zyUv`1zG61s1cs^cQocjjPoS?bG%r?N-a(tm($Ut?@8n{4B45u(``M^(L`_N<3G_F$ z=*fj~J$j=ovX_VKl~496CVPd+UX^68D#$I6Ee8Fo%&CEvQwWJg=rcWfBi``ysHOU; zr4~?29Y(pn60Pf(T8(UB+BmYn2lR{jMJ4{W>iRzn+;4oo>WvmQC;FIaDhO ztt+i7wPBRkBFbx+@>)rGy^8Xhpu8sSr;)RfYW+!@h595%6BrcFhztz-U#_rm85s5@ zU18A-ES`ZSGcZ|y)9GQ{cVQTxUD)gl4EvF;FzhC}u+L>+*iCnZJ(PjTQ6QZ<-sWA{ zBN-UhhFoF0GBB*cxxx--U|4~0g&{2$b|M2ilYzaSf#Lnp6%TKhX-xNKV0Z&|g<)PN%C^4(3kfU(L37_R(7eZcr7VP3t*Tbbn9NBjytM6gU(@gHJ+T1k$q zSG;SWUDFKdJLRf_027l3&G@ zC8^`q4dyX_Ot7S+WfBkBisaCnfJ|4#O-SixVkke>StVWB++9WzcIem1WDyhVxoB}| zx?F`<^cGXX4nLIz%N*~bD_c=oDqmDfR9P!I6R6x3d=hN&G&s;2!1q`UD#r0lM(;Jsc_XRVpk|5eCm+!8;68{Bo!{(v8K;T;nXY2S)^MY@CFcLvVd;W;o`p8S>J&DnI?EA^bNv{2YGsknsPntZNJPwW#9j+y8w; zP!um=oRG>e3{#Pa0xKhg2t*%5MDWFg^x)+vazH$o7(_utNDn1Ogc^hrgcA959txEt zA{3=0L!!`7q!2_3rQdDMciH=}|7X^>)~uOXvu0gp=G*^k8ZWzt{CR`Fc7wlegU75b z$2T3>;E!zZM>qJR8~m{i{@4b8e1qS@4>mn47w5BK6tOx^#xE@{{XpTJ828<{Q-Y)a zsycOr`*?7)aaHY^UGG}sxdM0B3U_zv(W4e(W_ z8+)u}6hbdY&i2Zhx3_xMB^ed`|f9h8d4=J|!dPQFmIZm-?m0L@ zN7#bxadk6ODJTZDo*cKrV+)jI0AZVKv%< zbcX+j$c2`p>Q9lG?0CHv>G_TcP@qxIh9ul;S~bgBT3_!PimcxYPV<2MDN!0Xoiilp z+Y4%e=be!t?a=Y zJS?iAwxi7jQdgGDdIP7qs0q7Ao};vGJ%Y{;O6YvAvCQVoh3#eiHJ4$5VAY~a))iVX zS#{}3+xu>vH)!}n+ryJ$QKmhd7dH+TWQF4ia^rNGyr_rUK{Jl$%fiLhEqxWr$-lW$ zC&hR1pkp-DTJDWmlKkWkd&^UFx5`;u_)x66o_oz&e7tJ0ysR~}f^y-ywRNL(P*zUK zTV0)f?^qrXC2Kl+XO`6pCGJ*aac4hgjc*UcRd)J;4EeN$zw{b9-CXTyFxINPx3IA1 z-<@m4CP2g7y0n3{aD#)Mcv0){TnmyQ4emQ_Xl^+`bL0Tcod;;{nx8-t;EYT!{gFQM z$)^VmrB;0FR(-QytU4dhXwT^piT~t={!4?N(O%W%p{FM#{N)Y($Q83!z%v~3=Zunm zlRNUwV)rMx&-JF4HzhsZXjw_~#-@)~{d)M*i<17P4gGyhuk}{=-dy!Z7LWAzZ|HwI z=p|8n=c?(cYo!0#hW^h@FF#!M7t_lFlm3+r{a**Y{p72mr&lKZ-`4aKZXRU59P6JF zdU|TmPp59^VZlwGyzj8-<-JLdQAi6Jm)VDNeEWv%)6<@FymQhXJv{sO;pQKCI%D!J zOya-M_~`nrt}owC{B7(0Vh3IFl}9K3o~|#eUiCoN5Bx2|W4(>Nr+B}|2fcE*dScVw zlU?6FqMjP^6^^!_uyyvKQnz>NYjVkJ53)Lr<+Ut#tyyZ zK}!jFOjwVI%9!=FUlv}rkN8VB^=U;(OMgWCXV>GKJ{LTExA32Dyyt7u-a6X~eA$M7 zuYYDV{%& zFlFQq*~)UySwHpG;{zee9jQJ7N=5gr$I=+=5#fJRVvaVr&bUvIXXpK?$NS7(4`o4# zkN_?H`m9H`RfY3W_slx=H9`B<5b4Cs$I%Muum(nigDg7nn)q;(;Bk_<8k&Br|M?uh z(?j^&V@bbvKo;DGX*s!H&S>3s%91T(8q|}=bD3Oxa~+73eF~&g7iX37V4R(%`J(uU zK4VE+mYrtDG1)x+A!AAyI)~cQ1!rs=&l!Bi*iQDJPrP^5D~?a>HG0kQ33dh)AuI)hV%)WYM{Y87zp~g#ls;tF*E57)h&9SRmSA}o? zkX&Pz>PLp9XYBtkH!#j~+HOUoSN+4utoc#fSs&*%gWg)crvH8D+iyHS`+-GlteuQi z+}eBkZ@T`lTW>Ae^U7JZhm&3R&u#d=V|huC|>OKj{p|i!%!2 zDM9HG@%x4Z4|y!snb#coBhCZ8*BSZse3DDmZ`GT&G{4JS8uz|&){FWekfTT3P>J=L zGX&=gy=n|`ZIN5==UiwZJ#;W5hU3oY-_wOf>X^)Yu^!Q-UZNa0>mOd#Zf8o}1{vq&IKOwu$O}R()%;Gt< z&Moj(1IyeQOgZ*n&wUzin)nFQ)4DW0BYKY?zHQ8yJxk9QdsOvIq~K9hJZBaNtPX{G24on(GS%o>_}n2y~{N4 zv1{!$#%k#~!`lxCfZ@pJ{bys!LouqoLPC`Nvk`M@Bvq#w)1q~3O9RY)awhN1b zOv50e1KIJld+lY{Tyff&e-#$u zH+Y}ZHF@0|u3!7Dzy78W2j_(FRt3uHFkRyI@cSRWGNg=3Gs$t`$f?t-ie%r%fScLPe$w%_9tC%&KY7>bRImY%Yd?N!)a9ld7>odvN)W=eoAEJ zEYfA+$FY=C2Y-#@2##?((&d9M0e*w?|E2ak-w0DU=KWK+rz|3@zLns75rAei+BK(MUu~1X`RQEbu5&perrtWYxeotzFa@A>c?ksj@RvD zwVzUX)$%n2@Xm9y^)jeutov$ZT6V18d+=cG{iv@>m(_c-jpeN6F)OmQ`-Qr%P1OmV zhv%1+b5>n%D5ol4fcaW^WR0>;Gk-g6=g)jqop6u3E^5zN&$GR)=XuYp0!5d=32D?S ztJQvD`SV9RM%(iKsiWOz!j3f5CZtQ(v55vOgK}VHOty%<+jT0l{+f$ zs=T{$U*-PF`zjArW-1R?K3e%&<*CYC<>!^>D*s-2p>m+|tICU&>U>~6I-i(N&Nt7u z&bQ6y=6mN?&JWFRp5Hou%KT~bXU?BJf8P8>^HNr>XW>T+zkI=Xq4$Lg zU--xi|FA!@zi0ot{U`1}Y5&Rlx9mS<|3&+6+5gG?KiL1=V*ld6;^^W@i{~%CZt+cv zcP&1+_>slO7oS+1UHtOmQwI;Cl{-aFtQ19Y!v96B>3o^iyx@@5eDe`o^TTM(Z&z%FCC#ZPpP%$xoFMTqcv|jOlv-VNNauxt+}tE zHFq3GYu>c@*2Vi5KfL(qdTSn>JNT1>KRo!)2mcA}`hWb_{_*x9AtI{*t5}#wyDm~B z5s629;opQ0@HqUeK8w`8@ZX2O6@EJWjqq2)f1|EFiL;+psgH;M9O*~H?+V`$e!V)g zGklraUmV_nD_d2%96phI{=zH5P2mjo$#6Uz!`>Hmgw(r2KM*1`8~SAEW1$(|8M;3- z9l90!cL3fHDq%YeD2CRAR)<=UN~^m}q})vL7n}q981OHEAE`6nN9t+7SAw4oekk~+ z;P#*q_~*d;g$PUrb_K2uTot%7urqKjj-CGR@d^F&U+h1_e}aF^zsBF|Z}DgRQGdkm zSNzwyLw@i0|BNnUr6G*05t08P_si$ybB0qMkUy5cFh-4a_*-ohjiP)EIe%9!$REk4 zaP@$kFg%7^UM^oP&xF=?pFG=$A&1B1T`Y?HFyQTg=j2{&e}?^xRYYF>fV>~utMJz< zf%nFre5ZUTu5AWfB2`PtSJ~I)M!AV;TzRe9Di3&q9a5^<@RSR$XVQF8dr;$|@=-XU%k?-qB8X>qUk6LFuoU%XE|Al@(j zRD1|nctm_yd_+77iTyG0aab;&6n`N;CH9KH6am&Ve7df!+=6|l1rqxlpa)<8Rs#9} zE2GES?`Hcp3{kvLzT1!F@in%5&?Z)R8UR= zdcLTjZ3*BcqJsWF5Tn?myaaF}Q2|{Nz>`E}qXzc#%4Q8>9rjx^hzabsYG4~xQ0EHh z1>8(jKpO;==KBET6BYDp0&!RY{Snw+m1{K!zH?H8I1&3dXb@%WZ_offDJpLU+>B>8 zVLzoou#C5902dXN+cl7vRPN9~UQ&6N2Jl%?0o@Q3&hJASAWp&lehus|mG@~-IC%(Z z0KFNN84co8>>t(ujx8!527DCvoQD0^G>9{?{|4YGoPP!Oa~f2;{~T$6s@HQ!1628c zf%Ly4eKz(lXi)hdKpH?^S^1R)^0~^38Xz-71@uLL^bqstBLvdqd{l!5J-FTd-k#&w;>JM zn!j6v_z3pX8XyV9{5^nsanIG*qpb-FSKw3g0OE80OMq`84ceUlmIm_m`R{2UU!VWJ z29^FH(g20qXOISvkIkbU3FPP;gvXn%XiH*YAK=?K&vJc717-8Vk2Fw@Ec{Y~m=WRy)Q2Gc z414qif_NDF9e@jwegu2aA3=N+`+v|N_6V^*qJjDE@6o`z?_Z~Z@^nA=Ac69C|4AAs zTlb%=fwFb~77dik`#~oJ%H{nRX`pP{e~Sk4hy8p8z&73g0}bLa?4Q%XGA#CMfQ~B` z2Q)z26^o-9sP8SJJOsAm;`tiHr?G#X2Jtxdpryq(;hw+3{;dGg3EFlM?YamYi?3mi zKDkKzJdHh{$8+NEuzx~>K$|SiY7oHRBHE20&`yg_X%PP?wkse%moNNG z0sFOl;pYkj@E~81>|pX|ECqOugU#?t$?ya?*Ebk z@@={Q%L)Yew%q?!1>}cv|JM|d_sacWSD@4X3+exbGCYiZMFIJeTudkskS}sEsepV* zE~XSvACQX~1=O$QBI*wyuak=-3UnIvSv&{ldG75B1Z12b|Yq|Ju3Mg~s;x80X=E}uiD-*_kdG@ z5TD21r9cRj{eWA65Km(7RUpvUM)_os=Yk6Q)0sF5!ut@>+2YFz#0wKO71VC<&yoH)(tELgPJvGUE7JdJoqrzb=dCo__gDXBrP02> z`h}JLcclMar(Xij0g4V^3Lzb`(#=RWBYi9OIR!$X|Gl(Afe@gxW4~IOV zH-(-Je=z*($Y|sP(bdt9#S*c-@oN*^iP_{}aw_?q)Ntzg^vd+U%n6yjO@Gup-2Cg7 z+1AyqA8eg#8*BS|`$g?v%{|a9y2ra;?D=56SlChci{4c4RlQ$dao5Vk%4=6X)z{Ux zv+wWvr&bNFHdeoB^|#k-UGt0L%s^(~-GgHAEkj*H4-aRCr$^R}ymNHp=zo@Wm3}dH z@7msVuU+>S>zmiVY5j92Jh0)+jqZ(aIdS!g)$)%|+IiBmo6g+y?UT2j{K3s)^NpLI z-BR4zz4h&KelwAg9SZl5|mbo%boD`)IHWA4lyXYP5$*ef0$ z-#q^1vtE7H_s-sRj{BU|=ltT_d(S)leE0d^z2L?jn|D0-%6Gr&#tZMbXzN8UUi=@I z%ua}j*~_M1z3Vlh%iFJb_iMlYy32Q-d!=#Z%vD`i9k}|@UFTnO+BGxRj$TV@aAAaX zR!+%T*djsbt}V2kN+q*Y7>K5aazljyvy?8RquAw!a_NCm=V)nQV6@aZkV>a;+HJbc z&VhU(Ux*gpfM45l&pr2sH%v2mzDicVC4-@a%qBuX$y9ZYspd!Vt3JN+(MR_oAy4P7 zcE^OBk~7efvIpnH1X6x@lSDjUaGO!Qd$bgF46-C6!-agV%XB9b>D15;Bb71;nUEL1 zklxBWc(OXjt;|+;)GpvMP(V%W;E(03d>At3EW9ISngc@vrGe43PNmXrGdI9#kwlJ0)=*qFB z+-NiYu_pNA8MGY!tSbWpgXzJcq{8nAS{Z-(dZD1&IL|YsQ9i4#j6A{DyPVw}onCh! zm`XHdGRAOw(CKnGJ32>WnM^e4H{;3HmW0D_pvozut!XH@>{eGe+Sb+wWW!Jz4IyFF$i>GPVVLk{xB0mB;`wr`aFs0Vi@y?(=R zy4;Q=8qhV!Hg*6jQodEb6?BxLFHfRorW^o9O46k;V5(Y` zOeQU@typsOifA+xs?KsN%i)%AAP{cR+k>L<2(Lc)>w|OhHqdmD)Rs=xXe~W}HUX}a z=vVo|NR7ULePBI3z&4pp8Sh90ebL)*kNSd%cMzvbkL8S!dgv@)G!Z=a++ZT=JL@6h zY55u8M2g74irg!w;ic6*D+&5_0}n$e0sGhpXnwSmFXRSBUgV2rm=m(MQ*!sR6Y3K2 z%|10J%cx@#o?a2xTmu+JZApowx{;FG9KaFZ#kcW&JTHt@t2S?5waT#fGsTXql-Z7= zy_dqiJXK3f@`fq<4wYaX6|RMR1m0*72d_ZiW}BA=qIO+}bPb~q1cHH`QEw=|d7QP{ zxs%&*c}EDvEfbL|s-I^42y(Z|`z5Q6eaPF*oE2YS|7VSOM)M5CA@NSW3D~@EWm`At zq`PmUc|vc&ko}MTBlE3RB5s%eA6untZYh{@Qnq%J@N#|9DD#eq$ig28_~`SyVDsdGwJTj)lFXo3cyt*%JRp&m(N7P&CaCX6LYq!8`T56ZlqK> z{|n`ul8<5p0OdqGIM@zDhoLl-iZqcMC_U+oCj!&x@nVAj=S_ldWdrri&?mn-g!#3F%Hb#KVII|_EU_>i>w6!+!+ zk4FNL*sF*y^w%HAlhI!j799=ZRcIsNA+DqvDI|iv;I0G{G2aiK(-aU01geuUZ!jTu zsdk1HV9{e2Jdv+K#=2(YE95NLs`_avM1O>|G@)nM6{Y;-IrgC<{`7XFI52>NoH|v% z!G1^_yekllQS53lQv zwzPKHM_sKg(e8CO^LhIj?u*M$*zNj##rIUZg1ZkWPKu@*VZn)ov^!_lLD#@y9K~a7 zRw-0-9&@|?M&2rKWxL9h=^Ah;8Pfwi50`pCQ1UHitolRQ6Z80!)x7~3l;g>Od_yvD z@1OXSG0z@%IAree!21E79ueb^7e&a>G^m8_*{OJ1XR;x!x~ZI03~icQJ1vXs9fZAh zLiJNbwdwN3-D#GO{23)H4Hr;K)8UE9p6U--JUNcyRreg$R%H@CY+yL%*`RS240ri@Z<&KiufI*lGw zsU;-Ignfr(qkG3_NuRT&sm&sIo{)qDr$#(jvg??}qpAx+bt_4+WBq!=SigP;OR;V3 zx~?uMySmn`-Dahmn+pTYxzQngeyBfd22(~b5RV6fd}^D_b$7F`sO>aQsSJUeCE2Jf zTMNz2(&*{or6HALvkyocZ$)OvvXxKnTaip8k}LFrGfN!-I0iU57ol1xh`KaVeZ-b+0TCV!i(fRAt^)E$)wLroOM>h^d;qV z^(R000coYqr#dhKwMkL4)CtwoEv2hPfg>h#dPY-#++vP<-wN@ zeox*mKZ@~m@YvkIfNcYz#TzwyG&cS~J=84aj?pb!Mh6GEjX(kEAH%P|KZIYuPD9^_ z$PS9v_4kKEp>RJ{7nVWmcvEPjD8};14``V+=ohBe`ZUV4 zHbSXOd`8DmH*@FqfkDF<9N4~dj7Zpd;^0slw1@V#p}`Y(Duhf*v%1%myodLC)Jb*S zx)+bhaiE|kcXUaXwqid2*0pU;N^Hs(;w9i z#`NZ5(f3}y;X_e>KzcWBd{raTcWej;BeCKZIcZ~D_O0B+vIGLLSFT-W=(f?17^O%o z9PFnWYT=)>&;@NKIRYWi%9Fj4>2_KvZMu&PbjopNN~q4+DVd#p>ZzxA_W3>BKA`lu z>LkQtT6lP-CCXjW=xcZ{4j44srYb#&UQ>T~j%Tv&IJ5diJC|a|(z|ItJ zE6^rX*2+jtYL4F*Mwrnbw_pxjK>vt8d;5Siv2t*^a z5aNYBkhH=YjHQh4@yQA|s?c}nW{}gWkh(w3!fxuu^P}nbK%B~_^7t?Z$kJRFtcob; zQ0Ewp`W}DW2kyaq9yDRBYjY(cKjaKm|F?{WobIS@Oj-V=-~Y=hELpsJI_kFC_Ftd} zJfgTgv=Zb@yfc6Bt%mnR!hV@oEf)^^t3S{w`9W8p`iN9+mFi@~bo%8b)yH)H5$3OX z75h&!JzViF)q|ARNJ~k`Nou3{9FWA$#p>0%(Ga>8{^p9ky&3#^dyDndoNQ|!9$CMB zWVpReE=f;j(koW3UcGV!od$Ml?}nkFj`sGBp`i`+lwH0u$`@7k@)DJpB@JmIp{uIx)Qh|wBFyXwZP zp{AxQ6o5htd522!oDu;<)3t95#iRZ!R=1%k3;A_ZyQik6q&d~o)Ffq7Q;$argW0{r z*aMHU&%Gzm-94}_UyyTqAklCS?*$7v_}hcumz&YYF}{ydL8ryvV7jRI2-3i!TiJa1 zLKh{XmeK026iTZ7ZUq=TY;ayr52!lmI}}gP7fR@ddGo?D-u?SA;v$ zfuKJblBU-e4!5>;Z%8No4vz)5mn{8fA8YR|vOhM4QV#9_N zy=XI}M@P>-dvuhX2dw&ebsCqS=Nq0^7jOfP_#Wj$xK(~c+r%~xq#lag9q`G8lfHZJ zRT`%mrWuluA2buykH`zDY*r_!e#+^jPv!O7gLB4aM4Wb`%oaZ_r4GrHd3UM2BT3&I zU*nEO-LH8g-r$-xqY?LIm$@TR_dTwJ{E#bA{VRD|M9N6@Gje;v#rHw`jL4I#Pe!oQ zuT^^D_m!RqnW=o9Cg>;+dQ6jtD^FNW;>b6#E8c&9I2H;1>7TOu+G%+cI$Y$j$0EUS z>~o)E=liskR&}EvjJhbTLY=q8nrc$4(1(r{c!VwRNFW*yz4yKH{%9Z+|Cx3v{wy8} zM8EYd-EZa)T|1-YfaTAUP$0-)v>%N}+G8~yHr>AJw`D6^uez5h)N0-{J}K)Rod+A?4)_cmyMJPX~+i6c&Wr_ z%a@c(I-`&6w~_QiVOgD!;oID+*hZ<@<03f`r<9Ow!~sm#$qjU%1%Ax zFl0F*!`X?ja2aI6iksW|L-5Ofe#2ceh6{0ug2^_pbjLbIwKex zP)Alw=MK|Eyc?#uRw&{{@Wdi0lv`kyTvFNW7qtRdxxXfglb14|{*-w26-sDs&*PO`!qoxn$pis0iV_CFw?q-vDJ7!j+_drY3ebG)wZ zDimZkY;Jyk*yZ$H*NkEW-}SCwAYe3K=X1Kk@84{OM@B|m!5h!_$mCUi|CI^Dd;X0< z*9gY4g6~N=LLuL^4~Bdm^VCyKxEUV2))xvnQtt`MSM1ug%kPMu=MC&0bGyfO2fXJ+ z9sXS)E#aj90ng7OBDw%g>2%aZw*%^eQs;)%@ZYG`h+u1@fwZPH;y{1Voq>(E#P-8& zxla0_N8p|*^!7ritL?sMw7tEntGzvnpPgC*)$L(~r6c#XwhRoQ^#)p6 z>#1r{c6Obx;pCGyoX`cDY)C)vpNNP2vGd3mXVrAvUy^z_Oy9uW@Yj=Im>OeTvm**#@?!BvbTvwcNl#7 zbFAJGHrpCqZrR2MF>(^Fs@Gs7PDX4F+Q3W8<;I8k62inGiE?AMOP&GF!HccFvPyZ7 zw5dy5u0i@K32Vs-^l*h$>_?IqV^{pIlqBz4Zt9iSZ#lIq0sSEu^>*j;xzhUcF1zfq z6@`_nR`q2@hPIDy(c`4O)t?URV6iVxgj>6sgWjaf#5`Wp6^%BBlC5VpH8uI-NohnE zyz!>)c{+$XB!piLd10}!_=U?D0vfdBST=P27;jw5m|10KV3ZaAU;A3n)#mj1LYK#aUrQzfskXLM^%>iEkrAdy=>dPVT7mlq`$^Ky zq`VbbMx)3w6#AOZQbyOgUH^(KL($7aKCh$A75p0W3nY^TnmN^qov+S9XD1`r^A%|B zWqkI0U};b@(g_S5MWeS5Lj3mAp<> zvK)<09e4HAlh-L!l|!K^OE0L&%u6{dsArfw-xi0Azo~grtRNvvh(dA4pXE=15Jl9E z(zvP7qf?kv4b^xIM#!K^L*D~CER_x;jgD8me#{*T#n-jOqEH30it_tCGPKTZ(4vx~ zjm-U+rSFANpHIf3EnueXJHe3I?DU4D%SgDrN#hHRas{;DJXnQX=D2DXWb#f%o?Bx& zL<%sb{=m)DAF!$ZED>#A)^1%sVBeqvanice@MPCOF_*$99IeO1Kv9jcjvSfnWOksp zx1%i)_xt0CwvOK3f#t_v>Mj;HY$z7Ha~$w?1=8tU!x_KJ<;R&XsZp_18iPj$`KHGM zmflrY!|Exp+IXzJrL8TUZfk34kHzKkjqS2CEYo#;rBSD8l7%x7C_7a0&&jI1b`U9;`l*EX2csh%wIXm2HUx+$=Uuhx%4_ zPQGvSbh`+G}7HVs`*mp8xKzA4y}?+U3_=+2>~wvDd*4xdQG z#(JV-@(Y1TJX|eudv-^*qp1O(k!Z_~8&?=M`jag!%`02fIHqjx{uql-_!(t)ArH04421oY8v{%_%ttB$`_xE6cOKL+x4QTw9Q^} zhTh&iV`DpkQ2dHxV>7+IyO>jZT2u*ZZeG$KxGJ`YkszWP z26ccuUS@aawwNpC+_~aFmsT)wFIdCPiA-Fn7 zam|`_Ivoo|eQra-taf`GAPuD_&sln(j>drmP=1!Q8kMj|Ta zHFvJL!BQ-5Xo)w+TW+u`kjcvMY($M3-ymJkVw>Ta2xqgrjvHBiZL}zzQ{ylNPxk<4 z1*%aU_Mw_*4C6ARrF5f_#t>d!)H!Zy828ERzBQU)FHhtC@CfX&^C*^oDq z(qUbaOvwi{A?JZe(z>d{0IEX4##8zRvRC!MPqXLf{BowBd*)KmNVB=?CJW12F}@KVd&c1#5K5@A%~q~C3ZH?1|zbY?Dtc;2;} z!X`YeAT_y48e^sN+?xt{*_px^i^GAay$np9NIbqKmrG=tn+FFr-r3&V)i;>W8%91q z$i36yaX1hyW;z^w_7E%g<<$*Q(P)duv5FCa$`2*SEam%*kR>gCVXyK_Ek~hN$&0Ea~b3xyz9~{C( z<-4h$MBt>$8A`;H{i|0O@)#rpqFfTX-r>(ufpBMa3ZQwDEXwJH%0xjc^g zsdcNZQ@01&+j|pEPim-;k2n)4kMi}-8D;P%#w`zGR@P~%Rc&u|XIcq9<)a=riot9R zmn#EuNDrN>v;j_71s9UDWR7H|bJe2Fp5&~Zs+KWejHqn2nc{X*ZD>JfvtcP5L1#whqk_)HPRfkGx>8+3x4NbaE3PppqzrQU<2me-Guox_n`%$w~$>8LD=UD zrn00Uz8T`k3TZw@{z#u%9#Lwnn(b8@DHN4|T#F>l9CHKI{%ruF6wl*x5C`z_Kwx18 z0G=o%O#RZ_K+;4h)Jau}oSc2^vB!+;G;2AB{*qC#TB#Jmn9`n5hzOD4u*|k3_t{lG z+c3JExXQLJXHF@uF^o0EQ!>E23>TGLD@P0?%fl>&&7lC<=QFbG@t{fIpJT5JWqhj@;|jFe zV-`6FUoxbHaUqe`FNNY-lhCRZL*@T(HUZlJ_Q4e7e;EDXI?Uw0lQWCs=;3q**pWhM z6_=4@E9gEzpVw%K5}XbMH%8zT9+h&C!{`s&fH>w|y44soZ3A0TwevZ%_si0!1PLF3KIPQ!v(3Sdj?fk*@Kz3mYLtPCYM(ya!r~*! zX3K+R&|j-ZLp2XVFR1Y(-ENxlY0KDPBbKVO;&Cd7gveIB%^ZXy-0odNEQ@A&)~Vl9 zTZrFtQ)nNl8gF9^<$3U`fhX&LDu%hT_OydFI%KAq8N$a%@w5ln zxpH#K63}NHXHidIPGPtk4l9hG1iFs5SZ7g0o(Y_xPJ==6yEE-Bu&M2mtU05)2HD58C35Arm$0Z{qL zNIVhwM1#h3cYAkt``w4vn8sx|b$1|eH%y?*Kkyca^U9mAoN204$`y!}fJc#TKACcPlCiLJz~K$YJ)ZV@Okcal6AybG1I}

2Y1DX6{nZ!Q5fRX-UoS;2YT$DkEgLBJ1(BWHD$TX=(EN`_|f_erx;uKH1dFk^F3n z&vO&U5bZqJAk`^m6p1iTq5KK*E5KDhRxdaMRHQWr%}^BEVF zCm1sF^5JR%c0_ZVJ}<&avFBOCk&TCcWw+6!-(GA>OO=qAn+IN zy{UM-xj7z}v$z%y^!2T8+FIh|2F!TI1c%brruBV&fjIJ<-~&ykZP;*H6Z5Ff;3+(7 z#q=0A%30@-^L+C$^Y6?TRbQrUo3yL~&E=u;z-wmz{*d|uHvT{nx;Om)qc4zycMfr@ z^t}0qECLkpQ5lUphudaLu&*75Tkj@iMD8ePF~!|&l2 z@$BqKB$J7b9e_t)+_3|3WydsA?FLjj~h zS>BPM9+-h07M2Z3m|hrr@^Dj~t061Pl!u!sYqbD1feOP@Q~RoW)fiU_OGU$(2@j*H zS@p%Kvc2R?S>C}JKFeRF-b(ug_Ev+koL2({34Xpr4Omc_1NreEw1NxjOjVv zu$*I#wXyYLJ63mGFsAi)EG4V~D*d#S;66a7B+BuJBW(}YLRS&^S}3XD89NS^_SMkw zR`W4`BHr2>PxzzJa4_21*4x|G8V!b{(JqWe1z`=qS_s1TJzG!m!ZBlKV-S%@7-tWL zLy=fayBA{^&kSFyGt}E9k+EvrrQY6WVzsX8e`kEU^_ZIu1y{}(ZL9vzVDnRm*>VSS zUH$!CxsWT7^m>x1j*e8)?D+4&<`n19^dwU$YwJ#G7CMT*h5*1UP*gd4_UW(SE#eCVg)4D>P z*J7^O?;0`7@FPef6~%$E;NjBYJO7cxmA@DaO#A)Qh|~`pwvX3&MLl(m+uVU!+@2k7 z1hwo9nagz_Msh8U)H>SC64fhp2UNrIFQex?uq66ui7UKDk&S-yJ8BH)5FKs9@s!iW zNPW5sp%kboXHXQ%sxPSR5wtRS*3{HgG>S-RM1^0+$ns-Q$zG3VLLo$FBX0aUKB;ue zS)&M_W;;emv0iQuG)CGG9J+_Hq9PwSc+WvIjFA+8RK3az22J4Yr~F_@8YGAs*5*U> z30r^4k&XcqSpLI^7DkGZt;#EEWnIv2;l@5>kB(a11q|1gKhqc;+E{373%Jzk2gR_w z>Z&q064<{p;Jq^tcsCRipD$8WD^evAX|KnPCHWjq1JT%i1WYMA!a(#=EZ!PY7LPJ^ z#;LmN=B&aBfVQhPU&1ORS+qnd*&T|h6%}xJ>80T!}_2c;1SV4)6#Q1Rz*c|$GnnB1pKhP}4QpkKhZ$Z>8td%?-^>Y84>owK-qx8AEM zD$nL2fS%Be%|cDM+i_4M$J?jn&^`Cu0|YzATtRyuZ1j!uJGS_I^vF zG(XhtIRV(PW|N^Z%Kj;7+R>pndMM8tUc%fk)uEIWR@KLFB>R*-yrnFi#@ z>4WQiA1C$h^!Ormj?o~M^jMv?cFLYff0!=!uzwQM;g<6&l=(RL6$c?{BdDlD8TH%CkxxAB_WhrMD~R>%Fsz|EH_}S5!Xvf zASaHyU4UnF7b~_S$**}J3@ZwE2WJnCU~iROj#9$~4Jgbemz19axKvVS6sHv!{Dh2s zv^oANHKwaI54Jx|nQ_!;3inNuNN`6>^@lYxcgpIwD$ayu*?>70B5jWk+PqQ;|LCE- zj-FKV&m8DP`)0s;8C8|Gcpi!=!!x=Njrx#Pl;%g3J3;HxWF$JplB2||V08{T>{H}g z8*i6AEvN>TGs4t&=PJ#?Ysemq&j6F=yD>&(HnOHWtSx)8#&E&LtEEn#1-awWTZn+g}=yjxe#2| zR{fD?Io2f0vV4eV6N&IzOy3TVWx%Wv7nx{p;;>rS?{ozMUY9%Qa0G%rr`zxJVh(p$ z`d9d{xWI}y=I6w+raRW@^Xjm%NCb~Ic^^XKacs}pY1;iEa6F@N>~gD7P*8#9S;Q3q zL8m;&2vtoBDoy#xbKI*fXD=x&O>qpi2LBSEAOc$iaeB-TsU96(Lv?PH&4ES&fg;NF z_lM)Q8j9gGSetG@F=lkWERJO~)*SCJ-SO-)BwxG?$!Bs{q^|92EIn2 z=9F7=+ki3BH0e^&HTJ|h>04nQdr~@EKvQR7prB`15|w;JZIKO{NN=rM)dN;GdbMb@ zk}|lJS#7WWgDwEM%;rIJ%H57Yz<18sm>ubey*lV}nQPaAM1!x6sq^Rf4mp3-Nhh5Y zc0|rx<@K&QGvWxJ6bdar4z)Koa~U-(|5s0ym&BudV%e+wXCLNOjYWIas#QmNo&EZ1 zb=fP`%O?*X$MO#JfryII(b0?bMJh{f#dtI^lWACgh{=Yknd`!M0Xu@4$XO~vKgAzA z2CiU63c#Jar&F$2adJFy+Teg8o16PLzH*(tme{s2YG)p|)9Jx9GX#Zs3}gGifPn=8 zaNg~9xqOBLGtjVv4OBXL@$gC8$JSIJ0+|1ISeBnGRrM2jJXnw_O#_G}P~iZdWj7%3i~Vv?l{p}?bL zKCF*-xf)^F1$7_j@2H9P9A!G-aV}dRMRN+vaR-B`RC7Ib%nIiO9!xhiVa*|CVWk@5 z65H@4l2h>2wJZ5mAWLgw=od+gWQf3Nq@!q~quHD<>-RBV_72rfIrgYr2$`jgzo%wX_CB=rb zHXbXmBiBIxIR{w0fnOft$S_?c?5mozZDovSsj4ki*|eX`7F&9RLWgUn^~e`m!M;az z2c;~tk#Jp^tr+7PLW|W0IqE6;-jP`us4CisR2pBgrU*`Evsty=Bi1NG{aD#7wW>&D z0#|Ibss5xkk;u4(8y$q0!gL=F;4jqlUS5dXMZkI4_ zo5JkBu$-7=0dOxjMW)MTFcXdk>A2=JzEX!3TT6&>WR;gFo4`4!c!0b`=>)ca%F;K} zd99TJZ%XE=Jy@tE%-q};8#K=bRbH>3(c=y$~xQ23D=& z{MMeH#`H1Q^WP$YaD44rPRA`48`H~eh*SCX$K$slpib1{%ypzji5<^cM^@{5)b>DH z4J~VTg@$I`rd<;K_L8xiH}~Tgz;_Nj0d$KcZF*SKVjsplm0^;#7n9vNhG&rj=vVnU zYWC7*`Zvi=) z1Mn87y)LI~+c8!Apr~boEZ3Ok35Z=Rn_dsTCb1KBugAf26%R%zU(GMo)#|V9zGYoG zdbECAvlP+O5o2hXjW{srSHu}T{HVHpfu=EeGC8as7gnf2N6&)8Xf}0ND^uU0ZmVyw zkY7g4!6ykB88aQum{_kISy}g3DC6k0Sd7#`0KPSl6MV_t}9 zt6NaS&5?8@vWe zCNFat%wh_1ca(*UcAGx0JUk@l1gBS2?f_ zs>DQYm?rAPF;&{Kk0b4d^zVeDwmqV|(FD3oLtC@1Cv(O^t-mZ0c}MFf*2*R{+)~=E zD`^R6ON3)#6PM9vUJQkb^q_ZiOz53`(xUdGQ+o9$d9 zF7Aojc?5eD4}+CLccQHU%L9@_zHM~-_R;ZFOG|2e^IF4Li#33v(ZJ?QFWro#dqSbW z;m&no-a;@q-Y;c8lj>n+^Bo-UBrfI}*EVXiPL3Zv+xn}Pc!*@#49)$*`BzxpwG{*UCFs}Y~`U0m7yG+F5&m{bQ??KW0 zm9KndQ4Za?Wy_ZTU40tu3|VOT`$sS@p^TLwPsbN$ui@83d+<^Y%A+YccY^wJ&cqf? zu83DPteS3NHMeSd2RM6fUY|wH>fMoDT(TP8-PePgj zttjz9x+=&|zw(u@^q6jFr|C2_RM^O`OuJ4uG3mUkW91gN$K&3zvZKr4FwE0k=}*H5 zHn5DZ;nl_?7i)-?7?R^l)&mdpE!*DzUubRtQ{c2-~z>@S`RBS&Eto)=4{!@ zMMUb7RKIyvR7!c9GW1nuC0Gl zfPQl(zfQk&^&3UZI!IBwclF32I2bTIz*U-nGFsb-bRiDHrGr?1oJz5^bSEbe+fybQ z*0@{=|k28~(D>y#})@u%u>Kwx{Y-C>mC-*%I($ z?nLLh6)Su(ErMc!wSV-->2Qc^S$7Vudc3+H=HuY{p1>A8-6CsGrQ*#VE^k-Z;L zRax6LxTH5?3}Zk!XyKkkXD6dp9aX8a;PPMy$G#}n+H|@pn{A3lLZQOYP;XC9@6b>I zOgzG~$Gb$=H}DWtzECI@$zw?ZW=AQI#uB{L$L5SO{CS+0b{e?Yam-C46Jkvj8rb?| za;T|E>jmkOCXLe3ZsVc?aBr2lm9u(fM{16Z>j~VELeN?`*xJ9Mh0DjZtmtp$h(ai3 z8}`%mx*YYU$;QDgW#=~zY*7#13;h(!7-P~OUZ7sofu)V9w_2g4MfJ9$+=Olfd}e{q zEbv)?U+OHbXo0vB;zIiki6w2>lacH3I*qO6YuR)z)AN+OU+Zr-iFbi zMoU~miW8rv_RmgO&G6MMJ>6(0M?~;`23|K{W=O z2d-r8njThDiF=d)sNbq*$!eqQk7!lL2Xj z3`Y=WZeP86wRKO?dc%^e>TlqSw}d^fG_WctLLp%Mx@C2)@kkDNxz>|cZ{;numjoPq z_$m{FXG=?MonBrUyQEk{0+FTK{~o}REG!;pEEnWCr7 zZ4d0zx|qYn#7V{6)ODuj+#I^L>_TNbQ2xSKru#U1c->!WQMmFL+LHt5RkdBHbR(tG z1vMYu>KnSh=)O=Wqlnhj>{?OFiu2B>D^@h2vX5&ws6>P=OuKgK3@8_Q%~+2h89^3H z?qKyA?A>9^IL3N3(7g02RJu>8HHA<}?d@em2n)`RtXH+Bt64cjIjff+nC0j)A5El( zFbuAPa6Gc_?6dm$$rNZrd%5+<{)fsk?=Xg!ojhd9qs1LceiQjQ)> zWaIH%XPhg(qLRFbij6=$VpHm-H8V>KeE3T3!P0(ha!$6Ng zzQc{rdZ-nEIXsOVOBiycbz(ou&ctPIX&7-Zn`V)H4Ich!#Q*{!tQZOQuxyV>()#lx zZP6G>%jt~eZ6MvnLa~?^i@|ijA?Q=<${P6WV=(CLL)g2^R9R0cu4B5r;4g?3YS`_> z^6nmY^j5aTjrfE`Zl|K<4nyjHys(VGv53E^E0FKZrVAZ$_PbD4F9gn-Sqk)Lu z?{;PRj!mJm<}tHqs#&p4ybmac6jS0T$@*K`A+du9i=jdM0kfsyk>MJ4wYE(RV>m#O z4ly|Z;@2&~=sZfcB=&j@6t+*p*w5*x?VVqfnWQAzY^uPj#?pf`q$AdyRu)FIgsa$q@ih+=jg zQ$%Ae4o`C^TSb3B)TJh8yFoEy0kh;BqEfVJYSu-79WU zt23bu*kPn}qBt=Frjc917vzLhRqJe+A9YJ>lhG6m1tH0yNxH%zBeBv5g`F#%QRz25 z5^gT?5BwCqG2#K~Ne={hhr*}ghs3gtWA=9Ks@1x%?d&E$AVQb6h~f>T*FtU^Nnww| z4obh1M-Q0pGA!YgvF0Az>fK2~*kd1kJBO(rugLP2)S21AZ|jjdQlKI>oObq_LB)0b zZ8W9TgH)!hbU4y-`O4v4eA%w<*2`hFv8rwG`E<*#qAz2$g?L{1rbkg@{j~|EQc1O? zPli;b5$TeTc@*{W$D& zgm%WI&l|Wu?3AI8Vrk##-;$JET=P-I>aQ1*!0@}odo8&{ZU>%qSjlAfU-sCg{EgNW z$54}K1t3|YS#et3f$O|gOE7(GO%YJ+6&cu!Hcy{i?GQQ-=`G^NDi7F4eJ&3}%L0C< zThq|khSsJ`R`k`if4h zIRRd?QwI$orVbw(RuOj9eav}6ZNS}i0{UG2EZWB{T2=de30mB_u+%2SN5o&TA1ExV z!Mhrs^%qxEyMdT(d^cbmOV29uE+iRzp1>bDsZyGTFi8vQQCc%rC9$-qVpD@Lpqp{= zC%c1@RZ!q*rJd|YD`Wb#Wanye8}(>Sf+l~{l1Mnrs4tyv#;PKokxYGUI9tpinh1X4 z7C$~><&HYSA@5zKQYqzj4>^J%_g~tLl8^O5GIBjSwkItCBCVI4L#-Q(p;O;!_RaEd znB#_lW_Xpoc=i41Tx}J+ZIP@c1IJJ{=Y!!y5z;sOaL5sU)hQqNzz6VoQnxd76?4z3 zhAHmqG7O)hBD_8WE-$$gAG%W>*KKFV zO@DHGx}R&oU|uq2x1yndFv~Up*TG0+8UAE?YS_zJ4epO^<>}6b8A6~x+Z>>BuhleL z*s%i~#}p#iF+~zmk&SAnv;lL>^NMwq5HK69yxThVZI?rPJGeQ*k&WMipoYiHMeZ72~I2%b@MrBrC!&Ly*VVAAyJ?!%6F zgsD@r_Oz)PzJy?ptFkRwr`PH?%F|5o+S~_-lR&dZIny=~9;aIO}^Qp0_7IT}lj6Um!pG z7o&`CfM(&h9>jPn{MKrw0GrDC3JumfQHqq-(bD+NO|%4>Hn9eBw17mqgs-je`=n80 z)F(rGyq?d_1hBAFc#p^P#EjqnU%%eHTaHan7x9(M-SRit4knwfgL8*}A&=GucikR)1E+{GwH|ZFTioZ43Uj^6#`^bjAK&W|DGH&9zeT ziRf({u^NJ-6NOSV2V)RkP{4>Lw>h;P9?|? zEs`nQhn5^2@6@I_n+HtViDM2e-PXu@8q=UJ6{n%vi}DgY@^`E$ymNJ>;V5KzWaN9-WjCxOLJHV#!1{)or%mTSw9r4EX$Be*oGV zrq@Qoq0s5w_^1XxOO@W*w{C1@djSe0nkyUkp6Bwk=J1u6)|L#Shhi;ew+D}fvP#qI zJ;7nL^sU2J6A-lOHG5j~g|@98Pc*U(1BPL_J?z}hg}T|bp%f~Gk!kr>6v-XQgs?gu zO62vzY;iceP)9xfkm)jg2o5>DGagH~w`VqC!Mg4i8Q!N}=<_zY{N4mU27wWIRTwT^ zi1O@1{+S*r52F9LJDX(lCXdgL&ug8`wJWxV6Sa3MzY&Ym*teRnBHt;HQG)|TtWpI; zLbYUL6V=K;Xwq}4T7o)16_F7v-iKS1ZKjnE`eWFN`P@M%pLTpA$|WfsPyhYhck9I{ z@m2UqQ|^ldo(9G86Y$e2QaJTA;<~2qHC#ciNf~q*_da{W4P1`$aeSNCd|W2H_eR?e z+Cjw!+oJb+L8K=Ariw3cymS!W5HS8xPDSkZvxNjt$c5o>34oYWj-w;prWIGmvTM!be@WXkQMtci+l zb~Fr@>iAqTCGS{JZyk7UEf9^V1B$~LxU?MBe!Kyyb#meP_bw40;;Fd0iO@wCQ{oS z#>)Qwm4@CHyD_B{LB!qb&bL36asE2Bq;4xeu@#NAj>{vg6@o7k#}f&D^@-cwL413) zc~Eb)4x(a^v+%^7&UkAH{h^U}(|n^EWrqaiz>+zTe3%t%xvaa!A_W6+%8f!RC4&^; zaAhz$v@F_JC?W>!v!e;Sjdj@V49vGCj`>^^57xN@Srxd4J-d!4NtgPQ< zJp|^S6${qIh`@LPQiE*Lt|FCXRY^=JQ}l19I~zXFtlO`K@amMq5eh^+Zmg!z@D*nH zT8Cq*R&?Yd66N{{h! zL1G<7rAG#7TC*Cqe~Uwe@CCyLKy*V6NMrug%93$Zh<9oWz&6lHz>*8YfYj7iMCKGp z0@*h8VP1!#Q>s~h5H3W}y){9;_m(8TIV1zj{Ri6##hdY#SvEdoPe8{`_E&Eyd zRp^#`EZbA7NhVrI&CP_$#1X(zwTHx4rX@!Sm!Gq*F^J4gTTVc28bJXYK?=%%GR^IM z-9)#nK-_1av-fE{X{R|BHkUFmau^D&-IPT9iqq4>VC|l4!r@7sxoOjxDbtzk=wTpt zkH?9SndGLmv_sQu*~2{7k%W)@=+DsvUY%wpYtJa0!TURsh%^tRJeZi{NapiN2PWir zQUS!ECp%IeN8-%<>6qP&psm#;E9=?Q^JlV*$MY=ONY7=UuOx^VrEU27@8yhBjzia0 z17>Pes|3x<`UHjL1|m-(SJA9;Xb26a=+y-GVPK!8RdAj35`%83dAIcF<5;Lw^4_zEgRLIyh_;hvH{*>mU$` zQ-0BPjvnV)UcimwZAvb8!O(UmdA`hPIx<+7U<4ud3fSeF(z6M2^^}6@aDZm!hEvs1}d$n>PaGj;&_4UZY@&-EB zD*8!R1d~`LR)Y-;tn^Q4-SONK)R`w zHmG|1`2`nTu;WwzylvaIx2+v~?6K;DfcxL}wzr)+CLeqL`R7f)-+bQhn=}KJfH~>& z%iR~_*K!7aw|w=h#WT+6)w(Z+3Pm{lfY0|pI1KWmJb^Q=41ZS>N_HmZUNe${Y@{v| zv~vTJ!LsWPW5nn<;br_t_tFw|NwOL=7&@h9L)u1AafphmPEckrRh`kni8ZZPM`Q0j z+`w zjU^|`(7n#W91EZ!rH&zUWxH>F8CESGN)EM^#+q=o**+d0( z9io8nnfPEaMo(`#h3_q6N>ys?YM8X2iT?AxZ+`QeabL45;E(-h%pY(yd+})tBNcN6 z!r4`;M>|u=K(Hlbn!!MFWlv9gTZH-Z6_GZdZxc1zb%j;9$23DNxF^+FTD2-04!H2a z>}nB_=-F`@8OA44`33rz&od0WMe7>WUr$0r>8pW5tw&je4kdyqEnk&Fitpb}O`8a^+m zZdPciKBj3VAy>q`KS%Uhj3B3#a_b5tE{ymP0N)*m#>3qOPoN8QE1P;R>_~^w@nFyx z86A&C-}df6@PyuiQJo^WbPNwSVvHD+QJrlJjsxoOvtTqcB7l)%YVo9=yjEc#*dY*r zOe*s^Oxz=4w7H{uBN0Ys3Ib6Q14D166w%$_fYO*6dS2$byL0mYDeg+6+qkYX?hG)4 zec=L7Bqc(mxXA(+ag!9uvYg1F6~|F5+p%5S5(o@Qm>>XSKx#=(;>6D4q)wHjX`(b~ zm8Nmrx@i=*P0}`Pm8Q+ow60GVANS<+N87*s)AY2b?K!3U-S=jI0SV9~#U$bp=56z4 z=DvIHyZ65P?vual1{D|!^!4E<#7G3XgWHC1-$-!&hp)c+YV_;TS6Y2t?iwYv{eXss z+uPdOhvn}j?2|mp*wHg=dwvY}aQ7`=Abd317sv zBz!(Tf=Pwh4O^c1LoH%q;9yQxj`fB1bo88?dEDO;42B}{XiW2V$NlXG54QW`-J8+S1?MhQuiDWT3~8DkYX9O@ zIM{Tu0kSh1Rjz)q4X5>Lpwt&+>E{jE(-zE6pTB-ZjG zNx}+x$*l}}!;d|%FV=ktJ)-AJ-LZWSJQns2D(;e0edI6G(FUe_0lV6z!hm_2#TKR` zAv=2^R|yN`e%J~2^O1DyH-edI{}iqO3%#;-fh}tszJ*>HqpLDY*T=@V5Lfi)ahz@b z4)F99J_(*(B_a0!W5K~~dpA2oqF88KxN@`zI8O@;?_n$=iH4AM_>XZ_Vyz_FnYzf? zY!!Dz&K6nb_K@3QE@u0=<)a;+c%h>$)CF(x&;k2+biR%aeT*ZMVp&fUyZy0)7W;0g zE78|Fc4YS0QMiPG%8wnLojrPt)1#i)s)V8ZWkXvvf3})J=}B+cABtli(9pPjlsaD{ zgNRLq&Ct58^L$O3KNfCr9;YtTrziV6KjZA1wZ&>aSxuqTvDUykAIHq!d5rhCP>}@a zG4FxdvPbunXdau%?E3e2CqM!v}o( z;A$Ga5K^@;uTAs$1lv{JRuPr};Wh|cHaK=;Sb-;U=n6Vh5bZY{){^XRiQW5nKCsxY zg+pqRf82^Hk(zl&l@~D%-w7OkW~crd9>5rw3$_9FF*psDZOc(S7ifStKr776fc(tF z8#UN2PLs>I_Hhj+W?^1V2upD-eY0uB(b3Vp-Q9afM~~K0wZ*zxs%~}a8gB&_2JMDV z+xRfR+*b#4K9l>L>jKunuke1NP3$PD#km_YNMjv#J zOgrwAoE?2&q^5BJzd_LihECiD>Sz-Byy3YA7g!48|F6kQT=^#Fgcx9~r-rGIp)4()7Qb%5(|6$-Y(a$J~^ZFWAj?&OmvuiujP-SgnY4`#l~U;Q3YAk^HTn7whr+q>v0B1q?sn z`V9EF2zjep#$F48LTB%TC?F&gOJWAlY_KIz#n=pqi1&61d2vEG7C}~;K#5S^$J;ql zJCg>_pR9XG&0~wucGbwfmTHc6YcDXW;h1#RoG#!$0)>f^7jE3RVY|Lm6CIllLu1b0 zkl2L$%HkmZV?0L~JuAGPeXSFR>W5|>zrQ8i_Dr+P0!Ujb4s#NW=N6&8-AI^^1Jm@@ zo}Ph$o}O037KN&XWUc(gBv@6J0N_Ep4yw`Sw>Q3VcgE)# z-jJdpb`V5JSa4Ji{1ziH9m9^Msn^$4Y96~%^Qb!?zjt6?saxY1|9GZCZc?=F_I5>S zZ|{bZhU{jw)p7lfs~b`3vaT0h{{p@*CP`r^VMsVru`@HgaY|`J zfQT?Nw+I4B*bMLUYTd}zkNWk^D(Ox)jLy-HL`2j4Y(pf!w=EP_9zYOh$NR|i^r*+3 znz4P(_)3Q~tp!n`*ItvHvBoL$+rx@_oT=i-O&9AO_rP-Wf!(Hkp;EIt$C{o{N~Wbw zf{7|2R<-y}2nIAYriD+1Vc>vWG8}dD@4I2>h=v0}x2lV}7=-#T zjC<~#6YGoI@2RjF<10VS6Xj=jV6fS!66UAHRJ5?3x&ij{I45kE`L1OF7YZNdEa64O zb63K{Hgn6E$KxU@0rmFXf%;O%nB@x|B%+Lj%0hxTtdy5@n8iD@MN53Wn+r{ z^IO*0T80D56H5-2}_aY0`R8o)LgmNO7As9iiAe3xE~;82K2IMltj#jogkVD0*; zbN9bZQ9R1Y+1Z&XT_29Mc=cg_;CA{TGPufmw|a8+tw&^i&KJa1X1}kitGBl|Ore3k z1Btc&OsCU+O;h)(2!E$)N8G9hX1Q-$DMhPQuKk#w-`y&n&#yx-g(G|o=(^%>+1njD zaeKf&tb1Ex!@4#-Gdp_{ucy52{&T0^Brl>`Z;cLBs~-!7@h)9mKELh`hJ1;>0|Ntl z_wu{=(+Jz+QQb#0%(0sKlIlL{5vhHOrupW$a&5lu>EXyaT6zpz?6W(yS*dKv6Fzyu zEQJBYlx0O|#4rl$6i5bY`nq;JwKZs$5OTR=c4X_;*4+#4Ry-ahHsImyusVTl^wQPhmZ$8-9EDxlGqbT;Fr8f$zn^^6P~RX)R}Ruq-YEpfS#J zL(C*P%M_}{5{MGlNu&*9)mdeYj9Gk{`?q8^n-&!(Uod06D!LuAX!K+ zn~RxJdSR-z-=-#|3Ylf|+Z)}eK&JErv2)<~@q6w$etf^K;hZrgJ~esz^yF0h&+nZ% z59=P5%{U^?;@;K7~SvFvqos zD-*e53o*9V#+uyc>qVGtNVQko?l8pCI|dMpV_@J8h^g3ncS7b)P+S=qJ%cY$&mTXb zC?}4eM=(zJ-J>JQ+K&(_EEH*N#bzB4xx(kwpoISg;lTkjD)^8`54X1R*;YZfQypY% z%GV1p+Y^4Ay3RqYCq9H|ZO;Pt1_TZ<%N3|4qt`evLW4I;n?SuyY)lO-M+qTp*RL7C zT*3?Yc$h#uPDxi8#wB{imPDziXUZM&+d?Rhl|SU3Ldc5dq+Ery)aGvKe}mzuK<;r!L8S9}fI=J+QqY^WG#-hrgFH#|hA5sJ4|XM*k4T0E zAqYoaPgOX=ZdjI+)(b~#|IuWKB!6~+KMx_=_5C=#_6hiBAdX2tFArlh*fhEG(mKmHO4%66PvPeahYz7+ za;lvkb-tC6zwH=?)_HVd zKC#oFnmW@5ixDu3O^i()X3F9}i)e6GX&^!vUP9#nHM|ydjQa#o1aoQ48+|iCUII@!?XL)wH1I zJtOB(`CD(auV15mmG)BhXNVt@8^^j1OX~5ZF^)Cp1N6)?ki&wvxiBjq14ht579Jai zG|YzITj_!y@YBId8&_?-eAkX;<1Je^4(^I#A_9Ee#-T->z`de zrZDijb{-z%1E1$OoseeSdL!{+OyPr=o%xUF^%~w;+^zkvaMDCCmaPRgX9OBt&#CPD zctz4q^Hp%jZS=v;RFa#@camw_=fqk##>-5A|HbR25upY^;Luozltvl;EC`c>bZ#JJ z&**%`DJiY7@J7q+)Tme0ZfnE|ZLYT&C)8khw%Mshm+Hm&>+409IS)Ixz}A&O5Jg-) z?nt<$4Q{-)^uyQQeTavr4;|WQ`fl?D_B_oT^9{LV1B}xH%wHw1)dTl9Re`oTk>;5g zPD$`YA}tSxl@3oN+9LAp^|}DdEN38V?pS6?h**YVvxBtK@z`TRUGK5A3v=Gn&;bJf z0R38p0c&KWw-@KLLhh@L)lTQHV;Bps9yquMLG3#C9K6zeBHAFUoN;~J_1aG7qQ;g|_JxtO@md^><*_v$Q@%_oK3~U?(b=Ot}*1`H4 zVojh-f$F9m!qiGdIhpf9=eZ zsDC4n8Zl>A%>}5I+Qb>?>ZZK7vF*E|e~;xU-bfFq*+`f+??mjJg6pHgr)oz&vV&Fs zK-f7jZLv9fdZw*?jKhz!sbgw#3d`VPC92Le0>R5}`vxtyzS{7R?JpQtyz;CNIkjVx z85Yr<_K=&KS2qTAbKB*IZTrijJoy7ow8G&VS8+s2(&?F)+(H|tO{Cv-2X;lwxh{du zg~5*viY(xAkPS{lTyW|y+caXaf!85P+MDHB@|00L*e*s_*}imWa`F&g_r+o)s6z*?4@O z&WM9k>=tZ4Y}e&}3EUvEOaV8#aD2<*TJRr;zqj?@X!gZVRiP(bMS=)ACR}Al_w$)K zBX@GZ5ZjavTztxrMh$ks?m6;Kr%DjLSsS}r>Pa|xghOr8@gtJxh@Rr%r+s|*&q1p5 z^QyNtIPsVH%vr?We|g9AlmtFwYmkfFU7;RBiRQBGK8KAU6q%p zMR4{$n$~eB#9OXKV2~?zD%h0v?6dG{Q96q-(nYSlB|hZ|tv=|bwjA8oUSh|x=MqXd z>@R!{7_Q%aH!nARuHZ+g_4spZ&(Yzvm+5dmpvE5X1uq@Jp4D~h>^%P?g2>Kfrv}q~ zVxv&N7F2KpkU4O7yV$b%g4mdIqr#R=HqDp4&N?GVZGhFifYkeT3M&8xaDWv?0|qd| zlj~d4GaP4p<9gSwdiZ>8-}rdXKDeHETY3iudf{xMEBg-ankawAURB+@x6g~!U~eSi z#p18GZ|_&O<>cdv!(t^uHv#IMuJ>4J?BI0Wu+j=V58iI2Ro8yBlkMG(HXcMH`=M2? zxjG=x$u@pOc-(KL1Fi&C#bkNZ)r$3FnU0D6RTsJ8b?=&_|G^G#PLpd|dCW>Ht}uPt zN~@3?|IbRh9c?_Wtnx{#Tyr7%u9fz?9-@<0I^Y_iFInlRYk>aFO2@eWyNZQM^3+Ac zEG`?#>EvBy!${s|EUe_y<<#`Z%*f&U7megaV{Xt)E*H&8vQ#W_T{4#`7Luk>Nu~?g zWTjZlFXbvD){TpmO36GnIy#TO)3WQ4OmVrvquyLBT`uPq7Awi2%y81#fYa7%P4i2o ztiGLX*1hk8M%m2at#I1V$k_N%4#_^19ICrvRW>=66rVN>A*2Xlyy8k?Tm3~GU27u0 zjB65ME|aJ&Bh9({@VkHwnt2HCWtcsuT_bQu836*^4>IKzeD@p}vWfIEdND<>C8SE# z`;u^%%!nr@QE!MAtPEsvPX*;g^uL5Q74%&H#6^@<(36P(fTQ@E7rj*QHqN&m5xp;O z@vGj9K1vY4%6Q@ezJj4JgdT=*Z3Y*+ydGN9RY;}Qy|>+dd+>b_uqoqPbK)zLfbC#sIb&U-B|P4M?I9J{nSf+ zbb$J4fCg!ZhUp;PMu#XxBQ%Q0q~mm$CTNnTXqsl|2py$k^d>q^C+K!MiM{)$=uUbw zy@gKGUG!F(rMu}2y^Zdnx6{4!4mwNkr2FU`-A@nDgY+(Xh#sa#=;!EBdW;^Y^K^mI zG)EcAl0oydK#P>4CuoWCv`hsmBD%+uR3?)uv_h+NkuK3?x`I=Je;$Y3y@%e5cvA19 z_tVq#41It;NFSmP)3fvu`Y8PZJx3p-UqtlOkJBgUlk`jUDf(slG<}Ay(P!yb=yUXW z`c?Wh>@)uY{W^V-euKV5&(oLb1^P|;EqalDo4!K7LtjN~hp*8~^t<$X^!xO6`UZWI z{(%0F{)oOse@uTue~L3wzD<8d-$9JMzo75Z_vrid1Nuw)A^jEoHN8xK6EH4i^6BMt z1=O!Erp?7ldLfW4=9!0?xrIU_`14IiFxsuMC!G*Gst{7!ewi9@T=8O3( z?$6|lrjgYO#Y)zg_beLea>Z>{(q;FGX_P&v%`An>My8T3EaZ(;K4(_k^ZE3Gcdl4m zT27ajJh|ocf)Oeig;b@OGVyX{BbdpRGiZH@8`zo5qLEpOST#?s7$$$eYFsva_@6TK z07NL0&Krd+;E+vUHgz!JWus8hZ1G~joxv0k zn9mnWrOT;o&Ro*u7kiDus)16&Q%ai^!+%&@y@N}^4VNr!ONYdO4)gzNL(ypq(lk?V&o&Tws_Gf zi{X-00^0(j>I#k>Fv_wxy^_rpWpXu_HHxywOfhR4^{^EgQ?^zj&ruZ~IL01lNHSDnp%@Rm4 zSi??yy380rAb;6dKt~2}zD7ihWnmj_QUXV6SwWk%tUwxdIbG71!D&FzHrbZaU<5YK znU!KGI1gDTWeG|?eg&Y~k`b~gAjJe4OlPxYW?9T8su`w5yDMfd-dq+moLw+VmNx1phEDr{;1%iSbB{`&s;KQG8g=Tr8ISfE&JYiBZE! z7MS#{@=}_gDVl)e83n7j44~MoV16Z^4_ZtN)L1biHHMJF=PpUE0QOtHER)&Xl`EHn zqSZV`c+tqpTLj~f&=-{pWq=}M`0Pv}Tuq_ltl`Mc8R_M=S}kW&=0!{}(ORLH8cat4 zxCFRpyw*Y%q$-$0tgpZ;6hIO6c~S4^r&25|tQd(}KeB+?7W!}BP|iScygO&*H!gv6 zWCf>EwT}{6ZkG}tA;FkWuPiJ|$cdzA9}`cLdHH;2i`tXHnNxFMBuny!GG=d}KngRN vDM!Xk1Eb5AL!v*<@K-yBmftQ~owER>auGx%o3E5h<(z5F2bCO%+U5Fx63joO literal 0 HcmV?d00001 diff --git a/fonts/fa-solid-900.ttf b/fonts/fa-solid-900.ttf new file mode 100644 index 0000000000000000000000000000000000000000..a0414182dca34041fdd585c0c4b4bd7a3a2753e2 GIT binary patch literal 426112 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

%HINjzu*e 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�Nl|_$ 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

E7E^ziYWPY-|AaZEuP^7qG)} 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ⅅ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 literal 0 HcmV?d00001 diff --git a/imgui.ini b/imgui.ini index bcf75aa..addc155 100644 --- a/imgui.ini +++ b/imgui.ini @@ -9,8 +9,8 @@ Size=400,400 Collapsed=0 [Window][Game Window] -Pos=8,25 -Size=1264,517 +Pos=8,28 +Size=1264,514 Collapsed=0 DockId=0x00000001,0 @@ -21,18 +21,18 @@ Collapsed=0 DockId=0x00000002,0 [Window][##TOAST0] -Pos=1062,643 -Size=198,57 +Pos=1007,637 +Size=253,63 Collapsed=0 [Window][##TOAST1] -Pos=1048,576 -Size=212,57 +Pos=1064,564 +Size=196,63 Collapsed=0 [Window][##TOAST2] -Pos=1048,509 -Size=212,57 +Pos=1064,491 +Size=196,63 Collapsed=0 [Window][##TOAST3] @@ -46,7 +46,7 @@ Size=212,57 Collapsed=0 [Docking][Data] -DockSpace ID=0x9076BACA Window=0x34F970D7 Pos=8,25 Size=1264,687 Split=Y Selected=0x27A02DAA +DockSpace ID=0x9076BACA Window=0x34F970D7 Pos=8,28 Size=1264,684 Split=Y Selected=0x27A02DAA DockNode ID=0x00000001 Parent=0x9076BACA SizeRef=1264,513 CentralNode=1 Selected=0x27A02DAA DockNode ID=0x00000002 Parent=0x9076BACA SizeRef=1264,168 Selected=0xBEDDA0C1 diff --git a/src/gui/GuiManager.cpp b/src/gui/GuiManager.cpp index da7152d..377f3e0 100644 --- a/src/gui/GuiManager.cpp +++ b/src/gui/GuiManager.cpp @@ -18,17 +18,7 @@ void GuiManager::Initialize(Application *application) ImGuiIO &io = ImGui::GetIO(); io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; - io.Fonts->AddFontDefault(); - float baseFontSize = 16.0f; - float iconFontSize = baseFontSize * 2.0f / 3.0f; - - static constexpr ImWchar iconsRanges[] = {ICON_MIN_FA, ICON_MAX_16_FA, 0}; - ImFontConfig iconsConfig; - iconsConfig.MergeMode = true; - iconsConfig.PixelSnapH = true; - iconsConfig.GlyphMinAdvanceX = iconFontSize; - io.Fonts->AddFontFromMemoryCompressedTTF(fa_solid_900_compressed_data, fa_solid_900_compressed_size, iconFontSize, &iconsConfig, iconsRanges); SetTheme(); logWindow.Initialize(); // Initialize the LogWindow @@ -145,6 +135,26 @@ void GuiManager::RenderNotifications() void GuiManager::SetTheme() { + ImGuiIO &io = ImGui::GetIO(); + + io.Fonts->Clear(); + + // Don't clear; just add new fonts and rebuild + io.Fonts->AddFontFromFileTTF("fonts/Inter-Regular.ttf", 16); // index 0 (replaces default) + + // Re-add FontAwesome as merge into default (index 0) + float iconFontSize = 16.0f * 2.0f / 3.0f; + static constexpr ImWchar iconsRanges[] = {ICON_MIN_FA, ICON_MAX_16_FA, 0}; + ImFontConfig iconsConfig; + iconsConfig.MergeMode = true; + iconsConfig.PixelSnapH = true; + iconsConfig.GlyphMinAdvanceX = iconFontSize; + io.Fonts->AddFontFromMemoryCompressedTTF(fa_solid_900_compressed_data, + fa_solid_900_compressed_size, + iconFontSize, &iconsConfig, iconsRanges); + io.Fonts->AddFontFromFileTTF("fonts/JetBrainsMono-Regular.ttf", 16); + io.Fonts->Build(); + ImVec4 *colors = ImGui::GetStyle().Colors; colors[ImGuiCol_Text] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); colors[ImGuiCol_TextDisabled] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f); diff --git a/src/gui/LogWindow.cpp b/src/gui/LogWindow.cpp index a8aeca4..127f3d1 100644 --- a/src/gui/LogWindow.cpp +++ b/src/gui/LogWindow.cpp @@ -13,6 +13,8 @@ void LogWindow::Render(bool& showLogWindow) return; ImGui::Begin("Log Viewer"); + ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[1]); // Assuming mono font is at index 1 + ImGui::BeginChild("LogText", ImVec2(0, 0), true, ImGuiWindowFlags_HorizontalScrollbar); for (const auto& entry : logEntries) @@ -24,6 +26,7 @@ void LogWindow::Render(bool& showLogWindow) ImGui::SetScrollHereY(1.0f); ImGui::EndChild(); + ImGui::PopFont(); ImGui::End(); } From ab5f50d1dcac6feb1fa0c94dd9d34ee351668355 Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Wed, 4 Mar 2026 21:56:38 +1300 Subject: [PATCH 11/53] feat: add support for running editor from justfile --- Justfile | 4 ++++ imgui.ini | 14 ++++++-------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/Justfile b/Justfile index a7c211f..d1574ba 100644 --- a/Justfile +++ b/Justfile @@ -40,6 +40,10 @@ run: @echo "Running simian (Release)..." {{BUILD_DIR}}\Release\simian.exe +run-editor: + @echo "Running simian (Release) with Editor..." + {{BUILD_DIR}}\Release\simian.exe --editor + # Run Debug build run-debug: @echo "Running simian (Debug)..." diff --git a/imgui.ini b/imgui.ini index addc155..0f2592e 100644 --- a/imgui.ini +++ b/imgui.ini @@ -10,15 +10,15 @@ Collapsed=0 [Window][Game Window] Pos=8,28 -Size=1264,514 +Size=1264,684 Collapsed=0 -DockId=0x00000001,0 +DockId=0x9076BACA,0 [Window][Log Viewer] -Pos=8,544 -Size=1264,168 +Pos=8,28 +Size=1264,684 Collapsed=0 -DockId=0x00000002,0 +DockId=0x9076BACA,1 [Window][##TOAST0] Pos=1007,637 @@ -46,7 +46,5 @@ Size=212,57 Collapsed=0 [Docking][Data] -DockSpace ID=0x9076BACA Window=0x34F970D7 Pos=8,28 Size=1264,684 Split=Y Selected=0x27A02DAA - DockNode ID=0x00000001 Parent=0x9076BACA SizeRef=1264,513 CentralNode=1 Selected=0x27A02DAA - DockNode ID=0x00000002 Parent=0x9076BACA SizeRef=1264,168 Selected=0xBEDDA0C1 +DockSpace ID=0x9076BACA Window=0x34F970D7 Pos=8,28 Size=1264,684 CentralNode=1 Selected=0x27A02DAA From 10f6df42c6c5489a8c75563a01bfe660e33251c5 Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Thu, 5 Mar 2026 22:25:29 +1300 Subject: [PATCH 12/53] Remove entt submodule reference, progress on shader testing --- CMakeLists.txt | 2 + imgui.ini | 29 +++++- include/Application.h | 2 + include/entt.hpp | 169 +++++++++++++++++++++++++++++++++ shaders/outline.fs | 37 ++++++++ shaders/toon.fs | 25 +++++ shaders/toon.vs | 17 ++++ src/Application.cpp | 207 +++++++++++++++++++++++++++++++++-------- src/gui/GuiManager.cpp | 2 + 9 files changed, 450 insertions(+), 40 deletions(-) create mode 100644 include/entt.hpp create mode 100644 shaders/outline.fs create mode 100644 shaders/toon.fs create mode 100644 shaders/toon.vs diff --git a/CMakeLists.txt b/CMakeLists.txt index 79f42d4..8909108 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,6 +55,7 @@ add_library(scriptstdstring STATIC target_include_directories(scriptstdstring PUBLIC external/angelscript/sdk/angelscript/include + external/entt/single_include ) # ------------------------- @@ -98,6 +99,7 @@ target_include_directories(simian PUBLIC external/angelscript/sdk/add_on/scriptstdstring external/angelscript/sdk/add_on/scriptbuilder external/imgui + external/entt ) target_link_libraries(simian PRIVATE diff --git a/imgui.ini b/imgui.ini index 0f2592e..8f74068 100644 --- a/imgui.ini +++ b/imgui.ini @@ -21,8 +21,8 @@ Collapsed=0 DockId=0x9076BACA,1 [Window][##TOAST0] -Pos=1007,637 -Size=253,63 +Pos=1060,637 +Size=200,63 Collapsed=0 [Window][##TOAST1] @@ -45,6 +45,31 @@ Pos=1048,375 Size=212,57 Collapsed=0 +[Window][Scene (0 entities)] +Pos=60,60 +Size=32,36 +Collapsed=1 + +[Window][Comic Engine] +Pos=60,60 +Size=387,337 +Collapsed=0 + +[Window][Scene (1 entities)] +Pos=60,60 +Size=71,56 +Collapsed=0 + +[Window][Scene (2 entities)] +Pos=60,60 +Size=71,82 +Collapsed=0 + +[Window][Scene (3 entities)] +Pos=60,60 +Size=71,108 +Collapsed=0 + [Docking][Data] DockSpace ID=0x9076BACA Window=0x34F970D7 Pos=8,28 Size=1264,684 CentralNode=1 Selected=0x27A02DAA diff --git a/include/Application.h b/include/Application.h index 4ea9f3d..78a6ee3 100644 --- a/include/Application.h +++ b/include/Application.h @@ -35,4 +35,6 @@ private: void Update(float deltaTime); void Draw(); + + void SpawnCube(); }; \ No newline at end of file diff --git a/include/entt.hpp b/include/entt.hpp new file mode 100644 index 0000000..d7e4f2a --- /dev/null +++ b/include/entt.hpp @@ -0,0 +1,169 @@ +/*! @brief `EnTT` default namespace. */ +namespace entt {} + +// IWYU pragma: begin_exports +// #include "config/config.h" +#ifndef ENTT_CONFIG_CONFIG_H +#define ENTT_CONFIG_CONFIG_H + +// #include "version.h" +#ifndef ENTT_CONFIG_VERSION_H +#define ENTT_CONFIG_VERSION_H + +// #include "macro.h" +#ifndef ENTT_CONFIG_MACRO_H +#define ENTT_CONFIG_MACRO_H + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#define ENTT_STR(arg) #arg +#define ENTT_XSTR(arg) ENTT_STR(arg) + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*) + +#define ENTT_VERSION_MAJOR 3 +#define ENTT_VERSION_MINOR 16 +#define ENTT_VERSION_PATCH 0 + +#define ENTT_VERSION \ + ENTT_XSTR(ENTT_VERSION_MAJOR) \ + "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH) + +// NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION) +# define ENTT_CONSTEXPR +# define ENTT_THROW throw +# define ENTT_TRY try +# define ENTT_CATCH catch(...) +#else +# define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20) +# define ENTT_THROW +# define ENTT_TRY if(true) +# define ENTT_CATCH if(false) +#endif + +#if __has_include() +# include +# +# if defined(__cpp_consteval) +# define ENTT_CONSTEVAL consteval +# endif +#endif + +#ifndef ENTT_CONSTEVAL +# define ENTT_CONSTEVAL constexpr +#endif + +#ifdef ENTT_USE_ATOMIC +# include +# define ENTT_MAYBE_ATOMIC(Type) std::atomic +#else +# define ENTT_MAYBE_ATOMIC(Type) Type +#endif + +#ifndef ENTT_ID_TYPE +# include +# define ENTT_ID_TYPE std::uint32_t +#else +# include // provides coverage for types in the std namespace +#endif + +#ifndef ENTT_SPARSE_PAGE +# define ENTT_SPARSE_PAGE 4096 +#endif + +#ifndef ENTT_PACKED_PAGE +# define ENTT_PACKED_PAGE 1024 +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT +# define ENTT_ASSERT(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT +# include +# define ENTT_ASSERT(condition, msg) assert(((condition) && (msg))) +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg) +#endif + +#define ENTT_FAIL(msg) ENTT_ASSERT(false, msg); + +#ifdef ENTT_NO_ETO +# define ENTT_ETO_TYPE(Type) void +#else +# define ENTT_ETO_TYPE(Type) Type +#endif + +#ifdef ENTT_NO_MIXIN +# define ENTT_STORAGE(Mixin, ...) __VA_ARGS__ +#else +# define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__> +#endif + +#ifdef ENTT_STANDARD_CPP +# define ENTT_NONSTD false +#else +# define ENTT_NONSTD true +# if defined __clang__ || defined __GNUC__ +# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ +# define ENTT_PRETTY_FUNCTION_PREFIX '=' +# define ENTT_PRETTY_FUNCTION_SUFFIX ']' +# elif defined _MSC_VER +# define ENTT_PRETTY_FUNCTION __FUNCSIG__ +# define ENTT_PRETTY_FUNCTION_PREFIX '<' +# define ENTT_PRETTY_FUNCTION_SUFFIX '>' +# endif +#endif + +#ifndef ENTT_EXPORT +# if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER +# define ENTT_EXPORT __declspec(dllexport) +# define ENTT_IMPORT __declspec(dllimport) +# define ENTT_HIDDEN +# elif defined __GNUC__ && __GNUC__ >= 4 +# define ENTT_EXPORT __attribute__((visibility("default"))) +# define ENTT_IMPORT __attribute__((visibility("default"))) +# define ENTT_HIDDEN __attribute__((visibility("hidden"))) +# else /* Unsupported compiler */ +# define ENTT_EXPORT +# define ENTT_IMPORT +# define ENTT_HIDDEN +# endif +#endif + +#ifndef ENTT_API +# if defined ENTT_API_EXPORT +# define ENTT_API ENTT_EXPORT +# elif defined ENTT_API_IMPORT +# define ENTT_API ENTT_IMPORT +# else /* No API */ +# define ENTT_API +# endif +#endif + +#if defined _MSC_VER +# pragma detect_mismatch("entt.version", ENTT_VERSION) +# pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY)) +# pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE)) +# pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD)) +#endif + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif diff --git a/shaders/outline.fs b/shaders/outline.fs new file mode 100644 index 0000000..5211863 --- /dev/null +++ b/shaders/outline.fs @@ -0,0 +1,37 @@ +#version 330 + +uniform sampler2D texture0; +uniform vec2 textureSize; +uniform int outlineSize = 2; + +in vec2 fragTexCoord; +out vec4 finalColor; + +void main() { + vec2 texel = 1.0 / textureSize; + float center = texture(texture0, fragTexCoord).r; + + if (center < 0.5) { + discard; // Transparent, show scene underneath + return; + } + + // Edge detection + bool edge = false; + for (int y = -outlineSize; y <= outlineSize; y++) { + for (int x = -outlineSize; x <= outlineSize; x++) { + vec2 offset = vec2(float(x), float(y)) * texel; + if (texture(texture0, fragTexCoord + offset).r < 0.5) { + edge = true; + break; + } + } + if (edge) break; + } + + if (edge) { + finalColor = vec4(0, 0, 0, 1); // Black outline + } else { + discard; + } +} diff --git a/shaders/toon.fs b/shaders/toon.fs new file mode 100644 index 0000000..4e52669 --- /dev/null +++ b/shaders/toon.fs @@ -0,0 +1,25 @@ +#version 330 + +in vec3 fragNormal; +in vec3 fragPosition; + +uniform vec3 lightDir; +uniform float bandCount; +uniform vec4 albedo; +out vec4 fragColor; + +void main() { + // Normalize the normal and light direction + vec3 normal = normalize(fragNormal); + vec3 light = normalize(lightDir); + + // Calculate the dot product for lighting + float intensity = max(dot(normal, light), 0.0); + + // Quantize the intensity for toon shading + intensity = floor(intensity * bandCount) / bandCount; + + // Set the fragment color + //fragColor = vec4(vec3(intensity), 1.0); + fragColor = vec4(albedo.rgb , albedo.a); +} \ No newline at end of file diff --git a/shaders/toon.vs b/shaders/toon.vs new file mode 100644 index 0000000..bddb0af --- /dev/null +++ b/shaders/toon.vs @@ -0,0 +1,17 @@ +#version 330 + +layout(location = 0) in vec3 vertexPosition; +layout(location = 1) in vec3 vertexNormal; + +uniform mat4 model; +uniform mat4 view; +uniform mat4 projection; + +out vec3 fragNormal; +out vec3 fragPosition; + +void main() { + fragPosition = vec3(model * vec4(vertexPosition, 1.0)); + fragNormal = mat3(transpose(inverse(model))) * vertexNormal; // Transform normals + gl_Position = projection * view * vec4(fragPosition, 1.0); +} \ No newline at end of file diff --git a/src/Application.cpp b/src/Application.cpp index 8ab04be..0dafa58 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "log/log.h" #include "rlImGui.h" @@ -31,6 +32,36 @@ Application::~Application() // Shutdown(); } +/// Shader and rendering data for the demo scene +Camera3D camera; +RenderTexture2D sceneRT, maskRT; +Shader toonShader, outlineShader; +Model cube; + +float globalBandCount = 3.0f; +Vector3 lightDir = {0.5f, 0.7f, 0.3f}; +bool showEditor = true; +bool dayMode = true; +entt::registry ecs; +std::vector models; +struct ECS_Transform +{ + Vector3 pos, scale; + float rot; +}; +struct Render +{ + int modelId; + float outlineSize; + Color color; +}; +struct ECS_Material +{ + Shader shader; + int lightLoc, bandLoc; +}; +/// ====== + bool Application::Initialize(int argc, char *argv[]) { if (fopen_s(&logFile, "log.txt", "w") != 0) @@ -55,6 +86,7 @@ bool Application::Initialize(int argc, char *argv[]) enableEditor = true; } } + // Initialize Raylib InitWindow(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_TITLE); SetTargetFPS(TARGET_FPS); @@ -87,9 +119,38 @@ bool Application::Initialize(int argc, char *argv[]) renderTexture = LoadRenderTexture(WINDOW_WIDTH, WINDOW_HEIGHT); } + camera.position = {5, 5, 5}; + camera.target = {0, 0, 0}; + camera.up = {0, 1, 0}; + camera.fovy = 45; + + // Assets + cube = LoadModelFromMesh(GenMeshCube(1, 1, 1)); + models.push_back(cube); + // Shaders (toon + outline) + toonShader = LoadShader(0, "shaders/toon.fs"); + outlineShader = LoadShader(0, "shaders/outline.fs"); + + // Render textures + sceneRT = LoadRenderTexture(1280, 720); + maskRT = LoadRenderTexture(1280, 720); + + // Cache uniform locations + cube.materials[0].shader = toonShader; + return true; } - +void Application::SpawnCube() +{ + auto e = ecs.create(); + ecs.emplace( + e, + Vector3{static_cast(rand() % 3 - 1), 0.0f, static_cast(rand() % 3 - 1)}, // Position + Vector3{1.0f, 1.0f, 1.0f}, // Scale + 0.0f // Rotation + ); + ecs.emplace(e, 0, 2.0f, YELLOW); +} void Application::Run() { scriptEngine.CallScriptFunction(scriptEngine.GetInitFunction()); @@ -116,62 +177,125 @@ void Application::Update(float deltaTime) { log_warn("Script compilation failed - keeping previous version"); Toast::Warning("Script compilation failed - check console for details."); - } else { + } + else + { Toast::Success("Script reloaded successfully."); - //Should call init function again or things don't work + // Should call init function again or things don't work scriptEngine.CallScriptFunction(scriptEngine.GetInitFunction()); } } // Call script Update function scriptEngine.CallScriptFunction(scriptEngine.GetUpdateFunction(), deltaTime); + + UpdateCamera(&camera, CAMERA_ORBITAL); + + // Day/night toggle + if (IsKeyPressed(KEY_SPACE)) + dayMode = !dayMode; + globalBandCount = dayMode ? 3.0f : 2.0f; + + // F1 editor toggle + if (IsKeyPressed(KEY_F1)) + showEditor = !showEditor; + + if (IsKeyPressed(KEY_F2)) + SpawnCube(); } void Application::Draw() { + + int screenWidth = GetScreenWidth(); + int screenHeight = GetScreenHeight(); + + // Fallback to default values if screen dimensions are invalid + if (screenWidth <= 0 || screenHeight <= 0) + { + log_warn("Invalid screen dimensions: %d x %d. Using default values.", screenWidth, screenHeight); + screenWidth = 800; + screenHeight = 600; + } + + ImGuiIO &io = ImGui::GetIO(); + io.DisplaySize = ImVec2((float)screenWidth, (float)screenHeight); // Set DisplaySize + + BeginTextureMode(renderTexture); + + ClearBackground(SKYBLUE); + BeginMode3D(camera); + DrawGrid(10, 1); + DrawLine3D(Vector3{0, 0, 0}, Vector3{lightDir.x * 5.0f, lightDir.y * 5.0f, lightDir.z * 5.0f}, RED); + BeginShaderMode(toonShader); + SetShaderValue(toonShader, GetShaderLocation(toonShader, "lightDir"), &lightDir, SHADER_UNIFORM_VEC3); + SetShaderValue(toonShader, GetShaderLocation(toonShader, "bandCount"), &globalBandCount, SHADER_UNIFORM_FLOAT); + + auto view = ecs.view(); + view.each([&](const auto &t, const auto &r) + { + Vector4 color = {r.color.r / 255.0f, r.color.g / 255.0f, r.color.b / 255.0f, r.color.a / 255.0f}; + SetShaderValue(toonShader, GetShaderLocation(toonShader, "albedo"), &color, SHADER_UNIFORM_VEC4); + DrawModel(models[r.modelId], t.pos, 1.0f, WHITE); // Use WHITE since color is handled by the shader + }); + + EndShaderMode(); + + EndMode3D(); + // Call script Draw function + scriptEngine.CallScriptFunction(scriptEngine.GetDrawFunction()); + + // 2. Silhouette mask + // BeginTextureMode(maskRT); + // ClearBackground(WHITE); + // BeginMode3D(camera); + + // for (auto e : ecs.view()) + // { + // auto &t = ecs.get(e); + // DrawModel(models[ecs.get(e).modelId], t.pos, 1.0f, BLACK); + // } + + // EndMode3D(); + // EndTextureMode(); + + // // 3. Outline postprocess + // BeginShaderMode(outlineShader); + // Rectangle src = {0, 0, (float)maskRT.texture.width, (float)-maskRT.texture.height}; + // DrawTextureRec(maskRT.texture, src, {0, 0}, WHITE); + EndShaderMode(); + EndTextureMode(); if (enableEditor) { - int screenWidth = GetScreenWidth(); - int screenHeight = GetScreenHeight(); - - // Fallback to default values if screen dimensions are invalid - if (screenWidth <= 0 || screenHeight <= 0) - { - log_warn("Invalid screen dimensions: %d x %d. Using default values.", screenWidth, screenHeight); - screenWidth = 800; - screenHeight = 600; - } - - ImGuiIO &io = ImGui::GetIO(); - io.DisplaySize = ImVec2((float)screenWidth, (float)screenHeight); // Set DisplaySize - - BeginTextureMode(renderTexture); - ClearBackground(RAYWHITE); - - // Call script Draw function - scriptEngine.CallScriptFunction(scriptEngine.GetDrawFunction()); - - EndTextureMode(); BeginDrawing(); ClearBackground(RAYWHITE); guiManager.Render(renderTexture); // Render the GUI - EndDrawing(); - } - else - { - BeginDrawing(); - ClearBackground(RAYWHITE); + // rlImGuiBegin(); + // ImGui::Begin("Comic Engine"); + // std::string fpsText = "FPS: " + std::to_string(GetFPS()); + // ImGui::Text(fpsText.c_str()); + // if (ImGui::Button("Spawn Cube")) + // SpawnCube(); + // ImGui::Checkbox("Day Mode", &dayMode); + // ImGui::SliderFloat("Band Count", &globalBandCount, 1.0f, 5.0f); + // ImGui::ColorEdit3("Light Dir", &lightDir.x); + // ImGui::Text("F1: Toggle editor"); + // ImGui::End(); - // Show script error status in top left if there's an error, otherwise show normal message - if (scriptCompilationError) - { - DrawText("SCRIPT ERROR - Check console for details", 10, 10, 16, RED); - } - - // Call script Draw function - scriptEngine.CallScriptFunction(scriptEngine.GetDrawFunction()); + // // Scene hierarchy + // std::string sceneTitle = "Scene (" + std::to_string(ecs.view().size()) + " entities)"; + // ImGui::Begin(sceneTitle.c_str()); + // for (auto e : ecs.view()) + // { + // if (ImGui::Button(std::string("Cube " + std::to_string((int)e)).c_str())) + // { + // ecs.get(e).pos.x += 1.0f; + // } + // } + // ImGui::End(); + // rlImGuiEnd(); EndDrawing(); } @@ -197,6 +321,13 @@ void Application::Shutdown() // Shutdown script engine scriptEngine.Shutdown(); + // Unload assets + UnloadModel(cube); + UnloadShader(toonShader); + UnloadShader(outlineShader); + UnloadRenderTexture(sceneRT); + UnloadRenderTexture(maskRT); + // Clear the trace log callback before closing window to prevent logging after cleanup SetTraceLogCallback(nullptr); CloseWindow(); diff --git a/src/gui/GuiManager.cpp b/src/gui/GuiManager.cpp index 377f3e0..2503e9c 100644 --- a/src/gui/GuiManager.cpp +++ b/src/gui/GuiManager.cpp @@ -33,6 +33,8 @@ void GuiManager::Render(RenderTexture2D &renderTexture) RenderErrorBanner(); RenderNotifications(); logWindow.Render(showLogWindow); // Render the LogWindow + + rlImGuiEnd(); ImGui::UpdatePlatformWindows(); From fc4489d211425ae3ad5959d99a46e1a51bc766d4 Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Thu, 5 Mar 2026 22:38:41 +1300 Subject: [PATCH 13/53] fix: code re-org --- CMakeLists.txt | 2 - imgui.ini | 18 +- include/entt.hpp | 95734 ++++++++++++++++++++++++++++++++++++++++++ src/Application.cpp | 2 +- 4 files changed, 95745 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8909108..79f42d4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,7 +55,6 @@ add_library(scriptstdstring STATIC target_include_directories(scriptstdstring PUBLIC external/angelscript/sdk/angelscript/include - external/entt/single_include ) # ------------------------- @@ -99,7 +98,6 @@ target_include_directories(simian PUBLIC external/angelscript/sdk/add_on/scriptstdstring external/angelscript/sdk/add_on/scriptbuilder external/imgui - external/entt ) target_link_libraries(simian PRIVATE diff --git a/imgui.ini b/imgui.ini index 8f74068..3cc24d0 100644 --- a/imgui.ini +++ b/imgui.ini @@ -10,19 +10,19 @@ Collapsed=0 [Window][Game Window] Pos=8,28 -Size=1264,684 +Size=1264,580 Collapsed=0 -DockId=0x9076BACA,0 +DockId=0x00000001,0 [Window][Log Viewer] -Pos=8,28 -Size=1264,684 +Pos=8,610 +Size=1264,102 Collapsed=0 -DockId=0x9076BACA,1 +DockId=0x00000002,0 [Window][##TOAST0] -Pos=1060,637 -Size=200,63 +Pos=1007,637 +Size=253,63 Collapsed=0 [Window][##TOAST1] @@ -71,5 +71,7 @@ Size=71,108 Collapsed=0 [Docking][Data] -DockSpace ID=0x9076BACA Window=0x34F970D7 Pos=8,28 Size=1264,684 CentralNode=1 Selected=0x27A02DAA +DockSpace ID=0x9076BACA Window=0x34F970D7 Pos=8,28 Size=1264,684 Split=Y Selected=0x27A02DAA + DockNode ID=0x00000001 Parent=0x9076BACA SizeRef=1264,580 CentralNode=1 Selected=0x27A02DAA + DockNode ID=0x00000002 Parent=0x9076BACA SizeRef=1264,102 Selected=0xBEDDA0C1 diff --git a/include/entt.hpp b/include/entt.hpp index d7e4f2a..90a121b 100644 --- a/include/entt.hpp +++ b/include/entt.hpp @@ -167,3 +167,95737 @@ namespace entt {} // NOLINTEND(cppcoreguidelines-macro-usage) #endif + +// #include "config/macro.h" +#ifndef ENTT_CONFIG_MACRO_H +#define ENTT_CONFIG_MACRO_H + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#define ENTT_STR(arg) #arg +#define ENTT_XSTR(arg) ENTT_STR(arg) + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + +// #include "config/version.h" +#ifndef ENTT_CONFIG_VERSION_H +#define ENTT_CONFIG_VERSION_H + +// #include "macro.h" + + +// NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*) + +#define ENTT_VERSION_MAJOR 3 +#define ENTT_VERSION_MINOR 16 +#define ENTT_VERSION_PATCH 0 + +#define ENTT_VERSION \ + ENTT_XSTR(ENTT_VERSION_MAJOR) \ + "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH) + +// NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*) + +#endif + +// #include "container/dense_map.hpp" +#ifndef ENTT_CONTAINER_DENSE_MAP_HPP +#define ENTT_CONTAINER_DENSE_MAP_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #include "../config/config.h" +#ifndef ENTT_CONFIG_CONFIG_H +#define ENTT_CONFIG_CONFIG_H + +// #include "version.h" +#ifndef ENTT_CONFIG_VERSION_H +#define ENTT_CONFIG_VERSION_H + +// #include "macro.h" +#ifndef ENTT_CONFIG_MACRO_H +#define ENTT_CONFIG_MACRO_H + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#define ENTT_STR(arg) #arg +#define ENTT_XSTR(arg) ENTT_STR(arg) + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*) + +#define ENTT_VERSION_MAJOR 3 +#define ENTT_VERSION_MINOR 16 +#define ENTT_VERSION_PATCH 0 + +#define ENTT_VERSION \ + ENTT_XSTR(ENTT_VERSION_MAJOR) \ + "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH) + +// NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION) +# define ENTT_CONSTEXPR +# define ENTT_THROW throw +# define ENTT_TRY try +# define ENTT_CATCH catch(...) +#else +# define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20) +# define ENTT_THROW +# define ENTT_TRY if(true) +# define ENTT_CATCH if(false) +#endif + +#if __has_include() +# include +# +# if defined(__cpp_consteval) +# define ENTT_CONSTEVAL consteval +# endif +#endif + +#ifndef ENTT_CONSTEVAL +# define ENTT_CONSTEVAL constexpr +#endif + +#ifdef ENTT_USE_ATOMIC +# include +# define ENTT_MAYBE_ATOMIC(Type) std::atomic +#else +# define ENTT_MAYBE_ATOMIC(Type) Type +#endif + +#ifndef ENTT_ID_TYPE +# include +# define ENTT_ID_TYPE std::uint32_t +#else +# include // provides coverage for types in the std namespace +#endif + +#ifndef ENTT_SPARSE_PAGE +# define ENTT_SPARSE_PAGE 4096 +#endif + +#ifndef ENTT_PACKED_PAGE +# define ENTT_PACKED_PAGE 1024 +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT +# define ENTT_ASSERT(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT +# include +# define ENTT_ASSERT(condition, msg) assert(((condition) && (msg))) +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg) +#endif + +#define ENTT_FAIL(msg) ENTT_ASSERT(false, msg); + +#ifdef ENTT_NO_ETO +# define ENTT_ETO_TYPE(Type) void +#else +# define ENTT_ETO_TYPE(Type) Type +#endif + +#ifdef ENTT_NO_MIXIN +# define ENTT_STORAGE(Mixin, ...) __VA_ARGS__ +#else +# define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__> +#endif + +#ifdef ENTT_STANDARD_CPP +# define ENTT_NONSTD false +#else +# define ENTT_NONSTD true +# if defined __clang__ || defined __GNUC__ +# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ +# define ENTT_PRETTY_FUNCTION_PREFIX '=' +# define ENTT_PRETTY_FUNCTION_SUFFIX ']' +# elif defined _MSC_VER +# define ENTT_PRETTY_FUNCTION __FUNCSIG__ +# define ENTT_PRETTY_FUNCTION_PREFIX '<' +# define ENTT_PRETTY_FUNCTION_SUFFIX '>' +# endif +#endif + +#ifndef ENTT_EXPORT +# if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER +# define ENTT_EXPORT __declspec(dllexport) +# define ENTT_IMPORT __declspec(dllimport) +# define ENTT_HIDDEN +# elif defined __GNUC__ && __GNUC__ >= 4 +# define ENTT_EXPORT __attribute__((visibility("default"))) +# define ENTT_IMPORT __attribute__((visibility("default"))) +# define ENTT_HIDDEN __attribute__((visibility("hidden"))) +# else /* Unsupported compiler */ +# define ENTT_EXPORT +# define ENTT_IMPORT +# define ENTT_HIDDEN +# endif +#endif + +#ifndef ENTT_API +# if defined ENTT_API_EXPORT +# define ENTT_API ENTT_EXPORT +# elif defined ENTT_API_IMPORT +# define ENTT_API ENTT_IMPORT +# else /* No API */ +# define ENTT_API +# endif +#endif + +#if defined _MSC_VER +# pragma detect_mismatch("entt.version", ENTT_VERSION) +# pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY)) +# pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE)) +# pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD)) +#endif + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + +// #include "../core/bit.hpp" +#ifndef ENTT_CORE_BIT_HPP +#define ENTT_CORE_BIT_HPP + +#include +#include +#include +// #include "../config/config.h" +#ifndef ENTT_CONFIG_CONFIG_H +#define ENTT_CONFIG_CONFIG_H + +// #include "version.h" +#ifndef ENTT_CONFIG_VERSION_H +#define ENTT_CONFIG_VERSION_H + +// #include "macro.h" +#ifndef ENTT_CONFIG_MACRO_H +#define ENTT_CONFIG_MACRO_H + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#define ENTT_STR(arg) #arg +#define ENTT_XSTR(arg) ENTT_STR(arg) + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*) + +#define ENTT_VERSION_MAJOR 3 +#define ENTT_VERSION_MINOR 16 +#define ENTT_VERSION_PATCH 0 + +#define ENTT_VERSION \ + ENTT_XSTR(ENTT_VERSION_MAJOR) \ + "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH) + +// NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION) +# define ENTT_CONSTEXPR +# define ENTT_THROW throw +# define ENTT_TRY try +# define ENTT_CATCH catch(...) +#else +# define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20) +# define ENTT_THROW +# define ENTT_TRY if(true) +# define ENTT_CATCH if(false) +#endif + +#if __has_include() +# include +# +# if defined(__cpp_consteval) +# define ENTT_CONSTEVAL consteval +# endif +#endif + +#ifndef ENTT_CONSTEVAL +# define ENTT_CONSTEVAL constexpr +#endif + +#ifdef ENTT_USE_ATOMIC +# include +# define ENTT_MAYBE_ATOMIC(Type) std::atomic +#else +# define ENTT_MAYBE_ATOMIC(Type) Type +#endif + +#ifndef ENTT_ID_TYPE +# include +# define ENTT_ID_TYPE std::uint32_t +#else +# include // provides coverage for types in the std namespace +#endif + +#ifndef ENTT_SPARSE_PAGE +# define ENTT_SPARSE_PAGE 4096 +#endif + +#ifndef ENTT_PACKED_PAGE +# define ENTT_PACKED_PAGE 1024 +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT +# define ENTT_ASSERT(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT +# include +# define ENTT_ASSERT(condition, msg) assert(((condition) && (msg))) +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg) +#endif + +#define ENTT_FAIL(msg) ENTT_ASSERT(false, msg); + +#ifdef ENTT_NO_ETO +# define ENTT_ETO_TYPE(Type) void +#else +# define ENTT_ETO_TYPE(Type) Type +#endif + +#ifdef ENTT_NO_MIXIN +# define ENTT_STORAGE(Mixin, ...) __VA_ARGS__ +#else +# define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__> +#endif + +#ifdef ENTT_STANDARD_CPP +# define ENTT_NONSTD false +#else +# define ENTT_NONSTD true +# if defined __clang__ || defined __GNUC__ +# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ +# define ENTT_PRETTY_FUNCTION_PREFIX '=' +# define ENTT_PRETTY_FUNCTION_SUFFIX ']' +# elif defined _MSC_VER +# define ENTT_PRETTY_FUNCTION __FUNCSIG__ +# define ENTT_PRETTY_FUNCTION_PREFIX '<' +# define ENTT_PRETTY_FUNCTION_SUFFIX '>' +# endif +#endif + +#ifndef ENTT_EXPORT +# if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER +# define ENTT_EXPORT __declspec(dllexport) +# define ENTT_IMPORT __declspec(dllimport) +# define ENTT_HIDDEN +# elif defined __GNUC__ && __GNUC__ >= 4 +# define ENTT_EXPORT __attribute__((visibility("default"))) +# define ENTT_IMPORT __attribute__((visibility("default"))) +# define ENTT_HIDDEN __attribute__((visibility("hidden"))) +# else /* Unsupported compiler */ +# define ENTT_EXPORT +# define ENTT_IMPORT +# define ENTT_HIDDEN +# endif +#endif + +#ifndef ENTT_API +# if defined ENTT_API_EXPORT +# define ENTT_API ENTT_EXPORT +# elif defined ENTT_API_IMPORT +# define ENTT_API ENTT_IMPORT +# else /* No API */ +# define ENTT_API +# endif +#endif + +#if defined _MSC_VER +# pragma detect_mismatch("entt.version", ENTT_VERSION) +# pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY)) +# pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE)) +# pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD)) +#endif + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +namespace entt { + +/** + * @brief Returns the number of set bits in a value (waiting for C++20 and + * `std::popcount`). + * @tparam Type Unsigned integer type. + * @param value A value of unsigned integer type. + * @return The number of set bits in the value. + */ +template +[[nodiscard]] constexpr std::enable_if_t, int> popcount(const Type value) noexcept { + return value ? (int(value & 1) + popcount(static_cast(value >> 1))) : 0; +} + +/** + * @brief Checks whether a value is a power of two or not (waiting for C++20 and + * `std::has_single_bit`). + * @tparam Type Unsigned integer type. + * @param value A value of unsigned integer type. + * @return True if the value is a power of two, false otherwise. + */ +template +[[nodiscard]] constexpr std::enable_if_t, bool> has_single_bit(const Type value) noexcept { + return value && ((value & (value - 1)) == 0); +} + +/** + * @brief Computes the smallest power of two greater than or equal to a value + * (waiting for C++20 and `std::bit_ceil`). + * @tparam Type Unsigned integer type. + * @param value A value of unsigned integer type. + * @return The smallest power of two greater than or equal to the given value. + */ +template +[[nodiscard]] constexpr std::enable_if_t, Type> next_power_of_two(const Type value) noexcept { + // NOLINTNEXTLINE(bugprone-assert-side-effect) + ENTT_ASSERT_CONSTEXPR(value < (Type{1u} << (std::numeric_limits::digits - 1)), "Numeric limits exceeded"); + Type curr = value - (value != 0u); + + for(int next = 1; next < std::numeric_limits::digits; next = next * 2) { + curr |= (curr >> next); + } + + return ++curr; +} + +/** + * @brief Fast module utility function (powers of two only). + * @tparam Type Unsigned integer type. + * @param value A value of unsigned integer type. + * @param mod _Modulus_, it must be a power of two. + * @return The common remainder. + */ +template +[[nodiscard]] constexpr std::enable_if_t, Type> fast_mod(const Type value, const std::size_t mod) noexcept { + ENTT_ASSERT_CONSTEXPR(has_single_bit(mod), "Value must be a power of two"); + return static_cast(value & (mod - 1u)); +} + +} // namespace entt + +#endif + +// #include "../core/compressed_pair.hpp" +#ifndef ENTT_CORE_COMPRESSED_PAIR_HPP +#define ENTT_CORE_COMPRESSED_PAIR_HPP + +#include +#include +#include +#include +// #include "fwd.hpp" +#ifndef ENTT_CORE_FWD_HPP +#define ENTT_CORE_FWD_HPP + +#include +#include +// #include "../config/config.h" + + +namespace entt { + +/*! @brief Possible modes of an any object. */ +enum class any_policy : std::uint8_t { + /*! @brief Default mode, no element available. */ + empty, + /*! @brief Owning mode, dynamically allocated element. */ + dynamic, + /*! @brief Owning mode, embedded element. */ + embedded, + /*! @brief Aliasing mode, non-const reference. */ + ref, + /*! @brief Const aliasing mode, const reference. */ + cref +}; + +// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) +template +class basic_any; + +/*! @brief Alias declaration for type identifiers. */ +using id_type = ENTT_ID_TYPE; + +/*! @brief Alias declaration for the most common use case. */ +using any = basic_any<>; + +template +class compressed_pair; + +template +class basic_hashed_string; + +/*! @brief Aliases for common character types. */ +using hashed_string = basic_hashed_string; + +/*! @brief Aliases for common character types. */ +using hashed_wstring = basic_hashed_string; + +// NOLINTNEXTLINE(bugprone-forward-declaration-namespace) +struct type_info; + +} // namespace entt + +#endif + +// #include "type_traits.hpp" +#ifndef ENTT_CORE_TYPE_TRAITS_HPP +#define ENTT_CORE_TYPE_TRAITS_HPP + +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "fwd.hpp" + + +namespace entt { + +/** + * @brief Utility class to disambiguate overloaded functions. + * @tparam N Number of choices available. + */ +template +struct choice_t + // unfortunately, doxygen cannot parse such a construct + : /*! @cond TURN_OFF_DOXYGEN */ choice_t /*! @endcond */ +{}; + +/*! @copybrief choice_t */ +template<> +struct choice_t<0> {}; + +/** + * @brief Variable template for the choice trick. + * @tparam N Number of choices available. + */ +template +inline constexpr choice_t choice{}; + +/** + * @brief Identity type trait. + * + * Useful to establish non-deduced contexts in template argument deduction + * (waiting for C++20) or to provide types through function arguments. + * + * @tparam Type A type. + */ +template +struct type_identity { + /*! @brief Identity type. */ + using type = Type; +}; + +/** + * @brief Helper type. + * @tparam Type A type. + */ +template +using type_identity_t = typename type_identity::type; + +/** + * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains. + * @tparam Type The type of which to return the size. + */ +template +struct size_of: std::integral_constant {}; + +/*! @copydoc size_of */ +template +struct size_of> + // NOLINTNEXTLINE(bugprone-sizeof-expression) + : std::integral_constant {}; + +/** + * @brief Helper variable template. + * @tparam Type The type of which to return the size. + */ +template +inline constexpr std::size_t size_of_v = size_of::value; + +/** + * @brief Using declaration to be used to _repeat_ the same type a number of + * times equal to the size of a given parameter pack. + * @tparam Type A type to repeat. + */ +template +using unpack_as_type = Type; + +/** + * @brief Helper variable template to be used to _repeat_ the same value a + * number of times equal to the size of a given parameter pack. + * @tparam Value A value to repeat. + */ +template +inline constexpr auto unpack_as_value = Value; + +/** + * @brief Wraps a static constant. + * @tparam Value A static constant. + */ +template +using integral_constant = std::integral_constant; + +/** + * @brief Alias template to facilitate the creation of named values. + * @tparam Value A constant value at least convertible to `id_type`. + */ +template +using tag = integral_constant; + +/** + * @brief A class to use to push around lists of types, nothing more. + * @tparam Type Types provided by the type list. + */ +template +struct type_list { + /*! @brief Type list type. */ + using type = type_list; + /*! @brief Compile-time number of elements in the type list. */ + static constexpr auto size = sizeof...(Type); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_element; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Index Index of the type to return. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element> + : type_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element<0u, type_list> { + /*! @brief Searched type. */ + using type = First; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Type list to search into. + */ +template +using type_list_element_t = typename type_list_element::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_index; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 1u + type_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + static_assert(type_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +inline constexpr std::size_t type_list_index_v = type_list_index::value; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @return A type list composed by the types of both the type lists. + */ +template +constexpr type_list operator+(type_list, type_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_cat; + +/*! @brief Concatenates multiple type lists. */ +template<> +struct type_list_cat<> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list<>; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @tparam List Other type lists, if any. + */ +template +struct type_list_cat, type_list, List...> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = typename type_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the type list. + */ +template +struct type_list_cat> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list; +}; + +/** + * @brief Helper type. + * @tparam List Type lists to concatenate. + */ +template +using type_list_cat_t = typename type_list_cat::type; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct type_list_unique; + +template +struct type_list_unique, Type...> + : std::conditional_t<(std::is_same_v || ...), type_list_unique, Type...>, type_list_unique, Type..., First>> {}; + +template +struct type_list_unique, Type...> { + using type = type_list; +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Removes duplicates types from a type list. + * @tparam List Type list. + */ +template +struct type_list_unique { + /*! @brief A type list without duplicate types. */ + using type = typename internal::type_list_unique::type; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + */ +template +using type_list_unique_t = typename type_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a type list contains a + * given type, false otherwise. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +struct type_list_contains; + +/** + * @copybrief type_list_contains + * @tparam Type Types provided by the type list. + * @tparam Other Type to look for. + */ +template +struct type_list_contains, Other> + : std::bool_constant<(std::is_same_v || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +inline constexpr bool type_list_contains_v = type_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_diff; + +/** + * @brief Computes the difference between two type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + */ +template +struct type_list_diff, type_list> { + /*! @brief A type list that is the difference between the two type lists. */ + using type = type_list_cat_t, Type>, type_list<>, type_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Type lists between which to compute the difference. + */ +template +using type_list_diff_t = typename type_list_diff::type; + +/*! @brief Primary template isn't defined on purpose. */ +template class> +struct type_list_transform; + +/** + * @brief Applies a given _function_ to a type list and generate a new list. + * @tparam Type Types provided by the type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +struct type_list_transform, Op> { + /*! @brief Resulting type list after applying the transform function. */ + // NOLINTNEXTLINE(modernize-type-traits) + using type = type_list::type...>; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +using type_list_transform_t = typename type_list_transform::type; + +/** + * @brief A class to use to push around lists of constant values, nothing more. + * @tparam Value Values provided by the value list. + */ +template +struct value_list { + /*! @brief Value list type. */ + using type = value_list; + /*! @brief Compile-time number of elements in the value list. */ + static constexpr auto size = sizeof...(Value); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_element; + +/** + * @brief Provides compile-time indexed access to the values of a value list. + * @tparam Index Index of the value to return. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element> + : value_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element<0u, value_list> { + /*! @brief Searched type. */ + using type = decltype(Value); + /*! @brief Searched value. */ + static constexpr auto value = Value; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Value list to search into. + */ +template +using value_list_element_t = typename value_list_element::type; + +/** + * @brief Helper type. + * @tparam Index Index of the value to return. + * @tparam List Value list to search into. + */ +template +inline constexpr auto value_list_element_v = value_list_element::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_index; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam First First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 1u + value_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + static_assert(value_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +inline constexpr std::size_t value_list_index_v = value_list_index::value; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @return A value list composed by the values of both the value lists. + */ +template +constexpr value_list operator+(value_list, value_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_cat; + +/*! @brief Concatenates multiple value lists. */ +template<> +struct value_list_cat<> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list<>; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @tparam List Other value lists, if any. + */ +template +struct value_list_cat, value_list, List...> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = typename value_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the value list. + */ +template +struct value_list_cat> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list; +}; + +/** + * @brief Helper type. + * @tparam List Value lists to concatenate. + */ +template +using value_list_cat_t = typename value_list_cat::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_unique; + +/** + * @brief Removes duplicates values from a value list. + * @tparam Value One of the values provided by the given value list. + * @tparam Other The other values provided by the given value list. + */ +template +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = std::conditional_t< + ((Value == Other) || ...), + typename value_list_unique>::type, + value_list_cat_t, typename value_list_unique>::type>>; +}; + +/*! @brief Removes duplicates values from a value list. */ +template<> +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = value_list<>; +}; + +/** + * @brief Helper type. + * @tparam Type A value list. + */ +template +using value_list_unique_t = typename value_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a value list contains + * a given value, false otherwise. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +struct value_list_contains; + +/** + * @copybrief value_list_contains + * @tparam Value Values provided by the value list. + * @tparam Other Value to look for. + */ +template +struct value_list_contains, Other> + : std::bool_constant<((Value == Other) || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +inline constexpr bool value_list_contains_v = value_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_diff; + +/** + * @brief Computes the difference between two value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + */ +template +struct value_list_diff, value_list> { + /*! @brief A value list that is the difference between the two value lists. */ + using type = value_list_cat_t, Value>, value_list<>, value_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Value lists between which to compute the difference. + */ +template +using value_list_diff_t = typename value_list_diff::type; + +/*! @brief Same as std::is_invocable, but with tuples. */ +template +struct is_applicable: std::false_type {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @brief Helper variable template. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_v = is_applicable::value; + +/*! @brief Same as std::is_invocable_r, but with tuples for arguments. */ +template +struct is_applicable_r: std::false_type {}; + +/** + * @copybrief is_applicable_r + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +struct is_applicable_r>: std::is_invocable_r {}; + +/** + * @brief Helper variable template. + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_r_v = is_applicable_r::value; + +/** + * @brief Provides the member constant `value` to true if a given type is + * complete, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_complete: std::false_type {}; + +/*! @copydoc is_complete */ +template +struct is_complete>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_complete_v = is_complete::value; + +/** + * @brief Provides the member constant `value` to true if a given type is an + * iterator, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_iterator: std::false_type {}; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_iterator_category: std::false_type {}; + +template +struct has_iterator_category::iterator_category>>: std::true_type {}; + +} // namespace internal +/*! @endcond */ + +/*! @copydoc is_iterator */ +template +struct is_iterator>>>> + : internal::has_iterator_category {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_iterator_v = is_iterator::value; + +/** + * @brief Provides the member constant `value` to true if a given type is both + * an empty and non-final class, false otherwise. + * @tparam Type The type to test + */ +template +struct is_ebco_eligible + : std::bool_constant && !std::is_final_v> {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_ebco_eligible_v = is_ebco_eligible::value; + +/** + * @brief Provides the member constant `value` to true if `Type::is_transparent` + * is valid and denotes a type, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_transparent: std::false_type {}; + +/*! @copydoc is_transparent */ +template +struct is_transparent>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_transparent_v = is_transparent::value; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_tuple_size_value: std::false_type {}; + +template +struct has_tuple_size_value::value)>>: std::true_type {}; + +template +struct has_value_type: std::false_type {}; + +template +struct has_value_type>: std::true_type {}; + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable(); + +template +[[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence) { + return (dispatch_is_equality_comparable>() && ...); +} + +template +[[nodiscard]] constexpr bool maybe_equality_comparable(char) { + return false; +} + +template +[[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval() == std::declval()) { + return true; +} + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable() { + // NOLINTBEGIN(modernize-use-transparent-functors) + if constexpr(std::is_array_v) { + return false; + } else if constexpr(is_complete_v>>) { + if constexpr(has_tuple_size_value::value) { + return maybe_equality_comparable(0) && unpack_maybe_equality_comparable(std::make_index_sequence::value>{}); + } else { + return maybe_equality_comparable(0); + } + } else if constexpr(has_value_type::value) { + if constexpr(is_iterator_v || std::is_same_v || dispatch_is_equality_comparable()) { + return maybe_equality_comparable(0); + } else { + return false; + } + } else { + return maybe_equality_comparable(0); + } + // NOLINTEND(modernize-use-transparent-functors) +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Provides the member constant `value` to true if a given type is + * equality comparable, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_equality_comparable: std::bool_constant()> {}; + +/*! @copydoc is_equality_comparable */ +template +struct is_equality_comparable: is_equality_comparable {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_equality_comparable_v = is_equality_comparable::value; + +/** + * @brief Transcribes the constness of a type to another type. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = std::remove_const_t; +}; + +/*! @copydoc constness_as */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = const To; +}; + +/** + * @brief Alias template to facilitate the transcription of the constness. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +using constness_as_t = typename constness_as::type; + +/** + * @brief Extracts the class of a non-static member object or function. + * @tparam Member A pointer to a non-static member object or function. + */ +template +class member_class { + static_assert(std::is_member_pointer_v, "Invalid pointer type to non-static member object or function"); + + template + static Class *clazz(Ret (Class::*)(Args...)); + + template + static Class *clazz(Ret (Class::*)(Args...) const); + + template + static Class *clazz(Type Class::*); + +public: + /*! @brief The class of the given non-static member object or function. */ + using type = std::remove_pointer_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Member A pointer to a non-static member object or function. + */ +template +using member_class_t = typename member_class::type; + +/** + * @brief Extracts the n-th argument of a _callable_ type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid _callable_ type. + */ +template +class nth_argument { + template + static constexpr type_list pick_up(Ret (*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...) const); + + template + static constexpr type_list pick_up(Type Class ::*); + + template + static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&); + +public: + /*! @brief N-th argument of the _callable_ type. */ + using type = type_list_element_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid function, member function or data member type. + */ +template +using nth_argument_t = typename nth_argument::type; + +} // namespace entt + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::type_list_element> {}; + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::value_list_element> {}; + +#endif + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct compressed_pair_element { + using reference = Type &; + using const_reference = const Type &; + + template>> + // NOLINTNEXTLINE(modernize-use-equals-default) + constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v) {} + + template>, compressed_pair_element>>> + constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v) + : value{std::forward(arg)} {} + + template + constexpr compressed_pair_element(std::tuple args, std::index_sequence) noexcept(std::is_nothrow_constructible_v) + : value{std::forward(std::get(args))...} {} + + [[nodiscard]] constexpr reference get() noexcept { + return value; + } + + [[nodiscard]] constexpr const_reference get() const noexcept { + return value; + } + +private: + Type value{}; +}; + +template +struct compressed_pair_element>>: Type { + using reference = Type &; + using const_reference = const Type &; + using base_type = Type; + + template>> + constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v) + : base_type{} {} + + template>, compressed_pair_element>>> + constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v) + : base_type{std::forward(arg)} {} + + template + constexpr compressed_pair_element(std::tuple args, std::index_sequence) noexcept(std::is_nothrow_constructible_v) + : base_type{std::forward(std::get(args))...} {} + + [[nodiscard]] constexpr reference get() noexcept { + return *this; + } + + [[nodiscard]] constexpr const_reference get() const noexcept { + return *this; + } +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief A compressed pair. + * + * A pair that exploits the _Empty Base Class Optimization_ (or _EBCO_) to + * reduce its final size to a minimum. + * + * @tparam First The type of the first element that the pair stores. + * @tparam Second The type of the second element that the pair stores. + */ +template +class compressed_pair final + : internal::compressed_pair_element, + internal::compressed_pair_element { + using first_base = internal::compressed_pair_element; + using second_base = internal::compressed_pair_element; + +public: + /*! @brief The type of the first element that the pair stores. */ + using first_type = First; + /*! @brief The type of the second element that the pair stores. */ + using second_type = Second; + + /** + * @brief Default constructor, conditionally enabled. + * + * This constructor is only available when the types that the pair stores + * are both at least default constructible. + * + * @tparam Dummy Dummy template parameter used for internal purposes. + */ + template && std::is_default_constructible_v>> + constexpr compressed_pair() noexcept(std::is_nothrow_default_constructible_v && std::is_nothrow_default_constructible_v) + : first_base{}, + second_base{} {} + + /** + * @brief Copy constructor. + * @param other The instance to copy from. + */ + constexpr compressed_pair(const compressed_pair &other) = default; + + /** + * @brief Move constructor. + * @param other The instance to move from. + */ + constexpr compressed_pair(compressed_pair &&other) noexcept = default; + + /** + * @brief Constructs a pair from its values. + * @tparam Arg Type of value to use to initialize the first element. + * @tparam Other Type of value to use to initialize the second element. + * @param arg Value to use to initialize the first element. + * @param other Value to use to initialize the second element. + */ + template + constexpr compressed_pair(Arg &&arg, Other &&other) noexcept(std::is_nothrow_constructible_v && std::is_nothrow_constructible_v) + : first_base{std::forward(arg)}, + second_base{std::forward(other)} {} + + /** + * @brief Constructs a pair by forwarding the arguments to its parts. + * @tparam Args Types of arguments to use to initialize the first element. + * @tparam Other Types of arguments to use to initialize the second element. + * @param args Arguments to use to initialize the first element. + * @param other Arguments to use to initialize the second element. + */ + template + constexpr compressed_pair(std::piecewise_construct_t, std::tuple args, std::tuple other) noexcept(std::is_nothrow_constructible_v && std::is_nothrow_constructible_v) + : first_base{std::move(args), std::index_sequence_for{}}, + second_base{std::move(other), std::index_sequence_for{}} {} + + /*! @brief Default destructor. */ + ~compressed_pair() = default; + + /** + * @brief Copy assignment operator. + * @param other The instance to copy from. + * @return This compressed pair object. + */ + constexpr compressed_pair &operator=(const compressed_pair &other) = default; + + /** + * @brief Move assignment operator. + * @param other The instance to move from. + * @return This compressed pair object. + */ + constexpr compressed_pair &operator=(compressed_pair &&other) noexcept = default; + + /** + * @brief Returns the first element that a pair stores. + * @return The first element that a pair stores. + */ + [[nodiscard]] constexpr first_type &first() noexcept { + return static_cast(*this).get(); + } + + /*! @copydoc first */ + [[nodiscard]] constexpr const first_type &first() const noexcept { + return static_cast(*this).get(); + } + + /** + * @brief Returns the second element that a pair stores. + * @return The second element that a pair stores. + */ + [[nodiscard]] constexpr second_type &second() noexcept { + return static_cast(*this).get(); + } + + /*! @copydoc second */ + [[nodiscard]] constexpr const second_type &second() const noexcept { + return static_cast(*this).get(); + } + + /** + * @brief Swaps two compressed pair objects. + * @param other The compressed pair to swap with. + */ + constexpr void swap(compressed_pair &other) noexcept { + using std::swap; + swap(first(), other.first()); + swap(second(), other.second()); + } + + /** + * @brief Extracts an element from the compressed pair. + * @tparam Index An integer value that is either 0 or 1. + * @return Returns a reference to the first element if `Index` is 0 and a + * reference to the second element if `Index` is 1. + */ + template + [[nodiscard]] constexpr decltype(auto) get() noexcept { + if constexpr(Index == 0u) { + return first(); + } else { + static_assert(Index == 1u, "Index out of bounds"); + return second(); + } + } + + /*! @copydoc get */ + template + [[nodiscard]] constexpr decltype(auto) get() const noexcept { + if constexpr(Index == 0u) { + return first(); + } else { + static_assert(Index == 1u, "Index out of bounds"); + return second(); + } + } +}; + +/** + * @brief Deduction guide. + * @tparam Type Type of value to use to initialize the first element. + * @tparam Other Type of value to use to initialize the second element. + */ +template +compressed_pair(Type &&, Other &&) -> compressed_pair, std::decay_t>; + +/** + * @brief Swaps two compressed pair objects. + * @tparam First The type of the first element that the pairs store. + * @tparam Second The type of the second element that the pairs store. + * @param lhs A valid compressed pair object. + * @param rhs A valid compressed pair object. + */ +template +constexpr void swap(compressed_pair &lhs, compressed_pair &rhs) noexcept { + lhs.swap(rhs); +} + +} // namespace entt + +namespace std { + +/** + * @brief `std::tuple_size` specialization for `compressed_pair`s. + * @tparam First The type of the first element that the pair stores. + * @tparam Second The type of the second element that the pair stores. + */ +template +struct tuple_size>: integral_constant {}; + +/** + * @brief `std::tuple_element` specialization for `compressed_pair`s. + * @tparam Index The index of the type to return. + * @tparam First The type of the first element that the pair stores. + * @tparam Second The type of the second element that the pair stores. + */ +template +struct tuple_element>: conditional { + static_assert(Index < 2u, "Index out of bounds"); +}; + +} // namespace std + +#endif + +// #include "../core/iterator.hpp" +#ifndef ENTT_CORE_ITERATOR_HPP +#define ENTT_CORE_ITERATOR_HPP + +#include +#include +#include +#include + +namespace entt { + +/** + * @brief Helper type to use as pointer with input iterators. + * @tparam Type of wrapped value. + */ +template +struct input_iterator_pointer final { + /*! @brief Value type. */ + using value_type = Type; + /*! @brief Pointer type. */ + using pointer = Type *; + /*! @brief Reference type. */ + using reference = Type &; + + /** + * @brief Constructs a proxy object by move. + * @param val Value to use to initialize the proxy object. + */ + constexpr input_iterator_pointer(value_type &&val) noexcept(std::is_nothrow_move_constructible_v) + : value{std::move(val)} {} + + /** + * @brief Access operator for accessing wrapped values. + * @return A pointer to the wrapped value. + */ + [[nodiscard]] constexpr pointer operator->() noexcept { + return std::addressof(value); + } + + /** + * @brief Dereference operator for accessing wrapped values. + * @return A reference to the wrapped value. + */ + [[nodiscard]] constexpr reference operator*() noexcept { + return value; + } + +private: + Type value; +}; + +/** + * @brief Plain iota iterator (waiting for C++20). + * @tparam Type Value type. + */ +template +class iota_iterator final { + static_assert(std::is_integral_v, "Not an integral type"); + +public: + /*! @brief Value type, likely an integral one. */ + using value_type = Type; + /*! @brief Invalid pointer type. */ + using pointer = void; + /*! @brief Non-reference type, same as value type. */ + using reference = value_type; + /*! @brief Difference type. */ + using difference_type = std::ptrdiff_t; + /*! @brief Iterator category. */ + using iterator_category = std::input_iterator_tag; + + /*! @brief Default constructor. */ + constexpr iota_iterator() noexcept + : current{} {} + + /** + * @brief Constructs an iota iterator from a given value. + * @param init The initial value assigned to the iota iterator. + */ + constexpr iota_iterator(const value_type init) noexcept + : current{init} {} + + /** + * @brief Pre-increment operator. + * @return This iota iterator. + */ + constexpr iota_iterator &operator++() noexcept { + return ++current, *this; + } + + /** + * @brief Post-increment operator. + * @return This iota iterator. + */ + constexpr iota_iterator operator++(int) noexcept { + const iota_iterator orig = *this; + return ++(*this), orig; + } + + /** + * @brief Dereference operator. + * @return The underlying value. + */ + [[nodiscard]] constexpr reference operator*() const noexcept { + return current; + } + +private: + value_type current; +}; + +/** + * @brief Comparison operator. + * @tparam Type Value type of the iota iterator. + * @param lhs A properly initialized iota iterator. + * @param rhs A properly initialized iota iterator. + * @return True if the two iterators are identical, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator==(const iota_iterator &lhs, const iota_iterator &rhs) noexcept { + return *lhs == *rhs; +} + +/** + * @brief Comparison operator. + * @tparam Type Value type of the iota iterator. + * @param lhs A properly initialized iota iterator. + * @param rhs A properly initialized iota iterator. + * @return True if the two iterators differ, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator!=(const iota_iterator &lhs, const iota_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +/** + * @brief Utility class to create an iterable object from a pair of iterators. + * @tparam It Type of iterator. + * @tparam Sentinel Type of sentinel. + */ +template +struct iterable_adaptor final { + /*! @brief Value type. */ + using value_type = typename std::iterator_traits::value_type; + /*! @brief Iterator type. */ + using iterator = It; + /*! @brief Sentinel type. */ + using sentinel = Sentinel; + + /*! @brief Default constructor. */ + constexpr iterable_adaptor() noexcept(std::is_nothrow_default_constructible_v && std::is_nothrow_default_constructible_v) + : first{}, + last{} {} + + /** + * @brief Creates an iterable object from a pair of iterators. + * @param from Begin iterator. + * @param to End iterator. + */ + constexpr iterable_adaptor(iterator from, sentinel to) noexcept(std::is_nothrow_move_constructible_v && std::is_nothrow_move_constructible_v) + : first{std::move(from)}, + last{std::move(to)} {} + + /** + * @brief Returns an iterator to the beginning. + * @return An iterator to the first element of the range. + */ + [[nodiscard]] constexpr iterator begin() const noexcept { + return first; + } + + /** + * @brief Returns an iterator to the end. + * @return An iterator to the element following the last element of the + * range. + */ + [[nodiscard]] constexpr sentinel end() const noexcept { + return last; + } + + /*! @copydoc begin */ + [[nodiscard]] constexpr iterator cbegin() const noexcept { + return begin(); + } + + /*! @copydoc end */ + [[nodiscard]] constexpr sentinel cend() const noexcept { + return end(); + } + +private: + It first; + Sentinel last; +}; + +} // namespace entt + +#endif + +// #include "../core/memory.hpp" +#ifndef ENTT_CORE_MEMORY_HPP +#define ENTT_CORE_MEMORY_HPP + +#include +#include +#include +#include +#include +// #include "../config/config.h" + + +namespace entt { + +/** + * @brief Unwraps fancy pointers, does nothing otherwise (waiting for C++20). + * @tparam Type Pointer type. + * @param ptr Fancy or raw pointer. + * @return A raw pointer that represents the address of the original pointer. + */ +template +[[nodiscard]] constexpr auto to_address(Type &&ptr) noexcept { + if constexpr(std::is_pointer_v>) { + return ptr; + } else { + return to_address(std::forward(ptr).operator->()); + } +} + +/** + * @brief Utility function to design allocation-aware containers. + * @tparam Allocator Type of allocator. + * @param lhs A valid allocator. + * @param rhs Another valid allocator. + */ +template +constexpr void propagate_on_container_copy_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept { + if constexpr(std::allocator_traits::propagate_on_container_copy_assignment::value) { + lhs = rhs; + } +} + +/** + * @brief Utility function to design allocation-aware containers. + * @tparam Allocator Type of allocator. + * @param lhs A valid allocator. + * @param rhs Another valid allocator. + */ +template +constexpr void propagate_on_container_move_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept { + if constexpr(std::allocator_traits::propagate_on_container_move_assignment::value) { + lhs = std::move(rhs); + } +} + +/** + * @brief Utility function to design allocation-aware containers. + * @tparam Allocator Type of allocator. + * @param lhs A valid allocator. + * @param rhs Another valid allocator. + */ +template +constexpr void propagate_on_container_swap([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept { + if constexpr(std::allocator_traits::propagate_on_container_swap::value) { + using std::swap; + swap(lhs, rhs); + } else { + ENTT_ASSERT_CONSTEXPR(lhs == rhs, "Cannot swap the containers"); + } +} + +/** + * @brief Deleter for allocator-aware unique pointers (waiting for C++20). + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +struct allocation_deleter: private Allocator { + /*! @brief Allocator type. */ + using allocator_type = Allocator; + /*! @brief Pointer type. */ + using pointer = typename std::allocator_traits::pointer; + + /** + * @brief Inherited constructors. + * @param alloc The allocator to use. + */ + constexpr allocation_deleter(const allocator_type &alloc) noexcept(std::is_nothrow_copy_constructible_v) + : Allocator{alloc} {} + + /** + * @brief Destroys the pointed object and deallocates its memory. + * @param ptr A valid pointer to an object of the given type. + */ + constexpr void operator()(pointer ptr) noexcept(std::is_nothrow_destructible_v) { + using alloc_traits = std::allocator_traits; + alloc_traits::destroy(*this, to_address(ptr)); + alloc_traits::deallocate(*this, ptr, 1u); + } +}; + +/** + * @brief Allows `std::unique_ptr` to use allocators (waiting for C++20). + * @tparam Type Type of object to allocate for and to construct. + * @tparam Allocator Type of allocator used to manage memory and elements. + * @tparam Args Types of arguments to use to construct the object. + * @param allocator The allocator to use. + * @param args Parameters to use to construct the object. + * @return A properly initialized unique pointer with a custom deleter. + */ +template +ENTT_CONSTEXPR auto allocate_unique(Allocator &allocator, Args &&...args) { + static_assert(!std::is_array_v, "Array types are not supported"); + + using alloc_traits = typename std::allocator_traits::template rebind_traits; + using allocator_type = typename alloc_traits::allocator_type; + + allocator_type alloc{allocator}; + auto ptr = alloc_traits::allocate(alloc, 1u); + + ENTT_TRY { + alloc_traits::construct(alloc, to_address(ptr), std::forward(args)...); + } + ENTT_CATCH { + alloc_traits::deallocate(alloc, ptr, 1u); + ENTT_THROW; + } + + return std::unique_ptr>{ptr, alloc}; +} + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct uses_allocator_construction { + template + static constexpr auto args([[maybe_unused]] const Allocator &allocator, Params &&...params) noexcept { + if constexpr(!std::uses_allocator_v && std::is_constructible_v) { + return std::forward_as_tuple(std::forward(params)...); + } else { + static_assert(std::uses_allocator_v, "Ill-formed request"); + + if constexpr(std::is_constructible_v) { + return std::tuple{std::allocator_arg, allocator, std::forward(params)...}; + } else { + static_assert(std::is_constructible_v, "Ill-formed request"); + return std::forward_as_tuple(std::forward(params)..., allocator); + } + } + } +}; + +template +struct uses_allocator_construction> { + using type = std::pair; + + template + static constexpr auto args(const Allocator &allocator, std::piecewise_construct_t, First &&first, Second &&second) noexcept { + return std::make_tuple( + std::piecewise_construct, + std::apply([&allocator](auto &&...curr) { return uses_allocator_construction::args(allocator, std::forward(curr)...); }, std::forward(first)), + std::apply([&allocator](auto &&...curr) { return uses_allocator_construction::args(allocator, std::forward(curr)...); }, std::forward(second))); + } + + template + static constexpr auto args(const Allocator &allocator) noexcept { + return uses_allocator_construction::args(allocator, std::piecewise_construct, std::tuple<>{}, std::tuple<>{}); + } + + template + static constexpr auto args(const Allocator &allocator, First &&first, Second &&second) noexcept { + return uses_allocator_construction::args(allocator, std::piecewise_construct, std::forward_as_tuple(std::forward(first)), std::forward_as_tuple(std::forward(second))); + } + + template + static constexpr auto args(const Allocator &allocator, const std::pair &value) noexcept { + return uses_allocator_construction::args(allocator, std::piecewise_construct, std::forward_as_tuple(value.first), std::forward_as_tuple(value.second)); + } + + template + static constexpr auto args(const Allocator &allocator, std::pair &&value) noexcept { + return uses_allocator_construction::args(allocator, std::piecewise_construct, std::forward_as_tuple(std::move(value.first)), std::forward_as_tuple(std::move(value.second))); + } +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Uses-allocator construction utility (waiting for C++20). + * + * Primarily intended for internal use. Prepares the argument list needed to + * create an object of a given type by means of uses-allocator construction. + * + * @tparam Type Type to return arguments for. + * @tparam Allocator Type of allocator used to manage memory and elements. + * @tparam Args Types of arguments to use to construct the object. + * @param allocator The allocator to use. + * @param args Parameters to use to construct the object. + * @return The arguments needed to create an object of the given type. + */ +template +constexpr auto uses_allocator_construction_args(const Allocator &allocator, Args &&...args) noexcept { + return internal::uses_allocator_construction::args(allocator, std::forward(args)...); +} + +/** + * @brief Uses-allocator construction utility (waiting for C++20). + * + * Primarily intended for internal use. Creates an object of a given type by + * means of uses-allocator construction. + * + * @tparam Type Type of object to create. + * @tparam Allocator Type of allocator used to manage memory and elements. + * @tparam Args Types of arguments to use to construct the object. + * @param allocator The allocator to use. + * @param args Parameters to use to construct the object. + * @return A newly created object of the given type. + */ +template +constexpr Type make_obj_using_allocator(const Allocator &allocator, Args &&...args) { + return std::make_from_tuple(internal::uses_allocator_construction::args(allocator, std::forward(args)...)); +} + +/** + * @brief Uses-allocator construction utility (waiting for C++20). + * + * Primarily intended for internal use. Creates an object of a given type by + * means of uses-allocator construction at an uninitialized memory location. + * + * @tparam Type Type of object to create. + * @tparam Allocator Type of allocator used to manage memory and elements. + * @tparam Args Types of arguments to use to construct the object. + * @param value Memory location in which to place the object. + * @param allocator The allocator to use. + * @param args Parameters to use to construct the object. + * @return A pointer to the newly created object of the given type. + */ +template +constexpr Type *uninitialized_construct_using_allocator(Type *value, const Allocator &allocator, Args &&...args) { + return std::apply([value](auto &&...curr) { return ::new(value) Type(std::forward(curr)...); }, internal::uses_allocator_construction::args(allocator, std::forward(args)...)); +} + +} // namespace entt + +#endif + +// #include "../core/type_traits.hpp" +#ifndef ENTT_CORE_TYPE_TRAITS_HPP +#define ENTT_CORE_TYPE_TRAITS_HPP + +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "fwd.hpp" + + +namespace entt { + +/** + * @brief Utility class to disambiguate overloaded functions. + * @tparam N Number of choices available. + */ +template +struct choice_t + // unfortunately, doxygen cannot parse such a construct + : /*! @cond TURN_OFF_DOXYGEN */ choice_t /*! @endcond */ +{}; + +/*! @copybrief choice_t */ +template<> +struct choice_t<0> {}; + +/** + * @brief Variable template for the choice trick. + * @tparam N Number of choices available. + */ +template +inline constexpr choice_t choice{}; + +/** + * @brief Identity type trait. + * + * Useful to establish non-deduced contexts in template argument deduction + * (waiting for C++20) or to provide types through function arguments. + * + * @tparam Type A type. + */ +template +struct type_identity { + /*! @brief Identity type. */ + using type = Type; +}; + +/** + * @brief Helper type. + * @tparam Type A type. + */ +template +using type_identity_t = typename type_identity::type; + +/** + * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains. + * @tparam Type The type of which to return the size. + */ +template +struct size_of: std::integral_constant {}; + +/*! @copydoc size_of */ +template +struct size_of> + // NOLINTNEXTLINE(bugprone-sizeof-expression) + : std::integral_constant {}; + +/** + * @brief Helper variable template. + * @tparam Type The type of which to return the size. + */ +template +inline constexpr std::size_t size_of_v = size_of::value; + +/** + * @brief Using declaration to be used to _repeat_ the same type a number of + * times equal to the size of a given parameter pack. + * @tparam Type A type to repeat. + */ +template +using unpack_as_type = Type; + +/** + * @brief Helper variable template to be used to _repeat_ the same value a + * number of times equal to the size of a given parameter pack. + * @tparam Value A value to repeat. + */ +template +inline constexpr auto unpack_as_value = Value; + +/** + * @brief Wraps a static constant. + * @tparam Value A static constant. + */ +template +using integral_constant = std::integral_constant; + +/** + * @brief Alias template to facilitate the creation of named values. + * @tparam Value A constant value at least convertible to `id_type`. + */ +template +using tag = integral_constant; + +/** + * @brief A class to use to push around lists of types, nothing more. + * @tparam Type Types provided by the type list. + */ +template +struct type_list { + /*! @brief Type list type. */ + using type = type_list; + /*! @brief Compile-time number of elements in the type list. */ + static constexpr auto size = sizeof...(Type); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_element; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Index Index of the type to return. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element> + : type_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element<0u, type_list> { + /*! @brief Searched type. */ + using type = First; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Type list to search into. + */ +template +using type_list_element_t = typename type_list_element::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_index; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 1u + type_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + static_assert(type_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +inline constexpr std::size_t type_list_index_v = type_list_index::value; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @return A type list composed by the types of both the type lists. + */ +template +constexpr type_list operator+(type_list, type_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_cat; + +/*! @brief Concatenates multiple type lists. */ +template<> +struct type_list_cat<> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list<>; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @tparam List Other type lists, if any. + */ +template +struct type_list_cat, type_list, List...> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = typename type_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the type list. + */ +template +struct type_list_cat> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list; +}; + +/** + * @brief Helper type. + * @tparam List Type lists to concatenate. + */ +template +using type_list_cat_t = typename type_list_cat::type; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct type_list_unique; + +template +struct type_list_unique, Type...> + : std::conditional_t<(std::is_same_v || ...), type_list_unique, Type...>, type_list_unique, Type..., First>> {}; + +template +struct type_list_unique, Type...> { + using type = type_list; +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Removes duplicates types from a type list. + * @tparam List Type list. + */ +template +struct type_list_unique { + /*! @brief A type list without duplicate types. */ + using type = typename internal::type_list_unique::type; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + */ +template +using type_list_unique_t = typename type_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a type list contains a + * given type, false otherwise. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +struct type_list_contains; + +/** + * @copybrief type_list_contains + * @tparam Type Types provided by the type list. + * @tparam Other Type to look for. + */ +template +struct type_list_contains, Other> + : std::bool_constant<(std::is_same_v || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +inline constexpr bool type_list_contains_v = type_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_diff; + +/** + * @brief Computes the difference between two type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + */ +template +struct type_list_diff, type_list> { + /*! @brief A type list that is the difference between the two type lists. */ + using type = type_list_cat_t, Type>, type_list<>, type_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Type lists between which to compute the difference. + */ +template +using type_list_diff_t = typename type_list_diff::type; + +/*! @brief Primary template isn't defined on purpose. */ +template class> +struct type_list_transform; + +/** + * @brief Applies a given _function_ to a type list and generate a new list. + * @tparam Type Types provided by the type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +struct type_list_transform, Op> { + /*! @brief Resulting type list after applying the transform function. */ + // NOLINTNEXTLINE(modernize-type-traits) + using type = type_list::type...>; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +using type_list_transform_t = typename type_list_transform::type; + +/** + * @brief A class to use to push around lists of constant values, nothing more. + * @tparam Value Values provided by the value list. + */ +template +struct value_list { + /*! @brief Value list type. */ + using type = value_list; + /*! @brief Compile-time number of elements in the value list. */ + static constexpr auto size = sizeof...(Value); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_element; + +/** + * @brief Provides compile-time indexed access to the values of a value list. + * @tparam Index Index of the value to return. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element> + : value_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element<0u, value_list> { + /*! @brief Searched type. */ + using type = decltype(Value); + /*! @brief Searched value. */ + static constexpr auto value = Value; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Value list to search into. + */ +template +using value_list_element_t = typename value_list_element::type; + +/** + * @brief Helper type. + * @tparam Index Index of the value to return. + * @tparam List Value list to search into. + */ +template +inline constexpr auto value_list_element_v = value_list_element::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_index; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam First First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 1u + value_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + static_assert(value_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +inline constexpr std::size_t value_list_index_v = value_list_index::value; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @return A value list composed by the values of both the value lists. + */ +template +constexpr value_list operator+(value_list, value_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_cat; + +/*! @brief Concatenates multiple value lists. */ +template<> +struct value_list_cat<> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list<>; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @tparam List Other value lists, if any. + */ +template +struct value_list_cat, value_list, List...> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = typename value_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the value list. + */ +template +struct value_list_cat> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list; +}; + +/** + * @brief Helper type. + * @tparam List Value lists to concatenate. + */ +template +using value_list_cat_t = typename value_list_cat::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_unique; + +/** + * @brief Removes duplicates values from a value list. + * @tparam Value One of the values provided by the given value list. + * @tparam Other The other values provided by the given value list. + */ +template +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = std::conditional_t< + ((Value == Other) || ...), + typename value_list_unique>::type, + value_list_cat_t, typename value_list_unique>::type>>; +}; + +/*! @brief Removes duplicates values from a value list. */ +template<> +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = value_list<>; +}; + +/** + * @brief Helper type. + * @tparam Type A value list. + */ +template +using value_list_unique_t = typename value_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a value list contains + * a given value, false otherwise. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +struct value_list_contains; + +/** + * @copybrief value_list_contains + * @tparam Value Values provided by the value list. + * @tparam Other Value to look for. + */ +template +struct value_list_contains, Other> + : std::bool_constant<((Value == Other) || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +inline constexpr bool value_list_contains_v = value_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_diff; + +/** + * @brief Computes the difference between two value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + */ +template +struct value_list_diff, value_list> { + /*! @brief A value list that is the difference between the two value lists. */ + using type = value_list_cat_t, Value>, value_list<>, value_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Value lists between which to compute the difference. + */ +template +using value_list_diff_t = typename value_list_diff::type; + +/*! @brief Same as std::is_invocable, but with tuples. */ +template +struct is_applicable: std::false_type {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @brief Helper variable template. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_v = is_applicable::value; + +/*! @brief Same as std::is_invocable_r, but with tuples for arguments. */ +template +struct is_applicable_r: std::false_type {}; + +/** + * @copybrief is_applicable_r + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +struct is_applicable_r>: std::is_invocable_r {}; + +/** + * @brief Helper variable template. + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_r_v = is_applicable_r::value; + +/** + * @brief Provides the member constant `value` to true if a given type is + * complete, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_complete: std::false_type {}; + +/*! @copydoc is_complete */ +template +struct is_complete>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_complete_v = is_complete::value; + +/** + * @brief Provides the member constant `value` to true if a given type is an + * iterator, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_iterator: std::false_type {}; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_iterator_category: std::false_type {}; + +template +struct has_iterator_category::iterator_category>>: std::true_type {}; + +} // namespace internal +/*! @endcond */ + +/*! @copydoc is_iterator */ +template +struct is_iterator>>>> + : internal::has_iterator_category {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_iterator_v = is_iterator::value; + +/** + * @brief Provides the member constant `value` to true if a given type is both + * an empty and non-final class, false otherwise. + * @tparam Type The type to test + */ +template +struct is_ebco_eligible + : std::bool_constant && !std::is_final_v> {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_ebco_eligible_v = is_ebco_eligible::value; + +/** + * @brief Provides the member constant `value` to true if `Type::is_transparent` + * is valid and denotes a type, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_transparent: std::false_type {}; + +/*! @copydoc is_transparent */ +template +struct is_transparent>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_transparent_v = is_transparent::value; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_tuple_size_value: std::false_type {}; + +template +struct has_tuple_size_value::value)>>: std::true_type {}; + +template +struct has_value_type: std::false_type {}; + +template +struct has_value_type>: std::true_type {}; + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable(); + +template +[[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence) { + return (dispatch_is_equality_comparable>() && ...); +} + +template +[[nodiscard]] constexpr bool maybe_equality_comparable(char) { + return false; +} + +template +[[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval() == std::declval()) { + return true; +} + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable() { + // NOLINTBEGIN(modernize-use-transparent-functors) + if constexpr(std::is_array_v) { + return false; + } else if constexpr(is_complete_v>>) { + if constexpr(has_tuple_size_value::value) { + return maybe_equality_comparable(0) && unpack_maybe_equality_comparable(std::make_index_sequence::value>{}); + } else { + return maybe_equality_comparable(0); + } + } else if constexpr(has_value_type::value) { + if constexpr(is_iterator_v || std::is_same_v || dispatch_is_equality_comparable()) { + return maybe_equality_comparable(0); + } else { + return false; + } + } else { + return maybe_equality_comparable(0); + } + // NOLINTEND(modernize-use-transparent-functors) +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Provides the member constant `value` to true if a given type is + * equality comparable, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_equality_comparable: std::bool_constant()> {}; + +/*! @copydoc is_equality_comparable */ +template +struct is_equality_comparable: is_equality_comparable {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_equality_comparable_v = is_equality_comparable::value; + +/** + * @brief Transcribes the constness of a type to another type. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = std::remove_const_t; +}; + +/*! @copydoc constness_as */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = const To; +}; + +/** + * @brief Alias template to facilitate the transcription of the constness. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +using constness_as_t = typename constness_as::type; + +/** + * @brief Extracts the class of a non-static member object or function. + * @tparam Member A pointer to a non-static member object or function. + */ +template +class member_class { + static_assert(std::is_member_pointer_v, "Invalid pointer type to non-static member object or function"); + + template + static Class *clazz(Ret (Class::*)(Args...)); + + template + static Class *clazz(Ret (Class::*)(Args...) const); + + template + static Class *clazz(Type Class::*); + +public: + /*! @brief The class of the given non-static member object or function. */ + using type = std::remove_pointer_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Member A pointer to a non-static member object or function. + */ +template +using member_class_t = typename member_class::type; + +/** + * @brief Extracts the n-th argument of a _callable_ type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid _callable_ type. + */ +template +class nth_argument { + template + static constexpr type_list pick_up(Ret (*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...) const); + + template + static constexpr type_list pick_up(Type Class ::*); + + template + static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&); + +public: + /*! @brief N-th argument of the _callable_ type. */ + using type = type_list_element_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid function, member function or data member type. + */ +template +using nth_argument_t = typename nth_argument::type; + +} // namespace entt + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::type_list_element> {}; + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::value_list_element> {}; + +#endif + +// #include "fwd.hpp" +#ifndef ENTT_CONTAINER_FWD_HPP +#define ENTT_CONTAINER_FWD_HPP + +#include +#include +#include +#include + +namespace entt { + +template< + typename Key, + typename Type, + typename = std::hash, + typename = std::equal_to<>, + typename = std::allocator>> +class dense_map; + +template< + typename Type, + typename = std::hash, + typename = std::equal_to<>, + typename = std::allocator> +class dense_set; + +template +class basic_table; + +/** + * @brief Alias declaration for the most common use case. + * @tparam Type Element types. + */ +template +using table = basic_table...>; + +} // namespace entt + +#endif + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +static constexpr std::size_t dense_map_placeholder_position = (std::numeric_limits::max)(); + +template +struct dense_map_node final { + using value_type = std::pair; + + template + dense_map_node(const std::size_t pos, Args &&...args) + : next{pos}, + element{std::forward(args)...} {} + + template + dense_map_node(std::allocator_arg_t, const Allocator &allocator, const std::size_t pos, Args &&...args) + : next{pos}, + element{entt::make_obj_using_allocator(allocator, std::forward(args)...)} {} + + template + dense_map_node(std::allocator_arg_t, const Allocator &allocator, const dense_map_node &other) + : next{other.next}, + element{entt::make_obj_using_allocator(allocator, other.element)} {} + + template + dense_map_node(std::allocator_arg_t, const Allocator &allocator, dense_map_node &&other) + : next{other.next}, + element{entt::make_obj_using_allocator(allocator, std::move(other.element))} {} + + std::size_t next; + value_type element; +}; + +template +class dense_map_iterator final { + template + friend class dense_map_iterator; + + using first_type = decltype(std::as_const(std::declval()->element.first)); + using second_type = decltype((std::declval()->element.second)); + +public: + using value_type = std::pair; + using pointer = input_iterator_pointer; + using reference = value_type; + using difference_type = std::ptrdiff_t; + using iterator_category = std::input_iterator_tag; + using iterator_concept = std::random_access_iterator_tag; + + constexpr dense_map_iterator() noexcept + : it{} {} + + constexpr dense_map_iterator(const It iter) noexcept + : it{iter} {} + + template && std::is_constructible_v>> + constexpr dense_map_iterator(const dense_map_iterator &other) noexcept + : it{other.it} {} + + constexpr dense_map_iterator &operator++() noexcept { + return ++it, *this; + } + + constexpr dense_map_iterator operator++(int) noexcept { + const dense_map_iterator orig = *this; + return ++(*this), orig; + } + + constexpr dense_map_iterator &operator--() noexcept { + return --it, *this; + } + + constexpr dense_map_iterator operator--(int) noexcept { + const dense_map_iterator orig = *this; + return operator--(), orig; + } + + constexpr dense_map_iterator &operator+=(const difference_type value) noexcept { + it += value; + return *this; + } + + constexpr dense_map_iterator operator+(const difference_type value) const noexcept { + dense_map_iterator copy = *this; + return (copy += value); + } + + constexpr dense_map_iterator &operator-=(const difference_type value) noexcept { + return (*this += -value); + } + + constexpr dense_map_iterator operator-(const difference_type value) const noexcept { + return (*this + -value); + } + + [[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept { + return {it[value].element.first, it[value].element.second}; + } + + [[nodiscard]] constexpr pointer operator->() const noexcept { + return operator*(); + } + + [[nodiscard]] constexpr reference operator*() const noexcept { + return operator[](0); + } + + template + friend constexpr std::ptrdiff_t operator-(const dense_map_iterator &, const dense_map_iterator &) noexcept; + + template + friend constexpr bool operator==(const dense_map_iterator &, const dense_map_iterator &) noexcept; + + template + friend constexpr bool operator<(const dense_map_iterator &, const dense_map_iterator &) noexcept; + +private: + It it; +}; + +template +[[nodiscard]] constexpr std::ptrdiff_t operator-(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return lhs.it - rhs.it; +} + +template +[[nodiscard]] constexpr bool operator==(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return lhs.it == rhs.it; +} + +template +[[nodiscard]] constexpr bool operator!=(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +template +[[nodiscard]] constexpr bool operator<(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return lhs.it < rhs.it; +} + +template +[[nodiscard]] constexpr bool operator>(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return rhs < lhs; +} + +template +[[nodiscard]] constexpr bool operator<=(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return !(lhs > rhs); +} + +template +[[nodiscard]] constexpr bool operator>=(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return !(lhs < rhs); +} + +template +class dense_map_local_iterator final { + template + friend class dense_map_local_iterator; + + using first_type = decltype(std::as_const(std::declval()->element.first)); + using second_type = decltype((std::declval()->element.second)); + +public: + using value_type = std::pair; + using pointer = input_iterator_pointer; + using reference = value_type; + using difference_type = std::ptrdiff_t; + using iterator_category = std::input_iterator_tag; + using iterator_concept = std::forward_iterator_tag; + + constexpr dense_map_local_iterator() noexcept = default; + + constexpr dense_map_local_iterator(It iter, const std::size_t pos) noexcept + : it{iter}, + offset{pos} {} + + template && std::is_constructible_v>> + constexpr dense_map_local_iterator(const dense_map_local_iterator &other) noexcept + : it{other.it}, + offset{other.offset} {} + + constexpr dense_map_local_iterator &operator++() noexcept { + return (offset = it[static_cast(offset)].next), *this; + } + + constexpr dense_map_local_iterator operator++(int) noexcept { + const dense_map_local_iterator orig = *this; + return ++(*this), orig; + } + + [[nodiscard]] constexpr pointer operator->() const noexcept { + return operator*(); + } + + [[nodiscard]] constexpr reference operator*() const noexcept { + const auto idx = static_cast(offset); + return {it[idx].element.first, it[idx].element.second}; + } + + [[nodiscard]] constexpr std::size_t index() const noexcept { + return offset; + } + +private: + It it{}; + std::size_t offset{dense_map_placeholder_position}; +}; + +template +[[nodiscard]] constexpr bool operator==(const dense_map_local_iterator &lhs, const dense_map_local_iterator &rhs) noexcept { + return lhs.index() == rhs.index(); +} + +template +[[nodiscard]] constexpr bool operator!=(const dense_map_local_iterator &lhs, const dense_map_local_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Associative container for key-value pairs with unique keys. + * + * Internally, elements are organized into buckets. Which bucket an element is + * placed into depends entirely on the hash of its key. Keys with the same hash + * code appear in the same bucket. + * + * @tparam Key Key type of the associative container. + * @tparam Type Mapped type of the associative container. + * @tparam Hash Type of function to use to hash the keys. + * @tparam KeyEqual Type of function to use to compare the keys for equality. + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +class dense_map { + static constexpr float default_threshold = 0.875f; + static constexpr std::size_t minimum_capacity = 8u; + static constexpr std::size_t placeholder_position = internal::dense_map_placeholder_position; + + using node_type = internal::dense_map_node; + using alloc_traits = std::allocator_traits; + static_assert(std::is_same_v>, "Invalid value type"); + using sparse_container_type = std::vector>; + using packed_container_type = std::vector>; + + template + [[nodiscard]] std::size_t key_to_bucket(const Other &key) const noexcept { + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay) + return fast_mod(static_cast(sparse.second()(key)), bucket_count()); + } + + template + [[nodiscard]] auto constrained_find(const Other &key, const std::size_t bucket) { + for(auto offset = sparse.first()[bucket]; offset != placeholder_position; offset = packed.first()[offset].next) { + if(packed.second()(packed.first()[offset].element.first, key)) { + return begin() + static_cast(offset); + } + } + + return end(); + } + + template + [[nodiscard]] auto constrained_find(const Other &key, const std::size_t bucket) const { + for(auto offset = sparse.first()[bucket]; offset != placeholder_position; offset = packed.first()[offset].next) { + if(packed.second()(packed.first()[offset].element.first, key)) { + return cbegin() + static_cast(offset); + } + } + + return cend(); + } + + template + [[nodiscard]] auto insert_or_do_nothing(Other &&key, Args &&...args) { + const auto index = key_to_bucket(key); + + if(auto it = constrained_find(key, index); it != end()) { + return std::make_pair(it, false); + } + + packed.first().emplace_back(sparse.first()[index], std::piecewise_construct, std::forward_as_tuple(std::forward(key)), std::forward_as_tuple(std::forward(args)...)); + sparse.first()[index] = packed.first().size() - 1u; + rehash_if_required(); + + return std::make_pair(--end(), true); + } + + template + [[nodiscard]] auto insert_or_overwrite(Other &&key, Arg &&value) { + const auto index = key_to_bucket(key); + + if(auto it = constrained_find(key, index); it != end()) { + it->second = std::forward(value); + return std::make_pair(it, false); + } + + packed.first().emplace_back(sparse.first()[index], std::forward(key), std::forward(value)); + sparse.first()[index] = packed.first().size() - 1u; + rehash_if_required(); + + return std::make_pair(--end(), true); + } + + void move_and_pop(const std::size_t pos) { + if(const auto last = size() - 1u; pos != last) { + size_type *curr = &sparse.first()[key_to_bucket(packed.first().back().element.first)]; + packed.first()[pos] = std::move(packed.first().back()); + for(; *curr != last; curr = &packed.first()[*curr].next) {} + *curr = pos; + } + + packed.first().pop_back(); + } + + void rehash_if_required() { + if(const auto bc = bucket_count(); size() > static_cast(static_cast(bc) * max_load_factor())) { + rehash(bc * 2u); + } + } + +public: + /*! @brief Allocator type. */ + using allocator_type = Allocator; + /*! @brief Key type of the container. */ + using key_type = Key; + /*! @brief Mapped type of the container. */ + using mapped_type = Type; + /*! @brief Key-value type of the container. */ + using value_type = std::pair; + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + /*! @brief Signed integer type. */ + using difference_type = std::ptrdiff_t; + /*! @brief Type of function to use to hash the keys. */ + using hasher = Hash; + /*! @brief Type of function to use to compare the keys for equality. */ + using key_equal = KeyEqual; + /*! @brief Input iterator type. */ + using iterator = internal::dense_map_iterator; + /*! @brief Constant input iterator type. */ + using const_iterator = internal::dense_map_iterator; + /*! @brief Input iterator type. */ + using local_iterator = internal::dense_map_local_iterator; + /*! @brief Constant input iterator type. */ + using const_local_iterator = internal::dense_map_local_iterator; + + /*! @brief Default constructor. */ + dense_map() + : dense_map{minimum_capacity} {} + + /** + * @brief Constructs an empty container with a given allocator. + * @param allocator The allocator to use. + */ + explicit dense_map(const allocator_type &allocator) + : dense_map{minimum_capacity, hasher{}, key_equal{}, allocator} {} + + /** + * @brief Constructs an empty container with a given allocator and user + * supplied minimal number of buckets. + * @param cnt Minimal number of buckets. + * @param allocator The allocator to use. + */ + dense_map(const size_type cnt, const allocator_type &allocator) + : dense_map{cnt, hasher{}, key_equal{}, allocator} {} + + /** + * @brief Constructs an empty container with a given allocator, hash + * function and user supplied minimal number of buckets. + * @param cnt Minimal number of buckets. + * @param hash Hash function to use. + * @param allocator The allocator to use. + */ + dense_map(const size_type cnt, const hasher &hash, const allocator_type &allocator) + : dense_map{cnt, hash, key_equal{}, allocator} {} + + /** + * @brief Constructs an empty container with a given allocator, hash + * function, compare function and user supplied minimal number of buckets. + * @param cnt Minimal number of buckets. + * @param hash Hash function to use. + * @param equal Compare function to use. + * @param allocator The allocator to use. + */ + explicit dense_map(const size_type cnt, const hasher &hash = hasher{}, const key_equal &equal = key_equal{}, const allocator_type &allocator = allocator_type{}) + : sparse{allocator, hash}, + packed{allocator, equal} { + rehash(cnt); + } + + /*! @brief Default copy constructor. */ + dense_map(const dense_map &) = default; + + /** + * @brief Allocator-extended copy constructor. + * @param other The instance to copy from. + * @param allocator The allocator to use. + */ + dense_map(const dense_map &other, const allocator_type &allocator) + : sparse{std::piecewise_construct, std::forward_as_tuple(other.sparse.first(), allocator), std::forward_as_tuple(other.sparse.second())}, + packed{std::piecewise_construct, std::forward_as_tuple(other.packed.first(), allocator), std::forward_as_tuple(other.packed.second())}, + threshold{other.threshold} {} + + /*! @brief Default move constructor. */ + dense_map(dense_map &&) noexcept = default; + + /** + * @brief Allocator-extended move constructor. + * @param other The instance to move from. + * @param allocator The allocator to use. + */ + dense_map(dense_map &&other, const allocator_type &allocator) + : sparse{std::piecewise_construct, std::forward_as_tuple(std::move(other.sparse.first()), allocator), std::forward_as_tuple(std::move(other.sparse.second()))}, + packed{std::piecewise_construct, std::forward_as_tuple(std::move(other.packed.first()), allocator), std::forward_as_tuple(std::move(other.packed.second()))}, + threshold{other.threshold} {} + + /*! @brief Default destructor. */ + ~dense_map() = default; + + /** + * @brief Default copy assignment operator. + * @return This container. + */ + dense_map &operator=(const dense_map &) = default; + + /** + * @brief Default move assignment operator. + * @return This container. + */ + dense_map &operator=(dense_map &&) noexcept = default; + + /** + * @brief Exchanges the contents with those of a given container. + * @param other Container to exchange the content with. + */ + void swap(dense_map &other) noexcept { + using std::swap; + swap(sparse, other.sparse); + swap(packed, other.packed); + swap(threshold, other.threshold); + } + + /** + * @brief Returns the associated allocator. + * @return The associated allocator. + */ + [[nodiscard]] constexpr allocator_type get_allocator() const noexcept { + return sparse.first().get_allocator(); + } + + /** + * @brief Returns an iterator to the beginning. + * + * If the array is empty, the returned iterator will be equal to `end()`. + * + * @return An iterator to the first instance of the internal array. + */ + [[nodiscard]] const_iterator cbegin() const noexcept { + return packed.first().begin(); + } + + /*! @copydoc cbegin */ + [[nodiscard]] const_iterator begin() const noexcept { + return cbegin(); + } + + /*! @copydoc begin */ + [[nodiscard]] iterator begin() noexcept { + return packed.first().begin(); + } + + /** + * @brief Returns an iterator to the end. + * @return An iterator to the element following the last instance of the + * internal array. + */ + [[nodiscard]] const_iterator cend() const noexcept { + return packed.first().end(); + } + + /*! @copydoc cend */ + [[nodiscard]] const_iterator end() const noexcept { + return cend(); + } + + /*! @copydoc end */ + [[nodiscard]] iterator end() noexcept { + return packed.first().end(); + } + + /** + * @brief Checks whether a container is empty. + * @return True if the container is empty, false otherwise. + */ + [[nodiscard]] bool empty() const noexcept { + return packed.first().empty(); + } + + /** + * @brief Returns the number of elements in a container. + * @return Number of elements in a container. + */ + [[nodiscard]] size_type size() const noexcept { + return packed.first().size(); + } + + /** + * @brief Returns the maximum possible number of elements. + * @return Maximum possible number of elements. + */ + [[nodiscard]] size_type max_size() const noexcept { + return packed.first().max_size(); + } + + /*! @brief Clears the container. */ + void clear() noexcept { + sparse.first().clear(); + packed.first().clear(); + rehash(0u); + } + + /** + * @brief Inserts an element into the container, if the key does not exist. + * @param value A key-value pair eventually convertible to the value type. + * @return A pair consisting of an iterator to the inserted element (or to + * the element that prevented the insertion) and a bool denoting whether the + * insertion took place. + */ + std::pair insert(const value_type &value) { + return insert_or_do_nothing(value.first, value.second); + } + + /*! @copydoc insert */ + std::pair insert(value_type &&value) { + return insert_or_do_nothing(std::move(value.first), std::move(value.second)); + } + + /** + * @copydoc insert + * @tparam Arg Type of the key-value pair to insert into the container. + */ + template + std::enable_if_t, std::pair> + insert(Arg &&value) { + return insert_or_do_nothing(std::forward(value).first, std::forward(value).second); + } + + /** + * @brief Inserts elements into the container, if their keys do not exist. + * @tparam It Type of input iterator. + * @param first An iterator to the first element of the range of elements. + * @param last An iterator past the last element of the range of elements. + */ + template + void insert(It first, It last) { + for(; first != last; ++first) { + insert(*first); + } + } + + /** + * @brief Inserts an element into the container or assigns to the current + * element if the key already exists. + * @tparam Arg Type of the value to insert or assign. + * @param key A key used both to look up and to insert if not found. + * @param value A value to insert or assign. + * @return A pair consisting of an iterator to the element and a bool + * denoting whether the insertion took place. + */ + template + std::pair insert_or_assign(const key_type &key, Arg &&value) { + return insert_or_overwrite(key, std::forward(value)); + } + + /*! @copydoc insert_or_assign */ + template + std::pair insert_or_assign(key_type &&key, Arg &&value) { + return insert_or_overwrite(std::move(key), std::forward(value)); + } + + /** + * @brief Constructs an element in-place, if the key does not exist. + * + * The element is also constructed when the container already has the key, + * in which case the newly constructed object is destroyed immediately. + * + * @tparam Args Types of arguments to forward to the constructor of the + * element. + * @param args Arguments to forward to the constructor of the element. + * @return A pair consisting of an iterator to the inserted element (or to + * the element that prevented the insertion) and a bool denoting whether the + * insertion took place. + */ + template + std::pair emplace([[maybe_unused]] Args &&...args) { + if constexpr(sizeof...(Args) == 0u) { + return insert_or_do_nothing(key_type{}); + } else if constexpr(sizeof...(Args) == 1u) { + return insert_or_do_nothing(std::forward(args).first..., std::forward(args).second...); + } else if constexpr(sizeof...(Args) == 2u) { + return insert_or_do_nothing(std::forward(args)...); + } else { + auto &node = packed.first().emplace_back(packed.first().size(), std::forward(args)...); + const auto index = key_to_bucket(node.element.first); + + if(auto it = constrained_find(node.element.first, index); it != end()) { + packed.first().pop_back(); + return std::make_pair(it, false); + } + + std::swap(node.next, sparse.first()[index]); + rehash_if_required(); + + return std::make_pair(--end(), true); + } + } + + /** + * @brief Inserts in-place if the key does not exist, does nothing if the + * key exists. + * @tparam Args Types of arguments to forward to the constructor of the + * element. + * @param key A key used both to look up and to insert if not found. + * @param args Arguments to forward to the constructor of the element. + * @return A pair consisting of an iterator to the inserted element (or to + * the element that prevented the insertion) and a bool denoting whether the + * insertion took place. + */ + template + std::pair try_emplace(const key_type &key, Args &&...args) { + return insert_or_do_nothing(key, std::forward(args)...); + } + + /*! @copydoc try_emplace */ + template + std::pair try_emplace(key_type &&key, Args &&...args) { + return insert_or_do_nothing(std::move(key), std::forward(args)...); + } + + /** + * @brief Removes an element from a given position. + * @param pos An iterator to the element to remove. + * @return An iterator following the removed element. + */ + iterator erase(const_iterator pos) { + const auto diff = pos - cbegin(); + erase(pos->first); + return begin() + diff; + } + + /** + * @brief Removes the given elements from a container. + * @param first An iterator to the first element of the range of elements. + * @param last An iterator past the last element of the range of elements. + * @return An iterator following the last removed element. + */ + iterator erase(const_iterator first, const_iterator last) { + const auto dist = first - cbegin(); + + for(auto from = last - cbegin(); from != dist; --from) { + erase(packed.first()[static_cast(from) - 1u].element.first); + } + + return (begin() + dist); + } + + /** + * @brief Removes the element associated with a given key. + * @param key A key value of an element to remove. + * @return Number of elements removed (either 0 or 1). + */ + size_type erase(const key_type &key) { + for(size_type *curr = &sparse.first()[key_to_bucket(key)]; *curr != placeholder_position; curr = &packed.first()[*curr].next) { + if(packed.second()(packed.first()[*curr].element.first, key)) { + const auto index = *curr; + *curr = packed.first()[*curr].next; + move_and_pop(index); + return 1u; + } + } + + return 0u; + } + + /** + * @brief Accesses a given element with bounds checking. + * @param key A key of an element to find. + * @return A reference to the mapped value of the requested element. + */ + [[nodiscard]] mapped_type &at(const key_type &key) { + auto it = find(key); + ENTT_ASSERT(it != end(), "Invalid key"); + return it->second; + } + + /*! @copydoc at */ + [[nodiscard]] const mapped_type &at(const key_type &key) const { + auto it = find(key); + ENTT_ASSERT(it != cend(), "Invalid key"); + return it->second; + } + + /** + * @brief Accesses a given element with bounds checking. + * @tparam Other Type of the key of an element to find. + * @param key A key of an element to find. + * @return A reference to the mapped value of the requested element. + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + at(const Other &key) const { + auto it = find(key); + ENTT_ASSERT(it != cend(), "Invalid key"); + return it->second; + } + + /*! @copydoc at */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + at(const Other &key) { + auto it = find(key); + ENTT_ASSERT(it != end(), "Invalid key"); + return it->second; + } + + /** + * @brief Accesses or inserts a given element. + * @param key A key of an element to find or insert. + * @return A reference to the mapped value of the requested element. + */ + [[nodiscard]] mapped_type &operator[](const key_type &key) { + return insert_or_do_nothing(key).first->second; + } + + /** + * @brief Accesses or inserts a given element. + * @param key A key of an element to find or insert. + * @return A reference to the mapped value of the requested element. + */ + [[nodiscard]] mapped_type &operator[](key_type &&key) { + return insert_or_do_nothing(std::move(key)).first->second; + } + + /** + * @brief Returns the number of elements matching a key (either 1 or 0). + * @param key Key value of an element to search for. + * @return Number of elements matching the key (either 1 or 0). + */ + [[nodiscard]] size_type count(const key_type &key) const { + return find(key) != end(); + } + + /** + * @brief Returns the number of elements matching a key (either 1 or 0). + * @tparam Other Type of the key value of an element to search for. + * @param key Key value of an element to search for. + * @return Number of elements matching the key (either 1 or 0). + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + count(const Other &key) const { + return find(key) != end(); + } + + /** + * @brief Finds an element with a given key. + * @param key Key value of an element to search for. + * @return An iterator to an element with the given key. If no such element + * is found, a past-the-end iterator is returned. + */ + [[nodiscard]] iterator find(const key_type &key) { + return constrained_find(key, key_to_bucket(key)); + } + + /*! @copydoc find */ + [[nodiscard]] const_iterator find(const key_type &key) const { + return constrained_find(key, key_to_bucket(key)); + } + + /** + * @brief Finds an element with a key that compares _equivalent_ to a given + * key. + * @tparam Other Type of the key value of an element to search for. + * @param key Key value of an element to search for. + * @return An iterator to an element with the given key. If no such element + * is found, a past-the-end iterator is returned. + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + find(const Other &key) { + return constrained_find(key, key_to_bucket(key)); + } + + /*! @copydoc find */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + find(const Other &key) const { + return constrained_find(key, key_to_bucket(key)); + } + + /** + * @brief Returns a range containing all elements with a given key. + * @param key Key value of an element to search for. + * @return A pair of iterators pointing to the first element and past the + * last element of the range. + */ + [[nodiscard]] std::pair equal_range(const key_type &key) { + const auto it = find(key); + return {it, it + !(it == end())}; + } + + /*! @copydoc equal_range */ + [[nodiscard]] std::pair equal_range(const key_type &key) const { + const auto it = find(key); + return {it, it + !(it == cend())}; + } + + /** + * @brief Returns a range containing all elements that compare _equivalent_ + * to a given key. + * @tparam Other Type of an element to search for. + * @param key Key value of an element to search for. + * @return A pair of iterators pointing to the first element and past the + * last element of the range. + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t>> + equal_range(const Other &key) { + const auto it = find(key); + return {it, it + !(it == end())}; + } + + /*! @copydoc equal_range */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t>> + equal_range(const Other &key) const { + const auto it = find(key); + return {it, it + !(it == cend())}; + } + + /** + * @brief Checks if the container contains an element with a given key. + * @param key Key value of an element to search for. + * @return True if there is such an element, false otherwise. + */ + [[nodiscard]] bool contains(const key_type &key) const { + return (find(key) != cend()); + } + + /** + * @brief Checks if the container contains an element with a key that + * compares _equivalent_ to a given value. + * @tparam Other Type of the key value of an element to search for. + * @param key Key value of an element to search for. + * @return True if there is such an element, false otherwise. + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + contains(const Other &key) const { + return (find(key) != cend()); + } + + /** + * @brief Returns an iterator to the beginning of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the beginning of the given bucket. + */ + [[nodiscard]] const_local_iterator cbegin(const size_type index) const { + return {packed.first().begin(), sparse.first()[index]}; + } + + /** + * @brief Returns an iterator to the beginning of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the beginning of the given bucket. + */ + [[nodiscard]] const_local_iterator begin(const size_type index) const { + return cbegin(index); + } + + /** + * @brief Returns an iterator to the beginning of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the beginning of the given bucket. + */ + [[nodiscard]] local_iterator begin(const size_type index) { + return {packed.first().begin(), sparse.first()[index]}; + } + + /** + * @brief Returns an iterator to the end of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the end of the given bucket. + */ + [[nodiscard]] const_local_iterator cend([[maybe_unused]] const size_type index) const { + return {}; + } + + /** + * @brief Returns an iterator to the end of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the end of the given bucket. + */ + [[nodiscard]] const_local_iterator end(const size_type index) const { + return cend(index); + } + + /** + * @brief Returns an iterator to the end of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the end of the given bucket. + */ + [[nodiscard]] local_iterator end([[maybe_unused]] const size_type index) { + return {}; + } + + /** + * @brief Returns the number of buckets. + * @return The number of buckets. + */ + [[nodiscard]] size_type bucket_count() const { + return sparse.first().size(); + } + + /** + * @brief Returns the maximum number of buckets. + * @return The maximum number of buckets. + */ + [[nodiscard]] size_type max_bucket_count() const { + return sparse.first().max_size(); + } + + /** + * @brief Returns the number of elements in a given bucket. + * @param index The index of the bucket to examine. + * @return The number of elements in the given bucket. + */ + [[nodiscard]] size_type bucket_size(const size_type index) const { + return static_cast(std::distance(begin(index), end(index))); + } + + /** + * @brief Returns the bucket for a given key. + * @param key The value of the key to examine. + * @return The bucket for the given key. + */ + [[nodiscard]] size_type bucket(const key_type &key) const { + return key_to_bucket(key); + } + + /** + * @brief Returns the average number of elements per bucket. + * @return The average number of elements per bucket. + */ + [[nodiscard]] float load_factor() const { + return static_cast(size()) / static_cast(bucket_count()); + } + + /** + * @brief Returns the maximum average number of elements per bucket. + * @return The maximum average number of elements per bucket. + */ + [[nodiscard]] float max_load_factor() const { + return threshold; + } + + /** + * @brief Sets the desired maximum average number of elements per bucket. + * @param value A desired maximum average number of elements per bucket. + */ + void max_load_factor(const float value) { + ENTT_ASSERT(value > 0.f, "Invalid load factor"); + threshold = value; + rehash(0u); + } + + /** + * @brief Reserves at least the specified number of buckets and regenerates + * the hash table. + * @param cnt New number of buckets. + */ + void rehash(const size_type cnt) { + auto value = cnt > minimum_capacity ? cnt : minimum_capacity; + const auto cap = static_cast(static_cast(size()) / max_load_factor()); + value = value > cap ? value : cap; + + if(const auto sz = next_power_of_two(value); sz != bucket_count()) { + sparse.first().resize(sz); + + for(auto &&elem: sparse.first()) { + elem = placeholder_position; + } + + for(size_type pos{}, last = size(); pos < last; ++pos) { + const auto index = key_to_bucket(packed.first()[pos].element.first); + packed.first()[pos].next = std::exchange(sparse.first()[index], pos); + } + } + } + + /** + * @brief Reserves space for at least the specified number of elements and + * regenerates the hash table. + * @param cnt New number of elements. + */ + void reserve(const size_type cnt) { + packed.first().reserve(cnt); + rehash(static_cast(std::ceil(static_cast(cnt) / max_load_factor()))); + } + + /** + * @brief Returns the function used to hash the keys. + * @return The function used to hash the keys. + */ + [[nodiscard]] hasher hash_function() const { + return sparse.second(); + } + + /** + * @brief Returns the function used to compare keys for equality. + * @return The function used to compare keys for equality. + */ + [[nodiscard]] key_equal key_eq() const { + return packed.second(); + } + +private: + compressed_pair sparse; + compressed_pair packed; + float threshold{default_threshold}; +}; + +} // namespace entt + +/*! @cond TURN_OFF_DOXYGEN */ +namespace std { + +template +struct uses_allocator, Allocator> + : std::true_type {}; + +} // namespace std +/*! @endcond */ + +#endif + +// #include "container/dense_set.hpp" +#ifndef ENTT_CONTAINER_DENSE_SET_HPP +#define ENTT_CONTAINER_DENSE_SET_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "../core/bit.hpp" + +// #include "../core/compressed_pair.hpp" + +// #include "../core/type_traits.hpp" + +// #include "fwd.hpp" + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +static constexpr std::size_t dense_set_placeholder_position = (std::numeric_limits::max)(); + +template +class dense_set_iterator final { + template + friend class dense_set_iterator; + +public: + using value_type = typename It::value_type::second_type; + using pointer = const value_type *; + using reference = const value_type &; + using difference_type = std::ptrdiff_t; + using iterator_category = std::random_access_iterator_tag; + + constexpr dense_set_iterator() noexcept + : it{} {} + + constexpr dense_set_iterator(const It iter) noexcept + : it{iter} {} + + template && std::is_constructible_v>> + constexpr dense_set_iterator(const dense_set_iterator &other) noexcept + : it{other.it} {} + + constexpr dense_set_iterator &operator++() noexcept { + return ++it, *this; + } + + constexpr dense_set_iterator operator++(int) noexcept { + const dense_set_iterator orig = *this; + return ++(*this), orig; + } + + constexpr dense_set_iterator &operator--() noexcept { + return --it, *this; + } + + constexpr dense_set_iterator operator--(int) noexcept { + const dense_set_iterator orig = *this; + return operator--(), orig; + } + + constexpr dense_set_iterator &operator+=(const difference_type value) noexcept { + it += value; + return *this; + } + + constexpr dense_set_iterator operator+(const difference_type value) const noexcept { + dense_set_iterator copy = *this; + return (copy += value); + } + + constexpr dense_set_iterator &operator-=(const difference_type value) noexcept { + return (*this += -value); + } + + constexpr dense_set_iterator operator-(const difference_type value) const noexcept { + return (*this + -value); + } + + [[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept { + return it[value].second; + } + + [[nodiscard]] constexpr pointer operator->() const noexcept { + return std::addressof(operator[](0)); + } + + [[nodiscard]] constexpr reference operator*() const noexcept { + return operator[](0); + } + + template + friend constexpr std::ptrdiff_t operator-(const dense_set_iterator &, const dense_set_iterator &) noexcept; + + template + friend constexpr bool operator==(const dense_set_iterator &, const dense_set_iterator &) noexcept; + + template + friend constexpr bool operator<(const dense_set_iterator &, const dense_set_iterator &) noexcept; + +private: + It it; +}; + +template +[[nodiscard]] constexpr std::ptrdiff_t operator-(const dense_set_iterator &lhs, const dense_set_iterator &rhs) noexcept { + return lhs.it - rhs.it; +} + +template +[[nodiscard]] constexpr bool operator==(const dense_set_iterator &lhs, const dense_set_iterator &rhs) noexcept { + return lhs.it == rhs.it; +} + +template +[[nodiscard]] constexpr bool operator!=(const dense_set_iterator &lhs, const dense_set_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +template +[[nodiscard]] constexpr bool operator<(const dense_set_iterator &lhs, const dense_set_iterator &rhs) noexcept { + return lhs.it < rhs.it; +} + +template +[[nodiscard]] constexpr bool operator>(const dense_set_iterator &lhs, const dense_set_iterator &rhs) noexcept { + return rhs < lhs; +} + +template +[[nodiscard]] constexpr bool operator<=(const dense_set_iterator &lhs, const dense_set_iterator &rhs) noexcept { + return !(lhs > rhs); +} + +template +[[nodiscard]] constexpr bool operator>=(const dense_set_iterator &lhs, const dense_set_iterator &rhs) noexcept { + return !(lhs < rhs); +} + +template +class dense_set_local_iterator final { + template + friend class dense_set_local_iterator; + +public: + using value_type = typename It::value_type::second_type; + using pointer = const value_type *; + using reference = const value_type &; + using difference_type = std::ptrdiff_t; + using iterator_category = std::forward_iterator_tag; + + constexpr dense_set_local_iterator() noexcept = default; + + constexpr dense_set_local_iterator(It iter, const std::size_t pos) noexcept + : it{iter}, + offset{pos} {} + + template && std::is_constructible_v>> + constexpr dense_set_local_iterator(const dense_set_local_iterator &other) noexcept + : it{other.it}, + offset{other.offset} {} + + constexpr dense_set_local_iterator &operator++() noexcept { + return offset = it[static_cast(offset)].first, *this; + } + + constexpr dense_set_local_iterator operator++(int) noexcept { + const dense_set_local_iterator orig = *this; + return ++(*this), orig; + } + + [[nodiscard]] constexpr pointer operator->() const noexcept { + return std::addressof(it[static_cast(offset)].second); + } + + [[nodiscard]] constexpr reference operator*() const noexcept { + return *operator->(); + } + + [[nodiscard]] constexpr std::size_t index() const noexcept { + return offset; + } + +private: + It it{}; + std::size_t offset{dense_set_placeholder_position}; +}; + +template +[[nodiscard]] constexpr bool operator==(const dense_set_local_iterator &lhs, const dense_set_local_iterator &rhs) noexcept { + return lhs.index() == rhs.index(); +} + +template +[[nodiscard]] constexpr bool operator!=(const dense_set_local_iterator &lhs, const dense_set_local_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Associative container for unique objects of a given type. + * + * Internally, elements are organized into buckets. Which bucket an element is + * placed into depends entirely on its hash. Elements with the same hash code + * appear in the same bucket. + * + * @tparam Type Value type of the associative container. + * @tparam Hash Type of function to use to hash the values. + * @tparam KeyEqual Type of function to use to compare the values for equality. + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +class dense_set { + static constexpr float default_threshold = 0.875f; + static constexpr std::size_t minimum_capacity = 8u; + static constexpr std::size_t placeholder_position = internal::dense_set_placeholder_position; + + using node_type = std::pair; + using alloc_traits = std::allocator_traits; + static_assert(std::is_same_v, "Invalid value type"); + using sparse_container_type = std::vector>; + using packed_container_type = std::vector>; + + template + [[nodiscard]] std::size_t value_to_bucket(const Other &value) const noexcept { + return fast_mod(static_cast(sparse.second()(value)), bucket_count()); + } + + template + [[nodiscard]] auto constrained_find(const Other &value, const std::size_t bucket) { + for(auto offset = sparse.first()[bucket]; offset != placeholder_position; offset = packed.first()[offset].first) { + if(packed.second()(packed.first()[offset].second, value)) { + return begin() + static_cast(offset); + } + } + + return end(); + } + + template + [[nodiscard]] auto constrained_find(const Other &value, const std::size_t bucket) const { + for(auto offset = sparse.first()[bucket]; offset != placeholder_position; offset = packed.first()[offset].first) { + if(packed.second()(packed.first()[offset].second, value)) { + return cbegin() + static_cast(offset); + } + } + + return cend(); + } + + template + [[nodiscard]] auto insert_or_do_nothing(Other &&value) { + const auto index = value_to_bucket(value); + + if(auto it = constrained_find(value, index); it != end()) { + return std::make_pair(it, false); + } + + packed.first().emplace_back(sparse.first()[index], std::forward(value)); + sparse.first()[index] = packed.first().size() - 1u; + rehash_if_required(); + + return std::make_pair(--end(), true); + } + + void move_and_pop(const std::size_t pos) { + if(const auto last = size() - 1u; pos != last) { + size_type *curr = &sparse.first()[value_to_bucket(packed.first().back().second)]; + packed.first()[pos] = std::move(packed.first().back()); + for(; *curr != last; curr = &packed.first()[*curr].first) {} + *curr = pos; + } + + packed.first().pop_back(); + } + + void rehash_if_required() { + if(const auto bc = bucket_count(); size() > static_cast(static_cast(bc) * max_load_factor())) { + rehash(bc * 2u); + } + } + +public: + /*! @brief Allocator type. */ + using allocator_type = Allocator; + /*! @brief Key type of the container. */ + using key_type = Type; + /*! @brief Value type of the container. */ + using value_type = Type; + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + /*! @brief Signed integer type. */ + using difference_type = std::ptrdiff_t; + /*! @brief Type of function to use to hash the elements. */ + using hasher = Hash; + /*! @brief Type of function to use to compare the elements for equality. */ + using key_equal = KeyEqual; + /*! @brief Random access iterator type. */ + using iterator = internal::dense_set_iterator; + /*! @brief Constant random access iterator type. */ + using const_iterator = internal::dense_set_iterator; + /*! @brief Reverse iterator type. */ + using reverse_iterator = std::reverse_iterator; + /*! @brief Constant reverse iterator type. */ + using const_reverse_iterator = std::reverse_iterator; + /*! @brief Forward iterator type. */ + using local_iterator = internal::dense_set_local_iterator; + /*! @brief Constant forward iterator type. */ + using const_local_iterator = internal::dense_set_local_iterator; + + /*! @brief Default constructor. */ + dense_set() + : dense_set{minimum_capacity} {} + + /** + * @brief Constructs an empty container with a given allocator. + * @param allocator The allocator to use. + */ + explicit dense_set(const allocator_type &allocator) + : dense_set{minimum_capacity, hasher{}, key_equal{}, allocator} {} + + /** + * @brief Constructs an empty container with a given allocator and user + * supplied minimal number of buckets. + * @param cnt Minimal number of buckets. + * @param allocator The allocator to use. + */ + dense_set(const size_type cnt, const allocator_type &allocator) + : dense_set{cnt, hasher{}, key_equal{}, allocator} {} + + /** + * @brief Constructs an empty container with a given allocator, hash + * function and user supplied minimal number of buckets. + * @param cnt Minimal number of buckets. + * @param hash Hash function to use. + * @param allocator The allocator to use. + */ + dense_set(const size_type cnt, const hasher &hash, const allocator_type &allocator) + : dense_set{cnt, hash, key_equal{}, allocator} {} + + /** + * @brief Constructs an empty container with a given allocator, hash + * function, compare function and user supplied minimal number of buckets. + * @param cnt Minimal number of buckets. + * @param hash Hash function to use. + * @param equal Compare function to use. + * @param allocator The allocator to use. + */ + explicit dense_set(const size_type cnt, const hasher &hash = hasher{}, const key_equal &equal = key_equal{}, const allocator_type &allocator = allocator_type{}) + : sparse{allocator, hash}, + packed{allocator, equal} { + rehash(cnt); + } + + /*! @brief Default copy constructor. */ + dense_set(const dense_set &) = default; + + /** + * @brief Allocator-extended copy constructor. + * @param other The instance to copy from. + * @param allocator The allocator to use. + */ + dense_set(const dense_set &other, const allocator_type &allocator) + : sparse{std::piecewise_construct, std::forward_as_tuple(other.sparse.first(), allocator), std::forward_as_tuple(other.sparse.second())}, + packed{std::piecewise_construct, std::forward_as_tuple(other.packed.first(), allocator), std::forward_as_tuple(other.packed.second())}, + threshold{other.threshold} {} + + /*! @brief Default move constructor. */ + dense_set(dense_set &&) noexcept = default; + + /** + * @brief Allocator-extended move constructor. + * @param other The instance to move from. + * @param allocator The allocator to use. + */ + dense_set(dense_set &&other, const allocator_type &allocator) + : sparse{std::piecewise_construct, std::forward_as_tuple(std::move(other.sparse.first()), allocator), std::forward_as_tuple(std::move(other.sparse.second()))}, + packed{std::piecewise_construct, std::forward_as_tuple(std::move(other.packed.first()), allocator), std::forward_as_tuple(std::move(other.packed.second()))}, + threshold{other.threshold} {} + + /*! @brief Default destructor. */ + ~dense_set() = default; + + /** + * @brief Default copy assignment operator. + * @return This container. + */ + dense_set &operator=(const dense_set &) = default; + + /** + * @brief Default move assignment operator. + * @return This container. + */ + dense_set &operator=(dense_set &&) noexcept = default; + + /** + * @brief Exchanges the contents with those of a given container. + * @param other Container to exchange the content with. + */ + void swap(dense_set &other) noexcept { + using std::swap; + swap(sparse, other.sparse); + swap(packed, other.packed); + swap(threshold, other.threshold); + } + + /** + * @brief Returns the associated allocator. + * @return The associated allocator. + */ + [[nodiscard]] constexpr allocator_type get_allocator() const noexcept { + return sparse.first().get_allocator(); + } + + /** + * @brief Returns an iterator to the beginning. + * + * If the array is empty, the returned iterator will be equal to `end()`. + * + * @return An iterator to the first instance of the internal array. + */ + [[nodiscard]] const_iterator cbegin() const noexcept { + return packed.first().begin(); + } + + /*! @copydoc cbegin */ + [[nodiscard]] const_iterator begin() const noexcept { + return cbegin(); + } + + /*! @copydoc begin */ + [[nodiscard]] iterator begin() noexcept { + return packed.first().begin(); + } + + /** + * @brief Returns an iterator to the end. + * @return An iterator to the element following the last instance of the + * internal array. + */ + [[nodiscard]] const_iterator cend() const noexcept { + return packed.first().end(); + } + + /*! @copydoc cend */ + [[nodiscard]] const_iterator end() const noexcept { + return cend(); + } + + /*! @copydoc end */ + [[nodiscard]] iterator end() noexcept { + return packed.first().end(); + } + + /** + * @brief Returns a reverse iterator to the beginning. + * + * If the array is empty, the returned iterator will be equal to `rend()`. + * + * @return An iterator to the first instance of the reversed internal array. + */ + [[nodiscard]] const_reverse_iterator crbegin() const noexcept { + return std::make_reverse_iterator(cend()); + } + + /*! @copydoc crbegin */ + [[nodiscard]] const_reverse_iterator rbegin() const noexcept { + return crbegin(); + } + + /*! @copydoc rbegin */ + [[nodiscard]] reverse_iterator rbegin() noexcept { + return std::make_reverse_iterator(end()); + } + + /** + * @brief Returns a reverse iterator to the end. + * @return An iterator to the element following the last instance of the + * reversed internal array. + */ + [[nodiscard]] const_reverse_iterator crend() const noexcept { + return std::make_reverse_iterator(cbegin()); + } + + /*! @copydoc crend */ + [[nodiscard]] const_reverse_iterator rend() const noexcept { + return crend(); + } + + /*! @copydoc rend */ + [[nodiscard]] reverse_iterator rend() noexcept { + return std::make_reverse_iterator(begin()); + } + + /** + * @brief Checks whether a container is empty. + * @return True if the container is empty, false otherwise. + */ + [[nodiscard]] bool empty() const noexcept { + return packed.first().empty(); + } + + /** + * @brief Returns the number of elements in a container. + * @return Number of elements in a container. + */ + [[nodiscard]] size_type size() const noexcept { + return packed.first().size(); + } + + /** + * @brief Returns the maximum possible number of elements. + * @return Maximum possible number of elements. + */ + [[nodiscard]] size_type max_size() const noexcept { + return packed.first().max_size(); + } + + /*! @brief Clears the container. */ + void clear() noexcept { + sparse.first().clear(); + packed.first().clear(); + rehash(0u); + } + + /** + * @brief Inserts an element into the container, if it does not exist. + * @param value An element to insert into the container. + * @return A pair consisting of an iterator to the inserted element (or to + * the element that prevented the insertion) and a bool denoting whether the + * insertion took place. + */ + std::pair insert(const value_type &value) { + return insert_or_do_nothing(value); + } + + /*! @copydoc insert */ + std::pair insert(value_type &&value) { + return insert_or_do_nothing(std::move(value)); + } + + /** + * @brief Inserts elements into the container, if they do not exist. + * @tparam It Type of input iterator. + * @param first An iterator to the first element of the range of elements. + * @param last An iterator past the last element of the range of elements. + */ + template + void insert(It first, It last) { + for(; first != last; ++first) { + insert(*first); + } + } + + /** + * @brief Constructs an element in-place, if it does not exist. + * + * The element is also constructed when the container already has the key, + * in which case the newly constructed object is destroyed immediately. + * + * @tparam Args Types of arguments to forward to the constructor of the + * element. + * @param args Arguments to forward to the constructor of the element. + * @return A pair consisting of an iterator to the inserted element (or to + * the element that prevented the insertion) and a bool denoting whether the + * insertion took place. + */ + template + std::pair emplace(Args &&...args) { + if constexpr(((sizeof...(Args) == 1u) && ... && std::is_same_v, value_type>)) { + return insert_or_do_nothing(std::forward(args)...); + } else { + auto &node = packed.first().emplace_back(std::piecewise_construct, std::make_tuple(packed.first().size()), std::forward_as_tuple(std::forward(args)...)); + const auto index = value_to_bucket(node.second); + + if(auto it = constrained_find(node.second, index); it != end()) { + packed.first().pop_back(); + return std::make_pair(it, false); + } + + std::swap(node.first, sparse.first()[index]); + rehash_if_required(); + + return std::make_pair(--end(), true); + } + } + + /** + * @brief Removes an element from a given position. + * @param pos An iterator to the element to remove. + * @return An iterator following the removed element. + */ + iterator erase(const_iterator pos) { + const auto diff = pos - cbegin(); + erase(*pos); + return begin() + diff; + } + + /** + * @brief Removes the given elements from a container. + * @param first An iterator to the first element of the range of elements. + * @param last An iterator past the last element of the range of elements. + * @return An iterator following the last removed element. + */ + iterator erase(const_iterator first, const_iterator last) { + const auto dist = first - cbegin(); + + for(auto from = last - cbegin(); from != dist; --from) { + erase(packed.first()[static_cast(from) - 1u].second); + } + + return (begin() + dist); + } + + /** + * @brief Removes the element associated with a given value. + * @param value Value of an element to remove. + * @return Number of elements removed (either 0 or 1). + */ + size_type erase(const value_type &value) { + for(size_type *curr = &sparse.first()[value_to_bucket(value)]; *curr != placeholder_position; curr = &packed.first()[*curr].first) { + if(packed.second()(packed.first()[*curr].second, value)) { + const auto index = *curr; + *curr = packed.first()[*curr].first; + move_and_pop(index); + return 1u; + } + } + + return 0u; + } + + /** + * @brief Returns the number of elements matching a value (either 1 or 0). + * @param key Key value of an element to search for. + * @return Number of elements matching the key (either 1 or 0). + */ + [[nodiscard]] size_type count(const value_type &key) const { + return find(key) != end(); + } + + /** + * @brief Returns the number of elements matching a key (either 1 or 0). + * @tparam Other Type of the key value of an element to search for. + * @param key Key value of an element to search for. + * @return Number of elements matching the key (either 1 or 0). + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + count(const Other &key) const { + return find(key) != end(); + } + + /** + * @brief Finds an element with a given value. + * @param value Value of an element to search for. + * @return An iterator to an element with the given value. If no such + * element is found, a past-the-end iterator is returned. + */ + [[nodiscard]] iterator find(const value_type &value) { + return constrained_find(value, value_to_bucket(value)); + } + + /*! @copydoc find */ + [[nodiscard]] const_iterator find(const value_type &value) const { + return constrained_find(value, value_to_bucket(value)); + } + + /** + * @brief Finds an element that compares _equivalent_ to a given value. + * @tparam Other Type of an element to search for. + * @param value Value of an element to search for. + * @return An iterator to an element with the given value. If no such + * element is found, a past-the-end iterator is returned. + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + find(const Other &value) { + return constrained_find(value, value_to_bucket(value)); + } + + /*! @copydoc find */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + find(const Other &value) const { + return constrained_find(value, value_to_bucket(value)); + } + + /** + * @brief Returns a range containing all elements with a given value. + * @param value Value of an element to search for. + * @return A pair of iterators pointing to the first element and past the + * last element of the range. + */ + [[nodiscard]] std::pair equal_range(const value_type &value) { + const auto it = find(value); + return {it, it + !(it == end())}; + } + + /*! @copydoc equal_range */ + [[nodiscard]] std::pair equal_range(const value_type &value) const { + const auto it = find(value); + return {it, it + !(it == cend())}; + } + + /** + * @brief Returns a range containing all elements that compare _equivalent_ + * to a given value. + * @tparam Other Type of an element to search for. + * @param value Value of an element to search for. + * @return A pair of iterators pointing to the first element and past the + * last element of the range. + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t>> + equal_range(const Other &value) { + const auto it = find(value); + return {it, it + !(it == end())}; + } + + /*! @copydoc equal_range */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t>> + equal_range(const Other &value) const { + const auto it = find(value); + return {it, it + !(it == cend())}; + } + + /** + * @brief Checks if the container contains an element with a given value. + * @param value Value of an element to search for. + * @return True if there is such an element, false otherwise. + */ + [[nodiscard]] bool contains(const value_type &value) const { + return (find(value) != cend()); + } + + /** + * @brief Checks if the container contains an element that compares + * _equivalent_ to a given value. + * @tparam Other Type of an element to search for. + * @param value Value of an element to search for. + * @return True if there is such an element, false otherwise. + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + contains(const Other &value) const { + return (find(value) != cend()); + } + + /** + * @brief Returns an iterator to the beginning of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the beginning of the given bucket. + */ + [[nodiscard]] const_local_iterator cbegin(const size_type index) const { + return {packed.first().begin(), sparse.first()[index]}; + } + + /** + * @brief Returns an iterator to the beginning of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the beginning of the given bucket. + */ + [[nodiscard]] const_local_iterator begin(const size_type index) const { + return cbegin(index); + } + + /** + * @brief Returns an iterator to the beginning of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the beginning of the given bucket. + */ + [[nodiscard]] local_iterator begin(const size_type index) { + return {packed.first().begin(), sparse.first()[index]}; + } + + /** + * @brief Returns an iterator to the end of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the end of the given bucket. + */ + [[nodiscard]] const_local_iterator cend([[maybe_unused]] const size_type index) const { + return {}; + } + + /** + * @brief Returns an iterator to the end of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the end of the given bucket. + */ + [[nodiscard]] const_local_iterator end(const size_type index) const { + return cend(index); + } + + /** + * @brief Returns an iterator to the end of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the end of the given bucket. + */ + [[nodiscard]] local_iterator end([[maybe_unused]] const size_type index) { + return {}; + } + + /** + * @brief Returns the number of buckets. + * @return The number of buckets. + */ + [[nodiscard]] size_type bucket_count() const { + return sparse.first().size(); + } + + /** + * @brief Returns the maximum number of buckets. + * @return The maximum number of buckets. + */ + [[nodiscard]] size_type max_bucket_count() const { + return sparse.first().max_size(); + } + + /** + * @brief Returns the number of elements in a given bucket. + * @param index The index of the bucket to examine. + * @return The number of elements in the given bucket. + */ + [[nodiscard]] size_type bucket_size(const size_type index) const { + return static_cast(std::distance(begin(index), end(index))); + } + + /** + * @brief Returns the bucket for a given element. + * @param value The value of the element to examine. + * @return The bucket for the given element. + */ + [[nodiscard]] size_type bucket(const value_type &value) const { + return value_to_bucket(value); + } + + /** + * @brief Returns the average number of elements per bucket. + * @return The average number of elements per bucket. + */ + [[nodiscard]] float load_factor() const { + return static_cast(size()) / static_cast(bucket_count()); + } + + /** + * @brief Returns the maximum average number of elements per bucket. + * @return The maximum average number of elements per bucket. + */ + [[nodiscard]] float max_load_factor() const { + return threshold; + } + + /** + * @brief Sets the desired maximum average number of elements per bucket. + * @param value A desired maximum average number of elements per bucket. + */ + void max_load_factor(const float value) { + ENTT_ASSERT(value > 0.f, "Invalid load factor"); + threshold = value; + rehash(0u); + } + + /** + * @brief Reserves at least the specified number of buckets and regenerates + * the hash table. + * @param cnt New number of buckets. + */ + void rehash(const size_type cnt) { + auto value = cnt > minimum_capacity ? cnt : minimum_capacity; + const auto cap = static_cast(static_cast(size()) / max_load_factor()); + value = value > cap ? value : cap; + + if(const auto sz = next_power_of_two(value); sz != bucket_count()) { + sparse.first().resize(sz); + + for(auto &&elem: sparse.first()) { + elem = placeholder_position; + } + + for(size_type pos{}, last = size(); pos < last; ++pos) { + const auto index = value_to_bucket(packed.first()[pos].second); + packed.first()[pos].first = std::exchange(sparse.first()[index], pos); + } + } + } + + /** + * @brief Reserves space for at least the specified number of elements and + * regenerates the hash table. + * @param cnt New number of elements. + */ + void reserve(const size_type cnt) { + packed.first().reserve(cnt); + rehash(static_cast(std::ceil(static_cast(cnt) / max_load_factor()))); + } + + /** + * @brief Returns the function used to hash the elements. + * @return The function used to hash the elements. + */ + [[nodiscard]] hasher hash_function() const { + return sparse.second(); + } + + /** + * @brief Returns the function used to compare elements for equality. + * @return The function used to compare elements for equality. + */ + [[nodiscard]] key_equal key_eq() const { + return packed.second(); + } + +private: + compressed_pair sparse; + compressed_pair packed; + float threshold{default_threshold}; +}; + +} // namespace entt + +#endif + +// #include "container/table.hpp" +#ifndef ENTT_CONTAINER_TABLE_HPP +#define ENTT_CONTAINER_TABLE_HPP + +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "../core/iterator.hpp" + +// #include "fwd.hpp" + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +class table_iterator { + template + friend class table_iterator; + +public: + using value_type = decltype(std::forward_as_tuple(*std::declval()...)); + using pointer = input_iterator_pointer; + using reference = value_type; + using difference_type = std::ptrdiff_t; + using iterator_category = std::input_iterator_tag; + using iterator_concept = std::random_access_iterator_tag; + + constexpr table_iterator() noexcept + : it{} {} + + constexpr table_iterator(It... from) noexcept + : it{from...} {} + + template && ...)>> + constexpr table_iterator(const table_iterator &other) noexcept + : table_iterator{std::get(other.it)...} {} + + constexpr table_iterator &operator++() noexcept { + return (++std::get(it), ...), *this; + } + + constexpr table_iterator operator++(int) noexcept { + const table_iterator orig = *this; + return ++(*this), orig; + } + + constexpr table_iterator &operator--() noexcept { + return (--std::get(it), ...), *this; + } + + constexpr table_iterator operator--(int) noexcept { + const table_iterator orig = *this; + return operator--(), orig; + } + + constexpr table_iterator &operator+=(const difference_type value) noexcept { + return ((std::get(it) += value), ...), *this; + } + + constexpr table_iterator operator+(const difference_type value) const noexcept { + table_iterator copy = *this; + return (copy += value); + } + + constexpr table_iterator &operator-=(const difference_type value) noexcept { + return (*this += -value); + } + + constexpr table_iterator operator-(const difference_type value) const noexcept { + return (*this + -value); + } + + [[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept { + return std::forward_as_tuple(std::get(it)[value]...); + } + + [[nodiscard]] constexpr pointer operator->() const noexcept { + return {operator[](0)}; + } + + [[nodiscard]] constexpr reference operator*() const noexcept { + return operator[](0); + } + + template + friend constexpr std::ptrdiff_t operator-(const table_iterator &, const table_iterator &) noexcept; + + template + friend constexpr bool operator==(const table_iterator &, const table_iterator &) noexcept; + + template + friend constexpr bool operator<(const table_iterator &, const table_iterator &) noexcept; + +private: + std::tuple it; +}; + +template +[[nodiscard]] constexpr std::ptrdiff_t operator-(const table_iterator &lhs, const table_iterator &rhs) noexcept { + return std::get<0>(lhs.it) - std::get<0>(rhs.it); +} + +template +[[nodiscard]] constexpr bool operator==(const table_iterator &lhs, const table_iterator &rhs) noexcept { + return std::get<0>(lhs.it) == std::get<0>(rhs.it); +} + +template +[[nodiscard]] constexpr bool operator!=(const table_iterator &lhs, const table_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +template +[[nodiscard]] constexpr bool operator<(const table_iterator &lhs, const table_iterator &rhs) noexcept { + return std::get<0>(lhs.it) < std::get<0>(rhs.it); +} + +template +[[nodiscard]] constexpr bool operator>(const table_iterator &lhs, const table_iterator &rhs) noexcept { + return rhs < lhs; +} + +template +[[nodiscard]] constexpr bool operator<=(const table_iterator &lhs, const table_iterator &rhs) noexcept { + return !(lhs > rhs); +} + +template +[[nodiscard]] constexpr bool operator>=(const table_iterator &lhs, const table_iterator &rhs) noexcept { + return !(lhs < rhs); +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Basic table implementation. + * + * Internal data structures arrange elements to maximize performance. There are + * no guarantees that objects are returned in the insertion order when iterate + * a table. Do not make assumption on the order in any case. + * + * @tparam Container Sequence container row types. + */ +template +class basic_table { + using container_type = std::tuple; + +public: + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + /*! @brief Signed integer type. */ + using difference_type = std::ptrdiff_t; + /*! @brief Input iterator type. */ + using iterator = internal::table_iterator; + /*! @brief Constant input iterator type. */ + using const_iterator = internal::table_iterator; + /*! @brief Reverse iterator type. */ + using reverse_iterator = internal::table_iterator; + /*! @brief Constant reverse iterator type. */ + using const_reverse_iterator = internal::table_iterator; + + /*! @brief Default constructor. */ + basic_table() + : payload{} { + } + + /** + * @brief Copy constructs the underlying containers. + * @param container The containers to copy from. + */ + explicit basic_table(const Container &...container) noexcept + : payload{container...} { + ENTT_ASSERT((((std::get(payload).size() * sizeof...(Container)) == (std::get(payload).size() + ...)) && ...), "Unexpected container size"); + } + + /** + * @brief Move constructs the underlying containers. + * @param container The containers to move from. + */ + explicit basic_table(Container &&...container) noexcept + : payload{std::move(container)...} { + ENTT_ASSERT((((std::get(payload).size() * sizeof...(Container)) == (std::get(payload).size() + ...)) && ...), "Unexpected container size"); + } + + /*! @brief Default copy constructor, deleted on purpose. */ + basic_table(const basic_table &) = delete; + + /** + * @brief Move constructor. + * @param other The instance to move from. + */ + basic_table(basic_table &&other) noexcept + : payload{std::move(other.payload)} {} + + /** + * @brief Constructs the underlying containers using a given allocator. + * @tparam Allocator Type of allocator. + * @param allocator A valid allocator. + */ + template + explicit basic_table(const Allocator &allocator) + : payload{Container{allocator}...} {} + + /** + * @brief Copy constructs the underlying containers using a given allocator. + * @tparam Allocator Type of allocator. + * @param container The containers to copy from. + * @param allocator A valid allocator. + */ + template + basic_table(const Container &...container, const Allocator &allocator) noexcept + : payload{Container{container, allocator}...} { + ENTT_ASSERT((((std::get(payload).size() * sizeof...(Container)) == (std::get(payload).size() + ...)) && ...), "Unexpected container size"); + } + + /** + * @brief Move constructs the underlying containers using a given allocator. + * @tparam Allocator Type of allocator. + * @param container The containers to move from. + * @param allocator A valid allocator. + */ + template + basic_table(Container &&...container, const Allocator &allocator) noexcept + : payload{Container{std::move(container), allocator}...} { + ENTT_ASSERT((((std::get(payload).size() * sizeof...(Container)) == (std::get(payload).size() + ...)) && ...), "Unexpected container size"); + } + + /** + * @brief Allocator-extended move constructor. + * @tparam Allocator Type of allocator. + * @param other The instance to move from. + * @param allocator The allocator to use. + */ + template + basic_table(basic_table &&other, const Allocator &allocator) + : payload{Container{std::move(std::get(other.payload)), allocator}...} {} + + /*! @brief Default destructor. */ + ~basic_table() = default; + + /** + * @brief Default copy assignment operator, deleted on purpose. + * @return This container. + */ + basic_table &operator=(const basic_table &) = delete; + + /** + * @brief Move assignment operator. + * @param other The instance to move from. + * @return This container. + */ + basic_table &operator=(basic_table &&other) noexcept { + swap(other); + return *this; + } + + /** + * @brief Exchanges the contents with those of a given table. + * @param other Table to exchange the content with. + */ + void swap(basic_table &other) noexcept { + using std::swap; + swap(payload, other.payload); + } + + /** + * @brief Increases the capacity of a table. + * + * If the new capacity is greater than the current capacity, new storage is + * allocated, otherwise the method does nothing. + * + * @param cap Desired capacity. + */ + void reserve(const size_type cap) { + (std::get(payload).reserve(cap), ...); + } + + /** + * @brief Returns the number of rows that a table has currently allocated + * space for. + * @return Capacity of the table. + */ + [[nodiscard]] size_type capacity() const noexcept { + return std::get<0>(payload).capacity(); + } + + /*! @brief Requests the removal of unused capacity. */ + void shrink_to_fit() { + (std::get(payload).shrink_to_fit(), ...); + } + + /** + * @brief Returns the number of rows in a table. + * @return Number of rows. + */ + [[nodiscard]] size_type size() const noexcept { + return std::get<0>(payload).size(); + } + + /** + * @brief Checks whether a table is empty. + * @return True if the table is empty, false otherwise. + */ + [[nodiscard]] bool empty() const noexcept { + return std::get<0>(payload).empty(); + } + + /** + * @brief Returns an iterator to the beginning. + * + * If the table is empty, the returned iterator will be equal to `end()`. + * + * @return An iterator to the first row of the table. + */ + [[nodiscard]] const_iterator cbegin() const noexcept { + return {std::get(payload).cbegin()...}; + } + + /*! @copydoc cbegin */ + [[nodiscard]] const_iterator begin() const noexcept { + return cbegin(); + } + + /*! @copydoc begin */ + [[nodiscard]] iterator begin() noexcept { + return {std::get(payload).begin()...}; + } + + /** + * @brief Returns an iterator to the end. + * @return An iterator to the element following the last row of the table. + */ + [[nodiscard]] const_iterator cend() const noexcept { + return {std::get(payload).cend()...}; + } + + /*! @copydoc cend */ + [[nodiscard]] const_iterator end() const noexcept { + return cend(); + } + + /*! @copydoc end */ + [[nodiscard]] iterator end() noexcept { + return {std::get(payload).end()...}; + } + + /** + * @brief Returns a reverse iterator to the beginning. + * + * If the table is empty, the returned iterator will be equal to `rend()`. + * + * @return An iterator to the first row of the reversed table. + */ + [[nodiscard]] const_reverse_iterator crbegin() const noexcept { + return {std::get(payload).crbegin()...}; + } + + /*! @copydoc crbegin */ + [[nodiscard]] const_reverse_iterator rbegin() const noexcept { + return crbegin(); + } + + /*! @copydoc rbegin */ + [[nodiscard]] reverse_iterator rbegin() noexcept { + return {std::get(payload).rbegin()...}; + } + + /** + * @brief Returns a reverse iterator to the end. + * @return An iterator to the element following the last row of the reversed + * table. + */ + [[nodiscard]] const_reverse_iterator crend() const noexcept { + return {std::get(payload).crend()...}; + } + + /*! @copydoc crend */ + [[nodiscard]] const_reverse_iterator rend() const noexcept { + return crend(); + } + + /*! @copydoc rend */ + [[nodiscard]] reverse_iterator rend() noexcept { + return {std::get(payload).rend()...}; + } + + /** + * @brief Appends a row to the end of a table. + * @tparam Args Types of arguments to use to construct the row data. + * @param args Parameters to use to construct the row data. + * @return A reference to the newly created row data. + */ + template + std::tuple emplace(Args &&...args) { + if constexpr(sizeof...(Args) == 0u) { + return std::forward_as_tuple(std::get(payload).emplace_back()...); + } else { + return std::forward_as_tuple(std::get(payload).emplace_back(std::forward(args))...); + } + } + + /** + * @brief Removes a row from a table. + * @param pos An iterator to the row to remove. + * @return An iterator following the removed row. + */ + iterator erase(const_iterator pos) { + const auto diff = pos - begin(); + return {std::get(payload).erase(std::get(payload).begin() + diff)...}; + } + + /** + * @brief Removes a row from a table. + * @param pos Index of the row to remove. + */ + void erase(const size_type pos) { + ENTT_ASSERT(pos < size(), "Index out of bounds"); + erase(begin() + static_cast(pos)); + } + + /** + * @brief Returns the row data at specified location. + * @param pos The row for which to return the data. + * @return The row data at specified location. + */ + [[nodiscard]] std::tuple operator[](const size_type pos) const { + ENTT_ASSERT(pos < size(), "Index out of bounds"); + return std::forward_as_tuple(std::get(payload)[pos]...); + } + + /*! @copydoc operator[] */ + [[nodiscard]] std::tuple operator[](const size_type pos) { + ENTT_ASSERT(pos < size(), "Index out of bounds"); + return std::forward_as_tuple(std::get(payload)[pos]...); + } + + /*! @brief Clears a table. */ + void clear() { + (std::get(payload).clear(), ...); + } + +private: + container_type payload; +}; + +} // namespace entt + +/*! @cond TURN_OFF_DOXYGEN */ +namespace std { + +template +struct uses_allocator, Allocator> + : std::bool_constant<(std::uses_allocator_v && ...)> {}; + +} // namespace std +/*! @endcond */ + +#endif + +// #include "core/algorithm.hpp" +#ifndef ENTT_CORE_ALGORITHM_HPP +#define ENTT_CORE_ALGORITHM_HPP + +#include +#include +#include +#include +#include +// #include "utility.hpp" +#ifndef ENTT_CORE_UTILITY_HPP +#define ENTT_CORE_UTILITY_HPP + +#include +#include + +namespace entt { + +/*! @brief Identity function object (waiting for C++20). */ +struct identity { + /*! @brief Indicates that this is a transparent function object. */ + using is_transparent = void; + + /** + * @brief Returns its argument unchanged. + * @tparam Type Type of the argument. + * @param value The actual argument. + * @return The submitted value as-is. + */ + template + [[nodiscard]] constexpr Type &&operator()(Type &&value) const noexcept { + return std::forward(value); + } +}; + +/** + * @brief Constant utility to disambiguate overloaded members of a class. + * @tparam Type Type of the desired overload. + * @tparam Class Type of class to which the member belongs. + * @param member A valid pointer to a member. + * @return Pointer to the member. + */ +template +[[nodiscard]] constexpr auto overload(Type Class::*member) noexcept { + return member; +} + +/** + * @brief Constant utility to disambiguate overloaded functions. + * @tparam Func Function type of the desired overload. + * @param func A valid pointer to a function. + * @return Pointer to the function. + */ +template +[[nodiscard]] constexpr auto overload(Func *func) noexcept { + return func; +} + +/** + * @brief Helper type for visitors. + * @tparam Func Types of function objects. + */ +template +struct overloaded: Func... { + using Func::operator()...; +}; + +/** + * @brief Deduction guide. + * @tparam Func Types of function objects. + */ +template +overloaded(Func...) -> overloaded; + +/** + * @brief Basic implementation of a y-combinator. + * @tparam Func Type of a potentially recursive function. + */ +template +struct y_combinator { + /** + * @brief Constructs a y-combinator from a given function. + * @param recursive A potentially recursive function. + */ + constexpr y_combinator(Func recursive) noexcept(std::is_nothrow_move_constructible_v) + : func{std::move(recursive)} {} + + /** + * @brief Invokes a y-combinator and therefore its underlying function. + * @tparam Args Types of arguments to use to invoke the underlying function. + * @param args Parameters to use to invoke the underlying function. + * @return Return value of the underlying function, if any. + */ + template + constexpr decltype(auto) operator()(Args &&...args) const noexcept(std::is_nothrow_invocable_v) { + return func(*this, std::forward(args)...); + } + + /*! @copydoc operator()() */ + template + constexpr decltype(auto) operator()(Args &&...args) noexcept(std::is_nothrow_invocable_v) { + return func(*this, std::forward(args)...); + } + +private: + Func func; +}; + +} // namespace entt + +#endif + + +namespace entt { + +/** + * @brief Function object to wrap `std::sort` in a class type. + * + * Unfortunately, `std::sort` cannot be passed as template argument to a class + * template or a function template.
+ * This class fills the gap by wrapping some flavors of `std::sort` in a + * function object. + */ +struct std_sort { + /** + * @brief Sorts the elements in a range. + * + * Sorts the elements in a range using the given binary comparison function. + * + * @tparam It Type of random access iterator. + * @tparam Compare Type of comparison function object. + * @tparam Args Types of arguments to forward to the sort function. + * @param first An iterator to the first element of the range to sort. + * @param last An iterator past the last element of the range to sort. + * @param compare A valid comparison function object. + * @param args Arguments to forward to the sort function, if any. + */ + template, typename... Args> + void operator()(It first, It last, Compare compare = Compare{}, Args &&...args) const { + std::sort(std::forward(args)..., std::move(first), std::move(last), std::move(compare)); + } +}; + +/*! @brief Function object for performing insertion sort. */ +struct insertion_sort { + /** + * @brief Sorts the elements in a range. + * + * Sorts the elements in a range using the given binary comparison function. + * + * @tparam It Type of random access iterator. + * @tparam Compare Type of comparison function object. + * @param first An iterator to the first element of the range to sort. + * @param last An iterator past the last element of the range to sort. + * @param compare A valid comparison function object. + */ + template> + void operator()(It first, It last, Compare compare = Compare{}) const { + if(first < last) { + for(auto it = first + 1; it < last; ++it) { + auto value = std::move(*it); + auto pre = it; + + // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic) + for(; pre > first && compare(value, *(pre - 1)); --pre) { + *pre = std::move(*(pre - 1)); + } + // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic) + + *pre = std::move(value); + } + } + } +}; + +/** + * @brief Function object for performing LSD radix sort. + * @tparam Bit Number of bits processed per pass. + * @tparam N Maximum number of bits to sort. + */ +template +struct radix_sort { + static_assert((N % Bit) == 0, "The maximum number of bits to sort must be a multiple of the number of bits processed per pass"); + + /** + * @brief Sorts the elements in a range. + * + * Sorts the elements in a range using the given _getter_ to access the + * actual data to be sorted. + * + * This implementation is inspired by the online book + * [Physically Based Rendering](http://www.pbr-book.org/3ed-2018/Primitives_and_Intersection_Acceleration/Bounding_Volume_Hierarchies.html#RadixSort). + * + * @tparam It Type of random access iterator. + * @tparam Getter Type of _getter_ function object. + * @param first An iterator to the first element of the range to sort. + * @param last An iterator past the last element of the range to sort. + * @param getter A valid _getter_ function object. + */ + template + void operator()(It first, It last, Getter getter = Getter{}) const { + if(first < last) { + constexpr auto passes = N / Bit; + + using value_type = typename std::iterator_traits::value_type; + using difference_type = typename std::iterator_traits::difference_type; + std::vector aux(static_cast(std::distance(first, last))); + + auto part = [getter = std::move(getter)](auto from, auto to, auto out, auto start) { + constexpr auto mask = (1 << Bit) - 1; + constexpr auto buckets = 1 << Bit; + + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays, misc-const-correctness) + std::size_t count[buckets]{}; + + for(auto it = from; it != to; ++it) { + ++count[(getter(*it) >> start) & mask]; + } + + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) + std::size_t index[buckets]{}; + + for(std::size_t pos{}, end = buckets - 1u; pos < end; ++pos) { + index[pos + 1u] = index[pos] + count[pos]; + } + + for(auto it = from; it != to; ++it) { + const auto pos = index[(getter(*it) >> start) & mask]++; + out[static_cast(pos)] = std::move(*it); + } + }; + + for(std::size_t pass = 0; pass < (passes & ~1u); pass += 2) { + part(first, last, aux.begin(), pass * Bit); + part(aux.begin(), aux.end(), first, (pass + 1) * Bit); + } + + if constexpr(passes & 1) { + part(first, last, aux.begin(), (passes - 1) * Bit); + std::move(aux.begin(), aux.end(), first); + } + } + } +}; + +} // namespace entt + +#endif + +// #include "core/any.hpp" +#ifndef ENTT_CORE_ANY_HPP +#define ENTT_CORE_ANY_HPP + +#include +#include +#include +#include +// #include "../config/config.h" +#ifndef ENTT_CONFIG_CONFIG_H +#define ENTT_CONFIG_CONFIG_H + +// #include "version.h" +#ifndef ENTT_CONFIG_VERSION_H +#define ENTT_CONFIG_VERSION_H + +// #include "macro.h" +#ifndef ENTT_CONFIG_MACRO_H +#define ENTT_CONFIG_MACRO_H + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#define ENTT_STR(arg) #arg +#define ENTT_XSTR(arg) ENTT_STR(arg) + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*) + +#define ENTT_VERSION_MAJOR 3 +#define ENTT_VERSION_MINOR 16 +#define ENTT_VERSION_PATCH 0 + +#define ENTT_VERSION \ + ENTT_XSTR(ENTT_VERSION_MAJOR) \ + "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH) + +// NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION) +# define ENTT_CONSTEXPR +# define ENTT_THROW throw +# define ENTT_TRY try +# define ENTT_CATCH catch(...) +#else +# define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20) +# define ENTT_THROW +# define ENTT_TRY if(true) +# define ENTT_CATCH if(false) +#endif + +#if __has_include() +# include +# +# if defined(__cpp_consteval) +# define ENTT_CONSTEVAL consteval +# endif +#endif + +#ifndef ENTT_CONSTEVAL +# define ENTT_CONSTEVAL constexpr +#endif + +#ifdef ENTT_USE_ATOMIC +# include +# define ENTT_MAYBE_ATOMIC(Type) std::atomic +#else +# define ENTT_MAYBE_ATOMIC(Type) Type +#endif + +#ifndef ENTT_ID_TYPE +# include +# define ENTT_ID_TYPE std::uint32_t +#else +# include // provides coverage for types in the std namespace +#endif + +#ifndef ENTT_SPARSE_PAGE +# define ENTT_SPARSE_PAGE 4096 +#endif + +#ifndef ENTT_PACKED_PAGE +# define ENTT_PACKED_PAGE 1024 +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT +# define ENTT_ASSERT(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT +# include +# define ENTT_ASSERT(condition, msg) assert(((condition) && (msg))) +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg) +#endif + +#define ENTT_FAIL(msg) ENTT_ASSERT(false, msg); + +#ifdef ENTT_NO_ETO +# define ENTT_ETO_TYPE(Type) void +#else +# define ENTT_ETO_TYPE(Type) Type +#endif + +#ifdef ENTT_NO_MIXIN +# define ENTT_STORAGE(Mixin, ...) __VA_ARGS__ +#else +# define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__> +#endif + +#ifdef ENTT_STANDARD_CPP +# define ENTT_NONSTD false +#else +# define ENTT_NONSTD true +# if defined __clang__ || defined __GNUC__ +# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ +# define ENTT_PRETTY_FUNCTION_PREFIX '=' +# define ENTT_PRETTY_FUNCTION_SUFFIX ']' +# elif defined _MSC_VER +# define ENTT_PRETTY_FUNCTION __FUNCSIG__ +# define ENTT_PRETTY_FUNCTION_PREFIX '<' +# define ENTT_PRETTY_FUNCTION_SUFFIX '>' +# endif +#endif + +#ifndef ENTT_EXPORT +# if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER +# define ENTT_EXPORT __declspec(dllexport) +# define ENTT_IMPORT __declspec(dllimport) +# define ENTT_HIDDEN +# elif defined __GNUC__ && __GNUC__ >= 4 +# define ENTT_EXPORT __attribute__((visibility("default"))) +# define ENTT_IMPORT __attribute__((visibility("default"))) +# define ENTT_HIDDEN __attribute__((visibility("hidden"))) +# else /* Unsupported compiler */ +# define ENTT_EXPORT +# define ENTT_IMPORT +# define ENTT_HIDDEN +# endif +#endif + +#ifndef ENTT_API +# if defined ENTT_API_EXPORT +# define ENTT_API ENTT_EXPORT +# elif defined ENTT_API_IMPORT +# define ENTT_API ENTT_IMPORT +# else /* No API */ +# define ENTT_API +# endif +#endif + +#if defined _MSC_VER +# pragma detect_mismatch("entt.version", ENTT_VERSION) +# pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY)) +# pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE)) +# pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD)) +#endif + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + +// #include "fwd.hpp" +#ifndef ENTT_CORE_FWD_HPP +#define ENTT_CORE_FWD_HPP + +#include +#include +// #include "../config/config.h" + + +namespace entt { + +/*! @brief Possible modes of an any object. */ +enum class any_policy : std::uint8_t { + /*! @brief Default mode, no element available. */ + empty, + /*! @brief Owning mode, dynamically allocated element. */ + dynamic, + /*! @brief Owning mode, embedded element. */ + embedded, + /*! @brief Aliasing mode, non-const reference. */ + ref, + /*! @brief Const aliasing mode, const reference. */ + cref +}; + +// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) +template +class basic_any; + +/*! @brief Alias declaration for type identifiers. */ +using id_type = ENTT_ID_TYPE; + +/*! @brief Alias declaration for the most common use case. */ +using any = basic_any<>; + +template +class compressed_pair; + +template +class basic_hashed_string; + +/*! @brief Aliases for common character types. */ +using hashed_string = basic_hashed_string; + +/*! @brief Aliases for common character types. */ +using hashed_wstring = basic_hashed_string; + +// NOLINTNEXTLINE(bugprone-forward-declaration-namespace) +struct type_info; + +} // namespace entt + +#endif + +// #include "type_info.hpp" +#ifndef ENTT_CORE_TYPE_INFO_HPP +#define ENTT_CORE_TYPE_INFO_HPP + +#include +#include +#include +// #include "../config/config.h" + +// #include "fwd.hpp" + +// #include "hashed_string.hpp" +#ifndef ENTT_CORE_HASHED_STRING_HPP +#define ENTT_CORE_HASHED_STRING_HPP + +#include +#include +// #include "fwd.hpp" + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct fnv_1a_params; + +template<> +struct fnv_1a_params { + static constexpr auto offset = 2166136261; + static constexpr auto prime = 16777619; +}; + +template<> +struct fnv_1a_params { + static constexpr auto offset = 14695981039346656037ull; + static constexpr auto prime = 1099511628211ull; +}; + +template +struct basic_hashed_string { + using value_type = Char; + using size_type = std::size_t; + using hash_type = id_type; + + const value_type *repr{}; + hash_type hash{fnv_1a_params<>::offset}; + size_type length{}; +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Zero overhead unique identifier. + * + * A hashed string is a compile-time tool that allows users to use + * human-readable identifiers in the codebase while using their numeric + * counterparts at runtime.
+ * Because of that, a hashed string can also be used in constant expressions if + * required. + * + * @warning + * This class doesn't take ownership of user-supplied strings nor does it make a + * copy of them. + * + * @tparam Char Character type. + */ +template +class basic_hashed_string: internal::basic_hashed_string { + using base_type = internal::basic_hashed_string; + using params = internal::fnv_1a_params<>; + + struct const_wrapper { + // non-explicit constructor on purpose + constexpr const_wrapper(const typename base_type::value_type *str) noexcept + : repr{str} {} + + const typename base_type::value_type *repr; + }; + +public: + /*! @brief Character type. */ + using value_type = typename base_type::value_type; + /*! @brief Unsigned integer type. */ + using size_type = typename base_type::size_type; + /*! @brief Unsigned integer type. */ + using hash_type = typename base_type::hash_type; + + /** + * @brief Returns directly the numeric representation of a string view. + * @param str Human-readable identifier. + * @param len Length of the string to hash. + * @return The numeric representation of the string. + */ + [[nodiscard]] static constexpr hash_type value(const value_type *str, const size_type len) noexcept { + return basic_hashed_string{str, len}; + } + + /** + * @brief Returns directly the numeric representation of a string. + * @tparam N Number of characters of the identifier. + * @param str Human-readable identifier. + * @return The numeric representation of the string. + */ + template + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) + [[nodiscard]] static ENTT_CONSTEVAL hash_type value(const value_type (&str)[N]) noexcept { + return basic_hashed_string{str}; + } + + /** + * @brief Returns directly the numeric representation of a string. + * @param wrapper Helps achieving the purpose by relying on overloading. + * @return The numeric representation of the string. + */ + [[nodiscard]] static constexpr hash_type value(const_wrapper wrapper) noexcept { + return basic_hashed_string{wrapper}; + } + + /*! @brief Constructs an empty hashed string. */ + constexpr basic_hashed_string() noexcept + : basic_hashed_string{nullptr, 0u} {} + + /** + * @brief Constructs a hashed string from a string view. + * @param str Human-readable identifier. + * @param len Length of the string to hash. + */ + constexpr basic_hashed_string(const value_type *str, const size_type len) noexcept + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay) + : base_type{str} { + // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic) + for(; base_type::length < len; ++base_type::length) { + base_type::hash = (base_type::hash ^ static_cast(str[base_type::length])) * params::prime; + } + // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic) + } + + /** + * @brief Constructs a hashed string from an array of const characters. + * @tparam N Number of characters of the identifier. + * @param str Human-readable identifier. + */ + template + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) + ENTT_CONSTEVAL basic_hashed_string(const value_type (&str)[N]) noexcept + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay) + : base_type{str} { + for(; str[base_type::length]; ++base_type::length) { + base_type::hash = (base_type::hash ^ static_cast(str[base_type::length])) * params::prime; + } + } + + /** + * @brief Explicit constructor on purpose to avoid constructing a hashed + * string directly from a `const value_type *`. + * + * @warning + * The lifetime of the string is not extended nor is it copied. + * + * @param wrapper Helps achieving the purpose by relying on overloading. + */ + explicit constexpr basic_hashed_string(const_wrapper wrapper) noexcept + : base_type{wrapper.repr} { + // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic) + for(; wrapper.repr[base_type::length]; ++base_type::length) { + base_type::hash = (base_type::hash ^ static_cast(wrapper.repr[base_type::length])) * params::prime; + } + // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic) + } + + /** + * @brief Returns the size of a hashed string. + * @return The size of the hashed string. + */ + [[nodiscard]] constexpr size_type size() const noexcept { + return base_type::length; + } + + /** + * @brief Returns the human-readable representation of a hashed string. + * @return The string used to initialize the hashed string. + */ + [[nodiscard]] constexpr const value_type *data() const noexcept { + return base_type::repr; + } + + /** + * @brief Returns the numeric representation of a hashed string. + * @return The numeric representation of the hashed string. + */ + [[nodiscard]] constexpr hash_type value() const noexcept { + return base_type::hash; + } + + /*! @copydoc data */ + [[nodiscard]] explicit constexpr operator const value_type *() const noexcept { + return data(); + } + + /** + * @brief Returns the numeric representation of a hashed string. + * @return The numeric representation of the hashed string. + */ + [[nodiscard]] constexpr operator hash_type() const noexcept { + return value(); + } +}; + +/** + * @brief Deduction guide. + * @tparam Char Character type. + * @param str Human-readable identifier. + * @param len Length of the string to hash. + */ +template +basic_hashed_string(const Char *str, std::size_t len) -> basic_hashed_string; + +/** + * @brief Deduction guide. + * @tparam Char Character type. + * @tparam N Number of characters of the identifier. + * @param str Human-readable identifier. + */ +template +// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) +basic_hashed_string(const Char (&str)[N]) -> basic_hashed_string; + +/** + * @brief Compares two hashed strings. + * @tparam Char Character type. + * @param lhs A valid hashed string. + * @param rhs A valid hashed string. + * @return True if the two hashed strings are identical, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator==(const basic_hashed_string &lhs, const basic_hashed_string &rhs) noexcept { + return lhs.value() == rhs.value(); +} + +/** + * @brief Compares two hashed strings. + * @tparam Char Character type. + * @param lhs A valid hashed string. + * @param rhs A valid hashed string. + * @return True if the two hashed strings differ, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator!=(const basic_hashed_string &lhs, const basic_hashed_string &rhs) noexcept { + return !(lhs == rhs); +} + +/** + * @brief Compares two hashed strings. + * @tparam Char Character type. + * @param lhs A valid hashed string. + * @param rhs A valid hashed string. + * @return True if the first element is less than the second, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator<(const basic_hashed_string &lhs, const basic_hashed_string &rhs) noexcept { + return lhs.value() < rhs.value(); +} + +/** + * @brief Compares two hashed strings. + * @tparam Char Character type. + * @param lhs A valid hashed string. + * @param rhs A valid hashed string. + * @return True if the first element is less than or equal to the second, false + * otherwise. + */ +template +[[nodiscard]] constexpr bool operator<=(const basic_hashed_string &lhs, const basic_hashed_string &rhs) noexcept { + return !(rhs < lhs); +} + +/** + * @brief Compares two hashed strings. + * @tparam Char Character type. + * @param lhs A valid hashed string. + * @param rhs A valid hashed string. + * @return True if the first element is greater than the second, false + * otherwise. + */ +template +[[nodiscard]] constexpr bool operator>(const basic_hashed_string &lhs, const basic_hashed_string &rhs) noexcept { + return rhs < lhs; +} + +/** + * @brief Compares two hashed strings. + * @tparam Char Character type. + * @param lhs A valid hashed string. + * @param rhs A valid hashed string. + * @return True if the first element is greater than or equal to the second, + * false otherwise. + */ +template +[[nodiscard]] constexpr bool operator>=(const basic_hashed_string &lhs, const basic_hashed_string &rhs) noexcept { + return !(lhs < rhs); +} + +inline namespace literals { + +/** + * @brief User defined literal for hashed strings. + * @param str The literal without its suffix. + * @return A properly initialized hashed string. + */ +[[nodiscard]] ENTT_CONSTEVAL hashed_string operator""_hs(const char *str, std::size_t) noexcept { + return hashed_string{str}; +} + +/** + * @brief User defined literal for hashed wstrings. + * @param str The literal without its suffix. + * @return A properly initialized hashed wstring. + */ +[[nodiscard]] ENTT_CONSTEVAL hashed_wstring operator""_hws(const wchar_t *str, std::size_t) noexcept { + return hashed_wstring{str}; +} + +} // namespace literals + +} // namespace entt + +#endif + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +struct ENTT_API type_index final { + [[nodiscard]] static id_type next() noexcept { + static ENTT_MAYBE_ATOMIC(id_type) value{}; + return value++; + } +}; + +template +[[nodiscard]] constexpr const char *pretty_function() noexcept { +#if defined ENTT_PRETTY_FUNCTION + return static_cast(ENTT_PRETTY_FUNCTION); +#else + return ""; +#endif +} + +template +[[nodiscard]] constexpr auto stripped_type_name() noexcept { +#if defined ENTT_PRETTY_FUNCTION + const std::string_view full_name{pretty_function()}; + auto first = full_name.find_first_not_of(' ', full_name.find_first_of(ENTT_PRETTY_FUNCTION_PREFIX) + 1); + auto value = full_name.substr(first, full_name.find_last_of(ENTT_PRETTY_FUNCTION_SUFFIX) - first); + return value; +#else + return std::string_view{}; +#endif +} + +template().find_first_of('.')> +[[nodiscard]] constexpr std::string_view type_name(int) noexcept { + constexpr auto value = stripped_type_name(); + return value; +} + +template +[[nodiscard]] std::string_view type_name(char) noexcept { + static const auto value = stripped_type_name(); + return value; +} + +template().find_first_of('.')> +[[nodiscard]] constexpr id_type type_hash(int) noexcept { + constexpr auto stripped = stripped_type_name(); + constexpr auto value = hashed_string::value(stripped.data(), stripped.size()); + return value; +} + +template +[[nodiscard]] id_type type_hash(char) noexcept { + static const auto value = [](const auto stripped) { + return hashed_string::value(stripped.data(), stripped.size()); + }(stripped_type_name()); + return value; +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Type sequential identifier. + * @tparam Type Type for which to generate a sequential identifier. + */ +template +struct ENTT_API type_index final { + /** + * @brief Returns the sequential identifier of a given type. + * @return The sequential identifier of a given type. + */ + [[nodiscard]] static id_type value() noexcept { + static const id_type value = internal::type_index::next(); + return value; + } + + /*! @copydoc value */ + [[nodiscard]] constexpr operator id_type() const noexcept { + return value(); + } +}; + +/** + * @brief Type hash. + * @tparam Type Type for which to generate a hash value. + */ +template +struct type_hash final { + /** + * @brief Returns the numeric representation of a given type. + * @return The numeric representation of the given type. + */ +#if defined ENTT_PRETTY_FUNCTION + [[nodiscard]] static constexpr id_type value() noexcept { + return internal::type_hash(0); +#else + [[nodiscard]] static constexpr id_type value() noexcept { + return type_index::value(); +#endif + } + + /*! @copydoc value */ + [[nodiscard]] constexpr operator id_type() const noexcept { + return value(); + } +}; + +/** + * @brief Type name. + * @tparam Type Type for which to generate a name. + */ +template +struct type_name final { + /** + * @brief Returns the name of a given type. + * @return The name of the given type. + */ + [[nodiscard]] static constexpr std::string_view value() noexcept { + return internal::type_name(0); + } + + /*! @copydoc value */ + [[nodiscard]] constexpr operator std::string_view() const noexcept { + return value(); + } +}; + +/*! @brief Implementation specific information about a type. */ +struct type_info final { + /** + * @brief Constructs a type info object for a given type. + * @tparam Type Type for which to construct a type info object. + */ + template + // NOLINTBEGIN(modernize-use-transparent-functors) + constexpr type_info(std::in_place_type_t) noexcept + : seq{type_index>>::value()}, + identifier{type_hash>>::value()}, + alias{type_name>>::value()} {} + // NOLINTEND(modernize-use-transparent-functors) + + /** + * @brief Type index. + * @return Type index. + */ + [[nodiscard]] constexpr id_type index() const noexcept { + return seq; + } + + /** + * @brief Type hash. + * @return Type hash. + */ + [[nodiscard]] constexpr id_type hash() const noexcept { + return identifier; + } + + /** + * @brief Type name. + * @return Type name. + */ + [[nodiscard]] constexpr std::string_view name() const noexcept { + return alias; + } + +private: + id_type seq; + id_type identifier; + std::string_view alias; +}; + +/** + * @brief Compares the contents of two type info objects. + * @param lhs A type info object. + * @param rhs A type info object. + * @return True if the two type info objects are identical, false otherwise. + */ +[[nodiscard]] constexpr bool operator==(const type_info &lhs, const type_info &rhs) noexcept { + return lhs.hash() == rhs.hash(); +} + +/** + * @brief Compares the contents of two type info objects. + * @param lhs A type info object. + * @param rhs A type info object. + * @return True if the two type info objects differ, false otherwise. + */ +[[nodiscard]] constexpr bool operator!=(const type_info &lhs, const type_info &rhs) noexcept { + return !(lhs == rhs); +} + +/** + * @brief Compares two type info objects. + * @param lhs A valid type info object. + * @param rhs A valid type info object. + * @return True if the first element is less than the second, false otherwise. + */ +[[nodiscard]] constexpr bool operator<(const type_info &lhs, const type_info &rhs) noexcept { + return lhs.index() < rhs.index(); +} + +/** + * @brief Compares two type info objects. + * @param lhs A valid type info object. + * @param rhs A valid type info object. + * @return True if the first element is less than or equal to the second, false + * otherwise. + */ +[[nodiscard]] constexpr bool operator<=(const type_info &lhs, const type_info &rhs) noexcept { + return !(rhs < lhs); +} + +/** + * @brief Compares two type info objects. + * @param lhs A valid type info object. + * @param rhs A valid type info object. + * @return True if the first element is greater than the second, false + * otherwise. + */ +[[nodiscard]] constexpr bool operator>(const type_info &lhs, const type_info &rhs) noexcept { + return rhs < lhs; +} + +/** + * @brief Compares two type info objects. + * @param lhs A valid type info object. + * @param rhs A valid type info object. + * @return True if the first element is greater than or equal to the second, + * false otherwise. + */ +[[nodiscard]] constexpr bool operator>=(const type_info &lhs, const type_info &rhs) noexcept { + return !(lhs < rhs); +} + +/** + * @brief Returns the type info object associated to a given type. + * + * The returned element refers to an object with static storage duration.
+ * The type doesn't need to be a complete type. If the type is a reference, the + * result refers to the referenced type. In all cases, top-level cv-qualifiers + * are ignored. + * + * @tparam Type Type for which to generate a type info object. + * @return A reference to a properly initialized type info object. + */ +template +[[nodiscard]] const type_info &type_id() noexcept { + if constexpr(std::is_same_v>>) { + static const type_info instance{std::in_place_type}; + return instance; + } else { + return type_id>>(); + } +} + +/*! @copydoc type_id */ +template +// NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward) +[[nodiscard]] const type_info &type_id(Type &&) noexcept { + return type_id>>(); +} + +} // namespace entt + +#endif + +// #include "type_traits.hpp" +#ifndef ENTT_CORE_TYPE_TRAITS_HPP +#define ENTT_CORE_TYPE_TRAITS_HPP + +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "fwd.hpp" + + +namespace entt { + +/** + * @brief Utility class to disambiguate overloaded functions. + * @tparam N Number of choices available. + */ +template +struct choice_t + // unfortunately, doxygen cannot parse such a construct + : /*! @cond TURN_OFF_DOXYGEN */ choice_t /*! @endcond */ +{}; + +/*! @copybrief choice_t */ +template<> +struct choice_t<0> {}; + +/** + * @brief Variable template for the choice trick. + * @tparam N Number of choices available. + */ +template +inline constexpr choice_t choice{}; + +/** + * @brief Identity type trait. + * + * Useful to establish non-deduced contexts in template argument deduction + * (waiting for C++20) or to provide types through function arguments. + * + * @tparam Type A type. + */ +template +struct type_identity { + /*! @brief Identity type. */ + using type = Type; +}; + +/** + * @brief Helper type. + * @tparam Type A type. + */ +template +using type_identity_t = typename type_identity::type; + +/** + * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains. + * @tparam Type The type of which to return the size. + */ +template +struct size_of: std::integral_constant {}; + +/*! @copydoc size_of */ +template +struct size_of> + // NOLINTNEXTLINE(bugprone-sizeof-expression) + : std::integral_constant {}; + +/** + * @brief Helper variable template. + * @tparam Type The type of which to return the size. + */ +template +inline constexpr std::size_t size_of_v = size_of::value; + +/** + * @brief Using declaration to be used to _repeat_ the same type a number of + * times equal to the size of a given parameter pack. + * @tparam Type A type to repeat. + */ +template +using unpack_as_type = Type; + +/** + * @brief Helper variable template to be used to _repeat_ the same value a + * number of times equal to the size of a given parameter pack. + * @tparam Value A value to repeat. + */ +template +inline constexpr auto unpack_as_value = Value; + +/** + * @brief Wraps a static constant. + * @tparam Value A static constant. + */ +template +using integral_constant = std::integral_constant; + +/** + * @brief Alias template to facilitate the creation of named values. + * @tparam Value A constant value at least convertible to `id_type`. + */ +template +using tag = integral_constant; + +/** + * @brief A class to use to push around lists of types, nothing more. + * @tparam Type Types provided by the type list. + */ +template +struct type_list { + /*! @brief Type list type. */ + using type = type_list; + /*! @brief Compile-time number of elements in the type list. */ + static constexpr auto size = sizeof...(Type); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_element; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Index Index of the type to return. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element> + : type_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element<0u, type_list> { + /*! @brief Searched type. */ + using type = First; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Type list to search into. + */ +template +using type_list_element_t = typename type_list_element::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_index; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 1u + type_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + static_assert(type_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +inline constexpr std::size_t type_list_index_v = type_list_index::value; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @return A type list composed by the types of both the type lists. + */ +template +constexpr type_list operator+(type_list, type_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_cat; + +/*! @brief Concatenates multiple type lists. */ +template<> +struct type_list_cat<> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list<>; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @tparam List Other type lists, if any. + */ +template +struct type_list_cat, type_list, List...> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = typename type_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the type list. + */ +template +struct type_list_cat> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list; +}; + +/** + * @brief Helper type. + * @tparam List Type lists to concatenate. + */ +template +using type_list_cat_t = typename type_list_cat::type; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct type_list_unique; + +template +struct type_list_unique, Type...> + : std::conditional_t<(std::is_same_v || ...), type_list_unique, Type...>, type_list_unique, Type..., First>> {}; + +template +struct type_list_unique, Type...> { + using type = type_list; +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Removes duplicates types from a type list. + * @tparam List Type list. + */ +template +struct type_list_unique { + /*! @brief A type list without duplicate types. */ + using type = typename internal::type_list_unique::type; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + */ +template +using type_list_unique_t = typename type_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a type list contains a + * given type, false otherwise. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +struct type_list_contains; + +/** + * @copybrief type_list_contains + * @tparam Type Types provided by the type list. + * @tparam Other Type to look for. + */ +template +struct type_list_contains, Other> + : std::bool_constant<(std::is_same_v || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +inline constexpr bool type_list_contains_v = type_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_diff; + +/** + * @brief Computes the difference between two type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + */ +template +struct type_list_diff, type_list> { + /*! @brief A type list that is the difference between the two type lists. */ + using type = type_list_cat_t, Type>, type_list<>, type_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Type lists between which to compute the difference. + */ +template +using type_list_diff_t = typename type_list_diff::type; + +/*! @brief Primary template isn't defined on purpose. */ +template class> +struct type_list_transform; + +/** + * @brief Applies a given _function_ to a type list and generate a new list. + * @tparam Type Types provided by the type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +struct type_list_transform, Op> { + /*! @brief Resulting type list after applying the transform function. */ + // NOLINTNEXTLINE(modernize-type-traits) + using type = type_list::type...>; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +using type_list_transform_t = typename type_list_transform::type; + +/** + * @brief A class to use to push around lists of constant values, nothing more. + * @tparam Value Values provided by the value list. + */ +template +struct value_list { + /*! @brief Value list type. */ + using type = value_list; + /*! @brief Compile-time number of elements in the value list. */ + static constexpr auto size = sizeof...(Value); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_element; + +/** + * @brief Provides compile-time indexed access to the values of a value list. + * @tparam Index Index of the value to return. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element> + : value_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element<0u, value_list> { + /*! @brief Searched type. */ + using type = decltype(Value); + /*! @brief Searched value. */ + static constexpr auto value = Value; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Value list to search into. + */ +template +using value_list_element_t = typename value_list_element::type; + +/** + * @brief Helper type. + * @tparam Index Index of the value to return. + * @tparam List Value list to search into. + */ +template +inline constexpr auto value_list_element_v = value_list_element::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_index; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam First First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 1u + value_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + static_assert(value_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +inline constexpr std::size_t value_list_index_v = value_list_index::value; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @return A value list composed by the values of both the value lists. + */ +template +constexpr value_list operator+(value_list, value_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_cat; + +/*! @brief Concatenates multiple value lists. */ +template<> +struct value_list_cat<> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list<>; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @tparam List Other value lists, if any. + */ +template +struct value_list_cat, value_list, List...> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = typename value_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the value list. + */ +template +struct value_list_cat> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list; +}; + +/** + * @brief Helper type. + * @tparam List Value lists to concatenate. + */ +template +using value_list_cat_t = typename value_list_cat::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_unique; + +/** + * @brief Removes duplicates values from a value list. + * @tparam Value One of the values provided by the given value list. + * @tparam Other The other values provided by the given value list. + */ +template +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = std::conditional_t< + ((Value == Other) || ...), + typename value_list_unique>::type, + value_list_cat_t, typename value_list_unique>::type>>; +}; + +/*! @brief Removes duplicates values from a value list. */ +template<> +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = value_list<>; +}; + +/** + * @brief Helper type. + * @tparam Type A value list. + */ +template +using value_list_unique_t = typename value_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a value list contains + * a given value, false otherwise. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +struct value_list_contains; + +/** + * @copybrief value_list_contains + * @tparam Value Values provided by the value list. + * @tparam Other Value to look for. + */ +template +struct value_list_contains, Other> + : std::bool_constant<((Value == Other) || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +inline constexpr bool value_list_contains_v = value_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_diff; + +/** + * @brief Computes the difference between two value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + */ +template +struct value_list_diff, value_list> { + /*! @brief A value list that is the difference between the two value lists. */ + using type = value_list_cat_t, Value>, value_list<>, value_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Value lists between which to compute the difference. + */ +template +using value_list_diff_t = typename value_list_diff::type; + +/*! @brief Same as std::is_invocable, but with tuples. */ +template +struct is_applicable: std::false_type {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @brief Helper variable template. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_v = is_applicable::value; + +/*! @brief Same as std::is_invocable_r, but with tuples for arguments. */ +template +struct is_applicable_r: std::false_type {}; + +/** + * @copybrief is_applicable_r + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +struct is_applicable_r>: std::is_invocable_r {}; + +/** + * @brief Helper variable template. + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_r_v = is_applicable_r::value; + +/** + * @brief Provides the member constant `value` to true if a given type is + * complete, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_complete: std::false_type {}; + +/*! @copydoc is_complete */ +template +struct is_complete>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_complete_v = is_complete::value; + +/** + * @brief Provides the member constant `value` to true if a given type is an + * iterator, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_iterator: std::false_type {}; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_iterator_category: std::false_type {}; + +template +struct has_iterator_category::iterator_category>>: std::true_type {}; + +} // namespace internal +/*! @endcond */ + +/*! @copydoc is_iterator */ +template +struct is_iterator>>>> + : internal::has_iterator_category {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_iterator_v = is_iterator::value; + +/** + * @brief Provides the member constant `value` to true if a given type is both + * an empty and non-final class, false otherwise. + * @tparam Type The type to test + */ +template +struct is_ebco_eligible + : std::bool_constant && !std::is_final_v> {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_ebco_eligible_v = is_ebco_eligible::value; + +/** + * @brief Provides the member constant `value` to true if `Type::is_transparent` + * is valid and denotes a type, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_transparent: std::false_type {}; + +/*! @copydoc is_transparent */ +template +struct is_transparent>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_transparent_v = is_transparent::value; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_tuple_size_value: std::false_type {}; + +template +struct has_tuple_size_value::value)>>: std::true_type {}; + +template +struct has_value_type: std::false_type {}; + +template +struct has_value_type>: std::true_type {}; + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable(); + +template +[[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence) { + return (dispatch_is_equality_comparable>() && ...); +} + +template +[[nodiscard]] constexpr bool maybe_equality_comparable(char) { + return false; +} + +template +[[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval() == std::declval()) { + return true; +} + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable() { + // NOLINTBEGIN(modernize-use-transparent-functors) + if constexpr(std::is_array_v) { + return false; + } else if constexpr(is_complete_v>>) { + if constexpr(has_tuple_size_value::value) { + return maybe_equality_comparable(0) && unpack_maybe_equality_comparable(std::make_index_sequence::value>{}); + } else { + return maybe_equality_comparable(0); + } + } else if constexpr(has_value_type::value) { + if constexpr(is_iterator_v || std::is_same_v || dispatch_is_equality_comparable()) { + return maybe_equality_comparable(0); + } else { + return false; + } + } else { + return maybe_equality_comparable(0); + } + // NOLINTEND(modernize-use-transparent-functors) +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Provides the member constant `value` to true if a given type is + * equality comparable, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_equality_comparable: std::bool_constant()> {}; + +/*! @copydoc is_equality_comparable */ +template +struct is_equality_comparable: is_equality_comparable {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_equality_comparable_v = is_equality_comparable::value; + +/** + * @brief Transcribes the constness of a type to another type. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = std::remove_const_t; +}; + +/*! @copydoc constness_as */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = const To; +}; + +/** + * @brief Alias template to facilitate the transcription of the constness. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +using constness_as_t = typename constness_as::type; + +/** + * @brief Extracts the class of a non-static member object or function. + * @tparam Member A pointer to a non-static member object or function. + */ +template +class member_class { + static_assert(std::is_member_pointer_v, "Invalid pointer type to non-static member object or function"); + + template + static Class *clazz(Ret (Class::*)(Args...)); + + template + static Class *clazz(Ret (Class::*)(Args...) const); + + template + static Class *clazz(Type Class::*); + +public: + /*! @brief The class of the given non-static member object or function. */ + using type = std::remove_pointer_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Member A pointer to a non-static member object or function. + */ +template +using member_class_t = typename member_class::type; + +/** + * @brief Extracts the n-th argument of a _callable_ type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid _callable_ type. + */ +template +class nth_argument { + template + static constexpr type_list pick_up(Ret (*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...) const); + + template + static constexpr type_list pick_up(Type Class ::*); + + template + static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&); + +public: + /*! @brief N-th argument of the _callable_ type. */ + using type = type_list_element_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid function, member function or data member type. + */ +template +using nth_argument_t = typename nth_argument::type; + +} // namespace entt + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::type_list_element> {}; + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::value_list_element> {}; + +#endif + +// #include "utility.hpp" + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +enum class any_request : std::uint8_t { + info, + transfer, + assign, + compare, + copy, + move +}; + +template +struct basic_any_storage { + static constexpr bool has_buffer = true; + union { + const void *instance{}; + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) + alignas(Align) std::byte buffer[Len]; + }; +}; + +template +struct basic_any_storage<0u, Align> { + static constexpr bool has_buffer = false; + const void *instance{}; +}; + +template +// NOLINTNEXTLINE(bugprone-sizeof-expression) +struct in_situ: std::bool_constant<(Len != 0u) && alignof(Type) <= Align && sizeof(Type) <= Len && std::is_nothrow_move_constructible_v> {}; + +template +struct in_situ: std::false_type {}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief A SBO friendly, type-safe container for single values of any type. + * @tparam Len Size of the buffer reserved for the small buffer optimization. + * @tparam Align Optional alignment requirement. + */ +template +class basic_any: private internal::basic_any_storage { + using request = internal::any_request; + using base_type = internal::basic_any_storage; + using vtable_type = const void *(const request, const basic_any &, const void *); + using deleter_type = void(const basic_any &); + + template + static constexpr bool in_situ_v = internal::in_situ::value; + + template + static const void *basic_vtable(const request req, const basic_any &value, const void *other) { + static_assert(std::is_same_v>, Type>, "Invalid type"); + + switch(const auto *elem = static_cast(value.data()); req) { + case request::info: + return &type_id(); + case request::transfer: + if constexpr(std::is_move_assignable_v) { + // NOLINTNEXTLINE(bugprone-casting-through-void) + *const_cast(elem) = std::move(*static_cast(const_cast(other))); + return other; + } + [[fallthrough]]; + case request::assign: + if constexpr(std::is_copy_assignable_v) { + *const_cast(elem) = *static_cast(other); + return other; + } + break; + case request::compare: + if constexpr(!std::is_function_v && !std::is_array_v && is_equality_comparable_v) { + return (*elem == *static_cast(other)) ? other : nullptr; + } else { + return (elem == other) ? other : nullptr; + } + case request::copy: + if constexpr(std::is_copy_constructible_v) { + // NOLINTNEXTLINE(bugprone-casting-through-void) + static_cast(const_cast(other))->initialize(*elem); + } + break; + case request::move: + ENTT_ASSERT(value.mode == any_policy::embedded, "Unexpected policy"); + if constexpr(in_situ_v) { + // NOLINTNEXTLINE(bugprone-casting-through-void, bugprone-multi-level-implicit-pointer-conversion) + return ::new(&static_cast(const_cast(other))->buffer) Type{std::move(*const_cast(elem))}; + } + } + + return nullptr; + } + + template + static void basic_deleter(const basic_any &value) { + static_assert(std::is_same_v>, Type>, "Invalid type"); + ENTT_ASSERT((value.mode == any_policy::dynamic) || ((value.mode == any_policy::embedded) && !std::is_trivially_destructible_v), "Unexpected policy"); + + const auto *elem = static_cast(value.data()); + + if constexpr(in_situ_v) { + (value.mode == any_policy::embedded) ? elem->~Type() : (delete elem); + } else if constexpr(std::is_array_v) { + delete[] elem; + } else { + delete elem; + } + } + + template + void initialize([[maybe_unused]] Args &&...args) { + using plain_type = std::remove_const_t>; + + vtable = basic_vtable; + underlying_type = type_hash::value(); + + if constexpr(std::is_void_v) { + deleter = nullptr; + mode = any_policy::empty; + this->instance = nullptr; + } else if constexpr(std::is_lvalue_reference_v) { + deleter = nullptr; + mode = std::is_const_v> ? any_policy::cref : any_policy::ref; + static_assert((std::is_lvalue_reference_v && ...) && (sizeof...(Args) == 1u), "Invalid arguments"); + // NOLINTNEXTLINE(bugprone-multi-level-implicit-pointer-conversion) + this->instance = (std::addressof(args), ...); + } else if constexpr(in_situ_v) { + if constexpr(std::is_trivially_destructible_v) { + deleter = nullptr; + } else { + deleter = &basic_deleter; + } + + mode = any_policy::embedded; + + if constexpr(std::is_aggregate_v && (sizeof...(Args) != 0u || !std::is_default_constructible_v)) { + ::new(&this->buffer) plain_type{std::forward(args)...}; + } else { + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay) + ::new(&this->buffer) plain_type(std::forward(args)...); + } + } else { + deleter = &basic_deleter; + mode = any_policy::dynamic; + + if constexpr(std::is_aggregate_v && (sizeof...(Args) != 0u || !std::is_default_constructible_v)) { + this->instance = new plain_type{std::forward(args)...}; + } else if constexpr(std::is_array_v) { + static_assert(sizeof...(Args) == 0u, "Invalid arguments"); + this->instance = new plain_type[std::extent_v](); + } else { + this->instance = new plain_type(std::forward(args)...); + } + } + } + + void invoke_deleter_if_exists() { + if(deleter != nullptr) { + deleter(*this); + } + } + +public: + /*! @brief Size of the internal buffer. */ + static constexpr auto length = Len; + /*! @brief Alignment requirement. */ + static constexpr auto alignment = Align; + + /*! @brief Default constructor. */ + constexpr basic_any() noexcept + : basic_any{std::in_place_type} {} + + /** + * @brief Constructs a wrapper by directly initializing the new object. + * @tparam Type Type of object to use to initialize the wrapper. + * @tparam Args Types of arguments to use to construct the new instance. + * @param args Parameters to use to construct the instance. + */ + template + explicit basic_any(std::in_place_type_t, Args &&...args) + : base_type{} { + initialize(std::forward(args)...); + } + + /** + * @brief Constructs a wrapper taking ownership of the passed object. + * @tparam Type Type of object to use to initialize the wrapper. + * @param value A pointer to an object to take ownership of. + */ + template + explicit basic_any(std::in_place_t, Type *value) + : base_type{} { + static_assert(!std::is_const_v && !std::is_void_v, "Non-const non-void pointer required"); + + if(value == nullptr) { + initialize(); + } else { + initialize(*value); + deleter = &basic_deleter; + mode = any_policy::dynamic; + } + } + + /** + * @brief Constructs a wrapper from a given value. + * @tparam Type Type of object to use to initialize the wrapper. + * @param value An instance of an object to use to initialize the wrapper. + */ + template, basic_any>>> + basic_any(Type &&value) + : basic_any{std::in_place_type>, std::forward(value)} {} + + /** + * @brief Copy constructor. + * @param other The instance to copy from. + */ + basic_any(const basic_any &other) + : basic_any{} { + other.vtable(request::copy, other, this); + } + + /** + * @brief Move constructor. + * @param other The instance to move from. + */ + basic_any(basic_any &&other) noexcept + : base_type{}, + vtable{other.vtable}, + deleter{other.deleter}, + underlying_type{other.underlying_type}, + mode{other.mode} { + if(other.mode == any_policy::embedded) { + other.vtable(request::move, other, this); + } else if(other.mode != any_policy::empty) { + this->instance = std::exchange(other.instance, nullptr); + } + } + + /*! @brief Frees the internal buffer, whatever it means. */ + ~basic_any() { + invoke_deleter_if_exists(); + } + + /** + * @brief Copy assignment operator. + * @param other The instance to copy from. + * @return This any object. + */ + basic_any &operator=(const basic_any &other) { + if(this != &other) { + invoke_deleter_if_exists(); + + if(other) { + other.vtable(request::copy, other, this); + } else { + initialize(); + } + } + + return *this; + } + + /** + * @brief Move assignment operator. + * @param other The instance to move from. + * @return This any object. + */ + basic_any &operator=(basic_any &&other) noexcept { + if(this != &other) { + invoke_deleter_if_exists(); + + if(other.mode == any_policy::embedded) { + other.vtable(request::move, other, this); + } else if(other.mode != any_policy::empty) { + this->instance = std::exchange(other.instance, nullptr); + } + + vtable = other.vtable; + deleter = other.deleter; + underlying_type = other.underlying_type; + mode = other.mode; + } + + return *this; + } + + /** + * @brief Value assignment operator. + * @tparam Type Type of object to use to initialize the wrapper. + * @param value An instance of an object to use to initialize the wrapper. + * @return This any object. + */ + template, basic_any>>> + basic_any &operator=(Type &&value) { + emplace>(std::forward(value)); + return *this; + } + + /** + * @brief Returns false if a wrapper is empty, true otherwise. + * @return False if the wrapper is empty, true otherwise. + */ + [[nodiscard]] bool has_value() const noexcept { + return (mode != any_policy::empty); + } + + /** + * @brief Returns false if the wrapper does not contain the expected type, + * true otherwise. + * @param req Expected type. + * @return False if the wrapper does not contain the expected type, true + * otherwise. + */ + [[nodiscard]] bool has_value(const type_info &req) const noexcept { + return (underlying_type == req.hash()); + } + + /** + * @brief Returns false if the wrapper does not contain the expected type, + * true otherwise. + * @tparam Type Expected type. + * @return False if the wrapper does not contain the expected type, true + * otherwise. + */ + template + [[nodiscard]] bool has_value() const noexcept { + static_assert(std::is_same_v, Type>, "Invalid type"); + return (underlying_type == type_hash::value()); + } + + /** + * @brief Returns the object type info if any, `type_id()` otherwise. + * @return The object type info if any, `type_id()` otherwise. + */ + [[nodiscard]] const type_info &info() const noexcept { + return *static_cast(vtable(request::info, *this, nullptr)); + } + + /*! @copydoc info */ + [[deprecated("use ::info instead")]] [[nodiscard]] const type_info &type() const noexcept { + return info(); + } + + /** + * @brief Returns an opaque pointer to the contained instance. + * @return An opaque pointer the contained instance, if any. + */ + [[nodiscard]] const void *data() const noexcept { + if constexpr(base_type::has_buffer) { + return (mode == any_policy::embedded) ? &this->buffer : this->instance; + } else { + return this->instance; + } + } + + /** + * @brief Returns an opaque pointer to the contained instance. + * @param req Expected type. + * @return An opaque pointer the contained instance, if any. + */ + [[nodiscard]] const void *data(const type_info &req) const noexcept { + return has_value(req) ? data() : nullptr; + } + + /** + * @brief Returns an opaque pointer to the contained instance. + * @tparam Type Expected type. + * @return An opaque pointer the contained instance, if any. + */ + template + [[nodiscard]] const Type *data() const noexcept { + return has_value>() ? static_cast(data()) : nullptr; + } + + /** + * @brief Returns an opaque pointer to the contained instance. + * @return An opaque pointer the contained instance, if any. + */ + [[nodiscard]] void *data() noexcept { + return (mode == any_policy::cref) ? nullptr : const_cast(std::as_const(*this).data()); + } + + /** + * @brief Returns an opaque pointer to the contained instance. + * @param req Expected type. + * @return An opaque pointer the contained instance, if any. + */ + [[nodiscard]] void *data(const type_info &req) noexcept { + return (mode == any_policy::cref) ? nullptr : const_cast(std::as_const(*this).data(req)); + } + + /** + * @brief Returns an opaque pointer to the contained instance. + * @tparam Type Expected type. + * @return An opaque pointer the contained instance, if any. + */ + template + [[nodiscard]] Type *data() noexcept { + if constexpr(std::is_const_v) { + return std::as_const(*this).template data>(); + } else { + return (mode == any_policy::cref) ? nullptr : const_cast(std::as_const(*this).template data>()); + } + } + + /** + * @brief Replaces the contained object by creating a new instance directly. + * @tparam Type Type of object to use to initialize the wrapper. + * @tparam Args Types of arguments to use to construct the new instance. + * @param args Parameters to use to construct the instance. + */ + template + void emplace(Args &&...args) { + invoke_deleter_if_exists(); + initialize(std::forward(args)...); + } + + /** + * @brief Assigns a value to the contained object without replacing it. + * @param other The value to assign to the contained object. + * @return True in case of success, false otherwise. + */ + bool assign(const basic_any &other) { + if(other && (mode != any_policy::cref) && (underlying_type == other.underlying_type)) { + return (vtable(request::assign, *this, other.data()) != nullptr); + } + + return false; + } + + /*! @copydoc assign */ + // NOLINTNEXTLINE(cppcoreguidelines-rvalue-reference-param-not-moved) + bool assign(basic_any &&other) { + if(other && (mode != any_policy::cref) && (underlying_type == other.underlying_type)) { + return (other.mode == any_policy::cref) ? (vtable(request::assign, *this, std::as_const(other).data()) != nullptr) : (vtable(request::transfer, *this, other.data()) != nullptr); + } + + return false; + } + + /*! @brief Destroys contained object */ + void reset() { + invoke_deleter_if_exists(); + initialize(); + } + + /** + * @brief Returns false if a wrapper is empty, true otherwise. + * @return False if the wrapper is empty, true otherwise. + */ + [[nodiscard]] explicit operator bool() const noexcept { + return has_value(); + } + + /** + * @brief Checks if two wrappers differ in their content. + * @param other Wrapper with which to compare. + * @return False if the two objects differ in their content, true otherwise. + */ + [[nodiscard]] bool operator==(const basic_any &other) const noexcept { + if(other && (underlying_type == other.underlying_type)) { + return (vtable(request::compare, *this, other.data()) != nullptr); + } + + return (!*this && !other); + } + + /** + * @brief Checks if two wrappers differ in their content. + * @param other Wrapper with which to compare. + * @return True if the two objects differ in their content, false otherwise. + */ + [[nodiscard]] bool operator!=(const basic_any &other) const noexcept { + return !(*this == other); + } + + /** + * @brief Aliasing constructor. + * @return A wrapper that shares a reference to an unmanaged object. + */ + [[nodiscard]] basic_any as_ref() noexcept { + basic_any other = std::as_const(*this).as_ref(); + other.mode = (mode == any_policy::cref ? any_policy::cref : any_policy::ref); + return other; + } + + /*! @copydoc as_ref */ + [[nodiscard]] basic_any as_ref() const noexcept { + basic_any other{}; + other.instance = data(); + other.vtable = vtable; + other.underlying_type = underlying_type; + other.mode = any_policy::cref; + return other; + } + + /** + * @brief Returns true if a wrapper owns its object, false otherwise. + * @return True if the wrapper owns its object, false otherwise. + */ + [[nodiscard]] bool owner() const noexcept { + return (mode == any_policy::dynamic || mode == any_policy::embedded); + } + + /** + * @brief Returns the current mode of an any object. + * @return The current mode of the any object. + */ + [[nodiscard]] any_policy policy() const noexcept { + return mode; + } + +private: + vtable_type *vtable{}; + deleter_type *deleter{}; + id_type underlying_type{}; + any_policy mode{}; +}; + +/** + * @brief Performs type-safe access to the contained object. + * @tparam Type Type to which conversion is required. + * @tparam Len Size of the buffer reserved for the small buffer optimization. + * @tparam Align Alignment requirement. + * @param data Target any object. + * @return The element converted to the requested type. + */ +template +[[nodiscard]] std::remove_const_t any_cast(const basic_any &data) noexcept { + const auto *const instance = any_cast>(&data); + ENTT_ASSERT(instance, "Invalid instance"); + return static_cast(*instance); +} + +/*! @copydoc any_cast */ +template +[[nodiscard]] std::remove_const_t any_cast(basic_any &data) noexcept { + // forces const on non-reference types to make them work also with wrappers for const references + auto *const instance = any_cast>(&data); + ENTT_ASSERT(instance, "Invalid instance"); + return static_cast(*instance); +} + +/*! @copydoc any_cast */ +template +// NOLINTNEXTLINE(cppcoreguidelines-rvalue-reference-param-not-moved) +[[nodiscard]] std::remove_const_t any_cast(basic_any &&data) noexcept { + if constexpr(std::is_copy_constructible_v>>) { + if(auto *const instance = any_cast>(&data); instance) { + return static_cast(std::move(*instance)); + } + + return any_cast(data); + } else { + auto *const instance = any_cast>(&data); + ENTT_ASSERT(instance, "Invalid instance"); + return static_cast(std::move(*instance)); + } +} + +/*! @copydoc any_cast */ +template +[[nodiscard]] const Type *any_cast(const basic_any *data) noexcept { + return data->template data>(); +} + +/*! @copydoc any_cast */ +template +[[nodiscard]] Type *any_cast(basic_any *data) noexcept { + if constexpr(std::is_const_v) { + // last attempt to make wrappers for const references return their values + return any_cast(&std::as_const(*data)); + } else { + return data->template data(); + } +} + +/** + * @brief Constructs a wrapper from a given type, passing it all arguments. + * @tparam Type Type of object to use to initialize the wrapper. + * @tparam Len Size of the buffer reserved for the small buffer optimization. + * @tparam Align Optional alignment requirement. + * @tparam Args Types of arguments to use to construct the new instance. + * @param args Parameters to use to construct the instance. + * @return A properly initialized wrapper for an object of the given type. + */ +template::length, std::size_t Align = basic_any::alignment, typename... Args> +[[nodiscard]] basic_any make_any(Args &&...args) { + return basic_any{std::in_place_type, std::forward(args)...}; +} + +/** + * @brief Forwards its argument and avoids copies for lvalue references. + * @tparam Len Size of the buffer reserved for the small buffer optimization. + * @tparam Align Optional alignment requirement. + * @tparam Type Type of argument to use to construct the new instance. + * @param value Parameter to use to construct the instance. + * @return A properly initialized and not necessarily owning wrapper. + */ +template::length, std::size_t Align = basic_any::alignment, typename Type> +[[nodiscard]] basic_any forward_as_any(Type &&value) { + return basic_any{std::in_place_type, std::forward(value)}; +} + +} // namespace entt + +#endif + +// #include "core/bit.hpp" +#ifndef ENTT_CORE_BIT_HPP +#define ENTT_CORE_BIT_HPP + +#include +#include +#include +// #include "../config/config.h" + + +namespace entt { + +/** + * @brief Returns the number of set bits in a value (waiting for C++20 and + * `std::popcount`). + * @tparam Type Unsigned integer type. + * @param value A value of unsigned integer type. + * @return The number of set bits in the value. + */ +template +[[nodiscard]] constexpr std::enable_if_t, int> popcount(const Type value) noexcept { + return value ? (int(value & 1) + popcount(static_cast(value >> 1))) : 0; +} + +/** + * @brief Checks whether a value is a power of two or not (waiting for C++20 and + * `std::has_single_bit`). + * @tparam Type Unsigned integer type. + * @param value A value of unsigned integer type. + * @return True if the value is a power of two, false otherwise. + */ +template +[[nodiscard]] constexpr std::enable_if_t, bool> has_single_bit(const Type value) noexcept { + return value && ((value & (value - 1)) == 0); +} + +/** + * @brief Computes the smallest power of two greater than or equal to a value + * (waiting for C++20 and `std::bit_ceil`). + * @tparam Type Unsigned integer type. + * @param value A value of unsigned integer type. + * @return The smallest power of two greater than or equal to the given value. + */ +template +[[nodiscard]] constexpr std::enable_if_t, Type> next_power_of_two(const Type value) noexcept { + // NOLINTNEXTLINE(bugprone-assert-side-effect) + ENTT_ASSERT_CONSTEXPR(value < (Type{1u} << (std::numeric_limits::digits - 1)), "Numeric limits exceeded"); + Type curr = value - (value != 0u); + + for(int next = 1; next < std::numeric_limits::digits; next = next * 2) { + curr |= (curr >> next); + } + + return ++curr; +} + +/** + * @brief Fast module utility function (powers of two only). + * @tparam Type Unsigned integer type. + * @param value A value of unsigned integer type. + * @param mod _Modulus_, it must be a power of two. + * @return The common remainder. + */ +template +[[nodiscard]] constexpr std::enable_if_t, Type> fast_mod(const Type value, const std::size_t mod) noexcept { + ENTT_ASSERT_CONSTEXPR(has_single_bit(mod), "Value must be a power of two"); + return static_cast(value & (mod - 1u)); +} + +} // namespace entt + +#endif + +// #include "core/compressed_pair.hpp" +#ifndef ENTT_CORE_COMPRESSED_PAIR_HPP +#define ENTT_CORE_COMPRESSED_PAIR_HPP + +#include +#include +#include +#include +// #include "fwd.hpp" + +// #include "type_traits.hpp" + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct compressed_pair_element { + using reference = Type &; + using const_reference = const Type &; + + template>> + // NOLINTNEXTLINE(modernize-use-equals-default) + constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v) {} + + template>, compressed_pair_element>>> + constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v) + : value{std::forward(arg)} {} + + template + constexpr compressed_pair_element(std::tuple args, std::index_sequence) noexcept(std::is_nothrow_constructible_v) + : value{std::forward(std::get(args))...} {} + + [[nodiscard]] constexpr reference get() noexcept { + return value; + } + + [[nodiscard]] constexpr const_reference get() const noexcept { + return value; + } + +private: + Type value{}; +}; + +template +struct compressed_pair_element>>: Type { + using reference = Type &; + using const_reference = const Type &; + using base_type = Type; + + template>> + constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v) + : base_type{} {} + + template>, compressed_pair_element>>> + constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v) + : base_type{std::forward(arg)} {} + + template + constexpr compressed_pair_element(std::tuple args, std::index_sequence) noexcept(std::is_nothrow_constructible_v) + : base_type{std::forward(std::get(args))...} {} + + [[nodiscard]] constexpr reference get() noexcept { + return *this; + } + + [[nodiscard]] constexpr const_reference get() const noexcept { + return *this; + } +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief A compressed pair. + * + * A pair that exploits the _Empty Base Class Optimization_ (or _EBCO_) to + * reduce its final size to a minimum. + * + * @tparam First The type of the first element that the pair stores. + * @tparam Second The type of the second element that the pair stores. + */ +template +class compressed_pair final + : internal::compressed_pair_element, + internal::compressed_pair_element { + using first_base = internal::compressed_pair_element; + using second_base = internal::compressed_pair_element; + +public: + /*! @brief The type of the first element that the pair stores. */ + using first_type = First; + /*! @brief The type of the second element that the pair stores. */ + using second_type = Second; + + /** + * @brief Default constructor, conditionally enabled. + * + * This constructor is only available when the types that the pair stores + * are both at least default constructible. + * + * @tparam Dummy Dummy template parameter used for internal purposes. + */ + template && std::is_default_constructible_v>> + constexpr compressed_pair() noexcept(std::is_nothrow_default_constructible_v && std::is_nothrow_default_constructible_v) + : first_base{}, + second_base{} {} + + /** + * @brief Copy constructor. + * @param other The instance to copy from. + */ + constexpr compressed_pair(const compressed_pair &other) = default; + + /** + * @brief Move constructor. + * @param other The instance to move from. + */ + constexpr compressed_pair(compressed_pair &&other) noexcept = default; + + /** + * @brief Constructs a pair from its values. + * @tparam Arg Type of value to use to initialize the first element. + * @tparam Other Type of value to use to initialize the second element. + * @param arg Value to use to initialize the first element. + * @param other Value to use to initialize the second element. + */ + template + constexpr compressed_pair(Arg &&arg, Other &&other) noexcept(std::is_nothrow_constructible_v && std::is_nothrow_constructible_v) + : first_base{std::forward(arg)}, + second_base{std::forward(other)} {} + + /** + * @brief Constructs a pair by forwarding the arguments to its parts. + * @tparam Args Types of arguments to use to initialize the first element. + * @tparam Other Types of arguments to use to initialize the second element. + * @param args Arguments to use to initialize the first element. + * @param other Arguments to use to initialize the second element. + */ + template + constexpr compressed_pair(std::piecewise_construct_t, std::tuple args, std::tuple other) noexcept(std::is_nothrow_constructible_v && std::is_nothrow_constructible_v) + : first_base{std::move(args), std::index_sequence_for{}}, + second_base{std::move(other), std::index_sequence_for{}} {} + + /*! @brief Default destructor. */ + ~compressed_pair() = default; + + /** + * @brief Copy assignment operator. + * @param other The instance to copy from. + * @return This compressed pair object. + */ + constexpr compressed_pair &operator=(const compressed_pair &other) = default; + + /** + * @brief Move assignment operator. + * @param other The instance to move from. + * @return This compressed pair object. + */ + constexpr compressed_pair &operator=(compressed_pair &&other) noexcept = default; + + /** + * @brief Returns the first element that a pair stores. + * @return The first element that a pair stores. + */ + [[nodiscard]] constexpr first_type &first() noexcept { + return static_cast(*this).get(); + } + + /*! @copydoc first */ + [[nodiscard]] constexpr const first_type &first() const noexcept { + return static_cast(*this).get(); + } + + /** + * @brief Returns the second element that a pair stores. + * @return The second element that a pair stores. + */ + [[nodiscard]] constexpr second_type &second() noexcept { + return static_cast(*this).get(); + } + + /*! @copydoc second */ + [[nodiscard]] constexpr const second_type &second() const noexcept { + return static_cast(*this).get(); + } + + /** + * @brief Swaps two compressed pair objects. + * @param other The compressed pair to swap with. + */ + constexpr void swap(compressed_pair &other) noexcept { + using std::swap; + swap(first(), other.first()); + swap(second(), other.second()); + } + + /** + * @brief Extracts an element from the compressed pair. + * @tparam Index An integer value that is either 0 or 1. + * @return Returns a reference to the first element if `Index` is 0 and a + * reference to the second element if `Index` is 1. + */ + template + [[nodiscard]] constexpr decltype(auto) get() noexcept { + if constexpr(Index == 0u) { + return first(); + } else { + static_assert(Index == 1u, "Index out of bounds"); + return second(); + } + } + + /*! @copydoc get */ + template + [[nodiscard]] constexpr decltype(auto) get() const noexcept { + if constexpr(Index == 0u) { + return first(); + } else { + static_assert(Index == 1u, "Index out of bounds"); + return second(); + } + } +}; + +/** + * @brief Deduction guide. + * @tparam Type Type of value to use to initialize the first element. + * @tparam Other Type of value to use to initialize the second element. + */ +template +compressed_pair(Type &&, Other &&) -> compressed_pair, std::decay_t>; + +/** + * @brief Swaps two compressed pair objects. + * @tparam First The type of the first element that the pairs store. + * @tparam Second The type of the second element that the pairs store. + * @param lhs A valid compressed pair object. + * @param rhs A valid compressed pair object. + */ +template +constexpr void swap(compressed_pair &lhs, compressed_pair &rhs) noexcept { + lhs.swap(rhs); +} + +} // namespace entt + +namespace std { + +/** + * @brief `std::tuple_size` specialization for `compressed_pair`s. + * @tparam First The type of the first element that the pair stores. + * @tparam Second The type of the second element that the pair stores. + */ +template +struct tuple_size>: integral_constant {}; + +/** + * @brief `std::tuple_element` specialization for `compressed_pair`s. + * @tparam Index The index of the type to return. + * @tparam First The type of the first element that the pair stores. + * @tparam Second The type of the second element that the pair stores. + */ +template +struct tuple_element>: conditional { + static_assert(Index < 2u, "Index out of bounds"); +}; + +} // namespace std + +#endif + +// #include "core/enum.hpp" +#ifndef ENTT_CORE_ENUM_HPP +#define ENTT_CORE_ENUM_HPP + +#include + +namespace entt { + +/** + * @brief Enable bitmask support for enum classes. + * @tparam Type The enum type for which to enable bitmask support. + */ +template +struct enum_as_bitmask: std::false_type {}; + +/*! @copydoc enum_as_bitmask */ +template +struct enum_as_bitmask>: std::is_enum {}; + +/** + * @brief Helper variable template. + * @tparam Type The enum class type for which to enable bitmask support. + */ +template +inline constexpr bool enum_as_bitmask_v = enum_as_bitmask::value; + +} // namespace entt + +/** + * @brief Operator available for enums for which bitmask support is enabled. + * @tparam Type Enum class type. + * @param lhs The first value to use. + * @param rhs The second value to use. + * @return The result of invoking the operator on the underlying types of the + * two values provided. + */ +template +[[nodiscard]] constexpr std::enable_if_t, Type> +operator|(const Type lhs, const Type rhs) noexcept { + return static_cast(static_cast>(lhs) | static_cast>(rhs)); +} + +/*! @copydoc operator| */ +template +[[nodiscard]] constexpr std::enable_if_t, Type> +operator&(const Type lhs, const Type rhs) noexcept { + return static_cast(static_cast>(lhs) & static_cast>(rhs)); +} + +/*! @copydoc operator| */ +template +[[nodiscard]] constexpr std::enable_if_t, Type> +operator^(const Type lhs, const Type rhs) noexcept { + return static_cast(static_cast>(lhs) ^ static_cast>(rhs)); +} + +/** + * @brief Operator available for enums for which bitmask support is enabled. + * @tparam Type Enum class type. + * @param value The value to use. + * @return The result of invoking the operator on the underlying types of the + * value provided. + */ +template +[[nodiscard]] constexpr std::enable_if_t, Type> +operator~(const Type value) noexcept { + return static_cast(~static_cast>(value)); +} + +/*! @copydoc operator~ */ +template +[[nodiscard]] constexpr std::enable_if_t, bool> +operator!(const Type value) noexcept { + return !static_cast>(value); +} + +/*! @copydoc operator| */ +template +constexpr std::enable_if_t, Type &> +operator|=(Type &lhs, const Type rhs) noexcept { + return (lhs = (lhs | rhs)); +} + +/*! @copydoc operator| */ +template +constexpr std::enable_if_t, Type &> +operator&=(Type &lhs, const Type rhs) noexcept { + return (lhs = (lhs & rhs)); +} + +/*! @copydoc operator| */ +template +constexpr std::enable_if_t, Type &> +operator^=(Type &lhs, const Type rhs) noexcept { + return (lhs = (lhs ^ rhs)); +} + +#endif + +// #include "core/family.hpp" +#ifndef ENTT_CORE_FAMILY_HPP +#define ENTT_CORE_FAMILY_HPP + +// #include "../config/config.h" + +// #include "fwd.hpp" + + +namespace entt { + +/** + * @brief Dynamic identifier generator. + * + * Utility class template that can be used to assign unique identifiers to types + * at runtime. Use different specializations to create separate sets of + * identifiers. + */ +template +class family { + static auto identifier() noexcept { + static ENTT_MAYBE_ATOMIC(id_type) value{}; + return value++; + } + +public: + /*! @brief Unsigned integer type. */ + using value_type = id_type; + + /*! @brief Statically generated unique identifier for the given type. */ + template + // at the time I'm writing, clang crashes during compilation if auto is used instead of family_type + inline static const value_type value = identifier(); +}; + +} // namespace entt + +#endif + +// #include "core/hashed_string.hpp" +#ifndef ENTT_CORE_HASHED_STRING_HPP +#define ENTT_CORE_HASHED_STRING_HPP + +#include +#include +// #include "fwd.hpp" + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct fnv_1a_params; + +template<> +struct fnv_1a_params { + static constexpr auto offset = 2166136261; + static constexpr auto prime = 16777619; +}; + +template<> +struct fnv_1a_params { + static constexpr auto offset = 14695981039346656037ull; + static constexpr auto prime = 1099511628211ull; +}; + +template +struct basic_hashed_string { + using value_type = Char; + using size_type = std::size_t; + using hash_type = id_type; + + const value_type *repr{}; + hash_type hash{fnv_1a_params<>::offset}; + size_type length{}; +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Zero overhead unique identifier. + * + * A hashed string is a compile-time tool that allows users to use + * human-readable identifiers in the codebase while using their numeric + * counterparts at runtime.
+ * Because of that, a hashed string can also be used in constant expressions if + * required. + * + * @warning + * This class doesn't take ownership of user-supplied strings nor does it make a + * copy of them. + * + * @tparam Char Character type. + */ +template +class basic_hashed_string: internal::basic_hashed_string { + using base_type = internal::basic_hashed_string; + using params = internal::fnv_1a_params<>; + + struct const_wrapper { + // non-explicit constructor on purpose + constexpr const_wrapper(const typename base_type::value_type *str) noexcept + : repr{str} {} + + const typename base_type::value_type *repr; + }; + +public: + /*! @brief Character type. */ + using value_type = typename base_type::value_type; + /*! @brief Unsigned integer type. */ + using size_type = typename base_type::size_type; + /*! @brief Unsigned integer type. */ + using hash_type = typename base_type::hash_type; + + /** + * @brief Returns directly the numeric representation of a string view. + * @param str Human-readable identifier. + * @param len Length of the string to hash. + * @return The numeric representation of the string. + */ + [[nodiscard]] static constexpr hash_type value(const value_type *str, const size_type len) noexcept { + return basic_hashed_string{str, len}; + } + + /** + * @brief Returns directly the numeric representation of a string. + * @tparam N Number of characters of the identifier. + * @param str Human-readable identifier. + * @return The numeric representation of the string. + */ + template + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) + [[nodiscard]] static ENTT_CONSTEVAL hash_type value(const value_type (&str)[N]) noexcept { + return basic_hashed_string{str}; + } + + /** + * @brief Returns directly the numeric representation of a string. + * @param wrapper Helps achieving the purpose by relying on overloading. + * @return The numeric representation of the string. + */ + [[nodiscard]] static constexpr hash_type value(const_wrapper wrapper) noexcept { + return basic_hashed_string{wrapper}; + } + + /*! @brief Constructs an empty hashed string. */ + constexpr basic_hashed_string() noexcept + : basic_hashed_string{nullptr, 0u} {} + + /** + * @brief Constructs a hashed string from a string view. + * @param str Human-readable identifier. + * @param len Length of the string to hash. + */ + constexpr basic_hashed_string(const value_type *str, const size_type len) noexcept + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay) + : base_type{str} { + // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic) + for(; base_type::length < len; ++base_type::length) { + base_type::hash = (base_type::hash ^ static_cast(str[base_type::length])) * params::prime; + } + // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic) + } + + /** + * @brief Constructs a hashed string from an array of const characters. + * @tparam N Number of characters of the identifier. + * @param str Human-readable identifier. + */ + template + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) + ENTT_CONSTEVAL basic_hashed_string(const value_type (&str)[N]) noexcept + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay) + : base_type{str} { + for(; str[base_type::length]; ++base_type::length) { + base_type::hash = (base_type::hash ^ static_cast(str[base_type::length])) * params::prime; + } + } + + /** + * @brief Explicit constructor on purpose to avoid constructing a hashed + * string directly from a `const value_type *`. + * + * @warning + * The lifetime of the string is not extended nor is it copied. + * + * @param wrapper Helps achieving the purpose by relying on overloading. + */ + explicit constexpr basic_hashed_string(const_wrapper wrapper) noexcept + : base_type{wrapper.repr} { + // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic) + for(; wrapper.repr[base_type::length]; ++base_type::length) { + base_type::hash = (base_type::hash ^ static_cast(wrapper.repr[base_type::length])) * params::prime; + } + // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic) + } + + /** + * @brief Returns the size of a hashed string. + * @return The size of the hashed string. + */ + [[nodiscard]] constexpr size_type size() const noexcept { + return base_type::length; + } + + /** + * @brief Returns the human-readable representation of a hashed string. + * @return The string used to initialize the hashed string. + */ + [[nodiscard]] constexpr const value_type *data() const noexcept { + return base_type::repr; + } + + /** + * @brief Returns the numeric representation of a hashed string. + * @return The numeric representation of the hashed string. + */ + [[nodiscard]] constexpr hash_type value() const noexcept { + return base_type::hash; + } + + /*! @copydoc data */ + [[nodiscard]] explicit constexpr operator const value_type *() const noexcept { + return data(); + } + + /** + * @brief Returns the numeric representation of a hashed string. + * @return The numeric representation of the hashed string. + */ + [[nodiscard]] constexpr operator hash_type() const noexcept { + return value(); + } +}; + +/** + * @brief Deduction guide. + * @tparam Char Character type. + * @param str Human-readable identifier. + * @param len Length of the string to hash. + */ +template +basic_hashed_string(const Char *str, std::size_t len) -> basic_hashed_string; + +/** + * @brief Deduction guide. + * @tparam Char Character type. + * @tparam N Number of characters of the identifier. + * @param str Human-readable identifier. + */ +template +// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) +basic_hashed_string(const Char (&str)[N]) -> basic_hashed_string; + +/** + * @brief Compares two hashed strings. + * @tparam Char Character type. + * @param lhs A valid hashed string. + * @param rhs A valid hashed string. + * @return True if the two hashed strings are identical, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator==(const basic_hashed_string &lhs, const basic_hashed_string &rhs) noexcept { + return lhs.value() == rhs.value(); +} + +/** + * @brief Compares two hashed strings. + * @tparam Char Character type. + * @param lhs A valid hashed string. + * @param rhs A valid hashed string. + * @return True if the two hashed strings differ, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator!=(const basic_hashed_string &lhs, const basic_hashed_string &rhs) noexcept { + return !(lhs == rhs); +} + +/** + * @brief Compares two hashed strings. + * @tparam Char Character type. + * @param lhs A valid hashed string. + * @param rhs A valid hashed string. + * @return True if the first element is less than the second, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator<(const basic_hashed_string &lhs, const basic_hashed_string &rhs) noexcept { + return lhs.value() < rhs.value(); +} + +/** + * @brief Compares two hashed strings. + * @tparam Char Character type. + * @param lhs A valid hashed string. + * @param rhs A valid hashed string. + * @return True if the first element is less than or equal to the second, false + * otherwise. + */ +template +[[nodiscard]] constexpr bool operator<=(const basic_hashed_string &lhs, const basic_hashed_string &rhs) noexcept { + return !(rhs < lhs); +} + +/** + * @brief Compares two hashed strings. + * @tparam Char Character type. + * @param lhs A valid hashed string. + * @param rhs A valid hashed string. + * @return True if the first element is greater than the second, false + * otherwise. + */ +template +[[nodiscard]] constexpr bool operator>(const basic_hashed_string &lhs, const basic_hashed_string &rhs) noexcept { + return rhs < lhs; +} + +/** + * @brief Compares two hashed strings. + * @tparam Char Character type. + * @param lhs A valid hashed string. + * @param rhs A valid hashed string. + * @return True if the first element is greater than or equal to the second, + * false otherwise. + */ +template +[[nodiscard]] constexpr bool operator>=(const basic_hashed_string &lhs, const basic_hashed_string &rhs) noexcept { + return !(lhs < rhs); +} + +inline namespace literals { + +/** + * @brief User defined literal for hashed strings. + * @param str The literal without its suffix. + * @return A properly initialized hashed string. + */ +[[nodiscard]] ENTT_CONSTEVAL hashed_string operator""_hs(const char *str, std::size_t) noexcept { + return hashed_string{str}; +} + +/** + * @brief User defined literal for hashed wstrings. + * @param str The literal without its suffix. + * @return A properly initialized hashed wstring. + */ +[[nodiscard]] ENTT_CONSTEVAL hashed_wstring operator""_hws(const wchar_t *str, std::size_t) noexcept { + return hashed_wstring{str}; +} + +} // namespace literals + +} // namespace entt + +#endif + +// #include "core/ident.hpp" +#ifndef ENTT_CORE_IDENT_HPP +#define ENTT_CORE_IDENT_HPP + +#include +#include +#include +// #include "fwd.hpp" + +// #include "type_traits.hpp" + + +namespace entt { + +/** + * @brief Type integral identifiers. + * @tparam Type List of types for which to generate identifiers. + */ +template +class ident { + template + [[nodiscard]] static constexpr id_type get(std::index_sequence) noexcept { + static_assert((std::is_same_v || ...), "Invalid type"); + return (0 + ... + (std::is_same_v...>>> ? id_type{Index} : id_type{})); + } + +public: + /*! @brief Unsigned integer type. */ + using value_type = id_type; + + /*! @brief Statically generated unique identifier for the given type. */ + template + static constexpr value_type value = get>(std::index_sequence_for{}); +}; + +} // namespace entt + +#endif + +// #include "core/iterator.hpp" +#ifndef ENTT_CORE_ITERATOR_HPP +#define ENTT_CORE_ITERATOR_HPP + +#include +#include +#include +#include + +namespace entt { + +/** + * @brief Helper type to use as pointer with input iterators. + * @tparam Type of wrapped value. + */ +template +struct input_iterator_pointer final { + /*! @brief Value type. */ + using value_type = Type; + /*! @brief Pointer type. */ + using pointer = Type *; + /*! @brief Reference type. */ + using reference = Type &; + + /** + * @brief Constructs a proxy object by move. + * @param val Value to use to initialize the proxy object. + */ + constexpr input_iterator_pointer(value_type &&val) noexcept(std::is_nothrow_move_constructible_v) + : value{std::move(val)} {} + + /** + * @brief Access operator for accessing wrapped values. + * @return A pointer to the wrapped value. + */ + [[nodiscard]] constexpr pointer operator->() noexcept { + return std::addressof(value); + } + + /** + * @brief Dereference operator for accessing wrapped values. + * @return A reference to the wrapped value. + */ + [[nodiscard]] constexpr reference operator*() noexcept { + return value; + } + +private: + Type value; +}; + +/** + * @brief Plain iota iterator (waiting for C++20). + * @tparam Type Value type. + */ +template +class iota_iterator final { + static_assert(std::is_integral_v, "Not an integral type"); + +public: + /*! @brief Value type, likely an integral one. */ + using value_type = Type; + /*! @brief Invalid pointer type. */ + using pointer = void; + /*! @brief Non-reference type, same as value type. */ + using reference = value_type; + /*! @brief Difference type. */ + using difference_type = std::ptrdiff_t; + /*! @brief Iterator category. */ + using iterator_category = std::input_iterator_tag; + + /*! @brief Default constructor. */ + constexpr iota_iterator() noexcept + : current{} {} + + /** + * @brief Constructs an iota iterator from a given value. + * @param init The initial value assigned to the iota iterator. + */ + constexpr iota_iterator(const value_type init) noexcept + : current{init} {} + + /** + * @brief Pre-increment operator. + * @return This iota iterator. + */ + constexpr iota_iterator &operator++() noexcept { + return ++current, *this; + } + + /** + * @brief Post-increment operator. + * @return This iota iterator. + */ + constexpr iota_iterator operator++(int) noexcept { + const iota_iterator orig = *this; + return ++(*this), orig; + } + + /** + * @brief Dereference operator. + * @return The underlying value. + */ + [[nodiscard]] constexpr reference operator*() const noexcept { + return current; + } + +private: + value_type current; +}; + +/** + * @brief Comparison operator. + * @tparam Type Value type of the iota iterator. + * @param lhs A properly initialized iota iterator. + * @param rhs A properly initialized iota iterator. + * @return True if the two iterators are identical, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator==(const iota_iterator &lhs, const iota_iterator &rhs) noexcept { + return *lhs == *rhs; +} + +/** + * @brief Comparison operator. + * @tparam Type Value type of the iota iterator. + * @param lhs A properly initialized iota iterator. + * @param rhs A properly initialized iota iterator. + * @return True if the two iterators differ, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator!=(const iota_iterator &lhs, const iota_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +/** + * @brief Utility class to create an iterable object from a pair of iterators. + * @tparam It Type of iterator. + * @tparam Sentinel Type of sentinel. + */ +template +struct iterable_adaptor final { + /*! @brief Value type. */ + using value_type = typename std::iterator_traits::value_type; + /*! @brief Iterator type. */ + using iterator = It; + /*! @brief Sentinel type. */ + using sentinel = Sentinel; + + /*! @brief Default constructor. */ + constexpr iterable_adaptor() noexcept(std::is_nothrow_default_constructible_v && std::is_nothrow_default_constructible_v) + : first{}, + last{} {} + + /** + * @brief Creates an iterable object from a pair of iterators. + * @param from Begin iterator. + * @param to End iterator. + */ + constexpr iterable_adaptor(iterator from, sentinel to) noexcept(std::is_nothrow_move_constructible_v && std::is_nothrow_move_constructible_v) + : first{std::move(from)}, + last{std::move(to)} {} + + /** + * @brief Returns an iterator to the beginning. + * @return An iterator to the first element of the range. + */ + [[nodiscard]] constexpr iterator begin() const noexcept { + return first; + } + + /** + * @brief Returns an iterator to the end. + * @return An iterator to the element following the last element of the + * range. + */ + [[nodiscard]] constexpr sentinel end() const noexcept { + return last; + } + + /*! @copydoc begin */ + [[nodiscard]] constexpr iterator cbegin() const noexcept { + return begin(); + } + + /*! @copydoc end */ + [[nodiscard]] constexpr sentinel cend() const noexcept { + return end(); + } + +private: + It first; + Sentinel last; +}; + +} // namespace entt + +#endif + +// #include "core/memory.hpp" +#ifndef ENTT_CORE_MEMORY_HPP +#define ENTT_CORE_MEMORY_HPP + +#include +#include +#include +#include +#include +// #include "../config/config.h" + + +namespace entt { + +/** + * @brief Unwraps fancy pointers, does nothing otherwise (waiting for C++20). + * @tparam Type Pointer type. + * @param ptr Fancy or raw pointer. + * @return A raw pointer that represents the address of the original pointer. + */ +template +[[nodiscard]] constexpr auto to_address(Type &&ptr) noexcept { + if constexpr(std::is_pointer_v>) { + return ptr; + } else { + return to_address(std::forward(ptr).operator->()); + } +} + +/** + * @brief Utility function to design allocation-aware containers. + * @tparam Allocator Type of allocator. + * @param lhs A valid allocator. + * @param rhs Another valid allocator. + */ +template +constexpr void propagate_on_container_copy_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept { + if constexpr(std::allocator_traits::propagate_on_container_copy_assignment::value) { + lhs = rhs; + } +} + +/** + * @brief Utility function to design allocation-aware containers. + * @tparam Allocator Type of allocator. + * @param lhs A valid allocator. + * @param rhs Another valid allocator. + */ +template +constexpr void propagate_on_container_move_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept { + if constexpr(std::allocator_traits::propagate_on_container_move_assignment::value) { + lhs = std::move(rhs); + } +} + +/** + * @brief Utility function to design allocation-aware containers. + * @tparam Allocator Type of allocator. + * @param lhs A valid allocator. + * @param rhs Another valid allocator. + */ +template +constexpr void propagate_on_container_swap([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept { + if constexpr(std::allocator_traits::propagate_on_container_swap::value) { + using std::swap; + swap(lhs, rhs); + } else { + ENTT_ASSERT_CONSTEXPR(lhs == rhs, "Cannot swap the containers"); + } +} + +/** + * @brief Deleter for allocator-aware unique pointers (waiting for C++20). + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +struct allocation_deleter: private Allocator { + /*! @brief Allocator type. */ + using allocator_type = Allocator; + /*! @brief Pointer type. */ + using pointer = typename std::allocator_traits::pointer; + + /** + * @brief Inherited constructors. + * @param alloc The allocator to use. + */ + constexpr allocation_deleter(const allocator_type &alloc) noexcept(std::is_nothrow_copy_constructible_v) + : Allocator{alloc} {} + + /** + * @brief Destroys the pointed object and deallocates its memory. + * @param ptr A valid pointer to an object of the given type. + */ + constexpr void operator()(pointer ptr) noexcept(std::is_nothrow_destructible_v) { + using alloc_traits = std::allocator_traits; + alloc_traits::destroy(*this, to_address(ptr)); + alloc_traits::deallocate(*this, ptr, 1u); + } +}; + +/** + * @brief Allows `std::unique_ptr` to use allocators (waiting for C++20). + * @tparam Type Type of object to allocate for and to construct. + * @tparam Allocator Type of allocator used to manage memory and elements. + * @tparam Args Types of arguments to use to construct the object. + * @param allocator The allocator to use. + * @param args Parameters to use to construct the object. + * @return A properly initialized unique pointer with a custom deleter. + */ +template +ENTT_CONSTEXPR auto allocate_unique(Allocator &allocator, Args &&...args) { + static_assert(!std::is_array_v, "Array types are not supported"); + + using alloc_traits = typename std::allocator_traits::template rebind_traits; + using allocator_type = typename alloc_traits::allocator_type; + + allocator_type alloc{allocator}; + auto ptr = alloc_traits::allocate(alloc, 1u); + + ENTT_TRY { + alloc_traits::construct(alloc, to_address(ptr), std::forward(args)...); + } + ENTT_CATCH { + alloc_traits::deallocate(alloc, ptr, 1u); + ENTT_THROW; + } + + return std::unique_ptr>{ptr, alloc}; +} + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct uses_allocator_construction { + template + static constexpr auto args([[maybe_unused]] const Allocator &allocator, Params &&...params) noexcept { + if constexpr(!std::uses_allocator_v && std::is_constructible_v) { + return std::forward_as_tuple(std::forward(params)...); + } else { + static_assert(std::uses_allocator_v, "Ill-formed request"); + + if constexpr(std::is_constructible_v) { + return std::tuple{std::allocator_arg, allocator, std::forward(params)...}; + } else { + static_assert(std::is_constructible_v, "Ill-formed request"); + return std::forward_as_tuple(std::forward(params)..., allocator); + } + } + } +}; + +template +struct uses_allocator_construction> { + using type = std::pair; + + template + static constexpr auto args(const Allocator &allocator, std::piecewise_construct_t, First &&first, Second &&second) noexcept { + return std::make_tuple( + std::piecewise_construct, + std::apply([&allocator](auto &&...curr) { return uses_allocator_construction::args(allocator, std::forward(curr)...); }, std::forward(first)), + std::apply([&allocator](auto &&...curr) { return uses_allocator_construction::args(allocator, std::forward(curr)...); }, std::forward(second))); + } + + template + static constexpr auto args(const Allocator &allocator) noexcept { + return uses_allocator_construction::args(allocator, std::piecewise_construct, std::tuple<>{}, std::tuple<>{}); + } + + template + static constexpr auto args(const Allocator &allocator, First &&first, Second &&second) noexcept { + return uses_allocator_construction::args(allocator, std::piecewise_construct, std::forward_as_tuple(std::forward(first)), std::forward_as_tuple(std::forward(second))); + } + + template + static constexpr auto args(const Allocator &allocator, const std::pair &value) noexcept { + return uses_allocator_construction::args(allocator, std::piecewise_construct, std::forward_as_tuple(value.first), std::forward_as_tuple(value.second)); + } + + template + static constexpr auto args(const Allocator &allocator, std::pair &&value) noexcept { + return uses_allocator_construction::args(allocator, std::piecewise_construct, std::forward_as_tuple(std::move(value.first)), std::forward_as_tuple(std::move(value.second))); + } +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Uses-allocator construction utility (waiting for C++20). + * + * Primarily intended for internal use. Prepares the argument list needed to + * create an object of a given type by means of uses-allocator construction. + * + * @tparam Type Type to return arguments for. + * @tparam Allocator Type of allocator used to manage memory and elements. + * @tparam Args Types of arguments to use to construct the object. + * @param allocator The allocator to use. + * @param args Parameters to use to construct the object. + * @return The arguments needed to create an object of the given type. + */ +template +constexpr auto uses_allocator_construction_args(const Allocator &allocator, Args &&...args) noexcept { + return internal::uses_allocator_construction::args(allocator, std::forward(args)...); +} + +/** + * @brief Uses-allocator construction utility (waiting for C++20). + * + * Primarily intended for internal use. Creates an object of a given type by + * means of uses-allocator construction. + * + * @tparam Type Type of object to create. + * @tparam Allocator Type of allocator used to manage memory and elements. + * @tparam Args Types of arguments to use to construct the object. + * @param allocator The allocator to use. + * @param args Parameters to use to construct the object. + * @return A newly created object of the given type. + */ +template +constexpr Type make_obj_using_allocator(const Allocator &allocator, Args &&...args) { + return std::make_from_tuple(internal::uses_allocator_construction::args(allocator, std::forward(args)...)); +} + +/** + * @brief Uses-allocator construction utility (waiting for C++20). + * + * Primarily intended for internal use. Creates an object of a given type by + * means of uses-allocator construction at an uninitialized memory location. + * + * @tparam Type Type of object to create. + * @tparam Allocator Type of allocator used to manage memory and elements. + * @tparam Args Types of arguments to use to construct the object. + * @param value Memory location in which to place the object. + * @param allocator The allocator to use. + * @param args Parameters to use to construct the object. + * @return A pointer to the newly created object of the given type. + */ +template +constexpr Type *uninitialized_construct_using_allocator(Type *value, const Allocator &allocator, Args &&...args) { + return std::apply([value](auto &&...curr) { return ::new(value) Type(std::forward(curr)...); }, internal::uses_allocator_construction::args(allocator, std::forward(args)...)); +} + +} // namespace entt + +#endif + +// #include "core/monostate.hpp" +#ifndef ENTT_CORE_MONOSTATE_HPP +#define ENTT_CORE_MONOSTATE_HPP + +// #include "../config/config.h" + +// #include "fwd.hpp" + + +namespace entt { + +/** + * @brief Minimal implementation of the monostate pattern. + * + * A minimal, yet complete configuration system built on top of the monostate + * pattern. Thread safe by design, it works only with basic types like `int`s or + * `bool`s.
+ * Multiple types and therefore more than one value can be associated with a + * single key. Because of this, users must pay attention to use the same type + * both during an assignment and when they try to read back their data. + * Otherwise, they can incur in unexpected results. + */ +template +struct monostate { + /** + * @brief Assigns a value of a specific type to a given key. + * @tparam Type Type of the value to assign. + * @param val User data to assign to the given key. + * @return This monostate object. + */ + template + monostate &operator=(Type val) noexcept { + value = val; + return *this; + } + + /** + * @brief Gets a value of a specific type for a given key. + * @tparam Type Type of the value to get. + * @return Stored value, if any. + */ + template + operator Type() const noexcept { + return value; + } + +private: + template + // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) + inline static ENTT_MAYBE_ATOMIC(Type) value{}; +}; + +/** + * @brief Helper variable template. + * @tparam Value Value used to differentiate between different variables. + */ +template +// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) +inline monostate monostate_v{}; + +} // namespace entt + +#endif + +// #include "core/ranges.hpp" +#ifndef ENTT_CORE_RANGES_HPP +#define ENTT_CORE_RANGES_HPP + +#if __has_include() +# include +# +# if defined(__cpp_lib_ranges) +# include +// # include "iterator.hpp" +#ifndef ENTT_CORE_ITERATOR_HPP +#define ENTT_CORE_ITERATOR_HPP + +#include +#include +#include +#include + +namespace entt { + +/** + * @brief Helper type to use as pointer with input iterators. + * @tparam Type of wrapped value. + */ +template +struct input_iterator_pointer final { + /*! @brief Value type. */ + using value_type = Type; + /*! @brief Pointer type. */ + using pointer = Type *; + /*! @brief Reference type. */ + using reference = Type &; + + /** + * @brief Constructs a proxy object by move. + * @param val Value to use to initialize the proxy object. + */ + constexpr input_iterator_pointer(value_type &&val) noexcept(std::is_nothrow_move_constructible_v) + : value{std::move(val)} {} + + /** + * @brief Access operator for accessing wrapped values. + * @return A pointer to the wrapped value. + */ + [[nodiscard]] constexpr pointer operator->() noexcept { + return std::addressof(value); + } + + /** + * @brief Dereference operator for accessing wrapped values. + * @return A reference to the wrapped value. + */ + [[nodiscard]] constexpr reference operator*() noexcept { + return value; + } + +private: + Type value; +}; + +/** + * @brief Plain iota iterator (waiting for C++20). + * @tparam Type Value type. + */ +template +class iota_iterator final { + static_assert(std::is_integral_v, "Not an integral type"); + +public: + /*! @brief Value type, likely an integral one. */ + using value_type = Type; + /*! @brief Invalid pointer type. */ + using pointer = void; + /*! @brief Non-reference type, same as value type. */ + using reference = value_type; + /*! @brief Difference type. */ + using difference_type = std::ptrdiff_t; + /*! @brief Iterator category. */ + using iterator_category = std::input_iterator_tag; + + /*! @brief Default constructor. */ + constexpr iota_iterator() noexcept + : current{} {} + + /** + * @brief Constructs an iota iterator from a given value. + * @param init The initial value assigned to the iota iterator. + */ + constexpr iota_iterator(const value_type init) noexcept + : current{init} {} + + /** + * @brief Pre-increment operator. + * @return This iota iterator. + */ + constexpr iota_iterator &operator++() noexcept { + return ++current, *this; + } + + /** + * @brief Post-increment operator. + * @return This iota iterator. + */ + constexpr iota_iterator operator++(int) noexcept { + const iota_iterator orig = *this; + return ++(*this), orig; + } + + /** + * @brief Dereference operator. + * @return The underlying value. + */ + [[nodiscard]] constexpr reference operator*() const noexcept { + return current; + } + +private: + value_type current; +}; + +/** + * @brief Comparison operator. + * @tparam Type Value type of the iota iterator. + * @param lhs A properly initialized iota iterator. + * @param rhs A properly initialized iota iterator. + * @return True if the two iterators are identical, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator==(const iota_iterator &lhs, const iota_iterator &rhs) noexcept { + return *lhs == *rhs; +} + +/** + * @brief Comparison operator. + * @tparam Type Value type of the iota iterator. + * @param lhs A properly initialized iota iterator. + * @param rhs A properly initialized iota iterator. + * @return True if the two iterators differ, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator!=(const iota_iterator &lhs, const iota_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +/** + * @brief Utility class to create an iterable object from a pair of iterators. + * @tparam It Type of iterator. + * @tparam Sentinel Type of sentinel. + */ +template +struct iterable_adaptor final { + /*! @brief Value type. */ + using value_type = typename std::iterator_traits::value_type; + /*! @brief Iterator type. */ + using iterator = It; + /*! @brief Sentinel type. */ + using sentinel = Sentinel; + + /*! @brief Default constructor. */ + constexpr iterable_adaptor() noexcept(std::is_nothrow_default_constructible_v && std::is_nothrow_default_constructible_v) + : first{}, + last{} {} + + /** + * @brief Creates an iterable object from a pair of iterators. + * @param from Begin iterator. + * @param to End iterator. + */ + constexpr iterable_adaptor(iterator from, sentinel to) noexcept(std::is_nothrow_move_constructible_v && std::is_nothrow_move_constructible_v) + : first{std::move(from)}, + last{std::move(to)} {} + + /** + * @brief Returns an iterator to the beginning. + * @return An iterator to the first element of the range. + */ + [[nodiscard]] constexpr iterator begin() const noexcept { + return first; + } + + /** + * @brief Returns an iterator to the end. + * @return An iterator to the element following the last element of the + * range. + */ + [[nodiscard]] constexpr sentinel end() const noexcept { + return last; + } + + /*! @copydoc begin */ + [[nodiscard]] constexpr iterator cbegin() const noexcept { + return begin(); + } + + /*! @copydoc end */ + [[nodiscard]] constexpr sentinel cend() const noexcept { + return end(); + } + +private: + It first; + Sentinel last; +}; + +} // namespace entt + +#endif + + +template +inline constexpr bool std::ranges::enable_borrowed_range>{true}; + +template +inline constexpr bool std::ranges::enable_view>{true}; + +# endif +#endif + +#endif +// #include "core/tuple.hpp" +#ifndef ENTT_CORE_TUPLE_HPP +#define ENTT_CORE_TUPLE_HPP + +#include +#include +#include + +namespace entt { + +/** + * @brief Provides the member constant `value` to true if a given type is a + * tuple, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_tuple: std::false_type {}; + +/** + * @copybrief is_tuple + * @tparam Args Tuple template arguments. + */ +template +struct is_tuple>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_tuple_v = is_tuple::value; + +/** + * @brief Utility function to unwrap tuples of a single element. + * @tparam Type Tuple type of any sizes. + * @param value A tuple object of the given type. + * @return The tuple itself if it contains more than one element, the first + * element otherwise. + */ +template +constexpr decltype(auto) unwrap_tuple(Type &&value) noexcept { + if constexpr(std::tuple_size_v> == 1u) { + return std::get<0>(std::forward(value)); + } else { + return std::forward(value); + } +} + +/** + * @brief Utility class to forward-and-apply tuple objects. + * @tparam Func Type of underlying invocable object. + */ +template +struct forward_apply: private Func { + /** + * @brief Constructs a forward-and-apply object. + * @tparam Args Types of arguments to use to construct the new instance. + * @param args Parameters to use to construct the instance. + */ + template + constexpr forward_apply(Args &&...args) noexcept(std::is_nothrow_constructible_v) + : Func{std::forward(args)...} {} + + /** + * @brief Forwards and applies the arguments with the underlying function. + * @tparam Type Tuple-like type to forward to the underlying function. + * @param args Parameters to forward to the underlying function. + * @return Return value of the underlying function, if any. + */ + template + constexpr decltype(auto) operator()(Type &&args) noexcept(noexcept(std::apply(std::declval(), args))) { + return std::apply(static_cast(*this), std::forward(args)); + } + + /*! @copydoc operator()() */ + template + constexpr decltype(auto) operator()(Type &&args) const noexcept(noexcept(std::apply(std::declval(), args))) { + return std::apply(static_cast(*this), std::forward(args)); + } +}; + +/** + * @brief Deduction guide. + * @tparam Func Type of underlying invocable object. + */ +template +forward_apply(Func) -> forward_apply>>; + +} // namespace entt + +#endif + +// #include "core/type_info.hpp" +#ifndef ENTT_CORE_TYPE_INFO_HPP +#define ENTT_CORE_TYPE_INFO_HPP + +#include +#include +#include +// #include "../config/config.h" + +// #include "fwd.hpp" + +// #include "hashed_string.hpp" + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +struct ENTT_API type_index final { + [[nodiscard]] static id_type next() noexcept { + static ENTT_MAYBE_ATOMIC(id_type) value{}; + return value++; + } +}; + +template +[[nodiscard]] constexpr const char *pretty_function() noexcept { +#if defined ENTT_PRETTY_FUNCTION + return static_cast(ENTT_PRETTY_FUNCTION); +#else + return ""; +#endif +} + +template +[[nodiscard]] constexpr auto stripped_type_name() noexcept { +#if defined ENTT_PRETTY_FUNCTION + const std::string_view full_name{pretty_function()}; + auto first = full_name.find_first_not_of(' ', full_name.find_first_of(ENTT_PRETTY_FUNCTION_PREFIX) + 1); + auto value = full_name.substr(first, full_name.find_last_of(ENTT_PRETTY_FUNCTION_SUFFIX) - first); + return value; +#else + return std::string_view{}; +#endif +} + +template().find_first_of('.')> +[[nodiscard]] constexpr std::string_view type_name(int) noexcept { + constexpr auto value = stripped_type_name(); + return value; +} + +template +[[nodiscard]] std::string_view type_name(char) noexcept { + static const auto value = stripped_type_name(); + return value; +} + +template().find_first_of('.')> +[[nodiscard]] constexpr id_type type_hash(int) noexcept { + constexpr auto stripped = stripped_type_name(); + constexpr auto value = hashed_string::value(stripped.data(), stripped.size()); + return value; +} + +template +[[nodiscard]] id_type type_hash(char) noexcept { + static const auto value = [](const auto stripped) { + return hashed_string::value(stripped.data(), stripped.size()); + }(stripped_type_name()); + return value; +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Type sequential identifier. + * @tparam Type Type for which to generate a sequential identifier. + */ +template +struct ENTT_API type_index final { + /** + * @brief Returns the sequential identifier of a given type. + * @return The sequential identifier of a given type. + */ + [[nodiscard]] static id_type value() noexcept { + static const id_type value = internal::type_index::next(); + return value; + } + + /*! @copydoc value */ + [[nodiscard]] constexpr operator id_type() const noexcept { + return value(); + } +}; + +/** + * @brief Type hash. + * @tparam Type Type for which to generate a hash value. + */ +template +struct type_hash final { + /** + * @brief Returns the numeric representation of a given type. + * @return The numeric representation of the given type. + */ +#if defined ENTT_PRETTY_FUNCTION + [[nodiscard]] static constexpr id_type value() noexcept { + return internal::type_hash(0); +#else + [[nodiscard]] static constexpr id_type value() noexcept { + return type_index::value(); +#endif + } + + /*! @copydoc value */ + [[nodiscard]] constexpr operator id_type() const noexcept { + return value(); + } +}; + +/** + * @brief Type name. + * @tparam Type Type for which to generate a name. + */ +template +struct type_name final { + /** + * @brief Returns the name of a given type. + * @return The name of the given type. + */ + [[nodiscard]] static constexpr std::string_view value() noexcept { + return internal::type_name(0); + } + + /*! @copydoc value */ + [[nodiscard]] constexpr operator std::string_view() const noexcept { + return value(); + } +}; + +/*! @brief Implementation specific information about a type. */ +struct type_info final { + /** + * @brief Constructs a type info object for a given type. + * @tparam Type Type for which to construct a type info object. + */ + template + // NOLINTBEGIN(modernize-use-transparent-functors) + constexpr type_info(std::in_place_type_t) noexcept + : seq{type_index>>::value()}, + identifier{type_hash>>::value()}, + alias{type_name>>::value()} {} + // NOLINTEND(modernize-use-transparent-functors) + + /** + * @brief Type index. + * @return Type index. + */ + [[nodiscard]] constexpr id_type index() const noexcept { + return seq; + } + + /** + * @brief Type hash. + * @return Type hash. + */ + [[nodiscard]] constexpr id_type hash() const noexcept { + return identifier; + } + + /** + * @brief Type name. + * @return Type name. + */ + [[nodiscard]] constexpr std::string_view name() const noexcept { + return alias; + } + +private: + id_type seq; + id_type identifier; + std::string_view alias; +}; + +/** + * @brief Compares the contents of two type info objects. + * @param lhs A type info object. + * @param rhs A type info object. + * @return True if the two type info objects are identical, false otherwise. + */ +[[nodiscard]] constexpr bool operator==(const type_info &lhs, const type_info &rhs) noexcept { + return lhs.hash() == rhs.hash(); +} + +/** + * @brief Compares the contents of two type info objects. + * @param lhs A type info object. + * @param rhs A type info object. + * @return True if the two type info objects differ, false otherwise. + */ +[[nodiscard]] constexpr bool operator!=(const type_info &lhs, const type_info &rhs) noexcept { + return !(lhs == rhs); +} + +/** + * @brief Compares two type info objects. + * @param lhs A valid type info object. + * @param rhs A valid type info object. + * @return True if the first element is less than the second, false otherwise. + */ +[[nodiscard]] constexpr bool operator<(const type_info &lhs, const type_info &rhs) noexcept { + return lhs.index() < rhs.index(); +} + +/** + * @brief Compares two type info objects. + * @param lhs A valid type info object. + * @param rhs A valid type info object. + * @return True if the first element is less than or equal to the second, false + * otherwise. + */ +[[nodiscard]] constexpr bool operator<=(const type_info &lhs, const type_info &rhs) noexcept { + return !(rhs < lhs); +} + +/** + * @brief Compares two type info objects. + * @param lhs A valid type info object. + * @param rhs A valid type info object. + * @return True if the first element is greater than the second, false + * otherwise. + */ +[[nodiscard]] constexpr bool operator>(const type_info &lhs, const type_info &rhs) noexcept { + return rhs < lhs; +} + +/** + * @brief Compares two type info objects. + * @param lhs A valid type info object. + * @param rhs A valid type info object. + * @return True if the first element is greater than or equal to the second, + * false otherwise. + */ +[[nodiscard]] constexpr bool operator>=(const type_info &lhs, const type_info &rhs) noexcept { + return !(lhs < rhs); +} + +/** + * @brief Returns the type info object associated to a given type. + * + * The returned element refers to an object with static storage duration.
+ * The type doesn't need to be a complete type. If the type is a reference, the + * result refers to the referenced type. In all cases, top-level cv-qualifiers + * are ignored. + * + * @tparam Type Type for which to generate a type info object. + * @return A reference to a properly initialized type info object. + */ +template +[[nodiscard]] const type_info &type_id() noexcept { + if constexpr(std::is_same_v>>) { + static const type_info instance{std::in_place_type}; + return instance; + } else { + return type_id>>(); + } +} + +/*! @copydoc type_id */ +template +// NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward) +[[nodiscard]] const type_info &type_id(Type &&) noexcept { + return type_id>>(); +} + +} // namespace entt + +#endif + +// #include "core/type_traits.hpp" +#ifndef ENTT_CORE_TYPE_TRAITS_HPP +#define ENTT_CORE_TYPE_TRAITS_HPP + +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "fwd.hpp" + + +namespace entt { + +/** + * @brief Utility class to disambiguate overloaded functions. + * @tparam N Number of choices available. + */ +template +struct choice_t + // unfortunately, doxygen cannot parse such a construct + : /*! @cond TURN_OFF_DOXYGEN */ choice_t /*! @endcond */ +{}; + +/*! @copybrief choice_t */ +template<> +struct choice_t<0> {}; + +/** + * @brief Variable template for the choice trick. + * @tparam N Number of choices available. + */ +template +inline constexpr choice_t choice{}; + +/** + * @brief Identity type trait. + * + * Useful to establish non-deduced contexts in template argument deduction + * (waiting for C++20) or to provide types through function arguments. + * + * @tparam Type A type. + */ +template +struct type_identity { + /*! @brief Identity type. */ + using type = Type; +}; + +/** + * @brief Helper type. + * @tparam Type A type. + */ +template +using type_identity_t = typename type_identity::type; + +/** + * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains. + * @tparam Type The type of which to return the size. + */ +template +struct size_of: std::integral_constant {}; + +/*! @copydoc size_of */ +template +struct size_of> + // NOLINTNEXTLINE(bugprone-sizeof-expression) + : std::integral_constant {}; + +/** + * @brief Helper variable template. + * @tparam Type The type of which to return the size. + */ +template +inline constexpr std::size_t size_of_v = size_of::value; + +/** + * @brief Using declaration to be used to _repeat_ the same type a number of + * times equal to the size of a given parameter pack. + * @tparam Type A type to repeat. + */ +template +using unpack_as_type = Type; + +/** + * @brief Helper variable template to be used to _repeat_ the same value a + * number of times equal to the size of a given parameter pack. + * @tparam Value A value to repeat. + */ +template +inline constexpr auto unpack_as_value = Value; + +/** + * @brief Wraps a static constant. + * @tparam Value A static constant. + */ +template +using integral_constant = std::integral_constant; + +/** + * @brief Alias template to facilitate the creation of named values. + * @tparam Value A constant value at least convertible to `id_type`. + */ +template +using tag = integral_constant; + +/** + * @brief A class to use to push around lists of types, nothing more. + * @tparam Type Types provided by the type list. + */ +template +struct type_list { + /*! @brief Type list type. */ + using type = type_list; + /*! @brief Compile-time number of elements in the type list. */ + static constexpr auto size = sizeof...(Type); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_element; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Index Index of the type to return. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element> + : type_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element<0u, type_list> { + /*! @brief Searched type. */ + using type = First; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Type list to search into. + */ +template +using type_list_element_t = typename type_list_element::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_index; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 1u + type_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + static_assert(type_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +inline constexpr std::size_t type_list_index_v = type_list_index::value; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @return A type list composed by the types of both the type lists. + */ +template +constexpr type_list operator+(type_list, type_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_cat; + +/*! @brief Concatenates multiple type lists. */ +template<> +struct type_list_cat<> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list<>; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @tparam List Other type lists, if any. + */ +template +struct type_list_cat, type_list, List...> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = typename type_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the type list. + */ +template +struct type_list_cat> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list; +}; + +/** + * @brief Helper type. + * @tparam List Type lists to concatenate. + */ +template +using type_list_cat_t = typename type_list_cat::type; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct type_list_unique; + +template +struct type_list_unique, Type...> + : std::conditional_t<(std::is_same_v || ...), type_list_unique, Type...>, type_list_unique, Type..., First>> {}; + +template +struct type_list_unique, Type...> { + using type = type_list; +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Removes duplicates types from a type list. + * @tparam List Type list. + */ +template +struct type_list_unique { + /*! @brief A type list without duplicate types. */ + using type = typename internal::type_list_unique::type; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + */ +template +using type_list_unique_t = typename type_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a type list contains a + * given type, false otherwise. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +struct type_list_contains; + +/** + * @copybrief type_list_contains + * @tparam Type Types provided by the type list. + * @tparam Other Type to look for. + */ +template +struct type_list_contains, Other> + : std::bool_constant<(std::is_same_v || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +inline constexpr bool type_list_contains_v = type_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_diff; + +/** + * @brief Computes the difference between two type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + */ +template +struct type_list_diff, type_list> { + /*! @brief A type list that is the difference between the two type lists. */ + using type = type_list_cat_t, Type>, type_list<>, type_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Type lists between which to compute the difference. + */ +template +using type_list_diff_t = typename type_list_diff::type; + +/*! @brief Primary template isn't defined on purpose. */ +template class> +struct type_list_transform; + +/** + * @brief Applies a given _function_ to a type list and generate a new list. + * @tparam Type Types provided by the type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +struct type_list_transform, Op> { + /*! @brief Resulting type list after applying the transform function. */ + // NOLINTNEXTLINE(modernize-type-traits) + using type = type_list::type...>; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +using type_list_transform_t = typename type_list_transform::type; + +/** + * @brief A class to use to push around lists of constant values, nothing more. + * @tparam Value Values provided by the value list. + */ +template +struct value_list { + /*! @brief Value list type. */ + using type = value_list; + /*! @brief Compile-time number of elements in the value list. */ + static constexpr auto size = sizeof...(Value); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_element; + +/** + * @brief Provides compile-time indexed access to the values of a value list. + * @tparam Index Index of the value to return. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element> + : value_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element<0u, value_list> { + /*! @brief Searched type. */ + using type = decltype(Value); + /*! @brief Searched value. */ + static constexpr auto value = Value; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Value list to search into. + */ +template +using value_list_element_t = typename value_list_element::type; + +/** + * @brief Helper type. + * @tparam Index Index of the value to return. + * @tparam List Value list to search into. + */ +template +inline constexpr auto value_list_element_v = value_list_element::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_index; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam First First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 1u + value_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + static_assert(value_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +inline constexpr std::size_t value_list_index_v = value_list_index::value; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @return A value list composed by the values of both the value lists. + */ +template +constexpr value_list operator+(value_list, value_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_cat; + +/*! @brief Concatenates multiple value lists. */ +template<> +struct value_list_cat<> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list<>; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @tparam List Other value lists, if any. + */ +template +struct value_list_cat, value_list, List...> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = typename value_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the value list. + */ +template +struct value_list_cat> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list; +}; + +/** + * @brief Helper type. + * @tparam List Value lists to concatenate. + */ +template +using value_list_cat_t = typename value_list_cat::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_unique; + +/** + * @brief Removes duplicates values from a value list. + * @tparam Value One of the values provided by the given value list. + * @tparam Other The other values provided by the given value list. + */ +template +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = std::conditional_t< + ((Value == Other) || ...), + typename value_list_unique>::type, + value_list_cat_t, typename value_list_unique>::type>>; +}; + +/*! @brief Removes duplicates values from a value list. */ +template<> +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = value_list<>; +}; + +/** + * @brief Helper type. + * @tparam Type A value list. + */ +template +using value_list_unique_t = typename value_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a value list contains + * a given value, false otherwise. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +struct value_list_contains; + +/** + * @copybrief value_list_contains + * @tparam Value Values provided by the value list. + * @tparam Other Value to look for. + */ +template +struct value_list_contains, Other> + : std::bool_constant<((Value == Other) || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +inline constexpr bool value_list_contains_v = value_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_diff; + +/** + * @brief Computes the difference between two value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + */ +template +struct value_list_diff, value_list> { + /*! @brief A value list that is the difference between the two value lists. */ + using type = value_list_cat_t, Value>, value_list<>, value_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Value lists between which to compute the difference. + */ +template +using value_list_diff_t = typename value_list_diff::type; + +/*! @brief Same as std::is_invocable, but with tuples. */ +template +struct is_applicable: std::false_type {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @brief Helper variable template. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_v = is_applicable::value; + +/*! @brief Same as std::is_invocable_r, but with tuples for arguments. */ +template +struct is_applicable_r: std::false_type {}; + +/** + * @copybrief is_applicable_r + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +struct is_applicable_r>: std::is_invocable_r {}; + +/** + * @brief Helper variable template. + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_r_v = is_applicable_r::value; + +/** + * @brief Provides the member constant `value` to true if a given type is + * complete, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_complete: std::false_type {}; + +/*! @copydoc is_complete */ +template +struct is_complete>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_complete_v = is_complete::value; + +/** + * @brief Provides the member constant `value` to true if a given type is an + * iterator, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_iterator: std::false_type {}; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_iterator_category: std::false_type {}; + +template +struct has_iterator_category::iterator_category>>: std::true_type {}; + +} // namespace internal +/*! @endcond */ + +/*! @copydoc is_iterator */ +template +struct is_iterator>>>> + : internal::has_iterator_category {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_iterator_v = is_iterator::value; + +/** + * @brief Provides the member constant `value` to true if a given type is both + * an empty and non-final class, false otherwise. + * @tparam Type The type to test + */ +template +struct is_ebco_eligible + : std::bool_constant && !std::is_final_v> {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_ebco_eligible_v = is_ebco_eligible::value; + +/** + * @brief Provides the member constant `value` to true if `Type::is_transparent` + * is valid and denotes a type, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_transparent: std::false_type {}; + +/*! @copydoc is_transparent */ +template +struct is_transparent>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_transparent_v = is_transparent::value; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_tuple_size_value: std::false_type {}; + +template +struct has_tuple_size_value::value)>>: std::true_type {}; + +template +struct has_value_type: std::false_type {}; + +template +struct has_value_type>: std::true_type {}; + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable(); + +template +[[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence) { + return (dispatch_is_equality_comparable>() && ...); +} + +template +[[nodiscard]] constexpr bool maybe_equality_comparable(char) { + return false; +} + +template +[[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval() == std::declval()) { + return true; +} + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable() { + // NOLINTBEGIN(modernize-use-transparent-functors) + if constexpr(std::is_array_v) { + return false; + } else if constexpr(is_complete_v>>) { + if constexpr(has_tuple_size_value::value) { + return maybe_equality_comparable(0) && unpack_maybe_equality_comparable(std::make_index_sequence::value>{}); + } else { + return maybe_equality_comparable(0); + } + } else if constexpr(has_value_type::value) { + if constexpr(is_iterator_v || std::is_same_v || dispatch_is_equality_comparable()) { + return maybe_equality_comparable(0); + } else { + return false; + } + } else { + return maybe_equality_comparable(0); + } + // NOLINTEND(modernize-use-transparent-functors) +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Provides the member constant `value` to true if a given type is + * equality comparable, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_equality_comparable: std::bool_constant()> {}; + +/*! @copydoc is_equality_comparable */ +template +struct is_equality_comparable: is_equality_comparable {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_equality_comparable_v = is_equality_comparable::value; + +/** + * @brief Transcribes the constness of a type to another type. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = std::remove_const_t; +}; + +/*! @copydoc constness_as */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = const To; +}; + +/** + * @brief Alias template to facilitate the transcription of the constness. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +using constness_as_t = typename constness_as::type; + +/** + * @brief Extracts the class of a non-static member object or function. + * @tparam Member A pointer to a non-static member object or function. + */ +template +class member_class { + static_assert(std::is_member_pointer_v, "Invalid pointer type to non-static member object or function"); + + template + static Class *clazz(Ret (Class::*)(Args...)); + + template + static Class *clazz(Ret (Class::*)(Args...) const); + + template + static Class *clazz(Type Class::*); + +public: + /*! @brief The class of the given non-static member object or function. */ + using type = std::remove_pointer_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Member A pointer to a non-static member object or function. + */ +template +using member_class_t = typename member_class::type; + +/** + * @brief Extracts the n-th argument of a _callable_ type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid _callable_ type. + */ +template +class nth_argument { + template + static constexpr type_list pick_up(Ret (*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...) const); + + template + static constexpr type_list pick_up(Type Class ::*); + + template + static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&); + +public: + /*! @brief N-th argument of the _callable_ type. */ + using type = type_list_element_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid function, member function or data member type. + */ +template +using nth_argument_t = typename nth_argument::type; + +} // namespace entt + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::type_list_element> {}; + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::value_list_element> {}; + +#endif + +// #include "core/utility.hpp" +#ifndef ENTT_CORE_UTILITY_HPP +#define ENTT_CORE_UTILITY_HPP + +#include +#include + +namespace entt { + +/*! @brief Identity function object (waiting for C++20). */ +struct identity { + /*! @brief Indicates that this is a transparent function object. */ + using is_transparent = void; + + /** + * @brief Returns its argument unchanged. + * @tparam Type Type of the argument. + * @param value The actual argument. + * @return The submitted value as-is. + */ + template + [[nodiscard]] constexpr Type &&operator()(Type &&value) const noexcept { + return std::forward(value); + } +}; + +/** + * @brief Constant utility to disambiguate overloaded members of a class. + * @tparam Type Type of the desired overload. + * @tparam Class Type of class to which the member belongs. + * @param member A valid pointer to a member. + * @return Pointer to the member. + */ +template +[[nodiscard]] constexpr auto overload(Type Class::*member) noexcept { + return member; +} + +/** + * @brief Constant utility to disambiguate overloaded functions. + * @tparam Func Function type of the desired overload. + * @param func A valid pointer to a function. + * @return Pointer to the function. + */ +template +[[nodiscard]] constexpr auto overload(Func *func) noexcept { + return func; +} + +/** + * @brief Helper type for visitors. + * @tparam Func Types of function objects. + */ +template +struct overloaded: Func... { + using Func::operator()...; +}; + +/** + * @brief Deduction guide. + * @tparam Func Types of function objects. + */ +template +overloaded(Func...) -> overloaded; + +/** + * @brief Basic implementation of a y-combinator. + * @tparam Func Type of a potentially recursive function. + */ +template +struct y_combinator { + /** + * @brief Constructs a y-combinator from a given function. + * @param recursive A potentially recursive function. + */ + constexpr y_combinator(Func recursive) noexcept(std::is_nothrow_move_constructible_v) + : func{std::move(recursive)} {} + + /** + * @brief Invokes a y-combinator and therefore its underlying function. + * @tparam Args Types of arguments to use to invoke the underlying function. + * @param args Parameters to use to invoke the underlying function. + * @return Return value of the underlying function, if any. + */ + template + constexpr decltype(auto) operator()(Args &&...args) const noexcept(std::is_nothrow_invocable_v) { + return func(*this, std::forward(args)...); + } + + /*! @copydoc operator()() */ + template + constexpr decltype(auto) operator()(Args &&...args) noexcept(std::is_nothrow_invocable_v) { + return func(*this, std::forward(args)...); + } + +private: + Func func; +}; + +} // namespace entt + +#endif + +// #include "entity/component.hpp" +#ifndef ENTT_ENTITY_COMPONENT_HPP +#define ENTT_ENTITY_COMPONENT_HPP + +#include +#include +// #include "../config/config.h" +#ifndef ENTT_CONFIG_CONFIG_H +#define ENTT_CONFIG_CONFIG_H + +// #include "version.h" +#ifndef ENTT_CONFIG_VERSION_H +#define ENTT_CONFIG_VERSION_H + +// #include "macro.h" +#ifndef ENTT_CONFIG_MACRO_H +#define ENTT_CONFIG_MACRO_H + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#define ENTT_STR(arg) #arg +#define ENTT_XSTR(arg) ENTT_STR(arg) + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*) + +#define ENTT_VERSION_MAJOR 3 +#define ENTT_VERSION_MINOR 16 +#define ENTT_VERSION_PATCH 0 + +#define ENTT_VERSION \ + ENTT_XSTR(ENTT_VERSION_MAJOR) \ + "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH) + +// NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION) +# define ENTT_CONSTEXPR +# define ENTT_THROW throw +# define ENTT_TRY try +# define ENTT_CATCH catch(...) +#else +# define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20) +# define ENTT_THROW +# define ENTT_TRY if(true) +# define ENTT_CATCH if(false) +#endif + +#if __has_include() +# include +# +# if defined(__cpp_consteval) +# define ENTT_CONSTEVAL consteval +# endif +#endif + +#ifndef ENTT_CONSTEVAL +# define ENTT_CONSTEVAL constexpr +#endif + +#ifdef ENTT_USE_ATOMIC +# include +# define ENTT_MAYBE_ATOMIC(Type) std::atomic +#else +# define ENTT_MAYBE_ATOMIC(Type) Type +#endif + +#ifndef ENTT_ID_TYPE +# include +# define ENTT_ID_TYPE std::uint32_t +#else +# include // provides coverage for types in the std namespace +#endif + +#ifndef ENTT_SPARSE_PAGE +# define ENTT_SPARSE_PAGE 4096 +#endif + +#ifndef ENTT_PACKED_PAGE +# define ENTT_PACKED_PAGE 1024 +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT +# define ENTT_ASSERT(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT +# include +# define ENTT_ASSERT(condition, msg) assert(((condition) && (msg))) +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg) +#endif + +#define ENTT_FAIL(msg) ENTT_ASSERT(false, msg); + +#ifdef ENTT_NO_ETO +# define ENTT_ETO_TYPE(Type) void +#else +# define ENTT_ETO_TYPE(Type) Type +#endif + +#ifdef ENTT_NO_MIXIN +# define ENTT_STORAGE(Mixin, ...) __VA_ARGS__ +#else +# define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__> +#endif + +#ifdef ENTT_STANDARD_CPP +# define ENTT_NONSTD false +#else +# define ENTT_NONSTD true +# if defined __clang__ || defined __GNUC__ +# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ +# define ENTT_PRETTY_FUNCTION_PREFIX '=' +# define ENTT_PRETTY_FUNCTION_SUFFIX ']' +# elif defined _MSC_VER +# define ENTT_PRETTY_FUNCTION __FUNCSIG__ +# define ENTT_PRETTY_FUNCTION_PREFIX '<' +# define ENTT_PRETTY_FUNCTION_SUFFIX '>' +# endif +#endif + +#ifndef ENTT_EXPORT +# if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER +# define ENTT_EXPORT __declspec(dllexport) +# define ENTT_IMPORT __declspec(dllimport) +# define ENTT_HIDDEN +# elif defined __GNUC__ && __GNUC__ >= 4 +# define ENTT_EXPORT __attribute__((visibility("default"))) +# define ENTT_IMPORT __attribute__((visibility("default"))) +# define ENTT_HIDDEN __attribute__((visibility("hidden"))) +# else /* Unsupported compiler */ +# define ENTT_EXPORT +# define ENTT_IMPORT +# define ENTT_HIDDEN +# endif +#endif + +#ifndef ENTT_API +# if defined ENTT_API_EXPORT +# define ENTT_API ENTT_EXPORT +# elif defined ENTT_API_IMPORT +# define ENTT_API ENTT_IMPORT +# else /* No API */ +# define ENTT_API +# endif +#endif + +#if defined _MSC_VER +# pragma detect_mismatch("entt.version", ENTT_VERSION) +# pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY)) +# pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE)) +# pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD)) +#endif + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + +// #include "fwd.hpp" +#ifndef ENTT_ENTITY_FWD_HPP +#define ENTT_ENTITY_FWD_HPP + +#include +#include +#include +// #include "../config/config.h" + +// #include "../core/fwd.hpp" +#ifndef ENTT_CORE_FWD_HPP +#define ENTT_CORE_FWD_HPP + +#include +#include +// #include "../config/config.h" +#ifndef ENTT_CONFIG_CONFIG_H +#define ENTT_CONFIG_CONFIG_H + +// #include "version.h" +#ifndef ENTT_CONFIG_VERSION_H +#define ENTT_CONFIG_VERSION_H + +// #include "macro.h" +#ifndef ENTT_CONFIG_MACRO_H +#define ENTT_CONFIG_MACRO_H + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#define ENTT_STR(arg) #arg +#define ENTT_XSTR(arg) ENTT_STR(arg) + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*) + +#define ENTT_VERSION_MAJOR 3 +#define ENTT_VERSION_MINOR 16 +#define ENTT_VERSION_PATCH 0 + +#define ENTT_VERSION \ + ENTT_XSTR(ENTT_VERSION_MAJOR) \ + "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH) + +// NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION) +# define ENTT_CONSTEXPR +# define ENTT_THROW throw +# define ENTT_TRY try +# define ENTT_CATCH catch(...) +#else +# define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20) +# define ENTT_THROW +# define ENTT_TRY if(true) +# define ENTT_CATCH if(false) +#endif + +#if __has_include() +# include +# +# if defined(__cpp_consteval) +# define ENTT_CONSTEVAL consteval +# endif +#endif + +#ifndef ENTT_CONSTEVAL +# define ENTT_CONSTEVAL constexpr +#endif + +#ifdef ENTT_USE_ATOMIC +# include +# define ENTT_MAYBE_ATOMIC(Type) std::atomic +#else +# define ENTT_MAYBE_ATOMIC(Type) Type +#endif + +#ifndef ENTT_ID_TYPE +# include +# define ENTT_ID_TYPE std::uint32_t +#else +# include // provides coverage for types in the std namespace +#endif + +#ifndef ENTT_SPARSE_PAGE +# define ENTT_SPARSE_PAGE 4096 +#endif + +#ifndef ENTT_PACKED_PAGE +# define ENTT_PACKED_PAGE 1024 +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT +# define ENTT_ASSERT(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT +# include +# define ENTT_ASSERT(condition, msg) assert(((condition) && (msg))) +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg) +#endif + +#define ENTT_FAIL(msg) ENTT_ASSERT(false, msg); + +#ifdef ENTT_NO_ETO +# define ENTT_ETO_TYPE(Type) void +#else +# define ENTT_ETO_TYPE(Type) Type +#endif + +#ifdef ENTT_NO_MIXIN +# define ENTT_STORAGE(Mixin, ...) __VA_ARGS__ +#else +# define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__> +#endif + +#ifdef ENTT_STANDARD_CPP +# define ENTT_NONSTD false +#else +# define ENTT_NONSTD true +# if defined __clang__ || defined __GNUC__ +# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ +# define ENTT_PRETTY_FUNCTION_PREFIX '=' +# define ENTT_PRETTY_FUNCTION_SUFFIX ']' +# elif defined _MSC_VER +# define ENTT_PRETTY_FUNCTION __FUNCSIG__ +# define ENTT_PRETTY_FUNCTION_PREFIX '<' +# define ENTT_PRETTY_FUNCTION_SUFFIX '>' +# endif +#endif + +#ifndef ENTT_EXPORT +# if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER +# define ENTT_EXPORT __declspec(dllexport) +# define ENTT_IMPORT __declspec(dllimport) +# define ENTT_HIDDEN +# elif defined __GNUC__ && __GNUC__ >= 4 +# define ENTT_EXPORT __attribute__((visibility("default"))) +# define ENTT_IMPORT __attribute__((visibility("default"))) +# define ENTT_HIDDEN __attribute__((visibility("hidden"))) +# else /* Unsupported compiler */ +# define ENTT_EXPORT +# define ENTT_IMPORT +# define ENTT_HIDDEN +# endif +#endif + +#ifndef ENTT_API +# if defined ENTT_API_EXPORT +# define ENTT_API ENTT_EXPORT +# elif defined ENTT_API_IMPORT +# define ENTT_API ENTT_IMPORT +# else /* No API */ +# define ENTT_API +# endif +#endif + +#if defined _MSC_VER +# pragma detect_mismatch("entt.version", ENTT_VERSION) +# pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY)) +# pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE)) +# pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD)) +#endif + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +namespace entt { + +/*! @brief Possible modes of an any object. */ +enum class any_policy : std::uint8_t { + /*! @brief Default mode, no element available. */ + empty, + /*! @brief Owning mode, dynamically allocated element. */ + dynamic, + /*! @brief Owning mode, embedded element. */ + embedded, + /*! @brief Aliasing mode, non-const reference. */ + ref, + /*! @brief Const aliasing mode, const reference. */ + cref +}; + +// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) +template +class basic_any; + +/*! @brief Alias declaration for type identifiers. */ +using id_type = ENTT_ID_TYPE; + +/*! @brief Alias declaration for the most common use case. */ +using any = basic_any<>; + +template +class compressed_pair; + +template +class basic_hashed_string; + +/*! @brief Aliases for common character types. */ +using hashed_string = basic_hashed_string; + +/*! @brief Aliases for common character types. */ +using hashed_wstring = basic_hashed_string; + +// NOLINTNEXTLINE(bugprone-forward-declaration-namespace) +struct type_info; + +} // namespace entt + +#endif + +// #include "../core/type_traits.hpp" +#ifndef ENTT_CORE_TYPE_TRAITS_HPP +#define ENTT_CORE_TYPE_TRAITS_HPP + +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "fwd.hpp" +#ifndef ENTT_CORE_FWD_HPP +#define ENTT_CORE_FWD_HPP + +#include +#include +// #include "../config/config.h" + + +namespace entt { + +/*! @brief Possible modes of an any object. */ +enum class any_policy : std::uint8_t { + /*! @brief Default mode, no element available. */ + empty, + /*! @brief Owning mode, dynamically allocated element. */ + dynamic, + /*! @brief Owning mode, embedded element. */ + embedded, + /*! @brief Aliasing mode, non-const reference. */ + ref, + /*! @brief Const aliasing mode, const reference. */ + cref +}; + +// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) +template +class basic_any; + +/*! @brief Alias declaration for type identifiers. */ +using id_type = ENTT_ID_TYPE; + +/*! @brief Alias declaration for the most common use case. */ +using any = basic_any<>; + +template +class compressed_pair; + +template +class basic_hashed_string; + +/*! @brief Aliases for common character types. */ +using hashed_string = basic_hashed_string; + +/*! @brief Aliases for common character types. */ +using hashed_wstring = basic_hashed_string; + +// NOLINTNEXTLINE(bugprone-forward-declaration-namespace) +struct type_info; + +} // namespace entt + +#endif + + +namespace entt { + +/** + * @brief Utility class to disambiguate overloaded functions. + * @tparam N Number of choices available. + */ +template +struct choice_t + // unfortunately, doxygen cannot parse such a construct + : /*! @cond TURN_OFF_DOXYGEN */ choice_t /*! @endcond */ +{}; + +/*! @copybrief choice_t */ +template<> +struct choice_t<0> {}; + +/** + * @brief Variable template for the choice trick. + * @tparam N Number of choices available. + */ +template +inline constexpr choice_t choice{}; + +/** + * @brief Identity type trait. + * + * Useful to establish non-deduced contexts in template argument deduction + * (waiting for C++20) or to provide types through function arguments. + * + * @tparam Type A type. + */ +template +struct type_identity { + /*! @brief Identity type. */ + using type = Type; +}; + +/** + * @brief Helper type. + * @tparam Type A type. + */ +template +using type_identity_t = typename type_identity::type; + +/** + * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains. + * @tparam Type The type of which to return the size. + */ +template +struct size_of: std::integral_constant {}; + +/*! @copydoc size_of */ +template +struct size_of> + // NOLINTNEXTLINE(bugprone-sizeof-expression) + : std::integral_constant {}; + +/** + * @brief Helper variable template. + * @tparam Type The type of which to return the size. + */ +template +inline constexpr std::size_t size_of_v = size_of::value; + +/** + * @brief Using declaration to be used to _repeat_ the same type a number of + * times equal to the size of a given parameter pack. + * @tparam Type A type to repeat. + */ +template +using unpack_as_type = Type; + +/** + * @brief Helper variable template to be used to _repeat_ the same value a + * number of times equal to the size of a given parameter pack. + * @tparam Value A value to repeat. + */ +template +inline constexpr auto unpack_as_value = Value; + +/** + * @brief Wraps a static constant. + * @tparam Value A static constant. + */ +template +using integral_constant = std::integral_constant; + +/** + * @brief Alias template to facilitate the creation of named values. + * @tparam Value A constant value at least convertible to `id_type`. + */ +template +using tag = integral_constant; + +/** + * @brief A class to use to push around lists of types, nothing more. + * @tparam Type Types provided by the type list. + */ +template +struct type_list { + /*! @brief Type list type. */ + using type = type_list; + /*! @brief Compile-time number of elements in the type list. */ + static constexpr auto size = sizeof...(Type); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_element; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Index Index of the type to return. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element> + : type_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element<0u, type_list> { + /*! @brief Searched type. */ + using type = First; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Type list to search into. + */ +template +using type_list_element_t = typename type_list_element::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_index; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 1u + type_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + static_assert(type_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +inline constexpr std::size_t type_list_index_v = type_list_index::value; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @return A type list composed by the types of both the type lists. + */ +template +constexpr type_list operator+(type_list, type_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_cat; + +/*! @brief Concatenates multiple type lists. */ +template<> +struct type_list_cat<> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list<>; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @tparam List Other type lists, if any. + */ +template +struct type_list_cat, type_list, List...> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = typename type_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the type list. + */ +template +struct type_list_cat> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list; +}; + +/** + * @brief Helper type. + * @tparam List Type lists to concatenate. + */ +template +using type_list_cat_t = typename type_list_cat::type; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct type_list_unique; + +template +struct type_list_unique, Type...> + : std::conditional_t<(std::is_same_v || ...), type_list_unique, Type...>, type_list_unique, Type..., First>> {}; + +template +struct type_list_unique, Type...> { + using type = type_list; +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Removes duplicates types from a type list. + * @tparam List Type list. + */ +template +struct type_list_unique { + /*! @brief A type list without duplicate types. */ + using type = typename internal::type_list_unique::type; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + */ +template +using type_list_unique_t = typename type_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a type list contains a + * given type, false otherwise. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +struct type_list_contains; + +/** + * @copybrief type_list_contains + * @tparam Type Types provided by the type list. + * @tparam Other Type to look for. + */ +template +struct type_list_contains, Other> + : std::bool_constant<(std::is_same_v || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +inline constexpr bool type_list_contains_v = type_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_diff; + +/** + * @brief Computes the difference between two type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + */ +template +struct type_list_diff, type_list> { + /*! @brief A type list that is the difference between the two type lists. */ + using type = type_list_cat_t, Type>, type_list<>, type_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Type lists between which to compute the difference. + */ +template +using type_list_diff_t = typename type_list_diff::type; + +/*! @brief Primary template isn't defined on purpose. */ +template class> +struct type_list_transform; + +/** + * @brief Applies a given _function_ to a type list and generate a new list. + * @tparam Type Types provided by the type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +struct type_list_transform, Op> { + /*! @brief Resulting type list after applying the transform function. */ + // NOLINTNEXTLINE(modernize-type-traits) + using type = type_list::type...>; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +using type_list_transform_t = typename type_list_transform::type; + +/** + * @brief A class to use to push around lists of constant values, nothing more. + * @tparam Value Values provided by the value list. + */ +template +struct value_list { + /*! @brief Value list type. */ + using type = value_list; + /*! @brief Compile-time number of elements in the value list. */ + static constexpr auto size = sizeof...(Value); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_element; + +/** + * @brief Provides compile-time indexed access to the values of a value list. + * @tparam Index Index of the value to return. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element> + : value_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element<0u, value_list> { + /*! @brief Searched type. */ + using type = decltype(Value); + /*! @brief Searched value. */ + static constexpr auto value = Value; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Value list to search into. + */ +template +using value_list_element_t = typename value_list_element::type; + +/** + * @brief Helper type. + * @tparam Index Index of the value to return. + * @tparam List Value list to search into. + */ +template +inline constexpr auto value_list_element_v = value_list_element::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_index; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam First First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 1u + value_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + static_assert(value_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +inline constexpr std::size_t value_list_index_v = value_list_index::value; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @return A value list composed by the values of both the value lists. + */ +template +constexpr value_list operator+(value_list, value_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_cat; + +/*! @brief Concatenates multiple value lists. */ +template<> +struct value_list_cat<> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list<>; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @tparam List Other value lists, if any. + */ +template +struct value_list_cat, value_list, List...> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = typename value_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the value list. + */ +template +struct value_list_cat> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list; +}; + +/** + * @brief Helper type. + * @tparam List Value lists to concatenate. + */ +template +using value_list_cat_t = typename value_list_cat::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_unique; + +/** + * @brief Removes duplicates values from a value list. + * @tparam Value One of the values provided by the given value list. + * @tparam Other The other values provided by the given value list. + */ +template +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = std::conditional_t< + ((Value == Other) || ...), + typename value_list_unique>::type, + value_list_cat_t, typename value_list_unique>::type>>; +}; + +/*! @brief Removes duplicates values from a value list. */ +template<> +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = value_list<>; +}; + +/** + * @brief Helper type. + * @tparam Type A value list. + */ +template +using value_list_unique_t = typename value_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a value list contains + * a given value, false otherwise. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +struct value_list_contains; + +/** + * @copybrief value_list_contains + * @tparam Value Values provided by the value list. + * @tparam Other Value to look for. + */ +template +struct value_list_contains, Other> + : std::bool_constant<((Value == Other) || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +inline constexpr bool value_list_contains_v = value_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_diff; + +/** + * @brief Computes the difference between two value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + */ +template +struct value_list_diff, value_list> { + /*! @brief A value list that is the difference between the two value lists. */ + using type = value_list_cat_t, Value>, value_list<>, value_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Value lists between which to compute the difference. + */ +template +using value_list_diff_t = typename value_list_diff::type; + +/*! @brief Same as std::is_invocable, but with tuples. */ +template +struct is_applicable: std::false_type {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @brief Helper variable template. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_v = is_applicable::value; + +/*! @brief Same as std::is_invocable_r, but with tuples for arguments. */ +template +struct is_applicable_r: std::false_type {}; + +/** + * @copybrief is_applicable_r + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +struct is_applicable_r>: std::is_invocable_r {}; + +/** + * @brief Helper variable template. + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_r_v = is_applicable_r::value; + +/** + * @brief Provides the member constant `value` to true if a given type is + * complete, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_complete: std::false_type {}; + +/*! @copydoc is_complete */ +template +struct is_complete>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_complete_v = is_complete::value; + +/** + * @brief Provides the member constant `value` to true if a given type is an + * iterator, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_iterator: std::false_type {}; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_iterator_category: std::false_type {}; + +template +struct has_iterator_category::iterator_category>>: std::true_type {}; + +} // namespace internal +/*! @endcond */ + +/*! @copydoc is_iterator */ +template +struct is_iterator>>>> + : internal::has_iterator_category {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_iterator_v = is_iterator::value; + +/** + * @brief Provides the member constant `value` to true if a given type is both + * an empty and non-final class, false otherwise. + * @tparam Type The type to test + */ +template +struct is_ebco_eligible + : std::bool_constant && !std::is_final_v> {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_ebco_eligible_v = is_ebco_eligible::value; + +/** + * @brief Provides the member constant `value` to true if `Type::is_transparent` + * is valid and denotes a type, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_transparent: std::false_type {}; + +/*! @copydoc is_transparent */ +template +struct is_transparent>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_transparent_v = is_transparent::value; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_tuple_size_value: std::false_type {}; + +template +struct has_tuple_size_value::value)>>: std::true_type {}; + +template +struct has_value_type: std::false_type {}; + +template +struct has_value_type>: std::true_type {}; + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable(); + +template +[[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence) { + return (dispatch_is_equality_comparable>() && ...); +} + +template +[[nodiscard]] constexpr bool maybe_equality_comparable(char) { + return false; +} + +template +[[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval() == std::declval()) { + return true; +} + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable() { + // NOLINTBEGIN(modernize-use-transparent-functors) + if constexpr(std::is_array_v) { + return false; + } else if constexpr(is_complete_v>>) { + if constexpr(has_tuple_size_value::value) { + return maybe_equality_comparable(0) && unpack_maybe_equality_comparable(std::make_index_sequence::value>{}); + } else { + return maybe_equality_comparable(0); + } + } else if constexpr(has_value_type::value) { + if constexpr(is_iterator_v || std::is_same_v || dispatch_is_equality_comparable()) { + return maybe_equality_comparable(0); + } else { + return false; + } + } else { + return maybe_equality_comparable(0); + } + // NOLINTEND(modernize-use-transparent-functors) +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Provides the member constant `value` to true if a given type is + * equality comparable, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_equality_comparable: std::bool_constant()> {}; + +/*! @copydoc is_equality_comparable */ +template +struct is_equality_comparable: is_equality_comparable {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_equality_comparable_v = is_equality_comparable::value; + +/** + * @brief Transcribes the constness of a type to another type. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = std::remove_const_t; +}; + +/*! @copydoc constness_as */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = const To; +}; + +/** + * @brief Alias template to facilitate the transcription of the constness. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +using constness_as_t = typename constness_as::type; + +/** + * @brief Extracts the class of a non-static member object or function. + * @tparam Member A pointer to a non-static member object or function. + */ +template +class member_class { + static_assert(std::is_member_pointer_v, "Invalid pointer type to non-static member object or function"); + + template + static Class *clazz(Ret (Class::*)(Args...)); + + template + static Class *clazz(Ret (Class::*)(Args...) const); + + template + static Class *clazz(Type Class::*); + +public: + /*! @brief The class of the given non-static member object or function. */ + using type = std::remove_pointer_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Member A pointer to a non-static member object or function. + */ +template +using member_class_t = typename member_class::type; + +/** + * @brief Extracts the n-th argument of a _callable_ type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid _callable_ type. + */ +template +class nth_argument { + template + static constexpr type_list pick_up(Ret (*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...) const); + + template + static constexpr type_list pick_up(Type Class ::*); + + template + static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&); + +public: + /*! @brief N-th argument of the _callable_ type. */ + using type = type_list_element_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid function, member function or data member type. + */ +template +using nth_argument_t = typename nth_argument::type; + +} // namespace entt + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::type_list_element> {}; + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::value_list_element> {}; + +#endif + + +namespace entt { + +/*! @brief Default entity identifier. */ +enum class entity : id_type {}; + +/*! @brief Storage deletion policy. */ +enum class deletion_policy : std::uint8_t { + /*! @brief Swap-and-pop deletion policy. */ + swap_and_pop = 0u, + /*! @brief In-place deletion policy. */ + in_place = 1u, + /*! @brief Swap-only deletion policy. */ + swap_only = 2u, + /*! @brief Unspecified deletion policy. */ + unspecified = swap_and_pop +}; + +template +struct component_traits; + +template> +class basic_sparse_set; + +template, typename = void> +class basic_storage; + +template +class basic_sigh_mixin; + +template +class basic_reactive_mixin; + +template> +class basic_registry; + +template +class basic_view; + +template> +class basic_runtime_view; + +template +class basic_group; + +template +class basic_organizer; + +template +class basic_handle; + +template +class basic_snapshot; + +template +class basic_snapshot_loader; + +template +class basic_continuous_loader; + +/*! @brief Alias declaration for the most common use case. */ +using sparse_set = basic_sparse_set<>; + +/** + * @brief Alias declaration for the most common use case. + * @tparam Type Element type. + */ +template +using storage = basic_storage; + +/** + * @brief Alias declaration for the most common use case. + * @tparam Type Underlying storage type. + */ +template +using sigh_mixin = basic_sigh_mixin>; + +/** + * @brief Alias declaration for the most common use case. + * @tparam Type Underlying storage type. + */ +template +using reactive_mixin = basic_reactive_mixin>; + +/*! @brief Alias declaration for the most common use case. */ +using registry = basic_registry<>; + +/*! @brief Alias declaration for the most common use case. */ +using organizer = basic_organizer; + +/*! @brief Alias declaration for the most common use case. */ +using handle = basic_handle; + +/*! @brief Alias declaration for the most common use case. */ +using const_handle = basic_handle; + +/** + * @brief Alias declaration for the most common use case. + * @tparam Args Other template parameters. + */ +template +using handle_view = basic_handle; + +/** + * @brief Alias declaration for the most common use case. + * @tparam Args Other template parameters. + */ +template +using const_handle_view = basic_handle; + +/*! @brief Alias declaration for the most common use case. */ +using snapshot = basic_snapshot; + +/*! @brief Alias declaration for the most common use case. */ +using snapshot_loader = basic_snapshot_loader; + +/*! @brief Alias declaration for the most common use case. */ +using continuous_loader = basic_continuous_loader; + +/*! @brief Alias declaration for the most common use case. */ +using runtime_view = basic_runtime_view; + +/*! @brief Alias declaration for the most common use case. */ +using const_runtime_view = basic_runtime_view; + +/** + * @brief Alias for exclusion lists. + * @tparam Type List of types. + */ +template +struct exclude_t final: type_list { + /*! @brief Default constructor. */ + explicit constexpr exclude_t() = default; +}; + +/** + * @brief Variable template for exclusion lists. + * @tparam Type List of types. + */ +template +inline constexpr exclude_t exclude{}; + +/** + * @brief Alias for lists of observed elements. + * @tparam Type List of types. + */ +template +struct get_t final: type_list { + /*! @brief Default constructor. */ + explicit constexpr get_t() = default; +}; + +/** + * @brief Variable template for lists of observed elements. + * @tparam Type List of types. + */ +template +inline constexpr get_t get{}; + +/** + * @brief Alias for lists of owned elements. + * @tparam Type List of types. + */ +template +struct owned_t final: type_list { + /*! @brief Default constructor. */ + explicit constexpr owned_t() = default; +}; + +/** + * @brief Variable template for lists of owned elements. + * @tparam Type List of types. + */ +template +inline constexpr owned_t owned{}; + +/** + * @brief Applies a given _function_ to a get list and generate a new list. + * @tparam Type Types provided by the get list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +struct type_list_transform, Op> { + /*! @brief Resulting get list after applying the transform function. */ + using type = get_t::type...>; +}; + +/** + * @brief Applies a given _function_ to an exclude list and generate a new list. + * @tparam Type Types provided by the exclude list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +struct type_list_transform, Op> { + /*! @brief Resulting exclude list after applying the transform function. */ + using type = exclude_t::type...>; +}; + +/** + * @brief Applies a given _function_ to an owned list and generate a new list. + * @tparam Type Types provided by the owned list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +struct type_list_transform, Op> { + /*! @brief Resulting owned list after applying the transform function. */ + using type = owned_t::type...>; +}; + +/** + * @brief Provides a common way to define storage types. + * @tparam Type Storage value type. + * @tparam Entity A valid entity type. + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template, typename = void> +struct storage_type { + /*! @brief Type-to-storage conversion result. */ + using type = ENTT_STORAGE(sigh_mixin, basic_storage); +}; + +/*! @brief Empty value type for reactive storage types. */ +struct reactive final {}; + +/** + * @ brief Partial specialization for reactive storage types. + * @tparam Entity A valid entity type. + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +struct storage_type { + /*! @brief Type-to-storage conversion result. */ + using type = ENTT_STORAGE(reactive_mixin, basic_storage); +}; + +/** + * @brief Helper type. + * @tparam Args Arguments to forward. + */ +template +using storage_type_t = typename storage_type::type; + +/** + * Type-to-storage conversion utility that preserves constness. + * @tparam Type Storage value type, eventually const. + * @tparam Entity A valid entity type. + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template>> +struct storage_for { + /*! @brief Type-to-storage conversion result. */ + using type = constness_as_t, Entity, Allocator>, Type>; +}; + +/** + * @brief Helper type. + * @tparam Args Arguments to forward. + */ +template +using storage_for_t = typename storage_for::type; + +/** + * @brief Alias declaration for the most common use case. + * @tparam Get Types of storage iterated by the view. + * @tparam Exclude Types of storage used to filter the view. + */ +template> +using view = basic_view, type_list_transform_t>; + +/** + * @brief Alias declaration for the most common use case. + * @tparam Owned Types of storage _owned_ by the group. + * @tparam Get Types of storage _observed_ by the group. + * @tparam Exclude Types of storage used to filter the group. + */ +template, typename Exclude = exclude_t<>> +using group = basic_group, type_list_transform_t, type_list_transform_t>; + +} // namespace entt + +#endif + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct in_place_delete: std::bool_constant && std::is_move_assignable_v)> {}; + +template<> +struct in_place_delete: std::false_type {}; + +template +struct in_place_delete> + : std::true_type {}; + +template +struct page_size: std::integral_constant * ENTT_PACKED_PAGE> {}; + +template<> +struct page_size: std::integral_constant {}; + +template +struct page_size> + : std::integral_constant {}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Common way to access various properties of components. + * @tparam Type Element type. + * @tparam Entity A valid entity type. + */ +template +struct component_traits { + static_assert(std::is_same_v, Type>, "Unsupported type"); + + /*! @brief Element type. */ + using element_type = Type; + /*! @brief Underlying entity identifier. */ + using entity_type = Entity; + + /*! @brief Pointer stability, default is `false`. */ + static constexpr bool in_place_delete = internal::in_place_delete::value; + /*! @brief Page size, default is `ENTT_PACKED_PAGE` for non-empty types. */ + static constexpr std::size_t page_size = internal::page_size::value; +}; + +} // namespace entt + +#endif + +// #include "entity/entity.hpp" +#ifndef ENTT_ENTITY_ENTITY_HPP +#define ENTT_ENTITY_ENTITY_HPP + +#include +#include +#include +// #include "../config/config.h" + +// #include "../core/bit.hpp" +#ifndef ENTT_CORE_BIT_HPP +#define ENTT_CORE_BIT_HPP + +#include +#include +#include +// #include "../config/config.h" + + +namespace entt { + +/** + * @brief Returns the number of set bits in a value (waiting for C++20 and + * `std::popcount`). + * @tparam Type Unsigned integer type. + * @param value A value of unsigned integer type. + * @return The number of set bits in the value. + */ +template +[[nodiscard]] constexpr std::enable_if_t, int> popcount(const Type value) noexcept { + return value ? (int(value & 1) + popcount(static_cast(value >> 1))) : 0; +} + +/** + * @brief Checks whether a value is a power of two or not (waiting for C++20 and + * `std::has_single_bit`). + * @tparam Type Unsigned integer type. + * @param value A value of unsigned integer type. + * @return True if the value is a power of two, false otherwise. + */ +template +[[nodiscard]] constexpr std::enable_if_t, bool> has_single_bit(const Type value) noexcept { + return value && ((value & (value - 1)) == 0); +} + +/** + * @brief Computes the smallest power of two greater than or equal to a value + * (waiting for C++20 and `std::bit_ceil`). + * @tparam Type Unsigned integer type. + * @param value A value of unsigned integer type. + * @return The smallest power of two greater than or equal to the given value. + */ +template +[[nodiscard]] constexpr std::enable_if_t, Type> next_power_of_two(const Type value) noexcept { + // NOLINTNEXTLINE(bugprone-assert-side-effect) + ENTT_ASSERT_CONSTEXPR(value < (Type{1u} << (std::numeric_limits::digits - 1)), "Numeric limits exceeded"); + Type curr = value - (value != 0u); + + for(int next = 1; next < std::numeric_limits::digits; next = next * 2) { + curr |= (curr >> next); + } + + return ++curr; +} + +/** + * @brief Fast module utility function (powers of two only). + * @tparam Type Unsigned integer type. + * @param value A value of unsigned integer type. + * @param mod _Modulus_, it must be a power of two. + * @return The common remainder. + */ +template +[[nodiscard]] constexpr std::enable_if_t, Type> fast_mod(const Type value, const std::size_t mod) noexcept { + ENTT_ASSERT_CONSTEXPR(has_single_bit(mod), "Value must be a power of two"); + return static_cast(value & (mod - 1u)); +} + +} // namespace entt + +#endif + +// #include "fwd.hpp" + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct entt_traits; + +template +struct entt_traits>> + : entt_traits> { + using value_type = Type; +}; + +template +struct entt_traits>> + : entt_traits { + using value_type = Type; +}; + +template<> +struct entt_traits { + using value_type = std::uint32_t; + + using entity_type = std::uint32_t; + using version_type = std::uint16_t; + + static constexpr entity_type entity_mask = 0xFFFFF; + static constexpr entity_type version_mask = 0xFFF; +}; + +template<> +struct entt_traits { + using value_type = std::uint64_t; + + using entity_type = std::uint64_t; + using version_type = std::uint32_t; + + static constexpr entity_type entity_mask = 0xFFFFFFFF; + static constexpr entity_type version_mask = 0xFFFFFFFF; +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Common basic entity traits implementation. + * @tparam Traits Actual entity traits to use. + */ +template +class basic_entt_traits { + static constexpr auto length = popcount(Traits::entity_mask); + + static_assert(Traits::entity_mask && ((Traits::entity_mask & (Traits::entity_mask + 1)) == 0), "Invalid entity mask"); + static_assert((Traits::version_mask & (Traits::version_mask + 1)) == 0, "Invalid version mask"); + +public: + /*! @brief Value type. */ + using value_type = typename Traits::value_type; + /*! @brief Underlying entity type. */ + using entity_type = typename Traits::entity_type; + /*! @brief Underlying version type. */ + using version_type = typename Traits::version_type; + + /*! @brief Entity mask size. */ + static constexpr entity_type entity_mask = Traits::entity_mask; + /*! @brief Version mask size */ + static constexpr entity_type version_mask = Traits::version_mask; + + /** + * @brief Converts an entity to its underlying type. + * @param value The value to convert. + * @return The integral representation of the given value. + */ + [[nodiscard]] static constexpr entity_type to_integral(const value_type value) noexcept { + return static_cast(value); + } + + /** + * @brief Returns the entity part once converted to the underlying type. + * @param value The value to convert. + * @return The integral representation of the entity part. + */ + [[nodiscard]] static constexpr entity_type to_entity(const value_type value) noexcept { + return (to_integral(value) & entity_mask); + } + + /** + * @brief Returns the version part once converted to the underlying type. + * @param value The value to convert. + * @return The integral representation of the version part. + */ + [[nodiscard]] static constexpr version_type to_version(const value_type value) noexcept { + if constexpr(Traits::version_mask == 0u) { + return version_type{}; + } else { + return (static_cast(to_integral(value) >> length) & version_mask); + } + } + + /** + * @brief Returns the successor of a given identifier. + * @param value The identifier of which to return the successor. + * @return The successor of the given identifier. + */ + [[nodiscard]] static constexpr value_type next(const value_type value) noexcept { + const auto vers = to_version(value) + 1; + return construct(to_integral(value), static_cast(vers + (vers == version_mask))); + } + + /** + * @brief Constructs an identifier from its parts. + * + * If the version part is not provided, a tombstone is returned.
+ * If the entity part is not provided, a null identifier is returned. + * + * @param entity The entity part of the identifier. + * @param version The version part of the identifier. + * @return A properly constructed identifier. + */ + [[nodiscard]] static constexpr value_type construct(const entity_type entity, const version_type version) noexcept { + if constexpr(Traits::version_mask == 0u) { + return value_type{entity & entity_mask}; + } else { + return value_type{(entity & entity_mask) | (static_cast(version & version_mask) << length)}; + } + } + + /** + * @brief Combines two identifiers in a single one. + * + * The returned identifier is a copy of the first element except for its + * version, which is taken from the second element. + * + * @param lhs The identifier from which to take the entity part. + * @param rhs The identifier from which to take the version part. + * @return A properly constructed identifier. + */ + [[nodiscard]] static constexpr value_type combine(const entity_type lhs, const entity_type rhs) noexcept { + if constexpr(Traits::version_mask == 0u) { + return value_type{lhs & entity_mask}; + } else { + return value_type{(lhs & entity_mask) | (rhs & (version_mask << length))}; + } + } +}; + +/** + * @brief Entity traits. + * @tparam Type Type of identifier. + */ +template +struct entt_traits: basic_entt_traits> { + /*! @brief Base type. */ + using base_type = basic_entt_traits>; + /*! @brief Page size, default is `ENTT_SPARSE_PAGE`. */ + static constexpr std::size_t page_size = ENTT_SPARSE_PAGE; +}; + +/** + * @brief Converts an entity to its underlying type. + * @tparam Entity The value type. + * @param value The value to convert. + * @return The integral representation of the given value. + */ +template +[[nodiscard]] constexpr typename entt_traits::entity_type to_integral(const Entity value) noexcept { + return entt_traits::to_integral(value); +} + +/** + * @brief Returns the entity part once converted to the underlying type. + * @tparam Entity The value type. + * @param value The value to convert. + * @return The integral representation of the entity part. + */ +template +[[nodiscard]] constexpr typename entt_traits::entity_type to_entity(const Entity value) noexcept { + return entt_traits::to_entity(value); +} + +/** + * @brief Returns the version part once converted to the underlying type. + * @tparam Entity The value type. + * @param value The value to convert. + * @return The integral representation of the version part. + */ +template +[[nodiscard]] constexpr typename entt_traits::version_type to_version(const Entity value) noexcept { + return entt_traits::to_version(value); +} + +/*! @brief Null object for all identifiers. */ +struct null_t { + /** + * @brief Converts the null object to identifiers of any type. + * @tparam Entity Type of identifier. + * @return The null representation for the given type. + */ + template + [[nodiscard]] constexpr operator Entity() const noexcept { + using traits_type = entt_traits; + constexpr auto value = traits_type::construct(traits_type::entity_mask, traits_type::version_mask); + return value; + } + + /** + * @brief Compares two null objects. + * @param other A null object. + * @return True in all cases. + */ + [[nodiscard]] constexpr bool operator==([[maybe_unused]] const null_t other) const noexcept { + return true; + } + + /** + * @brief Compares two null objects. + * @param other A null object. + * @return False in all cases. + */ + [[nodiscard]] constexpr bool operator!=([[maybe_unused]] const null_t other) const noexcept { + return false; + } + + /** + * @brief Compares a null object and an identifier of any type. + * @tparam Entity Type of identifier. + * @param entity Identifier with which to compare. + * @return False if the two elements differ, true otherwise. + */ + template + [[nodiscard]] constexpr bool operator==(const Entity entity) const noexcept { + using traits_type = entt_traits; + return traits_type::to_entity(entity) == traits_type::to_entity(*this); + } + + /** + * @brief Compares a null object and an identifier of any type. + * @tparam Entity Type of identifier. + * @param entity Identifier with which to compare. + * @return True if the two elements differ, false otherwise. + */ + template + [[nodiscard]] constexpr bool operator!=(const Entity entity) const noexcept { + return !(entity == *this); + } +}; + +/** + * @brief Compares a null object and an identifier of any type. + * @tparam Entity Type of identifier. + * @param lhs Identifier with which to compare. + * @param rhs A null object yet to be converted. + * @return False if the two elements differ, true otherwise. + */ +template +[[nodiscard]] constexpr bool operator==(const Entity lhs, const null_t rhs) noexcept { + return rhs.operator==(lhs); +} + +/** + * @brief Compares a null object and an identifier of any type. + * @tparam Entity Type of identifier. + * @param lhs Identifier with which to compare. + * @param rhs A null object yet to be converted. + * @return True if the two elements differ, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator!=(const Entity lhs, const null_t rhs) noexcept { + return !(rhs == lhs); +} + +/*! @brief Tombstone object for all identifiers. */ +struct tombstone_t { + /** + * @brief Converts the tombstone object to identifiers of any type. + * @tparam Entity Type of identifier. + * @return The tombstone representation for the given type. + */ + template + [[nodiscard]] constexpr operator Entity() const noexcept { + using traits_type = entt_traits; + constexpr auto value = traits_type::construct(traits_type::entity_mask, traits_type::version_mask); + return value; + } + + /** + * @brief Compares two tombstone objects. + * @param other A tombstone object. + * @return True in all cases. + */ + [[nodiscard]] constexpr bool operator==([[maybe_unused]] const tombstone_t other) const noexcept { + return true; + } + + /** + * @brief Compares two tombstone objects. + * @param other A tombstone object. + * @return False in all cases. + */ + [[nodiscard]] constexpr bool operator!=([[maybe_unused]] const tombstone_t other) const noexcept { + return false; + } + + /** + * @brief Compares a tombstone object and an identifier of any type. + * @tparam Entity Type of identifier. + * @param entity Identifier with which to compare. + * @return False if the two elements differ, true otherwise. + */ + template + [[nodiscard]] constexpr bool operator==(const Entity entity) const noexcept { + using traits_type = entt_traits; + + if constexpr(traits_type::version_mask == 0u) { + return false; + } else { + return (traits_type::to_version(entity) == traits_type::to_version(*this)); + } + } + + /** + * @brief Compares a tombstone object and an identifier of any type. + * @tparam Entity Type of identifier. + * @param entity Identifier with which to compare. + * @return True if the two elements differ, false otherwise. + */ + template + [[nodiscard]] constexpr bool operator!=(const Entity entity) const noexcept { + return !(entity == *this); + } +}; + +/** + * @brief Compares a tombstone object and an identifier of any type. + * @tparam Entity Type of identifier. + * @param lhs Identifier with which to compare. + * @param rhs A tombstone object yet to be converted. + * @return False if the two elements differ, true otherwise. + */ +template +[[nodiscard]] constexpr bool operator==(const Entity lhs, const tombstone_t rhs) noexcept { + return rhs.operator==(lhs); +} + +/** + * @brief Compares a tombstone object and an identifier of any type. + * @tparam Entity Type of identifier. + * @param lhs Identifier with which to compare. + * @param rhs A tombstone object yet to be converted. + * @return True if the two elements differ, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator!=(const Entity lhs, const tombstone_t rhs) noexcept { + return !(rhs == lhs); +} + +/** + * @brief Compile-time constant for null entities. + * + * There exist implicit conversions from this variable to identifiers of any + * allowed type. Similarly, there exist comparison operators between the null + * entity and any other identifier. + */ +inline constexpr null_t null{}; + +/** + * @brief Compile-time constant for tombstone entities. + * + * There exist implicit conversions from this variable to identifiers of any + * allowed type. Similarly, there exist comparison operators between the + * tombstone entity and any other identifier. + */ +inline constexpr tombstone_t tombstone{}; + +} // namespace entt + +#endif + +// #include "entity/group.hpp" +#ifndef ENTT_ENTITY_GROUP_HPP +#define ENTT_ENTITY_GROUP_HPP + +#include +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "../core/algorithm.hpp" +#ifndef ENTT_CORE_ALGORITHM_HPP +#define ENTT_CORE_ALGORITHM_HPP + +#include +#include +#include +#include +#include +// #include "utility.hpp" +#ifndef ENTT_CORE_UTILITY_HPP +#define ENTT_CORE_UTILITY_HPP + +#include +#include + +namespace entt { + +/*! @brief Identity function object (waiting for C++20). */ +struct identity { + /*! @brief Indicates that this is a transparent function object. */ + using is_transparent = void; + + /** + * @brief Returns its argument unchanged. + * @tparam Type Type of the argument. + * @param value The actual argument. + * @return The submitted value as-is. + */ + template + [[nodiscard]] constexpr Type &&operator()(Type &&value) const noexcept { + return std::forward(value); + } +}; + +/** + * @brief Constant utility to disambiguate overloaded members of a class. + * @tparam Type Type of the desired overload. + * @tparam Class Type of class to which the member belongs. + * @param member A valid pointer to a member. + * @return Pointer to the member. + */ +template +[[nodiscard]] constexpr auto overload(Type Class::*member) noexcept { + return member; +} + +/** + * @brief Constant utility to disambiguate overloaded functions. + * @tparam Func Function type of the desired overload. + * @param func A valid pointer to a function. + * @return Pointer to the function. + */ +template +[[nodiscard]] constexpr auto overload(Func *func) noexcept { + return func; +} + +/** + * @brief Helper type for visitors. + * @tparam Func Types of function objects. + */ +template +struct overloaded: Func... { + using Func::operator()...; +}; + +/** + * @brief Deduction guide. + * @tparam Func Types of function objects. + */ +template +overloaded(Func...) -> overloaded; + +/** + * @brief Basic implementation of a y-combinator. + * @tparam Func Type of a potentially recursive function. + */ +template +struct y_combinator { + /** + * @brief Constructs a y-combinator from a given function. + * @param recursive A potentially recursive function. + */ + constexpr y_combinator(Func recursive) noexcept(std::is_nothrow_move_constructible_v) + : func{std::move(recursive)} {} + + /** + * @brief Invokes a y-combinator and therefore its underlying function. + * @tparam Args Types of arguments to use to invoke the underlying function. + * @param args Parameters to use to invoke the underlying function. + * @return Return value of the underlying function, if any. + */ + template + constexpr decltype(auto) operator()(Args &&...args) const noexcept(std::is_nothrow_invocable_v) { + return func(*this, std::forward(args)...); + } + + /*! @copydoc operator()() */ + template + constexpr decltype(auto) operator()(Args &&...args) noexcept(std::is_nothrow_invocable_v) { + return func(*this, std::forward(args)...); + } + +private: + Func func; +}; + +} // namespace entt + +#endif + + +namespace entt { + +/** + * @brief Function object to wrap `std::sort` in a class type. + * + * Unfortunately, `std::sort` cannot be passed as template argument to a class + * template or a function template.
+ * This class fills the gap by wrapping some flavors of `std::sort` in a + * function object. + */ +struct std_sort { + /** + * @brief Sorts the elements in a range. + * + * Sorts the elements in a range using the given binary comparison function. + * + * @tparam It Type of random access iterator. + * @tparam Compare Type of comparison function object. + * @tparam Args Types of arguments to forward to the sort function. + * @param first An iterator to the first element of the range to sort. + * @param last An iterator past the last element of the range to sort. + * @param compare A valid comparison function object. + * @param args Arguments to forward to the sort function, if any. + */ + template, typename... Args> + void operator()(It first, It last, Compare compare = Compare{}, Args &&...args) const { + std::sort(std::forward(args)..., std::move(first), std::move(last), std::move(compare)); + } +}; + +/*! @brief Function object for performing insertion sort. */ +struct insertion_sort { + /** + * @brief Sorts the elements in a range. + * + * Sorts the elements in a range using the given binary comparison function. + * + * @tparam It Type of random access iterator. + * @tparam Compare Type of comparison function object. + * @param first An iterator to the first element of the range to sort. + * @param last An iterator past the last element of the range to sort. + * @param compare A valid comparison function object. + */ + template> + void operator()(It first, It last, Compare compare = Compare{}) const { + if(first < last) { + for(auto it = first + 1; it < last; ++it) { + auto value = std::move(*it); + auto pre = it; + + // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic) + for(; pre > first && compare(value, *(pre - 1)); --pre) { + *pre = std::move(*(pre - 1)); + } + // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic) + + *pre = std::move(value); + } + } + } +}; + +/** + * @brief Function object for performing LSD radix sort. + * @tparam Bit Number of bits processed per pass. + * @tparam N Maximum number of bits to sort. + */ +template +struct radix_sort { + static_assert((N % Bit) == 0, "The maximum number of bits to sort must be a multiple of the number of bits processed per pass"); + + /** + * @brief Sorts the elements in a range. + * + * Sorts the elements in a range using the given _getter_ to access the + * actual data to be sorted. + * + * This implementation is inspired by the online book + * [Physically Based Rendering](http://www.pbr-book.org/3ed-2018/Primitives_and_Intersection_Acceleration/Bounding_Volume_Hierarchies.html#RadixSort). + * + * @tparam It Type of random access iterator. + * @tparam Getter Type of _getter_ function object. + * @param first An iterator to the first element of the range to sort. + * @param last An iterator past the last element of the range to sort. + * @param getter A valid _getter_ function object. + */ + template + void operator()(It first, It last, Getter getter = Getter{}) const { + if(first < last) { + constexpr auto passes = N / Bit; + + using value_type = typename std::iterator_traits::value_type; + using difference_type = typename std::iterator_traits::difference_type; + std::vector aux(static_cast(std::distance(first, last))); + + auto part = [getter = std::move(getter)](auto from, auto to, auto out, auto start) { + constexpr auto mask = (1 << Bit) - 1; + constexpr auto buckets = 1 << Bit; + + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays, misc-const-correctness) + std::size_t count[buckets]{}; + + for(auto it = from; it != to; ++it) { + ++count[(getter(*it) >> start) & mask]; + } + + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) + std::size_t index[buckets]{}; + + for(std::size_t pos{}, end = buckets - 1u; pos < end; ++pos) { + index[pos + 1u] = index[pos] + count[pos]; + } + + for(auto it = from; it != to; ++it) { + const auto pos = index[(getter(*it) >> start) & mask]++; + out[static_cast(pos)] = std::move(*it); + } + }; + + for(std::size_t pass = 0; pass < (passes & ~1u); pass += 2) { + part(first, last, aux.begin(), pass * Bit); + part(aux.begin(), aux.end(), first, (pass + 1) * Bit); + } + + if constexpr(passes & 1) { + part(first, last, aux.begin(), (passes - 1) * Bit); + std::move(aux.begin(), aux.end(), first); + } + } + } +}; + +} // namespace entt + +#endif + +// #include "../core/fwd.hpp" + +// #include "../core/iterator.hpp" +#ifndef ENTT_CORE_ITERATOR_HPP +#define ENTT_CORE_ITERATOR_HPP + +#include +#include +#include +#include + +namespace entt { + +/** + * @brief Helper type to use as pointer with input iterators. + * @tparam Type of wrapped value. + */ +template +struct input_iterator_pointer final { + /*! @brief Value type. */ + using value_type = Type; + /*! @brief Pointer type. */ + using pointer = Type *; + /*! @brief Reference type. */ + using reference = Type &; + + /** + * @brief Constructs a proxy object by move. + * @param val Value to use to initialize the proxy object. + */ + constexpr input_iterator_pointer(value_type &&val) noexcept(std::is_nothrow_move_constructible_v) + : value{std::move(val)} {} + + /** + * @brief Access operator for accessing wrapped values. + * @return A pointer to the wrapped value. + */ + [[nodiscard]] constexpr pointer operator->() noexcept { + return std::addressof(value); + } + + /** + * @brief Dereference operator for accessing wrapped values. + * @return A reference to the wrapped value. + */ + [[nodiscard]] constexpr reference operator*() noexcept { + return value; + } + +private: + Type value; +}; + +/** + * @brief Plain iota iterator (waiting for C++20). + * @tparam Type Value type. + */ +template +class iota_iterator final { + static_assert(std::is_integral_v, "Not an integral type"); + +public: + /*! @brief Value type, likely an integral one. */ + using value_type = Type; + /*! @brief Invalid pointer type. */ + using pointer = void; + /*! @brief Non-reference type, same as value type. */ + using reference = value_type; + /*! @brief Difference type. */ + using difference_type = std::ptrdiff_t; + /*! @brief Iterator category. */ + using iterator_category = std::input_iterator_tag; + + /*! @brief Default constructor. */ + constexpr iota_iterator() noexcept + : current{} {} + + /** + * @brief Constructs an iota iterator from a given value. + * @param init The initial value assigned to the iota iterator. + */ + constexpr iota_iterator(const value_type init) noexcept + : current{init} {} + + /** + * @brief Pre-increment operator. + * @return This iota iterator. + */ + constexpr iota_iterator &operator++() noexcept { + return ++current, *this; + } + + /** + * @brief Post-increment operator. + * @return This iota iterator. + */ + constexpr iota_iterator operator++(int) noexcept { + const iota_iterator orig = *this; + return ++(*this), orig; + } + + /** + * @brief Dereference operator. + * @return The underlying value. + */ + [[nodiscard]] constexpr reference operator*() const noexcept { + return current; + } + +private: + value_type current; +}; + +/** + * @brief Comparison operator. + * @tparam Type Value type of the iota iterator. + * @param lhs A properly initialized iota iterator. + * @param rhs A properly initialized iota iterator. + * @return True if the two iterators are identical, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator==(const iota_iterator &lhs, const iota_iterator &rhs) noexcept { + return *lhs == *rhs; +} + +/** + * @brief Comparison operator. + * @tparam Type Value type of the iota iterator. + * @param lhs A properly initialized iota iterator. + * @param rhs A properly initialized iota iterator. + * @return True if the two iterators differ, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator!=(const iota_iterator &lhs, const iota_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +/** + * @brief Utility class to create an iterable object from a pair of iterators. + * @tparam It Type of iterator. + * @tparam Sentinel Type of sentinel. + */ +template +struct iterable_adaptor final { + /*! @brief Value type. */ + using value_type = typename std::iterator_traits::value_type; + /*! @brief Iterator type. */ + using iterator = It; + /*! @brief Sentinel type. */ + using sentinel = Sentinel; + + /*! @brief Default constructor. */ + constexpr iterable_adaptor() noexcept(std::is_nothrow_default_constructible_v && std::is_nothrow_default_constructible_v) + : first{}, + last{} {} + + /** + * @brief Creates an iterable object from a pair of iterators. + * @param from Begin iterator. + * @param to End iterator. + */ + constexpr iterable_adaptor(iterator from, sentinel to) noexcept(std::is_nothrow_move_constructible_v && std::is_nothrow_move_constructible_v) + : first{std::move(from)}, + last{std::move(to)} {} + + /** + * @brief Returns an iterator to the beginning. + * @return An iterator to the first element of the range. + */ + [[nodiscard]] constexpr iterator begin() const noexcept { + return first; + } + + /** + * @brief Returns an iterator to the end. + * @return An iterator to the element following the last element of the + * range. + */ + [[nodiscard]] constexpr sentinel end() const noexcept { + return last; + } + + /*! @copydoc begin */ + [[nodiscard]] constexpr iterator cbegin() const noexcept { + return begin(); + } + + /*! @copydoc end */ + [[nodiscard]] constexpr sentinel cend() const noexcept { + return end(); + } + +private: + It first; + Sentinel last; +}; + +} // namespace entt + +#endif + +// #include "../core/type_info.hpp" +#ifndef ENTT_CORE_TYPE_INFO_HPP +#define ENTT_CORE_TYPE_INFO_HPP + +#include +#include +#include +// #include "../config/config.h" + +// #include "fwd.hpp" + +// #include "hashed_string.hpp" +#ifndef ENTT_CORE_HASHED_STRING_HPP +#define ENTT_CORE_HASHED_STRING_HPP + +#include +#include +// #include "fwd.hpp" + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct fnv_1a_params; + +template<> +struct fnv_1a_params { + static constexpr auto offset = 2166136261; + static constexpr auto prime = 16777619; +}; + +template<> +struct fnv_1a_params { + static constexpr auto offset = 14695981039346656037ull; + static constexpr auto prime = 1099511628211ull; +}; + +template +struct basic_hashed_string { + using value_type = Char; + using size_type = std::size_t; + using hash_type = id_type; + + const value_type *repr{}; + hash_type hash{fnv_1a_params<>::offset}; + size_type length{}; +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Zero overhead unique identifier. + * + * A hashed string is a compile-time tool that allows users to use + * human-readable identifiers in the codebase while using their numeric + * counterparts at runtime.
+ * Because of that, a hashed string can also be used in constant expressions if + * required. + * + * @warning + * This class doesn't take ownership of user-supplied strings nor does it make a + * copy of them. + * + * @tparam Char Character type. + */ +template +class basic_hashed_string: internal::basic_hashed_string { + using base_type = internal::basic_hashed_string; + using params = internal::fnv_1a_params<>; + + struct const_wrapper { + // non-explicit constructor on purpose + constexpr const_wrapper(const typename base_type::value_type *str) noexcept + : repr{str} {} + + const typename base_type::value_type *repr; + }; + +public: + /*! @brief Character type. */ + using value_type = typename base_type::value_type; + /*! @brief Unsigned integer type. */ + using size_type = typename base_type::size_type; + /*! @brief Unsigned integer type. */ + using hash_type = typename base_type::hash_type; + + /** + * @brief Returns directly the numeric representation of a string view. + * @param str Human-readable identifier. + * @param len Length of the string to hash. + * @return The numeric representation of the string. + */ + [[nodiscard]] static constexpr hash_type value(const value_type *str, const size_type len) noexcept { + return basic_hashed_string{str, len}; + } + + /** + * @brief Returns directly the numeric representation of a string. + * @tparam N Number of characters of the identifier. + * @param str Human-readable identifier. + * @return The numeric representation of the string. + */ + template + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) + [[nodiscard]] static ENTT_CONSTEVAL hash_type value(const value_type (&str)[N]) noexcept { + return basic_hashed_string{str}; + } + + /** + * @brief Returns directly the numeric representation of a string. + * @param wrapper Helps achieving the purpose by relying on overloading. + * @return The numeric representation of the string. + */ + [[nodiscard]] static constexpr hash_type value(const_wrapper wrapper) noexcept { + return basic_hashed_string{wrapper}; + } + + /*! @brief Constructs an empty hashed string. */ + constexpr basic_hashed_string() noexcept + : basic_hashed_string{nullptr, 0u} {} + + /** + * @brief Constructs a hashed string from a string view. + * @param str Human-readable identifier. + * @param len Length of the string to hash. + */ + constexpr basic_hashed_string(const value_type *str, const size_type len) noexcept + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay) + : base_type{str} { + // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic) + for(; base_type::length < len; ++base_type::length) { + base_type::hash = (base_type::hash ^ static_cast(str[base_type::length])) * params::prime; + } + // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic) + } + + /** + * @brief Constructs a hashed string from an array of const characters. + * @tparam N Number of characters of the identifier. + * @param str Human-readable identifier. + */ + template + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) + ENTT_CONSTEVAL basic_hashed_string(const value_type (&str)[N]) noexcept + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay) + : base_type{str} { + for(; str[base_type::length]; ++base_type::length) { + base_type::hash = (base_type::hash ^ static_cast(str[base_type::length])) * params::prime; + } + } + + /** + * @brief Explicit constructor on purpose to avoid constructing a hashed + * string directly from a `const value_type *`. + * + * @warning + * The lifetime of the string is not extended nor is it copied. + * + * @param wrapper Helps achieving the purpose by relying on overloading. + */ + explicit constexpr basic_hashed_string(const_wrapper wrapper) noexcept + : base_type{wrapper.repr} { + // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic) + for(; wrapper.repr[base_type::length]; ++base_type::length) { + base_type::hash = (base_type::hash ^ static_cast(wrapper.repr[base_type::length])) * params::prime; + } + // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic) + } + + /** + * @brief Returns the size of a hashed string. + * @return The size of the hashed string. + */ + [[nodiscard]] constexpr size_type size() const noexcept { + return base_type::length; + } + + /** + * @brief Returns the human-readable representation of a hashed string. + * @return The string used to initialize the hashed string. + */ + [[nodiscard]] constexpr const value_type *data() const noexcept { + return base_type::repr; + } + + /** + * @brief Returns the numeric representation of a hashed string. + * @return The numeric representation of the hashed string. + */ + [[nodiscard]] constexpr hash_type value() const noexcept { + return base_type::hash; + } + + /*! @copydoc data */ + [[nodiscard]] explicit constexpr operator const value_type *() const noexcept { + return data(); + } + + /** + * @brief Returns the numeric representation of a hashed string. + * @return The numeric representation of the hashed string. + */ + [[nodiscard]] constexpr operator hash_type() const noexcept { + return value(); + } +}; + +/** + * @brief Deduction guide. + * @tparam Char Character type. + * @param str Human-readable identifier. + * @param len Length of the string to hash. + */ +template +basic_hashed_string(const Char *str, std::size_t len) -> basic_hashed_string; + +/** + * @brief Deduction guide. + * @tparam Char Character type. + * @tparam N Number of characters of the identifier. + * @param str Human-readable identifier. + */ +template +// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) +basic_hashed_string(const Char (&str)[N]) -> basic_hashed_string; + +/** + * @brief Compares two hashed strings. + * @tparam Char Character type. + * @param lhs A valid hashed string. + * @param rhs A valid hashed string. + * @return True if the two hashed strings are identical, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator==(const basic_hashed_string &lhs, const basic_hashed_string &rhs) noexcept { + return lhs.value() == rhs.value(); +} + +/** + * @brief Compares two hashed strings. + * @tparam Char Character type. + * @param lhs A valid hashed string. + * @param rhs A valid hashed string. + * @return True if the two hashed strings differ, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator!=(const basic_hashed_string &lhs, const basic_hashed_string &rhs) noexcept { + return !(lhs == rhs); +} + +/** + * @brief Compares two hashed strings. + * @tparam Char Character type. + * @param lhs A valid hashed string. + * @param rhs A valid hashed string. + * @return True if the first element is less than the second, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator<(const basic_hashed_string &lhs, const basic_hashed_string &rhs) noexcept { + return lhs.value() < rhs.value(); +} + +/** + * @brief Compares two hashed strings. + * @tparam Char Character type. + * @param lhs A valid hashed string. + * @param rhs A valid hashed string. + * @return True if the first element is less than or equal to the second, false + * otherwise. + */ +template +[[nodiscard]] constexpr bool operator<=(const basic_hashed_string &lhs, const basic_hashed_string &rhs) noexcept { + return !(rhs < lhs); +} + +/** + * @brief Compares two hashed strings. + * @tparam Char Character type. + * @param lhs A valid hashed string. + * @param rhs A valid hashed string. + * @return True if the first element is greater than the second, false + * otherwise. + */ +template +[[nodiscard]] constexpr bool operator>(const basic_hashed_string &lhs, const basic_hashed_string &rhs) noexcept { + return rhs < lhs; +} + +/** + * @brief Compares two hashed strings. + * @tparam Char Character type. + * @param lhs A valid hashed string. + * @param rhs A valid hashed string. + * @return True if the first element is greater than or equal to the second, + * false otherwise. + */ +template +[[nodiscard]] constexpr bool operator>=(const basic_hashed_string &lhs, const basic_hashed_string &rhs) noexcept { + return !(lhs < rhs); +} + +inline namespace literals { + +/** + * @brief User defined literal for hashed strings. + * @param str The literal without its suffix. + * @return A properly initialized hashed string. + */ +[[nodiscard]] ENTT_CONSTEVAL hashed_string operator""_hs(const char *str, std::size_t) noexcept { + return hashed_string{str}; +} + +/** + * @brief User defined literal for hashed wstrings. + * @param str The literal without its suffix. + * @return A properly initialized hashed wstring. + */ +[[nodiscard]] ENTT_CONSTEVAL hashed_wstring operator""_hws(const wchar_t *str, std::size_t) noexcept { + return hashed_wstring{str}; +} + +} // namespace literals + +} // namespace entt + +#endif + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +struct ENTT_API type_index final { + [[nodiscard]] static id_type next() noexcept { + static ENTT_MAYBE_ATOMIC(id_type) value{}; + return value++; + } +}; + +template +[[nodiscard]] constexpr const char *pretty_function() noexcept { +#if defined ENTT_PRETTY_FUNCTION + return static_cast(ENTT_PRETTY_FUNCTION); +#else + return ""; +#endif +} + +template +[[nodiscard]] constexpr auto stripped_type_name() noexcept { +#if defined ENTT_PRETTY_FUNCTION + const std::string_view full_name{pretty_function()}; + auto first = full_name.find_first_not_of(' ', full_name.find_first_of(ENTT_PRETTY_FUNCTION_PREFIX) + 1); + auto value = full_name.substr(first, full_name.find_last_of(ENTT_PRETTY_FUNCTION_SUFFIX) - first); + return value; +#else + return std::string_view{}; +#endif +} + +template().find_first_of('.')> +[[nodiscard]] constexpr std::string_view type_name(int) noexcept { + constexpr auto value = stripped_type_name(); + return value; +} + +template +[[nodiscard]] std::string_view type_name(char) noexcept { + static const auto value = stripped_type_name(); + return value; +} + +template().find_first_of('.')> +[[nodiscard]] constexpr id_type type_hash(int) noexcept { + constexpr auto stripped = stripped_type_name(); + constexpr auto value = hashed_string::value(stripped.data(), stripped.size()); + return value; +} + +template +[[nodiscard]] id_type type_hash(char) noexcept { + static const auto value = [](const auto stripped) { + return hashed_string::value(stripped.data(), stripped.size()); + }(stripped_type_name()); + return value; +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Type sequential identifier. + * @tparam Type Type for which to generate a sequential identifier. + */ +template +struct ENTT_API type_index final { + /** + * @brief Returns the sequential identifier of a given type. + * @return The sequential identifier of a given type. + */ + [[nodiscard]] static id_type value() noexcept { + static const id_type value = internal::type_index::next(); + return value; + } + + /*! @copydoc value */ + [[nodiscard]] constexpr operator id_type() const noexcept { + return value(); + } +}; + +/** + * @brief Type hash. + * @tparam Type Type for which to generate a hash value. + */ +template +struct type_hash final { + /** + * @brief Returns the numeric representation of a given type. + * @return The numeric representation of the given type. + */ +#if defined ENTT_PRETTY_FUNCTION + [[nodiscard]] static constexpr id_type value() noexcept { + return internal::type_hash(0); +#else + [[nodiscard]] static constexpr id_type value() noexcept { + return type_index::value(); +#endif + } + + /*! @copydoc value */ + [[nodiscard]] constexpr operator id_type() const noexcept { + return value(); + } +}; + +/** + * @brief Type name. + * @tparam Type Type for which to generate a name. + */ +template +struct type_name final { + /** + * @brief Returns the name of a given type. + * @return The name of the given type. + */ + [[nodiscard]] static constexpr std::string_view value() noexcept { + return internal::type_name(0); + } + + /*! @copydoc value */ + [[nodiscard]] constexpr operator std::string_view() const noexcept { + return value(); + } +}; + +/*! @brief Implementation specific information about a type. */ +struct type_info final { + /** + * @brief Constructs a type info object for a given type. + * @tparam Type Type for which to construct a type info object. + */ + template + // NOLINTBEGIN(modernize-use-transparent-functors) + constexpr type_info(std::in_place_type_t) noexcept + : seq{type_index>>::value()}, + identifier{type_hash>>::value()}, + alias{type_name>>::value()} {} + // NOLINTEND(modernize-use-transparent-functors) + + /** + * @brief Type index. + * @return Type index. + */ + [[nodiscard]] constexpr id_type index() const noexcept { + return seq; + } + + /** + * @brief Type hash. + * @return Type hash. + */ + [[nodiscard]] constexpr id_type hash() const noexcept { + return identifier; + } + + /** + * @brief Type name. + * @return Type name. + */ + [[nodiscard]] constexpr std::string_view name() const noexcept { + return alias; + } + +private: + id_type seq; + id_type identifier; + std::string_view alias; +}; + +/** + * @brief Compares the contents of two type info objects. + * @param lhs A type info object. + * @param rhs A type info object. + * @return True if the two type info objects are identical, false otherwise. + */ +[[nodiscard]] constexpr bool operator==(const type_info &lhs, const type_info &rhs) noexcept { + return lhs.hash() == rhs.hash(); +} + +/** + * @brief Compares the contents of two type info objects. + * @param lhs A type info object. + * @param rhs A type info object. + * @return True if the two type info objects differ, false otherwise. + */ +[[nodiscard]] constexpr bool operator!=(const type_info &lhs, const type_info &rhs) noexcept { + return !(lhs == rhs); +} + +/** + * @brief Compares two type info objects. + * @param lhs A valid type info object. + * @param rhs A valid type info object. + * @return True if the first element is less than the second, false otherwise. + */ +[[nodiscard]] constexpr bool operator<(const type_info &lhs, const type_info &rhs) noexcept { + return lhs.index() < rhs.index(); +} + +/** + * @brief Compares two type info objects. + * @param lhs A valid type info object. + * @param rhs A valid type info object. + * @return True if the first element is less than or equal to the second, false + * otherwise. + */ +[[nodiscard]] constexpr bool operator<=(const type_info &lhs, const type_info &rhs) noexcept { + return !(rhs < lhs); +} + +/** + * @brief Compares two type info objects. + * @param lhs A valid type info object. + * @param rhs A valid type info object. + * @return True if the first element is greater than the second, false + * otherwise. + */ +[[nodiscard]] constexpr bool operator>(const type_info &lhs, const type_info &rhs) noexcept { + return rhs < lhs; +} + +/** + * @brief Compares two type info objects. + * @param lhs A valid type info object. + * @param rhs A valid type info object. + * @return True if the first element is greater than or equal to the second, + * false otherwise. + */ +[[nodiscard]] constexpr bool operator>=(const type_info &lhs, const type_info &rhs) noexcept { + return !(lhs < rhs); +} + +/** + * @brief Returns the type info object associated to a given type. + * + * The returned element refers to an object with static storage duration.
+ * The type doesn't need to be a complete type. If the type is a reference, the + * result refers to the referenced type. In all cases, top-level cv-qualifiers + * are ignored. + * + * @tparam Type Type for which to generate a type info object. + * @return A reference to a properly initialized type info object. + */ +template +[[nodiscard]] const type_info &type_id() noexcept { + if constexpr(std::is_same_v>>) { + static const type_info instance{std::in_place_type}; + return instance; + } else { + return type_id>>(); + } +} + +/*! @copydoc type_id */ +template +// NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward) +[[nodiscard]] const type_info &type_id(Type &&) noexcept { + return type_id>>(); +} + +} // namespace entt + +#endif + +// #include "../core/type_traits.hpp" + +// #include "entity.hpp" +#ifndef ENTT_ENTITY_ENTITY_HPP +#define ENTT_ENTITY_ENTITY_HPP + +#include +#include +#include +// #include "../config/config.h" + +// #include "../core/bit.hpp" + +// #include "fwd.hpp" + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct entt_traits; + +template +struct entt_traits>> + : entt_traits> { + using value_type = Type; +}; + +template +struct entt_traits>> + : entt_traits { + using value_type = Type; +}; + +template<> +struct entt_traits { + using value_type = std::uint32_t; + + using entity_type = std::uint32_t; + using version_type = std::uint16_t; + + static constexpr entity_type entity_mask = 0xFFFFF; + static constexpr entity_type version_mask = 0xFFF; +}; + +template<> +struct entt_traits { + using value_type = std::uint64_t; + + using entity_type = std::uint64_t; + using version_type = std::uint32_t; + + static constexpr entity_type entity_mask = 0xFFFFFFFF; + static constexpr entity_type version_mask = 0xFFFFFFFF; +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Common basic entity traits implementation. + * @tparam Traits Actual entity traits to use. + */ +template +class basic_entt_traits { + static constexpr auto length = popcount(Traits::entity_mask); + + static_assert(Traits::entity_mask && ((Traits::entity_mask & (Traits::entity_mask + 1)) == 0), "Invalid entity mask"); + static_assert((Traits::version_mask & (Traits::version_mask + 1)) == 0, "Invalid version mask"); + +public: + /*! @brief Value type. */ + using value_type = typename Traits::value_type; + /*! @brief Underlying entity type. */ + using entity_type = typename Traits::entity_type; + /*! @brief Underlying version type. */ + using version_type = typename Traits::version_type; + + /*! @brief Entity mask size. */ + static constexpr entity_type entity_mask = Traits::entity_mask; + /*! @brief Version mask size */ + static constexpr entity_type version_mask = Traits::version_mask; + + /** + * @brief Converts an entity to its underlying type. + * @param value The value to convert. + * @return The integral representation of the given value. + */ + [[nodiscard]] static constexpr entity_type to_integral(const value_type value) noexcept { + return static_cast(value); + } + + /** + * @brief Returns the entity part once converted to the underlying type. + * @param value The value to convert. + * @return The integral representation of the entity part. + */ + [[nodiscard]] static constexpr entity_type to_entity(const value_type value) noexcept { + return (to_integral(value) & entity_mask); + } + + /** + * @brief Returns the version part once converted to the underlying type. + * @param value The value to convert. + * @return The integral representation of the version part. + */ + [[nodiscard]] static constexpr version_type to_version(const value_type value) noexcept { + if constexpr(Traits::version_mask == 0u) { + return version_type{}; + } else { + return (static_cast(to_integral(value) >> length) & version_mask); + } + } + + /** + * @brief Returns the successor of a given identifier. + * @param value The identifier of which to return the successor. + * @return The successor of the given identifier. + */ + [[nodiscard]] static constexpr value_type next(const value_type value) noexcept { + const auto vers = to_version(value) + 1; + return construct(to_integral(value), static_cast(vers + (vers == version_mask))); + } + + /** + * @brief Constructs an identifier from its parts. + * + * If the version part is not provided, a tombstone is returned.
+ * If the entity part is not provided, a null identifier is returned. + * + * @param entity The entity part of the identifier. + * @param version The version part of the identifier. + * @return A properly constructed identifier. + */ + [[nodiscard]] static constexpr value_type construct(const entity_type entity, const version_type version) noexcept { + if constexpr(Traits::version_mask == 0u) { + return value_type{entity & entity_mask}; + } else { + return value_type{(entity & entity_mask) | (static_cast(version & version_mask) << length)}; + } + } + + /** + * @brief Combines two identifiers in a single one. + * + * The returned identifier is a copy of the first element except for its + * version, which is taken from the second element. + * + * @param lhs The identifier from which to take the entity part. + * @param rhs The identifier from which to take the version part. + * @return A properly constructed identifier. + */ + [[nodiscard]] static constexpr value_type combine(const entity_type lhs, const entity_type rhs) noexcept { + if constexpr(Traits::version_mask == 0u) { + return value_type{lhs & entity_mask}; + } else { + return value_type{(lhs & entity_mask) | (rhs & (version_mask << length))}; + } + } +}; + +/** + * @brief Entity traits. + * @tparam Type Type of identifier. + */ +template +struct entt_traits: basic_entt_traits> { + /*! @brief Base type. */ + using base_type = basic_entt_traits>; + /*! @brief Page size, default is `ENTT_SPARSE_PAGE`. */ + static constexpr std::size_t page_size = ENTT_SPARSE_PAGE; +}; + +/** + * @brief Converts an entity to its underlying type. + * @tparam Entity The value type. + * @param value The value to convert. + * @return The integral representation of the given value. + */ +template +[[nodiscard]] constexpr typename entt_traits::entity_type to_integral(const Entity value) noexcept { + return entt_traits::to_integral(value); +} + +/** + * @brief Returns the entity part once converted to the underlying type. + * @tparam Entity The value type. + * @param value The value to convert. + * @return The integral representation of the entity part. + */ +template +[[nodiscard]] constexpr typename entt_traits::entity_type to_entity(const Entity value) noexcept { + return entt_traits::to_entity(value); +} + +/** + * @brief Returns the version part once converted to the underlying type. + * @tparam Entity The value type. + * @param value The value to convert. + * @return The integral representation of the version part. + */ +template +[[nodiscard]] constexpr typename entt_traits::version_type to_version(const Entity value) noexcept { + return entt_traits::to_version(value); +} + +/*! @brief Null object for all identifiers. */ +struct null_t { + /** + * @brief Converts the null object to identifiers of any type. + * @tparam Entity Type of identifier. + * @return The null representation for the given type. + */ + template + [[nodiscard]] constexpr operator Entity() const noexcept { + using traits_type = entt_traits; + constexpr auto value = traits_type::construct(traits_type::entity_mask, traits_type::version_mask); + return value; + } + + /** + * @brief Compares two null objects. + * @param other A null object. + * @return True in all cases. + */ + [[nodiscard]] constexpr bool operator==([[maybe_unused]] const null_t other) const noexcept { + return true; + } + + /** + * @brief Compares two null objects. + * @param other A null object. + * @return False in all cases. + */ + [[nodiscard]] constexpr bool operator!=([[maybe_unused]] const null_t other) const noexcept { + return false; + } + + /** + * @brief Compares a null object and an identifier of any type. + * @tparam Entity Type of identifier. + * @param entity Identifier with which to compare. + * @return False if the two elements differ, true otherwise. + */ + template + [[nodiscard]] constexpr bool operator==(const Entity entity) const noexcept { + using traits_type = entt_traits; + return traits_type::to_entity(entity) == traits_type::to_entity(*this); + } + + /** + * @brief Compares a null object and an identifier of any type. + * @tparam Entity Type of identifier. + * @param entity Identifier with which to compare. + * @return True if the two elements differ, false otherwise. + */ + template + [[nodiscard]] constexpr bool operator!=(const Entity entity) const noexcept { + return !(entity == *this); + } +}; + +/** + * @brief Compares a null object and an identifier of any type. + * @tparam Entity Type of identifier. + * @param lhs Identifier with which to compare. + * @param rhs A null object yet to be converted. + * @return False if the two elements differ, true otherwise. + */ +template +[[nodiscard]] constexpr bool operator==(const Entity lhs, const null_t rhs) noexcept { + return rhs.operator==(lhs); +} + +/** + * @brief Compares a null object and an identifier of any type. + * @tparam Entity Type of identifier. + * @param lhs Identifier with which to compare. + * @param rhs A null object yet to be converted. + * @return True if the two elements differ, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator!=(const Entity lhs, const null_t rhs) noexcept { + return !(rhs == lhs); +} + +/*! @brief Tombstone object for all identifiers. */ +struct tombstone_t { + /** + * @brief Converts the tombstone object to identifiers of any type. + * @tparam Entity Type of identifier. + * @return The tombstone representation for the given type. + */ + template + [[nodiscard]] constexpr operator Entity() const noexcept { + using traits_type = entt_traits; + constexpr auto value = traits_type::construct(traits_type::entity_mask, traits_type::version_mask); + return value; + } + + /** + * @brief Compares two tombstone objects. + * @param other A tombstone object. + * @return True in all cases. + */ + [[nodiscard]] constexpr bool operator==([[maybe_unused]] const tombstone_t other) const noexcept { + return true; + } + + /** + * @brief Compares two tombstone objects. + * @param other A tombstone object. + * @return False in all cases. + */ + [[nodiscard]] constexpr bool operator!=([[maybe_unused]] const tombstone_t other) const noexcept { + return false; + } + + /** + * @brief Compares a tombstone object and an identifier of any type. + * @tparam Entity Type of identifier. + * @param entity Identifier with which to compare. + * @return False if the two elements differ, true otherwise. + */ + template + [[nodiscard]] constexpr bool operator==(const Entity entity) const noexcept { + using traits_type = entt_traits; + + if constexpr(traits_type::version_mask == 0u) { + return false; + } else { + return (traits_type::to_version(entity) == traits_type::to_version(*this)); + } + } + + /** + * @brief Compares a tombstone object and an identifier of any type. + * @tparam Entity Type of identifier. + * @param entity Identifier with which to compare. + * @return True if the two elements differ, false otherwise. + */ + template + [[nodiscard]] constexpr bool operator!=(const Entity entity) const noexcept { + return !(entity == *this); + } +}; + +/** + * @brief Compares a tombstone object and an identifier of any type. + * @tparam Entity Type of identifier. + * @param lhs Identifier with which to compare. + * @param rhs A tombstone object yet to be converted. + * @return False if the two elements differ, true otherwise. + */ +template +[[nodiscard]] constexpr bool operator==(const Entity lhs, const tombstone_t rhs) noexcept { + return rhs.operator==(lhs); +} + +/** + * @brief Compares a tombstone object and an identifier of any type. + * @tparam Entity Type of identifier. + * @param lhs Identifier with which to compare. + * @param rhs A tombstone object yet to be converted. + * @return True if the two elements differ, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator!=(const Entity lhs, const tombstone_t rhs) noexcept { + return !(rhs == lhs); +} + +/** + * @brief Compile-time constant for null entities. + * + * There exist implicit conversions from this variable to identifiers of any + * allowed type. Similarly, there exist comparison operators between the null + * entity and any other identifier. + */ +inline constexpr null_t null{}; + +/** + * @brief Compile-time constant for tombstone entities. + * + * There exist implicit conversions from this variable to identifiers of any + * allowed type. Similarly, there exist comparison operators between the + * tombstone entity and any other identifier. + */ +inline constexpr tombstone_t tombstone{}; + +} // namespace entt + +#endif + +// #include "fwd.hpp" + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +class extended_group_iterator; + +template +class extended_group_iterator, get_t> { + template + [[nodiscard]] auto index_to_element([[maybe_unused]] Type &cpool) const { + if constexpr(std::is_void_v) { + return std::make_tuple(); + } else { + return std::forward_as_tuple(cpool.rbegin()[it.index()]); + } + } + +public: + using iterator_type = It; + using value_type = decltype(std::tuple_cat(std::make_tuple(*std::declval()), std::declval().get_as_tuple({})..., std::declval().get_as_tuple({})...)); + using pointer = input_iterator_pointer; + using reference = value_type; + using difference_type = std::ptrdiff_t; + using iterator_category = std::input_iterator_tag; + using iterator_concept = std::forward_iterator_tag; + + constexpr extended_group_iterator() + : it{}, + pools{} {} + + extended_group_iterator(iterator_type from, std::tuple cpools) + : it{from}, + pools{std::move(cpools)} {} + + extended_group_iterator &operator++() noexcept { + return ++it, *this; + } + + extended_group_iterator operator++(int) noexcept { + const extended_group_iterator orig = *this; + return ++(*this), orig; + } + + [[nodiscard]] reference operator*() const noexcept { + return std::tuple_cat(std::make_tuple(*it), index_to_element(*std::get(pools))..., std::get(pools)->get_as_tuple(*it)...); + } + + [[nodiscard]] pointer operator->() const noexcept { + return operator*(); + } + + [[nodiscard]] constexpr iterator_type base() const noexcept { + return it; + } + + template + friend constexpr bool operator==(const extended_group_iterator &, const extended_group_iterator &) noexcept; + +private: + It it; + std::tuple pools; +}; + +template +[[nodiscard]] constexpr bool operator==(const extended_group_iterator &lhs, const extended_group_iterator &rhs) noexcept { + return lhs.it == rhs.it; +} + +template +[[nodiscard]] constexpr bool operator!=(const extended_group_iterator &lhs, const extended_group_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +struct group_descriptor { + using size_type = std::size_t; + virtual ~group_descriptor() = default; + [[nodiscard]] virtual bool owned(const id_type) const noexcept { + return false; + } +}; + +template +class group_handler final: public group_descriptor { + using entity_type = typename Type::entity_type; + + void swap_elements(const std::size_t pos, const entity_type entt) { + for(size_type next{}; next < Owned; ++next) { + pools[next]->swap_elements((*pools[next])[pos], entt); + } + } + + void push_on_construct(const entity_type entt) { + if(std::apply([entt, pos = len](auto *cpool, auto *...other) { return cpool->contains(entt) && !(cpool->index(entt) < pos) && (other->contains(entt) && ...); }, pools) + && std::apply([entt](auto *...cpool) { return (!cpool->contains(entt) && ...); }, filter)) { + swap_elements(len++, entt); + } + } + + void push_on_destroy(const entity_type entt) { + if(std::apply([entt, pos = len](auto *cpool, auto *...other) { return cpool->contains(entt) && !(cpool->index(entt) < pos) && (other->contains(entt) && ...); }, pools) + && std::apply([entt](auto *...cpool) { return (0u + ... + cpool->contains(entt)) == 1u; }, filter)) { + swap_elements(len++, entt); + } + } + + void remove_if(const entity_type entt) { + if(pools[0u]->contains(entt) && (pools[0u]->index(entt) < len)) { + swap_elements(--len, entt); + } + } + + void common_setup() { + // we cannot iterate backwards because we want to leave behind valid entities in case of owned types + for(auto first = pools[0u]->rbegin(), last = first + static_cast(pools[0u]->size()); first != last; ++first) { + push_on_construct(*first); + } + } + +public: + using common_type = Type; + using size_type = typename Type::size_type; + + template + group_handler(std::tuple ogpool, std::tuple epool) + : pools{std::apply([](auto &&...cpool) { return std::array{&cpool...}; }, ogpool)}, + filter{std::apply([](auto &&...cpool) { return std::array{&cpool...}; }, epool)} { + std::apply([this](auto &...cpool) { ((cpool.on_construct().template connect<&group_handler::push_on_construct>(*this), cpool.on_destroy().template connect<&group_handler::remove_if>(*this)), ...); }, ogpool); + std::apply([this](auto &...cpool) { ((cpool.on_construct().template connect<&group_handler::remove_if>(*this), cpool.on_destroy().template connect<&group_handler::push_on_destroy>(*this)), ...); }, epool); + common_setup(); + } + + [[nodiscard]] bool owned(const id_type hash) const noexcept override { + for(size_type pos{}; pos < Owned; ++pos) { + if(pools[pos]->info().hash() == hash) { + return true; + } + } + + return false; + } + + [[nodiscard]] size_type length() const noexcept { + return len; + } + + template + [[nodiscard]] common_type *storage() const noexcept { + if constexpr(Index < (Owned + Get)) { + return pools[Index]; + } else { + return filter[Index - (Owned + Get)]; + } + } + +private: + std::array pools; + std::array filter; + std::size_t len{}; +}; + +template +class group_handler final: public group_descriptor { + using entity_type = typename Type::entity_type; + + void push_on_construct(const entity_type entt) { + if(!elem.contains(entt) + && std::apply([entt](auto *...cpool) { return (cpool->contains(entt) && ...); }, pools) + && std::apply([entt](auto *...cpool) { return (!cpool->contains(entt) && ...); }, filter)) { + elem.push(entt); + } + } + + void push_on_destroy(const entity_type entt) { + if(!elem.contains(entt) + && std::apply([entt](auto *...cpool) { return (cpool->contains(entt) && ...); }, pools) + && std::apply([entt](auto *...cpool) { return (0u + ... + cpool->contains(entt)) == 1u; }, filter)) { + elem.push(entt); + } + } + + void remove_if(const entity_type entt) { + elem.remove(entt); + } + + void common_setup() { + for(const auto entity: *pools[0u]) { + push_on_construct(entity); + } + } + +public: + using common_type = Type; + + template + group_handler(const Allocator &allocator, std::tuple gpool, std::tuple epool) + : pools{std::apply([](auto &&...cpool) { return std::array{&cpool...}; }, gpool)}, + filter{std::apply([](auto &&...cpool) { return std::array{&cpool...}; }, epool)}, + elem{allocator} { + std::apply([this](auto &...cpool) { ((cpool.on_construct().template connect<&group_handler::push_on_construct>(*this), cpool.on_destroy().template connect<&group_handler::remove_if>(*this)), ...); }, gpool); + std::apply([this](auto &...cpool) { ((cpool.on_construct().template connect<&group_handler::remove_if>(*this), cpool.on_destroy().template connect<&group_handler::push_on_destroy>(*this)), ...); }, epool); + common_setup(); + } + + [[nodiscard]] common_type &handle() noexcept { + return elem; + } + + [[nodiscard]] const common_type &handle() const noexcept { + return elem; + } + + template + [[nodiscard]] common_type *storage() const noexcept { + if constexpr(Index < Get) { + return pools[Index]; + } else { + return filter[Index - Get]; + } + } + +private: + std::array pools; + std::array filter; + common_type elem; +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Group. + * + * Primary template isn't defined on purpose. All the specializations give a + * compile-time error, but for a few reasonable cases. + */ +template +class basic_group; + +/** + * @brief Non-owning group. + * + * A non-owning group returns all entities and only the entities that are at + * least in the given storage. Moreover, it's guaranteed that the entity list is + * tightly packed in memory for fast iterations. + * + * @b Important + * + * Iterators aren't invalidated if: + * + * * New elements are added to the storage. + * * The entity currently pointed is modified (for example, elements are added + * or removed from it). + * * The entity currently pointed is destroyed. + * + * In all other cases, modifying the pools iterated by the group in any way + * invalidates all the iterators. + * + * @tparam Get Types of storage _observed_ by the group. + * @tparam Exclude Types of storage used to filter the group. + */ +template +class basic_group, get_t, exclude_t> { + using base_type = std::common_type_t; + using underlying_type = typename base_type::entity_type; + + template + static constexpr std::size_t index_of = type_list_index_v, type_list>; + + template + [[nodiscard]] auto pools_for(std::index_sequence) const noexcept { + using return_type = std::tuple; + return descriptor ? return_type{static_cast(descriptor->template storage())...} : return_type{}; + } + +public: + /*! @brief Underlying entity identifier. */ + using entity_type = underlying_type; + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + /*! @brief Signed integer type. */ + using difference_type = std::ptrdiff_t; + /*! @brief Common type among all storage types. */ + using common_type = base_type; + /*! @brief Random access iterator type. */ + using iterator = typename common_type::iterator; + /*! @brief Reverse iterator type. */ + using reverse_iterator = typename common_type::reverse_iterator; + /*! @brief Iterable group type. */ + using iterable = iterable_adaptor, get_t>>; + /*! @brief Group handler type. */ + using handler = internal::group_handler; + + /** + * @brief Group opaque identifier. + * @return Group opaque identifier. + */ + static id_type group_id() noexcept { + return type_hash, get_t...>, exclude_t...>>>::value(); + } + + /*! @brief Default constructor to use to create empty, invalid groups. */ + basic_group() noexcept + : descriptor{} {} + + /** + * @brief Constructs a group from a set of storage classes. + * @param ref A reference to a group handler. + */ + basic_group(handler &ref) noexcept + : descriptor{&ref} {} + + /** + * @brief Returns the leading storage of a group. + * @return The leading storage of the group. + */ + [[nodiscard]] const common_type &handle() const noexcept { + return descriptor->handle(); + } + + /** + * @brief Returns the storage for a given element type, if any. + * @tparam Type Type of element of which to return the storage. + * @return The storage for the given element type. + */ + template + [[nodiscard]] auto *storage() const noexcept { + return storage>(); + } + + /** + * @brief Returns the storage for a given index, if any. + * @tparam Index Index of the storage to return. + * @return The storage for the given index. + */ + template + [[nodiscard]] auto *storage() const noexcept { + using type = type_list_element_t>; + return *this ? static_cast(descriptor->template storage()) : nullptr; + } + + /** + * @brief Returns the number of entities that are part of the group. + * @return Number of entities that are part of the group. + */ + [[nodiscard]] size_type size() const noexcept { + return *this ? handle().size() : size_type{}; + } + + /** + * @brief Returns the number of elements that a group has currently + * allocated space for. + * @return Capacity of the group. + */ + [[nodiscard]] size_type capacity() const noexcept { + return *this ? handle().capacity() : size_type{}; + } + + /*! @brief Requests the removal of unused capacity. */ + void shrink_to_fit() { + if(*this) { + descriptor->handle().shrink_to_fit(); + } + } + + /** + * @brief Checks whether a group is empty. + * @return True if the group is empty, false otherwise. + */ + [[nodiscard]] bool empty() const noexcept { + return !*this || handle().empty(); + } + + /** + * @brief Returns an iterator to the first entity of the group. + * + * If the group is empty, the returned iterator will be equal to `end()`. + * + * @return An iterator to the first entity of the group. + */ + [[nodiscard]] iterator begin() const noexcept { + return *this ? handle().begin() : iterator{}; + } + + /** + * @brief Returns an iterator that is past the last entity of the group. + * @return An iterator to the entity following the last entity of the + * group. + */ + [[nodiscard]] iterator end() const noexcept { + return *this ? handle().end() : iterator{}; + } + + /** + * @brief Returns an iterator to the first entity of the reversed group. + * + * If the group is empty, the returned iterator will be equal to `rend()`. + * + * @return An iterator to the first entity of the reversed group. + */ + [[nodiscard]] reverse_iterator rbegin() const noexcept { + return *this ? handle().rbegin() : reverse_iterator{}; + } + + /** + * @brief Returns an iterator that is past the last entity of the reversed + * group. + * @return An iterator to the entity following the last entity of the + * reversed group. + */ + [[nodiscard]] reverse_iterator rend() const noexcept { + return *this ? handle().rend() : reverse_iterator{}; + } + + /** + * @brief Returns the first entity of the group, if any. + * @return The first entity of the group if one exists, the null entity + * otherwise. + */ + [[nodiscard]] entity_type front() const noexcept { + const auto it = begin(); + return it != end() ? *it : null; + } + + /** + * @brief Returns the last entity of the group, if any. + * @return The last entity of the group if one exists, the null entity + * otherwise. + */ + [[nodiscard]] entity_type back() const noexcept { + const auto it = rbegin(); + return it != rend() ? *it : null; + } + + /** + * @brief Finds an entity. + * @param entt A valid identifier. + * @return An iterator to the given entity if it's found, past the end + * iterator otherwise. + */ + [[nodiscard]] iterator find(const entity_type entt) const noexcept { + return *this ? handle().find(entt) : iterator{}; + } + + /** + * @brief Returns the identifier that occupies the given position. + * @param pos Position of the element to return. + * @return The identifier that occupies the given position. + */ + [[nodiscard]] entity_type operator[](const size_type pos) const { + return begin()[static_cast(pos)]; + } + + /** + * @brief Checks if a group is properly initialized. + * @return True if the group is properly initialized, false otherwise. + */ + [[nodiscard]] explicit operator bool() const noexcept { + return descriptor != nullptr; + } + + /** + * @brief Checks if a group contains an entity. + * @param entt A valid identifier. + * @return True if the group contains the given entity, false otherwise. + */ + [[nodiscard]] bool contains(const entity_type entt) const noexcept { + return *this && handle().contains(entt); + } + + /** + * @brief Returns the elements assigned to the given entity. + * @tparam Type Type of the element to get. + * @tparam Other Other types of elements to get. + * @param entt A valid identifier. + * @return The elements assigned to the entity. + */ + template + [[nodiscard]] decltype(auto) get(const entity_type entt) const { + return get, index_of...>(entt); + } + + /** + * @brief Returns the elements assigned to the given entity. + * @tparam Index Indexes of the elements to get. + * @param entt A valid identifier. + * @return The elements assigned to the entity. + */ + template + [[nodiscard]] decltype(auto) get(const entity_type entt) const { + const auto cpools = pools_for(std::index_sequence_for{}); + + if constexpr(sizeof...(Index) == 0) { + return std::apply([entt](auto *...curr) { return std::tuple_cat(curr->get_as_tuple(entt)...); }, cpools); + } else if constexpr(sizeof...(Index) == 1) { + return (std::get(cpools)->get(entt), ...); + } else { + return std::tuple_cat(std::get(cpools)->get_as_tuple(entt)...); + } + } + + /** + * @brief Iterates entities and elements and applies the given function + * object to them. + * + * The function object is invoked for each entity. It is provided with the + * entity itself and a set of references to non-empty elements. The + * _constness_ of the elements is as requested.
+ * The signature of the function must be equivalent to one of the following + * forms: + * + * @code{.cpp} + * void(const entity_type, Type &...); + * void(Type &...); + * @endcode + * + * @note + * Empty types aren't explicitly instantiated and therefore they are never + * returned during iterations. + * + * @tparam Func Type of the function object to invoke. + * @param func A valid function object. + */ + template + void each(Func func) const { + for(const auto entt: *this) { + if constexpr(is_applicable_v{}, std::declval().get({})))>) { + std::apply(func, std::tuple_cat(std::make_tuple(entt), get(entt))); + } else { + std::apply(func, get(entt)); + } + } + } + + /** + * @brief Returns an iterable object to use to _visit_ a group. + * + * The iterable object returns tuples that contain the current entity and a + * set of references to its non-empty elements. The _constness_ of the + * elements is as requested. + * + * @note + * Empty types aren't explicitly instantiated and therefore they are never + * returned during iterations. + * + * @return An iterable object to use to _visit_ the group. + */ + [[nodiscard]] iterable each() const noexcept { + const auto cpools = pools_for(std::index_sequence_for{}); + return iterable{{begin(), cpools}, {end(), cpools}}; + } + + /** + * @brief Sort a group according to the given comparison function. + * + * The comparison function object must return `true` if the first element + * is _less_ than the second one, `false` otherwise. The signature of the + * comparison function should be equivalent to one of the following: + * + * @code{.cpp} + * bool(std::tuple, std::tuple); + * bool(const Type &..., const Type &...); + * bool(const Entity, const Entity); + * @endcode + * + * Where `Type` are such that they are iterated by the group.
+ * Moreover, the comparison function object shall induce a + * _strict weak ordering_ on the values. + * + * The sort function object must offer a member function template + * `operator()` that accepts three arguments: + * + * * An iterator to the first element of the range to sort. + * * An iterator past the last element of the range to sort. + * * A comparison function to use to compare the elements. + * + * @tparam Type Optional type of element to compare. + * @tparam Other Other optional types of elements to compare. + * @tparam Compare Type of comparison function object. + * @tparam Sort Type of sort function object. + * @tparam Args Types of arguments to forward to the sort function object. + * @param compare A valid comparison function object. + * @param algo A valid sort function object. + * @param args Arguments to forward to the sort function object, if any. + */ + template + void sort(Compare compare, Sort algo = Sort{}, Args &&...args) { + sort, index_of...>(std::move(compare), std::move(algo), std::forward(args)...); + } + + /** + * @brief Sort a group according to the given comparison function. + * + * @sa sort + * + * @tparam Index Optional indexes of elements to compare. + * @tparam Compare Type of comparison function object. + * @tparam Sort Type of sort function object. + * @tparam Args Types of arguments to forward to the sort function object. + * @param compare A valid comparison function object. + * @param algo A valid sort function object. + * @param args Arguments to forward to the sort function object, if any. + */ + template + void sort(Compare compare, Sort algo = Sort{}, Args &&...args) { + if(*this) { + if constexpr(sizeof...(Index) == 0) { + static_assert(std::is_invocable_v, "Invalid comparison function"); + descriptor->handle().sort(std::move(compare), std::move(algo), std::forward(args)...); + } else { + auto comp = [&compare, cpools = pools_for(std::index_sequence_for{})](const entity_type lhs, const entity_type rhs) { + if constexpr(sizeof...(Index) == 1) { + return compare((std::get(cpools)->get(lhs), ...), (std::get(cpools)->get(rhs), ...)); + } else { + return compare(std::forward_as_tuple(std::get(cpools)->get(lhs)...), std::forward_as_tuple(std::get(cpools)->get(rhs)...)); + } + }; + + descriptor->handle().sort(std::move(comp), std::move(algo), std::forward(args)...); + } + } + } + + /** + * @brief Sort entities according to their order in a range. + * + * The shared pool of entities and thus its order is affected by the changes + * to each and every pool that it tracks. + * + * @tparam It Type of input iterator. + * @param first An iterator to the first element of the range of entities. + * @param last An iterator past the last element of the range of entities. + */ + template + void sort_as(It first, It last) const { + if(*this) { + descriptor->handle().sort_as(first, last); + } + } + +private: + handler *descriptor; +}; + +/** + * @brief Owning group. + * + * Owning groups returns all entities and only the entities that are at + * least in the given storage. Moreover: + * + * * It's guaranteed that the entity list is tightly packed in memory for fast + * iterations. + * * It's guaranteed that all elements in the owned storage are tightly packed + * in memory for even faster iterations and to allow direct access. + * * They stay true to the order of the owned storage and all instances have the + * same order in memory. + * + * The more types of storage are owned, the faster it is to iterate a group. + * + * @b Important + * + * Iterators aren't invalidated if: + * + * * New elements are added to the storage. + * * The entity currently pointed is modified (for example, elements are added + * or removed from it). + * * The entity currently pointed is destroyed. + * + * In all other cases, modifying the pools iterated by the group in any way + * invalidates all the iterators. + * + * @tparam Owned Types of storage _owned_ by the group. + * @tparam Get Types of storage _observed_ by the group. + * @tparam Exclude Types of storage used to filter the group. + */ +template +class basic_group, get_t, exclude_t> { + static_assert(((Owned::storage_policy != deletion_policy::in_place) && ...), "Groups do not support in-place delete"); + + using base_type = std::common_type_t; + using underlying_type = typename base_type::entity_type; + + template + static constexpr std::size_t index_of = type_list_index_v, type_list>; + + template + [[nodiscard]] auto pools_for(std::index_sequence, std::index_sequence) const noexcept { + using return_type = std::tuple; + return descriptor ? return_type{static_cast(descriptor->template storage())..., static_cast(descriptor->template storage())...} : return_type{}; + } + +public: + /*! @brief Underlying entity identifier. */ + using entity_type = underlying_type; + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + /*! @brief Signed integer type. */ + using difference_type = std::ptrdiff_t; + /*! @brief Common type among all storage types. */ + using common_type = base_type; + /*! @brief Random access iterator type. */ + using iterator = typename common_type::iterator; + /*! @brief Reverse iterator type. */ + using reverse_iterator = typename common_type::reverse_iterator; + /*! @brief Iterable group type. */ + using iterable = iterable_adaptor, get_t>>; + /*! @brief Group handler type. */ + using handler = internal::group_handler; + + /** + * @brief Group opaque identifier. + * @return Group opaque identifier. + */ + static id_type group_id() noexcept { + return type_hash...>, get_t...>, exclude_t...>>>::value(); + } + + /*! @brief Default constructor to use to create empty, invalid groups. */ + basic_group() noexcept + : descriptor{} {} + + /** + * @brief Constructs a group from a set of storage classes. + * @param ref A reference to a group handler. + */ + basic_group(handler &ref) noexcept + : descriptor{&ref} {} + + /** + * @brief Returns the leading storage of a group. + * @return The leading storage of the group. + */ + [[nodiscard]] const common_type &handle() const noexcept { + return *storage<0>(); + } + + /** + * @brief Returns the storage for a given element type, if any. + * @tparam Type Type of element of which to return the storage. + * @return The storage for the given element type. + */ + template + [[nodiscard]] auto *storage() const noexcept { + return storage>(); + } + + /** + * @brief Returns the storage for a given index, if any. + * @tparam Index Index of the storage to return. + * @return The storage for the given index. + */ + template + [[nodiscard]] auto *storage() const noexcept { + using type = type_list_element_t>; + return *this ? static_cast(descriptor->template storage()) : nullptr; + } + + /** + * @brief Returns the number of entities that that are part of the group. + * @return Number of entities that that are part of the group. + */ + [[nodiscard]] size_type size() const noexcept { + return *this ? descriptor->length() : size_type{}; + } + + /** + * @brief Checks whether a group is empty. + * @return True if the group is empty, false otherwise. + */ + [[nodiscard]] bool empty() const noexcept { + return !*this || !descriptor->length(); + } + + /** + * @brief Returns an iterator to the first entity of the group. + * + * If the group is empty, the returned iterator will be equal to `end()`. + * + * @return An iterator to the first entity of the group. + */ + [[nodiscard]] iterator begin() const noexcept { + return *this ? (handle().end() - static_cast(descriptor->length())) : iterator{}; + } + + /** + * @brief Returns an iterator that is past the last entity of the group. + * @return An iterator to the entity following the last entity of the + * group. + */ + [[nodiscard]] iterator end() const noexcept { + return *this ? handle().end() : iterator{}; + } + + /** + * @brief Returns an iterator to the first entity of the reversed group. + * + * If the group is empty, the returned iterator will be equal to `rend()`. + * + * @return An iterator to the first entity of the reversed group. + */ + [[nodiscard]] reverse_iterator rbegin() const noexcept { + return *this ? handle().rbegin() : reverse_iterator{}; + } + + /** + * @brief Returns an iterator that is past the last entity of the reversed + * group. + * @return An iterator to the entity following the last entity of the + * reversed group. + */ + [[nodiscard]] reverse_iterator rend() const noexcept { + return *this ? (handle().rbegin() + static_cast(descriptor->length())) : reverse_iterator{}; + } + + /** + * @brief Returns the first entity of the group, if any. + * @return The first entity of the group if one exists, the null entity + * otherwise. + */ + [[nodiscard]] entity_type front() const noexcept { + const auto it = begin(); + return it != end() ? *it : null; + } + + /** + * @brief Returns the last entity of the group, if any. + * @return The last entity of the group if one exists, the null entity + * otherwise. + */ + [[nodiscard]] entity_type back() const noexcept { + const auto it = rbegin(); + return it != rend() ? *it : null; + } + + /** + * @brief Finds an entity. + * @param entt A valid identifier. + * @return An iterator to the given entity if it's found, past the end + * iterator otherwise. + */ + [[nodiscard]] iterator find(const entity_type entt) const noexcept { + const auto it = *this ? handle().find(entt) : iterator{}; + return it >= begin() ? it : iterator{}; + } + + /** + * @brief Returns the identifier that occupies the given position. + * @param pos Position of the element to return. + * @return The identifier that occupies the given position. + */ + [[nodiscard]] entity_type operator[](const size_type pos) const { + return begin()[static_cast(pos)]; + } + + /** + * @brief Checks if a group is properly initialized. + * @return True if the group is properly initialized, false otherwise. + */ + [[nodiscard]] explicit operator bool() const noexcept { + return descriptor != nullptr; + } + + /** + * @brief Checks if a group contains an entity. + * @param entt A valid identifier. + * @return True if the group contains the given entity, false otherwise. + */ + [[nodiscard]] bool contains(const entity_type entt) const noexcept { + return *this && handle().contains(entt) && (handle().index(entt) < (descriptor->length())); + } + + /** + * @brief Returns the elements assigned to the given entity. + * @tparam Type Type of the element to get. + * @tparam Other Other types of elements to get. + * @param entt A valid identifier. + * @return The elements assigned to the entity. + */ + template + [[nodiscard]] decltype(auto) get(const entity_type entt) const { + return get, index_of...>(entt); + } + + /** + * @brief Returns the elements assigned to the given entity. + * @tparam Index Indexes of the elements to get. + * @param entt A valid identifier. + * @return The elements assigned to the entity. + */ + template + [[nodiscard]] decltype(auto) get(const entity_type entt) const { + const auto cpools = pools_for(std::index_sequence_for{}, std::index_sequence_for{}); + + if constexpr(sizeof...(Index) == 0) { + return std::apply([entt](auto *...curr) { return std::tuple_cat(curr->get_as_tuple(entt)...); }, cpools); + } else if constexpr(sizeof...(Index) == 1) { + return (std::get(cpools)->get(entt), ...); + } else { + return std::tuple_cat(std::get(cpools)->get_as_tuple(entt)...); + } + } + + /** + * @brief Iterates entities and elements and applies the given function + * object to them. + * + * The function object is invoked for each entity. It is provided with the + * entity itself and a set of references to non-empty elements. The + * _constness_ of the elements is as requested.
+ * The signature of the function must be equivalent to one of the following + * forms: + * + * @code{.cpp} + * void(const entity_type, Type &...); + * void(Type &...); + * @endcode + * + * @note + * Empty types aren't explicitly instantiated and therefore they are never + * returned during iterations. + * + * @tparam Func Type of the function object to invoke. + * @param func A valid function object. + */ + template + void each(Func func) const { + for(auto args: each()) { + if constexpr(is_applicable_v{}, std::declval().get({})))>) { + std::apply(func, args); + } else { + std::apply([&func](auto, auto &&...less) { func(std::forward(less)...); }, args); + } + } + } + + /** + * @brief Returns an iterable object to use to _visit_ a group. + * + * The iterable object returns tuples that contain the current entity and a + * set of references to its non-empty elements. The _constness_ of the + * elements is as requested. + * + * @note + * Empty types aren't explicitly instantiated and therefore they are never + * returned during iterations. + * + * @return An iterable object to use to _visit_ the group. + */ + [[nodiscard]] iterable each() const noexcept { + const auto cpools = pools_for(std::index_sequence_for{}, std::index_sequence_for{}); + return iterable{{begin(), cpools}, {end(), cpools}}; + } + + /** + * @brief Sort a group according to the given comparison function. + * + * The comparison function object must return `true` if the first element + * is _less_ than the second one, `false` otherwise. The signature of the + * comparison function should be equivalent to one of the following: + * + * @code{.cpp} + * bool(std::tuple, std::tuple); + * bool(const Type &, const Type &); + * bool(const Entity, const Entity); + * @endcode + * + * Where `Type` are either owned types or not but still such that they are + * iterated by the group.
+ * Moreover, the comparison function object shall induce a + * _strict weak ordering_ on the values. + * + * The sort function object must offer a member function template + * `operator()` that accepts three arguments: + * + * * An iterator to the first element of the range to sort. + * * An iterator past the last element of the range to sort. + * * A comparison function to use to compare the elements. + * + * @tparam Type Optional type of element to compare. + * @tparam Other Other optional types of elements to compare. + * @tparam Compare Type of comparison function object. + * @tparam Sort Type of sort function object. + * @tparam Args Types of arguments to forward to the sort function object. + * @param compare A valid comparison function object. + * @param algo A valid sort function object. + * @param args Arguments to forward to the sort function object, if any. + */ + template + void sort(Compare compare, Sort algo = Sort{}, Args &&...args) const { + sort, index_of...>(std::move(compare), std::move(algo), std::forward(args)...); + } + + /** + * @brief Sort a group according to the given comparison function. + * + * @sa sort + * + * @tparam Index Optional indexes of elements to compare. + * @tparam Compare Type of comparison function object. + * @tparam Sort Type of sort function object. + * @tparam Args Types of arguments to forward to the sort function object. + * @param compare A valid comparison function object. + * @param algo A valid sort function object. + * @param args Arguments to forward to the sort function object, if any. + */ + template + void sort(Compare compare, Sort algo = Sort{}, Args &&...args) const { + const auto cpools = pools_for(std::index_sequence_for{}, std::index_sequence_for{}); + + if constexpr(sizeof...(Index) == 0) { + static_assert(std::is_invocable_v, "Invalid comparison function"); + storage<0>()->sort_n(descriptor->length(), std::move(compare), std::move(algo), std::forward(args)...); + } else { + auto comp = [&compare, &cpools](const entity_type lhs, const entity_type rhs) { + if constexpr(sizeof...(Index) == 1) { + return compare((std::get(cpools)->get(lhs), ...), (std::get(cpools)->get(rhs), ...)); + } else { + return compare(std::forward_as_tuple(std::get(cpools)->get(lhs)...), std::forward_as_tuple(std::get(cpools)->get(rhs)...)); + } + }; + + storage<0>()->sort_n(descriptor->length(), std::move(comp), std::move(algo), std::forward(args)...); + } + + auto cb = [this](auto *head, auto *...other) { + for(auto next = descriptor->length(); next; --next) { + const auto pos = next - 1; + [[maybe_unused]] const auto entt = head->data()[pos]; + (other->swap_elements(other->data()[pos], entt), ...); + } + }; + + std::apply(cb, cpools); + } + +private: + handler *descriptor; +}; + +} // namespace entt + +#endif + +// #include "entity/handle.hpp" +#ifndef ENTT_ENTITY_HANDLE_HPP +#define ENTT_ENTITY_HANDLE_HPP + +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "../core/iterator.hpp" + +// #include "../core/type_traits.hpp" + +// #include "entity.hpp" + +// #include "fwd.hpp" + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +class handle_storage_iterator final { + template + friend class handle_storage_iterator; + + using underlying_type = std::remove_reference_t; + using entity_type = typename underlying_type::entity_type; + +public: + using value_type = typename std::iterator_traits::value_type; + using pointer = input_iterator_pointer; + using reference = value_type; + using difference_type = std::ptrdiff_t; + using iterator_category = std::input_iterator_tag; + using iterator_concept = std::forward_iterator_tag; + + constexpr handle_storage_iterator() noexcept + : entt{null}, + it{}, + last{} {} + + constexpr handle_storage_iterator(entity_type value, It from, It to) noexcept + : entt{value}, + it{from}, + last{to} { + while(it != last && !it->second.contains(entt)) { + ++it; + } + } + + constexpr handle_storage_iterator &operator++() noexcept { + for(++it; it != last && !it->second.contains(entt); ++it) {} + return *this; + } + + constexpr handle_storage_iterator operator++(int) noexcept { + const handle_storage_iterator orig = *this; + return ++(*this), orig; + } + + [[nodiscard]] constexpr reference operator*() const noexcept { + return *it; + } + + [[nodiscard]] constexpr pointer operator->() const noexcept { + return operator*(); + } + + template + friend constexpr bool operator==(const handle_storage_iterator &, const handle_storage_iterator &) noexcept; + +private: + entity_type entt; + It it; + It last; +}; + +template +[[nodiscard]] constexpr bool operator==(const handle_storage_iterator &lhs, const handle_storage_iterator &rhs) noexcept { + return lhs.it == rhs.it; +} + +template +[[nodiscard]] constexpr bool operator!=(const handle_storage_iterator &lhs, const handle_storage_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Non-owning handle to an entity. + * + * Tiny wrapper around a registry and an entity. + * + * @tparam Registry Basic registry type. + * @tparam Scope Types to which to restrict the scope of a handle. + */ +template +class basic_handle { + using traits_type = entt_traits; + + [[nodiscard]] auto &owner_or_assert() const noexcept { + ENTT_ASSERT(owner != nullptr, "Invalid pointer to registry"); + return static_cast(*owner); + } + +public: + /*! @brief Type of registry accepted by the handle. */ + using registry_type = Registry; + /*! @brief Underlying entity identifier. */ + using entity_type = typename traits_type::value_type; + /*! @brief Underlying version type. */ + using version_type = typename traits_type::version_type; + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + /*! @brief Iterable handle type. */ + using iterable = iterable_adaptor().storage())::iterator>>; + + /*! @brief Constructs an invalid handle. */ + basic_handle() noexcept + : owner{}, + entt{null} {} + + /** + * @brief Constructs a handle from a given registry and entity. + * @param ref An instance of the registry class. + * @param value A valid identifier. + */ + basic_handle(registry_type &ref, entity_type value) noexcept + : owner{&ref}, + entt{value} {} + + /** + * @brief Returns an iterable object to use to _visit_ a handle. + * + * The iterable object returns a pair that contains the name and a reference + * to the current storage.
+ * Returned storage are those that contain the entity associated with the + * handle. + * + * @return An iterable object to use to _visit_ the handle. + */ + [[nodiscard]] iterable storage() const noexcept { + auto underlying = owner_or_assert().storage(); + return iterable{{entt, underlying.begin(), underlying.end()}, {entt, underlying.end(), underlying.end()}}; + } + + /*! @copydoc valid */ + [[nodiscard]] explicit operator bool() const noexcept { + return owner && owner->valid(entt); + } + + /** + * @brief Checks if a handle refers to a valid registry and entity. + * @return True if the handle refers to a valid registry and entity, false + * otherwise. + */ + [[nodiscard]] bool valid() const { + return static_cast(*this); + } + + /** + * @brief Returns a pointer to the underlying registry, if any. + * @return A pointer to the underlying registry, if any. + */ + [[nodiscard]] registry_type *registry() const noexcept { + return owner; + } + + /** + * @brief Returns the entity associated with a handle. + * @return The entity associated with the handle. + */ + [[nodiscard]] entity_type entity() const noexcept { + return entt; + } + + /*! @copydoc entity */ + [[nodiscard]] operator entity_type() const noexcept { + return entity(); + } + + /*! @brief Destroys the entity associated with a handle. */ + void destroy() { + owner_or_assert().destroy(std::exchange(entt, null)); + } + + /** + * @brief Destroys the entity associated with a handle. + * @param version A desired version upon destruction. + */ + void destroy(const version_type version) { + owner_or_assert().destroy(std::exchange(entt, null), version); + } + + /** + * @brief Assigns the given element to a handle. + * @tparam Type Type of element to create. + * @tparam Args Types of arguments to use to construct the element. + * @param args Parameters to use to initialize the element. + * @return A reference to the newly created element. + */ + template + // NOLINTNEXTLINE(modernize-use-nodiscard) + decltype(auto) emplace(Args &&...args) const { + static_assert(((sizeof...(Scope) == 0) || ... || std::is_same_v), "Invalid type"); + return owner_or_assert().template emplace(entt, std::forward(args)...); + } + + /** + * @brief Assigns or replaces the given element for a handle. + * @tparam Type Type of element to assign or replace. + * @tparam Args Types of arguments to use to construct the element. + * @param args Parameters to use to initialize the element. + * @return A reference to the newly created element. + */ + template + decltype(auto) emplace_or_replace(Args &&...args) const { + static_assert(((sizeof...(Scope) == 0) || ... || std::is_same_v), "Invalid type"); + return owner_or_assert().template emplace_or_replace(entt, std::forward(args)...); + } + + /** + * @brief Patches the given element for a handle. + * @tparam Type Type of element to patch. + * @tparam Func Types of the function objects to invoke. + * @param func Valid function objects. + * @return A reference to the patched element. + */ + template + decltype(auto) patch(Func &&...func) const { + static_assert(((sizeof...(Scope) == 0) || ... || std::is_same_v), "Invalid type"); + return owner_or_assert().template patch(entt, std::forward(func)...); + } + + /** + * @brief Replaces the given element for a handle. + * @tparam Type Type of element to replace. + * @tparam Args Types of arguments to use to construct the element. + * @param args Parameters to use to initialize the element. + * @return A reference to the element being replaced. + */ + template + decltype(auto) replace(Args &&...args) const { + static_assert(((sizeof...(Scope) == 0) || ... || std::is_same_v), "Invalid type"); + return owner_or_assert().template replace(entt, std::forward(args)...); + } + + /** + * @brief Removes the given elements from a handle. + * @tparam Type Types of elements to remove. + * @return The number of elements actually removed. + */ + template + // NOLINTNEXTLINE(modernize-use-nodiscard) + size_type remove() const { + static_assert(sizeof...(Scope) == 0 || (type_list_contains_v, Type> && ...), "Invalid type"); + return owner_or_assert().template remove(entt); + } + + /** + * @brief Erases the given elements from a handle. + * @tparam Type Types of elements to erase. + */ + template + void erase() const { + static_assert(sizeof...(Scope) == 0 || (type_list_contains_v, Type> && ...), "Invalid type"); + owner_or_assert().template erase(entt); + } + + /** + * @brief Checks if a handle has all the given elements. + * @tparam Type Elements for which to perform the check. + * @return True if the handle has all the elements, false otherwise. + */ + template + [[nodiscard]] decltype(auto) all_of() const { + return owner_or_assert().template all_of(entt); + } + + /** + * @brief Checks if a handle has at least one of the given elements. + * @tparam Type Elements for which to perform the check. + * @return True if the handle has at least one of the given elements, + * false otherwise. + */ + template + [[nodiscard]] decltype(auto) any_of() const { + return owner_or_assert().template any_of(entt); + } + + /** + * @brief Returns references to the given elements for a handle. + * @tparam Type Types of elements to get. + * @return References to the elements owned by the handle. + */ + template + [[nodiscard]] decltype(auto) get() const { + static_assert(sizeof...(Scope) == 0 || (type_list_contains_v, Type> && ...), "Invalid type"); + return owner_or_assert().template get(entt); + } + + /** + * @brief Returns a reference to the given element for a handle. + * @tparam Type Type of element to get. + * @tparam Args Types of arguments to use to construct the element. + * @param args Parameters to use to initialize the element. + * @return Reference to the element owned by the handle. + */ + template + [[nodiscard]] decltype(auto) get_or_emplace(Args &&...args) const { + static_assert(((sizeof...(Scope) == 0) || ... || std::is_same_v), "Invalid type"); + return owner_or_assert().template get_or_emplace(entt, std::forward(args)...); + } + + /** + * @brief Returns pointers to the given elements for a handle. + * @tparam Type Types of elements to get. + * @return Pointers to the elements owned by the handle. + */ + template + [[nodiscard]] auto try_get() const { + static_assert(sizeof...(Scope) == 0 || (type_list_contains_v, Type> && ...), "Invalid type"); + return owner_or_assert().template try_get(entt); + } + + /** + * @brief Checks if a handle has elements assigned. + * @return True if the handle has no elements assigned, false otherwise. + */ + [[nodiscard]] bool orphan() const { + return owner_or_assert().orphan(entt); + } + + /** + * @brief Returns a const handle from a non-const one. + * @tparam Other A valid entity type. + * @tparam Args Scope of the handle to construct. + * @return A const handle referring to the same registry and the same + * entity. + */ + template + operator basic_handle() const noexcept { + static_assert(std::is_same_v || std::is_same_v, Registry>, "Invalid conversion between different handles"); + static_assert((sizeof...(Scope) == 0 || ((sizeof...(Args) != 0 && sizeof...(Args) <= sizeof...(Scope)) && ... && (type_list_contains_v, Args>))), "Invalid conversion between different handles"); + return owner ? basic_handle{*owner, entt} : basic_handle{}; + } + +private: + registry_type *owner; + entity_type entt; +}; + +/** + * @brief Compares two handles. + * @tparam Args Scope of the first handle. + * @tparam Other Scope of the second handle. + * @param lhs A valid handle. + * @param rhs A valid handle. + * @return True if both handles refer to the same registry and the same + * entity, false otherwise. + */ +template +[[nodiscard]] bool operator==(const basic_handle &lhs, const basic_handle &rhs) noexcept { + return lhs.registry() == rhs.registry() && lhs.entity() == rhs.entity(); +} + +/** + * @brief Compares two handles. + * @tparam Args Scope of the first handle. + * @tparam Other Scope of the second handle. + * @param lhs A valid handle. + * @param rhs A valid handle. + * @return False if both handles refer to the same registry and the same + * entity, true otherwise. + */ +template +[[nodiscard]] bool operator!=(const basic_handle &lhs, const basic_handle &rhs) noexcept { + return !(lhs == rhs); +} + +/** + * @brief Compares a handle with the null object. + * @tparam Args Scope of the handle. + * @param lhs A valid handle. + * @param rhs A null object yet to be converted. + * @return False if the two elements differ, true otherwise. + */ +template +[[nodiscard]] constexpr bool operator==(const basic_handle &lhs, const null_t rhs) noexcept { + return (lhs.entity() == rhs); +} + +/** + * @brief Compares a handle with the null object. + * @tparam Args Scope of the handle. + * @param lhs A null object yet to be converted. + * @param rhs A valid handle. + * @return False if the two elements differ, true otherwise. + */ +template +[[nodiscard]] constexpr bool operator==(const null_t lhs, const basic_handle &rhs) noexcept { + return (rhs == lhs); +} + +/** + * @brief Compares a handle with the null object. + * @tparam Args Scope of the handle. + * @param lhs A valid handle. + * @param rhs A null object yet to be converted. + * @return True if the two elements differ, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator!=(const basic_handle &lhs, const null_t rhs) noexcept { + return (lhs.entity() != rhs); +} + +/** + * @brief Compares a handle with the null object. + * @tparam Args Scope of the handle. + * @param lhs A null object yet to be converted. + * @param rhs A valid handle. + * @return True if the two elements differ, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator!=(const null_t lhs, const basic_handle &rhs) noexcept { + return (rhs != lhs); +} + +} // namespace entt + +#endif + +// #include "entity/helper.hpp" +#ifndef ENTT_ENTITY_HELPER_HPP +#define ENTT_ENTITY_HELPER_HPP + +#include +#include +#include +// #include "../core/fwd.hpp" + +// #include "../core/type_traits.hpp" + +// #include "component.hpp" +#ifndef ENTT_ENTITY_COMPONENT_HPP +#define ENTT_ENTITY_COMPONENT_HPP + +#include +#include +// #include "../config/config.h" + +// #include "fwd.hpp" + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct in_place_delete: std::bool_constant && std::is_move_assignable_v)> {}; + +template<> +struct in_place_delete: std::false_type {}; + +template +struct in_place_delete> + : std::true_type {}; + +template +struct page_size: std::integral_constant * ENTT_PACKED_PAGE> {}; + +template<> +struct page_size: std::integral_constant {}; + +template +struct page_size> + : std::integral_constant {}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Common way to access various properties of components. + * @tparam Type Element type. + * @tparam Entity A valid entity type. + */ +template +struct component_traits { + static_assert(std::is_same_v, Type>, "Unsupported type"); + + /*! @brief Element type. */ + using element_type = Type; + /*! @brief Underlying entity identifier. */ + using entity_type = Entity; + + /*! @brief Pointer stability, default is `false`. */ + static constexpr bool in_place_delete = internal::in_place_delete::value; + /*! @brief Page size, default is `ENTT_PACKED_PAGE` for non-empty types. */ + static constexpr std::size_t page_size = internal::page_size::value; +}; + +} // namespace entt + +#endif + +// #include "fwd.hpp" + +// #include "group.hpp" +#ifndef ENTT_ENTITY_GROUP_HPP +#define ENTT_ENTITY_GROUP_HPP + +#include +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "../core/algorithm.hpp" + +// #include "../core/fwd.hpp" + +// #include "../core/iterator.hpp" + +// #include "../core/type_info.hpp" + +// #include "../core/type_traits.hpp" + +// #include "entity.hpp" + +// #include "fwd.hpp" + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +class extended_group_iterator; + +template +class extended_group_iterator, get_t> { + template + [[nodiscard]] auto index_to_element([[maybe_unused]] Type &cpool) const { + if constexpr(std::is_void_v) { + return std::make_tuple(); + } else { + return std::forward_as_tuple(cpool.rbegin()[it.index()]); + } + } + +public: + using iterator_type = It; + using value_type = decltype(std::tuple_cat(std::make_tuple(*std::declval()), std::declval().get_as_tuple({})..., std::declval().get_as_tuple({})...)); + using pointer = input_iterator_pointer; + using reference = value_type; + using difference_type = std::ptrdiff_t; + using iterator_category = std::input_iterator_tag; + using iterator_concept = std::forward_iterator_tag; + + constexpr extended_group_iterator() + : it{}, + pools{} {} + + extended_group_iterator(iterator_type from, std::tuple cpools) + : it{from}, + pools{std::move(cpools)} {} + + extended_group_iterator &operator++() noexcept { + return ++it, *this; + } + + extended_group_iterator operator++(int) noexcept { + const extended_group_iterator orig = *this; + return ++(*this), orig; + } + + [[nodiscard]] reference operator*() const noexcept { + return std::tuple_cat(std::make_tuple(*it), index_to_element(*std::get(pools))..., std::get(pools)->get_as_tuple(*it)...); + } + + [[nodiscard]] pointer operator->() const noexcept { + return operator*(); + } + + [[nodiscard]] constexpr iterator_type base() const noexcept { + return it; + } + + template + friend constexpr bool operator==(const extended_group_iterator &, const extended_group_iterator &) noexcept; + +private: + It it; + std::tuple pools; +}; + +template +[[nodiscard]] constexpr bool operator==(const extended_group_iterator &lhs, const extended_group_iterator &rhs) noexcept { + return lhs.it == rhs.it; +} + +template +[[nodiscard]] constexpr bool operator!=(const extended_group_iterator &lhs, const extended_group_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +struct group_descriptor { + using size_type = std::size_t; + virtual ~group_descriptor() = default; + [[nodiscard]] virtual bool owned(const id_type) const noexcept { + return false; + } +}; + +template +class group_handler final: public group_descriptor { + using entity_type = typename Type::entity_type; + + void swap_elements(const std::size_t pos, const entity_type entt) { + for(size_type next{}; next < Owned; ++next) { + pools[next]->swap_elements((*pools[next])[pos], entt); + } + } + + void push_on_construct(const entity_type entt) { + if(std::apply([entt, pos = len](auto *cpool, auto *...other) { return cpool->contains(entt) && !(cpool->index(entt) < pos) && (other->contains(entt) && ...); }, pools) + && std::apply([entt](auto *...cpool) { return (!cpool->contains(entt) && ...); }, filter)) { + swap_elements(len++, entt); + } + } + + void push_on_destroy(const entity_type entt) { + if(std::apply([entt, pos = len](auto *cpool, auto *...other) { return cpool->contains(entt) && !(cpool->index(entt) < pos) && (other->contains(entt) && ...); }, pools) + && std::apply([entt](auto *...cpool) { return (0u + ... + cpool->contains(entt)) == 1u; }, filter)) { + swap_elements(len++, entt); + } + } + + void remove_if(const entity_type entt) { + if(pools[0u]->contains(entt) && (pools[0u]->index(entt) < len)) { + swap_elements(--len, entt); + } + } + + void common_setup() { + // we cannot iterate backwards because we want to leave behind valid entities in case of owned types + for(auto first = pools[0u]->rbegin(), last = first + static_cast(pools[0u]->size()); first != last; ++first) { + push_on_construct(*first); + } + } + +public: + using common_type = Type; + using size_type = typename Type::size_type; + + template + group_handler(std::tuple ogpool, std::tuple epool) + : pools{std::apply([](auto &&...cpool) { return std::array{&cpool...}; }, ogpool)}, + filter{std::apply([](auto &&...cpool) { return std::array{&cpool...}; }, epool)} { + std::apply([this](auto &...cpool) { ((cpool.on_construct().template connect<&group_handler::push_on_construct>(*this), cpool.on_destroy().template connect<&group_handler::remove_if>(*this)), ...); }, ogpool); + std::apply([this](auto &...cpool) { ((cpool.on_construct().template connect<&group_handler::remove_if>(*this), cpool.on_destroy().template connect<&group_handler::push_on_destroy>(*this)), ...); }, epool); + common_setup(); + } + + [[nodiscard]] bool owned(const id_type hash) const noexcept override { + for(size_type pos{}; pos < Owned; ++pos) { + if(pools[pos]->info().hash() == hash) { + return true; + } + } + + return false; + } + + [[nodiscard]] size_type length() const noexcept { + return len; + } + + template + [[nodiscard]] common_type *storage() const noexcept { + if constexpr(Index < (Owned + Get)) { + return pools[Index]; + } else { + return filter[Index - (Owned + Get)]; + } + } + +private: + std::array pools; + std::array filter; + std::size_t len{}; +}; + +template +class group_handler final: public group_descriptor { + using entity_type = typename Type::entity_type; + + void push_on_construct(const entity_type entt) { + if(!elem.contains(entt) + && std::apply([entt](auto *...cpool) { return (cpool->contains(entt) && ...); }, pools) + && std::apply([entt](auto *...cpool) { return (!cpool->contains(entt) && ...); }, filter)) { + elem.push(entt); + } + } + + void push_on_destroy(const entity_type entt) { + if(!elem.contains(entt) + && std::apply([entt](auto *...cpool) { return (cpool->contains(entt) && ...); }, pools) + && std::apply([entt](auto *...cpool) { return (0u + ... + cpool->contains(entt)) == 1u; }, filter)) { + elem.push(entt); + } + } + + void remove_if(const entity_type entt) { + elem.remove(entt); + } + + void common_setup() { + for(const auto entity: *pools[0u]) { + push_on_construct(entity); + } + } + +public: + using common_type = Type; + + template + group_handler(const Allocator &allocator, std::tuple gpool, std::tuple epool) + : pools{std::apply([](auto &&...cpool) { return std::array{&cpool...}; }, gpool)}, + filter{std::apply([](auto &&...cpool) { return std::array{&cpool...}; }, epool)}, + elem{allocator} { + std::apply([this](auto &...cpool) { ((cpool.on_construct().template connect<&group_handler::push_on_construct>(*this), cpool.on_destroy().template connect<&group_handler::remove_if>(*this)), ...); }, gpool); + std::apply([this](auto &...cpool) { ((cpool.on_construct().template connect<&group_handler::remove_if>(*this), cpool.on_destroy().template connect<&group_handler::push_on_destroy>(*this)), ...); }, epool); + common_setup(); + } + + [[nodiscard]] common_type &handle() noexcept { + return elem; + } + + [[nodiscard]] const common_type &handle() const noexcept { + return elem; + } + + template + [[nodiscard]] common_type *storage() const noexcept { + if constexpr(Index < Get) { + return pools[Index]; + } else { + return filter[Index - Get]; + } + } + +private: + std::array pools; + std::array filter; + common_type elem; +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Group. + * + * Primary template isn't defined on purpose. All the specializations give a + * compile-time error, but for a few reasonable cases. + */ +template +class basic_group; + +/** + * @brief Non-owning group. + * + * A non-owning group returns all entities and only the entities that are at + * least in the given storage. Moreover, it's guaranteed that the entity list is + * tightly packed in memory for fast iterations. + * + * @b Important + * + * Iterators aren't invalidated if: + * + * * New elements are added to the storage. + * * The entity currently pointed is modified (for example, elements are added + * or removed from it). + * * The entity currently pointed is destroyed. + * + * In all other cases, modifying the pools iterated by the group in any way + * invalidates all the iterators. + * + * @tparam Get Types of storage _observed_ by the group. + * @tparam Exclude Types of storage used to filter the group. + */ +template +class basic_group, get_t, exclude_t> { + using base_type = std::common_type_t; + using underlying_type = typename base_type::entity_type; + + template + static constexpr std::size_t index_of = type_list_index_v, type_list>; + + template + [[nodiscard]] auto pools_for(std::index_sequence) const noexcept { + using return_type = std::tuple; + return descriptor ? return_type{static_cast(descriptor->template storage())...} : return_type{}; + } + +public: + /*! @brief Underlying entity identifier. */ + using entity_type = underlying_type; + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + /*! @brief Signed integer type. */ + using difference_type = std::ptrdiff_t; + /*! @brief Common type among all storage types. */ + using common_type = base_type; + /*! @brief Random access iterator type. */ + using iterator = typename common_type::iterator; + /*! @brief Reverse iterator type. */ + using reverse_iterator = typename common_type::reverse_iterator; + /*! @brief Iterable group type. */ + using iterable = iterable_adaptor, get_t>>; + /*! @brief Group handler type. */ + using handler = internal::group_handler; + + /** + * @brief Group opaque identifier. + * @return Group opaque identifier. + */ + static id_type group_id() noexcept { + return type_hash, get_t...>, exclude_t...>>>::value(); + } + + /*! @brief Default constructor to use to create empty, invalid groups. */ + basic_group() noexcept + : descriptor{} {} + + /** + * @brief Constructs a group from a set of storage classes. + * @param ref A reference to a group handler. + */ + basic_group(handler &ref) noexcept + : descriptor{&ref} {} + + /** + * @brief Returns the leading storage of a group. + * @return The leading storage of the group. + */ + [[nodiscard]] const common_type &handle() const noexcept { + return descriptor->handle(); + } + + /** + * @brief Returns the storage for a given element type, if any. + * @tparam Type Type of element of which to return the storage. + * @return The storage for the given element type. + */ + template + [[nodiscard]] auto *storage() const noexcept { + return storage>(); + } + + /** + * @brief Returns the storage for a given index, if any. + * @tparam Index Index of the storage to return. + * @return The storage for the given index. + */ + template + [[nodiscard]] auto *storage() const noexcept { + using type = type_list_element_t>; + return *this ? static_cast(descriptor->template storage()) : nullptr; + } + + /** + * @brief Returns the number of entities that are part of the group. + * @return Number of entities that are part of the group. + */ + [[nodiscard]] size_type size() const noexcept { + return *this ? handle().size() : size_type{}; + } + + /** + * @brief Returns the number of elements that a group has currently + * allocated space for. + * @return Capacity of the group. + */ + [[nodiscard]] size_type capacity() const noexcept { + return *this ? handle().capacity() : size_type{}; + } + + /*! @brief Requests the removal of unused capacity. */ + void shrink_to_fit() { + if(*this) { + descriptor->handle().shrink_to_fit(); + } + } + + /** + * @brief Checks whether a group is empty. + * @return True if the group is empty, false otherwise. + */ + [[nodiscard]] bool empty() const noexcept { + return !*this || handle().empty(); + } + + /** + * @brief Returns an iterator to the first entity of the group. + * + * If the group is empty, the returned iterator will be equal to `end()`. + * + * @return An iterator to the first entity of the group. + */ + [[nodiscard]] iterator begin() const noexcept { + return *this ? handle().begin() : iterator{}; + } + + /** + * @brief Returns an iterator that is past the last entity of the group. + * @return An iterator to the entity following the last entity of the + * group. + */ + [[nodiscard]] iterator end() const noexcept { + return *this ? handle().end() : iterator{}; + } + + /** + * @brief Returns an iterator to the first entity of the reversed group. + * + * If the group is empty, the returned iterator will be equal to `rend()`. + * + * @return An iterator to the first entity of the reversed group. + */ + [[nodiscard]] reverse_iterator rbegin() const noexcept { + return *this ? handle().rbegin() : reverse_iterator{}; + } + + /** + * @brief Returns an iterator that is past the last entity of the reversed + * group. + * @return An iterator to the entity following the last entity of the + * reversed group. + */ + [[nodiscard]] reverse_iterator rend() const noexcept { + return *this ? handle().rend() : reverse_iterator{}; + } + + /** + * @brief Returns the first entity of the group, if any. + * @return The first entity of the group if one exists, the null entity + * otherwise. + */ + [[nodiscard]] entity_type front() const noexcept { + const auto it = begin(); + return it != end() ? *it : null; + } + + /** + * @brief Returns the last entity of the group, if any. + * @return The last entity of the group if one exists, the null entity + * otherwise. + */ + [[nodiscard]] entity_type back() const noexcept { + const auto it = rbegin(); + return it != rend() ? *it : null; + } + + /** + * @brief Finds an entity. + * @param entt A valid identifier. + * @return An iterator to the given entity if it's found, past the end + * iterator otherwise. + */ + [[nodiscard]] iterator find(const entity_type entt) const noexcept { + return *this ? handle().find(entt) : iterator{}; + } + + /** + * @brief Returns the identifier that occupies the given position. + * @param pos Position of the element to return. + * @return The identifier that occupies the given position. + */ + [[nodiscard]] entity_type operator[](const size_type pos) const { + return begin()[static_cast(pos)]; + } + + /** + * @brief Checks if a group is properly initialized. + * @return True if the group is properly initialized, false otherwise. + */ + [[nodiscard]] explicit operator bool() const noexcept { + return descriptor != nullptr; + } + + /** + * @brief Checks if a group contains an entity. + * @param entt A valid identifier. + * @return True if the group contains the given entity, false otherwise. + */ + [[nodiscard]] bool contains(const entity_type entt) const noexcept { + return *this && handle().contains(entt); + } + + /** + * @brief Returns the elements assigned to the given entity. + * @tparam Type Type of the element to get. + * @tparam Other Other types of elements to get. + * @param entt A valid identifier. + * @return The elements assigned to the entity. + */ + template + [[nodiscard]] decltype(auto) get(const entity_type entt) const { + return get, index_of...>(entt); + } + + /** + * @brief Returns the elements assigned to the given entity. + * @tparam Index Indexes of the elements to get. + * @param entt A valid identifier. + * @return The elements assigned to the entity. + */ + template + [[nodiscard]] decltype(auto) get(const entity_type entt) const { + const auto cpools = pools_for(std::index_sequence_for{}); + + if constexpr(sizeof...(Index) == 0) { + return std::apply([entt](auto *...curr) { return std::tuple_cat(curr->get_as_tuple(entt)...); }, cpools); + } else if constexpr(sizeof...(Index) == 1) { + return (std::get(cpools)->get(entt), ...); + } else { + return std::tuple_cat(std::get(cpools)->get_as_tuple(entt)...); + } + } + + /** + * @brief Iterates entities and elements and applies the given function + * object to them. + * + * The function object is invoked for each entity. It is provided with the + * entity itself and a set of references to non-empty elements. The + * _constness_ of the elements is as requested.
+ * The signature of the function must be equivalent to one of the following + * forms: + * + * @code{.cpp} + * void(const entity_type, Type &...); + * void(Type &...); + * @endcode + * + * @note + * Empty types aren't explicitly instantiated and therefore they are never + * returned during iterations. + * + * @tparam Func Type of the function object to invoke. + * @param func A valid function object. + */ + template + void each(Func func) const { + for(const auto entt: *this) { + if constexpr(is_applicable_v{}, std::declval().get({})))>) { + std::apply(func, std::tuple_cat(std::make_tuple(entt), get(entt))); + } else { + std::apply(func, get(entt)); + } + } + } + + /** + * @brief Returns an iterable object to use to _visit_ a group. + * + * The iterable object returns tuples that contain the current entity and a + * set of references to its non-empty elements. The _constness_ of the + * elements is as requested. + * + * @note + * Empty types aren't explicitly instantiated and therefore they are never + * returned during iterations. + * + * @return An iterable object to use to _visit_ the group. + */ + [[nodiscard]] iterable each() const noexcept { + const auto cpools = pools_for(std::index_sequence_for{}); + return iterable{{begin(), cpools}, {end(), cpools}}; + } + + /** + * @brief Sort a group according to the given comparison function. + * + * The comparison function object must return `true` if the first element + * is _less_ than the second one, `false` otherwise. The signature of the + * comparison function should be equivalent to one of the following: + * + * @code{.cpp} + * bool(std::tuple, std::tuple); + * bool(const Type &..., const Type &...); + * bool(const Entity, const Entity); + * @endcode + * + * Where `Type` are such that they are iterated by the group.
+ * Moreover, the comparison function object shall induce a + * _strict weak ordering_ on the values. + * + * The sort function object must offer a member function template + * `operator()` that accepts three arguments: + * + * * An iterator to the first element of the range to sort. + * * An iterator past the last element of the range to sort. + * * A comparison function to use to compare the elements. + * + * @tparam Type Optional type of element to compare. + * @tparam Other Other optional types of elements to compare. + * @tparam Compare Type of comparison function object. + * @tparam Sort Type of sort function object. + * @tparam Args Types of arguments to forward to the sort function object. + * @param compare A valid comparison function object. + * @param algo A valid sort function object. + * @param args Arguments to forward to the sort function object, if any. + */ + template + void sort(Compare compare, Sort algo = Sort{}, Args &&...args) { + sort, index_of...>(std::move(compare), std::move(algo), std::forward(args)...); + } + + /** + * @brief Sort a group according to the given comparison function. + * + * @sa sort + * + * @tparam Index Optional indexes of elements to compare. + * @tparam Compare Type of comparison function object. + * @tparam Sort Type of sort function object. + * @tparam Args Types of arguments to forward to the sort function object. + * @param compare A valid comparison function object. + * @param algo A valid sort function object. + * @param args Arguments to forward to the sort function object, if any. + */ + template + void sort(Compare compare, Sort algo = Sort{}, Args &&...args) { + if(*this) { + if constexpr(sizeof...(Index) == 0) { + static_assert(std::is_invocable_v, "Invalid comparison function"); + descriptor->handle().sort(std::move(compare), std::move(algo), std::forward(args)...); + } else { + auto comp = [&compare, cpools = pools_for(std::index_sequence_for{})](const entity_type lhs, const entity_type rhs) { + if constexpr(sizeof...(Index) == 1) { + return compare((std::get(cpools)->get(lhs), ...), (std::get(cpools)->get(rhs), ...)); + } else { + return compare(std::forward_as_tuple(std::get(cpools)->get(lhs)...), std::forward_as_tuple(std::get(cpools)->get(rhs)...)); + } + }; + + descriptor->handle().sort(std::move(comp), std::move(algo), std::forward(args)...); + } + } + } + + /** + * @brief Sort entities according to their order in a range. + * + * The shared pool of entities and thus its order is affected by the changes + * to each and every pool that it tracks. + * + * @tparam It Type of input iterator. + * @param first An iterator to the first element of the range of entities. + * @param last An iterator past the last element of the range of entities. + */ + template + void sort_as(It first, It last) const { + if(*this) { + descriptor->handle().sort_as(first, last); + } + } + +private: + handler *descriptor; +}; + +/** + * @brief Owning group. + * + * Owning groups returns all entities and only the entities that are at + * least in the given storage. Moreover: + * + * * It's guaranteed that the entity list is tightly packed in memory for fast + * iterations. + * * It's guaranteed that all elements in the owned storage are tightly packed + * in memory for even faster iterations and to allow direct access. + * * They stay true to the order of the owned storage and all instances have the + * same order in memory. + * + * The more types of storage are owned, the faster it is to iterate a group. + * + * @b Important + * + * Iterators aren't invalidated if: + * + * * New elements are added to the storage. + * * The entity currently pointed is modified (for example, elements are added + * or removed from it). + * * The entity currently pointed is destroyed. + * + * In all other cases, modifying the pools iterated by the group in any way + * invalidates all the iterators. + * + * @tparam Owned Types of storage _owned_ by the group. + * @tparam Get Types of storage _observed_ by the group. + * @tparam Exclude Types of storage used to filter the group. + */ +template +class basic_group, get_t, exclude_t> { + static_assert(((Owned::storage_policy != deletion_policy::in_place) && ...), "Groups do not support in-place delete"); + + using base_type = std::common_type_t; + using underlying_type = typename base_type::entity_type; + + template + static constexpr std::size_t index_of = type_list_index_v, type_list>; + + template + [[nodiscard]] auto pools_for(std::index_sequence, std::index_sequence) const noexcept { + using return_type = std::tuple; + return descriptor ? return_type{static_cast(descriptor->template storage())..., static_cast(descriptor->template storage())...} : return_type{}; + } + +public: + /*! @brief Underlying entity identifier. */ + using entity_type = underlying_type; + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + /*! @brief Signed integer type. */ + using difference_type = std::ptrdiff_t; + /*! @brief Common type among all storage types. */ + using common_type = base_type; + /*! @brief Random access iterator type. */ + using iterator = typename common_type::iterator; + /*! @brief Reverse iterator type. */ + using reverse_iterator = typename common_type::reverse_iterator; + /*! @brief Iterable group type. */ + using iterable = iterable_adaptor, get_t>>; + /*! @brief Group handler type. */ + using handler = internal::group_handler; + + /** + * @brief Group opaque identifier. + * @return Group opaque identifier. + */ + static id_type group_id() noexcept { + return type_hash...>, get_t...>, exclude_t...>>>::value(); + } + + /*! @brief Default constructor to use to create empty, invalid groups. */ + basic_group() noexcept + : descriptor{} {} + + /** + * @brief Constructs a group from a set of storage classes. + * @param ref A reference to a group handler. + */ + basic_group(handler &ref) noexcept + : descriptor{&ref} {} + + /** + * @brief Returns the leading storage of a group. + * @return The leading storage of the group. + */ + [[nodiscard]] const common_type &handle() const noexcept { + return *storage<0>(); + } + + /** + * @brief Returns the storage for a given element type, if any. + * @tparam Type Type of element of which to return the storage. + * @return The storage for the given element type. + */ + template + [[nodiscard]] auto *storage() const noexcept { + return storage>(); + } + + /** + * @brief Returns the storage for a given index, if any. + * @tparam Index Index of the storage to return. + * @return The storage for the given index. + */ + template + [[nodiscard]] auto *storage() const noexcept { + using type = type_list_element_t>; + return *this ? static_cast(descriptor->template storage()) : nullptr; + } + + /** + * @brief Returns the number of entities that that are part of the group. + * @return Number of entities that that are part of the group. + */ + [[nodiscard]] size_type size() const noexcept { + return *this ? descriptor->length() : size_type{}; + } + + /** + * @brief Checks whether a group is empty. + * @return True if the group is empty, false otherwise. + */ + [[nodiscard]] bool empty() const noexcept { + return !*this || !descriptor->length(); + } + + /** + * @brief Returns an iterator to the first entity of the group. + * + * If the group is empty, the returned iterator will be equal to `end()`. + * + * @return An iterator to the first entity of the group. + */ + [[nodiscard]] iterator begin() const noexcept { + return *this ? (handle().end() - static_cast(descriptor->length())) : iterator{}; + } + + /** + * @brief Returns an iterator that is past the last entity of the group. + * @return An iterator to the entity following the last entity of the + * group. + */ + [[nodiscard]] iterator end() const noexcept { + return *this ? handle().end() : iterator{}; + } + + /** + * @brief Returns an iterator to the first entity of the reversed group. + * + * If the group is empty, the returned iterator will be equal to `rend()`. + * + * @return An iterator to the first entity of the reversed group. + */ + [[nodiscard]] reverse_iterator rbegin() const noexcept { + return *this ? handle().rbegin() : reverse_iterator{}; + } + + /** + * @brief Returns an iterator that is past the last entity of the reversed + * group. + * @return An iterator to the entity following the last entity of the + * reversed group. + */ + [[nodiscard]] reverse_iterator rend() const noexcept { + return *this ? (handle().rbegin() + static_cast(descriptor->length())) : reverse_iterator{}; + } + + /** + * @brief Returns the first entity of the group, if any. + * @return The first entity of the group if one exists, the null entity + * otherwise. + */ + [[nodiscard]] entity_type front() const noexcept { + const auto it = begin(); + return it != end() ? *it : null; + } + + /** + * @brief Returns the last entity of the group, if any. + * @return The last entity of the group if one exists, the null entity + * otherwise. + */ + [[nodiscard]] entity_type back() const noexcept { + const auto it = rbegin(); + return it != rend() ? *it : null; + } + + /** + * @brief Finds an entity. + * @param entt A valid identifier. + * @return An iterator to the given entity if it's found, past the end + * iterator otherwise. + */ + [[nodiscard]] iterator find(const entity_type entt) const noexcept { + const auto it = *this ? handle().find(entt) : iterator{}; + return it >= begin() ? it : iterator{}; + } + + /** + * @brief Returns the identifier that occupies the given position. + * @param pos Position of the element to return. + * @return The identifier that occupies the given position. + */ + [[nodiscard]] entity_type operator[](const size_type pos) const { + return begin()[static_cast(pos)]; + } + + /** + * @brief Checks if a group is properly initialized. + * @return True if the group is properly initialized, false otherwise. + */ + [[nodiscard]] explicit operator bool() const noexcept { + return descriptor != nullptr; + } + + /** + * @brief Checks if a group contains an entity. + * @param entt A valid identifier. + * @return True if the group contains the given entity, false otherwise. + */ + [[nodiscard]] bool contains(const entity_type entt) const noexcept { + return *this && handle().contains(entt) && (handle().index(entt) < (descriptor->length())); + } + + /** + * @brief Returns the elements assigned to the given entity. + * @tparam Type Type of the element to get. + * @tparam Other Other types of elements to get. + * @param entt A valid identifier. + * @return The elements assigned to the entity. + */ + template + [[nodiscard]] decltype(auto) get(const entity_type entt) const { + return get, index_of...>(entt); + } + + /** + * @brief Returns the elements assigned to the given entity. + * @tparam Index Indexes of the elements to get. + * @param entt A valid identifier. + * @return The elements assigned to the entity. + */ + template + [[nodiscard]] decltype(auto) get(const entity_type entt) const { + const auto cpools = pools_for(std::index_sequence_for{}, std::index_sequence_for{}); + + if constexpr(sizeof...(Index) == 0) { + return std::apply([entt](auto *...curr) { return std::tuple_cat(curr->get_as_tuple(entt)...); }, cpools); + } else if constexpr(sizeof...(Index) == 1) { + return (std::get(cpools)->get(entt), ...); + } else { + return std::tuple_cat(std::get(cpools)->get_as_tuple(entt)...); + } + } + + /** + * @brief Iterates entities and elements and applies the given function + * object to them. + * + * The function object is invoked for each entity. It is provided with the + * entity itself and a set of references to non-empty elements. The + * _constness_ of the elements is as requested.
+ * The signature of the function must be equivalent to one of the following + * forms: + * + * @code{.cpp} + * void(const entity_type, Type &...); + * void(Type &...); + * @endcode + * + * @note + * Empty types aren't explicitly instantiated and therefore they are never + * returned during iterations. + * + * @tparam Func Type of the function object to invoke. + * @param func A valid function object. + */ + template + void each(Func func) const { + for(auto args: each()) { + if constexpr(is_applicable_v{}, std::declval().get({})))>) { + std::apply(func, args); + } else { + std::apply([&func](auto, auto &&...less) { func(std::forward(less)...); }, args); + } + } + } + + /** + * @brief Returns an iterable object to use to _visit_ a group. + * + * The iterable object returns tuples that contain the current entity and a + * set of references to its non-empty elements. The _constness_ of the + * elements is as requested. + * + * @note + * Empty types aren't explicitly instantiated and therefore they are never + * returned during iterations. + * + * @return An iterable object to use to _visit_ the group. + */ + [[nodiscard]] iterable each() const noexcept { + const auto cpools = pools_for(std::index_sequence_for{}, std::index_sequence_for{}); + return iterable{{begin(), cpools}, {end(), cpools}}; + } + + /** + * @brief Sort a group according to the given comparison function. + * + * The comparison function object must return `true` if the first element + * is _less_ than the second one, `false` otherwise. The signature of the + * comparison function should be equivalent to one of the following: + * + * @code{.cpp} + * bool(std::tuple, std::tuple); + * bool(const Type &, const Type &); + * bool(const Entity, const Entity); + * @endcode + * + * Where `Type` are either owned types or not but still such that they are + * iterated by the group.
+ * Moreover, the comparison function object shall induce a + * _strict weak ordering_ on the values. + * + * The sort function object must offer a member function template + * `operator()` that accepts three arguments: + * + * * An iterator to the first element of the range to sort. + * * An iterator past the last element of the range to sort. + * * A comparison function to use to compare the elements. + * + * @tparam Type Optional type of element to compare. + * @tparam Other Other optional types of elements to compare. + * @tparam Compare Type of comparison function object. + * @tparam Sort Type of sort function object. + * @tparam Args Types of arguments to forward to the sort function object. + * @param compare A valid comparison function object. + * @param algo A valid sort function object. + * @param args Arguments to forward to the sort function object, if any. + */ + template + void sort(Compare compare, Sort algo = Sort{}, Args &&...args) const { + sort, index_of...>(std::move(compare), std::move(algo), std::forward(args)...); + } + + /** + * @brief Sort a group according to the given comparison function. + * + * @sa sort + * + * @tparam Index Optional indexes of elements to compare. + * @tparam Compare Type of comparison function object. + * @tparam Sort Type of sort function object. + * @tparam Args Types of arguments to forward to the sort function object. + * @param compare A valid comparison function object. + * @param algo A valid sort function object. + * @param args Arguments to forward to the sort function object, if any. + */ + template + void sort(Compare compare, Sort algo = Sort{}, Args &&...args) const { + const auto cpools = pools_for(std::index_sequence_for{}, std::index_sequence_for{}); + + if constexpr(sizeof...(Index) == 0) { + static_assert(std::is_invocable_v, "Invalid comparison function"); + storage<0>()->sort_n(descriptor->length(), std::move(compare), std::move(algo), std::forward(args)...); + } else { + auto comp = [&compare, &cpools](const entity_type lhs, const entity_type rhs) { + if constexpr(sizeof...(Index) == 1) { + return compare((std::get(cpools)->get(lhs), ...), (std::get(cpools)->get(rhs), ...)); + } else { + return compare(std::forward_as_tuple(std::get(cpools)->get(lhs)...), std::forward_as_tuple(std::get(cpools)->get(rhs)...)); + } + }; + + storage<0>()->sort_n(descriptor->length(), std::move(comp), std::move(algo), std::forward(args)...); + } + + auto cb = [this](auto *head, auto *...other) { + for(auto next = descriptor->length(); next; --next) { + const auto pos = next - 1; + [[maybe_unused]] const auto entt = head->data()[pos]; + (other->swap_elements(other->data()[pos], entt), ...); + } + }; + + std::apply(cb, cpools); + } + +private: + handler *descriptor; +}; + +} // namespace entt + +#endif + +// #include "storage.hpp" +#ifndef ENTT_ENTITY_STORAGE_HPP +#define ENTT_ENTITY_STORAGE_HPP + +#include +#include +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "../core/bit.hpp" + +// #include "../core/iterator.hpp" + +// #include "../core/memory.hpp" +#ifndef ENTT_CORE_MEMORY_HPP +#define ENTT_CORE_MEMORY_HPP + +#include +#include +#include +#include +#include +// #include "../config/config.h" + + +namespace entt { + +/** + * @brief Unwraps fancy pointers, does nothing otherwise (waiting for C++20). + * @tparam Type Pointer type. + * @param ptr Fancy or raw pointer. + * @return A raw pointer that represents the address of the original pointer. + */ +template +[[nodiscard]] constexpr auto to_address(Type &&ptr) noexcept { + if constexpr(std::is_pointer_v>) { + return ptr; + } else { + return to_address(std::forward(ptr).operator->()); + } +} + +/** + * @brief Utility function to design allocation-aware containers. + * @tparam Allocator Type of allocator. + * @param lhs A valid allocator. + * @param rhs Another valid allocator. + */ +template +constexpr void propagate_on_container_copy_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept { + if constexpr(std::allocator_traits::propagate_on_container_copy_assignment::value) { + lhs = rhs; + } +} + +/** + * @brief Utility function to design allocation-aware containers. + * @tparam Allocator Type of allocator. + * @param lhs A valid allocator. + * @param rhs Another valid allocator. + */ +template +constexpr void propagate_on_container_move_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept { + if constexpr(std::allocator_traits::propagate_on_container_move_assignment::value) { + lhs = std::move(rhs); + } +} + +/** + * @brief Utility function to design allocation-aware containers. + * @tparam Allocator Type of allocator. + * @param lhs A valid allocator. + * @param rhs Another valid allocator. + */ +template +constexpr void propagate_on_container_swap([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept { + if constexpr(std::allocator_traits::propagate_on_container_swap::value) { + using std::swap; + swap(lhs, rhs); + } else { + ENTT_ASSERT_CONSTEXPR(lhs == rhs, "Cannot swap the containers"); + } +} + +/** + * @brief Deleter for allocator-aware unique pointers (waiting for C++20). + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +struct allocation_deleter: private Allocator { + /*! @brief Allocator type. */ + using allocator_type = Allocator; + /*! @brief Pointer type. */ + using pointer = typename std::allocator_traits::pointer; + + /** + * @brief Inherited constructors. + * @param alloc The allocator to use. + */ + constexpr allocation_deleter(const allocator_type &alloc) noexcept(std::is_nothrow_copy_constructible_v) + : Allocator{alloc} {} + + /** + * @brief Destroys the pointed object and deallocates its memory. + * @param ptr A valid pointer to an object of the given type. + */ + constexpr void operator()(pointer ptr) noexcept(std::is_nothrow_destructible_v) { + using alloc_traits = std::allocator_traits; + alloc_traits::destroy(*this, to_address(ptr)); + alloc_traits::deallocate(*this, ptr, 1u); + } +}; + +/** + * @brief Allows `std::unique_ptr` to use allocators (waiting for C++20). + * @tparam Type Type of object to allocate for and to construct. + * @tparam Allocator Type of allocator used to manage memory and elements. + * @tparam Args Types of arguments to use to construct the object. + * @param allocator The allocator to use. + * @param args Parameters to use to construct the object. + * @return A properly initialized unique pointer with a custom deleter. + */ +template +ENTT_CONSTEXPR auto allocate_unique(Allocator &allocator, Args &&...args) { + static_assert(!std::is_array_v, "Array types are not supported"); + + using alloc_traits = typename std::allocator_traits::template rebind_traits; + using allocator_type = typename alloc_traits::allocator_type; + + allocator_type alloc{allocator}; + auto ptr = alloc_traits::allocate(alloc, 1u); + + ENTT_TRY { + alloc_traits::construct(alloc, to_address(ptr), std::forward(args)...); + } + ENTT_CATCH { + alloc_traits::deallocate(alloc, ptr, 1u); + ENTT_THROW; + } + + return std::unique_ptr>{ptr, alloc}; +} + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct uses_allocator_construction { + template + static constexpr auto args([[maybe_unused]] const Allocator &allocator, Params &&...params) noexcept { + if constexpr(!std::uses_allocator_v && std::is_constructible_v) { + return std::forward_as_tuple(std::forward(params)...); + } else { + static_assert(std::uses_allocator_v, "Ill-formed request"); + + if constexpr(std::is_constructible_v) { + return std::tuple{std::allocator_arg, allocator, std::forward(params)...}; + } else { + static_assert(std::is_constructible_v, "Ill-formed request"); + return std::forward_as_tuple(std::forward(params)..., allocator); + } + } + } +}; + +template +struct uses_allocator_construction> { + using type = std::pair; + + template + static constexpr auto args(const Allocator &allocator, std::piecewise_construct_t, First &&first, Second &&second) noexcept { + return std::make_tuple( + std::piecewise_construct, + std::apply([&allocator](auto &&...curr) { return uses_allocator_construction::args(allocator, std::forward(curr)...); }, std::forward(first)), + std::apply([&allocator](auto &&...curr) { return uses_allocator_construction::args(allocator, std::forward(curr)...); }, std::forward(second))); + } + + template + static constexpr auto args(const Allocator &allocator) noexcept { + return uses_allocator_construction::args(allocator, std::piecewise_construct, std::tuple<>{}, std::tuple<>{}); + } + + template + static constexpr auto args(const Allocator &allocator, First &&first, Second &&second) noexcept { + return uses_allocator_construction::args(allocator, std::piecewise_construct, std::forward_as_tuple(std::forward(first)), std::forward_as_tuple(std::forward(second))); + } + + template + static constexpr auto args(const Allocator &allocator, const std::pair &value) noexcept { + return uses_allocator_construction::args(allocator, std::piecewise_construct, std::forward_as_tuple(value.first), std::forward_as_tuple(value.second)); + } + + template + static constexpr auto args(const Allocator &allocator, std::pair &&value) noexcept { + return uses_allocator_construction::args(allocator, std::piecewise_construct, std::forward_as_tuple(std::move(value.first)), std::forward_as_tuple(std::move(value.second))); + } +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Uses-allocator construction utility (waiting for C++20). + * + * Primarily intended for internal use. Prepares the argument list needed to + * create an object of a given type by means of uses-allocator construction. + * + * @tparam Type Type to return arguments for. + * @tparam Allocator Type of allocator used to manage memory and elements. + * @tparam Args Types of arguments to use to construct the object. + * @param allocator The allocator to use. + * @param args Parameters to use to construct the object. + * @return The arguments needed to create an object of the given type. + */ +template +constexpr auto uses_allocator_construction_args(const Allocator &allocator, Args &&...args) noexcept { + return internal::uses_allocator_construction::args(allocator, std::forward(args)...); +} + +/** + * @brief Uses-allocator construction utility (waiting for C++20). + * + * Primarily intended for internal use. Creates an object of a given type by + * means of uses-allocator construction. + * + * @tparam Type Type of object to create. + * @tparam Allocator Type of allocator used to manage memory and elements. + * @tparam Args Types of arguments to use to construct the object. + * @param allocator The allocator to use. + * @param args Parameters to use to construct the object. + * @return A newly created object of the given type. + */ +template +constexpr Type make_obj_using_allocator(const Allocator &allocator, Args &&...args) { + return std::make_from_tuple(internal::uses_allocator_construction::args(allocator, std::forward(args)...)); +} + +/** + * @brief Uses-allocator construction utility (waiting for C++20). + * + * Primarily intended for internal use. Creates an object of a given type by + * means of uses-allocator construction at an uninitialized memory location. + * + * @tparam Type Type of object to create. + * @tparam Allocator Type of allocator used to manage memory and elements. + * @tparam Args Types of arguments to use to construct the object. + * @param value Memory location in which to place the object. + * @param allocator The allocator to use. + * @param args Parameters to use to construct the object. + * @return A pointer to the newly created object of the given type. + */ +template +constexpr Type *uninitialized_construct_using_allocator(Type *value, const Allocator &allocator, Args &&...args) { + return std::apply([value](auto &&...curr) { return ::new(value) Type(std::forward(curr)...); }, internal::uses_allocator_construction::args(allocator, std::forward(args)...)); +} + +} // namespace entt + +#endif + +// #include "../core/type_info.hpp" + +// #include "component.hpp" + +// #include "entity.hpp" + +// #include "fwd.hpp" + +// #include "sparse_set.hpp" +#ifndef ENTT_ENTITY_SPARSE_SET_HPP +#define ENTT_ENTITY_SPARSE_SET_HPP + +#include +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "../core/algorithm.hpp" + +// #include "../core/any.hpp" +#ifndef ENTT_CORE_ANY_HPP +#define ENTT_CORE_ANY_HPP + +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "fwd.hpp" + +// #include "type_info.hpp" +#ifndef ENTT_CORE_TYPE_INFO_HPP +#define ENTT_CORE_TYPE_INFO_HPP + +#include +#include +#include +// #include "../config/config.h" + +// #include "fwd.hpp" + +// #include "hashed_string.hpp" + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +struct ENTT_API type_index final { + [[nodiscard]] static id_type next() noexcept { + static ENTT_MAYBE_ATOMIC(id_type) value{}; + return value++; + } +}; + +template +[[nodiscard]] constexpr const char *pretty_function() noexcept { +#if defined ENTT_PRETTY_FUNCTION + return static_cast(ENTT_PRETTY_FUNCTION); +#else + return ""; +#endif +} + +template +[[nodiscard]] constexpr auto stripped_type_name() noexcept { +#if defined ENTT_PRETTY_FUNCTION + const std::string_view full_name{pretty_function()}; + auto first = full_name.find_first_not_of(' ', full_name.find_first_of(ENTT_PRETTY_FUNCTION_PREFIX) + 1); + auto value = full_name.substr(first, full_name.find_last_of(ENTT_PRETTY_FUNCTION_SUFFIX) - first); + return value; +#else + return std::string_view{}; +#endif +} + +template().find_first_of('.')> +[[nodiscard]] constexpr std::string_view type_name(int) noexcept { + constexpr auto value = stripped_type_name(); + return value; +} + +template +[[nodiscard]] std::string_view type_name(char) noexcept { + static const auto value = stripped_type_name(); + return value; +} + +template().find_first_of('.')> +[[nodiscard]] constexpr id_type type_hash(int) noexcept { + constexpr auto stripped = stripped_type_name(); + constexpr auto value = hashed_string::value(stripped.data(), stripped.size()); + return value; +} + +template +[[nodiscard]] id_type type_hash(char) noexcept { + static const auto value = [](const auto stripped) { + return hashed_string::value(stripped.data(), stripped.size()); + }(stripped_type_name()); + return value; +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Type sequential identifier. + * @tparam Type Type for which to generate a sequential identifier. + */ +template +struct ENTT_API type_index final { + /** + * @brief Returns the sequential identifier of a given type. + * @return The sequential identifier of a given type. + */ + [[nodiscard]] static id_type value() noexcept { + static const id_type value = internal::type_index::next(); + return value; + } + + /*! @copydoc value */ + [[nodiscard]] constexpr operator id_type() const noexcept { + return value(); + } +}; + +/** + * @brief Type hash. + * @tparam Type Type for which to generate a hash value. + */ +template +struct type_hash final { + /** + * @brief Returns the numeric representation of a given type. + * @return The numeric representation of the given type. + */ +#if defined ENTT_PRETTY_FUNCTION + [[nodiscard]] static constexpr id_type value() noexcept { + return internal::type_hash(0); +#else + [[nodiscard]] static constexpr id_type value() noexcept { + return type_index::value(); +#endif + } + + /*! @copydoc value */ + [[nodiscard]] constexpr operator id_type() const noexcept { + return value(); + } +}; + +/** + * @brief Type name. + * @tparam Type Type for which to generate a name. + */ +template +struct type_name final { + /** + * @brief Returns the name of a given type. + * @return The name of the given type. + */ + [[nodiscard]] static constexpr std::string_view value() noexcept { + return internal::type_name(0); + } + + /*! @copydoc value */ + [[nodiscard]] constexpr operator std::string_view() const noexcept { + return value(); + } +}; + +/*! @brief Implementation specific information about a type. */ +struct type_info final { + /** + * @brief Constructs a type info object for a given type. + * @tparam Type Type for which to construct a type info object. + */ + template + // NOLINTBEGIN(modernize-use-transparent-functors) + constexpr type_info(std::in_place_type_t) noexcept + : seq{type_index>>::value()}, + identifier{type_hash>>::value()}, + alias{type_name>>::value()} {} + // NOLINTEND(modernize-use-transparent-functors) + + /** + * @brief Type index. + * @return Type index. + */ + [[nodiscard]] constexpr id_type index() const noexcept { + return seq; + } + + /** + * @brief Type hash. + * @return Type hash. + */ + [[nodiscard]] constexpr id_type hash() const noexcept { + return identifier; + } + + /** + * @brief Type name. + * @return Type name. + */ + [[nodiscard]] constexpr std::string_view name() const noexcept { + return alias; + } + +private: + id_type seq; + id_type identifier; + std::string_view alias; +}; + +/** + * @brief Compares the contents of two type info objects. + * @param lhs A type info object. + * @param rhs A type info object. + * @return True if the two type info objects are identical, false otherwise. + */ +[[nodiscard]] constexpr bool operator==(const type_info &lhs, const type_info &rhs) noexcept { + return lhs.hash() == rhs.hash(); +} + +/** + * @brief Compares the contents of two type info objects. + * @param lhs A type info object. + * @param rhs A type info object. + * @return True if the two type info objects differ, false otherwise. + */ +[[nodiscard]] constexpr bool operator!=(const type_info &lhs, const type_info &rhs) noexcept { + return !(lhs == rhs); +} + +/** + * @brief Compares two type info objects. + * @param lhs A valid type info object. + * @param rhs A valid type info object. + * @return True if the first element is less than the second, false otherwise. + */ +[[nodiscard]] constexpr bool operator<(const type_info &lhs, const type_info &rhs) noexcept { + return lhs.index() < rhs.index(); +} + +/** + * @brief Compares two type info objects. + * @param lhs A valid type info object. + * @param rhs A valid type info object. + * @return True if the first element is less than or equal to the second, false + * otherwise. + */ +[[nodiscard]] constexpr bool operator<=(const type_info &lhs, const type_info &rhs) noexcept { + return !(rhs < lhs); +} + +/** + * @brief Compares two type info objects. + * @param lhs A valid type info object. + * @param rhs A valid type info object. + * @return True if the first element is greater than the second, false + * otherwise. + */ +[[nodiscard]] constexpr bool operator>(const type_info &lhs, const type_info &rhs) noexcept { + return rhs < lhs; +} + +/** + * @brief Compares two type info objects. + * @param lhs A valid type info object. + * @param rhs A valid type info object. + * @return True if the first element is greater than or equal to the second, + * false otherwise. + */ +[[nodiscard]] constexpr bool operator>=(const type_info &lhs, const type_info &rhs) noexcept { + return !(lhs < rhs); +} + +/** + * @brief Returns the type info object associated to a given type. + * + * The returned element refers to an object with static storage duration.
+ * The type doesn't need to be a complete type. If the type is a reference, the + * result refers to the referenced type. In all cases, top-level cv-qualifiers + * are ignored. + * + * @tparam Type Type for which to generate a type info object. + * @return A reference to a properly initialized type info object. + */ +template +[[nodiscard]] const type_info &type_id() noexcept { + if constexpr(std::is_same_v>>) { + static const type_info instance{std::in_place_type}; + return instance; + } else { + return type_id>>(); + } +} + +/*! @copydoc type_id */ +template +// NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward) +[[nodiscard]] const type_info &type_id(Type &&) noexcept { + return type_id>>(); +} + +} // namespace entt + +#endif + +// #include "type_traits.hpp" +#ifndef ENTT_CORE_TYPE_TRAITS_HPP +#define ENTT_CORE_TYPE_TRAITS_HPP + +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "fwd.hpp" + + +namespace entt { + +/** + * @brief Utility class to disambiguate overloaded functions. + * @tparam N Number of choices available. + */ +template +struct choice_t + // unfortunately, doxygen cannot parse such a construct + : /*! @cond TURN_OFF_DOXYGEN */ choice_t /*! @endcond */ +{}; + +/*! @copybrief choice_t */ +template<> +struct choice_t<0> {}; + +/** + * @brief Variable template for the choice trick. + * @tparam N Number of choices available. + */ +template +inline constexpr choice_t choice{}; + +/** + * @brief Identity type trait. + * + * Useful to establish non-deduced contexts in template argument deduction + * (waiting for C++20) or to provide types through function arguments. + * + * @tparam Type A type. + */ +template +struct type_identity { + /*! @brief Identity type. */ + using type = Type; +}; + +/** + * @brief Helper type. + * @tparam Type A type. + */ +template +using type_identity_t = typename type_identity::type; + +/** + * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains. + * @tparam Type The type of which to return the size. + */ +template +struct size_of: std::integral_constant {}; + +/*! @copydoc size_of */ +template +struct size_of> + // NOLINTNEXTLINE(bugprone-sizeof-expression) + : std::integral_constant {}; + +/** + * @brief Helper variable template. + * @tparam Type The type of which to return the size. + */ +template +inline constexpr std::size_t size_of_v = size_of::value; + +/** + * @brief Using declaration to be used to _repeat_ the same type a number of + * times equal to the size of a given parameter pack. + * @tparam Type A type to repeat. + */ +template +using unpack_as_type = Type; + +/** + * @brief Helper variable template to be used to _repeat_ the same value a + * number of times equal to the size of a given parameter pack. + * @tparam Value A value to repeat. + */ +template +inline constexpr auto unpack_as_value = Value; + +/** + * @brief Wraps a static constant. + * @tparam Value A static constant. + */ +template +using integral_constant = std::integral_constant; + +/** + * @brief Alias template to facilitate the creation of named values. + * @tparam Value A constant value at least convertible to `id_type`. + */ +template +using tag = integral_constant; + +/** + * @brief A class to use to push around lists of types, nothing more. + * @tparam Type Types provided by the type list. + */ +template +struct type_list { + /*! @brief Type list type. */ + using type = type_list; + /*! @brief Compile-time number of elements in the type list. */ + static constexpr auto size = sizeof...(Type); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_element; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Index Index of the type to return. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element> + : type_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element<0u, type_list> { + /*! @brief Searched type. */ + using type = First; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Type list to search into. + */ +template +using type_list_element_t = typename type_list_element::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_index; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 1u + type_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + static_assert(type_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +inline constexpr std::size_t type_list_index_v = type_list_index::value; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @return A type list composed by the types of both the type lists. + */ +template +constexpr type_list operator+(type_list, type_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_cat; + +/*! @brief Concatenates multiple type lists. */ +template<> +struct type_list_cat<> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list<>; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @tparam List Other type lists, if any. + */ +template +struct type_list_cat, type_list, List...> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = typename type_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the type list. + */ +template +struct type_list_cat> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list; +}; + +/** + * @brief Helper type. + * @tparam List Type lists to concatenate. + */ +template +using type_list_cat_t = typename type_list_cat::type; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct type_list_unique; + +template +struct type_list_unique, Type...> + : std::conditional_t<(std::is_same_v || ...), type_list_unique, Type...>, type_list_unique, Type..., First>> {}; + +template +struct type_list_unique, Type...> { + using type = type_list; +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Removes duplicates types from a type list. + * @tparam List Type list. + */ +template +struct type_list_unique { + /*! @brief A type list without duplicate types. */ + using type = typename internal::type_list_unique::type; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + */ +template +using type_list_unique_t = typename type_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a type list contains a + * given type, false otherwise. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +struct type_list_contains; + +/** + * @copybrief type_list_contains + * @tparam Type Types provided by the type list. + * @tparam Other Type to look for. + */ +template +struct type_list_contains, Other> + : std::bool_constant<(std::is_same_v || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +inline constexpr bool type_list_contains_v = type_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_diff; + +/** + * @brief Computes the difference between two type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + */ +template +struct type_list_diff, type_list> { + /*! @brief A type list that is the difference between the two type lists. */ + using type = type_list_cat_t, Type>, type_list<>, type_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Type lists between which to compute the difference. + */ +template +using type_list_diff_t = typename type_list_diff::type; + +/*! @brief Primary template isn't defined on purpose. */ +template class> +struct type_list_transform; + +/** + * @brief Applies a given _function_ to a type list and generate a new list. + * @tparam Type Types provided by the type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +struct type_list_transform, Op> { + /*! @brief Resulting type list after applying the transform function. */ + // NOLINTNEXTLINE(modernize-type-traits) + using type = type_list::type...>; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +using type_list_transform_t = typename type_list_transform::type; + +/** + * @brief A class to use to push around lists of constant values, nothing more. + * @tparam Value Values provided by the value list. + */ +template +struct value_list { + /*! @brief Value list type. */ + using type = value_list; + /*! @brief Compile-time number of elements in the value list. */ + static constexpr auto size = sizeof...(Value); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_element; + +/** + * @brief Provides compile-time indexed access to the values of a value list. + * @tparam Index Index of the value to return. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element> + : value_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element<0u, value_list> { + /*! @brief Searched type. */ + using type = decltype(Value); + /*! @brief Searched value. */ + static constexpr auto value = Value; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Value list to search into. + */ +template +using value_list_element_t = typename value_list_element::type; + +/** + * @brief Helper type. + * @tparam Index Index of the value to return. + * @tparam List Value list to search into. + */ +template +inline constexpr auto value_list_element_v = value_list_element::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_index; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam First First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 1u + value_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + static_assert(value_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +inline constexpr std::size_t value_list_index_v = value_list_index::value; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @return A value list composed by the values of both the value lists. + */ +template +constexpr value_list operator+(value_list, value_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_cat; + +/*! @brief Concatenates multiple value lists. */ +template<> +struct value_list_cat<> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list<>; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @tparam List Other value lists, if any. + */ +template +struct value_list_cat, value_list, List...> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = typename value_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the value list. + */ +template +struct value_list_cat> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list; +}; + +/** + * @brief Helper type. + * @tparam List Value lists to concatenate. + */ +template +using value_list_cat_t = typename value_list_cat::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_unique; + +/** + * @brief Removes duplicates values from a value list. + * @tparam Value One of the values provided by the given value list. + * @tparam Other The other values provided by the given value list. + */ +template +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = std::conditional_t< + ((Value == Other) || ...), + typename value_list_unique>::type, + value_list_cat_t, typename value_list_unique>::type>>; +}; + +/*! @brief Removes duplicates values from a value list. */ +template<> +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = value_list<>; +}; + +/** + * @brief Helper type. + * @tparam Type A value list. + */ +template +using value_list_unique_t = typename value_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a value list contains + * a given value, false otherwise. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +struct value_list_contains; + +/** + * @copybrief value_list_contains + * @tparam Value Values provided by the value list. + * @tparam Other Value to look for. + */ +template +struct value_list_contains, Other> + : std::bool_constant<((Value == Other) || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +inline constexpr bool value_list_contains_v = value_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_diff; + +/** + * @brief Computes the difference between two value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + */ +template +struct value_list_diff, value_list> { + /*! @brief A value list that is the difference between the two value lists. */ + using type = value_list_cat_t, Value>, value_list<>, value_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Value lists between which to compute the difference. + */ +template +using value_list_diff_t = typename value_list_diff::type; + +/*! @brief Same as std::is_invocable, but with tuples. */ +template +struct is_applicable: std::false_type {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @brief Helper variable template. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_v = is_applicable::value; + +/*! @brief Same as std::is_invocable_r, but with tuples for arguments. */ +template +struct is_applicable_r: std::false_type {}; + +/** + * @copybrief is_applicable_r + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +struct is_applicable_r>: std::is_invocable_r {}; + +/** + * @brief Helper variable template. + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_r_v = is_applicable_r::value; + +/** + * @brief Provides the member constant `value` to true if a given type is + * complete, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_complete: std::false_type {}; + +/*! @copydoc is_complete */ +template +struct is_complete>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_complete_v = is_complete::value; + +/** + * @brief Provides the member constant `value` to true if a given type is an + * iterator, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_iterator: std::false_type {}; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_iterator_category: std::false_type {}; + +template +struct has_iterator_category::iterator_category>>: std::true_type {}; + +} // namespace internal +/*! @endcond */ + +/*! @copydoc is_iterator */ +template +struct is_iterator>>>> + : internal::has_iterator_category {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_iterator_v = is_iterator::value; + +/** + * @brief Provides the member constant `value` to true if a given type is both + * an empty and non-final class, false otherwise. + * @tparam Type The type to test + */ +template +struct is_ebco_eligible + : std::bool_constant && !std::is_final_v> {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_ebco_eligible_v = is_ebco_eligible::value; + +/** + * @brief Provides the member constant `value` to true if `Type::is_transparent` + * is valid and denotes a type, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_transparent: std::false_type {}; + +/*! @copydoc is_transparent */ +template +struct is_transparent>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_transparent_v = is_transparent::value; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_tuple_size_value: std::false_type {}; + +template +struct has_tuple_size_value::value)>>: std::true_type {}; + +template +struct has_value_type: std::false_type {}; + +template +struct has_value_type>: std::true_type {}; + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable(); + +template +[[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence) { + return (dispatch_is_equality_comparable>() && ...); +} + +template +[[nodiscard]] constexpr bool maybe_equality_comparable(char) { + return false; +} + +template +[[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval() == std::declval()) { + return true; +} + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable() { + // NOLINTBEGIN(modernize-use-transparent-functors) + if constexpr(std::is_array_v) { + return false; + } else if constexpr(is_complete_v>>) { + if constexpr(has_tuple_size_value::value) { + return maybe_equality_comparable(0) && unpack_maybe_equality_comparable(std::make_index_sequence::value>{}); + } else { + return maybe_equality_comparable(0); + } + } else if constexpr(has_value_type::value) { + if constexpr(is_iterator_v || std::is_same_v || dispatch_is_equality_comparable()) { + return maybe_equality_comparable(0); + } else { + return false; + } + } else { + return maybe_equality_comparable(0); + } + // NOLINTEND(modernize-use-transparent-functors) +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Provides the member constant `value` to true if a given type is + * equality comparable, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_equality_comparable: std::bool_constant()> {}; + +/*! @copydoc is_equality_comparable */ +template +struct is_equality_comparable: is_equality_comparable {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_equality_comparable_v = is_equality_comparable::value; + +/** + * @brief Transcribes the constness of a type to another type. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = std::remove_const_t; +}; + +/*! @copydoc constness_as */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = const To; +}; + +/** + * @brief Alias template to facilitate the transcription of the constness. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +using constness_as_t = typename constness_as::type; + +/** + * @brief Extracts the class of a non-static member object or function. + * @tparam Member A pointer to a non-static member object or function. + */ +template +class member_class { + static_assert(std::is_member_pointer_v, "Invalid pointer type to non-static member object or function"); + + template + static Class *clazz(Ret (Class::*)(Args...)); + + template + static Class *clazz(Ret (Class::*)(Args...) const); + + template + static Class *clazz(Type Class::*); + +public: + /*! @brief The class of the given non-static member object or function. */ + using type = std::remove_pointer_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Member A pointer to a non-static member object or function. + */ +template +using member_class_t = typename member_class::type; + +/** + * @brief Extracts the n-th argument of a _callable_ type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid _callable_ type. + */ +template +class nth_argument { + template + static constexpr type_list pick_up(Ret (*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...) const); + + template + static constexpr type_list pick_up(Type Class ::*); + + template + static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&); + +public: + /*! @brief N-th argument of the _callable_ type. */ + using type = type_list_element_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid function, member function or data member type. + */ +template +using nth_argument_t = typename nth_argument::type; + +} // namespace entt + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::type_list_element> {}; + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::value_list_element> {}; + +#endif + +// #include "utility.hpp" + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +enum class any_request : std::uint8_t { + info, + transfer, + assign, + compare, + copy, + move +}; + +template +struct basic_any_storage { + static constexpr bool has_buffer = true; + union { + const void *instance{}; + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) + alignas(Align) std::byte buffer[Len]; + }; +}; + +template +struct basic_any_storage<0u, Align> { + static constexpr bool has_buffer = false; + const void *instance{}; +}; + +template +// NOLINTNEXTLINE(bugprone-sizeof-expression) +struct in_situ: std::bool_constant<(Len != 0u) && alignof(Type) <= Align && sizeof(Type) <= Len && std::is_nothrow_move_constructible_v> {}; + +template +struct in_situ: std::false_type {}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief A SBO friendly, type-safe container for single values of any type. + * @tparam Len Size of the buffer reserved for the small buffer optimization. + * @tparam Align Optional alignment requirement. + */ +template +class basic_any: private internal::basic_any_storage { + using request = internal::any_request; + using base_type = internal::basic_any_storage; + using vtable_type = const void *(const request, const basic_any &, const void *); + using deleter_type = void(const basic_any &); + + template + static constexpr bool in_situ_v = internal::in_situ::value; + + template + static const void *basic_vtable(const request req, const basic_any &value, const void *other) { + static_assert(std::is_same_v>, Type>, "Invalid type"); + + switch(const auto *elem = static_cast(value.data()); req) { + case request::info: + return &type_id(); + case request::transfer: + if constexpr(std::is_move_assignable_v) { + // NOLINTNEXTLINE(bugprone-casting-through-void) + *const_cast(elem) = std::move(*static_cast(const_cast(other))); + return other; + } + [[fallthrough]]; + case request::assign: + if constexpr(std::is_copy_assignable_v) { + *const_cast(elem) = *static_cast(other); + return other; + } + break; + case request::compare: + if constexpr(!std::is_function_v && !std::is_array_v && is_equality_comparable_v) { + return (*elem == *static_cast(other)) ? other : nullptr; + } else { + return (elem == other) ? other : nullptr; + } + case request::copy: + if constexpr(std::is_copy_constructible_v) { + // NOLINTNEXTLINE(bugprone-casting-through-void) + static_cast(const_cast(other))->initialize(*elem); + } + break; + case request::move: + ENTT_ASSERT(value.mode == any_policy::embedded, "Unexpected policy"); + if constexpr(in_situ_v) { + // NOLINTNEXTLINE(bugprone-casting-through-void, bugprone-multi-level-implicit-pointer-conversion) + return ::new(&static_cast(const_cast(other))->buffer) Type{std::move(*const_cast(elem))}; + } + } + + return nullptr; + } + + template + static void basic_deleter(const basic_any &value) { + static_assert(std::is_same_v>, Type>, "Invalid type"); + ENTT_ASSERT((value.mode == any_policy::dynamic) || ((value.mode == any_policy::embedded) && !std::is_trivially_destructible_v), "Unexpected policy"); + + const auto *elem = static_cast(value.data()); + + if constexpr(in_situ_v) { + (value.mode == any_policy::embedded) ? elem->~Type() : (delete elem); + } else if constexpr(std::is_array_v) { + delete[] elem; + } else { + delete elem; + } + } + + template + void initialize([[maybe_unused]] Args &&...args) { + using plain_type = std::remove_const_t>; + + vtable = basic_vtable; + underlying_type = type_hash::value(); + + if constexpr(std::is_void_v) { + deleter = nullptr; + mode = any_policy::empty; + this->instance = nullptr; + } else if constexpr(std::is_lvalue_reference_v) { + deleter = nullptr; + mode = std::is_const_v> ? any_policy::cref : any_policy::ref; + static_assert((std::is_lvalue_reference_v && ...) && (sizeof...(Args) == 1u), "Invalid arguments"); + // NOLINTNEXTLINE(bugprone-multi-level-implicit-pointer-conversion) + this->instance = (std::addressof(args), ...); + } else if constexpr(in_situ_v) { + if constexpr(std::is_trivially_destructible_v) { + deleter = nullptr; + } else { + deleter = &basic_deleter; + } + + mode = any_policy::embedded; + + if constexpr(std::is_aggregate_v && (sizeof...(Args) != 0u || !std::is_default_constructible_v)) { + ::new(&this->buffer) plain_type{std::forward(args)...}; + } else { + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay) + ::new(&this->buffer) plain_type(std::forward(args)...); + } + } else { + deleter = &basic_deleter; + mode = any_policy::dynamic; + + if constexpr(std::is_aggregate_v && (sizeof...(Args) != 0u || !std::is_default_constructible_v)) { + this->instance = new plain_type{std::forward(args)...}; + } else if constexpr(std::is_array_v) { + static_assert(sizeof...(Args) == 0u, "Invalid arguments"); + this->instance = new plain_type[std::extent_v](); + } else { + this->instance = new plain_type(std::forward(args)...); + } + } + } + + void invoke_deleter_if_exists() { + if(deleter != nullptr) { + deleter(*this); + } + } + +public: + /*! @brief Size of the internal buffer. */ + static constexpr auto length = Len; + /*! @brief Alignment requirement. */ + static constexpr auto alignment = Align; + + /*! @brief Default constructor. */ + constexpr basic_any() noexcept + : basic_any{std::in_place_type} {} + + /** + * @brief Constructs a wrapper by directly initializing the new object. + * @tparam Type Type of object to use to initialize the wrapper. + * @tparam Args Types of arguments to use to construct the new instance. + * @param args Parameters to use to construct the instance. + */ + template + explicit basic_any(std::in_place_type_t, Args &&...args) + : base_type{} { + initialize(std::forward(args)...); + } + + /** + * @brief Constructs a wrapper taking ownership of the passed object. + * @tparam Type Type of object to use to initialize the wrapper. + * @param value A pointer to an object to take ownership of. + */ + template + explicit basic_any(std::in_place_t, Type *value) + : base_type{} { + static_assert(!std::is_const_v && !std::is_void_v, "Non-const non-void pointer required"); + + if(value == nullptr) { + initialize(); + } else { + initialize(*value); + deleter = &basic_deleter; + mode = any_policy::dynamic; + } + } + + /** + * @brief Constructs a wrapper from a given value. + * @tparam Type Type of object to use to initialize the wrapper. + * @param value An instance of an object to use to initialize the wrapper. + */ + template, basic_any>>> + basic_any(Type &&value) + : basic_any{std::in_place_type>, std::forward(value)} {} + + /** + * @brief Copy constructor. + * @param other The instance to copy from. + */ + basic_any(const basic_any &other) + : basic_any{} { + other.vtable(request::copy, other, this); + } + + /** + * @brief Move constructor. + * @param other The instance to move from. + */ + basic_any(basic_any &&other) noexcept + : base_type{}, + vtable{other.vtable}, + deleter{other.deleter}, + underlying_type{other.underlying_type}, + mode{other.mode} { + if(other.mode == any_policy::embedded) { + other.vtable(request::move, other, this); + } else if(other.mode != any_policy::empty) { + this->instance = std::exchange(other.instance, nullptr); + } + } + + /*! @brief Frees the internal buffer, whatever it means. */ + ~basic_any() { + invoke_deleter_if_exists(); + } + + /** + * @brief Copy assignment operator. + * @param other The instance to copy from. + * @return This any object. + */ + basic_any &operator=(const basic_any &other) { + if(this != &other) { + invoke_deleter_if_exists(); + + if(other) { + other.vtable(request::copy, other, this); + } else { + initialize(); + } + } + + return *this; + } + + /** + * @brief Move assignment operator. + * @param other The instance to move from. + * @return This any object. + */ + basic_any &operator=(basic_any &&other) noexcept { + if(this != &other) { + invoke_deleter_if_exists(); + + if(other.mode == any_policy::embedded) { + other.vtable(request::move, other, this); + } else if(other.mode != any_policy::empty) { + this->instance = std::exchange(other.instance, nullptr); + } + + vtable = other.vtable; + deleter = other.deleter; + underlying_type = other.underlying_type; + mode = other.mode; + } + + return *this; + } + + /** + * @brief Value assignment operator. + * @tparam Type Type of object to use to initialize the wrapper. + * @param value An instance of an object to use to initialize the wrapper. + * @return This any object. + */ + template, basic_any>>> + basic_any &operator=(Type &&value) { + emplace>(std::forward(value)); + return *this; + } + + /** + * @brief Returns false if a wrapper is empty, true otherwise. + * @return False if the wrapper is empty, true otherwise. + */ + [[nodiscard]] bool has_value() const noexcept { + return (mode != any_policy::empty); + } + + /** + * @brief Returns false if the wrapper does not contain the expected type, + * true otherwise. + * @param req Expected type. + * @return False if the wrapper does not contain the expected type, true + * otherwise. + */ + [[nodiscard]] bool has_value(const type_info &req) const noexcept { + return (underlying_type == req.hash()); + } + + /** + * @brief Returns false if the wrapper does not contain the expected type, + * true otherwise. + * @tparam Type Expected type. + * @return False if the wrapper does not contain the expected type, true + * otherwise. + */ + template + [[nodiscard]] bool has_value() const noexcept { + static_assert(std::is_same_v, Type>, "Invalid type"); + return (underlying_type == type_hash::value()); + } + + /** + * @brief Returns the object type info if any, `type_id()` otherwise. + * @return The object type info if any, `type_id()` otherwise. + */ + [[nodiscard]] const type_info &info() const noexcept { + return *static_cast(vtable(request::info, *this, nullptr)); + } + + /*! @copydoc info */ + [[deprecated("use ::info instead")]] [[nodiscard]] const type_info &type() const noexcept { + return info(); + } + + /** + * @brief Returns an opaque pointer to the contained instance. + * @return An opaque pointer the contained instance, if any. + */ + [[nodiscard]] const void *data() const noexcept { + if constexpr(base_type::has_buffer) { + return (mode == any_policy::embedded) ? &this->buffer : this->instance; + } else { + return this->instance; + } + } + + /** + * @brief Returns an opaque pointer to the contained instance. + * @param req Expected type. + * @return An opaque pointer the contained instance, if any. + */ + [[nodiscard]] const void *data(const type_info &req) const noexcept { + return has_value(req) ? data() : nullptr; + } + + /** + * @brief Returns an opaque pointer to the contained instance. + * @tparam Type Expected type. + * @return An opaque pointer the contained instance, if any. + */ + template + [[nodiscard]] const Type *data() const noexcept { + return has_value>() ? static_cast(data()) : nullptr; + } + + /** + * @brief Returns an opaque pointer to the contained instance. + * @return An opaque pointer the contained instance, if any. + */ + [[nodiscard]] void *data() noexcept { + return (mode == any_policy::cref) ? nullptr : const_cast(std::as_const(*this).data()); + } + + /** + * @brief Returns an opaque pointer to the contained instance. + * @param req Expected type. + * @return An opaque pointer the contained instance, if any. + */ + [[nodiscard]] void *data(const type_info &req) noexcept { + return (mode == any_policy::cref) ? nullptr : const_cast(std::as_const(*this).data(req)); + } + + /** + * @brief Returns an opaque pointer to the contained instance. + * @tparam Type Expected type. + * @return An opaque pointer the contained instance, if any. + */ + template + [[nodiscard]] Type *data() noexcept { + if constexpr(std::is_const_v) { + return std::as_const(*this).template data>(); + } else { + return (mode == any_policy::cref) ? nullptr : const_cast(std::as_const(*this).template data>()); + } + } + + /** + * @brief Replaces the contained object by creating a new instance directly. + * @tparam Type Type of object to use to initialize the wrapper. + * @tparam Args Types of arguments to use to construct the new instance. + * @param args Parameters to use to construct the instance. + */ + template + void emplace(Args &&...args) { + invoke_deleter_if_exists(); + initialize(std::forward(args)...); + } + + /** + * @brief Assigns a value to the contained object without replacing it. + * @param other The value to assign to the contained object. + * @return True in case of success, false otherwise. + */ + bool assign(const basic_any &other) { + if(other && (mode != any_policy::cref) && (underlying_type == other.underlying_type)) { + return (vtable(request::assign, *this, other.data()) != nullptr); + } + + return false; + } + + /*! @copydoc assign */ + // NOLINTNEXTLINE(cppcoreguidelines-rvalue-reference-param-not-moved) + bool assign(basic_any &&other) { + if(other && (mode != any_policy::cref) && (underlying_type == other.underlying_type)) { + return (other.mode == any_policy::cref) ? (vtable(request::assign, *this, std::as_const(other).data()) != nullptr) : (vtable(request::transfer, *this, other.data()) != nullptr); + } + + return false; + } + + /*! @brief Destroys contained object */ + void reset() { + invoke_deleter_if_exists(); + initialize(); + } + + /** + * @brief Returns false if a wrapper is empty, true otherwise. + * @return False if the wrapper is empty, true otherwise. + */ + [[nodiscard]] explicit operator bool() const noexcept { + return has_value(); + } + + /** + * @brief Checks if two wrappers differ in their content. + * @param other Wrapper with which to compare. + * @return False if the two objects differ in their content, true otherwise. + */ + [[nodiscard]] bool operator==(const basic_any &other) const noexcept { + if(other && (underlying_type == other.underlying_type)) { + return (vtable(request::compare, *this, other.data()) != nullptr); + } + + return (!*this && !other); + } + + /** + * @brief Checks if two wrappers differ in their content. + * @param other Wrapper with which to compare. + * @return True if the two objects differ in their content, false otherwise. + */ + [[nodiscard]] bool operator!=(const basic_any &other) const noexcept { + return !(*this == other); + } + + /** + * @brief Aliasing constructor. + * @return A wrapper that shares a reference to an unmanaged object. + */ + [[nodiscard]] basic_any as_ref() noexcept { + basic_any other = std::as_const(*this).as_ref(); + other.mode = (mode == any_policy::cref ? any_policy::cref : any_policy::ref); + return other; + } + + /*! @copydoc as_ref */ + [[nodiscard]] basic_any as_ref() const noexcept { + basic_any other{}; + other.instance = data(); + other.vtable = vtable; + other.underlying_type = underlying_type; + other.mode = any_policy::cref; + return other; + } + + /** + * @brief Returns true if a wrapper owns its object, false otherwise. + * @return True if the wrapper owns its object, false otherwise. + */ + [[nodiscard]] bool owner() const noexcept { + return (mode == any_policy::dynamic || mode == any_policy::embedded); + } + + /** + * @brief Returns the current mode of an any object. + * @return The current mode of the any object. + */ + [[nodiscard]] any_policy policy() const noexcept { + return mode; + } + +private: + vtable_type *vtable{}; + deleter_type *deleter{}; + id_type underlying_type{}; + any_policy mode{}; +}; + +/** + * @brief Performs type-safe access to the contained object. + * @tparam Type Type to which conversion is required. + * @tparam Len Size of the buffer reserved for the small buffer optimization. + * @tparam Align Alignment requirement. + * @param data Target any object. + * @return The element converted to the requested type. + */ +template +[[nodiscard]] std::remove_const_t any_cast(const basic_any &data) noexcept { + const auto *const instance = any_cast>(&data); + ENTT_ASSERT(instance, "Invalid instance"); + return static_cast(*instance); +} + +/*! @copydoc any_cast */ +template +[[nodiscard]] std::remove_const_t any_cast(basic_any &data) noexcept { + // forces const on non-reference types to make them work also with wrappers for const references + auto *const instance = any_cast>(&data); + ENTT_ASSERT(instance, "Invalid instance"); + return static_cast(*instance); +} + +/*! @copydoc any_cast */ +template +// NOLINTNEXTLINE(cppcoreguidelines-rvalue-reference-param-not-moved) +[[nodiscard]] std::remove_const_t any_cast(basic_any &&data) noexcept { + if constexpr(std::is_copy_constructible_v>>) { + if(auto *const instance = any_cast>(&data); instance) { + return static_cast(std::move(*instance)); + } + + return any_cast(data); + } else { + auto *const instance = any_cast>(&data); + ENTT_ASSERT(instance, "Invalid instance"); + return static_cast(std::move(*instance)); + } +} + +/*! @copydoc any_cast */ +template +[[nodiscard]] const Type *any_cast(const basic_any *data) noexcept { + return data->template data>(); +} + +/*! @copydoc any_cast */ +template +[[nodiscard]] Type *any_cast(basic_any *data) noexcept { + if constexpr(std::is_const_v) { + // last attempt to make wrappers for const references return their values + return any_cast(&std::as_const(*data)); + } else { + return data->template data(); + } +} + +/** + * @brief Constructs a wrapper from a given type, passing it all arguments. + * @tparam Type Type of object to use to initialize the wrapper. + * @tparam Len Size of the buffer reserved for the small buffer optimization. + * @tparam Align Optional alignment requirement. + * @tparam Args Types of arguments to use to construct the new instance. + * @param args Parameters to use to construct the instance. + * @return A properly initialized wrapper for an object of the given type. + */ +template::length, std::size_t Align = basic_any::alignment, typename... Args> +[[nodiscard]] basic_any make_any(Args &&...args) { + return basic_any{std::in_place_type, std::forward(args)...}; +} + +/** + * @brief Forwards its argument and avoids copies for lvalue references. + * @tparam Len Size of the buffer reserved for the small buffer optimization. + * @tparam Align Optional alignment requirement. + * @tparam Type Type of argument to use to construct the new instance. + * @param value Parameter to use to construct the instance. + * @return A properly initialized and not necessarily owning wrapper. + */ +template::length, std::size_t Align = basic_any::alignment, typename Type> +[[nodiscard]] basic_any forward_as_any(Type &&value) { + return basic_any{std::in_place_type, std::forward(value)}; +} + +} // namespace entt + +#endif + +// #include "../core/bit.hpp" + +// #include "../core/type_info.hpp" + +// #include "entity.hpp" + +// #include "fwd.hpp" + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct sparse_set_iterator final { + using value_type = typename Container::value_type; + using pointer = typename Container::const_pointer; + using reference = typename Container::const_reference; + using difference_type = typename Container::difference_type; + using iterator_category = std::random_access_iterator_tag; + + constexpr sparse_set_iterator() noexcept + : packed{}, + offset{} {} + + constexpr sparse_set_iterator(const Container &ref, const difference_type idx) noexcept + : packed{&ref}, + offset{idx} {} + + constexpr sparse_set_iterator &operator++() noexcept { + return --offset, *this; + } + + constexpr sparse_set_iterator operator++(int) noexcept { + const sparse_set_iterator orig = *this; + return ++(*this), orig; + } + + constexpr sparse_set_iterator &operator--() noexcept { + return ++offset, *this; + } + + constexpr sparse_set_iterator operator--(int) noexcept { + const sparse_set_iterator orig = *this; + return operator--(), orig; + } + + constexpr sparse_set_iterator &operator+=(const difference_type value) noexcept { + offset -= value; + return *this; + } + + constexpr sparse_set_iterator operator+(const difference_type value) const noexcept { + sparse_set_iterator copy = *this; + return (copy += value); + } + + constexpr sparse_set_iterator &operator-=(const difference_type value) noexcept { + return (*this += -value); + } + + constexpr sparse_set_iterator operator-(const difference_type value) const noexcept { + return (*this + -value); + } + + [[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept { + return (*packed)[static_cast(index() - value)]; + } + + [[nodiscard]] constexpr pointer operator->() const noexcept { + return std::addressof(operator[](0)); + } + + [[nodiscard]] constexpr reference operator*() const noexcept { + return operator[](0); + } + + [[nodiscard]] constexpr pointer data() const noexcept { + return packed ? packed->data() : nullptr; + } + + [[nodiscard]] constexpr difference_type index() const noexcept { + return offset - 1; + } + +private: + const Container *packed; + difference_type offset; +}; + +template +[[nodiscard]] constexpr std::ptrdiff_t operator-(const sparse_set_iterator &lhs, const sparse_set_iterator &rhs) noexcept { + return rhs.index() - lhs.index(); +} + +template +[[nodiscard]] constexpr bool operator==(const sparse_set_iterator &lhs, const sparse_set_iterator &rhs) noexcept { + return lhs.index() == rhs.index(); +} + +template +[[nodiscard]] constexpr bool operator!=(const sparse_set_iterator &lhs, const sparse_set_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +template +[[nodiscard]] constexpr bool operator<(const sparse_set_iterator &lhs, const sparse_set_iterator &rhs) noexcept { + return lhs.index() > rhs.index(); +} + +template +[[nodiscard]] constexpr bool operator>(const sparse_set_iterator &lhs, const sparse_set_iterator &rhs) noexcept { + return rhs < lhs; +} + +template +[[nodiscard]] constexpr bool operator<=(const sparse_set_iterator &lhs, const sparse_set_iterator &rhs) noexcept { + return !(lhs > rhs); +} + +template +[[nodiscard]] constexpr bool operator>=(const sparse_set_iterator &lhs, const sparse_set_iterator &rhs) noexcept { + return !(lhs < rhs); +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Sparse set implementation. + * + * Sparse set or packed array or whatever is the name users give it.
+ * Two arrays: an _external_ one and an _internal_ one; a _sparse_ one and a + * _packed_ one; one used for direct access through contiguous memory, the other + * one used to get the data through an extra level of indirection.
+ * This type of data structure is widely documented in the literature and on the + * web. This is nothing more than a customized implementation suitable for the + * purpose of the framework. + * + * @note + * Internal data structures arrange elements to maximize performance. There are + * no guarantees that entities are returned in the insertion order when iterate + * a sparse set. Do not make assumption on the order in any case. + * + * @tparam Entity A valid entity type. + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +class basic_sparse_set { + using alloc_traits = std::allocator_traits; + static_assert(std::is_same_v, "Invalid value type"); + using sparse_container_type = std::vector>; + using packed_container_type = std::vector; + using traits_type = entt_traits; + + static constexpr auto max_size = static_cast(traits_type::to_entity(null)); + + // it could be auto but gcc complains and emits a warning due to a false positive + [[nodiscard]] std::size_t policy_to_head() const noexcept { + return static_cast(max_size * static_cast>(mode != deletion_policy::swap_only)); + } + + [[nodiscard]] auto entity_to_pos(const Entity entt) const noexcept { + return static_cast(traits_type::to_entity(entt)); + } + + [[nodiscard]] auto pos_to_page(const std::size_t pos) const noexcept { + return static_cast(pos / traits_type::page_size); + } + + [[nodiscard]] auto sparse_ptr(const Entity entt) const { + const auto pos = entity_to_pos(entt); + const auto page = pos_to_page(pos); + return (page < sparse.size() && sparse[page]) ? (sparse[page] + fast_mod(pos, traits_type::page_size)) : nullptr; + } + + [[nodiscard]] auto &sparse_ref(const Entity entt) const { + ENTT_ASSERT(sparse_ptr(entt), "Invalid element"); + const auto pos = entity_to_pos(entt); + return sparse[pos_to_page(pos)][fast_mod(pos, traits_type::page_size)]; + } + + [[nodiscard]] auto to_iterator(const Entity entt) const { + return --(end() - static_cast(index(entt))); + } + + [[nodiscard]] auto &assure_at_least(const Entity entt) { + const auto pos = entity_to_pos(entt); + const auto page = pos_to_page(pos); + + if(!(page < sparse.size())) { + sparse.resize(page + 1u, nullptr); + } + + if(!sparse[page]) { + constexpr entity_type init = null; + auto page_allocator{packed.get_allocator()}; + sparse[page] = alloc_traits::allocate(page_allocator, traits_type::page_size); + std::uninitialized_fill(sparse[page], sparse[page] + traits_type::page_size, init); + } + + return sparse[page][fast_mod(pos, traits_type::page_size)]; + } + + void release_sparse_pages() { + auto page_allocator{packed.get_allocator()}; + + for(auto &&page: sparse) { + if(page != nullptr) { + std::destroy(page, page + traits_type::page_size); + alloc_traits::deallocate(page_allocator, page, traits_type::page_size); + page = nullptr; + } + } + } + + void swap_at(const std::size_t lhs, const std::size_t rhs) { + auto &from = packed[lhs]; + auto &to = packed[rhs]; + + sparse_ref(from) = traits_type::combine(static_cast(rhs), traits_type::to_integral(from)); + sparse_ref(to) = traits_type::combine(static_cast(lhs), traits_type::to_integral(to)); + + std::swap(from, to); + } + +private: + [[nodiscard]] virtual const void *get_at(const std::size_t) const { + return nullptr; + } + + virtual void swap_or_move([[maybe_unused]] const std::size_t lhs, [[maybe_unused]] const std::size_t rhs) { + ENTT_ASSERT((mode != deletion_policy::swap_only) || ((lhs < head) == (rhs < head)), "Cross swapping is not supported"); + } + +protected: + /*! @brief Random access iterator type. */ + using basic_iterator = internal::sparse_set_iterator; + + /** + * @brief Erases an entity from a sparse set. + * @param it An iterator to the element to pop. + */ + void swap_only(const basic_iterator it) { + ENTT_ASSERT(mode == deletion_policy::swap_only, "Deletion policy mismatch"); + const auto pos = index(*it); + bump(traits_type::next(*it)); + swap_at(pos, head -= (pos < head)); + } + + /** + * @brief Erases an entity from a sparse set. + * @param it An iterator to the element to pop. + */ + void swap_and_pop(const basic_iterator it) { + ENTT_ASSERT(mode == deletion_policy::swap_and_pop, "Deletion policy mismatch"); + auto &self = sparse_ref(*it); + const auto entt = traits_type::to_entity(self); + sparse_ref(packed.back()) = traits_type::combine(entt, traits_type::to_integral(packed.back())); + packed[static_cast(entt)] = packed.back(); + // unnecessary but it helps to detect nasty bugs + // NOLINTNEXTLINE(bugprone-assert-side-effect) + ENTT_ASSERT((packed.back() = null, true), ""); + // lazy self-assignment guard + self = null; + packed.pop_back(); + } + + /** + * @brief Erases an entity from a sparse set. + * @param it An iterator to the element to pop. + */ + void in_place_pop(const basic_iterator it) { + ENTT_ASSERT(mode == deletion_policy::in_place, "Deletion policy mismatch"); + const auto pos = entity_to_pos(std::exchange(sparse_ref(*it), null)); + packed[pos] = traits_type::combine(static_cast(std::exchange(head, pos)), tombstone); + } + + /** + * @brief Erases entities from a sparse set. + * @param first An iterator to the first element of the range of entities. + * @param last An iterator past the last element of the range of entities. + */ + virtual void pop(basic_iterator first, basic_iterator last) { + switch(mode) { + case deletion_policy::swap_and_pop: + for(; first != last; ++first) { + swap_and_pop(first); + } + break; + case deletion_policy::in_place: + for(; first != last; ++first) { + in_place_pop(first); + } + break; + case deletion_policy::swap_only: + for(; first != last; ++first) { + swap_only(first); + } + break; + } + } + + /*! @brief Erases all entities of a sparse set. */ + virtual void pop_all() { + switch(mode) { + case deletion_policy::in_place: + if(head != max_size) { + for(auto &&elem: packed) { + if(elem != tombstone) { + sparse_ref(elem) = null; + } + } + break; + } + [[fallthrough]]; + case deletion_policy::swap_only: + case deletion_policy::swap_and_pop: + for(auto &&elem: packed) { + sparse_ref(elem) = null; + } + break; + } + + head = policy_to_head(); + packed.clear(); + } + + /** + * @brief Assigns an entity to a sparse set. + * @param entt A valid identifier. + * @param force_back Force back insertion. + * @return Iterator pointing to the emplaced element. + */ + virtual basic_iterator try_emplace(const Entity entt, const bool force_back, const void * = nullptr) { + ENTT_ASSERT(entt != null && entt != tombstone, "Invalid element"); + auto &elem = assure_at_least(entt); + auto pos = size(); + + switch(mode) { + case deletion_policy::in_place: + if(head != max_size && !force_back) { + pos = head; + ENTT_ASSERT(elem == null, "Slot not available"); + elem = traits_type::combine(static_cast(head), traits_type::to_integral(entt)); + head = entity_to_pos(std::exchange(packed[pos], entt)); + break; + } + [[fallthrough]]; + case deletion_policy::swap_and_pop: + packed.push_back(entt); + ENTT_ASSERT(elem == null, "Slot not available"); + elem = traits_type::combine(static_cast(packed.size() - 1u), traits_type::to_integral(entt)); + break; + case deletion_policy::swap_only: + if(elem == null) { + packed.push_back(entt); + elem = traits_type::combine(static_cast(packed.size() - 1u), traits_type::to_integral(entt)); + } else { + ENTT_ASSERT(!(entity_to_pos(elem) < head), "Slot not available"); + bump(entt); + } + + pos = head++; + swap_at(entity_to_pos(elem), pos); + break; + } + + return iterator{packed, static_cast(++pos)}; + } + + /*! @brief Forwards variables to derived classes, if any. */ + // NOLINTNEXTLINE(performance-unnecessary-value-param) + virtual void bind_any(any) noexcept {} + +public: + /*! @brief Allocator type. */ + using allocator_type = Allocator; + /*! @brief Underlying entity identifier. */ + using entity_type = typename traits_type::value_type; + /*! @brief Underlying version type. */ + using version_type = typename traits_type::version_type; + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + /*! @brief Signed integer type. */ + using difference_type = std::ptrdiff_t; + /*! @brief Pointer type to contained entities. */ + using pointer = typename packed_container_type::const_pointer; + /*! @brief Random access iterator type. */ + using iterator = basic_iterator; + /*! @brief Constant random access iterator type. */ + using const_iterator = iterator; + /*! @brief Reverse iterator type. */ + using reverse_iterator = std::reverse_iterator; + /*! @brief Constant reverse iterator type. */ + using const_reverse_iterator = std::reverse_iterator; + + /*! @brief Default constructor. */ + basic_sparse_set() + : basic_sparse_set{type_id()} {} + + /** + * @brief Constructs an empty container with a given allocator. + * @param allocator The allocator to use. + */ + explicit basic_sparse_set(const allocator_type &allocator) + : basic_sparse_set{deletion_policy::swap_and_pop, allocator} {} + + /** + * @brief Constructs an empty container with the given policy and allocator. + * @param pol Type of deletion policy. + * @param allocator The allocator to use (possibly default-constructed). + */ + explicit basic_sparse_set(deletion_policy pol, const allocator_type &allocator = {}) + : basic_sparse_set{type_id(), pol, allocator} {} + + /** + * @brief Constructs an empty container with the given value type, policy + * and allocator. + * @param elem Returned value type, if any. + * @param pol Type of deletion policy. + * @param allocator The allocator to use (possibly default-constructed). + */ + explicit basic_sparse_set(const type_info &elem, deletion_policy pol = deletion_policy::swap_and_pop, const allocator_type &allocator = {}) + : sparse{allocator}, + packed{allocator}, + descriptor{&elem}, + mode{pol}, + head{policy_to_head()} { + ENTT_ASSERT(traits_type::version_mask || mode != deletion_policy::in_place, "Policy does not support zero-sized versions"); + } + + /*! @brief Default copy constructor, deleted on purpose. */ + basic_sparse_set(const basic_sparse_set &) = delete; + + /** + * @brief Move constructor. + * @param other The instance to move from. + */ + basic_sparse_set(basic_sparse_set &&other) noexcept + : sparse{std::move(other.sparse)}, + packed{std::move(other.packed)}, + descriptor{other.descriptor}, + mode{other.mode}, + head{std::exchange(other.head, policy_to_head())} {} + + /** + * @brief Allocator-extended move constructor. + * @param other The instance to move from. + * @param allocator The allocator to use. + */ + basic_sparse_set(basic_sparse_set &&other, const allocator_type &allocator) + : sparse{std::move(other.sparse), allocator}, + packed{std::move(other.packed), allocator}, + descriptor{other.descriptor}, + mode{other.mode}, + head{std::exchange(other.head, policy_to_head())} { + ENTT_ASSERT(alloc_traits::is_always_equal::value || get_allocator() == other.get_allocator(), "Copying a sparse set is not allowed"); + } + + /*! @brief Default destructor. */ + virtual ~basic_sparse_set() { + release_sparse_pages(); + } + + /** + * @brief Default copy assignment operator, deleted on purpose. + * @return This sparse set. + */ + basic_sparse_set &operator=(const basic_sparse_set &) = delete; + + /** + * @brief Move assignment operator. + * @param other The instance to move from. + * @return This sparse set. + */ + basic_sparse_set &operator=(basic_sparse_set &&other) noexcept { + ENTT_ASSERT(alloc_traits::is_always_equal::value || get_allocator() == other.get_allocator(), "Copying a sparse set is not allowed"); + swap(other); + return *this; + } + + /** + * @brief Exchanges the contents with those of a given sparse set. + * @param other Sparse set to exchange the content with. + */ + void swap(basic_sparse_set &other) noexcept { + using std::swap; + swap(sparse, other.sparse); + swap(packed, other.packed); + swap(descriptor, other.descriptor); + swap(mode, other.mode); + swap(head, other.head); + } + + /** + * @brief Returns the associated allocator. + * @return The associated allocator. + */ + [[nodiscard]] constexpr allocator_type get_allocator() const noexcept { + return packed.get_allocator(); + } + + /** + * @brief Returns the deletion policy of a sparse set. + * @return The deletion policy of the sparse set. + */ + [[nodiscard]] deletion_policy policy() const noexcept { + return mode; + } + + /** + * @brief Returns data on the free list whose meaning depends on the mode. + * @return Free list information that is mode dependent. + */ + [[nodiscard]] size_type free_list() const noexcept { + return head; + } + + /** + * @brief Sets data on the free list whose meaning depends on the mode. + * @param value Free list information that is mode dependent. + */ + void free_list(const size_type value) noexcept { + ENTT_ASSERT((mode == deletion_policy::swap_only) && !(value > packed.size()), "Invalid value"); + head = value; + } + + /** + * @brief Increases the capacity of a sparse set. + * + * If the new capacity is greater than the current capacity, new storage is + * allocated, otherwise the method does nothing. + * + * @param cap Desired capacity. + */ + virtual void reserve(const size_type cap) { + packed.reserve(cap); + } + + /** + * @brief Returns the number of elements that a sparse set has currently + * allocated space for. + * @return Capacity of the sparse set. + */ + [[nodiscard]] virtual size_type capacity() const noexcept { + return packed.capacity(); + } + + /*! @brief Requests the removal of unused capacity. */ + virtual void shrink_to_fit() { + sparse_container_type other{sparse.get_allocator()}; + const auto len = sparse.size(); + size_type cnt{}; + + other.reserve(len); + + for(auto &&elem: std::as_const(packed)) { + if(elem != tombstone) { + if(const auto page = pos_to_page(entity_to_pos(elem)); sparse[page] != nullptr) { + if(const auto sz = page + 1u; sz > other.size()) { + other.resize(sz, nullptr); + } + + other[page] = std::exchange(sparse[page], nullptr); + + if(++cnt == len) { + // early exit due to lack of pages + break; + } + } + } + } + + release_sparse_pages(); + sparse.swap(other); + + sparse.shrink_to_fit(); + packed.shrink_to_fit(); + } + + /** + * @brief Returns the extent of a sparse set. + * + * The extent of a sparse set is also the size of the internal sparse array. + * There is no guarantee that all pages have been allocated, nor that the + * internal packed array is be the same size. + * + * @return Extent of the sparse set. + */ + [[nodiscard]] size_type extent() const noexcept { + return sparse.size() * traits_type::page_size; + } + + /** + * @brief Returns the number of elements in a sparse set. + * + * The number of elements is also the size of the internal packed array. + * There is no guarantee that the internal sparse array has the same size. + * Usually the size of the internal sparse array is equal or greater than + * the one of the internal packed array. + * + * @return Number of elements. + */ + [[nodiscard]] size_type size() const noexcept { + return packed.size(); + } + + /** + * @brief Checks whether a sparse set is empty. + * @return True if the sparse set is empty, false otherwise. + */ + [[nodiscard]] bool empty() const noexcept { + return packed.empty(); + } + + /** + * @brief Checks whether a sparse set is fully packed. + * @return True if the sparse set is fully packed, false otherwise. + */ + [[nodiscard]] bool contiguous() const noexcept { + return (mode != deletion_policy::in_place) || (head == max_size); + } + + /** + * @brief Direct access to the internal packed array. + * @return A pointer to the internal packed array. + */ + [[nodiscard]] pointer data() const noexcept { + return packed.data(); + } + + /** + * @brief Returns an iterator to the beginning. + * + * If the sparse set is empty, the returned iterator will be equal to + * `end()`. + * + * @return An iterator to the first entity of the sparse set. + */ + [[nodiscard]] iterator begin() const noexcept { + const auto pos = static_cast(packed.size()); + return iterator{packed, pos}; + } + + /*! @copydoc begin */ + [[nodiscard]] const_iterator cbegin() const noexcept { + return begin(); + } + + /** + * @brief Returns an iterator to the end. + * @return An iterator to the element following the last entity of a sparse + * set. + */ + [[nodiscard]] iterator end() const noexcept { + return iterator{packed, {}}; + } + + /*! @copydoc end */ + [[nodiscard]] const_iterator cend() const noexcept { + return end(); + } + + /** + * @brief Returns a reverse iterator to the beginning. + * + * If the sparse set is empty, the returned iterator will be equal to + * `rend()`. + * + * @return An iterator to the first entity of the reversed internal packed + * array. + */ + [[nodiscard]] reverse_iterator rbegin() const noexcept { + return std::make_reverse_iterator(end()); + } + + /*! @copydoc rbegin */ + [[nodiscard]] const_reverse_iterator crbegin() const noexcept { + return rbegin(); + } + + /** + * @brief Returns a reverse iterator to the end. + * @return An iterator to the element following the last entity of the + * reversed sparse set. + */ + [[nodiscard]] reverse_iterator rend() const noexcept { + return std::make_reverse_iterator(begin()); + } + + /*! @copydoc rend */ + [[nodiscard]] const_reverse_iterator crend() const noexcept { + return rend(); + } + + /** + * @brief Finds an entity. + * @param entt A valid identifier. + * @return An iterator to the given entity if it's found, past the end + * iterator otherwise. + */ + [[nodiscard]] const_iterator find(const entity_type entt) const noexcept { + return contains(entt) ? to_iterator(entt) : end(); + } + + /** + * @brief Checks if a sparse set contains an entity. + * @param entt A valid identifier. + * @return True if the sparse set contains the entity, false otherwise. + */ + [[nodiscard]] bool contains(const entity_type entt) const noexcept { + const auto *elem = sparse_ptr(entt); + constexpr auto cap = traits_type::entity_mask; + constexpr auto mask = traits_type::to_integral(null) & ~cap; + // testing versions permits to avoid accessing the packed array + return elem && (((mask & traits_type::to_integral(entt)) ^ traits_type::to_integral(*elem)) < cap); + } + + /** + * @brief Returns the contained version for an identifier. + * @param entt A valid identifier. + * @return The version for the given identifier if present, the tombstone + * version otherwise. + */ + [[nodiscard]] version_type current(const entity_type entt) const noexcept { + const auto *elem = sparse_ptr(entt); + constexpr auto fallback = traits_type::to_version(tombstone); + return elem ? traits_type::to_version(*elem) : fallback; + } + + /** + * @brief Returns the position of an entity in a sparse set. + * + * @warning + * Attempting to get the position of an entity that doesn't belong to the + * sparse set results in undefined behavior. + * + * @param entt A valid identifier. + * @return The position of the entity in the sparse set. + */ + [[nodiscard]] size_type index(const entity_type entt) const noexcept { + ENTT_ASSERT(contains(entt), "Set does not contain entity"); + return entity_to_pos(sparse_ref(entt)); + } + + /** + * @brief Returns the entity at specified location. + * @param pos The position for which to return the entity. + * @return The entity at specified location. + */ + [[nodiscard]] entity_type operator[](const size_type pos) const noexcept { + ENTT_ASSERT(pos < packed.size(), "Index out of bounds"); + return packed[pos]; + } + + /** + * @brief Returns the element assigned to an entity, if any. + * + * @warning + * Attempting to use an entity that doesn't belong to the sparse set results + * in undefined behavior. + * + * @param entt A valid identifier. + * @return An opaque pointer to the element assigned to the entity, if any. + */ + [[nodiscard]] const void *value(const entity_type entt) const noexcept { + return get_at(index(entt)); + } + + /*! @copydoc value */ + [[nodiscard]] void *value(const entity_type entt) noexcept { + return const_cast(std::as_const(*this).value(entt)); + } + + /** + * @brief Assigns an entity to a sparse set. + * + * @warning + * Attempting to assign an entity that already belongs to the sparse set + * results in undefined behavior. + * + * @param entt A valid identifier. + * @param elem Optional opaque element to forward to mixins, if any. + * @return Iterator pointing to the emplaced element in case of success, the + * `end()` iterator otherwise. + */ + iterator push(const entity_type entt, const void *elem = nullptr) { + return try_emplace(entt, false, elem); + } + + /** + * @brief Assigns one or more entities to a sparse set. + * + * @warning + * Attempting to assign an entity that already belongs to the sparse set + * results in undefined behavior. + * + * @tparam It Type of input iterator. + * @param first An iterator to the first element of the range of entities. + * @param last An iterator past the last element of the range of entities. + * @return Iterator pointing to the first element inserted in case of + * success, the `end()` iterator otherwise. + */ + template + iterator push(It first, It last) { + auto curr = end(); + + for(; first != last; ++first) { + curr = try_emplace(*first, true); + } + + return curr; + } + + /** + * @brief Bump the version number of an entity. + * + * @warning + * Attempting to bump the version of an entity that doesn't belong to the + * sparse set results in undefined behavior. + * + * @param entt A valid identifier. + * @return The version of the given identifier. + */ + version_type bump(const entity_type entt) { + auto &elem = sparse_ref(entt); + ENTT_ASSERT(entt != null && elem != tombstone, "Cannot set the required version"); + elem = traits_type::combine(traits_type::to_integral(elem), traits_type::to_integral(entt)); + packed[entity_to_pos(elem)] = entt; + return traits_type::to_version(entt); + } + + /** + * @brief Erases an entity from a sparse set. + * + * @warning + * Attempting to erase an entity that doesn't belong to the sparse set + * results in undefined behavior. + * + * @param entt A valid identifier. + */ + void erase(const entity_type entt) { + const auto it = to_iterator(entt); + pop(it, it + 1u); + } + + /** + * @brief Erases entities from a set. + * + * @sa erase + * + * @tparam It Type of input iterator. + * @param first An iterator to the first element of the range of entities. + * @param last An iterator past the last element of the range of entities. + */ + template + void erase(It first, It last) { + if constexpr(std::is_same_v) { + pop(first, last); + } else { + for(; first != last; ++first) { + erase(*first); + } + } + } + + /** + * @brief Removes an entity from a sparse set if it exists. + * @param entt A valid identifier. + * @return True if the entity is actually removed, false otherwise. + */ + bool remove(const entity_type entt) { + return contains(entt) && (erase(entt), true); + } + + /** + * @brief Removes entities from a sparse set if they exist. + * @tparam It Type of input iterator. + * @param first An iterator to the first element of the range of entities. + * @param last An iterator past the last element of the range of entities. + * @return The number of entities actually removed. + */ + template + size_type remove(It first, It last) { + size_type count{}; + + if constexpr(std::is_same_v) { + while(first != last) { + while(first != last && !contains(*first)) { + ++first; + } + + const auto it = first; + + while(first != last && contains(*first)) { + ++first; + } + + count += static_cast(std::distance(it, first)); + erase(it, first); + } + } else { + for(; first != last; ++first) { + count += remove(*first); + } + } + + return count; + } + + /*! @brief Removes all tombstones from a sparse set. */ + void compact() { + if(mode == deletion_policy::in_place) { + size_type from = packed.size(); + size_type pos = std::exchange(head, max_size); + + for(; from && packed[from - 1u] == tombstone; --from) {} + + while(pos != max_size) { + if(const auto to = std::exchange(pos, entity_to_pos(packed[pos])); to < from) { + --from; + swap_or_move(from, to); + + packed[to] = packed[from]; + const auto elem = static_cast(to); + sparse_ref(packed[to]) = traits_type::combine(elem, traits_type::to_integral(packed[to])); + + for(; from && packed[from - 1u] == tombstone; --from) {} + } + } + + packed.erase(packed.begin() + static_cast(from), packed.end()); + } + } + + /** + * @brief Swaps two entities in a sparse set. + * + * For what it's worth, this function affects both the internal sparse array + * and the internal packed array. Users should not care of that anyway. + * + * @warning + * Attempting to swap entities that don't belong to the sparse set results + * in undefined behavior. + * + * @param lhs A valid identifier. + * @param rhs A valid identifier. + */ + void swap_elements(const entity_type lhs, const entity_type rhs) { + const auto from = index(lhs); + const auto to = index(rhs); + + // basic no-leak guarantee if swapping throws + swap_or_move(from, to); + swap_at(from, to); + } + + /** + * @brief Sort the first count elements according to the given comparison + * function. + * + * The comparison function object must return `true` if the first element + * is _less_ than the second one, `false` otherwise. The signature of the + * comparison function should be equivalent to the following: + * + * @code{.cpp} + * bool(const Entity, const Entity); + * @endcode + * + * Moreover, the comparison function object shall induce a + * _strict weak ordering_ on the values. + * + * The sort function object must offer a member function template + * `operator()` that accepts three arguments: + * + * * An iterator to the first element of the range to sort. + * * An iterator past the last element of the range to sort. + * * A comparison function to use to compare the elements. + * + * @tparam Compare Type of comparison function object. + * @tparam Sort Type of sort function object. + * @tparam Args Types of arguments to forward to the sort function object. + * @param length Number of elements to sort. + * @param compare A valid comparison function object. + * @param algo A valid sort function object. + * @param args Arguments to forward to the sort function object, if any. + */ + template + void sort_n(const size_type length, Compare compare, Sort algo = Sort{}, Args &&...args) { + ENTT_ASSERT((mode != deletion_policy::in_place) || (head == max_size), "Sorting with tombstones not allowed"); + ENTT_ASSERT(!(length > packed.size()), "Length exceeds the number of elements"); + + algo(packed.rend() - static_cast(length), packed.rend(), std::move(compare), std::forward(args)...); + + for(size_type pos{}; pos < length; ++pos) { + auto curr = pos; + auto next = index(packed[curr]); + + while(curr != next) { + const auto idx = index(packed[next]); + const auto entt = packed[curr]; + + swap_or_move(next, idx); + const auto elem = static_cast(curr); + sparse_ref(entt) = traits_type::combine(elem, traits_type::to_integral(packed[curr])); + curr = std::exchange(next, idx); + } + } + } + + /** + * @brief Sort all elements according to the given comparison function. + * + * @sa sort_n + * + * @tparam Compare Type of comparison function object. + * @tparam Sort Type of sort function object. + * @tparam Args Types of arguments to forward to the sort function object. + * @param compare A valid comparison function object. + * @param algo A valid sort function object. + * @param args Arguments to forward to the sort function object, if any. + */ + template + void sort(Compare compare, Sort algo = Sort{}, Args &&...args) { + const size_type len = (mode == deletion_policy::swap_only) ? head : packed.size(); + sort_n(len, std::move(compare), std::move(algo), std::forward(args)...); + } + + /** + * @brief Sort entities according to their order in a range. + * + * Entities that are part of both the sparse set and the range are ordered + * internally according to the order they have in the range.
+ * All other entities goes to the end of the sparse set and there are no + * guarantees on their order. + * + * @tparam It Type of input iterator. + * @param first An iterator to the first element of the range of entities. + * @param last An iterator past the last element of the range of entities. + * @return An iterator past the last of the elements actually shared. + */ + template + iterator sort_as(It first, It last) { + ENTT_ASSERT((mode != deletion_policy::in_place) || (head == max_size), "Sorting with tombstones not allowed"); + const size_type len = (mode == deletion_policy::swap_only) ? head : packed.size(); + auto it = end() - static_cast(len); + + for(const auto other = end(); (it != other) && (first != last); ++first) { + if(const auto curr = *first; contains(curr)) { + if(const auto entt = *it; entt != curr) { + // basic no-leak guarantee (with invalid state) if swapping throws + swap_elements(entt, curr); + } + + ++it; + } + } + + return it; + } + + /*! @brief Clears a sparse set. */ + void clear() { + pop_all(); + // sanity check to avoid subtle issues due to storage classes + ENTT_ASSERT((compact(), size()) == 0u, "Non-empty set"); + head = policy_to_head(); + packed.clear(); + } + + /** + * @brief Returns a type info object for the value type, if any. + * @return A type info object for the value type, if any. + */ + [[nodiscard]] const type_info &info() const noexcept { + return *descriptor; + } + + /*! @copydoc info */ + [[deprecated("use ::info instead")]] [[nodiscard]] const type_info &type() const noexcept { + return info(); + } + + /** + * @brief Forwards variables to derived classes, if any. + * @tparam Type Type of the element to forward. + * @param value The element to forward. + */ + template + void bind(Type &&value) noexcept { + bind_any(forward_as_any(std::forward(value))); + } + +private: + sparse_container_type sparse; + packed_container_type packed; + const type_info *descriptor; + deletion_policy mode; + size_type head; +}; + +} // namespace entt + +#endif + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +class storage_iterator final { + friend storage_iterator; + + using container_type = std::remove_const_t; + using alloc_traits = std::allocator_traits; + + using iterator_traits = std::iterator_traits, + typename alloc_traits::template rebind_traits::element_type>::const_pointer, + typename alloc_traits::template rebind_traits::element_type>::pointer>>; + +public: + using value_type = typename iterator_traits::value_type; + using pointer = typename iterator_traits::pointer; + using reference = typename iterator_traits::reference; + using difference_type = typename iterator_traits::difference_type; + using iterator_category = std::random_access_iterator_tag; + + constexpr storage_iterator() noexcept = default; + + constexpr storage_iterator(Container *ref, const difference_type idx) noexcept + : payload{ref}, + offset{idx} {} + + template, typename = std::enable_if_t> + constexpr storage_iterator(const storage_iterator, Page> &other) noexcept + : storage_iterator{other.payload, other.offset} {} + + constexpr storage_iterator &operator++() noexcept { + return --offset, *this; + } + + constexpr storage_iterator operator++(int) noexcept { + const storage_iterator orig = *this; + return ++(*this), orig; + } + + constexpr storage_iterator &operator--() noexcept { + return ++offset, *this; + } + + constexpr storage_iterator operator--(int) noexcept { + const storage_iterator orig = *this; + return operator--(), orig; + } + + constexpr storage_iterator &operator+=(const difference_type value) noexcept { + offset -= value; + return *this; + } + + constexpr storage_iterator operator+(const difference_type value) const noexcept { + storage_iterator copy = *this; + return (copy += value); + } + + constexpr storage_iterator &operator-=(const difference_type value) noexcept { + return (*this += -value); + } + + constexpr storage_iterator operator-(const difference_type value) const noexcept { + return (*this + -value); + } + + [[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept { + const auto pos = static_cast(index() - value); + return (*payload)[pos / Page][fast_mod(static_cast(pos), Page)]; + } + + [[nodiscard]] constexpr pointer operator->() const noexcept { + return std::addressof(operator[](0)); + } + + [[nodiscard]] constexpr reference operator*() const noexcept { + return operator[](0); + } + + [[nodiscard]] constexpr difference_type index() const noexcept { + return offset - 1; + } + +private: + Container *payload; + difference_type offset; +}; + +template +[[nodiscard]] constexpr std::ptrdiff_t operator-(const storage_iterator &lhs, const storage_iterator &rhs) noexcept { + return rhs.index() - lhs.index(); +} + +template +[[nodiscard]] constexpr bool operator==(const storage_iterator &lhs, const storage_iterator &rhs) noexcept { + return lhs.index() == rhs.index(); +} + +template +[[nodiscard]] constexpr bool operator!=(const storage_iterator &lhs, const storage_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +template +[[nodiscard]] constexpr bool operator<(const storage_iterator &lhs, const storage_iterator &rhs) noexcept { + return lhs.index() > rhs.index(); +} + +template +[[nodiscard]] constexpr bool operator>(const storage_iterator &lhs, const storage_iterator &rhs) noexcept { + return rhs < lhs; +} + +template +[[nodiscard]] constexpr bool operator<=(const storage_iterator &lhs, const storage_iterator &rhs) noexcept { + return !(lhs > rhs); +} + +template +[[nodiscard]] constexpr bool operator>=(const storage_iterator &lhs, const storage_iterator &rhs) noexcept { + return !(lhs < rhs); +} + +template +class extended_storage_iterator final { + template + friend class extended_storage_iterator; + +public: + using iterator_type = It; + using value_type = decltype(std::tuple_cat(std::make_tuple(*std::declval()), std::forward_as_tuple(*std::declval()...))); + using pointer = input_iterator_pointer; + using reference = value_type; + using difference_type = std::ptrdiff_t; + using iterator_category = std::input_iterator_tag; + using iterator_concept = std::forward_iterator_tag; + + constexpr extended_storage_iterator() + : it{} {} + + constexpr extended_storage_iterator(iterator_type base, Other... other) + : it{base, other...} {} + + template && ...) && (std::is_constructible_v && ...)>> + constexpr extended_storage_iterator(const extended_storage_iterator &other) + : it{other.it} {} + + constexpr extended_storage_iterator &operator++() noexcept { + return ++std::get(it), (++std::get(it), ...), *this; + } + + constexpr extended_storage_iterator operator++(int) noexcept { + const extended_storage_iterator orig = *this; + return ++(*this), orig; + } + + [[nodiscard]] constexpr pointer operator->() const noexcept { + return operator*(); + } + + [[nodiscard]] constexpr reference operator*() const noexcept { + return {*std::get(it), *std::get(it)...}; + } + + [[nodiscard]] constexpr iterator_type base() const noexcept { + return std::get(it); + } + + template + friend constexpr bool operator==(const extended_storage_iterator &, const extended_storage_iterator &) noexcept; + +private: + std::tuple it; +}; + +template +[[nodiscard]] constexpr bool operator==(const extended_storage_iterator &lhs, const extended_storage_iterator &rhs) noexcept { + return std::get<0>(lhs.it) == std::get<0>(rhs.it); +} + +template +[[nodiscard]] constexpr bool operator!=(const extended_storage_iterator &lhs, const extended_storage_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Storage implementation. + * + * Internal data structures arrange elements to maximize performance. There are + * no guarantees that objects are returned in the insertion order when iterate + * a storage. Do not make assumption on the order in any case. + * + * @warning + * Empty types aren't explicitly instantiated. Therefore, many of the functions + * normally available for non-empty types will not be available for empty ones. + * + * @tparam Type Element type. + * @tparam Entity A valid entity type. + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +class basic_storage: public basic_sparse_set::template rebind_alloc> { + using alloc_traits = std::allocator_traits; + static_assert(std::is_same_v, "Invalid value type"); + using container_type = std::vector>; + using underlying_type = basic_sparse_set>; + using underlying_iterator = typename underlying_type::basic_iterator; + using traits_type = component_traits; + + [[nodiscard]] auto &element_at(const std::size_t pos) const { + return payload[pos / traits_type::page_size][fast_mod(pos, traits_type::page_size)]; + } + + auto assure_at_least(const std::size_t pos) { + const auto idx = pos / traits_type::page_size; + + if(!(idx < payload.size())) { + auto curr = payload.size(); + allocator_type allocator{get_allocator()}; + payload.resize(idx + 1u, nullptr); + + ENTT_TRY { + for(const auto last = payload.size(); curr < last; ++curr) { + payload[curr] = alloc_traits::allocate(allocator, traits_type::page_size); + } + } + ENTT_CATCH { + payload.resize(curr); + ENTT_THROW; + } + } + + return payload[idx] + fast_mod(pos, traits_type::page_size); + } + + template + auto emplace_element(const Entity entt, const bool force_back, Args &&...args) { + const auto it = base_type::try_emplace(entt, force_back); + + ENTT_TRY { + auto *elem = to_address(assure_at_least(static_cast(it.index()))); + entt::uninitialized_construct_using_allocator(elem, get_allocator(), std::forward(args)...); + } + ENTT_CATCH { + base_type::pop(it, it + 1u); + ENTT_THROW; + } + + return it; + } + + void shrink_to_size(const std::size_t sz) { + const auto from = (sz + traits_type::page_size - 1u) / traits_type::page_size; + allocator_type allocator{get_allocator()}; + + for(auto pos = sz, length = base_type::size(); pos < length; ++pos) { + if constexpr(traits_type::in_place_delete) { + if(base_type::data()[pos] != tombstone) { + alloc_traits::destroy(allocator, std::addressof(element_at(pos))); + } + } else { + alloc_traits::destroy(allocator, std::addressof(element_at(pos))); + } + } + + for(auto pos = from, last = payload.size(); pos < last; ++pos) { + alloc_traits::deallocate(allocator, payload[pos], traits_type::page_size); + } + + payload.resize(from); + payload.shrink_to_fit(); + } + + void swap_at(const std::size_t lhs, const std::size_t rhs) { + using std::swap; + swap(element_at(lhs), element_at(rhs)); + } + + void move_to(const std::size_t lhs, const std::size_t rhs) { + auto &elem = element_at(lhs); + allocator_type allocator{get_allocator()}; + entt::uninitialized_construct_using_allocator(to_address(assure_at_least(rhs)), allocator, std::move(elem)); + alloc_traits::destroy(allocator, std::addressof(elem)); + } + +private: + [[nodiscard]] const void *get_at(const std::size_t pos) const final { + return std::addressof(element_at(pos)); + } + + void swap_or_move([[maybe_unused]] const std::size_t from, [[maybe_unused]] const std::size_t to) override { + static constexpr bool is_pinned_type = !(std::is_move_constructible_v && std::is_move_assignable_v); + // use a runtime value to avoid compile-time suppression that drives the code coverage tool crazy + ENTT_ASSERT((from + 1u) && !is_pinned_type, "Pinned type"); + + if constexpr(!is_pinned_type) { + if constexpr(traits_type::in_place_delete) { + (base_type::operator[](to) == tombstone) ? move_to(from, to) : swap_at(from, to); + } else { + swap_at(from, to); + } + } + } + +protected: + /** + * @brief Erases entities from a storage. + * @param first An iterator to the first element of the range of entities. + * @param last An iterator past the last element of the range of entities. + */ + void pop(underlying_iterator first, underlying_iterator last) override { + for(allocator_type allocator{get_allocator()}; first != last; ++first) { + // cannot use first.index() because it would break with cross iterators + auto &elem = element_at(base_type::index(*first)); + + if constexpr(traits_type::in_place_delete) { + base_type::in_place_pop(first); + alloc_traits::destroy(allocator, std::addressof(elem)); + } else { + auto &other = element_at(base_type::size() - 1u); + // destroying on exit allows reentrant destructors + [[maybe_unused]] auto unused = std::exchange(elem, std::move(other)); + alloc_traits::destroy(allocator, std::addressof(other)); + base_type::swap_and_pop(first); + } + } + } + + /*! @brief Erases all entities of a storage. */ + void pop_all() override { + allocator_type allocator{get_allocator()}; + + for(auto first = base_type::begin(); !(first.index() < 0); ++first) { + if constexpr(traits_type::in_place_delete) { + if(*first != tombstone) { + base_type::in_place_pop(first); + alloc_traits::destroy(allocator, std::addressof(element_at(static_cast(first.index())))); + } + } else { + base_type::swap_and_pop(first); + alloc_traits::destroy(allocator, std::addressof(element_at(static_cast(first.index())))); + } + } + } + + /** + * @brief Assigns an entity to a storage. + * @param entt A valid identifier. + * @param value Optional opaque value. + * @param force_back Force back insertion. + * @return Iterator pointing to the emplaced element. + */ + underlying_iterator try_emplace([[maybe_unused]] const Entity entt, [[maybe_unused]] const bool force_back, const void *value) override { + if(value != nullptr) { + if constexpr(std::is_copy_constructible_v) { + return emplace_element(entt, force_back, *static_cast(value)); + } else { + return base_type::end(); + } + } else { + if constexpr(std::is_default_constructible_v) { + return emplace_element(entt, force_back); + } else { + return base_type::end(); + } + } + } + +public: + /*! @brief Allocator type. */ + using allocator_type = Allocator; + /*! @brief Base type. */ + using base_type = underlying_type; + /*! @brief Element type. */ + using element_type = Type; + /*! @brief Type of the objects assigned to entities. */ + using value_type = element_type; + /*! @brief Underlying entity identifier. */ + using entity_type = Entity; + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + /*! @brief Signed integer type. */ + using difference_type = std::ptrdiff_t; + /*! @brief Pointer type to contained elements. */ + using pointer = typename container_type::pointer; + /*! @brief Constant pointer type to contained elements. */ + using const_pointer = typename alloc_traits::template rebind_traits::const_pointer; + /*! @brief Random access iterator type. */ + using iterator = internal::storage_iterator; + /*! @brief Constant random access iterator type. */ + using const_iterator = internal::storage_iterator; + /*! @brief Reverse iterator type. */ + using reverse_iterator = std::reverse_iterator; + /*! @brief Constant reverse iterator type. */ + using const_reverse_iterator = std::reverse_iterator; + /*! @brief Extended iterable storage proxy. */ + using iterable = iterable_adaptor>; + /*! @brief Constant extended iterable storage proxy. */ + using const_iterable = iterable_adaptor>; + /*! @brief Extended reverse iterable storage proxy. */ + using reverse_iterable = iterable_adaptor>; + /*! @brief Constant extended reverse iterable storage proxy. */ + using const_reverse_iterable = iterable_adaptor>; + /*! @brief Storage deletion policy. */ + static constexpr deletion_policy storage_policy{traits_type::in_place_delete}; + + /*! @brief Default constructor. */ + basic_storage() + : basic_storage{allocator_type{}} {} + + /** + * @brief Constructs an empty storage with a given allocator. + * @param allocator The allocator to use. + */ + explicit basic_storage(const allocator_type &allocator) + : base_type{type_id(), storage_policy, allocator}, + payload{allocator} {} + + /*! @brief Default copy constructor, deleted on purpose. */ + basic_storage(const basic_storage &) = delete; + + /** + * @brief Move constructor. + * @param other The instance to move from. + */ + basic_storage(basic_storage &&other) noexcept + : base_type{static_cast(other)}, + payload{std::move(other.payload)} {} + + /** + * @brief Allocator-extended move constructor. + * @param other The instance to move from. + * @param allocator The allocator to use. + */ + basic_storage(basic_storage &&other, const allocator_type &allocator) + : base_type{static_cast(other), allocator}, + payload{std::move(other.payload), allocator} { + ENTT_ASSERT(alloc_traits::is_always_equal::value || get_allocator() == other.get_allocator(), "Copying a storage is not allowed"); + } + + /*! @brief Default destructor. */ + // NOLINTNEXTLINE(bugprone-exception-escape) + ~basic_storage() override { + shrink_to_size(0u); + } + + /** + * @brief Default copy assignment operator, deleted on purpose. + * @return This storage. + */ + basic_storage &operator=(const basic_storage &) = delete; + + /** + * @brief Move assignment operator. + * @param other The instance to move from. + * @return This storage. + */ + basic_storage &operator=(basic_storage &&other) noexcept { + ENTT_ASSERT(alloc_traits::is_always_equal::value || get_allocator() == other.get_allocator(), "Copying a storage is not allowed"); + swap(other); + return *this; + } + + /** + * @brief Exchanges the contents with those of a given storage. + * @param other Storage to exchange the content with. + */ + void swap(basic_storage &other) noexcept { + using std::swap; + swap(payload, other.payload); + base_type::swap(other); + } + + /** + * @brief Returns the associated allocator. + * @return The associated allocator. + */ + [[nodiscard]] constexpr allocator_type get_allocator() const noexcept { + return payload.get_allocator(); + } + + /** + * @brief Increases the capacity of a storage. + * + * If the new capacity is greater than the current capacity, new storage is + * allocated, otherwise the method does nothing. + * + * @param cap Desired capacity. + */ + void reserve(const size_type cap) override { + if(cap != 0u) { + base_type::reserve(cap); + assure_at_least(cap - 1u); + } + } + + /** + * @brief Returns the number of elements that a storage has currently + * allocated space for. + * @return Capacity of the storage. + */ + [[nodiscard]] size_type capacity() const noexcept override { + return payload.size() * traits_type::page_size; + } + + /*! @brief Requests the removal of unused capacity. */ + void shrink_to_fit() override { + base_type::shrink_to_fit(); + shrink_to_size(base_type::size()); + } + + /** + * @brief Direct access to the array of objects. + * @return A pointer to the array of objects. + */ + [[nodiscard]] const_pointer raw() const noexcept { + return payload.data(); + } + + /*! @copydoc raw */ + [[nodiscard]] pointer raw() noexcept { + return payload.data(); + } + + /** + * @brief Returns an iterator to the beginning. + * + * If the storage is empty, the returned iterator will be equal to `end()`. + * + * @return An iterator to the first instance of the internal array. + */ + [[nodiscard]] const_iterator cbegin() const noexcept { + const auto pos = static_cast(base_type::size()); + return const_iterator{&payload, pos}; + } + + /*! @copydoc cbegin */ + [[nodiscard]] const_iterator begin() const noexcept { + return cbegin(); + } + + /*! @copydoc begin */ + [[nodiscard]] iterator begin() noexcept { + const auto pos = static_cast(base_type::size()); + return iterator{&payload, pos}; + } + + /** + * @brief Returns an iterator to the end. + * @return An iterator to the element following the last instance of the + * internal array. + */ + [[nodiscard]] const_iterator cend() const noexcept { + return const_iterator{&payload, {}}; + } + + /*! @copydoc cend */ + [[nodiscard]] const_iterator end() const noexcept { + return cend(); + } + + /*! @copydoc end */ + [[nodiscard]] iterator end() noexcept { + return iterator{&payload, {}}; + } + + /** + * @brief Returns a reverse iterator to the beginning. + * + * If the storage is empty, the returned iterator will be equal to `rend()`. + * + * @return An iterator to the first instance of the reversed internal array. + */ + [[nodiscard]] const_reverse_iterator crbegin() const noexcept { + return std::make_reverse_iterator(cend()); + } + + /*! @copydoc crbegin */ + [[nodiscard]] const_reverse_iterator rbegin() const noexcept { + return crbegin(); + } + + /*! @copydoc rbegin */ + [[nodiscard]] reverse_iterator rbegin() noexcept { + return std::make_reverse_iterator(end()); + } + + /** + * @brief Returns a reverse iterator to the end. + * @return An iterator to the element following the last instance of the + * reversed internal array. + */ + [[nodiscard]] const_reverse_iterator crend() const noexcept { + return std::make_reverse_iterator(cbegin()); + } + + /*! @copydoc crend */ + [[nodiscard]] const_reverse_iterator rend() const noexcept { + return crend(); + } + + /*! @copydoc rend */ + [[nodiscard]] reverse_iterator rend() noexcept { + return std::make_reverse_iterator(begin()); + } + + /** + * @brief Returns the object assigned to an entity. + * + * @warning + * Attempting to use an entity that doesn't belong to the storage results in + * undefined behavior. + * + * @param entt A valid identifier. + * @return The object assigned to the entity. + */ + [[nodiscard]] const value_type &get(const entity_type entt) const noexcept { + return element_at(base_type::index(entt)); + } + + /*! @copydoc get */ + [[nodiscard]] value_type &get(const entity_type entt) noexcept { + return const_cast(std::as_const(*this).get(entt)); + } + + /** + * @brief Returns the object assigned to an entity as a tuple. + * @param entt A valid identifier. + * @return The object assigned to the entity as a tuple. + */ + [[nodiscard]] std::tuple get_as_tuple(const entity_type entt) const noexcept { + return std::forward_as_tuple(get(entt)); + } + + /*! @copydoc get_as_tuple */ + [[nodiscard]] std::tuple get_as_tuple(const entity_type entt) noexcept { + return std::forward_as_tuple(get(entt)); + } + + /** + * @brief Assigns an entity to a storage and constructs its object. + * + * @warning + * Attempting to use an entity that already belongs to the storage results + * in undefined behavior. + * + * @tparam Args Types of arguments to use to construct the object. + * @param entt A valid identifier. + * @param args Parameters to use to construct an object for the entity. + * @return A reference to the newly created object. + */ + template + value_type &emplace(const entity_type entt, Args &&...args) { + if constexpr(std::is_aggregate_v && (sizeof...(Args) != 0u || !std::is_default_constructible_v)) { + const auto it = emplace_element(entt, false, Type{std::forward(args)...}); + return element_at(static_cast(it.index())); + } else { + const auto it = emplace_element(entt, false, std::forward(args)...); + return element_at(static_cast(it.index())); + } + } + + /** + * @brief Updates the instance assigned to a given entity in-place. + * @tparam Func Types of the function objects to invoke. + * @param entt A valid identifier. + * @param func Valid function objects. + * @return A reference to the updated instance. + */ + template + value_type &patch(const entity_type entt, Func &&...func) { + const auto idx = base_type::index(entt); + auto &elem = element_at(idx); + (std::forward(func)(elem), ...); + return elem; + } + + /** + * @brief Assigns one or more entities to a storage and constructs their + * objects from a given instance. + * + * @warning + * Attempting to assign an entity that already belongs to the storage + * results in undefined behavior. + * + * @tparam It Type of input iterator. + * @param first An iterator to the first element of the range of entities. + * @param last An iterator past the last element of the range of entities. + * @param value An instance of the object to construct. + * @return Iterator pointing to the first element inserted, if any. + */ + template + iterator insert(It first, It last, const value_type &value = {}) { + for(; first != last; ++first) { + emplace_element(*first, true, value); + } + + return begin(); + } + + /** + * @brief Assigns one or more entities to a storage and constructs their + * objects from a given range. + * + * @sa construct + * + * @tparam EIt Type of input iterator. + * @tparam CIt Type of input iterator. + * @param first An iterator to the first element of the range of entities. + * @param last An iterator past the last element of the range of entities. + * @param from An iterator to the first element of the range of objects. + * @return Iterator pointing to the first element inserted, if any. + */ + template::value_type, value_type>>> + iterator insert(EIt first, EIt last, CIt from) { + for(; first != last; ++first, ++from) { + emplace_element(*first, true, *from); + } + + return begin(); + } + + /** + * @brief Returns an iterable object to use to _visit_ a storage. + * + * The iterable object returns a tuple that contains the current entity and + * a reference to its element. + * + * @return An iterable object to use to _visit_ the storage. + */ + [[nodiscard]] iterable each() noexcept { + return iterable{{base_type::begin(), begin()}, {base_type::end(), end()}}; + } + + /*! @copydoc each */ + [[nodiscard]] const_iterable each() const noexcept { + return const_iterable{{base_type::cbegin(), cbegin()}, {base_type::cend(), cend()}}; + } + + /** + * @brief Returns a reverse iterable object to use to _visit_ a storage. + * + * @sa each + * + * @return A reverse iterable object to use to _visit_ the storage. + */ + [[nodiscard]] reverse_iterable reach() noexcept { + return reverse_iterable{{base_type::rbegin(), rbegin()}, {base_type::rend(), rend()}}; + } + + /*! @copydoc reach */ + [[nodiscard]] const_reverse_iterable reach() const noexcept { + return const_reverse_iterable{{base_type::crbegin(), crbegin()}, {base_type::crend(), crend()}}; + } + +private: + container_type payload; +}; + +/*! @copydoc basic_storage */ +template +class basic_storage::page_size == 0u>> + : public basic_sparse_set::template rebind_alloc> { + using alloc_traits = std::allocator_traits; + static_assert(std::is_same_v, "Invalid value type"); + using traits_type = component_traits; + +public: + /*! @brief Allocator type. */ + using allocator_type = Allocator; + /*! @brief Base type. */ + using base_type = basic_sparse_set>; + /*! @brief Element type. */ + using element_type = Type; + /*! @brief Type of the objects assigned to entities. */ + using value_type = void; + /*! @brief Underlying entity identifier. */ + using entity_type = Entity; + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + /*! @brief Signed integer type. */ + using difference_type = std::ptrdiff_t; + /*! @brief Extended iterable storage proxy. */ + using iterable = iterable_adaptor>; + /*! @brief Constant extended iterable storage proxy. */ + using const_iterable = iterable_adaptor>; + /*! @brief Extended reverse iterable storage proxy. */ + using reverse_iterable = iterable_adaptor>; + /*! @brief Constant extended reverse iterable storage proxy. */ + using const_reverse_iterable = iterable_adaptor>; + /*! @brief Storage deletion policy. */ + static constexpr deletion_policy storage_policy{traits_type::in_place_delete}; + + /*! @brief Default constructor. */ + basic_storage() + : basic_storage{allocator_type{}} {} + + /** + * @brief Constructs an empty container with a given allocator. + * @param allocator The allocator to use. + */ + explicit basic_storage(const allocator_type &allocator) + : base_type{type_id(), storage_policy, allocator} {} + + /*! @brief Default copy constructor, deleted on purpose. */ + basic_storage(const basic_storage &) = delete; + + /** + * @brief Move constructor. + * @param other The instance to move from. + */ + basic_storage(basic_storage &&other) noexcept = default; + + /** + * @brief Allocator-extended move constructor. + * @param other The instance to move from. + * @param allocator The allocator to use. + */ + basic_storage(basic_storage &&other, const allocator_type &allocator) + : base_type{std::move(other), allocator} {} + + /*! @brief Default destructor. */ + ~basic_storage() override = default; + + /** + * @brief Default copy assignment operator, deleted on purpose. + * @return This storage. + */ + basic_storage &operator=(const basic_storage &) = delete; + + /** + * @brief Move assignment operator. + * @param other The instance to move from. + * @return This storage. + */ + basic_storage &operator=(basic_storage &&other) noexcept = default; + + /** + * @brief Returns the associated allocator. + * @return The associated allocator. + */ + [[nodiscard]] constexpr allocator_type get_allocator() const noexcept { + // std::allocator has no cross constructors (waiting for C++20) + if constexpr(std::is_void_v && !std::is_constructible_v) { + return allocator_type{}; + } else { + return allocator_type{base_type::get_allocator()}; + } + } + + /** + * @brief Returns the object assigned to an entity, that is `void`. + * + * @warning + * Attempting to use an entity that doesn't belong to the storage results in + * undefined behavior. + * + * @param entt A valid identifier. + */ + void get([[maybe_unused]] const entity_type entt) const noexcept { + ENTT_ASSERT(base_type::contains(entt), "Invalid entity"); + } + + /** + * @brief Returns an empty tuple. + * @param entt A valid identifier. + * @return Returns an empty tuple. + */ + [[nodiscard]] std::tuple<> get_as_tuple([[maybe_unused]] const entity_type entt) const noexcept { + ENTT_ASSERT(base_type::contains(entt), "Invalid entity"); + return std::tuple{}; + } + + /** + * @brief Assigns an entity to a storage and constructs its object. + * + * @warning + * Attempting to use an entity that already belongs to the storage results + * in undefined behavior. + * + * @param entt A valid identifier. + */ + void emplace(const entity_type entt) { + base_type::try_emplace(entt, false); + } + + /** + * @brief Updates the instance assigned to a given entity in-place. + * @tparam Func Types of the function objects to invoke. + * @param entt A valid identifier. + * @param func Valid function objects. + */ + template + void patch([[maybe_unused]] const entity_type entt, Func &&...func) { + ENTT_ASSERT(base_type::contains(entt), "Invalid entity"); + (std::forward(func)(), ...); + } + + /** + * @brief Assigns entities to a storage. + * @tparam It Type of input iterator. + * @param first An iterator to the first element of the range of entities. + * @param last An iterator past the last element of the range of entities. + */ + template + void insert(It first, It last) { + for(; first != last; ++first) { + base_type::try_emplace(*first, true); + } + } + + /** + * @brief Returns an iterable object to use to _visit_ a storage. + * + * The iterable object returns a tuple that contains the current entity. + * + * @return An iterable object to use to _visit_ the storage. + */ + [[nodiscard]] iterable each() noexcept { + return iterable{base_type::begin(), base_type::end()}; + } + + /*! @copydoc each */ + [[nodiscard]] const_iterable each() const noexcept { + return const_iterable{base_type::cbegin(), base_type::cend()}; + } + + /** + * @brief Returns a reverse iterable object to use to _visit_ a storage. + * + * @sa each + * + * @return A reverse iterable object to use to _visit_ the storage. + */ + [[nodiscard]] reverse_iterable reach() noexcept { + return reverse_iterable{{base_type::rbegin()}, {base_type::rend()}}; + } + + /*! @copydoc reach */ + [[nodiscard]] const_reverse_iterable reach() const noexcept { + return const_reverse_iterable{{base_type::crbegin()}, {base_type::crend()}}; + } +}; + +/** + * @brief Swap-only entity storage specialization. + * @tparam Entity A valid entity type. + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +class basic_storage + : public basic_sparse_set { + using alloc_traits = std::allocator_traits; + static_assert(std::is_same_v, "Invalid value type"); + using underlying_iterator = typename basic_sparse_set::basic_iterator; + using traits_type = entt_traits; + + auto from_placeholder() noexcept { + const auto entt = traits_type::combine(static_cast(placeholder), {}); + ENTT_ASSERT(entt != null, "No more entities available"); + placeholder += static_cast(entt != null); + return entt; + } + + auto next() noexcept { + entity_type entt = from_placeholder(); + + while(base_type::current(entt) != traits_type::to_version(tombstone) && entt != null) { + entt = from_placeholder(); + } + + return entt; + } + +protected: + /*! @brief Erases all entities of a storage. */ + void pop_all() override { + base_type::pop_all(); + placeholder = {}; + } + + /** + * @brief Assigns an entity to a storage. + * @param hint A valid identifier. + * @return Iterator pointing to the emplaced element. + */ + underlying_iterator try_emplace(const Entity hint, const bool, const void *) override { + return base_type::find(generate(hint)); + } + +public: + /*! @brief Allocator type. */ + using allocator_type = Allocator; + /*! @brief Base type. */ + using base_type = basic_sparse_set; + /*! @brief Element type. */ + using element_type = Entity; + /*! @brief Type of the objects assigned to entities. */ + using value_type = void; + /*! @brief Underlying entity identifier. */ + using entity_type = Entity; + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + /*! @brief Signed integer type. */ + using difference_type = std::ptrdiff_t; + /*! @brief Extended iterable storage proxy. */ + using iterable = iterable_adaptor>; + /*! @brief Constant extended iterable storage proxy. */ + using const_iterable = iterable_adaptor>; + /*! @brief Extended reverse iterable storage proxy. */ + using reverse_iterable = iterable_adaptor>; + /*! @brief Constant extended reverse iterable storage proxy. */ + using const_reverse_iterable = iterable_adaptor>; + /*! @brief Storage deletion policy. */ + static constexpr deletion_policy storage_policy = deletion_policy::swap_only; + + /*! @brief Default constructor. */ + basic_storage() + : basic_storage{allocator_type{}} { + } + + /** + * @brief Constructs an empty container with a given allocator. + * @param allocator The allocator to use. + */ + explicit basic_storage(const allocator_type &allocator) + : base_type{type_id(), storage_policy, allocator} {} + + /*! @brief Default copy constructor, deleted on purpose. */ + basic_storage(const basic_storage &) = delete; + + /** + * @brief Move constructor. + * @param other The instance to move from. + */ + // NOLINTNEXTLINE(cppcoreguidelines-rvalue-reference-param-not-moved) + basic_storage(basic_storage &&other) noexcept + : base_type{static_cast(other)}, + placeholder{other.placeholder} {} + + /** + * @brief Allocator-extended move constructor. + * @param other The instance to move from. + * @param allocator The allocator to use. + */ + // NOLINTNEXTLINE(cppcoreguidelines-rvalue-reference-param-not-moved) + basic_storage(basic_storage &&other, const allocator_type &allocator) + : base_type{static_cast(other), allocator}, + placeholder{other.placeholder} {} + + /*! @brief Default destructor. */ + ~basic_storage() override = default; + + /** + * @brief Default copy assignment operator, deleted on purpose. + * @return This storage. + */ + basic_storage &operator=(const basic_storage &) = delete; + + /** + * @brief Move assignment operator. + * @param other The instance to move from. + * @return This storage. + */ + basic_storage &operator=(basic_storage &&other) noexcept { + placeholder = other.placeholder; + base_type::operator=(std::move(other)); + return *this; + } + + /** + * @brief Exchanges the contents with those of a given storage. + * @param other Storage to exchange the content with. + */ + void swap(basic_storage &other) noexcept { + using std::swap; + swap(placeholder, other.placeholder); + base_type::swap(other); + } + + /** + * @brief Returns the object assigned to an entity, that is `void`. + * + * @warning + * Attempting to use an entity that doesn't belong to the storage results in + * undefined behavior. + * + * @param entt A valid identifier. + */ + void get([[maybe_unused]] const entity_type entt) const noexcept { + ENTT_ASSERT(base_type::index(entt) < base_type::free_list(), "The requested entity is not a live one"); + } + + /** + * @brief Returns an empty tuple. + * @param entt A valid identifier. + * @return Returns an empty tuple. + */ + [[nodiscard]] std::tuple<> get_as_tuple([[maybe_unused]] const entity_type entt) const noexcept { + ENTT_ASSERT(base_type::index(entt) < base_type::free_list(), "The requested entity is not a live one"); + return std::tuple{}; + } + + /** + * @brief Creates a new identifier or recycles a destroyed one. + * @return A valid identifier. + */ + entity_type generate() { + const auto len = base_type::free_list(); + const auto entt = (len == base_type::size()) ? next() : base_type::data()[len]; + return *base_type::try_emplace(entt, true); + } + + /** + * @brief Creates a new identifier or recycles a destroyed one. + * + * If the requested identifier isn't in use, the suggested one is used. + * Otherwise, a new identifier is returned. + * + * @param hint Required identifier. + * @return A valid identifier. + */ + entity_type generate(const entity_type hint) { + if(hint != null && hint != tombstone) { + if(const auto curr = traits_type::construct(traits_type::to_entity(hint), base_type::current(hint)); curr == tombstone || !(base_type::index(curr) < base_type::free_list())) { + return *base_type::try_emplace(hint, true); + } + } + + return generate(); + } + + /** + * @brief Assigns each element in a range an identifier. + * @tparam It Type of mutable forward iterator. + * @param first An iterator to the first element of the range to generate. + * @param last An iterator past the last element of the range to generate. + */ + template + void generate(It first, It last) { + for(const auto sz = base_type::size(); first != last && base_type::free_list() != sz; ++first) { + *first = *base_type::try_emplace(base_type::data()[base_type::free_list()], true); + } + + for(; first != last; ++first) { + *first = *base_type::try_emplace(next(), true); + } + } + + /** + * @brief Updates a given identifier. + * @tparam Func Types of the function objects to invoke. + * @param entt A valid identifier. + * @param func Valid function objects. + */ + template + void patch([[maybe_unused]] const entity_type entt, Func &&...func) { + ENTT_ASSERT(base_type::index(entt) < base_type::free_list(), "The requested entity is not a live one"); + (std::forward(func)(), ...); + } + + /** + * @brief Returns an iterable object to use to _visit_ a storage. + * + * The iterable object returns a tuple that contains the current entity. + * + * @return An iterable object to use to _visit_ the storage. + */ + [[nodiscard]] iterable each() noexcept { + return std::as_const(*this).each(); + } + + /*! @copydoc each */ + [[nodiscard]] const_iterable each() const noexcept { + const auto it = base_type::cend(); + const auto offset = static_cast(base_type::free_list()); + return const_iterable{it - offset, it}; + } + + /** + * @brief Returns a reverse iterable object to use to _visit_ a storage. + * + * @sa each + * + * @return A reverse iterable object to use to _visit_ the storage. + */ + [[nodiscard]] reverse_iterable reach() noexcept { + return std::as_const(*this).reach(); + } + + /*! @copydoc reach */ + [[nodiscard]] const_reverse_iterable reach() const noexcept { + const auto it = base_type::crbegin(); + const auto offset = static_cast(base_type::free_list()); + return const_reverse_iterable{it, it + offset}; + } + + /** + * @brief Sets the starting identifier for generation. + * + * The version is ignored, regardless of the value. + * + * @param hint A valid identifier. + */ + void start_from(const entity_type hint) { + placeholder = static_cast(traits_type::to_entity(hint)); + } + +private: + size_type placeholder{}; +}; + +} // namespace entt + +#endif + +// #include "view.hpp" +#ifndef ENTT_ENTITY_VIEW_HPP +#define ENTT_ENTITY_VIEW_HPP + +#include +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "../core/iterator.hpp" + +// #include "../core/type_traits.hpp" + +// #include "entity.hpp" + +// #include "fwd.hpp" + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +// NOLINTNEXTLINE(misc-redundant-expression) +static constexpr bool tombstone_check_v = ((sizeof...(Type) == 1u) && ... && (Type::storage_policy == deletion_policy::in_place)); + +template +const Type *view_placeholder() { + static_assert(std::is_same_v>, Type>, "Unexpected type"); + static const Type placeholder{}; + return &placeholder; +} + +template +[[nodiscard]] bool all_of(It first, const It last, const Entity entt) noexcept { + for(; (first != last) && (*first)->contains(entt); ++first) {} + return first == last; +} + +template +[[nodiscard]] bool none_of(It first, const It last, const Entity entt) noexcept { + for(; (first != last) && !(*first)->contains(entt); ++first) {} + return first == last; +} + +template +[[nodiscard]] bool fully_initialized(It first, const It last, const std::remove_pointer_t::value_type> *placeholder) noexcept { + for(; (first != last) && *first != placeholder; ++first) {} + return first == last; +} + +template +[[nodiscard]] Result view_pack(const View &view, const Other &other, std::index_sequence, std::index_sequence, std::index_sequence, std::index_sequence) { + Result elem{}; + // friend-initialization, avoid multiple calls to refresh + elem.pools = {view.template storage()..., other.template storage()...}; + auto filter_or_placeholder = [placeholder = elem.placeholder](auto *value) { return (value == nullptr) ? placeholder : value; }; + elem.filter = {filter_or_placeholder(view.template storage())..., filter_or_placeholder(other.template storage())...}; + elem.refresh(); + return elem; +} + +template +class view_iterator final { + template + friend class extended_view_iterator; + + using iterator_type = typename Type::const_iterator; + using iterator_traits = std::iterator_traits; + + [[nodiscard]] bool valid(const typename iterator_traits::value_type entt) const noexcept { + return (!Checked || (entt != tombstone)) + && ((Get == 1u) || (internal::all_of(pools.begin(), pools.begin() + index, entt) && internal::all_of(pools.begin() + index + 1, pools.end(), entt))) + && ((Exclude == 0u) || internal::none_of(filter.begin(), filter.end(), entt)); + } + + void seek_next() { + for(constexpr iterator_type sentinel{}; it != sentinel && !valid(*it); ++it) {} + } + +public: + using value_type = typename iterator_traits::value_type; + using pointer = typename iterator_traits::pointer; + using reference = typename iterator_traits::reference; + using difference_type = typename iterator_traits::difference_type; + using iterator_category = std::forward_iterator_tag; + + constexpr view_iterator() noexcept + : it{}, + pools{}, + filter{}, + index{} {} + + view_iterator(iterator_type first, std::array value, std::array excl, const std::size_t idx) noexcept + : it{first}, + pools{value}, + filter{excl}, + index{static_cast(idx)} { + ENTT_ASSERT((Get != 1u) || (Exclude != 0u) || pools[0u]->policy() == deletion_policy::in_place, "Non in-place storage view iterator"); + seek_next(); + } + + view_iterator &operator++() noexcept { + ++it; + seek_next(); + return *this; + } + + view_iterator operator++(int) noexcept { + const view_iterator orig = *this; + return ++(*this), orig; + } + + [[nodiscard]] pointer operator->() const noexcept { + return &*it; + } + + [[nodiscard]] reference operator*() const noexcept { + return *operator->(); + } + + template + friend constexpr bool operator==(const view_iterator &, const view_iterator &) noexcept; + +private: + iterator_type it; + std::array pools; + std::array filter; + difference_type index; +}; + +template +[[nodiscard]] constexpr bool operator==(const view_iterator &lhs, const view_iterator &rhs) noexcept { + return lhs.it == rhs.it; +} + +template +[[nodiscard]] constexpr bool operator!=(const view_iterator &lhs, const view_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +template +class extended_view_iterator final { + template + [[nodiscard]] auto dereference(std::index_sequence) const noexcept { + return std::tuple_cat(std::make_tuple(*it), static_cast(const_cast *>(std::get(it.pools)))->get_as_tuple(*it)...); + } + +public: + using iterator_type = It; + using value_type = decltype(std::tuple_cat(std::make_tuple(*std::declval()), std::declval().get_as_tuple({})...)); + using pointer = input_iterator_pointer; + using reference = value_type; + using difference_type = std::ptrdiff_t; + using iterator_category = std::input_iterator_tag; + using iterator_concept = std::forward_iterator_tag; + + constexpr extended_view_iterator() + : it{} {} + + extended_view_iterator(iterator_type from) + : it{from} {} + + extended_view_iterator &operator++() noexcept { + return ++it, *this; + } + + extended_view_iterator operator++(int) noexcept { + const extended_view_iterator orig = *this; + return ++(*this), orig; + } + + [[nodiscard]] reference operator*() const noexcept { + return dereference(std::index_sequence_for{}); + } + + [[nodiscard]] pointer operator->() const noexcept { + return operator*(); + } + + [[nodiscard]] constexpr iterator_type base() const noexcept { + return it; + } + + template + friend bool constexpr operator==(const extended_view_iterator &, const extended_view_iterator &) noexcept; + +private: + It it; +}; + +template +[[nodiscard]] constexpr bool operator==(const extended_view_iterator &lhs, const extended_view_iterator &rhs) noexcept { + return lhs.it == rhs.it; +} + +template +[[nodiscard]] constexpr bool operator!=(const extended_view_iterator &lhs, const extended_view_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief View implementation. + * + * Primary template isn't defined on purpose. All the specializations give a + * compile-time error, but for a few reasonable cases. + * + * @b Important + * + * View iterators aren't invalidated if: + * + * * New elements are added to the storage iterated by the view. + * * The entity currently returned is modified (for example, elements are added + * or removed from it). + * * The entity currently returned is destroyed. + * + * In all other cases, modifying the storage iterated by a view in any way can + * invalidate all iterators. + */ +template +class basic_view; + +/** + * @brief Basic storage view implementation. + * @warning For internal use only, backward compatibility not guaranteed. + * @tparam Type Common type among all storage types. + * @tparam Checked True to enable the tombstone check, false otherwise. + * @tparam Get Number of storage iterated by the view. + * @tparam Exclude Number of storage used to filter the view. + */ +template +class basic_common_view { + static_assert(std::is_same_v>, Type>, "Unexpected type"); + + template + friend Return internal::view_pack(const View &, const Other &, std::index_sequence, std::index_sequence, std::index_sequence, std::index_sequence); + + [[nodiscard]] auto offset() const noexcept { + ENTT_ASSERT(index != Get, "Invalid view"); + return (pools[index]->policy() == deletion_policy::swap_only) ? pools[index]->free_list() : pools[index]->size(); + } + + void unchecked_refresh() noexcept { + index = 0u; + + if constexpr(Get > 1u) { + for(size_type pos{1u}; pos < Get; ++pos) { + if(pools[pos]->size() < pools[index]->size()) { + index = pos; + } + } + } + } + +protected: + /*! @cond TURN_OFF_DOXYGEN */ + basic_common_view() noexcept { + for(size_type pos{}, last = filter.size(); pos < last; ++pos) { + filter[pos] = placeholder; + } + } + + basic_common_view(std::array value, std::array excl) noexcept + : pools{value}, + filter{excl}, + index{Get} { + unchecked_refresh(); + } + + [[nodiscard]] const Type *pool_at(const std::size_t pos) const noexcept { + return pools[pos]; + } + + void pool_at(const std::size_t pos, const Type *elem) noexcept { + ENTT_ASSERT(elem != nullptr, "Unexpected element"); + pools[pos] = elem; + refresh(); + } + + [[nodiscard]] const Type *filter_at(const std::size_t pos) const noexcept { + return (filter[pos] == placeholder) ? nullptr : filter[pos]; + } + + void filter_at(const std::size_t pos, const Type *elem) noexcept { + ENTT_ASSERT(elem != nullptr, "Unexpected element"); + filter[pos] = elem; + } + + [[nodiscard]] bool none_of(const typename Type::entity_type entt) const noexcept { + return internal::none_of(filter.begin(), filter.end(), entt); + } + + void use(const std::size_t pos) noexcept { + index = (index != Get) ? pos : Get; + } + /*! @endcond */ + +public: + /*! @brief Common type among all storage types. */ + using common_type = Type; + /*! @brief Underlying entity identifier. */ + using entity_type = typename Type::entity_type; + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + /*! @brief Signed integer type. */ + using difference_type = std::ptrdiff_t; + /*! @brief Forward iterator type. */ + using iterator = internal::view_iterator; + + /*! @brief Updates the internal leading view if required. */ + void refresh() noexcept { + size_type pos = static_cast(index != Get) * Get; + for(; pos < Get && pools[pos] != nullptr; ++pos) {} + + if(pos == Get) { + unchecked_refresh(); + } + } + + /** + * @brief Returns the leading storage of a view, if any. + * @return The leading storage of the view. + */ + [[nodiscard]] const common_type *handle() const noexcept { + return (index != Get) ? pools[index] : nullptr; + } + + /** + * @brief Estimates the number of entities iterated by the view. + * @return Estimated number of entities iterated by the view. + */ + [[nodiscard]] size_type size_hint() const noexcept { + return (index != Get) ? offset() : size_type{}; + } + + /** + * @brief Returns an iterator to the first entity of the view. + * + * If the view is empty, the returned iterator will be equal to `end()`. + * + * @return An iterator to the first entity of the view. + */ + [[nodiscard]] iterator begin() const noexcept { + return (index != Get) ? iterator{pools[index]->end() - static_cast(offset()), pools, filter, index} : iterator{}; + } + + /** + * @brief Returns an iterator that is past the last entity of the view. + * @return An iterator to the entity following the last entity of the view. + */ + [[nodiscard]] iterator end() const noexcept { + return (index != Get) ? iterator{pools[index]->end(), pools, filter, index} : iterator{}; + } + + /** + * @brief Returns the first entity of the view, if any. + * @return The first entity of the view if one exists, the null entity + * otherwise. + */ + [[nodiscard]] entity_type front() const noexcept { + const auto it = begin(); + return it != end() ? *it : null; + } + + /** + * @brief Returns the last entity of the view, if any. + * @return The last entity of the view if one exists, the null entity + * otherwise. + */ + [[nodiscard]] entity_type back() const noexcept { + if(index != Get) { + auto it = pools[index]->rbegin(); + const auto last = it + static_cast(offset()); + for(const auto idx = static_cast(index); it != last && !(internal::all_of(pools.begin(), pools.begin() + idx, *it) && internal::all_of(pools.begin() + idx + 1, pools.end(), *it) && internal::none_of(filter.begin(), filter.end(), *it)); ++it) {} + return it == last ? null : *it; + } + + return null; + } + + /** + * @brief Finds an entity. + * @param entt A valid identifier. + * @return An iterator to the given entity if it's found, past the end + * iterator otherwise. + */ + [[nodiscard]] iterator find(const entity_type entt) const noexcept { + return contains(entt) ? iterator{pools[index]->find(entt), pools, filter, index} : end(); + } + + /** + * @brief Checks if a view is fully initialized. + * @return True if the view is fully initialized, false otherwise. + */ + [[nodiscard]] explicit operator bool() const noexcept { + return (index != Get) && internal::fully_initialized(filter.begin(), filter.end(), placeholder); + } + + /** + * @brief Checks if a view contains an entity. + * @param entt A valid identifier. + * @return True if the view contains the given entity, false otherwise. + */ + [[nodiscard]] bool contains(const entity_type entt) const noexcept { + return (index != Get) + && internal::all_of(pools.begin(), pools.end(), entt) + && internal::none_of(filter.begin(), filter.end(), entt) + && pools[index]->index(entt) < offset(); + } + +private: + std::array pools{}; + std::array filter{}; + const common_type *placeholder{internal::view_placeholder()}; + size_type index{Get}; +}; + +/** + * @brief General purpose view. + * + * This view visits all entities that are at least in the given storage. During + * initialization, it also looks at the number of elements available for each + * storage and uses the smallest set in order to get a performance boost. + * + * @sa basic_view + * + * @tparam Get Types of storage iterated by the view. + * @tparam Exclude Types of storage used to filter the view. + */ +template +class basic_view, exclude_t, std::enable_if_t<(sizeof...(Get) != 0u)>> + : public basic_common_view, internal::tombstone_check_v, sizeof...(Get), sizeof...(Exclude)> { + using base_type = basic_common_view, internal::tombstone_check_v, sizeof...(Get), sizeof...(Exclude)>; + + template + using element_at = type_list_element_t>; + + template + static constexpr std::size_t index_of = type_list_index_v, type_list>; + + template + [[nodiscard]] auto get(const typename base_type::entity_type entt, std::index_sequence) const noexcept { + return std::tuple_cat(storage()->get_as_tuple(entt)...); + } + + template + [[nodiscard]] auto dispatch_get(const std::tuple &curr) const { + if constexpr(Curr == Other) { + return std::forward_as_tuple(std::get(curr)...); + } else { + return storage()->get_as_tuple(std::get<0>(curr)); + } + } + + template + void each(Func &func, std::index_sequence) const { + for(const auto curr: storage()->each()) { + if(const auto entt = std::get<0>(curr); (!internal::tombstone_check_v || (entt != tombstone)) && ((Curr == Index || base_type::pool_at(Index)->contains(entt)) && ...) && base_type::none_of(entt)) { + if constexpr(is_applicable_v{}, std::declval().get({})))>) { + std::apply(func, std::tuple_cat(std::make_tuple(entt), dispatch_get(curr)...)); + } else { + std::apply(func, std::tuple_cat(dispatch_get(curr)...)); + } + } + } + } + + template + void pick_and_each(Func &func, std::index_sequence seq) const { + if(const auto *view = base_type::handle(); view != nullptr) { + ((view == base_type::pool_at(Index) ? each(func, seq) : void()), ...); + } + } + +public: + /*! @brief Common type among all storage types. */ + using common_type = typename base_type::common_type; + /*! @brief Underlying entity identifier. */ + using entity_type = typename base_type::entity_type; + /*! @brief Unsigned integer type. */ + using size_type = typename base_type::size_type; + /*! @brief Signed integer type. */ + using difference_type = std::ptrdiff_t; + /*! @brief Forward iterator type. */ + using iterator = typename base_type::iterator; + /*! @brief Iterable view type. */ + using iterable = iterable_adaptor>; + + /*! @brief Default constructor to use to create empty, invalid views. */ + basic_view() noexcept + : base_type{} {} + + /** + * @brief Constructs a view from a set of storage classes. + * @param value The storage for the types to iterate. + * @param excl The storage for the types used to filter the view. + */ + basic_view(Get &...value, Exclude &...excl) noexcept + : base_type{{&value...}, {&excl...}} { + } + + /** + * @brief Constructs a view from a set of storage classes. + * @param value The storage for the types to iterate. + * @param excl The storage for the types used to filter the view. + */ + basic_view(std::tuple value, std::tuple excl = {}) noexcept + : basic_view{std::make_from_tuple(std::tuple_cat(value, excl))} {} + + /** + * @brief Forces a view to use a given element to drive iterations + * @tparam Type Type of element to use to drive iterations. + */ + template + void use() noexcept { + use>(); + } + + /** + * @brief Forces a view to use a given element to drive iterations + * @tparam Index Index of the element to use to drive iterations. + */ + template + void use() noexcept { + base_type::use(Index); + } + + /** + * @brief Returns the storage for a given element type, if any. + * @tparam Type Type of element of which to return the storage. + * @return The storage for the given element type. + */ + template + [[nodiscard]] auto *storage() const noexcept { + return storage>(); + } + + /** + * @brief Returns the storage for a given index, if any. + * @tparam Index Index of the storage to return. + * @return The storage for the given index. + */ + template + [[nodiscard]] auto *storage() const noexcept { + if constexpr(Index < sizeof...(Get)) { + return static_cast *>(const_cast> *>(base_type::pool_at(Index))); + } else { + return static_cast *>(const_cast> *>(base_type::filter_at(Index - sizeof...(Get)))); + } + } + + /** + * @brief Assigns a storage to a view. + * @tparam Type Type of storage to assign to the view. + * @param elem A storage to assign to the view. + */ + template + void storage(Type &elem) noexcept { + storage>(elem); + } + + /** + * @brief Assigns a storage to a view. + * @tparam Index Index of the storage to assign to the view. + * @tparam Type Type of storage to assign to the view. + * @param elem A storage to assign to the view. + */ + template + void storage(Type &elem) noexcept { + static_assert(std::is_convertible_v &>, "Unexpected type"); + + if constexpr(Index < sizeof...(Get)) { + base_type::pool_at(Index, &elem); + } else { + base_type::filter_at(Index - sizeof...(Get), &elem); + } + } + + /** + * @brief Returns the elements assigned to the given entity. + * @param entt A valid identifier. + * @return The elements assigned to the given entity. + */ + [[nodiscard]] decltype(auto) operator[](const entity_type entt) const { + return get(entt); + } + + /** + * @brief Returns the elements assigned to the given entity. + * @tparam Type Type of the element to get. + * @tparam Other Other types of elements to get. + * @param entt A valid identifier. + * @return The elements assigned to the entity. + */ + template + [[nodiscard]] decltype(auto) get(const entity_type entt) const { + return get, index_of...>(entt); + } + + /** + * @brief Returns the elements assigned to the given entity. + * @tparam Index Indexes of the elements to get. + * @param entt A valid identifier. + * @return The elements assigned to the entity. + */ + template + [[nodiscard]] decltype(auto) get(const entity_type entt) const { + if constexpr(sizeof...(Index) == 0) { + return get(entt, std::index_sequence_for{}); + } else if constexpr(sizeof...(Index) == 1) { + return (storage()->get(entt), ...); + } else { + return std::tuple_cat(storage()->get_as_tuple(entt)...); + } + } + + /** + * @brief Iterates entities and elements and applies the given function + * object to them. + * + * The signature of the function must be equivalent to one of the following + * (non-empty types only, constness as requested): + * + * @code{.cpp} + * void(const entity_type, Type &...); + * void(Type &...); + * @endcode + * + * @tparam Func Type of the function object to invoke. + * @param func A valid function object. + */ + template + void each(Func func) const { + pick_and_each(func, std::index_sequence_for{}); + } + + /** + * @brief Returns an iterable object to use to _visit_ a view. + * + * The iterable object returns a tuple that contains the current entity and + * a set of references to its non-empty elements. The _constness_ of the + * elements is as requested. + * + * @return An iterable object to use to _visit_ the view. + */ + [[nodiscard]] iterable each() const noexcept { + return iterable{base_type::begin(), base_type::end()}; + } + + /** + * @brief Combines a view and a storage in _more specific_ view. + * @tparam OGet Type of storage to combine the view with. + * @param other The storage for the type to combine the view with. + * @return A more specific view. + */ + template + [[nodiscard]] std::enable_if_t, basic_view, exclude_t>> operator|(OGet &other) const noexcept { + return *this | basic_view, exclude_t<>>{other}; + } + + /** + * @brief Combines two views in a _more specific_ one. + * @tparam OGet Element list of the view to combine with. + * @tparam OExclude Filter list of the view to combine with. + * @param other The view to combine with. + * @return A more specific view. + */ + template + [[nodiscard]] auto operator|(const basic_view, exclude_t> &other) const noexcept { + return internal::view_pack, exclude_t>>( + *this, other, std::index_sequence_for{}, std::index_sequence_for{}, std::index_sequence_for{}, std::index_sequence_for{}); + } +}; + +/** + * @brief Basic storage view implementation. + * @warning For internal use only, backward compatibility not guaranteed. + * @tparam Type Common type among all storage types. + * @tparam Policy Storage policy. + */ +template +class basic_storage_view { + static_assert(std::is_same_v>, Type>, "Unexpected type"); + +protected: + /*! @cond TURN_OFF_DOXYGEN */ + basic_storage_view() noexcept = default; + + basic_storage_view(const Type *value) noexcept + : leading{value} { + ENTT_ASSERT(leading->policy() == Policy, "Unexpected storage policy"); + } + /*! @endcond */ + +public: + /*! @brief Common type among all storage types. */ + using common_type = Type; + /*! @brief Underlying entity identifier. */ + using entity_type = typename common_type::entity_type; + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + /*! @brief Signed integer type. */ + using difference_type = std::ptrdiff_t; + /*! @brief Random access iterator type. */ + using iterator = std::conditional_t, typename common_type::iterator>; + /*! @brief Reverse iterator type. */ + using reverse_iterator = std::conditional_t; + + /** + * @brief Returns the leading storage of a view, if any. + * @return The leading storage of the view. + */ + [[nodiscard]] const common_type *handle() const noexcept { + return leading; + } + + /** + * @brief Returns the number of entities that have the given element. + * @tparam Pol Dummy template parameter used for sfinae purposes only. + * @return Number of entities that have the given element. + */ + template + [[nodiscard]] std::enable_if_t size() const noexcept { + if constexpr(Policy == deletion_policy::swap_and_pop) { + return leading ? leading->size() : size_type{}; + } else { + static_assert(Policy == deletion_policy::swap_only, "Unexpected storage policy"); + return leading ? leading->free_list() : size_type{}; + } + } + + /** + * @brief Estimates the number of entities iterated by the view. + * @tparam Pol Dummy template parameter used for sfinae purposes only. + * @return Estimated number of entities iterated by the view. + */ + template + [[nodiscard]] std::enable_if_t size_hint() const noexcept { + return leading ? leading->size() : size_type{}; + } + + /** + * @brief Checks whether a view is empty. + * @tparam Pol Dummy template parameter used for sfinae purposes only. + * @return True if the view is empty, false otherwise. + */ + template + [[nodiscard]] std::enable_if_t empty() const noexcept { + if constexpr(Policy == deletion_policy::swap_and_pop) { + return !leading || leading->empty(); + } else { + static_assert(Policy == deletion_policy::swap_only, "Unexpected storage policy"); + return !leading || (leading->free_list() == 0u); + } + } + + /** + * @brief Returns an iterator to the first entity of the view. + * + * If the view is empty, the returned iterator will be equal to `end()`. + * + * @return An iterator to the first entity of the view. + */ + [[nodiscard]] iterator begin() const noexcept { + if constexpr(Policy == deletion_policy::swap_and_pop) { + return leading ? leading->begin() : iterator{}; + } else if constexpr(Policy == deletion_policy::swap_only) { + return leading ? (leading->end() - static_cast(leading->free_list())) : iterator{}; + } else { + static_assert(Policy == deletion_policy::in_place, "Unexpected storage policy"); + return leading ? iterator{leading->begin(), {leading}, {}, 0u} : iterator{}; + } + } + + /** + * @brief Returns an iterator that is past the last entity of the view. + * @return An iterator to the entity following the last entity of the view. + */ + [[nodiscard]] iterator end() const noexcept { + if constexpr(Policy == deletion_policy::swap_and_pop || Policy == deletion_policy::swap_only) { + return leading ? leading->end() : iterator{}; + } else { + static_assert(Policy == deletion_policy::in_place, "Unexpected storage policy"); + return leading ? iterator{leading->end(), {leading}, {}, 0u} : iterator{}; + } + } + + /** + * @brief Returns an iterator to the first entity of the reversed view. + * + * If the view is empty, the returned iterator will be equal to `rend()`. + * + * @tparam Pol Dummy template parameter used for sfinae purposes only. + * @return An iterator to the first entity of the reversed view. + */ + template + [[nodiscard]] std::enable_if_t rbegin() const noexcept { + return leading ? leading->rbegin() : reverse_iterator{}; + } + + /** + * @brief Returns an iterator that is past the last entity of the reversed + * view. + * @tparam Pol Dummy template parameter used for sfinae purposes only. + * @return An iterator to the entity following the last entity of the + * reversed view. + */ + template + [[nodiscard]] std::enable_if_t rend() const noexcept { + if constexpr(Policy == deletion_policy::swap_and_pop) { + return leading ? leading->rend() : reverse_iterator{}; + } else { + static_assert(Policy == deletion_policy::swap_only, "Unexpected storage policy"); + return leading ? (leading->rbegin() + static_cast(leading->free_list())) : reverse_iterator{}; + } + } + + /** + * @brief Returns the first entity of the view, if any. + * @return The first entity of the view if one exists, the null entity + * otherwise. + */ + [[nodiscard]] entity_type front() const noexcept { + if constexpr(Policy == deletion_policy::swap_and_pop) { + return empty() ? null : *leading->begin(); + } else if constexpr(Policy == deletion_policy::swap_only) { + return empty() ? null : *(leading->end() - static_cast(leading->free_list())); + } else { + static_assert(Policy == deletion_policy::in_place, "Unexpected storage policy"); + const auto it = begin(); + return (it == end()) ? null : *it; + } + } + + /** + * @brief Returns the last entity of the view, if any. + * @return The last entity of the view if one exists, the null entity + * otherwise. + */ + [[nodiscard]] entity_type back() const noexcept { + if constexpr(Policy == deletion_policy::swap_and_pop || Policy == deletion_policy::swap_only) { + return empty() ? null : *leading->rbegin(); + } else { + static_assert(Policy == deletion_policy::in_place, "Unexpected storage policy"); + + if(leading) { + auto it = leading->rbegin(); + const auto last = leading->rend(); + for(; (it != last) && (*it == tombstone); ++it) {} + return it == last ? null : *it; + } + + return null; + } + } + + /** + * @brief Finds an entity. + * @param entt A valid identifier. + * @return An iterator to the given entity if it's found, past the end + * iterator otherwise. + */ + [[nodiscard]] iterator find(const entity_type entt) const noexcept { + if constexpr(Policy == deletion_policy::swap_and_pop) { + return leading ? leading->find(entt) : iterator{}; + } else if constexpr(Policy == deletion_policy::swap_only) { + const auto it = leading ? leading->find(entt) : iterator{}; + return leading && (static_cast(it.index()) < leading->free_list()) ? it : iterator{}; + } else { + return leading ? iterator{leading->find(entt), {leading}, {}, 0u} : iterator{}; + } + } + + /** + * @brief Checks if a view is fully initialized. + * @return True if the view is fully initialized, false otherwise. + */ + [[nodiscard]] explicit operator bool() const noexcept { + return (leading != nullptr); + } + + /** + * @brief Checks if a view contains an entity. + * @param entt A valid identifier. + * @return True if the view contains the given entity, false otherwise. + */ + [[nodiscard]] bool contains(const entity_type entt) const noexcept { + if constexpr(Policy == deletion_policy::swap_and_pop || Policy == deletion_policy::in_place) { + return leading && leading->contains(entt); + } else { + static_assert(Policy == deletion_policy::swap_only, "Unexpected storage policy"); + return leading && leading->contains(entt) && (leading->index(entt) < leading->free_list()); + } + } + +private: + const common_type *leading{}; +}; + +/** + * @brief Storage view specialization. + * + * This specialization offers a boost in terms of performance. It can access the + * underlying data structure directly and avoid superfluous checks. + * + * @sa basic_view + * + * @tparam Get Type of storage iterated by the view. + */ +template +class basic_view, exclude_t<>> + : public basic_storage_view { + using base_type = basic_storage_view; + +public: + /*! @brief Common type among all storage types. */ + using common_type = typename base_type::common_type; + /*! @brief Underlying entity identifier. */ + using entity_type = typename base_type::entity_type; + /*! @brief Unsigned integer type. */ + using size_type = typename base_type::size_type; + /*! @brief Signed integer type. */ + using difference_type = std::ptrdiff_t; + /*! @brief Random access iterator type. */ + using iterator = typename base_type::iterator; + /*! @brief Reverse iterator type. */ + using reverse_iterator = typename base_type::reverse_iterator; + /*! @brief Iterable view type. */ + using iterable = std::conditional_t>, decltype(std::declval().each())>; + + /*! @brief Default constructor to use to create empty, invalid views. */ + basic_view() noexcept + : base_type{} {} + + /** + * @brief Constructs a view from a storage class. + * @param value The storage for the type to iterate. + */ + basic_view(Get &value) noexcept + : base_type{&value} { + } + + /** + * @brief Constructs a view from a storage class. + * @param value The storage for the type to iterate. + */ + basic_view(std::tuple value, std::tuple<> = {}) noexcept + : basic_view{std::get<0>(value)} {} + + /** + * @brief Returns the storage for a given element type, if any. + * @tparam Type Type of element of which to return the storage. + * @return The storage for the given element type. + */ + template + [[nodiscard]] auto *storage() const noexcept { + static_assert(std::is_same_v, typename Get::element_type>, "Invalid element type"); + return storage<0>(); + } + + /** + * @brief Returns the storage for a given index, if any. + * @tparam Index Index of the storage to return. + * @return The storage for the given index. + */ + template + [[nodiscard]] auto *storage() const noexcept { + static_assert(Index == 0u, "Index out of bounds"); + return static_cast(const_cast *>(base_type::handle())); + } + + /** + * @brief Assigns a storage to a view. + * @param elem A storage to assign to the view. + */ + void storage(Get &elem) noexcept { + storage<0>(elem); + } + + /** + * @brief Assigns a storage to a view. + * @tparam Index Index of the storage to assign to the view. + * @param elem A storage to assign to the view. + */ + template + void storage(Get &elem) noexcept { + static_assert(Index == 0u, "Index out of bounds"); + *this = basic_view{elem}; + } + + /** + * @brief Returns a pointer to the underlying storage. + * @return A pointer to the underlying storage. + */ + [[nodiscard]] Get *operator->() const noexcept { + return storage(); + } + + /** + * @brief Returns the element assigned to the given entity. + * @param entt A valid identifier. + * @return The element assigned to the given entity. + */ + [[nodiscard]] decltype(auto) operator[](const entity_type entt) const { + return storage()->get(entt); + } + + /** + * @brief Returns the element assigned to the given entity. + * @tparam Elem Type of the element to get. + * @param entt A valid identifier. + * @return The element assigned to the entity. + */ + template + [[nodiscard]] decltype(auto) get(const entity_type entt) const { + static_assert(std::is_same_v, typename Get::element_type>, "Invalid element type"); + return get<0>(entt); + } + + /** + * @brief Returns the element assigned to the given entity. + * @tparam Index Index of the element to get. + * @param entt A valid identifier. + * @return The element assigned to the entity. + */ + template + [[nodiscard]] decltype(auto) get(const entity_type entt) const { + if constexpr(sizeof...(Index) == 0) { + return storage()->get_as_tuple(entt); + } else { + return storage()->get(entt); + } + } + + /** + * @brief Iterates entities and elements and applies the given function + * object to them. + * + * The signature of the function must be equivalent to one of the following + * (non-empty types only, constness as requested): + * + * @code{.cpp} + * void(const entity_type, Type &); + * void(typename Type &); + * @endcode + * + * @tparam Func Type of the function object to invoke. + * @param func A valid function object. + */ + template + void each(Func func) const { + if constexpr(is_applicable_v{}, std::declval().get({})))>) { + for(const auto pack: each()) { + std::apply(func, pack); + } + } else if constexpr(Get::storage_policy == deletion_policy::swap_and_pop || Get::storage_policy == deletion_policy::swap_only) { + if constexpr(std::is_void_v) { + for(size_type pos = base_type::size(); pos; --pos) { + func(); + } + } else { + if(const auto len = static_cast(base_type::size()); len != 0) { + for(auto last = storage()->end(), first = last - len; first != last; ++first) { + func(*first); + } + } + } + } else { + static_assert(Get::storage_policy == deletion_policy::in_place, "Unexpected storage policy"); + + for(const auto pack: each()) { + std::apply([&func](const auto, auto &&...elem) { func(std::forward(elem)...); }, pack); + } + } + } + + /** + * @brief Returns an iterable object to use to _visit_ a view. + * + * The iterable object returns a tuple that contains the current entity and + * a reference to its element if it's a non-empty one. The _constness_ of + * the element is as requested. + * + * @return An iterable object to use to _visit_ the view. + */ + [[nodiscard]] iterable each() const noexcept { + if constexpr(Get::storage_policy == deletion_policy::swap_and_pop || Get::storage_policy == deletion_policy::swap_only) { + return base_type::handle() ? storage()->each() : iterable{}; + } else { + static_assert(Get::storage_policy == deletion_policy::in_place, "Unexpected storage policy"); + return iterable{base_type::begin(), base_type::end()}; + } + } + + /** + * @brief Combines a view and a storage in _more specific_ view. + * @tparam OGet Type of storage to combine the view with. + * @param other The storage for the type to combine the view with. + * @return A more specific view. + */ + template + [[nodiscard]] std::enable_if_t, basic_view, exclude_t<>>> operator|(OGet &other) const noexcept { + return *this | basic_view, exclude_t<>>{other}; + } + + /** + * @brief Combines two views in a _more specific_ one. + * @tparam OGet Element list of the view to combine with. + * @tparam OExclude Filter list of the view to combine with. + * @param other The view to combine with. + * @return A more specific view. + */ + template + [[nodiscard]] auto operator|(const basic_view, exclude_t> &other) const noexcept { + return internal::view_pack, exclude_t>>( + *this, other, std::index_sequence_for{}, std::index_sequence_for<>{}, std::index_sequence_for{}, std::index_sequence_for{}); + } +}; + +/** + * @brief Deduction guide. + * @tparam Type Type of storage classes used to create the view. + * @param storage The storage for the types to iterate. + */ +template +basic_view(Type &...storage) -> basic_view, exclude_t<>>; + +/** + * @brief Deduction guide. + * @tparam Get Types of elements iterated by the view. + * @tparam Exclude Types of elements used to filter the view. + */ +template +basic_view(std::tuple, std::tuple = {}) -> basic_view, exclude_t>; + +} // namespace entt + +#endif + + +namespace entt { + +/** + * @brief Converts a registry to a view. + * @tparam Registry Basic registry type. + */ +template +class as_view { + template + [[nodiscard]] auto dispatch(get_t, exclude_t) const { + return reg->template view...>(exclude_t...>{}); + } + +public: + /*! @brief Type of registry to convert. */ + using registry_type = Registry; + /*! @brief Underlying entity identifier. */ + using entity_type = typename registry_type::entity_type; + + /** + * @brief Constructs a converter for a given registry. + * @param source A valid reference to a registry. + */ + as_view(registry_type &source) noexcept + : reg{&source} {} + + /** + * @brief Conversion function from a registry to a view. + * @tparam Get Type of storage used to construct the view. + * @tparam Exclude Types of storage used to filter the view. + * @return A newly created view. + */ + template + operator basic_view() const { + return dispatch(Get{}, Exclude{}); + } + +private: + registry_type *reg; +}; + +/** + * @brief Converts a registry to a group. + * @tparam Registry Basic registry type. + */ +template +class as_group { + template + [[nodiscard]] auto dispatch(owned_t, get_t, exclude_t) const { + if constexpr(std::is_const_v) { + return reg->template group_if_exists(get_t{}, exclude_t{}); + } else { + return reg->template group...>(get_t...>{}, exclude_t...>{}); + } + } + +public: + /*! @brief Type of registry to convert. */ + using registry_type = Registry; + /*! @brief Underlying entity identifier. */ + using entity_type = typename registry_type::entity_type; + + /** + * @brief Constructs a converter for a given registry. + * @param source A valid reference to a registry. + */ + as_group(registry_type &source) noexcept + : reg{&source} {} + + /** + * @brief Conversion function from a registry to a group. + * @tparam Owned Types of _owned_ by the group. + * @tparam Get Types of storage _observed_ by the group. + * @tparam Exclude Types of storage used to filter the group. + * @return A newly created group. + */ + template + operator basic_group() const { + return dispatch(Owned{}, Get{}, Exclude{}); + } + +private: + registry_type *reg; +}; + +/** + * @brief Helper to create a listener that directly invokes a member function. + * @tparam Member Member function to invoke on an element of the given type. + * @tparam Registry Basic registry type. + * @param reg A registry that contains the given entity and its elements. + * @param entt Entity from which to get the element. + */ +template>> +void invoke(Registry ®, const typename Registry::entity_type entt) { + static_assert(std::is_member_function_pointer_v, "Invalid pointer to non-static member function"); + (reg.template get>(entt).*Member)(reg, entt); +} + +/** + * @brief Returns the entity associated with a given element. + * + * @warning + * Currently, this function only works correctly with the default storage as it + * makes assumptions about how the elements are laid out. + * + * @tparam Args Storage type template parameters. + * @param storage A storage that contains the given element. + * @param instance A valid element instance. + * @return The entity associated with the given element. + */ +template +typename basic_storage::entity_type to_entity(const basic_storage &storage, const typename basic_storage::value_type &instance) { + using traits_type = component_traits::value_type, typename basic_storage::entity_type>; + static_assert(traits_type::page_size != 0u, "Unexpected page size"); + const auto *page = storage.raw(); + + // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic) + for(std::size_t pos{}, count = storage.size(); pos < count; pos += traits_type::page_size, ++page) { + if(const auto dist = (std::addressof(instance) - *page); dist >= 0 && dist < static_cast(traits_type::page_size)) { + return *(static_cast::base_type &>(storage).rbegin() + static_cast(pos) + dist); + } + } + // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic) + + return null; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct sigh_helper; + +/** + * @brief Signal connection helper for registries. + * @tparam Registry Basic registry type. + */ +template +struct sigh_helper { + /*! @brief Registry type. */ + using registry_type = Registry; + + /** + * @brief Constructs a helper for a given registry. + * @param ref A valid reference to a registry. + */ + sigh_helper(registry_type &ref) + : bucket{&ref} {} + + /** + * @brief Binds a properly initialized helper to a given signal type. + * @tparam Type Type of signal to bind the helper to. + * @param id Optional name for the underlying storage to use. + * @return A helper for a given registry and signal type. + */ + template + auto with(const id_type id = type_hash::value()) noexcept { + return sigh_helper{*bucket, id}; + } + + /** + * @brief Returns a reference to the underlying registry. + * @return A reference to the underlying registry. + */ + [[nodiscard]] registry_type ®istry() noexcept { + return *bucket; + } + +private: + registry_type *bucket; +}; + +/** + * @brief Signal connection helper for registries. + * @tparam Registry Basic registry type. + * @tparam Type Type of signal to connect listeners to. + */ +template +struct sigh_helper final: sigh_helper { + /*! @brief Registry type. */ + using registry_type = Registry; + + /** + * @brief Constructs a helper for a given registry. + * @param ref A valid reference to a registry. + * @param id Optional name for the underlying storage to use. + */ + sigh_helper(registry_type &ref, const id_type id = type_hash::value()) + : sigh_helper{ref}, + name{id} {} + + /** + * @brief Forwards the call to `on_construct` on the underlying storage. + * @tparam Candidate Function or member to connect. + * @tparam Args Type of class or type of payload, if any. + * @param args A valid object that fits the purpose, if any. + * @return This helper. + */ + template + auto on_construct(Args &&...args) { + this->registry().template on_construct(name).template connect(std::forward(args)...); + return *this; + } + + /** + * @brief Forwards the call to `on_update` on the underlying storage. + * @tparam Candidate Function or member to connect. + * @tparam Args Type of class or type of payload, if any. + * @param args A valid object that fits the purpose, if any. + * @return This helper. + */ + template + auto on_update(Args &&...args) { + this->registry().template on_update(name).template connect(std::forward(args)...); + return *this; + } + + /** + * @brief Forwards the call to `on_destroy` on the underlying storage. + * @tparam Candidate Function or member to connect. + * @tparam Args Type of class or type of payload, if any. + * @param args A valid object that fits the purpose, if any. + * @return This helper. + */ + template + auto on_destroy(Args &&...args) { + this->registry().template on_destroy(name).template connect(std::forward(args)...); + return *this; + } + +private: + id_type name; +}; + +/** + * @brief Deduction guide. + * @tparam Registry Basic registry type. + */ +template +sigh_helper(Registry &) -> sigh_helper; + +} // namespace entt + +#endif + +// #include "entity/mixin.hpp" +#ifndef ENTT_ENTITY_MIXIN_HPP +#define ENTT_ENTITY_MIXIN_HPP + +#include +#include +// #include "../config/config.h" + +// #include "../core/any.hpp" + +// #include "../core/type_info.hpp" + +// #include "../signal/sigh.hpp" +#ifndef ENTT_SIGNAL_SIGH_HPP +#define ENTT_SIGNAL_SIGH_HPP + +#include +#include +#include +#include +#include +// #include "delegate.hpp" +#ifndef ENTT_SIGNAL_DELEGATE_HPP +#define ENTT_SIGNAL_DELEGATE_HPP + +#include +#include +#include +#include +#include +// #include "../config/config.h" +#ifndef ENTT_CONFIG_CONFIG_H +#define ENTT_CONFIG_CONFIG_H + +// #include "version.h" +#ifndef ENTT_CONFIG_VERSION_H +#define ENTT_CONFIG_VERSION_H + +// #include "macro.h" +#ifndef ENTT_CONFIG_MACRO_H +#define ENTT_CONFIG_MACRO_H + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#define ENTT_STR(arg) #arg +#define ENTT_XSTR(arg) ENTT_STR(arg) + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*) + +#define ENTT_VERSION_MAJOR 3 +#define ENTT_VERSION_MINOR 16 +#define ENTT_VERSION_PATCH 0 + +#define ENTT_VERSION \ + ENTT_XSTR(ENTT_VERSION_MAJOR) \ + "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH) + +// NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION) +# define ENTT_CONSTEXPR +# define ENTT_THROW throw +# define ENTT_TRY try +# define ENTT_CATCH catch(...) +#else +# define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20) +# define ENTT_THROW +# define ENTT_TRY if(true) +# define ENTT_CATCH if(false) +#endif + +#if __has_include() +# include +# +# if defined(__cpp_consteval) +# define ENTT_CONSTEVAL consteval +# endif +#endif + +#ifndef ENTT_CONSTEVAL +# define ENTT_CONSTEVAL constexpr +#endif + +#ifdef ENTT_USE_ATOMIC +# include +# define ENTT_MAYBE_ATOMIC(Type) std::atomic +#else +# define ENTT_MAYBE_ATOMIC(Type) Type +#endif + +#ifndef ENTT_ID_TYPE +# include +# define ENTT_ID_TYPE std::uint32_t +#else +# include // provides coverage for types in the std namespace +#endif + +#ifndef ENTT_SPARSE_PAGE +# define ENTT_SPARSE_PAGE 4096 +#endif + +#ifndef ENTT_PACKED_PAGE +# define ENTT_PACKED_PAGE 1024 +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT +# define ENTT_ASSERT(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT +# include +# define ENTT_ASSERT(condition, msg) assert(((condition) && (msg))) +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg) +#endif + +#define ENTT_FAIL(msg) ENTT_ASSERT(false, msg); + +#ifdef ENTT_NO_ETO +# define ENTT_ETO_TYPE(Type) void +#else +# define ENTT_ETO_TYPE(Type) Type +#endif + +#ifdef ENTT_NO_MIXIN +# define ENTT_STORAGE(Mixin, ...) __VA_ARGS__ +#else +# define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__> +#endif + +#ifdef ENTT_STANDARD_CPP +# define ENTT_NONSTD false +#else +# define ENTT_NONSTD true +# if defined __clang__ || defined __GNUC__ +# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ +# define ENTT_PRETTY_FUNCTION_PREFIX '=' +# define ENTT_PRETTY_FUNCTION_SUFFIX ']' +# elif defined _MSC_VER +# define ENTT_PRETTY_FUNCTION __FUNCSIG__ +# define ENTT_PRETTY_FUNCTION_PREFIX '<' +# define ENTT_PRETTY_FUNCTION_SUFFIX '>' +# endif +#endif + +#ifndef ENTT_EXPORT +# if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER +# define ENTT_EXPORT __declspec(dllexport) +# define ENTT_IMPORT __declspec(dllimport) +# define ENTT_HIDDEN +# elif defined __GNUC__ && __GNUC__ >= 4 +# define ENTT_EXPORT __attribute__((visibility("default"))) +# define ENTT_IMPORT __attribute__((visibility("default"))) +# define ENTT_HIDDEN __attribute__((visibility("hidden"))) +# else /* Unsupported compiler */ +# define ENTT_EXPORT +# define ENTT_IMPORT +# define ENTT_HIDDEN +# endif +#endif + +#ifndef ENTT_API +# if defined ENTT_API_EXPORT +# define ENTT_API ENTT_EXPORT +# elif defined ENTT_API_IMPORT +# define ENTT_API ENTT_IMPORT +# else /* No API */ +# define ENTT_API +# endif +#endif + +#if defined _MSC_VER +# pragma detect_mismatch("entt.version", ENTT_VERSION) +# pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY)) +# pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE)) +# pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD)) +#endif + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + +// #include "../core/type_traits.hpp" +#ifndef ENTT_CORE_TYPE_TRAITS_HPP +#define ENTT_CORE_TYPE_TRAITS_HPP + +#include +#include +#include +#include +#include +// #include "../config/config.h" +#ifndef ENTT_CONFIG_CONFIG_H +#define ENTT_CONFIG_CONFIG_H + +// #include "version.h" +#ifndef ENTT_CONFIG_VERSION_H +#define ENTT_CONFIG_VERSION_H + +// #include "macro.h" +#ifndef ENTT_CONFIG_MACRO_H +#define ENTT_CONFIG_MACRO_H + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#define ENTT_STR(arg) #arg +#define ENTT_XSTR(arg) ENTT_STR(arg) + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*) + +#define ENTT_VERSION_MAJOR 3 +#define ENTT_VERSION_MINOR 16 +#define ENTT_VERSION_PATCH 0 + +#define ENTT_VERSION \ + ENTT_XSTR(ENTT_VERSION_MAJOR) \ + "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH) + +// NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION) +# define ENTT_CONSTEXPR +# define ENTT_THROW throw +# define ENTT_TRY try +# define ENTT_CATCH catch(...) +#else +# define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20) +# define ENTT_THROW +# define ENTT_TRY if(true) +# define ENTT_CATCH if(false) +#endif + +#if __has_include() +# include +# +# if defined(__cpp_consteval) +# define ENTT_CONSTEVAL consteval +# endif +#endif + +#ifndef ENTT_CONSTEVAL +# define ENTT_CONSTEVAL constexpr +#endif + +#ifdef ENTT_USE_ATOMIC +# include +# define ENTT_MAYBE_ATOMIC(Type) std::atomic +#else +# define ENTT_MAYBE_ATOMIC(Type) Type +#endif + +#ifndef ENTT_ID_TYPE +# include +# define ENTT_ID_TYPE std::uint32_t +#else +# include // provides coverage for types in the std namespace +#endif + +#ifndef ENTT_SPARSE_PAGE +# define ENTT_SPARSE_PAGE 4096 +#endif + +#ifndef ENTT_PACKED_PAGE +# define ENTT_PACKED_PAGE 1024 +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT +# define ENTT_ASSERT(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT +# include +# define ENTT_ASSERT(condition, msg) assert(((condition) && (msg))) +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg) +#endif + +#define ENTT_FAIL(msg) ENTT_ASSERT(false, msg); + +#ifdef ENTT_NO_ETO +# define ENTT_ETO_TYPE(Type) void +#else +# define ENTT_ETO_TYPE(Type) Type +#endif + +#ifdef ENTT_NO_MIXIN +# define ENTT_STORAGE(Mixin, ...) __VA_ARGS__ +#else +# define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__> +#endif + +#ifdef ENTT_STANDARD_CPP +# define ENTT_NONSTD false +#else +# define ENTT_NONSTD true +# if defined __clang__ || defined __GNUC__ +# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ +# define ENTT_PRETTY_FUNCTION_PREFIX '=' +# define ENTT_PRETTY_FUNCTION_SUFFIX ']' +# elif defined _MSC_VER +# define ENTT_PRETTY_FUNCTION __FUNCSIG__ +# define ENTT_PRETTY_FUNCTION_PREFIX '<' +# define ENTT_PRETTY_FUNCTION_SUFFIX '>' +# endif +#endif + +#ifndef ENTT_EXPORT +# if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER +# define ENTT_EXPORT __declspec(dllexport) +# define ENTT_IMPORT __declspec(dllimport) +# define ENTT_HIDDEN +# elif defined __GNUC__ && __GNUC__ >= 4 +# define ENTT_EXPORT __attribute__((visibility("default"))) +# define ENTT_IMPORT __attribute__((visibility("default"))) +# define ENTT_HIDDEN __attribute__((visibility("hidden"))) +# else /* Unsupported compiler */ +# define ENTT_EXPORT +# define ENTT_IMPORT +# define ENTT_HIDDEN +# endif +#endif + +#ifndef ENTT_API +# if defined ENTT_API_EXPORT +# define ENTT_API ENTT_EXPORT +# elif defined ENTT_API_IMPORT +# define ENTT_API ENTT_IMPORT +# else /* No API */ +# define ENTT_API +# endif +#endif + +#if defined _MSC_VER +# pragma detect_mismatch("entt.version", ENTT_VERSION) +# pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY)) +# pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE)) +# pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD)) +#endif + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + +// #include "fwd.hpp" +#ifndef ENTT_CORE_FWD_HPP +#define ENTT_CORE_FWD_HPP + +#include +#include +// #include "../config/config.h" + + +namespace entt { + +/*! @brief Possible modes of an any object. */ +enum class any_policy : std::uint8_t { + /*! @brief Default mode, no element available. */ + empty, + /*! @brief Owning mode, dynamically allocated element. */ + dynamic, + /*! @brief Owning mode, embedded element. */ + embedded, + /*! @brief Aliasing mode, non-const reference. */ + ref, + /*! @brief Const aliasing mode, const reference. */ + cref +}; + +// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) +template +class basic_any; + +/*! @brief Alias declaration for type identifiers. */ +using id_type = ENTT_ID_TYPE; + +/*! @brief Alias declaration for the most common use case. */ +using any = basic_any<>; + +template +class compressed_pair; + +template +class basic_hashed_string; + +/*! @brief Aliases for common character types. */ +using hashed_string = basic_hashed_string; + +/*! @brief Aliases for common character types. */ +using hashed_wstring = basic_hashed_string; + +// NOLINTNEXTLINE(bugprone-forward-declaration-namespace) +struct type_info; + +} // namespace entt + +#endif + + +namespace entt { + +/** + * @brief Utility class to disambiguate overloaded functions. + * @tparam N Number of choices available. + */ +template +struct choice_t + // unfortunately, doxygen cannot parse such a construct + : /*! @cond TURN_OFF_DOXYGEN */ choice_t /*! @endcond */ +{}; + +/*! @copybrief choice_t */ +template<> +struct choice_t<0> {}; + +/** + * @brief Variable template for the choice trick. + * @tparam N Number of choices available. + */ +template +inline constexpr choice_t choice{}; + +/** + * @brief Identity type trait. + * + * Useful to establish non-deduced contexts in template argument deduction + * (waiting for C++20) or to provide types through function arguments. + * + * @tparam Type A type. + */ +template +struct type_identity { + /*! @brief Identity type. */ + using type = Type; +}; + +/** + * @brief Helper type. + * @tparam Type A type. + */ +template +using type_identity_t = typename type_identity::type; + +/** + * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains. + * @tparam Type The type of which to return the size. + */ +template +struct size_of: std::integral_constant {}; + +/*! @copydoc size_of */ +template +struct size_of> + // NOLINTNEXTLINE(bugprone-sizeof-expression) + : std::integral_constant {}; + +/** + * @brief Helper variable template. + * @tparam Type The type of which to return the size. + */ +template +inline constexpr std::size_t size_of_v = size_of::value; + +/** + * @brief Using declaration to be used to _repeat_ the same type a number of + * times equal to the size of a given parameter pack. + * @tparam Type A type to repeat. + */ +template +using unpack_as_type = Type; + +/** + * @brief Helper variable template to be used to _repeat_ the same value a + * number of times equal to the size of a given parameter pack. + * @tparam Value A value to repeat. + */ +template +inline constexpr auto unpack_as_value = Value; + +/** + * @brief Wraps a static constant. + * @tparam Value A static constant. + */ +template +using integral_constant = std::integral_constant; + +/** + * @brief Alias template to facilitate the creation of named values. + * @tparam Value A constant value at least convertible to `id_type`. + */ +template +using tag = integral_constant; + +/** + * @brief A class to use to push around lists of types, nothing more. + * @tparam Type Types provided by the type list. + */ +template +struct type_list { + /*! @brief Type list type. */ + using type = type_list; + /*! @brief Compile-time number of elements in the type list. */ + static constexpr auto size = sizeof...(Type); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_element; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Index Index of the type to return. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element> + : type_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element<0u, type_list> { + /*! @brief Searched type. */ + using type = First; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Type list to search into. + */ +template +using type_list_element_t = typename type_list_element::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_index; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 1u + type_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + static_assert(type_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +inline constexpr std::size_t type_list_index_v = type_list_index::value; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @return A type list composed by the types of both the type lists. + */ +template +constexpr type_list operator+(type_list, type_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_cat; + +/*! @brief Concatenates multiple type lists. */ +template<> +struct type_list_cat<> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list<>; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @tparam List Other type lists, if any. + */ +template +struct type_list_cat, type_list, List...> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = typename type_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the type list. + */ +template +struct type_list_cat> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list; +}; + +/** + * @brief Helper type. + * @tparam List Type lists to concatenate. + */ +template +using type_list_cat_t = typename type_list_cat::type; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct type_list_unique; + +template +struct type_list_unique, Type...> + : std::conditional_t<(std::is_same_v || ...), type_list_unique, Type...>, type_list_unique, Type..., First>> {}; + +template +struct type_list_unique, Type...> { + using type = type_list; +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Removes duplicates types from a type list. + * @tparam List Type list. + */ +template +struct type_list_unique { + /*! @brief A type list without duplicate types. */ + using type = typename internal::type_list_unique::type; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + */ +template +using type_list_unique_t = typename type_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a type list contains a + * given type, false otherwise. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +struct type_list_contains; + +/** + * @copybrief type_list_contains + * @tparam Type Types provided by the type list. + * @tparam Other Type to look for. + */ +template +struct type_list_contains, Other> + : std::bool_constant<(std::is_same_v || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +inline constexpr bool type_list_contains_v = type_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_diff; + +/** + * @brief Computes the difference between two type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + */ +template +struct type_list_diff, type_list> { + /*! @brief A type list that is the difference between the two type lists. */ + using type = type_list_cat_t, Type>, type_list<>, type_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Type lists between which to compute the difference. + */ +template +using type_list_diff_t = typename type_list_diff::type; + +/*! @brief Primary template isn't defined on purpose. */ +template class> +struct type_list_transform; + +/** + * @brief Applies a given _function_ to a type list and generate a new list. + * @tparam Type Types provided by the type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +struct type_list_transform, Op> { + /*! @brief Resulting type list after applying the transform function. */ + // NOLINTNEXTLINE(modernize-type-traits) + using type = type_list::type...>; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +using type_list_transform_t = typename type_list_transform::type; + +/** + * @brief A class to use to push around lists of constant values, nothing more. + * @tparam Value Values provided by the value list. + */ +template +struct value_list { + /*! @brief Value list type. */ + using type = value_list; + /*! @brief Compile-time number of elements in the value list. */ + static constexpr auto size = sizeof...(Value); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_element; + +/** + * @brief Provides compile-time indexed access to the values of a value list. + * @tparam Index Index of the value to return. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element> + : value_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element<0u, value_list> { + /*! @brief Searched type. */ + using type = decltype(Value); + /*! @brief Searched value. */ + static constexpr auto value = Value; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Value list to search into. + */ +template +using value_list_element_t = typename value_list_element::type; + +/** + * @brief Helper type. + * @tparam Index Index of the value to return. + * @tparam List Value list to search into. + */ +template +inline constexpr auto value_list_element_v = value_list_element::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_index; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam First First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 1u + value_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + static_assert(value_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +inline constexpr std::size_t value_list_index_v = value_list_index::value; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @return A value list composed by the values of both the value lists. + */ +template +constexpr value_list operator+(value_list, value_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_cat; + +/*! @brief Concatenates multiple value lists. */ +template<> +struct value_list_cat<> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list<>; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @tparam List Other value lists, if any. + */ +template +struct value_list_cat, value_list, List...> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = typename value_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the value list. + */ +template +struct value_list_cat> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list; +}; + +/** + * @brief Helper type. + * @tparam List Value lists to concatenate. + */ +template +using value_list_cat_t = typename value_list_cat::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_unique; + +/** + * @brief Removes duplicates values from a value list. + * @tparam Value One of the values provided by the given value list. + * @tparam Other The other values provided by the given value list. + */ +template +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = std::conditional_t< + ((Value == Other) || ...), + typename value_list_unique>::type, + value_list_cat_t, typename value_list_unique>::type>>; +}; + +/*! @brief Removes duplicates values from a value list. */ +template<> +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = value_list<>; +}; + +/** + * @brief Helper type. + * @tparam Type A value list. + */ +template +using value_list_unique_t = typename value_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a value list contains + * a given value, false otherwise. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +struct value_list_contains; + +/** + * @copybrief value_list_contains + * @tparam Value Values provided by the value list. + * @tparam Other Value to look for. + */ +template +struct value_list_contains, Other> + : std::bool_constant<((Value == Other) || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +inline constexpr bool value_list_contains_v = value_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_diff; + +/** + * @brief Computes the difference between two value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + */ +template +struct value_list_diff, value_list> { + /*! @brief A value list that is the difference between the two value lists. */ + using type = value_list_cat_t, Value>, value_list<>, value_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Value lists between which to compute the difference. + */ +template +using value_list_diff_t = typename value_list_diff::type; + +/*! @brief Same as std::is_invocable, but with tuples. */ +template +struct is_applicable: std::false_type {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @brief Helper variable template. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_v = is_applicable::value; + +/*! @brief Same as std::is_invocable_r, but with tuples for arguments. */ +template +struct is_applicable_r: std::false_type {}; + +/** + * @copybrief is_applicable_r + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +struct is_applicable_r>: std::is_invocable_r {}; + +/** + * @brief Helper variable template. + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_r_v = is_applicable_r::value; + +/** + * @brief Provides the member constant `value` to true if a given type is + * complete, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_complete: std::false_type {}; + +/*! @copydoc is_complete */ +template +struct is_complete>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_complete_v = is_complete::value; + +/** + * @brief Provides the member constant `value` to true if a given type is an + * iterator, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_iterator: std::false_type {}; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_iterator_category: std::false_type {}; + +template +struct has_iterator_category::iterator_category>>: std::true_type {}; + +} // namespace internal +/*! @endcond */ + +/*! @copydoc is_iterator */ +template +struct is_iterator>>>> + : internal::has_iterator_category {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_iterator_v = is_iterator::value; + +/** + * @brief Provides the member constant `value` to true if a given type is both + * an empty and non-final class, false otherwise. + * @tparam Type The type to test + */ +template +struct is_ebco_eligible + : std::bool_constant && !std::is_final_v> {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_ebco_eligible_v = is_ebco_eligible::value; + +/** + * @brief Provides the member constant `value` to true if `Type::is_transparent` + * is valid and denotes a type, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_transparent: std::false_type {}; + +/*! @copydoc is_transparent */ +template +struct is_transparent>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_transparent_v = is_transparent::value; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_tuple_size_value: std::false_type {}; + +template +struct has_tuple_size_value::value)>>: std::true_type {}; + +template +struct has_value_type: std::false_type {}; + +template +struct has_value_type>: std::true_type {}; + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable(); + +template +[[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence) { + return (dispatch_is_equality_comparable>() && ...); +} + +template +[[nodiscard]] constexpr bool maybe_equality_comparable(char) { + return false; +} + +template +[[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval() == std::declval()) { + return true; +} + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable() { + // NOLINTBEGIN(modernize-use-transparent-functors) + if constexpr(std::is_array_v) { + return false; + } else if constexpr(is_complete_v>>) { + if constexpr(has_tuple_size_value::value) { + return maybe_equality_comparable(0) && unpack_maybe_equality_comparable(std::make_index_sequence::value>{}); + } else { + return maybe_equality_comparable(0); + } + } else if constexpr(has_value_type::value) { + if constexpr(is_iterator_v || std::is_same_v || dispatch_is_equality_comparable()) { + return maybe_equality_comparable(0); + } else { + return false; + } + } else { + return maybe_equality_comparable(0); + } + // NOLINTEND(modernize-use-transparent-functors) +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Provides the member constant `value` to true if a given type is + * equality comparable, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_equality_comparable: std::bool_constant()> {}; + +/*! @copydoc is_equality_comparable */ +template +struct is_equality_comparable: is_equality_comparable {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_equality_comparable_v = is_equality_comparable::value; + +/** + * @brief Transcribes the constness of a type to another type. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = std::remove_const_t; +}; + +/*! @copydoc constness_as */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = const To; +}; + +/** + * @brief Alias template to facilitate the transcription of the constness. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +using constness_as_t = typename constness_as::type; + +/** + * @brief Extracts the class of a non-static member object or function. + * @tparam Member A pointer to a non-static member object or function. + */ +template +class member_class { + static_assert(std::is_member_pointer_v, "Invalid pointer type to non-static member object or function"); + + template + static Class *clazz(Ret (Class::*)(Args...)); + + template + static Class *clazz(Ret (Class::*)(Args...) const); + + template + static Class *clazz(Type Class::*); + +public: + /*! @brief The class of the given non-static member object or function. */ + using type = std::remove_pointer_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Member A pointer to a non-static member object or function. + */ +template +using member_class_t = typename member_class::type; + +/** + * @brief Extracts the n-th argument of a _callable_ type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid _callable_ type. + */ +template +class nth_argument { + template + static constexpr type_list pick_up(Ret (*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...) const); + + template + static constexpr type_list pick_up(Type Class ::*); + + template + static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&); + +public: + /*! @brief N-th argument of the _callable_ type. */ + using type = type_list_element_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid function, member function or data member type. + */ +template +using nth_argument_t = typename nth_argument::type; + +} // namespace entt + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::type_list_element> {}; + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::value_list_element> {}; + +#endif + +// #include "fwd.hpp" +#ifndef ENTT_SIGNAL_FWD_HPP +#define ENTT_SIGNAL_FWD_HPP + +#include + +namespace entt { + +template +class delegate; + +template> +class basic_dispatcher; + +template> +class emitter; + +class connection; + +struct scoped_connection; + +template +class sink; + +template> +class sigh; + +/*! @brief Alias declaration for the most common use case. */ +using dispatcher = basic_dispatcher<>; + +/*! @brief Disambiguation tag for constructors and the like. */ +template +struct connect_arg_t { + /*! @brief Default constructor. */ + explicit connect_arg_t() = default; +}; + +/** + * @brief Constant of type connect_arg_t used to disambiguate calls. + * @tparam Candidate Element to connect (likely a free or member function). + */ +template +inline constexpr connect_arg_t connect_arg{}; + +} // namespace entt + +#endif + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +constexpr auto function_pointer(Ret (*)(Args...)) -> Ret (*)(Args...); + +template +constexpr auto function_pointer(Ret (*)(Type, Args...), Other &&) -> Ret (*)(Args...); + +template +constexpr auto function_pointer(Ret (Class::*)(Args...), Other &&...) -> Ret (*)(Args...); + +template +constexpr auto function_pointer(Ret (Class::*)(Args...) const, Other &&...) -> Ret (*)(Args...); + +template>> +constexpr auto function_pointer(Type Class::*, Other &&...) -> Type (*)(); + +template +using function_pointer_t = decltype(function_pointer(std::declval()...)); + +template +[[nodiscard]] constexpr auto index_sequence_for(Ret (*)(Args...)) { + return std::index_sequence_for{}; +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Basic delegate implementation. + * + * Primary template isn't defined on purpose. All the specializations give a + * compile-time error unless the template parameter is a function type. + */ +template +class delegate; + +/** + * @brief Utility class to use to send around functions and members. + * + * Unmanaged delegate for function pointers and members. Users of this class are + * in charge of disconnecting instances before deleting them. + * + * A delegate can be used as a general purpose invoker without memory overhead + * for free functions possibly with payloads and bound or unbound members. + * + * @tparam Ret Return type of a function type. + * @tparam Args Types of arguments of a function type. + */ +template +class delegate { + using return_type = std::remove_const_t; + using delegate_type = return_type(const void *, Args...); + + template + [[nodiscard]] auto wrap(std::index_sequence) noexcept { + return [](const void *, Args... args) -> return_type { + [[maybe_unused]] const auto arguments = std::forward_as_tuple(std::forward(args)...); + [[maybe_unused]] constexpr auto offset = !std::is_invocable_r_v>...> * (sizeof...(Args) - sizeof...(Index)); + return static_cast(std::invoke(Candidate, std::forward>>(std::get(arguments))...)); + }; + } + + template + [[nodiscard]] auto wrap(Type &, std::index_sequence) noexcept { + return [](const void *payload, Args... args) -> return_type { + Type *curr = static_cast(const_cast *>(payload)); + [[maybe_unused]] const auto arguments = std::forward_as_tuple(std::forward(args)...); + [[maybe_unused]] constexpr auto offset = !std::is_invocable_r_v>...> * (sizeof...(Args) - sizeof...(Index)); + return static_cast(std::invoke(Candidate, *curr, std::forward>>(std::get(arguments))...)); + }; + } + + template + [[nodiscard]] auto wrap(Type *, std::index_sequence) noexcept { + return [](const void *payload, Args... args) -> return_type { + Type *curr = static_cast(const_cast *>(payload)); + [[maybe_unused]] const auto arguments = std::forward_as_tuple(std::forward(args)...); + [[maybe_unused]] constexpr auto offset = !std::is_invocable_r_v>...> * (sizeof...(Args) - sizeof...(Index)); + return static_cast(std::invoke(Candidate, curr, std::forward>>(std::get(arguments))...)); + }; + } + +public: + /*! @brief Function type of the contained target. */ + using function_type = Ret(const void *, Args...); + /*! @brief Function type of the delegate. */ + using type = Ret(Args...); + /*! @brief Return type of the delegate. */ + using result_type = Ret; + + /*! @brief Default constructor. */ + delegate() noexcept = default; + + /** + * @brief Constructs a delegate with a given object or payload, if any. + * @tparam Candidate Function or member to connect to the delegate. + * @tparam Type Type of class or type of payload, if any. + * @param value_or_instance Optional valid object that fits the purpose. + */ + template + delegate(connect_arg_t, Type &&...value_or_instance) noexcept { + connect(std::forward(value_or_instance)...); + } + + /** + * @brief Constructs a delegate and connects an user defined function with + * optional payload. + * @param function Function to connect to the delegate. + * @param payload User defined arbitrary data. + */ + delegate(function_type *function, const void *payload = nullptr) noexcept { + connect(function, payload); + } + + /** + * @brief Connects a free function or an unbound member to a delegate. + * @tparam Candidate Function or member to connect to the delegate. + */ + template + void connect() noexcept { + instance = nullptr; + + if constexpr(std::is_invocable_r_v) { + fn = [](const void *, Args... args) -> return_type { + return Ret(std::invoke(Candidate, std::forward(args)...)); + }; + } else if constexpr(std::is_member_pointer_v) { + fn = wrap(internal::index_sequence_for>>(internal::function_pointer_t{})); + } else { + fn = wrap(internal::index_sequence_for(internal::function_pointer_t{})); + } + } + + /** + * @brief Connects a free function with payload or a bound member to a + * delegate. + * + * The delegate isn't responsible for the connected object or the payload. + * Users must always guarantee that the lifetime of the instance overcomes + * the one of the delegate.
+ * When used to connect a free function with payload, its signature must be + * such that the instance is the first argument before the ones used to + * define the delegate itself. + * + * @tparam Candidate Function or member to connect to the delegate. + * @tparam Type Type of class or type of payload. + * @param value_or_instance A valid reference that fits the purpose. + */ + template + void connect(Type &value_or_instance) noexcept { + instance = &value_or_instance; + + if constexpr(std::is_invocable_r_v) { + fn = [](const void *payload, Args... args) -> return_type { + Type *curr = static_cast(const_cast *>(payload)); + return Ret(std::invoke(Candidate, *curr, std::forward(args)...)); + }; + } else { + fn = wrap(value_or_instance, internal::index_sequence_for(internal::function_pointer_t{})); + } + } + + /** + * @brief Connects a free function with payload or a bound member to a + * delegate. + * + * @sa connect(Type &) + * + * @tparam Candidate Function or member to connect to the delegate. + * @tparam Type Type of class or type of payload. + * @param value_or_instance A valid pointer that fits the purpose. + */ + template + void connect(Type *value_or_instance) noexcept { + instance = value_or_instance; + + if constexpr(std::is_invocable_r_v) { + fn = [](const void *payload, Args... args) -> return_type { + Type *curr = static_cast(const_cast *>(payload)); + return Ret(std::invoke(Candidate, curr, std::forward(args)...)); + }; + } else { + fn = wrap(value_or_instance, internal::index_sequence_for(internal::function_pointer_t{})); + } + } + + /** + * @brief Connects an user defined function with optional payload to a + * delegate. + * + * The delegate isn't responsible for the connected object or the payload. + * Users must always guarantee that the lifetime of an instance overcomes + * the one of the delegate.
+ * The payload is returned as the first argument to the target function in + * all cases. + * + * @param function Function to connect to the delegate. + * @param payload User defined arbitrary data. + */ + void connect(function_type *function, const void *payload = nullptr) noexcept { + ENTT_ASSERT(function != nullptr, "Uninitialized function pointer"); + instance = payload; + fn = function; + } + + /** + * @brief Resets a delegate. + * + * After a reset, a delegate cannot be invoked anymore. + */ + void reset() noexcept { + instance = nullptr; + fn = nullptr; + } + + /** + * @brief Returns a pointer to the stored callable function target, if any. + * @return An opaque pointer to the stored callable function target. + */ + [[nodiscard]] function_type *target() const noexcept { + return fn; + } + + /** + * @brief Returns the instance or the payload linked to a delegate, if any. + * @return An opaque pointer to the underlying data. + */ + [[nodiscard]] const void *data() const noexcept { + return instance; + } + + /** + * @brief Triggers a delegate. + * + * The delegate invokes the underlying function and returns the result. + * + * @warning + * Attempting to trigger an invalid delegate results in undefined + * behavior. + * + * @param args Arguments to use to invoke the underlying function. + * @return The value returned by the underlying function. + */ + Ret operator()(Args... args) const { + ENTT_ASSERT(static_cast(*this), "Uninitialized delegate"); + return fn(instance, std::forward(args)...); + } + + /** + * @brief Checks whether a delegate actually stores a listener. + * @return False if the delegate is empty, true otherwise. + */ + [[nodiscard]] explicit operator bool() const noexcept { + // no need to also test instance + return !(fn == nullptr); + } + + /** + * @brief Compares the contents of two delegates. + * @param other Delegate with which to compare. + * @return False if the two contents differ, true otherwise. + */ + [[nodiscard]] bool operator==(const delegate &other) const noexcept { + return fn == other.fn && instance == other.instance; + } + +private: + const void *instance{}; + delegate_type *fn{}; +}; + +/** + * @brief Compares the contents of two delegates. + * @tparam Ret Return type of a function type. + * @tparam Args Types of arguments of a function type. + * @param lhs A valid delegate object. + * @param rhs A valid delegate object. + * @return True if the two contents differ, false otherwise. + */ +template +[[nodiscard]] bool operator!=(const delegate &lhs, const delegate &rhs) noexcept { + return !(lhs == rhs); +} + +/** + * @brief Deduction guide. + * @tparam Candidate Function or member to connect to the delegate. + */ +template +delegate(connect_arg_t) -> delegate>>; + +/** + * @brief Deduction guide. + * @tparam Candidate Function or member to connect to the delegate. + * @tparam Type Type of class or type of payload. + */ +template +delegate(connect_arg_t, Type &&) -> delegate>>; + +/** + * @brief Deduction guide. + * @tparam Ret Return type of a function type. + * @tparam Args Types of arguments of a function type. + */ +template +delegate(Ret (*)(const void *, Args...), const void * = nullptr) -> delegate; + +} // namespace entt + +#endif + +// #include "fwd.hpp" + + +namespace entt { + +/** + * @brief Sink class. + * + * Primary template isn't defined on purpose. All the specializations give a + * compile-time error unless the template parameter is a function type. + * + * @tparam Type A valid signal handler type. + */ +template +class sink; + +/** + * @brief Unmanaged signal handler. + * + * Primary template isn't defined on purpose. All the specializations give a + * compile-time error unless the template parameter is a function type. + * + * @tparam Type A valid function type. + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +class sigh; + +/** + * @brief Unmanaged signal handler. + * + * It works directly with references to classes and pointers to member functions + * as well as pointers to free functions. Users of this class are in charge of + * disconnecting instances before deleting them. + * + * This class serves mainly two purposes: + * + * * Creating signals to use later to notify a bunch of listeners. + * * Collecting results from a set of functions like in a voting system. + * + * @tparam Ret Return type of a function type. + * @tparam Args Types of arguments of a function type. + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +class sigh { + friend class sink>; + + using alloc_traits = std::allocator_traits; + using delegate_type = delegate; + using container_type = std::vector>; + +public: + /*! @brief Allocator type. */ + using allocator_type = Allocator; + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + /*! @brief Sink type. */ + using sink_type = sink>; + + /*! @brief Default constructor. */ + sigh() noexcept(noexcept(allocator_type{})) + : sigh{allocator_type{}} {} + + /** + * @brief Constructs a signal handler with a given allocator. + * @param allocator The allocator to use. + */ + explicit sigh(const allocator_type &allocator) noexcept + : calls{allocator} {} + + /** + * @brief Copy constructor. + * @param other The instance to copy from. + */ + sigh(const sigh &other) + : calls{other.calls} {} + + /** + * @brief Allocator-extended copy constructor. + * @param other The instance to copy from. + * @param allocator The allocator to use. + */ + sigh(const sigh &other, const allocator_type &allocator) + : calls{other.calls, allocator} {} + + /** + * @brief Move constructor. + * @param other The instance to move from. + */ + sigh(sigh &&other) noexcept + : calls{std::move(other.calls)} {} + + /** + * @brief Allocator-extended move constructor. + * @param other The instance to move from. + * @param allocator The allocator to use. + */ + sigh(sigh &&other, const allocator_type &allocator) + : calls{std::move(other.calls), allocator} {} + + /*! @brief Default destructor. */ + ~sigh() = default; + + /** + * @brief Copy assignment operator. + * @param other The instance to copy from. + * @return This signal handler. + */ + sigh &operator=(const sigh &other) { + calls = other.calls; + return *this; + } + + /** + * @brief Move assignment operator. + * @param other The instance to move from. + * @return This signal handler. + */ + sigh &operator=(sigh &&other) noexcept { + swap(other); + return *this; + } + + /** + * @brief Exchanges the contents with those of a given signal handler. + * @param other Signal handler to exchange the content with. + */ + void swap(sigh &other) noexcept { + using std::swap; + swap(calls, other.calls); + } + + /** + * @brief Returns the associated allocator. + * @return The associated allocator. + */ + [[nodiscard]] constexpr allocator_type get_allocator() const noexcept { + return calls.get_allocator(); + } + + /** + * @brief Number of listeners connected to the signal. + * @return Number of listeners currently connected. + */ + [[nodiscard]] size_type size() const noexcept { + return calls.size(); + } + + /** + * @brief Returns false if at least a listener is connected to the signal. + * @return True if the signal has no listeners connected, false otherwise. + */ + [[nodiscard]] bool empty() const noexcept { + return calls.empty(); + } + + /** + * @brief Triggers a signal. + * + * All the listeners are notified. Order isn't guaranteed. + * + * @param args Arguments to use to invoke listeners. + */ + void publish(Args... args) const { + for(auto pos = calls.size(); pos; --pos) { + calls[pos - 1u](args...); + } + } + + /** + * @brief Collects return values from the listeners. + * + * The collector must expose a call operator with the following properties: + * + * * The return type is either `void` or such that it's convertible to + * `bool`. In the second case, a true value will stop the iteration. + * * The list of parameters is empty if `Ret` is `void`, otherwise it + * contains a single element such that `Ret` is convertible to it. + * + * @tparam Func Type of collector to use, if any. + * @param func A valid function object. + * @param args Arguments to use to invoke listeners. + */ + template + void collect(Func func, Args... args) const { + for(auto pos = calls.size(); pos; --pos) { + if constexpr(std::is_void_v || !std::is_invocable_v) { + calls[pos - 1u](args...); + + if constexpr(std::is_invocable_r_v) { + if(func()) { + break; + } + } else { + func(); + } + } else { + if constexpr(std::is_invocable_r_v) { + if(func(calls[pos - 1u](args...))) { + break; + } + } else { + func(calls[pos - 1u](args...)); + } + } + } + } + +private: + container_type calls; +}; + +/** + * @brief Connection class. + * + * Opaque object the aim of which is to allow users to release an already + * estabilished connection without having to keep a reference to the signal or + * the sink that generated it. + */ +class connection { + template + friend class sink; + + connection(delegate fn, void *ref) + : disconnect{fn}, signal{ref} {} + +public: + /*! @brief Default constructor. */ + connection() + : signal{} {} + + /** + * @brief Checks whether a connection is properly initialized. + * @return True if the connection is properly initialized, false otherwise. + */ + [[nodiscard]] explicit operator bool() const noexcept { + return static_cast(disconnect); + } + + /*! @brief Breaks the connection. */ + void release() { + if(disconnect) { + disconnect(signal); + disconnect.reset(); + } + } + +private: + delegate disconnect; + void *signal; +}; + +/** + * @brief Scoped connection class. + * + * Opaque object the aim of which is to allow users to release an already + * estabilished connection without having to keep a reference to the signal or + * the sink that generated it.
+ * A scoped connection automatically breaks the link between the two objects + * when it goes out of scope. + */ +struct scoped_connection { + /*! @brief Default constructor. */ + scoped_connection() = default; + + /** + * @brief Constructs a scoped connection from a basic connection. + * @param other A valid connection object. + */ + scoped_connection(const connection &other) + : conn{other} {} + + /*! @brief Default copy constructor, deleted on purpose. */ + scoped_connection(const scoped_connection &) = delete; + + /** + * @brief Move constructor. + * @param other The scoped connection to move from. + */ + scoped_connection(scoped_connection &&other) noexcept + : conn{std::exchange(other.conn, {})} {} + + /*! @brief Automatically breaks the link on destruction. */ + ~scoped_connection() { + conn.release(); + } + + /** + * @brief Default copy assignment operator, deleted on purpose. + * @return This scoped connection. + */ + scoped_connection &operator=(const scoped_connection &) = delete; + + /** + * @brief Move assignment operator. + * @param other The scoped connection to move from. + * @return This scoped connection. + */ + scoped_connection &operator=(scoped_connection &&other) noexcept { + conn = std::exchange(other.conn, {}); + return *this; + } + + /** + * @brief Acquires a connection. + * @param other The connection object to acquire. + * @return This scoped connection. + */ + scoped_connection &operator=(connection other) { + conn = other; + return *this; + } + + /** + * @brief Checks whether a scoped connection is properly initialized. + * @return True if the connection is properly initialized, false otherwise. + */ + [[nodiscard]] explicit operator bool() const noexcept { + return static_cast(conn); + } + + /*! @brief Breaks the connection. */ + void release() { + conn.release(); + } + +private: + connection conn; +}; + +/** + * @brief Sink class. + * + * A sink is used to connect listeners to signals and to disconnect them.
+ * The function type for a listener is the one of the signal to which it + * belongs. + * + * The clear separation between a signal and a sink permits to store the former + * as private data member without exposing the publish functionality to the + * users of the class. + * + * @warning + * Lifetime of a sink must not overcome that of the signal to which it refers. + * In any other case, attempting to use a sink results in undefined behavior. + * + * @tparam Ret Return type of a function type. + * @tparam Args Types of arguments of a function type. + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +class sink> { + using signal_type = sigh; + using delegate_type = typename signal_type::delegate_type; + using difference_type = typename signal_type::container_type::difference_type; + + template + static void release(Type value_or_instance, void *signal) { + sink{*static_cast(signal)}.disconnect(value_or_instance); + } + + template + static void release(void *signal) { + sink{*static_cast(signal)}.disconnect(); + } + + template + void disconnect_if(Func callback) { + auto &ref = signal_or_assert(); + + for(auto pos = ref.calls.size(); pos; --pos) { + if(auto &elem = ref.calls[pos - 1u]; callback(elem)) { + elem = std::move(ref.calls.back()); + ref.calls.pop_back(); + } + } + } + + [[nodiscard]] auto &signal_or_assert() const noexcept { + ENTT_ASSERT(signal != nullptr, "Invalid pointer to signal"); + return *signal; + } + +public: + /*! @brief Constructs an invalid sink. */ + sink() noexcept + : signal{} {} + + /** + * @brief Constructs a sink that is allowed to modify a given signal. + * @param ref A valid reference to a signal object. + */ + sink(sigh &ref) noexcept + : signal{&ref} {} + + /** + * @brief Returns false if at least a listener is connected to the sink. + * @return True if the sink has no listeners connected, false otherwise. + */ + [[nodiscard]] bool empty() const noexcept { + return signal_or_assert().calls.empty(); + } + + /** + * @brief Connects a free function or an unbound member to a signal. + * @tparam Candidate Function or member to connect to the signal. + * @return A properly initialized connection object. + */ + template + connection connect() { + disconnect(); + + delegate_type call{}; + call.template connect(); + signal_or_assert().calls.push_back(std::move(call)); + + delegate conn{}; + conn.template connect<&release>(); + return {conn, signal}; + } + + /** + * @brief Connects a free function with payload or a bound member to a + * signal. + * + * The signal isn't responsible for the connected object or the payload. + * Users must always guarantee that the lifetime of the instance overcomes + * the one of the signal.
+ * When used to connect a free function with payload, its signature must be + * such that the instance is the first argument before the ones used to + * define the signal itself. + * + * @tparam Candidate Function or member to connect to the signal. + * @tparam Type Type of class or type of payload. + * @param value_or_instance A valid reference that fits the purpose. + * @return A properly initialized connection object. + */ + template + connection connect(Type &value_or_instance) { + disconnect(value_or_instance); + + delegate_type call{}; + call.template connect(value_or_instance); + signal_or_assert().calls.push_back(std::move(call)); + + delegate conn{}; + conn.template connect<&release>(value_or_instance); + return {conn, signal}; + } + + /** + * @brief Connects a free function with payload or a bound member to a + * signal. + * + * @sa connect(Type &) + * + * @tparam Candidate Function or member to connect to the signal. + * @tparam Type Type of class or type of payload. + * @param value_or_instance A valid pointer that fits the purpose. + * @return A properly initialized connection object. + */ + template + connection connect(Type *value_or_instance) { + disconnect(value_or_instance); + + delegate_type call{}; + call.template connect(value_or_instance); + signal_or_assert().calls.push_back(std::move(call)); + + delegate conn{}; + conn.template connect<&release>(value_or_instance); + return {conn, signal}; + } + + /** + * @brief Disconnects a free function or an unbound member from a signal. + * @tparam Candidate Function or member to disconnect from the signal. + */ + template + void disconnect() { + delegate_type call{}; + call.template connect(); + disconnect_if([&call](const auto &elem) { return elem == call; }); + } + + /** + * @brief Disconnects a free function with payload or a bound member from a + * signal. + * + * The signal isn't responsible for the connected object or the payload. + * Users must always guarantee that the lifetime of the instance overcomes + * the one of the signal.
+ * When used to connect a free function with payload, its signature must be + * such that the instance is the first argument before the ones used to + * define the signal itself. + * + * @tparam Candidate Function or member to disconnect from the signal. + * @tparam Type Type of class or type of payload, if any. + * @param value_or_instance A valid reference that fits the purpose. + */ + template + void disconnect(Type &value_or_instance) { + delegate_type call{}; + call.template connect(value_or_instance); + disconnect_if([&call](const auto &elem) { return elem == call; }); + } + + /** + * @brief Disconnects a free function with payload or a bound member from a + * signal. + * + * @sa disconnect(Type &) + * + * @tparam Candidate Function or member to disconnect from the signal. + * @tparam Type Type of class or type of payload, if any. + * @param value_or_instance A valid pointer that fits the purpose. + */ + template + void disconnect(Type *value_or_instance) { + delegate_type call{}; + call.template connect(value_or_instance); + disconnect_if([&call](const auto &elem) { return elem == call; }); + } + + /** + * @brief Disconnects free functions with payload or bound members from a + * signal. + * @param value_or_instance A valid object that fits the purpose. + */ + void disconnect(const void *value_or_instance) { + ENTT_ASSERT(value_or_instance != nullptr, "Invalid value or instance"); + disconnect_if([value_or_instance](const auto &elem) { return elem.data() == value_or_instance; }); + } + + /*! @brief Disconnects all the listeners from a signal. */ + void disconnect() { + signal_or_assert().calls.clear(); + } + + /** + * @brief Returns true if a sink is correctly initialized, false otherwise. + * @return True if a sink is correctly initialized, false otherwise. + */ + [[nodiscard]] explicit operator bool() const noexcept { + return signal != nullptr; + } + +private: + signal_type *signal; +}; + +/** + * @brief Deduction guide. + * + * It allows to deduce the signal handler type of a sink directly from the + * signal it refers to. + * + * @tparam Ret Return type of a function type. + * @tparam Args Types of arguments of a function type. + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +sink(sigh &) -> sink>; + +} // namespace entt + +#endif + +// #include "entity.hpp" + +// #include "fwd.hpp" + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_on_construct final: std::false_type {}; + +template +struct has_on_construct(), std::declval().create()))>> + : std::true_type {}; + +template +struct has_on_update final: std::false_type {}; + +template +struct has_on_update(), std::declval().create()))>> + : std::true_type {}; + +template +struct has_on_destroy final: std::false_type {}; + +template +struct has_on_destroy(), std::declval().create()))>> + : std::true_type {}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Mixin type used to add signal support to storage types. + * + * The function type of a listener is equivalent to: + * + * @code{.cpp} + * void(basic_registry &, entity_type); + * @endcode + * + * This applies to all signals made available. + * + * @tparam Type Underlying storage type. + * @tparam Registry Basic registry type. + */ +template +class basic_sigh_mixin final: public Type { + using underlying_type = Type; + using owner_type = Registry; + + using basic_registry_type = basic_registry; + using sigh_type = sigh; + using underlying_iterator = typename underlying_type::base_type::basic_iterator; + + static_assert(std::is_base_of_v, "Invalid registry type"); + + [[nodiscard]] auto &owner_or_assert() const noexcept { + ENTT_ASSERT(owner != nullptr, "Invalid pointer to registry"); + return static_cast(*owner); + } + +private: + void pop(underlying_iterator first, underlying_iterator last) final { + if(auto ® = owner_or_assert(); destruction.empty()) { + underlying_type::pop(first, last); + } else { + for(; first != last; ++first) { + const auto entt = *first; + destruction.publish(reg, entt); + const auto it = underlying_type::find(entt); + underlying_type::pop(it, it + 1u); + } + } + } + + void pop_all() final { + if(auto ® = owner_or_assert(); !destruction.empty()) { + if constexpr(std::is_same_v) { + for(typename underlying_type::size_type pos{}, last = underlying_type::free_list(); pos < last; ++pos) { + destruction.publish(reg, underlying_type::base_type::operator[](pos)); + } + } else { + for(auto entt: static_cast(*this)) { + if constexpr(underlying_type::storage_policy == deletion_policy::in_place) { + if(entt != tombstone) { + destruction.publish(reg, entt); + } + } else { + destruction.publish(reg, entt); + } + } + } + } + + underlying_type::pop_all(); + } + + underlying_iterator try_emplace(const typename underlying_type::entity_type entt, const bool force_back, const void *value) final { + const auto it = underlying_type::try_emplace(entt, force_back, value); + + if(auto ® = owner_or_assert(); it != underlying_type::base_type::end()) { + construction.publish(reg, *it); + } + + return it; + } + + void bind_any(any value) noexcept final { + owner = any_cast(&value); + + if constexpr(!std::is_same_v) { + if(owner == nullptr) { + owner = any_cast(&value); + } + } + + underlying_type::bind_any(std::move(value)); + } + +public: + /*! @brief Allocator type. */ + using allocator_type = typename underlying_type::allocator_type; + /*! @brief Underlying entity identifier. */ + using entity_type = typename underlying_type::entity_type; + /*! @brief Expected registry type. */ + using registry_type = owner_type; + + /*! @brief Default constructor. */ + basic_sigh_mixin() + : basic_sigh_mixin{allocator_type{}} {} + + /** + * @brief Constructs an empty storage with a given allocator. + * @param allocator The allocator to use. + */ + explicit basic_sigh_mixin(const allocator_type &allocator) + : underlying_type{allocator}, + owner{}, + construction{allocator}, + destruction{allocator}, + update{allocator} { + if constexpr(internal::has_on_construct::value) { + sink{construction}.template connect<&underlying_type::element_type::on_construct>(); + } + + if constexpr(internal::has_on_update::value) { + sink{update}.template connect<&underlying_type::element_type::on_update>(); + } + + if constexpr(internal::has_on_destroy::value) { + sink{destruction}.template connect<&underlying_type::element_type::on_destroy>(); + } + } + + /*! @brief Default copy constructor, deleted on purpose. */ + basic_sigh_mixin(const basic_sigh_mixin &) = delete; + + /** + * @brief Move constructor. + * @param other The instance to move from. + */ + basic_sigh_mixin(basic_sigh_mixin &&other) noexcept + : underlying_type{static_cast(other)}, + owner{other.owner}, + construction{std::move(other.construction)}, + destruction{std::move(other.destruction)}, + update{std::move(other.update)} {} + + /** + * @brief Allocator-extended move constructor. + * @param other The instance to move from. + * @param allocator The allocator to use. + */ + basic_sigh_mixin(basic_sigh_mixin &&other, const allocator_type &allocator) + : underlying_type{static_cast(other), allocator}, + owner{other.owner}, + construction{std::move(other.construction), allocator}, + destruction{std::move(other.destruction), allocator}, + update{std::move(other.update), allocator} {} + + /*! @brief Default destructor. */ + ~basic_sigh_mixin() override = default; + + /** + * @brief Default copy assignment operator, deleted on purpose. + * @return This mixin. + */ + basic_sigh_mixin &operator=(const basic_sigh_mixin &) = delete; + + /** + * @brief Move assignment operator. + * @param other The instance to move from. + * @return This mixin. + */ + basic_sigh_mixin &operator=(basic_sigh_mixin &&other) noexcept { + swap(other); + return *this; + } + + /** + * @brief Exchanges the contents with those of a given storage. + * @param other Storage to exchange the content with. + */ + void swap(basic_sigh_mixin &other) noexcept { + using std::swap; + swap(owner, other.owner); + swap(construction, other.construction); + swap(destruction, other.destruction); + swap(update, other.update); + underlying_type::swap(other); + } + + /** + * @brief Returns a sink object. + * + * The sink returned by this function can be used to receive notifications + * whenever a new instance is created and assigned to an entity.
+ * Listeners are invoked after the object has been assigned to the entity. + * + * @sa sink + * + * @return A temporary sink object. + */ + [[nodiscard]] auto on_construct() noexcept { + return sink{construction}; + } + + /** + * @brief Returns a sink object. + * + * The sink returned by this function can be used to receive notifications + * whenever an instance is explicitly updated.
+ * Listeners are invoked after the object has been updated. + * + * @sa sink + * + * @return A temporary sink object. + */ + [[nodiscard]] auto on_update() noexcept { + return sink{update}; + } + + /** + * @brief Returns a sink object. + * + * The sink returned by this function can be used to receive notifications + * whenever an instance is removed from an entity and thus destroyed.
+ * Listeners are invoked before the object has been removed from the entity. + * + * @sa sink + * + * @return A temporary sink object. + */ + [[nodiscard]] auto on_destroy() noexcept { + return sink{destruction}; + } + + /** + * @brief Checks if a mixin refers to a valid registry. + * @return True if the mixin refers to a valid registry, false otherwise. + */ + [[nodiscard]] explicit operator bool() const noexcept { + return (owner != nullptr); + } + + /** + * @brief Returns a pointer to the underlying registry, if any. + * @return A pointer to the underlying registry, if any. + */ + [[nodiscard]] const registry_type ®istry() const noexcept { + return owner_or_assert(); + } + + /*! @copydoc registry */ + [[nodiscard]] registry_type ®istry() noexcept { + return owner_or_assert(); + } + + /** + * @brief Creates a new identifier or recycles a destroyed one. + * @return A valid identifier. + */ + auto generate() { + const auto entt = underlying_type::generate(); + construction.publish(owner_or_assert(), entt); + return entt; + } + + /** + * @brief Creates a new identifier or recycles a destroyed one. + * @param hint Required identifier. + * @return A valid identifier. + */ + entity_type generate(const entity_type hint) { + const auto entt = underlying_type::generate(hint); + construction.publish(owner_or_assert(), entt); + return entt; + } + + /** + * @brief Assigns each element in a range an identifier. + * @tparam It Type of mutable forward iterator. + * @param first An iterator to the first element of the range to generate. + * @param last An iterator past the last element of the range to generate. + */ + template + void generate(It first, It last) { + underlying_type::generate(first, last); + + if(auto ® = owner_or_assert(); !construction.empty()) { + for(; first != last; ++first) { + construction.publish(reg, *first); + } + } + } + + /** + * @brief Assigns an entity to a storage and constructs its object. + * @tparam Args Types of arguments to forward to the underlying storage. + * @param entt A valid identifier. + * @param args Parameters to forward to the underlying storage. + * @return A reference to the newly created object. + */ + template + decltype(auto) emplace(const entity_type entt, Args &&...args) { + underlying_type::emplace(entt, std::forward(args)...); + construction.publish(owner_or_assert(), entt); + return this->get(entt); + } + + /** + * @brief Updates the instance assigned to a given entity in-place. + * @tparam Func Types of the function objects to invoke. + * @param entt A valid identifier. + * @param func Valid function objects. + * @return A reference to the patched instance. + */ + template + decltype(auto) patch(const entity_type entt, Func &&...func) { + underlying_type::patch(entt, std::forward(func)...); + update.publish(owner_or_assert(), entt); + return this->get(entt); + } + + /** + * @brief Assigns one or more entities to a storage and constructs their + * objects from a given instance. + * @tparam It Type of input iterator. + * @tparam Args Types of arguments to forward to the underlying storage. + * @param first An iterator to the first element of the range of entities. + * @param last An iterator past the last element of the range of entities. + * @param args Parameters to use to forward to the underlying storage. + */ + template + void insert(It first, It last, Args &&...args) { + auto from = underlying_type::size(); + underlying_type::insert(first, last, std::forward(args)...); + + if(auto ® = owner_or_assert(); !construction.empty()) { + // fine as long as insert passes force_back true to try_emplace + for(const auto to = underlying_type::size(); from != to; ++from) { + construction.publish(reg, underlying_type::operator[](from)); + } + } + } + +private: + basic_registry_type *owner; + sigh_type construction; + sigh_type destruction; + sigh_type update; +}; + +/** + * @brief Mixin type used to add _reactive_ support to storage types. + * @tparam Type Underlying storage type. + * @tparam Registry Basic registry type. + */ +template +class basic_reactive_mixin final: public Type { + using underlying_type = Type; + using owner_type = Registry; + + using alloc_traits = std::allocator_traits; + using basic_registry_type = basic_registry; + using container_type = std::vector>; + + static_assert(std::is_base_of_v, "Invalid registry type"); + + [[nodiscard]] auto &owner_or_assert() const noexcept { + ENTT_ASSERT(owner != nullptr, "Invalid pointer to registry"); + return static_cast(*owner); + } + + void emplace_element(const Registry &, typename underlying_type::entity_type entity) { + if(!underlying_type::contains(entity)) { + underlying_type::emplace(entity); + } + } + +private: + void bind_any(any value) noexcept final { + owner = any_cast(&value); + + if constexpr(!std::is_same_v) { + if(owner == nullptr) { + owner = any_cast(&value); + } + } + + underlying_type::bind_any(std::move(value)); + } + +public: + /*! @brief Allocator type. */ + using allocator_type = typename underlying_type::allocator_type; + /*! @brief Underlying entity identifier. */ + using entity_type = typename underlying_type::entity_type; + /*! @brief Expected registry type. */ + using registry_type = owner_type; + + /*! @brief Default constructor. */ + basic_reactive_mixin() + : basic_reactive_mixin{allocator_type{}} {} + + /** + * @brief Constructs an empty storage with a given allocator. + * @param allocator The allocator to use. + */ + explicit basic_reactive_mixin(const allocator_type &allocator) + : underlying_type{allocator}, + owner{}, + conn{allocator} { + } + + /*! @brief Default copy constructor, deleted on purpose. */ + basic_reactive_mixin(const basic_reactive_mixin &) = delete; + + /** + * @brief Move constructor. + * @param other The instance to move from. + */ + basic_reactive_mixin(basic_reactive_mixin &&other) noexcept + : underlying_type{static_cast(other)}, + owner{other.owner}, + conn{std::move(other.conn)} { + } + + /** + * @brief Allocator-extended move constructor. + * @param other The instance to move from. + * @param allocator The allocator to use. + */ + basic_reactive_mixin(basic_reactive_mixin &&other, const allocator_type &allocator) + : underlying_type{static_cast(other), allocator}, + owner{other.owner}, + conn{std::move(other.conn), allocator} { + } + + /*! @brief Default destructor. */ + ~basic_reactive_mixin() override = default; + + /** + * @brief Default copy assignment operator, deleted on purpose. + * @return This mixin. + */ + basic_reactive_mixin &operator=(const basic_reactive_mixin &) = delete; + + /** + * @brief Move assignment operator. + * @param other The instance to move from. + * @return This mixin. + */ + basic_reactive_mixin &operator=(basic_reactive_mixin &&other) noexcept { + underlying_type::swap(other); + return *this; + } + + /** + * @brief Makes storage _react_ to creation of objects of the given type. + * @tparam Clazz Type of element to _react_ to. + * @tparam Candidate Function to use to _react_ to the event. + * @param id Optional name used to map the storage within the registry. + * @return This mixin. + */ + template + basic_reactive_mixin &on_construct(const id_type id = type_hash::value()) { + auto curr = owner_or_assert().template storage(id).on_construct().template connect(*this); + conn.push_back(std::move(curr)); + return *this; + } + + /** + * @brief Makes storage _react_ to update of objects of the given type. + * @tparam Clazz Type of element to _react_ to. + * @tparam Candidate Function to use to _react_ to the event. + * @param id Optional name used to map the storage within the registry. + * @return This mixin. + */ + template + basic_reactive_mixin &on_update(const id_type id = type_hash::value()) { + auto curr = owner_or_assert().template storage(id).on_update().template connect(*this); + conn.push_back(std::move(curr)); + return *this; + } + + /** + * @brief Makes storage _react_ to destruction of objects of the given type. + * @tparam Clazz Type of element to _react_ to. + * @tparam Candidate Function to use to _react_ to the event. + * @param id Optional name used to map the storage within the registry. + * @return This mixin. + */ + template + basic_reactive_mixin &on_destroy(const id_type id = type_hash::value()) { + auto curr = owner_or_assert().template storage(id).on_destroy().template connect(*this); + conn.push_back(std::move(curr)); + return *this; + } + + /** + * @brief Checks if a mixin refers to a valid registry. + * @return True if the mixin refers to a valid registry, false otherwise. + */ + [[nodiscard]] explicit operator bool() const noexcept { + return (owner != nullptr); + } + + /** + * @brief Returns a pointer to the underlying registry, if any. + * @return A pointer to the underlying registry, if any. + */ + [[nodiscard]] const registry_type ®istry() const noexcept { + return owner_or_assert(); + } + + /*! @copydoc registry */ + [[nodiscard]] registry_type ®istry() noexcept { + return owner_or_assert(); + } + + /** + * @brief Returns a view that is filtered by the underlying storage. + * @tparam Get Types of elements used to construct the view. + * @tparam Exclude Types of elements used to filter the view. + * @return A newly created view. + */ + template + [[nodiscard]] basic_view...>, exclude_t...>> + view(exclude_t = exclude_t{}) const { + const owner_type &parent = owner_or_assert(); + basic_view...>, exclude_t...>> elem{}; + [&elem](const auto *...curr) { ((curr ? elem.storage(*curr) : void()), ...); }(parent.template storage>()..., parent.template storage>()..., this); + return elem; + } + + /*! @copydoc view */ + template + [[nodiscard]] basic_view...>, exclude_t...>> + view(exclude_t = exclude_t{}) { + std::conditional_t<((std::is_const_v && ...) && (std::is_const_v && ...)), const owner_type, owner_type> &parent = owner_or_assert(); + return {*this, parent.template storage>()..., parent.template storage>()...}; + } + + /*! @brief Releases all connections to the underlying registry, if any. */ + void reset() { + for(auto &&curr: conn) { + curr.release(); + } + + conn.clear(); + } + +private: + basic_registry_type *owner; + container_type conn; +}; + +} // namespace entt + +#endif + +// #include "entity/organizer.hpp" +#ifndef ENTT_ENTITY_ORGANIZER_HPP +#define ENTT_ENTITY_ORGANIZER_HPP + +#include +#include +#include +#include +// #include "../core/type_info.hpp" + +// #include "../core/type_traits.hpp" + +// #include "../core/utility.hpp" +#ifndef ENTT_CORE_UTILITY_HPP +#define ENTT_CORE_UTILITY_HPP + +#include +#include + +namespace entt { + +/*! @brief Identity function object (waiting for C++20). */ +struct identity { + /*! @brief Indicates that this is a transparent function object. */ + using is_transparent = void; + + /** + * @brief Returns its argument unchanged. + * @tparam Type Type of the argument. + * @param value The actual argument. + * @return The submitted value as-is. + */ + template + [[nodiscard]] constexpr Type &&operator()(Type &&value) const noexcept { + return std::forward(value); + } +}; + +/** + * @brief Constant utility to disambiguate overloaded members of a class. + * @tparam Type Type of the desired overload. + * @tparam Class Type of class to which the member belongs. + * @param member A valid pointer to a member. + * @return Pointer to the member. + */ +template +[[nodiscard]] constexpr auto overload(Type Class::*member) noexcept { + return member; +} + +/** + * @brief Constant utility to disambiguate overloaded functions. + * @tparam Func Function type of the desired overload. + * @param func A valid pointer to a function. + * @return Pointer to the function. + */ +template +[[nodiscard]] constexpr auto overload(Func *func) noexcept { + return func; +} + +/** + * @brief Helper type for visitors. + * @tparam Func Types of function objects. + */ +template +struct overloaded: Func... { + using Func::operator()...; +}; + +/** + * @brief Deduction guide. + * @tparam Func Types of function objects. + */ +template +overloaded(Func...) -> overloaded; + +/** + * @brief Basic implementation of a y-combinator. + * @tparam Func Type of a potentially recursive function. + */ +template +struct y_combinator { + /** + * @brief Constructs a y-combinator from a given function. + * @param recursive A potentially recursive function. + */ + constexpr y_combinator(Func recursive) noexcept(std::is_nothrow_move_constructible_v) + : func{std::move(recursive)} {} + + /** + * @brief Invokes a y-combinator and therefore its underlying function. + * @tparam Args Types of arguments to use to invoke the underlying function. + * @param args Parameters to use to invoke the underlying function. + * @return Return value of the underlying function, if any. + */ + template + constexpr decltype(auto) operator()(Args &&...args) const noexcept(std::is_nothrow_invocable_v) { + return func(*this, std::forward(args)...); + } + + /*! @copydoc operator()() */ + template + constexpr decltype(auto) operator()(Args &&...args) noexcept(std::is_nothrow_invocable_v) { + return func(*this, std::forward(args)...); + } + +private: + Func func; +}; + +} // namespace entt + +#endif + +// #include "../graph/adjacency_matrix.hpp" +#ifndef ENTT_GRAPH_ADJACENCY_MATRIX_HPP +#define ENTT_GRAPH_ADJACENCY_MATRIX_HPP + +#include +#include +#include +#include +#include +#include +// #include "../config/config.h" +#ifndef ENTT_CONFIG_CONFIG_H +#define ENTT_CONFIG_CONFIG_H + +// #include "version.h" +#ifndef ENTT_CONFIG_VERSION_H +#define ENTT_CONFIG_VERSION_H + +// #include "macro.h" +#ifndef ENTT_CONFIG_MACRO_H +#define ENTT_CONFIG_MACRO_H + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#define ENTT_STR(arg) #arg +#define ENTT_XSTR(arg) ENTT_STR(arg) + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*) + +#define ENTT_VERSION_MAJOR 3 +#define ENTT_VERSION_MINOR 16 +#define ENTT_VERSION_PATCH 0 + +#define ENTT_VERSION \ + ENTT_XSTR(ENTT_VERSION_MAJOR) \ + "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH) + +// NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION) +# define ENTT_CONSTEXPR +# define ENTT_THROW throw +# define ENTT_TRY try +# define ENTT_CATCH catch(...) +#else +# define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20) +# define ENTT_THROW +# define ENTT_TRY if(true) +# define ENTT_CATCH if(false) +#endif + +#if __has_include() +# include +# +# if defined(__cpp_consteval) +# define ENTT_CONSTEVAL consteval +# endif +#endif + +#ifndef ENTT_CONSTEVAL +# define ENTT_CONSTEVAL constexpr +#endif + +#ifdef ENTT_USE_ATOMIC +# include +# define ENTT_MAYBE_ATOMIC(Type) std::atomic +#else +# define ENTT_MAYBE_ATOMIC(Type) Type +#endif + +#ifndef ENTT_ID_TYPE +# include +# define ENTT_ID_TYPE std::uint32_t +#else +# include // provides coverage for types in the std namespace +#endif + +#ifndef ENTT_SPARSE_PAGE +# define ENTT_SPARSE_PAGE 4096 +#endif + +#ifndef ENTT_PACKED_PAGE +# define ENTT_PACKED_PAGE 1024 +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT +# define ENTT_ASSERT(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT +# include +# define ENTT_ASSERT(condition, msg) assert(((condition) && (msg))) +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg) +#endif + +#define ENTT_FAIL(msg) ENTT_ASSERT(false, msg); + +#ifdef ENTT_NO_ETO +# define ENTT_ETO_TYPE(Type) void +#else +# define ENTT_ETO_TYPE(Type) Type +#endif + +#ifdef ENTT_NO_MIXIN +# define ENTT_STORAGE(Mixin, ...) __VA_ARGS__ +#else +# define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__> +#endif + +#ifdef ENTT_STANDARD_CPP +# define ENTT_NONSTD false +#else +# define ENTT_NONSTD true +# if defined __clang__ || defined __GNUC__ +# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ +# define ENTT_PRETTY_FUNCTION_PREFIX '=' +# define ENTT_PRETTY_FUNCTION_SUFFIX ']' +# elif defined _MSC_VER +# define ENTT_PRETTY_FUNCTION __FUNCSIG__ +# define ENTT_PRETTY_FUNCTION_PREFIX '<' +# define ENTT_PRETTY_FUNCTION_SUFFIX '>' +# endif +#endif + +#ifndef ENTT_EXPORT +# if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER +# define ENTT_EXPORT __declspec(dllexport) +# define ENTT_IMPORT __declspec(dllimport) +# define ENTT_HIDDEN +# elif defined __GNUC__ && __GNUC__ >= 4 +# define ENTT_EXPORT __attribute__((visibility("default"))) +# define ENTT_IMPORT __attribute__((visibility("default"))) +# define ENTT_HIDDEN __attribute__((visibility("hidden"))) +# else /* Unsupported compiler */ +# define ENTT_EXPORT +# define ENTT_IMPORT +# define ENTT_HIDDEN +# endif +#endif + +#ifndef ENTT_API +# if defined ENTT_API_EXPORT +# define ENTT_API ENTT_EXPORT +# elif defined ENTT_API_IMPORT +# define ENTT_API ENTT_IMPORT +# else /* No API */ +# define ENTT_API +# endif +#endif + +#if defined _MSC_VER +# pragma detect_mismatch("entt.version", ENTT_VERSION) +# pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY)) +# pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE)) +# pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD)) +#endif + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + +// #include "../core/iterator.hpp" +#ifndef ENTT_CORE_ITERATOR_HPP +#define ENTT_CORE_ITERATOR_HPP + +#include +#include +#include +#include + +namespace entt { + +/** + * @brief Helper type to use as pointer with input iterators. + * @tparam Type of wrapped value. + */ +template +struct input_iterator_pointer final { + /*! @brief Value type. */ + using value_type = Type; + /*! @brief Pointer type. */ + using pointer = Type *; + /*! @brief Reference type. */ + using reference = Type &; + + /** + * @brief Constructs a proxy object by move. + * @param val Value to use to initialize the proxy object. + */ + constexpr input_iterator_pointer(value_type &&val) noexcept(std::is_nothrow_move_constructible_v) + : value{std::move(val)} {} + + /** + * @brief Access operator for accessing wrapped values. + * @return A pointer to the wrapped value. + */ + [[nodiscard]] constexpr pointer operator->() noexcept { + return std::addressof(value); + } + + /** + * @brief Dereference operator for accessing wrapped values. + * @return A reference to the wrapped value. + */ + [[nodiscard]] constexpr reference operator*() noexcept { + return value; + } + +private: + Type value; +}; + +/** + * @brief Plain iota iterator (waiting for C++20). + * @tparam Type Value type. + */ +template +class iota_iterator final { + static_assert(std::is_integral_v, "Not an integral type"); + +public: + /*! @brief Value type, likely an integral one. */ + using value_type = Type; + /*! @brief Invalid pointer type. */ + using pointer = void; + /*! @brief Non-reference type, same as value type. */ + using reference = value_type; + /*! @brief Difference type. */ + using difference_type = std::ptrdiff_t; + /*! @brief Iterator category. */ + using iterator_category = std::input_iterator_tag; + + /*! @brief Default constructor. */ + constexpr iota_iterator() noexcept + : current{} {} + + /** + * @brief Constructs an iota iterator from a given value. + * @param init The initial value assigned to the iota iterator. + */ + constexpr iota_iterator(const value_type init) noexcept + : current{init} {} + + /** + * @brief Pre-increment operator. + * @return This iota iterator. + */ + constexpr iota_iterator &operator++() noexcept { + return ++current, *this; + } + + /** + * @brief Post-increment operator. + * @return This iota iterator. + */ + constexpr iota_iterator operator++(int) noexcept { + const iota_iterator orig = *this; + return ++(*this), orig; + } + + /** + * @brief Dereference operator. + * @return The underlying value. + */ + [[nodiscard]] constexpr reference operator*() const noexcept { + return current; + } + +private: + value_type current; +}; + +/** + * @brief Comparison operator. + * @tparam Type Value type of the iota iterator. + * @param lhs A properly initialized iota iterator. + * @param rhs A properly initialized iota iterator. + * @return True if the two iterators are identical, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator==(const iota_iterator &lhs, const iota_iterator &rhs) noexcept { + return *lhs == *rhs; +} + +/** + * @brief Comparison operator. + * @tparam Type Value type of the iota iterator. + * @param lhs A properly initialized iota iterator. + * @param rhs A properly initialized iota iterator. + * @return True if the two iterators differ, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator!=(const iota_iterator &lhs, const iota_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +/** + * @brief Utility class to create an iterable object from a pair of iterators. + * @tparam It Type of iterator. + * @tparam Sentinel Type of sentinel. + */ +template +struct iterable_adaptor final { + /*! @brief Value type. */ + using value_type = typename std::iterator_traits::value_type; + /*! @brief Iterator type. */ + using iterator = It; + /*! @brief Sentinel type. */ + using sentinel = Sentinel; + + /*! @brief Default constructor. */ + constexpr iterable_adaptor() noexcept(std::is_nothrow_default_constructible_v && std::is_nothrow_default_constructible_v) + : first{}, + last{} {} + + /** + * @brief Creates an iterable object from a pair of iterators. + * @param from Begin iterator. + * @param to End iterator. + */ + constexpr iterable_adaptor(iterator from, sentinel to) noexcept(std::is_nothrow_move_constructible_v && std::is_nothrow_move_constructible_v) + : first{std::move(from)}, + last{std::move(to)} {} + + /** + * @brief Returns an iterator to the beginning. + * @return An iterator to the first element of the range. + */ + [[nodiscard]] constexpr iterator begin() const noexcept { + return first; + } + + /** + * @brief Returns an iterator to the end. + * @return An iterator to the element following the last element of the + * range. + */ + [[nodiscard]] constexpr sentinel end() const noexcept { + return last; + } + + /*! @copydoc begin */ + [[nodiscard]] constexpr iterator cbegin() const noexcept { + return begin(); + } + + /*! @copydoc end */ + [[nodiscard]] constexpr sentinel cend() const noexcept { + return end(); + } + +private: + It first; + Sentinel last; +}; + +} // namespace entt + +#endif + +// #include "fwd.hpp" +#ifndef ENTT_GRAPH_FWD_HPP +#define ENTT_GRAPH_FWD_HPP + +#include +#include +// #include "../core/fwd.hpp" +#ifndef ENTT_CORE_FWD_HPP +#define ENTT_CORE_FWD_HPP + +#include +#include +// #include "../config/config.h" +#ifndef ENTT_CONFIG_CONFIG_H +#define ENTT_CONFIG_CONFIG_H + +// #include "version.h" +#ifndef ENTT_CONFIG_VERSION_H +#define ENTT_CONFIG_VERSION_H + +// #include "macro.h" +#ifndef ENTT_CONFIG_MACRO_H +#define ENTT_CONFIG_MACRO_H + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#define ENTT_STR(arg) #arg +#define ENTT_XSTR(arg) ENTT_STR(arg) + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*) + +#define ENTT_VERSION_MAJOR 3 +#define ENTT_VERSION_MINOR 16 +#define ENTT_VERSION_PATCH 0 + +#define ENTT_VERSION \ + ENTT_XSTR(ENTT_VERSION_MAJOR) \ + "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH) + +// NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION) +# define ENTT_CONSTEXPR +# define ENTT_THROW throw +# define ENTT_TRY try +# define ENTT_CATCH catch(...) +#else +# define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20) +# define ENTT_THROW +# define ENTT_TRY if(true) +# define ENTT_CATCH if(false) +#endif + +#if __has_include() +# include +# +# if defined(__cpp_consteval) +# define ENTT_CONSTEVAL consteval +# endif +#endif + +#ifndef ENTT_CONSTEVAL +# define ENTT_CONSTEVAL constexpr +#endif + +#ifdef ENTT_USE_ATOMIC +# include +# define ENTT_MAYBE_ATOMIC(Type) std::atomic +#else +# define ENTT_MAYBE_ATOMIC(Type) Type +#endif + +#ifndef ENTT_ID_TYPE +# include +# define ENTT_ID_TYPE std::uint32_t +#else +# include // provides coverage for types in the std namespace +#endif + +#ifndef ENTT_SPARSE_PAGE +# define ENTT_SPARSE_PAGE 4096 +#endif + +#ifndef ENTT_PACKED_PAGE +# define ENTT_PACKED_PAGE 1024 +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT +# define ENTT_ASSERT(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT +# include +# define ENTT_ASSERT(condition, msg) assert(((condition) && (msg))) +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg) +#endif + +#define ENTT_FAIL(msg) ENTT_ASSERT(false, msg); + +#ifdef ENTT_NO_ETO +# define ENTT_ETO_TYPE(Type) void +#else +# define ENTT_ETO_TYPE(Type) Type +#endif + +#ifdef ENTT_NO_MIXIN +# define ENTT_STORAGE(Mixin, ...) __VA_ARGS__ +#else +# define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__> +#endif + +#ifdef ENTT_STANDARD_CPP +# define ENTT_NONSTD false +#else +# define ENTT_NONSTD true +# if defined __clang__ || defined __GNUC__ +# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ +# define ENTT_PRETTY_FUNCTION_PREFIX '=' +# define ENTT_PRETTY_FUNCTION_SUFFIX ']' +# elif defined _MSC_VER +# define ENTT_PRETTY_FUNCTION __FUNCSIG__ +# define ENTT_PRETTY_FUNCTION_PREFIX '<' +# define ENTT_PRETTY_FUNCTION_SUFFIX '>' +# endif +#endif + +#ifndef ENTT_EXPORT +# if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER +# define ENTT_EXPORT __declspec(dllexport) +# define ENTT_IMPORT __declspec(dllimport) +# define ENTT_HIDDEN +# elif defined __GNUC__ && __GNUC__ >= 4 +# define ENTT_EXPORT __attribute__((visibility("default"))) +# define ENTT_IMPORT __attribute__((visibility("default"))) +# define ENTT_HIDDEN __attribute__((visibility("hidden"))) +# else /* Unsupported compiler */ +# define ENTT_EXPORT +# define ENTT_IMPORT +# define ENTT_HIDDEN +# endif +#endif + +#ifndef ENTT_API +# if defined ENTT_API_EXPORT +# define ENTT_API ENTT_EXPORT +# elif defined ENTT_API_IMPORT +# define ENTT_API ENTT_IMPORT +# else /* No API */ +# define ENTT_API +# endif +#endif + +#if defined _MSC_VER +# pragma detect_mismatch("entt.version", ENTT_VERSION) +# pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY)) +# pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE)) +# pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD)) +#endif + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +namespace entt { + +/*! @brief Possible modes of an any object. */ +enum class any_policy : std::uint8_t { + /*! @brief Default mode, no element available. */ + empty, + /*! @brief Owning mode, dynamically allocated element. */ + dynamic, + /*! @brief Owning mode, embedded element. */ + embedded, + /*! @brief Aliasing mode, non-const reference. */ + ref, + /*! @brief Const aliasing mode, const reference. */ + cref +}; + +// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) +template +class basic_any; + +/*! @brief Alias declaration for type identifiers. */ +using id_type = ENTT_ID_TYPE; + +/*! @brief Alias declaration for the most common use case. */ +using any = basic_any<>; + +template +class compressed_pair; + +template +class basic_hashed_string; + +/*! @brief Aliases for common character types. */ +using hashed_string = basic_hashed_string; + +/*! @brief Aliases for common character types. */ +using hashed_wstring = basic_hashed_string; + +// NOLINTNEXTLINE(bugprone-forward-declaration-namespace) +struct type_info; + +} // namespace entt + +#endif + + +namespace entt { + +/*! @brief Undirected graph category tag. */ +struct directed_tag {}; + +/*! @brief Directed graph category tag. */ +struct undirected_tag: directed_tag {}; + +template> +class adjacency_matrix; + +template> +class basic_flow; + +/*! @brief Alias declaration for the most common use case. */ +using flow = basic_flow<>; + +} // namespace entt + +#endif + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +class edge_iterator { + using size_type = std::size_t; + + void find_next() noexcept { + for(; pos != last && !it[static_cast(pos)]; pos += offset) {} + } + +public: + using value_type = std::pair; + using pointer = input_iterator_pointer; + using reference = value_type; + using difference_type = std::ptrdiff_t; + using iterator_category = std::input_iterator_tag; + using iterator_concept = std::forward_iterator_tag; + + constexpr edge_iterator() noexcept = default; + + // NOLINTNEXTLINE(bugprone-easily-swappable-parameters) + constexpr edge_iterator(It base, const size_type vertices, const size_type from, const size_type to, const size_type step) noexcept + : it{std::move(base)}, + vert{vertices}, + pos{from}, + last{to}, + offset{step} { + find_next(); + } + + constexpr edge_iterator &operator++() noexcept { + pos += offset; + find_next(); + return *this; + } + + constexpr edge_iterator operator++(int) noexcept { + const edge_iterator orig = *this; + return ++(*this), orig; + } + + [[nodiscard]] constexpr reference operator*() const noexcept { + return *operator->(); + } + + [[nodiscard]] constexpr pointer operator->() const noexcept { + return std::make_pair(pos / vert, pos % vert); + } + + template + friend constexpr bool operator==(const edge_iterator &, const edge_iterator &) noexcept; + +private: + It it{}; + size_type vert{}; + size_type pos{}; + size_type last{}; + size_type offset{}; +}; + +template +[[nodiscard]] constexpr bool operator==(const edge_iterator &lhs, const edge_iterator &rhs) noexcept { + return lhs.pos == rhs.pos; +} + +template +[[nodiscard]] constexpr bool operator!=(const edge_iterator &lhs, const edge_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Basic implementation of a directed adjacency matrix. + * @tparam Category Either a directed or undirected category tag. + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +class adjacency_matrix { + using alloc_traits = std::allocator_traits; + static_assert(std::is_base_of_v, "Invalid graph category"); + static_assert(std::is_same_v, "Invalid value type"); + using container_type = std::vector>; + +public: + /*! @brief Allocator type. */ + using allocator_type = Allocator; + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + /*! @brief Vertex type. */ + using vertex_type = size_type; + /*! @brief Edge type. */ + using edge_type = std::pair; + /*! @brief Vertex iterator type. */ + using vertex_iterator = iota_iterator; + /*! @brief Edge iterator type. */ + using edge_iterator = internal::edge_iterator; + /*! @brief Out-edge iterator type. */ + using out_edge_iterator = edge_iterator; + /*! @brief In-edge iterator type. */ + using in_edge_iterator = edge_iterator; + /*! @brief Graph category tag. */ + using graph_category = Category; + + /*! @brief Default constructor. */ + adjacency_matrix() noexcept(noexcept(allocator_type{})) + : adjacency_matrix{0u} { + } + + /** + * @brief Constructs an empty container with a given allocator. + * @param allocator The allocator to use. + */ + explicit adjacency_matrix(const allocator_type &allocator) noexcept + : adjacency_matrix{0u, allocator} {} + + /** + * @brief Constructs an empty container with a given allocator and user + * supplied number of vertices. + * @param vertices Number of vertices. + * @param allocator The allocator to use. + */ + adjacency_matrix(const size_type vertices, const allocator_type &allocator = allocator_type{}) + : matrix{vertices * vertices, allocator}, + vert{vertices} {} + + /*! @brief Default copy constructor. */ + adjacency_matrix(const adjacency_matrix &) = default; + + /** + * @brief Allocator-extended copy constructor. + * @param other The instance to copy from. + * @param allocator The allocator to use. + */ + adjacency_matrix(const adjacency_matrix &other, const allocator_type &allocator) + : matrix{other.matrix, allocator}, + vert{other.vert} {} + + /*! @brief Default move constructor. */ + adjacency_matrix(adjacency_matrix &&) noexcept = default; + + /** + * @brief Allocator-extended move constructor. + * @param other The instance to move from. + * @param allocator The allocator to use. + */ + adjacency_matrix(adjacency_matrix &&other, const allocator_type &allocator) + : matrix{std::move(other.matrix), allocator}, + vert{other.vert} {} + + /*! @brief Default destructor. */ + ~adjacency_matrix() = default; + + /** + * @brief Default copy assignment operator. + * @return This container. + */ + adjacency_matrix &operator=(const adjacency_matrix &) = default; + + /** + * @brief Default move assignment operator. + * @return This container. + */ + adjacency_matrix &operator=(adjacency_matrix &&) noexcept = default; + + /** + * @brief Exchanges the contents with those of a given adjacency matrix. + * @param other Adjacency matrix to exchange the content with. + */ + void swap(adjacency_matrix &other) noexcept { + using std::swap; + swap(matrix, other.matrix); + swap(vert, other.vert); + } + + /** + * @brief Returns the associated allocator. + * @return The associated allocator. + */ + [[nodiscard]] constexpr allocator_type get_allocator() const noexcept { + return matrix.get_allocator(); + } + + /*! @brief Clears the adjacency matrix. */ + void clear() noexcept { + matrix.clear(); + vert = {}; + } + + /** + * @brief Returns true if an adjacency matrix is empty, false otherwise. + * + * @warning + * Potentially expensive, try to avoid it on hot paths. + * + * @return True if the adjacency matrix is empty, false otherwise. + */ + [[nodiscard]] bool empty() const noexcept { + const auto iterable = edges(); + return (iterable.begin() == iterable.end()); + } + + /** + * @brief Returns the number of vertices. + * @return The number of vertices. + */ + [[nodiscard]] size_type size() const noexcept { + return vert; + } + + /** + * @brief Returns an iterable object to visit all vertices of a matrix. + * @return An iterable object to visit all vertices of a matrix. + */ + [[nodiscard]] iterable_adaptor vertices() const noexcept { + return {0u, vert}; + } + + /** + * @brief Returns an iterable object to visit all edges of a matrix. + * @return An iterable object to visit all edges of a matrix. + */ + [[nodiscard]] iterable_adaptor edges() const noexcept { + const auto it = matrix.cbegin(); + const auto sz = matrix.size(); + return {{it, vert, 0u, sz, 1u}, {it, vert, sz, sz, 1u}}; + } + + /** + * @brief Returns an iterable object to visit all out-edges of a vertex. + * @param vertex The vertex of which to return all out-edges. + * @return An iterable object to visit all out-edges of a vertex. + */ + [[nodiscard]] iterable_adaptor out_edges(const vertex_type vertex) const noexcept { + const auto it = matrix.cbegin(); + const auto from = vertex * vert; + const auto to = from + vert; + return {{it, vert, from, to, 1u}, {it, vert, to, to, 1u}}; + } + + /** + * @brief Returns an iterable object to visit all in-edges of a vertex. + * @param vertex The vertex of which to return all in-edges. + * @return An iterable object to visit all in-edges of a vertex. + */ + [[nodiscard]] iterable_adaptor in_edges(const vertex_type vertex) const noexcept { + const auto it = matrix.cbegin(); + const auto from = vertex; + const auto to = vert * vert + from; + return {{it, vert, from, to, vert}, {it, vert, to, to, vert}}; + } + + /** + * @brief Resizes an adjacency matrix. + * @param vertices The new number of vertices. + */ + void resize(const size_type vertices) { + adjacency_matrix other{vertices, get_allocator()}; + + for(auto [lhs, rhs]: edges()) { + other.insert(lhs, rhs); + } + + other.swap(*this); + } + + /** + * @brief Inserts an edge into the adjacency matrix, if it does not exist. + * @param lhs The left hand vertex of the edge. + * @param rhs The right hand vertex of the edge. + * @return A pair consisting of an iterator to the inserted element (or to + * the element that prevented the insertion) and a bool denoting whether the + * insertion took place. + */ + std::pair insert(const vertex_type lhs, const vertex_type rhs) { + const auto pos = lhs * vert + rhs; + + if constexpr(std::is_same_v) { + const auto rev = rhs * vert + lhs; + ENTT_ASSERT(matrix[pos] == matrix[rev], "Something went really wrong"); + matrix[rev] = 1u; + } + + const auto inserted = !std::exchange(matrix[pos], 1u); + return {edge_iterator{matrix.cbegin(), vert, pos, matrix.size(), 1u}, inserted}; + } + + /** + * @brief Removes the edge associated with a pair of given vertices. + * @param lhs The left hand vertex of the edge. + * @param rhs The right hand vertex of the edge. + * @return Number of elements removed (either 0 or 1). + */ + size_type erase(const vertex_type lhs, const vertex_type rhs) { + const auto pos = lhs * vert + rhs; + + if constexpr(std::is_same_v) { + const auto rev = rhs * vert + lhs; + ENTT_ASSERT(matrix[pos] == matrix[rev], "Something went really wrong"); + matrix[rev] = 0u; + } + + return std::exchange(matrix[pos], 0u); + } + + /** + * @brief Checks if an adjacency matrix contains a given edge. + * @param lhs The left hand vertex of the edge. + * @param rhs The right hand vertex of the edge. + * @return True if there is such an edge, false otherwise. + */ + [[nodiscard]] bool contains(const vertex_type lhs, const vertex_type rhs) const { + const auto pos = lhs * vert + rhs; + return pos < matrix.size() && matrix[pos]; + } + +private: + container_type matrix; + size_type vert; +}; + +} // namespace entt + +#endif + +// #include "../graph/flow.hpp" +#ifndef ENTT_GRAPH_FLOW_HPP +#define ENTT_GRAPH_FLOW_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "../container/dense_map.hpp" +#ifndef ENTT_CONTAINER_DENSE_MAP_HPP +#define ENTT_CONTAINER_DENSE_MAP_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #include "../config/config.h" +#ifndef ENTT_CONFIG_CONFIG_H +#define ENTT_CONFIG_CONFIG_H + +// #include "version.h" +#ifndef ENTT_CONFIG_VERSION_H +#define ENTT_CONFIG_VERSION_H + +// #include "macro.h" +#ifndef ENTT_CONFIG_MACRO_H +#define ENTT_CONFIG_MACRO_H + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#define ENTT_STR(arg) #arg +#define ENTT_XSTR(arg) ENTT_STR(arg) + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*) + +#define ENTT_VERSION_MAJOR 3 +#define ENTT_VERSION_MINOR 16 +#define ENTT_VERSION_PATCH 0 + +#define ENTT_VERSION \ + ENTT_XSTR(ENTT_VERSION_MAJOR) \ + "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH) + +// NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION) +# define ENTT_CONSTEXPR +# define ENTT_THROW throw +# define ENTT_TRY try +# define ENTT_CATCH catch(...) +#else +# define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20) +# define ENTT_THROW +# define ENTT_TRY if(true) +# define ENTT_CATCH if(false) +#endif + +#if __has_include() +# include +# +# if defined(__cpp_consteval) +# define ENTT_CONSTEVAL consteval +# endif +#endif + +#ifndef ENTT_CONSTEVAL +# define ENTT_CONSTEVAL constexpr +#endif + +#ifdef ENTT_USE_ATOMIC +# include +# define ENTT_MAYBE_ATOMIC(Type) std::atomic +#else +# define ENTT_MAYBE_ATOMIC(Type) Type +#endif + +#ifndef ENTT_ID_TYPE +# include +# define ENTT_ID_TYPE std::uint32_t +#else +# include // provides coverage for types in the std namespace +#endif + +#ifndef ENTT_SPARSE_PAGE +# define ENTT_SPARSE_PAGE 4096 +#endif + +#ifndef ENTT_PACKED_PAGE +# define ENTT_PACKED_PAGE 1024 +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT +# define ENTT_ASSERT(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT +# include +# define ENTT_ASSERT(condition, msg) assert(((condition) && (msg))) +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg) +#endif + +#define ENTT_FAIL(msg) ENTT_ASSERT(false, msg); + +#ifdef ENTT_NO_ETO +# define ENTT_ETO_TYPE(Type) void +#else +# define ENTT_ETO_TYPE(Type) Type +#endif + +#ifdef ENTT_NO_MIXIN +# define ENTT_STORAGE(Mixin, ...) __VA_ARGS__ +#else +# define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__> +#endif + +#ifdef ENTT_STANDARD_CPP +# define ENTT_NONSTD false +#else +# define ENTT_NONSTD true +# if defined __clang__ || defined __GNUC__ +# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ +# define ENTT_PRETTY_FUNCTION_PREFIX '=' +# define ENTT_PRETTY_FUNCTION_SUFFIX ']' +# elif defined _MSC_VER +# define ENTT_PRETTY_FUNCTION __FUNCSIG__ +# define ENTT_PRETTY_FUNCTION_PREFIX '<' +# define ENTT_PRETTY_FUNCTION_SUFFIX '>' +# endif +#endif + +#ifndef ENTT_EXPORT +# if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER +# define ENTT_EXPORT __declspec(dllexport) +# define ENTT_IMPORT __declspec(dllimport) +# define ENTT_HIDDEN +# elif defined __GNUC__ && __GNUC__ >= 4 +# define ENTT_EXPORT __attribute__((visibility("default"))) +# define ENTT_IMPORT __attribute__((visibility("default"))) +# define ENTT_HIDDEN __attribute__((visibility("hidden"))) +# else /* Unsupported compiler */ +# define ENTT_EXPORT +# define ENTT_IMPORT +# define ENTT_HIDDEN +# endif +#endif + +#ifndef ENTT_API +# if defined ENTT_API_EXPORT +# define ENTT_API ENTT_EXPORT +# elif defined ENTT_API_IMPORT +# define ENTT_API ENTT_IMPORT +# else /* No API */ +# define ENTT_API +# endif +#endif + +#if defined _MSC_VER +# pragma detect_mismatch("entt.version", ENTT_VERSION) +# pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY)) +# pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE)) +# pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD)) +#endif + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + +// #include "../core/bit.hpp" +#ifndef ENTT_CORE_BIT_HPP +#define ENTT_CORE_BIT_HPP + +#include +#include +#include +// #include "../config/config.h" +#ifndef ENTT_CONFIG_CONFIG_H +#define ENTT_CONFIG_CONFIG_H + +// #include "version.h" +#ifndef ENTT_CONFIG_VERSION_H +#define ENTT_CONFIG_VERSION_H + +// #include "macro.h" +#ifndef ENTT_CONFIG_MACRO_H +#define ENTT_CONFIG_MACRO_H + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#define ENTT_STR(arg) #arg +#define ENTT_XSTR(arg) ENTT_STR(arg) + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*) + +#define ENTT_VERSION_MAJOR 3 +#define ENTT_VERSION_MINOR 16 +#define ENTT_VERSION_PATCH 0 + +#define ENTT_VERSION \ + ENTT_XSTR(ENTT_VERSION_MAJOR) \ + "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH) + +// NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION) +# define ENTT_CONSTEXPR +# define ENTT_THROW throw +# define ENTT_TRY try +# define ENTT_CATCH catch(...) +#else +# define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20) +# define ENTT_THROW +# define ENTT_TRY if(true) +# define ENTT_CATCH if(false) +#endif + +#if __has_include() +# include +# +# if defined(__cpp_consteval) +# define ENTT_CONSTEVAL consteval +# endif +#endif + +#ifndef ENTT_CONSTEVAL +# define ENTT_CONSTEVAL constexpr +#endif + +#ifdef ENTT_USE_ATOMIC +# include +# define ENTT_MAYBE_ATOMIC(Type) std::atomic +#else +# define ENTT_MAYBE_ATOMIC(Type) Type +#endif + +#ifndef ENTT_ID_TYPE +# include +# define ENTT_ID_TYPE std::uint32_t +#else +# include // provides coverage for types in the std namespace +#endif + +#ifndef ENTT_SPARSE_PAGE +# define ENTT_SPARSE_PAGE 4096 +#endif + +#ifndef ENTT_PACKED_PAGE +# define ENTT_PACKED_PAGE 1024 +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT +# define ENTT_ASSERT(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT +# include +# define ENTT_ASSERT(condition, msg) assert(((condition) && (msg))) +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg) +#endif + +#define ENTT_FAIL(msg) ENTT_ASSERT(false, msg); + +#ifdef ENTT_NO_ETO +# define ENTT_ETO_TYPE(Type) void +#else +# define ENTT_ETO_TYPE(Type) Type +#endif + +#ifdef ENTT_NO_MIXIN +# define ENTT_STORAGE(Mixin, ...) __VA_ARGS__ +#else +# define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__> +#endif + +#ifdef ENTT_STANDARD_CPP +# define ENTT_NONSTD false +#else +# define ENTT_NONSTD true +# if defined __clang__ || defined __GNUC__ +# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ +# define ENTT_PRETTY_FUNCTION_PREFIX '=' +# define ENTT_PRETTY_FUNCTION_SUFFIX ']' +# elif defined _MSC_VER +# define ENTT_PRETTY_FUNCTION __FUNCSIG__ +# define ENTT_PRETTY_FUNCTION_PREFIX '<' +# define ENTT_PRETTY_FUNCTION_SUFFIX '>' +# endif +#endif + +#ifndef ENTT_EXPORT +# if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER +# define ENTT_EXPORT __declspec(dllexport) +# define ENTT_IMPORT __declspec(dllimport) +# define ENTT_HIDDEN +# elif defined __GNUC__ && __GNUC__ >= 4 +# define ENTT_EXPORT __attribute__((visibility("default"))) +# define ENTT_IMPORT __attribute__((visibility("default"))) +# define ENTT_HIDDEN __attribute__((visibility("hidden"))) +# else /* Unsupported compiler */ +# define ENTT_EXPORT +# define ENTT_IMPORT +# define ENTT_HIDDEN +# endif +#endif + +#ifndef ENTT_API +# if defined ENTT_API_EXPORT +# define ENTT_API ENTT_EXPORT +# elif defined ENTT_API_IMPORT +# define ENTT_API ENTT_IMPORT +# else /* No API */ +# define ENTT_API +# endif +#endif + +#if defined _MSC_VER +# pragma detect_mismatch("entt.version", ENTT_VERSION) +# pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY)) +# pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE)) +# pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD)) +#endif + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +namespace entt { + +/** + * @brief Returns the number of set bits in a value (waiting for C++20 and + * `std::popcount`). + * @tparam Type Unsigned integer type. + * @param value A value of unsigned integer type. + * @return The number of set bits in the value. + */ +template +[[nodiscard]] constexpr std::enable_if_t, int> popcount(const Type value) noexcept { + return value ? (int(value & 1) + popcount(static_cast(value >> 1))) : 0; +} + +/** + * @brief Checks whether a value is a power of two or not (waiting for C++20 and + * `std::has_single_bit`). + * @tparam Type Unsigned integer type. + * @param value A value of unsigned integer type. + * @return True if the value is a power of two, false otherwise. + */ +template +[[nodiscard]] constexpr std::enable_if_t, bool> has_single_bit(const Type value) noexcept { + return value && ((value & (value - 1)) == 0); +} + +/** + * @brief Computes the smallest power of two greater than or equal to a value + * (waiting for C++20 and `std::bit_ceil`). + * @tparam Type Unsigned integer type. + * @param value A value of unsigned integer type. + * @return The smallest power of two greater than or equal to the given value. + */ +template +[[nodiscard]] constexpr std::enable_if_t, Type> next_power_of_two(const Type value) noexcept { + // NOLINTNEXTLINE(bugprone-assert-side-effect) + ENTT_ASSERT_CONSTEXPR(value < (Type{1u} << (std::numeric_limits::digits - 1)), "Numeric limits exceeded"); + Type curr = value - (value != 0u); + + for(int next = 1; next < std::numeric_limits::digits; next = next * 2) { + curr |= (curr >> next); + } + + return ++curr; +} + +/** + * @brief Fast module utility function (powers of two only). + * @tparam Type Unsigned integer type. + * @param value A value of unsigned integer type. + * @param mod _Modulus_, it must be a power of two. + * @return The common remainder. + */ +template +[[nodiscard]] constexpr std::enable_if_t, Type> fast_mod(const Type value, const std::size_t mod) noexcept { + ENTT_ASSERT_CONSTEXPR(has_single_bit(mod), "Value must be a power of two"); + return static_cast(value & (mod - 1u)); +} + +} // namespace entt + +#endif + +// #include "../core/compressed_pair.hpp" +#ifndef ENTT_CORE_COMPRESSED_PAIR_HPP +#define ENTT_CORE_COMPRESSED_PAIR_HPP + +#include +#include +#include +#include +// #include "fwd.hpp" +#ifndef ENTT_CORE_FWD_HPP +#define ENTT_CORE_FWD_HPP + +#include +#include +// #include "../config/config.h" + + +namespace entt { + +/*! @brief Possible modes of an any object. */ +enum class any_policy : std::uint8_t { + /*! @brief Default mode, no element available. */ + empty, + /*! @brief Owning mode, dynamically allocated element. */ + dynamic, + /*! @brief Owning mode, embedded element. */ + embedded, + /*! @brief Aliasing mode, non-const reference. */ + ref, + /*! @brief Const aliasing mode, const reference. */ + cref +}; + +// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) +template +class basic_any; + +/*! @brief Alias declaration for type identifiers. */ +using id_type = ENTT_ID_TYPE; + +/*! @brief Alias declaration for the most common use case. */ +using any = basic_any<>; + +template +class compressed_pair; + +template +class basic_hashed_string; + +/*! @brief Aliases for common character types. */ +using hashed_string = basic_hashed_string; + +/*! @brief Aliases for common character types. */ +using hashed_wstring = basic_hashed_string; + +// NOLINTNEXTLINE(bugprone-forward-declaration-namespace) +struct type_info; + +} // namespace entt + +#endif + +// #include "type_traits.hpp" +#ifndef ENTT_CORE_TYPE_TRAITS_HPP +#define ENTT_CORE_TYPE_TRAITS_HPP + +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "fwd.hpp" + + +namespace entt { + +/** + * @brief Utility class to disambiguate overloaded functions. + * @tparam N Number of choices available. + */ +template +struct choice_t + // unfortunately, doxygen cannot parse such a construct + : /*! @cond TURN_OFF_DOXYGEN */ choice_t /*! @endcond */ +{}; + +/*! @copybrief choice_t */ +template<> +struct choice_t<0> {}; + +/** + * @brief Variable template for the choice trick. + * @tparam N Number of choices available. + */ +template +inline constexpr choice_t choice{}; + +/** + * @brief Identity type trait. + * + * Useful to establish non-deduced contexts in template argument deduction + * (waiting for C++20) or to provide types through function arguments. + * + * @tparam Type A type. + */ +template +struct type_identity { + /*! @brief Identity type. */ + using type = Type; +}; + +/** + * @brief Helper type. + * @tparam Type A type. + */ +template +using type_identity_t = typename type_identity::type; + +/** + * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains. + * @tparam Type The type of which to return the size. + */ +template +struct size_of: std::integral_constant {}; + +/*! @copydoc size_of */ +template +struct size_of> + // NOLINTNEXTLINE(bugprone-sizeof-expression) + : std::integral_constant {}; + +/** + * @brief Helper variable template. + * @tparam Type The type of which to return the size. + */ +template +inline constexpr std::size_t size_of_v = size_of::value; + +/** + * @brief Using declaration to be used to _repeat_ the same type a number of + * times equal to the size of a given parameter pack. + * @tparam Type A type to repeat. + */ +template +using unpack_as_type = Type; + +/** + * @brief Helper variable template to be used to _repeat_ the same value a + * number of times equal to the size of a given parameter pack. + * @tparam Value A value to repeat. + */ +template +inline constexpr auto unpack_as_value = Value; + +/** + * @brief Wraps a static constant. + * @tparam Value A static constant. + */ +template +using integral_constant = std::integral_constant; + +/** + * @brief Alias template to facilitate the creation of named values. + * @tparam Value A constant value at least convertible to `id_type`. + */ +template +using tag = integral_constant; + +/** + * @brief A class to use to push around lists of types, nothing more. + * @tparam Type Types provided by the type list. + */ +template +struct type_list { + /*! @brief Type list type. */ + using type = type_list; + /*! @brief Compile-time number of elements in the type list. */ + static constexpr auto size = sizeof...(Type); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_element; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Index Index of the type to return. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element> + : type_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element<0u, type_list> { + /*! @brief Searched type. */ + using type = First; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Type list to search into. + */ +template +using type_list_element_t = typename type_list_element::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_index; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 1u + type_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + static_assert(type_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +inline constexpr std::size_t type_list_index_v = type_list_index::value; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @return A type list composed by the types of both the type lists. + */ +template +constexpr type_list operator+(type_list, type_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_cat; + +/*! @brief Concatenates multiple type lists. */ +template<> +struct type_list_cat<> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list<>; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @tparam List Other type lists, if any. + */ +template +struct type_list_cat, type_list, List...> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = typename type_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the type list. + */ +template +struct type_list_cat> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list; +}; + +/** + * @brief Helper type. + * @tparam List Type lists to concatenate. + */ +template +using type_list_cat_t = typename type_list_cat::type; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct type_list_unique; + +template +struct type_list_unique, Type...> + : std::conditional_t<(std::is_same_v || ...), type_list_unique, Type...>, type_list_unique, Type..., First>> {}; + +template +struct type_list_unique, Type...> { + using type = type_list; +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Removes duplicates types from a type list. + * @tparam List Type list. + */ +template +struct type_list_unique { + /*! @brief A type list without duplicate types. */ + using type = typename internal::type_list_unique::type; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + */ +template +using type_list_unique_t = typename type_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a type list contains a + * given type, false otherwise. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +struct type_list_contains; + +/** + * @copybrief type_list_contains + * @tparam Type Types provided by the type list. + * @tparam Other Type to look for. + */ +template +struct type_list_contains, Other> + : std::bool_constant<(std::is_same_v || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +inline constexpr bool type_list_contains_v = type_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_diff; + +/** + * @brief Computes the difference between two type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + */ +template +struct type_list_diff, type_list> { + /*! @brief A type list that is the difference between the two type lists. */ + using type = type_list_cat_t, Type>, type_list<>, type_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Type lists between which to compute the difference. + */ +template +using type_list_diff_t = typename type_list_diff::type; + +/*! @brief Primary template isn't defined on purpose. */ +template class> +struct type_list_transform; + +/** + * @brief Applies a given _function_ to a type list and generate a new list. + * @tparam Type Types provided by the type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +struct type_list_transform, Op> { + /*! @brief Resulting type list after applying the transform function. */ + // NOLINTNEXTLINE(modernize-type-traits) + using type = type_list::type...>; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +using type_list_transform_t = typename type_list_transform::type; + +/** + * @brief A class to use to push around lists of constant values, nothing more. + * @tparam Value Values provided by the value list. + */ +template +struct value_list { + /*! @brief Value list type. */ + using type = value_list; + /*! @brief Compile-time number of elements in the value list. */ + static constexpr auto size = sizeof...(Value); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_element; + +/** + * @brief Provides compile-time indexed access to the values of a value list. + * @tparam Index Index of the value to return. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element> + : value_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element<0u, value_list> { + /*! @brief Searched type. */ + using type = decltype(Value); + /*! @brief Searched value. */ + static constexpr auto value = Value; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Value list to search into. + */ +template +using value_list_element_t = typename value_list_element::type; + +/** + * @brief Helper type. + * @tparam Index Index of the value to return. + * @tparam List Value list to search into. + */ +template +inline constexpr auto value_list_element_v = value_list_element::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_index; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam First First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 1u + value_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + static_assert(value_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +inline constexpr std::size_t value_list_index_v = value_list_index::value; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @return A value list composed by the values of both the value lists. + */ +template +constexpr value_list operator+(value_list, value_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_cat; + +/*! @brief Concatenates multiple value lists. */ +template<> +struct value_list_cat<> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list<>; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @tparam List Other value lists, if any. + */ +template +struct value_list_cat, value_list, List...> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = typename value_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the value list. + */ +template +struct value_list_cat> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list; +}; + +/** + * @brief Helper type. + * @tparam List Value lists to concatenate. + */ +template +using value_list_cat_t = typename value_list_cat::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_unique; + +/** + * @brief Removes duplicates values from a value list. + * @tparam Value One of the values provided by the given value list. + * @tparam Other The other values provided by the given value list. + */ +template +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = std::conditional_t< + ((Value == Other) || ...), + typename value_list_unique>::type, + value_list_cat_t, typename value_list_unique>::type>>; +}; + +/*! @brief Removes duplicates values from a value list. */ +template<> +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = value_list<>; +}; + +/** + * @brief Helper type. + * @tparam Type A value list. + */ +template +using value_list_unique_t = typename value_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a value list contains + * a given value, false otherwise. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +struct value_list_contains; + +/** + * @copybrief value_list_contains + * @tparam Value Values provided by the value list. + * @tparam Other Value to look for. + */ +template +struct value_list_contains, Other> + : std::bool_constant<((Value == Other) || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +inline constexpr bool value_list_contains_v = value_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_diff; + +/** + * @brief Computes the difference between two value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + */ +template +struct value_list_diff, value_list> { + /*! @brief A value list that is the difference between the two value lists. */ + using type = value_list_cat_t, Value>, value_list<>, value_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Value lists between which to compute the difference. + */ +template +using value_list_diff_t = typename value_list_diff::type; + +/*! @brief Same as std::is_invocable, but with tuples. */ +template +struct is_applicable: std::false_type {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @brief Helper variable template. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_v = is_applicable::value; + +/*! @brief Same as std::is_invocable_r, but with tuples for arguments. */ +template +struct is_applicable_r: std::false_type {}; + +/** + * @copybrief is_applicable_r + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +struct is_applicable_r>: std::is_invocable_r {}; + +/** + * @brief Helper variable template. + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_r_v = is_applicable_r::value; + +/** + * @brief Provides the member constant `value` to true if a given type is + * complete, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_complete: std::false_type {}; + +/*! @copydoc is_complete */ +template +struct is_complete>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_complete_v = is_complete::value; + +/** + * @brief Provides the member constant `value` to true if a given type is an + * iterator, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_iterator: std::false_type {}; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_iterator_category: std::false_type {}; + +template +struct has_iterator_category::iterator_category>>: std::true_type {}; + +} // namespace internal +/*! @endcond */ + +/*! @copydoc is_iterator */ +template +struct is_iterator>>>> + : internal::has_iterator_category {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_iterator_v = is_iterator::value; + +/** + * @brief Provides the member constant `value` to true if a given type is both + * an empty and non-final class, false otherwise. + * @tparam Type The type to test + */ +template +struct is_ebco_eligible + : std::bool_constant && !std::is_final_v> {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_ebco_eligible_v = is_ebco_eligible::value; + +/** + * @brief Provides the member constant `value` to true if `Type::is_transparent` + * is valid and denotes a type, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_transparent: std::false_type {}; + +/*! @copydoc is_transparent */ +template +struct is_transparent>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_transparent_v = is_transparent::value; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_tuple_size_value: std::false_type {}; + +template +struct has_tuple_size_value::value)>>: std::true_type {}; + +template +struct has_value_type: std::false_type {}; + +template +struct has_value_type>: std::true_type {}; + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable(); + +template +[[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence) { + return (dispatch_is_equality_comparable>() && ...); +} + +template +[[nodiscard]] constexpr bool maybe_equality_comparable(char) { + return false; +} + +template +[[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval() == std::declval()) { + return true; +} + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable() { + // NOLINTBEGIN(modernize-use-transparent-functors) + if constexpr(std::is_array_v) { + return false; + } else if constexpr(is_complete_v>>) { + if constexpr(has_tuple_size_value::value) { + return maybe_equality_comparable(0) && unpack_maybe_equality_comparable(std::make_index_sequence::value>{}); + } else { + return maybe_equality_comparable(0); + } + } else if constexpr(has_value_type::value) { + if constexpr(is_iterator_v || std::is_same_v || dispatch_is_equality_comparable()) { + return maybe_equality_comparable(0); + } else { + return false; + } + } else { + return maybe_equality_comparable(0); + } + // NOLINTEND(modernize-use-transparent-functors) +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Provides the member constant `value` to true if a given type is + * equality comparable, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_equality_comparable: std::bool_constant()> {}; + +/*! @copydoc is_equality_comparable */ +template +struct is_equality_comparable: is_equality_comparable {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_equality_comparable_v = is_equality_comparable::value; + +/** + * @brief Transcribes the constness of a type to another type. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = std::remove_const_t; +}; + +/*! @copydoc constness_as */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = const To; +}; + +/** + * @brief Alias template to facilitate the transcription of the constness. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +using constness_as_t = typename constness_as::type; + +/** + * @brief Extracts the class of a non-static member object or function. + * @tparam Member A pointer to a non-static member object or function. + */ +template +class member_class { + static_assert(std::is_member_pointer_v, "Invalid pointer type to non-static member object or function"); + + template + static Class *clazz(Ret (Class::*)(Args...)); + + template + static Class *clazz(Ret (Class::*)(Args...) const); + + template + static Class *clazz(Type Class::*); + +public: + /*! @brief The class of the given non-static member object or function. */ + using type = std::remove_pointer_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Member A pointer to a non-static member object or function. + */ +template +using member_class_t = typename member_class::type; + +/** + * @brief Extracts the n-th argument of a _callable_ type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid _callable_ type. + */ +template +class nth_argument { + template + static constexpr type_list pick_up(Ret (*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...) const); + + template + static constexpr type_list pick_up(Type Class ::*); + + template + static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&); + +public: + /*! @brief N-th argument of the _callable_ type. */ + using type = type_list_element_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid function, member function or data member type. + */ +template +using nth_argument_t = typename nth_argument::type; + +} // namespace entt + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::type_list_element> {}; + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::value_list_element> {}; + +#endif + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct compressed_pair_element { + using reference = Type &; + using const_reference = const Type &; + + template>> + // NOLINTNEXTLINE(modernize-use-equals-default) + constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v) {} + + template>, compressed_pair_element>>> + constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v) + : value{std::forward(arg)} {} + + template + constexpr compressed_pair_element(std::tuple args, std::index_sequence) noexcept(std::is_nothrow_constructible_v) + : value{std::forward(std::get(args))...} {} + + [[nodiscard]] constexpr reference get() noexcept { + return value; + } + + [[nodiscard]] constexpr const_reference get() const noexcept { + return value; + } + +private: + Type value{}; +}; + +template +struct compressed_pair_element>>: Type { + using reference = Type &; + using const_reference = const Type &; + using base_type = Type; + + template>> + constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v) + : base_type{} {} + + template>, compressed_pair_element>>> + constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v) + : base_type{std::forward(arg)} {} + + template + constexpr compressed_pair_element(std::tuple args, std::index_sequence) noexcept(std::is_nothrow_constructible_v) + : base_type{std::forward(std::get(args))...} {} + + [[nodiscard]] constexpr reference get() noexcept { + return *this; + } + + [[nodiscard]] constexpr const_reference get() const noexcept { + return *this; + } +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief A compressed pair. + * + * A pair that exploits the _Empty Base Class Optimization_ (or _EBCO_) to + * reduce its final size to a minimum. + * + * @tparam First The type of the first element that the pair stores. + * @tparam Second The type of the second element that the pair stores. + */ +template +class compressed_pair final + : internal::compressed_pair_element, + internal::compressed_pair_element { + using first_base = internal::compressed_pair_element; + using second_base = internal::compressed_pair_element; + +public: + /*! @brief The type of the first element that the pair stores. */ + using first_type = First; + /*! @brief The type of the second element that the pair stores. */ + using second_type = Second; + + /** + * @brief Default constructor, conditionally enabled. + * + * This constructor is only available when the types that the pair stores + * are both at least default constructible. + * + * @tparam Dummy Dummy template parameter used for internal purposes. + */ + template && std::is_default_constructible_v>> + constexpr compressed_pair() noexcept(std::is_nothrow_default_constructible_v && std::is_nothrow_default_constructible_v) + : first_base{}, + second_base{} {} + + /** + * @brief Copy constructor. + * @param other The instance to copy from. + */ + constexpr compressed_pair(const compressed_pair &other) = default; + + /** + * @brief Move constructor. + * @param other The instance to move from. + */ + constexpr compressed_pair(compressed_pair &&other) noexcept = default; + + /** + * @brief Constructs a pair from its values. + * @tparam Arg Type of value to use to initialize the first element. + * @tparam Other Type of value to use to initialize the second element. + * @param arg Value to use to initialize the first element. + * @param other Value to use to initialize the second element. + */ + template + constexpr compressed_pair(Arg &&arg, Other &&other) noexcept(std::is_nothrow_constructible_v && std::is_nothrow_constructible_v) + : first_base{std::forward(arg)}, + second_base{std::forward(other)} {} + + /** + * @brief Constructs a pair by forwarding the arguments to its parts. + * @tparam Args Types of arguments to use to initialize the first element. + * @tparam Other Types of arguments to use to initialize the second element. + * @param args Arguments to use to initialize the first element. + * @param other Arguments to use to initialize the second element. + */ + template + constexpr compressed_pair(std::piecewise_construct_t, std::tuple args, std::tuple other) noexcept(std::is_nothrow_constructible_v && std::is_nothrow_constructible_v) + : first_base{std::move(args), std::index_sequence_for{}}, + second_base{std::move(other), std::index_sequence_for{}} {} + + /*! @brief Default destructor. */ + ~compressed_pair() = default; + + /** + * @brief Copy assignment operator. + * @param other The instance to copy from. + * @return This compressed pair object. + */ + constexpr compressed_pair &operator=(const compressed_pair &other) = default; + + /** + * @brief Move assignment operator. + * @param other The instance to move from. + * @return This compressed pair object. + */ + constexpr compressed_pair &operator=(compressed_pair &&other) noexcept = default; + + /** + * @brief Returns the first element that a pair stores. + * @return The first element that a pair stores. + */ + [[nodiscard]] constexpr first_type &first() noexcept { + return static_cast(*this).get(); + } + + /*! @copydoc first */ + [[nodiscard]] constexpr const first_type &first() const noexcept { + return static_cast(*this).get(); + } + + /** + * @brief Returns the second element that a pair stores. + * @return The second element that a pair stores. + */ + [[nodiscard]] constexpr second_type &second() noexcept { + return static_cast(*this).get(); + } + + /*! @copydoc second */ + [[nodiscard]] constexpr const second_type &second() const noexcept { + return static_cast(*this).get(); + } + + /** + * @brief Swaps two compressed pair objects. + * @param other The compressed pair to swap with. + */ + constexpr void swap(compressed_pair &other) noexcept { + using std::swap; + swap(first(), other.first()); + swap(second(), other.second()); + } + + /** + * @brief Extracts an element from the compressed pair. + * @tparam Index An integer value that is either 0 or 1. + * @return Returns a reference to the first element if `Index` is 0 and a + * reference to the second element if `Index` is 1. + */ + template + [[nodiscard]] constexpr decltype(auto) get() noexcept { + if constexpr(Index == 0u) { + return first(); + } else { + static_assert(Index == 1u, "Index out of bounds"); + return second(); + } + } + + /*! @copydoc get */ + template + [[nodiscard]] constexpr decltype(auto) get() const noexcept { + if constexpr(Index == 0u) { + return first(); + } else { + static_assert(Index == 1u, "Index out of bounds"); + return second(); + } + } +}; + +/** + * @brief Deduction guide. + * @tparam Type Type of value to use to initialize the first element. + * @tparam Other Type of value to use to initialize the second element. + */ +template +compressed_pair(Type &&, Other &&) -> compressed_pair, std::decay_t>; + +/** + * @brief Swaps two compressed pair objects. + * @tparam First The type of the first element that the pairs store. + * @tparam Second The type of the second element that the pairs store. + * @param lhs A valid compressed pair object. + * @param rhs A valid compressed pair object. + */ +template +constexpr void swap(compressed_pair &lhs, compressed_pair &rhs) noexcept { + lhs.swap(rhs); +} + +} // namespace entt + +namespace std { + +/** + * @brief `std::tuple_size` specialization for `compressed_pair`s. + * @tparam First The type of the first element that the pair stores. + * @tparam Second The type of the second element that the pair stores. + */ +template +struct tuple_size>: integral_constant {}; + +/** + * @brief `std::tuple_element` specialization for `compressed_pair`s. + * @tparam Index The index of the type to return. + * @tparam First The type of the first element that the pair stores. + * @tparam Second The type of the second element that the pair stores. + */ +template +struct tuple_element>: conditional { + static_assert(Index < 2u, "Index out of bounds"); +}; + +} // namespace std + +#endif + +// #include "../core/iterator.hpp" +#ifndef ENTT_CORE_ITERATOR_HPP +#define ENTT_CORE_ITERATOR_HPP + +#include +#include +#include +#include + +namespace entt { + +/** + * @brief Helper type to use as pointer with input iterators. + * @tparam Type of wrapped value. + */ +template +struct input_iterator_pointer final { + /*! @brief Value type. */ + using value_type = Type; + /*! @brief Pointer type. */ + using pointer = Type *; + /*! @brief Reference type. */ + using reference = Type &; + + /** + * @brief Constructs a proxy object by move. + * @param val Value to use to initialize the proxy object. + */ + constexpr input_iterator_pointer(value_type &&val) noexcept(std::is_nothrow_move_constructible_v) + : value{std::move(val)} {} + + /** + * @brief Access operator for accessing wrapped values. + * @return A pointer to the wrapped value. + */ + [[nodiscard]] constexpr pointer operator->() noexcept { + return std::addressof(value); + } + + /** + * @brief Dereference operator for accessing wrapped values. + * @return A reference to the wrapped value. + */ + [[nodiscard]] constexpr reference operator*() noexcept { + return value; + } + +private: + Type value; +}; + +/** + * @brief Plain iota iterator (waiting for C++20). + * @tparam Type Value type. + */ +template +class iota_iterator final { + static_assert(std::is_integral_v, "Not an integral type"); + +public: + /*! @brief Value type, likely an integral one. */ + using value_type = Type; + /*! @brief Invalid pointer type. */ + using pointer = void; + /*! @brief Non-reference type, same as value type. */ + using reference = value_type; + /*! @brief Difference type. */ + using difference_type = std::ptrdiff_t; + /*! @brief Iterator category. */ + using iterator_category = std::input_iterator_tag; + + /*! @brief Default constructor. */ + constexpr iota_iterator() noexcept + : current{} {} + + /** + * @brief Constructs an iota iterator from a given value. + * @param init The initial value assigned to the iota iterator. + */ + constexpr iota_iterator(const value_type init) noexcept + : current{init} {} + + /** + * @brief Pre-increment operator. + * @return This iota iterator. + */ + constexpr iota_iterator &operator++() noexcept { + return ++current, *this; + } + + /** + * @brief Post-increment operator. + * @return This iota iterator. + */ + constexpr iota_iterator operator++(int) noexcept { + const iota_iterator orig = *this; + return ++(*this), orig; + } + + /** + * @brief Dereference operator. + * @return The underlying value. + */ + [[nodiscard]] constexpr reference operator*() const noexcept { + return current; + } + +private: + value_type current; +}; + +/** + * @brief Comparison operator. + * @tparam Type Value type of the iota iterator. + * @param lhs A properly initialized iota iterator. + * @param rhs A properly initialized iota iterator. + * @return True if the two iterators are identical, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator==(const iota_iterator &lhs, const iota_iterator &rhs) noexcept { + return *lhs == *rhs; +} + +/** + * @brief Comparison operator. + * @tparam Type Value type of the iota iterator. + * @param lhs A properly initialized iota iterator. + * @param rhs A properly initialized iota iterator. + * @return True if the two iterators differ, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator!=(const iota_iterator &lhs, const iota_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +/** + * @brief Utility class to create an iterable object from a pair of iterators. + * @tparam It Type of iterator. + * @tparam Sentinel Type of sentinel. + */ +template +struct iterable_adaptor final { + /*! @brief Value type. */ + using value_type = typename std::iterator_traits::value_type; + /*! @brief Iterator type. */ + using iterator = It; + /*! @brief Sentinel type. */ + using sentinel = Sentinel; + + /*! @brief Default constructor. */ + constexpr iterable_adaptor() noexcept(std::is_nothrow_default_constructible_v && std::is_nothrow_default_constructible_v) + : first{}, + last{} {} + + /** + * @brief Creates an iterable object from a pair of iterators. + * @param from Begin iterator. + * @param to End iterator. + */ + constexpr iterable_adaptor(iterator from, sentinel to) noexcept(std::is_nothrow_move_constructible_v && std::is_nothrow_move_constructible_v) + : first{std::move(from)}, + last{std::move(to)} {} + + /** + * @brief Returns an iterator to the beginning. + * @return An iterator to the first element of the range. + */ + [[nodiscard]] constexpr iterator begin() const noexcept { + return first; + } + + /** + * @brief Returns an iterator to the end. + * @return An iterator to the element following the last element of the + * range. + */ + [[nodiscard]] constexpr sentinel end() const noexcept { + return last; + } + + /*! @copydoc begin */ + [[nodiscard]] constexpr iterator cbegin() const noexcept { + return begin(); + } + + /*! @copydoc end */ + [[nodiscard]] constexpr sentinel cend() const noexcept { + return end(); + } + +private: + It first; + Sentinel last; +}; + +} // namespace entt + +#endif + +// #include "../core/memory.hpp" +#ifndef ENTT_CORE_MEMORY_HPP +#define ENTT_CORE_MEMORY_HPP + +#include +#include +#include +#include +#include +// #include "../config/config.h" + + +namespace entt { + +/** + * @brief Unwraps fancy pointers, does nothing otherwise (waiting for C++20). + * @tparam Type Pointer type. + * @param ptr Fancy or raw pointer. + * @return A raw pointer that represents the address of the original pointer. + */ +template +[[nodiscard]] constexpr auto to_address(Type &&ptr) noexcept { + if constexpr(std::is_pointer_v>) { + return ptr; + } else { + return to_address(std::forward(ptr).operator->()); + } +} + +/** + * @brief Utility function to design allocation-aware containers. + * @tparam Allocator Type of allocator. + * @param lhs A valid allocator. + * @param rhs Another valid allocator. + */ +template +constexpr void propagate_on_container_copy_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept { + if constexpr(std::allocator_traits::propagate_on_container_copy_assignment::value) { + lhs = rhs; + } +} + +/** + * @brief Utility function to design allocation-aware containers. + * @tparam Allocator Type of allocator. + * @param lhs A valid allocator. + * @param rhs Another valid allocator. + */ +template +constexpr void propagate_on_container_move_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept { + if constexpr(std::allocator_traits::propagate_on_container_move_assignment::value) { + lhs = std::move(rhs); + } +} + +/** + * @brief Utility function to design allocation-aware containers. + * @tparam Allocator Type of allocator. + * @param lhs A valid allocator. + * @param rhs Another valid allocator. + */ +template +constexpr void propagate_on_container_swap([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept { + if constexpr(std::allocator_traits::propagate_on_container_swap::value) { + using std::swap; + swap(lhs, rhs); + } else { + ENTT_ASSERT_CONSTEXPR(lhs == rhs, "Cannot swap the containers"); + } +} + +/** + * @brief Deleter for allocator-aware unique pointers (waiting for C++20). + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +struct allocation_deleter: private Allocator { + /*! @brief Allocator type. */ + using allocator_type = Allocator; + /*! @brief Pointer type. */ + using pointer = typename std::allocator_traits::pointer; + + /** + * @brief Inherited constructors. + * @param alloc The allocator to use. + */ + constexpr allocation_deleter(const allocator_type &alloc) noexcept(std::is_nothrow_copy_constructible_v) + : Allocator{alloc} {} + + /** + * @brief Destroys the pointed object and deallocates its memory. + * @param ptr A valid pointer to an object of the given type. + */ + constexpr void operator()(pointer ptr) noexcept(std::is_nothrow_destructible_v) { + using alloc_traits = std::allocator_traits; + alloc_traits::destroy(*this, to_address(ptr)); + alloc_traits::deallocate(*this, ptr, 1u); + } +}; + +/** + * @brief Allows `std::unique_ptr` to use allocators (waiting for C++20). + * @tparam Type Type of object to allocate for and to construct. + * @tparam Allocator Type of allocator used to manage memory and elements. + * @tparam Args Types of arguments to use to construct the object. + * @param allocator The allocator to use. + * @param args Parameters to use to construct the object. + * @return A properly initialized unique pointer with a custom deleter. + */ +template +ENTT_CONSTEXPR auto allocate_unique(Allocator &allocator, Args &&...args) { + static_assert(!std::is_array_v, "Array types are not supported"); + + using alloc_traits = typename std::allocator_traits::template rebind_traits; + using allocator_type = typename alloc_traits::allocator_type; + + allocator_type alloc{allocator}; + auto ptr = alloc_traits::allocate(alloc, 1u); + + ENTT_TRY { + alloc_traits::construct(alloc, to_address(ptr), std::forward(args)...); + } + ENTT_CATCH { + alloc_traits::deallocate(alloc, ptr, 1u); + ENTT_THROW; + } + + return std::unique_ptr>{ptr, alloc}; +} + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct uses_allocator_construction { + template + static constexpr auto args([[maybe_unused]] const Allocator &allocator, Params &&...params) noexcept { + if constexpr(!std::uses_allocator_v && std::is_constructible_v) { + return std::forward_as_tuple(std::forward(params)...); + } else { + static_assert(std::uses_allocator_v, "Ill-formed request"); + + if constexpr(std::is_constructible_v) { + return std::tuple{std::allocator_arg, allocator, std::forward(params)...}; + } else { + static_assert(std::is_constructible_v, "Ill-formed request"); + return std::forward_as_tuple(std::forward(params)..., allocator); + } + } + } +}; + +template +struct uses_allocator_construction> { + using type = std::pair; + + template + static constexpr auto args(const Allocator &allocator, std::piecewise_construct_t, First &&first, Second &&second) noexcept { + return std::make_tuple( + std::piecewise_construct, + std::apply([&allocator](auto &&...curr) { return uses_allocator_construction::args(allocator, std::forward(curr)...); }, std::forward(first)), + std::apply([&allocator](auto &&...curr) { return uses_allocator_construction::args(allocator, std::forward(curr)...); }, std::forward(second))); + } + + template + static constexpr auto args(const Allocator &allocator) noexcept { + return uses_allocator_construction::args(allocator, std::piecewise_construct, std::tuple<>{}, std::tuple<>{}); + } + + template + static constexpr auto args(const Allocator &allocator, First &&first, Second &&second) noexcept { + return uses_allocator_construction::args(allocator, std::piecewise_construct, std::forward_as_tuple(std::forward(first)), std::forward_as_tuple(std::forward(second))); + } + + template + static constexpr auto args(const Allocator &allocator, const std::pair &value) noexcept { + return uses_allocator_construction::args(allocator, std::piecewise_construct, std::forward_as_tuple(value.first), std::forward_as_tuple(value.second)); + } + + template + static constexpr auto args(const Allocator &allocator, std::pair &&value) noexcept { + return uses_allocator_construction::args(allocator, std::piecewise_construct, std::forward_as_tuple(std::move(value.first)), std::forward_as_tuple(std::move(value.second))); + } +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Uses-allocator construction utility (waiting for C++20). + * + * Primarily intended for internal use. Prepares the argument list needed to + * create an object of a given type by means of uses-allocator construction. + * + * @tparam Type Type to return arguments for. + * @tparam Allocator Type of allocator used to manage memory and elements. + * @tparam Args Types of arguments to use to construct the object. + * @param allocator The allocator to use. + * @param args Parameters to use to construct the object. + * @return The arguments needed to create an object of the given type. + */ +template +constexpr auto uses_allocator_construction_args(const Allocator &allocator, Args &&...args) noexcept { + return internal::uses_allocator_construction::args(allocator, std::forward(args)...); +} + +/** + * @brief Uses-allocator construction utility (waiting for C++20). + * + * Primarily intended for internal use. Creates an object of a given type by + * means of uses-allocator construction. + * + * @tparam Type Type of object to create. + * @tparam Allocator Type of allocator used to manage memory and elements. + * @tparam Args Types of arguments to use to construct the object. + * @param allocator The allocator to use. + * @param args Parameters to use to construct the object. + * @return A newly created object of the given type. + */ +template +constexpr Type make_obj_using_allocator(const Allocator &allocator, Args &&...args) { + return std::make_from_tuple(internal::uses_allocator_construction::args(allocator, std::forward(args)...)); +} + +/** + * @brief Uses-allocator construction utility (waiting for C++20). + * + * Primarily intended for internal use. Creates an object of a given type by + * means of uses-allocator construction at an uninitialized memory location. + * + * @tparam Type Type of object to create. + * @tparam Allocator Type of allocator used to manage memory and elements. + * @tparam Args Types of arguments to use to construct the object. + * @param value Memory location in which to place the object. + * @param allocator The allocator to use. + * @param args Parameters to use to construct the object. + * @return A pointer to the newly created object of the given type. + */ +template +constexpr Type *uninitialized_construct_using_allocator(Type *value, const Allocator &allocator, Args &&...args) { + return std::apply([value](auto &&...curr) { return ::new(value) Type(std::forward(curr)...); }, internal::uses_allocator_construction::args(allocator, std::forward(args)...)); +} + +} // namespace entt + +#endif + +// #include "../core/type_traits.hpp" +#ifndef ENTT_CORE_TYPE_TRAITS_HPP +#define ENTT_CORE_TYPE_TRAITS_HPP + +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "fwd.hpp" + + +namespace entt { + +/** + * @brief Utility class to disambiguate overloaded functions. + * @tparam N Number of choices available. + */ +template +struct choice_t + // unfortunately, doxygen cannot parse such a construct + : /*! @cond TURN_OFF_DOXYGEN */ choice_t /*! @endcond */ +{}; + +/*! @copybrief choice_t */ +template<> +struct choice_t<0> {}; + +/** + * @brief Variable template for the choice trick. + * @tparam N Number of choices available. + */ +template +inline constexpr choice_t choice{}; + +/** + * @brief Identity type trait. + * + * Useful to establish non-deduced contexts in template argument deduction + * (waiting for C++20) or to provide types through function arguments. + * + * @tparam Type A type. + */ +template +struct type_identity { + /*! @brief Identity type. */ + using type = Type; +}; + +/** + * @brief Helper type. + * @tparam Type A type. + */ +template +using type_identity_t = typename type_identity::type; + +/** + * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains. + * @tparam Type The type of which to return the size. + */ +template +struct size_of: std::integral_constant {}; + +/*! @copydoc size_of */ +template +struct size_of> + // NOLINTNEXTLINE(bugprone-sizeof-expression) + : std::integral_constant {}; + +/** + * @brief Helper variable template. + * @tparam Type The type of which to return the size. + */ +template +inline constexpr std::size_t size_of_v = size_of::value; + +/** + * @brief Using declaration to be used to _repeat_ the same type a number of + * times equal to the size of a given parameter pack. + * @tparam Type A type to repeat. + */ +template +using unpack_as_type = Type; + +/** + * @brief Helper variable template to be used to _repeat_ the same value a + * number of times equal to the size of a given parameter pack. + * @tparam Value A value to repeat. + */ +template +inline constexpr auto unpack_as_value = Value; + +/** + * @brief Wraps a static constant. + * @tparam Value A static constant. + */ +template +using integral_constant = std::integral_constant; + +/** + * @brief Alias template to facilitate the creation of named values. + * @tparam Value A constant value at least convertible to `id_type`. + */ +template +using tag = integral_constant; + +/** + * @brief A class to use to push around lists of types, nothing more. + * @tparam Type Types provided by the type list. + */ +template +struct type_list { + /*! @brief Type list type. */ + using type = type_list; + /*! @brief Compile-time number of elements in the type list. */ + static constexpr auto size = sizeof...(Type); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_element; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Index Index of the type to return. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element> + : type_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element<0u, type_list> { + /*! @brief Searched type. */ + using type = First; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Type list to search into. + */ +template +using type_list_element_t = typename type_list_element::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_index; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 1u + type_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + static_assert(type_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +inline constexpr std::size_t type_list_index_v = type_list_index::value; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @return A type list composed by the types of both the type lists. + */ +template +constexpr type_list operator+(type_list, type_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_cat; + +/*! @brief Concatenates multiple type lists. */ +template<> +struct type_list_cat<> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list<>; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @tparam List Other type lists, if any. + */ +template +struct type_list_cat, type_list, List...> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = typename type_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the type list. + */ +template +struct type_list_cat> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list; +}; + +/** + * @brief Helper type. + * @tparam List Type lists to concatenate. + */ +template +using type_list_cat_t = typename type_list_cat::type; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct type_list_unique; + +template +struct type_list_unique, Type...> + : std::conditional_t<(std::is_same_v || ...), type_list_unique, Type...>, type_list_unique, Type..., First>> {}; + +template +struct type_list_unique, Type...> { + using type = type_list; +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Removes duplicates types from a type list. + * @tparam List Type list. + */ +template +struct type_list_unique { + /*! @brief A type list without duplicate types. */ + using type = typename internal::type_list_unique::type; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + */ +template +using type_list_unique_t = typename type_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a type list contains a + * given type, false otherwise. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +struct type_list_contains; + +/** + * @copybrief type_list_contains + * @tparam Type Types provided by the type list. + * @tparam Other Type to look for. + */ +template +struct type_list_contains, Other> + : std::bool_constant<(std::is_same_v || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +inline constexpr bool type_list_contains_v = type_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_diff; + +/** + * @brief Computes the difference between two type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + */ +template +struct type_list_diff, type_list> { + /*! @brief A type list that is the difference between the two type lists. */ + using type = type_list_cat_t, Type>, type_list<>, type_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Type lists between which to compute the difference. + */ +template +using type_list_diff_t = typename type_list_diff::type; + +/*! @brief Primary template isn't defined on purpose. */ +template class> +struct type_list_transform; + +/** + * @brief Applies a given _function_ to a type list and generate a new list. + * @tparam Type Types provided by the type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +struct type_list_transform, Op> { + /*! @brief Resulting type list after applying the transform function. */ + // NOLINTNEXTLINE(modernize-type-traits) + using type = type_list::type...>; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +using type_list_transform_t = typename type_list_transform::type; + +/** + * @brief A class to use to push around lists of constant values, nothing more. + * @tparam Value Values provided by the value list. + */ +template +struct value_list { + /*! @brief Value list type. */ + using type = value_list; + /*! @brief Compile-time number of elements in the value list. */ + static constexpr auto size = sizeof...(Value); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_element; + +/** + * @brief Provides compile-time indexed access to the values of a value list. + * @tparam Index Index of the value to return. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element> + : value_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element<0u, value_list> { + /*! @brief Searched type. */ + using type = decltype(Value); + /*! @brief Searched value. */ + static constexpr auto value = Value; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Value list to search into. + */ +template +using value_list_element_t = typename value_list_element::type; + +/** + * @brief Helper type. + * @tparam Index Index of the value to return. + * @tparam List Value list to search into. + */ +template +inline constexpr auto value_list_element_v = value_list_element::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_index; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam First First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 1u + value_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + static_assert(value_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +inline constexpr std::size_t value_list_index_v = value_list_index::value; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @return A value list composed by the values of both the value lists. + */ +template +constexpr value_list operator+(value_list, value_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_cat; + +/*! @brief Concatenates multiple value lists. */ +template<> +struct value_list_cat<> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list<>; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @tparam List Other value lists, if any. + */ +template +struct value_list_cat, value_list, List...> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = typename value_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the value list. + */ +template +struct value_list_cat> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list; +}; + +/** + * @brief Helper type. + * @tparam List Value lists to concatenate. + */ +template +using value_list_cat_t = typename value_list_cat::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_unique; + +/** + * @brief Removes duplicates values from a value list. + * @tparam Value One of the values provided by the given value list. + * @tparam Other The other values provided by the given value list. + */ +template +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = std::conditional_t< + ((Value == Other) || ...), + typename value_list_unique>::type, + value_list_cat_t, typename value_list_unique>::type>>; +}; + +/*! @brief Removes duplicates values from a value list. */ +template<> +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = value_list<>; +}; + +/** + * @brief Helper type. + * @tparam Type A value list. + */ +template +using value_list_unique_t = typename value_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a value list contains + * a given value, false otherwise. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +struct value_list_contains; + +/** + * @copybrief value_list_contains + * @tparam Value Values provided by the value list. + * @tparam Other Value to look for. + */ +template +struct value_list_contains, Other> + : std::bool_constant<((Value == Other) || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +inline constexpr bool value_list_contains_v = value_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_diff; + +/** + * @brief Computes the difference between two value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + */ +template +struct value_list_diff, value_list> { + /*! @brief A value list that is the difference between the two value lists. */ + using type = value_list_cat_t, Value>, value_list<>, value_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Value lists between which to compute the difference. + */ +template +using value_list_diff_t = typename value_list_diff::type; + +/*! @brief Same as std::is_invocable, but with tuples. */ +template +struct is_applicable: std::false_type {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @brief Helper variable template. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_v = is_applicable::value; + +/*! @brief Same as std::is_invocable_r, but with tuples for arguments. */ +template +struct is_applicable_r: std::false_type {}; + +/** + * @copybrief is_applicable_r + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +struct is_applicable_r>: std::is_invocable_r {}; + +/** + * @brief Helper variable template. + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_r_v = is_applicable_r::value; + +/** + * @brief Provides the member constant `value` to true if a given type is + * complete, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_complete: std::false_type {}; + +/*! @copydoc is_complete */ +template +struct is_complete>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_complete_v = is_complete::value; + +/** + * @brief Provides the member constant `value` to true if a given type is an + * iterator, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_iterator: std::false_type {}; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_iterator_category: std::false_type {}; + +template +struct has_iterator_category::iterator_category>>: std::true_type {}; + +} // namespace internal +/*! @endcond */ + +/*! @copydoc is_iterator */ +template +struct is_iterator>>>> + : internal::has_iterator_category {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_iterator_v = is_iterator::value; + +/** + * @brief Provides the member constant `value` to true if a given type is both + * an empty and non-final class, false otherwise. + * @tparam Type The type to test + */ +template +struct is_ebco_eligible + : std::bool_constant && !std::is_final_v> {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_ebco_eligible_v = is_ebco_eligible::value; + +/** + * @brief Provides the member constant `value` to true if `Type::is_transparent` + * is valid and denotes a type, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_transparent: std::false_type {}; + +/*! @copydoc is_transparent */ +template +struct is_transparent>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_transparent_v = is_transparent::value; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_tuple_size_value: std::false_type {}; + +template +struct has_tuple_size_value::value)>>: std::true_type {}; + +template +struct has_value_type: std::false_type {}; + +template +struct has_value_type>: std::true_type {}; + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable(); + +template +[[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence) { + return (dispatch_is_equality_comparable>() && ...); +} + +template +[[nodiscard]] constexpr bool maybe_equality_comparable(char) { + return false; +} + +template +[[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval() == std::declval()) { + return true; +} + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable() { + // NOLINTBEGIN(modernize-use-transparent-functors) + if constexpr(std::is_array_v) { + return false; + } else if constexpr(is_complete_v>>) { + if constexpr(has_tuple_size_value::value) { + return maybe_equality_comparable(0) && unpack_maybe_equality_comparable(std::make_index_sequence::value>{}); + } else { + return maybe_equality_comparable(0); + } + } else if constexpr(has_value_type::value) { + if constexpr(is_iterator_v || std::is_same_v || dispatch_is_equality_comparable()) { + return maybe_equality_comparable(0); + } else { + return false; + } + } else { + return maybe_equality_comparable(0); + } + // NOLINTEND(modernize-use-transparent-functors) +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Provides the member constant `value` to true if a given type is + * equality comparable, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_equality_comparable: std::bool_constant()> {}; + +/*! @copydoc is_equality_comparable */ +template +struct is_equality_comparable: is_equality_comparable {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_equality_comparable_v = is_equality_comparable::value; + +/** + * @brief Transcribes the constness of a type to another type. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = std::remove_const_t; +}; + +/*! @copydoc constness_as */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = const To; +}; + +/** + * @brief Alias template to facilitate the transcription of the constness. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +using constness_as_t = typename constness_as::type; + +/** + * @brief Extracts the class of a non-static member object or function. + * @tparam Member A pointer to a non-static member object or function. + */ +template +class member_class { + static_assert(std::is_member_pointer_v, "Invalid pointer type to non-static member object or function"); + + template + static Class *clazz(Ret (Class::*)(Args...)); + + template + static Class *clazz(Ret (Class::*)(Args...) const); + + template + static Class *clazz(Type Class::*); + +public: + /*! @brief The class of the given non-static member object or function. */ + using type = std::remove_pointer_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Member A pointer to a non-static member object or function. + */ +template +using member_class_t = typename member_class::type; + +/** + * @brief Extracts the n-th argument of a _callable_ type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid _callable_ type. + */ +template +class nth_argument { + template + static constexpr type_list pick_up(Ret (*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...) const); + + template + static constexpr type_list pick_up(Type Class ::*); + + template + static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&); + +public: + /*! @brief N-th argument of the _callable_ type. */ + using type = type_list_element_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid function, member function or data member type. + */ +template +using nth_argument_t = typename nth_argument::type; + +} // namespace entt + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::type_list_element> {}; + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::value_list_element> {}; + +#endif + +// #include "fwd.hpp" +#ifndef ENTT_CONTAINER_FWD_HPP +#define ENTT_CONTAINER_FWD_HPP + +#include +#include +#include +#include + +namespace entt { + +template< + typename Key, + typename Type, + typename = std::hash, + typename = std::equal_to<>, + typename = std::allocator>> +class dense_map; + +template< + typename Type, + typename = std::hash, + typename = std::equal_to<>, + typename = std::allocator> +class dense_set; + +template +class basic_table; + +/** + * @brief Alias declaration for the most common use case. + * @tparam Type Element types. + */ +template +using table = basic_table...>; + +} // namespace entt + +#endif + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +static constexpr std::size_t dense_map_placeholder_position = (std::numeric_limits::max)(); + +template +struct dense_map_node final { + using value_type = std::pair; + + template + dense_map_node(const std::size_t pos, Args &&...args) + : next{pos}, + element{std::forward(args)...} {} + + template + dense_map_node(std::allocator_arg_t, const Allocator &allocator, const std::size_t pos, Args &&...args) + : next{pos}, + element{entt::make_obj_using_allocator(allocator, std::forward(args)...)} {} + + template + dense_map_node(std::allocator_arg_t, const Allocator &allocator, const dense_map_node &other) + : next{other.next}, + element{entt::make_obj_using_allocator(allocator, other.element)} {} + + template + dense_map_node(std::allocator_arg_t, const Allocator &allocator, dense_map_node &&other) + : next{other.next}, + element{entt::make_obj_using_allocator(allocator, std::move(other.element))} {} + + std::size_t next; + value_type element; +}; + +template +class dense_map_iterator final { + template + friend class dense_map_iterator; + + using first_type = decltype(std::as_const(std::declval()->element.first)); + using second_type = decltype((std::declval()->element.second)); + +public: + using value_type = std::pair; + using pointer = input_iterator_pointer; + using reference = value_type; + using difference_type = std::ptrdiff_t; + using iterator_category = std::input_iterator_tag; + using iterator_concept = std::random_access_iterator_tag; + + constexpr dense_map_iterator() noexcept + : it{} {} + + constexpr dense_map_iterator(const It iter) noexcept + : it{iter} {} + + template && std::is_constructible_v>> + constexpr dense_map_iterator(const dense_map_iterator &other) noexcept + : it{other.it} {} + + constexpr dense_map_iterator &operator++() noexcept { + return ++it, *this; + } + + constexpr dense_map_iterator operator++(int) noexcept { + const dense_map_iterator orig = *this; + return ++(*this), orig; + } + + constexpr dense_map_iterator &operator--() noexcept { + return --it, *this; + } + + constexpr dense_map_iterator operator--(int) noexcept { + const dense_map_iterator orig = *this; + return operator--(), orig; + } + + constexpr dense_map_iterator &operator+=(const difference_type value) noexcept { + it += value; + return *this; + } + + constexpr dense_map_iterator operator+(const difference_type value) const noexcept { + dense_map_iterator copy = *this; + return (copy += value); + } + + constexpr dense_map_iterator &operator-=(const difference_type value) noexcept { + return (*this += -value); + } + + constexpr dense_map_iterator operator-(const difference_type value) const noexcept { + return (*this + -value); + } + + [[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept { + return {it[value].element.first, it[value].element.second}; + } + + [[nodiscard]] constexpr pointer operator->() const noexcept { + return operator*(); + } + + [[nodiscard]] constexpr reference operator*() const noexcept { + return operator[](0); + } + + template + friend constexpr std::ptrdiff_t operator-(const dense_map_iterator &, const dense_map_iterator &) noexcept; + + template + friend constexpr bool operator==(const dense_map_iterator &, const dense_map_iterator &) noexcept; + + template + friend constexpr bool operator<(const dense_map_iterator &, const dense_map_iterator &) noexcept; + +private: + It it; +}; + +template +[[nodiscard]] constexpr std::ptrdiff_t operator-(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return lhs.it - rhs.it; +} + +template +[[nodiscard]] constexpr bool operator==(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return lhs.it == rhs.it; +} + +template +[[nodiscard]] constexpr bool operator!=(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +template +[[nodiscard]] constexpr bool operator<(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return lhs.it < rhs.it; +} + +template +[[nodiscard]] constexpr bool operator>(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return rhs < lhs; +} + +template +[[nodiscard]] constexpr bool operator<=(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return !(lhs > rhs); +} + +template +[[nodiscard]] constexpr bool operator>=(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return !(lhs < rhs); +} + +template +class dense_map_local_iterator final { + template + friend class dense_map_local_iterator; + + using first_type = decltype(std::as_const(std::declval()->element.first)); + using second_type = decltype((std::declval()->element.second)); + +public: + using value_type = std::pair; + using pointer = input_iterator_pointer; + using reference = value_type; + using difference_type = std::ptrdiff_t; + using iterator_category = std::input_iterator_tag; + using iterator_concept = std::forward_iterator_tag; + + constexpr dense_map_local_iterator() noexcept = default; + + constexpr dense_map_local_iterator(It iter, const std::size_t pos) noexcept + : it{iter}, + offset{pos} {} + + template && std::is_constructible_v>> + constexpr dense_map_local_iterator(const dense_map_local_iterator &other) noexcept + : it{other.it}, + offset{other.offset} {} + + constexpr dense_map_local_iterator &operator++() noexcept { + return (offset = it[static_cast(offset)].next), *this; + } + + constexpr dense_map_local_iterator operator++(int) noexcept { + const dense_map_local_iterator orig = *this; + return ++(*this), orig; + } + + [[nodiscard]] constexpr pointer operator->() const noexcept { + return operator*(); + } + + [[nodiscard]] constexpr reference operator*() const noexcept { + const auto idx = static_cast(offset); + return {it[idx].element.first, it[idx].element.second}; + } + + [[nodiscard]] constexpr std::size_t index() const noexcept { + return offset; + } + +private: + It it{}; + std::size_t offset{dense_map_placeholder_position}; +}; + +template +[[nodiscard]] constexpr bool operator==(const dense_map_local_iterator &lhs, const dense_map_local_iterator &rhs) noexcept { + return lhs.index() == rhs.index(); +} + +template +[[nodiscard]] constexpr bool operator!=(const dense_map_local_iterator &lhs, const dense_map_local_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Associative container for key-value pairs with unique keys. + * + * Internally, elements are organized into buckets. Which bucket an element is + * placed into depends entirely on the hash of its key. Keys with the same hash + * code appear in the same bucket. + * + * @tparam Key Key type of the associative container. + * @tparam Type Mapped type of the associative container. + * @tparam Hash Type of function to use to hash the keys. + * @tparam KeyEqual Type of function to use to compare the keys for equality. + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +class dense_map { + static constexpr float default_threshold = 0.875f; + static constexpr std::size_t minimum_capacity = 8u; + static constexpr std::size_t placeholder_position = internal::dense_map_placeholder_position; + + using node_type = internal::dense_map_node; + using alloc_traits = std::allocator_traits; + static_assert(std::is_same_v>, "Invalid value type"); + using sparse_container_type = std::vector>; + using packed_container_type = std::vector>; + + template + [[nodiscard]] std::size_t key_to_bucket(const Other &key) const noexcept { + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay) + return fast_mod(static_cast(sparse.second()(key)), bucket_count()); + } + + template + [[nodiscard]] auto constrained_find(const Other &key, const std::size_t bucket) { + for(auto offset = sparse.first()[bucket]; offset != placeholder_position; offset = packed.first()[offset].next) { + if(packed.second()(packed.first()[offset].element.first, key)) { + return begin() + static_cast(offset); + } + } + + return end(); + } + + template + [[nodiscard]] auto constrained_find(const Other &key, const std::size_t bucket) const { + for(auto offset = sparse.first()[bucket]; offset != placeholder_position; offset = packed.first()[offset].next) { + if(packed.second()(packed.first()[offset].element.first, key)) { + return cbegin() + static_cast(offset); + } + } + + return cend(); + } + + template + [[nodiscard]] auto insert_or_do_nothing(Other &&key, Args &&...args) { + const auto index = key_to_bucket(key); + + if(auto it = constrained_find(key, index); it != end()) { + return std::make_pair(it, false); + } + + packed.first().emplace_back(sparse.first()[index], std::piecewise_construct, std::forward_as_tuple(std::forward(key)), std::forward_as_tuple(std::forward(args)...)); + sparse.first()[index] = packed.first().size() - 1u; + rehash_if_required(); + + return std::make_pair(--end(), true); + } + + template + [[nodiscard]] auto insert_or_overwrite(Other &&key, Arg &&value) { + const auto index = key_to_bucket(key); + + if(auto it = constrained_find(key, index); it != end()) { + it->second = std::forward(value); + return std::make_pair(it, false); + } + + packed.first().emplace_back(sparse.first()[index], std::forward(key), std::forward(value)); + sparse.first()[index] = packed.first().size() - 1u; + rehash_if_required(); + + return std::make_pair(--end(), true); + } + + void move_and_pop(const std::size_t pos) { + if(const auto last = size() - 1u; pos != last) { + size_type *curr = &sparse.first()[key_to_bucket(packed.first().back().element.first)]; + packed.first()[pos] = std::move(packed.first().back()); + for(; *curr != last; curr = &packed.first()[*curr].next) {} + *curr = pos; + } + + packed.first().pop_back(); + } + + void rehash_if_required() { + if(const auto bc = bucket_count(); size() > static_cast(static_cast(bc) * max_load_factor())) { + rehash(bc * 2u); + } + } + +public: + /*! @brief Allocator type. */ + using allocator_type = Allocator; + /*! @brief Key type of the container. */ + using key_type = Key; + /*! @brief Mapped type of the container. */ + using mapped_type = Type; + /*! @brief Key-value type of the container. */ + using value_type = std::pair; + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + /*! @brief Signed integer type. */ + using difference_type = std::ptrdiff_t; + /*! @brief Type of function to use to hash the keys. */ + using hasher = Hash; + /*! @brief Type of function to use to compare the keys for equality. */ + using key_equal = KeyEqual; + /*! @brief Input iterator type. */ + using iterator = internal::dense_map_iterator; + /*! @brief Constant input iterator type. */ + using const_iterator = internal::dense_map_iterator; + /*! @brief Input iterator type. */ + using local_iterator = internal::dense_map_local_iterator; + /*! @brief Constant input iterator type. */ + using const_local_iterator = internal::dense_map_local_iterator; + + /*! @brief Default constructor. */ + dense_map() + : dense_map{minimum_capacity} {} + + /** + * @brief Constructs an empty container with a given allocator. + * @param allocator The allocator to use. + */ + explicit dense_map(const allocator_type &allocator) + : dense_map{minimum_capacity, hasher{}, key_equal{}, allocator} {} + + /** + * @brief Constructs an empty container with a given allocator and user + * supplied minimal number of buckets. + * @param cnt Minimal number of buckets. + * @param allocator The allocator to use. + */ + dense_map(const size_type cnt, const allocator_type &allocator) + : dense_map{cnt, hasher{}, key_equal{}, allocator} {} + + /** + * @brief Constructs an empty container with a given allocator, hash + * function and user supplied minimal number of buckets. + * @param cnt Minimal number of buckets. + * @param hash Hash function to use. + * @param allocator The allocator to use. + */ + dense_map(const size_type cnt, const hasher &hash, const allocator_type &allocator) + : dense_map{cnt, hash, key_equal{}, allocator} {} + + /** + * @brief Constructs an empty container with a given allocator, hash + * function, compare function and user supplied minimal number of buckets. + * @param cnt Minimal number of buckets. + * @param hash Hash function to use. + * @param equal Compare function to use. + * @param allocator The allocator to use. + */ + explicit dense_map(const size_type cnt, const hasher &hash = hasher{}, const key_equal &equal = key_equal{}, const allocator_type &allocator = allocator_type{}) + : sparse{allocator, hash}, + packed{allocator, equal} { + rehash(cnt); + } + + /*! @brief Default copy constructor. */ + dense_map(const dense_map &) = default; + + /** + * @brief Allocator-extended copy constructor. + * @param other The instance to copy from. + * @param allocator The allocator to use. + */ + dense_map(const dense_map &other, const allocator_type &allocator) + : sparse{std::piecewise_construct, std::forward_as_tuple(other.sparse.first(), allocator), std::forward_as_tuple(other.sparse.second())}, + packed{std::piecewise_construct, std::forward_as_tuple(other.packed.first(), allocator), std::forward_as_tuple(other.packed.second())}, + threshold{other.threshold} {} + + /*! @brief Default move constructor. */ + dense_map(dense_map &&) noexcept = default; + + /** + * @brief Allocator-extended move constructor. + * @param other The instance to move from. + * @param allocator The allocator to use. + */ + dense_map(dense_map &&other, const allocator_type &allocator) + : sparse{std::piecewise_construct, std::forward_as_tuple(std::move(other.sparse.first()), allocator), std::forward_as_tuple(std::move(other.sparse.second()))}, + packed{std::piecewise_construct, std::forward_as_tuple(std::move(other.packed.first()), allocator), std::forward_as_tuple(std::move(other.packed.second()))}, + threshold{other.threshold} {} + + /*! @brief Default destructor. */ + ~dense_map() = default; + + /** + * @brief Default copy assignment operator. + * @return This container. + */ + dense_map &operator=(const dense_map &) = default; + + /** + * @brief Default move assignment operator. + * @return This container. + */ + dense_map &operator=(dense_map &&) noexcept = default; + + /** + * @brief Exchanges the contents with those of a given container. + * @param other Container to exchange the content with. + */ + void swap(dense_map &other) noexcept { + using std::swap; + swap(sparse, other.sparse); + swap(packed, other.packed); + swap(threshold, other.threshold); + } + + /** + * @brief Returns the associated allocator. + * @return The associated allocator. + */ + [[nodiscard]] constexpr allocator_type get_allocator() const noexcept { + return sparse.first().get_allocator(); + } + + /** + * @brief Returns an iterator to the beginning. + * + * If the array is empty, the returned iterator will be equal to `end()`. + * + * @return An iterator to the first instance of the internal array. + */ + [[nodiscard]] const_iterator cbegin() const noexcept { + return packed.first().begin(); + } + + /*! @copydoc cbegin */ + [[nodiscard]] const_iterator begin() const noexcept { + return cbegin(); + } + + /*! @copydoc begin */ + [[nodiscard]] iterator begin() noexcept { + return packed.first().begin(); + } + + /** + * @brief Returns an iterator to the end. + * @return An iterator to the element following the last instance of the + * internal array. + */ + [[nodiscard]] const_iterator cend() const noexcept { + return packed.first().end(); + } + + /*! @copydoc cend */ + [[nodiscard]] const_iterator end() const noexcept { + return cend(); + } + + /*! @copydoc end */ + [[nodiscard]] iterator end() noexcept { + return packed.first().end(); + } + + /** + * @brief Checks whether a container is empty. + * @return True if the container is empty, false otherwise. + */ + [[nodiscard]] bool empty() const noexcept { + return packed.first().empty(); + } + + /** + * @brief Returns the number of elements in a container. + * @return Number of elements in a container. + */ + [[nodiscard]] size_type size() const noexcept { + return packed.first().size(); + } + + /** + * @brief Returns the maximum possible number of elements. + * @return Maximum possible number of elements. + */ + [[nodiscard]] size_type max_size() const noexcept { + return packed.first().max_size(); + } + + /*! @brief Clears the container. */ + void clear() noexcept { + sparse.first().clear(); + packed.first().clear(); + rehash(0u); + } + + /** + * @brief Inserts an element into the container, if the key does not exist. + * @param value A key-value pair eventually convertible to the value type. + * @return A pair consisting of an iterator to the inserted element (or to + * the element that prevented the insertion) and a bool denoting whether the + * insertion took place. + */ + std::pair insert(const value_type &value) { + return insert_or_do_nothing(value.first, value.second); + } + + /*! @copydoc insert */ + std::pair insert(value_type &&value) { + return insert_or_do_nothing(std::move(value.first), std::move(value.second)); + } + + /** + * @copydoc insert + * @tparam Arg Type of the key-value pair to insert into the container. + */ + template + std::enable_if_t, std::pair> + insert(Arg &&value) { + return insert_or_do_nothing(std::forward(value).first, std::forward(value).second); + } + + /** + * @brief Inserts elements into the container, if their keys do not exist. + * @tparam It Type of input iterator. + * @param first An iterator to the first element of the range of elements. + * @param last An iterator past the last element of the range of elements. + */ + template + void insert(It first, It last) { + for(; first != last; ++first) { + insert(*first); + } + } + + /** + * @brief Inserts an element into the container or assigns to the current + * element if the key already exists. + * @tparam Arg Type of the value to insert or assign. + * @param key A key used both to look up and to insert if not found. + * @param value A value to insert or assign. + * @return A pair consisting of an iterator to the element and a bool + * denoting whether the insertion took place. + */ + template + std::pair insert_or_assign(const key_type &key, Arg &&value) { + return insert_or_overwrite(key, std::forward(value)); + } + + /*! @copydoc insert_or_assign */ + template + std::pair insert_or_assign(key_type &&key, Arg &&value) { + return insert_or_overwrite(std::move(key), std::forward(value)); + } + + /** + * @brief Constructs an element in-place, if the key does not exist. + * + * The element is also constructed when the container already has the key, + * in which case the newly constructed object is destroyed immediately. + * + * @tparam Args Types of arguments to forward to the constructor of the + * element. + * @param args Arguments to forward to the constructor of the element. + * @return A pair consisting of an iterator to the inserted element (or to + * the element that prevented the insertion) and a bool denoting whether the + * insertion took place. + */ + template + std::pair emplace([[maybe_unused]] Args &&...args) { + if constexpr(sizeof...(Args) == 0u) { + return insert_or_do_nothing(key_type{}); + } else if constexpr(sizeof...(Args) == 1u) { + return insert_or_do_nothing(std::forward(args).first..., std::forward(args).second...); + } else if constexpr(sizeof...(Args) == 2u) { + return insert_or_do_nothing(std::forward(args)...); + } else { + auto &node = packed.first().emplace_back(packed.first().size(), std::forward(args)...); + const auto index = key_to_bucket(node.element.first); + + if(auto it = constrained_find(node.element.first, index); it != end()) { + packed.first().pop_back(); + return std::make_pair(it, false); + } + + std::swap(node.next, sparse.first()[index]); + rehash_if_required(); + + return std::make_pair(--end(), true); + } + } + + /** + * @brief Inserts in-place if the key does not exist, does nothing if the + * key exists. + * @tparam Args Types of arguments to forward to the constructor of the + * element. + * @param key A key used both to look up and to insert if not found. + * @param args Arguments to forward to the constructor of the element. + * @return A pair consisting of an iterator to the inserted element (or to + * the element that prevented the insertion) and a bool denoting whether the + * insertion took place. + */ + template + std::pair try_emplace(const key_type &key, Args &&...args) { + return insert_or_do_nothing(key, std::forward(args)...); + } + + /*! @copydoc try_emplace */ + template + std::pair try_emplace(key_type &&key, Args &&...args) { + return insert_or_do_nothing(std::move(key), std::forward(args)...); + } + + /** + * @brief Removes an element from a given position. + * @param pos An iterator to the element to remove. + * @return An iterator following the removed element. + */ + iterator erase(const_iterator pos) { + const auto diff = pos - cbegin(); + erase(pos->first); + return begin() + diff; + } + + /** + * @brief Removes the given elements from a container. + * @param first An iterator to the first element of the range of elements. + * @param last An iterator past the last element of the range of elements. + * @return An iterator following the last removed element. + */ + iterator erase(const_iterator first, const_iterator last) { + const auto dist = first - cbegin(); + + for(auto from = last - cbegin(); from != dist; --from) { + erase(packed.first()[static_cast(from) - 1u].element.first); + } + + return (begin() + dist); + } + + /** + * @brief Removes the element associated with a given key. + * @param key A key value of an element to remove. + * @return Number of elements removed (either 0 or 1). + */ + size_type erase(const key_type &key) { + for(size_type *curr = &sparse.first()[key_to_bucket(key)]; *curr != placeholder_position; curr = &packed.first()[*curr].next) { + if(packed.second()(packed.first()[*curr].element.first, key)) { + const auto index = *curr; + *curr = packed.first()[*curr].next; + move_and_pop(index); + return 1u; + } + } + + return 0u; + } + + /** + * @brief Accesses a given element with bounds checking. + * @param key A key of an element to find. + * @return A reference to the mapped value of the requested element. + */ + [[nodiscard]] mapped_type &at(const key_type &key) { + auto it = find(key); + ENTT_ASSERT(it != end(), "Invalid key"); + return it->second; + } + + /*! @copydoc at */ + [[nodiscard]] const mapped_type &at(const key_type &key) const { + auto it = find(key); + ENTT_ASSERT(it != cend(), "Invalid key"); + return it->second; + } + + /** + * @brief Accesses a given element with bounds checking. + * @tparam Other Type of the key of an element to find. + * @param key A key of an element to find. + * @return A reference to the mapped value of the requested element. + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + at(const Other &key) const { + auto it = find(key); + ENTT_ASSERT(it != cend(), "Invalid key"); + return it->second; + } + + /*! @copydoc at */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + at(const Other &key) { + auto it = find(key); + ENTT_ASSERT(it != end(), "Invalid key"); + return it->second; + } + + /** + * @brief Accesses or inserts a given element. + * @param key A key of an element to find or insert. + * @return A reference to the mapped value of the requested element. + */ + [[nodiscard]] mapped_type &operator[](const key_type &key) { + return insert_or_do_nothing(key).first->second; + } + + /** + * @brief Accesses or inserts a given element. + * @param key A key of an element to find or insert. + * @return A reference to the mapped value of the requested element. + */ + [[nodiscard]] mapped_type &operator[](key_type &&key) { + return insert_or_do_nothing(std::move(key)).first->second; + } + + /** + * @brief Returns the number of elements matching a key (either 1 or 0). + * @param key Key value of an element to search for. + * @return Number of elements matching the key (either 1 or 0). + */ + [[nodiscard]] size_type count(const key_type &key) const { + return find(key) != end(); + } + + /** + * @brief Returns the number of elements matching a key (either 1 or 0). + * @tparam Other Type of the key value of an element to search for. + * @param key Key value of an element to search for. + * @return Number of elements matching the key (either 1 or 0). + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + count(const Other &key) const { + return find(key) != end(); + } + + /** + * @brief Finds an element with a given key. + * @param key Key value of an element to search for. + * @return An iterator to an element with the given key. If no such element + * is found, a past-the-end iterator is returned. + */ + [[nodiscard]] iterator find(const key_type &key) { + return constrained_find(key, key_to_bucket(key)); + } + + /*! @copydoc find */ + [[nodiscard]] const_iterator find(const key_type &key) const { + return constrained_find(key, key_to_bucket(key)); + } + + /** + * @brief Finds an element with a key that compares _equivalent_ to a given + * key. + * @tparam Other Type of the key value of an element to search for. + * @param key Key value of an element to search for. + * @return An iterator to an element with the given key. If no such element + * is found, a past-the-end iterator is returned. + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + find(const Other &key) { + return constrained_find(key, key_to_bucket(key)); + } + + /*! @copydoc find */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + find(const Other &key) const { + return constrained_find(key, key_to_bucket(key)); + } + + /** + * @brief Returns a range containing all elements with a given key. + * @param key Key value of an element to search for. + * @return A pair of iterators pointing to the first element and past the + * last element of the range. + */ + [[nodiscard]] std::pair equal_range(const key_type &key) { + const auto it = find(key); + return {it, it + !(it == end())}; + } + + /*! @copydoc equal_range */ + [[nodiscard]] std::pair equal_range(const key_type &key) const { + const auto it = find(key); + return {it, it + !(it == cend())}; + } + + /** + * @brief Returns a range containing all elements that compare _equivalent_ + * to a given key. + * @tparam Other Type of an element to search for. + * @param key Key value of an element to search for. + * @return A pair of iterators pointing to the first element and past the + * last element of the range. + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t>> + equal_range(const Other &key) { + const auto it = find(key); + return {it, it + !(it == end())}; + } + + /*! @copydoc equal_range */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t>> + equal_range(const Other &key) const { + const auto it = find(key); + return {it, it + !(it == cend())}; + } + + /** + * @brief Checks if the container contains an element with a given key. + * @param key Key value of an element to search for. + * @return True if there is such an element, false otherwise. + */ + [[nodiscard]] bool contains(const key_type &key) const { + return (find(key) != cend()); + } + + /** + * @brief Checks if the container contains an element with a key that + * compares _equivalent_ to a given value. + * @tparam Other Type of the key value of an element to search for. + * @param key Key value of an element to search for. + * @return True if there is such an element, false otherwise. + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + contains(const Other &key) const { + return (find(key) != cend()); + } + + /** + * @brief Returns an iterator to the beginning of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the beginning of the given bucket. + */ + [[nodiscard]] const_local_iterator cbegin(const size_type index) const { + return {packed.first().begin(), sparse.first()[index]}; + } + + /** + * @brief Returns an iterator to the beginning of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the beginning of the given bucket. + */ + [[nodiscard]] const_local_iterator begin(const size_type index) const { + return cbegin(index); + } + + /** + * @brief Returns an iterator to the beginning of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the beginning of the given bucket. + */ + [[nodiscard]] local_iterator begin(const size_type index) { + return {packed.first().begin(), sparse.first()[index]}; + } + + /** + * @brief Returns an iterator to the end of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the end of the given bucket. + */ + [[nodiscard]] const_local_iterator cend([[maybe_unused]] const size_type index) const { + return {}; + } + + /** + * @brief Returns an iterator to the end of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the end of the given bucket. + */ + [[nodiscard]] const_local_iterator end(const size_type index) const { + return cend(index); + } + + /** + * @brief Returns an iterator to the end of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the end of the given bucket. + */ + [[nodiscard]] local_iterator end([[maybe_unused]] const size_type index) { + return {}; + } + + /** + * @brief Returns the number of buckets. + * @return The number of buckets. + */ + [[nodiscard]] size_type bucket_count() const { + return sparse.first().size(); + } + + /** + * @brief Returns the maximum number of buckets. + * @return The maximum number of buckets. + */ + [[nodiscard]] size_type max_bucket_count() const { + return sparse.first().max_size(); + } + + /** + * @brief Returns the number of elements in a given bucket. + * @param index The index of the bucket to examine. + * @return The number of elements in the given bucket. + */ + [[nodiscard]] size_type bucket_size(const size_type index) const { + return static_cast(std::distance(begin(index), end(index))); + } + + /** + * @brief Returns the bucket for a given key. + * @param key The value of the key to examine. + * @return The bucket for the given key. + */ + [[nodiscard]] size_type bucket(const key_type &key) const { + return key_to_bucket(key); + } + + /** + * @brief Returns the average number of elements per bucket. + * @return The average number of elements per bucket. + */ + [[nodiscard]] float load_factor() const { + return static_cast(size()) / static_cast(bucket_count()); + } + + /** + * @brief Returns the maximum average number of elements per bucket. + * @return The maximum average number of elements per bucket. + */ + [[nodiscard]] float max_load_factor() const { + return threshold; + } + + /** + * @brief Sets the desired maximum average number of elements per bucket. + * @param value A desired maximum average number of elements per bucket. + */ + void max_load_factor(const float value) { + ENTT_ASSERT(value > 0.f, "Invalid load factor"); + threshold = value; + rehash(0u); + } + + /** + * @brief Reserves at least the specified number of buckets and regenerates + * the hash table. + * @param cnt New number of buckets. + */ + void rehash(const size_type cnt) { + auto value = cnt > minimum_capacity ? cnt : minimum_capacity; + const auto cap = static_cast(static_cast(size()) / max_load_factor()); + value = value > cap ? value : cap; + + if(const auto sz = next_power_of_two(value); sz != bucket_count()) { + sparse.first().resize(sz); + + for(auto &&elem: sparse.first()) { + elem = placeholder_position; + } + + for(size_type pos{}, last = size(); pos < last; ++pos) { + const auto index = key_to_bucket(packed.first()[pos].element.first); + packed.first()[pos].next = std::exchange(sparse.first()[index], pos); + } + } + } + + /** + * @brief Reserves space for at least the specified number of elements and + * regenerates the hash table. + * @param cnt New number of elements. + */ + void reserve(const size_type cnt) { + packed.first().reserve(cnt); + rehash(static_cast(std::ceil(static_cast(cnt) / max_load_factor()))); + } + + /** + * @brief Returns the function used to hash the keys. + * @return The function used to hash the keys. + */ + [[nodiscard]] hasher hash_function() const { + return sparse.second(); + } + + /** + * @brief Returns the function used to compare keys for equality. + * @return The function used to compare keys for equality. + */ + [[nodiscard]] key_equal key_eq() const { + return packed.second(); + } + +private: + compressed_pair sparse; + compressed_pair packed; + float threshold{default_threshold}; +}; + +} // namespace entt + +/*! @cond TURN_OFF_DOXYGEN */ +namespace std { + +template +struct uses_allocator, Allocator> + : std::true_type {}; + +} // namespace std +/*! @endcond */ + +#endif + +// #include "../container/dense_set.hpp" +#ifndef ENTT_CONTAINER_DENSE_SET_HPP +#define ENTT_CONTAINER_DENSE_SET_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "../core/bit.hpp" + +// #include "../core/compressed_pair.hpp" + +// #include "../core/type_traits.hpp" + +// #include "fwd.hpp" + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +static constexpr std::size_t dense_set_placeholder_position = (std::numeric_limits::max)(); + +template +class dense_set_iterator final { + template + friend class dense_set_iterator; + +public: + using value_type = typename It::value_type::second_type; + using pointer = const value_type *; + using reference = const value_type &; + using difference_type = std::ptrdiff_t; + using iterator_category = std::random_access_iterator_tag; + + constexpr dense_set_iterator() noexcept + : it{} {} + + constexpr dense_set_iterator(const It iter) noexcept + : it{iter} {} + + template && std::is_constructible_v>> + constexpr dense_set_iterator(const dense_set_iterator &other) noexcept + : it{other.it} {} + + constexpr dense_set_iterator &operator++() noexcept { + return ++it, *this; + } + + constexpr dense_set_iterator operator++(int) noexcept { + const dense_set_iterator orig = *this; + return ++(*this), orig; + } + + constexpr dense_set_iterator &operator--() noexcept { + return --it, *this; + } + + constexpr dense_set_iterator operator--(int) noexcept { + const dense_set_iterator orig = *this; + return operator--(), orig; + } + + constexpr dense_set_iterator &operator+=(const difference_type value) noexcept { + it += value; + return *this; + } + + constexpr dense_set_iterator operator+(const difference_type value) const noexcept { + dense_set_iterator copy = *this; + return (copy += value); + } + + constexpr dense_set_iterator &operator-=(const difference_type value) noexcept { + return (*this += -value); + } + + constexpr dense_set_iterator operator-(const difference_type value) const noexcept { + return (*this + -value); + } + + [[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept { + return it[value].second; + } + + [[nodiscard]] constexpr pointer operator->() const noexcept { + return std::addressof(operator[](0)); + } + + [[nodiscard]] constexpr reference operator*() const noexcept { + return operator[](0); + } + + template + friend constexpr std::ptrdiff_t operator-(const dense_set_iterator &, const dense_set_iterator &) noexcept; + + template + friend constexpr bool operator==(const dense_set_iterator &, const dense_set_iterator &) noexcept; + + template + friend constexpr bool operator<(const dense_set_iterator &, const dense_set_iterator &) noexcept; + +private: + It it; +}; + +template +[[nodiscard]] constexpr std::ptrdiff_t operator-(const dense_set_iterator &lhs, const dense_set_iterator &rhs) noexcept { + return lhs.it - rhs.it; +} + +template +[[nodiscard]] constexpr bool operator==(const dense_set_iterator &lhs, const dense_set_iterator &rhs) noexcept { + return lhs.it == rhs.it; +} + +template +[[nodiscard]] constexpr bool operator!=(const dense_set_iterator &lhs, const dense_set_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +template +[[nodiscard]] constexpr bool operator<(const dense_set_iterator &lhs, const dense_set_iterator &rhs) noexcept { + return lhs.it < rhs.it; +} + +template +[[nodiscard]] constexpr bool operator>(const dense_set_iterator &lhs, const dense_set_iterator &rhs) noexcept { + return rhs < lhs; +} + +template +[[nodiscard]] constexpr bool operator<=(const dense_set_iterator &lhs, const dense_set_iterator &rhs) noexcept { + return !(lhs > rhs); +} + +template +[[nodiscard]] constexpr bool operator>=(const dense_set_iterator &lhs, const dense_set_iterator &rhs) noexcept { + return !(lhs < rhs); +} + +template +class dense_set_local_iterator final { + template + friend class dense_set_local_iterator; + +public: + using value_type = typename It::value_type::second_type; + using pointer = const value_type *; + using reference = const value_type &; + using difference_type = std::ptrdiff_t; + using iterator_category = std::forward_iterator_tag; + + constexpr dense_set_local_iterator() noexcept = default; + + constexpr dense_set_local_iterator(It iter, const std::size_t pos) noexcept + : it{iter}, + offset{pos} {} + + template && std::is_constructible_v>> + constexpr dense_set_local_iterator(const dense_set_local_iterator &other) noexcept + : it{other.it}, + offset{other.offset} {} + + constexpr dense_set_local_iterator &operator++() noexcept { + return offset = it[static_cast(offset)].first, *this; + } + + constexpr dense_set_local_iterator operator++(int) noexcept { + const dense_set_local_iterator orig = *this; + return ++(*this), orig; + } + + [[nodiscard]] constexpr pointer operator->() const noexcept { + return std::addressof(it[static_cast(offset)].second); + } + + [[nodiscard]] constexpr reference operator*() const noexcept { + return *operator->(); + } + + [[nodiscard]] constexpr std::size_t index() const noexcept { + return offset; + } + +private: + It it{}; + std::size_t offset{dense_set_placeholder_position}; +}; + +template +[[nodiscard]] constexpr bool operator==(const dense_set_local_iterator &lhs, const dense_set_local_iterator &rhs) noexcept { + return lhs.index() == rhs.index(); +} + +template +[[nodiscard]] constexpr bool operator!=(const dense_set_local_iterator &lhs, const dense_set_local_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Associative container for unique objects of a given type. + * + * Internally, elements are organized into buckets. Which bucket an element is + * placed into depends entirely on its hash. Elements with the same hash code + * appear in the same bucket. + * + * @tparam Type Value type of the associative container. + * @tparam Hash Type of function to use to hash the values. + * @tparam KeyEqual Type of function to use to compare the values for equality. + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +class dense_set { + static constexpr float default_threshold = 0.875f; + static constexpr std::size_t minimum_capacity = 8u; + static constexpr std::size_t placeholder_position = internal::dense_set_placeholder_position; + + using node_type = std::pair; + using alloc_traits = std::allocator_traits; + static_assert(std::is_same_v, "Invalid value type"); + using sparse_container_type = std::vector>; + using packed_container_type = std::vector>; + + template + [[nodiscard]] std::size_t value_to_bucket(const Other &value) const noexcept { + return fast_mod(static_cast(sparse.second()(value)), bucket_count()); + } + + template + [[nodiscard]] auto constrained_find(const Other &value, const std::size_t bucket) { + for(auto offset = sparse.first()[bucket]; offset != placeholder_position; offset = packed.first()[offset].first) { + if(packed.second()(packed.first()[offset].second, value)) { + return begin() + static_cast(offset); + } + } + + return end(); + } + + template + [[nodiscard]] auto constrained_find(const Other &value, const std::size_t bucket) const { + for(auto offset = sparse.first()[bucket]; offset != placeholder_position; offset = packed.first()[offset].first) { + if(packed.second()(packed.first()[offset].second, value)) { + return cbegin() + static_cast(offset); + } + } + + return cend(); + } + + template + [[nodiscard]] auto insert_or_do_nothing(Other &&value) { + const auto index = value_to_bucket(value); + + if(auto it = constrained_find(value, index); it != end()) { + return std::make_pair(it, false); + } + + packed.first().emplace_back(sparse.first()[index], std::forward(value)); + sparse.first()[index] = packed.first().size() - 1u; + rehash_if_required(); + + return std::make_pair(--end(), true); + } + + void move_and_pop(const std::size_t pos) { + if(const auto last = size() - 1u; pos != last) { + size_type *curr = &sparse.first()[value_to_bucket(packed.first().back().second)]; + packed.first()[pos] = std::move(packed.first().back()); + for(; *curr != last; curr = &packed.first()[*curr].first) {} + *curr = pos; + } + + packed.first().pop_back(); + } + + void rehash_if_required() { + if(const auto bc = bucket_count(); size() > static_cast(static_cast(bc) * max_load_factor())) { + rehash(bc * 2u); + } + } + +public: + /*! @brief Allocator type. */ + using allocator_type = Allocator; + /*! @brief Key type of the container. */ + using key_type = Type; + /*! @brief Value type of the container. */ + using value_type = Type; + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + /*! @brief Signed integer type. */ + using difference_type = std::ptrdiff_t; + /*! @brief Type of function to use to hash the elements. */ + using hasher = Hash; + /*! @brief Type of function to use to compare the elements for equality. */ + using key_equal = KeyEqual; + /*! @brief Random access iterator type. */ + using iterator = internal::dense_set_iterator; + /*! @brief Constant random access iterator type. */ + using const_iterator = internal::dense_set_iterator; + /*! @brief Reverse iterator type. */ + using reverse_iterator = std::reverse_iterator; + /*! @brief Constant reverse iterator type. */ + using const_reverse_iterator = std::reverse_iterator; + /*! @brief Forward iterator type. */ + using local_iterator = internal::dense_set_local_iterator; + /*! @brief Constant forward iterator type. */ + using const_local_iterator = internal::dense_set_local_iterator; + + /*! @brief Default constructor. */ + dense_set() + : dense_set{minimum_capacity} {} + + /** + * @brief Constructs an empty container with a given allocator. + * @param allocator The allocator to use. + */ + explicit dense_set(const allocator_type &allocator) + : dense_set{minimum_capacity, hasher{}, key_equal{}, allocator} {} + + /** + * @brief Constructs an empty container with a given allocator and user + * supplied minimal number of buckets. + * @param cnt Minimal number of buckets. + * @param allocator The allocator to use. + */ + dense_set(const size_type cnt, const allocator_type &allocator) + : dense_set{cnt, hasher{}, key_equal{}, allocator} {} + + /** + * @brief Constructs an empty container with a given allocator, hash + * function and user supplied minimal number of buckets. + * @param cnt Minimal number of buckets. + * @param hash Hash function to use. + * @param allocator The allocator to use. + */ + dense_set(const size_type cnt, const hasher &hash, const allocator_type &allocator) + : dense_set{cnt, hash, key_equal{}, allocator} {} + + /** + * @brief Constructs an empty container with a given allocator, hash + * function, compare function and user supplied minimal number of buckets. + * @param cnt Minimal number of buckets. + * @param hash Hash function to use. + * @param equal Compare function to use. + * @param allocator The allocator to use. + */ + explicit dense_set(const size_type cnt, const hasher &hash = hasher{}, const key_equal &equal = key_equal{}, const allocator_type &allocator = allocator_type{}) + : sparse{allocator, hash}, + packed{allocator, equal} { + rehash(cnt); + } + + /*! @brief Default copy constructor. */ + dense_set(const dense_set &) = default; + + /** + * @brief Allocator-extended copy constructor. + * @param other The instance to copy from. + * @param allocator The allocator to use. + */ + dense_set(const dense_set &other, const allocator_type &allocator) + : sparse{std::piecewise_construct, std::forward_as_tuple(other.sparse.first(), allocator), std::forward_as_tuple(other.sparse.second())}, + packed{std::piecewise_construct, std::forward_as_tuple(other.packed.first(), allocator), std::forward_as_tuple(other.packed.second())}, + threshold{other.threshold} {} + + /*! @brief Default move constructor. */ + dense_set(dense_set &&) noexcept = default; + + /** + * @brief Allocator-extended move constructor. + * @param other The instance to move from. + * @param allocator The allocator to use. + */ + dense_set(dense_set &&other, const allocator_type &allocator) + : sparse{std::piecewise_construct, std::forward_as_tuple(std::move(other.sparse.first()), allocator), std::forward_as_tuple(std::move(other.sparse.second()))}, + packed{std::piecewise_construct, std::forward_as_tuple(std::move(other.packed.first()), allocator), std::forward_as_tuple(std::move(other.packed.second()))}, + threshold{other.threshold} {} + + /*! @brief Default destructor. */ + ~dense_set() = default; + + /** + * @brief Default copy assignment operator. + * @return This container. + */ + dense_set &operator=(const dense_set &) = default; + + /** + * @brief Default move assignment operator. + * @return This container. + */ + dense_set &operator=(dense_set &&) noexcept = default; + + /** + * @brief Exchanges the contents with those of a given container. + * @param other Container to exchange the content with. + */ + void swap(dense_set &other) noexcept { + using std::swap; + swap(sparse, other.sparse); + swap(packed, other.packed); + swap(threshold, other.threshold); + } + + /** + * @brief Returns the associated allocator. + * @return The associated allocator. + */ + [[nodiscard]] constexpr allocator_type get_allocator() const noexcept { + return sparse.first().get_allocator(); + } + + /** + * @brief Returns an iterator to the beginning. + * + * If the array is empty, the returned iterator will be equal to `end()`. + * + * @return An iterator to the first instance of the internal array. + */ + [[nodiscard]] const_iterator cbegin() const noexcept { + return packed.first().begin(); + } + + /*! @copydoc cbegin */ + [[nodiscard]] const_iterator begin() const noexcept { + return cbegin(); + } + + /*! @copydoc begin */ + [[nodiscard]] iterator begin() noexcept { + return packed.first().begin(); + } + + /** + * @brief Returns an iterator to the end. + * @return An iterator to the element following the last instance of the + * internal array. + */ + [[nodiscard]] const_iterator cend() const noexcept { + return packed.first().end(); + } + + /*! @copydoc cend */ + [[nodiscard]] const_iterator end() const noexcept { + return cend(); + } + + /*! @copydoc end */ + [[nodiscard]] iterator end() noexcept { + return packed.first().end(); + } + + /** + * @brief Returns a reverse iterator to the beginning. + * + * If the array is empty, the returned iterator will be equal to `rend()`. + * + * @return An iterator to the first instance of the reversed internal array. + */ + [[nodiscard]] const_reverse_iterator crbegin() const noexcept { + return std::make_reverse_iterator(cend()); + } + + /*! @copydoc crbegin */ + [[nodiscard]] const_reverse_iterator rbegin() const noexcept { + return crbegin(); + } + + /*! @copydoc rbegin */ + [[nodiscard]] reverse_iterator rbegin() noexcept { + return std::make_reverse_iterator(end()); + } + + /** + * @brief Returns a reverse iterator to the end. + * @return An iterator to the element following the last instance of the + * reversed internal array. + */ + [[nodiscard]] const_reverse_iterator crend() const noexcept { + return std::make_reverse_iterator(cbegin()); + } + + /*! @copydoc crend */ + [[nodiscard]] const_reverse_iterator rend() const noexcept { + return crend(); + } + + /*! @copydoc rend */ + [[nodiscard]] reverse_iterator rend() noexcept { + return std::make_reverse_iterator(begin()); + } + + /** + * @brief Checks whether a container is empty. + * @return True if the container is empty, false otherwise. + */ + [[nodiscard]] bool empty() const noexcept { + return packed.first().empty(); + } + + /** + * @brief Returns the number of elements in a container. + * @return Number of elements in a container. + */ + [[nodiscard]] size_type size() const noexcept { + return packed.first().size(); + } + + /** + * @brief Returns the maximum possible number of elements. + * @return Maximum possible number of elements. + */ + [[nodiscard]] size_type max_size() const noexcept { + return packed.first().max_size(); + } + + /*! @brief Clears the container. */ + void clear() noexcept { + sparse.first().clear(); + packed.first().clear(); + rehash(0u); + } + + /** + * @brief Inserts an element into the container, if it does not exist. + * @param value An element to insert into the container. + * @return A pair consisting of an iterator to the inserted element (or to + * the element that prevented the insertion) and a bool denoting whether the + * insertion took place. + */ + std::pair insert(const value_type &value) { + return insert_or_do_nothing(value); + } + + /*! @copydoc insert */ + std::pair insert(value_type &&value) { + return insert_or_do_nothing(std::move(value)); + } + + /** + * @brief Inserts elements into the container, if they do not exist. + * @tparam It Type of input iterator. + * @param first An iterator to the first element of the range of elements. + * @param last An iterator past the last element of the range of elements. + */ + template + void insert(It first, It last) { + for(; first != last; ++first) { + insert(*first); + } + } + + /** + * @brief Constructs an element in-place, if it does not exist. + * + * The element is also constructed when the container already has the key, + * in which case the newly constructed object is destroyed immediately. + * + * @tparam Args Types of arguments to forward to the constructor of the + * element. + * @param args Arguments to forward to the constructor of the element. + * @return A pair consisting of an iterator to the inserted element (or to + * the element that prevented the insertion) and a bool denoting whether the + * insertion took place. + */ + template + std::pair emplace(Args &&...args) { + if constexpr(((sizeof...(Args) == 1u) && ... && std::is_same_v, value_type>)) { + return insert_or_do_nothing(std::forward(args)...); + } else { + auto &node = packed.first().emplace_back(std::piecewise_construct, std::make_tuple(packed.first().size()), std::forward_as_tuple(std::forward(args)...)); + const auto index = value_to_bucket(node.second); + + if(auto it = constrained_find(node.second, index); it != end()) { + packed.first().pop_back(); + return std::make_pair(it, false); + } + + std::swap(node.first, sparse.first()[index]); + rehash_if_required(); + + return std::make_pair(--end(), true); + } + } + + /** + * @brief Removes an element from a given position. + * @param pos An iterator to the element to remove. + * @return An iterator following the removed element. + */ + iterator erase(const_iterator pos) { + const auto diff = pos - cbegin(); + erase(*pos); + return begin() + diff; + } + + /** + * @brief Removes the given elements from a container. + * @param first An iterator to the first element of the range of elements. + * @param last An iterator past the last element of the range of elements. + * @return An iterator following the last removed element. + */ + iterator erase(const_iterator first, const_iterator last) { + const auto dist = first - cbegin(); + + for(auto from = last - cbegin(); from != dist; --from) { + erase(packed.first()[static_cast(from) - 1u].second); + } + + return (begin() + dist); + } + + /** + * @brief Removes the element associated with a given value. + * @param value Value of an element to remove. + * @return Number of elements removed (either 0 or 1). + */ + size_type erase(const value_type &value) { + for(size_type *curr = &sparse.first()[value_to_bucket(value)]; *curr != placeholder_position; curr = &packed.first()[*curr].first) { + if(packed.second()(packed.first()[*curr].second, value)) { + const auto index = *curr; + *curr = packed.first()[*curr].first; + move_and_pop(index); + return 1u; + } + } + + return 0u; + } + + /** + * @brief Returns the number of elements matching a value (either 1 or 0). + * @param key Key value of an element to search for. + * @return Number of elements matching the key (either 1 or 0). + */ + [[nodiscard]] size_type count(const value_type &key) const { + return find(key) != end(); + } + + /** + * @brief Returns the number of elements matching a key (either 1 or 0). + * @tparam Other Type of the key value of an element to search for. + * @param key Key value of an element to search for. + * @return Number of elements matching the key (either 1 or 0). + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + count(const Other &key) const { + return find(key) != end(); + } + + /** + * @brief Finds an element with a given value. + * @param value Value of an element to search for. + * @return An iterator to an element with the given value. If no such + * element is found, a past-the-end iterator is returned. + */ + [[nodiscard]] iterator find(const value_type &value) { + return constrained_find(value, value_to_bucket(value)); + } + + /*! @copydoc find */ + [[nodiscard]] const_iterator find(const value_type &value) const { + return constrained_find(value, value_to_bucket(value)); + } + + /** + * @brief Finds an element that compares _equivalent_ to a given value. + * @tparam Other Type of an element to search for. + * @param value Value of an element to search for. + * @return An iterator to an element with the given value. If no such + * element is found, a past-the-end iterator is returned. + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + find(const Other &value) { + return constrained_find(value, value_to_bucket(value)); + } + + /*! @copydoc find */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + find(const Other &value) const { + return constrained_find(value, value_to_bucket(value)); + } + + /** + * @brief Returns a range containing all elements with a given value. + * @param value Value of an element to search for. + * @return A pair of iterators pointing to the first element and past the + * last element of the range. + */ + [[nodiscard]] std::pair equal_range(const value_type &value) { + const auto it = find(value); + return {it, it + !(it == end())}; + } + + /*! @copydoc equal_range */ + [[nodiscard]] std::pair equal_range(const value_type &value) const { + const auto it = find(value); + return {it, it + !(it == cend())}; + } + + /** + * @brief Returns a range containing all elements that compare _equivalent_ + * to a given value. + * @tparam Other Type of an element to search for. + * @param value Value of an element to search for. + * @return A pair of iterators pointing to the first element and past the + * last element of the range. + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t>> + equal_range(const Other &value) { + const auto it = find(value); + return {it, it + !(it == end())}; + } + + /*! @copydoc equal_range */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t>> + equal_range(const Other &value) const { + const auto it = find(value); + return {it, it + !(it == cend())}; + } + + /** + * @brief Checks if the container contains an element with a given value. + * @param value Value of an element to search for. + * @return True if there is such an element, false otherwise. + */ + [[nodiscard]] bool contains(const value_type &value) const { + return (find(value) != cend()); + } + + /** + * @brief Checks if the container contains an element that compares + * _equivalent_ to a given value. + * @tparam Other Type of an element to search for. + * @param value Value of an element to search for. + * @return True if there is such an element, false otherwise. + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + contains(const Other &value) const { + return (find(value) != cend()); + } + + /** + * @brief Returns an iterator to the beginning of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the beginning of the given bucket. + */ + [[nodiscard]] const_local_iterator cbegin(const size_type index) const { + return {packed.first().begin(), sparse.first()[index]}; + } + + /** + * @brief Returns an iterator to the beginning of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the beginning of the given bucket. + */ + [[nodiscard]] const_local_iterator begin(const size_type index) const { + return cbegin(index); + } + + /** + * @brief Returns an iterator to the beginning of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the beginning of the given bucket. + */ + [[nodiscard]] local_iterator begin(const size_type index) { + return {packed.first().begin(), sparse.first()[index]}; + } + + /** + * @brief Returns an iterator to the end of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the end of the given bucket. + */ + [[nodiscard]] const_local_iterator cend([[maybe_unused]] const size_type index) const { + return {}; + } + + /** + * @brief Returns an iterator to the end of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the end of the given bucket. + */ + [[nodiscard]] const_local_iterator end(const size_type index) const { + return cend(index); + } + + /** + * @brief Returns an iterator to the end of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the end of the given bucket. + */ + [[nodiscard]] local_iterator end([[maybe_unused]] const size_type index) { + return {}; + } + + /** + * @brief Returns the number of buckets. + * @return The number of buckets. + */ + [[nodiscard]] size_type bucket_count() const { + return sparse.first().size(); + } + + /** + * @brief Returns the maximum number of buckets. + * @return The maximum number of buckets. + */ + [[nodiscard]] size_type max_bucket_count() const { + return sparse.first().max_size(); + } + + /** + * @brief Returns the number of elements in a given bucket. + * @param index The index of the bucket to examine. + * @return The number of elements in the given bucket. + */ + [[nodiscard]] size_type bucket_size(const size_type index) const { + return static_cast(std::distance(begin(index), end(index))); + } + + /** + * @brief Returns the bucket for a given element. + * @param value The value of the element to examine. + * @return The bucket for the given element. + */ + [[nodiscard]] size_type bucket(const value_type &value) const { + return value_to_bucket(value); + } + + /** + * @brief Returns the average number of elements per bucket. + * @return The average number of elements per bucket. + */ + [[nodiscard]] float load_factor() const { + return static_cast(size()) / static_cast(bucket_count()); + } + + /** + * @brief Returns the maximum average number of elements per bucket. + * @return The maximum average number of elements per bucket. + */ + [[nodiscard]] float max_load_factor() const { + return threshold; + } + + /** + * @brief Sets the desired maximum average number of elements per bucket. + * @param value A desired maximum average number of elements per bucket. + */ + void max_load_factor(const float value) { + ENTT_ASSERT(value > 0.f, "Invalid load factor"); + threshold = value; + rehash(0u); + } + + /** + * @brief Reserves at least the specified number of buckets and regenerates + * the hash table. + * @param cnt New number of buckets. + */ + void rehash(const size_type cnt) { + auto value = cnt > minimum_capacity ? cnt : minimum_capacity; + const auto cap = static_cast(static_cast(size()) / max_load_factor()); + value = value > cap ? value : cap; + + if(const auto sz = next_power_of_two(value); sz != bucket_count()) { + sparse.first().resize(sz); + + for(auto &&elem: sparse.first()) { + elem = placeholder_position; + } + + for(size_type pos{}, last = size(); pos < last; ++pos) { + const auto index = value_to_bucket(packed.first()[pos].second); + packed.first()[pos].first = std::exchange(sparse.first()[index], pos); + } + } + } + + /** + * @brief Reserves space for at least the specified number of elements and + * regenerates the hash table. + * @param cnt New number of elements. + */ + void reserve(const size_type cnt) { + packed.first().reserve(cnt); + rehash(static_cast(std::ceil(static_cast(cnt) / max_load_factor()))); + } + + /** + * @brief Returns the function used to hash the elements. + * @return The function used to hash the elements. + */ + [[nodiscard]] hasher hash_function() const { + return sparse.second(); + } + + /** + * @brief Returns the function used to compare elements for equality. + * @return The function used to compare elements for equality. + */ + [[nodiscard]] key_equal key_eq() const { + return packed.second(); + } + +private: + compressed_pair sparse; + compressed_pair packed; + float threshold{default_threshold}; +}; + +} // namespace entt + +#endif + +// #include "../core/compressed_pair.hpp" +#ifndef ENTT_CORE_COMPRESSED_PAIR_HPP +#define ENTT_CORE_COMPRESSED_PAIR_HPP + +#include +#include +#include +#include +// #include "fwd.hpp" +#ifndef ENTT_CORE_FWD_HPP +#define ENTT_CORE_FWD_HPP + +#include +#include +// #include "../config/config.h" + + +namespace entt { + +/*! @brief Possible modes of an any object. */ +enum class any_policy : std::uint8_t { + /*! @brief Default mode, no element available. */ + empty, + /*! @brief Owning mode, dynamically allocated element. */ + dynamic, + /*! @brief Owning mode, embedded element. */ + embedded, + /*! @brief Aliasing mode, non-const reference. */ + ref, + /*! @brief Const aliasing mode, const reference. */ + cref +}; + +// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) +template +class basic_any; + +/*! @brief Alias declaration for type identifiers. */ +using id_type = ENTT_ID_TYPE; + +/*! @brief Alias declaration for the most common use case. */ +using any = basic_any<>; + +template +class compressed_pair; + +template +class basic_hashed_string; + +/*! @brief Aliases for common character types. */ +using hashed_string = basic_hashed_string; + +/*! @brief Aliases for common character types. */ +using hashed_wstring = basic_hashed_string; + +// NOLINTNEXTLINE(bugprone-forward-declaration-namespace) +struct type_info; + +} // namespace entt + +#endif + +// #include "type_traits.hpp" +#ifndef ENTT_CORE_TYPE_TRAITS_HPP +#define ENTT_CORE_TYPE_TRAITS_HPP + +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "fwd.hpp" + + +namespace entt { + +/** + * @brief Utility class to disambiguate overloaded functions. + * @tparam N Number of choices available. + */ +template +struct choice_t + // unfortunately, doxygen cannot parse such a construct + : /*! @cond TURN_OFF_DOXYGEN */ choice_t /*! @endcond */ +{}; + +/*! @copybrief choice_t */ +template<> +struct choice_t<0> {}; + +/** + * @brief Variable template for the choice trick. + * @tparam N Number of choices available. + */ +template +inline constexpr choice_t choice{}; + +/** + * @brief Identity type trait. + * + * Useful to establish non-deduced contexts in template argument deduction + * (waiting for C++20) or to provide types through function arguments. + * + * @tparam Type A type. + */ +template +struct type_identity { + /*! @brief Identity type. */ + using type = Type; +}; + +/** + * @brief Helper type. + * @tparam Type A type. + */ +template +using type_identity_t = typename type_identity::type; + +/** + * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains. + * @tparam Type The type of which to return the size. + */ +template +struct size_of: std::integral_constant {}; + +/*! @copydoc size_of */ +template +struct size_of> + // NOLINTNEXTLINE(bugprone-sizeof-expression) + : std::integral_constant {}; + +/** + * @brief Helper variable template. + * @tparam Type The type of which to return the size. + */ +template +inline constexpr std::size_t size_of_v = size_of::value; + +/** + * @brief Using declaration to be used to _repeat_ the same type a number of + * times equal to the size of a given parameter pack. + * @tparam Type A type to repeat. + */ +template +using unpack_as_type = Type; + +/** + * @brief Helper variable template to be used to _repeat_ the same value a + * number of times equal to the size of a given parameter pack. + * @tparam Value A value to repeat. + */ +template +inline constexpr auto unpack_as_value = Value; + +/** + * @brief Wraps a static constant. + * @tparam Value A static constant. + */ +template +using integral_constant = std::integral_constant; + +/** + * @brief Alias template to facilitate the creation of named values. + * @tparam Value A constant value at least convertible to `id_type`. + */ +template +using tag = integral_constant; + +/** + * @brief A class to use to push around lists of types, nothing more. + * @tparam Type Types provided by the type list. + */ +template +struct type_list { + /*! @brief Type list type. */ + using type = type_list; + /*! @brief Compile-time number of elements in the type list. */ + static constexpr auto size = sizeof...(Type); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_element; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Index Index of the type to return. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element> + : type_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element<0u, type_list> { + /*! @brief Searched type. */ + using type = First; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Type list to search into. + */ +template +using type_list_element_t = typename type_list_element::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_index; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 1u + type_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + static_assert(type_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +inline constexpr std::size_t type_list_index_v = type_list_index::value; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @return A type list composed by the types of both the type lists. + */ +template +constexpr type_list operator+(type_list, type_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_cat; + +/*! @brief Concatenates multiple type lists. */ +template<> +struct type_list_cat<> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list<>; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @tparam List Other type lists, if any. + */ +template +struct type_list_cat, type_list, List...> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = typename type_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the type list. + */ +template +struct type_list_cat> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list; +}; + +/** + * @brief Helper type. + * @tparam List Type lists to concatenate. + */ +template +using type_list_cat_t = typename type_list_cat::type; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct type_list_unique; + +template +struct type_list_unique, Type...> + : std::conditional_t<(std::is_same_v || ...), type_list_unique, Type...>, type_list_unique, Type..., First>> {}; + +template +struct type_list_unique, Type...> { + using type = type_list; +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Removes duplicates types from a type list. + * @tparam List Type list. + */ +template +struct type_list_unique { + /*! @brief A type list without duplicate types. */ + using type = typename internal::type_list_unique::type; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + */ +template +using type_list_unique_t = typename type_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a type list contains a + * given type, false otherwise. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +struct type_list_contains; + +/** + * @copybrief type_list_contains + * @tparam Type Types provided by the type list. + * @tparam Other Type to look for. + */ +template +struct type_list_contains, Other> + : std::bool_constant<(std::is_same_v || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +inline constexpr bool type_list_contains_v = type_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_diff; + +/** + * @brief Computes the difference between two type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + */ +template +struct type_list_diff, type_list> { + /*! @brief A type list that is the difference between the two type lists. */ + using type = type_list_cat_t, Type>, type_list<>, type_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Type lists between which to compute the difference. + */ +template +using type_list_diff_t = typename type_list_diff::type; + +/*! @brief Primary template isn't defined on purpose. */ +template class> +struct type_list_transform; + +/** + * @brief Applies a given _function_ to a type list and generate a new list. + * @tparam Type Types provided by the type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +struct type_list_transform, Op> { + /*! @brief Resulting type list after applying the transform function. */ + // NOLINTNEXTLINE(modernize-type-traits) + using type = type_list::type...>; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +using type_list_transform_t = typename type_list_transform::type; + +/** + * @brief A class to use to push around lists of constant values, nothing more. + * @tparam Value Values provided by the value list. + */ +template +struct value_list { + /*! @brief Value list type. */ + using type = value_list; + /*! @brief Compile-time number of elements in the value list. */ + static constexpr auto size = sizeof...(Value); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_element; + +/** + * @brief Provides compile-time indexed access to the values of a value list. + * @tparam Index Index of the value to return. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element> + : value_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element<0u, value_list> { + /*! @brief Searched type. */ + using type = decltype(Value); + /*! @brief Searched value. */ + static constexpr auto value = Value; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Value list to search into. + */ +template +using value_list_element_t = typename value_list_element::type; + +/** + * @brief Helper type. + * @tparam Index Index of the value to return. + * @tparam List Value list to search into. + */ +template +inline constexpr auto value_list_element_v = value_list_element::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_index; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam First First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 1u + value_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + static_assert(value_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +inline constexpr std::size_t value_list_index_v = value_list_index::value; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @return A value list composed by the values of both the value lists. + */ +template +constexpr value_list operator+(value_list, value_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_cat; + +/*! @brief Concatenates multiple value lists. */ +template<> +struct value_list_cat<> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list<>; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @tparam List Other value lists, if any. + */ +template +struct value_list_cat, value_list, List...> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = typename value_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the value list. + */ +template +struct value_list_cat> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list; +}; + +/** + * @brief Helper type. + * @tparam List Value lists to concatenate. + */ +template +using value_list_cat_t = typename value_list_cat::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_unique; + +/** + * @brief Removes duplicates values from a value list. + * @tparam Value One of the values provided by the given value list. + * @tparam Other The other values provided by the given value list. + */ +template +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = std::conditional_t< + ((Value == Other) || ...), + typename value_list_unique>::type, + value_list_cat_t, typename value_list_unique>::type>>; +}; + +/*! @brief Removes duplicates values from a value list. */ +template<> +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = value_list<>; +}; + +/** + * @brief Helper type. + * @tparam Type A value list. + */ +template +using value_list_unique_t = typename value_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a value list contains + * a given value, false otherwise. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +struct value_list_contains; + +/** + * @copybrief value_list_contains + * @tparam Value Values provided by the value list. + * @tparam Other Value to look for. + */ +template +struct value_list_contains, Other> + : std::bool_constant<((Value == Other) || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +inline constexpr bool value_list_contains_v = value_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_diff; + +/** + * @brief Computes the difference between two value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + */ +template +struct value_list_diff, value_list> { + /*! @brief A value list that is the difference between the two value lists. */ + using type = value_list_cat_t, Value>, value_list<>, value_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Value lists between which to compute the difference. + */ +template +using value_list_diff_t = typename value_list_diff::type; + +/*! @brief Same as std::is_invocable, but with tuples. */ +template +struct is_applicable: std::false_type {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @brief Helper variable template. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_v = is_applicable::value; + +/*! @brief Same as std::is_invocable_r, but with tuples for arguments. */ +template +struct is_applicable_r: std::false_type {}; + +/** + * @copybrief is_applicable_r + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +struct is_applicable_r>: std::is_invocable_r {}; + +/** + * @brief Helper variable template. + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_r_v = is_applicable_r::value; + +/** + * @brief Provides the member constant `value` to true if a given type is + * complete, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_complete: std::false_type {}; + +/*! @copydoc is_complete */ +template +struct is_complete>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_complete_v = is_complete::value; + +/** + * @brief Provides the member constant `value` to true if a given type is an + * iterator, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_iterator: std::false_type {}; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_iterator_category: std::false_type {}; + +template +struct has_iterator_category::iterator_category>>: std::true_type {}; + +} // namespace internal +/*! @endcond */ + +/*! @copydoc is_iterator */ +template +struct is_iterator>>>> + : internal::has_iterator_category {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_iterator_v = is_iterator::value; + +/** + * @brief Provides the member constant `value` to true if a given type is both + * an empty and non-final class, false otherwise. + * @tparam Type The type to test + */ +template +struct is_ebco_eligible + : std::bool_constant && !std::is_final_v> {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_ebco_eligible_v = is_ebco_eligible::value; + +/** + * @brief Provides the member constant `value` to true if `Type::is_transparent` + * is valid and denotes a type, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_transparent: std::false_type {}; + +/*! @copydoc is_transparent */ +template +struct is_transparent>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_transparent_v = is_transparent::value; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_tuple_size_value: std::false_type {}; + +template +struct has_tuple_size_value::value)>>: std::true_type {}; + +template +struct has_value_type: std::false_type {}; + +template +struct has_value_type>: std::true_type {}; + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable(); + +template +[[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence) { + return (dispatch_is_equality_comparable>() && ...); +} + +template +[[nodiscard]] constexpr bool maybe_equality_comparable(char) { + return false; +} + +template +[[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval() == std::declval()) { + return true; +} + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable() { + // NOLINTBEGIN(modernize-use-transparent-functors) + if constexpr(std::is_array_v) { + return false; + } else if constexpr(is_complete_v>>) { + if constexpr(has_tuple_size_value::value) { + return maybe_equality_comparable(0) && unpack_maybe_equality_comparable(std::make_index_sequence::value>{}); + } else { + return maybe_equality_comparable(0); + } + } else if constexpr(has_value_type::value) { + if constexpr(is_iterator_v || std::is_same_v || dispatch_is_equality_comparable()) { + return maybe_equality_comparable(0); + } else { + return false; + } + } else { + return maybe_equality_comparable(0); + } + // NOLINTEND(modernize-use-transparent-functors) +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Provides the member constant `value` to true if a given type is + * equality comparable, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_equality_comparable: std::bool_constant()> {}; + +/*! @copydoc is_equality_comparable */ +template +struct is_equality_comparable: is_equality_comparable {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_equality_comparable_v = is_equality_comparable::value; + +/** + * @brief Transcribes the constness of a type to another type. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = std::remove_const_t; +}; + +/*! @copydoc constness_as */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = const To; +}; + +/** + * @brief Alias template to facilitate the transcription of the constness. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +using constness_as_t = typename constness_as::type; + +/** + * @brief Extracts the class of a non-static member object or function. + * @tparam Member A pointer to a non-static member object or function. + */ +template +class member_class { + static_assert(std::is_member_pointer_v, "Invalid pointer type to non-static member object or function"); + + template + static Class *clazz(Ret (Class::*)(Args...)); + + template + static Class *clazz(Ret (Class::*)(Args...) const); + + template + static Class *clazz(Type Class::*); + +public: + /*! @brief The class of the given non-static member object or function. */ + using type = std::remove_pointer_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Member A pointer to a non-static member object or function. + */ +template +using member_class_t = typename member_class::type; + +/** + * @brief Extracts the n-th argument of a _callable_ type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid _callable_ type. + */ +template +class nth_argument { + template + static constexpr type_list pick_up(Ret (*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...) const); + + template + static constexpr type_list pick_up(Type Class ::*); + + template + static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&); + +public: + /*! @brief N-th argument of the _callable_ type. */ + using type = type_list_element_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid function, member function or data member type. + */ +template +using nth_argument_t = typename nth_argument::type; + +} // namespace entt + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::type_list_element> {}; + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::value_list_element> {}; + +#endif + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct compressed_pair_element { + using reference = Type &; + using const_reference = const Type &; + + template>> + // NOLINTNEXTLINE(modernize-use-equals-default) + constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v) {} + + template>, compressed_pair_element>>> + constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v) + : value{std::forward(arg)} {} + + template + constexpr compressed_pair_element(std::tuple args, std::index_sequence) noexcept(std::is_nothrow_constructible_v) + : value{std::forward(std::get(args))...} {} + + [[nodiscard]] constexpr reference get() noexcept { + return value; + } + + [[nodiscard]] constexpr const_reference get() const noexcept { + return value; + } + +private: + Type value{}; +}; + +template +struct compressed_pair_element>>: Type { + using reference = Type &; + using const_reference = const Type &; + using base_type = Type; + + template>> + constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v) + : base_type{} {} + + template>, compressed_pair_element>>> + constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v) + : base_type{std::forward(arg)} {} + + template + constexpr compressed_pair_element(std::tuple args, std::index_sequence) noexcept(std::is_nothrow_constructible_v) + : base_type{std::forward(std::get(args))...} {} + + [[nodiscard]] constexpr reference get() noexcept { + return *this; + } + + [[nodiscard]] constexpr const_reference get() const noexcept { + return *this; + } +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief A compressed pair. + * + * A pair that exploits the _Empty Base Class Optimization_ (or _EBCO_) to + * reduce its final size to a minimum. + * + * @tparam First The type of the first element that the pair stores. + * @tparam Second The type of the second element that the pair stores. + */ +template +class compressed_pair final + : internal::compressed_pair_element, + internal::compressed_pair_element { + using first_base = internal::compressed_pair_element; + using second_base = internal::compressed_pair_element; + +public: + /*! @brief The type of the first element that the pair stores. */ + using first_type = First; + /*! @brief The type of the second element that the pair stores. */ + using second_type = Second; + + /** + * @brief Default constructor, conditionally enabled. + * + * This constructor is only available when the types that the pair stores + * are both at least default constructible. + * + * @tparam Dummy Dummy template parameter used for internal purposes. + */ + template && std::is_default_constructible_v>> + constexpr compressed_pair() noexcept(std::is_nothrow_default_constructible_v && std::is_nothrow_default_constructible_v) + : first_base{}, + second_base{} {} + + /** + * @brief Copy constructor. + * @param other The instance to copy from. + */ + constexpr compressed_pair(const compressed_pair &other) = default; + + /** + * @brief Move constructor. + * @param other The instance to move from. + */ + constexpr compressed_pair(compressed_pair &&other) noexcept = default; + + /** + * @brief Constructs a pair from its values. + * @tparam Arg Type of value to use to initialize the first element. + * @tparam Other Type of value to use to initialize the second element. + * @param arg Value to use to initialize the first element. + * @param other Value to use to initialize the second element. + */ + template + constexpr compressed_pair(Arg &&arg, Other &&other) noexcept(std::is_nothrow_constructible_v && std::is_nothrow_constructible_v) + : first_base{std::forward(arg)}, + second_base{std::forward(other)} {} + + /** + * @brief Constructs a pair by forwarding the arguments to its parts. + * @tparam Args Types of arguments to use to initialize the first element. + * @tparam Other Types of arguments to use to initialize the second element. + * @param args Arguments to use to initialize the first element. + * @param other Arguments to use to initialize the second element. + */ + template + constexpr compressed_pair(std::piecewise_construct_t, std::tuple args, std::tuple other) noexcept(std::is_nothrow_constructible_v && std::is_nothrow_constructible_v) + : first_base{std::move(args), std::index_sequence_for{}}, + second_base{std::move(other), std::index_sequence_for{}} {} + + /*! @brief Default destructor. */ + ~compressed_pair() = default; + + /** + * @brief Copy assignment operator. + * @param other The instance to copy from. + * @return This compressed pair object. + */ + constexpr compressed_pair &operator=(const compressed_pair &other) = default; + + /** + * @brief Move assignment operator. + * @param other The instance to move from. + * @return This compressed pair object. + */ + constexpr compressed_pair &operator=(compressed_pair &&other) noexcept = default; + + /** + * @brief Returns the first element that a pair stores. + * @return The first element that a pair stores. + */ + [[nodiscard]] constexpr first_type &first() noexcept { + return static_cast(*this).get(); + } + + /*! @copydoc first */ + [[nodiscard]] constexpr const first_type &first() const noexcept { + return static_cast(*this).get(); + } + + /** + * @brief Returns the second element that a pair stores. + * @return The second element that a pair stores. + */ + [[nodiscard]] constexpr second_type &second() noexcept { + return static_cast(*this).get(); + } + + /*! @copydoc second */ + [[nodiscard]] constexpr const second_type &second() const noexcept { + return static_cast(*this).get(); + } + + /** + * @brief Swaps two compressed pair objects. + * @param other The compressed pair to swap with. + */ + constexpr void swap(compressed_pair &other) noexcept { + using std::swap; + swap(first(), other.first()); + swap(second(), other.second()); + } + + /** + * @brief Extracts an element from the compressed pair. + * @tparam Index An integer value that is either 0 or 1. + * @return Returns a reference to the first element if `Index` is 0 and a + * reference to the second element if `Index` is 1. + */ + template + [[nodiscard]] constexpr decltype(auto) get() noexcept { + if constexpr(Index == 0u) { + return first(); + } else { + static_assert(Index == 1u, "Index out of bounds"); + return second(); + } + } + + /*! @copydoc get */ + template + [[nodiscard]] constexpr decltype(auto) get() const noexcept { + if constexpr(Index == 0u) { + return first(); + } else { + static_assert(Index == 1u, "Index out of bounds"); + return second(); + } + } +}; + +/** + * @brief Deduction guide. + * @tparam Type Type of value to use to initialize the first element. + * @tparam Other Type of value to use to initialize the second element. + */ +template +compressed_pair(Type &&, Other &&) -> compressed_pair, std::decay_t>; + +/** + * @brief Swaps two compressed pair objects. + * @tparam First The type of the first element that the pairs store. + * @tparam Second The type of the second element that the pairs store. + * @param lhs A valid compressed pair object. + * @param rhs A valid compressed pair object. + */ +template +constexpr void swap(compressed_pair &lhs, compressed_pair &rhs) noexcept { + lhs.swap(rhs); +} + +} // namespace entt + +namespace std { + +/** + * @brief `std::tuple_size` specialization for `compressed_pair`s. + * @tparam First The type of the first element that the pair stores. + * @tparam Second The type of the second element that the pair stores. + */ +template +struct tuple_size>: integral_constant {}; + +/** + * @brief `std::tuple_element` specialization for `compressed_pair`s. + * @tparam Index The index of the type to return. + * @tparam First The type of the first element that the pair stores. + * @tparam Second The type of the second element that the pair stores. + */ +template +struct tuple_element>: conditional { + static_assert(Index < 2u, "Index out of bounds"); +}; + +} // namespace std + +#endif + +// #include "../core/fwd.hpp" + +// #include "../core/iterator.hpp" + +// #include "../core/utility.hpp" +#ifndef ENTT_CORE_UTILITY_HPP +#define ENTT_CORE_UTILITY_HPP + +#include +#include + +namespace entt { + +/*! @brief Identity function object (waiting for C++20). */ +struct identity { + /*! @brief Indicates that this is a transparent function object. */ + using is_transparent = void; + + /** + * @brief Returns its argument unchanged. + * @tparam Type Type of the argument. + * @param value The actual argument. + * @return The submitted value as-is. + */ + template + [[nodiscard]] constexpr Type &&operator()(Type &&value) const noexcept { + return std::forward(value); + } +}; + +/** + * @brief Constant utility to disambiguate overloaded members of a class. + * @tparam Type Type of the desired overload. + * @tparam Class Type of class to which the member belongs. + * @param member A valid pointer to a member. + * @return Pointer to the member. + */ +template +[[nodiscard]] constexpr auto overload(Type Class::*member) noexcept { + return member; +} + +/** + * @brief Constant utility to disambiguate overloaded functions. + * @tparam Func Function type of the desired overload. + * @param func A valid pointer to a function. + * @return Pointer to the function. + */ +template +[[nodiscard]] constexpr auto overload(Func *func) noexcept { + return func; +} + +/** + * @brief Helper type for visitors. + * @tparam Func Types of function objects. + */ +template +struct overloaded: Func... { + using Func::operator()...; +}; + +/** + * @brief Deduction guide. + * @tparam Func Types of function objects. + */ +template +overloaded(Func...) -> overloaded; + +/** + * @brief Basic implementation of a y-combinator. + * @tparam Func Type of a potentially recursive function. + */ +template +struct y_combinator { + /** + * @brief Constructs a y-combinator from a given function. + * @param recursive A potentially recursive function. + */ + constexpr y_combinator(Func recursive) noexcept(std::is_nothrow_move_constructible_v) + : func{std::move(recursive)} {} + + /** + * @brief Invokes a y-combinator and therefore its underlying function. + * @tparam Args Types of arguments to use to invoke the underlying function. + * @param args Parameters to use to invoke the underlying function. + * @return Return value of the underlying function, if any. + */ + template + constexpr decltype(auto) operator()(Args &&...args) const noexcept(std::is_nothrow_invocable_v) { + return func(*this, std::forward(args)...); + } + + /*! @copydoc operator()() */ + template + constexpr decltype(auto) operator()(Args &&...args) noexcept(std::is_nothrow_invocable_v) { + return func(*this, std::forward(args)...); + } + +private: + Func func; +}; + +} // namespace entt + +#endif + +// #include "adjacency_matrix.hpp" +#ifndef ENTT_GRAPH_ADJACENCY_MATRIX_HPP +#define ENTT_GRAPH_ADJACENCY_MATRIX_HPP + +#include +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "../core/iterator.hpp" + +// #include "fwd.hpp" + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +class edge_iterator { + using size_type = std::size_t; + + void find_next() noexcept { + for(; pos != last && !it[static_cast(pos)]; pos += offset) {} + } + +public: + using value_type = std::pair; + using pointer = input_iterator_pointer; + using reference = value_type; + using difference_type = std::ptrdiff_t; + using iterator_category = std::input_iterator_tag; + using iterator_concept = std::forward_iterator_tag; + + constexpr edge_iterator() noexcept = default; + + // NOLINTNEXTLINE(bugprone-easily-swappable-parameters) + constexpr edge_iterator(It base, const size_type vertices, const size_type from, const size_type to, const size_type step) noexcept + : it{std::move(base)}, + vert{vertices}, + pos{from}, + last{to}, + offset{step} { + find_next(); + } + + constexpr edge_iterator &operator++() noexcept { + pos += offset; + find_next(); + return *this; + } + + constexpr edge_iterator operator++(int) noexcept { + const edge_iterator orig = *this; + return ++(*this), orig; + } + + [[nodiscard]] constexpr reference operator*() const noexcept { + return *operator->(); + } + + [[nodiscard]] constexpr pointer operator->() const noexcept { + return std::make_pair(pos / vert, pos % vert); + } + + template + friend constexpr bool operator==(const edge_iterator &, const edge_iterator &) noexcept; + +private: + It it{}; + size_type vert{}; + size_type pos{}; + size_type last{}; + size_type offset{}; +}; + +template +[[nodiscard]] constexpr bool operator==(const edge_iterator &lhs, const edge_iterator &rhs) noexcept { + return lhs.pos == rhs.pos; +} + +template +[[nodiscard]] constexpr bool operator!=(const edge_iterator &lhs, const edge_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Basic implementation of a directed adjacency matrix. + * @tparam Category Either a directed or undirected category tag. + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +class adjacency_matrix { + using alloc_traits = std::allocator_traits; + static_assert(std::is_base_of_v, "Invalid graph category"); + static_assert(std::is_same_v, "Invalid value type"); + using container_type = std::vector>; + +public: + /*! @brief Allocator type. */ + using allocator_type = Allocator; + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + /*! @brief Vertex type. */ + using vertex_type = size_type; + /*! @brief Edge type. */ + using edge_type = std::pair; + /*! @brief Vertex iterator type. */ + using vertex_iterator = iota_iterator; + /*! @brief Edge iterator type. */ + using edge_iterator = internal::edge_iterator; + /*! @brief Out-edge iterator type. */ + using out_edge_iterator = edge_iterator; + /*! @brief In-edge iterator type. */ + using in_edge_iterator = edge_iterator; + /*! @brief Graph category tag. */ + using graph_category = Category; + + /*! @brief Default constructor. */ + adjacency_matrix() noexcept(noexcept(allocator_type{})) + : adjacency_matrix{0u} { + } + + /** + * @brief Constructs an empty container with a given allocator. + * @param allocator The allocator to use. + */ + explicit adjacency_matrix(const allocator_type &allocator) noexcept + : adjacency_matrix{0u, allocator} {} + + /** + * @brief Constructs an empty container with a given allocator and user + * supplied number of vertices. + * @param vertices Number of vertices. + * @param allocator The allocator to use. + */ + adjacency_matrix(const size_type vertices, const allocator_type &allocator = allocator_type{}) + : matrix{vertices * vertices, allocator}, + vert{vertices} {} + + /*! @brief Default copy constructor. */ + adjacency_matrix(const adjacency_matrix &) = default; + + /** + * @brief Allocator-extended copy constructor. + * @param other The instance to copy from. + * @param allocator The allocator to use. + */ + adjacency_matrix(const adjacency_matrix &other, const allocator_type &allocator) + : matrix{other.matrix, allocator}, + vert{other.vert} {} + + /*! @brief Default move constructor. */ + adjacency_matrix(adjacency_matrix &&) noexcept = default; + + /** + * @brief Allocator-extended move constructor. + * @param other The instance to move from. + * @param allocator The allocator to use. + */ + adjacency_matrix(adjacency_matrix &&other, const allocator_type &allocator) + : matrix{std::move(other.matrix), allocator}, + vert{other.vert} {} + + /*! @brief Default destructor. */ + ~adjacency_matrix() = default; + + /** + * @brief Default copy assignment operator. + * @return This container. + */ + adjacency_matrix &operator=(const adjacency_matrix &) = default; + + /** + * @brief Default move assignment operator. + * @return This container. + */ + adjacency_matrix &operator=(adjacency_matrix &&) noexcept = default; + + /** + * @brief Exchanges the contents with those of a given adjacency matrix. + * @param other Adjacency matrix to exchange the content with. + */ + void swap(adjacency_matrix &other) noexcept { + using std::swap; + swap(matrix, other.matrix); + swap(vert, other.vert); + } + + /** + * @brief Returns the associated allocator. + * @return The associated allocator. + */ + [[nodiscard]] constexpr allocator_type get_allocator() const noexcept { + return matrix.get_allocator(); + } + + /*! @brief Clears the adjacency matrix. */ + void clear() noexcept { + matrix.clear(); + vert = {}; + } + + /** + * @brief Returns true if an adjacency matrix is empty, false otherwise. + * + * @warning + * Potentially expensive, try to avoid it on hot paths. + * + * @return True if the adjacency matrix is empty, false otherwise. + */ + [[nodiscard]] bool empty() const noexcept { + const auto iterable = edges(); + return (iterable.begin() == iterable.end()); + } + + /** + * @brief Returns the number of vertices. + * @return The number of vertices. + */ + [[nodiscard]] size_type size() const noexcept { + return vert; + } + + /** + * @brief Returns an iterable object to visit all vertices of a matrix. + * @return An iterable object to visit all vertices of a matrix. + */ + [[nodiscard]] iterable_adaptor vertices() const noexcept { + return {0u, vert}; + } + + /** + * @brief Returns an iterable object to visit all edges of a matrix. + * @return An iterable object to visit all edges of a matrix. + */ + [[nodiscard]] iterable_adaptor edges() const noexcept { + const auto it = matrix.cbegin(); + const auto sz = matrix.size(); + return {{it, vert, 0u, sz, 1u}, {it, vert, sz, sz, 1u}}; + } + + /** + * @brief Returns an iterable object to visit all out-edges of a vertex. + * @param vertex The vertex of which to return all out-edges. + * @return An iterable object to visit all out-edges of a vertex. + */ + [[nodiscard]] iterable_adaptor out_edges(const vertex_type vertex) const noexcept { + const auto it = matrix.cbegin(); + const auto from = vertex * vert; + const auto to = from + vert; + return {{it, vert, from, to, 1u}, {it, vert, to, to, 1u}}; + } + + /** + * @brief Returns an iterable object to visit all in-edges of a vertex. + * @param vertex The vertex of which to return all in-edges. + * @return An iterable object to visit all in-edges of a vertex. + */ + [[nodiscard]] iterable_adaptor in_edges(const vertex_type vertex) const noexcept { + const auto it = matrix.cbegin(); + const auto from = vertex; + const auto to = vert * vert + from; + return {{it, vert, from, to, vert}, {it, vert, to, to, vert}}; + } + + /** + * @brief Resizes an adjacency matrix. + * @param vertices The new number of vertices. + */ + void resize(const size_type vertices) { + adjacency_matrix other{vertices, get_allocator()}; + + for(auto [lhs, rhs]: edges()) { + other.insert(lhs, rhs); + } + + other.swap(*this); + } + + /** + * @brief Inserts an edge into the adjacency matrix, if it does not exist. + * @param lhs The left hand vertex of the edge. + * @param rhs The right hand vertex of the edge. + * @return A pair consisting of an iterator to the inserted element (or to + * the element that prevented the insertion) and a bool denoting whether the + * insertion took place. + */ + std::pair insert(const vertex_type lhs, const vertex_type rhs) { + const auto pos = lhs * vert + rhs; + + if constexpr(std::is_same_v) { + const auto rev = rhs * vert + lhs; + ENTT_ASSERT(matrix[pos] == matrix[rev], "Something went really wrong"); + matrix[rev] = 1u; + } + + const auto inserted = !std::exchange(matrix[pos], 1u); + return {edge_iterator{matrix.cbegin(), vert, pos, matrix.size(), 1u}, inserted}; + } + + /** + * @brief Removes the edge associated with a pair of given vertices. + * @param lhs The left hand vertex of the edge. + * @param rhs The right hand vertex of the edge. + * @return Number of elements removed (either 0 or 1). + */ + size_type erase(const vertex_type lhs, const vertex_type rhs) { + const auto pos = lhs * vert + rhs; + + if constexpr(std::is_same_v) { + const auto rev = rhs * vert + lhs; + ENTT_ASSERT(matrix[pos] == matrix[rev], "Something went really wrong"); + matrix[rev] = 0u; + } + + return std::exchange(matrix[pos], 0u); + } + + /** + * @brief Checks if an adjacency matrix contains a given edge. + * @param lhs The left hand vertex of the edge. + * @param rhs The right hand vertex of the edge. + * @return True if there is such an edge, false otherwise. + */ + [[nodiscard]] bool contains(const vertex_type lhs, const vertex_type rhs) const { + const auto pos = lhs * vert + rhs; + return pos < matrix.size() && matrix[pos]; + } + +private: + container_type matrix; + size_type vert; +}; + +} // namespace entt + +#endif + +// #include "fwd.hpp" + + +namespace entt { + +/** + * @brief Utility class for creating task graphs. + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +class basic_flow { + using alloc_traits = std::allocator_traits; + static_assert(std::is_same_v, "Invalid value type"); + using task_container_type = dense_set, typename alloc_traits::template rebind_alloc>; + using ro_rw_container_type = std::vector, typename alloc_traits::template rebind_alloc>>; + using deps_container_type = dense_map, typename alloc_traits::template rebind_alloc>>; + using adjacency_matrix_type = adjacency_matrix>; + + void emplace(const id_type res, const bool is_rw) { + ENTT_ASSERT(index.first() < vertices.size(), "Invalid node"); + + if(!deps.contains(res) && sync_on != vertices.size()) { + deps[res].emplace_back(sync_on, true); + } + + deps[res].emplace_back(index.first(), is_rw); + } + + void setup_graph(adjacency_matrix_type &matrix) const { + for(const auto &elem: deps) { + const auto last = elem.second.cend(); + auto it = elem.second.cbegin(); + + while(it != last) { + if(it->second) { + // rw item + if(auto curr = it++; it != last) { + if(it->second) { + matrix.insert(curr->first, it->first); + } else if(const auto next = std::find_if(it, last, [](const auto &value) { return value.second; }); next != last) { + for(; it != next; ++it) { + matrix.insert(curr->first, it->first); + matrix.insert(it->first, next->first); + } + } else { + for(; it != next; ++it) { + matrix.insert(curr->first, it->first); + } + } + } + } else { + // ro item (first iteration only) + if(const auto next = std::find_if(it, last, [](const auto &value) { return value.second; }); next != last) { + for(; it != next; ++it) { + matrix.insert(it->first, next->first); + } + } else { + it = last; + } + } + } + } + } + + void transitive_closure(adjacency_matrix_type &matrix) const { + const auto length = matrix.size(); + + for(std::size_t vk{}; vk < length; ++vk) { + for(std::size_t vi{}; vi < length; ++vi) { + for(std::size_t vj{}; vj < length; ++vj) { + if(matrix.contains(vi, vk) && matrix.contains(vk, vj)) { + matrix.insert(vi, vj); + } + } + } + } + } + + void transitive_reduction(adjacency_matrix_type &matrix) const { + const auto length = matrix.size(); + + for(std::size_t vert{}; vert < length; ++vert) { + matrix.erase(vert, vert); + } + + for(std::size_t vj{}; vj < length; ++vj) { + for(std::size_t vi{}; vi < length; ++vi) { + if(matrix.contains(vi, vj)) { + for(std::size_t vk{}; vk < length; ++vk) { + if(matrix.contains(vj, vk)) { + matrix.erase(vi, vk); + } + } + } + } + } + } + +public: + /*! @brief Allocator type. */ + using allocator_type = Allocator; + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + /*! @brief Iterable task list. */ + using iterable = iterable_adaptor; + /*! @brief Adjacency matrix type. */ + using graph_type = adjacency_matrix_type; + + /*! @brief Default constructor. */ + basic_flow() + : basic_flow{allocator_type{}} {} + + /** + * @brief Constructs a flow builder with a given allocator. + * @param allocator The allocator to use. + */ + explicit basic_flow(const allocator_type &allocator) + : index{0u, allocator}, + vertices{allocator}, + deps{allocator} {} + + /*! @brief Default copy constructor. */ + basic_flow(const basic_flow &) = default; + + /** + * @brief Allocator-extended copy constructor. + * @param other The instance to copy from. + * @param allocator The allocator to use. + */ + basic_flow(const basic_flow &other, const allocator_type &allocator) + : index{other.index.first(), allocator}, + vertices{other.vertices, allocator}, + deps{other.deps, allocator}, + sync_on{other.sync_on} {} + + /*! @brief Default move constructor. */ + basic_flow(basic_flow &&) noexcept = default; + + /** + * @brief Allocator-extended move constructor. + * @param other The instance to move from. + * @param allocator The allocator to use. + */ + basic_flow(basic_flow &&other, const allocator_type &allocator) + : index{other.index.first(), allocator}, + vertices{std::move(other.vertices), allocator}, + deps{std::move(other.deps), allocator}, + sync_on{other.sync_on} {} + + /*! @brief Default destructor. */ + ~basic_flow() = default; + + /** + * @brief Default copy assignment operator. + * @return This flow builder. + */ + basic_flow &operator=(const basic_flow &) = default; + + /** + * @brief Default move assignment operator. + * @return This flow builder. + */ + basic_flow &operator=(basic_flow &&) noexcept = default; + + /** + * @brief Exchanges the contents with those of a given flow builder. + * @param other Flow builder to exchange the content with. + */ + void swap(basic_flow &other) noexcept { + using std::swap; + std::swap(index, other.index); + std::swap(vertices, other.vertices); + std::swap(deps, other.deps); + std::swap(sync_on, other.sync_on); + } + + /** + * @brief Returns the associated allocator. + * @return The associated allocator. + */ + [[nodiscard]] constexpr allocator_type get_allocator() const noexcept { + return allocator_type{index.second()}; + } + + /** + * @brief Returns the identifier at specified location. + * @param pos Position of the identifier to return. + * @return The requested identifier. + */ + [[nodiscard]] id_type operator[](const size_type pos) const { + return vertices.cbegin()[static_cast(pos)]; + } + + /*! @brief Clears the flow builder. */ + void clear() noexcept { + index.first() = {}; + vertices.clear(); + deps.clear(); + sync_on = {}; + } + + /** + * @brief Returns true if a flow builder contains no tasks, false otherwise. + * @return True if the flow builder contains no tasks, false otherwise. + */ + [[nodiscard]] bool empty() const noexcept { + return vertices.empty(); + } + + /** + * @brief Returns the number of tasks. + * @return The number of tasks. + */ + [[nodiscard]] size_type size() const noexcept { + return vertices.size(); + } + + /** + * @brief Binds a task to a flow builder. + * @param value Task identifier. + * @return This flow builder. + */ + basic_flow &bind(const id_type value) { + sync_on += (sync_on == vertices.size()); + const auto it = vertices.emplace(value).first; + index.first() = size_type(it - vertices.begin()); + return *this; + } + + /** + * @brief Turns the current task into a sync point. + * @return This flow builder. + */ + basic_flow &sync() { + ENTT_ASSERT(index.first() < vertices.size(), "Invalid node"); + sync_on = index.first(); + + for(const auto &elem: deps) { + elem.second.emplace_back(sync_on, true); + } + + return *this; + } + + /** + * @brief Assigns a resource to the current task with a given access mode. + * @param res Resource identifier. + * @param is_rw Access mode. + * @return This flow builder. + */ + basic_flow &set(const id_type res, bool is_rw = false) { + emplace(res, is_rw); + return *this; + } + + /** + * @brief Assigns a read-only resource to the current task. + * @param res Resource identifier. + * @return This flow builder. + */ + basic_flow &ro(const id_type res) { + emplace(res, false); + return *this; + } + + /** + * @brief Assigns a range of read-only resources to the current task. + * @tparam It Type of input iterator. + * @param first An iterator to the first element of the range of elements. + * @param last An iterator past the last element of the range of elements. + * @return This flow builder. + */ + template + std::enable_if_t::value_type>, id_type>, basic_flow &> + ro(It first, It last) { + for(; first != last; ++first) { + emplace(*first, false); + } + + return *this; + } + + /** + * @brief Assigns a writable resource to the current task. + * @param res Resource identifier. + * @return This flow builder. + */ + basic_flow &rw(const id_type res) { + emplace(res, true); + return *this; + } + + /** + * @brief Assigns a range of writable resources to the current task. + * @tparam It Type of input iterator. + * @param first An iterator to the first element of the range of elements. + * @param last An iterator past the last element of the range of elements. + * @return This flow builder. + */ + template + std::enable_if_t::value_type>, id_type>, basic_flow &> + rw(It first, It last) { + for(; first != last; ++first) { + emplace(*first, true); + } + + return *this; + } + + /** + * @brief Generates a task graph for the current content. + * @return The adjacency matrix of the task graph. + */ + [[nodiscard]] graph_type graph() const { + graph_type matrix{vertices.size(), get_allocator()}; + + setup_graph(matrix); + transitive_closure(matrix); + transitive_reduction(matrix); + + return matrix; + } + +private: + compressed_pair index; + task_container_type vertices; + deps_container_type deps; + size_type sync_on{}; +}; + +} // namespace entt + +#endif + +// #include "fwd.hpp" + +// #include "helper.hpp" +#ifndef ENTT_ENTITY_HELPER_HPP +#define ENTT_ENTITY_HELPER_HPP + +#include +#include +#include +// #include "../core/fwd.hpp" + +// #include "../core/type_traits.hpp" + +// #include "component.hpp" + +// #include "fwd.hpp" + +// #include "group.hpp" + +// #include "storage.hpp" + +// #include "view.hpp" + + +namespace entt { + +/** + * @brief Converts a registry to a view. + * @tparam Registry Basic registry type. + */ +template +class as_view { + template + [[nodiscard]] auto dispatch(get_t, exclude_t) const { + return reg->template view...>(exclude_t...>{}); + } + +public: + /*! @brief Type of registry to convert. */ + using registry_type = Registry; + /*! @brief Underlying entity identifier. */ + using entity_type = typename registry_type::entity_type; + + /** + * @brief Constructs a converter for a given registry. + * @param source A valid reference to a registry. + */ + as_view(registry_type &source) noexcept + : reg{&source} {} + + /** + * @brief Conversion function from a registry to a view. + * @tparam Get Type of storage used to construct the view. + * @tparam Exclude Types of storage used to filter the view. + * @return A newly created view. + */ + template + operator basic_view() const { + return dispatch(Get{}, Exclude{}); + } + +private: + registry_type *reg; +}; + +/** + * @brief Converts a registry to a group. + * @tparam Registry Basic registry type. + */ +template +class as_group { + template + [[nodiscard]] auto dispatch(owned_t, get_t, exclude_t) const { + if constexpr(std::is_const_v) { + return reg->template group_if_exists(get_t{}, exclude_t{}); + } else { + return reg->template group...>(get_t...>{}, exclude_t...>{}); + } + } + +public: + /*! @brief Type of registry to convert. */ + using registry_type = Registry; + /*! @brief Underlying entity identifier. */ + using entity_type = typename registry_type::entity_type; + + /** + * @brief Constructs a converter for a given registry. + * @param source A valid reference to a registry. + */ + as_group(registry_type &source) noexcept + : reg{&source} {} + + /** + * @brief Conversion function from a registry to a group. + * @tparam Owned Types of _owned_ by the group. + * @tparam Get Types of storage _observed_ by the group. + * @tparam Exclude Types of storage used to filter the group. + * @return A newly created group. + */ + template + operator basic_group() const { + return dispatch(Owned{}, Get{}, Exclude{}); + } + +private: + registry_type *reg; +}; + +/** + * @brief Helper to create a listener that directly invokes a member function. + * @tparam Member Member function to invoke on an element of the given type. + * @tparam Registry Basic registry type. + * @param reg A registry that contains the given entity and its elements. + * @param entt Entity from which to get the element. + */ +template>> +void invoke(Registry ®, const typename Registry::entity_type entt) { + static_assert(std::is_member_function_pointer_v, "Invalid pointer to non-static member function"); + (reg.template get>(entt).*Member)(reg, entt); +} + +/** + * @brief Returns the entity associated with a given element. + * + * @warning + * Currently, this function only works correctly with the default storage as it + * makes assumptions about how the elements are laid out. + * + * @tparam Args Storage type template parameters. + * @param storage A storage that contains the given element. + * @param instance A valid element instance. + * @return The entity associated with the given element. + */ +template +typename basic_storage::entity_type to_entity(const basic_storage &storage, const typename basic_storage::value_type &instance) { + using traits_type = component_traits::value_type, typename basic_storage::entity_type>; + static_assert(traits_type::page_size != 0u, "Unexpected page size"); + const auto *page = storage.raw(); + + // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic) + for(std::size_t pos{}, count = storage.size(); pos < count; pos += traits_type::page_size, ++page) { + if(const auto dist = (std::addressof(instance) - *page); dist >= 0 && dist < static_cast(traits_type::page_size)) { + return *(static_cast::base_type &>(storage).rbegin() + static_cast(pos) + dist); + } + } + // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic) + + return null; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct sigh_helper; + +/** + * @brief Signal connection helper for registries. + * @tparam Registry Basic registry type. + */ +template +struct sigh_helper { + /*! @brief Registry type. */ + using registry_type = Registry; + + /** + * @brief Constructs a helper for a given registry. + * @param ref A valid reference to a registry. + */ + sigh_helper(registry_type &ref) + : bucket{&ref} {} + + /** + * @brief Binds a properly initialized helper to a given signal type. + * @tparam Type Type of signal to bind the helper to. + * @param id Optional name for the underlying storage to use. + * @return A helper for a given registry and signal type. + */ + template + auto with(const id_type id = type_hash::value()) noexcept { + return sigh_helper{*bucket, id}; + } + + /** + * @brief Returns a reference to the underlying registry. + * @return A reference to the underlying registry. + */ + [[nodiscard]] registry_type ®istry() noexcept { + return *bucket; + } + +private: + registry_type *bucket; +}; + +/** + * @brief Signal connection helper for registries. + * @tparam Registry Basic registry type. + * @tparam Type Type of signal to connect listeners to. + */ +template +struct sigh_helper final: sigh_helper { + /*! @brief Registry type. */ + using registry_type = Registry; + + /** + * @brief Constructs a helper for a given registry. + * @param ref A valid reference to a registry. + * @param id Optional name for the underlying storage to use. + */ + sigh_helper(registry_type &ref, const id_type id = type_hash::value()) + : sigh_helper{ref}, + name{id} {} + + /** + * @brief Forwards the call to `on_construct` on the underlying storage. + * @tparam Candidate Function or member to connect. + * @tparam Args Type of class or type of payload, if any. + * @param args A valid object that fits the purpose, if any. + * @return This helper. + */ + template + auto on_construct(Args &&...args) { + this->registry().template on_construct(name).template connect(std::forward(args)...); + return *this; + } + + /** + * @brief Forwards the call to `on_update` on the underlying storage. + * @tparam Candidate Function or member to connect. + * @tparam Args Type of class or type of payload, if any. + * @param args A valid object that fits the purpose, if any. + * @return This helper. + */ + template + auto on_update(Args &&...args) { + this->registry().template on_update(name).template connect(std::forward(args)...); + return *this; + } + + /** + * @brief Forwards the call to `on_destroy` on the underlying storage. + * @tparam Candidate Function or member to connect. + * @tparam Args Type of class or type of payload, if any. + * @param args A valid object that fits the purpose, if any. + * @return This helper. + */ + template + auto on_destroy(Args &&...args) { + this->registry().template on_destroy(name).template connect(std::forward(args)...); + return *this; + } + +private: + id_type name; +}; + +/** + * @brief Deduction guide. + * @tparam Registry Basic registry type. + */ +template +sigh_helper(Registry &) -> sigh_helper; + +} // namespace entt + +#endif + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct is_view: std::false_type {}; + +template +struct is_view>: std::true_type {}; + +template +inline constexpr bool is_view_v = is_view::value; + +template +struct is_group: std::false_type {}; + +template +struct is_group>: std::true_type {}; + +template +inline constexpr bool is_group_v = is_group::value; + +template +struct unpack_type { + using ro = std::conditional_t< + type_list_contains_v || (std::is_const_v && !type_list_contains_v>), + type_list>, + type_list<>>; + + using rw = std::conditional_t< + type_list_contains_v> || (!std::is_const_v && !type_list_contains_v), + type_list, + type_list<>>; +}; + +template +struct unpack_type, type_list> { + using ro = type_list<>; + using rw = type_list<>; +}; + +template +struct unpack_type, type_list> + : unpack_type, type_list> {}; + +template +struct unpack_type, exclude_t>, type_list> { + using ro = type_list_cat_t, typename unpack_type, type_list>::ro...>; + using rw = type_list_cat_t, type_list>::rw...>; +}; + +template +struct unpack_type, exclude_t>, type_list> + : unpack_type, exclude_t>, type_list> {}; + +template +struct unpack_type, get_t, exclude_t>, type_list> { + using ro = type_list_cat_t, typename unpack_type, type_list>::ro..., typename unpack_type, type_list>::ro...>; + using rw = type_list_cat_t, type_list>::rw..., typename unpack_type, type_list>::rw...>; +}; + +template +struct unpack_type, get_t, exclude_t>, type_list> + : unpack_type, get_t, exclude_t>, type_list> {}; + +template +struct resource_traits; + +template +struct resource_traits, type_list> { + using args = type_list...>; + using ro = type_list_cat_t>::ro..., typename unpack_type>::ro...>; + using rw = type_list_cat_t>::rw..., typename unpack_type>::rw...>; + static constexpr auto sync_point = (std::is_same_v || ...); +}; + +template +resource_traits...>, type_list> free_function_to_resource_traits(Ret (*)(Args...)); + +template +resource_traits...>, type_list> constrained_function_to_resource_traits(Ret (*)(Type &, Args...)); + +template +resource_traits...>, type_list> constrained_function_to_resource_traits(Ret (Class::*)(Args...)); + +template +resource_traits...>, type_list> constrained_function_to_resource_traits(Ret (Class::*)(Args...) const); + +} // namespace internal +/*! @endcond */ + +/** + * @brief Utility class for creating a static task graph. + * + * This class offers minimal support (but sufficient in many cases) for creating + * an execution graph from functions and their requirements on resources.
+ * Note that the resulting tasks aren't executed in any case. This isn't the + * goal of the tool. Instead, they are returned to the user in the form of a + * graph that allows for safe execution. + * + * @tparam Registry Basic registry type. + */ +template +class basic_organizer final { + using callback_type = void(const void *, Registry &); + using prepare_type = void(Registry &); + using dependency_type = std::size_t(const bool, const type_info **, const std::size_t); + + struct vertex_data final { + std::size_t ro_count{}; + std::size_t rw_count{}; + const char *name{}; + const void *payload{}; + callback_type *callback{}; + dependency_type *dependency{}; + prepare_type *prepare{}; + const type_info *info{}; + }; + + template + [[nodiscard]] static decltype(auto) extract(Registry ®) { + if constexpr(std::is_same_v) { + return reg; + } else if constexpr(internal::is_view_v) { + return static_cast(as_view{reg}); + } else if constexpr(internal::is_group_v) { + return static_cast(as_group{reg}); + } else { + return reg.ctx().template emplace>(); + } + } + + template + [[nodiscard]] static auto to_args(Registry ®, type_list) { + return std::tuple(reg))...>(extract(reg)...); + } + + template + [[nodiscard]] static std::size_t fill_dependencies(type_list, [[maybe_unused]] const type_info **buffer, [[maybe_unused]] const std::size_t count) { + if constexpr(sizeof...(Type) == 0u) { + return {}; + } else { + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) + const type_info *info[]{&type_id()...}; + const auto length = count < sizeof...(Type) ? count : sizeof...(Type); + + for(std::size_t pos{}; pos < length; ++pos) { + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) + buffer[pos] = info[pos]; + } + + return length; + } + } + + template + void track_dependencies(std::size_t index, const bool sync_point, type_list, type_list) { + builder.bind(static_cast(index)); + builder.set(type_hash::value(), sync_point || (sizeof...(RO) + sizeof...(RW) == 0u)); + (builder.ro(type_hash::value()), ...); + (builder.rw(type_hash::value()), ...); + } + +public: + /*! Basic registry type. */ + using registry_type = Registry; + /*! @brief Underlying entity identifier. */ + using entity_type = typename registry_type::entity_type; + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + /*! @brief Raw task function type. */ + using function_type = callback_type; + + /*! @brief Vertex type of a task graph defined as an adjacency list. */ + struct vertex { + /** + * @brief Constructs a vertex of the task graph. + * @param data The data associated with the vertex. + * @param from List of in-edges of the vertex. + * @param to List of out-edges of the vertex. + */ + vertex(vertex_data data, std::vector from, std::vector to) + : node{std::move(data)}, + in{std::move(from)}, + out{std::move(to)} {} + + /** + * @brief Fills a buffer with the type info objects for the writable + * resources of a vertex. + * @param buffer A buffer pre-allocated by the user. + * @param length The length of the user-supplied buffer. + * @return The number of type info objects written to the buffer. + */ + [[nodiscard]] size_type ro_dependency(const type_info **buffer, const std::size_t length) const noexcept { + return node.dependency(false, buffer, length); + } + + /** + * @brief Fills a buffer with the type info objects for the read-only + * resources of a vertex. + * @param buffer A buffer pre-allocated by the user. + * @param length The length of the user-supplied buffer. + * @return The number of type info objects written to the buffer. + */ + [[nodiscard]] size_type rw_dependency(const type_info **buffer, const std::size_t length) const noexcept { + return node.dependency(true, buffer, length); + } + + /** + * @brief Returns the number of read-only resources of a vertex. + * @return The number of read-only resources of the vertex. + */ + [[nodiscard]] size_type ro_count() const noexcept { + return node.ro_count; + } + + /** + * @brief Returns the number of writable resources of a vertex. + * @return The number of writable resources of the vertex. + */ + [[nodiscard]] size_type rw_count() const noexcept { + return node.rw_count; + } + + /** + * @brief Checks if a vertex is also a top-level one. + * @return True if the vertex is a top-level one, false otherwise. + */ + [[nodiscard]] bool top_level() const noexcept { + return in.empty(); + } + + /** + * @brief Returns a type info object associated with a vertex. + * @return A properly initialized type info object. + */ + [[nodiscard]] const type_info &info() const noexcept { + return *node.info; + } + + /** + * @brief Returns a user defined name associated with a vertex, if any. + * @return The user defined name associated with the vertex, if any. + */ + [[nodiscard]] const char *name() const noexcept { + return node.name; + } + + /** + * @brief Returns the function associated with a vertex. + * @return The function associated with the vertex. + */ + [[nodiscard]] function_type *callback() const noexcept { + return node.callback; + } + + /** + * @brief Returns the payload associated with a vertex, if any. + * @return The payload associated with the vertex, if any. + */ + [[nodiscard]] const void *data() const noexcept { + return node.payload; + } + + /** + * @brief Returns the list of in-edges of a vertex. + * @return The list of in-edges of a vertex. + */ + [[nodiscard]] const std::vector &in_edges() const noexcept { + return in; + } + + /** + * @brief Returns the list of out-edges of a vertex. + * @return The list of out-edges of a vertex. + */ + [[nodiscard]] const std::vector &out_edges() const noexcept { + return out; + } + + /** + * @brief Prepares a registry and assures that all required resources + * are properly instantiated before using them. + * @param reg A valid registry. + */ + void prepare(registry_type ®) const { + node.prepare ? node.prepare(reg) : void(); + } + + private: + vertex_data node; + std::vector in; + std::vector out; + }; + + /** + * @brief Adds a free function to the task list. + * @tparam Candidate Function to add to the task list. + * @tparam Req Additional requirements and/or override resource access mode. + * @param name Optional name to associate with the task. + */ + template + void emplace(const char *name = nullptr) { + using resource_type = decltype(internal::free_function_to_resource_traits(Candidate)); + + callback_type *callback = +[](const void *, registry_type ®) { + std::apply(Candidate, to_args(reg, typename resource_type::args{})); + }; + + vertex_data vdata{ + resource_type::ro::size, + resource_type::rw::size, + name, + nullptr, + callback, + +[](const bool rw, const type_info **buffer, const std::size_t length) { return rw ? fill_dependencies(typename resource_type::rw{}, buffer, length) : fill_dependencies(typename resource_type::ro{}, buffer, length); }, + +[](registry_type ®) { void(to_args(reg, typename resource_type::args{})); }, + &type_id>()}; + + track_dependencies(vertices.size(), resource_type::sync_point, typename resource_type::ro{}, typename resource_type::rw{}); + vertices.push_back(std::move(vdata)); + } + + /** + * @brief Adds a free function with payload or a member function with an + * instance to the task list. + * @tparam Candidate Function or member to add to the task list. + * @tparam Req Additional requirements and/or override resource access mode. + * @tparam Type Type of class or type of payload. + * @param value_or_instance A valid object that fits the purpose. + * @param name Optional name to associate with the task. + */ + template + void emplace(Type &value_or_instance, const char *name = nullptr) { + using resource_type = decltype(internal::constrained_function_to_resource_traits(Candidate)); + + callback_type *callback = +[](const void *payload, registry_type ®) { + Type *curr = static_cast(const_cast *>(payload)); + std::apply(Candidate, std::tuple_cat(std::forward_as_tuple(*curr), to_args(reg, typename resource_type::args{}))); + }; + + vertex_data vdata{ + resource_type::ro::size, + resource_type::rw::size, + name, + &value_or_instance, + callback, + +[](const bool rw, const type_info **buffer, const std::size_t length) { return rw ? fill_dependencies(typename resource_type::rw{}, buffer, length) : fill_dependencies(typename resource_type::ro{}, buffer, length); }, + +[](registry_type ®) { void(to_args(reg, typename resource_type::args{})); }, + &type_id>()}; + + track_dependencies(vertices.size(), resource_type::sync_point, typename resource_type::ro{}, typename resource_type::rw{}); + vertices.push_back(std::move(vdata)); + } + + /** + * @brief Adds an user defined function with optional payload to the task + * list. + * @tparam Req Additional requirements and/or override resource access mode. + * @param func Function to add to the task list. + * @param payload User defined arbitrary data. + * @param name Optional name to associate with the task. + */ + template + void emplace(function_type *func, const void *payload = nullptr, const char *name = nullptr) { + using resource_type = internal::resource_traits, type_list>; + track_dependencies(vertices.size(), true, typename resource_type::ro{}, typename resource_type::rw{}); + + vertex_data vdata{ + resource_type::ro::size, + resource_type::rw::size, + name, + payload, + func, + +[](const bool rw, const type_info **buffer, const std::size_t length) { return rw ? fill_dependencies(typename resource_type::rw{}, buffer, length) : fill_dependencies(typename resource_type::ro{}, buffer, length); }, + nullptr, + &type_id()}; + + vertices.push_back(std::move(vdata)); + } + + /** + * @brief Generates a task graph for the current content. + * @return The adjacency list of the task graph. + */ + [[nodiscard]] std::vector graph() const { + std::vector adjacency_list{}; + adjacency_list.reserve(vertices.size()); + auto adjacency_matrix = builder.graph(); + + for(auto curr: adjacency_matrix.vertices()) { + std::vector in{}; + std::vector out{}; + + for(auto &&edge: adjacency_matrix.in_edges(curr)) { + in.push_back(edge.first); + } + + for(auto &&edge: adjacency_matrix.out_edges(curr)) { + out.push_back(edge.second); + } + + adjacency_list.emplace_back(vertices[curr], std::move(in), std::move(out)); + } + + return adjacency_list; + } + + /*! @brief Erases all elements from a container. */ + void clear() { + builder.clear(); + vertices.clear(); + } + +private: + std::vector vertices; + flow builder; +}; + +} // namespace entt + +#endif + +// #include "entity/ranges.hpp" +#ifndef ENTT_ENTITY_RANGES_HPP +#define ENTT_ENTITY_RANGES_HPP + +#if __has_include() +# include +# +# if defined(__cpp_lib_ranges) +# include +// # include "fwd.hpp" + + +template +inline constexpr bool std::ranges::enable_borrowed_range>{true}; + +template +inline constexpr bool std::ranges::enable_borrowed_range>{true}; + +template +inline constexpr bool std::ranges::enable_view>{true}; + +template +inline constexpr bool std::ranges::enable_view>{true}; + +# endif +#endif + +#endif +// #include "entity/registry.hpp" +#ifndef ENTT_ENTITY_REGISTRY_HPP +#define ENTT_ENTITY_REGISTRY_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "../container/dense_map.hpp" +#ifndef ENTT_CONTAINER_DENSE_MAP_HPP +#define ENTT_CONTAINER_DENSE_MAP_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #include "../config/config.h" +#ifndef ENTT_CONFIG_CONFIG_H +#define ENTT_CONFIG_CONFIG_H + +// #include "version.h" +#ifndef ENTT_CONFIG_VERSION_H +#define ENTT_CONFIG_VERSION_H + +// #include "macro.h" +#ifndef ENTT_CONFIG_MACRO_H +#define ENTT_CONFIG_MACRO_H + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#define ENTT_STR(arg) #arg +#define ENTT_XSTR(arg) ENTT_STR(arg) + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*) + +#define ENTT_VERSION_MAJOR 3 +#define ENTT_VERSION_MINOR 16 +#define ENTT_VERSION_PATCH 0 + +#define ENTT_VERSION \ + ENTT_XSTR(ENTT_VERSION_MAJOR) \ + "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH) + +// NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION) +# define ENTT_CONSTEXPR +# define ENTT_THROW throw +# define ENTT_TRY try +# define ENTT_CATCH catch(...) +#else +# define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20) +# define ENTT_THROW +# define ENTT_TRY if(true) +# define ENTT_CATCH if(false) +#endif + +#if __has_include() +# include +# +# if defined(__cpp_consteval) +# define ENTT_CONSTEVAL consteval +# endif +#endif + +#ifndef ENTT_CONSTEVAL +# define ENTT_CONSTEVAL constexpr +#endif + +#ifdef ENTT_USE_ATOMIC +# include +# define ENTT_MAYBE_ATOMIC(Type) std::atomic +#else +# define ENTT_MAYBE_ATOMIC(Type) Type +#endif + +#ifndef ENTT_ID_TYPE +# include +# define ENTT_ID_TYPE std::uint32_t +#else +# include // provides coverage for types in the std namespace +#endif + +#ifndef ENTT_SPARSE_PAGE +# define ENTT_SPARSE_PAGE 4096 +#endif + +#ifndef ENTT_PACKED_PAGE +# define ENTT_PACKED_PAGE 1024 +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT +# define ENTT_ASSERT(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT +# include +# define ENTT_ASSERT(condition, msg) assert(((condition) && (msg))) +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg) +#endif + +#define ENTT_FAIL(msg) ENTT_ASSERT(false, msg); + +#ifdef ENTT_NO_ETO +# define ENTT_ETO_TYPE(Type) void +#else +# define ENTT_ETO_TYPE(Type) Type +#endif + +#ifdef ENTT_NO_MIXIN +# define ENTT_STORAGE(Mixin, ...) __VA_ARGS__ +#else +# define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__> +#endif + +#ifdef ENTT_STANDARD_CPP +# define ENTT_NONSTD false +#else +# define ENTT_NONSTD true +# if defined __clang__ || defined __GNUC__ +# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ +# define ENTT_PRETTY_FUNCTION_PREFIX '=' +# define ENTT_PRETTY_FUNCTION_SUFFIX ']' +# elif defined _MSC_VER +# define ENTT_PRETTY_FUNCTION __FUNCSIG__ +# define ENTT_PRETTY_FUNCTION_PREFIX '<' +# define ENTT_PRETTY_FUNCTION_SUFFIX '>' +# endif +#endif + +#ifndef ENTT_EXPORT +# if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER +# define ENTT_EXPORT __declspec(dllexport) +# define ENTT_IMPORT __declspec(dllimport) +# define ENTT_HIDDEN +# elif defined __GNUC__ && __GNUC__ >= 4 +# define ENTT_EXPORT __attribute__((visibility("default"))) +# define ENTT_IMPORT __attribute__((visibility("default"))) +# define ENTT_HIDDEN __attribute__((visibility("hidden"))) +# else /* Unsupported compiler */ +# define ENTT_EXPORT +# define ENTT_IMPORT +# define ENTT_HIDDEN +# endif +#endif + +#ifndef ENTT_API +# if defined ENTT_API_EXPORT +# define ENTT_API ENTT_EXPORT +# elif defined ENTT_API_IMPORT +# define ENTT_API ENTT_IMPORT +# else /* No API */ +# define ENTT_API +# endif +#endif + +#if defined _MSC_VER +# pragma detect_mismatch("entt.version", ENTT_VERSION) +# pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY)) +# pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE)) +# pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD)) +#endif + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + +// #include "../core/bit.hpp" +#ifndef ENTT_CORE_BIT_HPP +#define ENTT_CORE_BIT_HPP + +#include +#include +#include +// #include "../config/config.h" +#ifndef ENTT_CONFIG_CONFIG_H +#define ENTT_CONFIG_CONFIG_H + +// #include "version.h" +#ifndef ENTT_CONFIG_VERSION_H +#define ENTT_CONFIG_VERSION_H + +// #include "macro.h" +#ifndef ENTT_CONFIG_MACRO_H +#define ENTT_CONFIG_MACRO_H + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#define ENTT_STR(arg) #arg +#define ENTT_XSTR(arg) ENTT_STR(arg) + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*) + +#define ENTT_VERSION_MAJOR 3 +#define ENTT_VERSION_MINOR 16 +#define ENTT_VERSION_PATCH 0 + +#define ENTT_VERSION \ + ENTT_XSTR(ENTT_VERSION_MAJOR) \ + "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH) + +// NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION) +# define ENTT_CONSTEXPR +# define ENTT_THROW throw +# define ENTT_TRY try +# define ENTT_CATCH catch(...) +#else +# define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20) +# define ENTT_THROW +# define ENTT_TRY if(true) +# define ENTT_CATCH if(false) +#endif + +#if __has_include() +# include +# +# if defined(__cpp_consteval) +# define ENTT_CONSTEVAL consteval +# endif +#endif + +#ifndef ENTT_CONSTEVAL +# define ENTT_CONSTEVAL constexpr +#endif + +#ifdef ENTT_USE_ATOMIC +# include +# define ENTT_MAYBE_ATOMIC(Type) std::atomic +#else +# define ENTT_MAYBE_ATOMIC(Type) Type +#endif + +#ifndef ENTT_ID_TYPE +# include +# define ENTT_ID_TYPE std::uint32_t +#else +# include // provides coverage for types in the std namespace +#endif + +#ifndef ENTT_SPARSE_PAGE +# define ENTT_SPARSE_PAGE 4096 +#endif + +#ifndef ENTT_PACKED_PAGE +# define ENTT_PACKED_PAGE 1024 +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT +# define ENTT_ASSERT(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT +# include +# define ENTT_ASSERT(condition, msg) assert(((condition) && (msg))) +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg) +#endif + +#define ENTT_FAIL(msg) ENTT_ASSERT(false, msg); + +#ifdef ENTT_NO_ETO +# define ENTT_ETO_TYPE(Type) void +#else +# define ENTT_ETO_TYPE(Type) Type +#endif + +#ifdef ENTT_NO_MIXIN +# define ENTT_STORAGE(Mixin, ...) __VA_ARGS__ +#else +# define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__> +#endif + +#ifdef ENTT_STANDARD_CPP +# define ENTT_NONSTD false +#else +# define ENTT_NONSTD true +# if defined __clang__ || defined __GNUC__ +# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ +# define ENTT_PRETTY_FUNCTION_PREFIX '=' +# define ENTT_PRETTY_FUNCTION_SUFFIX ']' +# elif defined _MSC_VER +# define ENTT_PRETTY_FUNCTION __FUNCSIG__ +# define ENTT_PRETTY_FUNCTION_PREFIX '<' +# define ENTT_PRETTY_FUNCTION_SUFFIX '>' +# endif +#endif + +#ifndef ENTT_EXPORT +# if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER +# define ENTT_EXPORT __declspec(dllexport) +# define ENTT_IMPORT __declspec(dllimport) +# define ENTT_HIDDEN +# elif defined __GNUC__ && __GNUC__ >= 4 +# define ENTT_EXPORT __attribute__((visibility("default"))) +# define ENTT_IMPORT __attribute__((visibility("default"))) +# define ENTT_HIDDEN __attribute__((visibility("hidden"))) +# else /* Unsupported compiler */ +# define ENTT_EXPORT +# define ENTT_IMPORT +# define ENTT_HIDDEN +# endif +#endif + +#ifndef ENTT_API +# if defined ENTT_API_EXPORT +# define ENTT_API ENTT_EXPORT +# elif defined ENTT_API_IMPORT +# define ENTT_API ENTT_IMPORT +# else /* No API */ +# define ENTT_API +# endif +#endif + +#if defined _MSC_VER +# pragma detect_mismatch("entt.version", ENTT_VERSION) +# pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY)) +# pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE)) +# pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD)) +#endif + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +namespace entt { + +/** + * @brief Returns the number of set bits in a value (waiting for C++20 and + * `std::popcount`). + * @tparam Type Unsigned integer type. + * @param value A value of unsigned integer type. + * @return The number of set bits in the value. + */ +template +[[nodiscard]] constexpr std::enable_if_t, int> popcount(const Type value) noexcept { + return value ? (int(value & 1) + popcount(static_cast(value >> 1))) : 0; +} + +/** + * @brief Checks whether a value is a power of two or not (waiting for C++20 and + * `std::has_single_bit`). + * @tparam Type Unsigned integer type. + * @param value A value of unsigned integer type. + * @return True if the value is a power of two, false otherwise. + */ +template +[[nodiscard]] constexpr std::enable_if_t, bool> has_single_bit(const Type value) noexcept { + return value && ((value & (value - 1)) == 0); +} + +/** + * @brief Computes the smallest power of two greater than or equal to a value + * (waiting for C++20 and `std::bit_ceil`). + * @tparam Type Unsigned integer type. + * @param value A value of unsigned integer type. + * @return The smallest power of two greater than or equal to the given value. + */ +template +[[nodiscard]] constexpr std::enable_if_t, Type> next_power_of_two(const Type value) noexcept { + // NOLINTNEXTLINE(bugprone-assert-side-effect) + ENTT_ASSERT_CONSTEXPR(value < (Type{1u} << (std::numeric_limits::digits - 1)), "Numeric limits exceeded"); + Type curr = value - (value != 0u); + + for(int next = 1; next < std::numeric_limits::digits; next = next * 2) { + curr |= (curr >> next); + } + + return ++curr; +} + +/** + * @brief Fast module utility function (powers of two only). + * @tparam Type Unsigned integer type. + * @param value A value of unsigned integer type. + * @param mod _Modulus_, it must be a power of two. + * @return The common remainder. + */ +template +[[nodiscard]] constexpr std::enable_if_t, Type> fast_mod(const Type value, const std::size_t mod) noexcept { + ENTT_ASSERT_CONSTEXPR(has_single_bit(mod), "Value must be a power of two"); + return static_cast(value & (mod - 1u)); +} + +} // namespace entt + +#endif + +// #include "../core/compressed_pair.hpp" +#ifndef ENTT_CORE_COMPRESSED_PAIR_HPP +#define ENTT_CORE_COMPRESSED_PAIR_HPP + +#include +#include +#include +#include +// #include "fwd.hpp" +#ifndef ENTT_CORE_FWD_HPP +#define ENTT_CORE_FWD_HPP + +#include +#include +// #include "../config/config.h" + + +namespace entt { + +/*! @brief Possible modes of an any object. */ +enum class any_policy : std::uint8_t { + /*! @brief Default mode, no element available. */ + empty, + /*! @brief Owning mode, dynamically allocated element. */ + dynamic, + /*! @brief Owning mode, embedded element. */ + embedded, + /*! @brief Aliasing mode, non-const reference. */ + ref, + /*! @brief Const aliasing mode, const reference. */ + cref +}; + +// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) +template +class basic_any; + +/*! @brief Alias declaration for type identifiers. */ +using id_type = ENTT_ID_TYPE; + +/*! @brief Alias declaration for the most common use case. */ +using any = basic_any<>; + +template +class compressed_pair; + +template +class basic_hashed_string; + +/*! @brief Aliases for common character types. */ +using hashed_string = basic_hashed_string; + +/*! @brief Aliases for common character types. */ +using hashed_wstring = basic_hashed_string; + +// NOLINTNEXTLINE(bugprone-forward-declaration-namespace) +struct type_info; + +} // namespace entt + +#endif + +// #include "type_traits.hpp" +#ifndef ENTT_CORE_TYPE_TRAITS_HPP +#define ENTT_CORE_TYPE_TRAITS_HPP + +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "fwd.hpp" + + +namespace entt { + +/** + * @brief Utility class to disambiguate overloaded functions. + * @tparam N Number of choices available. + */ +template +struct choice_t + // unfortunately, doxygen cannot parse such a construct + : /*! @cond TURN_OFF_DOXYGEN */ choice_t /*! @endcond */ +{}; + +/*! @copybrief choice_t */ +template<> +struct choice_t<0> {}; + +/** + * @brief Variable template for the choice trick. + * @tparam N Number of choices available. + */ +template +inline constexpr choice_t choice{}; + +/** + * @brief Identity type trait. + * + * Useful to establish non-deduced contexts in template argument deduction + * (waiting for C++20) or to provide types through function arguments. + * + * @tparam Type A type. + */ +template +struct type_identity { + /*! @brief Identity type. */ + using type = Type; +}; + +/** + * @brief Helper type. + * @tparam Type A type. + */ +template +using type_identity_t = typename type_identity::type; + +/** + * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains. + * @tparam Type The type of which to return the size. + */ +template +struct size_of: std::integral_constant {}; + +/*! @copydoc size_of */ +template +struct size_of> + // NOLINTNEXTLINE(bugprone-sizeof-expression) + : std::integral_constant {}; + +/** + * @brief Helper variable template. + * @tparam Type The type of which to return the size. + */ +template +inline constexpr std::size_t size_of_v = size_of::value; + +/** + * @brief Using declaration to be used to _repeat_ the same type a number of + * times equal to the size of a given parameter pack. + * @tparam Type A type to repeat. + */ +template +using unpack_as_type = Type; + +/** + * @brief Helper variable template to be used to _repeat_ the same value a + * number of times equal to the size of a given parameter pack. + * @tparam Value A value to repeat. + */ +template +inline constexpr auto unpack_as_value = Value; + +/** + * @brief Wraps a static constant. + * @tparam Value A static constant. + */ +template +using integral_constant = std::integral_constant; + +/** + * @brief Alias template to facilitate the creation of named values. + * @tparam Value A constant value at least convertible to `id_type`. + */ +template +using tag = integral_constant; + +/** + * @brief A class to use to push around lists of types, nothing more. + * @tparam Type Types provided by the type list. + */ +template +struct type_list { + /*! @brief Type list type. */ + using type = type_list; + /*! @brief Compile-time number of elements in the type list. */ + static constexpr auto size = sizeof...(Type); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_element; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Index Index of the type to return. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element> + : type_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element<0u, type_list> { + /*! @brief Searched type. */ + using type = First; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Type list to search into. + */ +template +using type_list_element_t = typename type_list_element::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_index; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 1u + type_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + static_assert(type_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +inline constexpr std::size_t type_list_index_v = type_list_index::value; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @return A type list composed by the types of both the type lists. + */ +template +constexpr type_list operator+(type_list, type_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_cat; + +/*! @brief Concatenates multiple type lists. */ +template<> +struct type_list_cat<> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list<>; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @tparam List Other type lists, if any. + */ +template +struct type_list_cat, type_list, List...> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = typename type_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the type list. + */ +template +struct type_list_cat> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list; +}; + +/** + * @brief Helper type. + * @tparam List Type lists to concatenate. + */ +template +using type_list_cat_t = typename type_list_cat::type; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct type_list_unique; + +template +struct type_list_unique, Type...> + : std::conditional_t<(std::is_same_v || ...), type_list_unique, Type...>, type_list_unique, Type..., First>> {}; + +template +struct type_list_unique, Type...> { + using type = type_list; +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Removes duplicates types from a type list. + * @tparam List Type list. + */ +template +struct type_list_unique { + /*! @brief A type list without duplicate types. */ + using type = typename internal::type_list_unique::type; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + */ +template +using type_list_unique_t = typename type_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a type list contains a + * given type, false otherwise. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +struct type_list_contains; + +/** + * @copybrief type_list_contains + * @tparam Type Types provided by the type list. + * @tparam Other Type to look for. + */ +template +struct type_list_contains, Other> + : std::bool_constant<(std::is_same_v || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +inline constexpr bool type_list_contains_v = type_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_diff; + +/** + * @brief Computes the difference between two type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + */ +template +struct type_list_diff, type_list> { + /*! @brief A type list that is the difference between the two type lists. */ + using type = type_list_cat_t, Type>, type_list<>, type_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Type lists between which to compute the difference. + */ +template +using type_list_diff_t = typename type_list_diff::type; + +/*! @brief Primary template isn't defined on purpose. */ +template class> +struct type_list_transform; + +/** + * @brief Applies a given _function_ to a type list and generate a new list. + * @tparam Type Types provided by the type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +struct type_list_transform, Op> { + /*! @brief Resulting type list after applying the transform function. */ + // NOLINTNEXTLINE(modernize-type-traits) + using type = type_list::type...>; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +using type_list_transform_t = typename type_list_transform::type; + +/** + * @brief A class to use to push around lists of constant values, nothing more. + * @tparam Value Values provided by the value list. + */ +template +struct value_list { + /*! @brief Value list type. */ + using type = value_list; + /*! @brief Compile-time number of elements in the value list. */ + static constexpr auto size = sizeof...(Value); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_element; + +/** + * @brief Provides compile-time indexed access to the values of a value list. + * @tparam Index Index of the value to return. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element> + : value_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element<0u, value_list> { + /*! @brief Searched type. */ + using type = decltype(Value); + /*! @brief Searched value. */ + static constexpr auto value = Value; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Value list to search into. + */ +template +using value_list_element_t = typename value_list_element::type; + +/** + * @brief Helper type. + * @tparam Index Index of the value to return. + * @tparam List Value list to search into. + */ +template +inline constexpr auto value_list_element_v = value_list_element::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_index; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam First First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 1u + value_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + static_assert(value_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +inline constexpr std::size_t value_list_index_v = value_list_index::value; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @return A value list composed by the values of both the value lists. + */ +template +constexpr value_list operator+(value_list, value_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_cat; + +/*! @brief Concatenates multiple value lists. */ +template<> +struct value_list_cat<> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list<>; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @tparam List Other value lists, if any. + */ +template +struct value_list_cat, value_list, List...> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = typename value_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the value list. + */ +template +struct value_list_cat> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list; +}; + +/** + * @brief Helper type. + * @tparam List Value lists to concatenate. + */ +template +using value_list_cat_t = typename value_list_cat::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_unique; + +/** + * @brief Removes duplicates values from a value list. + * @tparam Value One of the values provided by the given value list. + * @tparam Other The other values provided by the given value list. + */ +template +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = std::conditional_t< + ((Value == Other) || ...), + typename value_list_unique>::type, + value_list_cat_t, typename value_list_unique>::type>>; +}; + +/*! @brief Removes duplicates values from a value list. */ +template<> +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = value_list<>; +}; + +/** + * @brief Helper type. + * @tparam Type A value list. + */ +template +using value_list_unique_t = typename value_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a value list contains + * a given value, false otherwise. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +struct value_list_contains; + +/** + * @copybrief value_list_contains + * @tparam Value Values provided by the value list. + * @tparam Other Value to look for. + */ +template +struct value_list_contains, Other> + : std::bool_constant<((Value == Other) || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +inline constexpr bool value_list_contains_v = value_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_diff; + +/** + * @brief Computes the difference between two value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + */ +template +struct value_list_diff, value_list> { + /*! @brief A value list that is the difference between the two value lists. */ + using type = value_list_cat_t, Value>, value_list<>, value_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Value lists between which to compute the difference. + */ +template +using value_list_diff_t = typename value_list_diff::type; + +/*! @brief Same as std::is_invocable, but with tuples. */ +template +struct is_applicable: std::false_type {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @brief Helper variable template. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_v = is_applicable::value; + +/*! @brief Same as std::is_invocable_r, but with tuples for arguments. */ +template +struct is_applicable_r: std::false_type {}; + +/** + * @copybrief is_applicable_r + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +struct is_applicable_r>: std::is_invocable_r {}; + +/** + * @brief Helper variable template. + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_r_v = is_applicable_r::value; + +/** + * @brief Provides the member constant `value` to true if a given type is + * complete, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_complete: std::false_type {}; + +/*! @copydoc is_complete */ +template +struct is_complete>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_complete_v = is_complete::value; + +/** + * @brief Provides the member constant `value` to true if a given type is an + * iterator, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_iterator: std::false_type {}; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_iterator_category: std::false_type {}; + +template +struct has_iterator_category::iterator_category>>: std::true_type {}; + +} // namespace internal +/*! @endcond */ + +/*! @copydoc is_iterator */ +template +struct is_iterator>>>> + : internal::has_iterator_category {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_iterator_v = is_iterator::value; + +/** + * @brief Provides the member constant `value` to true if a given type is both + * an empty and non-final class, false otherwise. + * @tparam Type The type to test + */ +template +struct is_ebco_eligible + : std::bool_constant && !std::is_final_v> {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_ebco_eligible_v = is_ebco_eligible::value; + +/** + * @brief Provides the member constant `value` to true if `Type::is_transparent` + * is valid and denotes a type, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_transparent: std::false_type {}; + +/*! @copydoc is_transparent */ +template +struct is_transparent>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_transparent_v = is_transparent::value; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_tuple_size_value: std::false_type {}; + +template +struct has_tuple_size_value::value)>>: std::true_type {}; + +template +struct has_value_type: std::false_type {}; + +template +struct has_value_type>: std::true_type {}; + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable(); + +template +[[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence) { + return (dispatch_is_equality_comparable>() && ...); +} + +template +[[nodiscard]] constexpr bool maybe_equality_comparable(char) { + return false; +} + +template +[[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval() == std::declval()) { + return true; +} + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable() { + // NOLINTBEGIN(modernize-use-transparent-functors) + if constexpr(std::is_array_v) { + return false; + } else if constexpr(is_complete_v>>) { + if constexpr(has_tuple_size_value::value) { + return maybe_equality_comparable(0) && unpack_maybe_equality_comparable(std::make_index_sequence::value>{}); + } else { + return maybe_equality_comparable(0); + } + } else if constexpr(has_value_type::value) { + if constexpr(is_iterator_v || std::is_same_v || dispatch_is_equality_comparable()) { + return maybe_equality_comparable(0); + } else { + return false; + } + } else { + return maybe_equality_comparable(0); + } + // NOLINTEND(modernize-use-transparent-functors) +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Provides the member constant `value` to true if a given type is + * equality comparable, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_equality_comparable: std::bool_constant()> {}; + +/*! @copydoc is_equality_comparable */ +template +struct is_equality_comparable: is_equality_comparable {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_equality_comparable_v = is_equality_comparable::value; + +/** + * @brief Transcribes the constness of a type to another type. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = std::remove_const_t; +}; + +/*! @copydoc constness_as */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = const To; +}; + +/** + * @brief Alias template to facilitate the transcription of the constness. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +using constness_as_t = typename constness_as::type; + +/** + * @brief Extracts the class of a non-static member object or function. + * @tparam Member A pointer to a non-static member object or function. + */ +template +class member_class { + static_assert(std::is_member_pointer_v, "Invalid pointer type to non-static member object or function"); + + template + static Class *clazz(Ret (Class::*)(Args...)); + + template + static Class *clazz(Ret (Class::*)(Args...) const); + + template + static Class *clazz(Type Class::*); + +public: + /*! @brief The class of the given non-static member object or function. */ + using type = std::remove_pointer_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Member A pointer to a non-static member object or function. + */ +template +using member_class_t = typename member_class::type; + +/** + * @brief Extracts the n-th argument of a _callable_ type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid _callable_ type. + */ +template +class nth_argument { + template + static constexpr type_list pick_up(Ret (*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...) const); + + template + static constexpr type_list pick_up(Type Class ::*); + + template + static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&); + +public: + /*! @brief N-th argument of the _callable_ type. */ + using type = type_list_element_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid function, member function or data member type. + */ +template +using nth_argument_t = typename nth_argument::type; + +} // namespace entt + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::type_list_element> {}; + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::value_list_element> {}; + +#endif + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct compressed_pair_element { + using reference = Type &; + using const_reference = const Type &; + + template>> + // NOLINTNEXTLINE(modernize-use-equals-default) + constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v) {} + + template>, compressed_pair_element>>> + constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v) + : value{std::forward(arg)} {} + + template + constexpr compressed_pair_element(std::tuple args, std::index_sequence) noexcept(std::is_nothrow_constructible_v) + : value{std::forward(std::get(args))...} {} + + [[nodiscard]] constexpr reference get() noexcept { + return value; + } + + [[nodiscard]] constexpr const_reference get() const noexcept { + return value; + } + +private: + Type value{}; +}; + +template +struct compressed_pair_element>>: Type { + using reference = Type &; + using const_reference = const Type &; + using base_type = Type; + + template>> + constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v) + : base_type{} {} + + template>, compressed_pair_element>>> + constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v) + : base_type{std::forward(arg)} {} + + template + constexpr compressed_pair_element(std::tuple args, std::index_sequence) noexcept(std::is_nothrow_constructible_v) + : base_type{std::forward(std::get(args))...} {} + + [[nodiscard]] constexpr reference get() noexcept { + return *this; + } + + [[nodiscard]] constexpr const_reference get() const noexcept { + return *this; + } +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief A compressed pair. + * + * A pair that exploits the _Empty Base Class Optimization_ (or _EBCO_) to + * reduce its final size to a minimum. + * + * @tparam First The type of the first element that the pair stores. + * @tparam Second The type of the second element that the pair stores. + */ +template +class compressed_pair final + : internal::compressed_pair_element, + internal::compressed_pair_element { + using first_base = internal::compressed_pair_element; + using second_base = internal::compressed_pair_element; + +public: + /*! @brief The type of the first element that the pair stores. */ + using first_type = First; + /*! @brief The type of the second element that the pair stores. */ + using second_type = Second; + + /** + * @brief Default constructor, conditionally enabled. + * + * This constructor is only available when the types that the pair stores + * are both at least default constructible. + * + * @tparam Dummy Dummy template parameter used for internal purposes. + */ + template && std::is_default_constructible_v>> + constexpr compressed_pair() noexcept(std::is_nothrow_default_constructible_v && std::is_nothrow_default_constructible_v) + : first_base{}, + second_base{} {} + + /** + * @brief Copy constructor. + * @param other The instance to copy from. + */ + constexpr compressed_pair(const compressed_pair &other) = default; + + /** + * @brief Move constructor. + * @param other The instance to move from. + */ + constexpr compressed_pair(compressed_pair &&other) noexcept = default; + + /** + * @brief Constructs a pair from its values. + * @tparam Arg Type of value to use to initialize the first element. + * @tparam Other Type of value to use to initialize the second element. + * @param arg Value to use to initialize the first element. + * @param other Value to use to initialize the second element. + */ + template + constexpr compressed_pair(Arg &&arg, Other &&other) noexcept(std::is_nothrow_constructible_v && std::is_nothrow_constructible_v) + : first_base{std::forward(arg)}, + second_base{std::forward(other)} {} + + /** + * @brief Constructs a pair by forwarding the arguments to its parts. + * @tparam Args Types of arguments to use to initialize the first element. + * @tparam Other Types of arguments to use to initialize the second element. + * @param args Arguments to use to initialize the first element. + * @param other Arguments to use to initialize the second element. + */ + template + constexpr compressed_pair(std::piecewise_construct_t, std::tuple args, std::tuple other) noexcept(std::is_nothrow_constructible_v && std::is_nothrow_constructible_v) + : first_base{std::move(args), std::index_sequence_for{}}, + second_base{std::move(other), std::index_sequence_for{}} {} + + /*! @brief Default destructor. */ + ~compressed_pair() = default; + + /** + * @brief Copy assignment operator. + * @param other The instance to copy from. + * @return This compressed pair object. + */ + constexpr compressed_pair &operator=(const compressed_pair &other) = default; + + /** + * @brief Move assignment operator. + * @param other The instance to move from. + * @return This compressed pair object. + */ + constexpr compressed_pair &operator=(compressed_pair &&other) noexcept = default; + + /** + * @brief Returns the first element that a pair stores. + * @return The first element that a pair stores. + */ + [[nodiscard]] constexpr first_type &first() noexcept { + return static_cast(*this).get(); + } + + /*! @copydoc first */ + [[nodiscard]] constexpr const first_type &first() const noexcept { + return static_cast(*this).get(); + } + + /** + * @brief Returns the second element that a pair stores. + * @return The second element that a pair stores. + */ + [[nodiscard]] constexpr second_type &second() noexcept { + return static_cast(*this).get(); + } + + /*! @copydoc second */ + [[nodiscard]] constexpr const second_type &second() const noexcept { + return static_cast(*this).get(); + } + + /** + * @brief Swaps two compressed pair objects. + * @param other The compressed pair to swap with. + */ + constexpr void swap(compressed_pair &other) noexcept { + using std::swap; + swap(first(), other.first()); + swap(second(), other.second()); + } + + /** + * @brief Extracts an element from the compressed pair. + * @tparam Index An integer value that is either 0 or 1. + * @return Returns a reference to the first element if `Index` is 0 and a + * reference to the second element if `Index` is 1. + */ + template + [[nodiscard]] constexpr decltype(auto) get() noexcept { + if constexpr(Index == 0u) { + return first(); + } else { + static_assert(Index == 1u, "Index out of bounds"); + return second(); + } + } + + /*! @copydoc get */ + template + [[nodiscard]] constexpr decltype(auto) get() const noexcept { + if constexpr(Index == 0u) { + return first(); + } else { + static_assert(Index == 1u, "Index out of bounds"); + return second(); + } + } +}; + +/** + * @brief Deduction guide. + * @tparam Type Type of value to use to initialize the first element. + * @tparam Other Type of value to use to initialize the second element. + */ +template +compressed_pair(Type &&, Other &&) -> compressed_pair, std::decay_t>; + +/** + * @brief Swaps two compressed pair objects. + * @tparam First The type of the first element that the pairs store. + * @tparam Second The type of the second element that the pairs store. + * @param lhs A valid compressed pair object. + * @param rhs A valid compressed pair object. + */ +template +constexpr void swap(compressed_pair &lhs, compressed_pair &rhs) noexcept { + lhs.swap(rhs); +} + +} // namespace entt + +namespace std { + +/** + * @brief `std::tuple_size` specialization for `compressed_pair`s. + * @tparam First The type of the first element that the pair stores. + * @tparam Second The type of the second element that the pair stores. + */ +template +struct tuple_size>: integral_constant {}; + +/** + * @brief `std::tuple_element` specialization for `compressed_pair`s. + * @tparam Index The index of the type to return. + * @tparam First The type of the first element that the pair stores. + * @tparam Second The type of the second element that the pair stores. + */ +template +struct tuple_element>: conditional { + static_assert(Index < 2u, "Index out of bounds"); +}; + +} // namespace std + +#endif + +// #include "../core/iterator.hpp" +#ifndef ENTT_CORE_ITERATOR_HPP +#define ENTT_CORE_ITERATOR_HPP + +#include +#include +#include +#include + +namespace entt { + +/** + * @brief Helper type to use as pointer with input iterators. + * @tparam Type of wrapped value. + */ +template +struct input_iterator_pointer final { + /*! @brief Value type. */ + using value_type = Type; + /*! @brief Pointer type. */ + using pointer = Type *; + /*! @brief Reference type. */ + using reference = Type &; + + /** + * @brief Constructs a proxy object by move. + * @param val Value to use to initialize the proxy object. + */ + constexpr input_iterator_pointer(value_type &&val) noexcept(std::is_nothrow_move_constructible_v) + : value{std::move(val)} {} + + /** + * @brief Access operator for accessing wrapped values. + * @return A pointer to the wrapped value. + */ + [[nodiscard]] constexpr pointer operator->() noexcept { + return std::addressof(value); + } + + /** + * @brief Dereference operator for accessing wrapped values. + * @return A reference to the wrapped value. + */ + [[nodiscard]] constexpr reference operator*() noexcept { + return value; + } + +private: + Type value; +}; + +/** + * @brief Plain iota iterator (waiting for C++20). + * @tparam Type Value type. + */ +template +class iota_iterator final { + static_assert(std::is_integral_v, "Not an integral type"); + +public: + /*! @brief Value type, likely an integral one. */ + using value_type = Type; + /*! @brief Invalid pointer type. */ + using pointer = void; + /*! @brief Non-reference type, same as value type. */ + using reference = value_type; + /*! @brief Difference type. */ + using difference_type = std::ptrdiff_t; + /*! @brief Iterator category. */ + using iterator_category = std::input_iterator_tag; + + /*! @brief Default constructor. */ + constexpr iota_iterator() noexcept + : current{} {} + + /** + * @brief Constructs an iota iterator from a given value. + * @param init The initial value assigned to the iota iterator. + */ + constexpr iota_iterator(const value_type init) noexcept + : current{init} {} + + /** + * @brief Pre-increment operator. + * @return This iota iterator. + */ + constexpr iota_iterator &operator++() noexcept { + return ++current, *this; + } + + /** + * @brief Post-increment operator. + * @return This iota iterator. + */ + constexpr iota_iterator operator++(int) noexcept { + const iota_iterator orig = *this; + return ++(*this), orig; + } + + /** + * @brief Dereference operator. + * @return The underlying value. + */ + [[nodiscard]] constexpr reference operator*() const noexcept { + return current; + } + +private: + value_type current; +}; + +/** + * @brief Comparison operator. + * @tparam Type Value type of the iota iterator. + * @param lhs A properly initialized iota iterator. + * @param rhs A properly initialized iota iterator. + * @return True if the two iterators are identical, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator==(const iota_iterator &lhs, const iota_iterator &rhs) noexcept { + return *lhs == *rhs; +} + +/** + * @brief Comparison operator. + * @tparam Type Value type of the iota iterator. + * @param lhs A properly initialized iota iterator. + * @param rhs A properly initialized iota iterator. + * @return True if the two iterators differ, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator!=(const iota_iterator &lhs, const iota_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +/** + * @brief Utility class to create an iterable object from a pair of iterators. + * @tparam It Type of iterator. + * @tparam Sentinel Type of sentinel. + */ +template +struct iterable_adaptor final { + /*! @brief Value type. */ + using value_type = typename std::iterator_traits::value_type; + /*! @brief Iterator type. */ + using iterator = It; + /*! @brief Sentinel type. */ + using sentinel = Sentinel; + + /*! @brief Default constructor. */ + constexpr iterable_adaptor() noexcept(std::is_nothrow_default_constructible_v && std::is_nothrow_default_constructible_v) + : first{}, + last{} {} + + /** + * @brief Creates an iterable object from a pair of iterators. + * @param from Begin iterator. + * @param to End iterator. + */ + constexpr iterable_adaptor(iterator from, sentinel to) noexcept(std::is_nothrow_move_constructible_v && std::is_nothrow_move_constructible_v) + : first{std::move(from)}, + last{std::move(to)} {} + + /** + * @brief Returns an iterator to the beginning. + * @return An iterator to the first element of the range. + */ + [[nodiscard]] constexpr iterator begin() const noexcept { + return first; + } + + /** + * @brief Returns an iterator to the end. + * @return An iterator to the element following the last element of the + * range. + */ + [[nodiscard]] constexpr sentinel end() const noexcept { + return last; + } + + /*! @copydoc begin */ + [[nodiscard]] constexpr iterator cbegin() const noexcept { + return begin(); + } + + /*! @copydoc end */ + [[nodiscard]] constexpr sentinel cend() const noexcept { + return end(); + } + +private: + It first; + Sentinel last; +}; + +} // namespace entt + +#endif + +// #include "../core/memory.hpp" +#ifndef ENTT_CORE_MEMORY_HPP +#define ENTT_CORE_MEMORY_HPP + +#include +#include +#include +#include +#include +// #include "../config/config.h" + + +namespace entt { + +/** + * @brief Unwraps fancy pointers, does nothing otherwise (waiting for C++20). + * @tparam Type Pointer type. + * @param ptr Fancy or raw pointer. + * @return A raw pointer that represents the address of the original pointer. + */ +template +[[nodiscard]] constexpr auto to_address(Type &&ptr) noexcept { + if constexpr(std::is_pointer_v>) { + return ptr; + } else { + return to_address(std::forward(ptr).operator->()); + } +} + +/** + * @brief Utility function to design allocation-aware containers. + * @tparam Allocator Type of allocator. + * @param lhs A valid allocator. + * @param rhs Another valid allocator. + */ +template +constexpr void propagate_on_container_copy_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept { + if constexpr(std::allocator_traits::propagate_on_container_copy_assignment::value) { + lhs = rhs; + } +} + +/** + * @brief Utility function to design allocation-aware containers. + * @tparam Allocator Type of allocator. + * @param lhs A valid allocator. + * @param rhs Another valid allocator. + */ +template +constexpr void propagate_on_container_move_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept { + if constexpr(std::allocator_traits::propagate_on_container_move_assignment::value) { + lhs = std::move(rhs); + } +} + +/** + * @brief Utility function to design allocation-aware containers. + * @tparam Allocator Type of allocator. + * @param lhs A valid allocator. + * @param rhs Another valid allocator. + */ +template +constexpr void propagate_on_container_swap([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept { + if constexpr(std::allocator_traits::propagate_on_container_swap::value) { + using std::swap; + swap(lhs, rhs); + } else { + ENTT_ASSERT_CONSTEXPR(lhs == rhs, "Cannot swap the containers"); + } +} + +/** + * @brief Deleter for allocator-aware unique pointers (waiting for C++20). + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +struct allocation_deleter: private Allocator { + /*! @brief Allocator type. */ + using allocator_type = Allocator; + /*! @brief Pointer type. */ + using pointer = typename std::allocator_traits::pointer; + + /** + * @brief Inherited constructors. + * @param alloc The allocator to use. + */ + constexpr allocation_deleter(const allocator_type &alloc) noexcept(std::is_nothrow_copy_constructible_v) + : Allocator{alloc} {} + + /** + * @brief Destroys the pointed object and deallocates its memory. + * @param ptr A valid pointer to an object of the given type. + */ + constexpr void operator()(pointer ptr) noexcept(std::is_nothrow_destructible_v) { + using alloc_traits = std::allocator_traits; + alloc_traits::destroy(*this, to_address(ptr)); + alloc_traits::deallocate(*this, ptr, 1u); + } +}; + +/** + * @brief Allows `std::unique_ptr` to use allocators (waiting for C++20). + * @tparam Type Type of object to allocate for and to construct. + * @tparam Allocator Type of allocator used to manage memory and elements. + * @tparam Args Types of arguments to use to construct the object. + * @param allocator The allocator to use. + * @param args Parameters to use to construct the object. + * @return A properly initialized unique pointer with a custom deleter. + */ +template +ENTT_CONSTEXPR auto allocate_unique(Allocator &allocator, Args &&...args) { + static_assert(!std::is_array_v, "Array types are not supported"); + + using alloc_traits = typename std::allocator_traits::template rebind_traits; + using allocator_type = typename alloc_traits::allocator_type; + + allocator_type alloc{allocator}; + auto ptr = alloc_traits::allocate(alloc, 1u); + + ENTT_TRY { + alloc_traits::construct(alloc, to_address(ptr), std::forward(args)...); + } + ENTT_CATCH { + alloc_traits::deallocate(alloc, ptr, 1u); + ENTT_THROW; + } + + return std::unique_ptr>{ptr, alloc}; +} + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct uses_allocator_construction { + template + static constexpr auto args([[maybe_unused]] const Allocator &allocator, Params &&...params) noexcept { + if constexpr(!std::uses_allocator_v && std::is_constructible_v) { + return std::forward_as_tuple(std::forward(params)...); + } else { + static_assert(std::uses_allocator_v, "Ill-formed request"); + + if constexpr(std::is_constructible_v) { + return std::tuple{std::allocator_arg, allocator, std::forward(params)...}; + } else { + static_assert(std::is_constructible_v, "Ill-formed request"); + return std::forward_as_tuple(std::forward(params)..., allocator); + } + } + } +}; + +template +struct uses_allocator_construction> { + using type = std::pair; + + template + static constexpr auto args(const Allocator &allocator, std::piecewise_construct_t, First &&first, Second &&second) noexcept { + return std::make_tuple( + std::piecewise_construct, + std::apply([&allocator](auto &&...curr) { return uses_allocator_construction::args(allocator, std::forward(curr)...); }, std::forward(first)), + std::apply([&allocator](auto &&...curr) { return uses_allocator_construction::args(allocator, std::forward(curr)...); }, std::forward(second))); + } + + template + static constexpr auto args(const Allocator &allocator) noexcept { + return uses_allocator_construction::args(allocator, std::piecewise_construct, std::tuple<>{}, std::tuple<>{}); + } + + template + static constexpr auto args(const Allocator &allocator, First &&first, Second &&second) noexcept { + return uses_allocator_construction::args(allocator, std::piecewise_construct, std::forward_as_tuple(std::forward(first)), std::forward_as_tuple(std::forward(second))); + } + + template + static constexpr auto args(const Allocator &allocator, const std::pair &value) noexcept { + return uses_allocator_construction::args(allocator, std::piecewise_construct, std::forward_as_tuple(value.first), std::forward_as_tuple(value.second)); + } + + template + static constexpr auto args(const Allocator &allocator, std::pair &&value) noexcept { + return uses_allocator_construction::args(allocator, std::piecewise_construct, std::forward_as_tuple(std::move(value.first)), std::forward_as_tuple(std::move(value.second))); + } +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Uses-allocator construction utility (waiting for C++20). + * + * Primarily intended for internal use. Prepares the argument list needed to + * create an object of a given type by means of uses-allocator construction. + * + * @tparam Type Type to return arguments for. + * @tparam Allocator Type of allocator used to manage memory and elements. + * @tparam Args Types of arguments to use to construct the object. + * @param allocator The allocator to use. + * @param args Parameters to use to construct the object. + * @return The arguments needed to create an object of the given type. + */ +template +constexpr auto uses_allocator_construction_args(const Allocator &allocator, Args &&...args) noexcept { + return internal::uses_allocator_construction::args(allocator, std::forward(args)...); +} + +/** + * @brief Uses-allocator construction utility (waiting for C++20). + * + * Primarily intended for internal use. Creates an object of a given type by + * means of uses-allocator construction. + * + * @tparam Type Type of object to create. + * @tparam Allocator Type of allocator used to manage memory and elements. + * @tparam Args Types of arguments to use to construct the object. + * @param allocator The allocator to use. + * @param args Parameters to use to construct the object. + * @return A newly created object of the given type. + */ +template +constexpr Type make_obj_using_allocator(const Allocator &allocator, Args &&...args) { + return std::make_from_tuple(internal::uses_allocator_construction::args(allocator, std::forward(args)...)); +} + +/** + * @brief Uses-allocator construction utility (waiting for C++20). + * + * Primarily intended for internal use. Creates an object of a given type by + * means of uses-allocator construction at an uninitialized memory location. + * + * @tparam Type Type of object to create. + * @tparam Allocator Type of allocator used to manage memory and elements. + * @tparam Args Types of arguments to use to construct the object. + * @param value Memory location in which to place the object. + * @param allocator The allocator to use. + * @param args Parameters to use to construct the object. + * @return A pointer to the newly created object of the given type. + */ +template +constexpr Type *uninitialized_construct_using_allocator(Type *value, const Allocator &allocator, Args &&...args) { + return std::apply([value](auto &&...curr) { return ::new(value) Type(std::forward(curr)...); }, internal::uses_allocator_construction::args(allocator, std::forward(args)...)); +} + +} // namespace entt + +#endif + +// #include "../core/type_traits.hpp" +#ifndef ENTT_CORE_TYPE_TRAITS_HPP +#define ENTT_CORE_TYPE_TRAITS_HPP + +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "fwd.hpp" + + +namespace entt { + +/** + * @brief Utility class to disambiguate overloaded functions. + * @tparam N Number of choices available. + */ +template +struct choice_t + // unfortunately, doxygen cannot parse such a construct + : /*! @cond TURN_OFF_DOXYGEN */ choice_t /*! @endcond */ +{}; + +/*! @copybrief choice_t */ +template<> +struct choice_t<0> {}; + +/** + * @brief Variable template for the choice trick. + * @tparam N Number of choices available. + */ +template +inline constexpr choice_t choice{}; + +/** + * @brief Identity type trait. + * + * Useful to establish non-deduced contexts in template argument deduction + * (waiting for C++20) or to provide types through function arguments. + * + * @tparam Type A type. + */ +template +struct type_identity { + /*! @brief Identity type. */ + using type = Type; +}; + +/** + * @brief Helper type. + * @tparam Type A type. + */ +template +using type_identity_t = typename type_identity::type; + +/** + * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains. + * @tparam Type The type of which to return the size. + */ +template +struct size_of: std::integral_constant {}; + +/*! @copydoc size_of */ +template +struct size_of> + // NOLINTNEXTLINE(bugprone-sizeof-expression) + : std::integral_constant {}; + +/** + * @brief Helper variable template. + * @tparam Type The type of which to return the size. + */ +template +inline constexpr std::size_t size_of_v = size_of::value; + +/** + * @brief Using declaration to be used to _repeat_ the same type a number of + * times equal to the size of a given parameter pack. + * @tparam Type A type to repeat. + */ +template +using unpack_as_type = Type; + +/** + * @brief Helper variable template to be used to _repeat_ the same value a + * number of times equal to the size of a given parameter pack. + * @tparam Value A value to repeat. + */ +template +inline constexpr auto unpack_as_value = Value; + +/** + * @brief Wraps a static constant. + * @tparam Value A static constant. + */ +template +using integral_constant = std::integral_constant; + +/** + * @brief Alias template to facilitate the creation of named values. + * @tparam Value A constant value at least convertible to `id_type`. + */ +template +using tag = integral_constant; + +/** + * @brief A class to use to push around lists of types, nothing more. + * @tparam Type Types provided by the type list. + */ +template +struct type_list { + /*! @brief Type list type. */ + using type = type_list; + /*! @brief Compile-time number of elements in the type list. */ + static constexpr auto size = sizeof...(Type); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_element; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Index Index of the type to return. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element> + : type_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element<0u, type_list> { + /*! @brief Searched type. */ + using type = First; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Type list to search into. + */ +template +using type_list_element_t = typename type_list_element::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_index; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 1u + type_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + static_assert(type_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +inline constexpr std::size_t type_list_index_v = type_list_index::value; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @return A type list composed by the types of both the type lists. + */ +template +constexpr type_list operator+(type_list, type_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_cat; + +/*! @brief Concatenates multiple type lists. */ +template<> +struct type_list_cat<> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list<>; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @tparam List Other type lists, if any. + */ +template +struct type_list_cat, type_list, List...> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = typename type_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the type list. + */ +template +struct type_list_cat> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list; +}; + +/** + * @brief Helper type. + * @tparam List Type lists to concatenate. + */ +template +using type_list_cat_t = typename type_list_cat::type; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct type_list_unique; + +template +struct type_list_unique, Type...> + : std::conditional_t<(std::is_same_v || ...), type_list_unique, Type...>, type_list_unique, Type..., First>> {}; + +template +struct type_list_unique, Type...> { + using type = type_list; +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Removes duplicates types from a type list. + * @tparam List Type list. + */ +template +struct type_list_unique { + /*! @brief A type list without duplicate types. */ + using type = typename internal::type_list_unique::type; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + */ +template +using type_list_unique_t = typename type_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a type list contains a + * given type, false otherwise. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +struct type_list_contains; + +/** + * @copybrief type_list_contains + * @tparam Type Types provided by the type list. + * @tparam Other Type to look for. + */ +template +struct type_list_contains, Other> + : std::bool_constant<(std::is_same_v || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +inline constexpr bool type_list_contains_v = type_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_diff; + +/** + * @brief Computes the difference between two type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + */ +template +struct type_list_diff, type_list> { + /*! @brief A type list that is the difference between the two type lists. */ + using type = type_list_cat_t, Type>, type_list<>, type_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Type lists between which to compute the difference. + */ +template +using type_list_diff_t = typename type_list_diff::type; + +/*! @brief Primary template isn't defined on purpose. */ +template class> +struct type_list_transform; + +/** + * @brief Applies a given _function_ to a type list and generate a new list. + * @tparam Type Types provided by the type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +struct type_list_transform, Op> { + /*! @brief Resulting type list after applying the transform function. */ + // NOLINTNEXTLINE(modernize-type-traits) + using type = type_list::type...>; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +using type_list_transform_t = typename type_list_transform::type; + +/** + * @brief A class to use to push around lists of constant values, nothing more. + * @tparam Value Values provided by the value list. + */ +template +struct value_list { + /*! @brief Value list type. */ + using type = value_list; + /*! @brief Compile-time number of elements in the value list. */ + static constexpr auto size = sizeof...(Value); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_element; + +/** + * @brief Provides compile-time indexed access to the values of a value list. + * @tparam Index Index of the value to return. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element> + : value_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element<0u, value_list> { + /*! @brief Searched type. */ + using type = decltype(Value); + /*! @brief Searched value. */ + static constexpr auto value = Value; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Value list to search into. + */ +template +using value_list_element_t = typename value_list_element::type; + +/** + * @brief Helper type. + * @tparam Index Index of the value to return. + * @tparam List Value list to search into. + */ +template +inline constexpr auto value_list_element_v = value_list_element::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_index; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam First First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 1u + value_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + static_assert(value_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +inline constexpr std::size_t value_list_index_v = value_list_index::value; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @return A value list composed by the values of both the value lists. + */ +template +constexpr value_list operator+(value_list, value_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_cat; + +/*! @brief Concatenates multiple value lists. */ +template<> +struct value_list_cat<> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list<>; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @tparam List Other value lists, if any. + */ +template +struct value_list_cat, value_list, List...> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = typename value_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the value list. + */ +template +struct value_list_cat> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list; +}; + +/** + * @brief Helper type. + * @tparam List Value lists to concatenate. + */ +template +using value_list_cat_t = typename value_list_cat::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_unique; + +/** + * @brief Removes duplicates values from a value list. + * @tparam Value One of the values provided by the given value list. + * @tparam Other The other values provided by the given value list. + */ +template +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = std::conditional_t< + ((Value == Other) || ...), + typename value_list_unique>::type, + value_list_cat_t, typename value_list_unique>::type>>; +}; + +/*! @brief Removes duplicates values from a value list. */ +template<> +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = value_list<>; +}; + +/** + * @brief Helper type. + * @tparam Type A value list. + */ +template +using value_list_unique_t = typename value_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a value list contains + * a given value, false otherwise. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +struct value_list_contains; + +/** + * @copybrief value_list_contains + * @tparam Value Values provided by the value list. + * @tparam Other Value to look for. + */ +template +struct value_list_contains, Other> + : std::bool_constant<((Value == Other) || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +inline constexpr bool value_list_contains_v = value_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_diff; + +/** + * @brief Computes the difference between two value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + */ +template +struct value_list_diff, value_list> { + /*! @brief A value list that is the difference between the two value lists. */ + using type = value_list_cat_t, Value>, value_list<>, value_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Value lists between which to compute the difference. + */ +template +using value_list_diff_t = typename value_list_diff::type; + +/*! @brief Same as std::is_invocable, but with tuples. */ +template +struct is_applicable: std::false_type {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @brief Helper variable template. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_v = is_applicable::value; + +/*! @brief Same as std::is_invocable_r, but with tuples for arguments. */ +template +struct is_applicable_r: std::false_type {}; + +/** + * @copybrief is_applicable_r + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +struct is_applicable_r>: std::is_invocable_r {}; + +/** + * @brief Helper variable template. + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_r_v = is_applicable_r::value; + +/** + * @brief Provides the member constant `value` to true if a given type is + * complete, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_complete: std::false_type {}; + +/*! @copydoc is_complete */ +template +struct is_complete>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_complete_v = is_complete::value; + +/** + * @brief Provides the member constant `value` to true if a given type is an + * iterator, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_iterator: std::false_type {}; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_iterator_category: std::false_type {}; + +template +struct has_iterator_category::iterator_category>>: std::true_type {}; + +} // namespace internal +/*! @endcond */ + +/*! @copydoc is_iterator */ +template +struct is_iterator>>>> + : internal::has_iterator_category {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_iterator_v = is_iterator::value; + +/** + * @brief Provides the member constant `value` to true if a given type is both + * an empty and non-final class, false otherwise. + * @tparam Type The type to test + */ +template +struct is_ebco_eligible + : std::bool_constant && !std::is_final_v> {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_ebco_eligible_v = is_ebco_eligible::value; + +/** + * @brief Provides the member constant `value` to true if `Type::is_transparent` + * is valid and denotes a type, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_transparent: std::false_type {}; + +/*! @copydoc is_transparent */ +template +struct is_transparent>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_transparent_v = is_transparent::value; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_tuple_size_value: std::false_type {}; + +template +struct has_tuple_size_value::value)>>: std::true_type {}; + +template +struct has_value_type: std::false_type {}; + +template +struct has_value_type>: std::true_type {}; + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable(); + +template +[[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence) { + return (dispatch_is_equality_comparable>() && ...); +} + +template +[[nodiscard]] constexpr bool maybe_equality_comparable(char) { + return false; +} + +template +[[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval() == std::declval()) { + return true; +} + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable() { + // NOLINTBEGIN(modernize-use-transparent-functors) + if constexpr(std::is_array_v) { + return false; + } else if constexpr(is_complete_v>>) { + if constexpr(has_tuple_size_value::value) { + return maybe_equality_comparable(0) && unpack_maybe_equality_comparable(std::make_index_sequence::value>{}); + } else { + return maybe_equality_comparable(0); + } + } else if constexpr(has_value_type::value) { + if constexpr(is_iterator_v || std::is_same_v || dispatch_is_equality_comparable()) { + return maybe_equality_comparable(0); + } else { + return false; + } + } else { + return maybe_equality_comparable(0); + } + // NOLINTEND(modernize-use-transparent-functors) +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Provides the member constant `value` to true if a given type is + * equality comparable, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_equality_comparable: std::bool_constant()> {}; + +/*! @copydoc is_equality_comparable */ +template +struct is_equality_comparable: is_equality_comparable {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_equality_comparable_v = is_equality_comparable::value; + +/** + * @brief Transcribes the constness of a type to another type. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = std::remove_const_t; +}; + +/*! @copydoc constness_as */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = const To; +}; + +/** + * @brief Alias template to facilitate the transcription of the constness. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +using constness_as_t = typename constness_as::type; + +/** + * @brief Extracts the class of a non-static member object or function. + * @tparam Member A pointer to a non-static member object or function. + */ +template +class member_class { + static_assert(std::is_member_pointer_v, "Invalid pointer type to non-static member object or function"); + + template + static Class *clazz(Ret (Class::*)(Args...)); + + template + static Class *clazz(Ret (Class::*)(Args...) const); + + template + static Class *clazz(Type Class::*); + +public: + /*! @brief The class of the given non-static member object or function. */ + using type = std::remove_pointer_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Member A pointer to a non-static member object or function. + */ +template +using member_class_t = typename member_class::type; + +/** + * @brief Extracts the n-th argument of a _callable_ type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid _callable_ type. + */ +template +class nth_argument { + template + static constexpr type_list pick_up(Ret (*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...) const); + + template + static constexpr type_list pick_up(Type Class ::*); + + template + static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&); + +public: + /*! @brief N-th argument of the _callable_ type. */ + using type = type_list_element_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid function, member function or data member type. + */ +template +using nth_argument_t = typename nth_argument::type; + +} // namespace entt + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::type_list_element> {}; + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::value_list_element> {}; + +#endif + +// #include "fwd.hpp" +#ifndef ENTT_CONTAINER_FWD_HPP +#define ENTT_CONTAINER_FWD_HPP + +#include +#include +#include +#include + +namespace entt { + +template< + typename Key, + typename Type, + typename = std::hash, + typename = std::equal_to<>, + typename = std::allocator>> +class dense_map; + +template< + typename Type, + typename = std::hash, + typename = std::equal_to<>, + typename = std::allocator> +class dense_set; + +template +class basic_table; + +/** + * @brief Alias declaration for the most common use case. + * @tparam Type Element types. + */ +template +using table = basic_table...>; + +} // namespace entt + +#endif + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +static constexpr std::size_t dense_map_placeholder_position = (std::numeric_limits::max)(); + +template +struct dense_map_node final { + using value_type = std::pair; + + template + dense_map_node(const std::size_t pos, Args &&...args) + : next{pos}, + element{std::forward(args)...} {} + + template + dense_map_node(std::allocator_arg_t, const Allocator &allocator, const std::size_t pos, Args &&...args) + : next{pos}, + element{entt::make_obj_using_allocator(allocator, std::forward(args)...)} {} + + template + dense_map_node(std::allocator_arg_t, const Allocator &allocator, const dense_map_node &other) + : next{other.next}, + element{entt::make_obj_using_allocator(allocator, other.element)} {} + + template + dense_map_node(std::allocator_arg_t, const Allocator &allocator, dense_map_node &&other) + : next{other.next}, + element{entt::make_obj_using_allocator(allocator, std::move(other.element))} {} + + std::size_t next; + value_type element; +}; + +template +class dense_map_iterator final { + template + friend class dense_map_iterator; + + using first_type = decltype(std::as_const(std::declval()->element.first)); + using second_type = decltype((std::declval()->element.second)); + +public: + using value_type = std::pair; + using pointer = input_iterator_pointer; + using reference = value_type; + using difference_type = std::ptrdiff_t; + using iterator_category = std::input_iterator_tag; + using iterator_concept = std::random_access_iterator_tag; + + constexpr dense_map_iterator() noexcept + : it{} {} + + constexpr dense_map_iterator(const It iter) noexcept + : it{iter} {} + + template && std::is_constructible_v>> + constexpr dense_map_iterator(const dense_map_iterator &other) noexcept + : it{other.it} {} + + constexpr dense_map_iterator &operator++() noexcept { + return ++it, *this; + } + + constexpr dense_map_iterator operator++(int) noexcept { + const dense_map_iterator orig = *this; + return ++(*this), orig; + } + + constexpr dense_map_iterator &operator--() noexcept { + return --it, *this; + } + + constexpr dense_map_iterator operator--(int) noexcept { + const dense_map_iterator orig = *this; + return operator--(), orig; + } + + constexpr dense_map_iterator &operator+=(const difference_type value) noexcept { + it += value; + return *this; + } + + constexpr dense_map_iterator operator+(const difference_type value) const noexcept { + dense_map_iterator copy = *this; + return (copy += value); + } + + constexpr dense_map_iterator &operator-=(const difference_type value) noexcept { + return (*this += -value); + } + + constexpr dense_map_iterator operator-(const difference_type value) const noexcept { + return (*this + -value); + } + + [[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept { + return {it[value].element.first, it[value].element.second}; + } + + [[nodiscard]] constexpr pointer operator->() const noexcept { + return operator*(); + } + + [[nodiscard]] constexpr reference operator*() const noexcept { + return operator[](0); + } + + template + friend constexpr std::ptrdiff_t operator-(const dense_map_iterator &, const dense_map_iterator &) noexcept; + + template + friend constexpr bool operator==(const dense_map_iterator &, const dense_map_iterator &) noexcept; + + template + friend constexpr bool operator<(const dense_map_iterator &, const dense_map_iterator &) noexcept; + +private: + It it; +}; + +template +[[nodiscard]] constexpr std::ptrdiff_t operator-(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return lhs.it - rhs.it; +} + +template +[[nodiscard]] constexpr bool operator==(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return lhs.it == rhs.it; +} + +template +[[nodiscard]] constexpr bool operator!=(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +template +[[nodiscard]] constexpr bool operator<(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return lhs.it < rhs.it; +} + +template +[[nodiscard]] constexpr bool operator>(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return rhs < lhs; +} + +template +[[nodiscard]] constexpr bool operator<=(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return !(lhs > rhs); +} + +template +[[nodiscard]] constexpr bool operator>=(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return !(lhs < rhs); +} + +template +class dense_map_local_iterator final { + template + friend class dense_map_local_iterator; + + using first_type = decltype(std::as_const(std::declval()->element.first)); + using second_type = decltype((std::declval()->element.second)); + +public: + using value_type = std::pair; + using pointer = input_iterator_pointer; + using reference = value_type; + using difference_type = std::ptrdiff_t; + using iterator_category = std::input_iterator_tag; + using iterator_concept = std::forward_iterator_tag; + + constexpr dense_map_local_iterator() noexcept = default; + + constexpr dense_map_local_iterator(It iter, const std::size_t pos) noexcept + : it{iter}, + offset{pos} {} + + template && std::is_constructible_v>> + constexpr dense_map_local_iterator(const dense_map_local_iterator &other) noexcept + : it{other.it}, + offset{other.offset} {} + + constexpr dense_map_local_iterator &operator++() noexcept { + return (offset = it[static_cast(offset)].next), *this; + } + + constexpr dense_map_local_iterator operator++(int) noexcept { + const dense_map_local_iterator orig = *this; + return ++(*this), orig; + } + + [[nodiscard]] constexpr pointer operator->() const noexcept { + return operator*(); + } + + [[nodiscard]] constexpr reference operator*() const noexcept { + const auto idx = static_cast(offset); + return {it[idx].element.first, it[idx].element.second}; + } + + [[nodiscard]] constexpr std::size_t index() const noexcept { + return offset; + } + +private: + It it{}; + std::size_t offset{dense_map_placeholder_position}; +}; + +template +[[nodiscard]] constexpr bool operator==(const dense_map_local_iterator &lhs, const dense_map_local_iterator &rhs) noexcept { + return lhs.index() == rhs.index(); +} + +template +[[nodiscard]] constexpr bool operator!=(const dense_map_local_iterator &lhs, const dense_map_local_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Associative container for key-value pairs with unique keys. + * + * Internally, elements are organized into buckets. Which bucket an element is + * placed into depends entirely on the hash of its key. Keys with the same hash + * code appear in the same bucket. + * + * @tparam Key Key type of the associative container. + * @tparam Type Mapped type of the associative container. + * @tparam Hash Type of function to use to hash the keys. + * @tparam KeyEqual Type of function to use to compare the keys for equality. + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +class dense_map { + static constexpr float default_threshold = 0.875f; + static constexpr std::size_t minimum_capacity = 8u; + static constexpr std::size_t placeholder_position = internal::dense_map_placeholder_position; + + using node_type = internal::dense_map_node; + using alloc_traits = std::allocator_traits; + static_assert(std::is_same_v>, "Invalid value type"); + using sparse_container_type = std::vector>; + using packed_container_type = std::vector>; + + template + [[nodiscard]] std::size_t key_to_bucket(const Other &key) const noexcept { + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay) + return fast_mod(static_cast(sparse.second()(key)), bucket_count()); + } + + template + [[nodiscard]] auto constrained_find(const Other &key, const std::size_t bucket) { + for(auto offset = sparse.first()[bucket]; offset != placeholder_position; offset = packed.first()[offset].next) { + if(packed.second()(packed.first()[offset].element.first, key)) { + return begin() + static_cast(offset); + } + } + + return end(); + } + + template + [[nodiscard]] auto constrained_find(const Other &key, const std::size_t bucket) const { + for(auto offset = sparse.first()[bucket]; offset != placeholder_position; offset = packed.first()[offset].next) { + if(packed.second()(packed.first()[offset].element.first, key)) { + return cbegin() + static_cast(offset); + } + } + + return cend(); + } + + template + [[nodiscard]] auto insert_or_do_nothing(Other &&key, Args &&...args) { + const auto index = key_to_bucket(key); + + if(auto it = constrained_find(key, index); it != end()) { + return std::make_pair(it, false); + } + + packed.first().emplace_back(sparse.first()[index], std::piecewise_construct, std::forward_as_tuple(std::forward(key)), std::forward_as_tuple(std::forward(args)...)); + sparse.first()[index] = packed.first().size() - 1u; + rehash_if_required(); + + return std::make_pair(--end(), true); + } + + template + [[nodiscard]] auto insert_or_overwrite(Other &&key, Arg &&value) { + const auto index = key_to_bucket(key); + + if(auto it = constrained_find(key, index); it != end()) { + it->second = std::forward(value); + return std::make_pair(it, false); + } + + packed.first().emplace_back(sparse.first()[index], std::forward(key), std::forward(value)); + sparse.first()[index] = packed.first().size() - 1u; + rehash_if_required(); + + return std::make_pair(--end(), true); + } + + void move_and_pop(const std::size_t pos) { + if(const auto last = size() - 1u; pos != last) { + size_type *curr = &sparse.first()[key_to_bucket(packed.first().back().element.first)]; + packed.first()[pos] = std::move(packed.first().back()); + for(; *curr != last; curr = &packed.first()[*curr].next) {} + *curr = pos; + } + + packed.first().pop_back(); + } + + void rehash_if_required() { + if(const auto bc = bucket_count(); size() > static_cast(static_cast(bc) * max_load_factor())) { + rehash(bc * 2u); + } + } + +public: + /*! @brief Allocator type. */ + using allocator_type = Allocator; + /*! @brief Key type of the container. */ + using key_type = Key; + /*! @brief Mapped type of the container. */ + using mapped_type = Type; + /*! @brief Key-value type of the container. */ + using value_type = std::pair; + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + /*! @brief Signed integer type. */ + using difference_type = std::ptrdiff_t; + /*! @brief Type of function to use to hash the keys. */ + using hasher = Hash; + /*! @brief Type of function to use to compare the keys for equality. */ + using key_equal = KeyEqual; + /*! @brief Input iterator type. */ + using iterator = internal::dense_map_iterator; + /*! @brief Constant input iterator type. */ + using const_iterator = internal::dense_map_iterator; + /*! @brief Input iterator type. */ + using local_iterator = internal::dense_map_local_iterator; + /*! @brief Constant input iterator type. */ + using const_local_iterator = internal::dense_map_local_iterator; + + /*! @brief Default constructor. */ + dense_map() + : dense_map{minimum_capacity} {} + + /** + * @brief Constructs an empty container with a given allocator. + * @param allocator The allocator to use. + */ + explicit dense_map(const allocator_type &allocator) + : dense_map{minimum_capacity, hasher{}, key_equal{}, allocator} {} + + /** + * @brief Constructs an empty container with a given allocator and user + * supplied minimal number of buckets. + * @param cnt Minimal number of buckets. + * @param allocator The allocator to use. + */ + dense_map(const size_type cnt, const allocator_type &allocator) + : dense_map{cnt, hasher{}, key_equal{}, allocator} {} + + /** + * @brief Constructs an empty container with a given allocator, hash + * function and user supplied minimal number of buckets. + * @param cnt Minimal number of buckets. + * @param hash Hash function to use. + * @param allocator The allocator to use. + */ + dense_map(const size_type cnt, const hasher &hash, const allocator_type &allocator) + : dense_map{cnt, hash, key_equal{}, allocator} {} + + /** + * @brief Constructs an empty container with a given allocator, hash + * function, compare function and user supplied minimal number of buckets. + * @param cnt Minimal number of buckets. + * @param hash Hash function to use. + * @param equal Compare function to use. + * @param allocator The allocator to use. + */ + explicit dense_map(const size_type cnt, const hasher &hash = hasher{}, const key_equal &equal = key_equal{}, const allocator_type &allocator = allocator_type{}) + : sparse{allocator, hash}, + packed{allocator, equal} { + rehash(cnt); + } + + /*! @brief Default copy constructor. */ + dense_map(const dense_map &) = default; + + /** + * @brief Allocator-extended copy constructor. + * @param other The instance to copy from. + * @param allocator The allocator to use. + */ + dense_map(const dense_map &other, const allocator_type &allocator) + : sparse{std::piecewise_construct, std::forward_as_tuple(other.sparse.first(), allocator), std::forward_as_tuple(other.sparse.second())}, + packed{std::piecewise_construct, std::forward_as_tuple(other.packed.first(), allocator), std::forward_as_tuple(other.packed.second())}, + threshold{other.threshold} {} + + /*! @brief Default move constructor. */ + dense_map(dense_map &&) noexcept = default; + + /** + * @brief Allocator-extended move constructor. + * @param other The instance to move from. + * @param allocator The allocator to use. + */ + dense_map(dense_map &&other, const allocator_type &allocator) + : sparse{std::piecewise_construct, std::forward_as_tuple(std::move(other.sparse.first()), allocator), std::forward_as_tuple(std::move(other.sparse.second()))}, + packed{std::piecewise_construct, std::forward_as_tuple(std::move(other.packed.first()), allocator), std::forward_as_tuple(std::move(other.packed.second()))}, + threshold{other.threshold} {} + + /*! @brief Default destructor. */ + ~dense_map() = default; + + /** + * @brief Default copy assignment operator. + * @return This container. + */ + dense_map &operator=(const dense_map &) = default; + + /** + * @brief Default move assignment operator. + * @return This container. + */ + dense_map &operator=(dense_map &&) noexcept = default; + + /** + * @brief Exchanges the contents with those of a given container. + * @param other Container to exchange the content with. + */ + void swap(dense_map &other) noexcept { + using std::swap; + swap(sparse, other.sparse); + swap(packed, other.packed); + swap(threshold, other.threshold); + } + + /** + * @brief Returns the associated allocator. + * @return The associated allocator. + */ + [[nodiscard]] constexpr allocator_type get_allocator() const noexcept { + return sparse.first().get_allocator(); + } + + /** + * @brief Returns an iterator to the beginning. + * + * If the array is empty, the returned iterator will be equal to `end()`. + * + * @return An iterator to the first instance of the internal array. + */ + [[nodiscard]] const_iterator cbegin() const noexcept { + return packed.first().begin(); + } + + /*! @copydoc cbegin */ + [[nodiscard]] const_iterator begin() const noexcept { + return cbegin(); + } + + /*! @copydoc begin */ + [[nodiscard]] iterator begin() noexcept { + return packed.first().begin(); + } + + /** + * @brief Returns an iterator to the end. + * @return An iterator to the element following the last instance of the + * internal array. + */ + [[nodiscard]] const_iterator cend() const noexcept { + return packed.first().end(); + } + + /*! @copydoc cend */ + [[nodiscard]] const_iterator end() const noexcept { + return cend(); + } + + /*! @copydoc end */ + [[nodiscard]] iterator end() noexcept { + return packed.first().end(); + } + + /** + * @brief Checks whether a container is empty. + * @return True if the container is empty, false otherwise. + */ + [[nodiscard]] bool empty() const noexcept { + return packed.first().empty(); + } + + /** + * @brief Returns the number of elements in a container. + * @return Number of elements in a container. + */ + [[nodiscard]] size_type size() const noexcept { + return packed.first().size(); + } + + /** + * @brief Returns the maximum possible number of elements. + * @return Maximum possible number of elements. + */ + [[nodiscard]] size_type max_size() const noexcept { + return packed.first().max_size(); + } + + /*! @brief Clears the container. */ + void clear() noexcept { + sparse.first().clear(); + packed.first().clear(); + rehash(0u); + } + + /** + * @brief Inserts an element into the container, if the key does not exist. + * @param value A key-value pair eventually convertible to the value type. + * @return A pair consisting of an iterator to the inserted element (or to + * the element that prevented the insertion) and a bool denoting whether the + * insertion took place. + */ + std::pair insert(const value_type &value) { + return insert_or_do_nothing(value.first, value.second); + } + + /*! @copydoc insert */ + std::pair insert(value_type &&value) { + return insert_or_do_nothing(std::move(value.first), std::move(value.second)); + } + + /** + * @copydoc insert + * @tparam Arg Type of the key-value pair to insert into the container. + */ + template + std::enable_if_t, std::pair> + insert(Arg &&value) { + return insert_or_do_nothing(std::forward(value).first, std::forward(value).second); + } + + /** + * @brief Inserts elements into the container, if their keys do not exist. + * @tparam It Type of input iterator. + * @param first An iterator to the first element of the range of elements. + * @param last An iterator past the last element of the range of elements. + */ + template + void insert(It first, It last) { + for(; first != last; ++first) { + insert(*first); + } + } + + /** + * @brief Inserts an element into the container or assigns to the current + * element if the key already exists. + * @tparam Arg Type of the value to insert or assign. + * @param key A key used both to look up and to insert if not found. + * @param value A value to insert or assign. + * @return A pair consisting of an iterator to the element and a bool + * denoting whether the insertion took place. + */ + template + std::pair insert_or_assign(const key_type &key, Arg &&value) { + return insert_or_overwrite(key, std::forward(value)); + } + + /*! @copydoc insert_or_assign */ + template + std::pair insert_or_assign(key_type &&key, Arg &&value) { + return insert_or_overwrite(std::move(key), std::forward(value)); + } + + /** + * @brief Constructs an element in-place, if the key does not exist. + * + * The element is also constructed when the container already has the key, + * in which case the newly constructed object is destroyed immediately. + * + * @tparam Args Types of arguments to forward to the constructor of the + * element. + * @param args Arguments to forward to the constructor of the element. + * @return A pair consisting of an iterator to the inserted element (or to + * the element that prevented the insertion) and a bool denoting whether the + * insertion took place. + */ + template + std::pair emplace([[maybe_unused]] Args &&...args) { + if constexpr(sizeof...(Args) == 0u) { + return insert_or_do_nothing(key_type{}); + } else if constexpr(sizeof...(Args) == 1u) { + return insert_or_do_nothing(std::forward(args).first..., std::forward(args).second...); + } else if constexpr(sizeof...(Args) == 2u) { + return insert_or_do_nothing(std::forward(args)...); + } else { + auto &node = packed.first().emplace_back(packed.first().size(), std::forward(args)...); + const auto index = key_to_bucket(node.element.first); + + if(auto it = constrained_find(node.element.first, index); it != end()) { + packed.first().pop_back(); + return std::make_pair(it, false); + } + + std::swap(node.next, sparse.first()[index]); + rehash_if_required(); + + return std::make_pair(--end(), true); + } + } + + /** + * @brief Inserts in-place if the key does not exist, does nothing if the + * key exists. + * @tparam Args Types of arguments to forward to the constructor of the + * element. + * @param key A key used both to look up and to insert if not found. + * @param args Arguments to forward to the constructor of the element. + * @return A pair consisting of an iterator to the inserted element (or to + * the element that prevented the insertion) and a bool denoting whether the + * insertion took place. + */ + template + std::pair try_emplace(const key_type &key, Args &&...args) { + return insert_or_do_nothing(key, std::forward(args)...); + } + + /*! @copydoc try_emplace */ + template + std::pair try_emplace(key_type &&key, Args &&...args) { + return insert_or_do_nothing(std::move(key), std::forward(args)...); + } + + /** + * @brief Removes an element from a given position. + * @param pos An iterator to the element to remove. + * @return An iterator following the removed element. + */ + iterator erase(const_iterator pos) { + const auto diff = pos - cbegin(); + erase(pos->first); + return begin() + diff; + } + + /** + * @brief Removes the given elements from a container. + * @param first An iterator to the first element of the range of elements. + * @param last An iterator past the last element of the range of elements. + * @return An iterator following the last removed element. + */ + iterator erase(const_iterator first, const_iterator last) { + const auto dist = first - cbegin(); + + for(auto from = last - cbegin(); from != dist; --from) { + erase(packed.first()[static_cast(from) - 1u].element.first); + } + + return (begin() + dist); + } + + /** + * @brief Removes the element associated with a given key. + * @param key A key value of an element to remove. + * @return Number of elements removed (either 0 or 1). + */ + size_type erase(const key_type &key) { + for(size_type *curr = &sparse.first()[key_to_bucket(key)]; *curr != placeholder_position; curr = &packed.first()[*curr].next) { + if(packed.second()(packed.first()[*curr].element.first, key)) { + const auto index = *curr; + *curr = packed.first()[*curr].next; + move_and_pop(index); + return 1u; + } + } + + return 0u; + } + + /** + * @brief Accesses a given element with bounds checking. + * @param key A key of an element to find. + * @return A reference to the mapped value of the requested element. + */ + [[nodiscard]] mapped_type &at(const key_type &key) { + auto it = find(key); + ENTT_ASSERT(it != end(), "Invalid key"); + return it->second; + } + + /*! @copydoc at */ + [[nodiscard]] const mapped_type &at(const key_type &key) const { + auto it = find(key); + ENTT_ASSERT(it != cend(), "Invalid key"); + return it->second; + } + + /** + * @brief Accesses a given element with bounds checking. + * @tparam Other Type of the key of an element to find. + * @param key A key of an element to find. + * @return A reference to the mapped value of the requested element. + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + at(const Other &key) const { + auto it = find(key); + ENTT_ASSERT(it != cend(), "Invalid key"); + return it->second; + } + + /*! @copydoc at */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + at(const Other &key) { + auto it = find(key); + ENTT_ASSERT(it != end(), "Invalid key"); + return it->second; + } + + /** + * @brief Accesses or inserts a given element. + * @param key A key of an element to find or insert. + * @return A reference to the mapped value of the requested element. + */ + [[nodiscard]] mapped_type &operator[](const key_type &key) { + return insert_or_do_nothing(key).first->second; + } + + /** + * @brief Accesses or inserts a given element. + * @param key A key of an element to find or insert. + * @return A reference to the mapped value of the requested element. + */ + [[nodiscard]] mapped_type &operator[](key_type &&key) { + return insert_or_do_nothing(std::move(key)).first->second; + } + + /** + * @brief Returns the number of elements matching a key (either 1 or 0). + * @param key Key value of an element to search for. + * @return Number of elements matching the key (either 1 or 0). + */ + [[nodiscard]] size_type count(const key_type &key) const { + return find(key) != end(); + } + + /** + * @brief Returns the number of elements matching a key (either 1 or 0). + * @tparam Other Type of the key value of an element to search for. + * @param key Key value of an element to search for. + * @return Number of elements matching the key (either 1 or 0). + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + count(const Other &key) const { + return find(key) != end(); + } + + /** + * @brief Finds an element with a given key. + * @param key Key value of an element to search for. + * @return An iterator to an element with the given key. If no such element + * is found, a past-the-end iterator is returned. + */ + [[nodiscard]] iterator find(const key_type &key) { + return constrained_find(key, key_to_bucket(key)); + } + + /*! @copydoc find */ + [[nodiscard]] const_iterator find(const key_type &key) const { + return constrained_find(key, key_to_bucket(key)); + } + + /** + * @brief Finds an element with a key that compares _equivalent_ to a given + * key. + * @tparam Other Type of the key value of an element to search for. + * @param key Key value of an element to search for. + * @return An iterator to an element with the given key. If no such element + * is found, a past-the-end iterator is returned. + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + find(const Other &key) { + return constrained_find(key, key_to_bucket(key)); + } + + /*! @copydoc find */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + find(const Other &key) const { + return constrained_find(key, key_to_bucket(key)); + } + + /** + * @brief Returns a range containing all elements with a given key. + * @param key Key value of an element to search for. + * @return A pair of iterators pointing to the first element and past the + * last element of the range. + */ + [[nodiscard]] std::pair equal_range(const key_type &key) { + const auto it = find(key); + return {it, it + !(it == end())}; + } + + /*! @copydoc equal_range */ + [[nodiscard]] std::pair equal_range(const key_type &key) const { + const auto it = find(key); + return {it, it + !(it == cend())}; + } + + /** + * @brief Returns a range containing all elements that compare _equivalent_ + * to a given key. + * @tparam Other Type of an element to search for. + * @param key Key value of an element to search for. + * @return A pair of iterators pointing to the first element and past the + * last element of the range. + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t>> + equal_range(const Other &key) { + const auto it = find(key); + return {it, it + !(it == end())}; + } + + /*! @copydoc equal_range */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t>> + equal_range(const Other &key) const { + const auto it = find(key); + return {it, it + !(it == cend())}; + } + + /** + * @brief Checks if the container contains an element with a given key. + * @param key Key value of an element to search for. + * @return True if there is such an element, false otherwise. + */ + [[nodiscard]] bool contains(const key_type &key) const { + return (find(key) != cend()); + } + + /** + * @brief Checks if the container contains an element with a key that + * compares _equivalent_ to a given value. + * @tparam Other Type of the key value of an element to search for. + * @param key Key value of an element to search for. + * @return True if there is such an element, false otherwise. + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + contains(const Other &key) const { + return (find(key) != cend()); + } + + /** + * @brief Returns an iterator to the beginning of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the beginning of the given bucket. + */ + [[nodiscard]] const_local_iterator cbegin(const size_type index) const { + return {packed.first().begin(), sparse.first()[index]}; + } + + /** + * @brief Returns an iterator to the beginning of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the beginning of the given bucket. + */ + [[nodiscard]] const_local_iterator begin(const size_type index) const { + return cbegin(index); + } + + /** + * @brief Returns an iterator to the beginning of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the beginning of the given bucket. + */ + [[nodiscard]] local_iterator begin(const size_type index) { + return {packed.first().begin(), sparse.first()[index]}; + } + + /** + * @brief Returns an iterator to the end of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the end of the given bucket. + */ + [[nodiscard]] const_local_iterator cend([[maybe_unused]] const size_type index) const { + return {}; + } + + /** + * @brief Returns an iterator to the end of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the end of the given bucket. + */ + [[nodiscard]] const_local_iterator end(const size_type index) const { + return cend(index); + } + + /** + * @brief Returns an iterator to the end of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the end of the given bucket. + */ + [[nodiscard]] local_iterator end([[maybe_unused]] const size_type index) { + return {}; + } + + /** + * @brief Returns the number of buckets. + * @return The number of buckets. + */ + [[nodiscard]] size_type bucket_count() const { + return sparse.first().size(); + } + + /** + * @brief Returns the maximum number of buckets. + * @return The maximum number of buckets. + */ + [[nodiscard]] size_type max_bucket_count() const { + return sparse.first().max_size(); + } + + /** + * @brief Returns the number of elements in a given bucket. + * @param index The index of the bucket to examine. + * @return The number of elements in the given bucket. + */ + [[nodiscard]] size_type bucket_size(const size_type index) const { + return static_cast(std::distance(begin(index), end(index))); + } + + /** + * @brief Returns the bucket for a given key. + * @param key The value of the key to examine. + * @return The bucket for the given key. + */ + [[nodiscard]] size_type bucket(const key_type &key) const { + return key_to_bucket(key); + } + + /** + * @brief Returns the average number of elements per bucket. + * @return The average number of elements per bucket. + */ + [[nodiscard]] float load_factor() const { + return static_cast(size()) / static_cast(bucket_count()); + } + + /** + * @brief Returns the maximum average number of elements per bucket. + * @return The maximum average number of elements per bucket. + */ + [[nodiscard]] float max_load_factor() const { + return threshold; + } + + /** + * @brief Sets the desired maximum average number of elements per bucket. + * @param value A desired maximum average number of elements per bucket. + */ + void max_load_factor(const float value) { + ENTT_ASSERT(value > 0.f, "Invalid load factor"); + threshold = value; + rehash(0u); + } + + /** + * @brief Reserves at least the specified number of buckets and regenerates + * the hash table. + * @param cnt New number of buckets. + */ + void rehash(const size_type cnt) { + auto value = cnt > minimum_capacity ? cnt : minimum_capacity; + const auto cap = static_cast(static_cast(size()) / max_load_factor()); + value = value > cap ? value : cap; + + if(const auto sz = next_power_of_two(value); sz != bucket_count()) { + sparse.first().resize(sz); + + for(auto &&elem: sparse.first()) { + elem = placeholder_position; + } + + for(size_type pos{}, last = size(); pos < last; ++pos) { + const auto index = key_to_bucket(packed.first()[pos].element.first); + packed.first()[pos].next = std::exchange(sparse.first()[index], pos); + } + } + } + + /** + * @brief Reserves space for at least the specified number of elements and + * regenerates the hash table. + * @param cnt New number of elements. + */ + void reserve(const size_type cnt) { + packed.first().reserve(cnt); + rehash(static_cast(std::ceil(static_cast(cnt) / max_load_factor()))); + } + + /** + * @brief Returns the function used to hash the keys. + * @return The function used to hash the keys. + */ + [[nodiscard]] hasher hash_function() const { + return sparse.second(); + } + + /** + * @brief Returns the function used to compare keys for equality. + * @return The function used to compare keys for equality. + */ + [[nodiscard]] key_equal key_eq() const { + return packed.second(); + } + +private: + compressed_pair sparse; + compressed_pair packed; + float threshold{default_threshold}; +}; + +} // namespace entt + +/*! @cond TURN_OFF_DOXYGEN */ +namespace std { + +template +struct uses_allocator, Allocator> + : std::true_type {}; + +} // namespace std +/*! @endcond */ + +#endif + +// #include "../core/algorithm.hpp" + +// #include "../core/any.hpp" + +// #include "../core/fwd.hpp" + +// #include "../core/iterator.hpp" + +// #include "../core/memory.hpp" + +// #include "../core/type_info.hpp" + +// #include "../core/type_traits.hpp" + +// #include "../core/utility.hpp" + +// #include "entity.hpp" + +// #include "fwd.hpp" + +// #include "group.hpp" + +// #include "mixin.hpp" +#ifndef ENTT_ENTITY_MIXIN_HPP +#define ENTT_ENTITY_MIXIN_HPP + +#include +#include +// #include "../config/config.h" + +// #include "../core/any.hpp" + +// #include "../core/type_info.hpp" + +// #include "../signal/sigh.hpp" + +// #include "entity.hpp" + +// #include "fwd.hpp" + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_on_construct final: std::false_type {}; + +template +struct has_on_construct(), std::declval().create()))>> + : std::true_type {}; + +template +struct has_on_update final: std::false_type {}; + +template +struct has_on_update(), std::declval().create()))>> + : std::true_type {}; + +template +struct has_on_destroy final: std::false_type {}; + +template +struct has_on_destroy(), std::declval().create()))>> + : std::true_type {}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Mixin type used to add signal support to storage types. + * + * The function type of a listener is equivalent to: + * + * @code{.cpp} + * void(basic_registry &, entity_type); + * @endcode + * + * This applies to all signals made available. + * + * @tparam Type Underlying storage type. + * @tparam Registry Basic registry type. + */ +template +class basic_sigh_mixin final: public Type { + using underlying_type = Type; + using owner_type = Registry; + + using basic_registry_type = basic_registry; + using sigh_type = sigh; + using underlying_iterator = typename underlying_type::base_type::basic_iterator; + + static_assert(std::is_base_of_v, "Invalid registry type"); + + [[nodiscard]] auto &owner_or_assert() const noexcept { + ENTT_ASSERT(owner != nullptr, "Invalid pointer to registry"); + return static_cast(*owner); + } + +private: + void pop(underlying_iterator first, underlying_iterator last) final { + if(auto ® = owner_or_assert(); destruction.empty()) { + underlying_type::pop(first, last); + } else { + for(; first != last; ++first) { + const auto entt = *first; + destruction.publish(reg, entt); + const auto it = underlying_type::find(entt); + underlying_type::pop(it, it + 1u); + } + } + } + + void pop_all() final { + if(auto ® = owner_or_assert(); !destruction.empty()) { + if constexpr(std::is_same_v) { + for(typename underlying_type::size_type pos{}, last = underlying_type::free_list(); pos < last; ++pos) { + destruction.publish(reg, underlying_type::base_type::operator[](pos)); + } + } else { + for(auto entt: static_cast(*this)) { + if constexpr(underlying_type::storage_policy == deletion_policy::in_place) { + if(entt != tombstone) { + destruction.publish(reg, entt); + } + } else { + destruction.publish(reg, entt); + } + } + } + } + + underlying_type::pop_all(); + } + + underlying_iterator try_emplace(const typename underlying_type::entity_type entt, const bool force_back, const void *value) final { + const auto it = underlying_type::try_emplace(entt, force_back, value); + + if(auto ® = owner_or_assert(); it != underlying_type::base_type::end()) { + construction.publish(reg, *it); + } + + return it; + } + + void bind_any(any value) noexcept final { + owner = any_cast(&value); + + if constexpr(!std::is_same_v) { + if(owner == nullptr) { + owner = any_cast(&value); + } + } + + underlying_type::bind_any(std::move(value)); + } + +public: + /*! @brief Allocator type. */ + using allocator_type = typename underlying_type::allocator_type; + /*! @brief Underlying entity identifier. */ + using entity_type = typename underlying_type::entity_type; + /*! @brief Expected registry type. */ + using registry_type = owner_type; + + /*! @brief Default constructor. */ + basic_sigh_mixin() + : basic_sigh_mixin{allocator_type{}} {} + + /** + * @brief Constructs an empty storage with a given allocator. + * @param allocator The allocator to use. + */ + explicit basic_sigh_mixin(const allocator_type &allocator) + : underlying_type{allocator}, + owner{}, + construction{allocator}, + destruction{allocator}, + update{allocator} { + if constexpr(internal::has_on_construct::value) { + sink{construction}.template connect<&underlying_type::element_type::on_construct>(); + } + + if constexpr(internal::has_on_update::value) { + sink{update}.template connect<&underlying_type::element_type::on_update>(); + } + + if constexpr(internal::has_on_destroy::value) { + sink{destruction}.template connect<&underlying_type::element_type::on_destroy>(); + } + } + + /*! @brief Default copy constructor, deleted on purpose. */ + basic_sigh_mixin(const basic_sigh_mixin &) = delete; + + /** + * @brief Move constructor. + * @param other The instance to move from. + */ + basic_sigh_mixin(basic_sigh_mixin &&other) noexcept + : underlying_type{static_cast(other)}, + owner{other.owner}, + construction{std::move(other.construction)}, + destruction{std::move(other.destruction)}, + update{std::move(other.update)} {} + + /** + * @brief Allocator-extended move constructor. + * @param other The instance to move from. + * @param allocator The allocator to use. + */ + basic_sigh_mixin(basic_sigh_mixin &&other, const allocator_type &allocator) + : underlying_type{static_cast(other), allocator}, + owner{other.owner}, + construction{std::move(other.construction), allocator}, + destruction{std::move(other.destruction), allocator}, + update{std::move(other.update), allocator} {} + + /*! @brief Default destructor. */ + ~basic_sigh_mixin() override = default; + + /** + * @brief Default copy assignment operator, deleted on purpose. + * @return This mixin. + */ + basic_sigh_mixin &operator=(const basic_sigh_mixin &) = delete; + + /** + * @brief Move assignment operator. + * @param other The instance to move from. + * @return This mixin. + */ + basic_sigh_mixin &operator=(basic_sigh_mixin &&other) noexcept { + swap(other); + return *this; + } + + /** + * @brief Exchanges the contents with those of a given storage. + * @param other Storage to exchange the content with. + */ + void swap(basic_sigh_mixin &other) noexcept { + using std::swap; + swap(owner, other.owner); + swap(construction, other.construction); + swap(destruction, other.destruction); + swap(update, other.update); + underlying_type::swap(other); + } + + /** + * @brief Returns a sink object. + * + * The sink returned by this function can be used to receive notifications + * whenever a new instance is created and assigned to an entity.
+ * Listeners are invoked after the object has been assigned to the entity. + * + * @sa sink + * + * @return A temporary sink object. + */ + [[nodiscard]] auto on_construct() noexcept { + return sink{construction}; + } + + /** + * @brief Returns a sink object. + * + * The sink returned by this function can be used to receive notifications + * whenever an instance is explicitly updated.
+ * Listeners are invoked after the object has been updated. + * + * @sa sink + * + * @return A temporary sink object. + */ + [[nodiscard]] auto on_update() noexcept { + return sink{update}; + } + + /** + * @brief Returns a sink object. + * + * The sink returned by this function can be used to receive notifications + * whenever an instance is removed from an entity and thus destroyed.
+ * Listeners are invoked before the object has been removed from the entity. + * + * @sa sink + * + * @return A temporary sink object. + */ + [[nodiscard]] auto on_destroy() noexcept { + return sink{destruction}; + } + + /** + * @brief Checks if a mixin refers to a valid registry. + * @return True if the mixin refers to a valid registry, false otherwise. + */ + [[nodiscard]] explicit operator bool() const noexcept { + return (owner != nullptr); + } + + /** + * @brief Returns a pointer to the underlying registry, if any. + * @return A pointer to the underlying registry, if any. + */ + [[nodiscard]] const registry_type ®istry() const noexcept { + return owner_or_assert(); + } + + /*! @copydoc registry */ + [[nodiscard]] registry_type ®istry() noexcept { + return owner_or_assert(); + } + + /** + * @brief Creates a new identifier or recycles a destroyed one. + * @return A valid identifier. + */ + auto generate() { + const auto entt = underlying_type::generate(); + construction.publish(owner_or_assert(), entt); + return entt; + } + + /** + * @brief Creates a new identifier or recycles a destroyed one. + * @param hint Required identifier. + * @return A valid identifier. + */ + entity_type generate(const entity_type hint) { + const auto entt = underlying_type::generate(hint); + construction.publish(owner_or_assert(), entt); + return entt; + } + + /** + * @brief Assigns each element in a range an identifier. + * @tparam It Type of mutable forward iterator. + * @param first An iterator to the first element of the range to generate. + * @param last An iterator past the last element of the range to generate. + */ + template + void generate(It first, It last) { + underlying_type::generate(first, last); + + if(auto ® = owner_or_assert(); !construction.empty()) { + for(; first != last; ++first) { + construction.publish(reg, *first); + } + } + } + + /** + * @brief Assigns an entity to a storage and constructs its object. + * @tparam Args Types of arguments to forward to the underlying storage. + * @param entt A valid identifier. + * @param args Parameters to forward to the underlying storage. + * @return A reference to the newly created object. + */ + template + decltype(auto) emplace(const entity_type entt, Args &&...args) { + underlying_type::emplace(entt, std::forward(args)...); + construction.publish(owner_or_assert(), entt); + return this->get(entt); + } + + /** + * @brief Updates the instance assigned to a given entity in-place. + * @tparam Func Types of the function objects to invoke. + * @param entt A valid identifier. + * @param func Valid function objects. + * @return A reference to the patched instance. + */ + template + decltype(auto) patch(const entity_type entt, Func &&...func) { + underlying_type::patch(entt, std::forward(func)...); + update.publish(owner_or_assert(), entt); + return this->get(entt); + } + + /** + * @brief Assigns one or more entities to a storage and constructs their + * objects from a given instance. + * @tparam It Type of input iterator. + * @tparam Args Types of arguments to forward to the underlying storage. + * @param first An iterator to the first element of the range of entities. + * @param last An iterator past the last element of the range of entities. + * @param args Parameters to use to forward to the underlying storage. + */ + template + void insert(It first, It last, Args &&...args) { + auto from = underlying_type::size(); + underlying_type::insert(first, last, std::forward(args)...); + + if(auto ® = owner_or_assert(); !construction.empty()) { + // fine as long as insert passes force_back true to try_emplace + for(const auto to = underlying_type::size(); from != to; ++from) { + construction.publish(reg, underlying_type::operator[](from)); + } + } + } + +private: + basic_registry_type *owner; + sigh_type construction; + sigh_type destruction; + sigh_type update; +}; + +/** + * @brief Mixin type used to add _reactive_ support to storage types. + * @tparam Type Underlying storage type. + * @tparam Registry Basic registry type. + */ +template +class basic_reactive_mixin final: public Type { + using underlying_type = Type; + using owner_type = Registry; + + using alloc_traits = std::allocator_traits; + using basic_registry_type = basic_registry; + using container_type = std::vector>; + + static_assert(std::is_base_of_v, "Invalid registry type"); + + [[nodiscard]] auto &owner_or_assert() const noexcept { + ENTT_ASSERT(owner != nullptr, "Invalid pointer to registry"); + return static_cast(*owner); + } + + void emplace_element(const Registry &, typename underlying_type::entity_type entity) { + if(!underlying_type::contains(entity)) { + underlying_type::emplace(entity); + } + } + +private: + void bind_any(any value) noexcept final { + owner = any_cast(&value); + + if constexpr(!std::is_same_v) { + if(owner == nullptr) { + owner = any_cast(&value); + } + } + + underlying_type::bind_any(std::move(value)); + } + +public: + /*! @brief Allocator type. */ + using allocator_type = typename underlying_type::allocator_type; + /*! @brief Underlying entity identifier. */ + using entity_type = typename underlying_type::entity_type; + /*! @brief Expected registry type. */ + using registry_type = owner_type; + + /*! @brief Default constructor. */ + basic_reactive_mixin() + : basic_reactive_mixin{allocator_type{}} {} + + /** + * @brief Constructs an empty storage with a given allocator. + * @param allocator The allocator to use. + */ + explicit basic_reactive_mixin(const allocator_type &allocator) + : underlying_type{allocator}, + owner{}, + conn{allocator} { + } + + /*! @brief Default copy constructor, deleted on purpose. */ + basic_reactive_mixin(const basic_reactive_mixin &) = delete; + + /** + * @brief Move constructor. + * @param other The instance to move from. + */ + basic_reactive_mixin(basic_reactive_mixin &&other) noexcept + : underlying_type{static_cast(other)}, + owner{other.owner}, + conn{std::move(other.conn)} { + } + + /** + * @brief Allocator-extended move constructor. + * @param other The instance to move from. + * @param allocator The allocator to use. + */ + basic_reactive_mixin(basic_reactive_mixin &&other, const allocator_type &allocator) + : underlying_type{static_cast(other), allocator}, + owner{other.owner}, + conn{std::move(other.conn), allocator} { + } + + /*! @brief Default destructor. */ + ~basic_reactive_mixin() override = default; + + /** + * @brief Default copy assignment operator, deleted on purpose. + * @return This mixin. + */ + basic_reactive_mixin &operator=(const basic_reactive_mixin &) = delete; + + /** + * @brief Move assignment operator. + * @param other The instance to move from. + * @return This mixin. + */ + basic_reactive_mixin &operator=(basic_reactive_mixin &&other) noexcept { + underlying_type::swap(other); + return *this; + } + + /** + * @brief Makes storage _react_ to creation of objects of the given type. + * @tparam Clazz Type of element to _react_ to. + * @tparam Candidate Function to use to _react_ to the event. + * @param id Optional name used to map the storage within the registry. + * @return This mixin. + */ + template + basic_reactive_mixin &on_construct(const id_type id = type_hash::value()) { + auto curr = owner_or_assert().template storage(id).on_construct().template connect(*this); + conn.push_back(std::move(curr)); + return *this; + } + + /** + * @brief Makes storage _react_ to update of objects of the given type. + * @tparam Clazz Type of element to _react_ to. + * @tparam Candidate Function to use to _react_ to the event. + * @param id Optional name used to map the storage within the registry. + * @return This mixin. + */ + template + basic_reactive_mixin &on_update(const id_type id = type_hash::value()) { + auto curr = owner_or_assert().template storage(id).on_update().template connect(*this); + conn.push_back(std::move(curr)); + return *this; + } + + /** + * @brief Makes storage _react_ to destruction of objects of the given type. + * @tparam Clazz Type of element to _react_ to. + * @tparam Candidate Function to use to _react_ to the event. + * @param id Optional name used to map the storage within the registry. + * @return This mixin. + */ + template + basic_reactive_mixin &on_destroy(const id_type id = type_hash::value()) { + auto curr = owner_or_assert().template storage(id).on_destroy().template connect(*this); + conn.push_back(std::move(curr)); + return *this; + } + + /** + * @brief Checks if a mixin refers to a valid registry. + * @return True if the mixin refers to a valid registry, false otherwise. + */ + [[nodiscard]] explicit operator bool() const noexcept { + return (owner != nullptr); + } + + /** + * @brief Returns a pointer to the underlying registry, if any. + * @return A pointer to the underlying registry, if any. + */ + [[nodiscard]] const registry_type ®istry() const noexcept { + return owner_or_assert(); + } + + /*! @copydoc registry */ + [[nodiscard]] registry_type ®istry() noexcept { + return owner_or_assert(); + } + + /** + * @brief Returns a view that is filtered by the underlying storage. + * @tparam Get Types of elements used to construct the view. + * @tparam Exclude Types of elements used to filter the view. + * @return A newly created view. + */ + template + [[nodiscard]] basic_view...>, exclude_t...>> + view(exclude_t = exclude_t{}) const { + const owner_type &parent = owner_or_assert(); + basic_view...>, exclude_t...>> elem{}; + [&elem](const auto *...curr) { ((curr ? elem.storage(*curr) : void()), ...); }(parent.template storage>()..., parent.template storage>()..., this); + return elem; + } + + /*! @copydoc view */ + template + [[nodiscard]] basic_view...>, exclude_t...>> + view(exclude_t = exclude_t{}) { + std::conditional_t<((std::is_const_v && ...) && (std::is_const_v && ...)), const owner_type, owner_type> &parent = owner_or_assert(); + return {*this, parent.template storage>()..., parent.template storage>()...}; + } + + /*! @brief Releases all connections to the underlying registry, if any. */ + void reset() { + for(auto &&curr: conn) { + curr.release(); + } + + conn.clear(); + } + +private: + basic_registry_type *owner; + container_type conn; +}; + +} // namespace entt + +#endif + +// #include "sparse_set.hpp" + +// #include "storage.hpp" + +// #include "view.hpp" + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +class registry_storage_iterator final { + template + friend class registry_storage_iterator; + + using mapped_type = std::remove_reference_t()->second)>; + +public: + using value_type = std::pair &>; + using pointer = input_iterator_pointer; + using reference = value_type; + using difference_type = std::ptrdiff_t; + using iterator_category = std::input_iterator_tag; + using iterator_concept = std::random_access_iterator_tag; + + constexpr registry_storage_iterator() noexcept + : it{} {} + + constexpr registry_storage_iterator(It iter) noexcept + : it{iter} {} + + template && std::is_constructible_v>> + constexpr registry_storage_iterator(const registry_storage_iterator &other) noexcept + : registry_storage_iterator{other.it} {} + + constexpr registry_storage_iterator &operator++() noexcept { + return ++it, *this; + } + + constexpr registry_storage_iterator operator++(int) noexcept { + const registry_storage_iterator orig = *this; + return ++(*this), orig; + } + + constexpr registry_storage_iterator &operator--() noexcept { + return --it, *this; + } + + constexpr registry_storage_iterator operator--(int) noexcept { + const registry_storage_iterator orig = *this; + return operator--(), orig; + } + + constexpr registry_storage_iterator &operator+=(const difference_type value) noexcept { + it += value; + return *this; + } + + constexpr registry_storage_iterator operator+(const difference_type value) const noexcept { + registry_storage_iterator copy = *this; + return (copy += value); + } + + constexpr registry_storage_iterator &operator-=(const difference_type value) noexcept { + return (*this += -value); + } + + constexpr registry_storage_iterator operator-(const difference_type value) const noexcept { + return (*this + -value); + } + + [[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept { + return {it[value].first, *it[value].second}; + } + + [[nodiscard]] constexpr reference operator*() const noexcept { + return operator[](0); + } + + [[nodiscard]] constexpr pointer operator->() const noexcept { + return operator*(); + } + + template + friend constexpr std::ptrdiff_t operator-(const registry_storage_iterator &, const registry_storage_iterator &) noexcept; + + template + friend constexpr bool operator==(const registry_storage_iterator &, const registry_storage_iterator &) noexcept; + + template + friend constexpr bool operator<(const registry_storage_iterator &, const registry_storage_iterator &) noexcept; + +private: + It it; +}; + +template +[[nodiscard]] constexpr std::ptrdiff_t operator-(const registry_storage_iterator &lhs, const registry_storage_iterator &rhs) noexcept { + return lhs.it - rhs.it; +} + +template +[[nodiscard]] constexpr bool operator==(const registry_storage_iterator &lhs, const registry_storage_iterator &rhs) noexcept { + return lhs.it == rhs.it; +} + +template +[[nodiscard]] constexpr bool operator!=(const registry_storage_iterator &lhs, const registry_storage_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +template +[[nodiscard]] constexpr bool operator<(const registry_storage_iterator &lhs, const registry_storage_iterator &rhs) noexcept { + return lhs.it < rhs.it; +} + +template +[[nodiscard]] constexpr bool operator>(const registry_storage_iterator &lhs, const registry_storage_iterator &rhs) noexcept { + return rhs < lhs; +} + +template +[[nodiscard]] constexpr bool operator<=(const registry_storage_iterator &lhs, const registry_storage_iterator &rhs) noexcept { + return !(lhs > rhs); +} + +template +[[nodiscard]] constexpr bool operator>=(const registry_storage_iterator &lhs, const registry_storage_iterator &rhs) noexcept { + return !(lhs < rhs); +} + +template +class registry_context { + using alloc_traits = std::allocator_traits; + using allocator_type = typename alloc_traits::template rebind_alloc>>; + +public: + explicit registry_context(const allocator_type &allocator) + : ctx{allocator} {} + + void clear() noexcept { + ctx.clear(); + } + + template + Type &emplace_as(const id_type id, Args &&...args) { + return any_cast(ctx.try_emplace(id, std::in_place_type, std::forward(args)...).first->second); + } + + template + Type &emplace(Args &&...args) { + return emplace_as(type_id().hash(), std::forward(args)...); + } + + template + Type &insert_or_assign(const id_type id, Type &&value) { + return any_cast> &>(ctx.insert_or_assign(id, std::forward(value)).first->second); + } + + template + Type &insert_or_assign(Type &&value) { + return insert_or_assign(type_id().hash(), std::forward(value)); + } + + template + bool erase(const id_type id = type_id().hash()) { + const auto it = ctx.find(id); + return it != ctx.end() && it->second.info() == type_id() ? (ctx.erase(it), true) : false; + } + + template + [[nodiscard]] const Type &get(const id_type id = type_id().hash()) const { + return any_cast(ctx.at(id)); + } + + template + [[nodiscard]] Type &get(const id_type id = type_id().hash()) { + return any_cast(ctx.at(id)); + } + + template + [[nodiscard]] const Type *find(const id_type id = type_id().hash()) const { + const auto it = ctx.find(id); + return it != ctx.cend() ? any_cast(&it->second) : nullptr; + } + + template + [[nodiscard]] Type *find(const id_type id = type_id().hash()) { + const auto it = ctx.find(id); + return it != ctx.end() ? any_cast(&it->second) : nullptr; + } + + template + [[nodiscard]] bool contains(const id_type id = type_id().hash()) const { + const auto it = ctx.find(id); + return it != ctx.cend() && it->second.info() == type_id(); + } + +private: + dense_map, identity, std::equal_to<>, allocator_type> ctx; +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Fast and reliable entity-component system. + * @tparam Entity A valid entity type. + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +class basic_registry { + using base_type = basic_sparse_set; + using alloc_traits = std::allocator_traits; + static_assert(std::is_same_v, "Invalid value type"); + // std::shared_ptr because of its type erased allocator which is useful here + using pool_container_type = dense_map, identity, std::equal_to<>, typename alloc_traits::template rebind_alloc>>>; + using group_container_type = dense_map, identity, std::equal_to<>, typename alloc_traits::template rebind_alloc>>>; + using traits_type = entt_traits; + + template + [[nodiscard]] auto &assure([[maybe_unused]] const id_type id = type_hash::value()) { + static_assert(std::is_same_v>, "Non-decayed types not allowed"); + + if constexpr(std::is_same_v) { + ENTT_ASSERT(id == type_hash::value(), "User entity storage not allowed"); + return entities; + } else { + using storage_type = storage_for_type; + + if(auto it = pools.find(id); it != pools.cend()) { + ENTT_ASSERT(it->second->info() == type_id(), "Unexpected type"); + return static_cast(*it->second); + } + + using alloc_type = typename storage_type::allocator_type; + typename pool_container_type::mapped_type cpool{}; + + if constexpr(std::is_void_v && !std::is_constructible_v) { + // std::allocator has no cross constructors (waiting for C++20) + cpool = std::allocate_shared(get_allocator(), alloc_type{}); + } else { + cpool = std::allocate_shared(get_allocator(), get_allocator()); + } + + pools.emplace(id, cpool); + cpool->bind(*this); + + return static_cast(*cpool); + } + } + + template + [[nodiscard]] const auto *assure([[maybe_unused]] const id_type id = type_hash::value()) const { + static_assert(std::is_same_v>, "Non-decayed types not allowed"); + + if constexpr(std::is_same_v) { + ENTT_ASSERT(id == type_hash::value(), "User entity storage not allowed"); + return &entities; + } else { + if(const auto it = pools.find(id); it != pools.cend()) { + ENTT_ASSERT(it->second->info() == type_id(), "Unexpected type"); + return static_cast *>(it->second.get()); + } + + return static_cast *>(nullptr); + } + } + + void rebind() { + entities.bind(*this); + + for(auto &&curr: pools) { + curr.second->bind(*this); + } + } + +public: + /*! @brief Allocator type. */ + using allocator_type = Allocator; + /*! @brief Underlying entity identifier. */ + using entity_type = typename traits_type::value_type; + /*! @brief Underlying version type. */ + using version_type = typename traits_type::version_type; + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + /*! @brief Common type among all storage types. */ + using common_type = base_type; + /*! @brief Context type. */ + using context = internal::registry_context; + /*! @brief Iterable registry type. */ + using iterable = iterable_adaptor>; + /*! @brief Constant iterable registry type. */ + using const_iterable = iterable_adaptor>; + + /** + * @copybrief storage_for + * @tparam Type Storage value type, eventually const. + */ + template + using storage_for_type = typename storage_for>>::type; + + /*! @brief Default constructor. */ + basic_registry() + : basic_registry{allocator_type{}} {} + + /** + * @brief Constructs an empty registry with a given allocator. + * @param allocator The allocator to use. + */ + explicit basic_registry(const allocator_type &allocator) + : basic_registry{0u, allocator} {} + + /** + * @brief Allocates enough memory upon construction to store `count` pools. + * @param count The number of pools to allocate memory for. + * @param allocator The allocator to use. + */ + basic_registry(const size_type count, const allocator_type &allocator = allocator_type{}) + : vars{allocator}, + pools{allocator}, + groups{allocator}, + entities{allocator} { + pools.reserve(count); + rebind(); + } + + /*! @brief Default copy constructor, deleted on purpose. */ + basic_registry(const basic_registry &) = delete; + + /** + * @brief Move constructor. + * @param other The instance to move from. + */ + basic_registry(basic_registry &&other) noexcept + : vars{std::move(other.vars)}, + pools{std::move(other.pools)}, + groups{std::move(other.groups)}, + entities{std::move(other.entities)} { + rebind(); + } + + /*! @brief Default destructor. */ + ~basic_registry() = default; + + /** + * @brief Default copy assignment operator, deleted on purpose. + * @return This mixin. + */ + basic_registry &operator=(const basic_registry &) = delete; + + /** + * @brief Move assignment operator. + * @param other The instance to move from. + * @return This registry. + */ + basic_registry &operator=(basic_registry &&other) noexcept { + swap(other); + return *this; + } + + /** + * @brief Exchanges the contents with those of a given registry. + * @param other Registry to exchange the content with. + */ + void swap(basic_registry &other) noexcept { + using std::swap; + + swap(vars, other.vars); + swap(pools, other.pools); + swap(groups, other.groups); + swap(entities, other.entities); + + rebind(); + other.rebind(); + } + + /** + * @brief Returns the associated allocator. + * @return The associated allocator. + */ + [[nodiscard]] constexpr allocator_type get_allocator() const noexcept { + return entities.get_allocator(); + } + + /** + * @brief Returns an iterable object to use to _visit_ a registry. + * + * The iterable object returns a pair that contains the name and a reference + * to the current storage. + * + * @return An iterable object to use to _visit_ the registry. + */ + [[nodiscard]] iterable storage() noexcept { + return iterable{pools.begin(), pools.end()}; + } + + /*! @copydoc storage */ + [[nodiscard]] const_iterable storage() const noexcept { + return const_iterable{pools.cbegin(), pools.cend()}; + } + + /** + * @brief Finds the storage associated with a given name, if any. + * @param id Name used to map the storage within the registry. + * @return A pointer to the storage if it exists, a null pointer otherwise. + */ + [[nodiscard]] common_type *storage(const id_type id) { + return const_cast(std::as_const(*this).storage(id)); + } + + /** + * @brief Finds the storage associated with a given name, if any. + * @param id Name used to map the storage within the registry. + * @return A pointer to the storage if it exists, a null pointer otherwise. + */ + [[nodiscard]] const common_type *storage(const id_type id) const { + const auto it = pools.find(id); + return it == pools.cend() ? nullptr : it->second.get(); + } + + /** + * @brief Returns the storage for a given element type. + * @tparam Type Type of element of which to return the storage. + * @param id Optional name used to map the storage within the registry. + * @return The storage for the given element type. + */ + template + storage_for_type &storage(const id_type id = type_hash::value()) { + return assure>(id); + } + + /** + * @brief Returns the storage for a given element type, if any. + * @tparam Type Type of element of which to return the storage. + * @param id Optional name used to map the storage within the registry. + * @return The storage for the given element type. + */ + template + [[nodiscard]] const storage_for_type *storage(const id_type id = type_hash::value()) const { + return assure>(id); + } + + /** + * @brief Discards the storage associated with a given name, if any. + * @param id Name used to map the storage within the registry. + * @return True in case of success, false otherwise. + */ + bool reset(const id_type id) { + ENTT_ASSERT(id != type_hash::value(), "Cannot reset entity storage"); + return !(pools.erase(id) == 0u); + } + + /** + * @brief Checks if an identifier refers to a valid entity. + * @param entt An identifier, either valid or not. + * @return True if the identifier is valid, false otherwise. + */ + [[nodiscard]] bool valid(const entity_type entt) const { + return static_cast(entities.find(entt).index()) < entities.free_list(); + } + + /** + * @brief Returns the actual version for an identifier. + * @param entt A valid identifier. + * @return The version for the given identifier if valid, the tombstone + * version otherwise. + */ + [[nodiscard]] version_type current(const entity_type entt) const { + return entities.current(entt); + } + + /** + * @brief Creates a new entity or recycles a destroyed one. + * @return A valid identifier. + */ + [[nodiscard]] entity_type create() { + return entities.generate(); + } + + /** + * @copybrief create + * + * If the requested entity isn't in use, the suggested identifier is used. + * Otherwise, a new identifier is generated. + * + * @param hint Required identifier. + * @return A valid identifier. + */ + [[nodiscard]] entity_type create(const entity_type hint) { + return entities.generate(hint); + } + + /** + * @brief Assigns each element in a range an identifier. + * + * @sa create + * + * @tparam It Type of forward iterator. + * @param first An iterator to the first element of the range to generate. + * @param last An iterator past the last element of the range to generate. + */ + template + void create(It first, It last) { + entities.generate(std::move(first), std::move(last)); + } + + /** + * @brief Destroys an entity and releases its identifier. + * + * @warning + * Adding or removing elements to an entity that is being destroyed can + * result in undefined behavior. + * + * @param entt A valid identifier. + * @return The version of the recycled entity. + */ + version_type destroy(const entity_type entt) { + for(size_type pos = pools.size(); pos != 0u; --pos) { + pools.begin()[static_cast(pos - 1u)].second->remove(entt); + } + + entities.erase(entt); + return entities.current(entt); + } + + /** + * @brief Destroys an entity and releases its identifier. + * + * The suggested version or the valid version closest to the suggested one + * is used instead of the implicitly generated version. + * + * @sa destroy + * + * @param entt A valid identifier. + * @param version A desired version upon destruction. + * @return The version actually assigned to the entity. + */ + version_type destroy(const entity_type entt, const version_type version) { + destroy(entt); + const auto elem = traits_type::construct(traits_type::to_entity(entt), version); + return entities.bump((elem == tombstone) ? traits_type::next(elem) : elem); + } + + /** + * @brief Destroys all entities in a range and releases their identifiers. + * + * @sa destroy + * + * @tparam It Type of input iterator. + * @param first An iterator to the first element of the range of entities. + * @param last An iterator past the last element of the range of entities. + */ + template + void destroy(It first, It last) { + const auto to = entities.sort_as(first, last); + const auto from = entities.cend() - static_cast(entities.free_list()); + + for(auto &&curr: pools) { + curr.second->remove(from, to); + } + + entities.erase(from, to); + } + + /** + * @brief Assigns the given element to an entity. + * + * The element must have a proper constructor or be of aggregate type. + * + * @warning + * Attempting to assign an element to an entity that already owns it results + * in undefined behavior. + * + * @tparam Type Type of element to create. + * @tparam Args Types of arguments to use to construct the element. + * @param entt A valid identifier. + * @param args Parameters to use to initialize the element. + * @return A reference to the newly created element. + */ + template + decltype(auto) emplace(const entity_type entt, Args &&...args) { + ENTT_ASSERT(valid(entt), "Invalid entity"); + return assure().emplace(entt, std::forward(args)...); + } + + /** + * @brief Assigns each entity in a range the given element. + * + * @sa emplace + * + * @tparam Type Type of element to create. + * @tparam It Type of input iterator. + * @param first An iterator to the first element of the range of entities. + * @param last An iterator past the last element of the range of entities. + */ + template + void insert(It first, It last) { + ENTT_ASSERT(std::all_of(first, last, [this](const auto entt) { return valid(entt); }), "Invalid entity"); + assure().insert(std::move(first), std::move(last)); + } + + /** + * @brief Assigns each entity in a range the given element. + * + * @sa emplace + * + * @tparam Type Type of element to create. + * @tparam It Type of input iterator. + * @param first An iterator to the first element of the range of entities. + * @param last An iterator past the last element of the range of entities. + * @param value An instance of the element to assign. + */ + template + void insert(It first, It last, const Type &value) { + ENTT_ASSERT(std::all_of(first, last, [this](const auto entt) { return valid(entt); }), "Invalid entity"); + assure().insert(std::move(first), std::move(last), value); + } + + /** + * @brief Assigns each entity in a range the given elements. + * + * @sa emplace + * + * @tparam Type Type of element to create. + * @tparam EIt Type of input iterator. + * @tparam CIt Type of input iterator. + * @param first An iterator to the first element of the range of entities. + * @param last An iterator past the last element of the range of entities. + * @param from An iterator to the first element of the range of elements. + */ + template::value_type, Type>>> + void insert(EIt first, EIt last, CIt from) { + ENTT_ASSERT(std::all_of(first, last, [this](const auto entt) { return valid(entt); }), "Invalid entity"); + assure().insert(first, last, from); + } + + /** + * @brief Assigns or replaces the given element for an entity. + * + * @sa emplace + * @sa replace + * + * @tparam Type Type of element to assign or replace. + * @tparam Args Types of arguments to use to construct the element. + * @param entt A valid identifier. + * @param args Parameters to use to initialize the element. + * @return A reference to the newly created element. + */ + template + decltype(auto) emplace_or_replace(const entity_type entt, Args &&...args) { + auto &cpool = assure(); + ENTT_ASSERT(valid(entt), "Invalid entity"); + return cpool.contains(entt) ? cpool.patch(entt, [&args...](auto &...curr) { ((curr = Type{std::forward(args)...}), ...); }) : cpool.emplace(entt, std::forward(args)...); + } + + /** + * @brief Patches the given element for an entity. + * + * The signature of the function should be equivalent to the following: + * + * @code{.cpp} + * void(Type &); + * @endcode + * + * @warning + * Attempting to patch an element of an entity that doesn't own it results + * in undefined behavior. + * + * @tparam Type Type of element to patch. + * @tparam Func Types of the function objects to invoke. + * @param entt A valid identifier. + * @param func Valid function objects. + * @return A reference to the patched element. + */ + template + decltype(auto) patch(const entity_type entt, Func &&...func) { + return assure().patch(entt, std::forward(func)...); + } + + /** + * @brief Replaces the given element for an entity. + * + * The element must have a proper constructor or be of aggregate type. + * + * @warning + * Attempting to replace an element of an entity that doesn't own it results + * in undefined behavior. + * + * @tparam Type Type of element to replace. + * @tparam Args Types of arguments to use to construct the element. + * @param entt A valid identifier. + * @param args Parameters to use to initialize the element. + * @return A reference to the element being replaced. + */ + template + decltype(auto) replace(const entity_type entt, Args &&...args) { + return patch(entt, [&args...](auto &...curr) { ((curr = Type{std::forward(args)...}), ...); }); + } + + /** + * @brief Removes the given elements from an entity. + * @tparam Type Type of element to remove. + * @tparam Other Other types of elements to remove. + * @param entt A valid identifier. + * @return The number of elements actually removed. + */ + template + size_type remove(const entity_type entt) { + return (assure().remove(entt) + ... + assure().remove(entt)); + } + + /** + * @brief Removes the given elements from all the entities in a range. + * + * @sa remove + * + * @tparam Type Type of element to remove. + * @tparam Other Other types of elements to remove. + * @tparam It Type of input iterator. + * @param first An iterator to the first element of the range of entities. + * @param last An iterator past the last element of the range of entities. + * @return The number of elements actually removed. + */ + template + size_type remove(It first, It last) { + size_type count{}; + + if constexpr(std::is_same_v) { + std::array cpools{static_cast(&assure()), static_cast(&assure())...}; + + for(auto from = cpools.begin(), to = cpools.end(); from != to; ++from) { + if constexpr(sizeof...(Other) != 0u) { + if((*from)->data() == first.data()) { + std::swap((*from), cpools.back()); + } + } + + count += (*from)->remove(first, last); + } + + } else { + for(auto cpools = std::forward_as_tuple(assure(), assure()...); first != last; ++first) { + count += std::apply([entt = *first](auto &...curr) { return (curr.remove(entt) + ... + 0u); }, cpools); + } + } + + return count; + } + + /** + * @brief Erases the given elements from an entity. + * + * @warning + * Attempting to erase an element from an entity that doesn't own it results + * in undefined behavior. + * + * @tparam Type Types of elements to erase. + * @tparam Other Other types of elements to erase. + * @param entt A valid identifier. + */ + template + void erase(const entity_type entt) { + (assure().erase(entt), (assure().erase(entt), ...)); + } + + /** + * @brief Erases the given elements from all the entities in a range. + * + * @sa erase + * + * @tparam Type Types of elements to erase. + * @tparam Other Other types of elements to erase. + * @tparam It Type of input iterator. + * @param first An iterator to the first element of the range of entities. + * @param last An iterator past the last element of the range of entities. + */ + template + void erase(It first, It last) { + if constexpr(std::is_same_v) { + std::array cpools{static_cast(&assure()), static_cast(&assure())...}; + + for(auto from = cpools.begin(), to = cpools.end(); from != to; ++from) { + if constexpr(sizeof...(Other) != 0u) { + if((*from)->data() == first.data()) { + std::swap(*from, cpools.back()); + } + } + + (*from)->erase(first, last); + } + } else { + for(auto cpools = std::forward_as_tuple(assure(), assure()...); first != last; ++first) { + std::apply([entt = *first](auto &...curr) { (curr.erase(entt), ...); }, cpools); + } + } + } + + /** + * @brief Erases elements satisfying specific criteria from an entity. + * + * The function type is equivalent to: + * + * @code{.cpp} + * void(const id_type, typename basic_registry::common_type &); + * @endcode + * + * Only storage where the entity exists are passed to the function. + * + * @tparam Func Type of the function object to invoke. + * @param entt A valid identifier. + * @param func A valid function object. + */ + template + void erase_if(const entity_type entt, Func func) { + for(auto [id, cpool]: storage()) { + if(cpool.contains(entt) && func(id, std::as_const(cpool))) { + cpool.erase(entt); + } + } + } + + /** + * @brief Removes all tombstones from a registry or only the pools for the + * given elements. + * @tparam Type Types of elements for which to clear all tombstones. + */ + template + void compact() { + if constexpr(sizeof...(Type) == 0u) { + for(auto &&curr: pools) { + curr.second->compact(); + } + } else { + (assure().compact(), ...); + } + } + + /** + * @brief Check if an entity is part of all the given storage. + * @tparam Type Type of storage to check for. + * @param entt A valid identifier. + * @return True if the entity is part of all the storage, false otherwise. + */ + template + [[nodiscard]] bool all_of([[maybe_unused]] const entity_type entt) const { + if constexpr(sizeof...(Type) == 1u) { + auto *cpool = assure...>(); + return cpool && cpool->contains(entt); + } else { + return (all_of(entt) && ...); + } + } + + /** + * @brief Check if an entity is part of at least one given storage. + * @tparam Type Type of storage to check for. + * @param entt A valid identifier. + * @return True if the entity is part of at least one storage, false + * otherwise. + */ + template + [[nodiscard]] bool any_of([[maybe_unused]] const entity_type entt) const { + return (all_of(entt) || ...); + } + + /** + * @brief Returns references to the given elements for an entity. + * + * @warning + * Attempting to get an element from an entity that doesn't own it results + * in undefined behavior. + * + * @tparam Type Types of elements to get. + * @param entt A valid identifier. + * @return References to the elements owned by the entity. + */ + template + [[nodiscard]] decltype(auto) get([[maybe_unused]] const entity_type entt) const { + if constexpr(sizeof...(Type) == 1u) { + return (assure>()->get(entt), ...); + } else { + return std::forward_as_tuple(get(entt)...); + } + } + + /*! @copydoc get */ + template + [[nodiscard]] decltype(auto) get([[maybe_unused]] const entity_type entt) { + if constexpr(sizeof...(Type) == 1u) { + return (static_cast &>(assure>()).get(entt), ...); + } else { + return std::forward_as_tuple(get(entt)...); + } + } + + /** + * @brief Returns a reference to the given element for an entity. + * + * In case the entity doesn't own the element, the parameters provided are + * used to construct it. + * + * @sa get + * @sa emplace + * + * @tparam Type Type of element to get. + * @tparam Args Types of arguments to use to construct the element. + * @param entt A valid identifier. + * @param args Parameters to use to initialize the element. + * @return Reference to the element owned by the entity. + */ + template + [[nodiscard]] decltype(auto) get_or_emplace(const entity_type entt, Args &&...args) { + auto &cpool = assure(); + ENTT_ASSERT(valid(entt), "Invalid entity"); + return cpool.contains(entt) ? cpool.get(entt) : cpool.emplace(entt, std::forward(args)...); + } + + /** + * @brief Returns pointers to the given elements for an entity. + * + * @note + * The registry retains ownership of the pointed-to elements. + * + * @tparam Type Types of elements to get. + * @param entt A valid identifier. + * @return Pointers to the elements owned by the entity. + */ + template + [[nodiscard]] auto try_get([[maybe_unused]] const entity_type entt) const { + if constexpr(sizeof...(Type) == 1u) { + const auto *cpool = assure...>(); + return (cpool && cpool->contains(entt)) ? std::addressof(cpool->get(entt)) : nullptr; + } else { + return std::make_tuple(try_get(entt)...); + } + } + + /*! @copydoc try_get */ + template + [[nodiscard]] auto try_get([[maybe_unused]] const entity_type entt) { + if constexpr(sizeof...(Type) == 1u) { + return (const_cast(std::as_const(*this).template try_get(entt)), ...); + } else { + return std::make_tuple(try_get(entt)...); + } + } + + /** + * @brief Clears a whole registry or the pools for the given elements. + * @tparam Type Types of elements to remove from their entities. + */ + template + void clear() { + if constexpr(sizeof...(Type) == 0u) { + for(size_type pos = pools.size(); pos; --pos) { + pools.begin()[static_cast(pos - 1u)].second->clear(); + } + + const auto elem = entities.each(); + entities.erase(elem.begin().base(), elem.end().base()); + } else { + (assure().clear(), ...); + } + } + + /** + * @brief Checks if an entity has elements assigned. + * @param entt A valid identifier. + * @return True if the entity has no elements assigned, false otherwise. + */ + [[nodiscard]] bool orphan(const entity_type entt) const { + return std::none_of(pools.cbegin(), pools.cend(), [entt](auto &&curr) { return curr.second->contains(entt); }); + } + + /** + * @brief Returns a sink object for the given element. + * + * Use this function to receive notifications whenever a new instance of the + * given element is created and assigned to an entity.
+ * The function type for a listener is equivalent to: + * + * @code{.cpp} + * void(basic_registry &, Entity); + * @endcode + * + * Listeners are invoked **after** assigning the element to the entity. + * + * @sa sink + * + * @tparam Type Type of element of which to get the sink. + * @param id Optional name used to map the storage within the registry. + * @return A temporary sink object. + */ + template + [[nodiscard]] auto on_construct(const id_type id = type_hash::value()) { + return assure(id).on_construct(); + } + + /** + * @brief Returns a sink object for the given element. + * + * Use this function to receive notifications whenever an instance of the + * given element is explicitly updated.
+ * The function type for a listener is equivalent to: + * + * @code{.cpp} + * void(basic_registry &, Entity); + * @endcode + * + * Listeners are invoked **after** updating the element. + * + * @sa sink + * + * @tparam Type Type of element of which to get the sink. + * @param id Optional name used to map the storage within the registry. + * @return A temporary sink object. + */ + template + [[nodiscard]] auto on_update(const id_type id = type_hash::value()) { + return assure(id).on_update(); + } + + /** + * @brief Returns a sink object for the given element. + * + * Use this function to receive notifications whenever an instance of the + * given element is removed from an entity and thus destroyed.
+ * The function type for a listener is equivalent to: + * + * @code{.cpp} + * void(basic_registry &, Entity); + * @endcode + * + * Listeners are invoked **before** removing the element from the entity. + * + * @sa sink + * + * @tparam Type Type of element of which to get the sink. + * @param id Optional name used to map the storage within the registry. + * @return A temporary sink object. + */ + template + [[nodiscard]] auto on_destroy(const id_type id = type_hash::value()) { + return assure(id).on_destroy(); + } + + /** + * @brief Returns a view for the given elements. + * @tparam Type Type of element used to construct the view. + * @tparam Other Other types of elements used to construct the view. + * @tparam Exclude Types of elements used to filter the view. + * @return A newly created view. + */ + template + [[nodiscard]] basic_view, storage_for_type...>, exclude_t...>> + view(exclude_t = exclude_t{}) const { + basic_view, storage_for_type...>, exclude_t...>> elem{}; + [&elem](const auto *...curr) { ((curr ? elem.storage(*curr) : void()), ...); }(assure>()..., assure>()..., assure>()); + return elem; + } + + /*! @copydoc view */ + template + [[nodiscard]] basic_view, storage_for_type...>, exclude_t...>> + view(exclude_t = exclude_t{}) { + return {assure>(), assure>()..., assure>()...}; + } + + /** + * @brief Returns a group for the given elements. + * @tparam Owned Types of storage _owned_ by the group. + * @tparam Get Types of storage _observed_ by the group, if any. + * @tparam Exclude Types of storage used to filter the group, if any. + * @return A newly created group. + */ + template + basic_group...>, get_t...>, exclude_t...>> + group(get_t = get_t{}, exclude_t = exclude_t{}) { + using group_type = basic_group...>, get_t...>, exclude_t...>>; + using handler_type = typename group_type::handler; + + if(auto it = groups.find(group_type::group_id()); it != groups.cend()) { + return {*std::static_pointer_cast(it->second)}; + } + + std::shared_ptr handler{}; + + if constexpr(sizeof...(Owned) == 0u) { + handler = std::allocate_shared(get_allocator(), get_allocator(), std::forward_as_tuple(assure>()...), std::forward_as_tuple(assure>()...)); + } else { + handler = std::allocate_shared(get_allocator(), std::forward_as_tuple(assure>()..., assure>()...), std::forward_as_tuple(assure>()...)); + ENTT_ASSERT(std::all_of(groups.cbegin(), groups.cend(), [](const auto &data) { return !(data.second->owned(type_id().hash()) || ...); }), "Conflicting groups"); + } + + groups.emplace(group_type::group_id(), handler); + return {*handler}; + } + + /*! @copydoc group */ + template + [[nodiscard]] basic_group...>, get_t...>, exclude_t...>> + group_if_exists(get_t = get_t{}, exclude_t = exclude_t{}) const { + using group_type = basic_group...>, get_t...>, exclude_t...>>; + using handler_type = typename group_type::handler; + + if(auto it = groups.find(group_type::group_id()); it != groups.cend()) { + return {*std::static_pointer_cast(it->second)}; + } + + return {}; + } + + /** + * @brief Checks whether the given elements belong to any group. + * @tparam Type Types of elements in which one is interested. + * @return True if the pools of the given elements are _free_, false + * otherwise. + */ + template + [[nodiscard]] bool owned() const { + return std::any_of(groups.cbegin(), groups.cend(), [](auto &&data) { return (data.second->owned(type_id().hash()) || ...); }); + } + + /** + * @brief Sorts the elements of a given element. + * + * The comparison function object returns `true` if the first element is + * _less_ than the second one, `false` otherwise. Its signature is also + * equivalent to one of the following: + * + * @code{.cpp} + * bool(const Entity, const Entity); + * bool(const Type &, const Type &); + * @endcode + * + * Moreover, it shall induce a _strict weak ordering_ on the values.
+ * The sort function object offers an `operator()` that accepts: + * + * * An iterator to the first element of the range to sort. + * * An iterator past the last element of the range to sort. + * * A comparison function object to use to compare the elements. + * + * The comparison function object hasn't necessarily the type of the one + * passed along with the other parameters to this member function. + * + * @warning + * Pools of elements owned by a group cannot be sorted. + * + * @tparam Type Type of elements to sort. + * @tparam Compare Type of comparison function object. + * @tparam Sort Type of sort function object. + * @tparam Args Types of arguments to forward to the sort function object. + * @param compare A valid comparison function object. + * @param algo A valid sort function object. + * @param args Arguments to forward to the sort function object, if any. + */ + template + void sort(Compare compare, Sort algo = Sort{}, Args &&...args) { + ENTT_ASSERT(!owned(), "Cannot sort owned storage"); + auto &cpool = assure(); + + if constexpr(std::is_invocable_v) { + auto comp = [&cpool, compare = std::move(compare)](const auto lhs, const auto rhs) { return compare(std::as_const(cpool.get(lhs)), std::as_const(cpool.get(rhs))); }; + cpool.sort(std::move(comp), std::move(algo), std::forward(args)...); + } else { + cpool.sort(std::move(compare), std::move(algo), std::forward(args)...); + } + } + + /** + * @brief Sorts two pools of elements in the same way. + * + * Entities and elements in `To` which are part of both storage are sorted + * internally with the order they have in `From`. The others follow in no + * particular order. + * + * @warning + * Pools of elements owned by a group cannot be sorted. + * + * @tparam To Type of elements to sort. + * @tparam From Type of elements to use to sort. + */ + template + void sort() { + ENTT_ASSERT(!owned(), "Cannot sort owned storage"); + const base_type &cpool = assure(); + assure().sort_as(cpool.begin(), cpool.end()); + } + + /** + * @brief Returns the context object, that is, a general purpose container. + * @return The context object, that is, a general purpose container. + */ + [[nodiscard]] context &ctx() noexcept { + return vars; + } + + /*! @copydoc ctx */ + [[nodiscard]] const context &ctx() const noexcept { + return vars; + } + +private: + context vars; + pool_container_type pools; + group_container_type groups; + storage_for_type entities; +}; + +} // namespace entt + +#endif + +// #include "entity/runtime_view.hpp" +#ifndef ENTT_ENTITY_RUNTIME_VIEW_HPP +#define ENTT_ENTITY_RUNTIME_VIEW_HPP + +#include +#include +#include +#include +#include +// #include "entity.hpp" + +// #include "fwd.hpp" + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +class runtime_view_iterator final { + using iterator_type = typename Set::iterator; + using iterator_traits = std::iterator_traits; + + [[nodiscard]] bool valid() const { + return (!tombstone_check || *it != tombstone) + && std::all_of(++pools->begin(), pools->end(), [entt = *it](const auto *curr) { return curr->contains(entt); }) + && std::none_of(filter->cbegin(), filter->cend(), [entt = *it](const auto *curr) { return curr && curr->contains(entt); }); + } + +public: + using value_type = typename iterator_traits::value_type; + using pointer = typename iterator_traits::pointer; + using reference = typename iterator_traits::reference; + using difference_type = typename iterator_traits::difference_type; + using iterator_category = std::bidirectional_iterator_tag; + + constexpr runtime_view_iterator() noexcept + : pools{}, + filter{}, + it{}, + tombstone_check{} {} + + runtime_view_iterator(const std::vector &cpools, iterator_type curr, const std::vector &ignore) noexcept + : pools{&cpools}, + filter{&ignore}, + it{curr}, + tombstone_check{pools->size() == 1u && (*pools)[0u]->policy() == deletion_policy::in_place} { + if(it != (*pools)[0]->end() && !valid()) { + ++(*this); + } + } + + runtime_view_iterator &operator++() { + ++it; + for(const auto last = (*pools)[0]->end(); it != last && !valid(); ++it) {} + return *this; + } + + runtime_view_iterator operator++(int) { + const runtime_view_iterator orig = *this; + return ++(*this), orig; + } + + runtime_view_iterator &operator--() { + --it; + for(const auto first = (*pools)[0]->begin(); it != first && !valid(); --it) {} + return *this; + } + + runtime_view_iterator operator--(int) { + const runtime_view_iterator orig = *this; + return operator--(), orig; + } + + [[nodiscard]] pointer operator->() const noexcept { + return it.operator->(); + } + + [[nodiscard]] reference operator*() const noexcept { + return *operator->(); + } + + [[nodiscard]] constexpr bool operator==(const runtime_view_iterator &other) const noexcept { + return it == other.it; + } + + [[nodiscard]] constexpr bool operator!=(const runtime_view_iterator &other) const noexcept { + return !(*this == other); + } + +private: + const std::vector *pools; + const std::vector *filter; + iterator_type it; + bool tombstone_check; +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Generic runtime view. + * + * Runtime views iterate over those entities that are at least in the given + * storage. During initialization, a runtime view looks at the number of + * entities available for each element and uses the smallest set in order to get + * a performance boost when iterating. + * + * @b Important + * + * Iterators aren't invalidated if: + * + * * New elements are added to the storage. + * * The entity currently pointed is modified (for example, elements are added + * or removed from it). + * * The entity currently pointed is destroyed. + * + * In all other cases, modifying the storage iterated by the view in any way + * invalidates all the iterators. + * + * @tparam Type Common base type. + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +class basic_runtime_view { + using alloc_traits = std::allocator_traits; + static_assert(std::is_same_v, "Invalid value type"); + using container_type = std::vector; + + [[nodiscard]] auto offset() const noexcept { + ENTT_ASSERT(!pools.empty(), "Invalid view"); + const auto &leading = *pools.front(); + return (leading.policy() == deletion_policy::swap_only) ? leading.free_list() : leading.size(); + } + +public: + /*! @brief Allocator type. */ + using allocator_type = Allocator; + /*! @brief Underlying entity identifier. */ + using entity_type = typename Type::entity_type; + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + /*! @brief Signed integer type. */ + using difference_type = std::ptrdiff_t; + /*! @brief Common type among all storage types. */ + using common_type = Type; + /*! @brief Bidirectional iterator type. */ + using iterator = internal::runtime_view_iterator; + + /*! @brief Default constructor to use to create empty, invalid views. */ + basic_runtime_view() noexcept + : basic_runtime_view{allocator_type{}} {} + + /** + * @brief Constructs an empty, invalid view with a given allocator. + * @param allocator The allocator to use. + */ + explicit basic_runtime_view(const allocator_type &allocator) + : pools{allocator}, + filter{allocator} {} + + /*! @brief Default copy constructor. */ + basic_runtime_view(const basic_runtime_view &) = default; + + /** + * @brief Allocator-extended copy constructor. + * @param other The instance to copy from. + * @param allocator The allocator to use. + */ + basic_runtime_view(const basic_runtime_view &other, const allocator_type &allocator) + : pools{other.pools, allocator}, + filter{other.filter, allocator} {} + + /*! @brief Default move constructor. */ + basic_runtime_view(basic_runtime_view &&) noexcept = default; + + /** + * @brief Allocator-extended move constructor. + * @param other The instance to move from. + * @param allocator The allocator to use. + */ + basic_runtime_view(basic_runtime_view &&other, const allocator_type &allocator) + : pools{std::move(other.pools), allocator}, + filter{std::move(other.filter), allocator} {} + + /*! @brief Default destructor. */ + ~basic_runtime_view() = default; + + /** + * @brief Default copy assignment operator. + * @return This runtime view. + */ + basic_runtime_view &operator=(const basic_runtime_view &) = default; + + /** + * @brief Default move assignment operator. + * @return This runtime view. + */ + basic_runtime_view &operator=(basic_runtime_view &&) noexcept = default; + + /** + * @brief Exchanges the contents with those of a given view. + * @param other View to exchange the content with. + */ + void swap(basic_runtime_view &other) noexcept { + using std::swap; + swap(pools, other.pools); + swap(filter, other.filter); + } + + /** + * @brief Returns the associated allocator. + * @return The associated allocator. + */ + [[nodiscard]] constexpr allocator_type get_allocator() const noexcept { + return pools.get_allocator(); + } + + /*! @brief Clears the view. */ + void clear() { + pools.clear(); + filter.clear(); + } + + /** + * @brief Appends an opaque storage object to a runtime view. + * @param base An opaque reference to a storage object. + * @return This runtime view. + */ + basic_runtime_view &iterate(common_type &base) { + if(pools.empty() || !(base.size() < pools.front()->size())) { + pools.push_back(&base); + } else { + pools.push_back(std::exchange(pools.front(), &base)); + } + + return *this; + } + + /** + * @brief Adds an opaque storage object as a filter of a runtime view. + * @param base An opaque reference to a storage object. + * @return This runtime view. + */ + basic_runtime_view &exclude(common_type &base) { + filter.push_back(&base); + return *this; + } + + /** + * @brief Estimates the number of entities iterated by the view. + * @return Estimated number of entities iterated by the view. + */ + [[nodiscard]] size_type size_hint() const { + return pools.empty() ? size_type{} : offset(); + } + + /** + * @brief Returns an iterator to the first entity that has the given + * elements. + * + * If the view is empty, the returned iterator will be equal to `end()`. + * + * @return An iterator to the first entity that has the given elements. + */ + [[nodiscard]] iterator begin() const { + return pools.empty() ? iterator{} : iterator{pools, pools.front()->end() - static_cast(offset()), filter}; + } + + /** + * @brief Returns an iterator that is past the last entity that has the + * given elements. + * @return An iterator to the entity following the last entity that has the + * given elements. + */ + [[nodiscard]] iterator end() const { + return pools.empty() ? iterator{} : iterator{pools, pools.front()->end(), filter}; + } + + /** + * @brief Checks whether a view is initialized or not. + * @return True if the view is initialized, false otherwise. + */ + [[nodiscard]] explicit operator bool() const noexcept { + return !(pools.empty() && filter.empty()); + } + + /** + * @brief Checks if a view contains an entity. + * @param entt A valid identifier. + * @return True if the view contains the given entity, false otherwise. + */ + [[nodiscard]] bool contains(const entity_type entt) const { + return !pools.empty() + && std::all_of(pools.cbegin(), pools.cend(), [entt](const auto *curr) { return curr->contains(entt); }) + && std::none_of(filter.cbegin(), filter.cend(), [entt](const auto *curr) { return curr && curr->contains(entt); }) + && pools.front()->index(entt) < offset(); + } + + /** + * @brief Iterates entities and applies the given function object to them. + * + * The function object is invoked for each entity. It is provided only with + * the entity itself.
+ * The signature of the function should be equivalent to the following: + * + * @code{.cpp} + * void(const entity_type); + * @endcode + * + * @tparam Func Type of the function object to invoke. + * @param func A valid function object. + */ + template + void each(Func func) const { + for(const auto entity: *this) { + func(entity); + } + } + +private: + container_type pools; + container_type filter; +}; + +} // namespace entt + +#endif + +// #include "entity/snapshot.hpp" +#ifndef ENTT_ENTITY_SNAPSHOT_HPP +#define ENTT_ENTITY_SNAPSHOT_HPP + +#include +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "../container/dense_map.hpp" + +// #include "../core/type_traits.hpp" + +// #include "entity.hpp" + +// #include "fwd.hpp" + +// #include "view.hpp" + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +void orphans(Registry ®istry) { + auto &storage = registry.template storage(); + + for(auto entt: storage) { + if(registry.orphan(entt)) { + storage.erase(entt); + } + } +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Utility class to create snapshots from a registry. + * + * A _snapshot_ can be either a dump of the entire registry or a narrower + * selection of elements of interest.
+ * This type can be used in both cases if provided with a correctly configured + * output archive. + * + * @tparam Registry Basic registry type. + */ +template +class basic_snapshot { + static_assert(!std::is_const_v, "Non-const registry type required"); + using traits_type = entt_traits; + +public: + /*! Basic registry type. */ + using registry_type = Registry; + /*! @brief Underlying entity identifier. */ + using entity_type = typename registry_type::entity_type; + + /** + * @brief Constructs an instance that is bound to a given registry. + * @param source A valid reference to a registry. + */ + basic_snapshot(const registry_type &source) noexcept + : reg{&source} {} + + /*! @brief Default copy constructor, deleted on purpose. */ + basic_snapshot(const basic_snapshot &) = delete; + + /*! @brief Default move constructor. */ + basic_snapshot(basic_snapshot &&) noexcept = default; + + /*! @brief Default destructor. */ + ~basic_snapshot() = default; + + /** + * @brief Default copy assignment operator, deleted on purpose. + * @return This snapshot. + */ + basic_snapshot &operator=(const basic_snapshot &) = delete; + + /** + * @brief Default move assignment operator. + * @return This snapshot. + */ + basic_snapshot &operator=(basic_snapshot &&) noexcept = default; + + /** + * @brief Serializes all elements of a type with associated identifiers. + * @tparam Type Type of elements to serialize. + * @tparam Archive Type of output archive. + * @param archive A valid reference to an output archive. + * @param id Optional name used to map the storage within the registry. + * @return An object of this type to continue creating the snapshot. + */ + template + const basic_snapshot &get(Archive &archive, const id_type id = type_hash::value()) const { + if(const auto *storage = reg->template storage(id); storage) { + const typename registry_type::common_type &base = *storage; + + archive(static_cast(storage->size())); + + if constexpr(std::is_same_v) { + archive(static_cast(storage->free_list())); + + for(auto first = base.rbegin(), last = base.rend(); first != last; ++first) { + archive(*first); + } + } else if constexpr(registry_type::template storage_for_type::storage_policy == deletion_policy::in_place) { + for(auto it = base.rbegin(), last = base.rend(); it != last; ++it) { + if(const auto entt = *it; entt == tombstone) { + archive(static_cast(null)); + } else { + archive(entt); + std::apply([&archive](auto &&...args) { (archive(std::forward(args)), ...); }, storage->get_as_tuple(entt)); + } + } + } else { + for(auto elem: storage->reach()) { + std::apply([&archive](auto &&...args) { (archive(std::forward(args)), ...); }, elem); + } + } + } else { + archive(typename traits_type::entity_type{}); + } + + return *this; + } + + /** + * @brief Serializes all elements of a type with associated identifiers for + * the entities in a range. + * @tparam Type Type of elements to serialize. + * @tparam Archive Type of output archive. + * @tparam It Type of input iterator. + * @param archive A valid reference to an output archive. + * @param first An iterator to the first element of the range to serialize. + * @param last An iterator past the last element of the range to serialize. + * @param id Optional name used to map the storage within the registry. + * @return An object of this type to continue creating the snapshot. + */ + template + const basic_snapshot &get(Archive &archive, It first, It last, const id_type id = type_hash::value()) const { + static_assert(!std::is_same_v, "Entity types not supported"); + + if(const auto *storage = reg->template storage(id); storage && !storage->empty()) { + archive(static_cast(std::distance(first, last))); + + for(; first != last; ++first) { + if(const auto entt = *first; storage->contains(entt)) { + archive(entt); + std::apply([&archive](auto &&...args) { (archive(std::forward(args)), ...); }, storage->get_as_tuple(entt)); + } else { + archive(static_cast(null)); + } + } + } else { + archive(typename traits_type::entity_type{}); + } + + return *this; + } + +private: + const registry_type *reg; +}; + +/** + * @brief Utility class to restore a snapshot as a whole. + * + * A snapshot loader requires that the destination registry be empty and loads + * all the data at once while keeping intact the identifiers that the entities + * originally had.
+ * An example of use is the implementation of a save/restore utility. + * + * @tparam Registry Basic registry type. + */ +template +class basic_snapshot_loader { + static_assert(!std::is_const_v, "Non-const registry type required"); + using traits_type = entt_traits; + +public: + /*! Basic registry type. */ + using registry_type = Registry; + /*! @brief Underlying entity identifier. */ + using entity_type = typename registry_type::entity_type; + + /** + * @brief Constructs an instance that is bound to a given registry. + * @param source A valid reference to a registry. + */ + basic_snapshot_loader(registry_type &source) noexcept + : reg{&source} { + // restoring a snapshot as a whole requires a clean registry + ENTT_ASSERT(reg->template storage().free_list() == 0u, "Registry must be empty"); + } + + /*! @brief Default copy constructor, deleted on purpose. */ + basic_snapshot_loader(const basic_snapshot_loader &) = delete; + + /*! @brief Default move constructor. */ + basic_snapshot_loader(basic_snapshot_loader &&) noexcept = default; + + /*! @brief Default destructor. */ + ~basic_snapshot_loader() = default; + + /** + * @brief Default copy assignment operator, deleted on purpose. + * @return This loader. + */ + basic_snapshot_loader &operator=(const basic_snapshot_loader &) = delete; + + /** + * @brief Default move assignment operator. + * @return This loader. + */ + basic_snapshot_loader &operator=(basic_snapshot_loader &&) noexcept = default; + + /** + * @brief Restores all elements of a type with associated identifiers. + * @tparam Type Type of elements to restore. + * @tparam Archive Type of input archive. + * @param archive A valid reference to an input archive. + * @param id Optional name used to map the storage within the registry. + * @return A valid loader to continue restoring data. + */ + template + basic_snapshot_loader &get(Archive &archive, const id_type id = type_hash::value()) { + auto &storage = reg->template storage(id); + typename traits_type::entity_type length{}; + + archive(length); + + if constexpr(std::is_same_v) { + typename traits_type::entity_type count{}; + entity_type placeholder{}; + + storage.reserve(length); + archive(count); + + for(entity_type entity = null; length; --length) { + archive(entity); + storage.generate(entity); + placeholder = (entity > placeholder) ? entity : placeholder; + } + + storage.start_from(traits_type::next(placeholder)); + storage.free_list(count); + } else { + auto &other = reg->template storage(); + entity_type entt{null}; + + while(length--) { + if(archive(entt); entt != null) { + const auto entity = other.contains(entt) ? entt : other.generate(entt); + ENTT_ASSERT(entity == entt, "Entity not available for use"); + + if constexpr(std::tuple_size_v == 0u) { + storage.emplace(entity); + } else { + Type elem{}; + archive(elem); + storage.emplace(entity, std::move(elem)); + } + } + } + } + + return *this; + } + + /** + * @brief Destroys those entities that have no elements. + * + * In case all the entities were serialized but only part of the elements + * was saved, it could happen that some of the entities have no elements + * once restored.
+ * This function helps to identify and destroy those entities. + * + * @return A valid loader to continue restoring data. + */ + basic_snapshot_loader &orphans() { + internal::orphans(*reg); + return *this; + } + +private: + registry_type *reg; +}; + +/** + * @brief Utility class for _continuous loading_. + * + * A _continuous loader_ is designed to load data from a source registry to a + * (possibly) non-empty destination. The loader can accommodate in a registry + * more than one snapshot in a sort of _continuous loading_ that updates the + * destination one step at a time.
+ * Identifiers that entities originally had are not transferred to the target. + * Instead, the loader maps remote identifiers to local ones while restoring a + * snapshot.
+ * An example of use is the implementation of a client-server application with + * the requirement of transferring somehow parts of the representation side to + * side. + * + * @tparam Registry Basic registry type. + */ +template +class basic_continuous_loader { + static_assert(!std::is_const_v, "Non-const registry type required"); + using traits_type = entt_traits; + + void restore(typename Registry::entity_type entt) { + if(const auto entity = to_entity(entt); remloc.contains(entity) && remloc[entity].first == entt) { + if(!reg->valid(remloc[entity].second)) { + remloc[entity].second = reg->create(); + } + } else { + remloc.insert_or_assign(entity, std::make_pair(entt, reg->create())); + } + } + + template + auto update(int, Container &container) -> decltype(typename Container::mapped_type{}, void()) { + // map like container + Container other; + + for(auto &&pair: container) { + using first_type = std::remove_const_t::first_type>; + using second_type = typename std::decay_t::second_type; + + if constexpr(std::is_same_v && std::is_same_v) { + other.emplace(map(pair.first), map(pair.second)); + } else if constexpr(std::is_same_v) { + other.emplace(map(pair.first), std::move(pair.second)); + } else { + static_assert(std::is_same_v, "Neither the key nor the value are of entity type"); + other.emplace(std::move(pair.first), map(pair.second)); + } + } + + using std::swap; + swap(container, other); + } + + template + auto update(char, Container &container) -> decltype(typename Container::value_type{}, void()) { + // vector like container + static_assert(std::is_same_v, "Invalid value type"); + + for(auto &&entt: container) { + entt = map(entt); + } + } + + template + void update([[maybe_unused]] Component &instance, [[maybe_unused]] Member Other::*member) { + if constexpr(!std::is_same_v) { + return; + } else if constexpr(std::is_same_v) { + instance.*member = map(instance.*member); + } else { + // maybe a container? let's try... + update(0, instance.*member); + } + } + +public: + /*! Basic registry type. */ + using registry_type = Registry; + /*! @brief Underlying entity identifier. */ + using entity_type = typename registry_type::entity_type; + + /** + * @brief Constructs an instance that is bound to a given registry. + * @param source A valid reference to a registry. + */ + basic_continuous_loader(registry_type &source) noexcept + : remloc{source.get_allocator()}, + reg{&source} {} + + /*! @brief Default copy constructor, deleted on purpose. */ + basic_continuous_loader(const basic_continuous_loader &) = delete; + + /*! @brief Default move constructor. */ + basic_continuous_loader(basic_continuous_loader &&) noexcept = default; + + /*! @brief Default destructor. */ + ~basic_continuous_loader() = default; + + /** + * @brief Default copy assignment operator, deleted on purpose. + * @return This loader. + */ + basic_continuous_loader &operator=(const basic_continuous_loader &) = delete; + + /** + * @brief Default move assignment operator. + * @return This loader. + */ + basic_continuous_loader &operator=(basic_continuous_loader &&) noexcept = default; + + /** + * @brief Restores all elements of a type with associated identifiers. + * + * It creates local counterparts for remote elements as needed.
+ * Members are either data members of type entity_type or containers of + * entities. In both cases, a loader visits them and replaces entities with + * their local counterpart. + * + * @tparam Type Type of elements to restore. + * @tparam Archive Type of input archive. + * @param archive A valid reference to an input archive. + * @param id Optional name used to map the storage within the registry. + * @return A valid loader to continue restoring data. + */ + template + basic_continuous_loader &get(Archive &archive, const id_type id = type_hash::value()) { + auto &storage = reg->template storage(id); + typename traits_type::entity_type length{}; + entity_type entt{null}; + + archive(length); + + if constexpr(std::is_same_v) { + typename traits_type::entity_type in_use{}; + + storage.reserve(length); + archive(in_use); + + for(std::size_t pos{}; pos < in_use; ++pos) { + archive(entt); + restore(entt); + } + + for(std::size_t pos = in_use; pos < length; ++pos) { + archive(entt); + + if(const auto entity = to_entity(entt); remloc.contains(entity)) { + if(reg->valid(remloc[entity].second)) { + reg->destroy(remloc[entity].second); + } + + remloc.erase(entity); + } + } + } else { + for(auto &&ref: remloc) { + storage.remove(ref.second.second); + } + + while(length--) { + if(archive(entt); entt != null) { + restore(entt); + + if constexpr(std::tuple_size_v == 0u) { + storage.emplace(map(entt)); + } else { + Type elem{}; + archive(elem); + storage.emplace(map(entt), std::move(elem)); + } + } + } + } + + return *this; + } + + /** + * @brief Destroys those entities that have no elements. + * + * In case all the entities were serialized but only part of the elements + * was saved, it could happen that some of the entities have no elements + * once restored.
+ * This function helps to identify and destroy those entities. + * + * @return A non-const reference to this loader. + */ + basic_continuous_loader &orphans() { + internal::orphans(*reg); + return *this; + } + + /** + * @brief Tests if a loader knows about a given entity. + * @param entt A valid identifier. + * @return True if `entity` is managed by the loader, false otherwise. + */ + [[nodiscard]] bool contains(entity_type entt) const noexcept { + const auto it = remloc.find(to_entity(entt)); + return it != remloc.cend() && it->second.first == entt; + } + + /** + * @brief Returns the identifier to which an entity refers. + * @param entt A valid identifier. + * @return The local identifier if any, the null entity otherwise. + */ + [[nodiscard]] entity_type map(entity_type entt) const noexcept { + if(const auto it = remloc.find(to_entity(entt)); it != remloc.cend() && it->second.first == entt) { + return it->second.second; + } + + return null; + } + +private: + dense_map> remloc; + registry_type *reg; +}; + +} // namespace entt + +#endif + +// #include "entity/sparse_set.hpp" +#ifndef ENTT_ENTITY_SPARSE_SET_HPP +#define ENTT_ENTITY_SPARSE_SET_HPP + +#include +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "../core/algorithm.hpp" + +// #include "../core/any.hpp" + +// #include "../core/bit.hpp" + +// #include "../core/type_info.hpp" + +// #include "entity.hpp" + +// #include "fwd.hpp" + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct sparse_set_iterator final { + using value_type = typename Container::value_type; + using pointer = typename Container::const_pointer; + using reference = typename Container::const_reference; + using difference_type = typename Container::difference_type; + using iterator_category = std::random_access_iterator_tag; + + constexpr sparse_set_iterator() noexcept + : packed{}, + offset{} {} + + constexpr sparse_set_iterator(const Container &ref, const difference_type idx) noexcept + : packed{&ref}, + offset{idx} {} + + constexpr sparse_set_iterator &operator++() noexcept { + return --offset, *this; + } + + constexpr sparse_set_iterator operator++(int) noexcept { + const sparse_set_iterator orig = *this; + return ++(*this), orig; + } + + constexpr sparse_set_iterator &operator--() noexcept { + return ++offset, *this; + } + + constexpr sparse_set_iterator operator--(int) noexcept { + const sparse_set_iterator orig = *this; + return operator--(), orig; + } + + constexpr sparse_set_iterator &operator+=(const difference_type value) noexcept { + offset -= value; + return *this; + } + + constexpr sparse_set_iterator operator+(const difference_type value) const noexcept { + sparse_set_iterator copy = *this; + return (copy += value); + } + + constexpr sparse_set_iterator &operator-=(const difference_type value) noexcept { + return (*this += -value); + } + + constexpr sparse_set_iterator operator-(const difference_type value) const noexcept { + return (*this + -value); + } + + [[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept { + return (*packed)[static_cast(index() - value)]; + } + + [[nodiscard]] constexpr pointer operator->() const noexcept { + return std::addressof(operator[](0)); + } + + [[nodiscard]] constexpr reference operator*() const noexcept { + return operator[](0); + } + + [[nodiscard]] constexpr pointer data() const noexcept { + return packed ? packed->data() : nullptr; + } + + [[nodiscard]] constexpr difference_type index() const noexcept { + return offset - 1; + } + +private: + const Container *packed; + difference_type offset; +}; + +template +[[nodiscard]] constexpr std::ptrdiff_t operator-(const sparse_set_iterator &lhs, const sparse_set_iterator &rhs) noexcept { + return rhs.index() - lhs.index(); +} + +template +[[nodiscard]] constexpr bool operator==(const sparse_set_iterator &lhs, const sparse_set_iterator &rhs) noexcept { + return lhs.index() == rhs.index(); +} + +template +[[nodiscard]] constexpr bool operator!=(const sparse_set_iterator &lhs, const sparse_set_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +template +[[nodiscard]] constexpr bool operator<(const sparse_set_iterator &lhs, const sparse_set_iterator &rhs) noexcept { + return lhs.index() > rhs.index(); +} + +template +[[nodiscard]] constexpr bool operator>(const sparse_set_iterator &lhs, const sparse_set_iterator &rhs) noexcept { + return rhs < lhs; +} + +template +[[nodiscard]] constexpr bool operator<=(const sparse_set_iterator &lhs, const sparse_set_iterator &rhs) noexcept { + return !(lhs > rhs); +} + +template +[[nodiscard]] constexpr bool operator>=(const sparse_set_iterator &lhs, const sparse_set_iterator &rhs) noexcept { + return !(lhs < rhs); +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Sparse set implementation. + * + * Sparse set or packed array or whatever is the name users give it.
+ * Two arrays: an _external_ one and an _internal_ one; a _sparse_ one and a + * _packed_ one; one used for direct access through contiguous memory, the other + * one used to get the data through an extra level of indirection.
+ * This type of data structure is widely documented in the literature and on the + * web. This is nothing more than a customized implementation suitable for the + * purpose of the framework. + * + * @note + * Internal data structures arrange elements to maximize performance. There are + * no guarantees that entities are returned in the insertion order when iterate + * a sparse set. Do not make assumption on the order in any case. + * + * @tparam Entity A valid entity type. + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +class basic_sparse_set { + using alloc_traits = std::allocator_traits; + static_assert(std::is_same_v, "Invalid value type"); + using sparse_container_type = std::vector>; + using packed_container_type = std::vector; + using traits_type = entt_traits; + + static constexpr auto max_size = static_cast(traits_type::to_entity(null)); + + // it could be auto but gcc complains and emits a warning due to a false positive + [[nodiscard]] std::size_t policy_to_head() const noexcept { + return static_cast(max_size * static_cast>(mode != deletion_policy::swap_only)); + } + + [[nodiscard]] auto entity_to_pos(const Entity entt) const noexcept { + return static_cast(traits_type::to_entity(entt)); + } + + [[nodiscard]] auto pos_to_page(const std::size_t pos) const noexcept { + return static_cast(pos / traits_type::page_size); + } + + [[nodiscard]] auto sparse_ptr(const Entity entt) const { + const auto pos = entity_to_pos(entt); + const auto page = pos_to_page(pos); + return (page < sparse.size() && sparse[page]) ? (sparse[page] + fast_mod(pos, traits_type::page_size)) : nullptr; + } + + [[nodiscard]] auto &sparse_ref(const Entity entt) const { + ENTT_ASSERT(sparse_ptr(entt), "Invalid element"); + const auto pos = entity_to_pos(entt); + return sparse[pos_to_page(pos)][fast_mod(pos, traits_type::page_size)]; + } + + [[nodiscard]] auto to_iterator(const Entity entt) const { + return --(end() - static_cast(index(entt))); + } + + [[nodiscard]] auto &assure_at_least(const Entity entt) { + const auto pos = entity_to_pos(entt); + const auto page = pos_to_page(pos); + + if(!(page < sparse.size())) { + sparse.resize(page + 1u, nullptr); + } + + if(!sparse[page]) { + constexpr entity_type init = null; + auto page_allocator{packed.get_allocator()}; + sparse[page] = alloc_traits::allocate(page_allocator, traits_type::page_size); + std::uninitialized_fill(sparse[page], sparse[page] + traits_type::page_size, init); + } + + return sparse[page][fast_mod(pos, traits_type::page_size)]; + } + + void release_sparse_pages() { + auto page_allocator{packed.get_allocator()}; + + for(auto &&page: sparse) { + if(page != nullptr) { + std::destroy(page, page + traits_type::page_size); + alloc_traits::deallocate(page_allocator, page, traits_type::page_size); + page = nullptr; + } + } + } + + void swap_at(const std::size_t lhs, const std::size_t rhs) { + auto &from = packed[lhs]; + auto &to = packed[rhs]; + + sparse_ref(from) = traits_type::combine(static_cast(rhs), traits_type::to_integral(from)); + sparse_ref(to) = traits_type::combine(static_cast(lhs), traits_type::to_integral(to)); + + std::swap(from, to); + } + +private: + [[nodiscard]] virtual const void *get_at(const std::size_t) const { + return nullptr; + } + + virtual void swap_or_move([[maybe_unused]] const std::size_t lhs, [[maybe_unused]] const std::size_t rhs) { + ENTT_ASSERT((mode != deletion_policy::swap_only) || ((lhs < head) == (rhs < head)), "Cross swapping is not supported"); + } + +protected: + /*! @brief Random access iterator type. */ + using basic_iterator = internal::sparse_set_iterator; + + /** + * @brief Erases an entity from a sparse set. + * @param it An iterator to the element to pop. + */ + void swap_only(const basic_iterator it) { + ENTT_ASSERT(mode == deletion_policy::swap_only, "Deletion policy mismatch"); + const auto pos = index(*it); + bump(traits_type::next(*it)); + swap_at(pos, head -= (pos < head)); + } + + /** + * @brief Erases an entity from a sparse set. + * @param it An iterator to the element to pop. + */ + void swap_and_pop(const basic_iterator it) { + ENTT_ASSERT(mode == deletion_policy::swap_and_pop, "Deletion policy mismatch"); + auto &self = sparse_ref(*it); + const auto entt = traits_type::to_entity(self); + sparse_ref(packed.back()) = traits_type::combine(entt, traits_type::to_integral(packed.back())); + packed[static_cast(entt)] = packed.back(); + // unnecessary but it helps to detect nasty bugs + // NOLINTNEXTLINE(bugprone-assert-side-effect) + ENTT_ASSERT((packed.back() = null, true), ""); + // lazy self-assignment guard + self = null; + packed.pop_back(); + } + + /** + * @brief Erases an entity from a sparse set. + * @param it An iterator to the element to pop. + */ + void in_place_pop(const basic_iterator it) { + ENTT_ASSERT(mode == deletion_policy::in_place, "Deletion policy mismatch"); + const auto pos = entity_to_pos(std::exchange(sparse_ref(*it), null)); + packed[pos] = traits_type::combine(static_cast(std::exchange(head, pos)), tombstone); + } + + /** + * @brief Erases entities from a sparse set. + * @param first An iterator to the first element of the range of entities. + * @param last An iterator past the last element of the range of entities. + */ + virtual void pop(basic_iterator first, basic_iterator last) { + switch(mode) { + case deletion_policy::swap_and_pop: + for(; first != last; ++first) { + swap_and_pop(first); + } + break; + case deletion_policy::in_place: + for(; first != last; ++first) { + in_place_pop(first); + } + break; + case deletion_policy::swap_only: + for(; first != last; ++first) { + swap_only(first); + } + break; + } + } + + /*! @brief Erases all entities of a sparse set. */ + virtual void pop_all() { + switch(mode) { + case deletion_policy::in_place: + if(head != max_size) { + for(auto &&elem: packed) { + if(elem != tombstone) { + sparse_ref(elem) = null; + } + } + break; + } + [[fallthrough]]; + case deletion_policy::swap_only: + case deletion_policy::swap_and_pop: + for(auto &&elem: packed) { + sparse_ref(elem) = null; + } + break; + } + + head = policy_to_head(); + packed.clear(); + } + + /** + * @brief Assigns an entity to a sparse set. + * @param entt A valid identifier. + * @param force_back Force back insertion. + * @return Iterator pointing to the emplaced element. + */ + virtual basic_iterator try_emplace(const Entity entt, const bool force_back, const void * = nullptr) { + ENTT_ASSERT(entt != null && entt != tombstone, "Invalid element"); + auto &elem = assure_at_least(entt); + auto pos = size(); + + switch(mode) { + case deletion_policy::in_place: + if(head != max_size && !force_back) { + pos = head; + ENTT_ASSERT(elem == null, "Slot not available"); + elem = traits_type::combine(static_cast(head), traits_type::to_integral(entt)); + head = entity_to_pos(std::exchange(packed[pos], entt)); + break; + } + [[fallthrough]]; + case deletion_policy::swap_and_pop: + packed.push_back(entt); + ENTT_ASSERT(elem == null, "Slot not available"); + elem = traits_type::combine(static_cast(packed.size() - 1u), traits_type::to_integral(entt)); + break; + case deletion_policy::swap_only: + if(elem == null) { + packed.push_back(entt); + elem = traits_type::combine(static_cast(packed.size() - 1u), traits_type::to_integral(entt)); + } else { + ENTT_ASSERT(!(entity_to_pos(elem) < head), "Slot not available"); + bump(entt); + } + + pos = head++; + swap_at(entity_to_pos(elem), pos); + break; + } + + return iterator{packed, static_cast(++pos)}; + } + + /*! @brief Forwards variables to derived classes, if any. */ + // NOLINTNEXTLINE(performance-unnecessary-value-param) + virtual void bind_any(any) noexcept {} + +public: + /*! @brief Allocator type. */ + using allocator_type = Allocator; + /*! @brief Underlying entity identifier. */ + using entity_type = typename traits_type::value_type; + /*! @brief Underlying version type. */ + using version_type = typename traits_type::version_type; + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + /*! @brief Signed integer type. */ + using difference_type = std::ptrdiff_t; + /*! @brief Pointer type to contained entities. */ + using pointer = typename packed_container_type::const_pointer; + /*! @brief Random access iterator type. */ + using iterator = basic_iterator; + /*! @brief Constant random access iterator type. */ + using const_iterator = iterator; + /*! @brief Reverse iterator type. */ + using reverse_iterator = std::reverse_iterator; + /*! @brief Constant reverse iterator type. */ + using const_reverse_iterator = std::reverse_iterator; + + /*! @brief Default constructor. */ + basic_sparse_set() + : basic_sparse_set{type_id()} {} + + /** + * @brief Constructs an empty container with a given allocator. + * @param allocator The allocator to use. + */ + explicit basic_sparse_set(const allocator_type &allocator) + : basic_sparse_set{deletion_policy::swap_and_pop, allocator} {} + + /** + * @brief Constructs an empty container with the given policy and allocator. + * @param pol Type of deletion policy. + * @param allocator The allocator to use (possibly default-constructed). + */ + explicit basic_sparse_set(deletion_policy pol, const allocator_type &allocator = {}) + : basic_sparse_set{type_id(), pol, allocator} {} + + /** + * @brief Constructs an empty container with the given value type, policy + * and allocator. + * @param elem Returned value type, if any. + * @param pol Type of deletion policy. + * @param allocator The allocator to use (possibly default-constructed). + */ + explicit basic_sparse_set(const type_info &elem, deletion_policy pol = deletion_policy::swap_and_pop, const allocator_type &allocator = {}) + : sparse{allocator}, + packed{allocator}, + descriptor{&elem}, + mode{pol}, + head{policy_to_head()} { + ENTT_ASSERT(traits_type::version_mask || mode != deletion_policy::in_place, "Policy does not support zero-sized versions"); + } + + /*! @brief Default copy constructor, deleted on purpose. */ + basic_sparse_set(const basic_sparse_set &) = delete; + + /** + * @brief Move constructor. + * @param other The instance to move from. + */ + basic_sparse_set(basic_sparse_set &&other) noexcept + : sparse{std::move(other.sparse)}, + packed{std::move(other.packed)}, + descriptor{other.descriptor}, + mode{other.mode}, + head{std::exchange(other.head, policy_to_head())} {} + + /** + * @brief Allocator-extended move constructor. + * @param other The instance to move from. + * @param allocator The allocator to use. + */ + basic_sparse_set(basic_sparse_set &&other, const allocator_type &allocator) + : sparse{std::move(other.sparse), allocator}, + packed{std::move(other.packed), allocator}, + descriptor{other.descriptor}, + mode{other.mode}, + head{std::exchange(other.head, policy_to_head())} { + ENTT_ASSERT(alloc_traits::is_always_equal::value || get_allocator() == other.get_allocator(), "Copying a sparse set is not allowed"); + } + + /*! @brief Default destructor. */ + virtual ~basic_sparse_set() { + release_sparse_pages(); + } + + /** + * @brief Default copy assignment operator, deleted on purpose. + * @return This sparse set. + */ + basic_sparse_set &operator=(const basic_sparse_set &) = delete; + + /** + * @brief Move assignment operator. + * @param other The instance to move from. + * @return This sparse set. + */ + basic_sparse_set &operator=(basic_sparse_set &&other) noexcept { + ENTT_ASSERT(alloc_traits::is_always_equal::value || get_allocator() == other.get_allocator(), "Copying a sparse set is not allowed"); + swap(other); + return *this; + } + + /** + * @brief Exchanges the contents with those of a given sparse set. + * @param other Sparse set to exchange the content with. + */ + void swap(basic_sparse_set &other) noexcept { + using std::swap; + swap(sparse, other.sparse); + swap(packed, other.packed); + swap(descriptor, other.descriptor); + swap(mode, other.mode); + swap(head, other.head); + } + + /** + * @brief Returns the associated allocator. + * @return The associated allocator. + */ + [[nodiscard]] constexpr allocator_type get_allocator() const noexcept { + return packed.get_allocator(); + } + + /** + * @brief Returns the deletion policy of a sparse set. + * @return The deletion policy of the sparse set. + */ + [[nodiscard]] deletion_policy policy() const noexcept { + return mode; + } + + /** + * @brief Returns data on the free list whose meaning depends on the mode. + * @return Free list information that is mode dependent. + */ + [[nodiscard]] size_type free_list() const noexcept { + return head; + } + + /** + * @brief Sets data on the free list whose meaning depends on the mode. + * @param value Free list information that is mode dependent. + */ + void free_list(const size_type value) noexcept { + ENTT_ASSERT((mode == deletion_policy::swap_only) && !(value > packed.size()), "Invalid value"); + head = value; + } + + /** + * @brief Increases the capacity of a sparse set. + * + * If the new capacity is greater than the current capacity, new storage is + * allocated, otherwise the method does nothing. + * + * @param cap Desired capacity. + */ + virtual void reserve(const size_type cap) { + packed.reserve(cap); + } + + /** + * @brief Returns the number of elements that a sparse set has currently + * allocated space for. + * @return Capacity of the sparse set. + */ + [[nodiscard]] virtual size_type capacity() const noexcept { + return packed.capacity(); + } + + /*! @brief Requests the removal of unused capacity. */ + virtual void shrink_to_fit() { + sparse_container_type other{sparse.get_allocator()}; + const auto len = sparse.size(); + size_type cnt{}; + + other.reserve(len); + + for(auto &&elem: std::as_const(packed)) { + if(elem != tombstone) { + if(const auto page = pos_to_page(entity_to_pos(elem)); sparse[page] != nullptr) { + if(const auto sz = page + 1u; sz > other.size()) { + other.resize(sz, nullptr); + } + + other[page] = std::exchange(sparse[page], nullptr); + + if(++cnt == len) { + // early exit due to lack of pages + break; + } + } + } + } + + release_sparse_pages(); + sparse.swap(other); + + sparse.shrink_to_fit(); + packed.shrink_to_fit(); + } + + /** + * @brief Returns the extent of a sparse set. + * + * The extent of a sparse set is also the size of the internal sparse array. + * There is no guarantee that all pages have been allocated, nor that the + * internal packed array is be the same size. + * + * @return Extent of the sparse set. + */ + [[nodiscard]] size_type extent() const noexcept { + return sparse.size() * traits_type::page_size; + } + + /** + * @brief Returns the number of elements in a sparse set. + * + * The number of elements is also the size of the internal packed array. + * There is no guarantee that the internal sparse array has the same size. + * Usually the size of the internal sparse array is equal or greater than + * the one of the internal packed array. + * + * @return Number of elements. + */ + [[nodiscard]] size_type size() const noexcept { + return packed.size(); + } + + /** + * @brief Checks whether a sparse set is empty. + * @return True if the sparse set is empty, false otherwise. + */ + [[nodiscard]] bool empty() const noexcept { + return packed.empty(); + } + + /** + * @brief Checks whether a sparse set is fully packed. + * @return True if the sparse set is fully packed, false otherwise. + */ + [[nodiscard]] bool contiguous() const noexcept { + return (mode != deletion_policy::in_place) || (head == max_size); + } + + /** + * @brief Direct access to the internal packed array. + * @return A pointer to the internal packed array. + */ + [[nodiscard]] pointer data() const noexcept { + return packed.data(); + } + + /** + * @brief Returns an iterator to the beginning. + * + * If the sparse set is empty, the returned iterator will be equal to + * `end()`. + * + * @return An iterator to the first entity of the sparse set. + */ + [[nodiscard]] iterator begin() const noexcept { + const auto pos = static_cast(packed.size()); + return iterator{packed, pos}; + } + + /*! @copydoc begin */ + [[nodiscard]] const_iterator cbegin() const noexcept { + return begin(); + } + + /** + * @brief Returns an iterator to the end. + * @return An iterator to the element following the last entity of a sparse + * set. + */ + [[nodiscard]] iterator end() const noexcept { + return iterator{packed, {}}; + } + + /*! @copydoc end */ + [[nodiscard]] const_iterator cend() const noexcept { + return end(); + } + + /** + * @brief Returns a reverse iterator to the beginning. + * + * If the sparse set is empty, the returned iterator will be equal to + * `rend()`. + * + * @return An iterator to the first entity of the reversed internal packed + * array. + */ + [[nodiscard]] reverse_iterator rbegin() const noexcept { + return std::make_reverse_iterator(end()); + } + + /*! @copydoc rbegin */ + [[nodiscard]] const_reverse_iterator crbegin() const noexcept { + return rbegin(); + } + + /** + * @brief Returns a reverse iterator to the end. + * @return An iterator to the element following the last entity of the + * reversed sparse set. + */ + [[nodiscard]] reverse_iterator rend() const noexcept { + return std::make_reverse_iterator(begin()); + } + + /*! @copydoc rend */ + [[nodiscard]] const_reverse_iterator crend() const noexcept { + return rend(); + } + + /** + * @brief Finds an entity. + * @param entt A valid identifier. + * @return An iterator to the given entity if it's found, past the end + * iterator otherwise. + */ + [[nodiscard]] const_iterator find(const entity_type entt) const noexcept { + return contains(entt) ? to_iterator(entt) : end(); + } + + /** + * @brief Checks if a sparse set contains an entity. + * @param entt A valid identifier. + * @return True if the sparse set contains the entity, false otherwise. + */ + [[nodiscard]] bool contains(const entity_type entt) const noexcept { + const auto *elem = sparse_ptr(entt); + constexpr auto cap = traits_type::entity_mask; + constexpr auto mask = traits_type::to_integral(null) & ~cap; + // testing versions permits to avoid accessing the packed array + return elem && (((mask & traits_type::to_integral(entt)) ^ traits_type::to_integral(*elem)) < cap); + } + + /** + * @brief Returns the contained version for an identifier. + * @param entt A valid identifier. + * @return The version for the given identifier if present, the tombstone + * version otherwise. + */ + [[nodiscard]] version_type current(const entity_type entt) const noexcept { + const auto *elem = sparse_ptr(entt); + constexpr auto fallback = traits_type::to_version(tombstone); + return elem ? traits_type::to_version(*elem) : fallback; + } + + /** + * @brief Returns the position of an entity in a sparse set. + * + * @warning + * Attempting to get the position of an entity that doesn't belong to the + * sparse set results in undefined behavior. + * + * @param entt A valid identifier. + * @return The position of the entity in the sparse set. + */ + [[nodiscard]] size_type index(const entity_type entt) const noexcept { + ENTT_ASSERT(contains(entt), "Set does not contain entity"); + return entity_to_pos(sparse_ref(entt)); + } + + /** + * @brief Returns the entity at specified location. + * @param pos The position for which to return the entity. + * @return The entity at specified location. + */ + [[nodiscard]] entity_type operator[](const size_type pos) const noexcept { + ENTT_ASSERT(pos < packed.size(), "Index out of bounds"); + return packed[pos]; + } + + /** + * @brief Returns the element assigned to an entity, if any. + * + * @warning + * Attempting to use an entity that doesn't belong to the sparse set results + * in undefined behavior. + * + * @param entt A valid identifier. + * @return An opaque pointer to the element assigned to the entity, if any. + */ + [[nodiscard]] const void *value(const entity_type entt) const noexcept { + return get_at(index(entt)); + } + + /*! @copydoc value */ + [[nodiscard]] void *value(const entity_type entt) noexcept { + return const_cast(std::as_const(*this).value(entt)); + } + + /** + * @brief Assigns an entity to a sparse set. + * + * @warning + * Attempting to assign an entity that already belongs to the sparse set + * results in undefined behavior. + * + * @param entt A valid identifier. + * @param elem Optional opaque element to forward to mixins, if any. + * @return Iterator pointing to the emplaced element in case of success, the + * `end()` iterator otherwise. + */ + iterator push(const entity_type entt, const void *elem = nullptr) { + return try_emplace(entt, false, elem); + } + + /** + * @brief Assigns one or more entities to a sparse set. + * + * @warning + * Attempting to assign an entity that already belongs to the sparse set + * results in undefined behavior. + * + * @tparam It Type of input iterator. + * @param first An iterator to the first element of the range of entities. + * @param last An iterator past the last element of the range of entities. + * @return Iterator pointing to the first element inserted in case of + * success, the `end()` iterator otherwise. + */ + template + iterator push(It first, It last) { + auto curr = end(); + + for(; first != last; ++first) { + curr = try_emplace(*first, true); + } + + return curr; + } + + /** + * @brief Bump the version number of an entity. + * + * @warning + * Attempting to bump the version of an entity that doesn't belong to the + * sparse set results in undefined behavior. + * + * @param entt A valid identifier. + * @return The version of the given identifier. + */ + version_type bump(const entity_type entt) { + auto &elem = sparse_ref(entt); + ENTT_ASSERT(entt != null && elem != tombstone, "Cannot set the required version"); + elem = traits_type::combine(traits_type::to_integral(elem), traits_type::to_integral(entt)); + packed[entity_to_pos(elem)] = entt; + return traits_type::to_version(entt); + } + + /** + * @brief Erases an entity from a sparse set. + * + * @warning + * Attempting to erase an entity that doesn't belong to the sparse set + * results in undefined behavior. + * + * @param entt A valid identifier. + */ + void erase(const entity_type entt) { + const auto it = to_iterator(entt); + pop(it, it + 1u); + } + + /** + * @brief Erases entities from a set. + * + * @sa erase + * + * @tparam It Type of input iterator. + * @param first An iterator to the first element of the range of entities. + * @param last An iterator past the last element of the range of entities. + */ + template + void erase(It first, It last) { + if constexpr(std::is_same_v) { + pop(first, last); + } else { + for(; first != last; ++first) { + erase(*first); + } + } + } + + /** + * @brief Removes an entity from a sparse set if it exists. + * @param entt A valid identifier. + * @return True if the entity is actually removed, false otherwise. + */ + bool remove(const entity_type entt) { + return contains(entt) && (erase(entt), true); + } + + /** + * @brief Removes entities from a sparse set if they exist. + * @tparam It Type of input iterator. + * @param first An iterator to the first element of the range of entities. + * @param last An iterator past the last element of the range of entities. + * @return The number of entities actually removed. + */ + template + size_type remove(It first, It last) { + size_type count{}; + + if constexpr(std::is_same_v) { + while(first != last) { + while(first != last && !contains(*first)) { + ++first; + } + + const auto it = first; + + while(first != last && contains(*first)) { + ++first; + } + + count += static_cast(std::distance(it, first)); + erase(it, first); + } + } else { + for(; first != last; ++first) { + count += remove(*first); + } + } + + return count; + } + + /*! @brief Removes all tombstones from a sparse set. */ + void compact() { + if(mode == deletion_policy::in_place) { + size_type from = packed.size(); + size_type pos = std::exchange(head, max_size); + + for(; from && packed[from - 1u] == tombstone; --from) {} + + while(pos != max_size) { + if(const auto to = std::exchange(pos, entity_to_pos(packed[pos])); to < from) { + --from; + swap_or_move(from, to); + + packed[to] = packed[from]; + const auto elem = static_cast(to); + sparse_ref(packed[to]) = traits_type::combine(elem, traits_type::to_integral(packed[to])); + + for(; from && packed[from - 1u] == tombstone; --from) {} + } + } + + packed.erase(packed.begin() + static_cast(from), packed.end()); + } + } + + /** + * @brief Swaps two entities in a sparse set. + * + * For what it's worth, this function affects both the internal sparse array + * and the internal packed array. Users should not care of that anyway. + * + * @warning + * Attempting to swap entities that don't belong to the sparse set results + * in undefined behavior. + * + * @param lhs A valid identifier. + * @param rhs A valid identifier. + */ + void swap_elements(const entity_type lhs, const entity_type rhs) { + const auto from = index(lhs); + const auto to = index(rhs); + + // basic no-leak guarantee if swapping throws + swap_or_move(from, to); + swap_at(from, to); + } + + /** + * @brief Sort the first count elements according to the given comparison + * function. + * + * The comparison function object must return `true` if the first element + * is _less_ than the second one, `false` otherwise. The signature of the + * comparison function should be equivalent to the following: + * + * @code{.cpp} + * bool(const Entity, const Entity); + * @endcode + * + * Moreover, the comparison function object shall induce a + * _strict weak ordering_ on the values. + * + * The sort function object must offer a member function template + * `operator()` that accepts three arguments: + * + * * An iterator to the first element of the range to sort. + * * An iterator past the last element of the range to sort. + * * A comparison function to use to compare the elements. + * + * @tparam Compare Type of comparison function object. + * @tparam Sort Type of sort function object. + * @tparam Args Types of arguments to forward to the sort function object. + * @param length Number of elements to sort. + * @param compare A valid comparison function object. + * @param algo A valid sort function object. + * @param args Arguments to forward to the sort function object, if any. + */ + template + void sort_n(const size_type length, Compare compare, Sort algo = Sort{}, Args &&...args) { + ENTT_ASSERT((mode != deletion_policy::in_place) || (head == max_size), "Sorting with tombstones not allowed"); + ENTT_ASSERT(!(length > packed.size()), "Length exceeds the number of elements"); + + algo(packed.rend() - static_cast(length), packed.rend(), std::move(compare), std::forward(args)...); + + for(size_type pos{}; pos < length; ++pos) { + auto curr = pos; + auto next = index(packed[curr]); + + while(curr != next) { + const auto idx = index(packed[next]); + const auto entt = packed[curr]; + + swap_or_move(next, idx); + const auto elem = static_cast(curr); + sparse_ref(entt) = traits_type::combine(elem, traits_type::to_integral(packed[curr])); + curr = std::exchange(next, idx); + } + } + } + + /** + * @brief Sort all elements according to the given comparison function. + * + * @sa sort_n + * + * @tparam Compare Type of comparison function object. + * @tparam Sort Type of sort function object. + * @tparam Args Types of arguments to forward to the sort function object. + * @param compare A valid comparison function object. + * @param algo A valid sort function object. + * @param args Arguments to forward to the sort function object, if any. + */ + template + void sort(Compare compare, Sort algo = Sort{}, Args &&...args) { + const size_type len = (mode == deletion_policy::swap_only) ? head : packed.size(); + sort_n(len, std::move(compare), std::move(algo), std::forward(args)...); + } + + /** + * @brief Sort entities according to their order in a range. + * + * Entities that are part of both the sparse set and the range are ordered + * internally according to the order they have in the range.
+ * All other entities goes to the end of the sparse set and there are no + * guarantees on their order. + * + * @tparam It Type of input iterator. + * @param first An iterator to the first element of the range of entities. + * @param last An iterator past the last element of the range of entities. + * @return An iterator past the last of the elements actually shared. + */ + template + iterator sort_as(It first, It last) { + ENTT_ASSERT((mode != deletion_policy::in_place) || (head == max_size), "Sorting with tombstones not allowed"); + const size_type len = (mode == deletion_policy::swap_only) ? head : packed.size(); + auto it = end() - static_cast(len); + + for(const auto other = end(); (it != other) && (first != last); ++first) { + if(const auto curr = *first; contains(curr)) { + if(const auto entt = *it; entt != curr) { + // basic no-leak guarantee (with invalid state) if swapping throws + swap_elements(entt, curr); + } + + ++it; + } + } + + return it; + } + + /*! @brief Clears a sparse set. */ + void clear() { + pop_all(); + // sanity check to avoid subtle issues due to storage classes + ENTT_ASSERT((compact(), size()) == 0u, "Non-empty set"); + head = policy_to_head(); + packed.clear(); + } + + /** + * @brief Returns a type info object for the value type, if any. + * @return A type info object for the value type, if any. + */ + [[nodiscard]] const type_info &info() const noexcept { + return *descriptor; + } + + /*! @copydoc info */ + [[deprecated("use ::info instead")]] [[nodiscard]] const type_info &type() const noexcept { + return info(); + } + + /** + * @brief Forwards variables to derived classes, if any. + * @tparam Type Type of the element to forward. + * @param value The element to forward. + */ + template + void bind(Type &&value) noexcept { + bind_any(forward_as_any(std::forward(value))); + } + +private: + sparse_container_type sparse; + packed_container_type packed; + const type_info *descriptor; + deletion_policy mode; + size_type head; +}; + +} // namespace entt + +#endif + +// #include "entity/storage.hpp" +#ifndef ENTT_ENTITY_STORAGE_HPP +#define ENTT_ENTITY_STORAGE_HPP + +#include +#include +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "../core/bit.hpp" + +// #include "../core/iterator.hpp" + +// #include "../core/memory.hpp" + +// #include "../core/type_info.hpp" + +// #include "component.hpp" + +// #include "entity.hpp" + +// #include "fwd.hpp" + +// #include "sparse_set.hpp" + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +class storage_iterator final { + friend storage_iterator; + + using container_type = std::remove_const_t; + using alloc_traits = std::allocator_traits; + + using iterator_traits = std::iterator_traits, + typename alloc_traits::template rebind_traits::element_type>::const_pointer, + typename alloc_traits::template rebind_traits::element_type>::pointer>>; + +public: + using value_type = typename iterator_traits::value_type; + using pointer = typename iterator_traits::pointer; + using reference = typename iterator_traits::reference; + using difference_type = typename iterator_traits::difference_type; + using iterator_category = std::random_access_iterator_tag; + + constexpr storage_iterator() noexcept = default; + + constexpr storage_iterator(Container *ref, const difference_type idx) noexcept + : payload{ref}, + offset{idx} {} + + template, typename = std::enable_if_t> + constexpr storage_iterator(const storage_iterator, Page> &other) noexcept + : storage_iterator{other.payload, other.offset} {} + + constexpr storage_iterator &operator++() noexcept { + return --offset, *this; + } + + constexpr storage_iterator operator++(int) noexcept { + const storage_iterator orig = *this; + return ++(*this), orig; + } + + constexpr storage_iterator &operator--() noexcept { + return ++offset, *this; + } + + constexpr storage_iterator operator--(int) noexcept { + const storage_iterator orig = *this; + return operator--(), orig; + } + + constexpr storage_iterator &operator+=(const difference_type value) noexcept { + offset -= value; + return *this; + } + + constexpr storage_iterator operator+(const difference_type value) const noexcept { + storage_iterator copy = *this; + return (copy += value); + } + + constexpr storage_iterator &operator-=(const difference_type value) noexcept { + return (*this += -value); + } + + constexpr storage_iterator operator-(const difference_type value) const noexcept { + return (*this + -value); + } + + [[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept { + const auto pos = static_cast(index() - value); + return (*payload)[pos / Page][fast_mod(static_cast(pos), Page)]; + } + + [[nodiscard]] constexpr pointer operator->() const noexcept { + return std::addressof(operator[](0)); + } + + [[nodiscard]] constexpr reference operator*() const noexcept { + return operator[](0); + } + + [[nodiscard]] constexpr difference_type index() const noexcept { + return offset - 1; + } + +private: + Container *payload; + difference_type offset; +}; + +template +[[nodiscard]] constexpr std::ptrdiff_t operator-(const storage_iterator &lhs, const storage_iterator &rhs) noexcept { + return rhs.index() - lhs.index(); +} + +template +[[nodiscard]] constexpr bool operator==(const storage_iterator &lhs, const storage_iterator &rhs) noexcept { + return lhs.index() == rhs.index(); +} + +template +[[nodiscard]] constexpr bool operator!=(const storage_iterator &lhs, const storage_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +template +[[nodiscard]] constexpr bool operator<(const storage_iterator &lhs, const storage_iterator &rhs) noexcept { + return lhs.index() > rhs.index(); +} + +template +[[nodiscard]] constexpr bool operator>(const storage_iterator &lhs, const storage_iterator &rhs) noexcept { + return rhs < lhs; +} + +template +[[nodiscard]] constexpr bool operator<=(const storage_iterator &lhs, const storage_iterator &rhs) noexcept { + return !(lhs > rhs); +} + +template +[[nodiscard]] constexpr bool operator>=(const storage_iterator &lhs, const storage_iterator &rhs) noexcept { + return !(lhs < rhs); +} + +template +class extended_storage_iterator final { + template + friend class extended_storage_iterator; + +public: + using iterator_type = It; + using value_type = decltype(std::tuple_cat(std::make_tuple(*std::declval()), std::forward_as_tuple(*std::declval()...))); + using pointer = input_iterator_pointer; + using reference = value_type; + using difference_type = std::ptrdiff_t; + using iterator_category = std::input_iterator_tag; + using iterator_concept = std::forward_iterator_tag; + + constexpr extended_storage_iterator() + : it{} {} + + constexpr extended_storage_iterator(iterator_type base, Other... other) + : it{base, other...} {} + + template && ...) && (std::is_constructible_v && ...)>> + constexpr extended_storage_iterator(const extended_storage_iterator &other) + : it{other.it} {} + + constexpr extended_storage_iterator &operator++() noexcept { + return ++std::get(it), (++std::get(it), ...), *this; + } + + constexpr extended_storage_iterator operator++(int) noexcept { + const extended_storage_iterator orig = *this; + return ++(*this), orig; + } + + [[nodiscard]] constexpr pointer operator->() const noexcept { + return operator*(); + } + + [[nodiscard]] constexpr reference operator*() const noexcept { + return {*std::get(it), *std::get(it)...}; + } + + [[nodiscard]] constexpr iterator_type base() const noexcept { + return std::get(it); + } + + template + friend constexpr bool operator==(const extended_storage_iterator &, const extended_storage_iterator &) noexcept; + +private: + std::tuple it; +}; + +template +[[nodiscard]] constexpr bool operator==(const extended_storage_iterator &lhs, const extended_storage_iterator &rhs) noexcept { + return std::get<0>(lhs.it) == std::get<0>(rhs.it); +} + +template +[[nodiscard]] constexpr bool operator!=(const extended_storage_iterator &lhs, const extended_storage_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Storage implementation. + * + * Internal data structures arrange elements to maximize performance. There are + * no guarantees that objects are returned in the insertion order when iterate + * a storage. Do not make assumption on the order in any case. + * + * @warning + * Empty types aren't explicitly instantiated. Therefore, many of the functions + * normally available for non-empty types will not be available for empty ones. + * + * @tparam Type Element type. + * @tparam Entity A valid entity type. + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +class basic_storage: public basic_sparse_set::template rebind_alloc> { + using alloc_traits = std::allocator_traits; + static_assert(std::is_same_v, "Invalid value type"); + using container_type = std::vector>; + using underlying_type = basic_sparse_set>; + using underlying_iterator = typename underlying_type::basic_iterator; + using traits_type = component_traits; + + [[nodiscard]] auto &element_at(const std::size_t pos) const { + return payload[pos / traits_type::page_size][fast_mod(pos, traits_type::page_size)]; + } + + auto assure_at_least(const std::size_t pos) { + const auto idx = pos / traits_type::page_size; + + if(!(idx < payload.size())) { + auto curr = payload.size(); + allocator_type allocator{get_allocator()}; + payload.resize(idx + 1u, nullptr); + + ENTT_TRY { + for(const auto last = payload.size(); curr < last; ++curr) { + payload[curr] = alloc_traits::allocate(allocator, traits_type::page_size); + } + } + ENTT_CATCH { + payload.resize(curr); + ENTT_THROW; + } + } + + return payload[idx] + fast_mod(pos, traits_type::page_size); + } + + template + auto emplace_element(const Entity entt, const bool force_back, Args &&...args) { + const auto it = base_type::try_emplace(entt, force_back); + + ENTT_TRY { + auto *elem = to_address(assure_at_least(static_cast(it.index()))); + entt::uninitialized_construct_using_allocator(elem, get_allocator(), std::forward(args)...); + } + ENTT_CATCH { + base_type::pop(it, it + 1u); + ENTT_THROW; + } + + return it; + } + + void shrink_to_size(const std::size_t sz) { + const auto from = (sz + traits_type::page_size - 1u) / traits_type::page_size; + allocator_type allocator{get_allocator()}; + + for(auto pos = sz, length = base_type::size(); pos < length; ++pos) { + if constexpr(traits_type::in_place_delete) { + if(base_type::data()[pos] != tombstone) { + alloc_traits::destroy(allocator, std::addressof(element_at(pos))); + } + } else { + alloc_traits::destroy(allocator, std::addressof(element_at(pos))); + } + } + + for(auto pos = from, last = payload.size(); pos < last; ++pos) { + alloc_traits::deallocate(allocator, payload[pos], traits_type::page_size); + } + + payload.resize(from); + payload.shrink_to_fit(); + } + + void swap_at(const std::size_t lhs, const std::size_t rhs) { + using std::swap; + swap(element_at(lhs), element_at(rhs)); + } + + void move_to(const std::size_t lhs, const std::size_t rhs) { + auto &elem = element_at(lhs); + allocator_type allocator{get_allocator()}; + entt::uninitialized_construct_using_allocator(to_address(assure_at_least(rhs)), allocator, std::move(elem)); + alloc_traits::destroy(allocator, std::addressof(elem)); + } + +private: + [[nodiscard]] const void *get_at(const std::size_t pos) const final { + return std::addressof(element_at(pos)); + } + + void swap_or_move([[maybe_unused]] const std::size_t from, [[maybe_unused]] const std::size_t to) override { + static constexpr bool is_pinned_type = !(std::is_move_constructible_v && std::is_move_assignable_v); + // use a runtime value to avoid compile-time suppression that drives the code coverage tool crazy + ENTT_ASSERT((from + 1u) && !is_pinned_type, "Pinned type"); + + if constexpr(!is_pinned_type) { + if constexpr(traits_type::in_place_delete) { + (base_type::operator[](to) == tombstone) ? move_to(from, to) : swap_at(from, to); + } else { + swap_at(from, to); + } + } + } + +protected: + /** + * @brief Erases entities from a storage. + * @param first An iterator to the first element of the range of entities. + * @param last An iterator past the last element of the range of entities. + */ + void pop(underlying_iterator first, underlying_iterator last) override { + for(allocator_type allocator{get_allocator()}; first != last; ++first) { + // cannot use first.index() because it would break with cross iterators + auto &elem = element_at(base_type::index(*first)); + + if constexpr(traits_type::in_place_delete) { + base_type::in_place_pop(first); + alloc_traits::destroy(allocator, std::addressof(elem)); + } else { + auto &other = element_at(base_type::size() - 1u); + // destroying on exit allows reentrant destructors + [[maybe_unused]] auto unused = std::exchange(elem, std::move(other)); + alloc_traits::destroy(allocator, std::addressof(other)); + base_type::swap_and_pop(first); + } + } + } + + /*! @brief Erases all entities of a storage. */ + void pop_all() override { + allocator_type allocator{get_allocator()}; + + for(auto first = base_type::begin(); !(first.index() < 0); ++first) { + if constexpr(traits_type::in_place_delete) { + if(*first != tombstone) { + base_type::in_place_pop(first); + alloc_traits::destroy(allocator, std::addressof(element_at(static_cast(first.index())))); + } + } else { + base_type::swap_and_pop(first); + alloc_traits::destroy(allocator, std::addressof(element_at(static_cast(first.index())))); + } + } + } + + /** + * @brief Assigns an entity to a storage. + * @param entt A valid identifier. + * @param value Optional opaque value. + * @param force_back Force back insertion. + * @return Iterator pointing to the emplaced element. + */ + underlying_iterator try_emplace([[maybe_unused]] const Entity entt, [[maybe_unused]] const bool force_back, const void *value) override { + if(value != nullptr) { + if constexpr(std::is_copy_constructible_v) { + return emplace_element(entt, force_back, *static_cast(value)); + } else { + return base_type::end(); + } + } else { + if constexpr(std::is_default_constructible_v) { + return emplace_element(entt, force_back); + } else { + return base_type::end(); + } + } + } + +public: + /*! @brief Allocator type. */ + using allocator_type = Allocator; + /*! @brief Base type. */ + using base_type = underlying_type; + /*! @brief Element type. */ + using element_type = Type; + /*! @brief Type of the objects assigned to entities. */ + using value_type = element_type; + /*! @brief Underlying entity identifier. */ + using entity_type = Entity; + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + /*! @brief Signed integer type. */ + using difference_type = std::ptrdiff_t; + /*! @brief Pointer type to contained elements. */ + using pointer = typename container_type::pointer; + /*! @brief Constant pointer type to contained elements. */ + using const_pointer = typename alloc_traits::template rebind_traits::const_pointer; + /*! @brief Random access iterator type. */ + using iterator = internal::storage_iterator; + /*! @brief Constant random access iterator type. */ + using const_iterator = internal::storage_iterator; + /*! @brief Reverse iterator type. */ + using reverse_iterator = std::reverse_iterator; + /*! @brief Constant reverse iterator type. */ + using const_reverse_iterator = std::reverse_iterator; + /*! @brief Extended iterable storage proxy. */ + using iterable = iterable_adaptor>; + /*! @brief Constant extended iterable storage proxy. */ + using const_iterable = iterable_adaptor>; + /*! @brief Extended reverse iterable storage proxy. */ + using reverse_iterable = iterable_adaptor>; + /*! @brief Constant extended reverse iterable storage proxy. */ + using const_reverse_iterable = iterable_adaptor>; + /*! @brief Storage deletion policy. */ + static constexpr deletion_policy storage_policy{traits_type::in_place_delete}; + + /*! @brief Default constructor. */ + basic_storage() + : basic_storage{allocator_type{}} {} + + /** + * @brief Constructs an empty storage with a given allocator. + * @param allocator The allocator to use. + */ + explicit basic_storage(const allocator_type &allocator) + : base_type{type_id(), storage_policy, allocator}, + payload{allocator} {} + + /*! @brief Default copy constructor, deleted on purpose. */ + basic_storage(const basic_storage &) = delete; + + /** + * @brief Move constructor. + * @param other The instance to move from. + */ + basic_storage(basic_storage &&other) noexcept + : base_type{static_cast(other)}, + payload{std::move(other.payload)} {} + + /** + * @brief Allocator-extended move constructor. + * @param other The instance to move from. + * @param allocator The allocator to use. + */ + basic_storage(basic_storage &&other, const allocator_type &allocator) + : base_type{static_cast(other), allocator}, + payload{std::move(other.payload), allocator} { + ENTT_ASSERT(alloc_traits::is_always_equal::value || get_allocator() == other.get_allocator(), "Copying a storage is not allowed"); + } + + /*! @brief Default destructor. */ + // NOLINTNEXTLINE(bugprone-exception-escape) + ~basic_storage() override { + shrink_to_size(0u); + } + + /** + * @brief Default copy assignment operator, deleted on purpose. + * @return This storage. + */ + basic_storage &operator=(const basic_storage &) = delete; + + /** + * @brief Move assignment operator. + * @param other The instance to move from. + * @return This storage. + */ + basic_storage &operator=(basic_storage &&other) noexcept { + ENTT_ASSERT(alloc_traits::is_always_equal::value || get_allocator() == other.get_allocator(), "Copying a storage is not allowed"); + swap(other); + return *this; + } + + /** + * @brief Exchanges the contents with those of a given storage. + * @param other Storage to exchange the content with. + */ + void swap(basic_storage &other) noexcept { + using std::swap; + swap(payload, other.payload); + base_type::swap(other); + } + + /** + * @brief Returns the associated allocator. + * @return The associated allocator. + */ + [[nodiscard]] constexpr allocator_type get_allocator() const noexcept { + return payload.get_allocator(); + } + + /** + * @brief Increases the capacity of a storage. + * + * If the new capacity is greater than the current capacity, new storage is + * allocated, otherwise the method does nothing. + * + * @param cap Desired capacity. + */ + void reserve(const size_type cap) override { + if(cap != 0u) { + base_type::reserve(cap); + assure_at_least(cap - 1u); + } + } + + /** + * @brief Returns the number of elements that a storage has currently + * allocated space for. + * @return Capacity of the storage. + */ + [[nodiscard]] size_type capacity() const noexcept override { + return payload.size() * traits_type::page_size; + } + + /*! @brief Requests the removal of unused capacity. */ + void shrink_to_fit() override { + base_type::shrink_to_fit(); + shrink_to_size(base_type::size()); + } + + /** + * @brief Direct access to the array of objects. + * @return A pointer to the array of objects. + */ + [[nodiscard]] const_pointer raw() const noexcept { + return payload.data(); + } + + /*! @copydoc raw */ + [[nodiscard]] pointer raw() noexcept { + return payload.data(); + } + + /** + * @brief Returns an iterator to the beginning. + * + * If the storage is empty, the returned iterator will be equal to `end()`. + * + * @return An iterator to the first instance of the internal array. + */ + [[nodiscard]] const_iterator cbegin() const noexcept { + const auto pos = static_cast(base_type::size()); + return const_iterator{&payload, pos}; + } + + /*! @copydoc cbegin */ + [[nodiscard]] const_iterator begin() const noexcept { + return cbegin(); + } + + /*! @copydoc begin */ + [[nodiscard]] iterator begin() noexcept { + const auto pos = static_cast(base_type::size()); + return iterator{&payload, pos}; + } + + /** + * @brief Returns an iterator to the end. + * @return An iterator to the element following the last instance of the + * internal array. + */ + [[nodiscard]] const_iterator cend() const noexcept { + return const_iterator{&payload, {}}; + } + + /*! @copydoc cend */ + [[nodiscard]] const_iterator end() const noexcept { + return cend(); + } + + /*! @copydoc end */ + [[nodiscard]] iterator end() noexcept { + return iterator{&payload, {}}; + } + + /** + * @brief Returns a reverse iterator to the beginning. + * + * If the storage is empty, the returned iterator will be equal to `rend()`. + * + * @return An iterator to the first instance of the reversed internal array. + */ + [[nodiscard]] const_reverse_iterator crbegin() const noexcept { + return std::make_reverse_iterator(cend()); + } + + /*! @copydoc crbegin */ + [[nodiscard]] const_reverse_iterator rbegin() const noexcept { + return crbegin(); + } + + /*! @copydoc rbegin */ + [[nodiscard]] reverse_iterator rbegin() noexcept { + return std::make_reverse_iterator(end()); + } + + /** + * @brief Returns a reverse iterator to the end. + * @return An iterator to the element following the last instance of the + * reversed internal array. + */ + [[nodiscard]] const_reverse_iterator crend() const noexcept { + return std::make_reverse_iterator(cbegin()); + } + + /*! @copydoc crend */ + [[nodiscard]] const_reverse_iterator rend() const noexcept { + return crend(); + } + + /*! @copydoc rend */ + [[nodiscard]] reverse_iterator rend() noexcept { + return std::make_reverse_iterator(begin()); + } + + /** + * @brief Returns the object assigned to an entity. + * + * @warning + * Attempting to use an entity that doesn't belong to the storage results in + * undefined behavior. + * + * @param entt A valid identifier. + * @return The object assigned to the entity. + */ + [[nodiscard]] const value_type &get(const entity_type entt) const noexcept { + return element_at(base_type::index(entt)); + } + + /*! @copydoc get */ + [[nodiscard]] value_type &get(const entity_type entt) noexcept { + return const_cast(std::as_const(*this).get(entt)); + } + + /** + * @brief Returns the object assigned to an entity as a tuple. + * @param entt A valid identifier. + * @return The object assigned to the entity as a tuple. + */ + [[nodiscard]] std::tuple get_as_tuple(const entity_type entt) const noexcept { + return std::forward_as_tuple(get(entt)); + } + + /*! @copydoc get_as_tuple */ + [[nodiscard]] std::tuple get_as_tuple(const entity_type entt) noexcept { + return std::forward_as_tuple(get(entt)); + } + + /** + * @brief Assigns an entity to a storage and constructs its object. + * + * @warning + * Attempting to use an entity that already belongs to the storage results + * in undefined behavior. + * + * @tparam Args Types of arguments to use to construct the object. + * @param entt A valid identifier. + * @param args Parameters to use to construct an object for the entity. + * @return A reference to the newly created object. + */ + template + value_type &emplace(const entity_type entt, Args &&...args) { + if constexpr(std::is_aggregate_v && (sizeof...(Args) != 0u || !std::is_default_constructible_v)) { + const auto it = emplace_element(entt, false, Type{std::forward(args)...}); + return element_at(static_cast(it.index())); + } else { + const auto it = emplace_element(entt, false, std::forward(args)...); + return element_at(static_cast(it.index())); + } + } + + /** + * @brief Updates the instance assigned to a given entity in-place. + * @tparam Func Types of the function objects to invoke. + * @param entt A valid identifier. + * @param func Valid function objects. + * @return A reference to the updated instance. + */ + template + value_type &patch(const entity_type entt, Func &&...func) { + const auto idx = base_type::index(entt); + auto &elem = element_at(idx); + (std::forward(func)(elem), ...); + return elem; + } + + /** + * @brief Assigns one or more entities to a storage and constructs their + * objects from a given instance. + * + * @warning + * Attempting to assign an entity that already belongs to the storage + * results in undefined behavior. + * + * @tparam It Type of input iterator. + * @param first An iterator to the first element of the range of entities. + * @param last An iterator past the last element of the range of entities. + * @param value An instance of the object to construct. + * @return Iterator pointing to the first element inserted, if any. + */ + template + iterator insert(It first, It last, const value_type &value = {}) { + for(; first != last; ++first) { + emplace_element(*first, true, value); + } + + return begin(); + } + + /** + * @brief Assigns one or more entities to a storage and constructs their + * objects from a given range. + * + * @sa construct + * + * @tparam EIt Type of input iterator. + * @tparam CIt Type of input iterator. + * @param first An iterator to the first element of the range of entities. + * @param last An iterator past the last element of the range of entities. + * @param from An iterator to the first element of the range of objects. + * @return Iterator pointing to the first element inserted, if any. + */ + template::value_type, value_type>>> + iterator insert(EIt first, EIt last, CIt from) { + for(; first != last; ++first, ++from) { + emplace_element(*first, true, *from); + } + + return begin(); + } + + /** + * @brief Returns an iterable object to use to _visit_ a storage. + * + * The iterable object returns a tuple that contains the current entity and + * a reference to its element. + * + * @return An iterable object to use to _visit_ the storage. + */ + [[nodiscard]] iterable each() noexcept { + return iterable{{base_type::begin(), begin()}, {base_type::end(), end()}}; + } + + /*! @copydoc each */ + [[nodiscard]] const_iterable each() const noexcept { + return const_iterable{{base_type::cbegin(), cbegin()}, {base_type::cend(), cend()}}; + } + + /** + * @brief Returns a reverse iterable object to use to _visit_ a storage. + * + * @sa each + * + * @return A reverse iterable object to use to _visit_ the storage. + */ + [[nodiscard]] reverse_iterable reach() noexcept { + return reverse_iterable{{base_type::rbegin(), rbegin()}, {base_type::rend(), rend()}}; + } + + /*! @copydoc reach */ + [[nodiscard]] const_reverse_iterable reach() const noexcept { + return const_reverse_iterable{{base_type::crbegin(), crbegin()}, {base_type::crend(), crend()}}; + } + +private: + container_type payload; +}; + +/*! @copydoc basic_storage */ +template +class basic_storage::page_size == 0u>> + : public basic_sparse_set::template rebind_alloc> { + using alloc_traits = std::allocator_traits; + static_assert(std::is_same_v, "Invalid value type"); + using traits_type = component_traits; + +public: + /*! @brief Allocator type. */ + using allocator_type = Allocator; + /*! @brief Base type. */ + using base_type = basic_sparse_set>; + /*! @brief Element type. */ + using element_type = Type; + /*! @brief Type of the objects assigned to entities. */ + using value_type = void; + /*! @brief Underlying entity identifier. */ + using entity_type = Entity; + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + /*! @brief Signed integer type. */ + using difference_type = std::ptrdiff_t; + /*! @brief Extended iterable storage proxy. */ + using iterable = iterable_adaptor>; + /*! @brief Constant extended iterable storage proxy. */ + using const_iterable = iterable_adaptor>; + /*! @brief Extended reverse iterable storage proxy. */ + using reverse_iterable = iterable_adaptor>; + /*! @brief Constant extended reverse iterable storage proxy. */ + using const_reverse_iterable = iterable_adaptor>; + /*! @brief Storage deletion policy. */ + static constexpr deletion_policy storage_policy{traits_type::in_place_delete}; + + /*! @brief Default constructor. */ + basic_storage() + : basic_storage{allocator_type{}} {} + + /** + * @brief Constructs an empty container with a given allocator. + * @param allocator The allocator to use. + */ + explicit basic_storage(const allocator_type &allocator) + : base_type{type_id(), storage_policy, allocator} {} + + /*! @brief Default copy constructor, deleted on purpose. */ + basic_storage(const basic_storage &) = delete; + + /** + * @brief Move constructor. + * @param other The instance to move from. + */ + basic_storage(basic_storage &&other) noexcept = default; + + /** + * @brief Allocator-extended move constructor. + * @param other The instance to move from. + * @param allocator The allocator to use. + */ + basic_storage(basic_storage &&other, const allocator_type &allocator) + : base_type{std::move(other), allocator} {} + + /*! @brief Default destructor. */ + ~basic_storage() override = default; + + /** + * @brief Default copy assignment operator, deleted on purpose. + * @return This storage. + */ + basic_storage &operator=(const basic_storage &) = delete; + + /** + * @brief Move assignment operator. + * @param other The instance to move from. + * @return This storage. + */ + basic_storage &operator=(basic_storage &&other) noexcept = default; + + /** + * @brief Returns the associated allocator. + * @return The associated allocator. + */ + [[nodiscard]] constexpr allocator_type get_allocator() const noexcept { + // std::allocator has no cross constructors (waiting for C++20) + if constexpr(std::is_void_v && !std::is_constructible_v) { + return allocator_type{}; + } else { + return allocator_type{base_type::get_allocator()}; + } + } + + /** + * @brief Returns the object assigned to an entity, that is `void`. + * + * @warning + * Attempting to use an entity that doesn't belong to the storage results in + * undefined behavior. + * + * @param entt A valid identifier. + */ + void get([[maybe_unused]] const entity_type entt) const noexcept { + ENTT_ASSERT(base_type::contains(entt), "Invalid entity"); + } + + /** + * @brief Returns an empty tuple. + * @param entt A valid identifier. + * @return Returns an empty tuple. + */ + [[nodiscard]] std::tuple<> get_as_tuple([[maybe_unused]] const entity_type entt) const noexcept { + ENTT_ASSERT(base_type::contains(entt), "Invalid entity"); + return std::tuple{}; + } + + /** + * @brief Assigns an entity to a storage and constructs its object. + * + * @warning + * Attempting to use an entity that already belongs to the storage results + * in undefined behavior. + * + * @param entt A valid identifier. + */ + void emplace(const entity_type entt) { + base_type::try_emplace(entt, false); + } + + /** + * @brief Updates the instance assigned to a given entity in-place. + * @tparam Func Types of the function objects to invoke. + * @param entt A valid identifier. + * @param func Valid function objects. + */ + template + void patch([[maybe_unused]] const entity_type entt, Func &&...func) { + ENTT_ASSERT(base_type::contains(entt), "Invalid entity"); + (std::forward(func)(), ...); + } + + /** + * @brief Assigns entities to a storage. + * @tparam It Type of input iterator. + * @param first An iterator to the first element of the range of entities. + * @param last An iterator past the last element of the range of entities. + */ + template + void insert(It first, It last) { + for(; first != last; ++first) { + base_type::try_emplace(*first, true); + } + } + + /** + * @brief Returns an iterable object to use to _visit_ a storage. + * + * The iterable object returns a tuple that contains the current entity. + * + * @return An iterable object to use to _visit_ the storage. + */ + [[nodiscard]] iterable each() noexcept { + return iterable{base_type::begin(), base_type::end()}; + } + + /*! @copydoc each */ + [[nodiscard]] const_iterable each() const noexcept { + return const_iterable{base_type::cbegin(), base_type::cend()}; + } + + /** + * @brief Returns a reverse iterable object to use to _visit_ a storage. + * + * @sa each + * + * @return A reverse iterable object to use to _visit_ the storage. + */ + [[nodiscard]] reverse_iterable reach() noexcept { + return reverse_iterable{{base_type::rbegin()}, {base_type::rend()}}; + } + + /*! @copydoc reach */ + [[nodiscard]] const_reverse_iterable reach() const noexcept { + return const_reverse_iterable{{base_type::crbegin()}, {base_type::crend()}}; + } +}; + +/** + * @brief Swap-only entity storage specialization. + * @tparam Entity A valid entity type. + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +class basic_storage + : public basic_sparse_set { + using alloc_traits = std::allocator_traits; + static_assert(std::is_same_v, "Invalid value type"); + using underlying_iterator = typename basic_sparse_set::basic_iterator; + using traits_type = entt_traits; + + auto from_placeholder() noexcept { + const auto entt = traits_type::combine(static_cast(placeholder), {}); + ENTT_ASSERT(entt != null, "No more entities available"); + placeholder += static_cast(entt != null); + return entt; + } + + auto next() noexcept { + entity_type entt = from_placeholder(); + + while(base_type::current(entt) != traits_type::to_version(tombstone) && entt != null) { + entt = from_placeholder(); + } + + return entt; + } + +protected: + /*! @brief Erases all entities of a storage. */ + void pop_all() override { + base_type::pop_all(); + placeholder = {}; + } + + /** + * @brief Assigns an entity to a storage. + * @param hint A valid identifier. + * @return Iterator pointing to the emplaced element. + */ + underlying_iterator try_emplace(const Entity hint, const bool, const void *) override { + return base_type::find(generate(hint)); + } + +public: + /*! @brief Allocator type. */ + using allocator_type = Allocator; + /*! @brief Base type. */ + using base_type = basic_sparse_set; + /*! @brief Element type. */ + using element_type = Entity; + /*! @brief Type of the objects assigned to entities. */ + using value_type = void; + /*! @brief Underlying entity identifier. */ + using entity_type = Entity; + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + /*! @brief Signed integer type. */ + using difference_type = std::ptrdiff_t; + /*! @brief Extended iterable storage proxy. */ + using iterable = iterable_adaptor>; + /*! @brief Constant extended iterable storage proxy. */ + using const_iterable = iterable_adaptor>; + /*! @brief Extended reverse iterable storage proxy. */ + using reverse_iterable = iterable_adaptor>; + /*! @brief Constant extended reverse iterable storage proxy. */ + using const_reverse_iterable = iterable_adaptor>; + /*! @brief Storage deletion policy. */ + static constexpr deletion_policy storage_policy = deletion_policy::swap_only; + + /*! @brief Default constructor. */ + basic_storage() + : basic_storage{allocator_type{}} { + } + + /** + * @brief Constructs an empty container with a given allocator. + * @param allocator The allocator to use. + */ + explicit basic_storage(const allocator_type &allocator) + : base_type{type_id(), storage_policy, allocator} {} + + /*! @brief Default copy constructor, deleted on purpose. */ + basic_storage(const basic_storage &) = delete; + + /** + * @brief Move constructor. + * @param other The instance to move from. + */ + // NOLINTNEXTLINE(cppcoreguidelines-rvalue-reference-param-not-moved) + basic_storage(basic_storage &&other) noexcept + : base_type{static_cast(other)}, + placeholder{other.placeholder} {} + + /** + * @brief Allocator-extended move constructor. + * @param other The instance to move from. + * @param allocator The allocator to use. + */ + // NOLINTNEXTLINE(cppcoreguidelines-rvalue-reference-param-not-moved) + basic_storage(basic_storage &&other, const allocator_type &allocator) + : base_type{static_cast(other), allocator}, + placeholder{other.placeholder} {} + + /*! @brief Default destructor. */ + ~basic_storage() override = default; + + /** + * @brief Default copy assignment operator, deleted on purpose. + * @return This storage. + */ + basic_storage &operator=(const basic_storage &) = delete; + + /** + * @brief Move assignment operator. + * @param other The instance to move from. + * @return This storage. + */ + basic_storage &operator=(basic_storage &&other) noexcept { + placeholder = other.placeholder; + base_type::operator=(std::move(other)); + return *this; + } + + /** + * @brief Exchanges the contents with those of a given storage. + * @param other Storage to exchange the content with. + */ + void swap(basic_storage &other) noexcept { + using std::swap; + swap(placeholder, other.placeholder); + base_type::swap(other); + } + + /** + * @brief Returns the object assigned to an entity, that is `void`. + * + * @warning + * Attempting to use an entity that doesn't belong to the storage results in + * undefined behavior. + * + * @param entt A valid identifier. + */ + void get([[maybe_unused]] const entity_type entt) const noexcept { + ENTT_ASSERT(base_type::index(entt) < base_type::free_list(), "The requested entity is not a live one"); + } + + /** + * @brief Returns an empty tuple. + * @param entt A valid identifier. + * @return Returns an empty tuple. + */ + [[nodiscard]] std::tuple<> get_as_tuple([[maybe_unused]] const entity_type entt) const noexcept { + ENTT_ASSERT(base_type::index(entt) < base_type::free_list(), "The requested entity is not a live one"); + return std::tuple{}; + } + + /** + * @brief Creates a new identifier or recycles a destroyed one. + * @return A valid identifier. + */ + entity_type generate() { + const auto len = base_type::free_list(); + const auto entt = (len == base_type::size()) ? next() : base_type::data()[len]; + return *base_type::try_emplace(entt, true); + } + + /** + * @brief Creates a new identifier or recycles a destroyed one. + * + * If the requested identifier isn't in use, the suggested one is used. + * Otherwise, a new identifier is returned. + * + * @param hint Required identifier. + * @return A valid identifier. + */ + entity_type generate(const entity_type hint) { + if(hint != null && hint != tombstone) { + if(const auto curr = traits_type::construct(traits_type::to_entity(hint), base_type::current(hint)); curr == tombstone || !(base_type::index(curr) < base_type::free_list())) { + return *base_type::try_emplace(hint, true); + } + } + + return generate(); + } + + /** + * @brief Assigns each element in a range an identifier. + * @tparam It Type of mutable forward iterator. + * @param first An iterator to the first element of the range to generate. + * @param last An iterator past the last element of the range to generate. + */ + template + void generate(It first, It last) { + for(const auto sz = base_type::size(); first != last && base_type::free_list() != sz; ++first) { + *first = *base_type::try_emplace(base_type::data()[base_type::free_list()], true); + } + + for(; first != last; ++first) { + *first = *base_type::try_emplace(next(), true); + } + } + + /** + * @brief Updates a given identifier. + * @tparam Func Types of the function objects to invoke. + * @param entt A valid identifier. + * @param func Valid function objects. + */ + template + void patch([[maybe_unused]] const entity_type entt, Func &&...func) { + ENTT_ASSERT(base_type::index(entt) < base_type::free_list(), "The requested entity is not a live one"); + (std::forward(func)(), ...); + } + + /** + * @brief Returns an iterable object to use to _visit_ a storage. + * + * The iterable object returns a tuple that contains the current entity. + * + * @return An iterable object to use to _visit_ the storage. + */ + [[nodiscard]] iterable each() noexcept { + return std::as_const(*this).each(); + } + + /*! @copydoc each */ + [[nodiscard]] const_iterable each() const noexcept { + const auto it = base_type::cend(); + const auto offset = static_cast(base_type::free_list()); + return const_iterable{it - offset, it}; + } + + /** + * @brief Returns a reverse iterable object to use to _visit_ a storage. + * + * @sa each + * + * @return A reverse iterable object to use to _visit_ the storage. + */ + [[nodiscard]] reverse_iterable reach() noexcept { + return std::as_const(*this).reach(); + } + + /*! @copydoc reach */ + [[nodiscard]] const_reverse_iterable reach() const noexcept { + const auto it = base_type::crbegin(); + const auto offset = static_cast(base_type::free_list()); + return const_reverse_iterable{it, it + offset}; + } + + /** + * @brief Sets the starting identifier for generation. + * + * The version is ignored, regardless of the value. + * + * @param hint A valid identifier. + */ + void start_from(const entity_type hint) { + placeholder = static_cast(traits_type::to_entity(hint)); + } + +private: + size_type placeholder{}; +}; + +} // namespace entt + +#endif + +// #include "entity/view.hpp" +#ifndef ENTT_ENTITY_VIEW_HPP +#define ENTT_ENTITY_VIEW_HPP + +#include +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "../core/iterator.hpp" + +// #include "../core/type_traits.hpp" + +// #include "entity.hpp" + +// #include "fwd.hpp" + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +// NOLINTNEXTLINE(misc-redundant-expression) +static constexpr bool tombstone_check_v = ((sizeof...(Type) == 1u) && ... && (Type::storage_policy == deletion_policy::in_place)); + +template +const Type *view_placeholder() { + static_assert(std::is_same_v>, Type>, "Unexpected type"); + static const Type placeholder{}; + return &placeholder; +} + +template +[[nodiscard]] bool all_of(It first, const It last, const Entity entt) noexcept { + for(; (first != last) && (*first)->contains(entt); ++first) {} + return first == last; +} + +template +[[nodiscard]] bool none_of(It first, const It last, const Entity entt) noexcept { + for(; (first != last) && !(*first)->contains(entt); ++first) {} + return first == last; +} + +template +[[nodiscard]] bool fully_initialized(It first, const It last, const std::remove_pointer_t::value_type> *placeholder) noexcept { + for(; (first != last) && *first != placeholder; ++first) {} + return first == last; +} + +template +[[nodiscard]] Result view_pack(const View &view, const Other &other, std::index_sequence, std::index_sequence, std::index_sequence, std::index_sequence) { + Result elem{}; + // friend-initialization, avoid multiple calls to refresh + elem.pools = {view.template storage()..., other.template storage()...}; + auto filter_or_placeholder = [placeholder = elem.placeholder](auto *value) { return (value == nullptr) ? placeholder : value; }; + elem.filter = {filter_or_placeholder(view.template storage())..., filter_or_placeholder(other.template storage())...}; + elem.refresh(); + return elem; +} + +template +class view_iterator final { + template + friend class extended_view_iterator; + + using iterator_type = typename Type::const_iterator; + using iterator_traits = std::iterator_traits; + + [[nodiscard]] bool valid(const typename iterator_traits::value_type entt) const noexcept { + return (!Checked || (entt != tombstone)) + && ((Get == 1u) || (internal::all_of(pools.begin(), pools.begin() + index, entt) && internal::all_of(pools.begin() + index + 1, pools.end(), entt))) + && ((Exclude == 0u) || internal::none_of(filter.begin(), filter.end(), entt)); + } + + void seek_next() { + for(constexpr iterator_type sentinel{}; it != sentinel && !valid(*it); ++it) {} + } + +public: + using value_type = typename iterator_traits::value_type; + using pointer = typename iterator_traits::pointer; + using reference = typename iterator_traits::reference; + using difference_type = typename iterator_traits::difference_type; + using iterator_category = std::forward_iterator_tag; + + constexpr view_iterator() noexcept + : it{}, + pools{}, + filter{}, + index{} {} + + view_iterator(iterator_type first, std::array value, std::array excl, const std::size_t idx) noexcept + : it{first}, + pools{value}, + filter{excl}, + index{static_cast(idx)} { + ENTT_ASSERT((Get != 1u) || (Exclude != 0u) || pools[0u]->policy() == deletion_policy::in_place, "Non in-place storage view iterator"); + seek_next(); + } + + view_iterator &operator++() noexcept { + ++it; + seek_next(); + return *this; + } + + view_iterator operator++(int) noexcept { + const view_iterator orig = *this; + return ++(*this), orig; + } + + [[nodiscard]] pointer operator->() const noexcept { + return &*it; + } + + [[nodiscard]] reference operator*() const noexcept { + return *operator->(); + } + + template + friend constexpr bool operator==(const view_iterator &, const view_iterator &) noexcept; + +private: + iterator_type it; + std::array pools; + std::array filter; + difference_type index; +}; + +template +[[nodiscard]] constexpr bool operator==(const view_iterator &lhs, const view_iterator &rhs) noexcept { + return lhs.it == rhs.it; +} + +template +[[nodiscard]] constexpr bool operator!=(const view_iterator &lhs, const view_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +template +class extended_view_iterator final { + template + [[nodiscard]] auto dereference(std::index_sequence) const noexcept { + return std::tuple_cat(std::make_tuple(*it), static_cast(const_cast *>(std::get(it.pools)))->get_as_tuple(*it)...); + } + +public: + using iterator_type = It; + using value_type = decltype(std::tuple_cat(std::make_tuple(*std::declval()), std::declval().get_as_tuple({})...)); + using pointer = input_iterator_pointer; + using reference = value_type; + using difference_type = std::ptrdiff_t; + using iterator_category = std::input_iterator_tag; + using iterator_concept = std::forward_iterator_tag; + + constexpr extended_view_iterator() + : it{} {} + + extended_view_iterator(iterator_type from) + : it{from} {} + + extended_view_iterator &operator++() noexcept { + return ++it, *this; + } + + extended_view_iterator operator++(int) noexcept { + const extended_view_iterator orig = *this; + return ++(*this), orig; + } + + [[nodiscard]] reference operator*() const noexcept { + return dereference(std::index_sequence_for{}); + } + + [[nodiscard]] pointer operator->() const noexcept { + return operator*(); + } + + [[nodiscard]] constexpr iterator_type base() const noexcept { + return it; + } + + template + friend bool constexpr operator==(const extended_view_iterator &, const extended_view_iterator &) noexcept; + +private: + It it; +}; + +template +[[nodiscard]] constexpr bool operator==(const extended_view_iterator &lhs, const extended_view_iterator &rhs) noexcept { + return lhs.it == rhs.it; +} + +template +[[nodiscard]] constexpr bool operator!=(const extended_view_iterator &lhs, const extended_view_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief View implementation. + * + * Primary template isn't defined on purpose. All the specializations give a + * compile-time error, but for a few reasonable cases. + * + * @b Important + * + * View iterators aren't invalidated if: + * + * * New elements are added to the storage iterated by the view. + * * The entity currently returned is modified (for example, elements are added + * or removed from it). + * * The entity currently returned is destroyed. + * + * In all other cases, modifying the storage iterated by a view in any way can + * invalidate all iterators. + */ +template +class basic_view; + +/** + * @brief Basic storage view implementation. + * @warning For internal use only, backward compatibility not guaranteed. + * @tparam Type Common type among all storage types. + * @tparam Checked True to enable the tombstone check, false otherwise. + * @tparam Get Number of storage iterated by the view. + * @tparam Exclude Number of storage used to filter the view. + */ +template +class basic_common_view { + static_assert(std::is_same_v>, Type>, "Unexpected type"); + + template + friend Return internal::view_pack(const View &, const Other &, std::index_sequence, std::index_sequence, std::index_sequence, std::index_sequence); + + [[nodiscard]] auto offset() const noexcept { + ENTT_ASSERT(index != Get, "Invalid view"); + return (pools[index]->policy() == deletion_policy::swap_only) ? pools[index]->free_list() : pools[index]->size(); + } + + void unchecked_refresh() noexcept { + index = 0u; + + if constexpr(Get > 1u) { + for(size_type pos{1u}; pos < Get; ++pos) { + if(pools[pos]->size() < pools[index]->size()) { + index = pos; + } + } + } + } + +protected: + /*! @cond TURN_OFF_DOXYGEN */ + basic_common_view() noexcept { + for(size_type pos{}, last = filter.size(); pos < last; ++pos) { + filter[pos] = placeholder; + } + } + + basic_common_view(std::array value, std::array excl) noexcept + : pools{value}, + filter{excl}, + index{Get} { + unchecked_refresh(); + } + + [[nodiscard]] const Type *pool_at(const std::size_t pos) const noexcept { + return pools[pos]; + } + + void pool_at(const std::size_t pos, const Type *elem) noexcept { + ENTT_ASSERT(elem != nullptr, "Unexpected element"); + pools[pos] = elem; + refresh(); + } + + [[nodiscard]] const Type *filter_at(const std::size_t pos) const noexcept { + return (filter[pos] == placeholder) ? nullptr : filter[pos]; + } + + void filter_at(const std::size_t pos, const Type *elem) noexcept { + ENTT_ASSERT(elem != nullptr, "Unexpected element"); + filter[pos] = elem; + } + + [[nodiscard]] bool none_of(const typename Type::entity_type entt) const noexcept { + return internal::none_of(filter.begin(), filter.end(), entt); + } + + void use(const std::size_t pos) noexcept { + index = (index != Get) ? pos : Get; + } + /*! @endcond */ + +public: + /*! @brief Common type among all storage types. */ + using common_type = Type; + /*! @brief Underlying entity identifier. */ + using entity_type = typename Type::entity_type; + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + /*! @brief Signed integer type. */ + using difference_type = std::ptrdiff_t; + /*! @brief Forward iterator type. */ + using iterator = internal::view_iterator; + + /*! @brief Updates the internal leading view if required. */ + void refresh() noexcept { + size_type pos = static_cast(index != Get) * Get; + for(; pos < Get && pools[pos] != nullptr; ++pos) {} + + if(pos == Get) { + unchecked_refresh(); + } + } + + /** + * @brief Returns the leading storage of a view, if any. + * @return The leading storage of the view. + */ + [[nodiscard]] const common_type *handle() const noexcept { + return (index != Get) ? pools[index] : nullptr; + } + + /** + * @brief Estimates the number of entities iterated by the view. + * @return Estimated number of entities iterated by the view. + */ + [[nodiscard]] size_type size_hint() const noexcept { + return (index != Get) ? offset() : size_type{}; + } + + /** + * @brief Returns an iterator to the first entity of the view. + * + * If the view is empty, the returned iterator will be equal to `end()`. + * + * @return An iterator to the first entity of the view. + */ + [[nodiscard]] iterator begin() const noexcept { + return (index != Get) ? iterator{pools[index]->end() - static_cast(offset()), pools, filter, index} : iterator{}; + } + + /** + * @brief Returns an iterator that is past the last entity of the view. + * @return An iterator to the entity following the last entity of the view. + */ + [[nodiscard]] iterator end() const noexcept { + return (index != Get) ? iterator{pools[index]->end(), pools, filter, index} : iterator{}; + } + + /** + * @brief Returns the first entity of the view, if any. + * @return The first entity of the view if one exists, the null entity + * otherwise. + */ + [[nodiscard]] entity_type front() const noexcept { + const auto it = begin(); + return it != end() ? *it : null; + } + + /** + * @brief Returns the last entity of the view, if any. + * @return The last entity of the view if one exists, the null entity + * otherwise. + */ + [[nodiscard]] entity_type back() const noexcept { + if(index != Get) { + auto it = pools[index]->rbegin(); + const auto last = it + static_cast(offset()); + for(const auto idx = static_cast(index); it != last && !(internal::all_of(pools.begin(), pools.begin() + idx, *it) && internal::all_of(pools.begin() + idx + 1, pools.end(), *it) && internal::none_of(filter.begin(), filter.end(), *it)); ++it) {} + return it == last ? null : *it; + } + + return null; + } + + /** + * @brief Finds an entity. + * @param entt A valid identifier. + * @return An iterator to the given entity if it's found, past the end + * iterator otherwise. + */ + [[nodiscard]] iterator find(const entity_type entt) const noexcept { + return contains(entt) ? iterator{pools[index]->find(entt), pools, filter, index} : end(); + } + + /** + * @brief Checks if a view is fully initialized. + * @return True if the view is fully initialized, false otherwise. + */ + [[nodiscard]] explicit operator bool() const noexcept { + return (index != Get) && internal::fully_initialized(filter.begin(), filter.end(), placeholder); + } + + /** + * @brief Checks if a view contains an entity. + * @param entt A valid identifier. + * @return True if the view contains the given entity, false otherwise. + */ + [[nodiscard]] bool contains(const entity_type entt) const noexcept { + return (index != Get) + && internal::all_of(pools.begin(), pools.end(), entt) + && internal::none_of(filter.begin(), filter.end(), entt) + && pools[index]->index(entt) < offset(); + } + +private: + std::array pools{}; + std::array filter{}; + const common_type *placeholder{internal::view_placeholder()}; + size_type index{Get}; +}; + +/** + * @brief General purpose view. + * + * This view visits all entities that are at least in the given storage. During + * initialization, it also looks at the number of elements available for each + * storage and uses the smallest set in order to get a performance boost. + * + * @sa basic_view + * + * @tparam Get Types of storage iterated by the view. + * @tparam Exclude Types of storage used to filter the view. + */ +template +class basic_view, exclude_t, std::enable_if_t<(sizeof...(Get) != 0u)>> + : public basic_common_view, internal::tombstone_check_v, sizeof...(Get), sizeof...(Exclude)> { + using base_type = basic_common_view, internal::tombstone_check_v, sizeof...(Get), sizeof...(Exclude)>; + + template + using element_at = type_list_element_t>; + + template + static constexpr std::size_t index_of = type_list_index_v, type_list>; + + template + [[nodiscard]] auto get(const typename base_type::entity_type entt, std::index_sequence) const noexcept { + return std::tuple_cat(storage()->get_as_tuple(entt)...); + } + + template + [[nodiscard]] auto dispatch_get(const std::tuple &curr) const { + if constexpr(Curr == Other) { + return std::forward_as_tuple(std::get(curr)...); + } else { + return storage()->get_as_tuple(std::get<0>(curr)); + } + } + + template + void each(Func &func, std::index_sequence) const { + for(const auto curr: storage()->each()) { + if(const auto entt = std::get<0>(curr); (!internal::tombstone_check_v || (entt != tombstone)) && ((Curr == Index || base_type::pool_at(Index)->contains(entt)) && ...) && base_type::none_of(entt)) { + if constexpr(is_applicable_v{}, std::declval().get({})))>) { + std::apply(func, std::tuple_cat(std::make_tuple(entt), dispatch_get(curr)...)); + } else { + std::apply(func, std::tuple_cat(dispatch_get(curr)...)); + } + } + } + } + + template + void pick_and_each(Func &func, std::index_sequence seq) const { + if(const auto *view = base_type::handle(); view != nullptr) { + ((view == base_type::pool_at(Index) ? each(func, seq) : void()), ...); + } + } + +public: + /*! @brief Common type among all storage types. */ + using common_type = typename base_type::common_type; + /*! @brief Underlying entity identifier. */ + using entity_type = typename base_type::entity_type; + /*! @brief Unsigned integer type. */ + using size_type = typename base_type::size_type; + /*! @brief Signed integer type. */ + using difference_type = std::ptrdiff_t; + /*! @brief Forward iterator type. */ + using iterator = typename base_type::iterator; + /*! @brief Iterable view type. */ + using iterable = iterable_adaptor>; + + /*! @brief Default constructor to use to create empty, invalid views. */ + basic_view() noexcept + : base_type{} {} + + /** + * @brief Constructs a view from a set of storage classes. + * @param value The storage for the types to iterate. + * @param excl The storage for the types used to filter the view. + */ + basic_view(Get &...value, Exclude &...excl) noexcept + : base_type{{&value...}, {&excl...}} { + } + + /** + * @brief Constructs a view from a set of storage classes. + * @param value The storage for the types to iterate. + * @param excl The storage for the types used to filter the view. + */ + basic_view(std::tuple value, std::tuple excl = {}) noexcept + : basic_view{std::make_from_tuple(std::tuple_cat(value, excl))} {} + + /** + * @brief Forces a view to use a given element to drive iterations + * @tparam Type Type of element to use to drive iterations. + */ + template + void use() noexcept { + use>(); + } + + /** + * @brief Forces a view to use a given element to drive iterations + * @tparam Index Index of the element to use to drive iterations. + */ + template + void use() noexcept { + base_type::use(Index); + } + + /** + * @brief Returns the storage for a given element type, if any. + * @tparam Type Type of element of which to return the storage. + * @return The storage for the given element type. + */ + template + [[nodiscard]] auto *storage() const noexcept { + return storage>(); + } + + /** + * @brief Returns the storage for a given index, if any. + * @tparam Index Index of the storage to return. + * @return The storage for the given index. + */ + template + [[nodiscard]] auto *storage() const noexcept { + if constexpr(Index < sizeof...(Get)) { + return static_cast *>(const_cast> *>(base_type::pool_at(Index))); + } else { + return static_cast *>(const_cast> *>(base_type::filter_at(Index - sizeof...(Get)))); + } + } + + /** + * @brief Assigns a storage to a view. + * @tparam Type Type of storage to assign to the view. + * @param elem A storage to assign to the view. + */ + template + void storage(Type &elem) noexcept { + storage>(elem); + } + + /** + * @brief Assigns a storage to a view. + * @tparam Index Index of the storage to assign to the view. + * @tparam Type Type of storage to assign to the view. + * @param elem A storage to assign to the view. + */ + template + void storage(Type &elem) noexcept { + static_assert(std::is_convertible_v &>, "Unexpected type"); + + if constexpr(Index < sizeof...(Get)) { + base_type::pool_at(Index, &elem); + } else { + base_type::filter_at(Index - sizeof...(Get), &elem); + } + } + + /** + * @brief Returns the elements assigned to the given entity. + * @param entt A valid identifier. + * @return The elements assigned to the given entity. + */ + [[nodiscard]] decltype(auto) operator[](const entity_type entt) const { + return get(entt); + } + + /** + * @brief Returns the elements assigned to the given entity. + * @tparam Type Type of the element to get. + * @tparam Other Other types of elements to get. + * @param entt A valid identifier. + * @return The elements assigned to the entity. + */ + template + [[nodiscard]] decltype(auto) get(const entity_type entt) const { + return get, index_of...>(entt); + } + + /** + * @brief Returns the elements assigned to the given entity. + * @tparam Index Indexes of the elements to get. + * @param entt A valid identifier. + * @return The elements assigned to the entity. + */ + template + [[nodiscard]] decltype(auto) get(const entity_type entt) const { + if constexpr(sizeof...(Index) == 0) { + return get(entt, std::index_sequence_for{}); + } else if constexpr(sizeof...(Index) == 1) { + return (storage()->get(entt), ...); + } else { + return std::tuple_cat(storage()->get_as_tuple(entt)...); + } + } + + /** + * @brief Iterates entities and elements and applies the given function + * object to them. + * + * The signature of the function must be equivalent to one of the following + * (non-empty types only, constness as requested): + * + * @code{.cpp} + * void(const entity_type, Type &...); + * void(Type &...); + * @endcode + * + * @tparam Func Type of the function object to invoke. + * @param func A valid function object. + */ + template + void each(Func func) const { + pick_and_each(func, std::index_sequence_for{}); + } + + /** + * @brief Returns an iterable object to use to _visit_ a view. + * + * The iterable object returns a tuple that contains the current entity and + * a set of references to its non-empty elements. The _constness_ of the + * elements is as requested. + * + * @return An iterable object to use to _visit_ the view. + */ + [[nodiscard]] iterable each() const noexcept { + return iterable{base_type::begin(), base_type::end()}; + } + + /** + * @brief Combines a view and a storage in _more specific_ view. + * @tparam OGet Type of storage to combine the view with. + * @param other The storage for the type to combine the view with. + * @return A more specific view. + */ + template + [[nodiscard]] std::enable_if_t, basic_view, exclude_t>> operator|(OGet &other) const noexcept { + return *this | basic_view, exclude_t<>>{other}; + } + + /** + * @brief Combines two views in a _more specific_ one. + * @tparam OGet Element list of the view to combine with. + * @tparam OExclude Filter list of the view to combine with. + * @param other The view to combine with. + * @return A more specific view. + */ + template + [[nodiscard]] auto operator|(const basic_view, exclude_t> &other) const noexcept { + return internal::view_pack, exclude_t>>( + *this, other, std::index_sequence_for{}, std::index_sequence_for{}, std::index_sequence_for{}, std::index_sequence_for{}); + } +}; + +/** + * @brief Basic storage view implementation. + * @warning For internal use only, backward compatibility not guaranteed. + * @tparam Type Common type among all storage types. + * @tparam Policy Storage policy. + */ +template +class basic_storage_view { + static_assert(std::is_same_v>, Type>, "Unexpected type"); + +protected: + /*! @cond TURN_OFF_DOXYGEN */ + basic_storage_view() noexcept = default; + + basic_storage_view(const Type *value) noexcept + : leading{value} { + ENTT_ASSERT(leading->policy() == Policy, "Unexpected storage policy"); + } + /*! @endcond */ + +public: + /*! @brief Common type among all storage types. */ + using common_type = Type; + /*! @brief Underlying entity identifier. */ + using entity_type = typename common_type::entity_type; + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + /*! @brief Signed integer type. */ + using difference_type = std::ptrdiff_t; + /*! @brief Random access iterator type. */ + using iterator = std::conditional_t, typename common_type::iterator>; + /*! @brief Reverse iterator type. */ + using reverse_iterator = std::conditional_t; + + /** + * @brief Returns the leading storage of a view, if any. + * @return The leading storage of the view. + */ + [[nodiscard]] const common_type *handle() const noexcept { + return leading; + } + + /** + * @brief Returns the number of entities that have the given element. + * @tparam Pol Dummy template parameter used for sfinae purposes only. + * @return Number of entities that have the given element. + */ + template + [[nodiscard]] std::enable_if_t size() const noexcept { + if constexpr(Policy == deletion_policy::swap_and_pop) { + return leading ? leading->size() : size_type{}; + } else { + static_assert(Policy == deletion_policy::swap_only, "Unexpected storage policy"); + return leading ? leading->free_list() : size_type{}; + } + } + + /** + * @brief Estimates the number of entities iterated by the view. + * @tparam Pol Dummy template parameter used for sfinae purposes only. + * @return Estimated number of entities iterated by the view. + */ + template + [[nodiscard]] std::enable_if_t size_hint() const noexcept { + return leading ? leading->size() : size_type{}; + } + + /** + * @brief Checks whether a view is empty. + * @tparam Pol Dummy template parameter used for sfinae purposes only. + * @return True if the view is empty, false otherwise. + */ + template + [[nodiscard]] std::enable_if_t empty() const noexcept { + if constexpr(Policy == deletion_policy::swap_and_pop) { + return !leading || leading->empty(); + } else { + static_assert(Policy == deletion_policy::swap_only, "Unexpected storage policy"); + return !leading || (leading->free_list() == 0u); + } + } + + /** + * @brief Returns an iterator to the first entity of the view. + * + * If the view is empty, the returned iterator will be equal to `end()`. + * + * @return An iterator to the first entity of the view. + */ + [[nodiscard]] iterator begin() const noexcept { + if constexpr(Policy == deletion_policy::swap_and_pop) { + return leading ? leading->begin() : iterator{}; + } else if constexpr(Policy == deletion_policy::swap_only) { + return leading ? (leading->end() - static_cast(leading->free_list())) : iterator{}; + } else { + static_assert(Policy == deletion_policy::in_place, "Unexpected storage policy"); + return leading ? iterator{leading->begin(), {leading}, {}, 0u} : iterator{}; + } + } + + /** + * @brief Returns an iterator that is past the last entity of the view. + * @return An iterator to the entity following the last entity of the view. + */ + [[nodiscard]] iterator end() const noexcept { + if constexpr(Policy == deletion_policy::swap_and_pop || Policy == deletion_policy::swap_only) { + return leading ? leading->end() : iterator{}; + } else { + static_assert(Policy == deletion_policy::in_place, "Unexpected storage policy"); + return leading ? iterator{leading->end(), {leading}, {}, 0u} : iterator{}; + } + } + + /** + * @brief Returns an iterator to the first entity of the reversed view. + * + * If the view is empty, the returned iterator will be equal to `rend()`. + * + * @tparam Pol Dummy template parameter used for sfinae purposes only. + * @return An iterator to the first entity of the reversed view. + */ + template + [[nodiscard]] std::enable_if_t rbegin() const noexcept { + return leading ? leading->rbegin() : reverse_iterator{}; + } + + /** + * @brief Returns an iterator that is past the last entity of the reversed + * view. + * @tparam Pol Dummy template parameter used for sfinae purposes only. + * @return An iterator to the entity following the last entity of the + * reversed view. + */ + template + [[nodiscard]] std::enable_if_t rend() const noexcept { + if constexpr(Policy == deletion_policy::swap_and_pop) { + return leading ? leading->rend() : reverse_iterator{}; + } else { + static_assert(Policy == deletion_policy::swap_only, "Unexpected storage policy"); + return leading ? (leading->rbegin() + static_cast(leading->free_list())) : reverse_iterator{}; + } + } + + /** + * @brief Returns the first entity of the view, if any. + * @return The first entity of the view if one exists, the null entity + * otherwise. + */ + [[nodiscard]] entity_type front() const noexcept { + if constexpr(Policy == deletion_policy::swap_and_pop) { + return empty() ? null : *leading->begin(); + } else if constexpr(Policy == deletion_policy::swap_only) { + return empty() ? null : *(leading->end() - static_cast(leading->free_list())); + } else { + static_assert(Policy == deletion_policy::in_place, "Unexpected storage policy"); + const auto it = begin(); + return (it == end()) ? null : *it; + } + } + + /** + * @brief Returns the last entity of the view, if any. + * @return The last entity of the view if one exists, the null entity + * otherwise. + */ + [[nodiscard]] entity_type back() const noexcept { + if constexpr(Policy == deletion_policy::swap_and_pop || Policy == deletion_policy::swap_only) { + return empty() ? null : *leading->rbegin(); + } else { + static_assert(Policy == deletion_policy::in_place, "Unexpected storage policy"); + + if(leading) { + auto it = leading->rbegin(); + const auto last = leading->rend(); + for(; (it != last) && (*it == tombstone); ++it) {} + return it == last ? null : *it; + } + + return null; + } + } + + /** + * @brief Finds an entity. + * @param entt A valid identifier. + * @return An iterator to the given entity if it's found, past the end + * iterator otherwise. + */ + [[nodiscard]] iterator find(const entity_type entt) const noexcept { + if constexpr(Policy == deletion_policy::swap_and_pop) { + return leading ? leading->find(entt) : iterator{}; + } else if constexpr(Policy == deletion_policy::swap_only) { + const auto it = leading ? leading->find(entt) : iterator{}; + return leading && (static_cast(it.index()) < leading->free_list()) ? it : iterator{}; + } else { + return leading ? iterator{leading->find(entt), {leading}, {}, 0u} : iterator{}; + } + } + + /** + * @brief Checks if a view is fully initialized. + * @return True if the view is fully initialized, false otherwise. + */ + [[nodiscard]] explicit operator bool() const noexcept { + return (leading != nullptr); + } + + /** + * @brief Checks if a view contains an entity. + * @param entt A valid identifier. + * @return True if the view contains the given entity, false otherwise. + */ + [[nodiscard]] bool contains(const entity_type entt) const noexcept { + if constexpr(Policy == deletion_policy::swap_and_pop || Policy == deletion_policy::in_place) { + return leading && leading->contains(entt); + } else { + static_assert(Policy == deletion_policy::swap_only, "Unexpected storage policy"); + return leading && leading->contains(entt) && (leading->index(entt) < leading->free_list()); + } + } + +private: + const common_type *leading{}; +}; + +/** + * @brief Storage view specialization. + * + * This specialization offers a boost in terms of performance. It can access the + * underlying data structure directly and avoid superfluous checks. + * + * @sa basic_view + * + * @tparam Get Type of storage iterated by the view. + */ +template +class basic_view, exclude_t<>> + : public basic_storage_view { + using base_type = basic_storage_view; + +public: + /*! @brief Common type among all storage types. */ + using common_type = typename base_type::common_type; + /*! @brief Underlying entity identifier. */ + using entity_type = typename base_type::entity_type; + /*! @brief Unsigned integer type. */ + using size_type = typename base_type::size_type; + /*! @brief Signed integer type. */ + using difference_type = std::ptrdiff_t; + /*! @brief Random access iterator type. */ + using iterator = typename base_type::iterator; + /*! @brief Reverse iterator type. */ + using reverse_iterator = typename base_type::reverse_iterator; + /*! @brief Iterable view type. */ + using iterable = std::conditional_t>, decltype(std::declval().each())>; + + /*! @brief Default constructor to use to create empty, invalid views. */ + basic_view() noexcept + : base_type{} {} + + /** + * @brief Constructs a view from a storage class. + * @param value The storage for the type to iterate. + */ + basic_view(Get &value) noexcept + : base_type{&value} { + } + + /** + * @brief Constructs a view from a storage class. + * @param value The storage for the type to iterate. + */ + basic_view(std::tuple value, std::tuple<> = {}) noexcept + : basic_view{std::get<0>(value)} {} + + /** + * @brief Returns the storage for a given element type, if any. + * @tparam Type Type of element of which to return the storage. + * @return The storage for the given element type. + */ + template + [[nodiscard]] auto *storage() const noexcept { + static_assert(std::is_same_v, typename Get::element_type>, "Invalid element type"); + return storage<0>(); + } + + /** + * @brief Returns the storage for a given index, if any. + * @tparam Index Index of the storage to return. + * @return The storage for the given index. + */ + template + [[nodiscard]] auto *storage() const noexcept { + static_assert(Index == 0u, "Index out of bounds"); + return static_cast(const_cast *>(base_type::handle())); + } + + /** + * @brief Assigns a storage to a view. + * @param elem A storage to assign to the view. + */ + void storage(Get &elem) noexcept { + storage<0>(elem); + } + + /** + * @brief Assigns a storage to a view. + * @tparam Index Index of the storage to assign to the view. + * @param elem A storage to assign to the view. + */ + template + void storage(Get &elem) noexcept { + static_assert(Index == 0u, "Index out of bounds"); + *this = basic_view{elem}; + } + + /** + * @brief Returns a pointer to the underlying storage. + * @return A pointer to the underlying storage. + */ + [[nodiscard]] Get *operator->() const noexcept { + return storage(); + } + + /** + * @brief Returns the element assigned to the given entity. + * @param entt A valid identifier. + * @return The element assigned to the given entity. + */ + [[nodiscard]] decltype(auto) operator[](const entity_type entt) const { + return storage()->get(entt); + } + + /** + * @brief Returns the element assigned to the given entity. + * @tparam Elem Type of the element to get. + * @param entt A valid identifier. + * @return The element assigned to the entity. + */ + template + [[nodiscard]] decltype(auto) get(const entity_type entt) const { + static_assert(std::is_same_v, typename Get::element_type>, "Invalid element type"); + return get<0>(entt); + } + + /** + * @brief Returns the element assigned to the given entity. + * @tparam Index Index of the element to get. + * @param entt A valid identifier. + * @return The element assigned to the entity. + */ + template + [[nodiscard]] decltype(auto) get(const entity_type entt) const { + if constexpr(sizeof...(Index) == 0) { + return storage()->get_as_tuple(entt); + } else { + return storage()->get(entt); + } + } + + /** + * @brief Iterates entities and elements and applies the given function + * object to them. + * + * The signature of the function must be equivalent to one of the following + * (non-empty types only, constness as requested): + * + * @code{.cpp} + * void(const entity_type, Type &); + * void(typename Type &); + * @endcode + * + * @tparam Func Type of the function object to invoke. + * @param func A valid function object. + */ + template + void each(Func func) const { + if constexpr(is_applicable_v{}, std::declval().get({})))>) { + for(const auto pack: each()) { + std::apply(func, pack); + } + } else if constexpr(Get::storage_policy == deletion_policy::swap_and_pop || Get::storage_policy == deletion_policy::swap_only) { + if constexpr(std::is_void_v) { + for(size_type pos = base_type::size(); pos; --pos) { + func(); + } + } else { + if(const auto len = static_cast(base_type::size()); len != 0) { + for(auto last = storage()->end(), first = last - len; first != last; ++first) { + func(*first); + } + } + } + } else { + static_assert(Get::storage_policy == deletion_policy::in_place, "Unexpected storage policy"); + + for(const auto pack: each()) { + std::apply([&func](const auto, auto &&...elem) { func(std::forward(elem)...); }, pack); + } + } + } + + /** + * @brief Returns an iterable object to use to _visit_ a view. + * + * The iterable object returns a tuple that contains the current entity and + * a reference to its element if it's a non-empty one. The _constness_ of + * the element is as requested. + * + * @return An iterable object to use to _visit_ the view. + */ + [[nodiscard]] iterable each() const noexcept { + if constexpr(Get::storage_policy == deletion_policy::swap_and_pop || Get::storage_policy == deletion_policy::swap_only) { + return base_type::handle() ? storage()->each() : iterable{}; + } else { + static_assert(Get::storage_policy == deletion_policy::in_place, "Unexpected storage policy"); + return iterable{base_type::begin(), base_type::end()}; + } + } + + /** + * @brief Combines a view and a storage in _more specific_ view. + * @tparam OGet Type of storage to combine the view with. + * @param other The storage for the type to combine the view with. + * @return A more specific view. + */ + template + [[nodiscard]] std::enable_if_t, basic_view, exclude_t<>>> operator|(OGet &other) const noexcept { + return *this | basic_view, exclude_t<>>{other}; + } + + /** + * @brief Combines two views in a _more specific_ one. + * @tparam OGet Element list of the view to combine with. + * @tparam OExclude Filter list of the view to combine with. + * @param other The view to combine with. + * @return A more specific view. + */ + template + [[nodiscard]] auto operator|(const basic_view, exclude_t> &other) const noexcept { + return internal::view_pack, exclude_t>>( + *this, other, std::index_sequence_for{}, std::index_sequence_for<>{}, std::index_sequence_for{}, std::index_sequence_for{}); + } +}; + +/** + * @brief Deduction guide. + * @tparam Type Type of storage classes used to create the view. + * @param storage The storage for the types to iterate. + */ +template +basic_view(Type &...storage) -> basic_view, exclude_t<>>; + +/** + * @brief Deduction guide. + * @tparam Get Types of elements iterated by the view. + * @tparam Exclude Types of elements used to filter the view. + */ +template +basic_view(std::tuple, std::tuple = {}) -> basic_view, exclude_t>; + +} // namespace entt + +#endif + +// #include "graph/adjacency_matrix.hpp" +#ifndef ENTT_GRAPH_ADJACENCY_MATRIX_HPP +#define ENTT_GRAPH_ADJACENCY_MATRIX_HPP + +#include +#include +#include +#include +#include +#include +// #include "../config/config.h" +#ifndef ENTT_CONFIG_CONFIG_H +#define ENTT_CONFIG_CONFIG_H + +// #include "version.h" +#ifndef ENTT_CONFIG_VERSION_H +#define ENTT_CONFIG_VERSION_H + +// #include "macro.h" +#ifndef ENTT_CONFIG_MACRO_H +#define ENTT_CONFIG_MACRO_H + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#define ENTT_STR(arg) #arg +#define ENTT_XSTR(arg) ENTT_STR(arg) + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*) + +#define ENTT_VERSION_MAJOR 3 +#define ENTT_VERSION_MINOR 16 +#define ENTT_VERSION_PATCH 0 + +#define ENTT_VERSION \ + ENTT_XSTR(ENTT_VERSION_MAJOR) \ + "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH) + +// NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION) +# define ENTT_CONSTEXPR +# define ENTT_THROW throw +# define ENTT_TRY try +# define ENTT_CATCH catch(...) +#else +# define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20) +# define ENTT_THROW +# define ENTT_TRY if(true) +# define ENTT_CATCH if(false) +#endif + +#if __has_include() +# include +# +# if defined(__cpp_consteval) +# define ENTT_CONSTEVAL consteval +# endif +#endif + +#ifndef ENTT_CONSTEVAL +# define ENTT_CONSTEVAL constexpr +#endif + +#ifdef ENTT_USE_ATOMIC +# include +# define ENTT_MAYBE_ATOMIC(Type) std::atomic +#else +# define ENTT_MAYBE_ATOMIC(Type) Type +#endif + +#ifndef ENTT_ID_TYPE +# include +# define ENTT_ID_TYPE std::uint32_t +#else +# include // provides coverage for types in the std namespace +#endif + +#ifndef ENTT_SPARSE_PAGE +# define ENTT_SPARSE_PAGE 4096 +#endif + +#ifndef ENTT_PACKED_PAGE +# define ENTT_PACKED_PAGE 1024 +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT +# define ENTT_ASSERT(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT +# include +# define ENTT_ASSERT(condition, msg) assert(((condition) && (msg))) +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg) +#endif + +#define ENTT_FAIL(msg) ENTT_ASSERT(false, msg); + +#ifdef ENTT_NO_ETO +# define ENTT_ETO_TYPE(Type) void +#else +# define ENTT_ETO_TYPE(Type) Type +#endif + +#ifdef ENTT_NO_MIXIN +# define ENTT_STORAGE(Mixin, ...) __VA_ARGS__ +#else +# define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__> +#endif + +#ifdef ENTT_STANDARD_CPP +# define ENTT_NONSTD false +#else +# define ENTT_NONSTD true +# if defined __clang__ || defined __GNUC__ +# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ +# define ENTT_PRETTY_FUNCTION_PREFIX '=' +# define ENTT_PRETTY_FUNCTION_SUFFIX ']' +# elif defined _MSC_VER +# define ENTT_PRETTY_FUNCTION __FUNCSIG__ +# define ENTT_PRETTY_FUNCTION_PREFIX '<' +# define ENTT_PRETTY_FUNCTION_SUFFIX '>' +# endif +#endif + +#ifndef ENTT_EXPORT +# if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER +# define ENTT_EXPORT __declspec(dllexport) +# define ENTT_IMPORT __declspec(dllimport) +# define ENTT_HIDDEN +# elif defined __GNUC__ && __GNUC__ >= 4 +# define ENTT_EXPORT __attribute__((visibility("default"))) +# define ENTT_IMPORT __attribute__((visibility("default"))) +# define ENTT_HIDDEN __attribute__((visibility("hidden"))) +# else /* Unsupported compiler */ +# define ENTT_EXPORT +# define ENTT_IMPORT +# define ENTT_HIDDEN +# endif +#endif + +#ifndef ENTT_API +# if defined ENTT_API_EXPORT +# define ENTT_API ENTT_EXPORT +# elif defined ENTT_API_IMPORT +# define ENTT_API ENTT_IMPORT +# else /* No API */ +# define ENTT_API +# endif +#endif + +#if defined _MSC_VER +# pragma detect_mismatch("entt.version", ENTT_VERSION) +# pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY)) +# pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE)) +# pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD)) +#endif + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + +// #include "../core/iterator.hpp" +#ifndef ENTT_CORE_ITERATOR_HPP +#define ENTT_CORE_ITERATOR_HPP + +#include +#include +#include +#include + +namespace entt { + +/** + * @brief Helper type to use as pointer with input iterators. + * @tparam Type of wrapped value. + */ +template +struct input_iterator_pointer final { + /*! @brief Value type. */ + using value_type = Type; + /*! @brief Pointer type. */ + using pointer = Type *; + /*! @brief Reference type. */ + using reference = Type &; + + /** + * @brief Constructs a proxy object by move. + * @param val Value to use to initialize the proxy object. + */ + constexpr input_iterator_pointer(value_type &&val) noexcept(std::is_nothrow_move_constructible_v) + : value{std::move(val)} {} + + /** + * @brief Access operator for accessing wrapped values. + * @return A pointer to the wrapped value. + */ + [[nodiscard]] constexpr pointer operator->() noexcept { + return std::addressof(value); + } + + /** + * @brief Dereference operator for accessing wrapped values. + * @return A reference to the wrapped value. + */ + [[nodiscard]] constexpr reference operator*() noexcept { + return value; + } + +private: + Type value; +}; + +/** + * @brief Plain iota iterator (waiting for C++20). + * @tparam Type Value type. + */ +template +class iota_iterator final { + static_assert(std::is_integral_v, "Not an integral type"); + +public: + /*! @brief Value type, likely an integral one. */ + using value_type = Type; + /*! @brief Invalid pointer type. */ + using pointer = void; + /*! @brief Non-reference type, same as value type. */ + using reference = value_type; + /*! @brief Difference type. */ + using difference_type = std::ptrdiff_t; + /*! @brief Iterator category. */ + using iterator_category = std::input_iterator_tag; + + /*! @brief Default constructor. */ + constexpr iota_iterator() noexcept + : current{} {} + + /** + * @brief Constructs an iota iterator from a given value. + * @param init The initial value assigned to the iota iterator. + */ + constexpr iota_iterator(const value_type init) noexcept + : current{init} {} + + /** + * @brief Pre-increment operator. + * @return This iota iterator. + */ + constexpr iota_iterator &operator++() noexcept { + return ++current, *this; + } + + /** + * @brief Post-increment operator. + * @return This iota iterator. + */ + constexpr iota_iterator operator++(int) noexcept { + const iota_iterator orig = *this; + return ++(*this), orig; + } + + /** + * @brief Dereference operator. + * @return The underlying value. + */ + [[nodiscard]] constexpr reference operator*() const noexcept { + return current; + } + +private: + value_type current; +}; + +/** + * @brief Comparison operator. + * @tparam Type Value type of the iota iterator. + * @param lhs A properly initialized iota iterator. + * @param rhs A properly initialized iota iterator. + * @return True if the two iterators are identical, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator==(const iota_iterator &lhs, const iota_iterator &rhs) noexcept { + return *lhs == *rhs; +} + +/** + * @brief Comparison operator. + * @tparam Type Value type of the iota iterator. + * @param lhs A properly initialized iota iterator. + * @param rhs A properly initialized iota iterator. + * @return True if the two iterators differ, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator!=(const iota_iterator &lhs, const iota_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +/** + * @brief Utility class to create an iterable object from a pair of iterators. + * @tparam It Type of iterator. + * @tparam Sentinel Type of sentinel. + */ +template +struct iterable_adaptor final { + /*! @brief Value type. */ + using value_type = typename std::iterator_traits::value_type; + /*! @brief Iterator type. */ + using iterator = It; + /*! @brief Sentinel type. */ + using sentinel = Sentinel; + + /*! @brief Default constructor. */ + constexpr iterable_adaptor() noexcept(std::is_nothrow_default_constructible_v && std::is_nothrow_default_constructible_v) + : first{}, + last{} {} + + /** + * @brief Creates an iterable object from a pair of iterators. + * @param from Begin iterator. + * @param to End iterator. + */ + constexpr iterable_adaptor(iterator from, sentinel to) noexcept(std::is_nothrow_move_constructible_v && std::is_nothrow_move_constructible_v) + : first{std::move(from)}, + last{std::move(to)} {} + + /** + * @brief Returns an iterator to the beginning. + * @return An iterator to the first element of the range. + */ + [[nodiscard]] constexpr iterator begin() const noexcept { + return first; + } + + /** + * @brief Returns an iterator to the end. + * @return An iterator to the element following the last element of the + * range. + */ + [[nodiscard]] constexpr sentinel end() const noexcept { + return last; + } + + /*! @copydoc begin */ + [[nodiscard]] constexpr iterator cbegin() const noexcept { + return begin(); + } + + /*! @copydoc end */ + [[nodiscard]] constexpr sentinel cend() const noexcept { + return end(); + } + +private: + It first; + Sentinel last; +}; + +} // namespace entt + +#endif + +// #include "fwd.hpp" +#ifndef ENTT_GRAPH_FWD_HPP +#define ENTT_GRAPH_FWD_HPP + +#include +#include +// #include "../core/fwd.hpp" +#ifndef ENTT_CORE_FWD_HPP +#define ENTT_CORE_FWD_HPP + +#include +#include +// #include "../config/config.h" +#ifndef ENTT_CONFIG_CONFIG_H +#define ENTT_CONFIG_CONFIG_H + +// #include "version.h" +#ifndef ENTT_CONFIG_VERSION_H +#define ENTT_CONFIG_VERSION_H + +// #include "macro.h" +#ifndef ENTT_CONFIG_MACRO_H +#define ENTT_CONFIG_MACRO_H + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#define ENTT_STR(arg) #arg +#define ENTT_XSTR(arg) ENTT_STR(arg) + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*) + +#define ENTT_VERSION_MAJOR 3 +#define ENTT_VERSION_MINOR 16 +#define ENTT_VERSION_PATCH 0 + +#define ENTT_VERSION \ + ENTT_XSTR(ENTT_VERSION_MAJOR) \ + "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH) + +// NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION) +# define ENTT_CONSTEXPR +# define ENTT_THROW throw +# define ENTT_TRY try +# define ENTT_CATCH catch(...) +#else +# define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20) +# define ENTT_THROW +# define ENTT_TRY if(true) +# define ENTT_CATCH if(false) +#endif + +#if __has_include() +# include +# +# if defined(__cpp_consteval) +# define ENTT_CONSTEVAL consteval +# endif +#endif + +#ifndef ENTT_CONSTEVAL +# define ENTT_CONSTEVAL constexpr +#endif + +#ifdef ENTT_USE_ATOMIC +# include +# define ENTT_MAYBE_ATOMIC(Type) std::atomic +#else +# define ENTT_MAYBE_ATOMIC(Type) Type +#endif + +#ifndef ENTT_ID_TYPE +# include +# define ENTT_ID_TYPE std::uint32_t +#else +# include // provides coverage for types in the std namespace +#endif + +#ifndef ENTT_SPARSE_PAGE +# define ENTT_SPARSE_PAGE 4096 +#endif + +#ifndef ENTT_PACKED_PAGE +# define ENTT_PACKED_PAGE 1024 +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT +# define ENTT_ASSERT(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT +# include +# define ENTT_ASSERT(condition, msg) assert(((condition) && (msg))) +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg) +#endif + +#define ENTT_FAIL(msg) ENTT_ASSERT(false, msg); + +#ifdef ENTT_NO_ETO +# define ENTT_ETO_TYPE(Type) void +#else +# define ENTT_ETO_TYPE(Type) Type +#endif + +#ifdef ENTT_NO_MIXIN +# define ENTT_STORAGE(Mixin, ...) __VA_ARGS__ +#else +# define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__> +#endif + +#ifdef ENTT_STANDARD_CPP +# define ENTT_NONSTD false +#else +# define ENTT_NONSTD true +# if defined __clang__ || defined __GNUC__ +# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ +# define ENTT_PRETTY_FUNCTION_PREFIX '=' +# define ENTT_PRETTY_FUNCTION_SUFFIX ']' +# elif defined _MSC_VER +# define ENTT_PRETTY_FUNCTION __FUNCSIG__ +# define ENTT_PRETTY_FUNCTION_PREFIX '<' +# define ENTT_PRETTY_FUNCTION_SUFFIX '>' +# endif +#endif + +#ifndef ENTT_EXPORT +# if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER +# define ENTT_EXPORT __declspec(dllexport) +# define ENTT_IMPORT __declspec(dllimport) +# define ENTT_HIDDEN +# elif defined __GNUC__ && __GNUC__ >= 4 +# define ENTT_EXPORT __attribute__((visibility("default"))) +# define ENTT_IMPORT __attribute__((visibility("default"))) +# define ENTT_HIDDEN __attribute__((visibility("hidden"))) +# else /* Unsupported compiler */ +# define ENTT_EXPORT +# define ENTT_IMPORT +# define ENTT_HIDDEN +# endif +#endif + +#ifndef ENTT_API +# if defined ENTT_API_EXPORT +# define ENTT_API ENTT_EXPORT +# elif defined ENTT_API_IMPORT +# define ENTT_API ENTT_IMPORT +# else /* No API */ +# define ENTT_API +# endif +#endif + +#if defined _MSC_VER +# pragma detect_mismatch("entt.version", ENTT_VERSION) +# pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY)) +# pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE)) +# pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD)) +#endif + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +namespace entt { + +/*! @brief Possible modes of an any object. */ +enum class any_policy : std::uint8_t { + /*! @brief Default mode, no element available. */ + empty, + /*! @brief Owning mode, dynamically allocated element. */ + dynamic, + /*! @brief Owning mode, embedded element. */ + embedded, + /*! @brief Aliasing mode, non-const reference. */ + ref, + /*! @brief Const aliasing mode, const reference. */ + cref +}; + +// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) +template +class basic_any; + +/*! @brief Alias declaration for type identifiers. */ +using id_type = ENTT_ID_TYPE; + +/*! @brief Alias declaration for the most common use case. */ +using any = basic_any<>; + +template +class compressed_pair; + +template +class basic_hashed_string; + +/*! @brief Aliases for common character types. */ +using hashed_string = basic_hashed_string; + +/*! @brief Aliases for common character types. */ +using hashed_wstring = basic_hashed_string; + +// NOLINTNEXTLINE(bugprone-forward-declaration-namespace) +struct type_info; + +} // namespace entt + +#endif + + +namespace entt { + +/*! @brief Undirected graph category tag. */ +struct directed_tag {}; + +/*! @brief Directed graph category tag. */ +struct undirected_tag: directed_tag {}; + +template> +class adjacency_matrix; + +template> +class basic_flow; + +/*! @brief Alias declaration for the most common use case. */ +using flow = basic_flow<>; + +} // namespace entt + +#endif + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +class edge_iterator { + using size_type = std::size_t; + + void find_next() noexcept { + for(; pos != last && !it[static_cast(pos)]; pos += offset) {} + } + +public: + using value_type = std::pair; + using pointer = input_iterator_pointer; + using reference = value_type; + using difference_type = std::ptrdiff_t; + using iterator_category = std::input_iterator_tag; + using iterator_concept = std::forward_iterator_tag; + + constexpr edge_iterator() noexcept = default; + + // NOLINTNEXTLINE(bugprone-easily-swappable-parameters) + constexpr edge_iterator(It base, const size_type vertices, const size_type from, const size_type to, const size_type step) noexcept + : it{std::move(base)}, + vert{vertices}, + pos{from}, + last{to}, + offset{step} { + find_next(); + } + + constexpr edge_iterator &operator++() noexcept { + pos += offset; + find_next(); + return *this; + } + + constexpr edge_iterator operator++(int) noexcept { + const edge_iterator orig = *this; + return ++(*this), orig; + } + + [[nodiscard]] constexpr reference operator*() const noexcept { + return *operator->(); + } + + [[nodiscard]] constexpr pointer operator->() const noexcept { + return std::make_pair(pos / vert, pos % vert); + } + + template + friend constexpr bool operator==(const edge_iterator &, const edge_iterator &) noexcept; + +private: + It it{}; + size_type vert{}; + size_type pos{}; + size_type last{}; + size_type offset{}; +}; + +template +[[nodiscard]] constexpr bool operator==(const edge_iterator &lhs, const edge_iterator &rhs) noexcept { + return lhs.pos == rhs.pos; +} + +template +[[nodiscard]] constexpr bool operator!=(const edge_iterator &lhs, const edge_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Basic implementation of a directed adjacency matrix. + * @tparam Category Either a directed or undirected category tag. + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +class adjacency_matrix { + using alloc_traits = std::allocator_traits; + static_assert(std::is_base_of_v, "Invalid graph category"); + static_assert(std::is_same_v, "Invalid value type"); + using container_type = std::vector>; + +public: + /*! @brief Allocator type. */ + using allocator_type = Allocator; + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + /*! @brief Vertex type. */ + using vertex_type = size_type; + /*! @brief Edge type. */ + using edge_type = std::pair; + /*! @brief Vertex iterator type. */ + using vertex_iterator = iota_iterator; + /*! @brief Edge iterator type. */ + using edge_iterator = internal::edge_iterator; + /*! @brief Out-edge iterator type. */ + using out_edge_iterator = edge_iterator; + /*! @brief In-edge iterator type. */ + using in_edge_iterator = edge_iterator; + /*! @brief Graph category tag. */ + using graph_category = Category; + + /*! @brief Default constructor. */ + adjacency_matrix() noexcept(noexcept(allocator_type{})) + : adjacency_matrix{0u} { + } + + /** + * @brief Constructs an empty container with a given allocator. + * @param allocator The allocator to use. + */ + explicit adjacency_matrix(const allocator_type &allocator) noexcept + : adjacency_matrix{0u, allocator} {} + + /** + * @brief Constructs an empty container with a given allocator and user + * supplied number of vertices. + * @param vertices Number of vertices. + * @param allocator The allocator to use. + */ + adjacency_matrix(const size_type vertices, const allocator_type &allocator = allocator_type{}) + : matrix{vertices * vertices, allocator}, + vert{vertices} {} + + /*! @brief Default copy constructor. */ + adjacency_matrix(const adjacency_matrix &) = default; + + /** + * @brief Allocator-extended copy constructor. + * @param other The instance to copy from. + * @param allocator The allocator to use. + */ + adjacency_matrix(const adjacency_matrix &other, const allocator_type &allocator) + : matrix{other.matrix, allocator}, + vert{other.vert} {} + + /*! @brief Default move constructor. */ + adjacency_matrix(adjacency_matrix &&) noexcept = default; + + /** + * @brief Allocator-extended move constructor. + * @param other The instance to move from. + * @param allocator The allocator to use. + */ + adjacency_matrix(adjacency_matrix &&other, const allocator_type &allocator) + : matrix{std::move(other.matrix), allocator}, + vert{other.vert} {} + + /*! @brief Default destructor. */ + ~adjacency_matrix() = default; + + /** + * @brief Default copy assignment operator. + * @return This container. + */ + adjacency_matrix &operator=(const adjacency_matrix &) = default; + + /** + * @brief Default move assignment operator. + * @return This container. + */ + adjacency_matrix &operator=(adjacency_matrix &&) noexcept = default; + + /** + * @brief Exchanges the contents with those of a given adjacency matrix. + * @param other Adjacency matrix to exchange the content with. + */ + void swap(adjacency_matrix &other) noexcept { + using std::swap; + swap(matrix, other.matrix); + swap(vert, other.vert); + } + + /** + * @brief Returns the associated allocator. + * @return The associated allocator. + */ + [[nodiscard]] constexpr allocator_type get_allocator() const noexcept { + return matrix.get_allocator(); + } + + /*! @brief Clears the adjacency matrix. */ + void clear() noexcept { + matrix.clear(); + vert = {}; + } + + /** + * @brief Returns true if an adjacency matrix is empty, false otherwise. + * + * @warning + * Potentially expensive, try to avoid it on hot paths. + * + * @return True if the adjacency matrix is empty, false otherwise. + */ + [[nodiscard]] bool empty() const noexcept { + const auto iterable = edges(); + return (iterable.begin() == iterable.end()); + } + + /** + * @brief Returns the number of vertices. + * @return The number of vertices. + */ + [[nodiscard]] size_type size() const noexcept { + return vert; + } + + /** + * @brief Returns an iterable object to visit all vertices of a matrix. + * @return An iterable object to visit all vertices of a matrix. + */ + [[nodiscard]] iterable_adaptor vertices() const noexcept { + return {0u, vert}; + } + + /** + * @brief Returns an iterable object to visit all edges of a matrix. + * @return An iterable object to visit all edges of a matrix. + */ + [[nodiscard]] iterable_adaptor edges() const noexcept { + const auto it = matrix.cbegin(); + const auto sz = matrix.size(); + return {{it, vert, 0u, sz, 1u}, {it, vert, sz, sz, 1u}}; + } + + /** + * @brief Returns an iterable object to visit all out-edges of a vertex. + * @param vertex The vertex of which to return all out-edges. + * @return An iterable object to visit all out-edges of a vertex. + */ + [[nodiscard]] iterable_adaptor out_edges(const vertex_type vertex) const noexcept { + const auto it = matrix.cbegin(); + const auto from = vertex * vert; + const auto to = from + vert; + return {{it, vert, from, to, 1u}, {it, vert, to, to, 1u}}; + } + + /** + * @brief Returns an iterable object to visit all in-edges of a vertex. + * @param vertex The vertex of which to return all in-edges. + * @return An iterable object to visit all in-edges of a vertex. + */ + [[nodiscard]] iterable_adaptor in_edges(const vertex_type vertex) const noexcept { + const auto it = matrix.cbegin(); + const auto from = vertex; + const auto to = vert * vert + from; + return {{it, vert, from, to, vert}, {it, vert, to, to, vert}}; + } + + /** + * @brief Resizes an adjacency matrix. + * @param vertices The new number of vertices. + */ + void resize(const size_type vertices) { + adjacency_matrix other{vertices, get_allocator()}; + + for(auto [lhs, rhs]: edges()) { + other.insert(lhs, rhs); + } + + other.swap(*this); + } + + /** + * @brief Inserts an edge into the adjacency matrix, if it does not exist. + * @param lhs The left hand vertex of the edge. + * @param rhs The right hand vertex of the edge. + * @return A pair consisting of an iterator to the inserted element (or to + * the element that prevented the insertion) and a bool denoting whether the + * insertion took place. + */ + std::pair insert(const vertex_type lhs, const vertex_type rhs) { + const auto pos = lhs * vert + rhs; + + if constexpr(std::is_same_v) { + const auto rev = rhs * vert + lhs; + ENTT_ASSERT(matrix[pos] == matrix[rev], "Something went really wrong"); + matrix[rev] = 1u; + } + + const auto inserted = !std::exchange(matrix[pos], 1u); + return {edge_iterator{matrix.cbegin(), vert, pos, matrix.size(), 1u}, inserted}; + } + + /** + * @brief Removes the edge associated with a pair of given vertices. + * @param lhs The left hand vertex of the edge. + * @param rhs The right hand vertex of the edge. + * @return Number of elements removed (either 0 or 1). + */ + size_type erase(const vertex_type lhs, const vertex_type rhs) { + const auto pos = lhs * vert + rhs; + + if constexpr(std::is_same_v) { + const auto rev = rhs * vert + lhs; + ENTT_ASSERT(matrix[pos] == matrix[rev], "Something went really wrong"); + matrix[rev] = 0u; + } + + return std::exchange(matrix[pos], 0u); + } + + /** + * @brief Checks if an adjacency matrix contains a given edge. + * @param lhs The left hand vertex of the edge. + * @param rhs The right hand vertex of the edge. + * @return True if there is such an edge, false otherwise. + */ + [[nodiscard]] bool contains(const vertex_type lhs, const vertex_type rhs) const { + const auto pos = lhs * vert + rhs; + return pos < matrix.size() && matrix[pos]; + } + +private: + container_type matrix; + size_type vert; +}; + +} // namespace entt + +#endif + +// #include "graph/dot.hpp" +#ifndef ENTT_GRAPH_DOT_HPP +#define ENTT_GRAPH_DOT_HPP + +#include +#include +// #include "fwd.hpp" + + +namespace entt { + +/** + * @brief Outputs a graph in dot format. + * @tparam Graph Graph type, valid as long as it exposes edges and vertices. + * @tparam Writer Vertex decorator type. + * @param out A standard output stream. + * @param graph The graph to output. + * @param writer Vertex decorator object. + */ +template +void dot(std::ostream &out, const Graph &graph, Writer writer) { + static_assert(std::is_base_of_v, "Invalid graph category"); + + if constexpr(std::is_same_v) { + out << "graph{"; + } else { + out << "digraph{"; + } + + for(auto &&vertex: graph.vertices()) { + out << vertex << "["; + writer(out, vertex); + out << "];"; + } + + for(auto [lhs, rhs]: graph.edges()) { + if constexpr(std::is_same_v) { + out << lhs << "--" << rhs << ";"; + } else { + out << lhs << "->" << rhs << ";"; + } + } + + out << "}"; +} + +/** + * @brief Outputs a graph in dot format. + * @tparam Graph Graph type, valid as long as it exposes edges and vertices. + * @param out A standard output stream. + * @param graph The graph to output. + */ +template +void dot(std::ostream &out, const Graph &graph) { + return dot(out, graph, [](auto &&...) {}); +} + +} // namespace entt + +#endif + +// #include "graph/flow.hpp" +#ifndef ENTT_GRAPH_FLOW_HPP +#define ENTT_GRAPH_FLOW_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "../container/dense_map.hpp" +#ifndef ENTT_CONTAINER_DENSE_MAP_HPP +#define ENTT_CONTAINER_DENSE_MAP_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #include "../config/config.h" +#ifndef ENTT_CONFIG_CONFIG_H +#define ENTT_CONFIG_CONFIG_H + +// #include "version.h" +#ifndef ENTT_CONFIG_VERSION_H +#define ENTT_CONFIG_VERSION_H + +// #include "macro.h" +#ifndef ENTT_CONFIG_MACRO_H +#define ENTT_CONFIG_MACRO_H + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#define ENTT_STR(arg) #arg +#define ENTT_XSTR(arg) ENTT_STR(arg) + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*) + +#define ENTT_VERSION_MAJOR 3 +#define ENTT_VERSION_MINOR 16 +#define ENTT_VERSION_PATCH 0 + +#define ENTT_VERSION \ + ENTT_XSTR(ENTT_VERSION_MAJOR) \ + "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH) + +// NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION) +# define ENTT_CONSTEXPR +# define ENTT_THROW throw +# define ENTT_TRY try +# define ENTT_CATCH catch(...) +#else +# define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20) +# define ENTT_THROW +# define ENTT_TRY if(true) +# define ENTT_CATCH if(false) +#endif + +#if __has_include() +# include +# +# if defined(__cpp_consteval) +# define ENTT_CONSTEVAL consteval +# endif +#endif + +#ifndef ENTT_CONSTEVAL +# define ENTT_CONSTEVAL constexpr +#endif + +#ifdef ENTT_USE_ATOMIC +# include +# define ENTT_MAYBE_ATOMIC(Type) std::atomic +#else +# define ENTT_MAYBE_ATOMIC(Type) Type +#endif + +#ifndef ENTT_ID_TYPE +# include +# define ENTT_ID_TYPE std::uint32_t +#else +# include // provides coverage for types in the std namespace +#endif + +#ifndef ENTT_SPARSE_PAGE +# define ENTT_SPARSE_PAGE 4096 +#endif + +#ifndef ENTT_PACKED_PAGE +# define ENTT_PACKED_PAGE 1024 +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT +# define ENTT_ASSERT(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT +# include +# define ENTT_ASSERT(condition, msg) assert(((condition) && (msg))) +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg) +#endif + +#define ENTT_FAIL(msg) ENTT_ASSERT(false, msg); + +#ifdef ENTT_NO_ETO +# define ENTT_ETO_TYPE(Type) void +#else +# define ENTT_ETO_TYPE(Type) Type +#endif + +#ifdef ENTT_NO_MIXIN +# define ENTT_STORAGE(Mixin, ...) __VA_ARGS__ +#else +# define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__> +#endif + +#ifdef ENTT_STANDARD_CPP +# define ENTT_NONSTD false +#else +# define ENTT_NONSTD true +# if defined __clang__ || defined __GNUC__ +# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ +# define ENTT_PRETTY_FUNCTION_PREFIX '=' +# define ENTT_PRETTY_FUNCTION_SUFFIX ']' +# elif defined _MSC_VER +# define ENTT_PRETTY_FUNCTION __FUNCSIG__ +# define ENTT_PRETTY_FUNCTION_PREFIX '<' +# define ENTT_PRETTY_FUNCTION_SUFFIX '>' +# endif +#endif + +#ifndef ENTT_EXPORT +# if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER +# define ENTT_EXPORT __declspec(dllexport) +# define ENTT_IMPORT __declspec(dllimport) +# define ENTT_HIDDEN +# elif defined __GNUC__ && __GNUC__ >= 4 +# define ENTT_EXPORT __attribute__((visibility("default"))) +# define ENTT_IMPORT __attribute__((visibility("default"))) +# define ENTT_HIDDEN __attribute__((visibility("hidden"))) +# else /* Unsupported compiler */ +# define ENTT_EXPORT +# define ENTT_IMPORT +# define ENTT_HIDDEN +# endif +#endif + +#ifndef ENTT_API +# if defined ENTT_API_EXPORT +# define ENTT_API ENTT_EXPORT +# elif defined ENTT_API_IMPORT +# define ENTT_API ENTT_IMPORT +# else /* No API */ +# define ENTT_API +# endif +#endif + +#if defined _MSC_VER +# pragma detect_mismatch("entt.version", ENTT_VERSION) +# pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY)) +# pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE)) +# pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD)) +#endif + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + +// #include "../core/bit.hpp" +#ifndef ENTT_CORE_BIT_HPP +#define ENTT_CORE_BIT_HPP + +#include +#include +#include +// #include "../config/config.h" +#ifndef ENTT_CONFIG_CONFIG_H +#define ENTT_CONFIG_CONFIG_H + +// #include "version.h" +#ifndef ENTT_CONFIG_VERSION_H +#define ENTT_CONFIG_VERSION_H + +// #include "macro.h" +#ifndef ENTT_CONFIG_MACRO_H +#define ENTT_CONFIG_MACRO_H + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#define ENTT_STR(arg) #arg +#define ENTT_XSTR(arg) ENTT_STR(arg) + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*) + +#define ENTT_VERSION_MAJOR 3 +#define ENTT_VERSION_MINOR 16 +#define ENTT_VERSION_PATCH 0 + +#define ENTT_VERSION \ + ENTT_XSTR(ENTT_VERSION_MAJOR) \ + "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH) + +// NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION) +# define ENTT_CONSTEXPR +# define ENTT_THROW throw +# define ENTT_TRY try +# define ENTT_CATCH catch(...) +#else +# define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20) +# define ENTT_THROW +# define ENTT_TRY if(true) +# define ENTT_CATCH if(false) +#endif + +#if __has_include() +# include +# +# if defined(__cpp_consteval) +# define ENTT_CONSTEVAL consteval +# endif +#endif + +#ifndef ENTT_CONSTEVAL +# define ENTT_CONSTEVAL constexpr +#endif + +#ifdef ENTT_USE_ATOMIC +# include +# define ENTT_MAYBE_ATOMIC(Type) std::atomic +#else +# define ENTT_MAYBE_ATOMIC(Type) Type +#endif + +#ifndef ENTT_ID_TYPE +# include +# define ENTT_ID_TYPE std::uint32_t +#else +# include // provides coverage for types in the std namespace +#endif + +#ifndef ENTT_SPARSE_PAGE +# define ENTT_SPARSE_PAGE 4096 +#endif + +#ifndef ENTT_PACKED_PAGE +# define ENTT_PACKED_PAGE 1024 +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT +# define ENTT_ASSERT(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT +# include +# define ENTT_ASSERT(condition, msg) assert(((condition) && (msg))) +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg) +#endif + +#define ENTT_FAIL(msg) ENTT_ASSERT(false, msg); + +#ifdef ENTT_NO_ETO +# define ENTT_ETO_TYPE(Type) void +#else +# define ENTT_ETO_TYPE(Type) Type +#endif + +#ifdef ENTT_NO_MIXIN +# define ENTT_STORAGE(Mixin, ...) __VA_ARGS__ +#else +# define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__> +#endif + +#ifdef ENTT_STANDARD_CPP +# define ENTT_NONSTD false +#else +# define ENTT_NONSTD true +# if defined __clang__ || defined __GNUC__ +# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ +# define ENTT_PRETTY_FUNCTION_PREFIX '=' +# define ENTT_PRETTY_FUNCTION_SUFFIX ']' +# elif defined _MSC_VER +# define ENTT_PRETTY_FUNCTION __FUNCSIG__ +# define ENTT_PRETTY_FUNCTION_PREFIX '<' +# define ENTT_PRETTY_FUNCTION_SUFFIX '>' +# endif +#endif + +#ifndef ENTT_EXPORT +# if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER +# define ENTT_EXPORT __declspec(dllexport) +# define ENTT_IMPORT __declspec(dllimport) +# define ENTT_HIDDEN +# elif defined __GNUC__ && __GNUC__ >= 4 +# define ENTT_EXPORT __attribute__((visibility("default"))) +# define ENTT_IMPORT __attribute__((visibility("default"))) +# define ENTT_HIDDEN __attribute__((visibility("hidden"))) +# else /* Unsupported compiler */ +# define ENTT_EXPORT +# define ENTT_IMPORT +# define ENTT_HIDDEN +# endif +#endif + +#ifndef ENTT_API +# if defined ENTT_API_EXPORT +# define ENTT_API ENTT_EXPORT +# elif defined ENTT_API_IMPORT +# define ENTT_API ENTT_IMPORT +# else /* No API */ +# define ENTT_API +# endif +#endif + +#if defined _MSC_VER +# pragma detect_mismatch("entt.version", ENTT_VERSION) +# pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY)) +# pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE)) +# pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD)) +#endif + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +namespace entt { + +/** + * @brief Returns the number of set bits in a value (waiting for C++20 and + * `std::popcount`). + * @tparam Type Unsigned integer type. + * @param value A value of unsigned integer type. + * @return The number of set bits in the value. + */ +template +[[nodiscard]] constexpr std::enable_if_t, int> popcount(const Type value) noexcept { + return value ? (int(value & 1) + popcount(static_cast(value >> 1))) : 0; +} + +/** + * @brief Checks whether a value is a power of two or not (waiting for C++20 and + * `std::has_single_bit`). + * @tparam Type Unsigned integer type. + * @param value A value of unsigned integer type. + * @return True if the value is a power of two, false otherwise. + */ +template +[[nodiscard]] constexpr std::enable_if_t, bool> has_single_bit(const Type value) noexcept { + return value && ((value & (value - 1)) == 0); +} + +/** + * @brief Computes the smallest power of two greater than or equal to a value + * (waiting for C++20 and `std::bit_ceil`). + * @tparam Type Unsigned integer type. + * @param value A value of unsigned integer type. + * @return The smallest power of two greater than or equal to the given value. + */ +template +[[nodiscard]] constexpr std::enable_if_t, Type> next_power_of_two(const Type value) noexcept { + // NOLINTNEXTLINE(bugprone-assert-side-effect) + ENTT_ASSERT_CONSTEXPR(value < (Type{1u} << (std::numeric_limits::digits - 1)), "Numeric limits exceeded"); + Type curr = value - (value != 0u); + + for(int next = 1; next < std::numeric_limits::digits; next = next * 2) { + curr |= (curr >> next); + } + + return ++curr; +} + +/** + * @brief Fast module utility function (powers of two only). + * @tparam Type Unsigned integer type. + * @param value A value of unsigned integer type. + * @param mod _Modulus_, it must be a power of two. + * @return The common remainder. + */ +template +[[nodiscard]] constexpr std::enable_if_t, Type> fast_mod(const Type value, const std::size_t mod) noexcept { + ENTT_ASSERT_CONSTEXPR(has_single_bit(mod), "Value must be a power of two"); + return static_cast(value & (mod - 1u)); +} + +} // namespace entt + +#endif + +// #include "../core/compressed_pair.hpp" +#ifndef ENTT_CORE_COMPRESSED_PAIR_HPP +#define ENTT_CORE_COMPRESSED_PAIR_HPP + +#include +#include +#include +#include +// #include "fwd.hpp" +#ifndef ENTT_CORE_FWD_HPP +#define ENTT_CORE_FWD_HPP + +#include +#include +// #include "../config/config.h" + + +namespace entt { + +/*! @brief Possible modes of an any object. */ +enum class any_policy : std::uint8_t { + /*! @brief Default mode, no element available. */ + empty, + /*! @brief Owning mode, dynamically allocated element. */ + dynamic, + /*! @brief Owning mode, embedded element. */ + embedded, + /*! @brief Aliasing mode, non-const reference. */ + ref, + /*! @brief Const aliasing mode, const reference. */ + cref +}; + +// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) +template +class basic_any; + +/*! @brief Alias declaration for type identifiers. */ +using id_type = ENTT_ID_TYPE; + +/*! @brief Alias declaration for the most common use case. */ +using any = basic_any<>; + +template +class compressed_pair; + +template +class basic_hashed_string; + +/*! @brief Aliases for common character types. */ +using hashed_string = basic_hashed_string; + +/*! @brief Aliases for common character types. */ +using hashed_wstring = basic_hashed_string; + +// NOLINTNEXTLINE(bugprone-forward-declaration-namespace) +struct type_info; + +} // namespace entt + +#endif + +// #include "type_traits.hpp" +#ifndef ENTT_CORE_TYPE_TRAITS_HPP +#define ENTT_CORE_TYPE_TRAITS_HPP + +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "fwd.hpp" + + +namespace entt { + +/** + * @brief Utility class to disambiguate overloaded functions. + * @tparam N Number of choices available. + */ +template +struct choice_t + // unfortunately, doxygen cannot parse such a construct + : /*! @cond TURN_OFF_DOXYGEN */ choice_t /*! @endcond */ +{}; + +/*! @copybrief choice_t */ +template<> +struct choice_t<0> {}; + +/** + * @brief Variable template for the choice trick. + * @tparam N Number of choices available. + */ +template +inline constexpr choice_t choice{}; + +/** + * @brief Identity type trait. + * + * Useful to establish non-deduced contexts in template argument deduction + * (waiting for C++20) or to provide types through function arguments. + * + * @tparam Type A type. + */ +template +struct type_identity { + /*! @brief Identity type. */ + using type = Type; +}; + +/** + * @brief Helper type. + * @tparam Type A type. + */ +template +using type_identity_t = typename type_identity::type; + +/** + * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains. + * @tparam Type The type of which to return the size. + */ +template +struct size_of: std::integral_constant {}; + +/*! @copydoc size_of */ +template +struct size_of> + // NOLINTNEXTLINE(bugprone-sizeof-expression) + : std::integral_constant {}; + +/** + * @brief Helper variable template. + * @tparam Type The type of which to return the size. + */ +template +inline constexpr std::size_t size_of_v = size_of::value; + +/** + * @brief Using declaration to be used to _repeat_ the same type a number of + * times equal to the size of a given parameter pack. + * @tparam Type A type to repeat. + */ +template +using unpack_as_type = Type; + +/** + * @brief Helper variable template to be used to _repeat_ the same value a + * number of times equal to the size of a given parameter pack. + * @tparam Value A value to repeat. + */ +template +inline constexpr auto unpack_as_value = Value; + +/** + * @brief Wraps a static constant. + * @tparam Value A static constant. + */ +template +using integral_constant = std::integral_constant; + +/** + * @brief Alias template to facilitate the creation of named values. + * @tparam Value A constant value at least convertible to `id_type`. + */ +template +using tag = integral_constant; + +/** + * @brief A class to use to push around lists of types, nothing more. + * @tparam Type Types provided by the type list. + */ +template +struct type_list { + /*! @brief Type list type. */ + using type = type_list; + /*! @brief Compile-time number of elements in the type list. */ + static constexpr auto size = sizeof...(Type); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_element; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Index Index of the type to return. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element> + : type_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element<0u, type_list> { + /*! @brief Searched type. */ + using type = First; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Type list to search into. + */ +template +using type_list_element_t = typename type_list_element::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_index; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 1u + type_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + static_assert(type_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +inline constexpr std::size_t type_list_index_v = type_list_index::value; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @return A type list composed by the types of both the type lists. + */ +template +constexpr type_list operator+(type_list, type_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_cat; + +/*! @brief Concatenates multiple type lists. */ +template<> +struct type_list_cat<> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list<>; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @tparam List Other type lists, if any. + */ +template +struct type_list_cat, type_list, List...> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = typename type_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the type list. + */ +template +struct type_list_cat> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list; +}; + +/** + * @brief Helper type. + * @tparam List Type lists to concatenate. + */ +template +using type_list_cat_t = typename type_list_cat::type; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct type_list_unique; + +template +struct type_list_unique, Type...> + : std::conditional_t<(std::is_same_v || ...), type_list_unique, Type...>, type_list_unique, Type..., First>> {}; + +template +struct type_list_unique, Type...> { + using type = type_list; +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Removes duplicates types from a type list. + * @tparam List Type list. + */ +template +struct type_list_unique { + /*! @brief A type list without duplicate types. */ + using type = typename internal::type_list_unique::type; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + */ +template +using type_list_unique_t = typename type_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a type list contains a + * given type, false otherwise. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +struct type_list_contains; + +/** + * @copybrief type_list_contains + * @tparam Type Types provided by the type list. + * @tparam Other Type to look for. + */ +template +struct type_list_contains, Other> + : std::bool_constant<(std::is_same_v || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +inline constexpr bool type_list_contains_v = type_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_diff; + +/** + * @brief Computes the difference between two type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + */ +template +struct type_list_diff, type_list> { + /*! @brief A type list that is the difference between the two type lists. */ + using type = type_list_cat_t, Type>, type_list<>, type_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Type lists between which to compute the difference. + */ +template +using type_list_diff_t = typename type_list_diff::type; + +/*! @brief Primary template isn't defined on purpose. */ +template class> +struct type_list_transform; + +/** + * @brief Applies a given _function_ to a type list and generate a new list. + * @tparam Type Types provided by the type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +struct type_list_transform, Op> { + /*! @brief Resulting type list after applying the transform function. */ + // NOLINTNEXTLINE(modernize-type-traits) + using type = type_list::type...>; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +using type_list_transform_t = typename type_list_transform::type; + +/** + * @brief A class to use to push around lists of constant values, nothing more. + * @tparam Value Values provided by the value list. + */ +template +struct value_list { + /*! @brief Value list type. */ + using type = value_list; + /*! @brief Compile-time number of elements in the value list. */ + static constexpr auto size = sizeof...(Value); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_element; + +/** + * @brief Provides compile-time indexed access to the values of a value list. + * @tparam Index Index of the value to return. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element> + : value_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element<0u, value_list> { + /*! @brief Searched type. */ + using type = decltype(Value); + /*! @brief Searched value. */ + static constexpr auto value = Value; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Value list to search into. + */ +template +using value_list_element_t = typename value_list_element::type; + +/** + * @brief Helper type. + * @tparam Index Index of the value to return. + * @tparam List Value list to search into. + */ +template +inline constexpr auto value_list_element_v = value_list_element::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_index; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam First First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 1u + value_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + static_assert(value_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +inline constexpr std::size_t value_list_index_v = value_list_index::value; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @return A value list composed by the values of both the value lists. + */ +template +constexpr value_list operator+(value_list, value_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_cat; + +/*! @brief Concatenates multiple value lists. */ +template<> +struct value_list_cat<> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list<>; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @tparam List Other value lists, if any. + */ +template +struct value_list_cat, value_list, List...> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = typename value_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the value list. + */ +template +struct value_list_cat> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list; +}; + +/** + * @brief Helper type. + * @tparam List Value lists to concatenate. + */ +template +using value_list_cat_t = typename value_list_cat::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_unique; + +/** + * @brief Removes duplicates values from a value list. + * @tparam Value One of the values provided by the given value list. + * @tparam Other The other values provided by the given value list. + */ +template +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = std::conditional_t< + ((Value == Other) || ...), + typename value_list_unique>::type, + value_list_cat_t, typename value_list_unique>::type>>; +}; + +/*! @brief Removes duplicates values from a value list. */ +template<> +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = value_list<>; +}; + +/** + * @brief Helper type. + * @tparam Type A value list. + */ +template +using value_list_unique_t = typename value_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a value list contains + * a given value, false otherwise. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +struct value_list_contains; + +/** + * @copybrief value_list_contains + * @tparam Value Values provided by the value list. + * @tparam Other Value to look for. + */ +template +struct value_list_contains, Other> + : std::bool_constant<((Value == Other) || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +inline constexpr bool value_list_contains_v = value_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_diff; + +/** + * @brief Computes the difference between two value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + */ +template +struct value_list_diff, value_list> { + /*! @brief A value list that is the difference between the two value lists. */ + using type = value_list_cat_t, Value>, value_list<>, value_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Value lists between which to compute the difference. + */ +template +using value_list_diff_t = typename value_list_diff::type; + +/*! @brief Same as std::is_invocable, but with tuples. */ +template +struct is_applicable: std::false_type {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @brief Helper variable template. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_v = is_applicable::value; + +/*! @brief Same as std::is_invocable_r, but with tuples for arguments. */ +template +struct is_applicable_r: std::false_type {}; + +/** + * @copybrief is_applicable_r + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +struct is_applicable_r>: std::is_invocable_r {}; + +/** + * @brief Helper variable template. + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_r_v = is_applicable_r::value; + +/** + * @brief Provides the member constant `value` to true if a given type is + * complete, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_complete: std::false_type {}; + +/*! @copydoc is_complete */ +template +struct is_complete>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_complete_v = is_complete::value; + +/** + * @brief Provides the member constant `value` to true if a given type is an + * iterator, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_iterator: std::false_type {}; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_iterator_category: std::false_type {}; + +template +struct has_iterator_category::iterator_category>>: std::true_type {}; + +} // namespace internal +/*! @endcond */ + +/*! @copydoc is_iterator */ +template +struct is_iterator>>>> + : internal::has_iterator_category {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_iterator_v = is_iterator::value; + +/** + * @brief Provides the member constant `value` to true if a given type is both + * an empty and non-final class, false otherwise. + * @tparam Type The type to test + */ +template +struct is_ebco_eligible + : std::bool_constant && !std::is_final_v> {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_ebco_eligible_v = is_ebco_eligible::value; + +/** + * @brief Provides the member constant `value` to true if `Type::is_transparent` + * is valid and denotes a type, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_transparent: std::false_type {}; + +/*! @copydoc is_transparent */ +template +struct is_transparent>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_transparent_v = is_transparent::value; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_tuple_size_value: std::false_type {}; + +template +struct has_tuple_size_value::value)>>: std::true_type {}; + +template +struct has_value_type: std::false_type {}; + +template +struct has_value_type>: std::true_type {}; + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable(); + +template +[[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence) { + return (dispatch_is_equality_comparable>() && ...); +} + +template +[[nodiscard]] constexpr bool maybe_equality_comparable(char) { + return false; +} + +template +[[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval() == std::declval()) { + return true; +} + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable() { + // NOLINTBEGIN(modernize-use-transparent-functors) + if constexpr(std::is_array_v) { + return false; + } else if constexpr(is_complete_v>>) { + if constexpr(has_tuple_size_value::value) { + return maybe_equality_comparable(0) && unpack_maybe_equality_comparable(std::make_index_sequence::value>{}); + } else { + return maybe_equality_comparable(0); + } + } else if constexpr(has_value_type::value) { + if constexpr(is_iterator_v || std::is_same_v || dispatch_is_equality_comparable()) { + return maybe_equality_comparable(0); + } else { + return false; + } + } else { + return maybe_equality_comparable(0); + } + // NOLINTEND(modernize-use-transparent-functors) +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Provides the member constant `value` to true if a given type is + * equality comparable, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_equality_comparable: std::bool_constant()> {}; + +/*! @copydoc is_equality_comparable */ +template +struct is_equality_comparable: is_equality_comparable {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_equality_comparable_v = is_equality_comparable::value; + +/** + * @brief Transcribes the constness of a type to another type. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = std::remove_const_t; +}; + +/*! @copydoc constness_as */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = const To; +}; + +/** + * @brief Alias template to facilitate the transcription of the constness. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +using constness_as_t = typename constness_as::type; + +/** + * @brief Extracts the class of a non-static member object or function. + * @tparam Member A pointer to a non-static member object or function. + */ +template +class member_class { + static_assert(std::is_member_pointer_v, "Invalid pointer type to non-static member object or function"); + + template + static Class *clazz(Ret (Class::*)(Args...)); + + template + static Class *clazz(Ret (Class::*)(Args...) const); + + template + static Class *clazz(Type Class::*); + +public: + /*! @brief The class of the given non-static member object or function. */ + using type = std::remove_pointer_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Member A pointer to a non-static member object or function. + */ +template +using member_class_t = typename member_class::type; + +/** + * @brief Extracts the n-th argument of a _callable_ type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid _callable_ type. + */ +template +class nth_argument { + template + static constexpr type_list pick_up(Ret (*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...) const); + + template + static constexpr type_list pick_up(Type Class ::*); + + template + static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&); + +public: + /*! @brief N-th argument of the _callable_ type. */ + using type = type_list_element_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid function, member function or data member type. + */ +template +using nth_argument_t = typename nth_argument::type; + +} // namespace entt + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::type_list_element> {}; + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::value_list_element> {}; + +#endif + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct compressed_pair_element { + using reference = Type &; + using const_reference = const Type &; + + template>> + // NOLINTNEXTLINE(modernize-use-equals-default) + constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v) {} + + template>, compressed_pair_element>>> + constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v) + : value{std::forward(arg)} {} + + template + constexpr compressed_pair_element(std::tuple args, std::index_sequence) noexcept(std::is_nothrow_constructible_v) + : value{std::forward(std::get(args))...} {} + + [[nodiscard]] constexpr reference get() noexcept { + return value; + } + + [[nodiscard]] constexpr const_reference get() const noexcept { + return value; + } + +private: + Type value{}; +}; + +template +struct compressed_pair_element>>: Type { + using reference = Type &; + using const_reference = const Type &; + using base_type = Type; + + template>> + constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v) + : base_type{} {} + + template>, compressed_pair_element>>> + constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v) + : base_type{std::forward(arg)} {} + + template + constexpr compressed_pair_element(std::tuple args, std::index_sequence) noexcept(std::is_nothrow_constructible_v) + : base_type{std::forward(std::get(args))...} {} + + [[nodiscard]] constexpr reference get() noexcept { + return *this; + } + + [[nodiscard]] constexpr const_reference get() const noexcept { + return *this; + } +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief A compressed pair. + * + * A pair that exploits the _Empty Base Class Optimization_ (or _EBCO_) to + * reduce its final size to a minimum. + * + * @tparam First The type of the first element that the pair stores. + * @tparam Second The type of the second element that the pair stores. + */ +template +class compressed_pair final + : internal::compressed_pair_element, + internal::compressed_pair_element { + using first_base = internal::compressed_pair_element; + using second_base = internal::compressed_pair_element; + +public: + /*! @brief The type of the first element that the pair stores. */ + using first_type = First; + /*! @brief The type of the second element that the pair stores. */ + using second_type = Second; + + /** + * @brief Default constructor, conditionally enabled. + * + * This constructor is only available when the types that the pair stores + * are both at least default constructible. + * + * @tparam Dummy Dummy template parameter used for internal purposes. + */ + template && std::is_default_constructible_v>> + constexpr compressed_pair() noexcept(std::is_nothrow_default_constructible_v && std::is_nothrow_default_constructible_v) + : first_base{}, + second_base{} {} + + /** + * @brief Copy constructor. + * @param other The instance to copy from. + */ + constexpr compressed_pair(const compressed_pair &other) = default; + + /** + * @brief Move constructor. + * @param other The instance to move from. + */ + constexpr compressed_pair(compressed_pair &&other) noexcept = default; + + /** + * @brief Constructs a pair from its values. + * @tparam Arg Type of value to use to initialize the first element. + * @tparam Other Type of value to use to initialize the second element. + * @param arg Value to use to initialize the first element. + * @param other Value to use to initialize the second element. + */ + template + constexpr compressed_pair(Arg &&arg, Other &&other) noexcept(std::is_nothrow_constructible_v && std::is_nothrow_constructible_v) + : first_base{std::forward(arg)}, + second_base{std::forward(other)} {} + + /** + * @brief Constructs a pair by forwarding the arguments to its parts. + * @tparam Args Types of arguments to use to initialize the first element. + * @tparam Other Types of arguments to use to initialize the second element. + * @param args Arguments to use to initialize the first element. + * @param other Arguments to use to initialize the second element. + */ + template + constexpr compressed_pair(std::piecewise_construct_t, std::tuple args, std::tuple other) noexcept(std::is_nothrow_constructible_v && std::is_nothrow_constructible_v) + : first_base{std::move(args), std::index_sequence_for{}}, + second_base{std::move(other), std::index_sequence_for{}} {} + + /*! @brief Default destructor. */ + ~compressed_pair() = default; + + /** + * @brief Copy assignment operator. + * @param other The instance to copy from. + * @return This compressed pair object. + */ + constexpr compressed_pair &operator=(const compressed_pair &other) = default; + + /** + * @brief Move assignment operator. + * @param other The instance to move from. + * @return This compressed pair object. + */ + constexpr compressed_pair &operator=(compressed_pair &&other) noexcept = default; + + /** + * @brief Returns the first element that a pair stores. + * @return The first element that a pair stores. + */ + [[nodiscard]] constexpr first_type &first() noexcept { + return static_cast(*this).get(); + } + + /*! @copydoc first */ + [[nodiscard]] constexpr const first_type &first() const noexcept { + return static_cast(*this).get(); + } + + /** + * @brief Returns the second element that a pair stores. + * @return The second element that a pair stores. + */ + [[nodiscard]] constexpr second_type &second() noexcept { + return static_cast(*this).get(); + } + + /*! @copydoc second */ + [[nodiscard]] constexpr const second_type &second() const noexcept { + return static_cast(*this).get(); + } + + /** + * @brief Swaps two compressed pair objects. + * @param other The compressed pair to swap with. + */ + constexpr void swap(compressed_pair &other) noexcept { + using std::swap; + swap(first(), other.first()); + swap(second(), other.second()); + } + + /** + * @brief Extracts an element from the compressed pair. + * @tparam Index An integer value that is either 0 or 1. + * @return Returns a reference to the first element if `Index` is 0 and a + * reference to the second element if `Index` is 1. + */ + template + [[nodiscard]] constexpr decltype(auto) get() noexcept { + if constexpr(Index == 0u) { + return first(); + } else { + static_assert(Index == 1u, "Index out of bounds"); + return second(); + } + } + + /*! @copydoc get */ + template + [[nodiscard]] constexpr decltype(auto) get() const noexcept { + if constexpr(Index == 0u) { + return first(); + } else { + static_assert(Index == 1u, "Index out of bounds"); + return second(); + } + } +}; + +/** + * @brief Deduction guide. + * @tparam Type Type of value to use to initialize the first element. + * @tparam Other Type of value to use to initialize the second element. + */ +template +compressed_pair(Type &&, Other &&) -> compressed_pair, std::decay_t>; + +/** + * @brief Swaps two compressed pair objects. + * @tparam First The type of the first element that the pairs store. + * @tparam Second The type of the second element that the pairs store. + * @param lhs A valid compressed pair object. + * @param rhs A valid compressed pair object. + */ +template +constexpr void swap(compressed_pair &lhs, compressed_pair &rhs) noexcept { + lhs.swap(rhs); +} + +} // namespace entt + +namespace std { + +/** + * @brief `std::tuple_size` specialization for `compressed_pair`s. + * @tparam First The type of the first element that the pair stores. + * @tparam Second The type of the second element that the pair stores. + */ +template +struct tuple_size>: integral_constant {}; + +/** + * @brief `std::tuple_element` specialization for `compressed_pair`s. + * @tparam Index The index of the type to return. + * @tparam First The type of the first element that the pair stores. + * @tparam Second The type of the second element that the pair stores. + */ +template +struct tuple_element>: conditional { + static_assert(Index < 2u, "Index out of bounds"); +}; + +} // namespace std + +#endif + +// #include "../core/iterator.hpp" +#ifndef ENTT_CORE_ITERATOR_HPP +#define ENTT_CORE_ITERATOR_HPP + +#include +#include +#include +#include + +namespace entt { + +/** + * @brief Helper type to use as pointer with input iterators. + * @tparam Type of wrapped value. + */ +template +struct input_iterator_pointer final { + /*! @brief Value type. */ + using value_type = Type; + /*! @brief Pointer type. */ + using pointer = Type *; + /*! @brief Reference type. */ + using reference = Type &; + + /** + * @brief Constructs a proxy object by move. + * @param val Value to use to initialize the proxy object. + */ + constexpr input_iterator_pointer(value_type &&val) noexcept(std::is_nothrow_move_constructible_v) + : value{std::move(val)} {} + + /** + * @brief Access operator for accessing wrapped values. + * @return A pointer to the wrapped value. + */ + [[nodiscard]] constexpr pointer operator->() noexcept { + return std::addressof(value); + } + + /** + * @brief Dereference operator for accessing wrapped values. + * @return A reference to the wrapped value. + */ + [[nodiscard]] constexpr reference operator*() noexcept { + return value; + } + +private: + Type value; +}; + +/** + * @brief Plain iota iterator (waiting for C++20). + * @tparam Type Value type. + */ +template +class iota_iterator final { + static_assert(std::is_integral_v, "Not an integral type"); + +public: + /*! @brief Value type, likely an integral one. */ + using value_type = Type; + /*! @brief Invalid pointer type. */ + using pointer = void; + /*! @brief Non-reference type, same as value type. */ + using reference = value_type; + /*! @brief Difference type. */ + using difference_type = std::ptrdiff_t; + /*! @brief Iterator category. */ + using iterator_category = std::input_iterator_tag; + + /*! @brief Default constructor. */ + constexpr iota_iterator() noexcept + : current{} {} + + /** + * @brief Constructs an iota iterator from a given value. + * @param init The initial value assigned to the iota iterator. + */ + constexpr iota_iterator(const value_type init) noexcept + : current{init} {} + + /** + * @brief Pre-increment operator. + * @return This iota iterator. + */ + constexpr iota_iterator &operator++() noexcept { + return ++current, *this; + } + + /** + * @brief Post-increment operator. + * @return This iota iterator. + */ + constexpr iota_iterator operator++(int) noexcept { + const iota_iterator orig = *this; + return ++(*this), orig; + } + + /** + * @brief Dereference operator. + * @return The underlying value. + */ + [[nodiscard]] constexpr reference operator*() const noexcept { + return current; + } + +private: + value_type current; +}; + +/** + * @brief Comparison operator. + * @tparam Type Value type of the iota iterator. + * @param lhs A properly initialized iota iterator. + * @param rhs A properly initialized iota iterator. + * @return True if the two iterators are identical, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator==(const iota_iterator &lhs, const iota_iterator &rhs) noexcept { + return *lhs == *rhs; +} + +/** + * @brief Comparison operator. + * @tparam Type Value type of the iota iterator. + * @param lhs A properly initialized iota iterator. + * @param rhs A properly initialized iota iterator. + * @return True if the two iterators differ, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator!=(const iota_iterator &lhs, const iota_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +/** + * @brief Utility class to create an iterable object from a pair of iterators. + * @tparam It Type of iterator. + * @tparam Sentinel Type of sentinel. + */ +template +struct iterable_adaptor final { + /*! @brief Value type. */ + using value_type = typename std::iterator_traits::value_type; + /*! @brief Iterator type. */ + using iterator = It; + /*! @brief Sentinel type. */ + using sentinel = Sentinel; + + /*! @brief Default constructor. */ + constexpr iterable_adaptor() noexcept(std::is_nothrow_default_constructible_v && std::is_nothrow_default_constructible_v) + : first{}, + last{} {} + + /** + * @brief Creates an iterable object from a pair of iterators. + * @param from Begin iterator. + * @param to End iterator. + */ + constexpr iterable_adaptor(iterator from, sentinel to) noexcept(std::is_nothrow_move_constructible_v && std::is_nothrow_move_constructible_v) + : first{std::move(from)}, + last{std::move(to)} {} + + /** + * @brief Returns an iterator to the beginning. + * @return An iterator to the first element of the range. + */ + [[nodiscard]] constexpr iterator begin() const noexcept { + return first; + } + + /** + * @brief Returns an iterator to the end. + * @return An iterator to the element following the last element of the + * range. + */ + [[nodiscard]] constexpr sentinel end() const noexcept { + return last; + } + + /*! @copydoc begin */ + [[nodiscard]] constexpr iterator cbegin() const noexcept { + return begin(); + } + + /*! @copydoc end */ + [[nodiscard]] constexpr sentinel cend() const noexcept { + return end(); + } + +private: + It first; + Sentinel last; +}; + +} // namespace entt + +#endif + +// #include "../core/memory.hpp" +#ifndef ENTT_CORE_MEMORY_HPP +#define ENTT_CORE_MEMORY_HPP + +#include +#include +#include +#include +#include +// #include "../config/config.h" + + +namespace entt { + +/** + * @brief Unwraps fancy pointers, does nothing otherwise (waiting for C++20). + * @tparam Type Pointer type. + * @param ptr Fancy or raw pointer. + * @return A raw pointer that represents the address of the original pointer. + */ +template +[[nodiscard]] constexpr auto to_address(Type &&ptr) noexcept { + if constexpr(std::is_pointer_v>) { + return ptr; + } else { + return to_address(std::forward(ptr).operator->()); + } +} + +/** + * @brief Utility function to design allocation-aware containers. + * @tparam Allocator Type of allocator. + * @param lhs A valid allocator. + * @param rhs Another valid allocator. + */ +template +constexpr void propagate_on_container_copy_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept { + if constexpr(std::allocator_traits::propagate_on_container_copy_assignment::value) { + lhs = rhs; + } +} + +/** + * @brief Utility function to design allocation-aware containers. + * @tparam Allocator Type of allocator. + * @param lhs A valid allocator. + * @param rhs Another valid allocator. + */ +template +constexpr void propagate_on_container_move_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept { + if constexpr(std::allocator_traits::propagate_on_container_move_assignment::value) { + lhs = std::move(rhs); + } +} + +/** + * @brief Utility function to design allocation-aware containers. + * @tparam Allocator Type of allocator. + * @param lhs A valid allocator. + * @param rhs Another valid allocator. + */ +template +constexpr void propagate_on_container_swap([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept { + if constexpr(std::allocator_traits::propagate_on_container_swap::value) { + using std::swap; + swap(lhs, rhs); + } else { + ENTT_ASSERT_CONSTEXPR(lhs == rhs, "Cannot swap the containers"); + } +} + +/** + * @brief Deleter for allocator-aware unique pointers (waiting for C++20). + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +struct allocation_deleter: private Allocator { + /*! @brief Allocator type. */ + using allocator_type = Allocator; + /*! @brief Pointer type. */ + using pointer = typename std::allocator_traits::pointer; + + /** + * @brief Inherited constructors. + * @param alloc The allocator to use. + */ + constexpr allocation_deleter(const allocator_type &alloc) noexcept(std::is_nothrow_copy_constructible_v) + : Allocator{alloc} {} + + /** + * @brief Destroys the pointed object and deallocates its memory. + * @param ptr A valid pointer to an object of the given type. + */ + constexpr void operator()(pointer ptr) noexcept(std::is_nothrow_destructible_v) { + using alloc_traits = std::allocator_traits; + alloc_traits::destroy(*this, to_address(ptr)); + alloc_traits::deallocate(*this, ptr, 1u); + } +}; + +/** + * @brief Allows `std::unique_ptr` to use allocators (waiting for C++20). + * @tparam Type Type of object to allocate for and to construct. + * @tparam Allocator Type of allocator used to manage memory and elements. + * @tparam Args Types of arguments to use to construct the object. + * @param allocator The allocator to use. + * @param args Parameters to use to construct the object. + * @return A properly initialized unique pointer with a custom deleter. + */ +template +ENTT_CONSTEXPR auto allocate_unique(Allocator &allocator, Args &&...args) { + static_assert(!std::is_array_v, "Array types are not supported"); + + using alloc_traits = typename std::allocator_traits::template rebind_traits; + using allocator_type = typename alloc_traits::allocator_type; + + allocator_type alloc{allocator}; + auto ptr = alloc_traits::allocate(alloc, 1u); + + ENTT_TRY { + alloc_traits::construct(alloc, to_address(ptr), std::forward(args)...); + } + ENTT_CATCH { + alloc_traits::deallocate(alloc, ptr, 1u); + ENTT_THROW; + } + + return std::unique_ptr>{ptr, alloc}; +} + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct uses_allocator_construction { + template + static constexpr auto args([[maybe_unused]] const Allocator &allocator, Params &&...params) noexcept { + if constexpr(!std::uses_allocator_v && std::is_constructible_v) { + return std::forward_as_tuple(std::forward(params)...); + } else { + static_assert(std::uses_allocator_v, "Ill-formed request"); + + if constexpr(std::is_constructible_v) { + return std::tuple{std::allocator_arg, allocator, std::forward(params)...}; + } else { + static_assert(std::is_constructible_v, "Ill-formed request"); + return std::forward_as_tuple(std::forward(params)..., allocator); + } + } + } +}; + +template +struct uses_allocator_construction> { + using type = std::pair; + + template + static constexpr auto args(const Allocator &allocator, std::piecewise_construct_t, First &&first, Second &&second) noexcept { + return std::make_tuple( + std::piecewise_construct, + std::apply([&allocator](auto &&...curr) { return uses_allocator_construction::args(allocator, std::forward(curr)...); }, std::forward(first)), + std::apply([&allocator](auto &&...curr) { return uses_allocator_construction::args(allocator, std::forward(curr)...); }, std::forward(second))); + } + + template + static constexpr auto args(const Allocator &allocator) noexcept { + return uses_allocator_construction::args(allocator, std::piecewise_construct, std::tuple<>{}, std::tuple<>{}); + } + + template + static constexpr auto args(const Allocator &allocator, First &&first, Second &&second) noexcept { + return uses_allocator_construction::args(allocator, std::piecewise_construct, std::forward_as_tuple(std::forward(first)), std::forward_as_tuple(std::forward(second))); + } + + template + static constexpr auto args(const Allocator &allocator, const std::pair &value) noexcept { + return uses_allocator_construction::args(allocator, std::piecewise_construct, std::forward_as_tuple(value.first), std::forward_as_tuple(value.second)); + } + + template + static constexpr auto args(const Allocator &allocator, std::pair &&value) noexcept { + return uses_allocator_construction::args(allocator, std::piecewise_construct, std::forward_as_tuple(std::move(value.first)), std::forward_as_tuple(std::move(value.second))); + } +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Uses-allocator construction utility (waiting for C++20). + * + * Primarily intended for internal use. Prepares the argument list needed to + * create an object of a given type by means of uses-allocator construction. + * + * @tparam Type Type to return arguments for. + * @tparam Allocator Type of allocator used to manage memory and elements. + * @tparam Args Types of arguments to use to construct the object. + * @param allocator The allocator to use. + * @param args Parameters to use to construct the object. + * @return The arguments needed to create an object of the given type. + */ +template +constexpr auto uses_allocator_construction_args(const Allocator &allocator, Args &&...args) noexcept { + return internal::uses_allocator_construction::args(allocator, std::forward(args)...); +} + +/** + * @brief Uses-allocator construction utility (waiting for C++20). + * + * Primarily intended for internal use. Creates an object of a given type by + * means of uses-allocator construction. + * + * @tparam Type Type of object to create. + * @tparam Allocator Type of allocator used to manage memory and elements. + * @tparam Args Types of arguments to use to construct the object. + * @param allocator The allocator to use. + * @param args Parameters to use to construct the object. + * @return A newly created object of the given type. + */ +template +constexpr Type make_obj_using_allocator(const Allocator &allocator, Args &&...args) { + return std::make_from_tuple(internal::uses_allocator_construction::args(allocator, std::forward(args)...)); +} + +/** + * @brief Uses-allocator construction utility (waiting for C++20). + * + * Primarily intended for internal use. Creates an object of a given type by + * means of uses-allocator construction at an uninitialized memory location. + * + * @tparam Type Type of object to create. + * @tparam Allocator Type of allocator used to manage memory and elements. + * @tparam Args Types of arguments to use to construct the object. + * @param value Memory location in which to place the object. + * @param allocator The allocator to use. + * @param args Parameters to use to construct the object. + * @return A pointer to the newly created object of the given type. + */ +template +constexpr Type *uninitialized_construct_using_allocator(Type *value, const Allocator &allocator, Args &&...args) { + return std::apply([value](auto &&...curr) { return ::new(value) Type(std::forward(curr)...); }, internal::uses_allocator_construction::args(allocator, std::forward(args)...)); +} + +} // namespace entt + +#endif + +// #include "../core/type_traits.hpp" +#ifndef ENTT_CORE_TYPE_TRAITS_HPP +#define ENTT_CORE_TYPE_TRAITS_HPP + +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "fwd.hpp" + + +namespace entt { + +/** + * @brief Utility class to disambiguate overloaded functions. + * @tparam N Number of choices available. + */ +template +struct choice_t + // unfortunately, doxygen cannot parse such a construct + : /*! @cond TURN_OFF_DOXYGEN */ choice_t /*! @endcond */ +{}; + +/*! @copybrief choice_t */ +template<> +struct choice_t<0> {}; + +/** + * @brief Variable template for the choice trick. + * @tparam N Number of choices available. + */ +template +inline constexpr choice_t choice{}; + +/** + * @brief Identity type trait. + * + * Useful to establish non-deduced contexts in template argument deduction + * (waiting for C++20) or to provide types through function arguments. + * + * @tparam Type A type. + */ +template +struct type_identity { + /*! @brief Identity type. */ + using type = Type; +}; + +/** + * @brief Helper type. + * @tparam Type A type. + */ +template +using type_identity_t = typename type_identity::type; + +/** + * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains. + * @tparam Type The type of which to return the size. + */ +template +struct size_of: std::integral_constant {}; + +/*! @copydoc size_of */ +template +struct size_of> + // NOLINTNEXTLINE(bugprone-sizeof-expression) + : std::integral_constant {}; + +/** + * @brief Helper variable template. + * @tparam Type The type of which to return the size. + */ +template +inline constexpr std::size_t size_of_v = size_of::value; + +/** + * @brief Using declaration to be used to _repeat_ the same type a number of + * times equal to the size of a given parameter pack. + * @tparam Type A type to repeat. + */ +template +using unpack_as_type = Type; + +/** + * @brief Helper variable template to be used to _repeat_ the same value a + * number of times equal to the size of a given parameter pack. + * @tparam Value A value to repeat. + */ +template +inline constexpr auto unpack_as_value = Value; + +/** + * @brief Wraps a static constant. + * @tparam Value A static constant. + */ +template +using integral_constant = std::integral_constant; + +/** + * @brief Alias template to facilitate the creation of named values. + * @tparam Value A constant value at least convertible to `id_type`. + */ +template +using tag = integral_constant; + +/** + * @brief A class to use to push around lists of types, nothing more. + * @tparam Type Types provided by the type list. + */ +template +struct type_list { + /*! @brief Type list type. */ + using type = type_list; + /*! @brief Compile-time number of elements in the type list. */ + static constexpr auto size = sizeof...(Type); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_element; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Index Index of the type to return. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element> + : type_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element<0u, type_list> { + /*! @brief Searched type. */ + using type = First; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Type list to search into. + */ +template +using type_list_element_t = typename type_list_element::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_index; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 1u + type_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + static_assert(type_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +inline constexpr std::size_t type_list_index_v = type_list_index::value; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @return A type list composed by the types of both the type lists. + */ +template +constexpr type_list operator+(type_list, type_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_cat; + +/*! @brief Concatenates multiple type lists. */ +template<> +struct type_list_cat<> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list<>; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @tparam List Other type lists, if any. + */ +template +struct type_list_cat, type_list, List...> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = typename type_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the type list. + */ +template +struct type_list_cat> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list; +}; + +/** + * @brief Helper type. + * @tparam List Type lists to concatenate. + */ +template +using type_list_cat_t = typename type_list_cat::type; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct type_list_unique; + +template +struct type_list_unique, Type...> + : std::conditional_t<(std::is_same_v || ...), type_list_unique, Type...>, type_list_unique, Type..., First>> {}; + +template +struct type_list_unique, Type...> { + using type = type_list; +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Removes duplicates types from a type list. + * @tparam List Type list. + */ +template +struct type_list_unique { + /*! @brief A type list without duplicate types. */ + using type = typename internal::type_list_unique::type; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + */ +template +using type_list_unique_t = typename type_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a type list contains a + * given type, false otherwise. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +struct type_list_contains; + +/** + * @copybrief type_list_contains + * @tparam Type Types provided by the type list. + * @tparam Other Type to look for. + */ +template +struct type_list_contains, Other> + : std::bool_constant<(std::is_same_v || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +inline constexpr bool type_list_contains_v = type_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_diff; + +/** + * @brief Computes the difference between two type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + */ +template +struct type_list_diff, type_list> { + /*! @brief A type list that is the difference between the two type lists. */ + using type = type_list_cat_t, Type>, type_list<>, type_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Type lists between which to compute the difference. + */ +template +using type_list_diff_t = typename type_list_diff::type; + +/*! @brief Primary template isn't defined on purpose. */ +template class> +struct type_list_transform; + +/** + * @brief Applies a given _function_ to a type list and generate a new list. + * @tparam Type Types provided by the type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +struct type_list_transform, Op> { + /*! @brief Resulting type list after applying the transform function. */ + // NOLINTNEXTLINE(modernize-type-traits) + using type = type_list::type...>; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +using type_list_transform_t = typename type_list_transform::type; + +/** + * @brief A class to use to push around lists of constant values, nothing more. + * @tparam Value Values provided by the value list. + */ +template +struct value_list { + /*! @brief Value list type. */ + using type = value_list; + /*! @brief Compile-time number of elements in the value list. */ + static constexpr auto size = sizeof...(Value); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_element; + +/** + * @brief Provides compile-time indexed access to the values of a value list. + * @tparam Index Index of the value to return. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element> + : value_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element<0u, value_list> { + /*! @brief Searched type. */ + using type = decltype(Value); + /*! @brief Searched value. */ + static constexpr auto value = Value; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Value list to search into. + */ +template +using value_list_element_t = typename value_list_element::type; + +/** + * @brief Helper type. + * @tparam Index Index of the value to return. + * @tparam List Value list to search into. + */ +template +inline constexpr auto value_list_element_v = value_list_element::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_index; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam First First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 1u + value_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + static_assert(value_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +inline constexpr std::size_t value_list_index_v = value_list_index::value; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @return A value list composed by the values of both the value lists. + */ +template +constexpr value_list operator+(value_list, value_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_cat; + +/*! @brief Concatenates multiple value lists. */ +template<> +struct value_list_cat<> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list<>; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @tparam List Other value lists, if any. + */ +template +struct value_list_cat, value_list, List...> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = typename value_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the value list. + */ +template +struct value_list_cat> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list; +}; + +/** + * @brief Helper type. + * @tparam List Value lists to concatenate. + */ +template +using value_list_cat_t = typename value_list_cat::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_unique; + +/** + * @brief Removes duplicates values from a value list. + * @tparam Value One of the values provided by the given value list. + * @tparam Other The other values provided by the given value list. + */ +template +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = std::conditional_t< + ((Value == Other) || ...), + typename value_list_unique>::type, + value_list_cat_t, typename value_list_unique>::type>>; +}; + +/*! @brief Removes duplicates values from a value list. */ +template<> +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = value_list<>; +}; + +/** + * @brief Helper type. + * @tparam Type A value list. + */ +template +using value_list_unique_t = typename value_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a value list contains + * a given value, false otherwise. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +struct value_list_contains; + +/** + * @copybrief value_list_contains + * @tparam Value Values provided by the value list. + * @tparam Other Value to look for. + */ +template +struct value_list_contains, Other> + : std::bool_constant<((Value == Other) || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +inline constexpr bool value_list_contains_v = value_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_diff; + +/** + * @brief Computes the difference between two value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + */ +template +struct value_list_diff, value_list> { + /*! @brief A value list that is the difference between the two value lists. */ + using type = value_list_cat_t, Value>, value_list<>, value_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Value lists between which to compute the difference. + */ +template +using value_list_diff_t = typename value_list_diff::type; + +/*! @brief Same as std::is_invocable, but with tuples. */ +template +struct is_applicable: std::false_type {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @brief Helper variable template. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_v = is_applicable::value; + +/*! @brief Same as std::is_invocable_r, but with tuples for arguments. */ +template +struct is_applicable_r: std::false_type {}; + +/** + * @copybrief is_applicable_r + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +struct is_applicable_r>: std::is_invocable_r {}; + +/** + * @brief Helper variable template. + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_r_v = is_applicable_r::value; + +/** + * @brief Provides the member constant `value` to true if a given type is + * complete, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_complete: std::false_type {}; + +/*! @copydoc is_complete */ +template +struct is_complete>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_complete_v = is_complete::value; + +/** + * @brief Provides the member constant `value` to true if a given type is an + * iterator, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_iterator: std::false_type {}; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_iterator_category: std::false_type {}; + +template +struct has_iterator_category::iterator_category>>: std::true_type {}; + +} // namespace internal +/*! @endcond */ + +/*! @copydoc is_iterator */ +template +struct is_iterator>>>> + : internal::has_iterator_category {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_iterator_v = is_iterator::value; + +/** + * @brief Provides the member constant `value` to true if a given type is both + * an empty and non-final class, false otherwise. + * @tparam Type The type to test + */ +template +struct is_ebco_eligible + : std::bool_constant && !std::is_final_v> {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_ebco_eligible_v = is_ebco_eligible::value; + +/** + * @brief Provides the member constant `value` to true if `Type::is_transparent` + * is valid and denotes a type, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_transparent: std::false_type {}; + +/*! @copydoc is_transparent */ +template +struct is_transparent>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_transparent_v = is_transparent::value; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_tuple_size_value: std::false_type {}; + +template +struct has_tuple_size_value::value)>>: std::true_type {}; + +template +struct has_value_type: std::false_type {}; + +template +struct has_value_type>: std::true_type {}; + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable(); + +template +[[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence) { + return (dispatch_is_equality_comparable>() && ...); +} + +template +[[nodiscard]] constexpr bool maybe_equality_comparable(char) { + return false; +} + +template +[[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval() == std::declval()) { + return true; +} + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable() { + // NOLINTBEGIN(modernize-use-transparent-functors) + if constexpr(std::is_array_v) { + return false; + } else if constexpr(is_complete_v>>) { + if constexpr(has_tuple_size_value::value) { + return maybe_equality_comparable(0) && unpack_maybe_equality_comparable(std::make_index_sequence::value>{}); + } else { + return maybe_equality_comparable(0); + } + } else if constexpr(has_value_type::value) { + if constexpr(is_iterator_v || std::is_same_v || dispatch_is_equality_comparable()) { + return maybe_equality_comparable(0); + } else { + return false; + } + } else { + return maybe_equality_comparable(0); + } + // NOLINTEND(modernize-use-transparent-functors) +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Provides the member constant `value` to true if a given type is + * equality comparable, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_equality_comparable: std::bool_constant()> {}; + +/*! @copydoc is_equality_comparable */ +template +struct is_equality_comparable: is_equality_comparable {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_equality_comparable_v = is_equality_comparable::value; + +/** + * @brief Transcribes the constness of a type to another type. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = std::remove_const_t; +}; + +/*! @copydoc constness_as */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = const To; +}; + +/** + * @brief Alias template to facilitate the transcription of the constness. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +using constness_as_t = typename constness_as::type; + +/** + * @brief Extracts the class of a non-static member object or function. + * @tparam Member A pointer to a non-static member object or function. + */ +template +class member_class { + static_assert(std::is_member_pointer_v, "Invalid pointer type to non-static member object or function"); + + template + static Class *clazz(Ret (Class::*)(Args...)); + + template + static Class *clazz(Ret (Class::*)(Args...) const); + + template + static Class *clazz(Type Class::*); + +public: + /*! @brief The class of the given non-static member object or function. */ + using type = std::remove_pointer_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Member A pointer to a non-static member object or function. + */ +template +using member_class_t = typename member_class::type; + +/** + * @brief Extracts the n-th argument of a _callable_ type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid _callable_ type. + */ +template +class nth_argument { + template + static constexpr type_list pick_up(Ret (*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...) const); + + template + static constexpr type_list pick_up(Type Class ::*); + + template + static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&); + +public: + /*! @brief N-th argument of the _callable_ type. */ + using type = type_list_element_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid function, member function or data member type. + */ +template +using nth_argument_t = typename nth_argument::type; + +} // namespace entt + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::type_list_element> {}; + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::value_list_element> {}; + +#endif + +// #include "fwd.hpp" +#ifndef ENTT_CONTAINER_FWD_HPP +#define ENTT_CONTAINER_FWD_HPP + +#include +#include +#include +#include + +namespace entt { + +template< + typename Key, + typename Type, + typename = std::hash, + typename = std::equal_to<>, + typename = std::allocator>> +class dense_map; + +template< + typename Type, + typename = std::hash, + typename = std::equal_to<>, + typename = std::allocator> +class dense_set; + +template +class basic_table; + +/** + * @brief Alias declaration for the most common use case. + * @tparam Type Element types. + */ +template +using table = basic_table...>; + +} // namespace entt + +#endif + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +static constexpr std::size_t dense_map_placeholder_position = (std::numeric_limits::max)(); + +template +struct dense_map_node final { + using value_type = std::pair; + + template + dense_map_node(const std::size_t pos, Args &&...args) + : next{pos}, + element{std::forward(args)...} {} + + template + dense_map_node(std::allocator_arg_t, const Allocator &allocator, const std::size_t pos, Args &&...args) + : next{pos}, + element{entt::make_obj_using_allocator(allocator, std::forward(args)...)} {} + + template + dense_map_node(std::allocator_arg_t, const Allocator &allocator, const dense_map_node &other) + : next{other.next}, + element{entt::make_obj_using_allocator(allocator, other.element)} {} + + template + dense_map_node(std::allocator_arg_t, const Allocator &allocator, dense_map_node &&other) + : next{other.next}, + element{entt::make_obj_using_allocator(allocator, std::move(other.element))} {} + + std::size_t next; + value_type element; +}; + +template +class dense_map_iterator final { + template + friend class dense_map_iterator; + + using first_type = decltype(std::as_const(std::declval()->element.first)); + using second_type = decltype((std::declval()->element.second)); + +public: + using value_type = std::pair; + using pointer = input_iterator_pointer; + using reference = value_type; + using difference_type = std::ptrdiff_t; + using iterator_category = std::input_iterator_tag; + using iterator_concept = std::random_access_iterator_tag; + + constexpr dense_map_iterator() noexcept + : it{} {} + + constexpr dense_map_iterator(const It iter) noexcept + : it{iter} {} + + template && std::is_constructible_v>> + constexpr dense_map_iterator(const dense_map_iterator &other) noexcept + : it{other.it} {} + + constexpr dense_map_iterator &operator++() noexcept { + return ++it, *this; + } + + constexpr dense_map_iterator operator++(int) noexcept { + const dense_map_iterator orig = *this; + return ++(*this), orig; + } + + constexpr dense_map_iterator &operator--() noexcept { + return --it, *this; + } + + constexpr dense_map_iterator operator--(int) noexcept { + const dense_map_iterator orig = *this; + return operator--(), orig; + } + + constexpr dense_map_iterator &operator+=(const difference_type value) noexcept { + it += value; + return *this; + } + + constexpr dense_map_iterator operator+(const difference_type value) const noexcept { + dense_map_iterator copy = *this; + return (copy += value); + } + + constexpr dense_map_iterator &operator-=(const difference_type value) noexcept { + return (*this += -value); + } + + constexpr dense_map_iterator operator-(const difference_type value) const noexcept { + return (*this + -value); + } + + [[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept { + return {it[value].element.first, it[value].element.second}; + } + + [[nodiscard]] constexpr pointer operator->() const noexcept { + return operator*(); + } + + [[nodiscard]] constexpr reference operator*() const noexcept { + return operator[](0); + } + + template + friend constexpr std::ptrdiff_t operator-(const dense_map_iterator &, const dense_map_iterator &) noexcept; + + template + friend constexpr bool operator==(const dense_map_iterator &, const dense_map_iterator &) noexcept; + + template + friend constexpr bool operator<(const dense_map_iterator &, const dense_map_iterator &) noexcept; + +private: + It it; +}; + +template +[[nodiscard]] constexpr std::ptrdiff_t operator-(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return lhs.it - rhs.it; +} + +template +[[nodiscard]] constexpr bool operator==(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return lhs.it == rhs.it; +} + +template +[[nodiscard]] constexpr bool operator!=(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +template +[[nodiscard]] constexpr bool operator<(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return lhs.it < rhs.it; +} + +template +[[nodiscard]] constexpr bool operator>(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return rhs < lhs; +} + +template +[[nodiscard]] constexpr bool operator<=(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return !(lhs > rhs); +} + +template +[[nodiscard]] constexpr bool operator>=(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return !(lhs < rhs); +} + +template +class dense_map_local_iterator final { + template + friend class dense_map_local_iterator; + + using first_type = decltype(std::as_const(std::declval()->element.first)); + using second_type = decltype((std::declval()->element.second)); + +public: + using value_type = std::pair; + using pointer = input_iterator_pointer; + using reference = value_type; + using difference_type = std::ptrdiff_t; + using iterator_category = std::input_iterator_tag; + using iterator_concept = std::forward_iterator_tag; + + constexpr dense_map_local_iterator() noexcept = default; + + constexpr dense_map_local_iterator(It iter, const std::size_t pos) noexcept + : it{iter}, + offset{pos} {} + + template && std::is_constructible_v>> + constexpr dense_map_local_iterator(const dense_map_local_iterator &other) noexcept + : it{other.it}, + offset{other.offset} {} + + constexpr dense_map_local_iterator &operator++() noexcept { + return (offset = it[static_cast(offset)].next), *this; + } + + constexpr dense_map_local_iterator operator++(int) noexcept { + const dense_map_local_iterator orig = *this; + return ++(*this), orig; + } + + [[nodiscard]] constexpr pointer operator->() const noexcept { + return operator*(); + } + + [[nodiscard]] constexpr reference operator*() const noexcept { + const auto idx = static_cast(offset); + return {it[idx].element.first, it[idx].element.second}; + } + + [[nodiscard]] constexpr std::size_t index() const noexcept { + return offset; + } + +private: + It it{}; + std::size_t offset{dense_map_placeholder_position}; +}; + +template +[[nodiscard]] constexpr bool operator==(const dense_map_local_iterator &lhs, const dense_map_local_iterator &rhs) noexcept { + return lhs.index() == rhs.index(); +} + +template +[[nodiscard]] constexpr bool operator!=(const dense_map_local_iterator &lhs, const dense_map_local_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Associative container for key-value pairs with unique keys. + * + * Internally, elements are organized into buckets. Which bucket an element is + * placed into depends entirely on the hash of its key. Keys with the same hash + * code appear in the same bucket. + * + * @tparam Key Key type of the associative container. + * @tparam Type Mapped type of the associative container. + * @tparam Hash Type of function to use to hash the keys. + * @tparam KeyEqual Type of function to use to compare the keys for equality. + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +class dense_map { + static constexpr float default_threshold = 0.875f; + static constexpr std::size_t minimum_capacity = 8u; + static constexpr std::size_t placeholder_position = internal::dense_map_placeholder_position; + + using node_type = internal::dense_map_node; + using alloc_traits = std::allocator_traits; + static_assert(std::is_same_v>, "Invalid value type"); + using sparse_container_type = std::vector>; + using packed_container_type = std::vector>; + + template + [[nodiscard]] std::size_t key_to_bucket(const Other &key) const noexcept { + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay) + return fast_mod(static_cast(sparse.second()(key)), bucket_count()); + } + + template + [[nodiscard]] auto constrained_find(const Other &key, const std::size_t bucket) { + for(auto offset = sparse.first()[bucket]; offset != placeholder_position; offset = packed.first()[offset].next) { + if(packed.second()(packed.first()[offset].element.first, key)) { + return begin() + static_cast(offset); + } + } + + return end(); + } + + template + [[nodiscard]] auto constrained_find(const Other &key, const std::size_t bucket) const { + for(auto offset = sparse.first()[bucket]; offset != placeholder_position; offset = packed.first()[offset].next) { + if(packed.second()(packed.first()[offset].element.first, key)) { + return cbegin() + static_cast(offset); + } + } + + return cend(); + } + + template + [[nodiscard]] auto insert_or_do_nothing(Other &&key, Args &&...args) { + const auto index = key_to_bucket(key); + + if(auto it = constrained_find(key, index); it != end()) { + return std::make_pair(it, false); + } + + packed.first().emplace_back(sparse.first()[index], std::piecewise_construct, std::forward_as_tuple(std::forward(key)), std::forward_as_tuple(std::forward(args)...)); + sparse.first()[index] = packed.first().size() - 1u; + rehash_if_required(); + + return std::make_pair(--end(), true); + } + + template + [[nodiscard]] auto insert_or_overwrite(Other &&key, Arg &&value) { + const auto index = key_to_bucket(key); + + if(auto it = constrained_find(key, index); it != end()) { + it->second = std::forward(value); + return std::make_pair(it, false); + } + + packed.first().emplace_back(sparse.first()[index], std::forward(key), std::forward(value)); + sparse.first()[index] = packed.first().size() - 1u; + rehash_if_required(); + + return std::make_pair(--end(), true); + } + + void move_and_pop(const std::size_t pos) { + if(const auto last = size() - 1u; pos != last) { + size_type *curr = &sparse.first()[key_to_bucket(packed.first().back().element.first)]; + packed.first()[pos] = std::move(packed.first().back()); + for(; *curr != last; curr = &packed.first()[*curr].next) {} + *curr = pos; + } + + packed.first().pop_back(); + } + + void rehash_if_required() { + if(const auto bc = bucket_count(); size() > static_cast(static_cast(bc) * max_load_factor())) { + rehash(bc * 2u); + } + } + +public: + /*! @brief Allocator type. */ + using allocator_type = Allocator; + /*! @brief Key type of the container. */ + using key_type = Key; + /*! @brief Mapped type of the container. */ + using mapped_type = Type; + /*! @brief Key-value type of the container. */ + using value_type = std::pair; + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + /*! @brief Signed integer type. */ + using difference_type = std::ptrdiff_t; + /*! @brief Type of function to use to hash the keys. */ + using hasher = Hash; + /*! @brief Type of function to use to compare the keys for equality. */ + using key_equal = KeyEqual; + /*! @brief Input iterator type. */ + using iterator = internal::dense_map_iterator; + /*! @brief Constant input iterator type. */ + using const_iterator = internal::dense_map_iterator; + /*! @brief Input iterator type. */ + using local_iterator = internal::dense_map_local_iterator; + /*! @brief Constant input iterator type. */ + using const_local_iterator = internal::dense_map_local_iterator; + + /*! @brief Default constructor. */ + dense_map() + : dense_map{minimum_capacity} {} + + /** + * @brief Constructs an empty container with a given allocator. + * @param allocator The allocator to use. + */ + explicit dense_map(const allocator_type &allocator) + : dense_map{minimum_capacity, hasher{}, key_equal{}, allocator} {} + + /** + * @brief Constructs an empty container with a given allocator and user + * supplied minimal number of buckets. + * @param cnt Minimal number of buckets. + * @param allocator The allocator to use. + */ + dense_map(const size_type cnt, const allocator_type &allocator) + : dense_map{cnt, hasher{}, key_equal{}, allocator} {} + + /** + * @brief Constructs an empty container with a given allocator, hash + * function and user supplied minimal number of buckets. + * @param cnt Minimal number of buckets. + * @param hash Hash function to use. + * @param allocator The allocator to use. + */ + dense_map(const size_type cnt, const hasher &hash, const allocator_type &allocator) + : dense_map{cnt, hash, key_equal{}, allocator} {} + + /** + * @brief Constructs an empty container with a given allocator, hash + * function, compare function and user supplied minimal number of buckets. + * @param cnt Minimal number of buckets. + * @param hash Hash function to use. + * @param equal Compare function to use. + * @param allocator The allocator to use. + */ + explicit dense_map(const size_type cnt, const hasher &hash = hasher{}, const key_equal &equal = key_equal{}, const allocator_type &allocator = allocator_type{}) + : sparse{allocator, hash}, + packed{allocator, equal} { + rehash(cnt); + } + + /*! @brief Default copy constructor. */ + dense_map(const dense_map &) = default; + + /** + * @brief Allocator-extended copy constructor. + * @param other The instance to copy from. + * @param allocator The allocator to use. + */ + dense_map(const dense_map &other, const allocator_type &allocator) + : sparse{std::piecewise_construct, std::forward_as_tuple(other.sparse.first(), allocator), std::forward_as_tuple(other.sparse.second())}, + packed{std::piecewise_construct, std::forward_as_tuple(other.packed.first(), allocator), std::forward_as_tuple(other.packed.second())}, + threshold{other.threshold} {} + + /*! @brief Default move constructor. */ + dense_map(dense_map &&) noexcept = default; + + /** + * @brief Allocator-extended move constructor. + * @param other The instance to move from. + * @param allocator The allocator to use. + */ + dense_map(dense_map &&other, const allocator_type &allocator) + : sparse{std::piecewise_construct, std::forward_as_tuple(std::move(other.sparse.first()), allocator), std::forward_as_tuple(std::move(other.sparse.second()))}, + packed{std::piecewise_construct, std::forward_as_tuple(std::move(other.packed.first()), allocator), std::forward_as_tuple(std::move(other.packed.second()))}, + threshold{other.threshold} {} + + /*! @brief Default destructor. */ + ~dense_map() = default; + + /** + * @brief Default copy assignment operator. + * @return This container. + */ + dense_map &operator=(const dense_map &) = default; + + /** + * @brief Default move assignment operator. + * @return This container. + */ + dense_map &operator=(dense_map &&) noexcept = default; + + /** + * @brief Exchanges the contents with those of a given container. + * @param other Container to exchange the content with. + */ + void swap(dense_map &other) noexcept { + using std::swap; + swap(sparse, other.sparse); + swap(packed, other.packed); + swap(threshold, other.threshold); + } + + /** + * @brief Returns the associated allocator. + * @return The associated allocator. + */ + [[nodiscard]] constexpr allocator_type get_allocator() const noexcept { + return sparse.first().get_allocator(); + } + + /** + * @brief Returns an iterator to the beginning. + * + * If the array is empty, the returned iterator will be equal to `end()`. + * + * @return An iterator to the first instance of the internal array. + */ + [[nodiscard]] const_iterator cbegin() const noexcept { + return packed.first().begin(); + } + + /*! @copydoc cbegin */ + [[nodiscard]] const_iterator begin() const noexcept { + return cbegin(); + } + + /*! @copydoc begin */ + [[nodiscard]] iterator begin() noexcept { + return packed.first().begin(); + } + + /** + * @brief Returns an iterator to the end. + * @return An iterator to the element following the last instance of the + * internal array. + */ + [[nodiscard]] const_iterator cend() const noexcept { + return packed.first().end(); + } + + /*! @copydoc cend */ + [[nodiscard]] const_iterator end() const noexcept { + return cend(); + } + + /*! @copydoc end */ + [[nodiscard]] iterator end() noexcept { + return packed.first().end(); + } + + /** + * @brief Checks whether a container is empty. + * @return True if the container is empty, false otherwise. + */ + [[nodiscard]] bool empty() const noexcept { + return packed.first().empty(); + } + + /** + * @brief Returns the number of elements in a container. + * @return Number of elements in a container. + */ + [[nodiscard]] size_type size() const noexcept { + return packed.first().size(); + } + + /** + * @brief Returns the maximum possible number of elements. + * @return Maximum possible number of elements. + */ + [[nodiscard]] size_type max_size() const noexcept { + return packed.first().max_size(); + } + + /*! @brief Clears the container. */ + void clear() noexcept { + sparse.first().clear(); + packed.first().clear(); + rehash(0u); + } + + /** + * @brief Inserts an element into the container, if the key does not exist. + * @param value A key-value pair eventually convertible to the value type. + * @return A pair consisting of an iterator to the inserted element (or to + * the element that prevented the insertion) and a bool denoting whether the + * insertion took place. + */ + std::pair insert(const value_type &value) { + return insert_or_do_nothing(value.first, value.second); + } + + /*! @copydoc insert */ + std::pair insert(value_type &&value) { + return insert_or_do_nothing(std::move(value.first), std::move(value.second)); + } + + /** + * @copydoc insert + * @tparam Arg Type of the key-value pair to insert into the container. + */ + template + std::enable_if_t, std::pair> + insert(Arg &&value) { + return insert_or_do_nothing(std::forward(value).first, std::forward(value).second); + } + + /** + * @brief Inserts elements into the container, if their keys do not exist. + * @tparam It Type of input iterator. + * @param first An iterator to the first element of the range of elements. + * @param last An iterator past the last element of the range of elements. + */ + template + void insert(It first, It last) { + for(; first != last; ++first) { + insert(*first); + } + } + + /** + * @brief Inserts an element into the container or assigns to the current + * element if the key already exists. + * @tparam Arg Type of the value to insert or assign. + * @param key A key used both to look up and to insert if not found. + * @param value A value to insert or assign. + * @return A pair consisting of an iterator to the element and a bool + * denoting whether the insertion took place. + */ + template + std::pair insert_or_assign(const key_type &key, Arg &&value) { + return insert_or_overwrite(key, std::forward(value)); + } + + /*! @copydoc insert_or_assign */ + template + std::pair insert_or_assign(key_type &&key, Arg &&value) { + return insert_or_overwrite(std::move(key), std::forward(value)); + } + + /** + * @brief Constructs an element in-place, if the key does not exist. + * + * The element is also constructed when the container already has the key, + * in which case the newly constructed object is destroyed immediately. + * + * @tparam Args Types of arguments to forward to the constructor of the + * element. + * @param args Arguments to forward to the constructor of the element. + * @return A pair consisting of an iterator to the inserted element (or to + * the element that prevented the insertion) and a bool denoting whether the + * insertion took place. + */ + template + std::pair emplace([[maybe_unused]] Args &&...args) { + if constexpr(sizeof...(Args) == 0u) { + return insert_or_do_nothing(key_type{}); + } else if constexpr(sizeof...(Args) == 1u) { + return insert_or_do_nothing(std::forward(args).first..., std::forward(args).second...); + } else if constexpr(sizeof...(Args) == 2u) { + return insert_or_do_nothing(std::forward(args)...); + } else { + auto &node = packed.first().emplace_back(packed.first().size(), std::forward(args)...); + const auto index = key_to_bucket(node.element.first); + + if(auto it = constrained_find(node.element.first, index); it != end()) { + packed.first().pop_back(); + return std::make_pair(it, false); + } + + std::swap(node.next, sparse.first()[index]); + rehash_if_required(); + + return std::make_pair(--end(), true); + } + } + + /** + * @brief Inserts in-place if the key does not exist, does nothing if the + * key exists. + * @tparam Args Types of arguments to forward to the constructor of the + * element. + * @param key A key used both to look up and to insert if not found. + * @param args Arguments to forward to the constructor of the element. + * @return A pair consisting of an iterator to the inserted element (or to + * the element that prevented the insertion) and a bool denoting whether the + * insertion took place. + */ + template + std::pair try_emplace(const key_type &key, Args &&...args) { + return insert_or_do_nothing(key, std::forward(args)...); + } + + /*! @copydoc try_emplace */ + template + std::pair try_emplace(key_type &&key, Args &&...args) { + return insert_or_do_nothing(std::move(key), std::forward(args)...); + } + + /** + * @brief Removes an element from a given position. + * @param pos An iterator to the element to remove. + * @return An iterator following the removed element. + */ + iterator erase(const_iterator pos) { + const auto diff = pos - cbegin(); + erase(pos->first); + return begin() + diff; + } + + /** + * @brief Removes the given elements from a container. + * @param first An iterator to the first element of the range of elements. + * @param last An iterator past the last element of the range of elements. + * @return An iterator following the last removed element. + */ + iterator erase(const_iterator first, const_iterator last) { + const auto dist = first - cbegin(); + + for(auto from = last - cbegin(); from != dist; --from) { + erase(packed.first()[static_cast(from) - 1u].element.first); + } + + return (begin() + dist); + } + + /** + * @brief Removes the element associated with a given key. + * @param key A key value of an element to remove. + * @return Number of elements removed (either 0 or 1). + */ + size_type erase(const key_type &key) { + for(size_type *curr = &sparse.first()[key_to_bucket(key)]; *curr != placeholder_position; curr = &packed.first()[*curr].next) { + if(packed.second()(packed.first()[*curr].element.first, key)) { + const auto index = *curr; + *curr = packed.first()[*curr].next; + move_and_pop(index); + return 1u; + } + } + + return 0u; + } + + /** + * @brief Accesses a given element with bounds checking. + * @param key A key of an element to find. + * @return A reference to the mapped value of the requested element. + */ + [[nodiscard]] mapped_type &at(const key_type &key) { + auto it = find(key); + ENTT_ASSERT(it != end(), "Invalid key"); + return it->second; + } + + /*! @copydoc at */ + [[nodiscard]] const mapped_type &at(const key_type &key) const { + auto it = find(key); + ENTT_ASSERT(it != cend(), "Invalid key"); + return it->second; + } + + /** + * @brief Accesses a given element with bounds checking. + * @tparam Other Type of the key of an element to find. + * @param key A key of an element to find. + * @return A reference to the mapped value of the requested element. + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + at(const Other &key) const { + auto it = find(key); + ENTT_ASSERT(it != cend(), "Invalid key"); + return it->second; + } + + /*! @copydoc at */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + at(const Other &key) { + auto it = find(key); + ENTT_ASSERT(it != end(), "Invalid key"); + return it->second; + } + + /** + * @brief Accesses or inserts a given element. + * @param key A key of an element to find or insert. + * @return A reference to the mapped value of the requested element. + */ + [[nodiscard]] mapped_type &operator[](const key_type &key) { + return insert_or_do_nothing(key).first->second; + } + + /** + * @brief Accesses or inserts a given element. + * @param key A key of an element to find or insert. + * @return A reference to the mapped value of the requested element. + */ + [[nodiscard]] mapped_type &operator[](key_type &&key) { + return insert_or_do_nothing(std::move(key)).first->second; + } + + /** + * @brief Returns the number of elements matching a key (either 1 or 0). + * @param key Key value of an element to search for. + * @return Number of elements matching the key (either 1 or 0). + */ + [[nodiscard]] size_type count(const key_type &key) const { + return find(key) != end(); + } + + /** + * @brief Returns the number of elements matching a key (either 1 or 0). + * @tparam Other Type of the key value of an element to search for. + * @param key Key value of an element to search for. + * @return Number of elements matching the key (either 1 or 0). + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + count(const Other &key) const { + return find(key) != end(); + } + + /** + * @brief Finds an element with a given key. + * @param key Key value of an element to search for. + * @return An iterator to an element with the given key. If no such element + * is found, a past-the-end iterator is returned. + */ + [[nodiscard]] iterator find(const key_type &key) { + return constrained_find(key, key_to_bucket(key)); + } + + /*! @copydoc find */ + [[nodiscard]] const_iterator find(const key_type &key) const { + return constrained_find(key, key_to_bucket(key)); + } + + /** + * @brief Finds an element with a key that compares _equivalent_ to a given + * key. + * @tparam Other Type of the key value of an element to search for. + * @param key Key value of an element to search for. + * @return An iterator to an element with the given key. If no such element + * is found, a past-the-end iterator is returned. + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + find(const Other &key) { + return constrained_find(key, key_to_bucket(key)); + } + + /*! @copydoc find */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + find(const Other &key) const { + return constrained_find(key, key_to_bucket(key)); + } + + /** + * @brief Returns a range containing all elements with a given key. + * @param key Key value of an element to search for. + * @return A pair of iterators pointing to the first element and past the + * last element of the range. + */ + [[nodiscard]] std::pair equal_range(const key_type &key) { + const auto it = find(key); + return {it, it + !(it == end())}; + } + + /*! @copydoc equal_range */ + [[nodiscard]] std::pair equal_range(const key_type &key) const { + const auto it = find(key); + return {it, it + !(it == cend())}; + } + + /** + * @brief Returns a range containing all elements that compare _equivalent_ + * to a given key. + * @tparam Other Type of an element to search for. + * @param key Key value of an element to search for. + * @return A pair of iterators pointing to the first element and past the + * last element of the range. + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t>> + equal_range(const Other &key) { + const auto it = find(key); + return {it, it + !(it == end())}; + } + + /*! @copydoc equal_range */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t>> + equal_range(const Other &key) const { + const auto it = find(key); + return {it, it + !(it == cend())}; + } + + /** + * @brief Checks if the container contains an element with a given key. + * @param key Key value of an element to search for. + * @return True if there is such an element, false otherwise. + */ + [[nodiscard]] bool contains(const key_type &key) const { + return (find(key) != cend()); + } + + /** + * @brief Checks if the container contains an element with a key that + * compares _equivalent_ to a given value. + * @tparam Other Type of the key value of an element to search for. + * @param key Key value of an element to search for. + * @return True if there is such an element, false otherwise. + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + contains(const Other &key) const { + return (find(key) != cend()); + } + + /** + * @brief Returns an iterator to the beginning of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the beginning of the given bucket. + */ + [[nodiscard]] const_local_iterator cbegin(const size_type index) const { + return {packed.first().begin(), sparse.first()[index]}; + } + + /** + * @brief Returns an iterator to the beginning of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the beginning of the given bucket. + */ + [[nodiscard]] const_local_iterator begin(const size_type index) const { + return cbegin(index); + } + + /** + * @brief Returns an iterator to the beginning of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the beginning of the given bucket. + */ + [[nodiscard]] local_iterator begin(const size_type index) { + return {packed.first().begin(), sparse.first()[index]}; + } + + /** + * @brief Returns an iterator to the end of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the end of the given bucket. + */ + [[nodiscard]] const_local_iterator cend([[maybe_unused]] const size_type index) const { + return {}; + } + + /** + * @brief Returns an iterator to the end of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the end of the given bucket. + */ + [[nodiscard]] const_local_iterator end(const size_type index) const { + return cend(index); + } + + /** + * @brief Returns an iterator to the end of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the end of the given bucket. + */ + [[nodiscard]] local_iterator end([[maybe_unused]] const size_type index) { + return {}; + } + + /** + * @brief Returns the number of buckets. + * @return The number of buckets. + */ + [[nodiscard]] size_type bucket_count() const { + return sparse.first().size(); + } + + /** + * @brief Returns the maximum number of buckets. + * @return The maximum number of buckets. + */ + [[nodiscard]] size_type max_bucket_count() const { + return sparse.first().max_size(); + } + + /** + * @brief Returns the number of elements in a given bucket. + * @param index The index of the bucket to examine. + * @return The number of elements in the given bucket. + */ + [[nodiscard]] size_type bucket_size(const size_type index) const { + return static_cast(std::distance(begin(index), end(index))); + } + + /** + * @brief Returns the bucket for a given key. + * @param key The value of the key to examine. + * @return The bucket for the given key. + */ + [[nodiscard]] size_type bucket(const key_type &key) const { + return key_to_bucket(key); + } + + /** + * @brief Returns the average number of elements per bucket. + * @return The average number of elements per bucket. + */ + [[nodiscard]] float load_factor() const { + return static_cast(size()) / static_cast(bucket_count()); + } + + /** + * @brief Returns the maximum average number of elements per bucket. + * @return The maximum average number of elements per bucket. + */ + [[nodiscard]] float max_load_factor() const { + return threshold; + } + + /** + * @brief Sets the desired maximum average number of elements per bucket. + * @param value A desired maximum average number of elements per bucket. + */ + void max_load_factor(const float value) { + ENTT_ASSERT(value > 0.f, "Invalid load factor"); + threshold = value; + rehash(0u); + } + + /** + * @brief Reserves at least the specified number of buckets and regenerates + * the hash table. + * @param cnt New number of buckets. + */ + void rehash(const size_type cnt) { + auto value = cnt > minimum_capacity ? cnt : minimum_capacity; + const auto cap = static_cast(static_cast(size()) / max_load_factor()); + value = value > cap ? value : cap; + + if(const auto sz = next_power_of_two(value); sz != bucket_count()) { + sparse.first().resize(sz); + + for(auto &&elem: sparse.first()) { + elem = placeholder_position; + } + + for(size_type pos{}, last = size(); pos < last; ++pos) { + const auto index = key_to_bucket(packed.first()[pos].element.first); + packed.first()[pos].next = std::exchange(sparse.first()[index], pos); + } + } + } + + /** + * @brief Reserves space for at least the specified number of elements and + * regenerates the hash table. + * @param cnt New number of elements. + */ + void reserve(const size_type cnt) { + packed.first().reserve(cnt); + rehash(static_cast(std::ceil(static_cast(cnt) / max_load_factor()))); + } + + /** + * @brief Returns the function used to hash the keys. + * @return The function used to hash the keys. + */ + [[nodiscard]] hasher hash_function() const { + return sparse.second(); + } + + /** + * @brief Returns the function used to compare keys for equality. + * @return The function used to compare keys for equality. + */ + [[nodiscard]] key_equal key_eq() const { + return packed.second(); + } + +private: + compressed_pair sparse; + compressed_pair packed; + float threshold{default_threshold}; +}; + +} // namespace entt + +/*! @cond TURN_OFF_DOXYGEN */ +namespace std { + +template +struct uses_allocator, Allocator> + : std::true_type {}; + +} // namespace std +/*! @endcond */ + +#endif + +// #include "../container/dense_set.hpp" +#ifndef ENTT_CONTAINER_DENSE_SET_HPP +#define ENTT_CONTAINER_DENSE_SET_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "../core/bit.hpp" + +// #include "../core/compressed_pair.hpp" + +// #include "../core/type_traits.hpp" + +// #include "fwd.hpp" + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +static constexpr std::size_t dense_set_placeholder_position = (std::numeric_limits::max)(); + +template +class dense_set_iterator final { + template + friend class dense_set_iterator; + +public: + using value_type = typename It::value_type::second_type; + using pointer = const value_type *; + using reference = const value_type &; + using difference_type = std::ptrdiff_t; + using iterator_category = std::random_access_iterator_tag; + + constexpr dense_set_iterator() noexcept + : it{} {} + + constexpr dense_set_iterator(const It iter) noexcept + : it{iter} {} + + template && std::is_constructible_v>> + constexpr dense_set_iterator(const dense_set_iterator &other) noexcept + : it{other.it} {} + + constexpr dense_set_iterator &operator++() noexcept { + return ++it, *this; + } + + constexpr dense_set_iterator operator++(int) noexcept { + const dense_set_iterator orig = *this; + return ++(*this), orig; + } + + constexpr dense_set_iterator &operator--() noexcept { + return --it, *this; + } + + constexpr dense_set_iterator operator--(int) noexcept { + const dense_set_iterator orig = *this; + return operator--(), orig; + } + + constexpr dense_set_iterator &operator+=(const difference_type value) noexcept { + it += value; + return *this; + } + + constexpr dense_set_iterator operator+(const difference_type value) const noexcept { + dense_set_iterator copy = *this; + return (copy += value); + } + + constexpr dense_set_iterator &operator-=(const difference_type value) noexcept { + return (*this += -value); + } + + constexpr dense_set_iterator operator-(const difference_type value) const noexcept { + return (*this + -value); + } + + [[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept { + return it[value].second; + } + + [[nodiscard]] constexpr pointer operator->() const noexcept { + return std::addressof(operator[](0)); + } + + [[nodiscard]] constexpr reference operator*() const noexcept { + return operator[](0); + } + + template + friend constexpr std::ptrdiff_t operator-(const dense_set_iterator &, const dense_set_iterator &) noexcept; + + template + friend constexpr bool operator==(const dense_set_iterator &, const dense_set_iterator &) noexcept; + + template + friend constexpr bool operator<(const dense_set_iterator &, const dense_set_iterator &) noexcept; + +private: + It it; +}; + +template +[[nodiscard]] constexpr std::ptrdiff_t operator-(const dense_set_iterator &lhs, const dense_set_iterator &rhs) noexcept { + return lhs.it - rhs.it; +} + +template +[[nodiscard]] constexpr bool operator==(const dense_set_iterator &lhs, const dense_set_iterator &rhs) noexcept { + return lhs.it == rhs.it; +} + +template +[[nodiscard]] constexpr bool operator!=(const dense_set_iterator &lhs, const dense_set_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +template +[[nodiscard]] constexpr bool operator<(const dense_set_iterator &lhs, const dense_set_iterator &rhs) noexcept { + return lhs.it < rhs.it; +} + +template +[[nodiscard]] constexpr bool operator>(const dense_set_iterator &lhs, const dense_set_iterator &rhs) noexcept { + return rhs < lhs; +} + +template +[[nodiscard]] constexpr bool operator<=(const dense_set_iterator &lhs, const dense_set_iterator &rhs) noexcept { + return !(lhs > rhs); +} + +template +[[nodiscard]] constexpr bool operator>=(const dense_set_iterator &lhs, const dense_set_iterator &rhs) noexcept { + return !(lhs < rhs); +} + +template +class dense_set_local_iterator final { + template + friend class dense_set_local_iterator; + +public: + using value_type = typename It::value_type::second_type; + using pointer = const value_type *; + using reference = const value_type &; + using difference_type = std::ptrdiff_t; + using iterator_category = std::forward_iterator_tag; + + constexpr dense_set_local_iterator() noexcept = default; + + constexpr dense_set_local_iterator(It iter, const std::size_t pos) noexcept + : it{iter}, + offset{pos} {} + + template && std::is_constructible_v>> + constexpr dense_set_local_iterator(const dense_set_local_iterator &other) noexcept + : it{other.it}, + offset{other.offset} {} + + constexpr dense_set_local_iterator &operator++() noexcept { + return offset = it[static_cast(offset)].first, *this; + } + + constexpr dense_set_local_iterator operator++(int) noexcept { + const dense_set_local_iterator orig = *this; + return ++(*this), orig; + } + + [[nodiscard]] constexpr pointer operator->() const noexcept { + return std::addressof(it[static_cast(offset)].second); + } + + [[nodiscard]] constexpr reference operator*() const noexcept { + return *operator->(); + } + + [[nodiscard]] constexpr std::size_t index() const noexcept { + return offset; + } + +private: + It it{}; + std::size_t offset{dense_set_placeholder_position}; +}; + +template +[[nodiscard]] constexpr bool operator==(const dense_set_local_iterator &lhs, const dense_set_local_iterator &rhs) noexcept { + return lhs.index() == rhs.index(); +} + +template +[[nodiscard]] constexpr bool operator!=(const dense_set_local_iterator &lhs, const dense_set_local_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Associative container for unique objects of a given type. + * + * Internally, elements are organized into buckets. Which bucket an element is + * placed into depends entirely on its hash. Elements with the same hash code + * appear in the same bucket. + * + * @tparam Type Value type of the associative container. + * @tparam Hash Type of function to use to hash the values. + * @tparam KeyEqual Type of function to use to compare the values for equality. + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +class dense_set { + static constexpr float default_threshold = 0.875f; + static constexpr std::size_t minimum_capacity = 8u; + static constexpr std::size_t placeholder_position = internal::dense_set_placeholder_position; + + using node_type = std::pair; + using alloc_traits = std::allocator_traits; + static_assert(std::is_same_v, "Invalid value type"); + using sparse_container_type = std::vector>; + using packed_container_type = std::vector>; + + template + [[nodiscard]] std::size_t value_to_bucket(const Other &value) const noexcept { + return fast_mod(static_cast(sparse.second()(value)), bucket_count()); + } + + template + [[nodiscard]] auto constrained_find(const Other &value, const std::size_t bucket) { + for(auto offset = sparse.first()[bucket]; offset != placeholder_position; offset = packed.first()[offset].first) { + if(packed.second()(packed.first()[offset].second, value)) { + return begin() + static_cast(offset); + } + } + + return end(); + } + + template + [[nodiscard]] auto constrained_find(const Other &value, const std::size_t bucket) const { + for(auto offset = sparse.first()[bucket]; offset != placeholder_position; offset = packed.first()[offset].first) { + if(packed.second()(packed.first()[offset].second, value)) { + return cbegin() + static_cast(offset); + } + } + + return cend(); + } + + template + [[nodiscard]] auto insert_or_do_nothing(Other &&value) { + const auto index = value_to_bucket(value); + + if(auto it = constrained_find(value, index); it != end()) { + return std::make_pair(it, false); + } + + packed.first().emplace_back(sparse.first()[index], std::forward(value)); + sparse.first()[index] = packed.first().size() - 1u; + rehash_if_required(); + + return std::make_pair(--end(), true); + } + + void move_and_pop(const std::size_t pos) { + if(const auto last = size() - 1u; pos != last) { + size_type *curr = &sparse.first()[value_to_bucket(packed.first().back().second)]; + packed.first()[pos] = std::move(packed.first().back()); + for(; *curr != last; curr = &packed.first()[*curr].first) {} + *curr = pos; + } + + packed.first().pop_back(); + } + + void rehash_if_required() { + if(const auto bc = bucket_count(); size() > static_cast(static_cast(bc) * max_load_factor())) { + rehash(bc * 2u); + } + } + +public: + /*! @brief Allocator type. */ + using allocator_type = Allocator; + /*! @brief Key type of the container. */ + using key_type = Type; + /*! @brief Value type of the container. */ + using value_type = Type; + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + /*! @brief Signed integer type. */ + using difference_type = std::ptrdiff_t; + /*! @brief Type of function to use to hash the elements. */ + using hasher = Hash; + /*! @brief Type of function to use to compare the elements for equality. */ + using key_equal = KeyEqual; + /*! @brief Random access iterator type. */ + using iterator = internal::dense_set_iterator; + /*! @brief Constant random access iterator type. */ + using const_iterator = internal::dense_set_iterator; + /*! @brief Reverse iterator type. */ + using reverse_iterator = std::reverse_iterator; + /*! @brief Constant reverse iterator type. */ + using const_reverse_iterator = std::reverse_iterator; + /*! @brief Forward iterator type. */ + using local_iterator = internal::dense_set_local_iterator; + /*! @brief Constant forward iterator type. */ + using const_local_iterator = internal::dense_set_local_iterator; + + /*! @brief Default constructor. */ + dense_set() + : dense_set{minimum_capacity} {} + + /** + * @brief Constructs an empty container with a given allocator. + * @param allocator The allocator to use. + */ + explicit dense_set(const allocator_type &allocator) + : dense_set{minimum_capacity, hasher{}, key_equal{}, allocator} {} + + /** + * @brief Constructs an empty container with a given allocator and user + * supplied minimal number of buckets. + * @param cnt Minimal number of buckets. + * @param allocator The allocator to use. + */ + dense_set(const size_type cnt, const allocator_type &allocator) + : dense_set{cnt, hasher{}, key_equal{}, allocator} {} + + /** + * @brief Constructs an empty container with a given allocator, hash + * function and user supplied minimal number of buckets. + * @param cnt Minimal number of buckets. + * @param hash Hash function to use. + * @param allocator The allocator to use. + */ + dense_set(const size_type cnt, const hasher &hash, const allocator_type &allocator) + : dense_set{cnt, hash, key_equal{}, allocator} {} + + /** + * @brief Constructs an empty container with a given allocator, hash + * function, compare function and user supplied minimal number of buckets. + * @param cnt Minimal number of buckets. + * @param hash Hash function to use. + * @param equal Compare function to use. + * @param allocator The allocator to use. + */ + explicit dense_set(const size_type cnt, const hasher &hash = hasher{}, const key_equal &equal = key_equal{}, const allocator_type &allocator = allocator_type{}) + : sparse{allocator, hash}, + packed{allocator, equal} { + rehash(cnt); + } + + /*! @brief Default copy constructor. */ + dense_set(const dense_set &) = default; + + /** + * @brief Allocator-extended copy constructor. + * @param other The instance to copy from. + * @param allocator The allocator to use. + */ + dense_set(const dense_set &other, const allocator_type &allocator) + : sparse{std::piecewise_construct, std::forward_as_tuple(other.sparse.first(), allocator), std::forward_as_tuple(other.sparse.second())}, + packed{std::piecewise_construct, std::forward_as_tuple(other.packed.first(), allocator), std::forward_as_tuple(other.packed.second())}, + threshold{other.threshold} {} + + /*! @brief Default move constructor. */ + dense_set(dense_set &&) noexcept = default; + + /** + * @brief Allocator-extended move constructor. + * @param other The instance to move from. + * @param allocator The allocator to use. + */ + dense_set(dense_set &&other, const allocator_type &allocator) + : sparse{std::piecewise_construct, std::forward_as_tuple(std::move(other.sparse.first()), allocator), std::forward_as_tuple(std::move(other.sparse.second()))}, + packed{std::piecewise_construct, std::forward_as_tuple(std::move(other.packed.first()), allocator), std::forward_as_tuple(std::move(other.packed.second()))}, + threshold{other.threshold} {} + + /*! @brief Default destructor. */ + ~dense_set() = default; + + /** + * @brief Default copy assignment operator. + * @return This container. + */ + dense_set &operator=(const dense_set &) = default; + + /** + * @brief Default move assignment operator. + * @return This container. + */ + dense_set &operator=(dense_set &&) noexcept = default; + + /** + * @brief Exchanges the contents with those of a given container. + * @param other Container to exchange the content with. + */ + void swap(dense_set &other) noexcept { + using std::swap; + swap(sparse, other.sparse); + swap(packed, other.packed); + swap(threshold, other.threshold); + } + + /** + * @brief Returns the associated allocator. + * @return The associated allocator. + */ + [[nodiscard]] constexpr allocator_type get_allocator() const noexcept { + return sparse.first().get_allocator(); + } + + /** + * @brief Returns an iterator to the beginning. + * + * If the array is empty, the returned iterator will be equal to `end()`. + * + * @return An iterator to the first instance of the internal array. + */ + [[nodiscard]] const_iterator cbegin() const noexcept { + return packed.first().begin(); + } + + /*! @copydoc cbegin */ + [[nodiscard]] const_iterator begin() const noexcept { + return cbegin(); + } + + /*! @copydoc begin */ + [[nodiscard]] iterator begin() noexcept { + return packed.first().begin(); + } + + /** + * @brief Returns an iterator to the end. + * @return An iterator to the element following the last instance of the + * internal array. + */ + [[nodiscard]] const_iterator cend() const noexcept { + return packed.first().end(); + } + + /*! @copydoc cend */ + [[nodiscard]] const_iterator end() const noexcept { + return cend(); + } + + /*! @copydoc end */ + [[nodiscard]] iterator end() noexcept { + return packed.first().end(); + } + + /** + * @brief Returns a reverse iterator to the beginning. + * + * If the array is empty, the returned iterator will be equal to `rend()`. + * + * @return An iterator to the first instance of the reversed internal array. + */ + [[nodiscard]] const_reverse_iterator crbegin() const noexcept { + return std::make_reverse_iterator(cend()); + } + + /*! @copydoc crbegin */ + [[nodiscard]] const_reverse_iterator rbegin() const noexcept { + return crbegin(); + } + + /*! @copydoc rbegin */ + [[nodiscard]] reverse_iterator rbegin() noexcept { + return std::make_reverse_iterator(end()); + } + + /** + * @brief Returns a reverse iterator to the end. + * @return An iterator to the element following the last instance of the + * reversed internal array. + */ + [[nodiscard]] const_reverse_iterator crend() const noexcept { + return std::make_reverse_iterator(cbegin()); + } + + /*! @copydoc crend */ + [[nodiscard]] const_reverse_iterator rend() const noexcept { + return crend(); + } + + /*! @copydoc rend */ + [[nodiscard]] reverse_iterator rend() noexcept { + return std::make_reverse_iterator(begin()); + } + + /** + * @brief Checks whether a container is empty. + * @return True if the container is empty, false otherwise. + */ + [[nodiscard]] bool empty() const noexcept { + return packed.first().empty(); + } + + /** + * @brief Returns the number of elements in a container. + * @return Number of elements in a container. + */ + [[nodiscard]] size_type size() const noexcept { + return packed.first().size(); + } + + /** + * @brief Returns the maximum possible number of elements. + * @return Maximum possible number of elements. + */ + [[nodiscard]] size_type max_size() const noexcept { + return packed.first().max_size(); + } + + /*! @brief Clears the container. */ + void clear() noexcept { + sparse.first().clear(); + packed.first().clear(); + rehash(0u); + } + + /** + * @brief Inserts an element into the container, if it does not exist. + * @param value An element to insert into the container. + * @return A pair consisting of an iterator to the inserted element (or to + * the element that prevented the insertion) and a bool denoting whether the + * insertion took place. + */ + std::pair insert(const value_type &value) { + return insert_or_do_nothing(value); + } + + /*! @copydoc insert */ + std::pair insert(value_type &&value) { + return insert_or_do_nothing(std::move(value)); + } + + /** + * @brief Inserts elements into the container, if they do not exist. + * @tparam It Type of input iterator. + * @param first An iterator to the first element of the range of elements. + * @param last An iterator past the last element of the range of elements. + */ + template + void insert(It first, It last) { + for(; first != last; ++first) { + insert(*first); + } + } + + /** + * @brief Constructs an element in-place, if it does not exist. + * + * The element is also constructed when the container already has the key, + * in which case the newly constructed object is destroyed immediately. + * + * @tparam Args Types of arguments to forward to the constructor of the + * element. + * @param args Arguments to forward to the constructor of the element. + * @return A pair consisting of an iterator to the inserted element (or to + * the element that prevented the insertion) and a bool denoting whether the + * insertion took place. + */ + template + std::pair emplace(Args &&...args) { + if constexpr(((sizeof...(Args) == 1u) && ... && std::is_same_v, value_type>)) { + return insert_or_do_nothing(std::forward(args)...); + } else { + auto &node = packed.first().emplace_back(std::piecewise_construct, std::make_tuple(packed.first().size()), std::forward_as_tuple(std::forward(args)...)); + const auto index = value_to_bucket(node.second); + + if(auto it = constrained_find(node.second, index); it != end()) { + packed.first().pop_back(); + return std::make_pair(it, false); + } + + std::swap(node.first, sparse.first()[index]); + rehash_if_required(); + + return std::make_pair(--end(), true); + } + } + + /** + * @brief Removes an element from a given position. + * @param pos An iterator to the element to remove. + * @return An iterator following the removed element. + */ + iterator erase(const_iterator pos) { + const auto diff = pos - cbegin(); + erase(*pos); + return begin() + diff; + } + + /** + * @brief Removes the given elements from a container. + * @param first An iterator to the first element of the range of elements. + * @param last An iterator past the last element of the range of elements. + * @return An iterator following the last removed element. + */ + iterator erase(const_iterator first, const_iterator last) { + const auto dist = first - cbegin(); + + for(auto from = last - cbegin(); from != dist; --from) { + erase(packed.first()[static_cast(from) - 1u].second); + } + + return (begin() + dist); + } + + /** + * @brief Removes the element associated with a given value. + * @param value Value of an element to remove. + * @return Number of elements removed (either 0 or 1). + */ + size_type erase(const value_type &value) { + for(size_type *curr = &sparse.first()[value_to_bucket(value)]; *curr != placeholder_position; curr = &packed.first()[*curr].first) { + if(packed.second()(packed.first()[*curr].second, value)) { + const auto index = *curr; + *curr = packed.first()[*curr].first; + move_and_pop(index); + return 1u; + } + } + + return 0u; + } + + /** + * @brief Returns the number of elements matching a value (either 1 or 0). + * @param key Key value of an element to search for. + * @return Number of elements matching the key (either 1 or 0). + */ + [[nodiscard]] size_type count(const value_type &key) const { + return find(key) != end(); + } + + /** + * @brief Returns the number of elements matching a key (either 1 or 0). + * @tparam Other Type of the key value of an element to search for. + * @param key Key value of an element to search for. + * @return Number of elements matching the key (either 1 or 0). + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + count(const Other &key) const { + return find(key) != end(); + } + + /** + * @brief Finds an element with a given value. + * @param value Value of an element to search for. + * @return An iterator to an element with the given value. If no such + * element is found, a past-the-end iterator is returned. + */ + [[nodiscard]] iterator find(const value_type &value) { + return constrained_find(value, value_to_bucket(value)); + } + + /*! @copydoc find */ + [[nodiscard]] const_iterator find(const value_type &value) const { + return constrained_find(value, value_to_bucket(value)); + } + + /** + * @brief Finds an element that compares _equivalent_ to a given value. + * @tparam Other Type of an element to search for. + * @param value Value of an element to search for. + * @return An iterator to an element with the given value. If no such + * element is found, a past-the-end iterator is returned. + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + find(const Other &value) { + return constrained_find(value, value_to_bucket(value)); + } + + /*! @copydoc find */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + find(const Other &value) const { + return constrained_find(value, value_to_bucket(value)); + } + + /** + * @brief Returns a range containing all elements with a given value. + * @param value Value of an element to search for. + * @return A pair of iterators pointing to the first element and past the + * last element of the range. + */ + [[nodiscard]] std::pair equal_range(const value_type &value) { + const auto it = find(value); + return {it, it + !(it == end())}; + } + + /*! @copydoc equal_range */ + [[nodiscard]] std::pair equal_range(const value_type &value) const { + const auto it = find(value); + return {it, it + !(it == cend())}; + } + + /** + * @brief Returns a range containing all elements that compare _equivalent_ + * to a given value. + * @tparam Other Type of an element to search for. + * @param value Value of an element to search for. + * @return A pair of iterators pointing to the first element and past the + * last element of the range. + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t>> + equal_range(const Other &value) { + const auto it = find(value); + return {it, it + !(it == end())}; + } + + /*! @copydoc equal_range */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t>> + equal_range(const Other &value) const { + const auto it = find(value); + return {it, it + !(it == cend())}; + } + + /** + * @brief Checks if the container contains an element with a given value. + * @param value Value of an element to search for. + * @return True if there is such an element, false otherwise. + */ + [[nodiscard]] bool contains(const value_type &value) const { + return (find(value) != cend()); + } + + /** + * @brief Checks if the container contains an element that compares + * _equivalent_ to a given value. + * @tparam Other Type of an element to search for. + * @param value Value of an element to search for. + * @return True if there is such an element, false otherwise. + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + contains(const Other &value) const { + return (find(value) != cend()); + } + + /** + * @brief Returns an iterator to the beginning of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the beginning of the given bucket. + */ + [[nodiscard]] const_local_iterator cbegin(const size_type index) const { + return {packed.first().begin(), sparse.first()[index]}; + } + + /** + * @brief Returns an iterator to the beginning of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the beginning of the given bucket. + */ + [[nodiscard]] const_local_iterator begin(const size_type index) const { + return cbegin(index); + } + + /** + * @brief Returns an iterator to the beginning of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the beginning of the given bucket. + */ + [[nodiscard]] local_iterator begin(const size_type index) { + return {packed.first().begin(), sparse.first()[index]}; + } + + /** + * @brief Returns an iterator to the end of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the end of the given bucket. + */ + [[nodiscard]] const_local_iterator cend([[maybe_unused]] const size_type index) const { + return {}; + } + + /** + * @brief Returns an iterator to the end of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the end of the given bucket. + */ + [[nodiscard]] const_local_iterator end(const size_type index) const { + return cend(index); + } + + /** + * @brief Returns an iterator to the end of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the end of the given bucket. + */ + [[nodiscard]] local_iterator end([[maybe_unused]] const size_type index) { + return {}; + } + + /** + * @brief Returns the number of buckets. + * @return The number of buckets. + */ + [[nodiscard]] size_type bucket_count() const { + return sparse.first().size(); + } + + /** + * @brief Returns the maximum number of buckets. + * @return The maximum number of buckets. + */ + [[nodiscard]] size_type max_bucket_count() const { + return sparse.first().max_size(); + } + + /** + * @brief Returns the number of elements in a given bucket. + * @param index The index of the bucket to examine. + * @return The number of elements in the given bucket. + */ + [[nodiscard]] size_type bucket_size(const size_type index) const { + return static_cast(std::distance(begin(index), end(index))); + } + + /** + * @brief Returns the bucket for a given element. + * @param value The value of the element to examine. + * @return The bucket for the given element. + */ + [[nodiscard]] size_type bucket(const value_type &value) const { + return value_to_bucket(value); + } + + /** + * @brief Returns the average number of elements per bucket. + * @return The average number of elements per bucket. + */ + [[nodiscard]] float load_factor() const { + return static_cast(size()) / static_cast(bucket_count()); + } + + /** + * @brief Returns the maximum average number of elements per bucket. + * @return The maximum average number of elements per bucket. + */ + [[nodiscard]] float max_load_factor() const { + return threshold; + } + + /** + * @brief Sets the desired maximum average number of elements per bucket. + * @param value A desired maximum average number of elements per bucket. + */ + void max_load_factor(const float value) { + ENTT_ASSERT(value > 0.f, "Invalid load factor"); + threshold = value; + rehash(0u); + } + + /** + * @brief Reserves at least the specified number of buckets and regenerates + * the hash table. + * @param cnt New number of buckets. + */ + void rehash(const size_type cnt) { + auto value = cnt > minimum_capacity ? cnt : minimum_capacity; + const auto cap = static_cast(static_cast(size()) / max_load_factor()); + value = value > cap ? value : cap; + + if(const auto sz = next_power_of_two(value); sz != bucket_count()) { + sparse.first().resize(sz); + + for(auto &&elem: sparse.first()) { + elem = placeholder_position; + } + + for(size_type pos{}, last = size(); pos < last; ++pos) { + const auto index = value_to_bucket(packed.first()[pos].second); + packed.first()[pos].first = std::exchange(sparse.first()[index], pos); + } + } + } + + /** + * @brief Reserves space for at least the specified number of elements and + * regenerates the hash table. + * @param cnt New number of elements. + */ + void reserve(const size_type cnt) { + packed.first().reserve(cnt); + rehash(static_cast(std::ceil(static_cast(cnt) / max_load_factor()))); + } + + /** + * @brief Returns the function used to hash the elements. + * @return The function used to hash the elements. + */ + [[nodiscard]] hasher hash_function() const { + return sparse.second(); + } + + /** + * @brief Returns the function used to compare elements for equality. + * @return The function used to compare elements for equality. + */ + [[nodiscard]] key_equal key_eq() const { + return packed.second(); + } + +private: + compressed_pair sparse; + compressed_pair packed; + float threshold{default_threshold}; +}; + +} // namespace entt + +#endif + +// #include "../core/compressed_pair.hpp" +#ifndef ENTT_CORE_COMPRESSED_PAIR_HPP +#define ENTT_CORE_COMPRESSED_PAIR_HPP + +#include +#include +#include +#include +// #include "fwd.hpp" +#ifndef ENTT_CORE_FWD_HPP +#define ENTT_CORE_FWD_HPP + +#include +#include +// #include "../config/config.h" + + +namespace entt { + +/*! @brief Possible modes of an any object. */ +enum class any_policy : std::uint8_t { + /*! @brief Default mode, no element available. */ + empty, + /*! @brief Owning mode, dynamically allocated element. */ + dynamic, + /*! @brief Owning mode, embedded element. */ + embedded, + /*! @brief Aliasing mode, non-const reference. */ + ref, + /*! @brief Const aliasing mode, const reference. */ + cref +}; + +// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) +template +class basic_any; + +/*! @brief Alias declaration for type identifiers. */ +using id_type = ENTT_ID_TYPE; + +/*! @brief Alias declaration for the most common use case. */ +using any = basic_any<>; + +template +class compressed_pair; + +template +class basic_hashed_string; + +/*! @brief Aliases for common character types. */ +using hashed_string = basic_hashed_string; + +/*! @brief Aliases for common character types. */ +using hashed_wstring = basic_hashed_string; + +// NOLINTNEXTLINE(bugprone-forward-declaration-namespace) +struct type_info; + +} // namespace entt + +#endif + +// #include "type_traits.hpp" +#ifndef ENTT_CORE_TYPE_TRAITS_HPP +#define ENTT_CORE_TYPE_TRAITS_HPP + +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "fwd.hpp" + + +namespace entt { + +/** + * @brief Utility class to disambiguate overloaded functions. + * @tparam N Number of choices available. + */ +template +struct choice_t + // unfortunately, doxygen cannot parse such a construct + : /*! @cond TURN_OFF_DOXYGEN */ choice_t /*! @endcond */ +{}; + +/*! @copybrief choice_t */ +template<> +struct choice_t<0> {}; + +/** + * @brief Variable template for the choice trick. + * @tparam N Number of choices available. + */ +template +inline constexpr choice_t choice{}; + +/** + * @brief Identity type trait. + * + * Useful to establish non-deduced contexts in template argument deduction + * (waiting for C++20) or to provide types through function arguments. + * + * @tparam Type A type. + */ +template +struct type_identity { + /*! @brief Identity type. */ + using type = Type; +}; + +/** + * @brief Helper type. + * @tparam Type A type. + */ +template +using type_identity_t = typename type_identity::type; + +/** + * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains. + * @tparam Type The type of which to return the size. + */ +template +struct size_of: std::integral_constant {}; + +/*! @copydoc size_of */ +template +struct size_of> + // NOLINTNEXTLINE(bugprone-sizeof-expression) + : std::integral_constant {}; + +/** + * @brief Helper variable template. + * @tparam Type The type of which to return the size. + */ +template +inline constexpr std::size_t size_of_v = size_of::value; + +/** + * @brief Using declaration to be used to _repeat_ the same type a number of + * times equal to the size of a given parameter pack. + * @tparam Type A type to repeat. + */ +template +using unpack_as_type = Type; + +/** + * @brief Helper variable template to be used to _repeat_ the same value a + * number of times equal to the size of a given parameter pack. + * @tparam Value A value to repeat. + */ +template +inline constexpr auto unpack_as_value = Value; + +/** + * @brief Wraps a static constant. + * @tparam Value A static constant. + */ +template +using integral_constant = std::integral_constant; + +/** + * @brief Alias template to facilitate the creation of named values. + * @tparam Value A constant value at least convertible to `id_type`. + */ +template +using tag = integral_constant; + +/** + * @brief A class to use to push around lists of types, nothing more. + * @tparam Type Types provided by the type list. + */ +template +struct type_list { + /*! @brief Type list type. */ + using type = type_list; + /*! @brief Compile-time number of elements in the type list. */ + static constexpr auto size = sizeof...(Type); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_element; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Index Index of the type to return. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element> + : type_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element<0u, type_list> { + /*! @brief Searched type. */ + using type = First; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Type list to search into. + */ +template +using type_list_element_t = typename type_list_element::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_index; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 1u + type_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + static_assert(type_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +inline constexpr std::size_t type_list_index_v = type_list_index::value; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @return A type list composed by the types of both the type lists. + */ +template +constexpr type_list operator+(type_list, type_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_cat; + +/*! @brief Concatenates multiple type lists. */ +template<> +struct type_list_cat<> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list<>; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @tparam List Other type lists, if any. + */ +template +struct type_list_cat, type_list, List...> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = typename type_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the type list. + */ +template +struct type_list_cat> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list; +}; + +/** + * @brief Helper type. + * @tparam List Type lists to concatenate. + */ +template +using type_list_cat_t = typename type_list_cat::type; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct type_list_unique; + +template +struct type_list_unique, Type...> + : std::conditional_t<(std::is_same_v || ...), type_list_unique, Type...>, type_list_unique, Type..., First>> {}; + +template +struct type_list_unique, Type...> { + using type = type_list; +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Removes duplicates types from a type list. + * @tparam List Type list. + */ +template +struct type_list_unique { + /*! @brief A type list without duplicate types. */ + using type = typename internal::type_list_unique::type; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + */ +template +using type_list_unique_t = typename type_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a type list contains a + * given type, false otherwise. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +struct type_list_contains; + +/** + * @copybrief type_list_contains + * @tparam Type Types provided by the type list. + * @tparam Other Type to look for. + */ +template +struct type_list_contains, Other> + : std::bool_constant<(std::is_same_v || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +inline constexpr bool type_list_contains_v = type_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_diff; + +/** + * @brief Computes the difference between two type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + */ +template +struct type_list_diff, type_list> { + /*! @brief A type list that is the difference between the two type lists. */ + using type = type_list_cat_t, Type>, type_list<>, type_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Type lists between which to compute the difference. + */ +template +using type_list_diff_t = typename type_list_diff::type; + +/*! @brief Primary template isn't defined on purpose. */ +template class> +struct type_list_transform; + +/** + * @brief Applies a given _function_ to a type list and generate a new list. + * @tparam Type Types provided by the type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +struct type_list_transform, Op> { + /*! @brief Resulting type list after applying the transform function. */ + // NOLINTNEXTLINE(modernize-type-traits) + using type = type_list::type...>; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +using type_list_transform_t = typename type_list_transform::type; + +/** + * @brief A class to use to push around lists of constant values, nothing more. + * @tparam Value Values provided by the value list. + */ +template +struct value_list { + /*! @brief Value list type. */ + using type = value_list; + /*! @brief Compile-time number of elements in the value list. */ + static constexpr auto size = sizeof...(Value); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_element; + +/** + * @brief Provides compile-time indexed access to the values of a value list. + * @tparam Index Index of the value to return. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element> + : value_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element<0u, value_list> { + /*! @brief Searched type. */ + using type = decltype(Value); + /*! @brief Searched value. */ + static constexpr auto value = Value; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Value list to search into. + */ +template +using value_list_element_t = typename value_list_element::type; + +/** + * @brief Helper type. + * @tparam Index Index of the value to return. + * @tparam List Value list to search into. + */ +template +inline constexpr auto value_list_element_v = value_list_element::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_index; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam First First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 1u + value_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + static_assert(value_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +inline constexpr std::size_t value_list_index_v = value_list_index::value; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @return A value list composed by the values of both the value lists. + */ +template +constexpr value_list operator+(value_list, value_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_cat; + +/*! @brief Concatenates multiple value lists. */ +template<> +struct value_list_cat<> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list<>; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @tparam List Other value lists, if any. + */ +template +struct value_list_cat, value_list, List...> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = typename value_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the value list. + */ +template +struct value_list_cat> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list; +}; + +/** + * @brief Helper type. + * @tparam List Value lists to concatenate. + */ +template +using value_list_cat_t = typename value_list_cat::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_unique; + +/** + * @brief Removes duplicates values from a value list. + * @tparam Value One of the values provided by the given value list. + * @tparam Other The other values provided by the given value list. + */ +template +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = std::conditional_t< + ((Value == Other) || ...), + typename value_list_unique>::type, + value_list_cat_t, typename value_list_unique>::type>>; +}; + +/*! @brief Removes duplicates values from a value list. */ +template<> +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = value_list<>; +}; + +/** + * @brief Helper type. + * @tparam Type A value list. + */ +template +using value_list_unique_t = typename value_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a value list contains + * a given value, false otherwise. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +struct value_list_contains; + +/** + * @copybrief value_list_contains + * @tparam Value Values provided by the value list. + * @tparam Other Value to look for. + */ +template +struct value_list_contains, Other> + : std::bool_constant<((Value == Other) || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +inline constexpr bool value_list_contains_v = value_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_diff; + +/** + * @brief Computes the difference between two value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + */ +template +struct value_list_diff, value_list> { + /*! @brief A value list that is the difference between the two value lists. */ + using type = value_list_cat_t, Value>, value_list<>, value_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Value lists between which to compute the difference. + */ +template +using value_list_diff_t = typename value_list_diff::type; + +/*! @brief Same as std::is_invocable, but with tuples. */ +template +struct is_applicable: std::false_type {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @brief Helper variable template. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_v = is_applicable::value; + +/*! @brief Same as std::is_invocable_r, but with tuples for arguments. */ +template +struct is_applicable_r: std::false_type {}; + +/** + * @copybrief is_applicable_r + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +struct is_applicable_r>: std::is_invocable_r {}; + +/** + * @brief Helper variable template. + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_r_v = is_applicable_r::value; + +/** + * @brief Provides the member constant `value` to true if a given type is + * complete, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_complete: std::false_type {}; + +/*! @copydoc is_complete */ +template +struct is_complete>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_complete_v = is_complete::value; + +/** + * @brief Provides the member constant `value` to true if a given type is an + * iterator, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_iterator: std::false_type {}; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_iterator_category: std::false_type {}; + +template +struct has_iterator_category::iterator_category>>: std::true_type {}; + +} // namespace internal +/*! @endcond */ + +/*! @copydoc is_iterator */ +template +struct is_iterator>>>> + : internal::has_iterator_category {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_iterator_v = is_iterator::value; + +/** + * @brief Provides the member constant `value` to true if a given type is both + * an empty and non-final class, false otherwise. + * @tparam Type The type to test + */ +template +struct is_ebco_eligible + : std::bool_constant && !std::is_final_v> {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_ebco_eligible_v = is_ebco_eligible::value; + +/** + * @brief Provides the member constant `value` to true if `Type::is_transparent` + * is valid and denotes a type, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_transparent: std::false_type {}; + +/*! @copydoc is_transparent */ +template +struct is_transparent>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_transparent_v = is_transparent::value; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_tuple_size_value: std::false_type {}; + +template +struct has_tuple_size_value::value)>>: std::true_type {}; + +template +struct has_value_type: std::false_type {}; + +template +struct has_value_type>: std::true_type {}; + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable(); + +template +[[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence) { + return (dispatch_is_equality_comparable>() && ...); +} + +template +[[nodiscard]] constexpr bool maybe_equality_comparable(char) { + return false; +} + +template +[[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval() == std::declval()) { + return true; +} + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable() { + // NOLINTBEGIN(modernize-use-transparent-functors) + if constexpr(std::is_array_v) { + return false; + } else if constexpr(is_complete_v>>) { + if constexpr(has_tuple_size_value::value) { + return maybe_equality_comparable(0) && unpack_maybe_equality_comparable(std::make_index_sequence::value>{}); + } else { + return maybe_equality_comparable(0); + } + } else if constexpr(has_value_type::value) { + if constexpr(is_iterator_v || std::is_same_v || dispatch_is_equality_comparable()) { + return maybe_equality_comparable(0); + } else { + return false; + } + } else { + return maybe_equality_comparable(0); + } + // NOLINTEND(modernize-use-transparent-functors) +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Provides the member constant `value` to true if a given type is + * equality comparable, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_equality_comparable: std::bool_constant()> {}; + +/*! @copydoc is_equality_comparable */ +template +struct is_equality_comparable: is_equality_comparable {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_equality_comparable_v = is_equality_comparable::value; + +/** + * @brief Transcribes the constness of a type to another type. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = std::remove_const_t; +}; + +/*! @copydoc constness_as */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = const To; +}; + +/** + * @brief Alias template to facilitate the transcription of the constness. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +using constness_as_t = typename constness_as::type; + +/** + * @brief Extracts the class of a non-static member object or function. + * @tparam Member A pointer to a non-static member object or function. + */ +template +class member_class { + static_assert(std::is_member_pointer_v, "Invalid pointer type to non-static member object or function"); + + template + static Class *clazz(Ret (Class::*)(Args...)); + + template + static Class *clazz(Ret (Class::*)(Args...) const); + + template + static Class *clazz(Type Class::*); + +public: + /*! @brief The class of the given non-static member object or function. */ + using type = std::remove_pointer_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Member A pointer to a non-static member object or function. + */ +template +using member_class_t = typename member_class::type; + +/** + * @brief Extracts the n-th argument of a _callable_ type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid _callable_ type. + */ +template +class nth_argument { + template + static constexpr type_list pick_up(Ret (*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...) const); + + template + static constexpr type_list pick_up(Type Class ::*); + + template + static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&); + +public: + /*! @brief N-th argument of the _callable_ type. */ + using type = type_list_element_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid function, member function or data member type. + */ +template +using nth_argument_t = typename nth_argument::type; + +} // namespace entt + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::type_list_element> {}; + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::value_list_element> {}; + +#endif + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct compressed_pair_element { + using reference = Type &; + using const_reference = const Type &; + + template>> + // NOLINTNEXTLINE(modernize-use-equals-default) + constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v) {} + + template>, compressed_pair_element>>> + constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v) + : value{std::forward(arg)} {} + + template + constexpr compressed_pair_element(std::tuple args, std::index_sequence) noexcept(std::is_nothrow_constructible_v) + : value{std::forward(std::get(args))...} {} + + [[nodiscard]] constexpr reference get() noexcept { + return value; + } + + [[nodiscard]] constexpr const_reference get() const noexcept { + return value; + } + +private: + Type value{}; +}; + +template +struct compressed_pair_element>>: Type { + using reference = Type &; + using const_reference = const Type &; + using base_type = Type; + + template>> + constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v) + : base_type{} {} + + template>, compressed_pair_element>>> + constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v) + : base_type{std::forward(arg)} {} + + template + constexpr compressed_pair_element(std::tuple args, std::index_sequence) noexcept(std::is_nothrow_constructible_v) + : base_type{std::forward(std::get(args))...} {} + + [[nodiscard]] constexpr reference get() noexcept { + return *this; + } + + [[nodiscard]] constexpr const_reference get() const noexcept { + return *this; + } +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief A compressed pair. + * + * A pair that exploits the _Empty Base Class Optimization_ (or _EBCO_) to + * reduce its final size to a minimum. + * + * @tparam First The type of the first element that the pair stores. + * @tparam Second The type of the second element that the pair stores. + */ +template +class compressed_pair final + : internal::compressed_pair_element, + internal::compressed_pair_element { + using first_base = internal::compressed_pair_element; + using second_base = internal::compressed_pair_element; + +public: + /*! @brief The type of the first element that the pair stores. */ + using first_type = First; + /*! @brief The type of the second element that the pair stores. */ + using second_type = Second; + + /** + * @brief Default constructor, conditionally enabled. + * + * This constructor is only available when the types that the pair stores + * are both at least default constructible. + * + * @tparam Dummy Dummy template parameter used for internal purposes. + */ + template && std::is_default_constructible_v>> + constexpr compressed_pair() noexcept(std::is_nothrow_default_constructible_v && std::is_nothrow_default_constructible_v) + : first_base{}, + second_base{} {} + + /** + * @brief Copy constructor. + * @param other The instance to copy from. + */ + constexpr compressed_pair(const compressed_pair &other) = default; + + /** + * @brief Move constructor. + * @param other The instance to move from. + */ + constexpr compressed_pair(compressed_pair &&other) noexcept = default; + + /** + * @brief Constructs a pair from its values. + * @tparam Arg Type of value to use to initialize the first element. + * @tparam Other Type of value to use to initialize the second element. + * @param arg Value to use to initialize the first element. + * @param other Value to use to initialize the second element. + */ + template + constexpr compressed_pair(Arg &&arg, Other &&other) noexcept(std::is_nothrow_constructible_v && std::is_nothrow_constructible_v) + : first_base{std::forward(arg)}, + second_base{std::forward(other)} {} + + /** + * @brief Constructs a pair by forwarding the arguments to its parts. + * @tparam Args Types of arguments to use to initialize the first element. + * @tparam Other Types of arguments to use to initialize the second element. + * @param args Arguments to use to initialize the first element. + * @param other Arguments to use to initialize the second element. + */ + template + constexpr compressed_pair(std::piecewise_construct_t, std::tuple args, std::tuple other) noexcept(std::is_nothrow_constructible_v && std::is_nothrow_constructible_v) + : first_base{std::move(args), std::index_sequence_for{}}, + second_base{std::move(other), std::index_sequence_for{}} {} + + /*! @brief Default destructor. */ + ~compressed_pair() = default; + + /** + * @brief Copy assignment operator. + * @param other The instance to copy from. + * @return This compressed pair object. + */ + constexpr compressed_pair &operator=(const compressed_pair &other) = default; + + /** + * @brief Move assignment operator. + * @param other The instance to move from. + * @return This compressed pair object. + */ + constexpr compressed_pair &operator=(compressed_pair &&other) noexcept = default; + + /** + * @brief Returns the first element that a pair stores. + * @return The first element that a pair stores. + */ + [[nodiscard]] constexpr first_type &first() noexcept { + return static_cast(*this).get(); + } + + /*! @copydoc first */ + [[nodiscard]] constexpr const first_type &first() const noexcept { + return static_cast(*this).get(); + } + + /** + * @brief Returns the second element that a pair stores. + * @return The second element that a pair stores. + */ + [[nodiscard]] constexpr second_type &second() noexcept { + return static_cast(*this).get(); + } + + /*! @copydoc second */ + [[nodiscard]] constexpr const second_type &second() const noexcept { + return static_cast(*this).get(); + } + + /** + * @brief Swaps two compressed pair objects. + * @param other The compressed pair to swap with. + */ + constexpr void swap(compressed_pair &other) noexcept { + using std::swap; + swap(first(), other.first()); + swap(second(), other.second()); + } + + /** + * @brief Extracts an element from the compressed pair. + * @tparam Index An integer value that is either 0 or 1. + * @return Returns a reference to the first element if `Index` is 0 and a + * reference to the second element if `Index` is 1. + */ + template + [[nodiscard]] constexpr decltype(auto) get() noexcept { + if constexpr(Index == 0u) { + return first(); + } else { + static_assert(Index == 1u, "Index out of bounds"); + return second(); + } + } + + /*! @copydoc get */ + template + [[nodiscard]] constexpr decltype(auto) get() const noexcept { + if constexpr(Index == 0u) { + return first(); + } else { + static_assert(Index == 1u, "Index out of bounds"); + return second(); + } + } +}; + +/** + * @brief Deduction guide. + * @tparam Type Type of value to use to initialize the first element. + * @tparam Other Type of value to use to initialize the second element. + */ +template +compressed_pair(Type &&, Other &&) -> compressed_pair, std::decay_t>; + +/** + * @brief Swaps two compressed pair objects. + * @tparam First The type of the first element that the pairs store. + * @tparam Second The type of the second element that the pairs store. + * @param lhs A valid compressed pair object. + * @param rhs A valid compressed pair object. + */ +template +constexpr void swap(compressed_pair &lhs, compressed_pair &rhs) noexcept { + lhs.swap(rhs); +} + +} // namespace entt + +namespace std { + +/** + * @brief `std::tuple_size` specialization for `compressed_pair`s. + * @tparam First The type of the first element that the pair stores. + * @tparam Second The type of the second element that the pair stores. + */ +template +struct tuple_size>: integral_constant {}; + +/** + * @brief `std::tuple_element` specialization for `compressed_pair`s. + * @tparam Index The index of the type to return. + * @tparam First The type of the first element that the pair stores. + * @tparam Second The type of the second element that the pair stores. + */ +template +struct tuple_element>: conditional { + static_assert(Index < 2u, "Index out of bounds"); +}; + +} // namespace std + +#endif + +// #include "../core/fwd.hpp" + +// #include "../core/iterator.hpp" + +// #include "../core/utility.hpp" +#ifndef ENTT_CORE_UTILITY_HPP +#define ENTT_CORE_UTILITY_HPP + +#include +#include + +namespace entt { + +/*! @brief Identity function object (waiting for C++20). */ +struct identity { + /*! @brief Indicates that this is a transparent function object. */ + using is_transparent = void; + + /** + * @brief Returns its argument unchanged. + * @tparam Type Type of the argument. + * @param value The actual argument. + * @return The submitted value as-is. + */ + template + [[nodiscard]] constexpr Type &&operator()(Type &&value) const noexcept { + return std::forward(value); + } +}; + +/** + * @brief Constant utility to disambiguate overloaded members of a class. + * @tparam Type Type of the desired overload. + * @tparam Class Type of class to which the member belongs. + * @param member A valid pointer to a member. + * @return Pointer to the member. + */ +template +[[nodiscard]] constexpr auto overload(Type Class::*member) noexcept { + return member; +} + +/** + * @brief Constant utility to disambiguate overloaded functions. + * @tparam Func Function type of the desired overload. + * @param func A valid pointer to a function. + * @return Pointer to the function. + */ +template +[[nodiscard]] constexpr auto overload(Func *func) noexcept { + return func; +} + +/** + * @brief Helper type for visitors. + * @tparam Func Types of function objects. + */ +template +struct overloaded: Func... { + using Func::operator()...; +}; + +/** + * @brief Deduction guide. + * @tparam Func Types of function objects. + */ +template +overloaded(Func...) -> overloaded; + +/** + * @brief Basic implementation of a y-combinator. + * @tparam Func Type of a potentially recursive function. + */ +template +struct y_combinator { + /** + * @brief Constructs a y-combinator from a given function. + * @param recursive A potentially recursive function. + */ + constexpr y_combinator(Func recursive) noexcept(std::is_nothrow_move_constructible_v) + : func{std::move(recursive)} {} + + /** + * @brief Invokes a y-combinator and therefore its underlying function. + * @tparam Args Types of arguments to use to invoke the underlying function. + * @param args Parameters to use to invoke the underlying function. + * @return Return value of the underlying function, if any. + */ + template + constexpr decltype(auto) operator()(Args &&...args) const noexcept(std::is_nothrow_invocable_v) { + return func(*this, std::forward(args)...); + } + + /*! @copydoc operator()() */ + template + constexpr decltype(auto) operator()(Args &&...args) noexcept(std::is_nothrow_invocable_v) { + return func(*this, std::forward(args)...); + } + +private: + Func func; +}; + +} // namespace entt + +#endif + +// #include "adjacency_matrix.hpp" +#ifndef ENTT_GRAPH_ADJACENCY_MATRIX_HPP +#define ENTT_GRAPH_ADJACENCY_MATRIX_HPP + +#include +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "../core/iterator.hpp" + +// #include "fwd.hpp" + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +class edge_iterator { + using size_type = std::size_t; + + void find_next() noexcept { + for(; pos != last && !it[static_cast(pos)]; pos += offset) {} + } + +public: + using value_type = std::pair; + using pointer = input_iterator_pointer; + using reference = value_type; + using difference_type = std::ptrdiff_t; + using iterator_category = std::input_iterator_tag; + using iterator_concept = std::forward_iterator_tag; + + constexpr edge_iterator() noexcept = default; + + // NOLINTNEXTLINE(bugprone-easily-swappable-parameters) + constexpr edge_iterator(It base, const size_type vertices, const size_type from, const size_type to, const size_type step) noexcept + : it{std::move(base)}, + vert{vertices}, + pos{from}, + last{to}, + offset{step} { + find_next(); + } + + constexpr edge_iterator &operator++() noexcept { + pos += offset; + find_next(); + return *this; + } + + constexpr edge_iterator operator++(int) noexcept { + const edge_iterator orig = *this; + return ++(*this), orig; + } + + [[nodiscard]] constexpr reference operator*() const noexcept { + return *operator->(); + } + + [[nodiscard]] constexpr pointer operator->() const noexcept { + return std::make_pair(pos / vert, pos % vert); + } + + template + friend constexpr bool operator==(const edge_iterator &, const edge_iterator &) noexcept; + +private: + It it{}; + size_type vert{}; + size_type pos{}; + size_type last{}; + size_type offset{}; +}; + +template +[[nodiscard]] constexpr bool operator==(const edge_iterator &lhs, const edge_iterator &rhs) noexcept { + return lhs.pos == rhs.pos; +} + +template +[[nodiscard]] constexpr bool operator!=(const edge_iterator &lhs, const edge_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Basic implementation of a directed adjacency matrix. + * @tparam Category Either a directed or undirected category tag. + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +class adjacency_matrix { + using alloc_traits = std::allocator_traits; + static_assert(std::is_base_of_v, "Invalid graph category"); + static_assert(std::is_same_v, "Invalid value type"); + using container_type = std::vector>; + +public: + /*! @brief Allocator type. */ + using allocator_type = Allocator; + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + /*! @brief Vertex type. */ + using vertex_type = size_type; + /*! @brief Edge type. */ + using edge_type = std::pair; + /*! @brief Vertex iterator type. */ + using vertex_iterator = iota_iterator; + /*! @brief Edge iterator type. */ + using edge_iterator = internal::edge_iterator; + /*! @brief Out-edge iterator type. */ + using out_edge_iterator = edge_iterator; + /*! @brief In-edge iterator type. */ + using in_edge_iterator = edge_iterator; + /*! @brief Graph category tag. */ + using graph_category = Category; + + /*! @brief Default constructor. */ + adjacency_matrix() noexcept(noexcept(allocator_type{})) + : adjacency_matrix{0u} { + } + + /** + * @brief Constructs an empty container with a given allocator. + * @param allocator The allocator to use. + */ + explicit adjacency_matrix(const allocator_type &allocator) noexcept + : adjacency_matrix{0u, allocator} {} + + /** + * @brief Constructs an empty container with a given allocator and user + * supplied number of vertices. + * @param vertices Number of vertices. + * @param allocator The allocator to use. + */ + adjacency_matrix(const size_type vertices, const allocator_type &allocator = allocator_type{}) + : matrix{vertices * vertices, allocator}, + vert{vertices} {} + + /*! @brief Default copy constructor. */ + adjacency_matrix(const adjacency_matrix &) = default; + + /** + * @brief Allocator-extended copy constructor. + * @param other The instance to copy from. + * @param allocator The allocator to use. + */ + adjacency_matrix(const adjacency_matrix &other, const allocator_type &allocator) + : matrix{other.matrix, allocator}, + vert{other.vert} {} + + /*! @brief Default move constructor. */ + adjacency_matrix(adjacency_matrix &&) noexcept = default; + + /** + * @brief Allocator-extended move constructor. + * @param other The instance to move from. + * @param allocator The allocator to use. + */ + adjacency_matrix(adjacency_matrix &&other, const allocator_type &allocator) + : matrix{std::move(other.matrix), allocator}, + vert{other.vert} {} + + /*! @brief Default destructor. */ + ~adjacency_matrix() = default; + + /** + * @brief Default copy assignment operator. + * @return This container. + */ + adjacency_matrix &operator=(const adjacency_matrix &) = default; + + /** + * @brief Default move assignment operator. + * @return This container. + */ + adjacency_matrix &operator=(adjacency_matrix &&) noexcept = default; + + /** + * @brief Exchanges the contents with those of a given adjacency matrix. + * @param other Adjacency matrix to exchange the content with. + */ + void swap(adjacency_matrix &other) noexcept { + using std::swap; + swap(matrix, other.matrix); + swap(vert, other.vert); + } + + /** + * @brief Returns the associated allocator. + * @return The associated allocator. + */ + [[nodiscard]] constexpr allocator_type get_allocator() const noexcept { + return matrix.get_allocator(); + } + + /*! @brief Clears the adjacency matrix. */ + void clear() noexcept { + matrix.clear(); + vert = {}; + } + + /** + * @brief Returns true if an adjacency matrix is empty, false otherwise. + * + * @warning + * Potentially expensive, try to avoid it on hot paths. + * + * @return True if the adjacency matrix is empty, false otherwise. + */ + [[nodiscard]] bool empty() const noexcept { + const auto iterable = edges(); + return (iterable.begin() == iterable.end()); + } + + /** + * @brief Returns the number of vertices. + * @return The number of vertices. + */ + [[nodiscard]] size_type size() const noexcept { + return vert; + } + + /** + * @brief Returns an iterable object to visit all vertices of a matrix. + * @return An iterable object to visit all vertices of a matrix. + */ + [[nodiscard]] iterable_adaptor vertices() const noexcept { + return {0u, vert}; + } + + /** + * @brief Returns an iterable object to visit all edges of a matrix. + * @return An iterable object to visit all edges of a matrix. + */ + [[nodiscard]] iterable_adaptor edges() const noexcept { + const auto it = matrix.cbegin(); + const auto sz = matrix.size(); + return {{it, vert, 0u, sz, 1u}, {it, vert, sz, sz, 1u}}; + } + + /** + * @brief Returns an iterable object to visit all out-edges of a vertex. + * @param vertex The vertex of which to return all out-edges. + * @return An iterable object to visit all out-edges of a vertex. + */ + [[nodiscard]] iterable_adaptor out_edges(const vertex_type vertex) const noexcept { + const auto it = matrix.cbegin(); + const auto from = vertex * vert; + const auto to = from + vert; + return {{it, vert, from, to, 1u}, {it, vert, to, to, 1u}}; + } + + /** + * @brief Returns an iterable object to visit all in-edges of a vertex. + * @param vertex The vertex of which to return all in-edges. + * @return An iterable object to visit all in-edges of a vertex. + */ + [[nodiscard]] iterable_adaptor in_edges(const vertex_type vertex) const noexcept { + const auto it = matrix.cbegin(); + const auto from = vertex; + const auto to = vert * vert + from; + return {{it, vert, from, to, vert}, {it, vert, to, to, vert}}; + } + + /** + * @brief Resizes an adjacency matrix. + * @param vertices The new number of vertices. + */ + void resize(const size_type vertices) { + adjacency_matrix other{vertices, get_allocator()}; + + for(auto [lhs, rhs]: edges()) { + other.insert(lhs, rhs); + } + + other.swap(*this); + } + + /** + * @brief Inserts an edge into the adjacency matrix, if it does not exist. + * @param lhs The left hand vertex of the edge. + * @param rhs The right hand vertex of the edge. + * @return A pair consisting of an iterator to the inserted element (or to + * the element that prevented the insertion) and a bool denoting whether the + * insertion took place. + */ + std::pair insert(const vertex_type lhs, const vertex_type rhs) { + const auto pos = lhs * vert + rhs; + + if constexpr(std::is_same_v) { + const auto rev = rhs * vert + lhs; + ENTT_ASSERT(matrix[pos] == matrix[rev], "Something went really wrong"); + matrix[rev] = 1u; + } + + const auto inserted = !std::exchange(matrix[pos], 1u); + return {edge_iterator{matrix.cbegin(), vert, pos, matrix.size(), 1u}, inserted}; + } + + /** + * @brief Removes the edge associated with a pair of given vertices. + * @param lhs The left hand vertex of the edge. + * @param rhs The right hand vertex of the edge. + * @return Number of elements removed (either 0 or 1). + */ + size_type erase(const vertex_type lhs, const vertex_type rhs) { + const auto pos = lhs * vert + rhs; + + if constexpr(std::is_same_v) { + const auto rev = rhs * vert + lhs; + ENTT_ASSERT(matrix[pos] == matrix[rev], "Something went really wrong"); + matrix[rev] = 0u; + } + + return std::exchange(matrix[pos], 0u); + } + + /** + * @brief Checks if an adjacency matrix contains a given edge. + * @param lhs The left hand vertex of the edge. + * @param rhs The right hand vertex of the edge. + * @return True if there is such an edge, false otherwise. + */ + [[nodiscard]] bool contains(const vertex_type lhs, const vertex_type rhs) const { + const auto pos = lhs * vert + rhs; + return pos < matrix.size() && matrix[pos]; + } + +private: + container_type matrix; + size_type vert; +}; + +} // namespace entt + +#endif + +// #include "fwd.hpp" + + +namespace entt { + +/** + * @brief Utility class for creating task graphs. + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +class basic_flow { + using alloc_traits = std::allocator_traits; + static_assert(std::is_same_v, "Invalid value type"); + using task_container_type = dense_set, typename alloc_traits::template rebind_alloc>; + using ro_rw_container_type = std::vector, typename alloc_traits::template rebind_alloc>>; + using deps_container_type = dense_map, typename alloc_traits::template rebind_alloc>>; + using adjacency_matrix_type = adjacency_matrix>; + + void emplace(const id_type res, const bool is_rw) { + ENTT_ASSERT(index.first() < vertices.size(), "Invalid node"); + + if(!deps.contains(res) && sync_on != vertices.size()) { + deps[res].emplace_back(sync_on, true); + } + + deps[res].emplace_back(index.first(), is_rw); + } + + void setup_graph(adjacency_matrix_type &matrix) const { + for(const auto &elem: deps) { + const auto last = elem.second.cend(); + auto it = elem.second.cbegin(); + + while(it != last) { + if(it->second) { + // rw item + if(auto curr = it++; it != last) { + if(it->second) { + matrix.insert(curr->first, it->first); + } else if(const auto next = std::find_if(it, last, [](const auto &value) { return value.second; }); next != last) { + for(; it != next; ++it) { + matrix.insert(curr->first, it->first); + matrix.insert(it->first, next->first); + } + } else { + for(; it != next; ++it) { + matrix.insert(curr->first, it->first); + } + } + } + } else { + // ro item (first iteration only) + if(const auto next = std::find_if(it, last, [](const auto &value) { return value.second; }); next != last) { + for(; it != next; ++it) { + matrix.insert(it->first, next->first); + } + } else { + it = last; + } + } + } + } + } + + void transitive_closure(adjacency_matrix_type &matrix) const { + const auto length = matrix.size(); + + for(std::size_t vk{}; vk < length; ++vk) { + for(std::size_t vi{}; vi < length; ++vi) { + for(std::size_t vj{}; vj < length; ++vj) { + if(matrix.contains(vi, vk) && matrix.contains(vk, vj)) { + matrix.insert(vi, vj); + } + } + } + } + } + + void transitive_reduction(adjacency_matrix_type &matrix) const { + const auto length = matrix.size(); + + for(std::size_t vert{}; vert < length; ++vert) { + matrix.erase(vert, vert); + } + + for(std::size_t vj{}; vj < length; ++vj) { + for(std::size_t vi{}; vi < length; ++vi) { + if(matrix.contains(vi, vj)) { + for(std::size_t vk{}; vk < length; ++vk) { + if(matrix.contains(vj, vk)) { + matrix.erase(vi, vk); + } + } + } + } + } + } + +public: + /*! @brief Allocator type. */ + using allocator_type = Allocator; + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + /*! @brief Iterable task list. */ + using iterable = iterable_adaptor; + /*! @brief Adjacency matrix type. */ + using graph_type = adjacency_matrix_type; + + /*! @brief Default constructor. */ + basic_flow() + : basic_flow{allocator_type{}} {} + + /** + * @brief Constructs a flow builder with a given allocator. + * @param allocator The allocator to use. + */ + explicit basic_flow(const allocator_type &allocator) + : index{0u, allocator}, + vertices{allocator}, + deps{allocator} {} + + /*! @brief Default copy constructor. */ + basic_flow(const basic_flow &) = default; + + /** + * @brief Allocator-extended copy constructor. + * @param other The instance to copy from. + * @param allocator The allocator to use. + */ + basic_flow(const basic_flow &other, const allocator_type &allocator) + : index{other.index.first(), allocator}, + vertices{other.vertices, allocator}, + deps{other.deps, allocator}, + sync_on{other.sync_on} {} + + /*! @brief Default move constructor. */ + basic_flow(basic_flow &&) noexcept = default; + + /** + * @brief Allocator-extended move constructor. + * @param other The instance to move from. + * @param allocator The allocator to use. + */ + basic_flow(basic_flow &&other, const allocator_type &allocator) + : index{other.index.first(), allocator}, + vertices{std::move(other.vertices), allocator}, + deps{std::move(other.deps), allocator}, + sync_on{other.sync_on} {} + + /*! @brief Default destructor. */ + ~basic_flow() = default; + + /** + * @brief Default copy assignment operator. + * @return This flow builder. + */ + basic_flow &operator=(const basic_flow &) = default; + + /** + * @brief Default move assignment operator. + * @return This flow builder. + */ + basic_flow &operator=(basic_flow &&) noexcept = default; + + /** + * @brief Exchanges the contents with those of a given flow builder. + * @param other Flow builder to exchange the content with. + */ + void swap(basic_flow &other) noexcept { + using std::swap; + std::swap(index, other.index); + std::swap(vertices, other.vertices); + std::swap(deps, other.deps); + std::swap(sync_on, other.sync_on); + } + + /** + * @brief Returns the associated allocator. + * @return The associated allocator. + */ + [[nodiscard]] constexpr allocator_type get_allocator() const noexcept { + return allocator_type{index.second()}; + } + + /** + * @brief Returns the identifier at specified location. + * @param pos Position of the identifier to return. + * @return The requested identifier. + */ + [[nodiscard]] id_type operator[](const size_type pos) const { + return vertices.cbegin()[static_cast(pos)]; + } + + /*! @brief Clears the flow builder. */ + void clear() noexcept { + index.first() = {}; + vertices.clear(); + deps.clear(); + sync_on = {}; + } + + /** + * @brief Returns true if a flow builder contains no tasks, false otherwise. + * @return True if the flow builder contains no tasks, false otherwise. + */ + [[nodiscard]] bool empty() const noexcept { + return vertices.empty(); + } + + /** + * @brief Returns the number of tasks. + * @return The number of tasks. + */ + [[nodiscard]] size_type size() const noexcept { + return vertices.size(); + } + + /** + * @brief Binds a task to a flow builder. + * @param value Task identifier. + * @return This flow builder. + */ + basic_flow &bind(const id_type value) { + sync_on += (sync_on == vertices.size()); + const auto it = vertices.emplace(value).first; + index.first() = size_type(it - vertices.begin()); + return *this; + } + + /** + * @brief Turns the current task into a sync point. + * @return This flow builder. + */ + basic_flow &sync() { + ENTT_ASSERT(index.first() < vertices.size(), "Invalid node"); + sync_on = index.first(); + + for(const auto &elem: deps) { + elem.second.emplace_back(sync_on, true); + } + + return *this; + } + + /** + * @brief Assigns a resource to the current task with a given access mode. + * @param res Resource identifier. + * @param is_rw Access mode. + * @return This flow builder. + */ + basic_flow &set(const id_type res, bool is_rw = false) { + emplace(res, is_rw); + return *this; + } + + /** + * @brief Assigns a read-only resource to the current task. + * @param res Resource identifier. + * @return This flow builder. + */ + basic_flow &ro(const id_type res) { + emplace(res, false); + return *this; + } + + /** + * @brief Assigns a range of read-only resources to the current task. + * @tparam It Type of input iterator. + * @param first An iterator to the first element of the range of elements. + * @param last An iterator past the last element of the range of elements. + * @return This flow builder. + */ + template + std::enable_if_t::value_type>, id_type>, basic_flow &> + ro(It first, It last) { + for(; first != last; ++first) { + emplace(*first, false); + } + + return *this; + } + + /** + * @brief Assigns a writable resource to the current task. + * @param res Resource identifier. + * @return This flow builder. + */ + basic_flow &rw(const id_type res) { + emplace(res, true); + return *this; + } + + /** + * @brief Assigns a range of writable resources to the current task. + * @tparam It Type of input iterator. + * @param first An iterator to the first element of the range of elements. + * @param last An iterator past the last element of the range of elements. + * @return This flow builder. + */ + template + std::enable_if_t::value_type>, id_type>, basic_flow &> + rw(It first, It last) { + for(; first != last; ++first) { + emplace(*first, true); + } + + return *this; + } + + /** + * @brief Generates a task graph for the current content. + * @return The adjacency matrix of the task graph. + */ + [[nodiscard]] graph_type graph() const { + graph_type matrix{vertices.size(), get_allocator()}; + + setup_graph(matrix); + transitive_closure(matrix); + transitive_reduction(matrix); + + return matrix; + } + +private: + compressed_pair index; + task_container_type vertices; + deps_container_type deps; + size_type sync_on{}; +}; + +} // namespace entt + +#endif + +// #include "locator/locator.hpp" +#ifndef ENTT_LOCATOR_LOCATOR_HPP +#define ENTT_LOCATOR_LOCATOR_HPP + +#include +#include +// #include "../config/config.h" +#ifndef ENTT_CONFIG_CONFIG_H +#define ENTT_CONFIG_CONFIG_H + +// #include "version.h" +#ifndef ENTT_CONFIG_VERSION_H +#define ENTT_CONFIG_VERSION_H + +// #include "macro.h" +#ifndef ENTT_CONFIG_MACRO_H +#define ENTT_CONFIG_MACRO_H + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#define ENTT_STR(arg) #arg +#define ENTT_XSTR(arg) ENTT_STR(arg) + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*) + +#define ENTT_VERSION_MAJOR 3 +#define ENTT_VERSION_MINOR 16 +#define ENTT_VERSION_PATCH 0 + +#define ENTT_VERSION \ + ENTT_XSTR(ENTT_VERSION_MAJOR) \ + "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH) + +// NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION) +# define ENTT_CONSTEXPR +# define ENTT_THROW throw +# define ENTT_TRY try +# define ENTT_CATCH catch(...) +#else +# define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20) +# define ENTT_THROW +# define ENTT_TRY if(true) +# define ENTT_CATCH if(false) +#endif + +#if __has_include() +# include +# +# if defined(__cpp_consteval) +# define ENTT_CONSTEVAL consteval +# endif +#endif + +#ifndef ENTT_CONSTEVAL +# define ENTT_CONSTEVAL constexpr +#endif + +#ifdef ENTT_USE_ATOMIC +# include +# define ENTT_MAYBE_ATOMIC(Type) std::atomic +#else +# define ENTT_MAYBE_ATOMIC(Type) Type +#endif + +#ifndef ENTT_ID_TYPE +# include +# define ENTT_ID_TYPE std::uint32_t +#else +# include // provides coverage for types in the std namespace +#endif + +#ifndef ENTT_SPARSE_PAGE +# define ENTT_SPARSE_PAGE 4096 +#endif + +#ifndef ENTT_PACKED_PAGE +# define ENTT_PACKED_PAGE 1024 +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT +# define ENTT_ASSERT(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT +# include +# define ENTT_ASSERT(condition, msg) assert(((condition) && (msg))) +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg) +#endif + +#define ENTT_FAIL(msg) ENTT_ASSERT(false, msg); + +#ifdef ENTT_NO_ETO +# define ENTT_ETO_TYPE(Type) void +#else +# define ENTT_ETO_TYPE(Type) Type +#endif + +#ifdef ENTT_NO_MIXIN +# define ENTT_STORAGE(Mixin, ...) __VA_ARGS__ +#else +# define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__> +#endif + +#ifdef ENTT_STANDARD_CPP +# define ENTT_NONSTD false +#else +# define ENTT_NONSTD true +# if defined __clang__ || defined __GNUC__ +# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ +# define ENTT_PRETTY_FUNCTION_PREFIX '=' +# define ENTT_PRETTY_FUNCTION_SUFFIX ']' +# elif defined _MSC_VER +# define ENTT_PRETTY_FUNCTION __FUNCSIG__ +# define ENTT_PRETTY_FUNCTION_PREFIX '<' +# define ENTT_PRETTY_FUNCTION_SUFFIX '>' +# endif +#endif + +#ifndef ENTT_EXPORT +# if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER +# define ENTT_EXPORT __declspec(dllexport) +# define ENTT_IMPORT __declspec(dllimport) +# define ENTT_HIDDEN +# elif defined __GNUC__ && __GNUC__ >= 4 +# define ENTT_EXPORT __attribute__((visibility("default"))) +# define ENTT_IMPORT __attribute__((visibility("default"))) +# define ENTT_HIDDEN __attribute__((visibility("hidden"))) +# else /* Unsupported compiler */ +# define ENTT_EXPORT +# define ENTT_IMPORT +# define ENTT_HIDDEN +# endif +#endif + +#ifndef ENTT_API +# if defined ENTT_API_EXPORT +# define ENTT_API ENTT_EXPORT +# elif defined ENTT_API_IMPORT +# define ENTT_API ENTT_IMPORT +# else /* No API */ +# define ENTT_API +# endif +#endif + +#if defined _MSC_VER +# pragma detect_mismatch("entt.version", ENTT_VERSION) +# pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY)) +# pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE)) +# pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD)) +#endif + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +namespace entt { + +/** + * @brief Service locator, nothing more. + * + * A service locator is used to do what it promises: locate services.
+ * Usually service locators are tightly bound to the services they expose and + * thus it's hard to define a general purpose class to do that. This tiny class + * tries to fill the gap and to get rid of the burden of defining a different + * specific locator for each application. + * + * @note + * Users shouldn't retain references to a service. The recommended way is to + * retrieve the service implementation currently set each and every time the + * need for it arises. The risk is to incur in unexpected behaviors otherwise. + * + * @tparam Service Service type. + */ +template +class locator final { + class service_handle { + friend class locator; + std::shared_ptr value{}; + }; + +public: + /*! @brief Service type. */ + using type = Service; + /*! @brief Service node type. */ + using node_type = service_handle; + + /*! @brief Default constructor, deleted on purpose. */ + locator() = delete; + + /*! @brief Default copy constructor, deleted on purpose. */ + locator(const locator &) = delete; + + /*! @brief Default destructor, deleted on purpose. */ + ~locator() = delete; + + /** + * @brief Default copy assignment operator, deleted on purpose. + * @return This locator. + */ + locator &operator=(const locator &) = delete; + + /** + * @brief Checks whether a service locator contains a value. + * @return True if the service locator contains a value, false otherwise. + */ + [[nodiscard]] static bool has_value() noexcept { + return (service != nullptr); + } + + /** + * @brief Returns a reference to a valid service, if any. + * + * @warning + * Invoking this function can result in undefined behavior if the service + * hasn't been set yet. + * + * @return A reference to the service currently set, if any. + */ + [[nodiscard]] static Service &value() noexcept { + ENTT_ASSERT(has_value(), "Service not available"); + return *service; + } + + /** + * @brief Returns a service if available or sets it from a fallback type. + * + * Arguments are used only if a service doesn't already exist. In all other + * cases, they are discarded. + * + * @tparam Args Types of arguments to use to construct the fallback service. + * @tparam Type Fallback service type. + * @param args Parameters to use to construct the fallback service. + * @return A reference to a valid service. + */ + template + [[nodiscard]] static Service &value_or(Args &&...args) { + return service ? *service : emplace(std::forward(args)...); + } + + /** + * @brief Sets or replaces a service. + * @tparam Type Service type. + * @tparam Args Types of arguments to use to construct the service. + * @param args Parameters to use to construct the service. + * @return A reference to a valid service. + */ + template + static Service &emplace(Args &&...args) { + service = std::make_shared(std::forward(args)...); + return *service; + } + + /** + * @brief Sets or replaces a service using a given allocator. + * @tparam Type Service type. + * @tparam Allocator Type of allocator used to manage memory and elements. + * @tparam Args Types of arguments to use to construct the service. + * @param alloc The allocator to use. + * @param args Parameters to use to construct the service. + * @return A reference to a valid service. + */ + template + static Service &emplace(std::allocator_arg_t, Allocator alloc, Args &&...args) { + service = std::allocate_shared(alloc, std::forward(args)...); + return *service; + } + + /** + * @brief Returns a handle to the underlying service. + * @return A handle to the underlying service. + */ + static node_type handle() noexcept { + node_type node{}; + node.value = service; + return node; + } + + /** + * @brief Resets or replaces a service. + * @param other Optional handle with which to replace the service. + */ + static void reset(const node_type &other = {}) noexcept { + service = other.value; + } + + /** + * @brief Resets or replaces a service. + * @tparam Type Service type. + * @tparam Deleter Deleter type. + * @param elem A pointer to a service to manage. + * @param deleter A deleter to use to destroy the service. + */ + template> + static void reset(Type *elem, Deleter deleter = {}) { + service = std::shared_ptr{elem, std::move(deleter)}; + } + +private: + // std::shared_ptr because of its type erased allocator which is useful here + // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) + inline static std::shared_ptr service{}; +}; + +} // namespace entt + +#endif + +// #include "meta/adl_pointer.hpp" +#ifndef ENTT_META_ADL_POINTER_HPP +#define ENTT_META_ADL_POINTER_HPP + +namespace entt { + +/** + * @brief ADL based lookup function for dereferencing meta pointer-like types. + * @tparam Type Element type. + * @param value A pointer-like object. + * @return The value returned from the dereferenced pointer. + */ +template +decltype(auto) dereference_meta_pointer_like(const Type &value) { + return *value; +} + +/** + * @brief Fake ADL based lookup function for meta pointer-like types. + * @tparam Type Element type. + */ +template +struct adl_meta_pointer_like { + /** + * @brief Uses the default ADL based lookup method to resolve the call. + * @param value A pointer-like object. + * @return The value returned from the dereferenced pointer. + */ + static decltype(auto) dereference(const Type &value) { + return dereference_meta_pointer_like(value); + } +}; + +} // namespace entt + +#endif + +// #include "meta/container.hpp" +// IWYU pragma: always_keep + +#ifndef ENTT_META_CONTAINER_HPP +#define ENTT_META_CONTAINER_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #include "../container/dense_map.hpp" +#ifndef ENTT_CONTAINER_DENSE_MAP_HPP +#define ENTT_CONTAINER_DENSE_MAP_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #include "../config/config.h" +#ifndef ENTT_CONFIG_CONFIG_H +#define ENTT_CONFIG_CONFIG_H + +// #include "version.h" +#ifndef ENTT_CONFIG_VERSION_H +#define ENTT_CONFIG_VERSION_H + +// #include "macro.h" +#ifndef ENTT_CONFIG_MACRO_H +#define ENTT_CONFIG_MACRO_H + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#define ENTT_STR(arg) #arg +#define ENTT_XSTR(arg) ENTT_STR(arg) + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*) + +#define ENTT_VERSION_MAJOR 3 +#define ENTT_VERSION_MINOR 16 +#define ENTT_VERSION_PATCH 0 + +#define ENTT_VERSION \ + ENTT_XSTR(ENTT_VERSION_MAJOR) \ + "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH) + +// NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION) +# define ENTT_CONSTEXPR +# define ENTT_THROW throw +# define ENTT_TRY try +# define ENTT_CATCH catch(...) +#else +# define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20) +# define ENTT_THROW +# define ENTT_TRY if(true) +# define ENTT_CATCH if(false) +#endif + +#if __has_include() +# include +# +# if defined(__cpp_consteval) +# define ENTT_CONSTEVAL consteval +# endif +#endif + +#ifndef ENTT_CONSTEVAL +# define ENTT_CONSTEVAL constexpr +#endif + +#ifdef ENTT_USE_ATOMIC +# include +# define ENTT_MAYBE_ATOMIC(Type) std::atomic +#else +# define ENTT_MAYBE_ATOMIC(Type) Type +#endif + +#ifndef ENTT_ID_TYPE +# include +# define ENTT_ID_TYPE std::uint32_t +#else +# include // provides coverage for types in the std namespace +#endif + +#ifndef ENTT_SPARSE_PAGE +# define ENTT_SPARSE_PAGE 4096 +#endif + +#ifndef ENTT_PACKED_PAGE +# define ENTT_PACKED_PAGE 1024 +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT +# define ENTT_ASSERT(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT +# include +# define ENTT_ASSERT(condition, msg) assert(((condition) && (msg))) +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg) +#endif + +#define ENTT_FAIL(msg) ENTT_ASSERT(false, msg); + +#ifdef ENTT_NO_ETO +# define ENTT_ETO_TYPE(Type) void +#else +# define ENTT_ETO_TYPE(Type) Type +#endif + +#ifdef ENTT_NO_MIXIN +# define ENTT_STORAGE(Mixin, ...) __VA_ARGS__ +#else +# define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__> +#endif + +#ifdef ENTT_STANDARD_CPP +# define ENTT_NONSTD false +#else +# define ENTT_NONSTD true +# if defined __clang__ || defined __GNUC__ +# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ +# define ENTT_PRETTY_FUNCTION_PREFIX '=' +# define ENTT_PRETTY_FUNCTION_SUFFIX ']' +# elif defined _MSC_VER +# define ENTT_PRETTY_FUNCTION __FUNCSIG__ +# define ENTT_PRETTY_FUNCTION_PREFIX '<' +# define ENTT_PRETTY_FUNCTION_SUFFIX '>' +# endif +#endif + +#ifndef ENTT_EXPORT +# if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER +# define ENTT_EXPORT __declspec(dllexport) +# define ENTT_IMPORT __declspec(dllimport) +# define ENTT_HIDDEN +# elif defined __GNUC__ && __GNUC__ >= 4 +# define ENTT_EXPORT __attribute__((visibility("default"))) +# define ENTT_IMPORT __attribute__((visibility("default"))) +# define ENTT_HIDDEN __attribute__((visibility("hidden"))) +# else /* Unsupported compiler */ +# define ENTT_EXPORT +# define ENTT_IMPORT +# define ENTT_HIDDEN +# endif +#endif + +#ifndef ENTT_API +# if defined ENTT_API_EXPORT +# define ENTT_API ENTT_EXPORT +# elif defined ENTT_API_IMPORT +# define ENTT_API ENTT_IMPORT +# else /* No API */ +# define ENTT_API +# endif +#endif + +#if defined _MSC_VER +# pragma detect_mismatch("entt.version", ENTT_VERSION) +# pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY)) +# pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE)) +# pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD)) +#endif + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + +// #include "../core/bit.hpp" +#ifndef ENTT_CORE_BIT_HPP +#define ENTT_CORE_BIT_HPP + +#include +#include +#include +// #include "../config/config.h" +#ifndef ENTT_CONFIG_CONFIG_H +#define ENTT_CONFIG_CONFIG_H + +// #include "version.h" +#ifndef ENTT_CONFIG_VERSION_H +#define ENTT_CONFIG_VERSION_H + +// #include "macro.h" +#ifndef ENTT_CONFIG_MACRO_H +#define ENTT_CONFIG_MACRO_H + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#define ENTT_STR(arg) #arg +#define ENTT_XSTR(arg) ENTT_STR(arg) + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*) + +#define ENTT_VERSION_MAJOR 3 +#define ENTT_VERSION_MINOR 16 +#define ENTT_VERSION_PATCH 0 + +#define ENTT_VERSION \ + ENTT_XSTR(ENTT_VERSION_MAJOR) \ + "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH) + +// NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION) +# define ENTT_CONSTEXPR +# define ENTT_THROW throw +# define ENTT_TRY try +# define ENTT_CATCH catch(...) +#else +# define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20) +# define ENTT_THROW +# define ENTT_TRY if(true) +# define ENTT_CATCH if(false) +#endif + +#if __has_include() +# include +# +# if defined(__cpp_consteval) +# define ENTT_CONSTEVAL consteval +# endif +#endif + +#ifndef ENTT_CONSTEVAL +# define ENTT_CONSTEVAL constexpr +#endif + +#ifdef ENTT_USE_ATOMIC +# include +# define ENTT_MAYBE_ATOMIC(Type) std::atomic +#else +# define ENTT_MAYBE_ATOMIC(Type) Type +#endif + +#ifndef ENTT_ID_TYPE +# include +# define ENTT_ID_TYPE std::uint32_t +#else +# include // provides coverage for types in the std namespace +#endif + +#ifndef ENTT_SPARSE_PAGE +# define ENTT_SPARSE_PAGE 4096 +#endif + +#ifndef ENTT_PACKED_PAGE +# define ENTT_PACKED_PAGE 1024 +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT +# define ENTT_ASSERT(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT +# include +# define ENTT_ASSERT(condition, msg) assert(((condition) && (msg))) +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg) +#endif + +#define ENTT_FAIL(msg) ENTT_ASSERT(false, msg); + +#ifdef ENTT_NO_ETO +# define ENTT_ETO_TYPE(Type) void +#else +# define ENTT_ETO_TYPE(Type) Type +#endif + +#ifdef ENTT_NO_MIXIN +# define ENTT_STORAGE(Mixin, ...) __VA_ARGS__ +#else +# define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__> +#endif + +#ifdef ENTT_STANDARD_CPP +# define ENTT_NONSTD false +#else +# define ENTT_NONSTD true +# if defined __clang__ || defined __GNUC__ +# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ +# define ENTT_PRETTY_FUNCTION_PREFIX '=' +# define ENTT_PRETTY_FUNCTION_SUFFIX ']' +# elif defined _MSC_VER +# define ENTT_PRETTY_FUNCTION __FUNCSIG__ +# define ENTT_PRETTY_FUNCTION_PREFIX '<' +# define ENTT_PRETTY_FUNCTION_SUFFIX '>' +# endif +#endif + +#ifndef ENTT_EXPORT +# if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER +# define ENTT_EXPORT __declspec(dllexport) +# define ENTT_IMPORT __declspec(dllimport) +# define ENTT_HIDDEN +# elif defined __GNUC__ && __GNUC__ >= 4 +# define ENTT_EXPORT __attribute__((visibility("default"))) +# define ENTT_IMPORT __attribute__((visibility("default"))) +# define ENTT_HIDDEN __attribute__((visibility("hidden"))) +# else /* Unsupported compiler */ +# define ENTT_EXPORT +# define ENTT_IMPORT +# define ENTT_HIDDEN +# endif +#endif + +#ifndef ENTT_API +# if defined ENTT_API_EXPORT +# define ENTT_API ENTT_EXPORT +# elif defined ENTT_API_IMPORT +# define ENTT_API ENTT_IMPORT +# else /* No API */ +# define ENTT_API +# endif +#endif + +#if defined _MSC_VER +# pragma detect_mismatch("entt.version", ENTT_VERSION) +# pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY)) +# pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE)) +# pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD)) +#endif + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +namespace entt { + +/** + * @brief Returns the number of set bits in a value (waiting for C++20 and + * `std::popcount`). + * @tparam Type Unsigned integer type. + * @param value A value of unsigned integer type. + * @return The number of set bits in the value. + */ +template +[[nodiscard]] constexpr std::enable_if_t, int> popcount(const Type value) noexcept { + return value ? (int(value & 1) + popcount(static_cast(value >> 1))) : 0; +} + +/** + * @brief Checks whether a value is a power of two or not (waiting for C++20 and + * `std::has_single_bit`). + * @tparam Type Unsigned integer type. + * @param value A value of unsigned integer type. + * @return True if the value is a power of two, false otherwise. + */ +template +[[nodiscard]] constexpr std::enable_if_t, bool> has_single_bit(const Type value) noexcept { + return value && ((value & (value - 1)) == 0); +} + +/** + * @brief Computes the smallest power of two greater than or equal to a value + * (waiting for C++20 and `std::bit_ceil`). + * @tparam Type Unsigned integer type. + * @param value A value of unsigned integer type. + * @return The smallest power of two greater than or equal to the given value. + */ +template +[[nodiscard]] constexpr std::enable_if_t, Type> next_power_of_two(const Type value) noexcept { + // NOLINTNEXTLINE(bugprone-assert-side-effect) + ENTT_ASSERT_CONSTEXPR(value < (Type{1u} << (std::numeric_limits::digits - 1)), "Numeric limits exceeded"); + Type curr = value - (value != 0u); + + for(int next = 1; next < std::numeric_limits::digits; next = next * 2) { + curr |= (curr >> next); + } + + return ++curr; +} + +/** + * @brief Fast module utility function (powers of two only). + * @tparam Type Unsigned integer type. + * @param value A value of unsigned integer type. + * @param mod _Modulus_, it must be a power of two. + * @return The common remainder. + */ +template +[[nodiscard]] constexpr std::enable_if_t, Type> fast_mod(const Type value, const std::size_t mod) noexcept { + ENTT_ASSERT_CONSTEXPR(has_single_bit(mod), "Value must be a power of two"); + return static_cast(value & (mod - 1u)); +} + +} // namespace entt + +#endif + +// #include "../core/compressed_pair.hpp" +#ifndef ENTT_CORE_COMPRESSED_PAIR_HPP +#define ENTT_CORE_COMPRESSED_PAIR_HPP + +#include +#include +#include +#include +// #include "fwd.hpp" +#ifndef ENTT_CORE_FWD_HPP +#define ENTT_CORE_FWD_HPP + +#include +#include +// #include "../config/config.h" + + +namespace entt { + +/*! @brief Possible modes of an any object. */ +enum class any_policy : std::uint8_t { + /*! @brief Default mode, no element available. */ + empty, + /*! @brief Owning mode, dynamically allocated element. */ + dynamic, + /*! @brief Owning mode, embedded element. */ + embedded, + /*! @brief Aliasing mode, non-const reference. */ + ref, + /*! @brief Const aliasing mode, const reference. */ + cref +}; + +// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) +template +class basic_any; + +/*! @brief Alias declaration for type identifiers. */ +using id_type = ENTT_ID_TYPE; + +/*! @brief Alias declaration for the most common use case. */ +using any = basic_any<>; + +template +class compressed_pair; + +template +class basic_hashed_string; + +/*! @brief Aliases for common character types. */ +using hashed_string = basic_hashed_string; + +/*! @brief Aliases for common character types. */ +using hashed_wstring = basic_hashed_string; + +// NOLINTNEXTLINE(bugprone-forward-declaration-namespace) +struct type_info; + +} // namespace entt + +#endif + +// #include "type_traits.hpp" +#ifndef ENTT_CORE_TYPE_TRAITS_HPP +#define ENTT_CORE_TYPE_TRAITS_HPP + +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "fwd.hpp" + + +namespace entt { + +/** + * @brief Utility class to disambiguate overloaded functions. + * @tparam N Number of choices available. + */ +template +struct choice_t + // unfortunately, doxygen cannot parse such a construct + : /*! @cond TURN_OFF_DOXYGEN */ choice_t /*! @endcond */ +{}; + +/*! @copybrief choice_t */ +template<> +struct choice_t<0> {}; + +/** + * @brief Variable template for the choice trick. + * @tparam N Number of choices available. + */ +template +inline constexpr choice_t choice{}; + +/** + * @brief Identity type trait. + * + * Useful to establish non-deduced contexts in template argument deduction + * (waiting for C++20) or to provide types through function arguments. + * + * @tparam Type A type. + */ +template +struct type_identity { + /*! @brief Identity type. */ + using type = Type; +}; + +/** + * @brief Helper type. + * @tparam Type A type. + */ +template +using type_identity_t = typename type_identity::type; + +/** + * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains. + * @tparam Type The type of which to return the size. + */ +template +struct size_of: std::integral_constant {}; + +/*! @copydoc size_of */ +template +struct size_of> + // NOLINTNEXTLINE(bugprone-sizeof-expression) + : std::integral_constant {}; + +/** + * @brief Helper variable template. + * @tparam Type The type of which to return the size. + */ +template +inline constexpr std::size_t size_of_v = size_of::value; + +/** + * @brief Using declaration to be used to _repeat_ the same type a number of + * times equal to the size of a given parameter pack. + * @tparam Type A type to repeat. + */ +template +using unpack_as_type = Type; + +/** + * @brief Helper variable template to be used to _repeat_ the same value a + * number of times equal to the size of a given parameter pack. + * @tparam Value A value to repeat. + */ +template +inline constexpr auto unpack_as_value = Value; + +/** + * @brief Wraps a static constant. + * @tparam Value A static constant. + */ +template +using integral_constant = std::integral_constant; + +/** + * @brief Alias template to facilitate the creation of named values. + * @tparam Value A constant value at least convertible to `id_type`. + */ +template +using tag = integral_constant; + +/** + * @brief A class to use to push around lists of types, nothing more. + * @tparam Type Types provided by the type list. + */ +template +struct type_list { + /*! @brief Type list type. */ + using type = type_list; + /*! @brief Compile-time number of elements in the type list. */ + static constexpr auto size = sizeof...(Type); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_element; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Index Index of the type to return. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element> + : type_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element<0u, type_list> { + /*! @brief Searched type. */ + using type = First; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Type list to search into. + */ +template +using type_list_element_t = typename type_list_element::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_index; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 1u + type_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + static_assert(type_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +inline constexpr std::size_t type_list_index_v = type_list_index::value; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @return A type list composed by the types of both the type lists. + */ +template +constexpr type_list operator+(type_list, type_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_cat; + +/*! @brief Concatenates multiple type lists. */ +template<> +struct type_list_cat<> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list<>; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @tparam List Other type lists, if any. + */ +template +struct type_list_cat, type_list, List...> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = typename type_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the type list. + */ +template +struct type_list_cat> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list; +}; + +/** + * @brief Helper type. + * @tparam List Type lists to concatenate. + */ +template +using type_list_cat_t = typename type_list_cat::type; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct type_list_unique; + +template +struct type_list_unique, Type...> + : std::conditional_t<(std::is_same_v || ...), type_list_unique, Type...>, type_list_unique, Type..., First>> {}; + +template +struct type_list_unique, Type...> { + using type = type_list; +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Removes duplicates types from a type list. + * @tparam List Type list. + */ +template +struct type_list_unique { + /*! @brief A type list without duplicate types. */ + using type = typename internal::type_list_unique::type; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + */ +template +using type_list_unique_t = typename type_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a type list contains a + * given type, false otherwise. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +struct type_list_contains; + +/** + * @copybrief type_list_contains + * @tparam Type Types provided by the type list. + * @tparam Other Type to look for. + */ +template +struct type_list_contains, Other> + : std::bool_constant<(std::is_same_v || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +inline constexpr bool type_list_contains_v = type_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_diff; + +/** + * @brief Computes the difference between two type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + */ +template +struct type_list_diff, type_list> { + /*! @brief A type list that is the difference between the two type lists. */ + using type = type_list_cat_t, Type>, type_list<>, type_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Type lists between which to compute the difference. + */ +template +using type_list_diff_t = typename type_list_diff::type; + +/*! @brief Primary template isn't defined on purpose. */ +template class> +struct type_list_transform; + +/** + * @brief Applies a given _function_ to a type list and generate a new list. + * @tparam Type Types provided by the type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +struct type_list_transform, Op> { + /*! @brief Resulting type list after applying the transform function. */ + // NOLINTNEXTLINE(modernize-type-traits) + using type = type_list::type...>; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +using type_list_transform_t = typename type_list_transform::type; + +/** + * @brief A class to use to push around lists of constant values, nothing more. + * @tparam Value Values provided by the value list. + */ +template +struct value_list { + /*! @brief Value list type. */ + using type = value_list; + /*! @brief Compile-time number of elements in the value list. */ + static constexpr auto size = sizeof...(Value); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_element; + +/** + * @brief Provides compile-time indexed access to the values of a value list. + * @tparam Index Index of the value to return. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element> + : value_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element<0u, value_list> { + /*! @brief Searched type. */ + using type = decltype(Value); + /*! @brief Searched value. */ + static constexpr auto value = Value; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Value list to search into. + */ +template +using value_list_element_t = typename value_list_element::type; + +/** + * @brief Helper type. + * @tparam Index Index of the value to return. + * @tparam List Value list to search into. + */ +template +inline constexpr auto value_list_element_v = value_list_element::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_index; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam First First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 1u + value_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + static_assert(value_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +inline constexpr std::size_t value_list_index_v = value_list_index::value; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @return A value list composed by the values of both the value lists. + */ +template +constexpr value_list operator+(value_list, value_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_cat; + +/*! @brief Concatenates multiple value lists. */ +template<> +struct value_list_cat<> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list<>; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @tparam List Other value lists, if any. + */ +template +struct value_list_cat, value_list, List...> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = typename value_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the value list. + */ +template +struct value_list_cat> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list; +}; + +/** + * @brief Helper type. + * @tparam List Value lists to concatenate. + */ +template +using value_list_cat_t = typename value_list_cat::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_unique; + +/** + * @brief Removes duplicates values from a value list. + * @tparam Value One of the values provided by the given value list. + * @tparam Other The other values provided by the given value list. + */ +template +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = std::conditional_t< + ((Value == Other) || ...), + typename value_list_unique>::type, + value_list_cat_t, typename value_list_unique>::type>>; +}; + +/*! @brief Removes duplicates values from a value list. */ +template<> +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = value_list<>; +}; + +/** + * @brief Helper type. + * @tparam Type A value list. + */ +template +using value_list_unique_t = typename value_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a value list contains + * a given value, false otherwise. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +struct value_list_contains; + +/** + * @copybrief value_list_contains + * @tparam Value Values provided by the value list. + * @tparam Other Value to look for. + */ +template +struct value_list_contains, Other> + : std::bool_constant<((Value == Other) || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +inline constexpr bool value_list_contains_v = value_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_diff; + +/** + * @brief Computes the difference between two value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + */ +template +struct value_list_diff, value_list> { + /*! @brief A value list that is the difference between the two value lists. */ + using type = value_list_cat_t, Value>, value_list<>, value_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Value lists between which to compute the difference. + */ +template +using value_list_diff_t = typename value_list_diff::type; + +/*! @brief Same as std::is_invocable, but with tuples. */ +template +struct is_applicable: std::false_type {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @brief Helper variable template. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_v = is_applicable::value; + +/*! @brief Same as std::is_invocable_r, but with tuples for arguments. */ +template +struct is_applicable_r: std::false_type {}; + +/** + * @copybrief is_applicable_r + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +struct is_applicable_r>: std::is_invocable_r {}; + +/** + * @brief Helper variable template. + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_r_v = is_applicable_r::value; + +/** + * @brief Provides the member constant `value` to true if a given type is + * complete, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_complete: std::false_type {}; + +/*! @copydoc is_complete */ +template +struct is_complete>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_complete_v = is_complete::value; + +/** + * @brief Provides the member constant `value` to true if a given type is an + * iterator, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_iterator: std::false_type {}; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_iterator_category: std::false_type {}; + +template +struct has_iterator_category::iterator_category>>: std::true_type {}; + +} // namespace internal +/*! @endcond */ + +/*! @copydoc is_iterator */ +template +struct is_iterator>>>> + : internal::has_iterator_category {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_iterator_v = is_iterator::value; + +/** + * @brief Provides the member constant `value` to true if a given type is both + * an empty and non-final class, false otherwise. + * @tparam Type The type to test + */ +template +struct is_ebco_eligible + : std::bool_constant && !std::is_final_v> {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_ebco_eligible_v = is_ebco_eligible::value; + +/** + * @brief Provides the member constant `value` to true if `Type::is_transparent` + * is valid and denotes a type, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_transparent: std::false_type {}; + +/*! @copydoc is_transparent */ +template +struct is_transparent>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_transparent_v = is_transparent::value; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_tuple_size_value: std::false_type {}; + +template +struct has_tuple_size_value::value)>>: std::true_type {}; + +template +struct has_value_type: std::false_type {}; + +template +struct has_value_type>: std::true_type {}; + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable(); + +template +[[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence) { + return (dispatch_is_equality_comparable>() && ...); +} + +template +[[nodiscard]] constexpr bool maybe_equality_comparable(char) { + return false; +} + +template +[[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval() == std::declval()) { + return true; +} + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable() { + // NOLINTBEGIN(modernize-use-transparent-functors) + if constexpr(std::is_array_v) { + return false; + } else if constexpr(is_complete_v>>) { + if constexpr(has_tuple_size_value::value) { + return maybe_equality_comparable(0) && unpack_maybe_equality_comparable(std::make_index_sequence::value>{}); + } else { + return maybe_equality_comparable(0); + } + } else if constexpr(has_value_type::value) { + if constexpr(is_iterator_v || std::is_same_v || dispatch_is_equality_comparable()) { + return maybe_equality_comparable(0); + } else { + return false; + } + } else { + return maybe_equality_comparable(0); + } + // NOLINTEND(modernize-use-transparent-functors) +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Provides the member constant `value` to true if a given type is + * equality comparable, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_equality_comparable: std::bool_constant()> {}; + +/*! @copydoc is_equality_comparable */ +template +struct is_equality_comparable: is_equality_comparable {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_equality_comparable_v = is_equality_comparable::value; + +/** + * @brief Transcribes the constness of a type to another type. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = std::remove_const_t; +}; + +/*! @copydoc constness_as */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = const To; +}; + +/** + * @brief Alias template to facilitate the transcription of the constness. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +using constness_as_t = typename constness_as::type; + +/** + * @brief Extracts the class of a non-static member object or function. + * @tparam Member A pointer to a non-static member object or function. + */ +template +class member_class { + static_assert(std::is_member_pointer_v, "Invalid pointer type to non-static member object or function"); + + template + static Class *clazz(Ret (Class::*)(Args...)); + + template + static Class *clazz(Ret (Class::*)(Args...) const); + + template + static Class *clazz(Type Class::*); + +public: + /*! @brief The class of the given non-static member object or function. */ + using type = std::remove_pointer_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Member A pointer to a non-static member object or function. + */ +template +using member_class_t = typename member_class::type; + +/** + * @brief Extracts the n-th argument of a _callable_ type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid _callable_ type. + */ +template +class nth_argument { + template + static constexpr type_list pick_up(Ret (*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...) const); + + template + static constexpr type_list pick_up(Type Class ::*); + + template + static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&); + +public: + /*! @brief N-th argument of the _callable_ type. */ + using type = type_list_element_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid function, member function or data member type. + */ +template +using nth_argument_t = typename nth_argument::type; + +} // namespace entt + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::type_list_element> {}; + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::value_list_element> {}; + +#endif + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct compressed_pair_element { + using reference = Type &; + using const_reference = const Type &; + + template>> + // NOLINTNEXTLINE(modernize-use-equals-default) + constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v) {} + + template>, compressed_pair_element>>> + constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v) + : value{std::forward(arg)} {} + + template + constexpr compressed_pair_element(std::tuple args, std::index_sequence) noexcept(std::is_nothrow_constructible_v) + : value{std::forward(std::get(args))...} {} + + [[nodiscard]] constexpr reference get() noexcept { + return value; + } + + [[nodiscard]] constexpr const_reference get() const noexcept { + return value; + } + +private: + Type value{}; +}; + +template +struct compressed_pair_element>>: Type { + using reference = Type &; + using const_reference = const Type &; + using base_type = Type; + + template>> + constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v) + : base_type{} {} + + template>, compressed_pair_element>>> + constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v) + : base_type{std::forward(arg)} {} + + template + constexpr compressed_pair_element(std::tuple args, std::index_sequence) noexcept(std::is_nothrow_constructible_v) + : base_type{std::forward(std::get(args))...} {} + + [[nodiscard]] constexpr reference get() noexcept { + return *this; + } + + [[nodiscard]] constexpr const_reference get() const noexcept { + return *this; + } +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief A compressed pair. + * + * A pair that exploits the _Empty Base Class Optimization_ (or _EBCO_) to + * reduce its final size to a minimum. + * + * @tparam First The type of the first element that the pair stores. + * @tparam Second The type of the second element that the pair stores. + */ +template +class compressed_pair final + : internal::compressed_pair_element, + internal::compressed_pair_element { + using first_base = internal::compressed_pair_element; + using second_base = internal::compressed_pair_element; + +public: + /*! @brief The type of the first element that the pair stores. */ + using first_type = First; + /*! @brief The type of the second element that the pair stores. */ + using second_type = Second; + + /** + * @brief Default constructor, conditionally enabled. + * + * This constructor is only available when the types that the pair stores + * are both at least default constructible. + * + * @tparam Dummy Dummy template parameter used for internal purposes. + */ + template && std::is_default_constructible_v>> + constexpr compressed_pair() noexcept(std::is_nothrow_default_constructible_v && std::is_nothrow_default_constructible_v) + : first_base{}, + second_base{} {} + + /** + * @brief Copy constructor. + * @param other The instance to copy from. + */ + constexpr compressed_pair(const compressed_pair &other) = default; + + /** + * @brief Move constructor. + * @param other The instance to move from. + */ + constexpr compressed_pair(compressed_pair &&other) noexcept = default; + + /** + * @brief Constructs a pair from its values. + * @tparam Arg Type of value to use to initialize the first element. + * @tparam Other Type of value to use to initialize the second element. + * @param arg Value to use to initialize the first element. + * @param other Value to use to initialize the second element. + */ + template + constexpr compressed_pair(Arg &&arg, Other &&other) noexcept(std::is_nothrow_constructible_v && std::is_nothrow_constructible_v) + : first_base{std::forward(arg)}, + second_base{std::forward(other)} {} + + /** + * @brief Constructs a pair by forwarding the arguments to its parts. + * @tparam Args Types of arguments to use to initialize the first element. + * @tparam Other Types of arguments to use to initialize the second element. + * @param args Arguments to use to initialize the first element. + * @param other Arguments to use to initialize the second element. + */ + template + constexpr compressed_pair(std::piecewise_construct_t, std::tuple args, std::tuple other) noexcept(std::is_nothrow_constructible_v && std::is_nothrow_constructible_v) + : first_base{std::move(args), std::index_sequence_for{}}, + second_base{std::move(other), std::index_sequence_for{}} {} + + /*! @brief Default destructor. */ + ~compressed_pair() = default; + + /** + * @brief Copy assignment operator. + * @param other The instance to copy from. + * @return This compressed pair object. + */ + constexpr compressed_pair &operator=(const compressed_pair &other) = default; + + /** + * @brief Move assignment operator. + * @param other The instance to move from. + * @return This compressed pair object. + */ + constexpr compressed_pair &operator=(compressed_pair &&other) noexcept = default; + + /** + * @brief Returns the first element that a pair stores. + * @return The first element that a pair stores. + */ + [[nodiscard]] constexpr first_type &first() noexcept { + return static_cast(*this).get(); + } + + /*! @copydoc first */ + [[nodiscard]] constexpr const first_type &first() const noexcept { + return static_cast(*this).get(); + } + + /** + * @brief Returns the second element that a pair stores. + * @return The second element that a pair stores. + */ + [[nodiscard]] constexpr second_type &second() noexcept { + return static_cast(*this).get(); + } + + /*! @copydoc second */ + [[nodiscard]] constexpr const second_type &second() const noexcept { + return static_cast(*this).get(); + } + + /** + * @brief Swaps two compressed pair objects. + * @param other The compressed pair to swap with. + */ + constexpr void swap(compressed_pair &other) noexcept { + using std::swap; + swap(first(), other.first()); + swap(second(), other.second()); + } + + /** + * @brief Extracts an element from the compressed pair. + * @tparam Index An integer value that is either 0 or 1. + * @return Returns a reference to the first element if `Index` is 0 and a + * reference to the second element if `Index` is 1. + */ + template + [[nodiscard]] constexpr decltype(auto) get() noexcept { + if constexpr(Index == 0u) { + return first(); + } else { + static_assert(Index == 1u, "Index out of bounds"); + return second(); + } + } + + /*! @copydoc get */ + template + [[nodiscard]] constexpr decltype(auto) get() const noexcept { + if constexpr(Index == 0u) { + return first(); + } else { + static_assert(Index == 1u, "Index out of bounds"); + return second(); + } + } +}; + +/** + * @brief Deduction guide. + * @tparam Type Type of value to use to initialize the first element. + * @tparam Other Type of value to use to initialize the second element. + */ +template +compressed_pair(Type &&, Other &&) -> compressed_pair, std::decay_t>; + +/** + * @brief Swaps two compressed pair objects. + * @tparam First The type of the first element that the pairs store. + * @tparam Second The type of the second element that the pairs store. + * @param lhs A valid compressed pair object. + * @param rhs A valid compressed pair object. + */ +template +constexpr void swap(compressed_pair &lhs, compressed_pair &rhs) noexcept { + lhs.swap(rhs); +} + +} // namespace entt + +namespace std { + +/** + * @brief `std::tuple_size` specialization for `compressed_pair`s. + * @tparam First The type of the first element that the pair stores. + * @tparam Second The type of the second element that the pair stores. + */ +template +struct tuple_size>: integral_constant {}; + +/** + * @brief `std::tuple_element` specialization for `compressed_pair`s. + * @tparam Index The index of the type to return. + * @tparam First The type of the first element that the pair stores. + * @tparam Second The type of the second element that the pair stores. + */ +template +struct tuple_element>: conditional { + static_assert(Index < 2u, "Index out of bounds"); +}; + +} // namespace std + +#endif + +// #include "../core/iterator.hpp" +#ifndef ENTT_CORE_ITERATOR_HPP +#define ENTT_CORE_ITERATOR_HPP + +#include +#include +#include +#include + +namespace entt { + +/** + * @brief Helper type to use as pointer with input iterators. + * @tparam Type of wrapped value. + */ +template +struct input_iterator_pointer final { + /*! @brief Value type. */ + using value_type = Type; + /*! @brief Pointer type. */ + using pointer = Type *; + /*! @brief Reference type. */ + using reference = Type &; + + /** + * @brief Constructs a proxy object by move. + * @param val Value to use to initialize the proxy object. + */ + constexpr input_iterator_pointer(value_type &&val) noexcept(std::is_nothrow_move_constructible_v) + : value{std::move(val)} {} + + /** + * @brief Access operator for accessing wrapped values. + * @return A pointer to the wrapped value. + */ + [[nodiscard]] constexpr pointer operator->() noexcept { + return std::addressof(value); + } + + /** + * @brief Dereference operator for accessing wrapped values. + * @return A reference to the wrapped value. + */ + [[nodiscard]] constexpr reference operator*() noexcept { + return value; + } + +private: + Type value; +}; + +/** + * @brief Plain iota iterator (waiting for C++20). + * @tparam Type Value type. + */ +template +class iota_iterator final { + static_assert(std::is_integral_v, "Not an integral type"); + +public: + /*! @brief Value type, likely an integral one. */ + using value_type = Type; + /*! @brief Invalid pointer type. */ + using pointer = void; + /*! @brief Non-reference type, same as value type. */ + using reference = value_type; + /*! @brief Difference type. */ + using difference_type = std::ptrdiff_t; + /*! @brief Iterator category. */ + using iterator_category = std::input_iterator_tag; + + /*! @brief Default constructor. */ + constexpr iota_iterator() noexcept + : current{} {} + + /** + * @brief Constructs an iota iterator from a given value. + * @param init The initial value assigned to the iota iterator. + */ + constexpr iota_iterator(const value_type init) noexcept + : current{init} {} + + /** + * @brief Pre-increment operator. + * @return This iota iterator. + */ + constexpr iota_iterator &operator++() noexcept { + return ++current, *this; + } + + /** + * @brief Post-increment operator. + * @return This iota iterator. + */ + constexpr iota_iterator operator++(int) noexcept { + const iota_iterator orig = *this; + return ++(*this), orig; + } + + /** + * @brief Dereference operator. + * @return The underlying value. + */ + [[nodiscard]] constexpr reference operator*() const noexcept { + return current; + } + +private: + value_type current; +}; + +/** + * @brief Comparison operator. + * @tparam Type Value type of the iota iterator. + * @param lhs A properly initialized iota iterator. + * @param rhs A properly initialized iota iterator. + * @return True if the two iterators are identical, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator==(const iota_iterator &lhs, const iota_iterator &rhs) noexcept { + return *lhs == *rhs; +} + +/** + * @brief Comparison operator. + * @tparam Type Value type of the iota iterator. + * @param lhs A properly initialized iota iterator. + * @param rhs A properly initialized iota iterator. + * @return True if the two iterators differ, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator!=(const iota_iterator &lhs, const iota_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +/** + * @brief Utility class to create an iterable object from a pair of iterators. + * @tparam It Type of iterator. + * @tparam Sentinel Type of sentinel. + */ +template +struct iterable_adaptor final { + /*! @brief Value type. */ + using value_type = typename std::iterator_traits::value_type; + /*! @brief Iterator type. */ + using iterator = It; + /*! @brief Sentinel type. */ + using sentinel = Sentinel; + + /*! @brief Default constructor. */ + constexpr iterable_adaptor() noexcept(std::is_nothrow_default_constructible_v && std::is_nothrow_default_constructible_v) + : first{}, + last{} {} + + /** + * @brief Creates an iterable object from a pair of iterators. + * @param from Begin iterator. + * @param to End iterator. + */ + constexpr iterable_adaptor(iterator from, sentinel to) noexcept(std::is_nothrow_move_constructible_v && std::is_nothrow_move_constructible_v) + : first{std::move(from)}, + last{std::move(to)} {} + + /** + * @brief Returns an iterator to the beginning. + * @return An iterator to the first element of the range. + */ + [[nodiscard]] constexpr iterator begin() const noexcept { + return first; + } + + /** + * @brief Returns an iterator to the end. + * @return An iterator to the element following the last element of the + * range. + */ + [[nodiscard]] constexpr sentinel end() const noexcept { + return last; + } + + /*! @copydoc begin */ + [[nodiscard]] constexpr iterator cbegin() const noexcept { + return begin(); + } + + /*! @copydoc end */ + [[nodiscard]] constexpr sentinel cend() const noexcept { + return end(); + } + +private: + It first; + Sentinel last; +}; + +} // namespace entt + +#endif + +// #include "../core/memory.hpp" +#ifndef ENTT_CORE_MEMORY_HPP +#define ENTT_CORE_MEMORY_HPP + +#include +#include +#include +#include +#include +// #include "../config/config.h" + + +namespace entt { + +/** + * @brief Unwraps fancy pointers, does nothing otherwise (waiting for C++20). + * @tparam Type Pointer type. + * @param ptr Fancy or raw pointer. + * @return A raw pointer that represents the address of the original pointer. + */ +template +[[nodiscard]] constexpr auto to_address(Type &&ptr) noexcept { + if constexpr(std::is_pointer_v>) { + return ptr; + } else { + return to_address(std::forward(ptr).operator->()); + } +} + +/** + * @brief Utility function to design allocation-aware containers. + * @tparam Allocator Type of allocator. + * @param lhs A valid allocator. + * @param rhs Another valid allocator. + */ +template +constexpr void propagate_on_container_copy_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept { + if constexpr(std::allocator_traits::propagate_on_container_copy_assignment::value) { + lhs = rhs; + } +} + +/** + * @brief Utility function to design allocation-aware containers. + * @tparam Allocator Type of allocator. + * @param lhs A valid allocator. + * @param rhs Another valid allocator. + */ +template +constexpr void propagate_on_container_move_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept { + if constexpr(std::allocator_traits::propagate_on_container_move_assignment::value) { + lhs = std::move(rhs); + } +} + +/** + * @brief Utility function to design allocation-aware containers. + * @tparam Allocator Type of allocator. + * @param lhs A valid allocator. + * @param rhs Another valid allocator. + */ +template +constexpr void propagate_on_container_swap([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept { + if constexpr(std::allocator_traits::propagate_on_container_swap::value) { + using std::swap; + swap(lhs, rhs); + } else { + ENTT_ASSERT_CONSTEXPR(lhs == rhs, "Cannot swap the containers"); + } +} + +/** + * @brief Deleter for allocator-aware unique pointers (waiting for C++20). + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +struct allocation_deleter: private Allocator { + /*! @brief Allocator type. */ + using allocator_type = Allocator; + /*! @brief Pointer type. */ + using pointer = typename std::allocator_traits::pointer; + + /** + * @brief Inherited constructors. + * @param alloc The allocator to use. + */ + constexpr allocation_deleter(const allocator_type &alloc) noexcept(std::is_nothrow_copy_constructible_v) + : Allocator{alloc} {} + + /** + * @brief Destroys the pointed object and deallocates its memory. + * @param ptr A valid pointer to an object of the given type. + */ + constexpr void operator()(pointer ptr) noexcept(std::is_nothrow_destructible_v) { + using alloc_traits = std::allocator_traits; + alloc_traits::destroy(*this, to_address(ptr)); + alloc_traits::deallocate(*this, ptr, 1u); + } +}; + +/** + * @brief Allows `std::unique_ptr` to use allocators (waiting for C++20). + * @tparam Type Type of object to allocate for and to construct. + * @tparam Allocator Type of allocator used to manage memory and elements. + * @tparam Args Types of arguments to use to construct the object. + * @param allocator The allocator to use. + * @param args Parameters to use to construct the object. + * @return A properly initialized unique pointer with a custom deleter. + */ +template +ENTT_CONSTEXPR auto allocate_unique(Allocator &allocator, Args &&...args) { + static_assert(!std::is_array_v, "Array types are not supported"); + + using alloc_traits = typename std::allocator_traits::template rebind_traits; + using allocator_type = typename alloc_traits::allocator_type; + + allocator_type alloc{allocator}; + auto ptr = alloc_traits::allocate(alloc, 1u); + + ENTT_TRY { + alloc_traits::construct(alloc, to_address(ptr), std::forward(args)...); + } + ENTT_CATCH { + alloc_traits::deallocate(alloc, ptr, 1u); + ENTT_THROW; + } + + return std::unique_ptr>{ptr, alloc}; +} + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct uses_allocator_construction { + template + static constexpr auto args([[maybe_unused]] const Allocator &allocator, Params &&...params) noexcept { + if constexpr(!std::uses_allocator_v && std::is_constructible_v) { + return std::forward_as_tuple(std::forward(params)...); + } else { + static_assert(std::uses_allocator_v, "Ill-formed request"); + + if constexpr(std::is_constructible_v) { + return std::tuple{std::allocator_arg, allocator, std::forward(params)...}; + } else { + static_assert(std::is_constructible_v, "Ill-formed request"); + return std::forward_as_tuple(std::forward(params)..., allocator); + } + } + } +}; + +template +struct uses_allocator_construction> { + using type = std::pair; + + template + static constexpr auto args(const Allocator &allocator, std::piecewise_construct_t, First &&first, Second &&second) noexcept { + return std::make_tuple( + std::piecewise_construct, + std::apply([&allocator](auto &&...curr) { return uses_allocator_construction::args(allocator, std::forward(curr)...); }, std::forward(first)), + std::apply([&allocator](auto &&...curr) { return uses_allocator_construction::args(allocator, std::forward(curr)...); }, std::forward(second))); + } + + template + static constexpr auto args(const Allocator &allocator) noexcept { + return uses_allocator_construction::args(allocator, std::piecewise_construct, std::tuple<>{}, std::tuple<>{}); + } + + template + static constexpr auto args(const Allocator &allocator, First &&first, Second &&second) noexcept { + return uses_allocator_construction::args(allocator, std::piecewise_construct, std::forward_as_tuple(std::forward(first)), std::forward_as_tuple(std::forward(second))); + } + + template + static constexpr auto args(const Allocator &allocator, const std::pair &value) noexcept { + return uses_allocator_construction::args(allocator, std::piecewise_construct, std::forward_as_tuple(value.first), std::forward_as_tuple(value.second)); + } + + template + static constexpr auto args(const Allocator &allocator, std::pair &&value) noexcept { + return uses_allocator_construction::args(allocator, std::piecewise_construct, std::forward_as_tuple(std::move(value.first)), std::forward_as_tuple(std::move(value.second))); + } +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Uses-allocator construction utility (waiting for C++20). + * + * Primarily intended for internal use. Prepares the argument list needed to + * create an object of a given type by means of uses-allocator construction. + * + * @tparam Type Type to return arguments for. + * @tparam Allocator Type of allocator used to manage memory and elements. + * @tparam Args Types of arguments to use to construct the object. + * @param allocator The allocator to use. + * @param args Parameters to use to construct the object. + * @return The arguments needed to create an object of the given type. + */ +template +constexpr auto uses_allocator_construction_args(const Allocator &allocator, Args &&...args) noexcept { + return internal::uses_allocator_construction::args(allocator, std::forward(args)...); +} + +/** + * @brief Uses-allocator construction utility (waiting for C++20). + * + * Primarily intended for internal use. Creates an object of a given type by + * means of uses-allocator construction. + * + * @tparam Type Type of object to create. + * @tparam Allocator Type of allocator used to manage memory and elements. + * @tparam Args Types of arguments to use to construct the object. + * @param allocator The allocator to use. + * @param args Parameters to use to construct the object. + * @return A newly created object of the given type. + */ +template +constexpr Type make_obj_using_allocator(const Allocator &allocator, Args &&...args) { + return std::make_from_tuple(internal::uses_allocator_construction::args(allocator, std::forward(args)...)); +} + +/** + * @brief Uses-allocator construction utility (waiting for C++20). + * + * Primarily intended for internal use. Creates an object of a given type by + * means of uses-allocator construction at an uninitialized memory location. + * + * @tparam Type Type of object to create. + * @tparam Allocator Type of allocator used to manage memory and elements. + * @tparam Args Types of arguments to use to construct the object. + * @param value Memory location in which to place the object. + * @param allocator The allocator to use. + * @param args Parameters to use to construct the object. + * @return A pointer to the newly created object of the given type. + */ +template +constexpr Type *uninitialized_construct_using_allocator(Type *value, const Allocator &allocator, Args &&...args) { + return std::apply([value](auto &&...curr) { return ::new(value) Type(std::forward(curr)...); }, internal::uses_allocator_construction::args(allocator, std::forward(args)...)); +} + +} // namespace entt + +#endif + +// #include "../core/type_traits.hpp" +#ifndef ENTT_CORE_TYPE_TRAITS_HPP +#define ENTT_CORE_TYPE_TRAITS_HPP + +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "fwd.hpp" + + +namespace entt { + +/** + * @brief Utility class to disambiguate overloaded functions. + * @tparam N Number of choices available. + */ +template +struct choice_t + // unfortunately, doxygen cannot parse such a construct + : /*! @cond TURN_OFF_DOXYGEN */ choice_t /*! @endcond */ +{}; + +/*! @copybrief choice_t */ +template<> +struct choice_t<0> {}; + +/** + * @brief Variable template for the choice trick. + * @tparam N Number of choices available. + */ +template +inline constexpr choice_t choice{}; + +/** + * @brief Identity type trait. + * + * Useful to establish non-deduced contexts in template argument deduction + * (waiting for C++20) or to provide types through function arguments. + * + * @tparam Type A type. + */ +template +struct type_identity { + /*! @brief Identity type. */ + using type = Type; +}; + +/** + * @brief Helper type. + * @tparam Type A type. + */ +template +using type_identity_t = typename type_identity::type; + +/** + * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains. + * @tparam Type The type of which to return the size. + */ +template +struct size_of: std::integral_constant {}; + +/*! @copydoc size_of */ +template +struct size_of> + // NOLINTNEXTLINE(bugprone-sizeof-expression) + : std::integral_constant {}; + +/** + * @brief Helper variable template. + * @tparam Type The type of which to return the size. + */ +template +inline constexpr std::size_t size_of_v = size_of::value; + +/** + * @brief Using declaration to be used to _repeat_ the same type a number of + * times equal to the size of a given parameter pack. + * @tparam Type A type to repeat. + */ +template +using unpack_as_type = Type; + +/** + * @brief Helper variable template to be used to _repeat_ the same value a + * number of times equal to the size of a given parameter pack. + * @tparam Value A value to repeat. + */ +template +inline constexpr auto unpack_as_value = Value; + +/** + * @brief Wraps a static constant. + * @tparam Value A static constant. + */ +template +using integral_constant = std::integral_constant; + +/** + * @brief Alias template to facilitate the creation of named values. + * @tparam Value A constant value at least convertible to `id_type`. + */ +template +using tag = integral_constant; + +/** + * @brief A class to use to push around lists of types, nothing more. + * @tparam Type Types provided by the type list. + */ +template +struct type_list { + /*! @brief Type list type. */ + using type = type_list; + /*! @brief Compile-time number of elements in the type list. */ + static constexpr auto size = sizeof...(Type); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_element; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Index Index of the type to return. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element> + : type_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element<0u, type_list> { + /*! @brief Searched type. */ + using type = First; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Type list to search into. + */ +template +using type_list_element_t = typename type_list_element::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_index; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 1u + type_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + static_assert(type_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +inline constexpr std::size_t type_list_index_v = type_list_index::value; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @return A type list composed by the types of both the type lists. + */ +template +constexpr type_list operator+(type_list, type_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_cat; + +/*! @brief Concatenates multiple type lists. */ +template<> +struct type_list_cat<> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list<>; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @tparam List Other type lists, if any. + */ +template +struct type_list_cat, type_list, List...> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = typename type_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the type list. + */ +template +struct type_list_cat> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list; +}; + +/** + * @brief Helper type. + * @tparam List Type lists to concatenate. + */ +template +using type_list_cat_t = typename type_list_cat::type; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct type_list_unique; + +template +struct type_list_unique, Type...> + : std::conditional_t<(std::is_same_v || ...), type_list_unique, Type...>, type_list_unique, Type..., First>> {}; + +template +struct type_list_unique, Type...> { + using type = type_list; +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Removes duplicates types from a type list. + * @tparam List Type list. + */ +template +struct type_list_unique { + /*! @brief A type list without duplicate types. */ + using type = typename internal::type_list_unique::type; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + */ +template +using type_list_unique_t = typename type_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a type list contains a + * given type, false otherwise. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +struct type_list_contains; + +/** + * @copybrief type_list_contains + * @tparam Type Types provided by the type list. + * @tparam Other Type to look for. + */ +template +struct type_list_contains, Other> + : std::bool_constant<(std::is_same_v || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +inline constexpr bool type_list_contains_v = type_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_diff; + +/** + * @brief Computes the difference between two type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + */ +template +struct type_list_diff, type_list> { + /*! @brief A type list that is the difference between the two type lists. */ + using type = type_list_cat_t, Type>, type_list<>, type_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Type lists between which to compute the difference. + */ +template +using type_list_diff_t = typename type_list_diff::type; + +/*! @brief Primary template isn't defined on purpose. */ +template class> +struct type_list_transform; + +/** + * @brief Applies a given _function_ to a type list and generate a new list. + * @tparam Type Types provided by the type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +struct type_list_transform, Op> { + /*! @brief Resulting type list after applying the transform function. */ + // NOLINTNEXTLINE(modernize-type-traits) + using type = type_list::type...>; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +using type_list_transform_t = typename type_list_transform::type; + +/** + * @brief A class to use to push around lists of constant values, nothing more. + * @tparam Value Values provided by the value list. + */ +template +struct value_list { + /*! @brief Value list type. */ + using type = value_list; + /*! @brief Compile-time number of elements in the value list. */ + static constexpr auto size = sizeof...(Value); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_element; + +/** + * @brief Provides compile-time indexed access to the values of a value list. + * @tparam Index Index of the value to return. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element> + : value_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element<0u, value_list> { + /*! @brief Searched type. */ + using type = decltype(Value); + /*! @brief Searched value. */ + static constexpr auto value = Value; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Value list to search into. + */ +template +using value_list_element_t = typename value_list_element::type; + +/** + * @brief Helper type. + * @tparam Index Index of the value to return. + * @tparam List Value list to search into. + */ +template +inline constexpr auto value_list_element_v = value_list_element::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_index; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam First First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 1u + value_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + static_assert(value_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +inline constexpr std::size_t value_list_index_v = value_list_index::value; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @return A value list composed by the values of both the value lists. + */ +template +constexpr value_list operator+(value_list, value_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_cat; + +/*! @brief Concatenates multiple value lists. */ +template<> +struct value_list_cat<> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list<>; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @tparam List Other value lists, if any. + */ +template +struct value_list_cat, value_list, List...> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = typename value_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the value list. + */ +template +struct value_list_cat> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list; +}; + +/** + * @brief Helper type. + * @tparam List Value lists to concatenate. + */ +template +using value_list_cat_t = typename value_list_cat::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_unique; + +/** + * @brief Removes duplicates values from a value list. + * @tparam Value One of the values provided by the given value list. + * @tparam Other The other values provided by the given value list. + */ +template +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = std::conditional_t< + ((Value == Other) || ...), + typename value_list_unique>::type, + value_list_cat_t, typename value_list_unique>::type>>; +}; + +/*! @brief Removes duplicates values from a value list. */ +template<> +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = value_list<>; +}; + +/** + * @brief Helper type. + * @tparam Type A value list. + */ +template +using value_list_unique_t = typename value_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a value list contains + * a given value, false otherwise. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +struct value_list_contains; + +/** + * @copybrief value_list_contains + * @tparam Value Values provided by the value list. + * @tparam Other Value to look for. + */ +template +struct value_list_contains, Other> + : std::bool_constant<((Value == Other) || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +inline constexpr bool value_list_contains_v = value_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_diff; + +/** + * @brief Computes the difference between two value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + */ +template +struct value_list_diff, value_list> { + /*! @brief A value list that is the difference between the two value lists. */ + using type = value_list_cat_t, Value>, value_list<>, value_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Value lists between which to compute the difference. + */ +template +using value_list_diff_t = typename value_list_diff::type; + +/*! @brief Same as std::is_invocable, but with tuples. */ +template +struct is_applicable: std::false_type {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @brief Helper variable template. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_v = is_applicable::value; + +/*! @brief Same as std::is_invocable_r, but with tuples for arguments. */ +template +struct is_applicable_r: std::false_type {}; + +/** + * @copybrief is_applicable_r + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +struct is_applicable_r>: std::is_invocable_r {}; + +/** + * @brief Helper variable template. + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_r_v = is_applicable_r::value; + +/** + * @brief Provides the member constant `value` to true if a given type is + * complete, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_complete: std::false_type {}; + +/*! @copydoc is_complete */ +template +struct is_complete>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_complete_v = is_complete::value; + +/** + * @brief Provides the member constant `value` to true if a given type is an + * iterator, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_iterator: std::false_type {}; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_iterator_category: std::false_type {}; + +template +struct has_iterator_category::iterator_category>>: std::true_type {}; + +} // namespace internal +/*! @endcond */ + +/*! @copydoc is_iterator */ +template +struct is_iterator>>>> + : internal::has_iterator_category {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_iterator_v = is_iterator::value; + +/** + * @brief Provides the member constant `value` to true if a given type is both + * an empty and non-final class, false otherwise. + * @tparam Type The type to test + */ +template +struct is_ebco_eligible + : std::bool_constant && !std::is_final_v> {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_ebco_eligible_v = is_ebco_eligible::value; + +/** + * @brief Provides the member constant `value` to true if `Type::is_transparent` + * is valid and denotes a type, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_transparent: std::false_type {}; + +/*! @copydoc is_transparent */ +template +struct is_transparent>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_transparent_v = is_transparent::value; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_tuple_size_value: std::false_type {}; + +template +struct has_tuple_size_value::value)>>: std::true_type {}; + +template +struct has_value_type: std::false_type {}; + +template +struct has_value_type>: std::true_type {}; + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable(); + +template +[[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence) { + return (dispatch_is_equality_comparable>() && ...); +} + +template +[[nodiscard]] constexpr bool maybe_equality_comparable(char) { + return false; +} + +template +[[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval() == std::declval()) { + return true; +} + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable() { + // NOLINTBEGIN(modernize-use-transparent-functors) + if constexpr(std::is_array_v) { + return false; + } else if constexpr(is_complete_v>>) { + if constexpr(has_tuple_size_value::value) { + return maybe_equality_comparable(0) && unpack_maybe_equality_comparable(std::make_index_sequence::value>{}); + } else { + return maybe_equality_comparable(0); + } + } else if constexpr(has_value_type::value) { + if constexpr(is_iterator_v || std::is_same_v || dispatch_is_equality_comparable()) { + return maybe_equality_comparable(0); + } else { + return false; + } + } else { + return maybe_equality_comparable(0); + } + // NOLINTEND(modernize-use-transparent-functors) +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Provides the member constant `value` to true if a given type is + * equality comparable, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_equality_comparable: std::bool_constant()> {}; + +/*! @copydoc is_equality_comparable */ +template +struct is_equality_comparable: is_equality_comparable {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_equality_comparable_v = is_equality_comparable::value; + +/** + * @brief Transcribes the constness of a type to another type. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = std::remove_const_t; +}; + +/*! @copydoc constness_as */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = const To; +}; + +/** + * @brief Alias template to facilitate the transcription of the constness. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +using constness_as_t = typename constness_as::type; + +/** + * @brief Extracts the class of a non-static member object or function. + * @tparam Member A pointer to a non-static member object or function. + */ +template +class member_class { + static_assert(std::is_member_pointer_v, "Invalid pointer type to non-static member object or function"); + + template + static Class *clazz(Ret (Class::*)(Args...)); + + template + static Class *clazz(Ret (Class::*)(Args...) const); + + template + static Class *clazz(Type Class::*); + +public: + /*! @brief The class of the given non-static member object or function. */ + using type = std::remove_pointer_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Member A pointer to a non-static member object or function. + */ +template +using member_class_t = typename member_class::type; + +/** + * @brief Extracts the n-th argument of a _callable_ type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid _callable_ type. + */ +template +class nth_argument { + template + static constexpr type_list pick_up(Ret (*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...) const); + + template + static constexpr type_list pick_up(Type Class ::*); + + template + static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&); + +public: + /*! @brief N-th argument of the _callable_ type. */ + using type = type_list_element_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid function, member function or data member type. + */ +template +using nth_argument_t = typename nth_argument::type; + +} // namespace entt + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::type_list_element> {}; + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::value_list_element> {}; + +#endif + +// #include "fwd.hpp" +#ifndef ENTT_CONTAINER_FWD_HPP +#define ENTT_CONTAINER_FWD_HPP + +#include +#include +#include +#include + +namespace entt { + +template< + typename Key, + typename Type, + typename = std::hash, + typename = std::equal_to<>, + typename = std::allocator>> +class dense_map; + +template< + typename Type, + typename = std::hash, + typename = std::equal_to<>, + typename = std::allocator> +class dense_set; + +template +class basic_table; + +/** + * @brief Alias declaration for the most common use case. + * @tparam Type Element types. + */ +template +using table = basic_table...>; + +} // namespace entt + +#endif + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +static constexpr std::size_t dense_map_placeholder_position = (std::numeric_limits::max)(); + +template +struct dense_map_node final { + using value_type = std::pair; + + template + dense_map_node(const std::size_t pos, Args &&...args) + : next{pos}, + element{std::forward(args)...} {} + + template + dense_map_node(std::allocator_arg_t, const Allocator &allocator, const std::size_t pos, Args &&...args) + : next{pos}, + element{entt::make_obj_using_allocator(allocator, std::forward(args)...)} {} + + template + dense_map_node(std::allocator_arg_t, const Allocator &allocator, const dense_map_node &other) + : next{other.next}, + element{entt::make_obj_using_allocator(allocator, other.element)} {} + + template + dense_map_node(std::allocator_arg_t, const Allocator &allocator, dense_map_node &&other) + : next{other.next}, + element{entt::make_obj_using_allocator(allocator, std::move(other.element))} {} + + std::size_t next; + value_type element; +}; + +template +class dense_map_iterator final { + template + friend class dense_map_iterator; + + using first_type = decltype(std::as_const(std::declval()->element.first)); + using second_type = decltype((std::declval()->element.second)); + +public: + using value_type = std::pair; + using pointer = input_iterator_pointer; + using reference = value_type; + using difference_type = std::ptrdiff_t; + using iterator_category = std::input_iterator_tag; + using iterator_concept = std::random_access_iterator_tag; + + constexpr dense_map_iterator() noexcept + : it{} {} + + constexpr dense_map_iterator(const It iter) noexcept + : it{iter} {} + + template && std::is_constructible_v>> + constexpr dense_map_iterator(const dense_map_iterator &other) noexcept + : it{other.it} {} + + constexpr dense_map_iterator &operator++() noexcept { + return ++it, *this; + } + + constexpr dense_map_iterator operator++(int) noexcept { + const dense_map_iterator orig = *this; + return ++(*this), orig; + } + + constexpr dense_map_iterator &operator--() noexcept { + return --it, *this; + } + + constexpr dense_map_iterator operator--(int) noexcept { + const dense_map_iterator orig = *this; + return operator--(), orig; + } + + constexpr dense_map_iterator &operator+=(const difference_type value) noexcept { + it += value; + return *this; + } + + constexpr dense_map_iterator operator+(const difference_type value) const noexcept { + dense_map_iterator copy = *this; + return (copy += value); + } + + constexpr dense_map_iterator &operator-=(const difference_type value) noexcept { + return (*this += -value); + } + + constexpr dense_map_iterator operator-(const difference_type value) const noexcept { + return (*this + -value); + } + + [[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept { + return {it[value].element.first, it[value].element.second}; + } + + [[nodiscard]] constexpr pointer operator->() const noexcept { + return operator*(); + } + + [[nodiscard]] constexpr reference operator*() const noexcept { + return operator[](0); + } + + template + friend constexpr std::ptrdiff_t operator-(const dense_map_iterator &, const dense_map_iterator &) noexcept; + + template + friend constexpr bool operator==(const dense_map_iterator &, const dense_map_iterator &) noexcept; + + template + friend constexpr bool operator<(const dense_map_iterator &, const dense_map_iterator &) noexcept; + +private: + It it; +}; + +template +[[nodiscard]] constexpr std::ptrdiff_t operator-(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return lhs.it - rhs.it; +} + +template +[[nodiscard]] constexpr bool operator==(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return lhs.it == rhs.it; +} + +template +[[nodiscard]] constexpr bool operator!=(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +template +[[nodiscard]] constexpr bool operator<(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return lhs.it < rhs.it; +} + +template +[[nodiscard]] constexpr bool operator>(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return rhs < lhs; +} + +template +[[nodiscard]] constexpr bool operator<=(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return !(lhs > rhs); +} + +template +[[nodiscard]] constexpr bool operator>=(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return !(lhs < rhs); +} + +template +class dense_map_local_iterator final { + template + friend class dense_map_local_iterator; + + using first_type = decltype(std::as_const(std::declval()->element.first)); + using second_type = decltype((std::declval()->element.second)); + +public: + using value_type = std::pair; + using pointer = input_iterator_pointer; + using reference = value_type; + using difference_type = std::ptrdiff_t; + using iterator_category = std::input_iterator_tag; + using iterator_concept = std::forward_iterator_tag; + + constexpr dense_map_local_iterator() noexcept = default; + + constexpr dense_map_local_iterator(It iter, const std::size_t pos) noexcept + : it{iter}, + offset{pos} {} + + template && std::is_constructible_v>> + constexpr dense_map_local_iterator(const dense_map_local_iterator &other) noexcept + : it{other.it}, + offset{other.offset} {} + + constexpr dense_map_local_iterator &operator++() noexcept { + return (offset = it[static_cast(offset)].next), *this; + } + + constexpr dense_map_local_iterator operator++(int) noexcept { + const dense_map_local_iterator orig = *this; + return ++(*this), orig; + } + + [[nodiscard]] constexpr pointer operator->() const noexcept { + return operator*(); + } + + [[nodiscard]] constexpr reference operator*() const noexcept { + const auto idx = static_cast(offset); + return {it[idx].element.first, it[idx].element.second}; + } + + [[nodiscard]] constexpr std::size_t index() const noexcept { + return offset; + } + +private: + It it{}; + std::size_t offset{dense_map_placeholder_position}; +}; + +template +[[nodiscard]] constexpr bool operator==(const dense_map_local_iterator &lhs, const dense_map_local_iterator &rhs) noexcept { + return lhs.index() == rhs.index(); +} + +template +[[nodiscard]] constexpr bool operator!=(const dense_map_local_iterator &lhs, const dense_map_local_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Associative container for key-value pairs with unique keys. + * + * Internally, elements are organized into buckets. Which bucket an element is + * placed into depends entirely on the hash of its key. Keys with the same hash + * code appear in the same bucket. + * + * @tparam Key Key type of the associative container. + * @tparam Type Mapped type of the associative container. + * @tparam Hash Type of function to use to hash the keys. + * @tparam KeyEqual Type of function to use to compare the keys for equality. + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +class dense_map { + static constexpr float default_threshold = 0.875f; + static constexpr std::size_t minimum_capacity = 8u; + static constexpr std::size_t placeholder_position = internal::dense_map_placeholder_position; + + using node_type = internal::dense_map_node; + using alloc_traits = std::allocator_traits; + static_assert(std::is_same_v>, "Invalid value type"); + using sparse_container_type = std::vector>; + using packed_container_type = std::vector>; + + template + [[nodiscard]] std::size_t key_to_bucket(const Other &key) const noexcept { + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay) + return fast_mod(static_cast(sparse.second()(key)), bucket_count()); + } + + template + [[nodiscard]] auto constrained_find(const Other &key, const std::size_t bucket) { + for(auto offset = sparse.first()[bucket]; offset != placeholder_position; offset = packed.first()[offset].next) { + if(packed.second()(packed.first()[offset].element.first, key)) { + return begin() + static_cast(offset); + } + } + + return end(); + } + + template + [[nodiscard]] auto constrained_find(const Other &key, const std::size_t bucket) const { + for(auto offset = sparse.first()[bucket]; offset != placeholder_position; offset = packed.first()[offset].next) { + if(packed.second()(packed.first()[offset].element.first, key)) { + return cbegin() + static_cast(offset); + } + } + + return cend(); + } + + template + [[nodiscard]] auto insert_or_do_nothing(Other &&key, Args &&...args) { + const auto index = key_to_bucket(key); + + if(auto it = constrained_find(key, index); it != end()) { + return std::make_pair(it, false); + } + + packed.first().emplace_back(sparse.first()[index], std::piecewise_construct, std::forward_as_tuple(std::forward(key)), std::forward_as_tuple(std::forward(args)...)); + sparse.first()[index] = packed.first().size() - 1u; + rehash_if_required(); + + return std::make_pair(--end(), true); + } + + template + [[nodiscard]] auto insert_or_overwrite(Other &&key, Arg &&value) { + const auto index = key_to_bucket(key); + + if(auto it = constrained_find(key, index); it != end()) { + it->second = std::forward(value); + return std::make_pair(it, false); + } + + packed.first().emplace_back(sparse.first()[index], std::forward(key), std::forward(value)); + sparse.first()[index] = packed.first().size() - 1u; + rehash_if_required(); + + return std::make_pair(--end(), true); + } + + void move_and_pop(const std::size_t pos) { + if(const auto last = size() - 1u; pos != last) { + size_type *curr = &sparse.first()[key_to_bucket(packed.first().back().element.first)]; + packed.first()[pos] = std::move(packed.first().back()); + for(; *curr != last; curr = &packed.first()[*curr].next) {} + *curr = pos; + } + + packed.first().pop_back(); + } + + void rehash_if_required() { + if(const auto bc = bucket_count(); size() > static_cast(static_cast(bc) * max_load_factor())) { + rehash(bc * 2u); + } + } + +public: + /*! @brief Allocator type. */ + using allocator_type = Allocator; + /*! @brief Key type of the container. */ + using key_type = Key; + /*! @brief Mapped type of the container. */ + using mapped_type = Type; + /*! @brief Key-value type of the container. */ + using value_type = std::pair; + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + /*! @brief Signed integer type. */ + using difference_type = std::ptrdiff_t; + /*! @brief Type of function to use to hash the keys. */ + using hasher = Hash; + /*! @brief Type of function to use to compare the keys for equality. */ + using key_equal = KeyEqual; + /*! @brief Input iterator type. */ + using iterator = internal::dense_map_iterator; + /*! @brief Constant input iterator type. */ + using const_iterator = internal::dense_map_iterator; + /*! @brief Input iterator type. */ + using local_iterator = internal::dense_map_local_iterator; + /*! @brief Constant input iterator type. */ + using const_local_iterator = internal::dense_map_local_iterator; + + /*! @brief Default constructor. */ + dense_map() + : dense_map{minimum_capacity} {} + + /** + * @brief Constructs an empty container with a given allocator. + * @param allocator The allocator to use. + */ + explicit dense_map(const allocator_type &allocator) + : dense_map{minimum_capacity, hasher{}, key_equal{}, allocator} {} + + /** + * @brief Constructs an empty container with a given allocator and user + * supplied minimal number of buckets. + * @param cnt Minimal number of buckets. + * @param allocator The allocator to use. + */ + dense_map(const size_type cnt, const allocator_type &allocator) + : dense_map{cnt, hasher{}, key_equal{}, allocator} {} + + /** + * @brief Constructs an empty container with a given allocator, hash + * function and user supplied minimal number of buckets. + * @param cnt Minimal number of buckets. + * @param hash Hash function to use. + * @param allocator The allocator to use. + */ + dense_map(const size_type cnt, const hasher &hash, const allocator_type &allocator) + : dense_map{cnt, hash, key_equal{}, allocator} {} + + /** + * @brief Constructs an empty container with a given allocator, hash + * function, compare function and user supplied minimal number of buckets. + * @param cnt Minimal number of buckets. + * @param hash Hash function to use. + * @param equal Compare function to use. + * @param allocator The allocator to use. + */ + explicit dense_map(const size_type cnt, const hasher &hash = hasher{}, const key_equal &equal = key_equal{}, const allocator_type &allocator = allocator_type{}) + : sparse{allocator, hash}, + packed{allocator, equal} { + rehash(cnt); + } + + /*! @brief Default copy constructor. */ + dense_map(const dense_map &) = default; + + /** + * @brief Allocator-extended copy constructor. + * @param other The instance to copy from. + * @param allocator The allocator to use. + */ + dense_map(const dense_map &other, const allocator_type &allocator) + : sparse{std::piecewise_construct, std::forward_as_tuple(other.sparse.first(), allocator), std::forward_as_tuple(other.sparse.second())}, + packed{std::piecewise_construct, std::forward_as_tuple(other.packed.first(), allocator), std::forward_as_tuple(other.packed.second())}, + threshold{other.threshold} {} + + /*! @brief Default move constructor. */ + dense_map(dense_map &&) noexcept = default; + + /** + * @brief Allocator-extended move constructor. + * @param other The instance to move from. + * @param allocator The allocator to use. + */ + dense_map(dense_map &&other, const allocator_type &allocator) + : sparse{std::piecewise_construct, std::forward_as_tuple(std::move(other.sparse.first()), allocator), std::forward_as_tuple(std::move(other.sparse.second()))}, + packed{std::piecewise_construct, std::forward_as_tuple(std::move(other.packed.first()), allocator), std::forward_as_tuple(std::move(other.packed.second()))}, + threshold{other.threshold} {} + + /*! @brief Default destructor. */ + ~dense_map() = default; + + /** + * @brief Default copy assignment operator. + * @return This container. + */ + dense_map &operator=(const dense_map &) = default; + + /** + * @brief Default move assignment operator. + * @return This container. + */ + dense_map &operator=(dense_map &&) noexcept = default; + + /** + * @brief Exchanges the contents with those of a given container. + * @param other Container to exchange the content with. + */ + void swap(dense_map &other) noexcept { + using std::swap; + swap(sparse, other.sparse); + swap(packed, other.packed); + swap(threshold, other.threshold); + } + + /** + * @brief Returns the associated allocator. + * @return The associated allocator. + */ + [[nodiscard]] constexpr allocator_type get_allocator() const noexcept { + return sparse.first().get_allocator(); + } + + /** + * @brief Returns an iterator to the beginning. + * + * If the array is empty, the returned iterator will be equal to `end()`. + * + * @return An iterator to the first instance of the internal array. + */ + [[nodiscard]] const_iterator cbegin() const noexcept { + return packed.first().begin(); + } + + /*! @copydoc cbegin */ + [[nodiscard]] const_iterator begin() const noexcept { + return cbegin(); + } + + /*! @copydoc begin */ + [[nodiscard]] iterator begin() noexcept { + return packed.first().begin(); + } + + /** + * @brief Returns an iterator to the end. + * @return An iterator to the element following the last instance of the + * internal array. + */ + [[nodiscard]] const_iterator cend() const noexcept { + return packed.first().end(); + } + + /*! @copydoc cend */ + [[nodiscard]] const_iterator end() const noexcept { + return cend(); + } + + /*! @copydoc end */ + [[nodiscard]] iterator end() noexcept { + return packed.first().end(); + } + + /** + * @brief Checks whether a container is empty. + * @return True if the container is empty, false otherwise. + */ + [[nodiscard]] bool empty() const noexcept { + return packed.first().empty(); + } + + /** + * @brief Returns the number of elements in a container. + * @return Number of elements in a container. + */ + [[nodiscard]] size_type size() const noexcept { + return packed.first().size(); + } + + /** + * @brief Returns the maximum possible number of elements. + * @return Maximum possible number of elements. + */ + [[nodiscard]] size_type max_size() const noexcept { + return packed.first().max_size(); + } + + /*! @brief Clears the container. */ + void clear() noexcept { + sparse.first().clear(); + packed.first().clear(); + rehash(0u); + } + + /** + * @brief Inserts an element into the container, if the key does not exist. + * @param value A key-value pair eventually convertible to the value type. + * @return A pair consisting of an iterator to the inserted element (or to + * the element that prevented the insertion) and a bool denoting whether the + * insertion took place. + */ + std::pair insert(const value_type &value) { + return insert_or_do_nothing(value.first, value.second); + } + + /*! @copydoc insert */ + std::pair insert(value_type &&value) { + return insert_or_do_nothing(std::move(value.first), std::move(value.second)); + } + + /** + * @copydoc insert + * @tparam Arg Type of the key-value pair to insert into the container. + */ + template + std::enable_if_t, std::pair> + insert(Arg &&value) { + return insert_or_do_nothing(std::forward(value).first, std::forward(value).second); + } + + /** + * @brief Inserts elements into the container, if their keys do not exist. + * @tparam It Type of input iterator. + * @param first An iterator to the first element of the range of elements. + * @param last An iterator past the last element of the range of elements. + */ + template + void insert(It first, It last) { + for(; first != last; ++first) { + insert(*first); + } + } + + /** + * @brief Inserts an element into the container or assigns to the current + * element if the key already exists. + * @tparam Arg Type of the value to insert or assign. + * @param key A key used both to look up and to insert if not found. + * @param value A value to insert or assign. + * @return A pair consisting of an iterator to the element and a bool + * denoting whether the insertion took place. + */ + template + std::pair insert_or_assign(const key_type &key, Arg &&value) { + return insert_or_overwrite(key, std::forward(value)); + } + + /*! @copydoc insert_or_assign */ + template + std::pair insert_or_assign(key_type &&key, Arg &&value) { + return insert_or_overwrite(std::move(key), std::forward(value)); + } + + /** + * @brief Constructs an element in-place, if the key does not exist. + * + * The element is also constructed when the container already has the key, + * in which case the newly constructed object is destroyed immediately. + * + * @tparam Args Types of arguments to forward to the constructor of the + * element. + * @param args Arguments to forward to the constructor of the element. + * @return A pair consisting of an iterator to the inserted element (or to + * the element that prevented the insertion) and a bool denoting whether the + * insertion took place. + */ + template + std::pair emplace([[maybe_unused]] Args &&...args) { + if constexpr(sizeof...(Args) == 0u) { + return insert_or_do_nothing(key_type{}); + } else if constexpr(sizeof...(Args) == 1u) { + return insert_or_do_nothing(std::forward(args).first..., std::forward(args).second...); + } else if constexpr(sizeof...(Args) == 2u) { + return insert_or_do_nothing(std::forward(args)...); + } else { + auto &node = packed.first().emplace_back(packed.first().size(), std::forward(args)...); + const auto index = key_to_bucket(node.element.first); + + if(auto it = constrained_find(node.element.first, index); it != end()) { + packed.first().pop_back(); + return std::make_pair(it, false); + } + + std::swap(node.next, sparse.first()[index]); + rehash_if_required(); + + return std::make_pair(--end(), true); + } + } + + /** + * @brief Inserts in-place if the key does not exist, does nothing if the + * key exists. + * @tparam Args Types of arguments to forward to the constructor of the + * element. + * @param key A key used both to look up and to insert if not found. + * @param args Arguments to forward to the constructor of the element. + * @return A pair consisting of an iterator to the inserted element (or to + * the element that prevented the insertion) and a bool denoting whether the + * insertion took place. + */ + template + std::pair try_emplace(const key_type &key, Args &&...args) { + return insert_or_do_nothing(key, std::forward(args)...); + } + + /*! @copydoc try_emplace */ + template + std::pair try_emplace(key_type &&key, Args &&...args) { + return insert_or_do_nothing(std::move(key), std::forward(args)...); + } + + /** + * @brief Removes an element from a given position. + * @param pos An iterator to the element to remove. + * @return An iterator following the removed element. + */ + iterator erase(const_iterator pos) { + const auto diff = pos - cbegin(); + erase(pos->first); + return begin() + diff; + } + + /** + * @brief Removes the given elements from a container. + * @param first An iterator to the first element of the range of elements. + * @param last An iterator past the last element of the range of elements. + * @return An iterator following the last removed element. + */ + iterator erase(const_iterator first, const_iterator last) { + const auto dist = first - cbegin(); + + for(auto from = last - cbegin(); from != dist; --from) { + erase(packed.first()[static_cast(from) - 1u].element.first); + } + + return (begin() + dist); + } + + /** + * @brief Removes the element associated with a given key. + * @param key A key value of an element to remove. + * @return Number of elements removed (either 0 or 1). + */ + size_type erase(const key_type &key) { + for(size_type *curr = &sparse.first()[key_to_bucket(key)]; *curr != placeholder_position; curr = &packed.first()[*curr].next) { + if(packed.second()(packed.first()[*curr].element.first, key)) { + const auto index = *curr; + *curr = packed.first()[*curr].next; + move_and_pop(index); + return 1u; + } + } + + return 0u; + } + + /** + * @brief Accesses a given element with bounds checking. + * @param key A key of an element to find. + * @return A reference to the mapped value of the requested element. + */ + [[nodiscard]] mapped_type &at(const key_type &key) { + auto it = find(key); + ENTT_ASSERT(it != end(), "Invalid key"); + return it->second; + } + + /*! @copydoc at */ + [[nodiscard]] const mapped_type &at(const key_type &key) const { + auto it = find(key); + ENTT_ASSERT(it != cend(), "Invalid key"); + return it->second; + } + + /** + * @brief Accesses a given element with bounds checking. + * @tparam Other Type of the key of an element to find. + * @param key A key of an element to find. + * @return A reference to the mapped value of the requested element. + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + at(const Other &key) const { + auto it = find(key); + ENTT_ASSERT(it != cend(), "Invalid key"); + return it->second; + } + + /*! @copydoc at */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + at(const Other &key) { + auto it = find(key); + ENTT_ASSERT(it != end(), "Invalid key"); + return it->second; + } + + /** + * @brief Accesses or inserts a given element. + * @param key A key of an element to find or insert. + * @return A reference to the mapped value of the requested element. + */ + [[nodiscard]] mapped_type &operator[](const key_type &key) { + return insert_or_do_nothing(key).first->second; + } + + /** + * @brief Accesses or inserts a given element. + * @param key A key of an element to find or insert. + * @return A reference to the mapped value of the requested element. + */ + [[nodiscard]] mapped_type &operator[](key_type &&key) { + return insert_or_do_nothing(std::move(key)).first->second; + } + + /** + * @brief Returns the number of elements matching a key (either 1 or 0). + * @param key Key value of an element to search for. + * @return Number of elements matching the key (either 1 or 0). + */ + [[nodiscard]] size_type count(const key_type &key) const { + return find(key) != end(); + } + + /** + * @brief Returns the number of elements matching a key (either 1 or 0). + * @tparam Other Type of the key value of an element to search for. + * @param key Key value of an element to search for. + * @return Number of elements matching the key (either 1 or 0). + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + count(const Other &key) const { + return find(key) != end(); + } + + /** + * @brief Finds an element with a given key. + * @param key Key value of an element to search for. + * @return An iterator to an element with the given key. If no such element + * is found, a past-the-end iterator is returned. + */ + [[nodiscard]] iterator find(const key_type &key) { + return constrained_find(key, key_to_bucket(key)); + } + + /*! @copydoc find */ + [[nodiscard]] const_iterator find(const key_type &key) const { + return constrained_find(key, key_to_bucket(key)); + } + + /** + * @brief Finds an element with a key that compares _equivalent_ to a given + * key. + * @tparam Other Type of the key value of an element to search for. + * @param key Key value of an element to search for. + * @return An iterator to an element with the given key. If no such element + * is found, a past-the-end iterator is returned. + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + find(const Other &key) { + return constrained_find(key, key_to_bucket(key)); + } + + /*! @copydoc find */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + find(const Other &key) const { + return constrained_find(key, key_to_bucket(key)); + } + + /** + * @brief Returns a range containing all elements with a given key. + * @param key Key value of an element to search for. + * @return A pair of iterators pointing to the first element and past the + * last element of the range. + */ + [[nodiscard]] std::pair equal_range(const key_type &key) { + const auto it = find(key); + return {it, it + !(it == end())}; + } + + /*! @copydoc equal_range */ + [[nodiscard]] std::pair equal_range(const key_type &key) const { + const auto it = find(key); + return {it, it + !(it == cend())}; + } + + /** + * @brief Returns a range containing all elements that compare _equivalent_ + * to a given key. + * @tparam Other Type of an element to search for. + * @param key Key value of an element to search for. + * @return A pair of iterators pointing to the first element and past the + * last element of the range. + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t>> + equal_range(const Other &key) { + const auto it = find(key); + return {it, it + !(it == end())}; + } + + /*! @copydoc equal_range */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t>> + equal_range(const Other &key) const { + const auto it = find(key); + return {it, it + !(it == cend())}; + } + + /** + * @brief Checks if the container contains an element with a given key. + * @param key Key value of an element to search for. + * @return True if there is such an element, false otherwise. + */ + [[nodiscard]] bool contains(const key_type &key) const { + return (find(key) != cend()); + } + + /** + * @brief Checks if the container contains an element with a key that + * compares _equivalent_ to a given value. + * @tparam Other Type of the key value of an element to search for. + * @param key Key value of an element to search for. + * @return True if there is such an element, false otherwise. + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + contains(const Other &key) const { + return (find(key) != cend()); + } + + /** + * @brief Returns an iterator to the beginning of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the beginning of the given bucket. + */ + [[nodiscard]] const_local_iterator cbegin(const size_type index) const { + return {packed.first().begin(), sparse.first()[index]}; + } + + /** + * @brief Returns an iterator to the beginning of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the beginning of the given bucket. + */ + [[nodiscard]] const_local_iterator begin(const size_type index) const { + return cbegin(index); + } + + /** + * @brief Returns an iterator to the beginning of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the beginning of the given bucket. + */ + [[nodiscard]] local_iterator begin(const size_type index) { + return {packed.first().begin(), sparse.first()[index]}; + } + + /** + * @brief Returns an iterator to the end of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the end of the given bucket. + */ + [[nodiscard]] const_local_iterator cend([[maybe_unused]] const size_type index) const { + return {}; + } + + /** + * @brief Returns an iterator to the end of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the end of the given bucket. + */ + [[nodiscard]] const_local_iterator end(const size_type index) const { + return cend(index); + } + + /** + * @brief Returns an iterator to the end of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the end of the given bucket. + */ + [[nodiscard]] local_iterator end([[maybe_unused]] const size_type index) { + return {}; + } + + /** + * @brief Returns the number of buckets. + * @return The number of buckets. + */ + [[nodiscard]] size_type bucket_count() const { + return sparse.first().size(); + } + + /** + * @brief Returns the maximum number of buckets. + * @return The maximum number of buckets. + */ + [[nodiscard]] size_type max_bucket_count() const { + return sparse.first().max_size(); + } + + /** + * @brief Returns the number of elements in a given bucket. + * @param index The index of the bucket to examine. + * @return The number of elements in the given bucket. + */ + [[nodiscard]] size_type bucket_size(const size_type index) const { + return static_cast(std::distance(begin(index), end(index))); + } + + /** + * @brief Returns the bucket for a given key. + * @param key The value of the key to examine. + * @return The bucket for the given key. + */ + [[nodiscard]] size_type bucket(const key_type &key) const { + return key_to_bucket(key); + } + + /** + * @brief Returns the average number of elements per bucket. + * @return The average number of elements per bucket. + */ + [[nodiscard]] float load_factor() const { + return static_cast(size()) / static_cast(bucket_count()); + } + + /** + * @brief Returns the maximum average number of elements per bucket. + * @return The maximum average number of elements per bucket. + */ + [[nodiscard]] float max_load_factor() const { + return threshold; + } + + /** + * @brief Sets the desired maximum average number of elements per bucket. + * @param value A desired maximum average number of elements per bucket. + */ + void max_load_factor(const float value) { + ENTT_ASSERT(value > 0.f, "Invalid load factor"); + threshold = value; + rehash(0u); + } + + /** + * @brief Reserves at least the specified number of buckets and regenerates + * the hash table. + * @param cnt New number of buckets. + */ + void rehash(const size_type cnt) { + auto value = cnt > minimum_capacity ? cnt : minimum_capacity; + const auto cap = static_cast(static_cast(size()) / max_load_factor()); + value = value > cap ? value : cap; + + if(const auto sz = next_power_of_two(value); sz != bucket_count()) { + sparse.first().resize(sz); + + for(auto &&elem: sparse.first()) { + elem = placeholder_position; + } + + for(size_type pos{}, last = size(); pos < last; ++pos) { + const auto index = key_to_bucket(packed.first()[pos].element.first); + packed.first()[pos].next = std::exchange(sparse.first()[index], pos); + } + } + } + + /** + * @brief Reserves space for at least the specified number of elements and + * regenerates the hash table. + * @param cnt New number of elements. + */ + void reserve(const size_type cnt) { + packed.first().reserve(cnt); + rehash(static_cast(std::ceil(static_cast(cnt) / max_load_factor()))); + } + + /** + * @brief Returns the function used to hash the keys. + * @return The function used to hash the keys. + */ + [[nodiscard]] hasher hash_function() const { + return sparse.second(); + } + + /** + * @brief Returns the function used to compare keys for equality. + * @return The function used to compare keys for equality. + */ + [[nodiscard]] key_equal key_eq() const { + return packed.second(); + } + +private: + compressed_pair sparse; + compressed_pair packed; + float threshold{default_threshold}; +}; + +} // namespace entt + +/*! @cond TURN_OFF_DOXYGEN */ +namespace std { + +template +struct uses_allocator, Allocator> + : std::true_type {}; + +} // namespace std +/*! @endcond */ + +#endif + +// #include "../container/dense_set.hpp" +#ifndef ENTT_CONTAINER_DENSE_SET_HPP +#define ENTT_CONTAINER_DENSE_SET_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "../core/bit.hpp" + +// #include "../core/compressed_pair.hpp" + +// #include "../core/type_traits.hpp" + +// #include "fwd.hpp" + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +static constexpr std::size_t dense_set_placeholder_position = (std::numeric_limits::max)(); + +template +class dense_set_iterator final { + template + friend class dense_set_iterator; + +public: + using value_type = typename It::value_type::second_type; + using pointer = const value_type *; + using reference = const value_type &; + using difference_type = std::ptrdiff_t; + using iterator_category = std::random_access_iterator_tag; + + constexpr dense_set_iterator() noexcept + : it{} {} + + constexpr dense_set_iterator(const It iter) noexcept + : it{iter} {} + + template && std::is_constructible_v>> + constexpr dense_set_iterator(const dense_set_iterator &other) noexcept + : it{other.it} {} + + constexpr dense_set_iterator &operator++() noexcept { + return ++it, *this; + } + + constexpr dense_set_iterator operator++(int) noexcept { + const dense_set_iterator orig = *this; + return ++(*this), orig; + } + + constexpr dense_set_iterator &operator--() noexcept { + return --it, *this; + } + + constexpr dense_set_iterator operator--(int) noexcept { + const dense_set_iterator orig = *this; + return operator--(), orig; + } + + constexpr dense_set_iterator &operator+=(const difference_type value) noexcept { + it += value; + return *this; + } + + constexpr dense_set_iterator operator+(const difference_type value) const noexcept { + dense_set_iterator copy = *this; + return (copy += value); + } + + constexpr dense_set_iterator &operator-=(const difference_type value) noexcept { + return (*this += -value); + } + + constexpr dense_set_iterator operator-(const difference_type value) const noexcept { + return (*this + -value); + } + + [[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept { + return it[value].second; + } + + [[nodiscard]] constexpr pointer operator->() const noexcept { + return std::addressof(operator[](0)); + } + + [[nodiscard]] constexpr reference operator*() const noexcept { + return operator[](0); + } + + template + friend constexpr std::ptrdiff_t operator-(const dense_set_iterator &, const dense_set_iterator &) noexcept; + + template + friend constexpr bool operator==(const dense_set_iterator &, const dense_set_iterator &) noexcept; + + template + friend constexpr bool operator<(const dense_set_iterator &, const dense_set_iterator &) noexcept; + +private: + It it; +}; + +template +[[nodiscard]] constexpr std::ptrdiff_t operator-(const dense_set_iterator &lhs, const dense_set_iterator &rhs) noexcept { + return lhs.it - rhs.it; +} + +template +[[nodiscard]] constexpr bool operator==(const dense_set_iterator &lhs, const dense_set_iterator &rhs) noexcept { + return lhs.it == rhs.it; +} + +template +[[nodiscard]] constexpr bool operator!=(const dense_set_iterator &lhs, const dense_set_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +template +[[nodiscard]] constexpr bool operator<(const dense_set_iterator &lhs, const dense_set_iterator &rhs) noexcept { + return lhs.it < rhs.it; +} + +template +[[nodiscard]] constexpr bool operator>(const dense_set_iterator &lhs, const dense_set_iterator &rhs) noexcept { + return rhs < lhs; +} + +template +[[nodiscard]] constexpr bool operator<=(const dense_set_iterator &lhs, const dense_set_iterator &rhs) noexcept { + return !(lhs > rhs); +} + +template +[[nodiscard]] constexpr bool operator>=(const dense_set_iterator &lhs, const dense_set_iterator &rhs) noexcept { + return !(lhs < rhs); +} + +template +class dense_set_local_iterator final { + template + friend class dense_set_local_iterator; + +public: + using value_type = typename It::value_type::second_type; + using pointer = const value_type *; + using reference = const value_type &; + using difference_type = std::ptrdiff_t; + using iterator_category = std::forward_iterator_tag; + + constexpr dense_set_local_iterator() noexcept = default; + + constexpr dense_set_local_iterator(It iter, const std::size_t pos) noexcept + : it{iter}, + offset{pos} {} + + template && std::is_constructible_v>> + constexpr dense_set_local_iterator(const dense_set_local_iterator &other) noexcept + : it{other.it}, + offset{other.offset} {} + + constexpr dense_set_local_iterator &operator++() noexcept { + return offset = it[static_cast(offset)].first, *this; + } + + constexpr dense_set_local_iterator operator++(int) noexcept { + const dense_set_local_iterator orig = *this; + return ++(*this), orig; + } + + [[nodiscard]] constexpr pointer operator->() const noexcept { + return std::addressof(it[static_cast(offset)].second); + } + + [[nodiscard]] constexpr reference operator*() const noexcept { + return *operator->(); + } + + [[nodiscard]] constexpr std::size_t index() const noexcept { + return offset; + } + +private: + It it{}; + std::size_t offset{dense_set_placeholder_position}; +}; + +template +[[nodiscard]] constexpr bool operator==(const dense_set_local_iterator &lhs, const dense_set_local_iterator &rhs) noexcept { + return lhs.index() == rhs.index(); +} + +template +[[nodiscard]] constexpr bool operator!=(const dense_set_local_iterator &lhs, const dense_set_local_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Associative container for unique objects of a given type. + * + * Internally, elements are organized into buckets. Which bucket an element is + * placed into depends entirely on its hash. Elements with the same hash code + * appear in the same bucket. + * + * @tparam Type Value type of the associative container. + * @tparam Hash Type of function to use to hash the values. + * @tparam KeyEqual Type of function to use to compare the values for equality. + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +class dense_set { + static constexpr float default_threshold = 0.875f; + static constexpr std::size_t minimum_capacity = 8u; + static constexpr std::size_t placeholder_position = internal::dense_set_placeholder_position; + + using node_type = std::pair; + using alloc_traits = std::allocator_traits; + static_assert(std::is_same_v, "Invalid value type"); + using sparse_container_type = std::vector>; + using packed_container_type = std::vector>; + + template + [[nodiscard]] std::size_t value_to_bucket(const Other &value) const noexcept { + return fast_mod(static_cast(sparse.second()(value)), bucket_count()); + } + + template + [[nodiscard]] auto constrained_find(const Other &value, const std::size_t bucket) { + for(auto offset = sparse.first()[bucket]; offset != placeholder_position; offset = packed.first()[offset].first) { + if(packed.second()(packed.first()[offset].second, value)) { + return begin() + static_cast(offset); + } + } + + return end(); + } + + template + [[nodiscard]] auto constrained_find(const Other &value, const std::size_t bucket) const { + for(auto offset = sparse.first()[bucket]; offset != placeholder_position; offset = packed.first()[offset].first) { + if(packed.second()(packed.first()[offset].second, value)) { + return cbegin() + static_cast(offset); + } + } + + return cend(); + } + + template + [[nodiscard]] auto insert_or_do_nothing(Other &&value) { + const auto index = value_to_bucket(value); + + if(auto it = constrained_find(value, index); it != end()) { + return std::make_pair(it, false); + } + + packed.first().emplace_back(sparse.first()[index], std::forward(value)); + sparse.first()[index] = packed.first().size() - 1u; + rehash_if_required(); + + return std::make_pair(--end(), true); + } + + void move_and_pop(const std::size_t pos) { + if(const auto last = size() - 1u; pos != last) { + size_type *curr = &sparse.first()[value_to_bucket(packed.first().back().second)]; + packed.first()[pos] = std::move(packed.first().back()); + for(; *curr != last; curr = &packed.first()[*curr].first) {} + *curr = pos; + } + + packed.first().pop_back(); + } + + void rehash_if_required() { + if(const auto bc = bucket_count(); size() > static_cast(static_cast(bc) * max_load_factor())) { + rehash(bc * 2u); + } + } + +public: + /*! @brief Allocator type. */ + using allocator_type = Allocator; + /*! @brief Key type of the container. */ + using key_type = Type; + /*! @brief Value type of the container. */ + using value_type = Type; + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + /*! @brief Signed integer type. */ + using difference_type = std::ptrdiff_t; + /*! @brief Type of function to use to hash the elements. */ + using hasher = Hash; + /*! @brief Type of function to use to compare the elements for equality. */ + using key_equal = KeyEqual; + /*! @brief Random access iterator type. */ + using iterator = internal::dense_set_iterator; + /*! @brief Constant random access iterator type. */ + using const_iterator = internal::dense_set_iterator; + /*! @brief Reverse iterator type. */ + using reverse_iterator = std::reverse_iterator; + /*! @brief Constant reverse iterator type. */ + using const_reverse_iterator = std::reverse_iterator; + /*! @brief Forward iterator type. */ + using local_iterator = internal::dense_set_local_iterator; + /*! @brief Constant forward iterator type. */ + using const_local_iterator = internal::dense_set_local_iterator; + + /*! @brief Default constructor. */ + dense_set() + : dense_set{minimum_capacity} {} + + /** + * @brief Constructs an empty container with a given allocator. + * @param allocator The allocator to use. + */ + explicit dense_set(const allocator_type &allocator) + : dense_set{minimum_capacity, hasher{}, key_equal{}, allocator} {} + + /** + * @brief Constructs an empty container with a given allocator and user + * supplied minimal number of buckets. + * @param cnt Minimal number of buckets. + * @param allocator The allocator to use. + */ + dense_set(const size_type cnt, const allocator_type &allocator) + : dense_set{cnt, hasher{}, key_equal{}, allocator} {} + + /** + * @brief Constructs an empty container with a given allocator, hash + * function and user supplied minimal number of buckets. + * @param cnt Minimal number of buckets. + * @param hash Hash function to use. + * @param allocator The allocator to use. + */ + dense_set(const size_type cnt, const hasher &hash, const allocator_type &allocator) + : dense_set{cnt, hash, key_equal{}, allocator} {} + + /** + * @brief Constructs an empty container with a given allocator, hash + * function, compare function and user supplied minimal number of buckets. + * @param cnt Minimal number of buckets. + * @param hash Hash function to use. + * @param equal Compare function to use. + * @param allocator The allocator to use. + */ + explicit dense_set(const size_type cnt, const hasher &hash = hasher{}, const key_equal &equal = key_equal{}, const allocator_type &allocator = allocator_type{}) + : sparse{allocator, hash}, + packed{allocator, equal} { + rehash(cnt); + } + + /*! @brief Default copy constructor. */ + dense_set(const dense_set &) = default; + + /** + * @brief Allocator-extended copy constructor. + * @param other The instance to copy from. + * @param allocator The allocator to use. + */ + dense_set(const dense_set &other, const allocator_type &allocator) + : sparse{std::piecewise_construct, std::forward_as_tuple(other.sparse.first(), allocator), std::forward_as_tuple(other.sparse.second())}, + packed{std::piecewise_construct, std::forward_as_tuple(other.packed.first(), allocator), std::forward_as_tuple(other.packed.second())}, + threshold{other.threshold} {} + + /*! @brief Default move constructor. */ + dense_set(dense_set &&) noexcept = default; + + /** + * @brief Allocator-extended move constructor. + * @param other The instance to move from. + * @param allocator The allocator to use. + */ + dense_set(dense_set &&other, const allocator_type &allocator) + : sparse{std::piecewise_construct, std::forward_as_tuple(std::move(other.sparse.first()), allocator), std::forward_as_tuple(std::move(other.sparse.second()))}, + packed{std::piecewise_construct, std::forward_as_tuple(std::move(other.packed.first()), allocator), std::forward_as_tuple(std::move(other.packed.second()))}, + threshold{other.threshold} {} + + /*! @brief Default destructor. */ + ~dense_set() = default; + + /** + * @brief Default copy assignment operator. + * @return This container. + */ + dense_set &operator=(const dense_set &) = default; + + /** + * @brief Default move assignment operator. + * @return This container. + */ + dense_set &operator=(dense_set &&) noexcept = default; + + /** + * @brief Exchanges the contents with those of a given container. + * @param other Container to exchange the content with. + */ + void swap(dense_set &other) noexcept { + using std::swap; + swap(sparse, other.sparse); + swap(packed, other.packed); + swap(threshold, other.threshold); + } + + /** + * @brief Returns the associated allocator. + * @return The associated allocator. + */ + [[nodiscard]] constexpr allocator_type get_allocator() const noexcept { + return sparse.first().get_allocator(); + } + + /** + * @brief Returns an iterator to the beginning. + * + * If the array is empty, the returned iterator will be equal to `end()`. + * + * @return An iterator to the first instance of the internal array. + */ + [[nodiscard]] const_iterator cbegin() const noexcept { + return packed.first().begin(); + } + + /*! @copydoc cbegin */ + [[nodiscard]] const_iterator begin() const noexcept { + return cbegin(); + } + + /*! @copydoc begin */ + [[nodiscard]] iterator begin() noexcept { + return packed.first().begin(); + } + + /** + * @brief Returns an iterator to the end. + * @return An iterator to the element following the last instance of the + * internal array. + */ + [[nodiscard]] const_iterator cend() const noexcept { + return packed.first().end(); + } + + /*! @copydoc cend */ + [[nodiscard]] const_iterator end() const noexcept { + return cend(); + } + + /*! @copydoc end */ + [[nodiscard]] iterator end() noexcept { + return packed.first().end(); + } + + /** + * @brief Returns a reverse iterator to the beginning. + * + * If the array is empty, the returned iterator will be equal to `rend()`. + * + * @return An iterator to the first instance of the reversed internal array. + */ + [[nodiscard]] const_reverse_iterator crbegin() const noexcept { + return std::make_reverse_iterator(cend()); + } + + /*! @copydoc crbegin */ + [[nodiscard]] const_reverse_iterator rbegin() const noexcept { + return crbegin(); + } + + /*! @copydoc rbegin */ + [[nodiscard]] reverse_iterator rbegin() noexcept { + return std::make_reverse_iterator(end()); + } + + /** + * @brief Returns a reverse iterator to the end. + * @return An iterator to the element following the last instance of the + * reversed internal array. + */ + [[nodiscard]] const_reverse_iterator crend() const noexcept { + return std::make_reverse_iterator(cbegin()); + } + + /*! @copydoc crend */ + [[nodiscard]] const_reverse_iterator rend() const noexcept { + return crend(); + } + + /*! @copydoc rend */ + [[nodiscard]] reverse_iterator rend() noexcept { + return std::make_reverse_iterator(begin()); + } + + /** + * @brief Checks whether a container is empty. + * @return True if the container is empty, false otherwise. + */ + [[nodiscard]] bool empty() const noexcept { + return packed.first().empty(); + } + + /** + * @brief Returns the number of elements in a container. + * @return Number of elements in a container. + */ + [[nodiscard]] size_type size() const noexcept { + return packed.first().size(); + } + + /** + * @brief Returns the maximum possible number of elements. + * @return Maximum possible number of elements. + */ + [[nodiscard]] size_type max_size() const noexcept { + return packed.first().max_size(); + } + + /*! @brief Clears the container. */ + void clear() noexcept { + sparse.first().clear(); + packed.first().clear(); + rehash(0u); + } + + /** + * @brief Inserts an element into the container, if it does not exist. + * @param value An element to insert into the container. + * @return A pair consisting of an iterator to the inserted element (or to + * the element that prevented the insertion) and a bool denoting whether the + * insertion took place. + */ + std::pair insert(const value_type &value) { + return insert_or_do_nothing(value); + } + + /*! @copydoc insert */ + std::pair insert(value_type &&value) { + return insert_or_do_nothing(std::move(value)); + } + + /** + * @brief Inserts elements into the container, if they do not exist. + * @tparam It Type of input iterator. + * @param first An iterator to the first element of the range of elements. + * @param last An iterator past the last element of the range of elements. + */ + template + void insert(It first, It last) { + for(; first != last; ++first) { + insert(*first); + } + } + + /** + * @brief Constructs an element in-place, if it does not exist. + * + * The element is also constructed when the container already has the key, + * in which case the newly constructed object is destroyed immediately. + * + * @tparam Args Types of arguments to forward to the constructor of the + * element. + * @param args Arguments to forward to the constructor of the element. + * @return A pair consisting of an iterator to the inserted element (or to + * the element that prevented the insertion) and a bool denoting whether the + * insertion took place. + */ + template + std::pair emplace(Args &&...args) { + if constexpr(((sizeof...(Args) == 1u) && ... && std::is_same_v, value_type>)) { + return insert_or_do_nothing(std::forward(args)...); + } else { + auto &node = packed.first().emplace_back(std::piecewise_construct, std::make_tuple(packed.first().size()), std::forward_as_tuple(std::forward(args)...)); + const auto index = value_to_bucket(node.second); + + if(auto it = constrained_find(node.second, index); it != end()) { + packed.first().pop_back(); + return std::make_pair(it, false); + } + + std::swap(node.first, sparse.first()[index]); + rehash_if_required(); + + return std::make_pair(--end(), true); + } + } + + /** + * @brief Removes an element from a given position. + * @param pos An iterator to the element to remove. + * @return An iterator following the removed element. + */ + iterator erase(const_iterator pos) { + const auto diff = pos - cbegin(); + erase(*pos); + return begin() + diff; + } + + /** + * @brief Removes the given elements from a container. + * @param first An iterator to the first element of the range of elements. + * @param last An iterator past the last element of the range of elements. + * @return An iterator following the last removed element. + */ + iterator erase(const_iterator first, const_iterator last) { + const auto dist = first - cbegin(); + + for(auto from = last - cbegin(); from != dist; --from) { + erase(packed.first()[static_cast(from) - 1u].second); + } + + return (begin() + dist); + } + + /** + * @brief Removes the element associated with a given value. + * @param value Value of an element to remove. + * @return Number of elements removed (either 0 or 1). + */ + size_type erase(const value_type &value) { + for(size_type *curr = &sparse.first()[value_to_bucket(value)]; *curr != placeholder_position; curr = &packed.first()[*curr].first) { + if(packed.second()(packed.first()[*curr].second, value)) { + const auto index = *curr; + *curr = packed.first()[*curr].first; + move_and_pop(index); + return 1u; + } + } + + return 0u; + } + + /** + * @brief Returns the number of elements matching a value (either 1 or 0). + * @param key Key value of an element to search for. + * @return Number of elements matching the key (either 1 or 0). + */ + [[nodiscard]] size_type count(const value_type &key) const { + return find(key) != end(); + } + + /** + * @brief Returns the number of elements matching a key (either 1 or 0). + * @tparam Other Type of the key value of an element to search for. + * @param key Key value of an element to search for. + * @return Number of elements matching the key (either 1 or 0). + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + count(const Other &key) const { + return find(key) != end(); + } + + /** + * @brief Finds an element with a given value. + * @param value Value of an element to search for. + * @return An iterator to an element with the given value. If no such + * element is found, a past-the-end iterator is returned. + */ + [[nodiscard]] iterator find(const value_type &value) { + return constrained_find(value, value_to_bucket(value)); + } + + /*! @copydoc find */ + [[nodiscard]] const_iterator find(const value_type &value) const { + return constrained_find(value, value_to_bucket(value)); + } + + /** + * @brief Finds an element that compares _equivalent_ to a given value. + * @tparam Other Type of an element to search for. + * @param value Value of an element to search for. + * @return An iterator to an element with the given value. If no such + * element is found, a past-the-end iterator is returned. + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + find(const Other &value) { + return constrained_find(value, value_to_bucket(value)); + } + + /*! @copydoc find */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + find(const Other &value) const { + return constrained_find(value, value_to_bucket(value)); + } + + /** + * @brief Returns a range containing all elements with a given value. + * @param value Value of an element to search for. + * @return A pair of iterators pointing to the first element and past the + * last element of the range. + */ + [[nodiscard]] std::pair equal_range(const value_type &value) { + const auto it = find(value); + return {it, it + !(it == end())}; + } + + /*! @copydoc equal_range */ + [[nodiscard]] std::pair equal_range(const value_type &value) const { + const auto it = find(value); + return {it, it + !(it == cend())}; + } + + /** + * @brief Returns a range containing all elements that compare _equivalent_ + * to a given value. + * @tparam Other Type of an element to search for. + * @param value Value of an element to search for. + * @return A pair of iterators pointing to the first element and past the + * last element of the range. + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t>> + equal_range(const Other &value) { + const auto it = find(value); + return {it, it + !(it == end())}; + } + + /*! @copydoc equal_range */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t>> + equal_range(const Other &value) const { + const auto it = find(value); + return {it, it + !(it == cend())}; + } + + /** + * @brief Checks if the container contains an element with a given value. + * @param value Value of an element to search for. + * @return True if there is such an element, false otherwise. + */ + [[nodiscard]] bool contains(const value_type &value) const { + return (find(value) != cend()); + } + + /** + * @brief Checks if the container contains an element that compares + * _equivalent_ to a given value. + * @tparam Other Type of an element to search for. + * @param value Value of an element to search for. + * @return True if there is such an element, false otherwise. + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + contains(const Other &value) const { + return (find(value) != cend()); + } + + /** + * @brief Returns an iterator to the beginning of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the beginning of the given bucket. + */ + [[nodiscard]] const_local_iterator cbegin(const size_type index) const { + return {packed.first().begin(), sparse.first()[index]}; + } + + /** + * @brief Returns an iterator to the beginning of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the beginning of the given bucket. + */ + [[nodiscard]] const_local_iterator begin(const size_type index) const { + return cbegin(index); + } + + /** + * @brief Returns an iterator to the beginning of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the beginning of the given bucket. + */ + [[nodiscard]] local_iterator begin(const size_type index) { + return {packed.first().begin(), sparse.first()[index]}; + } + + /** + * @brief Returns an iterator to the end of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the end of the given bucket. + */ + [[nodiscard]] const_local_iterator cend([[maybe_unused]] const size_type index) const { + return {}; + } + + /** + * @brief Returns an iterator to the end of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the end of the given bucket. + */ + [[nodiscard]] const_local_iterator end(const size_type index) const { + return cend(index); + } + + /** + * @brief Returns an iterator to the end of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the end of the given bucket. + */ + [[nodiscard]] local_iterator end([[maybe_unused]] const size_type index) { + return {}; + } + + /** + * @brief Returns the number of buckets. + * @return The number of buckets. + */ + [[nodiscard]] size_type bucket_count() const { + return sparse.first().size(); + } + + /** + * @brief Returns the maximum number of buckets. + * @return The maximum number of buckets. + */ + [[nodiscard]] size_type max_bucket_count() const { + return sparse.first().max_size(); + } + + /** + * @brief Returns the number of elements in a given bucket. + * @param index The index of the bucket to examine. + * @return The number of elements in the given bucket. + */ + [[nodiscard]] size_type bucket_size(const size_type index) const { + return static_cast(std::distance(begin(index), end(index))); + } + + /** + * @brief Returns the bucket for a given element. + * @param value The value of the element to examine. + * @return The bucket for the given element. + */ + [[nodiscard]] size_type bucket(const value_type &value) const { + return value_to_bucket(value); + } + + /** + * @brief Returns the average number of elements per bucket. + * @return The average number of elements per bucket. + */ + [[nodiscard]] float load_factor() const { + return static_cast(size()) / static_cast(bucket_count()); + } + + /** + * @brief Returns the maximum average number of elements per bucket. + * @return The maximum average number of elements per bucket. + */ + [[nodiscard]] float max_load_factor() const { + return threshold; + } + + /** + * @brief Sets the desired maximum average number of elements per bucket. + * @param value A desired maximum average number of elements per bucket. + */ + void max_load_factor(const float value) { + ENTT_ASSERT(value > 0.f, "Invalid load factor"); + threshold = value; + rehash(0u); + } + + /** + * @brief Reserves at least the specified number of buckets and regenerates + * the hash table. + * @param cnt New number of buckets. + */ + void rehash(const size_type cnt) { + auto value = cnt > minimum_capacity ? cnt : minimum_capacity; + const auto cap = static_cast(static_cast(size()) / max_load_factor()); + value = value > cap ? value : cap; + + if(const auto sz = next_power_of_two(value); sz != bucket_count()) { + sparse.first().resize(sz); + + for(auto &&elem: sparse.first()) { + elem = placeholder_position; + } + + for(size_type pos{}, last = size(); pos < last; ++pos) { + const auto index = value_to_bucket(packed.first()[pos].second); + packed.first()[pos].first = std::exchange(sparse.first()[index], pos); + } + } + } + + /** + * @brief Reserves space for at least the specified number of elements and + * regenerates the hash table. + * @param cnt New number of elements. + */ + void reserve(const size_type cnt) { + packed.first().reserve(cnt); + rehash(static_cast(std::ceil(static_cast(cnt) / max_load_factor()))); + } + + /** + * @brief Returns the function used to hash the elements. + * @return The function used to hash the elements. + */ + [[nodiscard]] hasher hash_function() const { + return sparse.second(); + } + + /** + * @brief Returns the function used to compare elements for equality. + * @return The function used to compare elements for equality. + */ + [[nodiscard]] key_equal key_eq() const { + return packed.second(); + } + +private: + compressed_pair sparse; + compressed_pair packed; + float threshold{default_threshold}; +}; + +} // namespace entt + +#endif + +// #include "../core/type_traits.hpp" +#ifndef ENTT_CORE_TYPE_TRAITS_HPP +#define ENTT_CORE_TYPE_TRAITS_HPP + +#include +#include +#include +#include +#include +// #include "../config/config.h" +#ifndef ENTT_CONFIG_CONFIG_H +#define ENTT_CONFIG_CONFIG_H + +// #include "version.h" +#ifndef ENTT_CONFIG_VERSION_H +#define ENTT_CONFIG_VERSION_H + +// #include "macro.h" +#ifndef ENTT_CONFIG_MACRO_H +#define ENTT_CONFIG_MACRO_H + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#define ENTT_STR(arg) #arg +#define ENTT_XSTR(arg) ENTT_STR(arg) + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*) + +#define ENTT_VERSION_MAJOR 3 +#define ENTT_VERSION_MINOR 16 +#define ENTT_VERSION_PATCH 0 + +#define ENTT_VERSION \ + ENTT_XSTR(ENTT_VERSION_MAJOR) \ + "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH) + +// NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION) +# define ENTT_CONSTEXPR +# define ENTT_THROW throw +# define ENTT_TRY try +# define ENTT_CATCH catch(...) +#else +# define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20) +# define ENTT_THROW +# define ENTT_TRY if(true) +# define ENTT_CATCH if(false) +#endif + +#if __has_include() +# include +# +# if defined(__cpp_consteval) +# define ENTT_CONSTEVAL consteval +# endif +#endif + +#ifndef ENTT_CONSTEVAL +# define ENTT_CONSTEVAL constexpr +#endif + +#ifdef ENTT_USE_ATOMIC +# include +# define ENTT_MAYBE_ATOMIC(Type) std::atomic +#else +# define ENTT_MAYBE_ATOMIC(Type) Type +#endif + +#ifndef ENTT_ID_TYPE +# include +# define ENTT_ID_TYPE std::uint32_t +#else +# include // provides coverage for types in the std namespace +#endif + +#ifndef ENTT_SPARSE_PAGE +# define ENTT_SPARSE_PAGE 4096 +#endif + +#ifndef ENTT_PACKED_PAGE +# define ENTT_PACKED_PAGE 1024 +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT +# define ENTT_ASSERT(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT +# include +# define ENTT_ASSERT(condition, msg) assert(((condition) && (msg))) +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg) +#endif + +#define ENTT_FAIL(msg) ENTT_ASSERT(false, msg); + +#ifdef ENTT_NO_ETO +# define ENTT_ETO_TYPE(Type) void +#else +# define ENTT_ETO_TYPE(Type) Type +#endif + +#ifdef ENTT_NO_MIXIN +# define ENTT_STORAGE(Mixin, ...) __VA_ARGS__ +#else +# define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__> +#endif + +#ifdef ENTT_STANDARD_CPP +# define ENTT_NONSTD false +#else +# define ENTT_NONSTD true +# if defined __clang__ || defined __GNUC__ +# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ +# define ENTT_PRETTY_FUNCTION_PREFIX '=' +# define ENTT_PRETTY_FUNCTION_SUFFIX ']' +# elif defined _MSC_VER +# define ENTT_PRETTY_FUNCTION __FUNCSIG__ +# define ENTT_PRETTY_FUNCTION_PREFIX '<' +# define ENTT_PRETTY_FUNCTION_SUFFIX '>' +# endif +#endif + +#ifndef ENTT_EXPORT +# if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER +# define ENTT_EXPORT __declspec(dllexport) +# define ENTT_IMPORT __declspec(dllimport) +# define ENTT_HIDDEN +# elif defined __GNUC__ && __GNUC__ >= 4 +# define ENTT_EXPORT __attribute__((visibility("default"))) +# define ENTT_IMPORT __attribute__((visibility("default"))) +# define ENTT_HIDDEN __attribute__((visibility("hidden"))) +# else /* Unsupported compiler */ +# define ENTT_EXPORT +# define ENTT_IMPORT +# define ENTT_HIDDEN +# endif +#endif + +#ifndef ENTT_API +# if defined ENTT_API_EXPORT +# define ENTT_API ENTT_EXPORT +# elif defined ENTT_API_IMPORT +# define ENTT_API ENTT_IMPORT +# else /* No API */ +# define ENTT_API +# endif +#endif + +#if defined _MSC_VER +# pragma detect_mismatch("entt.version", ENTT_VERSION) +# pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY)) +# pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE)) +# pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD)) +#endif + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + +// #include "fwd.hpp" +#ifndef ENTT_CORE_FWD_HPP +#define ENTT_CORE_FWD_HPP + +#include +#include +// #include "../config/config.h" + + +namespace entt { + +/*! @brief Possible modes of an any object. */ +enum class any_policy : std::uint8_t { + /*! @brief Default mode, no element available. */ + empty, + /*! @brief Owning mode, dynamically allocated element. */ + dynamic, + /*! @brief Owning mode, embedded element. */ + embedded, + /*! @brief Aliasing mode, non-const reference. */ + ref, + /*! @brief Const aliasing mode, const reference. */ + cref +}; + +// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) +template +class basic_any; + +/*! @brief Alias declaration for type identifiers. */ +using id_type = ENTT_ID_TYPE; + +/*! @brief Alias declaration for the most common use case. */ +using any = basic_any<>; + +template +class compressed_pair; + +template +class basic_hashed_string; + +/*! @brief Aliases for common character types. */ +using hashed_string = basic_hashed_string; + +/*! @brief Aliases for common character types. */ +using hashed_wstring = basic_hashed_string; + +// NOLINTNEXTLINE(bugprone-forward-declaration-namespace) +struct type_info; + +} // namespace entt + +#endif + + +namespace entt { + +/** + * @brief Utility class to disambiguate overloaded functions. + * @tparam N Number of choices available. + */ +template +struct choice_t + // unfortunately, doxygen cannot parse such a construct + : /*! @cond TURN_OFF_DOXYGEN */ choice_t /*! @endcond */ +{}; + +/*! @copybrief choice_t */ +template<> +struct choice_t<0> {}; + +/** + * @brief Variable template for the choice trick. + * @tparam N Number of choices available. + */ +template +inline constexpr choice_t choice{}; + +/** + * @brief Identity type trait. + * + * Useful to establish non-deduced contexts in template argument deduction + * (waiting for C++20) or to provide types through function arguments. + * + * @tparam Type A type. + */ +template +struct type_identity { + /*! @brief Identity type. */ + using type = Type; +}; + +/** + * @brief Helper type. + * @tparam Type A type. + */ +template +using type_identity_t = typename type_identity::type; + +/** + * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains. + * @tparam Type The type of which to return the size. + */ +template +struct size_of: std::integral_constant {}; + +/*! @copydoc size_of */ +template +struct size_of> + // NOLINTNEXTLINE(bugprone-sizeof-expression) + : std::integral_constant {}; + +/** + * @brief Helper variable template. + * @tparam Type The type of which to return the size. + */ +template +inline constexpr std::size_t size_of_v = size_of::value; + +/** + * @brief Using declaration to be used to _repeat_ the same type a number of + * times equal to the size of a given parameter pack. + * @tparam Type A type to repeat. + */ +template +using unpack_as_type = Type; + +/** + * @brief Helper variable template to be used to _repeat_ the same value a + * number of times equal to the size of a given parameter pack. + * @tparam Value A value to repeat. + */ +template +inline constexpr auto unpack_as_value = Value; + +/** + * @brief Wraps a static constant. + * @tparam Value A static constant. + */ +template +using integral_constant = std::integral_constant; + +/** + * @brief Alias template to facilitate the creation of named values. + * @tparam Value A constant value at least convertible to `id_type`. + */ +template +using tag = integral_constant; + +/** + * @brief A class to use to push around lists of types, nothing more. + * @tparam Type Types provided by the type list. + */ +template +struct type_list { + /*! @brief Type list type. */ + using type = type_list; + /*! @brief Compile-time number of elements in the type list. */ + static constexpr auto size = sizeof...(Type); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_element; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Index Index of the type to return. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element> + : type_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element<0u, type_list> { + /*! @brief Searched type. */ + using type = First; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Type list to search into. + */ +template +using type_list_element_t = typename type_list_element::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_index; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 1u + type_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + static_assert(type_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +inline constexpr std::size_t type_list_index_v = type_list_index::value; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @return A type list composed by the types of both the type lists. + */ +template +constexpr type_list operator+(type_list, type_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_cat; + +/*! @brief Concatenates multiple type lists. */ +template<> +struct type_list_cat<> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list<>; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @tparam List Other type lists, if any. + */ +template +struct type_list_cat, type_list, List...> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = typename type_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the type list. + */ +template +struct type_list_cat> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list; +}; + +/** + * @brief Helper type. + * @tparam List Type lists to concatenate. + */ +template +using type_list_cat_t = typename type_list_cat::type; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct type_list_unique; + +template +struct type_list_unique, Type...> + : std::conditional_t<(std::is_same_v || ...), type_list_unique, Type...>, type_list_unique, Type..., First>> {}; + +template +struct type_list_unique, Type...> { + using type = type_list; +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Removes duplicates types from a type list. + * @tparam List Type list. + */ +template +struct type_list_unique { + /*! @brief A type list without duplicate types. */ + using type = typename internal::type_list_unique::type; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + */ +template +using type_list_unique_t = typename type_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a type list contains a + * given type, false otherwise. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +struct type_list_contains; + +/** + * @copybrief type_list_contains + * @tparam Type Types provided by the type list. + * @tparam Other Type to look for. + */ +template +struct type_list_contains, Other> + : std::bool_constant<(std::is_same_v || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +inline constexpr bool type_list_contains_v = type_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_diff; + +/** + * @brief Computes the difference between two type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + */ +template +struct type_list_diff, type_list> { + /*! @brief A type list that is the difference between the two type lists. */ + using type = type_list_cat_t, Type>, type_list<>, type_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Type lists between which to compute the difference. + */ +template +using type_list_diff_t = typename type_list_diff::type; + +/*! @brief Primary template isn't defined on purpose. */ +template class> +struct type_list_transform; + +/** + * @brief Applies a given _function_ to a type list and generate a new list. + * @tparam Type Types provided by the type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +struct type_list_transform, Op> { + /*! @brief Resulting type list after applying the transform function. */ + // NOLINTNEXTLINE(modernize-type-traits) + using type = type_list::type...>; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +using type_list_transform_t = typename type_list_transform::type; + +/** + * @brief A class to use to push around lists of constant values, nothing more. + * @tparam Value Values provided by the value list. + */ +template +struct value_list { + /*! @brief Value list type. */ + using type = value_list; + /*! @brief Compile-time number of elements in the value list. */ + static constexpr auto size = sizeof...(Value); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_element; + +/** + * @brief Provides compile-time indexed access to the values of a value list. + * @tparam Index Index of the value to return. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element> + : value_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element<0u, value_list> { + /*! @brief Searched type. */ + using type = decltype(Value); + /*! @brief Searched value. */ + static constexpr auto value = Value; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Value list to search into. + */ +template +using value_list_element_t = typename value_list_element::type; + +/** + * @brief Helper type. + * @tparam Index Index of the value to return. + * @tparam List Value list to search into. + */ +template +inline constexpr auto value_list_element_v = value_list_element::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_index; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam First First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 1u + value_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + static_assert(value_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +inline constexpr std::size_t value_list_index_v = value_list_index::value; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @return A value list composed by the values of both the value lists. + */ +template +constexpr value_list operator+(value_list, value_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_cat; + +/*! @brief Concatenates multiple value lists. */ +template<> +struct value_list_cat<> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list<>; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @tparam List Other value lists, if any. + */ +template +struct value_list_cat, value_list, List...> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = typename value_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the value list. + */ +template +struct value_list_cat> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list; +}; + +/** + * @brief Helper type. + * @tparam List Value lists to concatenate. + */ +template +using value_list_cat_t = typename value_list_cat::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_unique; + +/** + * @brief Removes duplicates values from a value list. + * @tparam Value One of the values provided by the given value list. + * @tparam Other The other values provided by the given value list. + */ +template +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = std::conditional_t< + ((Value == Other) || ...), + typename value_list_unique>::type, + value_list_cat_t, typename value_list_unique>::type>>; +}; + +/*! @brief Removes duplicates values from a value list. */ +template<> +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = value_list<>; +}; + +/** + * @brief Helper type. + * @tparam Type A value list. + */ +template +using value_list_unique_t = typename value_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a value list contains + * a given value, false otherwise. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +struct value_list_contains; + +/** + * @copybrief value_list_contains + * @tparam Value Values provided by the value list. + * @tparam Other Value to look for. + */ +template +struct value_list_contains, Other> + : std::bool_constant<((Value == Other) || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +inline constexpr bool value_list_contains_v = value_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_diff; + +/** + * @brief Computes the difference between two value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + */ +template +struct value_list_diff, value_list> { + /*! @brief A value list that is the difference between the two value lists. */ + using type = value_list_cat_t, Value>, value_list<>, value_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Value lists between which to compute the difference. + */ +template +using value_list_diff_t = typename value_list_diff::type; + +/*! @brief Same as std::is_invocable, but with tuples. */ +template +struct is_applicable: std::false_type {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @brief Helper variable template. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_v = is_applicable::value; + +/*! @brief Same as std::is_invocable_r, but with tuples for arguments. */ +template +struct is_applicable_r: std::false_type {}; + +/** + * @copybrief is_applicable_r + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +struct is_applicable_r>: std::is_invocable_r {}; + +/** + * @brief Helper variable template. + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_r_v = is_applicable_r::value; + +/** + * @brief Provides the member constant `value` to true if a given type is + * complete, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_complete: std::false_type {}; + +/*! @copydoc is_complete */ +template +struct is_complete>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_complete_v = is_complete::value; + +/** + * @brief Provides the member constant `value` to true if a given type is an + * iterator, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_iterator: std::false_type {}; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_iterator_category: std::false_type {}; + +template +struct has_iterator_category::iterator_category>>: std::true_type {}; + +} // namespace internal +/*! @endcond */ + +/*! @copydoc is_iterator */ +template +struct is_iterator>>>> + : internal::has_iterator_category {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_iterator_v = is_iterator::value; + +/** + * @brief Provides the member constant `value` to true if a given type is both + * an empty and non-final class, false otherwise. + * @tparam Type The type to test + */ +template +struct is_ebco_eligible + : std::bool_constant && !std::is_final_v> {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_ebco_eligible_v = is_ebco_eligible::value; + +/** + * @brief Provides the member constant `value` to true if `Type::is_transparent` + * is valid and denotes a type, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_transparent: std::false_type {}; + +/*! @copydoc is_transparent */ +template +struct is_transparent>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_transparent_v = is_transparent::value; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_tuple_size_value: std::false_type {}; + +template +struct has_tuple_size_value::value)>>: std::true_type {}; + +template +struct has_value_type: std::false_type {}; + +template +struct has_value_type>: std::true_type {}; + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable(); + +template +[[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence) { + return (dispatch_is_equality_comparable>() && ...); +} + +template +[[nodiscard]] constexpr bool maybe_equality_comparable(char) { + return false; +} + +template +[[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval() == std::declval()) { + return true; +} + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable() { + // NOLINTBEGIN(modernize-use-transparent-functors) + if constexpr(std::is_array_v) { + return false; + } else if constexpr(is_complete_v>>) { + if constexpr(has_tuple_size_value::value) { + return maybe_equality_comparable(0) && unpack_maybe_equality_comparable(std::make_index_sequence::value>{}); + } else { + return maybe_equality_comparable(0); + } + } else if constexpr(has_value_type::value) { + if constexpr(is_iterator_v || std::is_same_v || dispatch_is_equality_comparable()) { + return maybe_equality_comparable(0); + } else { + return false; + } + } else { + return maybe_equality_comparable(0); + } + // NOLINTEND(modernize-use-transparent-functors) +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Provides the member constant `value` to true if a given type is + * equality comparable, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_equality_comparable: std::bool_constant()> {}; + +/*! @copydoc is_equality_comparable */ +template +struct is_equality_comparable: is_equality_comparable {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_equality_comparable_v = is_equality_comparable::value; + +/** + * @brief Transcribes the constness of a type to another type. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = std::remove_const_t; +}; + +/*! @copydoc constness_as */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = const To; +}; + +/** + * @brief Alias template to facilitate the transcription of the constness. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +using constness_as_t = typename constness_as::type; + +/** + * @brief Extracts the class of a non-static member object or function. + * @tparam Member A pointer to a non-static member object or function. + */ +template +class member_class { + static_assert(std::is_member_pointer_v, "Invalid pointer type to non-static member object or function"); + + template + static Class *clazz(Ret (Class::*)(Args...)); + + template + static Class *clazz(Ret (Class::*)(Args...) const); + + template + static Class *clazz(Type Class::*); + +public: + /*! @brief The class of the given non-static member object or function. */ + using type = std::remove_pointer_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Member A pointer to a non-static member object or function. + */ +template +using member_class_t = typename member_class::type; + +/** + * @brief Extracts the n-th argument of a _callable_ type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid _callable_ type. + */ +template +class nth_argument { + template + static constexpr type_list pick_up(Ret (*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...) const); + + template + static constexpr type_list pick_up(Type Class ::*); + + template + static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&); + +public: + /*! @brief N-th argument of the _callable_ type. */ + using type = type_list_element_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid function, member function or data member type. + */ +template +using nth_argument_t = typename nth_argument::type; + +} // namespace entt + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::type_list_element> {}; + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::value_list_element> {}; + +#endif + +// #include "context.hpp" +#ifndef ENTT_META_CTX_HPP +#define ENTT_META_CTX_HPP + +#include +// #include "../container/dense_map.hpp" + +// #include "../core/fwd.hpp" +#ifndef ENTT_CORE_FWD_HPP +#define ENTT_CORE_FWD_HPP + +#include +#include +// #include "../config/config.h" + + +namespace entt { + +/*! @brief Possible modes of an any object. */ +enum class any_policy : std::uint8_t { + /*! @brief Default mode, no element available. */ + empty, + /*! @brief Owning mode, dynamically allocated element. */ + dynamic, + /*! @brief Owning mode, embedded element. */ + embedded, + /*! @brief Aliasing mode, non-const reference. */ + ref, + /*! @brief Const aliasing mode, const reference. */ + cref +}; + +// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) +template +class basic_any; + +/*! @brief Alias declaration for type identifiers. */ +using id_type = ENTT_ID_TYPE; + +/*! @brief Alias declaration for the most common use case. */ +using any = basic_any<>; + +template +class compressed_pair; + +template +class basic_hashed_string; + +/*! @brief Aliases for common character types. */ +using hashed_string = basic_hashed_string; + +/*! @brief Aliases for common character types. */ +using hashed_wstring = basic_hashed_string; + +// NOLINTNEXTLINE(bugprone-forward-declaration-namespace) +struct type_info; + +} // namespace entt + +#endif + +// #include "../core/utility.hpp" +#ifndef ENTT_CORE_UTILITY_HPP +#define ENTT_CORE_UTILITY_HPP + +#include +#include + +namespace entt { + +/*! @brief Identity function object (waiting for C++20). */ +struct identity { + /*! @brief Indicates that this is a transparent function object. */ + using is_transparent = void; + + /** + * @brief Returns its argument unchanged. + * @tparam Type Type of the argument. + * @param value The actual argument. + * @return The submitted value as-is. + */ + template + [[nodiscard]] constexpr Type &&operator()(Type &&value) const noexcept { + return std::forward(value); + } +}; + +/** + * @brief Constant utility to disambiguate overloaded members of a class. + * @tparam Type Type of the desired overload. + * @tparam Class Type of class to which the member belongs. + * @param member A valid pointer to a member. + * @return Pointer to the member. + */ +template +[[nodiscard]] constexpr auto overload(Type Class::*member) noexcept { + return member; +} + +/** + * @brief Constant utility to disambiguate overloaded functions. + * @tparam Func Function type of the desired overload. + * @param func A valid pointer to a function. + * @return Pointer to the function. + */ +template +[[nodiscard]] constexpr auto overload(Func *func) noexcept { + return func; +} + +/** + * @brief Helper type for visitors. + * @tparam Func Types of function objects. + */ +template +struct overloaded: Func... { + using Func::operator()...; +}; + +/** + * @brief Deduction guide. + * @tparam Func Types of function objects. + */ +template +overloaded(Func...) -> overloaded; + +/** + * @brief Basic implementation of a y-combinator. + * @tparam Func Type of a potentially recursive function. + */ +template +struct y_combinator { + /** + * @brief Constructs a y-combinator from a given function. + * @param recursive A potentially recursive function. + */ + constexpr y_combinator(Func recursive) noexcept(std::is_nothrow_move_constructible_v) + : func{std::move(recursive)} {} + + /** + * @brief Invokes a y-combinator and therefore its underlying function. + * @tparam Args Types of arguments to use to invoke the underlying function. + * @param args Parameters to use to invoke the underlying function. + * @return Return value of the underlying function, if any. + */ + template + constexpr decltype(auto) operator()(Args &&...args) const noexcept(std::is_nothrow_invocable_v) { + return func(*this, std::forward(args)...); + } + + /*! @copydoc operator()() */ + template + constexpr decltype(auto) operator()(Args &&...args) noexcept(std::is_nothrow_invocable_v) { + return func(*this, std::forward(args)...); + } + +private: + Func func; +}; + +} // namespace entt + +#endif + +// #include "fwd.hpp" +#ifndef ENTT_META_FWD_HPP +#define ENTT_META_FWD_HPP + +#include +#include + +namespace entt { + +class meta_ctx; + +class meta_sequence_container; + +class meta_associative_container; + +class meta_any; + +class meta_handle; + +struct meta_custom; + +class meta_data; + +class meta_func; + +class meta_type; + +template +class meta_factory; + +/*! @brief Used to identicate that a sequence container has not a fixed size. */ +inline constexpr std::size_t meta_dynamic_extent = (std::numeric_limits::max)(); + +} // namespace entt + +#endif + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +struct meta_type_node; + +struct meta_context { + dense_map, identity> value; + + [[nodiscard]] inline static meta_context &from(meta_ctx &); + [[nodiscard]] inline static const meta_context &from(const meta_ctx &); +}; + +} // namespace internal +/*! @endcond */ + +/*! @brief Disambiguation tag for constructors and the like. */ +class meta_ctx_arg_t final {}; + +/*! @brief Constant of type meta_context_arg_t used to disambiguate calls. */ +inline constexpr meta_ctx_arg_t meta_ctx_arg{}; + +/*! @brief Opaque meta context type. */ +class meta_ctx: private internal::meta_context { + // attorney idiom like model to access the base class + friend struct internal::meta_context; +}; + +/*! @cond TURN_OFF_DOXYGEN */ +[[nodiscard]] inline internal::meta_context &internal::meta_context::from(meta_ctx &ctx) { + return ctx; +} + +[[nodiscard]] inline const internal::meta_context &internal::meta_context::from(const meta_ctx &ctx) { + return ctx; +} +/*! @endcond */ + +} // namespace entt + +#endif + +// #include "fwd.hpp" + +// #include "meta.hpp" +#ifndef ENTT_META_META_HPP +#define ENTT_META_META_HPP + +#include +#include +#include +#include +#include +#include +// #include "../config/config.h" +#ifndef ENTT_CONFIG_CONFIG_H +#define ENTT_CONFIG_CONFIG_H + +// #include "version.h" +#ifndef ENTT_CONFIG_VERSION_H +#define ENTT_CONFIG_VERSION_H + +// #include "macro.h" +#ifndef ENTT_CONFIG_MACRO_H +#define ENTT_CONFIG_MACRO_H + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#define ENTT_STR(arg) #arg +#define ENTT_XSTR(arg) ENTT_STR(arg) + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*) + +#define ENTT_VERSION_MAJOR 3 +#define ENTT_VERSION_MINOR 16 +#define ENTT_VERSION_PATCH 0 + +#define ENTT_VERSION \ + ENTT_XSTR(ENTT_VERSION_MAJOR) \ + "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH) + +// NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION) +# define ENTT_CONSTEXPR +# define ENTT_THROW throw +# define ENTT_TRY try +# define ENTT_CATCH catch(...) +#else +# define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20) +# define ENTT_THROW +# define ENTT_TRY if(true) +# define ENTT_CATCH if(false) +#endif + +#if __has_include() +# include +# +# if defined(__cpp_consteval) +# define ENTT_CONSTEVAL consteval +# endif +#endif + +#ifndef ENTT_CONSTEVAL +# define ENTT_CONSTEVAL constexpr +#endif + +#ifdef ENTT_USE_ATOMIC +# include +# define ENTT_MAYBE_ATOMIC(Type) std::atomic +#else +# define ENTT_MAYBE_ATOMIC(Type) Type +#endif + +#ifndef ENTT_ID_TYPE +# include +# define ENTT_ID_TYPE std::uint32_t +#else +# include // provides coverage for types in the std namespace +#endif + +#ifndef ENTT_SPARSE_PAGE +# define ENTT_SPARSE_PAGE 4096 +#endif + +#ifndef ENTT_PACKED_PAGE +# define ENTT_PACKED_PAGE 1024 +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT +# define ENTT_ASSERT(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT +# include +# define ENTT_ASSERT(condition, msg) assert(((condition) && (msg))) +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg) +#endif + +#define ENTT_FAIL(msg) ENTT_ASSERT(false, msg); + +#ifdef ENTT_NO_ETO +# define ENTT_ETO_TYPE(Type) void +#else +# define ENTT_ETO_TYPE(Type) Type +#endif + +#ifdef ENTT_NO_MIXIN +# define ENTT_STORAGE(Mixin, ...) __VA_ARGS__ +#else +# define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__> +#endif + +#ifdef ENTT_STANDARD_CPP +# define ENTT_NONSTD false +#else +# define ENTT_NONSTD true +# if defined __clang__ || defined __GNUC__ +# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ +# define ENTT_PRETTY_FUNCTION_PREFIX '=' +# define ENTT_PRETTY_FUNCTION_SUFFIX ']' +# elif defined _MSC_VER +# define ENTT_PRETTY_FUNCTION __FUNCSIG__ +# define ENTT_PRETTY_FUNCTION_PREFIX '<' +# define ENTT_PRETTY_FUNCTION_SUFFIX '>' +# endif +#endif + +#ifndef ENTT_EXPORT +# if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER +# define ENTT_EXPORT __declspec(dllexport) +# define ENTT_IMPORT __declspec(dllimport) +# define ENTT_HIDDEN +# elif defined __GNUC__ && __GNUC__ >= 4 +# define ENTT_EXPORT __attribute__((visibility("default"))) +# define ENTT_IMPORT __attribute__((visibility("default"))) +# define ENTT_HIDDEN __attribute__((visibility("hidden"))) +# else /* Unsupported compiler */ +# define ENTT_EXPORT +# define ENTT_IMPORT +# define ENTT_HIDDEN +# endif +#endif + +#ifndef ENTT_API +# if defined ENTT_API_EXPORT +# define ENTT_API ENTT_EXPORT +# elif defined ENTT_API_IMPORT +# define ENTT_API ENTT_IMPORT +# else /* No API */ +# define ENTT_API +# endif +#endif + +#if defined _MSC_VER +# pragma detect_mismatch("entt.version", ENTT_VERSION) +# pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY)) +# pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE)) +# pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD)) +#endif + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + +// #include "../core/any.hpp" +#ifndef ENTT_CORE_ANY_HPP +#define ENTT_CORE_ANY_HPP + +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "fwd.hpp" + +// #include "type_info.hpp" +#ifndef ENTT_CORE_TYPE_INFO_HPP +#define ENTT_CORE_TYPE_INFO_HPP + +#include +#include +#include +// #include "../config/config.h" + +// #include "fwd.hpp" + +// #include "hashed_string.hpp" +#ifndef ENTT_CORE_HASHED_STRING_HPP +#define ENTT_CORE_HASHED_STRING_HPP + +#include +#include +// #include "fwd.hpp" + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct fnv_1a_params; + +template<> +struct fnv_1a_params { + static constexpr auto offset = 2166136261; + static constexpr auto prime = 16777619; +}; + +template<> +struct fnv_1a_params { + static constexpr auto offset = 14695981039346656037ull; + static constexpr auto prime = 1099511628211ull; +}; + +template +struct basic_hashed_string { + using value_type = Char; + using size_type = std::size_t; + using hash_type = id_type; + + const value_type *repr{}; + hash_type hash{fnv_1a_params<>::offset}; + size_type length{}; +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Zero overhead unique identifier. + * + * A hashed string is a compile-time tool that allows users to use + * human-readable identifiers in the codebase while using their numeric + * counterparts at runtime.
+ * Because of that, a hashed string can also be used in constant expressions if + * required. + * + * @warning + * This class doesn't take ownership of user-supplied strings nor does it make a + * copy of them. + * + * @tparam Char Character type. + */ +template +class basic_hashed_string: internal::basic_hashed_string { + using base_type = internal::basic_hashed_string; + using params = internal::fnv_1a_params<>; + + struct const_wrapper { + // non-explicit constructor on purpose + constexpr const_wrapper(const typename base_type::value_type *str) noexcept + : repr{str} {} + + const typename base_type::value_type *repr; + }; + +public: + /*! @brief Character type. */ + using value_type = typename base_type::value_type; + /*! @brief Unsigned integer type. */ + using size_type = typename base_type::size_type; + /*! @brief Unsigned integer type. */ + using hash_type = typename base_type::hash_type; + + /** + * @brief Returns directly the numeric representation of a string view. + * @param str Human-readable identifier. + * @param len Length of the string to hash. + * @return The numeric representation of the string. + */ + [[nodiscard]] static constexpr hash_type value(const value_type *str, const size_type len) noexcept { + return basic_hashed_string{str, len}; + } + + /** + * @brief Returns directly the numeric representation of a string. + * @tparam N Number of characters of the identifier. + * @param str Human-readable identifier. + * @return The numeric representation of the string. + */ + template + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) + [[nodiscard]] static ENTT_CONSTEVAL hash_type value(const value_type (&str)[N]) noexcept { + return basic_hashed_string{str}; + } + + /** + * @brief Returns directly the numeric representation of a string. + * @param wrapper Helps achieving the purpose by relying on overloading. + * @return The numeric representation of the string. + */ + [[nodiscard]] static constexpr hash_type value(const_wrapper wrapper) noexcept { + return basic_hashed_string{wrapper}; + } + + /*! @brief Constructs an empty hashed string. */ + constexpr basic_hashed_string() noexcept + : basic_hashed_string{nullptr, 0u} {} + + /** + * @brief Constructs a hashed string from a string view. + * @param str Human-readable identifier. + * @param len Length of the string to hash. + */ + constexpr basic_hashed_string(const value_type *str, const size_type len) noexcept + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay) + : base_type{str} { + // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic) + for(; base_type::length < len; ++base_type::length) { + base_type::hash = (base_type::hash ^ static_cast(str[base_type::length])) * params::prime; + } + // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic) + } + + /** + * @brief Constructs a hashed string from an array of const characters. + * @tparam N Number of characters of the identifier. + * @param str Human-readable identifier. + */ + template + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) + ENTT_CONSTEVAL basic_hashed_string(const value_type (&str)[N]) noexcept + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay) + : base_type{str} { + for(; str[base_type::length]; ++base_type::length) { + base_type::hash = (base_type::hash ^ static_cast(str[base_type::length])) * params::prime; + } + } + + /** + * @brief Explicit constructor on purpose to avoid constructing a hashed + * string directly from a `const value_type *`. + * + * @warning + * The lifetime of the string is not extended nor is it copied. + * + * @param wrapper Helps achieving the purpose by relying on overloading. + */ + explicit constexpr basic_hashed_string(const_wrapper wrapper) noexcept + : base_type{wrapper.repr} { + // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic) + for(; wrapper.repr[base_type::length]; ++base_type::length) { + base_type::hash = (base_type::hash ^ static_cast(wrapper.repr[base_type::length])) * params::prime; + } + // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic) + } + + /** + * @brief Returns the size of a hashed string. + * @return The size of the hashed string. + */ + [[nodiscard]] constexpr size_type size() const noexcept { + return base_type::length; + } + + /** + * @brief Returns the human-readable representation of a hashed string. + * @return The string used to initialize the hashed string. + */ + [[nodiscard]] constexpr const value_type *data() const noexcept { + return base_type::repr; + } + + /** + * @brief Returns the numeric representation of a hashed string. + * @return The numeric representation of the hashed string. + */ + [[nodiscard]] constexpr hash_type value() const noexcept { + return base_type::hash; + } + + /*! @copydoc data */ + [[nodiscard]] explicit constexpr operator const value_type *() const noexcept { + return data(); + } + + /** + * @brief Returns the numeric representation of a hashed string. + * @return The numeric representation of the hashed string. + */ + [[nodiscard]] constexpr operator hash_type() const noexcept { + return value(); + } +}; + +/** + * @brief Deduction guide. + * @tparam Char Character type. + * @param str Human-readable identifier. + * @param len Length of the string to hash. + */ +template +basic_hashed_string(const Char *str, std::size_t len) -> basic_hashed_string; + +/** + * @brief Deduction guide. + * @tparam Char Character type. + * @tparam N Number of characters of the identifier. + * @param str Human-readable identifier. + */ +template +// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) +basic_hashed_string(const Char (&str)[N]) -> basic_hashed_string; + +/** + * @brief Compares two hashed strings. + * @tparam Char Character type. + * @param lhs A valid hashed string. + * @param rhs A valid hashed string. + * @return True if the two hashed strings are identical, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator==(const basic_hashed_string &lhs, const basic_hashed_string &rhs) noexcept { + return lhs.value() == rhs.value(); +} + +/** + * @brief Compares two hashed strings. + * @tparam Char Character type. + * @param lhs A valid hashed string. + * @param rhs A valid hashed string. + * @return True if the two hashed strings differ, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator!=(const basic_hashed_string &lhs, const basic_hashed_string &rhs) noexcept { + return !(lhs == rhs); +} + +/** + * @brief Compares two hashed strings. + * @tparam Char Character type. + * @param lhs A valid hashed string. + * @param rhs A valid hashed string. + * @return True if the first element is less than the second, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator<(const basic_hashed_string &lhs, const basic_hashed_string &rhs) noexcept { + return lhs.value() < rhs.value(); +} + +/** + * @brief Compares two hashed strings. + * @tparam Char Character type. + * @param lhs A valid hashed string. + * @param rhs A valid hashed string. + * @return True if the first element is less than or equal to the second, false + * otherwise. + */ +template +[[nodiscard]] constexpr bool operator<=(const basic_hashed_string &lhs, const basic_hashed_string &rhs) noexcept { + return !(rhs < lhs); +} + +/** + * @brief Compares two hashed strings. + * @tparam Char Character type. + * @param lhs A valid hashed string. + * @param rhs A valid hashed string. + * @return True if the first element is greater than the second, false + * otherwise. + */ +template +[[nodiscard]] constexpr bool operator>(const basic_hashed_string &lhs, const basic_hashed_string &rhs) noexcept { + return rhs < lhs; +} + +/** + * @brief Compares two hashed strings. + * @tparam Char Character type. + * @param lhs A valid hashed string. + * @param rhs A valid hashed string. + * @return True if the first element is greater than or equal to the second, + * false otherwise. + */ +template +[[nodiscard]] constexpr bool operator>=(const basic_hashed_string &lhs, const basic_hashed_string &rhs) noexcept { + return !(lhs < rhs); +} + +inline namespace literals { + +/** + * @brief User defined literal for hashed strings. + * @param str The literal without its suffix. + * @return A properly initialized hashed string. + */ +[[nodiscard]] ENTT_CONSTEVAL hashed_string operator""_hs(const char *str, std::size_t) noexcept { + return hashed_string{str}; +} + +/** + * @brief User defined literal for hashed wstrings. + * @param str The literal without its suffix. + * @return A properly initialized hashed wstring. + */ +[[nodiscard]] ENTT_CONSTEVAL hashed_wstring operator""_hws(const wchar_t *str, std::size_t) noexcept { + return hashed_wstring{str}; +} + +} // namespace literals + +} // namespace entt + +#endif + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +struct ENTT_API type_index final { + [[nodiscard]] static id_type next() noexcept { + static ENTT_MAYBE_ATOMIC(id_type) value{}; + return value++; + } +}; + +template +[[nodiscard]] constexpr const char *pretty_function() noexcept { +#if defined ENTT_PRETTY_FUNCTION + return static_cast(ENTT_PRETTY_FUNCTION); +#else + return ""; +#endif +} + +template +[[nodiscard]] constexpr auto stripped_type_name() noexcept { +#if defined ENTT_PRETTY_FUNCTION + const std::string_view full_name{pretty_function()}; + auto first = full_name.find_first_not_of(' ', full_name.find_first_of(ENTT_PRETTY_FUNCTION_PREFIX) + 1); + auto value = full_name.substr(first, full_name.find_last_of(ENTT_PRETTY_FUNCTION_SUFFIX) - first); + return value; +#else + return std::string_view{}; +#endif +} + +template().find_first_of('.')> +[[nodiscard]] constexpr std::string_view type_name(int) noexcept { + constexpr auto value = stripped_type_name(); + return value; +} + +template +[[nodiscard]] std::string_view type_name(char) noexcept { + static const auto value = stripped_type_name(); + return value; +} + +template().find_first_of('.')> +[[nodiscard]] constexpr id_type type_hash(int) noexcept { + constexpr auto stripped = stripped_type_name(); + constexpr auto value = hashed_string::value(stripped.data(), stripped.size()); + return value; +} + +template +[[nodiscard]] id_type type_hash(char) noexcept { + static const auto value = [](const auto stripped) { + return hashed_string::value(stripped.data(), stripped.size()); + }(stripped_type_name()); + return value; +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Type sequential identifier. + * @tparam Type Type for which to generate a sequential identifier. + */ +template +struct ENTT_API type_index final { + /** + * @brief Returns the sequential identifier of a given type. + * @return The sequential identifier of a given type. + */ + [[nodiscard]] static id_type value() noexcept { + static const id_type value = internal::type_index::next(); + return value; + } + + /*! @copydoc value */ + [[nodiscard]] constexpr operator id_type() const noexcept { + return value(); + } +}; + +/** + * @brief Type hash. + * @tparam Type Type for which to generate a hash value. + */ +template +struct type_hash final { + /** + * @brief Returns the numeric representation of a given type. + * @return The numeric representation of the given type. + */ +#if defined ENTT_PRETTY_FUNCTION + [[nodiscard]] static constexpr id_type value() noexcept { + return internal::type_hash(0); +#else + [[nodiscard]] static constexpr id_type value() noexcept { + return type_index::value(); +#endif + } + + /*! @copydoc value */ + [[nodiscard]] constexpr operator id_type() const noexcept { + return value(); + } +}; + +/** + * @brief Type name. + * @tparam Type Type for which to generate a name. + */ +template +struct type_name final { + /** + * @brief Returns the name of a given type. + * @return The name of the given type. + */ + [[nodiscard]] static constexpr std::string_view value() noexcept { + return internal::type_name(0); + } + + /*! @copydoc value */ + [[nodiscard]] constexpr operator std::string_view() const noexcept { + return value(); + } +}; + +/*! @brief Implementation specific information about a type. */ +struct type_info final { + /** + * @brief Constructs a type info object for a given type. + * @tparam Type Type for which to construct a type info object. + */ + template + // NOLINTBEGIN(modernize-use-transparent-functors) + constexpr type_info(std::in_place_type_t) noexcept + : seq{type_index>>::value()}, + identifier{type_hash>>::value()}, + alias{type_name>>::value()} {} + // NOLINTEND(modernize-use-transparent-functors) + + /** + * @brief Type index. + * @return Type index. + */ + [[nodiscard]] constexpr id_type index() const noexcept { + return seq; + } + + /** + * @brief Type hash. + * @return Type hash. + */ + [[nodiscard]] constexpr id_type hash() const noexcept { + return identifier; + } + + /** + * @brief Type name. + * @return Type name. + */ + [[nodiscard]] constexpr std::string_view name() const noexcept { + return alias; + } + +private: + id_type seq; + id_type identifier; + std::string_view alias; +}; + +/** + * @brief Compares the contents of two type info objects. + * @param lhs A type info object. + * @param rhs A type info object. + * @return True if the two type info objects are identical, false otherwise. + */ +[[nodiscard]] constexpr bool operator==(const type_info &lhs, const type_info &rhs) noexcept { + return lhs.hash() == rhs.hash(); +} + +/** + * @brief Compares the contents of two type info objects. + * @param lhs A type info object. + * @param rhs A type info object. + * @return True if the two type info objects differ, false otherwise. + */ +[[nodiscard]] constexpr bool operator!=(const type_info &lhs, const type_info &rhs) noexcept { + return !(lhs == rhs); +} + +/** + * @brief Compares two type info objects. + * @param lhs A valid type info object. + * @param rhs A valid type info object. + * @return True if the first element is less than the second, false otherwise. + */ +[[nodiscard]] constexpr bool operator<(const type_info &lhs, const type_info &rhs) noexcept { + return lhs.index() < rhs.index(); +} + +/** + * @brief Compares two type info objects. + * @param lhs A valid type info object. + * @param rhs A valid type info object. + * @return True if the first element is less than or equal to the second, false + * otherwise. + */ +[[nodiscard]] constexpr bool operator<=(const type_info &lhs, const type_info &rhs) noexcept { + return !(rhs < lhs); +} + +/** + * @brief Compares two type info objects. + * @param lhs A valid type info object. + * @param rhs A valid type info object. + * @return True if the first element is greater than the second, false + * otherwise. + */ +[[nodiscard]] constexpr bool operator>(const type_info &lhs, const type_info &rhs) noexcept { + return rhs < lhs; +} + +/** + * @brief Compares two type info objects. + * @param lhs A valid type info object. + * @param rhs A valid type info object. + * @return True if the first element is greater than or equal to the second, + * false otherwise. + */ +[[nodiscard]] constexpr bool operator>=(const type_info &lhs, const type_info &rhs) noexcept { + return !(lhs < rhs); +} + +/** + * @brief Returns the type info object associated to a given type. + * + * The returned element refers to an object with static storage duration.
+ * The type doesn't need to be a complete type. If the type is a reference, the + * result refers to the referenced type. In all cases, top-level cv-qualifiers + * are ignored. + * + * @tparam Type Type for which to generate a type info object. + * @return A reference to a properly initialized type info object. + */ +template +[[nodiscard]] const type_info &type_id() noexcept { + if constexpr(std::is_same_v>>) { + static const type_info instance{std::in_place_type}; + return instance; + } else { + return type_id>>(); + } +} + +/*! @copydoc type_id */ +template +// NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward) +[[nodiscard]] const type_info &type_id(Type &&) noexcept { + return type_id>>(); +} + +} // namespace entt + +#endif + +// #include "type_traits.hpp" +#ifndef ENTT_CORE_TYPE_TRAITS_HPP +#define ENTT_CORE_TYPE_TRAITS_HPP + +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "fwd.hpp" + + +namespace entt { + +/** + * @brief Utility class to disambiguate overloaded functions. + * @tparam N Number of choices available. + */ +template +struct choice_t + // unfortunately, doxygen cannot parse such a construct + : /*! @cond TURN_OFF_DOXYGEN */ choice_t /*! @endcond */ +{}; + +/*! @copybrief choice_t */ +template<> +struct choice_t<0> {}; + +/** + * @brief Variable template for the choice trick. + * @tparam N Number of choices available. + */ +template +inline constexpr choice_t choice{}; + +/** + * @brief Identity type trait. + * + * Useful to establish non-deduced contexts in template argument deduction + * (waiting for C++20) or to provide types through function arguments. + * + * @tparam Type A type. + */ +template +struct type_identity { + /*! @brief Identity type. */ + using type = Type; +}; + +/** + * @brief Helper type. + * @tparam Type A type. + */ +template +using type_identity_t = typename type_identity::type; + +/** + * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains. + * @tparam Type The type of which to return the size. + */ +template +struct size_of: std::integral_constant {}; + +/*! @copydoc size_of */ +template +struct size_of> + // NOLINTNEXTLINE(bugprone-sizeof-expression) + : std::integral_constant {}; + +/** + * @brief Helper variable template. + * @tparam Type The type of which to return the size. + */ +template +inline constexpr std::size_t size_of_v = size_of::value; + +/** + * @brief Using declaration to be used to _repeat_ the same type a number of + * times equal to the size of a given parameter pack. + * @tparam Type A type to repeat. + */ +template +using unpack_as_type = Type; + +/** + * @brief Helper variable template to be used to _repeat_ the same value a + * number of times equal to the size of a given parameter pack. + * @tparam Value A value to repeat. + */ +template +inline constexpr auto unpack_as_value = Value; + +/** + * @brief Wraps a static constant. + * @tparam Value A static constant. + */ +template +using integral_constant = std::integral_constant; + +/** + * @brief Alias template to facilitate the creation of named values. + * @tparam Value A constant value at least convertible to `id_type`. + */ +template +using tag = integral_constant; + +/** + * @brief A class to use to push around lists of types, nothing more. + * @tparam Type Types provided by the type list. + */ +template +struct type_list { + /*! @brief Type list type. */ + using type = type_list; + /*! @brief Compile-time number of elements in the type list. */ + static constexpr auto size = sizeof...(Type); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_element; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Index Index of the type to return. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element> + : type_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element<0u, type_list> { + /*! @brief Searched type. */ + using type = First; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Type list to search into. + */ +template +using type_list_element_t = typename type_list_element::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_index; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 1u + type_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + static_assert(type_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +inline constexpr std::size_t type_list_index_v = type_list_index::value; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @return A type list composed by the types of both the type lists. + */ +template +constexpr type_list operator+(type_list, type_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_cat; + +/*! @brief Concatenates multiple type lists. */ +template<> +struct type_list_cat<> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list<>; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @tparam List Other type lists, if any. + */ +template +struct type_list_cat, type_list, List...> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = typename type_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the type list. + */ +template +struct type_list_cat> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list; +}; + +/** + * @brief Helper type. + * @tparam List Type lists to concatenate. + */ +template +using type_list_cat_t = typename type_list_cat::type; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct type_list_unique; + +template +struct type_list_unique, Type...> + : std::conditional_t<(std::is_same_v || ...), type_list_unique, Type...>, type_list_unique, Type..., First>> {}; + +template +struct type_list_unique, Type...> { + using type = type_list; +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Removes duplicates types from a type list. + * @tparam List Type list. + */ +template +struct type_list_unique { + /*! @brief A type list without duplicate types. */ + using type = typename internal::type_list_unique::type; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + */ +template +using type_list_unique_t = typename type_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a type list contains a + * given type, false otherwise. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +struct type_list_contains; + +/** + * @copybrief type_list_contains + * @tparam Type Types provided by the type list. + * @tparam Other Type to look for. + */ +template +struct type_list_contains, Other> + : std::bool_constant<(std::is_same_v || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +inline constexpr bool type_list_contains_v = type_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_diff; + +/** + * @brief Computes the difference between two type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + */ +template +struct type_list_diff, type_list> { + /*! @brief A type list that is the difference between the two type lists. */ + using type = type_list_cat_t, Type>, type_list<>, type_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Type lists between which to compute the difference. + */ +template +using type_list_diff_t = typename type_list_diff::type; + +/*! @brief Primary template isn't defined on purpose. */ +template class> +struct type_list_transform; + +/** + * @brief Applies a given _function_ to a type list and generate a new list. + * @tparam Type Types provided by the type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +struct type_list_transform, Op> { + /*! @brief Resulting type list after applying the transform function. */ + // NOLINTNEXTLINE(modernize-type-traits) + using type = type_list::type...>; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +using type_list_transform_t = typename type_list_transform::type; + +/** + * @brief A class to use to push around lists of constant values, nothing more. + * @tparam Value Values provided by the value list. + */ +template +struct value_list { + /*! @brief Value list type. */ + using type = value_list; + /*! @brief Compile-time number of elements in the value list. */ + static constexpr auto size = sizeof...(Value); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_element; + +/** + * @brief Provides compile-time indexed access to the values of a value list. + * @tparam Index Index of the value to return. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element> + : value_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element<0u, value_list> { + /*! @brief Searched type. */ + using type = decltype(Value); + /*! @brief Searched value. */ + static constexpr auto value = Value; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Value list to search into. + */ +template +using value_list_element_t = typename value_list_element::type; + +/** + * @brief Helper type. + * @tparam Index Index of the value to return. + * @tparam List Value list to search into. + */ +template +inline constexpr auto value_list_element_v = value_list_element::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_index; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam First First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 1u + value_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + static_assert(value_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +inline constexpr std::size_t value_list_index_v = value_list_index::value; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @return A value list composed by the values of both the value lists. + */ +template +constexpr value_list operator+(value_list, value_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_cat; + +/*! @brief Concatenates multiple value lists. */ +template<> +struct value_list_cat<> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list<>; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @tparam List Other value lists, if any. + */ +template +struct value_list_cat, value_list, List...> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = typename value_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the value list. + */ +template +struct value_list_cat> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list; +}; + +/** + * @brief Helper type. + * @tparam List Value lists to concatenate. + */ +template +using value_list_cat_t = typename value_list_cat::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_unique; + +/** + * @brief Removes duplicates values from a value list. + * @tparam Value One of the values provided by the given value list. + * @tparam Other The other values provided by the given value list. + */ +template +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = std::conditional_t< + ((Value == Other) || ...), + typename value_list_unique>::type, + value_list_cat_t, typename value_list_unique>::type>>; +}; + +/*! @brief Removes duplicates values from a value list. */ +template<> +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = value_list<>; +}; + +/** + * @brief Helper type. + * @tparam Type A value list. + */ +template +using value_list_unique_t = typename value_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a value list contains + * a given value, false otherwise. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +struct value_list_contains; + +/** + * @copybrief value_list_contains + * @tparam Value Values provided by the value list. + * @tparam Other Value to look for. + */ +template +struct value_list_contains, Other> + : std::bool_constant<((Value == Other) || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +inline constexpr bool value_list_contains_v = value_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_diff; + +/** + * @brief Computes the difference between two value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + */ +template +struct value_list_diff, value_list> { + /*! @brief A value list that is the difference between the two value lists. */ + using type = value_list_cat_t, Value>, value_list<>, value_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Value lists between which to compute the difference. + */ +template +using value_list_diff_t = typename value_list_diff::type; + +/*! @brief Same as std::is_invocable, but with tuples. */ +template +struct is_applicable: std::false_type {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @brief Helper variable template. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_v = is_applicable::value; + +/*! @brief Same as std::is_invocable_r, but with tuples for arguments. */ +template +struct is_applicable_r: std::false_type {}; + +/** + * @copybrief is_applicable_r + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +struct is_applicable_r>: std::is_invocable_r {}; + +/** + * @brief Helper variable template. + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_r_v = is_applicable_r::value; + +/** + * @brief Provides the member constant `value` to true if a given type is + * complete, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_complete: std::false_type {}; + +/*! @copydoc is_complete */ +template +struct is_complete>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_complete_v = is_complete::value; + +/** + * @brief Provides the member constant `value` to true if a given type is an + * iterator, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_iterator: std::false_type {}; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_iterator_category: std::false_type {}; + +template +struct has_iterator_category::iterator_category>>: std::true_type {}; + +} // namespace internal +/*! @endcond */ + +/*! @copydoc is_iterator */ +template +struct is_iterator>>>> + : internal::has_iterator_category {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_iterator_v = is_iterator::value; + +/** + * @brief Provides the member constant `value` to true if a given type is both + * an empty and non-final class, false otherwise. + * @tparam Type The type to test + */ +template +struct is_ebco_eligible + : std::bool_constant && !std::is_final_v> {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_ebco_eligible_v = is_ebco_eligible::value; + +/** + * @brief Provides the member constant `value` to true if `Type::is_transparent` + * is valid and denotes a type, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_transparent: std::false_type {}; + +/*! @copydoc is_transparent */ +template +struct is_transparent>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_transparent_v = is_transparent::value; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_tuple_size_value: std::false_type {}; + +template +struct has_tuple_size_value::value)>>: std::true_type {}; + +template +struct has_value_type: std::false_type {}; + +template +struct has_value_type>: std::true_type {}; + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable(); + +template +[[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence) { + return (dispatch_is_equality_comparable>() && ...); +} + +template +[[nodiscard]] constexpr bool maybe_equality_comparable(char) { + return false; +} + +template +[[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval() == std::declval()) { + return true; +} + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable() { + // NOLINTBEGIN(modernize-use-transparent-functors) + if constexpr(std::is_array_v) { + return false; + } else if constexpr(is_complete_v>>) { + if constexpr(has_tuple_size_value::value) { + return maybe_equality_comparable(0) && unpack_maybe_equality_comparable(std::make_index_sequence::value>{}); + } else { + return maybe_equality_comparable(0); + } + } else if constexpr(has_value_type::value) { + if constexpr(is_iterator_v || std::is_same_v || dispatch_is_equality_comparable()) { + return maybe_equality_comparable(0); + } else { + return false; + } + } else { + return maybe_equality_comparable(0); + } + // NOLINTEND(modernize-use-transparent-functors) +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Provides the member constant `value` to true if a given type is + * equality comparable, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_equality_comparable: std::bool_constant()> {}; + +/*! @copydoc is_equality_comparable */ +template +struct is_equality_comparable: is_equality_comparable {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_equality_comparable_v = is_equality_comparable::value; + +/** + * @brief Transcribes the constness of a type to another type. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = std::remove_const_t; +}; + +/*! @copydoc constness_as */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = const To; +}; + +/** + * @brief Alias template to facilitate the transcription of the constness. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +using constness_as_t = typename constness_as::type; + +/** + * @brief Extracts the class of a non-static member object or function. + * @tparam Member A pointer to a non-static member object or function. + */ +template +class member_class { + static_assert(std::is_member_pointer_v, "Invalid pointer type to non-static member object or function"); + + template + static Class *clazz(Ret (Class::*)(Args...)); + + template + static Class *clazz(Ret (Class::*)(Args...) const); + + template + static Class *clazz(Type Class::*); + +public: + /*! @brief The class of the given non-static member object or function. */ + using type = std::remove_pointer_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Member A pointer to a non-static member object or function. + */ +template +using member_class_t = typename member_class::type; + +/** + * @brief Extracts the n-th argument of a _callable_ type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid _callable_ type. + */ +template +class nth_argument { + template + static constexpr type_list pick_up(Ret (*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...) const); + + template + static constexpr type_list pick_up(Type Class ::*); + + template + static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&); + +public: + /*! @brief N-th argument of the _callable_ type. */ + using type = type_list_element_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid function, member function or data member type. + */ +template +using nth_argument_t = typename nth_argument::type; + +} // namespace entt + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::type_list_element> {}; + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::value_list_element> {}; + +#endif + +// #include "utility.hpp" +#ifndef ENTT_CORE_UTILITY_HPP +#define ENTT_CORE_UTILITY_HPP + +#include +#include + +namespace entt { + +/*! @brief Identity function object (waiting for C++20). */ +struct identity { + /*! @brief Indicates that this is a transparent function object. */ + using is_transparent = void; + + /** + * @brief Returns its argument unchanged. + * @tparam Type Type of the argument. + * @param value The actual argument. + * @return The submitted value as-is. + */ + template + [[nodiscard]] constexpr Type &&operator()(Type &&value) const noexcept { + return std::forward(value); + } +}; + +/** + * @brief Constant utility to disambiguate overloaded members of a class. + * @tparam Type Type of the desired overload. + * @tparam Class Type of class to which the member belongs. + * @param member A valid pointer to a member. + * @return Pointer to the member. + */ +template +[[nodiscard]] constexpr auto overload(Type Class::*member) noexcept { + return member; +} + +/** + * @brief Constant utility to disambiguate overloaded functions. + * @tparam Func Function type of the desired overload. + * @param func A valid pointer to a function. + * @return Pointer to the function. + */ +template +[[nodiscard]] constexpr auto overload(Func *func) noexcept { + return func; +} + +/** + * @brief Helper type for visitors. + * @tparam Func Types of function objects. + */ +template +struct overloaded: Func... { + using Func::operator()...; +}; + +/** + * @brief Deduction guide. + * @tparam Func Types of function objects. + */ +template +overloaded(Func...) -> overloaded; + +/** + * @brief Basic implementation of a y-combinator. + * @tparam Func Type of a potentially recursive function. + */ +template +struct y_combinator { + /** + * @brief Constructs a y-combinator from a given function. + * @param recursive A potentially recursive function. + */ + constexpr y_combinator(Func recursive) noexcept(std::is_nothrow_move_constructible_v) + : func{std::move(recursive)} {} + + /** + * @brief Invokes a y-combinator and therefore its underlying function. + * @tparam Args Types of arguments to use to invoke the underlying function. + * @param args Parameters to use to invoke the underlying function. + * @return Return value of the underlying function, if any. + */ + template + constexpr decltype(auto) operator()(Args &&...args) const noexcept(std::is_nothrow_invocable_v) { + return func(*this, std::forward(args)...); + } + + /*! @copydoc operator()() */ + template + constexpr decltype(auto) operator()(Args &&...args) noexcept(std::is_nothrow_invocable_v) { + return func(*this, std::forward(args)...); + } + +private: + Func func; +}; + +} // namespace entt + +#endif + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +enum class any_request : std::uint8_t { + info, + transfer, + assign, + compare, + copy, + move +}; + +template +struct basic_any_storage { + static constexpr bool has_buffer = true; + union { + const void *instance{}; + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) + alignas(Align) std::byte buffer[Len]; + }; +}; + +template +struct basic_any_storage<0u, Align> { + static constexpr bool has_buffer = false; + const void *instance{}; +}; + +template +// NOLINTNEXTLINE(bugprone-sizeof-expression) +struct in_situ: std::bool_constant<(Len != 0u) && alignof(Type) <= Align && sizeof(Type) <= Len && std::is_nothrow_move_constructible_v> {}; + +template +struct in_situ: std::false_type {}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief A SBO friendly, type-safe container for single values of any type. + * @tparam Len Size of the buffer reserved for the small buffer optimization. + * @tparam Align Optional alignment requirement. + */ +template +class basic_any: private internal::basic_any_storage { + using request = internal::any_request; + using base_type = internal::basic_any_storage; + using vtable_type = const void *(const request, const basic_any &, const void *); + using deleter_type = void(const basic_any &); + + template + static constexpr bool in_situ_v = internal::in_situ::value; + + template + static const void *basic_vtable(const request req, const basic_any &value, const void *other) { + static_assert(std::is_same_v>, Type>, "Invalid type"); + + switch(const auto *elem = static_cast(value.data()); req) { + case request::info: + return &type_id(); + case request::transfer: + if constexpr(std::is_move_assignable_v) { + // NOLINTNEXTLINE(bugprone-casting-through-void) + *const_cast(elem) = std::move(*static_cast(const_cast(other))); + return other; + } + [[fallthrough]]; + case request::assign: + if constexpr(std::is_copy_assignable_v) { + *const_cast(elem) = *static_cast(other); + return other; + } + break; + case request::compare: + if constexpr(!std::is_function_v && !std::is_array_v && is_equality_comparable_v) { + return (*elem == *static_cast(other)) ? other : nullptr; + } else { + return (elem == other) ? other : nullptr; + } + case request::copy: + if constexpr(std::is_copy_constructible_v) { + // NOLINTNEXTLINE(bugprone-casting-through-void) + static_cast(const_cast(other))->initialize(*elem); + } + break; + case request::move: + ENTT_ASSERT(value.mode == any_policy::embedded, "Unexpected policy"); + if constexpr(in_situ_v) { + // NOLINTNEXTLINE(bugprone-casting-through-void, bugprone-multi-level-implicit-pointer-conversion) + return ::new(&static_cast(const_cast(other))->buffer) Type{std::move(*const_cast(elem))}; + } + } + + return nullptr; + } + + template + static void basic_deleter(const basic_any &value) { + static_assert(std::is_same_v>, Type>, "Invalid type"); + ENTT_ASSERT((value.mode == any_policy::dynamic) || ((value.mode == any_policy::embedded) && !std::is_trivially_destructible_v), "Unexpected policy"); + + const auto *elem = static_cast(value.data()); + + if constexpr(in_situ_v) { + (value.mode == any_policy::embedded) ? elem->~Type() : (delete elem); + } else if constexpr(std::is_array_v) { + delete[] elem; + } else { + delete elem; + } + } + + template + void initialize([[maybe_unused]] Args &&...args) { + using plain_type = std::remove_const_t>; + + vtable = basic_vtable; + underlying_type = type_hash::value(); + + if constexpr(std::is_void_v) { + deleter = nullptr; + mode = any_policy::empty; + this->instance = nullptr; + } else if constexpr(std::is_lvalue_reference_v) { + deleter = nullptr; + mode = std::is_const_v> ? any_policy::cref : any_policy::ref; + static_assert((std::is_lvalue_reference_v && ...) && (sizeof...(Args) == 1u), "Invalid arguments"); + // NOLINTNEXTLINE(bugprone-multi-level-implicit-pointer-conversion) + this->instance = (std::addressof(args), ...); + } else if constexpr(in_situ_v) { + if constexpr(std::is_trivially_destructible_v) { + deleter = nullptr; + } else { + deleter = &basic_deleter; + } + + mode = any_policy::embedded; + + if constexpr(std::is_aggregate_v && (sizeof...(Args) != 0u || !std::is_default_constructible_v)) { + ::new(&this->buffer) plain_type{std::forward(args)...}; + } else { + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay) + ::new(&this->buffer) plain_type(std::forward(args)...); + } + } else { + deleter = &basic_deleter; + mode = any_policy::dynamic; + + if constexpr(std::is_aggregate_v && (sizeof...(Args) != 0u || !std::is_default_constructible_v)) { + this->instance = new plain_type{std::forward(args)...}; + } else if constexpr(std::is_array_v) { + static_assert(sizeof...(Args) == 0u, "Invalid arguments"); + this->instance = new plain_type[std::extent_v](); + } else { + this->instance = new plain_type(std::forward(args)...); + } + } + } + + void invoke_deleter_if_exists() { + if(deleter != nullptr) { + deleter(*this); + } + } + +public: + /*! @brief Size of the internal buffer. */ + static constexpr auto length = Len; + /*! @brief Alignment requirement. */ + static constexpr auto alignment = Align; + + /*! @brief Default constructor. */ + constexpr basic_any() noexcept + : basic_any{std::in_place_type} {} + + /** + * @brief Constructs a wrapper by directly initializing the new object. + * @tparam Type Type of object to use to initialize the wrapper. + * @tparam Args Types of arguments to use to construct the new instance. + * @param args Parameters to use to construct the instance. + */ + template + explicit basic_any(std::in_place_type_t, Args &&...args) + : base_type{} { + initialize(std::forward(args)...); + } + + /** + * @brief Constructs a wrapper taking ownership of the passed object. + * @tparam Type Type of object to use to initialize the wrapper. + * @param value A pointer to an object to take ownership of. + */ + template + explicit basic_any(std::in_place_t, Type *value) + : base_type{} { + static_assert(!std::is_const_v && !std::is_void_v, "Non-const non-void pointer required"); + + if(value == nullptr) { + initialize(); + } else { + initialize(*value); + deleter = &basic_deleter; + mode = any_policy::dynamic; + } + } + + /** + * @brief Constructs a wrapper from a given value. + * @tparam Type Type of object to use to initialize the wrapper. + * @param value An instance of an object to use to initialize the wrapper. + */ + template, basic_any>>> + basic_any(Type &&value) + : basic_any{std::in_place_type>, std::forward(value)} {} + + /** + * @brief Copy constructor. + * @param other The instance to copy from. + */ + basic_any(const basic_any &other) + : basic_any{} { + other.vtable(request::copy, other, this); + } + + /** + * @brief Move constructor. + * @param other The instance to move from. + */ + basic_any(basic_any &&other) noexcept + : base_type{}, + vtable{other.vtable}, + deleter{other.deleter}, + underlying_type{other.underlying_type}, + mode{other.mode} { + if(other.mode == any_policy::embedded) { + other.vtable(request::move, other, this); + } else if(other.mode != any_policy::empty) { + this->instance = std::exchange(other.instance, nullptr); + } + } + + /*! @brief Frees the internal buffer, whatever it means. */ + ~basic_any() { + invoke_deleter_if_exists(); + } + + /** + * @brief Copy assignment operator. + * @param other The instance to copy from. + * @return This any object. + */ + basic_any &operator=(const basic_any &other) { + if(this != &other) { + invoke_deleter_if_exists(); + + if(other) { + other.vtable(request::copy, other, this); + } else { + initialize(); + } + } + + return *this; + } + + /** + * @brief Move assignment operator. + * @param other The instance to move from. + * @return This any object. + */ + basic_any &operator=(basic_any &&other) noexcept { + if(this != &other) { + invoke_deleter_if_exists(); + + if(other.mode == any_policy::embedded) { + other.vtable(request::move, other, this); + } else if(other.mode != any_policy::empty) { + this->instance = std::exchange(other.instance, nullptr); + } + + vtable = other.vtable; + deleter = other.deleter; + underlying_type = other.underlying_type; + mode = other.mode; + } + + return *this; + } + + /** + * @brief Value assignment operator. + * @tparam Type Type of object to use to initialize the wrapper. + * @param value An instance of an object to use to initialize the wrapper. + * @return This any object. + */ + template, basic_any>>> + basic_any &operator=(Type &&value) { + emplace>(std::forward(value)); + return *this; + } + + /** + * @brief Returns false if a wrapper is empty, true otherwise. + * @return False if the wrapper is empty, true otherwise. + */ + [[nodiscard]] bool has_value() const noexcept { + return (mode != any_policy::empty); + } + + /** + * @brief Returns false if the wrapper does not contain the expected type, + * true otherwise. + * @param req Expected type. + * @return False if the wrapper does not contain the expected type, true + * otherwise. + */ + [[nodiscard]] bool has_value(const type_info &req) const noexcept { + return (underlying_type == req.hash()); + } + + /** + * @brief Returns false if the wrapper does not contain the expected type, + * true otherwise. + * @tparam Type Expected type. + * @return False if the wrapper does not contain the expected type, true + * otherwise. + */ + template + [[nodiscard]] bool has_value() const noexcept { + static_assert(std::is_same_v, Type>, "Invalid type"); + return (underlying_type == type_hash::value()); + } + + /** + * @brief Returns the object type info if any, `type_id()` otherwise. + * @return The object type info if any, `type_id()` otherwise. + */ + [[nodiscard]] const type_info &info() const noexcept { + return *static_cast(vtable(request::info, *this, nullptr)); + } + + /*! @copydoc info */ + [[deprecated("use ::info instead")]] [[nodiscard]] const type_info &type() const noexcept { + return info(); + } + + /** + * @brief Returns an opaque pointer to the contained instance. + * @return An opaque pointer the contained instance, if any. + */ + [[nodiscard]] const void *data() const noexcept { + if constexpr(base_type::has_buffer) { + return (mode == any_policy::embedded) ? &this->buffer : this->instance; + } else { + return this->instance; + } + } + + /** + * @brief Returns an opaque pointer to the contained instance. + * @param req Expected type. + * @return An opaque pointer the contained instance, if any. + */ + [[nodiscard]] const void *data(const type_info &req) const noexcept { + return has_value(req) ? data() : nullptr; + } + + /** + * @brief Returns an opaque pointer to the contained instance. + * @tparam Type Expected type. + * @return An opaque pointer the contained instance, if any. + */ + template + [[nodiscard]] const Type *data() const noexcept { + return has_value>() ? static_cast(data()) : nullptr; + } + + /** + * @brief Returns an opaque pointer to the contained instance. + * @return An opaque pointer the contained instance, if any. + */ + [[nodiscard]] void *data() noexcept { + return (mode == any_policy::cref) ? nullptr : const_cast(std::as_const(*this).data()); + } + + /** + * @brief Returns an opaque pointer to the contained instance. + * @param req Expected type. + * @return An opaque pointer the contained instance, if any. + */ + [[nodiscard]] void *data(const type_info &req) noexcept { + return (mode == any_policy::cref) ? nullptr : const_cast(std::as_const(*this).data(req)); + } + + /** + * @brief Returns an opaque pointer to the contained instance. + * @tparam Type Expected type. + * @return An opaque pointer the contained instance, if any. + */ + template + [[nodiscard]] Type *data() noexcept { + if constexpr(std::is_const_v) { + return std::as_const(*this).template data>(); + } else { + return (mode == any_policy::cref) ? nullptr : const_cast(std::as_const(*this).template data>()); + } + } + + /** + * @brief Replaces the contained object by creating a new instance directly. + * @tparam Type Type of object to use to initialize the wrapper. + * @tparam Args Types of arguments to use to construct the new instance. + * @param args Parameters to use to construct the instance. + */ + template + void emplace(Args &&...args) { + invoke_deleter_if_exists(); + initialize(std::forward(args)...); + } + + /** + * @brief Assigns a value to the contained object without replacing it. + * @param other The value to assign to the contained object. + * @return True in case of success, false otherwise. + */ + bool assign(const basic_any &other) { + if(other && (mode != any_policy::cref) && (underlying_type == other.underlying_type)) { + return (vtable(request::assign, *this, other.data()) != nullptr); + } + + return false; + } + + /*! @copydoc assign */ + // NOLINTNEXTLINE(cppcoreguidelines-rvalue-reference-param-not-moved) + bool assign(basic_any &&other) { + if(other && (mode != any_policy::cref) && (underlying_type == other.underlying_type)) { + return (other.mode == any_policy::cref) ? (vtable(request::assign, *this, std::as_const(other).data()) != nullptr) : (vtable(request::transfer, *this, other.data()) != nullptr); + } + + return false; + } + + /*! @brief Destroys contained object */ + void reset() { + invoke_deleter_if_exists(); + initialize(); + } + + /** + * @brief Returns false if a wrapper is empty, true otherwise. + * @return False if the wrapper is empty, true otherwise. + */ + [[nodiscard]] explicit operator bool() const noexcept { + return has_value(); + } + + /** + * @brief Checks if two wrappers differ in their content. + * @param other Wrapper with which to compare. + * @return False if the two objects differ in their content, true otherwise. + */ + [[nodiscard]] bool operator==(const basic_any &other) const noexcept { + if(other && (underlying_type == other.underlying_type)) { + return (vtable(request::compare, *this, other.data()) != nullptr); + } + + return (!*this && !other); + } + + /** + * @brief Checks if two wrappers differ in their content. + * @param other Wrapper with which to compare. + * @return True if the two objects differ in their content, false otherwise. + */ + [[nodiscard]] bool operator!=(const basic_any &other) const noexcept { + return !(*this == other); + } + + /** + * @brief Aliasing constructor. + * @return A wrapper that shares a reference to an unmanaged object. + */ + [[nodiscard]] basic_any as_ref() noexcept { + basic_any other = std::as_const(*this).as_ref(); + other.mode = (mode == any_policy::cref ? any_policy::cref : any_policy::ref); + return other; + } + + /*! @copydoc as_ref */ + [[nodiscard]] basic_any as_ref() const noexcept { + basic_any other{}; + other.instance = data(); + other.vtable = vtable; + other.underlying_type = underlying_type; + other.mode = any_policy::cref; + return other; + } + + /** + * @brief Returns true if a wrapper owns its object, false otherwise. + * @return True if the wrapper owns its object, false otherwise. + */ + [[nodiscard]] bool owner() const noexcept { + return (mode == any_policy::dynamic || mode == any_policy::embedded); + } + + /** + * @brief Returns the current mode of an any object. + * @return The current mode of the any object. + */ + [[nodiscard]] any_policy policy() const noexcept { + return mode; + } + +private: + vtable_type *vtable{}; + deleter_type *deleter{}; + id_type underlying_type{}; + any_policy mode{}; +}; + +/** + * @brief Performs type-safe access to the contained object. + * @tparam Type Type to which conversion is required. + * @tparam Len Size of the buffer reserved for the small buffer optimization. + * @tparam Align Alignment requirement. + * @param data Target any object. + * @return The element converted to the requested type. + */ +template +[[nodiscard]] std::remove_const_t any_cast(const basic_any &data) noexcept { + const auto *const instance = any_cast>(&data); + ENTT_ASSERT(instance, "Invalid instance"); + return static_cast(*instance); +} + +/*! @copydoc any_cast */ +template +[[nodiscard]] std::remove_const_t any_cast(basic_any &data) noexcept { + // forces const on non-reference types to make them work also with wrappers for const references + auto *const instance = any_cast>(&data); + ENTT_ASSERT(instance, "Invalid instance"); + return static_cast(*instance); +} + +/*! @copydoc any_cast */ +template +// NOLINTNEXTLINE(cppcoreguidelines-rvalue-reference-param-not-moved) +[[nodiscard]] std::remove_const_t any_cast(basic_any &&data) noexcept { + if constexpr(std::is_copy_constructible_v>>) { + if(auto *const instance = any_cast>(&data); instance) { + return static_cast(std::move(*instance)); + } + + return any_cast(data); + } else { + auto *const instance = any_cast>(&data); + ENTT_ASSERT(instance, "Invalid instance"); + return static_cast(std::move(*instance)); + } +} + +/*! @copydoc any_cast */ +template +[[nodiscard]] const Type *any_cast(const basic_any *data) noexcept { + return data->template data>(); +} + +/*! @copydoc any_cast */ +template +[[nodiscard]] Type *any_cast(basic_any *data) noexcept { + if constexpr(std::is_const_v) { + // last attempt to make wrappers for const references return their values + return any_cast(&std::as_const(*data)); + } else { + return data->template data(); + } +} + +/** + * @brief Constructs a wrapper from a given type, passing it all arguments. + * @tparam Type Type of object to use to initialize the wrapper. + * @tparam Len Size of the buffer reserved for the small buffer optimization. + * @tparam Align Optional alignment requirement. + * @tparam Args Types of arguments to use to construct the new instance. + * @param args Parameters to use to construct the instance. + * @return A properly initialized wrapper for an object of the given type. + */ +template::length, std::size_t Align = basic_any::alignment, typename... Args> +[[nodiscard]] basic_any make_any(Args &&...args) { + return basic_any{std::in_place_type, std::forward(args)...}; +} + +/** + * @brief Forwards its argument and avoids copies for lvalue references. + * @tparam Len Size of the buffer reserved for the small buffer optimization. + * @tparam Align Optional alignment requirement. + * @tparam Type Type of argument to use to construct the new instance. + * @param value Parameter to use to construct the instance. + * @return A properly initialized and not necessarily owning wrapper. + */ +template::length, std::size_t Align = basic_any::alignment, typename Type> +[[nodiscard]] basic_any forward_as_any(Type &&value) { + return basic_any{std::in_place_type, std::forward(value)}; +} + +} // namespace entt + +#endif + +// #include "../core/fwd.hpp" + +// #include "../core/iterator.hpp" +#ifndef ENTT_CORE_ITERATOR_HPP +#define ENTT_CORE_ITERATOR_HPP + +#include +#include +#include +#include + +namespace entt { + +/** + * @brief Helper type to use as pointer with input iterators. + * @tparam Type of wrapped value. + */ +template +struct input_iterator_pointer final { + /*! @brief Value type. */ + using value_type = Type; + /*! @brief Pointer type. */ + using pointer = Type *; + /*! @brief Reference type. */ + using reference = Type &; + + /** + * @brief Constructs a proxy object by move. + * @param val Value to use to initialize the proxy object. + */ + constexpr input_iterator_pointer(value_type &&val) noexcept(std::is_nothrow_move_constructible_v) + : value{std::move(val)} {} + + /** + * @brief Access operator for accessing wrapped values. + * @return A pointer to the wrapped value. + */ + [[nodiscard]] constexpr pointer operator->() noexcept { + return std::addressof(value); + } + + /** + * @brief Dereference operator for accessing wrapped values. + * @return A reference to the wrapped value. + */ + [[nodiscard]] constexpr reference operator*() noexcept { + return value; + } + +private: + Type value; +}; + +/** + * @brief Plain iota iterator (waiting for C++20). + * @tparam Type Value type. + */ +template +class iota_iterator final { + static_assert(std::is_integral_v, "Not an integral type"); + +public: + /*! @brief Value type, likely an integral one. */ + using value_type = Type; + /*! @brief Invalid pointer type. */ + using pointer = void; + /*! @brief Non-reference type, same as value type. */ + using reference = value_type; + /*! @brief Difference type. */ + using difference_type = std::ptrdiff_t; + /*! @brief Iterator category. */ + using iterator_category = std::input_iterator_tag; + + /*! @brief Default constructor. */ + constexpr iota_iterator() noexcept + : current{} {} + + /** + * @brief Constructs an iota iterator from a given value. + * @param init The initial value assigned to the iota iterator. + */ + constexpr iota_iterator(const value_type init) noexcept + : current{init} {} + + /** + * @brief Pre-increment operator. + * @return This iota iterator. + */ + constexpr iota_iterator &operator++() noexcept { + return ++current, *this; + } + + /** + * @brief Post-increment operator. + * @return This iota iterator. + */ + constexpr iota_iterator operator++(int) noexcept { + const iota_iterator orig = *this; + return ++(*this), orig; + } + + /** + * @brief Dereference operator. + * @return The underlying value. + */ + [[nodiscard]] constexpr reference operator*() const noexcept { + return current; + } + +private: + value_type current; +}; + +/** + * @brief Comparison operator. + * @tparam Type Value type of the iota iterator. + * @param lhs A properly initialized iota iterator. + * @param rhs A properly initialized iota iterator. + * @return True if the two iterators are identical, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator==(const iota_iterator &lhs, const iota_iterator &rhs) noexcept { + return *lhs == *rhs; +} + +/** + * @brief Comparison operator. + * @tparam Type Value type of the iota iterator. + * @param lhs A properly initialized iota iterator. + * @param rhs A properly initialized iota iterator. + * @return True if the two iterators differ, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator!=(const iota_iterator &lhs, const iota_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +/** + * @brief Utility class to create an iterable object from a pair of iterators. + * @tparam It Type of iterator. + * @tparam Sentinel Type of sentinel. + */ +template +struct iterable_adaptor final { + /*! @brief Value type. */ + using value_type = typename std::iterator_traits::value_type; + /*! @brief Iterator type. */ + using iterator = It; + /*! @brief Sentinel type. */ + using sentinel = Sentinel; + + /*! @brief Default constructor. */ + constexpr iterable_adaptor() noexcept(std::is_nothrow_default_constructible_v && std::is_nothrow_default_constructible_v) + : first{}, + last{} {} + + /** + * @brief Creates an iterable object from a pair of iterators. + * @param from Begin iterator. + * @param to End iterator. + */ + constexpr iterable_adaptor(iterator from, sentinel to) noexcept(std::is_nothrow_move_constructible_v && std::is_nothrow_move_constructible_v) + : first{std::move(from)}, + last{std::move(to)} {} + + /** + * @brief Returns an iterator to the beginning. + * @return An iterator to the first element of the range. + */ + [[nodiscard]] constexpr iterator begin() const noexcept { + return first; + } + + /** + * @brief Returns an iterator to the end. + * @return An iterator to the element following the last element of the + * range. + */ + [[nodiscard]] constexpr sentinel end() const noexcept { + return last; + } + + /*! @copydoc begin */ + [[nodiscard]] constexpr iterator cbegin() const noexcept { + return begin(); + } + + /*! @copydoc end */ + [[nodiscard]] constexpr sentinel cend() const noexcept { + return end(); + } + +private: + It first; + Sentinel last; +}; + +} // namespace entt + +#endif + +// #include "../core/type_info.hpp" +#ifndef ENTT_CORE_TYPE_INFO_HPP +#define ENTT_CORE_TYPE_INFO_HPP + +#include +#include +#include +// #include "../config/config.h" + +// #include "fwd.hpp" + +// #include "hashed_string.hpp" + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +struct ENTT_API type_index final { + [[nodiscard]] static id_type next() noexcept { + static ENTT_MAYBE_ATOMIC(id_type) value{}; + return value++; + } +}; + +template +[[nodiscard]] constexpr const char *pretty_function() noexcept { +#if defined ENTT_PRETTY_FUNCTION + return static_cast(ENTT_PRETTY_FUNCTION); +#else + return ""; +#endif +} + +template +[[nodiscard]] constexpr auto stripped_type_name() noexcept { +#if defined ENTT_PRETTY_FUNCTION + const std::string_view full_name{pretty_function()}; + auto first = full_name.find_first_not_of(' ', full_name.find_first_of(ENTT_PRETTY_FUNCTION_PREFIX) + 1); + auto value = full_name.substr(first, full_name.find_last_of(ENTT_PRETTY_FUNCTION_SUFFIX) - first); + return value; +#else + return std::string_view{}; +#endif +} + +template().find_first_of('.')> +[[nodiscard]] constexpr std::string_view type_name(int) noexcept { + constexpr auto value = stripped_type_name(); + return value; +} + +template +[[nodiscard]] std::string_view type_name(char) noexcept { + static const auto value = stripped_type_name(); + return value; +} + +template().find_first_of('.')> +[[nodiscard]] constexpr id_type type_hash(int) noexcept { + constexpr auto stripped = stripped_type_name(); + constexpr auto value = hashed_string::value(stripped.data(), stripped.size()); + return value; +} + +template +[[nodiscard]] id_type type_hash(char) noexcept { + static const auto value = [](const auto stripped) { + return hashed_string::value(stripped.data(), stripped.size()); + }(stripped_type_name()); + return value; +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Type sequential identifier. + * @tparam Type Type for which to generate a sequential identifier. + */ +template +struct ENTT_API type_index final { + /** + * @brief Returns the sequential identifier of a given type. + * @return The sequential identifier of a given type. + */ + [[nodiscard]] static id_type value() noexcept { + static const id_type value = internal::type_index::next(); + return value; + } + + /*! @copydoc value */ + [[nodiscard]] constexpr operator id_type() const noexcept { + return value(); + } +}; + +/** + * @brief Type hash. + * @tparam Type Type for which to generate a hash value. + */ +template +struct type_hash final { + /** + * @brief Returns the numeric representation of a given type. + * @return The numeric representation of the given type. + */ +#if defined ENTT_PRETTY_FUNCTION + [[nodiscard]] static constexpr id_type value() noexcept { + return internal::type_hash(0); +#else + [[nodiscard]] static constexpr id_type value() noexcept { + return type_index::value(); +#endif + } + + /*! @copydoc value */ + [[nodiscard]] constexpr operator id_type() const noexcept { + return value(); + } +}; + +/** + * @brief Type name. + * @tparam Type Type for which to generate a name. + */ +template +struct type_name final { + /** + * @brief Returns the name of a given type. + * @return The name of the given type. + */ + [[nodiscard]] static constexpr std::string_view value() noexcept { + return internal::type_name(0); + } + + /*! @copydoc value */ + [[nodiscard]] constexpr operator std::string_view() const noexcept { + return value(); + } +}; + +/*! @brief Implementation specific information about a type. */ +struct type_info final { + /** + * @brief Constructs a type info object for a given type. + * @tparam Type Type for which to construct a type info object. + */ + template + // NOLINTBEGIN(modernize-use-transparent-functors) + constexpr type_info(std::in_place_type_t) noexcept + : seq{type_index>>::value()}, + identifier{type_hash>>::value()}, + alias{type_name>>::value()} {} + // NOLINTEND(modernize-use-transparent-functors) + + /** + * @brief Type index. + * @return Type index. + */ + [[nodiscard]] constexpr id_type index() const noexcept { + return seq; + } + + /** + * @brief Type hash. + * @return Type hash. + */ + [[nodiscard]] constexpr id_type hash() const noexcept { + return identifier; + } + + /** + * @brief Type name. + * @return Type name. + */ + [[nodiscard]] constexpr std::string_view name() const noexcept { + return alias; + } + +private: + id_type seq; + id_type identifier; + std::string_view alias; +}; + +/** + * @brief Compares the contents of two type info objects. + * @param lhs A type info object. + * @param rhs A type info object. + * @return True if the two type info objects are identical, false otherwise. + */ +[[nodiscard]] constexpr bool operator==(const type_info &lhs, const type_info &rhs) noexcept { + return lhs.hash() == rhs.hash(); +} + +/** + * @brief Compares the contents of two type info objects. + * @param lhs A type info object. + * @param rhs A type info object. + * @return True if the two type info objects differ, false otherwise. + */ +[[nodiscard]] constexpr bool operator!=(const type_info &lhs, const type_info &rhs) noexcept { + return !(lhs == rhs); +} + +/** + * @brief Compares two type info objects. + * @param lhs A valid type info object. + * @param rhs A valid type info object. + * @return True if the first element is less than the second, false otherwise. + */ +[[nodiscard]] constexpr bool operator<(const type_info &lhs, const type_info &rhs) noexcept { + return lhs.index() < rhs.index(); +} + +/** + * @brief Compares two type info objects. + * @param lhs A valid type info object. + * @param rhs A valid type info object. + * @return True if the first element is less than or equal to the second, false + * otherwise. + */ +[[nodiscard]] constexpr bool operator<=(const type_info &lhs, const type_info &rhs) noexcept { + return !(rhs < lhs); +} + +/** + * @brief Compares two type info objects. + * @param lhs A valid type info object. + * @param rhs A valid type info object. + * @return True if the first element is greater than the second, false + * otherwise. + */ +[[nodiscard]] constexpr bool operator>(const type_info &lhs, const type_info &rhs) noexcept { + return rhs < lhs; +} + +/** + * @brief Compares two type info objects. + * @param lhs A valid type info object. + * @param rhs A valid type info object. + * @return True if the first element is greater than or equal to the second, + * false otherwise. + */ +[[nodiscard]] constexpr bool operator>=(const type_info &lhs, const type_info &rhs) noexcept { + return !(lhs < rhs); +} + +/** + * @brief Returns the type info object associated to a given type. + * + * The returned element refers to an object with static storage duration.
+ * The type doesn't need to be a complete type. If the type is a reference, the + * result refers to the referenced type. In all cases, top-level cv-qualifiers + * are ignored. + * + * @tparam Type Type for which to generate a type info object. + * @return A reference to a properly initialized type info object. + */ +template +[[nodiscard]] const type_info &type_id() noexcept { + if constexpr(std::is_same_v>>) { + static const type_info instance{std::in_place_type}; + return instance; + } else { + return type_id>>(); + } +} + +/*! @copydoc type_id */ +template +// NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward) +[[nodiscard]] const type_info &type_id(Type &&) noexcept { + return type_id>>(); +} + +} // namespace entt + +#endif + +// #include "../core/type_traits.hpp" + +// #include "../core/utility.hpp" + +// #include "../locator/locator.hpp" +#ifndef ENTT_LOCATOR_LOCATOR_HPP +#define ENTT_LOCATOR_LOCATOR_HPP + +#include +#include +// #include "../config/config.h" +#ifndef ENTT_CONFIG_CONFIG_H +#define ENTT_CONFIG_CONFIG_H + +// #include "version.h" +#ifndef ENTT_CONFIG_VERSION_H +#define ENTT_CONFIG_VERSION_H + +// #include "macro.h" +#ifndef ENTT_CONFIG_MACRO_H +#define ENTT_CONFIG_MACRO_H + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#define ENTT_STR(arg) #arg +#define ENTT_XSTR(arg) ENTT_STR(arg) + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*) + +#define ENTT_VERSION_MAJOR 3 +#define ENTT_VERSION_MINOR 16 +#define ENTT_VERSION_PATCH 0 + +#define ENTT_VERSION \ + ENTT_XSTR(ENTT_VERSION_MAJOR) \ + "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH) + +// NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION) +# define ENTT_CONSTEXPR +# define ENTT_THROW throw +# define ENTT_TRY try +# define ENTT_CATCH catch(...) +#else +# define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20) +# define ENTT_THROW +# define ENTT_TRY if(true) +# define ENTT_CATCH if(false) +#endif + +#if __has_include() +# include +# +# if defined(__cpp_consteval) +# define ENTT_CONSTEVAL consteval +# endif +#endif + +#ifndef ENTT_CONSTEVAL +# define ENTT_CONSTEVAL constexpr +#endif + +#ifdef ENTT_USE_ATOMIC +# include +# define ENTT_MAYBE_ATOMIC(Type) std::atomic +#else +# define ENTT_MAYBE_ATOMIC(Type) Type +#endif + +#ifndef ENTT_ID_TYPE +# include +# define ENTT_ID_TYPE std::uint32_t +#else +# include // provides coverage for types in the std namespace +#endif + +#ifndef ENTT_SPARSE_PAGE +# define ENTT_SPARSE_PAGE 4096 +#endif + +#ifndef ENTT_PACKED_PAGE +# define ENTT_PACKED_PAGE 1024 +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT +# define ENTT_ASSERT(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT +# include +# define ENTT_ASSERT(condition, msg) assert(((condition) && (msg))) +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg) +#endif + +#define ENTT_FAIL(msg) ENTT_ASSERT(false, msg); + +#ifdef ENTT_NO_ETO +# define ENTT_ETO_TYPE(Type) void +#else +# define ENTT_ETO_TYPE(Type) Type +#endif + +#ifdef ENTT_NO_MIXIN +# define ENTT_STORAGE(Mixin, ...) __VA_ARGS__ +#else +# define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__> +#endif + +#ifdef ENTT_STANDARD_CPP +# define ENTT_NONSTD false +#else +# define ENTT_NONSTD true +# if defined __clang__ || defined __GNUC__ +# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ +# define ENTT_PRETTY_FUNCTION_PREFIX '=' +# define ENTT_PRETTY_FUNCTION_SUFFIX ']' +# elif defined _MSC_VER +# define ENTT_PRETTY_FUNCTION __FUNCSIG__ +# define ENTT_PRETTY_FUNCTION_PREFIX '<' +# define ENTT_PRETTY_FUNCTION_SUFFIX '>' +# endif +#endif + +#ifndef ENTT_EXPORT +# if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER +# define ENTT_EXPORT __declspec(dllexport) +# define ENTT_IMPORT __declspec(dllimport) +# define ENTT_HIDDEN +# elif defined __GNUC__ && __GNUC__ >= 4 +# define ENTT_EXPORT __attribute__((visibility("default"))) +# define ENTT_IMPORT __attribute__((visibility("default"))) +# define ENTT_HIDDEN __attribute__((visibility("hidden"))) +# else /* Unsupported compiler */ +# define ENTT_EXPORT +# define ENTT_IMPORT +# define ENTT_HIDDEN +# endif +#endif + +#ifndef ENTT_API +# if defined ENTT_API_EXPORT +# define ENTT_API ENTT_EXPORT +# elif defined ENTT_API_IMPORT +# define ENTT_API ENTT_IMPORT +# else /* No API */ +# define ENTT_API +# endif +#endif + +#if defined _MSC_VER +# pragma detect_mismatch("entt.version", ENTT_VERSION) +# pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY)) +# pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE)) +# pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD)) +#endif + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +namespace entt { + +/** + * @brief Service locator, nothing more. + * + * A service locator is used to do what it promises: locate services.
+ * Usually service locators are tightly bound to the services they expose and + * thus it's hard to define a general purpose class to do that. This tiny class + * tries to fill the gap and to get rid of the burden of defining a different + * specific locator for each application. + * + * @note + * Users shouldn't retain references to a service. The recommended way is to + * retrieve the service implementation currently set each and every time the + * need for it arises. The risk is to incur in unexpected behaviors otherwise. + * + * @tparam Service Service type. + */ +template +class locator final { + class service_handle { + friend class locator; + std::shared_ptr value{}; + }; + +public: + /*! @brief Service type. */ + using type = Service; + /*! @brief Service node type. */ + using node_type = service_handle; + + /*! @brief Default constructor, deleted on purpose. */ + locator() = delete; + + /*! @brief Default copy constructor, deleted on purpose. */ + locator(const locator &) = delete; + + /*! @brief Default destructor, deleted on purpose. */ + ~locator() = delete; + + /** + * @brief Default copy assignment operator, deleted on purpose. + * @return This locator. + */ + locator &operator=(const locator &) = delete; + + /** + * @brief Checks whether a service locator contains a value. + * @return True if the service locator contains a value, false otherwise. + */ + [[nodiscard]] static bool has_value() noexcept { + return (service != nullptr); + } + + /** + * @brief Returns a reference to a valid service, if any. + * + * @warning + * Invoking this function can result in undefined behavior if the service + * hasn't been set yet. + * + * @return A reference to the service currently set, if any. + */ + [[nodiscard]] static Service &value() noexcept { + ENTT_ASSERT(has_value(), "Service not available"); + return *service; + } + + /** + * @brief Returns a service if available or sets it from a fallback type. + * + * Arguments are used only if a service doesn't already exist. In all other + * cases, they are discarded. + * + * @tparam Args Types of arguments to use to construct the fallback service. + * @tparam Type Fallback service type. + * @param args Parameters to use to construct the fallback service. + * @return A reference to a valid service. + */ + template + [[nodiscard]] static Service &value_or(Args &&...args) { + return service ? *service : emplace(std::forward(args)...); + } + + /** + * @brief Sets or replaces a service. + * @tparam Type Service type. + * @tparam Args Types of arguments to use to construct the service. + * @param args Parameters to use to construct the service. + * @return A reference to a valid service. + */ + template + static Service &emplace(Args &&...args) { + service = std::make_shared(std::forward(args)...); + return *service; + } + + /** + * @brief Sets or replaces a service using a given allocator. + * @tparam Type Service type. + * @tparam Allocator Type of allocator used to manage memory and elements. + * @tparam Args Types of arguments to use to construct the service. + * @param alloc The allocator to use. + * @param args Parameters to use to construct the service. + * @return A reference to a valid service. + */ + template + static Service &emplace(std::allocator_arg_t, Allocator alloc, Args &&...args) { + service = std::allocate_shared(alloc, std::forward(args)...); + return *service; + } + + /** + * @brief Returns a handle to the underlying service. + * @return A handle to the underlying service. + */ + static node_type handle() noexcept { + node_type node{}; + node.value = service; + return node; + } + + /** + * @brief Resets or replaces a service. + * @param other Optional handle with which to replace the service. + */ + static void reset(const node_type &other = {}) noexcept { + service = other.value; + } + + /** + * @brief Resets or replaces a service. + * @tparam Type Service type. + * @tparam Deleter Deleter type. + * @param elem A pointer to a service to manage. + * @param deleter A deleter to use to destroy the service. + */ + template> + static void reset(Type *elem, Deleter deleter = {}) { + service = std::shared_ptr{elem, std::move(deleter)}; + } + +private: + // std::shared_ptr because of its type erased allocator which is useful here + // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) + inline static std::shared_ptr service{}; +}; + +} // namespace entt + +#endif + +// #include "adl_pointer.hpp" +#ifndef ENTT_META_ADL_POINTER_HPP +#define ENTT_META_ADL_POINTER_HPP + +namespace entt { + +/** + * @brief ADL based lookup function for dereferencing meta pointer-like types. + * @tparam Type Element type. + * @param value A pointer-like object. + * @return The value returned from the dereferenced pointer. + */ +template +decltype(auto) dereference_meta_pointer_like(const Type &value) { + return *value; +} + +/** + * @brief Fake ADL based lookup function for meta pointer-like types. + * @tparam Type Element type. + */ +template +struct adl_meta_pointer_like { + /** + * @brief Uses the default ADL based lookup method to resolve the call. + * @param value A pointer-like object. + * @return The value returned from the dereferenced pointer. + */ + static decltype(auto) dereference(const Type &value) { + return dereference_meta_pointer_like(value); + } +}; + +} // namespace entt + +#endif + +// #include "context.hpp" + +// #include "fwd.hpp" + +// #include "node.hpp" +#ifndef ENTT_META_NODE_HPP +#define ENTT_META_NODE_HPP + +#include +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "../core/bit.hpp" +#ifndef ENTT_CORE_BIT_HPP +#define ENTT_CORE_BIT_HPP + +#include +#include +#include +// #include "../config/config.h" + + +namespace entt { + +/** + * @brief Returns the number of set bits in a value (waiting for C++20 and + * `std::popcount`). + * @tparam Type Unsigned integer type. + * @param value A value of unsigned integer type. + * @return The number of set bits in the value. + */ +template +[[nodiscard]] constexpr std::enable_if_t, int> popcount(const Type value) noexcept { + return value ? (int(value & 1) + popcount(static_cast(value >> 1))) : 0; +} + +/** + * @brief Checks whether a value is a power of two or not (waiting for C++20 and + * `std::has_single_bit`). + * @tparam Type Unsigned integer type. + * @param value A value of unsigned integer type. + * @return True if the value is a power of two, false otherwise. + */ +template +[[nodiscard]] constexpr std::enable_if_t, bool> has_single_bit(const Type value) noexcept { + return value && ((value & (value - 1)) == 0); +} + +/** + * @brief Computes the smallest power of two greater than or equal to a value + * (waiting for C++20 and `std::bit_ceil`). + * @tparam Type Unsigned integer type. + * @param value A value of unsigned integer type. + * @return The smallest power of two greater than or equal to the given value. + */ +template +[[nodiscard]] constexpr std::enable_if_t, Type> next_power_of_two(const Type value) noexcept { + // NOLINTNEXTLINE(bugprone-assert-side-effect) + ENTT_ASSERT_CONSTEXPR(value < (Type{1u} << (std::numeric_limits::digits - 1)), "Numeric limits exceeded"); + Type curr = value - (value != 0u); + + for(int next = 1; next < std::numeric_limits::digits; next = next * 2) { + curr |= (curr >> next); + } + + return ++curr; +} + +/** + * @brief Fast module utility function (powers of two only). + * @tparam Type Unsigned integer type. + * @param value A value of unsigned integer type. + * @param mod _Modulus_, it must be a power of two. + * @return The common remainder. + */ +template +[[nodiscard]] constexpr std::enable_if_t, Type> fast_mod(const Type value, const std::size_t mod) noexcept { + ENTT_ASSERT_CONSTEXPR(has_single_bit(mod), "Value must be a power of two"); + return static_cast(value & (mod - 1u)); +} + +} // namespace entt + +#endif + +// #include "../core/enum.hpp" +#ifndef ENTT_CORE_ENUM_HPP +#define ENTT_CORE_ENUM_HPP + +#include + +namespace entt { + +/** + * @brief Enable bitmask support for enum classes. + * @tparam Type The enum type for which to enable bitmask support. + */ +template +struct enum_as_bitmask: std::false_type {}; + +/*! @copydoc enum_as_bitmask */ +template +struct enum_as_bitmask>: std::is_enum {}; + +/** + * @brief Helper variable template. + * @tparam Type The enum class type for which to enable bitmask support. + */ +template +inline constexpr bool enum_as_bitmask_v = enum_as_bitmask::value; + +} // namespace entt + +/** + * @brief Operator available for enums for which bitmask support is enabled. + * @tparam Type Enum class type. + * @param lhs The first value to use. + * @param rhs The second value to use. + * @return The result of invoking the operator on the underlying types of the + * two values provided. + */ +template +[[nodiscard]] constexpr std::enable_if_t, Type> +operator|(const Type lhs, const Type rhs) noexcept { + return static_cast(static_cast>(lhs) | static_cast>(rhs)); +} + +/*! @copydoc operator| */ +template +[[nodiscard]] constexpr std::enable_if_t, Type> +operator&(const Type lhs, const Type rhs) noexcept { + return static_cast(static_cast>(lhs) & static_cast>(rhs)); +} + +/*! @copydoc operator| */ +template +[[nodiscard]] constexpr std::enable_if_t, Type> +operator^(const Type lhs, const Type rhs) noexcept { + return static_cast(static_cast>(lhs) ^ static_cast>(rhs)); +} + +/** + * @brief Operator available for enums for which bitmask support is enabled. + * @tparam Type Enum class type. + * @param value The value to use. + * @return The result of invoking the operator on the underlying types of the + * value provided. + */ +template +[[nodiscard]] constexpr std::enable_if_t, Type> +operator~(const Type value) noexcept { + return static_cast(~static_cast>(value)); +} + +/*! @copydoc operator~ */ +template +[[nodiscard]] constexpr std::enable_if_t, bool> +operator!(const Type value) noexcept { + return !static_cast>(value); +} + +/*! @copydoc operator| */ +template +constexpr std::enable_if_t, Type &> +operator|=(Type &lhs, const Type rhs) noexcept { + return (lhs = (lhs | rhs)); +} + +/*! @copydoc operator| */ +template +constexpr std::enable_if_t, Type &> +operator&=(Type &lhs, const Type rhs) noexcept { + return (lhs = (lhs & rhs)); +} + +/*! @copydoc operator| */ +template +constexpr std::enable_if_t, Type &> +operator^=(Type &lhs, const Type rhs) noexcept { + return (lhs = (lhs ^ rhs)); +} + +#endif + +// #include "../core/fwd.hpp" + +// #include "../core/type_info.hpp" + +// #include "../core/type_traits.hpp" + +// #include "../core/utility.hpp" + +// #include "context.hpp" + +// #include "type_traits.hpp" +#ifndef ENTT_META_TYPE_TRAITS_HPP +#define ENTT_META_TYPE_TRAITS_HPP + +#include +#include + +namespace entt { + +/** + * @brief Traits class template to be specialized to enable support for meta + * template information. + */ +template +struct meta_template_traits; + +/** + * @brief Traits class template to be specialized to enable support for meta + * sequence containers. + */ +template +struct meta_sequence_container_traits; + +/** + * @brief Traits class template to be specialized to enable support for meta + * associative containers. + */ +template +struct meta_associative_container_traits; + +/** + * @brief Provides the member constant `value` to true if a given type is a + * pointer-like type from the point of view of the meta system, false otherwise. + */ +template +struct is_meta_pointer_like: std::false_type {}; + +/** + * @brief Partial specialization to ensure that const pointer-like types are + * also accepted. + * @tparam Type Potentially pointer-like type. + */ +template +struct is_meta_pointer_like: is_meta_pointer_like {}; + +/** + * @brief Helper variable template. + * @tparam Type Potentially pointer-like type. + */ +template +inline constexpr auto is_meta_pointer_like_v = is_meta_pointer_like::value; + +} // namespace entt + +#endif + + +namespace entt { + +class meta_any; +class meta_type; +class meta_handle; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +enum class meta_traits : std::uint32_t { + is_none = 0x0000, + is_const = 0x0001, + is_static = 0x0002, + is_arithmetic = 0x0004, + is_integral = 0x0008, + is_signed = 0x0010, + is_array = 0x0020, + is_enum = 0x0040, + is_class = 0x0080, + is_pointer = 0x0100, + is_pointer_like = 0x0200, + is_sequence_container = 0x0400, + is_associative_container = 0x0800, + _user_defined_traits = 0xFFFF, + _entt_enum_as_bitmask = 0xFFFF +}; + +template +[[nodiscard]] auto meta_to_user_traits(const meta_traits traits) noexcept { + static_assert(std::is_enum_v, "Invalid enum type"); + constexpr auto shift = popcount(static_cast>(meta_traits::_user_defined_traits)); + return Type{static_cast>(static_cast>(traits) >> shift)}; +} + +template +[[nodiscard]] auto user_to_meta_traits(const Type value) noexcept { + static_assert(std::is_enum_v, "Invalid enum type"); + constexpr auto shift = popcount(static_cast>(meta_traits::_user_defined_traits)); + const auto traits = static_cast>(static_cast>(value)); + ENTT_ASSERT(traits < ((~static_cast>(meta_traits::_user_defined_traits)) >> shift), "Invalid traits"); + return meta_traits{traits << shift}; +} + +struct meta_type_node; + +struct meta_custom_node { + id_type type{}; + std::shared_ptr value{}; +}; + +struct meta_base_node { + id_type type{}; + const meta_type_node &(*resolve)(const meta_context &) noexcept {}; + const void *(*cast)(const void *) noexcept {}; +}; + +struct meta_conv_node { + id_type type{}; + meta_any (*conv)(const meta_ctx &, const void *){}; +}; + +struct meta_ctor_node { + using size_type = std::size_t; + + id_type id{}; + size_type arity{0u}; + meta_type (*arg)(const meta_ctx &, const size_type) noexcept {}; + meta_any (*invoke)(const meta_ctx &, meta_any *const){}; +}; + +struct meta_data_node { + using size_type = std::size_t; + + id_type id{}; + const char *name{}; + meta_traits traits{meta_traits::is_none}; + size_type arity{0u}; + const meta_type_node &(*type)(const meta_context &) noexcept {}; + meta_type (*arg)(const meta_ctx &, const size_type) noexcept {}; + bool (*set)(meta_handle, meta_any){}; + meta_any (*get)(meta_handle){}; + meta_custom_node custom{}; +}; + +struct meta_func_node { + using size_type = std::size_t; + + id_type id{}; + const char *name{}; + meta_traits traits{meta_traits::is_none}; + size_type arity{0u}; + const meta_type_node &(*ret)(const meta_context &) noexcept {}; + meta_type (*arg)(const meta_ctx &, const size_type) noexcept {}; + meta_any (*invoke)(meta_handle, meta_any *const){}; + std::unique_ptr next; + meta_custom_node custom{}; +}; + +struct meta_template_node { + using size_type = std::size_t; + + size_type arity{0u}; + const meta_type_node &(*resolve)(const meta_context &) noexcept {}; + const meta_type_node &(*arg)(const meta_context &, const size_type) noexcept {}; +}; + +struct meta_type_descriptor { + std::vector ctor{}; + std::vector base{}; + std::vector conv{}; + std::vector data{}; + std::vector func{}; +}; + +struct meta_type_node { + using size_type = std::size_t; + + const type_info *info{}; + id_type id{}; + const char *name{}; + meta_traits traits{meta_traits::is_none}; + size_type size_of{0u}; + const meta_type_node &(*remove_pointer)(const meta_context &) noexcept {}; + meta_any (*default_constructor)(const meta_ctx &){}; + double (*conversion_helper)(void *, const void *){}; + meta_any (*from_void)(const meta_ctx &, void *, const void *){}; + meta_template_node templ{}; + meta_custom_node custom{}; + std::unique_ptr details{}; +}; + +template +[[nodiscard]] auto *find_member(Type &from, const Value value) { + for(auto &&elem: from) { + if((elem.*Member) == value) { + return &elem; + } + } + + return static_cast(nullptr); +} + +[[nodiscard]] inline auto *find_overload(meta_func_node *curr, std::remove_pointer_t *const ref) { + while((curr != nullptr) && (curr->invoke != ref)) { curr = curr->next.get(); } + return curr; +} + +template +[[nodiscard]] auto *look_for(const meta_context &context, const meta_type_node &node, const id_type id, bool recursive) { + using value_type = typename std::remove_reference_t*Member))>::value_type; + + if(node.details) { + if(auto *member = find_member<&value_type::id>((node.details.get()->*Member), id); member != nullptr) { + return member; + } + + if(recursive) { + for(auto &&curr: node.details->base) { + if(auto *elem = look_for(context, curr.resolve(context), id, recursive); elem) { + return elem; + } + } + } + } + + return static_cast(nullptr); +} + +template +const meta_type_node &resolve(const meta_context &) noexcept; + +template +[[nodiscard]] const meta_type_node &meta_arg_node(const meta_context &context, type_list, const std::size_t index) noexcept { + using resolve_type = const meta_type_node &(*)(const meta_context &) noexcept; + constexpr std::array list{&resolve>>...}; + ENTT_ASSERT(index < sizeof...(Args), "Out of bounds"); + return list[index](context); +} + +[[nodiscard]] inline const void *try_cast(const meta_context &context, const meta_type_node &from, const id_type to, const void *instance) noexcept { + if(from.details) { + for(auto &&curr: from.details->base) { + if(const void *other = curr.cast(instance); curr.type == to) { + return other; + } else if(const void *elem = try_cast(context, curr.resolve(context), to, other); elem) { + return elem; + } + } + } + + return nullptr; +} + +template +auto setup_node_for() noexcept { + meta_type_node node{ + &type_id(), + type_id().hash(), + nullptr, + (std::is_arithmetic_v ? meta_traits::is_arithmetic : meta_traits::is_none) + | (std::is_integral_v ? meta_traits::is_integral : meta_traits::is_none) + | (std::is_signed_v ? meta_traits::is_signed : meta_traits::is_none) + | (std::is_array_v ? meta_traits::is_array : meta_traits::is_none) + | (std::is_enum_v ? meta_traits::is_enum : meta_traits::is_none) + | (std::is_class_v ? meta_traits::is_class : meta_traits::is_none) + | (std::is_pointer_v ? meta_traits::is_pointer : meta_traits::is_none) + | (is_meta_pointer_like_v ? meta_traits::is_pointer_like : meta_traits::is_none) + | (is_complete_v> ? meta_traits::is_sequence_container : meta_traits::is_none) + | (is_complete_v> ? meta_traits::is_associative_container : meta_traits::is_none), + size_of_v, + &resolve>>}; + + if constexpr(std::is_default_constructible_v) { + node.default_constructor = +[](const meta_ctx &ctx) { + return meta_any{ctx, std::in_place_type}; + }; + } + + if constexpr(std::is_arithmetic_v) { + node.conversion_helper = +[](void *lhs, const void *rhs) { + return lhs ? static_cast(*static_cast(lhs) = static_cast(*static_cast(rhs))) : static_cast(*static_cast(rhs)); + }; + } else if constexpr(std::is_enum_v) { + node.conversion_helper = +[](void *lhs, const void *rhs) { + return lhs ? static_cast(*static_cast(lhs) = static_cast(static_cast>(*static_cast(rhs)))) : static_cast(*static_cast(rhs)); + }; + } + + if constexpr(!std::is_void_v && !std::is_function_v) { + node.from_void = +[](const meta_ctx &ctx, void *elem, const void *celem) { + if(elem && celem) { // ownership construction request + return meta_any{ctx, std::in_place, static_cast *>(elem)}; + } + + if(elem) { // non-const reference construction request + return meta_any{ctx, std::in_place_type &>, *static_cast *>(elem)}; + } + + // const reference construction request + return meta_any{ctx, std::in_place_type &>, *static_cast *>(celem)}; + }; + } + + if constexpr(is_complete_v>) { + node.templ = meta_template_node{ + meta_template_traits::args_type::size, + &resolve::class_type>, + +[](const meta_context &area, const std::size_t index) noexcept -> decltype(auto) { return meta_arg_node(area, typename meta_template_traits::args_type{}, index); }}; + } + + return node; +} + +[[nodiscard]] inline const meta_type_node *try_resolve(const meta_context &context, const type_info &info) noexcept { + const auto it = context.value.find(info.hash()); + return (it != context.value.end()) ? it->second.get() : nullptr; +} + +template +[[nodiscard]] const meta_type_node &resolve(const meta_context &context) noexcept { + static_assert(std::is_same_v>>, "Invalid type"); + static const meta_type_node node = setup_node_for(); + const auto *elem = try_resolve(context, *node.info); + return (elem == nullptr) ? node : *elem; +} + +} // namespace internal +/*! @endcond */ + +} // namespace entt + +#endif + +// #include "range.hpp" +#ifndef ENTT_META_RANGE_HPP +#define ENTT_META_RANGE_HPP + +#include +#include +#include +// #include "../core/fwd.hpp" + +// #include "../core/iterator.hpp" + +// #include "context.hpp" + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +struct meta_base_node; + +template +struct meta_range_iterator final { + using value_type = std::pair; + using pointer = input_iterator_pointer; + using reference = value_type; + using difference_type = std::ptrdiff_t; + using iterator_category = std::input_iterator_tag; + using iterator_concept = std::random_access_iterator_tag; + + constexpr meta_range_iterator() noexcept + : it{}, + ctx{} {} + + constexpr meta_range_iterator(const meta_ctx &area, const It iter) noexcept + : it{iter}, + ctx{&area} {} + + constexpr meta_range_iterator &operator++() noexcept { + return ++it, *this; + } + + constexpr meta_range_iterator operator++(int) noexcept { + const meta_range_iterator orig = *this; + return ++(*this), orig; + } + + constexpr meta_range_iterator &operator--() noexcept { + return --it, *this; + } + + constexpr meta_range_iterator operator--(int) noexcept { + const meta_range_iterator orig = *this; + return operator--(), orig; + } + + constexpr meta_range_iterator &operator+=(const difference_type value) noexcept { + it += value; + return *this; + } + + constexpr meta_range_iterator operator+(const difference_type value) const noexcept { + meta_range_iterator copy = *this; + return (copy += value); + } + + constexpr meta_range_iterator &operator-=(const difference_type value) noexcept { + return (*this += -value); + } + + constexpr meta_range_iterator operator-(const difference_type value) const noexcept { + return (*this + -value); + } + + [[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept { + if constexpr(std::is_same_v) { + return {it[value].first, Type{*ctx, *it[value].second}}; + } else if constexpr(std::is_same_v::value_type, meta_base_node>) { + return {it[value].type, Type{*ctx, it[value]}}; + } else { + return {it[value].id, Type{*ctx, it[value]}}; + } + } + + [[nodiscard]] constexpr pointer operator->() const noexcept { + return operator*(); + } + + [[nodiscard]] constexpr reference operator*() const noexcept { + return operator[](0); + } + + template + friend constexpr std::ptrdiff_t operator-(const meta_range_iterator &, const meta_range_iterator &) noexcept; + + template + friend constexpr bool operator==(const meta_range_iterator &, const meta_range_iterator &) noexcept; + + template + friend constexpr bool operator<(const meta_range_iterator &, const meta_range_iterator &) noexcept; + +private: + It it; + const meta_ctx *ctx; +}; + +template +[[nodiscard]] constexpr std::ptrdiff_t operator-(const meta_range_iterator &lhs, const meta_range_iterator &rhs) noexcept { + return lhs.it - rhs.it; +} + +template +[[nodiscard]] constexpr bool operator==(const meta_range_iterator &lhs, const meta_range_iterator &rhs) noexcept { + return lhs.it == rhs.it; +} + +template +[[nodiscard]] constexpr bool operator!=(const meta_range_iterator &lhs, const meta_range_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +template +[[nodiscard]] constexpr bool operator<(const meta_range_iterator &lhs, const meta_range_iterator &rhs) noexcept { + return lhs.it < rhs.it; +} + +template +[[nodiscard]] constexpr bool operator>(const meta_range_iterator &lhs, const meta_range_iterator &rhs) noexcept { + return rhs < lhs; +} + +template +[[nodiscard]] constexpr bool operator<=(const meta_range_iterator &lhs, const meta_range_iterator &rhs) noexcept { + return !(lhs > rhs); +} + +template +[[nodiscard]] constexpr bool operator>=(const meta_range_iterator &lhs, const meta_range_iterator &rhs) noexcept { + return !(lhs < rhs); +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Iterable range to use to iterate all types of meta objects. + * @tparam Type Type of meta objects returned. + * @tparam It Type of forward iterator. + */ +template +using meta_range = iterable_adaptor>; + +} // namespace entt + +#endif + +// #include "type_traits.hpp" + + +namespace entt { + +class meta_any; +class meta_type; + +/*! @brief Proxy object for sequence containers. */ +class meta_sequence_container { + class meta_iterator; + +public: + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + /*! @brief Meta iterator type. */ + using iterator = meta_iterator; + + /*! @brief Default constructor. */ + meta_sequence_container() = default; + + /** + * @brief Context aware constructor. + * @tparam Type Type of container to wrap. + * @param area The context from which to search for meta types. + * @param instance The container to wrap. + */ + template + meta_sequence_container(const meta_ctx &area, Type &instance) noexcept + : ctx{&area}, + data{&instance}, + value_type_node{&internal::resolve}, + const_reference_node{&internal::resolve>>}, + size_fn{meta_sequence_container_traits>::size}, + clear_fn{meta_sequence_container_traits>::clear}, + reserve_fn{meta_sequence_container_traits>::reserve}, + resize_fn{meta_sequence_container_traits>::resize}, + begin_end_fn{meta_sequence_container_traits>::iter}, + insert_fn{meta_sequence_container_traits>::insert}, + erase_fn{meta_sequence_container_traits>::erase}, + const_only{std::is_const_v} {} + + [[nodiscard]] inline meta_type value_type() const noexcept; + [[nodiscard]] inline size_type size() const noexcept; + inline bool resize(size_type); + inline bool clear(); + inline bool reserve(size_type); + [[nodiscard]] inline iterator begin(); + [[nodiscard]] inline iterator end(); + inline iterator insert(const iterator &, meta_any); + inline iterator erase(const iterator &); + [[nodiscard]] inline meta_any operator[](size_type); + [[nodiscard]] inline explicit operator bool() const noexcept; + +private: + const meta_ctx *ctx{}; + const void *data{}; + const internal::meta_type_node &(*value_type_node)(const internal::meta_context &){}; + const internal::meta_type_node &(*const_reference_node)(const internal::meta_context &){}; + size_type (*size_fn)(const void *){}; + bool (*clear_fn)(void *){}; + bool (*reserve_fn)(void *, const size_type){}; + bool (*resize_fn)(void *, const size_type){}; + iterator (*begin_end_fn)(const meta_ctx &, void *, const void *, const bool){}; + iterator (*insert_fn)(const meta_ctx &, void *, const void *, const void *, const iterator &){}; + iterator (*erase_fn)(const meta_ctx &, void *, const iterator &){}; + bool const_only{}; +}; + +/*! @brief Proxy object for associative containers. */ +class meta_associative_container { + class meta_iterator; + +public: + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + /*! @brief Meta iterator type. */ + using iterator = meta_iterator; + + /*! @brief Default constructor. */ + meta_associative_container() = default; + + /** + * @brief Context aware constructor. + * @tparam Type Type of container to wrap. + * @param area The context from which to search for meta types. + * @param instance The container to wrap. + */ + template + meta_associative_container(const meta_ctx &area, Type &instance) noexcept + : ctx{&area}, + data{&instance}, + key_type_node{&internal::resolve}, + value_type_node{&internal::resolve}, + size_fn{&meta_associative_container_traits>::size}, + clear_fn{&meta_associative_container_traits>::clear}, + reserve_fn{&meta_associative_container_traits>::reserve}, + begin_end_fn{&meta_associative_container_traits>::iter}, + insert_fn{&meta_associative_container_traits>::insert}, + erase_fn{&meta_associative_container_traits>::erase}, + find_fn{&meta_associative_container_traits>::find}, + const_only{std::is_const_v} { + if constexpr(!meta_associative_container_traits>::key_only) { + mapped_type_node = &internal::resolve; + } + } + + [[nodiscard]] inline meta_type key_type() const noexcept; + [[nodiscard]] inline meta_type mapped_type() const noexcept; + [[nodiscard]] inline meta_type value_type() const noexcept; + [[nodiscard]] inline size_type size() const noexcept; + inline bool clear(); + inline bool reserve(size_type); + [[nodiscard]] inline iterator begin(); + [[nodiscard]] inline iterator end(); + inline bool insert(meta_any, meta_any); + inline size_type erase(meta_any); + [[nodiscard]] inline iterator find(meta_any); + [[nodiscard]] inline explicit operator bool() const noexcept; + +private: + const meta_ctx *ctx{}; + const void *data{}; + const internal::meta_type_node &(*key_type_node)(const internal::meta_context &){}; + const internal::meta_type_node &(*mapped_type_node)(const internal::meta_context &){}; + const internal::meta_type_node &(*value_type_node)(const internal::meta_context &){}; + size_type (*size_fn)(const void *){}; + bool (*clear_fn)(void *){}; + bool (*reserve_fn)(void *, const size_type){}; + iterator (*begin_end_fn)(const meta_ctx &, void *, const void *, const bool){}; + bool (*insert_fn)(void *, const void *, const void *){}; + size_type (*erase_fn)(void *, const void *){}; + iterator (*find_fn)(const meta_ctx &, void *, const void *, const void *){}; + bool const_only{}; +}; + +/*! @brief Opaque wrapper for values of any type. */ +class meta_any { + using vtable_type = void(const internal::meta_traits, const meta_any &, const void *); + + template + static void basic_vtable(const internal::meta_traits req, const meta_any &value, [[maybe_unused]] const void *other) { + static_assert(std::is_same_v>, Type>, "Invalid type"); + + if(req == internal::meta_traits::is_none) { + value.node = &internal::resolve(internal::meta_context::from(*value.ctx)); + } + + if constexpr(is_meta_pointer_like_v) { + if(req == internal::meta_traits::is_pointer_like) { + if constexpr(std::is_function_v::element_type>) { + const_cast(value).emplace(*static_cast(other)); + } else if constexpr(!std::is_void_v::element_type>>) { + using in_place_type = decltype(adl_meta_pointer_like::dereference(std::declval())); + + if constexpr(std::is_constructible_v) { + if(const auto &pointer_like = *static_cast(other); pointer_like) { + const_cast(value).emplace(adl_meta_pointer_like::dereference(pointer_like)); + } + } else { + const_cast(value).emplace(adl_meta_pointer_like::dereference(*static_cast(other))); + } + } + } + } + + if constexpr(is_complete_v> || is_complete_v>) { + if(constexpr auto flag = (is_complete_v> ? internal::meta_traits::is_sequence_container : internal::meta_traits::is_associative_container); !!(req & flag)) { + using container_type = std::conditional_t>, meta_sequence_container, meta_associative_container>; + + if(!!(req & internal::meta_traits::is_const) || (value.storage.policy() == any_policy::cref)) { + // NOLINTNEXTLINE(bugprone-casting-through-void) + *static_cast(const_cast(other)) = container_type{*value.ctx, any_cast(value.storage)}; + } else { + // NOLINTNEXTLINE(bugprone-casting-through-void) + *static_cast(const_cast(other)) = container_type{*value.ctx, any_cast(const_cast(value).storage)}; + } + } + } + } + + [[nodiscard]] const auto &fetch_node() const { + if(node == nullptr) { + ENTT_ASSERT(*this, "Invalid vtable function"); + vtable(internal::meta_traits::is_none, *this, nullptr); + } + + ENTT_ASSERT(node != nullptr, "Invalid pointer to node"); + return *node; + } + + meta_any(const meta_any &other, any elem) + : storage{std::move(elem)}, + ctx{other.ctx}, + node{other.node}, + vtable{other.vtable} {} + +public: + /*! Default constructor. */ + meta_any() = default; + + /** + * @brief Context aware constructor. + * @param area The context from which to search for meta types. + */ + meta_any(meta_ctx_arg_t, const meta_ctx &area) + : ctx{&area} {} + + /** + * @brief Constructs a wrapper by directly initializing the new object. + * @tparam Type Type of object to use to initialize the wrapper. + * @tparam Args Types of arguments to use to construct the new instance. + * @param args Parameters to use to construct the instance. + */ + template + explicit meta_any(std::in_place_type_t, Args &&...args) + : meta_any{locator::value_or(), std::in_place_type, std::forward(args)...} {} + + /** + * @brief Constructs a wrapper by directly initializing the new object. + * @tparam Type Type of object to use to initialize the wrapper. + * @tparam Args Types of arguments to use to construct the new instance. + * @param area The context from which to search for meta types. + * @param args Parameters to use to construct the instance. + */ + template + explicit meta_any(const meta_ctx &area, std::in_place_type_t, Args &&...args) + : storage{std::in_place_type, std::forward(args)...}, + ctx{&area}, + vtable{&basic_vtable>>} {} + + /** + * @brief Constructs a wrapper taking ownership of the passed object. + * @tparam Type Type of object to use to initialize the wrapper. + * @param value A pointer to an object to take ownership of. + */ + template + explicit meta_any(std::in_place_t, Type *value) + : meta_any{locator::value_or(), std::in_place, value} {} + + /** + * @brief Constructs a wrapper taking ownership of the passed object. + * @tparam Type Type of object to use to initialize the wrapper. + * @param area The context from which to search for meta types. + * @param value A pointer to an object to take ownership of. + */ + template + explicit meta_any(const meta_ctx &area, std::in_place_t, Type *value) + : storage{std::in_place, value}, + ctx{&area}, + vtable{storage ? &basic_vtable : nullptr} { + } + + /** + * @brief Constructs a wrapper from a given value. + * @tparam Type Type of object to use to initialize the wrapper. + * @param value An instance of an object to use to initialize the wrapper. + */ + template, meta_any>>> + meta_any(Type &&value) + : meta_any{locator::value_or(), std::forward(value)} {} + + /** + * @brief Constructs a wrapper from a given value. + * @tparam Type Type of object to use to initialize the wrapper. + * @param area The context from which to search for meta types. + * @param value An instance of an object to use to initialize the wrapper. + */ + template, meta_any>>> + meta_any(const meta_ctx &area, Type &&value) + : meta_any{area, std::in_place_type>, std::forward(value)} {} + + /** + * @brief Context aware copy constructor. + * @param area The context from which to search for meta types. + * @param other The instance to copy from. + */ + meta_any(const meta_ctx &area, const meta_any &other) + : storage{other.storage}, + ctx{&area}, + node{(ctx == other.ctx) ? other.node : nullptr}, + vtable{other.vtable} {} + + /** + * @brief Context aware move constructor. + * @param area The context from which to search for meta types. + * @param other The instance to move from. + */ + meta_any(const meta_ctx &area, meta_any &&other) + : storage{std::move(other.storage)}, + ctx{&area}, + node{(ctx == other.ctx) ? std::exchange(other.node, nullptr) : nullptr}, + vtable{std::exchange(other.vtable, nullptr)} {} + + /** + * @brief Copy constructor. + * @param other The instance to copy from. + */ + meta_any(const meta_any &other) = default; + + /** + * @brief Move constructor. + * @param other The instance to move from. + */ + meta_any(meta_any &&other) noexcept + : storage{std::move(other.storage)}, + ctx{other.ctx}, + node{std::exchange(other.node, nullptr)}, + vtable{std::exchange(other.vtable, nullptr)} {} + + /*! @brief Default destructor. */ + ~meta_any() = default; + + /** + * @brief Copy assignment operator. + * @param other The instance to copy from. + * @return This meta any object. + */ + meta_any &operator=(const meta_any &other) { + if(this != &other) { + storage = other.storage; + ctx = other.ctx; + node = other.node; + vtable = other.vtable; + } + + return *this; + } + + /** + * @brief Move assignment operator. + * @param other The instance to move from. + * @return This meta any object. + */ + meta_any &operator=(meta_any &&other) noexcept { + storage = std::move(other.storage); + ctx = other.ctx; + node = std::exchange(other.node, nullptr); + vtable = std::exchange(other.vtable, nullptr); + return *this; + } + + /** + * @brief Value assignment operator. + * @tparam Type Type of object to use to initialize the wrapper. + * @param value An instance of an object to use to initialize the wrapper. + * @return This meta any object. + */ + template, meta_any>>> + meta_any &operator=(Type &&value) { + emplace>(std::forward(value)); + return *this; + } + + /*! @copydoc any::info */ + [[nodiscard]] inline meta_type type() const noexcept; + + /** + * @brief Invokes the underlying function, if possible. + * @tparam Args Types of arguments to use to invoke the function. + * @param id Unique identifier. + * @param args Parameters to use to invoke the function. + * @return A wrapper containing the returned value, if any. + */ + template + meta_any invoke(id_type id, Args &&...args) const; + + /*! @copydoc invoke */ + template + meta_any invoke(id_type id, Args &&...args); + + /** + * @brief Sets the value of a given variable. + * @tparam Type Type of value to assign. + * @param id Unique identifier. + * @param value Parameter to use to set the underlying variable. + * @return True in case of success, false otherwise. + */ + template + bool set(id_type id, Type &&value); + + /** + * @brief Gets the value of a given variable. + * @param id Unique identifier. + * @return A wrapper containing the value of the underlying variable. + */ + [[nodiscard]] meta_any get(id_type id) const; + + /*! @copydoc get */ + [[nodiscard]] meta_any get(id_type id); + + /** + * @brief Tries to cast an instance to a given type. + * @tparam Type Type to which to cast the instance. + * @return A (possibly null) pointer to the contained instance. + */ + template + [[nodiscard]] const Type *try_cast() const { + const auto *elem = any_cast(&storage); + return ((elem != nullptr) || !*this) ? elem : static_cast(internal::try_cast(internal::meta_context::from(*ctx), fetch_node(), type_hash>::value(), storage.data())); + } + + /*! @copydoc try_cast */ + template + [[nodiscard]] Type *try_cast() { + return ((storage.policy() == any_policy::cref) && !std::is_const_v) ? nullptr : const_cast(std::as_const(*this).try_cast>()); + } + + /** + * @brief Tries to cast an instance to a given type. + * @tparam Type Type to which to cast the instance. + * @return A reference to the contained instance. + */ + template + [[nodiscard]] std::remove_const_t cast() const { + auto *const instance = try_cast>(); + ENTT_ASSERT(instance, "Invalid instance"); + return static_cast(*instance); + } + + /*! @copydoc cast */ + template + [[nodiscard]] std::remove_const_t cast() { + // forces const on non-reference types to make them work also with wrappers for const references + auto *const instance = try_cast>(); + ENTT_ASSERT(instance, "Invalid instance"); + return static_cast(*instance); + } + + /** + * @brief Converts an object in such a way that a given cast becomes viable. + * @param type Meta type to which the cast is requested. + * @return A valid meta object if convertible, an invalid one otherwise. + */ + [[nodiscard]] meta_any allow_cast(const meta_type &type) const; + + /** + * @brief Converts an object in such a way that a given cast becomes viable. + * @param type Meta type to which the cast is requested. + * @return True if convertible, false otherwise. + */ + [[nodiscard]] bool allow_cast(const meta_type &type); + + /** + * @brief Converts an object in such a way that a given cast becomes viable. + * @tparam Type Type to which the cast is requested. + * @return A valid meta object if convertible, an invalid one otherwise. + */ + template + [[nodiscard]] meta_any allow_cast() const { + if constexpr(!std::is_reference_v || std::is_const_v>) { + if(storage.has_value>>()) { + return as_ref(); + } else if(*this) { + if constexpr(std::is_arithmetic_v>> || std::is_enum_v>>) { + if(const auto &from = fetch_node(); from.conversion_helper) { + return meta_any{*ctx, static_cast(from.conversion_helper(nullptr, storage.data()))}; + } + } + + if(const auto &from = fetch_node(); from.details != nullptr) { + if(const auto *elem = internal::find_member<&internal::meta_conv_node::type>(from.details->conv, entt::type_hash>>::value()); elem != nullptr) { + return elem->conv(*ctx, storage.data()); + } + + for(auto &&curr: from.details->base) { + if(auto other = curr.resolve(internal::meta_context::from(*ctx)).from_void(*ctx, nullptr, curr.cast(storage.data())); curr.type == entt::type_hash>>::value()) { + return other; + } else if(auto from_base = std::as_const(other).template allow_cast(); from_base) { + return from_base; + } + } + } + } + } + + return meta_any{meta_ctx_arg, *ctx}; + } + + /** + * @brief Converts an object in such a way that a given cast becomes viable. + * @tparam Type Type to which the cast is requested. + * @return True if convertible, false otherwise. + */ + template + [[nodiscard]] bool allow_cast() { + if constexpr(std::is_reference_v && !std::is_const_v>) { + return allow_cast &>() && (storage.policy() != any_policy::cref); + } else { + if(storage.has_value>>()) { + return true; + } else if(auto other = std::as_const(*this).allow_cast>>(); other) { + if(other.storage.owner()) { + std::swap(*this, other); + } + + return true; + } + + return false; + } + } + + /*! @copydoc any::emplace */ + template + void emplace(Args &&...args) { + storage.emplace(std::forward(args)...); + auto *prev = std::exchange(vtable, &basic_vtable>>); + node = (prev == vtable) ? node : nullptr; + } + + /*! @copydoc any::assign */ + bool assign(const meta_any &other); + + /*! @copydoc any::assign */ + bool assign(meta_any &&other); + + /*! @copydoc any::reset */ + void reset() { + storage.reset(); + node = nullptr; + vtable = nullptr; + } + + /** + * @brief Returns a sequence container proxy. + * @return A sequence container proxy for the underlying object. + */ + [[nodiscard]] meta_sequence_container as_sequence_container() noexcept { + meta_sequence_container proxy{}; + if(*this) { vtable(internal::meta_traits::is_sequence_container, *this, &proxy); } + return proxy; + } + + /*! @copydoc as_sequence_container */ + [[nodiscard]] meta_sequence_container as_sequence_container() const noexcept { + meta_sequence_container proxy{}; + if(*this) { vtable(internal::meta_traits::is_sequence_container | internal::meta_traits::is_const, *this, &proxy); } + return proxy; + } + + /** + * @brief Returns an associative container proxy. + * @return An associative container proxy for the underlying object. + */ + [[nodiscard]] meta_associative_container as_associative_container() noexcept { + meta_associative_container proxy{}; + if(*this) { vtable(internal::meta_traits::is_associative_container, *this, &proxy); } + return proxy; + } + + /*! @copydoc as_associative_container */ + [[nodiscard]] meta_associative_container as_associative_container() const noexcept { + meta_associative_container proxy{}; + if(*this) { vtable(internal::meta_traits::is_associative_container | internal::meta_traits::is_const, *this, &proxy); } + return proxy; + } + + /** + * @brief Indirection operator for dereferencing opaque objects. + * @return A wrapper that shares a reference to an unmanaged object if the + * wrapped element is dereferenceable, an invalid meta any otherwise. + */ + [[nodiscard]] meta_any operator*() const noexcept { + meta_any ret{meta_ctx_arg, *ctx}; + if(*this) { vtable(internal::meta_traits::is_pointer_like, ret, storage.data()); } + return ret; + } + + /*! @copydoc any::operator bool */ + [[nodiscard]] explicit operator bool() const noexcept { + return !(vtable == nullptr); + } + + /*! @copydoc any::operator== */ + [[nodiscard]] bool operator==(const meta_any &other) const noexcept { + return (ctx == other.ctx) && (!*this == !other) && (storage == other.storage); + } + + /*! @copydoc any::operator!= */ + [[nodiscard]] bool operator!=(const meta_any &other) const noexcept { + return !(*this == other); + } + + /*! @copydoc any::as_ref */ + [[nodiscard]] meta_any as_ref() noexcept { + return meta_any{*this, storage.as_ref()}; + } + + /*! @copydoc any::as_ref */ + [[nodiscard]] meta_any as_ref() const noexcept { + return meta_any{*this, storage.as_ref()}; + } + + /** + * @brief Returns the underlying storage. + * @return The underlyig storage. + */ + [[nodiscard]] const any &base() const noexcept { + return storage; + } + + /** + * @brief Returns the underlying meta context. + * @return The underlying meta context. + */ + [[nodiscard]] const meta_ctx &context() const noexcept { + return *ctx; + } + +private: + any storage{}; + const meta_ctx *ctx{&locator::value_or()}; + mutable const internal::meta_type_node *node{}; + vtable_type *vtable{}; +}; + +/** + * @brief Forwards its argument and avoids copies for lvalue references. + * @tparam Type Type of argument to use to construct the new instance. + * @param value Parameter to use to construct the instance. + * @param ctx The context from which to search for meta types. + * @return A properly initialized and not necessarily owning wrapper. + */ +template +[[nodiscard]] meta_any forward_as_meta(const meta_ctx &ctx, Type &&value) { + return meta_any{ctx, std::in_place_type, std::forward(value)}; +} + +/** + * @brief Forwards its argument and avoids copies for lvalue references. + * @tparam Type Type of argument to use to construct the new instance. + * @param value Parameter to use to construct the instance. + * @return A properly initialized and not necessarily owning wrapper. + */ +template +[[nodiscard]] meta_any forward_as_meta(Type &&value) { + return forward_as_meta(locator::value_or(), std::forward(value)); +} + +/*! @brief Opaque pointers to instances of any type. */ +class meta_handle { + template, meta_any>>> + meta_handle(int, Type &value, Args &&...args) + : any{std::forward(args)..., value.as_ref()} {} + + template + meta_handle(char, Type &value, Args &&...args) + : any{std::forward(args)..., std::in_place_type, value} {} + +public: + /*! Default constructor. */ + meta_handle() = default; + + /** + * @brief Creates a handle that points to an unmanaged object. + * @tparam Type Type of object to use to initialize the handle. + * @param ctx The context from which to search for meta types. + * @param value An instance of an object to use to initialize the handle. + */ + template, meta_handle>>> + meta_handle(const meta_ctx &ctx, Type &value) + : meta_handle{0, value, ctx} {} + + /** + * @brief Creates a handle that points to an unmanaged object. + * @tparam Type Type of object to use to initialize the handle. + * @param value An instance of an object to use to initialize the handle. + */ + template, meta_handle>>> + meta_handle(Type &value) + : meta_handle{0, value} {} + + /** + * @brief Context aware move constructor. + * @param area The context from which to search for meta types. + * @param other The instance to move from. + */ + meta_handle(const meta_ctx &area, meta_handle &&other) + : any{area, std::move(other.any)} {} + + /*! @brief Default copy constructor, deleted on purpose. */ + meta_handle(const meta_handle &) = delete; + + /*! @brief Default move constructor. */ + meta_handle(meta_handle &&) = default; + + /*! @brief Default destructor. */ + ~meta_handle() = default; + + /** + * @brief Default copy assignment operator, deleted on purpose. + * @return This meta handle. + */ + meta_handle &operator=(const meta_handle &) = delete; + + /** + * @brief Default move assignment operator. + * @return This meta handle. + */ + meta_handle &operator=(meta_handle &&) = default; + + /** + * @brief Returns false if a handle is invalid, true otherwise. + * @return False if the handle is invalid, true otherwise. + */ + [[nodiscard]] explicit operator bool() const noexcept { + return static_cast(any); + } + + /** + * @brief Access operator for accessing the contained opaque object. + * @return A wrapper that shares a reference to an unmanaged object. + */ + [[nodiscard]] meta_any *operator->() { + return &any; + } + + /*! @copydoc operator-> */ + [[deprecated("do not use const handles")]] [[nodiscard]] const meta_any *operator->() const { + return &any; + } + +private: + meta_any any{}; +}; + +/*! @brief Opaque wrapper for user defined data of any type. */ +struct meta_custom { + /*! @brief Default constructor. */ + meta_custom() noexcept = default; + + /** + * @brief Basic constructor for meta objects. + * @param curr The underlying node with which to construct the instance. + */ + meta_custom(const internal::meta_custom_node &curr) noexcept + : node{&curr} {} + + /** + * @brief Generic conversion operator. + * @tparam Type Type to which conversion is requested. + */ + template + [[nodiscard]] operator Type *() const noexcept { + return ((node != nullptr) && (type_hash>::value() == node->type)) ? static_cast(node->value.get()) : nullptr; + } + + /** + * @brief Generic conversion operator. + * @tparam Type Type to which conversion is requested. + */ + template + [[nodiscard]] operator Type &() const noexcept { + ENTT_ASSERT(static_cast(*this) != nullptr, "Invalid type"); + return *static_cast(node->value.get()); + } + +private: + const internal::meta_custom_node *node{}; +}; + +/*! @brief Opaque wrapper for data members. */ +class meta_data { + [[nodiscard]] auto &node_or_assert() const noexcept { + ENTT_ASSERT(node != nullptr, "Invalid pointer to node"); + return *node; + } + +public: + /*! @brief Unsigned integer type. */ + using size_type = typename internal::meta_data_node::size_type; + + /*! @brief Default constructor. */ + meta_data() noexcept = default; + + /** + * @brief Context aware constructor for meta objects. + * @param area The context from which to search for meta types. + * @param curr The underlying node with which to construct the instance. + */ + meta_data(const meta_ctx &area, const internal::meta_data_node &curr) noexcept + : node{&curr}, + ctx{&area} {} + + /** + * @brief Returns the name assigned to a data member, if any. + * @return The name assigned to the data member, if any. + */ + [[nodiscard]] const char *name() const noexcept { + return node_or_assert().name; + } + + /** + * @brief Returns the number of setters available. + * @return The number of setters available. + */ + [[nodiscard]] size_type arity() const noexcept { + return node_or_assert().arity; + } + + /** + * @brief Indicates whether a data member is constant or not. + * @return True if the data member is constant, false otherwise. + */ + [[nodiscard]] bool is_const() const noexcept { + return !!(node_or_assert().traits & internal::meta_traits::is_const); + } + + /** + * @brief Indicates whether a data member is static or not. + * @return True if the data member is static, false otherwise. + */ + [[nodiscard]] bool is_static() const noexcept { + return !!(node_or_assert().traits & internal::meta_traits::is_static); + } + + /*! @copydoc meta_any::type */ + [[nodiscard]] inline meta_type type() const noexcept; + + /** + * @brief Sets the value of a given variable. + * @tparam Instance Type of instance to operate on. + * @tparam Type Type of value to assign. + * @param instance An instance that fits the underlying type. + * @param value Parameter to use to set the underlying variable. + * @return True in case of success, false otherwise. + */ + template + // NOLINTNEXTLINE(modernize-use-nodiscard) + bool set(Instance &&instance, Type &&value) const { + return node_or_assert().set(meta_handle{*ctx, std::forward(instance)}, meta_any{*ctx, std::forward(value)}); + } + + /** + * @brief Gets the value of a given variable. + * @tparam Instance Type of instance to operate on. + * @param instance An instance that fits the underlying type. + * @return A wrapper containing the value of the underlying variable. + */ + template + [[nodiscard]] meta_any get(Instance &&instance) const { + return node_or_assert().get(meta_handle{*ctx, std::forward(instance)}); + } + + /** + * @brief Returns the type accepted by the i-th setter. + * @param index Index of the setter of which to return the accepted type. + * @return The type accepted by the i-th setter. + */ + [[nodiscard]] inline meta_type arg(size_type index) const noexcept; + + /** + * @brief Returns all meta traits for a given meta object. + * @tparam Type The type to convert the meta traits to. + * @return The registered meta traits, if any. + */ + template + [[nodiscard]] Type traits() const noexcept { + return internal::meta_to_user_traits(node_or_assert().traits); + } + + /** + * @brief Returns user defined data for a given meta object. + * @return User defined arbitrary data. + */ + [[nodiscard]] meta_custom custom() const noexcept { + return {node_or_assert().custom}; + } + + /** + * @brief Returns true if an object is valid, false otherwise. + * @return True if the object is valid, false otherwise. + */ + [[nodiscard]] explicit operator bool() const noexcept { + return (node != nullptr); + } + + /** + * @brief Checks if two objects refer to the same type. + * @param other The object with which to compare. + * @return True if the objects refer to the same type, false otherwise. + */ + [[nodiscard]] bool operator==(const meta_data &other) const noexcept { + return (ctx == other.ctx) && (node == other.node); + } + +private: + const internal::meta_data_node *node{}; + const meta_ctx *ctx{&locator::value_or()}; +}; + +/** + * @brief Checks if two objects refer to the same type. + * @param lhs An object, either valid or not. + * @param rhs An object, either valid or not. + * @return False if the objects refer to the same node, true otherwise. + */ +[[nodiscard]] inline bool operator!=(const meta_data &lhs, const meta_data &rhs) noexcept { + return !(lhs == rhs); +} + +/*! @brief Opaque wrapper for member functions. */ +class meta_func { + [[nodiscard]] auto &node_or_assert() const noexcept { + ENTT_ASSERT(node != nullptr, "Invalid pointer to node"); + return *node; + } + +public: + /*! @brief Unsigned integer type. */ + using size_type = typename internal::meta_func_node::size_type; + + /*! @brief Default constructor. */ + meta_func() noexcept = default; + + /** + * @brief Context aware constructor for meta objects. + * @param area The context from which to search for meta types. + * @param curr The underlying node with which to construct the instance. + */ + meta_func(const meta_ctx &area, const internal::meta_func_node &curr) noexcept + : node{&curr}, + ctx{&area} {} + + /** + * @brief Returns the name assigned to a member function, if any. + * @return The name assigned to the member function, if any. + */ + [[nodiscard]] const char *name() const noexcept { + return node_or_assert().name; + } + + /** + * @brief Returns the number of arguments accepted by a member function. + * @return The number of arguments accepted by the member function. + */ + [[nodiscard]] size_type arity() const noexcept { + return node_or_assert().arity; + } + + /** + * @brief Indicates whether a member function is constant or not. + * @return True if the member function is constant, false otherwise. + */ + [[nodiscard]] bool is_const() const noexcept { + return !!(node_or_assert().traits & internal::meta_traits::is_const); + } + + /** + * @brief Indicates whether a member function is static or not. + * @return True if the member function is static, false otherwise. + */ + [[nodiscard]] bool is_static() const noexcept { + return !!(node_or_assert().traits & internal::meta_traits::is_static); + } + + /** + * @brief Returns the return type of a member function. + * @return The return type of the member function. + */ + [[nodiscard]] inline meta_type ret() const noexcept; + + /** + * @brief Returns the type of the i-th argument of a member function. + * @param index Index of the argument of which to return the type. + * @return The type of the i-th argument of a member function. + */ + [[nodiscard]] inline meta_type arg(size_type index) const noexcept; + + /** + * @brief Invokes the underlying function, if possible. + * @tparam Instance Type of instance to operate on. + * @param instance An instance that fits the underlying type. + * @param args Parameters to use to invoke the function. + * @param sz Number of parameters to use to invoke the function. + * @return A wrapper containing the returned value, if any. + */ + template + meta_any invoke(Instance &&instance, meta_any *const args, const size_type sz) const { + return (sz == arity()) ? node_or_assert().invoke(meta_handle{*ctx, std::forward(instance)}, args) : meta_any{meta_ctx_arg, *ctx}; + } + + /** + * @copybrief invoke + * @tparam Instance Type of instance to operate on. + * @tparam Args Types of arguments to use to invoke the function. + * @param instance An instance that fits the underlying type. + * @param args Parameters to use to invoke the function. + * @return A wrapper containing the returned value, if any. + */ + template + // NOLINTNEXTLINE(modernize-use-nodiscard) + meta_any invoke(Instance &&instance, Args &&...args) const { + return invoke(std::forward(instance), std::array{meta_any{*ctx, std::forward(args)}...}.data(), sizeof...(Args)); + } + + /*! @copydoc meta_data::traits */ + template + [[nodiscard]] Type traits() const noexcept { + return internal::meta_to_user_traits(node_or_assert().traits); + } + + /*! @copydoc meta_data::custom */ + [[nodiscard]] meta_custom custom() const noexcept { + return {node_or_assert().custom}; + } + + /** + * @brief Returns the next overload of a given function, if any. + * @return The next overload of the given function, if any. + */ + [[nodiscard]] meta_func next() const { + return (node_or_assert().next != nullptr) ? meta_func{*ctx, *node_or_assert().next} : meta_func{}; + } + + /*! @copydoc meta_data::operator bool */ + [[nodiscard]] explicit operator bool() const noexcept { + return (node != nullptr); + } + + /*! @copydoc meta_data::operator== */ + [[nodiscard]] bool operator==(const meta_func &other) const noexcept { + return (ctx == other.ctx) && (node == other.node); + } + +private: + const internal::meta_func_node *node{}; + const meta_ctx *ctx{&locator::value_or()}; +}; + +/*! @copydoc operator!=(const meta_data &, const meta_data &) */ +[[nodiscard]] inline bool operator!=(const meta_func &lhs, const meta_func &rhs) noexcept { + return !(lhs == rhs); +} + +/*! @brief Opaque wrapper for types. */ +class meta_type { + [[nodiscard]] const auto &fetch_node() const { + return (node == nullptr) ? internal::resolve(internal::meta_context::from(*ctx)) : *node; + } + + template + [[nodiscard]] auto lookup(meta_any *const args, const typename internal::meta_type_node::size_type sz, [[maybe_unused]] bool constness, Func next) const { + decltype(next()) candidate = nullptr; + size_type same{}; + bool ambiguous{}; + + for(auto curr = next(); curr; curr = next()) { + if constexpr(std::is_same_v, internal::meta_func_node>) { + if(constness && !(curr->traits & internal::meta_traits::is_const)) { + continue; + } + } + + if(curr->arity == sz) { + size_type match{}; + size_type pos{}; + + // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic) - waiting for C++20 (and std::span) + for(; pos < sz && args[pos]; ++pos) { + const auto other = curr->arg(*ctx, pos); + const auto type = args[pos].type(); + + if(const auto &info = other.info(); info == type.info()) { + ++match; + } else if(!(type.fetch_node().conversion_helper && other.fetch_node().conversion_helper) && !(type.fetch_node().details && (internal::find_member<&internal::meta_base_node::type>(type.fetch_node().details->base, info.hash()) || internal::find_member<&internal::meta_conv_node::type>(type.fetch_node().details->conv, info.hash())))) { + break; + } + } + // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic) + + if(pos == sz) { + if(!candidate || match > same) { + candidate = curr; + same = match; + ambiguous = false; + } else if(match == same) { + if constexpr(std::is_same_v, internal::meta_func_node>) { + if(!!(curr->traits & internal::meta_traits::is_const) != !!(candidate->traits & internal::meta_traits::is_const)) { + candidate = !!(candidate->traits & internal::meta_traits::is_const) ? curr : candidate; + ambiguous = false; + continue; + } + } + + ambiguous = true; + } + } + } + } + + return ambiguous ? nullptr : candidate; + } + +public: + /*! @brief Unsigned integer type. */ + using size_type = typename internal::meta_type_node::size_type; + + /*! @brief Default constructor. */ + meta_type() noexcept = default; + + /** + * @brief Context aware constructor for meta objects. + * @param area The context from which to search for meta types. + * @param curr The underlying node with which to construct the instance. + */ + meta_type(const meta_ctx &area, const internal::meta_type_node &curr) noexcept + : node{&curr}, + ctx{&area} {} + + /** + * @brief Context aware constructor for meta objects. + * @param area The context from which to search for meta types. + * @param curr The underlying node with which to construct the instance. + */ + meta_type(const meta_ctx &area, const internal::meta_base_node &curr) noexcept + : meta_type{area, curr.resolve(internal::meta_context::from(area))} {} + + /** + * @brief Returns the type info object of the underlying type. + * @return The type info object of the underlying type. + */ + [[nodiscard]] const type_info &info() const noexcept { + return *fetch_node().info; + } + + /** + * @brief Returns the identifier assigned to a type. + * @return The identifier assigned to the type. + */ + [[nodiscard]] id_type id() const noexcept { + return fetch_node().id; + } + + /** + * @brief Returns the name assigned to a type, if any. + * @return The name assigned to the type, if any. + */ + [[nodiscard]] const char *name() const noexcept { + return fetch_node().name; + } + + /** + * @brief Returns the size of the underlying type if known. + * @return The size of the underlying type if known, 0 otherwise. + */ + [[nodiscard]] size_type size_of() const noexcept { + return fetch_node().size_of; + } + + /** + * @brief Checks whether a type refers to an arithmetic type or not. + * @return True if the underlying type is an arithmetic type, false + * otherwise. + */ + [[nodiscard]] bool is_arithmetic() const noexcept { + return !!(fetch_node().traits & internal::meta_traits::is_arithmetic); + } + + /** + * @brief Checks whether a type refers to an integral type or not. + * @return True if the underlying type is an integral type, false otherwise. + */ + [[nodiscard]] bool is_integral() const noexcept { + return !!(fetch_node().traits & internal::meta_traits::is_integral); + } + + /** + * @brief Checks whether a type refers to a signed type or not. + * @return True if the underlying type is a signed type, false otherwise. + */ + [[nodiscard]] bool is_signed() const noexcept { + return !!(fetch_node().traits & internal::meta_traits::is_signed); + } + + /** + * @brief Checks whether a type refers to an array type or not. + * @return True if the underlying type is an array type, false otherwise. + */ + [[nodiscard]] bool is_array() const noexcept { + return !!(fetch_node().traits & internal::meta_traits::is_array); + } + + /** + * @brief Checks whether a type refers to an enum or not. + * @return True if the underlying type is an enum, false otherwise. + */ + [[nodiscard]] bool is_enum() const noexcept { + return !!(fetch_node().traits & internal::meta_traits::is_enum); + } + + /** + * @brief Checks whether a type refers to a class or not. + * @return True if the underlying type is a class, false otherwise. + */ + [[nodiscard]] bool is_class() const noexcept { + return !!(fetch_node().traits & internal::meta_traits::is_class); + } + + /** + * @brief Checks whether a type refers to a pointer or not. + * @return True if the underlying type is a pointer, false otherwise. + */ + [[nodiscard]] bool is_pointer() const noexcept { + return !!(fetch_node().traits & internal::meta_traits::is_pointer); + } + + /** + * @brief Provides the type for which the pointer is defined. + * @return The type for which the pointer is defined or this type if it + * doesn't refer to a pointer type. + */ + [[nodiscard]] meta_type remove_pointer() const noexcept { + return meta_type{*ctx, fetch_node().remove_pointer(internal::meta_context::from(*ctx))}; + } + + /** + * @brief Checks whether a type is a pointer-like type or not. + * @return True if the underlying type is pointer-like, false otherwise. + */ + [[nodiscard]] bool is_pointer_like() const noexcept { + return !!(fetch_node().traits & internal::meta_traits::is_pointer_like); + } + + /** + * @brief Checks whether a type refers to a sequence container or not. + * @return True if the type is a sequence container, false otherwise. + */ + [[nodiscard]] bool is_sequence_container() const noexcept { + return !!(fetch_node().traits & internal::meta_traits::is_sequence_container); + } + + /** + * @brief Checks whether a type refers to an associative container or not. + * @return True if the type is an associative container, false otherwise. + */ + [[nodiscard]] bool is_associative_container() const noexcept { + return !!(fetch_node().traits & internal::meta_traits::is_associative_container); + } + + /** + * @brief Checks whether a type refers to a template specialization or not. + * @return True if the type is a template specialization, false otherwise. + */ + [[nodiscard]] bool is_template_specialization() const noexcept { + return (fetch_node().templ.arity != 0u); + } + + /** + * @brief Returns the number of template arguments. + * @return The number of template arguments. + */ + [[nodiscard]] size_type template_arity() const noexcept { + return fetch_node().templ.arity; + } + + /** + * @brief Returns a tag for the class template of the underlying type. + * @return The tag for the class template of the underlying type. + */ + [[nodiscard]] meta_type template_type() const noexcept { + return (fetch_node().templ.resolve != nullptr) ? meta_type{*ctx, fetch_node().templ.resolve(internal::meta_context::from(*ctx))} : meta_type{}; + } + + /** + * @brief Returns the type of the i-th template argument of a type. + * @param index Index of the template argument of which to return the type. + * @return The type of the i-th template argument of a type. + */ + [[nodiscard]] meta_type template_arg(const size_type index) const noexcept { + return index < template_arity() ? meta_type{*ctx, fetch_node().templ.arg(internal::meta_context::from(*ctx), index)} : meta_type{}; + } + + /** + * @brief Checks if a type supports direct casting to another type. + * @param other The meta type to test for. + * @return True if direct casting is allowed, false otherwise. + */ + [[nodiscard]] bool can_cast(const meta_type &other) const noexcept { + // casting this is UB in all cases but we aren't going to use the resulting pointer, so... + return other && ((*this == other) || (internal::try_cast(internal::meta_context::from(*ctx), fetch_node(), other.fetch_node().info->hash(), this) != nullptr)); + } + + /** + * @brief Checks whether a type supports conversion to another type. + * @param other The meta type to test for. + * @return True if the conversion is allowed, false otherwise. + */ + [[nodiscard]] bool can_convert(const meta_type &other) const noexcept { + if(const auto &to = other.info().hash(); (info().hash() == to) || ((fetch_node().conversion_helper != nullptr) && (other.is_arithmetic() || other.is_enum()))) { + return true; + } else if(const auto &from = fetch_node(); from.details) { + if(const auto *elem = internal::find_member<&internal::meta_conv_node::type>(from.details->conv, to); elem != nullptr) { + return true; + } + + for(auto &&curr: from.details->base) { + if(curr.type == to || meta_type{*ctx, curr.resolve(internal::meta_context::from(*ctx))}.can_convert(other)) { + return true; + } + } + } + + return false; + } + + /** + * @brief Returns a range to visit registered top-level base meta types. + * @return An iterable range to visit registered top-level base meta types. + */ + [[nodiscard]] meta_range base() const noexcept { + using range_type = meta_range; + return fetch_node().details ? range_type{{*ctx, fetch_node().details->base.cbegin()}, {*ctx, fetch_node().details->base.cend()}} : range_type{}; + } + + /** + * @brief Returns a range to visit registered top-level meta data. + * @return An iterable range to visit registered top-level meta data. + */ + [[nodiscard]] meta_range data() const noexcept { + using range_type = meta_range; + return fetch_node().details ? range_type{{*ctx, fetch_node().details->data.cbegin()}, {*ctx, fetch_node().details->data.cend()}} : range_type{}; + } + + /** + * @brief Lookup utility for meta data (bases are also visited). + * @param id Unique identifier. + * @param recursive True for a search in the base classes, false otherwise. + * @return The registered meta data for the given identifier, if any. + */ + [[nodiscard]] meta_data data(const id_type id, const bool recursive = true) const { + const auto *elem = internal::look_for<&internal::meta_type_descriptor::data>(internal::meta_context::from(*ctx), fetch_node(), id, recursive); + return (elem != nullptr) ? meta_data{*ctx, *elem} : meta_data{}; + } + + /** + * @brief Returns a range to visit registered top-level functions. + * @return An iterable range to visit registered top-level functions. + */ + [[nodiscard]] meta_range func() const noexcept { + using return_type = meta_range; + return fetch_node().details ? return_type{{*ctx, fetch_node().details->func.cbegin()}, {*ctx, fetch_node().details->func.cend()}} : return_type{}; + } + + /** + * @brief Lookup utility for meta functions (bases are also visited). + * @param id Unique identifier. + * @param recursive True for a search in the base classes, false otherwise. + * @return The registered meta function for the given identifier, if any. + */ + [[nodiscard]] meta_func func(const id_type id, const bool recursive = true) const { + const auto *elem = internal::look_for<&internal::meta_type_descriptor::func>(internal::meta_context::from(*ctx), fetch_node(), id, recursive); + return (elem != nullptr) ? meta_func{*ctx, *elem} : meta_func{}; + } + + /** + * @brief Creates an instance of the underlying type, if possible. + * @param args Parameters to use to construct the instance. + * @param sz Number of parameters to use to construct the instance. + * @return A wrapper containing the new instance, if any. + */ + [[nodiscard]] meta_any construct(meta_any *const args, const size_type sz) const { + if(const auto &ref = fetch_node(); ref.details) { + if(const auto *candidate = lookup(args, sz, false, [first = ref.details->ctor.cbegin(), last = ref.details->ctor.cend()]() mutable { return first == last ? nullptr : &*(first++); }); candidate) { + return candidate->invoke(*ctx, args); + } + } + + if(const auto &ref = fetch_node(); (sz == 0u) && (ref.default_constructor != nullptr)) { + return ref.default_constructor(*ctx); + } + + return meta_any{meta_ctx_arg, *ctx}; + } + + /** + * @copybrief construct + * @tparam Args Types of arguments to use to construct the instance. + * @param args Parameters to use to construct the instance. + * @return A wrapper containing the new instance, if any. + */ + template + [[nodiscard]] meta_any construct(Args &&...args) const { + return construct(std::array{meta_any{*ctx, std::forward(args)}...}.data(), sizeof...(Args)); + // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) + } + + /** + * @brief Wraps an opaque element of the underlying type. + * @param elem A valid pointer to an element of the underlying type. + * @param transfer_ownership True to transfer ownership, false otherwise. + * @return A wrapper that references the given instance. + */ + [[nodiscard]] meta_any from_void(void *elem, bool transfer_ownership = false) const { + return ((elem != nullptr) && (fetch_node().from_void != nullptr)) ? fetch_node().from_void(*ctx, elem, transfer_ownership ? elem : nullptr) : meta_any{meta_ctx_arg, *ctx}; + } + + /** + * @brief Wraps an opaque element of the underlying type. + * @param elem A valid pointer to an element of the underlying type. + * @return A wrapper that references the given instance. + */ + [[nodiscard]] meta_any from_void(const void *elem) const { + return ((elem != nullptr) && (fetch_node().from_void != nullptr)) ? fetch_node().from_void(*ctx, nullptr, elem) : meta_any{meta_ctx_arg, *ctx}; + } + + /** + * @brief Invokes a function given an identifier, if possible. + * @tparam Instance Type of instance to operate on. + * @param id Unique identifier. + * @param instance An instance that fits the underlying type. + * @param args Parameters to use to invoke the function. + * @param sz Number of parameters to use to invoke the function. + * @return A wrapper containing the returned value, if any. + */ + template + // NOLINTNEXTLINE(modernize-use-nodiscard) + meta_any invoke(const id_type id, Instance &&instance, meta_any *const args, const size_type sz) const { + meta_handle wrapped{*ctx, std::forward(instance)}; + + if(const auto &ref = fetch_node(); ref.details) { + if(auto *elem = internal::find_member<&internal::meta_func_node::id>(ref.details->func, id); elem != nullptr) { + if(const auto *candidate = lookup(args, sz, (wrapped->base().policy() == any_policy::cref), [curr = elem]() mutable { return (curr != nullptr) ? std::exchange(curr, curr->next.get()) : nullptr; }); candidate) { + return candidate->invoke(std::move(wrapped), args); + } + } + } + + for(auto &&curr: base()) { + if(auto elem = curr.second.invoke(id, *wrapped.operator->(), args, sz); elem) { + return elem; + } + } + + return meta_any{meta_ctx_arg, *ctx}; + } + + /** + * @copybrief invoke + * @param id Unique identifier. + * @tparam Instance Type of instance to operate on. + * @tparam Args Types of arguments to use to invoke the function. + * @param instance An instance that fits the underlying type. + * @param args Parameters to use to invoke the function. + * @return A wrapper containing the returned value, if any. + */ + template + // NOLINTNEXTLINE(modernize-use-nodiscard) + meta_any invoke(const id_type id, Instance &&instance, Args &&...args) const { + return invoke(id, std::forward(instance), std::array{meta_any{*ctx, std::forward(args)}...}.data(), sizeof...(Args)); + } + + /** + * @brief Sets the value of a given variable. + * @tparam Instance Type of instance to operate on. + * @tparam Type Type of value to assign. + * @param id Unique identifier. + * @param instance An instance that fits the underlying type. + * @param value Parameter to use to set the underlying variable. + * @return True in case of success, false otherwise. + */ + template + // NOLINTNEXTLINE(modernize-use-nodiscard) + bool set(const id_type id, Instance &&instance, Type &&value) const { + const auto candidate = data(id); + return candidate && candidate.set(std::forward(instance), std::forward(value)); + } + + /** + * @brief Gets the value of a given variable. + * @tparam Instance Type of instance to operate on. + * @param id Unique identifier. + * @param instance An instance that fits the underlying type. + * @return A wrapper containing the value of the underlying variable. + */ + template + [[nodiscard]] meta_any get(const id_type id, Instance &&instance) const { + const auto candidate = data(id); + return candidate ? candidate.get(std::forward(instance)) : meta_any{meta_ctx_arg, *ctx}; + } + + /*! @copydoc meta_data::traits */ + template + [[nodiscard]] Type traits() const noexcept { + return internal::meta_to_user_traits(fetch_node().traits); + } + + /*! @copydoc meta_data::custom */ + [[nodiscard]] meta_custom custom() const noexcept { + return fetch_node().custom; + } + + /*! @copydoc meta_data::operator bool */ + [[nodiscard]] explicit operator bool() const noexcept { + return (node != nullptr); + } + + /*! @copydoc meta_data::operator== */ + [[nodiscard]] bool operator==(const meta_type &other) const noexcept { + return (ctx == other.ctx) && (fetch_node().id == other.fetch_node().id); + } + +private: + mutable const internal::meta_type_node *node{}; + const meta_ctx *ctx{&locator::value_or()}; +}; + +/*! @copydoc operator!=(const meta_data &, const meta_data &) */ +[[nodiscard]] inline bool operator!=(const meta_type &lhs, const meta_type &rhs) noexcept { + return !(lhs == rhs); +} + +[[nodiscard]] inline meta_type meta_any::type() const noexcept { + return *this ? meta_type{*ctx, fetch_node()} : meta_type{}; +} + +template +// NOLINTNEXTLINE(modernize-use-nodiscard) +meta_any meta_any::invoke(const id_type id, Args &&...args) const { + return type().invoke(id, *this, std::forward(args)...); +} + +template +meta_any meta_any::invoke(const id_type id, Args &&...args) { + return type().invoke(id, *this, std::forward(args)...); +} + +template +bool meta_any::set(const id_type id, Type &&value) { + return type().set(id, *this, std::forward(value)); +} + +[[nodiscard]] inline meta_any meta_any::get(const id_type id) const { + return type().get(id, *this); +} + +[[nodiscard]] inline meta_any meta_any::get(const id_type id) { + return type().get(id, *this); +} + +[[nodiscard]] inline meta_any meta_any::allow_cast(const meta_type &type) const { + if(storage.has_value(type.info())) { + return as_ref(); + } else if(*this) { + if(const auto &from = fetch_node(); (from.conversion_helper != nullptr) && (type.is_arithmetic() || type.is_enum())) { + auto other = type.construct(); + const auto value = from.conversion_helper(nullptr, storage.data()); + other.fetch_node().conversion_helper(other.storage.data(), &value); + return other; + } + + if(const auto &from = fetch_node(); from.details) { + if(const auto *elem = internal::find_member<&internal::meta_conv_node::type>(from.details->conv, type.info().hash()); elem != nullptr) { + return elem->conv(*ctx, storage.data()); + } + + for(auto &&curr: from.details->base) { + if(auto other = curr.resolve(internal::meta_context::from(*ctx)).from_void(*ctx, nullptr, curr.cast(storage.data())); curr.type == type.info().hash()) { + return other; + } else if(auto from_base = std::as_const(other).allow_cast(type); from_base) { + return from_base; + } + } + } + } + + return meta_any{meta_ctx_arg, *ctx}; +} + +[[nodiscard]] inline bool meta_any::allow_cast(const meta_type &type) { + if(storage.has_value(type.info())) { + return true; + } else if(auto other = std::as_const(*this).allow_cast(type); other) { + if(other.storage.owner()) { + std::swap(*this, other); + } + + return true; + } + + return false; +} + +inline bool meta_any::assign(const meta_any &other) { + if(!storage.assign(other.storage)) { + auto value = other.allow_cast(type()); + return storage.assign(value.storage); + } + + return true; +} + +inline bool meta_any::assign(meta_any &&other) { + return storage.assign(std::move(other.storage)) || storage.assign(std::as_const(other).allow_cast(type()).storage); +} + +[[nodiscard]] inline meta_type meta_data::type() const noexcept { + return meta_type{*ctx, node_or_assert().type(internal::meta_context::from(*ctx))}; +} + +[[nodiscard]] inline meta_type meta_data::arg(const size_type index) const noexcept { + return index < arity() ? node_or_assert().arg(*ctx, index) : meta_type{}; +} + +[[nodiscard]] inline meta_type meta_func::ret() const noexcept { + return meta_type{*ctx, node_or_assert().ret(internal::meta_context::from(*ctx))}; +} + +[[nodiscard]] inline meta_type meta_func::arg(const size_type index) const noexcept { + return index < arity() ? node_or_assert().arg(*ctx, index) : meta_type{}; +} + +/*! @cond TURN_OFF_DOXYGEN */ +class meta_sequence_container::meta_iterator final { + using vtable_type = void(const void *, const std::ptrdiff_t, meta_any *); + + template + static void basic_vtable(const void *value, const std::ptrdiff_t offset, meta_any *other) { + const auto &it = *static_cast(value); + other ? other->emplace(*it) : std::advance(const_cast(it), offset); + } + +public: + using value_type = meta_any; + using pointer = input_iterator_pointer; + using reference = value_type; + using difference_type = std::ptrdiff_t; + using iterator_category = std::input_iterator_tag; + using iterator_concept = std::bidirectional_iterator_tag; + + meta_iterator() = default; + + template + meta_iterator(const meta_ctx &area, It iter) noexcept + : ctx{&area}, + vtable{&basic_vtable}, + handle{iter} {} + + meta_iterator &operator++() noexcept { + return vtable(handle.data(), 1, nullptr), *this; + } + + meta_iterator operator++(int value) noexcept { + meta_iterator orig = *this; + vtable(handle.data(), ++value, nullptr); + return orig; + } + + meta_iterator &operator--() noexcept { + return vtable(handle.data(), -1, nullptr), *this; + } + + meta_iterator operator--(int value) noexcept { + meta_iterator orig = *this; + vtable(handle.data(), --value, nullptr); + return orig; + } + + [[nodiscard]] reference operator*() const { + reference other{meta_ctx_arg, *ctx}; + vtable(handle.data(), 0, &other); + return other; + } + + [[nodiscard]] pointer operator->() const { + return operator*(); + } + + [[nodiscard]] explicit operator bool() const noexcept { + return (vtable != nullptr); + } + + [[nodiscard]] bool operator==(const meta_iterator &other) const noexcept { + return handle == other.handle; + } + + [[nodiscard]] const any &base() const noexcept { + return handle; + } + +private: + const meta_ctx *ctx{}; + vtable_type *vtable{}; + any handle{}; +}; + +[[nodiscard]] inline bool operator!=(const meta_sequence_container::iterator &lhs, const meta_sequence_container::iterator &rhs) noexcept { + return !(lhs == rhs); +} + +class meta_associative_container::meta_iterator final { + using vtable_type = void(const void *, std::pair *); + + template + static void basic_vtable(const void *value, std::pair *other) { + if(const auto &it = *static_cast(value); other) { + if constexpr(KeyOnly) { + other->first.emplace(*it); + } else { + other->first.emplacefirst))>(it->first); + other->second.emplacesecond))>(it->second); + } + } else { + ++const_cast(it); + } + } + +public: + using value_type = std::pair; + using pointer = input_iterator_pointer; + using reference = value_type; + using difference_type = std::ptrdiff_t; + using iterator_category = std::input_iterator_tag; + using iterator_concept = std::forward_iterator_tag; + + meta_iterator() = default; + + template + meta_iterator(const meta_ctx &area, std::bool_constant, It iter) noexcept + : ctx{&area}, + vtable{&basic_vtable}, + handle{iter} {} + + meta_iterator &operator++() noexcept { + return vtable(handle.data(), nullptr), *this; + } + + meta_iterator operator++(int) noexcept { + meta_iterator orig = *this; + vtable(handle.data(), nullptr); + return orig; + } + + [[nodiscard]] reference operator*() const { + reference other{{meta_ctx_arg, *ctx}, {meta_ctx_arg, *ctx}}; + vtable(handle.data(), &other); + return other; + } + + [[nodiscard]] pointer operator->() const { + return operator*(); + } + + [[nodiscard]] explicit operator bool() const noexcept { + return (vtable != nullptr); + } + + [[nodiscard]] bool operator==(const meta_iterator &other) const noexcept { + return handle == other.handle; + } + +private: + const meta_ctx *ctx{}; + vtable_type *vtable{}; + any handle{}; +}; + +[[nodiscard]] inline bool operator!=(const meta_associative_container::iterator &lhs, const meta_associative_container::iterator &rhs) noexcept { + return !(lhs == rhs); +} +/*! @endcond */ + +/** + * @brief Returns the meta value type of a container. + * @return The meta value type of the container. + */ +[[nodiscard]] inline meta_type meta_sequence_container::value_type() const noexcept { + return (value_type_node != nullptr) ? meta_type{*ctx, value_type_node(internal::meta_context::from(*ctx))} : meta_type{}; +} + +/** + * @brief Returns the size of a container. + * @return The size of the container. + */ +[[nodiscard]] inline meta_sequence_container::size_type meta_sequence_container::size() const noexcept { + return size_fn(data); +} + +/** + * @brief Resizes a container to contain a given number of elements. + * @param sz The new size of the container. + * @return True in case of success, false otherwise. + */ +inline bool meta_sequence_container::resize(const size_type sz) { + return !const_only && resize_fn(const_cast(data), sz); +} + +/** + * @brief Clears the content of a container. + * @return True in case of success, false otherwise. + */ +inline bool meta_sequence_container::clear() { + return !const_only && clear_fn(const_cast(data)); +} + +/** + * @brief Reserves storage for at least the given number of elements. + * @param sz The new capacity of the container. + * @return True in case of success, false otherwise. + */ +inline bool meta_sequence_container::reserve(const size_type sz) { + return !const_only && reserve_fn(const_cast(data), sz); +} + +/** + * @brief Returns an iterator to the first element of a container. + * @return An iterator to the first element of the container. + */ +[[nodiscard]] inline meta_sequence_container::iterator meta_sequence_container::begin() { + return begin_end_fn(*ctx, const_only ? nullptr : const_cast(data), data, false); +} + +/** + * @brief Returns an iterator that is past the last element of a container. + * @return An iterator that is past the last element of the container. + */ +[[nodiscard]] inline meta_sequence_container::iterator meta_sequence_container::end() { + return begin_end_fn(*ctx, const_only ? nullptr : const_cast(data), data, true); +} + +/** + * @brief Inserts an element at a specified location of a container. + * @param it Iterator before which the element will be inserted. + * @param value Element value to insert. + * @return A possibly invalid iterator to the inserted element. + */ +inline meta_sequence_container::iterator meta_sequence_container::insert(const iterator &it, meta_any value) { + // this abomination is necessary because only on macos value_type and const_reference are different types for std::vector + if(const auto &vtype = value_type_node(internal::meta_context::from(*ctx)); !const_only && (value.allow_cast({*ctx, vtype}) || value.allow_cast({*ctx, const_reference_node(internal::meta_context::from(*ctx))}))) { + const bool is_value_type = (value.type().info() == *vtype.info); + return insert_fn(*ctx, const_cast(data), is_value_type ? value.base().data() : nullptr, is_value_type ? nullptr : value.base().data(), it); + } + + return iterator{}; +} + +/** + * @brief Removes a given element from a container. + * @param it Iterator to the element to remove. + * @return A possibly invalid iterator following the last removed element. + */ +inline meta_sequence_container::iterator meta_sequence_container::erase(const iterator &it) { + return const_only ? iterator{} : erase_fn(*ctx, const_cast(data), it); +} + +/** + * @brief Returns a reference to the element at a given location of a container. + * @param pos The position of the element to return. + * @return A reference to the requested element properly wrapped. + */ +[[nodiscard]] inline meta_any meta_sequence_container::operator[](const size_type pos) { + auto it = begin(); + it.operator++(static_cast(pos) - 1); + return *it; +} + +/** + * @brief Returns false if a proxy is invalid, true otherwise. + * @return False if the proxy is invalid, true otherwise. + */ +[[nodiscard]] inline meta_sequence_container::operator bool() const noexcept { + return (data != nullptr); +} + +/** + * @brief Returns the meta key type of a container. + * @return The meta key type of the a container. + */ +[[nodiscard]] inline meta_type meta_associative_container::key_type() const noexcept { + return (key_type_node != nullptr) ? meta_type{*ctx, key_type_node(internal::meta_context::from(*ctx))} : meta_type{}; +} + +/** + * @brief Returns the meta mapped type of a container. + * @return The meta mapped type of the a container. + */ +[[nodiscard]] inline meta_type meta_associative_container::mapped_type() const noexcept { + return (mapped_type_node != nullptr) ? meta_type{*ctx, mapped_type_node(internal::meta_context::from(*ctx))} : meta_type{}; +} + +/*! @copydoc meta_sequence_container::value_type */ +[[nodiscard]] inline meta_type meta_associative_container::value_type() const noexcept { + return (value_type_node != nullptr) ? meta_type{*ctx, value_type_node(internal::meta_context::from(*ctx))} : meta_type{}; +} + +/*! @copydoc meta_sequence_container::size */ +[[nodiscard]] inline meta_associative_container::size_type meta_associative_container::size() const noexcept { + return size_fn(data); +} + +/*! @copydoc meta_sequence_container::clear */ +inline bool meta_associative_container::clear() { + return !const_only && clear_fn(const_cast(data)); +} + +/*! @copydoc meta_sequence_container::reserve */ +inline bool meta_associative_container::reserve(const size_type sz) { + return !const_only && reserve_fn(const_cast(data), sz); +} + +/*! @copydoc meta_sequence_container::begin */ +[[nodiscard]] inline meta_associative_container::iterator meta_associative_container::begin() { + return begin_end_fn(*ctx, const_only ? nullptr : const_cast(data), data, false); +} + +/*! @copydoc meta_sequence_container::end */ +[[nodiscard]] inline meta_associative_container::iterator meta_associative_container::end() { + return begin_end_fn(*ctx, const_only ? nullptr : const_cast(data), data, true); +} + +/** + * @brief Inserts a key-only or key/value element into a container. + * @param key The key of the element to insert. + * @param value The value of the element to insert, if needed. + * @return A bool denoting whether the insertion took place. + */ +inline bool meta_associative_container::insert(meta_any key, meta_any value = {}) { + return !const_only && key.allow_cast(meta_type{*ctx, key_type_node(internal::meta_context::from(*ctx))}) + && ((mapped_type_node == nullptr) || value.allow_cast(meta_type{*ctx, mapped_type_node(internal::meta_context::from(*ctx))})) + && insert_fn(const_cast(data), key.base().data(), value.base().data()); +} + +/** + * @brief Removes the specified element from a container. + * @param key The key of the element to remove. + * @return A bool denoting whether the removal took place. + */ +inline meta_associative_container::size_type meta_associative_container::erase(meta_any key) { + return (!const_only && key.allow_cast(meta_type{*ctx, key_type_node(internal::meta_context::from(*ctx))})) ? erase_fn(const_cast(data), key.base().data()) : 0u; +} + +/** + * @brief Returns an iterator to the element with a given key, if any. + * @param key The key of the element to search. + * @return An iterator to the element with the given key, if any. + */ +[[nodiscard]] inline meta_associative_container::iterator meta_associative_container::find(meta_any key) { + return key.allow_cast(meta_type{*ctx, key_type_node(internal::meta_context::from(*ctx))}) ? find_fn(*ctx, const_only ? nullptr : const_cast(data), data, key.base().data()) : iterator{}; +} + +/** + * @brief Returns false if a proxy is invalid, true otherwise. + * @return False if the proxy is invalid, true otherwise. + */ +[[nodiscard]] inline meta_associative_container::operator bool() const noexcept { + return (data != nullptr); +} + +} // namespace entt + +#endif + +// #include "type_traits.hpp" + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct sequence_container_extent: integral_constant {}; + +template +struct sequence_container_extent>>>: integral_constant> {}; + +template +inline constexpr std::size_t sequence_container_extent_v = sequence_container_extent::value; + +template +struct key_only_associative_container: std::true_type {}; + +template +struct key_only_associative_container>: std::false_type {}; + +template +inline constexpr bool key_only_associative_container_v = key_only_associative_container::value; + +template +struct reserve_aware_container: std::false_type {}; + +template +struct reserve_aware_container>: std::true_type {}; + +template +inline constexpr bool reserve_aware_container_v = reserve_aware_container::value; + +} // namespace internal +/*! @endcond */ + +/** + * @brief General purpose implementation of meta sequence container traits. + * @tparam Type Type of underlying sequence container. + */ +template +struct basic_meta_sequence_container_traits { + static_assert(std::is_same_v>>, "Unexpected type"); + + /*! @brief Unsigned integer type. */ + using size_type = typename meta_sequence_container::size_type; + /*! @brief Meta iterator type. */ + using iterator = typename meta_sequence_container::iterator; + + /*! @brief Number of elements, or `meta_dynamic_extent` if dynamic. */ + static constexpr std::size_t extent = internal::sequence_container_extent_v; + /*! @brief True in case of fixed size containers, false otherwise. */ + [[deprecated("use ::extent instead")]] static constexpr bool fixed_size = (extent != meta_dynamic_extent); + + /** + * @brief Returns the number of elements in a container. + * @param container Opaque pointer to a container of the given type. + * @return Number of elements. + */ + [[nodiscard]] static size_type size(const void *container) { + return static_cast(container)->size(); + } + + /** + * @brief Clears a container. + * @param container Opaque pointer to a container of the given type. + * @return True in case of success, false otherwise. + */ + [[nodiscard]] static bool clear([[maybe_unused]] void *container) { + if constexpr(extent == meta_dynamic_extent) { + static_cast(container)->clear(); + return true; + } else { + return false; + } + } + + /** + * @brief Increases the capacity of a container. + * @param container Opaque pointer to a container of the given type. + * @param sz Desired capacity. + * @return True in case of success, false otherwise. + */ + [[nodiscard]] static bool reserve([[maybe_unused]] void *container, [[maybe_unused]] const size_type sz) { + if constexpr(internal::reserve_aware_container_v) { + static_cast(container)->reserve(sz); + return true; + } else { + return false; + } + } + + /** + * @brief Resizes a container. + * @param container Opaque pointer to a container of the given type. + * @param sz The new number of elements. + * @return True in case of success, false otherwise. + */ + [[nodiscard]] static bool resize([[maybe_unused]] void *container, [[maybe_unused]] const size_type sz) { + if constexpr((extent == meta_dynamic_extent) && std::is_default_constructible_v) { + static_cast(container)->resize(sz); + return true; + } else { + return false; + } + } + + /** + * @brief Returns a possibly const iterator to the beginning or the end. + * @param area The context to pass to the newly created iterator. + * @param container Opaque pointer to a container of the given type. + * @param as_const Const opaque pointer fallback. + * @param end False to get a pointer that is past the last element. + * @return An iterator to the first or past the last element of the + * container. + */ + static iterator iter(const meta_ctx &area, void *container, const void *as_const, const bool end) { + return (container == nullptr) + ? iterator{area, end ? static_cast(as_const)->cend() : static_cast(as_const)->cbegin()} + : iterator{area, end ? static_cast(container)->end() : static_cast(container)->begin()}; + } + + /** + * @brief Assigns one element to a container and constructs its object from + * a given opaque instance. + * @param area The context to pass to the newly created iterator. + * @param container Opaque pointer to a container of the given type. + * @param value Optional opaque instance of the object to construct (as + * value type). + * @param cref Optional opaque instance of the object to construct (as + * decayed const reference type). + * @param it Iterator before which the element will be inserted. + * @return A possibly invalid iterator to the inserted element. + */ + [[nodiscard]] static iterator insert([[maybe_unused]] const meta_ctx &area, [[maybe_unused]] void *container, [[maybe_unused]] const void *value, [[maybe_unused]] const void *cref, [[maybe_unused]] const iterator &it) { + if constexpr(extent == meta_dynamic_extent) { + auto *const non_const = any_cast(&it.base()); + return {area, static_cast(container)->insert( + non_const ? *non_const : any_cast(it.base()), + (value != nullptr) ? *static_cast(value) : *static_cast *>(cref))}; + } else { + return iterator{}; + } + } + + /** + * @brief Erases an element from a container. + * @param area The context to pass to the newly created iterator. + * @param container Opaque pointer to a container of the given type. + * @param it An opaque iterator to the element to erase. + * @return A possibly invalid iterator following the last removed element. + */ + [[nodiscard]] static iterator erase([[maybe_unused]] const meta_ctx &area, [[maybe_unused]] void *container, [[maybe_unused]] const iterator &it) { + if constexpr(extent == meta_dynamic_extent) { + auto *const non_const = any_cast(&it.base()); + return {area, static_cast(container)->erase(non_const ? *non_const : any_cast(it.base()))}; + } else { + return iterator{}; + } + } +}; + +/** + * @brief General purpose implementation of meta associative container traits. + * @tparam Type Type of underlying associative container. + */ +template +struct basic_meta_associative_container_traits { + static_assert(std::is_same_v>>, "Unexpected type"); + + /*! @brief Unsigned integer type. */ + using size_type = typename meta_associative_container::size_type; + /*! @brief Meta iterator type. */ + using iterator = typename meta_associative_container::iterator; + + /*! @brief True in case of key-only containers, false otherwise. */ + static constexpr bool key_only = internal::key_only_associative_container_v; + + /** + * @brief Returns the number of elements in a container. + * @param container Opaque pointer to a container of the given type. + * @return Number of elements. + */ + [[nodiscard]] static size_type size(const void *container) { + return static_cast(container)->size(); + } + + /** + * @brief Clears a container. + * @param container Opaque pointer to a container of the given type. + * @return True in case of success, false otherwise. + */ + [[nodiscard]] static bool clear(void *container) { + static_cast(container)->clear(); + return true; + } + + /** + * @brief Increases the capacity of a container. + * @param container Opaque pointer to a container of the given type. + * @param sz Desired capacity. + * @return True in case of success, false otherwise. + */ + [[nodiscard]] static bool reserve([[maybe_unused]] void *container, [[maybe_unused]] const size_type sz) { + if constexpr(internal::reserve_aware_container_v) { + static_cast(container)->reserve(sz); + return true; + } else { + return false; + } + } + + /** + * @brief Returns a possibly const iterator to the beginning or the end. + * @param area The context to pass to the newly created iterator. + * @param container Opaque pointer to a container of the given type. + * @param as_const Const opaque pointer fallback. + * @param end False to get a pointer that is past the last element. + * @return An iterator to the first or past the last element of the + * container. + */ + static iterator iter(const meta_ctx &area, void *container, const void *as_const, const bool end) { + return (container == nullptr) + ? iterator{area, std::bool_constant{}, end ? static_cast(as_const)->cend() : static_cast(as_const)->cbegin()} + : iterator{area, std::bool_constant{}, end ? static_cast(container)->end() : static_cast(container)->begin()}; + } + + /** + * @brief Inserts an element into a container, if the key does not exist. + * @param container Opaque pointer to a container of the given type. + * @param key An opaque key value of an element to insert. + * @param value Optional opaque value to insert (key-value containers). + * @return True if the insertion took place, false otherwise. + */ + [[nodiscard]] static bool insert(void *container, const void *key, [[maybe_unused]] const void *value) { + if constexpr(key_only) { + return static_cast(container)->insert(*static_cast(key)).second; + } else { + return static_cast(container)->emplace(*static_cast(key), *static_cast(value)).second; + } + } + + /** + * @brief Removes an element from a container. + * @param container Opaque pointer to a container of the given type. + * @param key An opaque key value of an element to remove. + * @return Number of elements removed (either 0 or 1). + */ + [[nodiscard]] static size_type erase(void *container, const void *key) { + return static_cast(container)->erase(*static_cast(key)); + } + + /** + * @brief Finds an element with a given key. + * @param area The context to pass to the newly created iterator. + * @param container Opaque pointer to a container of the given type. + * @param as_const Const opaque pointer fallback. + * @param key Opaque key value of an element to search for. + * @return An iterator to the element with the given key, if any. + */ + static iterator find(const meta_ctx &area, void *container, const void *as_const, const void *key) { + return (container != nullptr) ? iterator{area, std::bool_constant{}, static_cast(container)->find(*static_cast(key))} + : iterator{area, std::bool_constant{}, static_cast(as_const)->find(*static_cast(key))}; + } +}; + +/** + * @brief Meta sequence container traits for `std::vector`s of any type. + * @tparam Args Template arguments for the container. + */ +template +struct meta_sequence_container_traits> + : basic_meta_sequence_container_traits> {}; + +/** + * @brief Meta sequence container traits for `std::array`s of any type. + * @tparam Type Template arguments for the container. + * @tparam N Template arguments for the container. + */ +template +struct meta_sequence_container_traits> + : basic_meta_sequence_container_traits> {}; + +/** + * @brief Meta sequence container traits for `std::list`s of any type. + * @tparam Args Template arguments for the container. + */ +template +struct meta_sequence_container_traits> + : basic_meta_sequence_container_traits> {}; + +/** + * @brief Meta sequence container traits for `std::deque`s of any type. + * @tparam Args Template arguments for the container. + */ +template +struct meta_sequence_container_traits> + : basic_meta_sequence_container_traits> {}; + +/** + * @brief Meta associative container traits for `std::map`s of any type. + * @tparam Args Template arguments for the container. + */ +template +struct meta_associative_container_traits> + : basic_meta_associative_container_traits> {}; + +/** + * @brief Meta associative container traits for `std::unordered_map`s of any + * type. + * @tparam Args Template arguments for the container. + */ +template +struct meta_associative_container_traits> + : basic_meta_associative_container_traits> {}; + +/** + * @brief Meta associative container traits for `std::set`s of any type. + * @tparam Args Template arguments for the container. + */ +template +struct meta_associative_container_traits> + : basic_meta_associative_container_traits> {}; + +/** + * @brief Meta associative container traits for `std::unordered_set`s of any + * type. + * @tparam Args Template arguments for the container. + */ +template +struct meta_associative_container_traits> + : basic_meta_associative_container_traits> {}; + +/** + * @brief Meta associative container traits for `dense_map`s of any type. + * @tparam Args Template arguments for the container. + */ +template +struct meta_associative_container_traits> + : basic_meta_associative_container_traits> {}; + +/** + * @brief Meta associative container traits for `dense_set`s of any type. + * @tparam Args Template arguments for the container. + */ +template +struct meta_associative_container_traits> + : basic_meta_associative_container_traits> {}; + +} // namespace entt + +#endif + +// #include "meta/context.hpp" +#ifndef ENTT_META_CTX_HPP +#define ENTT_META_CTX_HPP + +#include +// #include "../container/dense_map.hpp" + +// #include "../core/fwd.hpp" + +// #include "../core/utility.hpp" + +// #include "fwd.hpp" + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +struct meta_type_node; + +struct meta_context { + dense_map, identity> value; + + [[nodiscard]] inline static meta_context &from(meta_ctx &); + [[nodiscard]] inline static const meta_context &from(const meta_ctx &); +}; + +} // namespace internal +/*! @endcond */ + +/*! @brief Disambiguation tag for constructors and the like. */ +class meta_ctx_arg_t final {}; + +/*! @brief Constant of type meta_context_arg_t used to disambiguate calls. */ +inline constexpr meta_ctx_arg_t meta_ctx_arg{}; + +/*! @brief Opaque meta context type. */ +class meta_ctx: private internal::meta_context { + // attorney idiom like model to access the base class + friend struct internal::meta_context; +}; + +/*! @cond TURN_OFF_DOXYGEN */ +[[nodiscard]] inline internal::meta_context &internal::meta_context::from(meta_ctx &ctx) { + return ctx; +} + +[[nodiscard]] inline const internal::meta_context &internal::meta_context::from(const meta_ctx &ctx) { + return ctx; +} +/*! @endcond */ + +} // namespace entt + +#endif + +// #include "meta/factory.hpp" +#ifndef ENTT_META_FACTORY_HPP +#define ENTT_META_FACTORY_HPP + +#include +#include +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "../core/bit.hpp" + +// #include "../core/fwd.hpp" + +// #include "../core/hashed_string.hpp" +#ifndef ENTT_CORE_HASHED_STRING_HPP +#define ENTT_CORE_HASHED_STRING_HPP + +#include +#include +// #include "fwd.hpp" + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct fnv_1a_params; + +template<> +struct fnv_1a_params { + static constexpr auto offset = 2166136261; + static constexpr auto prime = 16777619; +}; + +template<> +struct fnv_1a_params { + static constexpr auto offset = 14695981039346656037ull; + static constexpr auto prime = 1099511628211ull; +}; + +template +struct basic_hashed_string { + using value_type = Char; + using size_type = std::size_t; + using hash_type = id_type; + + const value_type *repr{}; + hash_type hash{fnv_1a_params<>::offset}; + size_type length{}; +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Zero overhead unique identifier. + * + * A hashed string is a compile-time tool that allows users to use + * human-readable identifiers in the codebase while using their numeric + * counterparts at runtime.
+ * Because of that, a hashed string can also be used in constant expressions if + * required. + * + * @warning + * This class doesn't take ownership of user-supplied strings nor does it make a + * copy of them. + * + * @tparam Char Character type. + */ +template +class basic_hashed_string: internal::basic_hashed_string { + using base_type = internal::basic_hashed_string; + using params = internal::fnv_1a_params<>; + + struct const_wrapper { + // non-explicit constructor on purpose + constexpr const_wrapper(const typename base_type::value_type *str) noexcept + : repr{str} {} + + const typename base_type::value_type *repr; + }; + +public: + /*! @brief Character type. */ + using value_type = typename base_type::value_type; + /*! @brief Unsigned integer type. */ + using size_type = typename base_type::size_type; + /*! @brief Unsigned integer type. */ + using hash_type = typename base_type::hash_type; + + /** + * @brief Returns directly the numeric representation of a string view. + * @param str Human-readable identifier. + * @param len Length of the string to hash. + * @return The numeric representation of the string. + */ + [[nodiscard]] static constexpr hash_type value(const value_type *str, const size_type len) noexcept { + return basic_hashed_string{str, len}; + } + + /** + * @brief Returns directly the numeric representation of a string. + * @tparam N Number of characters of the identifier. + * @param str Human-readable identifier. + * @return The numeric representation of the string. + */ + template + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) + [[nodiscard]] static ENTT_CONSTEVAL hash_type value(const value_type (&str)[N]) noexcept { + return basic_hashed_string{str}; + } + + /** + * @brief Returns directly the numeric representation of a string. + * @param wrapper Helps achieving the purpose by relying on overloading. + * @return The numeric representation of the string. + */ + [[nodiscard]] static constexpr hash_type value(const_wrapper wrapper) noexcept { + return basic_hashed_string{wrapper}; + } + + /*! @brief Constructs an empty hashed string. */ + constexpr basic_hashed_string() noexcept + : basic_hashed_string{nullptr, 0u} {} + + /** + * @brief Constructs a hashed string from a string view. + * @param str Human-readable identifier. + * @param len Length of the string to hash. + */ + constexpr basic_hashed_string(const value_type *str, const size_type len) noexcept + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay) + : base_type{str} { + // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic) + for(; base_type::length < len; ++base_type::length) { + base_type::hash = (base_type::hash ^ static_cast(str[base_type::length])) * params::prime; + } + // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic) + } + + /** + * @brief Constructs a hashed string from an array of const characters. + * @tparam N Number of characters of the identifier. + * @param str Human-readable identifier. + */ + template + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) + ENTT_CONSTEVAL basic_hashed_string(const value_type (&str)[N]) noexcept + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay) + : base_type{str} { + for(; str[base_type::length]; ++base_type::length) { + base_type::hash = (base_type::hash ^ static_cast(str[base_type::length])) * params::prime; + } + } + + /** + * @brief Explicit constructor on purpose to avoid constructing a hashed + * string directly from a `const value_type *`. + * + * @warning + * The lifetime of the string is not extended nor is it copied. + * + * @param wrapper Helps achieving the purpose by relying on overloading. + */ + explicit constexpr basic_hashed_string(const_wrapper wrapper) noexcept + : base_type{wrapper.repr} { + // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic) + for(; wrapper.repr[base_type::length]; ++base_type::length) { + base_type::hash = (base_type::hash ^ static_cast(wrapper.repr[base_type::length])) * params::prime; + } + // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic) + } + + /** + * @brief Returns the size of a hashed string. + * @return The size of the hashed string. + */ + [[nodiscard]] constexpr size_type size() const noexcept { + return base_type::length; + } + + /** + * @brief Returns the human-readable representation of a hashed string. + * @return The string used to initialize the hashed string. + */ + [[nodiscard]] constexpr const value_type *data() const noexcept { + return base_type::repr; + } + + /** + * @brief Returns the numeric representation of a hashed string. + * @return The numeric representation of the hashed string. + */ + [[nodiscard]] constexpr hash_type value() const noexcept { + return base_type::hash; + } + + /*! @copydoc data */ + [[nodiscard]] explicit constexpr operator const value_type *() const noexcept { + return data(); + } + + /** + * @brief Returns the numeric representation of a hashed string. + * @return The numeric representation of the hashed string. + */ + [[nodiscard]] constexpr operator hash_type() const noexcept { + return value(); + } +}; + +/** + * @brief Deduction guide. + * @tparam Char Character type. + * @param str Human-readable identifier. + * @param len Length of the string to hash. + */ +template +basic_hashed_string(const Char *str, std::size_t len) -> basic_hashed_string; + +/** + * @brief Deduction guide. + * @tparam Char Character type. + * @tparam N Number of characters of the identifier. + * @param str Human-readable identifier. + */ +template +// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) +basic_hashed_string(const Char (&str)[N]) -> basic_hashed_string; + +/** + * @brief Compares two hashed strings. + * @tparam Char Character type. + * @param lhs A valid hashed string. + * @param rhs A valid hashed string. + * @return True if the two hashed strings are identical, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator==(const basic_hashed_string &lhs, const basic_hashed_string &rhs) noexcept { + return lhs.value() == rhs.value(); +} + +/** + * @brief Compares two hashed strings. + * @tparam Char Character type. + * @param lhs A valid hashed string. + * @param rhs A valid hashed string. + * @return True if the two hashed strings differ, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator!=(const basic_hashed_string &lhs, const basic_hashed_string &rhs) noexcept { + return !(lhs == rhs); +} + +/** + * @brief Compares two hashed strings. + * @tparam Char Character type. + * @param lhs A valid hashed string. + * @param rhs A valid hashed string. + * @return True if the first element is less than the second, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator<(const basic_hashed_string &lhs, const basic_hashed_string &rhs) noexcept { + return lhs.value() < rhs.value(); +} + +/** + * @brief Compares two hashed strings. + * @tparam Char Character type. + * @param lhs A valid hashed string. + * @param rhs A valid hashed string. + * @return True if the first element is less than or equal to the second, false + * otherwise. + */ +template +[[nodiscard]] constexpr bool operator<=(const basic_hashed_string &lhs, const basic_hashed_string &rhs) noexcept { + return !(rhs < lhs); +} + +/** + * @brief Compares two hashed strings. + * @tparam Char Character type. + * @param lhs A valid hashed string. + * @param rhs A valid hashed string. + * @return True if the first element is greater than the second, false + * otherwise. + */ +template +[[nodiscard]] constexpr bool operator>(const basic_hashed_string &lhs, const basic_hashed_string &rhs) noexcept { + return rhs < lhs; +} + +/** + * @brief Compares two hashed strings. + * @tparam Char Character type. + * @param lhs A valid hashed string. + * @param rhs A valid hashed string. + * @return True if the first element is greater than or equal to the second, + * false otherwise. + */ +template +[[nodiscard]] constexpr bool operator>=(const basic_hashed_string &lhs, const basic_hashed_string &rhs) noexcept { + return !(lhs < rhs); +} + +inline namespace literals { + +/** + * @brief User defined literal for hashed strings. + * @param str The literal without its suffix. + * @return A properly initialized hashed string. + */ +[[nodiscard]] ENTT_CONSTEVAL hashed_string operator""_hs(const char *str, std::size_t) noexcept { + return hashed_string{str}; +} + +/** + * @brief User defined literal for hashed wstrings. + * @param str The literal without its suffix. + * @return A properly initialized hashed wstring. + */ +[[nodiscard]] ENTT_CONSTEVAL hashed_wstring operator""_hws(const wchar_t *str, std::size_t) noexcept { + return hashed_wstring{str}; +} + +} // namespace literals + +} // namespace entt + +#endif + +// #include "../core/type_info.hpp" + +// #include "../core/type_traits.hpp" + +// #include "../locator/locator.hpp" + +// #include "context.hpp" + +// #include "fwd.hpp" + +// #include "meta.hpp" + +// #include "node.hpp" + +// #include "policy.hpp" +#ifndef ENTT_META_POLICY_HPP +#define ENTT_META_POLICY_HPP + +#include + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +struct meta_policy {}; + +} // namespace internal +/*! @endcond */ + +/*! @brief Empty class type used to request the _as-is_ policy. */ +struct as_value_t final: private internal::meta_policy { + /*! @cond TURN_OFF_DOXYGEN */ + template + static constexpr bool value = true; + /*! @endcond */ +}; + +/*! @brief Empty class type used to request the _as void_ policy. */ +struct as_void_t final: private internal::meta_policy { + /*! @cond TURN_OFF_DOXYGEN */ + template + static constexpr bool value = true; + /*! @endcond */ +}; + +/*! @brief Empty class type used to request the _as ref_ policy. */ +struct as_ref_t final: private internal::meta_policy { + /*! @cond TURN_OFF_DOXYGEN */ + template + static constexpr bool value = std::is_reference_v && !std::is_const_v>; + /*! @endcond */ +}; + +/*! @brief Empty class type used to request the _as cref_ policy. */ +struct as_cref_t final: private internal::meta_policy { + /*! @cond TURN_OFF_DOXYGEN */ + template + static constexpr bool value = std::is_reference_v; + /*! @endcond */ +}; + +/*! @brief Empty class type used to request the _as auto_ policy. */ +struct as_is_t final: private internal::meta_policy { + /*! @cond TURN_OFF_DOXYGEN */ + template + static constexpr bool value = true; + /*! @endcond */ +}; + +/** + * @brief Provides the member constant `value` to true if a type also is a meta + * policy, false otherwise. + * @tparam Type Type to check. + */ +template +struct is_meta_policy + : std::bool_constant> {}; + +/** + * @brief Helper variable template. + * @tparam Type Type to check. + */ +template +inline constexpr bool is_meta_policy_v = is_meta_policy::value; + +} // namespace entt + +#endif + +// #include "range.hpp" + +// #include "resolve.hpp" +#ifndef ENTT_META_RESOLVE_HPP +#define ENTT_META_RESOLVE_HPP + +#include +// #include "../core/type_info.hpp" + +// #include "../locator/locator.hpp" + +// #include "context.hpp" + +// #include "meta.hpp" + +// #include "node.hpp" + +// #include "range.hpp" + + +namespace entt { + +/** + * @brief Returns the meta type associated with a given type. + * @tparam Type Type to use to search for a meta type. + * @param ctx The context from which to search for meta types. + * @return The meta type associated with the given type, if any. + */ +template +[[nodiscard]] meta_type resolve(const meta_ctx &ctx) noexcept { + const auto &context = internal::meta_context::from(ctx); + return {ctx, internal::resolve>>(context)}; +} + +/** + * @brief Returns the meta type associated with a given type. + * @tparam Type Type to use to search for a meta type. + * @return The meta type associated with the given type, if any. + */ +template +[[nodiscard]] meta_type resolve() noexcept { + return resolve(locator::value_or()); +} + +/** + * @brief Returns a range to use to visit all meta types. + * @param ctx The context from which to search for meta types. + * @return An iterable range to use to visit all meta types. + */ +[[nodiscard]] inline meta_range resolve(const meta_ctx &ctx) noexcept { + const auto &context = internal::meta_context::from(ctx); + return {{ctx, context.value.cbegin()}, {ctx, context.value.cend()}}; +} + +/** + * @brief Returns a range to use to visit all meta types. + * @return An iterable range to use to visit all meta types. + */ +[[nodiscard]] inline meta_range resolve() noexcept { + return resolve(locator::value_or()); +} + +/** + * @brief Returns the meta type associated with a given identifier, if any. + * @param ctx The context from which to search for meta types. + * @param id Unique identifier. + * @return The meta type associated with the given identifier, if any. + */ +[[nodiscard]] inline meta_type resolve(const meta_ctx &ctx, const id_type id) noexcept { + for(auto &&curr: resolve(ctx)) { + if(curr.second.id() == id) { + return curr.second; + } + } + + return meta_type{}; +} + +/** + * @brief Returns the meta type associated with a given identifier, if any. + * @param id Unique identifier. + * @return The meta type associated with the given identifier, if any. + */ +[[nodiscard]] inline meta_type resolve(const id_type id) noexcept { + return resolve(locator::value_or(), id); +} + +/** + * @brief Returns the meta type associated with a given type info object. + * @param ctx The context from which to search for meta types. + * @param info The type info object of the requested type. + * @return The meta type associated with the given type info object, if any. + */ +[[nodiscard]] inline meta_type resolve(const meta_ctx &ctx, const type_info &info) noexcept { + const auto &context = internal::meta_context::from(ctx); + const auto *elem = internal::try_resolve(context, info); + return (elem != nullptr) ? meta_type{ctx, *elem} : meta_type{}; +} + +/** + * @brief Returns the meta type associated with a given type info object. + * @param info The type info object of the requested type. + * @return The meta type associated with the given type info object, if any. + */ +[[nodiscard]] inline meta_type resolve(const type_info &info) noexcept { + return resolve(locator::value_or(), info); +} + +} // namespace entt + +#endif + +// #include "utility.hpp" +#ifndef ENTT_META_UTILITY_HPP +#define ENTT_META_UTILITY_HPP + +#include +#include +#include +#include +// #include "../core/type_traits.hpp" + +// #include "../locator/locator.hpp" + +// #include "meta.hpp" + +// #include "node.hpp" + +// #include "policy.hpp" + + +namespace entt { + +/** + * @brief Meta function descriptor traits. + * @tparam Ret Function return type. + * @tparam Args Function arguments. + * @tparam Static Function staticness. + * @tparam Const Function constness. + */ +template +struct meta_function_descriptor_traits { + /*! @brief Meta function return type. */ + using return_type = Ret; + /*! @brief Meta function arguments. */ + using args_type = Args; + + /*! @brief True if the meta function is static, false otherwise. */ + static constexpr bool is_static = Static; + /*! @brief True if the meta function is const, false otherwise. */ + static constexpr bool is_const = Const; +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct meta_function_descriptor; + +/** + * @brief Meta function descriptor. + * @tparam Type Reflected type to which the meta function is associated. + * @tparam Ret Function return type. + * @tparam Class Actual owner of the member function. + * @tparam Args Function arguments. + */ +template +struct meta_function_descriptor + : meta_function_descriptor_traits< + Ret, + std::conditional_t, type_list, type_list>, + !std::is_base_of_v, + true> {}; + +/** + * @brief Meta function descriptor. + * @tparam Type Reflected type to which the meta function is associated. + * @tparam Ret Function return type. + * @tparam Class Actual owner of the member function. + * @tparam Args Function arguments. + */ +template +struct meta_function_descriptor + : meta_function_descriptor_traits< + Ret, + std::conditional_t, type_list, type_list>, + !std::is_base_of_v, + false> {}; + +/** + * @brief Meta function descriptor. + * @tparam Type Reflected type to which the meta data is associated. + * @tparam Class Actual owner of the data member. + * @tparam Ret Data member type. + */ +template +struct meta_function_descriptor + : meta_function_descriptor_traits< + Ret &, + std::conditional_t, type_list<>, type_list>, + !std::is_base_of_v, + false> {}; + +/** + * @brief Meta function descriptor. + * @tparam Type Reflected type to which the meta function is associated. + * @tparam Ret Function return type. + * @tparam MaybeType First function argument. + * @tparam Args Other function arguments. + */ +template +struct meta_function_descriptor + : meta_function_descriptor_traits< + Ret, + std::conditional_t< + std::is_same_v>, Type> || std::is_base_of_v>, Type>, + type_list, + type_list>, + !(std::is_same_v>, Type> || std::is_base_of_v>, Type>), + std::is_const_v> && (std::is_same_v>, Type> || std::is_base_of_v>, Type>)> {}; + +/** + * @brief Meta function descriptor. + * @tparam Type Reflected type to which the meta function is associated. + * @tparam Ret Function return type. + */ +template +struct meta_function_descriptor + : meta_function_descriptor_traits< + Ret, + type_list<>, + true, + false> {}; + +/** + * @brief Meta function helper. + * + * Converts a function type to be associated with a reflected type into its meta + * function descriptor. + * + * @tparam Type Reflected type to which the meta function is associated. + * @tparam Candidate The actual function to associate with the reflected type. + */ +template +class meta_function_helper { + template + static constexpr meta_function_descriptor get_rid_of_noexcept(Ret (Class::*)(Args...) const); + + template + static constexpr meta_function_descriptor get_rid_of_noexcept(Ret (Class::*)(Args...)); + + template>> + static constexpr meta_function_descriptor get_rid_of_noexcept(Ret Class::*); + + template + static constexpr meta_function_descriptor get_rid_of_noexcept(Ret (*)(Args...)); + + template + static constexpr meta_function_descriptor get_rid_of_noexcept(Class); + +public: + /*! @brief The meta function descriptor of the given function. */ + using type = decltype(get_rid_of_noexcept(std::declval())); +}; + +/** + * @brief Helper type. + * @tparam Type Reflected type to which the meta function is associated. + * @tparam Candidate The actual function to associate with the reflected type. + */ +template +using meta_function_helper_t = typename meta_function_helper::type; + +/** + * @brief Wraps a value depending on the given policy. + * + * This function always returns a wrapped value in the requested context.
+ * Therefore, if the passed value is itself a wrapped object with a different + * context, it undergoes a rebinding to the requested context. + * + * @tparam Policy Optional policy (no policy set by default). + * @tparam Type Type of value to wrap. + * @param ctx The context from which to search for meta types. + * @param value Value to wrap. + * @return A meta any containing the returned value, if any. + */ +template +[[nodiscard]] std::enable_if_t, meta_any> meta_dispatch(const meta_ctx &ctx, [[maybe_unused]] Type &&value) { + if constexpr(std::is_same_v) { + static_assert(std::is_lvalue_reference_v, "Invalid type"); + return meta_any{ctx, std::in_place_type &>, std::as_const(value)}; + } else if constexpr(std::is_same_v || (std::is_same_v && std::is_lvalue_reference_v)) { + return meta_any{ctx, std::in_place_type, value}; + } else if constexpr(std::is_same_v) { + return meta_any{ctx, std::in_place_type}; + } else { + return meta_any{ctx, std::forward(value)}; + } +} + +/** + * @brief Wraps a value depending on the given policy. + * @tparam Policy Optional policy (no policy set by default). + * @tparam Type Type of value to wrap. + * @param value Value to wrap. + * @return A meta any containing the returned value, if any. + */ +template +[[nodiscard]] std::enable_if_t, meta_any> meta_dispatch(Type &&value) { + return meta_dispatch(locator::value_or(), std::forward(value)); +} + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +[[nodiscard]] meta_any meta_invoke_with_args(const meta_ctx &ctx, Candidate &&candidate, Args &&...args) { + if constexpr(std::is_void_v(candidate), args...))>) { + std::invoke(std::forward(candidate), args...); + return meta_any{ctx, std::in_place_type}; + } else { + return meta_dispatch(ctx, std::invoke(std::forward(candidate), args...)); + } +} + +template +[[nodiscard]] meta_any meta_invoke(meta_any &instance, Candidate &&candidate, [[maybe_unused]] meta_any *const args, std::index_sequence) { + using descriptor = meta_function_helper_t>; + + // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic) - waiting for C++20 (and std::span) + if constexpr(std::is_invocable_v, const Type &, type_list_element_t...>) { + if(const auto *const clazz = instance.try_cast(); clazz && ((args + Index)->allow_cast>() && ...)) { + return meta_invoke_with_args(instance.context(), std::forward(candidate), *clazz, (args + Index)->cast>()...); + } + } else if constexpr(std::is_invocable_v, Type &, type_list_element_t...>) { + if(auto *const clazz = instance.try_cast(); clazz && ((args + Index)->allow_cast>() && ...)) { + return meta_invoke_with_args(instance.context(), std::forward(candidate), *clazz, (args + Index)->cast>()...); + } + } else { + if(((args + Index)->allow_cast>() && ...)) { + return meta_invoke_with_args(instance.context(), std::forward(candidate), (args + Index)->cast>()...); + } + } + // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic) + + return meta_any{meta_ctx_arg, instance.context()}; +} + +template +[[nodiscard]] meta_any meta_construct(const meta_ctx &ctx, meta_any *const args, std::index_sequence) { + // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic) - waiting for C++20 (and std::span) + if(((args + Index)->allow_cast() && ...)) { + return meta_any{ctx, std::in_place_type, (args + Index)->cast()...}; + } + // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic) + + return meta_any{meta_ctx_arg, ctx}; +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Returns the meta type of the i-th element of a list of arguments. + * @tparam Type Type list of the actual types of arguments. + * @param ctx The context from which to search for meta types. + * @param index The index of the element for which to return the meta type. + * @return The meta type of the i-th element of the list of arguments. + */ +template +[[nodiscard]] meta_type meta_arg(const meta_ctx &ctx, const std::size_t index) noexcept { + const auto &context = internal::meta_context::from(ctx); + return {ctx, internal::meta_arg_node(context, Type{}, index)}; +} + +/** + * @brief Returns the meta type of the i-th element of a list of arguments. + * @tparam Type Type list of the actual types of arguments. + * @param index The index of the element for which to return the meta type. + * @return The meta type of the i-th element of the list of arguments. + */ +template +[[nodiscard]] meta_type meta_arg(const std::size_t index) noexcept { + return meta_arg(locator::value_or(), index); +} + +/** + * @brief Sets the value of a given variable. + * @tparam Type Reflected type to which the variable is associated. + * @tparam Data The actual variable to set. + * @param instance An opaque instance of the underlying type, if required. + * @param value Parameter to use to set the variable. + * @return True in case of success, false otherwise. + */ +template +[[nodiscard]] bool meta_setter([[maybe_unused]] meta_handle instance, [[maybe_unused]] meta_any value) { + if constexpr(std::is_member_function_pointer_v || std::is_function_v>>) { + using descriptor = meta_function_helper_t; + using data_type = type_list_element_t; + + if(auto *const clazz = instance->try_cast(); clazz && value.allow_cast()) { + std::invoke(Data, *clazz, value.cast()); + return true; + } + } else if constexpr(std::is_member_object_pointer_v) { + using data_type = std::remove_reference_t::return_type>; + + if constexpr(!std::is_array_v && !std::is_const_v) { + if(auto *const clazz = instance->try_cast(); clazz && value.allow_cast()) { + std::invoke(Data, *clazz) = value.cast(); + return true; + } + } + } else if constexpr(std::is_pointer_v) { + using data_type = std::remove_reference_t; + + if constexpr(!std::is_array_v && !std::is_const_v) { + if(value.allow_cast()) { + *Data = value.cast(); + return true; + } + } + } + + return false; +} + +/** + * @brief Gets the value of a given variable. + * @tparam Type Reflected type to which the variable is associated. + * @tparam Data The actual variable to get. + * @tparam Policy Optional policy (no policy set by default). + * @param instance An opaque instance of the underlying type, if required. + * @return A meta any containing the value of the underlying variable. + */ +template +[[nodiscard]] std::enable_if_t, meta_any> meta_getter(meta_handle instance) { + if constexpr(std::is_member_pointer_v || std::is_function_v>>) { + if constexpr(!std::is_array_v>>>) { + if constexpr(std::is_invocable_v) { + if(auto *clazz = instance->try_cast(); clazz) { + return meta_dispatch(instance->context(), std::invoke(Data, *clazz)); + } + } + + if constexpr(std::is_invocable_v) { + if(auto *fallback = instance->try_cast(); fallback) { + return meta_dispatch(instance->context(), std::invoke(Data, *fallback)); + } + } + } + + return meta_any{meta_ctx_arg, instance->context()}; + } else if constexpr(std::is_pointer_v) { + if constexpr(std::is_array_v>) { + return meta_any{meta_ctx_arg, instance->context()}; + } else { + return meta_dispatch(instance->context(), *Data); + } + } else { + return meta_dispatch(instance->context(), Data); + } +} + +/** + * @brief Tries to _invoke_ an object given a list of erased parameters. + * @tparam Type Reflected type to which the object to _invoke_ is associated. + * @tparam Policy Optional policy (no policy set by default). + * @tparam Candidate The type of the actual object to _invoke_. + * @param instance An opaque instance of the underlying type, if required. + * @param candidate The actual object to _invoke_. + * @param args Parameters to use to _invoke_ the object. + * @return A meta any containing the returned value, if any. + */ +template +[[nodiscard]] std::enable_if_t, meta_any> meta_invoke(meta_handle instance, Candidate &&candidate, meta_any *const args) { + return internal::meta_invoke(*instance.operator->(), std::forward(candidate), args, std::make_index_sequence>::args_type::size>{}); +} + +/** + * @brief Tries to invoke a function given a list of erased parameters. + * @tparam Type Reflected type to which the function is associated. + * @tparam Candidate The actual function to invoke. + * @tparam Policy Optional policy (no policy set by default). + * @param instance An opaque instance of the underlying type, if required. + * @param args Parameters to use to invoke the function. + * @return A meta any containing the returned value, if any. + */ +template +[[nodiscard]] std::enable_if_t, meta_any> meta_invoke(meta_handle instance, meta_any *const args) { + return internal::meta_invoke(*instance.operator->(), Candidate, args, std::make_index_sequence>::args_type::size>{}); +} + +/** + * @brief Tries to construct an instance given a list of erased parameters. + * + * @warning + * The context provided is used only for the return type.
+ * It's up to the caller to bind the arguments to the right context(s). + * + * @tparam Type Actual type of the instance to construct. + * @tparam Args Types of arguments expected. + * @param ctx The context from which to search for meta types. + * @param args Parameters to use to construct the instance. + * @return A meta any containing the new instance, if any. + */ +template +[[nodiscard]] meta_any meta_construct(const meta_ctx &ctx, meta_any *const args) { + return internal::meta_construct(ctx, args, std::index_sequence_for{}); +} + +/** + * @brief Tries to construct an instance given a list of erased parameters. + * @tparam Type Actual type of the instance to construct. + * @tparam Args Types of arguments expected. + * @param args Parameters to use to construct the instance. + * @return A meta any containing the new instance, if any. + */ +template +[[nodiscard]] meta_any meta_construct(meta_any *const args) { + return meta_construct(locator::value_or(), args); +} + +/** + * @brief Tries to construct an instance given a list of erased parameters. + * + * @warning + * The context provided is used only for the return type.
+ * It's up to the caller to bind the arguments to the right context(s). + * + * @tparam Type Reflected type to which the object to _invoke_ is associated. + * @tparam Policy Optional policy (no policy set by default). + * @tparam Candidate The type of the actual object to _invoke_. + * @param ctx The context from which to search for meta types. + * @param candidate The actual object to _invoke_. + * @param args Parameters to use to _invoke_ the object. + * @return A meta any containing the returned value, if any. + */ +template +[[nodiscard]] meta_any meta_construct(const meta_ctx &ctx, Candidate &&candidate, meta_any *const args) { + if constexpr(meta_function_helper_t::is_static || std::is_class_v>>) { + meta_any placeholder{meta_ctx_arg, ctx}; + return internal::meta_invoke(placeholder, std::forward(candidate), args, std::make_index_sequence>::args_type::size>{}); + } else { + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - waiting for C++20 (and std::span) + return internal::meta_invoke(*args, std::forward(candidate), args + 1u, std::make_index_sequence>::args_type::size>{}); + } +} + +/** + * @brief Tries to construct an instance given a list of erased parameters. + * @tparam Type Reflected type to which the object to _invoke_ is associated. + * @tparam Policy Optional policy (no policy set by default). + * @tparam Candidate The type of the actual object to _invoke_. + * @param candidate The actual object to _invoke_. + * @param args Parameters to use to _invoke_ the object. + * @return A meta any containing the returned value, if any. + */ +template +[[nodiscard]] std::enable_if_t, meta_any> meta_construct(Candidate &&candidate, meta_any *const args) { + return meta_construct(locator::value_or(), std::forward(candidate), args); +} + +/** + * @brief Tries to construct an instance given a list of erased parameters. + * + * @warning + * The context provided is used only for the return type.
+ * It's up to the caller to bind the arguments to the right context(s). + * + * @tparam Type Reflected type to which the function is associated. + * @tparam Candidate The actual function to invoke. + * @tparam Policy Optional policy (no policy set by default). + * @param ctx The context from which to search for meta types. + * @param args Parameters to use to invoke the function. + * @return A meta any containing the returned value, if any. + */ +template +[[nodiscard]] std::enable_if_t, meta_any> meta_construct(const meta_ctx &ctx, meta_any *const args) { + return meta_construct(ctx, Candidate, args); +} + +/** + * @brief Tries to construct an instance given a list of erased parameters. + * @tparam Type Reflected type to which the function is associated. + * @tparam Candidate The actual function to invoke. + * @tparam Policy Optional policy (no policy set by default). + * @param args Parameters to use to invoke the function. + * @return A meta any containing the returned value, if any. + */ +template +[[nodiscard]] std::enable_if_t, meta_any> meta_construct(meta_any *const args) { + return meta_construct(locator::value_or(), args); +} + +} // namespace entt + +#endif + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +class basic_meta_factory { + using invoke_type = std::remove_pointer_t; + + [[nodiscard]] auto &fetch_node() noexcept { + return *meta_context::from(*ctx).value[parent]; + } + + [[nodiscard]] auto *find_member_or_assert() { + auto *member = find_member<&meta_data_node::id>(fetch_node().details->data, bucket); + ENTT_ASSERT(member != nullptr, "Cannot find member"); + return member; + } + + [[nodiscard]] auto *find_overload_or_assert() { + auto *overload = find_overload(find_member<&meta_func_node::id>(fetch_node().details->func, bucket), invoke); + ENTT_ASSERT(overload != nullptr, "Cannot find overload"); + return overload; + } + + void reset_bucket(const id_type id, invoke_type *const ref = nullptr) { + invoke = ref; + bucket = id; + } + +protected: + void type(const id_type id, const char *name) noexcept { + reset_bucket(parent); + auto &elem = fetch_node(); + ENTT_ASSERT(elem.id == id || !resolve(*ctx, id), "Duplicate identifier"); + elem.name = name; + elem.id = id; + } + + template + void insert_or_assign(Type node) { + auto &elem = fetch_node(); + + reset_bucket(parent); + + if constexpr(std::is_same_v) { + auto *member = find_member<&meta_base_node::type>(elem.details->base, node.type); + member ? (*member = node) : elem.details->base.emplace_back(node); + } else if constexpr(std::is_same_v) { + auto *member = find_member<&meta_conv_node::type>(elem.details->conv, node.type); + member ? (*member = node) : elem.details->conv.emplace_back(node); + } else { + static_assert(std::is_same_v, "Unexpected type"); + auto *member = find_member<&meta_ctor_node::id>(elem.details->ctor, node.id); + member ? (*member = node) : elem.details->ctor.emplace_back(node); + } + } + + void data(meta_data_node node) { + auto &elem = fetch_node(); + + reset_bucket(node.id); + + if(auto *member = find_member<&meta_data_node::id>(elem.details->data, node.id); member == nullptr) { + elem.details->data.emplace_back(std::move(node)); + } else if(member->set != node.set || member->get != node.get) { + *member = std::move(node); + } + } + + void func(meta_func_node node) { + auto &elem = fetch_node(); + + reset_bucket(node.id, node.invoke); + + if(auto *member = find_member<&meta_func_node::id>(elem.details->func, node.id); member == nullptr) { + elem.details->func.emplace_back(std::move(node)); + } else if(auto *overload = find_overload(member, node.invoke); overload == nullptr) { + while(member->next != nullptr) { member = member->next.get(); } + member->next = std::make_unique(std::move(node)); + } + } + + void traits(const meta_traits value, const bool unset) { + auto set_or_unset_on = [=](auto &node) { + node.traits = (unset ? (node.traits & ~value) : (node.traits | value)); + }; + + if(bucket == parent) { + set_or_unset_on(fetch_node()); + } else if(invoke == nullptr) { + set_or_unset_on(*find_member_or_assert()); + } else { + set_or_unset_on(*find_overload_or_assert()); + } + } + + void custom(meta_custom_node node) { + if(bucket == parent) { + fetch_node().custom = std::move(node); + } else if(invoke == nullptr) { + find_member_or_assert()->custom = std::move(node); + } else { + find_overload_or_assert()->custom = std::move(node); + } + } + +public: + basic_meta_factory(meta_ctx &area, meta_type_node node) + : ctx{&area}, + parent{node.info->hash()}, + bucket{parent} { + if(auto *curr = meta_context::from(*ctx).value.try_emplace(parent, std::make_unique(std::move(node))).first->second.get(); curr->details == nullptr) { + curr->details = std::make_unique(); + } + } + +private: + meta_ctx *ctx{}; + id_type parent{}; + id_type bucket{}; + invoke_type *invoke{}; +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Meta factory to be used for reflection purposes. + * @tparam Type Type for which the factory was created. + */ +template +class meta_factory: private internal::basic_meta_factory { + using base_type = internal::basic_meta_factory; + +public: + /*! @brief Type of object for which this factory builds a meta type. */ + using element_type = Type; + + /*! @brief Default constructor. */ + meta_factory() noexcept + : meta_factory{locator::value_or()} {} + + /** + * @brief Context aware constructor. + * @param area The context into which to construct meta types. + */ + meta_factory(meta_ctx &area) noexcept + : internal::basic_meta_factory{area, internal::setup_node_for()} {} + + /** + * @brief Assigns a custom unique identifier to a meta type. + * @param name A custom unique identifier as a **string literal**. + * @return A meta factory for the given type. + */ + meta_factory type(const char *name) noexcept { + return type(hashed_string::value(name), name); + } + + /** + * @brief Assigns a custom unique identifier to a meta type. + * @param id A custom unique identifier. + * @param name An optional name for the type as a **string literal**. + * @return A meta factory for the given type. + */ + meta_factory type(const id_type id, const char *name = nullptr) noexcept { + base_type::type(id, name); + return *this; + } + + /** + * @brief Assigns a meta base to a meta type. + * + * A reflected base class must be a real base class of the reflected type. + * + * @tparam Base Type of the base class to assign to the meta type. + * @return A meta factory for the parent type. + */ + template + meta_factory base() noexcept { + static_assert(!std::is_same_v && std::is_base_of_v, "Invalid base type"); + auto *const op = +[](const void *instance) noexcept { return static_cast(static_cast(static_cast(instance))); }; + base_type::insert_or_assign(internal::meta_base_node{type_id().hash(), &internal::resolve, op}); + return *this; + } + + /** + * @brief Assigns a meta conversion function to a meta type. + * + * Conversion functions can be either free functions or member + * functions.
+ * In case of free functions, they must accept a const reference to an + * instance of the parent type as an argument. In case of member functions, + * they should have no arguments at all. + * + * @tparam Candidate The actual function to use for the conversion. + * @return A meta factory for the parent type. + */ + template + auto conv() noexcept { + using conv_type = std::remove_const_t>>; + auto *const op = +[](const meta_ctx &area, const void *instance) { return forward_as_meta(area, std::invoke(Candidate, *static_cast(instance))); }; + base_type::insert_or_assign(internal::meta_conv_node{type_id().hash(), op}); + return *this; + } + + /** + * @brief Assigns a meta conversion function to a meta type. + * + * The given type must be such that an instance of the reflected type can be + * converted to it. + * + * @tparam To Type of the conversion function to assign to the meta type. + * @return A meta factory for the parent type. + */ + template + meta_factory conv() noexcept { + using conv_type = std::remove_const_t>; + auto *const op = +[](const meta_ctx &area, const void *instance) { return forward_as_meta(area, static_cast(*static_cast(instance))); }; + base_type::insert_or_assign(internal::meta_conv_node{type_id().hash(), op}); + return *this; + } + + /** + * @brief Assigns a meta constructor to a meta type. + * + * Both member functions and free function can be assigned to meta types in + * the role of constructors. All that is required is that they return an + * instance of the underlying type.
+ * From a client's point of view, nothing changes if a constructor of a meta + * type is a built-in one or not. + * + * @tparam Candidate The actual function to use as a constructor. + * @tparam Policy Optional policy (no policy set by default). + * @return A meta factory for the parent type. + */ + template + meta_factory ctor() noexcept { + using descriptor = meta_function_helper_t; + static_assert(Policy::template value, "Invalid return type for the given policy"); + static_assert(std::is_same_v>, Type>, "The function doesn't return an object of the required type"); + base_type::insert_or_assign(internal::meta_ctor_node{type_id().hash(), descriptor::args_type::size, &meta_arg, &meta_construct}); + return *this; + } + + /** + * @brief Assigns a meta constructor to a meta type. + * + * A meta constructor is uniquely identified by the types of its arguments + * and is such that there exists an actual constructor of the underlying + * type that can be invoked with parameters whose types are those given. + * + * @tparam Args Types of arguments to use to construct an instance. + * @return A meta factory for the parent type. + */ + template + meta_factory ctor() noexcept { + // default constructor is already implicitly generated, no need for redundancy + if constexpr(sizeof...(Args) != 0u) { + using descriptor = meta_function_helper_t; + base_type::insert_or_assign(internal::meta_ctor_node{type_id().hash(), descriptor::args_type::size, &meta_arg, &meta_construct}); + } + + return *this; + } + + /** + * @brief Assigns a meta data to a meta type. + * @tparam Data The actual variable to attach to the meta type. + * @tparam Policy Optional policy (no policy set by default). + * @param name A custom unique identifier as a **string literal**. + * @return A meta factory for the given type. + */ + template + meta_factory data(const char *name) noexcept { + return data(hashed_string::value(name), name); + } + + /** + * @brief Assigns a meta data to a meta type. + * + * Both data members and static and global variables, as well as constants + * of any kind, can be assigned to a meta type.
+ * From a client's point of view, all the variables associated with the + * reflected object will appear as if they were part of the type itself. + * + * @tparam Data The actual variable to attach to the meta type. + * @tparam Policy Optional policy (no policy set by default). + * @param id Unique identifier. + * @param name An optional name for the meta data as a **string literal**. + * @return A meta factory for the parent type. + */ + template + meta_factory data(const id_type id, const char *name = nullptr) noexcept { + if constexpr(std::is_member_object_pointer_v) { + using data_type = std::invoke_result_t; + static_assert(Policy::template value, "Invalid return type for the given policy"); + + base_type::data( + internal::meta_data_node{ + id, + name, + /* this is never static */ + std::is_const_v> ? internal::meta_traits::is_const : internal::meta_traits::is_none, + 1u, + &internal::resolve>>, + &meta_arg>>>, + &meta_setter, + &meta_getter}); + } else { + using data_type = std::remove_pointer_t; + + if constexpr(std::is_pointer_v) { + static_assert(Policy::template value, "Invalid return type for the given policy"); + } else { + static_assert(Policy::template value, "Invalid return type for the given policy"); + } + + base_type::data( + internal::meta_data_node{ + id, + name, + ((!std::is_pointer_v || std::is_const_v) ? internal::meta_traits::is_const : internal::meta_traits::is_none) | internal::meta_traits::is_static, + 1u, + &internal::resolve>>, + &meta_arg>>>, + &meta_setter, + &meta_getter}); + } + + return *this; + } + + /** + * @brief Assigns a meta data to a meta type by means of its setter and + * getter. + * @tparam Setter The actual function to use as a setter. + * @tparam Getter The actual function to use as a getter. + * @tparam Policy Optional policy (no policy set by default). + * @param name A custom unique identifier as a **string literal**. + * @return A meta factory for the given type. + */ + template + meta_factory data(const char *name) noexcept { + return data(hashed_string::value(name), name); + } + + /** + * @brief Assigns a meta data to a meta type by means of its setter and + * getter. + * + * Setters and getters can be either free functions, member functions or a + * mix of them.
+ * In case of free functions, setters and getters must accept a reference to + * an instance of the parent type as their first argument. A setter has then + * an extra argument of a type convertible to that of the parameter to + * set.
+ * In case of member functions, getters have no arguments at all, while + * setters has an argument of a type convertible to that of the parameter to + * set. + * + * @tparam Setter The actual function to use as a setter. + * @tparam Getter The actual function to use as a getter. + * @tparam Policy Optional policy (no policy set by default). + * @param id Unique identifier. + * @param name An optional name for the meta data as a **string literal**. + * @return A meta factory for the parent type. + */ + template + meta_factory data(const id_type id, const char *name = nullptr) noexcept { + using descriptor = meta_function_helper_t; + static_assert(Policy::template value, "Invalid return type for the given policy"); + + if constexpr(std::is_same_v) { + base_type::data( + internal::meta_data_node{ + id, + name, + /* this is never static */ + internal::meta_traits::is_const, + 0u, + &internal::resolve>>, + &meta_arg>, + &meta_setter, + &meta_getter}); + } else { + using args_type = typename meta_function_helper_t::args_type; + + base_type::data( + internal::meta_data_node{ + id, + name, + /* this is never static nor const */ + internal::meta_traits::is_none, + 1u, + &internal::resolve>>, + &meta_arg(args_type::size != 1u), args_type>>>, + &meta_setter, + &meta_getter}); + } + + return *this; + } + + /** + * @brief Assigns a meta function to a meta type. + * @tparam Candidate The actual function to attach to the meta function. + * @tparam Policy Optional policy (no policy set by default). + * @param name A custom unique identifier as a **string literal**. + * @return A meta factory for the given type. + */ + template + meta_factory func(const char *name) noexcept { + return func(hashed_string::value(name), name); + } + + /** + * @brief Assigns a meta function to a meta type. + * + * Both member functions and free functions can be assigned to a meta + * type.
+ * From a client's point of view, all the functions associated with the + * reflected object will appear as if they were part of the type itself. + * + * @tparam Candidate The actual function to attach to the meta type. + * @tparam Policy Optional policy (no policy set by default). + * @param id Unique identifier. + * @param name An optional name for the function as a **string literal**. + * @return A meta factory for the parent type. + */ + template + meta_factory func(const id_type id, const char *name = nullptr) noexcept { + using descriptor = meta_function_helper_t; + static_assert(Policy::template value, "Invalid return type for the given policy"); + + base_type::func( + internal::meta_func_node{ + id, + name, + (descriptor::is_const ? internal::meta_traits::is_const : internal::meta_traits::is_none) | (descriptor::is_static ? internal::meta_traits::is_static : internal::meta_traits::is_none), + descriptor::args_type::size, + &internal::resolve, void, std::remove_const_t>>>, + &meta_arg, + &meta_invoke}); + + return *this; + } + + /** + * @brief Sets traits on the last created meta object. + * + * The assigned value must be an enum and intended as a bitmask. + * + * @tparam Value Type of the traits value. + * @param value Traits value. + * @param unset True to unset the given traits, false otherwise. + * @return A meta factory for the parent type. + */ + template + meta_factory traits(const Value value, const bool unset = false) { + static_assert(std::is_enum_v, "Invalid enum type"); + base_type::traits(internal::user_to_meta_traits(value), unset); + return *this; + } + + /** + * @brief Sets user defined data that will never be used by the library. + * @tparam Value Type of user defined data to store. + * @tparam Args Types of arguments to use to construct the user data. + * @param args Parameters to use to initialize the user data. + * @return A meta factory for the parent type. + */ + template + meta_factory custom(Args &&...args) { + base_type::custom(internal::meta_custom_node{type_id().hash(), std::make_shared(std::forward(args)...)}); + return *this; + } +}; + +/** + * @brief Resets a type and all its parts. + * + * Resets a type and all its data members, member functions and properties, as + * well as its constructors, destructors and conversion functions if any.
+ * Base classes aren't reset but the link between the two types is removed. + * + * The type is also removed from the set of searchable types. + * + * @param id Unique identifier. + * @param ctx The context from which to reset meta types. + */ +inline void meta_reset(meta_ctx &ctx, const id_type id) noexcept { + auto &context = internal::meta_context::from(ctx); + + for(auto it = context.value.begin(); it != context.value.end();) { + if(it->second->id == id) { + it = context.value.erase(it); + } else { + ++it; + } + } +} + +/** + * @brief Resets a type and all its parts. + * + * Resets a type and all its data members, member functions and properties, as + * well as its constructors, destructors and conversion functions if any.
+ * Base classes aren't reset but the link between the two types is removed. + * + * The type is also removed from the set of searchable types. + * + * @param id Unique identifier. + */ +inline void meta_reset(const id_type id) noexcept { + meta_reset(locator::value_or(), id); +} + +/** + * @brief Resets a type and all its parts. + * + * @sa meta_reset + * + * @tparam Type Type to reset. + * @param ctx The context from which to reset meta types. + */ +template +void meta_reset(meta_ctx &ctx) noexcept { + internal::meta_context::from(ctx).value.erase(type_id().hash()); +} + +/** + * @brief Resets a type and all its parts. + * + * @sa meta_reset + * + * @tparam Type Type to reset. + */ +template +void meta_reset() noexcept { + meta_reset(locator::value_or()); +} + +/** + * @brief Resets all meta types. + * + * @sa meta_reset + * + * @param ctx The context from which to reset meta types. + */ +inline void meta_reset(meta_ctx &ctx) noexcept { + internal::meta_context::from(ctx).value.clear(); +} + +/** + * @brief Resets all meta types. + * + * @sa meta_reset + */ +inline void meta_reset() noexcept { + meta_reset(locator::value_or()); +} + +} // namespace entt + +#endif + +// #include "meta/meta.hpp" +#ifndef ENTT_META_META_HPP +#define ENTT_META_META_HPP + +#include +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "../core/any.hpp" + +// #include "../core/fwd.hpp" + +// #include "../core/iterator.hpp" + +// #include "../core/type_info.hpp" + +// #include "../core/type_traits.hpp" + +// #include "../core/utility.hpp" + +// #include "../locator/locator.hpp" + +// #include "adl_pointer.hpp" + +// #include "context.hpp" + +// #include "fwd.hpp" + +// #include "node.hpp" + +// #include "range.hpp" + +// #include "type_traits.hpp" + + +namespace entt { + +class meta_any; +class meta_type; + +/*! @brief Proxy object for sequence containers. */ +class meta_sequence_container { + class meta_iterator; + +public: + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + /*! @brief Meta iterator type. */ + using iterator = meta_iterator; + + /*! @brief Default constructor. */ + meta_sequence_container() = default; + + /** + * @brief Context aware constructor. + * @tparam Type Type of container to wrap. + * @param area The context from which to search for meta types. + * @param instance The container to wrap. + */ + template + meta_sequence_container(const meta_ctx &area, Type &instance) noexcept + : ctx{&area}, + data{&instance}, + value_type_node{&internal::resolve}, + const_reference_node{&internal::resolve>>}, + size_fn{meta_sequence_container_traits>::size}, + clear_fn{meta_sequence_container_traits>::clear}, + reserve_fn{meta_sequence_container_traits>::reserve}, + resize_fn{meta_sequence_container_traits>::resize}, + begin_end_fn{meta_sequence_container_traits>::iter}, + insert_fn{meta_sequence_container_traits>::insert}, + erase_fn{meta_sequence_container_traits>::erase}, + const_only{std::is_const_v} {} + + [[nodiscard]] inline meta_type value_type() const noexcept; + [[nodiscard]] inline size_type size() const noexcept; + inline bool resize(size_type); + inline bool clear(); + inline bool reserve(size_type); + [[nodiscard]] inline iterator begin(); + [[nodiscard]] inline iterator end(); + inline iterator insert(const iterator &, meta_any); + inline iterator erase(const iterator &); + [[nodiscard]] inline meta_any operator[](size_type); + [[nodiscard]] inline explicit operator bool() const noexcept; + +private: + const meta_ctx *ctx{}; + const void *data{}; + const internal::meta_type_node &(*value_type_node)(const internal::meta_context &){}; + const internal::meta_type_node &(*const_reference_node)(const internal::meta_context &){}; + size_type (*size_fn)(const void *){}; + bool (*clear_fn)(void *){}; + bool (*reserve_fn)(void *, const size_type){}; + bool (*resize_fn)(void *, const size_type){}; + iterator (*begin_end_fn)(const meta_ctx &, void *, const void *, const bool){}; + iterator (*insert_fn)(const meta_ctx &, void *, const void *, const void *, const iterator &){}; + iterator (*erase_fn)(const meta_ctx &, void *, const iterator &){}; + bool const_only{}; +}; + +/*! @brief Proxy object for associative containers. */ +class meta_associative_container { + class meta_iterator; + +public: + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + /*! @brief Meta iterator type. */ + using iterator = meta_iterator; + + /*! @brief Default constructor. */ + meta_associative_container() = default; + + /** + * @brief Context aware constructor. + * @tparam Type Type of container to wrap. + * @param area The context from which to search for meta types. + * @param instance The container to wrap. + */ + template + meta_associative_container(const meta_ctx &area, Type &instance) noexcept + : ctx{&area}, + data{&instance}, + key_type_node{&internal::resolve}, + value_type_node{&internal::resolve}, + size_fn{&meta_associative_container_traits>::size}, + clear_fn{&meta_associative_container_traits>::clear}, + reserve_fn{&meta_associative_container_traits>::reserve}, + begin_end_fn{&meta_associative_container_traits>::iter}, + insert_fn{&meta_associative_container_traits>::insert}, + erase_fn{&meta_associative_container_traits>::erase}, + find_fn{&meta_associative_container_traits>::find}, + const_only{std::is_const_v} { + if constexpr(!meta_associative_container_traits>::key_only) { + mapped_type_node = &internal::resolve; + } + } + + [[nodiscard]] inline meta_type key_type() const noexcept; + [[nodiscard]] inline meta_type mapped_type() const noexcept; + [[nodiscard]] inline meta_type value_type() const noexcept; + [[nodiscard]] inline size_type size() const noexcept; + inline bool clear(); + inline bool reserve(size_type); + [[nodiscard]] inline iterator begin(); + [[nodiscard]] inline iterator end(); + inline bool insert(meta_any, meta_any); + inline size_type erase(meta_any); + [[nodiscard]] inline iterator find(meta_any); + [[nodiscard]] inline explicit operator bool() const noexcept; + +private: + const meta_ctx *ctx{}; + const void *data{}; + const internal::meta_type_node &(*key_type_node)(const internal::meta_context &){}; + const internal::meta_type_node &(*mapped_type_node)(const internal::meta_context &){}; + const internal::meta_type_node &(*value_type_node)(const internal::meta_context &){}; + size_type (*size_fn)(const void *){}; + bool (*clear_fn)(void *){}; + bool (*reserve_fn)(void *, const size_type){}; + iterator (*begin_end_fn)(const meta_ctx &, void *, const void *, const bool){}; + bool (*insert_fn)(void *, const void *, const void *){}; + size_type (*erase_fn)(void *, const void *){}; + iterator (*find_fn)(const meta_ctx &, void *, const void *, const void *){}; + bool const_only{}; +}; + +/*! @brief Opaque wrapper for values of any type. */ +class meta_any { + using vtable_type = void(const internal::meta_traits, const meta_any &, const void *); + + template + static void basic_vtable(const internal::meta_traits req, const meta_any &value, [[maybe_unused]] const void *other) { + static_assert(std::is_same_v>, Type>, "Invalid type"); + + if(req == internal::meta_traits::is_none) { + value.node = &internal::resolve(internal::meta_context::from(*value.ctx)); + } + + if constexpr(is_meta_pointer_like_v) { + if(req == internal::meta_traits::is_pointer_like) { + if constexpr(std::is_function_v::element_type>) { + const_cast(value).emplace(*static_cast(other)); + } else if constexpr(!std::is_void_v::element_type>>) { + using in_place_type = decltype(adl_meta_pointer_like::dereference(std::declval())); + + if constexpr(std::is_constructible_v) { + if(const auto &pointer_like = *static_cast(other); pointer_like) { + const_cast(value).emplace(adl_meta_pointer_like::dereference(pointer_like)); + } + } else { + const_cast(value).emplace(adl_meta_pointer_like::dereference(*static_cast(other))); + } + } + } + } + + if constexpr(is_complete_v> || is_complete_v>) { + if(constexpr auto flag = (is_complete_v> ? internal::meta_traits::is_sequence_container : internal::meta_traits::is_associative_container); !!(req & flag)) { + using container_type = std::conditional_t>, meta_sequence_container, meta_associative_container>; + + if(!!(req & internal::meta_traits::is_const) || (value.storage.policy() == any_policy::cref)) { + // NOLINTNEXTLINE(bugprone-casting-through-void) + *static_cast(const_cast(other)) = container_type{*value.ctx, any_cast(value.storage)}; + } else { + // NOLINTNEXTLINE(bugprone-casting-through-void) + *static_cast(const_cast(other)) = container_type{*value.ctx, any_cast(const_cast(value).storage)}; + } + } + } + } + + [[nodiscard]] const auto &fetch_node() const { + if(node == nullptr) { + ENTT_ASSERT(*this, "Invalid vtable function"); + vtable(internal::meta_traits::is_none, *this, nullptr); + } + + ENTT_ASSERT(node != nullptr, "Invalid pointer to node"); + return *node; + } + + meta_any(const meta_any &other, any elem) + : storage{std::move(elem)}, + ctx{other.ctx}, + node{other.node}, + vtable{other.vtable} {} + +public: + /*! Default constructor. */ + meta_any() = default; + + /** + * @brief Context aware constructor. + * @param area The context from which to search for meta types. + */ + meta_any(meta_ctx_arg_t, const meta_ctx &area) + : ctx{&area} {} + + /** + * @brief Constructs a wrapper by directly initializing the new object. + * @tparam Type Type of object to use to initialize the wrapper. + * @tparam Args Types of arguments to use to construct the new instance. + * @param args Parameters to use to construct the instance. + */ + template + explicit meta_any(std::in_place_type_t, Args &&...args) + : meta_any{locator::value_or(), std::in_place_type, std::forward(args)...} {} + + /** + * @brief Constructs a wrapper by directly initializing the new object. + * @tparam Type Type of object to use to initialize the wrapper. + * @tparam Args Types of arguments to use to construct the new instance. + * @param area The context from which to search for meta types. + * @param args Parameters to use to construct the instance. + */ + template + explicit meta_any(const meta_ctx &area, std::in_place_type_t, Args &&...args) + : storage{std::in_place_type, std::forward(args)...}, + ctx{&area}, + vtable{&basic_vtable>>} {} + + /** + * @brief Constructs a wrapper taking ownership of the passed object. + * @tparam Type Type of object to use to initialize the wrapper. + * @param value A pointer to an object to take ownership of. + */ + template + explicit meta_any(std::in_place_t, Type *value) + : meta_any{locator::value_or(), std::in_place, value} {} + + /** + * @brief Constructs a wrapper taking ownership of the passed object. + * @tparam Type Type of object to use to initialize the wrapper. + * @param area The context from which to search for meta types. + * @param value A pointer to an object to take ownership of. + */ + template + explicit meta_any(const meta_ctx &area, std::in_place_t, Type *value) + : storage{std::in_place, value}, + ctx{&area}, + vtable{storage ? &basic_vtable : nullptr} { + } + + /** + * @brief Constructs a wrapper from a given value. + * @tparam Type Type of object to use to initialize the wrapper. + * @param value An instance of an object to use to initialize the wrapper. + */ + template, meta_any>>> + meta_any(Type &&value) + : meta_any{locator::value_or(), std::forward(value)} {} + + /** + * @brief Constructs a wrapper from a given value. + * @tparam Type Type of object to use to initialize the wrapper. + * @param area The context from which to search for meta types. + * @param value An instance of an object to use to initialize the wrapper. + */ + template, meta_any>>> + meta_any(const meta_ctx &area, Type &&value) + : meta_any{area, std::in_place_type>, std::forward(value)} {} + + /** + * @brief Context aware copy constructor. + * @param area The context from which to search for meta types. + * @param other The instance to copy from. + */ + meta_any(const meta_ctx &area, const meta_any &other) + : storage{other.storage}, + ctx{&area}, + node{(ctx == other.ctx) ? other.node : nullptr}, + vtable{other.vtable} {} + + /** + * @brief Context aware move constructor. + * @param area The context from which to search for meta types. + * @param other The instance to move from. + */ + meta_any(const meta_ctx &area, meta_any &&other) + : storage{std::move(other.storage)}, + ctx{&area}, + node{(ctx == other.ctx) ? std::exchange(other.node, nullptr) : nullptr}, + vtable{std::exchange(other.vtable, nullptr)} {} + + /** + * @brief Copy constructor. + * @param other The instance to copy from. + */ + meta_any(const meta_any &other) = default; + + /** + * @brief Move constructor. + * @param other The instance to move from. + */ + meta_any(meta_any &&other) noexcept + : storage{std::move(other.storage)}, + ctx{other.ctx}, + node{std::exchange(other.node, nullptr)}, + vtable{std::exchange(other.vtable, nullptr)} {} + + /*! @brief Default destructor. */ + ~meta_any() = default; + + /** + * @brief Copy assignment operator. + * @param other The instance to copy from. + * @return This meta any object. + */ + meta_any &operator=(const meta_any &other) { + if(this != &other) { + storage = other.storage; + ctx = other.ctx; + node = other.node; + vtable = other.vtable; + } + + return *this; + } + + /** + * @brief Move assignment operator. + * @param other The instance to move from. + * @return This meta any object. + */ + meta_any &operator=(meta_any &&other) noexcept { + storage = std::move(other.storage); + ctx = other.ctx; + node = std::exchange(other.node, nullptr); + vtable = std::exchange(other.vtable, nullptr); + return *this; + } + + /** + * @brief Value assignment operator. + * @tparam Type Type of object to use to initialize the wrapper. + * @param value An instance of an object to use to initialize the wrapper. + * @return This meta any object. + */ + template, meta_any>>> + meta_any &operator=(Type &&value) { + emplace>(std::forward(value)); + return *this; + } + + /*! @copydoc any::info */ + [[nodiscard]] inline meta_type type() const noexcept; + + /** + * @brief Invokes the underlying function, if possible. + * @tparam Args Types of arguments to use to invoke the function. + * @param id Unique identifier. + * @param args Parameters to use to invoke the function. + * @return A wrapper containing the returned value, if any. + */ + template + meta_any invoke(id_type id, Args &&...args) const; + + /*! @copydoc invoke */ + template + meta_any invoke(id_type id, Args &&...args); + + /** + * @brief Sets the value of a given variable. + * @tparam Type Type of value to assign. + * @param id Unique identifier. + * @param value Parameter to use to set the underlying variable. + * @return True in case of success, false otherwise. + */ + template + bool set(id_type id, Type &&value); + + /** + * @brief Gets the value of a given variable. + * @param id Unique identifier. + * @return A wrapper containing the value of the underlying variable. + */ + [[nodiscard]] meta_any get(id_type id) const; + + /*! @copydoc get */ + [[nodiscard]] meta_any get(id_type id); + + /** + * @brief Tries to cast an instance to a given type. + * @tparam Type Type to which to cast the instance. + * @return A (possibly null) pointer to the contained instance. + */ + template + [[nodiscard]] const Type *try_cast() const { + const auto *elem = any_cast(&storage); + return ((elem != nullptr) || !*this) ? elem : static_cast(internal::try_cast(internal::meta_context::from(*ctx), fetch_node(), type_hash>::value(), storage.data())); + } + + /*! @copydoc try_cast */ + template + [[nodiscard]] Type *try_cast() { + return ((storage.policy() == any_policy::cref) && !std::is_const_v) ? nullptr : const_cast(std::as_const(*this).try_cast>()); + } + + /** + * @brief Tries to cast an instance to a given type. + * @tparam Type Type to which to cast the instance. + * @return A reference to the contained instance. + */ + template + [[nodiscard]] std::remove_const_t cast() const { + auto *const instance = try_cast>(); + ENTT_ASSERT(instance, "Invalid instance"); + return static_cast(*instance); + } + + /*! @copydoc cast */ + template + [[nodiscard]] std::remove_const_t cast() { + // forces const on non-reference types to make them work also with wrappers for const references + auto *const instance = try_cast>(); + ENTT_ASSERT(instance, "Invalid instance"); + return static_cast(*instance); + } + + /** + * @brief Converts an object in such a way that a given cast becomes viable. + * @param type Meta type to which the cast is requested. + * @return A valid meta object if convertible, an invalid one otherwise. + */ + [[nodiscard]] meta_any allow_cast(const meta_type &type) const; + + /** + * @brief Converts an object in such a way that a given cast becomes viable. + * @param type Meta type to which the cast is requested. + * @return True if convertible, false otherwise. + */ + [[nodiscard]] bool allow_cast(const meta_type &type); + + /** + * @brief Converts an object in such a way that a given cast becomes viable. + * @tparam Type Type to which the cast is requested. + * @return A valid meta object if convertible, an invalid one otherwise. + */ + template + [[nodiscard]] meta_any allow_cast() const { + if constexpr(!std::is_reference_v || std::is_const_v>) { + if(storage.has_value>>()) { + return as_ref(); + } else if(*this) { + if constexpr(std::is_arithmetic_v>> || std::is_enum_v>>) { + if(const auto &from = fetch_node(); from.conversion_helper) { + return meta_any{*ctx, static_cast(from.conversion_helper(nullptr, storage.data()))}; + } + } + + if(const auto &from = fetch_node(); from.details != nullptr) { + if(const auto *elem = internal::find_member<&internal::meta_conv_node::type>(from.details->conv, entt::type_hash>>::value()); elem != nullptr) { + return elem->conv(*ctx, storage.data()); + } + + for(auto &&curr: from.details->base) { + if(auto other = curr.resolve(internal::meta_context::from(*ctx)).from_void(*ctx, nullptr, curr.cast(storage.data())); curr.type == entt::type_hash>>::value()) { + return other; + } else if(auto from_base = std::as_const(other).template allow_cast(); from_base) { + return from_base; + } + } + } + } + } + + return meta_any{meta_ctx_arg, *ctx}; + } + + /** + * @brief Converts an object in such a way that a given cast becomes viable. + * @tparam Type Type to which the cast is requested. + * @return True if convertible, false otherwise. + */ + template + [[nodiscard]] bool allow_cast() { + if constexpr(std::is_reference_v && !std::is_const_v>) { + return allow_cast &>() && (storage.policy() != any_policy::cref); + } else { + if(storage.has_value>>()) { + return true; + } else if(auto other = std::as_const(*this).allow_cast>>(); other) { + if(other.storage.owner()) { + std::swap(*this, other); + } + + return true; + } + + return false; + } + } + + /*! @copydoc any::emplace */ + template + void emplace(Args &&...args) { + storage.emplace(std::forward(args)...); + auto *prev = std::exchange(vtable, &basic_vtable>>); + node = (prev == vtable) ? node : nullptr; + } + + /*! @copydoc any::assign */ + bool assign(const meta_any &other); + + /*! @copydoc any::assign */ + bool assign(meta_any &&other); + + /*! @copydoc any::reset */ + void reset() { + storage.reset(); + node = nullptr; + vtable = nullptr; + } + + /** + * @brief Returns a sequence container proxy. + * @return A sequence container proxy for the underlying object. + */ + [[nodiscard]] meta_sequence_container as_sequence_container() noexcept { + meta_sequence_container proxy{}; + if(*this) { vtable(internal::meta_traits::is_sequence_container, *this, &proxy); } + return proxy; + } + + /*! @copydoc as_sequence_container */ + [[nodiscard]] meta_sequence_container as_sequence_container() const noexcept { + meta_sequence_container proxy{}; + if(*this) { vtable(internal::meta_traits::is_sequence_container | internal::meta_traits::is_const, *this, &proxy); } + return proxy; + } + + /** + * @brief Returns an associative container proxy. + * @return An associative container proxy for the underlying object. + */ + [[nodiscard]] meta_associative_container as_associative_container() noexcept { + meta_associative_container proxy{}; + if(*this) { vtable(internal::meta_traits::is_associative_container, *this, &proxy); } + return proxy; + } + + /*! @copydoc as_associative_container */ + [[nodiscard]] meta_associative_container as_associative_container() const noexcept { + meta_associative_container proxy{}; + if(*this) { vtable(internal::meta_traits::is_associative_container | internal::meta_traits::is_const, *this, &proxy); } + return proxy; + } + + /** + * @brief Indirection operator for dereferencing opaque objects. + * @return A wrapper that shares a reference to an unmanaged object if the + * wrapped element is dereferenceable, an invalid meta any otherwise. + */ + [[nodiscard]] meta_any operator*() const noexcept { + meta_any ret{meta_ctx_arg, *ctx}; + if(*this) { vtable(internal::meta_traits::is_pointer_like, ret, storage.data()); } + return ret; + } + + /*! @copydoc any::operator bool */ + [[nodiscard]] explicit operator bool() const noexcept { + return !(vtable == nullptr); + } + + /*! @copydoc any::operator== */ + [[nodiscard]] bool operator==(const meta_any &other) const noexcept { + return (ctx == other.ctx) && (!*this == !other) && (storage == other.storage); + } + + /*! @copydoc any::operator!= */ + [[nodiscard]] bool operator!=(const meta_any &other) const noexcept { + return !(*this == other); + } + + /*! @copydoc any::as_ref */ + [[nodiscard]] meta_any as_ref() noexcept { + return meta_any{*this, storage.as_ref()}; + } + + /*! @copydoc any::as_ref */ + [[nodiscard]] meta_any as_ref() const noexcept { + return meta_any{*this, storage.as_ref()}; + } + + /** + * @brief Returns the underlying storage. + * @return The underlyig storage. + */ + [[nodiscard]] const any &base() const noexcept { + return storage; + } + + /** + * @brief Returns the underlying meta context. + * @return The underlying meta context. + */ + [[nodiscard]] const meta_ctx &context() const noexcept { + return *ctx; + } + +private: + any storage{}; + const meta_ctx *ctx{&locator::value_or()}; + mutable const internal::meta_type_node *node{}; + vtable_type *vtable{}; +}; + +/** + * @brief Forwards its argument and avoids copies for lvalue references. + * @tparam Type Type of argument to use to construct the new instance. + * @param value Parameter to use to construct the instance. + * @param ctx The context from which to search for meta types. + * @return A properly initialized and not necessarily owning wrapper. + */ +template +[[nodiscard]] meta_any forward_as_meta(const meta_ctx &ctx, Type &&value) { + return meta_any{ctx, std::in_place_type, std::forward(value)}; +} + +/** + * @brief Forwards its argument and avoids copies for lvalue references. + * @tparam Type Type of argument to use to construct the new instance. + * @param value Parameter to use to construct the instance. + * @return A properly initialized and not necessarily owning wrapper. + */ +template +[[nodiscard]] meta_any forward_as_meta(Type &&value) { + return forward_as_meta(locator::value_or(), std::forward(value)); +} + +/*! @brief Opaque pointers to instances of any type. */ +class meta_handle { + template, meta_any>>> + meta_handle(int, Type &value, Args &&...args) + : any{std::forward(args)..., value.as_ref()} {} + + template + meta_handle(char, Type &value, Args &&...args) + : any{std::forward(args)..., std::in_place_type, value} {} + +public: + /*! Default constructor. */ + meta_handle() = default; + + /** + * @brief Creates a handle that points to an unmanaged object. + * @tparam Type Type of object to use to initialize the handle. + * @param ctx The context from which to search for meta types. + * @param value An instance of an object to use to initialize the handle. + */ + template, meta_handle>>> + meta_handle(const meta_ctx &ctx, Type &value) + : meta_handle{0, value, ctx} {} + + /** + * @brief Creates a handle that points to an unmanaged object. + * @tparam Type Type of object to use to initialize the handle. + * @param value An instance of an object to use to initialize the handle. + */ + template, meta_handle>>> + meta_handle(Type &value) + : meta_handle{0, value} {} + + /** + * @brief Context aware move constructor. + * @param area The context from which to search for meta types. + * @param other The instance to move from. + */ + meta_handle(const meta_ctx &area, meta_handle &&other) + : any{area, std::move(other.any)} {} + + /*! @brief Default copy constructor, deleted on purpose. */ + meta_handle(const meta_handle &) = delete; + + /*! @brief Default move constructor. */ + meta_handle(meta_handle &&) = default; + + /*! @brief Default destructor. */ + ~meta_handle() = default; + + /** + * @brief Default copy assignment operator, deleted on purpose. + * @return This meta handle. + */ + meta_handle &operator=(const meta_handle &) = delete; + + /** + * @brief Default move assignment operator. + * @return This meta handle. + */ + meta_handle &operator=(meta_handle &&) = default; + + /** + * @brief Returns false if a handle is invalid, true otherwise. + * @return False if the handle is invalid, true otherwise. + */ + [[nodiscard]] explicit operator bool() const noexcept { + return static_cast(any); + } + + /** + * @brief Access operator for accessing the contained opaque object. + * @return A wrapper that shares a reference to an unmanaged object. + */ + [[nodiscard]] meta_any *operator->() { + return &any; + } + + /*! @copydoc operator-> */ + [[deprecated("do not use const handles")]] [[nodiscard]] const meta_any *operator->() const { + return &any; + } + +private: + meta_any any{}; +}; + +/*! @brief Opaque wrapper for user defined data of any type. */ +struct meta_custom { + /*! @brief Default constructor. */ + meta_custom() noexcept = default; + + /** + * @brief Basic constructor for meta objects. + * @param curr The underlying node with which to construct the instance. + */ + meta_custom(const internal::meta_custom_node &curr) noexcept + : node{&curr} {} + + /** + * @brief Generic conversion operator. + * @tparam Type Type to which conversion is requested. + */ + template + [[nodiscard]] operator Type *() const noexcept { + return ((node != nullptr) && (type_hash>::value() == node->type)) ? static_cast(node->value.get()) : nullptr; + } + + /** + * @brief Generic conversion operator. + * @tparam Type Type to which conversion is requested. + */ + template + [[nodiscard]] operator Type &() const noexcept { + ENTT_ASSERT(static_cast(*this) != nullptr, "Invalid type"); + return *static_cast(node->value.get()); + } + +private: + const internal::meta_custom_node *node{}; +}; + +/*! @brief Opaque wrapper for data members. */ +class meta_data { + [[nodiscard]] auto &node_or_assert() const noexcept { + ENTT_ASSERT(node != nullptr, "Invalid pointer to node"); + return *node; + } + +public: + /*! @brief Unsigned integer type. */ + using size_type = typename internal::meta_data_node::size_type; + + /*! @brief Default constructor. */ + meta_data() noexcept = default; + + /** + * @brief Context aware constructor for meta objects. + * @param area The context from which to search for meta types. + * @param curr The underlying node with which to construct the instance. + */ + meta_data(const meta_ctx &area, const internal::meta_data_node &curr) noexcept + : node{&curr}, + ctx{&area} {} + + /** + * @brief Returns the name assigned to a data member, if any. + * @return The name assigned to the data member, if any. + */ + [[nodiscard]] const char *name() const noexcept { + return node_or_assert().name; + } + + /** + * @brief Returns the number of setters available. + * @return The number of setters available. + */ + [[nodiscard]] size_type arity() const noexcept { + return node_or_assert().arity; + } + + /** + * @brief Indicates whether a data member is constant or not. + * @return True if the data member is constant, false otherwise. + */ + [[nodiscard]] bool is_const() const noexcept { + return !!(node_or_assert().traits & internal::meta_traits::is_const); + } + + /** + * @brief Indicates whether a data member is static or not. + * @return True if the data member is static, false otherwise. + */ + [[nodiscard]] bool is_static() const noexcept { + return !!(node_or_assert().traits & internal::meta_traits::is_static); + } + + /*! @copydoc meta_any::type */ + [[nodiscard]] inline meta_type type() const noexcept; + + /** + * @brief Sets the value of a given variable. + * @tparam Instance Type of instance to operate on. + * @tparam Type Type of value to assign. + * @param instance An instance that fits the underlying type. + * @param value Parameter to use to set the underlying variable. + * @return True in case of success, false otherwise. + */ + template + // NOLINTNEXTLINE(modernize-use-nodiscard) + bool set(Instance &&instance, Type &&value) const { + return node_or_assert().set(meta_handle{*ctx, std::forward(instance)}, meta_any{*ctx, std::forward(value)}); + } + + /** + * @brief Gets the value of a given variable. + * @tparam Instance Type of instance to operate on. + * @param instance An instance that fits the underlying type. + * @return A wrapper containing the value of the underlying variable. + */ + template + [[nodiscard]] meta_any get(Instance &&instance) const { + return node_or_assert().get(meta_handle{*ctx, std::forward(instance)}); + } + + /** + * @brief Returns the type accepted by the i-th setter. + * @param index Index of the setter of which to return the accepted type. + * @return The type accepted by the i-th setter. + */ + [[nodiscard]] inline meta_type arg(size_type index) const noexcept; + + /** + * @brief Returns all meta traits for a given meta object. + * @tparam Type The type to convert the meta traits to. + * @return The registered meta traits, if any. + */ + template + [[nodiscard]] Type traits() const noexcept { + return internal::meta_to_user_traits(node_or_assert().traits); + } + + /** + * @brief Returns user defined data for a given meta object. + * @return User defined arbitrary data. + */ + [[nodiscard]] meta_custom custom() const noexcept { + return {node_or_assert().custom}; + } + + /** + * @brief Returns true if an object is valid, false otherwise. + * @return True if the object is valid, false otherwise. + */ + [[nodiscard]] explicit operator bool() const noexcept { + return (node != nullptr); + } + + /** + * @brief Checks if two objects refer to the same type. + * @param other The object with which to compare. + * @return True if the objects refer to the same type, false otherwise. + */ + [[nodiscard]] bool operator==(const meta_data &other) const noexcept { + return (ctx == other.ctx) && (node == other.node); + } + +private: + const internal::meta_data_node *node{}; + const meta_ctx *ctx{&locator::value_or()}; +}; + +/** + * @brief Checks if two objects refer to the same type. + * @param lhs An object, either valid or not. + * @param rhs An object, either valid or not. + * @return False if the objects refer to the same node, true otherwise. + */ +[[nodiscard]] inline bool operator!=(const meta_data &lhs, const meta_data &rhs) noexcept { + return !(lhs == rhs); +} + +/*! @brief Opaque wrapper for member functions. */ +class meta_func { + [[nodiscard]] auto &node_or_assert() const noexcept { + ENTT_ASSERT(node != nullptr, "Invalid pointer to node"); + return *node; + } + +public: + /*! @brief Unsigned integer type. */ + using size_type = typename internal::meta_func_node::size_type; + + /*! @brief Default constructor. */ + meta_func() noexcept = default; + + /** + * @brief Context aware constructor for meta objects. + * @param area The context from which to search for meta types. + * @param curr The underlying node with which to construct the instance. + */ + meta_func(const meta_ctx &area, const internal::meta_func_node &curr) noexcept + : node{&curr}, + ctx{&area} {} + + /** + * @brief Returns the name assigned to a member function, if any. + * @return The name assigned to the member function, if any. + */ + [[nodiscard]] const char *name() const noexcept { + return node_or_assert().name; + } + + /** + * @brief Returns the number of arguments accepted by a member function. + * @return The number of arguments accepted by the member function. + */ + [[nodiscard]] size_type arity() const noexcept { + return node_or_assert().arity; + } + + /** + * @brief Indicates whether a member function is constant or not. + * @return True if the member function is constant, false otherwise. + */ + [[nodiscard]] bool is_const() const noexcept { + return !!(node_or_assert().traits & internal::meta_traits::is_const); + } + + /** + * @brief Indicates whether a member function is static or not. + * @return True if the member function is static, false otherwise. + */ + [[nodiscard]] bool is_static() const noexcept { + return !!(node_or_assert().traits & internal::meta_traits::is_static); + } + + /** + * @brief Returns the return type of a member function. + * @return The return type of the member function. + */ + [[nodiscard]] inline meta_type ret() const noexcept; + + /** + * @brief Returns the type of the i-th argument of a member function. + * @param index Index of the argument of which to return the type. + * @return The type of the i-th argument of a member function. + */ + [[nodiscard]] inline meta_type arg(size_type index) const noexcept; + + /** + * @brief Invokes the underlying function, if possible. + * @tparam Instance Type of instance to operate on. + * @param instance An instance that fits the underlying type. + * @param args Parameters to use to invoke the function. + * @param sz Number of parameters to use to invoke the function. + * @return A wrapper containing the returned value, if any. + */ + template + meta_any invoke(Instance &&instance, meta_any *const args, const size_type sz) const { + return (sz == arity()) ? node_or_assert().invoke(meta_handle{*ctx, std::forward(instance)}, args) : meta_any{meta_ctx_arg, *ctx}; + } + + /** + * @copybrief invoke + * @tparam Instance Type of instance to operate on. + * @tparam Args Types of arguments to use to invoke the function. + * @param instance An instance that fits the underlying type. + * @param args Parameters to use to invoke the function. + * @return A wrapper containing the returned value, if any. + */ + template + // NOLINTNEXTLINE(modernize-use-nodiscard) + meta_any invoke(Instance &&instance, Args &&...args) const { + return invoke(std::forward(instance), std::array{meta_any{*ctx, std::forward(args)}...}.data(), sizeof...(Args)); + } + + /*! @copydoc meta_data::traits */ + template + [[nodiscard]] Type traits() const noexcept { + return internal::meta_to_user_traits(node_or_assert().traits); + } + + /*! @copydoc meta_data::custom */ + [[nodiscard]] meta_custom custom() const noexcept { + return {node_or_assert().custom}; + } + + /** + * @brief Returns the next overload of a given function, if any. + * @return The next overload of the given function, if any. + */ + [[nodiscard]] meta_func next() const { + return (node_or_assert().next != nullptr) ? meta_func{*ctx, *node_or_assert().next} : meta_func{}; + } + + /*! @copydoc meta_data::operator bool */ + [[nodiscard]] explicit operator bool() const noexcept { + return (node != nullptr); + } + + /*! @copydoc meta_data::operator== */ + [[nodiscard]] bool operator==(const meta_func &other) const noexcept { + return (ctx == other.ctx) && (node == other.node); + } + +private: + const internal::meta_func_node *node{}; + const meta_ctx *ctx{&locator::value_or()}; +}; + +/*! @copydoc operator!=(const meta_data &, const meta_data &) */ +[[nodiscard]] inline bool operator!=(const meta_func &lhs, const meta_func &rhs) noexcept { + return !(lhs == rhs); +} + +/*! @brief Opaque wrapper for types. */ +class meta_type { + [[nodiscard]] const auto &fetch_node() const { + return (node == nullptr) ? internal::resolve(internal::meta_context::from(*ctx)) : *node; + } + + template + [[nodiscard]] auto lookup(meta_any *const args, const typename internal::meta_type_node::size_type sz, [[maybe_unused]] bool constness, Func next) const { + decltype(next()) candidate = nullptr; + size_type same{}; + bool ambiguous{}; + + for(auto curr = next(); curr; curr = next()) { + if constexpr(std::is_same_v, internal::meta_func_node>) { + if(constness && !(curr->traits & internal::meta_traits::is_const)) { + continue; + } + } + + if(curr->arity == sz) { + size_type match{}; + size_type pos{}; + + // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic) - waiting for C++20 (and std::span) + for(; pos < sz && args[pos]; ++pos) { + const auto other = curr->arg(*ctx, pos); + const auto type = args[pos].type(); + + if(const auto &info = other.info(); info == type.info()) { + ++match; + } else if(!(type.fetch_node().conversion_helper && other.fetch_node().conversion_helper) && !(type.fetch_node().details && (internal::find_member<&internal::meta_base_node::type>(type.fetch_node().details->base, info.hash()) || internal::find_member<&internal::meta_conv_node::type>(type.fetch_node().details->conv, info.hash())))) { + break; + } + } + // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic) + + if(pos == sz) { + if(!candidate || match > same) { + candidate = curr; + same = match; + ambiguous = false; + } else if(match == same) { + if constexpr(std::is_same_v, internal::meta_func_node>) { + if(!!(curr->traits & internal::meta_traits::is_const) != !!(candidate->traits & internal::meta_traits::is_const)) { + candidate = !!(candidate->traits & internal::meta_traits::is_const) ? curr : candidate; + ambiguous = false; + continue; + } + } + + ambiguous = true; + } + } + } + } + + return ambiguous ? nullptr : candidate; + } + +public: + /*! @brief Unsigned integer type. */ + using size_type = typename internal::meta_type_node::size_type; + + /*! @brief Default constructor. */ + meta_type() noexcept = default; + + /** + * @brief Context aware constructor for meta objects. + * @param area The context from which to search for meta types. + * @param curr The underlying node with which to construct the instance. + */ + meta_type(const meta_ctx &area, const internal::meta_type_node &curr) noexcept + : node{&curr}, + ctx{&area} {} + + /** + * @brief Context aware constructor for meta objects. + * @param area The context from which to search for meta types. + * @param curr The underlying node with which to construct the instance. + */ + meta_type(const meta_ctx &area, const internal::meta_base_node &curr) noexcept + : meta_type{area, curr.resolve(internal::meta_context::from(area))} {} + + /** + * @brief Returns the type info object of the underlying type. + * @return The type info object of the underlying type. + */ + [[nodiscard]] const type_info &info() const noexcept { + return *fetch_node().info; + } + + /** + * @brief Returns the identifier assigned to a type. + * @return The identifier assigned to the type. + */ + [[nodiscard]] id_type id() const noexcept { + return fetch_node().id; + } + + /** + * @brief Returns the name assigned to a type, if any. + * @return The name assigned to the type, if any. + */ + [[nodiscard]] const char *name() const noexcept { + return fetch_node().name; + } + + /** + * @brief Returns the size of the underlying type if known. + * @return The size of the underlying type if known, 0 otherwise. + */ + [[nodiscard]] size_type size_of() const noexcept { + return fetch_node().size_of; + } + + /** + * @brief Checks whether a type refers to an arithmetic type or not. + * @return True if the underlying type is an arithmetic type, false + * otherwise. + */ + [[nodiscard]] bool is_arithmetic() const noexcept { + return !!(fetch_node().traits & internal::meta_traits::is_arithmetic); + } + + /** + * @brief Checks whether a type refers to an integral type or not. + * @return True if the underlying type is an integral type, false otherwise. + */ + [[nodiscard]] bool is_integral() const noexcept { + return !!(fetch_node().traits & internal::meta_traits::is_integral); + } + + /** + * @brief Checks whether a type refers to a signed type or not. + * @return True if the underlying type is a signed type, false otherwise. + */ + [[nodiscard]] bool is_signed() const noexcept { + return !!(fetch_node().traits & internal::meta_traits::is_signed); + } + + /** + * @brief Checks whether a type refers to an array type or not. + * @return True if the underlying type is an array type, false otherwise. + */ + [[nodiscard]] bool is_array() const noexcept { + return !!(fetch_node().traits & internal::meta_traits::is_array); + } + + /** + * @brief Checks whether a type refers to an enum or not. + * @return True if the underlying type is an enum, false otherwise. + */ + [[nodiscard]] bool is_enum() const noexcept { + return !!(fetch_node().traits & internal::meta_traits::is_enum); + } + + /** + * @brief Checks whether a type refers to a class or not. + * @return True if the underlying type is a class, false otherwise. + */ + [[nodiscard]] bool is_class() const noexcept { + return !!(fetch_node().traits & internal::meta_traits::is_class); + } + + /** + * @brief Checks whether a type refers to a pointer or not. + * @return True if the underlying type is a pointer, false otherwise. + */ + [[nodiscard]] bool is_pointer() const noexcept { + return !!(fetch_node().traits & internal::meta_traits::is_pointer); + } + + /** + * @brief Provides the type for which the pointer is defined. + * @return The type for which the pointer is defined or this type if it + * doesn't refer to a pointer type. + */ + [[nodiscard]] meta_type remove_pointer() const noexcept { + return meta_type{*ctx, fetch_node().remove_pointer(internal::meta_context::from(*ctx))}; + } + + /** + * @brief Checks whether a type is a pointer-like type or not. + * @return True if the underlying type is pointer-like, false otherwise. + */ + [[nodiscard]] bool is_pointer_like() const noexcept { + return !!(fetch_node().traits & internal::meta_traits::is_pointer_like); + } + + /** + * @brief Checks whether a type refers to a sequence container or not. + * @return True if the type is a sequence container, false otherwise. + */ + [[nodiscard]] bool is_sequence_container() const noexcept { + return !!(fetch_node().traits & internal::meta_traits::is_sequence_container); + } + + /** + * @brief Checks whether a type refers to an associative container or not. + * @return True if the type is an associative container, false otherwise. + */ + [[nodiscard]] bool is_associative_container() const noexcept { + return !!(fetch_node().traits & internal::meta_traits::is_associative_container); + } + + /** + * @brief Checks whether a type refers to a template specialization or not. + * @return True if the type is a template specialization, false otherwise. + */ + [[nodiscard]] bool is_template_specialization() const noexcept { + return (fetch_node().templ.arity != 0u); + } + + /** + * @brief Returns the number of template arguments. + * @return The number of template arguments. + */ + [[nodiscard]] size_type template_arity() const noexcept { + return fetch_node().templ.arity; + } + + /** + * @brief Returns a tag for the class template of the underlying type. + * @return The tag for the class template of the underlying type. + */ + [[nodiscard]] meta_type template_type() const noexcept { + return (fetch_node().templ.resolve != nullptr) ? meta_type{*ctx, fetch_node().templ.resolve(internal::meta_context::from(*ctx))} : meta_type{}; + } + + /** + * @brief Returns the type of the i-th template argument of a type. + * @param index Index of the template argument of which to return the type. + * @return The type of the i-th template argument of a type. + */ + [[nodiscard]] meta_type template_arg(const size_type index) const noexcept { + return index < template_arity() ? meta_type{*ctx, fetch_node().templ.arg(internal::meta_context::from(*ctx), index)} : meta_type{}; + } + + /** + * @brief Checks if a type supports direct casting to another type. + * @param other The meta type to test for. + * @return True if direct casting is allowed, false otherwise. + */ + [[nodiscard]] bool can_cast(const meta_type &other) const noexcept { + // casting this is UB in all cases but we aren't going to use the resulting pointer, so... + return other && ((*this == other) || (internal::try_cast(internal::meta_context::from(*ctx), fetch_node(), other.fetch_node().info->hash(), this) != nullptr)); + } + + /** + * @brief Checks whether a type supports conversion to another type. + * @param other The meta type to test for. + * @return True if the conversion is allowed, false otherwise. + */ + [[nodiscard]] bool can_convert(const meta_type &other) const noexcept { + if(const auto &to = other.info().hash(); (info().hash() == to) || ((fetch_node().conversion_helper != nullptr) && (other.is_arithmetic() || other.is_enum()))) { + return true; + } else if(const auto &from = fetch_node(); from.details) { + if(const auto *elem = internal::find_member<&internal::meta_conv_node::type>(from.details->conv, to); elem != nullptr) { + return true; + } + + for(auto &&curr: from.details->base) { + if(curr.type == to || meta_type{*ctx, curr.resolve(internal::meta_context::from(*ctx))}.can_convert(other)) { + return true; + } + } + } + + return false; + } + + /** + * @brief Returns a range to visit registered top-level base meta types. + * @return An iterable range to visit registered top-level base meta types. + */ + [[nodiscard]] meta_range base() const noexcept { + using range_type = meta_range; + return fetch_node().details ? range_type{{*ctx, fetch_node().details->base.cbegin()}, {*ctx, fetch_node().details->base.cend()}} : range_type{}; + } + + /** + * @brief Returns a range to visit registered top-level meta data. + * @return An iterable range to visit registered top-level meta data. + */ + [[nodiscard]] meta_range data() const noexcept { + using range_type = meta_range; + return fetch_node().details ? range_type{{*ctx, fetch_node().details->data.cbegin()}, {*ctx, fetch_node().details->data.cend()}} : range_type{}; + } + + /** + * @brief Lookup utility for meta data (bases are also visited). + * @param id Unique identifier. + * @param recursive True for a search in the base classes, false otherwise. + * @return The registered meta data for the given identifier, if any. + */ + [[nodiscard]] meta_data data(const id_type id, const bool recursive = true) const { + const auto *elem = internal::look_for<&internal::meta_type_descriptor::data>(internal::meta_context::from(*ctx), fetch_node(), id, recursive); + return (elem != nullptr) ? meta_data{*ctx, *elem} : meta_data{}; + } + + /** + * @brief Returns a range to visit registered top-level functions. + * @return An iterable range to visit registered top-level functions. + */ + [[nodiscard]] meta_range func() const noexcept { + using return_type = meta_range; + return fetch_node().details ? return_type{{*ctx, fetch_node().details->func.cbegin()}, {*ctx, fetch_node().details->func.cend()}} : return_type{}; + } + + /** + * @brief Lookup utility for meta functions (bases are also visited). + * @param id Unique identifier. + * @param recursive True for a search in the base classes, false otherwise. + * @return The registered meta function for the given identifier, if any. + */ + [[nodiscard]] meta_func func(const id_type id, const bool recursive = true) const { + const auto *elem = internal::look_for<&internal::meta_type_descriptor::func>(internal::meta_context::from(*ctx), fetch_node(), id, recursive); + return (elem != nullptr) ? meta_func{*ctx, *elem} : meta_func{}; + } + + /** + * @brief Creates an instance of the underlying type, if possible. + * @param args Parameters to use to construct the instance. + * @param sz Number of parameters to use to construct the instance. + * @return A wrapper containing the new instance, if any. + */ + [[nodiscard]] meta_any construct(meta_any *const args, const size_type sz) const { + if(const auto &ref = fetch_node(); ref.details) { + if(const auto *candidate = lookup(args, sz, false, [first = ref.details->ctor.cbegin(), last = ref.details->ctor.cend()]() mutable { return first == last ? nullptr : &*(first++); }); candidate) { + return candidate->invoke(*ctx, args); + } + } + + if(const auto &ref = fetch_node(); (sz == 0u) && (ref.default_constructor != nullptr)) { + return ref.default_constructor(*ctx); + } + + return meta_any{meta_ctx_arg, *ctx}; + } + + /** + * @copybrief construct + * @tparam Args Types of arguments to use to construct the instance. + * @param args Parameters to use to construct the instance. + * @return A wrapper containing the new instance, if any. + */ + template + [[nodiscard]] meta_any construct(Args &&...args) const { + return construct(std::array{meta_any{*ctx, std::forward(args)}...}.data(), sizeof...(Args)); + // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) + } + + /** + * @brief Wraps an opaque element of the underlying type. + * @param elem A valid pointer to an element of the underlying type. + * @param transfer_ownership True to transfer ownership, false otherwise. + * @return A wrapper that references the given instance. + */ + [[nodiscard]] meta_any from_void(void *elem, bool transfer_ownership = false) const { + return ((elem != nullptr) && (fetch_node().from_void != nullptr)) ? fetch_node().from_void(*ctx, elem, transfer_ownership ? elem : nullptr) : meta_any{meta_ctx_arg, *ctx}; + } + + /** + * @brief Wraps an opaque element of the underlying type. + * @param elem A valid pointer to an element of the underlying type. + * @return A wrapper that references the given instance. + */ + [[nodiscard]] meta_any from_void(const void *elem) const { + return ((elem != nullptr) && (fetch_node().from_void != nullptr)) ? fetch_node().from_void(*ctx, nullptr, elem) : meta_any{meta_ctx_arg, *ctx}; + } + + /** + * @brief Invokes a function given an identifier, if possible. + * @tparam Instance Type of instance to operate on. + * @param id Unique identifier. + * @param instance An instance that fits the underlying type. + * @param args Parameters to use to invoke the function. + * @param sz Number of parameters to use to invoke the function. + * @return A wrapper containing the returned value, if any. + */ + template + // NOLINTNEXTLINE(modernize-use-nodiscard) + meta_any invoke(const id_type id, Instance &&instance, meta_any *const args, const size_type sz) const { + meta_handle wrapped{*ctx, std::forward(instance)}; + + if(const auto &ref = fetch_node(); ref.details) { + if(auto *elem = internal::find_member<&internal::meta_func_node::id>(ref.details->func, id); elem != nullptr) { + if(const auto *candidate = lookup(args, sz, (wrapped->base().policy() == any_policy::cref), [curr = elem]() mutable { return (curr != nullptr) ? std::exchange(curr, curr->next.get()) : nullptr; }); candidate) { + return candidate->invoke(std::move(wrapped), args); + } + } + } + + for(auto &&curr: base()) { + if(auto elem = curr.second.invoke(id, *wrapped.operator->(), args, sz); elem) { + return elem; + } + } + + return meta_any{meta_ctx_arg, *ctx}; + } + + /** + * @copybrief invoke + * @param id Unique identifier. + * @tparam Instance Type of instance to operate on. + * @tparam Args Types of arguments to use to invoke the function. + * @param instance An instance that fits the underlying type. + * @param args Parameters to use to invoke the function. + * @return A wrapper containing the returned value, if any. + */ + template + // NOLINTNEXTLINE(modernize-use-nodiscard) + meta_any invoke(const id_type id, Instance &&instance, Args &&...args) const { + return invoke(id, std::forward(instance), std::array{meta_any{*ctx, std::forward(args)}...}.data(), sizeof...(Args)); + } + + /** + * @brief Sets the value of a given variable. + * @tparam Instance Type of instance to operate on. + * @tparam Type Type of value to assign. + * @param id Unique identifier. + * @param instance An instance that fits the underlying type. + * @param value Parameter to use to set the underlying variable. + * @return True in case of success, false otherwise. + */ + template + // NOLINTNEXTLINE(modernize-use-nodiscard) + bool set(const id_type id, Instance &&instance, Type &&value) const { + const auto candidate = data(id); + return candidate && candidate.set(std::forward(instance), std::forward(value)); + } + + /** + * @brief Gets the value of a given variable. + * @tparam Instance Type of instance to operate on. + * @param id Unique identifier. + * @param instance An instance that fits the underlying type. + * @return A wrapper containing the value of the underlying variable. + */ + template + [[nodiscard]] meta_any get(const id_type id, Instance &&instance) const { + const auto candidate = data(id); + return candidate ? candidate.get(std::forward(instance)) : meta_any{meta_ctx_arg, *ctx}; + } + + /*! @copydoc meta_data::traits */ + template + [[nodiscard]] Type traits() const noexcept { + return internal::meta_to_user_traits(fetch_node().traits); + } + + /*! @copydoc meta_data::custom */ + [[nodiscard]] meta_custom custom() const noexcept { + return fetch_node().custom; + } + + /*! @copydoc meta_data::operator bool */ + [[nodiscard]] explicit operator bool() const noexcept { + return (node != nullptr); + } + + /*! @copydoc meta_data::operator== */ + [[nodiscard]] bool operator==(const meta_type &other) const noexcept { + return (ctx == other.ctx) && (fetch_node().id == other.fetch_node().id); + } + +private: + mutable const internal::meta_type_node *node{}; + const meta_ctx *ctx{&locator::value_or()}; +}; + +/*! @copydoc operator!=(const meta_data &, const meta_data &) */ +[[nodiscard]] inline bool operator!=(const meta_type &lhs, const meta_type &rhs) noexcept { + return !(lhs == rhs); +} + +[[nodiscard]] inline meta_type meta_any::type() const noexcept { + return *this ? meta_type{*ctx, fetch_node()} : meta_type{}; +} + +template +// NOLINTNEXTLINE(modernize-use-nodiscard) +meta_any meta_any::invoke(const id_type id, Args &&...args) const { + return type().invoke(id, *this, std::forward(args)...); +} + +template +meta_any meta_any::invoke(const id_type id, Args &&...args) { + return type().invoke(id, *this, std::forward(args)...); +} + +template +bool meta_any::set(const id_type id, Type &&value) { + return type().set(id, *this, std::forward(value)); +} + +[[nodiscard]] inline meta_any meta_any::get(const id_type id) const { + return type().get(id, *this); +} + +[[nodiscard]] inline meta_any meta_any::get(const id_type id) { + return type().get(id, *this); +} + +[[nodiscard]] inline meta_any meta_any::allow_cast(const meta_type &type) const { + if(storage.has_value(type.info())) { + return as_ref(); + } else if(*this) { + if(const auto &from = fetch_node(); (from.conversion_helper != nullptr) && (type.is_arithmetic() || type.is_enum())) { + auto other = type.construct(); + const auto value = from.conversion_helper(nullptr, storage.data()); + other.fetch_node().conversion_helper(other.storage.data(), &value); + return other; + } + + if(const auto &from = fetch_node(); from.details) { + if(const auto *elem = internal::find_member<&internal::meta_conv_node::type>(from.details->conv, type.info().hash()); elem != nullptr) { + return elem->conv(*ctx, storage.data()); + } + + for(auto &&curr: from.details->base) { + if(auto other = curr.resolve(internal::meta_context::from(*ctx)).from_void(*ctx, nullptr, curr.cast(storage.data())); curr.type == type.info().hash()) { + return other; + } else if(auto from_base = std::as_const(other).allow_cast(type); from_base) { + return from_base; + } + } + } + } + + return meta_any{meta_ctx_arg, *ctx}; +} + +[[nodiscard]] inline bool meta_any::allow_cast(const meta_type &type) { + if(storage.has_value(type.info())) { + return true; + } else if(auto other = std::as_const(*this).allow_cast(type); other) { + if(other.storage.owner()) { + std::swap(*this, other); + } + + return true; + } + + return false; +} + +inline bool meta_any::assign(const meta_any &other) { + if(!storage.assign(other.storage)) { + auto value = other.allow_cast(type()); + return storage.assign(value.storage); + } + + return true; +} + +inline bool meta_any::assign(meta_any &&other) { + return storage.assign(std::move(other.storage)) || storage.assign(std::as_const(other).allow_cast(type()).storage); +} + +[[nodiscard]] inline meta_type meta_data::type() const noexcept { + return meta_type{*ctx, node_or_assert().type(internal::meta_context::from(*ctx))}; +} + +[[nodiscard]] inline meta_type meta_data::arg(const size_type index) const noexcept { + return index < arity() ? node_or_assert().arg(*ctx, index) : meta_type{}; +} + +[[nodiscard]] inline meta_type meta_func::ret() const noexcept { + return meta_type{*ctx, node_or_assert().ret(internal::meta_context::from(*ctx))}; +} + +[[nodiscard]] inline meta_type meta_func::arg(const size_type index) const noexcept { + return index < arity() ? node_or_assert().arg(*ctx, index) : meta_type{}; +} + +/*! @cond TURN_OFF_DOXYGEN */ +class meta_sequence_container::meta_iterator final { + using vtable_type = void(const void *, const std::ptrdiff_t, meta_any *); + + template + static void basic_vtable(const void *value, const std::ptrdiff_t offset, meta_any *other) { + const auto &it = *static_cast(value); + other ? other->emplace(*it) : std::advance(const_cast(it), offset); + } + +public: + using value_type = meta_any; + using pointer = input_iterator_pointer; + using reference = value_type; + using difference_type = std::ptrdiff_t; + using iterator_category = std::input_iterator_tag; + using iterator_concept = std::bidirectional_iterator_tag; + + meta_iterator() = default; + + template + meta_iterator(const meta_ctx &area, It iter) noexcept + : ctx{&area}, + vtable{&basic_vtable}, + handle{iter} {} + + meta_iterator &operator++() noexcept { + return vtable(handle.data(), 1, nullptr), *this; + } + + meta_iterator operator++(int value) noexcept { + meta_iterator orig = *this; + vtable(handle.data(), ++value, nullptr); + return orig; + } + + meta_iterator &operator--() noexcept { + return vtable(handle.data(), -1, nullptr), *this; + } + + meta_iterator operator--(int value) noexcept { + meta_iterator orig = *this; + vtable(handle.data(), --value, nullptr); + return orig; + } + + [[nodiscard]] reference operator*() const { + reference other{meta_ctx_arg, *ctx}; + vtable(handle.data(), 0, &other); + return other; + } + + [[nodiscard]] pointer operator->() const { + return operator*(); + } + + [[nodiscard]] explicit operator bool() const noexcept { + return (vtable != nullptr); + } + + [[nodiscard]] bool operator==(const meta_iterator &other) const noexcept { + return handle == other.handle; + } + + [[nodiscard]] const any &base() const noexcept { + return handle; + } + +private: + const meta_ctx *ctx{}; + vtable_type *vtable{}; + any handle{}; +}; + +[[nodiscard]] inline bool operator!=(const meta_sequence_container::iterator &lhs, const meta_sequence_container::iterator &rhs) noexcept { + return !(lhs == rhs); +} + +class meta_associative_container::meta_iterator final { + using vtable_type = void(const void *, std::pair *); + + template + static void basic_vtable(const void *value, std::pair *other) { + if(const auto &it = *static_cast(value); other) { + if constexpr(KeyOnly) { + other->first.emplace(*it); + } else { + other->first.emplacefirst))>(it->first); + other->second.emplacesecond))>(it->second); + } + } else { + ++const_cast(it); + } + } + +public: + using value_type = std::pair; + using pointer = input_iterator_pointer; + using reference = value_type; + using difference_type = std::ptrdiff_t; + using iterator_category = std::input_iterator_tag; + using iterator_concept = std::forward_iterator_tag; + + meta_iterator() = default; + + template + meta_iterator(const meta_ctx &area, std::bool_constant, It iter) noexcept + : ctx{&area}, + vtable{&basic_vtable}, + handle{iter} {} + + meta_iterator &operator++() noexcept { + return vtable(handle.data(), nullptr), *this; + } + + meta_iterator operator++(int) noexcept { + meta_iterator orig = *this; + vtable(handle.data(), nullptr); + return orig; + } + + [[nodiscard]] reference operator*() const { + reference other{{meta_ctx_arg, *ctx}, {meta_ctx_arg, *ctx}}; + vtable(handle.data(), &other); + return other; + } + + [[nodiscard]] pointer operator->() const { + return operator*(); + } + + [[nodiscard]] explicit operator bool() const noexcept { + return (vtable != nullptr); + } + + [[nodiscard]] bool operator==(const meta_iterator &other) const noexcept { + return handle == other.handle; + } + +private: + const meta_ctx *ctx{}; + vtable_type *vtable{}; + any handle{}; +}; + +[[nodiscard]] inline bool operator!=(const meta_associative_container::iterator &lhs, const meta_associative_container::iterator &rhs) noexcept { + return !(lhs == rhs); +} +/*! @endcond */ + +/** + * @brief Returns the meta value type of a container. + * @return The meta value type of the container. + */ +[[nodiscard]] inline meta_type meta_sequence_container::value_type() const noexcept { + return (value_type_node != nullptr) ? meta_type{*ctx, value_type_node(internal::meta_context::from(*ctx))} : meta_type{}; +} + +/** + * @brief Returns the size of a container. + * @return The size of the container. + */ +[[nodiscard]] inline meta_sequence_container::size_type meta_sequence_container::size() const noexcept { + return size_fn(data); +} + +/** + * @brief Resizes a container to contain a given number of elements. + * @param sz The new size of the container. + * @return True in case of success, false otherwise. + */ +inline bool meta_sequence_container::resize(const size_type sz) { + return !const_only && resize_fn(const_cast(data), sz); +} + +/** + * @brief Clears the content of a container. + * @return True in case of success, false otherwise. + */ +inline bool meta_sequence_container::clear() { + return !const_only && clear_fn(const_cast(data)); +} + +/** + * @brief Reserves storage for at least the given number of elements. + * @param sz The new capacity of the container. + * @return True in case of success, false otherwise. + */ +inline bool meta_sequence_container::reserve(const size_type sz) { + return !const_only && reserve_fn(const_cast(data), sz); +} + +/** + * @brief Returns an iterator to the first element of a container. + * @return An iterator to the first element of the container. + */ +[[nodiscard]] inline meta_sequence_container::iterator meta_sequence_container::begin() { + return begin_end_fn(*ctx, const_only ? nullptr : const_cast(data), data, false); +} + +/** + * @brief Returns an iterator that is past the last element of a container. + * @return An iterator that is past the last element of the container. + */ +[[nodiscard]] inline meta_sequence_container::iterator meta_sequence_container::end() { + return begin_end_fn(*ctx, const_only ? nullptr : const_cast(data), data, true); +} + +/** + * @brief Inserts an element at a specified location of a container. + * @param it Iterator before which the element will be inserted. + * @param value Element value to insert. + * @return A possibly invalid iterator to the inserted element. + */ +inline meta_sequence_container::iterator meta_sequence_container::insert(const iterator &it, meta_any value) { + // this abomination is necessary because only on macos value_type and const_reference are different types for std::vector + if(const auto &vtype = value_type_node(internal::meta_context::from(*ctx)); !const_only && (value.allow_cast({*ctx, vtype}) || value.allow_cast({*ctx, const_reference_node(internal::meta_context::from(*ctx))}))) { + const bool is_value_type = (value.type().info() == *vtype.info); + return insert_fn(*ctx, const_cast(data), is_value_type ? value.base().data() : nullptr, is_value_type ? nullptr : value.base().data(), it); + } + + return iterator{}; +} + +/** + * @brief Removes a given element from a container. + * @param it Iterator to the element to remove. + * @return A possibly invalid iterator following the last removed element. + */ +inline meta_sequence_container::iterator meta_sequence_container::erase(const iterator &it) { + return const_only ? iterator{} : erase_fn(*ctx, const_cast(data), it); +} + +/** + * @brief Returns a reference to the element at a given location of a container. + * @param pos The position of the element to return. + * @return A reference to the requested element properly wrapped. + */ +[[nodiscard]] inline meta_any meta_sequence_container::operator[](const size_type pos) { + auto it = begin(); + it.operator++(static_cast(pos) - 1); + return *it; +} + +/** + * @brief Returns false if a proxy is invalid, true otherwise. + * @return False if the proxy is invalid, true otherwise. + */ +[[nodiscard]] inline meta_sequence_container::operator bool() const noexcept { + return (data != nullptr); +} + +/** + * @brief Returns the meta key type of a container. + * @return The meta key type of the a container. + */ +[[nodiscard]] inline meta_type meta_associative_container::key_type() const noexcept { + return (key_type_node != nullptr) ? meta_type{*ctx, key_type_node(internal::meta_context::from(*ctx))} : meta_type{}; +} + +/** + * @brief Returns the meta mapped type of a container. + * @return The meta mapped type of the a container. + */ +[[nodiscard]] inline meta_type meta_associative_container::mapped_type() const noexcept { + return (mapped_type_node != nullptr) ? meta_type{*ctx, mapped_type_node(internal::meta_context::from(*ctx))} : meta_type{}; +} + +/*! @copydoc meta_sequence_container::value_type */ +[[nodiscard]] inline meta_type meta_associative_container::value_type() const noexcept { + return (value_type_node != nullptr) ? meta_type{*ctx, value_type_node(internal::meta_context::from(*ctx))} : meta_type{}; +} + +/*! @copydoc meta_sequence_container::size */ +[[nodiscard]] inline meta_associative_container::size_type meta_associative_container::size() const noexcept { + return size_fn(data); +} + +/*! @copydoc meta_sequence_container::clear */ +inline bool meta_associative_container::clear() { + return !const_only && clear_fn(const_cast(data)); +} + +/*! @copydoc meta_sequence_container::reserve */ +inline bool meta_associative_container::reserve(const size_type sz) { + return !const_only && reserve_fn(const_cast(data), sz); +} + +/*! @copydoc meta_sequence_container::begin */ +[[nodiscard]] inline meta_associative_container::iterator meta_associative_container::begin() { + return begin_end_fn(*ctx, const_only ? nullptr : const_cast(data), data, false); +} + +/*! @copydoc meta_sequence_container::end */ +[[nodiscard]] inline meta_associative_container::iterator meta_associative_container::end() { + return begin_end_fn(*ctx, const_only ? nullptr : const_cast(data), data, true); +} + +/** + * @brief Inserts a key-only or key/value element into a container. + * @param key The key of the element to insert. + * @param value The value of the element to insert, if needed. + * @return A bool denoting whether the insertion took place. + */ +inline bool meta_associative_container::insert(meta_any key, meta_any value = {}) { + return !const_only && key.allow_cast(meta_type{*ctx, key_type_node(internal::meta_context::from(*ctx))}) + && ((mapped_type_node == nullptr) || value.allow_cast(meta_type{*ctx, mapped_type_node(internal::meta_context::from(*ctx))})) + && insert_fn(const_cast(data), key.base().data(), value.base().data()); +} + +/** + * @brief Removes the specified element from a container. + * @param key The key of the element to remove. + * @return A bool denoting whether the removal took place. + */ +inline meta_associative_container::size_type meta_associative_container::erase(meta_any key) { + return (!const_only && key.allow_cast(meta_type{*ctx, key_type_node(internal::meta_context::from(*ctx))})) ? erase_fn(const_cast(data), key.base().data()) : 0u; +} + +/** + * @brief Returns an iterator to the element with a given key, if any. + * @param key The key of the element to search. + * @return An iterator to the element with the given key, if any. + */ +[[nodiscard]] inline meta_associative_container::iterator meta_associative_container::find(meta_any key) { + return key.allow_cast(meta_type{*ctx, key_type_node(internal::meta_context::from(*ctx))}) ? find_fn(*ctx, const_only ? nullptr : const_cast(data), data, key.base().data()) : iterator{}; +} + +/** + * @brief Returns false if a proxy is invalid, true otherwise. + * @return False if the proxy is invalid, true otherwise. + */ +[[nodiscard]] inline meta_associative_container::operator bool() const noexcept { + return (data != nullptr); +} + +} // namespace entt + +#endif + +// #include "meta/node.hpp" +#ifndef ENTT_META_NODE_HPP +#define ENTT_META_NODE_HPP + +#include +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "../core/bit.hpp" + +// #include "../core/enum.hpp" + +// #include "../core/fwd.hpp" + +// #include "../core/type_info.hpp" + +// #include "../core/type_traits.hpp" + +// #include "../core/utility.hpp" + +// #include "context.hpp" + +// #include "type_traits.hpp" + + +namespace entt { + +class meta_any; +class meta_type; +class meta_handle; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +enum class meta_traits : std::uint32_t { + is_none = 0x0000, + is_const = 0x0001, + is_static = 0x0002, + is_arithmetic = 0x0004, + is_integral = 0x0008, + is_signed = 0x0010, + is_array = 0x0020, + is_enum = 0x0040, + is_class = 0x0080, + is_pointer = 0x0100, + is_pointer_like = 0x0200, + is_sequence_container = 0x0400, + is_associative_container = 0x0800, + _user_defined_traits = 0xFFFF, + _entt_enum_as_bitmask = 0xFFFF +}; + +template +[[nodiscard]] auto meta_to_user_traits(const meta_traits traits) noexcept { + static_assert(std::is_enum_v, "Invalid enum type"); + constexpr auto shift = popcount(static_cast>(meta_traits::_user_defined_traits)); + return Type{static_cast>(static_cast>(traits) >> shift)}; +} + +template +[[nodiscard]] auto user_to_meta_traits(const Type value) noexcept { + static_assert(std::is_enum_v, "Invalid enum type"); + constexpr auto shift = popcount(static_cast>(meta_traits::_user_defined_traits)); + const auto traits = static_cast>(static_cast>(value)); + ENTT_ASSERT(traits < ((~static_cast>(meta_traits::_user_defined_traits)) >> shift), "Invalid traits"); + return meta_traits{traits << shift}; +} + +struct meta_type_node; + +struct meta_custom_node { + id_type type{}; + std::shared_ptr value{}; +}; + +struct meta_base_node { + id_type type{}; + const meta_type_node &(*resolve)(const meta_context &) noexcept {}; + const void *(*cast)(const void *) noexcept {}; +}; + +struct meta_conv_node { + id_type type{}; + meta_any (*conv)(const meta_ctx &, const void *){}; +}; + +struct meta_ctor_node { + using size_type = std::size_t; + + id_type id{}; + size_type arity{0u}; + meta_type (*arg)(const meta_ctx &, const size_type) noexcept {}; + meta_any (*invoke)(const meta_ctx &, meta_any *const){}; +}; + +struct meta_data_node { + using size_type = std::size_t; + + id_type id{}; + const char *name{}; + meta_traits traits{meta_traits::is_none}; + size_type arity{0u}; + const meta_type_node &(*type)(const meta_context &) noexcept {}; + meta_type (*arg)(const meta_ctx &, const size_type) noexcept {}; + bool (*set)(meta_handle, meta_any){}; + meta_any (*get)(meta_handle){}; + meta_custom_node custom{}; +}; + +struct meta_func_node { + using size_type = std::size_t; + + id_type id{}; + const char *name{}; + meta_traits traits{meta_traits::is_none}; + size_type arity{0u}; + const meta_type_node &(*ret)(const meta_context &) noexcept {}; + meta_type (*arg)(const meta_ctx &, const size_type) noexcept {}; + meta_any (*invoke)(meta_handle, meta_any *const){}; + std::unique_ptr next; + meta_custom_node custom{}; +}; + +struct meta_template_node { + using size_type = std::size_t; + + size_type arity{0u}; + const meta_type_node &(*resolve)(const meta_context &) noexcept {}; + const meta_type_node &(*arg)(const meta_context &, const size_type) noexcept {}; +}; + +struct meta_type_descriptor { + std::vector ctor{}; + std::vector base{}; + std::vector conv{}; + std::vector data{}; + std::vector func{}; +}; + +struct meta_type_node { + using size_type = std::size_t; + + const type_info *info{}; + id_type id{}; + const char *name{}; + meta_traits traits{meta_traits::is_none}; + size_type size_of{0u}; + const meta_type_node &(*remove_pointer)(const meta_context &) noexcept {}; + meta_any (*default_constructor)(const meta_ctx &){}; + double (*conversion_helper)(void *, const void *){}; + meta_any (*from_void)(const meta_ctx &, void *, const void *){}; + meta_template_node templ{}; + meta_custom_node custom{}; + std::unique_ptr details{}; +}; + +template +[[nodiscard]] auto *find_member(Type &from, const Value value) { + for(auto &&elem: from) { + if((elem.*Member) == value) { + return &elem; + } + } + + return static_cast(nullptr); +} + +[[nodiscard]] inline auto *find_overload(meta_func_node *curr, std::remove_pointer_t *const ref) { + while((curr != nullptr) && (curr->invoke != ref)) { curr = curr->next.get(); } + return curr; +} + +template +[[nodiscard]] auto *look_for(const meta_context &context, const meta_type_node &node, const id_type id, bool recursive) { + using value_type = typename std::remove_reference_t*Member))>::value_type; + + if(node.details) { + if(auto *member = find_member<&value_type::id>((node.details.get()->*Member), id); member != nullptr) { + return member; + } + + if(recursive) { + for(auto &&curr: node.details->base) { + if(auto *elem = look_for(context, curr.resolve(context), id, recursive); elem) { + return elem; + } + } + } + } + + return static_cast(nullptr); +} + +template +const meta_type_node &resolve(const meta_context &) noexcept; + +template +[[nodiscard]] const meta_type_node &meta_arg_node(const meta_context &context, type_list, const std::size_t index) noexcept { + using resolve_type = const meta_type_node &(*)(const meta_context &) noexcept; + constexpr std::array list{&resolve>>...}; + ENTT_ASSERT(index < sizeof...(Args), "Out of bounds"); + return list[index](context); +} + +[[nodiscard]] inline const void *try_cast(const meta_context &context, const meta_type_node &from, const id_type to, const void *instance) noexcept { + if(from.details) { + for(auto &&curr: from.details->base) { + if(const void *other = curr.cast(instance); curr.type == to) { + return other; + } else if(const void *elem = try_cast(context, curr.resolve(context), to, other); elem) { + return elem; + } + } + } + + return nullptr; +} + +template +auto setup_node_for() noexcept { + meta_type_node node{ + &type_id(), + type_id().hash(), + nullptr, + (std::is_arithmetic_v ? meta_traits::is_arithmetic : meta_traits::is_none) + | (std::is_integral_v ? meta_traits::is_integral : meta_traits::is_none) + | (std::is_signed_v ? meta_traits::is_signed : meta_traits::is_none) + | (std::is_array_v ? meta_traits::is_array : meta_traits::is_none) + | (std::is_enum_v ? meta_traits::is_enum : meta_traits::is_none) + | (std::is_class_v ? meta_traits::is_class : meta_traits::is_none) + | (std::is_pointer_v ? meta_traits::is_pointer : meta_traits::is_none) + | (is_meta_pointer_like_v ? meta_traits::is_pointer_like : meta_traits::is_none) + | (is_complete_v> ? meta_traits::is_sequence_container : meta_traits::is_none) + | (is_complete_v> ? meta_traits::is_associative_container : meta_traits::is_none), + size_of_v, + &resolve>>}; + + if constexpr(std::is_default_constructible_v) { + node.default_constructor = +[](const meta_ctx &ctx) { + return meta_any{ctx, std::in_place_type}; + }; + } + + if constexpr(std::is_arithmetic_v) { + node.conversion_helper = +[](void *lhs, const void *rhs) { + return lhs ? static_cast(*static_cast(lhs) = static_cast(*static_cast(rhs))) : static_cast(*static_cast(rhs)); + }; + } else if constexpr(std::is_enum_v) { + node.conversion_helper = +[](void *lhs, const void *rhs) { + return lhs ? static_cast(*static_cast(lhs) = static_cast(static_cast>(*static_cast(rhs)))) : static_cast(*static_cast(rhs)); + }; + } + + if constexpr(!std::is_void_v && !std::is_function_v) { + node.from_void = +[](const meta_ctx &ctx, void *elem, const void *celem) { + if(elem && celem) { // ownership construction request + return meta_any{ctx, std::in_place, static_cast *>(elem)}; + } + + if(elem) { // non-const reference construction request + return meta_any{ctx, std::in_place_type &>, *static_cast *>(elem)}; + } + + // const reference construction request + return meta_any{ctx, std::in_place_type &>, *static_cast *>(celem)}; + }; + } + + if constexpr(is_complete_v>) { + node.templ = meta_template_node{ + meta_template_traits::args_type::size, + &resolve::class_type>, + +[](const meta_context &area, const std::size_t index) noexcept -> decltype(auto) { return meta_arg_node(area, typename meta_template_traits::args_type{}, index); }}; + } + + return node; +} + +[[nodiscard]] inline const meta_type_node *try_resolve(const meta_context &context, const type_info &info) noexcept { + const auto it = context.value.find(info.hash()); + return (it != context.value.end()) ? it->second.get() : nullptr; +} + +template +[[nodiscard]] const meta_type_node &resolve(const meta_context &context) noexcept { + static_assert(std::is_same_v>>, "Invalid type"); + static const meta_type_node node = setup_node_for(); + const auto *elem = try_resolve(context, *node.info); + return (elem == nullptr) ? node : *elem; +} + +} // namespace internal +/*! @endcond */ + +} // namespace entt + +#endif + +// #include "meta/pointer.hpp" +// IWYU pragma: always_keep + +#ifndef ENTT_META_POINTER_HPP +#define ENTT_META_POINTER_HPP + +#include +#include +// #include "type_traits.hpp" + + +namespace entt { + +/** + * @brief Makes plain pointers pointer-like types for the meta system. + * @tparam Type Element type. + */ +template +struct is_meta_pointer_like + : std::true_type {}; + +/** + * @brief Partial specialization used to reject pointers to arrays. + * @tparam Type Type of elements of the array. + * @tparam N Number of elements of the array. + */ +template +// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) +struct is_meta_pointer_like + : std::false_type {}; + +/** + * @brief Makes `std::shared_ptr`s of any type pointer-like types for the meta + * system. + * @tparam Type Element type. + */ +template +struct is_meta_pointer_like> + : std::true_type {}; + +/** + * @brief Makes `std::unique_ptr`s of any type pointer-like types for the meta + * system. + * @tparam Type Element type. + * @tparam Args Other arguments. + */ +template +struct is_meta_pointer_like> + : std::true_type {}; + +/** + * @brief Specialization for self-proclaimed meta pointer like types. + * @tparam Type Element type. + */ +template +struct is_meta_pointer_like> + : std::true_type {}; + +} // namespace entt + +#endif + +// #include "meta/policy.hpp" +#ifndef ENTT_META_POLICY_HPP +#define ENTT_META_POLICY_HPP + +#include + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +struct meta_policy {}; + +} // namespace internal +/*! @endcond */ + +/*! @brief Empty class type used to request the _as-is_ policy. */ +struct as_value_t final: private internal::meta_policy { + /*! @cond TURN_OFF_DOXYGEN */ + template + static constexpr bool value = true; + /*! @endcond */ +}; + +/*! @brief Empty class type used to request the _as void_ policy. */ +struct as_void_t final: private internal::meta_policy { + /*! @cond TURN_OFF_DOXYGEN */ + template + static constexpr bool value = true; + /*! @endcond */ +}; + +/*! @brief Empty class type used to request the _as ref_ policy. */ +struct as_ref_t final: private internal::meta_policy { + /*! @cond TURN_OFF_DOXYGEN */ + template + static constexpr bool value = std::is_reference_v && !std::is_const_v>; + /*! @endcond */ +}; + +/*! @brief Empty class type used to request the _as cref_ policy. */ +struct as_cref_t final: private internal::meta_policy { + /*! @cond TURN_OFF_DOXYGEN */ + template + static constexpr bool value = std::is_reference_v; + /*! @endcond */ +}; + +/*! @brief Empty class type used to request the _as auto_ policy. */ +struct as_is_t final: private internal::meta_policy { + /*! @cond TURN_OFF_DOXYGEN */ + template + static constexpr bool value = true; + /*! @endcond */ +}; + +/** + * @brief Provides the member constant `value` to true if a type also is a meta + * policy, false otherwise. + * @tparam Type Type to check. + */ +template +struct is_meta_policy + : std::bool_constant> {}; + +/** + * @brief Helper variable template. + * @tparam Type Type to check. + */ +template +inline constexpr bool is_meta_policy_v = is_meta_policy::value; + +} // namespace entt + +#endif + +// #include "meta/range.hpp" +#ifndef ENTT_META_RANGE_HPP +#define ENTT_META_RANGE_HPP + +#include +#include +#include +// #include "../core/fwd.hpp" + +// #include "../core/iterator.hpp" + +// #include "context.hpp" + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +struct meta_base_node; + +template +struct meta_range_iterator final { + using value_type = std::pair; + using pointer = input_iterator_pointer; + using reference = value_type; + using difference_type = std::ptrdiff_t; + using iterator_category = std::input_iterator_tag; + using iterator_concept = std::random_access_iterator_tag; + + constexpr meta_range_iterator() noexcept + : it{}, + ctx{} {} + + constexpr meta_range_iterator(const meta_ctx &area, const It iter) noexcept + : it{iter}, + ctx{&area} {} + + constexpr meta_range_iterator &operator++() noexcept { + return ++it, *this; + } + + constexpr meta_range_iterator operator++(int) noexcept { + const meta_range_iterator orig = *this; + return ++(*this), orig; + } + + constexpr meta_range_iterator &operator--() noexcept { + return --it, *this; + } + + constexpr meta_range_iterator operator--(int) noexcept { + const meta_range_iterator orig = *this; + return operator--(), orig; + } + + constexpr meta_range_iterator &operator+=(const difference_type value) noexcept { + it += value; + return *this; + } + + constexpr meta_range_iterator operator+(const difference_type value) const noexcept { + meta_range_iterator copy = *this; + return (copy += value); + } + + constexpr meta_range_iterator &operator-=(const difference_type value) noexcept { + return (*this += -value); + } + + constexpr meta_range_iterator operator-(const difference_type value) const noexcept { + return (*this + -value); + } + + [[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept { + if constexpr(std::is_same_v) { + return {it[value].first, Type{*ctx, *it[value].second}}; + } else if constexpr(std::is_same_v::value_type, meta_base_node>) { + return {it[value].type, Type{*ctx, it[value]}}; + } else { + return {it[value].id, Type{*ctx, it[value]}}; + } + } + + [[nodiscard]] constexpr pointer operator->() const noexcept { + return operator*(); + } + + [[nodiscard]] constexpr reference operator*() const noexcept { + return operator[](0); + } + + template + friend constexpr std::ptrdiff_t operator-(const meta_range_iterator &, const meta_range_iterator &) noexcept; + + template + friend constexpr bool operator==(const meta_range_iterator &, const meta_range_iterator &) noexcept; + + template + friend constexpr bool operator<(const meta_range_iterator &, const meta_range_iterator &) noexcept; + +private: + It it; + const meta_ctx *ctx; +}; + +template +[[nodiscard]] constexpr std::ptrdiff_t operator-(const meta_range_iterator &lhs, const meta_range_iterator &rhs) noexcept { + return lhs.it - rhs.it; +} + +template +[[nodiscard]] constexpr bool operator==(const meta_range_iterator &lhs, const meta_range_iterator &rhs) noexcept { + return lhs.it == rhs.it; +} + +template +[[nodiscard]] constexpr bool operator!=(const meta_range_iterator &lhs, const meta_range_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +template +[[nodiscard]] constexpr bool operator<(const meta_range_iterator &lhs, const meta_range_iterator &rhs) noexcept { + return lhs.it < rhs.it; +} + +template +[[nodiscard]] constexpr bool operator>(const meta_range_iterator &lhs, const meta_range_iterator &rhs) noexcept { + return rhs < lhs; +} + +template +[[nodiscard]] constexpr bool operator<=(const meta_range_iterator &lhs, const meta_range_iterator &rhs) noexcept { + return !(lhs > rhs); +} + +template +[[nodiscard]] constexpr bool operator>=(const meta_range_iterator &lhs, const meta_range_iterator &rhs) noexcept { + return !(lhs < rhs); +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Iterable range to use to iterate all types of meta objects. + * @tparam Type Type of meta objects returned. + * @tparam It Type of forward iterator. + */ +template +using meta_range = iterable_adaptor>; + +} // namespace entt + +#endif + +// #include "meta/resolve.hpp" +#ifndef ENTT_META_RESOLVE_HPP +#define ENTT_META_RESOLVE_HPP + +#include +// #include "../core/type_info.hpp" + +// #include "../locator/locator.hpp" + +// #include "context.hpp" + +// #include "meta.hpp" + +// #include "node.hpp" + +// #include "range.hpp" + + +namespace entt { + +/** + * @brief Returns the meta type associated with a given type. + * @tparam Type Type to use to search for a meta type. + * @param ctx The context from which to search for meta types. + * @return The meta type associated with the given type, if any. + */ +template +[[nodiscard]] meta_type resolve(const meta_ctx &ctx) noexcept { + const auto &context = internal::meta_context::from(ctx); + return {ctx, internal::resolve>>(context)}; +} + +/** + * @brief Returns the meta type associated with a given type. + * @tparam Type Type to use to search for a meta type. + * @return The meta type associated with the given type, if any. + */ +template +[[nodiscard]] meta_type resolve() noexcept { + return resolve(locator::value_or()); +} + +/** + * @brief Returns a range to use to visit all meta types. + * @param ctx The context from which to search for meta types. + * @return An iterable range to use to visit all meta types. + */ +[[nodiscard]] inline meta_range resolve(const meta_ctx &ctx) noexcept { + const auto &context = internal::meta_context::from(ctx); + return {{ctx, context.value.cbegin()}, {ctx, context.value.cend()}}; +} + +/** + * @brief Returns a range to use to visit all meta types. + * @return An iterable range to use to visit all meta types. + */ +[[nodiscard]] inline meta_range resolve() noexcept { + return resolve(locator::value_or()); +} + +/** + * @brief Returns the meta type associated with a given identifier, if any. + * @param ctx The context from which to search for meta types. + * @param id Unique identifier. + * @return The meta type associated with the given identifier, if any. + */ +[[nodiscard]] inline meta_type resolve(const meta_ctx &ctx, const id_type id) noexcept { + for(auto &&curr: resolve(ctx)) { + if(curr.second.id() == id) { + return curr.second; + } + } + + return meta_type{}; +} + +/** + * @brief Returns the meta type associated with a given identifier, if any. + * @param id Unique identifier. + * @return The meta type associated with the given identifier, if any. + */ +[[nodiscard]] inline meta_type resolve(const id_type id) noexcept { + return resolve(locator::value_or(), id); +} + +/** + * @brief Returns the meta type associated with a given type info object. + * @param ctx The context from which to search for meta types. + * @param info The type info object of the requested type. + * @return The meta type associated with the given type info object, if any. + */ +[[nodiscard]] inline meta_type resolve(const meta_ctx &ctx, const type_info &info) noexcept { + const auto &context = internal::meta_context::from(ctx); + const auto *elem = internal::try_resolve(context, info); + return (elem != nullptr) ? meta_type{ctx, *elem} : meta_type{}; +} + +/** + * @brief Returns the meta type associated with a given type info object. + * @param info The type info object of the requested type. + * @return The meta type associated with the given type info object, if any. + */ +[[nodiscard]] inline meta_type resolve(const type_info &info) noexcept { + return resolve(locator::value_or(), info); +} + +} // namespace entt + +#endif + +// #include "meta/template.hpp" +// IWYU pragma: always_keep + +#ifndef ENTT_META_TEMPLATE_HPP +#define ENTT_META_TEMPLATE_HPP + +// #include "../core/type_traits.hpp" + + +namespace entt { + +/*! @brief Utility class to disambiguate class templates. */ +template class> +struct meta_class_template_tag {}; + +/** + * @brief General purpose traits class for generating meta template information. + * @tparam Clazz Type of class template. + * @tparam Args Types of template arguments. + */ +template class Clazz, typename... Args> +struct meta_template_traits> { + /*! @brief Wrapped class template. */ + using class_type = meta_class_template_tag; + /*! @brief List of template arguments. */ + using args_type = type_list; +}; + +} // namespace entt + +#endif + +// #include "meta/type_traits.hpp" +#ifndef ENTT_META_TYPE_TRAITS_HPP +#define ENTT_META_TYPE_TRAITS_HPP + +#include +#include + +namespace entt { + +/** + * @brief Traits class template to be specialized to enable support for meta + * template information. + */ +template +struct meta_template_traits; + +/** + * @brief Traits class template to be specialized to enable support for meta + * sequence containers. + */ +template +struct meta_sequence_container_traits; + +/** + * @brief Traits class template to be specialized to enable support for meta + * associative containers. + */ +template +struct meta_associative_container_traits; + +/** + * @brief Provides the member constant `value` to true if a given type is a + * pointer-like type from the point of view of the meta system, false otherwise. + */ +template +struct is_meta_pointer_like: std::false_type {}; + +/** + * @brief Partial specialization to ensure that const pointer-like types are + * also accepted. + * @tparam Type Potentially pointer-like type. + */ +template +struct is_meta_pointer_like: is_meta_pointer_like {}; + +/** + * @brief Helper variable template. + * @tparam Type Potentially pointer-like type. + */ +template +inline constexpr auto is_meta_pointer_like_v = is_meta_pointer_like::value; + +} // namespace entt + +#endif + +// #include "meta/utility.hpp" +#ifndef ENTT_META_UTILITY_HPP +#define ENTT_META_UTILITY_HPP + +#include +#include +#include +#include +// #include "../core/type_traits.hpp" + +// #include "../locator/locator.hpp" + +// #include "meta.hpp" + +// #include "node.hpp" + +// #include "policy.hpp" + + +namespace entt { + +/** + * @brief Meta function descriptor traits. + * @tparam Ret Function return type. + * @tparam Args Function arguments. + * @tparam Static Function staticness. + * @tparam Const Function constness. + */ +template +struct meta_function_descriptor_traits { + /*! @brief Meta function return type. */ + using return_type = Ret; + /*! @brief Meta function arguments. */ + using args_type = Args; + + /*! @brief True if the meta function is static, false otherwise. */ + static constexpr bool is_static = Static; + /*! @brief True if the meta function is const, false otherwise. */ + static constexpr bool is_const = Const; +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct meta_function_descriptor; + +/** + * @brief Meta function descriptor. + * @tparam Type Reflected type to which the meta function is associated. + * @tparam Ret Function return type. + * @tparam Class Actual owner of the member function. + * @tparam Args Function arguments. + */ +template +struct meta_function_descriptor + : meta_function_descriptor_traits< + Ret, + std::conditional_t, type_list, type_list>, + !std::is_base_of_v, + true> {}; + +/** + * @brief Meta function descriptor. + * @tparam Type Reflected type to which the meta function is associated. + * @tparam Ret Function return type. + * @tparam Class Actual owner of the member function. + * @tparam Args Function arguments. + */ +template +struct meta_function_descriptor + : meta_function_descriptor_traits< + Ret, + std::conditional_t, type_list, type_list>, + !std::is_base_of_v, + false> {}; + +/** + * @brief Meta function descriptor. + * @tparam Type Reflected type to which the meta data is associated. + * @tparam Class Actual owner of the data member. + * @tparam Ret Data member type. + */ +template +struct meta_function_descriptor + : meta_function_descriptor_traits< + Ret &, + std::conditional_t, type_list<>, type_list>, + !std::is_base_of_v, + false> {}; + +/** + * @brief Meta function descriptor. + * @tparam Type Reflected type to which the meta function is associated. + * @tparam Ret Function return type. + * @tparam MaybeType First function argument. + * @tparam Args Other function arguments. + */ +template +struct meta_function_descriptor + : meta_function_descriptor_traits< + Ret, + std::conditional_t< + std::is_same_v>, Type> || std::is_base_of_v>, Type>, + type_list, + type_list>, + !(std::is_same_v>, Type> || std::is_base_of_v>, Type>), + std::is_const_v> && (std::is_same_v>, Type> || std::is_base_of_v>, Type>)> {}; + +/** + * @brief Meta function descriptor. + * @tparam Type Reflected type to which the meta function is associated. + * @tparam Ret Function return type. + */ +template +struct meta_function_descriptor + : meta_function_descriptor_traits< + Ret, + type_list<>, + true, + false> {}; + +/** + * @brief Meta function helper. + * + * Converts a function type to be associated with a reflected type into its meta + * function descriptor. + * + * @tparam Type Reflected type to which the meta function is associated. + * @tparam Candidate The actual function to associate with the reflected type. + */ +template +class meta_function_helper { + template + static constexpr meta_function_descriptor get_rid_of_noexcept(Ret (Class::*)(Args...) const); + + template + static constexpr meta_function_descriptor get_rid_of_noexcept(Ret (Class::*)(Args...)); + + template>> + static constexpr meta_function_descriptor get_rid_of_noexcept(Ret Class::*); + + template + static constexpr meta_function_descriptor get_rid_of_noexcept(Ret (*)(Args...)); + + template + static constexpr meta_function_descriptor get_rid_of_noexcept(Class); + +public: + /*! @brief The meta function descriptor of the given function. */ + using type = decltype(get_rid_of_noexcept(std::declval())); +}; + +/** + * @brief Helper type. + * @tparam Type Reflected type to which the meta function is associated. + * @tparam Candidate The actual function to associate with the reflected type. + */ +template +using meta_function_helper_t = typename meta_function_helper::type; + +/** + * @brief Wraps a value depending on the given policy. + * + * This function always returns a wrapped value in the requested context.
+ * Therefore, if the passed value is itself a wrapped object with a different + * context, it undergoes a rebinding to the requested context. + * + * @tparam Policy Optional policy (no policy set by default). + * @tparam Type Type of value to wrap. + * @param ctx The context from which to search for meta types. + * @param value Value to wrap. + * @return A meta any containing the returned value, if any. + */ +template +[[nodiscard]] std::enable_if_t, meta_any> meta_dispatch(const meta_ctx &ctx, [[maybe_unused]] Type &&value) { + if constexpr(std::is_same_v) { + static_assert(std::is_lvalue_reference_v, "Invalid type"); + return meta_any{ctx, std::in_place_type &>, std::as_const(value)}; + } else if constexpr(std::is_same_v || (std::is_same_v && std::is_lvalue_reference_v)) { + return meta_any{ctx, std::in_place_type, value}; + } else if constexpr(std::is_same_v) { + return meta_any{ctx, std::in_place_type}; + } else { + return meta_any{ctx, std::forward(value)}; + } +} + +/** + * @brief Wraps a value depending on the given policy. + * @tparam Policy Optional policy (no policy set by default). + * @tparam Type Type of value to wrap. + * @param value Value to wrap. + * @return A meta any containing the returned value, if any. + */ +template +[[nodiscard]] std::enable_if_t, meta_any> meta_dispatch(Type &&value) { + return meta_dispatch(locator::value_or(), std::forward(value)); +} + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +[[nodiscard]] meta_any meta_invoke_with_args(const meta_ctx &ctx, Candidate &&candidate, Args &&...args) { + if constexpr(std::is_void_v(candidate), args...))>) { + std::invoke(std::forward(candidate), args...); + return meta_any{ctx, std::in_place_type}; + } else { + return meta_dispatch(ctx, std::invoke(std::forward(candidate), args...)); + } +} + +template +[[nodiscard]] meta_any meta_invoke(meta_any &instance, Candidate &&candidate, [[maybe_unused]] meta_any *const args, std::index_sequence) { + using descriptor = meta_function_helper_t>; + + // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic) - waiting for C++20 (and std::span) + if constexpr(std::is_invocable_v, const Type &, type_list_element_t...>) { + if(const auto *const clazz = instance.try_cast(); clazz && ((args + Index)->allow_cast>() && ...)) { + return meta_invoke_with_args(instance.context(), std::forward(candidate), *clazz, (args + Index)->cast>()...); + } + } else if constexpr(std::is_invocable_v, Type &, type_list_element_t...>) { + if(auto *const clazz = instance.try_cast(); clazz && ((args + Index)->allow_cast>() && ...)) { + return meta_invoke_with_args(instance.context(), std::forward(candidate), *clazz, (args + Index)->cast>()...); + } + } else { + if(((args + Index)->allow_cast>() && ...)) { + return meta_invoke_with_args(instance.context(), std::forward(candidate), (args + Index)->cast>()...); + } + } + // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic) + + return meta_any{meta_ctx_arg, instance.context()}; +} + +template +[[nodiscard]] meta_any meta_construct(const meta_ctx &ctx, meta_any *const args, std::index_sequence) { + // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic) - waiting for C++20 (and std::span) + if(((args + Index)->allow_cast() && ...)) { + return meta_any{ctx, std::in_place_type, (args + Index)->cast()...}; + } + // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic) + + return meta_any{meta_ctx_arg, ctx}; +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Returns the meta type of the i-th element of a list of arguments. + * @tparam Type Type list of the actual types of arguments. + * @param ctx The context from which to search for meta types. + * @param index The index of the element for which to return the meta type. + * @return The meta type of the i-th element of the list of arguments. + */ +template +[[nodiscard]] meta_type meta_arg(const meta_ctx &ctx, const std::size_t index) noexcept { + const auto &context = internal::meta_context::from(ctx); + return {ctx, internal::meta_arg_node(context, Type{}, index)}; +} + +/** + * @brief Returns the meta type of the i-th element of a list of arguments. + * @tparam Type Type list of the actual types of arguments. + * @param index The index of the element for which to return the meta type. + * @return The meta type of the i-th element of the list of arguments. + */ +template +[[nodiscard]] meta_type meta_arg(const std::size_t index) noexcept { + return meta_arg(locator::value_or(), index); +} + +/** + * @brief Sets the value of a given variable. + * @tparam Type Reflected type to which the variable is associated. + * @tparam Data The actual variable to set. + * @param instance An opaque instance of the underlying type, if required. + * @param value Parameter to use to set the variable. + * @return True in case of success, false otherwise. + */ +template +[[nodiscard]] bool meta_setter([[maybe_unused]] meta_handle instance, [[maybe_unused]] meta_any value) { + if constexpr(std::is_member_function_pointer_v || std::is_function_v>>) { + using descriptor = meta_function_helper_t; + using data_type = type_list_element_t; + + if(auto *const clazz = instance->try_cast(); clazz && value.allow_cast()) { + std::invoke(Data, *clazz, value.cast()); + return true; + } + } else if constexpr(std::is_member_object_pointer_v) { + using data_type = std::remove_reference_t::return_type>; + + if constexpr(!std::is_array_v && !std::is_const_v) { + if(auto *const clazz = instance->try_cast(); clazz && value.allow_cast()) { + std::invoke(Data, *clazz) = value.cast(); + return true; + } + } + } else if constexpr(std::is_pointer_v) { + using data_type = std::remove_reference_t; + + if constexpr(!std::is_array_v && !std::is_const_v) { + if(value.allow_cast()) { + *Data = value.cast(); + return true; + } + } + } + + return false; +} + +/** + * @brief Gets the value of a given variable. + * @tparam Type Reflected type to which the variable is associated. + * @tparam Data The actual variable to get. + * @tparam Policy Optional policy (no policy set by default). + * @param instance An opaque instance of the underlying type, if required. + * @return A meta any containing the value of the underlying variable. + */ +template +[[nodiscard]] std::enable_if_t, meta_any> meta_getter(meta_handle instance) { + if constexpr(std::is_member_pointer_v || std::is_function_v>>) { + if constexpr(!std::is_array_v>>>) { + if constexpr(std::is_invocable_v) { + if(auto *clazz = instance->try_cast(); clazz) { + return meta_dispatch(instance->context(), std::invoke(Data, *clazz)); + } + } + + if constexpr(std::is_invocable_v) { + if(auto *fallback = instance->try_cast(); fallback) { + return meta_dispatch(instance->context(), std::invoke(Data, *fallback)); + } + } + } + + return meta_any{meta_ctx_arg, instance->context()}; + } else if constexpr(std::is_pointer_v) { + if constexpr(std::is_array_v>) { + return meta_any{meta_ctx_arg, instance->context()}; + } else { + return meta_dispatch(instance->context(), *Data); + } + } else { + return meta_dispatch(instance->context(), Data); + } +} + +/** + * @brief Tries to _invoke_ an object given a list of erased parameters. + * @tparam Type Reflected type to which the object to _invoke_ is associated. + * @tparam Policy Optional policy (no policy set by default). + * @tparam Candidate The type of the actual object to _invoke_. + * @param instance An opaque instance of the underlying type, if required. + * @param candidate The actual object to _invoke_. + * @param args Parameters to use to _invoke_ the object. + * @return A meta any containing the returned value, if any. + */ +template +[[nodiscard]] std::enable_if_t, meta_any> meta_invoke(meta_handle instance, Candidate &&candidate, meta_any *const args) { + return internal::meta_invoke(*instance.operator->(), std::forward(candidate), args, std::make_index_sequence>::args_type::size>{}); +} + +/** + * @brief Tries to invoke a function given a list of erased parameters. + * @tparam Type Reflected type to which the function is associated. + * @tparam Candidate The actual function to invoke. + * @tparam Policy Optional policy (no policy set by default). + * @param instance An opaque instance of the underlying type, if required. + * @param args Parameters to use to invoke the function. + * @return A meta any containing the returned value, if any. + */ +template +[[nodiscard]] std::enable_if_t, meta_any> meta_invoke(meta_handle instance, meta_any *const args) { + return internal::meta_invoke(*instance.operator->(), Candidate, args, std::make_index_sequence>::args_type::size>{}); +} + +/** + * @brief Tries to construct an instance given a list of erased parameters. + * + * @warning + * The context provided is used only for the return type.
+ * It's up to the caller to bind the arguments to the right context(s). + * + * @tparam Type Actual type of the instance to construct. + * @tparam Args Types of arguments expected. + * @param ctx The context from which to search for meta types. + * @param args Parameters to use to construct the instance. + * @return A meta any containing the new instance, if any. + */ +template +[[nodiscard]] meta_any meta_construct(const meta_ctx &ctx, meta_any *const args) { + return internal::meta_construct(ctx, args, std::index_sequence_for{}); +} + +/** + * @brief Tries to construct an instance given a list of erased parameters. + * @tparam Type Actual type of the instance to construct. + * @tparam Args Types of arguments expected. + * @param args Parameters to use to construct the instance. + * @return A meta any containing the new instance, if any. + */ +template +[[nodiscard]] meta_any meta_construct(meta_any *const args) { + return meta_construct(locator::value_or(), args); +} + +/** + * @brief Tries to construct an instance given a list of erased parameters. + * + * @warning + * The context provided is used only for the return type.
+ * It's up to the caller to bind the arguments to the right context(s). + * + * @tparam Type Reflected type to which the object to _invoke_ is associated. + * @tparam Policy Optional policy (no policy set by default). + * @tparam Candidate The type of the actual object to _invoke_. + * @param ctx The context from which to search for meta types. + * @param candidate The actual object to _invoke_. + * @param args Parameters to use to _invoke_ the object. + * @return A meta any containing the returned value, if any. + */ +template +[[nodiscard]] meta_any meta_construct(const meta_ctx &ctx, Candidate &&candidate, meta_any *const args) { + if constexpr(meta_function_helper_t::is_static || std::is_class_v>>) { + meta_any placeholder{meta_ctx_arg, ctx}; + return internal::meta_invoke(placeholder, std::forward(candidate), args, std::make_index_sequence>::args_type::size>{}); + } else { + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - waiting for C++20 (and std::span) + return internal::meta_invoke(*args, std::forward(candidate), args + 1u, std::make_index_sequence>::args_type::size>{}); + } +} + +/** + * @brief Tries to construct an instance given a list of erased parameters. + * @tparam Type Reflected type to which the object to _invoke_ is associated. + * @tparam Policy Optional policy (no policy set by default). + * @tparam Candidate The type of the actual object to _invoke_. + * @param candidate The actual object to _invoke_. + * @param args Parameters to use to _invoke_ the object. + * @return A meta any containing the returned value, if any. + */ +template +[[nodiscard]] std::enable_if_t, meta_any> meta_construct(Candidate &&candidate, meta_any *const args) { + return meta_construct(locator::value_or(), std::forward(candidate), args); +} + +/** + * @brief Tries to construct an instance given a list of erased parameters. + * + * @warning + * The context provided is used only for the return type.
+ * It's up to the caller to bind the arguments to the right context(s). + * + * @tparam Type Reflected type to which the function is associated. + * @tparam Candidate The actual function to invoke. + * @tparam Policy Optional policy (no policy set by default). + * @param ctx The context from which to search for meta types. + * @param args Parameters to use to invoke the function. + * @return A meta any containing the returned value, if any. + */ +template +[[nodiscard]] std::enable_if_t, meta_any> meta_construct(const meta_ctx &ctx, meta_any *const args) { + return meta_construct(ctx, Candidate, args); +} + +/** + * @brief Tries to construct an instance given a list of erased parameters. + * @tparam Type Reflected type to which the function is associated. + * @tparam Candidate The actual function to invoke. + * @tparam Policy Optional policy (no policy set by default). + * @param args Parameters to use to invoke the function. + * @return A meta any containing the returned value, if any. + */ +template +[[nodiscard]] std::enable_if_t, meta_any> meta_construct(meta_any *const args) { + return meta_construct(locator::value_or(), args); +} + +} // namespace entt + +#endif + +// #include "poly/poly.hpp" +#ifndef ENTT_POLY_POLY_HPP +#define ENTT_POLY_POLY_HPP + +#include +#include +#include +#include +#include +// #include "../core/any.hpp" +#ifndef ENTT_CORE_ANY_HPP +#define ENTT_CORE_ANY_HPP + +#include +#include +#include +#include +// #include "../config/config.h" +#ifndef ENTT_CONFIG_CONFIG_H +#define ENTT_CONFIG_CONFIG_H + +// #include "version.h" +#ifndef ENTT_CONFIG_VERSION_H +#define ENTT_CONFIG_VERSION_H + +// #include "macro.h" +#ifndef ENTT_CONFIG_MACRO_H +#define ENTT_CONFIG_MACRO_H + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#define ENTT_STR(arg) #arg +#define ENTT_XSTR(arg) ENTT_STR(arg) + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*) + +#define ENTT_VERSION_MAJOR 3 +#define ENTT_VERSION_MINOR 16 +#define ENTT_VERSION_PATCH 0 + +#define ENTT_VERSION \ + ENTT_XSTR(ENTT_VERSION_MAJOR) \ + "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH) + +// NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION) +# define ENTT_CONSTEXPR +# define ENTT_THROW throw +# define ENTT_TRY try +# define ENTT_CATCH catch(...) +#else +# define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20) +# define ENTT_THROW +# define ENTT_TRY if(true) +# define ENTT_CATCH if(false) +#endif + +#if __has_include() +# include +# +# if defined(__cpp_consteval) +# define ENTT_CONSTEVAL consteval +# endif +#endif + +#ifndef ENTT_CONSTEVAL +# define ENTT_CONSTEVAL constexpr +#endif + +#ifdef ENTT_USE_ATOMIC +# include +# define ENTT_MAYBE_ATOMIC(Type) std::atomic +#else +# define ENTT_MAYBE_ATOMIC(Type) Type +#endif + +#ifndef ENTT_ID_TYPE +# include +# define ENTT_ID_TYPE std::uint32_t +#else +# include // provides coverage for types in the std namespace +#endif + +#ifndef ENTT_SPARSE_PAGE +# define ENTT_SPARSE_PAGE 4096 +#endif + +#ifndef ENTT_PACKED_PAGE +# define ENTT_PACKED_PAGE 1024 +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT +# define ENTT_ASSERT(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT +# include +# define ENTT_ASSERT(condition, msg) assert(((condition) && (msg))) +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg) +#endif + +#define ENTT_FAIL(msg) ENTT_ASSERT(false, msg); + +#ifdef ENTT_NO_ETO +# define ENTT_ETO_TYPE(Type) void +#else +# define ENTT_ETO_TYPE(Type) Type +#endif + +#ifdef ENTT_NO_MIXIN +# define ENTT_STORAGE(Mixin, ...) __VA_ARGS__ +#else +# define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__> +#endif + +#ifdef ENTT_STANDARD_CPP +# define ENTT_NONSTD false +#else +# define ENTT_NONSTD true +# if defined __clang__ || defined __GNUC__ +# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ +# define ENTT_PRETTY_FUNCTION_PREFIX '=' +# define ENTT_PRETTY_FUNCTION_SUFFIX ']' +# elif defined _MSC_VER +# define ENTT_PRETTY_FUNCTION __FUNCSIG__ +# define ENTT_PRETTY_FUNCTION_PREFIX '<' +# define ENTT_PRETTY_FUNCTION_SUFFIX '>' +# endif +#endif + +#ifndef ENTT_EXPORT +# if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER +# define ENTT_EXPORT __declspec(dllexport) +# define ENTT_IMPORT __declspec(dllimport) +# define ENTT_HIDDEN +# elif defined __GNUC__ && __GNUC__ >= 4 +# define ENTT_EXPORT __attribute__((visibility("default"))) +# define ENTT_IMPORT __attribute__((visibility("default"))) +# define ENTT_HIDDEN __attribute__((visibility("hidden"))) +# else /* Unsupported compiler */ +# define ENTT_EXPORT +# define ENTT_IMPORT +# define ENTT_HIDDEN +# endif +#endif + +#ifndef ENTT_API +# if defined ENTT_API_EXPORT +# define ENTT_API ENTT_EXPORT +# elif defined ENTT_API_IMPORT +# define ENTT_API ENTT_IMPORT +# else /* No API */ +# define ENTT_API +# endif +#endif + +#if defined _MSC_VER +# pragma detect_mismatch("entt.version", ENTT_VERSION) +# pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY)) +# pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE)) +# pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD)) +#endif + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + +// #include "fwd.hpp" +#ifndef ENTT_CORE_FWD_HPP +#define ENTT_CORE_FWD_HPP + +#include +#include +// #include "../config/config.h" + + +namespace entt { + +/*! @brief Possible modes of an any object. */ +enum class any_policy : std::uint8_t { + /*! @brief Default mode, no element available. */ + empty, + /*! @brief Owning mode, dynamically allocated element. */ + dynamic, + /*! @brief Owning mode, embedded element. */ + embedded, + /*! @brief Aliasing mode, non-const reference. */ + ref, + /*! @brief Const aliasing mode, const reference. */ + cref +}; + +// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) +template +class basic_any; + +/*! @brief Alias declaration for type identifiers. */ +using id_type = ENTT_ID_TYPE; + +/*! @brief Alias declaration for the most common use case. */ +using any = basic_any<>; + +template +class compressed_pair; + +template +class basic_hashed_string; + +/*! @brief Aliases for common character types. */ +using hashed_string = basic_hashed_string; + +/*! @brief Aliases for common character types. */ +using hashed_wstring = basic_hashed_string; + +// NOLINTNEXTLINE(bugprone-forward-declaration-namespace) +struct type_info; + +} // namespace entt + +#endif + +// #include "type_info.hpp" +#ifndef ENTT_CORE_TYPE_INFO_HPP +#define ENTT_CORE_TYPE_INFO_HPP + +#include +#include +#include +// #include "../config/config.h" + +// #include "fwd.hpp" + +// #include "hashed_string.hpp" +#ifndef ENTT_CORE_HASHED_STRING_HPP +#define ENTT_CORE_HASHED_STRING_HPP + +#include +#include +// #include "fwd.hpp" + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct fnv_1a_params; + +template<> +struct fnv_1a_params { + static constexpr auto offset = 2166136261; + static constexpr auto prime = 16777619; +}; + +template<> +struct fnv_1a_params { + static constexpr auto offset = 14695981039346656037ull; + static constexpr auto prime = 1099511628211ull; +}; + +template +struct basic_hashed_string { + using value_type = Char; + using size_type = std::size_t; + using hash_type = id_type; + + const value_type *repr{}; + hash_type hash{fnv_1a_params<>::offset}; + size_type length{}; +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Zero overhead unique identifier. + * + * A hashed string is a compile-time tool that allows users to use + * human-readable identifiers in the codebase while using their numeric + * counterparts at runtime.
+ * Because of that, a hashed string can also be used in constant expressions if + * required. + * + * @warning + * This class doesn't take ownership of user-supplied strings nor does it make a + * copy of them. + * + * @tparam Char Character type. + */ +template +class basic_hashed_string: internal::basic_hashed_string { + using base_type = internal::basic_hashed_string; + using params = internal::fnv_1a_params<>; + + struct const_wrapper { + // non-explicit constructor on purpose + constexpr const_wrapper(const typename base_type::value_type *str) noexcept + : repr{str} {} + + const typename base_type::value_type *repr; + }; + +public: + /*! @brief Character type. */ + using value_type = typename base_type::value_type; + /*! @brief Unsigned integer type. */ + using size_type = typename base_type::size_type; + /*! @brief Unsigned integer type. */ + using hash_type = typename base_type::hash_type; + + /** + * @brief Returns directly the numeric representation of a string view. + * @param str Human-readable identifier. + * @param len Length of the string to hash. + * @return The numeric representation of the string. + */ + [[nodiscard]] static constexpr hash_type value(const value_type *str, const size_type len) noexcept { + return basic_hashed_string{str, len}; + } + + /** + * @brief Returns directly the numeric representation of a string. + * @tparam N Number of characters of the identifier. + * @param str Human-readable identifier. + * @return The numeric representation of the string. + */ + template + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) + [[nodiscard]] static ENTT_CONSTEVAL hash_type value(const value_type (&str)[N]) noexcept { + return basic_hashed_string{str}; + } + + /** + * @brief Returns directly the numeric representation of a string. + * @param wrapper Helps achieving the purpose by relying on overloading. + * @return The numeric representation of the string. + */ + [[nodiscard]] static constexpr hash_type value(const_wrapper wrapper) noexcept { + return basic_hashed_string{wrapper}; + } + + /*! @brief Constructs an empty hashed string. */ + constexpr basic_hashed_string() noexcept + : basic_hashed_string{nullptr, 0u} {} + + /** + * @brief Constructs a hashed string from a string view. + * @param str Human-readable identifier. + * @param len Length of the string to hash. + */ + constexpr basic_hashed_string(const value_type *str, const size_type len) noexcept + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay) + : base_type{str} { + // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic) + for(; base_type::length < len; ++base_type::length) { + base_type::hash = (base_type::hash ^ static_cast(str[base_type::length])) * params::prime; + } + // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic) + } + + /** + * @brief Constructs a hashed string from an array of const characters. + * @tparam N Number of characters of the identifier. + * @param str Human-readable identifier. + */ + template + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) + ENTT_CONSTEVAL basic_hashed_string(const value_type (&str)[N]) noexcept + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay) + : base_type{str} { + for(; str[base_type::length]; ++base_type::length) { + base_type::hash = (base_type::hash ^ static_cast(str[base_type::length])) * params::prime; + } + } + + /** + * @brief Explicit constructor on purpose to avoid constructing a hashed + * string directly from a `const value_type *`. + * + * @warning + * The lifetime of the string is not extended nor is it copied. + * + * @param wrapper Helps achieving the purpose by relying on overloading. + */ + explicit constexpr basic_hashed_string(const_wrapper wrapper) noexcept + : base_type{wrapper.repr} { + // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic) + for(; wrapper.repr[base_type::length]; ++base_type::length) { + base_type::hash = (base_type::hash ^ static_cast(wrapper.repr[base_type::length])) * params::prime; + } + // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic) + } + + /** + * @brief Returns the size of a hashed string. + * @return The size of the hashed string. + */ + [[nodiscard]] constexpr size_type size() const noexcept { + return base_type::length; + } + + /** + * @brief Returns the human-readable representation of a hashed string. + * @return The string used to initialize the hashed string. + */ + [[nodiscard]] constexpr const value_type *data() const noexcept { + return base_type::repr; + } + + /** + * @brief Returns the numeric representation of a hashed string. + * @return The numeric representation of the hashed string. + */ + [[nodiscard]] constexpr hash_type value() const noexcept { + return base_type::hash; + } + + /*! @copydoc data */ + [[nodiscard]] explicit constexpr operator const value_type *() const noexcept { + return data(); + } + + /** + * @brief Returns the numeric representation of a hashed string. + * @return The numeric representation of the hashed string. + */ + [[nodiscard]] constexpr operator hash_type() const noexcept { + return value(); + } +}; + +/** + * @brief Deduction guide. + * @tparam Char Character type. + * @param str Human-readable identifier. + * @param len Length of the string to hash. + */ +template +basic_hashed_string(const Char *str, std::size_t len) -> basic_hashed_string; + +/** + * @brief Deduction guide. + * @tparam Char Character type. + * @tparam N Number of characters of the identifier. + * @param str Human-readable identifier. + */ +template +// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) +basic_hashed_string(const Char (&str)[N]) -> basic_hashed_string; + +/** + * @brief Compares two hashed strings. + * @tparam Char Character type. + * @param lhs A valid hashed string. + * @param rhs A valid hashed string. + * @return True if the two hashed strings are identical, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator==(const basic_hashed_string &lhs, const basic_hashed_string &rhs) noexcept { + return lhs.value() == rhs.value(); +} + +/** + * @brief Compares two hashed strings. + * @tparam Char Character type. + * @param lhs A valid hashed string. + * @param rhs A valid hashed string. + * @return True if the two hashed strings differ, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator!=(const basic_hashed_string &lhs, const basic_hashed_string &rhs) noexcept { + return !(lhs == rhs); +} + +/** + * @brief Compares two hashed strings. + * @tparam Char Character type. + * @param lhs A valid hashed string. + * @param rhs A valid hashed string. + * @return True if the first element is less than the second, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator<(const basic_hashed_string &lhs, const basic_hashed_string &rhs) noexcept { + return lhs.value() < rhs.value(); +} + +/** + * @brief Compares two hashed strings. + * @tparam Char Character type. + * @param lhs A valid hashed string. + * @param rhs A valid hashed string. + * @return True if the first element is less than or equal to the second, false + * otherwise. + */ +template +[[nodiscard]] constexpr bool operator<=(const basic_hashed_string &lhs, const basic_hashed_string &rhs) noexcept { + return !(rhs < lhs); +} + +/** + * @brief Compares two hashed strings. + * @tparam Char Character type. + * @param lhs A valid hashed string. + * @param rhs A valid hashed string. + * @return True if the first element is greater than the second, false + * otherwise. + */ +template +[[nodiscard]] constexpr bool operator>(const basic_hashed_string &lhs, const basic_hashed_string &rhs) noexcept { + return rhs < lhs; +} + +/** + * @brief Compares two hashed strings. + * @tparam Char Character type. + * @param lhs A valid hashed string. + * @param rhs A valid hashed string. + * @return True if the first element is greater than or equal to the second, + * false otherwise. + */ +template +[[nodiscard]] constexpr bool operator>=(const basic_hashed_string &lhs, const basic_hashed_string &rhs) noexcept { + return !(lhs < rhs); +} + +inline namespace literals { + +/** + * @brief User defined literal for hashed strings. + * @param str The literal without its suffix. + * @return A properly initialized hashed string. + */ +[[nodiscard]] ENTT_CONSTEVAL hashed_string operator""_hs(const char *str, std::size_t) noexcept { + return hashed_string{str}; +} + +/** + * @brief User defined literal for hashed wstrings. + * @param str The literal without its suffix. + * @return A properly initialized hashed wstring. + */ +[[nodiscard]] ENTT_CONSTEVAL hashed_wstring operator""_hws(const wchar_t *str, std::size_t) noexcept { + return hashed_wstring{str}; +} + +} // namespace literals + +} // namespace entt + +#endif + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +struct ENTT_API type_index final { + [[nodiscard]] static id_type next() noexcept { + static ENTT_MAYBE_ATOMIC(id_type) value{}; + return value++; + } +}; + +template +[[nodiscard]] constexpr const char *pretty_function() noexcept { +#if defined ENTT_PRETTY_FUNCTION + return static_cast(ENTT_PRETTY_FUNCTION); +#else + return ""; +#endif +} + +template +[[nodiscard]] constexpr auto stripped_type_name() noexcept { +#if defined ENTT_PRETTY_FUNCTION + const std::string_view full_name{pretty_function()}; + auto first = full_name.find_first_not_of(' ', full_name.find_first_of(ENTT_PRETTY_FUNCTION_PREFIX) + 1); + auto value = full_name.substr(first, full_name.find_last_of(ENTT_PRETTY_FUNCTION_SUFFIX) - first); + return value; +#else + return std::string_view{}; +#endif +} + +template().find_first_of('.')> +[[nodiscard]] constexpr std::string_view type_name(int) noexcept { + constexpr auto value = stripped_type_name(); + return value; +} + +template +[[nodiscard]] std::string_view type_name(char) noexcept { + static const auto value = stripped_type_name(); + return value; +} + +template().find_first_of('.')> +[[nodiscard]] constexpr id_type type_hash(int) noexcept { + constexpr auto stripped = stripped_type_name(); + constexpr auto value = hashed_string::value(stripped.data(), stripped.size()); + return value; +} + +template +[[nodiscard]] id_type type_hash(char) noexcept { + static const auto value = [](const auto stripped) { + return hashed_string::value(stripped.data(), stripped.size()); + }(stripped_type_name()); + return value; +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Type sequential identifier. + * @tparam Type Type for which to generate a sequential identifier. + */ +template +struct ENTT_API type_index final { + /** + * @brief Returns the sequential identifier of a given type. + * @return The sequential identifier of a given type. + */ + [[nodiscard]] static id_type value() noexcept { + static const id_type value = internal::type_index::next(); + return value; + } + + /*! @copydoc value */ + [[nodiscard]] constexpr operator id_type() const noexcept { + return value(); + } +}; + +/** + * @brief Type hash. + * @tparam Type Type for which to generate a hash value. + */ +template +struct type_hash final { + /** + * @brief Returns the numeric representation of a given type. + * @return The numeric representation of the given type. + */ +#if defined ENTT_PRETTY_FUNCTION + [[nodiscard]] static constexpr id_type value() noexcept { + return internal::type_hash(0); +#else + [[nodiscard]] static constexpr id_type value() noexcept { + return type_index::value(); +#endif + } + + /*! @copydoc value */ + [[nodiscard]] constexpr operator id_type() const noexcept { + return value(); + } +}; + +/** + * @brief Type name. + * @tparam Type Type for which to generate a name. + */ +template +struct type_name final { + /** + * @brief Returns the name of a given type. + * @return The name of the given type. + */ + [[nodiscard]] static constexpr std::string_view value() noexcept { + return internal::type_name(0); + } + + /*! @copydoc value */ + [[nodiscard]] constexpr operator std::string_view() const noexcept { + return value(); + } +}; + +/*! @brief Implementation specific information about a type. */ +struct type_info final { + /** + * @brief Constructs a type info object for a given type. + * @tparam Type Type for which to construct a type info object. + */ + template + // NOLINTBEGIN(modernize-use-transparent-functors) + constexpr type_info(std::in_place_type_t) noexcept + : seq{type_index>>::value()}, + identifier{type_hash>>::value()}, + alias{type_name>>::value()} {} + // NOLINTEND(modernize-use-transparent-functors) + + /** + * @brief Type index. + * @return Type index. + */ + [[nodiscard]] constexpr id_type index() const noexcept { + return seq; + } + + /** + * @brief Type hash. + * @return Type hash. + */ + [[nodiscard]] constexpr id_type hash() const noexcept { + return identifier; + } + + /** + * @brief Type name. + * @return Type name. + */ + [[nodiscard]] constexpr std::string_view name() const noexcept { + return alias; + } + +private: + id_type seq; + id_type identifier; + std::string_view alias; +}; + +/** + * @brief Compares the contents of two type info objects. + * @param lhs A type info object. + * @param rhs A type info object. + * @return True if the two type info objects are identical, false otherwise. + */ +[[nodiscard]] constexpr bool operator==(const type_info &lhs, const type_info &rhs) noexcept { + return lhs.hash() == rhs.hash(); +} + +/** + * @brief Compares the contents of two type info objects. + * @param lhs A type info object. + * @param rhs A type info object. + * @return True if the two type info objects differ, false otherwise. + */ +[[nodiscard]] constexpr bool operator!=(const type_info &lhs, const type_info &rhs) noexcept { + return !(lhs == rhs); +} + +/** + * @brief Compares two type info objects. + * @param lhs A valid type info object. + * @param rhs A valid type info object. + * @return True if the first element is less than the second, false otherwise. + */ +[[nodiscard]] constexpr bool operator<(const type_info &lhs, const type_info &rhs) noexcept { + return lhs.index() < rhs.index(); +} + +/** + * @brief Compares two type info objects. + * @param lhs A valid type info object. + * @param rhs A valid type info object. + * @return True if the first element is less than or equal to the second, false + * otherwise. + */ +[[nodiscard]] constexpr bool operator<=(const type_info &lhs, const type_info &rhs) noexcept { + return !(rhs < lhs); +} + +/** + * @brief Compares two type info objects. + * @param lhs A valid type info object. + * @param rhs A valid type info object. + * @return True if the first element is greater than the second, false + * otherwise. + */ +[[nodiscard]] constexpr bool operator>(const type_info &lhs, const type_info &rhs) noexcept { + return rhs < lhs; +} + +/** + * @brief Compares two type info objects. + * @param lhs A valid type info object. + * @param rhs A valid type info object. + * @return True if the first element is greater than or equal to the second, + * false otherwise. + */ +[[nodiscard]] constexpr bool operator>=(const type_info &lhs, const type_info &rhs) noexcept { + return !(lhs < rhs); +} + +/** + * @brief Returns the type info object associated to a given type. + * + * The returned element refers to an object with static storage duration.
+ * The type doesn't need to be a complete type. If the type is a reference, the + * result refers to the referenced type. In all cases, top-level cv-qualifiers + * are ignored. + * + * @tparam Type Type for which to generate a type info object. + * @return A reference to a properly initialized type info object. + */ +template +[[nodiscard]] const type_info &type_id() noexcept { + if constexpr(std::is_same_v>>) { + static const type_info instance{std::in_place_type}; + return instance; + } else { + return type_id>>(); + } +} + +/*! @copydoc type_id */ +template +// NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward) +[[nodiscard]] const type_info &type_id(Type &&) noexcept { + return type_id>>(); +} + +} // namespace entt + +#endif + +// #include "type_traits.hpp" +#ifndef ENTT_CORE_TYPE_TRAITS_HPP +#define ENTT_CORE_TYPE_TRAITS_HPP + +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "fwd.hpp" + + +namespace entt { + +/** + * @brief Utility class to disambiguate overloaded functions. + * @tparam N Number of choices available. + */ +template +struct choice_t + // unfortunately, doxygen cannot parse such a construct + : /*! @cond TURN_OFF_DOXYGEN */ choice_t /*! @endcond */ +{}; + +/*! @copybrief choice_t */ +template<> +struct choice_t<0> {}; + +/** + * @brief Variable template for the choice trick. + * @tparam N Number of choices available. + */ +template +inline constexpr choice_t choice{}; + +/** + * @brief Identity type trait. + * + * Useful to establish non-deduced contexts in template argument deduction + * (waiting for C++20) or to provide types through function arguments. + * + * @tparam Type A type. + */ +template +struct type_identity { + /*! @brief Identity type. */ + using type = Type; +}; + +/** + * @brief Helper type. + * @tparam Type A type. + */ +template +using type_identity_t = typename type_identity::type; + +/** + * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains. + * @tparam Type The type of which to return the size. + */ +template +struct size_of: std::integral_constant {}; + +/*! @copydoc size_of */ +template +struct size_of> + // NOLINTNEXTLINE(bugprone-sizeof-expression) + : std::integral_constant {}; + +/** + * @brief Helper variable template. + * @tparam Type The type of which to return the size. + */ +template +inline constexpr std::size_t size_of_v = size_of::value; + +/** + * @brief Using declaration to be used to _repeat_ the same type a number of + * times equal to the size of a given parameter pack. + * @tparam Type A type to repeat. + */ +template +using unpack_as_type = Type; + +/** + * @brief Helper variable template to be used to _repeat_ the same value a + * number of times equal to the size of a given parameter pack. + * @tparam Value A value to repeat. + */ +template +inline constexpr auto unpack_as_value = Value; + +/** + * @brief Wraps a static constant. + * @tparam Value A static constant. + */ +template +using integral_constant = std::integral_constant; + +/** + * @brief Alias template to facilitate the creation of named values. + * @tparam Value A constant value at least convertible to `id_type`. + */ +template +using tag = integral_constant; + +/** + * @brief A class to use to push around lists of types, nothing more. + * @tparam Type Types provided by the type list. + */ +template +struct type_list { + /*! @brief Type list type. */ + using type = type_list; + /*! @brief Compile-time number of elements in the type list. */ + static constexpr auto size = sizeof...(Type); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_element; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Index Index of the type to return. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element> + : type_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element<0u, type_list> { + /*! @brief Searched type. */ + using type = First; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Type list to search into. + */ +template +using type_list_element_t = typename type_list_element::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_index; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 1u + type_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + static_assert(type_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +inline constexpr std::size_t type_list_index_v = type_list_index::value; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @return A type list composed by the types of both the type lists. + */ +template +constexpr type_list operator+(type_list, type_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_cat; + +/*! @brief Concatenates multiple type lists. */ +template<> +struct type_list_cat<> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list<>; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @tparam List Other type lists, if any. + */ +template +struct type_list_cat, type_list, List...> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = typename type_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the type list. + */ +template +struct type_list_cat> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list; +}; + +/** + * @brief Helper type. + * @tparam List Type lists to concatenate. + */ +template +using type_list_cat_t = typename type_list_cat::type; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct type_list_unique; + +template +struct type_list_unique, Type...> + : std::conditional_t<(std::is_same_v || ...), type_list_unique, Type...>, type_list_unique, Type..., First>> {}; + +template +struct type_list_unique, Type...> { + using type = type_list; +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Removes duplicates types from a type list. + * @tparam List Type list. + */ +template +struct type_list_unique { + /*! @brief A type list without duplicate types. */ + using type = typename internal::type_list_unique::type; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + */ +template +using type_list_unique_t = typename type_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a type list contains a + * given type, false otherwise. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +struct type_list_contains; + +/** + * @copybrief type_list_contains + * @tparam Type Types provided by the type list. + * @tparam Other Type to look for. + */ +template +struct type_list_contains, Other> + : std::bool_constant<(std::is_same_v || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +inline constexpr bool type_list_contains_v = type_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_diff; + +/** + * @brief Computes the difference between two type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + */ +template +struct type_list_diff, type_list> { + /*! @brief A type list that is the difference between the two type lists. */ + using type = type_list_cat_t, Type>, type_list<>, type_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Type lists between which to compute the difference. + */ +template +using type_list_diff_t = typename type_list_diff::type; + +/*! @brief Primary template isn't defined on purpose. */ +template class> +struct type_list_transform; + +/** + * @brief Applies a given _function_ to a type list and generate a new list. + * @tparam Type Types provided by the type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +struct type_list_transform, Op> { + /*! @brief Resulting type list after applying the transform function. */ + // NOLINTNEXTLINE(modernize-type-traits) + using type = type_list::type...>; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +using type_list_transform_t = typename type_list_transform::type; + +/** + * @brief A class to use to push around lists of constant values, nothing more. + * @tparam Value Values provided by the value list. + */ +template +struct value_list { + /*! @brief Value list type. */ + using type = value_list; + /*! @brief Compile-time number of elements in the value list. */ + static constexpr auto size = sizeof...(Value); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_element; + +/** + * @brief Provides compile-time indexed access to the values of a value list. + * @tparam Index Index of the value to return. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element> + : value_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element<0u, value_list> { + /*! @brief Searched type. */ + using type = decltype(Value); + /*! @brief Searched value. */ + static constexpr auto value = Value; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Value list to search into. + */ +template +using value_list_element_t = typename value_list_element::type; + +/** + * @brief Helper type. + * @tparam Index Index of the value to return. + * @tparam List Value list to search into. + */ +template +inline constexpr auto value_list_element_v = value_list_element::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_index; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam First First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 1u + value_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + static_assert(value_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +inline constexpr std::size_t value_list_index_v = value_list_index::value; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @return A value list composed by the values of both the value lists. + */ +template +constexpr value_list operator+(value_list, value_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_cat; + +/*! @brief Concatenates multiple value lists. */ +template<> +struct value_list_cat<> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list<>; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @tparam List Other value lists, if any. + */ +template +struct value_list_cat, value_list, List...> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = typename value_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the value list. + */ +template +struct value_list_cat> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list; +}; + +/** + * @brief Helper type. + * @tparam List Value lists to concatenate. + */ +template +using value_list_cat_t = typename value_list_cat::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_unique; + +/** + * @brief Removes duplicates values from a value list. + * @tparam Value One of the values provided by the given value list. + * @tparam Other The other values provided by the given value list. + */ +template +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = std::conditional_t< + ((Value == Other) || ...), + typename value_list_unique>::type, + value_list_cat_t, typename value_list_unique>::type>>; +}; + +/*! @brief Removes duplicates values from a value list. */ +template<> +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = value_list<>; +}; + +/** + * @brief Helper type. + * @tparam Type A value list. + */ +template +using value_list_unique_t = typename value_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a value list contains + * a given value, false otherwise. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +struct value_list_contains; + +/** + * @copybrief value_list_contains + * @tparam Value Values provided by the value list. + * @tparam Other Value to look for. + */ +template +struct value_list_contains, Other> + : std::bool_constant<((Value == Other) || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +inline constexpr bool value_list_contains_v = value_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_diff; + +/** + * @brief Computes the difference between two value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + */ +template +struct value_list_diff, value_list> { + /*! @brief A value list that is the difference between the two value lists. */ + using type = value_list_cat_t, Value>, value_list<>, value_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Value lists between which to compute the difference. + */ +template +using value_list_diff_t = typename value_list_diff::type; + +/*! @brief Same as std::is_invocable, but with tuples. */ +template +struct is_applicable: std::false_type {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @brief Helper variable template. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_v = is_applicable::value; + +/*! @brief Same as std::is_invocable_r, but with tuples for arguments. */ +template +struct is_applicable_r: std::false_type {}; + +/** + * @copybrief is_applicable_r + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +struct is_applicable_r>: std::is_invocable_r {}; + +/** + * @brief Helper variable template. + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_r_v = is_applicable_r::value; + +/** + * @brief Provides the member constant `value` to true if a given type is + * complete, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_complete: std::false_type {}; + +/*! @copydoc is_complete */ +template +struct is_complete>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_complete_v = is_complete::value; + +/** + * @brief Provides the member constant `value` to true if a given type is an + * iterator, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_iterator: std::false_type {}; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_iterator_category: std::false_type {}; + +template +struct has_iterator_category::iterator_category>>: std::true_type {}; + +} // namespace internal +/*! @endcond */ + +/*! @copydoc is_iterator */ +template +struct is_iterator>>>> + : internal::has_iterator_category {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_iterator_v = is_iterator::value; + +/** + * @brief Provides the member constant `value` to true if a given type is both + * an empty and non-final class, false otherwise. + * @tparam Type The type to test + */ +template +struct is_ebco_eligible + : std::bool_constant && !std::is_final_v> {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_ebco_eligible_v = is_ebco_eligible::value; + +/** + * @brief Provides the member constant `value` to true if `Type::is_transparent` + * is valid and denotes a type, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_transparent: std::false_type {}; + +/*! @copydoc is_transparent */ +template +struct is_transparent>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_transparent_v = is_transparent::value; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_tuple_size_value: std::false_type {}; + +template +struct has_tuple_size_value::value)>>: std::true_type {}; + +template +struct has_value_type: std::false_type {}; + +template +struct has_value_type>: std::true_type {}; + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable(); + +template +[[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence) { + return (dispatch_is_equality_comparable>() && ...); +} + +template +[[nodiscard]] constexpr bool maybe_equality_comparable(char) { + return false; +} + +template +[[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval() == std::declval()) { + return true; +} + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable() { + // NOLINTBEGIN(modernize-use-transparent-functors) + if constexpr(std::is_array_v) { + return false; + } else if constexpr(is_complete_v>>) { + if constexpr(has_tuple_size_value::value) { + return maybe_equality_comparable(0) && unpack_maybe_equality_comparable(std::make_index_sequence::value>{}); + } else { + return maybe_equality_comparable(0); + } + } else if constexpr(has_value_type::value) { + if constexpr(is_iterator_v || std::is_same_v || dispatch_is_equality_comparable()) { + return maybe_equality_comparable(0); + } else { + return false; + } + } else { + return maybe_equality_comparable(0); + } + // NOLINTEND(modernize-use-transparent-functors) +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Provides the member constant `value` to true if a given type is + * equality comparable, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_equality_comparable: std::bool_constant()> {}; + +/*! @copydoc is_equality_comparable */ +template +struct is_equality_comparable: is_equality_comparable {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_equality_comparable_v = is_equality_comparable::value; + +/** + * @brief Transcribes the constness of a type to another type. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = std::remove_const_t; +}; + +/*! @copydoc constness_as */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = const To; +}; + +/** + * @brief Alias template to facilitate the transcription of the constness. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +using constness_as_t = typename constness_as::type; + +/** + * @brief Extracts the class of a non-static member object or function. + * @tparam Member A pointer to a non-static member object or function. + */ +template +class member_class { + static_assert(std::is_member_pointer_v, "Invalid pointer type to non-static member object or function"); + + template + static Class *clazz(Ret (Class::*)(Args...)); + + template + static Class *clazz(Ret (Class::*)(Args...) const); + + template + static Class *clazz(Type Class::*); + +public: + /*! @brief The class of the given non-static member object or function. */ + using type = std::remove_pointer_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Member A pointer to a non-static member object or function. + */ +template +using member_class_t = typename member_class::type; + +/** + * @brief Extracts the n-th argument of a _callable_ type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid _callable_ type. + */ +template +class nth_argument { + template + static constexpr type_list pick_up(Ret (*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...) const); + + template + static constexpr type_list pick_up(Type Class ::*); + + template + static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&); + +public: + /*! @brief N-th argument of the _callable_ type. */ + using type = type_list_element_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid function, member function or data member type. + */ +template +using nth_argument_t = typename nth_argument::type; + +} // namespace entt + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::type_list_element> {}; + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::value_list_element> {}; + +#endif + +// #include "utility.hpp" +#ifndef ENTT_CORE_UTILITY_HPP +#define ENTT_CORE_UTILITY_HPP + +#include +#include + +namespace entt { + +/*! @brief Identity function object (waiting for C++20). */ +struct identity { + /*! @brief Indicates that this is a transparent function object. */ + using is_transparent = void; + + /** + * @brief Returns its argument unchanged. + * @tparam Type Type of the argument. + * @param value The actual argument. + * @return The submitted value as-is. + */ + template + [[nodiscard]] constexpr Type &&operator()(Type &&value) const noexcept { + return std::forward(value); + } +}; + +/** + * @brief Constant utility to disambiguate overloaded members of a class. + * @tparam Type Type of the desired overload. + * @tparam Class Type of class to which the member belongs. + * @param member A valid pointer to a member. + * @return Pointer to the member. + */ +template +[[nodiscard]] constexpr auto overload(Type Class::*member) noexcept { + return member; +} + +/** + * @brief Constant utility to disambiguate overloaded functions. + * @tparam Func Function type of the desired overload. + * @param func A valid pointer to a function. + * @return Pointer to the function. + */ +template +[[nodiscard]] constexpr auto overload(Func *func) noexcept { + return func; +} + +/** + * @brief Helper type for visitors. + * @tparam Func Types of function objects. + */ +template +struct overloaded: Func... { + using Func::operator()...; +}; + +/** + * @brief Deduction guide. + * @tparam Func Types of function objects. + */ +template +overloaded(Func...) -> overloaded; + +/** + * @brief Basic implementation of a y-combinator. + * @tparam Func Type of a potentially recursive function. + */ +template +struct y_combinator { + /** + * @brief Constructs a y-combinator from a given function. + * @param recursive A potentially recursive function. + */ + constexpr y_combinator(Func recursive) noexcept(std::is_nothrow_move_constructible_v) + : func{std::move(recursive)} {} + + /** + * @brief Invokes a y-combinator and therefore its underlying function. + * @tparam Args Types of arguments to use to invoke the underlying function. + * @param args Parameters to use to invoke the underlying function. + * @return Return value of the underlying function, if any. + */ + template + constexpr decltype(auto) operator()(Args &&...args) const noexcept(std::is_nothrow_invocable_v) { + return func(*this, std::forward(args)...); + } + + /*! @copydoc operator()() */ + template + constexpr decltype(auto) operator()(Args &&...args) noexcept(std::is_nothrow_invocable_v) { + return func(*this, std::forward(args)...); + } + +private: + Func func; +}; + +} // namespace entt + +#endif + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +enum class any_request : std::uint8_t { + info, + transfer, + assign, + compare, + copy, + move +}; + +template +struct basic_any_storage { + static constexpr bool has_buffer = true; + union { + const void *instance{}; + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) + alignas(Align) std::byte buffer[Len]; + }; +}; + +template +struct basic_any_storage<0u, Align> { + static constexpr bool has_buffer = false; + const void *instance{}; +}; + +template +// NOLINTNEXTLINE(bugprone-sizeof-expression) +struct in_situ: std::bool_constant<(Len != 0u) && alignof(Type) <= Align && sizeof(Type) <= Len && std::is_nothrow_move_constructible_v> {}; + +template +struct in_situ: std::false_type {}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief A SBO friendly, type-safe container for single values of any type. + * @tparam Len Size of the buffer reserved for the small buffer optimization. + * @tparam Align Optional alignment requirement. + */ +template +class basic_any: private internal::basic_any_storage { + using request = internal::any_request; + using base_type = internal::basic_any_storage; + using vtable_type = const void *(const request, const basic_any &, const void *); + using deleter_type = void(const basic_any &); + + template + static constexpr bool in_situ_v = internal::in_situ::value; + + template + static const void *basic_vtable(const request req, const basic_any &value, const void *other) { + static_assert(std::is_same_v>, Type>, "Invalid type"); + + switch(const auto *elem = static_cast(value.data()); req) { + case request::info: + return &type_id(); + case request::transfer: + if constexpr(std::is_move_assignable_v) { + // NOLINTNEXTLINE(bugprone-casting-through-void) + *const_cast(elem) = std::move(*static_cast(const_cast(other))); + return other; + } + [[fallthrough]]; + case request::assign: + if constexpr(std::is_copy_assignable_v) { + *const_cast(elem) = *static_cast(other); + return other; + } + break; + case request::compare: + if constexpr(!std::is_function_v && !std::is_array_v && is_equality_comparable_v) { + return (*elem == *static_cast(other)) ? other : nullptr; + } else { + return (elem == other) ? other : nullptr; + } + case request::copy: + if constexpr(std::is_copy_constructible_v) { + // NOLINTNEXTLINE(bugprone-casting-through-void) + static_cast(const_cast(other))->initialize(*elem); + } + break; + case request::move: + ENTT_ASSERT(value.mode == any_policy::embedded, "Unexpected policy"); + if constexpr(in_situ_v) { + // NOLINTNEXTLINE(bugprone-casting-through-void, bugprone-multi-level-implicit-pointer-conversion) + return ::new(&static_cast(const_cast(other))->buffer) Type{std::move(*const_cast(elem))}; + } + } + + return nullptr; + } + + template + static void basic_deleter(const basic_any &value) { + static_assert(std::is_same_v>, Type>, "Invalid type"); + ENTT_ASSERT((value.mode == any_policy::dynamic) || ((value.mode == any_policy::embedded) && !std::is_trivially_destructible_v), "Unexpected policy"); + + const auto *elem = static_cast(value.data()); + + if constexpr(in_situ_v) { + (value.mode == any_policy::embedded) ? elem->~Type() : (delete elem); + } else if constexpr(std::is_array_v) { + delete[] elem; + } else { + delete elem; + } + } + + template + void initialize([[maybe_unused]] Args &&...args) { + using plain_type = std::remove_const_t>; + + vtable = basic_vtable; + underlying_type = type_hash::value(); + + if constexpr(std::is_void_v) { + deleter = nullptr; + mode = any_policy::empty; + this->instance = nullptr; + } else if constexpr(std::is_lvalue_reference_v) { + deleter = nullptr; + mode = std::is_const_v> ? any_policy::cref : any_policy::ref; + static_assert((std::is_lvalue_reference_v && ...) && (sizeof...(Args) == 1u), "Invalid arguments"); + // NOLINTNEXTLINE(bugprone-multi-level-implicit-pointer-conversion) + this->instance = (std::addressof(args), ...); + } else if constexpr(in_situ_v) { + if constexpr(std::is_trivially_destructible_v) { + deleter = nullptr; + } else { + deleter = &basic_deleter; + } + + mode = any_policy::embedded; + + if constexpr(std::is_aggregate_v && (sizeof...(Args) != 0u || !std::is_default_constructible_v)) { + ::new(&this->buffer) plain_type{std::forward(args)...}; + } else { + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay) + ::new(&this->buffer) plain_type(std::forward(args)...); + } + } else { + deleter = &basic_deleter; + mode = any_policy::dynamic; + + if constexpr(std::is_aggregate_v && (sizeof...(Args) != 0u || !std::is_default_constructible_v)) { + this->instance = new plain_type{std::forward(args)...}; + } else if constexpr(std::is_array_v) { + static_assert(sizeof...(Args) == 0u, "Invalid arguments"); + this->instance = new plain_type[std::extent_v](); + } else { + this->instance = new plain_type(std::forward(args)...); + } + } + } + + void invoke_deleter_if_exists() { + if(deleter != nullptr) { + deleter(*this); + } + } + +public: + /*! @brief Size of the internal buffer. */ + static constexpr auto length = Len; + /*! @brief Alignment requirement. */ + static constexpr auto alignment = Align; + + /*! @brief Default constructor. */ + constexpr basic_any() noexcept + : basic_any{std::in_place_type} {} + + /** + * @brief Constructs a wrapper by directly initializing the new object. + * @tparam Type Type of object to use to initialize the wrapper. + * @tparam Args Types of arguments to use to construct the new instance. + * @param args Parameters to use to construct the instance. + */ + template + explicit basic_any(std::in_place_type_t, Args &&...args) + : base_type{} { + initialize(std::forward(args)...); + } + + /** + * @brief Constructs a wrapper taking ownership of the passed object. + * @tparam Type Type of object to use to initialize the wrapper. + * @param value A pointer to an object to take ownership of. + */ + template + explicit basic_any(std::in_place_t, Type *value) + : base_type{} { + static_assert(!std::is_const_v && !std::is_void_v, "Non-const non-void pointer required"); + + if(value == nullptr) { + initialize(); + } else { + initialize(*value); + deleter = &basic_deleter; + mode = any_policy::dynamic; + } + } + + /** + * @brief Constructs a wrapper from a given value. + * @tparam Type Type of object to use to initialize the wrapper. + * @param value An instance of an object to use to initialize the wrapper. + */ + template, basic_any>>> + basic_any(Type &&value) + : basic_any{std::in_place_type>, std::forward(value)} {} + + /** + * @brief Copy constructor. + * @param other The instance to copy from. + */ + basic_any(const basic_any &other) + : basic_any{} { + other.vtable(request::copy, other, this); + } + + /** + * @brief Move constructor. + * @param other The instance to move from. + */ + basic_any(basic_any &&other) noexcept + : base_type{}, + vtable{other.vtable}, + deleter{other.deleter}, + underlying_type{other.underlying_type}, + mode{other.mode} { + if(other.mode == any_policy::embedded) { + other.vtable(request::move, other, this); + } else if(other.mode != any_policy::empty) { + this->instance = std::exchange(other.instance, nullptr); + } + } + + /*! @brief Frees the internal buffer, whatever it means. */ + ~basic_any() { + invoke_deleter_if_exists(); + } + + /** + * @brief Copy assignment operator. + * @param other The instance to copy from. + * @return This any object. + */ + basic_any &operator=(const basic_any &other) { + if(this != &other) { + invoke_deleter_if_exists(); + + if(other) { + other.vtable(request::copy, other, this); + } else { + initialize(); + } + } + + return *this; + } + + /** + * @brief Move assignment operator. + * @param other The instance to move from. + * @return This any object. + */ + basic_any &operator=(basic_any &&other) noexcept { + if(this != &other) { + invoke_deleter_if_exists(); + + if(other.mode == any_policy::embedded) { + other.vtable(request::move, other, this); + } else if(other.mode != any_policy::empty) { + this->instance = std::exchange(other.instance, nullptr); + } + + vtable = other.vtable; + deleter = other.deleter; + underlying_type = other.underlying_type; + mode = other.mode; + } + + return *this; + } + + /** + * @brief Value assignment operator. + * @tparam Type Type of object to use to initialize the wrapper. + * @param value An instance of an object to use to initialize the wrapper. + * @return This any object. + */ + template, basic_any>>> + basic_any &operator=(Type &&value) { + emplace>(std::forward(value)); + return *this; + } + + /** + * @brief Returns false if a wrapper is empty, true otherwise. + * @return False if the wrapper is empty, true otherwise. + */ + [[nodiscard]] bool has_value() const noexcept { + return (mode != any_policy::empty); + } + + /** + * @brief Returns false if the wrapper does not contain the expected type, + * true otherwise. + * @param req Expected type. + * @return False if the wrapper does not contain the expected type, true + * otherwise. + */ + [[nodiscard]] bool has_value(const type_info &req) const noexcept { + return (underlying_type == req.hash()); + } + + /** + * @brief Returns false if the wrapper does not contain the expected type, + * true otherwise. + * @tparam Type Expected type. + * @return False if the wrapper does not contain the expected type, true + * otherwise. + */ + template + [[nodiscard]] bool has_value() const noexcept { + static_assert(std::is_same_v, Type>, "Invalid type"); + return (underlying_type == type_hash::value()); + } + + /** + * @brief Returns the object type info if any, `type_id()` otherwise. + * @return The object type info if any, `type_id()` otherwise. + */ + [[nodiscard]] const type_info &info() const noexcept { + return *static_cast(vtable(request::info, *this, nullptr)); + } + + /*! @copydoc info */ + [[deprecated("use ::info instead")]] [[nodiscard]] const type_info &type() const noexcept { + return info(); + } + + /** + * @brief Returns an opaque pointer to the contained instance. + * @return An opaque pointer the contained instance, if any. + */ + [[nodiscard]] const void *data() const noexcept { + if constexpr(base_type::has_buffer) { + return (mode == any_policy::embedded) ? &this->buffer : this->instance; + } else { + return this->instance; + } + } + + /** + * @brief Returns an opaque pointer to the contained instance. + * @param req Expected type. + * @return An opaque pointer the contained instance, if any. + */ + [[nodiscard]] const void *data(const type_info &req) const noexcept { + return has_value(req) ? data() : nullptr; + } + + /** + * @brief Returns an opaque pointer to the contained instance. + * @tparam Type Expected type. + * @return An opaque pointer the contained instance, if any. + */ + template + [[nodiscard]] const Type *data() const noexcept { + return has_value>() ? static_cast(data()) : nullptr; + } + + /** + * @brief Returns an opaque pointer to the contained instance. + * @return An opaque pointer the contained instance, if any. + */ + [[nodiscard]] void *data() noexcept { + return (mode == any_policy::cref) ? nullptr : const_cast(std::as_const(*this).data()); + } + + /** + * @brief Returns an opaque pointer to the contained instance. + * @param req Expected type. + * @return An opaque pointer the contained instance, if any. + */ + [[nodiscard]] void *data(const type_info &req) noexcept { + return (mode == any_policy::cref) ? nullptr : const_cast(std::as_const(*this).data(req)); + } + + /** + * @brief Returns an opaque pointer to the contained instance. + * @tparam Type Expected type. + * @return An opaque pointer the contained instance, if any. + */ + template + [[nodiscard]] Type *data() noexcept { + if constexpr(std::is_const_v) { + return std::as_const(*this).template data>(); + } else { + return (mode == any_policy::cref) ? nullptr : const_cast(std::as_const(*this).template data>()); + } + } + + /** + * @brief Replaces the contained object by creating a new instance directly. + * @tparam Type Type of object to use to initialize the wrapper. + * @tparam Args Types of arguments to use to construct the new instance. + * @param args Parameters to use to construct the instance. + */ + template + void emplace(Args &&...args) { + invoke_deleter_if_exists(); + initialize(std::forward(args)...); + } + + /** + * @brief Assigns a value to the contained object without replacing it. + * @param other The value to assign to the contained object. + * @return True in case of success, false otherwise. + */ + bool assign(const basic_any &other) { + if(other && (mode != any_policy::cref) && (underlying_type == other.underlying_type)) { + return (vtable(request::assign, *this, other.data()) != nullptr); + } + + return false; + } + + /*! @copydoc assign */ + // NOLINTNEXTLINE(cppcoreguidelines-rvalue-reference-param-not-moved) + bool assign(basic_any &&other) { + if(other && (mode != any_policy::cref) && (underlying_type == other.underlying_type)) { + return (other.mode == any_policy::cref) ? (vtable(request::assign, *this, std::as_const(other).data()) != nullptr) : (vtable(request::transfer, *this, other.data()) != nullptr); + } + + return false; + } + + /*! @brief Destroys contained object */ + void reset() { + invoke_deleter_if_exists(); + initialize(); + } + + /** + * @brief Returns false if a wrapper is empty, true otherwise. + * @return False if the wrapper is empty, true otherwise. + */ + [[nodiscard]] explicit operator bool() const noexcept { + return has_value(); + } + + /** + * @brief Checks if two wrappers differ in their content. + * @param other Wrapper with which to compare. + * @return False if the two objects differ in their content, true otherwise. + */ + [[nodiscard]] bool operator==(const basic_any &other) const noexcept { + if(other && (underlying_type == other.underlying_type)) { + return (vtable(request::compare, *this, other.data()) != nullptr); + } + + return (!*this && !other); + } + + /** + * @brief Checks if two wrappers differ in their content. + * @param other Wrapper with which to compare. + * @return True if the two objects differ in their content, false otherwise. + */ + [[nodiscard]] bool operator!=(const basic_any &other) const noexcept { + return !(*this == other); + } + + /** + * @brief Aliasing constructor. + * @return A wrapper that shares a reference to an unmanaged object. + */ + [[nodiscard]] basic_any as_ref() noexcept { + basic_any other = std::as_const(*this).as_ref(); + other.mode = (mode == any_policy::cref ? any_policy::cref : any_policy::ref); + return other; + } + + /*! @copydoc as_ref */ + [[nodiscard]] basic_any as_ref() const noexcept { + basic_any other{}; + other.instance = data(); + other.vtable = vtable; + other.underlying_type = underlying_type; + other.mode = any_policy::cref; + return other; + } + + /** + * @brief Returns true if a wrapper owns its object, false otherwise. + * @return True if the wrapper owns its object, false otherwise. + */ + [[nodiscard]] bool owner() const noexcept { + return (mode == any_policy::dynamic || mode == any_policy::embedded); + } + + /** + * @brief Returns the current mode of an any object. + * @return The current mode of the any object. + */ + [[nodiscard]] any_policy policy() const noexcept { + return mode; + } + +private: + vtable_type *vtable{}; + deleter_type *deleter{}; + id_type underlying_type{}; + any_policy mode{}; +}; + +/** + * @brief Performs type-safe access to the contained object. + * @tparam Type Type to which conversion is required. + * @tparam Len Size of the buffer reserved for the small buffer optimization. + * @tparam Align Alignment requirement. + * @param data Target any object. + * @return The element converted to the requested type. + */ +template +[[nodiscard]] std::remove_const_t any_cast(const basic_any &data) noexcept { + const auto *const instance = any_cast>(&data); + ENTT_ASSERT(instance, "Invalid instance"); + return static_cast(*instance); +} + +/*! @copydoc any_cast */ +template +[[nodiscard]] std::remove_const_t any_cast(basic_any &data) noexcept { + // forces const on non-reference types to make them work also with wrappers for const references + auto *const instance = any_cast>(&data); + ENTT_ASSERT(instance, "Invalid instance"); + return static_cast(*instance); +} + +/*! @copydoc any_cast */ +template +// NOLINTNEXTLINE(cppcoreguidelines-rvalue-reference-param-not-moved) +[[nodiscard]] std::remove_const_t any_cast(basic_any &&data) noexcept { + if constexpr(std::is_copy_constructible_v>>) { + if(auto *const instance = any_cast>(&data); instance) { + return static_cast(std::move(*instance)); + } + + return any_cast(data); + } else { + auto *const instance = any_cast>(&data); + ENTT_ASSERT(instance, "Invalid instance"); + return static_cast(std::move(*instance)); + } +} + +/*! @copydoc any_cast */ +template +[[nodiscard]] const Type *any_cast(const basic_any *data) noexcept { + return data->template data>(); +} + +/*! @copydoc any_cast */ +template +[[nodiscard]] Type *any_cast(basic_any *data) noexcept { + if constexpr(std::is_const_v) { + // last attempt to make wrappers for const references return their values + return any_cast(&std::as_const(*data)); + } else { + return data->template data(); + } +} + +/** + * @brief Constructs a wrapper from a given type, passing it all arguments. + * @tparam Type Type of object to use to initialize the wrapper. + * @tparam Len Size of the buffer reserved for the small buffer optimization. + * @tparam Align Optional alignment requirement. + * @tparam Args Types of arguments to use to construct the new instance. + * @param args Parameters to use to construct the instance. + * @return A properly initialized wrapper for an object of the given type. + */ +template::length, std::size_t Align = basic_any::alignment, typename... Args> +[[nodiscard]] basic_any make_any(Args &&...args) { + return basic_any{std::in_place_type, std::forward(args)...}; +} + +/** + * @brief Forwards its argument and avoids copies for lvalue references. + * @tparam Len Size of the buffer reserved for the small buffer optimization. + * @tparam Align Optional alignment requirement. + * @tparam Type Type of argument to use to construct the new instance. + * @param value Parameter to use to construct the instance. + * @return A properly initialized and not necessarily owning wrapper. + */ +template::length, std::size_t Align = basic_any::alignment, typename Type> +[[nodiscard]] basic_any forward_as_any(Type &&value) { + return basic_any{std::in_place_type, std::forward(value)}; +} + +} // namespace entt + +#endif + +// #include "../core/type_info.hpp" +#ifndef ENTT_CORE_TYPE_INFO_HPP +#define ENTT_CORE_TYPE_INFO_HPP + +#include +#include +#include +// #include "../config/config.h" + +// #include "fwd.hpp" + +// #include "hashed_string.hpp" + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +struct ENTT_API type_index final { + [[nodiscard]] static id_type next() noexcept { + static ENTT_MAYBE_ATOMIC(id_type) value{}; + return value++; + } +}; + +template +[[nodiscard]] constexpr const char *pretty_function() noexcept { +#if defined ENTT_PRETTY_FUNCTION + return static_cast(ENTT_PRETTY_FUNCTION); +#else + return ""; +#endif +} + +template +[[nodiscard]] constexpr auto stripped_type_name() noexcept { +#if defined ENTT_PRETTY_FUNCTION + const std::string_view full_name{pretty_function()}; + auto first = full_name.find_first_not_of(' ', full_name.find_first_of(ENTT_PRETTY_FUNCTION_PREFIX) + 1); + auto value = full_name.substr(first, full_name.find_last_of(ENTT_PRETTY_FUNCTION_SUFFIX) - first); + return value; +#else + return std::string_view{}; +#endif +} + +template().find_first_of('.')> +[[nodiscard]] constexpr std::string_view type_name(int) noexcept { + constexpr auto value = stripped_type_name(); + return value; +} + +template +[[nodiscard]] std::string_view type_name(char) noexcept { + static const auto value = stripped_type_name(); + return value; +} + +template().find_first_of('.')> +[[nodiscard]] constexpr id_type type_hash(int) noexcept { + constexpr auto stripped = stripped_type_name(); + constexpr auto value = hashed_string::value(stripped.data(), stripped.size()); + return value; +} + +template +[[nodiscard]] id_type type_hash(char) noexcept { + static const auto value = [](const auto stripped) { + return hashed_string::value(stripped.data(), stripped.size()); + }(stripped_type_name()); + return value; +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Type sequential identifier. + * @tparam Type Type for which to generate a sequential identifier. + */ +template +struct ENTT_API type_index final { + /** + * @brief Returns the sequential identifier of a given type. + * @return The sequential identifier of a given type. + */ + [[nodiscard]] static id_type value() noexcept { + static const id_type value = internal::type_index::next(); + return value; + } + + /*! @copydoc value */ + [[nodiscard]] constexpr operator id_type() const noexcept { + return value(); + } +}; + +/** + * @brief Type hash. + * @tparam Type Type for which to generate a hash value. + */ +template +struct type_hash final { + /** + * @brief Returns the numeric representation of a given type. + * @return The numeric representation of the given type. + */ +#if defined ENTT_PRETTY_FUNCTION + [[nodiscard]] static constexpr id_type value() noexcept { + return internal::type_hash(0); +#else + [[nodiscard]] static constexpr id_type value() noexcept { + return type_index::value(); +#endif + } + + /*! @copydoc value */ + [[nodiscard]] constexpr operator id_type() const noexcept { + return value(); + } +}; + +/** + * @brief Type name. + * @tparam Type Type for which to generate a name. + */ +template +struct type_name final { + /** + * @brief Returns the name of a given type. + * @return The name of the given type. + */ + [[nodiscard]] static constexpr std::string_view value() noexcept { + return internal::type_name(0); + } + + /*! @copydoc value */ + [[nodiscard]] constexpr operator std::string_view() const noexcept { + return value(); + } +}; + +/*! @brief Implementation specific information about a type. */ +struct type_info final { + /** + * @brief Constructs a type info object for a given type. + * @tparam Type Type for which to construct a type info object. + */ + template + // NOLINTBEGIN(modernize-use-transparent-functors) + constexpr type_info(std::in_place_type_t) noexcept + : seq{type_index>>::value()}, + identifier{type_hash>>::value()}, + alias{type_name>>::value()} {} + // NOLINTEND(modernize-use-transparent-functors) + + /** + * @brief Type index. + * @return Type index. + */ + [[nodiscard]] constexpr id_type index() const noexcept { + return seq; + } + + /** + * @brief Type hash. + * @return Type hash. + */ + [[nodiscard]] constexpr id_type hash() const noexcept { + return identifier; + } + + /** + * @brief Type name. + * @return Type name. + */ + [[nodiscard]] constexpr std::string_view name() const noexcept { + return alias; + } + +private: + id_type seq; + id_type identifier; + std::string_view alias; +}; + +/** + * @brief Compares the contents of two type info objects. + * @param lhs A type info object. + * @param rhs A type info object. + * @return True if the two type info objects are identical, false otherwise. + */ +[[nodiscard]] constexpr bool operator==(const type_info &lhs, const type_info &rhs) noexcept { + return lhs.hash() == rhs.hash(); +} + +/** + * @brief Compares the contents of two type info objects. + * @param lhs A type info object. + * @param rhs A type info object. + * @return True if the two type info objects differ, false otherwise. + */ +[[nodiscard]] constexpr bool operator!=(const type_info &lhs, const type_info &rhs) noexcept { + return !(lhs == rhs); +} + +/** + * @brief Compares two type info objects. + * @param lhs A valid type info object. + * @param rhs A valid type info object. + * @return True if the first element is less than the second, false otherwise. + */ +[[nodiscard]] constexpr bool operator<(const type_info &lhs, const type_info &rhs) noexcept { + return lhs.index() < rhs.index(); +} + +/** + * @brief Compares two type info objects. + * @param lhs A valid type info object. + * @param rhs A valid type info object. + * @return True if the first element is less than or equal to the second, false + * otherwise. + */ +[[nodiscard]] constexpr bool operator<=(const type_info &lhs, const type_info &rhs) noexcept { + return !(rhs < lhs); +} + +/** + * @brief Compares two type info objects. + * @param lhs A valid type info object. + * @param rhs A valid type info object. + * @return True if the first element is greater than the second, false + * otherwise. + */ +[[nodiscard]] constexpr bool operator>(const type_info &lhs, const type_info &rhs) noexcept { + return rhs < lhs; +} + +/** + * @brief Compares two type info objects. + * @param lhs A valid type info object. + * @param rhs A valid type info object. + * @return True if the first element is greater than or equal to the second, + * false otherwise. + */ +[[nodiscard]] constexpr bool operator>=(const type_info &lhs, const type_info &rhs) noexcept { + return !(lhs < rhs); +} + +/** + * @brief Returns the type info object associated to a given type. + * + * The returned element refers to an object with static storage duration.
+ * The type doesn't need to be a complete type. If the type is a reference, the + * result refers to the referenced type. In all cases, top-level cv-qualifiers + * are ignored. + * + * @tparam Type Type for which to generate a type info object. + * @return A reference to a properly initialized type info object. + */ +template +[[nodiscard]] const type_info &type_id() noexcept { + if constexpr(std::is_same_v>>) { + static const type_info instance{std::in_place_type}; + return instance; + } else { + return type_id>>(); + } +} + +/*! @copydoc type_id */ +template +// NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward) +[[nodiscard]] const type_info &type_id(Type &&) noexcept { + return type_id>>(); +} + +} // namespace entt + +#endif + +// #include "../core/type_traits.hpp" +#ifndef ENTT_CORE_TYPE_TRAITS_HPP +#define ENTT_CORE_TYPE_TRAITS_HPP + +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "fwd.hpp" + + +namespace entt { + +/** + * @brief Utility class to disambiguate overloaded functions. + * @tparam N Number of choices available. + */ +template +struct choice_t + // unfortunately, doxygen cannot parse such a construct + : /*! @cond TURN_OFF_DOXYGEN */ choice_t /*! @endcond */ +{}; + +/*! @copybrief choice_t */ +template<> +struct choice_t<0> {}; + +/** + * @brief Variable template for the choice trick. + * @tparam N Number of choices available. + */ +template +inline constexpr choice_t choice{}; + +/** + * @brief Identity type trait. + * + * Useful to establish non-deduced contexts in template argument deduction + * (waiting for C++20) or to provide types through function arguments. + * + * @tparam Type A type. + */ +template +struct type_identity { + /*! @brief Identity type. */ + using type = Type; +}; + +/** + * @brief Helper type. + * @tparam Type A type. + */ +template +using type_identity_t = typename type_identity::type; + +/** + * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains. + * @tparam Type The type of which to return the size. + */ +template +struct size_of: std::integral_constant {}; + +/*! @copydoc size_of */ +template +struct size_of> + // NOLINTNEXTLINE(bugprone-sizeof-expression) + : std::integral_constant {}; + +/** + * @brief Helper variable template. + * @tparam Type The type of which to return the size. + */ +template +inline constexpr std::size_t size_of_v = size_of::value; + +/** + * @brief Using declaration to be used to _repeat_ the same type a number of + * times equal to the size of a given parameter pack. + * @tparam Type A type to repeat. + */ +template +using unpack_as_type = Type; + +/** + * @brief Helper variable template to be used to _repeat_ the same value a + * number of times equal to the size of a given parameter pack. + * @tparam Value A value to repeat. + */ +template +inline constexpr auto unpack_as_value = Value; + +/** + * @brief Wraps a static constant. + * @tparam Value A static constant. + */ +template +using integral_constant = std::integral_constant; + +/** + * @brief Alias template to facilitate the creation of named values. + * @tparam Value A constant value at least convertible to `id_type`. + */ +template +using tag = integral_constant; + +/** + * @brief A class to use to push around lists of types, nothing more. + * @tparam Type Types provided by the type list. + */ +template +struct type_list { + /*! @brief Type list type. */ + using type = type_list; + /*! @brief Compile-time number of elements in the type list. */ + static constexpr auto size = sizeof...(Type); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_element; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Index Index of the type to return. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element> + : type_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element<0u, type_list> { + /*! @brief Searched type. */ + using type = First; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Type list to search into. + */ +template +using type_list_element_t = typename type_list_element::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_index; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 1u + type_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + static_assert(type_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +inline constexpr std::size_t type_list_index_v = type_list_index::value; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @return A type list composed by the types of both the type lists. + */ +template +constexpr type_list operator+(type_list, type_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_cat; + +/*! @brief Concatenates multiple type lists. */ +template<> +struct type_list_cat<> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list<>; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @tparam List Other type lists, if any. + */ +template +struct type_list_cat, type_list, List...> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = typename type_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the type list. + */ +template +struct type_list_cat> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list; +}; + +/** + * @brief Helper type. + * @tparam List Type lists to concatenate. + */ +template +using type_list_cat_t = typename type_list_cat::type; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct type_list_unique; + +template +struct type_list_unique, Type...> + : std::conditional_t<(std::is_same_v || ...), type_list_unique, Type...>, type_list_unique, Type..., First>> {}; + +template +struct type_list_unique, Type...> { + using type = type_list; +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Removes duplicates types from a type list. + * @tparam List Type list. + */ +template +struct type_list_unique { + /*! @brief A type list without duplicate types. */ + using type = typename internal::type_list_unique::type; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + */ +template +using type_list_unique_t = typename type_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a type list contains a + * given type, false otherwise. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +struct type_list_contains; + +/** + * @copybrief type_list_contains + * @tparam Type Types provided by the type list. + * @tparam Other Type to look for. + */ +template +struct type_list_contains, Other> + : std::bool_constant<(std::is_same_v || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +inline constexpr bool type_list_contains_v = type_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_diff; + +/** + * @brief Computes the difference between two type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + */ +template +struct type_list_diff, type_list> { + /*! @brief A type list that is the difference between the two type lists. */ + using type = type_list_cat_t, Type>, type_list<>, type_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Type lists between which to compute the difference. + */ +template +using type_list_diff_t = typename type_list_diff::type; + +/*! @brief Primary template isn't defined on purpose. */ +template class> +struct type_list_transform; + +/** + * @brief Applies a given _function_ to a type list and generate a new list. + * @tparam Type Types provided by the type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +struct type_list_transform, Op> { + /*! @brief Resulting type list after applying the transform function. */ + // NOLINTNEXTLINE(modernize-type-traits) + using type = type_list::type...>; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +using type_list_transform_t = typename type_list_transform::type; + +/** + * @brief A class to use to push around lists of constant values, nothing more. + * @tparam Value Values provided by the value list. + */ +template +struct value_list { + /*! @brief Value list type. */ + using type = value_list; + /*! @brief Compile-time number of elements in the value list. */ + static constexpr auto size = sizeof...(Value); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_element; + +/** + * @brief Provides compile-time indexed access to the values of a value list. + * @tparam Index Index of the value to return. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element> + : value_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element<0u, value_list> { + /*! @brief Searched type. */ + using type = decltype(Value); + /*! @brief Searched value. */ + static constexpr auto value = Value; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Value list to search into. + */ +template +using value_list_element_t = typename value_list_element::type; + +/** + * @brief Helper type. + * @tparam Index Index of the value to return. + * @tparam List Value list to search into. + */ +template +inline constexpr auto value_list_element_v = value_list_element::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_index; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam First First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 1u + value_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + static_assert(value_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +inline constexpr std::size_t value_list_index_v = value_list_index::value; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @return A value list composed by the values of both the value lists. + */ +template +constexpr value_list operator+(value_list, value_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_cat; + +/*! @brief Concatenates multiple value lists. */ +template<> +struct value_list_cat<> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list<>; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @tparam List Other value lists, if any. + */ +template +struct value_list_cat, value_list, List...> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = typename value_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the value list. + */ +template +struct value_list_cat> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list; +}; + +/** + * @brief Helper type. + * @tparam List Value lists to concatenate. + */ +template +using value_list_cat_t = typename value_list_cat::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_unique; + +/** + * @brief Removes duplicates values from a value list. + * @tparam Value One of the values provided by the given value list. + * @tparam Other The other values provided by the given value list. + */ +template +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = std::conditional_t< + ((Value == Other) || ...), + typename value_list_unique>::type, + value_list_cat_t, typename value_list_unique>::type>>; +}; + +/*! @brief Removes duplicates values from a value list. */ +template<> +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = value_list<>; +}; + +/** + * @brief Helper type. + * @tparam Type A value list. + */ +template +using value_list_unique_t = typename value_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a value list contains + * a given value, false otherwise. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +struct value_list_contains; + +/** + * @copybrief value_list_contains + * @tparam Value Values provided by the value list. + * @tparam Other Value to look for. + */ +template +struct value_list_contains, Other> + : std::bool_constant<((Value == Other) || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +inline constexpr bool value_list_contains_v = value_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_diff; + +/** + * @brief Computes the difference between two value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + */ +template +struct value_list_diff, value_list> { + /*! @brief A value list that is the difference between the two value lists. */ + using type = value_list_cat_t, Value>, value_list<>, value_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Value lists between which to compute the difference. + */ +template +using value_list_diff_t = typename value_list_diff::type; + +/*! @brief Same as std::is_invocable, but with tuples. */ +template +struct is_applicable: std::false_type {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @brief Helper variable template. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_v = is_applicable::value; + +/*! @brief Same as std::is_invocable_r, but with tuples for arguments. */ +template +struct is_applicable_r: std::false_type {}; + +/** + * @copybrief is_applicable_r + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +struct is_applicable_r>: std::is_invocable_r {}; + +/** + * @brief Helper variable template. + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_r_v = is_applicable_r::value; + +/** + * @brief Provides the member constant `value` to true if a given type is + * complete, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_complete: std::false_type {}; + +/*! @copydoc is_complete */ +template +struct is_complete>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_complete_v = is_complete::value; + +/** + * @brief Provides the member constant `value` to true if a given type is an + * iterator, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_iterator: std::false_type {}; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_iterator_category: std::false_type {}; + +template +struct has_iterator_category::iterator_category>>: std::true_type {}; + +} // namespace internal +/*! @endcond */ + +/*! @copydoc is_iterator */ +template +struct is_iterator>>>> + : internal::has_iterator_category {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_iterator_v = is_iterator::value; + +/** + * @brief Provides the member constant `value` to true if a given type is both + * an empty and non-final class, false otherwise. + * @tparam Type The type to test + */ +template +struct is_ebco_eligible + : std::bool_constant && !std::is_final_v> {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_ebco_eligible_v = is_ebco_eligible::value; + +/** + * @brief Provides the member constant `value` to true if `Type::is_transparent` + * is valid and denotes a type, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_transparent: std::false_type {}; + +/*! @copydoc is_transparent */ +template +struct is_transparent>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_transparent_v = is_transparent::value; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_tuple_size_value: std::false_type {}; + +template +struct has_tuple_size_value::value)>>: std::true_type {}; + +template +struct has_value_type: std::false_type {}; + +template +struct has_value_type>: std::true_type {}; + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable(); + +template +[[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence) { + return (dispatch_is_equality_comparable>() && ...); +} + +template +[[nodiscard]] constexpr bool maybe_equality_comparable(char) { + return false; +} + +template +[[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval() == std::declval()) { + return true; +} + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable() { + // NOLINTBEGIN(modernize-use-transparent-functors) + if constexpr(std::is_array_v) { + return false; + } else if constexpr(is_complete_v>>) { + if constexpr(has_tuple_size_value::value) { + return maybe_equality_comparable(0) && unpack_maybe_equality_comparable(std::make_index_sequence::value>{}); + } else { + return maybe_equality_comparable(0); + } + } else if constexpr(has_value_type::value) { + if constexpr(is_iterator_v || std::is_same_v || dispatch_is_equality_comparable()) { + return maybe_equality_comparable(0); + } else { + return false; + } + } else { + return maybe_equality_comparable(0); + } + // NOLINTEND(modernize-use-transparent-functors) +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Provides the member constant `value` to true if a given type is + * equality comparable, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_equality_comparable: std::bool_constant()> {}; + +/*! @copydoc is_equality_comparable */ +template +struct is_equality_comparable: is_equality_comparable {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_equality_comparable_v = is_equality_comparable::value; + +/** + * @brief Transcribes the constness of a type to another type. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = std::remove_const_t; +}; + +/*! @copydoc constness_as */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = const To; +}; + +/** + * @brief Alias template to facilitate the transcription of the constness. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +using constness_as_t = typename constness_as::type; + +/** + * @brief Extracts the class of a non-static member object or function. + * @tparam Member A pointer to a non-static member object or function. + */ +template +class member_class { + static_assert(std::is_member_pointer_v, "Invalid pointer type to non-static member object or function"); + + template + static Class *clazz(Ret (Class::*)(Args...)); + + template + static Class *clazz(Ret (Class::*)(Args...) const); + + template + static Class *clazz(Type Class::*); + +public: + /*! @brief The class of the given non-static member object or function. */ + using type = std::remove_pointer_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Member A pointer to a non-static member object or function. + */ +template +using member_class_t = typename member_class::type; + +/** + * @brief Extracts the n-th argument of a _callable_ type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid _callable_ type. + */ +template +class nth_argument { + template + static constexpr type_list pick_up(Ret (*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...) const); + + template + static constexpr type_list pick_up(Type Class ::*); + + template + static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&); + +public: + /*! @brief N-th argument of the _callable_ type. */ + using type = type_list_element_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid function, member function or data member type. + */ +template +using nth_argument_t = typename nth_argument::type; + +} // namespace entt + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::type_list_element> {}; + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::value_list_element> {}; + +#endif + +// #include "fwd.hpp" +#ifndef ENTT_POLY_FWD_HPP +#define ENTT_POLY_FWD_HPP + +#include + +namespace entt { + +// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) +template +class basic_poly; + +/** + * @brief Alias declaration for the most common use case. + * @tparam Concept Concept descriptor. + */ +template +using poly = basic_poly; + +} // namespace entt + +#endif + + +namespace entt { + +/*! @brief Inspector class used to infer the type of the virtual table. */ +struct poly_inspector { + /** + * @brief Generic conversion operator (definition only). + * @tparam Type Type to which conversion is requested. + */ + template + operator Type &&() const; + + /** + * @brief Dummy invocation function (definition only). + * @tparam Member Index of the function to invoke. + * @tparam Args Types of arguments to pass to the function. + * @param args The arguments to pass to the function. + * @return A poly inspector convertible to any type. + */ + template + [[nodiscard]] poly_inspector invoke(Args &&...args) const; + + /*! @copydoc invoke */ + template + [[nodiscard]] poly_inspector invoke(Args &&...args); +}; + +/** + * @brief Static virtual table factory. + * @tparam Concept Concept descriptor. + * @tparam Len Size of the storage reserved for the small buffer optimization. + * @tparam Align Alignment requirement. + */ +template +class poly_vtable { + using inspector = typename Concept::template type; + + template + static auto vtable_entry(Ret (*)(Clazz &, Args...)) + -> std::enable_if_t, inspector>, Ret (*)(constness_as_t, Clazz> &, Args...)>; + + template + static auto vtable_entry(Ret (*)(Args...)) + -> Ret (*)(const basic_any &, Args...); + + template + static auto vtable_entry(Ret (Clazz::*)(Args...)) + -> std::enable_if_t, Ret (*)(basic_any &, Args...)>; + + template + static auto vtable_entry(Ret (Clazz::*)(Args...) const) + -> std::enable_if_t, Ret (*)(const basic_any &, Args...)>; + + template + static auto make_vtable(value_list) noexcept + -> decltype(std::make_tuple(vtable_entry(Candidate)...)); + + template + [[nodiscard]] static constexpr auto make_vtable(type_list) noexcept { + if constexpr(sizeof...(Func) == 0u) { + return decltype(make_vtable(typename Concept::template impl{})){}; + } else if constexpr((std::is_function_v && ...)) { + return decltype(std::make_tuple(vtable_entry(std::declval())...)){}; + } + } + + template + static void fill_vtable_entry(Ret (*&entry)(Any &, Args...)) noexcept { + if constexpr(std::is_invocable_r_v) { + entry = +[](Any &, Args... args) -> Ret { + return std::invoke(Candidate, std::forward(args)...); + }; + } else { + entry = +[](Any &instance, Args... args) -> Ret { + return static_cast(std::invoke(Candidate, any_cast &>(instance), std::forward(args)...)); + }; + } + } + + template + [[nodiscard]] static auto fill_vtable(std::index_sequence) noexcept { + vtable_type impl{}; + (fill_vtable_entry>>(std::get(impl)), ...); + return impl; + } + + using vtable_type = decltype(make_vtable(Concept{})); + static constexpr bool is_mono = std::tuple_size_v == 1u; + +public: + /*! @brief Virtual table type. */ + using type = std::conditional_t, const vtable_type *>; + + /** + * @brief Returns a static virtual table for a specific concept and type. + * @tparam Type The type for which to generate the virtual table. + * @return A static virtual table for the given concept and type. + */ + template + [[nodiscard]] static type instance() noexcept { + static_assert(std::is_same_v>, "Type differs from its decayed form"); + static const vtable_type vtable = fill_vtable(std::make_index_sequence::size>{}); + + if constexpr(is_mono) { + return std::get<0>(vtable); + } else { + return &vtable; + } + } +}; + +/** + * @brief Poly base class used to inject functionalities into concepts. + * @tparam Poly The outermost poly class. + */ +template +struct poly_base { + /** + * @brief Invokes a function from the static virtual table. + * @tparam Member Index of the function to invoke. + * @tparam Args Types of arguments to pass to the function. + * @param self A reference to the poly object that made the call. + * @param args The arguments to pass to the function. + * @return The return value of the invoked function, if any. + */ + template + [[nodiscard]] decltype(auto) invoke(const poly_base &self, Args &&...args) const { + const auto &poly = static_cast(self); + + if constexpr(std::is_function_v>) { + return poly.vtable(poly.storage, std::forward(args)...); + } else { + return std::get(*poly.vtable)(poly.storage, std::forward(args)...); + } + } + + /*! @copydoc invoke */ + template + [[nodiscard]] decltype(auto) invoke(poly_base &self, Args &&...args) { + auto &poly = static_cast(self); + + if constexpr(std::is_function_v>) { + static_assert(Member == 0u, "Unknown member"); + return poly.vtable(poly.storage, std::forward(args)...); + } else { + return std::get(*poly.vtable)(poly.storage, std::forward(args)...); + } + } +}; + +/** + * @brief Shortcut for calling `poly_base::invoke`. + * @tparam Member Index of the function to invoke. + * @tparam Poly A fully defined poly object. + * @tparam Args Types of arguments to pass to the function. + * @param self A reference to the poly object that made the call. + * @param args The arguments to pass to the function. + * @return The return value of the invoked function, if any. + */ +template +decltype(auto) poly_call(Poly &&self, Args &&...args) { + return std::forward(self).template invoke(self, std::forward(args)...); +} + +/** + * @brief Static polymorphism made simple and within everyone's reach. + * + * Static polymorphism is a very powerful tool in C++, albeit sometimes + * cumbersome to obtain.
+ * This class aims to make it simple and easy to use. + * + * @note + * Both deduced and defined static virtual tables are supported.
+ * Moreover, the `poly` class template also works with unmanaged objects. + * + * @tparam Concept Concept descriptor. + * @tparam Len Size of the storage reserved for the small buffer optimization. + * @tparam Align Optional alignment requirement. + */ +template +class basic_poly: private Concept::template type>> { + friend struct poly_base; + +public: + /*! @brief Concept type. */ + using concept_type = typename Concept::template type>; + /*! @brief Virtual table type. */ + using vtable_type = typename poly_vtable::type; + + /*! @brief Default constructor. */ + basic_poly() noexcept = default; + + /** + * @brief Constructs a poly by directly initializing the new object. + * @tparam Type Type of object to use to initialize the poly. + * @tparam Args Types of arguments to use to construct the new instance. + * @param args Parameters to use to construct the instance. + */ + template + explicit basic_poly(std::in_place_type_t, Args &&...args) + : storage{std::in_place_type, std::forward(args)...}, + vtable{poly_vtable::template instance>>()} {} + + /** + * @brief Constructs a poly from a given value. + * @tparam Type Type of object to use to initialize the poly. + * @param value An instance of an object to use to initialize the poly. + */ + template>, basic_poly>>> + basic_poly(Type &&value) noexcept + : basic_poly{std::in_place_type>>, std::forward(value)} {} + + /** + * @brief Returns the object type info if any, `type_id()` otherwise. + * @return The object type info if any, `type_id()` otherwise. + */ + [[nodiscard]] const type_info &info() const noexcept { + return storage.info(); + } + + /*! @copydoc info */ + [[deprecated("use ::info instead")]] [[nodiscard]] const type_info &type() const noexcept { + return info(); + } + + /** + * @brief Returns an opaque pointer to the contained instance. + * @return An opaque pointer the contained instance, if any. + */ + [[nodiscard]] const void *data() const noexcept { + return storage.data(); + } + + /*! @copydoc data */ + [[nodiscard]] void *data() noexcept { + return storage.data(); + } + + /** + * @brief Replaces the contained object by creating a new instance directly. + * @tparam Type Type of object to use to initialize the poly. + * @tparam Args Types of arguments to use to construct the new instance. + * @param args Parameters to use to construct the instance. + */ + template + void emplace(Args &&...args) { + storage.template emplace(std::forward(args)...); + vtable = poly_vtable::template instance>>(); + } + + /*! @brief Destroys contained object */ + void reset() { + storage.reset(); + vtable = {}; + } + + /** + * @brief Returns false if a poly is empty, true otherwise. + * @return False if the poly is empty, true otherwise. + */ + [[nodiscard]] explicit operator bool() const noexcept { + return static_cast(storage); + } + + /** + * @brief Returns a pointer to the underlying concept. + * @return A pointer to the underlying concept. + */ + [[nodiscard]] concept_type *operator->() noexcept { + return this; + } + + /*! @copydoc operator-> */ + [[nodiscard]] const concept_type *operator->() const noexcept { + return this; + } + + /** + * @brief Aliasing constructor. + * @return A poly that shares a reference to an unmanaged object. + */ + [[nodiscard]] basic_poly as_ref() noexcept { + basic_poly ref{}; + ref.storage = storage.as_ref(); + ref.vtable = vtable; + return ref; + } + + /*! @copydoc as_ref */ + [[nodiscard]] basic_poly as_ref() const noexcept { + basic_poly ref{}; + ref.storage = storage.as_ref(); + ref.vtable = vtable; + return ref; + } + +private: + basic_any storage{}; + vtable_type vtable{}; +}; + +} // namespace entt + +#endif + +// #include "process/process.hpp" +#ifndef ENTT_PROCESS_PROCESS_HPP +#define ENTT_PROCESS_PROCESS_HPP + +#include +#include +#include +#include +// #include "../core/compressed_pair.hpp" +#ifndef ENTT_CORE_COMPRESSED_PAIR_HPP +#define ENTT_CORE_COMPRESSED_PAIR_HPP + +#include +#include +#include +#include +// #include "fwd.hpp" +#ifndef ENTT_CORE_FWD_HPP +#define ENTT_CORE_FWD_HPP + +#include +#include +// #include "../config/config.h" +#ifndef ENTT_CONFIG_CONFIG_H +#define ENTT_CONFIG_CONFIG_H + +// #include "version.h" +#ifndef ENTT_CONFIG_VERSION_H +#define ENTT_CONFIG_VERSION_H + +// #include "macro.h" +#ifndef ENTT_CONFIG_MACRO_H +#define ENTT_CONFIG_MACRO_H + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#define ENTT_STR(arg) #arg +#define ENTT_XSTR(arg) ENTT_STR(arg) + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*) + +#define ENTT_VERSION_MAJOR 3 +#define ENTT_VERSION_MINOR 16 +#define ENTT_VERSION_PATCH 0 + +#define ENTT_VERSION \ + ENTT_XSTR(ENTT_VERSION_MAJOR) \ + "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH) + +// NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION) +# define ENTT_CONSTEXPR +# define ENTT_THROW throw +# define ENTT_TRY try +# define ENTT_CATCH catch(...) +#else +# define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20) +# define ENTT_THROW +# define ENTT_TRY if(true) +# define ENTT_CATCH if(false) +#endif + +#if __has_include() +# include +# +# if defined(__cpp_consteval) +# define ENTT_CONSTEVAL consteval +# endif +#endif + +#ifndef ENTT_CONSTEVAL +# define ENTT_CONSTEVAL constexpr +#endif + +#ifdef ENTT_USE_ATOMIC +# include +# define ENTT_MAYBE_ATOMIC(Type) std::atomic +#else +# define ENTT_MAYBE_ATOMIC(Type) Type +#endif + +#ifndef ENTT_ID_TYPE +# include +# define ENTT_ID_TYPE std::uint32_t +#else +# include // provides coverage for types in the std namespace +#endif + +#ifndef ENTT_SPARSE_PAGE +# define ENTT_SPARSE_PAGE 4096 +#endif + +#ifndef ENTT_PACKED_PAGE +# define ENTT_PACKED_PAGE 1024 +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT +# define ENTT_ASSERT(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT +# include +# define ENTT_ASSERT(condition, msg) assert(((condition) && (msg))) +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg) +#endif + +#define ENTT_FAIL(msg) ENTT_ASSERT(false, msg); + +#ifdef ENTT_NO_ETO +# define ENTT_ETO_TYPE(Type) void +#else +# define ENTT_ETO_TYPE(Type) Type +#endif + +#ifdef ENTT_NO_MIXIN +# define ENTT_STORAGE(Mixin, ...) __VA_ARGS__ +#else +# define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__> +#endif + +#ifdef ENTT_STANDARD_CPP +# define ENTT_NONSTD false +#else +# define ENTT_NONSTD true +# if defined __clang__ || defined __GNUC__ +# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ +# define ENTT_PRETTY_FUNCTION_PREFIX '=' +# define ENTT_PRETTY_FUNCTION_SUFFIX ']' +# elif defined _MSC_VER +# define ENTT_PRETTY_FUNCTION __FUNCSIG__ +# define ENTT_PRETTY_FUNCTION_PREFIX '<' +# define ENTT_PRETTY_FUNCTION_SUFFIX '>' +# endif +#endif + +#ifndef ENTT_EXPORT +# if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER +# define ENTT_EXPORT __declspec(dllexport) +# define ENTT_IMPORT __declspec(dllimport) +# define ENTT_HIDDEN +# elif defined __GNUC__ && __GNUC__ >= 4 +# define ENTT_EXPORT __attribute__((visibility("default"))) +# define ENTT_IMPORT __attribute__((visibility("default"))) +# define ENTT_HIDDEN __attribute__((visibility("hidden"))) +# else /* Unsupported compiler */ +# define ENTT_EXPORT +# define ENTT_IMPORT +# define ENTT_HIDDEN +# endif +#endif + +#ifndef ENTT_API +# if defined ENTT_API_EXPORT +# define ENTT_API ENTT_EXPORT +# elif defined ENTT_API_IMPORT +# define ENTT_API ENTT_IMPORT +# else /* No API */ +# define ENTT_API +# endif +#endif + +#if defined _MSC_VER +# pragma detect_mismatch("entt.version", ENTT_VERSION) +# pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY)) +# pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE)) +# pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD)) +#endif + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +namespace entt { + +/*! @brief Possible modes of an any object. */ +enum class any_policy : std::uint8_t { + /*! @brief Default mode, no element available. */ + empty, + /*! @brief Owning mode, dynamically allocated element. */ + dynamic, + /*! @brief Owning mode, embedded element. */ + embedded, + /*! @brief Aliasing mode, non-const reference. */ + ref, + /*! @brief Const aliasing mode, const reference. */ + cref +}; + +// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) +template +class basic_any; + +/*! @brief Alias declaration for type identifiers. */ +using id_type = ENTT_ID_TYPE; + +/*! @brief Alias declaration for the most common use case. */ +using any = basic_any<>; + +template +class compressed_pair; + +template +class basic_hashed_string; + +/*! @brief Aliases for common character types. */ +using hashed_string = basic_hashed_string; + +/*! @brief Aliases for common character types. */ +using hashed_wstring = basic_hashed_string; + +// NOLINTNEXTLINE(bugprone-forward-declaration-namespace) +struct type_info; + +} // namespace entt + +#endif + +// #include "type_traits.hpp" +#ifndef ENTT_CORE_TYPE_TRAITS_HPP +#define ENTT_CORE_TYPE_TRAITS_HPP + +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "fwd.hpp" + + +namespace entt { + +/** + * @brief Utility class to disambiguate overloaded functions. + * @tparam N Number of choices available. + */ +template +struct choice_t + // unfortunately, doxygen cannot parse such a construct + : /*! @cond TURN_OFF_DOXYGEN */ choice_t /*! @endcond */ +{}; + +/*! @copybrief choice_t */ +template<> +struct choice_t<0> {}; + +/** + * @brief Variable template for the choice trick. + * @tparam N Number of choices available. + */ +template +inline constexpr choice_t choice{}; + +/** + * @brief Identity type trait. + * + * Useful to establish non-deduced contexts in template argument deduction + * (waiting for C++20) or to provide types through function arguments. + * + * @tparam Type A type. + */ +template +struct type_identity { + /*! @brief Identity type. */ + using type = Type; +}; + +/** + * @brief Helper type. + * @tparam Type A type. + */ +template +using type_identity_t = typename type_identity::type; + +/** + * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains. + * @tparam Type The type of which to return the size. + */ +template +struct size_of: std::integral_constant {}; + +/*! @copydoc size_of */ +template +struct size_of> + // NOLINTNEXTLINE(bugprone-sizeof-expression) + : std::integral_constant {}; + +/** + * @brief Helper variable template. + * @tparam Type The type of which to return the size. + */ +template +inline constexpr std::size_t size_of_v = size_of::value; + +/** + * @brief Using declaration to be used to _repeat_ the same type a number of + * times equal to the size of a given parameter pack. + * @tparam Type A type to repeat. + */ +template +using unpack_as_type = Type; + +/** + * @brief Helper variable template to be used to _repeat_ the same value a + * number of times equal to the size of a given parameter pack. + * @tparam Value A value to repeat. + */ +template +inline constexpr auto unpack_as_value = Value; + +/** + * @brief Wraps a static constant. + * @tparam Value A static constant. + */ +template +using integral_constant = std::integral_constant; + +/** + * @brief Alias template to facilitate the creation of named values. + * @tparam Value A constant value at least convertible to `id_type`. + */ +template +using tag = integral_constant; + +/** + * @brief A class to use to push around lists of types, nothing more. + * @tparam Type Types provided by the type list. + */ +template +struct type_list { + /*! @brief Type list type. */ + using type = type_list; + /*! @brief Compile-time number of elements in the type list. */ + static constexpr auto size = sizeof...(Type); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_element; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Index Index of the type to return. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element> + : type_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element<0u, type_list> { + /*! @brief Searched type. */ + using type = First; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Type list to search into. + */ +template +using type_list_element_t = typename type_list_element::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_index; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 1u + type_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + static_assert(type_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +inline constexpr std::size_t type_list_index_v = type_list_index::value; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @return A type list composed by the types of both the type lists. + */ +template +constexpr type_list operator+(type_list, type_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_cat; + +/*! @brief Concatenates multiple type lists. */ +template<> +struct type_list_cat<> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list<>; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @tparam List Other type lists, if any. + */ +template +struct type_list_cat, type_list, List...> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = typename type_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the type list. + */ +template +struct type_list_cat> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list; +}; + +/** + * @brief Helper type. + * @tparam List Type lists to concatenate. + */ +template +using type_list_cat_t = typename type_list_cat::type; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct type_list_unique; + +template +struct type_list_unique, Type...> + : std::conditional_t<(std::is_same_v || ...), type_list_unique, Type...>, type_list_unique, Type..., First>> {}; + +template +struct type_list_unique, Type...> { + using type = type_list; +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Removes duplicates types from a type list. + * @tparam List Type list. + */ +template +struct type_list_unique { + /*! @brief A type list without duplicate types. */ + using type = typename internal::type_list_unique::type; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + */ +template +using type_list_unique_t = typename type_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a type list contains a + * given type, false otherwise. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +struct type_list_contains; + +/** + * @copybrief type_list_contains + * @tparam Type Types provided by the type list. + * @tparam Other Type to look for. + */ +template +struct type_list_contains, Other> + : std::bool_constant<(std::is_same_v || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +inline constexpr bool type_list_contains_v = type_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_diff; + +/** + * @brief Computes the difference between two type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + */ +template +struct type_list_diff, type_list> { + /*! @brief A type list that is the difference between the two type lists. */ + using type = type_list_cat_t, Type>, type_list<>, type_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Type lists between which to compute the difference. + */ +template +using type_list_diff_t = typename type_list_diff::type; + +/*! @brief Primary template isn't defined on purpose. */ +template class> +struct type_list_transform; + +/** + * @brief Applies a given _function_ to a type list and generate a new list. + * @tparam Type Types provided by the type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +struct type_list_transform, Op> { + /*! @brief Resulting type list after applying the transform function. */ + // NOLINTNEXTLINE(modernize-type-traits) + using type = type_list::type...>; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +using type_list_transform_t = typename type_list_transform::type; + +/** + * @brief A class to use to push around lists of constant values, nothing more. + * @tparam Value Values provided by the value list. + */ +template +struct value_list { + /*! @brief Value list type. */ + using type = value_list; + /*! @brief Compile-time number of elements in the value list. */ + static constexpr auto size = sizeof...(Value); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_element; + +/** + * @brief Provides compile-time indexed access to the values of a value list. + * @tparam Index Index of the value to return. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element> + : value_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element<0u, value_list> { + /*! @brief Searched type. */ + using type = decltype(Value); + /*! @brief Searched value. */ + static constexpr auto value = Value; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Value list to search into. + */ +template +using value_list_element_t = typename value_list_element::type; + +/** + * @brief Helper type. + * @tparam Index Index of the value to return. + * @tparam List Value list to search into. + */ +template +inline constexpr auto value_list_element_v = value_list_element::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_index; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam First First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 1u + value_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + static_assert(value_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +inline constexpr std::size_t value_list_index_v = value_list_index::value; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @return A value list composed by the values of both the value lists. + */ +template +constexpr value_list operator+(value_list, value_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_cat; + +/*! @brief Concatenates multiple value lists. */ +template<> +struct value_list_cat<> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list<>; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @tparam List Other value lists, if any. + */ +template +struct value_list_cat, value_list, List...> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = typename value_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the value list. + */ +template +struct value_list_cat> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list; +}; + +/** + * @brief Helper type. + * @tparam List Value lists to concatenate. + */ +template +using value_list_cat_t = typename value_list_cat::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_unique; + +/** + * @brief Removes duplicates values from a value list. + * @tparam Value One of the values provided by the given value list. + * @tparam Other The other values provided by the given value list. + */ +template +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = std::conditional_t< + ((Value == Other) || ...), + typename value_list_unique>::type, + value_list_cat_t, typename value_list_unique>::type>>; +}; + +/*! @brief Removes duplicates values from a value list. */ +template<> +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = value_list<>; +}; + +/** + * @brief Helper type. + * @tparam Type A value list. + */ +template +using value_list_unique_t = typename value_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a value list contains + * a given value, false otherwise. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +struct value_list_contains; + +/** + * @copybrief value_list_contains + * @tparam Value Values provided by the value list. + * @tparam Other Value to look for. + */ +template +struct value_list_contains, Other> + : std::bool_constant<((Value == Other) || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +inline constexpr bool value_list_contains_v = value_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_diff; + +/** + * @brief Computes the difference between two value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + */ +template +struct value_list_diff, value_list> { + /*! @brief A value list that is the difference between the two value lists. */ + using type = value_list_cat_t, Value>, value_list<>, value_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Value lists between which to compute the difference. + */ +template +using value_list_diff_t = typename value_list_diff::type; + +/*! @brief Same as std::is_invocable, but with tuples. */ +template +struct is_applicable: std::false_type {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @brief Helper variable template. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_v = is_applicable::value; + +/*! @brief Same as std::is_invocable_r, but with tuples for arguments. */ +template +struct is_applicable_r: std::false_type {}; + +/** + * @copybrief is_applicable_r + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +struct is_applicable_r>: std::is_invocable_r {}; + +/** + * @brief Helper variable template. + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_r_v = is_applicable_r::value; + +/** + * @brief Provides the member constant `value` to true if a given type is + * complete, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_complete: std::false_type {}; + +/*! @copydoc is_complete */ +template +struct is_complete>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_complete_v = is_complete::value; + +/** + * @brief Provides the member constant `value` to true if a given type is an + * iterator, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_iterator: std::false_type {}; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_iterator_category: std::false_type {}; + +template +struct has_iterator_category::iterator_category>>: std::true_type {}; + +} // namespace internal +/*! @endcond */ + +/*! @copydoc is_iterator */ +template +struct is_iterator>>>> + : internal::has_iterator_category {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_iterator_v = is_iterator::value; + +/** + * @brief Provides the member constant `value` to true if a given type is both + * an empty and non-final class, false otherwise. + * @tparam Type The type to test + */ +template +struct is_ebco_eligible + : std::bool_constant && !std::is_final_v> {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_ebco_eligible_v = is_ebco_eligible::value; + +/** + * @brief Provides the member constant `value` to true if `Type::is_transparent` + * is valid and denotes a type, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_transparent: std::false_type {}; + +/*! @copydoc is_transparent */ +template +struct is_transparent>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_transparent_v = is_transparent::value; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_tuple_size_value: std::false_type {}; + +template +struct has_tuple_size_value::value)>>: std::true_type {}; + +template +struct has_value_type: std::false_type {}; + +template +struct has_value_type>: std::true_type {}; + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable(); + +template +[[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence) { + return (dispatch_is_equality_comparable>() && ...); +} + +template +[[nodiscard]] constexpr bool maybe_equality_comparable(char) { + return false; +} + +template +[[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval() == std::declval()) { + return true; +} + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable() { + // NOLINTBEGIN(modernize-use-transparent-functors) + if constexpr(std::is_array_v) { + return false; + } else if constexpr(is_complete_v>>) { + if constexpr(has_tuple_size_value::value) { + return maybe_equality_comparable(0) && unpack_maybe_equality_comparable(std::make_index_sequence::value>{}); + } else { + return maybe_equality_comparable(0); + } + } else if constexpr(has_value_type::value) { + if constexpr(is_iterator_v || std::is_same_v || dispatch_is_equality_comparable()) { + return maybe_equality_comparable(0); + } else { + return false; + } + } else { + return maybe_equality_comparable(0); + } + // NOLINTEND(modernize-use-transparent-functors) +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Provides the member constant `value` to true if a given type is + * equality comparable, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_equality_comparable: std::bool_constant()> {}; + +/*! @copydoc is_equality_comparable */ +template +struct is_equality_comparable: is_equality_comparable {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_equality_comparable_v = is_equality_comparable::value; + +/** + * @brief Transcribes the constness of a type to another type. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = std::remove_const_t; +}; + +/*! @copydoc constness_as */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = const To; +}; + +/** + * @brief Alias template to facilitate the transcription of the constness. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +using constness_as_t = typename constness_as::type; + +/** + * @brief Extracts the class of a non-static member object or function. + * @tparam Member A pointer to a non-static member object or function. + */ +template +class member_class { + static_assert(std::is_member_pointer_v, "Invalid pointer type to non-static member object or function"); + + template + static Class *clazz(Ret (Class::*)(Args...)); + + template + static Class *clazz(Ret (Class::*)(Args...) const); + + template + static Class *clazz(Type Class::*); + +public: + /*! @brief The class of the given non-static member object or function. */ + using type = std::remove_pointer_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Member A pointer to a non-static member object or function. + */ +template +using member_class_t = typename member_class::type; + +/** + * @brief Extracts the n-th argument of a _callable_ type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid _callable_ type. + */ +template +class nth_argument { + template + static constexpr type_list pick_up(Ret (*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...) const); + + template + static constexpr type_list pick_up(Type Class ::*); + + template + static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&); + +public: + /*! @brief N-th argument of the _callable_ type. */ + using type = type_list_element_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid function, member function or data member type. + */ +template +using nth_argument_t = typename nth_argument::type; + +} // namespace entt + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::type_list_element> {}; + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::value_list_element> {}; + +#endif + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct compressed_pair_element { + using reference = Type &; + using const_reference = const Type &; + + template>> + // NOLINTNEXTLINE(modernize-use-equals-default) + constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v) {} + + template>, compressed_pair_element>>> + constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v) + : value{std::forward(arg)} {} + + template + constexpr compressed_pair_element(std::tuple args, std::index_sequence) noexcept(std::is_nothrow_constructible_v) + : value{std::forward(std::get(args))...} {} + + [[nodiscard]] constexpr reference get() noexcept { + return value; + } + + [[nodiscard]] constexpr const_reference get() const noexcept { + return value; + } + +private: + Type value{}; +}; + +template +struct compressed_pair_element>>: Type { + using reference = Type &; + using const_reference = const Type &; + using base_type = Type; + + template>> + constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v) + : base_type{} {} + + template>, compressed_pair_element>>> + constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v) + : base_type{std::forward(arg)} {} + + template + constexpr compressed_pair_element(std::tuple args, std::index_sequence) noexcept(std::is_nothrow_constructible_v) + : base_type{std::forward(std::get(args))...} {} + + [[nodiscard]] constexpr reference get() noexcept { + return *this; + } + + [[nodiscard]] constexpr const_reference get() const noexcept { + return *this; + } +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief A compressed pair. + * + * A pair that exploits the _Empty Base Class Optimization_ (or _EBCO_) to + * reduce its final size to a minimum. + * + * @tparam First The type of the first element that the pair stores. + * @tparam Second The type of the second element that the pair stores. + */ +template +class compressed_pair final + : internal::compressed_pair_element, + internal::compressed_pair_element { + using first_base = internal::compressed_pair_element; + using second_base = internal::compressed_pair_element; + +public: + /*! @brief The type of the first element that the pair stores. */ + using first_type = First; + /*! @brief The type of the second element that the pair stores. */ + using second_type = Second; + + /** + * @brief Default constructor, conditionally enabled. + * + * This constructor is only available when the types that the pair stores + * are both at least default constructible. + * + * @tparam Dummy Dummy template parameter used for internal purposes. + */ + template && std::is_default_constructible_v>> + constexpr compressed_pair() noexcept(std::is_nothrow_default_constructible_v && std::is_nothrow_default_constructible_v) + : first_base{}, + second_base{} {} + + /** + * @brief Copy constructor. + * @param other The instance to copy from. + */ + constexpr compressed_pair(const compressed_pair &other) = default; + + /** + * @brief Move constructor. + * @param other The instance to move from. + */ + constexpr compressed_pair(compressed_pair &&other) noexcept = default; + + /** + * @brief Constructs a pair from its values. + * @tparam Arg Type of value to use to initialize the first element. + * @tparam Other Type of value to use to initialize the second element. + * @param arg Value to use to initialize the first element. + * @param other Value to use to initialize the second element. + */ + template + constexpr compressed_pair(Arg &&arg, Other &&other) noexcept(std::is_nothrow_constructible_v && std::is_nothrow_constructible_v) + : first_base{std::forward(arg)}, + second_base{std::forward(other)} {} + + /** + * @brief Constructs a pair by forwarding the arguments to its parts. + * @tparam Args Types of arguments to use to initialize the first element. + * @tparam Other Types of arguments to use to initialize the second element. + * @param args Arguments to use to initialize the first element. + * @param other Arguments to use to initialize the second element. + */ + template + constexpr compressed_pair(std::piecewise_construct_t, std::tuple args, std::tuple other) noexcept(std::is_nothrow_constructible_v && std::is_nothrow_constructible_v) + : first_base{std::move(args), std::index_sequence_for{}}, + second_base{std::move(other), std::index_sequence_for{}} {} + + /*! @brief Default destructor. */ + ~compressed_pair() = default; + + /** + * @brief Copy assignment operator. + * @param other The instance to copy from. + * @return This compressed pair object. + */ + constexpr compressed_pair &operator=(const compressed_pair &other) = default; + + /** + * @brief Move assignment operator. + * @param other The instance to move from. + * @return This compressed pair object. + */ + constexpr compressed_pair &operator=(compressed_pair &&other) noexcept = default; + + /** + * @brief Returns the first element that a pair stores. + * @return The first element that a pair stores. + */ + [[nodiscard]] constexpr first_type &first() noexcept { + return static_cast(*this).get(); + } + + /*! @copydoc first */ + [[nodiscard]] constexpr const first_type &first() const noexcept { + return static_cast(*this).get(); + } + + /** + * @brief Returns the second element that a pair stores. + * @return The second element that a pair stores. + */ + [[nodiscard]] constexpr second_type &second() noexcept { + return static_cast(*this).get(); + } + + /*! @copydoc second */ + [[nodiscard]] constexpr const second_type &second() const noexcept { + return static_cast(*this).get(); + } + + /** + * @brief Swaps two compressed pair objects. + * @param other The compressed pair to swap with. + */ + constexpr void swap(compressed_pair &other) noexcept { + using std::swap; + swap(first(), other.first()); + swap(second(), other.second()); + } + + /** + * @brief Extracts an element from the compressed pair. + * @tparam Index An integer value that is either 0 or 1. + * @return Returns a reference to the first element if `Index` is 0 and a + * reference to the second element if `Index` is 1. + */ + template + [[nodiscard]] constexpr decltype(auto) get() noexcept { + if constexpr(Index == 0u) { + return first(); + } else { + static_assert(Index == 1u, "Index out of bounds"); + return second(); + } + } + + /*! @copydoc get */ + template + [[nodiscard]] constexpr decltype(auto) get() const noexcept { + if constexpr(Index == 0u) { + return first(); + } else { + static_assert(Index == 1u, "Index out of bounds"); + return second(); + } + } +}; + +/** + * @brief Deduction guide. + * @tparam Type Type of value to use to initialize the first element. + * @tparam Other Type of value to use to initialize the second element. + */ +template +compressed_pair(Type &&, Other &&) -> compressed_pair, std::decay_t>; + +/** + * @brief Swaps two compressed pair objects. + * @tparam First The type of the first element that the pairs store. + * @tparam Second The type of the second element that the pairs store. + * @param lhs A valid compressed pair object. + * @param rhs A valid compressed pair object. + */ +template +constexpr void swap(compressed_pair &lhs, compressed_pair &rhs) noexcept { + lhs.swap(rhs); +} + +} // namespace entt + +namespace std { + +/** + * @brief `std::tuple_size` specialization for `compressed_pair`s. + * @tparam First The type of the first element that the pair stores. + * @tparam Second The type of the second element that the pair stores. + */ +template +struct tuple_size>: integral_constant {}; + +/** + * @brief `std::tuple_element` specialization for `compressed_pair`s. + * @tparam Index The index of the type to return. + * @tparam First The type of the first element that the pair stores. + * @tparam Second The type of the second element that the pair stores. + */ +template +struct tuple_element>: conditional { + static_assert(Index < 2u, "Index out of bounds"); +}; + +} // namespace std + +#endif + +// #include "../core/type_traits.hpp" +#ifndef ENTT_CORE_TYPE_TRAITS_HPP +#define ENTT_CORE_TYPE_TRAITS_HPP + +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "fwd.hpp" + + +namespace entt { + +/** + * @brief Utility class to disambiguate overloaded functions. + * @tparam N Number of choices available. + */ +template +struct choice_t + // unfortunately, doxygen cannot parse such a construct + : /*! @cond TURN_OFF_DOXYGEN */ choice_t /*! @endcond */ +{}; + +/*! @copybrief choice_t */ +template<> +struct choice_t<0> {}; + +/** + * @brief Variable template for the choice trick. + * @tparam N Number of choices available. + */ +template +inline constexpr choice_t choice{}; + +/** + * @brief Identity type trait. + * + * Useful to establish non-deduced contexts in template argument deduction + * (waiting for C++20) or to provide types through function arguments. + * + * @tparam Type A type. + */ +template +struct type_identity { + /*! @brief Identity type. */ + using type = Type; +}; + +/** + * @brief Helper type. + * @tparam Type A type. + */ +template +using type_identity_t = typename type_identity::type; + +/** + * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains. + * @tparam Type The type of which to return the size. + */ +template +struct size_of: std::integral_constant {}; + +/*! @copydoc size_of */ +template +struct size_of> + // NOLINTNEXTLINE(bugprone-sizeof-expression) + : std::integral_constant {}; + +/** + * @brief Helper variable template. + * @tparam Type The type of which to return the size. + */ +template +inline constexpr std::size_t size_of_v = size_of::value; + +/** + * @brief Using declaration to be used to _repeat_ the same type a number of + * times equal to the size of a given parameter pack. + * @tparam Type A type to repeat. + */ +template +using unpack_as_type = Type; + +/** + * @brief Helper variable template to be used to _repeat_ the same value a + * number of times equal to the size of a given parameter pack. + * @tparam Value A value to repeat. + */ +template +inline constexpr auto unpack_as_value = Value; + +/** + * @brief Wraps a static constant. + * @tparam Value A static constant. + */ +template +using integral_constant = std::integral_constant; + +/** + * @brief Alias template to facilitate the creation of named values. + * @tparam Value A constant value at least convertible to `id_type`. + */ +template +using tag = integral_constant; + +/** + * @brief A class to use to push around lists of types, nothing more. + * @tparam Type Types provided by the type list. + */ +template +struct type_list { + /*! @brief Type list type. */ + using type = type_list; + /*! @brief Compile-time number of elements in the type list. */ + static constexpr auto size = sizeof...(Type); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_element; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Index Index of the type to return. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element> + : type_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element<0u, type_list> { + /*! @brief Searched type. */ + using type = First; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Type list to search into. + */ +template +using type_list_element_t = typename type_list_element::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_index; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 1u + type_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + static_assert(type_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +inline constexpr std::size_t type_list_index_v = type_list_index::value; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @return A type list composed by the types of both the type lists. + */ +template +constexpr type_list operator+(type_list, type_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_cat; + +/*! @brief Concatenates multiple type lists. */ +template<> +struct type_list_cat<> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list<>; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @tparam List Other type lists, if any. + */ +template +struct type_list_cat, type_list, List...> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = typename type_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the type list. + */ +template +struct type_list_cat> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list; +}; + +/** + * @brief Helper type. + * @tparam List Type lists to concatenate. + */ +template +using type_list_cat_t = typename type_list_cat::type; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct type_list_unique; + +template +struct type_list_unique, Type...> + : std::conditional_t<(std::is_same_v || ...), type_list_unique, Type...>, type_list_unique, Type..., First>> {}; + +template +struct type_list_unique, Type...> { + using type = type_list; +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Removes duplicates types from a type list. + * @tparam List Type list. + */ +template +struct type_list_unique { + /*! @brief A type list without duplicate types. */ + using type = typename internal::type_list_unique::type; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + */ +template +using type_list_unique_t = typename type_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a type list contains a + * given type, false otherwise. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +struct type_list_contains; + +/** + * @copybrief type_list_contains + * @tparam Type Types provided by the type list. + * @tparam Other Type to look for. + */ +template +struct type_list_contains, Other> + : std::bool_constant<(std::is_same_v || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +inline constexpr bool type_list_contains_v = type_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_diff; + +/** + * @brief Computes the difference between two type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + */ +template +struct type_list_diff, type_list> { + /*! @brief A type list that is the difference between the two type lists. */ + using type = type_list_cat_t, Type>, type_list<>, type_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Type lists between which to compute the difference. + */ +template +using type_list_diff_t = typename type_list_diff::type; + +/*! @brief Primary template isn't defined on purpose. */ +template class> +struct type_list_transform; + +/** + * @brief Applies a given _function_ to a type list and generate a new list. + * @tparam Type Types provided by the type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +struct type_list_transform, Op> { + /*! @brief Resulting type list after applying the transform function. */ + // NOLINTNEXTLINE(modernize-type-traits) + using type = type_list::type...>; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +using type_list_transform_t = typename type_list_transform::type; + +/** + * @brief A class to use to push around lists of constant values, nothing more. + * @tparam Value Values provided by the value list. + */ +template +struct value_list { + /*! @brief Value list type. */ + using type = value_list; + /*! @brief Compile-time number of elements in the value list. */ + static constexpr auto size = sizeof...(Value); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_element; + +/** + * @brief Provides compile-time indexed access to the values of a value list. + * @tparam Index Index of the value to return. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element> + : value_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element<0u, value_list> { + /*! @brief Searched type. */ + using type = decltype(Value); + /*! @brief Searched value. */ + static constexpr auto value = Value; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Value list to search into. + */ +template +using value_list_element_t = typename value_list_element::type; + +/** + * @brief Helper type. + * @tparam Index Index of the value to return. + * @tparam List Value list to search into. + */ +template +inline constexpr auto value_list_element_v = value_list_element::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_index; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam First First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 1u + value_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + static_assert(value_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +inline constexpr std::size_t value_list_index_v = value_list_index::value; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @return A value list composed by the values of both the value lists. + */ +template +constexpr value_list operator+(value_list, value_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_cat; + +/*! @brief Concatenates multiple value lists. */ +template<> +struct value_list_cat<> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list<>; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @tparam List Other value lists, if any. + */ +template +struct value_list_cat, value_list, List...> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = typename value_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the value list. + */ +template +struct value_list_cat> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list; +}; + +/** + * @brief Helper type. + * @tparam List Value lists to concatenate. + */ +template +using value_list_cat_t = typename value_list_cat::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_unique; + +/** + * @brief Removes duplicates values from a value list. + * @tparam Value One of the values provided by the given value list. + * @tparam Other The other values provided by the given value list. + */ +template +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = std::conditional_t< + ((Value == Other) || ...), + typename value_list_unique>::type, + value_list_cat_t, typename value_list_unique>::type>>; +}; + +/*! @brief Removes duplicates values from a value list. */ +template<> +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = value_list<>; +}; + +/** + * @brief Helper type. + * @tparam Type A value list. + */ +template +using value_list_unique_t = typename value_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a value list contains + * a given value, false otherwise. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +struct value_list_contains; + +/** + * @copybrief value_list_contains + * @tparam Value Values provided by the value list. + * @tparam Other Value to look for. + */ +template +struct value_list_contains, Other> + : std::bool_constant<((Value == Other) || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +inline constexpr bool value_list_contains_v = value_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_diff; + +/** + * @brief Computes the difference between two value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + */ +template +struct value_list_diff, value_list> { + /*! @brief A value list that is the difference between the two value lists. */ + using type = value_list_cat_t, Value>, value_list<>, value_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Value lists between which to compute the difference. + */ +template +using value_list_diff_t = typename value_list_diff::type; + +/*! @brief Same as std::is_invocable, but with tuples. */ +template +struct is_applicable: std::false_type {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @brief Helper variable template. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_v = is_applicable::value; + +/*! @brief Same as std::is_invocable_r, but with tuples for arguments. */ +template +struct is_applicable_r: std::false_type {}; + +/** + * @copybrief is_applicable_r + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +struct is_applicable_r>: std::is_invocable_r {}; + +/** + * @brief Helper variable template. + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_r_v = is_applicable_r::value; + +/** + * @brief Provides the member constant `value` to true if a given type is + * complete, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_complete: std::false_type {}; + +/*! @copydoc is_complete */ +template +struct is_complete>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_complete_v = is_complete::value; + +/** + * @brief Provides the member constant `value` to true if a given type is an + * iterator, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_iterator: std::false_type {}; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_iterator_category: std::false_type {}; + +template +struct has_iterator_category::iterator_category>>: std::true_type {}; + +} // namespace internal +/*! @endcond */ + +/*! @copydoc is_iterator */ +template +struct is_iterator>>>> + : internal::has_iterator_category {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_iterator_v = is_iterator::value; + +/** + * @brief Provides the member constant `value` to true if a given type is both + * an empty and non-final class, false otherwise. + * @tparam Type The type to test + */ +template +struct is_ebco_eligible + : std::bool_constant && !std::is_final_v> {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_ebco_eligible_v = is_ebco_eligible::value; + +/** + * @brief Provides the member constant `value` to true if `Type::is_transparent` + * is valid and denotes a type, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_transparent: std::false_type {}; + +/*! @copydoc is_transparent */ +template +struct is_transparent>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_transparent_v = is_transparent::value; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_tuple_size_value: std::false_type {}; + +template +struct has_tuple_size_value::value)>>: std::true_type {}; + +template +struct has_value_type: std::false_type {}; + +template +struct has_value_type>: std::true_type {}; + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable(); + +template +[[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence) { + return (dispatch_is_equality_comparable>() && ...); +} + +template +[[nodiscard]] constexpr bool maybe_equality_comparable(char) { + return false; +} + +template +[[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval() == std::declval()) { + return true; +} + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable() { + // NOLINTBEGIN(modernize-use-transparent-functors) + if constexpr(std::is_array_v) { + return false; + } else if constexpr(is_complete_v>>) { + if constexpr(has_tuple_size_value::value) { + return maybe_equality_comparable(0) && unpack_maybe_equality_comparable(std::make_index_sequence::value>{}); + } else { + return maybe_equality_comparable(0); + } + } else if constexpr(has_value_type::value) { + if constexpr(is_iterator_v || std::is_same_v || dispatch_is_equality_comparable()) { + return maybe_equality_comparable(0); + } else { + return false; + } + } else { + return maybe_equality_comparable(0); + } + // NOLINTEND(modernize-use-transparent-functors) +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Provides the member constant `value` to true if a given type is + * equality comparable, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_equality_comparable: std::bool_constant()> {}; + +/*! @copydoc is_equality_comparable */ +template +struct is_equality_comparable: is_equality_comparable {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_equality_comparable_v = is_equality_comparable::value; + +/** + * @brief Transcribes the constness of a type to another type. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = std::remove_const_t; +}; + +/*! @copydoc constness_as */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = const To; +}; + +/** + * @brief Alias template to facilitate the transcription of the constness. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +using constness_as_t = typename constness_as::type; + +/** + * @brief Extracts the class of a non-static member object or function. + * @tparam Member A pointer to a non-static member object or function. + */ +template +class member_class { + static_assert(std::is_member_pointer_v, "Invalid pointer type to non-static member object or function"); + + template + static Class *clazz(Ret (Class::*)(Args...)); + + template + static Class *clazz(Ret (Class::*)(Args...) const); + + template + static Class *clazz(Type Class::*); + +public: + /*! @brief The class of the given non-static member object or function. */ + using type = std::remove_pointer_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Member A pointer to a non-static member object or function. + */ +template +using member_class_t = typename member_class::type; + +/** + * @brief Extracts the n-th argument of a _callable_ type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid _callable_ type. + */ +template +class nth_argument { + template + static constexpr type_list pick_up(Ret (*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...) const); + + template + static constexpr type_list pick_up(Type Class ::*); + + template + static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&); + +public: + /*! @brief N-th argument of the _callable_ type. */ + using type = type_list_element_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid function, member function or data member type. + */ +template +using nth_argument_t = typename nth_argument::type; + +} // namespace entt + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::type_list_element> {}; + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::value_list_element> {}; + +#endif + +// #include "fwd.hpp" +#ifndef ENTT_PROCESS_FWD_HPP +#define ENTT_PROCESS_FWD_HPP + +#include +#include + +namespace entt { + +template> +class basic_process; + +/*! @brief Alias declaration for the most common use case. */ +using process = basic_process; + +template> +class basic_scheduler; + +/*! @brief Alias declaration for the most common use case. */ +using scheduler = basic_scheduler; + +} // namespace entt + +#endif + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct process_adaptor; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Base class for processes. + * + * Derived classes must specify what's the intended type for elapsed times.
+ * A process can implement the following member functions whether required: + * + * * @code{.cpp} + * void update(Delta, void *) override; + * @endcode + * + * It's invoked once per tick until a process is explicitly aborted or it + * terminates either with or without errors. Even though it's not mandatory to + * declare this member function, as a rule of thumb each process should at + * least define it to work properly. The `void *` parameter is an opaque + * pointer to user data (if any) forwarded directly to the process during an + * update. + * + * * @code{.cpp} + * void succeeded() override; + * @endcode + * + * It's invoked in case of success, immediately after an update and during the + * same tick. + * + * * @code{.cpp} + * void failed() override; + * @endcode + * + * It's invoked in case of errors, immediately after an update and during the + * same tick. + * + * * @code{.cpp} + * void aborted() override; + * @endcode + * + * It's invoked only if a process is explicitly aborted. There is no guarantee + * that it executes in the same tick, this depends solely on whether the + * process is aborted immediately or not. + * + * Derived classes can change the internal state of a process by invoking the + * `succeed` and `fail` member functions and even pause or unpause the process + * itself. + * + * @sa scheduler + * + * @tparam Delta Type to use to provide elapsed time. + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +class basic_process: public std::enable_shared_from_this> { + enum class state : std::uint8_t { + idle = 0, + running, + paused, + succeeded, + failed, + aborted, + finished, + rejected + }; + + virtual void update(const Delta, void *) { + abort(); + } + + virtual void succeeded() {} + virtual void failed() {} + virtual void aborted() {} + +public: + /*! @brief Allocator type. */ + using allocator_type = Allocator; + /*! @brief Type used to provide elapsed time. */ + using delta_type = Delta; + /*! @brief Handle type. */ + using handle_type = std::shared_ptr; + + /*! @brief Default constructor. */ + basic_process() + : basic_process{allocator_type{}} {} + + /** + * @brief Constructs a scheduler with a given allocator. + * @param allocator The allocator to use. + */ + explicit basic_process(const allocator_type &allocator) + : next{nullptr, allocator}, + current{state::idle} {} + + /*! @brief Default copy constructor, deleted on purpose. */ + basic_process(const basic_process &) = delete; + + /*! @brief Default move constructor, deleted on purpose. */ + basic_process(basic_process &&) = delete; + + /*! @brief Default destructor. */ + virtual ~basic_process() = default; + + /** + * @brief Default copy assignment operator, deleted on purpose. + * @return This process scheduler. + */ + basic_process &operator=(const basic_process &) = delete; + + /** + * @brief Default move assignment operator, deleted on purpose. + * @return This process scheduler. + */ + basic_process &operator=(basic_process &&) = delete; + + /** + * @brief Returns the associated allocator. + * @return The associated allocator. + */ + [[nodiscard]] constexpr allocator_type get_allocator() const noexcept { + return next.second(); + } + + /*! @brief Aborts a process if it's still alive, otherwise does nothing. */ + void abort() { + if(alive()) { + current = state::aborted; + } + } + + /** + * @brief Terminates a process with success if it's still alive, otherwise + * does nothing. + */ + void succeed() noexcept { + if(alive()) { + current = state::succeeded; + } + } + + /** + * @brief Terminates a process with errors if it's still alive, otherwise + * does nothing. + */ + void fail() noexcept { + if(alive()) { + current = state::failed; + } + } + + /*! @brief Stops a process if it's running, otherwise does nothing. */ + void pause() noexcept { + if(alive()) { + current = state::paused; + } + } + + /*! @brief Restarts a process if it's paused, otherwise does nothing. */ + void unpause() noexcept { + if(alive()) { + current = state::running; + } + } + + /** + * @brief Returns true if a process is either running or paused. + * @return True if the process is still alive, false otherwise. + */ + [[nodiscard]] bool alive() const noexcept { + return current == state::running || current == state::paused; + } + + /** + * @brief Returns true if a process is already terminated. + * @return True if the process is terminated, false otherwise. + */ + [[nodiscard]] bool finished() const noexcept { + return current == state::finished; + } + + /** + * @brief Returns true if a process is currently paused. + * @return True if the process is paused, false otherwise. + */ + [[nodiscard]] bool paused() const noexcept { + return current == state::paused; + } + + /** + * @brief Returns true if a process terminated with errors. + * @return True if the process terminated with errors, false otherwise. + */ + [[nodiscard]] bool rejected() const noexcept { + return current == state::rejected; + } + + /** + * @brief Assigns a child process to run in case of success. + * @tparam Type Type of child process to create. + * @tparam Args Types of arguments to use to initialize the child process. + * @param args Parameters to use to initialize the child process. + * @return A reference to the newly created child process. + */ + template + basic_process &then(Args &&...args) { + const auto &allocator = next.second(); + return *(next.first() = std::allocate_shared(allocator, allocator, std::forward(args)...)); + } + + /** + * @brief Assigns a child process to run in case of success. + * @tparam Func Type of child process to create. + * @param func Either a lambda or a functor to use as a child process. + * @return A reference to the newly created child process. + */ + template + basic_process &then(Func func) { + const auto &allocator = next.second(); + using process_type = internal::process_adaptor; + return *(next.first() = std::allocate_shared(allocator, allocator, std::move(func))); + } + + /** + * @brief Returns the child process without releasing ownership, if any. + * @return The child process attached to the object, if any. + */ + handle_type peek() { + return next.first(); + } + + /** + * @brief Updates a process and its internal state, if required. + * @param delta Elapsed time. + * @param data Optional data. + */ + void tick(const Delta delta, void *data = nullptr) { + switch(current) { + case state::idle: + case state::running: + current = state::running; + update(delta, data); + break; + default: + // suppress warnings + break; + } + + // if it's dead, it must be notified and removed immediately + switch(current) { + case state::succeeded: + succeeded(); + current = state::finished; + break; + case state::failed: + failed(); + current = state::rejected; + break; + case state::aborted: + aborted(); + current = state::rejected; + break; + default: + // suppress warnings + break; + } + } + +private: + compressed_pair next; + state current; +}; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct process_adaptor: public basic_process { + using allocator_type = Allocator; + using base_type = basic_process; + using delta_type = typename base_type::delta_type; + + process_adaptor(const allocator_type &allocator, Func proc) + : base_type{allocator}, + func{std::move(proc)} {} + + void update(const delta_type delta, void *data) override { + func(*this, delta, data); + } + +private: + Func func; +}; + +} // namespace internal +/*! @endcond */ + +} // namespace entt + +#endif + +// #include "process/scheduler.hpp" +#ifndef ENTT_PROCESS_SCHEDULER_HPP +#define ENTT_PROCESS_SCHEDULER_HPP + +#include +#include +#include +#include +#include +// #include "../config/config.h" +#ifndef ENTT_CONFIG_CONFIG_H +#define ENTT_CONFIG_CONFIG_H + +// #include "version.h" +#ifndef ENTT_CONFIG_VERSION_H +#define ENTT_CONFIG_VERSION_H + +// #include "macro.h" +#ifndef ENTT_CONFIG_MACRO_H +#define ENTT_CONFIG_MACRO_H + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#define ENTT_STR(arg) #arg +#define ENTT_XSTR(arg) ENTT_STR(arg) + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*) + +#define ENTT_VERSION_MAJOR 3 +#define ENTT_VERSION_MINOR 16 +#define ENTT_VERSION_PATCH 0 + +#define ENTT_VERSION \ + ENTT_XSTR(ENTT_VERSION_MAJOR) \ + "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH) + +// NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION) +# define ENTT_CONSTEXPR +# define ENTT_THROW throw +# define ENTT_TRY try +# define ENTT_CATCH catch(...) +#else +# define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20) +# define ENTT_THROW +# define ENTT_TRY if(true) +# define ENTT_CATCH if(false) +#endif + +#if __has_include() +# include +# +# if defined(__cpp_consteval) +# define ENTT_CONSTEVAL consteval +# endif +#endif + +#ifndef ENTT_CONSTEVAL +# define ENTT_CONSTEVAL constexpr +#endif + +#ifdef ENTT_USE_ATOMIC +# include +# define ENTT_MAYBE_ATOMIC(Type) std::atomic +#else +# define ENTT_MAYBE_ATOMIC(Type) Type +#endif + +#ifndef ENTT_ID_TYPE +# include +# define ENTT_ID_TYPE std::uint32_t +#else +# include // provides coverage for types in the std namespace +#endif + +#ifndef ENTT_SPARSE_PAGE +# define ENTT_SPARSE_PAGE 4096 +#endif + +#ifndef ENTT_PACKED_PAGE +# define ENTT_PACKED_PAGE 1024 +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT +# define ENTT_ASSERT(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT +# include +# define ENTT_ASSERT(condition, msg) assert(((condition) && (msg))) +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg) +#endif + +#define ENTT_FAIL(msg) ENTT_ASSERT(false, msg); + +#ifdef ENTT_NO_ETO +# define ENTT_ETO_TYPE(Type) void +#else +# define ENTT_ETO_TYPE(Type) Type +#endif + +#ifdef ENTT_NO_MIXIN +# define ENTT_STORAGE(Mixin, ...) __VA_ARGS__ +#else +# define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__> +#endif + +#ifdef ENTT_STANDARD_CPP +# define ENTT_NONSTD false +#else +# define ENTT_NONSTD true +# if defined __clang__ || defined __GNUC__ +# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ +# define ENTT_PRETTY_FUNCTION_PREFIX '=' +# define ENTT_PRETTY_FUNCTION_SUFFIX ']' +# elif defined _MSC_VER +# define ENTT_PRETTY_FUNCTION __FUNCSIG__ +# define ENTT_PRETTY_FUNCTION_PREFIX '<' +# define ENTT_PRETTY_FUNCTION_SUFFIX '>' +# endif +#endif + +#ifndef ENTT_EXPORT +# if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER +# define ENTT_EXPORT __declspec(dllexport) +# define ENTT_IMPORT __declspec(dllimport) +# define ENTT_HIDDEN +# elif defined __GNUC__ && __GNUC__ >= 4 +# define ENTT_EXPORT __attribute__((visibility("default"))) +# define ENTT_IMPORT __attribute__((visibility("default"))) +# define ENTT_HIDDEN __attribute__((visibility("hidden"))) +# else /* Unsupported compiler */ +# define ENTT_EXPORT +# define ENTT_IMPORT +# define ENTT_HIDDEN +# endif +#endif + +#ifndef ENTT_API +# if defined ENTT_API_EXPORT +# define ENTT_API ENTT_EXPORT +# elif defined ENTT_API_IMPORT +# define ENTT_API ENTT_IMPORT +# else /* No API */ +# define ENTT_API +# endif +#endif + +#if defined _MSC_VER +# pragma detect_mismatch("entt.version", ENTT_VERSION) +# pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY)) +# pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE)) +# pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD)) +#endif + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + +// #include "../core/compressed_pair.hpp" + +// #include "fwd.hpp" + +// #include "process.hpp" +#ifndef ENTT_PROCESS_PROCESS_HPP +#define ENTT_PROCESS_PROCESS_HPP + +#include +#include +#include +#include +// #include "../core/compressed_pair.hpp" + +// #include "../core/type_traits.hpp" + +// #include "fwd.hpp" + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct process_adaptor; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Base class for processes. + * + * Derived classes must specify what's the intended type for elapsed times.
+ * A process can implement the following member functions whether required: + * + * * @code{.cpp} + * void update(Delta, void *) override; + * @endcode + * + * It's invoked once per tick until a process is explicitly aborted or it + * terminates either with or without errors. Even though it's not mandatory to + * declare this member function, as a rule of thumb each process should at + * least define it to work properly. The `void *` parameter is an opaque + * pointer to user data (if any) forwarded directly to the process during an + * update. + * + * * @code{.cpp} + * void succeeded() override; + * @endcode + * + * It's invoked in case of success, immediately after an update and during the + * same tick. + * + * * @code{.cpp} + * void failed() override; + * @endcode + * + * It's invoked in case of errors, immediately after an update and during the + * same tick. + * + * * @code{.cpp} + * void aborted() override; + * @endcode + * + * It's invoked only if a process is explicitly aborted. There is no guarantee + * that it executes in the same tick, this depends solely on whether the + * process is aborted immediately or not. + * + * Derived classes can change the internal state of a process by invoking the + * `succeed` and `fail` member functions and even pause or unpause the process + * itself. + * + * @sa scheduler + * + * @tparam Delta Type to use to provide elapsed time. + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +class basic_process: public std::enable_shared_from_this> { + enum class state : std::uint8_t { + idle = 0, + running, + paused, + succeeded, + failed, + aborted, + finished, + rejected + }; + + virtual void update(const Delta, void *) { + abort(); + } + + virtual void succeeded() {} + virtual void failed() {} + virtual void aborted() {} + +public: + /*! @brief Allocator type. */ + using allocator_type = Allocator; + /*! @brief Type used to provide elapsed time. */ + using delta_type = Delta; + /*! @brief Handle type. */ + using handle_type = std::shared_ptr; + + /*! @brief Default constructor. */ + basic_process() + : basic_process{allocator_type{}} {} + + /** + * @brief Constructs a scheduler with a given allocator. + * @param allocator The allocator to use. + */ + explicit basic_process(const allocator_type &allocator) + : next{nullptr, allocator}, + current{state::idle} {} + + /*! @brief Default copy constructor, deleted on purpose. */ + basic_process(const basic_process &) = delete; + + /*! @brief Default move constructor, deleted on purpose. */ + basic_process(basic_process &&) = delete; + + /*! @brief Default destructor. */ + virtual ~basic_process() = default; + + /** + * @brief Default copy assignment operator, deleted on purpose. + * @return This process scheduler. + */ + basic_process &operator=(const basic_process &) = delete; + + /** + * @brief Default move assignment operator, deleted on purpose. + * @return This process scheduler. + */ + basic_process &operator=(basic_process &&) = delete; + + /** + * @brief Returns the associated allocator. + * @return The associated allocator. + */ + [[nodiscard]] constexpr allocator_type get_allocator() const noexcept { + return next.second(); + } + + /*! @brief Aborts a process if it's still alive, otherwise does nothing. */ + void abort() { + if(alive()) { + current = state::aborted; + } + } + + /** + * @brief Terminates a process with success if it's still alive, otherwise + * does nothing. + */ + void succeed() noexcept { + if(alive()) { + current = state::succeeded; + } + } + + /** + * @brief Terminates a process with errors if it's still alive, otherwise + * does nothing. + */ + void fail() noexcept { + if(alive()) { + current = state::failed; + } + } + + /*! @brief Stops a process if it's running, otherwise does nothing. */ + void pause() noexcept { + if(alive()) { + current = state::paused; + } + } + + /*! @brief Restarts a process if it's paused, otherwise does nothing. */ + void unpause() noexcept { + if(alive()) { + current = state::running; + } + } + + /** + * @brief Returns true if a process is either running or paused. + * @return True if the process is still alive, false otherwise. + */ + [[nodiscard]] bool alive() const noexcept { + return current == state::running || current == state::paused; + } + + /** + * @brief Returns true if a process is already terminated. + * @return True if the process is terminated, false otherwise. + */ + [[nodiscard]] bool finished() const noexcept { + return current == state::finished; + } + + /** + * @brief Returns true if a process is currently paused. + * @return True if the process is paused, false otherwise. + */ + [[nodiscard]] bool paused() const noexcept { + return current == state::paused; + } + + /** + * @brief Returns true if a process terminated with errors. + * @return True if the process terminated with errors, false otherwise. + */ + [[nodiscard]] bool rejected() const noexcept { + return current == state::rejected; + } + + /** + * @brief Assigns a child process to run in case of success. + * @tparam Type Type of child process to create. + * @tparam Args Types of arguments to use to initialize the child process. + * @param args Parameters to use to initialize the child process. + * @return A reference to the newly created child process. + */ + template + basic_process &then(Args &&...args) { + const auto &allocator = next.second(); + return *(next.first() = std::allocate_shared(allocator, allocator, std::forward(args)...)); + } + + /** + * @brief Assigns a child process to run in case of success. + * @tparam Func Type of child process to create. + * @param func Either a lambda or a functor to use as a child process. + * @return A reference to the newly created child process. + */ + template + basic_process &then(Func func) { + const auto &allocator = next.second(); + using process_type = internal::process_adaptor; + return *(next.first() = std::allocate_shared(allocator, allocator, std::move(func))); + } + + /** + * @brief Returns the child process without releasing ownership, if any. + * @return The child process attached to the object, if any. + */ + handle_type peek() { + return next.first(); + } + + /** + * @brief Updates a process and its internal state, if required. + * @param delta Elapsed time. + * @param data Optional data. + */ + void tick(const Delta delta, void *data = nullptr) { + switch(current) { + case state::idle: + case state::running: + current = state::running; + update(delta, data); + break; + default: + // suppress warnings + break; + } + + // if it's dead, it must be notified and removed immediately + switch(current) { + case state::succeeded: + succeeded(); + current = state::finished; + break; + case state::failed: + failed(); + current = state::rejected; + break; + case state::aborted: + aborted(); + current = state::rejected; + break; + default: + // suppress warnings + break; + } + } + +private: + compressed_pair next; + state current; +}; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct process_adaptor: public basic_process { + using allocator_type = Allocator; + using base_type = basic_process; + using delta_type = typename base_type::delta_type; + + process_adaptor(const allocator_type &allocator, Func proc) + : base_type{allocator}, + func{std::move(proc)} {} + + void update(const delta_type delta, void *data) override { + func(*this, delta, data); + } + +private: + Func func; +}; + +} // namespace internal +/*! @endcond */ + +} // namespace entt + +#endif + + +namespace entt { + +/** + * @brief Cooperative scheduler for processes. + * + * A cooperative scheduler runs processes and helps managing their life cycles. + * + * Each process is invoked once per tick. If a process terminates, it's + * removed automatically from the scheduler and it's never invoked again.
+ * A process can also have a child. In this case, the process is replaced with + * its child when it terminates if it returns with success. In case of errors, + * both the process and its child are discarded. + * + * In order to invoke all scheduled processes, call the `update` member function + * passing it the elapsed time to forward to the tasks. + * + * @sa process + * + * @tparam Delta Type to use to provide elapsed time. + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +class basic_scheduler { + using base_type = basic_process; + using alloc_traits = std::allocator_traits; + using container_allocator = typename alloc_traits::template rebind_alloc>; + using container_type = std::vector, container_allocator>; + +public: + /*! @brief Process type. */ + using type = base_type; + /*! @brief Allocator type. */ + using allocator_type = Allocator; + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + /*! @brief Unsigned integer type. */ + using delta_type = Delta; + + /*! @brief Default constructor. */ + basic_scheduler() + : basic_scheduler{allocator_type{}} {} + + /** + * @brief Constructs a scheduler with a given allocator. + * @param allocator The allocator to use. + */ + explicit basic_scheduler(const allocator_type &allocator) + : handlers{allocator, allocator} {} + + /*! @brief Default copy constructor, deleted on purpose. */ + basic_scheduler(const basic_scheduler &) = delete; + + /** + * @brief Move constructor. + * @param other The instance to move from. + */ + basic_scheduler(basic_scheduler &&other) noexcept + : handlers{std::move(other.handlers)} {} + + /** + * @brief Allocator-extended move constructor. + * @param other The instance to move from. + * @param allocator The allocator to use. + */ + basic_scheduler(basic_scheduler &&other, const allocator_type &allocator) + : handlers{container_type{std::move(other.handlers.first()), allocator}, allocator} { + ENTT_ASSERT(alloc_traits::is_always_equal::value || get_allocator() == other.get_allocator(), "Copying a scheduler is not allowed"); + } + + /*! @brief Default destructor. */ + ~basic_scheduler() = default; + + /** + * @brief Default copy assignment operator, deleted on purpose. + * @return This process scheduler. + */ + basic_scheduler &operator=(const basic_scheduler &) = delete; + + /** + * @brief Move assignment operator. + * @param other The instance to move from. + * @return This process scheduler. + */ + basic_scheduler &operator=(basic_scheduler &&other) noexcept { + ENTT_ASSERT(alloc_traits::is_always_equal::value || get_allocator() == other.get_allocator(), "Copying a scheduler is not allowed"); + swap(other); + return *this; + } + + /** + * @brief Exchanges the contents with those of a given scheduler. + * @param other Scheduler to exchange the content with. + */ + void swap(basic_scheduler &other) noexcept { + using std::swap; + swap(handlers, other.handlers); + } + + /** + * @brief Returns the associated allocator. + * @return The associated allocator. + */ + [[nodiscard]] constexpr allocator_type get_allocator() const noexcept { + return handlers.second(); + } + + /** + * @brief Number of processes currently scheduled. + * @return Number of processes currently scheduled. + */ + [[nodiscard]] size_type size() const noexcept { + return handlers.first().size(); + } + + /** + * @brief Returns true if at least a process is currently scheduled. + * @return True if there are scheduled processes, false otherwise. + */ + [[nodiscard]] bool empty() const noexcept { + return handlers.first().empty(); + } + + /** + * @brief Discards all scheduled processes. + * + * Processes aren't aborted. They are discarded along with their children + * and never executed again. + */ + void clear() { + handlers.first().clear(); + } + + /** + * @brief Schedules a process for the next tick. + * @tparam Type Type of process to create. + * @tparam Args Types of arguments to use to initialize the process. + * @param args Parameters to use to initialize the process. + * @return A reference to the newly created process. + */ + template + type &attach(Args &&...args) { + const auto &allocator = handlers.second(); + return *handlers.first().emplace_back(std::allocate_shared(allocator, allocator, std::forward(args)...)); + } + + /** + * @brief Schedules a process for the next tick. + * @tparam Func Type of process to create. + * @param func Either a lambda or a functor to use as a process. + * @return A reference to the newly created process. + */ + template + type &attach(Func func) { + const auto &allocator = handlers.second(); + using process_type = internal::process_adaptor; + return *handlers.first().emplace_back(std::allocate_shared(allocator, allocator, std::move(func))); + } + + /** + * @brief Updates all scheduled processes. + * + * All scheduled processes are executed in no specific order.
+ * If a process terminates with success, it's replaced with its child, if + * any. Otherwise, if a process terminates with an error, it's removed along + * with its child. + * + * @param delta Elapsed time. + * @param data Optional data. + */ + void update(const delta_type delta, void *data = nullptr) { + for(auto next = handlers.first().size(); next; --next) { + const auto pos = next - 1u; + handlers.first()[pos]->tick(delta, data); + // updating might spawn/reallocate, cannot hold refs until here + auto &elem = handlers.first()[pos]; + + if(elem->finished()) { + elem = elem->peek(); + } + + if(!elem || elem->rejected()) { + elem = std::move(handlers.first().back()); + handlers.first().pop_back(); + } + } + } + + /** + * @brief Aborts all scheduled processes. + * + * Unless an immediate operation is requested, the abort is scheduled for + * the next tick. Processes won't be executed anymore in any case.
+ * Once a process is fully aborted and thus finished, it's discarded along + * with its child, if any. + * + * @param immediate Requests an immediate operation. + */ + void abort(const bool immediate = false) { + for(auto &&curr: handlers.first()) { + curr->abort(); + + if(immediate) { + curr->tick({}); + } + } + } + +private: + compressed_pair handlers; +}; + +} // namespace entt + +#endif + +// #include "resource/cache.hpp" +#ifndef ENTT_RESOURCE_RESOURCE_CACHE_HPP +#define ENTT_RESOURCE_RESOURCE_CACHE_HPP + +#include +#include +#include +#include +#include +#include +#include +// #include "../container/dense_map.hpp" +#ifndef ENTT_CONTAINER_DENSE_MAP_HPP +#define ENTT_CONTAINER_DENSE_MAP_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #include "../config/config.h" +#ifndef ENTT_CONFIG_CONFIG_H +#define ENTT_CONFIG_CONFIG_H + +// #include "version.h" +#ifndef ENTT_CONFIG_VERSION_H +#define ENTT_CONFIG_VERSION_H + +// #include "macro.h" +#ifndef ENTT_CONFIG_MACRO_H +#define ENTT_CONFIG_MACRO_H + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#define ENTT_STR(arg) #arg +#define ENTT_XSTR(arg) ENTT_STR(arg) + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*) + +#define ENTT_VERSION_MAJOR 3 +#define ENTT_VERSION_MINOR 16 +#define ENTT_VERSION_PATCH 0 + +#define ENTT_VERSION \ + ENTT_XSTR(ENTT_VERSION_MAJOR) \ + "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH) + +// NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION) +# define ENTT_CONSTEXPR +# define ENTT_THROW throw +# define ENTT_TRY try +# define ENTT_CATCH catch(...) +#else +# define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20) +# define ENTT_THROW +# define ENTT_TRY if(true) +# define ENTT_CATCH if(false) +#endif + +#if __has_include() +# include +# +# if defined(__cpp_consteval) +# define ENTT_CONSTEVAL consteval +# endif +#endif + +#ifndef ENTT_CONSTEVAL +# define ENTT_CONSTEVAL constexpr +#endif + +#ifdef ENTT_USE_ATOMIC +# include +# define ENTT_MAYBE_ATOMIC(Type) std::atomic +#else +# define ENTT_MAYBE_ATOMIC(Type) Type +#endif + +#ifndef ENTT_ID_TYPE +# include +# define ENTT_ID_TYPE std::uint32_t +#else +# include // provides coverage for types in the std namespace +#endif + +#ifndef ENTT_SPARSE_PAGE +# define ENTT_SPARSE_PAGE 4096 +#endif + +#ifndef ENTT_PACKED_PAGE +# define ENTT_PACKED_PAGE 1024 +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT +# define ENTT_ASSERT(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT +# include +# define ENTT_ASSERT(condition, msg) assert(((condition) && (msg))) +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg) +#endif + +#define ENTT_FAIL(msg) ENTT_ASSERT(false, msg); + +#ifdef ENTT_NO_ETO +# define ENTT_ETO_TYPE(Type) void +#else +# define ENTT_ETO_TYPE(Type) Type +#endif + +#ifdef ENTT_NO_MIXIN +# define ENTT_STORAGE(Mixin, ...) __VA_ARGS__ +#else +# define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__> +#endif + +#ifdef ENTT_STANDARD_CPP +# define ENTT_NONSTD false +#else +# define ENTT_NONSTD true +# if defined __clang__ || defined __GNUC__ +# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ +# define ENTT_PRETTY_FUNCTION_PREFIX '=' +# define ENTT_PRETTY_FUNCTION_SUFFIX ']' +# elif defined _MSC_VER +# define ENTT_PRETTY_FUNCTION __FUNCSIG__ +# define ENTT_PRETTY_FUNCTION_PREFIX '<' +# define ENTT_PRETTY_FUNCTION_SUFFIX '>' +# endif +#endif + +#ifndef ENTT_EXPORT +# if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER +# define ENTT_EXPORT __declspec(dllexport) +# define ENTT_IMPORT __declspec(dllimport) +# define ENTT_HIDDEN +# elif defined __GNUC__ && __GNUC__ >= 4 +# define ENTT_EXPORT __attribute__((visibility("default"))) +# define ENTT_IMPORT __attribute__((visibility("default"))) +# define ENTT_HIDDEN __attribute__((visibility("hidden"))) +# else /* Unsupported compiler */ +# define ENTT_EXPORT +# define ENTT_IMPORT +# define ENTT_HIDDEN +# endif +#endif + +#ifndef ENTT_API +# if defined ENTT_API_EXPORT +# define ENTT_API ENTT_EXPORT +# elif defined ENTT_API_IMPORT +# define ENTT_API ENTT_IMPORT +# else /* No API */ +# define ENTT_API +# endif +#endif + +#if defined _MSC_VER +# pragma detect_mismatch("entt.version", ENTT_VERSION) +# pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY)) +# pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE)) +# pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD)) +#endif + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + +// #include "../core/bit.hpp" +#ifndef ENTT_CORE_BIT_HPP +#define ENTT_CORE_BIT_HPP + +#include +#include +#include +// #include "../config/config.h" +#ifndef ENTT_CONFIG_CONFIG_H +#define ENTT_CONFIG_CONFIG_H + +// #include "version.h" +#ifndef ENTT_CONFIG_VERSION_H +#define ENTT_CONFIG_VERSION_H + +// #include "macro.h" +#ifndef ENTT_CONFIG_MACRO_H +#define ENTT_CONFIG_MACRO_H + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#define ENTT_STR(arg) #arg +#define ENTT_XSTR(arg) ENTT_STR(arg) + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*) + +#define ENTT_VERSION_MAJOR 3 +#define ENTT_VERSION_MINOR 16 +#define ENTT_VERSION_PATCH 0 + +#define ENTT_VERSION \ + ENTT_XSTR(ENTT_VERSION_MAJOR) \ + "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH) + +// NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION) +# define ENTT_CONSTEXPR +# define ENTT_THROW throw +# define ENTT_TRY try +# define ENTT_CATCH catch(...) +#else +# define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20) +# define ENTT_THROW +# define ENTT_TRY if(true) +# define ENTT_CATCH if(false) +#endif + +#if __has_include() +# include +# +# if defined(__cpp_consteval) +# define ENTT_CONSTEVAL consteval +# endif +#endif + +#ifndef ENTT_CONSTEVAL +# define ENTT_CONSTEVAL constexpr +#endif + +#ifdef ENTT_USE_ATOMIC +# include +# define ENTT_MAYBE_ATOMIC(Type) std::atomic +#else +# define ENTT_MAYBE_ATOMIC(Type) Type +#endif + +#ifndef ENTT_ID_TYPE +# include +# define ENTT_ID_TYPE std::uint32_t +#else +# include // provides coverage for types in the std namespace +#endif + +#ifndef ENTT_SPARSE_PAGE +# define ENTT_SPARSE_PAGE 4096 +#endif + +#ifndef ENTT_PACKED_PAGE +# define ENTT_PACKED_PAGE 1024 +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT +# define ENTT_ASSERT(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT +# include +# define ENTT_ASSERT(condition, msg) assert(((condition) && (msg))) +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg) +#endif + +#define ENTT_FAIL(msg) ENTT_ASSERT(false, msg); + +#ifdef ENTT_NO_ETO +# define ENTT_ETO_TYPE(Type) void +#else +# define ENTT_ETO_TYPE(Type) Type +#endif + +#ifdef ENTT_NO_MIXIN +# define ENTT_STORAGE(Mixin, ...) __VA_ARGS__ +#else +# define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__> +#endif + +#ifdef ENTT_STANDARD_CPP +# define ENTT_NONSTD false +#else +# define ENTT_NONSTD true +# if defined __clang__ || defined __GNUC__ +# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ +# define ENTT_PRETTY_FUNCTION_PREFIX '=' +# define ENTT_PRETTY_FUNCTION_SUFFIX ']' +# elif defined _MSC_VER +# define ENTT_PRETTY_FUNCTION __FUNCSIG__ +# define ENTT_PRETTY_FUNCTION_PREFIX '<' +# define ENTT_PRETTY_FUNCTION_SUFFIX '>' +# endif +#endif + +#ifndef ENTT_EXPORT +# if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER +# define ENTT_EXPORT __declspec(dllexport) +# define ENTT_IMPORT __declspec(dllimport) +# define ENTT_HIDDEN +# elif defined __GNUC__ && __GNUC__ >= 4 +# define ENTT_EXPORT __attribute__((visibility("default"))) +# define ENTT_IMPORT __attribute__((visibility("default"))) +# define ENTT_HIDDEN __attribute__((visibility("hidden"))) +# else /* Unsupported compiler */ +# define ENTT_EXPORT +# define ENTT_IMPORT +# define ENTT_HIDDEN +# endif +#endif + +#ifndef ENTT_API +# if defined ENTT_API_EXPORT +# define ENTT_API ENTT_EXPORT +# elif defined ENTT_API_IMPORT +# define ENTT_API ENTT_IMPORT +# else /* No API */ +# define ENTT_API +# endif +#endif + +#if defined _MSC_VER +# pragma detect_mismatch("entt.version", ENTT_VERSION) +# pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY)) +# pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE)) +# pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD)) +#endif + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +namespace entt { + +/** + * @brief Returns the number of set bits in a value (waiting for C++20 and + * `std::popcount`). + * @tparam Type Unsigned integer type. + * @param value A value of unsigned integer type. + * @return The number of set bits in the value. + */ +template +[[nodiscard]] constexpr std::enable_if_t, int> popcount(const Type value) noexcept { + return value ? (int(value & 1) + popcount(static_cast(value >> 1))) : 0; +} + +/** + * @brief Checks whether a value is a power of two or not (waiting for C++20 and + * `std::has_single_bit`). + * @tparam Type Unsigned integer type. + * @param value A value of unsigned integer type. + * @return True if the value is a power of two, false otherwise. + */ +template +[[nodiscard]] constexpr std::enable_if_t, bool> has_single_bit(const Type value) noexcept { + return value && ((value & (value - 1)) == 0); +} + +/** + * @brief Computes the smallest power of two greater than or equal to a value + * (waiting for C++20 and `std::bit_ceil`). + * @tparam Type Unsigned integer type. + * @param value A value of unsigned integer type. + * @return The smallest power of two greater than or equal to the given value. + */ +template +[[nodiscard]] constexpr std::enable_if_t, Type> next_power_of_two(const Type value) noexcept { + // NOLINTNEXTLINE(bugprone-assert-side-effect) + ENTT_ASSERT_CONSTEXPR(value < (Type{1u} << (std::numeric_limits::digits - 1)), "Numeric limits exceeded"); + Type curr = value - (value != 0u); + + for(int next = 1; next < std::numeric_limits::digits; next = next * 2) { + curr |= (curr >> next); + } + + return ++curr; +} + +/** + * @brief Fast module utility function (powers of two only). + * @tparam Type Unsigned integer type. + * @param value A value of unsigned integer type. + * @param mod _Modulus_, it must be a power of two. + * @return The common remainder. + */ +template +[[nodiscard]] constexpr std::enable_if_t, Type> fast_mod(const Type value, const std::size_t mod) noexcept { + ENTT_ASSERT_CONSTEXPR(has_single_bit(mod), "Value must be a power of two"); + return static_cast(value & (mod - 1u)); +} + +} // namespace entt + +#endif + +// #include "../core/compressed_pair.hpp" +#ifndef ENTT_CORE_COMPRESSED_PAIR_HPP +#define ENTT_CORE_COMPRESSED_PAIR_HPP + +#include +#include +#include +#include +// #include "fwd.hpp" +#ifndef ENTT_CORE_FWD_HPP +#define ENTT_CORE_FWD_HPP + +#include +#include +// #include "../config/config.h" + + +namespace entt { + +/*! @brief Possible modes of an any object. */ +enum class any_policy : std::uint8_t { + /*! @brief Default mode, no element available. */ + empty, + /*! @brief Owning mode, dynamically allocated element. */ + dynamic, + /*! @brief Owning mode, embedded element. */ + embedded, + /*! @brief Aliasing mode, non-const reference. */ + ref, + /*! @brief Const aliasing mode, const reference. */ + cref +}; + +// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) +template +class basic_any; + +/*! @brief Alias declaration for type identifiers. */ +using id_type = ENTT_ID_TYPE; + +/*! @brief Alias declaration for the most common use case. */ +using any = basic_any<>; + +template +class compressed_pair; + +template +class basic_hashed_string; + +/*! @brief Aliases for common character types. */ +using hashed_string = basic_hashed_string; + +/*! @brief Aliases for common character types. */ +using hashed_wstring = basic_hashed_string; + +// NOLINTNEXTLINE(bugprone-forward-declaration-namespace) +struct type_info; + +} // namespace entt + +#endif + +// #include "type_traits.hpp" +#ifndef ENTT_CORE_TYPE_TRAITS_HPP +#define ENTT_CORE_TYPE_TRAITS_HPP + +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "fwd.hpp" + + +namespace entt { + +/** + * @brief Utility class to disambiguate overloaded functions. + * @tparam N Number of choices available. + */ +template +struct choice_t + // unfortunately, doxygen cannot parse such a construct + : /*! @cond TURN_OFF_DOXYGEN */ choice_t /*! @endcond */ +{}; + +/*! @copybrief choice_t */ +template<> +struct choice_t<0> {}; + +/** + * @brief Variable template for the choice trick. + * @tparam N Number of choices available. + */ +template +inline constexpr choice_t choice{}; + +/** + * @brief Identity type trait. + * + * Useful to establish non-deduced contexts in template argument deduction + * (waiting for C++20) or to provide types through function arguments. + * + * @tparam Type A type. + */ +template +struct type_identity { + /*! @brief Identity type. */ + using type = Type; +}; + +/** + * @brief Helper type. + * @tparam Type A type. + */ +template +using type_identity_t = typename type_identity::type; + +/** + * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains. + * @tparam Type The type of which to return the size. + */ +template +struct size_of: std::integral_constant {}; + +/*! @copydoc size_of */ +template +struct size_of> + // NOLINTNEXTLINE(bugprone-sizeof-expression) + : std::integral_constant {}; + +/** + * @brief Helper variable template. + * @tparam Type The type of which to return the size. + */ +template +inline constexpr std::size_t size_of_v = size_of::value; + +/** + * @brief Using declaration to be used to _repeat_ the same type a number of + * times equal to the size of a given parameter pack. + * @tparam Type A type to repeat. + */ +template +using unpack_as_type = Type; + +/** + * @brief Helper variable template to be used to _repeat_ the same value a + * number of times equal to the size of a given parameter pack. + * @tparam Value A value to repeat. + */ +template +inline constexpr auto unpack_as_value = Value; + +/** + * @brief Wraps a static constant. + * @tparam Value A static constant. + */ +template +using integral_constant = std::integral_constant; + +/** + * @brief Alias template to facilitate the creation of named values. + * @tparam Value A constant value at least convertible to `id_type`. + */ +template +using tag = integral_constant; + +/** + * @brief A class to use to push around lists of types, nothing more. + * @tparam Type Types provided by the type list. + */ +template +struct type_list { + /*! @brief Type list type. */ + using type = type_list; + /*! @brief Compile-time number of elements in the type list. */ + static constexpr auto size = sizeof...(Type); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_element; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Index Index of the type to return. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element> + : type_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element<0u, type_list> { + /*! @brief Searched type. */ + using type = First; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Type list to search into. + */ +template +using type_list_element_t = typename type_list_element::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_index; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 1u + type_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + static_assert(type_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +inline constexpr std::size_t type_list_index_v = type_list_index::value; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @return A type list composed by the types of both the type lists. + */ +template +constexpr type_list operator+(type_list, type_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_cat; + +/*! @brief Concatenates multiple type lists. */ +template<> +struct type_list_cat<> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list<>; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @tparam List Other type lists, if any. + */ +template +struct type_list_cat, type_list, List...> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = typename type_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the type list. + */ +template +struct type_list_cat> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list; +}; + +/** + * @brief Helper type. + * @tparam List Type lists to concatenate. + */ +template +using type_list_cat_t = typename type_list_cat::type; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct type_list_unique; + +template +struct type_list_unique, Type...> + : std::conditional_t<(std::is_same_v || ...), type_list_unique, Type...>, type_list_unique, Type..., First>> {}; + +template +struct type_list_unique, Type...> { + using type = type_list; +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Removes duplicates types from a type list. + * @tparam List Type list. + */ +template +struct type_list_unique { + /*! @brief A type list without duplicate types. */ + using type = typename internal::type_list_unique::type; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + */ +template +using type_list_unique_t = typename type_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a type list contains a + * given type, false otherwise. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +struct type_list_contains; + +/** + * @copybrief type_list_contains + * @tparam Type Types provided by the type list. + * @tparam Other Type to look for. + */ +template +struct type_list_contains, Other> + : std::bool_constant<(std::is_same_v || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +inline constexpr bool type_list_contains_v = type_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_diff; + +/** + * @brief Computes the difference between two type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + */ +template +struct type_list_diff, type_list> { + /*! @brief A type list that is the difference between the two type lists. */ + using type = type_list_cat_t, Type>, type_list<>, type_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Type lists between which to compute the difference. + */ +template +using type_list_diff_t = typename type_list_diff::type; + +/*! @brief Primary template isn't defined on purpose. */ +template class> +struct type_list_transform; + +/** + * @brief Applies a given _function_ to a type list and generate a new list. + * @tparam Type Types provided by the type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +struct type_list_transform, Op> { + /*! @brief Resulting type list after applying the transform function. */ + // NOLINTNEXTLINE(modernize-type-traits) + using type = type_list::type...>; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +using type_list_transform_t = typename type_list_transform::type; + +/** + * @brief A class to use to push around lists of constant values, nothing more. + * @tparam Value Values provided by the value list. + */ +template +struct value_list { + /*! @brief Value list type. */ + using type = value_list; + /*! @brief Compile-time number of elements in the value list. */ + static constexpr auto size = sizeof...(Value); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_element; + +/** + * @brief Provides compile-time indexed access to the values of a value list. + * @tparam Index Index of the value to return. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element> + : value_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element<0u, value_list> { + /*! @brief Searched type. */ + using type = decltype(Value); + /*! @brief Searched value. */ + static constexpr auto value = Value; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Value list to search into. + */ +template +using value_list_element_t = typename value_list_element::type; + +/** + * @brief Helper type. + * @tparam Index Index of the value to return. + * @tparam List Value list to search into. + */ +template +inline constexpr auto value_list_element_v = value_list_element::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_index; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam First First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 1u + value_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + static_assert(value_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +inline constexpr std::size_t value_list_index_v = value_list_index::value; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @return A value list composed by the values of both the value lists. + */ +template +constexpr value_list operator+(value_list, value_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_cat; + +/*! @brief Concatenates multiple value lists. */ +template<> +struct value_list_cat<> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list<>; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @tparam List Other value lists, if any. + */ +template +struct value_list_cat, value_list, List...> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = typename value_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the value list. + */ +template +struct value_list_cat> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list; +}; + +/** + * @brief Helper type. + * @tparam List Value lists to concatenate. + */ +template +using value_list_cat_t = typename value_list_cat::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_unique; + +/** + * @brief Removes duplicates values from a value list. + * @tparam Value One of the values provided by the given value list. + * @tparam Other The other values provided by the given value list. + */ +template +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = std::conditional_t< + ((Value == Other) || ...), + typename value_list_unique>::type, + value_list_cat_t, typename value_list_unique>::type>>; +}; + +/*! @brief Removes duplicates values from a value list. */ +template<> +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = value_list<>; +}; + +/** + * @brief Helper type. + * @tparam Type A value list. + */ +template +using value_list_unique_t = typename value_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a value list contains + * a given value, false otherwise. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +struct value_list_contains; + +/** + * @copybrief value_list_contains + * @tparam Value Values provided by the value list. + * @tparam Other Value to look for. + */ +template +struct value_list_contains, Other> + : std::bool_constant<((Value == Other) || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +inline constexpr bool value_list_contains_v = value_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_diff; + +/** + * @brief Computes the difference between two value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + */ +template +struct value_list_diff, value_list> { + /*! @brief A value list that is the difference between the two value lists. */ + using type = value_list_cat_t, Value>, value_list<>, value_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Value lists between which to compute the difference. + */ +template +using value_list_diff_t = typename value_list_diff::type; + +/*! @brief Same as std::is_invocable, but with tuples. */ +template +struct is_applicable: std::false_type {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @brief Helper variable template. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_v = is_applicable::value; + +/*! @brief Same as std::is_invocable_r, but with tuples for arguments. */ +template +struct is_applicable_r: std::false_type {}; + +/** + * @copybrief is_applicable_r + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +struct is_applicable_r>: std::is_invocable_r {}; + +/** + * @brief Helper variable template. + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_r_v = is_applicable_r::value; + +/** + * @brief Provides the member constant `value` to true if a given type is + * complete, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_complete: std::false_type {}; + +/*! @copydoc is_complete */ +template +struct is_complete>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_complete_v = is_complete::value; + +/** + * @brief Provides the member constant `value` to true if a given type is an + * iterator, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_iterator: std::false_type {}; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_iterator_category: std::false_type {}; + +template +struct has_iterator_category::iterator_category>>: std::true_type {}; + +} // namespace internal +/*! @endcond */ + +/*! @copydoc is_iterator */ +template +struct is_iterator>>>> + : internal::has_iterator_category {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_iterator_v = is_iterator::value; + +/** + * @brief Provides the member constant `value` to true if a given type is both + * an empty and non-final class, false otherwise. + * @tparam Type The type to test + */ +template +struct is_ebco_eligible + : std::bool_constant && !std::is_final_v> {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_ebco_eligible_v = is_ebco_eligible::value; + +/** + * @brief Provides the member constant `value` to true if `Type::is_transparent` + * is valid and denotes a type, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_transparent: std::false_type {}; + +/*! @copydoc is_transparent */ +template +struct is_transparent>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_transparent_v = is_transparent::value; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_tuple_size_value: std::false_type {}; + +template +struct has_tuple_size_value::value)>>: std::true_type {}; + +template +struct has_value_type: std::false_type {}; + +template +struct has_value_type>: std::true_type {}; + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable(); + +template +[[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence) { + return (dispatch_is_equality_comparable>() && ...); +} + +template +[[nodiscard]] constexpr bool maybe_equality_comparable(char) { + return false; +} + +template +[[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval() == std::declval()) { + return true; +} + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable() { + // NOLINTBEGIN(modernize-use-transparent-functors) + if constexpr(std::is_array_v) { + return false; + } else if constexpr(is_complete_v>>) { + if constexpr(has_tuple_size_value::value) { + return maybe_equality_comparable(0) && unpack_maybe_equality_comparable(std::make_index_sequence::value>{}); + } else { + return maybe_equality_comparable(0); + } + } else if constexpr(has_value_type::value) { + if constexpr(is_iterator_v || std::is_same_v || dispatch_is_equality_comparable()) { + return maybe_equality_comparable(0); + } else { + return false; + } + } else { + return maybe_equality_comparable(0); + } + // NOLINTEND(modernize-use-transparent-functors) +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Provides the member constant `value` to true if a given type is + * equality comparable, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_equality_comparable: std::bool_constant()> {}; + +/*! @copydoc is_equality_comparable */ +template +struct is_equality_comparable: is_equality_comparable {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_equality_comparable_v = is_equality_comparable::value; + +/** + * @brief Transcribes the constness of a type to another type. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = std::remove_const_t; +}; + +/*! @copydoc constness_as */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = const To; +}; + +/** + * @brief Alias template to facilitate the transcription of the constness. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +using constness_as_t = typename constness_as::type; + +/** + * @brief Extracts the class of a non-static member object or function. + * @tparam Member A pointer to a non-static member object or function. + */ +template +class member_class { + static_assert(std::is_member_pointer_v, "Invalid pointer type to non-static member object or function"); + + template + static Class *clazz(Ret (Class::*)(Args...)); + + template + static Class *clazz(Ret (Class::*)(Args...) const); + + template + static Class *clazz(Type Class::*); + +public: + /*! @brief The class of the given non-static member object or function. */ + using type = std::remove_pointer_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Member A pointer to a non-static member object or function. + */ +template +using member_class_t = typename member_class::type; + +/** + * @brief Extracts the n-th argument of a _callable_ type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid _callable_ type. + */ +template +class nth_argument { + template + static constexpr type_list pick_up(Ret (*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...) const); + + template + static constexpr type_list pick_up(Type Class ::*); + + template + static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&); + +public: + /*! @brief N-th argument of the _callable_ type. */ + using type = type_list_element_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid function, member function or data member type. + */ +template +using nth_argument_t = typename nth_argument::type; + +} // namespace entt + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::type_list_element> {}; + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::value_list_element> {}; + +#endif + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct compressed_pair_element { + using reference = Type &; + using const_reference = const Type &; + + template>> + // NOLINTNEXTLINE(modernize-use-equals-default) + constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v) {} + + template>, compressed_pair_element>>> + constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v) + : value{std::forward(arg)} {} + + template + constexpr compressed_pair_element(std::tuple args, std::index_sequence) noexcept(std::is_nothrow_constructible_v) + : value{std::forward(std::get(args))...} {} + + [[nodiscard]] constexpr reference get() noexcept { + return value; + } + + [[nodiscard]] constexpr const_reference get() const noexcept { + return value; + } + +private: + Type value{}; +}; + +template +struct compressed_pair_element>>: Type { + using reference = Type &; + using const_reference = const Type &; + using base_type = Type; + + template>> + constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v) + : base_type{} {} + + template>, compressed_pair_element>>> + constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v) + : base_type{std::forward(arg)} {} + + template + constexpr compressed_pair_element(std::tuple args, std::index_sequence) noexcept(std::is_nothrow_constructible_v) + : base_type{std::forward(std::get(args))...} {} + + [[nodiscard]] constexpr reference get() noexcept { + return *this; + } + + [[nodiscard]] constexpr const_reference get() const noexcept { + return *this; + } +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief A compressed pair. + * + * A pair that exploits the _Empty Base Class Optimization_ (or _EBCO_) to + * reduce its final size to a minimum. + * + * @tparam First The type of the first element that the pair stores. + * @tparam Second The type of the second element that the pair stores. + */ +template +class compressed_pair final + : internal::compressed_pair_element, + internal::compressed_pair_element { + using first_base = internal::compressed_pair_element; + using second_base = internal::compressed_pair_element; + +public: + /*! @brief The type of the first element that the pair stores. */ + using first_type = First; + /*! @brief The type of the second element that the pair stores. */ + using second_type = Second; + + /** + * @brief Default constructor, conditionally enabled. + * + * This constructor is only available when the types that the pair stores + * are both at least default constructible. + * + * @tparam Dummy Dummy template parameter used for internal purposes. + */ + template && std::is_default_constructible_v>> + constexpr compressed_pair() noexcept(std::is_nothrow_default_constructible_v && std::is_nothrow_default_constructible_v) + : first_base{}, + second_base{} {} + + /** + * @brief Copy constructor. + * @param other The instance to copy from. + */ + constexpr compressed_pair(const compressed_pair &other) = default; + + /** + * @brief Move constructor. + * @param other The instance to move from. + */ + constexpr compressed_pair(compressed_pair &&other) noexcept = default; + + /** + * @brief Constructs a pair from its values. + * @tparam Arg Type of value to use to initialize the first element. + * @tparam Other Type of value to use to initialize the second element. + * @param arg Value to use to initialize the first element. + * @param other Value to use to initialize the second element. + */ + template + constexpr compressed_pair(Arg &&arg, Other &&other) noexcept(std::is_nothrow_constructible_v && std::is_nothrow_constructible_v) + : first_base{std::forward(arg)}, + second_base{std::forward(other)} {} + + /** + * @brief Constructs a pair by forwarding the arguments to its parts. + * @tparam Args Types of arguments to use to initialize the first element. + * @tparam Other Types of arguments to use to initialize the second element. + * @param args Arguments to use to initialize the first element. + * @param other Arguments to use to initialize the second element. + */ + template + constexpr compressed_pair(std::piecewise_construct_t, std::tuple args, std::tuple other) noexcept(std::is_nothrow_constructible_v && std::is_nothrow_constructible_v) + : first_base{std::move(args), std::index_sequence_for{}}, + second_base{std::move(other), std::index_sequence_for{}} {} + + /*! @brief Default destructor. */ + ~compressed_pair() = default; + + /** + * @brief Copy assignment operator. + * @param other The instance to copy from. + * @return This compressed pair object. + */ + constexpr compressed_pair &operator=(const compressed_pair &other) = default; + + /** + * @brief Move assignment operator. + * @param other The instance to move from. + * @return This compressed pair object. + */ + constexpr compressed_pair &operator=(compressed_pair &&other) noexcept = default; + + /** + * @brief Returns the first element that a pair stores. + * @return The first element that a pair stores. + */ + [[nodiscard]] constexpr first_type &first() noexcept { + return static_cast(*this).get(); + } + + /*! @copydoc first */ + [[nodiscard]] constexpr const first_type &first() const noexcept { + return static_cast(*this).get(); + } + + /** + * @brief Returns the second element that a pair stores. + * @return The second element that a pair stores. + */ + [[nodiscard]] constexpr second_type &second() noexcept { + return static_cast(*this).get(); + } + + /*! @copydoc second */ + [[nodiscard]] constexpr const second_type &second() const noexcept { + return static_cast(*this).get(); + } + + /** + * @brief Swaps two compressed pair objects. + * @param other The compressed pair to swap with. + */ + constexpr void swap(compressed_pair &other) noexcept { + using std::swap; + swap(first(), other.first()); + swap(second(), other.second()); + } + + /** + * @brief Extracts an element from the compressed pair. + * @tparam Index An integer value that is either 0 or 1. + * @return Returns a reference to the first element if `Index` is 0 and a + * reference to the second element if `Index` is 1. + */ + template + [[nodiscard]] constexpr decltype(auto) get() noexcept { + if constexpr(Index == 0u) { + return first(); + } else { + static_assert(Index == 1u, "Index out of bounds"); + return second(); + } + } + + /*! @copydoc get */ + template + [[nodiscard]] constexpr decltype(auto) get() const noexcept { + if constexpr(Index == 0u) { + return first(); + } else { + static_assert(Index == 1u, "Index out of bounds"); + return second(); + } + } +}; + +/** + * @brief Deduction guide. + * @tparam Type Type of value to use to initialize the first element. + * @tparam Other Type of value to use to initialize the second element. + */ +template +compressed_pair(Type &&, Other &&) -> compressed_pair, std::decay_t>; + +/** + * @brief Swaps two compressed pair objects. + * @tparam First The type of the first element that the pairs store. + * @tparam Second The type of the second element that the pairs store. + * @param lhs A valid compressed pair object. + * @param rhs A valid compressed pair object. + */ +template +constexpr void swap(compressed_pair &lhs, compressed_pair &rhs) noexcept { + lhs.swap(rhs); +} + +} // namespace entt + +namespace std { + +/** + * @brief `std::tuple_size` specialization for `compressed_pair`s. + * @tparam First The type of the first element that the pair stores. + * @tparam Second The type of the second element that the pair stores. + */ +template +struct tuple_size>: integral_constant {}; + +/** + * @brief `std::tuple_element` specialization for `compressed_pair`s. + * @tparam Index The index of the type to return. + * @tparam First The type of the first element that the pair stores. + * @tparam Second The type of the second element that the pair stores. + */ +template +struct tuple_element>: conditional { + static_assert(Index < 2u, "Index out of bounds"); +}; + +} // namespace std + +#endif + +// #include "../core/iterator.hpp" +#ifndef ENTT_CORE_ITERATOR_HPP +#define ENTT_CORE_ITERATOR_HPP + +#include +#include +#include +#include + +namespace entt { + +/** + * @brief Helper type to use as pointer with input iterators. + * @tparam Type of wrapped value. + */ +template +struct input_iterator_pointer final { + /*! @brief Value type. */ + using value_type = Type; + /*! @brief Pointer type. */ + using pointer = Type *; + /*! @brief Reference type. */ + using reference = Type &; + + /** + * @brief Constructs a proxy object by move. + * @param val Value to use to initialize the proxy object. + */ + constexpr input_iterator_pointer(value_type &&val) noexcept(std::is_nothrow_move_constructible_v) + : value{std::move(val)} {} + + /** + * @brief Access operator for accessing wrapped values. + * @return A pointer to the wrapped value. + */ + [[nodiscard]] constexpr pointer operator->() noexcept { + return std::addressof(value); + } + + /** + * @brief Dereference operator for accessing wrapped values. + * @return A reference to the wrapped value. + */ + [[nodiscard]] constexpr reference operator*() noexcept { + return value; + } + +private: + Type value; +}; + +/** + * @brief Plain iota iterator (waiting for C++20). + * @tparam Type Value type. + */ +template +class iota_iterator final { + static_assert(std::is_integral_v, "Not an integral type"); + +public: + /*! @brief Value type, likely an integral one. */ + using value_type = Type; + /*! @brief Invalid pointer type. */ + using pointer = void; + /*! @brief Non-reference type, same as value type. */ + using reference = value_type; + /*! @brief Difference type. */ + using difference_type = std::ptrdiff_t; + /*! @brief Iterator category. */ + using iterator_category = std::input_iterator_tag; + + /*! @brief Default constructor. */ + constexpr iota_iterator() noexcept + : current{} {} + + /** + * @brief Constructs an iota iterator from a given value. + * @param init The initial value assigned to the iota iterator. + */ + constexpr iota_iterator(const value_type init) noexcept + : current{init} {} + + /** + * @brief Pre-increment operator. + * @return This iota iterator. + */ + constexpr iota_iterator &operator++() noexcept { + return ++current, *this; + } + + /** + * @brief Post-increment operator. + * @return This iota iterator. + */ + constexpr iota_iterator operator++(int) noexcept { + const iota_iterator orig = *this; + return ++(*this), orig; + } + + /** + * @brief Dereference operator. + * @return The underlying value. + */ + [[nodiscard]] constexpr reference operator*() const noexcept { + return current; + } + +private: + value_type current; +}; + +/** + * @brief Comparison operator. + * @tparam Type Value type of the iota iterator. + * @param lhs A properly initialized iota iterator. + * @param rhs A properly initialized iota iterator. + * @return True if the two iterators are identical, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator==(const iota_iterator &lhs, const iota_iterator &rhs) noexcept { + return *lhs == *rhs; +} + +/** + * @brief Comparison operator. + * @tparam Type Value type of the iota iterator. + * @param lhs A properly initialized iota iterator. + * @param rhs A properly initialized iota iterator. + * @return True if the two iterators differ, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator!=(const iota_iterator &lhs, const iota_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +/** + * @brief Utility class to create an iterable object from a pair of iterators. + * @tparam It Type of iterator. + * @tparam Sentinel Type of sentinel. + */ +template +struct iterable_adaptor final { + /*! @brief Value type. */ + using value_type = typename std::iterator_traits::value_type; + /*! @brief Iterator type. */ + using iterator = It; + /*! @brief Sentinel type. */ + using sentinel = Sentinel; + + /*! @brief Default constructor. */ + constexpr iterable_adaptor() noexcept(std::is_nothrow_default_constructible_v && std::is_nothrow_default_constructible_v) + : first{}, + last{} {} + + /** + * @brief Creates an iterable object from a pair of iterators. + * @param from Begin iterator. + * @param to End iterator. + */ + constexpr iterable_adaptor(iterator from, sentinel to) noexcept(std::is_nothrow_move_constructible_v && std::is_nothrow_move_constructible_v) + : first{std::move(from)}, + last{std::move(to)} {} + + /** + * @brief Returns an iterator to the beginning. + * @return An iterator to the first element of the range. + */ + [[nodiscard]] constexpr iterator begin() const noexcept { + return first; + } + + /** + * @brief Returns an iterator to the end. + * @return An iterator to the element following the last element of the + * range. + */ + [[nodiscard]] constexpr sentinel end() const noexcept { + return last; + } + + /*! @copydoc begin */ + [[nodiscard]] constexpr iterator cbegin() const noexcept { + return begin(); + } + + /*! @copydoc end */ + [[nodiscard]] constexpr sentinel cend() const noexcept { + return end(); + } + +private: + It first; + Sentinel last; +}; + +} // namespace entt + +#endif + +// #include "../core/memory.hpp" +#ifndef ENTT_CORE_MEMORY_HPP +#define ENTT_CORE_MEMORY_HPP + +#include +#include +#include +#include +#include +// #include "../config/config.h" + + +namespace entt { + +/** + * @brief Unwraps fancy pointers, does nothing otherwise (waiting for C++20). + * @tparam Type Pointer type. + * @param ptr Fancy or raw pointer. + * @return A raw pointer that represents the address of the original pointer. + */ +template +[[nodiscard]] constexpr auto to_address(Type &&ptr) noexcept { + if constexpr(std::is_pointer_v>) { + return ptr; + } else { + return to_address(std::forward(ptr).operator->()); + } +} + +/** + * @brief Utility function to design allocation-aware containers. + * @tparam Allocator Type of allocator. + * @param lhs A valid allocator. + * @param rhs Another valid allocator. + */ +template +constexpr void propagate_on_container_copy_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept { + if constexpr(std::allocator_traits::propagate_on_container_copy_assignment::value) { + lhs = rhs; + } +} + +/** + * @brief Utility function to design allocation-aware containers. + * @tparam Allocator Type of allocator. + * @param lhs A valid allocator. + * @param rhs Another valid allocator. + */ +template +constexpr void propagate_on_container_move_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept { + if constexpr(std::allocator_traits::propagate_on_container_move_assignment::value) { + lhs = std::move(rhs); + } +} + +/** + * @brief Utility function to design allocation-aware containers. + * @tparam Allocator Type of allocator. + * @param lhs A valid allocator. + * @param rhs Another valid allocator. + */ +template +constexpr void propagate_on_container_swap([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept { + if constexpr(std::allocator_traits::propagate_on_container_swap::value) { + using std::swap; + swap(lhs, rhs); + } else { + ENTT_ASSERT_CONSTEXPR(lhs == rhs, "Cannot swap the containers"); + } +} + +/** + * @brief Deleter for allocator-aware unique pointers (waiting for C++20). + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +struct allocation_deleter: private Allocator { + /*! @brief Allocator type. */ + using allocator_type = Allocator; + /*! @brief Pointer type. */ + using pointer = typename std::allocator_traits::pointer; + + /** + * @brief Inherited constructors. + * @param alloc The allocator to use. + */ + constexpr allocation_deleter(const allocator_type &alloc) noexcept(std::is_nothrow_copy_constructible_v) + : Allocator{alloc} {} + + /** + * @brief Destroys the pointed object and deallocates its memory. + * @param ptr A valid pointer to an object of the given type. + */ + constexpr void operator()(pointer ptr) noexcept(std::is_nothrow_destructible_v) { + using alloc_traits = std::allocator_traits; + alloc_traits::destroy(*this, to_address(ptr)); + alloc_traits::deallocate(*this, ptr, 1u); + } +}; + +/** + * @brief Allows `std::unique_ptr` to use allocators (waiting for C++20). + * @tparam Type Type of object to allocate for and to construct. + * @tparam Allocator Type of allocator used to manage memory and elements. + * @tparam Args Types of arguments to use to construct the object. + * @param allocator The allocator to use. + * @param args Parameters to use to construct the object. + * @return A properly initialized unique pointer with a custom deleter. + */ +template +ENTT_CONSTEXPR auto allocate_unique(Allocator &allocator, Args &&...args) { + static_assert(!std::is_array_v, "Array types are not supported"); + + using alloc_traits = typename std::allocator_traits::template rebind_traits; + using allocator_type = typename alloc_traits::allocator_type; + + allocator_type alloc{allocator}; + auto ptr = alloc_traits::allocate(alloc, 1u); + + ENTT_TRY { + alloc_traits::construct(alloc, to_address(ptr), std::forward(args)...); + } + ENTT_CATCH { + alloc_traits::deallocate(alloc, ptr, 1u); + ENTT_THROW; + } + + return std::unique_ptr>{ptr, alloc}; +} + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct uses_allocator_construction { + template + static constexpr auto args([[maybe_unused]] const Allocator &allocator, Params &&...params) noexcept { + if constexpr(!std::uses_allocator_v && std::is_constructible_v) { + return std::forward_as_tuple(std::forward(params)...); + } else { + static_assert(std::uses_allocator_v, "Ill-formed request"); + + if constexpr(std::is_constructible_v) { + return std::tuple{std::allocator_arg, allocator, std::forward(params)...}; + } else { + static_assert(std::is_constructible_v, "Ill-formed request"); + return std::forward_as_tuple(std::forward(params)..., allocator); + } + } + } +}; + +template +struct uses_allocator_construction> { + using type = std::pair; + + template + static constexpr auto args(const Allocator &allocator, std::piecewise_construct_t, First &&first, Second &&second) noexcept { + return std::make_tuple( + std::piecewise_construct, + std::apply([&allocator](auto &&...curr) { return uses_allocator_construction::args(allocator, std::forward(curr)...); }, std::forward(first)), + std::apply([&allocator](auto &&...curr) { return uses_allocator_construction::args(allocator, std::forward(curr)...); }, std::forward(second))); + } + + template + static constexpr auto args(const Allocator &allocator) noexcept { + return uses_allocator_construction::args(allocator, std::piecewise_construct, std::tuple<>{}, std::tuple<>{}); + } + + template + static constexpr auto args(const Allocator &allocator, First &&first, Second &&second) noexcept { + return uses_allocator_construction::args(allocator, std::piecewise_construct, std::forward_as_tuple(std::forward(first)), std::forward_as_tuple(std::forward(second))); + } + + template + static constexpr auto args(const Allocator &allocator, const std::pair &value) noexcept { + return uses_allocator_construction::args(allocator, std::piecewise_construct, std::forward_as_tuple(value.first), std::forward_as_tuple(value.second)); + } + + template + static constexpr auto args(const Allocator &allocator, std::pair &&value) noexcept { + return uses_allocator_construction::args(allocator, std::piecewise_construct, std::forward_as_tuple(std::move(value.first)), std::forward_as_tuple(std::move(value.second))); + } +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Uses-allocator construction utility (waiting for C++20). + * + * Primarily intended for internal use. Prepares the argument list needed to + * create an object of a given type by means of uses-allocator construction. + * + * @tparam Type Type to return arguments for. + * @tparam Allocator Type of allocator used to manage memory and elements. + * @tparam Args Types of arguments to use to construct the object. + * @param allocator The allocator to use. + * @param args Parameters to use to construct the object. + * @return The arguments needed to create an object of the given type. + */ +template +constexpr auto uses_allocator_construction_args(const Allocator &allocator, Args &&...args) noexcept { + return internal::uses_allocator_construction::args(allocator, std::forward(args)...); +} + +/** + * @brief Uses-allocator construction utility (waiting for C++20). + * + * Primarily intended for internal use. Creates an object of a given type by + * means of uses-allocator construction. + * + * @tparam Type Type of object to create. + * @tparam Allocator Type of allocator used to manage memory and elements. + * @tparam Args Types of arguments to use to construct the object. + * @param allocator The allocator to use. + * @param args Parameters to use to construct the object. + * @return A newly created object of the given type. + */ +template +constexpr Type make_obj_using_allocator(const Allocator &allocator, Args &&...args) { + return std::make_from_tuple(internal::uses_allocator_construction::args(allocator, std::forward(args)...)); +} + +/** + * @brief Uses-allocator construction utility (waiting for C++20). + * + * Primarily intended for internal use. Creates an object of a given type by + * means of uses-allocator construction at an uninitialized memory location. + * + * @tparam Type Type of object to create. + * @tparam Allocator Type of allocator used to manage memory and elements. + * @tparam Args Types of arguments to use to construct the object. + * @param value Memory location in which to place the object. + * @param allocator The allocator to use. + * @param args Parameters to use to construct the object. + * @return A pointer to the newly created object of the given type. + */ +template +constexpr Type *uninitialized_construct_using_allocator(Type *value, const Allocator &allocator, Args &&...args) { + return std::apply([value](auto &&...curr) { return ::new(value) Type(std::forward(curr)...); }, internal::uses_allocator_construction::args(allocator, std::forward(args)...)); +} + +} // namespace entt + +#endif + +// #include "../core/type_traits.hpp" +#ifndef ENTT_CORE_TYPE_TRAITS_HPP +#define ENTT_CORE_TYPE_TRAITS_HPP + +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "fwd.hpp" + + +namespace entt { + +/** + * @brief Utility class to disambiguate overloaded functions. + * @tparam N Number of choices available. + */ +template +struct choice_t + // unfortunately, doxygen cannot parse such a construct + : /*! @cond TURN_OFF_DOXYGEN */ choice_t /*! @endcond */ +{}; + +/*! @copybrief choice_t */ +template<> +struct choice_t<0> {}; + +/** + * @brief Variable template for the choice trick. + * @tparam N Number of choices available. + */ +template +inline constexpr choice_t choice{}; + +/** + * @brief Identity type trait. + * + * Useful to establish non-deduced contexts in template argument deduction + * (waiting for C++20) or to provide types through function arguments. + * + * @tparam Type A type. + */ +template +struct type_identity { + /*! @brief Identity type. */ + using type = Type; +}; + +/** + * @brief Helper type. + * @tparam Type A type. + */ +template +using type_identity_t = typename type_identity::type; + +/** + * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains. + * @tparam Type The type of which to return the size. + */ +template +struct size_of: std::integral_constant {}; + +/*! @copydoc size_of */ +template +struct size_of> + // NOLINTNEXTLINE(bugprone-sizeof-expression) + : std::integral_constant {}; + +/** + * @brief Helper variable template. + * @tparam Type The type of which to return the size. + */ +template +inline constexpr std::size_t size_of_v = size_of::value; + +/** + * @brief Using declaration to be used to _repeat_ the same type a number of + * times equal to the size of a given parameter pack. + * @tparam Type A type to repeat. + */ +template +using unpack_as_type = Type; + +/** + * @brief Helper variable template to be used to _repeat_ the same value a + * number of times equal to the size of a given parameter pack. + * @tparam Value A value to repeat. + */ +template +inline constexpr auto unpack_as_value = Value; + +/** + * @brief Wraps a static constant. + * @tparam Value A static constant. + */ +template +using integral_constant = std::integral_constant; + +/** + * @brief Alias template to facilitate the creation of named values. + * @tparam Value A constant value at least convertible to `id_type`. + */ +template +using tag = integral_constant; + +/** + * @brief A class to use to push around lists of types, nothing more. + * @tparam Type Types provided by the type list. + */ +template +struct type_list { + /*! @brief Type list type. */ + using type = type_list; + /*! @brief Compile-time number of elements in the type list. */ + static constexpr auto size = sizeof...(Type); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_element; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Index Index of the type to return. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element> + : type_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element<0u, type_list> { + /*! @brief Searched type. */ + using type = First; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Type list to search into. + */ +template +using type_list_element_t = typename type_list_element::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_index; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 1u + type_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + static_assert(type_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +inline constexpr std::size_t type_list_index_v = type_list_index::value; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @return A type list composed by the types of both the type lists. + */ +template +constexpr type_list operator+(type_list, type_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_cat; + +/*! @brief Concatenates multiple type lists. */ +template<> +struct type_list_cat<> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list<>; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @tparam List Other type lists, if any. + */ +template +struct type_list_cat, type_list, List...> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = typename type_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the type list. + */ +template +struct type_list_cat> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list; +}; + +/** + * @brief Helper type. + * @tparam List Type lists to concatenate. + */ +template +using type_list_cat_t = typename type_list_cat::type; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct type_list_unique; + +template +struct type_list_unique, Type...> + : std::conditional_t<(std::is_same_v || ...), type_list_unique, Type...>, type_list_unique, Type..., First>> {}; + +template +struct type_list_unique, Type...> { + using type = type_list; +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Removes duplicates types from a type list. + * @tparam List Type list. + */ +template +struct type_list_unique { + /*! @brief A type list without duplicate types. */ + using type = typename internal::type_list_unique::type; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + */ +template +using type_list_unique_t = typename type_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a type list contains a + * given type, false otherwise. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +struct type_list_contains; + +/** + * @copybrief type_list_contains + * @tparam Type Types provided by the type list. + * @tparam Other Type to look for. + */ +template +struct type_list_contains, Other> + : std::bool_constant<(std::is_same_v || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +inline constexpr bool type_list_contains_v = type_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_diff; + +/** + * @brief Computes the difference between two type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + */ +template +struct type_list_diff, type_list> { + /*! @brief A type list that is the difference between the two type lists. */ + using type = type_list_cat_t, Type>, type_list<>, type_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Type lists between which to compute the difference. + */ +template +using type_list_diff_t = typename type_list_diff::type; + +/*! @brief Primary template isn't defined on purpose. */ +template class> +struct type_list_transform; + +/** + * @brief Applies a given _function_ to a type list and generate a new list. + * @tparam Type Types provided by the type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +struct type_list_transform, Op> { + /*! @brief Resulting type list after applying the transform function. */ + // NOLINTNEXTLINE(modernize-type-traits) + using type = type_list::type...>; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +using type_list_transform_t = typename type_list_transform::type; + +/** + * @brief A class to use to push around lists of constant values, nothing more. + * @tparam Value Values provided by the value list. + */ +template +struct value_list { + /*! @brief Value list type. */ + using type = value_list; + /*! @brief Compile-time number of elements in the value list. */ + static constexpr auto size = sizeof...(Value); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_element; + +/** + * @brief Provides compile-time indexed access to the values of a value list. + * @tparam Index Index of the value to return. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element> + : value_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element<0u, value_list> { + /*! @brief Searched type. */ + using type = decltype(Value); + /*! @brief Searched value. */ + static constexpr auto value = Value; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Value list to search into. + */ +template +using value_list_element_t = typename value_list_element::type; + +/** + * @brief Helper type. + * @tparam Index Index of the value to return. + * @tparam List Value list to search into. + */ +template +inline constexpr auto value_list_element_v = value_list_element::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_index; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam First First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 1u + value_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + static_assert(value_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +inline constexpr std::size_t value_list_index_v = value_list_index::value; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @return A value list composed by the values of both the value lists. + */ +template +constexpr value_list operator+(value_list, value_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_cat; + +/*! @brief Concatenates multiple value lists. */ +template<> +struct value_list_cat<> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list<>; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @tparam List Other value lists, if any. + */ +template +struct value_list_cat, value_list, List...> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = typename value_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the value list. + */ +template +struct value_list_cat> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list; +}; + +/** + * @brief Helper type. + * @tparam List Value lists to concatenate. + */ +template +using value_list_cat_t = typename value_list_cat::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_unique; + +/** + * @brief Removes duplicates values from a value list. + * @tparam Value One of the values provided by the given value list. + * @tparam Other The other values provided by the given value list. + */ +template +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = std::conditional_t< + ((Value == Other) || ...), + typename value_list_unique>::type, + value_list_cat_t, typename value_list_unique>::type>>; +}; + +/*! @brief Removes duplicates values from a value list. */ +template<> +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = value_list<>; +}; + +/** + * @brief Helper type. + * @tparam Type A value list. + */ +template +using value_list_unique_t = typename value_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a value list contains + * a given value, false otherwise. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +struct value_list_contains; + +/** + * @copybrief value_list_contains + * @tparam Value Values provided by the value list. + * @tparam Other Value to look for. + */ +template +struct value_list_contains, Other> + : std::bool_constant<((Value == Other) || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +inline constexpr bool value_list_contains_v = value_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_diff; + +/** + * @brief Computes the difference between two value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + */ +template +struct value_list_diff, value_list> { + /*! @brief A value list that is the difference between the two value lists. */ + using type = value_list_cat_t, Value>, value_list<>, value_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Value lists between which to compute the difference. + */ +template +using value_list_diff_t = typename value_list_diff::type; + +/*! @brief Same as std::is_invocable, but with tuples. */ +template +struct is_applicable: std::false_type {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @brief Helper variable template. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_v = is_applicable::value; + +/*! @brief Same as std::is_invocable_r, but with tuples for arguments. */ +template +struct is_applicable_r: std::false_type {}; + +/** + * @copybrief is_applicable_r + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +struct is_applicable_r>: std::is_invocable_r {}; + +/** + * @brief Helper variable template. + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_r_v = is_applicable_r::value; + +/** + * @brief Provides the member constant `value` to true if a given type is + * complete, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_complete: std::false_type {}; + +/*! @copydoc is_complete */ +template +struct is_complete>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_complete_v = is_complete::value; + +/** + * @brief Provides the member constant `value` to true if a given type is an + * iterator, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_iterator: std::false_type {}; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_iterator_category: std::false_type {}; + +template +struct has_iterator_category::iterator_category>>: std::true_type {}; + +} // namespace internal +/*! @endcond */ + +/*! @copydoc is_iterator */ +template +struct is_iterator>>>> + : internal::has_iterator_category {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_iterator_v = is_iterator::value; + +/** + * @brief Provides the member constant `value` to true if a given type is both + * an empty and non-final class, false otherwise. + * @tparam Type The type to test + */ +template +struct is_ebco_eligible + : std::bool_constant && !std::is_final_v> {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_ebco_eligible_v = is_ebco_eligible::value; + +/** + * @brief Provides the member constant `value` to true if `Type::is_transparent` + * is valid and denotes a type, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_transparent: std::false_type {}; + +/*! @copydoc is_transparent */ +template +struct is_transparent>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_transparent_v = is_transparent::value; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_tuple_size_value: std::false_type {}; + +template +struct has_tuple_size_value::value)>>: std::true_type {}; + +template +struct has_value_type: std::false_type {}; + +template +struct has_value_type>: std::true_type {}; + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable(); + +template +[[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence) { + return (dispatch_is_equality_comparable>() && ...); +} + +template +[[nodiscard]] constexpr bool maybe_equality_comparable(char) { + return false; +} + +template +[[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval() == std::declval()) { + return true; +} + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable() { + // NOLINTBEGIN(modernize-use-transparent-functors) + if constexpr(std::is_array_v) { + return false; + } else if constexpr(is_complete_v>>) { + if constexpr(has_tuple_size_value::value) { + return maybe_equality_comparable(0) && unpack_maybe_equality_comparable(std::make_index_sequence::value>{}); + } else { + return maybe_equality_comparable(0); + } + } else if constexpr(has_value_type::value) { + if constexpr(is_iterator_v || std::is_same_v || dispatch_is_equality_comparable()) { + return maybe_equality_comparable(0); + } else { + return false; + } + } else { + return maybe_equality_comparable(0); + } + // NOLINTEND(modernize-use-transparent-functors) +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Provides the member constant `value` to true if a given type is + * equality comparable, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_equality_comparable: std::bool_constant()> {}; + +/*! @copydoc is_equality_comparable */ +template +struct is_equality_comparable: is_equality_comparable {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_equality_comparable_v = is_equality_comparable::value; + +/** + * @brief Transcribes the constness of a type to another type. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = std::remove_const_t; +}; + +/*! @copydoc constness_as */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = const To; +}; + +/** + * @brief Alias template to facilitate the transcription of the constness. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +using constness_as_t = typename constness_as::type; + +/** + * @brief Extracts the class of a non-static member object or function. + * @tparam Member A pointer to a non-static member object or function. + */ +template +class member_class { + static_assert(std::is_member_pointer_v, "Invalid pointer type to non-static member object or function"); + + template + static Class *clazz(Ret (Class::*)(Args...)); + + template + static Class *clazz(Ret (Class::*)(Args...) const); + + template + static Class *clazz(Type Class::*); + +public: + /*! @brief The class of the given non-static member object or function. */ + using type = std::remove_pointer_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Member A pointer to a non-static member object or function. + */ +template +using member_class_t = typename member_class::type; + +/** + * @brief Extracts the n-th argument of a _callable_ type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid _callable_ type. + */ +template +class nth_argument { + template + static constexpr type_list pick_up(Ret (*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...) const); + + template + static constexpr type_list pick_up(Type Class ::*); + + template + static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&); + +public: + /*! @brief N-th argument of the _callable_ type. */ + using type = type_list_element_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid function, member function or data member type. + */ +template +using nth_argument_t = typename nth_argument::type; + +} // namespace entt + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::type_list_element> {}; + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::value_list_element> {}; + +#endif + +// #include "fwd.hpp" +#ifndef ENTT_CONTAINER_FWD_HPP +#define ENTT_CONTAINER_FWD_HPP + +#include +#include +#include +#include + +namespace entt { + +template< + typename Key, + typename Type, + typename = std::hash, + typename = std::equal_to<>, + typename = std::allocator>> +class dense_map; + +template< + typename Type, + typename = std::hash, + typename = std::equal_to<>, + typename = std::allocator> +class dense_set; + +template +class basic_table; + +/** + * @brief Alias declaration for the most common use case. + * @tparam Type Element types. + */ +template +using table = basic_table...>; + +} // namespace entt + +#endif + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +static constexpr std::size_t dense_map_placeholder_position = (std::numeric_limits::max)(); + +template +struct dense_map_node final { + using value_type = std::pair; + + template + dense_map_node(const std::size_t pos, Args &&...args) + : next{pos}, + element{std::forward(args)...} {} + + template + dense_map_node(std::allocator_arg_t, const Allocator &allocator, const std::size_t pos, Args &&...args) + : next{pos}, + element{entt::make_obj_using_allocator(allocator, std::forward(args)...)} {} + + template + dense_map_node(std::allocator_arg_t, const Allocator &allocator, const dense_map_node &other) + : next{other.next}, + element{entt::make_obj_using_allocator(allocator, other.element)} {} + + template + dense_map_node(std::allocator_arg_t, const Allocator &allocator, dense_map_node &&other) + : next{other.next}, + element{entt::make_obj_using_allocator(allocator, std::move(other.element))} {} + + std::size_t next; + value_type element; +}; + +template +class dense_map_iterator final { + template + friend class dense_map_iterator; + + using first_type = decltype(std::as_const(std::declval()->element.first)); + using second_type = decltype((std::declval()->element.second)); + +public: + using value_type = std::pair; + using pointer = input_iterator_pointer; + using reference = value_type; + using difference_type = std::ptrdiff_t; + using iterator_category = std::input_iterator_tag; + using iterator_concept = std::random_access_iterator_tag; + + constexpr dense_map_iterator() noexcept + : it{} {} + + constexpr dense_map_iterator(const It iter) noexcept + : it{iter} {} + + template && std::is_constructible_v>> + constexpr dense_map_iterator(const dense_map_iterator &other) noexcept + : it{other.it} {} + + constexpr dense_map_iterator &operator++() noexcept { + return ++it, *this; + } + + constexpr dense_map_iterator operator++(int) noexcept { + const dense_map_iterator orig = *this; + return ++(*this), orig; + } + + constexpr dense_map_iterator &operator--() noexcept { + return --it, *this; + } + + constexpr dense_map_iterator operator--(int) noexcept { + const dense_map_iterator orig = *this; + return operator--(), orig; + } + + constexpr dense_map_iterator &operator+=(const difference_type value) noexcept { + it += value; + return *this; + } + + constexpr dense_map_iterator operator+(const difference_type value) const noexcept { + dense_map_iterator copy = *this; + return (copy += value); + } + + constexpr dense_map_iterator &operator-=(const difference_type value) noexcept { + return (*this += -value); + } + + constexpr dense_map_iterator operator-(const difference_type value) const noexcept { + return (*this + -value); + } + + [[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept { + return {it[value].element.first, it[value].element.second}; + } + + [[nodiscard]] constexpr pointer operator->() const noexcept { + return operator*(); + } + + [[nodiscard]] constexpr reference operator*() const noexcept { + return operator[](0); + } + + template + friend constexpr std::ptrdiff_t operator-(const dense_map_iterator &, const dense_map_iterator &) noexcept; + + template + friend constexpr bool operator==(const dense_map_iterator &, const dense_map_iterator &) noexcept; + + template + friend constexpr bool operator<(const dense_map_iterator &, const dense_map_iterator &) noexcept; + +private: + It it; +}; + +template +[[nodiscard]] constexpr std::ptrdiff_t operator-(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return lhs.it - rhs.it; +} + +template +[[nodiscard]] constexpr bool operator==(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return lhs.it == rhs.it; +} + +template +[[nodiscard]] constexpr bool operator!=(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +template +[[nodiscard]] constexpr bool operator<(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return lhs.it < rhs.it; +} + +template +[[nodiscard]] constexpr bool operator>(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return rhs < lhs; +} + +template +[[nodiscard]] constexpr bool operator<=(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return !(lhs > rhs); +} + +template +[[nodiscard]] constexpr bool operator>=(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return !(lhs < rhs); +} + +template +class dense_map_local_iterator final { + template + friend class dense_map_local_iterator; + + using first_type = decltype(std::as_const(std::declval()->element.first)); + using second_type = decltype((std::declval()->element.second)); + +public: + using value_type = std::pair; + using pointer = input_iterator_pointer; + using reference = value_type; + using difference_type = std::ptrdiff_t; + using iterator_category = std::input_iterator_tag; + using iterator_concept = std::forward_iterator_tag; + + constexpr dense_map_local_iterator() noexcept = default; + + constexpr dense_map_local_iterator(It iter, const std::size_t pos) noexcept + : it{iter}, + offset{pos} {} + + template && std::is_constructible_v>> + constexpr dense_map_local_iterator(const dense_map_local_iterator &other) noexcept + : it{other.it}, + offset{other.offset} {} + + constexpr dense_map_local_iterator &operator++() noexcept { + return (offset = it[static_cast(offset)].next), *this; + } + + constexpr dense_map_local_iterator operator++(int) noexcept { + const dense_map_local_iterator orig = *this; + return ++(*this), orig; + } + + [[nodiscard]] constexpr pointer operator->() const noexcept { + return operator*(); + } + + [[nodiscard]] constexpr reference operator*() const noexcept { + const auto idx = static_cast(offset); + return {it[idx].element.first, it[idx].element.second}; + } + + [[nodiscard]] constexpr std::size_t index() const noexcept { + return offset; + } + +private: + It it{}; + std::size_t offset{dense_map_placeholder_position}; +}; + +template +[[nodiscard]] constexpr bool operator==(const dense_map_local_iterator &lhs, const dense_map_local_iterator &rhs) noexcept { + return lhs.index() == rhs.index(); +} + +template +[[nodiscard]] constexpr bool operator!=(const dense_map_local_iterator &lhs, const dense_map_local_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Associative container for key-value pairs with unique keys. + * + * Internally, elements are organized into buckets. Which bucket an element is + * placed into depends entirely on the hash of its key. Keys with the same hash + * code appear in the same bucket. + * + * @tparam Key Key type of the associative container. + * @tparam Type Mapped type of the associative container. + * @tparam Hash Type of function to use to hash the keys. + * @tparam KeyEqual Type of function to use to compare the keys for equality. + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +class dense_map { + static constexpr float default_threshold = 0.875f; + static constexpr std::size_t minimum_capacity = 8u; + static constexpr std::size_t placeholder_position = internal::dense_map_placeholder_position; + + using node_type = internal::dense_map_node; + using alloc_traits = std::allocator_traits; + static_assert(std::is_same_v>, "Invalid value type"); + using sparse_container_type = std::vector>; + using packed_container_type = std::vector>; + + template + [[nodiscard]] std::size_t key_to_bucket(const Other &key) const noexcept { + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay) + return fast_mod(static_cast(sparse.second()(key)), bucket_count()); + } + + template + [[nodiscard]] auto constrained_find(const Other &key, const std::size_t bucket) { + for(auto offset = sparse.first()[bucket]; offset != placeholder_position; offset = packed.first()[offset].next) { + if(packed.second()(packed.first()[offset].element.first, key)) { + return begin() + static_cast(offset); + } + } + + return end(); + } + + template + [[nodiscard]] auto constrained_find(const Other &key, const std::size_t bucket) const { + for(auto offset = sparse.first()[bucket]; offset != placeholder_position; offset = packed.first()[offset].next) { + if(packed.second()(packed.first()[offset].element.first, key)) { + return cbegin() + static_cast(offset); + } + } + + return cend(); + } + + template + [[nodiscard]] auto insert_or_do_nothing(Other &&key, Args &&...args) { + const auto index = key_to_bucket(key); + + if(auto it = constrained_find(key, index); it != end()) { + return std::make_pair(it, false); + } + + packed.first().emplace_back(sparse.first()[index], std::piecewise_construct, std::forward_as_tuple(std::forward(key)), std::forward_as_tuple(std::forward(args)...)); + sparse.first()[index] = packed.first().size() - 1u; + rehash_if_required(); + + return std::make_pair(--end(), true); + } + + template + [[nodiscard]] auto insert_or_overwrite(Other &&key, Arg &&value) { + const auto index = key_to_bucket(key); + + if(auto it = constrained_find(key, index); it != end()) { + it->second = std::forward(value); + return std::make_pair(it, false); + } + + packed.first().emplace_back(sparse.first()[index], std::forward(key), std::forward(value)); + sparse.first()[index] = packed.first().size() - 1u; + rehash_if_required(); + + return std::make_pair(--end(), true); + } + + void move_and_pop(const std::size_t pos) { + if(const auto last = size() - 1u; pos != last) { + size_type *curr = &sparse.first()[key_to_bucket(packed.first().back().element.first)]; + packed.first()[pos] = std::move(packed.first().back()); + for(; *curr != last; curr = &packed.first()[*curr].next) {} + *curr = pos; + } + + packed.first().pop_back(); + } + + void rehash_if_required() { + if(const auto bc = bucket_count(); size() > static_cast(static_cast(bc) * max_load_factor())) { + rehash(bc * 2u); + } + } + +public: + /*! @brief Allocator type. */ + using allocator_type = Allocator; + /*! @brief Key type of the container. */ + using key_type = Key; + /*! @brief Mapped type of the container. */ + using mapped_type = Type; + /*! @brief Key-value type of the container. */ + using value_type = std::pair; + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + /*! @brief Signed integer type. */ + using difference_type = std::ptrdiff_t; + /*! @brief Type of function to use to hash the keys. */ + using hasher = Hash; + /*! @brief Type of function to use to compare the keys for equality. */ + using key_equal = KeyEqual; + /*! @brief Input iterator type. */ + using iterator = internal::dense_map_iterator; + /*! @brief Constant input iterator type. */ + using const_iterator = internal::dense_map_iterator; + /*! @brief Input iterator type. */ + using local_iterator = internal::dense_map_local_iterator; + /*! @brief Constant input iterator type. */ + using const_local_iterator = internal::dense_map_local_iterator; + + /*! @brief Default constructor. */ + dense_map() + : dense_map{minimum_capacity} {} + + /** + * @brief Constructs an empty container with a given allocator. + * @param allocator The allocator to use. + */ + explicit dense_map(const allocator_type &allocator) + : dense_map{minimum_capacity, hasher{}, key_equal{}, allocator} {} + + /** + * @brief Constructs an empty container with a given allocator and user + * supplied minimal number of buckets. + * @param cnt Minimal number of buckets. + * @param allocator The allocator to use. + */ + dense_map(const size_type cnt, const allocator_type &allocator) + : dense_map{cnt, hasher{}, key_equal{}, allocator} {} + + /** + * @brief Constructs an empty container with a given allocator, hash + * function and user supplied minimal number of buckets. + * @param cnt Minimal number of buckets. + * @param hash Hash function to use. + * @param allocator The allocator to use. + */ + dense_map(const size_type cnt, const hasher &hash, const allocator_type &allocator) + : dense_map{cnt, hash, key_equal{}, allocator} {} + + /** + * @brief Constructs an empty container with a given allocator, hash + * function, compare function and user supplied minimal number of buckets. + * @param cnt Minimal number of buckets. + * @param hash Hash function to use. + * @param equal Compare function to use. + * @param allocator The allocator to use. + */ + explicit dense_map(const size_type cnt, const hasher &hash = hasher{}, const key_equal &equal = key_equal{}, const allocator_type &allocator = allocator_type{}) + : sparse{allocator, hash}, + packed{allocator, equal} { + rehash(cnt); + } + + /*! @brief Default copy constructor. */ + dense_map(const dense_map &) = default; + + /** + * @brief Allocator-extended copy constructor. + * @param other The instance to copy from. + * @param allocator The allocator to use. + */ + dense_map(const dense_map &other, const allocator_type &allocator) + : sparse{std::piecewise_construct, std::forward_as_tuple(other.sparse.first(), allocator), std::forward_as_tuple(other.sparse.second())}, + packed{std::piecewise_construct, std::forward_as_tuple(other.packed.first(), allocator), std::forward_as_tuple(other.packed.second())}, + threshold{other.threshold} {} + + /*! @brief Default move constructor. */ + dense_map(dense_map &&) noexcept = default; + + /** + * @brief Allocator-extended move constructor. + * @param other The instance to move from. + * @param allocator The allocator to use. + */ + dense_map(dense_map &&other, const allocator_type &allocator) + : sparse{std::piecewise_construct, std::forward_as_tuple(std::move(other.sparse.first()), allocator), std::forward_as_tuple(std::move(other.sparse.second()))}, + packed{std::piecewise_construct, std::forward_as_tuple(std::move(other.packed.first()), allocator), std::forward_as_tuple(std::move(other.packed.second()))}, + threshold{other.threshold} {} + + /*! @brief Default destructor. */ + ~dense_map() = default; + + /** + * @brief Default copy assignment operator. + * @return This container. + */ + dense_map &operator=(const dense_map &) = default; + + /** + * @brief Default move assignment operator. + * @return This container. + */ + dense_map &operator=(dense_map &&) noexcept = default; + + /** + * @brief Exchanges the contents with those of a given container. + * @param other Container to exchange the content with. + */ + void swap(dense_map &other) noexcept { + using std::swap; + swap(sparse, other.sparse); + swap(packed, other.packed); + swap(threshold, other.threshold); + } + + /** + * @brief Returns the associated allocator. + * @return The associated allocator. + */ + [[nodiscard]] constexpr allocator_type get_allocator() const noexcept { + return sparse.first().get_allocator(); + } + + /** + * @brief Returns an iterator to the beginning. + * + * If the array is empty, the returned iterator will be equal to `end()`. + * + * @return An iterator to the first instance of the internal array. + */ + [[nodiscard]] const_iterator cbegin() const noexcept { + return packed.first().begin(); + } + + /*! @copydoc cbegin */ + [[nodiscard]] const_iterator begin() const noexcept { + return cbegin(); + } + + /*! @copydoc begin */ + [[nodiscard]] iterator begin() noexcept { + return packed.first().begin(); + } + + /** + * @brief Returns an iterator to the end. + * @return An iterator to the element following the last instance of the + * internal array. + */ + [[nodiscard]] const_iterator cend() const noexcept { + return packed.first().end(); + } + + /*! @copydoc cend */ + [[nodiscard]] const_iterator end() const noexcept { + return cend(); + } + + /*! @copydoc end */ + [[nodiscard]] iterator end() noexcept { + return packed.first().end(); + } + + /** + * @brief Checks whether a container is empty. + * @return True if the container is empty, false otherwise. + */ + [[nodiscard]] bool empty() const noexcept { + return packed.first().empty(); + } + + /** + * @brief Returns the number of elements in a container. + * @return Number of elements in a container. + */ + [[nodiscard]] size_type size() const noexcept { + return packed.first().size(); + } + + /** + * @brief Returns the maximum possible number of elements. + * @return Maximum possible number of elements. + */ + [[nodiscard]] size_type max_size() const noexcept { + return packed.first().max_size(); + } + + /*! @brief Clears the container. */ + void clear() noexcept { + sparse.first().clear(); + packed.first().clear(); + rehash(0u); + } + + /** + * @brief Inserts an element into the container, if the key does not exist. + * @param value A key-value pair eventually convertible to the value type. + * @return A pair consisting of an iterator to the inserted element (or to + * the element that prevented the insertion) and a bool denoting whether the + * insertion took place. + */ + std::pair insert(const value_type &value) { + return insert_or_do_nothing(value.first, value.second); + } + + /*! @copydoc insert */ + std::pair insert(value_type &&value) { + return insert_or_do_nothing(std::move(value.first), std::move(value.second)); + } + + /** + * @copydoc insert + * @tparam Arg Type of the key-value pair to insert into the container. + */ + template + std::enable_if_t, std::pair> + insert(Arg &&value) { + return insert_or_do_nothing(std::forward(value).first, std::forward(value).second); + } + + /** + * @brief Inserts elements into the container, if their keys do not exist. + * @tparam It Type of input iterator. + * @param first An iterator to the first element of the range of elements. + * @param last An iterator past the last element of the range of elements. + */ + template + void insert(It first, It last) { + for(; first != last; ++first) { + insert(*first); + } + } + + /** + * @brief Inserts an element into the container or assigns to the current + * element if the key already exists. + * @tparam Arg Type of the value to insert or assign. + * @param key A key used both to look up and to insert if not found. + * @param value A value to insert or assign. + * @return A pair consisting of an iterator to the element and a bool + * denoting whether the insertion took place. + */ + template + std::pair insert_or_assign(const key_type &key, Arg &&value) { + return insert_or_overwrite(key, std::forward(value)); + } + + /*! @copydoc insert_or_assign */ + template + std::pair insert_or_assign(key_type &&key, Arg &&value) { + return insert_or_overwrite(std::move(key), std::forward(value)); + } + + /** + * @brief Constructs an element in-place, if the key does not exist. + * + * The element is also constructed when the container already has the key, + * in which case the newly constructed object is destroyed immediately. + * + * @tparam Args Types of arguments to forward to the constructor of the + * element. + * @param args Arguments to forward to the constructor of the element. + * @return A pair consisting of an iterator to the inserted element (or to + * the element that prevented the insertion) and a bool denoting whether the + * insertion took place. + */ + template + std::pair emplace([[maybe_unused]] Args &&...args) { + if constexpr(sizeof...(Args) == 0u) { + return insert_or_do_nothing(key_type{}); + } else if constexpr(sizeof...(Args) == 1u) { + return insert_or_do_nothing(std::forward(args).first..., std::forward(args).second...); + } else if constexpr(sizeof...(Args) == 2u) { + return insert_or_do_nothing(std::forward(args)...); + } else { + auto &node = packed.first().emplace_back(packed.first().size(), std::forward(args)...); + const auto index = key_to_bucket(node.element.first); + + if(auto it = constrained_find(node.element.first, index); it != end()) { + packed.first().pop_back(); + return std::make_pair(it, false); + } + + std::swap(node.next, sparse.first()[index]); + rehash_if_required(); + + return std::make_pair(--end(), true); + } + } + + /** + * @brief Inserts in-place if the key does not exist, does nothing if the + * key exists. + * @tparam Args Types of arguments to forward to the constructor of the + * element. + * @param key A key used both to look up and to insert if not found. + * @param args Arguments to forward to the constructor of the element. + * @return A pair consisting of an iterator to the inserted element (or to + * the element that prevented the insertion) and a bool denoting whether the + * insertion took place. + */ + template + std::pair try_emplace(const key_type &key, Args &&...args) { + return insert_or_do_nothing(key, std::forward(args)...); + } + + /*! @copydoc try_emplace */ + template + std::pair try_emplace(key_type &&key, Args &&...args) { + return insert_or_do_nothing(std::move(key), std::forward(args)...); + } + + /** + * @brief Removes an element from a given position. + * @param pos An iterator to the element to remove. + * @return An iterator following the removed element. + */ + iterator erase(const_iterator pos) { + const auto diff = pos - cbegin(); + erase(pos->first); + return begin() + diff; + } + + /** + * @brief Removes the given elements from a container. + * @param first An iterator to the first element of the range of elements. + * @param last An iterator past the last element of the range of elements. + * @return An iterator following the last removed element. + */ + iterator erase(const_iterator first, const_iterator last) { + const auto dist = first - cbegin(); + + for(auto from = last - cbegin(); from != dist; --from) { + erase(packed.first()[static_cast(from) - 1u].element.first); + } + + return (begin() + dist); + } + + /** + * @brief Removes the element associated with a given key. + * @param key A key value of an element to remove. + * @return Number of elements removed (either 0 or 1). + */ + size_type erase(const key_type &key) { + for(size_type *curr = &sparse.first()[key_to_bucket(key)]; *curr != placeholder_position; curr = &packed.first()[*curr].next) { + if(packed.second()(packed.first()[*curr].element.first, key)) { + const auto index = *curr; + *curr = packed.first()[*curr].next; + move_and_pop(index); + return 1u; + } + } + + return 0u; + } + + /** + * @brief Accesses a given element with bounds checking. + * @param key A key of an element to find. + * @return A reference to the mapped value of the requested element. + */ + [[nodiscard]] mapped_type &at(const key_type &key) { + auto it = find(key); + ENTT_ASSERT(it != end(), "Invalid key"); + return it->second; + } + + /*! @copydoc at */ + [[nodiscard]] const mapped_type &at(const key_type &key) const { + auto it = find(key); + ENTT_ASSERT(it != cend(), "Invalid key"); + return it->second; + } + + /** + * @brief Accesses a given element with bounds checking. + * @tparam Other Type of the key of an element to find. + * @param key A key of an element to find. + * @return A reference to the mapped value of the requested element. + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + at(const Other &key) const { + auto it = find(key); + ENTT_ASSERT(it != cend(), "Invalid key"); + return it->second; + } + + /*! @copydoc at */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + at(const Other &key) { + auto it = find(key); + ENTT_ASSERT(it != end(), "Invalid key"); + return it->second; + } + + /** + * @brief Accesses or inserts a given element. + * @param key A key of an element to find or insert. + * @return A reference to the mapped value of the requested element. + */ + [[nodiscard]] mapped_type &operator[](const key_type &key) { + return insert_or_do_nothing(key).first->second; + } + + /** + * @brief Accesses or inserts a given element. + * @param key A key of an element to find or insert. + * @return A reference to the mapped value of the requested element. + */ + [[nodiscard]] mapped_type &operator[](key_type &&key) { + return insert_or_do_nothing(std::move(key)).first->second; + } + + /** + * @brief Returns the number of elements matching a key (either 1 or 0). + * @param key Key value of an element to search for. + * @return Number of elements matching the key (either 1 or 0). + */ + [[nodiscard]] size_type count(const key_type &key) const { + return find(key) != end(); + } + + /** + * @brief Returns the number of elements matching a key (either 1 or 0). + * @tparam Other Type of the key value of an element to search for. + * @param key Key value of an element to search for. + * @return Number of elements matching the key (either 1 or 0). + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + count(const Other &key) const { + return find(key) != end(); + } + + /** + * @brief Finds an element with a given key. + * @param key Key value of an element to search for. + * @return An iterator to an element with the given key. If no such element + * is found, a past-the-end iterator is returned. + */ + [[nodiscard]] iterator find(const key_type &key) { + return constrained_find(key, key_to_bucket(key)); + } + + /*! @copydoc find */ + [[nodiscard]] const_iterator find(const key_type &key) const { + return constrained_find(key, key_to_bucket(key)); + } + + /** + * @brief Finds an element with a key that compares _equivalent_ to a given + * key. + * @tparam Other Type of the key value of an element to search for. + * @param key Key value of an element to search for. + * @return An iterator to an element with the given key. If no such element + * is found, a past-the-end iterator is returned. + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + find(const Other &key) { + return constrained_find(key, key_to_bucket(key)); + } + + /*! @copydoc find */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + find(const Other &key) const { + return constrained_find(key, key_to_bucket(key)); + } + + /** + * @brief Returns a range containing all elements with a given key. + * @param key Key value of an element to search for. + * @return A pair of iterators pointing to the first element and past the + * last element of the range. + */ + [[nodiscard]] std::pair equal_range(const key_type &key) { + const auto it = find(key); + return {it, it + !(it == end())}; + } + + /*! @copydoc equal_range */ + [[nodiscard]] std::pair equal_range(const key_type &key) const { + const auto it = find(key); + return {it, it + !(it == cend())}; + } + + /** + * @brief Returns a range containing all elements that compare _equivalent_ + * to a given key. + * @tparam Other Type of an element to search for. + * @param key Key value of an element to search for. + * @return A pair of iterators pointing to the first element and past the + * last element of the range. + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t>> + equal_range(const Other &key) { + const auto it = find(key); + return {it, it + !(it == end())}; + } + + /*! @copydoc equal_range */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t>> + equal_range(const Other &key) const { + const auto it = find(key); + return {it, it + !(it == cend())}; + } + + /** + * @brief Checks if the container contains an element with a given key. + * @param key Key value of an element to search for. + * @return True if there is such an element, false otherwise. + */ + [[nodiscard]] bool contains(const key_type &key) const { + return (find(key) != cend()); + } + + /** + * @brief Checks if the container contains an element with a key that + * compares _equivalent_ to a given value. + * @tparam Other Type of the key value of an element to search for. + * @param key Key value of an element to search for. + * @return True if there is such an element, false otherwise. + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + contains(const Other &key) const { + return (find(key) != cend()); + } + + /** + * @brief Returns an iterator to the beginning of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the beginning of the given bucket. + */ + [[nodiscard]] const_local_iterator cbegin(const size_type index) const { + return {packed.first().begin(), sparse.first()[index]}; + } + + /** + * @brief Returns an iterator to the beginning of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the beginning of the given bucket. + */ + [[nodiscard]] const_local_iterator begin(const size_type index) const { + return cbegin(index); + } + + /** + * @brief Returns an iterator to the beginning of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the beginning of the given bucket. + */ + [[nodiscard]] local_iterator begin(const size_type index) { + return {packed.first().begin(), sparse.first()[index]}; + } + + /** + * @brief Returns an iterator to the end of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the end of the given bucket. + */ + [[nodiscard]] const_local_iterator cend([[maybe_unused]] const size_type index) const { + return {}; + } + + /** + * @brief Returns an iterator to the end of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the end of the given bucket. + */ + [[nodiscard]] const_local_iterator end(const size_type index) const { + return cend(index); + } + + /** + * @brief Returns an iterator to the end of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the end of the given bucket. + */ + [[nodiscard]] local_iterator end([[maybe_unused]] const size_type index) { + return {}; + } + + /** + * @brief Returns the number of buckets. + * @return The number of buckets. + */ + [[nodiscard]] size_type bucket_count() const { + return sparse.first().size(); + } + + /** + * @brief Returns the maximum number of buckets. + * @return The maximum number of buckets. + */ + [[nodiscard]] size_type max_bucket_count() const { + return sparse.first().max_size(); + } + + /** + * @brief Returns the number of elements in a given bucket. + * @param index The index of the bucket to examine. + * @return The number of elements in the given bucket. + */ + [[nodiscard]] size_type bucket_size(const size_type index) const { + return static_cast(std::distance(begin(index), end(index))); + } + + /** + * @brief Returns the bucket for a given key. + * @param key The value of the key to examine. + * @return The bucket for the given key. + */ + [[nodiscard]] size_type bucket(const key_type &key) const { + return key_to_bucket(key); + } + + /** + * @brief Returns the average number of elements per bucket. + * @return The average number of elements per bucket. + */ + [[nodiscard]] float load_factor() const { + return static_cast(size()) / static_cast(bucket_count()); + } + + /** + * @brief Returns the maximum average number of elements per bucket. + * @return The maximum average number of elements per bucket. + */ + [[nodiscard]] float max_load_factor() const { + return threshold; + } + + /** + * @brief Sets the desired maximum average number of elements per bucket. + * @param value A desired maximum average number of elements per bucket. + */ + void max_load_factor(const float value) { + ENTT_ASSERT(value > 0.f, "Invalid load factor"); + threshold = value; + rehash(0u); + } + + /** + * @brief Reserves at least the specified number of buckets and regenerates + * the hash table. + * @param cnt New number of buckets. + */ + void rehash(const size_type cnt) { + auto value = cnt > minimum_capacity ? cnt : minimum_capacity; + const auto cap = static_cast(static_cast(size()) / max_load_factor()); + value = value > cap ? value : cap; + + if(const auto sz = next_power_of_two(value); sz != bucket_count()) { + sparse.first().resize(sz); + + for(auto &&elem: sparse.first()) { + elem = placeholder_position; + } + + for(size_type pos{}, last = size(); pos < last; ++pos) { + const auto index = key_to_bucket(packed.first()[pos].element.first); + packed.first()[pos].next = std::exchange(sparse.first()[index], pos); + } + } + } + + /** + * @brief Reserves space for at least the specified number of elements and + * regenerates the hash table. + * @param cnt New number of elements. + */ + void reserve(const size_type cnt) { + packed.first().reserve(cnt); + rehash(static_cast(std::ceil(static_cast(cnt) / max_load_factor()))); + } + + /** + * @brief Returns the function used to hash the keys. + * @return The function used to hash the keys. + */ + [[nodiscard]] hasher hash_function() const { + return sparse.second(); + } + + /** + * @brief Returns the function used to compare keys for equality. + * @return The function used to compare keys for equality. + */ + [[nodiscard]] key_equal key_eq() const { + return packed.second(); + } + +private: + compressed_pair sparse; + compressed_pair packed; + float threshold{default_threshold}; +}; + +} // namespace entt + +/*! @cond TURN_OFF_DOXYGEN */ +namespace std { + +template +struct uses_allocator, Allocator> + : std::true_type {}; + +} // namespace std +/*! @endcond */ + +#endif + +// #include "../core/compressed_pair.hpp" +#ifndef ENTT_CORE_COMPRESSED_PAIR_HPP +#define ENTT_CORE_COMPRESSED_PAIR_HPP + +#include +#include +#include +#include +// #include "fwd.hpp" +#ifndef ENTT_CORE_FWD_HPP +#define ENTT_CORE_FWD_HPP + +#include +#include +// #include "../config/config.h" +#ifndef ENTT_CONFIG_CONFIG_H +#define ENTT_CONFIG_CONFIG_H + +// #include "version.h" +#ifndef ENTT_CONFIG_VERSION_H +#define ENTT_CONFIG_VERSION_H + +// #include "macro.h" +#ifndef ENTT_CONFIG_MACRO_H +#define ENTT_CONFIG_MACRO_H + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#define ENTT_STR(arg) #arg +#define ENTT_XSTR(arg) ENTT_STR(arg) + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*) + +#define ENTT_VERSION_MAJOR 3 +#define ENTT_VERSION_MINOR 16 +#define ENTT_VERSION_PATCH 0 + +#define ENTT_VERSION \ + ENTT_XSTR(ENTT_VERSION_MAJOR) \ + "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH) + +// NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION) +# define ENTT_CONSTEXPR +# define ENTT_THROW throw +# define ENTT_TRY try +# define ENTT_CATCH catch(...) +#else +# define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20) +# define ENTT_THROW +# define ENTT_TRY if(true) +# define ENTT_CATCH if(false) +#endif + +#if __has_include() +# include +# +# if defined(__cpp_consteval) +# define ENTT_CONSTEVAL consteval +# endif +#endif + +#ifndef ENTT_CONSTEVAL +# define ENTT_CONSTEVAL constexpr +#endif + +#ifdef ENTT_USE_ATOMIC +# include +# define ENTT_MAYBE_ATOMIC(Type) std::atomic +#else +# define ENTT_MAYBE_ATOMIC(Type) Type +#endif + +#ifndef ENTT_ID_TYPE +# include +# define ENTT_ID_TYPE std::uint32_t +#else +# include // provides coverage for types in the std namespace +#endif + +#ifndef ENTT_SPARSE_PAGE +# define ENTT_SPARSE_PAGE 4096 +#endif + +#ifndef ENTT_PACKED_PAGE +# define ENTT_PACKED_PAGE 1024 +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT +# define ENTT_ASSERT(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT +# include +# define ENTT_ASSERT(condition, msg) assert(((condition) && (msg))) +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg) +#endif + +#define ENTT_FAIL(msg) ENTT_ASSERT(false, msg); + +#ifdef ENTT_NO_ETO +# define ENTT_ETO_TYPE(Type) void +#else +# define ENTT_ETO_TYPE(Type) Type +#endif + +#ifdef ENTT_NO_MIXIN +# define ENTT_STORAGE(Mixin, ...) __VA_ARGS__ +#else +# define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__> +#endif + +#ifdef ENTT_STANDARD_CPP +# define ENTT_NONSTD false +#else +# define ENTT_NONSTD true +# if defined __clang__ || defined __GNUC__ +# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ +# define ENTT_PRETTY_FUNCTION_PREFIX '=' +# define ENTT_PRETTY_FUNCTION_SUFFIX ']' +# elif defined _MSC_VER +# define ENTT_PRETTY_FUNCTION __FUNCSIG__ +# define ENTT_PRETTY_FUNCTION_PREFIX '<' +# define ENTT_PRETTY_FUNCTION_SUFFIX '>' +# endif +#endif + +#ifndef ENTT_EXPORT +# if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER +# define ENTT_EXPORT __declspec(dllexport) +# define ENTT_IMPORT __declspec(dllimport) +# define ENTT_HIDDEN +# elif defined __GNUC__ && __GNUC__ >= 4 +# define ENTT_EXPORT __attribute__((visibility("default"))) +# define ENTT_IMPORT __attribute__((visibility("default"))) +# define ENTT_HIDDEN __attribute__((visibility("hidden"))) +# else /* Unsupported compiler */ +# define ENTT_EXPORT +# define ENTT_IMPORT +# define ENTT_HIDDEN +# endif +#endif + +#ifndef ENTT_API +# if defined ENTT_API_EXPORT +# define ENTT_API ENTT_EXPORT +# elif defined ENTT_API_IMPORT +# define ENTT_API ENTT_IMPORT +# else /* No API */ +# define ENTT_API +# endif +#endif + +#if defined _MSC_VER +# pragma detect_mismatch("entt.version", ENTT_VERSION) +# pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY)) +# pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE)) +# pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD)) +#endif + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +namespace entt { + +/*! @brief Possible modes of an any object. */ +enum class any_policy : std::uint8_t { + /*! @brief Default mode, no element available. */ + empty, + /*! @brief Owning mode, dynamically allocated element. */ + dynamic, + /*! @brief Owning mode, embedded element. */ + embedded, + /*! @brief Aliasing mode, non-const reference. */ + ref, + /*! @brief Const aliasing mode, const reference. */ + cref +}; + +// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) +template +class basic_any; + +/*! @brief Alias declaration for type identifiers. */ +using id_type = ENTT_ID_TYPE; + +/*! @brief Alias declaration for the most common use case. */ +using any = basic_any<>; + +template +class compressed_pair; + +template +class basic_hashed_string; + +/*! @brief Aliases for common character types. */ +using hashed_string = basic_hashed_string; + +/*! @brief Aliases for common character types. */ +using hashed_wstring = basic_hashed_string; + +// NOLINTNEXTLINE(bugprone-forward-declaration-namespace) +struct type_info; + +} // namespace entt + +#endif + +// #include "type_traits.hpp" +#ifndef ENTT_CORE_TYPE_TRAITS_HPP +#define ENTT_CORE_TYPE_TRAITS_HPP + +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "fwd.hpp" + + +namespace entt { + +/** + * @brief Utility class to disambiguate overloaded functions. + * @tparam N Number of choices available. + */ +template +struct choice_t + // unfortunately, doxygen cannot parse such a construct + : /*! @cond TURN_OFF_DOXYGEN */ choice_t /*! @endcond */ +{}; + +/*! @copybrief choice_t */ +template<> +struct choice_t<0> {}; + +/** + * @brief Variable template for the choice trick. + * @tparam N Number of choices available. + */ +template +inline constexpr choice_t choice{}; + +/** + * @brief Identity type trait. + * + * Useful to establish non-deduced contexts in template argument deduction + * (waiting for C++20) or to provide types through function arguments. + * + * @tparam Type A type. + */ +template +struct type_identity { + /*! @brief Identity type. */ + using type = Type; +}; + +/** + * @brief Helper type. + * @tparam Type A type. + */ +template +using type_identity_t = typename type_identity::type; + +/** + * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains. + * @tparam Type The type of which to return the size. + */ +template +struct size_of: std::integral_constant {}; + +/*! @copydoc size_of */ +template +struct size_of> + // NOLINTNEXTLINE(bugprone-sizeof-expression) + : std::integral_constant {}; + +/** + * @brief Helper variable template. + * @tparam Type The type of which to return the size. + */ +template +inline constexpr std::size_t size_of_v = size_of::value; + +/** + * @brief Using declaration to be used to _repeat_ the same type a number of + * times equal to the size of a given parameter pack. + * @tparam Type A type to repeat. + */ +template +using unpack_as_type = Type; + +/** + * @brief Helper variable template to be used to _repeat_ the same value a + * number of times equal to the size of a given parameter pack. + * @tparam Value A value to repeat. + */ +template +inline constexpr auto unpack_as_value = Value; + +/** + * @brief Wraps a static constant. + * @tparam Value A static constant. + */ +template +using integral_constant = std::integral_constant; + +/** + * @brief Alias template to facilitate the creation of named values. + * @tparam Value A constant value at least convertible to `id_type`. + */ +template +using tag = integral_constant; + +/** + * @brief A class to use to push around lists of types, nothing more. + * @tparam Type Types provided by the type list. + */ +template +struct type_list { + /*! @brief Type list type. */ + using type = type_list; + /*! @brief Compile-time number of elements in the type list. */ + static constexpr auto size = sizeof...(Type); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_element; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Index Index of the type to return. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element> + : type_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element<0u, type_list> { + /*! @brief Searched type. */ + using type = First; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Type list to search into. + */ +template +using type_list_element_t = typename type_list_element::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_index; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 1u + type_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + static_assert(type_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +inline constexpr std::size_t type_list_index_v = type_list_index::value; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @return A type list composed by the types of both the type lists. + */ +template +constexpr type_list operator+(type_list, type_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_cat; + +/*! @brief Concatenates multiple type lists. */ +template<> +struct type_list_cat<> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list<>; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @tparam List Other type lists, if any. + */ +template +struct type_list_cat, type_list, List...> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = typename type_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the type list. + */ +template +struct type_list_cat> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list; +}; + +/** + * @brief Helper type. + * @tparam List Type lists to concatenate. + */ +template +using type_list_cat_t = typename type_list_cat::type; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct type_list_unique; + +template +struct type_list_unique, Type...> + : std::conditional_t<(std::is_same_v || ...), type_list_unique, Type...>, type_list_unique, Type..., First>> {}; + +template +struct type_list_unique, Type...> { + using type = type_list; +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Removes duplicates types from a type list. + * @tparam List Type list. + */ +template +struct type_list_unique { + /*! @brief A type list without duplicate types. */ + using type = typename internal::type_list_unique::type; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + */ +template +using type_list_unique_t = typename type_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a type list contains a + * given type, false otherwise. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +struct type_list_contains; + +/** + * @copybrief type_list_contains + * @tparam Type Types provided by the type list. + * @tparam Other Type to look for. + */ +template +struct type_list_contains, Other> + : std::bool_constant<(std::is_same_v || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +inline constexpr bool type_list_contains_v = type_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_diff; + +/** + * @brief Computes the difference between two type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + */ +template +struct type_list_diff, type_list> { + /*! @brief A type list that is the difference between the two type lists. */ + using type = type_list_cat_t, Type>, type_list<>, type_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Type lists between which to compute the difference. + */ +template +using type_list_diff_t = typename type_list_diff::type; + +/*! @brief Primary template isn't defined on purpose. */ +template class> +struct type_list_transform; + +/** + * @brief Applies a given _function_ to a type list and generate a new list. + * @tparam Type Types provided by the type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +struct type_list_transform, Op> { + /*! @brief Resulting type list after applying the transform function. */ + // NOLINTNEXTLINE(modernize-type-traits) + using type = type_list::type...>; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +using type_list_transform_t = typename type_list_transform::type; + +/** + * @brief A class to use to push around lists of constant values, nothing more. + * @tparam Value Values provided by the value list. + */ +template +struct value_list { + /*! @brief Value list type. */ + using type = value_list; + /*! @brief Compile-time number of elements in the value list. */ + static constexpr auto size = sizeof...(Value); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_element; + +/** + * @brief Provides compile-time indexed access to the values of a value list. + * @tparam Index Index of the value to return. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element> + : value_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element<0u, value_list> { + /*! @brief Searched type. */ + using type = decltype(Value); + /*! @brief Searched value. */ + static constexpr auto value = Value; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Value list to search into. + */ +template +using value_list_element_t = typename value_list_element::type; + +/** + * @brief Helper type. + * @tparam Index Index of the value to return. + * @tparam List Value list to search into. + */ +template +inline constexpr auto value_list_element_v = value_list_element::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_index; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam First First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 1u + value_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + static_assert(value_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +inline constexpr std::size_t value_list_index_v = value_list_index::value; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @return A value list composed by the values of both the value lists. + */ +template +constexpr value_list operator+(value_list, value_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_cat; + +/*! @brief Concatenates multiple value lists. */ +template<> +struct value_list_cat<> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list<>; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @tparam List Other value lists, if any. + */ +template +struct value_list_cat, value_list, List...> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = typename value_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the value list. + */ +template +struct value_list_cat> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list; +}; + +/** + * @brief Helper type. + * @tparam List Value lists to concatenate. + */ +template +using value_list_cat_t = typename value_list_cat::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_unique; + +/** + * @brief Removes duplicates values from a value list. + * @tparam Value One of the values provided by the given value list. + * @tparam Other The other values provided by the given value list. + */ +template +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = std::conditional_t< + ((Value == Other) || ...), + typename value_list_unique>::type, + value_list_cat_t, typename value_list_unique>::type>>; +}; + +/*! @brief Removes duplicates values from a value list. */ +template<> +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = value_list<>; +}; + +/** + * @brief Helper type. + * @tparam Type A value list. + */ +template +using value_list_unique_t = typename value_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a value list contains + * a given value, false otherwise. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +struct value_list_contains; + +/** + * @copybrief value_list_contains + * @tparam Value Values provided by the value list. + * @tparam Other Value to look for. + */ +template +struct value_list_contains, Other> + : std::bool_constant<((Value == Other) || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +inline constexpr bool value_list_contains_v = value_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_diff; + +/** + * @brief Computes the difference between two value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + */ +template +struct value_list_diff, value_list> { + /*! @brief A value list that is the difference between the two value lists. */ + using type = value_list_cat_t, Value>, value_list<>, value_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Value lists between which to compute the difference. + */ +template +using value_list_diff_t = typename value_list_diff::type; + +/*! @brief Same as std::is_invocable, but with tuples. */ +template +struct is_applicable: std::false_type {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @brief Helper variable template. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_v = is_applicable::value; + +/*! @brief Same as std::is_invocable_r, but with tuples for arguments. */ +template +struct is_applicable_r: std::false_type {}; + +/** + * @copybrief is_applicable_r + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +struct is_applicable_r>: std::is_invocable_r {}; + +/** + * @brief Helper variable template. + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_r_v = is_applicable_r::value; + +/** + * @brief Provides the member constant `value` to true if a given type is + * complete, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_complete: std::false_type {}; + +/*! @copydoc is_complete */ +template +struct is_complete>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_complete_v = is_complete::value; + +/** + * @brief Provides the member constant `value` to true if a given type is an + * iterator, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_iterator: std::false_type {}; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_iterator_category: std::false_type {}; + +template +struct has_iterator_category::iterator_category>>: std::true_type {}; + +} // namespace internal +/*! @endcond */ + +/*! @copydoc is_iterator */ +template +struct is_iterator>>>> + : internal::has_iterator_category {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_iterator_v = is_iterator::value; + +/** + * @brief Provides the member constant `value` to true if a given type is both + * an empty and non-final class, false otherwise. + * @tparam Type The type to test + */ +template +struct is_ebco_eligible + : std::bool_constant && !std::is_final_v> {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_ebco_eligible_v = is_ebco_eligible::value; + +/** + * @brief Provides the member constant `value` to true if `Type::is_transparent` + * is valid and denotes a type, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_transparent: std::false_type {}; + +/*! @copydoc is_transparent */ +template +struct is_transparent>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_transparent_v = is_transparent::value; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_tuple_size_value: std::false_type {}; + +template +struct has_tuple_size_value::value)>>: std::true_type {}; + +template +struct has_value_type: std::false_type {}; + +template +struct has_value_type>: std::true_type {}; + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable(); + +template +[[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence) { + return (dispatch_is_equality_comparable>() && ...); +} + +template +[[nodiscard]] constexpr bool maybe_equality_comparable(char) { + return false; +} + +template +[[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval() == std::declval()) { + return true; +} + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable() { + // NOLINTBEGIN(modernize-use-transparent-functors) + if constexpr(std::is_array_v) { + return false; + } else if constexpr(is_complete_v>>) { + if constexpr(has_tuple_size_value::value) { + return maybe_equality_comparable(0) && unpack_maybe_equality_comparable(std::make_index_sequence::value>{}); + } else { + return maybe_equality_comparable(0); + } + } else if constexpr(has_value_type::value) { + if constexpr(is_iterator_v || std::is_same_v || dispatch_is_equality_comparable()) { + return maybe_equality_comparable(0); + } else { + return false; + } + } else { + return maybe_equality_comparable(0); + } + // NOLINTEND(modernize-use-transparent-functors) +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Provides the member constant `value` to true if a given type is + * equality comparable, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_equality_comparable: std::bool_constant()> {}; + +/*! @copydoc is_equality_comparable */ +template +struct is_equality_comparable: is_equality_comparable {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_equality_comparable_v = is_equality_comparable::value; + +/** + * @brief Transcribes the constness of a type to another type. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = std::remove_const_t; +}; + +/*! @copydoc constness_as */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = const To; +}; + +/** + * @brief Alias template to facilitate the transcription of the constness. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +using constness_as_t = typename constness_as::type; + +/** + * @brief Extracts the class of a non-static member object or function. + * @tparam Member A pointer to a non-static member object or function. + */ +template +class member_class { + static_assert(std::is_member_pointer_v, "Invalid pointer type to non-static member object or function"); + + template + static Class *clazz(Ret (Class::*)(Args...)); + + template + static Class *clazz(Ret (Class::*)(Args...) const); + + template + static Class *clazz(Type Class::*); + +public: + /*! @brief The class of the given non-static member object or function. */ + using type = std::remove_pointer_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Member A pointer to a non-static member object or function. + */ +template +using member_class_t = typename member_class::type; + +/** + * @brief Extracts the n-th argument of a _callable_ type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid _callable_ type. + */ +template +class nth_argument { + template + static constexpr type_list pick_up(Ret (*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...) const); + + template + static constexpr type_list pick_up(Type Class ::*); + + template + static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&); + +public: + /*! @brief N-th argument of the _callable_ type. */ + using type = type_list_element_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid function, member function or data member type. + */ +template +using nth_argument_t = typename nth_argument::type; + +} // namespace entt + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::type_list_element> {}; + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::value_list_element> {}; + +#endif + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct compressed_pair_element { + using reference = Type &; + using const_reference = const Type &; + + template>> + // NOLINTNEXTLINE(modernize-use-equals-default) + constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v) {} + + template>, compressed_pair_element>>> + constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v) + : value{std::forward(arg)} {} + + template + constexpr compressed_pair_element(std::tuple args, std::index_sequence) noexcept(std::is_nothrow_constructible_v) + : value{std::forward(std::get(args))...} {} + + [[nodiscard]] constexpr reference get() noexcept { + return value; + } + + [[nodiscard]] constexpr const_reference get() const noexcept { + return value; + } + +private: + Type value{}; +}; + +template +struct compressed_pair_element>>: Type { + using reference = Type &; + using const_reference = const Type &; + using base_type = Type; + + template>> + constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v) + : base_type{} {} + + template>, compressed_pair_element>>> + constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v) + : base_type{std::forward(arg)} {} + + template + constexpr compressed_pair_element(std::tuple args, std::index_sequence) noexcept(std::is_nothrow_constructible_v) + : base_type{std::forward(std::get(args))...} {} + + [[nodiscard]] constexpr reference get() noexcept { + return *this; + } + + [[nodiscard]] constexpr const_reference get() const noexcept { + return *this; + } +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief A compressed pair. + * + * A pair that exploits the _Empty Base Class Optimization_ (or _EBCO_) to + * reduce its final size to a minimum. + * + * @tparam First The type of the first element that the pair stores. + * @tparam Second The type of the second element that the pair stores. + */ +template +class compressed_pair final + : internal::compressed_pair_element, + internal::compressed_pair_element { + using first_base = internal::compressed_pair_element; + using second_base = internal::compressed_pair_element; + +public: + /*! @brief The type of the first element that the pair stores. */ + using first_type = First; + /*! @brief The type of the second element that the pair stores. */ + using second_type = Second; + + /** + * @brief Default constructor, conditionally enabled. + * + * This constructor is only available when the types that the pair stores + * are both at least default constructible. + * + * @tparam Dummy Dummy template parameter used for internal purposes. + */ + template && std::is_default_constructible_v>> + constexpr compressed_pair() noexcept(std::is_nothrow_default_constructible_v && std::is_nothrow_default_constructible_v) + : first_base{}, + second_base{} {} + + /** + * @brief Copy constructor. + * @param other The instance to copy from. + */ + constexpr compressed_pair(const compressed_pair &other) = default; + + /** + * @brief Move constructor. + * @param other The instance to move from. + */ + constexpr compressed_pair(compressed_pair &&other) noexcept = default; + + /** + * @brief Constructs a pair from its values. + * @tparam Arg Type of value to use to initialize the first element. + * @tparam Other Type of value to use to initialize the second element. + * @param arg Value to use to initialize the first element. + * @param other Value to use to initialize the second element. + */ + template + constexpr compressed_pair(Arg &&arg, Other &&other) noexcept(std::is_nothrow_constructible_v && std::is_nothrow_constructible_v) + : first_base{std::forward(arg)}, + second_base{std::forward(other)} {} + + /** + * @brief Constructs a pair by forwarding the arguments to its parts. + * @tparam Args Types of arguments to use to initialize the first element. + * @tparam Other Types of arguments to use to initialize the second element. + * @param args Arguments to use to initialize the first element. + * @param other Arguments to use to initialize the second element. + */ + template + constexpr compressed_pair(std::piecewise_construct_t, std::tuple args, std::tuple other) noexcept(std::is_nothrow_constructible_v && std::is_nothrow_constructible_v) + : first_base{std::move(args), std::index_sequence_for{}}, + second_base{std::move(other), std::index_sequence_for{}} {} + + /*! @brief Default destructor. */ + ~compressed_pair() = default; + + /** + * @brief Copy assignment operator. + * @param other The instance to copy from. + * @return This compressed pair object. + */ + constexpr compressed_pair &operator=(const compressed_pair &other) = default; + + /** + * @brief Move assignment operator. + * @param other The instance to move from. + * @return This compressed pair object. + */ + constexpr compressed_pair &operator=(compressed_pair &&other) noexcept = default; + + /** + * @brief Returns the first element that a pair stores. + * @return The first element that a pair stores. + */ + [[nodiscard]] constexpr first_type &first() noexcept { + return static_cast(*this).get(); + } + + /*! @copydoc first */ + [[nodiscard]] constexpr const first_type &first() const noexcept { + return static_cast(*this).get(); + } + + /** + * @brief Returns the second element that a pair stores. + * @return The second element that a pair stores. + */ + [[nodiscard]] constexpr second_type &second() noexcept { + return static_cast(*this).get(); + } + + /*! @copydoc second */ + [[nodiscard]] constexpr const second_type &second() const noexcept { + return static_cast(*this).get(); + } + + /** + * @brief Swaps two compressed pair objects. + * @param other The compressed pair to swap with. + */ + constexpr void swap(compressed_pair &other) noexcept { + using std::swap; + swap(first(), other.first()); + swap(second(), other.second()); + } + + /** + * @brief Extracts an element from the compressed pair. + * @tparam Index An integer value that is either 0 or 1. + * @return Returns a reference to the first element if `Index` is 0 and a + * reference to the second element if `Index` is 1. + */ + template + [[nodiscard]] constexpr decltype(auto) get() noexcept { + if constexpr(Index == 0u) { + return first(); + } else { + static_assert(Index == 1u, "Index out of bounds"); + return second(); + } + } + + /*! @copydoc get */ + template + [[nodiscard]] constexpr decltype(auto) get() const noexcept { + if constexpr(Index == 0u) { + return first(); + } else { + static_assert(Index == 1u, "Index out of bounds"); + return second(); + } + } +}; + +/** + * @brief Deduction guide. + * @tparam Type Type of value to use to initialize the first element. + * @tparam Other Type of value to use to initialize the second element. + */ +template +compressed_pair(Type &&, Other &&) -> compressed_pair, std::decay_t>; + +/** + * @brief Swaps two compressed pair objects. + * @tparam First The type of the first element that the pairs store. + * @tparam Second The type of the second element that the pairs store. + * @param lhs A valid compressed pair object. + * @param rhs A valid compressed pair object. + */ +template +constexpr void swap(compressed_pair &lhs, compressed_pair &rhs) noexcept { + lhs.swap(rhs); +} + +} // namespace entt + +namespace std { + +/** + * @brief `std::tuple_size` specialization for `compressed_pair`s. + * @tparam First The type of the first element that the pair stores. + * @tparam Second The type of the second element that the pair stores. + */ +template +struct tuple_size>: integral_constant {}; + +/** + * @brief `std::tuple_element` specialization for `compressed_pair`s. + * @tparam Index The index of the type to return. + * @tparam First The type of the first element that the pair stores. + * @tparam Second The type of the second element that the pair stores. + */ +template +struct tuple_element>: conditional { + static_assert(Index < 2u, "Index out of bounds"); +}; + +} // namespace std + +#endif + +// #include "../core/fwd.hpp" +#ifndef ENTT_CORE_FWD_HPP +#define ENTT_CORE_FWD_HPP + +#include +#include +// #include "../config/config.h" + + +namespace entt { + +/*! @brief Possible modes of an any object. */ +enum class any_policy : std::uint8_t { + /*! @brief Default mode, no element available. */ + empty, + /*! @brief Owning mode, dynamically allocated element. */ + dynamic, + /*! @brief Owning mode, embedded element. */ + embedded, + /*! @brief Aliasing mode, non-const reference. */ + ref, + /*! @brief Const aliasing mode, const reference. */ + cref +}; + +// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) +template +class basic_any; + +/*! @brief Alias declaration for type identifiers. */ +using id_type = ENTT_ID_TYPE; + +/*! @brief Alias declaration for the most common use case. */ +using any = basic_any<>; + +template +class compressed_pair; + +template +class basic_hashed_string; + +/*! @brief Aliases for common character types. */ +using hashed_string = basic_hashed_string; + +/*! @brief Aliases for common character types. */ +using hashed_wstring = basic_hashed_string; + +// NOLINTNEXTLINE(bugprone-forward-declaration-namespace) +struct type_info; + +} // namespace entt + +#endif + +// #include "../core/iterator.hpp" +#ifndef ENTT_CORE_ITERATOR_HPP +#define ENTT_CORE_ITERATOR_HPP + +#include +#include +#include +#include + +namespace entt { + +/** + * @brief Helper type to use as pointer with input iterators. + * @tparam Type of wrapped value. + */ +template +struct input_iterator_pointer final { + /*! @brief Value type. */ + using value_type = Type; + /*! @brief Pointer type. */ + using pointer = Type *; + /*! @brief Reference type. */ + using reference = Type &; + + /** + * @brief Constructs a proxy object by move. + * @param val Value to use to initialize the proxy object. + */ + constexpr input_iterator_pointer(value_type &&val) noexcept(std::is_nothrow_move_constructible_v) + : value{std::move(val)} {} + + /** + * @brief Access operator for accessing wrapped values. + * @return A pointer to the wrapped value. + */ + [[nodiscard]] constexpr pointer operator->() noexcept { + return std::addressof(value); + } + + /** + * @brief Dereference operator for accessing wrapped values. + * @return A reference to the wrapped value. + */ + [[nodiscard]] constexpr reference operator*() noexcept { + return value; + } + +private: + Type value; +}; + +/** + * @brief Plain iota iterator (waiting for C++20). + * @tparam Type Value type. + */ +template +class iota_iterator final { + static_assert(std::is_integral_v, "Not an integral type"); + +public: + /*! @brief Value type, likely an integral one. */ + using value_type = Type; + /*! @brief Invalid pointer type. */ + using pointer = void; + /*! @brief Non-reference type, same as value type. */ + using reference = value_type; + /*! @brief Difference type. */ + using difference_type = std::ptrdiff_t; + /*! @brief Iterator category. */ + using iterator_category = std::input_iterator_tag; + + /*! @brief Default constructor. */ + constexpr iota_iterator() noexcept + : current{} {} + + /** + * @brief Constructs an iota iterator from a given value. + * @param init The initial value assigned to the iota iterator. + */ + constexpr iota_iterator(const value_type init) noexcept + : current{init} {} + + /** + * @brief Pre-increment operator. + * @return This iota iterator. + */ + constexpr iota_iterator &operator++() noexcept { + return ++current, *this; + } + + /** + * @brief Post-increment operator. + * @return This iota iterator. + */ + constexpr iota_iterator operator++(int) noexcept { + const iota_iterator orig = *this; + return ++(*this), orig; + } + + /** + * @brief Dereference operator. + * @return The underlying value. + */ + [[nodiscard]] constexpr reference operator*() const noexcept { + return current; + } + +private: + value_type current; +}; + +/** + * @brief Comparison operator. + * @tparam Type Value type of the iota iterator. + * @param lhs A properly initialized iota iterator. + * @param rhs A properly initialized iota iterator. + * @return True if the two iterators are identical, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator==(const iota_iterator &lhs, const iota_iterator &rhs) noexcept { + return *lhs == *rhs; +} + +/** + * @brief Comparison operator. + * @tparam Type Value type of the iota iterator. + * @param lhs A properly initialized iota iterator. + * @param rhs A properly initialized iota iterator. + * @return True if the two iterators differ, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator!=(const iota_iterator &lhs, const iota_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +/** + * @brief Utility class to create an iterable object from a pair of iterators. + * @tparam It Type of iterator. + * @tparam Sentinel Type of sentinel. + */ +template +struct iterable_adaptor final { + /*! @brief Value type. */ + using value_type = typename std::iterator_traits::value_type; + /*! @brief Iterator type. */ + using iterator = It; + /*! @brief Sentinel type. */ + using sentinel = Sentinel; + + /*! @brief Default constructor. */ + constexpr iterable_adaptor() noexcept(std::is_nothrow_default_constructible_v && std::is_nothrow_default_constructible_v) + : first{}, + last{} {} + + /** + * @brief Creates an iterable object from a pair of iterators. + * @param from Begin iterator. + * @param to End iterator. + */ + constexpr iterable_adaptor(iterator from, sentinel to) noexcept(std::is_nothrow_move_constructible_v && std::is_nothrow_move_constructible_v) + : first{std::move(from)}, + last{std::move(to)} {} + + /** + * @brief Returns an iterator to the beginning. + * @return An iterator to the first element of the range. + */ + [[nodiscard]] constexpr iterator begin() const noexcept { + return first; + } + + /** + * @brief Returns an iterator to the end. + * @return An iterator to the element following the last element of the + * range. + */ + [[nodiscard]] constexpr sentinel end() const noexcept { + return last; + } + + /*! @copydoc begin */ + [[nodiscard]] constexpr iterator cbegin() const noexcept { + return begin(); + } + + /*! @copydoc end */ + [[nodiscard]] constexpr sentinel cend() const noexcept { + return end(); + } + +private: + It first; + Sentinel last; +}; + +} // namespace entt + +#endif + +// #include "../core/utility.hpp" +#ifndef ENTT_CORE_UTILITY_HPP +#define ENTT_CORE_UTILITY_HPP + +#include +#include + +namespace entt { + +/*! @brief Identity function object (waiting for C++20). */ +struct identity { + /*! @brief Indicates that this is a transparent function object. */ + using is_transparent = void; + + /** + * @brief Returns its argument unchanged. + * @tparam Type Type of the argument. + * @param value The actual argument. + * @return The submitted value as-is. + */ + template + [[nodiscard]] constexpr Type &&operator()(Type &&value) const noexcept { + return std::forward(value); + } +}; + +/** + * @brief Constant utility to disambiguate overloaded members of a class. + * @tparam Type Type of the desired overload. + * @tparam Class Type of class to which the member belongs. + * @param member A valid pointer to a member. + * @return Pointer to the member. + */ +template +[[nodiscard]] constexpr auto overload(Type Class::*member) noexcept { + return member; +} + +/** + * @brief Constant utility to disambiguate overloaded functions. + * @tparam Func Function type of the desired overload. + * @param func A valid pointer to a function. + * @return Pointer to the function. + */ +template +[[nodiscard]] constexpr auto overload(Func *func) noexcept { + return func; +} + +/** + * @brief Helper type for visitors. + * @tparam Func Types of function objects. + */ +template +struct overloaded: Func... { + using Func::operator()...; +}; + +/** + * @brief Deduction guide. + * @tparam Func Types of function objects. + */ +template +overloaded(Func...) -> overloaded; + +/** + * @brief Basic implementation of a y-combinator. + * @tparam Func Type of a potentially recursive function. + */ +template +struct y_combinator { + /** + * @brief Constructs a y-combinator from a given function. + * @param recursive A potentially recursive function. + */ + constexpr y_combinator(Func recursive) noexcept(std::is_nothrow_move_constructible_v) + : func{std::move(recursive)} {} + + /** + * @brief Invokes a y-combinator and therefore its underlying function. + * @tparam Args Types of arguments to use to invoke the underlying function. + * @param args Parameters to use to invoke the underlying function. + * @return Return value of the underlying function, if any. + */ + template + constexpr decltype(auto) operator()(Args &&...args) const noexcept(std::is_nothrow_invocable_v) { + return func(*this, std::forward(args)...); + } + + /*! @copydoc operator()() */ + template + constexpr decltype(auto) operator()(Args &&...args) noexcept(std::is_nothrow_invocable_v) { + return func(*this, std::forward(args)...); + } + +private: + Func func; +}; + +} // namespace entt + +#endif + +// #include "fwd.hpp" +#ifndef ENTT_RESOURCE_FWD_HPP +#define ENTT_RESOURCE_FWD_HPP + +#include + +namespace entt { + +template +struct resource_loader; + +template, typename = std::allocator> +class resource_cache; + +template +class resource; + +} // namespace entt + +#endif + +// #include "loader.hpp" +#ifndef ENTT_RESOURCE_LOADER_HPP +#define ENTT_RESOURCE_LOADER_HPP + +#include +#include +// #include "fwd.hpp" + + +namespace entt { + +/** + * @brief Transparent loader for shared resources. + * @tparam Type Type of resources created by the loader. + */ +template +struct resource_loader { + /*! @brief Result type. */ + using result_type = std::shared_ptr; + + /** + * @brief Constructs a shared pointer to a resource from its arguments. + * @tparam Args Types of arguments to use to construct the resource. + * @param args Parameters to use to construct the resource. + * @return A shared pointer to a resource of the given type. + */ + template + result_type operator()(Args &&...args) const { + return std::make_shared(std::forward(args)...); + } +}; + +} // namespace entt + +#endif + +// #include "resource.hpp" +#ifndef ENTT_RESOURCE_RESOURCE_HPP +#define ENTT_RESOURCE_RESOURCE_HPP + +#include +#include +#include +// #include "fwd.hpp" + + +namespace entt { + +/** + * @brief Basic resource handle. + * + * A handle wraps a resource and extends its lifetime. It also shares the same + * resource with all other handles constructed from the same element.
+ * As a rule of thumb, resources should never be copied nor moved. Handles are + * the way to go to push references around. + * + * @tparam Type Type of resource managed by a handle. + */ +template +class resource { + template + friend class resource; + + template + static constexpr bool is_acceptable = !std::is_same_v && std::is_constructible_v; + +public: + /*! @brief Resource type. */ + using element_type = Type; + /*! @brief Handle type. */ + using handle_type = std::shared_ptr; + + /*! @brief Default constructor. */ + resource() noexcept + : value{} {} + + /** + * @brief Creates a new resource handle. + * @param res A handle to a resource. + */ + explicit resource(handle_type res) noexcept + : value{std::move(res)} {} + + /*! @brief Default copy constructor. */ + resource(const resource &) noexcept = default; + + /*! @brief Default move constructor. */ + resource(resource &&) noexcept = default; + + /** + * @brief Aliasing constructor. + * @tparam Other Type of resource managed by the received handle. + * @param other The handle with which to share ownership information. + * @param res Unrelated and unmanaged resources. + */ + template + resource(const resource &other, element_type &res) noexcept + : value{other.value, std::addressof(res)} {} + + /** + * @brief Copy constructs a handle which shares ownership of the resource. + * @tparam Other Type of resource managed by the received handle. + * @param other The handle to copy from. + */ + template>> + resource(const resource &other) noexcept + : value{other.value} {} + + /** + * @brief Move constructs a handle which takes ownership of the resource. + * @tparam Other Type of resource managed by the received handle. + * @param other The handle to move from. + */ + template>> + resource(resource &&other) noexcept + : value{std::move(other.value)} {} + + /*! @brief Default destructor. */ + ~resource() = default; + + /** + * @brief Default copy assignment operator. + * @return This resource handle. + */ + resource &operator=(const resource &) noexcept = default; + + /** + * @brief Default move assignment operator. + * @return This resource handle. + */ + resource &operator=(resource &&) noexcept = default; + + /** + * @brief Copy assignment operator from foreign handle. + * @tparam Other Type of resource managed by the received handle. + * @param other The handle to copy from. + * @return This resource handle. + */ + template>> + resource &operator=(const resource &other) noexcept { + value = other.value; + return *this; + } + + /** + * @brief Move assignment operator from foreign handle. + * @tparam Other Type of resource managed by the received handle. + * @param other The handle to move from. + * @return This resource handle. + */ + template>> + resource &operator=(resource &&other) noexcept { + value = std::move(other.value); + return *this; + } + + /** + * @brief Exchanges the content with that of a given resource. + * @param other Resource to exchange the content with. + */ + void swap(resource &other) noexcept { + using std::swap; + swap(value, other.value); + } + + /** + * @brief Returns a reference to the managed resource. + * + * @warning + * The behavior is undefined if the handle doesn't contain a resource. + * + * @return A reference to the managed resource. + */ + [[nodiscard]] element_type &operator*() const noexcept { + return *value; + } + + /*! @copydoc operator* */ + [[nodiscard]] operator element_type &() const noexcept { + return *value; + } + + /** + * @brief Returns a pointer to the managed resource. + * @return A pointer to the managed resource. + */ + [[nodiscard]] element_type *operator->() const noexcept { + return value.get(); + } + + /** + * @brief Returns true if a handle contains a resource, false otherwise. + * @return True if the handle contains a resource, false otherwise. + */ + [[nodiscard]] explicit operator bool() const noexcept { + return static_cast(value); + } + + /*! @brief Releases the ownership of the managed resource. */ + void reset() { + value.reset(); + } + + /** + * @brief Replaces the managed resource. + * @param other A handle to a resource. + */ + void reset(handle_type other) { + value = std::move(other); + } + + /** + * @brief Returns the underlying resource handle. + * @return The underlying resource handle. + */ + [[nodiscard]] handle_type handle() const noexcept { + return value; + } + +private: + handle_type value; +}; + +/** + * @brief Compares two handles. + * @tparam Lhs Type of resource managed by the first handle. + * @tparam Rhs Type of resource managed by the second handle. + * @param lhs A valid handle. + * @param rhs A valid handle. + * @return True if both handles refer to the same resource, false otherwise. + */ +template +[[nodiscard]] bool operator==(const resource &lhs, const resource &rhs) noexcept { + return (std::addressof(*lhs) == std::addressof(*rhs)); +} + +/** + * @brief Compares two handles. + * @tparam Lhs Type of resource managed by the first handle. + * @tparam Rhs Type of resource managed by the second handle. + * @param lhs A valid handle. + * @param rhs A valid handle. + * @return False if both handles refer to the same resource, true otherwise. + */ +template +[[nodiscard]] bool operator!=(const resource &lhs, const resource &rhs) noexcept { + return !(lhs == rhs); +} + +/** + * @brief Compares two handles. + * @tparam Lhs Type of resource managed by the first handle. + * @tparam Rhs Type of resource managed by the second handle. + * @param lhs A valid handle. + * @param rhs A valid handle. + * @return True if the first handle is less than the second, false otherwise. + */ +template +[[nodiscard]] bool operator<(const resource &lhs, const resource &rhs) noexcept { + return (std::addressof(*lhs) < std::addressof(*rhs)); +} + +/** + * @brief Compares two handles. + * @tparam Lhs Type of resource managed by the first handle. + * @tparam Rhs Type of resource managed by the second handle. + * @param lhs A valid handle. + * @param rhs A valid handle. + * @return True if the first handle is greater than the second, false otherwise. + */ +template +[[nodiscard]] bool operator>(const resource &lhs, const resource &rhs) noexcept { + return rhs < lhs; +} + +/** + * @brief Compares two handles. + * @tparam Lhs Type of resource managed by the first handle. + * @tparam Rhs Type of resource managed by the second handle. + * @param lhs A valid handle. + * @param rhs A valid handle. + * @return True if the first handle is less than or equal to the second, false + * otherwise. + */ +template +[[nodiscard]] bool operator<=(const resource &lhs, const resource &rhs) noexcept { + return !(lhs > rhs); +} + +/** + * @brief Compares two handles. + * @tparam Lhs Type of resource managed by the first handle. + * @tparam Rhs Type of resource managed by the second handle. + * @param lhs A valid handle. + * @param rhs A valid handle. + * @return True if the first handle is greater than or equal to the second, + * false otherwise. + */ +template +[[nodiscard]] bool operator>=(const resource &lhs, const resource &rhs) noexcept { + return !(lhs < rhs); +} + +} // namespace entt + +#endif + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +class resource_cache_iterator final { + template + friend class resource_cache_iterator; + +public: + using value_type = std::pair>; + using pointer = input_iterator_pointer; + using reference = value_type; + using difference_type = std::ptrdiff_t; + using iterator_category = std::input_iterator_tag; + using iterator_concept = std::random_access_iterator_tag; + + constexpr resource_cache_iterator() noexcept = default; + + constexpr resource_cache_iterator(const It iter) noexcept + : it{iter} {} + + template && std::is_constructible_v>> + constexpr resource_cache_iterator(const resource_cache_iterator, Other> &other) noexcept + : it{other.it} {} + + constexpr resource_cache_iterator &operator++() noexcept { + return ++it, *this; + } + + constexpr resource_cache_iterator operator++(int) noexcept { + const resource_cache_iterator orig = *this; + return ++(*this), orig; + } + + constexpr resource_cache_iterator &operator--() noexcept { + return --it, *this; + } + + constexpr resource_cache_iterator operator--(int) noexcept { + const resource_cache_iterator orig = *this; + return operator--(), orig; + } + + constexpr resource_cache_iterator &operator+=(const difference_type value) noexcept { + it += value; + return *this; + } + + constexpr resource_cache_iterator operator+(const difference_type value) const noexcept { + resource_cache_iterator copy = *this; + return (copy += value); + } + + constexpr resource_cache_iterator &operator-=(const difference_type value) noexcept { + return (*this += -value); + } + + constexpr resource_cache_iterator operator-(const difference_type value) const noexcept { + return (*this + -value); + } + + [[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept { + return {it[value].first, resource{it[value].second}}; + } + + [[nodiscard]] constexpr reference operator*() const noexcept { + return operator[](0); + } + + [[nodiscard]] constexpr pointer operator->() const noexcept { + return operator*(); + } + + template + friend constexpr std::ptrdiff_t operator-(const resource_cache_iterator &, const resource_cache_iterator &) noexcept; + + template + friend constexpr bool operator==(const resource_cache_iterator &, const resource_cache_iterator &) noexcept; + + template + friend constexpr bool operator<(const resource_cache_iterator &, const resource_cache_iterator &) noexcept; + +private: + It it; +}; + +template +[[nodiscard]] constexpr std::ptrdiff_t operator-(const resource_cache_iterator &lhs, const resource_cache_iterator &rhs) noexcept { + return lhs.it - rhs.it; +} + +template +[[nodiscard]] constexpr bool operator==(const resource_cache_iterator &lhs, const resource_cache_iterator &rhs) noexcept { + return lhs.it == rhs.it; +} + +template +[[nodiscard]] constexpr bool operator!=(const resource_cache_iterator &lhs, const resource_cache_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +template +[[nodiscard]] constexpr bool operator<(const resource_cache_iterator &lhs, const resource_cache_iterator &rhs) noexcept { + return lhs.it < rhs.it; +} + +template +[[nodiscard]] constexpr bool operator>(const resource_cache_iterator &lhs, const resource_cache_iterator &rhs) noexcept { + return rhs < lhs; +} + +template +[[nodiscard]] constexpr bool operator<=(const resource_cache_iterator &lhs, const resource_cache_iterator &rhs) noexcept { + return !(lhs > rhs); +} + +template +[[nodiscard]] constexpr bool operator>=(const resource_cache_iterator &lhs, const resource_cache_iterator &rhs) noexcept { + return !(lhs < rhs); +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Basic cache for resources of any type. + * @tparam Type Type of resources managed by a cache. + * @tparam Loader Type of loader used to create the resources. + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +class resource_cache { + using alloc_traits = std::allocator_traits; + static_assert(std::is_same_v, "Invalid value type"); + using container_allocator = typename alloc_traits::template rebind_alloc>; + using container_type = dense_map, container_allocator>; + +public: + /*! @brief Allocator type. */ + using allocator_type = Allocator; + /*! @brief Resource type. */ + using value_type = Type; + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + /*! @brief Loader type. */ + using loader_type = Loader; + /*! @brief Input iterator type. */ + using iterator = internal::resource_cache_iterator; + /*! @brief Constant input iterator type. */ + using const_iterator = internal::resource_cache_iterator; + + /*! @brief Default constructor. */ + resource_cache() + : resource_cache{loader_type{}} {} + + /** + * @brief Constructs an empty cache with a given allocator. + * @param allocator The allocator to use. + */ + explicit resource_cache(const allocator_type &allocator) + : resource_cache{loader_type{}, allocator} {} + + /** + * @brief Constructs an empty cache with a given allocator and loader. + * @param callable The loader to use. + * @param allocator The allocator to use. + */ + explicit resource_cache(const loader_type &callable, const allocator_type &allocator = allocator_type{}) + : pool{container_type{allocator}, callable} {} + + /*! @brief Default copy constructor. */ + resource_cache(const resource_cache &) = default; + + /** + * @brief Allocator-extended copy constructor. + * @param other The instance to copy from. + * @param allocator The allocator to use. + */ + resource_cache(const resource_cache &other, const allocator_type &allocator) + : pool{std::piecewise_construct, std::forward_as_tuple(other.pool.first(), allocator), std::forward_as_tuple(other.pool.second())} {} + + /*! @brief Default move constructor. */ + resource_cache(resource_cache &&) noexcept = default; + + /** + * @brief Allocator-extended move constructor. + * @param other The instance to move from. + * @param allocator The allocator to use. + */ + resource_cache(resource_cache &&other, const allocator_type &allocator) + : pool{std::piecewise_construct, std::forward_as_tuple(std::move(other.pool.first()), allocator), std::forward_as_tuple(std::move(other.pool.second()))} {} + + /*! @brief Default destructor. */ + ~resource_cache() = default; + + /** + * @brief Default copy assignment operator. + * @return This cache. + */ + resource_cache &operator=(const resource_cache &) = default; + + /** + * @brief Default move assignment operator. + * @return This cache. + */ + resource_cache &operator=(resource_cache &&) noexcept = default; + + /** + * @brief Returns the associated allocator. + * @return The associated allocator. + */ + [[nodiscard]] constexpr allocator_type get_allocator() const noexcept { + return pool.first().get_allocator(); + } + + /** + * @brief Returns an iterator to the beginning. + * + * If the cache is empty, the returned iterator will be equal to `end()`. + * + * @return An iterator to the first instance of the internal cache. + */ + [[nodiscard]] const_iterator cbegin() const noexcept { + return pool.first().begin(); + } + + /*! @copydoc cbegin */ + [[nodiscard]] const_iterator begin() const noexcept { + return cbegin(); + } + + /*! @copydoc begin */ + [[nodiscard]] iterator begin() noexcept { + return pool.first().begin(); + } + + /** + * @brief Returns an iterator to the end. + * @return An iterator to the element following the last instance of the + * internal cache. + */ + [[nodiscard]] const_iterator cend() const noexcept { + return pool.first().end(); + } + + /*! @copydoc cend */ + [[nodiscard]] const_iterator end() const noexcept { + return cend(); + } + + /*! @copydoc end */ + [[nodiscard]] iterator end() noexcept { + return pool.first().end(); + } + + /** + * @brief Returns true if a cache contains no resources, false otherwise. + * @return True if the cache contains no resources, false otherwise. + */ + [[nodiscard]] bool empty() const noexcept { + return pool.first().empty(); + } + + /** + * @brief Number of resources managed by a cache. + * @return Number of resources currently stored. + */ + [[nodiscard]] size_type size() const noexcept { + return pool.first().size(); + } + + /*! @brief Clears a cache. */ + void clear() noexcept { + pool.first().clear(); + } + + /** + * @brief Loads a resource, if its identifier does not exist. + * + * Arguments are forwarded directly to the loader and _consumed_ only if the + * resource doesn't already exist. + * + * @warning + * If the resource isn't loaded correctly, the returned handle could be + * invalid and any use of it will result in undefined behavior. + * + * @tparam Args Types of arguments to use to load the resource if required. + * @param id Unique resource identifier. + * @param args Arguments to use to load the resource if required. + * @return A pair consisting of an iterator to the inserted element (or to + * the element that prevented the insertion) and a bool denoting whether the + * insertion took place. + */ + template + std::pair load(const id_type id, Args &&...args) { + if(auto it = pool.first().find(id); it != pool.first().end()) { + return {it, false}; + } + + return pool.first().emplace(id, pool.second()(std::forward(args)...)); + } + + /** + * @brief Force loads a resource, if its identifier does not exist. + * @copydetails load + */ + template + std::pair force_load(const id_type id, Args &&...args) { + return {pool.first().insert_or_assign(id, pool.second()(std::forward(args)...)).first, true}; + } + + /** + * @brief Returns a handle for a given resource identifier. + * + * @warning + * There is no guarantee that the returned handle is valid.
+ * If it is not, any use will result in indefinite behavior. + * + * @param id Unique resource identifier. + * @return A handle for the given resource. + */ + [[nodiscard]] resource operator[](const id_type id) const { + if(auto it = pool.first().find(id); it != pool.first().cend()) { + return resource{it->second}; + } + + return {}; + } + + /*! @copydoc operator[] */ + [[nodiscard]] resource operator[](const id_type id) { + if(auto it = pool.first().find(id); it != pool.first().end()) { + return resource{it->second}; + } + + return {}; + } + + /** + * @brief Checks if a cache contains a given identifier. + * @param id Unique resource identifier. + * @return True if the cache contains the resource, false otherwise. + */ + [[nodiscard]] bool contains(const id_type id) const { + return pool.first().contains(id); + } + + /** + * @brief Removes an element from a given position. + * @param pos An iterator to the element to remove. + * @return An iterator following the removed element. + */ + iterator erase(const_iterator pos) { + const auto it = pool.first().begin(); + return pool.first().erase(it + (pos - const_iterator{it})); + } + + /** + * @brief Removes the given elements from a cache. + * @param first An iterator to the first element of the range of elements. + * @param last An iterator past the last element of the range of elements. + * @return An iterator following the last removed element. + */ + iterator erase(const_iterator first, const_iterator last) { + const auto it = pool.first().begin(); + return pool.first().erase(it + (first - const_iterator{it}), it + (last - const_iterator{it})); + } + + /** + * @brief Removes the given elements from a cache. + * @param id Unique resource identifier. + * @return Number of resources erased (either 0 or 1). + */ + size_type erase(const id_type id) { + return pool.first().erase(id); + } + + /** + * @brief Returns the loader used to create resources. + * @return The loader used to create resources. + */ + [[nodiscard]] loader_type loader() const { + return pool.second(); + } + +private: + compressed_pair pool; +}; + +} // namespace entt + +#endif + +// #include "resource/loader.hpp" +#ifndef ENTT_RESOURCE_LOADER_HPP +#define ENTT_RESOURCE_LOADER_HPP + +#include +#include +// #include "fwd.hpp" + + +namespace entt { + +/** + * @brief Transparent loader for shared resources. + * @tparam Type Type of resources created by the loader. + */ +template +struct resource_loader { + /*! @brief Result type. */ + using result_type = std::shared_ptr; + + /** + * @brief Constructs a shared pointer to a resource from its arguments. + * @tparam Args Types of arguments to use to construct the resource. + * @param args Parameters to use to construct the resource. + * @return A shared pointer to a resource of the given type. + */ + template + result_type operator()(Args &&...args) const { + return std::make_shared(std::forward(args)...); + } +}; + +} // namespace entt + +#endif + +// #include "resource/resource.hpp" +#ifndef ENTT_RESOURCE_RESOURCE_HPP +#define ENTT_RESOURCE_RESOURCE_HPP + +#include +#include +#include +// #include "fwd.hpp" + + +namespace entt { + +/** + * @brief Basic resource handle. + * + * A handle wraps a resource and extends its lifetime. It also shares the same + * resource with all other handles constructed from the same element.
+ * As a rule of thumb, resources should never be copied nor moved. Handles are + * the way to go to push references around. + * + * @tparam Type Type of resource managed by a handle. + */ +template +class resource { + template + friend class resource; + + template + static constexpr bool is_acceptable = !std::is_same_v && std::is_constructible_v; + +public: + /*! @brief Resource type. */ + using element_type = Type; + /*! @brief Handle type. */ + using handle_type = std::shared_ptr; + + /*! @brief Default constructor. */ + resource() noexcept + : value{} {} + + /** + * @brief Creates a new resource handle. + * @param res A handle to a resource. + */ + explicit resource(handle_type res) noexcept + : value{std::move(res)} {} + + /*! @brief Default copy constructor. */ + resource(const resource &) noexcept = default; + + /*! @brief Default move constructor. */ + resource(resource &&) noexcept = default; + + /** + * @brief Aliasing constructor. + * @tparam Other Type of resource managed by the received handle. + * @param other The handle with which to share ownership information. + * @param res Unrelated and unmanaged resources. + */ + template + resource(const resource &other, element_type &res) noexcept + : value{other.value, std::addressof(res)} {} + + /** + * @brief Copy constructs a handle which shares ownership of the resource. + * @tparam Other Type of resource managed by the received handle. + * @param other The handle to copy from. + */ + template>> + resource(const resource &other) noexcept + : value{other.value} {} + + /** + * @brief Move constructs a handle which takes ownership of the resource. + * @tparam Other Type of resource managed by the received handle. + * @param other The handle to move from. + */ + template>> + resource(resource &&other) noexcept + : value{std::move(other.value)} {} + + /*! @brief Default destructor. */ + ~resource() = default; + + /** + * @brief Default copy assignment operator. + * @return This resource handle. + */ + resource &operator=(const resource &) noexcept = default; + + /** + * @brief Default move assignment operator. + * @return This resource handle. + */ + resource &operator=(resource &&) noexcept = default; + + /** + * @brief Copy assignment operator from foreign handle. + * @tparam Other Type of resource managed by the received handle. + * @param other The handle to copy from. + * @return This resource handle. + */ + template>> + resource &operator=(const resource &other) noexcept { + value = other.value; + return *this; + } + + /** + * @brief Move assignment operator from foreign handle. + * @tparam Other Type of resource managed by the received handle. + * @param other The handle to move from. + * @return This resource handle. + */ + template>> + resource &operator=(resource &&other) noexcept { + value = std::move(other.value); + return *this; + } + + /** + * @brief Exchanges the content with that of a given resource. + * @param other Resource to exchange the content with. + */ + void swap(resource &other) noexcept { + using std::swap; + swap(value, other.value); + } + + /** + * @brief Returns a reference to the managed resource. + * + * @warning + * The behavior is undefined if the handle doesn't contain a resource. + * + * @return A reference to the managed resource. + */ + [[nodiscard]] element_type &operator*() const noexcept { + return *value; + } + + /*! @copydoc operator* */ + [[nodiscard]] operator element_type &() const noexcept { + return *value; + } + + /** + * @brief Returns a pointer to the managed resource. + * @return A pointer to the managed resource. + */ + [[nodiscard]] element_type *operator->() const noexcept { + return value.get(); + } + + /** + * @brief Returns true if a handle contains a resource, false otherwise. + * @return True if the handle contains a resource, false otherwise. + */ + [[nodiscard]] explicit operator bool() const noexcept { + return static_cast(value); + } + + /*! @brief Releases the ownership of the managed resource. */ + void reset() { + value.reset(); + } + + /** + * @brief Replaces the managed resource. + * @param other A handle to a resource. + */ + void reset(handle_type other) { + value = std::move(other); + } + + /** + * @brief Returns the underlying resource handle. + * @return The underlying resource handle. + */ + [[nodiscard]] handle_type handle() const noexcept { + return value; + } + +private: + handle_type value; +}; + +/** + * @brief Compares two handles. + * @tparam Lhs Type of resource managed by the first handle. + * @tparam Rhs Type of resource managed by the second handle. + * @param lhs A valid handle. + * @param rhs A valid handle. + * @return True if both handles refer to the same resource, false otherwise. + */ +template +[[nodiscard]] bool operator==(const resource &lhs, const resource &rhs) noexcept { + return (std::addressof(*lhs) == std::addressof(*rhs)); +} + +/** + * @brief Compares two handles. + * @tparam Lhs Type of resource managed by the first handle. + * @tparam Rhs Type of resource managed by the second handle. + * @param lhs A valid handle. + * @param rhs A valid handle. + * @return False if both handles refer to the same resource, true otherwise. + */ +template +[[nodiscard]] bool operator!=(const resource &lhs, const resource &rhs) noexcept { + return !(lhs == rhs); +} + +/** + * @brief Compares two handles. + * @tparam Lhs Type of resource managed by the first handle. + * @tparam Rhs Type of resource managed by the second handle. + * @param lhs A valid handle. + * @param rhs A valid handle. + * @return True if the first handle is less than the second, false otherwise. + */ +template +[[nodiscard]] bool operator<(const resource &lhs, const resource &rhs) noexcept { + return (std::addressof(*lhs) < std::addressof(*rhs)); +} + +/** + * @brief Compares two handles. + * @tparam Lhs Type of resource managed by the first handle. + * @tparam Rhs Type of resource managed by the second handle. + * @param lhs A valid handle. + * @param rhs A valid handle. + * @return True if the first handle is greater than the second, false otherwise. + */ +template +[[nodiscard]] bool operator>(const resource &lhs, const resource &rhs) noexcept { + return rhs < lhs; +} + +/** + * @brief Compares two handles. + * @tparam Lhs Type of resource managed by the first handle. + * @tparam Rhs Type of resource managed by the second handle. + * @param lhs A valid handle. + * @param rhs A valid handle. + * @return True if the first handle is less than or equal to the second, false + * otherwise. + */ +template +[[nodiscard]] bool operator<=(const resource &lhs, const resource &rhs) noexcept { + return !(lhs > rhs); +} + +/** + * @brief Compares two handles. + * @tparam Lhs Type of resource managed by the first handle. + * @tparam Rhs Type of resource managed by the second handle. + * @param lhs A valid handle. + * @param rhs A valid handle. + * @return True if the first handle is greater than or equal to the second, + * false otherwise. + */ +template +[[nodiscard]] bool operator>=(const resource &lhs, const resource &rhs) noexcept { + return !(lhs < rhs); +} + +} // namespace entt + +#endif + +// #include "signal/delegate.hpp" +#ifndef ENTT_SIGNAL_DELEGATE_HPP +#define ENTT_SIGNAL_DELEGATE_HPP + +#include +#include +#include +#include +#include +// #include "../config/config.h" +#ifndef ENTT_CONFIG_CONFIG_H +#define ENTT_CONFIG_CONFIG_H + +// #include "version.h" +#ifndef ENTT_CONFIG_VERSION_H +#define ENTT_CONFIG_VERSION_H + +// #include "macro.h" +#ifndef ENTT_CONFIG_MACRO_H +#define ENTT_CONFIG_MACRO_H + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#define ENTT_STR(arg) #arg +#define ENTT_XSTR(arg) ENTT_STR(arg) + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*) + +#define ENTT_VERSION_MAJOR 3 +#define ENTT_VERSION_MINOR 16 +#define ENTT_VERSION_PATCH 0 + +#define ENTT_VERSION \ + ENTT_XSTR(ENTT_VERSION_MAJOR) \ + "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH) + +// NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION) +# define ENTT_CONSTEXPR +# define ENTT_THROW throw +# define ENTT_TRY try +# define ENTT_CATCH catch(...) +#else +# define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20) +# define ENTT_THROW +# define ENTT_TRY if(true) +# define ENTT_CATCH if(false) +#endif + +#if __has_include() +# include +# +# if defined(__cpp_consteval) +# define ENTT_CONSTEVAL consteval +# endif +#endif + +#ifndef ENTT_CONSTEVAL +# define ENTT_CONSTEVAL constexpr +#endif + +#ifdef ENTT_USE_ATOMIC +# include +# define ENTT_MAYBE_ATOMIC(Type) std::atomic +#else +# define ENTT_MAYBE_ATOMIC(Type) Type +#endif + +#ifndef ENTT_ID_TYPE +# include +# define ENTT_ID_TYPE std::uint32_t +#else +# include // provides coverage for types in the std namespace +#endif + +#ifndef ENTT_SPARSE_PAGE +# define ENTT_SPARSE_PAGE 4096 +#endif + +#ifndef ENTT_PACKED_PAGE +# define ENTT_PACKED_PAGE 1024 +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT +# define ENTT_ASSERT(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT +# include +# define ENTT_ASSERT(condition, msg) assert(((condition) && (msg))) +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg) +#endif + +#define ENTT_FAIL(msg) ENTT_ASSERT(false, msg); + +#ifdef ENTT_NO_ETO +# define ENTT_ETO_TYPE(Type) void +#else +# define ENTT_ETO_TYPE(Type) Type +#endif + +#ifdef ENTT_NO_MIXIN +# define ENTT_STORAGE(Mixin, ...) __VA_ARGS__ +#else +# define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__> +#endif + +#ifdef ENTT_STANDARD_CPP +# define ENTT_NONSTD false +#else +# define ENTT_NONSTD true +# if defined __clang__ || defined __GNUC__ +# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ +# define ENTT_PRETTY_FUNCTION_PREFIX '=' +# define ENTT_PRETTY_FUNCTION_SUFFIX ']' +# elif defined _MSC_VER +# define ENTT_PRETTY_FUNCTION __FUNCSIG__ +# define ENTT_PRETTY_FUNCTION_PREFIX '<' +# define ENTT_PRETTY_FUNCTION_SUFFIX '>' +# endif +#endif + +#ifndef ENTT_EXPORT +# if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER +# define ENTT_EXPORT __declspec(dllexport) +# define ENTT_IMPORT __declspec(dllimport) +# define ENTT_HIDDEN +# elif defined __GNUC__ && __GNUC__ >= 4 +# define ENTT_EXPORT __attribute__((visibility("default"))) +# define ENTT_IMPORT __attribute__((visibility("default"))) +# define ENTT_HIDDEN __attribute__((visibility("hidden"))) +# else /* Unsupported compiler */ +# define ENTT_EXPORT +# define ENTT_IMPORT +# define ENTT_HIDDEN +# endif +#endif + +#ifndef ENTT_API +# if defined ENTT_API_EXPORT +# define ENTT_API ENTT_EXPORT +# elif defined ENTT_API_IMPORT +# define ENTT_API ENTT_IMPORT +# else /* No API */ +# define ENTT_API +# endif +#endif + +#if defined _MSC_VER +# pragma detect_mismatch("entt.version", ENTT_VERSION) +# pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY)) +# pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE)) +# pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD)) +#endif + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + +// #include "../core/type_traits.hpp" +#ifndef ENTT_CORE_TYPE_TRAITS_HPP +#define ENTT_CORE_TYPE_TRAITS_HPP + +#include +#include +#include +#include +#include +// #include "../config/config.h" +#ifndef ENTT_CONFIG_CONFIG_H +#define ENTT_CONFIG_CONFIG_H + +// #include "version.h" +#ifndef ENTT_CONFIG_VERSION_H +#define ENTT_CONFIG_VERSION_H + +// #include "macro.h" +#ifndef ENTT_CONFIG_MACRO_H +#define ENTT_CONFIG_MACRO_H + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#define ENTT_STR(arg) #arg +#define ENTT_XSTR(arg) ENTT_STR(arg) + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*) + +#define ENTT_VERSION_MAJOR 3 +#define ENTT_VERSION_MINOR 16 +#define ENTT_VERSION_PATCH 0 + +#define ENTT_VERSION \ + ENTT_XSTR(ENTT_VERSION_MAJOR) \ + "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH) + +// NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION) +# define ENTT_CONSTEXPR +# define ENTT_THROW throw +# define ENTT_TRY try +# define ENTT_CATCH catch(...) +#else +# define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20) +# define ENTT_THROW +# define ENTT_TRY if(true) +# define ENTT_CATCH if(false) +#endif + +#if __has_include() +# include +# +# if defined(__cpp_consteval) +# define ENTT_CONSTEVAL consteval +# endif +#endif + +#ifndef ENTT_CONSTEVAL +# define ENTT_CONSTEVAL constexpr +#endif + +#ifdef ENTT_USE_ATOMIC +# include +# define ENTT_MAYBE_ATOMIC(Type) std::atomic +#else +# define ENTT_MAYBE_ATOMIC(Type) Type +#endif + +#ifndef ENTT_ID_TYPE +# include +# define ENTT_ID_TYPE std::uint32_t +#else +# include // provides coverage for types in the std namespace +#endif + +#ifndef ENTT_SPARSE_PAGE +# define ENTT_SPARSE_PAGE 4096 +#endif + +#ifndef ENTT_PACKED_PAGE +# define ENTT_PACKED_PAGE 1024 +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT +# define ENTT_ASSERT(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT +# include +# define ENTT_ASSERT(condition, msg) assert(((condition) && (msg))) +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg) +#endif + +#define ENTT_FAIL(msg) ENTT_ASSERT(false, msg); + +#ifdef ENTT_NO_ETO +# define ENTT_ETO_TYPE(Type) void +#else +# define ENTT_ETO_TYPE(Type) Type +#endif + +#ifdef ENTT_NO_MIXIN +# define ENTT_STORAGE(Mixin, ...) __VA_ARGS__ +#else +# define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__> +#endif + +#ifdef ENTT_STANDARD_CPP +# define ENTT_NONSTD false +#else +# define ENTT_NONSTD true +# if defined __clang__ || defined __GNUC__ +# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ +# define ENTT_PRETTY_FUNCTION_PREFIX '=' +# define ENTT_PRETTY_FUNCTION_SUFFIX ']' +# elif defined _MSC_VER +# define ENTT_PRETTY_FUNCTION __FUNCSIG__ +# define ENTT_PRETTY_FUNCTION_PREFIX '<' +# define ENTT_PRETTY_FUNCTION_SUFFIX '>' +# endif +#endif + +#ifndef ENTT_EXPORT +# if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER +# define ENTT_EXPORT __declspec(dllexport) +# define ENTT_IMPORT __declspec(dllimport) +# define ENTT_HIDDEN +# elif defined __GNUC__ && __GNUC__ >= 4 +# define ENTT_EXPORT __attribute__((visibility("default"))) +# define ENTT_IMPORT __attribute__((visibility("default"))) +# define ENTT_HIDDEN __attribute__((visibility("hidden"))) +# else /* Unsupported compiler */ +# define ENTT_EXPORT +# define ENTT_IMPORT +# define ENTT_HIDDEN +# endif +#endif + +#ifndef ENTT_API +# if defined ENTT_API_EXPORT +# define ENTT_API ENTT_EXPORT +# elif defined ENTT_API_IMPORT +# define ENTT_API ENTT_IMPORT +# else /* No API */ +# define ENTT_API +# endif +#endif + +#if defined _MSC_VER +# pragma detect_mismatch("entt.version", ENTT_VERSION) +# pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY)) +# pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE)) +# pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD)) +#endif + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + +// #include "fwd.hpp" +#ifndef ENTT_CORE_FWD_HPP +#define ENTT_CORE_FWD_HPP + +#include +#include +// #include "../config/config.h" + + +namespace entt { + +/*! @brief Possible modes of an any object. */ +enum class any_policy : std::uint8_t { + /*! @brief Default mode, no element available. */ + empty, + /*! @brief Owning mode, dynamically allocated element. */ + dynamic, + /*! @brief Owning mode, embedded element. */ + embedded, + /*! @brief Aliasing mode, non-const reference. */ + ref, + /*! @brief Const aliasing mode, const reference. */ + cref +}; + +// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) +template +class basic_any; + +/*! @brief Alias declaration for type identifiers. */ +using id_type = ENTT_ID_TYPE; + +/*! @brief Alias declaration for the most common use case. */ +using any = basic_any<>; + +template +class compressed_pair; + +template +class basic_hashed_string; + +/*! @brief Aliases for common character types. */ +using hashed_string = basic_hashed_string; + +/*! @brief Aliases for common character types. */ +using hashed_wstring = basic_hashed_string; + +// NOLINTNEXTLINE(bugprone-forward-declaration-namespace) +struct type_info; + +} // namespace entt + +#endif + + +namespace entt { + +/** + * @brief Utility class to disambiguate overloaded functions. + * @tparam N Number of choices available. + */ +template +struct choice_t + // unfortunately, doxygen cannot parse such a construct + : /*! @cond TURN_OFF_DOXYGEN */ choice_t /*! @endcond */ +{}; + +/*! @copybrief choice_t */ +template<> +struct choice_t<0> {}; + +/** + * @brief Variable template for the choice trick. + * @tparam N Number of choices available. + */ +template +inline constexpr choice_t choice{}; + +/** + * @brief Identity type trait. + * + * Useful to establish non-deduced contexts in template argument deduction + * (waiting for C++20) or to provide types through function arguments. + * + * @tparam Type A type. + */ +template +struct type_identity { + /*! @brief Identity type. */ + using type = Type; +}; + +/** + * @brief Helper type. + * @tparam Type A type. + */ +template +using type_identity_t = typename type_identity::type; + +/** + * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains. + * @tparam Type The type of which to return the size. + */ +template +struct size_of: std::integral_constant {}; + +/*! @copydoc size_of */ +template +struct size_of> + // NOLINTNEXTLINE(bugprone-sizeof-expression) + : std::integral_constant {}; + +/** + * @brief Helper variable template. + * @tparam Type The type of which to return the size. + */ +template +inline constexpr std::size_t size_of_v = size_of::value; + +/** + * @brief Using declaration to be used to _repeat_ the same type a number of + * times equal to the size of a given parameter pack. + * @tparam Type A type to repeat. + */ +template +using unpack_as_type = Type; + +/** + * @brief Helper variable template to be used to _repeat_ the same value a + * number of times equal to the size of a given parameter pack. + * @tparam Value A value to repeat. + */ +template +inline constexpr auto unpack_as_value = Value; + +/** + * @brief Wraps a static constant. + * @tparam Value A static constant. + */ +template +using integral_constant = std::integral_constant; + +/** + * @brief Alias template to facilitate the creation of named values. + * @tparam Value A constant value at least convertible to `id_type`. + */ +template +using tag = integral_constant; + +/** + * @brief A class to use to push around lists of types, nothing more. + * @tparam Type Types provided by the type list. + */ +template +struct type_list { + /*! @brief Type list type. */ + using type = type_list; + /*! @brief Compile-time number of elements in the type list. */ + static constexpr auto size = sizeof...(Type); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_element; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Index Index of the type to return. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element> + : type_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element<0u, type_list> { + /*! @brief Searched type. */ + using type = First; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Type list to search into. + */ +template +using type_list_element_t = typename type_list_element::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_index; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 1u + type_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + static_assert(type_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +inline constexpr std::size_t type_list_index_v = type_list_index::value; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @return A type list composed by the types of both the type lists. + */ +template +constexpr type_list operator+(type_list, type_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_cat; + +/*! @brief Concatenates multiple type lists. */ +template<> +struct type_list_cat<> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list<>; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @tparam List Other type lists, if any. + */ +template +struct type_list_cat, type_list, List...> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = typename type_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the type list. + */ +template +struct type_list_cat> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list; +}; + +/** + * @brief Helper type. + * @tparam List Type lists to concatenate. + */ +template +using type_list_cat_t = typename type_list_cat::type; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct type_list_unique; + +template +struct type_list_unique, Type...> + : std::conditional_t<(std::is_same_v || ...), type_list_unique, Type...>, type_list_unique, Type..., First>> {}; + +template +struct type_list_unique, Type...> { + using type = type_list; +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Removes duplicates types from a type list. + * @tparam List Type list. + */ +template +struct type_list_unique { + /*! @brief A type list without duplicate types. */ + using type = typename internal::type_list_unique::type; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + */ +template +using type_list_unique_t = typename type_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a type list contains a + * given type, false otherwise. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +struct type_list_contains; + +/** + * @copybrief type_list_contains + * @tparam Type Types provided by the type list. + * @tparam Other Type to look for. + */ +template +struct type_list_contains, Other> + : std::bool_constant<(std::is_same_v || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +inline constexpr bool type_list_contains_v = type_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_diff; + +/** + * @brief Computes the difference between two type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + */ +template +struct type_list_diff, type_list> { + /*! @brief A type list that is the difference between the two type lists. */ + using type = type_list_cat_t, Type>, type_list<>, type_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Type lists between which to compute the difference. + */ +template +using type_list_diff_t = typename type_list_diff::type; + +/*! @brief Primary template isn't defined on purpose. */ +template class> +struct type_list_transform; + +/** + * @brief Applies a given _function_ to a type list and generate a new list. + * @tparam Type Types provided by the type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +struct type_list_transform, Op> { + /*! @brief Resulting type list after applying the transform function. */ + // NOLINTNEXTLINE(modernize-type-traits) + using type = type_list::type...>; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +using type_list_transform_t = typename type_list_transform::type; + +/** + * @brief A class to use to push around lists of constant values, nothing more. + * @tparam Value Values provided by the value list. + */ +template +struct value_list { + /*! @brief Value list type. */ + using type = value_list; + /*! @brief Compile-time number of elements in the value list. */ + static constexpr auto size = sizeof...(Value); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_element; + +/** + * @brief Provides compile-time indexed access to the values of a value list. + * @tparam Index Index of the value to return. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element> + : value_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element<0u, value_list> { + /*! @brief Searched type. */ + using type = decltype(Value); + /*! @brief Searched value. */ + static constexpr auto value = Value; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Value list to search into. + */ +template +using value_list_element_t = typename value_list_element::type; + +/** + * @brief Helper type. + * @tparam Index Index of the value to return. + * @tparam List Value list to search into. + */ +template +inline constexpr auto value_list_element_v = value_list_element::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_index; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam First First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 1u + value_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + static_assert(value_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +inline constexpr std::size_t value_list_index_v = value_list_index::value; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @return A value list composed by the values of both the value lists. + */ +template +constexpr value_list operator+(value_list, value_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_cat; + +/*! @brief Concatenates multiple value lists. */ +template<> +struct value_list_cat<> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list<>; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @tparam List Other value lists, if any. + */ +template +struct value_list_cat, value_list, List...> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = typename value_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the value list. + */ +template +struct value_list_cat> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list; +}; + +/** + * @brief Helper type. + * @tparam List Value lists to concatenate. + */ +template +using value_list_cat_t = typename value_list_cat::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_unique; + +/** + * @brief Removes duplicates values from a value list. + * @tparam Value One of the values provided by the given value list. + * @tparam Other The other values provided by the given value list. + */ +template +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = std::conditional_t< + ((Value == Other) || ...), + typename value_list_unique>::type, + value_list_cat_t, typename value_list_unique>::type>>; +}; + +/*! @brief Removes duplicates values from a value list. */ +template<> +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = value_list<>; +}; + +/** + * @brief Helper type. + * @tparam Type A value list. + */ +template +using value_list_unique_t = typename value_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a value list contains + * a given value, false otherwise. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +struct value_list_contains; + +/** + * @copybrief value_list_contains + * @tparam Value Values provided by the value list. + * @tparam Other Value to look for. + */ +template +struct value_list_contains, Other> + : std::bool_constant<((Value == Other) || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +inline constexpr bool value_list_contains_v = value_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_diff; + +/** + * @brief Computes the difference between two value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + */ +template +struct value_list_diff, value_list> { + /*! @brief A value list that is the difference between the two value lists. */ + using type = value_list_cat_t, Value>, value_list<>, value_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Value lists between which to compute the difference. + */ +template +using value_list_diff_t = typename value_list_diff::type; + +/*! @brief Same as std::is_invocable, but with tuples. */ +template +struct is_applicable: std::false_type {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @brief Helper variable template. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_v = is_applicable::value; + +/*! @brief Same as std::is_invocable_r, but with tuples for arguments. */ +template +struct is_applicable_r: std::false_type {}; + +/** + * @copybrief is_applicable_r + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +struct is_applicable_r>: std::is_invocable_r {}; + +/** + * @brief Helper variable template. + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_r_v = is_applicable_r::value; + +/** + * @brief Provides the member constant `value` to true if a given type is + * complete, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_complete: std::false_type {}; + +/*! @copydoc is_complete */ +template +struct is_complete>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_complete_v = is_complete::value; + +/** + * @brief Provides the member constant `value` to true if a given type is an + * iterator, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_iterator: std::false_type {}; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_iterator_category: std::false_type {}; + +template +struct has_iterator_category::iterator_category>>: std::true_type {}; + +} // namespace internal +/*! @endcond */ + +/*! @copydoc is_iterator */ +template +struct is_iterator>>>> + : internal::has_iterator_category {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_iterator_v = is_iterator::value; + +/** + * @brief Provides the member constant `value` to true if a given type is both + * an empty and non-final class, false otherwise. + * @tparam Type The type to test + */ +template +struct is_ebco_eligible + : std::bool_constant && !std::is_final_v> {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_ebco_eligible_v = is_ebco_eligible::value; + +/** + * @brief Provides the member constant `value` to true if `Type::is_transparent` + * is valid and denotes a type, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_transparent: std::false_type {}; + +/*! @copydoc is_transparent */ +template +struct is_transparent>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_transparent_v = is_transparent::value; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_tuple_size_value: std::false_type {}; + +template +struct has_tuple_size_value::value)>>: std::true_type {}; + +template +struct has_value_type: std::false_type {}; + +template +struct has_value_type>: std::true_type {}; + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable(); + +template +[[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence) { + return (dispatch_is_equality_comparable>() && ...); +} + +template +[[nodiscard]] constexpr bool maybe_equality_comparable(char) { + return false; +} + +template +[[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval() == std::declval()) { + return true; +} + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable() { + // NOLINTBEGIN(modernize-use-transparent-functors) + if constexpr(std::is_array_v) { + return false; + } else if constexpr(is_complete_v>>) { + if constexpr(has_tuple_size_value::value) { + return maybe_equality_comparable(0) && unpack_maybe_equality_comparable(std::make_index_sequence::value>{}); + } else { + return maybe_equality_comparable(0); + } + } else if constexpr(has_value_type::value) { + if constexpr(is_iterator_v || std::is_same_v || dispatch_is_equality_comparable()) { + return maybe_equality_comparable(0); + } else { + return false; + } + } else { + return maybe_equality_comparable(0); + } + // NOLINTEND(modernize-use-transparent-functors) +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Provides the member constant `value` to true if a given type is + * equality comparable, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_equality_comparable: std::bool_constant()> {}; + +/*! @copydoc is_equality_comparable */ +template +struct is_equality_comparable: is_equality_comparable {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_equality_comparable_v = is_equality_comparable::value; + +/** + * @brief Transcribes the constness of a type to another type. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = std::remove_const_t; +}; + +/*! @copydoc constness_as */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = const To; +}; + +/** + * @brief Alias template to facilitate the transcription of the constness. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +using constness_as_t = typename constness_as::type; + +/** + * @brief Extracts the class of a non-static member object or function. + * @tparam Member A pointer to a non-static member object or function. + */ +template +class member_class { + static_assert(std::is_member_pointer_v, "Invalid pointer type to non-static member object or function"); + + template + static Class *clazz(Ret (Class::*)(Args...)); + + template + static Class *clazz(Ret (Class::*)(Args...) const); + + template + static Class *clazz(Type Class::*); + +public: + /*! @brief The class of the given non-static member object or function. */ + using type = std::remove_pointer_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Member A pointer to a non-static member object or function. + */ +template +using member_class_t = typename member_class::type; + +/** + * @brief Extracts the n-th argument of a _callable_ type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid _callable_ type. + */ +template +class nth_argument { + template + static constexpr type_list pick_up(Ret (*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...) const); + + template + static constexpr type_list pick_up(Type Class ::*); + + template + static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&); + +public: + /*! @brief N-th argument of the _callable_ type. */ + using type = type_list_element_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid function, member function or data member type. + */ +template +using nth_argument_t = typename nth_argument::type; + +} // namespace entt + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::type_list_element> {}; + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::value_list_element> {}; + +#endif + +// #include "fwd.hpp" +#ifndef ENTT_SIGNAL_FWD_HPP +#define ENTT_SIGNAL_FWD_HPP + +#include + +namespace entt { + +template +class delegate; + +template> +class basic_dispatcher; + +template> +class emitter; + +class connection; + +struct scoped_connection; + +template +class sink; + +template> +class sigh; + +/*! @brief Alias declaration for the most common use case. */ +using dispatcher = basic_dispatcher<>; + +/*! @brief Disambiguation tag for constructors and the like. */ +template +struct connect_arg_t { + /*! @brief Default constructor. */ + explicit connect_arg_t() = default; +}; + +/** + * @brief Constant of type connect_arg_t used to disambiguate calls. + * @tparam Candidate Element to connect (likely a free or member function). + */ +template +inline constexpr connect_arg_t connect_arg{}; + +} // namespace entt + +#endif + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +constexpr auto function_pointer(Ret (*)(Args...)) -> Ret (*)(Args...); + +template +constexpr auto function_pointer(Ret (*)(Type, Args...), Other &&) -> Ret (*)(Args...); + +template +constexpr auto function_pointer(Ret (Class::*)(Args...), Other &&...) -> Ret (*)(Args...); + +template +constexpr auto function_pointer(Ret (Class::*)(Args...) const, Other &&...) -> Ret (*)(Args...); + +template>> +constexpr auto function_pointer(Type Class::*, Other &&...) -> Type (*)(); + +template +using function_pointer_t = decltype(function_pointer(std::declval()...)); + +template +[[nodiscard]] constexpr auto index_sequence_for(Ret (*)(Args...)) { + return std::index_sequence_for{}; +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Basic delegate implementation. + * + * Primary template isn't defined on purpose. All the specializations give a + * compile-time error unless the template parameter is a function type. + */ +template +class delegate; + +/** + * @brief Utility class to use to send around functions and members. + * + * Unmanaged delegate for function pointers and members. Users of this class are + * in charge of disconnecting instances before deleting them. + * + * A delegate can be used as a general purpose invoker without memory overhead + * for free functions possibly with payloads and bound or unbound members. + * + * @tparam Ret Return type of a function type. + * @tparam Args Types of arguments of a function type. + */ +template +class delegate { + using return_type = std::remove_const_t; + using delegate_type = return_type(const void *, Args...); + + template + [[nodiscard]] auto wrap(std::index_sequence) noexcept { + return [](const void *, Args... args) -> return_type { + [[maybe_unused]] const auto arguments = std::forward_as_tuple(std::forward(args)...); + [[maybe_unused]] constexpr auto offset = !std::is_invocable_r_v>...> * (sizeof...(Args) - sizeof...(Index)); + return static_cast(std::invoke(Candidate, std::forward>>(std::get(arguments))...)); + }; + } + + template + [[nodiscard]] auto wrap(Type &, std::index_sequence) noexcept { + return [](const void *payload, Args... args) -> return_type { + Type *curr = static_cast(const_cast *>(payload)); + [[maybe_unused]] const auto arguments = std::forward_as_tuple(std::forward(args)...); + [[maybe_unused]] constexpr auto offset = !std::is_invocable_r_v>...> * (sizeof...(Args) - sizeof...(Index)); + return static_cast(std::invoke(Candidate, *curr, std::forward>>(std::get(arguments))...)); + }; + } + + template + [[nodiscard]] auto wrap(Type *, std::index_sequence) noexcept { + return [](const void *payload, Args... args) -> return_type { + Type *curr = static_cast(const_cast *>(payload)); + [[maybe_unused]] const auto arguments = std::forward_as_tuple(std::forward(args)...); + [[maybe_unused]] constexpr auto offset = !std::is_invocable_r_v>...> * (sizeof...(Args) - sizeof...(Index)); + return static_cast(std::invoke(Candidate, curr, std::forward>>(std::get(arguments))...)); + }; + } + +public: + /*! @brief Function type of the contained target. */ + using function_type = Ret(const void *, Args...); + /*! @brief Function type of the delegate. */ + using type = Ret(Args...); + /*! @brief Return type of the delegate. */ + using result_type = Ret; + + /*! @brief Default constructor. */ + delegate() noexcept = default; + + /** + * @brief Constructs a delegate with a given object or payload, if any. + * @tparam Candidate Function or member to connect to the delegate. + * @tparam Type Type of class or type of payload, if any. + * @param value_or_instance Optional valid object that fits the purpose. + */ + template + delegate(connect_arg_t, Type &&...value_or_instance) noexcept { + connect(std::forward(value_or_instance)...); + } + + /** + * @brief Constructs a delegate and connects an user defined function with + * optional payload. + * @param function Function to connect to the delegate. + * @param payload User defined arbitrary data. + */ + delegate(function_type *function, const void *payload = nullptr) noexcept { + connect(function, payload); + } + + /** + * @brief Connects a free function or an unbound member to a delegate. + * @tparam Candidate Function or member to connect to the delegate. + */ + template + void connect() noexcept { + instance = nullptr; + + if constexpr(std::is_invocable_r_v) { + fn = [](const void *, Args... args) -> return_type { + return Ret(std::invoke(Candidate, std::forward(args)...)); + }; + } else if constexpr(std::is_member_pointer_v) { + fn = wrap(internal::index_sequence_for>>(internal::function_pointer_t{})); + } else { + fn = wrap(internal::index_sequence_for(internal::function_pointer_t{})); + } + } + + /** + * @brief Connects a free function with payload or a bound member to a + * delegate. + * + * The delegate isn't responsible for the connected object or the payload. + * Users must always guarantee that the lifetime of the instance overcomes + * the one of the delegate.
+ * When used to connect a free function with payload, its signature must be + * such that the instance is the first argument before the ones used to + * define the delegate itself. + * + * @tparam Candidate Function or member to connect to the delegate. + * @tparam Type Type of class or type of payload. + * @param value_or_instance A valid reference that fits the purpose. + */ + template + void connect(Type &value_or_instance) noexcept { + instance = &value_or_instance; + + if constexpr(std::is_invocable_r_v) { + fn = [](const void *payload, Args... args) -> return_type { + Type *curr = static_cast(const_cast *>(payload)); + return Ret(std::invoke(Candidate, *curr, std::forward(args)...)); + }; + } else { + fn = wrap(value_or_instance, internal::index_sequence_for(internal::function_pointer_t{})); + } + } + + /** + * @brief Connects a free function with payload or a bound member to a + * delegate. + * + * @sa connect(Type &) + * + * @tparam Candidate Function or member to connect to the delegate. + * @tparam Type Type of class or type of payload. + * @param value_or_instance A valid pointer that fits the purpose. + */ + template + void connect(Type *value_or_instance) noexcept { + instance = value_or_instance; + + if constexpr(std::is_invocable_r_v) { + fn = [](const void *payload, Args... args) -> return_type { + Type *curr = static_cast(const_cast *>(payload)); + return Ret(std::invoke(Candidate, curr, std::forward(args)...)); + }; + } else { + fn = wrap(value_or_instance, internal::index_sequence_for(internal::function_pointer_t{})); + } + } + + /** + * @brief Connects an user defined function with optional payload to a + * delegate. + * + * The delegate isn't responsible for the connected object or the payload. + * Users must always guarantee that the lifetime of an instance overcomes + * the one of the delegate.
+ * The payload is returned as the first argument to the target function in + * all cases. + * + * @param function Function to connect to the delegate. + * @param payload User defined arbitrary data. + */ + void connect(function_type *function, const void *payload = nullptr) noexcept { + ENTT_ASSERT(function != nullptr, "Uninitialized function pointer"); + instance = payload; + fn = function; + } + + /** + * @brief Resets a delegate. + * + * After a reset, a delegate cannot be invoked anymore. + */ + void reset() noexcept { + instance = nullptr; + fn = nullptr; + } + + /** + * @brief Returns a pointer to the stored callable function target, if any. + * @return An opaque pointer to the stored callable function target. + */ + [[nodiscard]] function_type *target() const noexcept { + return fn; + } + + /** + * @brief Returns the instance or the payload linked to a delegate, if any. + * @return An opaque pointer to the underlying data. + */ + [[nodiscard]] const void *data() const noexcept { + return instance; + } + + /** + * @brief Triggers a delegate. + * + * The delegate invokes the underlying function and returns the result. + * + * @warning + * Attempting to trigger an invalid delegate results in undefined + * behavior. + * + * @param args Arguments to use to invoke the underlying function. + * @return The value returned by the underlying function. + */ + Ret operator()(Args... args) const { + ENTT_ASSERT(static_cast(*this), "Uninitialized delegate"); + return fn(instance, std::forward(args)...); + } + + /** + * @brief Checks whether a delegate actually stores a listener. + * @return False if the delegate is empty, true otherwise. + */ + [[nodiscard]] explicit operator bool() const noexcept { + // no need to also test instance + return !(fn == nullptr); + } + + /** + * @brief Compares the contents of two delegates. + * @param other Delegate with which to compare. + * @return False if the two contents differ, true otherwise. + */ + [[nodiscard]] bool operator==(const delegate &other) const noexcept { + return fn == other.fn && instance == other.instance; + } + +private: + const void *instance{}; + delegate_type *fn{}; +}; + +/** + * @brief Compares the contents of two delegates. + * @tparam Ret Return type of a function type. + * @tparam Args Types of arguments of a function type. + * @param lhs A valid delegate object. + * @param rhs A valid delegate object. + * @return True if the two contents differ, false otherwise. + */ +template +[[nodiscard]] bool operator!=(const delegate &lhs, const delegate &rhs) noexcept { + return !(lhs == rhs); +} + +/** + * @brief Deduction guide. + * @tparam Candidate Function or member to connect to the delegate. + */ +template +delegate(connect_arg_t) -> delegate>>; + +/** + * @brief Deduction guide. + * @tparam Candidate Function or member to connect to the delegate. + * @tparam Type Type of class or type of payload. + */ +template +delegate(connect_arg_t, Type &&) -> delegate>>; + +/** + * @brief Deduction guide. + * @tparam Ret Return type of a function type. + * @tparam Args Types of arguments of a function type. + */ +template +delegate(Ret (*)(const void *, Args...), const void * = nullptr) -> delegate; + +} // namespace entt + +#endif + +// #include "signal/dispatcher.hpp" +#ifndef ENTT_SIGNAL_DISPATCHER_HPP +#define ENTT_SIGNAL_DISPATCHER_HPP + +#include +#include +#include +#include +#include +#include +// #include "../container/dense_map.hpp" +#ifndef ENTT_CONTAINER_DENSE_MAP_HPP +#define ENTT_CONTAINER_DENSE_MAP_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #include "../config/config.h" +#ifndef ENTT_CONFIG_CONFIG_H +#define ENTT_CONFIG_CONFIG_H + +// #include "version.h" +#ifndef ENTT_CONFIG_VERSION_H +#define ENTT_CONFIG_VERSION_H + +// #include "macro.h" +#ifndef ENTT_CONFIG_MACRO_H +#define ENTT_CONFIG_MACRO_H + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#define ENTT_STR(arg) #arg +#define ENTT_XSTR(arg) ENTT_STR(arg) + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*) + +#define ENTT_VERSION_MAJOR 3 +#define ENTT_VERSION_MINOR 16 +#define ENTT_VERSION_PATCH 0 + +#define ENTT_VERSION \ + ENTT_XSTR(ENTT_VERSION_MAJOR) \ + "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH) + +// NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION) +# define ENTT_CONSTEXPR +# define ENTT_THROW throw +# define ENTT_TRY try +# define ENTT_CATCH catch(...) +#else +# define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20) +# define ENTT_THROW +# define ENTT_TRY if(true) +# define ENTT_CATCH if(false) +#endif + +#if __has_include() +# include +# +# if defined(__cpp_consteval) +# define ENTT_CONSTEVAL consteval +# endif +#endif + +#ifndef ENTT_CONSTEVAL +# define ENTT_CONSTEVAL constexpr +#endif + +#ifdef ENTT_USE_ATOMIC +# include +# define ENTT_MAYBE_ATOMIC(Type) std::atomic +#else +# define ENTT_MAYBE_ATOMIC(Type) Type +#endif + +#ifndef ENTT_ID_TYPE +# include +# define ENTT_ID_TYPE std::uint32_t +#else +# include // provides coverage for types in the std namespace +#endif + +#ifndef ENTT_SPARSE_PAGE +# define ENTT_SPARSE_PAGE 4096 +#endif + +#ifndef ENTT_PACKED_PAGE +# define ENTT_PACKED_PAGE 1024 +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT +# define ENTT_ASSERT(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT +# include +# define ENTT_ASSERT(condition, msg) assert(((condition) && (msg))) +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg) +#endif + +#define ENTT_FAIL(msg) ENTT_ASSERT(false, msg); + +#ifdef ENTT_NO_ETO +# define ENTT_ETO_TYPE(Type) void +#else +# define ENTT_ETO_TYPE(Type) Type +#endif + +#ifdef ENTT_NO_MIXIN +# define ENTT_STORAGE(Mixin, ...) __VA_ARGS__ +#else +# define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__> +#endif + +#ifdef ENTT_STANDARD_CPP +# define ENTT_NONSTD false +#else +# define ENTT_NONSTD true +# if defined __clang__ || defined __GNUC__ +# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ +# define ENTT_PRETTY_FUNCTION_PREFIX '=' +# define ENTT_PRETTY_FUNCTION_SUFFIX ']' +# elif defined _MSC_VER +# define ENTT_PRETTY_FUNCTION __FUNCSIG__ +# define ENTT_PRETTY_FUNCTION_PREFIX '<' +# define ENTT_PRETTY_FUNCTION_SUFFIX '>' +# endif +#endif + +#ifndef ENTT_EXPORT +# if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER +# define ENTT_EXPORT __declspec(dllexport) +# define ENTT_IMPORT __declspec(dllimport) +# define ENTT_HIDDEN +# elif defined __GNUC__ && __GNUC__ >= 4 +# define ENTT_EXPORT __attribute__((visibility("default"))) +# define ENTT_IMPORT __attribute__((visibility("default"))) +# define ENTT_HIDDEN __attribute__((visibility("hidden"))) +# else /* Unsupported compiler */ +# define ENTT_EXPORT +# define ENTT_IMPORT +# define ENTT_HIDDEN +# endif +#endif + +#ifndef ENTT_API +# if defined ENTT_API_EXPORT +# define ENTT_API ENTT_EXPORT +# elif defined ENTT_API_IMPORT +# define ENTT_API ENTT_IMPORT +# else /* No API */ +# define ENTT_API +# endif +#endif + +#if defined _MSC_VER +# pragma detect_mismatch("entt.version", ENTT_VERSION) +# pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY)) +# pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE)) +# pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD)) +#endif + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + +// #include "../core/bit.hpp" +#ifndef ENTT_CORE_BIT_HPP +#define ENTT_CORE_BIT_HPP + +#include +#include +#include +// #include "../config/config.h" +#ifndef ENTT_CONFIG_CONFIG_H +#define ENTT_CONFIG_CONFIG_H + +// #include "version.h" +#ifndef ENTT_CONFIG_VERSION_H +#define ENTT_CONFIG_VERSION_H + +// #include "macro.h" +#ifndef ENTT_CONFIG_MACRO_H +#define ENTT_CONFIG_MACRO_H + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#define ENTT_STR(arg) #arg +#define ENTT_XSTR(arg) ENTT_STR(arg) + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*) + +#define ENTT_VERSION_MAJOR 3 +#define ENTT_VERSION_MINOR 16 +#define ENTT_VERSION_PATCH 0 + +#define ENTT_VERSION \ + ENTT_XSTR(ENTT_VERSION_MAJOR) \ + "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH) + +// NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*) + +#endif + + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + +#if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION) +# define ENTT_CONSTEXPR +# define ENTT_THROW throw +# define ENTT_TRY try +# define ENTT_CATCH catch(...) +#else +# define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20) +# define ENTT_THROW +# define ENTT_TRY if(true) +# define ENTT_CATCH if(false) +#endif + +#if __has_include() +# include +# +# if defined(__cpp_consteval) +# define ENTT_CONSTEVAL consteval +# endif +#endif + +#ifndef ENTT_CONSTEVAL +# define ENTT_CONSTEVAL constexpr +#endif + +#ifdef ENTT_USE_ATOMIC +# include +# define ENTT_MAYBE_ATOMIC(Type) std::atomic +#else +# define ENTT_MAYBE_ATOMIC(Type) Type +#endif + +#ifndef ENTT_ID_TYPE +# include +# define ENTT_ID_TYPE std::uint32_t +#else +# include // provides coverage for types in the std namespace +#endif + +#ifndef ENTT_SPARSE_PAGE +# define ENTT_SPARSE_PAGE 4096 +#endif + +#ifndef ENTT_PACKED_PAGE +# define ENTT_PACKED_PAGE 1024 +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT +# define ENTT_ASSERT(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT +# include +# define ENTT_ASSERT(condition, msg) assert(((condition) && (msg))) +#endif + +#ifdef ENTT_DISABLE_ASSERT +# undef ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0)) +#elif !defined ENTT_ASSERT_CONSTEXPR +# define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg) +#endif + +#define ENTT_FAIL(msg) ENTT_ASSERT(false, msg); + +#ifdef ENTT_NO_ETO +# define ENTT_ETO_TYPE(Type) void +#else +# define ENTT_ETO_TYPE(Type) Type +#endif + +#ifdef ENTT_NO_MIXIN +# define ENTT_STORAGE(Mixin, ...) __VA_ARGS__ +#else +# define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__> +#endif + +#ifdef ENTT_STANDARD_CPP +# define ENTT_NONSTD false +#else +# define ENTT_NONSTD true +# if defined __clang__ || defined __GNUC__ +# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ +# define ENTT_PRETTY_FUNCTION_PREFIX '=' +# define ENTT_PRETTY_FUNCTION_SUFFIX ']' +# elif defined _MSC_VER +# define ENTT_PRETTY_FUNCTION __FUNCSIG__ +# define ENTT_PRETTY_FUNCTION_PREFIX '<' +# define ENTT_PRETTY_FUNCTION_SUFFIX '>' +# endif +#endif + +#ifndef ENTT_EXPORT +# if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER +# define ENTT_EXPORT __declspec(dllexport) +# define ENTT_IMPORT __declspec(dllimport) +# define ENTT_HIDDEN +# elif defined __GNUC__ && __GNUC__ >= 4 +# define ENTT_EXPORT __attribute__((visibility("default"))) +# define ENTT_IMPORT __attribute__((visibility("default"))) +# define ENTT_HIDDEN __attribute__((visibility("hidden"))) +# else /* Unsupported compiler */ +# define ENTT_EXPORT +# define ENTT_IMPORT +# define ENTT_HIDDEN +# endif +#endif + +#ifndef ENTT_API +# if defined ENTT_API_EXPORT +# define ENTT_API ENTT_EXPORT +# elif defined ENTT_API_IMPORT +# define ENTT_API ENTT_IMPORT +# else /* No API */ +# define ENTT_API +# endif +#endif + +#if defined _MSC_VER +# pragma detect_mismatch("entt.version", ENTT_VERSION) +# pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY)) +# pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE)) +# pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD)) +#endif + +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif + + +namespace entt { + +/** + * @brief Returns the number of set bits in a value (waiting for C++20 and + * `std::popcount`). + * @tparam Type Unsigned integer type. + * @param value A value of unsigned integer type. + * @return The number of set bits in the value. + */ +template +[[nodiscard]] constexpr std::enable_if_t, int> popcount(const Type value) noexcept { + return value ? (int(value & 1) + popcount(static_cast(value >> 1))) : 0; +} + +/** + * @brief Checks whether a value is a power of two or not (waiting for C++20 and + * `std::has_single_bit`). + * @tparam Type Unsigned integer type. + * @param value A value of unsigned integer type. + * @return True if the value is a power of two, false otherwise. + */ +template +[[nodiscard]] constexpr std::enable_if_t, bool> has_single_bit(const Type value) noexcept { + return value && ((value & (value - 1)) == 0); +} + +/** + * @brief Computes the smallest power of two greater than or equal to a value + * (waiting for C++20 and `std::bit_ceil`). + * @tparam Type Unsigned integer type. + * @param value A value of unsigned integer type. + * @return The smallest power of two greater than or equal to the given value. + */ +template +[[nodiscard]] constexpr std::enable_if_t, Type> next_power_of_two(const Type value) noexcept { + // NOLINTNEXTLINE(bugprone-assert-side-effect) + ENTT_ASSERT_CONSTEXPR(value < (Type{1u} << (std::numeric_limits::digits - 1)), "Numeric limits exceeded"); + Type curr = value - (value != 0u); + + for(int next = 1; next < std::numeric_limits::digits; next = next * 2) { + curr |= (curr >> next); + } + + return ++curr; +} + +/** + * @brief Fast module utility function (powers of two only). + * @tparam Type Unsigned integer type. + * @param value A value of unsigned integer type. + * @param mod _Modulus_, it must be a power of two. + * @return The common remainder. + */ +template +[[nodiscard]] constexpr std::enable_if_t, Type> fast_mod(const Type value, const std::size_t mod) noexcept { + ENTT_ASSERT_CONSTEXPR(has_single_bit(mod), "Value must be a power of two"); + return static_cast(value & (mod - 1u)); +} + +} // namespace entt + +#endif + +// #include "../core/compressed_pair.hpp" +#ifndef ENTT_CORE_COMPRESSED_PAIR_HPP +#define ENTT_CORE_COMPRESSED_PAIR_HPP + +#include +#include +#include +#include +// #include "fwd.hpp" +#ifndef ENTT_CORE_FWD_HPP +#define ENTT_CORE_FWD_HPP + +#include +#include +// #include "../config/config.h" + + +namespace entt { + +/*! @brief Possible modes of an any object. */ +enum class any_policy : std::uint8_t { + /*! @brief Default mode, no element available. */ + empty, + /*! @brief Owning mode, dynamically allocated element. */ + dynamic, + /*! @brief Owning mode, embedded element. */ + embedded, + /*! @brief Aliasing mode, non-const reference. */ + ref, + /*! @brief Const aliasing mode, const reference. */ + cref +}; + +// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) +template +class basic_any; + +/*! @brief Alias declaration for type identifiers. */ +using id_type = ENTT_ID_TYPE; + +/*! @brief Alias declaration for the most common use case. */ +using any = basic_any<>; + +template +class compressed_pair; + +template +class basic_hashed_string; + +/*! @brief Aliases for common character types. */ +using hashed_string = basic_hashed_string; + +/*! @brief Aliases for common character types. */ +using hashed_wstring = basic_hashed_string; + +// NOLINTNEXTLINE(bugprone-forward-declaration-namespace) +struct type_info; + +} // namespace entt + +#endif + +// #include "type_traits.hpp" +#ifndef ENTT_CORE_TYPE_TRAITS_HPP +#define ENTT_CORE_TYPE_TRAITS_HPP + +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "fwd.hpp" + + +namespace entt { + +/** + * @brief Utility class to disambiguate overloaded functions. + * @tparam N Number of choices available. + */ +template +struct choice_t + // unfortunately, doxygen cannot parse such a construct + : /*! @cond TURN_OFF_DOXYGEN */ choice_t /*! @endcond */ +{}; + +/*! @copybrief choice_t */ +template<> +struct choice_t<0> {}; + +/** + * @brief Variable template for the choice trick. + * @tparam N Number of choices available. + */ +template +inline constexpr choice_t choice{}; + +/** + * @brief Identity type trait. + * + * Useful to establish non-deduced contexts in template argument deduction + * (waiting for C++20) or to provide types through function arguments. + * + * @tparam Type A type. + */ +template +struct type_identity { + /*! @brief Identity type. */ + using type = Type; +}; + +/** + * @brief Helper type. + * @tparam Type A type. + */ +template +using type_identity_t = typename type_identity::type; + +/** + * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains. + * @tparam Type The type of which to return the size. + */ +template +struct size_of: std::integral_constant {}; + +/*! @copydoc size_of */ +template +struct size_of> + // NOLINTNEXTLINE(bugprone-sizeof-expression) + : std::integral_constant {}; + +/** + * @brief Helper variable template. + * @tparam Type The type of which to return the size. + */ +template +inline constexpr std::size_t size_of_v = size_of::value; + +/** + * @brief Using declaration to be used to _repeat_ the same type a number of + * times equal to the size of a given parameter pack. + * @tparam Type A type to repeat. + */ +template +using unpack_as_type = Type; + +/** + * @brief Helper variable template to be used to _repeat_ the same value a + * number of times equal to the size of a given parameter pack. + * @tparam Value A value to repeat. + */ +template +inline constexpr auto unpack_as_value = Value; + +/** + * @brief Wraps a static constant. + * @tparam Value A static constant. + */ +template +using integral_constant = std::integral_constant; + +/** + * @brief Alias template to facilitate the creation of named values. + * @tparam Value A constant value at least convertible to `id_type`. + */ +template +using tag = integral_constant; + +/** + * @brief A class to use to push around lists of types, nothing more. + * @tparam Type Types provided by the type list. + */ +template +struct type_list { + /*! @brief Type list type. */ + using type = type_list; + /*! @brief Compile-time number of elements in the type list. */ + static constexpr auto size = sizeof...(Type); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_element; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Index Index of the type to return. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element> + : type_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element<0u, type_list> { + /*! @brief Searched type. */ + using type = First; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Type list to search into. + */ +template +using type_list_element_t = typename type_list_element::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_index; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 1u + type_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + static_assert(type_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +inline constexpr std::size_t type_list_index_v = type_list_index::value; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @return A type list composed by the types of both the type lists. + */ +template +constexpr type_list operator+(type_list, type_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_cat; + +/*! @brief Concatenates multiple type lists. */ +template<> +struct type_list_cat<> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list<>; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @tparam List Other type lists, if any. + */ +template +struct type_list_cat, type_list, List...> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = typename type_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the type list. + */ +template +struct type_list_cat> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list; +}; + +/** + * @brief Helper type. + * @tparam List Type lists to concatenate. + */ +template +using type_list_cat_t = typename type_list_cat::type; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct type_list_unique; + +template +struct type_list_unique, Type...> + : std::conditional_t<(std::is_same_v || ...), type_list_unique, Type...>, type_list_unique, Type..., First>> {}; + +template +struct type_list_unique, Type...> { + using type = type_list; +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Removes duplicates types from a type list. + * @tparam List Type list. + */ +template +struct type_list_unique { + /*! @brief A type list without duplicate types. */ + using type = typename internal::type_list_unique::type; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + */ +template +using type_list_unique_t = typename type_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a type list contains a + * given type, false otherwise. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +struct type_list_contains; + +/** + * @copybrief type_list_contains + * @tparam Type Types provided by the type list. + * @tparam Other Type to look for. + */ +template +struct type_list_contains, Other> + : std::bool_constant<(std::is_same_v || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +inline constexpr bool type_list_contains_v = type_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_diff; + +/** + * @brief Computes the difference between two type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + */ +template +struct type_list_diff, type_list> { + /*! @brief A type list that is the difference between the two type lists. */ + using type = type_list_cat_t, Type>, type_list<>, type_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Type lists between which to compute the difference. + */ +template +using type_list_diff_t = typename type_list_diff::type; + +/*! @brief Primary template isn't defined on purpose. */ +template class> +struct type_list_transform; + +/** + * @brief Applies a given _function_ to a type list and generate a new list. + * @tparam Type Types provided by the type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +struct type_list_transform, Op> { + /*! @brief Resulting type list after applying the transform function. */ + // NOLINTNEXTLINE(modernize-type-traits) + using type = type_list::type...>; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +using type_list_transform_t = typename type_list_transform::type; + +/** + * @brief A class to use to push around lists of constant values, nothing more. + * @tparam Value Values provided by the value list. + */ +template +struct value_list { + /*! @brief Value list type. */ + using type = value_list; + /*! @brief Compile-time number of elements in the value list. */ + static constexpr auto size = sizeof...(Value); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_element; + +/** + * @brief Provides compile-time indexed access to the values of a value list. + * @tparam Index Index of the value to return. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element> + : value_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element<0u, value_list> { + /*! @brief Searched type. */ + using type = decltype(Value); + /*! @brief Searched value. */ + static constexpr auto value = Value; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Value list to search into. + */ +template +using value_list_element_t = typename value_list_element::type; + +/** + * @brief Helper type. + * @tparam Index Index of the value to return. + * @tparam List Value list to search into. + */ +template +inline constexpr auto value_list_element_v = value_list_element::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_index; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam First First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 1u + value_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + static_assert(value_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +inline constexpr std::size_t value_list_index_v = value_list_index::value; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @return A value list composed by the values of both the value lists. + */ +template +constexpr value_list operator+(value_list, value_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_cat; + +/*! @brief Concatenates multiple value lists. */ +template<> +struct value_list_cat<> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list<>; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @tparam List Other value lists, if any. + */ +template +struct value_list_cat, value_list, List...> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = typename value_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the value list. + */ +template +struct value_list_cat> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list; +}; + +/** + * @brief Helper type. + * @tparam List Value lists to concatenate. + */ +template +using value_list_cat_t = typename value_list_cat::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_unique; + +/** + * @brief Removes duplicates values from a value list. + * @tparam Value One of the values provided by the given value list. + * @tparam Other The other values provided by the given value list. + */ +template +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = std::conditional_t< + ((Value == Other) || ...), + typename value_list_unique>::type, + value_list_cat_t, typename value_list_unique>::type>>; +}; + +/*! @brief Removes duplicates values from a value list. */ +template<> +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = value_list<>; +}; + +/** + * @brief Helper type. + * @tparam Type A value list. + */ +template +using value_list_unique_t = typename value_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a value list contains + * a given value, false otherwise. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +struct value_list_contains; + +/** + * @copybrief value_list_contains + * @tparam Value Values provided by the value list. + * @tparam Other Value to look for. + */ +template +struct value_list_contains, Other> + : std::bool_constant<((Value == Other) || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +inline constexpr bool value_list_contains_v = value_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_diff; + +/** + * @brief Computes the difference between two value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + */ +template +struct value_list_diff, value_list> { + /*! @brief A value list that is the difference between the two value lists. */ + using type = value_list_cat_t, Value>, value_list<>, value_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Value lists between which to compute the difference. + */ +template +using value_list_diff_t = typename value_list_diff::type; + +/*! @brief Same as std::is_invocable, but with tuples. */ +template +struct is_applicable: std::false_type {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @brief Helper variable template. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_v = is_applicable::value; + +/*! @brief Same as std::is_invocable_r, but with tuples for arguments. */ +template +struct is_applicable_r: std::false_type {}; + +/** + * @copybrief is_applicable_r + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +struct is_applicable_r>: std::is_invocable_r {}; + +/** + * @brief Helper variable template. + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_r_v = is_applicable_r::value; + +/** + * @brief Provides the member constant `value` to true if a given type is + * complete, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_complete: std::false_type {}; + +/*! @copydoc is_complete */ +template +struct is_complete>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_complete_v = is_complete::value; + +/** + * @brief Provides the member constant `value` to true if a given type is an + * iterator, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_iterator: std::false_type {}; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_iterator_category: std::false_type {}; + +template +struct has_iterator_category::iterator_category>>: std::true_type {}; + +} // namespace internal +/*! @endcond */ + +/*! @copydoc is_iterator */ +template +struct is_iterator>>>> + : internal::has_iterator_category {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_iterator_v = is_iterator::value; + +/** + * @brief Provides the member constant `value` to true if a given type is both + * an empty and non-final class, false otherwise. + * @tparam Type The type to test + */ +template +struct is_ebco_eligible + : std::bool_constant && !std::is_final_v> {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_ebco_eligible_v = is_ebco_eligible::value; + +/** + * @brief Provides the member constant `value` to true if `Type::is_transparent` + * is valid and denotes a type, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_transparent: std::false_type {}; + +/*! @copydoc is_transparent */ +template +struct is_transparent>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_transparent_v = is_transparent::value; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_tuple_size_value: std::false_type {}; + +template +struct has_tuple_size_value::value)>>: std::true_type {}; + +template +struct has_value_type: std::false_type {}; + +template +struct has_value_type>: std::true_type {}; + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable(); + +template +[[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence) { + return (dispatch_is_equality_comparable>() && ...); +} + +template +[[nodiscard]] constexpr bool maybe_equality_comparable(char) { + return false; +} + +template +[[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval() == std::declval()) { + return true; +} + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable() { + // NOLINTBEGIN(modernize-use-transparent-functors) + if constexpr(std::is_array_v) { + return false; + } else if constexpr(is_complete_v>>) { + if constexpr(has_tuple_size_value::value) { + return maybe_equality_comparable(0) && unpack_maybe_equality_comparable(std::make_index_sequence::value>{}); + } else { + return maybe_equality_comparable(0); + } + } else if constexpr(has_value_type::value) { + if constexpr(is_iterator_v || std::is_same_v || dispatch_is_equality_comparable()) { + return maybe_equality_comparable(0); + } else { + return false; + } + } else { + return maybe_equality_comparable(0); + } + // NOLINTEND(modernize-use-transparent-functors) +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Provides the member constant `value` to true if a given type is + * equality comparable, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_equality_comparable: std::bool_constant()> {}; + +/*! @copydoc is_equality_comparable */ +template +struct is_equality_comparable: is_equality_comparable {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_equality_comparable_v = is_equality_comparable::value; + +/** + * @brief Transcribes the constness of a type to another type. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = std::remove_const_t; +}; + +/*! @copydoc constness_as */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = const To; +}; + +/** + * @brief Alias template to facilitate the transcription of the constness. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +using constness_as_t = typename constness_as::type; + +/** + * @brief Extracts the class of a non-static member object or function. + * @tparam Member A pointer to a non-static member object or function. + */ +template +class member_class { + static_assert(std::is_member_pointer_v, "Invalid pointer type to non-static member object or function"); + + template + static Class *clazz(Ret (Class::*)(Args...)); + + template + static Class *clazz(Ret (Class::*)(Args...) const); + + template + static Class *clazz(Type Class::*); + +public: + /*! @brief The class of the given non-static member object or function. */ + using type = std::remove_pointer_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Member A pointer to a non-static member object or function. + */ +template +using member_class_t = typename member_class::type; + +/** + * @brief Extracts the n-th argument of a _callable_ type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid _callable_ type. + */ +template +class nth_argument { + template + static constexpr type_list pick_up(Ret (*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...) const); + + template + static constexpr type_list pick_up(Type Class ::*); + + template + static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&); + +public: + /*! @brief N-th argument of the _callable_ type. */ + using type = type_list_element_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid function, member function or data member type. + */ +template +using nth_argument_t = typename nth_argument::type; + +} // namespace entt + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::type_list_element> {}; + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::value_list_element> {}; + +#endif + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct compressed_pair_element { + using reference = Type &; + using const_reference = const Type &; + + template>> + // NOLINTNEXTLINE(modernize-use-equals-default) + constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v) {} + + template>, compressed_pair_element>>> + constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v) + : value{std::forward(arg)} {} + + template + constexpr compressed_pair_element(std::tuple args, std::index_sequence) noexcept(std::is_nothrow_constructible_v) + : value{std::forward(std::get(args))...} {} + + [[nodiscard]] constexpr reference get() noexcept { + return value; + } + + [[nodiscard]] constexpr const_reference get() const noexcept { + return value; + } + +private: + Type value{}; +}; + +template +struct compressed_pair_element>>: Type { + using reference = Type &; + using const_reference = const Type &; + using base_type = Type; + + template>> + constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v) + : base_type{} {} + + template>, compressed_pair_element>>> + constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v) + : base_type{std::forward(arg)} {} + + template + constexpr compressed_pair_element(std::tuple args, std::index_sequence) noexcept(std::is_nothrow_constructible_v) + : base_type{std::forward(std::get(args))...} {} + + [[nodiscard]] constexpr reference get() noexcept { + return *this; + } + + [[nodiscard]] constexpr const_reference get() const noexcept { + return *this; + } +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief A compressed pair. + * + * A pair that exploits the _Empty Base Class Optimization_ (or _EBCO_) to + * reduce its final size to a minimum. + * + * @tparam First The type of the first element that the pair stores. + * @tparam Second The type of the second element that the pair stores. + */ +template +class compressed_pair final + : internal::compressed_pair_element, + internal::compressed_pair_element { + using first_base = internal::compressed_pair_element; + using second_base = internal::compressed_pair_element; + +public: + /*! @brief The type of the first element that the pair stores. */ + using first_type = First; + /*! @brief The type of the second element that the pair stores. */ + using second_type = Second; + + /** + * @brief Default constructor, conditionally enabled. + * + * This constructor is only available when the types that the pair stores + * are both at least default constructible. + * + * @tparam Dummy Dummy template parameter used for internal purposes. + */ + template && std::is_default_constructible_v>> + constexpr compressed_pair() noexcept(std::is_nothrow_default_constructible_v && std::is_nothrow_default_constructible_v) + : first_base{}, + second_base{} {} + + /** + * @brief Copy constructor. + * @param other The instance to copy from. + */ + constexpr compressed_pair(const compressed_pair &other) = default; + + /** + * @brief Move constructor. + * @param other The instance to move from. + */ + constexpr compressed_pair(compressed_pair &&other) noexcept = default; + + /** + * @brief Constructs a pair from its values. + * @tparam Arg Type of value to use to initialize the first element. + * @tparam Other Type of value to use to initialize the second element. + * @param arg Value to use to initialize the first element. + * @param other Value to use to initialize the second element. + */ + template + constexpr compressed_pair(Arg &&arg, Other &&other) noexcept(std::is_nothrow_constructible_v && std::is_nothrow_constructible_v) + : first_base{std::forward(arg)}, + second_base{std::forward(other)} {} + + /** + * @brief Constructs a pair by forwarding the arguments to its parts. + * @tparam Args Types of arguments to use to initialize the first element. + * @tparam Other Types of arguments to use to initialize the second element. + * @param args Arguments to use to initialize the first element. + * @param other Arguments to use to initialize the second element. + */ + template + constexpr compressed_pair(std::piecewise_construct_t, std::tuple args, std::tuple other) noexcept(std::is_nothrow_constructible_v && std::is_nothrow_constructible_v) + : first_base{std::move(args), std::index_sequence_for{}}, + second_base{std::move(other), std::index_sequence_for{}} {} + + /*! @brief Default destructor. */ + ~compressed_pair() = default; + + /** + * @brief Copy assignment operator. + * @param other The instance to copy from. + * @return This compressed pair object. + */ + constexpr compressed_pair &operator=(const compressed_pair &other) = default; + + /** + * @brief Move assignment operator. + * @param other The instance to move from. + * @return This compressed pair object. + */ + constexpr compressed_pair &operator=(compressed_pair &&other) noexcept = default; + + /** + * @brief Returns the first element that a pair stores. + * @return The first element that a pair stores. + */ + [[nodiscard]] constexpr first_type &first() noexcept { + return static_cast(*this).get(); + } + + /*! @copydoc first */ + [[nodiscard]] constexpr const first_type &first() const noexcept { + return static_cast(*this).get(); + } + + /** + * @brief Returns the second element that a pair stores. + * @return The second element that a pair stores. + */ + [[nodiscard]] constexpr second_type &second() noexcept { + return static_cast(*this).get(); + } + + /*! @copydoc second */ + [[nodiscard]] constexpr const second_type &second() const noexcept { + return static_cast(*this).get(); + } + + /** + * @brief Swaps two compressed pair objects. + * @param other The compressed pair to swap with. + */ + constexpr void swap(compressed_pair &other) noexcept { + using std::swap; + swap(first(), other.first()); + swap(second(), other.second()); + } + + /** + * @brief Extracts an element from the compressed pair. + * @tparam Index An integer value that is either 0 or 1. + * @return Returns a reference to the first element if `Index` is 0 and a + * reference to the second element if `Index` is 1. + */ + template + [[nodiscard]] constexpr decltype(auto) get() noexcept { + if constexpr(Index == 0u) { + return first(); + } else { + static_assert(Index == 1u, "Index out of bounds"); + return second(); + } + } + + /*! @copydoc get */ + template + [[nodiscard]] constexpr decltype(auto) get() const noexcept { + if constexpr(Index == 0u) { + return first(); + } else { + static_assert(Index == 1u, "Index out of bounds"); + return second(); + } + } +}; + +/** + * @brief Deduction guide. + * @tparam Type Type of value to use to initialize the first element. + * @tparam Other Type of value to use to initialize the second element. + */ +template +compressed_pair(Type &&, Other &&) -> compressed_pair, std::decay_t>; + +/** + * @brief Swaps two compressed pair objects. + * @tparam First The type of the first element that the pairs store. + * @tparam Second The type of the second element that the pairs store. + * @param lhs A valid compressed pair object. + * @param rhs A valid compressed pair object. + */ +template +constexpr void swap(compressed_pair &lhs, compressed_pair &rhs) noexcept { + lhs.swap(rhs); +} + +} // namespace entt + +namespace std { + +/** + * @brief `std::tuple_size` specialization for `compressed_pair`s. + * @tparam First The type of the first element that the pair stores. + * @tparam Second The type of the second element that the pair stores. + */ +template +struct tuple_size>: integral_constant {}; + +/** + * @brief `std::tuple_element` specialization for `compressed_pair`s. + * @tparam Index The index of the type to return. + * @tparam First The type of the first element that the pair stores. + * @tparam Second The type of the second element that the pair stores. + */ +template +struct tuple_element>: conditional { + static_assert(Index < 2u, "Index out of bounds"); +}; + +} // namespace std + +#endif + +// #include "../core/iterator.hpp" +#ifndef ENTT_CORE_ITERATOR_HPP +#define ENTT_CORE_ITERATOR_HPP + +#include +#include +#include +#include + +namespace entt { + +/** + * @brief Helper type to use as pointer with input iterators. + * @tparam Type of wrapped value. + */ +template +struct input_iterator_pointer final { + /*! @brief Value type. */ + using value_type = Type; + /*! @brief Pointer type. */ + using pointer = Type *; + /*! @brief Reference type. */ + using reference = Type &; + + /** + * @brief Constructs a proxy object by move. + * @param val Value to use to initialize the proxy object. + */ + constexpr input_iterator_pointer(value_type &&val) noexcept(std::is_nothrow_move_constructible_v) + : value{std::move(val)} {} + + /** + * @brief Access operator for accessing wrapped values. + * @return A pointer to the wrapped value. + */ + [[nodiscard]] constexpr pointer operator->() noexcept { + return std::addressof(value); + } + + /** + * @brief Dereference operator for accessing wrapped values. + * @return A reference to the wrapped value. + */ + [[nodiscard]] constexpr reference operator*() noexcept { + return value; + } + +private: + Type value; +}; + +/** + * @brief Plain iota iterator (waiting for C++20). + * @tparam Type Value type. + */ +template +class iota_iterator final { + static_assert(std::is_integral_v, "Not an integral type"); + +public: + /*! @brief Value type, likely an integral one. */ + using value_type = Type; + /*! @brief Invalid pointer type. */ + using pointer = void; + /*! @brief Non-reference type, same as value type. */ + using reference = value_type; + /*! @brief Difference type. */ + using difference_type = std::ptrdiff_t; + /*! @brief Iterator category. */ + using iterator_category = std::input_iterator_tag; + + /*! @brief Default constructor. */ + constexpr iota_iterator() noexcept + : current{} {} + + /** + * @brief Constructs an iota iterator from a given value. + * @param init The initial value assigned to the iota iterator. + */ + constexpr iota_iterator(const value_type init) noexcept + : current{init} {} + + /** + * @brief Pre-increment operator. + * @return This iota iterator. + */ + constexpr iota_iterator &operator++() noexcept { + return ++current, *this; + } + + /** + * @brief Post-increment operator. + * @return This iota iterator. + */ + constexpr iota_iterator operator++(int) noexcept { + const iota_iterator orig = *this; + return ++(*this), orig; + } + + /** + * @brief Dereference operator. + * @return The underlying value. + */ + [[nodiscard]] constexpr reference operator*() const noexcept { + return current; + } + +private: + value_type current; +}; + +/** + * @brief Comparison operator. + * @tparam Type Value type of the iota iterator. + * @param lhs A properly initialized iota iterator. + * @param rhs A properly initialized iota iterator. + * @return True if the two iterators are identical, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator==(const iota_iterator &lhs, const iota_iterator &rhs) noexcept { + return *lhs == *rhs; +} + +/** + * @brief Comparison operator. + * @tparam Type Value type of the iota iterator. + * @param lhs A properly initialized iota iterator. + * @param rhs A properly initialized iota iterator. + * @return True if the two iterators differ, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator!=(const iota_iterator &lhs, const iota_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +/** + * @brief Utility class to create an iterable object from a pair of iterators. + * @tparam It Type of iterator. + * @tparam Sentinel Type of sentinel. + */ +template +struct iterable_adaptor final { + /*! @brief Value type. */ + using value_type = typename std::iterator_traits::value_type; + /*! @brief Iterator type. */ + using iterator = It; + /*! @brief Sentinel type. */ + using sentinel = Sentinel; + + /*! @brief Default constructor. */ + constexpr iterable_adaptor() noexcept(std::is_nothrow_default_constructible_v && std::is_nothrow_default_constructible_v) + : first{}, + last{} {} + + /** + * @brief Creates an iterable object from a pair of iterators. + * @param from Begin iterator. + * @param to End iterator. + */ + constexpr iterable_adaptor(iterator from, sentinel to) noexcept(std::is_nothrow_move_constructible_v && std::is_nothrow_move_constructible_v) + : first{std::move(from)}, + last{std::move(to)} {} + + /** + * @brief Returns an iterator to the beginning. + * @return An iterator to the first element of the range. + */ + [[nodiscard]] constexpr iterator begin() const noexcept { + return first; + } + + /** + * @brief Returns an iterator to the end. + * @return An iterator to the element following the last element of the + * range. + */ + [[nodiscard]] constexpr sentinel end() const noexcept { + return last; + } + + /*! @copydoc begin */ + [[nodiscard]] constexpr iterator cbegin() const noexcept { + return begin(); + } + + /*! @copydoc end */ + [[nodiscard]] constexpr sentinel cend() const noexcept { + return end(); + } + +private: + It first; + Sentinel last; +}; + +} // namespace entt + +#endif + +// #include "../core/memory.hpp" +#ifndef ENTT_CORE_MEMORY_HPP +#define ENTT_CORE_MEMORY_HPP + +#include +#include +#include +#include +#include +// #include "../config/config.h" + + +namespace entt { + +/** + * @brief Unwraps fancy pointers, does nothing otherwise (waiting for C++20). + * @tparam Type Pointer type. + * @param ptr Fancy or raw pointer. + * @return A raw pointer that represents the address of the original pointer. + */ +template +[[nodiscard]] constexpr auto to_address(Type &&ptr) noexcept { + if constexpr(std::is_pointer_v>) { + return ptr; + } else { + return to_address(std::forward(ptr).operator->()); + } +} + +/** + * @brief Utility function to design allocation-aware containers. + * @tparam Allocator Type of allocator. + * @param lhs A valid allocator. + * @param rhs Another valid allocator. + */ +template +constexpr void propagate_on_container_copy_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept { + if constexpr(std::allocator_traits::propagate_on_container_copy_assignment::value) { + lhs = rhs; + } +} + +/** + * @brief Utility function to design allocation-aware containers. + * @tparam Allocator Type of allocator. + * @param lhs A valid allocator. + * @param rhs Another valid allocator. + */ +template +constexpr void propagate_on_container_move_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept { + if constexpr(std::allocator_traits::propagate_on_container_move_assignment::value) { + lhs = std::move(rhs); + } +} + +/** + * @brief Utility function to design allocation-aware containers. + * @tparam Allocator Type of allocator. + * @param lhs A valid allocator. + * @param rhs Another valid allocator. + */ +template +constexpr void propagate_on_container_swap([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept { + if constexpr(std::allocator_traits::propagate_on_container_swap::value) { + using std::swap; + swap(lhs, rhs); + } else { + ENTT_ASSERT_CONSTEXPR(lhs == rhs, "Cannot swap the containers"); + } +} + +/** + * @brief Deleter for allocator-aware unique pointers (waiting for C++20). + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +struct allocation_deleter: private Allocator { + /*! @brief Allocator type. */ + using allocator_type = Allocator; + /*! @brief Pointer type. */ + using pointer = typename std::allocator_traits::pointer; + + /** + * @brief Inherited constructors. + * @param alloc The allocator to use. + */ + constexpr allocation_deleter(const allocator_type &alloc) noexcept(std::is_nothrow_copy_constructible_v) + : Allocator{alloc} {} + + /** + * @brief Destroys the pointed object and deallocates its memory. + * @param ptr A valid pointer to an object of the given type. + */ + constexpr void operator()(pointer ptr) noexcept(std::is_nothrow_destructible_v) { + using alloc_traits = std::allocator_traits; + alloc_traits::destroy(*this, to_address(ptr)); + alloc_traits::deallocate(*this, ptr, 1u); + } +}; + +/** + * @brief Allows `std::unique_ptr` to use allocators (waiting for C++20). + * @tparam Type Type of object to allocate for and to construct. + * @tparam Allocator Type of allocator used to manage memory and elements. + * @tparam Args Types of arguments to use to construct the object. + * @param allocator The allocator to use. + * @param args Parameters to use to construct the object. + * @return A properly initialized unique pointer with a custom deleter. + */ +template +ENTT_CONSTEXPR auto allocate_unique(Allocator &allocator, Args &&...args) { + static_assert(!std::is_array_v, "Array types are not supported"); + + using alloc_traits = typename std::allocator_traits::template rebind_traits; + using allocator_type = typename alloc_traits::allocator_type; + + allocator_type alloc{allocator}; + auto ptr = alloc_traits::allocate(alloc, 1u); + + ENTT_TRY { + alloc_traits::construct(alloc, to_address(ptr), std::forward(args)...); + } + ENTT_CATCH { + alloc_traits::deallocate(alloc, ptr, 1u); + ENTT_THROW; + } + + return std::unique_ptr>{ptr, alloc}; +} + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct uses_allocator_construction { + template + static constexpr auto args([[maybe_unused]] const Allocator &allocator, Params &&...params) noexcept { + if constexpr(!std::uses_allocator_v && std::is_constructible_v) { + return std::forward_as_tuple(std::forward(params)...); + } else { + static_assert(std::uses_allocator_v, "Ill-formed request"); + + if constexpr(std::is_constructible_v) { + return std::tuple{std::allocator_arg, allocator, std::forward(params)...}; + } else { + static_assert(std::is_constructible_v, "Ill-formed request"); + return std::forward_as_tuple(std::forward(params)..., allocator); + } + } + } +}; + +template +struct uses_allocator_construction> { + using type = std::pair; + + template + static constexpr auto args(const Allocator &allocator, std::piecewise_construct_t, First &&first, Second &&second) noexcept { + return std::make_tuple( + std::piecewise_construct, + std::apply([&allocator](auto &&...curr) { return uses_allocator_construction::args(allocator, std::forward(curr)...); }, std::forward(first)), + std::apply([&allocator](auto &&...curr) { return uses_allocator_construction::args(allocator, std::forward(curr)...); }, std::forward(second))); + } + + template + static constexpr auto args(const Allocator &allocator) noexcept { + return uses_allocator_construction::args(allocator, std::piecewise_construct, std::tuple<>{}, std::tuple<>{}); + } + + template + static constexpr auto args(const Allocator &allocator, First &&first, Second &&second) noexcept { + return uses_allocator_construction::args(allocator, std::piecewise_construct, std::forward_as_tuple(std::forward(first)), std::forward_as_tuple(std::forward(second))); + } + + template + static constexpr auto args(const Allocator &allocator, const std::pair &value) noexcept { + return uses_allocator_construction::args(allocator, std::piecewise_construct, std::forward_as_tuple(value.first), std::forward_as_tuple(value.second)); + } + + template + static constexpr auto args(const Allocator &allocator, std::pair &&value) noexcept { + return uses_allocator_construction::args(allocator, std::piecewise_construct, std::forward_as_tuple(std::move(value.first)), std::forward_as_tuple(std::move(value.second))); + } +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Uses-allocator construction utility (waiting for C++20). + * + * Primarily intended for internal use. Prepares the argument list needed to + * create an object of a given type by means of uses-allocator construction. + * + * @tparam Type Type to return arguments for. + * @tparam Allocator Type of allocator used to manage memory and elements. + * @tparam Args Types of arguments to use to construct the object. + * @param allocator The allocator to use. + * @param args Parameters to use to construct the object. + * @return The arguments needed to create an object of the given type. + */ +template +constexpr auto uses_allocator_construction_args(const Allocator &allocator, Args &&...args) noexcept { + return internal::uses_allocator_construction::args(allocator, std::forward(args)...); +} + +/** + * @brief Uses-allocator construction utility (waiting for C++20). + * + * Primarily intended for internal use. Creates an object of a given type by + * means of uses-allocator construction. + * + * @tparam Type Type of object to create. + * @tparam Allocator Type of allocator used to manage memory and elements. + * @tparam Args Types of arguments to use to construct the object. + * @param allocator The allocator to use. + * @param args Parameters to use to construct the object. + * @return A newly created object of the given type. + */ +template +constexpr Type make_obj_using_allocator(const Allocator &allocator, Args &&...args) { + return std::make_from_tuple(internal::uses_allocator_construction::args(allocator, std::forward(args)...)); +} + +/** + * @brief Uses-allocator construction utility (waiting for C++20). + * + * Primarily intended for internal use. Creates an object of a given type by + * means of uses-allocator construction at an uninitialized memory location. + * + * @tparam Type Type of object to create. + * @tparam Allocator Type of allocator used to manage memory and elements. + * @tparam Args Types of arguments to use to construct the object. + * @param value Memory location in which to place the object. + * @param allocator The allocator to use. + * @param args Parameters to use to construct the object. + * @return A pointer to the newly created object of the given type. + */ +template +constexpr Type *uninitialized_construct_using_allocator(Type *value, const Allocator &allocator, Args &&...args) { + return std::apply([value](auto &&...curr) { return ::new(value) Type(std::forward(curr)...); }, internal::uses_allocator_construction::args(allocator, std::forward(args)...)); +} + +} // namespace entt + +#endif + +// #include "../core/type_traits.hpp" +#ifndef ENTT_CORE_TYPE_TRAITS_HPP +#define ENTT_CORE_TYPE_TRAITS_HPP + +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "fwd.hpp" + + +namespace entt { + +/** + * @brief Utility class to disambiguate overloaded functions. + * @tparam N Number of choices available. + */ +template +struct choice_t + // unfortunately, doxygen cannot parse such a construct + : /*! @cond TURN_OFF_DOXYGEN */ choice_t /*! @endcond */ +{}; + +/*! @copybrief choice_t */ +template<> +struct choice_t<0> {}; + +/** + * @brief Variable template for the choice trick. + * @tparam N Number of choices available. + */ +template +inline constexpr choice_t choice{}; + +/** + * @brief Identity type trait. + * + * Useful to establish non-deduced contexts in template argument deduction + * (waiting for C++20) or to provide types through function arguments. + * + * @tparam Type A type. + */ +template +struct type_identity { + /*! @brief Identity type. */ + using type = Type; +}; + +/** + * @brief Helper type. + * @tparam Type A type. + */ +template +using type_identity_t = typename type_identity::type; + +/** + * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains. + * @tparam Type The type of which to return the size. + */ +template +struct size_of: std::integral_constant {}; + +/*! @copydoc size_of */ +template +struct size_of> + // NOLINTNEXTLINE(bugprone-sizeof-expression) + : std::integral_constant {}; + +/** + * @brief Helper variable template. + * @tparam Type The type of which to return the size. + */ +template +inline constexpr std::size_t size_of_v = size_of::value; + +/** + * @brief Using declaration to be used to _repeat_ the same type a number of + * times equal to the size of a given parameter pack. + * @tparam Type A type to repeat. + */ +template +using unpack_as_type = Type; + +/** + * @brief Helper variable template to be used to _repeat_ the same value a + * number of times equal to the size of a given parameter pack. + * @tparam Value A value to repeat. + */ +template +inline constexpr auto unpack_as_value = Value; + +/** + * @brief Wraps a static constant. + * @tparam Value A static constant. + */ +template +using integral_constant = std::integral_constant; + +/** + * @brief Alias template to facilitate the creation of named values. + * @tparam Value A constant value at least convertible to `id_type`. + */ +template +using tag = integral_constant; + +/** + * @brief A class to use to push around lists of types, nothing more. + * @tparam Type Types provided by the type list. + */ +template +struct type_list { + /*! @brief Type list type. */ + using type = type_list; + /*! @brief Compile-time number of elements in the type list. */ + static constexpr auto size = sizeof...(Type); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_element; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Index Index of the type to return. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element> + : type_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element<0u, type_list> { + /*! @brief Searched type. */ + using type = First; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Type list to search into. + */ +template +using type_list_element_t = typename type_list_element::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_index; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 1u + type_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + static_assert(type_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +inline constexpr std::size_t type_list_index_v = type_list_index::value; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @return A type list composed by the types of both the type lists. + */ +template +constexpr type_list operator+(type_list, type_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_cat; + +/*! @brief Concatenates multiple type lists. */ +template<> +struct type_list_cat<> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list<>; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @tparam List Other type lists, if any. + */ +template +struct type_list_cat, type_list, List...> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = typename type_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the type list. + */ +template +struct type_list_cat> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list; +}; + +/** + * @brief Helper type. + * @tparam List Type lists to concatenate. + */ +template +using type_list_cat_t = typename type_list_cat::type; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct type_list_unique; + +template +struct type_list_unique, Type...> + : std::conditional_t<(std::is_same_v || ...), type_list_unique, Type...>, type_list_unique, Type..., First>> {}; + +template +struct type_list_unique, Type...> { + using type = type_list; +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Removes duplicates types from a type list. + * @tparam List Type list. + */ +template +struct type_list_unique { + /*! @brief A type list without duplicate types. */ + using type = typename internal::type_list_unique::type; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + */ +template +using type_list_unique_t = typename type_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a type list contains a + * given type, false otherwise. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +struct type_list_contains; + +/** + * @copybrief type_list_contains + * @tparam Type Types provided by the type list. + * @tparam Other Type to look for. + */ +template +struct type_list_contains, Other> + : std::bool_constant<(std::is_same_v || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +inline constexpr bool type_list_contains_v = type_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_diff; + +/** + * @brief Computes the difference between two type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + */ +template +struct type_list_diff, type_list> { + /*! @brief A type list that is the difference between the two type lists. */ + using type = type_list_cat_t, Type>, type_list<>, type_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Type lists between which to compute the difference. + */ +template +using type_list_diff_t = typename type_list_diff::type; + +/*! @brief Primary template isn't defined on purpose. */ +template class> +struct type_list_transform; + +/** + * @brief Applies a given _function_ to a type list and generate a new list. + * @tparam Type Types provided by the type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +struct type_list_transform, Op> { + /*! @brief Resulting type list after applying the transform function. */ + // NOLINTNEXTLINE(modernize-type-traits) + using type = type_list::type...>; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +using type_list_transform_t = typename type_list_transform::type; + +/** + * @brief A class to use to push around lists of constant values, nothing more. + * @tparam Value Values provided by the value list. + */ +template +struct value_list { + /*! @brief Value list type. */ + using type = value_list; + /*! @brief Compile-time number of elements in the value list. */ + static constexpr auto size = sizeof...(Value); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_element; + +/** + * @brief Provides compile-time indexed access to the values of a value list. + * @tparam Index Index of the value to return. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element> + : value_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element<0u, value_list> { + /*! @brief Searched type. */ + using type = decltype(Value); + /*! @brief Searched value. */ + static constexpr auto value = Value; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Value list to search into. + */ +template +using value_list_element_t = typename value_list_element::type; + +/** + * @brief Helper type. + * @tparam Index Index of the value to return. + * @tparam List Value list to search into. + */ +template +inline constexpr auto value_list_element_v = value_list_element::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_index; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam First First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 1u + value_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + static_assert(value_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +inline constexpr std::size_t value_list_index_v = value_list_index::value; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @return A value list composed by the values of both the value lists. + */ +template +constexpr value_list operator+(value_list, value_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_cat; + +/*! @brief Concatenates multiple value lists. */ +template<> +struct value_list_cat<> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list<>; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @tparam List Other value lists, if any. + */ +template +struct value_list_cat, value_list, List...> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = typename value_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the value list. + */ +template +struct value_list_cat> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list; +}; + +/** + * @brief Helper type. + * @tparam List Value lists to concatenate. + */ +template +using value_list_cat_t = typename value_list_cat::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_unique; + +/** + * @brief Removes duplicates values from a value list. + * @tparam Value One of the values provided by the given value list. + * @tparam Other The other values provided by the given value list. + */ +template +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = std::conditional_t< + ((Value == Other) || ...), + typename value_list_unique>::type, + value_list_cat_t, typename value_list_unique>::type>>; +}; + +/*! @brief Removes duplicates values from a value list. */ +template<> +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = value_list<>; +}; + +/** + * @brief Helper type. + * @tparam Type A value list. + */ +template +using value_list_unique_t = typename value_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a value list contains + * a given value, false otherwise. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +struct value_list_contains; + +/** + * @copybrief value_list_contains + * @tparam Value Values provided by the value list. + * @tparam Other Value to look for. + */ +template +struct value_list_contains, Other> + : std::bool_constant<((Value == Other) || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +inline constexpr bool value_list_contains_v = value_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_diff; + +/** + * @brief Computes the difference between two value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + */ +template +struct value_list_diff, value_list> { + /*! @brief A value list that is the difference between the two value lists. */ + using type = value_list_cat_t, Value>, value_list<>, value_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Value lists between which to compute the difference. + */ +template +using value_list_diff_t = typename value_list_diff::type; + +/*! @brief Same as std::is_invocable, but with tuples. */ +template +struct is_applicable: std::false_type {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @brief Helper variable template. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_v = is_applicable::value; + +/*! @brief Same as std::is_invocable_r, but with tuples for arguments. */ +template +struct is_applicable_r: std::false_type {}; + +/** + * @copybrief is_applicable_r + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +struct is_applicable_r>: std::is_invocable_r {}; + +/** + * @brief Helper variable template. + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_r_v = is_applicable_r::value; + +/** + * @brief Provides the member constant `value` to true if a given type is + * complete, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_complete: std::false_type {}; + +/*! @copydoc is_complete */ +template +struct is_complete>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_complete_v = is_complete::value; + +/** + * @brief Provides the member constant `value` to true if a given type is an + * iterator, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_iterator: std::false_type {}; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_iterator_category: std::false_type {}; + +template +struct has_iterator_category::iterator_category>>: std::true_type {}; + +} // namespace internal +/*! @endcond */ + +/*! @copydoc is_iterator */ +template +struct is_iterator>>>> + : internal::has_iterator_category {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_iterator_v = is_iterator::value; + +/** + * @brief Provides the member constant `value` to true if a given type is both + * an empty and non-final class, false otherwise. + * @tparam Type The type to test + */ +template +struct is_ebco_eligible + : std::bool_constant && !std::is_final_v> {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_ebco_eligible_v = is_ebco_eligible::value; + +/** + * @brief Provides the member constant `value` to true if `Type::is_transparent` + * is valid and denotes a type, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_transparent: std::false_type {}; + +/*! @copydoc is_transparent */ +template +struct is_transparent>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_transparent_v = is_transparent::value; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_tuple_size_value: std::false_type {}; + +template +struct has_tuple_size_value::value)>>: std::true_type {}; + +template +struct has_value_type: std::false_type {}; + +template +struct has_value_type>: std::true_type {}; + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable(); + +template +[[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence) { + return (dispatch_is_equality_comparable>() && ...); +} + +template +[[nodiscard]] constexpr bool maybe_equality_comparable(char) { + return false; +} + +template +[[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval() == std::declval()) { + return true; +} + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable() { + // NOLINTBEGIN(modernize-use-transparent-functors) + if constexpr(std::is_array_v) { + return false; + } else if constexpr(is_complete_v>>) { + if constexpr(has_tuple_size_value::value) { + return maybe_equality_comparable(0) && unpack_maybe_equality_comparable(std::make_index_sequence::value>{}); + } else { + return maybe_equality_comparable(0); + } + } else if constexpr(has_value_type::value) { + if constexpr(is_iterator_v || std::is_same_v || dispatch_is_equality_comparable()) { + return maybe_equality_comparable(0); + } else { + return false; + } + } else { + return maybe_equality_comparable(0); + } + // NOLINTEND(modernize-use-transparent-functors) +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Provides the member constant `value` to true if a given type is + * equality comparable, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_equality_comparable: std::bool_constant()> {}; + +/*! @copydoc is_equality_comparable */ +template +struct is_equality_comparable: is_equality_comparable {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_equality_comparable_v = is_equality_comparable::value; + +/** + * @brief Transcribes the constness of a type to another type. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = std::remove_const_t; +}; + +/*! @copydoc constness_as */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = const To; +}; + +/** + * @brief Alias template to facilitate the transcription of the constness. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +using constness_as_t = typename constness_as::type; + +/** + * @brief Extracts the class of a non-static member object or function. + * @tparam Member A pointer to a non-static member object or function. + */ +template +class member_class { + static_assert(std::is_member_pointer_v, "Invalid pointer type to non-static member object or function"); + + template + static Class *clazz(Ret (Class::*)(Args...)); + + template + static Class *clazz(Ret (Class::*)(Args...) const); + + template + static Class *clazz(Type Class::*); + +public: + /*! @brief The class of the given non-static member object or function. */ + using type = std::remove_pointer_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Member A pointer to a non-static member object or function. + */ +template +using member_class_t = typename member_class::type; + +/** + * @brief Extracts the n-th argument of a _callable_ type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid _callable_ type. + */ +template +class nth_argument { + template + static constexpr type_list pick_up(Ret (*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...) const); + + template + static constexpr type_list pick_up(Type Class ::*); + + template + static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&); + +public: + /*! @brief N-th argument of the _callable_ type. */ + using type = type_list_element_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid function, member function or data member type. + */ +template +using nth_argument_t = typename nth_argument::type; + +} // namespace entt + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::type_list_element> {}; + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::value_list_element> {}; + +#endif + +// #include "fwd.hpp" +#ifndef ENTT_CONTAINER_FWD_HPP +#define ENTT_CONTAINER_FWD_HPP + +#include +#include +#include +#include + +namespace entt { + +template< + typename Key, + typename Type, + typename = std::hash, + typename = std::equal_to<>, + typename = std::allocator>> +class dense_map; + +template< + typename Type, + typename = std::hash, + typename = std::equal_to<>, + typename = std::allocator> +class dense_set; + +template +class basic_table; + +/** + * @brief Alias declaration for the most common use case. + * @tparam Type Element types. + */ +template +using table = basic_table...>; + +} // namespace entt + +#endif + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +static constexpr std::size_t dense_map_placeholder_position = (std::numeric_limits::max)(); + +template +struct dense_map_node final { + using value_type = std::pair; + + template + dense_map_node(const std::size_t pos, Args &&...args) + : next{pos}, + element{std::forward(args)...} {} + + template + dense_map_node(std::allocator_arg_t, const Allocator &allocator, const std::size_t pos, Args &&...args) + : next{pos}, + element{entt::make_obj_using_allocator(allocator, std::forward(args)...)} {} + + template + dense_map_node(std::allocator_arg_t, const Allocator &allocator, const dense_map_node &other) + : next{other.next}, + element{entt::make_obj_using_allocator(allocator, other.element)} {} + + template + dense_map_node(std::allocator_arg_t, const Allocator &allocator, dense_map_node &&other) + : next{other.next}, + element{entt::make_obj_using_allocator(allocator, std::move(other.element))} {} + + std::size_t next; + value_type element; +}; + +template +class dense_map_iterator final { + template + friend class dense_map_iterator; + + using first_type = decltype(std::as_const(std::declval()->element.first)); + using second_type = decltype((std::declval()->element.second)); + +public: + using value_type = std::pair; + using pointer = input_iterator_pointer; + using reference = value_type; + using difference_type = std::ptrdiff_t; + using iterator_category = std::input_iterator_tag; + using iterator_concept = std::random_access_iterator_tag; + + constexpr dense_map_iterator() noexcept + : it{} {} + + constexpr dense_map_iterator(const It iter) noexcept + : it{iter} {} + + template && std::is_constructible_v>> + constexpr dense_map_iterator(const dense_map_iterator &other) noexcept + : it{other.it} {} + + constexpr dense_map_iterator &operator++() noexcept { + return ++it, *this; + } + + constexpr dense_map_iterator operator++(int) noexcept { + const dense_map_iterator orig = *this; + return ++(*this), orig; + } + + constexpr dense_map_iterator &operator--() noexcept { + return --it, *this; + } + + constexpr dense_map_iterator operator--(int) noexcept { + const dense_map_iterator orig = *this; + return operator--(), orig; + } + + constexpr dense_map_iterator &operator+=(const difference_type value) noexcept { + it += value; + return *this; + } + + constexpr dense_map_iterator operator+(const difference_type value) const noexcept { + dense_map_iterator copy = *this; + return (copy += value); + } + + constexpr dense_map_iterator &operator-=(const difference_type value) noexcept { + return (*this += -value); + } + + constexpr dense_map_iterator operator-(const difference_type value) const noexcept { + return (*this + -value); + } + + [[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept { + return {it[value].element.first, it[value].element.second}; + } + + [[nodiscard]] constexpr pointer operator->() const noexcept { + return operator*(); + } + + [[nodiscard]] constexpr reference operator*() const noexcept { + return operator[](0); + } + + template + friend constexpr std::ptrdiff_t operator-(const dense_map_iterator &, const dense_map_iterator &) noexcept; + + template + friend constexpr bool operator==(const dense_map_iterator &, const dense_map_iterator &) noexcept; + + template + friend constexpr bool operator<(const dense_map_iterator &, const dense_map_iterator &) noexcept; + +private: + It it; +}; + +template +[[nodiscard]] constexpr std::ptrdiff_t operator-(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return lhs.it - rhs.it; +} + +template +[[nodiscard]] constexpr bool operator==(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return lhs.it == rhs.it; +} + +template +[[nodiscard]] constexpr bool operator!=(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +template +[[nodiscard]] constexpr bool operator<(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return lhs.it < rhs.it; +} + +template +[[nodiscard]] constexpr bool operator>(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return rhs < lhs; +} + +template +[[nodiscard]] constexpr bool operator<=(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return !(lhs > rhs); +} + +template +[[nodiscard]] constexpr bool operator>=(const dense_map_iterator &lhs, const dense_map_iterator &rhs) noexcept { + return !(lhs < rhs); +} + +template +class dense_map_local_iterator final { + template + friend class dense_map_local_iterator; + + using first_type = decltype(std::as_const(std::declval()->element.first)); + using second_type = decltype((std::declval()->element.second)); + +public: + using value_type = std::pair; + using pointer = input_iterator_pointer; + using reference = value_type; + using difference_type = std::ptrdiff_t; + using iterator_category = std::input_iterator_tag; + using iterator_concept = std::forward_iterator_tag; + + constexpr dense_map_local_iterator() noexcept = default; + + constexpr dense_map_local_iterator(It iter, const std::size_t pos) noexcept + : it{iter}, + offset{pos} {} + + template && std::is_constructible_v>> + constexpr dense_map_local_iterator(const dense_map_local_iterator &other) noexcept + : it{other.it}, + offset{other.offset} {} + + constexpr dense_map_local_iterator &operator++() noexcept { + return (offset = it[static_cast(offset)].next), *this; + } + + constexpr dense_map_local_iterator operator++(int) noexcept { + const dense_map_local_iterator orig = *this; + return ++(*this), orig; + } + + [[nodiscard]] constexpr pointer operator->() const noexcept { + return operator*(); + } + + [[nodiscard]] constexpr reference operator*() const noexcept { + const auto idx = static_cast(offset); + return {it[idx].element.first, it[idx].element.second}; + } + + [[nodiscard]] constexpr std::size_t index() const noexcept { + return offset; + } + +private: + It it{}; + std::size_t offset{dense_map_placeholder_position}; +}; + +template +[[nodiscard]] constexpr bool operator==(const dense_map_local_iterator &lhs, const dense_map_local_iterator &rhs) noexcept { + return lhs.index() == rhs.index(); +} + +template +[[nodiscard]] constexpr bool operator!=(const dense_map_local_iterator &lhs, const dense_map_local_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Associative container for key-value pairs with unique keys. + * + * Internally, elements are organized into buckets. Which bucket an element is + * placed into depends entirely on the hash of its key. Keys with the same hash + * code appear in the same bucket. + * + * @tparam Key Key type of the associative container. + * @tparam Type Mapped type of the associative container. + * @tparam Hash Type of function to use to hash the keys. + * @tparam KeyEqual Type of function to use to compare the keys for equality. + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +class dense_map { + static constexpr float default_threshold = 0.875f; + static constexpr std::size_t minimum_capacity = 8u; + static constexpr std::size_t placeholder_position = internal::dense_map_placeholder_position; + + using node_type = internal::dense_map_node; + using alloc_traits = std::allocator_traits; + static_assert(std::is_same_v>, "Invalid value type"); + using sparse_container_type = std::vector>; + using packed_container_type = std::vector>; + + template + [[nodiscard]] std::size_t key_to_bucket(const Other &key) const noexcept { + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay) + return fast_mod(static_cast(sparse.second()(key)), bucket_count()); + } + + template + [[nodiscard]] auto constrained_find(const Other &key, const std::size_t bucket) { + for(auto offset = sparse.first()[bucket]; offset != placeholder_position; offset = packed.first()[offset].next) { + if(packed.second()(packed.first()[offset].element.first, key)) { + return begin() + static_cast(offset); + } + } + + return end(); + } + + template + [[nodiscard]] auto constrained_find(const Other &key, const std::size_t bucket) const { + for(auto offset = sparse.first()[bucket]; offset != placeholder_position; offset = packed.first()[offset].next) { + if(packed.second()(packed.first()[offset].element.first, key)) { + return cbegin() + static_cast(offset); + } + } + + return cend(); + } + + template + [[nodiscard]] auto insert_or_do_nothing(Other &&key, Args &&...args) { + const auto index = key_to_bucket(key); + + if(auto it = constrained_find(key, index); it != end()) { + return std::make_pair(it, false); + } + + packed.first().emplace_back(sparse.first()[index], std::piecewise_construct, std::forward_as_tuple(std::forward(key)), std::forward_as_tuple(std::forward(args)...)); + sparse.first()[index] = packed.first().size() - 1u; + rehash_if_required(); + + return std::make_pair(--end(), true); + } + + template + [[nodiscard]] auto insert_or_overwrite(Other &&key, Arg &&value) { + const auto index = key_to_bucket(key); + + if(auto it = constrained_find(key, index); it != end()) { + it->second = std::forward(value); + return std::make_pair(it, false); + } + + packed.first().emplace_back(sparse.first()[index], std::forward(key), std::forward(value)); + sparse.first()[index] = packed.first().size() - 1u; + rehash_if_required(); + + return std::make_pair(--end(), true); + } + + void move_and_pop(const std::size_t pos) { + if(const auto last = size() - 1u; pos != last) { + size_type *curr = &sparse.first()[key_to_bucket(packed.first().back().element.first)]; + packed.first()[pos] = std::move(packed.first().back()); + for(; *curr != last; curr = &packed.first()[*curr].next) {} + *curr = pos; + } + + packed.first().pop_back(); + } + + void rehash_if_required() { + if(const auto bc = bucket_count(); size() > static_cast(static_cast(bc) * max_load_factor())) { + rehash(bc * 2u); + } + } + +public: + /*! @brief Allocator type. */ + using allocator_type = Allocator; + /*! @brief Key type of the container. */ + using key_type = Key; + /*! @brief Mapped type of the container. */ + using mapped_type = Type; + /*! @brief Key-value type of the container. */ + using value_type = std::pair; + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + /*! @brief Signed integer type. */ + using difference_type = std::ptrdiff_t; + /*! @brief Type of function to use to hash the keys. */ + using hasher = Hash; + /*! @brief Type of function to use to compare the keys for equality. */ + using key_equal = KeyEqual; + /*! @brief Input iterator type. */ + using iterator = internal::dense_map_iterator; + /*! @brief Constant input iterator type. */ + using const_iterator = internal::dense_map_iterator; + /*! @brief Input iterator type. */ + using local_iterator = internal::dense_map_local_iterator; + /*! @brief Constant input iterator type. */ + using const_local_iterator = internal::dense_map_local_iterator; + + /*! @brief Default constructor. */ + dense_map() + : dense_map{minimum_capacity} {} + + /** + * @brief Constructs an empty container with a given allocator. + * @param allocator The allocator to use. + */ + explicit dense_map(const allocator_type &allocator) + : dense_map{minimum_capacity, hasher{}, key_equal{}, allocator} {} + + /** + * @brief Constructs an empty container with a given allocator and user + * supplied minimal number of buckets. + * @param cnt Minimal number of buckets. + * @param allocator The allocator to use. + */ + dense_map(const size_type cnt, const allocator_type &allocator) + : dense_map{cnt, hasher{}, key_equal{}, allocator} {} + + /** + * @brief Constructs an empty container with a given allocator, hash + * function and user supplied minimal number of buckets. + * @param cnt Minimal number of buckets. + * @param hash Hash function to use. + * @param allocator The allocator to use. + */ + dense_map(const size_type cnt, const hasher &hash, const allocator_type &allocator) + : dense_map{cnt, hash, key_equal{}, allocator} {} + + /** + * @brief Constructs an empty container with a given allocator, hash + * function, compare function and user supplied minimal number of buckets. + * @param cnt Minimal number of buckets. + * @param hash Hash function to use. + * @param equal Compare function to use. + * @param allocator The allocator to use. + */ + explicit dense_map(const size_type cnt, const hasher &hash = hasher{}, const key_equal &equal = key_equal{}, const allocator_type &allocator = allocator_type{}) + : sparse{allocator, hash}, + packed{allocator, equal} { + rehash(cnt); + } + + /*! @brief Default copy constructor. */ + dense_map(const dense_map &) = default; + + /** + * @brief Allocator-extended copy constructor. + * @param other The instance to copy from. + * @param allocator The allocator to use. + */ + dense_map(const dense_map &other, const allocator_type &allocator) + : sparse{std::piecewise_construct, std::forward_as_tuple(other.sparse.first(), allocator), std::forward_as_tuple(other.sparse.second())}, + packed{std::piecewise_construct, std::forward_as_tuple(other.packed.first(), allocator), std::forward_as_tuple(other.packed.second())}, + threshold{other.threshold} {} + + /*! @brief Default move constructor. */ + dense_map(dense_map &&) noexcept = default; + + /** + * @brief Allocator-extended move constructor. + * @param other The instance to move from. + * @param allocator The allocator to use. + */ + dense_map(dense_map &&other, const allocator_type &allocator) + : sparse{std::piecewise_construct, std::forward_as_tuple(std::move(other.sparse.first()), allocator), std::forward_as_tuple(std::move(other.sparse.second()))}, + packed{std::piecewise_construct, std::forward_as_tuple(std::move(other.packed.first()), allocator), std::forward_as_tuple(std::move(other.packed.second()))}, + threshold{other.threshold} {} + + /*! @brief Default destructor. */ + ~dense_map() = default; + + /** + * @brief Default copy assignment operator. + * @return This container. + */ + dense_map &operator=(const dense_map &) = default; + + /** + * @brief Default move assignment operator. + * @return This container. + */ + dense_map &operator=(dense_map &&) noexcept = default; + + /** + * @brief Exchanges the contents with those of a given container. + * @param other Container to exchange the content with. + */ + void swap(dense_map &other) noexcept { + using std::swap; + swap(sparse, other.sparse); + swap(packed, other.packed); + swap(threshold, other.threshold); + } + + /** + * @brief Returns the associated allocator. + * @return The associated allocator. + */ + [[nodiscard]] constexpr allocator_type get_allocator() const noexcept { + return sparse.first().get_allocator(); + } + + /** + * @brief Returns an iterator to the beginning. + * + * If the array is empty, the returned iterator will be equal to `end()`. + * + * @return An iterator to the first instance of the internal array. + */ + [[nodiscard]] const_iterator cbegin() const noexcept { + return packed.first().begin(); + } + + /*! @copydoc cbegin */ + [[nodiscard]] const_iterator begin() const noexcept { + return cbegin(); + } + + /*! @copydoc begin */ + [[nodiscard]] iterator begin() noexcept { + return packed.first().begin(); + } + + /** + * @brief Returns an iterator to the end. + * @return An iterator to the element following the last instance of the + * internal array. + */ + [[nodiscard]] const_iterator cend() const noexcept { + return packed.first().end(); + } + + /*! @copydoc cend */ + [[nodiscard]] const_iterator end() const noexcept { + return cend(); + } + + /*! @copydoc end */ + [[nodiscard]] iterator end() noexcept { + return packed.first().end(); + } + + /** + * @brief Checks whether a container is empty. + * @return True if the container is empty, false otherwise. + */ + [[nodiscard]] bool empty() const noexcept { + return packed.first().empty(); + } + + /** + * @brief Returns the number of elements in a container. + * @return Number of elements in a container. + */ + [[nodiscard]] size_type size() const noexcept { + return packed.first().size(); + } + + /** + * @brief Returns the maximum possible number of elements. + * @return Maximum possible number of elements. + */ + [[nodiscard]] size_type max_size() const noexcept { + return packed.first().max_size(); + } + + /*! @brief Clears the container. */ + void clear() noexcept { + sparse.first().clear(); + packed.first().clear(); + rehash(0u); + } + + /** + * @brief Inserts an element into the container, if the key does not exist. + * @param value A key-value pair eventually convertible to the value type. + * @return A pair consisting of an iterator to the inserted element (or to + * the element that prevented the insertion) and a bool denoting whether the + * insertion took place. + */ + std::pair insert(const value_type &value) { + return insert_or_do_nothing(value.first, value.second); + } + + /*! @copydoc insert */ + std::pair insert(value_type &&value) { + return insert_or_do_nothing(std::move(value.first), std::move(value.second)); + } + + /** + * @copydoc insert + * @tparam Arg Type of the key-value pair to insert into the container. + */ + template + std::enable_if_t, std::pair> + insert(Arg &&value) { + return insert_or_do_nothing(std::forward(value).first, std::forward(value).second); + } + + /** + * @brief Inserts elements into the container, if their keys do not exist. + * @tparam It Type of input iterator. + * @param first An iterator to the first element of the range of elements. + * @param last An iterator past the last element of the range of elements. + */ + template + void insert(It first, It last) { + for(; first != last; ++first) { + insert(*first); + } + } + + /** + * @brief Inserts an element into the container or assigns to the current + * element if the key already exists. + * @tparam Arg Type of the value to insert or assign. + * @param key A key used both to look up and to insert if not found. + * @param value A value to insert or assign. + * @return A pair consisting of an iterator to the element and a bool + * denoting whether the insertion took place. + */ + template + std::pair insert_or_assign(const key_type &key, Arg &&value) { + return insert_or_overwrite(key, std::forward(value)); + } + + /*! @copydoc insert_or_assign */ + template + std::pair insert_or_assign(key_type &&key, Arg &&value) { + return insert_or_overwrite(std::move(key), std::forward(value)); + } + + /** + * @brief Constructs an element in-place, if the key does not exist. + * + * The element is also constructed when the container already has the key, + * in which case the newly constructed object is destroyed immediately. + * + * @tparam Args Types of arguments to forward to the constructor of the + * element. + * @param args Arguments to forward to the constructor of the element. + * @return A pair consisting of an iterator to the inserted element (or to + * the element that prevented the insertion) and a bool denoting whether the + * insertion took place. + */ + template + std::pair emplace([[maybe_unused]] Args &&...args) { + if constexpr(sizeof...(Args) == 0u) { + return insert_or_do_nothing(key_type{}); + } else if constexpr(sizeof...(Args) == 1u) { + return insert_or_do_nothing(std::forward(args).first..., std::forward(args).second...); + } else if constexpr(sizeof...(Args) == 2u) { + return insert_or_do_nothing(std::forward(args)...); + } else { + auto &node = packed.first().emplace_back(packed.first().size(), std::forward(args)...); + const auto index = key_to_bucket(node.element.first); + + if(auto it = constrained_find(node.element.first, index); it != end()) { + packed.first().pop_back(); + return std::make_pair(it, false); + } + + std::swap(node.next, sparse.first()[index]); + rehash_if_required(); + + return std::make_pair(--end(), true); + } + } + + /** + * @brief Inserts in-place if the key does not exist, does nothing if the + * key exists. + * @tparam Args Types of arguments to forward to the constructor of the + * element. + * @param key A key used both to look up and to insert if not found. + * @param args Arguments to forward to the constructor of the element. + * @return A pair consisting of an iterator to the inserted element (or to + * the element that prevented the insertion) and a bool denoting whether the + * insertion took place. + */ + template + std::pair try_emplace(const key_type &key, Args &&...args) { + return insert_or_do_nothing(key, std::forward(args)...); + } + + /*! @copydoc try_emplace */ + template + std::pair try_emplace(key_type &&key, Args &&...args) { + return insert_or_do_nothing(std::move(key), std::forward(args)...); + } + + /** + * @brief Removes an element from a given position. + * @param pos An iterator to the element to remove. + * @return An iterator following the removed element. + */ + iterator erase(const_iterator pos) { + const auto diff = pos - cbegin(); + erase(pos->first); + return begin() + diff; + } + + /** + * @brief Removes the given elements from a container. + * @param first An iterator to the first element of the range of elements. + * @param last An iterator past the last element of the range of elements. + * @return An iterator following the last removed element. + */ + iterator erase(const_iterator first, const_iterator last) { + const auto dist = first - cbegin(); + + for(auto from = last - cbegin(); from != dist; --from) { + erase(packed.first()[static_cast(from) - 1u].element.first); + } + + return (begin() + dist); + } + + /** + * @brief Removes the element associated with a given key. + * @param key A key value of an element to remove. + * @return Number of elements removed (either 0 or 1). + */ + size_type erase(const key_type &key) { + for(size_type *curr = &sparse.first()[key_to_bucket(key)]; *curr != placeholder_position; curr = &packed.first()[*curr].next) { + if(packed.second()(packed.first()[*curr].element.first, key)) { + const auto index = *curr; + *curr = packed.first()[*curr].next; + move_and_pop(index); + return 1u; + } + } + + return 0u; + } + + /** + * @brief Accesses a given element with bounds checking. + * @param key A key of an element to find. + * @return A reference to the mapped value of the requested element. + */ + [[nodiscard]] mapped_type &at(const key_type &key) { + auto it = find(key); + ENTT_ASSERT(it != end(), "Invalid key"); + return it->second; + } + + /*! @copydoc at */ + [[nodiscard]] const mapped_type &at(const key_type &key) const { + auto it = find(key); + ENTT_ASSERT(it != cend(), "Invalid key"); + return it->second; + } + + /** + * @brief Accesses a given element with bounds checking. + * @tparam Other Type of the key of an element to find. + * @param key A key of an element to find. + * @return A reference to the mapped value of the requested element. + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + at(const Other &key) const { + auto it = find(key); + ENTT_ASSERT(it != cend(), "Invalid key"); + return it->second; + } + + /*! @copydoc at */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + at(const Other &key) { + auto it = find(key); + ENTT_ASSERT(it != end(), "Invalid key"); + return it->second; + } + + /** + * @brief Accesses or inserts a given element. + * @param key A key of an element to find or insert. + * @return A reference to the mapped value of the requested element. + */ + [[nodiscard]] mapped_type &operator[](const key_type &key) { + return insert_or_do_nothing(key).first->second; + } + + /** + * @brief Accesses or inserts a given element. + * @param key A key of an element to find or insert. + * @return A reference to the mapped value of the requested element. + */ + [[nodiscard]] mapped_type &operator[](key_type &&key) { + return insert_or_do_nothing(std::move(key)).first->second; + } + + /** + * @brief Returns the number of elements matching a key (either 1 or 0). + * @param key Key value of an element to search for. + * @return Number of elements matching the key (either 1 or 0). + */ + [[nodiscard]] size_type count(const key_type &key) const { + return find(key) != end(); + } + + /** + * @brief Returns the number of elements matching a key (either 1 or 0). + * @tparam Other Type of the key value of an element to search for. + * @param key Key value of an element to search for. + * @return Number of elements matching the key (either 1 or 0). + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + count(const Other &key) const { + return find(key) != end(); + } + + /** + * @brief Finds an element with a given key. + * @param key Key value of an element to search for. + * @return An iterator to an element with the given key. If no such element + * is found, a past-the-end iterator is returned. + */ + [[nodiscard]] iterator find(const key_type &key) { + return constrained_find(key, key_to_bucket(key)); + } + + /*! @copydoc find */ + [[nodiscard]] const_iterator find(const key_type &key) const { + return constrained_find(key, key_to_bucket(key)); + } + + /** + * @brief Finds an element with a key that compares _equivalent_ to a given + * key. + * @tparam Other Type of the key value of an element to search for. + * @param key Key value of an element to search for. + * @return An iterator to an element with the given key. If no such element + * is found, a past-the-end iterator is returned. + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + find(const Other &key) { + return constrained_find(key, key_to_bucket(key)); + } + + /*! @copydoc find */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + find(const Other &key) const { + return constrained_find(key, key_to_bucket(key)); + } + + /** + * @brief Returns a range containing all elements with a given key. + * @param key Key value of an element to search for. + * @return A pair of iterators pointing to the first element and past the + * last element of the range. + */ + [[nodiscard]] std::pair equal_range(const key_type &key) { + const auto it = find(key); + return {it, it + !(it == end())}; + } + + /*! @copydoc equal_range */ + [[nodiscard]] std::pair equal_range(const key_type &key) const { + const auto it = find(key); + return {it, it + !(it == cend())}; + } + + /** + * @brief Returns a range containing all elements that compare _equivalent_ + * to a given key. + * @tparam Other Type of an element to search for. + * @param key Key value of an element to search for. + * @return A pair of iterators pointing to the first element and past the + * last element of the range. + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t>> + equal_range(const Other &key) { + const auto it = find(key); + return {it, it + !(it == end())}; + } + + /*! @copydoc equal_range */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t>> + equal_range(const Other &key) const { + const auto it = find(key); + return {it, it + !(it == cend())}; + } + + /** + * @brief Checks if the container contains an element with a given key. + * @param key Key value of an element to search for. + * @return True if there is such an element, false otherwise. + */ + [[nodiscard]] bool contains(const key_type &key) const { + return (find(key) != cend()); + } + + /** + * @brief Checks if the container contains an element with a key that + * compares _equivalent_ to a given value. + * @tparam Other Type of the key value of an element to search for. + * @param key Key value of an element to search for. + * @return True if there is such an element, false otherwise. + */ + template + [[nodiscard]] std::enable_if_t && is_transparent_v, std::conditional_t> + contains(const Other &key) const { + return (find(key) != cend()); + } + + /** + * @brief Returns an iterator to the beginning of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the beginning of the given bucket. + */ + [[nodiscard]] const_local_iterator cbegin(const size_type index) const { + return {packed.first().begin(), sparse.first()[index]}; + } + + /** + * @brief Returns an iterator to the beginning of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the beginning of the given bucket. + */ + [[nodiscard]] const_local_iterator begin(const size_type index) const { + return cbegin(index); + } + + /** + * @brief Returns an iterator to the beginning of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the beginning of the given bucket. + */ + [[nodiscard]] local_iterator begin(const size_type index) { + return {packed.first().begin(), sparse.first()[index]}; + } + + /** + * @brief Returns an iterator to the end of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the end of the given bucket. + */ + [[nodiscard]] const_local_iterator cend([[maybe_unused]] const size_type index) const { + return {}; + } + + /** + * @brief Returns an iterator to the end of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the end of the given bucket. + */ + [[nodiscard]] const_local_iterator end(const size_type index) const { + return cend(index); + } + + /** + * @brief Returns an iterator to the end of a given bucket. + * @param index An index of a bucket to access. + * @return An iterator to the end of the given bucket. + */ + [[nodiscard]] local_iterator end([[maybe_unused]] const size_type index) { + return {}; + } + + /** + * @brief Returns the number of buckets. + * @return The number of buckets. + */ + [[nodiscard]] size_type bucket_count() const { + return sparse.first().size(); + } + + /** + * @brief Returns the maximum number of buckets. + * @return The maximum number of buckets. + */ + [[nodiscard]] size_type max_bucket_count() const { + return sparse.first().max_size(); + } + + /** + * @brief Returns the number of elements in a given bucket. + * @param index The index of the bucket to examine. + * @return The number of elements in the given bucket. + */ + [[nodiscard]] size_type bucket_size(const size_type index) const { + return static_cast(std::distance(begin(index), end(index))); + } + + /** + * @brief Returns the bucket for a given key. + * @param key The value of the key to examine. + * @return The bucket for the given key. + */ + [[nodiscard]] size_type bucket(const key_type &key) const { + return key_to_bucket(key); + } + + /** + * @brief Returns the average number of elements per bucket. + * @return The average number of elements per bucket. + */ + [[nodiscard]] float load_factor() const { + return static_cast(size()) / static_cast(bucket_count()); + } + + /** + * @brief Returns the maximum average number of elements per bucket. + * @return The maximum average number of elements per bucket. + */ + [[nodiscard]] float max_load_factor() const { + return threshold; + } + + /** + * @brief Sets the desired maximum average number of elements per bucket. + * @param value A desired maximum average number of elements per bucket. + */ + void max_load_factor(const float value) { + ENTT_ASSERT(value > 0.f, "Invalid load factor"); + threshold = value; + rehash(0u); + } + + /** + * @brief Reserves at least the specified number of buckets and regenerates + * the hash table. + * @param cnt New number of buckets. + */ + void rehash(const size_type cnt) { + auto value = cnt > minimum_capacity ? cnt : minimum_capacity; + const auto cap = static_cast(static_cast(size()) / max_load_factor()); + value = value > cap ? value : cap; + + if(const auto sz = next_power_of_two(value); sz != bucket_count()) { + sparse.first().resize(sz); + + for(auto &&elem: sparse.first()) { + elem = placeholder_position; + } + + for(size_type pos{}, last = size(); pos < last; ++pos) { + const auto index = key_to_bucket(packed.first()[pos].element.first); + packed.first()[pos].next = std::exchange(sparse.first()[index], pos); + } + } + } + + /** + * @brief Reserves space for at least the specified number of elements and + * regenerates the hash table. + * @param cnt New number of elements. + */ + void reserve(const size_type cnt) { + packed.first().reserve(cnt); + rehash(static_cast(std::ceil(static_cast(cnt) / max_load_factor()))); + } + + /** + * @brief Returns the function used to hash the keys. + * @return The function used to hash the keys. + */ + [[nodiscard]] hasher hash_function() const { + return sparse.second(); + } + + /** + * @brief Returns the function used to compare keys for equality. + * @return The function used to compare keys for equality. + */ + [[nodiscard]] key_equal key_eq() const { + return packed.second(); + } + +private: + compressed_pair sparse; + compressed_pair packed; + float threshold{default_threshold}; +}; + +} // namespace entt + +/*! @cond TURN_OFF_DOXYGEN */ +namespace std { + +template +struct uses_allocator, Allocator> + : std::true_type {}; + +} // namespace std +/*! @endcond */ + +#endif + +// #include "../core/compressed_pair.hpp" +#ifndef ENTT_CORE_COMPRESSED_PAIR_HPP +#define ENTT_CORE_COMPRESSED_PAIR_HPP + +#include +#include +#include +#include +// #include "fwd.hpp" + +// #include "type_traits.hpp" +#ifndef ENTT_CORE_TYPE_TRAITS_HPP +#define ENTT_CORE_TYPE_TRAITS_HPP + +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "fwd.hpp" + + +namespace entt { + +/** + * @brief Utility class to disambiguate overloaded functions. + * @tparam N Number of choices available. + */ +template +struct choice_t + // unfortunately, doxygen cannot parse such a construct + : /*! @cond TURN_OFF_DOXYGEN */ choice_t /*! @endcond */ +{}; + +/*! @copybrief choice_t */ +template<> +struct choice_t<0> {}; + +/** + * @brief Variable template for the choice trick. + * @tparam N Number of choices available. + */ +template +inline constexpr choice_t choice{}; + +/** + * @brief Identity type trait. + * + * Useful to establish non-deduced contexts in template argument deduction + * (waiting for C++20) or to provide types through function arguments. + * + * @tparam Type A type. + */ +template +struct type_identity { + /*! @brief Identity type. */ + using type = Type; +}; + +/** + * @brief Helper type. + * @tparam Type A type. + */ +template +using type_identity_t = typename type_identity::type; + +/** + * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains. + * @tparam Type The type of which to return the size. + */ +template +struct size_of: std::integral_constant {}; + +/*! @copydoc size_of */ +template +struct size_of> + // NOLINTNEXTLINE(bugprone-sizeof-expression) + : std::integral_constant {}; + +/** + * @brief Helper variable template. + * @tparam Type The type of which to return the size. + */ +template +inline constexpr std::size_t size_of_v = size_of::value; + +/** + * @brief Using declaration to be used to _repeat_ the same type a number of + * times equal to the size of a given parameter pack. + * @tparam Type A type to repeat. + */ +template +using unpack_as_type = Type; + +/** + * @brief Helper variable template to be used to _repeat_ the same value a + * number of times equal to the size of a given parameter pack. + * @tparam Value A value to repeat. + */ +template +inline constexpr auto unpack_as_value = Value; + +/** + * @brief Wraps a static constant. + * @tparam Value A static constant. + */ +template +using integral_constant = std::integral_constant; + +/** + * @brief Alias template to facilitate the creation of named values. + * @tparam Value A constant value at least convertible to `id_type`. + */ +template +using tag = integral_constant; + +/** + * @brief A class to use to push around lists of types, nothing more. + * @tparam Type Types provided by the type list. + */ +template +struct type_list { + /*! @brief Type list type. */ + using type = type_list; + /*! @brief Compile-time number of elements in the type list. */ + static constexpr auto size = sizeof...(Type); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_element; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Index Index of the type to return. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element> + : type_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_element<0u, type_list> { + /*! @brief Searched type. */ + using type = First; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Type list to search into. + */ +template +using type_list_element_t = typename type_list_element::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_index; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam First First type provided by the type list. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 1u + type_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + * @tparam Other Other types provided by the type list. + */ +template +struct type_list_index> { + static_assert(type_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the types of a type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +struct type_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for and for which to return the index. + */ +template +inline constexpr std::size_t type_list_index_v = type_list_index::value; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @return A type list composed by the types of both the type lists. + */ +template +constexpr type_list operator+(type_list, type_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_cat; + +/*! @brief Concatenates multiple type lists. */ +template<> +struct type_list_cat<> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list<>; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + * @tparam List Other type lists, if any. + */ +template +struct type_list_cat, type_list, List...> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = typename type_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple type lists. + * @tparam Type Types provided by the type list. + */ +template +struct type_list_cat> { + /*! @brief A type list composed by the types of all the type lists. */ + using type = type_list; +}; + +/** + * @brief Helper type. + * @tparam List Type lists to concatenate. + */ +template +using type_list_cat_t = typename type_list_cat::type; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct type_list_unique; + +template +struct type_list_unique, Type...> + : std::conditional_t<(std::is_same_v || ...), type_list_unique, Type...>, type_list_unique, Type..., First>> {}; + +template +struct type_list_unique, Type...> { + using type = type_list; +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Removes duplicates types from a type list. + * @tparam List Type list. + */ +template +struct type_list_unique { + /*! @brief A type list without duplicate types. */ + using type = typename internal::type_list_unique::type; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + */ +template +using type_list_unique_t = typename type_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a type list contains a + * given type, false otherwise. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +struct type_list_contains; + +/** + * @copybrief type_list_contains + * @tparam Type Types provided by the type list. + * @tparam Other Type to look for. + */ +template +struct type_list_contains, Other> + : std::bool_constant<(std::is_same_v || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Type list. + * @tparam Type Type to look for. + */ +template +inline constexpr bool type_list_contains_v = type_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct type_list_diff; + +/** + * @brief Computes the difference between two type lists. + * @tparam Type Types provided by the first type list. + * @tparam Other Types provided by the second type list. + */ +template +struct type_list_diff, type_list> { + /*! @brief A type list that is the difference between the two type lists. */ + using type = type_list_cat_t, Type>, type_list<>, type_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Type lists between which to compute the difference. + */ +template +using type_list_diff_t = typename type_list_diff::type; + +/*! @brief Primary template isn't defined on purpose. */ +template class> +struct type_list_transform; + +/** + * @brief Applies a given _function_ to a type list and generate a new list. + * @tparam Type Types provided by the type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +struct type_list_transform, Op> { + /*! @brief Resulting type list after applying the transform function. */ + // NOLINTNEXTLINE(modernize-type-traits) + using type = type_list::type...>; +}; + +/** + * @brief Helper type. + * @tparam List Type list. + * @tparam Op Unary operation as template class with a type member named `type`. + */ +template class Op> +using type_list_transform_t = typename type_list_transform::type; + +/** + * @brief A class to use to push around lists of constant values, nothing more. + * @tparam Value Values provided by the value list. + */ +template +struct value_list { + /*! @brief Value list type. */ + using type = value_list; + /*! @brief Compile-time number of elements in the value list. */ + static constexpr auto size = sizeof...(Value); +}; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_element; + +/** + * @brief Provides compile-time indexed access to the values of a value list. + * @tparam Index Index of the value to return. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element> + : value_list_element> {}; + +/** + * @brief Provides compile-time indexed access to the types of a type list. + * @tparam Value First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_element<0u, value_list> { + /*! @brief Searched type. */ + using type = decltype(Value); + /*! @brief Searched value. */ + static constexpr auto value = Value; +}; + +/** + * @brief Helper type. + * @tparam Index Index of the type to return. + * @tparam List Value list to search into. + */ +template +using value_list_element_t = typename value_list_element::type; + +/** + * @brief Helper type. + * @tparam Index Index of the value to return. + * @tparam List Value list to search into. + */ +template +inline constexpr auto value_list_element_v = value_list_element::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_index; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam First First value provided by the value list. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 1u + value_list_index>::value; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + * @tparam Other Other values provided by the value list. + */ +template +struct value_list_index> { + static_assert(value_list_index>::value == sizeof...(Other), "Non-unique type"); + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given value in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Provides compile-time type access to the values of a value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +struct value_list_index> { + /*! @brief Unsigned integer type. */ + using value_type = std::size_t; + /*! @brief Compile-time position of the given type in the sublist. */ + static constexpr value_type value = 0u; +}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for and for which to return the index. + */ +template +inline constexpr std::size_t value_list_index_v = value_list_index::value; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @return A value list composed by the values of both the value lists. + */ +template +constexpr value_list operator+(value_list, value_list) { + return {}; +} + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_cat; + +/*! @brief Concatenates multiple value lists. */ +template<> +struct value_list_cat<> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list<>; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + * @tparam List Other value lists, if any. + */ +template +struct value_list_cat, value_list, List...> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = typename value_list_cat, List...>::type; +}; + +/** + * @brief Concatenates multiple value lists. + * @tparam Value Values provided by the value list. + */ +template +struct value_list_cat> { + /*! @brief A value list composed by the values of all the value lists. */ + using type = value_list; +}; + +/** + * @brief Helper type. + * @tparam List Value lists to concatenate. + */ +template +using value_list_cat_t = typename value_list_cat::type; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_unique; + +/** + * @brief Removes duplicates values from a value list. + * @tparam Value One of the values provided by the given value list. + * @tparam Other The other values provided by the given value list. + */ +template +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = std::conditional_t< + ((Value == Other) || ...), + typename value_list_unique>::type, + value_list_cat_t, typename value_list_unique>::type>>; +}; + +/*! @brief Removes duplicates values from a value list. */ +template<> +struct value_list_unique> { + /*! @brief A value list without duplicate types. */ + using type = value_list<>; +}; + +/** + * @brief Helper type. + * @tparam Type A value list. + */ +template +using value_list_unique_t = typename value_list_unique::type; + +/** + * @brief Provides the member constant `value` to true if a value list contains + * a given value, false otherwise. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +struct value_list_contains; + +/** + * @copybrief value_list_contains + * @tparam Value Values provided by the value list. + * @tparam Other Value to look for. + */ +template +struct value_list_contains, Other> + : std::bool_constant<((Value == Other) || ...)> {}; + +/** + * @brief Helper variable template. + * @tparam List Value list. + * @tparam Value Value to look for. + */ +template +inline constexpr bool value_list_contains_v = value_list_contains::value; + +/*! @brief Primary template isn't defined on purpose. */ +template +struct value_list_diff; + +/** + * @brief Computes the difference between two value lists. + * @tparam Value Values provided by the first value list. + * @tparam Other Values provided by the second value list. + */ +template +struct value_list_diff, value_list> { + /*! @brief A value list that is the difference between the two value lists. */ + using type = value_list_cat_t, Value>, value_list<>, value_list>...>; +}; + +/** + * @brief Helper type. + * @tparam List Value lists between which to compute the difference. + */ +template +using value_list_diff_t = typename value_list_diff::type; + +/*! @brief Same as std::is_invocable, but with tuples. */ +template +struct is_applicable: std::false_type {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @copybrief is_applicable + * @tparam Func A valid function type. + * @tparam Tuple Tuple-like type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template class Tuple, typename... Args> +struct is_applicable>: std::is_invocable {}; + +/** + * @brief Helper variable template. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_v = is_applicable::value; + +/*! @brief Same as std::is_invocable_r, but with tuples for arguments. */ +template +struct is_applicable_r: std::false_type {}; + +/** + * @copybrief is_applicable_r + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +struct is_applicable_r>: std::is_invocable_r {}; + +/** + * @brief Helper variable template. + * @tparam Ret The type to which the return type of the function should be + * convertible. + * @tparam Func A valid function type. + * @tparam Args The list of arguments to use to probe the function type. + */ +template +inline constexpr bool is_applicable_r_v = is_applicable_r::value; + +/** + * @brief Provides the member constant `value` to true if a given type is + * complete, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_complete: std::false_type {}; + +/*! @copydoc is_complete */ +template +struct is_complete>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_complete_v = is_complete::value; + +/** + * @brief Provides the member constant `value` to true if a given type is an + * iterator, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_iterator: std::false_type {}; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_iterator_category: std::false_type {}; + +template +struct has_iterator_category::iterator_category>>: std::true_type {}; + +} // namespace internal +/*! @endcond */ + +/*! @copydoc is_iterator */ +template +struct is_iterator>>>> + : internal::has_iterator_category {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_iterator_v = is_iterator::value; + +/** + * @brief Provides the member constant `value` to true if a given type is both + * an empty and non-final class, false otherwise. + * @tparam Type The type to test + */ +template +struct is_ebco_eligible + : std::bool_constant && !std::is_final_v> {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_ebco_eligible_v = is_ebco_eligible::value; + +/** + * @brief Provides the member constant `value` to true if `Type::is_transparent` + * is valid and denotes a type, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_transparent: std::false_type {}; + +/*! @copydoc is_transparent */ +template +struct is_transparent>: std::true_type {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_transparent_v = is_transparent::value; + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct has_tuple_size_value: std::false_type {}; + +template +struct has_tuple_size_value::value)>>: std::true_type {}; + +template +struct has_value_type: std::false_type {}; + +template +struct has_value_type>: std::true_type {}; + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable(); + +template +[[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence) { + return (dispatch_is_equality_comparable>() && ...); +} + +template +[[nodiscard]] constexpr bool maybe_equality_comparable(char) { + return false; +} + +template +[[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval() == std::declval()) { + return true; +} + +template +[[nodiscard]] constexpr bool dispatch_is_equality_comparable() { + // NOLINTBEGIN(modernize-use-transparent-functors) + if constexpr(std::is_array_v) { + return false; + } else if constexpr(is_complete_v>>) { + if constexpr(has_tuple_size_value::value) { + return maybe_equality_comparable(0) && unpack_maybe_equality_comparable(std::make_index_sequence::value>{}); + } else { + return maybe_equality_comparable(0); + } + } else if constexpr(has_value_type::value) { + if constexpr(is_iterator_v || std::is_same_v || dispatch_is_equality_comparable()) { + return maybe_equality_comparable(0); + } else { + return false; + } + } else { + return maybe_equality_comparable(0); + } + // NOLINTEND(modernize-use-transparent-functors) +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Provides the member constant `value` to true if a given type is + * equality comparable, false otherwise. + * @tparam Type The type to test. + */ +template +struct is_equality_comparable: std::bool_constant()> {}; + +/*! @copydoc is_equality_comparable */ +template +struct is_equality_comparable: is_equality_comparable {}; + +/** + * @brief Helper variable template. + * @tparam Type The type to test. + */ +template +inline constexpr bool is_equality_comparable_v = is_equality_comparable::value; + +/** + * @brief Transcribes the constness of a type to another type. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = std::remove_const_t; +}; + +/*! @copydoc constness_as */ +template +struct constness_as { + /*! @brief The type resulting from the transcription of the constness. */ + using type = const To; +}; + +/** + * @brief Alias template to facilitate the transcription of the constness. + * @tparam To The type to which to transcribe the constness. + * @tparam From The type from which to transcribe the constness. + */ +template +using constness_as_t = typename constness_as::type; + +/** + * @brief Extracts the class of a non-static member object or function. + * @tparam Member A pointer to a non-static member object or function. + */ +template +class member_class { + static_assert(std::is_member_pointer_v, "Invalid pointer type to non-static member object or function"); + + template + static Class *clazz(Ret (Class::*)(Args...)); + + template + static Class *clazz(Ret (Class::*)(Args...) const); + + template + static Class *clazz(Type Class::*); + +public: + /*! @brief The class of the given non-static member object or function. */ + using type = std::remove_pointer_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Member A pointer to a non-static member object or function. + */ +template +using member_class_t = typename member_class::type; + +/** + * @brief Extracts the n-th argument of a _callable_ type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid _callable_ type. + */ +template +class nth_argument { + template + static constexpr type_list pick_up(Ret (*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...)); + + template + static constexpr type_list pick_up(Ret (Class ::*)(Args...) const); + + template + static constexpr type_list pick_up(Type Class ::*); + + template + static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&); + +public: + /*! @brief N-th argument of the _callable_ type. */ + using type = type_list_element_t()))>; +}; + +/** + * @brief Helper type. + * @tparam Index The index of the argument to extract. + * @tparam Candidate A valid function, member function or data member type. + */ +template +using nth_argument_t = typename nth_argument::type; + +} // namespace entt + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::type_list_element> {}; + +template +struct std::tuple_size>: std::integral_constant::size> {}; + +template +struct std::tuple_element>: entt::value_list_element> {}; + +#endif + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct compressed_pair_element { + using reference = Type &; + using const_reference = const Type &; + + template>> + // NOLINTNEXTLINE(modernize-use-equals-default) + constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v) {} + + template>, compressed_pair_element>>> + constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v) + : value{std::forward(arg)} {} + + template + constexpr compressed_pair_element(std::tuple args, std::index_sequence) noexcept(std::is_nothrow_constructible_v) + : value{std::forward(std::get(args))...} {} + + [[nodiscard]] constexpr reference get() noexcept { + return value; + } + + [[nodiscard]] constexpr const_reference get() const noexcept { + return value; + } + +private: + Type value{}; +}; + +template +struct compressed_pair_element>>: Type { + using reference = Type &; + using const_reference = const Type &; + using base_type = Type; + + template>> + constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v) + : base_type{} {} + + template>, compressed_pair_element>>> + constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v) + : base_type{std::forward(arg)} {} + + template + constexpr compressed_pair_element(std::tuple args, std::index_sequence) noexcept(std::is_nothrow_constructible_v) + : base_type{std::forward(std::get(args))...} {} + + [[nodiscard]] constexpr reference get() noexcept { + return *this; + } + + [[nodiscard]] constexpr const_reference get() const noexcept { + return *this; + } +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief A compressed pair. + * + * A pair that exploits the _Empty Base Class Optimization_ (or _EBCO_) to + * reduce its final size to a minimum. + * + * @tparam First The type of the first element that the pair stores. + * @tparam Second The type of the second element that the pair stores. + */ +template +class compressed_pair final + : internal::compressed_pair_element, + internal::compressed_pair_element { + using first_base = internal::compressed_pair_element; + using second_base = internal::compressed_pair_element; + +public: + /*! @brief The type of the first element that the pair stores. */ + using first_type = First; + /*! @brief The type of the second element that the pair stores. */ + using second_type = Second; + + /** + * @brief Default constructor, conditionally enabled. + * + * This constructor is only available when the types that the pair stores + * are both at least default constructible. + * + * @tparam Dummy Dummy template parameter used for internal purposes. + */ + template && std::is_default_constructible_v>> + constexpr compressed_pair() noexcept(std::is_nothrow_default_constructible_v && std::is_nothrow_default_constructible_v) + : first_base{}, + second_base{} {} + + /** + * @brief Copy constructor. + * @param other The instance to copy from. + */ + constexpr compressed_pair(const compressed_pair &other) = default; + + /** + * @brief Move constructor. + * @param other The instance to move from. + */ + constexpr compressed_pair(compressed_pair &&other) noexcept = default; + + /** + * @brief Constructs a pair from its values. + * @tparam Arg Type of value to use to initialize the first element. + * @tparam Other Type of value to use to initialize the second element. + * @param arg Value to use to initialize the first element. + * @param other Value to use to initialize the second element. + */ + template + constexpr compressed_pair(Arg &&arg, Other &&other) noexcept(std::is_nothrow_constructible_v && std::is_nothrow_constructible_v) + : first_base{std::forward(arg)}, + second_base{std::forward(other)} {} + + /** + * @brief Constructs a pair by forwarding the arguments to its parts. + * @tparam Args Types of arguments to use to initialize the first element. + * @tparam Other Types of arguments to use to initialize the second element. + * @param args Arguments to use to initialize the first element. + * @param other Arguments to use to initialize the second element. + */ + template + constexpr compressed_pair(std::piecewise_construct_t, std::tuple args, std::tuple other) noexcept(std::is_nothrow_constructible_v && std::is_nothrow_constructible_v) + : first_base{std::move(args), std::index_sequence_for{}}, + second_base{std::move(other), std::index_sequence_for{}} {} + + /*! @brief Default destructor. */ + ~compressed_pair() = default; + + /** + * @brief Copy assignment operator. + * @param other The instance to copy from. + * @return This compressed pair object. + */ + constexpr compressed_pair &operator=(const compressed_pair &other) = default; + + /** + * @brief Move assignment operator. + * @param other The instance to move from. + * @return This compressed pair object. + */ + constexpr compressed_pair &operator=(compressed_pair &&other) noexcept = default; + + /** + * @brief Returns the first element that a pair stores. + * @return The first element that a pair stores. + */ + [[nodiscard]] constexpr first_type &first() noexcept { + return static_cast(*this).get(); + } + + /*! @copydoc first */ + [[nodiscard]] constexpr const first_type &first() const noexcept { + return static_cast(*this).get(); + } + + /** + * @brief Returns the second element that a pair stores. + * @return The second element that a pair stores. + */ + [[nodiscard]] constexpr second_type &second() noexcept { + return static_cast(*this).get(); + } + + /*! @copydoc second */ + [[nodiscard]] constexpr const second_type &second() const noexcept { + return static_cast(*this).get(); + } + + /** + * @brief Swaps two compressed pair objects. + * @param other The compressed pair to swap with. + */ + constexpr void swap(compressed_pair &other) noexcept { + using std::swap; + swap(first(), other.first()); + swap(second(), other.second()); + } + + /** + * @brief Extracts an element from the compressed pair. + * @tparam Index An integer value that is either 0 or 1. + * @return Returns a reference to the first element if `Index` is 0 and a + * reference to the second element if `Index` is 1. + */ + template + [[nodiscard]] constexpr decltype(auto) get() noexcept { + if constexpr(Index == 0u) { + return first(); + } else { + static_assert(Index == 1u, "Index out of bounds"); + return second(); + } + } + + /*! @copydoc get */ + template + [[nodiscard]] constexpr decltype(auto) get() const noexcept { + if constexpr(Index == 0u) { + return first(); + } else { + static_assert(Index == 1u, "Index out of bounds"); + return second(); + } + } +}; + +/** + * @brief Deduction guide. + * @tparam Type Type of value to use to initialize the first element. + * @tparam Other Type of value to use to initialize the second element. + */ +template +compressed_pair(Type &&, Other &&) -> compressed_pair, std::decay_t>; + +/** + * @brief Swaps two compressed pair objects. + * @tparam First The type of the first element that the pairs store. + * @tparam Second The type of the second element that the pairs store. + * @param lhs A valid compressed pair object. + * @param rhs A valid compressed pair object. + */ +template +constexpr void swap(compressed_pair &lhs, compressed_pair &rhs) noexcept { + lhs.swap(rhs); +} + +} // namespace entt + +namespace std { + +/** + * @brief `std::tuple_size` specialization for `compressed_pair`s. + * @tparam First The type of the first element that the pair stores. + * @tparam Second The type of the second element that the pair stores. + */ +template +struct tuple_size>: integral_constant {}; + +/** + * @brief `std::tuple_element` specialization for `compressed_pair`s. + * @tparam Index The index of the type to return. + * @tparam First The type of the first element that the pair stores. + * @tparam Second The type of the second element that the pair stores. + */ +template +struct tuple_element>: conditional { + static_assert(Index < 2u, "Index out of bounds"); +}; + +} // namespace std + +#endif + +// #include "../core/fwd.hpp" +#ifndef ENTT_CORE_FWD_HPP +#define ENTT_CORE_FWD_HPP + +#include +#include +// #include "../config/config.h" + + +namespace entt { + +/*! @brief Possible modes of an any object. */ +enum class any_policy : std::uint8_t { + /*! @brief Default mode, no element available. */ + empty, + /*! @brief Owning mode, dynamically allocated element. */ + dynamic, + /*! @brief Owning mode, embedded element. */ + embedded, + /*! @brief Aliasing mode, non-const reference. */ + ref, + /*! @brief Const aliasing mode, const reference. */ + cref +}; + +// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) +template +class basic_any; + +/*! @brief Alias declaration for type identifiers. */ +using id_type = ENTT_ID_TYPE; + +/*! @brief Alias declaration for the most common use case. */ +using any = basic_any<>; + +template +class compressed_pair; + +template +class basic_hashed_string; + +/*! @brief Aliases for common character types. */ +using hashed_string = basic_hashed_string; + +/*! @brief Aliases for common character types. */ +using hashed_wstring = basic_hashed_string; + +// NOLINTNEXTLINE(bugprone-forward-declaration-namespace) +struct type_info; + +} // namespace entt + +#endif + +// #include "../core/type_info.hpp" +#ifndef ENTT_CORE_TYPE_INFO_HPP +#define ENTT_CORE_TYPE_INFO_HPP + +#include +#include +#include +// #include "../config/config.h" + +// #include "fwd.hpp" + +// #include "hashed_string.hpp" +#ifndef ENTT_CORE_HASHED_STRING_HPP +#define ENTT_CORE_HASHED_STRING_HPP + +#include +#include +// #include "fwd.hpp" + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct fnv_1a_params; + +template<> +struct fnv_1a_params { + static constexpr auto offset = 2166136261; + static constexpr auto prime = 16777619; +}; + +template<> +struct fnv_1a_params { + static constexpr auto offset = 14695981039346656037ull; + static constexpr auto prime = 1099511628211ull; +}; + +template +struct basic_hashed_string { + using value_type = Char; + using size_type = std::size_t; + using hash_type = id_type; + + const value_type *repr{}; + hash_type hash{fnv_1a_params<>::offset}; + size_type length{}; +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Zero overhead unique identifier. + * + * A hashed string is a compile-time tool that allows users to use + * human-readable identifiers in the codebase while using their numeric + * counterparts at runtime.
+ * Because of that, a hashed string can also be used in constant expressions if + * required. + * + * @warning + * This class doesn't take ownership of user-supplied strings nor does it make a + * copy of them. + * + * @tparam Char Character type. + */ +template +class basic_hashed_string: internal::basic_hashed_string { + using base_type = internal::basic_hashed_string; + using params = internal::fnv_1a_params<>; + + struct const_wrapper { + // non-explicit constructor on purpose + constexpr const_wrapper(const typename base_type::value_type *str) noexcept + : repr{str} {} + + const typename base_type::value_type *repr; + }; + +public: + /*! @brief Character type. */ + using value_type = typename base_type::value_type; + /*! @brief Unsigned integer type. */ + using size_type = typename base_type::size_type; + /*! @brief Unsigned integer type. */ + using hash_type = typename base_type::hash_type; + + /** + * @brief Returns directly the numeric representation of a string view. + * @param str Human-readable identifier. + * @param len Length of the string to hash. + * @return The numeric representation of the string. + */ + [[nodiscard]] static constexpr hash_type value(const value_type *str, const size_type len) noexcept { + return basic_hashed_string{str, len}; + } + + /** + * @brief Returns directly the numeric representation of a string. + * @tparam N Number of characters of the identifier. + * @param str Human-readable identifier. + * @return The numeric representation of the string. + */ + template + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) + [[nodiscard]] static ENTT_CONSTEVAL hash_type value(const value_type (&str)[N]) noexcept { + return basic_hashed_string{str}; + } + + /** + * @brief Returns directly the numeric representation of a string. + * @param wrapper Helps achieving the purpose by relying on overloading. + * @return The numeric representation of the string. + */ + [[nodiscard]] static constexpr hash_type value(const_wrapper wrapper) noexcept { + return basic_hashed_string{wrapper}; + } + + /*! @brief Constructs an empty hashed string. */ + constexpr basic_hashed_string() noexcept + : basic_hashed_string{nullptr, 0u} {} + + /** + * @brief Constructs a hashed string from a string view. + * @param str Human-readable identifier. + * @param len Length of the string to hash. + */ + constexpr basic_hashed_string(const value_type *str, const size_type len) noexcept + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay) + : base_type{str} { + // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic) + for(; base_type::length < len; ++base_type::length) { + base_type::hash = (base_type::hash ^ static_cast(str[base_type::length])) * params::prime; + } + // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic) + } + + /** + * @brief Constructs a hashed string from an array of const characters. + * @tparam N Number of characters of the identifier. + * @param str Human-readable identifier. + */ + template + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) + ENTT_CONSTEVAL basic_hashed_string(const value_type (&str)[N]) noexcept + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay) + : base_type{str} { + for(; str[base_type::length]; ++base_type::length) { + base_type::hash = (base_type::hash ^ static_cast(str[base_type::length])) * params::prime; + } + } + + /** + * @brief Explicit constructor on purpose to avoid constructing a hashed + * string directly from a `const value_type *`. + * + * @warning + * The lifetime of the string is not extended nor is it copied. + * + * @param wrapper Helps achieving the purpose by relying on overloading. + */ + explicit constexpr basic_hashed_string(const_wrapper wrapper) noexcept + : base_type{wrapper.repr} { + // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic) + for(; wrapper.repr[base_type::length]; ++base_type::length) { + base_type::hash = (base_type::hash ^ static_cast(wrapper.repr[base_type::length])) * params::prime; + } + // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic) + } + + /** + * @brief Returns the size of a hashed string. + * @return The size of the hashed string. + */ + [[nodiscard]] constexpr size_type size() const noexcept { + return base_type::length; + } + + /** + * @brief Returns the human-readable representation of a hashed string. + * @return The string used to initialize the hashed string. + */ + [[nodiscard]] constexpr const value_type *data() const noexcept { + return base_type::repr; + } + + /** + * @brief Returns the numeric representation of a hashed string. + * @return The numeric representation of the hashed string. + */ + [[nodiscard]] constexpr hash_type value() const noexcept { + return base_type::hash; + } + + /*! @copydoc data */ + [[nodiscard]] explicit constexpr operator const value_type *() const noexcept { + return data(); + } + + /** + * @brief Returns the numeric representation of a hashed string. + * @return The numeric representation of the hashed string. + */ + [[nodiscard]] constexpr operator hash_type() const noexcept { + return value(); + } +}; + +/** + * @brief Deduction guide. + * @tparam Char Character type. + * @param str Human-readable identifier. + * @param len Length of the string to hash. + */ +template +basic_hashed_string(const Char *str, std::size_t len) -> basic_hashed_string; + +/** + * @brief Deduction guide. + * @tparam Char Character type. + * @tparam N Number of characters of the identifier. + * @param str Human-readable identifier. + */ +template +// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) +basic_hashed_string(const Char (&str)[N]) -> basic_hashed_string; + +/** + * @brief Compares two hashed strings. + * @tparam Char Character type. + * @param lhs A valid hashed string. + * @param rhs A valid hashed string. + * @return True if the two hashed strings are identical, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator==(const basic_hashed_string &lhs, const basic_hashed_string &rhs) noexcept { + return lhs.value() == rhs.value(); +} + +/** + * @brief Compares two hashed strings. + * @tparam Char Character type. + * @param lhs A valid hashed string. + * @param rhs A valid hashed string. + * @return True if the two hashed strings differ, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator!=(const basic_hashed_string &lhs, const basic_hashed_string &rhs) noexcept { + return !(lhs == rhs); +} + +/** + * @brief Compares two hashed strings. + * @tparam Char Character type. + * @param lhs A valid hashed string. + * @param rhs A valid hashed string. + * @return True if the first element is less than the second, false otherwise. + */ +template +[[nodiscard]] constexpr bool operator<(const basic_hashed_string &lhs, const basic_hashed_string &rhs) noexcept { + return lhs.value() < rhs.value(); +} + +/** + * @brief Compares two hashed strings. + * @tparam Char Character type. + * @param lhs A valid hashed string. + * @param rhs A valid hashed string. + * @return True if the first element is less than or equal to the second, false + * otherwise. + */ +template +[[nodiscard]] constexpr bool operator<=(const basic_hashed_string &lhs, const basic_hashed_string &rhs) noexcept { + return !(rhs < lhs); +} + +/** + * @brief Compares two hashed strings. + * @tparam Char Character type. + * @param lhs A valid hashed string. + * @param rhs A valid hashed string. + * @return True if the first element is greater than the second, false + * otherwise. + */ +template +[[nodiscard]] constexpr bool operator>(const basic_hashed_string &lhs, const basic_hashed_string &rhs) noexcept { + return rhs < lhs; +} + +/** + * @brief Compares two hashed strings. + * @tparam Char Character type. + * @param lhs A valid hashed string. + * @param rhs A valid hashed string. + * @return True if the first element is greater than or equal to the second, + * false otherwise. + */ +template +[[nodiscard]] constexpr bool operator>=(const basic_hashed_string &lhs, const basic_hashed_string &rhs) noexcept { + return !(lhs < rhs); +} + +inline namespace literals { + +/** + * @brief User defined literal for hashed strings. + * @param str The literal without its suffix. + * @return A properly initialized hashed string. + */ +[[nodiscard]] ENTT_CONSTEVAL hashed_string operator""_hs(const char *str, std::size_t) noexcept { + return hashed_string{str}; +} + +/** + * @brief User defined literal for hashed wstrings. + * @param str The literal without its suffix. + * @return A properly initialized hashed wstring. + */ +[[nodiscard]] ENTT_CONSTEVAL hashed_wstring operator""_hws(const wchar_t *str, std::size_t) noexcept { + return hashed_wstring{str}; +} + +} // namespace literals + +} // namespace entt + +#endif + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +struct ENTT_API type_index final { + [[nodiscard]] static id_type next() noexcept { + static ENTT_MAYBE_ATOMIC(id_type) value{}; + return value++; + } +}; + +template +[[nodiscard]] constexpr const char *pretty_function() noexcept { +#if defined ENTT_PRETTY_FUNCTION + return static_cast(ENTT_PRETTY_FUNCTION); +#else + return ""; +#endif +} + +template +[[nodiscard]] constexpr auto stripped_type_name() noexcept { +#if defined ENTT_PRETTY_FUNCTION + const std::string_view full_name{pretty_function()}; + auto first = full_name.find_first_not_of(' ', full_name.find_first_of(ENTT_PRETTY_FUNCTION_PREFIX) + 1); + auto value = full_name.substr(first, full_name.find_last_of(ENTT_PRETTY_FUNCTION_SUFFIX) - first); + return value; +#else + return std::string_view{}; +#endif +} + +template().find_first_of('.')> +[[nodiscard]] constexpr std::string_view type_name(int) noexcept { + constexpr auto value = stripped_type_name(); + return value; +} + +template +[[nodiscard]] std::string_view type_name(char) noexcept { + static const auto value = stripped_type_name(); + return value; +} + +template().find_first_of('.')> +[[nodiscard]] constexpr id_type type_hash(int) noexcept { + constexpr auto stripped = stripped_type_name(); + constexpr auto value = hashed_string::value(stripped.data(), stripped.size()); + return value; +} + +template +[[nodiscard]] id_type type_hash(char) noexcept { + static const auto value = [](const auto stripped) { + return hashed_string::value(stripped.data(), stripped.size()); + }(stripped_type_name()); + return value; +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Type sequential identifier. + * @tparam Type Type for which to generate a sequential identifier. + */ +template +struct ENTT_API type_index final { + /** + * @brief Returns the sequential identifier of a given type. + * @return The sequential identifier of a given type. + */ + [[nodiscard]] static id_type value() noexcept { + static const id_type value = internal::type_index::next(); + return value; + } + + /*! @copydoc value */ + [[nodiscard]] constexpr operator id_type() const noexcept { + return value(); + } +}; + +/** + * @brief Type hash. + * @tparam Type Type for which to generate a hash value. + */ +template +struct type_hash final { + /** + * @brief Returns the numeric representation of a given type. + * @return The numeric representation of the given type. + */ +#if defined ENTT_PRETTY_FUNCTION + [[nodiscard]] static constexpr id_type value() noexcept { + return internal::type_hash(0); +#else + [[nodiscard]] static constexpr id_type value() noexcept { + return type_index::value(); +#endif + } + + /*! @copydoc value */ + [[nodiscard]] constexpr operator id_type() const noexcept { + return value(); + } +}; + +/** + * @brief Type name. + * @tparam Type Type for which to generate a name. + */ +template +struct type_name final { + /** + * @brief Returns the name of a given type. + * @return The name of the given type. + */ + [[nodiscard]] static constexpr std::string_view value() noexcept { + return internal::type_name(0); + } + + /*! @copydoc value */ + [[nodiscard]] constexpr operator std::string_view() const noexcept { + return value(); + } +}; + +/*! @brief Implementation specific information about a type. */ +struct type_info final { + /** + * @brief Constructs a type info object for a given type. + * @tparam Type Type for which to construct a type info object. + */ + template + // NOLINTBEGIN(modernize-use-transparent-functors) + constexpr type_info(std::in_place_type_t) noexcept + : seq{type_index>>::value()}, + identifier{type_hash>>::value()}, + alias{type_name>>::value()} {} + // NOLINTEND(modernize-use-transparent-functors) + + /** + * @brief Type index. + * @return Type index. + */ + [[nodiscard]] constexpr id_type index() const noexcept { + return seq; + } + + /** + * @brief Type hash. + * @return Type hash. + */ + [[nodiscard]] constexpr id_type hash() const noexcept { + return identifier; + } + + /** + * @brief Type name. + * @return Type name. + */ + [[nodiscard]] constexpr std::string_view name() const noexcept { + return alias; + } + +private: + id_type seq; + id_type identifier; + std::string_view alias; +}; + +/** + * @brief Compares the contents of two type info objects. + * @param lhs A type info object. + * @param rhs A type info object. + * @return True if the two type info objects are identical, false otherwise. + */ +[[nodiscard]] constexpr bool operator==(const type_info &lhs, const type_info &rhs) noexcept { + return lhs.hash() == rhs.hash(); +} + +/** + * @brief Compares the contents of two type info objects. + * @param lhs A type info object. + * @param rhs A type info object. + * @return True if the two type info objects differ, false otherwise. + */ +[[nodiscard]] constexpr bool operator!=(const type_info &lhs, const type_info &rhs) noexcept { + return !(lhs == rhs); +} + +/** + * @brief Compares two type info objects. + * @param lhs A valid type info object. + * @param rhs A valid type info object. + * @return True if the first element is less than the second, false otherwise. + */ +[[nodiscard]] constexpr bool operator<(const type_info &lhs, const type_info &rhs) noexcept { + return lhs.index() < rhs.index(); +} + +/** + * @brief Compares two type info objects. + * @param lhs A valid type info object. + * @param rhs A valid type info object. + * @return True if the first element is less than or equal to the second, false + * otherwise. + */ +[[nodiscard]] constexpr bool operator<=(const type_info &lhs, const type_info &rhs) noexcept { + return !(rhs < lhs); +} + +/** + * @brief Compares two type info objects. + * @param lhs A valid type info object. + * @param rhs A valid type info object. + * @return True if the first element is greater than the second, false + * otherwise. + */ +[[nodiscard]] constexpr bool operator>(const type_info &lhs, const type_info &rhs) noexcept { + return rhs < lhs; +} + +/** + * @brief Compares two type info objects. + * @param lhs A valid type info object. + * @param rhs A valid type info object. + * @return True if the first element is greater than or equal to the second, + * false otherwise. + */ +[[nodiscard]] constexpr bool operator>=(const type_info &lhs, const type_info &rhs) noexcept { + return !(lhs < rhs); +} + +/** + * @brief Returns the type info object associated to a given type. + * + * The returned element refers to an object with static storage duration.
+ * The type doesn't need to be a complete type. If the type is a reference, the + * result refers to the referenced type. In all cases, top-level cv-qualifiers + * are ignored. + * + * @tparam Type Type for which to generate a type info object. + * @return A reference to a properly initialized type info object. + */ +template +[[nodiscard]] const type_info &type_id() noexcept { + if constexpr(std::is_same_v>>) { + static const type_info instance{std::in_place_type}; + return instance; + } else { + return type_id>>(); + } +} + +/*! @copydoc type_id */ +template +// NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward) +[[nodiscard]] const type_info &type_id(Type &&) noexcept { + return type_id>>(); +} + +} // namespace entt + +#endif + +// #include "../core/utility.hpp" +#ifndef ENTT_CORE_UTILITY_HPP +#define ENTT_CORE_UTILITY_HPP + +#include +#include + +namespace entt { + +/*! @brief Identity function object (waiting for C++20). */ +struct identity { + /*! @brief Indicates that this is a transparent function object. */ + using is_transparent = void; + + /** + * @brief Returns its argument unchanged. + * @tparam Type Type of the argument. + * @param value The actual argument. + * @return The submitted value as-is. + */ + template + [[nodiscard]] constexpr Type &&operator()(Type &&value) const noexcept { + return std::forward(value); + } +}; + +/** + * @brief Constant utility to disambiguate overloaded members of a class. + * @tparam Type Type of the desired overload. + * @tparam Class Type of class to which the member belongs. + * @param member A valid pointer to a member. + * @return Pointer to the member. + */ +template +[[nodiscard]] constexpr auto overload(Type Class::*member) noexcept { + return member; +} + +/** + * @brief Constant utility to disambiguate overloaded functions. + * @tparam Func Function type of the desired overload. + * @param func A valid pointer to a function. + * @return Pointer to the function. + */ +template +[[nodiscard]] constexpr auto overload(Func *func) noexcept { + return func; +} + +/** + * @brief Helper type for visitors. + * @tparam Func Types of function objects. + */ +template +struct overloaded: Func... { + using Func::operator()...; +}; + +/** + * @brief Deduction guide. + * @tparam Func Types of function objects. + */ +template +overloaded(Func...) -> overloaded; + +/** + * @brief Basic implementation of a y-combinator. + * @tparam Func Type of a potentially recursive function. + */ +template +struct y_combinator { + /** + * @brief Constructs a y-combinator from a given function. + * @param recursive A potentially recursive function. + */ + constexpr y_combinator(Func recursive) noexcept(std::is_nothrow_move_constructible_v) + : func{std::move(recursive)} {} + + /** + * @brief Invokes a y-combinator and therefore its underlying function. + * @tparam Args Types of arguments to use to invoke the underlying function. + * @param args Parameters to use to invoke the underlying function. + * @return Return value of the underlying function, if any. + */ + template + constexpr decltype(auto) operator()(Args &&...args) const noexcept(std::is_nothrow_invocable_v) { + return func(*this, std::forward(args)...); + } + + /*! @copydoc operator()() */ + template + constexpr decltype(auto) operator()(Args &&...args) noexcept(std::is_nothrow_invocable_v) { + return func(*this, std::forward(args)...); + } + +private: + Func func; +}; + +} // namespace entt + +#endif + +// #include "fwd.hpp" + +// #include "sigh.hpp" +#ifndef ENTT_SIGNAL_SIGH_HPP +#define ENTT_SIGNAL_SIGH_HPP + +#include +#include +#include +#include +#include +// #include "delegate.hpp" +#ifndef ENTT_SIGNAL_DELEGATE_HPP +#define ENTT_SIGNAL_DELEGATE_HPP + +#include +#include +#include +#include +#include +// #include "../config/config.h" + +// #include "../core/type_traits.hpp" + +// #include "fwd.hpp" + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +constexpr auto function_pointer(Ret (*)(Args...)) -> Ret (*)(Args...); + +template +constexpr auto function_pointer(Ret (*)(Type, Args...), Other &&) -> Ret (*)(Args...); + +template +constexpr auto function_pointer(Ret (Class::*)(Args...), Other &&...) -> Ret (*)(Args...); + +template +constexpr auto function_pointer(Ret (Class::*)(Args...) const, Other &&...) -> Ret (*)(Args...); + +template>> +constexpr auto function_pointer(Type Class::*, Other &&...) -> Type (*)(); + +template +using function_pointer_t = decltype(function_pointer(std::declval()...)); + +template +[[nodiscard]] constexpr auto index_sequence_for(Ret (*)(Args...)) { + return std::index_sequence_for{}; +} + +} // namespace internal +/*! @endcond */ + +/** + * @brief Basic delegate implementation. + * + * Primary template isn't defined on purpose. All the specializations give a + * compile-time error unless the template parameter is a function type. + */ +template +class delegate; + +/** + * @brief Utility class to use to send around functions and members. + * + * Unmanaged delegate for function pointers and members. Users of this class are + * in charge of disconnecting instances before deleting them. + * + * A delegate can be used as a general purpose invoker without memory overhead + * for free functions possibly with payloads and bound or unbound members. + * + * @tparam Ret Return type of a function type. + * @tparam Args Types of arguments of a function type. + */ +template +class delegate { + using return_type = std::remove_const_t; + using delegate_type = return_type(const void *, Args...); + + template + [[nodiscard]] auto wrap(std::index_sequence) noexcept { + return [](const void *, Args... args) -> return_type { + [[maybe_unused]] const auto arguments = std::forward_as_tuple(std::forward(args)...); + [[maybe_unused]] constexpr auto offset = !std::is_invocable_r_v>...> * (sizeof...(Args) - sizeof...(Index)); + return static_cast(std::invoke(Candidate, std::forward>>(std::get(arguments))...)); + }; + } + + template + [[nodiscard]] auto wrap(Type &, std::index_sequence) noexcept { + return [](const void *payload, Args... args) -> return_type { + Type *curr = static_cast(const_cast *>(payload)); + [[maybe_unused]] const auto arguments = std::forward_as_tuple(std::forward(args)...); + [[maybe_unused]] constexpr auto offset = !std::is_invocable_r_v>...> * (sizeof...(Args) - sizeof...(Index)); + return static_cast(std::invoke(Candidate, *curr, std::forward>>(std::get(arguments))...)); + }; + } + + template + [[nodiscard]] auto wrap(Type *, std::index_sequence) noexcept { + return [](const void *payload, Args... args) -> return_type { + Type *curr = static_cast(const_cast *>(payload)); + [[maybe_unused]] const auto arguments = std::forward_as_tuple(std::forward(args)...); + [[maybe_unused]] constexpr auto offset = !std::is_invocable_r_v>...> * (sizeof...(Args) - sizeof...(Index)); + return static_cast(std::invoke(Candidate, curr, std::forward>>(std::get(arguments))...)); + }; + } + +public: + /*! @brief Function type of the contained target. */ + using function_type = Ret(const void *, Args...); + /*! @brief Function type of the delegate. */ + using type = Ret(Args...); + /*! @brief Return type of the delegate. */ + using result_type = Ret; + + /*! @brief Default constructor. */ + delegate() noexcept = default; + + /** + * @brief Constructs a delegate with a given object or payload, if any. + * @tparam Candidate Function or member to connect to the delegate. + * @tparam Type Type of class or type of payload, if any. + * @param value_or_instance Optional valid object that fits the purpose. + */ + template + delegate(connect_arg_t, Type &&...value_or_instance) noexcept { + connect(std::forward(value_or_instance)...); + } + + /** + * @brief Constructs a delegate and connects an user defined function with + * optional payload. + * @param function Function to connect to the delegate. + * @param payload User defined arbitrary data. + */ + delegate(function_type *function, const void *payload = nullptr) noexcept { + connect(function, payload); + } + + /** + * @brief Connects a free function or an unbound member to a delegate. + * @tparam Candidate Function or member to connect to the delegate. + */ + template + void connect() noexcept { + instance = nullptr; + + if constexpr(std::is_invocable_r_v) { + fn = [](const void *, Args... args) -> return_type { + return Ret(std::invoke(Candidate, std::forward(args)...)); + }; + } else if constexpr(std::is_member_pointer_v) { + fn = wrap(internal::index_sequence_for>>(internal::function_pointer_t{})); + } else { + fn = wrap(internal::index_sequence_for(internal::function_pointer_t{})); + } + } + + /** + * @brief Connects a free function with payload or a bound member to a + * delegate. + * + * The delegate isn't responsible for the connected object or the payload. + * Users must always guarantee that the lifetime of the instance overcomes + * the one of the delegate.
+ * When used to connect a free function with payload, its signature must be + * such that the instance is the first argument before the ones used to + * define the delegate itself. + * + * @tparam Candidate Function or member to connect to the delegate. + * @tparam Type Type of class or type of payload. + * @param value_or_instance A valid reference that fits the purpose. + */ + template + void connect(Type &value_or_instance) noexcept { + instance = &value_or_instance; + + if constexpr(std::is_invocable_r_v) { + fn = [](const void *payload, Args... args) -> return_type { + Type *curr = static_cast(const_cast *>(payload)); + return Ret(std::invoke(Candidate, *curr, std::forward(args)...)); + }; + } else { + fn = wrap(value_or_instance, internal::index_sequence_for(internal::function_pointer_t{})); + } + } + + /** + * @brief Connects a free function with payload or a bound member to a + * delegate. + * + * @sa connect(Type &) + * + * @tparam Candidate Function or member to connect to the delegate. + * @tparam Type Type of class or type of payload. + * @param value_or_instance A valid pointer that fits the purpose. + */ + template + void connect(Type *value_or_instance) noexcept { + instance = value_or_instance; + + if constexpr(std::is_invocable_r_v) { + fn = [](const void *payload, Args... args) -> return_type { + Type *curr = static_cast(const_cast *>(payload)); + return Ret(std::invoke(Candidate, curr, std::forward(args)...)); + }; + } else { + fn = wrap(value_or_instance, internal::index_sequence_for(internal::function_pointer_t{})); + } + } + + /** + * @brief Connects an user defined function with optional payload to a + * delegate. + * + * The delegate isn't responsible for the connected object or the payload. + * Users must always guarantee that the lifetime of an instance overcomes + * the one of the delegate.
+ * The payload is returned as the first argument to the target function in + * all cases. + * + * @param function Function to connect to the delegate. + * @param payload User defined arbitrary data. + */ + void connect(function_type *function, const void *payload = nullptr) noexcept { + ENTT_ASSERT(function != nullptr, "Uninitialized function pointer"); + instance = payload; + fn = function; + } + + /** + * @brief Resets a delegate. + * + * After a reset, a delegate cannot be invoked anymore. + */ + void reset() noexcept { + instance = nullptr; + fn = nullptr; + } + + /** + * @brief Returns a pointer to the stored callable function target, if any. + * @return An opaque pointer to the stored callable function target. + */ + [[nodiscard]] function_type *target() const noexcept { + return fn; + } + + /** + * @brief Returns the instance or the payload linked to a delegate, if any. + * @return An opaque pointer to the underlying data. + */ + [[nodiscard]] const void *data() const noexcept { + return instance; + } + + /** + * @brief Triggers a delegate. + * + * The delegate invokes the underlying function and returns the result. + * + * @warning + * Attempting to trigger an invalid delegate results in undefined + * behavior. + * + * @param args Arguments to use to invoke the underlying function. + * @return The value returned by the underlying function. + */ + Ret operator()(Args... args) const { + ENTT_ASSERT(static_cast(*this), "Uninitialized delegate"); + return fn(instance, std::forward(args)...); + } + + /** + * @brief Checks whether a delegate actually stores a listener. + * @return False if the delegate is empty, true otherwise. + */ + [[nodiscard]] explicit operator bool() const noexcept { + // no need to also test instance + return !(fn == nullptr); + } + + /** + * @brief Compares the contents of two delegates. + * @param other Delegate with which to compare. + * @return False if the two contents differ, true otherwise. + */ + [[nodiscard]] bool operator==(const delegate &other) const noexcept { + return fn == other.fn && instance == other.instance; + } + +private: + const void *instance{}; + delegate_type *fn{}; +}; + +/** + * @brief Compares the contents of two delegates. + * @tparam Ret Return type of a function type. + * @tparam Args Types of arguments of a function type. + * @param lhs A valid delegate object. + * @param rhs A valid delegate object. + * @return True if the two contents differ, false otherwise. + */ +template +[[nodiscard]] bool operator!=(const delegate &lhs, const delegate &rhs) noexcept { + return !(lhs == rhs); +} + +/** + * @brief Deduction guide. + * @tparam Candidate Function or member to connect to the delegate. + */ +template +delegate(connect_arg_t) -> delegate>>; + +/** + * @brief Deduction guide. + * @tparam Candidate Function or member to connect to the delegate. + * @tparam Type Type of class or type of payload. + */ +template +delegate(connect_arg_t, Type &&) -> delegate>>; + +/** + * @brief Deduction guide. + * @tparam Ret Return type of a function type. + * @tparam Args Types of arguments of a function type. + */ +template +delegate(Ret (*)(const void *, Args...), const void * = nullptr) -> delegate; + +} // namespace entt + +#endif + +// #include "fwd.hpp" + + +namespace entt { + +/** + * @brief Sink class. + * + * Primary template isn't defined on purpose. All the specializations give a + * compile-time error unless the template parameter is a function type. + * + * @tparam Type A valid signal handler type. + */ +template +class sink; + +/** + * @brief Unmanaged signal handler. + * + * Primary template isn't defined on purpose. All the specializations give a + * compile-time error unless the template parameter is a function type. + * + * @tparam Type A valid function type. + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +class sigh; + +/** + * @brief Unmanaged signal handler. + * + * It works directly with references to classes and pointers to member functions + * as well as pointers to free functions. Users of this class are in charge of + * disconnecting instances before deleting them. + * + * This class serves mainly two purposes: + * + * * Creating signals to use later to notify a bunch of listeners. + * * Collecting results from a set of functions like in a voting system. + * + * @tparam Ret Return type of a function type. + * @tparam Args Types of arguments of a function type. + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +class sigh { + friend class sink>; + + using alloc_traits = std::allocator_traits; + using delegate_type = delegate; + using container_type = std::vector>; + +public: + /*! @brief Allocator type. */ + using allocator_type = Allocator; + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + /*! @brief Sink type. */ + using sink_type = sink>; + + /*! @brief Default constructor. */ + sigh() noexcept(noexcept(allocator_type{})) + : sigh{allocator_type{}} {} + + /** + * @brief Constructs a signal handler with a given allocator. + * @param allocator The allocator to use. + */ + explicit sigh(const allocator_type &allocator) noexcept + : calls{allocator} {} + + /** + * @brief Copy constructor. + * @param other The instance to copy from. + */ + sigh(const sigh &other) + : calls{other.calls} {} + + /** + * @brief Allocator-extended copy constructor. + * @param other The instance to copy from. + * @param allocator The allocator to use. + */ + sigh(const sigh &other, const allocator_type &allocator) + : calls{other.calls, allocator} {} + + /** + * @brief Move constructor. + * @param other The instance to move from. + */ + sigh(sigh &&other) noexcept + : calls{std::move(other.calls)} {} + + /** + * @brief Allocator-extended move constructor. + * @param other The instance to move from. + * @param allocator The allocator to use. + */ + sigh(sigh &&other, const allocator_type &allocator) + : calls{std::move(other.calls), allocator} {} + + /*! @brief Default destructor. */ + ~sigh() = default; + + /** + * @brief Copy assignment operator. + * @param other The instance to copy from. + * @return This signal handler. + */ + sigh &operator=(const sigh &other) { + calls = other.calls; + return *this; + } + + /** + * @brief Move assignment operator. + * @param other The instance to move from. + * @return This signal handler. + */ + sigh &operator=(sigh &&other) noexcept { + swap(other); + return *this; + } + + /** + * @brief Exchanges the contents with those of a given signal handler. + * @param other Signal handler to exchange the content with. + */ + void swap(sigh &other) noexcept { + using std::swap; + swap(calls, other.calls); + } + + /** + * @brief Returns the associated allocator. + * @return The associated allocator. + */ + [[nodiscard]] constexpr allocator_type get_allocator() const noexcept { + return calls.get_allocator(); + } + + /** + * @brief Number of listeners connected to the signal. + * @return Number of listeners currently connected. + */ + [[nodiscard]] size_type size() const noexcept { + return calls.size(); + } + + /** + * @brief Returns false if at least a listener is connected to the signal. + * @return True if the signal has no listeners connected, false otherwise. + */ + [[nodiscard]] bool empty() const noexcept { + return calls.empty(); + } + + /** + * @brief Triggers a signal. + * + * All the listeners are notified. Order isn't guaranteed. + * + * @param args Arguments to use to invoke listeners. + */ + void publish(Args... args) const { + for(auto pos = calls.size(); pos; --pos) { + calls[pos - 1u](args...); + } + } + + /** + * @brief Collects return values from the listeners. + * + * The collector must expose a call operator with the following properties: + * + * * The return type is either `void` or such that it's convertible to + * `bool`. In the second case, a true value will stop the iteration. + * * The list of parameters is empty if `Ret` is `void`, otherwise it + * contains a single element such that `Ret` is convertible to it. + * + * @tparam Func Type of collector to use, if any. + * @param func A valid function object. + * @param args Arguments to use to invoke listeners. + */ + template + void collect(Func func, Args... args) const { + for(auto pos = calls.size(); pos; --pos) { + if constexpr(std::is_void_v || !std::is_invocable_v) { + calls[pos - 1u](args...); + + if constexpr(std::is_invocable_r_v) { + if(func()) { + break; + } + } else { + func(); + } + } else { + if constexpr(std::is_invocable_r_v) { + if(func(calls[pos - 1u](args...))) { + break; + } + } else { + func(calls[pos - 1u](args...)); + } + } + } + } + +private: + container_type calls; +}; + +/** + * @brief Connection class. + * + * Opaque object the aim of which is to allow users to release an already + * estabilished connection without having to keep a reference to the signal or + * the sink that generated it. + */ +class connection { + template + friend class sink; + + connection(delegate fn, void *ref) + : disconnect{fn}, signal{ref} {} + +public: + /*! @brief Default constructor. */ + connection() + : signal{} {} + + /** + * @brief Checks whether a connection is properly initialized. + * @return True if the connection is properly initialized, false otherwise. + */ + [[nodiscard]] explicit operator bool() const noexcept { + return static_cast(disconnect); + } + + /*! @brief Breaks the connection. */ + void release() { + if(disconnect) { + disconnect(signal); + disconnect.reset(); + } + } + +private: + delegate disconnect; + void *signal; +}; + +/** + * @brief Scoped connection class. + * + * Opaque object the aim of which is to allow users to release an already + * estabilished connection without having to keep a reference to the signal or + * the sink that generated it.
+ * A scoped connection automatically breaks the link between the two objects + * when it goes out of scope. + */ +struct scoped_connection { + /*! @brief Default constructor. */ + scoped_connection() = default; + + /** + * @brief Constructs a scoped connection from a basic connection. + * @param other A valid connection object. + */ + scoped_connection(const connection &other) + : conn{other} {} + + /*! @brief Default copy constructor, deleted on purpose. */ + scoped_connection(const scoped_connection &) = delete; + + /** + * @brief Move constructor. + * @param other The scoped connection to move from. + */ + scoped_connection(scoped_connection &&other) noexcept + : conn{std::exchange(other.conn, {})} {} + + /*! @brief Automatically breaks the link on destruction. */ + ~scoped_connection() { + conn.release(); + } + + /** + * @brief Default copy assignment operator, deleted on purpose. + * @return This scoped connection. + */ + scoped_connection &operator=(const scoped_connection &) = delete; + + /** + * @brief Move assignment operator. + * @param other The scoped connection to move from. + * @return This scoped connection. + */ + scoped_connection &operator=(scoped_connection &&other) noexcept { + conn = std::exchange(other.conn, {}); + return *this; + } + + /** + * @brief Acquires a connection. + * @param other The connection object to acquire. + * @return This scoped connection. + */ + scoped_connection &operator=(connection other) { + conn = other; + return *this; + } + + /** + * @brief Checks whether a scoped connection is properly initialized. + * @return True if the connection is properly initialized, false otherwise. + */ + [[nodiscard]] explicit operator bool() const noexcept { + return static_cast(conn); + } + + /*! @brief Breaks the connection. */ + void release() { + conn.release(); + } + +private: + connection conn; +}; + +/** + * @brief Sink class. + * + * A sink is used to connect listeners to signals and to disconnect them.
+ * The function type for a listener is the one of the signal to which it + * belongs. + * + * The clear separation between a signal and a sink permits to store the former + * as private data member without exposing the publish functionality to the + * users of the class. + * + * @warning + * Lifetime of a sink must not overcome that of the signal to which it refers. + * In any other case, attempting to use a sink results in undefined behavior. + * + * @tparam Ret Return type of a function type. + * @tparam Args Types of arguments of a function type. + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +class sink> { + using signal_type = sigh; + using delegate_type = typename signal_type::delegate_type; + using difference_type = typename signal_type::container_type::difference_type; + + template + static void release(Type value_or_instance, void *signal) { + sink{*static_cast(signal)}.disconnect(value_or_instance); + } + + template + static void release(void *signal) { + sink{*static_cast(signal)}.disconnect(); + } + + template + void disconnect_if(Func callback) { + auto &ref = signal_or_assert(); + + for(auto pos = ref.calls.size(); pos; --pos) { + if(auto &elem = ref.calls[pos - 1u]; callback(elem)) { + elem = std::move(ref.calls.back()); + ref.calls.pop_back(); + } + } + } + + [[nodiscard]] auto &signal_or_assert() const noexcept { + ENTT_ASSERT(signal != nullptr, "Invalid pointer to signal"); + return *signal; + } + +public: + /*! @brief Constructs an invalid sink. */ + sink() noexcept + : signal{} {} + + /** + * @brief Constructs a sink that is allowed to modify a given signal. + * @param ref A valid reference to a signal object. + */ + sink(sigh &ref) noexcept + : signal{&ref} {} + + /** + * @brief Returns false if at least a listener is connected to the sink. + * @return True if the sink has no listeners connected, false otherwise. + */ + [[nodiscard]] bool empty() const noexcept { + return signal_or_assert().calls.empty(); + } + + /** + * @brief Connects a free function or an unbound member to a signal. + * @tparam Candidate Function or member to connect to the signal. + * @return A properly initialized connection object. + */ + template + connection connect() { + disconnect(); + + delegate_type call{}; + call.template connect(); + signal_or_assert().calls.push_back(std::move(call)); + + delegate conn{}; + conn.template connect<&release>(); + return {conn, signal}; + } + + /** + * @brief Connects a free function with payload or a bound member to a + * signal. + * + * The signal isn't responsible for the connected object or the payload. + * Users must always guarantee that the lifetime of the instance overcomes + * the one of the signal.
+ * When used to connect a free function with payload, its signature must be + * such that the instance is the first argument before the ones used to + * define the signal itself. + * + * @tparam Candidate Function or member to connect to the signal. + * @tparam Type Type of class or type of payload. + * @param value_or_instance A valid reference that fits the purpose. + * @return A properly initialized connection object. + */ + template + connection connect(Type &value_or_instance) { + disconnect(value_or_instance); + + delegate_type call{}; + call.template connect(value_or_instance); + signal_or_assert().calls.push_back(std::move(call)); + + delegate conn{}; + conn.template connect<&release>(value_or_instance); + return {conn, signal}; + } + + /** + * @brief Connects a free function with payload or a bound member to a + * signal. + * + * @sa connect(Type &) + * + * @tparam Candidate Function or member to connect to the signal. + * @tparam Type Type of class or type of payload. + * @param value_or_instance A valid pointer that fits the purpose. + * @return A properly initialized connection object. + */ + template + connection connect(Type *value_or_instance) { + disconnect(value_or_instance); + + delegate_type call{}; + call.template connect(value_or_instance); + signal_or_assert().calls.push_back(std::move(call)); + + delegate conn{}; + conn.template connect<&release>(value_or_instance); + return {conn, signal}; + } + + /** + * @brief Disconnects a free function or an unbound member from a signal. + * @tparam Candidate Function or member to disconnect from the signal. + */ + template + void disconnect() { + delegate_type call{}; + call.template connect(); + disconnect_if([&call](const auto &elem) { return elem == call; }); + } + + /** + * @brief Disconnects a free function with payload or a bound member from a + * signal. + * + * The signal isn't responsible for the connected object or the payload. + * Users must always guarantee that the lifetime of the instance overcomes + * the one of the signal.
+ * When used to connect a free function with payload, its signature must be + * such that the instance is the first argument before the ones used to + * define the signal itself. + * + * @tparam Candidate Function or member to disconnect from the signal. + * @tparam Type Type of class or type of payload, if any. + * @param value_or_instance A valid reference that fits the purpose. + */ + template + void disconnect(Type &value_or_instance) { + delegate_type call{}; + call.template connect(value_or_instance); + disconnect_if([&call](const auto &elem) { return elem == call; }); + } + + /** + * @brief Disconnects a free function with payload or a bound member from a + * signal. + * + * @sa disconnect(Type &) + * + * @tparam Candidate Function or member to disconnect from the signal. + * @tparam Type Type of class or type of payload, if any. + * @param value_or_instance A valid pointer that fits the purpose. + */ + template + void disconnect(Type *value_or_instance) { + delegate_type call{}; + call.template connect(value_or_instance); + disconnect_if([&call](const auto &elem) { return elem == call; }); + } + + /** + * @brief Disconnects free functions with payload or bound members from a + * signal. + * @param value_or_instance A valid object that fits the purpose. + */ + void disconnect(const void *value_or_instance) { + ENTT_ASSERT(value_or_instance != nullptr, "Invalid value or instance"); + disconnect_if([value_or_instance](const auto &elem) { return elem.data() == value_or_instance; }); + } + + /*! @brief Disconnects all the listeners from a signal. */ + void disconnect() { + signal_or_assert().calls.clear(); + } + + /** + * @brief Returns true if a sink is correctly initialized, false otherwise. + * @return True if a sink is correctly initialized, false otherwise. + */ + [[nodiscard]] explicit operator bool() const noexcept { + return signal != nullptr; + } + +private: + signal_type *signal; +}; + +/** + * @brief Deduction guide. + * + * It allows to deduce the signal handler type of a sink directly from the + * signal it refers to. + * + * @tparam Ret Return type of a function type. + * @tparam Args Types of arguments of a function type. + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +sink(sigh &) -> sink>; + +} // namespace entt + +#endif + + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +struct basic_dispatcher_handler { + virtual ~basic_dispatcher_handler() = default; + virtual void publish() = 0; + virtual void disconnect(void *) = 0; + virtual void clear() noexcept = 0; + [[nodiscard]] virtual std::size_t size() const noexcept = 0; +}; + +template +class dispatcher_handler final: public basic_dispatcher_handler { + static_assert(std::is_same_v>, "Invalid type"); + + using alloc_traits = std::allocator_traits; + using signal_type = sigh; + using container_type = std::vector>; + +public: + using allocator_type = Allocator; + + dispatcher_handler(const allocator_type &allocator) + : signal{allocator}, + events{allocator} {} + + void publish() override { + const auto length = events.size(); + + for(std::size_t pos{}; pos < length; ++pos) { + signal.publish(events[pos]); + } + + events.erase(events.cbegin(), events.cbegin() + static_cast(length)); + } + + void disconnect(void *instance) override { + bucket().disconnect(instance); + } + + void clear() noexcept override { + events.clear(); + } + + [[nodiscard]] auto bucket() noexcept { + return typename signal_type::sink_type{signal}; + } + + void trigger(Type event) { + signal.publish(event); + } + + template + void enqueue(Args &&...args) { + if constexpr(std::is_aggregate_v && (sizeof...(Args) != 0u || !std::is_default_constructible_v)) { + events.push_back(Type{std::forward(args)...}); + } else { + events.emplace_back(std::forward(args)...); + } + } + + [[nodiscard]] std::size_t size() const noexcept override { + return events.size(); + } + +private: + signal_type signal; + container_type events; +}; + +} // namespace internal +/*! @endcond */ + +/** + * @brief Basic dispatcher implementation. + * + * A dispatcher can be used either to trigger an immediate event or to enqueue + * events to be published all together once per tick.
+ * Listeners are provided in the form of member functions. For each event of + * type `Type`, listeners are such that they can be invoked with an argument of + * type `Type &`, no matter what the return type is. + * + * The dispatcher creates instances of the `sigh` class internally. Refer to the + * documentation of the latter for more details. + * + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +class basic_dispatcher { + template + using handler_type = internal::dispatcher_handler; + + using key_type = id_type; + // std::shared_ptr because of its type erased allocator which is useful here + using mapped_type = std::shared_ptr; + + using alloc_traits = std::allocator_traits; + using container_allocator = typename alloc_traits::template rebind_alloc>; + using container_type = dense_map, container_allocator>; + + template + [[nodiscard]] handler_type &assure(const id_type id) { + static_assert(std::is_same_v>, "Non-decayed types not allowed"); + auto &&ptr = pools.first()[id]; + + if(!ptr) { + const auto &allocator = get_allocator(); + ptr = std::allocate_shared>(allocator, allocator); + } + + return static_cast &>(*ptr); + } + + template + [[nodiscard]] const handler_type *assure(const id_type id) const { + static_assert(std::is_same_v>, "Non-decayed types not allowed"); + + if(auto it = pools.first().find(id); it != pools.first().cend()) { + return static_cast *>(it->second.get()); + } + + return nullptr; + } + +public: + /*! @brief Allocator type. */ + using allocator_type = Allocator; + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + + /*! @brief Default constructor. */ + basic_dispatcher() + : basic_dispatcher{allocator_type{}} {} + + /** + * @brief Constructs a dispatcher with a given allocator. + * @param allocator The allocator to use. + */ + explicit basic_dispatcher(const allocator_type &allocator) + : pools{allocator, allocator} {} + + /*! @brief Default copy constructor, deleted on purpose. */ + basic_dispatcher(const basic_dispatcher &) = delete; + + /** + * @brief Move constructor. + * @param other The instance to move from. + */ + basic_dispatcher(basic_dispatcher &&other) noexcept + : pools{std::move(other.pools)} {} + + /** + * @brief Allocator-extended move constructor. + * @param other The instance to move from. + * @param allocator The allocator to use. + */ + basic_dispatcher(basic_dispatcher &&other, const allocator_type &allocator) + : pools{container_type{std::move(other.pools.first()), allocator}, allocator} { + ENTT_ASSERT(alloc_traits::is_always_equal::value || get_allocator() == other.get_allocator(), "Copying a dispatcher is not allowed"); + } + + /*! @brief Default destructor. */ + ~basic_dispatcher() = default; + + /** + * @brief Default copy assignment operator, deleted on purpose. + * @return This dispatcher. + */ + basic_dispatcher &operator=(const basic_dispatcher &) = delete; + + /** + * @brief Move assignment operator. + * @param other The instance to move from. + * @return This dispatcher. + */ + basic_dispatcher &operator=(basic_dispatcher &&other) noexcept { + ENTT_ASSERT(alloc_traits::is_always_equal::value || get_allocator() == other.get_allocator(), "Copying a dispatcher is not allowed"); + swap(other); + return *this; + } + + /** + * @brief Exchanges the contents with those of a given dispatcher. + * @param other Dispatcher to exchange the content with. + */ + void swap(basic_dispatcher &other) noexcept { + using std::swap; + swap(pools, other.pools); + } + + /** + * @brief Returns the associated allocator. + * @return The associated allocator. + */ + [[nodiscard]] constexpr allocator_type get_allocator() const noexcept { + return pools.second(); + } + + /** + * @brief Returns the number of pending events for a given type. + * @tparam Type Type of event for which to return the count. + * @param id Name used to map the event queue within the dispatcher. + * @return The number of pending events for the given type. + */ + template + [[nodiscard]] size_type size(const id_type id = type_hash::value()) const noexcept { + const auto *cpool = assure>(id); + return cpool ? cpool->size() : 0u; + } + + /** + * @brief Returns the total number of pending events. + * @return The total number of pending events. + */ + [[nodiscard]] size_type size() const noexcept { + size_type count{}; + + for(auto &&cpool: pools.first()) { + count += cpool.second->size(); + } + + return count; + } + + /** + * @brief Returns a sink object for the given event and queue. + * + * A sink is an opaque object used to connect listeners to events. + * + * The function type for a listener is _compatible_ with: + * + * @code{.cpp} + * void(Type &); + * @endcode + * + * The order of invocation of the listeners isn't guaranteed. + * + * @sa sink + * + * @tparam Type Type of event of which to get the sink. + * @param id Name used to map the event queue within the dispatcher. + * @return A temporary sink object. + */ + template + [[nodiscard]] auto sink(const id_type id = type_hash::value()) { + return assure(id).bucket(); + } + + /** + * @brief Triggers an immediate event of a given type. + * @tparam Type Type of event to trigger. + * @param value An instance of the given type of event. + */ + template + void trigger(Type &&value = {}) { + trigger(type_hash>::value(), std::forward(value)); + } + + /** + * @brief Triggers an immediate event on a queue of a given type. + * @tparam Type Type of event to trigger. + * @param value An instance of the given type of event. + * @param id Name used to map the event queue within the dispatcher. + */ + template + void trigger(const id_type id, Type &&value = {}) { + assure>(id).trigger(std::forward(value)); + } + + /** + * @brief Enqueues an event of the given type. + * @tparam Type Type of event to enqueue. + * @tparam Args Types of arguments to use to construct the event. + * @param args Arguments to use to construct the event. + */ + template + void enqueue(Args &&...args) { + enqueue_hint(type_hash::value(), std::forward(args)...); + } + + /** + * @brief Enqueues an event of the given type. + * @tparam Type Type of event to enqueue. + * @param value An instance of the given type of event. + */ + template + void enqueue(Type &&value) { + enqueue_hint(type_hash>::value(), std::forward(value)); + } + + /** + * @brief Enqueues an event of the given type. + * @tparam Type Type of event to enqueue. + * @tparam Args Types of arguments to use to construct the event. + * @param id Name used to map the event queue within the dispatcher. + * @param args Arguments to use to construct the event. + */ + template + void enqueue_hint(const id_type id, Args &&...args) { + assure(id).enqueue(std::forward(args)...); + } + + /** + * @brief Enqueues an event of the given type. + * @tparam Type Type of event to enqueue. + * @param id Name used to map the event queue within the dispatcher. + * @param value An instance of the given type of event. + */ + template + void enqueue_hint(const id_type id, Type &&value) { + assure>(id).enqueue(std::forward(value)); + } + + /** + * @brief Utility function to disconnect everything related to a given value + * or instance from a dispatcher. + * @tparam Type Type of class or type of payload. + * @param value_or_instance A valid object that fits the purpose. + */ + template + void disconnect(Type &value_or_instance) { + disconnect(&value_or_instance); + } + + /** + * @brief Utility function to disconnect everything related to a given value + * or instance from a dispatcher. + * @tparam Type Type of class or type of payload. + * @param value_or_instance A valid object that fits the purpose. + */ + template + void disconnect(Type *value_or_instance) { + for(auto &&cpool: pools.first()) { + cpool.second->disconnect(value_or_instance); + } + } + + /** + * @brief Discards all the events stored so far in a given queue. + * @tparam Type Type of event to discard. + * @param id Name used to map the event queue within the dispatcher. + */ + template + void clear(const id_type id = type_hash::value()) { + assure(id).clear(); + } + + /*! @brief Discards all the events queued so far. */ + void clear() noexcept { + for(auto &&cpool: pools.first()) { + cpool.second->clear(); + } + } + + /** + * @brief Delivers all the pending events of a given queue. + * @tparam Type Type of event to send. + * @param id Name used to map the event queue within the dispatcher. + */ + template + void update(const id_type id = type_hash::value()) { + assure(id).publish(); + } + + /*! @brief Delivers all the pending events. */ + void update() const { + for(auto &&cpool: pools.first()) { + cpool.second->publish(); + } + } + +private: + compressed_pair pools; +}; + +} // namespace entt + +#endif + +// #include "signal/emitter.hpp" +#ifndef ENTT_SIGNAL_EMITTER_HPP +#define ENTT_SIGNAL_EMITTER_HPP + +#include +#include +#include +// #include "../container/dense_map.hpp" + +// #include "../core/compressed_pair.hpp" + +// #include "../core/fwd.hpp" + +// #include "../core/type_info.hpp" + +// #include "../core/utility.hpp" + +// #include "fwd.hpp" + + +namespace entt { + +/** + * @brief General purpose event emitter. + * + * To create an emitter type, derived classes must inherit from the base as: + * + * @code{.cpp} + * struct my_emitter: emitter { + * // ... + * } + * @endcode + * + * Handlers for the different events are created internally on the fly. It's not + * required to specify in advance the full list of accepted events.
+ * Moreover, whenever an event is published, an emitter also passes a reference + * to itself to its listeners. + * + * @tparam Derived Emitter type. + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +class emitter { + using key_type = id_type; + using mapped_type = std::function; + + using alloc_traits = std::allocator_traits; + using container_allocator = typename alloc_traits::template rebind_alloc>; + using container_type = dense_map, container_allocator>; + +public: + /*! @brief Allocator type. */ + using allocator_type = Allocator; + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + + /*! @brief Default constructor. */ + emitter() + : emitter{allocator_type{}} {} + + /** + * @brief Constructs an emitter with a given allocator. + * @param allocator The allocator to use. + */ + explicit emitter(const allocator_type &allocator) + : handlers{allocator, allocator} {} + + /*! @brief Default copy constructor, deleted on purpose. */ + emitter(const emitter &) = delete; + + /** + * @brief Move constructor. + * @param other The instance to move from. + */ + emitter(emitter &&other) noexcept + : handlers{std::move(other.handlers)} {} + + /** + * @brief Allocator-extended move constructor. + * @param other The instance to move from. + * @param allocator The allocator to use. + */ + emitter(emitter &&other, const allocator_type &allocator) + : handlers{container_type{std::move(other.handlers.first()), allocator}, allocator} { + ENTT_ASSERT(alloc_traits::is_always_equal::value || handlers.second() == other.handlers.second(), "Copying an emitter is not allowed"); + } + + /*! @brief Default destructor. */ + virtual ~emitter() { + static_assert(std::is_base_of_v, Derived>, "Invalid emitter type"); + } + + /** + * @brief Default copy assignment operator, deleted on purpose. + * @return This emitter. + */ + emitter &operator=(const emitter &) = delete; + + /** + * @brief Move assignment operator. + * @param other The instance to move from. + * @return This emitter. + */ + emitter &operator=(emitter &&other) noexcept { + ENTT_ASSERT(alloc_traits::is_always_equal::value || handlers.second() == other.handlers.second(), "Copying an emitter is not allowed"); + swap(other); + return *this; + } + + /** + * @brief Exchanges the contents with those of a given emitter. + * @param other Emitter to exchange the content with. + */ + void swap(emitter &other) noexcept { + using std::swap; + swap(handlers, other.handlers); + } + + /** + * @brief Returns the associated allocator. + * @return The associated allocator. + */ + [[nodiscard]] constexpr allocator_type get_allocator() const noexcept { + return handlers.second(); + } + + /** + * @brief Publishes a given event. + * @tparam Type Type of event to trigger. + * @param value An instance of the given type of event. + */ + template + void publish(Type value) { + if(const auto id = type_id().hash(); handlers.first().contains(id)) { + handlers.first()[id](&value); + } + } + + /** + * @brief Registers a listener with the event emitter. + * @tparam Type Type of event to which to connect the listener. + * @param func The listener to register. + */ + template + void on(std::function func) { + handlers.first().insert_or_assign(type_id().hash(), [func = std::move(func), this](void *value) { + func(*static_cast(value), static_cast(*this)); + }); + } + + /** + * @brief Disconnects a listener from the event emitter. + * @tparam Type Type of event of the listener. + */ + template + void erase() { + handlers.first().erase(type_hash>>::value()); + } + + /*! @brief Disconnects all the listeners. */ + void clear() noexcept { + handlers.first().clear(); + } + + /** + * @brief Checks if there are listeners registered for the specific event. + * @tparam Type Type of event to test. + * @return True if there are no listeners registered, false otherwise. + */ + template + [[nodiscard]] bool contains() const { + return handlers.first().contains(type_hash>>::value()); + } + + /** + * @brief Checks if there are listeners registered with the event emitter. + * @return True if there are no listeners registered, false otherwise. + */ + [[nodiscard]] bool empty() const noexcept { + return handlers.first().empty(); + } + +private: + compressed_pair handlers; +}; + +} // namespace entt + +#endif + +// #include "signal/sigh.hpp" +#ifndef ENTT_SIGNAL_SIGH_HPP +#define ENTT_SIGNAL_SIGH_HPP + +#include +#include +#include +#include +#include +// #include "delegate.hpp" + +// #include "fwd.hpp" + + +namespace entt { + +/** + * @brief Sink class. + * + * Primary template isn't defined on purpose. All the specializations give a + * compile-time error unless the template parameter is a function type. + * + * @tparam Type A valid signal handler type. + */ +template +class sink; + +/** + * @brief Unmanaged signal handler. + * + * Primary template isn't defined on purpose. All the specializations give a + * compile-time error unless the template parameter is a function type. + * + * @tparam Type A valid function type. + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +class sigh; + +/** + * @brief Unmanaged signal handler. + * + * It works directly with references to classes and pointers to member functions + * as well as pointers to free functions. Users of this class are in charge of + * disconnecting instances before deleting them. + * + * This class serves mainly two purposes: + * + * * Creating signals to use later to notify a bunch of listeners. + * * Collecting results from a set of functions like in a voting system. + * + * @tparam Ret Return type of a function type. + * @tparam Args Types of arguments of a function type. + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +class sigh { + friend class sink>; + + using alloc_traits = std::allocator_traits; + using delegate_type = delegate; + using container_type = std::vector>; + +public: + /*! @brief Allocator type. */ + using allocator_type = Allocator; + /*! @brief Unsigned integer type. */ + using size_type = std::size_t; + /*! @brief Sink type. */ + using sink_type = sink>; + + /*! @brief Default constructor. */ + sigh() noexcept(noexcept(allocator_type{})) + : sigh{allocator_type{}} {} + + /** + * @brief Constructs a signal handler with a given allocator. + * @param allocator The allocator to use. + */ + explicit sigh(const allocator_type &allocator) noexcept + : calls{allocator} {} + + /** + * @brief Copy constructor. + * @param other The instance to copy from. + */ + sigh(const sigh &other) + : calls{other.calls} {} + + /** + * @brief Allocator-extended copy constructor. + * @param other The instance to copy from. + * @param allocator The allocator to use. + */ + sigh(const sigh &other, const allocator_type &allocator) + : calls{other.calls, allocator} {} + + /** + * @brief Move constructor. + * @param other The instance to move from. + */ + sigh(sigh &&other) noexcept + : calls{std::move(other.calls)} {} + + /** + * @brief Allocator-extended move constructor. + * @param other The instance to move from. + * @param allocator The allocator to use. + */ + sigh(sigh &&other, const allocator_type &allocator) + : calls{std::move(other.calls), allocator} {} + + /*! @brief Default destructor. */ + ~sigh() = default; + + /** + * @brief Copy assignment operator. + * @param other The instance to copy from. + * @return This signal handler. + */ + sigh &operator=(const sigh &other) { + calls = other.calls; + return *this; + } + + /** + * @brief Move assignment operator. + * @param other The instance to move from. + * @return This signal handler. + */ + sigh &operator=(sigh &&other) noexcept { + swap(other); + return *this; + } + + /** + * @brief Exchanges the contents with those of a given signal handler. + * @param other Signal handler to exchange the content with. + */ + void swap(sigh &other) noexcept { + using std::swap; + swap(calls, other.calls); + } + + /** + * @brief Returns the associated allocator. + * @return The associated allocator. + */ + [[nodiscard]] constexpr allocator_type get_allocator() const noexcept { + return calls.get_allocator(); + } + + /** + * @brief Number of listeners connected to the signal. + * @return Number of listeners currently connected. + */ + [[nodiscard]] size_type size() const noexcept { + return calls.size(); + } + + /** + * @brief Returns false if at least a listener is connected to the signal. + * @return True if the signal has no listeners connected, false otherwise. + */ + [[nodiscard]] bool empty() const noexcept { + return calls.empty(); + } + + /** + * @brief Triggers a signal. + * + * All the listeners are notified. Order isn't guaranteed. + * + * @param args Arguments to use to invoke listeners. + */ + void publish(Args... args) const { + for(auto pos = calls.size(); pos; --pos) { + calls[pos - 1u](args...); + } + } + + /** + * @brief Collects return values from the listeners. + * + * The collector must expose a call operator with the following properties: + * + * * The return type is either `void` or such that it's convertible to + * `bool`. In the second case, a true value will stop the iteration. + * * The list of parameters is empty if `Ret` is `void`, otherwise it + * contains a single element such that `Ret` is convertible to it. + * + * @tparam Func Type of collector to use, if any. + * @param func A valid function object. + * @param args Arguments to use to invoke listeners. + */ + template + void collect(Func func, Args... args) const { + for(auto pos = calls.size(); pos; --pos) { + if constexpr(std::is_void_v || !std::is_invocable_v) { + calls[pos - 1u](args...); + + if constexpr(std::is_invocable_r_v) { + if(func()) { + break; + } + } else { + func(); + } + } else { + if constexpr(std::is_invocable_r_v) { + if(func(calls[pos - 1u](args...))) { + break; + } + } else { + func(calls[pos - 1u](args...)); + } + } + } + } + +private: + container_type calls; +}; + +/** + * @brief Connection class. + * + * Opaque object the aim of which is to allow users to release an already + * estabilished connection without having to keep a reference to the signal or + * the sink that generated it. + */ +class connection { + template + friend class sink; + + connection(delegate fn, void *ref) + : disconnect{fn}, signal{ref} {} + +public: + /*! @brief Default constructor. */ + connection() + : signal{} {} + + /** + * @brief Checks whether a connection is properly initialized. + * @return True if the connection is properly initialized, false otherwise. + */ + [[nodiscard]] explicit operator bool() const noexcept { + return static_cast(disconnect); + } + + /*! @brief Breaks the connection. */ + void release() { + if(disconnect) { + disconnect(signal); + disconnect.reset(); + } + } + +private: + delegate disconnect; + void *signal; +}; + +/** + * @brief Scoped connection class. + * + * Opaque object the aim of which is to allow users to release an already + * estabilished connection without having to keep a reference to the signal or + * the sink that generated it.
+ * A scoped connection automatically breaks the link between the two objects + * when it goes out of scope. + */ +struct scoped_connection { + /*! @brief Default constructor. */ + scoped_connection() = default; + + /** + * @brief Constructs a scoped connection from a basic connection. + * @param other A valid connection object. + */ + scoped_connection(const connection &other) + : conn{other} {} + + /*! @brief Default copy constructor, deleted on purpose. */ + scoped_connection(const scoped_connection &) = delete; + + /** + * @brief Move constructor. + * @param other The scoped connection to move from. + */ + scoped_connection(scoped_connection &&other) noexcept + : conn{std::exchange(other.conn, {})} {} + + /*! @brief Automatically breaks the link on destruction. */ + ~scoped_connection() { + conn.release(); + } + + /** + * @brief Default copy assignment operator, deleted on purpose. + * @return This scoped connection. + */ + scoped_connection &operator=(const scoped_connection &) = delete; + + /** + * @brief Move assignment operator. + * @param other The scoped connection to move from. + * @return This scoped connection. + */ + scoped_connection &operator=(scoped_connection &&other) noexcept { + conn = std::exchange(other.conn, {}); + return *this; + } + + /** + * @brief Acquires a connection. + * @param other The connection object to acquire. + * @return This scoped connection. + */ + scoped_connection &operator=(connection other) { + conn = other; + return *this; + } + + /** + * @brief Checks whether a scoped connection is properly initialized. + * @return True if the connection is properly initialized, false otherwise. + */ + [[nodiscard]] explicit operator bool() const noexcept { + return static_cast(conn); + } + + /*! @brief Breaks the connection. */ + void release() { + conn.release(); + } + +private: + connection conn; +}; + +/** + * @brief Sink class. + * + * A sink is used to connect listeners to signals and to disconnect them.
+ * The function type for a listener is the one of the signal to which it + * belongs. + * + * The clear separation between a signal and a sink permits to store the former + * as private data member without exposing the publish functionality to the + * users of the class. + * + * @warning + * Lifetime of a sink must not overcome that of the signal to which it refers. + * In any other case, attempting to use a sink results in undefined behavior. + * + * @tparam Ret Return type of a function type. + * @tparam Args Types of arguments of a function type. + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +class sink> { + using signal_type = sigh; + using delegate_type = typename signal_type::delegate_type; + using difference_type = typename signal_type::container_type::difference_type; + + template + static void release(Type value_or_instance, void *signal) { + sink{*static_cast(signal)}.disconnect(value_or_instance); + } + + template + static void release(void *signal) { + sink{*static_cast(signal)}.disconnect(); + } + + template + void disconnect_if(Func callback) { + auto &ref = signal_or_assert(); + + for(auto pos = ref.calls.size(); pos; --pos) { + if(auto &elem = ref.calls[pos - 1u]; callback(elem)) { + elem = std::move(ref.calls.back()); + ref.calls.pop_back(); + } + } + } + + [[nodiscard]] auto &signal_or_assert() const noexcept { + ENTT_ASSERT(signal != nullptr, "Invalid pointer to signal"); + return *signal; + } + +public: + /*! @brief Constructs an invalid sink. */ + sink() noexcept + : signal{} {} + + /** + * @brief Constructs a sink that is allowed to modify a given signal. + * @param ref A valid reference to a signal object. + */ + sink(sigh &ref) noexcept + : signal{&ref} {} + + /** + * @brief Returns false if at least a listener is connected to the sink. + * @return True if the sink has no listeners connected, false otherwise. + */ + [[nodiscard]] bool empty() const noexcept { + return signal_or_assert().calls.empty(); + } + + /** + * @brief Connects a free function or an unbound member to a signal. + * @tparam Candidate Function or member to connect to the signal. + * @return A properly initialized connection object. + */ + template + connection connect() { + disconnect(); + + delegate_type call{}; + call.template connect(); + signal_or_assert().calls.push_back(std::move(call)); + + delegate conn{}; + conn.template connect<&release>(); + return {conn, signal}; + } + + /** + * @brief Connects a free function with payload or a bound member to a + * signal. + * + * The signal isn't responsible for the connected object or the payload. + * Users must always guarantee that the lifetime of the instance overcomes + * the one of the signal.
+ * When used to connect a free function with payload, its signature must be + * such that the instance is the first argument before the ones used to + * define the signal itself. + * + * @tparam Candidate Function or member to connect to the signal. + * @tparam Type Type of class or type of payload. + * @param value_or_instance A valid reference that fits the purpose. + * @return A properly initialized connection object. + */ + template + connection connect(Type &value_or_instance) { + disconnect(value_or_instance); + + delegate_type call{}; + call.template connect(value_or_instance); + signal_or_assert().calls.push_back(std::move(call)); + + delegate conn{}; + conn.template connect<&release>(value_or_instance); + return {conn, signal}; + } + + /** + * @brief Connects a free function with payload or a bound member to a + * signal. + * + * @sa connect(Type &) + * + * @tparam Candidate Function or member to connect to the signal. + * @tparam Type Type of class or type of payload. + * @param value_or_instance A valid pointer that fits the purpose. + * @return A properly initialized connection object. + */ + template + connection connect(Type *value_or_instance) { + disconnect(value_or_instance); + + delegate_type call{}; + call.template connect(value_or_instance); + signal_or_assert().calls.push_back(std::move(call)); + + delegate conn{}; + conn.template connect<&release>(value_or_instance); + return {conn, signal}; + } + + /** + * @brief Disconnects a free function or an unbound member from a signal. + * @tparam Candidate Function or member to disconnect from the signal. + */ + template + void disconnect() { + delegate_type call{}; + call.template connect(); + disconnect_if([&call](const auto &elem) { return elem == call; }); + } + + /** + * @brief Disconnects a free function with payload or a bound member from a + * signal. + * + * The signal isn't responsible for the connected object or the payload. + * Users must always guarantee that the lifetime of the instance overcomes + * the one of the signal.
+ * When used to connect a free function with payload, its signature must be + * such that the instance is the first argument before the ones used to + * define the signal itself. + * + * @tparam Candidate Function or member to disconnect from the signal. + * @tparam Type Type of class or type of payload, if any. + * @param value_or_instance A valid reference that fits the purpose. + */ + template + void disconnect(Type &value_or_instance) { + delegate_type call{}; + call.template connect(value_or_instance); + disconnect_if([&call](const auto &elem) { return elem == call; }); + } + + /** + * @brief Disconnects a free function with payload or a bound member from a + * signal. + * + * @sa disconnect(Type &) + * + * @tparam Candidate Function or member to disconnect from the signal. + * @tparam Type Type of class or type of payload, if any. + * @param value_or_instance A valid pointer that fits the purpose. + */ + template + void disconnect(Type *value_or_instance) { + delegate_type call{}; + call.template connect(value_or_instance); + disconnect_if([&call](const auto &elem) { return elem == call; }); + } + + /** + * @brief Disconnects free functions with payload or bound members from a + * signal. + * @param value_or_instance A valid object that fits the purpose. + */ + void disconnect(const void *value_or_instance) { + ENTT_ASSERT(value_or_instance != nullptr, "Invalid value or instance"); + disconnect_if([value_or_instance](const auto &elem) { return elem.data() == value_or_instance; }); + } + + /*! @brief Disconnects all the listeners from a signal. */ + void disconnect() { + signal_or_assert().calls.clear(); + } + + /** + * @brief Returns true if a sink is correctly initialized, false otherwise. + * @return True if a sink is correctly initialized, false otherwise. + */ + [[nodiscard]] explicit operator bool() const noexcept { + return signal != nullptr; + } + +private: + signal_type *signal; +}; + +/** + * @brief Deduction guide. + * + * It allows to deduce the signal handler type of a sink directly from the + * signal it refers to. + * + * @tparam Ret Return type of a function type. + * @tparam Args Types of arguments of a function type. + * @tparam Allocator Type of allocator used to manage memory and elements. + */ +template +sink(sigh &) -> sink>; + +} // namespace entt + +#endif + +// IWYU pragma: end_exports \ No newline at end of file diff --git a/src/Application.cpp b/src/Application.cpp index 0dafa58..3c834ef 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include "log/log.h" #include "rlImGui.h" From 8f7bafb43f5ff8f18c77b371870ebcf27d846499 Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Thu, 5 Mar 2026 22:39:57 +1300 Subject: [PATCH 14/53] chore: include license for entt --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index a36580a..eab863d 100644 --- a/README.md +++ b/README.md @@ -128,3 +128,4 @@ cd ../.. && git add external/raylib external/angelscript && git commit -m "Updat * Raylib: Zlib License (see https://github.com/raysan5/raylib#license) * AngelScript: MIT License (see https://github.com/angelcode/angelscript/blob/master/license.txt) * Simian: Not open source (yet) +* Entt: MIT License (see https://github.com/skypjack/entt/blob/main/LICENSE) From aa4c7cf58a5cc3853a32671eebb95e7d5065bf4c Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Thu, 5 Mar 2026 23:22:09 +1300 Subject: [PATCH 15/53] feat: entt scripting support --- CMakeLists.txt | 19 +- imgui.ini | 8 +- include/Application.h | 17 +- include/ECSComponents.h | 54 +++++ include/scripting/ECSBindings.h | 8 + include/scripting/ScriptEngine.h | 2 - scripts/as.predefined | 58 +++++- scripts/game.as | 117 ++++++++++- src/Application.cpp | 241 ++++++++++------------- src/scripting/ECSBindings.cpp | 317 ++++++++++++++++++++++++++++++ src/scripting/ScriptBindings.cpp | 4 +- src/scripting/ScriptEngine.cpp | 8 +- src/scripting/TextureBindings.cpp | 11 +- tests/CMakeLists.txt | 4 +- 14 files changed, 694 insertions(+), 174 deletions(-) create mode 100644 include/ECSComponents.h create mode 100644 include/scripting/ECSBindings.h create mode 100644 src/scripting/ECSBindings.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 79f42d4..40a0a36 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,6 +46,10 @@ endif() # ------------------------- enable_testing() add_subdirectory(tests) + +# ------------------------- +# 3️⃣.2️⃣ ECS Bindings +# ------------------------- # ------------------------- # 3️⃣ scriptstdstring add-on # ------------------------- @@ -68,6 +72,17 @@ target_include_directories(scriptbuilder PUBLIC external/angelscript/sdk/angelscript/include ) +# ------------------------- +# 3️⃣.2️⃣ scriptarray add-on +# ------------------------- +add_library(scriptarray STATIC + external/angelscript/sdk/add_on/scriptarray/scriptarray.cpp +) + +target_include_directories(scriptarray + PUBLIC external/angelscript/sdk/angelscript/include +) + # ------------------------- # 4️⃣ Main executable # ------------------------- @@ -78,10 +93,10 @@ add_executable(simian src/scripting/ScriptBindings.cpp src/scripting/ToastBindings.cpp src/scripting/LogBindings.cpp - src/scripting/DrawBindings.cpp src/scripting/ImageBindings.cpp src/scripting/TextureBindings.cpp src/scripting/MathBindings.cpp + src/scripting/ECSBindings.cpp src/HotReload.cpp src/gui/GuiManager.cpp src/gui/LogWindow.cpp @@ -97,6 +112,7 @@ target_include_directories(simian PUBLIC external/angelscript/sdk/angelscript/include external/angelscript/sdk/add_on/scriptstdstring external/angelscript/sdk/add_on/scriptbuilder + external/angelscript/sdk/add_on/scriptarray external/imgui ) @@ -105,6 +121,7 @@ target_link_libraries(simian PRIVATE angelscript scriptstdstring scriptbuilder + scriptarray imgui ) diff --git a/imgui.ini b/imgui.ini index 3cc24d0..2e3c391 100644 --- a/imgui.ini +++ b/imgui.ini @@ -21,13 +21,13 @@ Collapsed=0 DockId=0x00000002,0 [Window][##TOAST0] -Pos=1007,637 -Size=253,63 +Pos=1033,637 +Size=227,63 Collapsed=0 [Window][##TOAST1] -Pos=1064,564 -Size=196,63 +Pos=1035,564 +Size=225,63 Collapsed=0 [Window][##TOAST2] diff --git a/include/Application.h b/include/Application.h index 78a6ee3..e4fcc4e 100644 --- a/include/Application.h +++ b/include/Application.h @@ -3,6 +3,8 @@ #include "HotReload.h" #include "gui/GuiManager.h" #include "raylib.h" +#include +#include class Application { public: @@ -27,6 +29,17 @@ private: bool queueShutdown = false; RenderTexture2D renderTexture; // renderTexture for Raylib rendering + // ECS + entt::registry registry; + std::vector models; + + // Scene/rendering data + Camera3D camera; + Shader toonShader; + Vector3 lightDir; + float globalBandCount; + bool dayMode; + static const int WINDOW_WIDTH = 1280; static const int WINDOW_HEIGHT = 720; static const int TARGET_FPS = 60; @@ -34,7 +47,7 @@ private: static const char* SCRIPT_FILE; void Update(float deltaTime); + void UpdateSystems(float deltaTime); + void RenderScene(); void Draw(); - - void SpawnCube(); }; \ No newline at end of file diff --git a/include/ECSComponents.h b/include/ECSComponents.h new file mode 100644 index 0000000..d1b7c13 --- /dev/null +++ b/include/ECSComponents.h @@ -0,0 +1,54 @@ +#pragma once +#include "raylib.h" +#include + +// ECSTransform component - position, rotation, and scale +struct ECSTransform { + Vector3 position; + Vector3 scale; + float rotation; // Rotation around Y axis in radians + + ECSTransform() + : position{0.0f, 0.0f, 0.0f} + , scale{1.0f, 1.0f, 1.0f} + , rotation(0.0f) {} + + ECSTransform(Vector3 pos, Vector3 scl = {1.0f, 1.0f, 1.0f}, float rot = 0.0f) + : position(pos), scale(scl), rotation(rot) {} +}; + +// Velocity component - for movement +struct Velocity { + Vector3 linear; // Linear velocity (units per second) + float angular; // Angular velocity (radians per second) + + Velocity() + : linear{0.0f, 0.0f, 0.0f} + , angular(0.0f) {} + + Velocity(Vector3 lin, float ang = 0.0f) + : linear(lin), angular(ang) {} +}; + +// Sprite component - visual representation +struct Sprite { + int modelId; // Index into models array + Color color; // Tint color + float outlineSize; // Outline thickness + + Sprite() + : modelId(0) + , color(WHITE) + , outlineSize(0.0f) {} + + Sprite(int model, Color col = WHITE, float outline = 0.0f) + : modelId(model), color(col), outlineSize(outline) {} +}; + +// Tag component - simple string identifier +struct Tag { + std::string name; + + Tag() : name("") {} + Tag(const std::string& n) : name(n) {} +}; diff --git a/include/scripting/ECSBindings.h b/include/scripting/ECSBindings.h new file mode 100644 index 0000000..5036374 --- /dev/null +++ b/include/scripting/ECSBindings.h @@ -0,0 +1,8 @@ +#pragma once +#include +#include + +// Set the global registry that scripts will interact with +void SetGlobalRegistry(entt::registry* reg); + +void RegisterECSBindings(asIScriptEngine *engine); diff --git a/include/scripting/ScriptEngine.h b/include/scripting/ScriptEngine.h index cb20b77..650936d 100644 --- a/include/scripting/ScriptEngine.h +++ b/include/scripting/ScriptEngine.h @@ -25,14 +25,12 @@ public: asIScriptEngine* GetEngine() const { return engine; } asIScriptFunction* GetUpdateFunction() const { return updateFunc; } - asIScriptFunction* GetDrawFunction() const { return drawFunc; } asIScriptFunction* GetInitFunction() const { return initFunc; } asIScriptFunction* GetShutdownFunction() const { return shutdownFunc; } private: asIScriptEngine* engine; asIScriptFunction* updateFunc; - asIScriptFunction* drawFunc; asIScriptFunction* initFunc; asIScriptFunction* shutdownFunc; asIScriptModule* currentModule; diff --git a/scripts/as.predefined b/scripts/as.predefined index 18beee9..b26ad4b 100644 --- a/scripts/as.predefined +++ b/scripts/as.predefined @@ -1,6 +1,18 @@ typedef void string; string format(const string&in fmt, const ?&in ...); +// Array template (provided by scriptarray add-on) +external shared interface array { + uint length() const; + void resize(uint); + void insertAt(uint, const T&in); + void insertLast(const T&in); + void removeAt(uint); + void removeLast(); + T& opIndex(uint); + const T& opIndex(uint) const; +} + // Logging functions void Print(const string&in); void Log(int level, const string&in); @@ -19,14 +31,44 @@ namespace Toast { void Success(const string&in); } -// Drawing functions -namespace Draw { - void Pixel(int x, int y, int color); - void Line(int startX, int startY, int endX, int endY, int color); - void Circle(int centerX, int centerY, float radius, int color); - void Text(const string&in text, int x, int y, int fontSize, int color); - void Rectangle(int x, int y, int width, int height, int color); - void FPS(int x, int y); +// ECS functions +namespace ECS { + // Entity management + uint CreateEntity(); + void DestroyEntity(uint entity); + bool IsValid(uint entity); + + // Transform component + void AddTransform(uint entity, float x, float y, float z); + void SetPosition(uint entity, float x, float y, float z); + void GetPosition(uint entity, float &out x, float &out y, float &out z); + void SetScale(uint entity, float x, float y, float z); + void SetRotation(uint entity, float rotation); + float GetRotation(uint entity); + bool HasTransform(uint entity); + void RemoveTransform(uint entity); + + // Velocity component + void AddVelocity(uint entity, float vx, float vy, float vz, float angular = 0.0f); + void SetVelocity(uint entity, float vx, float vy, float vz); + void SetAngularVelocity(uint entity, float angular); + bool HasVelocity(uint entity); + void RemoveVelocity(uint entity); + + // Sprite component + void AddSprite(uint entity, int modelId, uint color, float outlineSize = 0.0f); + void SetSpriteColor(uint entity, uint color); + void SetSpriteModel(uint entity, int modelId); + void SetSpriteOutline(uint entity, float outlineSize); + bool HasSprite(uint entity); + void RemoveSprite(uint entity); + + // Tag component + void AddTag(uint entity, const string &in name); + string GetTag(uint entity); + void SetTag(uint entity, const string &in name); + bool HasTag(uint entity); + void RemoveTag(uint entity); } namespace Texture { diff --git a/scripts/game.as b/scripts/game.as index 5dfa215..01cc269 100644 --- a/scripts/game.as +++ b/scripts/game.as @@ -1,11 +1,108 @@ -#include "update.as" +// ECS-based game script demo +// This demonstrates creating entities with various components -void Draw() { - Draw::FPS(10, 10); - Draw::Text(format("Hello from AngelScript - at x {} and y {}", int(x), int(y)), int(x), int(y), 20, 0xFF0000FF); - Draw::Rectangle(300, 200, 200, 100, 0x00FF00FF); - Draw::Pixel(250, 200, 0x0000FFFF); - Draw::Line(int(x), int(y), 400, 300, 0xFFFF00FF); - Draw::Circle(600, 400, 50.0f, 0xFF00FFFF); - Texture::Draw(tex, int(ix), int(iy), 0xFFFFFFFF); -} \ No newline at end of file +// Store entity IDs for manipulation +array entities; +uint player; +uint spinningCube; +float time = 0.0f; + +void Init() { + Log(LOG_TRACE, "Initialization complete - ECS Demo!"); + Toast::Success("ECS Script initialized successfully!"); + + // Create a player entity at origin + player = ECS::CreateEntity(); + ECS::AddTransform(player, 0.0f, 0.0f, 0.0f); + ECS::AddSprite(player, 0, 0xFF0000FF, 0.0f); // Red cube, model 0 + ECS::AddTag(player, "Player"); + Log(LOG_INFO, "Created player entity: " + player); + + // Create a spinning cube + spinningCube = ECS::CreateEntity(); + ECS::AddTransform(spinningCube, 2.0f, 0.0f, 0.0f); + ECS::AddSprite(spinningCube, 0, 0x00FF00FF, 0.0f); // Green cube + ECS::AddVelocity(spinningCube, 0.0f, 0.0f, 0.0f, 2.0f); // Angular velocity + ECS::AddTag(spinningCube, "Spinner"); + Log(LOG_INFO, "Created spinning cube: " + spinningCube); + + // Create orbiting entities + for (int i = 0; i < 5; i++) { + uint entity = ECS::CreateEntity(); + + float angle = (float(i) / 5.0f) * 6.28318f; // 2*PI + float radius = 3.0f; + float x = Math::Cos(angle) * radius; + float z = Math::Sin(angle) * radius; + + ECS::AddTransform(entity, x, 0.0f, z); + + // Different colors for each + uint color = 0; + if (i == 0) color = 0xFFFF00FF; // Yellow + else if (i == 1) color = 0xFF00FFFF; // Magenta + else if (i == 2) color = 0x00FFFFFF; // Cyan + else if (i == 3) color = 0xFFA500FF; // Orange + else color = 0xFF69B4FF; // Pink + + ECS::AddSprite(entity, 0, color, 0.0f); + ECS::AddTag(entity, "Orbiter" + i); + + entities.insertLast(entity); + } + + // Create a moving entity + uint mover = ECS::CreateEntity(); + ECS::AddTransform(mover, -3.0f, 0.5f, 0.0f); + ECS::AddSprite(mover, 0, 0xFFFFFFFF, 0.0f); // White cube + ECS::AddVelocity(mover, 1.0f, 0.0f, 0.5f, 0.0f); // Moving velocity + ECS::AddTag(mover, "Mover"); + entities.insertLast(mover); + + Toast::Success("Created " + (entities.length() + 3) + " entities!"); +} + +void Shutdown() { + Log(LOG_TRACE, "Shutdown complete!"); +} + +void Update(float dt) { + time += dt; + + // Update player position - simple back and forth motion + float playerX = Math::Sin(time) * 2.0f; + ECS::SetPosition(player, playerX, 0.0f, 0.0f); + + // Update orbiting entities in a circle + for (uint i = 0; i < entities.length() - 1; i++) { + uint entity = entities[i]; + if (!ECS::IsValid(entity)) continue; + + float angle = (float(i) / 5.0f) * 6.28318f + time * 0.5f; + float radius = 3.0f; + float x = Math::Cos(angle) * radius; + float z = Math::Sin(angle) * radius; + float y = Math::Sin(time * 2.0f + float(i)) * 0.5f; // Bobbing motion + + ECS::SetPosition(entity, x, y, z); + ECS::SetRotation(entity, time + float(i)); + } + + // The mover entity wraps around using the Velocity component + // which is handled by the C++ movement system + if (entities.length() > 0) { + uint mover = entities[entities.length() - 1]; + if (ECS::IsValid(mover) && ECS::HasTransform(mover)) { + float x, y, z; + ECS::GetPosition(mover, x, y, z); + + // Wrap around + if (x > 5.0f) { + ECS::SetPosition(mover, -5.0f, y, z); + } + if (z > 5.0f) { + ECS::SetPosition(mover, x, y, -5.0f); + } + } + } +} diff --git a/src/Application.cpp b/src/Application.cpp index 3c834ef..aee6863 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -1,4 +1,6 @@ #include "Application.h" +#include "ECSComponents.h" +#include "scripting/ECSBindings.h" #include "raylib.h" #include #include @@ -18,10 +20,18 @@ // On non-Windows platforms, define fopen_s as a macro for fopen. #define fopen_s(pFile, filename, mode) ((*(pFile) = fopen((filename), (mode))) == NULL) #endif + const char *Application::WINDOW_TITLE = "Simian"; const char *Application::SCRIPT_FILE = "scripts/game.as"; -Application::Application() : hotReload(nullptr), scriptCompilationError(false), logFile(nullptr), renderTexture{} // Initialize renderTexture +Application::Application() + : hotReload(nullptr) + , scriptCompilationError(false) + , logFile(nullptr) + , renderTexture{} + , lightDir{0.5f, 0.7f, 0.3f} + , globalBandCount(3.0f) + , dayMode(true) { } @@ -32,36 +42,6 @@ Application::~Application() // Shutdown(); } -/// Shader and rendering data for the demo scene -Camera3D camera; -RenderTexture2D sceneRT, maskRT; -Shader toonShader, outlineShader; -Model cube; - -float globalBandCount = 3.0f; -Vector3 lightDir = {0.5f, 0.7f, 0.3f}; -bool showEditor = true; -bool dayMode = true; -entt::registry ecs; -std::vector models; -struct ECS_Transform -{ - Vector3 pos, scale; - float rot; -}; -struct Render -{ - int modelId; - float outlineSize; - Color color; -}; -struct ECS_Material -{ - Shader shader; - int lightLoc, bandLoc; -}; -/// ====== - bool Application::Initialize(int argc, char *argv[]) { if (fopen_s(&logFile, "log.txt", "w") != 0) @@ -98,6 +78,9 @@ bool Application::Initialize(int argc, char *argv[]) return false; } + // Set up ECS bindings with our registry + SetGlobalRegistry(®istry); + // Initialize hot reload to watch the scripts directory so any script change // triggers a reload. { @@ -113,44 +96,30 @@ bool Application::Initialize(int argc, char *argv[]) if (enableEditor) { - guiManager.Initialize(this); - renderTexture = LoadRenderTexture(WINDOW_WIDTH, WINDOW_HEIGHT); } + // Set up camera camera.position = {5, 5, 5}; camera.target = {0, 0, 0}; camera.up = {0, 1, 0}; camera.fovy = 45; - // Assets - cube = LoadModelFromMesh(GenMeshCube(1, 1, 1)); - models.push_back(cube); - // Shaders (toon + outline) + // Load models + Model cube = LoadModelFromMesh(GenMeshCube(1, 1, 1)); + + // Load shaders toonShader = LoadShader(0, "shaders/toon.fs"); - outlineShader = LoadShader(0, "shaders/outline.fs"); - - // Render textures - sceneRT = LoadRenderTexture(1280, 720); - maskRT = LoadRenderTexture(1280, 720); - - // Cache uniform locations + + // Assign shader to cube material cube.materials[0].shader = toonShader; + + models.push_back(cube); return true; } -void Application::SpawnCube() -{ - auto e = ecs.create(); - ecs.emplace( - e, - Vector3{static_cast(rand() % 3 - 1), 0.0f, static_cast(rand() % 3 - 1)}, // Position - Vector3{1.0f, 1.0f, 1.0f}, // Scale - 0.0f // Rotation - ); - ecs.emplace(e, 0, 2.0f, YELLOW); -} + void Application::Run() { scriptEngine.CallScriptFunction(scriptEngine.GetInitFunction()); @@ -189,24 +158,75 @@ void Application::Update(float deltaTime) // Call script Update function scriptEngine.CallScriptFunction(scriptEngine.GetUpdateFunction(), deltaTime); + // Update ECS systems + UpdateSystems(deltaTime); + UpdateCamera(&camera, CAMERA_ORBITAL); // Day/night toggle if (IsKeyPressed(KEY_SPACE)) dayMode = !dayMode; globalBandCount = dayMode ? 3.0f : 2.0f; +} - // F1 editor toggle - if (IsKeyPressed(KEY_F1)) - showEditor = !showEditor; +void Application::UpdateSystems(float deltaTime) +{ + // Movement system - apply velocity to transform + auto view = registry.view(); + for (auto entity : view) + { + auto& transform = view.get(entity); + auto& velocity = view.get(entity); + + // Apply linear velocity + transform.position.x += velocity.linear.x * deltaTime; + transform.position.y += velocity.linear.y * deltaTime; + transform.position.z += velocity.linear.z * deltaTime; + + // Apply angular velocity + transform.rotation += velocity.angular * deltaTime; + } +} - if (IsKeyPressed(KEY_F2)) - SpawnCube(); +void Application::RenderScene() +{ + BeginMode3D(camera); + + DrawGrid(10, 1); + DrawLine3D(Vector3{0, 0, 0}, Vector3{lightDir.x * 5.0f, lightDir.y * 5.0f, lightDir.z * 5.0f}, RED); + + // Render all entities with ECSTransform and Sprite components + BeginShaderMode(toonShader); + SetShaderValue(toonShader, GetShaderLocation(toonShader, "lightDir"), &lightDir, SHADER_UNIFORM_VEC3); + SetShaderValue(toonShader, GetShaderLocation(toonShader, "bandCount"), &globalBandCount, SHADER_UNIFORM_FLOAT); + + auto view = registry.view(); + for (auto entity : view) + { + const auto& transform = view.get(entity); + const auto& sprite = view.get(entity); + + // Set color for this entity + Vector4 color = { + sprite.color.r / 255.0f, + sprite.color.g / 255.0f, + sprite.color.b / 255.0f, + sprite.color.a / 255.0f + }; + SetShaderValue(toonShader, GetShaderLocation(toonShader, "albedo"), &color, SHADER_UNIFORM_VEC4); + + // Draw the model with transform + Model& model = models[sprite.modelId]; + DrawModelEx(model, transform.position, Vector3{0, 1, 0}, transform.rotation * RAD2DEG, + transform.scale, WHITE); + } + + EndShaderMode(); + EndMode3D(); } void Application::Draw() { - int screenWidth = GetScreenWidth(); int screenHeight = GetScreenHeight(); @@ -218,85 +238,26 @@ void Application::Draw() screenHeight = 600; } - ImGuiIO &io = ImGui::GetIO(); - io.DisplaySize = ImVec2((float)screenWidth, (float)screenHeight); // Set DisplaySize - - BeginTextureMode(renderTexture); - - ClearBackground(SKYBLUE); - BeginMode3D(camera); - DrawGrid(10, 1); - DrawLine3D(Vector3{0, 0, 0}, Vector3{lightDir.x * 5.0f, lightDir.y * 5.0f, lightDir.z * 5.0f}, RED); - BeginShaderMode(toonShader); - SetShaderValue(toonShader, GetShaderLocation(toonShader, "lightDir"), &lightDir, SHADER_UNIFORM_VEC3); - SetShaderValue(toonShader, GetShaderLocation(toonShader, "bandCount"), &globalBandCount, SHADER_UNIFORM_FLOAT); - - auto view = ecs.view(); - view.each([&](const auto &t, const auto &r) - { - Vector4 color = {r.color.r / 255.0f, r.color.g / 255.0f, r.color.b / 255.0f, r.color.a / 255.0f}; - SetShaderValue(toonShader, GetShaderLocation(toonShader, "albedo"), &color, SHADER_UNIFORM_VEC4); - DrawModel(models[r.modelId], t.pos, 1.0f, WHITE); // Use WHITE since color is handled by the shader - }); - - EndShaderMode(); - - EndMode3D(); - // Call script Draw function - scriptEngine.CallScriptFunction(scriptEngine.GetDrawFunction()); - - // 2. Silhouette mask - // BeginTextureMode(maskRT); - // ClearBackground(WHITE); - // BeginMode3D(camera); - - // for (auto e : ecs.view()) - // { - // auto &t = ecs.get(e); - // DrawModel(models[ecs.get(e).modelId], t.pos, 1.0f, BLACK); - // } - - // EndMode3D(); - // EndTextureMode(); - - // // 3. Outline postprocess - // BeginShaderMode(outlineShader); - // Rectangle src = {0, 0, (float)maskRT.texture.width, (float)-maskRT.texture.height}; - // DrawTextureRec(maskRT.texture, src, {0, 0}, WHITE); - EndShaderMode(); - EndTextureMode(); if (enableEditor) { + ImGuiIO &io = ImGui::GetIO(); + io.DisplaySize = ImVec2((float)screenWidth, (float)screenHeight); + + BeginTextureMode(renderTexture); + ClearBackground(SKYBLUE); + RenderScene(); + EndTextureMode(); + BeginDrawing(); ClearBackground(RAYWHITE); - - guiManager.Render(renderTexture); // Render the GUI - - // rlImGuiBegin(); - // ImGui::Begin("Comic Engine"); - // std::string fpsText = "FPS: " + std::to_string(GetFPS()); - // ImGui::Text(fpsText.c_str()); - // if (ImGui::Button("Spawn Cube")) - // SpawnCube(); - // ImGui::Checkbox("Day Mode", &dayMode); - // ImGui::SliderFloat("Band Count", &globalBandCount, 1.0f, 5.0f); - // ImGui::ColorEdit3("Light Dir", &lightDir.x); - // ImGui::Text("F1: Toggle editor"); - // ImGui::End(); - - // // Scene hierarchy - // std::string sceneTitle = "Scene (" + std::to_string(ecs.view().size()) + " entities)"; - // ImGui::Begin(sceneTitle.c_str()); - // for (auto e : ecs.view()) - // { - // if (ImGui::Button(std::string("Cube " + std::to_string((int)e)).c_str())) - // { - // ecs.get(e).pos.x += 1.0f; - // } - // } - // ImGui::End(); - // rlImGuiEnd(); - + guiManager.Render(renderTexture); + EndDrawing(); + } + else + { + BeginDrawing(); + ClearBackground(SKYBLUE); + RenderScene(); EndDrawing(); } } @@ -322,11 +283,11 @@ void Application::Shutdown() scriptEngine.Shutdown(); // Unload assets - UnloadModel(cube); + for (auto& model : models) + { + UnloadModel(model); + } UnloadShader(toonShader); - UnloadShader(outlineShader); - UnloadRenderTexture(sceneRT); - UnloadRenderTexture(maskRT); // Clear the trace log callback before closing window to prevent logging after cleanup SetTraceLogCallback(nullptr); diff --git a/src/scripting/ECSBindings.cpp b/src/scripting/ECSBindings.cpp new file mode 100644 index 0000000..454d21a --- /dev/null +++ b/src/scripting/ECSBindings.cpp @@ -0,0 +1,317 @@ +#include "scripting/ECSBindings.h" +#include "ECSComponents.h" +#include +#include +#include + +// Global registry pointer for script access +static entt::registry* g_registry = nullptr; + +void SetGlobalRegistry(entt::registry* reg) { + g_registry = reg; +} + +// === Entity Management === + +uint32_t AS_CreateEntity() { + if (!g_registry) return 0; + return (uint32_t)g_registry->create(); +} + +void AS_DestroyEntity(uint32_t entity) { + if (!g_registry) return; + g_registry->destroy((entt::entity)entity); +} + +bool AS_IsEntityValid(uint32_t entity) { + if (!g_registry) return false; + return g_registry->valid((entt::entity)entity); +} + +// === Transform Component === + +void AS_AddTransform(uint32_t entity, float x, float y, float z) { + if (!g_registry) return; + g_registry->emplace((entt::entity)entity, + Vector3{x, y, z}, Vector3{1.0f, 1.0f, 1.0f}, 0.0f); +} + +void AS_SetPosition(uint32_t entity, float x, float y, float z) { + if (!g_registry) return; + if (auto* t = g_registry->try_get((entt::entity)entity)) { + t->position = {x, y, z}; + } +} + +void AS_GetPosition(uint32_t entity, float* x, float* y, float* z) { + if (!g_registry || !x || !y || !z) return; + if (auto* t = g_registry->try_get((entt::entity)entity)) { + *x = t->position.x; + *y = t->position.y; + *z = t->position.z; + } +} + +void AS_SetScale(uint32_t entity, float x, float y, float z) { + if (!g_registry) return; + if (auto* t = g_registry->try_get((entt::entity)entity)) { + t->scale = {x, y, z}; + } +} + +void AS_SetRotation(uint32_t entity, float rotation) { + if (!g_registry) return; + if (auto* t = g_registry->try_get((entt::entity)entity)) { + t->rotation = rotation; + } +} + +float AS_GetRotation(uint32_t entity) { + if (!g_registry) return 0.0f; + if (auto* t = g_registry->try_get((entt::entity)entity)) { + return t->rotation; + } + return 0.0f; +} + +bool AS_HasTransform(uint32_t entity) { + if (!g_registry) return false; + return g_registry->all_of((entt::entity)entity); +} + +void AS_RemoveTransform(uint32_t entity) { + if (!g_registry) return; + g_registry->remove((entt::entity)entity); +} + +// === Velocity Component === + +void AS_AddVelocity(uint32_t entity, float vx, float vy, float vz, float angular) { + if (!g_registry) return; + g_registry->emplace((entt::entity)entity, Vector3{vx, vy, vz}, angular); +} + +void AS_SetVelocity(uint32_t entity, float vx, float vy, float vz) { + if (!g_registry) return; + if (auto* v = g_registry->try_get((entt::entity)entity)) { + v->linear = {vx, vy, vz}; + } +} + +void AS_SetAngularVelocity(uint32_t entity, float angular) { + if (!g_registry) return; + if (auto* v = g_registry->try_get((entt::entity)entity)) { + v->angular = angular; + } +} + +bool AS_HasVelocity(uint32_t entity) { + if (!g_registry) return false; + return g_registry->all_of((entt::entity)entity); +} + +void AS_RemoveVelocity(uint32_t entity) { + if (!g_registry) return; + g_registry->remove((entt::entity)entity); +} + +// === Sprite Component === + +void AS_AddSprite(uint32_t entity, int modelId, uint32_t color, float outlineSize) { + if (!g_registry) return; + Color col; + col.r = (color >> 24) & 0xFF; + col.g = (color >> 16) & 0xFF; + col.b = (color >> 8) & 0xFF; + col.a = color & 0xFF; + g_registry->emplace((entt::entity)entity, modelId, col, outlineSize); +} + +void AS_SetSpriteColor(uint32_t entity, uint32_t color) { + if (!g_registry) return; + if (auto* s = g_registry->try_get((entt::entity)entity)) { + s->color.r = (color >> 24) & 0xFF; + s->color.g = (color >> 16) & 0xFF; + s->color.b = (color >> 8) & 0xFF; + s->color.a = color & 0xFF; + } +} + +void AS_SetSpriteModel(uint32_t entity, int modelId) { + if (!g_registry) return; + if (auto* s = g_registry->try_get((entt::entity)entity)) { + s->modelId = modelId; + } +} + +void AS_SetSpriteOutline(uint32_t entity, float outlineSize) { + if (!g_registry) return; + if (auto* s = g_registry->try_get((entt::entity)entity)) { + s->outlineSize = outlineSize; + } +} + +bool AS_HasSprite(uint32_t entity) { + if (!g_registry) return false; + return g_registry->all_of((entt::entity)entity); +} + +void AS_RemoveSprite(uint32_t entity) { + if (!g_registry) return; + g_registry->remove((entt::entity)entity); +} + +// === Tag Component === + +void AS_AddTag(uint32_t entity, const std::string& name) { + if (!g_registry) return; + g_registry->emplace((entt::entity)entity, name); +} + +std::string AS_GetTag(uint32_t entity) { + if (!g_registry) return ""; + if (auto* t = g_registry->try_get((entt::entity)entity)) { + return t->name; + } + return ""; +} + +void AS_SetTag(uint32_t entity, const std::string& name) { + if (!g_registry) return; + if (auto* t = g_registry->try_get((entt::entity)entity)) { + t->name = name; + } +} + +bool AS_HasTag(uint32_t entity) { + if (!g_registry) return false; + return g_registry->all_of((entt::entity)entity); +} + +void AS_RemoveTag(uint32_t entity) { + if (!g_registry) return; + g_registry->remove((entt::entity)entity); +} + +// === Registration === + +void RegisterECSBindings(asIScriptEngine *engine) { + int r; + + engine->SetDefaultNamespace("ECS"); + + // Entity management + r = engine->RegisterGlobalFunction("uint CreateEntity()", + asFUNCTION(AS_CreateEntity), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void DestroyEntity(uint)", + asFUNCTION(AS_DestroyEntity), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("bool IsValid(uint)", + asFUNCTION(AS_IsEntityValid), asCALL_CDECL); + assert(r >= 0); + + // Transform component + r = engine->RegisterGlobalFunction("void AddTransform(uint, float, float, float)", + asFUNCTION(AS_AddTransform), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void SetPosition(uint, float, float, float)", + asFUNCTION(AS_SetPosition), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void GetPosition(uint, float &out, float &out, float &out)", + asFUNCTION(AS_GetPosition), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void SetScale(uint, float, float, float)", + asFUNCTION(AS_SetScale), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void SetRotation(uint, float)", + asFUNCTION(AS_SetRotation), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("float GetRotation(uint)", + asFUNCTION(AS_GetRotation), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("bool HasTransform(uint)", + asFUNCTION(AS_HasTransform), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void RemoveTransform(uint)", + asFUNCTION(AS_RemoveTransform), asCALL_CDECL); + assert(r >= 0); + + // Velocity component + r = engine->RegisterGlobalFunction("void AddVelocity(uint, float, float, float, float = 0.0f)", + asFUNCTION(AS_AddVelocity), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void SetVelocity(uint, float, float, float)", + asFUNCTION(AS_SetVelocity), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void SetAngularVelocity(uint, float)", + asFUNCTION(AS_SetAngularVelocity), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("bool HasVelocity(uint)", + asFUNCTION(AS_HasVelocity), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void RemoveVelocity(uint)", + asFUNCTION(AS_RemoveVelocity), asCALL_CDECL); + assert(r >= 0); + + // Sprite component + r = engine->RegisterGlobalFunction("void AddSprite(uint, int, uint, float = 0.0f)", + asFUNCTION(AS_AddSprite), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void SetSpriteColor(uint, uint)", + asFUNCTION(AS_SetSpriteColor), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void SetSpriteModel(uint, int)", + asFUNCTION(AS_SetSpriteModel), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void SetSpriteOutline(uint, float)", + asFUNCTION(AS_SetSpriteOutline), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("bool HasSprite(uint)", + asFUNCTION(AS_HasSprite), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void RemoveSprite(uint)", + asFUNCTION(AS_RemoveSprite), asCALL_CDECL); + assert(r >= 0); + + // Tag component + r = engine->RegisterGlobalFunction("void AddTag(uint, const string &in)", + asFUNCTION(AS_AddTag), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("string GetTag(uint)", + asFUNCTION(AS_GetTag), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void SetTag(uint, const string &in)", + asFUNCTION(AS_SetTag), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("bool HasTag(uint)", + asFUNCTION(AS_HasTag), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void RemoveTag(uint)", + asFUNCTION(AS_RemoveTag), asCALL_CDECL); + assert(r >= 0); + + engine->SetDefaultNamespace(""); +} diff --git a/src/scripting/ScriptBindings.cpp b/src/scripting/ScriptBindings.cpp index d61fa91..707e647 100644 --- a/src/scripting/ScriptBindings.cpp +++ b/src/scripting/ScriptBindings.cpp @@ -1,18 +1,18 @@ #include "scripting/ScriptBindings.h" #include "scripting/ToastBindings.h" #include "scripting/LogBindings.h" -#include "scripting/DrawBindings.h" #include "scripting/ImageBindings.h" #include "scripting/TextureBindings.h" #include "scripting/MathBindings.h" +#include "scripting/ECSBindings.h" void ScriptBindings::RegisterAll(asIScriptEngine *engine) { // Delegate to separate binding files RegisterToastBindings(engine); RegisterLogBindings(engine); - RegisterDrawBindings(engine); RegisterImageBindings(engine); RegisterTextureBindings(engine); RegisterMathBindings(engine); + RegisterECSBindings(engine); } \ No newline at end of file diff --git a/src/scripting/ScriptEngine.cpp b/src/scripting/ScriptEngine.cpp index c64195b..f44a8be 100644 --- a/src/scripting/ScriptEngine.cpp +++ b/src/scripting/ScriptEngine.cpp @@ -2,6 +2,7 @@ #include "scripting/ScriptBindings.h" #include "scriptstdstring.h" #include "scriptbuilder.h" +#include "scriptarray.h" #include #include #include @@ -11,7 +12,7 @@ #include #include -ScriptEngine::ScriptEngine() : engine(nullptr), updateFunc(nullptr), drawFunc(nullptr), initFunc(nullptr), shutdownFunc(nullptr),currentModule(nullptr), hasValidScript(false) { +ScriptEngine::ScriptEngine() : engine(nullptr), updateFunc(nullptr), initFunc(nullptr), shutdownFunc(nullptr),currentModule(nullptr), hasValidScript(false) { } ScriptEngine::~ScriptEngine() { @@ -28,6 +29,9 @@ bool ScriptEngine::Initialize() { // Register std::string RegisterStdString(engine); + // Register array template + RegisterScriptArray(engine, true); + // Register script bindings ScriptBindings::RegisterAll(engine); @@ -164,7 +168,6 @@ bool ScriptEngine::CompileScript(const std::string& filename) { // Cache new functions initFunc = currentModule->GetFunctionByName("Init"); updateFunc = currentModule->GetFunctionByName("Update"); - drawFunc = currentModule->GetFunctionByName("Draw"); shutdownFunc = currentModule->GetFunctionByName("Shutdown"); hasValidScript = true; log_info("Script compiled and cached: %s", filename.c_str()); @@ -199,7 +202,6 @@ void ScriptEngine::CallScriptFunction(asIScriptFunction* func, float dt) { void ScriptEngine::ClearCachedFunctions() { updateFunc = nullptr; - drawFunc = nullptr; hasValidScript = false; } diff --git a/src/scripting/TextureBindings.cpp b/src/scripting/TextureBindings.cpp index 48f6b0e..b4905ff 100644 --- a/src/scripting/TextureBindings.cpp +++ b/src/scripting/TextureBindings.cpp @@ -3,7 +3,16 @@ #include #include -Color ColorFromUInt(unsigned int c); +// Utility function to convert uint color to Raylib Color +Color ColorFromUInt(unsigned int c) +{ + Color col; + col.r = (c >> 24) & 0xFF; + col.g = (c >> 16) & 0xFF; + col.b = (c >> 8) & 0xFF; + col.a = c & 0xFF; + return col; +} Texture2D AS_LoadTexture(const std::string &filename) { diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 155b313..340f355 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -11,7 +11,7 @@ add_executable(unit_tests ${CMAKE_SOURCE_DIR}/src/scripting/ScriptBindings.cpp ${CMAKE_SOURCE_DIR}/src/scripting/ToastBindings.cpp ${CMAKE_SOURCE_DIR}/src/scripting/LogBindings.cpp - ${CMAKE_SOURCE_DIR}/src/scripting/DrawBindings.cpp + ${CMAKE_SOURCE_DIR}/src/scripting/ECSBindings.cpp ${CMAKE_SOURCE_DIR}/src/scripting/ImageBindings.cpp ${CMAKE_SOURCE_DIR}/src/scripting/TextureBindings.cpp ${CMAKE_SOURCE_DIR}/src/scripting/MathBindings.cpp @@ -25,6 +25,7 @@ target_include_directories(unit_tests PRIVATE ${CMAKE_SOURCE_DIR}/external/angelscript/sdk/angelscript/include ${CMAKE_SOURCE_DIR}/external/angelscript/sdk/add_on/scriptstdstring ${CMAKE_SOURCE_DIR}/external/angelscript/sdk/add_on/scriptbuilder + ${CMAKE_SOURCE_DIR}/external/angelscript/sdk/add_on/scriptarray ${CMAKE_SOURCE_DIR}/external/raylib/src ${CMAKE_SOURCE_DIR}/external/imgui ${CMAKE_SOURCE_DIR}/external/rlImGui @@ -36,6 +37,7 @@ target_link_libraries(unit_tests PRIVATE angelscript scriptstdstring scriptbuilder + scriptarray raylib imgui ) From 766f7ecd7aefd4b9aca794c8647ad22c11cd6997 Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Fri, 6 Mar 2026 09:45:29 +1300 Subject: [PATCH 16/53] fix: include all tests --- tests/CMakeLists.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 340f355..8cb4e06 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -42,4 +42,8 @@ target_link_libraries(unit_tests PRIVATE imgui ) -add_test(NAME unit_tests COMMAND unit_tests) \ No newline at end of file +add_test(NAME unit_tests COMMAND unit_tests) +add_test(NAME hotreload_dir COMMAND unit_tests hotreload_dir) +add_test(NAME script_compile COMMAND unit_tests script_compile) +add_test(NAME script_include COMMAND unit_tests script_include) +add_test(NAME math_bindings COMMAND unit_tests math_bindings) \ No newline at end of file From 670f65b37b813aed27b873728af7553f8125c6a4 Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Fri, 6 Mar 2026 11:24:28 +1300 Subject: [PATCH 17/53] fix: rendering on linux and toon shader --- scripts/as.predefined | 2 +- scripts/game.as | 4 +- shaders/toon.fs | 19 ++++----- shaders/toon.vs | 24 +++++++---- src/Application.cpp | 98 +++++++++++++++++++++++++++---------------- 5 files changed, 89 insertions(+), 58 deletions(-) diff --git a/scripts/as.predefined b/scripts/as.predefined index b26ad4b..e4d5951 100644 --- a/scripts/as.predefined +++ b/scripts/as.predefined @@ -2,7 +2,7 @@ typedef void string; string format(const string&in fmt, const ?&in ...); // Array template (provided by scriptarray add-on) -external shared interface array { +external shared class array { uint length() const; void resize(uint); void insertAt(uint, const T&in); diff --git a/scripts/game.as b/scripts/game.as index 01cc269..db6e4f4 100644 --- a/scripts/game.as +++ b/scripts/game.as @@ -14,7 +14,7 @@ void Init() { // Create a player entity at origin player = ECS::CreateEntity(); ECS::AddTransform(player, 0.0f, 0.0f, 0.0f); - ECS::AddSprite(player, 0, 0xFF0000FF, 0.0f); // Red cube, model 0 + ECS::AddSprite(player, 1, 0xFF0000FF, 0.0f); // Red cube, model 0 ECS::AddTag(player, "Player"); Log(LOG_INFO, "Created player entity: " + player); @@ -45,7 +45,7 @@ void Init() { else if (i == 3) color = 0xFFA500FF; // Orange else color = 0xFF69B4FF; // Pink - ECS::AddSprite(entity, 0, color, 0.0f); + ECS::AddSprite(entity, 1, color, 0.0f); ECS::AddTag(entity, "Orbiter" + i); entities.insertLast(entity); diff --git a/shaders/toon.fs b/shaders/toon.fs index 4e52669..f3d8705 100644 --- a/shaders/toon.fs +++ b/shaders/toon.fs @@ -3,23 +3,20 @@ in vec3 fragNormal; in vec3 fragPosition; -uniform vec3 lightDir; -uniform float bandCount; uniform vec4 albedo; out vec4 fragColor; void main() { - // Normalize the normal and light direction + // Hardcoded values since uniforms get optimized out + vec3 lightDir = normalize(vec3(0.5, 0.7, 0.3)); + float bandCount = 3.0; + vec3 normal = normalize(fragNormal); vec3 light = normalize(lightDir); - - // Calculate the dot product for lighting + float intensity = max(dot(normal, light), 0.0); - - // Quantize the intensity for toon shading intensity = floor(intensity * bandCount) / bandCount; - - // Set the fragment color - //fragColor = vec4(vec3(intensity), 1.0); - fragColor = vec4(albedo.rgb , albedo.a); + intensity = max(intensity, 0.3); // Minimum visibility + + fragColor = vec4(albedo.rgb * intensity, albedo.a); } \ No newline at end of file diff --git a/shaders/toon.vs b/shaders/toon.vs index bddb0af..5564e00 100644 --- a/shaders/toon.vs +++ b/shaders/toon.vs @@ -1,17 +1,27 @@ #version 330 +// Raylib's default attribute locations layout(location = 0) in vec3 vertexPosition; -layout(location = 1) in vec3 vertexNormal; +layout(location = 1) in vec2 vertexTexCoord; +layout(location = 2) in vec3 vertexNormal; +layout(location = 3) in vec4 vertexColor; -uniform mat4 model; -uniform mat4 view; -uniform mat4 projection; +// Raylib's built-in uniforms (automatically provided) +uniform mat4 mvp; // Model-View-Projection matrix +uniform mat4 matModel; // Model matrix +uniform mat4 matNormal; // Normal matrix for transforming normals out vec3 fragNormal; out vec3 fragPosition; void main() { - fragPosition = vec3(model * vec4(vertexPosition, 1.0)); - fragNormal = mat3(transpose(inverse(model))) * vertexNormal; // Transform normals - gl_Position = projection * view * vec4(fragPosition, 1.0); + // Transform position + vec4 worldPos = matModel * vec4(vertexPosition, 1.0); + fragPosition = worldPos.xyz; + + // Transform normal properly + fragNormal = normalize(vec3(matNormal * vec4(vertexNormal, 0.0))); + + // Final position + gl_Position = mvp * vec4(vertexPosition, 1.0); } \ No newline at end of file diff --git a/src/Application.cpp b/src/Application.cpp index aee6863..d10f2c8 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -24,14 +24,8 @@ const char *Application::WINDOW_TITLE = "Simian"; const char *Application::SCRIPT_FILE = "scripts/game.as"; -Application::Application() - : hotReload(nullptr) - , scriptCompilationError(false) - , logFile(nullptr) - , renderTexture{} - , lightDir{0.5f, 0.7f, 0.3f} - , globalBandCount(3.0f) - , dayMode(true) +Application::Application() + : hotReload(nullptr), scriptCompilationError(false), logFile(nullptr), renderTexture{}, lightDir{0.5f, 0.7f, 0.3f}, globalBandCount(3.0f), dayMode(true) { } @@ -105,17 +99,37 @@ bool Application::Initialize(int argc, char *argv[]) camera.target = {0, 0, 0}; camera.up = {0, 1, 0}; camera.fovy = 45; + camera.projection = CAMERA_PERSPECTIVE; // ADD THIS LINE! // Load models Model cube = LoadModelFromMesh(GenMeshCube(1, 1, 1)); - - // Load shaders - toonShader = LoadShader(0, "shaders/toon.fs"); - + Model sphere = LoadModelFromMesh(GenMeshSphere(0.5f, 16, 16)); + + // Load shaders (use both vertex and fragment shader files explicitly) + toonShader = LoadShader("shaders/toon.vs", "shaders/toon.fs"); + if (toonShader.id == 0) { + log_warn("Failed to load toon shader (id=0). Check shader paths and GL support."); + } else { + log_info("Loaded toon shader id=%d", toonShader.id); + + // Verify shader locations exist + int lightLoc = GetShaderLocation(toonShader, "lightDir"); + int bandLoc = GetShaderLocation(toonShader, "bandCount"); + int albedoLoc = GetShaderLocation(toonShader, "albedo"); + + log_info("Shader locations: lightDir=%d, bandCount=%d, albedo=%d", lightLoc, bandLoc, albedoLoc); + + if (lightLoc == -1 || bandLoc == -1 || albedoLoc == -1) { + log_warn("Some shader uniforms not found - shader may not work correctly"); + } + } + // Assign shader to cube material cube.materials[0].shader = toonShader; - + sphere.materials[0].shader = toonShader; + models.push_back(cube); + models.push_back(sphere); return true; } @@ -173,38 +187,46 @@ void Application::UpdateSystems(float deltaTime) { // Movement system - apply velocity to transform auto view = registry.view(); - for (auto entity : view) - { - auto& transform = view.get(entity); - auto& velocity = view.get(entity); - + view.each([deltaTime](auto &transform, auto &velocity) + { // Apply linear velocity transform.position.x += velocity.linear.x * deltaTime; transform.position.y += velocity.linear.y * deltaTime; transform.position.z += velocity.linear.z * deltaTime; // Apply angular velocity - transform.rotation += velocity.angular * deltaTime; - } + transform.rotation += velocity.angular * deltaTime; }); } void Application::RenderScene() { - BeginMode3D(camera); - + BeginMode3D(camera); DrawGrid(10, 1); - DrawLine3D(Vector3{0, 0, 0}, Vector3{lightDir.x * 5.0f, lightDir.y * 5.0f, lightDir.z * 5.0f}, RED); - - // Render all entities with ECSTransform and Sprite components - BeginShaderMode(toonShader); - SetShaderValue(toonShader, GetShaderLocation(toonShader, "lightDir"), &lightDir, SHADER_UNIFORM_VEC3); - SetShaderValue(toonShader, GetShaderLocation(toonShader, "bandCount"), &globalBandCount, SHADER_UNIFORM_FLOAT); + BeginShaderMode(toonShader); + + // Get shader locations once + int lightLoc = GetShaderLocation(toonShader, "lightDir"); + int bandLoc = GetShaderLocation(toonShader, "bandCount"); + int albedoLoc = GetShaderLocation(toonShader, "albedo"); + auto view = registry.view(); - for (auto entity : view) + + view.each([&](auto &transform, auto &sprite) { - const auto& transform = view.get(entity); - const auto& sprite = view.get(entity); + // Validate model index + // if (sprite.modelId < 0 || sprite.modelId >= models.size()) { + // return; + // } + + // Set ALL uniforms before each draw call + if (lightLoc != -1) { + SetShaderValue(toonShader, lightLoc, &lightDir, SHADER_UNIFORM_VEC3); + } + + if (bandLoc != -1) { + SetShaderValue(toonShader, bandLoc, &globalBandCount, SHADER_UNIFORM_FLOAT); + } // Set color for this entity Vector4 color = { @@ -213,18 +235,20 @@ void Application::RenderScene() sprite.color.b / 255.0f, sprite.color.a / 255.0f }; - SetShaderValue(toonShader, GetShaderLocation(toonShader, "albedo"), &color, SHADER_UNIFORM_VEC4); - // Draw the model with transform + if (albedoLoc != -1) { + SetShaderValue(toonShader, albedoLoc, &color, SHADER_UNIFORM_VEC4); + } + + // Draw the model Model& model = models[sprite.modelId]; DrawModelEx(model, transform.position, Vector3{0, 1, 0}, transform.rotation * RAD2DEG, transform.scale, WHITE); - } - + }); + EndShaderMode(); EndMode3D(); } - void Application::Draw() { int screenWidth = GetScreenWidth(); @@ -283,7 +307,7 @@ void Application::Shutdown() scriptEngine.Shutdown(); // Unload assets - for (auto& model : models) + for (auto &model : models) { UnloadModel(model); } From 82886349ae1bc934ae0a5a910256175da40e67db Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Fri, 6 Mar 2026 14:32:25 +1300 Subject: [PATCH 18/53] feat: refactor to move more elements to the scripting layer --- CMakeLists.txt | 4 + include/Application.h | 15 +- include/ECSComponents.h | 52 ++++- include/MaterialManager.h | 44 +++++ include/ModelManager.h | 34 ++++ include/ShaderManager.h | 30 +++ include/scripting/ResourceBindings.h | 9 + scripts/as.predefined | 70 ++++++- scripts/example_rendering.as | 101 ++++++++++ scripts/game.as | 107 +++++++++-- shaders/outline.fs | 36 +--- shaders/outline.vs | 21 +++ src/Application.cpp | 272 +++++++++++++++++---------- src/MaterialManager.cpp | 76 ++++++++ src/ModelManager.cpp | 79 ++++++++ src/ShaderManager.cpp | 68 +++++++ src/scripting/ECSBindings.cpp | 249 ++++++++++++++++++++++++ src/scripting/ResourceBindings.cpp | 144 ++++++++++++++ src/scripting/ScriptBindings.cpp | 2 + tests/CMakeLists.txt | 4 + 20 files changed, 1261 insertions(+), 156 deletions(-) create mode 100644 include/MaterialManager.h create mode 100644 include/ModelManager.h create mode 100644 include/ShaderManager.h create mode 100644 include/scripting/ResourceBindings.h create mode 100644 scripts/example_rendering.as create mode 100644 shaders/outline.vs create mode 100644 src/MaterialManager.cpp create mode 100644 src/ModelManager.cpp create mode 100644 src/ShaderManager.cpp create mode 100644 src/scripting/ResourceBindings.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 40a0a36..69f1aa4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -97,10 +97,14 @@ add_executable(simian src/scripting/TextureBindings.cpp src/scripting/MathBindings.cpp src/scripting/ECSBindings.cpp + src/scripting/ResourceBindings.cpp src/HotReload.cpp src/gui/GuiManager.cpp src/gui/LogWindow.cpp src/log/log.c + src/ShaderManager.cpp + src/ModelManager.cpp + src/MaterialManager.cpp ) target_include_directories(simian PUBLIC diff --git a/include/Application.h b/include/Application.h index e4fcc4e..246326b 100644 --- a/include/Application.h +++ b/include/Application.h @@ -3,8 +3,10 @@ #include "HotReload.h" #include "gui/GuiManager.h" #include "raylib.h" +#include "ShaderManager.h" +#include "ModelManager.h" +#include "MaterialManager.h" #include -#include class Application { public: @@ -31,14 +33,11 @@ private: // ECS entt::registry registry; - std::vector models; - // Scene/rendering data - Camera3D camera; - Shader toonShader; - Vector3 lightDir; - float globalBandCount; - bool dayMode; + // Resource managers + ShaderManager shaderManager; + ModelManager modelManager; + MaterialManager materialManager; static const int WINDOW_WIDTH = 1280; static const int WINDOW_HEIGHT = 720; diff --git a/include/ECSComponents.h b/include/ECSComponents.h index d1b7c13..7aba09e 100644 --- a/include/ECSComponents.h +++ b/include/ECSComponents.h @@ -32,7 +32,7 @@ struct Velocity { // Sprite component - visual representation struct Sprite { - int modelId; // Index into models array + size_t modelId; // Index into models array Color color; // Tint color float outlineSize; // Outline thickness @@ -52,3 +52,53 @@ struct Tag { Tag() : name("") {} Tag(const std::string& n) : name(n) {} }; + +// Camera3D component - camera settings +struct Camera3DComponent { + Vector3 position; + Vector3 target; + Vector3 up; + float fovy; + int projection; // 0 = CAMERA_PERSPECTIVE, 1 = CAMERA_ORTHOGRAPHIC + + Camera3DComponent() + : position{0.0f, 10.0f, 10.0f} + , target{0.0f, 0.0f, 0.0f} + , up{0.0f, 1.0f, 0.0f} + , fovy(45.0f) + , projection(0) {} +}; + +// Light component - directional light +struct LightComponent { + Vector3 direction; + Color color; + float intensity; + + LightComponent() + : direction{0.5f, 0.7f, 0.3f} + , color(WHITE) + , intensity(1.0f) {} +}; + +// Material component - references shader and material managers +struct MaterialComponent { + unsigned int materialId; // ID in MaterialManager + + MaterialComponent() : materialId(0) {} + MaterialComponent(unsigned int id) : materialId(id) {} +}; + +// RenderPass component - controls rendering order and properties +struct RenderPassComponent { + int order; // Render order (lower = earlier) + bool depthTest; // Enable depth testing + bool depthWrite; // Enable depth writing + unsigned int shaderId; // Override shader for this pass (0 = use material shader) + + RenderPassComponent() + : order(0) + , depthTest(true) + , depthWrite(true) + , shaderId(0) {} +}; diff --git a/include/MaterialManager.h b/include/MaterialManager.h new file mode 100644 index 0000000..fc1b567 --- /dev/null +++ b/include/MaterialManager.h @@ -0,0 +1,44 @@ +#pragma once + +#include "raylib.h" +#include +#include + +struct MaterialData +{ + unsigned int shaderId; + Color albedo; + + MaterialData() : shaderId(0), albedo(WHITE) {} +}; + +class MaterialManager +{ +public: + MaterialManager(); + ~MaterialManager(); + + // Create a material with a shader ID + // Returns a unique ID for the material + unsigned int Create(unsigned int shaderId, Color albedo = WHITE); + + // Remove a material by ID + void Remove(unsigned int id); + + // Get material data by ID (returns nullptr if not found) + MaterialData* Get(unsigned int id); + + // Update material shader + void SetShader(unsigned int id, unsigned int shaderId); + + // Update material albedo + void SetAlbedo(unsigned int id, Color albedo); + + // Clear all materials + void Clear(); + +private: + std::unordered_map materials; + unsigned int nextId; + bool cleared; +}; diff --git a/include/ModelManager.h b/include/ModelManager.h new file mode 100644 index 0000000..834402b --- /dev/null +++ b/include/ModelManager.h @@ -0,0 +1,34 @@ +#pragma once + +#include "raylib.h" +#include +#include + +class ModelManager +{ +public: + ModelManager(); + ~ModelManager(); + + // Load a model from a file + // Returns a unique ID for the model, or 0 on failure + unsigned int Load(const std::string& path); + + // Load a model from a mesh + // Returns a unique ID for the model, or 0 on failure + unsigned int LoadFromMesh(Mesh mesh); + + // Unload a model by ID + void Unload(unsigned int id); + + // Get a model by ID (returns nullptr if not found) + Model* Get(unsigned int id); + + // Unload all models + void UnloadAll(); + +private: + std::unordered_map models; + unsigned int nextId; + bool unloaded; +}; diff --git a/include/ShaderManager.h b/include/ShaderManager.h new file mode 100644 index 0000000..860aedf --- /dev/null +++ b/include/ShaderManager.h @@ -0,0 +1,30 @@ +#pragma once + +#include "raylib.h" +#include +#include + +class ShaderManager +{ +public: + ShaderManager(); + ~ShaderManager(); + + // Load a shader from vertex and fragment shader files + // Returns a unique ID for the shader, or 0 on failure + unsigned int Load(const std::string& vsPath, const std::string& fsPath); + + // Unload a shader by ID + void Unload(unsigned int id); + + // Get a shader by ID (returns nullptr if not found) + Shader* Get(unsigned int id); + + // Unload all shaders + void UnloadAll(); + +private: + std::unordered_map shaders; + unsigned int nextId; + bool unloaded; +}; diff --git a/include/scripting/ResourceBindings.h b/include/scripting/ResourceBindings.h new file mode 100644 index 0000000..c76c467 --- /dev/null +++ b/include/scripting/ResourceBindings.h @@ -0,0 +1,9 @@ +#pragma once + +class asIScriptEngine; +class ShaderManager; +class ModelManager; +class MaterialManager; + +void SetResourceManagers(ShaderManager* shaderMgr, ModelManager* modelMgr, MaterialManager* materialMgr); +void RegisterResourceBindings(asIScriptEngine *engine); diff --git a/scripts/as.predefined b/scripts/as.predefined index e4d5951..7153935 100644 --- a/scripts/as.predefined +++ b/scripts/as.predefined @@ -69,6 +69,59 @@ namespace ECS { void SetTag(uint entity, const string &in name); bool HasTag(uint entity); void RemoveTag(uint entity); + + // Camera3D component + void AddCamera3D(uint entity, float px, float py, float pz, float tx, float ty, float tz, float fovy); + void SetCameraPosition(uint entity, float x, float y, float z); + void SetCameraTarget(uint entity, float x, float y, float z); + void SetCameraFovy(uint entity, float fovy); + bool HasCamera3D(uint entity); + void RemoveCamera3D(uint entity); + + // Light component + void AddLight(uint entity, float dx, float dy, float dz, float intensity = 1.0f); + void SetLightDirection(uint entity, float x, float y, float z); + void SetLightIntensity(uint entity, float intensity); + void SetLightColor(uint entity, uint color); + bool HasLight(uint entity); + void RemoveLight(uint entity); + + // Material component + void AddMaterial(uint entity, uint materialId); + void SetMaterialId(uint entity, uint materialId); + uint GetMaterialId(uint entity); + bool HasMaterial(uint entity); + void RemoveMaterial(uint entity); + + // RenderPass component + void AddRenderPass(uint entity, int order, bool depthTest, bool depthWrite, uint shaderId); + void SetRenderPassOrder(uint entity, int order); + void SetRenderPassShader(uint entity, uint shaderId); + bool HasRenderPass(uint entity); + void RemoveRenderPass(uint entity); +} + +// Shader resource management +namespace Shader { + uint Load(const string &in vsPath, const string &in fsPath); + void Unload(uint id); +} + +// Model resource management +namespace Model { + uint Load(const string &in path); + uint LoadCube(float width, float height, float length); + uint LoadSphere(float radius, int rings, int slices); + uint LoadPlane(float width, float length, int resX, int resZ); + void Unload(uint id); +} + +// Material resource management +namespace Material { + uint Create(uint shaderId, uint8 r, uint8 g, uint8 b, uint8 a); + void Remove(uint id); + void SetShader(uint id, uint shaderId); + void SetAlbedo(uint id, uint8 r, uint8 g, uint8 b, uint8 a); } namespace Texture { @@ -110,4 +163,19 @@ namespace Math { float Ceil(float value); float Modf(float x, float y); float Abs(float value); -} \ No newline at end of file +} + +// Raylib input and timing functions +float GetTime(); +bool IsKeyPressed(int key); + +// Raylib key constants +const int KEY_SPACE = 32; +const int KEY_ESCAPE = 256; +const int KEY_ENTER = 257; +const int KEY_TAB = 258; +const int KEY_BACKSPACE = 259; +const int KEY_RIGHT = 262; +const int KEY_LEFT = 263; +const int KEY_DOWN = 264; +const int KEY_UP = 265; diff --git a/scripts/example_rendering.as b/scripts/example_rendering.as new file mode 100644 index 0000000..cc2b00c --- /dev/null +++ b/scripts/example_rendering.as @@ -0,0 +1,101 @@ +// Example script showing how to use the new script-driven rendering system + +// Global variables to track our resources +uint g_toonShader = 0; +uint g_outlineShader = 0; +uint g_cubeModel = 0; +uint g_sphereModel = 0; +uint g_redMaterial = 0; +uint g_blueMaterial = 0; + +// Entities +uint g_camera = 0; +uint g_light = 0; +uint g_cube = 0; +uint g_sphere = 0; + +void Init() { + Toast::Info("Initializing script-driven rendering..."); + + // === Load Shaders === + g_toonShader = Shader::Load("shaders/toon.vs", "shaders/toon.fs"); + g_outlineShader = Shader::Load("shaders/outline.vs", "shaders/outline.fs"); + + if (g_toonShader == 0 || g_outlineShader == 0) { + Toast::Error("Failed to load shaders!"); + return; + } + + // === Load Models === + g_cubeModel = Model::LoadCube(1.0, 1.0, 1.0); + g_sphereModel = Model::LoadSphere(0.5, 16, 16); + + // === Create Materials === + // Red material with toon shader + g_redMaterial = Material::Create(g_toonShader, 255, 100, 100, 255); + + // Blue material with toon shader + g_blueMaterial = Material::Create(g_toonShader, 100, 100, 255, 255); + + // === Set up Camera === + g_camera = ECS::CreateEntity(); + ECS::AddCamera3D(g_camera, + 5.0, 5.0, 5.0, // position + 0.0, 0.0, 0.0, // target + 45.0); // fovy + ECS::AddTag(g_camera, "MainCamera"); + + // === Set up Light === + g_light = ECS::CreateEntity(); + ECS::AddLight(g_light, 0.5, 0.7, 0.3, 1.0); // direction + intensity + ECS::AddTag(g_light, "MainLight"); + + // === Create Cube with Outline === + g_cube = ECS::CreateEntity(); + ECS::AddTransform(g_cube, -1.5, 0.5, 0.0); + ECS::AddSprite(g_cube, g_cubeModel, 0xFFFFFFFF, 0.0); + ECS::AddMaterial(g_cube, g_redMaterial); + ECS::AddTag(g_cube, "Cube"); + ECS::AddVelocity(g_cube, 0.0, 0.0, 0.0, 1.0); // rotating + + // Add outline render pass (order 0 = first) + ECS::AddRenderPass(g_cube, 0, false, true, g_outlineShader); // order=0, no depth test + + // === Create Sphere === + g_sphere = ECS::CreateEntity(); + ECS::AddTransform(g_sphere, 1.5, 0.5, 0.0); + ECS::AddSprite(g_sphere, g_sphereModel, 0xFFFFFFFF, 0.0); + ECS::AddMaterial(g_sphere, g_blueMaterial); + ECS::AddTag(g_sphere, "Sphere"); + ECS::AddVelocity(g_sphere, 0.5, 0.0, 0.2, 0.5); // moving and rotating + + // Add main render pass (order 1 = second, after outlines) + ECS::AddRenderPass(g_sphere, 1, true, true, 0); // order=1, with depth test + + Toast::Success("Script-driven rendering initialized!"); +} +bool lightToggle = false; +void Update(float dt) { + // Camera orbital movement + if (ECS::HasCamera3D(g_camera)) { + float angle = GetTime() * 0.3; + float radius = 7.0; + float x = Math::Cos(angle) * radius; + float z = Math::Sin(angle) * radius; + ECS::SetCameraPosition(g_camera, x, 5.0, z); + } + + // Example: Toggle light direction with space + if (IsKeyPressed(KEY_SPACE)) { + + lightToggle = !lightToggle; + + if (lightToggle) { + ECS::SetLightDirection(g_light, -0.5, 0.7, -0.3); + Toast::Info("Light direction changed!"); + } else { + ECS::SetLightDirection(g_light, 0.5, 0.7, 0.3); + Toast::Info("Light direction reset!"); + } + } +} diff --git a/scripts/game.as b/scripts/game.as index db6e4f4..049875d 100644 --- a/scripts/game.as +++ b/scripts/game.as @@ -1,5 +1,16 @@ -// ECS-based game script demo -// This demonstrates creating entities with various components +// ECS-based game script demo with script-driven rendering +// This demonstrates creating entities with various components and managing rendering + +// Resource IDs +uint g_toonShader = 0; +uint g_outlineShader = 0; +uint g_cubeModel = 0; +uint g_sphereModel = 0; +uint g_defaultMaterial = 0; + +// Scene entities +uint g_camera = 0; +uint g_light = 0; // Store entity IDs for manipulation array entities; @@ -8,25 +19,67 @@ uint spinningCube; float time = 0.0f; void Init() { - Log(LOG_TRACE, "Initialization complete - ECS Demo!"); + Log(LOG_TRACE, "Initialization complete - ECS Demo with Script-Driven Rendering!"); Toast::Success("ECS Script initialized successfully!"); - // Create a player entity at origin + // === Load shaders === + g_toonShader = Shader::Load("shaders/toon.vs", "shaders/toon.fs"); + g_outlineShader = Shader::Load("shaders/outline.vs", "shaders/outline.fs"); + + if (g_toonShader == 0 || g_outlineShader == 0) { + Toast::Error("Failed to load shaders!"); + return; + } + + // === Load models === + g_cubeModel = Model::LoadCube(1.0, 1.0, 1.0); + g_sphereModel = Model::LoadSphere(0.5, 16, 16); + + // === Create default material === + g_defaultMaterial = Material::Create(g_toonShader, 255, 255, 255, 255); + + // === Set up camera === + g_camera = ECS::CreateEntity(); + ECS::AddCamera3D(g_camera, + 5.0, 5.0, 5.0, // position + 0.0, 0.0, 0.0, // target + 45.0); // fovy + ECS::AddTag(g_camera, "MainCamera"); + + // === Set up light === + g_light = ECS::CreateEntity(); + ECS::AddLight(g_light, 0.5, 0.7, 0.3, 1.0); // direction + intensity + ECS::AddTag(g_light, "MainLight"); + + // === Create player entity at origin with outline === player = ECS::CreateEntity(); ECS::AddTransform(player, 0.0f, 0.0f, 0.0f); - ECS::AddSprite(player, 1, 0xFF0000FF, 0.0f); // Red cube, model 0 + ECS::AddSprite(player, g_sphereModel, 0xFF0000FF, 0.0f); // Red sphere + + // Create material for player + uint playerMat = Material::Create(g_toonShader, 255, 0, 0, 255); + ECS::AddMaterial(player, playerMat); + + // Add outline pass (order=0) and main pass (order=1) + ECS::AddRenderPass(player, 0, false, true, g_outlineShader); + ECS::AddTag(player, "Player"); Log(LOG_INFO, "Created player entity: " + player); - // Create a spinning cube + // === Create a spinning cube === spinningCube = ECS::CreateEntity(); ECS::AddTransform(spinningCube, 2.0f, 0.0f, 0.0f); - ECS::AddSprite(spinningCube, 0, 0x00FF00FF, 0.0f); // Green cube + ECS::AddSprite(spinningCube, g_cubeModel, 0x00FF00FF, 0.0f); // Green cube ECS::AddVelocity(spinningCube, 0.0f, 0.0f, 0.0f, 2.0f); // Angular velocity + + uint greenMat = Material::Create(g_toonShader, 0, 255, 0, 255); + ECS::AddMaterial(spinningCube, greenMat); + ECS::AddRenderPass(spinningCube, 1, true, true, 0); // Main pass + ECS::AddTag(spinningCube, "Spinner"); Log(LOG_INFO, "Created spinning cube: " + spinningCube); - // Create orbiting entities + // === Create orbiting entities === for (int i = 0; i < 5; i++) { uint entity = ECS::CreateEntity(); @@ -39,27 +92,36 @@ void Init() { // Different colors for each uint color = 0; - if (i == 0) color = 0xFFFF00FF; // Yellow - else if (i == 1) color = 0xFF00FFFF; // Magenta - else if (i == 2) color = 0x00FFFFFF; // Cyan - else if (i == 3) color = 0xFFA500FF; // Orange - else color = 0xFF69B4FF; // Pink + uint8 r = 255, g = 255, b = 255; + if (i == 0) { color = 0xFFFF00FF; r = 255; g = 255; b = 0; } // Yellow + else if (i == 1) { color = 0xFF00FFFF; r = 255; g = 0; b = 255; } // Magenta + else if (i == 2) { color = 0x00FFFFFF; r = 0; g = 255; b = 255; } // Cyan + else if (i == 3) { color = 0xFFA500FF; r = 255; g = 165; b = 0; } // Orange + else { color = 0xFF69B4FF; r = 255; g = 105; b = 180; } // Pink + + ECS::AddSprite(entity, g_sphereModel, color, 0.0f); + + uint mat = Material::Create(g_toonShader, r, g, b, 255); + ECS::AddMaterial(entity, mat); + ECS::AddRenderPass(entity, 1, true, true, 0); - ECS::AddSprite(entity, 1, color, 0.0f); ECS::AddTag(entity, "Orbiter" + i); - entities.insertLast(entity); } - // Create a moving entity + // === Create a moving entity === uint mover = ECS::CreateEntity(); ECS::AddTransform(mover, -3.0f, 0.5f, 0.0f); - ECS::AddSprite(mover, 0, 0xFFFFFFFF, 0.0f); // White cube + ECS::AddSprite(mover, g_cubeModel, 0xFFFFFFFF, 0.0f); // White cube ECS::AddVelocity(mover, 1.0f, 0.0f, 0.5f, 0.0f); // Moving velocity + + ECS::AddMaterial(mover, g_defaultMaterial); + ECS::AddRenderPass(mover, 1, true, true, 0); + ECS::AddTag(mover, "Mover"); entities.insertLast(mover); - Toast::Success("Created " + (entities.length() + 3) + " entities!"); + Toast::Success("Created " + (entities.length() + 2) + " entities with script-driven rendering!"); } void Shutdown() { @@ -69,6 +131,15 @@ void Shutdown() { void Update(float dt) { time += dt; + // Update camera to orbit around the scene + if (ECS::HasCamera3D(g_camera)) { + float angle = time * 0.3; + float radius = 7.0; + float x = Math::Cos(angle) * radius; + float z = Math::Sin(angle) * radius; + ECS::SetCameraPosition(g_camera, x, 5.0, z); + } + // Update player position - simple back and forth motion float playerX = Math::Sin(time) * 2.0f; ECS::SetPosition(player, playerX, 0.0f, 0.0f); diff --git a/shaders/outline.fs b/shaders/outline.fs index 5211863..7cdc0d5 100644 --- a/shaders/outline.fs +++ b/shaders/outline.fs @@ -1,37 +1,9 @@ #version 330 -uniform sampler2D texture0; -uniform vec2 textureSize; -uniform int outlineSize = 2; +out vec4 fragColor; -in vec2 fragTexCoord; -out vec4 finalColor; +uniform vec4 outlineColor; // Color of the outline void main() { - vec2 texel = 1.0 / textureSize; - float center = texture(texture0, fragTexCoord).r; - - if (center < 0.5) { - discard; // Transparent, show scene underneath - return; - } - - // Edge detection - bool edge = false; - for (int y = -outlineSize; y <= outlineSize; y++) { - for (int x = -outlineSize; x <= outlineSize; x++) { - vec2 offset = vec2(float(x), float(y)) * texel; - if (texture(texture0, fragTexCoord + offset).r < 0.5) { - edge = true; - break; - } - } - if (edge) break; - } - - if (edge) { - finalColor = vec4(0, 0, 0, 1); // Black outline - } else { - discard; - } -} + fragColor = outlineColor; +} \ No newline at end of file diff --git a/shaders/outline.vs b/shaders/outline.vs new file mode 100644 index 0000000..a83baa8 --- /dev/null +++ b/shaders/outline.vs @@ -0,0 +1,21 @@ +#version 330 + +layout(location = 0) in vec3 vertexPosition; +layout(location = 2) in vec3 vertexNormal; + +uniform mat4 mvp; +uniform mat4 matModel; +uniform mat4 matNormal; +uniform float outlineThickness; + +void main() { + // Transform normal to world space + vec3 worldNormal = normalize(vec3(matNormal * vec4(vertexNormal, 0.0))); + + // Expand vertices along normals in world space + vec3 worldPos = vec3(matModel * vec4(vertexPosition, 1.0)); + vec3 expandedPos = worldPos + worldNormal * outlineThickness; + + // Transform to clip space + gl_Position = mvp * vec4(vertexPosition + vertexNormal * outlineThickness, 1.0); +} \ No newline at end of file diff --git a/src/Application.cpp b/src/Application.cpp index d10f2c8..c22ce6f 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -1,7 +1,9 @@ #include "Application.h" #include "ECSComponents.h" #include "scripting/ECSBindings.h" +#include "scripting/ResourceBindings.h" #include "raylib.h" +#include "rlgl.h" #include #include #include @@ -25,7 +27,7 @@ const char *Application::WINDOW_TITLE = "Simian"; const char *Application::SCRIPT_FILE = "scripts/game.as"; Application::Application() - : hotReload(nullptr), scriptCompilationError(false), logFile(nullptr), renderTexture{}, lightDir{0.5f, 0.7f, 0.3f}, globalBandCount(3.0f), dayMode(true) + : hotReload(nullptr), scriptCompilationError(false), logFile(nullptr), renderTexture{} { } @@ -75,6 +77,10 @@ bool Application::Initialize(int argc, char *argv[]) // Set up ECS bindings with our registry SetGlobalRegistry(®istry); + // Set up resource managers for script access + extern void SetResourceManagers(ShaderManager*, ModelManager*, MaterialManager*); + SetResourceManagers(&shaderManager, &modelManager, &materialManager); + // Initialize hot reload to watch the scripts directory so any script change // triggers a reload. { @@ -94,43 +100,6 @@ bool Application::Initialize(int argc, char *argv[]) renderTexture = LoadRenderTexture(WINDOW_WIDTH, WINDOW_HEIGHT); } - // Set up camera - camera.position = {5, 5, 5}; - camera.target = {0, 0, 0}; - camera.up = {0, 1, 0}; - camera.fovy = 45; - camera.projection = CAMERA_PERSPECTIVE; // ADD THIS LINE! - - // Load models - Model cube = LoadModelFromMesh(GenMeshCube(1, 1, 1)); - Model sphere = LoadModelFromMesh(GenMeshSphere(0.5f, 16, 16)); - - // Load shaders (use both vertex and fragment shader files explicitly) - toonShader = LoadShader("shaders/toon.vs", "shaders/toon.fs"); - if (toonShader.id == 0) { - log_warn("Failed to load toon shader (id=0). Check shader paths and GL support."); - } else { - log_info("Loaded toon shader id=%d", toonShader.id); - - // Verify shader locations exist - int lightLoc = GetShaderLocation(toonShader, "lightDir"); - int bandLoc = GetShaderLocation(toonShader, "bandCount"); - int albedoLoc = GetShaderLocation(toonShader, "albedo"); - - log_info("Shader locations: lightDir=%d, bandCount=%d, albedo=%d", lightLoc, bandLoc, albedoLoc); - - if (lightLoc == -1 || bandLoc == -1 || albedoLoc == -1) { - log_warn("Some shader uniforms not found - shader may not work correctly"); - } - } - - // Assign shader to cube material - cube.materials[0].shader = toonShader; - sphere.materials[0].shader = toonShader; - - models.push_back(cube); - models.push_back(sphere); - return true; } @@ -174,13 +143,6 @@ void Application::Update(float deltaTime) // Update ECS systems UpdateSystems(deltaTime); - - UpdateCamera(&camera, CAMERA_ORBITAL); - - // Day/night toggle - if (IsKeyPressed(KEY_SPACE)) - dayMode = !dayMode; - globalBandCount = dayMode ? 3.0f : 2.0f; } void Application::UpdateSystems(float deltaTime) @@ -200,53 +162,172 @@ void Application::UpdateSystems(float deltaTime) void Application::RenderScene() { - BeginMode3D(camera); - DrawGrid(10, 1); - - BeginShaderMode(toonShader); + // Query for active camera (first one found with Camera3DComponent) + Camera3D camera = {}; + bool hasCamera = false; - // Get shader locations once - int lightLoc = GetShaderLocation(toonShader, "lightDir"); - int bandLoc = GetShaderLocation(toonShader, "bandCount"); - int albedoLoc = GetShaderLocation(toonShader, "albedo"); - - auto view = registry.view(); - - view.each([&](auto &transform, auto &sprite) - { - // Validate model index - // if (sprite.modelId < 0 || sprite.modelId >= models.size()) { - // return; - // } - - // Set ALL uniforms before each draw call - if (lightLoc != -1) { - SetShaderValue(toonShader, lightLoc, &lightDir, SHADER_UNIFORM_VEC3); + auto cameraView = registry.view(); + cameraView.each([&](auto& camComp) { + if (!hasCamera) { + camera.position = camComp.position; + camera.target = camComp.target; + camera.up = camComp.up; + camera.fovy = camComp.fovy; + camera.projection = camComp.projection; + hasCamera = true; } - - if (bandLoc != -1) { - SetShaderValue(toonShader, bandLoc, &globalBandCount, SHADER_UNIFORM_FLOAT); - } - - // Set color for this entity - Vector4 color = { - sprite.color.r / 255.0f, - sprite.color.g / 255.0f, - sprite.color.b / 255.0f, - sprite.color.a / 255.0f - }; - - if (albedoLoc != -1) { - SetShaderValue(toonShader, albedoLoc, &color, SHADER_UNIFORM_VEC4); - } - - // Draw the model - Model& model = models[sprite.modelId]; - DrawModelEx(model, transform.position, Vector3{0, 1, 0}, transform.rotation * RAD2DEG, - transform.scale, WHITE); }); - EndShaderMode(); + // If no camera found, use a default one + if (!hasCamera) { + camera.position = {5, 5, 5}; + camera.target = {0, 0, 0}; + camera.up = {0, 1, 0}; + camera.fovy = 45; + camera.projection = CAMERA_PERSPECTIVE; + } + + // Get the first light (if any) for shader uniforms + Vector3 lightDir = {0.5f, 0.7f, 0.3f}; + float lightIntensity = 1.0f; + + auto lightView = registry.view(); + lightView.each([&](auto& light) { + lightDir = light.direction; + lightIntensity = light.intensity; + return; // Use first light only for now + }); + + BeginMode3D(camera); + DrawGrid(10, 1); + + // Collect entities with renderables and organize by render pass + struct RenderableEntity { + entt::entity entity; + ECSTransform* transform; + Sprite* sprite; + RenderPassComponent* renderPass; + }; + + std::vector renderables; + + auto renderView = registry.view(); + renderView.each([&](auto entity, auto& transform, auto& sprite) { + RenderableEntity re; + re.entity = entity; + re.transform = &transform; + re.sprite = &sprite; + re.renderPass = registry.try_get(entity); + renderables.push_back(re); + }); + + // Sort by render pass order (lower = earlier) + std::sort(renderables.begin(), renderables.end(), [](const RenderableEntity& a, const RenderableEntity& b) { + int orderA = a.renderPass ? a.renderPass->order : 0; + int orderB = b.renderPass ? b.renderPass->order : 0; + return orderA < orderB; + }); + + // Group by render pass and render + int currentPassOrder = INT_MIN; + Shader* currentShader = nullptr; + + for (const auto& re : renderables) { + int passOrder = re.renderPass ? re.renderPass->order : 0; + + // If we've moved to a new render pass, update settings + if (passOrder != currentPassOrder) { + if (currentShader) { + EndShaderMode(); + currentShader = nullptr; + } + + // Apply render pass settings + if (re.renderPass) { + if (!re.renderPass->depthTest) { + rlDisableDepthTest(); + } else { + rlEnableDepthTest(); + } + + // If pass has a shader override, use it + if (re.renderPass->shaderId > 0) { + currentShader = shaderManager.Get(re.renderPass->shaderId); + if (currentShader) { + BeginShaderMode(*currentShader); + + // Set uniforms for this shader + int lightLoc = GetShaderLocation(*currentShader, "lightDir"); + if (lightLoc != -1) { + SetShaderValue(*currentShader, lightLoc, &lightDir, SHADER_UNIFORM_VEC3); + } + } + } + } + + currentPassOrder = passOrder; + } + + // Get material if entity has one + MaterialComponent* matComp = registry.try_get(re.entity); + Shader* matShader = nullptr; + Color albedo = WHITE; + + if (matComp && matComp->materialId > 0) { + MaterialData* matData = materialManager.Get(matComp->materialId); + if (matData) { + albedo = matData->albedo; + if (matData->shaderId > 0 && !currentShader) { + matShader = shaderManager.Get(matData->shaderId); + if (matShader) { + BeginShaderMode(*matShader); + currentShader = matShader; + + // Set uniforms + int lightLoc = GetShaderLocation(*matShader, "lightDir"); + if (lightLoc != -1) { + SetShaderValue(*matShader, lightLoc, &lightDir, SHADER_UNIFORM_VEC3); + } + + Vector4 color = { + albedo.r / 255.0f, + albedo.g / 255.0f, + albedo.b / 255.0f, + albedo.a / 255.0f + }; + int albedoLoc = GetShaderLocation(*matShader, "albedo"); + if (albedoLoc != -1) { + SetShaderValue(*matShader, albedoLoc, &color, SHADER_UNIFORM_VEC4); + } + } + } + } + } + + // Render the model + if (re.sprite->modelId > 0) { + Model* model = modelManager.Get(re.sprite->modelId); + if (model) { + DrawModelEx(*model, re.transform->position, Vector3{0, 1, 0}, + re.transform->rotation * RAD2DEG, re.transform->scale, + re.sprite->color); + } + } + + // Clean up material shader if we started it + if (matShader && currentShader == matShader) { + EndShaderMode(); + currentShader = nullptr; + } + } + + // Clean up any active shader + if (currentShader) { + EndShaderMode(); + } + + rlEnableDepthTest(); // Ensure depth test is re-enabled + EndMode3D(); } void Application::Draw() @@ -294,6 +375,7 @@ void Application::Shutdown() hotReload = nullptr; } + scriptEngine.Shutdown(); if (enableEditor) { @@ -303,15 +385,13 @@ void Application::Shutdown() // Shutdown rlImGui first while the GL context and window are still valid rlImGuiShutdown(); - // Shutdown script engine - scriptEngine.Shutdown(); + // Clear ECS registry first to release all component data + registry.clear(); - // Unload assets - for (auto &model : models) - { - UnloadModel(model); - } - UnloadShader(toonShader); + // Unload all resources before closing window (while GL context is still valid) + materialManager.Clear(); + shaderManager.UnloadAll(); + modelManager.UnloadAll(); // Clear the trace log callback before closing window to prevent logging after cleanup SetTraceLogCallback(nullptr); diff --git a/src/MaterialManager.cpp b/src/MaterialManager.cpp new file mode 100644 index 0000000..ebcaf3f --- /dev/null +++ b/src/MaterialManager.cpp @@ -0,0 +1,76 @@ +#include "MaterialManager.h" +#include "log/log.h" + +MaterialManager::MaterialManager() : nextId(1), cleared(false) +{ +} + +MaterialManager::~MaterialManager() +{ + // Only clear if not already done + if (!cleared) { + materials.clear(); + } +} + +unsigned int MaterialManager::Create(unsigned int shaderId, Color albedo) +{ + unsigned int id = nextId++; + + MaterialData data; + data.shaderId = shaderId; + data.albedo = albedo; + + materials[id] = data; + log_info("Created material id=%u with shader=%u", id, shaderId); + + return id; +} + +void MaterialManager::Remove(unsigned int id) +{ + auto it = materials.find(id); + if (it != materials.end()) + { + materials.erase(it); + log_info("Removed material id=%u", id); + } +} + +MaterialData* MaterialManager::Get(unsigned int id) +{ + auto it = materials.find(id); + if (it != materials.end()) + { + return &it->second; + } + return nullptr; +} + +void MaterialManager::SetShader(unsigned int id, unsigned int shaderId) +{ + auto it = materials.find(id); + if (it != materials.end()) + { + it->second.shaderId = shaderId; + log_info("Updated material id=%u shader to %u", id, shaderId); + } +} + +void MaterialManager::SetAlbedo(unsigned int id, Color albedo) +{ + auto it = materials.find(id); + if (it != materials.end()) + { + it->second.albedo = albedo; + } +} + +void MaterialManager::Clear() +{ + if (!cleared) { + materials.clear(); + cleared = true; + log_info("Cleared all materials"); + } +} diff --git a/src/ModelManager.cpp b/src/ModelManager.cpp new file mode 100644 index 0000000..31225d8 --- /dev/null +++ b/src/ModelManager.cpp @@ -0,0 +1,79 @@ +#include "ModelManager.h" +#include "log/log.h" + +ModelManager::ModelManager() : nextId(1), unloaded(false) +{ +} + +ModelManager::~ModelManager() +{ + // Only unload if not already done + if (!unloaded) { + for (auto& pair : models) { + UnloadModel(pair.second); + } + models.clear(); + } +} + +unsigned int ModelManager::Load(const std::string& path) +{ + Model model = LoadModel(path.c_str()); + + if (model.meshCount == 0) + { + log_warn("Failed to load model: %s", path.c_str()); + return 0; + } + + unsigned int id = nextId++; + models[id] = model; + log_info("Loaded model id=%u from %s", id, path.c_str()); + + return id; +} + +unsigned int ModelManager::LoadFromMesh(Mesh mesh) +{ + Model model = LoadModelFromMesh(mesh); + + unsigned int id = nextId++; + models[id] = model; + log_info("Loaded model id=%u from mesh", id); + + return id; +} + +void ModelManager::Unload(unsigned int id) +{ + auto it = models.find(id); + if (it != models.end()) + { + UnloadModel(it->second); + models.erase(it); + log_info("Unloaded model id=%u", id); + } +} + +Model* ModelManager::Get(unsigned int id) +{ + auto it = models.find(id); + if (it != models.end()) + { + return &it->second; + } + return nullptr; +} + +void ModelManager::UnloadAll() +{ + if (!unloaded) { + for (auto& pair : models) + { + UnloadModel(pair.second); + } + models.clear(); + unloaded = true; + log_info("Unloaded all models"); + } +} diff --git a/src/ShaderManager.cpp b/src/ShaderManager.cpp new file mode 100644 index 0000000..f8325fa --- /dev/null +++ b/src/ShaderManager.cpp @@ -0,0 +1,68 @@ +#include "ShaderManager.h" +#include "log/log.h" + +ShaderManager::ShaderManager() : nextId(1), unloaded(false) +{ +} + +ShaderManager::~ShaderManager() +{ + // Only unload if not already done + if (!unloaded) { + for (auto& pair : shaders) { + UnloadShader(pair.second); + } + shaders.clear(); + } +} + +unsigned int ShaderManager::Load(const std::string& vsPath, const std::string& fsPath) +{ + Shader shader = LoadShader(vsPath.c_str(), fsPath.c_str()); + + if (shader.id == 0) + { + log_warn("Failed to load shader: %s / %s", vsPath.c_str(), fsPath.c_str()); + return 0; + } + + unsigned int id = nextId++; + shaders[id] = shader; + log_info("Loaded shader id=%u from %s / %s (raylib id=%u)", id, vsPath.c_str(), fsPath.c_str(), shader.id); + + return id; +} + +void ShaderManager::Unload(unsigned int id) +{ + auto it = shaders.find(id); + if (it != shaders.end()) + { + UnloadShader(it->second); + shaders.erase(it); + log_info("Unloaded shader id=%u", id); + } +} + +Shader* ShaderManager::Get(unsigned int id) +{ + auto it = shaders.find(id); + if (it != shaders.end()) + { + return &it->second; + } + return nullptr; +} + +void ShaderManager::UnloadAll() +{ + if (!unloaded) { + for (auto& pair : shaders) + { + UnloadShader(pair.second); + } + shaders.clear(); + unloaded = true; + log_info("Unloaded all shaders"); + } +} diff --git a/src/scripting/ECSBindings.cpp b/src/scripting/ECSBindings.cpp index 454d21a..8b435f6 100644 --- a/src/scripting/ECSBindings.cpp +++ b/src/scripting/ECSBindings.cpp @@ -193,6 +193,163 @@ void AS_RemoveTag(uint32_t entity) { g_registry->remove((entt::entity)entity); } +// === Camera3D Component === + +void AS_AddCamera3D(uint32_t entity, float px, float py, float pz, float tx, float ty, float tz, float fovy) { + if (!g_registry) return; + Camera3DComponent cam; + cam.position = {px, py, pz}; + cam.target = {tx, ty, tz}; + cam.up = {0.0f, 1.0f, 0.0f}; + cam.fovy = fovy; + cam.projection = 0; // CAMERA_PERSPECTIVE + g_registry->emplace((entt::entity)entity, cam); +} + +void AS_SetCameraPosition(uint32_t entity, float x, float y, float z) { + if (!g_registry) return; + if (auto* c = g_registry->try_get((entt::entity)entity)) { + c->position = {x, y, z}; + } +} + +void AS_SetCameraTarget(uint32_t entity, float x, float y, float z) { + if (!g_registry) return; + if (auto* c = g_registry->try_get((entt::entity)entity)) { + c->target = {x, y, z}; + } +} + +void AS_SetCameraFovy(uint32_t entity, float fovy) { + if (!g_registry) return; + if (auto* c = g_registry->try_get((entt::entity)entity)) { + c->fovy = fovy; + } +} + +bool AS_HasCamera3D(uint32_t entity) { + if (!g_registry) return false; + return g_registry->all_of((entt::entity)entity); +} + +void AS_RemoveCamera3D(uint32_t entity) { + if (!g_registry) return; + g_registry->remove((entt::entity)entity); +} + +// === Light Component === + +void AS_AddLight(uint32_t entity, float dx, float dy, float dz, float intensity) { + if (!g_registry) return; + LightComponent light; + light.direction = {dx, dy, dz}; + light.color = WHITE; + light.intensity = intensity; + g_registry->emplace((entt::entity)entity, light); +} + +void AS_SetLightDirection(uint32_t entity, float x, float y, float z) { + if (!g_registry) return; + if (auto* l = g_registry->try_get((entt::entity)entity)) { + l->direction = {x, y, z}; + } +} + +void AS_SetLightIntensity(uint32_t entity, float intensity) { + if (!g_registry) return; + if (auto* l = g_registry->try_get((entt::entity)entity)) { + l->intensity = intensity; + } +} + +void AS_SetLightColor(uint32_t entity, uint32_t color) { + if (!g_registry) return; + if (auto* l = g_registry->try_get((entt::entity)entity)) { + l->color.r = (color >> 24) & 0xFF; + l->color.g = (color >> 16) & 0xFF; + l->color.b = (color >> 8) & 0xFF; + l->color.a = color & 0xFF; + } +} + +bool AS_HasLight(uint32_t entity) { + if (!g_registry) return false; + return g_registry->all_of((entt::entity)entity); +} + +void AS_RemoveLight(uint32_t entity) { + if (!g_registry) return; + g_registry->remove((entt::entity)entity); +} + +// === Material Component === + +void AS_AddMaterial(uint32_t entity, unsigned int materialId) { + if (!g_registry) return; + g_registry->emplace((entt::entity)entity, materialId); +} + +void AS_SetMaterialId(uint32_t entity, unsigned int materialId) { + if (!g_registry) return; + if (auto* m = g_registry->try_get((entt::entity)entity)) { + m->materialId = materialId; + } +} + +unsigned int AS_GetMaterialId(uint32_t entity) { + if (!g_registry) return 0; + if (auto* m = g_registry->try_get((entt::entity)entity)) { + return m->materialId; + } + return 0; +} + +bool AS_HasMaterial(uint32_t entity) { + if (!g_registry) return false; + return g_registry->all_of((entt::entity)entity); +} + +void AS_RemoveMaterialComponent(uint32_t entity) { + if (!g_registry) return; + g_registry->remove((entt::entity)entity); +} + +// === RenderPass Component === + +void AS_AddRenderPass(uint32_t entity, int order, bool depthTest, bool depthWrite, unsigned int shaderId) { + if (!g_registry) return; + RenderPassComponent pass; + pass.order = order; + pass.depthTest = depthTest; + pass.depthWrite = depthWrite; + pass.shaderId = shaderId; + g_registry->emplace((entt::entity)entity, pass); +} + +void AS_SetRenderPassOrder(uint32_t entity, int order) { + if (!g_registry) return; + if (auto* p = g_registry->try_get((entt::entity)entity)) { + p->order = order; + } +} + +void AS_SetRenderPassShader(uint32_t entity, unsigned int shaderId) { + if (!g_registry) return; + if (auto* p = g_registry->try_get((entt::entity)entity)) { + p->shaderId = shaderId; + } +} + +bool AS_HasRenderPass(uint32_t entity) { + if (!g_registry) return false; + return g_registry->all_of((entt::entity)entity); +} + +void AS_RemoveRenderPass(uint32_t entity) { + if (!g_registry) return; + g_registry->remove((entt::entity)entity); +} + // === Registration === void RegisterECSBindings(asIScriptEngine *engine) { @@ -313,5 +470,97 @@ void RegisterECSBindings(asIScriptEngine *engine) { asFUNCTION(AS_RemoveTag), asCALL_CDECL); assert(r >= 0); + // Camera3D component + r = engine->RegisterGlobalFunction("void AddCamera3D(uint, float, float, float, float, float, float, float)", + asFUNCTION(AS_AddCamera3D), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void SetCameraPosition(uint, float, float, float)", + asFUNCTION(AS_SetCameraPosition), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void SetCameraTarget(uint, float, float, float)", + asFUNCTION(AS_SetCameraTarget), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void SetCameraFovy(uint, float)", + asFUNCTION(AS_SetCameraFovy), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("bool HasCamera3D(uint)", + asFUNCTION(AS_HasCamera3D), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void RemoveCamera3D(uint)", + asFUNCTION(AS_RemoveCamera3D), asCALL_CDECL); + assert(r >= 0); + + // Light component + r = engine->RegisterGlobalFunction("void AddLight(uint, float, float, float, float = 1.0f)", + asFUNCTION(AS_AddLight), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void SetLightDirection(uint, float, float, float)", + asFUNCTION(AS_SetLightDirection), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void SetLightIntensity(uint, float)", + asFUNCTION(AS_SetLightIntensity), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void SetLightColor(uint, uint)", + asFUNCTION(AS_SetLightColor), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("bool HasLight(uint)", + asFUNCTION(AS_HasLight), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void RemoveLight(uint)", + asFUNCTION(AS_RemoveLight), asCALL_CDECL); + assert(r >= 0); + + // Material component + r = engine->RegisterGlobalFunction("void AddMaterial(uint, uint)", + asFUNCTION(AS_AddMaterial), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void SetMaterialId(uint, uint)", + asFUNCTION(AS_SetMaterialId), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("uint GetMaterialId(uint)", + asFUNCTION(AS_GetMaterialId), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("bool HasMaterial(uint)", + asFUNCTION(AS_HasMaterial), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void RemoveMaterial(uint)", + asFUNCTION(AS_RemoveMaterialComponent), asCALL_CDECL); + assert(r >= 0); + + // RenderPass component + r = engine->RegisterGlobalFunction("void AddRenderPass(uint, int, bool, bool, uint)", + asFUNCTION(AS_AddRenderPass), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void SetRenderPassOrder(uint, int)", + asFUNCTION(AS_SetRenderPassOrder), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void SetRenderPassShader(uint, uint)", + asFUNCTION(AS_SetRenderPassShader), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("bool HasRenderPass(uint)", + asFUNCTION(AS_HasRenderPass), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void RemoveRenderPass(uint)", + asFUNCTION(AS_RemoveRenderPass), asCALL_CDECL); + assert(r >= 0); + engine->SetDefaultNamespace(""); } diff --git a/src/scripting/ResourceBindings.cpp b/src/scripting/ResourceBindings.cpp new file mode 100644 index 0000000..debcf07 --- /dev/null +++ b/src/scripting/ResourceBindings.cpp @@ -0,0 +1,144 @@ +#include "scripting/ResourceBindings.h" +#include "ShaderManager.h" +#include "ModelManager.h" +#include "MaterialManager.h" +#include +#include +#include "raylib.h" + +// Global resource manager pointers for script access +static ShaderManager* g_shaderManager = nullptr; +static ModelManager* g_modelManager = nullptr; +static MaterialManager* g_materialManager = nullptr; + +void SetResourceManagers(ShaderManager* shaderMgr, ModelManager* modelMgr, MaterialManager* materialMgr) { + g_shaderManager = shaderMgr; + g_modelManager = modelMgr; + g_materialManager = materialMgr; +} + +// === Shader Management === + +unsigned int AS_LoadShader(const std::string& vsPath, const std::string& fsPath) { + if (!g_shaderManager) return 0; + return g_shaderManager->Load(vsPath, fsPath); +} + +void AS_UnloadShader(unsigned int id) { + if (!g_shaderManager) return; + g_shaderManager->Unload(id); +} + +// === Model Management === + +unsigned int AS_LoadModel(const std::string& path) { + if (!g_modelManager) return 0; + return g_modelManager->Load(path); +} + +unsigned int AS_LoadModelCube(float width, float height, float length) { + if (!g_modelManager) return 0; + Mesh mesh = GenMeshCube(width, height, length); + return g_modelManager->LoadFromMesh(mesh); +} + +unsigned int AS_LoadModelSphere(float radius, int rings, int slices) { + if (!g_modelManager) return 0; + Mesh mesh = GenMeshSphere(radius, rings, slices); + return g_modelManager->LoadFromMesh(mesh); +} + +unsigned int AS_LoadModelPlane(float width, float length, int resX, int resZ) { + if (!g_modelManager) return 0; + Mesh mesh = GenMeshPlane(width, length, resX, resZ); + return g_modelManager->LoadFromMesh(mesh); +} + +void AS_UnloadModel(unsigned int id) { + if (!g_modelManager) return; + g_modelManager->Unload(id); +} + +// === Material Management === + +unsigned int AS_CreateMaterial(unsigned int shaderId, unsigned char r, unsigned char g, unsigned char b, unsigned char a) { + if (!g_materialManager) return 0; + Color albedo = {r, g, b, a}; + return g_materialManager->Create(shaderId, albedo); +} + +void AS_RemoveMaterial(unsigned int id) { + if (!g_materialManager) return; + g_materialManager->Remove(id); +} + +void AS_SetMaterialShader(unsigned int id, unsigned int shaderId) { + if (!g_materialManager) return; + g_materialManager->SetShader(id, shaderId); +} + +void AS_SetMaterialAlbedo(unsigned int id, unsigned char r, unsigned char g, unsigned char b, unsigned char a) { + if (!g_materialManager) return; + Color albedo = {r, g, b, a}; + g_materialManager->SetAlbedo(id, albedo); +} + +void RegisterResourceBindings(asIScriptEngine *engine) +{ + int r; + + // === Shader namespace === + engine->SetDefaultNamespace("Shader"); + + r = engine->RegisterGlobalFunction("uint Load(const string &in, const string &in)", + asFUNCTION(AS_LoadShader), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void Unload(uint)", + asFUNCTION(AS_UnloadShader), asCALL_CDECL); + assert(r >= 0); + + // === Model namespace === + engine->SetDefaultNamespace("Model"); + + r = engine->RegisterGlobalFunction("uint Load(const string &in)", + asFUNCTION(AS_LoadModel), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("uint LoadCube(float, float, float)", + asFUNCTION(AS_LoadModelCube), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("uint LoadSphere(float, int, int)", + asFUNCTION(AS_LoadModelSphere), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("uint LoadPlane(float, float, int, int)", + asFUNCTION(AS_LoadModelPlane), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void Unload(uint)", + asFUNCTION(AS_UnloadModel), asCALL_CDECL); + assert(r >= 0); + + // === Material namespace === + engine->SetDefaultNamespace("Material"); + + r = engine->RegisterGlobalFunction("uint Create(uint, uint8, uint8, uint8, uint8)", + asFUNCTION(AS_CreateMaterial), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void Remove(uint)", + asFUNCTION(AS_RemoveMaterial), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void SetShader(uint, uint)", + asFUNCTION(AS_SetMaterialShader), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void SetAlbedo(uint, uint8, uint8, uint8, uint8)", + asFUNCTION(AS_SetMaterialAlbedo), asCALL_CDECL); + assert(r >= 0); + + engine->SetDefaultNamespace(""); +} diff --git a/src/scripting/ScriptBindings.cpp b/src/scripting/ScriptBindings.cpp index 707e647..3ac898c 100644 --- a/src/scripting/ScriptBindings.cpp +++ b/src/scripting/ScriptBindings.cpp @@ -5,6 +5,7 @@ #include "scripting/TextureBindings.h" #include "scripting/MathBindings.h" #include "scripting/ECSBindings.h" +#include "scripting/ResourceBindings.h" void ScriptBindings::RegisterAll(asIScriptEngine *engine) { @@ -15,4 +16,5 @@ void ScriptBindings::RegisterAll(asIScriptEngine *engine) RegisterTextureBindings(engine); RegisterMathBindings(engine); RegisterECSBindings(engine); + RegisterResourceBindings(engine); } \ No newline at end of file diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 8cb4e06..f8d9f39 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -15,6 +15,10 @@ add_executable(unit_tests ${CMAKE_SOURCE_DIR}/src/scripting/ImageBindings.cpp ${CMAKE_SOURCE_DIR}/src/scripting/TextureBindings.cpp ${CMAKE_SOURCE_DIR}/src/scripting/MathBindings.cpp + ${CMAKE_SOURCE_DIR}/src/scripting/ResourceBindings.cpp + ${CMAKE_SOURCE_DIR}/src/ShaderManager.cpp + ${CMAKE_SOURCE_DIR}/src/ModelManager.cpp + ${CMAKE_SOURCE_DIR}/src/MaterialManager.cpp ${CMAKE_SOURCE_DIR}/src/log/log.c ) From 283d057507d7502f7b01e9aef31f1c42d83a1c8b Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Fri, 6 Mar 2026 14:51:54 +1300 Subject: [PATCH 19/53] chore(wip): attempting to get shaders working again --- shaders/toon.fs | 6 +- src/Application.cpp | 139 ++++++++++++++++++++++++++++---------------- 2 files changed, 93 insertions(+), 52 deletions(-) diff --git a/shaders/toon.fs b/shaders/toon.fs index f3d8705..5d3b6a3 100644 --- a/shaders/toon.fs +++ b/shaders/toon.fs @@ -4,15 +4,15 @@ in vec3 fragNormal; in vec3 fragPosition; uniform vec4 albedo; +uniform vec3 lightDir; out vec4 fragColor; void main() { - // Hardcoded values since uniforms get optimized out - vec3 lightDir = normalize(vec3(0.5, 0.7, 0.3)); + // Use uniform light direction, with fallback + vec3 light = normalize(lightDir); float bandCount = 3.0; vec3 normal = normalize(fragNormal); - vec3 light = normalize(lightDir); float intensity = max(dot(normal, light), 0.0); intensity = floor(intensity * bandCount) / bandCount; diff --git a/src/Application.cpp b/src/Application.cpp index c22ce6f..8fd1613 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -195,6 +195,13 @@ void Application::RenderScene() lightView.each([&](auto& light) { lightDir = light.direction; lightIntensity = light.intensity; + + static bool loggedLight = false; + if (!loggedLight) { + log_info("Light direction: (%.2f, %.2f, %.2f), intensity: %.2f", + lightDir.x, lightDir.y, lightDir.z, lightIntensity); + loggedLight = true; + } return; // Use first light only for now }); @@ -231,16 +238,18 @@ void Application::RenderScene() // Group by render pass and render int currentPassOrder = INT_MIN; Shader* currentShader = nullptr; + uint currentShaderId = 0; for (const auto& re : renderables) { int passOrder = re.renderPass ? re.renderPass->order : 0; - // If we've moved to a new render pass, update settings + // If we've moved to a new render pass, end current shader and update settings if (passOrder != currentPassOrder) { if (currentShader) { EndShaderMode(); currentShader = nullptr; } + currentShaderId = 0; // Reset shader tracking for new pass // Apply render pass settings if (re.renderPass) { @@ -249,76 +258,108 @@ void Application::RenderScene() } else { rlEnableDepthTest(); } - - // If pass has a shader override, use it - if (re.renderPass->shaderId > 0) { - currentShader = shaderManager.Get(re.renderPass->shaderId); - if (currentShader) { - BeginShaderMode(*currentShader); - - // Set uniforms for this shader - int lightLoc = GetShaderLocation(*currentShader, "lightDir"); - if (lightLoc != -1) { - SetShaderValue(*currentShader, lightLoc, &lightDir, SHADER_UNIFORM_VEC3); - } - } - } } currentPassOrder = passOrder; } - // Get material if entity has one + // Determine which shader to use: Material shader takes priority, then RenderPass shader MaterialComponent* matComp = registry.try_get(re.entity); - Shader* matShader = nullptr; Color albedo = WHITE; + uint desiredShaderId = 0; + // Get material data first (for color) if (matComp && matComp->materialId > 0) { MaterialData* matData = materialManager.Get(matComp->materialId); if (matData) { - albedo = matData->albedo; - if (matData->shaderId > 0 && !currentShader) { - matShader = shaderManager.Get(matData->shaderId); - if (matShader) { - BeginShaderMode(*matShader); - currentShader = matShader; - - // Set uniforms - int lightLoc = GetShaderLocation(*matShader, "lightDir"); - if (lightLoc != -1) { - SetShaderValue(*matShader, lightLoc, &lightDir, SHADER_UNIFORM_VEC3); - } - - Vector4 color = { - albedo.r / 255.0f, - albedo.g / 255.0f, - albedo.b / 255.0f, - albedo.a / 255.0f - }; - int albedoLoc = GetShaderLocation(*matShader, "albedo"); - if (albedoLoc != -1) { - SetShaderValue(*matShader, albedoLoc, &color, SHADER_UNIFORM_VEC4); - } - } + albedo = matData->albedo; // Always get the color from material + if (matData->shaderId > 0) { + desiredShaderId = matData->shaderId; + } + + // Debug: Log first frame only + static bool logged = false; + if (!logged && matComp->materialId <= 3) { + log_info("Entity material=%u, shader=%u, albedo=(%d,%d,%d,%d)", + matComp->materialId, matData->shaderId, + albedo.r, albedo.g, albedo.b, albedo.a); + if (matComp->materialId == 3) logged = true; } } } - // Render the model + // Fall back to RenderPass shader if no material shader + if (desiredShaderId == 0 && re.renderPass && re.renderPass->shaderId > 0) { + desiredShaderId = re.renderPass->shaderId; + } + + // Switch shader if needed + if (desiredShaderId != currentShaderId) { + if (currentShader) { + EndShaderMode(); + currentShader = nullptr; + } + + if (desiredShaderId > 0) { + currentShader = shaderManager.Get(desiredShaderId); + if (currentShader) { + BeginShaderMode(*currentShader); + currentShaderId = desiredShaderId; + + // Debug: Log shader switches + static int switchCount = 0; + if (switchCount < 5) { + log_info("Switched to shader %u (raylib id=%u)", desiredShaderId, currentShader->id); + switchCount++; + } + + // Set light direction uniform + int lightLoc = GetShaderLocation(*currentShader, "lightDir"); + if (switchCount <= 1) { + log_info("lightDir uniform location: %d, value=(%.2f,%.2f,%.2f)", + lightLoc, lightDir.x, lightDir.y, lightDir.z); + } + if (lightLoc != -1) { + SetShaderValue(*currentShader, lightLoc, &lightDir, SHADER_UNIFORM_VEC3); + } + } + } else { + currentShaderId = 0; + } + } + + // Set per-entity uniforms (albedo) if shader is active + if (currentShader) { + Vector4 color = { + albedo.r / 255.0f, + albedo.g / 255.0f, + albedo.b / 255.0f, + albedo.a / 255.0f + }; + int albedoLoc = GetShaderLocation(*currentShader, "albedo"); + + // Debug: Log uniform location + static int setCount = 0; + if (setCount < 3) { + log_info("Setting albedo uniform: loc=%d, color=(%.2f,%.2f,%.2f,%.2f)", + albedoLoc, color.x, color.y, color.z, color.w); + setCount++; + } + + if (albedoLoc != -1) { + SetShaderValue(*currentShader, albedoLoc, &color, SHADER_UNIFORM_VEC4); + } + } + + // Render the model with WHITE tint (let shader control color) if (re.sprite->modelId > 0) { Model* model = modelManager.Get(re.sprite->modelId); if (model) { DrawModelEx(*model, re.transform->position, Vector3{0, 1, 0}, re.transform->rotation * RAD2DEG, re.transform->scale, - re.sprite->color); + WHITE); } } - - // Clean up material shader if we started it - if (matShader && currentShader == matShader) { - EndShaderMode(); - currentShader = nullptr; - } } // Clean up any active shader From 05b0773189f3e16076f4947dea0f4b45d519dfa3 Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Fri, 6 Mar 2026 18:03:48 +1300 Subject: [PATCH 20/53] fix: Windows unsigned int type compatibility --- src/Application.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Application.cpp b/src/Application.cpp index 8fd1613..a6f21a3 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -238,7 +238,7 @@ void Application::RenderScene() // Group by render pass and render int currentPassOrder = INT_MIN; Shader* currentShader = nullptr; - uint currentShaderId = 0; + unsigned int currentShaderId = 0; for (const auto& re : renderables) { int passOrder = re.renderPass ? re.renderPass->order : 0; @@ -266,7 +266,7 @@ void Application::RenderScene() // Determine which shader to use: Material shader takes priority, then RenderPass shader MaterialComponent* matComp = registry.try_get(re.entity); Color albedo = WHITE; - uint desiredShaderId = 0; + unsigned int desiredShaderId = 0; // Get material data first (for color) if (matComp && matComp->materialId > 0) { From 0cce80e9560bdb305c05b3eb6f72a13930d201bc Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Sun, 8 Mar 2026 10:37:38 +1300 Subject: [PATCH 21/53] chore: code code tidy and style tweaks --- imgui.ini | 4 +- scripts/game.as | 80 ++++++------- src/Application.cpp | 8 -- src/scripting/ECSBindings.cpp | 200 ++++++++++++++++---------------- src/scripting/ToastBindings.cpp | 7 +- 5 files changed, 146 insertions(+), 153 deletions(-) diff --git a/imgui.ini b/imgui.ini index 2e3c391..d6659ad 100644 --- a/imgui.ini +++ b/imgui.ini @@ -26,8 +26,8 @@ Size=227,63 Collapsed=0 [Window][##TOAST1] -Pos=1035,564 -Size=225,63 +Pos=956,564 +Size=304,63 Collapsed=0 [Window][##TOAST2] diff --git a/scripts/game.as b/scripts/game.as index 049875d..37d74cc 100644 --- a/scripts/game.as +++ b/scripts/game.as @@ -2,15 +2,15 @@ // This demonstrates creating entities with various components and managing rendering // Resource IDs -uint g_toonShader = 0; -uint g_outlineShader = 0; -uint g_cubeModel = 0; -uint g_sphereModel = 0; -uint g_defaultMaterial = 0; +uint toonShader = 0; +uint outlineShader = 0; +uint cubeModel = 0; +uint sphereModel = 0; +uint defaultMaterial = 0; // Scene entities -uint g_camera = 0; -uint g_light = 0; +uint camera = 0; +uint light = 0; // Store entity IDs for manipulation array entities; @@ -23,45 +23,45 @@ void Init() { Toast::Success("ECS Script initialized successfully!"); // === Load shaders === - g_toonShader = Shader::Load("shaders/toon.vs", "shaders/toon.fs"); - g_outlineShader = Shader::Load("shaders/outline.vs", "shaders/outline.fs"); + toonShader = Shader::Load("shaders/toon.vs", "shaders/toon.fs"); + outlineShader = Shader::Load("shaders/outline.vs", "shaders/outline.fs"); - if (g_toonShader == 0 || g_outlineShader == 0) { + if (toonShader == 0 || outlineShader == 0) { Toast::Error("Failed to load shaders!"); return; } // === Load models === - g_cubeModel = Model::LoadCube(1.0, 1.0, 1.0); - g_sphereModel = Model::LoadSphere(0.5, 16, 16); + cubeModel = Model::LoadCube(1.0, 1.0, 1.0); + sphereModel = Model::LoadSphere(0.5, 16, 16); // === Create default material === - g_defaultMaterial = Material::Create(g_toonShader, 255, 255, 255, 255); + defaultMaterial = Material::Create(toonShader, 255, 255, 255, 255); // === Set up camera === - g_camera = ECS::CreateEntity(); - ECS::AddCamera3D(g_camera, - 5.0, 5.0, 5.0, // position - 0.0, 0.0, 0.0, // target - 45.0); // fovy - ECS::AddTag(g_camera, "MainCamera"); + camera = ECS::CreateEntity(); + ECS::AddCamera3D(camera, + 5.0, 5.0, 5.0, // position + 0.0, 0.0, 0.0, // target + 45.0); // fovy + ECS::AddTag(camera, "MainCamera"); // === Set up light === - g_light = ECS::CreateEntity(); - ECS::AddLight(g_light, 0.5, 0.7, 0.3, 1.0); // direction + intensity - ECS::AddTag(g_light, "MainLight"); + light = ECS::CreateEntity(); + ECS::AddLight(light, 0.5, 0.7, 0.3, 1.0); // direction + intensity + ECS::AddTag(light, "MainLight"); // === Create player entity at origin with outline === player = ECS::CreateEntity(); ECS::AddTransform(player, 0.0f, 0.0f, 0.0f); - ECS::AddSprite(player, g_sphereModel, 0xFF0000FF, 0.0f); // Red sphere + ECS::AddSprite(player, sphereModel, 0xFF0000FF, 0.0f); // Red sphere // Create material for player - uint playerMat = Material::Create(g_toonShader, 255, 0, 0, 255); + uint playerMat = Material::Create(toonShader, 255, 0, 0, 255); ECS::AddMaterial(player, playerMat); // Add outline pass (order=0) and main pass (order=1) - ECS::AddRenderPass(player, 0, false, true, g_outlineShader); + ECS::AddRenderPass(player, 0, false, true, outlineShader); ECS::AddTag(player, "Player"); Log(LOG_INFO, "Created player entity: " + player); @@ -69,10 +69,10 @@ void Init() { // === Create a spinning cube === spinningCube = ECS::CreateEntity(); ECS::AddTransform(spinningCube, 2.0f, 0.0f, 0.0f); - ECS::AddSprite(spinningCube, g_cubeModel, 0x00FF00FF, 0.0f); // Green cube - ECS::AddVelocity(spinningCube, 0.0f, 0.0f, 0.0f, 2.0f); // Angular velocity + ECS::AddSprite(spinningCube, cubeModel, 0x00FF00FF, 0.0f); // Green cube + ECS::AddVelocity(spinningCube, 0.0f, 0.0f, 0.0f, 2.0f); // Angular velocity - uint greenMat = Material::Create(g_toonShader, 0, 255, 0, 255); + uint greenMat = Material::Create(toonShader, 0, 255, 0, 255); ECS::AddMaterial(spinningCube, greenMat); ECS::AddRenderPass(spinningCube, 1, true, true, 0); // Main pass @@ -83,7 +83,7 @@ void Init() { for (int i = 0; i < 5; i++) { uint entity = ECS::CreateEntity(); - float angle = (float(i) / 5.0f) * 6.28318f; // 2*PI + float angle = (float(i) / 5.0f) * 6.28318f; // 2*PI float radius = 3.0f; float x = Math::Cos(angle) * radius; float z = Math::Sin(angle) * radius; @@ -93,15 +93,11 @@ void Init() { // Different colors for each uint color = 0; uint8 r = 255, g = 255, b = 255; - if (i == 0) { color = 0xFFFF00FF; r = 255; g = 255; b = 0; } // Yellow - else if (i == 1) { color = 0xFF00FFFF; r = 255; g = 0; b = 255; } // Magenta - else if (i == 2) { color = 0x00FFFFFF; r = 0; g = 255; b = 255; } // Cyan - else if (i == 3) { color = 0xFFA500FF; r = 255; g = 165; b = 0; } // Orange - else { color = 0xFF69B4FF; r = 255; g = 105; b = 180; } // Pink + if (i == 0) { color = 0xFFFF00FF; r = 255; g = 255; b = 0; } // Yellow else if (i == 1) { color = 0xFF00FFFF; r = 255; g = 0; b = 255; } // Magenta else if (i == 2) { color = 0x00FFFFFF; r = 0; g = 255; b = 255; } // Cyan else if (i == 3) { color = 0xFFA500FF; r = 255; g = 165; b = 0; } // Orange else { color = 0xFF69B4FF; r = 255; g = 105; b = 180; } // Pink - ECS::AddSprite(entity, g_sphereModel, color, 0.0f); + ECS::AddSprite(entity, sphereModel, color, 0.0f); - uint mat = Material::Create(g_toonShader, r, g, b, 255); + uint mat = Material::Create(toonShader, r, g, b, 255); ECS::AddMaterial(entity, mat); ECS::AddRenderPass(entity, 1, true, true, 0); @@ -112,10 +108,10 @@ void Init() { // === Create a moving entity === uint mover = ECS::CreateEntity(); ECS::AddTransform(mover, -3.0f, 0.5f, 0.0f); - ECS::AddSprite(mover, g_cubeModel, 0xFFFFFFFF, 0.0f); // White cube - ECS::AddVelocity(mover, 1.0f, 0.0f, 0.5f, 0.0f); // Moving velocity + ECS::AddSprite(mover, cubeModel, 0xFFFFFFFF, 0.0f); // White cube + ECS::AddVelocity(mover, 1.0f, 0.0f, 0.5f, 0.0f); // Moving velocity - ECS::AddMaterial(mover, g_defaultMaterial); + ECS::AddMaterial(mover, defaultMaterial); ECS::AddRenderPass(mover, 1, true, true, 0); ECS::AddTag(mover, "Mover"); @@ -132,12 +128,12 @@ void Update(float dt) { time += dt; // Update camera to orbit around the scene - if (ECS::HasCamera3D(g_camera)) { + if (ECS::HasCamera3D(camera)) { float angle = time * 0.3; float radius = 7.0; float x = Math::Cos(angle) * radius; float z = Math::Sin(angle) * radius; - ECS::SetCameraPosition(g_camera, x, 5.0, z); + ECS::SetCameraPosition(camera, x, 5.0, z); } // Update player position - simple back and forth motion @@ -153,7 +149,7 @@ void Update(float dt) { float radius = 3.0f; float x = Math::Cos(angle) * radius; float z = Math::Sin(angle) * radius; - float y = Math::Sin(time * 2.0f + float(i)) * 0.5f; // Bobbing motion + float y = Math::Sin(time * 2.0f + float(i)) * 0.5f; // Bobbing motion ECS::SetPosition(entity, x, y, z); ECS::SetRotation(entity, time + float(i)); diff --git a/src/Application.cpp b/src/Application.cpp index a6f21a3..2b6e58a 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -277,14 +277,6 @@ void Application::RenderScene() desiredShaderId = matData->shaderId; } - // Debug: Log first frame only - static bool logged = false; - if (!logged && matComp->materialId <= 3) { - log_info("Entity material=%u, shader=%u, albedo=(%d,%d,%d,%d)", - matComp->materialId, matData->shaderId, - albedo.r, albedo.g, albedo.b, albedo.a); - if (matComp->materialId == 3) logged = true; - } } } diff --git a/src/scripting/ECSBindings.cpp b/src/scripting/ECSBindings.cpp index 8b435f6..11c1b8c 100644 --- a/src/scripting/ECSBindings.cpp +++ b/src/scripting/ECSBindings.cpp @@ -5,47 +5,47 @@ #include // Global registry pointer for script access -static entt::registry* g_registry = nullptr; +static entt::registry* registry = nullptr; void SetGlobalRegistry(entt::registry* reg) { - g_registry = reg; + registry = reg; } // === Entity Management === uint32_t AS_CreateEntity() { - if (!g_registry) return 0; - return (uint32_t)g_registry->create(); + if (!registry) return 0; + return (uint32_t)registry->create(); } void AS_DestroyEntity(uint32_t entity) { - if (!g_registry) return; - g_registry->destroy((entt::entity)entity); + if (!registry) return; + registry->destroy((entt::entity)entity); } bool AS_IsEntityValid(uint32_t entity) { - if (!g_registry) return false; - return g_registry->valid((entt::entity)entity); + if (!registry) return false; + return registry->valid((entt::entity)entity); } // === Transform Component === void AS_AddTransform(uint32_t entity, float x, float y, float z) { - if (!g_registry) return; - g_registry->emplace((entt::entity)entity, + if (!registry) return; + registry->emplace((entt::entity)entity, Vector3{x, y, z}, Vector3{1.0f, 1.0f, 1.0f}, 0.0f); } void AS_SetPosition(uint32_t entity, float x, float y, float z) { - if (!g_registry) return; - if (auto* t = g_registry->try_get((entt::entity)entity)) { + if (!registry) return; + if (auto* t = registry->try_get((entt::entity)entity)) { t->position = {x, y, z}; } } void AS_GetPosition(uint32_t entity, float* x, float* y, float* z) { - if (!g_registry || !x || !y || !z) return; - if (auto* t = g_registry->try_get((entt::entity)entity)) { + if (!registry || !x || !y || !z) return; + if (auto* t = registry->try_get((entt::entity)entity)) { *x = t->position.x; *y = t->position.y; *z = t->position.z; @@ -53,83 +53,83 @@ void AS_GetPosition(uint32_t entity, float* x, float* y, float* z) { } void AS_SetScale(uint32_t entity, float x, float y, float z) { - if (!g_registry) return; - if (auto* t = g_registry->try_get((entt::entity)entity)) { + if (!registry) return; + if (auto* t = registry->try_get((entt::entity)entity)) { t->scale = {x, y, z}; } } void AS_SetRotation(uint32_t entity, float rotation) { - if (!g_registry) return; - if (auto* t = g_registry->try_get((entt::entity)entity)) { + if (!registry) return; + if (auto* t = registry->try_get((entt::entity)entity)) { t->rotation = rotation; } } float AS_GetRotation(uint32_t entity) { - if (!g_registry) return 0.0f; - if (auto* t = g_registry->try_get((entt::entity)entity)) { + if (!registry) return 0.0f; + if (auto* t = registry->try_get((entt::entity)entity)) { return t->rotation; } return 0.0f; } bool AS_HasTransform(uint32_t entity) { - if (!g_registry) return false; - return g_registry->all_of((entt::entity)entity); + if (!registry) return false; + return registry->all_of((entt::entity)entity); } void AS_RemoveTransform(uint32_t entity) { - if (!g_registry) return; - g_registry->remove((entt::entity)entity); + if (!registry) return; + registry->remove((entt::entity)entity); } // === Velocity Component === void AS_AddVelocity(uint32_t entity, float vx, float vy, float vz, float angular) { - if (!g_registry) return; - g_registry->emplace((entt::entity)entity, Vector3{vx, vy, vz}, angular); + if (!registry) return; + registry->emplace((entt::entity)entity, Vector3{vx, vy, vz}, angular); } void AS_SetVelocity(uint32_t entity, float vx, float vy, float vz) { - if (!g_registry) return; - if (auto* v = g_registry->try_get((entt::entity)entity)) { + if (!registry) return; + if (auto* v = registry->try_get((entt::entity)entity)) { v->linear = {vx, vy, vz}; } } void AS_SetAngularVelocity(uint32_t entity, float angular) { - if (!g_registry) return; - if (auto* v = g_registry->try_get((entt::entity)entity)) { + if (!registry) return; + if (auto* v = registry->try_get((entt::entity)entity)) { v->angular = angular; } } bool AS_HasVelocity(uint32_t entity) { - if (!g_registry) return false; - return g_registry->all_of((entt::entity)entity); + if (!registry) return false; + return registry->all_of((entt::entity)entity); } void AS_RemoveVelocity(uint32_t entity) { - if (!g_registry) return; - g_registry->remove((entt::entity)entity); + if (!registry) return; + registry->remove((entt::entity)entity); } // === Sprite Component === void AS_AddSprite(uint32_t entity, int modelId, uint32_t color, float outlineSize) { - if (!g_registry) return; + if (!registry) return; Color col; col.r = (color >> 24) & 0xFF; col.g = (color >> 16) & 0xFF; col.b = (color >> 8) & 0xFF; col.a = color & 0xFF; - g_registry->emplace((entt::entity)entity, modelId, col, outlineSize); + registry->emplace((entt::entity)entity, modelId, col, outlineSize); } void AS_SetSpriteColor(uint32_t entity, uint32_t color) { - if (!g_registry) return; - if (auto* s = g_registry->try_get((entt::entity)entity)) { + if (!registry) return; + if (auto* s = registry->try_get((entt::entity)entity)) { s->color.r = (color >> 24) & 0xFF; s->color.g = (color >> 16) & 0xFF; s->color.b = (color >> 8) & 0xFF; @@ -138,133 +138,133 @@ void AS_SetSpriteColor(uint32_t entity, uint32_t color) { } void AS_SetSpriteModel(uint32_t entity, int modelId) { - if (!g_registry) return; - if (auto* s = g_registry->try_get((entt::entity)entity)) { + if (!registry) return; + if (auto* s = registry->try_get((entt::entity)entity)) { s->modelId = modelId; } } void AS_SetSpriteOutline(uint32_t entity, float outlineSize) { - if (!g_registry) return; - if (auto* s = g_registry->try_get((entt::entity)entity)) { + if (!registry) return; + if (auto* s = registry->try_get((entt::entity)entity)) { s->outlineSize = outlineSize; } } bool AS_HasSprite(uint32_t entity) { - if (!g_registry) return false; - return g_registry->all_of((entt::entity)entity); + if (!registry) return false; + return registry->all_of((entt::entity)entity); } void AS_RemoveSprite(uint32_t entity) { - if (!g_registry) return; - g_registry->remove((entt::entity)entity); + if (!registry) return; + registry->remove((entt::entity)entity); } // === Tag Component === void AS_AddTag(uint32_t entity, const std::string& name) { - if (!g_registry) return; - g_registry->emplace((entt::entity)entity, name); + if (!registry) return; + registry->emplace((entt::entity)entity, name); } std::string AS_GetTag(uint32_t entity) { - if (!g_registry) return ""; - if (auto* t = g_registry->try_get((entt::entity)entity)) { + if (!registry) return ""; + if (auto* t = registry->try_get((entt::entity)entity)) { return t->name; } return ""; } void AS_SetTag(uint32_t entity, const std::string& name) { - if (!g_registry) return; - if (auto* t = g_registry->try_get((entt::entity)entity)) { + if (!registry) return; + if (auto* t = registry->try_get((entt::entity)entity)) { t->name = name; } } bool AS_HasTag(uint32_t entity) { - if (!g_registry) return false; - return g_registry->all_of((entt::entity)entity); + if (!registry) return false; + return registry->all_of((entt::entity)entity); } void AS_RemoveTag(uint32_t entity) { - if (!g_registry) return; - g_registry->remove((entt::entity)entity); + if (!registry) return; + registry->remove((entt::entity)entity); } // === Camera3D Component === void AS_AddCamera3D(uint32_t entity, float px, float py, float pz, float tx, float ty, float tz, float fovy) { - if (!g_registry) return; + if (!registry) return; Camera3DComponent cam; cam.position = {px, py, pz}; cam.target = {tx, ty, tz}; cam.up = {0.0f, 1.0f, 0.0f}; cam.fovy = fovy; cam.projection = 0; // CAMERA_PERSPECTIVE - g_registry->emplace((entt::entity)entity, cam); + registry->emplace((entt::entity)entity, cam); } void AS_SetCameraPosition(uint32_t entity, float x, float y, float z) { - if (!g_registry) return; - if (auto* c = g_registry->try_get((entt::entity)entity)) { + if (!registry) return; + if (auto* c = registry->try_get((entt::entity)entity)) { c->position = {x, y, z}; } } void AS_SetCameraTarget(uint32_t entity, float x, float y, float z) { - if (!g_registry) return; - if (auto* c = g_registry->try_get((entt::entity)entity)) { + if (!registry) return; + if (auto* c = registry->try_get((entt::entity)entity)) { c->target = {x, y, z}; } } void AS_SetCameraFovy(uint32_t entity, float fovy) { - if (!g_registry) return; - if (auto* c = g_registry->try_get((entt::entity)entity)) { + if (!registry) return; + if (auto* c = registry->try_get((entt::entity)entity)) { c->fovy = fovy; } } bool AS_HasCamera3D(uint32_t entity) { - if (!g_registry) return false; - return g_registry->all_of((entt::entity)entity); + if (!registry) return false; + return registry->all_of((entt::entity)entity); } void AS_RemoveCamera3D(uint32_t entity) { - if (!g_registry) return; - g_registry->remove((entt::entity)entity); + if (!registry) return; + registry->remove((entt::entity)entity); } // === Light Component === void AS_AddLight(uint32_t entity, float dx, float dy, float dz, float intensity) { - if (!g_registry) return; + if (!registry) return; LightComponent light; light.direction = {dx, dy, dz}; light.color = WHITE; light.intensity = intensity; - g_registry->emplace((entt::entity)entity, light); + registry->emplace((entt::entity)entity, light); } void AS_SetLightDirection(uint32_t entity, float x, float y, float z) { - if (!g_registry) return; - if (auto* l = g_registry->try_get((entt::entity)entity)) { + if (!registry) return; + if (auto* l = registry->try_get((entt::entity)entity)) { l->direction = {x, y, z}; } } void AS_SetLightIntensity(uint32_t entity, float intensity) { - if (!g_registry) return; - if (auto* l = g_registry->try_get((entt::entity)entity)) { + if (!registry) return; + if (auto* l = registry->try_get((entt::entity)entity)) { l->intensity = intensity; } } void AS_SetLightColor(uint32_t entity, uint32_t color) { - if (!g_registry) return; - if (auto* l = g_registry->try_get((entt::entity)entity)) { + if (!registry) return; + if (auto* l = registry->try_get((entt::entity)entity)) { l->color.r = (color >> 24) & 0xFF; l->color.g = (color >> 16) & 0xFF; l->color.b = (color >> 8) & 0xFF; @@ -273,81 +273,81 @@ void AS_SetLightColor(uint32_t entity, uint32_t color) { } bool AS_HasLight(uint32_t entity) { - if (!g_registry) return false; - return g_registry->all_of((entt::entity)entity); + if (!registry) return false; + return registry->all_of((entt::entity)entity); } void AS_RemoveLight(uint32_t entity) { - if (!g_registry) return; - g_registry->remove((entt::entity)entity); + if (!registry) return; + registry->remove((entt::entity)entity); } // === Material Component === void AS_AddMaterial(uint32_t entity, unsigned int materialId) { - if (!g_registry) return; - g_registry->emplace((entt::entity)entity, materialId); + if (!registry) return; + registry->emplace((entt::entity)entity, materialId); } void AS_SetMaterialId(uint32_t entity, unsigned int materialId) { - if (!g_registry) return; - if (auto* m = g_registry->try_get((entt::entity)entity)) { + if (!registry) return; + if (auto* m = registry->try_get((entt::entity)entity)) { m->materialId = materialId; } } unsigned int AS_GetMaterialId(uint32_t entity) { - if (!g_registry) return 0; - if (auto* m = g_registry->try_get((entt::entity)entity)) { + if (!registry) return 0; + if (auto* m = registry->try_get((entt::entity)entity)) { return m->materialId; } return 0; } bool AS_HasMaterial(uint32_t entity) { - if (!g_registry) return false; - return g_registry->all_of((entt::entity)entity); + if (!registry) return false; + return registry->all_of((entt::entity)entity); } void AS_RemoveMaterialComponent(uint32_t entity) { - if (!g_registry) return; - g_registry->remove((entt::entity)entity); + if (!registry) return; + registry->remove((entt::entity)entity); } // === RenderPass Component === void AS_AddRenderPass(uint32_t entity, int order, bool depthTest, bool depthWrite, unsigned int shaderId) { - if (!g_registry) return; + if (!registry) return; RenderPassComponent pass; pass.order = order; pass.depthTest = depthTest; pass.depthWrite = depthWrite; pass.shaderId = shaderId; - g_registry->emplace((entt::entity)entity, pass); + registry->emplace((entt::entity)entity, pass); } void AS_SetRenderPassOrder(uint32_t entity, int order) { - if (!g_registry) return; - if (auto* p = g_registry->try_get((entt::entity)entity)) { + if (!registry) return; + if (auto* p = registry->try_get((entt::entity)entity)) { p->order = order; } } void AS_SetRenderPassShader(uint32_t entity, unsigned int shaderId) { - if (!g_registry) return; - if (auto* p = g_registry->try_get((entt::entity)entity)) { + if (!registry) return; + if (auto* p = registry->try_get((entt::entity)entity)) { p->shaderId = shaderId; } } bool AS_HasRenderPass(uint32_t entity) { - if (!g_registry) return false; - return g_registry->all_of((entt::entity)entity); + if (!registry) return false; + return registry->all_of((entt::entity)entity); } void AS_RemoveRenderPass(uint32_t entity) { - if (!g_registry) return; - g_registry->remove((entt::entity)entity); + if (!registry) return; + registry->remove((entt::entity)entity); } // === Registration === diff --git a/src/scripting/ToastBindings.cpp b/src/scripting/ToastBindings.cpp index 2cb658c..7494e73 100644 --- a/src/scripting/ToastBindings.cpp +++ b/src/scripting/ToastBindings.cpp @@ -2,25 +2,30 @@ #include "gui/Toast.h" #include #include - +#include +#include "../log/log.h" // Toast binding functions static void AS_ToastInfo(const std::string& message) { + log_info("%s", message.c_str()); Toast::Info(message); } static void AS_ToastWarning(const std::string& message) { + log_warn("%s", message.c_str()); Toast::Warning(message); } static void AS_ToastError(const std::string& message) { + log_error("%s", message.c_str()); Toast::Error(message); } static void AS_ToastSuccess(const std::string& message) { + log_info("%s", message.c_str()); Toast::Success(message); } From 4116678556224ae15f40332dfddbc448bf79906d Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Sun, 8 Mar 2026 11:08:12 +1300 Subject: [PATCH 22/53] fix: shaders work again now --- include/ECSComponents.h | 8 +- scripts/as.predefined | 1 + scripts/game.as | 22 +--- src/Application.cpp | 203 +++++++--------------------------- src/scripting/ECSBindings.cpp | 11 ++ 5 files changed, 62 insertions(+), 183 deletions(-) diff --git a/include/ECSComponents.h b/include/ECSComponents.h index 7aba09e..b808a8c 100644 --- a/include/ECSComponents.h +++ b/include/ECSComponents.h @@ -35,14 +35,16 @@ struct Sprite { size_t modelId; // Index into models array Color color; // Tint color float outlineSize; // Outline thickness + unsigned int shaderId; // Shader to use (0 = no shader) Sprite() : modelId(0) , color(WHITE) - , outlineSize(0.0f) {} + , outlineSize(0.0f) + , shaderId(0) {} - Sprite(int model, Color col = WHITE, float outline = 0.0f) - : modelId(model), color(col), outlineSize(outline) {} + Sprite(int model, Color col = WHITE, float outline = 0.0f, unsigned int shader = 0) + : modelId(model), color(col), outlineSize(outline), shaderId(shader) {} }; // Tag component - simple string identifier diff --git a/scripts/as.predefined b/scripts/as.predefined index 7153935..e994fde 100644 --- a/scripts/as.predefined +++ b/scripts/as.predefined @@ -60,6 +60,7 @@ namespace ECS { void SetSpriteColor(uint entity, uint color); void SetSpriteModel(uint entity, int modelId); void SetSpriteOutline(uint entity, float outlineSize); + void SetSpriteShader(uint entity, uint shaderId); bool HasSprite(uint entity); void RemoveSprite(uint entity); diff --git a/scripts/game.as b/scripts/game.as index 37d74cc..c41c4a4 100644 --- a/scripts/game.as +++ b/scripts/game.as @@ -55,13 +55,7 @@ void Init() { player = ECS::CreateEntity(); ECS::AddTransform(player, 0.0f, 0.0f, 0.0f); ECS::AddSprite(player, sphereModel, 0xFF0000FF, 0.0f); // Red sphere - - // Create material for player - uint playerMat = Material::Create(toonShader, 255, 0, 0, 255); - ECS::AddMaterial(player, playerMat); - - // Add outline pass (order=0) and main pass (order=1) - ECS::AddRenderPass(player, 0, false, true, outlineShader); + ECS::SetSpriteShader(player, toonShader); // Apply toon shader ECS::AddTag(player, "Player"); Log(LOG_INFO, "Created player entity: " + player); @@ -70,12 +64,9 @@ void Init() { spinningCube = ECS::CreateEntity(); ECS::AddTransform(spinningCube, 2.0f, 0.0f, 0.0f); ECS::AddSprite(spinningCube, cubeModel, 0x00FF00FF, 0.0f); // Green cube + ECS::SetSpriteShader(spinningCube, toonShader); // Apply toon shader ECS::AddVelocity(spinningCube, 0.0f, 0.0f, 0.0f, 2.0f); // Angular velocity - uint greenMat = Material::Create(toonShader, 0, 255, 0, 255); - ECS::AddMaterial(spinningCube, greenMat); - ECS::AddRenderPass(spinningCube, 1, true, true, 0); // Main pass - ECS::AddTag(spinningCube, "Spinner"); Log(LOG_INFO, "Created spinning cube: " + spinningCube); @@ -96,10 +87,7 @@ void Init() { if (i == 0) { color = 0xFFFF00FF; r = 255; g = 255; b = 0; } // Yellow else if (i == 1) { color = 0xFF00FFFF; r = 255; g = 0; b = 255; } // Magenta else if (i == 2) { color = 0x00FFFFFF; r = 0; g = 255; b = 255; } // Cyan else if (i == 3) { color = 0xFFA500FF; r = 255; g = 165; b = 0; } // Orange else { color = 0xFF69B4FF; r = 255; g = 105; b = 180; } // Pink ECS::AddSprite(entity, sphereModel, color, 0.0f); - - uint mat = Material::Create(toonShader, r, g, b, 255); - ECS::AddMaterial(entity, mat); - ECS::AddRenderPass(entity, 1, true, true, 0); + ECS::SetSpriteShader(entity, toonShader); // Apply toon shader ECS::AddTag(entity, "Orbiter" + i); entities.insertLast(entity); @@ -109,11 +97,9 @@ void Init() { uint mover = ECS::CreateEntity(); ECS::AddTransform(mover, -3.0f, 0.5f, 0.0f); ECS::AddSprite(mover, cubeModel, 0xFFFFFFFF, 0.0f); // White cube + ECS::SetSpriteShader(mover, toonShader); // Apply toon shader ECS::AddVelocity(mover, 1.0f, 0.0f, 0.5f, 0.0f); // Moving velocity - ECS::AddMaterial(mover, defaultMaterial); - ECS::AddRenderPass(mover, 1, true, true, 0); - ECS::AddTag(mover, "Mover"); entities.insertLast(mover); diff --git a/src/Application.cpp b/src/Application.cpp index 2b6e58a..9ba08fb 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -4,6 +4,7 @@ #include "scripting/ResourceBindings.h" #include "raylib.h" #include "rlgl.h" +#include "raymath.h" #include #include #include @@ -187,182 +188,60 @@ void Application::RenderScene() camera.projection = CAMERA_PERSPECTIVE; } - // Get the first light (if any) for shader uniforms + // Find the first light or use a default Vector3 lightDir = {0.5f, 0.7f, 0.3f}; - float lightIntensity = 1.0f; - auto lightView = registry.view(); - lightView.each([&](auto& light) { - lightDir = light.direction; - lightIntensity = light.intensity; - - static bool loggedLight = false; - if (!loggedLight) { - log_info("Light direction: (%.2f, %.2f, %.2f), intensity: %.2f", - lightDir.x, lightDir.y, lightDir.z, lightIntensity); - loggedLight = true; - } - return; // Use first light only for now + lightView.each([&](auto& lightComp) { + lightDir = Vector3Normalize(lightComp.direction); }); BeginMode3D(camera); DrawGrid(10, 1); - // Collect entities with renderables and organize by render pass - struct RenderableEntity { - entt::entity entity; - ECSTransform* transform; - Sprite* sprite; - RenderPassComponent* renderPass; - }; - - std::vector renderables; - - auto renderView = registry.view(); - renderView.each([&](auto entity, auto& transform, auto& sprite) { - RenderableEntity re; - re.entity = entity; - re.transform = &transform; - re.sprite = &sprite; - re.renderPass = registry.try_get(entity); - renderables.push_back(re); - }); - - // Sort by render pass order (lower = earlier) - std::sort(renderables.begin(), renderables.end(), [](const RenderableEntity& a, const RenderableEntity& b) { - int orderA = a.renderPass ? a.renderPass->order : 0; - int orderB = b.renderPass ? b.renderPass->order : 0; - return orderA < orderB; - }); - - // Group by render pass and render - int currentPassOrder = INT_MIN; - Shader* currentShader = nullptr; - unsigned int currentShaderId = 0; - - for (const auto& re : renderables) { - int passOrder = re.renderPass ? re.renderPass->order : 0; - - // If we've moved to a new render pass, end current shader and update settings - if (passOrder != currentPassOrder) { - if (currentShader) { - EndShaderMode(); - currentShader = nullptr; - } - currentShaderId = 0; // Reset shader tracking for new pass - - // Apply render pass settings - if (re.renderPass) { - if (!re.renderPass->depthTest) { - rlDisableDepthTest(); - } else { - rlEnableDepthTest(); - } - } - - currentPassOrder = passOrder; - } - - // Determine which shader to use: Material shader takes priority, then RenderPass shader - MaterialComponent* matComp = registry.try_get(re.entity); - Color albedo = WHITE; - unsigned int desiredShaderId = 0; - - // Get material data first (for color) - if (matComp && matComp->materialId > 0) { - MaterialData* matData = materialManager.Get(matComp->materialId); - if (matData) { - albedo = matData->albedo; // Always get the color from material - if (matData->shaderId > 0) { - desiredShaderId = matData->shaderId; + // Render all entities with Transform and Sprite components + auto view = registry.view(); + view.each([&](auto& transform, auto& sprite) { + if (sprite.modelId > 0) { + Model* model = modelManager.Get(sprite.modelId); + if (model) { + // If sprite has a shader, apply it with uniforms + if (sprite.shaderId > 0) { + Shader* shader = shaderManager.Get(sprite.shaderId); + if (shader) { + // Set shader uniforms + int albedoLoc = GetShaderLocation(*shader, "albedo"); + int lightDirLoc = GetShaderLocation(*shader, "lightDir"); + + if (albedoLoc != -1) { + Vector4 albedo = { + sprite.color.r / 255.0f, + sprite.color.g / 255.0f, + sprite.color.b / 255.0f, + sprite.color.a / 255.0f + }; + SetShaderValue(*shader, albedoLoc, &albedo, SHADER_UNIFORM_VEC4); + } + + if (lightDirLoc != -1) { + SetShaderValue(*shader, lightDirLoc, &lightDir, SHADER_UNIFORM_VEC3); + } + + // Assign shader to model's first material + model->materials[0].shader = *shader; + } } + // Draw model using Sprite.color as the tint + DrawModelEx(*model, transform.position, Vector3{0, 1, 0}, + transform.rotation * RAD2DEG, transform.scale, + sprite.color); } } - - // Fall back to RenderPass shader if no material shader - if (desiredShaderId == 0 && re.renderPass && re.renderPass->shaderId > 0) { - desiredShaderId = re.renderPass->shaderId; - } - - // Switch shader if needed - if (desiredShaderId != currentShaderId) { - if (currentShader) { - EndShaderMode(); - currentShader = nullptr; - } - - if (desiredShaderId > 0) { - currentShader = shaderManager.Get(desiredShaderId); - if (currentShader) { - BeginShaderMode(*currentShader); - currentShaderId = desiredShaderId; - - // Debug: Log shader switches - static int switchCount = 0; - if (switchCount < 5) { - log_info("Switched to shader %u (raylib id=%u)", desiredShaderId, currentShader->id); - switchCount++; - } - - // Set light direction uniform - int lightLoc = GetShaderLocation(*currentShader, "lightDir"); - if (switchCount <= 1) { - log_info("lightDir uniform location: %d, value=(%.2f,%.2f,%.2f)", - lightLoc, lightDir.x, lightDir.y, lightDir.z); - } - if (lightLoc != -1) { - SetShaderValue(*currentShader, lightLoc, &lightDir, SHADER_UNIFORM_VEC3); - } - } - } else { - currentShaderId = 0; - } - } - - // Set per-entity uniforms (albedo) if shader is active - if (currentShader) { - Vector4 color = { - albedo.r / 255.0f, - albedo.g / 255.0f, - albedo.b / 255.0f, - albedo.a / 255.0f - }; - int albedoLoc = GetShaderLocation(*currentShader, "albedo"); - - // Debug: Log uniform location - static int setCount = 0; - if (setCount < 3) { - log_info("Setting albedo uniform: loc=%d, color=(%.2f,%.2f,%.2f,%.2f)", - albedoLoc, color.x, color.y, color.z, color.w); - setCount++; - } - - if (albedoLoc != -1) { - SetShaderValue(*currentShader, albedoLoc, &color, SHADER_UNIFORM_VEC4); - } - } - - // Render the model with WHITE tint (let shader control color) - if (re.sprite->modelId > 0) { - Model* model = modelManager.Get(re.sprite->modelId); - if (model) { - DrawModelEx(*model, re.transform->position, Vector3{0, 1, 0}, - re.transform->rotation * RAD2DEG, re.transform->scale, - WHITE); - } - } - } - - // Clean up any active shader - if (currentShader) { - EndShaderMode(); - } - - rlEnableDepthTest(); // Ensure depth test is re-enabled + }); EndMode3D(); } + void Application::Draw() { int screenWidth = GetScreenWidth(); diff --git a/src/scripting/ECSBindings.cpp b/src/scripting/ECSBindings.cpp index 11c1b8c..00249b2 100644 --- a/src/scripting/ECSBindings.cpp +++ b/src/scripting/ECSBindings.cpp @@ -151,6 +151,13 @@ void AS_SetSpriteOutline(uint32_t entity, float outlineSize) { } } +void AS_SetSpriteShader(uint32_t entity, unsigned int shaderId) { + if (!registry) return; + if (auto* s = registry->try_get((entt::entity)entity)) { + s->shaderId = shaderId; + } +} + bool AS_HasSprite(uint32_t entity) { if (!registry) return false; return registry->all_of((entt::entity)entity); @@ -441,6 +448,10 @@ void RegisterECSBindings(asIScriptEngine *engine) { asFUNCTION(AS_SetSpriteOutline), asCALL_CDECL); assert(r >= 0); + r = engine->RegisterGlobalFunction("void SetSpriteShader(uint, uint)", + asFUNCTION(AS_SetSpriteShader), asCALL_CDECL); + assert(r >= 0); + r = engine->RegisterGlobalFunction("bool HasSprite(uint)", asFUNCTION(AS_HasSprite), asCALL_CDECL); assert(r >= 0); From a37910de25d3a7644356ca11686928f65f87830f Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Sun, 8 Mar 2026 11:09:09 +1300 Subject: [PATCH 23/53] chore: remove g_ prfix noise --- scripts/example_rendering.as | 82 ++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/scripts/example_rendering.as b/scripts/example_rendering.as index cc2b00c..9b6da77 100644 --- a/scripts/example_rendering.as +++ b/scripts/example_rendering.as @@ -1,88 +1,88 @@ // Example script showing how to use the new script-driven rendering system // Global variables to track our resources -uint g_toonShader = 0; -uint g_outlineShader = 0; -uint g_cubeModel = 0; -uint g_sphereModel = 0; -uint g_redMaterial = 0; -uint g_blueMaterial = 0; +uint toonShader = 0; +uint outlineShader = 0; +uint cubeModel = 0; +uint sphereModel = 0; +uint redMaterial = 0; +uint blueMaterial = 0; // Entities -uint g_camera = 0; -uint g_light = 0; -uint g_cube = 0; -uint g_sphere = 0; +uint camera = 0; +uint light = 0; +uint cube = 0; +uint sphere = 0; void Init() { Toast::Info("Initializing script-driven rendering..."); // === Load Shaders === - g_toonShader = Shader::Load("shaders/toon.vs", "shaders/toon.fs"); - g_outlineShader = Shader::Load("shaders/outline.vs", "shaders/outline.fs"); + toonShader = Shader::Load("shaders/toon.vs", "shaders/toon.fs"); + outlineShader = Shader::Load("shaders/outline.vs", "shaders/outline.fs"); - if (g_toonShader == 0 || g_outlineShader == 0) { + if (toonShader == 0 || outlineShader == 0) { Toast::Error("Failed to load shaders!"); return; } // === Load Models === - g_cubeModel = Model::LoadCube(1.0, 1.0, 1.0); - g_sphereModel = Model::LoadSphere(0.5, 16, 16); + cubeModel = Model::LoadCube(1.0, 1.0, 1.0); + sphereModel = Model::LoadSphere(0.5, 16, 16); // === Create Materials === // Red material with toon shader - g_redMaterial = Material::Create(g_toonShader, 255, 100, 100, 255); + redMaterial = Material::Create(toonShader, 255, 100, 100, 255); // Blue material with toon shader - g_blueMaterial = Material::Create(g_toonShader, 100, 100, 255, 255); + blueMaterial = Material::Create(toonShader, 100, 100, 255, 255); // === Set up Camera === - g_camera = ECS::CreateEntity(); - ECS::AddCamera3D(g_camera, + camera = ECS::CreateEntity(); + ECS::AddCamera3D(camera, 5.0, 5.0, 5.0, // position 0.0, 0.0, 0.0, // target 45.0); // fovy - ECS::AddTag(g_camera, "MainCamera"); + ECS::AddTag(camera, "MainCamera"); // === Set up Light === - g_light = ECS::CreateEntity(); - ECS::AddLight(g_light, 0.5, 0.7, 0.3, 1.0); // direction + intensity - ECS::AddTag(g_light, "MainLight"); + light = ECS::CreateEntity(); + ECS::AddLight(light, 0.5, 0.7, 0.3, 1.0); // direction + intensity + ECS::AddTag(light, "MainLight"); // === Create Cube with Outline === - g_cube = ECS::CreateEntity(); - ECS::AddTransform(g_cube, -1.5, 0.5, 0.0); - ECS::AddSprite(g_cube, g_cubeModel, 0xFFFFFFFF, 0.0); - ECS::AddMaterial(g_cube, g_redMaterial); - ECS::AddTag(g_cube, "Cube"); - ECS::AddVelocity(g_cube, 0.0, 0.0, 0.0, 1.0); // rotating + cube = ECS::CreateEntity(); + ECS::AddTransform(cube, -1.5, 0.5, 0.0); + ECS::AddSprite(cube, cubeModel, 0xFFFFFFFF, 0.0); + ECS::AddMaterial(cube, redMaterial); + ECS::AddTag(cube, "Cube"); + ECS::AddVelocity(cube, 0.0, 0.0, 0.0, 1.0); // rotating // Add outline render pass (order 0 = first) - ECS::AddRenderPass(g_cube, 0, false, true, g_outlineShader); // order=0, no depth test + ECS::AddRenderPass(cube, 0, false, true, outlineShader); // order=0, no depth test // === Create Sphere === - g_sphere = ECS::CreateEntity(); - ECS::AddTransform(g_sphere, 1.5, 0.5, 0.0); - ECS::AddSprite(g_sphere, g_sphereModel, 0xFFFFFFFF, 0.0); - ECS::AddMaterial(g_sphere, g_blueMaterial); - ECS::AddTag(g_sphere, "Sphere"); - ECS::AddVelocity(g_sphere, 0.5, 0.0, 0.2, 0.5); // moving and rotating + sphere = ECS::CreateEntity(); + ECS::AddTransform(sphere, 1.5, 0.5, 0.0); + ECS::AddSprite(sphere, sphereModel, 0xFFFFFFFF, 0.0); + ECS::AddMaterial(sphere, blueMaterial); + ECS::AddTag(sphere, "Sphere"); + ECS::AddVelocity(sphere, 0.5, 0.0, 0.2, 0.5); // moving and rotating // Add main render pass (order 1 = second, after outlines) - ECS::AddRenderPass(g_sphere, 1, true, true, 0); // order=1, with depth test + ECS::AddRenderPass(sphere, 1, true, true, 0); // order=1, with depth test Toast::Success("Script-driven rendering initialized!"); } bool lightToggle = false; void Update(float dt) { // Camera orbital movement - if (ECS::HasCamera3D(g_camera)) { + if (ECS::HasCamera3D(camera)) { float angle = GetTime() * 0.3; float radius = 7.0; float x = Math::Cos(angle) * radius; float z = Math::Sin(angle) * radius; - ECS::SetCameraPosition(g_camera, x, 5.0, z); + ECS::SetCameraPosition(camera, x, 5.0, z); } // Example: Toggle light direction with space @@ -91,10 +91,10 @@ void Update(float dt) { lightToggle = !lightToggle; if (lightToggle) { - ECS::SetLightDirection(g_light, -0.5, 0.7, -0.3); + ECS::SetLightDirection(light, -0.5, 0.7, -0.3); Toast::Info("Light direction changed!"); } else { - ECS::SetLightDirection(g_light, 0.5, 0.7, 0.3); + ECS::SetLightDirection(light, 0.5, 0.7, 0.3); Toast::Info("Light direction reset!"); } } From d0c28dc6630a739844a0681c7df47827971d7b2d Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Sun, 8 Mar 2026 12:14:50 +1300 Subject: [PATCH 24/53] feat: input manager, refactor compliation for efficiency --- CMakeLists.txt | 50 ++++--- imgui.ini | 21 ++- include/Application.h | 2 + include/InputManager.h | 81 ++++++++++ include/scripting/InputBindings.h | 7 + scripts/as.predefined | 44 ++++-- scripts/example_rendering.as | 2 +- scripts/game.as | 38 ++++- src/Application.cpp | 11 +- src/InputManager.cpp | 241 ++++++++++++++++++++++++++++++ src/scripting/InputBindings.cpp | 117 +++++++++++++++ src/scripting/ScriptBindings.cpp | 2 + tests/CMakeLists.txt | 42 ++---- 13 files changed, 580 insertions(+), 78 deletions(-) create mode 100644 include/InputManager.h create mode 100644 include/scripting/InputBindings.h create mode 100644 src/InputManager.cpp create mode 100644 src/scripting/InputBindings.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 69f1aa4..109a103 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,15 +42,6 @@ else() set(HAVE_RLIMGUI FALSE) endif() # ------------------------- -# Tests -# ------------------------- -enable_testing() -add_subdirectory(tests) - -# ------------------------- -# 3️⃣.2️⃣ ECS Bindings -# ------------------------- -# ------------------------- # 3️⃣ scriptstdstring add-on # ------------------------- add_library(scriptstdstring STATIC @@ -84,10 +75,9 @@ target_include_directories(scriptarray ) # ------------------------- -# 4️⃣ Main executable +# 4️⃣ Simian Core Library (SHARED CODE) # ------------------------- -add_executable(simian - main.cpp +add_library(simian_core STATIC src/Application.cpp src/scripting/ScriptEngine.cpp src/scripting/ScriptBindings.cpp @@ -98,6 +88,7 @@ add_executable(simian src/scripting/MathBindings.cpp src/scripting/ECSBindings.cpp src/scripting/ResourceBindings.cpp + src/scripting/InputBindings.cpp src/HotReload.cpp src/gui/GuiManager.cpp src/gui/LogWindow.cpp @@ -105,9 +96,10 @@ add_executable(simian src/ShaderManager.cpp src/ModelManager.cpp src/MaterialManager.cpp + src/InputManager.cpp ) -target_include_directories(simian PUBLIC +target_include_directories(simian_core PUBLIC include include/scripting include/gui @@ -120,7 +112,7 @@ target_include_directories(simian PUBLIC external/imgui ) -target_link_libraries(simian PRIVATE +target_link_libraries(simian_core PUBLIC raylib angelscript scriptstdstring @@ -130,17 +122,24 @@ target_link_libraries(simian PRIVATE ) if(HAVE_RLIMGUI) - target_include_directories(simian PUBLIC ${RLIMGUI_ROOT}/include) - target_link_libraries(simian PRIVATE rlImGui) + target_include_directories(simian_core PUBLIC ${RLIMGUI_ROOT}/include) + target_link_libraries(simian_core PUBLIC rlImGui) # Expose HAVE_RLIMGUI to the C++ compiler so source can guard ImGui calls - target_compile_definitions(simian PRIVATE HAVE_RLIMGUI=1) - message(STATUS "Linking rlImGui into simian") + target_compile_definitions(simian_core PUBLIC HAVE_RLIMGUI=1) + message(STATUS "Linking rlImGui into simian_core") else() message(STATUS "rlImGui not found - building without rlImGui integration") endif() # ------------------------- -# 5️⃣ Platform-specific linking +# 5️⃣ Main executable (just main.cpp) +# ------------------------- +add_executable(simian main.cpp) + +target_link_libraries(simian PRIVATE simian_core) + +# ------------------------- +# 6️⃣ Platform-specific linking # ------------------------- if(WIN32) target_link_libraries(simian PRIVATE winmm gdi32) @@ -149,11 +148,16 @@ elseif(UNIX) endif() # ------------------------- -# 6️⃣ Optional: Compile flags +# 7️⃣ Optional: Compile flags # ------------------------- if(MSVC) - target_compile_options(simian PRIVATE /W4 /EHsc) + target_compile_options(simian_core PRIVATE /W4 /EHsc) else() - target_compile_options(simian PRIVATE -Wall -Wextra -pedantic) + target_compile_options(simian_core PRIVATE -Wall -Wextra -pedantic) endif() -# ------------------------- \ No newline at end of file + +# ------------------------- +# 8️⃣ Tests +# ------------------------- +enable_testing() +add_subdirectory(tests) \ No newline at end of file diff --git a/imgui.ini b/imgui.ini index d6659ad..e474fc2 100644 --- a/imgui.ini +++ b/imgui.ini @@ -21,13 +21,13 @@ Collapsed=0 DockId=0x00000002,0 [Window][##TOAST0] -Pos=1033,637 -Size=227,63 +Pos=1060,637 +Size=200,63 Collapsed=0 [Window][##TOAST1] -Pos=956,564 -Size=304,63 +Pos=1060,564 +Size=200,63 Collapsed=0 [Window][##TOAST2] @@ -36,13 +36,13 @@ Size=196,63 Collapsed=0 [Window][##TOAST3] -Pos=1048,442 -Size=212,57 +Pos=1064,418 +Size=196,63 Collapsed=0 [Window][##TOAST4] -Pos=1048,375 -Size=212,57 +Pos=1064,345 +Size=196,63 Collapsed=0 [Window][Scene (0 entities)] @@ -70,6 +70,11 @@ Pos=60,60 Size=71,108 Collapsed=0 +[Window][##TOAST5] +Pos=1064,272 +Size=196,63 +Collapsed=0 + [Docking][Data] DockSpace ID=0x9076BACA Window=0x34F970D7 Pos=8,28 Size=1264,684 Split=Y Selected=0x27A02DAA DockNode ID=0x00000001 Parent=0x9076BACA SizeRef=1264,580 CentralNode=1 Selected=0x27A02DAA diff --git a/include/Application.h b/include/Application.h index 246326b..055b1fb 100644 --- a/include/Application.h +++ b/include/Application.h @@ -6,6 +6,7 @@ #include "ShaderManager.h" #include "ModelManager.h" #include "MaterialManager.h" +#include "InputManager.h" #include class Application { @@ -38,6 +39,7 @@ private: ShaderManager shaderManager; ModelManager modelManager; MaterialManager materialManager; + InputManager inputManager; static const int WINDOW_WIDTH = 1280; static const int WINDOW_HEIGHT = 720; diff --git a/include/InputManager.h b/include/InputManager.h new file mode 100644 index 0000000..012025b --- /dev/null +++ b/include/InputManager.h @@ -0,0 +1,81 @@ +#pragma once +#include "raylib.h" +#include +#include +#include + +// Input types supported by the action system +enum class InputType { + Keyboard, + MouseButton, + GamepadButton, + GamepadAxis +}; + +// Represents a single input binding (e.g., KEY_SPACE, MOUSE_BUTTON_LEFT) +struct InputBinding { + InputType type; + int code; // Key code, mouse button, or gamepad button + int gamepadId; // For gamepad inputs (0-3) + float axisThreshold; // For axis inputs (e.g., trigger > 0.5) + bool negative; // For axis inputs (e.g., left stick left = negative) + + InputBinding() + : type(InputType::Keyboard) + , code(0) + , gamepadId(0) + , axisThreshold(0.5f) + , negative(false) {} + + InputBinding(InputType t, int c, int gamepad = 0) + : type(t) + , code(c) + , gamepadId(gamepad) + , axisThreshold(0.5f) + , negative(false) {} +}; + +// Manages input actions with remappable bindings +class InputManager { +public: + InputManager(); + ~InputManager(); + + // Action management + void RegisterAction(const std::string& actionName); + void UnregisterAction(const std::string& actionName); + bool HasAction(const std::string& actionName) const; + + // Binding management + void BindKeyboard(const std::string& actionName, int keyCode); + void BindMouseButton(const std::string& actionName, int mouseButton); + void BindGamepadButton(const std::string& actionName, int gamepadId, int button); + void BindGamepadAxis(const std::string& actionName, int gamepadId, int axis, float threshold, bool negative = false); + void ClearBindings(const std::string& actionName); + + // Input queries (called per frame) + bool IsActionPressed(const std::string& actionName) const; + bool IsActionDown(const std::string& actionName) const; + bool IsActionReleased(const std::string& actionName) const; + float GetActionStrength(const std::string& actionName) const; // For analog inputs + + // Configuration + void LoadFromFile(const std::string& filepath); + void SaveToFile(const std::string& filepath) const; + void SetupDefaultBindings(); // Define default controls + + // Get list of all actions + std::vector GetAllActions() const; + + // Get bindings for an action + const std::vector& GetBindings(const std::string& actionName) const; + +private: + std::unordered_map> actions; + + // Helper to check if a single binding is active + bool IsBindingPressed(const InputBinding& binding) const; + bool IsBindingDown(const InputBinding& binding) const; + bool IsBindingReleased(const InputBinding& binding) const; + float GetBindingStrength(const InputBinding& binding) const; +}; diff --git a/include/scripting/InputBindings.h b/include/scripting/InputBindings.h new file mode 100644 index 0000000..17345bd --- /dev/null +++ b/include/scripting/InputBindings.h @@ -0,0 +1,7 @@ +#pragma once + +class asIScriptEngine; +class InputManager; + +void SetGlobalInputManager(InputManager* inputManager); +void RegisterInputBindings(asIScriptEngine* engine); diff --git a/scripts/as.predefined b/scripts/as.predefined index e994fde..afc5497 100644 --- a/scripts/as.predefined +++ b/scripts/as.predefined @@ -170,13 +170,37 @@ namespace Math { float GetTime(); bool IsKeyPressed(int key); -// Raylib key constants -const int KEY_SPACE = 32; -const int KEY_ESCAPE = 256; -const int KEY_ENTER = 257; -const int KEY_TAB = 258; -const int KEY_BACKSPACE = 259; -const int KEY_RIGHT = 262; -const int KEY_LEFT = 263; -const int KEY_DOWN = 264; -const int KEY_UP = 265; +// Input Action System +bool IsActionPressed(const string &in actionName); +bool IsActionDown(const string &in actionName); +bool IsActionReleased(const string &in actionName); +float GetActionStrength(const string &in actionName); +void RegisterAction(const string &in actionName); +void BindKeyboard(const string &in actionName, int keyCode); +void BindMouseButton(const string &in actionName, int mouseButton); +void ClearBindings(const string &in actionName); + +namespace Key { + const int SPACE = 32; + const int ESCAPE = 256; + const int ENTER = 257; + const int TAB = 258; + const int BACKSPACE = 259; + const int RIGHT = 262; + const int LEFT = 263; + const int DOWN = 264; + const int UP = 265; + const int W = 87; + const int A = 65; + const int S = 83; + const int D = 68; + const int E = 69; + const int LEFT_CONTROL = 341; +} + +namespace MouseButton { + const int LEFT = 0; + const int RIGHT = 1; + const int MIDDLE = 2; +} + diff --git a/scripts/example_rendering.as b/scripts/example_rendering.as index 9b6da77..a6ebcd0 100644 --- a/scripts/example_rendering.as +++ b/scripts/example_rendering.as @@ -86,7 +86,7 @@ void Update(float dt) { } // Example: Toggle light direction with space - if (IsKeyPressed(KEY_SPACE)) { + if (IsKeyPressed(Key::SPACE)) { lightToggle = !lightToggle; diff --git a/scripts/game.as b/scripts/game.as index c41c4a4..e481c19 100644 --- a/scripts/game.as +++ b/scripts/game.as @@ -109,7 +109,7 @@ void Init() { void Shutdown() { Log(LOG_TRACE, "Shutdown complete!"); } - +bool lightToggle = false; void Update(float dt) { time += dt; @@ -158,4 +158,40 @@ void Update(float dt) { } } } + + // === Input Action System Demo === + // Toggle light with jump action + if (IsActionPressed("jump")) { + lightToggle = !lightToggle; + + if (lightToggle) { + ECS::SetLightDirection(light, -0.5, 0.7, -0.3); + Toast::Info("Light direction changed!"); + } else { + ECS::SetLightDirection(light, 0.5, 0.7, 0.3); + Toast::Info("Light direction reset!"); + } + } + + // Move player entity with input actions + if (ECS::IsValid(player) && ECS::HasTransform(player)) { + float x, y, z; + ECS::GetPosition(player, x, y, z); + float moveSpeed = 3.0f * dt; + + if (IsActionDown("move_left")) { + x -= moveSpeed; + } + if (IsActionDown("move_right")) { + x += moveSpeed; + } + if (IsActionDown("move_up")) { + z -= moveSpeed; + } + if (IsActionDown("move_down")) { + z += moveSpeed; + } + + ECS::SetPosition(player, x, y, z); + } } diff --git a/src/Application.cpp b/src/Application.cpp index 9ba08fb..c83ecfc 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -82,6 +82,13 @@ bool Application::Initialize(int argc, char *argv[]) extern void SetResourceManagers(ShaderManager*, ModelManager*, MaterialManager*); SetResourceManagers(&shaderManager, &modelManager, &materialManager); + // Set up input manager for script access + extern void SetGlobalInputManager(InputManager*); + SetGlobalInputManager(&inputManager); + + // Setup default input bindings + inputManager.SetupDefaultBindings(); + // Initialize hot reload to watch the scripts directory so any script change // triggers a reload. { @@ -202,11 +209,11 @@ void Application::RenderScene() auto view = registry.view(); view.each([&](auto& transform, auto& sprite) { if (sprite.modelId > 0) { - Model* model = modelManager.Get(sprite.modelId); + Model* model = modelManager.Get(static_cast(sprite.modelId)); if (model) { // If sprite has a shader, apply it with uniforms if (sprite.shaderId > 0) { - Shader* shader = shaderManager.Get(sprite.shaderId); + Shader* shader = shaderManager.Get(static_cast(sprite.shaderId)); if (shader) { // Set shader uniforms int albedoLoc = GetShaderLocation(*shader, "albedo"); diff --git a/src/InputManager.cpp b/src/InputManager.cpp new file mode 100644 index 0000000..16d9a1b --- /dev/null +++ b/src/InputManager.cpp @@ -0,0 +1,241 @@ +#include "InputManager.h" +#include "log/log.h" +#include +#include +#include + +InputManager::InputManager() { +} + +InputManager::~InputManager() { +} + +void InputManager::RegisterAction(const std::string& actionName) { + if (actions.find(actionName) == actions.end()) { + actions[actionName] = std::vector(); + log_debug("Registered input action: %s", actionName.c_str()); + } +} + +void InputManager::UnregisterAction(const std::string& actionName) { + actions.erase(actionName); +} + +bool InputManager::HasAction(const std::string& actionName) const { + return actions.find(actionName) != actions.end(); +} + +void InputManager::BindKeyboard(const std::string& actionName, int keyCode) { + RegisterAction(actionName); + actions[actionName].push_back(InputBinding(InputType::Keyboard, keyCode)); + log_debug("Bound key %d to action: %s", keyCode, actionName.c_str()); +} + +void InputManager::BindMouseButton(const std::string& actionName, int mouseButton) { + RegisterAction(actionName); + actions[actionName].push_back(InputBinding(InputType::MouseButton, mouseButton)); +} + +void InputManager::BindGamepadButton(const std::string& actionName, int gamepadId, int button) { + RegisterAction(actionName); + actions[actionName].push_back(InputBinding(InputType::GamepadButton, button, gamepadId)); +} + +void InputManager::BindGamepadAxis(const std::string& actionName, int gamepadId, int axis, float threshold, bool negative) { + RegisterAction(actionName); + InputBinding binding(InputType::GamepadAxis, axis, gamepadId); + binding.axisThreshold = threshold; + binding.negative = negative; + actions[actionName].push_back(binding); +} + +void InputManager::ClearBindings(const std::string& actionName) { + if (HasAction(actionName)) { + actions[actionName].clear(); + } +} + +bool InputManager::IsActionPressed(const std::string& actionName) const { + auto it = actions.find(actionName); + if (it == actions.end()) return false; + + for (const auto& binding : it->second) { + if (IsBindingPressed(binding)) { + return true; + } + } + return false; +} + +bool InputManager::IsActionDown(const std::string& actionName) const { + auto it = actions.find(actionName); + if (it == actions.end()) return false; + + for (const auto& binding : it->second) { + if (IsBindingDown(binding)) { + return true; + } + } + return false; +} + +bool InputManager::IsActionReleased(const std::string& actionName) const { + auto it = actions.find(actionName); + if (it == actions.end()) return false; + + for (const auto& binding : it->second) { + if (IsBindingReleased(binding)) { + return true; + } + } + return false; +} + +float InputManager::GetActionStrength(const std::string& actionName) const { + auto it = actions.find(actionName); + if (it == actions.end()) return 0.0f; + + float maxStrength = 0.0f; + for (const auto& binding : it->second) { + float strength = GetBindingStrength(binding); + if (std::abs(strength) > std::abs(maxStrength)) { + maxStrength = strength; + } + } + return maxStrength; +} + +bool InputManager::IsBindingPressed(const InputBinding& binding) const { + switch (binding.type) { + case InputType::Keyboard: + return IsKeyPressed(binding.code); + case InputType::MouseButton: + return IsMouseButtonPressed(binding.code); + case InputType::GamepadButton: + if (IsGamepadAvailable(binding.gamepadId)) { + return IsGamepadButtonPressed(binding.gamepadId, binding.code); + } + return false; + case InputType::GamepadAxis: { + // Axis "pressed" is harder to detect - simplified to just checking threshold + if (IsGamepadAvailable(binding.gamepadId)) { + float value = GetGamepadAxisMovement(binding.gamepadId, binding.code); + return binding.negative ? value < -binding.axisThreshold : value > binding.axisThreshold; + } + return false; + } + } + return false; +} + +bool InputManager::IsBindingDown(const InputBinding& binding) const { + switch (binding.type) { + case InputType::Keyboard: + return IsKeyDown(binding.code); + case InputType::MouseButton: + return IsMouseButtonDown(binding.code); + case InputType::GamepadButton: + if (IsGamepadAvailable(binding.gamepadId)) { + return IsGamepadButtonDown(binding.gamepadId, binding.code); + } + return false; + case InputType::GamepadAxis: + if (IsGamepadAvailable(binding.gamepadId)) { + float value = GetGamepadAxisMovement(binding.gamepadId, binding.code); + return binding.negative ? value < -binding.axisThreshold : value > binding.axisThreshold; + } + return false; + } + return false; +} + +bool InputManager::IsBindingReleased(const InputBinding& binding) const { + switch (binding.type) { + case InputType::Keyboard: + return IsKeyReleased(binding.code); + case InputType::MouseButton: + return IsMouseButtonReleased(binding.code); + case InputType::GamepadButton: + if (IsGamepadAvailable(binding.gamepadId)) { + return IsGamepadButtonReleased(binding.gamepadId, binding.code); + } + return false; + case InputType::GamepadAxis: + return false; // Axes don't have a clear "released" state + } + return false; +} + +float InputManager::GetBindingStrength(const InputBinding& binding) const { + switch (binding.type) { + case InputType::Keyboard: + return IsKeyDown(binding.code) ? 1.0f : 0.0f; + case InputType::MouseButton: + return IsMouseButtonDown(binding.code) ? 1.0f : 0.0f; + case InputType::GamepadButton: + if (IsGamepadAvailable(binding.gamepadId)) { + return IsGamepadButtonDown(binding.gamepadId, binding.code) ? 1.0f : 0.0f; + } + return 0.0f; + case InputType::GamepadAxis: + if (IsGamepadAvailable(binding.gamepadId)) { + float value = GetGamepadAxisMovement(binding.gamepadId, binding.code); + return binding.negative ? -value : value; + } + return 0.0f; + } + return 0.0f; +} + +void InputManager::SetupDefaultBindings() { + // Movement + BindKeyboard("move_up", KEY_W); + BindKeyboard("move_up", KEY_UP); + BindKeyboard("move_down", KEY_S); + BindKeyboard("move_down", KEY_DOWN); + BindKeyboard("move_left", KEY_A); + BindKeyboard("move_left", KEY_LEFT); + BindKeyboard("move_right", KEY_D); + BindKeyboard("move_right", KEY_RIGHT); + + // Actions + BindKeyboard("jump", KEY_SPACE); + BindKeyboard("interact", KEY_E); + BindKeyboard("attack", KEY_LEFT_CONTROL); + BindMouseButton("attack", MOUSE_BUTTON_LEFT); + + // Gamepad (if available) + BindGamepadButton("jump", 0, GAMEPAD_BUTTON_RIGHT_FACE_DOWN); + BindGamepadButton("interact", 0, GAMEPAD_BUTTON_RIGHT_FACE_RIGHT); + BindGamepadAxis("move_left", 0, GAMEPAD_AXIS_LEFT_X, 0.3f, true); + BindGamepadAxis("move_right", 0, GAMEPAD_AXIS_LEFT_X, 0.3f, false); + + log_info("Input manager: Default bindings configured"); +} + +std::vector InputManager::GetAllActions() const { + std::vector result; + for (const auto& pair : actions) { + result.push_back(pair.first); + } + return result; +} + +const std::vector& InputManager::GetBindings(const std::string& actionName) const { + static std::vector empty; + auto it = actions.find(actionName); + if (it != actions.end()) { + return it->second; + } + return empty; +} + +void InputManager::LoadFromFile(const std::string& filepath) { + // TODO: Implement config file loading (JSON or simple text format) + log_info("Input config loading not yet implemented: %s", filepath.c_str()); +} + +void InputManager::SaveToFile(const std::string& filepath) const { + // TODO: Implement config file saving + log_info("Input config saving not yet implemented: %s", filepath.c_str()); +} diff --git a/src/scripting/InputBindings.cpp b/src/scripting/InputBindings.cpp new file mode 100644 index 0000000..dd43d3e --- /dev/null +++ b/src/scripting/InputBindings.cpp @@ -0,0 +1,117 @@ +#include "scripting/InputBindings.h" +#include "InputManager.h" +#include +#include + +static InputManager* g_inputManager = nullptr; + +void SetGlobalInputManager(InputManager* inputManager) { + g_inputManager = inputManager; +} + +// AngelScript wrapper functions +static bool AS_IsActionPressed(const std::string& actionName) { + return g_inputManager ? g_inputManager->IsActionPressed(actionName) : false; +} + +static bool AS_IsActionDown(const std::string& actionName) { + return g_inputManager ? g_inputManager->IsActionDown(actionName) : false; +} + +static bool AS_IsActionReleased(const std::string& actionName) { + return g_inputManager ? g_inputManager->IsActionReleased(actionName) : false; +} + +static float AS_GetActionStrength(const std::string& actionName) { + return g_inputManager ? g_inputManager->GetActionStrength(actionName) : 0.0f; +} + +static void AS_RegisterAction(const std::string& actionName) { + if (g_inputManager) g_inputManager->RegisterAction(actionName); +} + +static void AS_BindKeyboard(const std::string& actionName, int keyCode) { + if (g_inputManager) g_inputManager->BindKeyboard(actionName, keyCode); +} + +static void AS_BindMouseButton(const std::string& actionName, int mouseButton) { + if (g_inputManager) g_inputManager->BindMouseButton(actionName, mouseButton); +} + +static void AS_ClearBindings(const std::string& actionName) { + if (g_inputManager) g_inputManager->ClearBindings(actionName); +} + +void RegisterInputBindings(asIScriptEngine* engine) { + int r; + + // Input action queries + r = engine->RegisterGlobalFunction("bool IsActionPressed(const string &in)", + asFUNCTION(AS_IsActionPressed), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("bool IsActionDown(const string &in)", + asFUNCTION(AS_IsActionDown), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("bool IsActionReleased(const string &in)", + asFUNCTION(AS_IsActionReleased), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("float GetActionStrength(const string &in)", + asFUNCTION(AS_GetActionStrength), asCALL_CDECL); + assert(r >= 0); + + // Allow runtime binding from scripts + r = engine->RegisterGlobalFunction("void RegisterAction(const string &in)", + asFUNCTION(AS_RegisterAction), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void BindKeyboard(const string &in, int)", + asFUNCTION(AS_BindKeyboard), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void BindMouseButton(const string &in, int)", + asFUNCTION(AS_BindMouseButton), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void ClearBindings(const string &in)", + asFUNCTION(AS_ClearBindings), asCALL_CDECL); + assert(r >= 0); + + // Key constants for binding + r = engine->RegisterEnum("Key"); + assert(r >= 0); + r = engine->RegisterEnumValue("Key", "W", KEY_W); + assert(r >= 0); + r = engine->RegisterEnumValue("Key", "A", KEY_A); + assert(r >= 0); + r = engine->RegisterEnumValue("Key", "S", KEY_S); + assert(r >= 0); + r = engine->RegisterEnumValue("Key", "D", KEY_D); + assert(r >= 0); + r = engine->RegisterEnumValue("Key", "SPACE", KEY_SPACE); + assert(r >= 0); + r = engine->RegisterEnumValue("Key", "E", KEY_E); + assert(r >= 0); + r = engine->RegisterEnumValue("Key", "LEFT_CONTROL", KEY_LEFT_CONTROL); + assert(r >= 0); + r = engine->RegisterEnumValue("Key", "UP", KEY_UP); + assert(r >= 0); + r = engine->RegisterEnumValue("Key", "DOWN", KEY_DOWN); + assert(r >= 0); + r = engine->RegisterEnumValue("Key", "LEFT", KEY_LEFT); + assert(r >= 0); + r = engine->RegisterEnumValue("Key", "RIGHT", KEY_RIGHT); + assert(r >= 0); + + r = engine->RegisterEnum("MouseButton"); + assert(r >= 0); + // Mouse button constants + r = engine->RegisterEnumValue("MouseButton", "LEFT", MOUSE_BUTTON_LEFT); + assert(r >= 0); + r= engine->RegisterEnumValue("MouseButton", "RIGHT", MOUSE_BUTTON_RIGHT); + assert(r >= 0); + r = engine->RegisterEnumValue("MouseButton", "MIDDLE", MOUSE_BUTTON_MIDDLE); + assert(r >= 0); +} diff --git a/src/scripting/ScriptBindings.cpp b/src/scripting/ScriptBindings.cpp index 3ac898c..20ceb57 100644 --- a/src/scripting/ScriptBindings.cpp +++ b/src/scripting/ScriptBindings.cpp @@ -6,6 +6,7 @@ #include "scripting/MathBindings.h" #include "scripting/ECSBindings.h" #include "scripting/ResourceBindings.h" +#include "scripting/InputBindings.h" void ScriptBindings::RegisterAll(asIScriptEngine *engine) { @@ -17,4 +18,5 @@ void ScriptBindings::RegisterAll(asIScriptEngine *engine) RegisterMathBindings(engine); RegisterECSBindings(engine); RegisterResourceBindings(engine); + RegisterInputBindings(engine); } \ No newline at end of file diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index f8d9f39..580e2c7 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,50 +1,26 @@ cmake_minimum_required(VERSION 3.16) -# Simple unit test executable that compiles acutest.c directly +# Unit tests just need test sources + link to simian_core add_executable(unit_tests test.cpp hot_reload.cpp script_engine_tests.cpp math_bindings_tests.cpp - ${CMAKE_SOURCE_DIR}/src/HotReload.cpp - ${CMAKE_SOURCE_DIR}/src/scripting/ScriptEngine.cpp - ${CMAKE_SOURCE_DIR}/src/scripting/ScriptBindings.cpp - ${CMAKE_SOURCE_DIR}/src/scripting/ToastBindings.cpp - ${CMAKE_SOURCE_DIR}/src/scripting/LogBindings.cpp - ${CMAKE_SOURCE_DIR}/src/scripting/ECSBindings.cpp - ${CMAKE_SOURCE_DIR}/src/scripting/ImageBindings.cpp - ${CMAKE_SOURCE_DIR}/src/scripting/TextureBindings.cpp - ${CMAKE_SOURCE_DIR}/src/scripting/MathBindings.cpp - ${CMAKE_SOURCE_DIR}/src/scripting/ResourceBindings.cpp - ${CMAKE_SOURCE_DIR}/src/ShaderManager.cpp - ${CMAKE_SOURCE_DIR}/src/ModelManager.cpp - ${CMAKE_SOURCE_DIR}/src/MaterialManager.cpp - ${CMAKE_SOURCE_DIR}/src/log/log.c ) target_include_directories(unit_tests PRIVATE ${CMAKE_SOURCE_DIR}/tests ${CMAKE_SOURCE_DIR}/include - ${CMAKE_SOURCE_DIR}/src/log - ${CMAKE_SOURCE_DIR}/external/angelscript/sdk/angelscript/include - ${CMAKE_SOURCE_DIR}/external/angelscript/sdk/add_on/scriptstdstring - ${CMAKE_SOURCE_DIR}/external/angelscript/sdk/add_on/scriptbuilder - ${CMAKE_SOURCE_DIR}/external/angelscript/sdk/add_on/scriptarray - ${CMAKE_SOURCE_DIR}/external/raylib/src - ${CMAKE_SOURCE_DIR}/external/imgui - ${CMAKE_SOURCE_DIR}/external/rlImGui - + ${CMAKE_SOURCE_DIR}/external/acutest ) -# Link AngelScript and its add-ons needed by ScriptEngine -target_link_libraries(unit_tests PRIVATE - angelscript - scriptstdstring - scriptbuilder - scriptarray - raylib - imgui -) +# Link the shared simian_core library - that's it! +target_link_libraries(unit_tests PRIVATE simian_core) + +# Platform-specific linking for tests too +if(WIN32) + target_link_libraries(unit_tests PRIVATE winmm gdi32) +endif() add_test(NAME unit_tests COMMAND unit_tests) add_test(NAME hotreload_dir COMMAND unit_tests hotreload_dir) From 33226dfae1e5051e0d1bee9a5dddff1c4f994a39 Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Sun, 8 Mar 2026 14:48:55 +1300 Subject: [PATCH 25/53] feat: Wiki pages and sync --- .github/workflows/sync-docs-to-wiki.yml | 36 ++++++++++ docs/Home.md | 12 ++++ docs/Scripting.md | 13 ++++ docs/Usage.md | 95 +++++++++++++++++++++++++ scripts/sync_wiki.sh | 27 +++++++ 5 files changed, 183 insertions(+) create mode 100644 .github/workflows/sync-docs-to-wiki.yml create mode 100644 docs/Home.md create mode 100644 docs/Scripting.md create mode 100644 docs/Usage.md create mode 100644 scripts/sync_wiki.sh diff --git a/.github/workflows/sync-docs-to-wiki.yml b/.github/workflows/sync-docs-to-wiki.yml new file mode 100644 index 0000000..94745af --- /dev/null +++ b/.github/workflows/sync-docs-to-wiki.yml @@ -0,0 +1,36 @@ +name: Sync Docs to Gitea Wiki + +on: + push: + paths: + - 'docs/**' + +jobs: + sync: + name: Sync docs to Gitea wiki + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Start SSH agent + uses: webfactory/ssh-agent@v0.8.1 + with: + ssh-private-key: ${{ secrets.WIKI_SSH_KEY }} + + - name: Sync docs to wiki + env: + WIKI_REPO: git@gitea.appstack.me:nick/simian.wiki.git + run: | + git config --global user.name "Simian CI" + git config --global user.email "ci@simian.local" + git clone "$WIKI_REPO" wiki + rsync -av --delete docs/ wiki/ + cd wiki + git add -A + if git diff --staged --quiet; then + echo "No wiki changes" + else + git commit -m "Update wiki from docs (CI)" + git push origin HEAD + fi diff --git a/docs/Home.md b/docs/Home.md new file mode 100644 index 0000000..c06761d --- /dev/null +++ b/docs/Home.md @@ -0,0 +1,12 @@ +# Simian Documentation + +This folder contains project documentation that is synced to the project's Gitea wiki. +Edit markdown files here and push to the repository; CI will mirror them to the wiki. + +## Pages +- [Scripting](Scripting.md) — scripting API and examples +- [Usage](Usage.md) — getting started and build instructions + +## Notes +The CI workflow (.github/workflows/sync-docs-to-wiki.yml) clones the wiki repository and copies these files into it. +Make sure `GITEA_SSH_KEY` is configured in repository secrets (SSH private key with push access to the wiki). diff --git a/docs/Scripting.md b/docs/Scripting.md new file mode 100644 index 0000000..124402a --- /dev/null +++ b/docs/Scripting.md @@ -0,0 +1,13 @@ +# Scripting + +This page is a starting point for scripting documentation. + +## Overview +- Scripts live in `scripts/` and are executed by AngelScript. +- Predefined API and engine bindings are declared in `scripts/as.predefined`. + +## Examples +- `scripts/game.as` — demo showing ECS usage, rendering and input actions. + +## How to document APIs +Add Markdown pages in the `docs/` folder. Use relative links and include code fences for examples. diff --git a/docs/Usage.md b/docs/Usage.md new file mode 100644 index 0000000..4bb1f07 --- /dev/null +++ b/docs/Usage.md @@ -0,0 +1,95 @@ +# Usage + +This page documents how to build, run and maintain the Simian project and how to publish documentation to the Gitea wiki. + +## Prerequisites + +- Git +- CMake (>= 3.16; 3.25 recommended) +- A C++ toolchain (Visual Studio on Windows, GCC/Clang on Linux/macOS) +- Optional: SSH access to your Gitea instance (for wiki sync) + +If you just cloned the repository, initialise submodules: + +```bash +git submodule update --init --recursive +``` + +## Build (Windows / MSVC) + +```powershell +mkdir build +cd build +cmake -S .. -B . -G "Visual Studio 17 2022" -A x64 +cmake --build . --config Release +# Run +.\Release\simian.exe +``` + +## Build (Linux / macOS) + +```bash +mkdir build +cd build +cmake .. +cmake --build . --config Release +./simian +``` + +## Run tests + +From the project root (after configuring the build): + +```bash +cmake --build build --config Release --target RUN_TESTS +# or use CTest +ctest --test-dir build --output-on-failure +``` + +## Scripting / Hot-reload + +- Scripts live in the `scripts/` directory (e.g. `scripts/game.as`). +- The engine watches the scripts directory and will hot-reload scripts when changed. +- Predefined API is declared in `scripts/as.predefined`. + +## Documentation & Wiki + +Docs source lives in the `docs/` folder. The repository contains a CI workflow and a local script to mirror `docs/` to the Gitea wiki. + +Manual sync (local): + +```bash +bash scripts/sync_wiki.sh +``` + +CI sync (automated): + +1. The workflow `.github/workflows/sync-docs-to-wiki.yml` runs on pushes that affect `docs/**`. +2. The workflow requires an SSH private key in repository secrets named `GITEA_SSH_KEY`. + +To create the deploy key and CI secret: + +```bash +# Generate a keypair (do not commit the private key) +ssh-keygen -t ed25519 -C "simian-wiki-ci" -f simian_wiki_ci -N "" + +# Add simian_wiki_ci.pub as a deploy key in your Gitea repo: Settings → Deploy Keys +# Enable write/push access for that key. + +# Copy the private key (simian_wiki_ci) into your CI provider as secret GITEA_SSH_KEY. +``` + +Notes: +- The workflow clones the wiki remote `git@gitea.appstack.me:nick/simian.wiki.git` and pushes updates. +- If your Gitea host/paths differ, update `.github/workflows/sync-docs-to-wiki.yml` or the `scripts/sync_wiki.sh` script accordingly. + +## Adding / Updating Documentation + +1. Add or edit Markdown files under `docs/`. +2. Put images in `docs/images/` and reference them with relative paths, e.g. `![Alt](images/diagram.png)`. +3. Commit and push to the repo; CI will sync changes automatically (once secrets/deploy-key are configured). + +## Troubleshooting + +- If the CI job fails with authentication errors, confirm the deploy key was added to the Gitea repo and the private key is stored in the CI secrets as `GITEA_SSH_KEY`. +- To debug locally, run the `scripts/sync_wiki.sh` script and watch for `git push` errors. diff --git a/scripts/sync_wiki.sh b/scripts/sync_wiki.sh new file mode 100644 index 0000000..f6b93ed --- /dev/null +++ b/scripts/sync_wiki.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Script to sync local docs/ to the Gitea wiki for this repo. +# Requires SSH access to the wiki (deploy key or account key). + +WIKI_REPO="git@gitea.appstack.me:nick/simian.wiki.git" + +TMPDIR="$(mktemp -d)" +echo "Cloning wiki to $TMPDIR" +git clone "$WIKI_REPO" "$TMPDIR" + +echo "Syncing docs/ -> wiki/" +rsync -av --delete docs/ "$TMPDIR"/ + +pushd "$TMPDIR" > /dev/null +git add -A +if git diff --staged --quiet; then + echo "No changes to wiki" +else + git commit -m "Update wiki from docs" + git push origin HEAD +fi +popd > /dev/null + +rm -rf "$TMPDIR" +echo "Done." From 9f8686345c67c337b7105a63f58f30ca715425d3 Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Sun, 8 Mar 2026 14:50:43 +1300 Subject: [PATCH 26/53] fix: move CI piplein to correct folder --- {.github => .gitea}/workflows/sync-docs-to-wiki.yml | 0 docs/Home.md | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename {.github => .gitea}/workflows/sync-docs-to-wiki.yml (100%) diff --git a/.github/workflows/sync-docs-to-wiki.yml b/.gitea/workflows/sync-docs-to-wiki.yml similarity index 100% rename from .github/workflows/sync-docs-to-wiki.yml rename to .gitea/workflows/sync-docs-to-wiki.yml diff --git a/docs/Home.md b/docs/Home.md index c06761d..7c8e5e3 100644 --- a/docs/Home.md +++ b/docs/Home.md @@ -9,4 +9,4 @@ Edit markdown files here and push to the repository; CI will mirror them to the ## Notes The CI workflow (.github/workflows/sync-docs-to-wiki.yml) clones the wiki repository and copies these files into it. -Make sure `GITEA_SSH_KEY` is configured in repository secrets (SSH private key with push access to the wiki). +Make sure `WIKI_SSH_KEY` is configured in repository secrets (SSH private key with push access to the wiki). From 95deb65106add09e04ad5c192786b1976ed0a5d4 Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Sun, 8 Mar 2026 15:00:19 +1300 Subject: [PATCH 27/53] chore: trying CI workflow --- .gitea/workflows/sync-docs-to-wiki.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/sync-docs-to-wiki.yml b/.gitea/workflows/sync-docs-to-wiki.yml index 94745af..55d3f46 100644 --- a/.gitea/workflows/sync-docs-to-wiki.yml +++ b/.gitea/workflows/sync-docs-to-wiki.yml @@ -14,7 +14,7 @@ jobs: uses: actions/checkout@v4 - name: Start SSH agent - uses: webfactory/ssh-agent@v0.8.1 + uses: webfactory/ssh-agent@v0.9.0 with: ssh-private-key: ${{ secrets.WIKI_SSH_KEY }} From 50ec04aa12aa820031f404ae3890c2232e50af28 Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Sun, 8 Mar 2026 15:03:16 +1300 Subject: [PATCH 28/53] chore: minor change to commit docs --- docs/Usage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Usage.md b/docs/Usage.md index 4bb1f07..da6020c 100644 --- a/docs/Usage.md +++ b/docs/Usage.md @@ -76,7 +76,7 @@ ssh-keygen -t ed25519 -C "simian-wiki-ci" -f simian_wiki_ci -N "" # Add simian_wiki_ci.pub as a deploy key in your Gitea repo: Settings → Deploy Keys # Enable write/push access for that key. -# Copy the private key (simian_wiki_ci) into your CI provider as secret GITEA_SSH_KEY. +# Copy the private key (simian_wiki_ci) into your CI provider as secret WIKI_SSH_KEY. ``` Notes: From 15e5d580da1ccf82d969257f149e195ded682f86 Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Sun, 8 Mar 2026 15:37:25 +1300 Subject: [PATCH 29/53] feat: Scenegraph --- .gitea/workflows/sync-docs-to-wiki.yml | 5 + CMakeLists.txt | 3 + docs/Home.md | 3 +- docs/Scenegraph.md | 94 +++++++ docs/Usage.md | 11 +- imgui.ini | 8 +- include/ECSComponents.h | 21 ++ include/SceneGraph.h | 16 ++ include/SceneLoader.h | 17 ++ include/scripting/SceneBindings.h | 5 + scenes/demo.toml | 36 +++ scripts/as.predefined | 11 + scripts/game.as | 186 ++------------ src/Application.cpp | 11 +- src/SceneGraph.cpp | 139 +++++++++++ src/SceneLoader.cpp | 333 +++++++++++++++++++++++++ src/scripting/ECSBindings.cpp | 61 ++++- src/scripting/SceneBindings.cpp | 28 +++ src/scripting/ScriptBindings.cpp | 2 + 19 files changed, 820 insertions(+), 170 deletions(-) create mode 100644 docs/Scenegraph.md create mode 100644 include/SceneGraph.h create mode 100644 include/SceneLoader.h create mode 100644 include/scripting/SceneBindings.h create mode 100644 scenes/demo.toml create mode 100644 src/SceneGraph.cpp create mode 100644 src/SceneLoader.cpp create mode 100644 src/scripting/SceneBindings.cpp diff --git a/.gitea/workflows/sync-docs-to-wiki.yml b/.gitea/workflows/sync-docs-to-wiki.yml index 55d3f46..b46679f 100644 --- a/.gitea/workflows/sync-docs-to-wiki.yml +++ b/.gitea/workflows/sync-docs-to-wiki.yml @@ -18,6 +18,11 @@ jobs: with: ssh-private-key: ${{ secrets.WIKI_SSH_KEY }} + - name: Add Gitea host key + run: | + mkdir -p ~/.ssh + ssh-keyscan -t rsa,gssapi-with-mic,gssapi-keyex gitea.appstack.me >> ~/.ssh/known_hosts + - name: Sync docs to wiki env: WIKI_REPO: git@gitea.appstack.me:nick/simian.wiki.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 109a103..26b4f72 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -79,6 +79,8 @@ target_include_directories(scriptarray # ------------------------- add_library(simian_core STATIC src/Application.cpp + src/SceneGraph.cpp + src/SceneLoader.cpp src/scripting/ScriptEngine.cpp src/scripting/ScriptBindings.cpp src/scripting/ToastBindings.cpp @@ -89,6 +91,7 @@ add_library(simian_core STATIC src/scripting/ECSBindings.cpp src/scripting/ResourceBindings.cpp src/scripting/InputBindings.cpp + src/scripting/SceneBindings.cpp src/HotReload.cpp src/gui/GuiManager.cpp src/gui/LogWindow.cpp diff --git a/docs/Home.md b/docs/Home.md index 7c8e5e3..b124b85 100644 --- a/docs/Home.md +++ b/docs/Home.md @@ -6,7 +6,8 @@ Edit markdown files here and push to the repository; CI will mirror them to the ## Pages - [Scripting](Scripting.md) — scripting API and examples - [Usage](Usage.md) — getting started and build instructions +- [Scenegraph](Scenegraph.md) — hierarchy components and scene format ## Notes -The CI workflow (.github/workflows/sync-docs-to-wiki.yml) clones the wiki repository and copies these files into it. +The CI workflow (.gitea/workflows/sync-docs-to-wiki.yml) clones the wiki repository and copies these files into it. Make sure `WIKI_SSH_KEY` is configured in repository secrets (SSH private key with push access to the wiki). diff --git a/docs/Scenegraph.md b/docs/Scenegraph.md new file mode 100644 index 0000000..74382c2 --- /dev/null +++ b/docs/Scenegraph.md @@ -0,0 +1,94 @@ +# Scenegraph + +This project uses a lightweight hierarchy component to model parent/child relationships in ECS. +The scenegraph is EnTT-friendly and uses a linked-list structure for children. + +## Components + +### `Hierarchy` +Each entity can have a `Hierarchy` component with these fields: + +- `parent` — parent entity or `null` +- `first` — first child entity +- `prev` / `next` — sibling links + +This mirrors the common EnTT scenegraph pattern and avoids storing vectors of children inside a component. + +### `ECSTransform` (local) +Stores local position/scale and a Y-axis rotation (radians). + +### `WorldTransform` (computed) +Computed each frame from the hierarchy and local transform. Rendering uses `WorldTransform` so children move with parents. + +## Update Order + +1. Systems update local transforms (e.g., velocity system). +2. `UpdateWorldTransforms()` traverses the hierarchy and computes `WorldTransform`. +3. Rendering draws from `WorldTransform` + `Sprite`. + +## Script API + +```angelscript +ECS::SetParent(child, parent); +ECS::ClearParent(child); +uint p = ECS::GetParent(child); +bool has = ECS::HasParent(child); +``` + +## Scene File Format (TOML) + +Scenes are stored in `scenes/*.toml` using a minimal TOML-like structure. Example: + +```toml +[[entity]] +id = "root" +tag = "Root" +position = [0.0, 0.0, 0.0] +rotation_deg = 0.0 +scale = [1.0, 1.0, 1.0] + +[[entity]] +id = "parent" +parent = "root" +tag = "Parent" +position = [2.0, 0.0, 0.0] +model = "cube" +model_size = [1.0, 1.0, 1.0] +color = 0x00FF00FF +shader_vs = "shaders/toon.vs" +shader_fs = "shaders/toon.fs" + +[[entity]] +id = "child" +parent = "parent" +tag = "Child" +position = [0.0, 1.25, 0.0] +model = "sphere" +radius = 0.5 +color = 0xFF0000FF +shader_vs = "shaders/toon.vs" +shader_fs = "shaders/toon.fs" +``` + +### Supported Keys + +- `id` (string) — unique identifier for parent links +- `parent` (string) — parent entity id +- `tag` (string) — `Tag` component value +- `position` (vec3) +- `rotation` (radians) or `rotation_deg` (degrees) +- `scale` (vec3) +- `model` — `cube`, `sphere`, `plane`, or file path +- `model_size` (vec3) for cubes/planes +- `radius`, `rings`, `slices` for spheres +- `color` — hex `0xRRGGBBAA` (matches script colors) +- `outline_size` — optional sprite outline +- `shader_vs`, `shader_fs` — optional shader paths + +## Loading a Scene + +```angelscript +uint root = Scene::Load("scenes/demo.toml"); +``` + +`Scene::Load` returns a root entity that parents all top-level entities. Entity id `0` can be valid in EnTT, so use `ECS::IsValid(root)` to check success. diff --git a/docs/Usage.md b/docs/Usage.md index da6020c..2ed7f30 100644 --- a/docs/Usage.md +++ b/docs/Usage.md @@ -64,8 +64,8 @@ bash scripts/sync_wiki.sh CI sync (automated): -1. The workflow `.github/workflows/sync-docs-to-wiki.yml` runs on pushes that affect `docs/**`. -2. The workflow requires an SSH private key in repository secrets named `GITEA_SSH_KEY`. +1. The workflow `.gitea/workflows/sync-docs-to-wiki.yml` runs on pushes that affect `docs/**`. +2. The workflow requires an SSH private key in repository secrets named `WIKI_SSH_KEY`. To create the deploy key and CI secret: @@ -91,5 +91,10 @@ Notes: ## Troubleshooting -- If the CI job fails with authentication errors, confirm the deploy key was added to the Gitea repo and the private key is stored in the CI secrets as `GITEA_SSH_KEY`. +- If the CI job fails with authentication errors, confirm the deploy key was added to the Gitea repo and the private key is stored in the CI secrets as `WIKI_SSH_KEY`. - To debug locally, run the `scripts/sync_wiki.sh` script and watch for `git push` errors. + +## Scenes + +Scenes are stored as TOML files in `scenes/`. Use `Scene::Load("scenes/demo.toml")` from scripts to create entities with hierarchy relationships. +See [Scenegraph](Scenegraph.md) for the format and examples. diff --git a/imgui.ini b/imgui.ini index e474fc2..4a469ff 100644 --- a/imgui.ini +++ b/imgui.ini @@ -21,13 +21,13 @@ Collapsed=0 DockId=0x00000002,0 [Window][##TOAST0] -Pos=1060,637 -Size=200,63 +Pos=1035,637 +Size=225,63 Collapsed=0 [Window][##TOAST1] -Pos=1060,564 -Size=200,63 +Pos=1057,564 +Size=203,63 Collapsed=0 [Window][##TOAST2] diff --git a/include/ECSComponents.h b/include/ECSComponents.h index b808a8c..721f6da 100644 --- a/include/ECSComponents.h +++ b/include/ECSComponents.h @@ -1,5 +1,6 @@ #pragma once #include "raylib.h" +#include "entt.hpp" #include // ECSTransform component - position, rotation, and scale @@ -55,6 +56,26 @@ struct Tag { Tag(const std::string& n) : name(n) {} }; +// Hierarchy component - parent/child links using EnTT-friendly linked list +struct Hierarchy { + entt::entity parent{entt::null}; + entt::entity first{entt::null}; + entt::entity prev{entt::null}; + entt::entity next{entt::null}; +}; + +// WorldTransform component - computed from hierarchy + local transform +struct WorldTransform { + Vector3 position; + Vector3 scale; + float rotation; // Rotation around Y axis in radians + + WorldTransform() + : position{0.0f, 0.0f, 0.0f} + , scale{1.0f, 1.0f, 1.0f} + , rotation(0.0f) {} +}; + // Camera3D component - camera settings struct Camera3DComponent { Vector3 position; diff --git a/include/SceneGraph.h b/include/SceneGraph.h new file mode 100644 index 0000000..154febb --- /dev/null +++ b/include/SceneGraph.h @@ -0,0 +1,16 @@ +#pragma once + +#include "entt.hpp" + + +// Attach child to parent (updates linked list) +void AttachChild(entt::registry& registry, entt::entity child, entt::entity parent); + +// Detach child from its parent (if any) +void DetachFromParent(entt::registry& registry, entt::entity child); + +// Detach all children from a parent (orphans them) +void DetachChildren(entt::registry& registry, entt::entity parent); + +// Update WorldTransform for all entities using hierarchy traversal +void UpdateWorldTransforms(entt::registry& registry); diff --git a/include/SceneLoader.h b/include/SceneLoader.h new file mode 100644 index 0000000..142699f --- /dev/null +++ b/include/SceneLoader.h @@ -0,0 +1,17 @@ +#pragma once + +#include "entt.hpp" +#include + +class ModelManager; +class ShaderManager; + + +// Set global context used by scene loading +void SetSceneContext(entt::registry* registry, ModelManager* modelManager, ShaderManager* shaderManager); + +// Load a scene from a TOML-like file. Returns the root entity (or entt::null on failure). +entt::entity LoadSceneFromFile(const std::string& path, bool clearExisting); + +// Clear all entities from the registry +void ClearScene(); diff --git a/include/scripting/SceneBindings.h b/include/scripting/SceneBindings.h new file mode 100644 index 0000000..5dece1d --- /dev/null +++ b/include/scripting/SceneBindings.h @@ -0,0 +1,5 @@ +#pragma once + +class asIScriptEngine; + +void RegisterSceneBindings(asIScriptEngine* engine); diff --git a/scenes/demo.toml b/scenes/demo.toml new file mode 100644 index 0000000..0d717a5 --- /dev/null +++ b/scenes/demo.toml @@ -0,0 +1,36 @@ +# Simian demo scene with hierarchy + +[[entity]] +id = "root" +tag = "Root" +position = [0.0, 0.0, 0.0] +rotation_deg = 0.0 +scale = [1.0, 1.0, 1.0] + +[[entity]] +id = "parent" +tag = "Parent" +parent = "root" +position = [2.0, 0.0, 0.0] +rotation_deg = 0.0 +scale = [1.0, 1.0, 1.0] +model = "cube" +model_size = [1.0, 1.0, 1.0] +color = 0x00FF00FF +shader_vs = "shaders/toon.vs" +shader_fs = "shaders/toon.fs" + +[[entity]] +id = "child" +tag = "Child" +parent = "parent" +position = [0.0, 1.25, 0.0] +rotation_deg = 0.0 +scale = [0.6, 0.6, 0.6] +model = "sphere" +radius = 0.5 +rings = 16 +slices = 16 +color = 0xFFFF00FF +shader_vs = "shaders/toon.vs" +shader_fs = "shaders/toon.fs" diff --git a/scripts/as.predefined b/scripts/as.predefined index afc5497..875bb92 100644 --- a/scripts/as.predefined +++ b/scripts/as.predefined @@ -70,6 +70,12 @@ namespace ECS { void SetTag(uint entity, const string &in name); bool HasTag(uint entity); void RemoveTag(uint entity); + + // Hierarchy component + void SetParent(uint child, uint parent); + void ClearParent(uint child); + uint GetParent(uint child); + bool HasParent(uint child); // Camera3D component void AddCamera3D(uint entity, float px, float py, float pz, float tx, float ty, float tz, float fovy); @@ -125,6 +131,11 @@ namespace Material { void SetAlbedo(uint id, uint8 r, uint8 g, uint8 b, uint8 a); } +namespace Scene { + uint Load(const string &in path, bool clearExisting = true); + void Clear(); +} + namespace Texture { class Image { int width; diff --git a/scripts/game.as b/scripts/game.as index e481c19..1cc28b0 100644 --- a/scripts/game.as +++ b/scripts/game.as @@ -1,169 +1,59 @@ -// ECS-based game script demo with script-driven rendering -// This demonstrates creating entities with various components and managing rendering +// ECS scenegraph demo +// Loads a scene from TOML and animates the hierarchy -// Resource IDs -uint toonShader = 0; -uint outlineShader = 0; -uint cubeModel = 0; -uint sphereModel = 0; -uint defaultMaterial = 0; - -// Scene entities +uint sceneRoot = 0; uint camera = 0; uint light = 0; - -// Store entity IDs for manipulation -array entities; -uint player; -uint spinningCube; float time = 0.0f; +bool lightToggle = false; void Init() { - Log(LOG_TRACE, "Initialization complete - ECS Demo with Script-Driven Rendering!"); - Toast::Success("ECS Script initialized successfully!"); - - // === Load shaders === - toonShader = Shader::Load("shaders/toon.vs", "shaders/toon.fs"); - outlineShader = Shader::Load("shaders/outline.vs", "shaders/outline.fs"); - - if (toonShader == 0 || outlineShader == 0) { - Toast::Error("Failed to load shaders!"); - return; + Log(LOG_TRACE, "Initialization complete - Scenegraph demo!"); + Toast::Success("Scenegraph demo initialized."); + + sceneRoot = Scene::Load("scenes/demo.toml"); + if (!ECS::IsValid(sceneRoot)) { + Toast::Error("Failed to load scene"); } - - // === Load models === - cubeModel = Model::LoadCube(1.0, 1.0, 1.0); - sphereModel = Model::LoadSphere(0.5, 16, 16); - - // === Create default material === - defaultMaterial = Material::Create(toonShader, 255, 255, 255, 255); - + // === Set up camera === camera = ECS::CreateEntity(); - ECS::AddCamera3D(camera, + ECS::AddCamera3D(camera, 5.0, 5.0, 5.0, // position 0.0, 0.0, 0.0, // target 45.0); // fovy ECS::AddTag(camera, "MainCamera"); - + // === Set up light === light = ECS::CreateEntity(); ECS::AddLight(light, 0.5, 0.7, 0.3, 1.0); // direction + intensity ECS::AddTag(light, "MainLight"); - - // === Create player entity at origin with outline === - player = ECS::CreateEntity(); - ECS::AddTransform(player, 0.0f, 0.0f, 0.0f); - ECS::AddSprite(player, sphereModel, 0xFF0000FF, 0.0f); // Red sphere - ECS::SetSpriteShader(player, toonShader); // Apply toon shader - - ECS::AddTag(player, "Player"); - Log(LOG_INFO, "Created player entity: " + player); - - // === Create a spinning cube === - spinningCube = ECS::CreateEntity(); - ECS::AddTransform(spinningCube, 2.0f, 0.0f, 0.0f); - ECS::AddSprite(spinningCube, cubeModel, 0x00FF00FF, 0.0f); // Green cube - ECS::SetSpriteShader(spinningCube, toonShader); // Apply toon shader - ECS::AddVelocity(spinningCube, 0.0f, 0.0f, 0.0f, 2.0f); // Angular velocity - - ECS::AddTag(spinningCube, "Spinner"); - Log(LOG_INFO, "Created spinning cube: " + spinningCube); - - // === Create orbiting entities === - for (int i = 0; i < 5; i++) { - uint entity = ECS::CreateEntity(); - - float angle = (float(i) / 5.0f) * 6.28318f; // 2*PI - float radius = 3.0f; - float x = Math::Cos(angle) * radius; - float z = Math::Sin(angle) * radius; - - ECS::AddTransform(entity, x, 0.0f, z); - - // Different colors for each - uint color = 0; - uint8 r = 255, g = 255, b = 255; - if (i == 0) { color = 0xFFFF00FF; r = 255; g = 255; b = 0; } // Yellow else if (i == 1) { color = 0xFF00FFFF; r = 255; g = 0; b = 255; } // Magenta else if (i == 2) { color = 0x00FFFFFF; r = 0; g = 255; b = 255; } // Cyan else if (i == 3) { color = 0xFFA500FF; r = 255; g = 165; b = 0; } // Orange else { color = 0xFF69B4FF; r = 255; g = 105; b = 180; } // Pink - - ECS::AddSprite(entity, sphereModel, color, 0.0f); - ECS::SetSpriteShader(entity, toonShader); // Apply toon shader - - ECS::AddTag(entity, "Orbiter" + i); - entities.insertLast(entity); - } - - // === Create a moving entity === - uint mover = ECS::CreateEntity(); - ECS::AddTransform(mover, -3.0f, 0.5f, 0.0f); - ECS::AddSprite(mover, cubeModel, 0xFFFFFFFF, 0.0f); // White cube - ECS::SetSpriteShader(mover, toonShader); // Apply toon shader - ECS::AddVelocity(mover, 1.0f, 0.0f, 0.5f, 0.0f); // Moving velocity - - ECS::AddTag(mover, "Mover"); - entities.insertLast(mover); - - Toast::Success("Created " + (entities.length() + 2) + " entities with script-driven rendering!"); } void Shutdown() { Log(LOG_TRACE, "Shutdown complete!"); } -bool lightToggle = false; + void Update(float dt) { time += dt; - - // Update camera to orbit around the scene - if (ECS::HasCamera3D(camera)) { - float angle = time * 0.3; - float radius = 7.0; - float x = Math::Cos(angle) * radius; - float z = Math::Sin(angle) * radius; - ECS::SetCameraPosition(camera, x, 5.0, z); - } - - // Update player position - simple back and forth motion - float playerX = Math::Sin(time) * 2.0f; - ECS::SetPosition(player, playerX, 0.0f, 0.0f); - - // Update orbiting entities in a circle - for (uint i = 0; i < entities.length() - 1; i++) { - uint entity = entities[i]; - if (!ECS::IsValid(entity)) continue; - - float angle = (float(i) / 5.0f) * 6.28318f + time * 0.5f; - float radius = 3.0f; - float x = Math::Cos(angle) * radius; - float z = Math::Sin(angle) * radius; - float y = Math::Sin(time * 2.0f + float(i)) * 0.5f; // Bobbing motion - - ECS::SetPosition(entity, x, y, z); - ECS::SetRotation(entity, time + float(i)); - } - - // The mover entity wraps around using the Velocity component - // which is handled by the C++ movement system - if (entities.length() > 0) { - uint mover = entities[entities.length() - 1]; - if (ECS::IsValid(mover) && ECS::HasTransform(mover)) { - float x, y, z; - ECS::GetPosition(mover, x, y, z); - - // Wrap around - if (x > 5.0f) { - ECS::SetPosition(mover, -5.0f, y, z); - } - if (z > 5.0f) { - ECS::SetPosition(mover, x, y, -5.0f); - } - } + + // Rotate the scene root to show parent/child propagation + if (ECS::IsValid(sceneRoot) && ECS::HasTransform(sceneRoot)) { + ECS::SetRotation(sceneRoot, time * 0.5f); + } + + // Orbit the camera around the scene + if (ECS::HasCamera3D(camera)) { + float angle = time * 0.3f; + float radius = 7.0f; + float x = Math::Cos(angle) * radius; + float z = Math::Sin(angle) * radius; + ECS::SetCameraPosition(camera, x, 5.0f, z); } - // === Input Action System Demo === // Toggle light with jump action if (IsActionPressed("jump")) { lightToggle = !lightToggle; - if (lightToggle) { ECS::SetLightDirection(light, -0.5, 0.7, -0.3); Toast::Info("Light direction changed!"); @@ -172,26 +62,4 @@ void Update(float dt) { Toast::Info("Light direction reset!"); } } - - // Move player entity with input actions - if (ECS::IsValid(player) && ECS::HasTransform(player)) { - float x, y, z; - ECS::GetPosition(player, x, y, z); - float moveSpeed = 3.0f * dt; - - if (IsActionDown("move_left")) { - x -= moveSpeed; - } - if (IsActionDown("move_right")) { - x += moveSpeed; - } - if (IsActionDown("move_up")) { - z -= moveSpeed; - } - if (IsActionDown("move_down")) { - z += moveSpeed; - } - - ECS::SetPosition(player, x, y, z); - } } diff --git a/src/Application.cpp b/src/Application.cpp index c83ecfc..3b4aeea 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -2,6 +2,8 @@ #include "ECSComponents.h" #include "scripting/ECSBindings.h" #include "scripting/ResourceBindings.h" +#include "SceneGraph.h" +#include "SceneLoader.h" #include "raylib.h" #include "rlgl.h" #include "raymath.h" @@ -82,6 +84,9 @@ bool Application::Initialize(int argc, char *argv[]) extern void SetResourceManagers(ShaderManager*, ModelManager*, MaterialManager*); SetResourceManagers(&shaderManager, &modelManager, &materialManager); + // Set up scene loader context + SetSceneContext(®istry, &modelManager, &shaderManager); + // Set up input manager for script access extern void SetGlobalInputManager(InputManager*); SetGlobalInputManager(&inputManager); @@ -166,6 +171,8 @@ void Application::UpdateSystems(float deltaTime) // Apply angular velocity transform.rotation += velocity.angular * deltaTime; }); + + UpdateWorldTransforms(registry); } void Application::RenderScene() @@ -205,8 +212,8 @@ void Application::RenderScene() BeginMode3D(camera); DrawGrid(10, 1); - // Render all entities with Transform and Sprite components - auto view = registry.view(); + // Render all entities with WorldTransform and Sprite components + auto view = registry.view(); view.each([&](auto& transform, auto& sprite) { if (sprite.modelId > 0) { Model* model = modelManager.Get(static_cast(sprite.modelId)); diff --git a/src/SceneGraph.cpp b/src/SceneGraph.cpp new file mode 100644 index 0000000..e334cd0 --- /dev/null +++ b/src/SceneGraph.cpp @@ -0,0 +1,139 @@ +#include "SceneGraph.h" +#include "ECSComponents.h" +#include "raymath.h" +#include "entt.hpp" + +static WorldTransform ComputeWorldFromParent(const ECSTransform& local, const WorldTransform* parentWorld) { + if (!parentWorld) { + WorldTransform world; + world.position = local.position; + world.scale = local.scale; + world.rotation = local.rotation; + return world; + } + + Vector3 scaledLocal = { + local.position.x * parentWorld->scale.x, + local.position.y * parentWorld->scale.y, + local.position.z * parentWorld->scale.z + }; + + Vector3 rotatedLocal = Vector3RotateByAxisAngle(scaledLocal, Vector3{0.0f, 1.0f, 0.0f}, parentWorld->rotation); + + WorldTransform world; + world.position = Vector3Add(parentWorld->position, rotatedLocal); + world.scale = { + parentWorld->scale.x * local.scale.x, + parentWorld->scale.y * local.scale.y, + parentWorld->scale.z * local.scale.z + }; + world.rotation = parentWorld->rotation + local.rotation; + return world; +} + +void AttachChild(entt::registry& registry, entt::entity child, entt::entity parent) { + if (child == parent) return; + + DetachFromParent(registry, child); + + auto& childHierarchy = registry.get_or_emplace(child); + auto& parentHierarchy = registry.get_or_emplace(parent); + + childHierarchy.parent = parent; + childHierarchy.prev = entt::null; + childHierarchy.next = parentHierarchy.first; + + if (parentHierarchy.first != entt::null) { + registry.get_or_emplace(parentHierarchy.first).prev = child; + } + + parentHierarchy.first = child; +} + +void DetachFromParent(entt::registry& registry, entt::entity child) { + auto* childHierarchy = registry.try_get(child); + if (!childHierarchy || childHierarchy->parent == entt::null) { + return; + } + + entt::entity parent = childHierarchy->parent; + auto& parentHierarchy = registry.get_or_emplace(parent); + + if (parentHierarchy.first == child) { + parentHierarchy.first = childHierarchy->next; + } + + if (childHierarchy->prev != entt::null) { + registry.get_or_emplace(childHierarchy->prev).next = childHierarchy->next; + } + + if (childHierarchy->next != entt::null) { + registry.get_or_emplace(childHierarchy->next).prev = childHierarchy->prev; + } + + childHierarchy->parent = entt::null; + childHierarchy->prev = entt::null; + childHierarchy->next = entt::null; +} + +void DetachChildren(entt::registry& registry, entt::entity parent) { + auto* parentHierarchy = registry.try_get(parent); + if (!parentHierarchy) { + return; + } + + entt::entity child = parentHierarchy->first; + parentHierarchy->first = entt::null; + + while (child != entt::null) { + auto* childHierarchy = registry.try_get(child); + entt::entity nextChild = childHierarchy ? childHierarchy->next : entt::null; + + if (childHierarchy) { + childHierarchy->parent = entt::null; + childHierarchy->prev = entt::null; + childHierarchy->next = entt::null; + } + + child = nextChild; + } +} + +static void UpdateWorldRecursive(entt::registry& registry, entt::entity entity, const WorldTransform* parentWorld) { + const WorldTransform* currentWorld = parentWorld; + + if (auto* local = registry.try_get(entity)) { + auto& world = registry.get_or_emplace(entity); + world = ComputeWorldFromParent(*local, parentWorld); + currentWorld = &world; + } + + auto* hierarchy = registry.try_get(entity); + if (!hierarchy) { + return; + } + + entt::entity child = hierarchy->first; + while (child != entt::null) { + auto* childHierarchy = registry.try_get(child); + entt::entity nextChild = childHierarchy ? childHierarchy->next : entt::null; + UpdateWorldRecursive(registry, child, currentWorld); + child = nextChild; + } +} + +void UpdateWorldTransforms(entt::registry& registry) { + // Roots: entities with no hierarchy, or hierarchy parent == null + auto transformView = registry.view(entt::exclude); + for (auto entity : transformView) { + UpdateWorldRecursive(registry, entity, nullptr); + } + + auto hierarchyView = registry.view(); + for (auto entity : hierarchyView) { + const auto& hierarchy = hierarchyView.get(entity); + if (hierarchy.parent == entt::null) { + UpdateWorldRecursive(registry, entity, nullptr); + } + } +} diff --git a/src/SceneLoader.cpp b/src/SceneLoader.cpp new file mode 100644 index 0000000..1543d09 --- /dev/null +++ b/src/SceneLoader.cpp @@ -0,0 +1,333 @@ +#include "SceneLoader.h" +#include "ECSComponents.h" +#include "ModelManager.h" +#include "ShaderManager.h" +#include "SceneGraph.h" +#include "log/log.h" +#include "raylib.h" +#include "entt.hpp" +#include +#include +#include +#include +#include + +static entt::registry* g_sceneRegistry = nullptr; +static ModelManager* g_sceneModelManager = nullptr; +static ShaderManager* g_sceneShaderManager = nullptr; + +void SetSceneContext(entt::registry* registry, ModelManager* modelManager, ShaderManager* shaderManager) { + g_sceneRegistry = registry; + g_sceneModelManager = modelManager; + g_sceneShaderManager = shaderManager; +} + +void ClearScene() { + if (g_sceneRegistry) { + g_sceneRegistry->clear(); + } +} + +struct SceneEntityDef { + std::string id; + std::string parent; + std::string tag; + bool hasTransform = false; + Vector3 position{0.0f, 0.0f, 0.0f}; + Vector3 scale{1.0f, 1.0f, 1.0f}; + float rotation = 0.0f; + + bool hasSprite = false; + std::string model; + Vector3 modelSize{1.0f, 1.0f, 1.0f}; + float radius = 0.5f; + int rings = 16; + int slices = 16; + unsigned int color = 0xFFFFFFFF; + float outlineSize = 0.0f; + std::string shaderVs; + std::string shaderFs; +}; + +static std::string Trim(const std::string& value) { + size_t start = 0; + while (start < value.size() && std::isspace(static_cast(value[start]))) { + start++; + } + size_t end = value.size(); + while (end > start && std::isspace(static_cast(value[end - 1]))) { + end--; + } + return value.substr(start, end - start); +} + +static std::string StripComment(const std::string& line) { + bool inString = false; + for (size_t i = 0; i < line.size(); ++i) { + char c = line[i]; + if (c == '"') { + inString = !inString; + } + if (!inString && c == '#') { + return line.substr(0, i); + } + } + return line; +} + +static bool ParseVec3(const std::string& value, Vector3& out) { + std::string trimmed = Trim(value); + if (trimmed.size() < 5 || trimmed.front() != '[' || trimmed.back() != ']') { + return false; + } + + std::string inner = trimmed.substr(1, trimmed.size() - 2); + std::stringstream ss(inner); + std::string token; + float vals[3] = {0.0f, 0.0f, 0.0f}; + int count = 0; + + while (std::getline(ss, token, ',')) { + if (count >= 3) break; + vals[count] = std::stof(Trim(token)); + count++; + } + + if (count != 3) return false; + out = {vals[0], vals[1], vals[2]}; + return true; +} + +static bool ParseHexColor(const std::string& value, unsigned int& out) { + std::string trimmed = Trim(value); + if (trimmed.rfind("0x", 0) == 0 || trimmed.rfind("0X", 0) == 0) { + out = static_cast(std::stoul(trimmed, nullptr, 16)); + return true; + } + if (!trimmed.empty() && trimmed.front() == '"' && trimmed.back() == '"') { + std::string inner = trimmed.substr(1, trimmed.size() - 2); + if (!inner.empty() && inner.front() == '#') { + inner = inner.substr(1); + } + out = static_cast(std::stoul(inner, nullptr, 16)); + return true; + } + return false; +} + +static bool ParseString(const std::string& value, std::string& out) { + std::string trimmed = Trim(value); + if (trimmed.size() >= 2 && trimmed.front() == '"' && trimmed.back() == '"') { + out = trimmed.substr(1, trimmed.size() - 2); + return true; + } + out = trimmed; + return !out.empty(); +} + +static unsigned int LoadModelFor(const SceneEntityDef& def, std::unordered_map& modelCache) { + if (!g_sceneModelManager || def.model.empty()) return 0; + + std::string key = def.model; + if (def.model == "cube") { + key += ":" + std::to_string(def.modelSize.x) + "," + std::to_string(def.modelSize.y) + "," + std::to_string(def.modelSize.z); + } else if (def.model == "sphere") { + key += ":" + std::to_string(def.radius) + "," + std::to_string(def.rings) + "," + std::to_string(def.slices); + } + + auto cached = modelCache.find(key); + if (cached != modelCache.end()) { + return cached->second; + } + + unsigned int modelId = 0; + if (def.model == "cube") { + Mesh mesh = GenMeshCube(def.modelSize.x, def.modelSize.y, def.modelSize.z); + modelId = g_sceneModelManager->LoadFromMesh(mesh); + } else if (def.model == "sphere") { + Mesh mesh = GenMeshSphere(def.radius, def.rings, def.slices); + modelId = g_sceneModelManager->LoadFromMesh(mesh); + } else if (def.model == "plane") { + Mesh mesh = GenMeshPlane(def.modelSize.x, def.modelSize.z, def.rings, def.slices); + modelId = g_sceneModelManager->LoadFromMesh(mesh); + } else { + modelId = g_sceneModelManager->Load(def.model); + } + + if (modelId != 0) { + modelCache[key] = modelId; + } + + return modelId; +} + +static unsigned int LoadShaderFor(const SceneEntityDef& def, std::unordered_map& shaderCache) { + if (!g_sceneShaderManager || def.shaderVs.empty() || def.shaderFs.empty()) return 0; + + std::string key = def.shaderVs + "|" + def.shaderFs; + auto cached = shaderCache.find(key); + if (cached != shaderCache.end()) { + return cached->second; + } + + unsigned int shaderId = g_sceneShaderManager->Load(def.shaderVs, def.shaderFs); + if (shaderId != 0) { + shaderCache[key] = shaderId; + } + return shaderId; +} + +entt::entity LoadSceneFromFile(const std::string& path, bool clearExisting) { + if (!g_sceneRegistry) { + log_error("Scene loader not initialized (registry missing)"); + return entt::null; + } + + if (clearExisting) { + g_sceneRegistry->clear(); + } + + std::ifstream file(path); + if (!file.is_open()) { + log_error("Failed to open scene file: %s", path.c_str()); + return entt::null; + } + + std::vector defs; + SceneEntityDef* current = nullptr; + std::string line; + int lineNumber = 0; + + while (std::getline(file, line)) { + lineNumber++; + line = StripComment(line); + line = Trim(line); + if (line.empty()) continue; + + if (line == "[[entity]]") { + defs.emplace_back(); + current = &defs.back(); + continue; + } + + if (!current) { + log_warn("Scene parse: key/value outside entity section at line %d", lineNumber); + continue; + } + + size_t eq = line.find('='); + if (eq == std::string::npos) { + log_warn("Scene parse: invalid line %d", lineNumber); + continue; + } + + std::string key = Trim(line.substr(0, eq)); + std::string value = Trim(line.substr(eq + 1)); + + if (key == "id") { + ParseString(value, current->id); + } else if (key == "parent") { + ParseString(value, current->parent); + } else if (key == "tag") { + ParseString(value, current->tag); + } else if (key == "position") { + current->hasTransform = ParseVec3(value, current->position); + } else if (key == "scale") { + current->hasTransform = ParseVec3(value, current->scale); + } else if (key == "rotation") { + current->rotation = std::stof(value); + current->hasTransform = true; + } else if (key == "rotation_deg") { + current->rotation = std::stof(value) * DEG2RAD; + current->hasTransform = true; + } else if (key == "model") { + ParseString(value, current->model); + current->hasSprite = true; + } else if (key == "model_size") { + ParseVec3(value, current->modelSize); + } else if (key == "radius") { + current->radius = std::stof(value); + } else if (key == "rings") { + current->rings = std::stoi(value); + } else if (key == "slices") { + current->slices = std::stoi(value); + } else if (key == "color") { + ParseHexColor(value, current->color); + current->hasSprite = true; + } else if (key == "outline_size") { + current->outlineSize = std::stof(value); + } else if (key == "shader_vs") { + ParseString(value, current->shaderVs); + } else if (key == "shader_fs") { + ParseString(value, current->shaderFs); + } else { + log_warn("Scene parse: unknown key '%s' at line %d", key.c_str(), lineNumber); + } + } + + if (defs.empty()) { + log_warn("Scene file contained no entities: %s", path.c_str()); + return entt::null; + } + + entt::entity root = g_sceneRegistry->create(); + g_sceneRegistry->emplace(root, "SceneRoot"); + g_sceneRegistry->emplace(root, Vector3{0.0f, 0.0f, 0.0f}, Vector3{1.0f, 1.0f, 1.0f}, 0.0f); + + std::unordered_map idMap; + std::vector created; + created.reserve(defs.size()); + std::unordered_map modelCache; + std::unordered_map shaderCache; + + for (const auto& def : defs) { + entt::entity entity = g_sceneRegistry->create(); + created.push_back(entity); + + if (!def.id.empty()) { + idMap[def.id] = entity; + } + + if (!def.tag.empty()) { + g_sceneRegistry->emplace(entity, def.tag); + } else if (!def.id.empty()) { + g_sceneRegistry->emplace(entity, def.id); + } + + if (def.hasTransform || def.hasSprite) { + g_sceneRegistry->emplace(entity, def.position, def.scale, def.rotation); + } + + if (def.hasSprite) { + unsigned int modelId = LoadModelFor(def, modelCache); + Color col = { + static_cast((def.color >> 24) & 0xFF), + static_cast((def.color >> 16) & 0xFF), + static_cast((def.color >> 8) & 0xFF), + static_cast(def.color & 0xFF) + }; + unsigned int shaderId = LoadShaderFor(def, shaderCache); + g_sceneRegistry->emplace(entity, static_cast(modelId), col, def.outlineSize, shaderId); + } + } + + for (size_t i = 0; i < defs.size(); ++i) { + entt::entity entity = created[i]; + const auto& def = defs[i]; + + entt::entity parent = root; + if (!def.parent.empty()) { + auto it = idMap.find(def.parent); + if (it != idMap.end()) { + parent = it->second; + } else { + log_warn("Scene load: parent '%s' not found for entity '%s'", def.parent.c_str(), def.id.c_str()); + } + } + + AttachChild(*g_sceneRegistry, entity, parent); + } + + UpdateWorldTransforms(*g_sceneRegistry); + return root; +} diff --git a/src/scripting/ECSBindings.cpp b/src/scripting/ECSBindings.cpp index 00249b2..a500718 100644 --- a/src/scripting/ECSBindings.cpp +++ b/src/scripting/ECSBindings.cpp @@ -1,5 +1,6 @@ #include "scripting/ECSBindings.h" #include "ECSComponents.h" +#include "SceneGraph.h" #include #include #include @@ -20,7 +21,10 @@ uint32_t AS_CreateEntity() { void AS_DestroyEntity(uint32_t entity) { if (!registry) return; - registry->destroy((entt::entity)entity); + entt::entity e = (entt::entity)entity; + DetachFromParent(*registry, e); + DetachChildren(*registry, e); + registry->destroy(e); } bool AS_IsEntityValid(uint32_t entity) { @@ -200,6 +204,44 @@ void AS_RemoveTag(uint32_t entity) { registry->remove((entt::entity)entity); } +// === Hierarchy Component === + +void AS_SetParent(uint32_t child, uint32_t parent) { + if (!registry) return; + entt::entity childEntity = (entt::entity)child; + entt::entity parentEntity = (entt::entity)parent; + + if (!registry->valid(childEntity)) return; + if (parent == 0 || !registry->valid(parentEntity)) { + DetachFromParent(*registry, childEntity); + return; + } + + AttachChild(*registry, childEntity, parentEntity); +} + +void AS_ClearParent(uint32_t child) { + if (!registry) return; + entt::entity childEntity = (entt::entity)child; + DetachFromParent(*registry, childEntity); +} + +uint32_t AS_GetParent(uint32_t child) { + if (!registry) return 0; + if (auto* h = registry->try_get((entt::entity)child)) { + return static_cast(h->parent); + } + return 0; +} + +bool AS_HasParent(uint32_t child) { + if (!registry) return false; + if (auto* h = registry->try_get((entt::entity)child)) { + return h->parent != entt::null; + } + return false; +} + // === Camera3D Component === void AS_AddCamera3D(uint32_t entity, float px, float py, float pz, float tx, float ty, float tz, float fovy) { @@ -481,6 +523,23 @@ void RegisterECSBindings(asIScriptEngine *engine) { asFUNCTION(AS_RemoveTag), asCALL_CDECL); assert(r >= 0); + // Hierarchy component + r = engine->RegisterGlobalFunction("void SetParent(uint, uint)", + asFUNCTION(AS_SetParent), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void ClearParent(uint)", + asFUNCTION(AS_ClearParent), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("uint GetParent(uint)", + asFUNCTION(AS_GetParent), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("bool HasParent(uint)", + asFUNCTION(AS_HasParent), asCALL_CDECL); + assert(r >= 0); + // Camera3D component r = engine->RegisterGlobalFunction("void AddCamera3D(uint, float, float, float, float, float, float, float)", asFUNCTION(AS_AddCamera3D), asCALL_CDECL); diff --git a/src/scripting/SceneBindings.cpp b/src/scripting/SceneBindings.cpp new file mode 100644 index 0000000..8684b0d --- /dev/null +++ b/src/scripting/SceneBindings.cpp @@ -0,0 +1,28 @@ +#include "scripting/SceneBindings.h" +#include "SceneLoader.h" +#include +#include + +static unsigned int AS_LoadScene(const std::string& path, bool clearExisting) { + entt::entity root = LoadSceneFromFile(path, clearExisting); + return static_cast(root); +} + +static void AS_ClearScene() { + ClearScene(); +} + +void RegisterSceneBindings(asIScriptEngine* engine) { + int r; + + engine->SetDefaultNamespace("Scene"); + + r = engine->RegisterGlobalFunction("uint Load(const string &in, bool clearExisting = true)", + asFUNCTION(AS_LoadScene), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void Clear()", asFUNCTION(AS_ClearScene), asCALL_CDECL); + assert(r >= 0); + + engine->SetDefaultNamespace(""); +} diff --git a/src/scripting/ScriptBindings.cpp b/src/scripting/ScriptBindings.cpp index 20ceb57..121acfa 100644 --- a/src/scripting/ScriptBindings.cpp +++ b/src/scripting/ScriptBindings.cpp @@ -7,6 +7,7 @@ #include "scripting/ECSBindings.h" #include "scripting/ResourceBindings.h" #include "scripting/InputBindings.h" +#include "scripting/SceneBindings.h" void ScriptBindings::RegisterAll(asIScriptEngine *engine) { @@ -19,4 +20,5 @@ void ScriptBindings::RegisterAll(asIScriptEngine *engine) RegisterECSBindings(engine); RegisterResourceBindings(engine); RegisterInputBindings(engine); + RegisterSceneBindings(engine); } \ No newline at end of file From e6a53baa1a5f97ca5fee1d1ce903706abaaa9226 Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Sun, 8 Mar 2026 15:52:14 +1300 Subject: [PATCH 30/53] chore: added tests and tidied docs --- .gitea/workflows/sync-docs-to-wiki.yml | 2 +- docs/Home.md | 4 +- tests/CMakeLists.txt | 11 +- tests/resource_tests.cpp | 197 +++++++++++++++++++++++++ tests/resource_tests.h | 6 + tests/scenegraph_tests.cpp | 143 ++++++++++++++++++ tests/scenegraph_tests.h | 5 + tests/test.cpp | 9 ++ 8 files changed, 372 insertions(+), 5 deletions(-) create mode 100644 tests/resource_tests.cpp create mode 100644 tests/resource_tests.h create mode 100644 tests/scenegraph_tests.cpp create mode 100644 tests/scenegraph_tests.h diff --git a/.gitea/workflows/sync-docs-to-wiki.yml b/.gitea/workflows/sync-docs-to-wiki.yml index b46679f..3b8ab83 100644 --- a/.gitea/workflows/sync-docs-to-wiki.yml +++ b/.gitea/workflows/sync-docs-to-wiki.yml @@ -21,7 +21,7 @@ jobs: - name: Add Gitea host key run: | mkdir -p ~/.ssh - ssh-keyscan -t rsa,gssapi-with-mic,gssapi-keyex gitea.appstack.me >> ~/.ssh/known_hosts + ssh-keyscan -t rsa gitea.appstack.me >> ~/.ssh/known_hosts - name: Sync docs to wiki env: diff --git a/docs/Home.md b/docs/Home.md index b124b85..0b27670 100644 --- a/docs/Home.md +++ b/docs/Home.md @@ -8,6 +8,4 @@ Edit markdown files here and push to the repository; CI will mirror them to the - [Usage](Usage.md) — getting started and build instructions - [Scenegraph](Scenegraph.md) — hierarchy components and scene format -## Notes -The CI workflow (.gitea/workflows/sync-docs-to-wiki.yml) clones the wiki repository and copies these files into it. -Make sure `WIKI_SSH_KEY` is configured in repository secrets (SSH private key with push access to the wiki). + diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 580e2c7..a24f48f 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -6,6 +6,8 @@ add_executable(unit_tests hot_reload.cpp script_engine_tests.cpp math_bindings_tests.cpp + resource_tests.cpp + scenegraph_tests.cpp ) target_include_directories(unit_tests PRIVATE @@ -26,4 +28,11 @@ add_test(NAME unit_tests COMMAND unit_tests) add_test(NAME hotreload_dir COMMAND unit_tests hotreload_dir) add_test(NAME script_compile COMMAND unit_tests script_compile) add_test(NAME script_include COMMAND unit_tests script_include) -add_test(NAME math_bindings COMMAND unit_tests math_bindings) \ No newline at end of file +add_test(NAME math_bindings COMMAND unit_tests math_bindings) +add_test(NAME shader_manager COMMAND unit_tests shader_manager) +add_test(NAME model_manager COMMAND unit_tests model_manager) +add_test(NAME material_manager COMMAND unit_tests material_manager) +add_test(NAME resource_bindings COMMAND unit_tests resource_bindings) +add_test(NAME scenegraph_world COMMAND unit_tests scenegraph_world) +add_test(NAME scenegraph_detach COMMAND unit_tests scenegraph_detach) +add_test(NAME scene_loader COMMAND unit_tests scene_loader) diff --git a/tests/resource_tests.cpp b/tests/resource_tests.cpp new file mode 100644 index 0000000..b39f22e --- /dev/null +++ b/tests/resource_tests.cpp @@ -0,0 +1,197 @@ +#define TEST_NO_MAIN +#include "acutest.h" +#include +#include +#include "../include/ShaderManager.h" +#include "../include/ModelManager.h" +#include "../include/MaterialManager.h" +#include "../include/scripting/ScriptEngine.h" +#include "../include/scripting/ResourceBindings.h" +#include "raylib.h" + +static void InitRaylibHidden() { + if (!IsWindowReady()) { + SetConfigFlags(FLAG_WINDOW_HIDDEN); + InitWindow(1, 1, "simian_test"); + SetTargetFPS(60); + } +} + +static void ShutdownRaylibHidden() { + if (IsWindowReady()) { + CloseWindow(); + } +} + +static std::filesystem::path WriteTempShader(const std::filesystem::path& dir, const std::string& name, const std::string& code) { + std::filesystem::path path = dir / name; + std::ofstream ofs(path); + ofs << code; + return path; +} + +void test_shader_manager(void) { + InitRaylibHidden(); + + std::filesystem::path tmpDir = std::filesystem::current_path() / "tmp_shader"; + std::filesystem::create_directories(tmpDir); + + const std::string vsCode = + "#version 330\n" + "layout(location = 0) in vec3 vertexPosition;\n" + "uniform mat4 mvp;\n" + "void main() {\n" + " gl_Position = mvp * vec4(vertexPosition, 1.0);\n" + "}\n"; + + const std::string fsCode = + "#version 330\n" + "out vec4 fragColor;\n" + "void main() {\n" + " fragColor = vec4(1.0, 0.0, 0.0, 1.0);\n" + "}\n"; + + auto vsPath = WriteTempShader(tmpDir, "test.vs", vsCode); + auto fsPath = WriteTempShader(tmpDir, "test.fs", fsCode); + + ShaderManager shaderManager; + unsigned int shaderId = shaderManager.Load(vsPath.string(), fsPath.string()); + TEST_CHECK(shaderId != 0); + TEST_CHECK(shaderManager.Get(shaderId) != nullptr); + + shaderManager.Unload(shaderId); + TEST_CHECK(shaderManager.Get(shaderId) == nullptr); + + std::filesystem::remove(vsPath); + std::filesystem::remove(fsPath); + std::filesystem::remove(tmpDir); + + ShutdownRaylibHidden(); +} + +void test_model_manager(void) { + InitRaylibHidden(); + + ModelManager modelManager; + Mesh mesh = GenMeshCube(1.0f, 1.0f, 1.0f); + unsigned int modelId = modelManager.LoadFromMesh(mesh); + TEST_CHECK(modelId != 0); + TEST_CHECK(modelManager.Get(modelId) != nullptr); + + modelManager.Unload(modelId); + TEST_CHECK(modelManager.Get(modelId) == nullptr); + + ShutdownRaylibHidden(); +} + +void test_material_manager(void) { + MaterialManager materialManager; + Color albedo = {1, 2, 3, 4}; + unsigned int materialId = materialManager.Create(7, albedo); + TEST_CHECK(materialId != 0); + + MaterialData* data = materialManager.Get(materialId); + TEST_CHECK(data != nullptr); + TEST_CHECK(data->shaderId == 7); + TEST_CHECK(data->albedo.r == 1); + TEST_CHECK(data->albedo.g == 2); + TEST_CHECK(data->albedo.b == 3); + TEST_CHECK(data->albedo.a == 4); + + materialManager.SetShader(materialId, 42); + TEST_CHECK(data->shaderId == 42); + + Color newAlbedo = {10, 20, 30, 40}; + materialManager.SetAlbedo(materialId, newAlbedo); + TEST_CHECK(data->albedo.r == 10); + TEST_CHECK(data->albedo.g == 20); + TEST_CHECK(data->albedo.b == 30); + TEST_CHECK(data->albedo.a == 40); + + materialManager.Remove(materialId); + TEST_CHECK(materialManager.Get(materialId) == nullptr); +} + +void test_resource_bindings_script(void) { + InitRaylibHidden(); + + std::filesystem::path tmpDir = std::filesystem::current_path() / "tmp_resource"; + std::filesystem::create_directories(tmpDir); + + const std::string vsCode = + "#version 330\n" + "layout(location = 0) in vec3 vertexPosition;\n" + "uniform mat4 mvp;\n" + "void main() {\n" + " gl_Position = mvp * vec4(vertexPosition, 1.0);\n" + "}\n"; + + const std::string fsCode = + "#version 330\n" + "out vec4 fragColor;\n" + "void main() {\n" + " fragColor = vec4(0.0, 1.0, 0.0, 1.0);\n" + "}\n"; + + auto vsPath = WriteTempShader(tmpDir, "script.vs", vsCode); + auto fsPath = WriteTempShader(tmpDir, "script.fs", fsCode); + + std::filesystem::path scriptPath = tmpDir / "resource_test.as"; + { + std::ofstream script(scriptPath); + script << "uint shaderId = 0;\n"; + script << "uint modelId = 0;\n"; + script << "uint materialId = 0;\n"; + script << "void Init() {\n"; + script << " shaderId = Shader::Load(\"" << vsPath.generic_string() << "\", \"" << fsPath.generic_string() << "\");\n"; + script << " modelId = Model::LoadCube(1.0f, 1.0f, 1.0f);\n"; + script << " materialId = Material::Create(shaderId, 255, 0, 0, 255);\n"; + script << "}\n"; + } + + ShaderManager shaderManager; + ModelManager modelManager; + MaterialManager materialManager; + SetResourceManagers(&shaderManager, &modelManager, &materialManager); + + ScriptEngine se; + TEST_CHECK(se.Initialize() == true); + bool compiled = se.CompileScript(scriptPath.string()); + TEST_CHECK(compiled == true); + + asIScriptFunction* initFunc = se.GetInitFunction(); + TEST_CHECK(initFunc != nullptr); + se.CallScriptFunction(initFunc); + + asIScriptEngine* engine = se.GetEngine(); + TEST_CHECK(engine != nullptr); + asIScriptModule* module = engine ? engine->GetModule("main") : nullptr; + TEST_CHECK(module != nullptr); + + auto fetchUInt = [module](const char* name) -> unsigned int { + int idx = module->GetGlobalVarIndexByName(name); + TEST_CHECK_(idx >= 0, "Global '%s' not found", name); + if (idx < 0) return 0; + void* address = module->GetAddressOfGlobalVar(idx); + TEST_CHECK_(address != nullptr, "Global '%s' address null", name); + if (!address) return 0; + return *static_cast(address); + }; + + unsigned int shaderId = fetchUInt("shaderId"); + unsigned int modelId = fetchUInt("modelId"); + unsigned int materialId = fetchUInt("materialId"); + + TEST_CHECK(shaderId != 0); + TEST_CHECK(modelId != 0); + TEST_CHECK(materialId != 0); + + se.Shutdown(); + + std::filesystem::remove(scriptPath); + std::filesystem::remove(vsPath); + std::filesystem::remove(fsPath); + std::filesystem::remove(tmpDir); + + ShutdownRaylibHidden(); +} diff --git a/tests/resource_tests.h b/tests/resource_tests.h new file mode 100644 index 0000000..bc35f2d --- /dev/null +++ b/tests/resource_tests.h @@ -0,0 +1,6 @@ +#pragma once + +void test_shader_manager(void); +void test_model_manager(void); +void test_material_manager(void); +void test_resource_bindings_script(void); diff --git a/tests/scenegraph_tests.cpp b/tests/scenegraph_tests.cpp new file mode 100644 index 0000000..a43d275 --- /dev/null +++ b/tests/scenegraph_tests.cpp @@ -0,0 +1,143 @@ +#define TEST_NO_MAIN +#include "acutest.h" +#include +#include +#include "../include/ECSComponents.h" +#include "../include/SceneGraph.h" +#include "../include/SceneLoader.h" +#include "../include/ModelManager.h" +#include "../include/ShaderManager.h" +#include "raylib.h" +#include "entt.hpp" + +static void InitRaylibHidden() { + if (!IsWindowReady()) { + SetConfigFlags(FLAG_WINDOW_HIDDEN); + InitWindow(1, 1, "simian_test_scene"); + SetTargetFPS(60); + } +} + +static void ShutdownRaylibHidden() { + if (IsWindowReady()) { + CloseWindow(); + } +} + +void test_scenegraph_world_transform(void) { + entt::registry registry; + + entt::entity parent = registry.create(); + entt::entity child = registry.create(); + + registry.emplace(parent, Vector3{1.0f, 0.0f, 0.0f}, Vector3{2.0f, 2.0f, 2.0f}, 0.0f); + registry.emplace(child, Vector3{1.0f, 0.0f, 0.0f}, Vector3{1.0f, 1.0f, 1.0f}, 0.0f); + + AttachChild(registry, child, parent); + UpdateWorldTransforms(registry); + + auto* childWorld = registry.try_get(child); + TEST_CHECK(childWorld != nullptr); + if (childWorld) { + TEST_CHECK(childWorld->position.x == 3.0f); + TEST_CHECK(childWorld->position.y == 0.0f); + TEST_CHECK(childWorld->position.z == 0.0f); + } +} + +void test_scenegraph_detach(void) { + entt::registry registry; + + entt::entity parent = registry.create(); + entt::entity child = registry.create(); + + AttachChild(registry, child, parent); + DetachFromParent(registry, child); + + auto* childHierarchy = registry.try_get(child); + TEST_CHECK(childHierarchy != nullptr); + if (childHierarchy) { + TEST_CHECK(childHierarchy->parent == entt::null); + TEST_CHECK(childHierarchy->prev == entt::null); + TEST_CHECK(childHierarchy->next == entt::null); + } + + auto* parentHierarchy = registry.try_get(parent); + TEST_CHECK(parentHierarchy != nullptr); + if (parentHierarchy) { + TEST_CHECK(parentHierarchy->first == entt::null); + } +} + +void test_scene_loader_basic(void) { + InitRaylibHidden(); + + entt::registry registry; + ModelManager modelManager; + ShaderManager shaderManager; + SetSceneContext(®istry, &modelManager, &shaderManager); + + std::filesystem::path tmpDir = std::filesystem::current_path() / "tmp_scene"; + std::filesystem::create_directories(tmpDir); + std::filesystem::path scenePath = tmpDir / "scene.toml"; + + { + std::ofstream scene(scenePath); + scene << "[[entity]]\n"; + scene << "id = \"root\"\n"; + scene << "tag = \"Root\"\n"; + scene << "position = [0.0, 0.0, 0.0]\n"; + scene << "\n"; + scene << "[[entity]]\n"; + scene << "id = \"parent\"\n"; + scene << "parent = \"root\"\n"; + scene << "tag = \"Parent\"\n"; + scene << "position = [1.0, 0.0, 0.0]\n"; + scene << "model = \"cube\"\n"; + scene << "model_size = [1.0, 1.0, 1.0]\n"; + scene << "color = 0x00FF00FF\n"; + scene << "\n"; + scene << "[[entity]]\n"; + scene << "id = \"child\"\n"; + scene << "parent = \"parent\"\n"; + scene << "tag = \"Child\"\n"; + scene << "position = [0.0, 1.0, 0.0]\n"; + scene << "model = \"sphere\"\n"; + scene << "radius = 0.5\n"; + scene << "color = 0xFF0000FF\n"; + } + + entt::entity root = LoadSceneFromFile(scenePath.string(), true); + TEST_CHECK(root != entt::null); + + entt::entity parentEntity = entt::null; + entt::entity childEntity = entt::null; + + auto tagView = registry.view(); + for (auto entity : tagView) { + const auto& tag = tagView.get(entity); + if (tag.name == "Parent") { + parentEntity = entity; + } else if (tag.name == "Child") { + childEntity = entity; + } + } + + TEST_CHECK(parentEntity != entt::null); + TEST_CHECK(childEntity != entt::null); + + if (parentEntity != entt::null && childEntity != entt::null) { + auto* childHierarchy = registry.try_get(childEntity); + TEST_CHECK(childHierarchy != nullptr); + if (childHierarchy) { + TEST_CHECK(childHierarchy->parent == parentEntity); + } + TEST_CHECK(registry.all_of(parentEntity)); + TEST_CHECK(registry.all_of(childEntity)); + } + + std::filesystem::remove(scenePath); + std::filesystem::remove(tmpDir); + + ShutdownRaylibHidden(); +} diff --git a/tests/scenegraph_tests.h b/tests/scenegraph_tests.h new file mode 100644 index 0000000..d364ab0 --- /dev/null +++ b/tests/scenegraph_tests.h @@ -0,0 +1,5 @@ +#pragma once + +void test_scenegraph_world_transform(void); +void test_scenegraph_detach(void); +void test_scene_loader_basic(void); diff --git a/tests/test.cpp b/tests/test.cpp index a2cbc99..1cd79bd 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -2,10 +2,19 @@ #include "hot_reload.h" #include "script_engine_tests.h" #include "math_bindings_tests.h" +#include "resource_tests.h" +#include "scenegraph_tests.h" TEST_LIST = { { "hotreload_dir", test_hotreload_directory_watch }, { "script_compile", test_scriptengine_compile_and_call }, { "script_include", test_scriptengine_include }, { "math_bindings", test_math_bindings }, + { "shader_manager", test_shader_manager }, + { "model_manager", test_model_manager }, + { "material_manager", test_material_manager }, + { "resource_bindings", test_resource_bindings_script }, + { "scenegraph_world", test_scenegraph_world_transform }, + { "scenegraph_detach", test_scenegraph_detach }, + { "scene_loader", test_scene_loader_basic }, { NULL, NULL } }; From 5367b31f4e8885bad782ecd0edf08a286f0d1cc8 Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Sun, 8 Mar 2026 16:04:38 +1300 Subject: [PATCH 31/53] chore: fixing CI --- .gitea/workflows/sync-docs-to-wiki.yml | 4 ++- docs/Scenegraph.md | 2 +- tests/resource_tests.cpp | 41 +++++++++++++++++++++++--- tests/scenegraph_tests.cpp | 31 +++++++++++++++++-- 4 files changed, 70 insertions(+), 8 deletions(-) diff --git a/.gitea/workflows/sync-docs-to-wiki.yml b/.gitea/workflows/sync-docs-to-wiki.yml index 3b8ab83..8676fd4 100644 --- a/.gitea/workflows/sync-docs-to-wiki.yml +++ b/.gitea/workflows/sync-docs-to-wiki.yml @@ -27,6 +27,8 @@ jobs: env: WIKI_REPO: git@gitea.appstack.me:nick/simian.wiki.git run: | + sudo apt-get update -qq + sudo apt-get install -y rsync openssh-client git config --global user.name "Simian CI" git config --global user.email "ci@simian.local" git clone "$WIKI_REPO" wiki @@ -37,5 +39,5 @@ jobs: echo "No wiki changes" else git commit -m "Update wiki from docs (CI)" - git push origin HEAD + git push origin main fi diff --git a/docs/Scenegraph.md b/docs/Scenegraph.md index 74382c2..c407130 100644 --- a/docs/Scenegraph.md +++ b/docs/Scenegraph.md @@ -91,4 +91,4 @@ shader_fs = "shaders/toon.fs" uint root = Scene::Load("scenes/demo.toml"); ``` -`Scene::Load` returns a root entity that parents all top-level entities. Entity id `0` can be valid in EnTT, so use `ECS::IsValid(root)` to check success. +`Scene::Load` returns a root entity that parents all top-level entities. Use `ECS::IsValid(root)` to check success on the scene load. diff --git a/tests/resource_tests.cpp b/tests/resource_tests.cpp index b39f22e..22ed42e 100644 --- a/tests/resource_tests.cpp +++ b/tests/resource_tests.cpp @@ -2,6 +2,7 @@ #include "acutest.h" #include #include +#include #include "../include/ShaderManager.h" #include "../include/ModelManager.h" #include "../include/MaterialManager.h" @@ -9,12 +10,35 @@ #include "../include/scripting/ResourceBindings.h" #include "raylib.h" -static void InitRaylibHidden() { +static bool HasDisplay() { +#if defined(_WIN32) + return true; +#elif defined(__APPLE__) + return true; +#else + const char* display = std::getenv("DISPLAY"); + const char* wayland = std::getenv("WAYLAND_DISPLAY"); + return (display && *display) || (wayland && *wayland); +#endif +} + +static bool InitRaylibHidden() { + const char* forceHeadless = std::getenv("SIMIAN_HEADLESS"); + if (forceHeadless && forceHeadless[0] == '1') { + return false; + } + + if (!HasDisplay()) { + return false; + } + if (!IsWindowReady()) { SetConfigFlags(FLAG_WINDOW_HIDDEN); InitWindow(1, 1, "simian_test"); SetTargetFPS(60); } + + return IsWindowReady(); } static void ShutdownRaylibHidden() { @@ -31,7 +55,10 @@ static std::filesystem::path WriteTempShader(const std::filesystem::path& dir, c } void test_shader_manager(void) { - InitRaylibHidden(); + if (!InitRaylibHidden()) { + TEST_SKIP("No display available for raylib"); + return; + } std::filesystem::path tmpDir = std::filesystem::current_path() / "tmp_shader"; std::filesystem::create_directories(tmpDir); @@ -70,7 +97,10 @@ void test_shader_manager(void) { } void test_model_manager(void) { - InitRaylibHidden(); + if (!InitRaylibHidden()) { + TEST_SKIP("No display available for raylib"); + return; + } ModelManager modelManager; Mesh mesh = GenMeshCube(1.0f, 1.0f, 1.0f); @@ -113,7 +143,10 @@ void test_material_manager(void) { } void test_resource_bindings_script(void) { - InitRaylibHidden(); + if (!InitRaylibHidden()) { + TEST_SKIP("No display available for raylib"); + return; + } std::filesystem::path tmpDir = std::filesystem::current_path() / "tmp_resource"; std::filesystem::create_directories(tmpDir); diff --git a/tests/scenegraph_tests.cpp b/tests/scenegraph_tests.cpp index a43d275..256c8a1 100644 --- a/tests/scenegraph_tests.cpp +++ b/tests/scenegraph_tests.cpp @@ -2,6 +2,7 @@ #include "acutest.h" #include #include +#include #include "../include/ECSComponents.h" #include "../include/SceneGraph.h" #include "../include/SceneLoader.h" @@ -10,12 +11,35 @@ #include "raylib.h" #include "entt.hpp" -static void InitRaylibHidden() { +static bool HasDisplay() { +#if defined(_WIN32) + return true; +#elif defined(__APPLE__) + return true; +#else + const char* display = std::getenv("DISPLAY"); + const char* wayland = std::getenv("WAYLAND_DISPLAY"); + return (display && *display) || (wayland && *wayland); +#endif +} + +static bool InitRaylibHidden() { + const char* forceHeadless = std::getenv("SIMIAN_HEADLESS"); + if (forceHeadless && forceHeadless[0] == '1') { + return false; + } + + if (!HasDisplay()) { + return false; + } + if (!IsWindowReady()) { SetConfigFlags(FLAG_WINDOW_HIDDEN); InitWindow(1, 1, "simian_test_scene"); SetTargetFPS(60); } + + return IsWindowReady(); } static void ShutdownRaylibHidden() { @@ -70,7 +94,10 @@ void test_scenegraph_detach(void) { } void test_scene_loader_basic(void) { - InitRaylibHidden(); + if (!InitRaylibHidden()) { + TEST_SKIP("No display available for raylib"); + return; + } entt::registry registry; ModelManager modelManager; From d7f9019e616a99df1725474f831ad55629e780df Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Sun, 8 Mar 2026 16:26:34 +1300 Subject: [PATCH 32/53] chore: fix for headless raylib --- .gitea/workflows/sync-docs-to-wiki.yml | 2 +- docs/Scripting.md | 2 +- tests/resource_tests.cpp | 4 +++- tests/scenegraph_tests.cpp | 3 +++ 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/.gitea/workflows/sync-docs-to-wiki.yml b/.gitea/workflows/sync-docs-to-wiki.yml index 8676fd4..acafe21 100644 --- a/.gitea/workflows/sync-docs-to-wiki.yml +++ b/.gitea/workflows/sync-docs-to-wiki.yml @@ -39,5 +39,5 @@ jobs: echo "No wiki changes" else git commit -m "Update wiki from docs (CI)" - git push origin main + git push fi diff --git a/docs/Scripting.md b/docs/Scripting.md index 124402a..3e0061f 100644 --- a/docs/Scripting.md +++ b/docs/Scripting.md @@ -7,7 +7,7 @@ This page is a starting point for scripting documentation. - Predefined API and engine bindings are declared in `scripts/as.predefined`. ## Examples -- `scripts/game.as` — demo showing ECS usage, rendering and input actions. +- `scripts/game.as` — demo showing ECS usage, rendering, scenegraph and input actions. ## How to document APIs Add Markdown pages in the `docs/` folder. Use relative links and include code fences for examples. diff --git a/tests/resource_tests.cpp b/tests/resource_tests.cpp index 22ed42e..4f441d4 100644 --- a/tests/resource_tests.cpp +++ b/tests/resource_tests.cpp @@ -9,7 +9,9 @@ #include "../include/scripting/ScriptEngine.h" #include "../include/scripting/ResourceBindings.h" #include "raylib.h" - +extern "C" { +void acutest_skip_(const char* file, int line, const char* fmt, ...); +} static bool HasDisplay() { #if defined(_WIN32) return true; diff --git a/tests/scenegraph_tests.cpp b/tests/scenegraph_tests.cpp index 256c8a1..c49da20 100644 --- a/tests/scenegraph_tests.cpp +++ b/tests/scenegraph_tests.cpp @@ -11,6 +11,9 @@ #include "raylib.h" #include "entt.hpp" +extern "C" { +void acutest_skip_(const char* file, int line, const char* fmt, ...); +} static bool HasDisplay() { #if defined(_WIN32) return true; From 271e2ea7b77a514968984b8e1592713a3281244a Mon Sep 17 00:00:00 2001 From: Simian CI Date: Sun, 8 Mar 2026 03:28:05 +0000 Subject: [PATCH 33/53] Update wiki from docs (CI) --- wiki/Home.md | 11 +++++ wiki/Scenegraph.md | 94 ++++++++++++++++++++++++++++++++++++++++++ wiki/Scripting.md | 13 ++++++ wiki/Usage.md | 100 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 218 insertions(+) create mode 100644 wiki/Home.md create mode 100644 wiki/Scenegraph.md create mode 100644 wiki/Scripting.md create mode 100644 wiki/Usage.md diff --git a/wiki/Home.md b/wiki/Home.md new file mode 100644 index 0000000..0b27670 --- /dev/null +++ b/wiki/Home.md @@ -0,0 +1,11 @@ +# Simian Documentation + +This folder contains project documentation that is synced to the project's Gitea wiki. +Edit markdown files here and push to the repository; CI will mirror them to the wiki. + +## Pages +- [Scripting](Scripting.md) — scripting API and examples +- [Usage](Usage.md) — getting started and build instructions +- [Scenegraph](Scenegraph.md) — hierarchy components and scene format + + diff --git a/wiki/Scenegraph.md b/wiki/Scenegraph.md new file mode 100644 index 0000000..c407130 --- /dev/null +++ b/wiki/Scenegraph.md @@ -0,0 +1,94 @@ +# Scenegraph + +This project uses a lightweight hierarchy component to model parent/child relationships in ECS. +The scenegraph is EnTT-friendly and uses a linked-list structure for children. + +## Components + +### `Hierarchy` +Each entity can have a `Hierarchy` component with these fields: + +- `parent` — parent entity or `null` +- `first` — first child entity +- `prev` / `next` — sibling links + +This mirrors the common EnTT scenegraph pattern and avoids storing vectors of children inside a component. + +### `ECSTransform` (local) +Stores local position/scale and a Y-axis rotation (radians). + +### `WorldTransform` (computed) +Computed each frame from the hierarchy and local transform. Rendering uses `WorldTransform` so children move with parents. + +## Update Order + +1. Systems update local transforms (e.g., velocity system). +2. `UpdateWorldTransforms()` traverses the hierarchy and computes `WorldTransform`. +3. Rendering draws from `WorldTransform` + `Sprite`. + +## Script API + +```angelscript +ECS::SetParent(child, parent); +ECS::ClearParent(child); +uint p = ECS::GetParent(child); +bool has = ECS::HasParent(child); +``` + +## Scene File Format (TOML) + +Scenes are stored in `scenes/*.toml` using a minimal TOML-like structure. Example: + +```toml +[[entity]] +id = "root" +tag = "Root" +position = [0.0, 0.0, 0.0] +rotation_deg = 0.0 +scale = [1.0, 1.0, 1.0] + +[[entity]] +id = "parent" +parent = "root" +tag = "Parent" +position = [2.0, 0.0, 0.0] +model = "cube" +model_size = [1.0, 1.0, 1.0] +color = 0x00FF00FF +shader_vs = "shaders/toon.vs" +shader_fs = "shaders/toon.fs" + +[[entity]] +id = "child" +parent = "parent" +tag = "Child" +position = [0.0, 1.25, 0.0] +model = "sphere" +radius = 0.5 +color = 0xFF0000FF +shader_vs = "shaders/toon.vs" +shader_fs = "shaders/toon.fs" +``` + +### Supported Keys + +- `id` (string) — unique identifier for parent links +- `parent` (string) — parent entity id +- `tag` (string) — `Tag` component value +- `position` (vec3) +- `rotation` (radians) or `rotation_deg` (degrees) +- `scale` (vec3) +- `model` — `cube`, `sphere`, `plane`, or file path +- `model_size` (vec3) for cubes/planes +- `radius`, `rings`, `slices` for spheres +- `color` — hex `0xRRGGBBAA` (matches script colors) +- `outline_size` — optional sprite outline +- `shader_vs`, `shader_fs` — optional shader paths + +## Loading a Scene + +```angelscript +uint root = Scene::Load("scenes/demo.toml"); +``` + +`Scene::Load` returns a root entity that parents all top-level entities. Use `ECS::IsValid(root)` to check success on the scene load. diff --git a/wiki/Scripting.md b/wiki/Scripting.md new file mode 100644 index 0000000..3e0061f --- /dev/null +++ b/wiki/Scripting.md @@ -0,0 +1,13 @@ +# Scripting + +This page is a starting point for scripting documentation. + +## Overview +- Scripts live in `scripts/` and are executed by AngelScript. +- Predefined API and engine bindings are declared in `scripts/as.predefined`. + +## Examples +- `scripts/game.as` — demo showing ECS usage, rendering, scenegraph and input actions. + +## How to document APIs +Add Markdown pages in the `docs/` folder. Use relative links and include code fences for examples. diff --git a/wiki/Usage.md b/wiki/Usage.md new file mode 100644 index 0000000..2ed7f30 --- /dev/null +++ b/wiki/Usage.md @@ -0,0 +1,100 @@ +# Usage + +This page documents how to build, run and maintain the Simian project and how to publish documentation to the Gitea wiki. + +## Prerequisites + +- Git +- CMake (>= 3.16; 3.25 recommended) +- A C++ toolchain (Visual Studio on Windows, GCC/Clang on Linux/macOS) +- Optional: SSH access to your Gitea instance (for wiki sync) + +If you just cloned the repository, initialise submodules: + +```bash +git submodule update --init --recursive +``` + +## Build (Windows / MSVC) + +```powershell +mkdir build +cd build +cmake -S .. -B . -G "Visual Studio 17 2022" -A x64 +cmake --build . --config Release +# Run +.\Release\simian.exe +``` + +## Build (Linux / macOS) + +```bash +mkdir build +cd build +cmake .. +cmake --build . --config Release +./simian +``` + +## Run tests + +From the project root (after configuring the build): + +```bash +cmake --build build --config Release --target RUN_TESTS +# or use CTest +ctest --test-dir build --output-on-failure +``` + +## Scripting / Hot-reload + +- Scripts live in the `scripts/` directory (e.g. `scripts/game.as`). +- The engine watches the scripts directory and will hot-reload scripts when changed. +- Predefined API is declared in `scripts/as.predefined`. + +## Documentation & Wiki + +Docs source lives in the `docs/` folder. The repository contains a CI workflow and a local script to mirror `docs/` to the Gitea wiki. + +Manual sync (local): + +```bash +bash scripts/sync_wiki.sh +``` + +CI sync (automated): + +1. The workflow `.gitea/workflows/sync-docs-to-wiki.yml` runs on pushes that affect `docs/**`. +2. The workflow requires an SSH private key in repository secrets named `WIKI_SSH_KEY`. + +To create the deploy key and CI secret: + +```bash +# Generate a keypair (do not commit the private key) +ssh-keygen -t ed25519 -C "simian-wiki-ci" -f simian_wiki_ci -N "" + +# Add simian_wiki_ci.pub as a deploy key in your Gitea repo: Settings → Deploy Keys +# Enable write/push access for that key. + +# Copy the private key (simian_wiki_ci) into your CI provider as secret WIKI_SSH_KEY. +``` + +Notes: +- The workflow clones the wiki remote `git@gitea.appstack.me:nick/simian.wiki.git` and pushes updates. +- If your Gitea host/paths differ, update `.github/workflows/sync-docs-to-wiki.yml` or the `scripts/sync_wiki.sh` script accordingly. + +## Adding / Updating Documentation + +1. Add or edit Markdown files under `docs/`. +2. Put images in `docs/images/` and reference them with relative paths, e.g. `![Alt](images/diagram.png)`. +3. Commit and push to the repo; CI will sync changes automatically (once secrets/deploy-key are configured). + +## Troubleshooting + +- If the CI job fails with authentication errors, confirm the deploy key was added to the Gitea repo and the private key is stored in the CI secrets as `WIKI_SSH_KEY`. +- To debug locally, run the `scripts/sync_wiki.sh` script and watch for `git push` errors. + +## Scenes + +Scenes are stored as TOML files in `scenes/`. Use `Scene::Load("scenes/demo.toml")` from scripts to create entities with hierarchy relationships. +See [Scenegraph](Scenegraph.md) for the format and examples. From b95365f6a6f61e77e7208c9df0f5040bccabcd66 Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Sun, 8 Mar 2026 16:41:13 +1300 Subject: [PATCH 34/53] chore: fixing wiki stuff --- .gitea/workflows/sync-docs-to-wiki.yml | 11 ++- wiki/Home.md | 11 --- wiki/Scenegraph.md | 94 ----------------------- wiki/Scripting.md | 13 ---- wiki/Usage.md | 100 ------------------------- 5 files changed, 9 insertions(+), 220 deletions(-) delete mode 100644 wiki/Home.md delete mode 100644 wiki/Scenegraph.md delete mode 100644 wiki/Scripting.md delete mode 100644 wiki/Usage.md diff --git a/.gitea/workflows/sync-docs-to-wiki.yml b/.gitea/workflows/sync-docs-to-wiki.yml index acafe21..42f8925 100644 --- a/.gitea/workflows/sync-docs-to-wiki.yml +++ b/.gitea/workflows/sync-docs-to-wiki.yml @@ -29,15 +29,22 @@ jobs: run: | sudo apt-get update -qq sudo apt-get install -y rsync openssh-client + git config --global user.name "Simian CI" git config --global user.email "ci@simian.local" + + # Clean workspace to avoid committing local wiki/ dir back to main repo + git clean -fdx + git clone "$WIKI_REPO" wiki rsync -av --delete docs/ wiki/ + cd wiki + git checkout main 2>/dev/null || git checkout -b main git add -A if git diff --staged --quiet; then echo "No wiki changes" else - git commit -m "Update wiki from docs (CI)" - git push + git commit -m "Update wiki from docs (CI) [skip ci]" + git push origin main fi diff --git a/wiki/Home.md b/wiki/Home.md deleted file mode 100644 index 0b27670..0000000 --- a/wiki/Home.md +++ /dev/null @@ -1,11 +0,0 @@ -# Simian Documentation - -This folder contains project documentation that is synced to the project's Gitea wiki. -Edit markdown files here and push to the repository; CI will mirror them to the wiki. - -## Pages -- [Scripting](Scripting.md) — scripting API and examples -- [Usage](Usage.md) — getting started and build instructions -- [Scenegraph](Scenegraph.md) — hierarchy components and scene format - - diff --git a/wiki/Scenegraph.md b/wiki/Scenegraph.md deleted file mode 100644 index c407130..0000000 --- a/wiki/Scenegraph.md +++ /dev/null @@ -1,94 +0,0 @@ -# Scenegraph - -This project uses a lightweight hierarchy component to model parent/child relationships in ECS. -The scenegraph is EnTT-friendly and uses a linked-list structure for children. - -## Components - -### `Hierarchy` -Each entity can have a `Hierarchy` component with these fields: - -- `parent` — parent entity or `null` -- `first` — first child entity -- `prev` / `next` — sibling links - -This mirrors the common EnTT scenegraph pattern and avoids storing vectors of children inside a component. - -### `ECSTransform` (local) -Stores local position/scale and a Y-axis rotation (radians). - -### `WorldTransform` (computed) -Computed each frame from the hierarchy and local transform. Rendering uses `WorldTransform` so children move with parents. - -## Update Order - -1. Systems update local transforms (e.g., velocity system). -2. `UpdateWorldTransforms()` traverses the hierarchy and computes `WorldTransform`. -3. Rendering draws from `WorldTransform` + `Sprite`. - -## Script API - -```angelscript -ECS::SetParent(child, parent); -ECS::ClearParent(child); -uint p = ECS::GetParent(child); -bool has = ECS::HasParent(child); -``` - -## Scene File Format (TOML) - -Scenes are stored in `scenes/*.toml` using a minimal TOML-like structure. Example: - -```toml -[[entity]] -id = "root" -tag = "Root" -position = [0.0, 0.0, 0.0] -rotation_deg = 0.0 -scale = [1.0, 1.0, 1.0] - -[[entity]] -id = "parent" -parent = "root" -tag = "Parent" -position = [2.0, 0.0, 0.0] -model = "cube" -model_size = [1.0, 1.0, 1.0] -color = 0x00FF00FF -shader_vs = "shaders/toon.vs" -shader_fs = "shaders/toon.fs" - -[[entity]] -id = "child" -parent = "parent" -tag = "Child" -position = [0.0, 1.25, 0.0] -model = "sphere" -radius = 0.5 -color = 0xFF0000FF -shader_vs = "shaders/toon.vs" -shader_fs = "shaders/toon.fs" -``` - -### Supported Keys - -- `id` (string) — unique identifier for parent links -- `parent` (string) — parent entity id -- `tag` (string) — `Tag` component value -- `position` (vec3) -- `rotation` (radians) or `rotation_deg` (degrees) -- `scale` (vec3) -- `model` — `cube`, `sphere`, `plane`, or file path -- `model_size` (vec3) for cubes/planes -- `radius`, `rings`, `slices` for spheres -- `color` — hex `0xRRGGBBAA` (matches script colors) -- `outline_size` — optional sprite outline -- `shader_vs`, `shader_fs` — optional shader paths - -## Loading a Scene - -```angelscript -uint root = Scene::Load("scenes/demo.toml"); -``` - -`Scene::Load` returns a root entity that parents all top-level entities. Use `ECS::IsValid(root)` to check success on the scene load. diff --git a/wiki/Scripting.md b/wiki/Scripting.md deleted file mode 100644 index 3e0061f..0000000 --- a/wiki/Scripting.md +++ /dev/null @@ -1,13 +0,0 @@ -# Scripting - -This page is a starting point for scripting documentation. - -## Overview -- Scripts live in `scripts/` and are executed by AngelScript. -- Predefined API and engine bindings are declared in `scripts/as.predefined`. - -## Examples -- `scripts/game.as` — demo showing ECS usage, rendering, scenegraph and input actions. - -## How to document APIs -Add Markdown pages in the `docs/` folder. Use relative links and include code fences for examples. diff --git a/wiki/Usage.md b/wiki/Usage.md deleted file mode 100644 index 2ed7f30..0000000 --- a/wiki/Usage.md +++ /dev/null @@ -1,100 +0,0 @@ -# Usage - -This page documents how to build, run and maintain the Simian project and how to publish documentation to the Gitea wiki. - -## Prerequisites - -- Git -- CMake (>= 3.16; 3.25 recommended) -- A C++ toolchain (Visual Studio on Windows, GCC/Clang on Linux/macOS) -- Optional: SSH access to your Gitea instance (for wiki sync) - -If you just cloned the repository, initialise submodules: - -```bash -git submodule update --init --recursive -``` - -## Build (Windows / MSVC) - -```powershell -mkdir build -cd build -cmake -S .. -B . -G "Visual Studio 17 2022" -A x64 -cmake --build . --config Release -# Run -.\Release\simian.exe -``` - -## Build (Linux / macOS) - -```bash -mkdir build -cd build -cmake .. -cmake --build . --config Release -./simian -``` - -## Run tests - -From the project root (after configuring the build): - -```bash -cmake --build build --config Release --target RUN_TESTS -# or use CTest -ctest --test-dir build --output-on-failure -``` - -## Scripting / Hot-reload - -- Scripts live in the `scripts/` directory (e.g. `scripts/game.as`). -- The engine watches the scripts directory and will hot-reload scripts when changed. -- Predefined API is declared in `scripts/as.predefined`. - -## Documentation & Wiki - -Docs source lives in the `docs/` folder. The repository contains a CI workflow and a local script to mirror `docs/` to the Gitea wiki. - -Manual sync (local): - -```bash -bash scripts/sync_wiki.sh -``` - -CI sync (automated): - -1. The workflow `.gitea/workflows/sync-docs-to-wiki.yml` runs on pushes that affect `docs/**`. -2. The workflow requires an SSH private key in repository secrets named `WIKI_SSH_KEY`. - -To create the deploy key and CI secret: - -```bash -# Generate a keypair (do not commit the private key) -ssh-keygen -t ed25519 -C "simian-wiki-ci" -f simian_wiki_ci -N "" - -# Add simian_wiki_ci.pub as a deploy key in your Gitea repo: Settings → Deploy Keys -# Enable write/push access for that key. - -# Copy the private key (simian_wiki_ci) into your CI provider as secret WIKI_SSH_KEY. -``` - -Notes: -- The workflow clones the wiki remote `git@gitea.appstack.me:nick/simian.wiki.git` and pushes updates. -- If your Gitea host/paths differ, update `.github/workflows/sync-docs-to-wiki.yml` or the `scripts/sync_wiki.sh` script accordingly. - -## Adding / Updating Documentation - -1. Add or edit Markdown files under `docs/`. -2. Put images in `docs/images/` and reference them with relative paths, e.g. `![Alt](images/diagram.png)`. -3. Commit and push to the repo; CI will sync changes automatically (once secrets/deploy-key are configured). - -## Troubleshooting - -- If the CI job fails with authentication errors, confirm the deploy key was added to the Gitea repo and the private key is stored in the CI secrets as `WIKI_SSH_KEY`. -- To debug locally, run the `scripts/sync_wiki.sh` script and watch for `git push` errors. - -## Scenes - -Scenes are stored as TOML files in `scenes/`. Use `Scene::Load("scenes/demo.toml")` from scripts to create entities with hierarchy relationships. -See [Scenegraph](Scenegraph.md) for the format and examples. From 9a4dba0a503fc00ffa0e72e767b560f34f767b5d Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Sun, 8 Mar 2026 17:52:44 +1300 Subject: [PATCH 35/53] feat: scene editor --- docs/Scenegraph.md | 4 + imgui.ini | 32 +++-- include/Application.h | 1 + include/gui/GuiManager.h | 12 ++ src/gui/GuiManager.cpp | 297 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 338 insertions(+), 8 deletions(-) diff --git a/docs/Scenegraph.md b/docs/Scenegraph.md index c407130..8db1e67 100644 --- a/docs/Scenegraph.md +++ b/docs/Scenegraph.md @@ -92,3 +92,7 @@ uint root = Scene::Load("scenes/demo.toml"); ``` `Scene::Load` returns a root entity that parents all top-level entities. Use `ECS::IsValid(root)` to check success on the scene load. + +## Editor + +Run the app with `--editor` to open the ImGui editor. The **Scene** window shows the hierarchy tree, supports drag-and-drop reparenting, and lets you create/delete entities. The **Inspector** window shows `Tag`, `ECSTransform`, and `Sprite` for the selected entity and allows live editing. diff --git a/imgui.ini b/imgui.ini index 4a469ff..c8ba7a9 100644 --- a/imgui.ini +++ b/imgui.ini @@ -9,14 +9,14 @@ Size=400,400 Collapsed=0 [Window][Game Window] -Pos=8,28 -Size=1264,580 +Pos=324,28 +Size=645,580 Collapsed=0 DockId=0x00000001,0 [Window][Log Viewer] -Pos=8,610 -Size=1264,102 +Pos=324,610 +Size=645,102 Collapsed=0 DockId=0x00000002,0 @@ -75,8 +75,24 @@ Pos=1064,272 Size=196,63 Collapsed=0 -[Docking][Data] -DockSpace ID=0x9076BACA Window=0x34F970D7 Pos=8,28 Size=1264,684 Split=Y Selected=0x27A02DAA - DockNode ID=0x00000001 Parent=0x9076BACA SizeRef=1264,580 CentralNode=1 Selected=0x27A02DAA - DockNode ID=0x00000002 Parent=0x9076BACA SizeRef=1264,102 Selected=0xBEDDA0C1 +[Window][Inspector] +Pos=971,28 +Size=301,684 +Collapsed=0 +DockId=0x00000006,0 + +[Window][Scene] +Pos=8,28 +Size=314,684 +Collapsed=0 +DockId=0x00000003,0 + +[Docking][Data] +DockSpace ID=0x9076BACA Window=0x34F970D7 Pos=8,28 Size=1264,684 Split=X Selected=0x27A02DAA + DockNode ID=0x00000005 Parent=0x9076BACA SizeRef=961,684 Split=X + DockNode ID=0x00000003 Parent=0x00000005 SizeRef=314,684 Selected=0xE601B12F + DockNode ID=0x00000004 Parent=0x00000005 SizeRef=645,684 Split=Y + DockNode ID=0x00000001 Parent=0x00000004 SizeRef=1264,580 CentralNode=1 Selected=0x27A02DAA + DockNode ID=0x00000002 Parent=0x00000004 SizeRef=1264,102 Selected=0xBEDDA0C1 + DockNode ID=0x00000006 Parent=0x9076BACA SizeRef=301,684 Selected=0x36DC96AB diff --git a/include/Application.h b/include/Application.h index 055b1fb..b726922 100644 --- a/include/Application.h +++ b/include/Application.h @@ -21,6 +21,7 @@ public: bool IsEditorEnabled() const { return enableEditor; } bool HasScriptCompilationError() const { return scriptCompilationError; } + entt::registry& GetRegistry() { return registry; } private: ScriptEngine scriptEngine; diff --git a/include/gui/GuiManager.h b/include/gui/GuiManager.h index bbd51e0..7e631c4 100644 --- a/include/gui/GuiManager.h +++ b/include/gui/GuiManager.h @@ -5,6 +5,7 @@ #include "gui/fa-solid-900.h" #include "gui/ImGuiNotify.hpp" #include "LogWindow.h" // Include the new LogWindow class +#include class Application; @@ -22,8 +23,19 @@ private: void RenderNotifications(); void RenderErrorBanner(); void SetTheme(); + void RenderSceneWindow(); + void RenderInspectorWindow(); + void RenderEntityNode(entt::entity entity); + bool IsEntityAncestor(entt::entity ancestor, entt::entity entity) const; + const char* GetEntityLabel(entt::entity entity); + void SyncTagBuffer(entt::entity entity); bool showLogWindow = true; + bool showSceneWindow = true; + bool showInspectorWindow = true; Application *app; LogWindow logWindow; // Add LogWindow as a member + entt::entity selectedEntity = entt::null; + entt::entity tagBufferEntity = entt::null; + char tagBuffer[128] = {0}; }; \ No newline at end of file diff --git a/src/gui/GuiManager.cpp b/src/gui/GuiManager.cpp index 2503e9c..eec8393 100644 --- a/src/gui/GuiManager.cpp +++ b/src/gui/GuiManager.cpp @@ -3,8 +3,15 @@ #include // Add this to fix the incomplete type error #include #include +#include +#include +#include +#include +#include #include "log.h" #include "Application.h" +#include "ECSComponents.h" +#include "SceneGraph.h" #include // Add this for cross-platform file handling GuiManager::GuiManager() {} @@ -33,6 +40,8 @@ void GuiManager::Render(RenderTexture2D &renderTexture) RenderErrorBanner(); RenderNotifications(); logWindow.Render(showLogWindow); // Render the LogWindow + RenderSceneWindow(); + RenderInspectorWindow(); rlImGuiEnd(); @@ -82,6 +91,8 @@ void GuiManager::SetupDockspace(RenderTexture2D &renderTexture) if (ImGui::BeginMenu("View")) { ImGui::MenuItem("Log Viewer", "Ctrl + L", &showLogWindow); + ImGui::MenuItem("Scene", nullptr, &showSceneWindow); + ImGui::MenuItem("Inspector", nullptr, &showInspectorWindow); ImGui::EndMenu(); } ImGui::EndMenuBar(); @@ -108,6 +119,292 @@ void GuiManager::SetupDockspace(RenderTexture2D &renderTexture) ImGui::End(); } +static entt::id_type ToId(entt::entity entity) { + return entt::to_integral(entity); +} + +bool GuiManager::IsEntityAncestor(entt::entity ancestor, entt::entity entity) const +{ + if (!app) return false; + auto& registry = app->GetRegistry(); + entt::entity current = entity; + while (auto* hierarchy = registry.try_get(current)) { + if (hierarchy->parent == ancestor) { + return true; + } + if (hierarchy->parent == entt::null) { + return false; + } + current = hierarchy->parent; + } + return false; +} + +const char* GuiManager::GetEntityLabel(entt::entity entity) +{ + if (!app) return ""; + auto& registry = app->GetRegistry(); + if (auto* tag = registry.try_get(entity)) { + if (!tag->name.empty()) { + return tag->name.c_str(); + } + } + + static char label[64]; + std::snprintf(label, sizeof(label), "Entity %u", static_cast(ToId(entity))); + return label; +} + +void GuiManager::SyncTagBuffer(entt::entity entity) +{ + if (!app) return; + if (entity == tagBufferEntity) return; + + tagBufferEntity = entity; + tagBuffer[0] = '\0'; + auto& registry = app->GetRegistry(); + if (auto* tag = registry.try_get(entity)) { + std::snprintf(tagBuffer, sizeof(tagBuffer), "%s", tag->name.c_str()); + } +} + +void GuiManager::RenderEntityNode(entt::entity entity) +{ + if (!app) return; + auto& registry = app->GetRegistry(); + + auto* hierarchy = registry.try_get(entity); + bool hasChildren = hierarchy && hierarchy->first != entt::null; + + ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_SpanFullWidth; + if (entity == selectedEntity) { + flags |= ImGuiTreeNodeFlags_Selected; + } + if (!hasChildren) { + flags |= ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen; + } + + bool opened = ImGui::TreeNodeEx(reinterpret_cast(static_cast(ToId(entity))), flags, "%s", GetEntityLabel(entity)); + if (ImGui::IsItemClicked()) { + selectedEntity = entity; + SyncTagBuffer(entity); + } + + if (ImGui::BeginDragDropSource()) { + entt::entity payload = entity; + ImGui::SetDragDropPayload("SCENE_ENTITY", &payload, sizeof(payload)); + ImGui::Text("%s", GetEntityLabel(entity)); + ImGui::EndDragDropSource(); + } + + if (ImGui::BeginDragDropTarget()) { + if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("SCENE_ENTITY")) { + entt::entity dragged = *static_cast(payload->Data); + if (registry.valid(dragged) && dragged != entity && !IsEntityAncestor(dragged, entity)) { + AttachChild(registry, dragged, entity); + } + } + ImGui::EndDragDropTarget(); + } + + if (opened && hasChildren) { + entt::entity child = hierarchy->first; + while (child != entt::null) { + RenderEntityNode(child); + auto* childHierarchy = registry.try_get(child); + child = childHierarchy ? childHierarchy->next : entt::null; + } + ImGui::TreePop(); + } +} + +void GuiManager::RenderSceneWindow() +{ + if (!showSceneWindow) return; + ImGui::Begin("Scene", &showSceneWindow); + + if (!app) { + ImGui::Text("No application context."); + ImGui::End(); + return; + } + + auto& registry = app->GetRegistry(); + + if (ImGui::Button("Create Entity")) { + entt::entity entity = registry.create(); + std::string name = "Entity " + std::to_string(static_cast(ToId(entity))); + registry.emplace(entity, name); + registry.emplace(entity, Vector3{0.0f, 0.0f, 0.0f}, Vector3{1.0f, 1.0f, 1.0f}, 0.0f); + selectedEntity = entity; + SyncTagBuffer(entity); + } + + ImGui::SameLine(); + bool canDelete = registry.valid(selectedEntity); + if (!canDelete) { + ImGui::BeginDisabled(); + } + if (ImGui::Button("Delete Selected") && canDelete) { + DetachChildren(registry, selectedEntity); + DetachFromParent(registry, selectedEntity); + registry.destroy(selectedEntity); + selectedEntity = entt::null; + tagBufferEntity = entt::null; + tagBuffer[0] = '\0'; + } + if (!canDelete) { + ImGui::EndDisabled(); + } + + ImGui::Separator(); + + std::vector roots; + auto &storage = registry.storage(); + for (auto entity : storage) { + auto* hierarchy = registry.try_get(entity); + if (!hierarchy || hierarchy->parent == entt::null || !registry.valid(hierarchy->parent)) { + roots.push_back(entity); + } + } + + std::sort(roots.begin(), roots.end(), [](entt::entity a, entt::entity b) { + return ToId(a) < ToId(b); + }); + + for (auto entity : roots) { + RenderEntityNode(entity); + } + + ImGui::Separator(); + ImGui::TextDisabled("Drop here to clear parent"); + if (ImGui::BeginDragDropTarget()) { + if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("SCENE_ENTITY")) { + entt::entity dragged = *static_cast(payload->Data); + if (registry.valid(dragged)) { + DetachFromParent(registry, dragged); + } + } + ImGui::EndDragDropTarget(); + } + + ImGui::End(); +} + +void GuiManager::RenderInspectorWindow() +{ + if (!showInspectorWindow) return; + ImGui::Begin("Inspector", &showInspectorWindow); + + if (!app) { + ImGui::Text("No application context."); + ImGui::End(); + return; + } + + auto& registry = app->GetRegistry(); + if (!registry.valid(selectedEntity)) { + ImGui::Text("No entity selected."); + ImGui::End(); + return; + } + + ImGui::Text("%s", GetEntityLabel(selectedEntity)); + ImGui::Separator(); + + // Tag + if (registry.any_of(selectedEntity)) { + SyncTagBuffer(selectedEntity); + if (ImGui::InputText("Tag", tagBuffer, sizeof(tagBuffer))) { + auto& tag = registry.get(selectedEntity); + tag.name = tagBuffer; + } + } else { + if (ImGui::Button("Add Tag")) { + registry.emplace(selectedEntity, "Entity"); + SyncTagBuffer(selectedEntity); + } + } + + // Transform + if (registry.any_of(selectedEntity)) { + auto& transform = registry.get(selectedEntity); + float position[3] = {transform.position.x, transform.position.y, transform.position.z}; + float scale[3] = {transform.scale.x, transform.scale.y, transform.scale.z}; + float rotationDeg = transform.rotation * RAD2DEG; + + if (ImGui::DragFloat3("Position", position, 0.1f)) { + transform.position = {position[0], position[1], position[2]}; + } + if (ImGui::DragFloat3("Scale", scale, 0.05f)) { + transform.scale = {scale[0], scale[1], scale[2]}; + } + if (ImGui::DragFloat("Rotation (deg)", &rotationDeg, 0.5f)) { + transform.rotation = rotationDeg * DEG2RAD; + } + } else { + if (ImGui::Button("Add Transform")) { + registry.emplace(selectedEntity, Vector3{0.0f, 0.0f, 0.0f}, Vector3{1.0f, 1.0f, 1.0f}, 0.0f); + } + } + + // Hierarchy + if (auto* hierarchy = registry.try_get(selectedEntity)) { + ImGui::Separator(); + ImGui::Text("Hierarchy"); + if (hierarchy->parent != entt::null) { + ImGui::Text("Parent: %s", GetEntityLabel(hierarchy->parent)); + if (ImGui::Button("Clear Parent")) { + DetachFromParent(registry, selectedEntity); + } + } else { + ImGui::Text("Parent: "); + } + } + + // Sprite + if (registry.any_of(selectedEntity)) { + auto& sprite = registry.get(selectedEntity); + ImGui::Separator(); + ImGui::Text("Sprite"); + + int modelId = static_cast(sprite.modelId); + if (ImGui::InputInt("Model Id", &modelId)) { + sprite.modelId = modelId < 0 ? 0 : static_cast(modelId); + } + + int shaderId = static_cast(sprite.shaderId); + if (ImGui::InputInt("Shader Id", &shaderId)) { + sprite.shaderId = shaderId < 0 ? 0 : static_cast(shaderId); + } + + float color[4] = { + sprite.color.r / 255.0f, + sprite.color.g / 255.0f, + sprite.color.b / 255.0f, + sprite.color.a / 255.0f + }; + if (ImGui::ColorEdit4("Color", color)) { + sprite.color.r = static_cast(color[0] * 255.0f); + sprite.color.g = static_cast(color[1] * 255.0f); + sprite.color.b = static_cast(color[2] * 255.0f); + sprite.color.a = static_cast(color[3] * 255.0f); + } + + ImGui::DragFloat("Outline", &sprite.outlineSize, 0.05f, 0.0f, 10.0f); + + if (ImGui::Button("Remove Sprite")) { + registry.remove(selectedEntity); + } + } else { + if (ImGui::Button("Add Sprite")) { + registry.emplace(selectedEntity, 0, WHITE, 0.0f, 0); + } + } + + ImGui::End(); +} + void GuiManager::RenderErrorBanner() { if (!app || !app->HasScriptCompilationError()) From 18ca7105c5d4dd2c9ebbe52ab48114c92a64f812 Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Sun, 8 Mar 2026 19:24:39 +1300 Subject: [PATCH 36/53] fix: mazimise window and notification freezing --- imgui.ini | 34 ++++---- include/SceneLoader.h | 3 + include/gui/GuiManager.h | 7 ++ include/gui/ImGuiNotify.hpp | 5 +- src/Application.cpp | 3 + src/SceneLoader.cpp | 149 ++++++++++++++++++++++++++++++- src/gui/GuiManager.cpp | 169 ++++++++++++++++++++++++++++++++++-- 7 files changed, 344 insertions(+), 26 deletions(-) diff --git a/imgui.ini b/imgui.ini index c8ba7a9..afcbfa3 100644 --- a/imgui.ini +++ b/imgui.ini @@ -1,6 +1,6 @@ [Window][DockSpaceHost] Pos=0,0 -Size=1280,720 +Size=1920,991 Collapsed=0 [Window][Debug##Default] @@ -10,38 +10,38 @@ Collapsed=0 [Window][Game Window] Pos=324,28 -Size=645,580 +Size=1285,851 Collapsed=0 DockId=0x00000001,0 [Window][Log Viewer] -Pos=324,610 -Size=645,102 +Pos=324,881 +Size=1285,102 Collapsed=0 DockId=0x00000002,0 [Window][##TOAST0] -Pos=1035,637 -Size=225,63 +Pos=1700,908 +Size=200,63 Collapsed=0 [Window][##TOAST1] -Pos=1057,564 -Size=203,63 +Pos=1704,835 +Size=196,63 Collapsed=0 [Window][##TOAST2] -Pos=1064,491 +Pos=1704,762 Size=196,63 Collapsed=0 [Window][##TOAST3] -Pos=1064,418 +Pos=1704,689 Size=196,63 Collapsed=0 [Window][##TOAST4] -Pos=1064,345 +Pos=1704,616 Size=196,63 Collapsed=0 @@ -71,24 +71,24 @@ Size=71,108 Collapsed=0 [Window][##TOAST5] -Pos=1064,272 -Size=196,63 +Pos=1071,272 +Size=189,63 Collapsed=0 [Window][Inspector] -Pos=971,28 -Size=301,684 +Pos=1611,28 +Size=301,955 Collapsed=0 DockId=0x00000006,0 [Window][Scene] Pos=8,28 -Size=314,684 +Size=314,955 Collapsed=0 DockId=0x00000003,0 [Docking][Data] -DockSpace ID=0x9076BACA Window=0x34F970D7 Pos=8,28 Size=1264,684 Split=X Selected=0x27A02DAA +DockSpace ID=0x9076BACA Window=0x34F970D7 Pos=8,28 Size=1904,955 Split=X Selected=0x27A02DAA DockNode ID=0x00000005 Parent=0x9076BACA SizeRef=961,684 Split=X DockNode ID=0x00000003 Parent=0x00000005 SizeRef=314,684 Selected=0xE601B12F DockNode ID=0x00000004 Parent=0x00000005 SizeRef=645,684 Split=Y diff --git a/include/SceneLoader.h b/include/SceneLoader.h index 142699f..b35d79c 100644 --- a/include/SceneLoader.h +++ b/include/SceneLoader.h @@ -13,5 +13,8 @@ void SetSceneContext(entt::registry* registry, ModelManager* modelManager, Shade // Load a scene from a TOML-like file. Returns the root entity (or entt::null on failure). entt::entity LoadSceneFromFile(const std::string& path, bool clearExisting); +// Save the current scene to a TOML-like file. Returns true on success. +bool SaveSceneToFile(const std::string& path); + // Clear all entities from the registry void ClearScene(); diff --git a/include/gui/GuiManager.h b/include/gui/GuiManager.h index 7e631c4..b758bf3 100644 --- a/include/gui/GuiManager.h +++ b/include/gui/GuiManager.h @@ -16,6 +16,7 @@ public: void Initialize(Application* application); void Render(RenderTexture2D& renderTexture); + void ApplyRenderTextureResize(RenderTexture2D& renderTexture); void Shutdown(); private: @@ -38,4 +39,10 @@ private: entt::entity selectedEntity = entt::null; entt::entity tagBufferEntity = entt::null; char tagBuffer[128] = {0}; + ImVec2 desiredRenderSize = ImVec2(0.0f, 0.0f); + bool requestSceneNew = false; + bool requestSceneLoad = false; + bool requestSceneSave = false; + char sceneLoadPath[260] = {0}; + char sceneSavePath[260] = {0}; }; \ No newline at end of file diff --git a/include/gui/ImGuiNotify.hpp b/include/gui/ImGuiNotify.hpp index c633b40..e127a56 100644 --- a/include/gui/ImGuiNotify.hpp +++ b/include/gui/ImGuiNotify.hpp @@ -41,7 +41,7 @@ // Warning: Requires ImGui docking with multi-viewport enabled #ifndef NOTIFY_RENDER_OUTSIDE_MAIN_WINDOW -#define NOTIFY_RENDER_OUTSIDE_MAIN_WINDOW true // If true, the notifications will be rendered in the corner of the monitor, otherwise in the corner of the main window +#define NOTIFY_RENDER_OUTSIDE_MAIN_WINDOW false // If true, the notifications will be rendered in the corner of the monitor, otherwise in the corner of the main window #endif /** @@ -502,8 +502,9 @@ namespace ImGui } #if NOTIFY_RENDER_LIMIT > 0 - if (i > NOTIFY_RENDER_LIMIT) + if (i >= NOTIFY_RENDER_LIMIT) { + ++i; continue; } #endif diff --git a/src/Application.cpp b/src/Application.cpp index 3b4aeea..c120722 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -67,6 +67,7 @@ bool Application::Initialize(int argc, char *argv[]) } // Initialize Raylib + SetConfigFlags(FLAG_WINDOW_RESIZABLE); InitWindow(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_TITLE); SetTargetFPS(TARGET_FPS); @@ -274,6 +275,8 @@ void Application::Draw() ImGuiIO &io = ImGui::GetIO(); io.DisplaySize = ImVec2((float)screenWidth, (float)screenHeight); + guiManager.ApplyRenderTextureResize(renderTexture); + BeginTextureMode(renderTexture); ClearBackground(SKYBLUE); RenderScene(); diff --git a/src/SceneLoader.cpp b/src/SceneLoader.cpp index 1543d09..d5c6b91 100644 --- a/src/SceneLoader.cpp +++ b/src/SceneLoader.cpp @@ -11,6 +11,8 @@ #include #include #include +#include +#include static entt::registry* g_sceneRegistry = nullptr; static ModelManager* g_sceneModelManager = nullptr; @@ -39,6 +41,8 @@ struct SceneEntityDef { bool hasSprite = false; std::string model; + unsigned int modelId = 0; + bool hasModelId = false; Vector3 modelSize{1.0f, 1.0f, 1.0f}; float radius = 0.5f; int rings = 16; @@ -47,6 +51,8 @@ struct SceneEntityDef { float outlineSize = 0.0f; std::string shaderVs; std::string shaderFs; + unsigned int shaderId = 0; + bool hasShaderId = false; }; static std::string Trim(const std::string& value) { @@ -125,6 +131,43 @@ static bool ParseString(const std::string& value, std::string& out) { return !out.empty(); } +static std::string EscapeString(const std::string& value) { + std::string out; + out.reserve(value.size()); + for (char c : value) { + if (c == '"' || c == '\\') { + out.push_back('\\'); + } + out.push_back(c); + } + return out; +} + +static std::string FloatToString(float value) { + std::ostringstream ss; + ss << std::fixed << std::setprecision(3) << value; + return ss.str(); +} + +static std::string Vec3ToString(const Vector3& value) { + std::ostringstream ss; + ss << '[' + << FloatToString(value.x) << ", " + << FloatToString(value.y) << ", " + << FloatToString(value.z) << ']'; + return ss.str(); +} + +static std::string ColorToHexString(Color color) { + unsigned int packed = (static_cast(color.r) << 24) + | (static_cast(color.g) << 16) + | (static_cast(color.b) << 8) + | static_cast(color.a); + std::ostringstream ss; + ss << "0x" << std::uppercase << std::hex << std::setw(8) << std::setfill('0') << packed; + return ss.str(); +} + static unsigned int LoadModelFor(const SceneEntityDef& def, std::unordered_map& modelCache) { if (!g_sceneModelManager || def.model.empty()) return 0; @@ -243,6 +286,10 @@ entt::entity LoadSceneFromFile(const std::string& path, bool clearExisting) { } else if (key == "model") { ParseString(value, current->model); current->hasSprite = true; + } else if (key == "model_id") { + current->modelId = static_cast(std::stoul(value, nullptr, 0)); + current->hasModelId = true; + current->hasSprite = true; } else if (key == "model_size") { ParseVec3(value, current->modelSize); } else if (key == "radius") { @@ -260,6 +307,10 @@ entt::entity LoadSceneFromFile(const std::string& path, bool clearExisting) { ParseString(value, current->shaderVs); } else if (key == "shader_fs") { ParseString(value, current->shaderFs); + } else if (key == "shader_id") { + current->shaderId = static_cast(std::stoul(value, nullptr, 0)); + current->hasShaderId = true; + current->hasSprite = true; } else { log_warn("Scene parse: unknown key '%s' at line %d", key.c_str(), lineNumber); } @@ -299,14 +350,24 @@ entt::entity LoadSceneFromFile(const std::string& path, bool clearExisting) { } if (def.hasSprite) { - unsigned int modelId = LoadModelFor(def, modelCache); + unsigned int modelId = 0; + if (def.hasModelId) { + modelId = def.modelId; + } else if (!def.model.empty()) { + modelId = LoadModelFor(def, modelCache); + } Color col = { static_cast((def.color >> 24) & 0xFF), static_cast((def.color >> 16) & 0xFF), static_cast((def.color >> 8) & 0xFF), static_cast(def.color & 0xFF) }; - unsigned int shaderId = LoadShaderFor(def, shaderCache); + unsigned int shaderId = 0; + if (def.hasShaderId) { + shaderId = def.shaderId; + } else if (!def.shaderVs.empty() && !def.shaderFs.empty()) { + shaderId = LoadShaderFor(def, shaderCache); + } g_sceneRegistry->emplace(entity, static_cast(modelId), col, def.outlineSize, shaderId); } } @@ -331,3 +392,87 @@ entt::entity LoadSceneFromFile(const std::string& path, bool clearExisting) { UpdateWorldTransforms(*g_sceneRegistry); return root; } + +bool SaveSceneToFile(const std::string& path) { + if (!g_sceneRegistry) { + log_error("Scene save failed (registry missing)"); + return false; + } + + std::ofstream file(path); + if (!file.is_open()) { + log_error("Failed to open scene file for writing: %s", path.c_str()); + return false; + } + + auto& registry = *g_sceneRegistry; + std::vector entities; + auto& storage = registry.storage(); + + for (auto entity : storage) { + if (!registry.valid(entity)) { + continue; + } + + auto* tag = registry.try_get(entity); + auto* hierarchy = registry.try_get(entity); + if (tag && tag->name == "SceneRoot" && (!hierarchy || hierarchy->parent == entt::null)) { + continue; + } + + entities.push_back(entity); + } + + std::sort(entities.begin(), entities.end(), [](entt::entity a, entt::entity b) { + return entt::to_integral(a) < entt::to_integral(b); + }); + + std::unordered_map idMap; + idMap.reserve(entities.size()); + for (auto entity : entities) { + std::ostringstream ss; + ss << "entity_" << static_cast(entt::to_integral(entity)); + idMap[entity] = ss.str(); + } + + for (auto entity : entities) { + file << "[[entity]]\n"; + file << "id = \"" << idMap[entity] << "\"\n"; + + if (auto* hierarchy = registry.try_get(entity)) { + if (hierarchy->parent != entt::null) { + auto it = idMap.find(hierarchy->parent); + if (it != idMap.end()) { + file << "parent = \"" << it->second << "\"\n"; + } + } + } + + if (auto* tag = registry.try_get(entity)) { + if (!tag->name.empty()) { + file << "tag = \"" << EscapeString(tag->name) << "\"\n"; + } + } + + if (auto* transform = registry.try_get(entity)) { + file << "position = " << Vec3ToString(transform->position) << "\n"; + file << "scale = " << Vec3ToString(transform->scale) << "\n"; + file << "rotation_deg = " << FloatToString(transform->rotation * RAD2DEG) << "\n"; + } + + if (auto* sprite = registry.try_get(entity)) { + if (sprite->modelId > 0) { + file << "model_id = " << sprite->modelId << "\n"; + } + file << "color = " << ColorToHexString(sprite->color) << "\n"; + file << "outline_size = " << FloatToString(sprite->outlineSize) << "\n"; + if (sprite->shaderId > 0) { + file << "shader_id = " << sprite->shaderId << "\n"; + } + } + + file << "\n"; + } + + return true; +} diff --git a/src/gui/GuiManager.cpp b/src/gui/GuiManager.cpp index eec8393..249ee05 100644 --- a/src/gui/GuiManager.cpp +++ b/src/gui/GuiManager.cpp @@ -12,6 +12,7 @@ #include "Application.h" #include "ECSComponents.h" #include "SceneGraph.h" +#include "SceneLoader.h" #include // Add this for cross-platform file handling GuiManager::GuiManager() {} @@ -24,10 +25,16 @@ void GuiManager::Initialize(Application *application) rlImGuiSetup(true); ImGuiIO &io = ImGui::GetIO(); io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; - io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; SetTheme(); + if (sceneLoadPath[0] == '\0') { + std::snprintf(sceneLoadPath, sizeof(sceneLoadPath), "scenes/demo.toml"); + } + if (sceneSavePath[0] == '\0') { + std::snprintf(sceneSavePath, sizeof(sceneSavePath), "scenes/demo.toml"); + } + logWindow.Initialize(); // Initialize the LogWindow log_trace("GuiManager::Initialize - Started"); } @@ -50,6 +57,25 @@ void GuiManager::Render(RenderTexture2D &renderTexture) ImGui::RenderPlatformWindowsDefault(); } +void GuiManager::ApplyRenderTextureResize(RenderTexture2D& renderTexture) +{ + if (desiredRenderSize.x < 1.0f || desiredRenderSize.y < 1.0f) { + return; + } + + const int targetWidth = std::max(1, static_cast(desiredRenderSize.x)); + const int targetHeight = std::max(1, static_cast(desiredRenderSize.y)); + + if (renderTexture.texture.id == 0 || + renderTexture.texture.width != targetWidth || + renderTexture.texture.height != targetHeight) { + if (renderTexture.texture.id != 0) { + UnloadRenderTexture(renderTexture); + } + renderTexture = LoadRenderTexture(targetWidth, targetHeight); + } +} + void GuiManager::Shutdown() { rlImGuiShutdown(); @@ -88,6 +114,22 @@ void GuiManager::SetupDockspace(RenderTexture2D &renderTexture) } ImGui::EndMenu(); } + if (ImGui::BeginMenu("Scene")) + { + if (ImGui::MenuItem("New", "Ctrl + N")) + { + requestSceneNew = true; + } + if (ImGui::MenuItem("Load...", "Ctrl + O")) + { + requestSceneLoad = true; + } + if (ImGui::MenuItem("Save As...", "Ctrl + S")) + { + requestSceneSave = true; + } + ImGui::EndMenu(); + } if (ImGui::BeginMenu("View")) { ImGui::MenuItem("Log Viewer", "Ctrl + L", &showLogWindow); @@ -106,6 +148,113 @@ void GuiManager::SetupDockspace(RenderTexture2D &renderTexture) { app->Shutdown(); } + if (ImGui::GetIO().KeyCtrl && ImGui::IsKeyPressed(ImGuiKey_N)) + { + requestSceneNew = true; + } + if (ImGui::GetIO().KeyCtrl && ImGui::IsKeyPressed(ImGuiKey_O)) + { + requestSceneLoad = true; + } + if (ImGui::GetIO().KeyCtrl && ImGui::IsKeyPressed(ImGuiKey_S)) + { + requestSceneSave = true; + } + + if (requestSceneNew) + { + ImGui::OpenPopup("New Scene"); + requestSceneNew = false; + } + if (requestSceneLoad) + { + ImGui::OpenPopup("Load Scene"); + requestSceneLoad = false; + } + if (requestSceneSave) + { + ImGui::OpenPopup("Save Scene"); + requestSceneSave = false; + } + + if (ImGui::BeginPopupModal("New Scene", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) + { + ImGui::Text("Clear the current scene and start new?"); + ImGui::Spacing(); + + if (ImGui::Button("Create New")) + { + ClearScene(); + selectedEntity = entt::null; + tagBufferEntity = entt::null; + tagBuffer[0] = '\0'; + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::Button("Cancel")) + { + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } + + if (ImGui::BeginPopupModal("Load Scene", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) + { + ImGui::InputText("Path", sceneLoadPath, sizeof(sceneLoadPath)); + bool hasPath = sceneLoadPath[0] != '\0'; + if (!hasPath) + { + ImGui::BeginDisabled(); + } + if (ImGui::Button("Load")) + { + entt::entity root = LoadSceneFromFile(sceneLoadPath, true); + if (root != entt::null) + { + selectedEntity = entt::null; + tagBufferEntity = entt::null; + tagBuffer[0] = '\0'; + ImGui::CloseCurrentPopup(); + } + } + if (!hasPath) + { + ImGui::EndDisabled(); + } + ImGui::SameLine(); + if (ImGui::Button("Cancel")) + { + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } + + if (ImGui::BeginPopupModal("Save Scene", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) + { + ImGui::InputText("Path", sceneSavePath, sizeof(sceneSavePath)); + bool hasPath = sceneSavePath[0] != '\0'; + if (!hasPath) + { + ImGui::BeginDisabled(); + } + if (ImGui::Button("Save")) + { + if (SaveSceneToFile(sceneSavePath)) + { + ImGui::CloseCurrentPopup(); + } + } + if (!hasPath) + { + ImGui::EndDisabled(); + } + ImGui::SameLine(); + if (ImGui::Button("Cancel")) + { + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } ImGuiID dockspace_id = ImGui::GetID("MyDockSpace"); ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags); @@ -113,7 +262,17 @@ void GuiManager::SetupDockspace(RenderTexture2D &renderTexture) ImGui::Begin("Game Window"); // Render Raylib content to the Game Window - rlImGuiImageRenderTexture(&renderTexture); + ImVec2 avail = ImGui::GetContentRegionAvail(); + const int drawWidth = std::max(1, static_cast(avail.x)); + const int drawHeight = std::max(1, static_cast(avail.y)); + desiredRenderSize = ImVec2(static_cast(drawWidth), static_cast(drawHeight)); + + if (renderTexture.texture.id != 0 && drawWidth > 0 && drawHeight > 0) { + rlImGuiImageRect(&renderTexture.texture, drawWidth, drawHeight, + Rectangle{0, 0, static_cast(renderTexture.texture.width), -static_cast(renderTexture.texture.height)}); + } else { + ImGui::TextDisabled("No render target available"); + } ImGui::End(); ImGui::End(); @@ -476,9 +635,9 @@ void GuiManager::SetTheme() colors[ImGuiCol_CheckMark] = ImVec4(0.33f, 0.67f, 0.86f, 1.00f); colors[ImGuiCol_SliderGrab] = ImVec4(0.34f, 0.34f, 0.34f, 0.54f); colors[ImGuiCol_SliderGrabActive] = ImVec4(0.56f, 0.56f, 0.56f, 0.54f); - colors[ImGuiCol_Button] = ImVec4(0.05f, 0.05f, 0.05f, 0.54f); - colors[ImGuiCol_ButtonHovered] = ImVec4(0.19f, 0.19f, 0.19f, 0.54f); - colors[ImGuiCol_ButtonActive] = ImVec4(0.20f, 0.22f, 0.23f, 1.00f); + colors[ImGuiCol_Button] = ImVec4(0.12f, 0.38f, 0.70f, 0.90f); + colors[ImGuiCol_ButtonHovered] = ImVec4(0.16f, 0.50f, 0.88f, 1.00f); + colors[ImGuiCol_ButtonActive] = ImVec4(0.10f, 0.32f, 0.60f, 1.00f); colors[ImGuiCol_Header] = ImVec4(0.00f, 0.00f, 0.00f, 0.52f); colors[ImGuiCol_HeaderHovered] = ImVec4(0.00f, 0.00f, 0.00f, 0.36f); colors[ImGuiCol_HeaderActive] = ImVec4(0.20f, 0.22f, 0.23f, 0.33f); From 28328cbc0d4f5a78b24a7cd07027eba5179f8c49 Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Sun, 8 Mar 2026 20:25:11 +1300 Subject: [PATCH 37/53] feat: editor improvements --- .gitea/workflows/sync-docs-to-wiki.yml | 18 +- docs/Editor.md | 77 +++++++ docs/Home.md | 2 +- imgui.ini | 35 ++- include/ModelManager.h | 30 +++ include/ShaderManager.h | 9 + include/gui/GuiManager.h | 1 + scenes/demo.toml | 47 ++-- scenes/demo2.toml | 43 ++++ scripts/update.as | 35 --- src/ModelManager.cpp | 60 +++++ src/SceneLoader.cpp | 73 ++++-- src/ShaderManager.cpp | 14 ++ src/gui/GuiManager.cpp | 308 +++++++++++++++++++++++-- src/scripting/ResourceBindings.cpp | 9 +- 15 files changed, 655 insertions(+), 106 deletions(-) create mode 100644 docs/Editor.md create mode 100644 scenes/demo2.toml delete mode 100644 scripts/update.as diff --git a/.gitea/workflows/sync-docs-to-wiki.yml b/.gitea/workflows/sync-docs-to-wiki.yml index 42f8925..444d84b 100644 --- a/.gitea/workflows/sync-docs-to-wiki.yml +++ b/.gitea/workflows/sync-docs-to-wiki.yml @@ -28,18 +28,22 @@ jobs: WIKI_REPO: git@gitea.appstack.me:nick/simian.wiki.git run: | sudo apt-get update -qq - sudo apt-get install -y rsync openssh-client - + sudo apt-get install -y rsync + git config --global user.name "Simian CI" git config --global user.email "ci@simian.local" - - # Clean workspace to avoid committing local wiki/ dir back to main repo - git clean -fdx - + + # Clean slate: remove any existing wiki/ dir + rm -rf wiki + + # Fresh clone of simian.wiki.git git clone "$WIKI_REPO" wiki + + # Overwrite contents with docs/ rsync -av --delete docs/ wiki/ - + cd wiki + # Ensure main branch (create if empty) git checkout main 2>/dev/null || git checkout -b main git add -A if git diff --staged --quiet; then diff --git a/docs/Editor.md b/docs/Editor.md new file mode 100644 index 0000000..5841ce9 --- /dev/null +++ b/docs/Editor.md @@ -0,0 +1,77 @@ +# Editor Overview + +This document outlines the in-app editor UI, its panels, and common workflows. + +## Launching the Editor + +- Start the app with the editor flag enabled. +- The editor UI appears as dockable panels around the Game Window. + +## Layout + +- DockSpace host with a top menu bar. +- Panels: Game Window, Scene, Inspector, Log Viewer. + +## Menu Bar + +### Game + +- Quit: request a clean shutdown. + +### Scene + +- New: clear the current scene. +- Load: load a scene from a TOML-like file path. +- Save As: save the current scene to a file path. + +### View + +- Toggle Log Viewer, Scene, and Inspector panels. + +## Game Window + +- Renders the current scene view. +- Resizes with the available docked panel space. + +## Scene Panel + +- Displays the entity hierarchy as a tree. +- Drag and drop entities to re-parent. +- Drop on the bottom target to clear parent. +- Create Entity and Delete Selected controls. + +## Inspector Panel + +- Shows components for the selected entity. +- Add Component dropdown lists only components not yet on the entity. +- Remove buttons appear on removable components. + +### Components + +- Tag: rename the entity. +- Transform: position, scale, rotation (degrees in UI). +- Velocity: linear and angular velocity. +- Sprite: model id, shader id, color, outline. +- Camera: position, target, up, FOV, projection, helper actions. +- Light: direction, color, intensity, helper presets. +- Material: material id. +- Render Pass: order, depth flags, shader id. +- World Transform: read-only computed transform. + +## Log Viewer + +- Shows engine log output in real time. + +## Shortcuts + +- Ctrl+Q: Quit +- Ctrl+L: Toggle Log Viewer +- Ctrl+N: New Scene +- Ctrl+O: Load Scene +- Ctrl+S: Save Scene + +## Notes + +- Scene Save and Load use file path text fields. +- Component IDs are numeric and map to runtime resource managers. +- World Transform is computed from hierarchy and local transforms and is read-only. diff --git a/docs/Home.md b/docs/Home.md index 0b27670..a6d6189 100644 --- a/docs/Home.md +++ b/docs/Home.md @@ -7,5 +7,5 @@ Edit markdown files here and push to the repository; CI will mirror them to the - [Scripting](Scripting.md) — scripting API and examples - [Usage](Usage.md) — getting started and build instructions - [Scenegraph](Scenegraph.md) — hierarchy components and scene format - +- [Editor](Editor.md) - how to use the editor diff --git a/imgui.ini b/imgui.ini index afcbfa3..8d1eaf3 100644 --- a/imgui.ini +++ b/imgui.ini @@ -1,6 +1,6 @@ [Window][DockSpaceHost] Pos=0,0 -Size=1920,991 +Size=1280,720 Collapsed=0 [Window][Debug##Default] @@ -10,19 +10,19 @@ Collapsed=0 [Window][Game Window] Pos=324,28 -Size=1285,851 +Size=645,580 Collapsed=0 DockId=0x00000001,0 [Window][Log Viewer] -Pos=324,881 -Size=1285,102 +Pos=324,610 +Size=645,102 Collapsed=0 DockId=0x00000002,0 [Window][##TOAST0] -Pos=1700,908 -Size=200,63 +Pos=1035,637 +Size=225,63 Collapsed=0 [Window][##TOAST1] @@ -76,19 +76,34 @@ Size=189,63 Collapsed=0 [Window][Inspector] -Pos=1611,28 -Size=301,955 +Pos=971,28 +Size=301,684 Collapsed=0 DockId=0x00000006,0 [Window][Scene] Pos=8,28 -Size=314,955 +Size=314,684 Collapsed=0 DockId=0x00000003,0 +[Window][New Scene] +Pos=512,318 +Size=255,84 +Collapsed=0 + +[Window][Save Scene] +Pos=807,454 +Size=306,82 +Collapsed=0 + +[Window][Load Scene] +Pos=807,454 +Size=306,82 +Collapsed=0 + [Docking][Data] -DockSpace ID=0x9076BACA Window=0x34F970D7 Pos=8,28 Size=1904,955 Split=X Selected=0x27A02DAA +DockSpace ID=0x9076BACA Window=0x34F970D7 Pos=8,28 Size=1264,684 Split=X Selected=0x27A02DAA DockNode ID=0x00000005 Parent=0x9076BACA SizeRef=961,684 Split=X DockNode ID=0x00000003 Parent=0x00000005 SizeRef=314,684 Selected=0xE601B12F DockNode ID=0x00000004 Parent=0x00000005 SizeRef=645,684 Split=Y diff --git a/include/ModelManager.h b/include/ModelManager.h index 834402b..759cc5c 100644 --- a/include/ModelManager.h +++ b/include/ModelManager.h @@ -4,6 +4,23 @@ #include #include +enum class ModelSourceType { + None, + Path, + Cube, + Sphere, + Plane +}; + +struct ModelSource { + ModelSourceType type = ModelSourceType::None; + std::string path; + Vector3 size{1.0f, 1.0f, 1.0f}; + float radius = 0.5f; + int rings = 16; + int slices = 16; +}; + class ModelManager { public: @@ -18,17 +35,30 @@ public: // Returns a unique ID for the model, or 0 on failure unsigned int LoadFromMesh(Mesh mesh); + // Load a model from a generated cube mesh + unsigned int LoadCube(float width, float height, float length); + + // Load a model from a generated sphere mesh + unsigned int LoadSphere(float radius, int rings, int slices); + + // Load a model from a generated plane mesh + unsigned int LoadPlane(float width, float length, int resX, int resZ); + // Unload a model by ID void Unload(unsigned int id); // Get a model by ID (returns nullptr if not found) Model* Get(unsigned int id); + // Get source metadata for a model if available + const ModelSource* GetSource(unsigned int id) const; + // Unload all models void UnloadAll(); private: std::unordered_map models; + std::unordered_map modelSources; unsigned int nextId; bool unloaded; }; diff --git a/include/ShaderManager.h b/include/ShaderManager.h index 860aedf..991b40e 100644 --- a/include/ShaderManager.h +++ b/include/ShaderManager.h @@ -4,6 +4,11 @@ #include #include +struct ShaderSource { + std::string vsPath; + std::string fsPath; +}; + class ShaderManager { public: @@ -20,11 +25,15 @@ public: // Get a shader by ID (returns nullptr if not found) Shader* Get(unsigned int id); + // Get source metadata for a shader if available + const ShaderSource* GetSource(unsigned int id) const; + // Unload all shaders void UnloadAll(); private: std::unordered_map shaders; + std::unordered_map shaderSources; unsigned int nextId; bool unloaded; }; diff --git a/include/gui/GuiManager.h b/include/gui/GuiManager.h index b758bf3..ed5fde5 100644 --- a/include/gui/GuiManager.h +++ b/include/gui/GuiManager.h @@ -45,4 +45,5 @@ private: bool requestSceneSave = false; char sceneLoadPath[260] = {0}; char sceneSavePath[260] = {0}; + int addComponentIndex = 0; }; \ No newline at end of file diff --git a/scenes/demo.toml b/scenes/demo.toml index 0d717a5..19a17e8 100644 --- a/scenes/demo.toml +++ b/scenes/demo.toml @@ -1,36 +1,45 @@ -# Simian demo scene with hierarchy - [[entity]] -id = "root" +id = "entity_1" tag = "Root" -position = [0.0, 0.0, 0.0] -rotation_deg = 0.0 -scale = [1.0, 1.0, 1.0] +position = [0.000, 0.000, 0.000] +scale = [1.000, 1.000, 1.000] +rotation_deg = 0.000 [[entity]] -id = "parent" +id = "entity_2" +parent = "entity_1" tag = "Parent" -parent = "root" -position = [2.0, 0.0, 0.0] -rotation_deg = 0.0 -scale = [1.0, 1.0, 1.0] +position = [2.000, 0.000, 0.000] +scale = [1.000, 1.000, 1.000] +rotation_deg = 0.000 model = "cube" -model_size = [1.0, 1.0, 1.0] +model_size = [1.000, 1.000, 1.000] color = 0x00FF00FF +outline_size = 0.000 shader_vs = "shaders/toon.vs" shader_fs = "shaders/toon.fs" [[entity]] -id = "child" +id = "entity_3" +parent = "entity_2" tag = "Child" -parent = "parent" -position = [0.0, 1.25, 0.0] -rotation_deg = 0.0 -scale = [0.6, 0.6, 0.6] +position = [0.000, 1.250, 0.000] +scale = [0.600, 0.600, 0.600] +rotation_deg = 0.000 model = "sphere" -radius = 0.5 +radius = 0.500 rings = 16 slices = 16 -color = 0xFFFF00FF +color = 0xFF0000FF +outline_size = 0.000 shader_vs = "shaders/toon.vs" shader_fs = "shaders/toon.fs" + +[[entity]] +id = "entity_4" +tag = "MainCamera" + +[[entity]] +id = "entity_5" +tag = "MainLight" + diff --git a/scenes/demo2.toml b/scenes/demo2.toml new file mode 100644 index 0000000..e0c4282 --- /dev/null +++ b/scenes/demo2.toml @@ -0,0 +1,43 @@ +[[entity]] +id = "entity_1048576" +tag = "Camera" +position = [0.000, 0.000, 0.000] +scale = [1.000, 1.000, 1.000] +rotation_deg = 0.000 + +[[entity]] +id = "entity_1048578" +tag = "Root" +position = [0.000, 0.000, 0.000] +scale = [1.000, 1.000, 1.000] +rotation_deg = 0.000 + +[[entity]] +id = "entity_1048579" +tag = "Parent" +position = [0.000, 0.000, 0.000] +scale = [1.000, 1.000, 1.000] +rotation_deg = 0.000 +model_id = 1 +color = 0xFFFFFFFF +outline_size = 0.000 + +[[entity]] +id = "entity_1048580" +parent = "entity_1048579" +tag = "Child" +position = [0.000, 1.400, 0.000] +scale = [1.000, 1.000, 1.000] +rotation_deg = 0.000 +model_id = 2 +color = 0xC11E1EFF +outline_size = 0.000 +shader_id = 1 + +[[entity]] +id = "entity_1048581" +tag = "Light" +position = [0.000, 0.000, 0.000] +scale = [1.000, 1.000, 1.000] +rotation_deg = 0.000 + diff --git a/scripts/update.as b/scripts/update.as deleted file mode 100644 index b96e620..0000000 --- a/scripts/update.as +++ /dev/null @@ -1,35 +0,0 @@ -float x = 50; -float y = 100; -float r = 40.0f; -float theta = 0.0f; -float ix = 0.0f; -float iy = 0.0f; -Texture::Image img; -Texture::Texture2D tex; - -void Init() { - Log(LOG_TRACE, "Initialization complete!"); - Toast::Success("Script initialized successfully!"); - img = Texture::LoadImage("assets/raylib_96x96.png"); - Toast::Info("Image loaded successfully."); - tex = Texture::LoadTexture("assets/raylib_96x96.png"); - Toast::Info("Texture loaded successfully."); -} - -void Shutdown() { - Texture::Unload(img); - Texture::Unload(tex); - Log(LOG_TRACE, "Shutdown complete!"); -} - -void Update(float dt) { - x += 64 * dt; - theta += 2.0f * dt; - ix = 100+ r * Math::Cos(theta); - iy = 100+r * Math::Sin(theta); - if (x > 800) { - Log(LOG_TRACE, format("Reset happened at position {}", x)); - x = 0; - Toast::Info(format("X position has been reset to {}", x)); - } -} diff --git a/src/ModelManager.cpp b/src/ModelManager.cpp index 31225d8..fd329a1 100644 --- a/src/ModelManager.cpp +++ b/src/ModelManager.cpp @@ -13,6 +13,7 @@ ModelManager::~ModelManager() UnloadModel(pair.second); } models.clear(); + modelSources.clear(); } } @@ -28,6 +29,10 @@ unsigned int ModelManager::Load(const std::string& path) unsigned int id = nextId++; models[id] = model; + ModelSource source; + source.type = ModelSourceType::Path; + source.path = path; + modelSources[id] = source; log_info("Loaded model id=%u from %s", id, path.c_str()); return id; @@ -44,6 +49,49 @@ unsigned int ModelManager::LoadFromMesh(Mesh mesh) return id; } +unsigned int ModelManager::LoadCube(float width, float height, float length) +{ + Mesh mesh = GenMeshCube(width, height, length); + unsigned int id = LoadFromMesh(mesh); + if (id != 0) { + ModelSource source; + source.type = ModelSourceType::Cube; + source.size = {width, height, length}; + modelSources[id] = source; + } + return id; +} + +unsigned int ModelManager::LoadSphere(float radius, int rings, int slices) +{ + Mesh mesh = GenMeshSphere(radius, rings, slices); + unsigned int id = LoadFromMesh(mesh); + if (id != 0) { + ModelSource source; + source.type = ModelSourceType::Sphere; + source.radius = radius; + source.rings = rings; + source.slices = slices; + modelSources[id] = source; + } + return id; +} + +unsigned int ModelManager::LoadPlane(float width, float length, int resX, int resZ) +{ + Mesh mesh = GenMeshPlane(width, length, resX, resZ); + unsigned int id = LoadFromMesh(mesh); + if (id != 0) { + ModelSource source; + source.type = ModelSourceType::Plane; + source.size = {width, 1.0f, length}; + source.rings = resX; + source.slices = resZ; + modelSources[id] = source; + } + return id; +} + void ModelManager::Unload(unsigned int id) { auto it = models.find(id); @@ -51,6 +99,7 @@ void ModelManager::Unload(unsigned int id) { UnloadModel(it->second); models.erase(it); + modelSources.erase(id); log_info("Unloaded model id=%u", id); } } @@ -65,6 +114,16 @@ Model* ModelManager::Get(unsigned int id) return nullptr; } +const ModelSource* ModelManager::GetSource(unsigned int id) const +{ + auto it = modelSources.find(id); + if (it != modelSources.end()) + { + return &it->second; + } + return nullptr; +} + void ModelManager::UnloadAll() { if (!unloaded) { @@ -73,6 +132,7 @@ void ModelManager::UnloadAll() UnloadModel(pair.second); } models.clear(); + modelSources.clear(); unloaded = true; log_info("Unloaded all models"); } diff --git a/src/SceneLoader.cpp b/src/SceneLoader.cpp index d5c6b91..3e157c2 100644 --- a/src/SceneLoader.cpp +++ b/src/SceneLoader.cpp @@ -185,14 +185,11 @@ static unsigned int LoadModelFor(const SceneEntityDef& def, std::unordered_mapLoadFromMesh(mesh); + modelId = g_sceneModelManager->LoadCube(def.modelSize.x, def.modelSize.y, def.modelSize.z); } else if (def.model == "sphere") { - Mesh mesh = GenMeshSphere(def.radius, def.rings, def.slices); - modelId = g_sceneModelManager->LoadFromMesh(mesh); + modelId = g_sceneModelManager->LoadSphere(def.radius, def.rings, def.slices); } else if (def.model == "plane") { - Mesh mesh = GenMeshPlane(def.modelSize.x, def.modelSize.z, def.rings, def.slices); - modelId = g_sceneModelManager->LoadFromMesh(mesh); + modelId = g_sceneModelManager->LoadPlane(def.modelSize.x, def.modelSize.z, def.rings, def.slices); } else { modelId = g_sceneModelManager->Load(def.model); } @@ -351,11 +348,12 @@ entt::entity LoadSceneFromFile(const std::string& path, bool clearExisting) { if (def.hasSprite) { unsigned int modelId = 0; - if (def.hasModelId) { - modelId = def.modelId; - } else if (!def.model.empty()) { + if (!def.model.empty()) { modelId = LoadModelFor(def, modelCache); } + if (modelId == 0 && def.hasModelId) { + modelId = def.modelId; + } Color col = { static_cast((def.color >> 24) & 0xFF), static_cast((def.color >> 16) & 0xFF), @@ -363,11 +361,12 @@ entt::entity LoadSceneFromFile(const std::string& path, bool clearExisting) { static_cast(def.color & 0xFF) }; unsigned int shaderId = 0; - if (def.hasShaderId) { - shaderId = def.shaderId; - } else if (!def.shaderVs.empty() && !def.shaderFs.empty()) { + if (!def.shaderVs.empty() && !def.shaderFs.empty()) { shaderId = LoadShaderFor(def, shaderCache); } + if (shaderId == 0 && def.hasShaderId) { + shaderId = def.shaderId; + } g_sceneRegistry->emplace(entity, static_cast(modelId), col, def.outlineSize, shaderId); } } @@ -461,12 +460,58 @@ bool SaveSceneToFile(const std::string& path) { } if (auto* sprite = registry.try_get(entity)) { - if (sprite->modelId > 0) { + bool wroteModel = false; + if (g_sceneModelManager && sprite->modelId > 0) { + const ModelSource* source = g_sceneModelManager->GetSource(static_cast(sprite->modelId)); + if (source) { + switch (source->type) { + case ModelSourceType::Path: + if (!source->path.empty()) { + file << "model = \"" << EscapeString(source->path) << "\"\n"; + wroteModel = true; + } + break; + case ModelSourceType::Cube: + file << "model = \"cube\"\n"; + file << "model_size = " << Vec3ToString(source->size) << "\n"; + wroteModel = true; + break; + case ModelSourceType::Sphere: + file << "model = \"sphere\"\n"; + file << "radius = " << FloatToString(source->radius) << "\n"; + file << "rings = " << source->rings << "\n"; + file << "slices = " << source->slices << "\n"; + wroteModel = true; + break; + case ModelSourceType::Plane: + file << "model = \"plane\"\n"; + file << "model_size = " << Vec3ToString(source->size) << "\n"; + file << "rings = " << source->rings << "\n"; + file << "slices = " << source->slices << "\n"; + wroteModel = true; + break; + case ModelSourceType::None: + default: + break; + } + } + } + + if (!wroteModel && sprite->modelId > 0) { file << "model_id = " << sprite->modelId << "\n"; } file << "color = " << ColorToHexString(sprite->color) << "\n"; file << "outline_size = " << FloatToString(sprite->outlineSize) << "\n"; - if (sprite->shaderId > 0) { + bool wroteShader = false; + if (g_sceneShaderManager && sprite->shaderId > 0) { + const ShaderSource* source = g_sceneShaderManager->GetSource(sprite->shaderId); + if (source && !source->vsPath.empty() && !source->fsPath.empty()) { + file << "shader_vs = \"" << EscapeString(source->vsPath) << "\"\n"; + file << "shader_fs = \"" << EscapeString(source->fsPath) << "\"\n"; + wroteShader = true; + } + } + if (!wroteShader && sprite->shaderId > 0) { file << "shader_id = " << sprite->shaderId << "\n"; } } diff --git a/src/ShaderManager.cpp b/src/ShaderManager.cpp index f8325fa..30a5c95 100644 --- a/src/ShaderManager.cpp +++ b/src/ShaderManager.cpp @@ -13,6 +13,7 @@ ShaderManager::~ShaderManager() UnloadShader(pair.second); } shaders.clear(); + shaderSources.clear(); } } @@ -28,6 +29,7 @@ unsigned int ShaderManager::Load(const std::string& vsPath, const std::string& f unsigned int id = nextId++; shaders[id] = shader; + shaderSources[id] = ShaderSource{vsPath, fsPath}; log_info("Loaded shader id=%u from %s / %s (raylib id=%u)", id, vsPath.c_str(), fsPath.c_str(), shader.id); return id; @@ -40,6 +42,7 @@ void ShaderManager::Unload(unsigned int id) { UnloadShader(it->second); shaders.erase(it); + shaderSources.erase(id); log_info("Unloaded shader id=%u", id); } } @@ -54,6 +57,16 @@ Shader* ShaderManager::Get(unsigned int id) return nullptr; } +const ShaderSource* ShaderManager::GetSource(unsigned int id) const +{ + auto it = shaderSources.find(id); + if (it != shaderSources.end()) + { + return &it->second; + } + return nullptr; +} + void ShaderManager::UnloadAll() { if (!unloaded) { @@ -62,6 +75,7 @@ void ShaderManager::UnloadAll() UnloadShader(pair.second); } shaders.clear(); + shaderSources.clear(); unloaded = true; log_info("Unloaded all shaders"); } diff --git a/src/gui/GuiManager.cpp b/src/gui/GuiManager.cpp index 249ee05..8d0d561 100644 --- a/src/gui/GuiManager.cpp +++ b/src/gui/GuiManager.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include "log.h" @@ -331,6 +332,7 @@ void GuiManager::RenderEntityNode(entt::entity entity) { if (!app) return; auto& registry = app->GetRegistry(); + if (!registry.valid(entity)) return; auto* hierarchy = registry.try_get(entity); bool hasChildren = hierarchy && hierarchy->first != entt::null; @@ -369,6 +371,9 @@ void GuiManager::RenderEntityNode(entt::entity entity) if (opened && hasChildren) { entt::entity child = hierarchy->first; while (child != entt::null) { + if (!registry.valid(child)) { + break; + } RenderEntityNode(child); auto* childHierarchy = registry.try_get(child); child = childHierarchy ? childHierarchy->next : entt::null; @@ -421,6 +426,9 @@ void GuiManager::RenderSceneWindow() std::vector roots; auto &storage = registry.storage(); for (auto entity : storage) { + if (!registry.valid(entity)) { + continue; + } auto* hierarchy = registry.try_get(entity); if (!hierarchy || hierarchy->parent == entt::null || !registry.valid(hierarchy->parent)) { roots.push_back(entity); @@ -471,6 +479,112 @@ void GuiManager::RenderInspectorWindow() ImGui::Text("%s", GetEntityLabel(selectedEntity)); ImGui::Separator(); + struct ComponentOption { + const char* label; + int id; + }; + + const ComponentOption allOptions[] = { + {"Tag", 0}, + {"Transform", 1}, + {"Velocity", 2}, + {"Sprite", 3}, + {"Camera", 4}, + {"Light", 5}, + {"Material", 6}, + {"Render Pass", 7} + }; + + auto hasComponent = [&](int id) { + switch (id) { + case 0: return registry.any_of(selectedEntity); + case 1: return registry.any_of(selectedEntity); + case 2: return registry.any_of(selectedEntity); + case 3: return registry.any_of(selectedEntity); + case 4: return registry.any_of(selectedEntity); + case 5: return registry.any_of(selectedEntity); + case 6: return registry.any_of(selectedEntity); + case 7: return registry.any_of(selectedEntity); + default: return false; + } + }; + + std::vector availableLabels; + std::vector availableIds; + availableLabels.reserve(sizeof(allOptions) / sizeof(allOptions[0])); + availableIds.reserve(sizeof(allOptions) / sizeof(allOptions[0])); + + for (const auto& option : allOptions) { + if (!hasComponent(option.id)) { + availableLabels.push_back(option.label); + availableIds.push_back(option.id); + } + } + + ImGui::Text("Add Component"); + ImGui::SameLine(); + ImGui::SetNextItemWidth(180.0f); + + if (availableLabels.empty()) { + ImGui::TextDisabled("All added"); + } else { + if (addComponentIndex < 0 || addComponentIndex >= static_cast(availableLabels.size())) { + addComponentIndex = 0; + } + ImGui::Combo("##AddComponentCombo", &addComponentIndex, availableLabels.data(), static_cast(availableLabels.size())); + } + + bool canAddComponent = !availableIds.empty(); + + if (!canAddComponent) { + ImGui::BeginDisabled(); + } + if (ImGui::Button("Add")) { + int selectedId = canAddComponent ? availableIds[addComponentIndex] : -1; + switch (selectedId) { + case 0: { + registry.emplace(selectedEntity, "Entity"); + SyncTagBuffer(selectedEntity); + break; + } + case 1: + registry.emplace(selectedEntity, Vector3{0.0f, 0.0f, 0.0f}, Vector3{1.0f, 1.0f, 1.0f}, 0.0f); + break; + case 2: + registry.emplace(selectedEntity, Vector3{0.0f, 0.0f, 0.0f}, 0.0f); + break; + case 3: + registry.emplace(selectedEntity, 0, WHITE, 0.0f, 0); + break; + case 4: + registry.emplace(selectedEntity); + break; + case 5: + registry.emplace(selectedEntity); + break; + case 6: + registry.emplace(selectedEntity); + break; + case 7: + registry.emplace(selectedEntity); + break; + default: + break; + } + } + if (!canAddComponent) { + ImGui::EndDisabled(); + } + ImGui::Separator(); + + auto normalizeVector = [](Vector3 value, Vector3 fallback = Vector3{0.0f, 1.0f, 0.0f}) { + float length = std::sqrt(value.x * value.x + value.y * value.y + value.z * value.z); + if (length <= 0.0001f) { + return fallback; + } + return Vector3{value.x / length, value.y / length, value.z / length}; + }; + // Tag if (registry.any_of(selectedEntity)) { SyncTagBuffer(selectedEntity); @@ -478,15 +592,11 @@ void GuiManager::RenderInspectorWindow() auto& tag = registry.get(selectedEntity); tag.name = tagBuffer; } - } else { - if (ImGui::Button("Add Tag")) { - registry.emplace(selectedEntity, "Entity"); - SyncTagBuffer(selectedEntity); - } } // Transform if (registry.any_of(selectedEntity)) { + ImGui::PushID("Transform"); auto& transform = registry.get(selectedEntity); float position[3] = {transform.position.x, transform.position.y, transform.position.z}; float scale[3] = {transform.scale.x, transform.scale.y, transform.scale.z}; @@ -501,9 +611,27 @@ void GuiManager::RenderInspectorWindow() if (ImGui::DragFloat("Rotation (deg)", &rotationDeg, 0.5f)) { transform.rotation = rotationDeg * DEG2RAD; } - } else { - if (ImGui::Button("Add Transform")) { - registry.emplace(selectedEntity, Vector3{0.0f, 0.0f, 0.0f}, Vector3{1.0f, 1.0f, 1.0f}, 0.0f); + ImGui::PopID(); + } + + // Velocity + if (registry.any_of(selectedEntity)) { + auto& velocity = registry.get(selectedEntity); + ImGui::Separator(); + ImGui::Text("Velocity"); + + float linear[3] = {velocity.linear.x, velocity.linear.y, velocity.linear.z}; + if (ImGui::DragFloat3("Linear", linear, 0.1f)) { + velocity.linear = {linear[0], linear[1], linear[2]}; + } + + float angular = velocity.angular; + if (ImGui::DragFloat("Angular (rad/s)", &angular, 0.05f)) { + velocity.angular = angular; + } + + if (ImGui::Button("Remove Velocity")) { + registry.remove(selectedEntity); } } @@ -521,6 +649,23 @@ void GuiManager::RenderInspectorWindow() } } + // World Transform (computed) + if (auto* world = registry.try_get(selectedEntity)) { + ImGui::Separator(); + ImGui::Text("World Transform (computed)"); + ImGui::BeginDisabled(); + + float worldPos[3] = {world->position.x, world->position.y, world->position.z}; + float worldScale[3] = {world->scale.x, world->scale.y, world->scale.z}; + float worldRotDeg = world->rotation * RAD2DEG; + + ImGui::DragFloat3("World Position", worldPos, 0.1f); + ImGui::DragFloat3("World Scale", worldScale, 0.05f); + ImGui::DragFloat("World Rotation (deg)", &worldRotDeg, 0.5f); + + ImGui::EndDisabled(); + } + // Sprite if (registry.any_of(selectedEntity)) { auto& sprite = registry.get(selectedEntity); @@ -555,9 +700,144 @@ void GuiManager::RenderInspectorWindow() if (ImGui::Button("Remove Sprite")) { registry.remove(selectedEntity); } - } else { - if (ImGui::Button("Add Sprite")) { - registry.emplace(selectedEntity, 0, WHITE, 0.0f, 0); + } + + // Camera + if (registry.any_of(selectedEntity)) { + ImGui::PushID("Camera"); + auto& camera = registry.get(selectedEntity); + ImGui::Separator(); + ImGui::Text("Camera"); + + float camPos[3] = {camera.position.x, camera.position.y, camera.position.z}; + float camTarget[3] = {camera.target.x, camera.target.y, camera.target.z}; + float camUp[3] = {camera.up.x, camera.up.y, camera.up.z}; + + if (ImGui::DragFloat3("Position", camPos, 0.1f)) { + camera.position = {camPos[0], camPos[1], camPos[2]}; + } + if (ImGui::DragFloat3("Target", camTarget, 0.1f)) { + camera.target = {camTarget[0], camTarget[1], camTarget[2]}; + } + if (ImGui::DragFloat3("Up", camUp, 0.05f)) { + camera.up = {camUp[0], camUp[1], camUp[2]}; + } + + float fovy = camera.fovy; + if (ImGui::SliderFloat("FOV", &fovy, 1.0f, 179.0f)) { + camera.fovy = fovy; + } + + const char* projectionLabels[] = {"Perspective", "Orthographic"}; + int projectionIndex = (camera.projection == CAMERA_ORTHOGRAPHIC) ? 1 : 0; + if (ImGui::Combo("Projection", &projectionIndex, projectionLabels, 2)) { + camera.projection = (projectionIndex == 1) ? CAMERA_ORTHOGRAPHIC : CAMERA_PERSPECTIVE; + } + + if (ImGui::Button("Look At Origin")) { + camera.target = {0.0f, 0.0f, 0.0f}; + } + ImGui::SameLine(); + if (ImGui::Button("Normalize Up")) { + camera.up = normalizeVector(camera.up, Vector3{0.0f, 1.0f, 0.0f}); + } + ImGui::SameLine(); + if (ImGui::Button("Reset Camera")) { + camera = Camera3DComponent(); + } + + if (ImGui::Button("Remove Camera")) { + registry.remove(selectedEntity); + } + ImGui::PopID(); + } + + // Light + if (registry.any_of(selectedEntity)) { + auto& light = registry.get(selectedEntity); + ImGui::Separator(); + ImGui::Text("Light"); + + float lightDir[3] = {light.direction.x, light.direction.y, light.direction.z}; + if (ImGui::DragFloat3("Direction", lightDir, 0.05f)) { + light.direction = {lightDir[0], lightDir[1], lightDir[2]}; + } + + if (ImGui::Button("Normalize Dir")) { + light.direction = normalizeVector(light.direction, Vector3{0.5f, 0.7f, 0.3f}); + } + ImGui::SameLine(); + if (ImGui::Button("Top")) { + light.direction = {0.0f, 1.0f, 0.0f}; + } + ImGui::SameLine(); + if (ImGui::Button("Angled")) { + light.direction = {0.5f, 0.7f, 0.3f}; + } + ImGui::SameLine(); + if (ImGui::Button("Side")) { + light.direction = {1.0f, 0.0f, 0.0f}; + } + + float lightColor[4] = { + light.color.r / 255.0f, + light.color.g / 255.0f, + light.color.b / 255.0f, + light.color.a / 255.0f + }; + if (ImGui::ColorEdit4("Light Color", lightColor)) { + light.color.r = static_cast(lightColor[0] * 255.0f); + light.color.g = static_cast(lightColor[1] * 255.0f); + light.color.b = static_cast(lightColor[2] * 255.0f); + light.color.a = static_cast(lightColor[3] * 255.0f); + } + + float intensity = light.intensity; + if (ImGui::SliderFloat("Intensity", &intensity, 0.0f, 10.0f)) { + light.intensity = intensity; + } + + if (ImGui::Button("Remove Light")) { + registry.remove(selectedEntity); + } + } + + // Material + if (registry.any_of(selectedEntity)) { + auto& material = registry.get(selectedEntity); + ImGui::Separator(); + ImGui::Text("Material"); + + int materialId = static_cast(material.materialId); + if (ImGui::InputInt("Material Id", &materialId)) { + material.materialId = materialId < 0 ? 0u : static_cast(materialId); + } + + if (ImGui::Button("Remove Material")) { + registry.remove(selectedEntity); + } + } + + // Render Pass + if (registry.any_of(selectedEntity)) { + auto& pass = registry.get(selectedEntity); + ImGui::Separator(); + ImGui::Text("Render Pass"); + + int order = pass.order; + if (ImGui::InputInt("Order", &order)) { + pass.order = order; + } + ImGui::Checkbox("Depth Test", &pass.depthTest); + ImGui::Checkbox("Depth Write", &pass.depthWrite); + + int shaderId = static_cast(pass.shaderId); + if (ImGui::InputInt("Pass Shader Id", &shaderId)) { + pass.shaderId = shaderId < 0 ? 0u : static_cast(shaderId); + } + + if (ImGui::Button("Remove Render Pass")) { + registry.remove(selectedEntity); } } @@ -635,9 +915,9 @@ void GuiManager::SetTheme() colors[ImGuiCol_CheckMark] = ImVec4(0.33f, 0.67f, 0.86f, 1.00f); colors[ImGuiCol_SliderGrab] = ImVec4(0.34f, 0.34f, 0.34f, 0.54f); colors[ImGuiCol_SliderGrabActive] = ImVec4(0.56f, 0.56f, 0.56f, 0.54f); - colors[ImGuiCol_Button] = ImVec4(0.12f, 0.38f, 0.70f, 0.90f); - colors[ImGuiCol_ButtonHovered] = ImVec4(0.16f, 0.50f, 0.88f, 1.00f); - colors[ImGuiCol_ButtonActive] = ImVec4(0.10f, 0.32f, 0.60f, 1.00f); + colors[ImGuiCol_Button] = ImVec4(0.10f, 0.58f, 0.30f, 0.90f); + colors[ImGuiCol_ButtonHovered] = ImVec4(0.12f, 0.70f, 0.36f, 1.00f); + colors[ImGuiCol_ButtonActive] = ImVec4(0.08f, 0.46f, 0.24f, 1.00f); colors[ImGuiCol_Header] = ImVec4(0.00f, 0.00f, 0.00f, 0.52f); colors[ImGuiCol_HeaderHovered] = ImVec4(0.00f, 0.00f, 0.00f, 0.36f); colors[ImGuiCol_HeaderActive] = ImVec4(0.20f, 0.22f, 0.23f, 0.33f); diff --git a/src/scripting/ResourceBindings.cpp b/src/scripting/ResourceBindings.cpp index debcf07..623a187 100644 --- a/src/scripting/ResourceBindings.cpp +++ b/src/scripting/ResourceBindings.cpp @@ -38,20 +38,17 @@ unsigned int AS_LoadModel(const std::string& path) { unsigned int AS_LoadModelCube(float width, float height, float length) { if (!g_modelManager) return 0; - Mesh mesh = GenMeshCube(width, height, length); - return g_modelManager->LoadFromMesh(mesh); + return g_modelManager->LoadCube(width, height, length); } unsigned int AS_LoadModelSphere(float radius, int rings, int slices) { if (!g_modelManager) return 0; - Mesh mesh = GenMeshSphere(radius, rings, slices); - return g_modelManager->LoadFromMesh(mesh); + return g_modelManager->LoadSphere(radius, rings, slices); } unsigned int AS_LoadModelPlane(float width, float length, int resX, int resZ) { if (!g_modelManager) return 0; - Mesh mesh = GenMeshPlane(width, length, resX, resZ); - return g_modelManager->LoadFromMesh(mesh); + return g_modelManager->LoadPlane(width, length, resX, resZ); } void AS_UnloadModel(unsigned int id) { From 0baabd689f02e4f0ed8127a6239729f4e573ed7a Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Sun, 8 Mar 2026 20:29:45 +1300 Subject: [PATCH 38/53] chore: more docs attempts --- .gitea/workflows/sync-docs-to-wiki.yml | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/.gitea/workflows/sync-docs-to-wiki.yml b/.gitea/workflows/sync-docs-to-wiki.yml index 444d84b..4d05cdf 100644 --- a/.gitea/workflows/sync-docs-to-wiki.yml +++ b/.gitea/workflows/sync-docs-to-wiki.yml @@ -33,17 +33,12 @@ jobs: git config --global user.name "Simian CI" git config --global user.email "ci@simian.local" - # Clean slate: remove any existing wiki/ dir rm -rf wiki - - # Fresh clone of simian.wiki.git git clone "$WIKI_REPO" wiki - - # Overwrite contents with docs/ rsync -av --delete docs/ wiki/ cd wiki - # Ensure main branch (create if empty) + git remote set-url origin "$WIKI_REPO" # Force wiki remote git checkout main 2>/dev/null || git checkout -b main git add -A if git diff --staged --quiet; then @@ -51,4 +46,4 @@ jobs: else git commit -m "Update wiki from docs (CI) [skip ci]" git push origin main - fi + fi \ No newline at end of file From ae21d4a5d27059779a89cf0acfe99072d7d4014c Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Sun, 8 Mar 2026 20:32:14 +1300 Subject: [PATCH 39/53] chore: docs update --- docs/Editor.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Editor.md b/docs/Editor.md index 5841ce9..a8c8d6a 100644 --- a/docs/Editor.md +++ b/docs/Editor.md @@ -10,6 +10,7 @@ This document outlines the in-app editor UI, its panels, and common workflows. ## Layout - DockSpace host with a top menu bar. +- You can drag and drop to move panels around. - Panels: Game Window, Scene, Inspector, Log Viewer. ## Menu Bar From 7a3810805e4e46572eda9a8dd7c6035ee6bf5bf9 Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Sun, 8 Mar 2026 20:47:09 +1300 Subject: [PATCH 40/53] fix: issue with duplicating entities when created by the script --- .gitea/workflows/sync-docs-to-wiki.yml | 24 +++++++++++++-------- docs/Home.md | 2 +- include/ECSComponents.h | 6 ++++++ scenes/demo.toml | 20 ++++++++++++------ src/SceneLoader.cpp | 29 ++++++++++++++++++++------ src/gui/GuiManager.cpp | 3 +++ 6 files changed, 62 insertions(+), 22 deletions(-) diff --git a/.gitea/workflows/sync-docs-to-wiki.yml b/.gitea/workflows/sync-docs-to-wiki.yml index 4d05cdf..3d78a9e 100644 --- a/.gitea/workflows/sync-docs-to-wiki.yml +++ b/.gitea/workflows/sync-docs-to-wiki.yml @@ -12,6 +12,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v4 + with: + fetch-depth: 0 # Full history - name: Start SSH agent uses: webfactory/ssh-agent@v0.9.0 @@ -33,17 +35,21 @@ jobs: git config --global user.name "Simian CI" git config --global user.email "ci@simian.local" - rm -rf wiki - git clone "$WIKI_REPO" wiki - rsync -av --delete docs/ wiki/ + # Clone wiki to TEMP dir (not workspace) + TEMP_WIKI=$(mktemp -d) + git clone "$WIKI_REPO" "$TEMP_WIKI" - cd wiki - git remote set-url origin "$WIKI_REPO" # Force wiki remote + # Copy docs into wiki clone + rsync -av --delete docs/ "$TEMP_WIKI/" + + cd "$TEMP_WIKI" git checkout main 2>/dev/null || git checkout -b main git add -A - if git diff --staged --quiet; then - echo "No wiki changes" - else + + if ! git diff --staged --quiet; then git commit -m "Update wiki from docs (CI) [skip ci]" git push origin main - fi \ No newline at end of file + echo "✅ Pushed to simian.wiki main" + else + echo "No wiki changes" + fi diff --git a/docs/Home.md b/docs/Home.md index a6d6189..04428eb 100644 --- a/docs/Home.md +++ b/docs/Home.md @@ -7,5 +7,5 @@ Edit markdown files here and push to the repository; CI will mirror them to the - [Scripting](Scripting.md) — scripting API and examples - [Usage](Usage.md) — getting started and build instructions - [Scenegraph](Scenegraph.md) — hierarchy components and scene format -- [Editor](Editor.md) - how to use the editor +- [Editor](Editor.md) - details on how to use the editor diff --git a/include/ECSComponents.h b/include/ECSComponents.h index 721f6da..ef7b56e 100644 --- a/include/ECSComponents.h +++ b/include/ECSComponents.h @@ -56,6 +56,12 @@ struct Tag { Tag(const std::string& n) : name(n) {} }; +// SceneEntity component - marks entities owned by the scene +struct SceneEntity { + bool persistent = false; + std::string id; +}; + // Hierarchy component - parent/child links using EnTT-friendly linked list struct Hierarchy { entt::entity parent{entt::null}; diff --git a/scenes/demo.toml b/scenes/demo.toml index 19a17e8..5dd1eea 100644 --- a/scenes/demo.toml +++ b/scenes/demo.toml @@ -36,10 +36,18 @@ shader_vs = "shaders/toon.vs" shader_fs = "shaders/toon.fs" [[entity]] -id = "entity_4" -tag = "MainCamera" - -[[entity]] -id = "entity_5" -tag = "MainLight" +id = "entity_6" +parent = "entity_2" +tag = "Child 2" +position = [0.000, 1.000, 1.900] +scale = [1.000, 1.000, 1.000] +rotation_deg = 0.000 +model = "sphere" +radius = 0.500 +rings = 16 +slices = 16 +color = 0x4523BAFF +outline_size = 0.000 +shader_vs = "shaders/toon.vs" +shader_fs = "shaders/toon.fs" diff --git a/src/SceneLoader.cpp b/src/SceneLoader.cpp index 3e157c2..d77ed53 100644 --- a/src/SceneLoader.cpp +++ b/src/SceneLoader.cpp @@ -332,6 +332,14 @@ entt::entity LoadSceneFromFile(const std::string& path, bool clearExisting) { entt::entity entity = g_sceneRegistry->create(); created.push_back(entity); + auto& sceneEntity = g_sceneRegistry->emplace(entity); + sceneEntity.persistent = true; + if (!def.id.empty()) { + sceneEntity.id = def.id; + } else { + sceneEntity.id = "entity_" + std::to_string(static_cast(entt::to_integral(entity))); + } + if (!def.id.empty()) { idMap[def.id] = entity; } @@ -413,9 +421,8 @@ bool SaveSceneToFile(const std::string& path) { continue; } - auto* tag = registry.try_get(entity); - auto* hierarchy = registry.try_get(entity); - if (tag && tag->name == "SceneRoot" && (!hierarchy || hierarchy->parent == entt::null)) { + auto* sceneEntity = registry.try_get(entity); + if (!sceneEntity || !sceneEntity->persistent) { continue; } @@ -429,9 +436,19 @@ bool SaveSceneToFile(const std::string& path) { std::unordered_map idMap; idMap.reserve(entities.size()); for (auto entity : entities) { - std::ostringstream ss; - ss << "entity_" << static_cast(entt::to_integral(entity)); - idMap[entity] = ss.str(); + auto* sceneEntity = registry.try_get(entity); + std::string idValue; + if (sceneEntity && !sceneEntity->id.empty()) { + idValue = sceneEntity->id; + } else { + std::ostringstream ss; + ss << "entity_" << static_cast(entt::to_integral(entity)); + idValue = ss.str(); + if (sceneEntity) { + sceneEntity->id = idValue; + } + } + idMap[entity] = idValue; } for (auto entity : entities) { diff --git a/src/gui/GuiManager.cpp b/src/gui/GuiManager.cpp index 8d0d561..7d99b92 100644 --- a/src/gui/GuiManager.cpp +++ b/src/gui/GuiManager.cpp @@ -400,6 +400,9 @@ void GuiManager::RenderSceneWindow() std::string name = "Entity " + std::to_string(static_cast(ToId(entity))); registry.emplace(entity, name); registry.emplace(entity, Vector3{0.0f, 0.0f, 0.0f}, Vector3{1.0f, 1.0f, 1.0f}, 0.0f); + auto& sceneEntity = registry.emplace(entity); + sceneEntity.persistent = true; + sceneEntity.id = "entity_" + std::to_string(static_cast(ToId(entity))); selectedEntity = entity; SyncTagBuffer(entity); } From d6f2cc1ea32427f480ffa4208e1cd30448846251 Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Sun, 8 Mar 2026 21:48:40 +1300 Subject: [PATCH 41/53] feat: example entity script --- .gitea/workflows/sync-docs-to-wiki.yml | 28 ++-- docs/Editor.md | 15 +++ imgui.ini | 4 +- include/Application.h | 20 +++ include/ECSComponents.h | 7 + include/SceneLoader.h | 5 + include/gui/GuiManager.h | 6 + include/scripting/ScriptEngine.h | 2 + scenes/demo.toml | 1 + scripts/ball.as | 104 +++++++++++++++ src/Application.cpp | 169 ++++++++++++++++++++++++- src/SceneLoader.cpp | 90 ++++++++++++- src/gui/GuiManager.cpp | 87 +++++++++++-- src/scripting/ScriptEngine.cpp | 85 ++++++++++++- 14 files changed, 588 insertions(+), 35 deletions(-) create mode 100644 scripts/ball.as diff --git a/.gitea/workflows/sync-docs-to-wiki.yml b/.gitea/workflows/sync-docs-to-wiki.yml index 3d78a9e..d1fdcdd 100644 --- a/.gitea/workflows/sync-docs-to-wiki.yml +++ b/.gitea/workflows/sync-docs-to-wiki.yml @@ -12,8 +12,6 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v4 - with: - fetch-depth: 0 # Full history - name: Start SSH agent uses: webfactory/ssh-agent@v0.9.0 @@ -29,27 +27,25 @@ jobs: env: WIKI_REPO: git@gitea.appstack.me:nick/simian.wiki.git run: | - sudo apt-get update -qq - sudo apt-get install -y rsync - git config --global user.name "Simian CI" git config --global user.email "ci@simian.local" - # Clone wiki to TEMP dir (not workspace) TEMP_WIKI=$(mktemp -d) git clone "$WIKI_REPO" "$TEMP_WIKI" - # Copy docs into wiki clone - rsync -av --delete docs/ "$TEMP_WIKI/" - cd "$TEMP_WIKI" - git checkout main 2>/dev/null || git checkout -b main - git add -A - if ! git diff --staged --quiet; then + # Git-safe clean: delete everything except .git + find . -mindepth 1 -maxdepth 1 ! -name '.git' -exec rm -rf {} + + + # Copy docs files + cp -r ../docs/* . 2>/dev/null || true + + git add -A + if git diff --staged --quiet; then + echo "No wiki changes" + else git commit -m "Update wiki from docs (CI) [skip ci]" git push origin main - echo "✅ Pushed to simian.wiki main" - else - echo "No wiki changes" - fi + echo "✅ Synced to simian.wiki main" + fi \ No newline at end of file diff --git a/docs/Editor.md b/docs/Editor.md index a8c8d6a..dde22b2 100644 --- a/docs/Editor.md +++ b/docs/Editor.md @@ -53,6 +53,7 @@ This document outlines the in-app editor UI, its panels, and common workflows. - Transform: position, scale, rotation (degrees in UI). - Velocity: linear and angular velocity. - Sprite: model id, shader id, color, outline. +- Script: per-entity script path and enabled toggle. - Camera: position, target, up, FOV, projection, helper actions. - Light: direction, color, intensity, helper presets. - Material: material id. @@ -76,3 +77,17 @@ This document outlines the in-app editor UI, its panels, and common workflows. - Scene Save and Load use file path text fields. - Component IDs are numeric and map to runtime resource managers. - World Transform is computed from hierarchy and local transforms and is read-only. + +## Scene Scripts + +- Scene scripts are loaded by the scene system and run once per scene. +- The editor lets you set a scene-level script path in the Scene panel. +- Preferred scene callbacks: `SceneInit()`, `SceneUpdate(float dt)`, `SceneShutdown()`. +- Legacy callbacks still work: `Init()`, `Update(float dt)`, `Shutdown()`. + +## ScriptComponent + +- ScriptComponent runs a per-entity script module. +- Set the script path in the Inspector and toggle enabled. +- Preferred callbacks: `EntityInit(uint entity)`, `EntityUpdate(uint entity, float dt)`, `EntityShutdown(uint entity)`. +- Legacy callbacks still work: `Init(uint entity)`, `Update(uint entity, float dt)`, `Shutdown(uint entity)`. diff --git a/imgui.ini b/imgui.ini index 8d1eaf3..6310b76 100644 --- a/imgui.ini +++ b/imgui.ini @@ -26,8 +26,8 @@ Size=225,63 Collapsed=0 [Window][##TOAST1] -Pos=1704,835 -Size=196,63 +Pos=1035,564 +Size=225,63 Collapsed=0 [Window][##TOAST2] diff --git a/include/Application.h b/include/Application.h index b726922..452831c 100644 --- a/include/Application.h +++ b/include/Application.h @@ -8,6 +8,8 @@ #include "MaterialManager.h" #include "InputManager.h" #include +#include +#include class Application { public: @@ -24,6 +26,16 @@ public: entt::registry& GetRegistry() { return registry; } private: + struct EntityScriptModule { + std::string path; + std::string moduleName; + asIScriptModule* module = nullptr; + asIScriptFunction* initFunc = nullptr; + asIScriptFunction* updateFunc = nullptr; + asIScriptFunction* shutdownFunc = nullptr; + bool valid = false; + }; + ScriptEngine scriptEngine; HotReload* hotReload; bool scriptCompilationError; @@ -41,6 +53,10 @@ private: ModelManager modelManager; MaterialManager materialManager; InputManager inputManager; + std::unordered_map entityScriptModules; + std::unordered_map entityScriptBindings; + unsigned int entityScriptModuleCounter = 0; + std::string currentSceneScriptPath; static const int WINDOW_WIDTH = 1280; static const int WINDOW_HEIGHT = 720; @@ -50,6 +66,10 @@ private: void Update(float deltaTime); void UpdateSystems(float deltaTime); + void UpdateEntityScripts(float deltaTime); + void ShutdownEntityScripts(); + void ProcessSceneScriptChanges(); + EntityScriptModule* GetEntityScriptModule(const std::string& path); void RenderScene(); void Draw(); }; \ No newline at end of file diff --git a/include/ECSComponents.h b/include/ECSComponents.h index ef7b56e..6acb29f 100644 --- a/include/ECSComponents.h +++ b/include/ECSComponents.h @@ -56,6 +56,13 @@ struct Tag { Tag(const std::string& n) : name(n) {} }; +// ScriptComponent - per-entity script reference +struct ScriptComponent { + std::string scriptPath; + bool enabled = true; + bool started = false; +}; + // SceneEntity component - marks entities owned by the scene struct SceneEntity { bool persistent = false; diff --git a/include/SceneLoader.h b/include/SceneLoader.h index b35d79c..b5497d1 100644 --- a/include/SceneLoader.h +++ b/include/SceneLoader.h @@ -18,3 +18,8 @@ bool SaveSceneToFile(const std::string& path); // Clear all entities from the registry void ClearScene(); + +// Scene script path helpers +void SetSceneScriptPath(const std::string& path); +const std::string& GetSceneScriptPath(); +bool ConsumeSceneScriptPath(std::string& outPath); diff --git a/include/gui/GuiManager.h b/include/gui/GuiManager.h index ed5fde5..a17acf7 100644 --- a/include/gui/GuiManager.h +++ b/include/gui/GuiManager.h @@ -6,6 +6,7 @@ #include "gui/ImGuiNotify.hpp" #include "LogWindow.h" // Include the new LogWindow class #include +#include class Application; @@ -30,6 +31,7 @@ private: bool IsEntityAncestor(entt::entity ancestor, entt::entity entity) const; const char* GetEntityLabel(entt::entity entity); void SyncTagBuffer(entt::entity entity); + void SyncScriptPathBuffer(entt::entity entity); bool showLogWindow = true; bool showSceneWindow = true; @@ -39,6 +41,10 @@ private: entt::entity selectedEntity = entt::null; entt::entity tagBufferEntity = entt::null; char tagBuffer[128] = {0}; + entt::entity scriptPathEntity = entt::null; + char scriptPathBuffer[260] = {0}; + char sceneScriptPathBuffer[260] = {0}; + std::string lastSceneScriptPath; ImVec2 desiredRenderSize = ImVec2(0.0f, 0.0f); bool requestSceneNew = false; bool requestSceneLoad = false; diff --git a/include/scripting/ScriptEngine.h b/include/scripting/ScriptEngine.h index 650936d..649c1c4 100644 --- a/include/scripting/ScriptEngine.h +++ b/include/scripting/ScriptEngine.h @@ -12,7 +12,9 @@ public: bool Initialize(); void Shutdown(); bool CompileScript(const std::string& filename); + bool CompileModule(const std::string& moduleName, const std::string& filename, asIScriptModule** outModule); void CallScriptFunction(asIScriptFunction* func, float dt = 0.0f); + void CallScriptFunction(asIScriptFunction* func, unsigned int entityId, float dt); void GarbageCollect(); // Add a path used to resolve #include directives in scripts diff --git a/scenes/demo.toml b/scenes/demo.toml index 5dd1eea..90059b1 100644 --- a/scenes/demo.toml +++ b/scenes/demo.toml @@ -50,4 +50,5 @@ color = 0x4523BAFF outline_size = 0.000 shader_vs = "shaders/toon.vs" shader_fs = "shaders/toon.fs" +script = "scripts/ball.as" diff --git a/scripts/ball.as b/scripts/ball.as new file mode 100644 index 0000000..f21e1c1 --- /dev/null +++ b/scripts/ball.as @@ -0,0 +1,104 @@ +// ScriptComponent example: vertical sine movement + +array trackedEntities; +array baseX; +array baseY; +array baseZ; +array phase; + +float amplitude = 0.5f; +float speed = 1.5f; + +int FindEntityIndex(uint entity) +{ + for (uint i = 0; i < trackedEntities.length(); ++i) + { + if (trackedEntities[i] == entity) + { + return int(i); + } + } + return -1; +} + +void TrackEntity(uint entity) +{ + if (FindEntityIndex(entity) != -1) + { + return; + } + + if (!ECS::HasTransform(entity)) + { + ECS::AddTransform(entity, 0.0f, 0.0f, 0.0f); + } + + float x = 0.0f; + float y = 0.0f; + float z = 0.0f; + ECS::GetPosition(entity, x, y, z); + + trackedEntities.insertLast(entity); + baseX.insertLast(x); + baseY.insertLast(y); + baseZ.insertLast(z); + phase.insertLast(0.0f); +} + +void UntrackEntity(uint entity) +{ + int idx = FindEntityIndex(entity); + if (idx < 0) + { + return; + } + + trackedEntities.removeAt(idx); + baseX.removeAt(idx); + baseY.removeAt(idx); + baseZ.removeAt(idx); + phase.removeAt(idx); +} + +void EntityInit(uint entity) +{ + if (!ECS::IsValid(entity)) + { + return; + } + + TrackEntity(entity); +} + +void EntityUpdate(uint entity, float dt) +{ + if (!ECS::IsValid(entity)) + { + return; + } + + int idx = FindEntityIndex(entity); + if (idx < 0) + { + TrackEntity(entity); + idx = FindEntityIndex(entity); + if (idx < 0) + { + return; + } + } + + if (!ECS::HasTransform(entity)) + { + return; + } + + phase[idx] += dt; + float offset = Math::Sin(phase[idx] * speed + float(entity) * 0.1f) * amplitude; + ECS::SetPosition(entity, baseX[idx], baseY[idx] + offset, baseZ[idx]); +} + +void EntityShutdown(uint entity) +{ + UntrackEntity(entity); +} diff --git a/src/Application.cpp b/src/Application.cpp index c120722..b3af0ff 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -107,6 +107,7 @@ bool Application::Initialize(int argc, char *argv[]) // Compile initial script scriptCompilationError = !scriptEngine.CompileScript(SCRIPT_FILE); + currentSceneScriptPath = SCRIPT_FILE; if (enableEditor) { @@ -134,10 +135,12 @@ void Application::Run() void Application::Update(float deltaTime) { + ProcessSceneScriptChanges(); + // Check for hot reload if (hotReload && hotReload->CheckForChanges()) { - bool success = scriptEngine.CompileScript(SCRIPT_FILE); + bool success = scriptEngine.CompileScript(currentSceneScriptPath); scriptCompilationError = !success; if (!success) { @@ -155,6 +158,8 @@ void Application::Update(float deltaTime) // Call script Update function scriptEngine.CallScriptFunction(scriptEngine.GetUpdateFunction(), deltaTime); + UpdateEntityScripts(deltaTime); + // Update ECS systems UpdateSystems(deltaTime); } @@ -176,6 +181,167 @@ void Application::UpdateSystems(float deltaTime) UpdateWorldTransforms(registry); } +Application::EntityScriptModule* Application::GetEntityScriptModule(const std::string& path) +{ + if (path.empty()) { + return nullptr; + } + + auto it = entityScriptModules.find(path); + if (it != entityScriptModules.end()) { + return &it->second; + } + + EntityScriptModule moduleInfo; + moduleInfo.path = path; + moduleInfo.moduleName = "entity_script_" + std::to_string(entityScriptModuleCounter++); + + if (!scriptEngine.CompileModule(moduleInfo.moduleName, path, &moduleInfo.module)) { + log_warn("Failed to compile entity script: %s", path.c_str()); + entityScriptModules.emplace(path, moduleInfo); + return &entityScriptModules[path]; + } + + if (moduleInfo.module) { + moduleInfo.initFunc = moduleInfo.module->GetFunctionByDecl("void EntityInit(uint)"); + if (!moduleInfo.initFunc) { + moduleInfo.initFunc = moduleInfo.module->GetFunctionByDecl("void Init(uint)"); + } + + moduleInfo.updateFunc = moduleInfo.module->GetFunctionByDecl("void EntityUpdate(uint, float)"); + if (!moduleInfo.updateFunc) { + moduleInfo.updateFunc = moduleInfo.module->GetFunctionByDecl("void Update(uint, float)"); + } + + moduleInfo.shutdownFunc = moduleInfo.module->GetFunctionByDecl("void EntityShutdown(uint)"); + if (!moduleInfo.shutdownFunc) { + moduleInfo.shutdownFunc = moduleInfo.module->GetFunctionByDecl("void Shutdown(uint)"); + } + + moduleInfo.valid = true; + } + + entityScriptModules.emplace(path, moduleInfo); + return &entityScriptModules[path]; +} + +void Application::UpdateEntityScripts(float deltaTime) +{ + auto view = registry.view(); + std::vector invalidBindings; + + for (auto entity : view) { + auto& script = view.get(entity); + if (!script.enabled || script.scriptPath.empty()) { + auto existingBinding = entityScriptBindings.find(entity); + if (script.started && existingBinding != entityScriptBindings.end()) { + auto* moduleInfo = GetEntityScriptModule(existingBinding->second); + if (moduleInfo && moduleInfo->valid && moduleInfo->shutdownFunc) { + scriptEngine.CallScriptFunction(moduleInfo->shutdownFunc, static_cast(entity), 0.0f); + } + } + script.started = false; + entityScriptBindings.erase(entity); + continue; + } + + std::string previousPath; + auto existingBinding = entityScriptBindings.find(entity); + if (existingBinding != entityScriptBindings.end()) { + previousPath = existingBinding->second; + } + + if (previousPath != script.scriptPath) { + if (!previousPath.empty()) { + auto* oldModule = GetEntityScriptModule(previousPath); + if (oldModule && oldModule->valid && oldModule->shutdownFunc) { + scriptEngine.CallScriptFunction(oldModule->shutdownFunc, static_cast(entity), 0.0f); + } + } + entityScriptBindings[entity] = script.scriptPath; + script.started = false; + } + + auto* moduleInfo = GetEntityScriptModule(script.scriptPath); + if (!moduleInfo || !moduleInfo->valid) { + continue; + } + + if (!script.started) { + if (moduleInfo->initFunc) { + scriptEngine.CallScriptFunction(moduleInfo->initFunc, static_cast(entity), 0.0f); + } + script.started = true; + } + + if (moduleInfo->updateFunc) { + scriptEngine.CallScriptFunction(moduleInfo->updateFunc, static_cast(entity), deltaTime); + } + } + + for (const auto& [entity, path] : entityScriptBindings) { + if (!registry.valid(entity)) { + invalidBindings.push_back(entity); + } + } + + for (auto entity : invalidBindings) { + entityScriptBindings.erase(entity); + } +} + +void Application::ShutdownEntityScripts() +{ + auto view = registry.view(); + for (auto entity : view) { + auto& script = view.get(entity); + if (!script.started || script.scriptPath.empty()) { + continue; + } + + auto* moduleInfo = GetEntityScriptModule(script.scriptPath); + if (moduleInfo && moduleInfo->valid && moduleInfo->shutdownFunc) { + scriptEngine.CallScriptFunction(moduleInfo->shutdownFunc, static_cast(entity), 0.0f); + } + script.started = false; + } +} + +void Application::ProcessSceneScriptChanges() +{ + std::string sceneScriptPath; + if (!ConsumeSceneScriptPath(sceneScriptPath)) { + return; + } + + if (sceneScriptPath.empty() || sceneScriptPath == currentSceneScriptPath) { + return; + } + + currentSceneScriptPath = sceneScriptPath; + bool success = scriptEngine.CompileScript(currentSceneScriptPath); + scriptCompilationError = !success; + if (!success) { + log_warn("Scene script compilation failed - keeping previous version"); + Toast::Warning("Scene script compilation failed - check console for details."); + return; + } + + if (hotReload) { + delete hotReload; + hotReload = nullptr; + } + + std::filesystem::path p(currentSceneScriptPath); + std::string watchPath = p.parent_path().string(); + if (watchPath.empty()) { + watchPath = "."; + } + hotReload = new HotReload(watchPath); + + scriptEngine.CallScriptFunction(scriptEngine.GetInitFunction()); +} + void Application::RenderScene() { // Query for active camera (first one found with Camera3DComponent) @@ -305,6 +471,7 @@ void Application::Shutdown() } + ShutdownEntityScripts(); scriptEngine.Shutdown(); if (enableEditor) { diff --git a/src/SceneLoader.cpp b/src/SceneLoader.cpp index d77ed53..d731d96 100644 --- a/src/SceneLoader.cpp +++ b/src/SceneLoader.cpp @@ -17,6 +17,8 @@ static entt::registry* g_sceneRegistry = nullptr; static ModelManager* g_sceneModelManager = nullptr; static ShaderManager* g_sceneShaderManager = nullptr; +static std::string g_sceneScriptPath; +static bool g_sceneScriptDirty = false; void SetSceneContext(entt::registry* registry, ModelManager* modelManager, ShaderManager* shaderManager) { g_sceneRegistry = registry; @@ -30,6 +32,26 @@ void ClearScene() { } } +void SetSceneScriptPath(const std::string& path) { + if (g_sceneScriptPath != path) { + g_sceneScriptPath = path; + g_sceneScriptDirty = true; + } +} + +const std::string& GetSceneScriptPath() { + return g_sceneScriptPath; +} + +bool ConsumeSceneScriptPath(std::string& outPath) { + if (!g_sceneScriptDirty) { + return false; + } + outPath = g_sceneScriptPath; + g_sceneScriptDirty = false; + return true; +} + struct SceneEntityDef { std::string id; std::string parent; @@ -53,6 +75,10 @@ struct SceneEntityDef { std::string shaderFs; unsigned int shaderId = 0; bool hasShaderId = false; + + bool hasScript = false; + std::string scriptPath; + bool scriptEnabled = true; }; static std::string Trim(const std::string& value) { @@ -131,6 +157,24 @@ static bool ParseString(const std::string& value, std::string& out) { return !out.empty(); } +static bool ParseBool(const std::string& value, bool& out) { + std::string trimmed = Trim(value); + std::string lower; + lower.reserve(trimmed.size()); + for (char c : trimmed) { + lower.push_back(static_cast(std::tolower(static_cast(c)))); + } + if (lower == "true" || lower == "1") { + out = true; + return true; + } + if (lower == "false" || lower == "0") { + out = false; + return true; + } + return false; +} + static std::string EscapeString(const std::string& value) { std::string out; out.reserve(value.size()); @@ -251,7 +295,23 @@ entt::entity LoadSceneFromFile(const std::string& path, bool clearExisting) { } if (!current) { - log_warn("Scene parse: key/value outside entity section at line %d", lineNumber); + size_t eq = line.find('='); + if (eq == std::string::npos) { + log_warn("Scene parse: invalid line %d", lineNumber); + continue; + } + + std::string key = Trim(line.substr(0, eq)); + std::string value = Trim(line.substr(eq + 1)); + + if (key == "scene_script") { + std::string sceneScript; + if (ParseString(value, sceneScript)) { + SetSceneScriptPath(sceneScript); + } + } else { + log_warn("Scene parse: key/value outside entity section at line %d", lineNumber); + } continue; } @@ -308,6 +368,14 @@ entt::entity LoadSceneFromFile(const std::string& path, bool clearExisting) { current->shaderId = static_cast(std::stoul(value, nullptr, 0)); current->hasShaderId = true; current->hasSprite = true; + } else if (key == "script") { + if (ParseString(value, current->scriptPath)) { + current->hasScript = true; + } + } else if (key == "script_enabled") { + if (ParseBool(value, current->scriptEnabled)) { + current->hasScript = true; + } } else { log_warn("Scene parse: unknown key '%s' at line %d", key.c_str(), lineNumber); } @@ -377,6 +445,13 @@ entt::entity LoadSceneFromFile(const std::string& path, bool clearExisting) { } g_sceneRegistry->emplace(entity, static_cast(modelId), col, def.outlineSize, shaderId); } + + if (def.hasScript || !def.scriptPath.empty()) { + auto& script = g_sceneRegistry->emplace(entity); + script.scriptPath = def.scriptPath; + script.enabled = def.scriptEnabled; + script.started = false; + } } for (size_t i = 0; i < defs.size(); ++i) { @@ -412,6 +487,10 @@ bool SaveSceneToFile(const std::string& path) { return false; } + if (!g_sceneScriptPath.empty()) { + file << "scene_script = \"" << EscapeString(g_sceneScriptPath) << "\"\n\n"; + } + auto& registry = *g_sceneRegistry; std::vector entities; auto& storage = registry.storage(); @@ -533,6 +612,15 @@ bool SaveSceneToFile(const std::string& path) { } } + if (auto* script = registry.try_get(entity)) { + if (!script->scriptPath.empty()) { + file << "script = \"" << EscapeString(script->scriptPath) << "\"\n"; + } + if (!script->enabled) { + file << "script_enabled = false\n"; + } + } + file << "\n"; } diff --git a/src/gui/GuiManager.cpp b/src/gui/GuiManager.cpp index 7d99b92..1e30512 100644 --- a/src/gui/GuiManager.cpp +++ b/src/gui/GuiManager.cpp @@ -328,6 +328,19 @@ void GuiManager::SyncTagBuffer(entt::entity entity) } } +void GuiManager::SyncScriptPathBuffer(entt::entity entity) +{ + if (!app) return; + if (entity == scriptPathEntity) return; + + scriptPathEntity = entity; + scriptPathBuffer[0] = '\0'; + auto& registry = app->GetRegistry(); + if (auto* script = registry.try_get(entity)) { + std::snprintf(scriptPathBuffer, sizeof(scriptPathBuffer), "%s", script->scriptPath.c_str()); + } +} + void GuiManager::RenderEntityNode(entt::entity entity) { if (!app) return; @@ -395,6 +408,24 @@ void GuiManager::RenderSceneWindow() auto& registry = app->GetRegistry(); + const std::string& sceneScriptPath = GetSceneScriptPath(); + if (sceneScriptPath != lastSceneScriptPath) { + std::snprintf(sceneScriptPathBuffer, sizeof(sceneScriptPathBuffer), "%s", sceneScriptPath.c_str()); + lastSceneScriptPath = sceneScriptPath; + } + + ImGui::Text("Scene Script"); + ImGui::SameLine(); + ImGui::SetNextItemWidth(240.0f); + ImGui::InputText("##SceneScriptPath", sceneScriptPathBuffer, sizeof(sceneScriptPathBuffer)); + ImGui::SameLine(); + if (ImGui::Button("Apply")) { + SetSceneScriptPath(sceneScriptPathBuffer); + lastSceneScriptPath = sceneScriptPathBuffer; + } + + ImGui::Separator(); + if (ImGui::Button("Create Entity")) { entt::entity entity = registry.create(); std::string name = "Entity " + std::to_string(static_cast(ToId(entity))); @@ -492,10 +523,11 @@ void GuiManager::RenderInspectorWindow() {"Transform", 1}, {"Velocity", 2}, {"Sprite", 3}, - {"Camera", 4}, - {"Light", 5}, - {"Material", 6}, - {"Render Pass", 7} + {"Script", 4}, + {"Camera", 5}, + {"Light", 6}, + {"Material", 7}, + {"Render Pass", 8} }; auto hasComponent = [&](int id) { @@ -504,10 +536,11 @@ void GuiManager::RenderInspectorWindow() case 1: return registry.any_of(selectedEntity); case 2: return registry.any_of(selectedEntity); case 3: return registry.any_of(selectedEntity); - case 4: return registry.any_of(selectedEntity); - case 5: return registry.any_of(selectedEntity); - case 6: return registry.any_of(selectedEntity); - case 7: return registry.any_of(selectedEntity); + case 4: return registry.any_of(selectedEntity); + case 5: return registry.any_of(selectedEntity); + case 6: return registry.any_of(selectedEntity); + case 7: return registry.any_of(selectedEntity); + case 8: return registry.any_of(selectedEntity); default: return false; } }; @@ -560,15 +593,19 @@ void GuiManager::RenderInspectorWindow() registry.emplace(selectedEntity, 0, WHITE, 0.0f, 0); break; case 4: - registry.emplace(selectedEntity); + registry.emplace(selectedEntity); + SyncScriptPathBuffer(selectedEntity); break; case 5: - registry.emplace(selectedEntity); + registry.emplace(selectedEntity); break; case 6: - registry.emplace(selectedEntity); + registry.emplace(selectedEntity); break; case 7: + registry.emplace(selectedEntity); + break; + case 8: registry.emplace(selectedEntity); break; default: @@ -705,6 +742,34 @@ void GuiManager::RenderInspectorWindow() } } + // Script + if (registry.any_of(selectedEntity)) { + auto& script = registry.get(selectedEntity); + ImGui::Separator(); + ImGui::Text("Script"); + ImGui::PushID("ScriptComponent"); + + SyncScriptPathBuffer(selectedEntity); + if (ImGui::InputText("Path", scriptPathBuffer, sizeof(scriptPathBuffer))) { + script.scriptPath = scriptPathBuffer; + script.started = false; + } + + if (ImGui::Checkbox("Enabled", &script.enabled)) { + if (!script.enabled) { + script.started = false; + } + } + + if (ImGui::Button("Remove Script")) { + registry.remove(selectedEntity); + scriptPathEntity = entt::null; + scriptPathBuffer[0] = '\0'; + } + + ImGui::PopID(); + } + // Camera if (registry.any_of(selectedEntity)) { ImGui::PushID("Camera"); diff --git a/src/scripting/ScriptEngine.cpp b/src/scripting/ScriptEngine.cpp index f44a8be..68a29aa 100644 --- a/src/scripting/ScriptEngine.cpp +++ b/src/scripting/ScriptEngine.cpp @@ -165,15 +165,62 @@ bool ScriptEngine::CompileScript(const std::string& filename) { // Get the newly created module currentModule = engine->GetModule("main"); - // Cache new functions - initFunc = currentModule->GetFunctionByName("Init"); - updateFunc = currentModule->GetFunctionByName("Update"); - shutdownFunc = currentModule->GetFunctionByName("Shutdown"); + // Cache new functions (scene-specific names preferred) + initFunc = currentModule->GetFunctionByDecl("void SceneInit()"); + if (!initFunc) { + initFunc = currentModule->GetFunctionByDecl("void Init()"); + } + + updateFunc = currentModule->GetFunctionByDecl("void SceneUpdate(float)"); + if (!updateFunc) { + updateFunc = currentModule->GetFunctionByDecl("void Update(float)"); + } + + shutdownFunc = currentModule->GetFunctionByDecl("void SceneShutdown()"); + if (!shutdownFunc) { + shutdownFunc = currentModule->GetFunctionByDecl("void Shutdown()"); + } hasValidScript = true; log_info("Script compiled and cached: %s", filename.c_str()); return true; } +bool ScriptEngine::CompileModule(const std::string& moduleName, const std::string& filename, asIScriptModule** outModule) { + if (!engine) return false; + + if (engine->GetModule(moduleName.c_str())) { + engine->DiscardModule(moduleName.c_str()); + } + + CScriptBuilder builder; + builder.SetIncludeCallback(IncludeCallback, nullptr); + + int r = builder.StartNewModule(engine, moduleName.c_str()); + if (r < 0) { + log_error("Failed to start module: %s", moduleName.c_str()); + return false; + } + + r = builder.AddSectionFromFile(filename.c_str()); + if (r < 0) { + log_error("Failed to add script section from file: %s", filename.c_str()); + engine->DiscardModule(moduleName.c_str()); + return false; + } + + r = builder.BuildModule(); + if (r < 0) { + log_error("Failed to build module: %s", moduleName.c_str()); + engine->DiscardModule(moduleName.c_str()); + return false; + } + + if (outModule) { + *outModule = engine->GetModule(moduleName.c_str()); + } + return true; +} + void ScriptEngine::CallScriptFunction(asIScriptFunction* func, float dt) { if (!func || !engine || !hasValidScript) return; @@ -200,6 +247,36 @@ void ScriptEngine::CallScriptFunction(asIScriptFunction* func, float dt) { ctx->Release(); } +void ScriptEngine::CallScriptFunction(asIScriptFunction* func, unsigned int entityId, float dt) { + if (!func || !engine) return; + + asIScriptContext* ctx = engine->CreateContext(); + if (!ctx) return; + + int r = ctx->Prepare(func); + if (r < 0) { + ctx->Release(); + return; + } + + const asUINT paramCount = func->GetParamCount(); + if (paramCount >= 1) { + ctx->SetArgDWord(0, entityId); + } + if (paramCount >= 2) { + ctx->SetArgFloat(1, dt); + } + + r = ctx->Execute(); + if (r != asEXECUTION_FINISHED) { + if (r == asEXECUTION_EXCEPTION) { + log_error("Script exception: %s", ctx->GetExceptionString()); + } + } + + ctx->Release(); +} + void ScriptEngine::ClearCachedFunctions() { updateFunc = nullptr; hasValidScript = false; From 9ebf77daec84d11a25f4fad33c775d6d9b5ad52a Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Sun, 8 Mar 2026 22:07:23 +1300 Subject: [PATCH 42/53] chore: trying to fix the wiki --- .gitea/workflows/sync-docs-to-wiki.yml | 11 +++++++---- docs/Editor.md | 1 + 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.gitea/workflows/sync-docs-to-wiki.yml b/.gitea/workflows/sync-docs-to-wiki.yml index d1fdcdd..157ed62 100644 --- a/.gitea/workflows/sync-docs-to-wiki.yml +++ b/.gitea/workflows/sync-docs-to-wiki.yml @@ -30,16 +30,19 @@ jobs: git config --global user.name "Simian CI" git config --global user.email "ci@simian.local" + # Workspace is always $GITHUB_WORKSPACE in Actions + WORKSPACE=${GITHUB_WORKSPACE:-.} + TEMP_WIKI=$(mktemp -d) git clone "$WIKI_REPO" "$TEMP_WIKI" cd "$TEMP_WIKI" - # Git-safe clean: delete everything except .git + # Safe clean (keep .git) find . -mindepth 1 -maxdepth 1 ! -name '.git' -exec rm -rf {} + - # Copy docs files - cp -r ../docs/* . 2>/dev/null || true + # Copy from workspace/docs + cp -r "$WORKSPACE/docs"/* . 2>/dev/null || true git add -A if git diff --staged --quiet; then @@ -48,4 +51,4 @@ jobs: git commit -m "Update wiki from docs (CI) [skip ci]" git push origin main echo "✅ Synced to simian.wiki main" - fi \ No newline at end of file + fi diff --git a/docs/Editor.md b/docs/Editor.md index dde22b2..7ac5a7e 100644 --- a/docs/Editor.md +++ b/docs/Editor.md @@ -91,3 +91,4 @@ This document outlines the in-app editor UI, its panels, and common workflows. - Set the script path in the Inspector and toggle enabled. - Preferred callbacks: `EntityInit(uint entity)`, `EntityUpdate(uint entity, float dt)`, `EntityShutdown(uint entity)`. - Legacy callbacks still work: `Init(uint entity)`, `Update(uint entity, float dt)`, `Shutdown(uint entity)`. +- Subject to change From cd754fda284c98a994243c2a38a06cdf06a7f707 Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Mon, 9 Mar 2026 12:55:55 +1300 Subject: [PATCH 43/53] feat: class instances for entity scripts --- imgui.ini | 24 ++-- include/Application.h | 13 +- include/ECSComponents.h | 5 + include/scripting/ScriptEngine.h | 8 ++ scenes/demo.toml | 5 +- scripts/ball.as | 141 ++++++------------- src/Application.cpp | 232 ++++++++++++++++++++++++++----- src/scripting/ScriptEngine.cpp | 69 +++++++++ 8 files changed, 348 insertions(+), 149 deletions(-) diff --git a/imgui.ini b/imgui.ini index 6310b76..1c57316 100644 --- a/imgui.ini +++ b/imgui.ini @@ -12,11 +12,11 @@ Collapsed=0 Pos=324,28 Size=645,580 Collapsed=0 -DockId=0x00000001,0 +DockId=0x00000004,0 [Window][Log Viewer] -Pos=324,610 -Size=645,102 +Pos=8,610 +Size=1264,102 Collapsed=0 DockId=0x00000002,0 @@ -77,13 +77,13 @@ Collapsed=0 [Window][Inspector] Pos=971,28 -Size=301,684 +Size=301,580 Collapsed=0 DockId=0x00000006,0 [Window][Scene] Pos=8,28 -Size=314,684 +Size=314,580 Collapsed=0 DockId=0x00000003,0 @@ -103,11 +103,11 @@ Size=306,82 Collapsed=0 [Docking][Data] -DockSpace ID=0x9076BACA Window=0x34F970D7 Pos=8,28 Size=1264,684 Split=X Selected=0x27A02DAA - DockNode ID=0x00000005 Parent=0x9076BACA SizeRef=961,684 Split=X - DockNode ID=0x00000003 Parent=0x00000005 SizeRef=314,684 Selected=0xE601B12F - DockNode ID=0x00000004 Parent=0x00000005 SizeRef=645,684 Split=Y - DockNode ID=0x00000001 Parent=0x00000004 SizeRef=1264,580 CentralNode=1 Selected=0x27A02DAA - DockNode ID=0x00000002 Parent=0x00000004 SizeRef=1264,102 Selected=0xBEDDA0C1 - DockNode ID=0x00000006 Parent=0x9076BACA SizeRef=301,684 Selected=0x36DC96AB +DockSpace ID=0x9076BACA Window=0x34F970D7 Pos=8,28 Size=1264,684 Split=Y Selected=0x27A02DAA + DockNode ID=0x00000001 Parent=0x9076BACA SizeRef=1264,580 Split=X + DockNode ID=0x00000005 Parent=0x00000001 SizeRef=961,684 Split=X + DockNode ID=0x00000003 Parent=0x00000005 SizeRef=314,684 Selected=0xE601B12F + DockNode ID=0x00000004 Parent=0x00000005 SizeRef=645,684 CentralNode=1 Selected=0x27A02DAA + DockNode ID=0x00000006 Parent=0x00000001 SizeRef=301,684 Selected=0x36DC96AB + DockNode ID=0x00000002 Parent=0x9076BACA SizeRef=1264,102 Selected=0xBEDDA0C1 diff --git a/include/Application.h b/include/Application.h index 452831c..22751ec 100644 --- a/include/Application.h +++ b/include/Application.h @@ -30,9 +30,15 @@ private: std::string path; std::string moduleName; asIScriptModule* module = nullptr; - asIScriptFunction* initFunc = nullptr; - asIScriptFunction* updateFunc = nullptr; - asIScriptFunction* shutdownFunc = nullptr; + // For object-instance based entity scripts we cache the object type + // (stored opaquely here to avoid requiring the AngelScript headers + // in all translation units) and the object-methods (Init/Update/Shutdown) + // to avoid repeated lookups. + asITypeInfo* objectType = nullptr; + std::string objectTypeName; + asIScriptFunction* initFunc = nullptr; // object method: Init(uint) + asIScriptFunction* updateFunc = nullptr; // object method: Update(uint,float) + asIScriptFunction* shutdownFunc = nullptr;// object method: Shutdown(uint) bool valid = false; }; @@ -69,6 +75,7 @@ private: void UpdateEntityScripts(float deltaTime); void ShutdownEntityScripts(); void ProcessSceneScriptChanges(); + void ReloadEntityScriptModules(); EntityScriptModule* GetEntityScriptModule(const std::string& path); void RenderScene(); void Draw(); diff --git a/include/ECSComponents.h b/include/ECSComponents.h index 6acb29f..38a6770 100644 --- a/include/ECSComponents.h +++ b/include/ECSComponents.h @@ -61,6 +61,11 @@ struct ScriptComponent { std::string scriptPath; bool enabled = true; bool started = false; + // Optional: name of the script class to instantiate. If empty, engine + // will attempt to pick a reasonable object type from the module. + std::string className; + // Opaque pointer to the script object instance (asIScriptObject*). + void* scriptInstance = nullptr; }; // SceneEntity component - marks entities owned by the scene diff --git a/include/scripting/ScriptEngine.h b/include/scripting/ScriptEngine.h index 649c1c4..6f016af 100644 --- a/include/scripting/ScriptEngine.h +++ b/include/scripting/ScriptEngine.h @@ -30,6 +30,14 @@ public: asIScriptFunction* GetInitFunction() const { return initFunc; } asIScriptFunction* GetShutdownFunction() const { return shutdownFunc; } + // Create and release script object instances for entity scripts + asIScriptObject* CreateObjectInstance(asIScriptModule* module, const std::string& className); + void ReleaseObjectInstance(asIScriptObject* obj); + // Retrieve an object's method by declaration (e.g. "void Update(uint, float)") + asIScriptFunction* GetObjectMethod(asIScriptModule* module, const std::string& className, const std::string& methodDecl); + // Call an object method; method must be an object method (use GetObjectMethod) + void CallObjectMethod(asIScriptFunction* method, asIScriptObject* object, unsigned int entityId, float dt); + private: asIScriptEngine* engine; asIScriptFunction* updateFunc; diff --git a/scenes/demo.toml b/scenes/demo.toml index 90059b1..88c71d2 100644 --- a/scenes/demo.toml +++ b/scenes/demo.toml @@ -23,7 +23,7 @@ shader_fs = "shaders/toon.fs" id = "entity_3" parent = "entity_2" tag = "Child" -position = [0.000, 1.250, 0.000] +position = [0.000, 1.950, 0.000] scale = [0.600, 0.600, 0.600] rotation_deg = 0.000 model = "sphere" @@ -34,12 +34,13 @@ color = 0xFF0000FF outline_size = 0.000 shader_vs = "shaders/toon.vs" shader_fs = "shaders/toon.fs" +script = "scripts/ball.as" [[entity]] id = "entity_6" parent = "entity_2" tag = "Child 2" -position = [0.000, 1.000, 1.900] +position = [0.000, 1.998, 1.900] scale = [1.000, 1.000, 1.000] rotation_deg = 0.000 model = "sphere" diff --git a/scripts/ball.as b/scripts/ball.as index f21e1c1..c389c4f 100644 --- a/scripts/ball.as +++ b/scripts/ball.as @@ -1,104 +1,47 @@ -// ScriptComponent example: vertical sine movement +// Class-based entity script: one `EntityScript` instance per entity. +// Implements Init/Update/Shutdown so the engine will instantiate it per-entity. -array trackedEntities; -array baseX; -array baseY; -array baseZ; -array phase; - -float amplitude = 0.5f; -float speed = 1.5f; - -int FindEntityIndex(uint entity) +class EntityScript { - for (uint i = 0; i < trackedEntities.length(); ++i) + float baseX; + float baseY; + float baseZ; + float phase; + + // per-instance movement parameters (can be tuned per-entity) + float amplitude = 2.5f; + float speed = 2.5f; + + EntityScript() { - if (trackedEntities[i] == entity) - { - return int(i); - } + baseX = 0.0f; + baseY = 0.0f; + baseZ = 0.0f; + phase = 0.0f; + } + + void Init(uint entity) + { + if (!ECS::IsValid(entity)) return; + if (!ECS::HasTransform(entity)) + ECS::AddTransform(entity, 0.0f, 0.0f, 0.0f); + + ECS::GetPosition(entity, baseX, baseY, baseZ); + phase = 0.0f; + } + + void Update(uint entity, float dt) + { + if (!ECS::IsValid(entity)) return; + if (!ECS::HasTransform(entity)) return; + + phase += dt; + float offset = Math::Sin(phase * speed + float(entity) * 0.1f) * amplitude; + ECS::SetPosition(entity, baseX, baseY + offset, baseZ); + } + + void Shutdown(uint entity) + { + // nothing to clean up per-instance for this simple example } - return -1; -} - -void TrackEntity(uint entity) -{ - if (FindEntityIndex(entity) != -1) - { - return; - } - - if (!ECS::HasTransform(entity)) - { - ECS::AddTransform(entity, 0.0f, 0.0f, 0.0f); - } - - float x = 0.0f; - float y = 0.0f; - float z = 0.0f; - ECS::GetPosition(entity, x, y, z); - - trackedEntities.insertLast(entity); - baseX.insertLast(x); - baseY.insertLast(y); - baseZ.insertLast(z); - phase.insertLast(0.0f); -} - -void UntrackEntity(uint entity) -{ - int idx = FindEntityIndex(entity); - if (idx < 0) - { - return; - } - - trackedEntities.removeAt(idx); - baseX.removeAt(idx); - baseY.removeAt(idx); - baseZ.removeAt(idx); - phase.removeAt(idx); -} - -void EntityInit(uint entity) -{ - if (!ECS::IsValid(entity)) - { - return; - } - - TrackEntity(entity); -} - -void EntityUpdate(uint entity, float dt) -{ - if (!ECS::IsValid(entity)) - { - return; - } - - int idx = FindEntityIndex(entity); - if (idx < 0) - { - TrackEntity(entity); - idx = FindEntityIndex(entity); - if (idx < 0) - { - return; - } - } - - if (!ECS::HasTransform(entity)) - { - return; - } - - phase[idx] += dt; - float offset = Math::Sin(phase[idx] * speed + float(entity) * 0.1f) * amplitude; - ECS::SetPosition(entity, baseX[idx], baseY[idx] + offset, baseZ[idx]); -} - -void EntityShutdown(uint entity) -{ - UntrackEntity(entity); } diff --git a/src/Application.cpp b/src/Application.cpp index b3af0ff..eab479d 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -138,20 +138,26 @@ void Application::Update(float deltaTime) ProcessSceneScriptChanges(); // Check for hot reload - if (hotReload && hotReload->CheckForChanges()) - { - bool success = scriptEngine.CompileScript(currentSceneScriptPath); - scriptCompilationError = !success; - if (!success) - { - log_warn("Script compilation failed - keeping previous version"); - Toast::Warning("Script compilation failed - check console for details."); - } - else - { - Toast::Success("Script reloaded successfully."); - // Should call init function again or things don't work - scriptEngine.CallScriptFunction(scriptEngine.GetInitFunction()); + if (hotReload) { + bool changed = hotReload->CheckForChanges(); + if (changed) { + bool success = scriptEngine.CompileScript(currentSceneScriptPath); + scriptCompilationError = !success; + if (!success) + { + log_warn("Script compilation failed - keeping previous version"); + Toast::Warning("Script compilation failed - check console for details."); + } + else + { + Toast::Success("Script reloaded successfully."); + // Should call init function again or things don't work + scriptEngine.CallScriptFunction(scriptEngine.GetInitFunction()); + } + + // Refresh any entity script modules so class-based entity scripts + // pick up changes immediately (release old instances then recompile). + ReloadEntityScriptModules(); } } @@ -203,19 +209,55 @@ Application::EntityScriptModule* Application::GetEntityScriptModule(const std::s } if (moduleInfo.module) { - moduleInfo.initFunc = moduleInfo.module->GetFunctionByDecl("void EntityInit(uint)"); - if (!moduleInfo.initFunc) { - moduleInfo.initFunc = moduleInfo.module->GetFunctionByDecl("void Init(uint)"); + // Try to detect an object type to instantiate for per-entity scripts. + // Prefer an explicit type named 'EntityScript' or any type that + // implements the expected entity methods. Do NOT pick the first + // available type as that may be an add-on type (array/string/etc). + asITypeInfo* objType = nullptr; + int count = moduleInfo.module->GetObjectTypeCount(); + for (int i = 0; i < count; ++i) { + asITypeInfo* t = moduleInfo.module->GetObjectTypeByIndex(i); + const char* n = t->GetName(); + if (!n) continue; + std::string name(n); + // Prefer explicit EntityScript class name + if (name == "EntityScript") { objType = t; break; } + // Otherwise, accept any script class that exposes Update/Init/Shutdown + // (at least one of the methods must exist) + bool hasInit = (t->GetMethodByDecl("void Init(uint)") != nullptr); + bool hasUpdate = (t->GetMethodByDecl("void Update(uint, float)") != nullptr); + bool hasShutdown = (t->GetMethodByDecl("void Shutdown(uint)") != nullptr); + if (hasInit || hasUpdate || hasShutdown) { + objType = t; + break; + } } - moduleInfo.updateFunc = moduleInfo.module->GetFunctionByDecl("void EntityUpdate(uint, float)"); - if (!moduleInfo.updateFunc) { - moduleInfo.updateFunc = moduleInfo.module->GetFunctionByDecl("void Update(uint, float)"); - } + if (objType) { + moduleInfo.objectType = objType; + const char* n = objType->GetName(); + moduleInfo.objectTypeName = n ? n : std::string(); - moduleInfo.shutdownFunc = moduleInfo.module->GetFunctionByDecl("void EntityShutdown(uint)"); - if (!moduleInfo.shutdownFunc) { - moduleInfo.shutdownFunc = moduleInfo.module->GetFunctionByDecl("void Shutdown(uint)"); + // Cache object-methods (decls must match what's used in scripts) + moduleInfo.initFunc = objType->GetMethodByDecl("void Init(uint)"); + moduleInfo.updateFunc = objType->GetMethodByDecl("void Update(uint, float)"); + moduleInfo.shutdownFunc = objType->GetMethodByDecl("void Shutdown(uint)"); + } else { + // Also accept free functions for backward compatibility + moduleInfo.initFunc = moduleInfo.module->GetFunctionByDecl("void EntityInit(uint)"); + if (!moduleInfo.initFunc) { + moduleInfo.initFunc = moduleInfo.module->GetFunctionByDecl("void Init(uint)"); + } + + moduleInfo.updateFunc = moduleInfo.module->GetFunctionByDecl("void EntityUpdate(uint, float)"); + if (!moduleInfo.updateFunc) { + moduleInfo.updateFunc = moduleInfo.module->GetFunctionByDecl("void Update(uint, float)"); + } + + moduleInfo.shutdownFunc = moduleInfo.module->GetFunctionByDecl("void EntityShutdown(uint)"); + if (!moduleInfo.shutdownFunc) { + moduleInfo.shutdownFunc = moduleInfo.module->GetFunctionByDecl("void Shutdown(uint)"); + } } moduleInfo.valid = true; @@ -236,8 +278,16 @@ void Application::UpdateEntityScripts(float deltaTime) auto existingBinding = entityScriptBindings.find(entity); if (script.started && existingBinding != entityScriptBindings.end()) { auto* moduleInfo = GetEntityScriptModule(existingBinding->second); - if (moduleInfo && moduleInfo->valid && moduleInfo->shutdownFunc) { - scriptEngine.CallScriptFunction(moduleInfo->shutdownFunc, static_cast(entity), 0.0f); + if (moduleInfo && moduleInfo->valid) { + // If using object instances, call method on instance and release + if (script.scriptInstance && moduleInfo->shutdownFunc) { + scriptEngine.CallObjectMethod(moduleInfo->shutdownFunc, reinterpret_cast(script.scriptInstance), static_cast(entity), 0.0f); + scriptEngine.ReleaseObjectInstance(reinterpret_cast(script.scriptInstance)); + script.scriptInstance = nullptr; + } else if (moduleInfo->shutdownFunc) { + // Fallback to free-function shutdown + scriptEngine.CallScriptFunction(moduleInfo->shutdownFunc, static_cast(entity), 0.0f); + } } } script.started = false; @@ -254,8 +304,14 @@ void Application::UpdateEntityScripts(float deltaTime) if (previousPath != script.scriptPath) { if (!previousPath.empty()) { auto* oldModule = GetEntityScriptModule(previousPath); - if (oldModule && oldModule->valid && oldModule->shutdownFunc) { - scriptEngine.CallScriptFunction(oldModule->shutdownFunc, static_cast(entity), 0.0f); + if (oldModule && oldModule->valid) { + if (script.scriptInstance && oldModule->shutdownFunc) { + scriptEngine.CallObjectMethod(oldModule->shutdownFunc, reinterpret_cast(script.scriptInstance), static_cast(entity), 0.0f); + scriptEngine.ReleaseObjectInstance(reinterpret_cast(script.scriptInstance)); + script.scriptInstance = nullptr; + } else if (oldModule->shutdownFunc) { + scriptEngine.CallScriptFunction(oldModule->shutdownFunc, static_cast(entity), 0.0f); + } } } entityScriptBindings[entity] = script.scriptPath; @@ -268,14 +324,37 @@ void Application::UpdateEntityScripts(float deltaTime) } if (!script.started) { - if (moduleInfo->initFunc) { - scriptEngine.CallScriptFunction(moduleInfo->initFunc, static_cast(entity), 0.0f); + // Create per-entity instance if object-type based + if (!script.scriptInstance && moduleInfo->objectType) { + std::string classToCreate = !script.className.empty() ? script.className : moduleInfo->objectTypeName; + asIScriptObject* inst = scriptEngine.CreateObjectInstance(moduleInfo->module, classToCreate); + if (inst) { + script.scriptInstance = reinterpret_cast(inst); + // Call Init method if present + if (moduleInfo->initFunc) { + scriptEngine.CallObjectMethod(moduleInfo->initFunc, inst, static_cast(entity), 0.0f); + } + } else { + // Fallback: call free-function init if exists + if (moduleInfo->initFunc) { + scriptEngine.CallScriptFunction(moduleInfo->initFunc, static_cast(entity), 0.0f); + } + } + } else { + // No object instance model; use existing free-function init + if (moduleInfo->initFunc) { + scriptEngine.CallScriptFunction(moduleInfo->initFunc, static_cast(entity), 0.0f); + } } script.started = true; } if (moduleInfo->updateFunc) { - scriptEngine.CallScriptFunction(moduleInfo->updateFunc, static_cast(entity), deltaTime); + if (script.scriptInstance && moduleInfo->objectType) { + scriptEngine.CallObjectMethod(moduleInfo->updateFunc, reinterpret_cast(script.scriptInstance), static_cast(entity), deltaTime); + } else { + scriptEngine.CallScriptFunction(moduleInfo->updateFunc, static_cast(entity), deltaTime); + } } } @@ -300,8 +379,14 @@ void Application::ShutdownEntityScripts() } auto* moduleInfo = GetEntityScriptModule(script.scriptPath); - if (moduleInfo && moduleInfo->valid && moduleInfo->shutdownFunc) { - scriptEngine.CallScriptFunction(moduleInfo->shutdownFunc, static_cast(entity), 0.0f); + if (moduleInfo && moduleInfo->valid) { + if (script.scriptInstance && moduleInfo->shutdownFunc) { + scriptEngine.CallObjectMethod(moduleInfo->shutdownFunc, reinterpret_cast(script.scriptInstance), static_cast(entity), 0.0f); + scriptEngine.ReleaseObjectInstance(reinterpret_cast(script.scriptInstance)); + script.scriptInstance = nullptr; + } else if (moduleInfo->shutdownFunc) { + scriptEngine.CallScriptFunction(moduleInfo->shutdownFunc, static_cast(entity), 0.0f); + } } script.started = false; } @@ -342,6 +427,87 @@ void Application::ProcessSceneScriptChanges() scriptEngine.CallScriptFunction(scriptEngine.GetInitFunction()); } +void Application::ReloadEntityScriptModules() +{ + // Iterate all known entity script modules. For each, call shutdown on + // existing instances, release them, then recompile the module and + // refresh cached method pointers. + for (auto &kv : entityScriptModules) { + auto &moduleInfo = kv.second; + if (moduleInfo.path.empty()) continue; + + log_info("Reloading entity module: %s", moduleInfo.path.c_str()); + // For every entity bound to this path, release its current instance + for (auto it = entityScriptBindings.begin(); it != entityScriptBindings.end(); ++it) { + if (it->second != moduleInfo.path) continue; + entt::entity e = it->first; + if (!registry.valid(e)) continue; + auto &script = registry.get(e); + if (script.scriptInstance) { + // Call old module shutdown method if available + if (moduleInfo.shutdownFunc) { + scriptEngine.CallObjectMethod(moduleInfo.shutdownFunc, reinterpret_cast(script.scriptInstance), static_cast(e), 0.0f); + } + // Release the old instance + scriptEngine.ReleaseObjectInstance(reinterpret_cast(script.scriptInstance)); + script.scriptInstance = nullptr; + script.started = false; + } + } + + // Recompile module in-place using the same moduleName so the engine + // replaces the module's bytecode and types. + asIScriptModule* newModule = nullptr; + bool ok = scriptEngine.CompileModule(moduleInfo.moduleName, moduleInfo.path, &newModule); + moduleInfo.module = newModule; + moduleInfo.valid = ok && (moduleInfo.module != nullptr); + if (moduleInfo.valid) { + log_info("Reloaded entity module: %s", moduleInfo.path.c_str()); + } else { + log_warn("Failed to reload entity module: %s", moduleInfo.path.c_str()); + } + + // Re-detect object type and cached methods (same logic as in GetEntityScriptModule) + moduleInfo.objectType = nullptr; + moduleInfo.objectTypeName.clear(); + moduleInfo.initFunc = nullptr; + moduleInfo.updateFunc = nullptr; + moduleInfo.shutdownFunc = nullptr; + + if (moduleInfo.module) { + asITypeInfo* objType = nullptr; + int count = moduleInfo.module->GetObjectTypeCount(); + for (int i = 0; i < count; ++i) { + asITypeInfo* t = moduleInfo.module->GetObjectTypeByIndex(i); + const char* n = t->GetName(); + if (!n) continue; + std::string name(n); + if (name == "EntityScript") { objType = t; break; } + bool hasInit = (t->GetMethodByDecl("void Init(uint)") != nullptr); + bool hasUpdate = (t->GetMethodByDecl("void Update(uint, float)") != nullptr); + bool hasShutdown = (t->GetMethodByDecl("void Shutdown(uint)") != nullptr); + if (hasInit || hasUpdate || hasShutdown) { objType = t; break; } + } + + if (objType) { + moduleInfo.objectType = objType; + const char* n = objType->GetName(); + moduleInfo.objectTypeName = n ? n : std::string(); + moduleInfo.initFunc = objType->GetMethodByDecl("void Init(uint)"); + moduleInfo.updateFunc = objType->GetMethodByDecl("void Update(uint, float)"); + moduleInfo.shutdownFunc = objType->GetMethodByDecl("void Shutdown(uint)"); + } else { + moduleInfo.initFunc = moduleInfo.module->GetFunctionByDecl("void EntityInit(uint)"); + if (!moduleInfo.initFunc) moduleInfo.initFunc = moduleInfo.module->GetFunctionByDecl("void Init(uint)"); + moduleInfo.updateFunc = moduleInfo.module->GetFunctionByDecl("void EntityUpdate(uint, float)"); + if (!moduleInfo.updateFunc) moduleInfo.updateFunc = moduleInfo.module->GetFunctionByDecl("void Update(uint, float)"); + moduleInfo.shutdownFunc = moduleInfo.module->GetFunctionByDecl("void EntityShutdown(uint)"); + if (!moduleInfo.shutdownFunc) moduleInfo.shutdownFunc = moduleInfo.module->GetFunctionByDecl("void Shutdown(uint)"); + } + } + } +} + void Application::RenderScene() { // Query for active camera (first one found with Camera3DComponent) diff --git a/src/scripting/ScriptEngine.cpp b/src/scripting/ScriptEngine.cpp index 68a29aa..8c1028b 100644 --- a/src/scripting/ScriptEngine.cpp +++ b/src/scripting/ScriptEngine.cpp @@ -277,6 +277,75 @@ void ScriptEngine::CallScriptFunction(asIScriptFunction* func, unsigned int enti ctx->Release(); } +asIScriptObject* ScriptEngine::CreateObjectInstance(asIScriptModule* module, const std::string& className) +{ + if (!engine || !module) return nullptr; + asITypeInfo* typeInfo = nullptr; + int count = module->GetObjectTypeCount(); + for (int i = 0; i < count; ++i) { + asITypeInfo* t = module->GetObjectTypeByIndex(i); + const char* n = t->GetName(); + if (n && className == n) { + typeInfo = t; + break; + } + } + if (!typeInfo) return nullptr; + void* raw = engine->CreateScriptObject(typeInfo); + return reinterpret_cast(raw); +} + +void ScriptEngine::ReleaseObjectInstance(asIScriptObject* obj) +{ + if (!obj) return; + // Prefer using the engine helper to properly destroy the script object + asITypeInfo* ti = obj->GetObjectType(); + if (engine && ti) { + engine->ReleaseScriptObject(obj, ti); + } else { + obj->Release(); + } +} + +asIScriptFunction* ScriptEngine::GetObjectMethod(asIScriptModule* module, const std::string& className, const std::string& methodDecl) +{ + if (!module) return nullptr; + asITypeInfo* typeInfo = module->GetTypeInfoByName(className.c_str()); + if (!typeInfo) return nullptr; + return typeInfo->GetMethodByDecl(methodDecl.c_str()); +} + +void ScriptEngine::CallObjectMethod(asIScriptFunction* method, asIScriptObject* object, unsigned int entityId, float dt) +{ + if (!method || !engine || !object) return; + + asIScriptContext* ctx = engine->CreateContext(); + if (!ctx) return; + + int r = ctx->Prepare(method); + if (r < 0) { ctx->Release(); return; } + + // Set the object instance for the call + ctx->SetObject(object); + + const asUINT paramCount = method->GetParamCount(); + if (paramCount >= 1) { + ctx->SetArgDWord(0, entityId); + } + if (paramCount >= 2) { + ctx->SetArgFloat(1, dt); + } + + r = ctx->Execute(); + if (r != asEXECUTION_FINISHED) { + if (r == asEXECUTION_EXCEPTION) { + log_error("Script exception: %s", ctx->GetExceptionString()); + } + } + + ctx->Release(); +} + void ScriptEngine::ClearCachedFunctions() { updateFunc = nullptr; hasValidScript = false; From 2a74648ffdcbc892f62d8362865117fe2a1c02cb Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Mon, 9 Mar 2026 13:24:39 +1300 Subject: [PATCH 44/53] feat: editable properties --- include/gui/GuiManager.h | 35 ++++ scripts/ball.as | 6 +- src/gui/GuiManager.cpp | 340 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 378 insertions(+), 3 deletions(-) diff --git a/include/gui/GuiManager.h b/include/gui/GuiManager.h index a17acf7..2746866 100644 --- a/include/gui/GuiManager.h +++ b/include/gui/GuiManager.h @@ -7,6 +7,9 @@ #include "LogWindow.h" // Include the new LogWindow class #include #include +#include +#include +#include class Application; @@ -30,8 +33,37 @@ private: void RenderEntityNode(entt::entity entity); bool IsEntityAncestor(entt::entity ancestor, entt::entity entity) const; const char* GetEntityLabel(entt::entity entity); + struct ScriptEditableFieldMeta { + std::string name; + std::string type; + bool hasRange = false; + float rangeMin = 0.0f; + float rangeMax = 1.0f; + std::vector options; + }; + + struct ScriptEditableCache { + std::string className; + std::vector fields; + std::filesystem::file_time_type lastWriteTime; + bool hasWriteTime = false; + }; + + enum class ScriptValueKind { Float, Int, Bool, String }; + + struct ScriptEditableValue { + ScriptValueKind kind = ScriptValueKind::Float; + bool hasValue = false; + float f = 0.0f; + int i = 0; + bool b = false; + std::string s; + }; + void SyncTagBuffer(entt::entity entity); void SyncScriptPathBuffer(entt::entity entity); + void RenderScriptEditableControls(entt::entity entity); + ScriptEditableCache &GetOrParseEditableCache(const std::string &path, const std::string &className); bool showLogWindow = true; bool showSceneWindow = true; @@ -52,4 +84,7 @@ private: char sceneLoadPath[260] = {0}; char sceneSavePath[260] = {0}; int addComponentIndex = 0; + + std::unordered_map scriptEditableCache; + std::unordered_map> scriptEditableStaged; }; \ No newline at end of file diff --git a/scripts/ball.as b/scripts/ball.as index c389c4f..60a9848 100644 --- a/scripts/ball.as +++ b/scripts/ball.as @@ -6,11 +6,11 @@ class EntityScript float baseX; float baseY; float baseZ; - float phase; + [editable][range[0,1]]float phase; // per-instance movement parameters (can be tuned per-entity) - float amplitude = 2.5f; - float speed = 2.5f; + [editable][range[0,10]]float amplitude = 2.5f; + [editable][range[0,10]]float speed = 2.5f; EntityScript() { diff --git a/src/gui/GuiManager.cpp b/src/gui/GuiManager.cpp index 1e30512..c1ece9d 100644 --- a/src/gui/GuiManager.cpp +++ b/src/gui/GuiManager.cpp @@ -5,9 +5,11 @@ #include #include #include +#include #include #include #include +#include #include #include "log.h" #include "Application.h" @@ -768,6 +770,8 @@ void GuiManager::RenderInspectorWindow() } ImGui::PopID(); + + RenderScriptEditableControls(selectedEntity); } // Camera @@ -912,6 +916,342 @@ void GuiManager::RenderInspectorWindow() ImGui::End(); } +static std::string TrimString(const std::string &value) +{ + size_t start = value.find_first_not_of(" \t\r\n"); + if (start == std::string::npos) return std::string(); + size_t end = value.find_last_not_of(" \t\r\n"); + return value.substr(start, end - start + 1); +} + +static bool ExtractTagContent(const std::string &line, const std::string &tag, std::string &out) +{ + std::string needle = "[" + tag + "["; + size_t start = line.find(needle); + if (start == std::string::npos) return false; + start += needle.size(); + size_t end = line.find("]]", start); + if (end == std::string::npos) return false; + out = line.substr(start, end - start); + return true; +} + +static std::vector SplitOptions(const std::string &value) +{ + std::vector parts; + std::stringstream ss(value); + std::string item; + while (std::getline(ss, item, ',')) { + parts.push_back(TrimString(item)); + } + return parts; +} + +static bool TryParseRange(const std::string &value, float &outMin, float &outMax) +{ + size_t comma = value.find(','); + if (comma == std::string::npos) return false; + std::string left = TrimString(value.substr(0, comma)); + std::string right = TrimString(value.substr(comma + 1)); + try { + outMin = std::stof(left); + outMax = std::stof(right); + return true; + } catch (...) { + return false; + } +} + +GuiManager::ScriptEditableCache &GuiManager::GetOrParseEditableCache(const std::string &path, const std::string &className) +{ + std::string key = path + "::" + className; + auto &cache = scriptEditableCache[key]; + cache.className = className; + + bool needsParse = true; + try { + auto writeTime = std::filesystem::last_write_time(path); + if (cache.hasWriteTime && cache.lastWriteTime == writeTime) { + needsParse = false; + } else { + cache.lastWriteTime = writeTime; + cache.hasWriteTime = true; + } + } catch (const std::exception &) { + // If file is missing or time cannot be read, parse anyway (will be empty). + } + + if (!needsParse) return cache; + + cache.fields.clear(); + + std::ifstream file(path); + if (!file.is_open()) { + return cache; + } + + std::string line; + bool inClass = false; + int braceDepth = 0; + + while (std::getline(file, line)) { + std::string trimmed = TrimString(line); + if (!inClass) { + if (trimmed.find("class " + className) != std::string::npos) { + inClass = true; + for (char c : trimmed) { + if (c == '{') braceDepth++; + } + } + continue; + } + + for (char c : line) { + if (c == '{') braceDepth++; + if (c == '}') braceDepth--; + } + + if (braceDepth <= 0) { + inClass = false; + continue; + } + + if (line.find("[editable]") == std::string::npos) continue; + + ScriptEditableFieldMeta meta; + meta.hasRange = false; + meta.rangeMin = 0.0f; + meta.rangeMax = 1.0f; + + std::string rangeContent; + if (ExtractTagContent(line, "range", rangeContent)) { + float minVal = 0.0f; + float maxVal = 1.0f; + if (TryParseRange(rangeContent, minVal, maxVal)) { + meta.hasRange = true; + meta.rangeMin = minVal; + meta.rangeMax = maxVal; + } + } + + std::string optionsContent; + if (ExtractTagContent(line, "options", optionsContent)) { + meta.options = SplitOptions(optionsContent); + } + + size_t lastTag = line.find_last_of(']'); + if (lastTag == std::string::npos) continue; + std::string declaration = TrimString(line.substr(lastTag + 1)); + if (declaration.empty()) continue; + + std::stringstream declStream(declaration); + declStream >> meta.type; + std::string nameToken; + declStream >> nameToken; + if (meta.type.empty() || nameToken.empty()) continue; + + size_t equalPos = nameToken.find('='); + if (equalPos != std::string::npos) { + nameToken = nameToken.substr(0, equalPos); + } + if (!nameToken.empty() && nameToken.back() == ';') { + nameToken.pop_back(); + } + meta.name = TrimString(nameToken); + if (!meta.name.empty()) { + cache.fields.push_back(meta); + } + } + + return cache; +} + +void GuiManager::RenderScriptEditableControls(entt::entity entity) +{ + auto ®istry = app->GetRegistry(); + auto &script = registry.get(entity); + if (!script.enabled || script.scriptPath.empty() || !script.scriptInstance) return; + + auto *obj = reinterpret_cast(script.scriptInstance); + if (!obj) return; + + asITypeInfo *objType = obj->GetObjectType(); + if (!objType) return; + asIScriptEngine *engine = obj->GetEngine(); + if (!engine) return; + + const char *className = objType->GetName(); + if (!className) return; + + auto &cache = GetOrParseEditableCache(script.scriptPath, className); + if (cache.fields.empty()) return; + + ImGui::Separator(); + ImGui::Text("Editable"); + ImGui::PushID("ScriptEditable"); + + int floatTypeId = engine->GetTypeIdByDecl("float"); + int intTypeId = engine->GetTypeIdByDecl("int"); + int boolTypeId = engine->GetTypeIdByDecl("bool"); + int stringTypeId = engine->GetTypeIdByDecl("string"); + + auto &stagedMap = scriptEditableStaged[entity]; + + for (const auto &field : cache.fields) { + int propertyIndex = -1; + int propertyTypeId = 0; + const int propertyCount = static_cast(obj->GetPropertyCount()); + for (int i = 0; i < propertyCount; ++i) { + const char *propName = obj->GetPropertyName(i); + if (propName && field.name == propName) { + propertyIndex = i; + propertyTypeId = obj->GetPropertyTypeId(i); + break; + } + } + if (propertyIndex < 0) continue; + + void *propAddr = obj->GetAddressOfProperty(propertyIndex); + if (!propAddr) continue; + + ScriptEditableValue &staged = stagedMap[field.name]; + if (!staged.hasValue) { + if (propertyTypeId == floatTypeId) { + staged.kind = ScriptValueKind::Float; + staged.f = *reinterpret_cast(propAddr); + staged.hasValue = true; + } else if (propertyTypeId == intTypeId) { + staged.kind = ScriptValueKind::Int; + staged.i = *reinterpret_cast(propAddr); + staged.hasValue = true; + } else if (propertyTypeId == boolTypeId) { + staged.kind = ScriptValueKind::Bool; + staged.b = *reinterpret_cast(propAddr); + staged.hasValue = true; + } else if (propertyTypeId == stringTypeId) { + staged.kind = ScriptValueKind::String; + staged.s = *reinterpret_cast(propAddr); + staged.hasValue = true; + } else { + continue; + } + } + + ImGui::PushID(field.name.c_str()); + if (staged.kind == ScriptValueKind::Float) { + if (!field.options.empty()) { + int currentIndex = 0; + float currentValue = staged.f; + int maxIndex = static_cast(field.options.size()) - 1; + if (maxIndex < 0) maxIndex = 0; + currentIndex = static_cast(currentValue); + currentIndex = std::clamp(currentIndex, 0, maxIndex); + if (ImGui::SliderInt(field.name.c_str(), ¤tIndex, 0, maxIndex)) { + staged.f = static_cast(currentIndex); + } + } else if (field.hasRange) { + if (ImGui::SliderFloat(field.name.c_str(), &staged.f, field.rangeMin, field.rangeMax)) { + staged.hasValue = true; + } + } else { + if (ImGui::DragFloat(field.name.c_str(), &staged.f, 0.1f)) { + staged.hasValue = true; + } + } + } else if (staged.kind == ScriptValueKind::Int) { + if (!field.options.empty()) { + int currentIndex = staged.i; + int maxIndex = static_cast(field.options.size()) - 1; + if (maxIndex < 0) maxIndex = 0; + currentIndex = std::clamp(currentIndex, 0, maxIndex); + if (ImGui::SliderInt(field.name.c_str(), ¤tIndex, 0, maxIndex)) { + staged.i = currentIndex; + } + } else if (field.hasRange) { + if (ImGui::SliderInt(field.name.c_str(), &staged.i, static_cast(field.rangeMin), static_cast(field.rangeMax))) { + staged.hasValue = true; + } + } else { + if (ImGui::DragInt(field.name.c_str(), &staged.i, 1.0f)) { + staged.hasValue = true; + } + } + } else if (staged.kind == ScriptValueKind::Bool) { + if (ImGui::Checkbox(field.name.c_str(), &staged.b)) { + staged.hasValue = true; + } + } else if (staged.kind == ScriptValueKind::String) { + if (!field.options.empty()) { + int currentIndex = 0; + for (size_t i = 0; i < field.options.size(); ++i) { + if (field.options[i] == staged.s) { + currentIndex = static_cast(i); + break; + } + } + if (ImGui::Combo(field.name.c_str(), ¤tIndex, [](void *data, int idx, const char **outText) { + auto *opts = reinterpret_cast *>(data); + if (idx < 0 || idx >= static_cast(opts->size())) return false; + *outText = (*opts)[idx].c_str(); + return true; + }, (void *)&field.options, static_cast(field.options.size()))) { + if (currentIndex >= 0 && currentIndex < static_cast(field.options.size())) { + staged.s = field.options[currentIndex]; + } + } + } else { + char buffer[256]; + std::snprintf(buffer, sizeof(buffer), "%s", staged.s.c_str()); + if (ImGui::InputText(field.name.c_str(), buffer, sizeof(buffer))) { + staged.s = buffer; + staged.hasValue = true; + } + } + } + ImGui::PopID(); + } + + if (ImGui::Button("Apply")) { + for (const auto &field : cache.fields) { + auto it = stagedMap.find(field.name); + if (it == stagedMap.end()) continue; + ScriptEditableValue &staged = it->second; + if (!staged.hasValue) continue; + + int propertyIndex = -1; + int propertyTypeId = 0; + const int propertyCount = static_cast(obj->GetPropertyCount()); + for (int i = 0; i < propertyCount; ++i) { + const char *propName = obj->GetPropertyName(i); + if (propName && field.name == propName) { + propertyIndex = i; + propertyTypeId = obj->GetPropertyTypeId(i); + break; + } + } + if (propertyIndex < 0) continue; + void *propAddr = obj->GetAddressOfProperty(propertyIndex); + if (!propAddr) continue; + + if (propertyTypeId == floatTypeId && staged.kind == ScriptValueKind::Float) { + *reinterpret_cast(propAddr) = staged.f; + } else if (propertyTypeId == intTypeId && staged.kind == ScriptValueKind::Int) { + *reinterpret_cast(propAddr) = staged.i; + } else if (propertyTypeId == boolTypeId && staged.kind == ScriptValueKind::Bool) { + *reinterpret_cast(propAddr) = staged.b; + } else if (propertyTypeId == stringTypeId && staged.kind == ScriptValueKind::String) { + *reinterpret_cast(propAddr) = staged.s; + } + } + } + ImGui::SameLine(); + if (ImGui::Button("Reset")) { + stagedMap.clear(); + } + + ImGui::PopID(); +} + void GuiManager::RenderErrorBanner() { if (!app || !app->HasScriptCompilationError()) From b3871716a1f100e0fa5beab7b4a1e05dfabb585f Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Mon, 9 Mar 2026 13:33:54 +1300 Subject: [PATCH 45/53] feat: edit values and persist --- imgui.ini | 18 +++--- include/ECSComponents.h | 3 + include/gui/GuiManager.h | 6 ++ scenes/demo.toml | 7 ++- src/Application.cpp | 62 ++++++++++++++++++++ src/SceneLoader.cpp | 35 ++++++++++++ src/gui/GuiManager.cpp | 119 ++++++++++++++++++++++++--------------- 7 files changed, 193 insertions(+), 57 deletions(-) diff --git a/imgui.ini b/imgui.ini index 1c57316..39837fe 100644 --- a/imgui.ini +++ b/imgui.ini @@ -9,8 +9,8 @@ Size=400,400 Collapsed=0 [Window][Game Window] -Pos=324,28 -Size=645,580 +Pos=232,28 +Size=663,580 Collapsed=0 DockId=0x00000004,0 @@ -76,14 +76,14 @@ Size=189,63 Collapsed=0 [Window][Inspector] -Pos=971,28 -Size=301,580 +Pos=897,28 +Size=375,580 Collapsed=0 DockId=0x00000006,0 [Window][Scene] Pos=8,28 -Size=314,580 +Size=222,580 Collapsed=0 DockId=0x00000003,0 @@ -105,9 +105,9 @@ Collapsed=0 [Docking][Data] DockSpace ID=0x9076BACA Window=0x34F970D7 Pos=8,28 Size=1264,684 Split=Y Selected=0x27A02DAA DockNode ID=0x00000001 Parent=0x9076BACA SizeRef=1264,580 Split=X - DockNode ID=0x00000005 Parent=0x00000001 SizeRef=961,684 Split=X - DockNode ID=0x00000003 Parent=0x00000005 SizeRef=314,684 Selected=0xE601B12F - DockNode ID=0x00000004 Parent=0x00000005 SizeRef=645,684 CentralNode=1 Selected=0x27A02DAA - DockNode ID=0x00000006 Parent=0x00000001 SizeRef=301,684 Selected=0x36DC96AB + DockNode ID=0x00000005 Parent=0x00000001 SizeRef=887,684 Split=X + DockNode ID=0x00000003 Parent=0x00000005 SizeRef=222,684 Selected=0xE601B12F + DockNode ID=0x00000004 Parent=0x00000005 SizeRef=663,684 CentralNode=1 Selected=0x27A02DAA + DockNode ID=0x00000006 Parent=0x00000001 SizeRef=375,684 Selected=0x36DC96AB DockNode ID=0x00000002 Parent=0x9076BACA SizeRef=1264,102 Selected=0xBEDDA0C1 diff --git a/include/ECSComponents.h b/include/ECSComponents.h index 38a6770..01daaf7 100644 --- a/include/ECSComponents.h +++ b/include/ECSComponents.h @@ -2,6 +2,7 @@ #include "raylib.h" #include "entt.hpp" #include +#include // ECSTransform component - position, rotation, and scale struct ECSTransform { @@ -66,6 +67,8 @@ struct ScriptComponent { std::string className; // Opaque pointer to the script object instance (asIScriptObject*). void* scriptInstance = nullptr; + // Persisted overrides for editable script fields (name -> raw value string). + std::unordered_map scriptOverrides; }; // SceneEntity component - marks entities owned by the scene diff --git a/include/gui/GuiManager.h b/include/gui/GuiManager.h index 2746866..997551d 100644 --- a/include/gui/GuiManager.h +++ b/include/gui/GuiManager.h @@ -54,10 +54,15 @@ private: struct ScriptEditableValue { ScriptValueKind kind = ScriptValueKind::Float; bool hasValue = false; + bool hasBaseline = false; float f = 0.0f; + float baselineF = 0.0f; int i = 0; + int baselineI = 0; bool b = false; + bool baselineB = false; std::string s; + std::string baselineS; }; void SyncTagBuffer(entt::entity entity); @@ -87,4 +92,5 @@ private: std::unordered_map scriptEditableCache; std::unordered_map> scriptEditableStaged; + std::unordered_map scriptEditableInstancePtr; }; \ No newline at end of file diff --git a/scenes/demo.toml b/scenes/demo.toml index 88c71d2..0546022 100644 --- a/scenes/demo.toml +++ b/scenes/demo.toml @@ -23,7 +23,7 @@ shader_fs = "shaders/toon.fs" id = "entity_3" parent = "entity_2" tag = "Child" -position = [0.000, 1.950, 0.000] +position = [0.000, 3.571, 0.000] scale = [0.600, 0.600, 0.600] rotation_deg = 0.000 model = "sphere" @@ -40,7 +40,7 @@ script = "scripts/ball.as" id = "entity_6" parent = "entity_2" tag = "Child 2" -position = [0.000, 1.998, 1.900] +position = [0.000, 1.634, 1.900] scale = [1.000, 1.000, 1.000] rotation_deg = 0.000 model = "sphere" @@ -52,4 +52,7 @@ outline_size = 0.000 shader_vs = "shaders/toon.vs" shader_fs = "shaders/toon.fs" script = "scripts/ball.as" +script_var_speed = "8.352000" +script_var_amplitude = "0.491000" +script_var_phase = "0.576000" diff --git a/src/Application.cpp b/src/Application.cpp index eab479d..e10e3b4 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -187,6 +187,67 @@ void Application::UpdateSystems(float deltaTime) UpdateWorldTransforms(registry); } +static bool ParseOverrideBool(const std::string& value, bool& out) +{ + std::string lower; + lower.reserve(value.size()); + for (char c : value) { + lower.push_back(static_cast(std::tolower(static_cast(c)))); + } + if (lower == "true" || lower == "1") { out = true; return true; } + if (lower == "false" || lower == "0") { out = false; return true; } + return false; +} + +static void ApplyScriptOverrides(ScriptEngine& scriptEngine, ScriptComponent& script, asIScriptObject* instance) +{ + if (!instance || script.scriptOverrides.empty()) return; + asIScriptEngine* engine = scriptEngine.GetEngine(); + if (!engine) return; + + const int floatTypeId = engine->GetTypeIdByDecl("float"); + const int intTypeId = engine->GetTypeIdByDecl("int"); + const int boolTypeId = engine->GetTypeIdByDecl("bool"); + const int stringTypeId = engine->GetTypeIdByDecl("string"); + + const int propertyCount = static_cast(instance->GetPropertyCount()); + for (const auto& entry : script.scriptOverrides) { + const std::string& name = entry.first; + const std::string& raw = entry.second; + + int propIndex = -1; + int propTypeId = 0; + for (int i = 0; i < propertyCount; ++i) { + const char* propName = instance->GetPropertyName(i); + if (propName && name == propName) { + propIndex = i; + propTypeId = instance->GetPropertyTypeId(i); + break; + } + } + if (propIndex < 0) continue; + void* propAddr = instance->GetAddressOfProperty(propIndex); + if (!propAddr) continue; + + try { + if (propTypeId == floatTypeId) { + *reinterpret_cast(propAddr) = std::stof(raw); + } else if (propTypeId == intTypeId) { + *reinterpret_cast(propAddr) = std::stoi(raw); + } else if (propTypeId == boolTypeId) { + bool b = false; + if (ParseOverrideBool(raw, b)) { + *reinterpret_cast(propAddr) = b; + } + } else if (propTypeId == stringTypeId) { + *reinterpret_cast(propAddr) = raw; + } + } catch (...) { + // Ignore parse errors; leave the script value as-is. + } + } +} + Application::EntityScriptModule* Application::GetEntityScriptModule(const std::string& path) { if (path.empty()) { @@ -334,6 +395,7 @@ void Application::UpdateEntityScripts(float deltaTime) if (moduleInfo->initFunc) { scriptEngine.CallObjectMethod(moduleInfo->initFunc, inst, static_cast(entity), 0.0f); } + ApplyScriptOverrides(scriptEngine, script, inst); } else { // Fallback: call free-function init if exists if (moduleInfo->initFunc) { diff --git a/src/SceneLoader.cpp b/src/SceneLoader.cpp index d731d96..791700f 100644 --- a/src/SceneLoader.cpp +++ b/src/SceneLoader.cpp @@ -79,6 +79,8 @@ struct SceneEntityDef { bool hasScript = false; std::string scriptPath; bool scriptEnabled = true; + std::string scriptClass; + std::unordered_map scriptOverrides; }; static std::string Trim(const std::string& value) { @@ -157,6 +159,18 @@ static bool ParseString(const std::string& value, std::string& out) { return !out.empty(); } +static bool ParseScriptOverrideValue(const std::string& value, std::string& out) { + // Preserve raw text for later type-aware parsing on apply. + std::string trimmed = Trim(value); + if (trimmed.empty()) return false; + if (trimmed.size() >= 2 && trimmed.front() == '"' && trimmed.back() == '"') { + out = trimmed.substr(1, trimmed.size() - 2); + return true; + } + out = trimmed; + return true; +} + static bool ParseBool(const std::string& value, bool& out) { std::string trimmed = Trim(value); std::string lower; @@ -376,6 +390,17 @@ entt::entity LoadSceneFromFile(const std::string& path, bool clearExisting) { if (ParseBool(value, current->scriptEnabled)) { current->hasScript = true; } + } else if (key == "script_class") { + if (ParseString(value, current->scriptClass)) { + current->hasScript = true; + } + } else if (key.rfind("script_var_", 0) == 0) { + std::string fieldName = key.substr(std::string("script_var_").size()); + std::string rawValue; + if (ParseScriptOverrideValue(value, rawValue)) { + current->scriptOverrides[fieldName] = rawValue; + current->hasScript = true; + } } else { log_warn("Scene parse: unknown key '%s' at line %d", key.c_str(), lineNumber); } @@ -451,6 +476,8 @@ entt::entity LoadSceneFromFile(const std::string& path, bool clearExisting) { script.scriptPath = def.scriptPath; script.enabled = def.scriptEnabled; script.started = false; + script.className = def.scriptClass; + script.scriptOverrides = def.scriptOverrides; } } @@ -619,6 +646,14 @@ bool SaveSceneToFile(const std::string& path) { if (!script->enabled) { file << "script_enabled = false\n"; } + if (!script->className.empty()) { + file << "script_class = \"" << EscapeString(script->className) << "\"\n"; + } + for (const auto& entry : script->scriptOverrides) { + if (entry.first.empty()) continue; + file << "script_var_" << entry.first << " = "; + file << '"' << EscapeString(entry.second) << '"' << "\n"; + } } file << "\n"; diff --git a/src/gui/GuiManager.cpp b/src/gui/GuiManager.cpp index c1ece9d..8b30be5 100644 --- a/src/gui/GuiManager.cpp +++ b/src/gui/GuiManager.cpp @@ -1075,6 +1075,13 @@ void GuiManager::RenderScriptEditableControls(entt::entity entity) auto *obj = reinterpret_cast(script.scriptInstance); if (!obj) return; + // If the script instance changed (hot reload or reassign), drop staged values + auto instIt = scriptEditableInstancePtr.find(entity); + if (instIt == scriptEditableInstancePtr.end() || instIt->second != script.scriptInstance) { + scriptEditableStaged.erase(entity); + scriptEditableInstancePtr[entity] = script.scriptInstance; + } + asITypeInfo *objType = obj->GetObjectType(); if (!objType) return; asIScriptEngine *engine = obj->GetEngine(); @@ -1120,24 +1127,33 @@ void GuiManager::RenderScriptEditableControls(entt::entity entity) staged.kind = ScriptValueKind::Float; staged.f = *reinterpret_cast(propAddr); staged.hasValue = true; + staged.baselineF = staged.f; + staged.hasBaseline = true; } else if (propertyTypeId == intTypeId) { staged.kind = ScriptValueKind::Int; staged.i = *reinterpret_cast(propAddr); staged.hasValue = true; + staged.baselineI = staged.i; + staged.hasBaseline = true; } else if (propertyTypeId == boolTypeId) { staged.kind = ScriptValueKind::Bool; staged.b = *reinterpret_cast(propAddr); staged.hasValue = true; + staged.baselineB = staged.b; + staged.hasBaseline = true; } else if (propertyTypeId == stringTypeId) { staged.kind = ScriptValueKind::String; staged.s = *reinterpret_cast(propAddr); staged.hasValue = true; + staged.baselineS = staged.s; + staged.hasBaseline = true; } else { continue; } } ImGui::PushID(field.name.c_str()); + bool changed = false; if (staged.kind == ScriptValueKind::Float) { if (!field.options.empty()) { int currentIndex = 0; @@ -1148,14 +1164,15 @@ void GuiManager::RenderScriptEditableControls(entt::entity entity) currentIndex = std::clamp(currentIndex, 0, maxIndex); if (ImGui::SliderInt(field.name.c_str(), ¤tIndex, 0, maxIndex)) { staged.f = static_cast(currentIndex); + changed = true; } } else if (field.hasRange) { if (ImGui::SliderFloat(field.name.c_str(), &staged.f, field.rangeMin, field.rangeMax)) { - staged.hasValue = true; + changed = true; } } else { if (ImGui::DragFloat(field.name.c_str(), &staged.f, 0.1f)) { - staged.hasValue = true; + changed = true; } } } else if (staged.kind == ScriptValueKind::Int) { @@ -1164,21 +1181,27 @@ void GuiManager::RenderScriptEditableControls(entt::entity entity) int maxIndex = static_cast(field.options.size()) - 1; if (maxIndex < 0) maxIndex = 0; currentIndex = std::clamp(currentIndex, 0, maxIndex); - if (ImGui::SliderInt(field.name.c_str(), ¤tIndex, 0, maxIndex)) { + if (ImGui::Combo(field.name.c_str(), ¤tIndex, [](void *data, int idx, const char **outText) { + auto *opts = reinterpret_cast *>(data); + if (idx < 0 || idx >= static_cast(opts->size())) return false; + *outText = (*opts)[idx].c_str(); + return true; + }, (void *)&field.options, static_cast(field.options.size()))) { staged.i = currentIndex; + changed = true; } } else if (field.hasRange) { if (ImGui::SliderInt(field.name.c_str(), &staged.i, static_cast(field.rangeMin), static_cast(field.rangeMax))) { - staged.hasValue = true; + changed = true; } } else { if (ImGui::DragInt(field.name.c_str(), &staged.i, 1.0f)) { - staged.hasValue = true; + changed = true; } } } else if (staged.kind == ScriptValueKind::Bool) { if (ImGui::Checkbox(field.name.c_str(), &staged.b)) { - staged.hasValue = true; + changed = true; } } else if (staged.kind == ScriptValueKind::String) { if (!field.options.empty()) { @@ -1197,6 +1220,7 @@ void GuiManager::RenderScriptEditableControls(entt::entity entity) }, (void *)&field.options, static_cast(field.options.size()))) { if (currentIndex >= 0 && currentIndex < static_cast(field.options.size())) { staged.s = field.options[currentIndex]; + changed = true; } } } else { @@ -1204,51 +1228,54 @@ void GuiManager::RenderScriptEditableControls(entt::entity entity) std::snprintf(buffer, sizeof(buffer), "%s", staged.s.c_str()); if (ImGui::InputText(field.name.c_str(), buffer, sizeof(buffer))) { staged.s = buffer; - staged.hasValue = true; + changed = true; + } + } + } + + ImGui::SameLine(); + if (ImGui::SmallButton(ICON_FA_ROTATE_LEFT)) { + if (staged.kind == ScriptValueKind::Float && staged.hasBaseline) { + staged.f = staged.baselineF; + } else if (staged.kind == ScriptValueKind::Int && staged.hasBaseline) { + staged.i = staged.baselineI; + } else if (staged.kind == ScriptValueKind::Bool && staged.hasBaseline) { + staged.b = staged.baselineB; + } else if (staged.kind == ScriptValueKind::String && staged.hasBaseline) { + staged.s = staged.baselineS; + } + changed = true; + } + + if (changed) { + if (propertyTypeId == floatTypeId && staged.kind == ScriptValueKind::Float) { + *reinterpret_cast(propAddr) = staged.f; + script.scriptOverrides[field.name] = std::to_string(staged.f); + } else if (propertyTypeId == intTypeId && staged.kind == ScriptValueKind::Int) { + *reinterpret_cast(propAddr) = staged.i; + script.scriptOverrides[field.name] = std::to_string(staged.i); + } else if (propertyTypeId == boolTypeId && staged.kind == ScriptValueKind::Bool) { + *reinterpret_cast(propAddr) = staged.b; + script.scriptOverrides[field.name] = staged.b ? "true" : "false"; + } else if (propertyTypeId == stringTypeId && staged.kind == ScriptValueKind::String) { + *reinterpret_cast(propAddr) = staged.s; + script.scriptOverrides[field.name] = staged.s; + } + + // If reset was clicked and we returned to baseline, clear overrides + if (staged.hasBaseline) { + bool atBaseline = false; + if (staged.kind == ScriptValueKind::Float) atBaseline = (staged.f == staged.baselineF); + else if (staged.kind == ScriptValueKind::Int) atBaseline = (staged.i == staged.baselineI); + else if (staged.kind == ScriptValueKind::Bool) atBaseline = (staged.b == staged.baselineB); + else if (staged.kind == ScriptValueKind::String) atBaseline = (staged.s == staged.baselineS); + if (atBaseline) { + script.scriptOverrides.erase(field.name); } } } ImGui::PopID(); } - - if (ImGui::Button("Apply")) { - for (const auto &field : cache.fields) { - auto it = stagedMap.find(field.name); - if (it == stagedMap.end()) continue; - ScriptEditableValue &staged = it->second; - if (!staged.hasValue) continue; - - int propertyIndex = -1; - int propertyTypeId = 0; - const int propertyCount = static_cast(obj->GetPropertyCount()); - for (int i = 0; i < propertyCount; ++i) { - const char *propName = obj->GetPropertyName(i); - if (propName && field.name == propName) { - propertyIndex = i; - propertyTypeId = obj->GetPropertyTypeId(i); - break; - } - } - if (propertyIndex < 0) continue; - void *propAddr = obj->GetAddressOfProperty(propertyIndex); - if (!propAddr) continue; - - if (propertyTypeId == floatTypeId && staged.kind == ScriptValueKind::Float) { - *reinterpret_cast(propAddr) = staged.f; - } else if (propertyTypeId == intTypeId && staged.kind == ScriptValueKind::Int) { - *reinterpret_cast(propAddr) = staged.i; - } else if (propertyTypeId == boolTypeId && staged.kind == ScriptValueKind::Bool) { - *reinterpret_cast(propAddr) = staged.b; - } else if (propertyTypeId == stringTypeId && staged.kind == ScriptValueKind::String) { - *reinterpret_cast(propAddr) = staged.s; - } - } - } - ImGui::SameLine(); - if (ImGui::Button("Reset")) { - stagedMap.clear(); - } - ImGui::PopID(); } From 8041286a9d6deed50be856de05592d2fdbb87ad9 Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Mon, 9 Mar 2026 13:51:45 +1300 Subject: [PATCH 46/53] feat: tool tips and groups for editable properties --- imgui.ini | 2 +- include/gui/GuiManager.h | 2 ++ scripts/ball.as | 8 +++-- src/gui/GuiManager.cpp | 63 ++++++++++++++++++++++++++++++++-------- 4 files changed, 59 insertions(+), 16 deletions(-) diff --git a/imgui.ini b/imgui.ini index 39837fe..7b72388 100644 --- a/imgui.ini +++ b/imgui.ini @@ -10,7 +10,7 @@ Collapsed=0 [Window][Game Window] Pos=232,28 -Size=663,580 +Size=1040,580 Collapsed=0 DockId=0x00000004,0 diff --git a/include/gui/GuiManager.h b/include/gui/GuiManager.h index 997551d..dff5458 100644 --- a/include/gui/GuiManager.h +++ b/include/gui/GuiManager.h @@ -36,6 +36,8 @@ private: struct ScriptEditableFieldMeta { std::string name; std::string type; + std::string group; + std::string description; bool hasRange = false; float rangeMin = 0.0f; float rangeMax = 1.0f; diff --git a/scripts/ball.as b/scripts/ball.as index 60a9848..b94dcec 100644 --- a/scripts/ball.as +++ b/scripts/ball.as @@ -6,11 +6,13 @@ class EntityScript float baseX; float baseY; float baseZ; - [editable][range[0,1]]float phase; + [group["Movement"]][desc["Phase accumulator for the sine wave"]][editable][range[0,1]]float phase; // per-instance movement parameters (can be tuned per-entity) - [editable][range[0,10]]float amplitude = 2.5f; - [editable][range[0,10]]float speed = 2.5f; + [group["Movement"]][desc["Bounce height"]][editable][range[0,10]]float amplitude = 2.5f; + [group["Movement"]][desc["Cycles per second"]][editable][range[0,10]]float speed = 2.5f; + + [group["State"]][desc["Debug animation state"]][editable][options[Idle,Walk,Run]] int state = 0; EntityScript() { diff --git a/src/gui/GuiManager.cpp b/src/gui/GuiManager.cpp index 8b30be5..8ed4395 100644 --- a/src/gui/GuiManager.cpp +++ b/src/gui/GuiManager.cpp @@ -924,6 +924,14 @@ static std::string TrimString(const std::string &value) return value.substr(start, end - start + 1); } +static std::string UnquoteString(const std::string &value) +{ + if (value.size() >= 2 && value.front() == '"' && value.back() == '"') { + return value.substr(1, value.size() - 2); + } + return value; +} + static bool ExtractTagContent(const std::string &line, const std::string &tag, std::string &out) { std::string needle = "[" + tag + "["; @@ -1022,6 +1030,8 @@ GuiManager::ScriptEditableCache &GuiManager::GetOrParseEditableCache(const std:: meta.hasRange = false; meta.rangeMin = 0.0f; meta.rangeMax = 1.0f; + meta.group.clear(); + meta.description.clear(); std::string rangeContent; if (ExtractTagContent(line, "range", rangeContent)) { @@ -1034,6 +1044,16 @@ GuiManager::ScriptEditableCache &GuiManager::GetOrParseEditableCache(const std:: } } + std::string groupContent; + if (ExtractTagContent(line, "group", groupContent)) { + meta.group = UnquoteString(TrimString(groupContent)); + } + + std::string descContent; + if (ExtractTagContent(line, "desc", descContent)) { + meta.description = UnquoteString(TrimString(descContent)); + } + std::string optionsContent; if (ExtractTagContent(line, "options", optionsContent)) { meta.options = SplitOptions(optionsContent); @@ -1104,7 +1124,20 @@ void GuiManager::RenderScriptEditableControls(entt::entity entity) auto &stagedMap = scriptEditableStaged[entity]; + std::string currentGroup; + bool groupOpen = true; for (const auto &field : cache.fields) { + if (field.group != currentGroup) { + currentGroup = field.group; + if (!currentGroup.empty()) { + groupOpen = ImGui::CollapsingHeader(currentGroup.c_str(), ImGuiTreeNodeFlags_DefaultOpen); + } else { + groupOpen = true; + } + } + if (!groupOpen) { + continue; + } int propertyIndex = -1; int propertyTypeId = 0; const int propertyCount = static_cast(obj->GetPropertyCount()); @@ -1154,6 +1187,20 @@ void GuiManager::RenderScriptEditableControls(entt::entity entity) ImGui::PushID(field.name.c_str()); bool changed = false; + if (ImGui::SmallButton(ICON_FA_ROTATE_LEFT)) { + if (staged.kind == ScriptValueKind::Float && staged.hasBaseline) { + staged.f = staged.baselineF; + } else if (staged.kind == ScriptValueKind::Int && staged.hasBaseline) { + staged.i = staged.baselineI; + } else if (staged.kind == ScriptValueKind::Bool && staged.hasBaseline) { + staged.b = staged.baselineB; + } else if (staged.kind == ScriptValueKind::String && staged.hasBaseline) { + staged.s = staged.baselineS; + } + changed = true; + } + ImGui::SameLine(); + if (staged.kind == ScriptValueKind::Float) { if (!field.options.empty()) { int currentIndex = 0; @@ -1233,18 +1280,10 @@ void GuiManager::RenderScriptEditableControls(entt::entity entity) } } - ImGui::SameLine(); - if (ImGui::SmallButton(ICON_FA_ROTATE_LEFT)) { - if (staged.kind == ScriptValueKind::Float && staged.hasBaseline) { - staged.f = staged.baselineF; - } else if (staged.kind == ScriptValueKind::Int && staged.hasBaseline) { - staged.i = staged.baselineI; - } else if (staged.kind == ScriptValueKind::Bool && staged.hasBaseline) { - staged.b = staged.baselineB; - } else if (staged.kind == ScriptValueKind::String && staged.hasBaseline) { - staged.s = staged.baselineS; - } - changed = true; + if (!field.description.empty() && ImGui::IsItemHovered()) { + ImGui::BeginTooltip(); + ImGui::TextUnformatted(field.description.c_str()); + ImGui::EndTooltip(); } if (changed) { From d7add3964db9049e963ee18a16775e4a4c98e2c2 Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Mon, 9 Mar 2026 17:37:29 +1300 Subject: [PATCH 47/53] feat: additonal components, updated docs --- CMakeLists.txt | 1 + docs/Editor.md | 3 + docs/Scenegraph.md | 19 ++++- docs/Scripting.md | 30 +++++++ imgui.ini | 2 +- include/Application.h | 2 + include/ECSComponents.h | 23 ++++++ include/SceneLoader.h | 3 +- include/TextureManager.h | 38 +++++++++ include/scripting/ResourceBindings.h | 3 +- scenes/demo.toml | 11 +-- src/Application.cpp | 118 ++++++++++++++++++--------- src/SceneLoader.cpp | 115 +++++++++++++++++++++++++- src/TextureManager.cpp | 74 +++++++++++++++++ src/gui/GuiManager.cpp | 54 +++++++++++- src/scripting/ECSBindings.cpp | 117 ++++++++++++++++++++++++++ src/scripting/InputBindings.cpp | 68 +++++++++++++++ src/scripting/ResourceBindings.cpp | 28 ++++++- tests/resource_tests.cpp | 4 +- tests/scenegraph_tests.cpp | 4 +- 20 files changed, 666 insertions(+), 51 deletions(-) create mode 100644 include/TextureManager.h create mode 100644 src/TextureManager.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 26b4f72..ee5ee99 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -99,6 +99,7 @@ add_library(simian_core STATIC src/ShaderManager.cpp src/ModelManager.cpp src/MaterialManager.cpp + src/TextureManager.cpp src/InputManager.cpp ) diff --git a/docs/Editor.md b/docs/Editor.md index 7ac5a7e..40b7145 100644 --- a/docs/Editor.md +++ b/docs/Editor.md @@ -53,6 +53,8 @@ This document outlines the in-app editor UI, its panels, and common workflows. - Transform: position, scale, rotation (degrees in UI). - Velocity: linear and angular velocity. - Sprite: model id, shader id, color, outline. +- Texture: texture id. +- UV Transform: scale, offset, rotation (radians). - Script: per-entity script path and enabled toggle. - Camera: position, target, up, FOV, projection, helper actions. - Light: direction, color, intensity, helper presets. @@ -77,6 +79,7 @@ This document outlines the in-app editor UI, its panels, and common workflows. - Scene Save and Load use file path text fields. - Component IDs are numeric and map to runtime resource managers. - World Transform is computed from hierarchy and local transforms and is read-only. +- UV Transform values are passed as shader uniforms `uvScale`, `uvOffset`, and `uvRotation` when present. ## Scene Scripts diff --git a/docs/Scenegraph.md b/docs/Scenegraph.md index 8db1e67..433d5a2 100644 --- a/docs/Scenegraph.md +++ b/docs/Scenegraph.md @@ -40,6 +40,8 @@ bool has = ECS::HasParent(child); Scenes are stored in `scenes/*.toml` using a minimal TOML-like structure. Example: ```toml +scene_script = "scripts/scene.as" + [[entity]] id = "root" tag = "Root" @@ -57,6 +59,9 @@ model_size = [1.0, 1.0, 1.0] color = 0x00FF00FF shader_vs = "shaders/toon.vs" shader_fs = "shaders/toon.fs" +texture = "assets/textures/grid.png" +uv_scale = [2.0, 2.0] +uv_offset = [0.0, 0.0] [[entity]] id = "child" @@ -72,6 +77,7 @@ shader_fs = "shaders/toon.fs" ### Supported Keys +- `scene_script` (string) — scene-level script path (outside entity blocks) - `id` (string) — unique identifier for parent links - `parent` (string) — parent entity id - `tag` (string) — `Tag` component value @@ -79,11 +85,22 @@ shader_fs = "shaders/toon.fs" - `rotation` (radians) or `rotation_deg` (degrees) - `scale` (vec3) - `model` — `cube`, `sphere`, `plane`, or file path +- `model_id` (int) — numeric model id - `model_size` (vec3) for cubes/planes - `radius`, `rings`, `slices` for spheres - `color` — hex `0xRRGGBBAA` (matches script colors) - `outline_size` — optional sprite outline - `shader_vs`, `shader_fs` — optional shader paths +- `shader_id` (int) — numeric shader id +- `texture` (string) — texture path +- `texture_id` (int) — numeric texture id +- `uv_scale` (vec2) +- `uv_offset` (vec2) +- `uv_rotation` (radians) +- `script` (string) — per-entity script path +- `script_enabled` (bool) +- `script_class` (string) +- `script_var_*` (string) — per-field overrides for script-editable values ## Loading a Scene @@ -95,4 +112,4 @@ uint root = Scene::Load("scenes/demo.toml"); ## Editor -Run the app with `--editor` to open the ImGui editor. The **Scene** window shows the hierarchy tree, supports drag-and-drop reparenting, and lets you create/delete entities. The **Inspector** window shows `Tag`, `ECSTransform`, and `Sprite` for the selected entity and allows live editing. +Run the app with `--editor` to open the ImGui editor. The **Scene** window shows the hierarchy tree, supports drag-and-drop reparenting, and lets you create/delete entities. The **Inspector** window shows components for the selected entity and allows live editing. diff --git a/docs/Scripting.md b/docs/Scripting.md index 3e0061f..fb96d92 100644 --- a/docs/Scripting.md +++ b/docs/Scripting.md @@ -6,6 +6,36 @@ This page is a starting point for scripting documentation. - Scripts live in `scripts/` and are executed by AngelScript. - Predefined API and engine bindings are declared in `scripts/as.predefined`. +## Input Actions +- Query input with `IsActionPressed`, `IsActionDown`, `IsActionReleased`, and `GetActionStrength`. +- Register and bind at runtime with `RegisterAction`, `BindKeyboard`, `BindMouseButton`, `BindGamepadButton`, and `BindGamepadAxis`. +- Enums: `Key`, `MouseButton`, `GamepadButton`, `GamepadAxis`. + +Example: + +```angelscript +RegisterAction("boost"); +BindKeyboard("boost", Key::LEFT_CONTROL); +BindGamepadButton("boost", 0, GamepadButton::RIGHT_TRIGGER_1); + +RegisterAction("zoom"); +BindGamepadAxis("zoom", 0, GamepadAxis::RIGHT_TRIGGER, 0.2f, false); +``` + +## ECS Texture + UV +- Texture and UV helpers live under the `ECS::` namespace. +- Texture: `AddTexture`, `SetTextureId`, `GetTextureId`, `HasTexture`, `RemoveTexture`. +- UV Transform: `AddUVTransform`, `SetUVScale`, `SetUVOffset`, `SetUVRotation`, `HasUVTransform`, `RemoveUVTransform`. + +Example: + +```angelscript +uint e = ECS::CreateEntity(); +ECS::AddTexture(e, texId); +ECS::AddUVTransform(e, 2.0f, 2.0f, 0.0f, 0.0f, 0.0f); +ECS::SetUVOffset(e, 0.25f, 0.0f); +``` + ## Examples - `scripts/game.as` — demo showing ECS usage, rendering, scenegraph and input actions. diff --git a/imgui.ini b/imgui.ini index 7b72388..39837fe 100644 --- a/imgui.ini +++ b/imgui.ini @@ -10,7 +10,7 @@ Collapsed=0 [Window][Game Window] Pos=232,28 -Size=1040,580 +Size=663,580 Collapsed=0 DockId=0x00000004,0 diff --git a/include/Application.h b/include/Application.h index 22751ec..2106ee8 100644 --- a/include/Application.h +++ b/include/Application.h @@ -6,6 +6,7 @@ #include "ShaderManager.h" #include "ModelManager.h" #include "MaterialManager.h" +#include "TextureManager.h" #include "InputManager.h" #include #include @@ -58,6 +59,7 @@ private: ShaderManager shaderManager; ModelManager modelManager; MaterialManager materialManager; + TextureManager textureManager; InputManager inputManager; std::unordered_map entityScriptModules; std::unordered_map entityScriptBindings; diff --git a/include/ECSComponents.h b/include/ECSComponents.h index 01daaf7..80717d3 100644 --- a/include/ECSComponents.h +++ b/include/ECSComponents.h @@ -49,6 +49,29 @@ struct Sprite { : modelId(model), color(col), outlineSize(outline), shaderId(shader) {} }; +// Texture component - material texture reference +struct TextureComponent { + unsigned int textureId; + + TextureComponent() : textureId(0) {} + TextureComponent(unsigned int id) : textureId(id) {} +}; + +// UV transform component - tiling and offset for texture sampling +struct UVTransform { + Vector2 scale; + Vector2 offset; + float rotation; + + UVTransform() + : scale{1.0f, 1.0f} + , offset{0.0f, 0.0f} + , rotation(0.0f) {} + + UVTransform(Vector2 s, Vector2 o = {0.0f, 0.0f}, float r = 0.0f) + : scale(s), offset(o), rotation(r) {} +}; + // Tag component - simple string identifier struct Tag { std::string name; diff --git a/include/SceneLoader.h b/include/SceneLoader.h index b5497d1..7f940ce 100644 --- a/include/SceneLoader.h +++ b/include/SceneLoader.h @@ -5,10 +5,11 @@ class ModelManager; class ShaderManager; +class TextureManager; // Set global context used by scene loading -void SetSceneContext(entt::registry* registry, ModelManager* modelManager, ShaderManager* shaderManager); +void SetSceneContext(entt::registry* registry, ModelManager* modelManager, ShaderManager* shaderManager, TextureManager* textureManager); // Load a scene from a TOML-like file. Returns the root entity (or entt::null on failure). entt::entity LoadSceneFromFile(const std::string& path, bool clearExisting); diff --git a/include/TextureManager.h b/include/TextureManager.h new file mode 100644 index 0000000..e94ac81 --- /dev/null +++ b/include/TextureManager.h @@ -0,0 +1,38 @@ +#pragma once + +#include "raylib.h" +#include +#include + +struct TextureSource { + std::string path; +}; + +class TextureManager +{ +public: + TextureManager(); + ~TextureManager(); + + // Load a texture from a file + // Returns a unique ID for the texture, or 0 on failure + unsigned int Load(const std::string& path); + + // Unload a texture by ID + void Unload(unsigned int id); + + // Get a texture by ID (returns nullptr if not found) + Texture2D* Get(unsigned int id); + + // Get source metadata for a texture if available + const TextureSource* GetSource(unsigned int id) const; + + // Unload all textures + void UnloadAll(); + +private: + std::unordered_map textures; + std::unordered_map textureSources; + unsigned int nextId; + bool unloaded; +}; diff --git a/include/scripting/ResourceBindings.h b/include/scripting/ResourceBindings.h index c76c467..36150e4 100644 --- a/include/scripting/ResourceBindings.h +++ b/include/scripting/ResourceBindings.h @@ -4,6 +4,7 @@ class asIScriptEngine; class ShaderManager; class ModelManager; class MaterialManager; +class TextureManager; -void SetResourceManagers(ShaderManager* shaderMgr, ModelManager* modelMgr, MaterialManager* materialMgr); +void SetResourceManagers(ShaderManager* shaderMgr, ModelManager* modelMgr, MaterialManager* materialMgr, TextureManager* textureMgr); void RegisterResourceBindings(asIScriptEngine *engine); diff --git a/scenes/demo.toml b/scenes/demo.toml index 0546022..cae0739 100644 --- a/scenes/demo.toml +++ b/scenes/demo.toml @@ -23,7 +23,7 @@ shader_fs = "shaders/toon.fs" id = "entity_3" parent = "entity_2" tag = "Child" -position = [0.000, 3.571, 0.000] +position = [0.500, 1.248, 1.600] scale = [0.600, 0.600, 0.600] rotation_deg = 0.000 model = "sphere" @@ -35,12 +35,13 @@ outline_size = 0.000 shader_vs = "shaders/toon.vs" shader_fs = "shaders/toon.fs" script = "scripts/ball.as" +script_var_amplitude = "1.452000" [[entity]] id = "entity_6" parent = "entity_2" tag = "Child 2" -position = [0.000, 1.634, 1.900] +position = [0.000, 0.587, 1.900] scale = [1.000, 1.000, 1.000] rotation_deg = 0.000 model = "sphere" @@ -52,7 +53,7 @@ outline_size = 0.000 shader_vs = "shaders/toon.vs" shader_fs = "shaders/toon.fs" script = "scripts/ball.as" -script_var_speed = "8.352000" -script_var_amplitude = "0.491000" -script_var_phase = "0.576000" +script_var_speed = "10.000000" +script_var_phase = "0.472000" +script_var_amplitude = "0.568000" diff --git a/src/Application.cpp b/src/Application.cpp index e10e3b4..5f15c64 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -82,11 +82,11 @@ bool Application::Initialize(int argc, char *argv[]) SetGlobalRegistry(®istry); // Set up resource managers for script access - extern void SetResourceManagers(ShaderManager*, ModelManager*, MaterialManager*); - SetResourceManagers(&shaderManager, &modelManager, &materialManager); + extern void SetResourceManagers(ShaderManager*, ModelManager*, MaterialManager*, TextureManager*); + SetResourceManagers(&shaderManager, &modelManager, &materialManager, &textureManager); // Set up scene loader context - SetSceneContext(®istry, &modelManager, &shaderManager); + SetSceneContext(®istry, &modelManager, &shaderManager, &textureManager); // Set up input manager for script access extern void SetGlobalInputManager(InputManager*); @@ -609,43 +609,86 @@ void Application::RenderScene() // Render all entities with WorldTransform and Sprite components auto view = registry.view(); - view.each([&](auto& transform, auto& sprite) { - if (sprite.modelId > 0) { - Model* model = modelManager.Get(static_cast(sprite.modelId)); - if (model) { - // If sprite has a shader, apply it with uniforms - if (sprite.shaderId > 0) { - Shader* shader = shaderManager.Get(static_cast(sprite.shaderId)); - if (shader) { - // Set shader uniforms - int albedoLoc = GetShaderLocation(*shader, "albedo"); - int lightDirLoc = GetShaderLocation(*shader, "lightDir"); - - if (albedoLoc != -1) { - Vector4 albedo = { - sprite.color.r / 255.0f, - sprite.color.g / 255.0f, - sprite.color.b / 255.0f, - sprite.color.a / 255.0f - }; - SetShaderValue(*shader, albedoLoc, &albedo, SHADER_UNIFORM_VEC4); - } - - if (lightDirLoc != -1) { - SetShaderValue(*shader, lightDirLoc, &lightDir, SHADER_UNIFORM_VEC3); - } - - // Assign shader to model's first material - model->materials[0].shader = *shader; - } + view.each([&](auto entity, auto& transform, auto& sprite) { + if (sprite.modelId <= 0) { + return; + } + + Model* model = modelManager.Get(static_cast(sprite.modelId)); + if (!model) { + return; + } + + Texture2D originalTexture = {}; + bool restoreTexture = false; + if (auto* tex = registry.try_get(entity)) { + if (tex->textureId > 0) { + Texture2D* texture = textureManager.Get(tex->textureId); + if (texture && model->materialCount > 0) { + originalTexture = model->materials[0].maps[MATERIAL_MAP_DIFFUSE].texture; + model->materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = *texture; + restoreTexture = true; } - - // Draw model using Sprite.color as the tint - DrawModelEx(*model, transform.position, Vector3{0, 1, 0}, - transform.rotation * RAD2DEG, transform.scale, - sprite.color); } } + + // If sprite has a shader, apply it with uniforms + if (sprite.shaderId > 0) { + Shader* shader = shaderManager.Get(static_cast(sprite.shaderId)); + if (shader) { + // Set shader uniforms + int albedoLoc = GetShaderLocation(*shader, "albedo"); + int lightDirLoc = GetShaderLocation(*shader, "lightDir"); + + if (albedoLoc != -1) { + Vector4 albedo = { + sprite.color.r / 255.0f, + sprite.color.g / 255.0f, + sprite.color.b / 255.0f, + sprite.color.a / 255.0f + }; + SetShaderValue(*shader, albedoLoc, &albedo, SHADER_UNIFORM_VEC4); + } + + if (lightDirLoc != -1) { + SetShaderValue(*shader, lightDirLoc, &lightDir, SHADER_UNIFORM_VEC3); + } + + Vector2 uvScale = {1.0f, 1.0f}; + Vector2 uvOffset = {0.0f, 0.0f}; + float uvRotation = 0.0f; + if (auto* uv = registry.try_get(entity)) { + uvScale = uv->scale; + uvOffset = uv->offset; + uvRotation = uv->rotation; + } + + int uvScaleLoc = GetShaderLocation(*shader, "uvScale"); + if (uvScaleLoc != -1) { + SetShaderValue(*shader, uvScaleLoc, &uvScale, SHADER_UNIFORM_VEC2); + } + int uvOffsetLoc = GetShaderLocation(*shader, "uvOffset"); + if (uvOffsetLoc != -1) { + SetShaderValue(*shader, uvOffsetLoc, &uvOffset, SHADER_UNIFORM_VEC2); + } + int uvRotationLoc = GetShaderLocation(*shader, "uvRotation"); + if (uvRotationLoc != -1) { + SetShaderValue(*shader, uvRotationLoc, &uvRotation, SHADER_UNIFORM_FLOAT); + } + + // Assign shader to model's first material + model->materials[0].shader = *shader; + } + } + + // Draw model using Sprite.color as the tint + DrawModelEx(*model, transform.position, Vector3{0, 1, 0}, + transform.rotation * RAD2DEG, transform.scale, + sprite.color); + + if (restoreTexture) { + model->materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = originalTexture; + } }); EndMode3D(); @@ -716,6 +759,7 @@ void Application::Shutdown() materialManager.Clear(); shaderManager.UnloadAll(); modelManager.UnloadAll(); + textureManager.UnloadAll(); // Clear the trace log callback before closing window to prevent logging after cleanup SetTraceLogCallback(nullptr); diff --git a/src/SceneLoader.cpp b/src/SceneLoader.cpp index 791700f..9787291 100644 --- a/src/SceneLoader.cpp +++ b/src/SceneLoader.cpp @@ -3,6 +3,7 @@ #include "ModelManager.h" #include "ShaderManager.h" #include "SceneGraph.h" +#include "TextureManager.h" #include "log/log.h" #include "raylib.h" #include "entt.hpp" @@ -17,13 +18,15 @@ static entt::registry* g_sceneRegistry = nullptr; static ModelManager* g_sceneModelManager = nullptr; static ShaderManager* g_sceneShaderManager = nullptr; +static TextureManager* g_sceneTextureManager = nullptr; static std::string g_sceneScriptPath; static bool g_sceneScriptDirty = false; -void SetSceneContext(entt::registry* registry, ModelManager* modelManager, ShaderManager* shaderManager) { +void SetSceneContext(entt::registry* registry, ModelManager* modelManager, ShaderManager* shaderManager, TextureManager* textureManager) { g_sceneRegistry = registry; g_sceneModelManager = modelManager; g_sceneShaderManager = shaderManager; + g_sceneTextureManager = textureManager; } void ClearScene() { @@ -81,6 +84,15 @@ struct SceneEntityDef { bool scriptEnabled = true; std::string scriptClass; std::unordered_map scriptOverrides; + + bool hasTexture = false; + std::string texturePath; + unsigned int textureId = 0; + bool hasTextureId = false; + bool hasUV = false; + Vector2 uvScale{1.0f, 1.0f}; + Vector2 uvOffset{0.0f, 0.0f}; + float uvRotation = 0.0f; }; static std::string Trim(const std::string& value) { @@ -132,6 +144,29 @@ static bool ParseVec3(const std::string& value, Vector3& out) { return true; } +static bool ParseVec2(const std::string& value, Vector2& out) { + std::string trimmed = Trim(value); + if (trimmed.size() < 5 || trimmed.front() != '[' || trimmed.back() != ']') { + return false; + } + + std::string inner = trimmed.substr(1, trimmed.size() - 2); + std::stringstream ss(inner); + std::string token; + float vals[2] = {0.0f, 0.0f}; + int count = 0; + + while (std::getline(ss, token, ',')) { + if (count >= 2) break; + vals[count] = std::stof(Trim(token)); + count++; + } + + if (count != 2) return false; + out = {vals[0], vals[1]}; + return true; +} + static bool ParseHexColor(const std::string& value, unsigned int& out) { std::string trimmed = Trim(value); if (trimmed.rfind("0x", 0) == 0 || trimmed.rfind("0X", 0) == 0) { @@ -216,6 +251,14 @@ static std::string Vec3ToString(const Vector3& value) { return ss.str(); } +static std::string Vec2ToString(const Vector2& value) { + std::ostringstream ss; + ss << '[' + << FloatToString(value.x) << ", " + << FloatToString(value.y) << ']'; + return ss.str(); +} + static std::string ColorToHexString(Color color) { unsigned int packed = (static_cast(color.r) << 24) | (static_cast(color.g) << 16) @@ -275,6 +318,21 @@ static unsigned int LoadShaderFor(const SceneEntityDef& def, std::unordered_map< return shaderId; } +static unsigned int LoadTextureFor(const SceneEntityDef& def, std::unordered_map& textureCache) { + if (!g_sceneTextureManager || def.texturePath.empty()) return 0; + + auto cached = textureCache.find(def.texturePath); + if (cached != textureCache.end()) { + return cached->second; + } + + unsigned int textureId = g_sceneTextureManager->Load(def.texturePath); + if (textureId != 0) { + textureCache[def.texturePath] = textureId; + } + return textureId; +} + entt::entity LoadSceneFromFile(const std::string& path, bool clearExisting) { if (!g_sceneRegistry) { log_error("Scene loader not initialized (registry missing)"); @@ -382,6 +440,25 @@ entt::entity LoadSceneFromFile(const std::string& path, bool clearExisting) { current->shaderId = static_cast(std::stoul(value, nullptr, 0)); current->hasShaderId = true; current->hasSprite = true; + } else if (key == "texture") { + if (ParseString(value, current->texturePath)) { + current->hasTexture = true; + } + } else if (key == "texture_id") { + current->textureId = static_cast(std::stoul(value, nullptr, 0)); + current->hasTextureId = true; + current->hasTexture = true; + } else if (key == "uv_scale") { + if (ParseVec2(value, current->uvScale)) { + current->hasUV = true; + } + } else if (key == "uv_offset") { + if (ParseVec2(value, current->uvOffset)) { + current->hasUV = true; + } + } else if (key == "uv_rotation") { + current->uvRotation = std::stof(value); + current->hasUV = true; } else if (key == "script") { if (ParseString(value, current->scriptPath)) { current->hasScript = true; @@ -420,6 +497,7 @@ entt::entity LoadSceneFromFile(const std::string& path, bool clearExisting) { created.reserve(defs.size()); std::unordered_map modelCache; std::unordered_map shaderCache; + std::unordered_map textureCache; for (const auto& def : defs) { entt::entity entity = g_sceneRegistry->create(); @@ -471,6 +549,21 @@ entt::entity LoadSceneFromFile(const std::string& path, bool clearExisting) { g_sceneRegistry->emplace(entity, static_cast(modelId), col, def.outlineSize, shaderId); } + if (def.hasTexture) { + unsigned int textureId = 0; + if (!def.texturePath.empty()) { + textureId = LoadTextureFor(def, textureCache); + } + if (textureId == 0 && def.hasTextureId) { + textureId = def.textureId; + } + g_sceneRegistry->emplace(entity, textureId); + } + + if (def.hasUV) { + g_sceneRegistry->emplace(entity, def.uvScale, def.uvOffset, def.uvRotation); + } + if (def.hasScript || !def.scriptPath.empty()) { auto& script = g_sceneRegistry->emplace(entity); script.scriptPath = def.scriptPath; @@ -639,6 +732,26 @@ bool SaveSceneToFile(const std::string& path) { } } + if (auto* texture = registry.try_get(entity)) { + bool wroteTexture = false; + if (g_sceneTextureManager && texture->textureId > 0) { + const TextureSource* source = g_sceneTextureManager->GetSource(texture->textureId); + if (source && !source->path.empty()) { + file << "texture = \"" << EscapeString(source->path) << "\"\n"; + wroteTexture = true; + } + } + if (!wroteTexture && texture->textureId > 0) { + file << "texture_id = " << texture->textureId << "\n"; + } + } + + if (auto* uv = registry.try_get(entity)) { + file << "uv_scale = " << Vec2ToString(uv->scale) << "\n"; + file << "uv_offset = " << Vec2ToString(uv->offset) << "\n"; + file << "uv_rotation = " << FloatToString(uv->rotation) << "\n"; + } + if (auto* script = registry.try_get(entity)) { if (!script->scriptPath.empty()) { file << "script = \"" << EscapeString(script->scriptPath) << "\"\n"; diff --git a/src/TextureManager.cpp b/src/TextureManager.cpp new file mode 100644 index 0000000..d2baa77 --- /dev/null +++ b/src/TextureManager.cpp @@ -0,0 +1,74 @@ +#include "TextureManager.h" +#include "log/log.h" + +TextureManager::TextureManager() : nextId(1), unloaded(false) +{ +} + +TextureManager::~TextureManager() +{ + if (!unloaded) { + for (auto& pair : textures) { + UnloadTexture(pair.second); + } + textures.clear(); + textureSources.clear(); + } +} + +unsigned int TextureManager::Load(const std::string& path) +{ + Texture2D texture = LoadTexture(path.c_str()); + if (texture.id == 0) { + log_warn("Failed to load texture: %s", path.c_str()); + return 0; + } + + unsigned int id = nextId++; + textures[id] = texture; + textureSources[id] = TextureSource{path}; + log_info("Loaded texture id=%u from %s", id, path.c_str()); + return id; +} + +void TextureManager::Unload(unsigned int id) +{ + auto it = textures.find(id); + if (it != textures.end()) { + UnloadTexture(it->second); + textures.erase(it); + textureSources.erase(id); + log_info("Unloaded texture id=%u", id); + } +} + +Texture2D* TextureManager::Get(unsigned int id) +{ + auto it = textures.find(id); + if (it != textures.end()) { + return &it->second; + } + return nullptr; +} + +const TextureSource* TextureManager::GetSource(unsigned int id) const +{ + auto it = textureSources.find(id); + if (it != textureSources.end()) { + return &it->second; + } + return nullptr; +} + +void TextureManager::UnloadAll() +{ + if (!unloaded) { + for (auto& pair : textures) { + UnloadTexture(pair.second); + } + textures.clear(); + textureSources.clear(); + unloaded = true; + log_info("Unloaded all textures"); + } +} diff --git a/src/gui/GuiManager.cpp b/src/gui/GuiManager.cpp index 8ed4395..62b789d 100644 --- a/src/gui/GuiManager.cpp +++ b/src/gui/GuiManager.cpp @@ -529,7 +529,9 @@ void GuiManager::RenderInspectorWindow() {"Camera", 5}, {"Light", 6}, {"Material", 7}, - {"Render Pass", 8} + {"Render Pass", 8}, + {"Texture", 9}, + {"UV Transform", 10} }; auto hasComponent = [&](int id) { @@ -543,6 +545,8 @@ void GuiManager::RenderInspectorWindow() case 6: return registry.any_of(selectedEntity); case 7: return registry.any_of(selectedEntity); case 8: return registry.any_of(selectedEntity); + case 9: return registry.any_of(selectedEntity); + case 10: return registry.any_of(selectedEntity); default: return false; } }; @@ -610,6 +614,12 @@ void GuiManager::RenderInspectorWindow() case 8: registry.emplace(selectedEntity); break; + case 9: + registry.emplace(selectedEntity, 0); + break; + case 10: + registry.emplace(selectedEntity); + break; default: break; } @@ -744,6 +754,48 @@ void GuiManager::RenderInspectorWindow() } } + // Texture + if (registry.any_of(selectedEntity)) { + auto& texture = registry.get(selectedEntity); + ImGui::Separator(); + ImGui::Text("Texture"); + + int textureId = static_cast(texture.textureId); + if (ImGui::InputInt("Texture Id", &textureId)) { + texture.textureId = textureId < 0 ? 0u : static_cast(textureId); + } + + if (ImGui::Button("Remove Texture")) { + registry.remove(selectedEntity); + } + } + + // UV Transform + if (registry.any_of(selectedEntity)) { + auto& uv = registry.get(selectedEntity); + ImGui::Separator(); + ImGui::Text("UV Transform"); + + float scale[2] = {uv.scale.x, uv.scale.y}; + if (ImGui::DragFloat2("Scale", scale, 0.01f)) { + uv.scale = {scale[0], scale[1]}; + } + + float offset[2] = {uv.offset.x, uv.offset.y}; + if (ImGui::DragFloat2("Offset", offset, 0.01f)) { + uv.offset = {offset[0], offset[1]}; + } + + float rotation = uv.rotation; + if (ImGui::DragFloat("Rotation (rad)", &rotation, 0.01f)) { + uv.rotation = rotation; + } + + if (ImGui::Button("Remove UV Transform")) { + registry.remove(selectedEntity); + } + } + // Script if (registry.any_of(selectedEntity)) { auto& script = registry.get(selectedEntity); diff --git a/src/scripting/ECSBindings.cpp b/src/scripting/ECSBindings.cpp index a500718..2bfc3de 100644 --- a/src/scripting/ECSBindings.cpp +++ b/src/scripting/ECSBindings.cpp @@ -172,6 +172,77 @@ void AS_RemoveSprite(uint32_t entity) { registry->remove((entt::entity)entity); } +// === Texture Component === + +void AS_AddTexture(uint32_t entity, unsigned int textureId) { + if (!registry) return; + registry->emplace((entt::entity)entity, textureId); +} + +void AS_SetTextureId(uint32_t entity, unsigned int textureId) { + if (!registry) return; + if (auto* t = registry->try_get((entt::entity)entity)) { + t->textureId = textureId; + } +} + +unsigned int AS_GetTextureId(uint32_t entity) { + if (!registry) return 0; + if (auto* t = registry->try_get((entt::entity)entity)) { + return t->textureId; + } + return 0; +} + +bool AS_HasTexture(uint32_t entity) { + if (!registry) return false; + return registry->all_of((entt::entity)entity); +} + +void AS_RemoveTexture(uint32_t entity) { + if (!registry) return; + registry->remove((entt::entity)entity); +} + +// === UV Transform Component === + +void AS_AddUVTransform(uint32_t entity, float scaleX, float scaleY, float offsetX, float offsetY, float rotation) { + if (!registry) return; + registry->emplace((entt::entity)entity, + Vector2{scaleX, scaleY}, Vector2{offsetX, offsetY}, rotation); +} + +void AS_SetUVScale(uint32_t entity, float scaleX, float scaleY) { + if (!registry) return; + if (auto* uv = registry->try_get((entt::entity)entity)) { + uv->scale = {scaleX, scaleY}; + } +} + +void AS_SetUVOffset(uint32_t entity, float offsetX, float offsetY) { + if (!registry) return; + if (auto* uv = registry->try_get((entt::entity)entity)) { + uv->offset = {offsetX, offsetY}; + } +} + +void AS_SetUVRotation(uint32_t entity, float rotation) { + if (!registry) return; + if (auto* uv = registry->try_get((entt::entity)entity)) { + uv->rotation = rotation; + } +} + +bool AS_HasUVTransform(uint32_t entity) { + if (!registry) return false; + return registry->all_of((entt::entity)entity); +} + +void AS_RemoveUVTransform(uint32_t entity) { + if (!registry) return; + registry->remove((entt::entity)entity); +} + // === Tag Component === void AS_AddTag(uint32_t entity, const std::string& name) { @@ -502,6 +573,52 @@ void RegisterECSBindings(asIScriptEngine *engine) { asFUNCTION(AS_RemoveSprite), asCALL_CDECL); assert(r >= 0); + // Texture component + r = engine->RegisterGlobalFunction("void AddTexture(uint, uint)", + asFUNCTION(AS_AddTexture), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void SetTextureId(uint, uint)", + asFUNCTION(AS_SetTextureId), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("uint GetTextureId(uint)", + asFUNCTION(AS_GetTextureId), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("bool HasTexture(uint)", + asFUNCTION(AS_HasTexture), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void RemoveTexture(uint)", + asFUNCTION(AS_RemoveTexture), asCALL_CDECL); + assert(r >= 0); + + // UV Transform component + r = engine->RegisterGlobalFunction("void AddUVTransform(uint, float, float, float = 0.0f, float = 0.0f, float = 0.0f)", + asFUNCTION(AS_AddUVTransform), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void SetUVScale(uint, float, float)", + asFUNCTION(AS_SetUVScale), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void SetUVOffset(uint, float, float)", + asFUNCTION(AS_SetUVOffset), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void SetUVRotation(uint, float)", + asFUNCTION(AS_SetUVRotation), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("bool HasUVTransform(uint)", + asFUNCTION(AS_HasUVTransform), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void RemoveUVTransform(uint)", + asFUNCTION(AS_RemoveUVTransform), asCALL_CDECL); + assert(r >= 0); + // Tag component r = engine->RegisterGlobalFunction("void AddTag(uint, const string &in)", asFUNCTION(AS_AddTag), asCALL_CDECL); diff --git a/src/scripting/InputBindings.cpp b/src/scripting/InputBindings.cpp index dd43d3e..e97eade 100644 --- a/src/scripting/InputBindings.cpp +++ b/src/scripting/InputBindings.cpp @@ -38,6 +38,14 @@ static void AS_BindMouseButton(const std::string& actionName, int mouseButton) { if (g_inputManager) g_inputManager->BindMouseButton(actionName, mouseButton); } +static void AS_BindGamepadButton(const std::string& actionName, int gamepadId, int button) { + if (g_inputManager) g_inputManager->BindGamepadButton(actionName, gamepadId, button); +} + +static void AS_BindGamepadAxis(const std::string& actionName, int gamepadId, int axis, float threshold, bool negative) { + if (g_inputManager) g_inputManager->BindGamepadAxis(actionName, gamepadId, axis, threshold, negative); +} + static void AS_ClearBindings(const std::string& actionName) { if (g_inputManager) g_inputManager->ClearBindings(actionName); } @@ -74,6 +82,14 @@ void RegisterInputBindings(asIScriptEngine* engine) { r = engine->RegisterGlobalFunction("void BindMouseButton(const string &in, int)", asFUNCTION(AS_BindMouseButton), asCALL_CDECL); assert(r >= 0); + + r = engine->RegisterGlobalFunction("void BindGamepadButton(const string &in, int, int)", + asFUNCTION(AS_BindGamepadButton), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void BindGamepadAxis(const string &in, int, int, float = 0.5f, bool = false)", + asFUNCTION(AS_BindGamepadAxis), asCALL_CDECL); + assert(r >= 0); r = engine->RegisterGlobalFunction("void ClearBindings(const string &in)", asFUNCTION(AS_ClearBindings), asCALL_CDECL); @@ -114,4 +130,56 @@ void RegisterInputBindings(asIScriptEngine* engine) { assert(r >= 0); r = engine->RegisterEnumValue("MouseButton", "MIDDLE", MOUSE_BUTTON_MIDDLE); assert(r >= 0); + + r = engine->RegisterEnum("GamepadButton"); + assert(r >= 0); + r = engine->RegisterEnumValue("GamepadButton", "LEFT_FACE_UP", GAMEPAD_BUTTON_LEFT_FACE_UP); + assert(r >= 0); + r = engine->RegisterEnumValue("GamepadButton", "LEFT_FACE_RIGHT", GAMEPAD_BUTTON_LEFT_FACE_RIGHT); + assert(r >= 0); + r = engine->RegisterEnumValue("GamepadButton", "LEFT_FACE_DOWN", GAMEPAD_BUTTON_LEFT_FACE_DOWN); + assert(r >= 0); + r = engine->RegisterEnumValue("GamepadButton", "LEFT_FACE_LEFT", GAMEPAD_BUTTON_LEFT_FACE_LEFT); + assert(r >= 0); + r = engine->RegisterEnumValue("GamepadButton", "RIGHT_FACE_UP", GAMEPAD_BUTTON_RIGHT_FACE_UP); + assert(r >= 0); + r = engine->RegisterEnumValue("GamepadButton", "RIGHT_FACE_RIGHT", GAMEPAD_BUTTON_RIGHT_FACE_RIGHT); + assert(r >= 0); + r = engine->RegisterEnumValue("GamepadButton", "RIGHT_FACE_DOWN", GAMEPAD_BUTTON_RIGHT_FACE_DOWN); + assert(r >= 0); + r = engine->RegisterEnumValue("GamepadButton", "RIGHT_FACE_LEFT", GAMEPAD_BUTTON_RIGHT_FACE_LEFT); + assert(r >= 0); + r = engine->RegisterEnumValue("GamepadButton", "LEFT_TRIGGER_1", GAMEPAD_BUTTON_LEFT_TRIGGER_1); + assert(r >= 0); + r = engine->RegisterEnumValue("GamepadButton", "LEFT_TRIGGER_2", GAMEPAD_BUTTON_LEFT_TRIGGER_2); + assert(r >= 0); + r = engine->RegisterEnumValue("GamepadButton", "RIGHT_TRIGGER_1", GAMEPAD_BUTTON_RIGHT_TRIGGER_1); + assert(r >= 0); + r = engine->RegisterEnumValue("GamepadButton", "RIGHT_TRIGGER_2", GAMEPAD_BUTTON_RIGHT_TRIGGER_2); + assert(r >= 0); + r = engine->RegisterEnumValue("GamepadButton", "MIDDLE_LEFT", GAMEPAD_BUTTON_MIDDLE_LEFT); + assert(r >= 0); + r = engine->RegisterEnumValue("GamepadButton", "MIDDLE", GAMEPAD_BUTTON_MIDDLE); + assert(r >= 0); + r = engine->RegisterEnumValue("GamepadButton", "MIDDLE_RIGHT", GAMEPAD_BUTTON_MIDDLE_RIGHT); + assert(r >= 0); + r = engine->RegisterEnumValue("GamepadButton", "LEFT_THUMB", GAMEPAD_BUTTON_LEFT_THUMB); + assert(r >= 0); + r = engine->RegisterEnumValue("GamepadButton", "RIGHT_THUMB", GAMEPAD_BUTTON_RIGHT_THUMB); + assert(r >= 0); + + r = engine->RegisterEnum("GamepadAxis"); + assert(r >= 0); + r = engine->RegisterEnumValue("GamepadAxis", "LEFT_X", GAMEPAD_AXIS_LEFT_X); + assert(r >= 0); + r = engine->RegisterEnumValue("GamepadAxis", "LEFT_Y", GAMEPAD_AXIS_LEFT_Y); + assert(r >= 0); + r = engine->RegisterEnumValue("GamepadAxis", "RIGHT_X", GAMEPAD_AXIS_RIGHT_X); + assert(r >= 0); + r = engine->RegisterEnumValue("GamepadAxis", "RIGHT_Y", GAMEPAD_AXIS_RIGHT_Y); + assert(r >= 0); + r = engine->RegisterEnumValue("GamepadAxis", "LEFT_TRIGGER", GAMEPAD_AXIS_LEFT_TRIGGER); + assert(r >= 0); + r = engine->RegisterEnumValue("GamepadAxis", "RIGHT_TRIGGER", GAMEPAD_AXIS_RIGHT_TRIGGER); + assert(r >= 0); } diff --git a/src/scripting/ResourceBindings.cpp b/src/scripting/ResourceBindings.cpp index 623a187..da1ff37 100644 --- a/src/scripting/ResourceBindings.cpp +++ b/src/scripting/ResourceBindings.cpp @@ -2,6 +2,7 @@ #include "ShaderManager.h" #include "ModelManager.h" #include "MaterialManager.h" +#include "TextureManager.h" #include #include #include "raylib.h" @@ -10,11 +11,13 @@ static ShaderManager* g_shaderManager = nullptr; static ModelManager* g_modelManager = nullptr; static MaterialManager* g_materialManager = nullptr; +static TextureManager* g_textureManager = nullptr; -void SetResourceManagers(ShaderManager* shaderMgr, ModelManager* modelMgr, MaterialManager* materialMgr) { +void SetResourceManagers(ShaderManager* shaderMgr, ModelManager* modelMgr, MaterialManager* materialMgr, TextureManager* textureMgr) { g_shaderManager = shaderMgr; g_modelManager = modelMgr; g_materialManager = materialMgr; + g_textureManager = textureMgr; } // === Shader Management === @@ -80,6 +83,18 @@ void AS_SetMaterialAlbedo(unsigned int id, unsigned char r, unsigned char g, uns g_materialManager->SetAlbedo(id, albedo); } +// === Texture Management === + +unsigned int AS_LoadTextureAsset(const std::string& path) { + if (!g_textureManager) return 0; + return g_textureManager->Load(path); +} + +void AS_UnloadTextureAsset(unsigned int id) { + if (!g_textureManager) return; + g_textureManager->Unload(id); +} + void RegisterResourceBindings(asIScriptEngine *engine) { int r; @@ -137,5 +152,16 @@ void RegisterResourceBindings(asIScriptEngine *engine) asFUNCTION(AS_SetMaterialAlbedo), asCALL_CDECL); assert(r >= 0); + // === TextureAsset namespace === + engine->SetDefaultNamespace("TextureAsset"); + + r = engine->RegisterGlobalFunction("uint Load(const string &in)", + asFUNCTION(AS_LoadTextureAsset), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("void Unload(uint)", + asFUNCTION(AS_UnloadTextureAsset), asCALL_CDECL); + assert(r >= 0); + engine->SetDefaultNamespace(""); } diff --git a/tests/resource_tests.cpp b/tests/resource_tests.cpp index 4f441d4..3b00d2c 100644 --- a/tests/resource_tests.cpp +++ b/tests/resource_tests.cpp @@ -6,6 +6,7 @@ #include "../include/ShaderManager.h" #include "../include/ModelManager.h" #include "../include/MaterialManager.h" +#include "../include/TextureManager.h" #include "../include/scripting/ScriptEngine.h" #include "../include/scripting/ResourceBindings.h" #include "raylib.h" @@ -187,7 +188,8 @@ void test_resource_bindings_script(void) { ShaderManager shaderManager; ModelManager modelManager; MaterialManager materialManager; - SetResourceManagers(&shaderManager, &modelManager, &materialManager); + TextureManager textureManager; + SetResourceManagers(&shaderManager, &modelManager, &materialManager, &textureManager); ScriptEngine se; TEST_CHECK(se.Initialize() == true); diff --git a/tests/scenegraph_tests.cpp b/tests/scenegraph_tests.cpp index c49da20..9b6dc0a 100644 --- a/tests/scenegraph_tests.cpp +++ b/tests/scenegraph_tests.cpp @@ -8,6 +8,7 @@ #include "../include/SceneLoader.h" #include "../include/ModelManager.h" #include "../include/ShaderManager.h" +#include "../include/TextureManager.h" #include "raylib.h" #include "entt.hpp" @@ -105,7 +106,8 @@ void test_scene_loader_basic(void) { entt::registry registry; ModelManager modelManager; ShaderManager shaderManager; - SetSceneContext(®istry, &modelManager, &shaderManager); + TextureManager textureManager; + SetSceneContext(®istry, &modelManager, &shaderManager, &textureManager); std::filesystem::path tmpDir = std::filesystem::current_path() / "tmp_scene"; std::filesystem::create_directories(tmpDir); From 756b818f46e24194e0ab3c861fd1c375ff5dbcc5 Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Mon, 9 Mar 2026 21:31:51 +1300 Subject: [PATCH 48/53] feat: asset management, editor camera --- CMakeLists.txt | 3 + README.md | 10 + assets/registry.toml | 9 + docs/Editor.md | 11 +- docs/Scenegraph.md | 9 + docs/Scripting.md | 19 + external/ImViewGuizmo/ImViewGuizmo.h | 603 ++++++++++++++ imgui.ini | 20 +- include/Application.h | 20 + include/AssetManager.h | 144 ++++ include/ECSComponents.h | 25 +- include/ImViewGuizmoRaymath.h | 155 ++++ include/SceneLoader.h | 2 + include/gui/GuiManager.h | 57 ++ include/scripting/ResourceBindings.h | 2 + include/scripting/ScriptEngine.h | 3 + scenes/demo.toml | 21 +- scripts/as.predefined | 77 ++ scripts/game.as | 106 +-- scripts/scene_example.as | 20 + src/Application.cpp | 168 +++- src/AssetManager.cpp | 1089 ++++++++++++++++++++++++++ src/SceneGraph.cpp | 44 +- src/SceneLoader.cpp | 174 +++- src/gui/GuiManager.cpp | 671 +++++++++++++++- src/gui/ImViewGuizmoIntegration.cpp | 1 + src/scripting/ECSBindings.cpp | 28 +- src/scripting/ResourceBindings.cpp | 228 ++++++ src/scripting/ScriptEngine.cpp | 27 + 29 files changed, 3615 insertions(+), 131 deletions(-) create mode 100644 assets/registry.toml create mode 100644 external/ImViewGuizmo/ImViewGuizmo.h create mode 100644 include/AssetManager.h create mode 100644 include/ImViewGuizmoRaymath.h create mode 100644 scripts/scene_example.as create mode 100644 src/AssetManager.cpp create mode 100644 src/gui/ImViewGuizmoIntegration.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index ee5ee99..4ef239c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -94,11 +94,13 @@ add_library(simian_core STATIC src/scripting/SceneBindings.cpp src/HotReload.cpp src/gui/GuiManager.cpp + src/gui/ImViewGuizmoIntegration.cpp src/gui/LogWindow.cpp src/log/log.c src/ShaderManager.cpp src/ModelManager.cpp src/MaterialManager.cpp + src/AssetManager.cpp src/TextureManager.cpp src/InputManager.cpp ) @@ -114,6 +116,7 @@ target_include_directories(simian_core PUBLIC external/angelscript/sdk/add_on/scriptbuilder external/angelscript/sdk/add_on/scriptarray external/imgui + external/ImViewGuizmo ) target_link_libraries(simian_core PUBLIC diff --git a/README.md b/README.md index eab863d..22e8012 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,16 @@ Simian/ - If compilation succeeds, the temp module replaces the live `main` module and new functions are used. If compilation fails, the running module is left intact and a single-line error is shown on-screen. - This avoids crashes that happen when a script with compilation errors would otherwise replace/break function pointers while the engine is executing. +## Asset registry + +Asset keys are persisted in a project-wide registry at `assets/registry.toml`. This file is loaded on startup and written on shutdown so scene references stay valid across sessions. + +## Scene scripts (class-based) + +Scene scripts now use class instances (similar to entity scripts). Implement a class with `Init()`, `Update(float)`, and `Shutdown()` methods. The engine picks the first class that exposes any of those methods and instantiates it. + +See `scripts/game.as` and `scripts/scene_example.as` for examples. + ## ImGui / rlImGui (optional) The repository prefers to keep upstream code as submodules. Some upstream projects (like certain ImGui tags or rlImGui) don't provide a CMakeLists.txt. To support those without editing submodules, the project includes small wrappers in `cmake/`: diff --git a/assets/registry.toml b/assets/registry.toml new file mode 100644 index 0000000..a577f87 --- /dev/null +++ b/assets/registry.toml @@ -0,0 +1,9 @@ +# Simian asset registry +# Auto-generated - edits may be overwritten + +[[model]] +key = "Torus" +type = "primitive" +primitive = "torus" +params = [0.5, 1, 16, 8] + diff --git a/docs/Editor.md b/docs/Editor.md index 40b7145..e0197de 100644 --- a/docs/Editor.md +++ b/docs/Editor.md @@ -11,7 +11,7 @@ This document outlines the in-app editor UI, its panels, and common workflows. - DockSpace host with a top menu bar. - You can drag and drop to move panels around. -- Panels: Game Window, Scene, Inspector, Log Viewer. +- Panels: Game Window, Scene, Assets, Inspector, Log Viewer. ## Menu Bar @@ -28,6 +28,7 @@ This document outlines the in-app editor UI, its panels, and common workflows. ### View - Toggle Log Viewer, Scene, and Inspector panels. +- Toggle Assets panel. ## Game Window @@ -62,6 +63,12 @@ This document outlines the in-app editor UI, its panels, and common workflows. - Render Pass: order, depth flags, shader id. - World Transform: read-only computed transform. +## Assets Panel + +- Browse loaded textures, shaders, models, and materials. +- Load assets by key and path, or create primitive models. +- Unload assets by key. + ## Log Viewer - Shows engine log output in real time. @@ -77,7 +84,7 @@ This document outlines the in-app editor UI, its panels, and common workflows. ## Notes - Scene Save and Load use file path text fields. -- Component IDs are numeric and map to runtime resource managers. +- Components can be assigned via asset keys in the inspector; numeric IDs remain as a fallback. - World Transform is computed from hierarchy and local transforms and is read-only. - UV Transform values are passed as shader uniforms `uvScale`, `uvOffset`, and `uvRotation` when present. diff --git a/docs/Scenegraph.md b/docs/Scenegraph.md index 433d5a2..edca096 100644 --- a/docs/Scenegraph.md +++ b/docs/Scenegraph.md @@ -55,13 +55,17 @@ parent = "root" tag = "Parent" position = [2.0, 0.0, 0.0] model = "cube" +model_asset = "unit_cube" model_size = [1.0, 1.0, 1.0] color = 0x00FF00FF shader_vs = "shaders/toon.vs" shader_fs = "shaders/toon.fs" +shader_asset = "toon" texture = "assets/textures/grid.png" +texture_asset = "grid" uv_scale = [2.0, 2.0] uv_offset = [0.0, 0.0] +material_asset = "toon_mat" [[entity]] id = "child" @@ -85,15 +89,20 @@ shader_fs = "shaders/toon.fs" - `rotation` (radians) or `rotation_deg` (degrees) - `scale` (vec3) - `model` — `cube`, `sphere`, `plane`, or file path +- `model_asset` (string) — asset key for models - `model_id` (int) — numeric model id - `model_size` (vec3) for cubes/planes - `radius`, `rings`, `slices` for spheres - `color` — hex `0xRRGGBBAA` (matches script colors) - `outline_size` — optional sprite outline - `shader_vs`, `shader_fs` — optional shader paths +- `shader_asset` (string) — asset key for shaders - `shader_id` (int) — numeric shader id - `texture` (string) — texture path +- `texture_asset` (string) — asset key for textures - `texture_id` (int) — numeric texture id +- `material_asset` (string) — asset key for materials +- `material_id` (int) — numeric material id - `uv_scale` (vec2) - `uv_offset` (vec2) - `uv_rotation` (radians) diff --git a/docs/Scripting.md b/docs/Scripting.md index fb96d92..9273631 100644 --- a/docs/Scripting.md +++ b/docs/Scripting.md @@ -36,6 +36,25 @@ ECS::AddUVTransform(e, 2.0f, 2.0f, 0.0f, 0.0f, 0.0f); ECS::SetUVOffset(e, 0.25f, 0.0f); ``` +## Asset Manager +- Asset loading can be keyed for editor and scene usage. +- Use `Asset::Load*` helpers to create assets and reference them by key. + +Example: + +```angelscript +Asset::LoadTexture("grid", "assets/textures/grid.png"); +Asset::LoadShader("toon", "shaders/toon.vs", "shaders/toon.fs"); +Asset::LoadCube("unit_cube", 1.0f, 1.0f, 1.0f); +Asset::CreateMaterial("toon_mat", Asset::GetShaderId("toon"), 255, 255, 255, 255); + +uint e = ECS::CreateEntity(); +ECS::AddSprite(e, int(Asset::GetModelId("unit_cube")), 0xFFFFFFFF, 0.0f); +ECS::SetSpriteShader(e, Asset::GetShaderId("toon")); +ECS::AddTexture(e, Asset::GetTextureId("grid")); +ECS::AddMaterial(e, Asset::GetMaterialId("toon_mat")); +``` + ## Examples - `scripts/game.as` — demo showing ECS usage, rendering, scenegraph and input actions. diff --git a/external/ImViewGuizmo/ImViewGuizmo.h b/external/ImViewGuizmo/ImViewGuizmo.h new file mode 100644 index 0000000..964ef5a --- /dev/null +++ b/external/ImViewGuizmo/ImViewGuizmo.h @@ -0,0 +1,603 @@ +#pragma once + +#include +#include + +/*=============================================== +ImViewGuizmo Single-Header Library by Marcel Kazemi + +To use, do this in one (and only one) of your C++ files: +#define IMVIEWGUIZMO_IMPLEMENTATION + #include "ImViewGuizmo.h" + +In all other files, just include the header as usual: +#include "ImViewGuizmo.h" + +Copyright (c) 2025 Marcel Kazemi + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +======================================================*/ + +#ifndef IMVIEWGUIZMO_VEC3 + #define IMVIEWGUIZMO_USE_GLM_DEFAULTS + #ifndef GLM_ENABLE_EXPERIMENTAL + #define GLM_ENABLE_EXPERIMENTAL + #endif + #include + #include + #include + #include + + #define IMVIEWGUIZMO_VEC3 glm::vec3 + #define IMVIEWGUIZMO_VEC4 glm::vec4 + #define IMVIEWGUIZMO_QUAT glm::quat + #define IMVIEWGUIZMO_MAT4 glm::mat4 +#endif + +namespace ImViewGuizmo +{ + using vec3_t = IMVIEWGUIZMO_VEC3; + using vec4_t = IMVIEWGUIZMO_VEC4; + using quat_t = IMVIEWGUIZMO_QUAT; + using mat4_t = IMVIEWGUIZMO_MAT4; + +#ifdef IMVIEWGUIZMO_USE_GLM_DEFAULTS + namespace GizmoMath { + inline float get_vec_comp(const vec3_t& v, int index) { return v[index]; } + inline float get_vec_comp(const vec4_t& v, int index) { return v[index]; } + + inline vec3_t make_vec3(float x, float y, float z) { return vec3_t(x, y, z); } + inline vec4_t make_vec4(float x, float y, float z, float w) { return vec4_t(x, y, z, w); } + inline quat_t angleAxis(float angle, const vec3_t& axis) { return glm::angleAxis(angle, axis); } + inline quat_t quatLookAt(const vec3_t& dir, const vec3_t& up) { return glm::quatLookAt(dir, up); } + inline mat4_t mat4_identity() { return mat4_t(1.0f); } + + inline vec3_t cross(const vec3_t& a, const vec3_t& b) { return glm::cross(a, b); } + inline float dot(const vec3_t& a, const vec3_t& b) { return glm::dot(a, b); } + inline float dot(const quat_t& a, const quat_t& b) { return glm::dot(a, b); } + inline float length(const vec3_t& v) { return glm::length(v); } + inline float length2(const vec3_t& v) { return glm::length2(v); } + inline vec3_t normalize(const vec3_t& v) { return glm::normalize(v); } + inline vec3_t mix(const vec3_t& a, const vec3_t& b, float t) { return glm::mix(a, b, t); } + inline vec3_t add_vv(const vec3_t& a, const vec3_t& b) { return a + b; } + inline vec3_t subtract_vv(const vec3_t& a, const vec3_t& b) { return a - b; } + inline vec3_t multiply_vf(const vec3_t& v, float f) { return v * f; } + + inline mat4_t mat4_cast(const quat_t& q) { return glm::mat4_cast(q); } + inline mat4_t transpose(const mat4_t& m) { return glm::transpose(m); } + inline vec3_t get_matrix_col(const mat4_t& m, int col) { return vec3_t(m[col]); } + inline void set_matrix_col(mat4_t& m, int col, const vec4_t& v) { m[col] = v; } + + inline quat_t multiply_qq(const quat_t& a, const quat_t& b) { return a * b; } + inline vec3_t multiply_qv(const quat_t& q, const vec3_t& v) { return q * v; } + inline mat4_t multiply_mm(const mat4_t& a, const mat4_t& b) { return a * b; } + inline vec4_t multiply_mv4(const mat4_t& m, const vec4_t& v) { return m * v; } + } +#else + // User must provide a GizmoMath namespace implementing all functions if using custom types +#endif + + // INTERFACE + struct Style { + float scale = 1.f; + + // Axis visuals + float lineLength = 0.5f; + float lineWidth = 4.0f; + float circleRadius = 15.0f; + float fadeFactor = 0.25f; + + // Highlight + ImU32 highlightColor = IM_COL32(255, 255, 0, 255); + float highlightWidth = 2.0f; + + // Axis + ImU32 axisColors[3] = { + IM_COL32(230, 51, 51, 255), // X + IM_COL32(51, 230, 51, 255), // Y + IM_COL32(51, 128, 255, 255) // Z + }; + + // Labels + float labelSize = 1.0f; + const char* axisLabels[3] = {"X", "Y", "Z"}; + ImU32 labelColor = IM_COL32(255, 255, 255, 255); + + //Big Circle + float bigCircleRadius = 80.0f; + ImU32 bigCircleColor = IM_COL32(255, 255, 255, 50); + + // Animation + bool animateSnap = true; + float snapAnimationDuration = 0.5f; // in seconds + + // Zoom/Pan Button Visuals + float toolButtonRadius = 25.f; + float toolButtonInnerPadding = 4.f; + + ImU32 toolButtonColor = IM_COL32(144, 144, 144, 50); + ImU32 toolButtonHoveredColor = IM_COL32(215, 215, 215, 50); + ImU32 toolButtonIconColor = IM_COL32(215, 215, 215, 225); + }; + + // Constants + const vec3_t origin = GizmoMath::make_vec3(0.f, 0.f, 0.f); + const vec3_t worldRight = GizmoMath::make_vec3(1.f, 0.f, 0.f); // +X + const vec3_t worldUp = GizmoMath::make_vec3(0.f, -1.f, 0.f); // -Y + const vec3_t worldForward = GizmoMath::make_vec3(0.f, 0.f, 1.f); // +Z + const vec3_t axisVectors[3] = { GizmoMath::make_vec3(1,0,0), GizmoMath::make_vec3(0,1,0), GizmoMath::make_vec3(0,0,1) }; + static constexpr mat4_t gizmoProjectionMatrix = { + -1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, -0.01f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f + }; + + inline Style& GetStyle() { + static Style style; + return style; + } + + // Gizmo Axis Struct + struct GizmoAxis { + int id; // 0-5 for (+X,-X,+Y,-Y,+Z,-Z), 6=center + int axisIndex; // 0=X, 1=Y, 2=Z + float depth; // Screen-space depth + vec3_t direction; // 3D vector + }; + + enum ActiveTool { + TOOL_NONE, + TOOL_GIZMO, + TOOL_DOLLY, + TOOL_PAN + }; + + struct Context { + int hoveredAxisID = -1; + bool isZoomButtonHovered = false; + bool isPanButtonHovered = false; + ActiveTool activeTool = TOOL_NONE; + + // Animation state + bool isAnimating = false; + float animationStartTime = 0.f; + + vec3_t startPos; + vec3_t targetPos; + vec3_t startUp; + vec3_t targetUp; + + vec3_t animStartDir, animTargetDir; + float animStartDist, animTargetDist; + + void Reset() { + hoveredAxisID = -1; + isZoomButtonHovered = false; + isPanButtonHovered = false; + } + }; + + // Global context + inline Context& GetContext() { + static Context ctx; + return ctx; + } + + static float ImViewGuizmoLengthSqr(const ImVec2& v) { return v.x * v.x + v.y * v.y; } + static float mix(float a, float b, float t) { return a * (1.0f - t) + b * t; } + + inline void BeginFrame() { + static int lastFrame = -1; + const int currentFrame = ImGui::GetFrameCount(); + if (lastFrame != currentFrame) + lastFrame = currentFrame; GetContext().Reset(); + } + + inline bool IsUsing() { + return GetContext().activeTool != TOOL_NONE; + } + + inline bool IsOver() { + const Context& ctx = GetContext(); + return ctx.hoveredAxisID != -1 || ctx.isZoomButtonHovered || ctx.isPanButtonHovered; + } + + /// @brief Renders and handles the view gizmo logic. + /// @param cameraPos The position of the camera (will be modified). + /// @param cameraRot The rotation of the camera (will be modified). + /// @param pivot The position the camera will rotate around. + /// @param position The top-left screen position where the gizmo should be rendered. + /// @param rotationSpeed The rotation speed when dragging the gizmo. + /// @return True if the camera was modified, false otherwise. + bool Rotate(vec3_t& cameraPos, quat_t& cameraRot, const vec3_t& pivot, ImVec2 position, float rotationSpeed = 0.01f); + + /// @brief Renders a zoom button and handles its logic. + /// @param cameraPos The position of the camera (will be modified). + /// @param cameraRot The rotation of the camera (used for direction). + /// @param position The top-left screen position of the button. + /// @param zoomSpeed The speed/sensitivity of the zoom. + /// @return True if the camera was modified, false otherwise. + bool Dolly(vec3_t& cameraPos, const quat_t& cameraRot, ImVec2 position, float zoomSpeed = 0.05f); + + /// @brief Renders a pan button and handles its logic. + /// @param cameraPos The position of the camera (will be modified). + /// @param cameraRot The rotation of the camera (used for direction). + /// @param position The top-left screen position of the button. + /// @param panSpeed The speed/sensitivity of the pan. + /// @return True if the camera was modified, false otherwise. + bool Pan(vec3_t& cameraPos, const quat_t& cameraRot, ImVec2 position, float panSpeed = 0.01f); +} + +#ifdef IMVIEWGUIZMO_IMPLEMENTATION +namespace ImViewGuizmo { + + /// @brief Renders and handles the view gizmo logic. + inline bool Rotate(vec3_t& cameraPos, quat_t& cameraRot, const vec3_t& pivot, ImVec2 position, float rotationSpeed ) { + + auto& io = ImGui::GetIO(); + ImDrawList* drawList = ImGui::GetWindowDrawList(); + auto& ctx = GetContext(); + auto& style = GetStyle(); + bool wasModified = false; + + // Animation + if (ctx.isAnimating) { + float elapsedTime = static_cast(ImGui::GetTime()) - ctx.animationStartTime; + float t = std::min(1.0f, elapsedTime / style.snapAnimationDuration); + t = 1.0f - (1.0f - t) * (1.0f - t); // ease-out quad + + vec3_t currentDir = GizmoMath::normalize(GizmoMath::mix(ctx.animStartDir, ctx.animTargetDir, t)); + float currentDistance = mix(ctx.animStartDist, ctx.animTargetDist, t); + cameraPos = GizmoMath::add_vv(pivot, GizmoMath::multiply_vf(currentDir, currentDistance)); + + vec3_t currentUp = GizmoMath::normalize(GizmoMath::mix(ctx.startUp, ctx.targetUp, t)); + cameraRot = GizmoMath::quatLookAt(currentDir, currentUp); + + wasModified = true; + + if (t >= 1.0f) { + cameraPos = ctx.targetPos; + cameraRot = GizmoMath::quatLookAt(ctx.animTargetDir, ctx.targetUp); + ctx.isAnimating = false; + } + } + + // Gizmo sizes + const float gizmoDiameter = 256.f * style.scale; + const float halfGizmoSize = gizmoDiameter / 2.f; + const float scaledCircleRadius = style.circleRadius * style.scale; + const float scaledBigCircleRadius = style.bigCircleRadius * style.scale; + const float scaledLineWidth = style.lineWidth * style.scale; + const float scaledHighlightWidth = style.highlightWidth * style.scale; + const float scaledHighlightRadius = (style.circleRadius + 2.0f) * style.scale; + const float scaledFontSize = ImGui::GetFontSize() * style.scale * style.labelSize; + + // Gizmo view matrix (transpose of rotation) + mat4_t rotMat4 = GizmoMath::mat4_cast(cameraRot); + + vec3_t rcol0 = GizmoMath::get_matrix_col(rotMat4, 0); + vec3_t rcol1 = GizmoMath::get_matrix_col(rotMat4, 1); + vec3_t rcol2 = GizmoMath::get_matrix_col(rotMat4, 2); + + mat4_t gizmoViewMatrix = GizmoMath::mat4_identity(); + GizmoMath::set_matrix_col(gizmoViewMatrix, 0, GizmoMath::make_vec4(rcol0.x, rcol1.x, rcol2.x, 0.0f)); + GizmoMath::set_matrix_col(gizmoViewMatrix, 1, GizmoMath::make_vec4(rcol0.y, rcol1.y, rcol2.y, 0.0f)); + GizmoMath::set_matrix_col(gizmoViewMatrix, 2, GizmoMath::make_vec4(rcol0.z, rcol1.z, rcol2.z, 0.0f)); + GizmoMath::set_matrix_col(gizmoViewMatrix, 3, GizmoMath::make_vec4(0.0f, 0.0f, 0.0f, 1.0f)); + + mat4_t gizmoMvp = GizmoMath::multiply_mm(gizmoProjectionMatrix, gizmoViewMatrix); + + // Axes (same ordering/depth calc as glm version) + std::array axes; + + vec3_t xAxisInView = GizmoMath::get_matrix_col(gizmoViewMatrix, 0); + vec3_t yAxisInView = GizmoMath::get_matrix_col(gizmoViewMatrix, 1); + vec3_t zAxisInView = GizmoMath::get_matrix_col(gizmoViewMatrix, 2); + + axes[0] = {0, 0, xAxisInView.z, axisVectors[0]}; + axes[1] = {1, 0, -xAxisInView.z, GizmoMath::multiply_vf(axisVectors[0], -1.0f)}; + axes[2] = {2, 1, yAxisInView.z, axisVectors[1]}; + axes[3] = {3, 1, -yAxisInView.z, GizmoMath::multiply_vf(axisVectors[1], -1.0f)}; + axes[4] = {4, 2, zAxisInView.z, axisVectors[2]}; + axes[5] = {5, 2, -zAxisInView.z, GizmoMath::multiply_vf(axisVectors[2], -1.0f)}; + + std::sort(axes.begin(), axes.end(), [](const GizmoAxis& a, const GizmoAxis& b) { + return a.depth < b.depth; + }); + + // world->screen + auto worldToScreen = [&](const vec3_t& worldPos) -> ImVec2 { + const vec4_t clipPos = GizmoMath::multiply_mv4(gizmoMvp, GizmoMath::make_vec4(worldPos.x, worldPos.y, worldPos.z, 1.0f)); + const float w = clipPos.w; + if (fabsf(w) < 1e-6f) + return {-FLT_MAX, -FLT_MAX}; + const float ndcX = clipPos.x / w; + const float ndcY = clipPos.y / w; + return {position.x + ndcX * halfGizmoSize, position.y - ndcY * halfGizmoSize}; + }; + + const ImVec2 originScreenPos = worldToScreen(origin); + + // Hover detection + const bool canInteract = !(io.ConfigFlags & ImGuiConfigFlags_NoMouse); + if (canInteract && ctx.activeTool == TOOL_NONE && !ctx.isAnimating) { + ImVec2 mousePos = io.MousePos; + float distToCenterSq = ImViewGuizmoLengthSqr(ImVec2(mousePos.x - position.x, mousePos.y - position.y)); + + if (distToCenterSq < (halfGizmoSize + scaledCircleRadius) * (halfGizmoSize + scaledCircleRadius)) { + const float minDistanceSq = scaledCircleRadius * scaledCircleRadius; + for (const auto& axis : axes) { + if (axis.depth < -0.1f) + continue; + + ImVec2 handlePos = worldToScreen(GizmoMath::multiply_vf(axis.direction, style.lineLength)); + if (ImViewGuizmoLengthSqr(ImVec2(handlePos.x - mousePos.x, handlePos.y - mousePos.y)) < minDistanceSq) + ctx.hoveredAxisID = axis.id; + } + if (ctx.hoveredAxisID == -1 && + ImViewGuizmoLengthSqr(ImVec2(originScreenPos.x - mousePos.x, originScreenPos.y - mousePos.y)) < scaledBigCircleRadius * scaledBigCircleRadius) + ctx.hoveredAxisID = 6; + } + } + + // Drawing + if (ctx.hoveredAxisID == 6 || ctx.activeTool == TOOL_GIZMO) + drawList->AddCircleFilled(originScreenPos, scaledBigCircleRadius, style.bigCircleColor); + + ImFont* font = ImGui::GetFont(); + for (const auto& axis : axes) { + float colorFactor = mix(style.fadeFactor, 1.0f, (axis.depth + 1.0f) * 0.5f); + ImVec4 baseColor = ImGui::ColorConvertU32ToFloat4(style.axisColors[axis.axisIndex]); + baseColor.w *= colorFactor; + ImU32 final_color = ImGui::ColorConvertFloat4ToU32(baseColor); + + const ImVec2 handlePos = worldToScreen(GizmoMath::multiply_vf(axis.direction, style.lineLength)); + + ImVec2 lineDir = {handlePos.x - originScreenPos.x, handlePos.y - originScreenPos.y}; + float lineLengthVal = sqrtf(lineDir.x * lineDir.x + lineDir.y * lineDir.y) + 1e-6f; + lineDir.x /= lineLengthVal; lineDir.y /= lineLengthVal; + ImVec2 lineEndPos = {handlePos.x - lineDir.x * scaledCircleRadius, handlePos.y - lineDir.y * scaledCircleRadius}; + + drawList->AddLine(originScreenPos, lineEndPos, final_color, scaledLineWidth); + drawList->AddCircleFilled(handlePos, scaledCircleRadius, final_color); + + if (ctx.hoveredAxisID == axis.id) + drawList->AddCircle(handlePos, scaledHighlightRadius, style.highlightColor, 0, scaledHighlightWidth); + + float textFactor = std::max(0.0f, std::min(1.0f, 1.0f + axis.depth * 2.5f)); + if (textFactor > 0.01f) { + ImVec4 textColor = ImGui::ColorConvertU32ToFloat4(style.labelColor); + textColor.w *= textFactor; + const char* label = style.axisLabels[axis.axisIndex]; + ImVec2 textSize = font->CalcTextSizeA(scaledFontSize, FLT_MAX, 0.f, label); + drawList->AddText(font, scaledFontSize, {handlePos.x - textSize.x * 0.5f, handlePos.y - textSize.y * 0.5f}, ImGui::ColorConvertFloat4ToU32(textColor), label); + } + } + + // Drag start + if (canInteract && io.MouseDown[0] && ctx.activeTool == TOOL_NONE && ctx.hoveredAxisID == 6) { + ctx.activeTool = TOOL_GIZMO; + ctx.isAnimating = false; + } + + // Active tool rotation + if (ctx.activeTool == TOOL_GIZMO) { + float yawAngle = -io.MouseDelta.x * rotationSpeed; + float pitchAngle = -io.MouseDelta.y * rotationSpeed; + + quat_t yawRotation = GizmoMath::angleAxis(yawAngle, worldUp); + vec3_t rightAxis = GizmoMath::multiply_qv(cameraRot, worldRight); + quat_t pitchRotation = GizmoMath::angleAxis(pitchAngle, rightAxis); + quat_t totalRotation = GizmoMath::multiply_qq(yawRotation, pitchRotation); + + vec3_t relativeCamPos = GizmoMath::subtract_vv(cameraPos, pivot); + cameraPos = GizmoMath::add_vv(pivot, GizmoMath::multiply_qv(totalRotation, relativeCamPos)); + cameraRot = GizmoMath::multiply_qq(totalRotation, cameraRot); + + wasModified = true; + } + + // Snap on release + if (canInteract && ImGui::IsMouseReleased(0) && ctx.hoveredAxisID >= 0 && ctx.hoveredAxisID <= 5 && ctx.activeTool == TOOL_NONE) { + int axisIndex = ctx.hoveredAxisID / 2; + float sign = (ctx.hoveredAxisID % 2 == 0) ? -1.0f : 1.0f; + vec3_t targetDir = GizmoMath::multiply_vf(axisVectors[axisIndex], sign); + + float currentDistance = GizmoMath::length(GizmoMath::subtract_vv(cameraPos, pivot)); + vec3_t targetPosition = GizmoMath::add_vv(pivot, GizmoMath::multiply_vf(targetDir, currentDistance)); + + vec3_t dirNormalized = GizmoMath::normalize(targetDir); + + vec3_t targetUp = GizmoMath::multiply_vf(worldUp, -1.0f); + // If dir is nearly parallel to worldUp, pick a different up to avoid flipping + if (fabsf(GizmoMath::dot(dirNormalized, targetUp)) > 0.999f) + if (dirNormalized.y > 0.0f) // facing "up" + targetUp = worldForward; + else // facing "down" + targetUp = GizmoMath::multiply_vf(worldForward, -1.0f); + + quat_t targetRotation = GizmoMath::quatLookAt(targetDir, targetUp); + + if (style.animateSnap && style.snapAnimationDuration > 0.0f) { + bool pos_is_different = GizmoMath::length2(GizmoMath::subtract_vv(cameraPos, targetPosition)) > 0.0001f; + bool rot_is_different = (1.0f - fabsf(GizmoMath::dot(cameraRot, targetRotation))) > 0.0001f; + + if (pos_is_different || rot_is_different) { + ctx.isAnimating = true; + ctx.animationStartTime = static_cast(ImGui::GetTime()); + ctx.startPos = cameraPos; + ctx.targetPos = targetPosition; + ctx.startUp = GizmoMath::multiply_qv(cameraRot, GizmoMath::multiply_vf(worldUp, -1.0f)); + ctx.targetUp = targetUp; + + ctx.animStartDist = GizmoMath::length(GizmoMath::subtract_vv(ctx.startPos, pivot)); + ctx.animTargetDist = GizmoMath::length(GizmoMath::subtract_vv(ctx.targetPos, pivot)); + + if (ctx.animStartDist > 0.0001f) + ctx.animStartDir = GizmoMath::normalize(GizmoMath::subtract_vv(ctx.startPos, pivot)); + else + ctx.animStartDir = worldForward; + + if (ctx.animTargetDist > 0.0001f) + ctx.animTargetDir = GizmoMath::normalize(GizmoMath::subtract_vv(ctx.targetPos, pivot)); + } + } else { + cameraRot = targetRotation; + cameraPos = targetPosition; + wasModified = true; + } + } + + if (!io.MouseDown[0] && ctx.activeTool != TOOL_NONE) + ctx.activeTool = TOOL_NONE; + + return wasModified; + } + + /// @brief Renders a zoom button and handles its logic. + inline bool Dolly(vec3_t& cameraPos, const quat_t& cameraRot, const ImVec2 position, const float zoomSpeed) { + + const ImGuiIO& io = ImGui::GetIO(); + ImDrawList* drawList = ImGui::GetWindowDrawList(); + auto& ctx = GetContext(); + const Style& style = GetStyle(); + bool wasModified = false; + + const bool canInteract = !(io.ConfigFlags & ImGuiConfigFlags_NoMouse); + const float radius = style.toolButtonRadius * style.scale; + const ImVec2 center = { position.x + radius, position.y + radius }; + + bool isHovered = false; + if (canInteract && (ctx.activeTool == TOOL_NONE || ctx.activeTool == TOOL_DOLLY)) { + if (ImViewGuizmoLengthSqr({io.MousePos.x - center.x, io.MousePos.y - center.y}) < radius * radius) { + isHovered = true; + } + } + ctx.isZoomButtonHovered = isHovered; + + if (canInteract && (isHovered || ctx.activeTool == TOOL_DOLLY)) { + ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeNS); + } + + if (canInteract && isHovered && io.MouseDown[0] && ctx.activeTool == TOOL_NONE) { + ctx.activeTool = TOOL_DOLLY; + ctx.isAnimating = false; + } + + if (ctx.activeTool == TOOL_DOLLY && io.MouseDelta.y != 0.0f) { + vec3_t forwardMovement = GizmoMath::multiply_vf( + GizmoMath::multiply_qv(cameraRot, worldForward), + -io.MouseDelta.y * zoomSpeed + ); + cameraPos = GizmoMath::add_vv(cameraPos, forwardMovement); + wasModified = true; + } + + const ImU32 bgColor = (ctx.activeTool == TOOL_DOLLY || isHovered) ? style.toolButtonHoveredColor : style.toolButtonColor; + drawList->AddCircleFilled(center, radius, bgColor); + + const float p = style.toolButtonInnerPadding * style.scale; + const float th = 2.0f * style.scale; + const ImU32 iconColor = style.toolButtonIconColor; + constexpr float iconScale = 0.5f; + const float scaledP = p * iconScale; + const float scaledRadius = radius * iconScale; + + ImVec2 glassCenter = { center.x - scaledP / 2.0f, center.y - scaledP / 2.0f }; + const float glassRadius = scaledRadius - scaledP; + drawList->AddCircle(glassCenter, glassRadius, iconColor, 0, th); + + const ImVec2 handleStart = { center.x + scaledRadius / 2.0f, center.y + scaledRadius / 2.0f }; + const ImVec2 handleEnd = { center.x + scaledRadius - (p * iconScale), center.y + scaledRadius - (p * iconScale) }; + drawList->AddLine(handleStart, handleEnd, iconColor, th); + + const float plusHalfSize = glassRadius * 0.5f; + drawList->AddLine({glassCenter.x, glassCenter.y - plusHalfSize}, {glassCenter.x, glassCenter.y + plusHalfSize}, iconColor, th); + drawList->AddLine({glassCenter.x - plusHalfSize, glassCenter.y}, {glassCenter.x + plusHalfSize, glassCenter.y}, iconColor, th); + + return wasModified; + } + + /// @brief Renders a pan button and handles its logic. + inline bool Pan(vec3_t& cameraPos, const quat_t& cameraRot, const ImVec2 position, const float panSpeed) { + + const ImGuiIO& io = ImGui::GetIO(); + ImDrawList* drawList = ImGui::GetWindowDrawList(); + auto& ctx = GetContext(); + const Style& style = GetStyle(); + bool wasModified = false; + + const vec3_t localWorldRight = GizmoMath::make_vec3(1.0f, 0.0f, 0.0f); + const vec3_t localWorldUp = GizmoMath::make_vec3(0.0f, -1.0f, 0.0f); + const bool canInteract = !(io.ConfigFlags & ImGuiConfigFlags_NoMouse); + const float radius = style.toolButtonRadius * style.scale; + const ImVec2 center = { position.x + radius, position.y + radius }; + + bool isHovered = false; + if (canInteract && (ctx.activeTool == TOOL_NONE || ctx.activeTool == TOOL_PAN)) { + if (ImViewGuizmoLengthSqr({io.MousePos.x - center.x, io.MousePos.y - center.y}) < radius * radius) { + isHovered = true; + } + } + ctx.isPanButtonHovered = isHovered; + + if (canInteract && (isHovered || ctx.activeTool == TOOL_PAN)) { + ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeAll); + } + + if (canInteract && isHovered && io.MouseDown[0] && ctx.activeTool == TOOL_NONE) { + ctx.activeTool = TOOL_PAN; + ctx.isAnimating = false; + } + + if (ctx.activeTool == TOOL_PAN && (io.MouseDelta.x != 0.0f || io.MouseDelta.y != 0.0f)) { + vec3_t rightMovement = GizmoMath::multiply_vf(GizmoMath::multiply_qv(cameraRot, localWorldRight), -io.MouseDelta.x * panSpeed); + vec3_t upMovement = GizmoMath::multiply_vf(GizmoMath::multiply_qv(cameraRot, localWorldUp), io.MouseDelta.y * panSpeed); + cameraPos = GizmoMath::add_vv(cameraPos, rightMovement); + cameraPos = GizmoMath::add_vv(cameraPos, upMovement); + wasModified = true; + } + + const ImU32 bgColor = (isHovered || ctx.activeTool == TOOL_PAN) ? style.toolButtonHoveredColor : style.toolButtonColor; + drawList->AddCircleFilled(center, radius, bgColor); + + const ImU32 iconColor = style.toolButtonIconColor; + const float th = 2.0f * style.scale; + const float size = radius * 0.5f; + const float arm = size * 0.25f; + + const ImVec2 topTip = { center.x, center.y - size }; + drawList->AddLine({ topTip.x - arm, topTip.y + arm }, topTip, iconColor, th); + drawList->AddLine({ topTip.x + arm, topTip.y + arm }, topTip, iconColor, th); + const ImVec2 botTip = { center.x, center.y + size }; + drawList->AddLine({ botTip.x - arm, botTip.y - arm }, botTip, iconColor, th); + drawList->AddLine({ botTip.x + arm, botTip.y - arm }, botTip, iconColor, th); + const ImVec2 leftTip = { center.x - size, center.y }; + drawList->AddLine({ leftTip.x + arm, leftTip.y - arm }, leftTip, iconColor, th); + drawList->AddLine({ leftTip.x + arm, leftTip.y + arm }, leftTip, iconColor, th); + const ImVec2 rightTip = { center.x + size, center.y }; + drawList->AddLine({ rightTip.x - arm, rightTip.y - arm }, rightTip, iconColor, th); + drawList->AddLine({ rightTip.x - arm, rightTip.y + arm }, rightTip, iconColor, th); + + return wasModified; + } + +} // namespace ImViewGuizmo +#endif // IMVIEWGUIZMO_IMPLEMENTATION \ No newline at end of file diff --git a/imgui.ini b/imgui.ini index 39837fe..d34daa6 100644 --- a/imgui.ini +++ b/imgui.ini @@ -10,13 +10,13 @@ Collapsed=0 [Window][Game Window] Pos=232,28 -Size=663,580 +Size=663,408 Collapsed=0 DockId=0x00000004,0 [Window][Log Viewer] -Pos=8,610 -Size=1264,102 +Pos=8,438 +Size=1264,274 Collapsed=0 DockId=0x00000002,0 @@ -77,13 +77,13 @@ Collapsed=0 [Window][Inspector] Pos=897,28 -Size=375,580 +Size=375,408 Collapsed=0 DockId=0x00000006,0 [Window][Scene] Pos=8,28 -Size=222,580 +Size=222,408 Collapsed=0 DockId=0x00000003,0 @@ -102,12 +102,18 @@ Pos=807,454 Size=306,82 Collapsed=0 +[Window][Assets] +Pos=8,438 +Size=1264,274 +Collapsed=0 +DockId=0x00000002,1 + [Docking][Data] DockSpace ID=0x9076BACA Window=0x34F970D7 Pos=8,28 Size=1264,684 Split=Y Selected=0x27A02DAA - DockNode ID=0x00000001 Parent=0x9076BACA SizeRef=1264,580 Split=X + DockNode ID=0x00000001 Parent=0x9076BACA SizeRef=1264,679 Split=X DockNode ID=0x00000005 Parent=0x00000001 SizeRef=887,684 Split=X DockNode ID=0x00000003 Parent=0x00000005 SizeRef=222,684 Selected=0xE601B12F DockNode ID=0x00000004 Parent=0x00000005 SizeRef=663,684 CentralNode=1 Selected=0x27A02DAA DockNode ID=0x00000006 Parent=0x00000001 SizeRef=375,684 Selected=0x36DC96AB - DockNode ID=0x00000002 Parent=0x9076BACA SizeRef=1264,102 Selected=0xBEDDA0C1 + DockNode ID=0x00000002 Parent=0x9076BACA SizeRef=1264,274 Selected=0x42C24103 diff --git a/include/Application.h b/include/Application.h index 2106ee8..ecec93f 100644 --- a/include/Application.h +++ b/include/Application.h @@ -6,6 +6,7 @@ #include "ShaderManager.h" #include "ModelManager.h" #include "MaterialManager.h" +#include "AssetManager.h" #include "TextureManager.h" #include "InputManager.h" #include @@ -25,6 +26,10 @@ public: bool IsEditorEnabled() const { return enableEditor; } bool HasScriptCompilationError() const { return scriptCompilationError; } entt::registry& GetRegistry() { return registry; } + AssetManager& GetAssetManager() { return assetManager; } + Camera3D& GetEditorCamera() { return editorCamera; } + bool IsUsingEditorCamera() const { return useEditorCamera; } + void SetUseEditorCamera(bool enabled) { useEditorCamera = enabled; } private: struct EntityScriptModule { @@ -43,6 +48,14 @@ private: bool valid = false; }; + struct SceneScriptInstance { + asIScriptObject* instance = nullptr; + std::string className; + asIScriptFunction* initFunc = nullptr; + asIScriptFunction* updateFunc = nullptr; + asIScriptFunction* shutdownFunc = nullptr; + }; + ScriptEngine scriptEngine; HotReload* hotReload; bool scriptCompilationError; @@ -59,12 +72,16 @@ private: ShaderManager shaderManager; ModelManager modelManager; MaterialManager materialManager; + AssetManager assetManager; TextureManager textureManager; InputManager inputManager; std::unordered_map entityScriptModules; std::unordered_map entityScriptBindings; unsigned int entityScriptModuleCounter = 0; std::string currentSceneScriptPath; + SceneScriptInstance sceneScriptInstance; + Camera3D editorCamera; + bool useEditorCamera = false; static const int WINDOW_WIDTH = 1280; static const int WINDOW_HEIGHT = 720; @@ -79,6 +96,9 @@ private: void ProcessSceneScriptChanges(); void ReloadEntityScriptModules(); EntityScriptModule* GetEntityScriptModule(const std::string& path); + void InitializeSceneScriptInstance(); + void ShutdownSceneScriptInstance(); + void CallSceneUpdate(float deltaTime); void RenderScene(); void Draw(); }; \ No newline at end of file diff --git a/include/AssetManager.h b/include/AssetManager.h new file mode 100644 index 0000000..9bc35c4 --- /dev/null +++ b/include/AssetManager.h @@ -0,0 +1,144 @@ +#pragma once + +#include "raylib.h" +#include +#include +#include + +class ModelManager; +class ShaderManager; +class MaterialManager; +class TextureManager; + +struct AssetEntry { + unsigned int id = 0; + std::string source; +}; + +struct TextureDefinition { + std::string path; +}; + +struct ShaderDefinition { + std::string vsPath; + std::string fsPath; +}; + +struct ModelDefinition { + enum class Type { + Path, + Primitive, + Heightmap, + Cubicmap, + Mesh + }; + + Type type = Type::Path; + std::string path; + std::string primitive; + std::vector params; +}; + +struct MaterialDefinition { + std::string shaderKey; + unsigned int shaderId = 0; + Color albedo = {255, 255, 255, 255}; + bool hasShaderKey = false; + bool hasShaderId = false; +}; + +class AssetManager +{ +public: + AssetManager(); + ~AssetManager(); + + void SetManagers(ModelManager* modelMgr, ShaderManager* shaderMgr, + MaterialManager* materialMgr, TextureManager* textureMgr); + + // Register an existing asset ID under a key (no loading performed). + bool RegisterTexture(const std::string& key, unsigned int id, const std::string& source = std::string()); + bool RegisterShader(const std::string& key, unsigned int id, const std::string& source = std::string()); + bool RegisterModel(const std::string& key, unsigned int id, const std::string& source = std::string()); + bool RegisterMaterial(const std::string& key, unsigned int id, const std::string& source = std::string()); + + // Load helpers that also register by key. + unsigned int LoadTexture(const std::string& key, const std::string& path); + unsigned int LoadShader(const std::string& key, const std::string& vsPath, const std::string& fsPath); + unsigned int LoadModel(const std::string& key, const std::string& path); + unsigned int LoadCube(const std::string& key, float width, float height, float length); + unsigned int LoadPoly(const std::string& key, int sides, float radius); + unsigned int LoadSphere(const std::string& key, float radius, int rings, int slices); + unsigned int LoadHemiSphere(const std::string& key, float radius, int rings, int slices); + unsigned int LoadPlane(const std::string& key, float width, float length, int resX, int resZ); + unsigned int LoadCylinder(const std::string& key, float radius, float height, int slices); + unsigned int LoadCone(const std::string& key, float radius, float height, int slices); + unsigned int LoadTorus(const std::string& key, float radius, float size, int radSeg, int sides); + unsigned int LoadKnot(const std::string& key, float radius, float size, int radSeg, int sides); + unsigned int LoadHeightmap(const std::string& key, const std::string& heightmapPath, float sizeX, float sizeY, float sizeZ); + unsigned int LoadCubicmap(const std::string& key, const std::string& cubicmapPath, float sizeX, float sizeY, float sizeZ); + unsigned int LoadFromMesh(const std::string& key, Mesh mesh, const std::string& source = std::string()); + unsigned int CreateMaterial(const std::string& key, unsigned int shaderId, Color albedo); + bool ApplyMeshTangents(const std::string& key, int meshIndex = 0); + + // Unload by key (removes registry entries). + bool UnloadTexture(const std::string& key); + bool UnloadShader(const std::string& key); + bool UnloadModel(const std::string& key); + bool UnloadMaterial(const std::string& key); + + // Query by key. + unsigned int GetTextureId(const std::string& key) const; + unsigned int GetShaderId(const std::string& key) const; + unsigned int GetModelId(const std::string& key) const; + unsigned int GetMaterialId(const std::string& key) const; + + // Query by id. + const std::string& GetTextureKey(unsigned int id) const; + const std::string& GetShaderKey(unsigned int id) const; + const std::string& GetModelKey(unsigned int id) const; + const std::string& GetMaterialKey(unsigned int id) const; + + // Asset listing for editor UI. + std::vector ListTextureKeys() const; + std::vector ListShaderKeys() const; + std::vector ListModelKeys() const; + std::vector ListMaterialKeys() const; + + // Source info (path or descriptive string). + std::string GetTextureSource(const std::string& key) const; + std::string GetShaderSource(const std::string& key) const; + std::string GetModelSource(const std::string& key) const; + std::string GetMaterialSource(const std::string& key) const; + + // Asset registry persistence. + bool SaveRegistry(const std::string& path) const; + bool LoadRegistry(const std::string& path); + + // Clear registry entries (does not unload underlying resources). + void Clear(); + +private: + ModelManager* modelManager = nullptr; + ShaderManager* shaderManager = nullptr; + MaterialManager* materialManager = nullptr; + TextureManager* textureManager = nullptr; + + std::unordered_map textureAssets; + std::unordered_map shaderAssets; + std::unordered_map modelAssets; + std::unordered_map materialAssets; + + std::unordered_map textureDefs; + std::unordered_map shaderDefs; + std::unordered_map modelDefs; + std::unordered_map materialDefs; + + std::unordered_map textureIds; + std::unordered_map shaderIds; + std::unordered_map modelIds; + std::unordered_map materialIds; + + const std::string& GetKeyForId(const std::unordered_map& map, unsigned int id) const; + std::vector ListKeys(const std::unordered_map& map) const; +}; diff --git a/include/ECSComponents.h b/include/ECSComponents.h index 80717d3..e466527 100644 --- a/include/ECSComponents.h +++ b/include/ECSComponents.h @@ -1,22 +1,31 @@ #pragma once #include "raylib.h" +#include "raymath.h" #include "entt.hpp" #include #include -// ECSTransform component - position, rotation, and scale +// ECSTransform component - position, rotation, scale, and cached local matrix struct ECSTransform { Vector3 position; + Vector3 rotation; // Euler rotation (radians) Vector3 scale; - float rotation; // Rotation around Y axis in radians + Matrix localMatrix; ECSTransform() : position{0.0f, 0.0f, 0.0f} + , rotation{0.0f, 0.0f, 0.0f} , scale{1.0f, 1.0f, 1.0f} - , rotation(0.0f) {} + , localMatrix(MatrixIdentity()) {} - ECSTransform(Vector3 pos, Vector3 scl = {1.0f, 1.0f, 1.0f}, float rot = 0.0f) - : position(pos), scale(scl), rotation(rot) {} + ECSTransform(Vector3 pos, Vector3 scl, Vector3 rot) + : position(pos), rotation(rot), scale(scl), localMatrix(MatrixIdentity()) {} + + ECSTransform(Vector3 pos, Vector3 scl = {1.0f, 1.0f, 1.0f}, float rotY = 0.0f) + : position(pos) + , rotation{0.0f, rotY, 0.0f} + , scale(scl) + , localMatrix(MatrixIdentity()) {} }; // Velocity component - for movement @@ -111,13 +120,15 @@ struct Hierarchy { // WorldTransform component - computed from hierarchy + local transform struct WorldTransform { Vector3 position; + Vector3 rotation; // Euler rotation (radians) Vector3 scale; - float rotation; // Rotation around Y axis in radians + Matrix worldMatrix; WorldTransform() : position{0.0f, 0.0f, 0.0f} + , rotation{0.0f, 0.0f, 0.0f} , scale{1.0f, 1.0f, 1.0f} - , rotation(0.0f) {} + , worldMatrix(MatrixIdentity()) {} }; // Camera3D component - camera settings diff --git a/include/ImViewGuizmoRaymath.h b/include/ImViewGuizmoRaymath.h new file mode 100644 index 0000000..d418e0e --- /dev/null +++ b/include/ImViewGuizmoRaymath.h @@ -0,0 +1,155 @@ +#pragma once + +#include "raylib.h" +#include "raymath.h" +#include "imgui.h" + +#define IMVIEWGUIZMO_VEC3 Vector3 +#define IMVIEWGUIZMO_VEC4 Vector4 +#define IMVIEWGUIZMO_QUAT Quaternion +#define IMVIEWGUIZMO_MAT4 Matrix + +namespace ImViewGuizmo { +namespace GizmoMath { + inline float get_vec_comp(const Vector3& v, int index) { + switch (index) { + case 0: return v.x; + case 1: return v.y; + default: return v.z; + } + } + + inline float get_vec_comp(const Vector4& v, int index) { + switch (index) { + case 0: return v.x; + case 1: return v.y; + case 2: return v.z; + default: return v.w; + } + } + + inline Vector3 make_vec3(float x, float y, float z) { return {x, y, z}; } + inline Vector4 make_vec4(float x, float y, float z, float w) { return {x, y, z, w}; } + + inline Quaternion angleAxis(float angle, const Vector3& axis) { + return QuaternionFromAxisAngle(axis, angle); + } + + inline Quaternion quatLookAt(const Vector3& dir, const Vector3& up) { + Vector3 forward = Vector3Normalize(dir); + Vector3 right = Vector3Normalize(Vector3CrossProduct(up, forward)); + Vector3 correctedUp = Vector3CrossProduct(forward, right); + + Matrix mat = MatrixIdentity(); + mat.m0 = right.x; + mat.m1 = right.y; + mat.m2 = right.z; + mat.m4 = correctedUp.x; + mat.m5 = correctedUp.y; + mat.m6 = correctedUp.z; + mat.m8 = forward.x; + mat.m9 = forward.y; + mat.m10 = forward.z; + return QuaternionFromMatrix(mat); + } + + inline Matrix mat4_identity() { return MatrixIdentity(); } + + inline Vector3 cross(const Vector3& a, const Vector3& b) { + return Vector3CrossProduct(a, b); + } + + inline float dot(const Vector3& a, const Vector3& b) { + return Vector3DotProduct(a, b); + } + + inline float dot(const Quaternion& a, const Quaternion& b) { + return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; + } + + inline float length(const Vector3& v) { + return Vector3Length(v); + } + + inline float length2(const Vector3& v) { + return v.x * v.x + v.y * v.y + v.z * v.z; + } + + inline Vector3 normalize(const Vector3& v) { + return Vector3Normalize(v); + } + + inline Vector3 mix(const Vector3& a, const Vector3& b, float t) { + return Vector3Lerp(a, b, t); + } + + inline Vector3 add_vv(const Vector3& a, const Vector3& b) { + return Vector3Add(a, b); + } + + inline Vector3 subtract_vv(const Vector3& a, const Vector3& b) { + return Vector3Subtract(a, b); + } + + inline Vector3 multiply_vf(const Vector3& v, float f) { + return Vector3Scale(v, f); + } + + inline Matrix mat4_cast(const Quaternion& q) { + return QuaternionToMatrix(q); + } + + inline Matrix transpose(const Matrix& m) { + return MatrixTranspose(m); + } + + inline Vector3 get_matrix_col(const Matrix& m, int col) { + switch (col) { + case 0: return {m.m0, m.m1, m.m2}; + case 1: return {m.m4, m.m5, m.m6}; + case 2: return {m.m8, m.m9, m.m10}; + default: return {m.m12, m.m13, m.m14}; + } + } + + inline void set_matrix_col(Matrix& m, int col, const Vector4& v) { + switch (col) { + case 0: + m.m0 = v.x; m.m1 = v.y; m.m2 = v.z; m.m3 = v.w; + break; + case 1: + m.m4 = v.x; m.m5 = v.y; m.m6 = v.z; m.m7 = v.w; + break; + case 2: + m.m8 = v.x; m.m9 = v.y; m.m10 = v.z; m.m11 = v.w; + break; + default: + m.m12 = v.x; m.m13 = v.y; m.m14 = v.z; m.m15 = v.w; + break; + } + } + + inline Quaternion multiply_qq(const Quaternion& a, const Quaternion& b) { + return QuaternionMultiply(a, b); + } + + inline Vector3 multiply_qv(const Quaternion& q, const Vector3& v) { + return Vector3RotateByQuaternion(v, q); + } + + inline Matrix multiply_mm(const Matrix& a, const Matrix& b) { + return MatrixMultiply(a, b); + } + + inline Vector4 multiply_mv4(const Matrix& m, const Vector4& v) { + Vector4 result; + result.x = m.m0 * v.x + m.m4 * v.y + m.m8 * v.z + m.m12 * v.w; + result.y = m.m1 * v.x + m.m5 * v.y + m.m9 * v.z + m.m13 * v.w; + result.z = m.m2 * v.x + m.m6 * v.y + m.m10 * v.z + m.m14 * v.w; + result.w = m.m3 * v.x + m.m7 * v.y + m.m11 * v.z + m.m15 * v.w; + return result; + } +} +} // namespace ImViewGuizmo + +#include "ImViewGuizmo.h" diff --git a/include/SceneLoader.h b/include/SceneLoader.h index 7f940ce..b252e99 100644 --- a/include/SceneLoader.h +++ b/include/SceneLoader.h @@ -6,10 +6,12 @@ class ModelManager; class ShaderManager; class TextureManager; +class AssetManager; // Set global context used by scene loading void SetSceneContext(entt::registry* registry, ModelManager* modelManager, ShaderManager* shaderManager, TextureManager* textureManager); +void SetSceneAssetManager(AssetManager* assetManager); // Load a scene from a TOML-like file. Returns the root entity (or entt::null on failure). entt::entity LoadSceneFromFile(const std::string& path, bool clearExisting); diff --git a/include/gui/GuiManager.h b/include/gui/GuiManager.h index dff5458..4f58e17 100644 --- a/include/gui/GuiManager.h +++ b/include/gui/GuiManager.h @@ -5,6 +5,7 @@ #include "gui/fa-solid-900.h" #include "gui/ImGuiNotify.hpp" #include "LogWindow.h" // Include the new LogWindow class +#include "raylib.h" #include #include #include @@ -24,11 +25,20 @@ public: void Shutdown(); private: + enum class AssetUnloadType { + None, + Texture, + Shader, + Model, + Material + }; + void SetupDockspace(RenderTexture2D& renderTexture); void RenderNotifications(); void RenderErrorBanner(); void SetTheme(); void RenderSceneWindow(); + void RenderAssetWindow(); void RenderInspectorWindow(); void RenderEntityNode(entt::entity entity); bool IsEntityAncestor(entt::entity ancestor, entt::entity entity) const; @@ -75,6 +85,7 @@ private: bool showLogWindow = true; bool showSceneWindow = true; bool showInspectorWindow = true; + bool showAssetWindow = false; Application *app; LogWindow logWindow; // Add LogWindow as a member entt::entity selectedEntity = entt::null; @@ -85,6 +96,7 @@ private: char sceneScriptPathBuffer[260] = {0}; std::string lastSceneScriptPath; ImVec2 desiredRenderSize = ImVec2(0.0f, 0.0f); + ImGuiID mainDockspaceId = 0; bool requestSceneNew = false; bool requestSceneLoad = false; bool requestSceneSave = false; @@ -92,6 +104,51 @@ private: char sceneSavePath[260] = {0}; int addComponentIndex = 0; + char textureKeyBuffer[128] = {0}; + char texturePathBuffer[260] = {0}; + int textureUnloadIndex = 0; + + char shaderKeyBuffer[128] = {0}; + char shaderVsPathBuffer[260] = {0}; + char shaderFsPathBuffer[260] = {0}; + int shaderUnloadIndex = 0; + + char modelKeyBuffer[128] = {0}; + char modelPathBuffer[260] = {0}; + char modelHeightmapPathBuffer[260] = {0}; + char modelCubicmapPathBuffer[260] = {0}; + int modelUnloadIndex = 0; + int modelPrimitiveIndex = 0; + float modelWidth = 1.0f; + float modelHeight = 1.0f; + float modelLength = 1.0f; + float modelRadius = 0.5f; + int modelRings = 16; + int modelSlices = 16; + int modelResX = 1; + int modelResZ = 1; + int modelRadSeg = 16; + int modelSides = 8; + int modelPolySides = 6; + float modelSizeX = 1.0f; + float modelSizeY = 1.0f; + float modelSizeZ = 1.0f; + int modelAutoKeyCounter = 0; + + char materialKeyBuffer[128] = {0}; + int materialUnloadIndex = 0; + int materialShaderIndex = 0; + int materialShaderId = 0; + float materialAlbedo[4] = {1.0f, 1.0f, 1.0f, 1.0f}; + + AssetUnloadType pendingAssetUnloadType = AssetUnloadType::None; + std::string pendingAssetUnloadKey; + + Vector3 editorCameraPivot = {0.0f, 0.0f, 0.0f}; + Vector3 editorPivotOffset = {0.0f, 0.0f, 0.0f}; + entt::entity editorPivotEntity = entt::null; + bool editorPivotInitialized = false; + std::unordered_map scriptEditableCache; std::unordered_map> scriptEditableStaged; std::unordered_map scriptEditableInstancePtr; diff --git a/include/scripting/ResourceBindings.h b/include/scripting/ResourceBindings.h index 36150e4..78c92eb 100644 --- a/include/scripting/ResourceBindings.h +++ b/include/scripting/ResourceBindings.h @@ -5,6 +5,8 @@ class ShaderManager; class ModelManager; class MaterialManager; class TextureManager; +class AssetManager; void SetResourceManagers(ShaderManager* shaderMgr, ModelManager* modelMgr, MaterialManager* materialMgr, TextureManager* textureMgr); +void SetAssetManager(AssetManager* assetMgr); void RegisterResourceBindings(asIScriptEngine *engine); diff --git a/include/scripting/ScriptEngine.h b/include/scripting/ScriptEngine.h index 6f016af..76cb787 100644 --- a/include/scripting/ScriptEngine.h +++ b/include/scripting/ScriptEngine.h @@ -26,6 +26,7 @@ public: void RestoreScriptState(const std::string &state); asIScriptEngine* GetEngine() const { return engine; } + asIScriptModule* GetCurrentModule() const { return currentModule; } asIScriptFunction* GetUpdateFunction() const { return updateFunc; } asIScriptFunction* GetInitFunction() const { return initFunc; } asIScriptFunction* GetShutdownFunction() const { return shutdownFunc; } @@ -37,6 +38,8 @@ public: asIScriptFunction* GetObjectMethod(asIScriptModule* module, const std::string& className, const std::string& methodDecl); // Call an object method; method must be an object method (use GetObjectMethod) void CallObjectMethod(asIScriptFunction* method, asIScriptObject* object, unsigned int entityId, float dt); + // Call a scene object method (Init/Update/Shutdown) without entity id + void CallSceneObjectMethod(asIScriptFunction* method, asIScriptObject* object, float dt = 0.0f); private: asIScriptEngine* engine; diff --git a/scenes/demo.toml b/scenes/demo.toml index cae0739..5364bed 100644 --- a/scenes/demo.toml +++ b/scenes/demo.toml @@ -3,29 +3,32 @@ id = "entity_1" tag = "Root" position = [0.000, 0.000, 0.000] scale = [1.000, 1.000, 1.000] -rotation_deg = 0.000 +rotation_deg = [0.000, 0.000, 0.000] [[entity]] id = "entity_2" parent = "entity_1" tag = "Parent" -position = [2.000, 0.000, 0.000] +position = [2.000, -6.197, 0.000] scale = [1.000, 1.000, 1.000] -rotation_deg = 0.000 -model = "cube" -model_size = [1.000, 1.000, 1.000] +rotation_deg = [0.000, 0.000, 0.000] +model_asset = "Torus" +model_id = 2 color = 0x00FF00FF outline_size = 0.000 shader_vs = "shaders/toon.vs" shader_fs = "shaders/toon.fs" +script = "scripts/ball.as" +script_var_amplitude = "7.293000" +script_var_speed = "0.219000" [[entity]] id = "entity_3" parent = "entity_2" tag = "Child" -position = [0.500, 1.248, 1.600] +position = [0.500, -1.434, 1.600] scale = [0.600, 0.600, 0.600] -rotation_deg = 0.000 +rotation_deg = [0.000, 0.000, 0.000] model = "sphere" radius = 0.500 rings = 16 @@ -41,9 +44,9 @@ script_var_amplitude = "1.452000" id = "entity_6" parent = "entity_2" tag = "Child 2" -position = [0.000, 0.587, 1.900] +position = [0.000, 0.848, 1.900] scale = [1.000, 1.000, 1.000] -rotation_deg = 0.000 +rotation_deg = [0.000, 0.000, 0.000] model = "sphere" radius = 0.500 rings = 16 diff --git a/scripts/as.predefined b/scripts/as.predefined index 875bb92..00e35bc 100644 --- a/scripts/as.predefined +++ b/scripts/as.predefined @@ -44,7 +44,9 @@ namespace ECS { void GetPosition(uint entity, float &out x, float &out y, float &out z); void SetScale(uint entity, float x, float y, float z); void SetRotation(uint entity, float rotation); + void SetRotationEuler(uint entity, float x, float y, float z); float GetRotation(uint entity); + void GetRotationEuler(uint entity, float &out x, float &out y, float &out z); bool HasTransform(uint entity); void RemoveTransform(uint entity); @@ -63,6 +65,21 @@ namespace ECS { void SetSpriteShader(uint entity, uint shaderId); bool HasSprite(uint entity); void RemoveSprite(uint entity); + + // Texture component + void AddTexture(uint entity, uint textureId); + void SetTextureId(uint entity, uint textureId); + uint GetTextureId(uint entity); + bool HasTexture(uint entity); + void RemoveTexture(uint entity); + + // UV transform component + void AddUVTransform(uint entity, float scaleX, float scaleY, float offsetX = 0.0f, float offsetY = 0.0f, float rotation = 0.0f); + void SetUVScale(uint entity, float scaleX, float scaleY); + void SetUVOffset(uint entity, float offsetX, float offsetY); + void SetUVRotation(uint entity, float rotation); + bool HasUVTransform(uint entity); + void RemoveUVTransform(uint entity); // Tag component void AddTag(uint entity, const string &in name); @@ -131,6 +148,34 @@ namespace Material { void SetAlbedo(uint id, uint8 r, uint8 g, uint8 b, uint8 a); } +// Asset manager (keyed assets) +namespace Asset { + uint LoadTexture(const string &in key, const string &in path); + uint LoadShader(const string &in key, const string &in vsPath, const string &in fsPath); + uint LoadModel(const string &in key, const string &in path); + uint LoadCube(const string &in key, float width, float height, float length); + uint LoadPoly(const string &in key, int sides, float radius); + uint LoadSphere(const string &in key, float radius, int rings, int slices); + uint LoadHemiSphere(const string &in key, float radius, int rings, int slices); + uint LoadPlane(const string &in key, float width, float length, int resX, int resZ); + uint LoadCylinder(const string &in key, float radius, float height, int slices); + uint LoadCone(const string &in key, float radius, float height, int slices); + uint LoadTorus(const string &in key, float radius, float size, int radSeg, int sides); + uint LoadKnot(const string &in key, float radius, float size, int radSeg, int sides); + uint LoadHeightmap(const string &in key, const string &in heightmapPath, float sizeX, float sizeY, float sizeZ); + uint LoadCubicmap(const string &in key, const string &in cubicmapPath, float sizeX, float sizeY, float sizeZ); + uint CreateMaterial(const string &in key, uint shaderId, uint8 r, uint8 g, uint8 b, uint8 a); + bool UnloadTexture(const string &in key); + bool UnloadShader(const string &in key); + bool UnloadModel(const string &in key); + bool UnloadMaterial(const string &in key); + uint GetTextureId(const string &in key); + uint GetShaderId(const string &in key); + uint GetModelId(const string &in key); + uint GetMaterialId(const string &in key); + bool ApplyMeshTangents(const string &in key, int meshIndex = 0); +} + namespace Scene { uint Load(const string &in path, bool clearExisting = true); void Clear(); @@ -189,6 +234,8 @@ float GetActionStrength(const string &in actionName); void RegisterAction(const string &in actionName); void BindKeyboard(const string &in actionName, int keyCode); void BindMouseButton(const string &in actionName, int mouseButton); +void BindGamepadButton(const string &in actionName, int gamepadId, int button); +void BindGamepadAxis(const string &in actionName, int gamepadId, int axis, float threshold = 0.5f, bool negative = false); void ClearBindings(const string &in actionName); namespace Key { @@ -215,3 +262,33 @@ namespace MouseButton { const int MIDDLE = 2; } +namespace GamepadButton { + const int UNKNOWN = 0; + const int LEFT_FACE_UP = 1; + const int LEFT_FACE_RIGHT = 2; + const int LEFT_FACE_DOWN = 3; + const int LEFT_FACE_LEFT = 4; + const int RIGHT_FACE_UP = 5; + const int RIGHT_FACE_RIGHT = 6; + const int RIGHT_FACE_DOWN = 7; + const int RIGHT_FACE_LEFT = 8; + const int LEFT_TRIGGER_1 = 9; + const int LEFT_TRIGGER_2 = 10; + const int RIGHT_TRIGGER_1 = 11; + const int RIGHT_TRIGGER_2 = 12; + const int MIDDLE_LEFT = 13; + const int MIDDLE = 14; + const int MIDDLE_RIGHT = 15; + const int LEFT_THUMB = 16; + const int RIGHT_THUMB = 17; +} + +namespace GamepadAxis { + const int LEFT_X = 0; + const int LEFT_Y = 1; + const int RIGHT_X = 2; + const int RIGHT_Y = 3; + const int LEFT_TRIGGER = 4; + const int RIGHT_TRIGGER = 5; +} + diff --git a/scripts/game.as b/scripts/game.as index 1cc28b0..cc6f974 100644 --- a/scripts/game.as +++ b/scripts/game.as @@ -1,65 +1,67 @@ // ECS scenegraph demo // Loads a scene from TOML and animates the hierarchy -uint sceneRoot = 0; -uint camera = 0; -uint light = 0; -float time = 0.0f; -bool lightToggle = false; +class SceneScript { + uint sceneRoot = 0; + uint camera = 0; + uint light = 0; + float time = 0.0f; + bool lightToggle = false; -void Init() { - Log(LOG_TRACE, "Initialization complete - Scenegraph demo!"); - Toast::Success("Scenegraph demo initialized."); + void Init() { + Log(LOG_TRACE, "Initialization complete - Scenegraph demo!"); + Toast::Success("Scenegraph demo initialized."); - sceneRoot = Scene::Load("scenes/demo.toml"); - if (!ECS::IsValid(sceneRoot)) { - Toast::Error("Failed to load scene"); + sceneRoot = Scene::Load("scenes/demo.toml"); + if (!ECS::IsValid(sceneRoot)) { + Toast::Error("Failed to load scene"); + } + + // === Set up camera === + camera = ECS::CreateEntity(); + ECS::AddCamera3D(camera, + 5.0, 5.0, 5.0, // position + 0.0, 0.0, 0.0, // target + 45.0); // fovy + ECS::AddTag(camera, "MainCamera"); + + // === Set up light === + light = ECS::CreateEntity(); + ECS::AddLight(light, 0.5, 0.7, 0.3, 1.0); // direction + intensity + ECS::AddTag(light, "MainLight"); } - // === Set up camera === - camera = ECS::CreateEntity(); - ECS::AddCamera3D(camera, - 5.0, 5.0, 5.0, // position - 0.0, 0.0, 0.0, // target - 45.0); // fovy - ECS::AddTag(camera, "MainCamera"); - - // === Set up light === - light = ECS::CreateEntity(); - ECS::AddLight(light, 0.5, 0.7, 0.3, 1.0); // direction + intensity - ECS::AddTag(light, "MainLight"); -} - -void Shutdown() { - Log(LOG_TRACE, "Shutdown complete!"); -} - -void Update(float dt) { - time += dt; - - // Rotate the scene root to show parent/child propagation - if (ECS::IsValid(sceneRoot) && ECS::HasTransform(sceneRoot)) { - ECS::SetRotation(sceneRoot, time * 0.5f); + void Shutdown() { + Log(LOG_TRACE, "Shutdown complete!"); } - // Orbit the camera around the scene - if (ECS::HasCamera3D(camera)) { - float angle = time * 0.3f; - float radius = 7.0f; - float x = Math::Cos(angle) * radius; - float z = Math::Sin(angle) * radius; - ECS::SetCameraPosition(camera, x, 5.0f, z); - } + void Update(float dt) { + time += dt; - // Toggle light with jump action - if (IsActionPressed("jump")) { - lightToggle = !lightToggle; - if (lightToggle) { - ECS::SetLightDirection(light, -0.5, 0.7, -0.3); - Toast::Info("Light direction changed!"); - } else { - ECS::SetLightDirection(light, 0.5, 0.7, 0.3); - Toast::Info("Light direction reset!"); + // Rotate the scene root to show parent/child propagation + if (ECS::IsValid(sceneRoot) && ECS::HasTransform(sceneRoot)) { + ECS::SetRotation(sceneRoot, time * 0.5f); + } + + // Orbit the camera around the scene + if (ECS::HasCamera3D(camera)) { + float angle = time * 0.3f; + float radius = 7.0f; + float x = Math::Cos(angle) * radius; + float z = Math::Sin(angle) * radius; + ECS::SetCameraPosition(camera, x, 5.0f, z); + } + + // Toggle light with jump action + if (IsActionPressed("jump")) { + lightToggle = !lightToggle; + if (lightToggle) { + ECS::SetLightDirection(light, -0.5, 0.7, -0.3); + Toast::Info("Light direction changed!"); + } else { + ECS::SetLightDirection(light, 0.5, 0.7, 0.3); + Toast::Info("Light direction reset!"); + } } } } diff --git a/scripts/scene_example.as b/scripts/scene_example.as new file mode 100644 index 0000000..95f9948 --- /dev/null +++ b/scripts/scene_example.as @@ -0,0 +1,20 @@ +// Example scene script using a class instance. +class SceneScript { + float time = 0.0f; + + void Init() { + Log(LOG_INFO, "SceneScript.Init (example)"); + } + + void Update(float dt) { + time += dt; + if (time > 1.0f) { + time = 0.0f; + Log(LOG_DEBUG, "SceneScript.Update tick"); + } + } + + void Shutdown() { + Log(LOG_INFO, "SceneScript.Shutdown (example)"); + } +} diff --git a/src/Application.cpp b/src/Application.cpp index 5f15c64..ad248ca 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -28,6 +28,7 @@ const char *Application::WINDOW_TITLE = "Simian"; const char *Application::SCRIPT_FILE = "scripts/game.as"; +static const char* kAssetRegistryFile = "assets/registry.toml"; Application::Application() : hotReload(nullptr), scriptCompilationError(false), logFile(nullptr), renderTexture{} @@ -85,8 +86,16 @@ bool Application::Initialize(int argc, char *argv[]) extern void SetResourceManagers(ShaderManager*, ModelManager*, MaterialManager*, TextureManager*); SetResourceManagers(&shaderManager, &modelManager, &materialManager, &textureManager); + extern void SetAssetManager(AssetManager*); + SetAssetManager(&assetManager); + + assetManager.SetManagers(&modelManager, &shaderManager, &materialManager, &textureManager); + // Set up scene loader context SetSceneContext(®istry, &modelManager, &shaderManager, &textureManager); + SetSceneAssetManager(&assetManager); + + assetManager.LoadRegistry(kAssetRegistryFile); // Set up input manager for script access extern void SetGlobalInputManager(InputManager*); @@ -115,12 +124,18 @@ bool Application::Initialize(int argc, char *argv[]) renderTexture = LoadRenderTexture(WINDOW_WIDTH, WINDOW_HEIGHT); } + editorCamera.position = {5.0f, 5.0f, 5.0f}; + editorCamera.target = {0.0f, 0.0f, 0.0f}; + editorCamera.up = {0.0f, 1.0f, 0.0f}; + editorCamera.fovy = 45.0f; + editorCamera.projection = CAMERA_PERSPECTIVE; + return true; } void Application::Run() { - scriptEngine.CallScriptFunction(scriptEngine.GetInitFunction()); + InitializeSceneScriptInstance(); while (!WindowShouldClose() && !queueShutdown) { float deltaTime = GetFrameTime(); @@ -152,7 +167,7 @@ void Application::Update(float deltaTime) { Toast::Success("Script reloaded successfully."); // Should call init function again or things don't work - scriptEngine.CallScriptFunction(scriptEngine.GetInitFunction()); + InitializeSceneScriptInstance(); } // Refresh any entity script modules so class-based entity scripts @@ -161,8 +176,8 @@ void Application::Update(float deltaTime) } } - // Call script Update function - scriptEngine.CallScriptFunction(scriptEngine.GetUpdateFunction(), deltaTime); + // Call scene script Update (class instance or fallback) + CallSceneUpdate(deltaTime); UpdateEntityScripts(deltaTime); @@ -181,8 +196,8 @@ void Application::UpdateSystems(float deltaTime) transform.position.y += velocity.linear.y * deltaTime; transform.position.z += velocity.linear.z * deltaTime; - // Apply angular velocity - transform.rotation += velocity.angular * deltaTime; }); + // Apply angular velocity (default to Y axis) + transform.rotation.y += velocity.angular * deltaTime; }); UpdateWorldTransforms(registry); } @@ -454,6 +469,97 @@ void Application::ShutdownEntityScripts() } } +void Application::InitializeSceneScriptInstance() +{ + ShutdownSceneScriptInstance(); + + asIScriptModule* module = scriptEngine.GetCurrentModule(); + if (!module) { + return; + } + + asITypeInfo* objType = nullptr; + asIScriptFunction* initMethod = nullptr; + asIScriptFunction* updateMethod = nullptr; + asIScriptFunction* shutdownMethod = nullptr; + + const int count = module->GetObjectTypeCount(); + for (int i = 0; i < count; ++i) { + asITypeInfo* typeInfo = module->GetObjectTypeByIndex(i); + if (!typeInfo) { + continue; + } + if ((typeInfo->GetFlags() & asOBJ_SCRIPT_OBJECT) == 0) { + continue; + } + + asIScriptFunction* typeInit = typeInfo->GetMethodByDecl("void SceneInit()"); + if (!typeInit) { + typeInit = typeInfo->GetMethodByDecl("void Init()"); + } + asIScriptFunction* typeUpdate = typeInfo->GetMethodByDecl("void SceneUpdate(float)"); + if (!typeUpdate) { + typeUpdate = typeInfo->GetMethodByDecl("void Update(float)"); + } + asIScriptFunction* typeShutdown = typeInfo->GetMethodByDecl("void SceneShutdown()"); + if (!typeShutdown) { + typeShutdown = typeInfo->GetMethodByDecl("void Shutdown()"); + } + + if (typeInit || typeUpdate || typeShutdown) { + objType = typeInfo; + initMethod = typeInit; + updateMethod = typeUpdate; + shutdownMethod = typeShutdown; + break; + } + } + + if (objType) { + const char* name = objType->GetName(); + sceneScriptInstance.className = name ? name : std::string(); + sceneScriptInstance.initFunc = initMethod; + sceneScriptInstance.updateFunc = updateMethod; + sceneScriptInstance.shutdownFunc = shutdownMethod; + sceneScriptInstance.instance = scriptEngine.CreateObjectInstance(module, sceneScriptInstance.className); + + if (sceneScriptInstance.instance) { + if (sceneScriptInstance.initFunc) { + scriptEngine.CallSceneObjectMethod(sceneScriptInstance.initFunc, sceneScriptInstance.instance, 0.0f); + } + return; + } + } + + // Fallback to free functions when no class-based scene script is available. + scriptEngine.CallScriptFunction(scriptEngine.GetInitFunction()); +} + +void Application::ShutdownSceneScriptInstance() +{ + if (sceneScriptInstance.instance) { + if (sceneScriptInstance.shutdownFunc) { + scriptEngine.CallSceneObjectMethod(sceneScriptInstance.shutdownFunc, sceneScriptInstance.instance, 0.0f); + } + scriptEngine.ReleaseObjectInstance(sceneScriptInstance.instance); + sceneScriptInstance.instance = nullptr; + } + + sceneScriptInstance.className.clear(); + sceneScriptInstance.initFunc = nullptr; + sceneScriptInstance.updateFunc = nullptr; + sceneScriptInstance.shutdownFunc = nullptr; +} + +void Application::CallSceneUpdate(float deltaTime) +{ + if (sceneScriptInstance.instance && sceneScriptInstance.updateFunc) { + scriptEngine.CallSceneObjectMethod(sceneScriptInstance.updateFunc, sceneScriptInstance.instance, deltaTime); + return; + } + scriptEngine.CallScriptFunction(scriptEngine.GetUpdateFunction(), deltaTime); +} + void Application::ProcessSceneScriptChanges() { std::string sceneScriptPath; @@ -486,7 +592,7 @@ void Application::ProcessSceneScriptChanges() } hotReload = new HotReload(watchPath); - scriptEngine.CallScriptFunction(scriptEngine.GetInitFunction()); + InitializeSceneScriptInstance(); } void Application::ReloadEntityScriptModules() @@ -575,19 +681,24 @@ void Application::RenderScene() // Query for active camera (first one found with Camera3DComponent) Camera3D camera = {}; bool hasCamera = false; - - auto cameraView = registry.view(); - cameraView.each([&](auto& camComp) { - if (!hasCamera) { - camera.position = camComp.position; - camera.target = camComp.target; - camera.up = camComp.up; - camera.fovy = camComp.fovy; - camera.projection = camComp.projection; - hasCamera = true; - } - }); - + + if (useEditorCamera) { + camera = editorCamera; + hasCamera = true; + } else { + auto cameraView = registry.view(); + cameraView.each([&](auto& camComp) { + if (!hasCamera) { + camera.position = camComp.position; + camera.target = camComp.target; + camera.up = camComp.up; + camera.fovy = camComp.fovy; + camera.projection = camComp.projection; + hasCamera = true; + } + }); + } + // If no camera found, use a default one if (!hasCamera) { camera.position = {5, 5, 5}; @@ -682,8 +793,18 @@ void Application::RenderScene() } // Draw model using Sprite.color as the tint - DrawModelEx(*model, transform.position, Vector3{0, 1, 0}, - transform.rotation * RAD2DEG, transform.scale, + Quaternion rotation = QuaternionFromEuler(transform.rotation.x, transform.rotation.y, transform.rotation.z); + Vector3 axis = {0.0f, 1.0f, 0.0f}; + float angle = 0.0f; + QuaternionToAxisAngle(rotation, &axis, &angle); + float axisLength = sqrtf(axis.x * axis.x + axis.y * axis.y + axis.z * axis.z); + if (axisLength <= 0.0001f) { + axis = {0.0f, 1.0f, 0.0f}; + angle = 0.0f; + } + + DrawModelEx(*model, transform.position, axis, + angle * RAD2DEG, transform.scale, sprite.color); if (restoreTexture) { @@ -743,6 +864,7 @@ void Application::Shutdown() ShutdownEntityScripts(); + ShutdownSceneScriptInstance(); scriptEngine.Shutdown(); if (enableEditor) { @@ -757,6 +879,8 @@ void Application::Shutdown() // Unload all resources before closing window (while GL context is still valid) materialManager.Clear(); + assetManager.SaveRegistry(kAssetRegistryFile); + assetManager.Clear(); shaderManager.UnloadAll(); modelManager.UnloadAll(); textureManager.UnloadAll(); diff --git a/src/AssetManager.cpp b/src/AssetManager.cpp new file mode 100644 index 0000000..17df0e5 --- /dev/null +++ b/src/AssetManager.cpp @@ -0,0 +1,1089 @@ +#include "AssetManager.h" +#include "ModelManager.h" +#include "ShaderManager.h" +#include "MaterialManager.h" +#include "TextureManager.h" +#include "log/log.h" +#include +#include +#include +#include +#include +#include + +namespace { +std::string TrimAsset(const std::string& value) { + size_t start = 0; + while (start < value.size() && std::isspace(static_cast(value[start]))) { + start++; + } + size_t end = value.size(); + while (end > start && std::isspace(static_cast(value[end - 1]))) { + end--; + } + return value.substr(start, end - start); +} + +std::string StripCommentAsset(const std::string& line) { + bool inString = false; + for (size_t i = 0; i < line.size(); ++i) { + char c = line[i]; + if (c == '"') { + inString = !inString; + } + if (!inString && c == '#') { + return line.substr(0, i); + } + } + return line; +} + +bool ParseStringAsset(const std::string& value, std::string& out) { + std::string trimmed = TrimAsset(value); + if (trimmed.size() >= 2 && trimmed.front() == '"' && trimmed.back() == '"') { + out = trimmed.substr(1, trimmed.size() - 2); + return true; + } + return false; +} + +bool ParseFloatList(const std::string& value, std::vector& out) { + std::string trimmed = TrimAsset(value); + if (trimmed.size() < 2 || trimmed.front() != '[' || trimmed.back() != ']') { + return false; + } + + std::string inner = trimmed.substr(1, trimmed.size() - 2); + std::stringstream ss(inner); + std::string token; + out.clear(); + + while (std::getline(ss, token, ',')) { + std::string piece = TrimAsset(token); + if (piece.empty()) { + continue; + } + try { + out.push_back(std::stof(piece)); + } catch (...) { + return false; + } + } + + return !out.empty(); +} + +std::string EscapeStringAsset(const std::string& value) { + std::string out; + out.reserve(value.size()); + for (char c : value) { + if (c == '\\' || c == '"') { + out.push_back('\\'); + } + out.push_back(c); + } + return out; +} + +void WriteFloatList(std::ostream& out, const std::vector& values) { + out << '['; + for (size_t i = 0; i < values.size(); ++i) { + if (i > 0) { + out << ", "; + } + out << values[i]; + } + out << ']'; +} +} + +AssetManager::AssetManager() = default; + +AssetManager::~AssetManager() = default; + +void AssetManager::SetManagers(ModelManager* modelMgr, ShaderManager* shaderMgr, + MaterialManager* materialMgr, TextureManager* textureMgr) +{ + modelManager = modelMgr; + shaderManager = shaderMgr; + materialManager = materialMgr; + textureManager = textureMgr; +} + +bool AssetManager::RegisterTexture(const std::string& key, unsigned int id, const std::string& source) +{ + if (key.empty() || id == 0) { + return false; + } + if (textureAssets.find(key) != textureAssets.end()) { + return textureAssets[key].id == id; + } + + textureAssets[key] = AssetEntry{id, source}; + textureIds[id] = key; + return true; +} + +bool AssetManager::RegisterShader(const std::string& key, unsigned int id, const std::string& source) +{ + if (key.empty() || id == 0) { + return false; + } + if (shaderAssets.find(key) != shaderAssets.end()) { + return shaderAssets[key].id == id; + } + + shaderAssets[key] = AssetEntry{id, source}; + shaderIds[id] = key; + return true; +} + +bool AssetManager::RegisterModel(const std::string& key, unsigned int id, const std::string& source) +{ + if (key.empty() || id == 0) { + return false; + } + if (modelAssets.find(key) != modelAssets.end()) { + return modelAssets[key].id == id; + } + + modelAssets[key] = AssetEntry{id, source}; + modelIds[id] = key; + return true; +} + +bool AssetManager::RegisterMaterial(const std::string& key, unsigned int id, const std::string& source) +{ + if (key.empty() || id == 0) { + return false; + } + if (materialAssets.find(key) != materialAssets.end()) { + return materialAssets[key].id == id; + } + + materialAssets[key] = AssetEntry{id, source}; + materialIds[id] = key; + return true; +} + +unsigned int AssetManager::LoadTexture(const std::string& key, const std::string& path) +{ + if (!textureManager) { + log_warn("AssetManager: texture manager not set"); + return 0; + } + if (textureAssets.find(key) != textureAssets.end()) { + return textureAssets[key].id; + } + + unsigned int id = textureManager->Load(path); + if (id != 0) { + RegisterTexture(key, id, path); + textureDefs[key] = TextureDefinition{path}; + } + return id; +} + +unsigned int AssetManager::LoadShader(const std::string& key, const std::string& vsPath, const std::string& fsPath) +{ + if (!shaderManager) { + log_warn("AssetManager: shader manager not set"); + return 0; + } + if (shaderAssets.find(key) != shaderAssets.end()) { + return shaderAssets[key].id; + } + + unsigned int id = shaderManager->Load(vsPath, fsPath); + if (id != 0) { + RegisterShader(key, id, vsPath + "|" + fsPath); + shaderDefs[key] = ShaderDefinition{vsPath, fsPath}; + } + return id; +} + +unsigned int AssetManager::LoadModel(const std::string& key, const std::string& path) +{ + if (!modelManager) { + log_warn("AssetManager: model manager not set"); + return 0; + } + if (modelAssets.find(key) != modelAssets.end()) { + return modelAssets[key].id; + } + + unsigned int id = modelManager->Load(path); + if (id != 0) { + RegisterModel(key, id, path); + ModelDefinition def; + def.type = ModelDefinition::Type::Path; + def.path = path; + modelDefs[key] = def; + } + return id; +} + +unsigned int AssetManager::LoadCube(const std::string& key, float width, float height, float length) +{ + if (!modelManager) { + log_warn("AssetManager: model manager not set"); + return 0; + } + if (modelAssets.find(key) != modelAssets.end()) { + return modelAssets[key].id; + } + + unsigned int id = modelManager->LoadCube(width, height, length); + if (id != 0) { + RegisterModel(key, id, "cube"); + ModelDefinition def; + def.type = ModelDefinition::Type::Primitive; + def.primitive = "cube"; + def.params = {width, height, length}; + modelDefs[key] = def; + } + return id; +} + +unsigned int AssetManager::LoadPoly(const std::string& key, int sides, float radius) +{ + if (!modelManager) { + log_warn("AssetManager: model manager not set"); + return 0; + } + if (modelAssets.find(key) != modelAssets.end()) { + return modelAssets[key].id; + } + + Mesh mesh = GenMeshPoly(sides, radius); + unsigned int id = modelManager->LoadFromMesh(mesh); + if (id != 0) { + RegisterModel(key, id, "poly"); + ModelDefinition def; + def.type = ModelDefinition::Type::Primitive; + def.primitive = "poly"; + def.params = {static_cast(sides), radius}; + modelDefs[key] = def; + } + return id; +} + +unsigned int AssetManager::LoadSphere(const std::string& key, float radius, int rings, int slices) +{ + if (!modelManager) { + log_warn("AssetManager: model manager not set"); + return 0; + } + if (modelAssets.find(key) != modelAssets.end()) { + return modelAssets[key].id; + } + + unsigned int id = modelManager->LoadSphere(radius, rings, slices); + if (id != 0) { + RegisterModel(key, id, "sphere"); + ModelDefinition def; + def.type = ModelDefinition::Type::Primitive; + def.primitive = "sphere"; + def.params = {radius, static_cast(rings), static_cast(slices)}; + modelDefs[key] = def; + } + return id; +} + +unsigned int AssetManager::LoadHemiSphere(const std::string& key, float radius, int rings, int slices) +{ + if (!modelManager) { + log_warn("AssetManager: model manager not set"); + return 0; + } + if (modelAssets.find(key) != modelAssets.end()) { + return modelAssets[key].id; + } + + Mesh mesh = GenMeshHemiSphere(radius, rings, slices); + unsigned int id = modelManager->LoadFromMesh(mesh); + if (id != 0) { + RegisterModel(key, id, "hemisphere"); + ModelDefinition def; + def.type = ModelDefinition::Type::Primitive; + def.primitive = "hemisphere"; + def.params = {radius, static_cast(rings), static_cast(slices)}; + modelDefs[key] = def; + } + return id; +} + +unsigned int AssetManager::LoadPlane(const std::string& key, float width, float length, int resX, int resZ) +{ + if (!modelManager) { + log_warn("AssetManager: model manager not set"); + return 0; + } + if (modelAssets.find(key) != modelAssets.end()) { + return modelAssets[key].id; + } + + unsigned int id = modelManager->LoadPlane(width, length, resX, resZ); + if (id != 0) { + RegisterModel(key, id, "plane"); + ModelDefinition def; + def.type = ModelDefinition::Type::Primitive; + def.primitive = "plane"; + def.params = {width, length, static_cast(resX), static_cast(resZ)}; + modelDefs[key] = def; + } + return id; +} + +unsigned int AssetManager::LoadCylinder(const std::string& key, float radius, float height, int slices) +{ + if (!modelManager) { + log_warn("AssetManager: model manager not set"); + return 0; + } + if (modelAssets.find(key) != modelAssets.end()) { + return modelAssets[key].id; + } + + Mesh mesh = GenMeshCylinder(radius, height, slices); + unsigned int id = modelManager->LoadFromMesh(mesh); + if (id != 0) { + RegisterModel(key, id, "cylinder"); + ModelDefinition def; + def.type = ModelDefinition::Type::Primitive; + def.primitive = "cylinder"; + def.params = {radius, height, static_cast(slices)}; + modelDefs[key] = def; + } + return id; +} + +unsigned int AssetManager::LoadCone(const std::string& key, float radius, float height, int slices) +{ + if (!modelManager) { + log_warn("AssetManager: model manager not set"); + return 0; + } + if (modelAssets.find(key) != modelAssets.end()) { + return modelAssets[key].id; + } + + Mesh mesh = GenMeshCone(radius, height, slices); + unsigned int id = modelManager->LoadFromMesh(mesh); + if (id != 0) { + RegisterModel(key, id, "cone"); + ModelDefinition def; + def.type = ModelDefinition::Type::Primitive; + def.primitive = "cone"; + def.params = {radius, height, static_cast(slices)}; + modelDefs[key] = def; + } + return id; +} + +unsigned int AssetManager::LoadTorus(const std::string& key, float radius, float size, int radSeg, int sides) +{ + if (!modelManager) { + log_warn("AssetManager: model manager not set"); + return 0; + } + if (modelAssets.find(key) != modelAssets.end()) { + return modelAssets[key].id; + } + + Mesh mesh = GenMeshTorus(radius, size, radSeg, sides); + unsigned int id = modelManager->LoadFromMesh(mesh); + if (id != 0) { + RegisterModel(key, id, "torus"); + ModelDefinition def; + def.type = ModelDefinition::Type::Primitive; + def.primitive = "torus"; + def.params = {radius, size, static_cast(radSeg), static_cast(sides)}; + modelDefs[key] = def; + } + return id; +} + +unsigned int AssetManager::LoadKnot(const std::string& key, float radius, float size, int radSeg, int sides) +{ + if (!modelManager) { + log_warn("AssetManager: model manager not set"); + return 0; + } + if (modelAssets.find(key) != modelAssets.end()) { + return modelAssets[key].id; + } + + Mesh mesh = GenMeshKnot(radius, size, radSeg, sides); + unsigned int id = modelManager->LoadFromMesh(mesh); + if (id != 0) { + RegisterModel(key, id, "knot"); + ModelDefinition def; + def.type = ModelDefinition::Type::Primitive; + def.primitive = "knot"; + def.params = {radius, size, static_cast(radSeg), static_cast(sides)}; + modelDefs[key] = def; + } + return id; +} + +unsigned int AssetManager::LoadHeightmap(const std::string& key, const std::string& heightmapPath, float sizeX, float sizeY, float sizeZ) +{ + if (!modelManager) { + log_warn("AssetManager: model manager not set"); + return 0; + } + if (modelAssets.find(key) != modelAssets.end()) { + return modelAssets[key].id; + } + + Image heightmap = LoadImage(heightmapPath.c_str()); + if (!heightmap.data) { + log_warn("AssetManager: failed to load heightmap %s", heightmapPath.c_str()); + return 0; + } + + Mesh mesh = GenMeshHeightmap(heightmap, Vector3{sizeX, sizeY, sizeZ}); + UnloadImage(heightmap); + + unsigned int id = modelManager->LoadFromMesh(mesh); + if (id != 0) { + RegisterModel(key, id, "heightmap:" + heightmapPath); + ModelDefinition def; + def.type = ModelDefinition::Type::Heightmap; + def.path = heightmapPath; + def.params = {sizeX, sizeY, sizeZ}; + modelDefs[key] = def; + } + return id; +} + +unsigned int AssetManager::LoadCubicmap(const std::string& key, const std::string& cubicmapPath, float sizeX, float sizeY, float sizeZ) +{ + if (!modelManager) { + log_warn("AssetManager: model manager not set"); + return 0; + } + if (modelAssets.find(key) != modelAssets.end()) { + return modelAssets[key].id; + } + + Image cubicmap = LoadImage(cubicmapPath.c_str()); + if (!cubicmap.data) { + log_warn("AssetManager: failed to load cubicmap %s", cubicmapPath.c_str()); + return 0; + } + + Mesh mesh = GenMeshCubicmap(cubicmap, Vector3{sizeX, sizeY, sizeZ}); + UnloadImage(cubicmap); + + unsigned int id = modelManager->LoadFromMesh(mesh); + if (id != 0) { + RegisterModel(key, id, "cubicmap:" + cubicmapPath); + ModelDefinition def; + def.type = ModelDefinition::Type::Cubicmap; + def.path = cubicmapPath; + def.params = {sizeX, sizeY, sizeZ}; + modelDefs[key] = def; + } + return id; +} + +unsigned int AssetManager::LoadFromMesh(const std::string& key, Mesh mesh, const std::string& source) +{ + if (!modelManager) { + log_warn("AssetManager: model manager not set"); + return 0; + } + if (modelAssets.find(key) != modelAssets.end()) { + return modelAssets[key].id; + } + + unsigned int id = modelManager->LoadFromMesh(mesh); + if (id != 0) { + RegisterModel(key, id, source); + ModelDefinition def; + def.type = ModelDefinition::Type::Mesh; + def.path = source; + modelDefs[key] = def; + } + return id; +} + +unsigned int AssetManager::CreateMaterial(const std::string& key, unsigned int shaderId, Color albedo) +{ + if (!materialManager) { + log_warn("AssetManager: material manager not set"); + return 0; + } + if (materialAssets.find(key) != materialAssets.end()) { + return materialAssets[key].id; + } + + unsigned int id = materialManager->Create(shaderId, albedo); + if (id != 0) { + RegisterMaterial(key, id, "shader_id=" + std::to_string(shaderId)); + MaterialDefinition def; + def.albedo = albedo; + if (shaderId != 0) { + const std::string& shaderKey = GetShaderKey(shaderId); + if (!shaderKey.empty()) { + def.shaderKey = shaderKey; + def.hasShaderKey = true; + } else { + def.shaderId = shaderId; + def.hasShaderId = true; + } + } + materialDefs[key] = def; + } + return id; +} + +bool AssetManager::ApplyMeshTangents(const std::string& key, int meshIndex) +{ + if (!modelManager) { + log_warn("AssetManager: model manager not set"); + return false; + } + + unsigned int id = GetModelId(key); + if (id == 0) { + return false; + } + + Model* model = modelManager->Get(id); + if (!model || model->meshCount <= 0) { + return false; + } + + if (meshIndex < 0 || meshIndex >= model->meshCount) { + return false; + } + + GenMeshTangents(&model->meshes[meshIndex]); + UploadMesh(&model->meshes[meshIndex], false); + return true; +} + +bool AssetManager::UnloadTexture(const std::string& key) +{ + if (!textureManager) { + log_warn("AssetManager: texture manager not set"); + return false; + } + auto it = textureAssets.find(key); + if (it == textureAssets.end()) { + return false; + } + textureManager->Unload(it->second.id); + textureIds.erase(it->second.id); + textureAssets.erase(it); + textureDefs.erase(key); + return true; +} + +bool AssetManager::UnloadShader(const std::string& key) +{ + if (!shaderManager) { + log_warn("AssetManager: shader manager not set"); + return false; + } + auto it = shaderAssets.find(key); + if (it == shaderAssets.end()) { + return false; + } + shaderManager->Unload(it->second.id); + shaderIds.erase(it->second.id); + shaderAssets.erase(it); + shaderDefs.erase(key); + return true; +} + +bool AssetManager::UnloadModel(const std::string& key) +{ + if (!modelManager) { + log_warn("AssetManager: model manager not set"); + return false; + } + auto it = modelAssets.find(key); + if (it == modelAssets.end()) { + return false; + } + modelManager->Unload(it->second.id); + modelIds.erase(it->second.id); + modelAssets.erase(it); + modelDefs.erase(key); + return true; +} + +bool AssetManager::UnloadMaterial(const std::string& key) +{ + if (!materialManager) { + log_warn("AssetManager: material manager not set"); + return false; + } + auto it = materialAssets.find(key); + if (it == materialAssets.end()) { + return false; + } + materialManager->Remove(it->second.id); + materialIds.erase(it->second.id); + materialAssets.erase(it); + materialDefs.erase(key); + return true; +} + +unsigned int AssetManager::GetTextureId(const std::string& key) const +{ + auto it = textureAssets.find(key); + return (it != textureAssets.end()) ? it->second.id : 0; +} + +unsigned int AssetManager::GetShaderId(const std::string& key) const +{ + auto it = shaderAssets.find(key); + return (it != shaderAssets.end()) ? it->second.id : 0; +} + +unsigned int AssetManager::GetModelId(const std::string& key) const +{ + auto it = modelAssets.find(key); + return (it != modelAssets.end()) ? it->second.id : 0; +} + +unsigned int AssetManager::GetMaterialId(const std::string& key) const +{ + auto it = materialAssets.find(key); + return (it != materialAssets.end()) ? it->second.id : 0; +} + +const std::string& AssetManager::GetTextureKey(unsigned int id) const +{ + return GetKeyForId(textureIds, id); +} + +const std::string& AssetManager::GetShaderKey(unsigned int id) const +{ + return GetKeyForId(shaderIds, id); +} + +const std::string& AssetManager::GetModelKey(unsigned int id) const +{ + return GetKeyForId(modelIds, id); +} + +const std::string& AssetManager::GetMaterialKey(unsigned int id) const +{ + return GetKeyForId(materialIds, id); +} + +std::vector AssetManager::ListTextureKeys() const +{ + return ListKeys(textureAssets); +} + +std::vector AssetManager::ListShaderKeys() const +{ + return ListKeys(shaderAssets); +} + +std::vector AssetManager::ListModelKeys() const +{ + return ListKeys(modelAssets); +} + +std::vector AssetManager::ListMaterialKeys() const +{ + return ListKeys(materialAssets); +} + +std::string AssetManager::GetTextureSource(const std::string& key) const +{ + auto it = textureAssets.find(key); + return (it != textureAssets.end()) ? it->second.source : std::string(); +} + +std::string AssetManager::GetShaderSource(const std::string& key) const +{ + auto it = shaderAssets.find(key); + return (it != shaderAssets.end()) ? it->second.source : std::string(); +} + +std::string AssetManager::GetModelSource(const std::string& key) const +{ + auto it = modelAssets.find(key); + return (it != modelAssets.end()) ? it->second.source : std::string(); +} + +std::string AssetManager::GetMaterialSource(const std::string& key) const +{ + auto it = materialAssets.find(key); + return (it != materialAssets.end()) ? it->second.source : std::string(); +} + +void AssetManager::Clear() +{ + textureAssets.clear(); + shaderAssets.clear(); + modelAssets.clear(); + materialAssets.clear(); + + textureDefs.clear(); + shaderDefs.clear(); + modelDefs.clear(); + materialDefs.clear(); + + textureIds.clear(); + shaderIds.clear(); + modelIds.clear(); + materialIds.clear(); +} + +const std::string& AssetManager::GetKeyForId(const std::unordered_map& map, unsigned int id) const +{ + static const std::string empty; + auto it = map.find(id); + return (it != map.end()) ? it->second : empty; +} + +std::vector AssetManager::ListKeys(const std::unordered_map& map) const +{ + std::vector keys; + keys.reserve(map.size()); + for (const auto& pair : map) { + keys.push_back(pair.first); + } + return keys; +} + +bool AssetManager::SaveRegistry(const std::string& path) const +{ + std::filesystem::path outPath(path); + if (outPath.has_parent_path()) { + std::error_code ec; + std::filesystem::create_directories(outPath.parent_path(), ec); + } + + std::ofstream file(path); + if (!file.is_open()) { + log_error("Asset registry save failed: %s", path.c_str()); + return false; + } + + file << "# Simian asset registry\n"; + file << "# Auto-generated - edits may be overwritten\n\n"; + file << std::setprecision(6); + + for (const auto& [key, def] : textureDefs) { + if (key.empty() || def.path.empty()) { + continue; + } + file << "[[texture]]\n"; + file << "key = \"" << EscapeStringAsset(key) << "\"\n"; + file << "path = \"" << EscapeStringAsset(def.path) << "\"\n\n"; + } + + for (const auto& [key, def] : shaderDefs) { + if (key.empty() || def.vsPath.empty() || def.fsPath.empty()) { + continue; + } + file << "[[shader]]\n"; + file << "key = \"" << EscapeStringAsset(key) << "\"\n"; + file << "vs = \"" << EscapeStringAsset(def.vsPath) << "\"\n"; + file << "fs = \"" << EscapeStringAsset(def.fsPath) << "\"\n\n"; + } + + for (const auto& [key, def] : modelDefs) { + if (key.empty()) { + continue; + } + if (def.type == ModelDefinition::Type::Mesh) { + continue; + } + + file << "[[model]]\n"; + file << "key = \"" << EscapeStringAsset(key) << "\"\n"; + switch (def.type) { + case ModelDefinition::Type::Path: + if (!def.path.empty()) { + file << "type = \"path\"\n"; + file << "path = \"" << EscapeStringAsset(def.path) << "\"\n\n"; + } + break; + case ModelDefinition::Type::Primitive: + if (!def.primitive.empty() && !def.params.empty()) { + file << "type = \"primitive\"\n"; + file << "primitive = \"" << EscapeStringAsset(def.primitive) << "\"\n"; + file << "params = "; + WriteFloatList(file, def.params); + file << "\n\n"; + } + break; + case ModelDefinition::Type::Heightmap: + if (!def.path.empty() && def.params.size() >= 3) { + file << "type = \"heightmap\"\n"; + file << "path = \"" << EscapeStringAsset(def.path) << "\"\n"; + file << "size = "; + WriteFloatList(file, def.params); + file << "\n\n"; + } + break; + case ModelDefinition::Type::Cubicmap: + if (!def.path.empty() && def.params.size() >= 3) { + file << "type = \"cubicmap\"\n"; + file << "path = \"" << EscapeStringAsset(def.path) << "\"\n"; + file << "size = "; + WriteFloatList(file, def.params); + file << "\n\n"; + } + break; + case ModelDefinition::Type::Mesh: + break; + } + } + + for (const auto& [key, def] : materialDefs) { + if (key.empty()) { + continue; + } + file << "[[material]]\n"; + file << "key = \"" << EscapeStringAsset(key) << "\"\n"; + if (def.hasShaderKey && !def.shaderKey.empty()) { + file << "shader_key = \"" << EscapeStringAsset(def.shaderKey) << "\"\n"; + } else if (def.hasShaderId && def.shaderId > 0) { + file << "shader_id = " << def.shaderId << "\n"; + } + std::vector albedo = { + static_cast(def.albedo.r), + static_cast(def.albedo.g), + static_cast(def.albedo.b), + static_cast(def.albedo.a) + }; + file << "albedo = "; + WriteFloatList(file, albedo); + file << "\n\n"; + } + + return true; +} + +bool AssetManager::LoadRegistry(const std::string& path) +{ + std::ifstream file(path); + if (!file.is_open()) { + log_warn("Asset registry not found: %s", path.c_str()); + return false; + } + + enum class Section { + None, + Texture, + Shader, + Model, + Material + }; + + Section section = Section::None; + std::string entryKey; + std::unordered_map fields; + + auto flushEntry = [&]() { + if (section == Section::None || entryKey.empty()) { + entryKey.clear(); + fields.clear(); + return; + } + + if (section == Section::Texture) { + auto it = fields.find("path"); + if (it != fields.end()) { + std::string pathValue; + if (ParseStringAsset(it->second, pathValue)) { + textureDefs[entryKey] = TextureDefinition{pathValue}; + if (GetTextureId(entryKey) == 0) { + LoadTexture(entryKey, pathValue); + } + } + } + } else if (section == Section::Shader) { + std::string vsPath; + std::string fsPath; + auto itVs = fields.find("vs"); + auto itFs = fields.find("fs"); + if (itVs != fields.end() && itFs != fields.end() && + ParseStringAsset(itVs->second, vsPath) && ParseStringAsset(itFs->second, fsPath)) { + shaderDefs[entryKey] = ShaderDefinition{vsPath, fsPath}; + if (GetShaderId(entryKey) == 0) { + LoadShader(entryKey, vsPath, fsPath); + } + } + } else if (section == Section::Model) { + std::string typeValue; + auto itType = fields.find("type"); + if (itType != fields.end() && ParseStringAsset(itType->second, typeValue)) { + if (typeValue == "path") { + std::string modelPath; + auto itPath = fields.find("path"); + if (itPath != fields.end() && ParseStringAsset(itPath->second, modelPath)) { + ModelDefinition def; + def.type = ModelDefinition::Type::Path; + def.path = modelPath; + modelDefs[entryKey] = def; + if (GetModelId(entryKey) == 0) { + LoadModel(entryKey, modelPath); + } + } + } else if (typeValue == "primitive") { + std::string primitive; + std::vector params; + auto itPrim = fields.find("primitive"); + auto itParams = fields.find("params"); + if (itPrim != fields.end() && itParams != fields.end() && + ParseStringAsset(itPrim->second, primitive) && ParseFloatList(itParams->second, params)) { + ModelDefinition def; + def.type = ModelDefinition::Type::Primitive; + def.primitive = primitive; + def.params = params; + modelDefs[entryKey] = def; + + if (GetModelId(entryKey) == 0) { + if (primitive == "cube" && params.size() >= 3) { + LoadCube(entryKey, params[0], params[1], params[2]); + } else if (primitive == "poly" && params.size() >= 2) { + LoadPoly(entryKey, static_cast(params[0]), params[1]); + } else if (primitive == "sphere" && params.size() >= 3) { + LoadSphere(entryKey, params[0], static_cast(params[1]), static_cast(params[2])); + } else if (primitive == "hemisphere" && params.size() >= 3) { + LoadHemiSphere(entryKey, params[0], static_cast(params[1]), static_cast(params[2])); + } else if (primitive == "plane" && params.size() >= 4) { + LoadPlane(entryKey, params[0], params[1], static_cast(params[2]), static_cast(params[3])); + } else if (primitive == "cylinder" && params.size() >= 3) { + LoadCylinder(entryKey, params[0], params[1], static_cast(params[2])); + } else if (primitive == "cone" && params.size() >= 3) { + LoadCone(entryKey, params[0], params[1], static_cast(params[2])); + } else if (primitive == "torus" && params.size() >= 4) { + LoadTorus(entryKey, params[0], params[1], static_cast(params[2]), static_cast(params[3])); + } else if (primitive == "knot" && params.size() >= 4) { + LoadKnot(entryKey, params[0], params[1], static_cast(params[2]), static_cast(params[3])); + } + } + } + } else if (typeValue == "heightmap" || typeValue == "cubicmap") { + std::string mapPath; + std::vector sizeValues; + auto itPath = fields.find("path"); + auto itSize = fields.find("size"); + if (itPath != fields.end() && itSize != fields.end() && + ParseStringAsset(itPath->second, mapPath) && ParseFloatList(itSize->second, sizeValues) && sizeValues.size() >= 3) { + ModelDefinition def; + def.type = (typeValue == "heightmap") ? ModelDefinition::Type::Heightmap : ModelDefinition::Type::Cubicmap; + def.path = mapPath; + def.params = sizeValues; + modelDefs[entryKey] = def; + if (GetModelId(entryKey) == 0) { + if (typeValue == "heightmap") { + LoadHeightmap(entryKey, mapPath, sizeValues[0], sizeValues[1], sizeValues[2]); + } else { + LoadCubicmap(entryKey, mapPath, sizeValues[0], sizeValues[1], sizeValues[2]); + } + } + } + } + } + } else if (section == Section::Material) { + MaterialDefinition def; + std::vector albedoVals; + + auto itShaderKey = fields.find("shader_key"); + if (itShaderKey != fields.end()) { + std::string shaderKey; + if (ParseStringAsset(itShaderKey->second, shaderKey)) { + def.shaderKey = shaderKey; + def.hasShaderKey = true; + } + } + + auto itShaderId = fields.find("shader_id"); + if (!def.hasShaderKey && itShaderId != fields.end()) { + try { + def.shaderId = static_cast(std::stoul(TrimAsset(itShaderId->second), nullptr, 0)); + def.hasShaderId = def.shaderId > 0; + } catch (...) { + } + } + + auto itAlbedo = fields.find("albedo"); + if (itAlbedo != fields.end() && ParseFloatList(itAlbedo->second, albedoVals) && albedoVals.size() >= 4) { + def.albedo = { + static_cast(std::clamp(albedoVals[0], 0.0f, 255.0f)), + static_cast(std::clamp(albedoVals[1], 0.0f, 255.0f)), + static_cast(std::clamp(albedoVals[2], 0.0f, 255.0f)), + static_cast(std::clamp(albedoVals[3], 0.0f, 255.0f)) + }; + } + + materialDefs[entryKey] = def; + + if (GetMaterialId(entryKey) == 0) { + unsigned int shaderId = 0; + if (def.hasShaderKey) { + shaderId = GetShaderId(def.shaderKey); + } else if (def.hasShaderId) { + shaderId = def.shaderId; + } + CreateMaterial(entryKey, shaderId, def.albedo); + materialDefs[entryKey] = def; + } + } + + entryKey.clear(); + fields.clear(); + }; + + std::string line; + while (std::getline(file, line)) { + line = StripCommentAsset(line); + line = TrimAsset(line); + if (line.empty()) { + continue; + } + + if (line == "[[texture]]") { + flushEntry(); + section = Section::Texture; + continue; + } + if (line == "[[shader]]") { + flushEntry(); + section = Section::Shader; + continue; + } + if (line == "[[model]]") { + flushEntry(); + section = Section::Model; + continue; + } + if (line == "[[material]]") { + flushEntry(); + section = Section::Material; + continue; + } + + size_t eq = line.find('='); + if (eq == std::string::npos) { + continue; + } + + std::string key = TrimAsset(line.substr(0, eq)); + std::string value = TrimAsset(line.substr(eq + 1)); + if (key == "key") { + ParseStringAsset(value, entryKey); + } else { + fields[key] = value; + } + } + + flushEntry(); + return true; +} diff --git a/src/SceneGraph.cpp b/src/SceneGraph.cpp index e334cd0..4feae8f 100644 --- a/src/SceneGraph.cpp +++ b/src/SceneGraph.cpp @@ -3,31 +3,37 @@ #include "raymath.h" #include "entt.hpp" -static WorldTransform ComputeWorldFromParent(const ECSTransform& local, const WorldTransform* parentWorld) { +static Matrix BuildLocalMatrix(const ECSTransform& local) { + Matrix scale = MatrixScale(local.scale.x, local.scale.y, local.scale.z); + Matrix rotation = MatrixRotateXYZ(local.rotation); + Matrix translation = MatrixTranslate(local.position.x, local.position.y, local.position.z); + return MatrixMultiply(MatrixMultiply(scale, rotation), translation); +} + +static Vector3 ExtractScale(const Matrix& matrix) { + Vector3 scale; + scale.x = sqrtf(matrix.m0 * matrix.m0 + matrix.m1 * matrix.m1 + matrix.m2 * matrix.m2); + scale.y = sqrtf(matrix.m4 * matrix.m4 + matrix.m5 * matrix.m5 + matrix.m6 * matrix.m6); + scale.z = sqrtf(matrix.m8 * matrix.m8 + matrix.m9 * matrix.m9 + matrix.m10 * matrix.m10); + return scale; +} + +static WorldTransform ComputeWorldFromParent(ECSTransform& local, const WorldTransform* parentWorld) { + local.localMatrix = BuildLocalMatrix(local); + + WorldTransform world; if (!parentWorld) { - WorldTransform world; + world.worldMatrix = local.localMatrix; world.position = local.position; - world.scale = local.scale; world.rotation = local.rotation; + world.scale = local.scale; return world; } - Vector3 scaledLocal = { - local.position.x * parentWorld->scale.x, - local.position.y * parentWorld->scale.y, - local.position.z * parentWorld->scale.z - }; - - Vector3 rotatedLocal = Vector3RotateByAxisAngle(scaledLocal, Vector3{0.0f, 1.0f, 0.0f}, parentWorld->rotation); - - WorldTransform world; - world.position = Vector3Add(parentWorld->position, rotatedLocal); - world.scale = { - parentWorld->scale.x * local.scale.x, - parentWorld->scale.y * local.scale.y, - parentWorld->scale.z * local.scale.z - }; - world.rotation = parentWorld->rotation + local.rotation; + world.worldMatrix = MatrixMultiply(parentWorld->worldMatrix, local.localMatrix); + world.position = {world.worldMatrix.m12, world.worldMatrix.m13, world.worldMatrix.m14}; + world.scale = ExtractScale(world.worldMatrix); + world.rotation = QuaternionToEuler(QuaternionFromMatrix(world.worldMatrix)); return world; } diff --git a/src/SceneLoader.cpp b/src/SceneLoader.cpp index 9787291..2d69842 100644 --- a/src/SceneLoader.cpp +++ b/src/SceneLoader.cpp @@ -4,6 +4,7 @@ #include "ShaderManager.h" #include "SceneGraph.h" #include "TextureManager.h" +#include "AssetManager.h" #include "log/log.h" #include "raylib.h" #include "entt.hpp" @@ -19,6 +20,7 @@ static entt::registry* g_sceneRegistry = nullptr; static ModelManager* g_sceneModelManager = nullptr; static ShaderManager* g_sceneShaderManager = nullptr; static TextureManager* g_sceneTextureManager = nullptr; +static AssetManager* g_sceneAssetManager = nullptr; static std::string g_sceneScriptPath; static bool g_sceneScriptDirty = false; @@ -29,6 +31,10 @@ void SetSceneContext(entt::registry* registry, ModelManager* modelManager, Shade g_sceneTextureManager = textureManager; } +void SetSceneAssetManager(AssetManager* assetManager) { + g_sceneAssetManager = assetManager; +} + void ClearScene() { if (g_sceneRegistry) { g_sceneRegistry->clear(); @@ -62,10 +68,11 @@ struct SceneEntityDef { bool hasTransform = false; Vector3 position{0.0f, 0.0f, 0.0f}; Vector3 scale{1.0f, 1.0f, 1.0f}; - float rotation = 0.0f; + Vector3 rotation{0.0f, 0.0f, 0.0f}; bool hasSprite = false; std::string model; + std::string modelAsset; unsigned int modelId = 0; bool hasModelId = false; Vector3 modelSize{1.0f, 1.0f, 1.0f}; @@ -76,9 +83,15 @@ struct SceneEntityDef { float outlineSize = 0.0f; std::string shaderVs; std::string shaderFs; + std::string shaderAsset; unsigned int shaderId = 0; bool hasShaderId = false; + bool hasMaterial = false; + std::string materialAsset; + unsigned int materialId = 0; + bool hasMaterialId = false; + bool hasScript = false; std::string scriptPath; bool scriptEnabled = true; @@ -87,6 +100,7 @@ struct SceneEntityDef { bool hasTexture = false; std::string texturePath; + std::string textureAsset; unsigned int textureId = 0; bool hasTextureId = false; bool hasUV = false; @@ -167,6 +181,23 @@ static bool ParseVec2(const std::string& value, Vector2& out) { return true; } +static bool ParseRotationVector(const std::string& value, Vector3& out, float scale) { + Vector3 vec{}; + if (ParseVec3(value, vec)) { + out = {vec.x * scale, vec.y * scale, vec.z * scale}; + return true; + } + + std::string trimmed = Trim(value); + try { + float rot = std::stof(trimmed); + out = {0.0f, rot * scale, 0.0f}; + return true; + } catch (...) { + return false; + } +} + static bool ParseHexColor(const std::string& value, unsigned int& out) { std::string trimmed = Trim(value); if (trimmed.rfind("0x", 0) == 0 || trimmed.rfind("0X", 0) == 0) { @@ -270,6 +301,31 @@ static std::string ColorToHexString(Color color) { } static unsigned int LoadModelFor(const SceneEntityDef& def, std::unordered_map& modelCache) { + if (g_sceneAssetManager && !def.modelAsset.empty()) { + unsigned int existing = g_sceneAssetManager->GetModelId(def.modelAsset); + if (existing != 0) { + return existing; + } + + if (!def.model.empty()) { + if (def.model == "cube") { + return g_sceneAssetManager->LoadCube(def.modelAsset, def.modelSize.x, def.modelSize.y, def.modelSize.z); + } + if (def.model == "sphere") { + return g_sceneAssetManager->LoadSphere(def.modelAsset, def.radius, def.rings, def.slices); + } + if (def.model == "plane") { + return g_sceneAssetManager->LoadPlane(def.modelAsset, def.modelSize.x, def.modelSize.z, def.rings, def.slices); + } + return g_sceneAssetManager->LoadModel(def.modelAsset, def.model); + } + + if (def.hasModelId) { + g_sceneAssetManager->RegisterModel(def.modelAsset, def.modelId, "id"); + return def.modelId; + } + } + if (!g_sceneModelManager || def.model.empty()) return 0; std::string key = def.model; @@ -303,6 +359,22 @@ static unsigned int LoadModelFor(const SceneEntityDef& def, std::unordered_map& shaderCache) { + if (g_sceneAssetManager && !def.shaderAsset.empty()) { + unsigned int existing = g_sceneAssetManager->GetShaderId(def.shaderAsset); + if (existing != 0) { + return existing; + } + + if (!def.shaderVs.empty() && !def.shaderFs.empty()) { + return g_sceneAssetManager->LoadShader(def.shaderAsset, def.shaderVs, def.shaderFs); + } + + if (def.hasShaderId) { + g_sceneAssetManager->RegisterShader(def.shaderAsset, def.shaderId, "id"); + return def.shaderId; + } + } + if (!g_sceneShaderManager || def.shaderVs.empty() || def.shaderFs.empty()) return 0; std::string key = def.shaderVs + "|" + def.shaderFs; @@ -319,6 +391,22 @@ static unsigned int LoadShaderFor(const SceneEntityDef& def, std::unordered_map< } static unsigned int LoadTextureFor(const SceneEntityDef& def, std::unordered_map& textureCache) { + if (g_sceneAssetManager && !def.textureAsset.empty()) { + unsigned int existing = g_sceneAssetManager->GetTextureId(def.textureAsset); + if (existing != 0) { + return existing; + } + + if (!def.texturePath.empty()) { + return g_sceneAssetManager->LoadTexture(def.textureAsset, def.texturePath); + } + + if (def.hasTextureId) { + g_sceneAssetManager->RegisterTexture(def.textureAsset, def.textureId, "id"); + return def.textureId; + } + } + if (!g_sceneTextureManager || def.texturePath.empty()) return 0; auto cached = textureCache.find(def.texturePath); @@ -407,14 +495,20 @@ entt::entity LoadSceneFromFile(const std::string& path, bool clearExisting) { } else if (key == "scale") { current->hasTransform = ParseVec3(value, current->scale); } else if (key == "rotation") { - current->rotation = std::stof(value); - current->hasTransform = true; + if (ParseRotationVector(value, current->rotation, 1.0f)) { + current->hasTransform = true; + } } else if (key == "rotation_deg") { - current->rotation = std::stof(value) * DEG2RAD; - current->hasTransform = true; + if (ParseRotationVector(value, current->rotation, DEG2RAD)) { + current->hasTransform = true; + } } else if (key == "model") { ParseString(value, current->model); current->hasSprite = true; + } else if (key == "model_asset") { + if (ParseString(value, current->modelAsset)) { + current->hasSprite = true; + } } else if (key == "model_id") { current->modelId = static_cast(std::stoul(value, nullptr, 0)); current->hasModelId = true; @@ -436,14 +530,30 @@ entt::entity LoadSceneFromFile(const std::string& path, bool clearExisting) { ParseString(value, current->shaderVs); } else if (key == "shader_fs") { ParseString(value, current->shaderFs); + } else if (key == "shader_asset") { + if (ParseString(value, current->shaderAsset)) { + current->hasSprite = true; + } } else if (key == "shader_id") { current->shaderId = static_cast(std::stoul(value, nullptr, 0)); current->hasShaderId = true; current->hasSprite = true; + } else if (key == "material_asset") { + if (ParseString(value, current->materialAsset)) { + current->hasMaterial = true; + } + } else if (key == "material_id") { + current->materialId = static_cast(std::stoul(value, nullptr, 0)); + current->hasMaterialId = true; + current->hasMaterial = true; } else if (key == "texture") { if (ParseString(value, current->texturePath)) { current->hasTexture = true; } + } else if (key == "texture_asset") { + if (ParseString(value, current->textureAsset)) { + current->hasTexture = true; + } } else if (key == "texture_id") { current->textureId = static_cast(std::stoul(value, nullptr, 0)); current->hasTextureId = true; @@ -549,6 +659,21 @@ entt::entity LoadSceneFromFile(const std::string& path, bool clearExisting) { g_sceneRegistry->emplace(entity, static_cast(modelId), col, def.outlineSize, shaderId); } + if (def.hasMaterial) { + unsigned int materialId = 0; + if (g_sceneAssetManager && !def.materialAsset.empty()) { + materialId = g_sceneAssetManager->GetMaterialId(def.materialAsset); + if (materialId == 0 && def.hasMaterialId) { + g_sceneAssetManager->RegisterMaterial(def.materialAsset, def.materialId, "id"); + materialId = def.materialId; + } + } + if (materialId == 0 && def.hasMaterialId) { + materialId = def.materialId; + } + g_sceneRegistry->emplace(entity, materialId); + } + if (def.hasTexture) { unsigned int textureId = 0; if (!def.texturePath.empty()) { @@ -672,11 +797,22 @@ bool SaveSceneToFile(const std::string& path) { if (auto* transform = registry.try_get(entity)) { file << "position = " << Vec3ToString(transform->position) << "\n"; file << "scale = " << Vec3ToString(transform->scale) << "\n"; - file << "rotation_deg = " << FloatToString(transform->rotation * RAD2DEG) << "\n"; + Vector3 rotDeg = { + transform->rotation.x * RAD2DEG, + transform->rotation.y * RAD2DEG, + transform->rotation.z * RAD2DEG + }; + file << "rotation_deg = " << Vec3ToString(rotDeg) << "\n"; } if (auto* sprite = registry.try_get(entity)) { bool wroteModel = false; + if (g_sceneAssetManager && sprite->modelId > 0) { + const std::string& modelKey = g_sceneAssetManager->GetModelKey(static_cast(sprite->modelId)); + if (!modelKey.empty()) { + file << "model_asset = \"" << EscapeString(modelKey) << "\"\n"; + } + } if (g_sceneModelManager && sprite->modelId > 0) { const ModelSource* source = g_sceneModelManager->GetSource(static_cast(sprite->modelId)); if (source) { @@ -719,6 +855,12 @@ bool SaveSceneToFile(const std::string& path) { file << "color = " << ColorToHexString(sprite->color) << "\n"; file << "outline_size = " << FloatToString(sprite->outlineSize) << "\n"; bool wroteShader = false; + if (g_sceneAssetManager && sprite->shaderId > 0) { + const std::string& shaderKey = g_sceneAssetManager->GetShaderKey(sprite->shaderId); + if (!shaderKey.empty()) { + file << "shader_asset = \"" << EscapeString(shaderKey) << "\"\n"; + } + } if (g_sceneShaderManager && sprite->shaderId > 0) { const ShaderSource* source = g_sceneShaderManager->GetSource(sprite->shaderId); if (source && !source->vsPath.empty() && !source->fsPath.empty()) { @@ -734,6 +876,12 @@ bool SaveSceneToFile(const std::string& path) { if (auto* texture = registry.try_get(entity)) { bool wroteTexture = false; + if (g_sceneAssetManager && texture->textureId > 0) { + const std::string& textureKey = g_sceneAssetManager->GetTextureKey(texture->textureId); + if (!textureKey.empty()) { + file << "texture_asset = \"" << EscapeString(textureKey) << "\"\n"; + } + } if (g_sceneTextureManager && texture->textureId > 0) { const TextureSource* source = g_sceneTextureManager->GetSource(texture->textureId); if (source && !source->path.empty()) { @@ -746,6 +894,20 @@ bool SaveSceneToFile(const std::string& path) { } } + if (auto* material = registry.try_get(entity)) { + bool wroteMaterial = false; + if (g_sceneAssetManager && material->materialId > 0) { + const std::string& materialKey = g_sceneAssetManager->GetMaterialKey(material->materialId); + if (!materialKey.empty()) { + file << "material_asset = \"" << EscapeString(materialKey) << "\"\n"; + wroteMaterial = true; + } + } + if (!wroteMaterial && material->materialId > 0) { + file << "material_id = " << material->materialId << "\n"; + } + } + if (auto* uv = registry.try_get(entity)) { file << "uv_scale = " << Vec2ToString(uv->scale) << "\n"; file << "uv_offset = " << Vec2ToString(uv->offset) << "\n"; diff --git a/src/gui/GuiManager.cpp b/src/gui/GuiManager.cpp index 62b789d..b2a6cad 100644 --- a/src/gui/GuiManager.cpp +++ b/src/gui/GuiManager.cpp @@ -17,6 +17,8 @@ #include "SceneGraph.h" #include "SceneLoader.h" #include // Add this for cross-platform file handling +#define IMVIEWGUIZMO_IMPLEMENTATION +#include "ImViewGuizmoRaymath.h" GuiManager::GuiManager() {} @@ -45,12 +47,14 @@ void GuiManager::Initialize(Application *application) void GuiManager::Render(RenderTexture2D &renderTexture) { rlImGuiBegin(); + ImViewGuizmo::BeginFrame(); SetupDockspace(renderTexture); RenderErrorBanner(); RenderNotifications(); logWindow.Render(showLogWindow); // Render the LogWindow RenderSceneWindow(); + RenderAssetWindow(); RenderInspectorWindow(); @@ -137,6 +141,11 @@ void GuiManager::SetupDockspace(RenderTexture2D &renderTexture) { ImGui::MenuItem("Log Viewer", "Ctrl + L", &showLogWindow); ImGui::MenuItem("Scene", nullptr, &showSceneWindow); + ImGui::MenuItem("Assets", nullptr, &showAssetWindow); + bool useEditorCamera = app->IsUsingEditorCamera(); + if (ImGui::MenuItem("Use Editor Camera", nullptr, &useEditorCamera)) { + app->SetUseEditorCamera(useEditorCamera); + } ImGui::MenuItem("Inspector", nullptr, &showInspectorWindow); ImGui::EndMenu(); } @@ -259,6 +268,7 @@ void GuiManager::SetupDockspace(RenderTexture2D &renderTexture) ImGui::EndPopup(); } ImGuiID dockspace_id = ImGui::GetID("MyDockSpace"); + mainDockspaceId = dockspace_id; ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags); // Add a Game Window @@ -266,6 +276,7 @@ void GuiManager::SetupDockspace(RenderTexture2D &renderTexture) // Render Raylib content to the Game Window ImVec2 avail = ImGui::GetContentRegionAvail(); + ImVec2 windowPos = ImGui::GetCursorScreenPos(); const int drawWidth = std::max(1, static_cast(avail.x)); const int drawHeight = std::max(1, static_cast(avail.y)); desiredRenderSize = ImVec2(static_cast(drawWidth), static_cast(drawHeight)); @@ -277,6 +288,100 @@ void GuiManager::SetupDockspace(RenderTexture2D &renderTexture) ImGui::TextDisabled("No render target available"); } + ImGui::SetCursorScreenPos({windowPos.x + 12.0f, windowPos.y + 12.0f}); + bool useEditorCamera = app->IsUsingEditorCamera(); + const char* cameraLabel = useEditorCamera ? "Use Game Camera" : "Use Editor Camera"; + if (ImGui::Button(cameraLabel)) { + app->SetUseEditorCamera(!useEditorCamera); + } + + if (app->IsUsingEditorCamera()) { + Camera3D& editorCamera = app->GetEditorCamera(); + Vector3 camPos = editorCamera.position; + Vector3 pivot = editorCameraPivot; + if (selectedEntity != entt::null) { + auto& registry = app->GetRegistry(); + Vector3 entityPos = {0.0f, 0.0f, 0.0f}; + if (auto* worldTransform = registry.try_get(selectedEntity)) { + entityPos = worldTransform->position; + } else if (auto* localTransform = registry.try_get(selectedEntity)) { + entityPos = localTransform->position; + } + + if (editorPivotEntity != selectedEntity) { + editorPivotEntity = selectedEntity; + editorPivotOffset = {0.0f, 0.0f, 0.0f}; + } + + pivot = Vector3Add(entityPos, editorPivotOffset); + editorCameraPivot = pivot; + editorPivotInitialized = true; + } else { + editorPivotEntity = entt::null; + if (!editorPivotInitialized) { + editorCameraPivot = editorCamera.target; + editorPivotInitialized = true; + } + pivot = editorCameraPivot; + } + + Vector3 direction = Vector3Subtract(editorCamera.target, editorCamera.position); + if (Vector3Length(direction) <= 0.0001f) { + direction = {0.0f, 0.0f, 1.0f}; + } + direction = Vector3Normalize(direction); + + Quaternion camRot = ImViewGuizmo::GizmoMath::quatLookAt(direction, editorCamera.up); + + const float baseGizmoSize = 256.0f; + const float marginX = 6.0f; + const float marginY = 75.0f; + ImViewGuizmo::Style& gizmoStyle = ImViewGuizmo::GetStyle(); + + const float maxScaleX = (avail.x - (marginX * 2.0f)) / baseGizmoSize; + const float maxScaleY = (avail.y - (marginY * 2.0f) - 12.0f) / + (baseGizmoSize + (gizmoStyle.toolButtonRadius * 2.0f)); + float gizmoScale = std::min(1.0f, std::min(maxScaleX, maxScaleY)); + if (gizmoScale < 0.0f) { + gizmoScale = 0.0f; + } + gizmoStyle.scale = gizmoScale; + + const float gizmoSize = baseGizmoSize * gizmoScale; + if (gizmoSize <= 0.0f) { + ImGui::End(); + ImGui::End(); + return; + } + + ImVec2 gizmoPos = {windowPos.x + avail.x - gizmoSize - marginX, windowPos.y + marginY}; + ImVec2 dollyPos = {gizmoPos.x, gizmoPos.y + gizmoSize + 12.0f}; + ImVec2 panPos = {gizmoPos.x + 60.0f, gizmoPos.y + gizmoSize + 12.0f}; + + bool cameraChanged = false; + cameraChanged |= ImViewGuizmo::Rotate(camPos, camRot, pivot, gizmoPos); + cameraChanged |= ImViewGuizmo::Dolly(camPos, camRot, dollyPos); + Vector3 panStartPos = camPos; + bool panChanged = ImViewGuizmo::Pan(camPos, camRot, panPos); + cameraChanged |= panChanged; + if (panChanged) { + Vector3 delta = Vector3Subtract(camPos, panStartPos); + pivot = Vector3Add(pivot, delta); + if (selectedEntity != entt::null) { + editorPivotOffset = Vector3Add(editorPivotOffset, delta); + } else { + editorCameraPivot = pivot; + } + } + + if (cameraChanged) { + editorCamera.position = camPos; + Vector3 up = Vector3RotateByQuaternion({0.0f, 1.0f, 0.0f}, camRot); + editorCamera.target = pivot; + editorCamera.up = up; + } + } + ImGui::End(); ImGui::End(); } @@ -494,6 +599,394 @@ void GuiManager::RenderSceneWindow() ImGui::End(); } +void GuiManager::RenderAssetWindow() +{ + if (!showAssetWindow) return; + if (mainDockspaceId != 0) { + ImGui::SetNextWindowDockID(mainDockspaceId, ImGuiCond_FirstUseEver); + } + ImGui::Begin("Assets", &showAssetWindow); + + if (!app) { + ImGui::Text("No application context."); + ImGui::End(); + return; + } + + auto& assets = app->GetAssetManager(); + + auto openUnloadPopup = [&](AssetUnloadType type, const std::string& key) { + pendingAssetUnloadType = type; + pendingAssetUnloadKey = key; + ImGui::OpenPopup("Unload Asset"); + }; + + auto assetTypeLabel = [](AssetUnloadType type) { + switch (type) { + case AssetUnloadType::Texture: return "texture"; + case AssetUnloadType::Shader: return "shader"; + case AssetUnloadType::Model: return "model"; + case AssetUnloadType::Material: return "material"; + default: return "asset"; + } + }; + + if (ImGui::BeginTabBar("AssetsTabs")) { + if (ImGui::BeginTabItem("Textures")) { + ImGui::InputText("Key", textureKeyBuffer, sizeof(textureKeyBuffer)); + ImGui::InputText("Path", texturePathBuffer, sizeof(texturePathBuffer)); + + bool canLoad = textureKeyBuffer[0] != '\0' && texturePathBuffer[0] != '\0'; + if (!canLoad) ImGui::BeginDisabled(); + if (ImGui::Button("Load Texture")) { + assets.LoadTexture(textureKeyBuffer, texturePathBuffer); + } + if (!canLoad) ImGui::EndDisabled(); + + auto keys = assets.ListTextureKeys(); + std::sort(keys.begin(), keys.end()); + + if (ImGui::BeginTable("TextureList", 3, ImGuiTableFlags_RowBg | ImGuiTableFlags_Borders)) { + ImGui::TableSetupColumn("Key"); + ImGui::TableSetupColumn("Source"); + ImGui::TableSetupColumn("Actions", ImGuiTableColumnFlags_WidthFixed, 90.0f); + ImGui::TableHeadersRow(); + for (const auto& key : keys) { + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted(key.c_str()); + ImGui::TableSetColumnIndex(1); + std::string source = assets.GetTextureSource(key); + ImGui::TextUnformatted(source.c_str()); + ImGui::TableSetColumnIndex(2); + ImGui::PushID(key.c_str()); + if (ImGui::SmallButton("Unload")) { + openUnloadPopup(AssetUnloadType::Texture, key); + } + ImGui::PopID(); + } + ImGui::EndTable(); + } + + if (keys.empty()) { + ImGui::TextDisabled("No textures loaded."); + } + + ImGui::EndTabItem(); + } + + if (ImGui::BeginTabItem("Shaders")) { + ImGui::InputText("Key", shaderKeyBuffer, sizeof(shaderKeyBuffer)); + ImGui::InputText("Vertex Path", shaderVsPathBuffer, sizeof(shaderVsPathBuffer)); + ImGui::InputText("Fragment Path", shaderFsPathBuffer, sizeof(shaderFsPathBuffer)); + + bool canLoad = shaderKeyBuffer[0] != '\0' && shaderVsPathBuffer[0] != '\0' && shaderFsPathBuffer[0] != '\0'; + if (!canLoad) ImGui::BeginDisabled(); + if (ImGui::Button("Load Shader")) { + assets.LoadShader(shaderKeyBuffer, shaderVsPathBuffer, shaderFsPathBuffer); + } + if (!canLoad) ImGui::EndDisabled(); + + auto keys = assets.ListShaderKeys(); + std::sort(keys.begin(), keys.end()); + + if (ImGui::BeginTable("ShaderList", 3, ImGuiTableFlags_RowBg | ImGuiTableFlags_Borders)) { + ImGui::TableSetupColumn("Key"); + ImGui::TableSetupColumn("Source"); + ImGui::TableSetupColumn("Actions", ImGuiTableColumnFlags_WidthFixed, 90.0f); + ImGui::TableHeadersRow(); + for (const auto& key : keys) { + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted(key.c_str()); + ImGui::TableSetColumnIndex(1); + std::string source = assets.GetShaderSource(key); + ImGui::TextUnformatted(source.c_str()); + ImGui::TableSetColumnIndex(2); + ImGui::PushID(key.c_str()); + if (ImGui::SmallButton("Unload")) { + openUnloadPopup(AssetUnloadType::Shader, key); + } + ImGui::PopID(); + } + ImGui::EndTable(); + } + + if (keys.empty()) { + ImGui::TextDisabled("No shaders loaded."); + } + + ImGui::EndTabItem(); + } + + if (ImGui::BeginTabItem("Models")) { + ImGui::InputText("Key", modelKeyBuffer, sizeof(modelKeyBuffer)); + ImGui::InputText("Path", modelPathBuffer, sizeof(modelPathBuffer)); + + bool canLoad = modelKeyBuffer[0] != '\0' && modelPathBuffer[0] != '\0'; + if (!canLoad) ImGui::BeginDisabled(); + if (ImGui::Button("Load Model")) { + assets.LoadModel(modelKeyBuffer, modelPathBuffer); + } + if (!canLoad) ImGui::EndDisabled(); + + ImGui::Separator(); + ImGui::Text("Primitive"); + + const char* primitiveLabels[] = { + "Cube", "Sphere", "HemiSphere", "Plane", "Cylinder", "Cone", "Torus", "Knot", "Poly", "Heightmap", "Cubicmap" + }; + ImGui::Combo("Type", &modelPrimitiveIndex, primitiveLabels, IM_ARRAYSIZE(primitiveLabels)); + + switch (modelPrimitiveIndex) { + case 0: + ImGui::DragFloat("Width", &modelWidth, 0.05f, 0.01f, 100.0f); + ImGui::DragFloat("Height", &modelHeight, 0.05f, 0.01f, 100.0f); + ImGui::DragFloat("Length", &modelLength, 0.05f, 0.01f, 100.0f); + break; + case 1: + case 2: + ImGui::DragFloat("Radius", &modelRadius, 0.05f, 0.01f, 100.0f); + ImGui::InputInt("Rings", &modelRings); + ImGui::InputInt("Slices", &modelSlices); + break; + case 3: + ImGui::DragFloat("Width", &modelWidth, 0.05f, 0.01f, 100.0f); + ImGui::DragFloat("Length", &modelLength, 0.05f, 0.01f, 100.0f); + ImGui::InputInt("Res X", &modelResX); + ImGui::InputInt("Res Z", &modelResZ); + break; + case 4: + case 5: + ImGui::DragFloat("Radius", &modelRadius, 0.05f, 0.01f, 100.0f); + ImGui::DragFloat("Height", &modelHeight, 0.05f, 0.01f, 100.0f); + ImGui::InputInt("Slices", &modelSlices); + break; + case 6: + case 7: + ImGui::DragFloat("Radius", &modelRadius, 0.05f, 0.01f, 100.0f); + ImGui::DragFloat("Size", &modelLength, 0.05f, 0.01f, 100.0f); + ImGui::InputInt("Rad Seg", &modelRadSeg); + ImGui::InputInt("Sides", &modelSides); + break; + case 8: + ImGui::InputInt("Sides", &modelPolySides); + ImGui::DragFloat("Radius", &modelRadius, 0.05f, 0.01f, 100.0f); + break; + case 9: + ImGui::InputText("Heightmap Path", modelHeightmapPathBuffer, sizeof(modelHeightmapPathBuffer)); + ImGui::DragFloat("Size X", &modelSizeX, 0.05f, 0.01f, 1000.0f); + ImGui::DragFloat("Size Y", &modelSizeY, 0.05f, 0.01f, 1000.0f); + ImGui::DragFloat("Size Z", &modelSizeZ, 0.05f, 0.01f, 1000.0f); + break; + case 10: + ImGui::InputText("Cubicmap Path", modelCubicmapPathBuffer, sizeof(modelCubicmapPathBuffer)); + ImGui::DragFloat("Size X", &modelSizeX, 0.05f, 0.01f, 1000.0f); + ImGui::DragFloat("Size Y", &modelSizeY, 0.05f, 0.01f, 1000.0f); + ImGui::DragFloat("Size Z", &modelSizeZ, 0.05f, 0.01f, 1000.0f); + break; + default: + break; + } + + if (ImGui::Button("Create Primitive")) { + std::string key = modelKeyBuffer; + if (key.empty()) { + std::snprintf(modelKeyBuffer, sizeof(modelKeyBuffer), "%s_%d", + primitiveLabels[modelPrimitiveIndex], ++modelAutoKeyCounter); + key = modelKeyBuffer; + } + + switch (modelPrimitiveIndex) { + case 0: + assets.LoadCube(key, modelWidth, modelHeight, modelLength); + break; + case 1: + assets.LoadSphere(key, modelRadius, modelRings, modelSlices); + break; + case 2: + assets.LoadHemiSphere(key, modelRadius, modelRings, modelSlices); + break; + case 3: + assets.LoadPlane(key, modelWidth, modelLength, modelResX, modelResZ); + break; + case 4: + assets.LoadCylinder(key, modelRadius, modelHeight, modelSlices); + break; + case 5: + assets.LoadCone(key, modelRadius, modelHeight, modelSlices); + break; + case 6: + assets.LoadTorus(key, modelRadius, modelLength, modelRadSeg, modelSides); + break; + case 7: + assets.LoadKnot(key, modelRadius, modelLength, modelRadSeg, modelSides); + break; + case 8: + assets.LoadPoly(key, modelPolySides, modelRadius); + break; + case 9: + if (modelHeightmapPathBuffer[0] != '\0') { + assets.LoadHeightmap(key, modelHeightmapPathBuffer, modelSizeX, modelSizeY, modelSizeZ); + } + break; + case 10: + if (modelCubicmapPathBuffer[0] != '\0') { + assets.LoadCubicmap(key, modelCubicmapPathBuffer, modelSizeX, modelSizeY, modelSizeZ); + } + break; + default: + break; + } + } + ImGui::TextDisabled("Leave key empty to auto-generate."); + + auto keys = assets.ListModelKeys(); + std::sort(keys.begin(), keys.end()); + + if (ImGui::BeginTable("ModelList", 3, ImGuiTableFlags_RowBg | ImGuiTableFlags_Borders)) { + ImGui::TableSetupColumn("Key"); + ImGui::TableSetupColumn("Source"); + ImGui::TableSetupColumn("Actions", ImGuiTableColumnFlags_WidthFixed, 90.0f); + ImGui::TableHeadersRow(); + for (const auto& key : keys) { + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted(key.c_str()); + ImGui::TableSetColumnIndex(1); + std::string source = assets.GetModelSource(key); + ImGui::TextUnformatted(source.c_str()); + ImGui::TableSetColumnIndex(2); + ImGui::PushID(key.c_str()); + if (ImGui::SmallButton("Unload")) { + openUnloadPopup(AssetUnloadType::Model, key); + } + ImGui::PopID(); + } + ImGui::EndTable(); + } + + if (keys.empty()) { + ImGui::TextDisabled("No models loaded."); + } + + ImGui::EndTabItem(); + } + + if (ImGui::BeginTabItem("Materials")) { + ImGui::InputText("Key", materialKeyBuffer, sizeof(materialKeyBuffer)); + + auto shaderKeys = assets.ListShaderKeys(); + std::sort(shaderKeys.begin(), shaderKeys.end()); + if (shaderKeys.empty()) { + ImGui::InputInt("Shader Id", &materialShaderId); + } else { + if (materialShaderIndex < 0 || materialShaderIndex >= static_cast(shaderKeys.size())) { + materialShaderIndex = 0; + } + std::vector keyLabels; + keyLabels.reserve(shaderKeys.size()); + for (const auto& key : shaderKeys) { + keyLabels.push_back(key.c_str()); + } + ImGui::Combo("Shader Asset", &materialShaderIndex, keyLabels.data(), static_cast(keyLabels.size())); + } + + ImGui::ColorEdit4("Albedo", materialAlbedo); + + bool canCreate = materialKeyBuffer[0] != '\0'; + if (!canCreate) ImGui::BeginDisabled(); + if (ImGui::Button("Create Material")) { + unsigned int shaderId = 0; + if (shaderKeys.empty()) { + shaderId = materialShaderId < 0 ? 0u : static_cast(materialShaderId); + } else { + shaderId = assets.GetShaderId(shaderKeys[materialShaderIndex]); + } + Color albedo = { + static_cast(materialAlbedo[0] * 255.0f), + static_cast(materialAlbedo[1] * 255.0f), + static_cast(materialAlbedo[2] * 255.0f), + static_cast(materialAlbedo[3] * 255.0f) + }; + assets.CreateMaterial(materialKeyBuffer, shaderId, albedo); + } + if (!canCreate) ImGui::EndDisabled(); + + auto keys = assets.ListMaterialKeys(); + std::sort(keys.begin(), keys.end()); + + if (ImGui::BeginTable("MaterialList", 3, ImGuiTableFlags_RowBg | ImGuiTableFlags_Borders)) { + ImGui::TableSetupColumn("Key"); + ImGui::TableSetupColumn("Source"); + ImGui::TableSetupColumn("Actions", ImGuiTableColumnFlags_WidthFixed, 90.0f); + ImGui::TableHeadersRow(); + for (const auto& key : keys) { + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::TextUnformatted(key.c_str()); + ImGui::TableSetColumnIndex(1); + std::string source = assets.GetMaterialSource(key); + ImGui::TextUnformatted(source.c_str()); + ImGui::TableSetColumnIndex(2); + ImGui::PushID(key.c_str()); + if (ImGui::SmallButton("Unload")) { + openUnloadPopup(AssetUnloadType::Material, key); + } + ImGui::PopID(); + } + ImGui::EndTable(); + } + + if (keys.empty()) { + ImGui::TextDisabled("No materials loaded."); + } + + ImGui::EndTabItem(); + } + + ImGui::EndTabBar(); + } + + if (ImGui::BeginPopupModal("Unload Asset", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) { + const char* typeLabel = assetTypeLabel(pendingAssetUnloadType); + ImGui::Text("Unload %s '%s'?", typeLabel, pendingAssetUnloadKey.c_str()); + ImGui::Spacing(); + + if (ImGui::Button("Unload")) { + switch (pendingAssetUnloadType) { + case AssetUnloadType::Texture: + assets.UnloadTexture(pendingAssetUnloadKey); + break; + case AssetUnloadType::Shader: + assets.UnloadShader(pendingAssetUnloadKey); + break; + case AssetUnloadType::Model: + assets.UnloadModel(pendingAssetUnloadKey); + break; + case AssetUnloadType::Material: + assets.UnloadMaterial(pendingAssetUnloadKey); + break; + default: + break; + } + pendingAssetUnloadType = AssetUnloadType::None; + pendingAssetUnloadKey.clear(); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::Button("Cancel")) { + pendingAssetUnloadType = AssetUnloadType::None; + pendingAssetUnloadKey.clear(); + ImGui::CloseCurrentPopup(); + } + + ImGui::EndPopup(); + } + + ImGui::End(); +} + void GuiManager::RenderInspectorWindow() { if (!showInspectorWindow) return; @@ -506,6 +999,7 @@ void GuiManager::RenderInspectorWindow() } auto& registry = app->GetRegistry(); + auto& assets = app->GetAssetManager(); if (!registry.valid(selectedEntity)) { ImGui::Text("No entity selected."); ImGui::End(); @@ -652,7 +1146,11 @@ void GuiManager::RenderInspectorWindow() auto& transform = registry.get(selectedEntity); float position[3] = {transform.position.x, transform.position.y, transform.position.z}; float scale[3] = {transform.scale.x, transform.scale.y, transform.scale.z}; - float rotationDeg = transform.rotation * RAD2DEG; + float rotationDeg[3] = { + transform.rotation.x * RAD2DEG, + transform.rotation.y * RAD2DEG, + transform.rotation.z * RAD2DEG + }; if (ImGui::DragFloat3("Position", position, 0.1f)) { transform.position = {position[0], position[1], position[2]}; @@ -660,8 +1158,12 @@ void GuiManager::RenderInspectorWindow() if (ImGui::DragFloat3("Scale", scale, 0.05f)) { transform.scale = {scale[0], scale[1], scale[2]}; } - if (ImGui::DragFloat("Rotation (deg)", &rotationDeg, 0.5f)) { - transform.rotation = rotationDeg * DEG2RAD; + if (ImGui::DragFloat3("Rotation (deg)", rotationDeg, 0.5f)) { + transform.rotation = { + rotationDeg[0] * DEG2RAD, + rotationDeg[1] * DEG2RAD, + rotationDeg[2] * DEG2RAD + }; } ImGui::PopID(); } @@ -709,11 +1211,15 @@ void GuiManager::RenderInspectorWindow() float worldPos[3] = {world->position.x, world->position.y, world->position.z}; float worldScale[3] = {world->scale.x, world->scale.y, world->scale.z}; - float worldRotDeg = world->rotation * RAD2DEG; + float worldRotDeg[3] = { + world->rotation.x * RAD2DEG, + world->rotation.y * RAD2DEG, + world->rotation.z * RAD2DEG + }; ImGui::DragFloat3("World Position", worldPos, 0.1f); ImGui::DragFloat3("World Scale", worldScale, 0.05f); - ImGui::DragFloat("World Rotation (deg)", &worldRotDeg, 0.5f); + ImGui::DragFloat3("World Rotation (deg)", worldRotDeg, 0.5f); ImGui::EndDisabled(); } @@ -724,11 +1230,73 @@ void GuiManager::RenderInspectorWindow() ImGui::Separator(); ImGui::Text("Sprite"); + auto modelKeys = assets.ListModelKeys(); + std::sort(modelKeys.begin(), modelKeys.end()); + std::vector modelLabels; + modelLabels.reserve(modelKeys.size() + 1); + modelLabels.push_back(""); + for (const auto& key : modelKeys) { + modelLabels.push_back(key); + } + std::vector modelLabelPtrs; + modelLabelPtrs.reserve(modelLabels.size()); + for (const auto& label : modelLabels) { + modelLabelPtrs.push_back(label.c_str()); + } + + int modelIndex = 0; + std::string currentModelKey = assets.GetModelKey(static_cast(sprite.modelId)); + if (!currentModelKey.empty()) { + auto it = std::find(modelKeys.begin(), modelKeys.end(), currentModelKey); + if (it != modelKeys.end()) { + modelIndex = static_cast(std::distance(modelKeys.begin(), it)) + 1; + } + } + int selectedModelIndex = modelIndex; + if (ImGui::Combo("Model Asset", &selectedModelIndex, modelLabelPtrs.data(), static_cast(modelLabelPtrs.size()))) { + if (selectedModelIndex == 0) { + sprite.modelId = 0; + } else { + sprite.modelId = assets.GetModelId(modelKeys[selectedModelIndex - 1]); + } + } + int modelId = static_cast(sprite.modelId); if (ImGui::InputInt("Model Id", &modelId)) { sprite.modelId = modelId < 0 ? 0 : static_cast(modelId); } + auto shaderKeys = assets.ListShaderKeys(); + std::sort(shaderKeys.begin(), shaderKeys.end()); + std::vector shaderLabels; + shaderLabels.reserve(shaderKeys.size() + 1); + shaderLabels.push_back(""); + for (const auto& key : shaderKeys) { + shaderLabels.push_back(key); + } + std::vector shaderLabelPtrs; + shaderLabelPtrs.reserve(shaderLabels.size()); + for (const auto& label : shaderLabels) { + shaderLabelPtrs.push_back(label.c_str()); + } + + int shaderIndex = 0; + std::string currentShaderKey = assets.GetShaderKey(sprite.shaderId); + if (!currentShaderKey.empty()) { + auto it = std::find(shaderKeys.begin(), shaderKeys.end(), currentShaderKey); + if (it != shaderKeys.end()) { + shaderIndex = static_cast(std::distance(shaderKeys.begin(), it)) + 1; + } + } + int selectedShaderIndex = shaderIndex; + if (ImGui::Combo("Shader Asset", &selectedShaderIndex, shaderLabelPtrs.data(), static_cast(shaderLabelPtrs.size()))) { + if (selectedShaderIndex == 0) { + sprite.shaderId = 0; + } else { + sprite.shaderId = assets.GetShaderId(shaderKeys[selectedShaderIndex - 1]); + } + } + int shaderId = static_cast(sprite.shaderId); if (ImGui::InputInt("Shader Id", &shaderId)) { sprite.shaderId = shaderId < 0 ? 0 : static_cast(shaderId); @@ -760,6 +1328,37 @@ void GuiManager::RenderInspectorWindow() ImGui::Separator(); ImGui::Text("Texture"); + auto textureKeys = assets.ListTextureKeys(); + std::sort(textureKeys.begin(), textureKeys.end()); + std::vector textureLabels; + textureLabels.reserve(textureKeys.size() + 1); + textureLabels.push_back(""); + for (const auto& key : textureKeys) { + textureLabels.push_back(key); + } + std::vector textureLabelPtrs; + textureLabelPtrs.reserve(textureLabels.size()); + for (const auto& label : textureLabels) { + textureLabelPtrs.push_back(label.c_str()); + } + + int textureIndex = 0; + std::string currentTextureKey = assets.GetTextureKey(texture.textureId); + if (!currentTextureKey.empty()) { + auto it = std::find(textureKeys.begin(), textureKeys.end(), currentTextureKey); + if (it != textureKeys.end()) { + textureIndex = static_cast(std::distance(textureKeys.begin(), it)) + 1; + } + } + int selectedTextureIndex = textureIndex; + if (ImGui::Combo("Texture Asset", &selectedTextureIndex, textureLabelPtrs.data(), static_cast(textureLabelPtrs.size()))) { + if (selectedTextureIndex == 0) { + texture.textureId = 0; + } else { + texture.textureId = assets.GetTextureId(textureKeys[selectedTextureIndex - 1]); + } + } + int textureId = static_cast(texture.textureId); if (ImGui::InputInt("Texture Id", &textureId)) { texture.textureId = textureId < 0 ? 0u : static_cast(textureId); @@ -932,6 +1531,37 @@ void GuiManager::RenderInspectorWindow() ImGui::Separator(); ImGui::Text("Material"); + auto materialKeys = assets.ListMaterialKeys(); + std::sort(materialKeys.begin(), materialKeys.end()); + std::vector materialLabels; + materialLabels.reserve(materialKeys.size() + 1); + materialLabels.push_back(""); + for (const auto& key : materialKeys) { + materialLabels.push_back(key); + } + std::vector materialLabelPtrs; + materialLabelPtrs.reserve(materialLabels.size()); + for (const auto& label : materialLabels) { + materialLabelPtrs.push_back(label.c_str()); + } + + int materialIndex = 0; + std::string currentMaterialKey = assets.GetMaterialKey(material.materialId); + if (!currentMaterialKey.empty()) { + auto it = std::find(materialKeys.begin(), materialKeys.end(), currentMaterialKey); + if (it != materialKeys.end()) { + materialIndex = static_cast(std::distance(materialKeys.begin(), it)) + 1; + } + } + int selectedMaterialIndex = materialIndex; + if (ImGui::Combo("Material Asset", &selectedMaterialIndex, materialLabelPtrs.data(), static_cast(materialLabelPtrs.size()))) { + if (selectedMaterialIndex == 0) { + material.materialId = 0; + } else { + material.materialId = assets.GetMaterialId(materialKeys[selectedMaterialIndex - 1]); + } + } + int materialId = static_cast(material.materialId); if (ImGui::InputInt("Material Id", &materialId)) { material.materialId = materialId < 0 ? 0u : static_cast(materialId); @@ -955,6 +1585,37 @@ void GuiManager::RenderInspectorWindow() ImGui::Checkbox("Depth Test", &pass.depthTest); ImGui::Checkbox("Depth Write", &pass.depthWrite); + auto passShaderKeys = assets.ListShaderKeys(); + std::sort(passShaderKeys.begin(), passShaderKeys.end()); + std::vector passShaderLabels; + passShaderLabels.reserve(passShaderKeys.size() + 1); + passShaderLabels.push_back(""); + for (const auto& key : passShaderKeys) { + passShaderLabels.push_back(key); + } + std::vector passShaderLabelPtrs; + passShaderLabelPtrs.reserve(passShaderLabels.size()); + for (const auto& label : passShaderLabels) { + passShaderLabelPtrs.push_back(label.c_str()); + } + + int passShaderIndex = 0; + std::string currentPassShaderKey = assets.GetShaderKey(pass.shaderId); + if (!currentPassShaderKey.empty()) { + auto it = std::find(passShaderKeys.begin(), passShaderKeys.end(), currentPassShaderKey); + if (it != passShaderKeys.end()) { + passShaderIndex = static_cast(std::distance(passShaderKeys.begin(), it)) + 1; + } + } + int selectedPassShaderIndex = passShaderIndex; + if (ImGui::Combo("Pass Shader Asset", &selectedPassShaderIndex, passShaderLabelPtrs.data(), static_cast(passShaderLabelPtrs.size()))) { + if (selectedPassShaderIndex == 0) { + pass.shaderId = 0; + } else { + pass.shaderId = assets.GetShaderId(passShaderKeys[selectedPassShaderIndex - 1]); + } + } + int shaderId = static_cast(pass.shaderId); if (ImGui::InputInt("Pass Shader Id", &shaderId)) { pass.shaderId = shaderId < 0 ? 0u : static_cast(shaderId); diff --git a/src/gui/ImViewGuizmoIntegration.cpp b/src/gui/ImViewGuizmoIntegration.cpp new file mode 100644 index 0000000..48db19f --- /dev/null +++ b/src/gui/ImViewGuizmoIntegration.cpp @@ -0,0 +1 @@ +#include "ImViewGuizmoRaymath.h" diff --git a/src/scripting/ECSBindings.cpp b/src/scripting/ECSBindings.cpp index 2bfc3de..77ff808 100644 --- a/src/scripting/ECSBindings.cpp +++ b/src/scripting/ECSBindings.cpp @@ -66,18 +66,34 @@ void AS_SetScale(uint32_t entity, float x, float y, float z) { void AS_SetRotation(uint32_t entity, float rotation) { if (!registry) return; if (auto* t = registry->try_get((entt::entity)entity)) { - t->rotation = rotation; + t->rotation.y = rotation; } } float AS_GetRotation(uint32_t entity) { if (!registry) return 0.0f; if (auto* t = registry->try_get((entt::entity)entity)) { - return t->rotation; + return t->rotation.y; } return 0.0f; } +void AS_SetRotationEuler(uint32_t entity, float x, float y, float z) { + if (!registry) return; + if (auto* t = registry->try_get((entt::entity)entity)) { + t->rotation = {x, y, z}; + } +} + +void AS_GetRotationEuler(uint32_t entity, float* x, float* y, float* z) { + if (!registry || !x || !y || !z) return; + if (auto* t = registry->try_get((entt::entity)entity)) { + *x = t->rotation.x; + *y = t->rotation.y; + *z = t->rotation.z; + } +} + bool AS_HasTransform(uint32_t entity) { if (!registry) return false; return registry->all_of((entt::entity)entity); @@ -511,10 +527,18 @@ void RegisterECSBindings(asIScriptEngine *engine) { asFUNCTION(AS_SetRotation), asCALL_CDECL); assert(r >= 0); + r = engine->RegisterGlobalFunction("void SetRotationEuler(uint, float, float, float)", + asFUNCTION(AS_SetRotationEuler), asCALL_CDECL); + assert(r >= 0); + r = engine->RegisterGlobalFunction("float GetRotation(uint)", asFUNCTION(AS_GetRotation), asCALL_CDECL); assert(r >= 0); + r = engine->RegisterGlobalFunction("void GetRotationEuler(uint, float &out, float &out, float &out)", + asFUNCTION(AS_GetRotationEuler), asCALL_CDECL); + assert(r >= 0); + r = engine->RegisterGlobalFunction("bool HasTransform(uint)", asFUNCTION(AS_HasTransform), asCALL_CDECL); assert(r >= 0); diff --git a/src/scripting/ResourceBindings.cpp b/src/scripting/ResourceBindings.cpp index da1ff37..57f8ab9 100644 --- a/src/scripting/ResourceBindings.cpp +++ b/src/scripting/ResourceBindings.cpp @@ -3,6 +3,7 @@ #include "ModelManager.h" #include "MaterialManager.h" #include "TextureManager.h" +#include "AssetManager.h" #include #include #include "raylib.h" @@ -12,6 +13,7 @@ static ShaderManager* g_shaderManager = nullptr; static ModelManager* g_modelManager = nullptr; static MaterialManager* g_materialManager = nullptr; static TextureManager* g_textureManager = nullptr; +static AssetManager* g_assetManager = nullptr; void SetResourceManagers(ShaderManager* shaderMgr, ModelManager* modelMgr, MaterialManager* materialMgr, TextureManager* textureMgr) { g_shaderManager = shaderMgr; @@ -20,6 +22,10 @@ void SetResourceManagers(ShaderManager* shaderMgr, ModelManager* modelMgr, Mater g_textureManager = textureMgr; } +void SetAssetManager(AssetManager* assetMgr) { + g_assetManager = assetMgr; +} + // === Shader Management === unsigned int AS_LoadShader(const std::string& vsPath, const std::string& fsPath) { @@ -95,6 +101,129 @@ void AS_UnloadTextureAsset(unsigned int id) { g_textureManager->Unload(id); } +// === Asset Manager === + +unsigned int AS_AssetLoadTexture(const std::string& key, const std::string& path) { + if (!g_assetManager) return 0; + return g_assetManager->LoadTexture(key, path); +} + +unsigned int AS_AssetLoadShader(const std::string& key, const std::string& vsPath, const std::string& fsPath) { + if (!g_assetManager) return 0; + return g_assetManager->LoadShader(key, vsPath, fsPath); +} + +unsigned int AS_AssetLoadModel(const std::string& key, const std::string& path) { + if (!g_assetManager) return 0; + return g_assetManager->LoadModel(key, path); +} + +unsigned int AS_AssetLoadCube(const std::string& key, float width, float height, float length) { + if (!g_assetManager) return 0; + return g_assetManager->LoadCube(key, width, height, length); +} + +unsigned int AS_AssetLoadPoly(const std::string& key, int sides, float radius) { + if (!g_assetManager) return 0; + return g_assetManager->LoadPoly(key, sides, radius); +} + +unsigned int AS_AssetLoadSphere(const std::string& key, float radius, int rings, int slices) { + if (!g_assetManager) return 0; + return g_assetManager->LoadSphere(key, radius, rings, slices); +} + +unsigned int AS_AssetLoadHemiSphere(const std::string& key, float radius, int rings, int slices) { + if (!g_assetManager) return 0; + return g_assetManager->LoadHemiSphere(key, radius, rings, slices); +} + +unsigned int AS_AssetLoadPlane(const std::string& key, float width, float length, int resX, int resZ) { + if (!g_assetManager) return 0; + return g_assetManager->LoadPlane(key, width, length, resX, resZ); +} + +unsigned int AS_AssetLoadCylinder(const std::string& key, float radius, float height, int slices) { + if (!g_assetManager) return 0; + return g_assetManager->LoadCylinder(key, radius, height, slices); +} + +unsigned int AS_AssetLoadCone(const std::string& key, float radius, float height, int slices) { + if (!g_assetManager) return 0; + return g_assetManager->LoadCone(key, radius, height, slices); +} + +unsigned int AS_AssetLoadTorus(const std::string& key, float radius, float size, int radSeg, int sides) { + if (!g_assetManager) return 0; + return g_assetManager->LoadTorus(key, radius, size, radSeg, sides); +} + +unsigned int AS_AssetLoadKnot(const std::string& key, float radius, float size, int radSeg, int sides) { + if (!g_assetManager) return 0; + return g_assetManager->LoadKnot(key, radius, size, radSeg, sides); +} + +unsigned int AS_AssetLoadHeightmap(const std::string& key, const std::string& heightmapPath, float sizeX, float sizeY, float sizeZ) { + if (!g_assetManager) return 0; + return g_assetManager->LoadHeightmap(key, heightmapPath, sizeX, sizeY, sizeZ); +} + +unsigned int AS_AssetLoadCubicmap(const std::string& key, const std::string& cubicmapPath, float sizeX, float sizeY, float sizeZ) { + if (!g_assetManager) return 0; + return g_assetManager->LoadCubicmap(key, cubicmapPath, sizeX, sizeY, sizeZ); +} + +unsigned int AS_AssetCreateMaterial(const std::string& key, unsigned int shaderId, unsigned char r, unsigned char g, unsigned char b, unsigned char a) { + if (!g_assetManager) return 0; + Color albedo = {r, g, b, a}; + return g_assetManager->CreateMaterial(key, shaderId, albedo); +} + +bool AS_AssetUnloadTexture(const std::string& key) { + if (!g_assetManager) return false; + return g_assetManager->UnloadTexture(key); +} + +bool AS_AssetUnloadShader(const std::string& key) { + if (!g_assetManager) return false; + return g_assetManager->UnloadShader(key); +} + +bool AS_AssetUnloadModel(const std::string& key) { + if (!g_assetManager) return false; + return g_assetManager->UnloadModel(key); +} + +bool AS_AssetUnloadMaterial(const std::string& key) { + if (!g_assetManager) return false; + return g_assetManager->UnloadMaterial(key); +} + +unsigned int AS_AssetGetTextureId(const std::string& key) { + if (!g_assetManager) return 0; + return g_assetManager->GetTextureId(key); +} + +unsigned int AS_AssetGetShaderId(const std::string& key) { + if (!g_assetManager) return 0; + return g_assetManager->GetShaderId(key); +} + +unsigned int AS_AssetGetModelId(const std::string& key) { + if (!g_assetManager) return 0; + return g_assetManager->GetModelId(key); +} + +unsigned int AS_AssetGetMaterialId(const std::string& key) { + if (!g_assetManager) return 0; + return g_assetManager->GetMaterialId(key); +} + +bool AS_AssetApplyMeshTangents(const std::string& key, int meshIndex) { + if (!g_assetManager) return false; + return g_assetManager->ApplyMeshTangents(key, meshIndex); +} + void RegisterResourceBindings(asIScriptEngine *engine) { int r; @@ -163,5 +292,104 @@ void RegisterResourceBindings(asIScriptEngine *engine) asFUNCTION(AS_UnloadTextureAsset), asCALL_CDECL); assert(r >= 0); + // === Asset namespace === + engine->SetDefaultNamespace("Asset"); + + r = engine->RegisterGlobalFunction("uint LoadTexture(const string &in, const string &in)", + asFUNCTION(AS_AssetLoadTexture), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("uint LoadShader(const string &in, const string &in, const string &in)", + asFUNCTION(AS_AssetLoadShader), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("uint LoadModel(const string &in, const string &in)", + asFUNCTION(AS_AssetLoadModel), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("uint LoadCube(const string &in, float, float, float)", + asFUNCTION(AS_AssetLoadCube), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("uint LoadPoly(const string &in, int, float)", + asFUNCTION(AS_AssetLoadPoly), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("uint LoadSphere(const string &in, float, int, int)", + asFUNCTION(AS_AssetLoadSphere), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("uint LoadHemiSphere(const string &in, float, int, int)", + asFUNCTION(AS_AssetLoadHemiSphere), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("uint LoadPlane(const string &in, float, float, int, int)", + asFUNCTION(AS_AssetLoadPlane), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("uint LoadCylinder(const string &in, float, float, int)", + asFUNCTION(AS_AssetLoadCylinder), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("uint LoadCone(const string &in, float, float, int)", + asFUNCTION(AS_AssetLoadCone), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("uint LoadTorus(const string &in, float, float, int, int)", + asFUNCTION(AS_AssetLoadTorus), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("uint LoadKnot(const string &in, float, float, int, int)", + asFUNCTION(AS_AssetLoadKnot), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("uint LoadHeightmap(const string &in, const string &in, float, float, float)", + asFUNCTION(AS_AssetLoadHeightmap), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("uint LoadCubicmap(const string &in, const string &in, float, float, float)", + asFUNCTION(AS_AssetLoadCubicmap), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("uint CreateMaterial(const string &in, uint, uint8, uint8, uint8, uint8)", + asFUNCTION(AS_AssetCreateMaterial), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("bool UnloadTexture(const string &in)", + asFUNCTION(AS_AssetUnloadTexture), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("bool UnloadShader(const string &in)", + asFUNCTION(AS_AssetUnloadShader), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("bool UnloadModel(const string &in)", + asFUNCTION(AS_AssetUnloadModel), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("bool UnloadMaterial(const string &in)", + asFUNCTION(AS_AssetUnloadMaterial), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("uint GetTextureId(const string &in)", + asFUNCTION(AS_AssetGetTextureId), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("uint GetShaderId(const string &in)", + asFUNCTION(AS_AssetGetShaderId), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("uint GetModelId(const string &in)", + asFUNCTION(AS_AssetGetModelId), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("uint GetMaterialId(const string &in)", + asFUNCTION(AS_AssetGetMaterialId), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("bool ApplyMeshTangents(const string &in, int = 0)", + asFUNCTION(AS_AssetApplyMeshTangents), asCALL_CDECL); + assert(r >= 0); + engine->SetDefaultNamespace(""); } diff --git a/src/scripting/ScriptEngine.cpp b/src/scripting/ScriptEngine.cpp index 8c1028b..895abcf 100644 --- a/src/scripting/ScriptEngine.cpp +++ b/src/scripting/ScriptEngine.cpp @@ -346,6 +346,33 @@ void ScriptEngine::CallObjectMethod(asIScriptFunction* method, asIScriptObject* ctx->Release(); } +void ScriptEngine::CallSceneObjectMethod(asIScriptFunction* method, asIScriptObject* object, float dt) +{ + if (!method || !engine || !object) return; + + asIScriptContext* ctx = engine->CreateContext(); + if (!ctx) return; + + int r = ctx->Prepare(method); + if (r < 0) { ctx->Release(); return; } + + ctx->SetObject(object); + + const asUINT paramCount = method->GetParamCount(); + if (paramCount >= 1) { + ctx->SetArgFloat(0, dt); + } + + r = ctx->Execute(); + if (r != asEXECUTION_FINISHED) { + if (r == asEXECUTION_EXCEPTION) { + log_error("Script exception: %s", ctx->GetExceptionString()); + } + } + + ctx->Release(); +} + void ScriptEngine::ClearCachedFunctions() { updateFunc = nullptr; hasValidScript = false; From 36fd4047dcc6bc7047dccc79861d4b15b31f212e Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Tue, 10 Mar 2026 20:03:44 +1300 Subject: [PATCH 49/53] fix: scene scripts and asset restore --- assets/registry.toml | 6 +++ docs/Editor.md | 2 +- docs/Scenegraph.md | 4 +- docs/Scripting.md | 4 +- imgui.ini | 20 ++++----- include/ECSComponents.h | 8 ++-- scenes/demo.toml | 2 + scripts/as.predefined | 16 ++++---- scripts/demo_scene.as | 52 +++++++++++++++++++++++ scripts/example_rendering.as | 4 +- src/Application.cpp | 30 +++++++------- src/SceneLoader.cpp | 77 ++++++++++++++++++++++------------- src/gui/GuiManager.cpp | 56 ++++++++++++------------- src/scripting/ECSBindings.cpp | 74 ++++++++++++++++----------------- tests/scenegraph_tests.cpp | 4 +- 15 files changed, 220 insertions(+), 139 deletions(-) create mode 100644 scripts/demo_scene.as diff --git a/assets/registry.toml b/assets/registry.toml index a577f87..0d52586 100644 --- a/assets/registry.toml +++ b/assets/registry.toml @@ -7,3 +7,9 @@ type = "primitive" primitive = "torus" params = [0.5, 1, 16, 8] +[[model]] +key = "demo_cube" +type = "primitive" +primitive = "cube" +params = [1, 1, 1] + diff --git a/docs/Editor.md b/docs/Editor.md index e0197de..6ddff2e 100644 --- a/docs/Editor.md +++ b/docs/Editor.md @@ -53,7 +53,7 @@ This document outlines the in-app editor UI, its panels, and common workflows. - Tag: rename the entity. - Transform: position, scale, rotation (degrees in UI). - Velocity: linear and angular velocity. -- Sprite: model id, shader id, color, outline. +- Model Renderer: model id, shader id, color, outline. - Texture: texture id. - UV Transform: scale, offset, rotation (radians). - Script: per-entity script path and enabled toggle. diff --git a/docs/Scenegraph.md b/docs/Scenegraph.md index edca096..62c5a5a 100644 --- a/docs/Scenegraph.md +++ b/docs/Scenegraph.md @@ -24,7 +24,7 @@ Computed each frame from the hierarchy and local transform. Rendering uses `Worl 1. Systems update local transforms (e.g., velocity system). 2. `UpdateWorldTransforms()` traverses the hierarchy and computes `WorldTransform`. -3. Rendering draws from `WorldTransform` + `Sprite`. +3. Rendering draws from `WorldTransform` + `ModelRenderer`. ## Script API @@ -94,7 +94,7 @@ shader_fs = "shaders/toon.fs" - `model_size` (vec3) for cubes/planes - `radius`, `rings`, `slices` for spheres - `color` — hex `0xRRGGBBAA` (matches script colors) -- `outline_size` — optional sprite outline +- `outline_size` — optional model outline - `shader_vs`, `shader_fs` — optional shader paths - `shader_asset` (string) — asset key for shaders - `shader_id` (int) — numeric shader id diff --git a/docs/Scripting.md b/docs/Scripting.md index 9273631..0309cc5 100644 --- a/docs/Scripting.md +++ b/docs/Scripting.md @@ -49,8 +49,8 @@ Asset::LoadCube("unit_cube", 1.0f, 1.0f, 1.0f); Asset::CreateMaterial("toon_mat", Asset::GetShaderId("toon"), 255, 255, 255, 255); uint e = ECS::CreateEntity(); -ECS::AddSprite(e, int(Asset::GetModelId("unit_cube")), 0xFFFFFFFF, 0.0f); -ECS::SetSpriteShader(e, Asset::GetShaderId("toon")); +ECS::AddModelRenderer(e, int(Asset::GetModelId("unit_cube")), 0xFFFFFFFF, 0.0f); +ECS::SetModelRendererShader(e, Asset::GetShaderId("toon")); ECS::AddTexture(e, Asset::GetTextureId("grid")); ECS::AddMaterial(e, Asset::GetMaterialId("toon_mat")); ``` diff --git a/imgui.ini b/imgui.ini index d34daa6..2b194ed 100644 --- a/imgui.ini +++ b/imgui.ini @@ -21,27 +21,27 @@ Collapsed=0 DockId=0x00000002,0 [Window][##TOAST0] -Pos=1035,637 -Size=225,63 +Pos=1060,637 +Size=200,63 Collapsed=0 [Window][##TOAST1] -Pos=1035,564 -Size=225,63 +Pos=1060,564 +Size=200,63 Collapsed=0 [Window][##TOAST2] -Pos=1704,762 -Size=196,63 +Pos=1060,491 +Size=200,63 Collapsed=0 [Window][##TOAST3] -Pos=1704,689 -Size=196,63 +Pos=1060,418 +Size=200,63 Collapsed=0 [Window][##TOAST4] -Pos=1704,616 +Pos=1064,345 Size=196,63 Collapsed=0 @@ -115,5 +115,5 @@ DockSpace ID=0x9076BACA Window=0x34F970D7 Pos=8,28 Size=1264,684 Split=Y S DockNode ID=0x00000003 Parent=0x00000005 SizeRef=222,684 Selected=0xE601B12F DockNode ID=0x00000004 Parent=0x00000005 SizeRef=663,684 CentralNode=1 Selected=0x27A02DAA DockNode ID=0x00000006 Parent=0x00000001 SizeRef=375,684 Selected=0x36DC96AB - DockNode ID=0x00000002 Parent=0x9076BACA SizeRef=1264,274 Selected=0x42C24103 + DockNode ID=0x00000002 Parent=0x9076BACA SizeRef=1264,274 Selected=0xBEDDA0C1 diff --git a/include/ECSComponents.h b/include/ECSComponents.h index e466527..46e018c 100644 --- a/include/ECSComponents.h +++ b/include/ECSComponents.h @@ -41,20 +41,20 @@ struct Velocity { : linear(lin), angular(ang) {} }; -// Sprite component - visual representation -struct Sprite { +// ModelRenderer component - 3D model rendering data +struct ModelRenderer { size_t modelId; // Index into models array Color color; // Tint color float outlineSize; // Outline thickness unsigned int shaderId; // Shader to use (0 = no shader) - Sprite() + ModelRenderer() : modelId(0) , color(WHITE) , outlineSize(0.0f) , shaderId(0) {} - Sprite(int model, Color col = WHITE, float outline = 0.0f, unsigned int shader = 0) + ModelRenderer(int model, Color col = WHITE, float outline = 0.0f, unsigned int shader = 0) : modelId(model), color(col), outlineSize(outline), shaderId(shader) {} }; diff --git a/scenes/demo.toml b/scenes/demo.toml index 5364bed..621380c 100644 --- a/scenes/demo.toml +++ b/scenes/demo.toml @@ -1,3 +1,5 @@ +scene_script = "scripts/demo_scene.as" + [[entity]] id = "entity_1" tag = "Root" diff --git a/scripts/as.predefined b/scripts/as.predefined index 00e35bc..af7f20d 100644 --- a/scripts/as.predefined +++ b/scripts/as.predefined @@ -57,14 +57,14 @@ namespace ECS { bool HasVelocity(uint entity); void RemoveVelocity(uint entity); - // Sprite component - void AddSprite(uint entity, int modelId, uint color, float outlineSize = 0.0f); - void SetSpriteColor(uint entity, uint color); - void SetSpriteModel(uint entity, int modelId); - void SetSpriteOutline(uint entity, float outlineSize); - void SetSpriteShader(uint entity, uint shaderId); - bool HasSprite(uint entity); - void RemoveSprite(uint entity); + // ModelRenderer component + void AddModelRenderer(uint entity, int modelId, uint color, float outlineSize = 0.0f); + void SetModelRendererColor(uint entity, uint color); + void SetModelRendererModel(uint entity, int modelId); + void SetModelRendererOutline(uint entity, float outlineSize); + void SetModelRendererShader(uint entity, uint shaderId); + bool HasModelRenderer(uint entity); + void RemoveModelRenderer(uint entity); // Texture component void AddTexture(uint entity, uint textureId); diff --git a/scripts/demo_scene.as b/scripts/demo_scene.as new file mode 100644 index 0000000..0b23fdc --- /dev/null +++ b/scripts/demo_scene.as @@ -0,0 +1,52 @@ +// Demo scene script with input-driven behavior. +class SceneScript { + uint sceneRoot = 0; + uint camera = 0; + uint light = 0; + uint cube = 0; + float time = 0.0f; + bool highlight = false; + + void Init() { + Log(LOG_INFO, "Demo scene script init"); + + cube = ECS::CreateEntity(); + ECS::AddTransform(cube, 0.0f, 1.5f, 0.0f); + uint modelId = Asset::GetModelId("demo_cube"); + if (modelId == 0) { + modelId = Asset::LoadCube("demo_cube", 1.0f, 1.0f, 1.0f); + } + ECS::AddModelRenderer(cube, int(modelId), 0xFFAA00FF, 0.0f); + ECS::AddTag(cube, "InputCube"); + } + + void Shutdown() { + Log(LOG_INFO, "Demo scene script shutdown"); + } + + void Update(float dt) { + time += dt; + + if (ECS::IsValid(cube) && ECS::HasTransform(cube)) { + ECS::SetRotationEuler(cube, 0.0f, time, time * 0.5f); + } + + if (IsActionPressed("jump")) { + highlight = !highlight; + if (highlight) { + ECS::SetModelRendererColor(cube, 0x00FF88FF); + ECS::SetModelRendererOutline(cube, 2.0f); + Toast::Info("Highlight on"); + } else { + ECS::SetModelRendererColor(cube, 0xFFAA00FF); + ECS::SetModelRendererOutline(cube, 0.0f); + Toast::Info("Highlight off"); + } + } + + if (IsActionPressed("attack")) { + ECS::SetLightDirection(light, -0.5f, 0.7f, -0.3f); + Toast::Success("Light toggled"); + } + } +} diff --git a/scripts/example_rendering.as b/scripts/example_rendering.as index a6ebcd0..1c2ea78 100644 --- a/scripts/example_rendering.as +++ b/scripts/example_rendering.as @@ -53,7 +53,7 @@ void Init() { // === Create Cube with Outline === cube = ECS::CreateEntity(); ECS::AddTransform(cube, -1.5, 0.5, 0.0); - ECS::AddSprite(cube, cubeModel, 0xFFFFFFFF, 0.0); + ECS::AddModelRenderer(cube, cubeModel, 0xFFFFFFFF, 0.0); ECS::AddMaterial(cube, redMaterial); ECS::AddTag(cube, "Cube"); ECS::AddVelocity(cube, 0.0, 0.0, 0.0, 1.0); // rotating @@ -64,7 +64,7 @@ void Init() { // === Create Sphere === sphere = ECS::CreateEntity(); ECS::AddTransform(sphere, 1.5, 0.5, 0.0); - ECS::AddSprite(sphere, sphereModel, 0xFFFFFFFF, 0.0); + ECS::AddModelRenderer(sphere, sphereModel, 0xFFFFFFFF, 0.0); ECS::AddMaterial(sphere, blueMaterial); ECS::AddTag(sphere, "Sphere"); ECS::AddVelocity(sphere, 0.5, 0.0, 0.2, 0.5); // moving and rotating diff --git a/src/Application.cpp b/src/Application.cpp index ad248ca..21f9612 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -718,14 +718,14 @@ void Application::RenderScene() BeginMode3D(camera); DrawGrid(10, 1); - // Render all entities with WorldTransform and Sprite components - auto view = registry.view(); - view.each([&](auto entity, auto& transform, auto& sprite) { - if (sprite.modelId <= 0) { + // Render all entities with WorldTransform and ModelRenderer components + auto view = registry.view(); + view.each([&](auto entity, auto& transform, auto& renderer) { + if (renderer.modelId <= 0) { return; } - Model* model = modelManager.Get(static_cast(sprite.modelId)); + Model* model = modelManager.Get(static_cast(renderer.modelId)); if (!model) { return; } @@ -743,9 +743,9 @@ void Application::RenderScene() } } - // If sprite has a shader, apply it with uniforms - if (sprite.shaderId > 0) { - Shader* shader = shaderManager.Get(static_cast(sprite.shaderId)); + // If model renderer has a shader, apply it with uniforms + if (renderer.shaderId > 0) { + Shader* shader = shaderManager.Get(static_cast(renderer.shaderId)); if (shader) { // Set shader uniforms int albedoLoc = GetShaderLocation(*shader, "albedo"); @@ -753,10 +753,10 @@ void Application::RenderScene() if (albedoLoc != -1) { Vector4 albedo = { - sprite.color.r / 255.0f, - sprite.color.g / 255.0f, - sprite.color.b / 255.0f, - sprite.color.a / 255.0f + renderer.color.r / 255.0f, + renderer.color.g / 255.0f, + renderer.color.b / 255.0f, + renderer.color.a / 255.0f }; SetShaderValue(*shader, albedoLoc, &albedo, SHADER_UNIFORM_VEC4); } @@ -792,7 +792,7 @@ void Application::RenderScene() } } - // Draw model using Sprite.color as the tint + // Draw model using ModelRenderer.color as the tint Quaternion rotation = QuaternionFromEuler(transform.rotation.x, transform.rotation.y, transform.rotation.z); Vector3 axis = {0.0f, 1.0f, 0.0f}; float angle = 0.0f; @@ -804,8 +804,8 @@ void Application::RenderScene() } DrawModelEx(*model, transform.position, axis, - angle * RAD2DEG, transform.scale, - sprite.color); + angle * RAD2DEG, transform.scale, + renderer.color); if (restoreTexture) { model->materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = originalTexture; diff --git a/src/SceneLoader.cpp b/src/SceneLoader.cpp index 2d69842..9d5967b 100644 --- a/src/SceneLoader.cpp +++ b/src/SceneLoader.cpp @@ -70,7 +70,7 @@ struct SceneEntityDef { Vector3 scale{1.0f, 1.0f, 1.0f}; Vector3 rotation{0.0f, 0.0f, 0.0f}; - bool hasSprite = false; + bool hasModelRenderer = false; std::string model; std::string modelAsset; unsigned int modelId = 0; @@ -504,15 +504,15 @@ entt::entity LoadSceneFromFile(const std::string& path, bool clearExisting) { } } else if (key == "model") { ParseString(value, current->model); - current->hasSprite = true; + current->hasModelRenderer = true; } else if (key == "model_asset") { if (ParseString(value, current->modelAsset)) { - current->hasSprite = true; + current->hasModelRenderer = true; } } else if (key == "model_id") { current->modelId = static_cast(std::stoul(value, nullptr, 0)); current->hasModelId = true; - current->hasSprite = true; + current->hasModelRenderer = true; } else if (key == "model_size") { ParseVec3(value, current->modelSize); } else if (key == "radius") { @@ -523,7 +523,7 @@ entt::entity LoadSceneFromFile(const std::string& path, bool clearExisting) { current->slices = std::stoi(value); } else if (key == "color") { ParseHexColor(value, current->color); - current->hasSprite = true; + current->hasModelRenderer = true; } else if (key == "outline_size") { current->outlineSize = std::stof(value); } else if (key == "shader_vs") { @@ -532,12 +532,12 @@ entt::entity LoadSceneFromFile(const std::string& path, bool clearExisting) { ParseString(value, current->shaderFs); } else if (key == "shader_asset") { if (ParseString(value, current->shaderAsset)) { - current->hasSprite = true; + current->hasModelRenderer = true; } } else if (key == "shader_id") { current->shaderId = static_cast(std::stoul(value, nullptr, 0)); current->hasShaderId = true; - current->hasSprite = true; + current->hasModelRenderer = true; } else if (key == "material_asset") { if (ParseString(value, current->materialAsset)) { current->hasMaterial = true; @@ -631,13 +631,20 @@ entt::entity LoadSceneFromFile(const std::string& path, bool clearExisting) { g_sceneRegistry->emplace(entity, def.id); } - if (def.hasTransform || def.hasSprite) { + if (def.hasTransform || def.hasModelRenderer) { g_sceneRegistry->emplace(entity, def.position, def.scale, def.rotation); } - if (def.hasSprite) { + if (def.hasModelRenderer) { unsigned int modelId = 0; - if (!def.model.empty()) { + if (g_sceneAssetManager && !def.modelAsset.empty()) { + modelId = g_sceneAssetManager->GetModelId(def.modelAsset); + if (modelId == 0 && def.hasModelId) { + g_sceneAssetManager->RegisterModel(def.modelAsset, def.modelId, "id"); + modelId = def.modelId; + } + } + if (modelId == 0 && !def.model.empty()) { modelId = LoadModelFor(def, modelCache); } if (modelId == 0 && def.hasModelId) { @@ -650,13 +657,20 @@ entt::entity LoadSceneFromFile(const std::string& path, bool clearExisting) { static_cast(def.color & 0xFF) }; unsigned int shaderId = 0; - if (!def.shaderVs.empty() && !def.shaderFs.empty()) { + if (g_sceneAssetManager && !def.shaderAsset.empty()) { + shaderId = g_sceneAssetManager->GetShaderId(def.shaderAsset); + if (shaderId == 0 && def.hasShaderId) { + g_sceneAssetManager->RegisterShader(def.shaderAsset, def.shaderId, "id"); + shaderId = def.shaderId; + } + } + if (shaderId == 0 && !def.shaderVs.empty() && !def.shaderFs.empty()) { shaderId = LoadShaderFor(def, shaderCache); } if (shaderId == 0 && def.hasShaderId) { shaderId = def.shaderId; } - g_sceneRegistry->emplace(entity, static_cast(modelId), col, def.outlineSize, shaderId); + g_sceneRegistry->emplace(entity, static_cast(modelId), col, def.outlineSize, shaderId); } if (def.hasMaterial) { @@ -676,7 +690,14 @@ entt::entity LoadSceneFromFile(const std::string& path, bool clearExisting) { if (def.hasTexture) { unsigned int textureId = 0; - if (!def.texturePath.empty()) { + if (g_sceneAssetManager && !def.textureAsset.empty()) { + textureId = g_sceneAssetManager->GetTextureId(def.textureAsset); + if (textureId == 0 && def.hasTextureId) { + g_sceneAssetManager->RegisterTexture(def.textureAsset, def.textureId, "id"); + textureId = def.textureId; + } + } + if (textureId == 0 && !def.texturePath.empty()) { textureId = LoadTextureFor(def, textureCache); } if (textureId == 0 && def.hasTextureId) { @@ -805,16 +826,16 @@ bool SaveSceneToFile(const std::string& path) { file << "rotation_deg = " << Vec3ToString(rotDeg) << "\n"; } - if (auto* sprite = registry.try_get(entity)) { + if (auto* renderer = registry.try_get(entity)) { bool wroteModel = false; - if (g_sceneAssetManager && sprite->modelId > 0) { - const std::string& modelKey = g_sceneAssetManager->GetModelKey(static_cast(sprite->modelId)); + if (g_sceneAssetManager && renderer->modelId > 0) { + const std::string& modelKey = g_sceneAssetManager->GetModelKey(static_cast(renderer->modelId)); if (!modelKey.empty()) { file << "model_asset = \"" << EscapeString(modelKey) << "\"\n"; } } - if (g_sceneModelManager && sprite->modelId > 0) { - const ModelSource* source = g_sceneModelManager->GetSource(static_cast(sprite->modelId)); + if (g_sceneModelManager && renderer->modelId > 0) { + const ModelSource* source = g_sceneModelManager->GetSource(static_cast(renderer->modelId)); if (source) { switch (source->type) { case ModelSourceType::Path: @@ -849,28 +870,28 @@ bool SaveSceneToFile(const std::string& path) { } } - if (!wroteModel && sprite->modelId > 0) { - file << "model_id = " << sprite->modelId << "\n"; + if (!wroteModel && renderer->modelId > 0) { + file << "model_id = " << renderer->modelId << "\n"; } - file << "color = " << ColorToHexString(sprite->color) << "\n"; - file << "outline_size = " << FloatToString(sprite->outlineSize) << "\n"; + file << "color = " << ColorToHexString(renderer->color) << "\n"; + file << "outline_size = " << FloatToString(renderer->outlineSize) << "\n"; bool wroteShader = false; - if (g_sceneAssetManager && sprite->shaderId > 0) { - const std::string& shaderKey = g_sceneAssetManager->GetShaderKey(sprite->shaderId); + if (g_sceneAssetManager && renderer->shaderId > 0) { + const std::string& shaderKey = g_sceneAssetManager->GetShaderKey(renderer->shaderId); if (!shaderKey.empty()) { file << "shader_asset = \"" << EscapeString(shaderKey) << "\"\n"; } } - if (g_sceneShaderManager && sprite->shaderId > 0) { - const ShaderSource* source = g_sceneShaderManager->GetSource(sprite->shaderId); + if (g_sceneShaderManager && renderer->shaderId > 0) { + const ShaderSource* source = g_sceneShaderManager->GetSource(renderer->shaderId); if (source && !source->vsPath.empty() && !source->fsPath.empty()) { file << "shader_vs = \"" << EscapeString(source->vsPath) << "\"\n"; file << "shader_fs = \"" << EscapeString(source->fsPath) << "\"\n"; wroteShader = true; } } - if (!wroteShader && sprite->shaderId > 0) { - file << "shader_id = " << sprite->shaderId << "\n"; + if (!wroteShader && renderer->shaderId > 0) { + file << "shader_id = " << renderer->shaderId << "\n"; } } diff --git a/src/gui/GuiManager.cpp b/src/gui/GuiManager.cpp index b2a6cad..a0639e2 100644 --- a/src/gui/GuiManager.cpp +++ b/src/gui/GuiManager.cpp @@ -1018,7 +1018,7 @@ void GuiManager::RenderInspectorWindow() {"Tag", 0}, {"Transform", 1}, {"Velocity", 2}, - {"Sprite", 3}, + {"Model Renderer", 3}, {"Script", 4}, {"Camera", 5}, {"Light", 6}, @@ -1033,7 +1033,7 @@ void GuiManager::RenderInspectorWindow() case 0: return registry.any_of(selectedEntity); case 1: return registry.any_of(selectedEntity); case 2: return registry.any_of(selectedEntity); - case 3: return registry.any_of(selectedEntity); + case 3: return registry.any_of(selectedEntity); case 4: return registry.any_of(selectedEntity); case 5: return registry.any_of(selectedEntity); case 6: return registry.any_of(selectedEntity); @@ -1090,7 +1090,7 @@ void GuiManager::RenderInspectorWindow() registry.emplace(selectedEntity, Vector3{0.0f, 0.0f, 0.0f}, 0.0f); break; case 3: - registry.emplace(selectedEntity, 0, WHITE, 0.0f, 0); + registry.emplace(selectedEntity, 0, WHITE, 0.0f, 0); break; case 4: registry.emplace(selectedEntity); @@ -1224,11 +1224,11 @@ void GuiManager::RenderInspectorWindow() ImGui::EndDisabled(); } - // Sprite - if (registry.any_of(selectedEntity)) { - auto& sprite = registry.get(selectedEntity); + // Model Renderer + if (registry.any_of(selectedEntity)) { + auto& renderer = registry.get(selectedEntity); ImGui::Separator(); - ImGui::Text("Sprite"); + ImGui::Text("Model Renderer"); auto modelKeys = assets.ListModelKeys(); std::sort(modelKeys.begin(), modelKeys.end()); @@ -1245,7 +1245,7 @@ void GuiManager::RenderInspectorWindow() } int modelIndex = 0; - std::string currentModelKey = assets.GetModelKey(static_cast(sprite.modelId)); + std::string currentModelKey = assets.GetModelKey(static_cast(renderer.modelId)); if (!currentModelKey.empty()) { auto it = std::find(modelKeys.begin(), modelKeys.end(), currentModelKey); if (it != modelKeys.end()) { @@ -1255,15 +1255,15 @@ void GuiManager::RenderInspectorWindow() int selectedModelIndex = modelIndex; if (ImGui::Combo("Model Asset", &selectedModelIndex, modelLabelPtrs.data(), static_cast(modelLabelPtrs.size()))) { if (selectedModelIndex == 0) { - sprite.modelId = 0; + renderer.modelId = 0; } else { - sprite.modelId = assets.GetModelId(modelKeys[selectedModelIndex - 1]); + renderer.modelId = assets.GetModelId(modelKeys[selectedModelIndex - 1]); } } - int modelId = static_cast(sprite.modelId); + int modelId = static_cast(renderer.modelId); if (ImGui::InputInt("Model Id", &modelId)) { - sprite.modelId = modelId < 0 ? 0 : static_cast(modelId); + renderer.modelId = modelId < 0 ? 0 : static_cast(modelId); } auto shaderKeys = assets.ListShaderKeys(); @@ -1281,7 +1281,7 @@ void GuiManager::RenderInspectorWindow() } int shaderIndex = 0; - std::string currentShaderKey = assets.GetShaderKey(sprite.shaderId); + std::string currentShaderKey = assets.GetShaderKey(renderer.shaderId); if (!currentShaderKey.empty()) { auto it = std::find(shaderKeys.begin(), shaderKeys.end(), currentShaderKey); if (it != shaderKeys.end()) { @@ -1291,34 +1291,34 @@ void GuiManager::RenderInspectorWindow() int selectedShaderIndex = shaderIndex; if (ImGui::Combo("Shader Asset", &selectedShaderIndex, shaderLabelPtrs.data(), static_cast(shaderLabelPtrs.size()))) { if (selectedShaderIndex == 0) { - sprite.shaderId = 0; + renderer.shaderId = 0; } else { - sprite.shaderId = assets.GetShaderId(shaderKeys[selectedShaderIndex - 1]); + renderer.shaderId = assets.GetShaderId(shaderKeys[selectedShaderIndex - 1]); } } - int shaderId = static_cast(sprite.shaderId); + int shaderId = static_cast(renderer.shaderId); if (ImGui::InputInt("Shader Id", &shaderId)) { - sprite.shaderId = shaderId < 0 ? 0 : static_cast(shaderId); + renderer.shaderId = shaderId < 0 ? 0 : static_cast(shaderId); } float color[4] = { - sprite.color.r / 255.0f, - sprite.color.g / 255.0f, - sprite.color.b / 255.0f, - sprite.color.a / 255.0f + renderer.color.r / 255.0f, + renderer.color.g / 255.0f, + renderer.color.b / 255.0f, + renderer.color.a / 255.0f }; if (ImGui::ColorEdit4("Color", color)) { - sprite.color.r = static_cast(color[0] * 255.0f); - sprite.color.g = static_cast(color[1] * 255.0f); - sprite.color.b = static_cast(color[2] * 255.0f); - sprite.color.a = static_cast(color[3] * 255.0f); + renderer.color.r = static_cast(color[0] * 255.0f); + renderer.color.g = static_cast(color[1] * 255.0f); + renderer.color.b = static_cast(color[2] * 255.0f); + renderer.color.a = static_cast(color[3] * 255.0f); } - ImGui::DragFloat("Outline", &sprite.outlineSize, 0.05f, 0.0f, 10.0f); + ImGui::DragFloat("Outline", &renderer.outlineSize, 0.05f, 0.0f, 10.0f); - if (ImGui::Button("Remove Sprite")) { - registry.remove(selectedEntity); + if (ImGui::Button("Remove Model Renderer")) { + registry.remove(selectedEntity); } } diff --git a/src/scripting/ECSBindings.cpp b/src/scripting/ECSBindings.cpp index 77ff808..0737509 100644 --- a/src/scripting/ECSBindings.cpp +++ b/src/scripting/ECSBindings.cpp @@ -135,57 +135,57 @@ void AS_RemoveVelocity(uint32_t entity) { registry->remove((entt::entity)entity); } -// === Sprite Component === +// === ModelRenderer Component === -void AS_AddSprite(uint32_t entity, int modelId, uint32_t color, float outlineSize) { +void AS_AddModelRenderer(uint32_t entity, int modelId, uint32_t color, float outlineSize) { if (!registry) return; Color col; col.r = (color >> 24) & 0xFF; col.g = (color >> 16) & 0xFF; col.b = (color >> 8) & 0xFF; col.a = color & 0xFF; - registry->emplace((entt::entity)entity, modelId, col, outlineSize); + registry->emplace((entt::entity)entity, modelId, col, outlineSize); } -void AS_SetSpriteColor(uint32_t entity, uint32_t color) { +void AS_SetModelRendererColor(uint32_t entity, uint32_t color) { if (!registry) return; - if (auto* s = registry->try_get((entt::entity)entity)) { - s->color.r = (color >> 24) & 0xFF; - s->color.g = (color >> 16) & 0xFF; - s->color.b = (color >> 8) & 0xFF; - s->color.a = color & 0xFF; + if (auto* renderer = registry->try_get((entt::entity)entity)) { + renderer->color.r = (color >> 24) & 0xFF; + renderer->color.g = (color >> 16) & 0xFF; + renderer->color.b = (color >> 8) & 0xFF; + renderer->color.a = color & 0xFF; } } -void AS_SetSpriteModel(uint32_t entity, int modelId) { +void AS_SetModelRendererModel(uint32_t entity, int modelId) { if (!registry) return; - if (auto* s = registry->try_get((entt::entity)entity)) { - s->modelId = modelId; + if (auto* renderer = registry->try_get((entt::entity)entity)) { + renderer->modelId = modelId; } } -void AS_SetSpriteOutline(uint32_t entity, float outlineSize) { +void AS_SetModelRendererOutline(uint32_t entity, float outlineSize) { if (!registry) return; - if (auto* s = registry->try_get((entt::entity)entity)) { - s->outlineSize = outlineSize; + if (auto* renderer = registry->try_get((entt::entity)entity)) { + renderer->outlineSize = outlineSize; } } -void AS_SetSpriteShader(uint32_t entity, unsigned int shaderId) { +void AS_SetModelRendererShader(uint32_t entity, unsigned int shaderId) { if (!registry) return; - if (auto* s = registry->try_get((entt::entity)entity)) { - s->shaderId = shaderId; + if (auto* renderer = registry->try_get((entt::entity)entity)) { + renderer->shaderId = shaderId; } } -bool AS_HasSprite(uint32_t entity) { +bool AS_HasModelRenderer(uint32_t entity) { if (!registry) return false; - return registry->all_of((entt::entity)entity); + return registry->all_of((entt::entity)entity); } -void AS_RemoveSprite(uint32_t entity) { +void AS_RemoveModelRenderer(uint32_t entity) { if (!registry) return; - registry->remove((entt::entity)entity); + registry->remove((entt::entity)entity); } // === Texture Component === @@ -568,33 +568,33 @@ void RegisterECSBindings(asIScriptEngine *engine) { asFUNCTION(AS_RemoveVelocity), asCALL_CDECL); assert(r >= 0); - // Sprite component - r = engine->RegisterGlobalFunction("void AddSprite(uint, int, uint, float = 0.0f)", - asFUNCTION(AS_AddSprite), asCALL_CDECL); + // ModelRenderer component + r = engine->RegisterGlobalFunction("void AddModelRenderer(uint, int, uint, float = 0.0f)", + asFUNCTION(AS_AddModelRenderer), asCALL_CDECL); assert(r >= 0); - r = engine->RegisterGlobalFunction("void SetSpriteColor(uint, uint)", - asFUNCTION(AS_SetSpriteColor), asCALL_CDECL); + r = engine->RegisterGlobalFunction("void SetModelRendererColor(uint, uint)", + asFUNCTION(AS_SetModelRendererColor), asCALL_CDECL); assert(r >= 0); - r = engine->RegisterGlobalFunction("void SetSpriteModel(uint, int)", - asFUNCTION(AS_SetSpriteModel), asCALL_CDECL); + r = engine->RegisterGlobalFunction("void SetModelRendererModel(uint, int)", + asFUNCTION(AS_SetModelRendererModel), asCALL_CDECL); assert(r >= 0); - r = engine->RegisterGlobalFunction("void SetSpriteOutline(uint, float)", - asFUNCTION(AS_SetSpriteOutline), asCALL_CDECL); + r = engine->RegisterGlobalFunction("void SetModelRendererOutline(uint, float)", + asFUNCTION(AS_SetModelRendererOutline), asCALL_CDECL); assert(r >= 0); - r = engine->RegisterGlobalFunction("void SetSpriteShader(uint, uint)", - asFUNCTION(AS_SetSpriteShader), asCALL_CDECL); + r = engine->RegisterGlobalFunction("void SetModelRendererShader(uint, uint)", + asFUNCTION(AS_SetModelRendererShader), asCALL_CDECL); assert(r >= 0); - r = engine->RegisterGlobalFunction("bool HasSprite(uint)", - asFUNCTION(AS_HasSprite), asCALL_CDECL); + r = engine->RegisterGlobalFunction("bool HasModelRenderer(uint)", + asFUNCTION(AS_HasModelRenderer), asCALL_CDECL); assert(r >= 0); - r = engine->RegisterGlobalFunction("void RemoveSprite(uint)", - asFUNCTION(AS_RemoveSprite), asCALL_CDECL); + r = engine->RegisterGlobalFunction("void RemoveModelRenderer(uint)", + asFUNCTION(AS_RemoveModelRenderer), asCALL_CDECL); assert(r >= 0); // Texture component diff --git a/tests/scenegraph_tests.cpp b/tests/scenegraph_tests.cpp index 9b6dc0a..5cc09c7 100644 --- a/tests/scenegraph_tests.cpp +++ b/tests/scenegraph_tests.cpp @@ -164,8 +164,8 @@ void test_scene_loader_basic(void) { if (childHierarchy) { TEST_CHECK(childHierarchy->parent == parentEntity); } - TEST_CHECK(registry.all_of(parentEntity)); - TEST_CHECK(registry.all_of(childEntity)); + TEST_CHECK(registry.all_of(parentEntity)); + TEST_CHECK(registry.all_of(childEntity)); } std::filesystem::remove(scenePath); From eb155da5d895942187eb09d6876f918bcd893eb1 Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Tue, 10 Mar 2026 20:48:33 +1300 Subject: [PATCH 50/53] chore: fix for tests --- src/SceneGraph.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SceneGraph.cpp b/src/SceneGraph.cpp index 4feae8f..7b80929 100644 --- a/src/SceneGraph.cpp +++ b/src/SceneGraph.cpp @@ -7,7 +7,7 @@ static Matrix BuildLocalMatrix(const ECSTransform& local) { Matrix scale = MatrixScale(local.scale.x, local.scale.y, local.scale.z); Matrix rotation = MatrixRotateXYZ(local.rotation); Matrix translation = MatrixTranslate(local.position.x, local.position.y, local.position.z); - return MatrixMultiply(MatrixMultiply(scale, rotation), translation); + return MatrixMultiply(MatrixMultiply(translation, rotation), scale); } static Vector3 ExtractScale(const Matrix& matrix) { From 5f031b80c29997ca6f84c8e9ceb1365e792b4c85 Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Tue, 10 Mar 2026 21:20:30 +1300 Subject: [PATCH 51/53] chore: more tests --- tests/CMakeLists.txt | 2 + tests/resource_tests.cpp | 42 +++++++++++++++++++++ tests/resource_tests.h | 1 + tests/scenegraph_tests.cpp | 75 ++++++++++++++++++++++++++++++++++++++ tests/scenegraph_tests.h | 1 + tests/test.cpp | 2 + 6 files changed, 123 insertions(+) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index a24f48f..1b83cdc 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -32,7 +32,9 @@ add_test(NAME math_bindings COMMAND unit_tests math_bindings) add_test(NAME shader_manager COMMAND unit_tests shader_manager) add_test(NAME model_manager COMMAND unit_tests model_manager) add_test(NAME material_manager COMMAND unit_tests material_manager) +add_test(NAME asset_registry_material COMMAND unit_tests asset_registry_material) add_test(NAME resource_bindings COMMAND unit_tests resource_bindings) add_test(NAME scenegraph_world COMMAND unit_tests scenegraph_world) add_test(NAME scenegraph_detach COMMAND unit_tests scenegraph_detach) add_test(NAME scene_loader COMMAND unit_tests scene_loader) +add_test(NAME scene_loader_assets COMMAND unit_tests scene_loader_assets) diff --git a/tests/resource_tests.cpp b/tests/resource_tests.cpp index 3b00d2c..381ac9a 100644 --- a/tests/resource_tests.cpp +++ b/tests/resource_tests.cpp @@ -7,6 +7,7 @@ #include "../include/ModelManager.h" #include "../include/MaterialManager.h" #include "../include/TextureManager.h" +#include "../include/AssetManager.h" #include "../include/scripting/ScriptEngine.h" #include "../include/scripting/ResourceBindings.h" #include "raylib.h" @@ -232,3 +233,44 @@ void test_resource_bindings_script(void) { ShutdownRaylibHidden(); } + +void test_asset_registry_material(void) { + std::filesystem::path tmpDir = std::filesystem::current_path() / "tmp_asset_registry"; + std::filesystem::create_directories(tmpDir); + std::filesystem::path registryPath = tmpDir / "registry.toml"; + + MaterialManager materialManager; + AssetManager assets; + assets.SetManagers(nullptr, nullptr, &materialManager, nullptr); + + Color albedo = {10, 20, 30, 40}; + unsigned int materialId = assets.CreateMaterial("test_mat", 0, albedo); + TEST_CHECK(materialId != 0); + + bool saved = assets.SaveRegistry(registryPath.string()); + TEST_CHECK(saved == true); + + assets.Clear(); + materialManager.Clear(); + + MaterialManager materialManagerReload; + AssetManager assetsReload; + assetsReload.SetManagers(nullptr, nullptr, &materialManagerReload, nullptr); + + bool loaded = assetsReload.LoadRegistry(registryPath.string()); + TEST_CHECK(loaded == true); + + unsigned int loadedId = assetsReload.GetMaterialId("test_mat"); + TEST_CHECK(loadedId != 0); + MaterialData* data = materialManagerReload.Get(loadedId); + TEST_CHECK(data != nullptr); + if (data) { + TEST_CHECK(data->albedo.r == 10); + TEST_CHECK(data->albedo.g == 20); + TEST_CHECK(data->albedo.b == 30); + TEST_CHECK(data->albedo.a == 40); + } + + std::filesystem::remove(registryPath); + std::filesystem::remove(tmpDir); +} diff --git a/tests/resource_tests.h b/tests/resource_tests.h index bc35f2d..f2f9ed4 100644 --- a/tests/resource_tests.h +++ b/tests/resource_tests.h @@ -4,3 +4,4 @@ void test_shader_manager(void); void test_model_manager(void); void test_material_manager(void); void test_resource_bindings_script(void); +void test_asset_registry_material(void); diff --git a/tests/scenegraph_tests.cpp b/tests/scenegraph_tests.cpp index 5cc09c7..7a79974 100644 --- a/tests/scenegraph_tests.cpp +++ b/tests/scenegraph_tests.cpp @@ -9,6 +9,7 @@ #include "../include/ModelManager.h" #include "../include/ShaderManager.h" #include "../include/TextureManager.h" +#include "../include/AssetManager.h" #include "raylib.h" #include "entt.hpp" @@ -173,3 +174,77 @@ void test_scene_loader_basic(void) { ShutdownRaylibHidden(); } + +void test_scene_loader_asset_keys(void) { + if (!InitRaylibHidden()) { + TEST_SKIP("No display available for raylib"); + return; + } + + std::filesystem::path tmpDir = std::filesystem::current_path() / "tmp_scene_assets"; + std::filesystem::create_directories(tmpDir); + std::filesystem::path registryPath = tmpDir / "registry.toml"; + std::filesystem::path scenePath = tmpDir / "scene_asset.toml"; + + { + ModelManager modelManager; + ShaderManager shaderManager; + TextureManager textureManager; + AssetManager assets; + assets.SetManagers(&modelManager, &shaderManager, nullptr, &textureManager); + assets.LoadCube("demo_cube", 1.0f, 1.0f, 1.0f); + assets.SaveRegistry(registryPath.string()); + } + + entt::registry registry; + ModelManager modelManager; + ShaderManager shaderManager; + TextureManager textureManager; + AssetManager assets; + assets.SetManagers(&modelManager, &shaderManager, nullptr, &textureManager); + assets.LoadRegistry(registryPath.string()); + + SetSceneContext(®istry, &modelManager, &shaderManager, &textureManager); + SetSceneAssetManager(&assets); + + { + std::ofstream scene(scenePath); + scene << "[[entity]]\n"; + scene << "id = \"root\"\n"; + scene << "tag = \"Root\"\n"; + scene << "position = [0.0, 0.0, 0.0]\n"; + scene << "model_asset = \"demo_cube\"\n"; + scene << "color = 0xFFFFFFFF\n"; + scene << "\n"; + } + + entt::entity root = LoadSceneFromFile(scenePath.string(), true); + TEST_CHECK(root != entt::null); + + auto tagView = registry.view(); + entt::entity rootEntity = entt::null; + for (auto entity : tagView) { + const auto& tag = tagView.get(entity); + if (tag.name == "Root") { + rootEntity = entity; + break; + } + } + + TEST_CHECK(rootEntity != entt::null); + if (rootEntity != entt::null) { + auto* renderer = registry.try_get(rootEntity); + TEST_CHECK(renderer != nullptr); + if (renderer) { + unsigned int expectedId = assets.GetModelId("demo_cube"); + TEST_CHECK(expectedId != 0); + TEST_CHECK(renderer->modelId == expectedId); + } + } + + std::filesystem::remove(scenePath); + std::filesystem::remove(registryPath); + std::filesystem::remove(tmpDir); + + ShutdownRaylibHidden(); +} diff --git a/tests/scenegraph_tests.h b/tests/scenegraph_tests.h index d364ab0..a8c5958 100644 --- a/tests/scenegraph_tests.h +++ b/tests/scenegraph_tests.h @@ -3,3 +3,4 @@ void test_scenegraph_world_transform(void); void test_scenegraph_detach(void); void test_scene_loader_basic(void); +void test_scene_loader_asset_keys(void); diff --git a/tests/test.cpp b/tests/test.cpp index 1cd79bd..1c6a563 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -12,9 +12,11 @@ TEST_LIST = { { "shader_manager", test_shader_manager }, { "model_manager", test_model_manager }, { "material_manager", test_material_manager }, + { "asset_registry_material", test_asset_registry_material }, { "resource_bindings", test_resource_bindings_script }, { "scenegraph_world", test_scenegraph_world_transform }, { "scenegraph_detach", test_scenegraph_detach }, { "scene_loader", test_scene_loader_basic }, + { "scene_loader_assets", test_scene_loader_asset_keys }, { NULL, NULL } }; From 8c2ce637a2b6d1bfd8e3a933c577f484e899b16b Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Wed, 11 Mar 2026 15:58:51 +1300 Subject: [PATCH 52/53] feat: autoload script --- CMakeLists.txt | 3 + assets/registry.toml | 12 ++-- imgui.ini | 38 +++++------ include/Application.h | 5 +- include/InputManager.h | 1 + include/scripting/ScriptEngine.h | 1 + scenes/demo.toml | 15 ++--- scenes/demo2.toml | 32 ++++++---- scripts/as.predefined | 1 + scripts/autoload.as | 40 ++++++++++++ scripts/game.as | 66 +------------------ src/Application.cpp | 100 +++++++++++++++++------------ src/InputManager.cpp | 4 ++ src/SceneLoader.cpp | 1 + src/gui/GuiManager.cpp | 105 +++++++++++++++++++++++++------ src/scripting/InputBindings.cpp | 8 +++ src/scripting/ScriptEngine.cpp | 28 +++++++++ tests/scenegraph_tests.cpp | 65 +++++++++++++++++++ 18 files changed, 356 insertions(+), 169 deletions(-) create mode 100644 scripts/autoload.as diff --git a/CMakeLists.txt b/CMakeLists.txt index 4ef239c..4be7d2a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -161,6 +161,9 @@ if(MSVC) target_compile_options(simian_core PRIVATE /W4 /EHsc) else() target_compile_options(simian_core PRIVATE -Wall -Wextra -pedantic) + if(TARGET raylib) + target_compile_options(raylib PRIVATE -Wno-missing-field-initializers) + endif() endif() # ------------------------- diff --git a/assets/registry.toml b/assets/registry.toml index 0d52586..70b2f7d 100644 --- a/assets/registry.toml +++ b/assets/registry.toml @@ -1,15 +1,15 @@ # Simian asset registry # Auto-generated - edits may be overwritten -[[model]] -key = "Torus" -type = "primitive" -primitive = "torus" -params = [0.5, 1, 16, 8] - [[model]] key = "demo_cube" type = "primitive" primitive = "cube" params = [1, 1, 1] +[[model]] +key = "Torus" +type = "primitive" +primitive = "torus" +params = [0.5, 1, 16, 8] + diff --git a/imgui.ini b/imgui.ini index 2b194ed..74bdeae 100644 --- a/imgui.ini +++ b/imgui.ini @@ -10,39 +10,39 @@ Collapsed=0 [Window][Game Window] Pos=232,28 -Size=663,408 +Size=663,507 Collapsed=0 DockId=0x00000004,0 [Window][Log Viewer] -Pos=8,438 -Size=1264,274 +Pos=8,537 +Size=1264,175 Collapsed=0 DockId=0x00000002,0 [Window][##TOAST0] -Pos=1060,637 -Size=200,63 +Pos=1035,637 +Size=225,63 Collapsed=0 [Window][##TOAST1] -Pos=1060,564 -Size=200,63 +Pos=1035,564 +Size=225,63 Collapsed=0 [Window][##TOAST2] -Pos=1060,491 -Size=200,63 +Pos=1035,491 +Size=225,63 Collapsed=0 [Window][##TOAST3] -Pos=1060,418 -Size=200,63 +Pos=1675,741 +Size=225,63 Collapsed=0 [Window][##TOAST4] -Pos=1064,345 -Size=196,63 +Pos=1068,345 +Size=192,63 Collapsed=0 [Window][Scene (0 entities)] @@ -77,13 +77,13 @@ Collapsed=0 [Window][Inspector] Pos=897,28 -Size=375,408 +Size=375,507 Collapsed=0 DockId=0x00000006,0 [Window][Scene] Pos=8,28 -Size=222,408 +Size=222,507 Collapsed=0 DockId=0x00000003,0 @@ -103,17 +103,17 @@ Size=306,82 Collapsed=0 [Window][Assets] -Pos=8,438 -Size=1264,274 +Pos=8,761 +Size=1904,274 Collapsed=0 DockId=0x00000002,1 [Docking][Data] DockSpace ID=0x9076BACA Window=0x34F970D7 Pos=8,28 Size=1264,684 Split=Y Selected=0x27A02DAA - DockNode ID=0x00000001 Parent=0x9076BACA SizeRef=1264,679 Split=X + DockNode ID=0x00000001 Parent=0x9076BACA SizeRef=1264,507 Split=X DockNode ID=0x00000005 Parent=0x00000001 SizeRef=887,684 Split=X DockNode ID=0x00000003 Parent=0x00000005 SizeRef=222,684 Selected=0xE601B12F DockNode ID=0x00000004 Parent=0x00000005 SizeRef=663,684 CentralNode=1 Selected=0x27A02DAA DockNode ID=0x00000006 Parent=0x00000001 SizeRef=375,684 Selected=0x36DC96AB - DockNode ID=0x00000002 Parent=0x9076BACA SizeRef=1264,274 Selected=0xBEDDA0C1 + DockNode ID=0x00000002 Parent=0x9076BACA SizeRef=1264,175 Selected=0xBEDDA0C1 diff --git a/include/Application.h b/include/Application.h index ecec93f..7759310 100644 --- a/include/Application.h +++ b/include/Application.h @@ -27,6 +27,7 @@ public: bool HasScriptCompilationError() const { return scriptCompilationError; } entt::registry& GetRegistry() { return registry; } AssetManager& GetAssetManager() { return assetManager; } + InputManager& GetInputManager() { return inputManager; } Camera3D& GetEditorCamera() { return editorCamera; } bool IsUsingEditorCamera() const { return useEditorCamera; } void SetUseEditorCamera(bool enabled) { useEditorCamera = enabled; } @@ -87,13 +88,12 @@ private: static const int WINDOW_HEIGHT = 720; static const int TARGET_FPS = 60; static const char* WINDOW_TITLE; - static const char* SCRIPT_FILE; void Update(float deltaTime); void UpdateSystems(float deltaTime); void UpdateEntityScripts(float deltaTime); void ShutdownEntityScripts(); - void ProcessSceneScriptChanges(); + bool ProcessSceneScriptChanges(); void ReloadEntityScriptModules(); EntityScriptModule* GetEntityScriptModule(const std::string& path); void InitializeSceneScriptInstance(); @@ -101,4 +101,5 @@ private: void CallSceneUpdate(float deltaTime); void RenderScene(); void Draw(); + bool RunAutoloadScript(bool abortOnFailure); }; \ No newline at end of file diff --git a/include/InputManager.h b/include/InputManager.h index 012025b..0b555d7 100644 --- a/include/InputManager.h +++ b/include/InputManager.h @@ -52,6 +52,7 @@ public: void BindGamepadButton(const std::string& actionName, int gamepadId, int button); void BindGamepadAxis(const std::string& actionName, int gamepadId, int axis, float threshold, bool negative = false); void ClearBindings(const std::string& actionName); + void ClearAllActions(); // Input queries (called per frame) bool IsActionPressed(const std::string& actionName) const; diff --git a/include/scripting/ScriptEngine.h b/include/scripting/ScriptEngine.h index 76cb787..dead221 100644 --- a/include/scripting/ScriptEngine.h +++ b/include/scripting/ScriptEngine.h @@ -13,6 +13,7 @@ public: void Shutdown(); bool CompileScript(const std::string& filename); bool CompileModule(const std::string& moduleName, const std::string& filename, asIScriptModule** outModule); + bool CallModuleFunction(asIScriptModule* module, const std::string& decl); void CallScriptFunction(asIScriptFunction* func, float dt = 0.0f); void CallScriptFunction(asIScriptFunction* func, unsigned int entityId, float dt); void GarbageCollect(); diff --git a/scenes/demo.toml b/scenes/demo.toml index 621380c..b8601dc 100644 --- a/scenes/demo.toml +++ b/scenes/demo.toml @@ -11,7 +11,7 @@ rotation_deg = [0.000, 0.000, 0.000] id = "entity_2" parent = "entity_1" tag = "Parent" -position = [2.000, -6.197, 0.000] +position = [2.000, -1.555, 0.000] scale = [1.000, 1.000, 1.000] rotation_deg = [0.000, 0.000, 0.000] model_asset = "Torus" @@ -21,14 +21,15 @@ outline_size = 0.000 shader_vs = "shaders/toon.vs" shader_fs = "shaders/toon.fs" script = "scripts/ball.as" -script_var_amplitude = "7.293000" -script_var_speed = "0.219000" +script_var_phase = "0.000000" +script_var_speed = "0.699000" +script_var_amplitude = "1.748000" [[entity]] id = "entity_3" parent = "entity_2" tag = "Child" -position = [0.500, -1.434, 1.600] +position = [0.500, -3.100, 1.600] scale = [0.600, 0.600, 0.600] rotation_deg = [0.000, 0.000, 0.000] model = "sphere" @@ -46,7 +47,7 @@ script_var_amplitude = "1.452000" id = "entity_6" parent = "entity_2" tag = "Child 2" -position = [0.000, 0.848, 1.900] +position = [0.000, 0.351, 1.900] scale = [1.000, 1.000, 1.000] rotation_deg = [0.000, 0.000, 0.000] model = "sphere" @@ -58,7 +59,7 @@ outline_size = 0.000 shader_vs = "shaders/toon.vs" shader_fs = "shaders/toon.fs" script = "scripts/ball.as" -script_var_speed = "10.000000" -script_var_phase = "0.472000" script_var_amplitude = "0.568000" +script_var_phase = "0.472000" +script_var_speed = "10.000000" diff --git a/scenes/demo2.toml b/scenes/demo2.toml index e0c4282..bf80381 100644 --- a/scenes/demo2.toml +++ b/scenes/demo2.toml @@ -1,23 +1,33 @@ +scene_script = "scripts/demo_scene.as" + +[[entity]] +id = "entity_1048581" +tag = "Light" +position = [0.000, 0.000, 0.000] +scale = [1.000, 1.000, 1.000] +rotation_deg = [0.000, 0.000, 0.000] + [[entity]] id = "entity_1048576" tag = "Camera" position = [0.000, 0.000, 0.000] scale = [1.000, 1.000, 1.000] -rotation_deg = 0.000 +rotation_deg = [0.000, 0.000, 0.000] [[entity]] id = "entity_1048578" tag = "Root" position = [0.000, 0.000, 0.000] scale = [1.000, 1.000, 1.000] -rotation_deg = 0.000 +rotation_deg = [0.000, 0.000, 0.000] [[entity]] id = "entity_1048579" tag = "Parent" position = [0.000, 0.000, 0.000] scale = [1.000, 1.000, 1.000] -rotation_deg = 0.000 +rotation_deg = [0.000, 0.000, 0.000] +model_asset = "Torus" model_id = 1 color = 0xFFFFFFFF outline_size = 0.000 @@ -28,16 +38,12 @@ parent = "entity_1048579" tag = "Child" position = [0.000, 1.400, 0.000] scale = [1.000, 1.000, 1.000] -rotation_deg = 0.000 -model_id = 2 +rotation_deg = [0.000, 0.000, 0.000] +model_asset = "demo_cube" +model = "cube" +model_size = [1.000, 1.000, 1.000] color = 0xC11E1EFF outline_size = 0.000 -shader_id = 1 - -[[entity]] -id = "entity_1048581" -tag = "Light" -position = [0.000, 0.000, 0.000] -scale = [1.000, 1.000, 1.000] -rotation_deg = 0.000 +shader_vs = "shaders/toon.vs" +shader_fs = "shaders/toon.fs" diff --git a/scripts/as.predefined b/scripts/as.predefined index af7f20d..9c6d912 100644 --- a/scripts/as.predefined +++ b/scripts/as.predefined @@ -237,6 +237,7 @@ void BindMouseButton(const string &in actionName, int mouseButton); void BindGamepadButton(const string &in actionName, int gamepadId, int button); void BindGamepadAxis(const string &in actionName, int gamepadId, int axis, float threshold = 0.5f, bool negative = false); void ClearBindings(const string &in actionName); +void ClearAllActions(); namespace Key { const int SPACE = 32; diff --git a/scripts/autoload.as b/scripts/autoload.as new file mode 100644 index 0000000..7c5cb34 --- /dev/null +++ b/scripts/autoload.as @@ -0,0 +1,40 @@ +// Autoload configuration script. +// Runs before any scene/game script to configure input and preload resources. + +void Autoload() { + // Pick the initial scene to load. + Scene::Load("scenes/demo.toml"); + + ClearAllActions(); + + // Movement + RegisterAction("move_up"); + RegisterAction("move_down"); + RegisterAction("move_left"); + RegisterAction("move_right"); + BindKeyboard("move_up", Key::W); + BindKeyboard("move_up", Key::UP); + BindKeyboard("move_down", Key::S); + BindKeyboard("move_down", Key::DOWN); + BindKeyboard("move_left", Key::A); + BindKeyboard("move_left", Key::LEFT); + BindKeyboard("move_right", Key::D); + BindKeyboard("move_right", Key::RIGHT); + + // Actions + RegisterAction("jump"); + RegisterAction("interact"); + RegisterAction("attack"); + BindKeyboard("jump", Key::SPACE); + BindKeyboard("interact", Key::E); + BindKeyboard("attack", Key::LEFT_CONTROL); + BindMouseButton("attack", MouseButton::LEFT); + + // Gamepad (optional) + BindGamepadButton("jump", 0, GamepadButton::RIGHT_FACE_DOWN); + BindGamepadButton("interact", 0, GamepadButton::RIGHT_FACE_RIGHT); + BindGamepadAxis("move_left", 0, GamepadAxis::LEFT_X, 0.3f, true); + BindGamepadAxis("move_right", 0, GamepadAxis::LEFT_X, 0.3f, false); + + // TODO: Preload assets and other config here. +} diff --git a/scripts/game.as b/scripts/game.as index cc6f974..374ac4f 100644 --- a/scripts/game.as +++ b/scripts/game.as @@ -1,67 +1,7 @@ -// ECS scenegraph demo -// Loads a scene from TOML and animates the hierarchy - +// Empty scene script to avoid auto-loading demo content. class SceneScript { - uint sceneRoot = 0; - uint camera = 0; - uint light = 0; - float time = 0.0f; - bool lightToggle = false; - - void Init() { - Log(LOG_TRACE, "Initialization complete - Scenegraph demo!"); - Toast::Success("Scenegraph demo initialized."); - - sceneRoot = Scene::Load("scenes/demo.toml"); - if (!ECS::IsValid(sceneRoot)) { - Toast::Error("Failed to load scene"); - } - - // === Set up camera === - camera = ECS::CreateEntity(); - ECS::AddCamera3D(camera, - 5.0, 5.0, 5.0, // position - 0.0, 0.0, 0.0, // target - 45.0); // fovy - ECS::AddTag(camera, "MainCamera"); - - // === Set up light === - light = ECS::CreateEntity(); - ECS::AddLight(light, 0.5, 0.7, 0.3, 1.0); // direction + intensity - ECS::AddTag(light, "MainLight"); - } - - void Shutdown() { - Log(LOG_TRACE, "Shutdown complete!"); - } - + void Init() {} + void Shutdown() {} void Update(float dt) { - time += dt; - - // Rotate the scene root to show parent/child propagation - if (ECS::IsValid(sceneRoot) && ECS::HasTransform(sceneRoot)) { - ECS::SetRotation(sceneRoot, time * 0.5f); - } - - // Orbit the camera around the scene - if (ECS::HasCamera3D(camera)) { - float angle = time * 0.3f; - float radius = 7.0f; - float x = Math::Cos(angle) * radius; - float z = Math::Sin(angle) * radius; - ECS::SetCameraPosition(camera, x, 5.0f, z); - } - - // Toggle light with jump action - if (IsActionPressed("jump")) { - lightToggle = !lightToggle; - if (lightToggle) { - ECS::SetLightDirection(light, -0.5, 0.7, -0.3); - Toast::Info("Light direction changed!"); - } else { - ECS::SetLightDirection(light, 0.5, 0.7, 0.3); - Toast::Info("Light direction reset!"); - } - } } } diff --git a/src/Application.cpp b/src/Application.cpp index 21f9612..fbc4aac 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -27,7 +27,7 @@ #endif const char *Application::WINDOW_TITLE = "Simian"; -const char *Application::SCRIPT_FILE = "scripts/game.as"; +static const char* kAutoloadScriptFile = "scripts/autoload.as"; static const char* kAssetRegistryFile = "assets/registry.toml"; Application::Application() @@ -101,23 +101,24 @@ bool Application::Initialize(int argc, char *argv[]) extern void SetGlobalInputManager(InputManager*); SetGlobalInputManager(&inputManager); - // Setup default input bindings - inputManager.SetupDefaultBindings(); + currentSceneScriptPath.clear(); + + if (!RunAutoloadScript(true)) + { + log_error("Autoload script failed - aborting startup"); + return false; + } // Initialize hot reload to watch the scripts directory so any script change // triggers a reload. { - std::filesystem::path p(SCRIPT_FILE); + std::filesystem::path p(kAutoloadScriptFile); std::string watchPath = p.parent_path().string(); if (watchPath.empty()) watchPath = "."; hotReload = new HotReload(watchPath); } - // Compile initial script - scriptCompilationError = !scriptEngine.CompileScript(SCRIPT_FILE); - currentSceneScriptPath = SCRIPT_FILE; - if (enableEditor) { guiManager.Initialize(this); @@ -135,7 +136,7 @@ bool Application::Initialize(int argc, char *argv[]) void Application::Run() { - InitializeSceneScriptInstance(); + ProcessSceneScriptChanges(); while (!WindowShouldClose() && !queueShutdown) { float deltaTime = GetFrameTime(); @@ -156,18 +157,25 @@ void Application::Update(float deltaTime) if (hotReload) { bool changed = hotReload->CheckForChanges(); if (changed) { - bool success = scriptEngine.CompileScript(currentSceneScriptPath); - scriptCompilationError = !success; - if (!success) - { - log_warn("Script compilation failed - keeping previous version"); - Toast::Warning("Script compilation failed - check console for details."); + if (!RunAutoloadScript(false)) { + log_warn("Autoload script failed during reload - keeping previous config"); } - else - { - Toast::Success("Script reloaded successfully."); - // Should call init function again or things don't work - InitializeSceneScriptInstance(); + + bool scriptChanged = ProcessSceneScriptChanges(); + if (!scriptChanged && !currentSceneScriptPath.empty()) { + bool success = scriptEngine.CompileScript(currentSceneScriptPath); + scriptCompilationError = !success; + if (!success) + { + log_warn("Script compilation failed - keeping previous version"); + Toast::Warning("Script compilation failed - check console for details."); + } + else + { + Toast::Success("Script reloaded successfully."); + // Should call init function again or things don't work + InitializeSceneScriptInstance(); + } } // Refresh any entity script modules so class-based entity scripts @@ -185,6 +193,22 @@ void Application::Update(float deltaTime) UpdateSystems(deltaTime); } +bool Application::RunAutoloadScript(bool abortOnFailure) +{ + asIScriptModule* module = nullptr; + if (!scriptEngine.CompileModule("autoload", kAutoloadScriptFile, &module) || !module) { + log_error("Failed to compile autoload script: %s", kAutoloadScriptFile); + return !abortOnFailure; + } + + if (!scriptEngine.CallModuleFunction(module, "void Autoload()")) { + log_error("Failed to execute autoload script: %s", kAutoloadScriptFile); + return !abortOnFailure; + } + + return true; +} + void Application::UpdateSystems(float deltaTime) { // Movement system - apply velocity to transform @@ -560,39 +584,37 @@ void Application::CallSceneUpdate(float deltaTime) scriptEngine.CallScriptFunction(scriptEngine.GetUpdateFunction(), deltaTime); } -void Application::ProcessSceneScriptChanges() +bool Application::ProcessSceneScriptChanges() { std::string sceneScriptPath; if (!ConsumeSceneScriptPath(sceneScriptPath)) { - return; + return false; } - if (sceneScriptPath.empty() || sceneScriptPath == currentSceneScriptPath) { - return; + if (sceneScriptPath.empty()) { + if (!currentSceneScriptPath.empty()) { + currentSceneScriptPath.clear(); + ShutdownSceneScriptInstance(); + scriptCompilationError = false; + } + return true; } - currentSceneScriptPath = sceneScriptPath; - bool success = scriptEngine.CompileScript(currentSceneScriptPath); + if (sceneScriptPath == currentSceneScriptPath) { + return false; + } + + bool success = scriptEngine.CompileScript(sceneScriptPath); scriptCompilationError = !success; if (!success) { log_warn("Scene script compilation failed - keeping previous version"); Toast::Warning("Scene script compilation failed - check console for details."); - return; + return true; } - if (hotReload) { - delete hotReload; - hotReload = nullptr; - } - - std::filesystem::path p(currentSceneScriptPath); - std::string watchPath = p.parent_path().string(); - if (watchPath.empty()) { - watchPath = "."; - } - hotReload = new HotReload(watchPath); - + currentSceneScriptPath = sceneScriptPath; InitializeSceneScriptInstance(); + return true; } void Application::ReloadEntityScriptModules() diff --git a/src/InputManager.cpp b/src/InputManager.cpp index 16d9a1b..e6c94b1 100644 --- a/src/InputManager.cpp +++ b/src/InputManager.cpp @@ -55,6 +55,10 @@ void InputManager::ClearBindings(const std::string& actionName) { } } +void InputManager::ClearAllActions() { + actions.clear(); +} + bool InputManager::IsActionPressed(const std::string& actionName) const { auto it = actions.find(actionName); if (it == actions.end()) return false; diff --git a/src/SceneLoader.cpp b/src/SceneLoader.cpp index 9d5967b..f74ad27 100644 --- a/src/SceneLoader.cpp +++ b/src/SceneLoader.cpp @@ -429,6 +429,7 @@ entt::entity LoadSceneFromFile(const std::string& path, bool clearExisting) { if (clearExisting) { g_sceneRegistry->clear(); + SetSceneScriptPath(std::string()); } std::ifstream file(path); diff --git a/src/gui/GuiManager.cpp b/src/gui/GuiManager.cpp index a0639e2..f4e50a5 100644 --- a/src/gui/GuiManager.cpp +++ b/src/gui/GuiManager.cpp @@ -1,5 +1,6 @@ #include "gui/GuiManager.h" #include "raylib.h" +#include "raymath.h" #include // Add this to fix the incomplete type error #include #include @@ -299,7 +300,16 @@ void GuiManager::SetupDockspace(RenderTexture2D &renderTexture) Camera3D& editorCamera = app->GetEditorCamera(); Vector3 camPos = editorCamera.position; Vector3 pivot = editorCameraPivot; - if (selectedEntity != entt::null) { + const bool viewportHovered = ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem); + const bool flyActive = viewportHovered && IsMouseButtonDown(MOUSE_BUTTON_RIGHT); + + if (flyActive) { + editorPivotEntity = entt::null; + editorPivotOffset = {0.0f, 0.0f, 0.0f}; + editorCameraPivot = editorCamera.target; + editorPivotInitialized = true; + pivot = editorCamera.target; + } else if (selectedEntity != entt::null) { auto& registry = app->GetRegistry(); Vector3 entityPos = {0.0f, 0.0f, 0.0f}; if (auto* worldTransform = registry.try_get(selectedEntity)) { @@ -333,6 +343,59 @@ void GuiManager::SetupDockspace(RenderTexture2D &renderTexture) Quaternion camRot = ImViewGuizmo::GizmoMath::quatLookAt(direction, editorCamera.up); + if (flyActive) { + Vector2 mouseDelta = GetMouseDelta(); + float yaw = std::atan2(direction.x, direction.z); + float pitch = std::asin(direction.y); + const float lookSensitivity = 0.003f; + + yaw -= mouseDelta.x * lookSensitivity; + pitch -= mouseDelta.y * lookSensitivity; + + const float maxPitch = 1.55f; + if (pitch > maxPitch) pitch = maxPitch; + if (pitch < -maxPitch) pitch = -maxPitch; + + Vector3 forward = { + std::sin(yaw) * std::cos(pitch), + std::sin(pitch), + std::cos(yaw) * std::cos(pitch) + }; + + Vector3 right = Vector3Normalize(Vector3CrossProduct(forward, editorCamera.up)); + Vector3 up = Vector3Normalize(Vector3CrossProduct(right, forward)); + + InputManager& input = app->GetInputManager(); + Vector3 move = {0.0f, 0.0f, 0.0f}; + if (input.IsActionDown("move_up")) { + move = Vector3Add(move, forward); + } + if (input.IsActionDown("move_down")) { + move = Vector3Subtract(move, forward); + } + if (input.IsActionDown("move_left")) { + move = Vector3Subtract(move, right); + } + if (input.IsActionDown("move_right")) { + move = Vector3Add(move, right); + } + + const float baseSpeed = 6.0f; + float speed = baseSpeed; + if (IsKeyDown(KEY_LEFT_SHIFT) || IsKeyDown(KEY_RIGHT_SHIFT)) { + speed *= 3.0f; + } + + if (Vector3Length(move) > 0.0001f) { + move = Vector3Scale(Vector3Normalize(move), speed * GetFrameTime()); + editorCamera.position = Vector3Add(editorCamera.position, move); + } + + editorCamera.target = Vector3Add(editorCamera.position, forward); + editorCamera.up = up; + editorCameraPivot = editorCamera.target; + } + const float baseGizmoSize = 256.0f; const float marginX = 6.0f; const float marginY = 75.0f; @@ -358,27 +421,29 @@ void GuiManager::SetupDockspace(RenderTexture2D &renderTexture) ImVec2 dollyPos = {gizmoPos.x, gizmoPos.y + gizmoSize + 12.0f}; ImVec2 panPos = {gizmoPos.x + 60.0f, gizmoPos.y + gizmoSize + 12.0f}; - bool cameraChanged = false; - cameraChanged |= ImViewGuizmo::Rotate(camPos, camRot, pivot, gizmoPos); - cameraChanged |= ImViewGuizmo::Dolly(camPos, camRot, dollyPos); - Vector3 panStartPos = camPos; - bool panChanged = ImViewGuizmo::Pan(camPos, camRot, panPos); - cameraChanged |= panChanged; - if (panChanged) { - Vector3 delta = Vector3Subtract(camPos, panStartPos); - pivot = Vector3Add(pivot, delta); - if (selectedEntity != entt::null) { - editorPivotOffset = Vector3Add(editorPivotOffset, delta); - } else { - editorCameraPivot = pivot; + if (!flyActive) { + bool cameraChanged = false; + cameraChanged |= ImViewGuizmo::Rotate(camPos, camRot, pivot, gizmoPos); + cameraChanged |= ImViewGuizmo::Dolly(camPos, camRot, dollyPos); + Vector3 panStartPos = camPos; + bool panChanged = ImViewGuizmo::Pan(camPos, camRot, panPos); + cameraChanged |= panChanged; + if (panChanged) { + Vector3 delta = Vector3Subtract(camPos, panStartPos); + pivot = Vector3Add(pivot, delta); + if (selectedEntity != entt::null) { + editorPivotOffset = Vector3Add(editorPivotOffset, delta); + } else { + editorCameraPivot = pivot; + } } - } - if (cameraChanged) { - editorCamera.position = camPos; - Vector3 up = Vector3RotateByQuaternion({0.0f, 1.0f, 0.0f}, camRot); - editorCamera.target = pivot; - editorCamera.up = up; + if (cameraChanged) { + editorCamera.position = camPos; + Vector3 up = Vector3RotateByQuaternion({0.0f, 1.0f, 0.0f}, camRot); + editorCamera.target = pivot; + editorCamera.up = up; + } } } diff --git a/src/scripting/InputBindings.cpp b/src/scripting/InputBindings.cpp index e97eade..cb1bfe2 100644 --- a/src/scripting/InputBindings.cpp +++ b/src/scripting/InputBindings.cpp @@ -50,6 +50,10 @@ static void AS_ClearBindings(const std::string& actionName) { if (g_inputManager) g_inputManager->ClearBindings(actionName); } +static void AS_ClearAllActions() { + if (g_inputManager) g_inputManager->ClearAllActions(); +} + void RegisterInputBindings(asIScriptEngine* engine) { int r; @@ -94,6 +98,10 @@ void RegisterInputBindings(asIScriptEngine* engine) { r = engine->RegisterGlobalFunction("void ClearBindings(const string &in)", asFUNCTION(AS_ClearBindings), asCALL_CDECL); assert(r >= 0); + + r = engine->RegisterGlobalFunction("void ClearAllActions()", + asFUNCTION(AS_ClearAllActions), asCALL_CDECL); + assert(r >= 0); // Key constants for binding r = engine->RegisterEnum("Key"); diff --git a/src/scripting/ScriptEngine.cpp b/src/scripting/ScriptEngine.cpp index 895abcf..62d24fc 100644 --- a/src/scripting/ScriptEngine.cpp +++ b/src/scripting/ScriptEngine.cpp @@ -247,6 +247,34 @@ void ScriptEngine::CallScriptFunction(asIScriptFunction* func, float dt) { ctx->Release(); } +bool ScriptEngine::CallModuleFunction(asIScriptModule* module, const std::string& decl) { + if (!engine || !module) return false; + + asIScriptFunction* func = module->GetFunctionByDecl(decl.c_str()); + if (!func) return false; + + asIScriptContext* ctx = engine->CreateContext(); + if (!ctx) return false; + + int r = ctx->Prepare(func); + if (r < 0) { + ctx->Release(); + return false; + } + + r = ctx->Execute(); + if (r != asEXECUTION_FINISHED) { + if (r == asEXECUTION_EXCEPTION) { + log_error("Script exception: %s", ctx->GetExceptionString()); + } + ctx->Release(); + return false; + } + + ctx->Release(); + return true; +} + void ScriptEngine::CallScriptFunction(asIScriptFunction* func, unsigned int entityId, float dt) { if (!func || !engine) return; diff --git a/tests/scenegraph_tests.cpp b/tests/scenegraph_tests.cpp index 7a79974..492bb42 100644 --- a/tests/scenegraph_tests.cpp +++ b/tests/scenegraph_tests.cpp @@ -175,6 +175,71 @@ void test_scene_loader_basic(void) { ShutdownRaylibHidden(); } +void test_scene_loader_scene_script_path(void) { + entt::registry registry; + ModelManager modelManager; + ShaderManager shaderManager; + TextureManager textureManager; + SetSceneContext(®istry, &modelManager, &shaderManager, &textureManager); + + std::filesystem::path tmpDir = std::filesystem::current_path() / "tmp_scene_script"; + std::filesystem::create_directories(tmpDir); + std::filesystem::path scenePath = tmpDir / "scene.toml"; + + { + std::ofstream scene(scenePath); + scene << "scene_script = \"scripts/demo_scene.as\"\n"; + scene << "\n"; + scene << "[[entity]]\n"; + scene << "id = \"root\"\n"; + scene << "tag = \"Root\"\n"; + } + + entt::entity root = LoadSceneFromFile(scenePath.string(), true); + TEST_CHECK(root != entt::null); + + std::string sceneScript; + bool changed = ConsumeSceneScriptPath(sceneScript); + TEST_CHECK(changed == true); + TEST_CHECK(sceneScript == "scripts/demo_scene.as"); + + std::filesystem::remove(scenePath); + std::filesystem::remove(tmpDir); +} + +void test_scene_loader_clear_scene_script(void) { + entt::registry registry; + ModelManager modelManager; + ShaderManager shaderManager; + TextureManager textureManager; + SetSceneContext(®istry, &modelManager, &shaderManager, &textureManager); + + SetSceneScriptPath("scripts/old_scene.as"); + std::string previous; + ConsumeSceneScriptPath(previous); + + std::filesystem::path tmpDir = std::filesystem::current_path() / "tmp_scene_clear"; + std::filesystem::create_directories(tmpDir); + std::filesystem::path scenePath = tmpDir / "scene.toml"; + + { + std::ofstream scene(scenePath); + scene << "[[entity]]\n"; + scene << "id = \"root\"\n"; + scene << "tag = \"Root\"\n"; + } + + LoadSceneFromFile(scenePath.string(), true); + + std::string sceneScript; + bool changed = ConsumeSceneScriptPath(sceneScript); + TEST_CHECK(changed == true); + TEST_CHECK(sceneScript.empty()); + + std::filesystem::remove(scenePath); + std::filesystem::remove(tmpDir); +} + void test_scene_loader_asset_keys(void) { if (!InitRaylibHidden()) { TEST_SKIP("No display available for raylib"); From 3e23f7da8eeff25b18315ae1af3bae50c466215f Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Wed, 11 Mar 2026 16:43:36 +1300 Subject: [PATCH 53/53] feat: added physFS --- .gitmodules | 3 + CMakeLists.txt | 9 ++ assets/registry.toml | 12 +- external/physfs | 1 + include/Application.h | 2 +- include/HotReload.h | 1 - include/PhysFSManager.h | 36 +++++ include/gui/GuiManager.h | 4 +- include/scripting/PhysFSBindings.h | 5 + src/Application.cpp | 71 +++++--- src/AssetManager.cpp | 24 ++- src/HotReload.cpp | 53 +++--- src/PhysFSManager.cpp | 250 +++++++++++++++++++++++++++++ src/SceneLoader.cpp | 19 ++- src/gui/GuiManager.cpp | 24 ++- src/scripting/PhysFSBindings.cpp | 73 +++++++++ src/scripting/ScriptBindings.cpp | 2 + src/scripting/ScriptEngine.cpp | 37 +++-- tests/CMakeLists.txt | 4 + tests/hot_reload.cpp | 8 +- tests/math_bindings_tests.cpp | 8 +- tests/physfs_test_utils.cpp | 31 ++++ tests/physfs_test_utils.h | 9 ++ tests/resource_tests.cpp | 92 ++++++----- tests/scenegraph_tests.cpp | 156 ++++++++++++------ tests/scenegraph_tests.h | 3 + tests/script_engine_tests.cpp | 15 +- tests/test.cpp | 3 + 28 files changed, 757 insertions(+), 198 deletions(-) create mode 160000 external/physfs create mode 100644 include/PhysFSManager.h create mode 100644 include/scripting/PhysFSBindings.h create mode 100644 src/PhysFSManager.cpp create mode 100644 src/scripting/PhysFSBindings.cpp create mode 100644 tests/physfs_test_utils.cpp create mode 100644 tests/physfs_test_utils.h diff --git a/.gitmodules b/.gitmodules index a62c29d..482df24 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,3 +10,6 @@ [submodule "external/rlImGui"] path = external/rlImGui url = https://github.com/raylib-extras/rlImGui.git +[submodule "external/physfs"] + path = external/physfs + url = https://github.com/icculus/physfs diff --git a/CMakeLists.txt b/CMakeLists.txt index 4be7d2a..3102dca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,11 @@ add_subdirectory(external/raylib) # ------------------------- add_subdirectory(external/angelscript/sdk/angelscript/projects/cmake) +# ------------------------- +# PhysFS (submodule) +# ------------------------- +add_subdirectory(external/physfs) + # ------------------------- # Dear ImGui (docking branch) # ------------------------- @@ -79,6 +84,7 @@ target_include_directories(scriptarray # ------------------------- add_library(simian_core STATIC src/Application.cpp + src/PhysFSManager.cpp src/SceneGraph.cpp src/SceneLoader.cpp src/scripting/ScriptEngine.cpp @@ -92,6 +98,7 @@ add_library(simian_core STATIC src/scripting/ResourceBindings.cpp src/scripting/InputBindings.cpp src/scripting/SceneBindings.cpp + src/scripting/PhysFSBindings.cpp src/HotReload.cpp src/gui/GuiManager.cpp src/gui/ImViewGuizmoIntegration.cpp @@ -115,6 +122,7 @@ target_include_directories(simian_core PUBLIC external/angelscript/sdk/add_on/scriptstdstring external/angelscript/sdk/add_on/scriptbuilder external/angelscript/sdk/add_on/scriptarray + external/physfs/src external/imgui external/ImViewGuizmo ) @@ -122,6 +130,7 @@ target_include_directories(simian_core PUBLIC target_link_libraries(simian_core PUBLIC raylib angelscript + PhysFS::PhysFS-static scriptstdstring scriptbuilder scriptarray diff --git a/assets/registry.toml b/assets/registry.toml index 70b2f7d..0d52586 100644 --- a/assets/registry.toml +++ b/assets/registry.toml @@ -1,15 +1,15 @@ # Simian asset registry # Auto-generated - edits may be overwritten -[[model]] -key = "demo_cube" -type = "primitive" -primitive = "cube" -params = [1, 1, 1] - [[model]] key = "Torus" type = "primitive" primitive = "torus" params = [0.5, 1, 16, 8] +[[model]] +key = "demo_cube" +type = "primitive" +primitive = "cube" +params = [1, 1, 1] + diff --git a/external/physfs b/external/physfs new file mode 160000 index 0000000..49cfd5f --- /dev/null +++ b/external/physfs @@ -0,0 +1 @@ +Subproject commit 49cfd5fdd46f38b4c2611556b44ee9b0d308e162 diff --git a/include/Application.h b/include/Application.h index 7759310..b840529 100644 --- a/include/Application.h +++ b/include/Application.h @@ -60,7 +60,7 @@ private: ScriptEngine scriptEngine; HotReload* hotReload; bool scriptCompilationError; - FILE* logFile; + struct PHYSFS_File* logFile; GuiManager guiManager; bool enableEditor; bool queueShutdown = false; diff --git a/include/HotReload.h b/include/HotReload.h index 1802fdb..4545e98 100644 --- a/include/HotReload.h +++ b/include/HotReload.h @@ -1,7 +1,6 @@ #pragma once #include #include -#include class HotReload { public: diff --git a/include/PhysFSManager.h b/include/PhysFSManager.h new file mode 100644 index 0000000..c790bd7 --- /dev/null +++ b/include/PhysFSManager.h @@ -0,0 +1,36 @@ +#pragma once + +#include +#include +#include + +struct PHYSFS_File; + +namespace PhysFSManager { + +bool Initialize(const char* argv0); +bool IsInitialized(); +void Shutdown(); + +bool MountPath(const std::string& path, const std::string& mountPoint, bool append = true); +bool UnmountPath(const std::string& path); +void ClearSearchPath(); + +bool SetWriteDir(const std::string& path); +bool EnsureDir(const std::string& path); + +bool Exists(const std::string& path); +bool IsDirectory(const std::string& path); +std::string GetRealDir(const std::string& path); + +std::int64_t GetModTime(const std::string& path); +std::vector ListFiles(const std::string& path); + +bool ReadTextFile(const std::string& path, std::string& out); +bool WriteTextFile(const std::string& path, const std::string& contents); + +PHYSFS_File* OpenRead(const std::string& path); +PHYSFS_File* OpenWrite(const std::string& path); +void Close(PHYSFS_File* file); + +} // namespace PhysFSManager diff --git a/include/gui/GuiManager.h b/include/gui/GuiManager.h index 4f58e17..5fc2695 100644 --- a/include/gui/GuiManager.h +++ b/include/gui/GuiManager.h @@ -10,7 +10,7 @@ #include #include #include -#include +#include class Application; @@ -57,7 +57,7 @@ private: struct ScriptEditableCache { std::string className; std::vector fields; - std::filesystem::file_time_type lastWriteTime; + std::int64_t lastWriteTime = 0; bool hasWriteTime = false; }; diff --git a/include/scripting/PhysFSBindings.h b/include/scripting/PhysFSBindings.h new file mode 100644 index 0000000..fa3ecb0 --- /dev/null +++ b/include/scripting/PhysFSBindings.h @@ -0,0 +1,5 @@ +#pragma once + +class asIScriptEngine; + +void RegisterPhysFSBindings(asIScriptEngine* engine); diff --git a/src/Application.cpp b/src/Application.cpp index fbc4aac..cd4b0ac 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -4,13 +4,14 @@ #include "scripting/ResourceBindings.h" #include "SceneGraph.h" #include "SceneLoader.h" +#include "PhysFSManager.h" #include "raylib.h" #include "rlgl.h" #include "raymath.h" #include #include #include -#include +#include #include #include "log/log.h" @@ -18,17 +19,36 @@ #include "imgui.h" #include "gui/GuiManager.h" #include "gui/Toast.h" - -#ifdef _WIN32 -// On Windows, fopen_s is already available, so no need to define it. -#else -// On non-Windows platforms, define fopen_s as a macro for fopen. -#define fopen_s(pFile, filename, mode) ((*(pFile) = fopen((filename), (mode))) == NULL) -#endif +#include "physfs.h" const char *Application::WINDOW_TITLE = "Simian"; static const char* kAutoloadScriptFile = "scripts/autoload.as"; static const char* kAssetRegistryFile = "assets/registry.toml"; +static const char* kLogFilePath = "log.txt"; + +static void PhysFSLogCallback(log_Event* ev) +{ + if (!ev || !ev->udata) return; + PHYSFS_File* file = static_cast(ev->udata); + + char buf[64]; + buf[strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", ev->time)] = '\0'; + + std::string line; + if (ev->file) { + line = std::string(buf) + " " + log_level_string(ev->level) + " " + ev->file + ":" + std::to_string(ev->line) + ": "; + } else { + line = std::string(buf) + " " + log_level_string(ev->level) + ": "; + } + + char message[1024]; + vsnprintf(message, sizeof(message), ev->fmt, ev->ap); + line += message; + line.push_back('\n'); + + PHYSFS_writeBytes(file, line.data(), static_cast(line.size())); + PHYSFS_flush(file); +} Application::Application() : hotReload(nullptr), scriptCompilationError(false), logFile(nullptr), renderTexture{} @@ -44,14 +64,24 @@ Application::~Application() bool Application::Initialize(int argc, char *argv[]) { - if (fopen_s(&logFile, "log.txt", "w") != 0) + logFile = nullptr; + + if (!PhysFSManager::Initialize(argc > 0 ? argv[0] : nullptr)) { - logFile = nullptr; - log_error("Failed to open log file"); + log_error("Failed to initialize PhysFS"); + return false; } - else - { - log_add_fp(logFile, LOG_TRACE); + + PhysFSManager::SetWriteDir("."); + + const char* mountDirs[] = {"scripts", "scenes", "assets", "shaders", "fonts", "textures", "models"}; + for (const char* dir : mountDirs) { + PhysFSManager::MountPath(dir, dir, true); + } + + logFile = PhysFSManager::OpenWrite(kLogFilePath); + if (logFile) { + log_add_callback(PhysFSLogCallback, logFile, LOG_TRACE); } SetTraceLogCallback(raylib_log); @@ -112,10 +142,13 @@ bool Application::Initialize(int argc, char *argv[]) // Initialize hot reload to watch the scripts directory so any script change // triggers a reload. { - std::filesystem::path p(kAutoloadScriptFile); - std::string watchPath = p.parent_path().string(); - if (watchPath.empty()) + std::string watchPath = kAutoloadScriptFile; + size_t sep = watchPath.find_last_of("/\\"); + if (sep != std::string::npos) { + watchPath = watchPath.substr(0, sep); + } else { watchPath = "."; + } hotReload = new HotReload(watchPath); } @@ -914,7 +947,9 @@ void Application::Shutdown() // Close log file after everything else is cleaned up if (logFile) { - fclose(logFile); + PhysFSManager::Close(logFile); logFile = nullptr; } + + PhysFSManager::Shutdown(); } diff --git a/src/AssetManager.cpp b/src/AssetManager.cpp index 17df0e5..812dd26 100644 --- a/src/AssetManager.cpp +++ b/src/AssetManager.cpp @@ -3,11 +3,10 @@ #include "ShaderManager.h" #include "MaterialManager.h" #include "TextureManager.h" +#include "PhysFSManager.h" #include "log/log.h" #include #include -#include -#include #include #include @@ -759,18 +758,12 @@ std::vector AssetManager::ListKeys(const std::unordered_map -namespace fs = std::filesystem; - HotReload::HotReload(const std::string& pathToWatch) : path(pathToWatch), lastWriteTime(0) { UpdateLastWriteTime(); } @@ -21,36 +20,32 @@ void HotReload::UpdateLastWriteTime() { } std::time_t HotReload::GetFileWriteTime(const std::string& filename) { - try { - auto ftime = fs::last_write_time(filename); - auto sctp = std::chrono::time_point_cast( - ftime - fs::file_time_type::clock::now() + std::chrono::system_clock::now()); - return std::chrono::system_clock::to_time_t(sctp); - } catch (const std::exception&) { - return 0; - } + return static_cast(PhysFSManager::GetModTime(filename)); } std::time_t HotReload::GetLatestWriteTimeInPath() { - try { - fs::path p(path); - if (fs::is_regular_file(p)) { - return GetFileWriteTime(path); - } - - // If it's a directory, scan files (non-recursively) and return the - // newest write time found. - if (fs::is_directory(p)) { - std::time_t newest = 0; - for (auto &entry : fs::directory_iterator(p)) { - if (!fs::is_regular_file(entry.path())) continue; - std::time_t t = GetFileWriteTime(entry.path().string()); - if (t > newest) newest = t; - } - return newest; - } - } catch (const std::exception&) { - // fall through + if (PhysFSManager::Exists(path) && !PhysFSManager::IsDirectory(path)) { + return GetFileWriteTime(path); } + + if (PhysFSManager::IsDirectory(path)) { + std::time_t newest = 0; + auto entries = PhysFSManager::ListFiles(path); + for (const auto& entry : entries) { + if (entry == "." || entry == "..") continue; + std::string child = path; + if (!child.empty() && child.back() != '/') { + child.push_back('/'); + } + child += entry; + if (PhysFSManager::IsDirectory(child)) { + continue; + } + std::time_t t = GetFileWriteTime(child); + if (t > newest) newest = t; + } + return newest; + } + return 0; } diff --git a/src/PhysFSManager.cpp b/src/PhysFSManager.cpp new file mode 100644 index 0000000..4b50d5a --- /dev/null +++ b/src/PhysFSManager.cpp @@ -0,0 +1,250 @@ +#include "PhysFSManager.h" +#include "raylib.h" +#include "physfs.h" +#include "log/log.h" +#include +#include +#include + +namespace PhysFSManager { + +static bool g_initialized = false; + +static unsigned char* RaylibLoadFileDataCallback(const char* fileName, int* dataSize) { + if (!fileName || !dataSize) { + return nullptr; + } + + PHYSFS_File* file = PHYSFS_openRead(fileName); + if (!file) { + *dataSize = 0; + return nullptr; + } + + PHYSFS_sint64 length = PHYSFS_fileLength(file); + if (length <= 0 || length > static_cast(INT32_MAX)) { + PHYSFS_close(file); + *dataSize = 0; + return nullptr; + } + + unsigned char* data = static_cast(MemAlloc(static_cast(length))); + if (!data) { + PHYSFS_close(file); + *dataSize = 0; + return nullptr; + } + + PHYSFS_sint64 read = PHYSFS_readBytes(file, data, length); + PHYSFS_close(file); + if (read != length) { + MemFree(data); + *dataSize = 0; + return nullptr; + } + + *dataSize = static_cast(length); + return data; +} + +static bool RaylibSaveFileDataCallback(const char* fileName, void* data, int dataSize) { + if (!fileName || !data || dataSize <= 0) { + return false; + } + + PHYSFS_File* file = PHYSFS_openWrite(fileName); + if (!file) { + return false; + } + + PHYSFS_sint64 written = PHYSFS_writeBytes(file, data, dataSize); + PHYSFS_close(file); + return written == dataSize; +} + +bool Initialize(const char* argv0) { + if (g_initialized) { + return true; + } + + if (!PHYSFS_init(argv0)) { + log_error("PhysFS init failed: %s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode())); + return false; + } + + PHYSFS_permitSymbolicLinks(0); + + // Configure raylib to use PhysFS for all file reads/writes. + SetLoadFileDataCallback(RaylibLoadFileDataCallback); + SetSaveFileDataCallback(RaylibSaveFileDataCallback); + + g_initialized = true; + return true; +} + +bool IsInitialized() { + return g_initialized; +} + +void Shutdown() { + if (!g_initialized) { + return; + } + + ClearSearchPath(); + SetLoadFileDataCallback(nullptr); + SetSaveFileDataCallback(nullptr); + PHYSFS_deinit(); + g_initialized = false; +} + +bool MountPath(const std::string& path, const std::string& mountPoint, bool append) { + const char* mount = mountPoint.empty() ? nullptr : mountPoint.c_str(); + if (!PHYSFS_mount(path.c_str(), mount, append ? 1 : 0)) { + log_warn("PhysFS mount failed: %s -> %s (%s)", path.c_str(), mountPoint.c_str(), + PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode())); + return false; + } + return true; +} + +bool UnmountPath(const std::string& path) { + if (!PHYSFS_unmount(path.c_str())) { + return false; + } + return true; +} + +void ClearSearchPath() { + char** paths = PHYSFS_getSearchPath(); + if (!paths) { + return; + } + + for (char** i = paths; *i != nullptr; ++i) { + PHYSFS_unmount(*i); + } + + PHYSFS_freeList(paths); +} + +bool SetWriteDir(const std::string& path) { + if (!PHYSFS_setWriteDir(path.c_str())) { + log_warn("PhysFS set write dir failed: %s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode())); + return false; + } + return true; +} + +bool EnsureDir(const std::string& path) { + if (path.empty()) { + return true; + } + + std::string normalized = path; + std::replace(normalized.begin(), normalized.end(), '\\', '/'); + + size_t start = 0; + while (start < normalized.size()) { + size_t slash = normalized.find('/', start); + std::string segment = normalized.substr(0, slash); + if (!segment.empty() && !IsDirectory(segment)) { + if (!PHYSFS_mkdir(segment.c_str())) { + return false; + } + } + if (slash == std::string::npos) { + break; + } + start = slash + 1; + } + + return true; +} + +bool Exists(const std::string& path) { + return PHYSFS_exists(path.c_str()) != 0; +} + +bool IsDirectory(const std::string& path) { + return PHYSFS_isDirectory(path.c_str()) != 0; +} + +std::string GetRealDir(const std::string& path) { + const char* dir = PHYSFS_getRealDir(path.c_str()); + return dir ? std::string(dir) : std::string(); +} + +std::int64_t GetModTime(const std::string& path) { + PHYSFS_Stat stat{}; + if (!PHYSFS_stat(path.c_str(), &stat)) { + return 0; + } + return static_cast(stat.modtime); +} + +std::vector ListFiles(const std::string& path) { + std::vector result; + char** files = PHYSFS_enumerateFiles(path.c_str()); + if (!files) { + return result; + } + + for (char** i = files; *i != nullptr; ++i) { + result.emplace_back(*i); + } + + PHYSFS_freeList(files); + return result; +} + +bool ReadTextFile(const std::string& path, std::string& out) { + out.clear(); + PHYSFS_File* file = PHYSFS_openRead(path.c_str()); + if (!file) { + return false; + } + + PHYSFS_sint64 length = PHYSFS_fileLength(file); + if (length < 0) { + PHYSFS_close(file); + return false; + } + + out.resize(static_cast(length)); + PHYSFS_sint64 read = PHYSFS_readBytes(file, out.data(), length); + PHYSFS_close(file); + if (read != length) { + out.clear(); + return false; + } + + return true; +} + +bool WriteTextFile(const std::string& path, const std::string& contents) { + PHYSFS_File* file = PHYSFS_openWrite(path.c_str()); + if (!file) { + return false; + } + + PHYSFS_sint64 written = PHYSFS_writeBytes(file, contents.data(), contents.size()); + PHYSFS_close(file); + return written == static_cast(contents.size()); +} + +PHYSFS_File* OpenRead(const std::string& path) { + return PHYSFS_openRead(path.c_str()); +} + +PHYSFS_File* OpenWrite(const std::string& path) { + return PHYSFS_openWrite(path.c_str()); +} + +void Close(PHYSFS_File* file) { + if (file) { + PHYSFS_close(file); + } +} + +} // namespace PhysFSManager diff --git a/src/SceneLoader.cpp b/src/SceneLoader.cpp index f74ad27..d7e8221 100644 --- a/src/SceneLoader.cpp +++ b/src/SceneLoader.cpp @@ -5,10 +5,10 @@ #include "SceneGraph.h" #include "TextureManager.h" #include "AssetManager.h" +#include "PhysFSManager.h" #include "log/log.h" #include "raylib.h" #include "entt.hpp" -#include #include #include #include @@ -432,12 +432,14 @@ entt::entity LoadSceneFromFile(const std::string& path, bool clearExisting) { SetSceneScriptPath(std::string()); } - std::ifstream file(path); - if (!file.is_open()) { + std::string contents; + if (!PhysFSManager::ReadTextFile(path, contents)) { log_error("Failed to open scene file: %s", path.c_str()); return entt::null; } + std::istringstream file(contents); + std::vector defs; SceneEntityDef* current = nullptr; std::string line; @@ -748,12 +750,13 @@ bool SaveSceneToFile(const std::string& path) { return false; } - std::ofstream file(path); - if (!file.is_open()) { - log_error("Failed to open scene file for writing: %s", path.c_str()); - return false; + auto parentPos = path.find_last_of("/\\"); + if (parentPos != std::string::npos) { + PhysFSManager::EnsureDir(path.substr(0, parentPos)); } + std::ostringstream file; + if (!g_sceneScriptPath.empty()) { file << "scene_script = \"" << EscapeString(g_sceneScriptPath) << "\"\n\n"; } @@ -956,5 +959,5 @@ bool SaveSceneToFile(const std::string& path) { file << "\n"; } - return true; + return PhysFSManager::WriteTextFile(path, file.str()); } diff --git a/src/gui/GuiManager.cpp b/src/gui/GuiManager.cpp index f4e50a5..897e4e2 100644 --- a/src/gui/GuiManager.cpp +++ b/src/gui/GuiManager.cpp @@ -1,7 +1,6 @@ #include "gui/GuiManager.h" #include "raylib.h" #include "raymath.h" -#include // Add this to fix the incomplete type error #include #include #include @@ -17,7 +16,7 @@ #include "ECSComponents.h" #include "SceneGraph.h" #include "SceneLoader.h" -#include // Add this for cross-platform file handling +#include "PhysFSManager.h" #define IMVIEWGUIZMO_IMPLEMENTATION #include "ImViewGuizmoRaymath.h" @@ -1755,27 +1754,24 @@ GuiManager::ScriptEditableCache &GuiManager::GetOrParseEditableCache(const std:: cache.className = className; bool needsParse = true; - try { - auto writeTime = std::filesystem::last_write_time(path); - if (cache.hasWriteTime && cache.lastWriteTime == writeTime) { - needsParse = false; - } else { - cache.lastWriteTime = writeTime; - cache.hasWriteTime = true; - } - } catch (const std::exception &) { - // If file is missing or time cannot be read, parse anyway (will be empty). + std::int64_t writeTime = PhysFSManager::GetModTime(path); + if (writeTime != 0 && cache.hasWriteTime && cache.lastWriteTime == writeTime) { + needsParse = false; + } else { + cache.lastWriteTime = writeTime; + cache.hasWriteTime = (writeTime != 0); } if (!needsParse) return cache; cache.fields.clear(); - std::ifstream file(path); - if (!file.is_open()) { + std::string contents; + if (!PhysFSManager::ReadTextFile(path, contents)) { return cache; } + std::istringstream file(contents); std::string line; bool inClass = false; int braceDepth = 0; diff --git a/src/scripting/PhysFSBindings.cpp b/src/scripting/PhysFSBindings.cpp new file mode 100644 index 0000000..7553004 --- /dev/null +++ b/src/scripting/PhysFSBindings.cpp @@ -0,0 +1,73 @@ +#include "scripting/PhysFSBindings.h" +#include "PhysFSManager.h" +#include "scriptarray.h" +#include +#include + +static asIScriptEngine* g_engine = nullptr; + +static bool AS_Mount(const std::string& path, const std::string& mountPoint, bool append) { + return PhysFSManager::MountPath(path, mountPoint, append); +} + +static bool AS_Unmount(const std::string& path) { + return PhysFSManager::UnmountPath(path); +} + +static bool AS_Exists(const std::string& path) { + return PhysFSManager::Exists(path); +} + +static bool AS_IsDirectory(const std::string& path) { + return PhysFSManager::IsDirectory(path); +} + +static std::string AS_GetRealDir(const std::string& path) { + return PhysFSManager::GetRealDir(path); +} + +static CScriptArray* AS_ListFiles(const std::string& path) { + if (!g_engine) return nullptr; + const std::vector files = PhysFSManager::ListFiles(path); + asITypeInfo* arrayType = g_engine->GetTypeInfoByDecl("array"); + if (!arrayType) return nullptr; + + CScriptArray* array = CScriptArray::Create(arrayType, static_cast(files.size())); + for (asUINT i = 0; i < static_cast(files.size()); ++i) { + static_cast(array->At(i))->assign(files[i]); + } + return array; +} + +void RegisterPhysFSBindings(asIScriptEngine* engine) { + int r; + g_engine = engine; + + engine->SetDefaultNamespace("PhysFS"); + + r = engine->RegisterGlobalFunction("bool Mount(const string &in, const string &in mountPoint = \"\", bool append = true)", + asFUNCTION(AS_Mount), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("bool Unmount(const string &in)", + asFUNCTION(AS_Unmount), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("bool Exists(const string &in)", + asFUNCTION(AS_Exists), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("bool IsDirectory(const string &in)", + asFUNCTION(AS_IsDirectory), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("string GetRealDir(const string &in)", + asFUNCTION(AS_GetRealDir), asCALL_CDECL); + assert(r >= 0); + + r = engine->RegisterGlobalFunction("array@ ListFiles(const string &in)", + asFUNCTION(AS_ListFiles), asCALL_CDECL); + assert(r >= 0); + + engine->SetDefaultNamespace(""); +} diff --git a/src/scripting/ScriptBindings.cpp b/src/scripting/ScriptBindings.cpp index 121acfa..40a2403 100644 --- a/src/scripting/ScriptBindings.cpp +++ b/src/scripting/ScriptBindings.cpp @@ -8,6 +8,7 @@ #include "scripting/ResourceBindings.h" #include "scripting/InputBindings.h" #include "scripting/SceneBindings.h" +#include "scripting/PhysFSBindings.h" void ScriptBindings::RegisterAll(asIScriptEngine *engine) { @@ -21,4 +22,5 @@ void ScriptBindings::RegisterAll(asIScriptEngine *engine) RegisterResourceBindings(engine); RegisterInputBindings(engine); RegisterSceneBindings(engine); + RegisterPhysFSBindings(engine); } \ No newline at end of file diff --git a/src/scripting/ScriptEngine.cpp b/src/scripting/ScriptEngine.cpp index 62d24fc..20bf13b 100644 --- a/src/scripting/ScriptEngine.cpp +++ b/src/scripting/ScriptEngine.cpp @@ -3,8 +3,7 @@ #include "scriptstdstring.h" #include "scriptbuilder.h" #include "scriptarray.h" -#include -#include +#include "PhysFSManager.h" #include #include #include "../log/log.h" @@ -110,6 +109,12 @@ void ScriptEngine::Shutdown() { bool ScriptEngine::CompileScript(const std::string& filename) { if (!engine) return false; + std::string source; + if (!PhysFSManager::ReadTextFile(filename, source)) { + log_error("Failed to read script file: %s", filename.c_str()); + return false; + } + // Try to compile in a temporary module first using CScriptBuilder CScriptBuilder tempBuilder; tempBuilder.SetIncludeCallback(IncludeCallback, nullptr); @@ -120,7 +125,7 @@ bool ScriptEngine::CompileScript(const std::string& filename) { return false; } - r = tempBuilder.AddSectionFromFile(filename.c_str()); + r = tempBuilder.AddSectionFromMemory(filename.c_str(), source.c_str(), static_cast(source.size())); if (r < 0) { log_error("Failed to add script section from file: %s", filename.c_str()); engine->DiscardModule("temp"); @@ -146,7 +151,7 @@ bool ScriptEngine::CompileScript(const std::string& filename) { r = mainBuilder.StartNewModule(engine, "main"); if (r >= 0) { - r = mainBuilder.AddSectionFromFile(filename.c_str()); + r = mainBuilder.AddSectionFromMemory(filename.c_str(), source.c_str(), static_cast(source.size())); } if (r >= 0) { r = mainBuilder.BuildModule(); @@ -188,6 +193,12 @@ bool ScriptEngine::CompileScript(const std::string& filename) { bool ScriptEngine::CompileModule(const std::string& moduleName, const std::string& filename, asIScriptModule** outModule) { if (!engine) return false; + std::string source; + if (!PhysFSManager::ReadTextFile(filename, source)) { + log_error("Failed to read script module file: %s", filename.c_str()); + return false; + } + if (engine->GetModule(moduleName.c_str())) { engine->DiscardModule(moduleName.c_str()); } @@ -201,7 +212,7 @@ bool ScriptEngine::CompileModule(const std::string& moduleName, const std::strin return false; } - r = builder.AddSectionFromFile(filename.c_str()); + r = builder.AddSectionFromMemory(filename.c_str(), source.c_str(), static_cast(source.size())); if (r < 0) { log_error("Failed to add script section from file: %s", filename.c_str()); engine->DiscardModule(moduleName.c_str()); @@ -459,7 +470,11 @@ int ScriptEngine::IncludeCallback(const char* include, const char* from, CScript int result = -1; for (auto &cand : candidates) { - result = builder->AddSectionFromFile(cand.c_str()); + std::string source; + if (!PhysFSManager::ReadTextFile(cand, source)) { + continue; + } + result = builder->AddSectionFromMemory(cand.c_str(), source.c_str(), static_cast(source.size())); if (result >= 0) { log_info("Successfully included: %s", cand.c_str()); return result; @@ -471,9 +486,9 @@ int ScriptEngine::IncludeCallback(const char* include, const char* from, CScript } std::string ScriptEngine::ReadFile(const std::string& filename) { - std::ifstream file(filename); - if (!file) return ""; - std::stringstream ss; - ss << file.rdbuf(); - return ss.str(); + std::string out; + if (!PhysFSManager::ReadTextFile(filename, out)) { + return std::string(); + } + return out; } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 1b83cdc..c4c46ec 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -3,6 +3,7 @@ cmake_minimum_required(VERSION 3.16) # Unit tests just need test sources + link to simian_core add_executable(unit_tests test.cpp + physfs_test_utils.cpp hot_reload.cpp script_engine_tests.cpp math_bindings_tests.cpp @@ -37,4 +38,7 @@ add_test(NAME resource_bindings COMMAND unit_tests resource_bindings) add_test(NAME scenegraph_world COMMAND unit_tests scenegraph_world) add_test(NAME scenegraph_detach COMMAND unit_tests scenegraph_detach) add_test(NAME scene_loader COMMAND unit_tests scene_loader) +add_test(NAME scene_loader_script_path COMMAND unit_tests scene_loader_script_path) +add_test(NAME scene_loader_clear_script COMMAND unit_tests scene_loader_clear_script) add_test(NAME scene_loader_assets COMMAND unit_tests scene_loader_assets) +add_test(NAME scene_loader_sandbox COMMAND unit_tests scene_loader_sandbox) diff --git a/tests/hot_reload.cpp b/tests/hot_reload.cpp index b4eb150..40a2903 100644 --- a/tests/hot_reload.cpp +++ b/tests/hot_reload.cpp @@ -6,6 +6,7 @@ #include #include #include "../include/HotReload.h" +#include "physfs_test_utils.h" using namespace std::chrono_literals; @@ -18,7 +19,10 @@ void test_hotreload_directory_watch(void) { ofs << "// test" << std::endl; ofs.close(); - HotReload hr(tmpDir.string()); + TEST_CHECK(InitPhysFSTest(tmpDir) == true); + TEST_CHECK(MountPhysFSTest(tmpDir, "tmp_watch") == true); + + HotReload hr("tmp_watch"); TEST_CHECK(hr.CheckForChanges() == false); std::this_thread::sleep_for(1s); @@ -28,6 +32,8 @@ void test_hotreload_directory_watch(void) { TEST_CHECK(hr.CheckForChanges() == true); + ShutdownPhysFSTest(); + std::filesystem::remove(f); std::filesystem::remove(tmpDir); } diff --git a/tests/math_bindings_tests.cpp b/tests/math_bindings_tests.cpp index 5f4b55b..d1269c5 100644 --- a/tests/math_bindings_tests.cpp +++ b/tests/math_bindings_tests.cpp @@ -4,6 +4,7 @@ #include #include #include "../include/scripting/ScriptEngine.h" +#include "physfs_test_utils.h" void test_math_bindings(void) { std::filesystem::path tmpDir = std::filesystem::current_path() / "tmp_math"; @@ -20,9 +21,12 @@ void test_math_bindings(void) { script << "float testAbs = Math::Abs(-42.5f);\n"; } + TEST_CHECK(InitPhysFSTest(tmpDir) == true); + TEST_CHECK(MountPhysFSTest(tmpDir, "") == true); + ScriptEngine se; TEST_CHECK(se.Initialize() == true); - bool compiled = se.CompileScript(scriptPath.string()); + bool compiled = se.CompileScript("math_test.as"); TEST_CHECK(compiled == true); asIScriptEngine* engine = se.GetEngine(); @@ -58,6 +62,8 @@ void test_math_bindings(void) { se.Shutdown(); + ShutdownPhysFSTest(); + std::filesystem::remove(scriptPath); std::filesystem::remove(tmpDir); } diff --git a/tests/physfs_test_utils.cpp b/tests/physfs_test_utils.cpp new file mode 100644 index 0000000..f293dd4 --- /dev/null +++ b/tests/physfs_test_utils.cpp @@ -0,0 +1,31 @@ +#include "physfs_test_utils.h" +#include "PhysFSManager.h" + +static bool g_initialized = false; + +bool InitPhysFSTest(const std::filesystem::path& writeDir) { + if (!g_initialized) { + if (!PhysFSManager::Initialize("unit_tests")) { + return false; + } + g_initialized = true; + } + + PhysFSManager::SetWriteDir(writeDir.string()); + return true; +} + +bool MountPhysFSTest(const std::filesystem::path& realPath, const std::string& mountPoint) { + return PhysFSManager::MountPath(realPath.string(), mountPoint, true); +} + +bool UnmountPhysFSTest(const std::filesystem::path& realPath) { + return PhysFSManager::UnmountPath(realPath.string()); +} + +void ShutdownPhysFSTest() { + if (g_initialized) { + PhysFSManager::Shutdown(); + g_initialized = false; + } +} diff --git a/tests/physfs_test_utils.h b/tests/physfs_test_utils.h new file mode 100644 index 0000000..cd66965 --- /dev/null +++ b/tests/physfs_test_utils.h @@ -0,0 +1,9 @@ +#pragma once + +#include +#include + +bool InitPhysFSTest(const std::filesystem::path& writeDir); +bool MountPhysFSTest(const std::filesystem::path& realPath, const std::string& mountPoint); +bool UnmountPhysFSTest(const std::filesystem::path& realPath); +void ShutdownPhysFSTest(); diff --git a/tests/resource_tests.cpp b/tests/resource_tests.cpp index 381ac9a..78aa947 100644 --- a/tests/resource_tests.cpp +++ b/tests/resource_tests.cpp @@ -11,6 +11,7 @@ #include "../include/scripting/ScriptEngine.h" #include "../include/scripting/ResourceBindings.h" #include "raylib.h" +#include "physfs_test_utils.h" extern "C" { void acutest_skip_(const char* file, int line, const char* fmt, ...); } @@ -85,19 +86,23 @@ void test_shader_manager(void) { auto vsPath = WriteTempShader(tmpDir, "test.vs", vsCode); auto fsPath = WriteTempShader(tmpDir, "test.fs", fsCode); + TEST_CHECK(InitPhysFSTest(tmpDir) == true); + TEST_CHECK(MountPhysFSTest(tmpDir, "") == true); + ShaderManager shaderManager; - unsigned int shaderId = shaderManager.Load(vsPath.string(), fsPath.string()); + unsigned int shaderId = shaderManager.Load("test.vs", "test.fs"); TEST_CHECK(shaderId != 0); TEST_CHECK(shaderManager.Get(shaderId) != nullptr); shaderManager.Unload(shaderId); TEST_CHECK(shaderManager.Get(shaderId) == nullptr); + ShutdownRaylibHidden(); + + std::filesystem::remove(vsPath); std::filesystem::remove(fsPath); std::filesystem::remove(tmpDir); - - ShutdownRaylibHidden(); } void test_model_manager(void) { @@ -180,51 +185,56 @@ void test_resource_bindings_script(void) { script << "uint modelId = 0;\n"; script << "uint materialId = 0;\n"; script << "void Init() {\n"; - script << " shaderId = Shader::Load(\"" << vsPath.generic_string() << "\", \"" << fsPath.generic_string() << "\");\n"; + script << " shaderId = Shader::Load(\"script.vs\", \"script.fs\");\n"; script << " modelId = Model::LoadCube(1.0f, 1.0f, 1.0f);\n"; script << " materialId = Material::Create(shaderId, 255, 0, 0, 255);\n"; script << "}\n"; } - ShaderManager shaderManager; - ModelManager modelManager; - MaterialManager materialManager; - TextureManager textureManager; - SetResourceManagers(&shaderManager, &modelManager, &materialManager, &textureManager); + TEST_CHECK(InitPhysFSTest(tmpDir) == true); + TEST_CHECK(MountPhysFSTest(tmpDir, "") == true); - ScriptEngine se; - TEST_CHECK(se.Initialize() == true); - bool compiled = se.CompileScript(scriptPath.string()); - TEST_CHECK(compiled == true); + { + ShaderManager shaderManager; + ModelManager modelManager; + MaterialManager materialManager; + TextureManager textureManager; + SetResourceManagers(&shaderManager, &modelManager, &materialManager, &textureManager); - asIScriptFunction* initFunc = se.GetInitFunction(); - TEST_CHECK(initFunc != nullptr); - se.CallScriptFunction(initFunc); + ScriptEngine se; + TEST_CHECK(se.Initialize() == true); + bool compiled = se.CompileScript("resource_test.as"); + TEST_CHECK(compiled == true); - asIScriptEngine* engine = se.GetEngine(); - TEST_CHECK(engine != nullptr); - asIScriptModule* module = engine ? engine->GetModule("main") : nullptr; - TEST_CHECK(module != nullptr); + asIScriptFunction* initFunc = se.GetInitFunction(); + TEST_CHECK(initFunc != nullptr); + se.CallScriptFunction(initFunc); - auto fetchUInt = [module](const char* name) -> unsigned int { - int idx = module->GetGlobalVarIndexByName(name); - TEST_CHECK_(idx >= 0, "Global '%s' not found", name); - if (idx < 0) return 0; - void* address = module->GetAddressOfGlobalVar(idx); - TEST_CHECK_(address != nullptr, "Global '%s' address null", name); - if (!address) return 0; - return *static_cast(address); - }; + asIScriptEngine* engine = se.GetEngine(); + TEST_CHECK(engine != nullptr); + asIScriptModule* module = engine ? engine->GetModule("main") : nullptr; + TEST_CHECK(module != nullptr); - unsigned int shaderId = fetchUInt("shaderId"); - unsigned int modelId = fetchUInt("modelId"); - unsigned int materialId = fetchUInt("materialId"); + auto fetchUInt = [module](const char* name) -> unsigned int { + int idx = module->GetGlobalVarIndexByName(name); + TEST_CHECK_(idx >= 0, "Global '%s' not found", name); + if (idx < 0) return 0; + void* address = module->GetAddressOfGlobalVar(idx); + TEST_CHECK_(address != nullptr, "Global '%s' address null", name); + if (!address) return 0; + return *static_cast(address); + }; - TEST_CHECK(shaderId != 0); - TEST_CHECK(modelId != 0); - TEST_CHECK(materialId != 0); + unsigned int shaderId = fetchUInt("shaderId"); + unsigned int modelId = fetchUInt("modelId"); + unsigned int materialId = fetchUInt("materialId"); - se.Shutdown(); + TEST_CHECK(shaderId != 0); + TEST_CHECK(modelId != 0); + TEST_CHECK(materialId != 0); + + se.Shutdown(); + } std::filesystem::remove(scriptPath); std::filesystem::remove(vsPath); @@ -232,6 +242,7 @@ void test_resource_bindings_script(void) { std::filesystem::remove(tmpDir); ShutdownRaylibHidden(); + } void test_asset_registry_material(void) { @@ -239,6 +250,9 @@ void test_asset_registry_material(void) { std::filesystem::create_directories(tmpDir); std::filesystem::path registryPath = tmpDir / "registry.toml"; + TEST_CHECK(InitPhysFSTest(tmpDir) == true); + TEST_CHECK(MountPhysFSTest(tmpDir, "") == true); + MaterialManager materialManager; AssetManager assets; assets.SetManagers(nullptr, nullptr, &materialManager, nullptr); @@ -247,7 +261,7 @@ void test_asset_registry_material(void) { unsigned int materialId = assets.CreateMaterial("test_mat", 0, albedo); TEST_CHECK(materialId != 0); - bool saved = assets.SaveRegistry(registryPath.string()); + bool saved = assets.SaveRegistry("registry.toml"); TEST_CHECK(saved == true); assets.Clear(); @@ -257,7 +271,7 @@ void test_asset_registry_material(void) { AssetManager assetsReload; assetsReload.SetManagers(nullptr, nullptr, &materialManagerReload, nullptr); - bool loaded = assetsReload.LoadRegistry(registryPath.string()); + bool loaded = assetsReload.LoadRegistry("registry.toml"); TEST_CHECK(loaded == true); unsigned int loadedId = assetsReload.GetMaterialId("test_mat"); @@ -271,6 +285,8 @@ void test_asset_registry_material(void) { TEST_CHECK(data->albedo.a == 40); } + ShutdownPhysFSTest(); + std::filesystem::remove(registryPath); std::filesystem::remove(tmpDir); } diff --git a/tests/scenegraph_tests.cpp b/tests/scenegraph_tests.cpp index 492bb42..0bfbb2d 100644 --- a/tests/scenegraph_tests.cpp +++ b/tests/scenegraph_tests.cpp @@ -12,6 +12,7 @@ #include "../include/AssetManager.h" #include "raylib.h" #include "entt.hpp" +#include "physfs_test_utils.h" extern "C" { void acutest_skip_(const char* file, int line, const char* fmt, ...); @@ -105,10 +106,6 @@ void test_scene_loader_basic(void) { } entt::registry registry; - ModelManager modelManager; - ShaderManager shaderManager; - TextureManager textureManager; - SetSceneContext(®istry, &modelManager, &shaderManager, &textureManager); std::filesystem::path tmpDir = std::filesystem::current_path() / "tmp_scene"; std::filesystem::create_directories(tmpDir); @@ -140,8 +137,18 @@ void test_scene_loader_basic(void) { scene << "color = 0xFF0000FF\n"; } - entt::entity root = LoadSceneFromFile(scenePath.string(), true); - TEST_CHECK(root != entt::null); + TEST_CHECK(InitPhysFSTest(tmpDir) == true); + TEST_CHECK(MountPhysFSTest(tmpDir, "") == true); + + { + ModelManager modelManager; + ShaderManager shaderManager; + TextureManager textureManager; + SetSceneContext(®istry, &modelManager, &shaderManager, &textureManager); + + entt::entity root = LoadSceneFromFile("scene.toml", true); + TEST_CHECK(root != entt::null); + } entt::entity parentEntity = entt::null; entt::entity childEntity = entt::null; @@ -169,10 +176,11 @@ void test_scene_loader_basic(void) { TEST_CHECK(registry.all_of(childEntity)); } + ShutdownRaylibHidden(); + + std::filesystem::remove(scenePath); std::filesystem::remove(tmpDir); - - ShutdownRaylibHidden(); } void test_scene_loader_scene_script_path(void) { @@ -195,7 +203,10 @@ void test_scene_loader_scene_script_path(void) { scene << "tag = \"Root\"\n"; } - entt::entity root = LoadSceneFromFile(scenePath.string(), true); + TEST_CHECK(InitPhysFSTest(tmpDir) == true); + TEST_CHECK(MountPhysFSTest(tmpDir, "") == true); + + entt::entity root = LoadSceneFromFile("scene.toml", true); TEST_CHECK(root != entt::null); std::string sceneScript; @@ -203,6 +214,7 @@ void test_scene_loader_scene_script_path(void) { TEST_CHECK(changed == true); TEST_CHECK(sceneScript == "scripts/demo_scene.as"); + std::filesystem::remove(scenePath); std::filesystem::remove(tmpDir); } @@ -229,13 +241,18 @@ void test_scene_loader_clear_scene_script(void) { scene << "tag = \"Root\"\n"; } - LoadSceneFromFile(scenePath.string(), true); + TEST_CHECK(InitPhysFSTest(tmpDir) == true); + TEST_CHECK(MountPhysFSTest(tmpDir, "") == true); + + LoadSceneFromFile("scene.toml", true); std::string sceneScript; bool changed = ConsumeSceneScriptPath(sceneScript); TEST_CHECK(changed == true); TEST_CHECK(sceneScript.empty()); + ShutdownPhysFSTest(); + std::filesystem::remove(scenePath); std::filesystem::remove(tmpDir); } @@ -251,6 +268,9 @@ void test_scene_loader_asset_keys(void) { std::filesystem::path registryPath = tmpDir / "registry.toml"; std::filesystem::path scenePath = tmpDir / "scene_asset.toml"; + TEST_CHECK(InitPhysFSTest(tmpDir) == true); + TEST_CHECK(MountPhysFSTest(tmpDir, "") == true); + { ModelManager modelManager; ShaderManager shaderManager; @@ -258,58 +278,92 @@ void test_scene_loader_asset_keys(void) { AssetManager assets; assets.SetManagers(&modelManager, &shaderManager, nullptr, &textureManager); assets.LoadCube("demo_cube", 1.0f, 1.0f, 1.0f); - assets.SaveRegistry(registryPath.string()); + assets.SaveRegistry("registry.toml"); } entt::registry registry; - ModelManager modelManager; - ShaderManager shaderManager; - TextureManager textureManager; - AssetManager assets; - assets.SetManagers(&modelManager, &shaderManager, nullptr, &textureManager); - assets.LoadRegistry(registryPath.string()); - - SetSceneContext(®istry, &modelManager, &shaderManager, &textureManager); - SetSceneAssetManager(&assets); - { - std::ofstream scene(scenePath); - scene << "[[entity]]\n"; - scene << "id = \"root\"\n"; - scene << "tag = \"Root\"\n"; - scene << "position = [0.0, 0.0, 0.0]\n"; - scene << "model_asset = \"demo_cube\"\n"; - scene << "color = 0xFFFFFFFF\n"; - scene << "\n"; - } + ModelManager modelManager; + ShaderManager shaderManager; + TextureManager textureManager; + AssetManager assets; + assets.SetManagers(&modelManager, &shaderManager, nullptr, &textureManager); + assets.LoadRegistry("registry.toml"); - entt::entity root = LoadSceneFromFile(scenePath.string(), true); - TEST_CHECK(root != entt::null); + SetSceneContext(®istry, &modelManager, &shaderManager, &textureManager); + SetSceneAssetManager(&assets); - auto tagView = registry.view(); - entt::entity rootEntity = entt::null; - for (auto entity : tagView) { - const auto& tag = tagView.get(entity); - if (tag.name == "Root") { - rootEntity = entity; - break; + { + std::ofstream scene(scenePath); + scene << "[[entity]]\n"; + scene << "id = \"root\"\n"; + scene << "tag = \"Root\"\n"; + scene << "position = [0.0, 0.0, 0.0]\n"; + scene << "model_asset = \"demo_cube\"\n"; + scene << "color = 0xFFFFFFFF\n"; + scene << "\n"; + } + + entt::entity root = LoadSceneFromFile("scene_asset.toml", true); + TEST_CHECK(root != entt::null); + + auto tagView = registry.view(); + entt::entity rootEntity = entt::null; + for (auto entity : tagView) { + const auto& tag = tagView.get(entity); + if (tag.name == "Root") { + rootEntity = entity; + break; + } + } + + TEST_CHECK(rootEntity != entt::null); + if (rootEntity != entt::null) { + auto* renderer = registry.try_get(rootEntity); + TEST_CHECK(renderer != nullptr); + if (renderer) { + unsigned int expectedId = assets.GetModelId("demo_cube"); + TEST_CHECK(expectedId != 0); + TEST_CHECK(renderer->modelId == expectedId); + } } } - TEST_CHECK(rootEntity != entt::null); - if (rootEntity != entt::null) { - auto* renderer = registry.try_get(rootEntity); - TEST_CHECK(renderer != nullptr); - if (renderer) { - unsigned int expectedId = assets.GetModelId("demo_cube"); - TEST_CHECK(expectedId != 0); - TEST_CHECK(renderer->modelId == expectedId); - } - } + ShutdownRaylibHidden(); + + ShutdownPhysFSTest(); std::filesystem::remove(scenePath); std::filesystem::remove(registryPath); std::filesystem::remove(tmpDir); - - ShutdownRaylibHidden(); +} + +void test_scene_loader_rejects_escape(void) { + entt::registry registry; + ModelManager modelManager; + ShaderManager shaderManager; + TextureManager textureManager; + SetSceneContext(®istry, &modelManager, &shaderManager, &textureManager); + + std::filesystem::path tmpDir = std::filesystem::current_path() / "tmp_scene_sandbox"; + std::filesystem::create_directories(tmpDir); + std::filesystem::path outsidePath = std::filesystem::current_path() / "outside_scene.toml"; + + { + std::ofstream scene(outsidePath); + scene << "[[entity]]\n"; + scene << "id = \"root\"\n"; + scene << "tag = \"Root\"\n"; + } + + TEST_CHECK(InitPhysFSTest(tmpDir) == true); + TEST_CHECK(MountPhysFSTest(tmpDir, "") == true); + + entt::entity root = LoadSceneFromFile("../outside_scene.toml", true); + TEST_CHECK(root == entt::null); + + ShutdownPhysFSTest(); + + std::filesystem::remove(outsidePath); + std::filesystem::remove(tmpDir); } diff --git a/tests/scenegraph_tests.h b/tests/scenegraph_tests.h index a8c5958..bf404b9 100644 --- a/tests/scenegraph_tests.h +++ b/tests/scenegraph_tests.h @@ -4,3 +4,6 @@ void test_scenegraph_world_transform(void); void test_scenegraph_detach(void); void test_scene_loader_basic(void); void test_scene_loader_asset_keys(void); +void test_scene_loader_scene_script_path(void); +void test_scene_loader_clear_scene_script(void); +void test_scene_loader_rejects_escape(void); diff --git a/tests/script_engine_tests.cpp b/tests/script_engine_tests.cpp index 207822f..776c9e1 100644 --- a/tests/script_engine_tests.cpp +++ b/tests/script_engine_tests.cpp @@ -3,6 +3,7 @@ #include #include #include "../include/scripting/ScriptEngine.h" +#include "physfs_test_utils.h" void test_scriptengine_compile_and_call(void) { std::filesystem::path tmpDir = std::filesystem::current_path() / "tmp_script"; @@ -14,9 +15,12 @@ void test_scriptengine_compile_and_call(void) { ofs << "void Update(float dt) { g_x += dt * 10.0f; }\n"; } + TEST_CHECK(InitPhysFSTest(tmpDir) == true); + TEST_CHECK(MountPhysFSTest(tmpDir, "") == true); + ScriptEngine se; TEST_CHECK(se.Initialize() == true); - bool ok = se.CompileScript(script.string()); + bool ok = se.CompileScript("simple.as"); TEST_CHECK(ok == true); asIScriptFunction* upd = se.GetUpdateFunction(); TEST_CHECK(upd != nullptr); @@ -25,6 +29,8 @@ void test_scriptengine_compile_and_call(void) { se.Shutdown(); + ShutdownPhysFSTest(); + std::filesystem::remove(script); std::filesystem::remove(tmpDir); } @@ -46,12 +52,17 @@ void test_scriptengine_include(void) { ofsmain << "void Update(float dt) { Included(); }\n"; } + TEST_CHECK(InitPhysFSTest(tmpDir) == true); + TEST_CHECK(MountPhysFSTest(tmpDir, "") == true); + ScriptEngine se; TEST_CHECK(se.Initialize() == true); - bool ok = se.CompileScript(main.string()); + bool ok = se.CompileScript("main.as"); TEST_CHECK(ok == true); se.Shutdown(); + ShutdownPhysFSTest(); + std::filesystem::remove(inc); std::filesystem::remove(main); std::filesystem::remove(tmpDir); diff --git a/tests/test.cpp b/tests/test.cpp index 1c6a563..1cffdd5 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -17,6 +17,9 @@ TEST_LIST = { { "scenegraph_world", test_scenegraph_world_transform }, { "scenegraph_detach", test_scenegraph_detach }, { "scene_loader", test_scene_loader_basic }, + { "scene_loader_script_path", test_scene_loader_scene_script_path }, + { "scene_loader_clear_script", test_scene_loader_clear_scene_script }, { "scene_loader_assets", test_scene_loader_asset_keys }, + { "scene_loader_sandbox", test_scene_loader_rejects_escape }, { NULL, NULL } };