aboutsummaryrefslogtreecommitdiff
path: root/include/cru
diff options
context:
space:
mode:
Diffstat (limited to 'include/cru')
-rw-r--r--include/cru/common/Format.hpp140
-rw-r--r--include/cru/common/Logger.hpp1
-rw-r--r--include/cru/common/String.hpp79
-rw-r--r--include/cru/common/StringUtil.hpp1
-rw-r--r--include/cru/platform/Check.hpp1
-rw-r--r--include/cru/platform/Color.hpp1
-rw-r--r--include/cru/platform/GraphicsBase.hpp1
-rw-r--r--include/cru/platform/gui/InputMethod.hpp25
8 files changed, 146 insertions, 103 deletions
diff --git a/include/cru/common/Format.hpp b/include/cru/common/Format.hpp
new file mode 100644
index 00000000..d53a5720
--- /dev/null
+++ b/include/cru/common/Format.hpp
@@ -0,0 +1,140 @@
+#pragma once
+
+#include "Exception.hpp"
+#include "String.hpp"
+
+namespace cru {
+inline String ToString(bool value) {
+ return value ? String(u"true") : String(u"false");
+}
+
+template <typename T>
+std::enable_if_t<std::is_integral_v<T>, String> ToString(T value) {
+ std::array<char, 50> buffer;
+ auto result =
+ std::to_chars(buffer.data(), buffer.data() + buffer.size(), value);
+
+ if (result.ec == std::errc{}) {
+ } else {
+ throw std::invalid_argument("Failed to convert value to chars.");
+ }
+
+ auto size = result.ptr - buffer.data();
+ auto b = new char16_t[size + 1];
+ b[size] = 0;
+ std::copy(buffer.data(), result.ptr, b);
+ return String::FromBuffer(b, size, size);
+}
+
+template <typename T>
+std::enable_if_t<std::is_floating_point_v<T>, String> ToString(T value) {
+ auto str = std::to_string(value);
+ return String(str.cbegin(), str.cend());
+}
+
+template <typename T>
+std::enable_if_t<
+ std::is_convertible_v<decltype(ToString(std::declval<const T&>)), String>,
+ String>
+ToString(const T& value, StringView option) {
+ return ToString(value);
+}
+
+inline String ToString(String value) { return value; }
+
+namespace details {
+enum class FormatTokenType { PlaceHolder, Text };
+enum class FormatPlaceHolderType { None, Positioned, Named };
+
+struct FormatToken {
+ static FormatToken Text() {
+ return FormatToken{FormatTokenType::Text, {}, {}, 0, {}, {}};
+ }
+
+ static FormatToken NonePlaceHolder(String option) {
+ return FormatToken(FormatTokenType::PlaceHolder, {},
+ FormatPlaceHolderType::None, 0, {}, std::move(option));
+ }
+
+ static FormatToken PositionedPlaceHolder(int position, String option) {
+ return FormatToken(FormatTokenType::PlaceHolder, {},
+ FormatPlaceHolderType::Positioned, position, {},
+ std::move(option));
+ }
+
+ static FormatToken NamedPlaceHolder(String name, String option) {
+ return FormatToken(FormatTokenType::PlaceHolder, {},
+ FormatPlaceHolderType::Named, 0, std::move(name),
+ std::move(option));
+ }
+
+ FormatToken(FormatTokenType type, String data,
+ FormatPlaceHolderType place_holder_type,
+ int place_holder_position, String place_holder_name,
+ String place_holder_option)
+ : type(type),
+ data(std::move(data)),
+ place_holder_type(place_holder_type),
+ place_holder_position(place_holder_position),
+ place_holder_name(std::move(place_holder_name)),
+ place_holder_option(std::move(place_holder_option)) {}
+
+ CRU_DEFAULT_COPY(FormatToken)
+ CRU_DEFAULT_MOVE(FormatToken)
+
+ CRU_DEFAULT_DESTRUCTOR(FormatToken)
+
+ FormatTokenType type;
+ String data;
+ FormatPlaceHolderType place_holder_type;
+ int place_holder_position;
+ String place_holder_name;
+ String place_holder_option;
+};
+
+std::vector<FormatToken> CRU_BASE_API ParseToFormatTokenList(const String& str);
+
+void CRU_BASE_API 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 < static_cast<Index>(format_token_list.size()); i++) {
+ const auto& token = format_token_list[i];
+ if (token.type == FormatTokenType::PlaceHolder) {
+ if (token.place_holder_type == FormatPlaceHolderType::None) {
+ current += ToString(std::forward<TA>(args0), token.place_holder_option);
+ FormatAppendFromFormatTokenList(current, format_token_list, i + 1,
+ std::forward<T>(args)...);
+
+ return;
+ } else {
+ throw Exception(
+ u"Currently do not support positional or named place holder.");
+ }
+ } 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/common/Logger.hpp b/include/cru/common/Logger.hpp
index 7d43fc5a..c4a3e54a 100644
--- a/include/cru/common/Logger.hpp
+++ b/include/cru/common/Logger.hpp
@@ -2,6 +2,7 @@
#include "Base.hpp"
#include "String.hpp"
+#include "Format.hpp"
#include <list>
#include <memory>
diff --git a/include/cru/common/String.hpp b/include/cru/common/String.hpp
index dd3da52f..8db012cb 100644
--- a/include/cru/common/String.hpp
+++ b/include/cru/common/String.hpp
@@ -14,6 +14,7 @@
#include <string>
#include <string_view>
#include <system_error>
+#include <tuple>
#include <type_traits>
#include <vector>
@@ -320,84 +321,6 @@ inline String operator+(const String& left, const String& right) {
return result;
}
-inline String ToString(bool value) {
- return value ? String(u"true") : String(u"false");
-}
-
-template <typename T>
-std::enable_if_t<std::is_integral_v<T>, String> ToString(T value) {
- std::array<char, 50> buffer;
- auto result =
- std::to_chars(buffer.data(), buffer.data() + buffer.size(), value);
-
- if (result.ec == std::errc{}) {
- } else {
- throw std::invalid_argument("Failed to convert value to chars.");
- }
-
- auto size = result.ptr - buffer.data();
- auto b = new char16_t[size + 1];
- b[size] = 0;
- std::copy(buffer.data(), result.ptr, b);
- return String::FromBuffer(b, size, size);
-}
-
-template <typename T>
-std::enable_if_t<std::is_floating_point_v<T>, String> ToString(T value) {
- auto str = std::to_string(value);
- return String(str.cbegin(), str.cend());
-}
-
-inline String ToString(String value) { return value; }
-
-namespace details {
-enum class FormatTokenType { PlaceHolder, Text };
-
-struct FormatToken {
- FormatTokenType type;
- String data;
-};
-
-std::vector<FormatToken> CRU_BASE_API ParseToFormatTokenList(const String& str);
-
-void CRU_BASE_API 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 < static_cast<Index>(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)...);
- return;
- } 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)...);
-}
-
CRU_DEFINE_COMPARE_OPERATORS(StringView)
inline String::iterator String::insert(const_iterator pos, StringView str) {
diff --git a/include/cru/common/StringUtil.hpp b/include/cru/common/StringUtil.hpp
index 3c673db1..2d53fc2b 100644
--- a/include/cru/common/StringUtil.hpp
+++ b/include/cru/common/StringUtil.hpp
@@ -223,6 +223,7 @@ char16_t CRU_BASE_API ToLower(char16_t c);
char16_t CRU_BASE_API ToUpper(char16_t c);
bool CRU_BASE_API IsWhitespace(char16_t c);
+bool CRU_BASE_API IsDigit(char16_t c);
Utf8CodePointIterator CRU_BASE_API CreateUtf8Iterator(const std::byte* buffer,
Index size);
diff --git a/include/cru/platform/Check.hpp b/include/cru/platform/Check.hpp
index 5d99aa9c..121e3505 100644
--- a/include/cru/platform/Check.hpp
+++ b/include/cru/platform/Check.hpp
@@ -3,6 +3,7 @@
#include "Resource.hpp"
#include "cru/common/String.hpp"
+#include "cru/common/Format.hpp"
#include <memory>
#include <type_traits>
diff --git a/include/cru/platform/Color.hpp b/include/cru/platform/Color.hpp
index 94c6c485..cdc6518b 100644
--- a/include/cru/platform/Color.hpp
+++ b/include/cru/platform/Color.hpp
@@ -3,6 +3,7 @@
#include "cru/platform/Base.hpp"
#include "cru/common/String.hpp"
+#include "cru/common/Format.hpp"
#include <cstdint>
#include <optional>
diff --git a/include/cru/platform/GraphicsBase.hpp b/include/cru/platform/GraphicsBase.hpp
index 73b41bb5..088086e9 100644
--- a/include/cru/platform/GraphicsBase.hpp
+++ b/include/cru/platform/GraphicsBase.hpp
@@ -3,6 +3,7 @@
#include "cru/common/Range.hpp"
#include "cru/common/String.hpp"
+#include "cru/common/Format.hpp"
#include <cstdint>
#include <limits>
diff --git a/include/cru/platform/gui/InputMethod.hpp b/include/cru/platform/gui/InputMethod.hpp
index 923a2088..a34aba74 100644
--- a/include/cru/platform/gui/InputMethod.hpp
+++ b/include/cru/platform/gui/InputMethod.hpp
@@ -53,28 +53,3 @@ 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;
-// }
-// };