diff options
author | crupest <crupest@outlook.com> | 2021-09-14 22:10:02 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2021-09-14 22:10:02 +0800 |
commit | 46d4838ac8ff1bd8658b57cf4ebb4438e396fce8 (patch) | |
tree | f1e04c19630c7f42ad57618e9a2d7cf5ea4d31c1 /include/cru/common | |
parent | 9bc202a2e1664df3e3c148abfe90a90501bc1650 (diff) | |
download | cru-46d4838ac8ff1bd8658b57cf4ebb4438e396fce8.tar.gz cru-46d4838ac8ff1bd8658b57cf4ebb4438e396fce8.tar.bz2 cru-46d4838ac8ff1bd8658b57cf4ebb4438e396fce8.zip |
...
Diffstat (limited to 'include/cru/common')
-rw-r--r-- | include/cru/common/Exception.hpp | 2 | ||||
-rw-r--r-- | include/cru/common/HandlerRegistry.hpp | 1 | ||||
-rw-r--r-- | include/cru/common/Logger.hpp | 26 | ||||
-rw-r--r-- | include/cru/common/String.hpp | 98 |
4 files changed, 106 insertions, 21 deletions
diff --git a/include/cru/common/Exception.hpp b/include/cru/common/Exception.hpp index 8864f4df..4e5d3a16 100644 --- a/include/cru/common/Exception.hpp +++ b/include/cru/common/Exception.hpp @@ -5,7 +5,7 @@ namespace cru { class CRU_BASE_API Exception { public: Exception() = default; - Exception(String message) : message_(std::move(message)) {} + explicit Exception(String message) : message_(std::move(message)) {} CRU_DEFAULT_COPY(Exception) CRU_DEFAULT_MOVE(Exception) diff --git a/include/cru/common/HandlerRegistry.hpp b/include/cru/common/HandlerRegistry.hpp index bd74a9e0..0af97968 100644 --- a/include/cru/common/HandlerRegistry.hpp +++ b/include/cru/common/HandlerRegistry.hpp @@ -59,6 +59,7 @@ class HandlerRegistry final { int AddHandler(std::function<T> handler) { auto id = current_id_++; handler_list_.push_back({id, std::move(handler)}); + return id; } void RemoveHandler(int id) { diff --git a/include/cru/common/Logger.hpp b/include/cru/common/Logger.hpp index 239a25cd..5aea5126 100644 --- a/include/cru/common/Logger.hpp +++ b/include/cru/common/Logger.hpp @@ -1,10 +1,10 @@ #pragma once #include "Base.hpp" -#include <fmt/format.h> +#include "String.hpp" + #include <list> #include <memory> -#include <string_view> namespace cru::log { @@ -13,7 +13,7 @@ enum class LogLevel { Debug, Info, Warn, Error }; struct CRU_BASE_API ILogSource : virtual Interface { // Write the string s. LogLevel is just a helper. It has no effect on the // content to write. - virtual void Write(LogLevel level, const std::u16string& s) = 0; + virtual void Write(LogLevel level, const String& s) = 0; }; class CRU_BASE_API Logger : public Object { @@ -33,8 +33,8 @@ class CRU_BASE_API Logger : public Object { void RemoveSource(ILogSource* source); public: - void Log(LogLevel level, std::u16string_view s); - void Log(LogLevel level, std::u16string_view tag, std::u16string_view s); + void Log(LogLevel level, const String& message); + void Log(LogLevel level, const String& tag, const String& message); private: std::list<std::unique_ptr<ILogSource>> sources_; @@ -45,26 +45,26 @@ template <typename... TArgs> void Debug([[maybe_unused]] TArgs&&... args) { #ifdef CRU_DEBUG Logger::GetInstance()->Log(LogLevel::Debug, - fmt::format(std::forward<TArgs>(args)...)); + Format(std::forward<TArgs>(args)...)); #endif } template <typename... TArgs> void Info(TArgs&&... args) { Logger::GetInstance()->Log(LogLevel::Info, - fmt::format(std::forward<TArgs>(args)...)); + Format(std::forward<TArgs>(args)...)); } template <typename... TArgs> void Warn(TArgs&&... args) { Logger::GetInstance()->Log(LogLevel::Warn, - fmt::format(std::forward<TArgs>(args)...)); + Format(std::forward<TArgs>(args)...)); } template <typename... TArgs> void Error(TArgs&&... args) { Logger::GetInstance()->Log(LogLevel::Error, - fmt::format(std::forward<TArgs>(args)...)); + Format(std::forward<TArgs>(args)...)); } // TODO: Remove argument evaluation in Debug. @@ -73,25 +73,25 @@ void TagDebug([[maybe_unused]] std::u16string_view tag, [[maybe_unused]] TArgs&&... args) { #ifdef CRU_DEBUG Logger::GetInstance()->Log(LogLevel::Debug, tag, - fmt::format(std::forward<TArgs>(args)...)); + Format(std::forward<TArgs>(args)...)); #endif } template <typename... TArgs> void TagInfo(std::u16string_view tag, TArgs&&... args) { Logger::GetInstance()->Log(LogLevel::Info, tag, - fmt::format(std::forward<TArgs>(args)...)); + Format(std::forward<TArgs>(args)...)); } template <typename... TArgs> void TagWarn(std::u16string_view tag, TArgs&&... args) { Logger::GetInstance()->Log(LogLevel::Warn, tag, - fmt::format(std::forward<TArgs>(args)...)); + Format(std::forward<TArgs>(args)...)); } template <typename... TArgs> void TagError(std::u16string_view tag, TArgs&&... args) { Logger::GetInstance()->Log(LogLevel::Error, tag, - fmt::format(std::forward<TArgs>(args)...)); + Format(std::forward<TArgs>(args)...)); } } // namespace cru::log diff --git a/include/cru/common/String.hpp b/include/cru/common/String.hpp index 42143c9d..9443417f 100644 --- a/include/cru/common/String.hpp +++ b/include/cru/common/String.hpp @@ -4,8 +4,14 @@ #include "Range.hpp" #include "StringUtil.hpp" -#include <cstdint> +#include <algorithm> +#include <array> +#include <charconv> #include <iterator> +#include <stdexcept> +#include <system_error> +#include <type_traits> +#include <vector> namespace cru { class CRU_BASE_API String { @@ -25,6 +31,11 @@ class CRU_BASE_API String { return String(str, size); } + // Never use this if you don't know what this mean! + static String FromBuffer(std::uint16_t* buffer, Index size, Index capacity) { + return String{from_buffer_tag{}, buffer, size, capacity}; + } + #ifdef CRU_PLATFORM_WINDOWS static String FromUtf16(wchar_t* str) { return String(str); } static String FromUtf16(wchar_t* str, Index size) { @@ -69,6 +80,10 @@ class CRU_BASE_API String { ~String(); + private: + struct from_buffer_tag {}; + String(from_buffer_tag, std::uint16_t* buffer, Index size, Index capacity); + public: bool empty() const { return this->size_ == 0; } Index size() const { return this->size_; } @@ -136,12 +151,6 @@ class CRU_BASE_API String { return *this; } - String operator+(const String& other) const { - String result(*this); - result += other; - return result; - } - public: Utf16CodePointIterator CodePointIterator() const { return Utf16CodePointIterator( @@ -163,6 +172,9 @@ class CRU_BASE_API String { } #endif + template <typename... T> + String Format(T&&... args) const; + std::string ToUtf8() const; int Compare(const String& other) const; @@ -178,4 +190,76 @@ class CRU_BASE_API String { CRU_DEFINE_COMPARE_OPERATORS(String) +inline String operator+(const String& left, const String& right) { + String result(left); + result += right; + return result; +} + +template <typename T, typename = std::enable_if_t<std::is_arithmetic_v<T>>> +String ToString(T value) { + std::array<char, 50> buffer; + auto result = + std::to_chars(buffer.data(), buffer.data() + buffer.size(), value); + + auto size = result.ptr - buffer.data(); + auto b = new std::uint16_t[size + 1]; + b[size] = 0; + std::copy(buffer.data(), result.ptr, b); + return String::FromBuffer(b, size, size); + + if (result.ec == std::errc{}) { + } else { + throw std::invalid_argument("Failed to convert value to chars."); + } +} + +inline String ToString(String value) { return std::move(value); } + +namespace details { +enum class FormatTokenType { PlaceHolder, Text }; + +struct FormatToken { + FormatTokenType type; + String data; +}; + +std::vector<FormatToken> ParseToFormatTokenList(const String& str); + +void FormatAppendFromFormatTokenList( + String& current, const std::vector<FormatToken>& format_token_list, + Index index); + +template <typename TA, typename... T> +void FormatAppendFromFormatTokenList( + String& current, const std::vector<FormatToken>& format_token_list, + Index index, TA&& args0, T&&... args) { + for (Index i = index; i < format_token_list.size(); i++) { + const auto& token = format_token_list[i]; + if (token.type == FormatTokenType::PlaceHolder) { + current += ToString(std::forward<TA>(args0)); + FormatAppendFromFormatTokenList(current, format_token_list, i + 1, + std::forward<T>(args)...); + } else { + current += token.data; + } + } +} +} // namespace details + +template <typename... T> +String Format(const String& format, T&&... args) { + String result; + + details::FormatAppendFromFormatTokenList( + result, details::ParseToFormatTokenList(format), 0, + std::forward<T>(args)...); + + return result; +} + +template <typename... T> +String String::Format(T&&... args) const { + return cru::Format(*this, std::forward<T>(args)...); +} } // namespace cru |