blob: 68f6561152e78c0a11a89d66432a69f36c37b396 [file] [log] [blame]
Patrick Williamsbf0283a2023-08-19 07:18:04 -05001#pragma once
2
3#include <sdbusplus/async/context.hpp>
4#include <sdbusplus/server/manager.hpp>
5#include <sdbusplus/vtable.hpp>
6
7namespace sdbusplus::async
8{
9
10namespace server
11{
12
13namespace details
14{
15struct server_context_friend;
16}
17
18template <typename Instance, template <typename, typename> typename... Types>
19class server :
20 public sdbusplus::async::context_ref,
21 public Types<Instance, server<Instance, Types...>>...
22{
23 public:
24 using Self = server<Instance, Types...>;
25 friend details::server_context_friend;
26
27 server() = delete;
28 explicit server(sdbusplus::async::context& ctx, const char* path) :
29 context_ref(ctx), Types<Instance, Self>(path)...
30 {}
31};
32
33} // namespace server
34
35template <typename Instance, template <typename, typename> typename... Types>
36using server_t = server::server<Instance, Types...>;
37
38namespace server::details
39{
40/* Indirect so that the generated Types can access the server_t's context.
41 *
42 * If P2893 gets into C++26 we could eliminate this because we can set all
43 * the Types as friends directly.
44 */
45struct server_context_friend
46{
Patrick Williamsfdbc18f2023-11-28 11:37:30 -060047 template <typename Client, typename Self>
48 static sdbusplus::async::context& context(Self* self)
Patrick Williamsbf0283a2023-08-19 07:18:04 -050049 {
Patrick Williamsfdbc18f2023-11-28 11:37:30 -060050 return static_cast<Client*>(self)->ctx;
Patrick Williamsbf0283a2023-08-19 07:18:04 -050051 }
52};
Patrick Williamsf84f1112023-08-20 19:03:08 -050053
54/* Determine if a type has a get_property call. */
55template <typename Tag, typename Instance>
56concept has_get_property_nomsg =
57 requires(const Instance& i) { i.get_property(Tag{}); };
58
Manojkiran Eda3baa3042024-06-17 15:05:29 +053059/* Determine if a type has a get property call that requires a msg. */
Patrick Williamsf84f1112023-08-20 19:03:08 -050060template <typename Tag, typename Instance>
61concept has_get_property_msg = requires(
62 const Instance& i, sdbusplus::message_t& m) { i.get_property(Tag{}, m); };
63
64/* Determine if a type has any get_property call. */
65template <typename Tag, typename Instance>
66concept has_get_property = has_get_property_nomsg<Tag, Instance> ||
67 has_get_property_msg<Tag, Instance>;
68
69/* Determine if a type is missing the 'const' on get-property calls. */
70template <typename Tag, typename Instance>
71concept has_get_property_missing_const =
72 !has_get_property<Tag, Instance> &&
73 (
74 requires(Instance& i) { i.get_property(Tag{}); } ||
75 requires(Instance& i, sdbusplus::message_t& m) {
76 i.get_property(Tag{}, m);
77 });
78
Patrick Williams72f71162023-08-20 21:36:14 -050079/* Determine if a type has a set_property call. */
80template <typename Tag, typename Instance, typename Arg>
81concept has_set_property_nomsg = requires(
82 Instance& i, Arg&& a) { i.set_property(Tag{}, std::forward<Arg>(a)); };
83
Manojkiran Eda3baa3042024-06-17 15:05:29 +053084/* Determine if a type has a set property call that requires a msg. */
Patrick Williams72f71162023-08-20 21:36:14 -050085template <typename Tag, typename Instance, typename Arg>
86concept has_set_property_msg =
87 requires(Instance& i, sdbusplus::message_t& m, Arg&& a) {
88 i.set_property(Tag{}, m, std::forward<Arg>(a));
89 };
90
91/* Determine if a type has any set_property call. */
92template <typename Tag, typename Instance, typename Arg>
93concept has_set_property = has_set_property_nomsg<Tag, Instance, Arg> ||
94 has_set_property_msg<Tag, Instance, Arg>;
95
Patrick Williamse15ff882023-08-22 16:59:16 -050096/* Determine if a type has a method call. */
97template <typename Tag, typename Instance, typename... Args>
98concept has_method_nomsg = requires(Instance& i, Args&&... a) {
99 i.method_call(Tag{}, std::forward<Args>(a)...);
100 };
101
102/* Determine if a type has a method call that requires a msg. */
103template <typename Tag, typename Instance, typename... Args>
104concept has_method_msg =
105 requires(Instance& i, sdbusplus::message_t& m, Args&&... a) {
106 i.method_call(Tag{}, m, std::forward<Args>(a)...);
107 };
108
109/* Determine if a type has any method call. */
110template <typename Tag, typename Instance, typename... Args>
111concept has_method = has_method_nomsg<Tag, Instance, Args...> ||
112 has_method_msg<Tag, Instance, Args...>;
113
Patrick Williamsbf0283a2023-08-19 07:18:04 -0500114} // namespace server::details
115
116} // namespace sdbusplus::async