This is an automated email from the ASF dual-hosted git repository. pnoltes pushed a commit to branch feature/apply_use_stringview in repository https://gitbox.apache.org/repos/asf/celix.git
commit de6fbfe565be114cf58320a8ab3a173eb84687a7 Author: Pepijn Noltes <[email protected]> AuthorDate: Sun Dec 5 11:42:18 2021 +0100 Applies use of string_view for all C++17 headers --- libs/framework/include/celix/Bundle.h | 23 ++++---- libs/framework/include/celix/BundleContext.h | 53 ++++++++--------- libs/framework/include/celix/ServiceRegistration.h | 20 +++---- .../include/celix/ServiceRegistrationBuilder.h | 24 ++------ libs/framework/include/celix/TrackerBuilders.h | 10 ++-- libs/framework/include/celix/Trackers.h | 32 +++++------ libs/framework/include/celix/UseServiceBuilder.h | 6 +- libs/utils/gtest/src/CxxPropertiesTestSuite.cc | 18 ++++++ libs/utils/gtest/src/CxxUtilsTestSuite.cc | 12 +++- libs/utils/include/celix/Filter.h | 19 ++++--- libs/utils/include/celix/Properties.h | 66 +++++++++------------- libs/utils/include/celix/Utils.h | 14 ++--- 12 files changed, 150 insertions(+), 147 deletions(-) diff --git a/libs/framework/include/celix/Bundle.h b/libs/framework/include/celix/Bundle.h index 4b11cfd..954628c 100644 --- a/libs/framework/include/celix/Bundle.h +++ b/libs/framework/include/celix/Bundle.h @@ -41,6 +41,7 @@ namespace celix { * Each bundle installed in the Celix framework must have an associated Bundle object. * A bundle must have a unique identity, a long, chosen by the Celix framework. * + * @note Provided `std::string_view` values must be null terminated strings. * @note Thread safe. */ class Bundle { @@ -63,9 +64,9 @@ namespace celix { * @param path The relative path to a bundle resource * @return The use-able entry path or an empty string if the entry is not found. */ - [[nodiscard]] std::string getEntry(const std::string& path) const { + [[nodiscard]] std::string getEntry(std::string_view path) const { std::string result{}; - char* entry = celix_bundle_getEntry(cBnd.get(), path.c_str()); + char* entry = celix_bundle_getEntry(cBnd.get(), path.data()); if (entry != nullptr) { result = std::string{entry}; free(entry); @@ -76,29 +77,29 @@ namespace celix { /** * @brief the symbolic name of the bundle. */ - [[nodiscard]] std::string getSymbolicName() const { - return std::string{celix_bundle_getSymbolicName(cBnd.get())}; + [[nodiscard]] std::string_view getSymbolicName() const { + return std::string_view{celix_bundle_getSymbolicName(cBnd.get())}; } /** * @brief The name of the bundle. */ - [[nodiscard]] std::string getName() const { - return std::string{celix_bundle_getName(cBnd.get())}; + [[nodiscard]] std::string_view getName() const { + return std::string_view{celix_bundle_getName(cBnd.get())}; } /** * @brief The group of the bundle. */ - [[nodiscard]] std::string getGroup() const { - return std::string{celix_bundle_getGroup(cBnd.get())}; + [[nodiscard]] std::string_view getGroup() const { + return std::string_view{celix_bundle_getGroup(cBnd.get())}; } /** - * @brief The descriptoin of the bundle. + * @brief The description of the bundle. */ - [[nodiscard]] std::string getDescription() const { - return std::string{celix_bundle_getDescription(cBnd.get())}; + [[nodiscard]] std::string_view getDescription() const { + return std::string_view{celix_bundle_getDescription(cBnd.get())}; } /** diff --git a/libs/framework/include/celix/BundleContext.h b/libs/framework/include/celix/BundleContext.h index 66c79a0..a63e220 100644 --- a/libs/framework/include/celix/BundleContext.h +++ b/libs/framework/include/celix/BundleContext.h @@ -46,6 +46,7 @@ namespace celix { * - Access bundles * - Get config properties * + * @note Provided `std::string_view` values must be null terminated strings. * @note Thread safe. */ class BundleContext { @@ -78,7 +79,7 @@ namespace celix { * @return A ServiceRegistrationBuilder object. */ template<typename I, typename Implementer> - ServiceRegistrationBuilder<I> registerService(std::shared_ptr<Implementer> implementer, const std::string& name = {}) { + ServiceRegistrationBuilder<I> registerService(std::shared_ptr<Implementer> implementer, std::string_view name = {}) { std::shared_ptr<I> svc = implementer; //note Implement should be derived from I return ServiceRegistrationBuilder<I>{cCtx, std::move(svc), celix::typeName<I>(name)}; } @@ -94,7 +95,7 @@ namespace celix { * service sync (because the svc pointer is unmanaged). */ template<typename I, typename Implementer> - ServiceRegistrationBuilder<I> registerUnmanagedService(Implementer* svc, const std::string& name = {}) { + ServiceRegistrationBuilder<I> registerUnmanagedService(Implementer* svc, std::string_view name = {}) { auto unmanagedSvc = std::shared_ptr<I>{svc, [](I*){/*nop*/}}; return ServiceRegistrationBuilder<I>{cCtx, std::move(unmanagedSvc), celix::typeName<I>(name), true, false}; } @@ -128,7 +129,7 @@ namespace celix { * @return A UseServiceBuilder object. */ template<typename I> - UseServiceBuilder<I> useService(const std::string& name = {}) { + UseServiceBuilder<I> useService(std::string_view name = {}) { return UseServiceBuilder<I>{cCtx, celix::typeName<I>(name), true}; } @@ -156,7 +157,7 @@ namespace celix { * @return A UseServiceBuilder object. */ template<typename I> - UseServiceBuilder<I> useServices(const std::string& name = {}) { + UseServiceBuilder<I> useServices(std::string_view name = {}) { return UseServiceBuilder<I>{cCtx, celix::typeName<I>(name), false}; } @@ -172,7 +173,7 @@ namespace celix { * @return The service id of the found service or -1 if the service was not found. */ template<typename I> - long findService(const std::string& filter = {}, const std::string& versionRange = {}) { + long findService(std::string_view filter = {}, std::string_view versionRange = {}) { return findServiceWithName(celix::typeName<I>(), filter, versionRange); } @@ -185,12 +186,12 @@ namespace celix { * @param versionRange An optional version range. * @return The service id of the found service or -1 if the service was not found. */ - long findServiceWithName(const std::string& name, const std::string& filter = {}, const std::string& versionRange = {}) { + long findServiceWithName(std::string_view name, std::string_view filter = {}, std::string_view versionRange = {}) { waitIfAbleForEvents(); celix_service_filter_options_t opts{}; - opts.serviceName = name.empty() ? nullptr : name.c_str(); - opts.filter = filter.empty() ? nullptr : filter.c_str(); - opts.versionRange = versionRange.empty() ? nullptr : versionRange.c_str(); + opts.serviceName = name.empty() ? nullptr : name.data(); + opts.filter = filter.empty() ? nullptr : filter.data(); + opts.versionRange = versionRange.empty() ? nullptr : versionRange.data(); return celix_bundleContext_findServiceWithOptions(cCtx.get(), &opts); } @@ -206,7 +207,7 @@ namespace celix { * @return A vector of service ids. */ template<typename I> - std::vector<long> findServices(const std::string& filter = {}, const std::string& versionRange = {}) { + std::vector<long> findServices(std::string_view filter = {}, std::string_view versionRange = {}) { return findServicesWithName(celix::typeName<I>(), filter, versionRange); } @@ -219,12 +220,12 @@ namespace celix { * @param versionRange An optional version range. * @return A vector of service ids. */ - std::vector<long> findServicesWithName(const std::string& name, const std::string& filter = {}, const std::string& versionRange = {}) { + std::vector<long> findServicesWithName(std::string_view name, std::string_view filter = {}, std::string_view versionRange = {}) { waitIfAbleForEvents(); celix_service_filter_options_t opts{}; - opts.serviceName = name.empty() ? nullptr : name.c_str(); - opts.filter = filter.empty() ? nullptr : filter.c_str(); - opts.versionRange = versionRange.empty() ? nullptr : versionRange.c_str(); + opts.serviceName = name.empty() ? nullptr : name.data(); + opts.filter = filter.empty() ? nullptr : filter.data(); + opts.versionRange = versionRange.empty() ? nullptr : versionRange.data(); std::vector<long> result{}; auto cList = celix_bundleContext_findServicesWithOptions(cCtx.get(), &opts); @@ -257,7 +258,7 @@ namespace celix { * @return A ServiceTrackerBuilder object. */ template<typename I> - ServiceTrackerBuilder<I> trackServices(const std::string& name = {}) { + ServiceTrackerBuilder<I> trackServices(std::string_view name = {}) { return ServiceTrackerBuilder<I>{cCtx, celix::typeName<I>(name)}; } @@ -310,7 +311,7 @@ namespace celix { * @return A MetaTrackerBuilder object. */ template<typename I> - MetaTrackerBuilder trackServiceTrackers(const std::string& name = {}) { + MetaTrackerBuilder trackServiceTrackers(std::string_view name = {}) { return MetaTrackerBuilder(cCtx, celix::typeName<I>(name)); } @@ -332,8 +333,8 @@ namespace celix { * @param autoStart If the bundle should also be started. * @return the bundleId (>= 0) or < 0 if the bundle could not be installed and possibly started. */ - long installBundle(const std::string& bndLocation, bool autoStart = true) { - return celix_bundleContext_installBundle(cCtx.get(), bndLocation.c_str(), autoStart); + long installBundle(std::string_view bndLocation, bool autoStart = true) { + return celix_bundleContext_installBundle(cCtx.get(), bndLocation.data(), autoStart); } /** @@ -399,8 +400,8 @@ namespace celix { * @param defaultVal The default value to use if the property is not found. * @return The config property value for the provided key or the provided defaultValue is the name is not found. */ - [[nodiscard]] std::string getConfigProperty(const std::string& name, const std::string& defaultValue) const { - return std::string{celix_bundleContext_getProperty(cCtx.get(), name.c_str(), defaultValue.c_str())}; + [[nodiscard]] std::string getConfigProperty(std::string_view name, std::string_view defaultValue) const { + return std::string{celix_bundleContext_getProperty(cCtx.get(), name.data(), defaultValue.data())}; } /** @@ -415,8 +416,8 @@ namespace celix { * @return The config property value (as long) for the provided key or the provided defaultValue is the name * is not found or not a valid long. */ - [[nodiscard]] long getConfigPropertyAsLong(const std::string& name, long defaultValue) const { - return celix_bundleContext_getPropertyAsLong(cCtx.get(), name.c_str(), defaultValue); + [[nodiscard]] long getConfigPropertyAsLong(std::string_view name, long defaultValue) const { + return celix_bundleContext_getPropertyAsLong(cCtx.get(), name.data(), defaultValue); } /** @@ -431,8 +432,8 @@ namespace celix { * @return The config property value (as double) for the provided key or the provided defaultValue is the name * is not found or not a valid double. */ - [[nodiscard]] double getConfigPropertyAsDouble(const std::string& name, double defaultValue) const { - return celix_bundleContext_getPropertyAsDouble(cCtx.get(), name.c_str(), defaultValue); + [[nodiscard]] double getConfigPropertyAsDouble(std::string_view name, double defaultValue) const { + return celix_bundleContext_getPropertyAsDouble(cCtx.get(), name.data(), defaultValue); } /** @@ -449,8 +450,8 @@ namespace celix { * @return The config property value (as boolean) for the provided key or the provided defaultValue is the name * is not found or not a valid boolean. */ - [[nodiscard]] long getConfigPropertyAsBool(const std::string& name, bool defaultValue) const { - return celix_bundleContext_getPropertyAsBool(cCtx.get(), name.c_str(), defaultValue); + [[nodiscard]] long getConfigPropertyAsBool(std::string_view name, bool defaultValue) const { + return celix_bundleContext_getPropertyAsBool(cCtx.get(), name.data(), defaultValue); } /** diff --git a/libs/framework/include/celix/ServiceRegistration.h b/libs/framework/include/celix/ServiceRegistration.h index d3e4d0c..d3db605 100644 --- a/libs/framework/include/celix/ServiceRegistration.h +++ b/libs/framework/include/celix/ServiceRegistration.h @@ -69,8 +69,8 @@ namespace celix { */ static std::shared_ptr<ServiceRegistration> create(std::shared_ptr<celix_bundle_context_t> cCtx, std::shared_ptr<void> svc, - std::string name, - std::string version, + std::string_view name, + std::string_view version, celix::Properties properties, bool registerAsync, bool unregisterAsync, @@ -111,8 +111,8 @@ namespace celix { new ServiceRegistration{ std::move(cCtx), std::move(svc), - std::move(name), - std::move(version), + name, + version, std::move(properties), registerAsync, unregisterAsync, @@ -128,14 +128,14 @@ namespace celix { /** * @brief The service name for this service registration. */ - const std::string& getServiceName() const { return name; } + std::string_view getServiceName() const { return name; } /** * @brief The service version for this service registration. * * Empty string if there is no service version. */ - const std::string& getServiceVersion() const { return version; } + std::string_view getServiceVersion() const { return version; } /** * @brief The service properties for this service registration. @@ -256,16 +256,16 @@ namespace celix { ServiceRegistration( std::shared_ptr<celix_bundle_context_t> _cCtx, std::shared_ptr<void> _svc, - std::string _name, - std::string _version, + std::string_view _name, + std::string_view _version, celix::Properties _properties, bool _registerAsync, bool _unregisterAsync, std::vector<std::function<void(ServiceRegistration&)>> _onRegisteredCallbacks, std::vector<std::function<void(ServiceRegistration&)>> _onUnregisteredCallbacks) : cCtx{std::move(_cCtx)}, - name{std::move(_name)}, - version{std::move(_version)}, + name{_name}, + version{_version}, properties{std::move(_properties)}, registerAsync{_registerAsync}, unregisterAsync{_unregisterAsync}, diff --git a/libs/framework/include/celix/ServiceRegistrationBuilder.h b/libs/framework/include/celix/ServiceRegistrationBuilder.h index b4798a6..54bbd0e 100644 --- a/libs/framework/include/celix/ServiceRegistrationBuilder.h +++ b/libs/framework/include/celix/ServiceRegistrationBuilder.h @@ -45,12 +45,12 @@ namespace celix { ServiceRegistrationBuilder( std::shared_ptr<celix_bundle_context_t> _cCtx, std::shared_ptr<I> _svc, - std::string _name, + std::string_view _name, bool _registerAsync = true, bool _unregisterAsync = true) : cCtx{std::move(_cCtx)}, svc{std::move(_svc)}, - name{std::move(_name)}, + name{_name}, version{celix::typeVersion<I>()}, registerAsync{_registerAsync}, unregisterAsync{_unregisterAsync}{} @@ -64,21 +64,7 @@ namespace celix { * * This will lead to a 'service.version' service property. */ - ServiceRegistrationBuilder& setVersion(std::string v) { version = std::move(v); return *this; } - - /** - * @brief Add a property to the service properties. - * - * If a key is already present the value will be overridden. - */ - ServiceRegistrationBuilder& addProperty(const std::string& key, const std::string& value) { properties.set(key, value); return *this; } - - /** - * @brief Add a property to the service properties. - * - * If a key is already present the value will be overridden. - */ - ServiceRegistrationBuilder& addProperty(const std::string& key, const char* value) { properties.set(key, std::string{value}); return *this; } + ServiceRegistrationBuilder& setVersion(std::string_view v) { version = v; return *this; } /** * @brief Add a property to the service properties. @@ -86,12 +72,12 @@ namespace celix { * If a key is already present the value will be overridden. */ template<typename T> - ServiceRegistrationBuilder& addProperty(const std::string& key, T value) { properties.set(key, std::to_string(std::move(value))); return *this; } + ServiceRegistrationBuilder& addProperty(std::string_view key, T&& value) { properties.template set(key, std::forward<T>(value)); return *this; } /** * @brief Set the service properties. * - * Note this call will clear any already set properties. + * Note this call will clear already set properties. */ ServiceRegistrationBuilder& setProperties(celix::Properties p) { properties = std::move(p); return *this; } diff --git a/libs/framework/include/celix/TrackerBuilders.h b/libs/framework/include/celix/TrackerBuilders.h index f4acc0b..bec7308 100644 --- a/libs/framework/include/celix/TrackerBuilders.h +++ b/libs/framework/include/celix/TrackerBuilders.h @@ -42,9 +42,9 @@ namespace celix { //NOTE private to prevent move so that a build() call cannot be forgotten ServiceTrackerBuilder(ServiceTrackerBuilder&&) noexcept = default; public: - explicit ServiceTrackerBuilder(std::shared_ptr<celix_bundle_context_t> _cCtx, std::string _name) : + explicit ServiceTrackerBuilder(std::shared_ptr<celix_bundle_context_t> _cCtx, std::string_view _name) : cCtx{std::move(_cCtx)}, - name{std::move(_name)} {} + name{_name} {} ServiceTrackerBuilder& operator=(ServiceTrackerBuilder&&) = delete; ServiceTrackerBuilder(const ServiceTrackerBuilder&) = delete; @@ -57,7 +57,7 @@ namespace celix { * Example: * "(property_key=value)" */ - ServiceTrackerBuilder& setFilter(const std::string& f) { filter = celix::Filter{f}; return *this; } + ServiceTrackerBuilder& setFilter(std::string_view f) { filter = celix::Filter{f}; return *this; } /** * @brief Set filter to be used to matching services. @@ -310,9 +310,9 @@ namespace celix { //NOTE private to prevent move so that a build() call cannot be forgotten MetaTrackerBuilder(MetaTrackerBuilder &&) = default; public: - explicit MetaTrackerBuilder(std::shared_ptr<celix_bundle_context_t> _cCtx, std::string _serviceName) : + explicit MetaTrackerBuilder(std::shared_ptr<celix_bundle_context_t> _cCtx, std::string_view _serviceName) : cCtx{std::move(_cCtx)}, - serviceName{std::move(_serviceName)} + serviceName{_serviceName} {} MetaTrackerBuilder &operator=(MetaTrackerBuilder &&) = delete; diff --git a/libs/framework/include/celix/Trackers.h b/libs/framework/include/celix/Trackers.h index 2e4fc37..85ba4a3 100644 --- a/libs/framework/include/celix/Trackers.h +++ b/libs/framework/include/celix/Trackers.h @@ -216,9 +216,9 @@ namespace celix { */ class GenericServiceTracker : public AbstractTracker { public: - GenericServiceTracker(std::shared_ptr<celix_bundle_context_t> _cCtx, std::string _svcName, - std::string _svcVersionRange, celix::Filter _filter) : AbstractTracker{std::move(_cCtx)}, svcName{std::move(_svcName)}, - svcVersionRange{std::move(_svcVersionRange)}, filter{std::move(_filter)} { + GenericServiceTracker(std::shared_ptr<celix_bundle_context_t> _cCtx, std::string_view _svcName, + std::string_view _svcVersionRange, celix::Filter _filter) : AbstractTracker{std::move(_cCtx)}, svcName{_svcName}, + svcVersionRange{_svcVersionRange}, filter{std::move(_filter)} { opts.trackerCreatedCallbackData = this; opts.trackerCreatedCallback = [](void *data) { auto* trk = static_cast<GenericServiceTracker*>(data); @@ -250,12 +250,12 @@ namespace celix { /** * @brief The service name tracked by this service tracker. */ - const std::string& getServiceName() const { return svcName; } + std::string_view getServiceName() const { return svcName; } /** * @brief The service version range tracked by this service tracker. */ - const std::string& getServiceRange() const { return svcVersionRange; } + std::string_view getServiceRange() const { return svcVersionRange; } /** * @brief The additional filter for services tracked by this service tracker. @@ -308,8 +308,8 @@ namespace celix { */ static std::shared_ptr<ServiceTracker<I>> create( std::shared_ptr<celix_bundle_context_t> cCtx, - std::string svcName, - std::string svcVersionRange, + std::string_view svcName, + std::string_view svcVersionRange, celix::Filter filter, std::vector<std::function<void(const std::shared_ptr<I>&, const std::shared_ptr<const celix::Properties>&, const std::shared_ptr<const celix::Bundle>&)>> setCallbacks, std::vector<std::function<void(const std::shared_ptr<I>&, const std::shared_ptr<const celix::Properties>&, const std::shared_ptr<const celix::Bundle>&)>> addCallbacks, @@ -318,8 +318,8 @@ namespace celix { auto tracker = std::shared_ptr<ServiceTracker<I>>{ new ServiceTracker<I>{ std::move(cCtx), - std::move(svcName), - std::move(svcVersionRange), + svcName, + svcVersionRange, std::move(filter), std::move(setCallbacks), std::move(addCallbacks), @@ -381,12 +381,12 @@ namespace celix { std::shared_ptr<const celix::Bundle> owner; }; - ServiceTracker(std::shared_ptr<celix_bundle_context_t> _cCtx, std::string _svcName, - std::string _svcVersionRange, celix::Filter _filter, + ServiceTracker(std::shared_ptr<celix_bundle_context_t> _cCtx, std::string_view _svcName, + std::string_view _svcVersionRange, celix::Filter _filter, std::vector<std::function<void(const std::shared_ptr<I>&, const std::shared_ptr<const celix::Properties>&, const std::shared_ptr<const celix::Bundle>&)>> _setCallbacks, std::vector<std::function<void(const std::shared_ptr<I>&, const std::shared_ptr<const celix::Properties>&, const std::shared_ptr<const celix::Bundle>&)>> _addCallbacks, std::vector<std::function<void(const std::shared_ptr<I>&, const std::shared_ptr<const celix::Properties>&, const std::shared_ptr<const celix::Bundle>&)>> _remCallbacks) : - GenericServiceTracker{std::move(_cCtx), std::move(_svcName), std::move(_svcVersionRange), std::move(_filter)}, + GenericServiceTracker{std::move(_cCtx), _svcName, _svcVersionRange, std::move(_filter)}, setCallbacks{std::move(_setCallbacks)}, addCallbacks{std::move(_addCallbacks)}, remCallbacks{std::move(_remCallbacks)} { @@ -696,14 +696,14 @@ namespace celix { */ static std::shared_ptr<MetaTracker> create( std::shared_ptr<celix_bundle_context_t> cCtx, - std::string serviceName, + std::string_view serviceName, std::vector<std::function<void(const ServiceTrackerInfo&)>> onTrackerCreated, std::vector<std::function<void(const ServiceTrackerInfo&)>> onTrackerDestroyed) { auto tracker = std::shared_ptr<MetaTracker>{ new MetaTracker{ std::move(cCtx), - std::move(serviceName), + serviceName, std::move(onTrackerCreated), std::move(onTrackerDestroyed)}, AbstractTracker::delCallback<MetaTracker>()}; @@ -753,11 +753,11 @@ namespace celix { private: MetaTracker( std::shared_ptr<celix_bundle_context_t> _cCtx, - std::string _serviceName, + std::string_view _serviceName, std::vector<std::function<void(const ServiceTrackerInfo&)>> _onTrackerCreated, std::vector<std::function<void(const ServiceTrackerInfo&)>> _onTrackerDestroyed) : AbstractTracker{std::move(_cCtx)}, - serviceName{std::move(_serviceName)}, + serviceName{_serviceName}, onTrackerCreated{std::move(_onTrackerCreated)}, onTrackerDestroyed{std::move(_onTrackerDestroyed)} {} diff --git a/libs/framework/include/celix/UseServiceBuilder.h b/libs/framework/include/celix/UseServiceBuilder.h index c504cfd..f6c6d11 100644 --- a/libs/framework/include/celix/UseServiceBuilder.h +++ b/libs/framework/include/celix/UseServiceBuilder.h @@ -54,9 +54,9 @@ namespace celix { //NOTE private to prevent move so that a build() call cannot be forgotten UseServiceBuilder(UseServiceBuilder&&) noexcept = default; public: - explicit UseServiceBuilder(std::shared_ptr<celix_bundle_context_t> _cCtx, std::string _name, bool _useSingleService = true) : + explicit UseServiceBuilder(std::shared_ptr<celix_bundle_context_t> _cCtx, std::string_view _name, bool _useSingleService = true) : cCtx{std::move(_cCtx)}, - name{std::move(_name)}, + name{_name}, useSingleService{_useSingleService} { } @@ -71,7 +71,7 @@ namespace celix { * Example: * "(property_key=value)" */ - UseServiceBuilder& setFilter(const std::string& f) { filter = celix::Filter{f}; return *this; } + UseServiceBuilder& setFilter(std::string_view f) { filter = celix::Filter{f}; return *this; } /** * @brief Set filter to be used to matching services. diff --git a/libs/utils/gtest/src/CxxPropertiesTestSuite.cc b/libs/utils/gtest/src/CxxPropertiesTestSuite.cc index 060562b..01241b9 100644 --- a/libs/utils/gtest/src/CxxPropertiesTestSuite.cc +++ b/libs/utils/gtest/src/CxxPropertiesTestSuite.cc @@ -144,4 +144,22 @@ TEST_F(CxxPropertiesTestSuite, testStringView) { EXPECT_EQ(true, props.getAsBool(key, false)); } } + +TEST_F(CxxPropertiesTestSuite, testUseOfConstexprInSetMethod) { + celix::Properties props{}; + + //Test if different bool "types" are correctly handled + props.set("key1", true); + props.set<const bool>("key2", false); + props.set<const bool&>("key3", 1); + props.set<bool&&>("key4", 0); + props.set<volatile bool&&>("key5", true); + EXPECT_EQ(5, props.size()); + + EXPECT_EQ(props.getAsBool("key1", false), true); + EXPECT_EQ(props.get("key2"), "false"); + EXPECT_EQ(props.get("key3"), "true"); + EXPECT_EQ(props.get("key4"), "false"); + EXPECT_EQ(props.get("key5"), "true"); +} #endif diff --git a/libs/utils/gtest/src/CxxUtilsTestSuite.cc b/libs/utils/gtest/src/CxxUtilsTestSuite.cc index b98a5b0..11f21e9 100644 --- a/libs/utils/gtest/src/CxxUtilsTestSuite.cc +++ b/libs/utils/gtest/src/CxxUtilsTestSuite.cc @@ -103,11 +103,19 @@ TEST_F(CxxUtilsTestSuite, testSplit) { EXPECT_EQ(tokens[1], "item2"); EXPECT_EQ(tokens[2], "item3"); - tokens = celix::split(" item1 , item2 , item3 "); - ASSERT_EQ(tokens.size(), 3); + tokens = celix::split(" item1 , item2 , item3,item4 "); + ASSERT_EQ(tokens.size(), 4); + EXPECT_EQ(tokens[0], "item1"); + EXPECT_EQ(tokens[1], "item2"); + EXPECT_EQ(tokens[2], "item3"); + EXPECT_EQ(tokens[3], "item4"); + + tokens = celix::split(" item1 ; item2 ; item3;item4 ", ";"); + ASSERT_EQ(tokens.size(), 4); EXPECT_EQ(tokens[0], "item1"); EXPECT_EQ(tokens[1], "item2"); EXPECT_EQ(tokens[2], "item3"); + EXPECT_EQ(tokens[3], "item4"); tokens = celix::split(" item1 , "); ASSERT_EQ(tokens.size(), 1); diff --git a/libs/utils/include/celix/Filter.h b/libs/utils/include/celix/Filter.h index 1157b91..5d60ba9 100644 --- a/libs/utils/include/celix/Filter.h +++ b/libs/utils/include/celix/Filter.h @@ -53,12 +53,13 @@ namespace celix { * "(!(cn=Tim Howes))" * "(&(" + celix::Constants::SERVICE_NAME + "=Person)(|(sn=Jensen)(cn=Babs J*)))" * + * @note Provided `const char*` and `std::string_view` values must be null terminated strings. * @note Not thread safe. */ class Filter { public: Filter() : cFilter{createFilter("")} {} - explicit Filter(const std::string& filterStr) : cFilter{createFilter(filterStr)} {} + explicit Filter(std::string_view filterStr) : cFilter{createFilter(filterStr)} {} Filter(Filter&&) = default; Filter& operator=(Filter&&) = default; @@ -83,9 +84,9 @@ namespace celix { /** * @brief Gets the filter string */ - [[nodiscard]] std::string getFilterString() const { + [[nodiscard]] std::string_view getFilterString() const { auto cStr = getFilterCString(); - return cStr == nullptr ? std::string{} : std::string{cStr}; + return cStr == nullptr ? std::string_view{} : std::string_view{cStr}; } /** @@ -106,9 +107,9 @@ namespace celix { * @brief Find the attribute based on the provided key. * @return The found attribute value or an empty string if the attribute was not found. */ - [[nodiscard]] std::string findAttribute(const std::string& attributeKey) const { - auto* cValue = celix_filter_findAttribute(cFilter.get(), attributeKey.c_str()); - return cValue == nullptr ? std::string{} : std::string{cValue}; + [[nodiscard]] std::string_view findAttribute(std::string_view attributeKey) const { + auto* cValue = celix_filter_findAttribute(cFilter.get(), attributeKey.data()); + return cValue == nullptr ? std::string_view{} : std::string_view{cValue}; } /** @@ -135,13 +136,13 @@ namespace celix { return cFilter == nullptr; } private: - static std::shared_ptr<celix_filter_t> createFilter(const std::string& filterStr) { + static std::shared_ptr<celix_filter_t> createFilter(std::string_view filterStr) { if (filterStr.empty()) { return nullptr; } - auto* cf = celix_filter_create(filterStr.c_str()); + auto* cf = celix_filter_create(filterStr.data()); if (cf == nullptr) { - throw celix::FilterException{"Invalid LDAP filter '" + filterStr + "'"}; + throw celix::FilterException{"Invalid LDAP filter '" + std::string{filterStr} + "'"}; } return std::shared_ptr<celix_filter_t>{cf, [](celix_filter_t *f) { celix_filter_destroy(f); diff --git a/libs/utils/include/celix/Properties.h b/libs/utils/include/celix/Properties.h index 0d00cd2..123fa93 100644 --- a/libs/utils/include/celix/Properties.h +++ b/libs/utils/include/celix/Properties.h @@ -95,6 +95,8 @@ namespace celix { /** * @brief A collection of strings key values mainly used as meta data for registered services. + * + * @note Provided `const char*` and `std::string_view` values must be null terminated strings. * @note Not thread safe. */ class Properties { @@ -103,10 +105,18 @@ namespace celix { class ValueRef { public: +#if __cplusplus >= 201703L //C++17 or higher + ValueRef(std::shared_ptr<celix_properties_t> _props, std::string_view _key) : props{std::move(_props)}, stringKey{}, charKey{_key.data()} {} +#else ValueRef(std::shared_ptr<celix_properties_t> _props, std::string _key) : props{std::move(_props)}, stringKey{std::move(_key)}, charKey{nullptr} {} - +#endif ValueRef(std::shared_ptr<celix_properties_t> _props, const char* _key) : props{std::move(_props)}, stringKey{}, charKey{_key} {} + ValueRef(const ValueRef&) = default; + ValueRef(ValueRef&&) = default; + ValueRef& operator=(const ValueRef&) = default; + ValueRef& operator=(ValueRef&&) = default; + #if __cplusplus >= 201703L //C++17 or higher ValueRef& operator=(std::string_view value) { if (charKey == nullptr) { @@ -164,13 +174,13 @@ namespace celix { #if __cplusplus >= 201703L //C++17 or higher Properties(std::initializer_list<std::pair<std::string_view, std::string_view>> list) : cProps{celix_properties_create(), [](celix_properties_t* p) { celix_properties_destroy(p); }} { for(auto &entry : list) { - celix_properties_set(cProps.get(), entry.first.data(), entry.second.data()); + set(entry.first, entry.second); } } #else Properties(std::initializer_list<std::pair<std::string, std::string>> list) : cProps{celix_properties_create(), [](celix_properties_t* p) { celix_properties_destroy(p); }} { for(auto &entry : list) { - celix_properties_set(cProps.get(), entry.first.c_str(), entry.second.c_str()); + set(entry.first, entry.second); } } #endif @@ -198,14 +208,14 @@ namespace celix { * @brief Get the value for a property key */ ValueRef operator[](std::string_view key) { - return ValueRef{cProps, key.data()}; + return ValueRef{cProps, key}; } /** * @brief Get the value for a property key */ ValueRef operator[](std::string_view key) const { - return ValueRef{cProps, key.data()}; + return ValueRef{cProps, key}; } #else /** @@ -285,41 +295,19 @@ namespace celix { return celix_properties_getAsBool(cProps.get(), key.data(), defaultValue); } - /** - * @brief Sets a property - */ - void set(std::string_view key, std::string_view value) { - celix_properties_set(cProps.get(), key.data(), value.data()); - } - - /** - * @brief Sets a property - */ - void set(std::string_view key, std::string value) { - celix_properties_set(cProps.get(), key.data(), value.data()); - } - - /** - * @brief Sets a property - */ - void set(std::string_view key, const char* value) { - celix_properties_set(cProps.get(), key.data(), value); - } - - /** - * @brief Sets a bool property - */ - void set(std::string_view key, bool value) { - celix_properties_setBool(cProps.get(), key.data(), value); - } - - /** - * @brief Sets a T property. Will use std::to_string to convert the value to string. - */ template<typename T> - void set(std::string_view key, T value) { - using namespace std; - celix_properties_set(cProps.get(), key.data(), to_string(value).c_str()); + void set(std::string_view key, T&& value) { + if constexpr (std::is_same_v<std::decay_t<T>, bool>) { + celix_properties_setBool(cProps.get(), key.data(), value); + } else if constexpr (std::is_same_v<std::decay_t<T>, std::string_view>) { + celix_properties_set(cProps.get(), key.data(), value.data()); + } else if constexpr (std::is_convertible_v<T, std::string_view>) { + std::string_view view{value}; + celix_properties_set(cProps.get(), key.data(), view.data()); + } else { + using namespace std; + celix_properties_set(cProps.get(), key.data(), to_string(value).c_str()); + } } #else /** diff --git a/libs/utils/include/celix/Utils.h b/libs/utils/include/celix/Utils.h index 205360d..aae33bc 100644 --- a/libs/utils/include/celix/Utils.h +++ b/libs/utils/include/celix/Utils.h @@ -150,9 +150,9 @@ namespace celix { * celix::impl::typeName uses the macro __PRETTY_FUNCTION__ to extract a type name. */ template<typename I> - std::string typeName(const std::string& providedTypeName = "") { + std::string typeName(std::string_view providedTypeName = "") { if (!providedTypeName.empty()) { - return providedTypeName; + return std::string{providedTypeName}; } else if constexpr (celix::impl::hasStaticMemberName<I>) { return std::string{I::NAME}; } else { @@ -169,9 +169,9 @@ namespace celix { * Otherwise a empty string will be returned. */ template<typename I> - std::string typeVersion(const std::string& providedVersion = "") { + std::string typeVersion(std::string_view providedVersion = "") { if (!providedVersion.empty()) { - return providedVersion; + return std::string{providedVersion}; } else if constexpr (celix::impl::hasStaticMemberVersion<I>) { return std::string{I::VERSION}; } else { @@ -186,13 +186,13 @@ namespace celix { * @param str The string to split * @param delimiter The delimiter to use (default ",") */ - inline std::vector<std::string> split(const std::string& str, const std::string& delimiter = ",") { + inline std::vector<std::string> split(std::string_view str, std::string_view delimiter = ",") { std::vector<std::string> result{}; - std::string delimiters = delimiter + " \t"; + std::string delimiters = std::string{delimiter} + " \t"; size_t found; size_t pos = 0; while ((found = str.find_first_not_of(delimiters, pos)) != std::string::npos) { - pos = str.find_first_of(", ", found); + pos = str.find_first_of(delimiters, found); result.emplace_back(str.substr(found, pos - found)); } return result;
