Ranges: add unit test and fix corner case in split view
This commit is contained in:
parent
2f48bbf6ff
commit
bedb98220c
27
src/ranges.cc
Normal file
27
src/ranges.cc
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
#include "ranges.hh"
|
||||||
|
#include "unit_tests.hh"
|
||||||
|
#include "string.hh"
|
||||||
|
#include "string_utils.hh"
|
||||||
|
|
||||||
|
namespace Kakoune
|
||||||
|
{
|
||||||
|
|
||||||
|
UnitTest test_ranges{[] {
|
||||||
|
auto check_equal = [](auto&& container, ConstArrayView<StringView> expected) {
|
||||||
|
kak_assert(std::equal(container.begin(), container.end(), expected.begin(), expected.end()));
|
||||||
|
};
|
||||||
|
check_equal("a,b,c"_sv | split<StringView>(','), {"a", "b", "c"});
|
||||||
|
check_equal(",b,c"_sv | split<StringView>(','), {"", "b", "c"});
|
||||||
|
check_equal(",b,"_sv | split<StringView>(','), {"", "b", ""});
|
||||||
|
check_equal(","_sv | split<StringView>(','), {"", ""});
|
||||||
|
check_equal(""_sv | split<StringView>(','), {});
|
||||||
|
|
||||||
|
check_equal(R"(a\,,\,b,\,)"_sv | split<StringView>(',', '\\')
|
||||||
|
| transform(unescape<',', '\\'>), {"a,", ",b", ","});
|
||||||
|
check_equal(R"(\,\,)"_sv | split<StringView>(',', '\\')
|
||||||
|
| transform(unescape<',', '\\'>), {",,"});
|
||||||
|
check_equal(R"(\\,\\,)"_sv | split<StringView>(',', '\\')
|
||||||
|
| transform(unescape<',', '\\'>), {R"(\)", R"(\)", ""});
|
||||||
|
}};
|
||||||
|
|
||||||
|
}
|
|
@ -173,13 +173,13 @@ struct SplitView
|
||||||
|
|
||||||
struct Iterator : std::iterator<std::forward_iterator_tag, ValueType>
|
struct Iterator : std::iterator<std::forward_iterator_tag, ValueType>
|
||||||
{
|
{
|
||||||
Iterator(RangeIt pos, RangeIt end, Element separator, Element escaper)
|
Iterator(RangeIt pos, const RangeIt& end, Element separator, Element escaper)
|
||||||
: pos(pos), sep(pos), end(end), separator(separator), escaper(escaper)
|
: done{pos == end}, pos{pos}, sep{pos}, end(end), separator{std::move(separator)}, escaper{std::move(escaper)}
|
||||||
{
|
{
|
||||||
bool escaped = false;
|
bool escaped = false;
|
||||||
while (sep != end and (escaped or *sep != separator))
|
while (sep != end and (escaped or *sep != separator))
|
||||||
{
|
{
|
||||||
escaped = escape and *sep == escaper;
|
escaped = escape and not escaped and *sep == escaper;
|
||||||
++sep;
|
++sep;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -187,8 +187,8 @@ struct SplitView
|
||||||
Iterator& operator++() { advance(); return *this; }
|
Iterator& operator++() { advance(); return *this; }
|
||||||
Iterator operator++(int) { auto copy = *this; advance(); return copy; }
|
Iterator operator++(int) { auto copy = *this; advance(); return copy; }
|
||||||
|
|
||||||
bool operator==(const Iterator& other) const { return pos == other.pos; }
|
bool operator==(const Iterator& other) const { return pos == other.pos and done == other.done; }
|
||||||
bool operator!=(const Iterator& other) const { return pos != other.pos; }
|
bool operator!=(const Iterator& other) const { return pos != other.pos or done != other.done; }
|
||||||
|
|
||||||
ValueType operator*() { return {pos, sep}; }
|
ValueType operator*() { return {pos, sep}; }
|
||||||
|
|
||||||
|
@ -198,6 +198,7 @@ struct SplitView
|
||||||
if (sep == end)
|
if (sep == end)
|
||||||
{
|
{
|
||||||
pos = end;
|
pos = end;
|
||||||
|
done = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,6 +212,7 @@ struct SplitView
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool done;
|
||||||
RangeIt pos;
|
RangeIt pos;
|
||||||
RangeIt sep;
|
RangeIt sep;
|
||||||
RangeIt end;
|
RangeIt end;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user