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::proxy_ns::proxy<S, P, false, Preserved> proxy{};
25 
26   public:
27     /* Delete default constructor if Service or Path have been provided. */
28     constexpr client()
29         requires(S || P)
30     = delete;
31     /* Default (empty) constructor only when Service and Path are missing. */
32     constexpr client()
33         requires(!S && !P)
34         : Types<decltype(proxy)>(proxy)...
35     {}
36 
37     /* Conversion constructor for a non-empty (Service and/or Path) proxy. */
38     constexpr explicit client(
39         sdbusplus::async::proxy_ns::proxy<S, P, false, Preserved> p)
40         requires(S || P)
41         : Types<decltype(proxy)>(p)..., proxy(p)
42     {}
43 
44     /* Convert a non-Service instance to a Service instance. */
45     constexpr auto service(auto& s) const noexcept
46         requires(!S)
47     {
48         return client<true, P, Preserved, Types...>(proxy.service(s));
49     }
50 
51     /* Convert a non-Path instance to a Path instance. */
52     constexpr auto path(auto& p) const noexcept
53         requires(!P)
54     {
55         return client<S, true, Preserved, Types...>(proxy.path(p));
56     }
57 };
58 
59 } // namespace client
60 
61 /** A non-Preserved client alias.
62  *
63  *  This holds Service/Path in string-views, which must exist longer than
64  *  the lifetime of this client_t.
65  */
66 template <template <typename> typename... Types>
67 using client_t = client::client<false, false, false, Types...>;
68 /** A Preserved client alias.
69  *
70  *  This holds Service/Path in strings, which thus have lifetimes that are
71  *  the same as the client itself.
72  */
73 template <template <typename> typename... Types>
74 using client_preserved_t = client::client<false, false, false, Types...>;
75 
76 } // namespace sdbusplus::async
77