From e650e70fff8b79eff506dfea61e916b9af4841c2 Mon Sep 17 00:00:00 2001 From: Mingxin Wang Date: Sun, 14 Apr 2024 23:18:09 +0800 Subject: [PATCH] Improve code generation (#83) * Improve code generation * Add missing header * Resolve build error --- proxy.h | 82 +++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 56 insertions(+), 26 deletions(-) diff --git a/proxy.h b/proxy.h index 7d0e679..1ee1bda 100644 --- a/proxy.h +++ b/proxy.h @@ -4,6 +4,7 @@ #ifndef _MSFT_PROXY_ #define _MSFT_PROXY_ +#include #include #include #include @@ -164,14 +165,41 @@ R invoke_dispatch(Args&&... args) { return F{}(std::forward(args)...); } } -template -R dispatcher_default_impl(const char*, Args... args) noexcept(NE) - { return invoke_dispatch(std::forward(args)...); } -template -R dispatcher_impl(const char* erased, Args... args) noexcept(NE) { +template +R invocation_dispatcher(const char* self, Args... args) + noexcept(is_invoker_well_formed< + F, typename ptr_traits

::target_type, true, R, Args...>()) { return invoke_dispatch(ptr_traits

::dereference(*std::launder( - reinterpret_cast(erased))), std::forward(args)...); + reinterpret_cast(self))), std::forward(args)...); +} +template +R invocation_default_dispatcher(const char*, Args... args) + noexcept(is_invoker_well_formed()) + { return invoke_dispatch(std::forward(args)...); } +template +void copying_dispatcher(char* self, const char* rhs) + noexcept(has_copyability

(constraint_level::nothrow)) { + std::construct_at(reinterpret_cast(self), + *std::launder(reinterpret_cast(rhs))); } +template +void copying_default_dispatcher(char* self, const char* rhs) noexcept { + std::memcpy(std::assume_aligned(self), + std::assume_aligned(rhs), Len); +} +template +void relocation_dispatcher(char* self, const char* rhs) + noexcept(has_relocatability

(constraint_level::nothrow)) { + P* other = std::launder(reinterpret_cast(const_cast(rhs))); + std::construct_at(reinterpret_cast(self), std::move(*other)); + std::destroy_at(other); +} +template +void destruction_dispatcher(char* self) + noexcept(has_destructibility

(constraint_level::nothrow)) + { std::destroy_at(std::launder(reinterpret_cast(self))); } +inline void destruction_default_dispatcher(char*) noexcept {} + template struct overload_traits_impl : applicable_traits { template @@ -180,11 +208,11 @@ struct overload_traits_impl : applicable_traits { static constexpr func_ptr_t get() { if constexpr (invocable_dispatch< D, typename ptr_traits

::target_type, NE, R, Args...>) { - return &dispatcher_impl::target_type>, NE, R, Args...>; + return &invocation_dispatcher::target_type>, R, Args...>; } else { - return &dispatcher_default_impl< - typename D::template invoker, NE, R, Args...>; + return &invocation_default_dispatcher< + typename D::template invoker, R, Args...>; } } }; @@ -271,29 +299,33 @@ template struct copyability_meta_provider { template static constexpr func_ptr_t get() { - return [](char* self, const char* rhs) noexcept(NE) { - std::construct_at(reinterpret_cast(self), - *std::launder(reinterpret_cast(rhs))); - }; + if constexpr (has_copyability

(constraint_level::trivial)) { + return ©ing_default_dispatcher; + } else { + return ©ing_dispatcher

; + } } }; template struct relocatability_meta_provider { template - static constexpr func_ptr_t get() { - return [](char* self, char* rhs) noexcept(NE) { - P* other = std::launder(reinterpret_cast(rhs)); - std::construct_at(reinterpret_cast(self), std::move(*other)); - std::destroy_at(other); - }; + static constexpr func_ptr_t get() { + if constexpr (has_relocatability

(constraint_level::trivial)) { + return ©ing_default_dispatcher; + } else { + return &relocation_dispatcher

; + } } }; template struct destructibility_meta_provider { template static constexpr func_ptr_t get() { - return [](char* self) noexcept(NE) - { std::destroy_at(std::launder(reinterpret_cast(self))); }; + if constexpr (has_destructibility

(constraint_level::trivial)) { + return &destruction_default_dispatcher; + } else { + return &destruction_dispatcher

; + } } }; template