From af4e29f8c071b089fb46b5d8b964dd2b1fb3f57a Mon Sep 17 00:00:00 2001 From: Steven Le Rouzic Date: Tue, 11 Mar 2025 23:51:51 +0100 Subject: Remake deref --- asl/base/meta.hpp | 42 ++++++++++++++++++++++-------------------- asl/base/meta_tests.cpp | 11 +++++++++-- 2 files changed, 31 insertions(+), 22 deletions(-) (limited to 'asl/base') diff --git a/asl/base/meta.hpp b/asl/base/meta.hpp index 06c7c59..8376d5c 100644 --- a/asl/base/meta.hpp +++ b/asl/base/meta.hpp @@ -90,6 +90,9 @@ template concept moveable = move_constructible && move_assignable template concept convertible_from = __is_convertible(From, To); +template +concept convertible_to = __is_convertible(From, To); + template concept derived_from = __is_class(Derived) && __is_class(Base) && convertible_from; @@ -244,29 +247,28 @@ concept has_niche = constructible_from && equality_comparable_with concept is_niche = same_as, niche_t>; -template -concept _derefs_with_indirection_as = requires(T& t) +template +concept _dereferenceable_as_convertible = requires(From& t) { - *t; - requires convertible_from; + { *t } -> convertible_to; }; -template -concept _derefs_reference_as = is_ref && convertible_from; - -template -concept _derefs_value_as = !is_ref && convertible_from; - -template T> -constexpr U& deref(T&& t) { return static_cast(*t); } - -template T> -constexpr U& deref(T&& t) { return static_cast(t); } - -template T> -constexpr U& deref(T&& t) { return static_cast(t); } +template +concept derefs_as = is_object && + (convertible_to&, To&> || _dereferenceable_as_convertible, To>); -template -concept derefs_as = _derefs_with_indirection_as || _derefs_reference_as || _derefs_value_as; +template From> +constexpr auto&& deref(From&& from) // NOLINT(*forward*) +{ + if constexpr (_dereferenceable_as_convertible) + { + using deref_type = decltype(*declval()); + return static_cast>(*static_cast(from)); + } + else + { + return static_cast>(from); + } +} } // namespace asl diff --git a/asl/base/meta_tests.cpp b/asl/base/meta_tests.cpp index 774f9bc..6c8efab 100644 --- a/asl/base/meta_tests.cpp +++ b/asl/base/meta_tests.cpp @@ -255,16 +255,22 @@ static_assert(asl::is_enum); static_assert(asl::derefs_as); static_assert(asl::derefs_as); +static_assert(!asl::derefs_as); static_assert(asl::derefs_as); +static_assert(!asl::derefs_as); static_assert(asl::derefs_as, int>); static_assert(asl::derefs_as); +static_assert(!asl::derefs_as); static_assert(asl::derefs_as); static_assert(asl::derefs_as); +static_assert(!asl::derefs_as); static_assert(asl::derefs_as, Base>); +static_assert(asl::derefs_as, Derived>); +static_assert(asl::derefs_as, Base>); static void wants_int(int) {} -static void wants_base(Base&) {} +static void wants_base(const Base&) {} static void wants_base_ptr(Base*) {} ASL_TEST(deref) @@ -285,10 +291,11 @@ ASL_TEST(deref) wants_base(asl::deref(&c)); wants_base(asl::deref(d)); - wants_base_ptr(&asl::deref(Derived{})); wants_base_ptr(&asl::deref(c)); wants_base_ptr(&asl::deref(&c)); wants_base_ptr(&asl::deref(d)); + + wants_base(asl::deref(std::move(d))); } static_assert(asl::same_as, float>); -- cgit