From a5dc639958de5864282063aa6981b307807a7a98 Mon Sep 17 00:00:00 2001 From: NaifBanana <30419422+NaifBanana@users.noreply.github.com> Date: Sun, 19 Apr 2026 18:08:58 -0500 Subject: [PATCH] Added type traits and string utils --- engine/NBCore/CMakeLists.txt | 2 + engine/NBCore/DataSink.hpp | 2 +- engine/NBCore/Errors.hpp | 34 ++----- engine/NBCore/Logger.hpp | 40 +++++--- engine/NBCore/StringUtils.hpp | 142 +++++++++++++++++++++++++++++ engine/NBCore/TypeTraits.hpp | 38 +++++++- engine/NBCore/Utils.hpp | 72 --------------- engine/NBCore/src/Logger.cpp | 2 + engine/NBCore/src/StringUtils.cpp | 1 + engine/NBCore/src/Utils.cpp | 7 -- engine/NBCore/tests/testErrors.cpp | 1 - engine/NBCore/tests/testUtils.cpp | 2 +- 12 files changed, 218 insertions(+), 125 deletions(-) create mode 100644 engine/NBCore/StringUtils.hpp create mode 100644 engine/NBCore/src/StringUtils.cpp diff --git a/engine/NBCore/CMakeLists.txt b/engine/NBCore/CMakeLists.txt index b457870..9f67cd0 100644 --- a/engine/NBCore/CMakeLists.txt +++ b/engine/NBCore/CMakeLists.txt @@ -2,6 +2,7 @@ toAbsolutePath(NB_CORE_SOURCE ./src/Errors.cpp # ./src/Logger.cpp ./src/Processes.cpp + ./src/StringUtils.cpp ./src/Utils.cpp ) @@ -11,6 +12,7 @@ toAbsolutePath(NB_CORE_INCLUDE ./Errors.hpp ./Logger.hpp ./Processes.hpp + ./StringUtils.hpp ./ThreadsafeQueue.hpp ./Types.hpp ./TypeTraits.hpp diff --git a/engine/NBCore/DataSink.hpp b/engine/NBCore/DataSink.hpp index 75cbad6..3aa0c50 100644 --- a/engine/NBCore/DataSink.hpp +++ b/engine/NBCore/DataSink.hpp @@ -77,7 +77,7 @@ public: bool isRunning() const noexcept override { return this->_running && (_runningThread!=nullptr); } - bool run() { + bool run() override { if (!type_ptr->isRunning()) { this->_running = true; _runningThread = std::make_shared([&]{ diff --git a/engine/NBCore/Errors.hpp b/engine/NBCore/Errors.hpp index e406347..d36f749 100644 --- a/engine/NBCore/Errors.hpp +++ b/engine/NBCore/Errors.hpp @@ -9,23 +9,7 @@ #include #include "TypeTraits.hpp" #include -#include "Utils.hpp" - -/* #ifndef THROW_WITH_INFO - #ifdef CODE_ERROR_LOCATIONS - #define THROW_WITH_INFO(type, ...) throw type(__VA_ARGS__, __LINE__, __FILE__) - #else - #define THROW_WITH_INFO(type, ...) throw type(__VA_ARGS__) - #endif // CODE_ERROR_LOCATIONS -#endif // THROW_WITH_INFO - -#ifndef THROW - #ifdef LOGGING - #define THROW_WTIH_INFO(type, ...) throw type(__VA_ARGS__, __LINE__, __FILE__) - #else - #define THROW(...) THROW_WITH_INFO(__VA_ARGS__) - #endif // LOGGING -#endif // THROW */ +#include "StringUtils.hpp" namespace nb { @@ -83,9 +67,9 @@ public: ErrorBase& operator=(const ErrorBase&) = delete; virtual inline std::string str() const noexcept override { - std::string ret = msg; + std::string ret = msg + nb::NEWLINE; if (trace) { - const std::string replace = nb::NEWLINE+" "; + const std::string tabover = " "; std::string trace_msg; if (traceIsNBError) { trace_msg = std::static_pointer_cast(trace)->str(); @@ -95,13 +79,9 @@ public: } else { trace_msg = std::string(trace->what()); } - ret += replace + "Trace: " + find_and_replace( - trace_msg, - nb::NEWLINE, - replace - ); + ret += indent_strblock(trace_msg, tabover, tabover+"Trace: ")+nb::NEWLINE; } - return ret + nb::NEWLINE; + return ret; } static const std::string type; @@ -226,6 +206,7 @@ public: using Base::code; using Base::msg; using Base::trace; + using Base::traceIsNBError; using Base::type; using Base::ErrorMessages; @@ -245,10 +226,11 @@ public: using Base::str; using Base::what; + using Base::code; using Base::msg; using Base::trace; - + using Base::traceIsNBError; static const std::string type; static const ErrorCodeMap ErrorMessages; }; diff --git a/engine/NBCore/Logger.hpp b/engine/NBCore/Logger.hpp index e767eea..40919f6 100644 --- a/engine/NBCore/Logger.hpp +++ b/engine/NBCore/Logger.hpp @@ -2,15 +2,28 @@ #ifndef _NB_LOGGER #define _NB_LOGGER -#include #include -#include #include #include -#include #include #include +#ifndef THROW_WITH_INFO + #ifdef CODE_ERROR_LOCATIONS + #define THROW_WITH_INFO(type, ...) throw type(__VA_ARGS__, __LINE__, __FILE__) + #else + #define THROW_WITH_INFO(type, ...) throw type(__VA_ARGS__) + #endif // CODE_ERROR_LOCATIONS +#endif // THROW_WITH_INFO + +#ifndef THROW + #ifdef LOGGING + #define THROW_WTIH_INFO(type, ...) throw type(__VA_ARGS__, __LINE__, __FILE__) + #else + #define THROW(...) THROW_WITH_INFO(__VA_ARGS__) + #endif // LOGGING +#endif // THROW + #include "DataSink.hpp" #include "Processes.hpp" #include "ThreadSafeQueue.hpp" @@ -23,14 +36,6 @@ typedef std::chrono::time_point< std::chrono::nanoseconds > LoggerTimePoint; -struct LogEvent{ - const LoggerTimePoint time; - const unsigned char lvl; - const std::string msg; - const std::thread::id tid; - const uint64_t pid; -}; - typedef std::string (*LogProcessFunction)(const LoggerTimePoint&, const std::string&); typedef std::unordered_map LogProcessFunctionMap; @@ -41,7 +46,7 @@ class LoggerBase using LoggerType = Logger; using Base = MultithreadedDataProcessor; public: - bool run() { + bool run() override { if (!type_ptr->isRunning()) { this->_running = true; this->_runningThread = std::make_shared([&]{ @@ -62,6 +67,14 @@ private: LoggerType* type_ptr = static_cast(this); }; +struct LogEvent{ + const LoggerTimePoint time; + const unsigned char lvl; + const std::string msg; + const std::thread::id tid; + const uint64_t pid; +}; + template class DebugLogger : public LoggerBase>{ using StreamType = std::vector; @@ -90,7 +103,7 @@ public: } void log(const std::exception& err, const uint8_t& lvl=0xFF) { - type_ptr->log(err.what(), lvl); + type_ptr->log(prepend_strblock(err.what(), " "), lvl); } template @@ -104,7 +117,6 @@ protected: private: LoggerType* type_ptr = static_cast(this); - }; class DefaultDebugLogger : public DebugLogger { diff --git a/engine/NBCore/StringUtils.hpp b/engine/NBCore/StringUtils.hpp new file mode 100644 index 0000000..a8cab98 --- /dev/null +++ b/engine/NBCore/StringUtils.hpp @@ -0,0 +1,142 @@ +#pragma once +#ifndef _NB_CORE_TYPES +#define _NB_CORE_TYPES + +#include +#include +#include + +#include "TypeTraits.hpp" + +namespace nb { + +#ifdef _NB_TARGET_WINDOWS + const std::string NEWLINE = "\n"; + const std::wstring WNEWLINE = L"\n"; +#endif // _NB_TARGET_WINDOWS +#ifdef _NB_TARGET_LINUX + const std::string NEWLINE = "\n"; + const std::wstring WNEWLINE = L"\n"; +#endif // _NB_TARGET_LINUX + +template +using StringConvertible = ValidConversion; + +template +using WStringConvertible = ValidConversion; + +template +constexpr bool StringConvertible_v = StringConvertible::value; + +template +constexpr bool WStringConvertible_v = WStringConvertible::value; + +template +using StringConvertible_to = typename StringConvertible::to; + +template +using WStringConvertible_to = typename WStringConvertible::to; + +template +using StringConvertible_from = typename StringConvertible::from; + +template +using WStringConvertible_from = typename WStringConvertible::from; + +template +std::enable_if_t, std::wstring> str_to_wstr(T in) { + std::string str(in); + std::wstring ret(str.begin(), str.end()); + return ret; +} + +template +std::enable_if_t, std::string> wstr_to_str(T in) { + std::wstring wstr(in); + std::size_t wstrlen = wstr.length(); + char* c_str= new char[wstrlen]; + std::wcstombs(c_str, wstr.c_str(), wstrlen); + std::string ret(c_str, wstrlen); + delete[] c_str; + return ret; +} + +template +void stream(Stream& s, Args&&... args); + +template +void stream(Stream& s, Args&&... args) { + (s << ... << args); +} + +template +void term(Args&&... args) { stream(std::cout, args..., nb::NEWLINE); } + +template +void wterm(Args&&... args) { stream(std::wcout, args..., nb::WNEWLINE); } + +template +ValidConversion_to find_and_replace( + A original, + B find, + C replace +) { + const T& find_t = T(find); + const T& replace_t = T(replace); + + T ret(original); + + std::size_t find_len = find_t.length(); + std::size_t replace_len = replace_t.length(); + std::size_t currpos = 0; + while(true) { + currpos = ret.find(find_t, currpos); + if (currpos == T::npos) { + break; + } + ret = ret.erase(currpos, find_len); + ret = ret.insert(currpos, replace_t); + currpos += replace_len; + } + return ret; +} + +template +StringConvertible_to indent_strblock( + A block, + B prepend, + C topIndent +) { + return std::string(topIndent) + find_and_replace( + std::string(block), + nb::NEWLINE, + nb::NEWLINE + std::string(prepend) + ); +} + +template +StringConvertible_to indent_strblock( + A block, + B prepend +) { + return indent_strblock(block, prepend, prepend); +} + +/* template +T swap_endian(const T& val) { + T ret; + const int size = sizeof(T); + auto retLoc = static_cast(&ret); + auto valLoc = static_cast(&val); + + for (int i = 0; i < size; ++i) { + memcpy(retLoc+i, valLoc+(size-i-1), 1); + } + return ret; +} */ + + +// using ByteVector = std::vector; + +} // namespace nb +#endif // _NB_CORE_TYPES \ No newline at end of file diff --git a/engine/NBCore/TypeTraits.hpp b/engine/NBCore/TypeTraits.hpp index 5277159..f92df9a 100644 --- a/engine/NBCore/TypeTraits.hpp +++ b/engine/NBCore/TypeTraits.hpp @@ -2,7 +2,9 @@ #ifndef _NB_TYPE_TRAITS #define _NB_TYPE_TRAITS +#include #include +#include namespace nb { @@ -37,11 +39,41 @@ template < > using is_detected = typename detail::detector::value; -/*template +template +struct ValidConversion; + +template +struct ValidConversion { + typedef std::conjunction< + std::is_constructible, std::is_constructible, std::conjunction...> + > value_type; + static constexpr bool value = value_type::value; + typedef std::enable_if_t to; + +}; + +template +struct ValidConversion { + typedef std::is_constructible value_type; + static constexpr bool value = value_type::value; + typedef std::enable_if_t to; + typedef std::enable_if_t from; +}; + +template +using ValidConversion_v = typename ValidConversion::value; + +template +using ValidConversion_to = typename ValidConversion::to; + +template +using ValidConversion_from = typename ValidConversion::from; + +template inline typename std::enable_if::type ForEach(std::tuple&, Func) {} -template +template inline typename std::enable_if::type ForEach(std::tuple& tup, Func f) { f(N, std::get(tup)); @@ -99,7 +131,7 @@ struct PackIsSameType { template struct PackIsSameType { const bool value = std::is_base_of::value && PackIsSameType::value; -};*/ +}; } // namespace nb diff --git a/engine/NBCore/Utils.hpp b/engine/NBCore/Utils.hpp index 01d6dac..a8d47a5 100644 --- a/engine/NBCore/Utils.hpp +++ b/engine/NBCore/Utils.hpp @@ -2,80 +2,8 @@ #ifndef _NB_CORE_TYPES #define _NB_CORE_TYPES -#include -#include -#include - namespace nb { -#ifdef _NB_TARGET_WINDOWS - const std::string NEWLINE = "\n"; - const std::wstring WNEWLINE = L"\n"; -#endif // _NB_TARGET_WINDOWS -#ifdef _NB_TARGET_LINUX - const std::string NEWLINE = "\n"; - const std::wstring WNEWLINE = L"\n"; -#endif // _NB_TARGET_LINUX - -template -std::enable_if_t, std::wstring> str_to_wstr(T in) { - std::string str(in); - std::wstring ret(str.begin(), str.end()); - return ret; -} - -template -std::enable_if_t, std::string> wstr_to_str(T in) { - std::wstring wstr(in); - std::size_t wstrlen = wstr.length(); - char* c_str= new char[wstrlen]; - std::wcstombs(c_str, wstr.c_str(), wstrlen); - std::string ret(c_str, wstrlen); - delete[] c_str; - return ret; -} - -template -void stream(Stream& s, Args&&... args); - -template -void stream(Stream& s, Args&&... args) { - (s << ... << args); -} - -template -void term(Args&&... args) { stream(std::cout, args..., nb::NEWLINE); } - -template -void wterm(Args&&... args) { stream(std::wcout, args..., nb::WNEWLINE); } - -template -T find_and_replace( - A original, - B find, - C replace -) { - const T& original_t = T(original); - const T& find_t = T(find); - const T& replace_t = T(replace); - - T ret = original_t; - - std::size_t find_len = find_t.length(); - std::size_t replace_len = replace_t.length(); - std::size_t currpos = 0; - while(true) { - currpos = ret.find(find_t, currpos); - if (currpos == T::npos) { - break; - } - ret = ret.erase(currpos, find_len); - ret = ret.insert(currpos, replace_t); - currpos += replace_len; - } - return ret; -} - /* template T swap_endian(const T& val) { T ret; diff --git a/engine/NBCore/src/Logger.cpp b/engine/NBCore/src/Logger.cpp index 1deed87..042fdaf 100644 --- a/engine/NBCore/src/Logger.cpp +++ b/engine/NBCore/src/Logger.cpp @@ -10,6 +10,8 @@ static bool RUN_LOGGER(nb::DefaultDebugLogger& log) { return log.run(); } + + static const bool LOGGER_RUNNING = RUN_LOGGER(logger); } // namespace nb \ No newline at end of file diff --git a/engine/NBCore/src/StringUtils.cpp b/engine/NBCore/src/StringUtils.cpp new file mode 100644 index 0000000..44f97f5 --- /dev/null +++ b/engine/NBCore/src/StringUtils.cpp @@ -0,0 +1 @@ +#include "StringUtils.hpp" diff --git a/engine/NBCore/src/Utils.cpp b/engine/NBCore/src/Utils.cpp index 336d3b6..8b13789 100644 --- a/engine/NBCore/src/Utils.cpp +++ b/engine/NBCore/src/Utils.cpp @@ -1,8 +1 @@ -#include -#include "Utils.hpp" -template<> -std::wstring nb::str_to_wstr(const std::string& in) { - std::wstring ret(in.begin(), in.end()); - return ret; -} diff --git a/engine/NBCore/tests/testErrors.cpp b/engine/NBCore/tests/testErrors.cpp index 81187be..1e919aa 100644 --- a/engine/NBCore/tests/testErrors.cpp +++ b/engine/NBCore/tests/testErrors.cpp @@ -4,7 +4,6 @@ #include "Errors.hpp" #include -#include "Utils.hpp" using namespace nb; diff --git a/engine/NBCore/tests/testUtils.cpp b/engine/NBCore/tests/testUtils.cpp index e097788..24ca054 100644 --- a/engine/NBCore/tests/testUtils.cpp +++ b/engine/NBCore/tests/testUtils.cpp @@ -4,7 +4,7 @@ #include #include "TypeTraits.hpp" -#include "Utils.hpp" +#include "StringUtils.hpp" namespace nb {