sdbus++: async: client: fix client_t usage
When using the "Alternatively,..." syntax from calculator-client, we
end up with the compiler error:
```
example/gen/net/poettering/Calculator/client.hpp:149:40: error: ‘constexpr sdbusplus::client::net::poettering::details::Calculator<Proxy>::Calculator(sdbusplus::async::context&, Proxy) [with Proxy = sdbusplus::async::proxy_ns::proxy<true, true, false, false>]’ is private within this context
149 | std::forward<Args>(args)...)
```
Fix this by making the generated alias class a friend of the details
class, in addition to the client_t proxy. Add a compile test to ensure
this works. Fix up a few whitespace alignment to better match
clang-format expectations.
Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
Change-Id: Ie0def6e6c96acc287c002c157d93016b4a79015c
diff --git a/example/calculator-client.cpp b/example/calculator-client.cpp
index 6bb2bc7..ab47767 100644
--- a/example/calculator-client.cpp
+++ b/example/calculator-client.cpp
@@ -14,6 +14,11 @@
// Alternatively, sdbusplus::async::client_t<Calculator, ...>() could have
// been used to combine multiple interfaces into a single client-proxy.
+ auto alternative_c [[maybe_unused]] =
+ sdbusplus::async::client_t<
+ sdbusplus::client::net::poettering::Calculator>(ctx)
+ .service(service)
+ .path(path);
{
// Call the Multiply method.
diff --git a/tools/sdbusplus/templates/interface.client.hpp.mako b/tools/sdbusplus/templates/interface.client.hpp.mako
index 1d29441..e5b3c9b 100644
--- a/tools/sdbusplus/templates/interface.client.hpp.mako
+++ b/tools/sdbusplus/templates/interface.client.hpp.mako
@@ -22,15 +22,44 @@
namespace details
{
+// forward declaration
+template <typename Proxy>
+class ${interface.classname};
+} // namespace details
+
+/** Alias class so we can use the client in both a client_t aggregation
+ * and individually.
+ *
+ * sdbusplus::async::client_t<${interface.classname}>() or
+ * ${interface.classname}() both construct an equivalent instance.
+ */
+template <typename Proxy = void>
+struct ${interface.classname} :
+ public std::conditional_t<std::is_void_v<Proxy>,
+ sdbusplus::async::client_t<details::${interface.classname}>,
+ details::${interface.classname}<Proxy>>
+{
+ template <typename... Args>
+ ${interface.classname}(Args&&... args) :
+ std::conditional_t<std::is_void_v<Proxy>,
+ sdbusplus::async::client_t<details::${interface.classname}>,
+ details::${interface.classname}<Proxy>>(
+ std::forward<Args>(args)...)
+ {}
+};
+
+namespace details
+{
template <typename Proxy>
-class ${interface.classname} :
- public sdbusplus::common::${interface.cppNamespacedClass()}
+class ${interface.classname} : public sdbusplus::common::${interface.cppNamespacedClass()}
{
public:
- template <bool S, bool P, bool Preserved,
- template <typename> typename... Types>
+ template <bool, bool, bool, template <typename> typename...>
friend class sdbusplus::async::client::client;
+ template <typename>
+ friend class sdbusplus::client::${interface.cppNamespacedClass()};
+
// Delete default constructor as these should only be constructed
// indirectly through sdbusplus::async::client_t.
${interface.classname}() = delete;
@@ -44,7 +73,8 @@
private:
// Conversion constructor from proxy used by client_t.
constexpr ${interface.classname}(sdbusplus::async::context& ctx, Proxy p) :
- ctx(ctx), proxy(p.interface(interface)) {}
+ ctx(ctx), proxy(p.interface(interface))
+ {}
sdbusplus::async::context& ctx{};
decltype(std::declval<Proxy>().interface(interface)) proxy = {};
@@ -52,26 +82,4 @@
} // namespace details
-/** Alias class so we can use the client in both a client_t aggregation
- * and individually.
- *
- * sdbusplus::async::client_t<${interface.classname}>() or
- * ${interface.classname}() both construct an equivalent instance.
- */
-template <typename Proxy = void>
-struct ${interface.classname} : public
- std::conditional_t<
- std::is_void_v<Proxy>,
- sdbusplus::async::client_t<details::${interface.classname}>,
- details::${interface.classname}<Proxy>>
-{
- template <typename... Args>
- ${interface.classname}(Args&&... args) :
- std::conditional_t<std::is_void_v<Proxy>,
- sdbusplus::async::client_t<details::${interface.classname}>,
- details::${interface.classname}<Proxy>>(
- std::forward<Args>(args)...)
- {}
-};
-
-} // namespace sdbusplus::client::${interface.cppNamespacedClass()}
+} // namespace sdbusplus::client::${interface.cppNamespace()}