Replace is(Unqual!T == Unqual!U) with is(immutable T == immutable U) for speed & memory usage

This commit is contained in:
Nathan Sashihara 2020-08-02 09:54:29 -07:00 committed by The Dlang Bot
parent a4d8029c48
commit 453faadf5b
31 changed files with 169 additions and 173 deletions

View file

@ -623,7 +623,8 @@ if (isInputRange!R1 && isInputRange!R2)
static if (isDynamicArray!R1 && isDynamicArray!R2 static if (isDynamicArray!R1 && isDynamicArray!R2
&& __traits(isUnsigned, E1) && __traits(isUnsigned, E2) && __traits(isUnsigned, E1) && __traits(isUnsigned, E2)
&& E1.sizeof == 1 && E2.sizeof == 1 && E1.sizeof == 1 && E2.sizeof == 1
&& (is(Unqual!E1 == char) == is(Unqual!E2 == char))) // Both or neither must auto-decode. // Both or neither must auto-decode.
&& (is(immutable E1 == immutable char) == is(immutable E2 == immutable char)))
{ {
// dstrcmp algorithm is correct for both ubyte[] and for char[]. // dstrcmp algorithm is correct for both ubyte[] and for char[].
import core.internal.string : dstrcmp; import core.internal.string : dstrcmp;

View file

@ -5486,8 +5486,8 @@ if (isSomeString!Range ||
import std.uni : isWhite; import std.uni : isWhite;
import std.traits : Unqual; import std.traits : Unqual;
static if (is(Unqual!(ElementEncodingType!Range) == wchar) && static if (is(immutable ElementEncodingType!Range == immutable wchar) &&
is(Unqual!(ElementType!Range) == dchar)) is(immutable ElementType!Range == immutable dchar))
{ {
// all unicode whitespace characters fit into a wchar. However, // all unicode whitespace characters fit into a wchar. However,
// this range is a wchar array, so we will treat it like a // this range is a wchar array, so we will treat it like a
@ -5500,8 +5500,8 @@ if (isSomeString!Range ||
break; break;
} }
} }
else static if (is(Unqual!(ElementType!Range) == dchar) || else static if (is(immutable ElementType!Range == immutable dchar) ||
is(Unqual!(ElementType!Range) == wchar)) is(immutable ElementType!Range == immutable wchar))
{ {
// dchar or wchar range, we can just use find. // dchar or wchar range, we can just use find.
auto r = find!(isWhite)(_s.save); auto r = find!(isWhite)(_s.save);

View file

@ -233,7 +233,7 @@ if (isInputRange!(Range) && is(typeof(r.front == lPar)))
{ {
size_t count; size_t count;
static if (is(Unqual!(ElementEncodingType!Range) == Unqual!E) && isNarrowString!Range) static if (is(immutable ElementEncodingType!Range == immutable E) && isNarrowString!Range)
{ {
import std.utf : byCodeUnit; import std.utf : byCodeUnit;
auto rn = r.byCodeUnit; auto rn = r.byCodeUnit;
@ -1106,7 +1106,7 @@ if (isBidirectionalRange!R1 &&
enum isDefaultPred = false; enum isDefaultPred = false;
static if (isDefaultPred && isArray!R1 && isArray!R2 && static if (isDefaultPred && isArray!R1 && isArray!R2 &&
is(Unqual!(ElementEncodingType!R1) == Unqual!(ElementEncodingType!R2))) is(immutable ElementEncodingType!R1 == immutable ElementEncodingType!R2))
{ {
if (haystack.length < needle.length) return false; if (haystack.length < needle.length) return false;
@ -4614,7 +4614,7 @@ if (isInputRange!Range && Needles.length > 1 &&
template checkType(T) template checkType(T)
{ {
enum checkType = is(Unqual!(ElementEncodingType!Range) == Unqual!T); enum checkType = is(immutable ElementEncodingType!Range == immutable T);
} }
// auto-decoding special case // auto-decoding special case
@ -4719,7 +4719,7 @@ if (isInputRange!R1 &&
} }
static if (isDefaultPred && isArray!R1 && isArray!R2 && static if (isDefaultPred && isArray!R1 && isArray!R2 &&
is(Unqual!(ElementEncodingType!R1) == Unqual!(ElementEncodingType!R2))) is(immutable ElementEncodingType!R1 == immutable ElementEncodingType!R2))
{ {
//Array slice comparison mode //Array slice comparison mode
return haystack[0 .. needle.length] == needle; return haystack[0 .. needle.length] == needle;

View file

@ -1942,7 +1942,7 @@ ElementEncodingType!(ElementType!RoR)[] join(RoR, R)(RoR ror, scope R sep)
if (isInputRange!RoR && if (isInputRange!RoR &&
isInputRange!(Unqual!(ElementType!RoR)) && isInputRange!(Unqual!(ElementType!RoR)) &&
isInputRange!R && isInputRange!R &&
is(Unqual!(ElementType!(ElementType!RoR)) == Unqual!(ElementType!R))) is(immutable ElementType!(ElementType!RoR) == immutable ElementType!R))
{ {
alias RetType = typeof(return); alias RetType = typeof(return);
alias RetTypeElement = Unqual!(ElementEncodingType!RetType); alias RetTypeElement = Unqual!(ElementEncodingType!RetType);

View file

@ -194,7 +194,7 @@ public:
} }
/// Construct a `BigInt` from another `BigInt`. /// Construct a `BigInt` from another `BigInt`.
this(T)(T x) pure nothrow @safe if (is(Unqual!T == BigInt)) this(T)(T x) pure nothrow @safe if (is(immutable T == immutable BigInt))
{ {
opAssign(x); opAssign(x);
} }
@ -514,11 +514,11 @@ public:
// BigInt % long => long // BigInt % long => long
// BigInt % ulong => BigInt // BigInt % ulong => BigInt
// BigInt % other_type => int // BigInt % other_type => int
static if (is(Unqual!T == long) || is(Unqual!T == ulong)) static if (is(immutable T == immutable long) || is(immutable T == immutable ulong))
{ {
auto r = this % BigInt(y); auto r = this % BigInt(y);
static if (is(Unqual!T == long)) static if (is(immutable T == immutable long))
{ {
return r.toLong(); return r.toLong();
} }
@ -531,7 +531,7 @@ public:
else else
{ {
immutable uint u = absUnsign(y); immutable uint u = absUnsign(y);
static if (is(Unqual!T == uint)) static if (is(immutable T == immutable uint))
alias R = long; alias R = long;
else else
alias R = int; alias R = int;
@ -1021,7 +1021,7 @@ public:
system guarantees. Use with care. system guarantees. Use with care.
*/ */
T opCast(T)() pure nothrow @nogc const T opCast(T)() pure nothrow @nogc const
if (is(Unqual!T == BigInt)) if (is(immutable T == immutable BigInt))
{ {
return this; return this;
} }

View file

@ -265,7 +265,7 @@ private struct RangeT(A)
* instead of `array.map!`). The container itself is not a range. * instead of `array.map!`). The container itself is not a range.
*/ */
struct Array(T) struct Array(T)
if (!is(Unqual!T == bool)) if (!is(immutable T == immutable bool))
{ {
import core.memory : free = pureFree; import core.memory : free = pureFree;
import std.internal.memory : enforceMalloc, enforceRealloc; import std.internal.memory : enforceMalloc, enforceRealloc;
@ -1624,7 +1624,7 @@ if (!is(Unqual!T == bool))
* allocating one bit per element. * allocating one bit per element.
*/ */
struct Array(T) struct Array(T)
if (is(Unqual!T == bool)) if (is(immutable T == immutable bool))
{ {
import std.exception : enforce; import std.exception : enforce;
import std.typecons : RefCounted, RefCountedAutoInitialize; import std.typecons : RefCounted, RefCountedAutoInitialize;

View file

@ -167,7 +167,7 @@ private
template isNullToStr(S, T) template isNullToStr(S, T)
{ {
enum isNullToStr = isImplicitlyConvertible!(S, T) && enum isNullToStr = isImplicitlyConvertible!(S, T) &&
(is(Unqual!S == typeof(null))) && isExactSomeString!T; (is(immutable S == immutable typeof(null))) && isExactSomeString!T;
} }
} }
@ -2187,7 +2187,7 @@ Note:
Target parse(Target, Source)(ref Source source) Target parse(Target, Source)(ref Source source)
if (isInputRange!Source && if (isInputRange!Source &&
isSomeChar!(ElementType!Source) && isSomeChar!(ElementType!Source) &&
is(Unqual!Target == bool)) is(immutable Target == immutable bool))
{ {
import std.ascii : toLower; import std.ascii : toLower;
@ -3470,11 +3470,11 @@ Throws:
*/ */
Target parse(Target, Source)(ref Source s) Target parse(Target, Source)(ref Source s)
if (isSomeString!Source && !is(Source == enum) && if (isSomeString!Source && !is(Source == enum) &&
staticIndexOf!(Unqual!Target, dchar, Unqual!(ElementEncodingType!Source)) >= 0) staticIndexOf!(immutable Target, immutable dchar, immutable ElementEncodingType!Source) >= 0)
{ {
if (s.empty) if (s.empty)
throw convError!(Source, Target)(s); throw convError!(Source, Target)(s);
static if (is(Unqual!Target == dchar)) static if (is(immutable Target == immutable dchar))
{ {
Target result = s.front; Target result = s.front;
s.popFront(); s.popFront();
@ -3495,7 +3495,7 @@ if (isSomeString!Source && !is(Source == enum) &&
{ {
static foreach (Char; AliasSeq!(char, wchar, dchar)) static foreach (Char; AliasSeq!(char, wchar, dchar))
{{ {{
static if (is(Unqual!Char == dchar) || static if (is(immutable Char == immutable dchar) ||
Char.sizeof == ElementEncodingType!Str.sizeof) Char.sizeof == ElementEncodingType!Str.sizeof)
{ {
Str s = "aaa"; Str s = "aaa";
@ -3573,7 +3573,7 @@ Throws:
Target parse(Target, Source)(ref Source s) Target parse(Target, Source)(ref Source s)
if (isInputRange!Source && if (isInputRange!Source &&
isSomeChar!(ElementType!Source) && isSomeChar!(ElementType!Source) &&
is(Unqual!Target == typeof(null))) is(immutable Target == immutable typeof(null)))
{ {
import std.ascii : toLower; import std.ascii : toLower;
foreach (c; "null") foreach (c; "null")
@ -4224,8 +4224,8 @@ private S textImpl(S, U...)(U args)
app.put(arg); app.put(arg);
else static if ( else static if (
is(Unqual!(typeof(arg)) == uint) || is(Unqual!(typeof(arg)) == ulong) || is(immutable typeof(arg) == immutable uint) || is(immutable typeof(arg) == immutable ulong) ||
is(Unqual!(typeof(arg)) == int) || is(Unqual!(typeof(arg)) == long) is(immutable typeof(arg) == immutable int) || is(immutable typeof(arg) == immutable long)
) )
// https://issues.dlang.org/show_bug.cgi?id=17712#c15 // https://issues.dlang.org/show_bug.cgi?id=17712#c15
app.put(textImpl!(S)(arg)); app.put(textImpl!(S)(arg));
@ -6291,8 +6291,8 @@ private auto hexStrLiteral(String)(scope String hexData)
auto toChars(ubyte radix = 10, Char = char, LetterCase letterCase = LetterCase.lower, T)(T value) auto toChars(ubyte radix = 10, Char = char, LetterCase letterCase = LetterCase.lower, T)(T value)
pure nothrow @nogc @safe pure nothrow @nogc @safe
if ((radix == 2 || radix == 8 || radix == 10 || radix == 16) && if ((radix == 2 || radix == 8 || radix == 10 || radix == 16) &&
(is(Unqual!T == uint) || is(Unqual!T == ulong) || (is(immutable T == immutable uint) || is(immutable T == immutable ulong) ||
radix == 10 && (is(Unqual!T == int) || is(Unqual!T == long)))) radix == 10 && (is(immutable T == immutable int) || is(immutable T == immutable long))))
{ {
alias UT = Unqual!T; alias UT = Unqual!T;

View file

@ -339,7 +339,7 @@ Throws:
*/ */
auto csvReader(Contents = string,Malformed ErrorLevel = Malformed.throwException, Range, Separator = char)(Range input, auto csvReader(Contents = string,Malformed ErrorLevel = Malformed.throwException, Range, Separator = char)(Range input,
Separator delimiter = ',', Separator quote = '"') Separator delimiter = ',', Separator quote = '"')
if (isInputRange!Range && is(Unqual!(ElementType!Range) == dchar) if (isInputRange!Range && is(immutable ElementType!Range == immutable dchar)
&& isSomeChar!(Separator) && isSomeChar!(Separator)
&& !is(Contents T : T[U], U : string)) && !is(Contents T : T[U], U : string))
{ {
@ -354,7 +354,7 @@ auto csvReader(Contents = string,
Range, Header, Separator = char) Range, Header, Separator = char)
(Range input, Header header, (Range input, Header header,
Separator delimiter = ',', Separator quote = '"') Separator delimiter = ',', Separator quote = '"')
if (isInputRange!Range && is(Unqual!(ElementType!Range) == dchar) if (isInputRange!Range && is(immutable ElementType!Range == immutable dchar)
&& isSomeChar!(Separator) && isSomeChar!(Separator)
&& isForwardRange!Header && isForwardRange!Header
&& isSomeString!(ElementType!Header)) && isSomeString!(ElementType!Header))
@ -370,7 +370,7 @@ auto csvReader(Contents = string,
Range, Header, Separator = char) Range, Header, Separator = char)
(Range input, Header header, (Range input, Header header,
Separator delimiter = ',', Separator quote = '"') Separator delimiter = ',', Separator quote = '"')
if (isInputRange!Range && is(Unqual!(ElementType!Range) == dchar) if (isInputRange!Range && is(immutable ElementType!Range == immutable dchar)
&& isSomeChar!(Separator) && isSomeChar!(Separator)
&& is(Header : typeof(null))) && is(Header : typeof(null)))
{ {
@ -834,7 +834,7 @@ private pure struct Input(Range, Malformed ErrorLevel)
*/ */
private struct CsvReader(Contents, Malformed ErrorLevel, Range, Separator, Header) private struct CsvReader(Contents, Malformed ErrorLevel, Range, Separator, Header)
if (isSomeChar!Separator && isInputRange!Range if (isSomeChar!Separator && isInputRange!Range
&& is(Unqual!(ElementType!Range) == dchar) && is(immutable ElementType!Range == immutable dchar)
&& isForwardRange!Header && isSomeString!(ElementType!Header)) && isForwardRange!Header && isSomeString!(ElementType!Header))
{ {
private: private:
@ -1417,7 +1417,7 @@ void csvNextToken(Range, Malformed ErrorLevel = Malformed.throwException,
Separator sep, Separator quote, Separator sep, Separator quote,
bool startQuoted = false) bool startQuoted = false)
if (isSomeChar!Separator && isInputRange!Range if (isSomeChar!Separator && isInputRange!Range
&& is(Unqual!(ElementType!Range) == dchar) && is(immutable ElementType!Range == immutable dchar)
&& isOutputRange!(Output, dchar)) && isOutputRange!(Output, dchar))
{ {
bool quoted = startQuoted; bool quoted = startQuoted;

View file

@ -39,7 +39,7 @@ import std.datetime.date : AllowDayOverflow, DateTimeException, daysToDayOfWeek,
DayOfWeek, isTimePoint, Month; DayOfWeek, isTimePoint, Month;
import std.exception : enforce; import std.exception : enforce;
import std.range.primitives : isOutputRange; import std.range.primitives : isOutputRange;
import std.traits : isIntegral, Unqual; import std.traits : isIntegral;
import std.typecons : Flag; import std.typecons : Flag;
version (StdUnittest) import std.exception : assertThrown; version (StdUnittest) import std.exception : assertThrown;
@ -137,7 +137,7 @@ public:
-------------------- --------------------
+/ +/
this(U)(scope const TP begin, scope const U end) pure this(U)(scope const TP begin, scope const U end) pure
if (is(Unqual!TP == Unqual!U)) if (is(immutable TP == immutable U))
{ {
if (!_valid(begin, end)) if (!_valid(begin, end))
throw new DateTimeException("Arguments would result in an invalid Interval."); throw new DateTimeException("Arguments would result in an invalid Interval.");

View file

@ -86,7 +86,7 @@ import std.datetime.timezone;// : LocalTime, SimpleTimeZone, TimeZone, UTC;
import std.exception : enforce; import std.exception : enforce;
import std.format : format; import std.format : format;
import std.range.primitives; import std.range.primitives;
import std.traits : isIntegral, isSigned, isSomeString, Unqual, isNarrowString; import std.traits : isIntegral, isSigned, isSomeString, isNarrowString;
version (Windows) version (Windows)
{ {
@ -7916,7 +7916,7 @@ public:
Returns a $(REF Date,std,datetime,date) equivalent to this $(LREF SysTime). Returns a $(REF Date,std,datetime,date) equivalent to this $(LREF SysTime).
+/ +/
Date opCast(T)() @safe const nothrow scope Date opCast(T)() @safe const nothrow scope
if (is(Unqual!T == Date)) if (is(immutable T == immutable Date))
{ {
return Date(dayOfGregorianCal); return Date(dayOfGregorianCal);
} }
@ -7957,7 +7957,7 @@ public:
$(LREF SysTime). $(LREF SysTime).
+/ +/
DateTime opCast(T)() @safe const nothrow scope DateTime opCast(T)() @safe const nothrow scope
if (is(Unqual!T == DateTime)) if (is(immutable T == immutable DateTime))
{ {
try try
{ {
@ -8023,7 +8023,7 @@ public:
$(LREF SysTime). $(LREF SysTime).
+/ +/
TimeOfDay opCast(T)() @safe const nothrow scope TimeOfDay opCast(T)() @safe const nothrow scope
if (is(Unqual!T == TimeOfDay)) if (is(immutable T == immutable TimeOfDay))
{ {
try try
{ {
@ -8080,7 +8080,7 @@ public:
// should be allowed, and it doesn't work without this opCast() since opCast() // should be allowed, and it doesn't work without this opCast() since opCast()
// has already been defined for other types. // has already been defined for other types.
SysTime opCast(T)() @safe const pure nothrow scope SysTime opCast(T)() @safe const pure nothrow scope
if (is(Unqual!T == SysTime)) if (is(immutable T == immutable SysTime))
{ {
return SysTime(_stdTime, _timezone); return SysTime(_stdTime, _timezone);
} }
@ -10244,7 +10244,7 @@ SysTime parseRFC822DateTime()(scope const char[] value) @safe
/++ Ditto +/ /++ Ditto +/
SysTime parseRFC822DateTime(R)(scope R value) SysTime parseRFC822DateTime(R)(scope R value)
if (isRandomAccessRange!R && hasSlicing!R && hasLength!R && if (isRandomAccessRange!R && hasSlicing!R && hasLength!R &&
(is(Unqual!(ElementType!R) == char) || is(Unqual!(ElementType!R) == ubyte))) (is(immutable ElementType!R == immutable char) || is(immutable ElementType!R == immutable ubyte)))
{ {
import std.algorithm.searching : find, all; import std.algorithm.searching : find, all;
import std.ascii : isDigit, isAlpha, isPrintable; import std.ascii : isDigit, isAlpha, isPrintable;
@ -11215,7 +11215,7 @@ if (validTimeUnits(units) &&
+/ +/
R _stripCFWS(R)(R range) R _stripCFWS(R)(R range)
if (isRandomAccessRange!R && hasSlicing!R && hasLength!R && if (isRandomAccessRange!R && hasSlicing!R && hasLength!R &&
(is(Unqual!(ElementType!R) == char) || is(Unqual!(ElementType!R) == ubyte))) (is(immutable ElementType!R == immutable char) || is(immutable ElementType!R == immutable ubyte)))
{ {
immutable e = range.length; immutable e = range.length;
outer: for (size_t i = 0; i < e; ) outer: for (size_t i = 0; i < e; )

View file

@ -31,7 +31,7 @@ module std.datetime.timezone;
import core.time : abs, convert, dur, Duration, hours, minutes; import core.time : abs, convert, dur, Duration, hours, minutes;
import std.datetime.systime : Clock, stdTimeToUnixTime, SysTime; import std.datetime.systime : Clock, stdTimeToUnixTime, SysTime;
import std.range.primitives : back, empty, front, isOutputRange, popFront; import std.range.primitives : back, empty, front, isOutputRange, popFront;
import std.traits : isIntegral, isSomeString, Unqual; import std.traits : isIntegral, isSomeString;
version (OSX) version (OSX)
version = Darwin; version = Darwin;
@ -2633,7 +2633,7 @@ private:
Reads an int from a TZ file. Reads an int from a TZ file.
+/ +/
static T readVal(T)(ref File tzFile) @trusted static T readVal(T)(ref File tzFile) @trusted
if ((isIntegral!T || isSomeChar!T) || is(Unqual!T == bool)) if ((isIntegral!T || isSomeChar!T) || is(immutable T == immutable bool))
{ {
import std.bitmanip : bigEndianToNative; import std.bitmanip : bigEndianToNative;
T[1] buff; T[1] buff;

View file

@ -2175,7 +2175,7 @@ output range `R`. Returns the number of `E`s written.
size_t encode(E, R)(dchar c, auto ref R range) size_t encode(E, R)(dchar c, auto ref R range)
if (isNativeOutputRange!(R, E)) if (isNativeOutputRange!(R, E))
{ {
static if (is(Unqual!E == char)) static if (is(immutable E == immutable char))
{ {
if (c <= 0x7F) if (c <= 0x7F)
{ {
@ -2208,7 +2208,7 @@ if (isNativeOutputRange!(R, E))
assert(0); assert(0);
} }
} }
else static if (is(Unqual!E == wchar)) else static if (is(immutable E == immutable wchar))
{ {
if (c <= 0xFFFF) if (c <= 0xFFFF)
{ {
@ -2219,7 +2219,7 @@ if (isNativeOutputRange!(R, E))
range.put(cast(wchar) (((c - 0x10000) & 0x3FF) + 0xDC00)); range.put(cast(wchar) (((c - 0x10000) & 0x3FF) + 0xDC00));
return 2; return 2;
} }
else static if (is(Unqual!E == dchar)) else static if (is(immutable E == immutable dchar))
{ {
range.put(c); range.put(c);
return 1; return 1;
@ -2420,17 +2420,17 @@ do
{ {
r = s; r = s;
} }
else static if (is(Unqual!Src == AsciiChar)) else static if (is(immutable Src == immutable AsciiChar))
{ {
transcode(cast(const(char)[])s, r); transcode(cast(const(char)[])s, r);
} }
else else
{ {
static if (is(Unqual!Dst == wchar)) static if (is(immutable Dst == immutable wchar))
{ {
immutable minReservePlace = 2; immutable minReservePlace = 2;
} }
else static if (is(Unqual!Dst == dchar)) else static if (is(immutable Dst == immutable dchar))
{ {
immutable minReservePlace = 1; immutable minReservePlace = 1;
} }
@ -3745,7 +3745,7 @@ Returns:
the found `BOMSeq` corresponding to the passed `input`. the found `BOMSeq` corresponding to the passed `input`.
*/ */
immutable(BOMSeq) getBOM(Range)(Range input) immutable(BOMSeq) getBOM(Range)(Range input)
if (isForwardRange!Range && is(Unqual!(ElementType!Range) == ubyte)) if (isForwardRange!Range && is(immutable ElementType!Range == immutable ubyte))
{ {
import std.algorithm.searching : startsWith; import std.algorithm.searching : startsWith;
foreach (it; bomTable[1 .. $]) foreach (it; bomTable[1 .. $])

View file

@ -1493,7 +1493,7 @@ private T[] uninitializedFillDefault(T)(T[] array) nothrow
memset(array.ptr, 0, T.sizeof * array.length); memset(array.ptr, 0, T.sizeof * array.length);
return array; return array;
} }
else static if (is(Unqual!T == char) || is(Unqual!T == wchar)) else static if (is(immutable T == immutable char) || is(immutable T == immutable wchar))
{ {
import core.stdc.string : memset; import core.stdc.string : memset;
if (array !is null) if (array !is null)

View file

@ -1368,7 +1368,7 @@ abstract class Logger
string moduleName = __MODULE__, A...)(lazy A args) string moduleName = __MODULE__, A...)(lazy A args)
if ((args.length > 1 if ((args.length > 1
&& !is(Unqual!(A[0]) : bool) && !is(Unqual!(A[0]) : bool)
&& !is(Unqual!(A[0]) == LogLevel)) && !is(immutable A[0] == immutable LogLevel))
|| args.length == 0) || args.length == 0)
{ {
static if (isLoggingActive) synchronized (mutex) static if (isLoggingActive) synchronized (mutex)

View file

@ -316,7 +316,7 @@ void[] read(R)(R name, size_t upTo = size_t.max)
if (isInputRange!R && isSomeChar!(ElementEncodingType!R) && !isInfinite!R && if (isInputRange!R && isSomeChar!(ElementEncodingType!R) && !isInfinite!R &&
!isConvertibleToString!R) !isConvertibleToString!R)
{ {
static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == char)) static if (isNarrowString!R && is(immutable ElementEncodingType!R == immutable char))
return readImpl(name, name.tempCString!FSChar(), upTo); return readImpl(name, name.tempCString!FSChar(), upTo);
else else
return readImpl(null, name.tempCString!FSChar(), upTo); return readImpl(null, name.tempCString!FSChar(), upTo);
@ -521,7 +521,7 @@ if (isSomeString!S && (isInputRange!R && !isInfinite!R && isSomeChar!(ElementTyp
immutable bomSeq = getBOM(data); immutable bomSeq = getBOM(data);
immutable bom = bomSeq.schema; immutable bom = bomSeq.schema;
static if (is(Unqual!(ElementEncodingType!S) == char)) static if (is(immutable ElementEncodingType!S == immutable char))
{ {
with(BOM) switch (bom) with(BOM) switch (bom)
{ {
@ -532,7 +532,7 @@ if (isSomeString!S && (isInputRange!R && !isInfinite!R && isSomeChar!(ElementTyp
default: break; default: break;
} }
} }
else static if (is(Unqual!(ElementEncodingType!S) == wchar)) else static if (is(immutable ElementEncodingType!S == immutable wchar))
{ {
with(BOM) switch (bom) with(BOM) switch (bom)
{ {
@ -741,7 +741,7 @@ void write(R)(R name, const void[] buffer)
if ((isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) || isSomeString!R) && if ((isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) || isSomeString!R) &&
!isConvertibleToString!R) !isConvertibleToString!R)
{ {
static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == char)) static if (isNarrowString!R && is(immutable ElementEncodingType!R == immutable char))
writeImpl(name, name.tempCString!FSChar(), buffer, false); writeImpl(name, name.tempCString!FSChar(), buffer, false);
else else
writeImpl(null, name.tempCString!FSChar(), buffer, false); writeImpl(null, name.tempCString!FSChar(), buffer, false);
@ -788,7 +788,7 @@ void append(R)(R name, const void[] buffer)
if ((isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) || isSomeString!R) && if ((isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) || isSomeString!R) &&
!isConvertibleToString!R) !isConvertibleToString!R)
{ {
static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == char)) static if (isNarrowString!R && is(immutable ElementEncodingType!R == immutable char))
writeImpl(name, name.tempCString!FSChar(), buffer, true); writeImpl(name, name.tempCString!FSChar(), buffer, true);
else else
writeImpl(null, name.tempCString!FSChar(), buffer, true); writeImpl(null, name.tempCString!FSChar(), buffer, true);
@ -922,12 +922,12 @@ if ((isInputRange!RF && !isInfinite!RF && isSomeChar!(ElementEncodingType!RF) ||
auto fromz = from.tempCString!FSChar(); auto fromz = from.tempCString!FSChar();
auto toz = to.tempCString!FSChar(); auto toz = to.tempCString!FSChar();
static if (isNarrowString!RF && is(Unqual!(ElementEncodingType!RF) == char)) static if (isNarrowString!RF && is(immutable ElementEncodingType!RF == immutable char))
alias f = from; alias f = from;
else else
enum string f = null; enum string f = null;
static if (isNarrowString!RT && is(Unqual!(ElementEncodingType!RT) == char)) static if (isNarrowString!RT && is(immutable ElementEncodingType!RT == immutable char))
alias t = to; alias t = to;
else else
enum string t = null; enum string t = null;
@ -1028,7 +1028,7 @@ void remove(R)(R name)
if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) && if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
!isConvertibleToString!R) !isConvertibleToString!R)
{ {
static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == char)) static if (isNarrowString!R && is(immutable ElementEncodingType!R == immutable char))
removeImpl(name, name.tempCString!FSChar()); removeImpl(name, name.tempCString!FSChar());
else else
removeImpl(null, name.tempCString!FSChar()); removeImpl(null, name.tempCString!FSChar());
@ -1086,7 +1086,7 @@ if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R))
WIN32_FILE_ATTRIBUTE_DATA fad = void; WIN32_FILE_ATTRIBUTE_DATA fad = void;
static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == char)) static if (isNarrowString!R && is(immutable ElementEncodingType!R == immutable char))
{ {
static void getFA(scope const(char)[] name, scope const(FSChar)* namez, static void getFA(scope const(char)[] name, scope const(FSChar)* namez,
out WIN32_FILE_ATTRIBUTE_DATA fad) @trusted out WIN32_FILE_ATTRIBUTE_DATA fad) @trusted
@ -1148,7 +1148,7 @@ if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
{ {
return stat(namez, &buf); return stat(namez, &buf);
} }
static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == char)) static if (isNarrowString!R && is(immutable ElementEncodingType!R == immutable char))
alias names = name; alias names = name;
else else
string names = null; string names = null;
@ -1255,7 +1255,7 @@ if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
} }
stat_t statbuf = void; stat_t statbuf = void;
static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == char)) static if (isNarrowString!R && is(immutable ElementEncodingType!R == immutable char))
alias names = name; alias names = name;
else else
string names = null; string names = null;
@ -1553,7 +1553,7 @@ if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
HANDLE.init); HANDLE.init);
auto h = trustedCreateFileW(namez, defaults); auto h = trustedCreateFileW(namez, defaults);
static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == char)) static if (isNarrowString!R && is(immutable ElementEncodingType!R == immutable char))
alias names = name; alias names = name;
else else
string names = null; string names = null;
@ -1578,7 +1578,7 @@ if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
t[0] = accessTime.toTimeSpec(); t[0] = accessTime.toTimeSpec();
t[1] = modificationTime.toTimeSpec(); t[1] = modificationTime.toTimeSpec();
static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == char)) static if (isNarrowString!R && is(immutable ElementEncodingType!R == immutable char))
alias names = name; alias names = name;
else else
string names = null; string names = null;
@ -1586,7 +1586,7 @@ if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
} }
else else
{ {
static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == char)) static if (isNarrowString!R && is(immutable ElementEncodingType!R == immutable char))
alias names = name; alias names = name;
else else
string names = null; string names = null;
@ -1718,7 +1718,7 @@ if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
} }
stat_t statbuf = void; stat_t statbuf = void;
static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == char)) static if (isNarrowString!R && is(immutable ElementEncodingType!R == immutable char))
alias names = name; alias names = name;
else else
string names = null; string names = null;
@ -2055,7 +2055,7 @@ if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
} }
immutable result = trustedGetFileAttributesW(namez); immutable result = trustedGetFileAttributesW(namez);
static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == char)) static if (isNarrowString!R && is(immutable ElementEncodingType!R == immutable char))
alias names = name; alias names = name;
else else
string names = null; string names = null;
@ -2072,7 +2072,7 @@ if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
} }
stat_t statbuf = void; stat_t statbuf = void;
static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == char)) static if (isNarrowString!R && is(immutable ElementEncodingType!R == immutable char))
alias names = name; alias names = name;
else else
string names = null; string names = null;
@ -2163,7 +2163,7 @@ if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
return lstat(namez, &buf); return lstat(namez, &buf);
} }
stat_t lstatbuf = void; stat_t lstatbuf = void;
static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == char)) static if (isNarrowString!R && is(immutable ElementEncodingType!R == immutable char))
alias names = name; alias names = name;
else else
string names = null; string names = null;
@ -2267,7 +2267,7 @@ if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
{ {
return SetFileAttributesW(namez, dwFileAttributes); return SetFileAttributesW(namez, dwFileAttributes);
} }
static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == char)) static if (isNarrowString!R && is(immutable ElementEncodingType!R == immutable char))
alias names = name; alias names = name;
else else
string names = null; string names = null;
@ -2281,7 +2281,7 @@ if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
return chmod(namez, mode); return chmod(namez, mode);
} }
assert(attributes <= mode_t.max); assert(attributes <= mode_t.max);
static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == char)) static if (isNarrowString!R && is(immutable ElementEncodingType!R == immutable char))
alias names = name; alias names = name;
else else
string names = null; string names = null;
@ -2923,7 +2923,7 @@ if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
return core.sys.posix.unistd.chdir(pathz) == 0; return core.sys.posix.unistd.chdir(pathz) == 0;
} }
} }
static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == char)) static if (isNarrowString!R && is(immutable ElementEncodingType!R == immutable char))
alias pathStr = pathname; alias pathStr = pathname;
else else
string pathStr = null; string pathStr = null;
@ -2984,7 +2984,7 @@ if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
{ {
return CreateDirectoryW(pathz, null); return CreateDirectoryW(pathz, null);
} }
static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == char)) static if (isNarrowString!R && is(immutable ElementEncodingType!R == immutable char))
alias pathStr = pathname; alias pathStr = pathname;
else else
string pathStr = null; string pathStr = null;
@ -2998,7 +2998,7 @@ if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
{ {
return core.sys.posix.sys.stat.mkdir(pathz, mode); return core.sys.posix.sys.stat.mkdir(pathz, mode);
} }
static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == char)) static if (isNarrowString!R && is(immutable ElementEncodingType!R == immutable char))
alias pathStr = pathname; alias pathStr = pathname;
else else
string pathStr = null; string pathStr = null;
@ -3196,7 +3196,7 @@ if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
return core.sys.posix.unistd.rmdir(pathz) == 0; return core.sys.posix.unistd.rmdir(pathz) == 0;
} }
} }
static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == char)) static if (isNarrowString!R && is(immutable ElementEncodingType!R == immutable char))
alias pathStr = pathname; alias pathStr = pathname;
else else
string pathStr = null; string pathStr = null;
@ -4213,12 +4213,12 @@ if (isInputRange!RF && !isInfinite!RF && isSomeChar!(ElementEncodingType!RF) &&
auto fromz = from.tempCString!FSChar(); auto fromz = from.tempCString!FSChar();
auto toz = to.tempCString!FSChar(); auto toz = to.tempCString!FSChar();
static if (isNarrowString!RF && is(Unqual!(ElementEncodingType!RF) == char)) static if (isNarrowString!RF && is(immutable ElementEncodingType!RF == immutable char))
alias f = from; alias f = from;
else else
enum string f = null; enum string f = null;
static if (isNarrowString!RT && is(Unqual!(ElementEncodingType!RT) == char)) static if (isNarrowString!RT && is(immutable ElementEncodingType!RT == immutable char))
alias t = to; alias t = to;
else else
enum string t = null; enum string t = null;
@ -4765,7 +4765,7 @@ private struct DirIteratorImpl
_mode = mode; _mode = mode;
_followSymlink = followSymlink; _followSymlink = followSymlink;
static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == char)) static if (isNarrowString!R && is(immutable ElementEncodingType!R == immutable char))
alias pathnameStr = pathname; alias pathnameStr = pathname;
else else
{ {

View file

@ -2208,7 +2208,7 @@ if (is(BooleanTypeOf!T) && !is(T == enum) && !hasToString!(T, Char))
`null` literal is formatted as `"null"` `null` literal is formatted as `"null"`
*/ */
private void formatValueImpl(Writer, T, Char)(auto ref Writer w, T obj, scope const ref FormatSpec!Char f) private void formatValueImpl(Writer, T, Char)(auto ref Writer w, T obj, scope const ref FormatSpec!Char f)
if (is(Unqual!T == typeof(null)) && !is(T == enum) && !hasToString!(T, Char)) if (is(immutable T == immutable typeof(null)) && !is(T == enum) && !hasToString!(T, Char))
{ {
const spec = f.spec; const spec = f.spec;
enforceFmt(spec == 's', enforceFmt(spec == 's',
@ -5712,7 +5712,7 @@ T unformatValue(T, Range, Char)(ref Range input, scope const ref FormatSpec!Char
} }
private T unformatValueImpl(T, Range, Char)(ref Range input, scope const ref FormatSpec!Char spec) private T unformatValueImpl(T, Range, Char)(ref Range input, scope const ref FormatSpec!Char spec)
if (isInputRange!Range && is(Unqual!T == bool)) if (isInputRange!Range && is(immutable T == immutable bool))
{ {
import std.algorithm.searching : find; import std.algorithm.searching : find;
import std.conv : parse, text; import std.conv : parse, text;
@ -5745,9 +5745,9 @@ if (isInputRange!Range && isIntegral!T && !is(T == enum) && isSomeChar!(ElementT
if (spec.spec == 'r') if (spec.spec == 'r')
{ {
static if (is(Unqual!(ElementEncodingType!Range) == char) static if (is(immutable ElementEncodingType!Range == immutable char)
|| is(Unqual!(ElementEncodingType!Range) == byte) || is(immutable ElementEncodingType!Range == immutable byte)
|| is(Unqual!(ElementEncodingType!Range) == ubyte)) || is(immutable ElementEncodingType!Range == immutable ubyte))
return rawRead!T(input); return rawRead!T(input);
else else
throw new FormatException( throw new FormatException(
@ -5781,9 +5781,9 @@ if (isFloatingPoint!T && !is(T == enum) && isInputRange!Range
if (spec.spec == 'r') if (spec.spec == 'r')
{ {
static if (is(Unqual!(ElementEncodingType!Range) == char) static if (is(immutable ElementEncodingType!Range == immutable char)
|| is(Unqual!(ElementEncodingType!Range) == byte) || is(immutable ElementEncodingType!Range == immutable byte)
|| is(Unqual!(ElementEncodingType!Range) == ubyte)) || is(immutable ElementEncodingType!Range == immutable ubyte))
return rawRead!T(input); return rawRead!T(input);
else else
throw new FormatException( throw new FormatException(
@ -5914,9 +5914,9 @@ if (isInputRange!Range && isAssociativeArray!T && !is(T == enum))
* for integral and float types. * for integral and float types.
*/ */
private T rawRead(T, Range)(ref Range input) private T rawRead(T, Range)(ref Range input)
if (is(Unqual!(ElementEncodingType!Range) == char) if (is(immutable ElementEncodingType!Range == immutable char)
|| is(Unqual!(ElementEncodingType!Range) == byte) || is(immutable ElementEncodingType!Range == immutable byte)
|| is(Unqual!(ElementEncodingType!Range) == ubyte)) || is(immutable ElementEncodingType!Range == immutable ubyte))
{ {
union X union X
{ {

View file

@ -880,7 +880,7 @@ public:
// return x / y // return x / y
static BigUint divInt(T)(BigUint x, T y_) pure nothrow @safe static BigUint divInt(T)(BigUint x, T y_) pure nothrow @safe
if ( is(Unqual!T == uint) ) if ( is(immutable T == immutable uint) )
{ {
uint y = y_; uint y = y_;
if (y == 1) if (y == 1)
@ -906,7 +906,7 @@ public:
} }
static BigUint divInt(T)(BigUint x, T y) pure nothrow @safe static BigUint divInt(T)(BigUint x, T y) pure nothrow @safe
if ( is(Unqual!T == ulong) ) if ( is(immutable T == immutable ulong) )
{ {
if (y <= uint.max) if (y <= uint.max)
return divInt!uint(x, cast(uint) y); return divInt!uint(x, cast(uint) y);
@ -921,7 +921,7 @@ public:
} }
// return x % y // return x % y
static uint modInt(T)(BigUint x, T y_) pure if ( is(Unqual!T == uint) ) static uint modInt(T)(BigUint x, T y_) pure if ( is(immutable T == immutable uint) )
{ {
import core.memory : GC; import core.memory : GC;
uint y = y_; uint y = y_;

View file

@ -421,7 +421,6 @@ if (is(T == TestFoo))
{ {
import std.algorithm.comparison : equal; import std.algorithm.comparison : equal;
import std.range : iota, retro, repeat; import std.range : iota, retro, repeat;
import std.traits : Unqual;
static void testInputRange(T,Cmp)() static void testInputRange(T,Cmp)()
{ {
@ -431,7 +430,7 @@ if (is(T == TestFoo))
{ {
if (numRuns == 1) if (numRuns == 1)
{ {
static if (is(Unqual!(ElementType!(T)) == uint)) static if (is(immutable ElementType!(T) == immutable uint))
{ {
it.reinit(); it.reinit();
} }

View file

@ -371,11 +371,11 @@ struct JSONValue
*/ */
@property inout(T) get(T)() inout const pure @safe @property inout(T) get(T)() inout const pure @safe
{ {
static if (is(Unqual!T == string)) static if (is(immutable T == immutable string))
{ {
return str; return str;
} }
else static if (is(Unqual!T == bool)) else static if (is(immutable T == immutable bool))
{ {
return boolean; return boolean;
} }

View file

@ -295,14 +295,14 @@ enum real SQRT1_2 = SQRT2/2; /** $(SQRT)$(HALF)
* Does not work correctly for signed intergal types and value `Num`.min. * Does not work correctly for signed intergal types and value `Num`.min.
*/ */
auto abs(Num)(Num x) @nogc pure nothrow auto abs(Num)(Num x) @nogc pure nothrow
if ((is(Unqual!Num == short) || is(Unqual!Num == byte)) || if ((is(immutable Num == immutable short) || is(immutable Num == immutable byte)) ||
(is(typeof(Num.init >= 0)) && is(typeof(-Num.init)))) (is(typeof(Num.init >= 0)) && is(typeof(-Num.init))))
{ {
static if (isFloatingPoint!(Num)) static if (isFloatingPoint!(Num))
return fabs(x); return fabs(x);
else else
{ {
static if (is(Unqual!Num == short) || is(Unqual!Num == byte)) static if (is(immutable Num == immutable short) || is(immutable Num == immutable byte))
return x >= 0 ? x : cast(Num) -int(x); return x >= 0 ? x : cast(Num) -int(x);
else else
return x >= 0 ? x : -x; return x >= 0 ? x : -x;
@ -2780,7 +2780,7 @@ if (isFloatingPoint!T)
Unqual!T vf = value; Unqual!T vf = value;
ushort* vu = cast(ushort*)&vf; ushort* vu = cast(ushort*)&vf;
static if (is(Unqual!T == float)) static if (is(immutable T == immutable float))
int* vi = cast(int*)&vf; int* vi = cast(int*)&vf;
else else
long* vl = cast(long*)&vf; long* vl = cast(long*)&vf;
@ -8181,7 +8181,7 @@ in
} }
do do
{ {
static if (is(Unqual!T2 == real)) static if (is(immutable T2 == immutable real))
{ {
return polyImpl(x, A); return polyImpl(x, A);
} }

View file

@ -1783,7 +1783,7 @@ enum AsciiToken
* ) * )
*/ */
int compareFirstN(alias pred = "a < b", S1, S2) (S1 s1, S2 s2, size_t length) int compareFirstN(alias pred = "a < b", S1, S2) (S1 s1, S2 s2, size_t length)
if (is(Unqual!(ElementType!(S1)) == dchar) && is(Unqual!(ElementType!(S2)) == dchar)) if (is(immutable ElementType!(S1) == immutable dchar) && is(immutable ElementType!(S2) == immutable dchar))
{ {
import std.uni : icmp; import std.uni : icmp;
auto s1End = length <= s1.length ? length : s1.length; auto s1End = length <= s1.length ? length : s1.length;

View file

@ -488,7 +488,7 @@ public:
{ {
import std.conv : text; import std.conv : text;
static if (staticIndexOf!(Unqual!F, float, double, real) >= 0) static if (staticIndexOf!(immutable F, immutable float, immutable double, immutable real) >= 0)
auto value = ToBinary!(Unqual!F)(input); auto value = ToBinary!(Unqual!F)(input);
else else
auto value = ToBinary!(real )(input); auto value = ToBinary!(real )(input);
@ -518,7 +518,7 @@ public:
/// Fetches the stored value either as a `float`, `double` or `real`. /// Fetches the stored value either as a `float`, `double` or `real`.
@property F get(F)() @property F get(F)()
if (staticIndexOf!(Unqual!F, float, double, real) >= 0) if (staticIndexOf!(immutable F, immutable float, immutable double, immutable real) >= 0)
{ {
import std.conv : text; import std.conv : text;

View file

@ -1180,8 +1180,8 @@ private auto _stripExtension(R)(R path)
See_Also: See_Also:
$(LREF withExtension) which does not allocate and returns a lazy range. $(LREF withExtension) which does not allocate and returns a lazy range.
*/ */
immutable(Unqual!C1)[] setExtension(C1, C2)(in C1[] path, in C2[] ext) immutable(C1)[] setExtension(C1, C2)(in C1[] path, in C2[] ext)
if (isSomeChar!C1 && !is(C1 == immutable) && is(Unqual!C1 == Unqual!C2)) if (isSomeChar!C1 && !is(C1 == immutable) && is(immutable C1 == immutable C2))
{ {
try try
{ {
@ -1196,7 +1196,7 @@ if (isSomeChar!C1 && !is(C1 == immutable) && is(Unqual!C1 == Unqual!C2))
///ditto ///ditto
immutable(C1)[] setExtension(C1, C2)(immutable(C1)[] path, const(C2)[] ext) immutable(C1)[] setExtension(C1, C2)(immutable(C1)[] path, const(C2)[] ext)
if (isSomeChar!C1 && is(Unqual!C1 == Unqual!C2)) if (isSomeChar!C1 && is(immutable C1 == immutable C2))
{ {
if (ext.length == 0) if (ext.length == 0)
return stripExtension(path); return stripExtension(path);
@ -1320,8 +1320,8 @@ private auto _withExtension(R, C)(R path, C[] ext)
This function always allocates a new string, except in the case when This function always allocates a new string, except in the case when
path is immutable and already has an extension. path is immutable and already has an extension.
*/ */
immutable(Unqual!C1)[] defaultExtension(C1, C2)(in C1[] path, in C2[] ext) immutable(C1)[] defaultExtension(C1, C2)(in C1[] path, in C2[] ext)
if (isSomeChar!C1 && is(Unqual!C1 == Unqual!C2)) if (isSomeChar!C1 && is(immutable C1 == immutable C2))
{ {
import std.conv : to; import std.conv : to;
return withDefaultExtension(path, ext).to!(typeof(return)); return withDefaultExtension(path, ext).to!(typeof(return));
@ -3344,7 +3344,7 @@ bool globMatch(CaseSensitive cs = CaseSensitive.osDefault, C, Range)
@safe pure nothrow @safe pure nothrow
if (isForwardRange!Range && !isInfinite!Range && if (isForwardRange!Range && !isInfinite!Range &&
isSomeChar!(ElementEncodingType!Range) && !isConvertibleToString!Range && isSomeChar!(ElementEncodingType!Range) && !isConvertibleToString!Range &&
isSomeChar!C && is(Unqual!C == Unqual!(ElementEncodingType!Range))) isSomeChar!C && is(immutable C == immutable ElementEncodingType!Range))
in in
{ {
// Verify that pattern[] is valid // Verify that pattern[] is valid

View file

@ -2261,7 +2261,7 @@ if (isAutodecodableString!(C[]) && !isAggregateType!(C[]))
assert(str.length, "Attempting to popFront() past the end of an array of " ~ C.stringof); assert(str.length, "Attempting to popFront() past the end of an array of " ~ C.stringof);
static if (is(Unqual!C == char)) static if (is(immutable C == immutable char))
{ {
static immutable ubyte[] charWidthTab = [ static immutable ubyte[] charWidthTab = [
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@ -2274,7 +2274,7 @@ if (isAutodecodableString!(C[]) && !isAggregateType!(C[]))
immutable charWidth = c < 192 ? 1 : charWidthTab.ptr[c - 192]; immutable charWidth = c < 192 ? 1 : charWidthTab.ptr[c - 192];
str = str.ptr[min(str.length, charWidth) .. str.length]; str = str.ptr[min(str.length, charWidth) .. str.length];
} }
else static if (is(Unqual!C == wchar)) else static if (is(immutable C == immutable wchar))
{ {
immutable u = str[0]; immutable u = str[0];
immutable seqLen = 1 + (u >= 0xD800 && u <= 0xDBFF); immutable seqLen = 1 + (u >= 0xD800 && u <= 0xDBFF);

View file

@ -507,8 +507,9 @@ template ctRegexImpl(alias pattern, string flags=[])
+/ +/
public enum ctRegex(alias pattern, alias flags=[]) = ctRegexImpl!(pattern, flags).wrapper; public enum ctRegex(alias pattern, alias flags=[]) = ctRegexImpl!(pattern, flags).wrapper;
enum isRegexFor(RegEx, R) = is(Unqual!RegEx == Regex!(BasicElementOf!R)) || is(RegEx : const(Regex!(BasicElementOf!R))) enum isRegexFor(RegEx, R) = is(immutable RegEx == immutable Regex!(BasicElementOf!R))
|| is(Unqual!RegEx == StaticRegex!(BasicElementOf!R)); || is(RegEx : const(Regex!(BasicElementOf!R)))
|| is(immutable RegEx == immutable StaticRegex!(BasicElementOf!R));
/++ /++

View file

@ -2477,7 +2477,7 @@ $(REF readText, std,file)
/// ditto /// ditto
auto byLineCopy(Terminator, Char = immutable char) auto byLineCopy(Terminator, Char = immutable char)
(KeepTerminator keepTerminator, Terminator terminator) (KeepTerminator keepTerminator, Terminator terminator)
if (is(Unqual!(ElementEncodingType!Terminator) == Unqual!Char)) if (is(immutable ElementEncodingType!Terminator == immutable Char))
{ {
return ByLineCopy!(Char, Terminator)(this, keepTerminator, terminator); return ByLineCopy!(Char, Terminator)(this, keepTerminator, terminator);
} }

View file

@ -224,9 +224,9 @@ if (isSomeChar!Char)
{ {
import core.stdc.stddef : wchar_t; import core.stdc.stddef : wchar_t;
static if (is(Unqual!Char == char)) static if (is(immutable Char == immutable char))
import core.stdc.string : cstrlen = strlen; import core.stdc.string : cstrlen = strlen;
else static if (is(Unqual!Char == wchar_t)) else static if (is(immutable Char == immutable wchar_t))
import core.stdc.wchar_ : cstrlen = wcslen; import core.stdc.wchar_ : cstrlen = wcslen;
else else
static size_t cstrlen(scope const Char* s) static size_t cstrlen(scope const Char* s)
@ -1327,7 +1327,7 @@ if (isSomeChar!Char1 && isSomeChar!Char2)
if (cs == Yes.caseSensitive) if (cs == Yes.caseSensitive)
{ {
static if (is(Unqual!Char1 == Unqual!Char2)) static if (is(immutable Char1 == immutable Char2))
{ {
import core.stdc.string : memcmp; import core.stdc.string : memcmp;
@ -3013,8 +3013,8 @@ if (isForwardRange!Range && isSomeChar!(ElementEncodingType!Range) &&
static import std.ascii; static import std.ascii;
static import std.uni; static import std.uni;
static if (is(Unqual!(ElementEncodingType!Range) == dchar) static if (is(immutable ElementEncodingType!Range == immutable dchar)
|| is(Unqual!(ElementEncodingType!Range) == wchar)) || is(immutable ElementEncodingType!Range == immutable wchar))
{ {
// Decoding is never needed for dchar. It happens not to be needed // Decoding is never needed for dchar. It happens not to be needed
// here for wchar because no whitepace is outside the basic // here for wchar because no whitepace is outside the basic
@ -3715,7 +3715,7 @@ if ((isBidirectionalRange!Range && isSomeChar!(ElementEncodingType!Range) ||
alias C1 = ElementEncodingType!Range; alias C1 = ElementEncodingType!Range;
static if (is(Unqual!C1 == Unqual!C2) && (isSomeString!Range || (hasSlicing!Range && C2.sizeof == 4))) static if (is(immutable C1 == immutable C2) && (isSomeString!Range || (hasSlicing!Range && C2.sizeof == 4)))
{ {
import std.algorithm.searching : endsWith; import std.algorithm.searching : endsWith;
if (str.endsWith(delimiter)) if (str.endsWith(delimiter))
@ -3866,7 +3866,7 @@ if ((isForwardRange!Range && isSomeChar!(ElementEncodingType!Range) ||
{ {
alias C1 = ElementEncodingType!Range; alias C1 = ElementEncodingType!Range;
static if (is(Unqual!C1 == Unqual!C2) && (isSomeString!Range || (hasSlicing!Range && C2.sizeof == 4))) static if (is(immutable C1 == immutable C2) && (isSomeString!Range || (hasSlicing!Range && C2.sizeof == 4)))
{ {
import std.algorithm.searching : startsWith; import std.algorithm.searching : startsWith;
if (str.startsWith(delimiter)) if (str.startsWith(delimiter))
@ -5499,7 +5499,7 @@ private void translateImpl(C1, T, C2, Buffer)(const(C1)[] str,
+/ +/
C[] translate(C = immutable char)(scope const(char)[] str, scope const(char)[] transTable, C[] translate(C = immutable char)(scope const(char)[] str, scope const(char)[] transTable,
scope const(char)[] toRemove = null) @trusted pure nothrow scope const(char)[] toRemove = null) @trusted pure nothrow
if (is(Unqual!C == char)) if (is(immutable C == immutable char))
in in
{ {
import std.conv : to; import std.conv : to;
@ -5657,7 +5657,7 @@ do
+/ +/
void translate(C = immutable char, Buffer)(scope const(char)[] str, scope const(char)[] transTable, void translate(C = immutable char, Buffer)(scope const(char)[] str, scope const(char)[] transTable,
scope const(char)[] toRemove, Buffer buffer) @trusted pure scope const(char)[] toRemove, Buffer buffer) @trusted pure
if (is(Unqual!C == char) && isOutputRange!(Buffer, char)) if (is(immutable C == immutable char) && isOutputRange!(Buffer, char))
in in
{ {
assert(transTable.length == 256, format! assert(transTable.length == 256, format!
@ -6662,7 +6662,7 @@ if ((isInputRange!Range && isSomeChar!(Unqual!(ElementEncodingType!Range)) ||
isNarrowString!Range) && isNarrowString!Range) &&
!isConvertibleToString!Range) !isConvertibleToString!Range)
{ {
static if (is(Unqual!(ElementEncodingType!Range) == char)) static if (is(immutable ElementEncodingType!Range == immutable char))
{ {
// decoding needed for chars // decoding needed for chars
import std.utf : byDchar; import std.utf : byDchar;
@ -7148,7 +7148,7 @@ Throws:
See_Also: $(LREF representation) See_Also: $(LREF representation)
*/ */
auto assumeUTF(T)(T[] arr) auto assumeUTF(T)(T[] arr)
if (staticIndexOf!(Unqual!T, ubyte, ushort, uint) != -1) if (staticIndexOf!(immutable T, immutable ubyte, immutable ushort, immutable uint) != -1)
{ {
import std.traits : ModifyTypePreservingTQ; import std.traits : ModifyTypePreservingTQ;
import std.exception : collectException; import std.exception : collectException;

View file

@ -2657,7 +2657,7 @@ template hasNested(T)
else static if (is(T == class) || is(T == struct) || is(T == union)) else static if (is(T == class) || is(T == struct) || is(T == union))
{ {
// prevent infinite recursion for class with member of same type // prevent infinite recursion for class with member of same type
enum notSame(U) = !is(Unqual!T == Unqual!U); enum notSame(U) = !is(immutable T == immutable U);
enum hasNested = isNested!T || enum hasNested = isNested!T ||
anySatisfy!(.hasNested, Filter!(notSame, Fields!T)); anySatisfy!(.hasNested, Filter!(notSame, Fields!T));
} }
@ -5659,7 +5659,7 @@ template BooleanTypeOf(T)
else else
alias X = OriginalType!T; alias X = OriginalType!T;
static if (is(Unqual!X == bool)) static if (is(immutable X == immutable bool))
{ {
alias BooleanTypeOf = X; alias BooleanTypeOf = X;
} }
@ -6171,12 +6171,7 @@ enum bool isIntegral(T) = is(IntegralTypeOf!T) && !isAggregateType!T;
/** /**
* Detect whether `T` is a built-in floating point type. * Detect whether `T` is a built-in floating point type.
*/ */
enum bool isFloatingPoint(T) = __traits(isFloating, T) && !(is(Unqual!T == cfloat) || enum bool isFloatingPoint(T) = __traits(isFloating, T) && !is(T : ireal) && !is(T : creal);
is(Unqual!T == cdouble) ||
is(Unqual!T == creal) ||
is(Unqual!T == ifloat) ||
is(Unqual!T == idouble) ||
is(Unqual!T == ireal));
/// ///
@safe unittest @safe unittest
@ -6244,10 +6239,10 @@ enum bool isFloatingPoint(T) = __traits(isFloating, T) && !(is(Unqual!T == cfloa
* Detect whether `T` is a built-in numeric type (integral or floating * Detect whether `T` is a built-in numeric type (integral or floating
* point). * point).
*/ */
enum bool isNumeric(T) = __traits(isArithmetic, T) && !(is(Unqual!T == bool) || enum bool isNumeric(T) = __traits(isArithmetic, T) && !(is(immutable T == immutable bool) ||
is(Unqual!T == char) || is(immutable T == immutable char) ||
is(Unqual!T == wchar) || is(immutable T == immutable wchar) ||
is(Unqual!T == dchar)); is(immutable T == immutable dchar));
/// ///
@safe unittest @safe unittest
@ -6337,7 +6332,7 @@ enum bool isScalarType(T) = is(T : real) && !isAggregateType!T;
/** /**
* Detect whether `T` is a basic type (scalar type or void). * Detect whether `T` is a basic type (scalar type or void).
*/ */
enum bool isBasicType(T) = isScalarType!T || is(Unqual!T == void); enum bool isBasicType(T) = isScalarType!T || is(immutable T == immutable void);
/// ///
@safe unittest @safe unittest
@ -6360,10 +6355,10 @@ enum bool isBasicType(T) = isScalarType!T || is(Unqual!T == void);
/** /**
* Detect whether `T` is a built-in unsigned numeric type. * Detect whether `T` is a built-in unsigned numeric type.
*/ */
enum bool isUnsigned(T) = __traits(isUnsigned, T) && !(is(Unqual!T == char) || enum bool isUnsigned(T) = __traits(isUnsigned, T) && !(is(immutable T == immutable char) ||
is(Unqual!T == wchar) || is(immutable T == immutable wchar) ||
is(Unqual!T == dchar) || is(immutable T == immutable dchar) ||
is(Unqual!T == bool)); is(immutable T == immutable bool));
/// ///
@safe unittest @safe unittest

View file

@ -7144,7 +7144,7 @@ if (is(C : dchar))
must be an L-value. must be an L-value.
+/ +/
Grapheme decodeGrapheme(Input)(ref Input inp) Grapheme decodeGrapheme(Input)(ref Input inp)
if (isInputRange!Input && is(Unqual!(ElementType!Input) == dchar)) if (isInputRange!Input && is(immutable ElementType!Input == immutable dchar))
{ {
return genericDecodeGrapheme!true(inp); return genericDecodeGrapheme!true(inp);
} }
@ -7177,7 +7177,7 @@ if (isInputRange!Input && is(Unqual!(ElementType!Input) == dchar))
$(LREF byCodePoint) $(LREF byCodePoint)
+/ +/
auto byGrapheme(Range)(Range range) auto byGrapheme(Range)(Range range)
if (isInputRange!Range && is(Unqual!(ElementType!Range) == dchar)) if (isInputRange!Range && is(immutable ElementType!Range == immutable dchar))
{ {
// TODO: Bidirectional access // TODO: Bidirectional access
static struct Result(R) static struct Result(R)
@ -7280,7 +7280,7 @@ private static struct InputRangeString
$(P If passed in a range of code points, returns a range with equivalent capabilities.) $(P If passed in a range of code points, returns a range with equivalent capabilities.)
+/ +/
auto byCodePoint(Range)(Range range) auto byCodePoint(Range)(Range range)
if (isInputRange!Range && is(Unqual!(ElementType!Range) == Grapheme)) if (isInputRange!Range && is(immutable ElementType!Range == immutable Grapheme))
{ {
// TODO: Propagate bidirectional access // TODO: Propagate bidirectional access
static struct Result static struct Result
@ -7323,7 +7323,7 @@ if (isInputRange!Range && is(Unqual!(ElementType!Range) == Grapheme))
/// Ditto /// Ditto
auto byCodePoint(Range)(Range range) auto byCodePoint(Range)(Range range)
if (isInputRange!Range && is(Unqual!(ElementType!Range) == dchar)) if (isInputRange!Range && is(immutable ElementType!Range == immutable dchar))
{ {
import std.range.primitives : isBidirectionalRange, popBack; import std.range.primitives : isBidirectionalRange, popBack;
import std.traits : isNarrowString; import std.traits : isNarrowString;

View file

@ -333,7 +333,7 @@ pure nothrow @safe @nogc unittest
+/ +/
uint stride(S)(auto ref S str, size_t index) uint stride(S)(auto ref S str, size_t index)
if (is(S : const char[]) || if (is(S : const char[]) ||
(isRandomAccessRange!S && is(Unqual!(ElementType!S) == char))) (isRandomAccessRange!S && is(immutable ElementType!S == immutable char)))
{ {
static if (is(typeof(str.length) : ulong)) static if (is(typeof(str.length) : ulong))
assert(index < str.length, "Past the end of the UTF-8 sequence"); assert(index < str.length, "Past the end of the UTF-8 sequence");
@ -348,7 +348,7 @@ if (is(S : const char[]) ||
/// Ditto /// Ditto
uint stride(S)(auto ref S str) uint stride(S)(auto ref S str)
if (is(S : const char[]) || if (is(S : const char[]) ||
(isInputRange!S && is(Unqual!(ElementType!S) == char))) (isInputRange!S && is(immutable ElementType!S == immutable char)))
{ {
static if (is(S : const char[])) static if (is(S : const char[]))
immutable c = str[0]; immutable c = str[0];
@ -446,7 +446,7 @@ if (is(S : const char[]) ||
/// Ditto /// Ditto
uint stride(S)(auto ref S str, size_t index) uint stride(S)(auto ref S str, size_t index)
if (is(S : const wchar[]) || if (is(S : const wchar[]) ||
(isRandomAccessRange!S && is(Unqual!(ElementType!S) == wchar))) (isRandomAccessRange!S && is(immutable ElementType!S == immutable wchar)))
{ {
static if (is(typeof(str.length) : ulong)) static if (is(typeof(str.length) : ulong))
assert(index < str.length, "Past the end of the UTF-16 sequence"); assert(index < str.length, "Past the end of the UTF-16 sequence");
@ -463,7 +463,7 @@ if (is(S : const wchar[]))
/// Ditto /// Ditto
uint stride(S)(auto ref S str) uint stride(S)(auto ref S str)
if (isInputRange!S && is(Unqual!(ElementType!S) == wchar)) if (isInputRange!S && is(immutable ElementType!S == immutable wchar))
{ {
assert(!str.empty, "UTF-16 sequence is empty"); assert(!str.empty, "UTF-16 sequence is empty");
immutable uint u = str.front; immutable uint u = str.front;
@ -541,7 +541,7 @@ if (isInputRange!S && is(Unqual!(ElementType!S) == wchar))
/// Ditto /// Ditto
uint stride(S)(auto ref S str, size_t index = 0) uint stride(S)(auto ref S str, size_t index = 0)
if (is(S : const dchar[]) || if (is(S : const dchar[]) ||
(isInputRange!S && is(Unqual!(ElementEncodingType!S) == dchar))) (isInputRange!S && is(immutable ElementEncodingType!S == immutable dchar)))
{ {
static if (is(typeof(str.length) : ulong)) static if (is(typeof(str.length) : ulong))
assert(index < str.length, "Past the end of the UTF-32 sequence"); assert(index < str.length, "Past the end of the UTF-32 sequence");
@ -665,7 +665,7 @@ do
+/ +/
uint strideBack(S)(auto ref S str, size_t index) uint strideBack(S)(auto ref S str, size_t index)
if (is(S : const char[]) || if (is(S : const char[]) ||
(isRandomAccessRange!S && is(Unqual!(ElementType!S) == char))) (isRandomAccessRange!S && is(immutable ElementType!S == immutable char)))
{ {
static if (is(typeof(str.length) : ulong)) static if (is(typeof(str.length) : ulong))
assert(index <= str.length, "Past the end of the UTF-8 sequence"); assert(index <= str.length, "Past the end of the UTF-8 sequence");
@ -696,14 +696,14 @@ if (is(S : const char[]) ||
/// Ditto /// Ditto
uint strideBack(S)(auto ref S str) uint strideBack(S)(auto ref S str)
if (is(S : const char[]) || if (is(S : const char[]) ||
(isRandomAccessRange!S && hasLength!S && is(Unqual!(ElementType!S) == char))) (isRandomAccessRange!S && hasLength!S && is(immutable ElementType!S == immutable char)))
{ {
return strideBack(str, str.length); return strideBack(str, str.length);
} }
/// Ditto /// Ditto
uint strideBack(S)(auto ref S str) uint strideBack(S)(auto ref S str)
if (isBidirectionalRange!S && is(Unqual!(ElementType!S) == char) && !isRandomAccessRange!S) if (isBidirectionalRange!S && is(immutable ElementType!S == immutable char) && !isRandomAccessRange!S)
{ {
assert(!str.empty, "Past the end of the UTF-8 sequence"); assert(!str.empty, "Past the end of the UTF-8 sequence");
auto temp = str.save; auto temp = str.save;
@ -791,7 +791,7 @@ if (isBidirectionalRange!S && is(Unqual!(ElementType!S) == char) && !isRandomAcc
/// Ditto /// Ditto
uint strideBack(S)(auto ref S str, size_t index) uint strideBack(S)(auto ref S str, size_t index)
if (is(S : const wchar[]) || if (is(S : const wchar[]) ||
(isRandomAccessRange!S && is(Unqual!(ElementType!S) == wchar))) (isRandomAccessRange!S && is(immutable ElementType!S == immutable wchar)))
{ {
static if (is(typeof(str.length) : ulong)) static if (is(typeof(str.length) : ulong))
assert(index <= str.length, "Past the end of the UTF-16 sequence"); assert(index <= str.length, "Past the end of the UTF-16 sequence");
@ -804,7 +804,7 @@ if (is(S : const wchar[]) ||
/// Ditto /// Ditto
uint strideBack(S)(auto ref S str) uint strideBack(S)(auto ref S str)
if (is(S : const wchar[]) || if (is(S : const wchar[]) ||
(isBidirectionalRange!S && is(Unqual!(ElementType!S) == wchar))) (isBidirectionalRange!S && is(immutable ElementType!S == immutable wchar)))
{ {
assert(!str.empty, "UTF-16 sequence is empty"); assert(!str.empty, "UTF-16 sequence is empty");
@ -886,7 +886,7 @@ if (is(S : const wchar[]) ||
/// Ditto /// Ditto
uint strideBack(S)(auto ref S str, size_t index) uint strideBack(S)(auto ref S str, size_t index)
if (isRandomAccessRange!S && is(Unqual!(ElementEncodingType!S) == dchar)) if (isRandomAccessRange!S && is(immutable ElementEncodingType!S == immutable dchar))
{ {
static if (is(typeof(str.length) : ulong)) static if (is(typeof(str.length) : ulong))
assert(index <= str.length, "Past the end of the UTF-32 sequence"); assert(index <= str.length, "Past the end of the UTF-32 sequence");
@ -896,7 +896,7 @@ if (isRandomAccessRange!S && is(Unqual!(ElementEncodingType!S) == dchar))
/// Ditto /// Ditto
uint strideBack(S)(auto ref S str) uint strideBack(S)(auto ref S str)
if (isBidirectionalRange!S && is(Unqual!(ElementEncodingType!S) == dchar)) if (isBidirectionalRange!S && is(immutable ElementEncodingType!S == immutable dchar))
{ {
assert(!str.empty, "Empty UTF-32 sequence"); assert(!str.empty, "Empty UTF-32 sequence");
return 1; return 1;
@ -991,7 +991,7 @@ if (isBidirectionalRange!S && is(Unqual!(ElementEncodingType!S) == dchar))
size_t toUCSindex(C)(const(C)[] str, size_t index) @safe pure size_t toUCSindex(C)(const(C)[] str, size_t index) @safe pure
if (isSomeChar!C) if (isSomeChar!C)
{ {
static if (is(Unqual!C == dchar)) static if (is(immutable C == immutable dchar))
return index; return index;
else else
{ {
@ -1003,7 +1003,7 @@ if (isSomeChar!C)
if (j > index) if (j > index)
{ {
static if (is(Unqual!C == char)) static if (is(immutable C == immutable char))
throw new UTFException("Invalid UTF-8 sequence", index); throw new UTFException("Invalid UTF-8 sequence", index);
else else
throw new UTFException("Invalid UTF-16 sequence", index); throw new UTFException("Invalid UTF-16 sequence", index);
@ -1038,7 +1038,7 @@ if (isSomeChar!C)
size_t toUTFindex(C)(const(C)[] str, size_t n) @safe pure size_t toUTFindex(C)(const(C)[] str, size_t n) @safe pure
if (isSomeChar!C) if (isSomeChar!C)
{ {
static if (is(Unqual!C == dchar)) static if (is(immutable C == immutable dchar))
{ {
return n; return n;
} }
@ -1424,9 +1424,9 @@ do
package template codeUnitLimit(S) package template codeUnitLimit(S)
if (isSomeChar!(ElementEncodingType!S)) if (isSomeChar!(ElementEncodingType!S))
{ {
static if (is(Unqual!(ElementEncodingType!S) == char)) static if (is(immutable ElementEncodingType!S == immutable char))
enum char codeUnitLimit = 0x80; enum char codeUnitLimit = 0x80;
else static if (is(Unqual!(ElementEncodingType!S) == wchar)) else static if (is(immutable ElementEncodingType!S == immutable wchar))
enum wchar codeUnitLimit = 0xD800; enum wchar codeUnitLimit = 0xD800;
else else
enum dchar codeUnitLimit = 0xD800; enum dchar codeUnitLimit = 0xD800;
@ -1452,7 +1452,7 @@ if (isSomeChar!(ElementEncodingType!S))
private dchar decodeImpl(bool canIndex, UseReplacementDchar useReplacementDchar = No.useReplacementDchar, S)( private dchar decodeImpl(bool canIndex, UseReplacementDchar useReplacementDchar = No.useReplacementDchar, S)(
auto ref S str, ref size_t index) auto ref S str, ref size_t index)
if ( if (
is(S : const char[]) || (isInputRange!S && is(Unqual!(ElementEncodingType!S) == char))) is(S : const char[]) || (isInputRange!S && is(immutable ElementEncodingType!S == immutable char)))
{ {
/* The following encodings are valid, except for the 5 and 6 byte /* The following encodings are valid, except for the 5 and 6 byte
* combinations: * combinations:
@ -1683,7 +1683,7 @@ unittest
private dchar decodeImpl(bool canIndex, UseReplacementDchar useReplacementDchar = No.useReplacementDchar, S) private dchar decodeImpl(bool canIndex, UseReplacementDchar useReplacementDchar = No.useReplacementDchar, S)
(auto ref S str, ref size_t index) (auto ref S str, ref size_t index)
if (is(S : const wchar[]) || (isInputRange!S && is(Unqual!(ElementEncodingType!S) == wchar))) if (is(S : const wchar[]) || (isInputRange!S && is(immutable ElementEncodingType!S == immutable wchar)))
{ {
static if (is(S : const wchar[])) static if (is(S : const wchar[]))
auto pstr = str.ptr + index; auto pstr = str.ptr + index;
@ -1801,7 +1801,7 @@ unittest
private dchar decodeImpl(bool canIndex, UseReplacementDchar useReplacementDchar = No.useReplacementDchar, S)( private dchar decodeImpl(bool canIndex, UseReplacementDchar useReplacementDchar = No.useReplacementDchar, S)(
auto ref S str, ref size_t index) auto ref S str, ref size_t index)
if (is(S : const dchar[]) || (isInputRange!S && is(Unqual!(ElementEncodingType!S) == dchar))) if (is(S : const dchar[]) || (isInputRange!S && is(immutable ElementEncodingType!S == immutable dchar)))
{ {
static if (is(S : const dchar[])) static if (is(S : const dchar[]))
auto pstr = str.ptr; auto pstr = str.ptr;
@ -3110,8 +3110,8 @@ template toUTFz(P)
private P toUTFzImpl(P, S)(S str) @safe pure private P toUTFzImpl(P, S)(S str) @safe pure
if (isSomeString!S && isPointer!P && isSomeChar!(typeof(*P.init)) && if (isSomeString!S && isPointer!P && isSomeChar!(typeof(*P.init)) &&
is(Unqual!(typeof(*P.init)) == Unqual!(ElementEncodingType!S)) && is(immutable typeof(*P.init) == immutable ElementEncodingType!S) &&
is(immutable(Unqual!(ElementEncodingType!S)) == ElementEncodingType!S)) is(immutable ElementEncodingType!S == ElementEncodingType!S))
//immutable(C)[] -> C*, const(C)*, or immutable(C)* //immutable(C)[] -> C*, const(C)*, or immutable(C)*
{ {
if (str.empty) if (str.empty)
@ -3155,8 +3155,8 @@ if (isSomeString!S && isPointer!P && isSomeChar!(typeof(*P.init)) &&
private P toUTFzImpl(P, S)(S str) @safe pure private P toUTFzImpl(P, S)(S str) @safe pure
if (isSomeString!S && isPointer!P && isSomeChar!(typeof(*P.init)) && if (isSomeString!S && isPointer!P && isSomeChar!(typeof(*P.init)) &&
is(Unqual!(typeof(*P.init)) == Unqual!(ElementEncodingType!S)) && is(immutable typeof(*P.init) == immutable ElementEncodingType!S) &&
!is(immutable(Unqual!(ElementEncodingType!S)) == ElementEncodingType!S)) !is(immutable ElementEncodingType!S == ElementEncodingType!S))
//C[] or const(C)[] -> C*, const(C)*, or immutable(C)* //C[] or const(C)[] -> C*, const(C)*, or immutable(C)*
{ {
alias InChar = ElementEncodingType!S; alias InChar = ElementEncodingType!S;
@ -3195,7 +3195,7 @@ if (isSomeString!S && isPointer!P && isSomeChar!(typeof(*P.init)) &&
private P toUTFzImpl(P, S)(S str) @safe pure private P toUTFzImpl(P, S)(S str) @safe pure
if (isSomeString!S && isPointer!P && isSomeChar!(typeof(*P.init)) && if (isSomeString!S && isPointer!P && isSomeChar!(typeof(*P.init)) &&
!is(Unqual!(typeof(*P.init)) == Unqual!(ElementEncodingType!S))) !is(immutable typeof(*P.init) == immutable ElementEncodingType!S))
//C1[], const(C1)[], or immutable(C1)[] -> C2*, const(C2)*, or immutable(C2)* //C1[], const(C1)[], or immutable(C1)[] -> C2*, const(C2)*, or immutable(C2)*
{ {
import std.array : appender; import std.array : appender;

View file

@ -1333,7 +1333,7 @@ if (isSomeString!T)
///ditto ///ditto
UUID parseUUID(Range)(ref Range uuidRange) UUID parseUUID(Range)(ref Range uuidRange)
if (isInputRange!Range if (isInputRange!Range
&& is(Unqual!(ElementType!Range) == dchar)) && is(immutable ElementType!Range == immutable dchar))
{ {
import std.ascii : isHexDigit; import std.ascii : isHexDigit;
import std.conv : ConvException, parse; import std.conv : ConvException, parse;