aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/deps/rpclib/include/rpc/dispatcher.inl
blob: dc10edcf9539d070fe423b31b16649b374073b93 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
namespace rpc {
namespace detail {

template <typename F> void dispatcher::bind(std::string const &name, F func) {
    bind(name, func, typename detail::func_kind_info<F>::result_kind(),
         typename detail::func_kind_info<F>::args_kind());
}

template <typename F>
void dispatcher::bind(std::string const &name, F func,
                      detail::tags::void_result const &,
                      detail::tags::zero_arg const &) {
    funcs_.insert(
        std::make_pair(name, [func, name](RPCLIB_MSGPACK::object const &args) {
            enforce_arg_count(name, 0, args.via.array.size);
            func();
            return rpc::detail::make_unique<RPCLIB_MSGPACK::object_handle>();
        }));
}

template <typename F>
void dispatcher::bind(std::string const &name, F func,
                      detail::tags::void_result const &,
                      detail::tags::nonzero_arg const &) {
    using detail::func_traits;
    using args_type = typename func_traits<F>::args_type;

    funcs_.insert(
        std::make_pair(name, [func, name](RPCLIB_MSGPACK::object const &args) {
            constexpr int args_count = std::tuple_size<args_type>::value;
            enforce_arg_count(name, args_count, args.via.array.size);
            args_type args_real;
            args.convert(&args_real);
            detail::call(func, args_real);
            return rpc::detail::make_unique<RPCLIB_MSGPACK::object_handle>();
        }));
}

template <typename F>
void dispatcher::bind(std::string const &name, F func,
                      detail::tags::nonvoid_result const &,
                      detail::tags::zero_arg const &) {
    using detail::func_traits;

    funcs_.insert(std::make_pair(name, [func,
                                        name](RPCLIB_MSGPACK::object const &args) {
        enforce_arg_count(name, 0, args.via.array.size);
        auto z = rpc::detail::make_unique<RPCLIB_MSGPACK::zone>();
        auto result = RPCLIB_MSGPACK::object(func(), *z);
        return rpc::detail::make_unique<RPCLIB_MSGPACK::object_handle>(result, std::move(z));
    }));
}

template <typename F>
void dispatcher::bind(std::string const &name, F func,
                      detail::tags::nonvoid_result const &,
                      detail::tags::nonzero_arg const &) {
    using detail::func_traits;
    using args_type = typename func_traits<F>::args_type;

    funcs_.insert(std::make_pair(name, [func,
                                        name](RPCLIB_MSGPACK::object const &args) {
        constexpr int args_count = std::tuple_size<args_type>::value;
        enforce_arg_count(name, args_count, args.via.array.size);
        args_type args_real;
        args.convert(&args_real);
        auto z = rpc::detail::make_unique<RPCLIB_MSGPACK::zone>();
        auto result = RPCLIB_MSGPACK::object(detail::call(func, args_real), *z);
        return rpc::detail::make_unique<RPCLIB_MSGPACK::object_handle>(result, std::move(z));
    }));
}
}
}