| @@ -62,7 +62,7 @@ namespace cppcore | |||||
| using enum_type = T_enum; | using enum_type = T_enum; | ||||
| using traits_type = T_traits; | using traits_type = T_traits; | ||||
| using enum_to_string_map_type = std::map<enum_type, std::string>; | using enum_to_string_map_type = std::map<enum_type, std::string>; | ||||
| using string_to_enum_map_type = std::map<std::string, enum_type, op_less_invariant_string>; | |||||
| using string_to_enum_map_type = std::map<std::string, enum_type, op_invariant_string_less>; | |||||
| /** | /** | ||||
| * @brief Returns a map with enum to string values. | * @brief Returns a map with enum to string values. | ||||
| @@ -6,12 +6,12 @@ namespace cppcore | |||||
| { | { | ||||
| /** | /** | ||||
| * @brief Predicate class to caompare to string ignoring the case and variant. | |||||
| * @brief Predicate class to compare two strings ignoring the case and variant. | |||||
| */ | */ | ||||
| struct op_less_invariant_string | |||||
| struct op_invariant_string_less | |||||
| { | { | ||||
| /** | /** | ||||
| * @brief Compare to string. | |||||
| * @brief Compare two strings. | |||||
| * | * | ||||
| * @param[in] lhs Left hand value. | * @param[in] lhs Left hand value. | ||||
| * @param[in] rhs Right hand value. | * @param[in] rhs Right hand value. | ||||
| @@ -22,6 +22,24 @@ namespace cppcore | |||||
| inline bool operator()(const std::string& lhs, const std::string& rhs) const; | inline bool operator()(const std::string& lhs, const std::string& rhs) const; | ||||
| }; | }; | ||||
| /** | |||||
| * @brief Predicate class to compare two strings ignoring the case and variant. | |||||
| */ | |||||
| struct op_invariant_string_compare | |||||
| { | |||||
| /** | |||||
| * @brief Compare two strings. | |||||
| * | |||||
| * @param[in] lhs Left hand value. | |||||
| * @param[in] rhs Right hand value. | |||||
| * | |||||
| * @retval -1 If lhs is less than rhs. | |||||
| * @retval 0 If lhs is equal rhs. | |||||
| * @retval 1 If lhs is greater than rhs. | |||||
| */ | |||||
| inline int operator()(const std::string& lhs, const std::string& rhs) const; | |||||
| }; | |||||
| } | } | ||||
| #include "compare.inl" | #include "compare.inl" | ||||
| @@ -5,15 +5,21 @@ | |||||
| namespace cppcore | namespace cppcore | ||||
| { | { | ||||
| /* op_less_invariant_string */ | |||||
| /* op_invariant_string_less */ | |||||
| bool op_less_invariant_string | |||||
| bool op_invariant_string_less | |||||
| ::operator()(const std::string& lhs, const std::string& rhs) const | ::operator()(const std::string& lhs, const std::string& rhs) const | ||||
| { return op_invariant_string_compare { } (lhs, rhs) < 0; } | |||||
| /* op_invariant_string_compare */ | |||||
| int op_invariant_string_compare::operator()(const std::string& lhs, const std::string& rhs) const | |||||
| { | { | ||||
| auto c1 = lhs.c_str(); | auto c1 = lhs.c_str(); | ||||
| auto c2 = rhs.c_str(); | auto c2 = rhs.c_str(); | ||||
| auto l1 = lhs.size(); | auto l1 = lhs.size(); | ||||
| auto l2 = rhs.size(); | auto l2 = rhs.size(); | ||||
| while (l1 > 0 && l2 > 0 && std::tolower(*c1) == std::tolower(*c2)) | while (l1 > 0 && l2 > 0 && std::tolower(*c1) == std::tolower(*c2)) | ||||
| { | { | ||||
| ++c1; | ++c1; | ||||
| @@ -21,9 +27,25 @@ namespace cppcore | |||||
| --l1; | --l1; | ||||
| --l2; | --l2; | ||||
| } | } | ||||
| return l1 > 0 && l2 > 0 | |||||
| ? std::tolower(*c1) < std::tolower(*c2) | |||||
| : l1 < l2; | |||||
| if (l1 > 0 && l2 > 0) | |||||
| { | |||||
| auto x1 = std::tolower(*c1); | |||||
| auto x2 = std::tolower(*c2); | |||||
| return | |||||
| x1 < x2 ? -1 : | |||||
| x1 > x2 ? 1 : | |||||
| 0; | |||||
| } | |||||
| else | |||||
| { | |||||
| return | |||||
| l1 < l2 ? -1 : | |||||
| l1 > l2 ? 1 : | |||||
| 0; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -0,0 +1,21 @@ | |||||
| #include <gtest/gtest.h> | |||||
| #include <cppcore/misc/compare.h> | |||||
| using namespace ::cppcore; | |||||
| using namespace ::testing; | |||||
| TEST(compare_tests, invariant_string_compare) | |||||
| { | |||||
| op_invariant_string_compare cmp; | |||||
| // Length check | |||||
| EXPECT_EQ( 0, cmp("abcdef", "AbCdef")); | |||||
| EXPECT_EQ(-1, cmp("abcde", "AbCdef")); | |||||
| EXPECT_EQ( 1, cmp("abcdeF", "AbCde")); | |||||
| // Value checks | |||||
| EXPECT_EQ( 0, cmp("abcdef", "AbCdef")); | |||||
| EXPECT_EQ(-1, cmp("aBbDef", "AbCdef")); | |||||
| EXPECT_EQ( 1, cmp("abcdeF", "AbCdeD")); | |||||
| } | |||||