Skip to content

Commit

Permalink
Merge pull request #1823 from andralex/6730
Browse files Browse the repository at this point in the history
Fix Issue 6730
  • Loading branch information
WalterBright committed Dec 30, 2013
2 parents 97d3f75 + 06352bc commit 72a1c4d
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 83 deletions.
86 changes: 78 additions & 8 deletions std/algorithm.d
Expand Up @@ -2959,14 +2959,84 @@ unittest
assert(equal(splitter!"a=='本'"("日本語"), ["", ""]));
}

//Explicitly undocumented. It will be removed in December 2014.
//@@@6730@@@ This exists already in std.array, so this declaration, at best, will only create ambiguity.
//unfortunately, an alias will conflict with the existing splitter in std.algorithm.
deprecated("Please use std.array.splitter for string specific splitting")
auto splitter(Range)(Range input)
if (isSomeString!Range)
{
return std.array.splitter(input);
/++
Lazily splits the string $(D s) into words, using whitespace as the delimiter.
This function is string specific and, contrary to
$(D splitter!(std.uni.isWhite)), runs of whitespace will be merged together
(no empty tokens will be produced).
+/
auto splitter(C)(C[] s)
if (isSomeChar!C)
{
static struct Result
{
private:
import core.exception;
C[] _s;
size_t _frontLength;

void getFirst() pure @safe
{
auto r = find!(std.uni.isWhite)(_s);
_frontLength = _s.length - r.length;
}

public:
this(C[] s) pure @safe
{
import std.string;
_s = s.strip();
getFirst();
}

@property C[] front() pure @safe
{
version(assert) if (empty) throw new RangeError();
return _s[0 .. _frontLength];
}

void popFront() pure @safe
{
import std.string : stripLeft;
version(assert) if (empty) throw new RangeError();
_s = _s[_frontLength .. $].stripLeft();
getFirst();
}

@property bool empty() const pure nothrow @safe
{
return _s.empty;
}

@property inout(Result) save() inout pure nothrow @safe
{
return this;
}
}
return Result(s);
}

///
@safe pure unittest
{
auto a = " a bcd ef gh ";
assert(equal(splitter(a), ["a", "bcd", "ef", "gh"][]));
}

@safe pure unittest
{
foreach(S; TypeTuple!(string, wstring, dstring))
{
import std.conv : to;
S a = " a bcd ef gh ";
assert(equal(splitter(a), [to!S("a"), to!S("bcd"), to!S("ef"), to!S("gh")]));
a = "";
assert(splitter(a).empty);
}

immutable string s = " a bcd ef gh ";
assert(equal(splitter(s), ["a", "bcd", "ef", "gh"][]));
}

unittest
Expand Down
78 changes: 3 additions & 75 deletions std/array.d
Expand Up @@ -1426,81 +1426,9 @@ unittest //safety, purity, ctfe ...
}

/++
Lazily splits the string $(D s) into words, using whitespace as
the delimiter.
This function is string specific and, contrary to $(D
splitter!(std.uni.isWhite)), runs of whitespace will be merged together
(no empty tokens will be produced).
Alias for $(XREF algorithm, splitter).
+/
auto splitter(C)(C[] s)
if(isSomeChar!C)
{
static struct Result
{
private:
C[] _s;
size_t _frontLength;

void getFirst() pure @safe
{
auto r = find!(std.uni.isWhite)(_s);
_frontLength = _s.length - r.length;
}

public:
this(C[] s) pure @safe
{
_s = s.strip();
getFirst();
}

@property C[] front() pure @safe
{
version(assert) if (empty) throw new RangeError();
return _s[0 .. _frontLength];
}

void popFront() pure @safe
{
version(assert) if (empty) throw new RangeError();
_s = _s[_frontLength .. $].stripLeft();
getFirst();
}

@property bool empty() const pure nothrow @safe
{
return _s.empty;
}

@property inout(Result) save() inout pure nothrow @safe
{
return this;
}
}
return Result(s);
}

///
@safe pure unittest
{
auto a = " a bcd ef gh ";
assert(equal(splitter(a), ["a", "bcd", "ef", "gh"][]));
}

@safe pure unittest
{
foreach(S; TypeTuple!(string, wstring, dstring))
{
S a = " a bcd ef gh ";
assert(equal(splitter(a), [to!S("a"), to!S("bcd"), to!S("ef"), to!S("gh")]));
a = "";
assert(splitter(a).empty);
}

immutable string s = " a bcd ef gh ";
assert(equal(splitter(s), ["a", "bcd", "ef", "gh"][]));
}
alias splitter = std.algorithm.splitter;

/++
Eagerly splits $(D s) into an array, using $(D delim) as the delimiter.
Expand Down Expand Up @@ -2399,7 +2327,7 @@ struct Appender(A : T[], T)
static if (is(Unqual!T == T))
alias uitem = item;
else
auto ref uitem() @trusted nothrow @property { return cast(Unqual!T)item;}
auto ref uitem() @trusted nothrow @property { return cast(Unqual!T)item;}

//The idea is to only call emplace if we must.
static if ( is(typeof(bigData[0].opAssign(uitem))) ||
Expand Down

0 comments on commit 72a1c4d

Please sign in to comment.