diff options
| author | Stefan Boberg <[email protected]> | 2021-09-15 19:49:20 +0200 |
|---|---|---|
| committer | Stefan Boberg <[email protected]> | 2021-09-15 19:49:20 +0200 |
| commit | 83ccd52321a23c8f1c8a3228cbbf34b8f199a22b (patch) | |
| tree | 9cf1fb68651f616aef2fa28000e4f328ef9204d8 /zencore/include | |
| parent | Added GetSize/GetData functions to reduce cognitive load and bridge the gap b... (diff) | |
| parent | Tweaked logging to streamline access, and simplified setup code for new loggers (diff) | |
| download | zen-83ccd52321a23c8f1c8a3228cbbf34b8f199a22b.tar.xz zen-83ccd52321a23c8f1c8a3228cbbf34b8f199a22b.zip | |
Merge branch 'main' into cbpackage-update
Diffstat (limited to 'zencore/include')
| -rw-r--r-- | zencore/include/zencore/atomic.h | 31 | ||||
| -rw-r--r-- | zencore/include/zencore/compactbinary.h | 2 | ||||
| -rw-r--r-- | zencore/include/zencore/compactbinarybuilder.h | 2 | ||||
| -rw-r--r-- | zencore/include/zencore/endian.h | 12 | ||||
| -rw-r--r-- | zencore/include/zencore/except.h | 37 | ||||
| -rw-r--r-- | zencore/include/zencore/fmtutils.h | 2 | ||||
| -rw-r--r-- | zencore/include/zencore/intmath.h | 52 | ||||
| -rw-r--r-- | zencore/include/zencore/iohash.h | 1 | ||||
| -rw-r--r-- | zencore/include/zencore/logging.h | 27 | ||||
| -rw-r--r-- | zencore/include/zencore/memory.h | 32 | ||||
| -rw-r--r-- | zencore/include/zencore/sharedbuffer.h | 2 | ||||
| -rw-r--r-- | zencore/include/zencore/string.h | 10 | ||||
| -rw-r--r-- | zencore/include/zencore/thread.h | 8 | ||||
| -rw-r--r-- | zencore/include/zencore/timer.h | 10 | ||||
| -rw-r--r-- | zencore/include/zencore/zencore.h | 68 |
15 files changed, 252 insertions, 44 deletions
diff --git a/zencore/include/zencore/atomic.h b/zencore/include/zencore/atomic.h index 457128bd4..7e261771b 100644 --- a/zencore/include/zencore/atomic.h +++ b/zencore/include/zencore/atomic.h @@ -2,7 +2,14 @@ #pragma once +#include <zencore/zencore.h> + +#if ZEN_COMPILER_MSC #include <intrin.h> +#else +#include <atomic> +#endif + #include <cinttypes> namespace zen { @@ -10,34 +17,58 @@ namespace zen { inline uint32_t AtomicIncrement(volatile uint32_t& value) { +#if ZEN_COMPILER_MSC return _InterlockedIncrement((long volatile*)&value); +#else + return ((std::atomic<uint32_t>*)(&value))->fetch_add(1, std::memory_order_seq_cst) + 1; +#endif } inline uint32_t AtomicDecrement(volatile uint32_t& value) { +#if ZEN_COMPILER_MSC return _InterlockedDecrement((long volatile*)&value); +#else + return ((std::atomic<uint32_t>*)(&value))->fetch_sub(1, std::memory_order_seq_cst) - 1; +#endif } inline uint64_t AtomicIncrement(volatile uint64_t& value) { +#if ZEN_COMPILER_MSC return _InterlockedIncrement64((__int64 volatile*)&value); +#else + return ((std::atomic<uint64_t>*)(&value))->fetch_add(1, std::memory_order_seq_cst) + 1; +#endif } inline uint64_t AtomicDecrement(volatile uint64_t& value) { +#if ZEN_COMPILER_MSC return _InterlockedDecrement64((__int64 volatile*)&value); +#else + return ((std::atomic<uint64_t>*)(&value))->fetch_sub(1, std::memory_order_seq_cst) - 1; +#endif } inline uint32_t AtomicAdd(volatile uint32_t& value, uint32_t amount) { +#if ZEN_COMPILER_MSC return _InterlockedExchangeAdd((long volatile*)&value, amount); +#else + return ((std::atomic<uint32_t>*)(&value))->fetch_add(amount, std::memory_order_seq_cst); +#endif } inline uint64_t AtomicAdd(volatile uint64_t& value, uint64_t amount) { +#if ZEN_COMPILER_MSC return _InterlockedExchangeAdd64((__int64 volatile*)&value, amount); +#else + return ((std::atomic<uint64_t>*)(&value))->fetch_add(amount, std::memory_order_seq_cst); +#endif } } // namespace zen diff --git a/zencore/include/zencore/compactbinary.h b/zencore/include/zencore/compactbinary.h index 09619be8b..4fce129ea 100644 --- a/zencore/include/zencore/compactbinary.h +++ b/zencore/include/zencore/compactbinary.h @@ -748,6 +748,8 @@ private: friend class CbFieldViewIterator; + friend class CbFieldIterator; + /** Pointer to the first byte past the end of the last field. Set to null at the end. */ const void* FieldsEnd = nullptr; }; diff --git a/zencore/include/zencore/compactbinarybuilder.h b/zencore/include/zencore/compactbinarybuilder.h index f7f2bbfd3..5f6d9fd0c 100644 --- a/zencore/include/zencore/compactbinarybuilder.h +++ b/zencore/include/zencore/compactbinarybuilder.h @@ -533,7 +533,7 @@ operator<<(CbWriter& Writer, const CbArray& Value) } inline CbWriter& -operator<<(CbWriter& Writer, nullptr_t) +operator<<(CbWriter& Writer, std::nullptr_t) { Writer.AddNull(); return Writer; diff --git a/zencore/include/zencore/endian.h b/zencore/include/zencore/endian.h index 1f79a59e8..d44a27b01 100644 --- a/zencore/include/zencore/endian.h +++ b/zencore/include/zencore/endian.h @@ -7,19 +7,31 @@ namespace zen { inline uint16_t ByteSwap(uint16_t x) { +#if ZEN_COMPILER_MSC return _byteswap_ushort(x); +#else + return __builtin_bswap16(x); +#endif } inline uint32_t ByteSwap(uint32_t x) { +#if ZEN_COMPILER_MSC return _byteswap_ulong(x); +#else + return __builtin_bswap32(x); +#endif } inline uint64_t ByteSwap(uint64_t x) { +#if ZEN_COMPILER_MSC return _byteswap_uint64(x); +#else + return __builtin_bswap64(x); +#endif } inline uint16_t diff --git a/zencore/include/zencore/except.h b/zencore/include/zencore/except.h index 8625f01d0..36cca895f 100644 --- a/zencore/include/zencore/except.h +++ b/zencore/include/zencore/except.h @@ -3,12 +3,18 @@ #pragma once #include <zencore/string.h> -#include <zencore/windows.h> +#if ZEN_PLATFORM_WINDOWS +# include <zencore/windows.h> +#else +# include <errno.h> +#endif #include <source_location> #include <string> +#include <system_error> namespace zen { +#if ZEN_PLATFORM_WINDOWS class WindowsException : public std::exception { public: @@ -45,17 +51,36 @@ private: }; ZENCORE_API void ThrowSystemException(HRESULT hRes, std::string_view Message); +#endif // ZEN_PLATFORM_WINDOWS + +ZENCORE_API void ThrowLastError(std::string_view Message); + +#if __cpp_lib_source_location +ZENCORE_API void ThrowLastError(std::string_view Message, const std::source_location& Location); +#endif + +ZENCORE_API std::string GetLastErrorAsString(); +ZENCORE_API std::string GetWindowsErrorAsString(uint32_t Win32ErrorCode); inline void ThrowSystemException(const char* Message) { +#if ZEN_PLATFORM_WINDOWS throw WindowsException(Message); +#else + ThrowLastError(Message); +#endif } -ZENCORE_API void ThrowLastError(std::string_view Message); -ZENCORE_API void ThrowLastError(std::string_view Message, const std::source_location& Location); -ZENCORE_API std::string GetLastErrorAsString(); -ZENCORE_API std::string GetWindowsErrorAsString(uint32_t Win32ErrorCode); +inline int32_t +GetLastError() +{ +#if ZEN_PLATFORM_WINDOWS + return ::GetLastError(); +#else + return errno; +#endif +} inline std::error_code MakeWin32ErrorCode(uint32_t Win32ErrorCode) noexcept @@ -66,7 +91,7 @@ MakeWin32ErrorCode(uint32_t Win32ErrorCode) noexcept inline std::error_code MakeErrorCodeFromLastError() noexcept { - return std::error_code(::GetLastError(), std::system_category()); + return std::error_code(zen::GetLastError(), std::system_category()); } } // namespace zen diff --git a/zencore/include/zencore/fmtutils.h b/zencore/include/zencore/fmtutils.h index fb5a08d56..29e2ae78a 100644 --- a/zencore/include/zencore/fmtutils.h +++ b/zencore/include/zencore/fmtutils.h @@ -43,7 +43,7 @@ struct fmt::formatter<std::filesystem::path> : formatter<string_view> auto format(const std::filesystem::path& Path, FormatContext& ctx) { zen::ExtendableStringBuilder<128> String; - WideToUtf8(Path.c_str(), String); + String << Path.u8string(); return formatter<string_view>::format(String.ToView(), ctx); } }; diff --git a/zencore/include/zencore/intmath.h b/zencore/include/zencore/intmath.h index 792b8b2b4..814a03df4 100644 --- a/zencore/include/zencore/intmath.h +++ b/zencore/include/zencore/intmath.h @@ -9,8 +9,46 @@ ////////////////////////////////////////////////////////////////////////// -#pragma intrinsic(_BitScanReverse) -#pragma intrinsic(_BitScanReverse64) +#if ZEN_COMPILER_MSC || ZEN_PLATFORM_WINDOWS +# pragma intrinsic(_BitScanReverse) +# pragma intrinsic(_BitScanReverse64) +#else +inline uint8_t +_BitScanReverse(unsigned long* Index, uint32_t Mask) +{ + if (Mask == 0) + { + return 0; + } + + *Index = __builtin_clz(Mask); + return 1; +} + +inline uint8_t +_BitScanReverse64(unsigned long* Index, uint64_t Mask) +{ + if (Mask == 0) + { + return 0; + } + + *Index = __builtin_clzll(Mask); + return 0; +} + +inline uint8_t +_BitScanForward64(unsigned long* Index, uint64_t Mask) +{ + if (Mask == 0) + { + return 0; + } + + *Index = __builtin_ctzll(Mask); + return 0; +} +#endif namespace zen { @@ -121,8 +159,10 @@ IsPointerAligned(const void* Ptr, uint64_t Alignment) ////////////////////////////////////////////////////////////////////////// -#ifdef min -# error "Looks like you did #include <windows.h> -- use <zencore/windows.h> instead" +#if ZEN_PLATFORM_WINDOWS +# ifdef min +# error "Looks like you did #include <windows.h> -- use <zencore/windows.h> instead" +# endif #endif constexpr auto @@ -137,4 +177,8 @@ Max(auto x, auto y) return x > y ? x : y; } +////////////////////////////////////////////////////////////////////////// + +void intmath_forcelink(); // internal + } // namespace zen diff --git a/zencore/include/zencore/iohash.h b/zencore/include/zencore/iohash.h index aaa638684..fd0f4b2a7 100644 --- a/zencore/include/zencore/iohash.h +++ b/zencore/include/zencore/iohash.h @@ -8,6 +8,7 @@ #include <zencore/blake3.h> #include <zencore/memory.h> +#include <compare> #include <string_view> namespace zen { diff --git a/zencore/include/zencore/logging.h b/zencore/include/zencore/logging.h index a2404a5e9..4eee20414 100644 --- a/zencore/include/zencore/logging.h +++ b/zencore/include/zencore/logging.h @@ -13,6 +13,7 @@ namespace zen::logging { spdlog::logger& Default(); +void SetDefault(std::shared_ptr<spdlog::logger> NewDefaultLogger); spdlog::logger& ConsoleLog(); spdlog::logger& Get(std::string_view Name); @@ -20,3 +21,29 @@ void InitializeLogging(); void ShutdownLogging(); } // namespace zen::logging + +namespace zen { +extern spdlog::logger* TheDefaultLogger; + +inline spdlog::logger& +Log() +{ + return *TheDefaultLogger; +} + +using logging::ConsoleLog; +} // namespace zen + +using zen::ConsoleLog; +using zen::Log; + +// Helper macros for logging + +using namespace std::literals; + +#define ZEN_TRACE(fmtstr, ...) Log().trace(fmtstr##sv, __VA_ARGS__) +#define ZEN_DEBUG(fmtstr, ...) Log().debug(fmtstr##sv, __VA_ARGS__) +#define ZEN_INFO(fmtstr, ...) Log().info(fmtstr##sv, __VA_ARGS__) +#define ZEN_WARN(fmtstr, ...) Log().warn(fmtstr##sv, __VA_ARGS__) +#define ZEN_ERROR(fmtstr, ...) Log().error(fmtstr##sv, __VA_ARGS__) +#define ZEN_CRITICAL(fmtstr, ...) Log().critical(fmtstr##sv, __VA_ARGS__) diff --git a/zencore/include/zencore/memory.h b/zencore/include/zencore/memory.h index 5a324955d..9d6339595 100644 --- a/zencore/include/zencore/memory.h +++ b/zencore/include/zencore/memory.h @@ -8,6 +8,8 @@ #include <zencore/thread.h> #include <algorithm> +#include <cstddef> +#include <cstring> #include <span> #include <vector> @@ -81,7 +83,7 @@ struct MutableMemoryView { } - inline bool IsEmpty() const { return m_Data == m_DataEnd; } + inline bool IsEmpty() const { return m_Data == m_DataEnd; } void* GetData() const { return m_Data; } void* GetDataEnd() const { return m_DataEnd; } size_t GetSize() const { return reinterpret_cast<uint8_t*>(m_DataEnd) - reinterpret_cast<uint8_t*>(m_Data); } @@ -111,7 +113,7 @@ struct MutableMemoryView } /** Modifies the view by chopping the given number of bytes from the left. */ - inline constexpr void RightChopInline(uint64_t InSize) + inline void RightChopInline(uint64_t InSize) { const uint64_t Offset = zen::Min(GetSize(), InSize); m_Data = GetDataAtOffsetNoCheck(Offset); @@ -151,7 +153,7 @@ struct MutableMemoryView return View; } - inline constexpr MutableMemoryView& operator+=(size_t InSize) + inline MutableMemoryView& operator+=(size_t InSize) { RightChopInline(InSize); return *this; @@ -192,10 +194,10 @@ struct MemoryView { } - inline bool Contains(const MemoryView& Other) const { return (m_Data <= Other.m_Data) && (m_DataEnd >= Other.m_DataEnd); } - inline bool IsEmpty() const { return m_Data == m_DataEnd; } - const void* GetData() const { return m_Data; } - const void* GetDataEnd() const { return m_DataEnd; } + inline bool Contains(const MemoryView& Other) const { return (m_Data <= Other.m_Data) && (m_DataEnd >= Other.m_DataEnd); } + inline bool IsEmpty() const { return m_Data == m_DataEnd; } + const void* GetData() const { return m_Data; } + const void* GetDataEnd() const { return m_DataEnd; } size_t GetSize() const { return reinterpret_cast<const uint8_t*>(m_DataEnd) - reinterpret_cast<const uint8_t*>(m_Data); } inline bool operator==(const MemoryView& Rhs) const { return m_Data == Rhs.m_Data && m_DataEnd == Rhs.m_DataEnd; } @@ -206,14 +208,14 @@ struct MemoryView return Size == InView.GetSize() && (memcmp(m_Data, InView.GetData(), Size) == 0); } - inline constexpr MemoryView& operator+=(size_t InSize) + inline MemoryView& operator+=(size_t InSize) { RightChopInline(InSize); return *this; } /** Modifies the view by chopping the given number of bytes from the left. */ - inline constexpr void RightChopInline(uint64_t InSize) + inline void RightChopInline(uint64_t InSize) { const uint64_t Offset = std::min(GetSize(), InSize); m_Data = GetDataAtOffsetNoCheck(Offset); @@ -244,7 +246,7 @@ struct MemoryView } /** Returns the left-most part of the view by taking the given number of bytes from the left. */ - constexpr inline MemoryView Left(uint64_t InSize) const + inline MemoryView Left(uint64_t InSize) const { MemoryView View(*this); View.LeftInline(InSize); @@ -252,7 +254,7 @@ struct MemoryView } /** Modifies the view to be the given number of bytes from the left. */ - constexpr inline void LeftInline(uint64_t InSize) + inline void LeftInline(uint64_t InSize) { InSize = zen::Min(GetSize(), InSize); m_DataEnd = std::min(m_DataEnd, m_Data + InSize); @@ -296,28 +298,28 @@ MutableMemoryView::CopyFrom(MemoryView InView) const } /** Advances the start of the view by an offset, which is clamped to stay within the view. */ -constexpr inline MemoryView +inline MemoryView operator+(const MemoryView& View, uint64_t Offset) { return MemoryView(View) += Offset; } /** Advances the start of the view by an offset, which is clamped to stay within the view. */ -constexpr inline MemoryView +inline MemoryView operator+(uint64_t Offset, const MemoryView& View) { return MemoryView(View) += Offset; } /** Advances the start of the view by an offset, which is clamped to stay within the view. */ -constexpr inline MutableMemoryView +inline MutableMemoryView operator+(const MutableMemoryView& View, uint64_t Offset) { return MutableMemoryView(View) += Offset; } /** Advances the start of the view by an offset, which is clamped to stay within the view. */ -constexpr inline MutableMemoryView +inline MutableMemoryView operator+(uint64_t Offset, const MutableMemoryView& View) { return MutableMemoryView(View) += Offset; diff --git a/zencore/include/zencore/sharedbuffer.h b/zencore/include/zencore/sharedbuffer.h index b230c05b1..640c3fe74 100644 --- a/zencore/include/zencore/sharedbuffer.h +++ b/zencore/include/zencore/sharedbuffer.h @@ -12,6 +12,8 @@ namespace zen { +class SharedBuffer; + /** * Reference to a memory buffer with a single owner * diff --git a/zencore/include/zencore/string.h b/zencore/include/zencore/string.h index de2ca71d9..2b5f20f86 100644 --- a/zencore/include/zencore/string.h +++ b/zencore/include/zencore/string.h @@ -560,15 +560,17 @@ NiceRate(uint64_t Num, uint32_t DurationMilliseconds, const char* Unit = "B") if (DurationMilliseconds) { - NiceNumToBuffer(Num * 1000 / DurationMilliseconds, Buffer); + // Leave a little of 'Buffer' for the "Unit/s" suffix + std::span<char> BufferSpan(Buffer, sizeof(Buffer) - 8); + NiceNumToBuffer(Num * 1000 / DurationMilliseconds, BufferSpan); } else { - strcpy_s(Buffer, "0"); + strcpy(Buffer, "0"); } - strcat_s(Buffer, Unit); - strcat_s(Buffer, "/s"); + strncat(Buffer, Unit, 4); + strcat(Buffer, "/s"); return Buffer; } diff --git a/zencore/include/zencore/thread.h b/zencore/include/zencore/thread.h index 30d0c0897..b18da6031 100644 --- a/zencore/include/zencore/thread.h +++ b/zencore/include/zencore/thread.h @@ -4,6 +4,10 @@ #include "zencore.h" +#if !ZEN_PLATFORM_WINDOWS +# include <shared_mutex> +#endif + namespace zen { /** @@ -60,7 +64,11 @@ public: }; private: +#if ZEN_PLATFORM_WINDOWS void* m_Srw = nullptr; +#else + std::shared_mutex m_Mutex; +#endif }; /** Basic abstraction of a simple event synchronization mechanism (aka 'binary semaphore') diff --git a/zencore/include/zencore/timer.h b/zencore/include/zencore/timer.h index c9122eb44..eb284eaee 100644 --- a/zencore/include/zencore/timer.h +++ b/zencore/include/zencore/timer.h @@ -2,10 +2,16 @@ #pragma once -#include <intrin.h> -#include <stdint.h> #include "zencore.h" +#if ZEN_COMPILER_MSC +# include <intrin.h> +#elif ZEN_ARCH_X64 +# include <x86intrin.h> +#endif + +#include <stdint.h> + namespace zen { // High frequency timers diff --git a/zencore/include/zencore/zencore.h b/zencore/include/zencore/zencore.h index 206046f0b..73446b447 100644 --- a/zencore/include/zencore/zencore.h +++ b/zencore/include/zencore/zencore.h @@ -10,24 +10,65 @@ // Platform // -#define ZEN_PLATFORM_WINDOWS 1 -#define ZEN_PLATFORM_LINUX 0 -#define ZEN_PLATFORM_MACOS 0 +#define ZEN_PLATFORM_WINDOWS 0 +#define ZEN_PLATFORM_LINUX 0 +#define ZEN_PLATFORM_MACOS 0 + +#ifdef _WIN32 +# undef ZEN_PLATFORM_WINDOWS +# define ZEN_PLATFORM_WINDOWS 1 +#elif defined(__linux__) +# undef ZEN_PLATFORM_LINUX +# define ZEN_PLATFORM_LINUX 1 +#elif defined(__APPLE__) +# undef ZEN_PLATFORM_MACOS +# define ZEN_PLATFORM_MACOS 1 +#endif ////////////////////////////////////////////////////////////////////////// // Compiler // -#ifdef _MSC_VER -# define ZEN_COMPILER_MSC 1 +#define ZEN_COMPILER_CLANG 0 +#define ZEN_COMPILER_MSC 0 +#define ZEN_COMPILER_GCC 0 + +// Clang can define __GNUC__ and/or _MSC_VER so we check for Clang first +#ifdef __clang__ +# undef ZEN_COMPILER_CLANG +# define ZEN_COMPILER_CLANG 1 +#elif defined(_MSC_VER) +# undef ZEN_COMPILER_MSC +# define ZEN_COMPILER_MSC 1 +#elif defined(__GNUC__) +# undef ZEN_COMPILER_GCC +# define ZEN_COMPILER_GCC 1 +#else +# error Unknown compiler #endif -#ifndef ZEN_COMPILER_MSC -# define ZEN_COMPILER_MSC 0 +// Check for C++20 support +#if !ZEN_PLATFORM_WINDOWS +# if ZEN_COMPILER_CLANG && __clang_major__ < 14 +# error LLVM-14 onwards required for complete C++20 support +# elif ZEN_COMPILER_GCC && __GNUC__ < 11 +# error GCC-11 onwards required for complete C++20 support +# endif #endif -#ifndef ZEN_COMPILER_CLANG -# define ZEN_COMPILER_CLANG 0 + +////////////////////////////////////////////////////////////////////////// +// Architecture +// + +#if defined(__amd64__) || defined(_M_X64) +# define ZEN_ARCH_X64 1 +# define ZEN_ARCH_ARM64 0 +#elif defined(__arm64__) || defined(_M_ARM64) +# define ZEN_ARCH_X64 0 +# define ZEN_ARCH_ARM64 1 +#else +# error Unknown architecture #endif ////////////////////////////////////////////////////////////////////////// @@ -58,7 +99,7 @@ public: AssertException(const char* Msg); ~AssertException(); - [[nodiscard]] virtual char const* what() const override { return m_Msg.c_str(); } + [[nodiscard]] virtual char const* what() const noexcept override { return m_Msg.c_str(); } private: std::string m_Msg; @@ -100,7 +141,12 @@ char (&ZenArrayCountHelper(const T (&)[N]))[N + 1]; ////////////////////////////////////////////////////////////////////////// -#define ZEN_NOINLINE __declspec(noinline) +#if ZEN_COMPILER_MSC +# define ZEN_NOINLINE __declspec(noinline) +#else +# define ZEN_NOINLINE __attribute__((noinline)) +#endif + #define ZEN_UNUSED(...) ((void)__VA_ARGS__) #define ZEN_NOT_IMPLEMENTED(...) ZEN_ASSERT(false) #define ZENCORE_API // Placeholder to allow DLL configs in the future |