aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/cru/common/Exception.hpp2
-rw-r--r--include/cru/common/HandlerRegistry.hpp1
-rw-r--r--include/cru/common/Logger.hpp26
-rw-r--r--include/cru/common/String.hpp98
-rw-r--r--include/cru/platform/Check.hpp15
-rw-r--r--include/cru/platform/GraphBase.hpp11
-rw-r--r--include/cru/platform/gui/InputMethod.hpp51
-rw-r--r--include/cru/ui/render/MeasureRequirement.hpp14
8 files changed, 149 insertions, 69 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
diff --git a/include/cru/platform/Check.hpp b/include/cru/platform/Check.hpp
index 9ecd2d1d..5d99aa9c 100644
--- a/include/cru/platform/Check.hpp
+++ b/include/cru/platform/Check.hpp
@@ -2,9 +2,8 @@
#include "Exception.hpp"
#include "Resource.hpp"
-#include "cru/common/StringUtil.hpp"
+#include "cru/common/String.hpp"
-#include <fmt/format.h>
#include <memory>
#include <type_traits>
@@ -15,10 +14,10 @@ TTarget* CheckPlatform(IPlatformResource* resource,
Expects(resource);
const auto result = dynamic_cast<TTarget*>(resource);
if (result == nullptr) {
- throw UnsupportPlatformException(String::FromUtf8(fmt::format(
- "Try to convert resource to target platform failed. Platform id of "
+ throw UnsupportPlatformException(Format(
+ u"Try to convert resource to target platform failed. Platform id of "
"resource to convert: {} . Target platform id: {} .",
- resource->GetPlatformId().ToUtf8(), target_platform.ToUtf8())));
+ resource->GetPlatformId(), target_platform));
}
return result;
}
@@ -31,10 +30,10 @@ std::shared_ptr<TTarget> CheckPlatform(const std::shared_ptr<TSource>& resource,
Expects(resource);
const auto result = std::dynamic_pointer_cast<TTarget>(resource);
if (result == nullptr) {
- throw UnsupportPlatformException(String::FromUtf8(fmt::format(
- "Try to convert resource to target platform failed. Platform id of "
+ throw UnsupportPlatformException(Format(
+ u"Try to convert resource to target platform failed. Platform id of "
"resource to convert: {} . Target platform id: {} .",
- resource->GetPlatformId().ToUtf8(), target_platform.ToUtf8())));
+ resource->GetPlatformId(), target_platform));
}
return result;
}
diff --git a/include/cru/platform/GraphBase.hpp b/include/cru/platform/GraphBase.hpp
index cc0ffcc7..2cfc9cc4 100644
--- a/include/cru/platform/GraphBase.hpp
+++ b/include/cru/platform/GraphBase.hpp
@@ -4,8 +4,8 @@
#include "Color.hpp"
#include "cru/common/Format.hpp"
#include "cru/common/Range.hpp"
+#include "cru/common/String.hpp"
-#include <fmt/core.h>
#include <cstdint>
#include <limits>
#include <optional>
@@ -20,8 +20,8 @@ struct Point final {
constexpr Point(const float x, const float y) : x(x), y(y) {}
explicit constexpr Point(const Size& size);
- std::u16string ToDebugString() const {
- return fmt::format(u"({}, {})", ToUtf16String(x), ToUtf16String(y));
+ String ToDebugString() const {
+ return Format(u"({}, {})", ToUtf16String(x), ToUtf16String(y));
}
constexpr Point& operator+=(const Point& other) {
@@ -62,9 +62,8 @@ struct Size final {
std::numeric_limits<float>::max()};
}
- std::u16string ToDebugString() const {
- return fmt::format(u"({}, {})", ToUtf16String(width),
- ToUtf16String(height));
+ String ToDebugString() const {
+ return Format(u"({}, {})", ToUtf16String(width), ToUtf16String(height));
}
float width = 0;
diff --git a/include/cru/platform/gui/InputMethod.hpp b/include/cru/platform/gui/InputMethod.hpp
index 9b07959c..c259e63c 100644
--- a/include/cru/platform/gui/InputMethod.hpp
+++ b/include/cru/platform/gui/InputMethod.hpp
@@ -3,7 +3,6 @@
#include "cru/common/Event.hpp"
-#include <fmt/format.h>
#include <memory>
#include <vector>
@@ -54,28 +53,28 @@ struct IInputMethodContext : virtual IPlatformResource {
};
} // namespace cru::platform::gui
-template <>
-struct fmt::formatter<cru::platform::gui::CompositionText, char16_t>
- : fmt::formatter<std::u16string_view, char16_t> {
- auto parse(fmt::basic_format_parse_context<char16_t>& ctx) {
- return fmt::formatter<std::u16string_view, char16_t>::parse(ctx);
- }
-
- template <typename FormatContext>
- auto format(const cru::platform::gui::CompositionText& ct,
- FormatContext& ctx) {
- auto output = ctx.out();
- output = format_to(output, u"text: {}\n", ct.text);
- output = format_to(output, u"clauses:\n");
- for (gsl::index i = 0; i < static_cast<gsl::index>(ct.clauses.size());
- i++) {
- const auto& clause = ct.clauses[i];
- output =
- format_to(output, u"\t{}. start: {} end: {}{}\n", i, clause.start,
- clause.end, clause.target ? u" target" : u"");
- }
- output = format_to(output, u"selection: position: {} count: {}",
- ct.selection.position, ct.selection.count);
- return output;
- }
-};
+// template <>
+// struct fmt::formatter<cru::platform::gui::CompositionText, char16_t>
+// : fmt::formatter<std::u16string_view, char16_t> {
+// auto parse(fmt::basic_format_parse_context<char16_t>& ctx) {
+// return fmt::formatter<std::u16string_view, char16_t>::parse(ctx);
+// }
+
+// template <typename FormatContext>
+// auto format(const cru::platform::gui::CompositionText& ct,
+// FormatContext& ctx) {
+// auto output = ctx.out();
+// output = format_to(output, u"text: {}\n", ct.text);
+// output = format_to(output, u"clauses:\n");
+// for (gsl::index i = 0; i < static_cast<gsl::index>(ct.clauses.size());
+// i++) {
+// const auto& clause = ct.clauses[i];
+// output =
+// format_to(output, u"\t{}. start: {} end: {}{}\n", i, clause.start,
+// clause.end, clause.target ? u" target" : u"");
+// }
+// output = format_to(output, u"selection: position: {} count: {}",
+// ct.selection.position, ct.selection.count);
+// return output;
+// }
+// };
diff --git a/include/cru/ui/render/MeasureRequirement.hpp b/include/cru/ui/render/MeasureRequirement.hpp
index 6a0c6952..ff9dd6e3 100644
--- a/include/cru/ui/render/MeasureRequirement.hpp
+++ b/include/cru/ui/render/MeasureRequirement.hpp
@@ -1,9 +1,8 @@
#pragma once
#include "Base.hpp"
-#include "cru/common/Format.hpp"
+#include "cru/common/String.hpp"
-#include <fmt/core.h>
#include <algorithm>
#include <limits>
#include <string>
@@ -169,9 +168,8 @@ struct MeasureSize {
};
}
- std::u16string ToDebugString() const {
- return fmt::format(u"({}, {})", width.ToDebugString(),
- height.ToDebugString());
+ String ToDebugString() const {
+ return Format(u"({}, {})", width.ToDebugString(), height.ToDebugString());
}
constexpr static MeasureSize NotSpecified() {
@@ -240,9 +238,9 @@ struct MeasureRequirement {
return result;
}
- std::u16string ToDebugString() const {
- return fmt::format(u"{{min: {}, max: {}}}", min.ToDebugString(),
- max.ToDebugString());
+ String ToDebugString() const {
+ return Format(u"{{min: {}, max: {}}}", min.ToDebugString(),
+ max.ToDebugString());
}
constexpr static MeasureRequirement Merge(const MeasureRequirement& left,