diff options
Diffstat (limited to 'include/cru/common')
-rw-r--r-- | include/cru/common/Base.hpp | 2 | ||||
-rw-r--r-- | include/cru/common/Logger.hpp | 37 | ||||
-rw-r--r-- | include/cru/common/PreConfig.hpp | 1 | ||||
-rw-r--r-- | include/cru/common/StringUtil.hpp | 79 |
4 files changed, 75 insertions, 44 deletions
diff --git a/include/cru/common/Base.hpp b/include/cru/common/Base.hpp index 409c2b0e..93d6f9a6 100644 --- a/include/cru/common/Base.hpp +++ b/include/cru/common/Base.hpp @@ -47,5 +47,5 @@ using Index = gsl::index; #define CRU_DEFINE_CLASS_LOG_TAG(tag) \ private: \ - constexpr static std::string_view log_tag = tag; + constexpr static std::u16string_view log_tag = tag; } // namespace cru diff --git a/include/cru/common/Logger.hpp b/include/cru/common/Logger.hpp index f76e4626..f83ba8dc 100644 --- a/include/cru/common/Logger.hpp +++ b/include/cru/common/Logger.hpp @@ -15,30 +15,7 @@ enum class LogLevel { Debug, Info, Warn, Error }; struct 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, std::string_view s) = 0; -}; - -class StdioLogSource : public virtual ILogSource { - public: - StdioLogSource() = default; - - CRU_DELETE_COPY(StdioLogSource) - CRU_DELETE_MOVE(StdioLogSource) - - ~StdioLogSource() override = default; - - void Write(LogLevel level, std::string_view s) override { - // TODO: Emmm... Since it is buggy to use narrow char in UTF-8 on Windows. I - // think this implementation might be broken. (However, I didn't test it.) - // Maybe, I should detect Windows and use wide char (And I didn't test this - // either) or other more complicated implementation. Currently, I settled - // with this. - if (level == LogLevel::Error) { - std::cerr << s; - } else { - std::cout << s; - } - } + virtual void Write(LogLevel level, const std::u16string& s) = 0; }; class Logger : public Object { @@ -58,8 +35,8 @@ class Logger : public Object { void RemoveSource(ILogSource* source); public: - void Log(LogLevel level, std::string_view s); - void Log(LogLevel level, std::string_view tag, std::string_view s); + void Log(LogLevel level, std::u16string_view s); + void Log(LogLevel level, std::u16string_view tag, std::u16string_view s); public: std::list<std::unique_ptr<ILogSource>> sources_; @@ -92,7 +69,7 @@ void Error(TArgs&&... args) { } template <typename... TArgs> -void TagDebug([[maybe_unused]] std::string_view tag, +void TagDebug([[maybe_unused]] std::u16string_view tag, [[maybe_unused]] TArgs&&... args) { #ifdef CRU_DEBUG Logger::GetInstance()->Log(LogLevel::Debug, tag, @@ -101,19 +78,19 @@ void TagDebug([[maybe_unused]] std::string_view tag, } template <typename... TArgs> -void TagInfo(std::string_view tag, TArgs&&... args) { +void TagInfo(std::u16string_view tag, TArgs&&... args) { Logger::GetInstance()->Log(LogLevel::Info, tag, fmt::format(std::forward<TArgs>(args)...)); } template <typename... TArgs> -void TagWarn(std::string_view tag, TArgs&&... args) { +void TagWarn(std::u16string_view tag, TArgs&&... args) { Logger::GetInstance()->Log(LogLevel::Warn, tag, fmt::format(std::forward<TArgs>(args)...)); } template <typename... TArgs> -void TagError(std::string_view tag, TArgs&&... args) { +void TagError(std::u16string_view tag, TArgs&&... args) { Logger::GetInstance()->Log(LogLevel::Error, tag, fmt::format(std::forward<TArgs>(args)...)); } diff --git a/include/cru/common/PreConfig.hpp b/include/cru/common/PreConfig.hpp index 4bccef1d..802f17f8 100644 --- a/include/cru/common/PreConfig.hpp +++ b/include/cru/common/PreConfig.hpp @@ -6,3 +6,4 @@ #endif #define _CRT_SECURE_NO_WARNINGS +#define _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING diff --git a/include/cru/common/StringUtil.hpp b/include/cru/common/StringUtil.hpp index a44ae6b4..714f1d49 100644 --- a/include/cru/common/StringUtil.hpp +++ b/include/cru/common/StringUtil.hpp @@ -3,37 +3,90 @@ namespace cru { using CodePoint = std::int32_t; -constexpr CodePoint k_code_point_end = -1; +constexpr CodePoint k_invalid_code_point = -1; class TextEncodeException : public std::runtime_error { public: using runtime_error::runtime_error; }; -class Utf8Iterator : public Object { +inline bool IsSurrogatePair(char16_t c) { return c >= 0xD800 && c <= 0xDFFF; } + +inline bool IsSurrogatePairLeading(char16_t c) { + return c >= 0xD800 && c <= 0xDBFF; +} + +inline bool IsSurrogatePairTrailing(char16_t c) { + return c >= 0xDC00 && c <= 0xDFFF; +} + +class Utf16Iterator : public Object { public: - explicit Utf8Iterator(const std::string_view& string) : string_(string) {} - Utf8Iterator(const std::string_view& string, Index position) - : string_(string), position_(position) {} + explicit Utf16Iterator(std::u16string_view string) + : string_(std::move(string)) {} + Utf16Iterator(std::u16string_view string, Index position) + : string_(std::move(string)), position_(position) {} - CRU_DEFAULT_COPY(Utf8Iterator) - CRU_DEFAULT_MOVE(Utf8Iterator) + CRU_DEFAULT_COPY(Utf16Iterator) + CRU_DEFAULT_MOVE(Utf16Iterator) - ~Utf8Iterator() = default; + ~Utf16Iterator() = default; public: - void SetToHead() { position_ = 0; } + void SetPositionToHead() { position_ = 0; } void SetPosition(Index position) { position_ = position; } - // Advance current position and get next code point. Return k_code_point_end - // if there is no next code unit(point). Throw TextEncodeException if decoding - // fails. + // Backward current position and get previous code point. Return + // k_invalid_code_point if reach head. Throw TextEncodeException if encounter + // encoding problem. + CodePoint Previous(); + + // Advance current position and get next code point. Return + // k_invalid_code_point if reach tail. Throw TextEncodeException if encounter + // encoding problem. CodePoint Next(); Index CurrentPosition() const { return this->position_; } private: - std::string_view string_; + std::u16string_view string_; Index position_ = 0; }; + +Index PreviousIndex(std::u16string_view string, Index current); +Index NextIndex(std::u16string_view string, Index current); + +std::string ToUtf8(const std::u16string& s); +inline std::string ToUtf8(std::u16string_view s) { + return ToUtf8(std::u16string{s}); +} + +// class Utf8Iterator : public Object { +// public: +// explicit Utf8Iterator(const std::string_view& string) : string_(string) {} +// Utf8Iterator(const std::string_view& string, Index position) +// : string_(string), position_(position) {} + +// CRU_DEFAULT_COPY(Utf8Iterator) +// CRU_DEFAULT_MOVE(Utf8Iterator) + +// ~Utf8Iterator() = default; + +// public: +// void SetToHead() { position_ = 0; } +// void SetPosition(Index position) { position_ = position; } + +// // Advance current position and get next code point. Return +// k_invalid_code_point +// // if there is no next code unit(point). Throw TextEncodeException if +// decoding +// // fails. +// CodePoint Next(); + +// Index CurrentPosition() const { return this->position_; } + +// private: +// std::string_view string_; +// Index position_ = 0; +// }; } // namespace cru |