From d41a176c2a98d4c9b3a2b2a86725c47dc055ae10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stanislav=20Angelovi=C4=8D?= Date: Tue, 16 Apr 2024 18:16:40 +0200 Subject: [PATCH] refactor: use string_view in Property convenience classes --- include/sdbus-c++/ConvenienceApiClasses.h | 49 ++++---- include/sdbus-c++/ConvenienceApiClasses.inl | 126 +++++++------------- include/sdbus-c++/IProxy.h | 9 +- include/sdbus-c++/StandardInterfaces.h | 3 +- 4 files changed, 69 insertions(+), 118 deletions(-) diff --git a/include/sdbus-c++/ConvenienceApiClasses.h b/include/sdbus-c++/ConvenienceApiClasses.h index fbad100..2d9dcec 100644 --- a/include/sdbus-c++/ConvenienceApiClasses.h +++ b/include/sdbus-c++/ConvenienceApiClasses.h @@ -37,6 +37,7 @@ #include #include #include +#include #include // Forward declarations @@ -133,8 +134,8 @@ namespace sdbus { { public: SignalSubscriber(IProxy& proxy, const SignalName& signalName); - SignalSubscriber& onInterface(InterfaceName interfaceName); - SignalSubscriber& onInterface(std::string interfaceName); + SignalSubscriber& onInterface(InterfaceName interfaceName); // TODO: This could be const char* + SignalSubscriber& onInterface(std::string interfaceName); // TODO: This could be const char* template void call(_Function&& callback); template [[nodiscard]] Slot call(_Function&& callback, return_slot_t); @@ -150,24 +151,22 @@ namespace sdbus { class PropertyGetter { public: - PropertyGetter(IProxy& proxy, const PropertyName& propertyName); - Variant onInterface(const InterfaceName& interfaceName); - Variant onInterface(const std::string& interfaceName); + PropertyGetter(IProxy& proxy, std::string_view propertyName); + Variant onInterface(std::string_view interfaceName); private: static inline const InterfaceName DBUS_PROPERTIES_INTERFACE_NAME{"org.freedesktop.DBus.Properties"}; private: IProxy& proxy_; - const PropertyName& propertyName_; + std::string_view propertyName_; }; class AsyncPropertyGetter { public: - AsyncPropertyGetter(IProxy& proxy, const PropertyName& propertyName); - AsyncPropertyGetter& onInterface(const InterfaceName& interfaceName); - AsyncPropertyGetter& onInterface(const std::string& interfaceName); + AsyncPropertyGetter(IProxy& proxy, std::string_view propertyName); + AsyncPropertyGetter& onInterface(std::string_view interfaceName); template PendingAsyncCall uponReplyInvoke(_Function&& callback); std::future getResultAsFuture(); @@ -176,16 +175,15 @@ namespace sdbus { private: IProxy& proxy_; - const PropertyName& propertyName_; - const InterfaceName* interfaceName_{}; + std::string_view propertyName_; + std::string_view interfaceName_; }; class PropertySetter { public: - PropertySetter(IProxy& proxy, const PropertyName& propertyName); - PropertySetter& onInterface(const InterfaceName& interfaceName); - PropertySetter& onInterface(const std::string& interfaceName); + PropertySetter(IProxy& proxy, std::string_view propertyName); + PropertySetter& onInterface(std::string_view interfaceName); template void toValue(const _Value& value); template void toValue(const _Value& value, dont_expect_reply_t); void toValue(const Variant& value); @@ -196,16 +194,15 @@ namespace sdbus { private: IProxy& proxy_; - const PropertyName& propertyName_; - const InterfaceName* interfaceName_{}; + std::string_view propertyName_; + std::string_view interfaceName_; }; class AsyncPropertySetter { public: - AsyncPropertySetter(IProxy& proxy, const PropertyName& propertyName); - AsyncPropertySetter& onInterface(const InterfaceName& interfaceName); - AsyncPropertySetter& onInterface(const std::string& interfaceName); + AsyncPropertySetter(IProxy& proxy, std::string_view propertyName); + AsyncPropertySetter& onInterface(std::string_view interfaceName); template AsyncPropertySetter& toValue(_Value&& value); AsyncPropertySetter& toValue(Variant value); template PendingAsyncCall uponReplyInvoke(_Function&& callback); @@ -216,8 +213,8 @@ namespace sdbus { private: IProxy& proxy_; - const PropertyName& propertyName_; - const InterfaceName* interfaceName_{}; + std::string_view propertyName_; + std::string_view interfaceName_; Variant value_; }; @@ -225,8 +222,7 @@ namespace sdbus { { public: AllPropertiesGetter(IProxy& proxy); - std::map onInterface(const InterfaceName& interfaceName); - std::map onInterface(const std::string& interfaceName); + std::map onInterface(std::string_view interfaceName); private: static inline const InterfaceName DBUS_PROPERTIES_INTERFACE_NAME{"org.freedesktop.DBus.Properties"}; @@ -239,17 +235,16 @@ namespace sdbus { { public: AsyncAllPropertiesGetter(IProxy& proxy); - AsyncAllPropertiesGetter& onInterface(const InterfaceName& interfaceName); - AsyncAllPropertiesGetter& onInterface(const std::string& interfaceName); + AsyncAllPropertiesGetter& onInterface(std::string_view interfaceName); template PendingAsyncCall uponReplyInvoke(_Function&& callback); std::future> getResultAsFuture(); private: - static inline const InterfaceName DBUS_PROPERTIES_INTERFACE_NAME{"org.freedesktop.DBus.Properties"}; + static inline const InterfaceName DBUS_PROPERTIES_INTERFACE_NAME{"org.freedesktop.DBus.Properties"}; // TODO: Couldn't this be const char*? private: IProxy& proxy_; - const InterfaceName* interfaceName_{}; + std::string_view interfaceName_; }; } // namespace sdbus diff --git a/include/sdbus-c++/ConvenienceApiClasses.inl b/include/sdbus-c++/ConvenienceApiClasses.inl index a6111da..fb67973 100644 --- a/include/sdbus-c++/ConvenienceApiClasses.inl +++ b/include/sdbus-c++/ConvenienceApiClasses.inl @@ -404,13 +404,13 @@ namespace sdbus { /*** PropertyGetter ***/ /*** -------------- ***/ - inline PropertyGetter::PropertyGetter(IProxy& proxy, const PropertyName& propertyName) + inline PropertyGetter::PropertyGetter(IProxy& proxy, std::string_view propertyName) : proxy_(proxy) - , propertyName_(propertyName) + , propertyName_(std::move(propertyName)) { } - inline Variant PropertyGetter::onInterface(const InterfaceName& interfaceName) + inline Variant PropertyGetter::onInterface(std::string_view interfaceName) { Variant var; proxy_.callMethod("Get") @@ -420,57 +420,43 @@ namespace sdbus { return var; } - inline Variant PropertyGetter::onInterface(const std::string& interfaceName) - { - // Down-cast through static cast for performance reasons (no extra copy and object construction needed) - static_assert(sizeof(interfaceName) == sizeof(InterfaceName)); - return onInterface(static_cast(interfaceName)); - } - /*** ------------------- ***/ /*** AsyncPropertyGetter ***/ /*** ------------------- ***/ - inline AsyncPropertyGetter::AsyncPropertyGetter(IProxy& proxy, const PropertyName& propertyName) - : proxy_(proxy) - , propertyName_(propertyName) + inline AsyncPropertyGetter::AsyncPropertyGetter(IProxy& proxy, std::string_view propertyName) + : proxy_(proxy) + , propertyName_(std::move(propertyName)) { } - inline AsyncPropertyGetter& AsyncPropertyGetter::onInterface(const InterfaceName& interfaceName) + inline AsyncPropertyGetter& AsyncPropertyGetter::onInterface(std::string_view interfaceName) { - interfaceName_ = &interfaceName; + interfaceName_ = std::move(interfaceName); return *this; } - inline AsyncPropertyGetter& AsyncPropertyGetter::onInterface(const std::string& interfaceName) - { - // Down-cast through static cast for performance reasons (no extra copy and object construction needed) - static_assert(sizeof(interfaceName) == sizeof(InterfaceName)); - return onInterface(static_cast(interfaceName)); - } - template PendingAsyncCall AsyncPropertyGetter::uponReplyInvoke(_Function&& callback) { static_assert(std::is_invocable_r_v, Variant>, "Property get callback function must accept std::optional and property value as Variant"); - assert(interfaceName_ != nullptr); // onInterface() must be placed/called prior to this function + assert(!interfaceName_.empty()); // onInterface() must be placed/called prior to this function return proxy_.callMethodAsync("Get") .onInterface(DBUS_PROPERTIES_INTERFACE_NAME) - .withArguments(*interfaceName_, propertyName_) + .withArguments(interfaceName_, propertyName_) .uponReplyInvoke(std::forward<_Function>(callback)); } inline std::future AsyncPropertyGetter::getResultAsFuture() { - assert(interfaceName_ != nullptr); // onInterface() must be placed/called prior to this function + assert(!interfaceName_.empty()); // onInterface() must be placed/called prior to this function return proxy_.callMethodAsync("Get") .onInterface(DBUS_PROPERTIES_INTERFACE_NAME) - .withArguments(*interfaceName_, propertyName_) + .withArguments(interfaceName_, propertyName_) .getResultAsFuture(); } @@ -478,26 +464,19 @@ namespace sdbus { /*** PropertySetter ***/ /*** -------------- ***/ - inline PropertySetter::PropertySetter(IProxy& proxy, const PropertyName& propertyName) + inline PropertySetter::PropertySetter(IProxy& proxy, std::string_view propertyName) : proxy_(proxy) - , propertyName_(propertyName) + , propertyName_(std::move(propertyName)) { } - inline PropertySetter& PropertySetter::onInterface(const InterfaceName& interfaceName) + inline PropertySetter& PropertySetter::onInterface(std::string_view interfaceName) { - interfaceName_ = &interfaceName; + interfaceName_ = std::move(interfaceName); return *this; } - inline PropertySetter& PropertySetter::onInterface(const std::string& interfaceName) - { - // Down-cast through static cast for performance reasons (no extra copy and object construction needed) - static_assert(sizeof(interfaceName) == sizeof(InterfaceName)); - return onInterface(static_cast(interfaceName)); - } - template inline void PropertySetter::toValue(const _Value& value) { @@ -512,47 +491,40 @@ namespace sdbus { inline void PropertySetter::toValue(const Variant& value) { - assert(interfaceName_ != nullptr); // onInterface() must be placed/called prior to this function + assert(!interfaceName_.empty()); // onInterface() must be placed/called prior to this function proxy_.callMethod("Set") .onInterface(DBUS_PROPERTIES_INTERFACE_NAME) - .withArguments(*interfaceName_, propertyName_, value); + .withArguments(interfaceName_, propertyName_, value); } inline void PropertySetter::toValue(const Variant& value, dont_expect_reply_t) { - assert(interfaceName_ != nullptr); // onInterface() must be placed/called prior to this function + assert(!interfaceName_.empty()); // onInterface() must be placed/called prior to this function proxy_.callMethod("Set") - .onInterface(DBUS_PROPERTIES_INTERFACE_NAME) - .withArguments(*interfaceName_, propertyName_, value) - .dontExpectReply(); + .onInterface(DBUS_PROPERTIES_INTERFACE_NAME) + .withArguments(interfaceName_, propertyName_, value) + .dontExpectReply(); } /*** ------------------- ***/ /*** AsyncPropertySetter ***/ /*** ------------------- ***/ - inline AsyncPropertySetter::AsyncPropertySetter(IProxy& proxy, const PropertyName& propertyName) - : proxy_(proxy) - , propertyName_(propertyName) + inline AsyncPropertySetter::AsyncPropertySetter(IProxy& proxy, std::string_view propertyName) + : proxy_(proxy) + , propertyName_(propertyName) { } - inline AsyncPropertySetter& AsyncPropertySetter::onInterface(const InterfaceName& interfaceName) + inline AsyncPropertySetter& AsyncPropertySetter::onInterface(std::string_view interfaceName) { - interfaceName_ = &interfaceName; + interfaceName_ = std::move(interfaceName); return *this; } - inline AsyncPropertySetter& AsyncPropertySetter::onInterface(const std::string& interfaceName) - { - // Down-cast through static cast for performance reasons (no extra copy and object construction needed) - static_assert(sizeof(interfaceName) == sizeof(InterfaceName)); - return onInterface(static_cast(interfaceName)); - } - template inline AsyncPropertySetter& AsyncPropertySetter::toValue(_Value&& value) { @@ -571,21 +543,21 @@ namespace sdbus { { static_assert(std::is_invocable_r_v>, "Property set callback function must accept std::optional only"); - assert(interfaceName_ != nullptr); // onInterface() must be placed/called prior to this function + assert(!interfaceName_.empty()); // onInterface() must be placed/called prior to this function return proxy_.callMethodAsync("Set") .onInterface(DBUS_PROPERTIES_INTERFACE_NAME) - .withArguments(*interfaceName_, propertyName_, std::move(value_)) + .withArguments(interfaceName_, propertyName_, std::move(value_)) .uponReplyInvoke(std::forward<_Function>(callback)); } inline std::future AsyncPropertySetter::getResultAsFuture() { - assert(interfaceName_ != nullptr); // onInterface() must be placed/called prior to this function + assert(!interfaceName_.empty()); // onInterface() must be placed/called prior to this function return proxy_.callMethodAsync("Set") .onInterface(DBUS_PROPERTIES_INTERFACE_NAME) - .withArguments(*interfaceName_, propertyName_, std::move(value_)) + .withArguments(interfaceName_, propertyName_, std::move(value_)) .getResultAsFuture<>(); } @@ -594,27 +566,20 @@ namespace sdbus { /*** ------------------- ***/ inline AllPropertiesGetter::AllPropertiesGetter(IProxy& proxy) - : proxy_(proxy) + : proxy_(proxy) { } - inline std::map AllPropertiesGetter::onInterface(const InterfaceName& interfaceName) + inline std::map AllPropertiesGetter::onInterface(std::string_view interfaceName) { std::map props; proxy_.callMethod("GetAll") - .onInterface(DBUS_PROPERTIES_INTERFACE_NAME) - .withArguments(interfaceName) - .storeResultsTo(props); + .onInterface(DBUS_PROPERTIES_INTERFACE_NAME) + .withArguments(std::move(interfaceName)) + .storeResultsTo(props); return props; } - inline std::map AllPropertiesGetter::onInterface(const std::string& interfaceName) - { - // Down-cast through static cast for performance reasons (no extra copy and object construction needed) - static_assert(sizeof(interfaceName) == sizeof(InterfaceName)); - return onInterface(static_cast(interfaceName)); - } - /*** ------------------------ ***/ /*** AsyncAllPropertiesGetter ***/ /*** ------------------------ ***/ @@ -624,41 +589,34 @@ namespace sdbus { { } - inline AsyncAllPropertiesGetter& AsyncAllPropertiesGetter::onInterface(const InterfaceName& interfaceName) + inline AsyncAllPropertiesGetter& AsyncAllPropertiesGetter::onInterface(std::string_view interfaceName) { - interfaceName_ = &interfaceName; + interfaceName_ = std::move(interfaceName); return *this; } - inline AsyncAllPropertiesGetter& AsyncAllPropertiesGetter::onInterface(const std::string& interfaceName) - { - // Down-cast through static cast for performance reasons (no extra copy and object construction needed) - static_assert(sizeof(interfaceName) == sizeof(InterfaceName)); - return onInterface(static_cast(interfaceName)); - } - template PendingAsyncCall AsyncAllPropertiesGetter::uponReplyInvoke(_Function&& callback) { static_assert( std::is_invocable_r_v, std::map> , "All properties get callback function must accept std::optional and a map of property names to their values" ); - assert(interfaceName_ != nullptr); // onInterface() must be placed/called prior to this function + assert(!interfaceName_.empty()); // onInterface() must be placed/called prior to this function return proxy_.callMethodAsync("GetAll") .onInterface(DBUS_PROPERTIES_INTERFACE_NAME) - .withArguments(*interfaceName_) + .withArguments(interfaceName_) .uponReplyInvoke(std::forward<_Function>(callback)); } inline std::future> AsyncAllPropertiesGetter::getResultAsFuture() { - assert(interfaceName_ != nullptr); // onInterface() must be placed/called prior to this function + assert(!interfaceName_.empty()); // onInterface() must be placed/called prior to this function return proxy_.callMethodAsync("GetAll") .onInterface(DBUS_PROPERTIES_INTERFACE_NAME) - .withArguments(*interfaceName_) + .withArguments(interfaceName_) .getResultAsFuture>(); } diff --git a/include/sdbus-c++/IProxy.h b/include/sdbus-c++/IProxy.h index 88eb1b8..46c7cbe 100644 --- a/include/sdbus-c++/IProxy.h +++ b/include/sdbus-c++/IProxy.h @@ -35,6 +35,7 @@ #include #include #include +#include // Forward declarations namespace sdbus { @@ -358,7 +359,7 @@ namespace sdbus { /*! * @copydoc IProxy::getProperty(const PropertyName&) */ - [[nodiscard]] PropertyGetter getProperty(const std::string& propertyName); + [[nodiscard]] PropertyGetter getProperty(std::string_view propertyName); /*! * @brief Gets value of a property of the D-Bus object asynchronously @@ -610,11 +611,9 @@ namespace sdbus { return PropertyGetter(*this, propertyName); } - inline PropertyGetter IProxy::getProperty(const std::string& propertyName) + inline PropertyGetter IProxy::getProperty(std::string_view propertyName) { - // Down-cast through static cast for performance reasons (no extra copy and object construction needed) - static_assert(sizeof(propertyName) == sizeof(PropertyName)); - return getProperty(static_cast(propertyName)); + return PropertyGetter(*this, propertyName); } inline AsyncPropertyGetter IProxy::getPropertyAsync(const PropertyName& propertyName) diff --git a/include/sdbus-c++/StandardInterfaces.h b/include/sdbus-c++/StandardInterfaces.h index c1ffa50..a4217d0 100644 --- a/include/sdbus-c++/StandardInterfaces.h +++ b/include/sdbus-c++/StandardInterfaces.h @@ -150,8 +150,7 @@ namespace sdbus { return proxy_->getProperty(propertyName).onInterface(interfaceName); } - // TODO: Refactor from std::string to std::string_view before release/v2.0 !!! - sdbus::Variant Get(const InterfaceName& interfaceName, const std::string& propertyName) + sdbus::Variant Get(const InterfaceName& interfaceName, std::string_view propertyName) { return proxy_->getProperty(propertyName).onInterface(interfaceName); }