Closed uselessgoddess closed 2 years ago
Heh, its interesting... You can use smth like this:
// do not works for fundamental types
template <typename T, TTA... Methods>
struct AA_MSVC_EBO static_ref : T, aa::plugin_t<Methods, static_ref<T, Methods...>>... {
static_ref() = delete;
static_ref(const static_ref&) = delete;
void operator=(const static_ref&) = delete;
};
template<TTA... Methods, typename T>
static_ref<T, Methods...>& make_static_ref(T& value) noexcept {
return static_cast<static_ref<T, Methods...>&>(value);
}
I try to make the smartest static or poly ref sop_ref
:
struct infallible{};
template <TTA... Methods>
constexpr inline bool satisfies_v<infallible, Methods...> = true;
template <typename T, TTA... Methods>
using static_or_poly = std::variant<static_ref<T, Methods...>*, poly_ref<Methods...>>;
// static or poly
template <typename T, TTA... Methods>
struct sop_ref : plugin_t<Methods, sop_ref<T, Methods...>>... {
static_or_poly<T, Methods...> sop;
sop_ref(poly_ref<Methods...> ref) : sop(std::move(ref)) {}
sop_ref(static_ref<T, Methods...>& ref) : sop(ref) {}
sop_ref(T& ref) : sop(&make_static_ref<Methods...>(ref)) {}
};
template <TTA... Methods>
sop_ref(poly_ref<Methods...>) -> sop_ref<infallible, Methods...>;
// in `invoke_fn`
template <typename T, TTA... Methods>
result_t<Method> operator()(sop_ref<T, Methods...> p, Args... args) const {
return std::visit(/* impl */, p.sop);
}
But it doesn't make sense. C++ not have basic type infer :(
template <typename T>
auto smart_foo(aa::sop_ref<T, Foo> ref) {
return ref.foo();
}
. . .
auto val = xd{10};
// not works
smart_foo(val);
// works :(
smart_foo(aa::sop_ref<xd, Foo>(val));
Right now, I can only hope for compiler optimizations for poly_ref
.
Why not use overload in this case? smart_foo(poly_ref) smart_foo(auto&&) / smart_foo(static_ref) if you want to use plugin methods
For the same reason that I want to use plugins.
self.foo()
looks shorter than aa::invoke<Foo>(self)
I try to make the smartest static or poly ref
sop_ref
:struct infallible{}; template <TTA... Methods> constexpr inline bool satisfies_v<infallible, Methods...> = true; template <typename T, TTA... Methods> using static_or_poly = std::variant<static_ref<T, Methods...>*, poly_ref<Methods...>>; // static or poly template <typename T, TTA... Methods> struct sop_ref : plugin_t<Methods, sop_ref<T, Methods...>>... { static_or_poly<T, Methods...> sop; sop_ref(poly_ref<Methods...> ref) : sop(std::move(ref)) {} sop_ref(static_ref<T, Methods...>& ref) : sop(ref) {} sop_ref(T& ref) : sop(&make_static_ref<Methods...>(ref)) {} }; template <TTA... Methods> sop_ref(poly_ref<Methods...>) -> sop_ref<infallible, Methods...>; // in `invoke_fn` template <typename T, TTA... Methods> result_t<Method> operator()(sop_ref<T, Methods...> p, Args... args) const { return std::visit(/* impl */, p.sop); }
But it doesn't make sense. C++ not have basic type infer :(
template <typename T> auto smart_foo(aa::sop_ref<T, Foo> ref) { return ref.foo(); } . . . auto val = xd{10}; // not works smart_foo(val); // works :( smart_foo(aa::sop_ref<xd, Foo>(val));
hmm, may be i will add specialization for aa::interface_t (satisfy)
I try to make the smartest static or poly ref
sop_ref
:struct infallible{}; template <TTA... Methods> constexpr inline bool satisfies_v<infallible, Methods...> = true; template <typename T, TTA... Methods> using static_or_poly = std::variant<static_ref<T, Methods...>*, poly_ref<Methods...>>; // static or poly template <typename T, TTA... Methods> struct sop_ref : plugin_t<Methods, sop_ref<T, Methods...>>... { static_or_poly<T, Methods...> sop; sop_ref(poly_ref<Methods...> ref) : sop(std::move(ref)) {} sop_ref(static_ref<T, Methods...>& ref) : sop(ref) {} sop_ref(T& ref) : sop(&make_static_ref<Methods...>(ref)) {} }; template <TTA... Methods> sop_ref(poly_ref<Methods...>) -> sop_ref<infallible, Methods...>; // in `invoke_fn` template <typename T, TTA... Methods> result_t<Method> operator()(sop_ref<T, Methods...> p, Args... args) const { return std::visit(/* impl */, p.sop); }
But it doesn't make sense. C++ not have basic type infer :(
template <typename T> auto smart_foo(aa::sop_ref<T, Foo> ref) { return ref.foo(); } . . . auto val = xd{10}; // not works smart_foo(val); // works :( smart_foo(aa::sop_ref<xd, Foo>(val));
hm, why you cant change realization invoke for !any type such that it will invoke through static_ref, so you can use plugins?..
hm, why you cant change realization invoke for !any type such that it will invoke through static_ref, so you can use plugins?..
Implementation, bro))
I would like to use static and dynamic refs in one function.
I try to use static_ref
with poly_ref
– not works. (double inherit of plugin_t
)
auto val = xd{123};
std::cout << smart_foo(aa::make_static_ref<Foo>(val)) << std::endl;
aa::poly_ref<Foo> ref = val;
std::cout << smart_foo(aa::make_static_ref<Foo>(ref)) << std::endl;
And it's too long))
I write simple
trait/interface
Fizz
:I can write function that use it:
I know:
aa::invoke
calldo_invoke
as static ifself
isn'tany-like
type But i cannot callplugin
methodsfunctions withoutconst_poly_ref
or etc.Is there something like
poly_or_static_ref
?