1bf0283aeSPatrick Williams #pragma once 2bf0283aeSPatrick Williams 3bf0283aeSPatrick Williams #include <sdbusplus/async/context.hpp> 4bf0283aeSPatrick Williams #include <sdbusplus/server/manager.hpp> 5bf0283aeSPatrick Williams #include <sdbusplus/vtable.hpp> 6bf0283aeSPatrick Williams 7bf0283aeSPatrick Williams namespace sdbusplus::async 8bf0283aeSPatrick Williams { 9bf0283aeSPatrick Williams 10bf0283aeSPatrick Williams namespace server 11bf0283aeSPatrick Williams { 12bf0283aeSPatrick Williams 13bf0283aeSPatrick Williams namespace details 14bf0283aeSPatrick Williams { 15bf0283aeSPatrick Williams struct server_context_friend; 16bf0283aeSPatrick Williams } 17bf0283aeSPatrick Williams 18bf0283aeSPatrick Williams template <typename Instance, template <typename, typename> typename... Types> 19bf0283aeSPatrick Williams class server : 20bf0283aeSPatrick Williams public sdbusplus::async::context_ref, 21bf0283aeSPatrick Williams public Types<Instance, server<Instance, Types...>>... 22bf0283aeSPatrick Williams { 23bf0283aeSPatrick Williams public: 24bf0283aeSPatrick Williams using Self = server<Instance, Types...>; 25bf0283aeSPatrick Williams friend details::server_context_friend; 26bf0283aeSPatrick Williams 27bf0283aeSPatrick Williams server() = delete; server(sdbusplus::async::context & ctx,const char * path)28bf0283aeSPatrick Williams explicit server(sdbusplus::async::context& ctx, const char* path) : 29bf0283aeSPatrick Williams context_ref(ctx), Types<Instance, Self>(path)... 30bf0283aeSPatrick Williams {} 31bf0283aeSPatrick Williams }; 32bf0283aeSPatrick Williams 33bf0283aeSPatrick Williams } // namespace server 34bf0283aeSPatrick Williams 35bf0283aeSPatrick Williams template <typename Instance, template <typename, typename> typename... Types> 36bf0283aeSPatrick Williams using server_t = server::server<Instance, Types...>; 37bf0283aeSPatrick Williams 38bf0283aeSPatrick Williams namespace server::details 39bf0283aeSPatrick Williams { 40bf0283aeSPatrick Williams /* Indirect so that the generated Types can access the server_t's context. 41bf0283aeSPatrick Williams * 42bf0283aeSPatrick Williams * If P2893 gets into C++26 we could eliminate this because we can set all 43bf0283aeSPatrick Williams * the Types as friends directly. 44bf0283aeSPatrick Williams */ 45bf0283aeSPatrick Williams struct server_context_friend 46bf0283aeSPatrick Williams { 47fdbc18ffSPatrick Williams template <typename Client, typename Self> contextsdbusplus::async::server::details::server_context_friend48fdbc18ffSPatrick Williams static sdbusplus::async::context& context(Self* self) 49bf0283aeSPatrick Williams { 50fdbc18ffSPatrick Williams return static_cast<Client*>(self)->ctx; 51bf0283aeSPatrick Williams } 52bf0283aeSPatrick Williams }; 53f84f1117SPatrick Williams 54f84f1117SPatrick Williams /* Determine if a type has a get_property call. */ 55f84f1117SPatrick Williams template <typename Tag, typename Instance> 56f84f1117SPatrick Williams concept has_get_property_nomsg = 57f84f1117SPatrick Williams requires(const Instance& i) { i.get_property(Tag{}); }; 58f84f1117SPatrick Williams 593baa3045SManojkiran Eda /* Determine if a type has a get property call that requires a msg. */ 60f84f1117SPatrick Williams template <typename Tag, typename Instance> 61*06f265f6SPatrick Williams concept has_get_property_msg = 62*06f265f6SPatrick Williams requires(const Instance& i, sdbusplus::message_t& m) { 63*06f265f6SPatrick Williams i.get_property(Tag{}, m); 64*06f265f6SPatrick Williams }; 65f84f1117SPatrick Williams 66f84f1117SPatrick Williams /* Determine if a type has any get_property call. */ 67f84f1117SPatrick Williams template <typename Tag, typename Instance> 68f84f1117SPatrick Williams concept has_get_property = has_get_property_nomsg<Tag, Instance> || 69f84f1117SPatrick Williams has_get_property_msg<Tag, Instance>; 70f84f1117SPatrick Williams 71f84f1117SPatrick Williams /* Determine if a type is missing the 'const' on get-property calls. */ 72f84f1117SPatrick Williams template <typename Tag, typename Instance> 73f84f1117SPatrick Williams concept has_get_property_missing_const = 74f84f1117SPatrick Williams !has_get_property<Tag, Instance> && 75f84f1117SPatrick Williams ( 76f84f1117SPatrick Williams requires(Instance& i) { i.get_property(Tag{}); } || 77f84f1117SPatrick Williams requires(Instance& i, sdbusplus::message_t& m) { 78f84f1117SPatrick Williams i.get_property(Tag{}, m); 79f84f1117SPatrick Williams }); 80f84f1117SPatrick Williams 8172f7116aSPatrick Williams /* Determine if a type has a set_property call. */ 8272f7116aSPatrick Williams template <typename Tag, typename Instance, typename Arg> 83*06f265f6SPatrick Williams concept has_set_property_nomsg = 84*06f265f6SPatrick Williams requires(Instance& i, Arg&& a) { 85*06f265f6SPatrick Williams i.set_property(Tag{}, std::forward<Arg>(a)); 86*06f265f6SPatrick Williams }; 8772f7116aSPatrick Williams 883baa3045SManojkiran Eda /* Determine if a type has a set property call that requires a msg. */ 8972f7116aSPatrick Williams template <typename Tag, typename Instance, typename Arg> 9072f7116aSPatrick Williams concept has_set_property_msg = 9172f7116aSPatrick Williams requires(Instance& i, sdbusplus::message_t& m, Arg&& a) { 9272f7116aSPatrick Williams i.set_property(Tag{}, m, std::forward<Arg>(a)); 9372f7116aSPatrick Williams }; 9472f7116aSPatrick Williams 9572f7116aSPatrick Williams /* Determine if a type has any set_property call. */ 9672f7116aSPatrick Williams template <typename Tag, typename Instance, typename Arg> 9772f7116aSPatrick Williams concept has_set_property = has_set_property_nomsg<Tag, Instance, Arg> || 9872f7116aSPatrick Williams has_set_property_msg<Tag, Instance, Arg>; 9972f7116aSPatrick Williams 100e15ff88bSPatrick Williams /* Determine if a type has a method call. */ 101e15ff88bSPatrick Williams template <typename Tag, typename Instance, typename... Args> 102e15ff88bSPatrick Williams concept has_method_nomsg = requires(Instance& i, Args&&... a) { 103e15ff88bSPatrick Williams i.method_call(Tag{}, std::forward<Args>(a)...); 104e15ff88bSPatrick Williams }; 105e15ff88bSPatrick Williams 106e15ff88bSPatrick Williams /* Determine if a type has a method call that requires a msg. */ 107e15ff88bSPatrick Williams template <typename Tag, typename Instance, typename... Args> 108e15ff88bSPatrick Williams concept has_method_msg = 109e15ff88bSPatrick Williams requires(Instance& i, sdbusplus::message_t& m, Args&&... a) { 110e15ff88bSPatrick Williams i.method_call(Tag{}, m, std::forward<Args>(a)...); 111e15ff88bSPatrick Williams }; 112e15ff88bSPatrick Williams 113e15ff88bSPatrick Williams /* Determine if a type has any method call. */ 114e15ff88bSPatrick Williams template <typename Tag, typename Instance, typename... Args> 115e15ff88bSPatrick Williams concept has_method = has_method_nomsg<Tag, Instance, Args...> || 116e15ff88bSPatrick Williams has_method_msg<Tag, Instance, Args...>; 117e15ff88bSPatrick Williams 118bf0283aeSPatrick Williams } // namespace server::details 119bf0283aeSPatrick Williams 120bf0283aeSPatrick Williams } // namespace sdbusplus::async 121