Alien-libpanda
view release on metacpan or search on metacpan
src/panda/function_utils.h view on Meta::CPAN
template <typename... Tail>
struct is_panda_function_t {
static constexpr bool value = false;
};
template <typename... Params>
struct is_panda_function_t<function<Params...>> {
static constexpr bool value = true;
};
template <typename Ret, typename... Args>
auto make_abstract_function(Ret (*f)(Args...)) -> iptr<abstract_function<Ret (*)(Args...), Ret, true, Args...>> {
if (!f) return nullptr;
return new abstract_function<Ret (*)(Args...), Ret, true, Args...>(f);
}
template <typename Ret, typename... Args>
auto tmp_abstract_function(Ret (*f)(Args...)) -> abstract_function<Ret (*)(Args...), Ret, true, Args...> {
assert(f);
return abstract_function<Ret (*)(Args...), Ret, true, Args...>(f);
}
template <typename Ret, typename... Args, typename Functor,
bool IsComp = is_comparable<std::remove_reference_t<Functor>>::value,
typename DeFunctor = std::remove_reference_t<Functor>,
typename = std::enable_if_t<has_call_operator<Functor, Ifunction<Ret, Args...>&, Args...>::value ||
has_call_operator<Functor, Args...>::value>,
typename = std::enable_if_t<!std::is_same<Functor, Ret(&)(Args...)>::value>,
typename = std::enable_if_t<!is_panda_function_t<DeFunctor>::value>>
iptr<abstract_function<DeFunctor, Ret, IsComp, Args...>> make_abstract_function(Functor&& f) {
if (!bool_or(f, true)) return nullptr;
return new abstract_function<DeFunctor, Ret, IsComp, Args...>(std::forward<Functor>(f));
}
template <typename Ret, typename... Args, typename Functor,
bool IsComp = is_comparable<std::remove_reference_t<Functor>>::value,
typename DeFunctor = std::remove_reference_t<Functor>,
typename = std::enable_if_t<has_call_operator<Functor, Ifunction<Ret, Args...>&, Args...>::value ||
has_call_operator<Functor, Args...>::value>,
typename = std::enable_if_t<!std::is_same<Functor, Ret(&)(Args...)>::value>,
typename = std::enable_if_t<!is_panda_function_t<DeFunctor>::value>>
abstract_function<DeFunctor, Ret, IsComp, Args...> tmp_abstract_function (Functor&& f) {
assert(bool_or(f, true));
return abstract_function<DeFunctor, Ret, IsComp, Args...>(std::forward<Functor>(f));
}
template <typename Ret, typename... Args, typename ORet, typename... OArgs,
typename = std::enable_if_t<has_call_operator<function<ORet, OArgs...>, Args...>::value>>
auto make_abstract_function(const function<ORet, OArgs...>& func) -> iptr<function_caster<decltype(func.func), Ret, Args...>> {
if (!func) return nullptr;
return new function_caster<decltype(func.func), Ret, Args...>(func.func);
}
template <class Class, typename Ret, typename... Args>
struct method : public Ifunction<Ret, Args...>{
using Method = Ret (Class::*)(Args...);
using ifunction = Ifunction<Ret, Args...>;
method(Method method, iptr<Class> thiz = nullptr) : thiz(thiz), meth(method) {}
iptr<method> bind(iptr<Class> thiz) {
this->thiz = thiz;
return iptr<method>(this);
}
Ret operator()(Args... args) override {
return (thiz.get()->*meth)(std::forward<Args>(args)...);
}
bool equals(const AnyFunction* oth) const override {
auto moth = dynamic_cast<const method<Class, Ret, Args...>*>(oth->get_base());
if (moth == nullptr) return false;
return operator ==(*moth);
}
bool operator==(const method& oth) const {
return thiz == oth.thiz && meth == oth.meth;
}
bool operator !=(const method& oth) const {
return !operator ==(oth);
}
explicit operator bool() const {
return thiz && meth;
}
private:
iptr<Class> thiz;
Method meth;
};
template <class Class, typename Ret, typename... Args>
inline iptr<method<Class, Ret, Args...>> make_method(Ret (Class::*meth)(Args...), iptr<Class> thiz = nullptr) {
if (!meth) return nullptr;
return new method<Class, Ret, Args...>(meth, thiz);
}
template <typename Ret, typename... Args, class Class>
inline iptr<method<Class, Ret, Args...>> make_abstract_function(Ret (Class::*meth)(Args...), iptr<Class> thiz = nullptr) {
if (!meth) return nullptr;
return new method<Class, Ret, Args...>(meth, thiz);
}
template <typename Ret, typename... Args, class Class>
inline method<Class, Ret, Args...> tmp_abstract_function(Ret (Class::*meth)(Args...), iptr<Class> thiz = nullptr) {
assert(meth);
return method<Class, Ret, Args...>(meth, thiz);
}
}
}
( run in 1.571 second using v1.01-cache-2.11-cpan-13bb782fe5a )