Showing with 25 additions and 2 deletions.
  1. +25 −2 std/range/primitives.d
27 changes: 25 additions & 2 deletions std/range/primitives.d
Original file line number Diff line number Diff line change
Expand Up @@ -2085,6 +2085,8 @@ version(unittest)
void popFront(C)(ref C[] str) @trusted pure nothrow
if (isNarrowString!(C[]))
{
import std.algorithm : min;

assert(str.length, "Attempting to popFront() past the end of an array of " ~ C.stringof);

static if (is(Unqual!C == char))
Expand All @@ -2104,13 +2106,14 @@ if (isNarrowString!(C[]))
//Invalid UTF-8
msbs = 1;
}
str = str[msbs .. $];
str = str.ptr[min(msbs, str.length) .. str.length];
}
}
else static if (is(Unqual!C == wchar))
{
immutable u = str[0];
str = str[1 + (u >= 0xD800 && u <= 0xDBFF) .. $];
immutable seqLen = 1 + (u >= 0xD800 && u <= 0xDBFF);
str = str.ptr[min(seqLen, str.length) .. str.length];
}
else static assert(0, "Bad template constraint.");
}
Expand Down Expand Up @@ -2150,6 +2153,26 @@ if (isNarrowString!(C[]))
static assert(checkCTFEW.empty);
}

unittest // issue 16090
{
string s = "\u00E4";
assert(s.length == 2);
s = s[0 .. 1];
assert(s.length == 1);
s.popFront;
assert(s.empty);
}

unittest
{
wstring s = "\U00010000";
assert(s.length == 2);
s = s[0 .. 1];
assert(s.length == 1);
s.popFront;
assert(s.empty);
}

/**
Implements the range interface primitive $(D popBack) for built-in
arrays. Due to the fact that nonmember functions can be called with
Expand Down