diff options
-rw-r--r-- | include/cru/common/String.hpp | 104 | ||||
-rw-r--r-- | include/cru/platform/Color.hpp | 12 | ||||
-rw-r--r-- | include/cru/platform/GraphBase.hpp | 18 | ||||
-rw-r--r-- | src/common/String.cpp | 41 | ||||
-rw-r--r-- | src/platform/Color.cpp | 28 |
5 files changed, 162 insertions, 41 deletions
diff --git a/include/cru/common/String.hpp b/include/cru/common/String.hpp index 4859a696..47b20147 100644 --- a/include/cru/common/String.hpp +++ b/include/cru/common/String.hpp @@ -8,12 +8,15 @@ #include <array> #include <charconv> #include <iterator> +#include <limits> #include <stdexcept> #include <system_error> #include <type_traits> #include <vector> namespace cru { +class StringView; + class CRU_BASE_API String { public: static String FromUtf8(std::string_view str) { @@ -135,6 +138,7 @@ class CRU_BASE_API String { return this->insert(pos, &value, 1); } iterator insert(const_iterator pos, const std::uint16_t* str, Index size); + iterator insert(const_iterator pos, StringView str); iterator erase(const_iterator pos) { return this->erase(pos, pos + 1); } iterator erase(const_iterator start, const_iterator end); void push_back(std::uint16_t value) { this->append(value); } @@ -144,6 +148,7 @@ class CRU_BASE_API String { this->insert(cend(), str, size); } void append(const String& other) { append(other.data(), other.size()); } + inline void append(StringView str); public: String& operator+=(const String& other) { @@ -224,9 +229,9 @@ struct FormatToken { String data; }; -std::vector<FormatToken> ParseToFormatTokenList(const String& str); +std::vector<FormatToken> CRU_BASE_API ParseToFormatTokenList(const String& str); -void FormatAppendFromFormatTokenList( +void CRU_BASE_API FormatAppendFromFormatTokenList( String& current, const std::vector<FormatToken>& format_token_list, Index index); @@ -263,4 +268,99 @@ template <typename... T> String String::Format(T&&... args) const { return cru::Format(*this, std::forward<T>(args)...); } + +class CRU_BASE_API StringView { + public: + using value_type = std::uint16_t; + using size_type = Index; + using difference_type = Index; + using reference = std::uint16_t&; + using const_reference = const std::uint16_t&; + using pointer = std::uint16_t*; + using const_pointer = const std::uint16_t*; + using iterator = const std::uint16_t*; + using const_iterator = const std::uint16_t*; + using reverse_iterator = std::reverse_iterator<iterator>; + using const_reverse_iterator = std::reverse_iterator<const_iterator>; + + StringView() = default; + + StringView(const std::uint16_t* ptr); + StringView(const std::uint16_t* ptr, Index size) : ptr_(ptr), size_(size) {} + + StringView(const char16_t* ptr) + : StringView(reinterpret_cast<const std::uint16_t*>(ptr)) {} + StringView(const char16_t* ptr, Index size) + : StringView(reinterpret_cast<const std::uint16_t*>(ptr), size) {} + + StringView(const String& str) : StringView(str.data(), str.size()) {} + + CRU_DEFAULT_COPY(StringView) + CRU_DEFAULT_MOVE(StringView) ~StringView() = default; + + Index size() const { return size_; } + const std::uint16_t* data() const { return ptr_; } + + public: + iterator begin() { return this->ptr_; } + const_iterator begin() const { return this->ptr_; } + const_iterator cbegin() const { return this->ptr_; } + + iterator end() { return this->ptr_ + this->size_; } + const_iterator end() const { return this->ptr_ + this->size_; } + const_iterator cend() const { return this->ptr_ + this->size_; } + + reverse_iterator rbegin() { return reverse_iterator{begin()}; } + const_reverse_iterator rbegin() const { + return const_reverse_iterator{begin()}; + } + const_reverse_iterator crbegin() const { + return const_reverse_iterator{cbegin()}; + } + + reverse_iterator rend() { return reverse_iterator{end()}; } + const_reverse_iterator rend() const { return const_reverse_iterator{end()}; } + const_reverse_iterator crend() const { + return const_reverse_iterator{cend()}; + } + + StringView substr(Index pos); + StringView substr(Index pos, Index size); + + int Compare(const StringView& other) const; + + String ToString() const { return String(ptr_, size_); } + + std::uint16_t operator[](Index index) const { return ptr_[index]; } + + private: + const std::uint16_t* ptr_; + Index size_; +}; + +CRU_DEFINE_COMPARE_OPERATORS(StringView) + +inline String::iterator String::insert(const_iterator pos, StringView str) { + return insert(pos, str.data(), str.size()); +} + +inline void String::append(StringView str) { + this->append(str.data(), str.size()); +} } // namespace cru + +template <> +struct std::hash<cru::String> { + std::size_t operator()(const cru::String& value) const { + return std::hash<std::u16string_view>{}(std::u16string_view( + reinterpret_cast<const char16_t*>(value.data()), value.size())); + } +}; + +template <> +struct std::hash<cru::StringView> { + std::size_t operator()(const cru::StringView& value) const { + return std::hash<std::u16string_view>{}(std::u16string_view( + reinterpret_cast<const char16_t*>(value.data()), value.size())); + } +}; diff --git a/include/cru/platform/Color.hpp b/include/cru/platform/Color.hpp index 3388de25..3a72aa65 100644 --- a/include/cru/platform/Color.hpp +++ b/include/cru/platform/Color.hpp @@ -1,6 +1,8 @@ #pragma once #include "cru/platform/Base.hpp" +#include "cru/common/String.hpp" + #include <boost/functional/hash.hpp> #include <cstdint> @@ -37,15 +39,14 @@ struct CRU_PLATFORM_API Color { float GetFloatBlue() const { return static_cast<float>(blue) / 255.f; } float GetFloatAlpha() const { return static_cast<float>(alpha) / 255.f; } - std::string ToUtf8String() const; - std::u16string ToString() const; + String ToString() const; std::uint8_t red; std::uint8_t green; std::uint8_t blue; std::uint8_t alpha; - static std::optional<Color> Parse(std::u16string_view string, + static std::optional<Color> Parse(StringView string, bool parse_predefined_color = true); }; @@ -252,9 +253,8 @@ struct std::hash<cru::platform::Color> { namespace cru::platform { namespace details { -extern const std::unordered_map<std::u16string_view, Color> - predefined_name_color_map; +extern const std::unordered_map<StringView, Color> predefined_name_color_map; } // namespace details -std::optional<Color> GetPredefinedColorByName(std::u16string_view name); +std::optional<Color> GetPredefinedColorByName(StringView name); } // namespace cru::platform diff --git a/include/cru/platform/GraphBase.hpp b/include/cru/platform/GraphBase.hpp index 2cfc9cc4..e7201ec0 100644 --- a/include/cru/platform/GraphBase.hpp +++ b/include/cru/platform/GraphBase.hpp @@ -1,8 +1,6 @@ #pragma once #include "cru/common/Base.hpp" -#include "Color.hpp" -#include "cru/common/Format.hpp" #include "cru/common/Range.hpp" #include "cru/common/String.hpp" @@ -20,10 +18,6 @@ struct Point final { constexpr Point(const float x, const float y) : x(x), y(y) {} explicit constexpr Point(const Size& size); - String ToDebugString() const { - return Format(u"({}, {})", ToUtf16String(x), ToUtf16String(y)); - } - constexpr Point& operator+=(const Point& other) { this->x += other.x; this->y += other.y; @@ -50,6 +44,10 @@ constexpr bool operator!=(const Point& left, const Point& right) { return !(left == right); } +inline String ToString(const Point& point) { + return Format(u"(x: {}, y: {})", point.x, point.y); +} + struct Size final { constexpr Size() = default; constexpr Size(const float width, const float height) @@ -62,10 +60,6 @@ struct Size final { std::numeric_limits<float>::max()}; } - String ToDebugString() const { - return Format(u"({}, {})", ToUtf16String(width), ToUtf16String(height)); - } - float width = 0; float height = 0; }; @@ -88,6 +82,10 @@ constexpr bool operator!=(const Size& left, const Size& right) { return !(left == right); } +inline String ToString(const Size& size) { + return Format(u"(width: {}, height: {})", size.width, size.height); +} + struct Thickness final { constexpr Thickness() : Thickness(0) {} diff --git a/src/common/String.cpp b/src/common/String.cpp index 6d958688..602bcc51 100644 --- a/src/common/String.cpp +++ b/src/common/String.cpp @@ -1,8 +1,11 @@ #include "cru/common/String.hpp" #include "cru/common/StringUtil.hpp" +#include <gsl/gsl> + #include <algorithm> #include <cstring> +#include <functional> #include <string_view> namespace cru { @@ -302,4 +305,42 @@ void FormatAppendFromFormatTokenList( } } // namespace details +StringView::StringView(const std::uint16_t* ptr) + : ptr_(ptr), size_(GetStrSize(ptr)) {} + +int StringView::Compare(const StringView& other) const { + const_iterator i1 = cbegin(); + const_iterator i2 = other.cbegin(); + + const_iterator end1 = cend(); + const_iterator end2 = other.cend(); + + while (i1 != end1 && i2 != end2) { + int r = cru::Compare(*i1, *i2); + if (r != 0) return r; + i1++; + i2++; + } + + if (i1 == end1) { + if (i2 == end2) { + return 0; + } else { + return -1; + } + } else { + return 1; + } +} + +StringView StringView::substr(Index pos) { + Expects(pos >= 0 && pos < size_); + return StringView(ptr_ + pos, size_ - pos); +} + +StringView StringView::substr(Index pos, Index size) { + Expects(pos >= 0 && pos < size_); + return StringView(ptr_ + pos, std::min(size, size_ - pos)); +} + } // namespace cru diff --git a/src/platform/Color.cpp b/src/platform/Color.cpp index c4cc511b..52534048 100644 --- a/src/platform/Color.cpp +++ b/src/platform/Color.cpp @@ -8,24 +8,7 @@ #include <string_view> namespace cru::platform { -std::string Color::ToUtf8String() const { - auto to_hex = [](std::uint8_t v) -> char { - return v >= 10 ? v - 10 + 'a' : v + '0'; - }; - - auto to_two_hex_digit = [to_hex](std::uint8_t v) -> std::string { - return {to_hex(v /= 16), to_hex(v %= 16)}; - }; - - std::string result = "#"; - result.append(to_two_hex_digit(red)); - result.append(to_two_hex_digit(green)); - result.append(to_two_hex_digit(blue)); - result.append(to_two_hex_digit(alpha)); - return result; -} - -std::u16string Color::ToString() const { +String Color::ToString() const { auto to_hex = [](std::uint8_t v) -> char16_t { return v >= 10 ? v - 10 + u'a' : v + u'0'; }; @@ -42,7 +25,7 @@ std::u16string Color::ToString() const { return result; } -std::optional<Color> Color::Parse(std::u16string_view string, +std::optional<Color> Color::Parse(StringView string, bool parse_predefined_color) { if (parse_predefined_color) { auto optional_predefined_color = GetPredefinedColorByName(string); @@ -58,8 +41,7 @@ std::optional<Color> Color::Parse(std::u16string_view string, return std::nullopt; }; - auto get_num_for_two_digit = - [get_num](std::u16string_view str) -> std::optional<int> { + auto get_num_for_two_digit = [get_num](StringView str) -> std::optional<int> { int num = 0; auto d1 = get_num(str[0]); if (!d1) return std::nullopt; @@ -102,7 +84,7 @@ std::optional<Color> Color::Parse(std::u16string_view string, } namespace details { -const std::unordered_map<std::u16string_view, Color> predefined_name_color_map{ +const std::unordered_map<StringView, Color> predefined_name_color_map{ {u"transparent", colors::transparent}, {u"black", colors::black}, {u"silver", colors::silver}, @@ -255,7 +237,7 @@ const std::unordered_map<std::u16string_view, Color> predefined_name_color_map{ }; } // namespace details -std::optional<Color> GetPredefinedColorByName(std::u16string_view name) { +std::optional<Color> GetPredefinedColorByName(StringView name) { auto result = details::predefined_name_color_map.find(name); if (result != details::predefined_name_color_map.cend()) { return result->second; |