mirror of
https://github.com/dlang/phobos.git
synced 2025-05-05 09:30:49 +03:00
Merge pull request #6545 from JackStouffer/toCase-random-access
Issue 18948 - std.uni.toLower and std.uni.toUpper should work with random access ranges merged-on-behalf-of: Jack Stouffer <jack@jackstouffer.com>
This commit is contained in:
commit
cc58e8a7bf
1 changed files with 68 additions and 17 deletions
79
std/uni.d
79
std/uni.d
|
@ -8996,20 +8996,24 @@ private alias UpperTriple = AliasSeq!(toUpperIndex, MAX_SIMPLE_UPPER, toUpperTab
|
||||||
private alias LowerTriple = AliasSeq!(toLowerIndex, MAX_SIMPLE_LOWER, toLowerTab);
|
private alias LowerTriple = AliasSeq!(toLowerIndex, MAX_SIMPLE_LOWER, toLowerTab);
|
||||||
|
|
||||||
// generic toUpper/toLower on whole string, creates new or returns as is
|
// generic toUpper/toLower on whole string, creates new or returns as is
|
||||||
private S toCase(alias indexFn, uint maxIdx, alias tableFn, alias asciiConvert, S)(S s) @trusted pure
|
private ElementEncodingType!S[] toCase(alias indexFn, uint maxIdx, alias tableFn, alias asciiConvert, S)(S s)
|
||||||
if (isSomeString!S)
|
if (isSomeString!S || (isRandomAccessRange!S && hasLength!S && hasSlicing!S && isSomeChar!(ElementType!S)))
|
||||||
{
|
{
|
||||||
import std.array : appender;
|
import std.array : appender, array;
|
||||||
import std.ascii : isASCII;
|
import std.ascii : isASCII;
|
||||||
|
import std.utf : byDchar;
|
||||||
|
|
||||||
foreach (i, dchar cOuter; s)
|
auto r = s.byDchar;
|
||||||
|
for (size_t i; !r.empty; ++i, r.popFront())
|
||||||
{
|
{
|
||||||
|
auto cOuter = r.front;
|
||||||
ushort idx = indexFn(cOuter);
|
ushort idx = indexFn(cOuter);
|
||||||
if (idx == ushort.max)
|
if (idx == ushort.max)
|
||||||
continue;
|
continue;
|
||||||
auto result = appender!S(s[0 .. i]);
|
auto result = appender!(ElementEncodingType!S[])();
|
||||||
|
result.put(s[0 .. i]);
|
||||||
result.reserve(s.length);
|
result.reserve(s.length);
|
||||||
foreach (dchar c; s[i .. $])
|
foreach (dchar c; s[i .. $].byDchar)
|
||||||
{
|
{
|
||||||
if (c.isASCII)
|
if (c.isASCII)
|
||||||
{
|
{
|
||||||
|
@ -9038,7 +9042,11 @@ if (isSomeString!S)
|
||||||
}
|
}
|
||||||
return result.data;
|
return result.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static if (isSomeString!S)
|
||||||
return s;
|
return s;
|
||||||
|
else
|
||||||
|
return s.array;
|
||||||
}
|
}
|
||||||
|
|
||||||
@safe unittest //12428
|
@safe unittest //12428
|
||||||
|
@ -9782,16 +9790,28 @@ dchar toLower(dchar c)
|
||||||
}
|
}
|
||||||
|
|
||||||
/++
|
/++
|
||||||
Returns a string which is identical to `s` except that all of its
|
Creates a new array which is identical to `s` except that all of its
|
||||||
characters are converted to lowercase (by preforming Unicode lowercase mapping).
|
characters are converted to lowercase (by preforming Unicode lowercase mapping).
|
||||||
If none of `s` characters were affected, then `s` itself is returned.
|
If none of `s` characters were affected, then `s` itself is returned if `s` is a
|
||||||
|
`string`-like type.
|
||||||
|
|
||||||
|
Params:
|
||||||
|
s = A $(REF_ALTTEXT random access range, isRandomAccessRange, std,range,primitives)
|
||||||
|
of characters
|
||||||
|
Returns:
|
||||||
|
An array with the same element type as `s`.
|
||||||
+/
|
+/
|
||||||
S toLower(S)(S s) @trusted pure
|
ElementEncodingType!S[] toLower(S)(S s)
|
||||||
if (isSomeString!S)
|
if (isSomeString!S || (isRandomAccessRange!S && hasLength!S && hasSlicing!S && isSomeChar!(ElementType!S)))
|
||||||
{
|
{
|
||||||
static import std.ascii;
|
static import std.ascii;
|
||||||
|
|
||||||
|
static if (isSomeString!S)
|
||||||
|
return () @trusted { return toCase!(LowerTriple, std.ascii.toLower)(s); } ();
|
||||||
|
else
|
||||||
return toCase!(LowerTriple, std.ascii.toLower)(s);
|
return toCase!(LowerTriple, std.ascii.toLower)(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
// overloads for the most common cases to reduce compile time
|
// overloads for the most common cases to reduce compile time
|
||||||
@safe pure /*TODO nothrow*/
|
@safe pure /*TODO nothrow*/
|
||||||
{
|
{
|
||||||
|
@ -9899,6 +9919,15 @@ if (isSomeString!S)
|
||||||
assert(toUpper(c) == '\u1F8F');
|
assert(toUpper(c) == '\u1F8F');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@safe pure unittest
|
||||||
|
{
|
||||||
|
import std.algorithm.comparison : cmp, equal;
|
||||||
|
import std.utf : byCodeUnit;
|
||||||
|
auto r1 = "FoL".byCodeUnit;
|
||||||
|
assert(r1.toLower.cmp("fol") == 0);
|
||||||
|
auto r2 = "A\u0460B\u0461d".byCodeUnit;
|
||||||
|
assert(r2.toLower.cmp("a\u0461b\u0461d") == 0);
|
||||||
|
}
|
||||||
|
|
||||||
/++
|
/++
|
||||||
If `c` is a Unicode lowercase $(CHARACTER), then its uppercase equivalent
|
If `c` is a Unicode lowercase $(CHARACTER), then its uppercase equivalent
|
||||||
|
@ -9964,16 +9993,28 @@ dchar toUpper(dchar c)
|
||||||
}
|
}
|
||||||
|
|
||||||
/++
|
/++
|
||||||
Returns a string which is identical to `s` except that all of its
|
Allocates a new array which is identical to `s` except that all of its
|
||||||
characters are converted to uppercase (by preforming Unicode uppercase mapping).
|
characters are converted to uppercase (by preforming Unicode uppercase mapping).
|
||||||
If none of `s` characters were affected, then `s` itself is returned.
|
If none of `s` characters were affected, then `s` itself is returned if `s`
|
||||||
|
is a `string`-like type.
|
||||||
|
|
||||||
|
Params:
|
||||||
|
s = A $(REF_ALTTEXT random access range, isRandomAccessRange, std,range,primitives)
|
||||||
|
of characters
|
||||||
|
Returns:
|
||||||
|
An new array with the same element type as `s`.
|
||||||
+/
|
+/
|
||||||
S toUpper(S)(S s) @trusted pure
|
ElementEncodingType!S[] toUpper(S)(S s)
|
||||||
if (isSomeString!S)
|
if (isSomeString!S || (isRandomAccessRange!S && hasLength!S && hasSlicing!S && isSomeChar!(ElementType!S)))
|
||||||
{
|
{
|
||||||
static import std.ascii;
|
static import std.ascii;
|
||||||
|
|
||||||
|
static if (isSomeString!S)
|
||||||
|
return () @trusted { return toCase!(UpperTriple, std.ascii.toUpper)(s); } ();
|
||||||
|
else
|
||||||
return toCase!(UpperTriple, std.ascii.toUpper)(s);
|
return toCase!(UpperTriple, std.ascii.toUpper)(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
// overloads for the most common cases to reduce compile time
|
// overloads for the most common cases to reduce compile time
|
||||||
@safe pure /*TODO nothrow*/
|
@safe pure /*TODO nothrow*/
|
||||||
{
|
{
|
||||||
|
@ -10087,6 +10128,16 @@ if (isSomeString!S)
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// test random access ranges
|
||||||
|
@safe pure unittest
|
||||||
|
{
|
||||||
|
import std.algorithm.comparison : cmp;
|
||||||
|
import std.utf : byCodeUnit;
|
||||||
|
auto s1 = "FoL".byCodeUnit;
|
||||||
|
assert(s1.toUpper.cmp("FOL") == 0);
|
||||||
|
auto s2 = "a\u0460B\u0461d".byCodeUnit;
|
||||||
|
assert(s2.toUpper.cmp("A\u0460B\u0460D") == 0);
|
||||||
|
}
|
||||||
|
|
||||||
/++
|
/++
|
||||||
Returns whether `c` is a Unicode alphabetic $(CHARACTER)
|
Returns whether `c` is a Unicode alphabetic $(CHARACTER)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue