Hi,
I have a string wrapper called SlicedString. What it does is very simple: Returning each piece as a slice with a assured separator at compile time by used indexOf() ! Here it is:
struct SlicedString(string E)
{
long index, back, next = -1;
string data;
auto length() const
{
import std.array : split;
import std.range : walkLength;
return data.split(E).walkLength;
}
auto popIndex(ref SlicedString!E range)
{
scope(exit) range.popFront();
return [range.back, range.next];
}
auto elementsPos()
{
long[][] result;
auto r = SlicedString!E(index, back, next, data);
while(!r.empty)
{
result ~= popIndex(r);
}
return result;
}
bool empty() { return index == 0; }
auto front() { return data[back..next]; }
void popFront()
{
import std.string : find = indexOf;
--index;
back = ++next;
next = data.find(E, next);
if(next == -1)
{
next = data.length;
}
}
}
auto sliceOff(string E = " ")(string data)
{
SlicedString!E s;
s.data = data;
s.popFront();
return s;
}
// UNIT TESTS:
void main()
{
auto str = "abc def ghi";
auto slc = str.sliceOff;
auto len = slc.length;
slc.index = len;
import std.stdio, std.algorithm: equal;
assert(slc.equal(["abc", "def", "ghi"]));
// Print range:
foreach(s; slc) s.write;
writeln;
// Print Elements Position
slc.elementsPos.writeln;
slc.elementsPos.writeln;
}
The unit tests work as I want, but I find calculating the length with split() too expensive; despite walkLength()...
Is there a more accurate method? Last year, Ali Çehreli told me that splitter() was also possible, but then he did something with map(). I really don't understand these!
Thanks...
SDB@79