string: add upper
comparator
This commit is contained in:
parent
f9aa13ad81
commit
654f391cba
55
string.hpp
55
string.hpp
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "ascii.hpp"
|
||||||
#include "debug.hpp"
|
#include "debug.hpp"
|
||||||
#include "view.hpp"
|
#include "view.hpp"
|
||||||
|
|
||||||
@ -216,3 +217,57 @@ namespace cruft {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace cruft::string::compare {
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
/// A case comparator that tests equality on a string after a
|
||||||
|
/// per-character transform is applied.
|
||||||
|
///
|
||||||
|
/// Neither string will be modified.
|
||||||
|
///
|
||||||
|
/// \tparam TransformV A character transform function
|
||||||
|
template <char (*TransformV)(char) noexcept>
|
||||||
|
struct transform {
|
||||||
|
template <
|
||||||
|
typename CharT,
|
||||||
|
typename = std::void_t<
|
||||||
|
typename std::char_traits<CharT>::char_type
|
||||||
|
>
|
||||||
|
>
|
||||||
|
bool operator() (cruft::view<CharT const *> a, cruft::view<CharT const*> b)
|
||||||
|
{
|
||||||
|
if (a.size () != b.size ())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (auto i = a.begin (), j = b.begin (); i != a.end (); ++i, ++j)
|
||||||
|
if (TransformV (*i) != TransformV (*j))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <
|
||||||
|
typename CharT,
|
||||||
|
typename = std::void_t<
|
||||||
|
typename std::char_traits<CharT>::char_type
|
||||||
|
>
|
||||||
|
>
|
||||||
|
bool operator() (CharT const *a, CharT const *b) const noexcept
|
||||||
|
{
|
||||||
|
auto const *i = a;
|
||||||
|
auto const *j = b;
|
||||||
|
|
||||||
|
for ( ; *i && *j; ++i, ++j)
|
||||||
|
if (TransformV (*i) != TransformV (*j))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Ensure we've reached the ends of both strings
|
||||||
|
return !*i && !*j;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
using lower = transform<ascii::try_lower>;
|
||||||
|
using upper = transform<ascii::try_upper>;
|
||||||
|
}
|
||||||
|
@ -144,7 +144,7 @@ test_contains (cruft::TAP::logger &tap)
|
|||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
void test_comparator (cruft::TAP::logger &tap)
|
void test_comparator_less (cruft::TAP::logger &tap)
|
||||||
{
|
{
|
||||||
cruft::string_less cmp;
|
cruft::string_less cmp;
|
||||||
|
|
||||||
@ -164,6 +164,39 @@ void test_comparator (cruft::TAP::logger &tap)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
void test_comparator_lower (cruft::TAP::logger &tap)
|
||||||
|
{
|
||||||
|
struct {
|
||||||
|
char const *a;
|
||||||
|
char const *b;
|
||||||
|
bool equal;
|
||||||
|
char const *message;
|
||||||
|
} const TESTS[] = {
|
||||||
|
{ "a", "a", true, "both single lower" },
|
||||||
|
{ "a", "A", true, "lower, upper singles" },
|
||||||
|
{ "A", "a", true, "upper, lower singles" },
|
||||||
|
{ "AbcDEf", "aBcdEF", true, "mixed upper lower" },
|
||||||
|
{ "A", "aa", false, "mixed case, different lengths" },
|
||||||
|
};
|
||||||
|
|
||||||
|
cruft::string::compare::lower cmp;
|
||||||
|
|
||||||
|
for (auto const &t: TESTS) {
|
||||||
|
tap.expect_eq (cmp (t.a, t.b), t.equal, "compare::lower, pointers, %!", t.message);
|
||||||
|
tap.expect_eq (
|
||||||
|
cmp (
|
||||||
|
cruft::view (t.a),
|
||||||
|
cruft::view (t.b)
|
||||||
|
),
|
||||||
|
t.equal,
|
||||||
|
"compare::lower, views, %!",
|
||||||
|
t.message
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
int
|
int
|
||||||
main (int, char**)
|
main (int, char**)
|
||||||
@ -173,7 +206,8 @@ main (int, char**)
|
|||||||
test_tokeniser (tap);
|
test_tokeniser (tap);
|
||||||
test_position (tap);
|
test_position (tap);
|
||||||
test_contains (tap);
|
test_contains (tap);
|
||||||
test_comparator (tap);
|
test_comparator_less (tap);
|
||||||
|
test_comparator_lower (tap);
|
||||||
|
|
||||||
return tap.status ();
|
return tap.status ();
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user