+ static add_qualifier_t get_ptr(add_qualifier_t, Q> p) {
+ if constexpr (std::is_same_v>) {
+ return std::forward>(p);
+ } else {
+ return static_cast>(
+ *std::launder(reinterpret_cast>(p.ptr_)));
+ }
+ }
+};
+
+template
+class proxy_resetting_guard {
public:
- explicit destruction_guard(T* p) noexcept : p_(p) {}
- destruction_guard(const destruction_guard&) = delete;
- ~destruction_guard() noexcept(std::is_nothrow_destructible_v)
- { std::destroy_at(p_); }
+ explicit proxy_resetting_guard(proxy& p) noexcept : p_(p) {}
+ proxy_resetting_guard(const proxy_resetting_guard&) = delete;
+ ~proxy_resetting_guard() noexcept(false) {
+ if constexpr (std::is_same_v>) {
+ p_.reset();
+ } else {
+ std::destroy_at(std::addressof(
+ proxy_helper::template get_ptr(p_)));
+ proxy_helper::reset_meta(p_);
+ }
+ }
private:
- T* p_;
+ proxy& p_;
};
template
@@ -226,56 +251,56 @@ R invoke_dispatch(Args&&... args) {
return D{}(std::forward(args)...);
}
}
-template
-decltype(auto) get_operand(T& ptr) {
+template
+decltype(auto) get_operand(P&& ptr) {
if constexpr (IsDirect) {
- return std::forward>(ptr);
+ return std::forward(ptr);
} else {
- if constexpr (std::is_constructible_v) { assert(ptr); }
- return *std::forward>(ptr);
+ if constexpr (std::is_constructible_v) { assert(ptr); }
+ return *std::forward(ptr);
}
}
-template
-R conv_dispatcher(add_qualifier_t self, Args... args)
+R conv_dispatcher(add_qualifier_t, Q> self, Args... args)
noexcept(invocable_dispatch_ptr) {
- auto& qp = *std::launder(reinterpret_cast>(&self));
if constexpr (Q == qualifier_type::rv) {
- destruction_guard guard{&qp};
- return invoke_dispatch(get_operand(qp),
+ proxy_resetting_guard guard{self};
+ return invoke_dispatch(
+ get_operand(proxy_helper::template get_ptr(
+ std::move(self))),
std::forward(args)...);
} else {
- return invoke_dispatch(get_operand(qp),
+ return invoke_dispatch(
+ get_operand(proxy_helper::template get_ptr(
+ std::forward, Q>>(self))),
std::forward(args)...);
}
}
-template
-R default_conv_dispatcher(add_qualifier_t, Args... args)
- noexcept(invocable_dispatch)
- { return invoke_dispatch(nullptr, std::forward(args)...); }
template struct overload_traits : inapplicable_traits {};
template
struct overload_traits_impl : applicable_traits {
using return_type = R;
using view_type = R(Args...) const noexcept(NE);
+ template
using dispatcher_type =
- R (*)(add_qualifier_t, Args...) noexcept(NE);
+ R (*)(add_qualifier_t, Q>, Args...) noexcept(NE);
- template
+ template
static consteval bool is_applicable_ptr() {
if constexpr (invocable_dispatch_ptr) {
return true;
} else {
- return invocable_dispatch;
+ return invocable_dispatch_ptr, Q, NE, R, Args...>;
}
}
- template
- static consteval dispatcher_type get_dispatcher() {
+ template
+ static consteval dispatcher_type get_dispatcher() {
if constexpr (invocable_dispatch_ptr) {
- return &conv_dispatcher;
+ return &conv_dispatcher;
} else {
- return &default_conv_dispatcher;
+ return &conv_dispatcher, Q, R, Args...>;
}
}
@@ -335,21 +360,21 @@ consteval bool diagnose_proxiable_required_convention_not_implemented() {
constexpr bool verdict =
overload_traits>::applicable &&
overload_traits>
- ::template is_applicable_ptr();
+ ::template is_applicable_ptr();
static_assert(verdict,
"not proxiable due to a required convention not implemented");
return verdict;
}
-template
+template
struct invocation_meta {
constexpr invocation_meta() noexcept : dispatcher(nullptr) {}
template
constexpr explicit invocation_meta(std::in_place_type_t) noexcept
: dispatcher(overload_traits
- ::template get_dispatcher()) {}
+ ::template get_dispatcher()) {}
- typename overload_traits::dispatcher_type dispatcher;
+ typename overload_traits::template dispatcher_type dispatcher;
};
template
@@ -404,7 +429,7 @@ struct conv_traits_impl : inapplicable_traits {};
template
requires(overload_traits>::applicable && ...)
struct conv_traits_impl : applicable_traits {
- using meta = composite_meta_impl>...>;
template
@@ -418,7 +443,7 @@ struct conv_traits_impl : applicable_traits {
template
static constexpr bool applicable_ptr = (overload_traits<
substituted_overload_t>::template is_applicable_ptr<
- C::is_direct, typename C::dispatch_type, P>() && ...);
+ F, C::is_direct, typename C::dispatch_type, P>() && ...);
};
template
struct conv_traits
@@ -491,16 +516,16 @@ struct destroy_dispatch {
___PRO_STATIC_CALL(void, T& self) noexcept(std::is_nothrow_destructible_v)
requires(std::is_destructible_v) { std::destroy_at(&self); }
};
-template
+template
struct lifetime_meta_traits : std::type_identity {};
-template
-struct lifetime_meta_traits
- : std::type_identity> {};
-template
-struct lifetime_meta_traits
- : std::type_identity> {};
-template
-using lifetime_meta_t = typename lifetime_meta_traits::type;
+template
+struct lifetime_meta_traits
+ : std::type_identity> {};
+template
+struct lifetime_meta_traits
+ : std::type_identity> {};
+template
+using lifetime_meta_t = typename lifetime_meta_traits::type;
template
class ___PRO_ENFORCE_EBO composite_accessor_impl : public As... {
@@ -646,7 +671,7 @@ struct facade_conv_traits_impl : applicable_traits {
(conv_traits::template applicable_ptr && ...);
template
static constexpr bool is_invocable = std::is_base_of_v<
- invocation_meta, conv_meta>;
+ invocation_meta, conv_meta>;
};
template
struct facade_refl_traits_impl {
@@ -672,11 +697,11 @@ struct facade_traits
: instantiated_t,
instantiated_t {
using meta = composite_meta<
- lifetime_meta_t&) const noexcept,
+ lifetime_meta_t&) const noexcept,
void(proxy&) const, F::constraints.copyability>,
- lifetime_meta_t&) && noexcept,
+ lifetime_meta_t&) && noexcept,
void(proxy&) &&, F::constraints.relocatability>,
- lifetime_meta_t, typename facade_traits::conv_meta,
typename facade_traits::refl_meta>;
using indirect_accessor = merged_composite_accessor<
@@ -739,12 +764,12 @@ struct meta_ptr_direct_impl : private M {
};
template
struct meta_ptr_traits_impl : std::type_identity> {};
-template
+template
struct meta_ptr_traits_impl<
- composite_meta_impl, Ms...>>
+ composite_meta_impl, Ms...>>
: std::type_identity, Ms...>,
- invocation_meta>> {};
+ invocation_meta, Ms...>,
+ invocation_meta>> {};
template
struct meta_ptr_traits : std::type_identity> {};
template
@@ -756,17 +781,6 @@ struct meta_ptr_traits : meta_ptr_traits_impl {};
template
using meta_ptr = typename meta_ptr_traits::type;
-template
-struct meta_ptr_reset_guard {
- public:
- explicit meta_ptr_reset_guard(MP& meta) noexcept : meta_(meta) {}
- meta_ptr_reset_guard(const meta_ptr_reset_guard&) = delete;
- ~meta_ptr_reset_guard() { meta_.reset(); }
-
- private:
- MP& meta_;
-};
-
template
class inplace_ptr {
public:
@@ -791,37 +805,23 @@ class inplace_ptr {
T value_;
};
-template
-struct proxy_helper {
- static inline const auto& get_meta(const proxy& p) noexcept {
- assert(p.has_value());
- return *p.meta_.operator->();
- }
- template
- static decltype(auto) invoke(add_qualifier_t, Q> p, Args&&... args) {
- auto dispatcher = get_meta(p).template invocation_meta
- ::dispatcher;
- if constexpr (overload_traits::qualifier == qualifier_type::rv) {
- meta_ptr_reset_guard guard{p.meta_};
- return dispatcher(std::forward>(*p.ptr_),
- std::forward(args)...);
- } else {
- return dispatcher(std::forward>(*p.ptr_),
- std::forward(args)...);
- }
- }
- template
- static add_qualifier_t, Q> access(add_qualifier_t a) {
- if constexpr (std::is_base_of_v>) {
- return static_cast, Q>>(a);
- } else {
- using IA = proxy_indirect_accessor;
- return static_cast, Q>>(
- *reinterpret_cast, Q>>(
- static_cast>(std::addressof(a))));
- }
+template
+decltype(auto) invoke_impl(P&& p, Args&&... args) {
+ auto dispatcher = proxy_helper::get_meta(p)
+ .template invocation_meta::dispatcher;
+ return dispatcher(std::forward(p), std::forward(args)...);
+}
+template
+add_qualifier_t, Q> access_impl(add_qualifier_t a) {
+ if constexpr (std::is_base_of_v>) {
+ return static_cast, Q>>(a);
+ } else {
+ using IA = proxy_indirect_accessor;
+ return static_cast, Q>>(
+ *reinterpret_cast, Q>>(
+ static_cast>(std::addressof(a))));
}
-};
+}
} // namespace details
@@ -836,27 +836,25 @@ struct proxy_indirect_accessor : details::facade_traits::indirect_accessor
template
auto proxy_invoke(proxy& p, Args&&... args)
-> typename details::overload_traits::return_type {
- return details::proxy_helper::template invoke(p, std::forward(args)...);
+ return details::invoke_impl(
+ p, std::forward(args)...);
}
template
auto proxy_invoke(const proxy& p, Args&&... args)
-> typename details::overload_traits::return_type {
- return details::proxy_helper::template invoke(p, std::forward(args)...);
+ return details::invoke_impl(
+ p, std::forward(args)...);
}
template
auto proxy_invoke(proxy&& p, Args&&... args)
-> typename details::overload_traits::return_type {
- return details::proxy_helper::template invoke<
- IsDirect, D, O, details::qualifier_type::rv>(
+ return details::invoke_impl(
std::move(p), std::forward(args)...);
}
template
auto proxy_invoke(const proxy&& p, Args&&... args)
-> typename details::overload_traits::return_type {
- return details::proxy_helper::template invoke<
- IsDirect, D, O, details::qualifier_type::const_rv>(
+ return details::invoke_impl(
std::move(p), std::forward(args)...);
}
@@ -867,24 +865,19 @@ const R& proxy_reflect(const proxy& p) noexcept {
}
template
-proxy& access_proxy(A& a) noexcept {
- return details::proxy_helper::template access<
- A, details::qualifier_type::lv>(a);
-}
+proxy& access_proxy(A& a) noexcept
+ { return details::access_impl(a); }
template
-const proxy& access_proxy(const A& a) noexcept {
- return details::proxy_helper::template access<
- A, details::qualifier_type::const_lv>(a);
-}
+const proxy& access_proxy(const A& a) noexcept
+ { return details::access_impl(a); }
template
proxy&& access_proxy(A&& a) noexcept {
- return details::proxy_helper::template access<
- A, details::qualifier_type::rv>(std::forward(a));
+ return details::access_impl(std::move(a));
}
template
const proxy&& access_proxy(const A&& a) noexcept {
- return details::proxy_helper::template access<
- A, details::qualifier_type::const_rv>(std::forward(a));
+ return details::access_impl(
+ std::move(a));
}
template
@@ -916,11 +909,11 @@ class proxy : public details::facade_traits::direct_accessor,
requires(F::constraints.relocatability >= constraint_level::nontrivial &&
F::constraints.copyability != constraint_level::trivial) {
if (rhs.meta_.has_value()) {
- details::meta_ptr_reset_guard guard{rhs.meta_};
if constexpr (F::constraints.relocatability ==
constraint_level::trivial) {
std::ranges::uninitialized_copy(rhs.ptr_, ptr_);
meta_ = rhs.meta_;
+ rhs.meta_.reset();
} else {
proxy_invoke(
@@ -1580,18 +1573,19 @@ class bad_proxy_cast : public std::bad_cast {
__SELF, ::std::forward<__Args>(__args)...); \
} \
}
-#define ___PRO_DEF_MEM_DISPATCH_IMPL(__NAME, __FUNC, __FNAME) \
+#define ___PRO_DEF_MEM_DISPATCH_IMPL(__NAME, __FUNC, __FNAME, __TTYPE) \
struct __NAME { \
- template \
+ template <__TTYPE __T, class... __Args> \
___PRO_STATIC_CALL(decltype(auto), __T&& __self, __Args&&... __args) \
___PRO_DIRECT_FUNC_IMPL(::std::forward<__T>(__self) \
.__FUNC(::std::forward<__Args>(__args)...)) \
___PRO_DEF_MEM_ACCESSOR_TEMPLATE(___PRO_DEF_MEM_ACCESSOR, __FNAME) \
}
#define ___PRO_DEF_MEM_DISPATCH_2(__NAME, __FUNC) \
- ___PRO_DEF_MEM_DISPATCH_IMPL(__NAME, __FUNC, __FUNC)
+ ___PRO_DEF_MEM_DISPATCH_IMPL( \
+ __NAME, __FUNC, __FUNC, ::pro::details::non_proxy_arg)
#define ___PRO_DEF_MEM_DISPATCH_3(__NAME, __FUNC, __FNAME) \
- ___PRO_DEF_MEM_DISPATCH_IMPL(__NAME, __FUNC, __FNAME)
+ ___PRO_DEF_MEM_DISPATCH_IMPL(__NAME, __FUNC, __FNAME, class)
#define PRO_DEF_MEM_DISPATCH(__NAME, ...) \
___PRO_EXPAND_MACRO(___PRO_DEF_MEM_DISPATCH, __NAME, __VA_ARGS__)
@@ -1613,18 +1607,19 @@ ___PRO_DEBUG( \
} \
) \
}
-#define ___PRO_DEF_FREE_DISPATCH_IMPL(__NAME, __FUNC, __FNAME) \
+#define ___PRO_DEF_FREE_DISPATCH_IMPL(__NAME, __FUNC, __FNAME, __TTYPE) \
struct __NAME { \
- template