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;

Reply via email to