1 #pragma once
2 
3 #include <sdbusplus/async/proxy.hpp>
4 
5 namespace sdbusplus::async
6 {
7 
8 namespace client
9 {
10 
11 /** An aggregation class of sdbusplus::async::proxy-based client types.
12  *
13  *  The resulting class acts as a union of all Types from the template
14  *  arguments.
15  *
16  *  Like a `proxy`, the class only becomes functional once the service and
17  *  path are populated.
18  */
19 template <bool S, bool P, bool Preserved, template <typename> typename... Types>
20 class client :
21     public Types<sdbusplus::async::proxy_ns::proxy<S, P, false, Preserved>>...
22 {
23   private:
24     sdbusplus::async::context& ctx;
25     sdbusplus::async::proxy_ns::proxy<S, P, false, Preserved> proxy{};
26 
27   public:
28     constexpr client() = delete;
29     /* Delete default constructor if Service or Path have been provided. */
30     explicit client(sdbusplus::async::context& ctx)
31         requires(S || P)
32     = delete;
33     /* Default (empty) constructor only when Service and Path are missing. */
34     explicit client(sdbusplus::async::context& ctx)
35         requires(!S && !P)
36         : Types<decltype(proxy)>(ctx, proxy)..., ctx(ctx)
37     {}
38 
39     /* Conversion constructor for a non-empty (Service and/or Path) proxy. */
40     explicit client(sdbusplus::async::context& ctx,
41                     sdbusplus::async::proxy_ns::proxy<S, P, false, Preserved> p)
42         requires(S || P)
43         : Types<decltype(proxy)>(ctx, p)..., ctx(ctx), proxy(p)
44     {}
45 
46     /* Convert a non-Service instance to a Service instance. */
47     auto service(auto& s) const noexcept
48         requires(!S)
49     {
50         return client<true, P, Preserved, Types...>(ctx, proxy.service(s));
51     }
52 
53     /* Convert a non-Path instance to a Path instance. */
54     auto path(auto& p) const noexcept
55         requires(!P)
56     {
57         return client<S, true, Preserved, Types...>(ctx, proxy.path(p));
58     }
59 };
60 
61 } // namespace client
62 
63 /** A non-Preserved client alias.
64  *
65  *  This holds Service/Path in string-views, which must exist longer than
66  *  the lifetime of this client_t.
67  */
68 template <template <typename> typename... Types>
69 using client_t = client::client<false, false, false, Types...>;
70 /** A Preserved client alias.
71  *
72  *  This holds Service/Path in strings, which thus have lifetimes that are
73  *  the same as the client itself.
74  */
75 template <template <typename> typename... Types>
76 using client_preserved_t = client::client<false, false, false, Types...>;
77 
78 } // namespace sdbusplus::async
79