8#include "lamppp/common/assert.hpp"
9#include "lamppp/nets/module.hpp"
15 template <
typename Derived>
21 std::shared_ptr<ModuleImpl> getImpl();
22 std::any call(
const std::vector<std::any>& args)
const;
26 template <
typename MImpl,
typename... Args>
29 std::shared_ptr<Placeholder> impl_;
31 template <
typename Impl,
typename R,
typename... Args>
32 std::shared_ptr<AnyModule::Placeholder> make_holder(std::shared_ptr<Impl> m,
33 R (Impl::*fp)(Args...)
35 using H =
typename AnyModule::Holder<Impl, Args...>;
36 return std::make_shared<H>(std::move(m), fp);
45 virtual std::any call(
const std::vector<std::any>& args) = 0;
46 virtual std::shared_ptr<ModuleImpl> getImpl() = 0;
50template <
typename MImpl,
typename... Args>
52 using FuncPtr = std::invoke_result_t<
decltype(&MImpl::forward), MImpl*,
53 Args...> (MImpl::*)(Args...) const;
56 ~Holder()
override =
default;
57 explicit Holder(std::shared_ptr<MImpl> mod, FuncPtr forward)
58 : mod_(mod), forward_(forward) {};
60 std::any call(
const std::vector<std::any>& args)
override {
61 LMP_CHECK(args.size() ==
sizeof...(Args)) <<
"Invalid forward arguments";
62 return invoke(args, std::index_sequence_for<Args...>{});
64 std::shared_ptr<ModuleImpl> getImpl()
override {
return mod_; };
67 template <
size_t... Idx>
68 std::any invoke(
const std::vector<std::any>& args,
69 std::index_sequence<Idx...> ) {
70 return std::any((
static_cast<MImpl*
>(mod_.get())->*forward_)(
71 any_cast<Args>(args[Idx])...));
74 std::shared_ptr<MImpl> mod_;