Browse Source

* Implemented invariant string comparison

master
bergmann 6 years ago
parent
commit
e56696ad85
4 changed files with 70 additions and 9 deletions
  1. +1
    -1
      include/cppcore/conversion/enum.h
  2. +21
    -3
      include/cppcore/misc/compare.h
  3. +27
    -5
      include/cppcore/misc/compare.inl
  4. +21
    -0
      test/cppcore/misc/compare_tests.cpp

+ 1
- 1
include/cppcore/conversion/enum.h View File

@@ -62,7 +62,7 @@ namespace cppcore
using enum_type = T_enum;
using traits_type = T_traits;
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.


+ 21
- 3
include/cppcore/misc/compare.h View File

@@ -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] rhs Right hand value.
@@ -22,6 +22,24 @@ namespace cppcore
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"

+ 27
- 5
include/cppcore/misc/compare.inl View File

@@ -5,15 +5,21 @@
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
{ 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 c2 = rhs.c_str();
auto l1 = lhs.size();
auto l2 = rhs.size();

while (l1 > 0 && l2 > 0 && std::tolower(*c1) == std::tolower(*c2))
{
++c1;
@@ -21,9 +27,25 @@ namespace cppcore
--l1;
--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;
}
}


}

+ 21
- 0
test/cppcore/misc/compare_tests.cpp View File

@@ -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"));
}

Loading…
Cancel
Save