diff --git a/Bin2CPP/Sources/Bin2CPPLib/CMakeLists.txt b/Bin2CPP/Sources/Bin2CPPLib/CMakeLists.txt index c5f1e6c..5331509 100644 --- a/Bin2CPP/Sources/Bin2CPPLib/CMakeLists.txt +++ b/Bin2CPP/Sources/Bin2CPPLib/CMakeLists.txt @@ -20,13 +20,11 @@ target_sources(${PROJECT_NAME} ${SOURCES} ) -target_link_libraries(${PROJECT_NAME} PUBLIC EASTL::EASTL mimalloc) -target_link_libraries(${PROJECT_NAME} PRIVATE ${CMAKE_DL_LIBS}) -target_link_libraries(${PROJECT_NAME} PRIVATE $<$:cpptrace::cpptrace> quill::quill) +target_link_libraries(${PROJECT_NAME} PUBLIC EASTL::EASTL mimalloc quill::quill $<$:cpptrace::cpptrace>) target_compile_definitions(${PROJECT_NAME} - PUBLIC $<$:QUILL_NO_EXCEPTIONS> - PUBLIC $<$:QUILL_DISABLE_NON_PREFIXED_MACROS> + PUBLIC QUILL_NO_EXCEPTIONS + PUBLIC QUILL_DISABLE_NON_PREFIXED_MACROS PUBLIC MI_SHARED_LIB) diff --git a/Bin2CPP/Sources/Bin2CPPLib/GeneratedTemplate.hpp.in b/Bin2CPP/Sources/Bin2CPPLib/GeneratedTemplate.hpp.in index 3d8d9e1..8c280d8 100644 --- a/Bin2CPP/Sources/Bin2CPPLib/GeneratedTemplate.hpp.in +++ b/Bin2CPP/Sources/Bin2CPPLib/GeneratedTemplate.hpp.in @@ -1,11 +1,11 @@ -#ifndef {{GUARD_NAME}} -#define {{GUARD_NAME}} /** * Auto-generated header from: {{FILENAME}} * Generated by Bin2CPP * * DO NOT TOUCH */ +#ifndef {{GUARD_NAME}} +#define {{GUARD_NAME}} #include {{ARRAY_TYPE_INCLUDE}} #include diff --git a/Bin2CPP/Sources/Bin2CPPLib/Include/Assert.hpp b/Bin2CPP/Sources/Bin2CPPLib/Include/Assert.hpp new file mode 100644 index 0000000..2370756 --- /dev/null +++ b/Bin2CPP/Sources/Bin2CPPLib/Include/Assert.hpp @@ -0,0 +1,138 @@ +/********************************************************************* + * \file Assert.hpp + * + * \author Romain BOULLARD + * \date October 2025 + *********************************************************************/ +#ifndef BIGFOOT_SYSTEM_ASSERT_HPP +#define BIGFOOT_SYSTEM_ASSERT_HPP +#include + +#if defined BIN2CPP_NOT_OPTIMIZED + +#include + +#include +#include + +#if defined BIN2CPP_LINUX +#include +#endif + +namespace Bin2CPP +{ +class AssertHandler +{ + public: + AssertHandler() = delete; + + AssertHandler(const AssertHandler& p_handler) = delete; + AssertHandler(AssertHandler&& p_handler) = delete; + + ~AssertHandler() = delete; + + /** + * Handle an assertion. + * + * \param p_location Location of the assertion. + * \param p_stacktrace The stack trace + * \param p_format Format string for the assertion message. + * \param p_args Arguments for the format string. + */ + template + static void Handle(const std::source_location& p_location, + const std::string_view p_stacktrace, + std::format_string p_format, + ARGS&&... p_args) + { + BIN2CPP_LOG_FATAL("Assert: {} (File:{}, Line:{}, Function:{}\n{}", + std::format(p_format, std::forward(p_args)...), + p_location.file_name(), + p_location.line(), + p_location.function_name(), + p_stacktrace); + } + + AssertHandler& operator=(const AssertHandler& p_handler) = delete; + AssertHandler& operator=(AssertHandler&& p_handler) = delete; +}; +} // namespace Bin2CPP + +#if defined BIN2CPP_WINDOWS +#define BIN2CPP_BREAK \ + do \ + { \ + __debugbreak(); \ + } while (false) +#elif defined BIN2CPP_LINUX +#define BIN2CPP_BREAK \ + do \ + { \ + std::raise(SIGTRAP); \ + } while (false) +#endif + +#define BIN2CPP_ASSERT(p_assert, p_message, ...) \ + do \ + { \ + constexpr std::source_location location = std::source_location::current(); \ + if (!(p_assert)) [[unlikely]] \ + { \ + constexpr auto stacktrace = []() -> std::string \ + { \ + const cpptrace::stacktrace stacktrace = cpptrace::generate_trace(); \ + return stacktrace.to_string(); \ + }; \ + \ + Bin2CPP::AssertHandler::Handle(location, stacktrace(), p_message __VA_OPT__(, ) __VA_ARGS__); \ + BIN2CPP_BREAK; \ + } \ + } while (false) + +#define BIN2CPP_SOFT_ASSERT(p_assert, p_message, ...) \ + do \ + { \ + constexpr std::source_location location = std::source_location::current(); \ + if (!(p_assert)) [[unlikely]] \ + { \ + constexpr auto stacktrace = []() -> std::string \ + { \ + const cpptrace::stacktrace stacktrace = cpptrace::generate_trace(); \ + return stacktrace.to_string(); \ + }; \ + \ + Bin2CPP::AssertHandler::Handle(location, stacktrace(), p_message __VA_OPT__(, ) __VA_ARGS__); \ + BIN2CPP_BREAK; \ + } \ + } while (false) + +#define BIN2CPP_CRITICAL_ASSERT(p_assert, p_message, ...) \ + do \ + { \ + constexpr std::source_location location = std::source_location::current(); \ + if (!(p_assert)) [[unlikely]] \ + { \ + constexpr auto stacktrace = []() -> std::string \ + { \ + const cpptrace::stacktrace stacktrace = cpptrace::generate_trace(); \ + return stacktrace.to_string(); \ + }; \ + \ + Bin2CPP::AssertHandler::Handle(location, stacktrace(), p_message __VA_OPT__(, ) __VA_ARGS__); \ + if (Bin2CPP::Singleton::HasInstance()) \ + { \ + Bin2CPP::Singleton::Instance().Flush(); \ + } \ + BIN2CPP_BREAK; \ + std::abort(); \ + } \ + } while (false) + +#else +#define BIN2CPP_ASSERT(p_assert, p_message, ...) + +#define BIN2CPP_SOFT_ASSERT(p_assert, p_message, ...) + +#define BIN2CPP_CRITICAL_ASSERT(p_assert, p_message, ...) +#endif +#endif diff --git a/Bin2CPP/Sources/Bin2CPPLib/Include/Bin2CPPLib/Assert.hpp b/Bin2CPP/Sources/Bin2CPPLib/Include/Bin2CPPLib/Assert.hpp deleted file mode 100644 index e69de29..0000000 diff --git a/Bin2CPP/Sources/Bin2CPPLib/Include/Bin2CPPLib/Log.hpp b/Bin2CPP/Sources/Bin2CPPLib/Include/Bin2CPPLib/Log.hpp deleted file mode 100644 index e69de29..0000000 diff --git a/Bin2CPP/Sources/Bin2CPPLib/Include/EASTLFormatters.hpp b/Bin2CPP/Sources/Bin2CPPLib/Include/EASTLFormatters.hpp new file mode 100644 index 0000000..2fbd09d --- /dev/null +++ b/Bin2CPP/Sources/Bin2CPPLib/Include/EASTLFormatters.hpp @@ -0,0 +1,87 @@ +/********************************************************************* + * \file EASTLFormatters.hpp + * + * \author Romain BOULLARD + * \date February 2026 + *********************************************************************/ +#ifndef BIN2CPP_EASTLFORMATTERS_HPP +#define BIN2CPP_EASTLFORMATTERS_HPP +#include + +#include + +#include +#include + +// STRING + +template<> +struct std::formatter +{ + constexpr auto parse(std::format_parse_context& ctx) + { + return ctx.begin(); + } + + template + auto format(const eastl::string& p_string, FormatContext& ctx) const + { + return std::format_to(ctx.out(), "{}", p_string.c_str()); + } +}; + +template<> +struct fmtquill::formatter +{ + constexpr auto parse(format_parse_context& ctx) + { + return ctx.begin(); + } + + auto format(const eastl::string& p_string, format_context& ctx) const + { + return fmtquill::format_to(ctx.out(), "{}", p_string.c_str()); + } +}; + +template<> +struct quill::Codec: quill::DeferredFormatCodec +{ +}; + +// STRING_VIEW + +template<> +struct std::formatter +{ + constexpr auto parse(std::format_parse_context& ctx) + { + return ctx.begin(); + } + + template + auto format(const eastl::string_view& p_stringView, FormatContext& ctx) const + { + return std::format_to(ctx.out(), "{}", p_stringView.data()); + } +}; + +template<> +struct fmtquill::formatter +{ + constexpr auto parse(format_parse_context& ctx) + { + return ctx.begin(); + } + + auto format(const eastl::string_view& p_stringView, format_context& ctx) const + { + return fmtquill::format_to(ctx.out(), "{}", p_stringView.data()); + } +}; + +template<> +struct quill::Codec: quill::DeferredFormatCodec +{ +}; +#endif diff --git a/Bin2CPP/Sources/Bin2CPPLib/Include/Bin2CPPLib/Generator.hpp b/Bin2CPP/Sources/Bin2CPPLib/Include/Generator.hpp similarity index 100% rename from Bin2CPP/Sources/Bin2CPPLib/Include/Bin2CPPLib/Generator.hpp rename to Bin2CPP/Sources/Bin2CPPLib/Include/Generator.hpp diff --git a/Bin2CPP/Sources/Bin2CPPLib/Include/Log.hpp b/Bin2CPP/Sources/Bin2CPPLib/Include/Log.hpp new file mode 100644 index 0000000..4e90d38 --- /dev/null +++ b/Bin2CPP/Sources/Bin2CPPLib/Include/Log.hpp @@ -0,0 +1,116 @@ +/********************************************************************* + * \file Log.hpp + * + * \author Romain BOULLARD + * \date February 2026 + *********************************************************************/ +#ifndef BIN2CPP_LOG_HPP +#define BIN2CPP_LOG_HPP +#include +#include + +#include + +#ifdef BIGFOOT_WINDOWS +#pragma warning(disable: 4702) +#endif +#include +#include +#include +#include +#include +#if defined BIGFOOT_WINDOWS +#pragma warning(default: 4702) +#endif + +namespace Bin2CPP +{ +class Log +{ + public: + Log(); + + Log(const Log& p_logger) = delete; + Log(Log&& p_logger) = delete; + + /** + * Register a logger. + * + * \return The logger, nullptr if it does not exist + */ + [[nodiscard]] + quill::Logger* GetLogger(); + + /* + * Flush all the loggers + * + */ + void Flush(); + + ~Log(); + + Log& operator=(const Log& p_logger) = delete; + Log& operator=(Log&& p_logger) = delete; + + private: + /* + * The sinks + */ + eastl::array, 1> m_sinks; +}; +} // namespace Bin2CPP + +#define BIN2CPP_LOG_DEBUG(fmt, ...) \ + do \ + { \ + if (quill::Logger* logger = Bin2CPP::Singleton::Instance().GetLogger()) \ + { \ + QUILL_LOG_DEBUG(logger, fmt __VA_OPT__(, ) __VA_ARGS__); \ + } \ + } while (0) + +#define BIN2CPP_LOG_TRACE(fmt, ...) \ + do \ + { \ + if (quill::Logger* logger = Bin2CPP::Singleton::Instance().GetLogger()) \ + { \ + QUILL_LOG_TRACE_L3(logger, fmt __VA_OPT__(, ) __VA_ARGS__); \ + } \ + } while (0) + +#define BIN2CPP_LOG_INFO(fmt, ...) \ + do \ + { \ + if (quill::Logger* logger = Bin2CPP::Singleton::Instance().GetLogger()) \ + { \ + QUILL_LOG_INFO(logger, fmt __VA_OPT__(, ) __VA_ARGS__); \ + } \ + } while (0) + +#define BIN2CPP_LOG_WARN(fmt, ...) \ + do \ + { \ + if (quill::Logger* logger = Bin2CPP::Singleton::Instance().GetLogger()) \ + { \ + QUILL_LOG_WARNING(logger, fmt __VA_OPT__(, ) __VA_ARGS__); \ + } \ + } while (0) + +#define BIN2CPP_LOG_ERROR(fmt, ...) \ + do \ + { \ + if (quill::Logger* logger = Bin2CPP::Singleton::Instance().GetLogger()) \ + { \ + QUILL_LOG_ERROR(logger, fmt __VA_OPT__(, ) __VA_ARGS__); \ + } \ + } while (0) + +#define BIN2CPP_LOG_FATAL(fmt, ...) \ + do \ + { \ + if (quill::Logger* logger = Bin2CPP::Singleton::Instance().GetLogger()) \ + { \ + QUILL_LOG_CRITICAL(logger, fmt __VA_OPT__(, ) __VA_ARGS__); \ + } \ + } while (0) +#endif diff --git a/Bin2CPP/Sources/Bin2CPPLib/Include/Singleton.hpp b/Bin2CPP/Sources/Bin2CPPLib/Include/Singleton.hpp new file mode 100644 index 0000000..3fc8f3b --- /dev/null +++ b/Bin2CPP/Sources/Bin2CPPLib/Include/Singleton.hpp @@ -0,0 +1,104 @@ +/********************************************************************* + * \file Singleton.hpp + * + * \author Romain BOULLARD + * \date February 2026 + *********************************************************************/ +#ifndef BIN2CPP_SINGLETON_HPP +#define BIN2CPP_SINGLETON_HPP +#include + +namespace Bin2CPP +{ +template +class Singleton +{ + public: + Singleton() = delete; + + Singleton(const Singleton& p_singleton) = delete; + Singleton(Singleton&& p_singleton) = delete; + + ~Singleton() = delete; + + /** + * Get the instance. + * + * \return The instance + */ + static constexpr TYPE& Instance() + { + return ms_instance.value(); + } + + /** + * Is the instance initialized + * + * \return True if initialized, false otherwise + */ + static constexpr bool HasInstance() + { + return ms_instance.has_value(); + } + + class Lifetime + { + public: + /** + * Constructor. + * + * \param p_args Arguments for the singleton + */ + template + explicit Lifetime(ARGS&&... p_args) + { + Initialize(std::forward(p_args)...); + } + + Lifetime(const Lifetime& p_lifetime) = delete; + Lifetime(Lifetime&& p_lifetime) = delete; + + ~Lifetime() + { + Finalize(); + } + + [[nodiscard]] + Lifetime& operator=(const Lifetime& p_lifetime) = delete; + [[nodiscard]] + Lifetime& operator=(Lifetime&& p_lifetime) = delete; + }; + + [[nodiscard]] + Singleton& operator=(const Singleton& p_singleton) = delete; + [[nodiscard]] + Singleton& operator=(Singleton&& p_singleton) = delete; + + private: + /** + * Initialize the singleton. + * + * \param p_args Arguments for the singleton + */ + template + static void Initialize(ARGS&&... p_args) + { + ms_instance.emplace(std::forward(p_args)...); + } + + /** + * Finalize the singleton. + * + */ + static void Finalize() + { + ms_instance.reset(); + } + + /** + * The singleton. + */ + inline static eastl::optional ms_instance; +}; +} // namespace Bin2CPP +#endif diff --git a/Bin2CPP/Sources/Bin2CPPLib/Log.cpp b/Bin2CPP/Sources/Bin2CPPLib/Log.cpp index e69de29..525a093 100644 --- a/Bin2CPP/Sources/Bin2CPPLib/Log.cpp +++ b/Bin2CPP/Sources/Bin2CPPLib/Log.cpp @@ -0,0 +1,49 @@ +/******************************************************************* + * \file Log.cpp + * + * \author Romain BOULLARD + * \date February 2026 + *********************************************************************/ +#include + +namespace Bin2CPP +{ +Log::Log() +{ + quill::Backend::start(); + + m_sinks[0] = quill::Frontend::create_or_get_sink("ConsoleSink"); + + quill::Logger* logger = quill::Frontend::create_or_get_logger("Bin2CPP", m_sinks[0]); + logger->set_log_level(quill::LogLevel::TraceL3); +} + +/****************************************************************************************/ + +quill::Logger* Log::GetLogger() +{ + return quill::Frontend::get_logger("Bin2CPP"); +} + +/****************************************************************************************/ + +void Log::Flush() +{ + for (quill::Logger* logger: quill::Frontend::get_all_loggers()) + { + logger->flush_log(); + } +} + +/****************************************************************************************/ + +Log::~Log() +{ + for (quill::Logger* logger: quill::Frontend::get_all_loggers()) + { + quill::Frontend::remove_logger(logger); + } + + quill::Backend::stop(); +} +} // namespace Bin2CPP diff --git a/Bin2CPP/Tests/Bin2CPPLib/Assert.cpp b/Bin2CPP/Tests/Bin2CPPLib/Assert.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/Bin2CPP/Tests/Bin2CPPLib/Log.cpp b/Bin2CPP/Tests/Bin2CPPLib/Log.cpp index e69de29..47dabe7 100644 --- a/Bin2CPP/Tests/Bin2CPPLib/Log.cpp +++ b/Bin2CPP/Tests/Bin2CPPLib/Log.cpp @@ -0,0 +1,39 @@ +/********************************************************************* + * \file Singleton.cpp + * + * \author Romain BOULLARD + * \date February 2026 + *********************************************************************/ +#include + +#include + +namespace Bin2CPP +{ +class SingletonFixture: public ::testing::Test +{ + protected: + Singleton::Lifetime m_lifetime{8}; +}; + +/****************************************************************************************/ + +TEST_F(SingletonFixture, HasInstance_ShouldReturnTrueIfSingletonIsInitialized) +{ + EXPECT_TRUE(Singleton::HasInstance()); +} + +/****************************************************************************************/ + +TEST_F(SingletonFixture, HasInstance_ShouldReturnFaleIfSingletonIsNotInitialized) +{ + EXPECT_FALSE(Singleton::HasInstance()); +} + +/****************************************************************************************/ + +TEST_F(SingletonFixture, Instance_ShouldReturnTheInstance) +{ + EXPECT_EQ(Singleton::Instance(), 8); +} +} // namespace Bin2CPP diff --git a/Bin2CPP/Tests/Bin2CPPLib/Singleton.cpp b/Bin2CPP/Tests/Bin2CPPLib/Singleton.cpp new file mode 100644 index 0000000..32421e9 --- /dev/null +++ b/Bin2CPP/Tests/Bin2CPPLib/Singleton.cpp @@ -0,0 +1,3 @@ +// +// Created by romain on 16/02/2026. +// diff --git a/format.sh b/format.sh old mode 100644 new mode 100755 diff --git a/generate_bin2cpp.sh b/generate_bin2cpp.sh old mode 100644 new mode 100755 diff --git a/generate_dependencies.sh b/generate_dependencies.sh old mode 100644 new mode 100755