Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
151 changes: 53 additions & 98 deletions include/proxy/v4/proxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -400,13 +400,10 @@ template <class O>
concept extended_overload = overload_traits<O>::applicable ||
overload_substitution_traits<O>::applicable;
template <class P, class F, bool IsDirect, class D, class O>
consteval bool diagnose_proxiable_required_convention_not_implemented() {
constexpr bool verdict =
overload_traits<O>::applicable &&
overload_traits<O>::template applicable_ptr<P, IsDirect, D>;
static_assert(verdict,
consteval void diagnose_proxiable_required_convention_not_implemented() {
static_assert(overload_traits<O>::applicable &&
overload_traits<O>::template applicable_ptr<P, IsDirect, D>,
"not proxiable due to a required convention not implemented");
return verdict;
}

template <class F, bool IsDirect, class D, class O>
Expand Down Expand Up @@ -484,13 +481,11 @@ struct conv_traits_impl {
substituted_overload_t<Os, F>...>;

template <class P>
static consteval bool diagnose_proxiable() {
bool verdict = true;
((verdict &= diagnose_proxiable_required_convention_not_implemented<
P, F, C::is_direct, typename C::dispatch_type,
substituted_overload_t<Os, F>>()),
static consteval void diagnose_proxiable() {
((diagnose_proxiable_required_convention_not_implemented<
P, F, C::is_direct, typename C::dispatch_type,
substituted_overload_t<Os, F>>()),
...);
return verdict;
}

template <class P>
Expand All @@ -504,15 +499,15 @@ struct conv_traits
: instantiated_t<conv_traits_impl, typename C::overload_types, C, F> {};

template <bool IsDirect, class R>
struct refl_meta {
refl_meta() = default;
struct reflection_meta {
reflection_meta() = default;
template <class P>
requires(IsDirect)
constexpr explicit refl_meta(std::in_place_type_t<P>)
constexpr explicit reflection_meta(std::in_place_type_t<P>)
: reflector(std::in_place_type<P>) {}
template <class P>
requires(!IsDirect)
constexpr explicit refl_meta(std::in_place_type_t<P>)
constexpr explicit reflection_meta(std::in_place_type_t<P>)
: reflector(
std::in_place_type<typename std::pointer_traits<P>::element_type>) {
}
Expand All @@ -521,13 +516,6 @@ struct refl_meta {
R reflector;
};

template <class R>
struct basic_refl_traits : inapplicable_traits {};
template <class R>
requires(requires { typename R::reflector_type; } &&
is_is_direct_well_formed<R>())
struct basic_refl_traits<R> : applicable_traits {};

template <class T, bool IsDirect, class R>
consteval bool is_reflector_well_formed() {
if constexpr (IsDirect) {
Expand All @@ -543,28 +531,11 @@ consteval bool is_reflector_well_formed() {
return false;
}
template <class P, class F, bool IsDirect, class R>
consteval bool diagnose_proxiable_required_reflection_not_implemented() {
constexpr bool verdict = is_reflector_well_formed<P, IsDirect, R>();
static_assert(verdict,
consteval void diagnose_proxiable_required_reflection_not_implemented() {
static_assert(is_reflector_well_formed<P, IsDirect, R>(),
"not proxiable due to a required reflection not implemented");
return verdict;
}

template <class R>
struct refl_traits {
using meta = refl_meta<R::is_direct, typename R::reflector_type>;

template <class P, class F>
static consteval bool diagnose_proxiable() {
return diagnose_proxiable_required_reflection_not_implemented<
P, F, R::is_direct, typename R::reflector_type>();
}

template <class P>
static constexpr bool applicable_ptr =
is_reflector_well_formed<P, R::is_direct, typename R::reflector_type>();
};

struct copy_dispatch {
template <class T, class F>
PRO4D_STATIC_CALL(void, const T& self, proxy<F>& rhs) noexcept(
Expand Down Expand Up @@ -647,37 +618,28 @@ template <class F>
struct ptr_traits<proxy<F>> : inapplicable_traits {};

template <class P, class F, std::size_t ActualSize, std::size_t MaxSize>
consteval bool diagnose_proxiable_size_too_large() {
constexpr bool verdict = ActualSize <= MaxSize;
static_assert(verdict, "not proxiable due to size too large");
return verdict;
consteval void diagnose_proxiable_size_too_large() {
static_assert(ActualSize <= MaxSize, "not proxiable due to size too large");
}
template <class P, class F, std::size_t ActualAlign, std::size_t MaxAlign>
consteval bool diagnose_proxiable_align_too_large() {
constexpr bool verdict = ActualAlign <= MaxAlign;
static_assert(verdict, "not proxiable due to alignment too large");
return verdict;
consteval void diagnose_proxiable_align_too_large() {
static_assert(ActualAlign <= MaxAlign,
"not proxiable due to alignment too large");
}
template <class P, class F, constraint_level RequiredCopyability>
consteval bool diagnose_proxiable_insufficient_copyability() {
constexpr bool verdict =
copyability_traits<P, RequiredCopyability>::applicable;
static_assert(verdict, "not proxiable due to insufficient copyability");
return verdict;
consteval void diagnose_proxiable_insufficient_copyability() {
static_assert(copyability_traits<P, RequiredCopyability>::applicable,
"not proxiable due to insufficient copyability");
}
template <class P, class F, constraint_level RequiredRelocatability>
consteval bool diagnose_proxiable_insufficient_relocatability() {
constexpr bool verdict =
relocatability_traits<P, RequiredRelocatability>::applicable;
static_assert(verdict, "not proxiable due to insufficient relocatability");
return verdict;
consteval void diagnose_proxiable_insufficient_relocatability() {
static_assert(relocatability_traits<P, RequiredRelocatability>::applicable,
"not proxiable due to insufficient relocatability");
}
template <class P, class F, constraint_level RequiredDestructibility>
consteval bool diagnose_proxiable_insufficient_destructibility() {
constexpr bool verdict =
destructibility_traits<P, RequiredDestructibility>::applicable;
static_assert(verdict, "not proxiable due to insufficient destructibility");
return verdict;
consteval void diagnose_proxiable_insufficient_destructibility() {
static_assert(destructibility_traits<P, RequiredDestructibility>::applicable,
"not proxiable due to insufficient destructibility");
}

consteval bool is_layout_well_formed(std::size_t size, std::size_t align) {
Expand Down Expand Up @@ -715,7 +677,9 @@ struct basic_facade_conv_traits_impl<Cs...> : applicable_traits {};
template <class... Rs>
struct basic_facade_refl_traits_impl : inapplicable_traits {};
template <class... Rs>
requires(basic_refl_traits<Rs>::applicable && ...)
requires((requires {
typename Rs::reflector_type;
} && is_is_direct_well_formed<Rs>()) && ...)
struct basic_facade_refl_traits_impl<Rs...> : applicable_traits {};
template <class F>
struct basic_facade_traits : inapplicable_traits {};
Expand All @@ -742,10 +706,8 @@ struct facade_conv_traits_impl {
composite_t<composite_accessor<>, conv_accessor_t<Cs, F, true>...>;

template <class P>
static consteval bool diagnose_proxiable_conv() {
bool verdict = true;
((verdict &= conv_traits<Cs, F>::template diagnose_proxiable<P>()), ...);
return verdict;
static consteval void diagnose_proxiable_conv() {
(conv_traits<Cs, F>::template diagnose_proxiable<P>(), ...);
}

template <class P>
Expand All @@ -757,22 +719,25 @@ struct facade_conv_traits_impl {
};
template <class F, class... Rs>
struct facade_refl_traits_impl {
using refl_meta = composite_meta<typename refl_traits<Rs>::meta...>;
using refl_meta = composite_meta<
reflection_meta<Rs::is_direct, typename Rs::reflector_type>...>;
using refl_indirect_accessor =
composite_t<composite_accessor<>, refl_accessor_t<Rs, F, false>...>;
using refl_direct_accessor =
composite_t<composite_accessor<>, refl_accessor_t<Rs, F, true>...>;

template <class P>
static consteval bool diagnose_proxiable_refl() {
bool verdict = true;
((verdict &= refl_traits<Rs>::template diagnose_proxiable<P, F>()), ...);
return verdict;
static consteval void diagnose_proxiable_refl() {
(diagnose_proxiable_required_reflection_not_implemented<
P, F, Rs::is_direct, typename Rs::reflector_type>(),
...);
}

template <class P>
static constexpr bool refl_applicable_ptr =
(refl_traits<Rs>::template applicable_ptr<P> && ...);
(is_reflector_well_formed<P, Rs::is_direct,
typename Rs::reflector_type>() &&
...);
};
template <class F>
struct facade_traits
Expand All @@ -795,25 +760,15 @@ struct facade_traits
typename facade_traits::refl_direct_accessor>;

template <class P>
static consteval void diagnose_proxiable() {
bool verdict = true;
verdict &=
diagnose_proxiable_size_too_large<P, F, sizeof(P), F::max_size>();
verdict &=
diagnose_proxiable_align_too_large<P, F, alignof(P), F::max_align>();
verdict &=
diagnose_proxiable_insufficient_copyability<P, F, F::copyability>();
verdict &=
diagnose_proxiable_insufficient_relocatability<P, F,
F::relocatability>();
verdict &=
diagnose_proxiable_insufficient_destructibility<P, F,
F::destructibility>();
verdict &= facade_traits::template diagnose_proxiable_conv<P>();
verdict &= facade_traits::template diagnose_proxiable_refl<P>();
if (!verdict) {
PROD_UNREACHABLE(); // Propagate the error to the caller side
}
[[noreturn]] static consteval void diagnose_proxiable_noreturn() {
diagnose_proxiable_size_too_large<P, F, sizeof(P), F::max_size>();
diagnose_proxiable_align_too_large<P, F, alignof(P), F::max_align>();
diagnose_proxiable_insufficient_copyability<P, F, F::copyability>();
diagnose_proxiable_insufficient_relocatability<P, F, F::relocatability>();
diagnose_proxiable_insufficient_destructibility<P, F, F::destructibility>();
facade_traits::template diagnose_proxiable_conv<P>();
facade_traits::template diagnose_proxiable_refl<P>();
PROD_UNREACHABLE(); // Propagate the error to the caller side
}

template <class P>
Expand Down Expand Up @@ -954,7 +909,7 @@ class proxy_indirect_accessor
}
template <class R>
friend const R& reflect(const proxy_indirect_accessor& p) noexcept {
return static_cast<const details::refl_meta<false, R>&>(
return static_cast<const details::reflection_meta<false, R>&>(
details::proxy_helper::get_meta(
details::as_proxy<F, details::qualifier_type::const_lv>(p)))
.reflector;
Expand Down Expand Up @@ -1176,7 +1131,7 @@ class proxy : public details::facade_traits<F>::direct_accessor,
}
template <class R>
friend const R& reflect(const proxy& p) noexcept {
return static_cast<const details::refl_meta<true, R>&>(
return static_cast<const details::reflection_meta<true, R>&>(
details::proxy_helper::get_meta(p))
.reflector;
}
Expand Down Expand Up @@ -1231,7 +1186,7 @@ class proxy : public details::facade_traits<F>::direct_accessor,
meta_ = details::meta_ptr<typename details::facade_traits<F>::meta>{
std::in_place_type<P>};
} else {
details::facade_traits<F>::template diagnose_proxiable<P>();
details::facade_traits<F>::template diagnose_proxiable_noreturn<P>();
}
return result;
}
Expand Down
Loading