diff --git a/iceoryx_hoofs/include/iceoryx_hoofs/cxx/string.hpp b/iceoryx_hoofs/include/iceoryx_hoofs/cxx/string.hpp index a7c18e1f69..120866b0b7 100644 --- a/iceoryx_hoofs/include/iceoryx_hoofs/cxx/string.hpp +++ b/iceoryx_hoofs/include/iceoryx_hoofs/cxx/string.hpp @@ -30,20 +30,22 @@ namespace iox { namespace cxx { +// AXIVION DISABLE STYLE AutosarC++19_03-A18.1.1 : C-array type usage is intentional + template using IsStringOrCharArrayOrChar = - typename std::enable_if<(is_cxx_string::value || is_char_array::value || std::is_same::value - || std::is_same::value), + typename std::enable_if<((is_cxx_string::value || is_char_array::value) + || (std::is_same::value || std::is_same::value)), ReturnType>::type; template -using IsStringOrCharArray = - typename std::enable_if<(is_cxx_string::value || is_char_array::value || std::is_same::value), - ReturnType>::type; +using IsStringOrCharArray = typename std::enable_if<((is_cxx_string::value || is_char_array::value) + || std::is_same::value), + ReturnType>::type; template using IsStdStringOrCharArrayOrChar = - typename std::enable_if<(is_char_array::value || std::is_same::value + typename std::enable_if<((is_char_array::value || std::is_same::value) || std::is_same::value), ReturnType>::type; @@ -53,8 +55,8 @@ using IsCxxStringOrCharArray = template using IsCxxStringOrCharArrayOrChar = - typename std::enable_if<(is_char_array::value || is_cxx_string::value || std::is_same::value) - && (is_char_array::value || is_cxx_string::value + typename std::enable_if<((is_char_array::value || is_cxx_string::value) || std::is_same::value) + && ((is_char_array::value || is_cxx_string::value) || std::is_same::value), ReturnType>::type; @@ -62,8 +64,8 @@ template using IsCxxStringAndCxxStringOrCharArrayOrChar = typename std::enable_if<((is_char_array::value || std::is_same::value) && is_cxx_string::value) || (is_cxx_string::value - && (is_char_array::value || std::is_same::value)) - || (is_cxx_string::value && is_cxx_string::value), + && ((is_char_array::value || std::is_same::value) + || (is_cxx_string::value && is_cxx_string::value))), ReturnType>::type; /// @brief concatenates two iox::cxx::strings/string literals/chars @@ -94,6 +96,8 @@ template IsCxxStringOrCharArrayOrChar::value>> concatenate(const T1& str1, const T2& str2, const Targs&... targs) noexcept; +// AXIVION Next Construct AutosarC++19_03-M17.0.3 : operator+ is defined within iox::cxx namespace which prevents easy +// misuse /// @brief concatenates two iox::cxx::strings or one iox::cxx::string and one string literal/char; concatenation of two /// string literals/chars is not possible /// @@ -115,7 +119,7 @@ constexpr TruncateToCapacity_t TruncateToCapacity{}; /// @brief string implementation with some adjustments in the API, because we are not allowed to throw exceptions or use /// heap. template -class string +class string final { static_assert(Capacity > 0U, "The capacity of the fixed string must be greater than 0!"); @@ -359,54 +363,6 @@ class string template IsStringOrCharArray compare(const T& other) const noexcept; - /// @brief checks if self is equal to rhs - /// - /// @param [in] rhs is the iox::cxx::string, std::string, char array or char to compare with self - /// - /// @return true if both strings are equal, otherwise false - template - IsStringOrCharArrayOrChar operator==(const T& rhs) const noexcept; - - /// @brief checks if self is not equal to rhs - /// - /// @param [in] rhs is the iox::cxx::string, std::string, char array or char to compare with self - /// - /// @return true if both strings are not equal, otherwise false - template - IsStringOrCharArrayOrChar operator!=(const T& rhs) const noexcept; - - /// @brief checks if self is less than rhs, in lexicographical order - /// - /// @param [in] rhs is the iox::cxx::string, std::string, char array or char to compare with self - /// - /// @return true if self is less than rhs, otherwise false - template - IsStringOrCharArrayOrChar operator<(const T& rhs) const noexcept; - - /// @brief checks if self is less than or equal to rhs, in lexicographical order - /// - /// @param [in] rhs is the iox::cxx::string, std::string, char array or char to compare with self - /// - /// @return true if self is less than or equal to rhs, otherwise false - template - IsStringOrCharArrayOrChar operator<=(const T& rhs) const noexcept; - - /// @brief checks if self is greater than rhs, in lexicographical order - /// - /// @param [in] rhs is the iox::cxx::string, std::string, char array or char to compare with self - /// - /// @return true if self is greater than rhs, otherwise false - template - IsStringOrCharArrayOrChar operator>(const T& rhs) const noexcept; - - /// @brief checks if self is greater than or equal to rhs, in lexicographical order - /// - /// @param [in] rhs is the iox::cxx::string, std::string, char array or char to compare with self - /// - /// @return true if self is greater than or equal to rhs, otherwise false - template - IsStringOrCharArrayOrChar operator>=(const T& rhs) const noexcept; - /// @brief compares self and a char /// /// @param [in] other is the char to compare with self @@ -441,10 +397,14 @@ class string /// @brief clears the content of the string constexpr void clear() noexcept; + // AXIVION Next Construct AutosarC++19_03-A13.5.2 , AutosarC++19_03-A13.5.3: used for interoperability with + // std::string /// @brief converts the string to a std::string /// /// @return a std::string with data equivalent to those stored in the string - // NOLINTNEXTLINE(hicpp-explicit-conversions) @todo iox-#260 remove this conversion and implement toStdString method + + // @todo iox-#260 remove this conversion and implement toStdString method + // NOLINTNEXTLINE(hicpp-explicit-conversions) operator std::string() const noexcept; /// @brief since there are two valid options for what should happen when appending a string larger than this' @@ -585,7 +545,7 @@ class string template friend IsCxxStringOrCharArrayOrChar::value>> - concatenate(const T1& t1, const T2& t2) noexcept; + concatenate(const T1& str1, const T2& str2) noexcept; private: /// @brief copies rhs fixed string to this with compile time check whether rhs capacity is less than or equal to @@ -612,6 +572,17 @@ class string uint64_t m_rawstringSize{0U}; }; +/// @brief outputs the fixed string on stream +/// +/// @param [in] stream is the output stream +/// @param [in] str is the fixed string +/// +/// @return the stream output of the fixed string +template +inline std::ostream& operator<<(std::ostream& stream, const string& str) noexcept; + +// AXIVION DISABLE STYLE AutosarC++19_03-A13.5.5: Comparison with std::string, char array or +// char is also intended /// @brief checks if a lhs std::string, char array or char is equal to a rhs iox::cxx::string /// /// @param [in] rhs is the iox::cxx::string @@ -665,14 +636,62 @@ IsStdStringOrCharArrayOrChar operator>(const T& lhs, const string IsStdStringOrCharArrayOrChar operator>=(const T& lhs, const string& rhs) noexcept; -/// @brief outputs the fixed string on stream +/// @brief checks if lhs is equal to rhs /// -/// @param [in] stream is the output stream -/// @param [in] str is the fixed string +/// @param [in] lhs is the iox::cxx::string +/// @param [in] rhs is the iox::cxx::string, std::string, char array or char to compare with lhs /// -/// @return the stream output of the fixed string -template -inline std::ostream& operator<<(std::ostream& stream, const string& str) noexcept; +/// @return true if both strings are equal, otherwise false +template +IsStringOrCharArrayOrChar operator==(const string& lhs, const T& rhs) noexcept; + +/// @brief checks if lhs is not equal to rhs +/// +/// @param [in] lhs is the iox::cxx::string +/// @param [in] rhs is the iox::cxx::string, std::string, char array or char to compare with lhs +/// +/// @return true if both strings are not equal, otherwise false +template +IsStringOrCharArrayOrChar operator!=(const string& lhs, const T& rhs) noexcept; + +/// @brief checks if lhs is less than rhs, in lexicographical order +/// +/// @param [in] lhs is the iox::cxx::string +/// @param [in] rhs is the iox::cxx::string, std::string, char array or char to compare with lhs +/// +/// @return true if lhs is less than rhs, otherwise false +template +IsStringOrCharArrayOrChar operator<(const string& lhs, const T& rhs) noexcept; + +/// @brief checks if lhs is less than or equal to rhs, in lexicographical order +/// +/// @param [in] lhs is the iox::cxx::string +/// @param [in] rhs is the iox::cxx::string, std::string, char array or char to compare with lhs +/// +/// @return true if lhs is less than or equal to rhs, otherwise false +template +IsStringOrCharArrayOrChar operator<=(const string& lhs, const T& rhs) noexcept; + +/// @brief checks if lhs is greater than rhs, in lexicographical order +/// +/// @param [in] lhs is the iox::cxx::string +/// @param [in] rhs is the iox::cxx::string, std::string, char array or char to compare with lhs +/// +/// @return true if lhs is greater than rhs, otherwise false +template +IsStringOrCharArrayOrChar operator>(const string& lhs, const T& rhs) noexcept; + +/// @brief checks if lhs is greater than or equal to rhs, in lexicographical order +/// +/// @param [in] lhs is the iox::cxx::string +/// @param [in] rhs is the iox::cxx::string, std::string, char array or char to compare with lhs +/// +/// @return true if lhs is greater than or equal to rhs, otherwise false +template +IsStringOrCharArrayOrChar operator>=(const string& lhs, const T& rhs) noexcept; +// AXIVION ENABLE STYLE AutosarC++19_03-A13.5.5 +// AXIVION ENABLE STYLE AutosarC++19_03-A18.1.1 + } // namespace cxx } // namespace iox #include "iceoryx_hoofs/internal/cxx/string.inl" diff --git a/iceoryx_hoofs/include/iceoryx_hoofs/internal/cxx/string.inl b/iceoryx_hoofs/include/iceoryx_hoofs/internal/cxx/string.inl index 2ae17b71c6..664936dffd 100644 --- a/iceoryx_hoofs/include/iceoryx_hoofs/internal/cxx/string.inl +++ b/iceoryx_hoofs/include/iceoryx_hoofs/internal/cxx/string.inl @@ -98,6 +98,7 @@ inline string& string::operator=(string&& rhs) noexcept template template +// AXIVION Next Construct AutosarC++19_03-A18.1.1 : C-array type usage is intentional // NOLINTNEXTLINE(hicpp-avoid-c-arrays, cppcoreguidelines-avoid-c-arrays) cxx::string wraps char array inline string::string(const char (&other)[N]) noexcept { @@ -107,8 +108,9 @@ inline string::string(const char (&other)[N]) noexcept template // NOLINTNEXTLINE(hicpp-named-parameter, readability-named-parameter) justification in header inline string::string(TruncateToCapacity_t, const char* const other) noexcept - : string( - TruncateToCapacity, other, [&]() -> uint64_t { return (other != nullptr) ? strnlen(other, Capacity) : 0U; }()) + : string(TruncateToCapacity, other, [&other]() -> uint64_t { + return (other != nullptr) ? strnlen(other, Capacity) : 0U; + }()) { } @@ -131,14 +133,18 @@ inline string::string(TruncateToCapacity_t, const char* const other, c } else if (Capacity < count) { -#if defined(__GNUC__) && __GNUC__ == 8 && __GNUC_MINOR__ == 3 +// AXIVION DISABLE STYLE AutosarC++19_03-A16.0.1: conditional compilation is required for setting gcc diagnostics, since +// gcc 8 incorrectly warns here about out of bounds array access +#if (defined(__GNUC__) && (__GNUC__ == 8)) && (__GNUC_MINOR__ == 3) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Warray-bounds" #endif std::memcpy(&(m_rawstring[0]), other, Capacity); -#if defined(__GNUC__) && __GNUC__ == 8 && __GNUC_MINOR__ == 3 +#if (defined(__GNUC__) && (__GNUC__ == 8)) && (__GNUC_MINOR__ == 3) #pragma GCC diagnostic pop #endif + // AXIVION ENABLE STYLE AutosarC++19_03-A16.0.1 + m_rawstring[Capacity] = '\0'; m_rawstringSize = Capacity; std::cerr << "Constructor truncates the last " << count - Capacity << " characters of " << other @@ -154,10 +160,11 @@ inline string::string(TruncateToCapacity_t, const char* const other, c template template +// AXIVION Next Construct AutosarC++19_03-A18.1.1 : C-array type usage is intentional // NOLINTNEXTLINE(hicpp-avoid-c-arrays, cppcoreguidelines-avoid-c-arrays) cxx::string wraps char array inline string& string::operator=(const char (&rhs)[N]) noexcept { - static_assert(N <= Capacity + 1U, + static_assert(N <= (Capacity + 1U), "Assignment failed. The given char array is larger than the capacity of the fixed string."); if (c_str() == rhs) @@ -191,6 +198,7 @@ inline string& string::assign(const string& str) noexcept template template +// AXIVION Next Construct AutosarC++19_03-A18.1.1 : C-array type usage is intentional // NOLINTNEXTLINE(hicpp-avoid-c-arrays, cppcoreguidelines-avoid-c-arrays) cxx::string wraps char array inline string& string::assign(const char (&str)[N]) noexcept { @@ -205,7 +213,7 @@ inline bool string::unsafe_assign(const char* const str) noexcept { return false; } - const uint64_t strSize = strnlen(str, Capacity + 1U); + const uint64_t strSize{strnlen(str, Capacity + 1U)}; if (Capacity < strSize) { std::cerr << "Assignment failed. The given cstring is larger (" << strSize << ") than the capacity (" @@ -221,7 +229,7 @@ inline bool string::unsafe_assign(const char* const str) noexcept template inline bool string::unsafe_assign(const std::string& str) noexcept { - uint64_t strSize = str.size(); + uint64_t strSize{str.size()}; if (Capacity < strSize) { std::cerr << "Assignment failed. The given std::string is larger than the capacity of the fixed string." @@ -238,7 +246,7 @@ template template inline IsStringOrCharArray string::compare(const T& other) const noexcept { - uint64_t otherSize = internal::GetSize::call(other); + uint64_t otherSize{internal::GetSize::call(other)}; auto result = memcmp(c_str(), internal::GetData::call(other), std::min(m_rawstringSize, otherSize)); if (result == 0) { @@ -246,89 +254,11 @@ inline IsStringOrCharArray string::compare(const T& other) { return -1; } - return (m_rawstringSize > otherSize ? 1 : 0); + return ((m_rawstringSize > otherSize) ? 1 : 0); } return result; } -template -template -inline IsStringOrCharArrayOrChar string::operator==(const T& rhs) const noexcept -{ - return (compare(rhs) == 0); -} - -template -template -inline IsStringOrCharArrayOrChar string::operator!=(const T& rhs) const noexcept -{ - return (compare(rhs) != 0); -} - -template -template -inline IsStringOrCharArrayOrChar string::operator<(const T& rhs) const noexcept -{ - return (compare(rhs) < 0); -} - -template -template -inline IsStringOrCharArrayOrChar string::operator<=(const T& rhs) const noexcept -{ - return (compare(rhs) <= 0); -} - -template -template -inline IsStringOrCharArrayOrChar string::operator>(const T& rhs) const noexcept -{ - return (compare(rhs) > 0); -} - -template -template -inline IsStringOrCharArrayOrChar string::operator>=(const T& rhs) const noexcept -{ - return (compare(rhs) >= 0); -} - -template -inline IsStdStringOrCharArrayOrChar operator==(const T& lhs, const string& rhs) noexcept -{ - return (rhs.compare(lhs) == 0); -} - -template -inline IsStdStringOrCharArrayOrChar operator!=(const T& lhs, const string& rhs) noexcept -{ - return (rhs.compare(lhs) != 0); -} - -template -inline IsStdStringOrCharArrayOrChar operator<(const T& lhs, const string& rhs) noexcept -{ - return (rhs.compare(lhs) > 0); -} - -template -inline IsStdStringOrCharArrayOrChar operator<=(const T& lhs, const string& rhs) noexcept -{ - return (rhs.compare(lhs) >= 0); -} - -template -inline IsStdStringOrCharArrayOrChar operator>(const T& lhs, const string& rhs) noexcept -{ - return (rhs.compare(lhs) < 0); -} - -template -inline IsStdStringOrCharArrayOrChar operator>=(const T& lhs, const string& rhs) noexcept -{ - return (rhs.compare(lhs) <= 0); -} - template inline int64_t string::compare(char other) const noexcept { @@ -339,7 +269,7 @@ inline int64_t string::compare(char other) const noexcept { return -1; } - return (m_rawstringSize > 1U ? 1 : 0); + return ((m_rawstringSize > 1U) ? 1L : 0L); } return result; } @@ -387,7 +317,7 @@ inline string& string::copy(const string& rhs) noexcept { static_assert(N <= Capacity, "Assignment failed. The capacity of the given fixed string is larger than the capacity of this."); - uint64_t strSize = rhs.size(); + uint64_t strSize{rhs.size()}; std::memcpy(&(m_rawstring[0]), rhs.c_str(), strSize); m_rawstring[strSize] = '\0'; m_rawstringSize = strSize; @@ -400,7 +330,7 @@ inline string& string::move(string&& rhs) noexcept { static_assert(N <= Capacity, "Assignment failed. The capacity of the given fixed string is larger than the capacity of this."); - uint64_t strSize = rhs.size(); + const uint64_t strSize{rhs.size()}; std::memcpy(&(m_rawstring[0]), rhs.c_str(), strSize); m_rawstring[strSize] = '\0'; m_rawstringSize = strSize; @@ -408,6 +338,8 @@ inline string& string::move(string&& rhs) noexcept return *this; } +// AXIVION Next Construct AutosarC++19_03-M5.17.1: This is not used as shift operator but as stream operator and does +// not require to implement '<<=' template inline std::ostream& operator<<(std::ostream& stream, const string& str) noexcept { @@ -429,8 +361,8 @@ template inline IsCxxStringOrCharArrayOrChar::value>> concatenate(const T1& str1, const T2& str2) noexcept { - uint64_t size1 = internal::GetSize::call(str1); - uint64_t size2 = internal::GetSize::call(str2); + uint64_t size1{internal::GetSize::call(str1)}; + uint64_t size2{internal::GetSize::call(str2)}; using NewStringType = string::value>; NewStringType newString; std::memcpy(&(newString.m_rawstring[0]), internal::GetData::call(str1), size1); @@ -449,6 +381,8 @@ concatenate(const T1& str1, const T2& str2, const Targs&... targs) noexcept } template +// AXIVION Next Construct AutosarC++19_03-M17.0.3 : operator+ is defined within iox::cxx namespace which prevents easy +// misuse inline IsCxxStringAndCxxStringOrCharArrayOrChar::value>> operator+(const T1& str1, const T2& str2) noexcept { @@ -459,9 +393,9 @@ template template inline IsStringOrCharArrayOrChar string::unsafe_append(const T& str) noexcept { - uint64_t tSize = internal::GetSize::call(str); - const char* tData = internal::GetData::call(str); - uint64_t clampedTSize = std::min(Capacity - m_rawstringSize, tSize); + uint64_t tSize{internal::GetSize::call(str)}; + const char* tData{internal::GetData::call(str)}; + uint64_t clampedTSize{std::min(Capacity - m_rawstringSize, tSize)}; if (tSize > clampedTSize) { @@ -482,14 +416,14 @@ template inline IsStringOrCharArrayOrChar&> string::append(TruncateToCapacity_t, const T& str) noexcept { - uint64_t tSize = internal::GetSize::call(str); - const char* tData = internal::GetData::call(str); - uint64_t clampedTSize = std::min(Capacity - m_rawstringSize, tSize); + uint64_t tSize{internal::GetSize::call(str)}; + const char* tData{internal::GetData::call(str)}; + uint64_t clampedTSize{std::min(Capacity - m_rawstringSize, tSize)}; std::memcpy(&(m_rawstring[m_rawstringSize]), tData, clampedTSize); if (tSize > clampedTSize) { - std::cerr << "The last " << tSize - Capacity + m_rawstringSize << " characters of " << tData + std::cerr << "The last " << (tSize - Capacity) + m_rawstringSize << " characters of " << tData << " are truncated, because the length is larger than the capacity." << std::endl; } @@ -523,9 +457,9 @@ string::insert(const uint64_t pos, const T& str, const uint64_t count) { return false; } - const auto new_size = m_rawstringSize + count; + const uint64_t new_size{m_rawstringSize + count}; // check if the new size would exceed capacity or a size overflow occured - if (new_size > Capacity || new_size < m_rawstringSize) + if ((new_size > Capacity) || (new_size < m_rawstringSize)) { return false; } @@ -551,7 +485,7 @@ inline optional> string::substr(const uint64_t pos, c return nullopt; } - uint64_t length = std::min(count, m_rawstringSize - pos); + uint64_t length{std::min(count, m_rawstringSize - pos)}; string subString; std::memcpy(&(subString.m_rawstring[0]), &m_rawstring[pos], length); subString.m_rawstring[length] = '\0'; @@ -574,12 +508,12 @@ inline IsStringOrCharArray> string::find(const T { return nullopt; } - const char* found = std::strstr(c_str() + pos, internal::GetData::call(str)); + const char* found{std::strstr(c_str() + pos, internal::GetData::call(str))}; if (found == nullptr) { return nullopt; } - return (static_cast(found - c_str())); + return static_cast(found - c_str()); } template @@ -591,8 +525,8 @@ inline IsStringOrCharArray> string::find_first_o { return nullopt; } - const char* found = nullptr; - const char* data = internal::GetData::call(str); + const char* found{nullptr}; + const char* data{internal::GetData::call(str)}; for (auto p = pos; p < m_rawstringSize; ++p) { found = std::strchr(data, m_rawstring[p]); @@ -614,13 +548,13 @@ inline IsStringOrCharArray> string::find_last_of return nullopt; } - auto p = pos; - if (m_rawstringSize - 1U < p) + uint64_t p{pos}; + if ((m_rawstringSize - 1U) < p) { p = m_rawstringSize - 1U; } - const char* found = nullptr; - const char* data = internal::GetData::call(str); + const char* found{nullptr}; + const char* data{internal::GetData::call(str)}; for (; p > 0U; --p) { found = std::strchr(data, m_rawstring[p]); @@ -640,8 +574,8 @@ inline IsStringOrCharArray> string::find_last_of template inline constexpr char& string::at(const uint64_t pos) noexcept { - // const_cast to avoid code duplication, safe since it's first casted to a const type and then the const is removed - // again + // AXIVION Next Construct AutosarC++19_03-A5.2.3 : const_cast to avoid code duplication, safe since it's first + // casted to a const type and then the const is removed // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast) return const_cast(const_cast*>(this)->at(pos)); } @@ -649,7 +583,7 @@ inline constexpr char& string::at(const uint64_t pos) noexcept template inline constexpr const char& string::at(const uint64_t pos) const noexcept { - Expects(pos < size() && "Out of bounds access!"); + ExpectsWithMsg((pos < size()), "Out of bounds access!"); return m_rawstring[pos]; } @@ -664,6 +598,81 @@ inline constexpr const char& string::operator[](const uint64_t pos) co { return at(pos); } + +// AXIVION DISABLE STYLE AutosarC++19_03-A13.5.5: Comparison with std::string, char array or +// char is also intended +template +inline IsStdStringOrCharArrayOrChar operator==(const T& lhs, const string& rhs) noexcept +{ + return (rhs.compare(lhs) == 0); +} + +template +inline IsStdStringOrCharArrayOrChar operator!=(const T& lhs, const string& rhs) noexcept +{ + return (rhs.compare(lhs) != 0); +} + +template +inline IsStdStringOrCharArrayOrChar operator<(const T& lhs, const string& rhs) noexcept +{ + return (rhs.compare(lhs) > 0); +} + +template +inline IsStdStringOrCharArrayOrChar operator<=(const T& lhs, const string& rhs) noexcept +{ + return (rhs.compare(lhs) >= 0); +} + +template +inline IsStdStringOrCharArrayOrChar operator>(const T& lhs, const string& rhs) noexcept +{ + return (rhs.compare(lhs) < 0); +} + +template +inline IsStdStringOrCharArrayOrChar operator>=(const T& lhs, const string& rhs) noexcept +{ + return (rhs.compare(lhs) <= 0); +} + +template +inline IsStringOrCharArrayOrChar operator==(const string& lhs, const T& rhs) noexcept +{ + return (lhs.compare(rhs) == 0); +} + +template +inline IsStringOrCharArrayOrChar operator!=(const string& lhs, const T& rhs) noexcept +{ + return (lhs.compare(rhs) != 0); +} + +template +inline IsStringOrCharArrayOrChar operator<(const string& lhs, const T& rhs) noexcept +{ + return (lhs.compare(rhs) < 0); +} + +template +inline IsStringOrCharArrayOrChar operator<=(const string& lhs, const T& rhs) noexcept +{ + return (lhs.compare(rhs) <= 0); +} + +template +inline IsStringOrCharArrayOrChar operator>(const string& lhs, const T& rhs) noexcept +{ + return (lhs.compare(rhs) > 0); +} + +template +inline IsStringOrCharArrayOrChar operator>=(const string& lhs, const T& rhs) noexcept +{ + return (lhs.compare(rhs) >= 0); +} +// AXIVION ENABLE Style AutosarC++19_03-A13.5.5 } // namespace cxx } // namespace iox