This is an automated email from the ASF dual-hosted git repository. pnoltes pushed a commit to branch feature/type_support_for_properties in repository https://gitbox.apache.org/repos/asf/celix.git
commit efb74c19a30c51ad14f4c1a0a50ce5ce31208030 Author: Pepijn Noltes <[email protected]> AuthorDate: Sun Jan 8 16:32:54 2023 +0100 Fix Properties implementation for C++11 and C++14. --- libs/utils/gtest/src/VersionTestSuite.cc | 6 -- libs/utils/include/celix/Properties.h | 102 ++++++++++++++++++++++++------- libs/utils/include/celix/Version.h | 67 +++++++++++++++++--- libs/utils/include/celix_version.h | 11 ++++ 4 files changed, 149 insertions(+), 37 deletions(-) diff --git a/libs/utils/gtest/src/VersionTestSuite.cc b/libs/utils/gtest/src/VersionTestSuite.cc index 54539c7b..5707e427 100644 --- a/libs/utils/gtest/src/VersionTestSuite.cc +++ b/libs/utils/gtest/src/VersionTestSuite.cc @@ -150,8 +150,6 @@ TEST_F(VersionTestSuite, CreateEmptyVersionTest) { } TEST_F(VersionTestSuite, CompareTest) { - //TODO update to updated API - celix_version_t* version = nullptr; celix_version_t* compare = nullptr; celix_status_t status = CELIX_SUCCESS; @@ -227,8 +225,6 @@ TEST_F(VersionTestSuite, CompareToMajorMinorTest) { } TEST_F(VersionTestSuite, ToStringTest) { - //TODO update to updated API - celix_version_t* version = nullptr; celix_status_t status = CELIX_SUCCESS; char * str; @@ -262,8 +258,6 @@ TEST_F(VersionTestSuite, ToStringTest) { } TEST_F(VersionTestSuite, SemanticCompatibilityTest) { - //TODO update to updated API - celix_version_t* provider = nullptr; celix_version_t* compatible_user = nullptr; celix_version_t* incompatible_user_by_major = nullptr; diff --git a/libs/utils/include/celix/Properties.h b/libs/utils/include/celix/Properties.h index 5be5a762..e451ddc1 100644 --- a/libs/utils/include/celix/Properties.h +++ b/libs/utils/include/celix/Properties.h @@ -23,6 +23,12 @@ #include <unordered_map> #include <memory> #include <string> +#if __cplusplus >= 201703L //C++17 or higher +#include <string_view> +#else +#include <type_traits> +#endif + #include "celix_properties.h" #include "celix_utils.h" @@ -31,6 +37,48 @@ namespace celix { + +#if __cplusplus < 201703L //lower than C++17 + template<typename T> + struct IsIntegralDoubleBoolOrVersion : std::false_type {}; + + template <> + struct IsIntegralDoubleBoolOrVersion<char> : std::true_type {}; + + template <> + struct IsIntegralDoubleBoolOrVersion<unsigned char> : std::true_type {}; + + template <> + struct IsIntegralDoubleBoolOrVersion<short> : std::true_type {}; + + template <> + struct IsIntegralDoubleBoolOrVersion<unsigned short> : std::true_type {}; + + template <> + struct IsIntegralDoubleBoolOrVersion<int> : std::true_type {}; + + template <> + struct IsIntegralDoubleBoolOrVersion<long> : std::true_type {}; + + template <> + struct IsIntegralDoubleBoolOrVersion<unsigned int> : std::true_type {}; + + template<> + struct IsIntegralDoubleBoolOrVersion<double> : std::true_type {}; + + template<> + struct IsIntegralDoubleBoolOrVersion<float> : std::true_type {}; + + template<> + struct IsIntegralDoubleBoolOrVersion<bool> : std::true_type {}; + + template<> + struct IsIntegralDoubleBoolOrVersion<celix::Version> : std::true_type {}; + + template<> + struct IsIntegralDoubleBoolOrVersion<celix_version_t*> : std::true_type {}; +#endif + /** * @brief A iterator for celix::Properties. */ @@ -431,7 +479,7 @@ namespace celix { [[nodiscard]] bool getAsBool(const std::string &key, bool defaultValue) const { return celix_properties_getAsBool(cProps.get(), key.c_str(), defaultValue); } - + /** * @brief Get the value of the property with key as a Celix version. * @@ -454,7 +502,7 @@ namespace celix { celix_version_destroy(cVersion); return version; } - return defaultValue + return defaultValue; } /** @@ -478,16 +526,6 @@ namespace celix { celix_properties_set(cProps.get(), key.data(), value.c_str()); } - /** - * @brief Set the value of a property to a boolean. - * - * @param[in] key The key of the property to set. - * @param[in] value The boolean value to set the property to. - */ - void set(const std::string& key, bool value) { - celix_properties_setBool(cProps.get(), key.data(), value); - } - /** * @brief Set the value of a property. * @@ -509,9 +547,21 @@ namespace celix { * @param[in] value The value to set for the property. */ template<typename T> - void set(const std::string& key, T&& value) { + typename std::enable_if<!celix::IsIntegralDoubleBoolOrVersion<T>::value, void>::type + set(const std::string& key, T&& value) { + std::cout << "Setting with T&&" << std::endl; using namespace std; - celix_properties_set(cProps.get(), key.data()(), to_string(value).c_str()); + celix_properties_set(cProps.get(), key.data(), to_string(value).c_str()); + } + + /** + * @brief Sets a celix::Version property value for a given key. + * + * @param[in] key The key of the property to set. + * @param[in] value The value to set for the property. + */ + void set(const std::string& key, celix::Version&& value) { + celix_properties_setVersion(cProps.get(), key.data(), value.getCVersion()); } /** @@ -535,23 +585,33 @@ namespace celix { } /** - * @brief Sets a double property value for a given key. + * @brief Sets a long property value for a given key. * * @param[in] key The key of the property to set. * @param[in] value The value to set for the property. */ - void set(const std::string& key, double value) { - celix_properties_setDouble(cProps.get(), key.data(), value); + void set(const std::string& key, int value) { + celix_properties_setLong(cProps.get(), key.data(), value); } /** - * @brief Sets a celix::Version property value for a given key. + * @brief Sets a long property value for a given key. * * @param[in] key The key of the property to set. * @param[in] value The value to set for the property. */ - void set(const std::string& key, const celix::Version& value) { - celix_properties_setVersion(cProps.get(), key.data(), value.getCVersion()); + void set(const std::string& key, unsigned int value) { + celix_properties_setLong(cProps.get(), key.data(), value); + } + + /** + * @brief Sets a double property value for a given key. + * + * @param[in] key The key of the property to set. + * @param[in] value The value to set for the property. + */ + void set(const std::string& key, double value) { + celix_properties_setDouble(cProps.get(), key.data(), value); } /** @@ -643,7 +703,7 @@ namespace celix { private: Properties(celix_properties_t* props, bool takeOwnership) : - cProps{props, [ownership = takeOwnership](celix_properties_t* p){ if (ownership) { celix_properties_destroy(p); }}} {} + cProps{props, [takeOwnership](celix_properties_t* p){ if (takeOwnership) { celix_properties_destroy(p); }}} {} static celix::Properties::ValueType getAndConvertType( const std::shared_ptr<celix_properties_t>& cProperties, diff --git a/libs/utils/include/celix/Version.h b/libs/utils/include/celix/Version.h index c8d2943d..556f4e92 100644 --- a/libs/utils/include/celix/Version.h +++ b/libs/utils/include/celix/Version.h @@ -26,14 +26,34 @@ namespace celix { - //TODO doxygen + /** + * @class Version + * @brief Class for storing and manipulating version information. + * + * The Version class represents a version number that follows the Semantic Versioning specification (SemVer). + * It consists of three non-negative integers for the major, minor, and micro version, and an optional string for + * the qualifier. + * The Version class provides comparison operators and functions for getting the individual version components. + * + * @note This class is a thin wrapper around the C API defined in celix_version.h. + */ class Version { public: + + ///@brief Constructs a new empty version with all components set to zero. Version() : cVersion{createVersion(celix_version_createEmptyVersion())}, qualifier{celix_version_getQualifier(cVersion.get())} {} #if __cplusplus >= 201703L //C++17 or higher + + /** + * @brief Constructs a new version with the given components and qualifier. + * @param major The major component of the version. + * @param minor The minor component of the version. + * @param micro The micro component of the version. + * @param qualifier The qualifier string of the version. + */ Version(int major, int minor, int micro, std::string_view qualifier = {}) : cVersion{createVersion(celix_version_create(major, minor, micro, qualifier.empty() ? "" : qualifier.data()))}, qualifier{celix_version_getQualifier(cVersion.get())} {} @@ -43,26 +63,31 @@ namespace celix { qualifier{celix_version_getQualifier(cVersion.get())} {} #endif - + ///@brief Move-constructs a new version from an existing one. Version(Version&&) = default; + + ///@brief Copy constructor for a Celix Version object. Version(const Version& rhs) = default; + ///@brief Move assignment operator for the Celix Version class. Version& operator=(Version&&) = default; + + ///@brief Copy assignment operator for the Celix Version class. Version& operator=(const Version& rhs) = default; + ///@brief Test whether two Version objects are equal. bool operator==(const Version& rhs) const { return celix_version_compareTo(cVersion.get(), rhs.cVersion.get()) == 0; } + ///@brief Overload the < operator to compare two Version objects. bool operator<(const Version& rhs) const { return celix_version_compareTo(cVersion.get(), rhs.cVersion.get()) < 0; } - //TODO rest of the operators, is that needed? - /** - * @brief Warps a C Celix Version to a C++ Celix Version, but takes no ownership. - * Dealloction is still the responsibility of the caller. + * @brief Warp a C Celix Version to a C++ Celix Version, but takes no ownership. + * De-allocation is still the responsibility of the caller. */ static Version wrap(celix_version_t* v) { return Version{v}; @@ -78,22 +103,38 @@ namespace celix { return cVersion.get(); } - //TODO doc + /** + * @brief Get the major component of the version. + * The major component designates the primary release. + * @return The major component of the version. + */ [[nodiscard]] int getMajor() const { return celix_version_getMajor(cVersion.get()); } - //TODO doc + /** + * @brief Get the minor component of the version. + * The minor component designates a new or improved feature. + * @return The minor component of the version. + */ [[nodiscard]] int getMinor() const { return celix_version_getMinor(cVersion.get()); } - //TODO doc + /** + * @brief Get the micro component of the version. + * The micro component designates a bug fix. + * @return The micro component of the version. + */ [[nodiscard]] int getMicro() const { return celix_version_getMicro(cVersion.get()); } - //TODO doc + /** + * @brief Get the qualifier component of the version. + * The qualifier component designates additional information about the version. + * @return The qualifier component of the version. + */ [[nodiscard]] const std::string& getQualifier() const { return qualifier; } @@ -117,6 +158,12 @@ namespace celix { } namespace std { + + /** + * @brief The hash celix::Version struct provides a std::hash compatible hashing function for the celix::Version + * class. This allows celix::Version objects to be used as keys in std::unordered_map and std::unordered_set. + * @see std::hash + */ template<> struct hash<celix::Version> { size_t operator()(const celix::Version& v) const { diff --git a/libs/utils/include/celix_version.h b/libs/utils/include/celix_version.h index f4cea390..c539dd56 100644 --- a/libs/utils/include/celix_version.h +++ b/libs/utils/include/celix_version.h @@ -26,6 +26,17 @@ extern "C" { #include <stdbool.h> + +/** + * @file celix_version.h + * @brief Header file for the Celix Version API. + * + * The Celix Version API provides a means for storing and manipulating version information, which consists of + * three non-negative integers for the major, minor, and micro version, and an optional string for the qualifier. + * This implementation is based on the Semantic Versioning specification (SemVer). + * Functions are provided for creating and destroying version objects, comparing versions, and extracting the individual version components. + */ + /** * @brief The definition of the celix_version_t* abstract data type. */
