diff options
author | crupest <crupest@outlook.com> | 2021-08-10 01:00:33 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2021-08-10 01:00:33 +0800 |
commit | d2448884500811bf1cd1eba89e7a4193a76c4d6b (patch) | |
tree | 2c9117f3e91128c3f08639283281c1898e01b063 | |
parent | 9c32e6d705b23cf0f5d7c0909271640401f9785f (diff) | |
download | cru-d2448884500811bf1cd1eba89e7a4193a76c4d6b.tar.gz cru-d2448884500811bf1cd1eba89e7a4193a76c4d6b.tar.bz2 cru-d2448884500811bf1cd1eba89e7a4193a76c4d6b.zip |
...
-rw-r--r-- | .vscode/settings.json | 3 | ||||
-rw-r--r-- | CMakeLists.txt | 5 | ||||
-rw-r--r-- | include/cru/common/Base.hpp | 33 | ||||
-rw-r--r-- | include/cru/common/Logger.hpp | 6 | ||||
-rw-r--r-- | include/cru/common/PreConfig.hpp | 4 | ||||
-rw-r--r-- | include/cru/common/StringUtil.hpp | 67 | ||||
-rw-r--r-- | src/common/CMakeLists.txt | 9 | ||||
-rw-r--r-- | src/common/StringUtil.cpp | 27 |
8 files changed, 106 insertions, 48 deletions
diff --git a/.vscode/settings.json b/.vscode/settings.json index f951b23c..33832555 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -86,7 +86,8 @@ "regex": "cpp", "stack": "cpp", "unordered_set": "cpp", - "variant": "cpp" + "variant": "cpp", + "gsl": "cpp" }, "cmake.generator": "Ninja" } diff --git a/CMakeLists.txt b/CMakeLists.txt index 09c0b114..87e15f5b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,12 +3,15 @@ cmake_minimum_required(VERSION 3.14) set(CMAKE_TOOLCHAIN_FILE $ENV{VCPKG_INSTALLATION_ROOT}/scripts/buildsystems/vcpkg.cmake CACHE STRING "Vcpkg toolchain file") -project(CruUI) +project(cru) enable_testing() set(CMAKE_CXX_STANDARD 17) +set (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) +set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) + if (MSVC) string(REGEX REPLACE "/W[0-4]\\s*" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) add_compile_options(/utf-8 /W4 /WX) diff --git a/include/cru/common/Base.hpp b/include/cru/common/Base.hpp index 560f83bb..93b0008c 100644 --- a/include/cru/common/Base.hpp +++ b/include/cru/common/Base.hpp @@ -1,9 +1,19 @@ #pragma once #include "PreConfig.hpp" -#include <exception> +#ifdef CRU_PLATFORM_WINDOWS +#ifdef CRU_BASE_EXPORT_API +#define CRU_BASE_API __declspec(dllexport) +#else +#define CRU_BASE_API __declspec(dllimport) +#endif +#else +#define CRU_BASE_API +#endif + #include <gsl/gsl> #include <stdexcept> +#include <string> #define CRU_UNUSED(entity) static_cast<void>(entity); @@ -27,7 +37,7 @@ classname& operator=(classname&&) = delete; namespace cru { -class Object { +class CRU_BASE_API Object { public: Object() = default; CRU_DEFAULT_COPY(Object) @@ -35,7 +45,7 @@ class Object { virtual ~Object() = default; }; -struct Interface { +struct CRU_BASE_API Interface { Interface() = default; CRU_DELETE_COPY(Interface) CRU_DELETE_MOVE(Interface) @@ -56,4 +66,21 @@ inline void hash_combine(std::size_t& s, const T& v) { #define CRU_DEFINE_CLASS_LOG_TAG(tag) \ private: \ constexpr static std::u16string_view log_tag = tag; + +class CRU_BASE_API Exception { + public: + Exception() = default; + Exception(std::u16string message) : message_(std::move(message)) {} + + CRU_DEFAULT_COPY(Exception) + CRU_DEFAULT_MOVE(Exception) + + virtual ~Exception() = default; + + public: + std::u16string GetMessage() const { return message_; } + + private: + std::u16string message_; +}; } // namespace cru diff --git a/include/cru/common/Logger.hpp b/include/cru/common/Logger.hpp index daf2e7d2..239a25cd 100644 --- a/include/cru/common/Logger.hpp +++ b/include/cru/common/Logger.hpp @@ -10,13 +10,13 @@ namespace cru::log { enum class LogLevel { Debug, Info, Warn, Error }; -struct ILogSource : virtual Interface { +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; }; -class Logger : public Object { +class CRU_BASE_API Logger : public Object { public: static Logger* GetInstance(); @@ -36,7 +36,7 @@ class Logger : public Object { void Log(LogLevel level, std::u16string_view s); void Log(LogLevel level, std::u16string_view tag, std::u16string_view s); - public: + private: std::list<std::unique_ptr<ILogSource>> sources_; }; diff --git a/include/cru/common/PreConfig.hpp b/include/cru/common/PreConfig.hpp index 4bccef1d..6011dc54 100644 --- a/include/cru/common/PreConfig.hpp +++ b/include/cru/common/PreConfig.hpp @@ -3,6 +3,10 @@ #ifdef _MSC_VER // disable the unnecessary warning about multi-inheritance #pragma warning(disable : 4250) +// disable dll export template issue warning +#pragma warning(disable : 4251) #endif +#ifdef CRU_PLATFORM_WINDOWS #define _CRT_SECURE_NO_WARNINGS +#endif diff --git a/include/cru/common/StringUtil.hpp b/include/cru/common/StringUtil.hpp index 912106c3..0ea842c2 100644 --- a/include/cru/common/StringUtil.hpp +++ b/include/cru/common/StringUtil.hpp @@ -9,9 +9,9 @@ namespace cru { using CodePoint = std::int32_t; constexpr CodePoint k_invalid_code_point = -1; -class TextEncodeException : public std::runtime_error { +class CRU_BASE_API TextEncodeException : public Exception { public: - using runtime_error::runtime_error; + using Exception::Exception; }; inline bool IsUtf16SurrogatePairCodeUnit(char16_t c) { @@ -26,13 +26,14 @@ inline bool IsUtf16SurrogatePairTrailing(char16_t c) { return c >= 0xDC00 && c <= 0xDFFF; } -CodePoint Utf8NextCodePoint(std::string_view str, Index current, - Index* next_position); +CodePoint CRU_BASE_API Utf8NextCodePoint(std::string_view str, Index current, + Index* next_position); -CodePoint Utf16NextCodePoint(std::u16string_view str, Index current, - Index* next_position); -CodePoint Utf16PreviousCodePoint(std::u16string_view str, Index current, - Index* previous_position); +CodePoint CRU_BASE_API Utf16NextCodePoint(std::u16string_view str, + Index current, Index* next_position); +CodePoint CRU_BASE_API Utf16PreviousCodePoint(std::u16string_view str, + Index current, + Index* previous_position); template <typename StringType> using NextCodePointFunctionType = CodePoint (*)(StringType, Index, Index*); @@ -117,37 +118,49 @@ class CodePointIterator { mutable Index next_position_cache_; }; +extern template CRU_BASE_API class CodePointIterator<std::string_view, + &Utf8NextCodePoint>; +extern template CRU_BASE_API class CodePointIterator<std::u16string_view, + &Utf16NextCodePoint>; + using Utf8CodePointIterator = CodePointIterator<std::string_view, &Utf8NextCodePoint>; using Utf16CodePointIterator = CodePointIterator<std::u16string_view, &Utf16NextCodePoint>; -void Utf8EncodeCodePointAppend(CodePoint code_point, std::string& str); -void Utf16EncodeCodePointAppend(CodePoint code_point, std::u16string& str); +void CRU_BASE_API Utf8EncodeCodePointAppend(CodePoint code_point, + std::string& str); +void CRU_BASE_API Utf16EncodeCodePointAppend(CodePoint code_point, + std::u16string& str); -std::string ToUtf8(std::u16string_view s); -std::u16string ToUtf16(std::string_view s); +std::string CRU_BASE_API ToUtf8(std::u16string_view s); +std::u16string CRU_BASE_API ToUtf16(std::string_view s); // If given s is not a valid utf16 string, return value is UD. -bool Utf16IsValidInsertPosition(std::u16string_view s, gsl::index position); +bool CRU_BASE_API Utf16IsValidInsertPosition(std::u16string_view s, + gsl::index position); // Return position after the character making predicate returns true or 0 if no // character doing so. -gsl::index Utf16BackwardUntil(std::u16string_view str, gsl::index position, - const std::function<bool(CodePoint)>& predicate); +gsl::index CRU_BASE_API +Utf16BackwardUntil(std::u16string_view str, gsl::index position, + const std::function<bool(CodePoint)>& predicate); // Return position before the character making predicate returns true or // str.size() if no character doing so. -gsl::index Utf16ForwardUntil(std::u16string_view str, gsl::index position, - const std::function<bool(CodePoint)>& predicate); - -gsl::index Utf16PreviousWord(std::u16string_view str, gsl::index position, - bool* is_space = nullptr); -gsl::index Utf16NextWord(std::u16string_view str, gsl::index position, - bool* is_space = nullptr); - -char16_t ToLower(char16_t c); -char16_t ToUpper(char16_t c); -std::u16string ToLower(std::u16string_view s); -std::u16string ToUpper(std::u16string_view s); +gsl::index CRU_BASE_API +Utf16ForwardUntil(std::u16string_view str, gsl::index position, + const std::function<bool(CodePoint)>& predicate); + +gsl::index CRU_BASE_API Utf16PreviousWord(std::u16string_view str, + gsl::index position, + bool* is_space = nullptr); +gsl::index CRU_BASE_API Utf16NextWord(std::u16string_view str, + gsl::index position, + bool* is_space = nullptr); + +char16_t CRU_BASE_API ToLower(char16_t c); +char16_t CRU_BASE_API ToUpper(char16_t c); +std::u16string CRU_BASE_API ToLower(std::u16string_view s); +std::u16string CRU_BASE_API ToUpper(std::u16string_view s); } // namespace cru diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 73ad9456..cfd5be15 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -1,5 +1,5 @@ set(CRU_BASE_INCLUDE_DIR ${CRU_INCLUDE_DIR}/cru/common) -add_library(cru_base STATIC +add_library(cru_base SHARED Logger.cpp StringUtil.cpp ) @@ -15,6 +15,13 @@ target_sources(cru_base PUBLIC ) target_include_directories(cru_base PUBLIC ${CRU_INCLUDE_DIR}) target_compile_definitions(cru_base PUBLIC $<$<CONFIG:Debug>:CRU_DEBUG>) +target_compile_definitions(cru_base PRIVATE CRU_BASE_EXPORT_API) + +if (WIN32) + target_compile_definitions(cru_base PUBLIC CRU_PLATFORM_WINDOWS) +else() + target_compile_definitions(cru_base PUBLIC CRU_PLATFORM_UNIX) +endif() find_package(Microsoft.GSL CONFIG REQUIRED) find_package(fmt CONFIG REQUIRED) diff --git a/src/common/StringUtil.cpp b/src/common/StringUtil.cpp index bf95f88d..54adebd9 100644 --- a/src/common/StringUtil.cpp +++ b/src/common/StringUtil.cpp @@ -23,13 +23,13 @@ CodePoint Utf8NextCodePoint(std::string_view str, Index current, auto read_next_folowing_code = [&str, ¤t]() -> CodePoint { if (current == static_cast<Index>(str.length())) throw TextEncodeException( - "Unexpected end when read continuing byte of multi-byte code " + u"Unexpected end when read continuing byte of multi-byte code " "point."); const auto u = static_cast<std::uint8_t>(str[current]); if (!(u & (1u << 7)) || (u & (1u << 6))) { throw TextEncodeException( - "Unexpected bad-format (not 0b10xxxxxx) continuing byte of " + u"Unexpected bad-format (not 0b10xxxxxx) continuing byte of " "multi-byte code point."); } @@ -42,7 +42,7 @@ CodePoint Utf8NextCodePoint(std::string_view str, Index current, if ((1u << 4) & cu0) { // 4-length code point if (cu0 & (1u << 3)) { throw TextEncodeException( - "Unexpected bad-format begin byte (not 0b11110xxx) of 4-byte" + u"Unexpected bad-format begin byte (not 0b11110xxx) of 4-byte" "code point."); } @@ -67,7 +67,7 @@ CodePoint Utf8NextCodePoint(std::string_view str, Index current, } } else { throw TextEncodeException( - "Unexpected bad-format (0b10xxxxxx) begin byte of a code point."); + u"Unexpected bad-format (0b10xxxxxx) begin byte of a code point."); } } else { result = static_cast<CodePoint>(cu0); @@ -92,13 +92,13 @@ CodePoint Utf16NextCodePoint(std::u16string_view str, Index current, } else if (IsUtf16SurrogatePairLeading(cu0)) { // 2-length code point if (current >= static_cast<Index>(str.length())) { throw TextEncodeException( - "Unexpected end when reading second code unit of surrogate pair."); + u"Unexpected end when reading second code unit of surrogate pair."); } const auto cu1 = str[current++]; if (!IsUtf16SurrogatePairTrailing(cu1)) { throw TextEncodeException( - "Unexpected bad-range second code unit of surrogate pair."); + u"Unexpected bad-range second code unit of surrogate pair."); } const auto s0 = ExtractBits<std::uint16_t, 10, CodePoint>(cu0) << 10; @@ -108,7 +108,7 @@ CodePoint Utf16NextCodePoint(std::u16string_view str, Index current, } else { throw TextEncodeException( - "Unexpected bad-range first code unit of surrogate pair."); + u"Unexpected bad-range first code unit of surrogate pair."); } } @@ -129,13 +129,13 @@ CodePoint Utf16PreviousCodePoint(std::u16string_view str, Index current, } else if (IsUtf16SurrogatePairTrailing(cu0)) { // 2-length code point if (current <= 0) { throw TextEncodeException( - "Unexpected end when reading first code unit of surrogate pair."); + u"Unexpected end when reading first code unit of surrogate pair."); } const auto cu1 = str[--current]; if (!IsUtf16SurrogatePairLeading(cu1)) { throw TextEncodeException( - "Unexpected bad-range first code unit of surrogate pair."); + u"Unexpected bad-range first code unit of surrogate pair."); } const auto s0 = ExtractBits<std::uint16_t, 10, CodePoint>(cu1) << 10; @@ -145,7 +145,7 @@ CodePoint Utf16PreviousCodePoint(std::u16string_view str, Index current, } else { throw TextEncodeException( - "Unexpected bad-range second code unit of surrogate pair."); + u"Unexpected bad-range second code unit of surrogate pair."); } } @@ -153,6 +153,9 @@ CodePoint Utf16PreviousCodePoint(std::u16string_view str, Index current, return result; } +template class CodePointIterator<std::string_view, &Utf8NextCodePoint>; +template class CodePointIterator<std::u16string_view, &Utf16NextCodePoint>; + void Utf8EncodeCodePointAppend(CodePoint code_point, std::string& str) { auto write_continue_byte = [&str](std::uint8_t byte6) { str.push_back((1u << 7) + (((1u << 6) - 1) & byte6)); @@ -188,7 +191,7 @@ void Utf8EncodeCodePointAppend(CodePoint code_point, std::string& str) { write_continue_byte( ExtractBits<std::uint32_t, 6, std::uint8_t>(unsigned_code_point)); } else { - throw TextEncodeException("Code point out of range."); + throw TextEncodeException(u"Code point out of range."); } } @@ -203,7 +206,7 @@ void Utf16EncodeCodePointAppend(CodePoint code_point, std::u16string& str) { str.push_back(static_cast<char16_t>( ExtractBits<std::uint32_t, 10, std::uint32_t>(u) + 0xDC00u)); } else { - throw TextEncodeException("Code point out of range."); + throw TextEncodeException(u"Code point out of range."); } } |