aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.vscode/settings.json3
-rw-r--r--CMakeLists.txt5
-rw-r--r--include/cru/common/Base.hpp33
-rw-r--r--include/cru/common/Logger.hpp6
-rw-r--r--include/cru/common/PreConfig.hpp4
-rw-r--r--include/cru/common/StringUtil.hpp67
-rw-r--r--src/common/CMakeLists.txt9
-rw-r--r--src/common/StringUtil.cpp27
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, &current]() -> 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.");
}
}