From 7d51b1f79220532a02028d1185a328de11b66cb2 Mon Sep 17 00:00:00 2001 From: Mingxin Wang Date: Fri, 15 Nov 2024 15:18:08 +0800 Subject: [PATCH 1/5] test --- proxy.h | 44 +++++++++++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/proxy.h b/proxy.h index 16ef19c..c7a778b 100644 --- a/proxy.h +++ b/proxy.h @@ -460,20 +460,25 @@ class ___PRO_ENFORCE_EBO composite_accessor_impl : public As... { = default; }; +template +struct accessor_traits_impl : std::type_identity {}; +template + requires(std::is_nothrow_default_constructible_v && + std::is_trivially_copyable_v && !std::is_final_v) +struct accessor_traits_impl : std::type_identity {}; template struct sfinae_accessor_traits : std::type_identity {}; template struct sfinae_accessor_traits< std::void_t>, T, Args...> - : std::type_identity> {}; + : accessor_traits_impl> {}; template using accessor_t = typename sfinae_accessor_traits::type; template struct composite_accessor_reduction : std::type_identity {}; template - requires(IS_DIRECT == I::is_direct && std::is_trivial_v> && - !std::is_final_v>) + requires(IS_DIRECT == I::is_direct && !std::is_void_v>) struct composite_accessor_reduction< IS_DIRECT, F, composite_accessor_impl, I> { using type = composite_accessor_impl>; }; @@ -678,8 +683,17 @@ class proxy : public details::facade_traits::base { using _Traits = details::facade_traits; public: - proxy() noexcept = default; - proxy(std::nullptr_t) noexcept {} + proxy() noexcept { + if constexpr (_Traits::has_indirection) { + std::ignore = **this; + std::ignore = *std::as_const(*this); + std::ignore = (*this).operator->(); + std::ignore = (std::move(*this)).operator->(); + std::ignore = (std::as_const(*this)).operator->(); + std::ignore = (std::forward(*this)).operator->(); + } + } + proxy(std::nullptr_t) noexcept : proxy() {} proxy(const proxy&) noexcept requires(F::constraints.copyability == constraint_level::trivial) = default; proxy(const proxy& rhs) @@ -709,12 +723,12 @@ class proxy : public details::facade_traits::base { template proxy(P&& ptr) noexcept(std::is_nothrow_constructible_v, P>) requires(proxiable, F> && - std::is_constructible_v, P>) + std::is_constructible_v, P>) : proxy() { initialize>(std::forward

(ptr)); } template P, class... Args> explicit proxy(std::in_place_type_t

, Args&&... args) noexcept(std::is_nothrow_constructible_v) - requires(std::is_constructible_v) + requires(std::is_constructible_v) : proxy() { initialize

(std::forward(args)...); } template P, class U, class... Args> explicit proxy(std::in_place_type_t

, std::initializer_list il, @@ -722,7 +736,7 @@ class proxy : public details::facade_traits::base { noexcept(std::is_nothrow_constructible_v< P, std::initializer_list&, Args...>) requires(std::is_constructible_v&, Args...>) - { initialize

(il, std::forward(args)...); } + : proxy() { initialize

(il, std::forward(args)...); } proxy& operator=(std::nullptr_t) noexcept(F::constraints.destructibility >= constraint_level::nothrow) requires(F::constraints.destructibility >= constraint_level::nontrivial) @@ -1106,10 +1120,9 @@ proxy make_proxy(T&& value) { template \ struct ___PRO_ENFORCE_EBO accessor { accessor() = delete; }; \ template \ - requires(sizeof...(__Os) > 1u && \ - (::std::is_trivial_v> && ...)) \ + requires(sizeof...(__Os) > 1u) \ struct accessor<__F, __C, __Os...> : accessor<__F, __C, __Os>... \ - { using accessor<__F, __C, __Os>:: __VA_ARGS__ ...; }; \ + { using accessor<__F, __C, __Os>::__VA_ARGS__...; }; \ __MACRO(, *this, __VA_ARGS__); \ __MACRO(noexcept, *this, __VA_ARGS__); \ __MACRO(&, *this, __VA_ARGS__); \ @@ -1128,8 +1141,7 @@ proxy make_proxy(T&& value) { template \ struct ___PRO_ENFORCE_EBO accessor { accessor() = delete; }; \ template \ - requires(sizeof...(__Os) > 1u && \ - (::std::is_trivial_v> && ...)) \ + requires(sizeof...(__Os) > 1u) \ struct accessor<__F, __C, __Os...> : accessor<__F, __C, __Os>... {}; \ __MACRO(,, accessor& __self, __self, __VA_ARGS__); \ __MACRO(noexcept, noexcept, accessor& __self, __self, __VA_ARGS__); \ @@ -1227,6 +1239,7 @@ struct facade_impl { #define ___PRO_DEF_UPWARD_CONVERSION_ACCESSOR(Q, SELF, ...) \ template \ struct accessor() Q> { \ + accessor() noexcept { std::ignore = &accessor::__VA_ARGS__; } \ __VA_ARGS__ () Q { \ if (access_proxy(SELF).has_value()) { \ return proxy_invoke() Q>(access_proxy(SELF)); \ @@ -1389,12 +1402,14 @@ struct operator_dispatch; #define ___PRO_DEF_LHS_LEFT_OP_ACCESSOR(Q, SELF, ...) \ template \ struct accessor { \ + accessor() noexcept { std::ignore = &accessor::__VA_ARGS__; } \ R __VA_ARGS__ () Q \ { return proxy_invoke(access_proxy(SELF)); } \ } #define ___PRO_DEF_LHS_ANY_OP_ACCESSOR(Q, SELF, ...) \ template \ struct accessor { \ + accessor() noexcept { std::ignore = &accessor::__VA_ARGS__; } \ R __VA_ARGS__ (Args... args) Q { \ return proxy_invoke( \ access_proxy(SELF), std::forward(args)...); \ @@ -1460,6 +1475,7 @@ struct operator_dispatch; #define ___PRO_DEF_LHS_ASSIGNMENT_OP_ACCESSOR(Q, SELF, ...) \ template \ struct accessor { \ + accessor() noexcept { std::ignore = &accessor::__VA_ARGS__; } \ decltype(auto) __VA_ARGS__ (Arg arg) Q { \ proxy_invoke( \ access_proxy(SELF), std::forward(arg)); \ @@ -1577,6 +1593,7 @@ struct operator_dispatch<"[]", false> { #define ___PRO_DEF_CONVERSION_ACCESSOR(Q, SELF, ...) \ template \ struct accessor { \ + accessor() noexcept { std::ignore = &accessor::__VA_ARGS__; } \ explicit(Expl) __VA_ARGS__ () Q \ { return proxy_invoke(access_proxy(SELF)); } \ } @@ -1604,6 +1621,7 @@ struct conversion_dispatch { #define ___PRO_DEF_MEM_ACCESSOR(__Q, __SELF, ...) \ template \ struct accessor<__F, __C, __R(__Args...) __Q> { \ + accessor() noexcept { ::std::ignore = &accessor::__VA_ARGS__; } \ __R __VA_ARGS__ (__Args... __args) __Q { \ return ::pro::proxy_invoke<__C, __R(__Args...) __Q>( \ ::pro::access_proxy<__F>(__SELF), \ From cd306186b17f656ac1205923e46314b823b77878 Mon Sep 17 00:00:00 2001 From: Mingxin Wang Date: Fri, 15 Nov 2024 17:31:17 +0800 Subject: [PATCH 2/5] test --- proxy.h | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/proxy.h b/proxy.h index c7a778b..c5d6f17 100644 --- a/proxy.h +++ b/proxy.h @@ -683,6 +683,9 @@ class proxy : public details::facade_traits::base { using _Traits = details::facade_traits; public: +#ifdef NODEBUG + proxy() noexcept = default; +#else proxy() noexcept { if constexpr (_Traits::has_indirection) { std::ignore = **this; @@ -693,6 +696,7 @@ class proxy : public details::facade_traits::base { std::ignore = (std::forward(*this)).operator->(); } } +#endif // NODEBUG proxy(std::nullptr_t) noexcept : proxy() {} proxy(const proxy&) noexcept requires(F::constraints.copyability == constraint_level::trivial) = default; @@ -1162,6 +1166,13 @@ proxy make_proxy(T&& value) { __MACRO(const&& noexcept, noexcept, const accessor&& __self, \ ::std::forward(__self), __VA_ARGS__); +#ifdef NODEBUG +#define ___PRO_DEF_MEM_ACCESSOR_CTOR(...) +#else +#define ___PRO_DEF_MEM_ACCESSOR_CTOR(...) \ + accessor() noexcept { ::std::ignore = &accessor::__VA_ARGS__; } +#endif // NODEBUG + namespace details { constexpr std::size_t invalid_size = std::numeric_limits::max(); @@ -1239,7 +1250,7 @@ struct facade_impl { #define ___PRO_DEF_UPWARD_CONVERSION_ACCESSOR(Q, SELF, ...) \ template \ struct accessor() Q> { \ - accessor() noexcept { std::ignore = &accessor::__VA_ARGS__; } \ + ___PRO_DEF_MEM_ACCESSOR_CTOR(__VA_ARGS__) \ __VA_ARGS__ () Q { \ if (access_proxy(SELF).has_value()) { \ return proxy_invoke() Q>(access_proxy(SELF)); \ @@ -1402,14 +1413,14 @@ struct operator_dispatch; #define ___PRO_DEF_LHS_LEFT_OP_ACCESSOR(Q, SELF, ...) \ template \ struct accessor { \ - accessor() noexcept { std::ignore = &accessor::__VA_ARGS__; } \ + ___PRO_DEF_MEM_ACCESSOR_CTOR(__VA_ARGS__) \ R __VA_ARGS__ () Q \ { return proxy_invoke(access_proxy(SELF)); } \ } #define ___PRO_DEF_LHS_ANY_OP_ACCESSOR(Q, SELF, ...) \ template \ struct accessor { \ - accessor() noexcept { std::ignore = &accessor::__VA_ARGS__; } \ + ___PRO_DEF_MEM_ACCESSOR_CTOR(__VA_ARGS__) \ R __VA_ARGS__ (Args... args) Q { \ return proxy_invoke( \ access_proxy(SELF), std::forward(args)...); \ @@ -1475,7 +1486,7 @@ struct operator_dispatch; #define ___PRO_DEF_LHS_ASSIGNMENT_OP_ACCESSOR(Q, SELF, ...) \ template \ struct accessor { \ - accessor() noexcept { std::ignore = &accessor::__VA_ARGS__; } \ + ___PRO_DEF_MEM_ACCESSOR_CTOR(__VA_ARGS__) \ decltype(auto) __VA_ARGS__ (Arg arg) Q { \ proxy_invoke( \ access_proxy(SELF), std::forward(arg)); \ @@ -1593,7 +1604,7 @@ struct operator_dispatch<"[]", false> { #define ___PRO_DEF_CONVERSION_ACCESSOR(Q, SELF, ...) \ template \ struct accessor { \ - accessor() noexcept { std::ignore = &accessor::__VA_ARGS__; } \ + ___PRO_DEF_MEM_ACCESSOR_CTOR(__VA_ARGS__) \ explicit(Expl) __VA_ARGS__ () Q \ { return proxy_invoke(access_proxy(SELF)); } \ } @@ -1621,7 +1632,7 @@ struct conversion_dispatch { #define ___PRO_DEF_MEM_ACCESSOR(__Q, __SELF, ...) \ template \ struct accessor<__F, __C, __R(__Args...) __Q> { \ - accessor() noexcept { ::std::ignore = &accessor::__VA_ARGS__; } \ + ___PRO_DEF_MEM_ACCESSOR_CTOR(__VA_ARGS__) \ __R __VA_ARGS__ (__Args... __args) __Q { \ return ::pro::proxy_invoke<__C, __R(__Args...) __Q>( \ ::pro::access_proxy<__F>(__SELF), \ From 56beecda273736e89f9370c39b17e5bb6981e5d7 Mon Sep 17 00:00:00 2001 From: Mingxin Wang Date: Mon, 18 Nov 2024 19:38:14 +0800 Subject: [PATCH 3/5] Generate symbols for member accessors --- docs/ProAccessible.md | 2 +- proxy.h | 30 ++++++++++++++++-------------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/docs/ProAccessible.md b/docs/ProAccessible.md index f8e3ddd..fde8a85 100644 --- a/docs/ProAccessible.md +++ b/docs/ProAccessible.md @@ -4,7 +4,7 @@ Given that `F` is a type meeting the [*ProBasicFacade* requirements](ProBasicFac | Expressions | Semantics | | ------------------------------------------- | ------------------------------------------------------------ | -| `typename T::template accessor` | A type that provides accessibility to `proxy`. It shall be a trivial class type and not [final](https://en.cppreference.com/w/cpp/language/final). | +| `typename T::template accessor` | A type that provides accessibility to `proxy`. It shall be a *nothrow-default-constructible*, *trivially-copyable* type, and shall not be [final](https://en.cppreference.com/w/cpp/language/final). | ## See Also diff --git a/proxy.h b/proxy.h index c5d6f17..9eea33f 100644 --- a/proxy.h +++ b/proxy.h @@ -688,12 +688,14 @@ class proxy : public details::facade_traits::base { #else proxy() noexcept { if constexpr (_Traits::has_indirection) { - std::ignore = **this; - std::ignore = *std::as_const(*this); - std::ignore = (*this).operator->(); - std::ignore = (std::move(*this)).operator->(); - std::ignore = (std::as_const(*this)).operator->(); - std::ignore = (std::forward(*this)).operator->(); + if (false) { + std::ignore = **this; + std::ignore = *std::as_const(*this); + std::ignore = (*this).operator->(); + std::ignore = (std::move(*this)).operator->(); + std::ignore = (std::as_const(*this)).operator->(); + std::ignore = (std::forward(*this)).operator->(); + } } } #endif // NODEBUG @@ -1167,9 +1169,9 @@ proxy make_proxy(T&& value) { ::std::forward(__self), __VA_ARGS__); #ifdef NODEBUG -#define ___PRO_DEF_MEM_ACCESSOR_CTOR(...) +#define ___PRO_GEN_SYMBOL_FOR_MEM_ACCESSOR(...) #else -#define ___PRO_DEF_MEM_ACCESSOR_CTOR(...) \ +#define ___PRO_GEN_SYMBOL_FOR_MEM_ACCESSOR(...) \ accessor() noexcept { ::std::ignore = &accessor::__VA_ARGS__; } #endif // NODEBUG @@ -1250,7 +1252,7 @@ struct facade_impl { #define ___PRO_DEF_UPWARD_CONVERSION_ACCESSOR(Q, SELF, ...) \ template \ struct accessor() Q> { \ - ___PRO_DEF_MEM_ACCESSOR_CTOR(__VA_ARGS__) \ + ___PRO_GEN_SYMBOL_FOR_MEM_ACCESSOR(__VA_ARGS__) \ __VA_ARGS__ () Q { \ if (access_proxy(SELF).has_value()) { \ return proxy_invoke() Q>(access_proxy(SELF)); \ @@ -1413,14 +1415,14 @@ struct operator_dispatch; #define ___PRO_DEF_LHS_LEFT_OP_ACCESSOR(Q, SELF, ...) \ template \ struct accessor { \ - ___PRO_DEF_MEM_ACCESSOR_CTOR(__VA_ARGS__) \ + ___PRO_GEN_SYMBOL_FOR_MEM_ACCESSOR(__VA_ARGS__) \ R __VA_ARGS__ () Q \ { return proxy_invoke(access_proxy(SELF)); } \ } #define ___PRO_DEF_LHS_ANY_OP_ACCESSOR(Q, SELF, ...) \ template \ struct accessor { \ - ___PRO_DEF_MEM_ACCESSOR_CTOR(__VA_ARGS__) \ + ___PRO_GEN_SYMBOL_FOR_MEM_ACCESSOR(__VA_ARGS__) \ R __VA_ARGS__ (Args... args) Q { \ return proxy_invoke( \ access_proxy(SELF), std::forward(args)...); \ @@ -1486,7 +1488,7 @@ struct operator_dispatch; #define ___PRO_DEF_LHS_ASSIGNMENT_OP_ACCESSOR(Q, SELF, ...) \ template \ struct accessor { \ - ___PRO_DEF_MEM_ACCESSOR_CTOR(__VA_ARGS__) \ + ___PRO_GEN_SYMBOL_FOR_MEM_ACCESSOR(__VA_ARGS__) \ decltype(auto) __VA_ARGS__ (Arg arg) Q { \ proxy_invoke( \ access_proxy(SELF), std::forward(arg)); \ @@ -1604,7 +1606,7 @@ struct operator_dispatch<"[]", false> { #define ___PRO_DEF_CONVERSION_ACCESSOR(Q, SELF, ...) \ template \ struct accessor { \ - ___PRO_DEF_MEM_ACCESSOR_CTOR(__VA_ARGS__) \ + ___PRO_GEN_SYMBOL_FOR_MEM_ACCESSOR(__VA_ARGS__) \ explicit(Expl) __VA_ARGS__ () Q \ { return proxy_invoke(access_proxy(SELF)); } \ } @@ -1632,7 +1634,7 @@ struct conversion_dispatch { #define ___PRO_DEF_MEM_ACCESSOR(__Q, __SELF, ...) \ template \ struct accessor<__F, __C, __R(__Args...) __Q> { \ - ___PRO_DEF_MEM_ACCESSOR_CTOR(__VA_ARGS__) \ + ___PRO_GEN_SYMBOL_FOR_MEM_ACCESSOR(__VA_ARGS__) \ __R __VA_ARGS__ (__Args... __args) __Q { \ return ::pro::proxy_invoke<__C, __R(__Args...) __Q>( \ ::pro::access_proxy<__F>(__SELF), \ From de20dffcd34b85f8e553db3bb25e60b2e9447fc4 Mon Sep 17 00:00:00 2001 From: Mingxin Wang Date: Mon, 18 Nov 2024 20:59:27 +0800 Subject: [PATCH 4/5] Resolve comments --- proxy.h | 61 ++++++++++++++++++++++++++++++++------------------------- 1 file changed, 34 insertions(+), 27 deletions(-) diff --git a/proxy.h b/proxy.h index 9eea33f..cc34ee0 100644 --- a/proxy.h +++ b/proxy.h @@ -450,9 +450,11 @@ struct lifetime_meta_traits template