// Copyright (c) OpenMMLab. All rights reserved. #ifndef MMDEPLOY_SRC_EXPERIMENTAL_MODULE_ADAPTER_H_ #define MMDEPLOY_SRC_EXPERIMENTAL_MODULE_ADAPTER_H_ #include "archive/value_archive.h" #include "core/module.h" #include "core/mpl/type_traits.h" namespace mmdeploy { namespace module_detail { template struct is_tuple : std::false_type {}; template struct is_tuple> : std::true_type {}; template inline constexpr auto is_tuple_v = is_tuple::value; template struct InvokeImpl { template static Result apply(F&& f, const Value& params, Ts&&... ts) { std::tuple...> args; try { from_value(params, args); auto ret = apply_impl(std::forward(f), std::move(args), std::index_sequence_for{}, std::forward(ts)...); return make_ret_val(std::move(ret)); } catch (const std::exception& e) { MMDEPLOY_ERROR("unhandled exception: {}", e.what()); return Status(eFail); } catch (...) { return Status(eFail); } } template static decltype(auto) apply_impl(F&& f, Tuple&& tuple, std::index_sequence, Ts&&... ts) { return std::invoke(std::forward(f), std::forward(ts)..., std::get(std::forward(tuple))...); } template > static Result make_ret_val(T&& ret) { if constexpr (module_detail::is_tuple_v) { return to_value(std::forward(ret)); } else if constexpr (is_result_v) { return ret ? make_ret_val(std::forward(ret).value()) : std::forward(ret).as_failure(); } else { return make_ret_val(std::forward_as_tuple(std::forward(ret))); } } }; // function pointer template Result Invoke(Ret (*f)(Args...), const Value& args) { return InvokeImpl::apply(f, args); } // member function pointer template Result Invoke(Ret (C::*f)(Args...) const, C* inst, const Value& args) { return InvokeImpl::apply(f, args, inst); } template Result Invoke(Ret (C::*f)(Args...), C* inst, const Value& args) { return InvokeImpl::apply(f, args, inst); } // function object template , typename = std::void_t> Result Invoke(T&& t, const Value& args) { return Invoke(&C::operator(), &t, args); } template struct IsPointer : std::false_type {}; template struct IsPointer : std::false_type {}; template struct IsPointer> : std::true_type {}; template struct IsPointer> : std::true_type {}; template struct IsPointer : std::true_type {}; template struct AccessPolicy { static constexpr auto apply = [](auto& x) -> decltype(auto) { return x; }; }; template struct AccessPolicy::value>> { static constexpr auto apply = [](auto& x) -> decltype(auto) { return *x; }; }; template > class Task : public Module { public: explicit Task(T task) : task_(std::move(task)) {} Result Process(const Value& arg) override { return module_detail::Invoke(A::apply(task_), arg); } private: T task_; }; template std::unique_ptr CreateTask(T&& x) { return std::unique_ptr(new Task{std::forward(x)}); } template auto MakeTask(T&& x) { return Task(std::forward(x)); } } // namespace module_detail using module_detail::CreateTask; using module_detail::MakeTask; } // namespace mmdeploy #endif // MMDEPLOY_SRC_EXPERIMENTAL_MODULE_ADAPTER_H_