From eb285643ed5dab8125e9c6bc94abd7ef562096a5 Mon Sep 17 00:00:00 2001 From: Steven Le Rouzic Date: Thu, 27 Feb 2025 23:58:57 +0100 Subject: Finish work on deducing this, for now --- asl/base/defer.hpp | 96 ++++++++++++++++----------------- asl/base/defer_tests.cpp | 64 +++++++++++----------- asl/base/utility_tests.cpp | 3 +- asl/containers/buffer.hpp | 55 +++++++------------ asl/containers/hash_map.hpp | 25 +++------ asl/containers/intrusive_list.hpp | 31 +++++------ asl/containers/intrusive_list_tests.cpp | 2 +- asl/logging/logging_tests.cpp | 4 +- asl/strings/string_builder.hpp | 51 +++++++----------- asl/testing/testing.cpp | 2 +- asl/types/maybe_uninit.hpp | 20 +++---- asl/types/option.hpp | 20 ++++--- asl/types/status_or.hpp | 3 +- 13 files changed, 158 insertions(+), 218 deletions(-) (limited to 'asl') diff --git a/asl/base/defer.hpp b/asl/base/defer.hpp index e881d8a..122312a 100644 --- a/asl/base/defer.hpp +++ b/asl/base/defer.hpp @@ -1,48 +1,48 @@ -#pragma once - -#include "asl/base/utility.hpp" -#include "asl/base/functional.hpp" - -namespace asl -{ - -template -class DeferCallback -{ - Callback m_callback; - bool m_moved = false; - -public: - template - explicit DeferCallback(T&& callback) : m_callback(ASL_FWD(callback)) - { - } - - ASL_DELETE_COPY(DeferCallback); - - DeferCallback(DeferCallback&& other) : - m_callback(ASL_MOVE(other.m_callback)), m_moved(exchange(other.m_moved, true)) - { - } - - DeferCallback& operator=(DeferCallback&&) = delete; - - ~DeferCallback() - { - if (!m_moved) { invoke(m_callback); } - } -}; - -struct DeferFactory -{ - template - DeferCallback operator<<(Callback&& callback) const - { - return DeferCallback(ASL_FWD(callback)); - } -}; - -} // namespace asl - -#define ASL_DEFER auto ASL_CONCAT(_defer_, __COUNTER__) = ::asl::DeferFactory{} << - +#pragma once + +#include "asl/base/utility.hpp" +#include "asl/base/functional.hpp" + +namespace asl +{ + +template +class DeferCallback +{ + Callback m_callback; + bool m_moved = false; + +public: + template + explicit DeferCallback(T&& callback) : m_callback(ASL_FWD(callback)) + { + } + + ASL_DELETE_COPY(DeferCallback); + + DeferCallback(DeferCallback&& other) : + m_callback(ASL_MOVE(other.m_callback)), m_moved(exchange(other.m_moved, true)) + { + } + + DeferCallback& operator=(DeferCallback&&) = delete; + + ~DeferCallback() + { + if (!m_moved) { invoke(m_callback); } + } +}; + +struct DeferFactory +{ + template + DeferCallback operator<<(Callback&& callback) const + { + return DeferCallback(ASL_FWD(callback)); + } +}; + +} // namespace asl + +#define ASL_DEFER auto ASL_CONCAT(_defer_, __COUNTER__) = ::asl::DeferFactory{} << + diff --git a/asl/base/defer_tests.cpp b/asl/base/defer_tests.cpp index b5139d5..488350f 100644 --- a/asl/base/defer_tests.cpp +++ b/asl/base/defer_tests.cpp @@ -1,32 +1,32 @@ -#include "asl/base/defer.hpp" -#include "asl/testing/testing.hpp" - -ASL_TEST(defer) -{ - uint32_t a = 0; - - { - ASL_DEFER [&a]() { a |= 1; }; - ASL_TEST_EXPECT(a == 0); - - { - ASL_DEFER [&a]() { a |= 2; }; - ASL_DEFER [&a]() { a |= 4; }; - ASL_TEST_EXPECT(a == 0); - } - - ASL_TEST_EXPECT(a == 6); - - { - ASL_DEFER [&a]() { a |= 8; }; - ASL_TEST_EXPECT(a == 6); - } - - ASL_TEST_EXPECT(a == 14); - - ASL_DEFER [&a]() { a |= 16; }; - ASL_TEST_EXPECT(a == 14); - } - - ASL_TEST_EXPECT(a == 31); -} +#include "asl/base/defer.hpp" +#include "asl/testing/testing.hpp" + +ASL_TEST(defer) +{ + uint32_t a = 0; + + { + ASL_DEFER [&a]() { a |= 1; }; + ASL_TEST_EXPECT(a == 0); + + { + ASL_DEFER [&a]() { a |= 2; }; + ASL_DEFER [&a]() { a |= 4; }; + ASL_TEST_EXPECT(a == 0); + } + + ASL_TEST_EXPECT(a == 6); + + { + ASL_DEFER [&a]() { a |= 8; }; + ASL_TEST_EXPECT(a == 6); + } + + ASL_TEST_EXPECT(a == 14); + + ASL_DEFER [&a]() { a |= 16; }; + ASL_TEST_EXPECT(a == 14); + } + + ASL_TEST_EXPECT(a == 31); +} diff --git a/asl/base/utility_tests.cpp b/asl/base/utility_tests.cpp index d959369..8fd6479 100644 --- a/asl/base/utility_tests.cpp +++ b/asl/base/utility_tests.cpp @@ -8,8 +8,7 @@ template static constexpr int identify(T&&) { return 4; } struct IdentifySelf { - template - constexpr int get(this Self&& self) { return identify(ASL_FWD(self)); } + constexpr int get(this auto&& self) { return identify(ASL_FWD(self)); } }; static int get_const_lref(const IdentifySelf& i) { return ASL_FWD(i).get(); } diff --git a/asl/containers/buffer.hpp b/asl/containers/buffer.hpp index 76562d3..3954d35 100644 --- a/asl/containers/buffer.hpp +++ b/asl/containers/buffer.hpp @@ -381,39 +381,31 @@ public: return *init; } - // @Todo(C++23) Use deducing this - const T* data() const + auto data(this auto&& self) { + using return_type = un_ref_t>*; if constexpr (kInlineCapacity == 0) { - return m_data; + return return_type{ self.m_data }; } else { - return is_on_heap() ? m_data : reinterpret_cast(this); + return self.is_on_heap() ? return_type{ self.m_data } : reinterpret_cast(&self); } } - T* data() + constexpr auto begin(this auto&& self) { - if constexpr (kInlineCapacity == 0) - { - return m_data; - } - else - { - return is_on_heap() ? m_data : reinterpret_cast(this); - } + using type = un_ref_t>; + return contiguous_iterator{self.data()}; } - // @Todo(C++23) Use deducing this - constexpr contiguous_iterator begin() const { return contiguous_iterator{data()}; } - constexpr contiguous_iterator end() const { return contiguous_iterator{data() + size()}; } - - constexpr contiguous_iterator begin() { return contiguous_iterator{data()}; } - constexpr contiguous_iterator end() { return contiguous_iterator{data() + size()}; } + constexpr auto end(this auto&& self) + { + using type = un_ref_t>; + return contiguous_iterator{self.data() + self.size()}; + } - // @Todo(C++23) Deducing this constexpr operator span() const // NOLINT(*-explicit-conversions) { return as_span(); @@ -424,27 +416,16 @@ public: return as_span(); } - constexpr span as_span() const - { - return span{data(), size()}; - } - - constexpr span as_span() - { - return span{data(), size()}; - } - - // @Todo(C++23) Use deducing this - constexpr T& operator[](isize_t i) + constexpr auto as_span(this auto&& self) { - ASL_ASSERT(i >= 0 && i <= size()); - return data()[i]; + using type = un_ref_t>; + return span{self.data(), self.size()}; } - constexpr const T& operator[](isize_t i) const + constexpr auto&& operator[](this auto&& self, isize_t i) { - ASL_ASSERT(i >= 0 && i <= size()); - return data()[i]; + ASL_ASSERT(i >= 0 && i <= self.size()); + return ASL_FWD_LIKE(decltype(self), ASL_FWD(self).data()[i]); } template diff --git a/asl/containers/hash_map.hpp b/asl/containers/hash_map.hpp index 104bd6a..a59e580 100644 --- a/asl/containers/hash_map.hpp +++ b/asl/containers/hash_map.hpp @@ -147,31 +147,18 @@ public: // NOLINTEND(*-pointer-arithmetic) } - // @Todo(C++23) Deducing this template - requires key_hasher && key_comparator - const V* get(const U& value) const + auto get(this auto&& self, const U& value) + requires key_hasher && key_comparator { - isize_t index = Base::find_slot_lookup(value); + using return_type = un_ref_t>*; + isize_t index = self.find_slot_lookup(value); if (index >= 0) { // NOLINTNEXTLINE(*-pointer-arithmetic) - return &Base::m_values[index].as_init_unsafe().value; + return return_type{ &self.m_values[index].as_init_unsafe().value }; } - return nullptr; - } - - template - requires key_hasher && key_comparator - V* get(const U& value) - { - isize_t index = Base::find_slot_lookup(value); - if (index >= 0) - { - // NOLINTNEXTLINE(*-pointer-arithmetic) - return &Base::m_values[index].as_init_unsafe().value; - } - return nullptr; + return return_type{ nullptr }; } }; diff --git a/asl/containers/intrusive_list.hpp b/asl/containers/intrusive_list.hpp index dcf0508..99509b8 100644 --- a/asl/containers/intrusive_list.hpp +++ b/asl/containers/intrusive_list.hpp @@ -76,14 +76,16 @@ public: } } - constexpr T* head() const + constexpr auto head(this auto&& self) { - return m_head; + using return_type = un_ref_t>*; + return return_type{ self.m_head }; } - constexpr T* tail() const + constexpr auto tail(this auto&& self) { - return m_head != nullptr ? m_head->m_prev : nullptr; + using return_type = un_ref_t>*; + return return_type{ self.m_head != nullptr ? self.m_head->m_prev : nullptr }; } void detach(T* node) @@ -169,25 +171,16 @@ public: using iterator = generic_iterator; using const_iterator = generic_iterator; - // @Todo(C++23) Deduplicate with deducing-this maybe - const_iterator begin() const + auto begin(this auto&& self) { - return const_iterator{ head(), is_empty() }; - } - - const_iterator end() const - { - return const_iterator{ head(), true }; + using iterator_type = select_t>, const_iterator, iterator>; + return iterator_type{ self.head(), self.is_empty() }; } - iterator begin() - { - return iterator{ head(), is_empty() }; - } - - iterator end() + auto end(this auto&& self) { - return iterator{ head(), true }; + using iterator_type = select_t>, const_iterator, iterator>; + return iterator_type{ self.head(), true }; } }; diff --git a/asl/containers/intrusive_list_tests.cpp b/asl/containers/intrusive_list_tests.cpp index ceb54a6..373913c 100644 --- a/asl/containers/intrusive_list_tests.cpp +++ b/asl/containers/intrusive_list_tests.cpp @@ -13,7 +13,7 @@ struct IntNode : public asl::intrusive_list_node ASL_TEST(empty_list) { - asl::IntrusiveList list; + const asl::IntrusiveList list; ASL_TEST_EXPECT(list.is_empty()); ASL_TEST_EXPECT(list.head() == nullptr); ASL_TEST_EXPECT(list.tail() == nullptr); diff --git a/asl/logging/logging_tests.cpp b/asl/logging/logging_tests.cpp index d531cda..404f6eb 100644 --- a/asl/logging/logging_tests.cpp +++ b/asl/logging/logging_tests.cpp @@ -14,12 +14,12 @@ ASL_TEST(custom_writer) { asl::StringWriter string_writer{}; asl::log::DefaultLogger&> logger(string_writer); - + asl::log::register_logger(&logger); ASL_DEFER [&logger]() { asl::log::unregister_logger(&logger); }; - + ASL_LOG_INFO("Hello"); auto sv = string_writer.as_string_view(); diff --git a/asl/strings/string_builder.hpp b/asl/strings/string_builder.hpp index d30f1d5..b983bc9 100644 --- a/asl/strings/string_builder.hpp +++ b/asl/strings/string_builder.hpp @@ -37,34 +37,21 @@ public: m_buffer.clear(); } - // @Todo(C++23) Deducing this - - StringBuilder& push(string_view sv) & + auto push(this auto&& self, string_view sv) -> decltype(self) + requires (!is_const>) { - isize_t old_size = m_buffer.size(); - m_buffer.resize_zero(old_size + sv.size()); - asl::memcpy(m_buffer.data() + old_size, sv.data(), sv.size()); - return *this; + isize_t old_size = self.m_buffer.size(); + self.m_buffer.resize_zero(old_size + sv.size()); + // NOLINTNEXTLINE(*-pointer-arithmetic) + asl::memcpy(self.m_buffer.data() + old_size, sv.data(), sv.size()); + return ASL_FWD(self); } - StringBuilder&& push(string_view sv) && + auto push(this auto&& self, char c) -> decltype(self) + requires (!is_const>) { - isize_t old_size = m_buffer.size(); - m_buffer.resize_zero(old_size + sv.size()); - asl::memcpy(m_buffer.data() + old_size, sv.data(), sv.size()); - return ASL_MOVE(*this); - } - - StringBuilder& push(char c) & - { - m_buffer.push(c); - return *this; - } - - StringBuilder&& push(char c) && - { - m_buffer.push(c); - return ASL_MOVE(*this); + self.m_buffer.push(c); + return ASL_FWD(self); } string finish() && @@ -73,14 +60,14 @@ public: } template - string as_string() + string as_string() const requires default_constructible { return string{as_string_view()}; } template - string as_string(Allocator allocator) + string as_string(Allocator allocator) const { return string{as_string_view(), ASL_MOVE(allocator)}; } @@ -121,14 +108,14 @@ public: } template - string as_string() + string as_string() const requires default_constructible { return m_builder.as_string(); } template - string as_string(Allocator allocator) + string as_string(Allocator allocator) const { return m_builder.as_string(ASL_MOVE(allocator)); } @@ -136,8 +123,8 @@ public: StringWriter() -> StringWriter<>; -template -string format_to_string(string_view fmt, const Args&... args) +template +string format_to_string(string_view fmt, const formattable auto&... args) requires default_constructible { StringWriter writer{}; @@ -145,8 +132,8 @@ string format_to_string(string_view fmt, const Args&... args) return ASL_MOVE(writer).finish(); } -template -string format_to_string(Allocator allocator, string_view fmt, const Args&... args) +template +string format_to_string(Allocator allocator, string_view fmt, const formattable auto&... args) { StringWriter writer{ASL_MOVE(allocator)}; format(&writer, fmt, args...); diff --git a/asl/testing/testing.cpp b/asl/testing/testing.cpp index a4eecd7..c788c39 100644 --- a/asl/testing/testing.cpp +++ b/asl/testing/testing.cpp @@ -45,7 +45,7 @@ static void report_assert_failure(const char* msg, const asl::source_location& s int main([[maybe_unused]] int argc, [[maybe_unused]] char* argv[]) { asl::set_assert_failure_handler(report_assert_failure, nullptr); - + int fail = 0; int pass = 0; diff --git a/asl/types/maybe_uninit.hpp b/asl/types/maybe_uninit.hpp index 36429e4..e8ccbd3 100644 --- a/asl/types/maybe_uninit.hpp +++ b/asl/types/maybe_uninit.hpp @@ -17,9 +17,8 @@ public: constexpr maybe_uninit() requires trivially_default_constructible = default; constexpr maybe_uninit() requires (!trivially_default_constructible) {} // NOLINT - template - explicit constexpr maybe_uninit(in_place_t, Args&&... args) - requires constructible_from + explicit constexpr maybe_uninit(in_place_t, auto&&... args) + requires constructible_from : m_value{ASL_FWD(args)...} {} @@ -39,17 +38,15 @@ public: constexpr ~maybe_uninit() requires (!trivially_destructible) {} // NOLINT // @Safety Value must not have been initialized yet - template - constexpr void construct_unsafe(Args&&... args) - requires constructible_from + constexpr void construct_unsafe(auto&&... args) + requires constructible_from { construct_at(&m_value, ASL_FWD(args)...); } // @Safety Value must have been initialized - template - constexpr void assign_unsafe(U&& value) - requires assignable_from + constexpr void assign_unsafe(auto&& value) + requires assignable_from { m_value = ASL_FWD(value); } @@ -64,10 +61,9 @@ public: } // @Safety Value must have been initialized - template - constexpr auto&& as_init_unsafe(this Self&& self) + constexpr auto&& as_init_unsafe(this auto&& self) { - return ASL_FWD_LIKE(decltype(self), ASL_FWD(self).m_value); + return ASL_FWD(self).m_value; } }; diff --git a/asl/types/option.hpp b/asl/types/option.hpp index b32483b..8b5f313 100644 --- a/asl/types/option.hpp +++ b/asl/types/option.hpp @@ -365,8 +365,7 @@ public: } } - template - constexpr auto&& value(this Self&& self) + constexpr auto&& value(this auto&& self) { ASL_ASSERT_RELEASE(self.has_value()); return ASL_FWD(self).m_payload.as_init_unsafe(); @@ -386,19 +385,18 @@ public: return has_value() ? ASL_MOVE(value()) : static_cast(ASL_FWD(other_value)); } - template - constexpr T& emplace(Args&&... args) & - requires constructible_from + constexpr T& emplace(auto&&... args) & + requires constructible_from { if (has_value()) { reset(); } construct(ASL_FWD(args)...); return value(); } - template - constexpr auto and_then(this Self&& self, F&& f) + template + constexpr auto and_then(this auto&& self, F&& f) { - using Result = invoke_result_t>; + using Result = invoke_result_t>; static_assert(is_option); if (self.has_value()) @@ -408,10 +406,10 @@ public: return Result{ asl::nullopt }; } - template - constexpr auto transform(this Self&& self, F&& f) + template + constexpr auto transform(this auto&& self, F&& f) { - using Result = invoke_result_t>; + using Result = invoke_result_t>; if (self.has_value()) { return option>{ diff --git a/asl/types/status_or.hpp b/asl/types/status_or.hpp index 5771d58..a8a48c1 100644 --- a/asl/types/status_or.hpp +++ b/asl/types/status_or.hpp @@ -129,8 +129,7 @@ public: constexpr status&& throw_status() && { return ASL_MOVE(m_status); } - template - constexpr auto&& value(this Self&& self) + constexpr auto&& value(this auto&& self) { ASL_ASSERT_RELEASE(self.ok()); return ASL_FWD(self).m_value.as_init_unsafe(); -- cgit