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 )