On Friday, 19 July 2013 at 17:18:00 UTC, JS wrote:
I'm trying to create a split function that can handle both char
and string delims. I initially created two separate functions
but this doesn't work for default parameters since the compiler
doesn't know which one to choose(but in this case both would
work fine and it would be nice to inform the compiler of that).
I then tried to template and conditionally code the two but it
still doesn't work:
both functions work separately but when i uncomment the string
version I get an error about the string version shadowing.
import std.stdio, std.cstream;
string[] split(T)(string s, T d) if (is(T == char) || is(T ==
string))
{
int i = 0, oldj = 0; bool ok = true;
string[] r;
foreach(j, c; s)
{
static if (is(T == char))
{
if (c == d)
{
if (!ok) { oldj++; continue; }
if (r.length <= i) r.length += 5;
r[i] = s[oldj..j];
i++; oldj = j+1;
ok = false;
} else if (!ok) ok = true;
}
else if (is(T == string))
{
/*
for(int j = 0; j < s.length - d.length; j++)
{
if (s[j..j + d.length] == d)
{
if (!ok) { oldj++; continue; }
if (i == r.length) r.length += 5;
r[i] = s[oldj..j - d.length + 1];
i++; oldj = j + d.length;
ok = false;
} else if (!ok) ok = true;
}
*/
}
}
if (oldj < s.length)
{
if (r.length <= i) r.length++;
r[i] = s[oldj..$];
i++;
}
r.length = i;
return r;
}
string[] splitS(string s, string d = " ")
{
int i = 0, oldj = 0; bool ok = true;
string[] r;
for(int j = 0; j < s.length - d.length; j++)
{
if (s[j..j + d.length] == d)
{
if (!ok) { oldj++; continue; }
if (r.length <= i) r.length += 5;
r[i] = s[oldj..j - d.length + 1];
i++; oldj = j + d.length;
ok = false;
} else if (!ok) ok = true;
}
if (oldj < s.length)
{
if (r.length <= i) r.length++;
r[i] = s[oldj..$];
i++;
}
r.length = i;
return r;
}
void main(string[] args)
{
auto s = splitS("abc bas ccc", " ");
foreach(a; s) writeln(a);
din.getc();
}
BTW, I'd like to have a default value for d. That or efficiently
allow for variadic d, which then the default delim could easily
be tested for.