From ac47be51b79f4c3e49656870e135453eefe759ea Mon Sep 17 00:00:00 2001 From: Steven Le Rouzic Date: Thu, 7 Nov 2024 23:38:52 +0100 Subject: Some more work on asl::string_view --- asl/format.cpp | 2 +- asl/format.hpp | 4 ++-- asl/io.hpp | 2 +- asl/layout.hpp | 8 ++++---- asl/meta.hpp | 2 +- asl/print.cpp | 2 +- asl/span.hpp | 36 ++++++++++++++++++------------------ asl/string_view.hpp | 26 +++++++++++++++++++------- asl/tests/format_tests.cpp | 4 ++-- asl/tests/span_tests.cpp | 18 +++++++++--------- asl/tests/string_view_tests.cpp | 24 ++++++++++++++++++++++++ 11 files changed, 82 insertions(+), 46 deletions(-) (limited to 'asl') diff --git a/asl/format.cpp b/asl/format.cpp index b410d39..a86ce69 100644 --- a/asl/format.cpp +++ b/asl/format.cpp @@ -71,7 +71,7 @@ void asl::format_internals::format( void asl::AslFormat(formatter& f, const char* str) { - f.write(str, static_cast(__builtin_strlen(str))); + f.write(str, static_cast(__builtin_strlen(str))); } void asl::AslFormat(formatter& f, float) diff --git a/asl/format.hpp b/asl/format.hpp index aad9d65..eb8379a 100644 --- a/asl/format.hpp +++ b/asl/format.hpp @@ -52,7 +52,7 @@ public: {} // @Todo Use string_view - constexpr void write(const char* s, int64_t len) + constexpr void write(const char* s, isize_t len) { m_writer->write(s, len); } @@ -76,7 +76,7 @@ void format(writer* w, const char* fmt, const Args&... args) } } -template +template void AslFormat(formatter& f, const char (&str)[N]) { f.write(str, N - 1); diff --git a/asl/io.hpp b/asl/io.hpp index 79c70c2..e7d1c9c 100644 --- a/asl/io.hpp +++ b/asl/io.hpp @@ -14,7 +14,7 @@ public: virtual ~writer() = default; // @Todo Use string view, or span of bytes? - virtual void write(const char* str, int64_t len) = 0; + virtual void write(const char* str, isize_t len) = 0; }; } // namespace asl diff --git a/asl/layout.hpp b/asl/layout.hpp index 5141456..06fbe10 100644 --- a/asl/layout.hpp +++ b/asl/layout.hpp @@ -7,15 +7,15 @@ namespace asl { template -inline constexpr int64_t size_of = static_cast(sizeof(T)); +inline constexpr isize_t size_of = static_cast(sizeof(T)); template -inline constexpr int64_t align_of = static_cast(alignof(T)); +inline constexpr isize_t align_of = static_cast(alignof(T)); struct layout { - int64_t size; - int64_t align; + isize_t size; + isize_t align; constexpr bool operator==(const layout&) const = default; diff --git a/asl/meta.hpp b/asl/meta.hpp index 1d82739..1c058c4 100644 --- a/asl/meta.hpp +++ b/asl/meta.hpp @@ -8,7 +8,7 @@ struct empty {}; template struct id { using type = T; }; -template static constexpr int64_t types_count = sizeof...(Args); +template static constexpr isize_t types_count = sizeof...(Args); template struct integral_constant { static constexpr T value = kValue; }; template using bool_constant = integral_constant; diff --git a/asl/print.cpp b/asl/print.cpp index 6e43bb3..1f55541 100644 --- a/asl/print.cpp +++ b/asl/print.cpp @@ -12,7 +12,7 @@ public: : m_handle{handle} {} - void write(const char* str, int64_t len) override + void write(const char* str, isize_t len) override { fwrite(str, 1, static_cast(len), m_handle); } diff --git a/asl/span.hpp b/asl/span.hpp index fe0e163..e0db059 100644 --- a/asl/span.hpp +++ b/asl/span.hpp @@ -8,19 +8,19 @@ namespace asl { -static constexpr int64_t dynamic_size = -1; +static constexpr isize_t dynamic_size = -1; -template +template class span { - static constexpr bool is_dynamic(int64_t size) + static constexpr bool is_dynamic(isize_t size) { return size < 0; } static constexpr bool kIsDynamic = is_dynamic(kSize); - using SizeType = select_t; + using SizeType = select_t; T* m_data{}; ASL_NO_UNIQUE_ADDRESS SizeType m_size{}; @@ -28,33 +28,33 @@ class span public: constexpr span() requires (kIsDynamic || kSize == 0) = default; - constexpr span(T* data, int64_t size) + constexpr span(T* data, isize_t size) requires kIsDynamic : m_data{data} , m_size{size} {} - constexpr explicit span(T* data, int64_t size) + constexpr explicit span(T* data, isize_t size) requires (!kIsDynamic) : m_data{data} { ASL_ASSERT(size == kSize); } - template + template constexpr span(T (&array)[N]) // NOLINT(*-explicit-conversions) requires (kIsDynamic) : m_data{array} , m_size{N} {} - template + template constexpr span(T (&array)[N]) // NOLINT(*-explicit-conversions) requires (!kIsDynamic) && (N == kSize) : m_data{array} {} - template + template constexpr explicit(!kIsDynamic) span(const span& other) // NOLINT(*-explicit-conversions) requires ( @@ -76,13 +76,13 @@ public: ~span() = default; - constexpr int64_t size() const + constexpr isize_t size() const { if constexpr (kIsDynamic) { return m_size; } else { return kSize; } } - constexpr int64_t size_bytes() const { return size() * size_of; } + constexpr isize_t size_bytes() const { return size() * size_of; } constexpr bool is_empty() const { return size() == 0; } @@ -91,13 +91,13 @@ public: constexpr T* begin() const { return m_data; } constexpr T* end() const { return m_data + size(); } - constexpr T& operator[](int64_t i) const + constexpr T& operator[](isize_t i) const { ASL_ASSERT(i >= 0 && i < size()); return m_data[i]; // NOLINT(*-pointer-arithmetic) } - template + template constexpr auto subspan() const requires ( kOffset >= 0 && @@ -125,7 +125,7 @@ public: } } - constexpr span subspan(int64_t offset, int64_t sub_size = dynamic_size) const + constexpr span subspan(isize_t offset, isize_t sub_size = dynamic_size) const { ASL_ASSERT(offset <= size()); @@ -138,7 +138,7 @@ public: return span{ data() + offset, sub_size }; } - template + template constexpr auto first() const requires ( kSubSize >= 0 && @@ -149,13 +149,13 @@ public: return span{ data(), kSubSize }; } - constexpr span first(int64_t sub_size) const + constexpr span first(isize_t sub_size) const { ASL_ASSERT(sub_size >= 0 && sub_size <= size()); return span{ data(), sub_size }; } - template + template constexpr auto last() const requires ( kSubSize >= 0 && @@ -166,7 +166,7 @@ public: return span{ data() + size() - kSubSize, kSubSize }; } - constexpr span last(int64_t sub_size) const + constexpr span last(isize_t sub_size) const { ASL_ASSERT(sub_size >= 0 && sub_size <= size()); return span{ data() + size() - sub_size, sub_size }; diff --git a/asl/string_view.hpp b/asl/string_view.hpp index 57934fa..9045eda 100644 --- a/asl/string_view.hpp +++ b/asl/string_view.hpp @@ -6,26 +6,23 @@ namespace asl { +// @Todo Replace all the __builtin_strlen + class string_view { const char* m_data{}; - int64_t m_size{}; + isize_t m_size{}; public: constexpr string_view() = default; constexpr string_view(nullptr_t) : string_view() {} // NOLINT(*-explicit-conversions) - constexpr string_view(const char* data, int64_t size) + constexpr string_view(const char* data, isize_t size) : m_data{data} , m_size{size} {} - constexpr string_view(const char* data) // NOLINT(*-explicit-conversions) - : m_data{data} - , m_size{static_cast(__builtin_strlen(data))} - {} - constexpr string_view(const string_view&) = default; constexpr string_view(string_view&&) = default; @@ -33,6 +30,21 @@ public: constexpr string_view& operator=(string_view&&) = default; ~string_view() = default; + + constexpr isize_t size() const { return m_size; } + + constexpr bool is_empty() const { return m_size == 0; } + + constexpr const char* data() const { return m_data; } + + constexpr const char* begin() const { return m_data; } + + constexpr const char* end() const { return m_data + m_size; } // NOLINT(*-pointer-arithmetic) }; } // namespace asl + +constexpr asl::string_view operator ""_sv(const char* s, size_t len) +{ + return asl::string_view(s, static_cast(len)); +} diff --git a/asl/tests/format_tests.cpp b/asl/tests/format_tests.cpp index 81395c2..bfde454 100644 --- a/asl/tests/format_tests.cpp +++ b/asl/tests/format_tests.cpp @@ -12,11 +12,11 @@ static_assert(asl::formattable); class StringSink : public asl::writer { - int64_t m_current_len{}; + isize_t m_current_len{}; char* m_data{}; public: - void write(const char* str, int64_t len) override + void write(const char* str, isize_t len) override { m_data = (char*)realloc(m_data, (size_t)(m_current_len + len + 1)); memcpy(m_data + m_current_len, str, (size_t)len); diff --git a/asl/tests/span_tests.cpp b/asl/tests/span_tests.cpp index aca0fb3..3baaf5c 100644 --- a/asl/tests/span_tests.cpp +++ b/asl/tests/span_tests.cpp @@ -94,14 +94,14 @@ ASL_TEST(conversion) ASL_TEST_EXPECT(span4[2] == 3); } -template +template [[maybe_unused]] static auto try_static_subspan(int) -> decltype(asl::declval().template subspan()); -template +template [[maybe_unused]] static auto try_static_subspan(...) -> asl::empty; -template +template concept invalid_subspan = asl::same_as(0)), asl::empty>; static_assert(asl::same_as, @@ -216,14 +216,14 @@ ASL_TEST(subspan_dynamic) ASL_TEST_EXPECT(s4[1] == 3); } -template +template [[maybe_unused]] static auto try_static_first(int) -> decltype(asl::declval().template first()); -template +template [[maybe_unused]] static auto try_static_first(...) -> asl::empty; -template +template concept invalid_first = asl::same_as(0)), asl::empty>; static_assert(asl::same_as, @@ -320,14 +320,14 @@ ASL_TEST(first_dynamic) ASL_TEST_EXPECT(s3[3] == 4); } -template +template [[maybe_unused]] static auto try_static_last(int) -> decltype(asl::declval().template last()); -template +template [[maybe_unused]] static auto try_static_last(...) -> asl::empty; -template +template concept invalid_last = asl::same_as(0)), asl::empty>; static_assert(asl::same_as, diff --git a/asl/tests/string_view_tests.cpp b/asl/tests/string_view_tests.cpp index f3cc752..dafb91c 100644 --- a/asl/tests/string_view_tests.cpp +++ b/asl/tests/string_view_tests.cpp @@ -1,3 +1,27 @@ #include "asl/string_view.hpp" #include "asl/testing/testing.hpp" +// @Todo Don't use stdlib, remake memcmp +#include + +static_assert(asl::trivially_destructible); +static_assert(asl::trivially_copyable); + +ASL_TEST(default) +{ + asl::string_view s1; + ASL_TEST_EXPECT(s1.is_empty()); + + asl::string_view s2 = nullptr; + ASL_TEST_EXPECT(s2.is_empty()); +} + +ASL_TEST(from_literal) +{ + asl::string_view s1 = "Hello"_sv; + ASL_TEST_ASSERT(s1.size() == 5); + ASL_TEST_EXPECT(memcmp(s1.data(), "Hello", 5) == 0); + + asl::string_view s2 = ""_sv; + ASL_TEST_EXPECT(s2.is_empty()); +} -- cgit