mirror of
https://github.com/dlang/phobos.git
synced 2025-05-10 22:18:03 +03:00
Merge pull request #6727 from n8sh/strip-ascii
Add ASCII fast path to stripLeft & avoid unnecessary decoding
This commit is contained in:
commit
4e6f70a134
1 changed files with 80 additions and 12 deletions
72
std/string.d
72
std/string.d
|
@ -2937,8 +2937,70 @@ if (isForwardRange!Range && isSomeChar!(ElementEncodingType!Range) &&
|
||||||
{
|
{
|
||||||
static import std.ascii;
|
static import std.ascii;
|
||||||
static import std.uni;
|
static import std.uni;
|
||||||
import std.utf : decodeFront;
|
|
||||||
|
|
||||||
|
static if (is(Unqual!(ElementEncodingType!Range) == dchar)
|
||||||
|
|| is(Unqual!(ElementEncodingType!Range) == wchar))
|
||||||
|
{
|
||||||
|
// Decoding is never needed for dchar. It happens not to be needed
|
||||||
|
// here for wchar because no whitepace is outside the basic
|
||||||
|
// multilingual plane meaning every whitespace character is encoded
|
||||||
|
// with a single wchar and due to the design of UTF-16 those wchars
|
||||||
|
// will not occur as part of the encoding of multi-wchar codepoints.
|
||||||
|
static if (isDynamicArray!Range)
|
||||||
|
{
|
||||||
|
foreach (i; 0 .. input.length)
|
||||||
|
{
|
||||||
|
if (!std.uni.isWhite(input[i]))
|
||||||
|
return input[i .. $];
|
||||||
|
}
|
||||||
|
return input[$ .. $];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (!input.empty)
|
||||||
|
{
|
||||||
|
if (!std.uni.isWhite(input.front))
|
||||||
|
break;
|
||||||
|
input.popFront();
|
||||||
|
}
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
static if (isDynamicArray!Range)
|
||||||
|
{
|
||||||
|
// ASCII optimization for dynamic arrays.
|
||||||
|
size_t i = 0;
|
||||||
|
for (const size_t end = input.length; i < end; ++i)
|
||||||
|
{
|
||||||
|
auto c = input[i];
|
||||||
|
if (c >= 0x80) goto NonAsciiPath;
|
||||||
|
if (!std.ascii.isWhite(c)) break;
|
||||||
|
}
|
||||||
|
input = input[i .. $];
|
||||||
|
return input;
|
||||||
|
|
||||||
|
NonAsciiPath:
|
||||||
|
input = input[i .. $];
|
||||||
|
// Fall through to standard case.
|
||||||
|
}
|
||||||
|
|
||||||
|
static if (ElementType!Range.sizeof > ElementEncodingType!Range.sizeof)
|
||||||
|
{
|
||||||
|
// Type performs its own decoding.
|
||||||
|
while (!input.empty)
|
||||||
|
{
|
||||||
|
if (!std.uni.isWhite(input.front))
|
||||||
|
break;
|
||||||
|
input.popFront();
|
||||||
|
}
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Type doesn't perform its own decoding.
|
||||||
|
import std.utf : decodeFront, UseReplacementDchar;
|
||||||
while (!input.empty)
|
while (!input.empty)
|
||||||
{
|
{
|
||||||
auto c = input.front;
|
auto c = input.front;
|
||||||
|
@ -2951,13 +3013,15 @@ if (isForwardRange!Range && isSomeChar!(ElementEncodingType!Range) &&
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto save = input.save;
|
auto save = input.save;
|
||||||
auto dc = decodeFront(input);
|
auto dc = decodeFront!(UseReplacementDchar.yes)(input);
|
||||||
if (!std.uni.isWhite(dc))
|
if (!std.uni.isWhite(dc))
|
||||||
return save;
|
return save;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@safe pure unittest
|
@safe pure unittest
|
||||||
|
@ -2967,6 +3031,8 @@ if (isForwardRange!Range && isSomeChar!(ElementEncodingType!Range) &&
|
||||||
"hello world ");
|
"hello world ");
|
||||||
assert(stripLeft("\n\t\v\rhello world\n\t\v\r") ==
|
assert(stripLeft("\n\t\v\rhello world\n\t\v\r") ==
|
||||||
"hello world\n\t\v\r");
|
"hello world\n\t\v\r");
|
||||||
|
assert(stripLeft(" \u2028hello world") ==
|
||||||
|
"hello world");
|
||||||
assert(stripLeft("hello world") ==
|
assert(stripLeft("hello world") ==
|
||||||
"hello world");
|
"hello world");
|
||||||
assert(stripLeft([lineSep] ~ "hello world" ~ lineSep) ==
|
assert(stripLeft([lineSep] ~ "hello world" ~ lineSep) ==
|
||||||
|
@ -2978,6 +3044,8 @@ if (isForwardRange!Range && isSomeChar!(ElementEncodingType!Range) &&
|
||||||
import std.utf : byChar;
|
import std.utf : byChar;
|
||||||
assert(stripLeft(" hello world "w.byChar).array ==
|
assert(stripLeft(" hello world "w.byChar).array ==
|
||||||
"hello world ");
|
"hello world ");
|
||||||
|
assert(stripLeft(" \u2022hello world ".byChar).array ==
|
||||||
|
"\u2022hello world ");
|
||||||
}
|
}
|
||||||
|
|
||||||
auto stripLeft(Range)(auto ref Range str)
|
auto stripLeft(Range)(auto ref Range str)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue