mirror of
https://github.com/dlang/phobos.git
synced 2025-05-05 01:20:40 +03:00
fix Issue 9836 - std.array.popFront does not work with alias this.
empty, front, popFront, back, popBack should work with alias this type.
This commit is contained in:
parent
113526f6b5
commit
53640bf046
1 changed files with 70 additions and 54 deletions
124
std/array.d
124
std/array.d
|
@ -407,11 +407,10 @@ assert(a == [ 2, 3 ]);
|
|||
), $(ARGS), $(ARGS), $(ARGS import std.array;))
|
||||
*/
|
||||
|
||||
void popFront(A)(ref A a)
|
||||
if (!isNarrowString!A && isDynamicArray!A && isMutable!A && !is(A == void[]))
|
||||
void popFront(T)(ref T[] a)
|
||||
if (!isNarrowString!(T[]) && !is(T[] == void[]))
|
||||
{
|
||||
assert(a.length, "Attempting to popFront() past the end of an array of "
|
||||
~ typeof(a[0]).stringof);
|
||||
assert(a.length, "Attempting to popFront() past the end of an array of " ~ T.stringof);
|
||||
a = a[1 .. $];
|
||||
}
|
||||
|
||||
|
@ -420,16 +419,16 @@ unittest
|
|||
auto a = [ 1, 2, 3 ];
|
||||
a.popFront();
|
||||
assert(a == [ 2, 3 ]);
|
||||
static assert(!__traits(compiles, popFront!(immutable int[])()));
|
||||
static assert(!__traits(compiles, popFront!(void[])()));
|
||||
|
||||
static assert(!is(typeof({ int[4] a; popFront(a); })));
|
||||
static assert(!is(typeof({ immutable int[] a; popFront(a); })));
|
||||
static assert(!is(typeof({ void[] a; popFront(a); })));
|
||||
}
|
||||
|
||||
// Specialization for narrow strings. The necessity of
|
||||
// !isStaticArray!A suggests a compiler @@@BUG@@@.
|
||||
void popFront(S)(ref S str) @trusted pure nothrow
|
||||
if (isNarrowString!S && isMutable!S && !isStaticArray!S)
|
||||
void popFront(C)(ref C[] str) @trusted pure nothrow
|
||||
if (isNarrowString!(C[]))
|
||||
{
|
||||
alias ElementEncodingType!S C;
|
||||
assert(str.length, "Attempting to popFront() past the end of an array of " ~ C.stringof);
|
||||
|
||||
static if(is(Unqual!C == char))
|
||||
|
@ -460,26 +459,14 @@ if (isNarrowString!S && isMutable!S && !isStaticArray!S)
|
|||
else static assert(0, "Bad template constraint.");
|
||||
}
|
||||
|
||||
version(unittest) C[] _eatString(C)(C[] str)
|
||||
{
|
||||
while(!str.empty)
|
||||
str.popFront();
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
unittest
|
||||
{
|
||||
string s1 = "\xC2\xA9hello";
|
||||
s1.popFront();
|
||||
assert(s1 == "hello");
|
||||
wstring s2 = "\xC2\xA9hello";
|
||||
s2.popFront();
|
||||
assert(s2 == "hello");
|
||||
string s3 = "\u20AC100";
|
||||
|
||||
foreach(S; TypeTuple!(string, wstring, dstring))
|
||||
{
|
||||
S s = "\xC2\xA9hello";
|
||||
s.popFront();
|
||||
assert(s == "hello");
|
||||
|
||||
S str = "hello\U00010143\u0100\U00010143";
|
||||
foreach(dchar c; ['h', 'e', 'l', 'l', 'o', '\U00010143', '\u0100', '\U00010143'])
|
||||
{
|
||||
|
@ -487,11 +474,18 @@ unittest
|
|||
str.popFront();
|
||||
}
|
||||
assert(str.empty);
|
||||
|
||||
static assert(!is(typeof({ immutable S a; popFront(a); })));
|
||||
static assert(!is(typeof({ typeof(S.init[0])[4] a; popFront(a); })));
|
||||
}
|
||||
|
||||
static assert(!is(typeof(popFront!(immutable string))));
|
||||
static assert(!is(typeof(popFront!(char[4]))));
|
||||
C[] _eatString(C)(C[] str)
|
||||
{
|
||||
while(!str.empty)
|
||||
str.popFront();
|
||||
|
||||
return str;
|
||||
}
|
||||
enum checkCTFE = _eatString("ウェブサイト@La_Verité.com");
|
||||
static assert(checkCTFE.empty);
|
||||
enum checkCTFEW = _eatString("ウェブサイト@La_Verité.com"w);
|
||||
|
@ -517,8 +511,8 @@ assert(a == [ 1, 2 ]);
|
|||
), $(ARGS), $(ARGS), $(ARGS import std.array;))
|
||||
*/
|
||||
|
||||
void popBack(A)(ref A a)
|
||||
if (isDynamicArray!A && !isNarrowString!A && isMutable!A && !is(A == void[]))
|
||||
void popBack(T)(ref T[] a)
|
||||
if (!isNarrowString!(T[]) && !is(T[] == void[]))
|
||||
{
|
||||
assert(a.length);
|
||||
a = a[0 .. $ - 1];
|
||||
|
@ -529,17 +523,18 @@ unittest
|
|||
auto a = [ 1, 2, 3 ];
|
||||
a.popBack();
|
||||
assert(a == [ 1, 2 ]);
|
||||
static assert(!__traits(compiles, popBack!(immutable int[])));
|
||||
static assert(!__traits(compiles, popBack!(void[])));
|
||||
|
||||
static assert(!is(typeof({ immutable int[] a; popBack(a); })));
|
||||
static assert(!is(typeof({ int[4] a; popBack(a); })));
|
||||
static assert(!is(typeof({ void[] a; popBack(a); })));
|
||||
}
|
||||
|
||||
// Specialization for arrays of char
|
||||
@trusted void popBack(A)(ref A a)
|
||||
if(isNarrowString!A && isMutable!A)
|
||||
@trusted void popBack(T)(ref T[] a)
|
||||
if (isNarrowString!(T[]))
|
||||
{
|
||||
assert(a.length, "Attempting to popBack() past the front of an array of " ~
|
||||
typeof(a[0]).stringof);
|
||||
a = a[0 .. $ - std.utf.strideBack(a, a.length)];
|
||||
assert(a.length, "Attempting to popBack() past the front of an array of " ~ T.stringof);
|
||||
a = a[0 .. $ - std.utf.strideBack(a, $)];
|
||||
}
|
||||
|
||||
unittest
|
||||
|
@ -563,7 +558,8 @@ unittest
|
|||
}
|
||||
assert(str.empty);
|
||||
|
||||
static assert(!__traits(compiles, popBack!(immutable S)));
|
||||
static assert(!is(typeof({ immutable S a; popBack(a); })));
|
||||
static assert(!is(typeof({ typeof(S.init[0])[4] a; popBack(a); })));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -588,19 +584,10 @@ assert(a.front == 1);
|
|||
@property ref T front(T)(T[] a)
|
||||
if (!isNarrowString!(T[]) && !is(T[] == void[]))
|
||||
{
|
||||
assert(a.length, "Attempting to fetch the front of an empty array of " ~
|
||||
typeof(a[0]).stringof);
|
||||
assert(a.length, "Attempting to fetch the front of an empty array of " ~ T.stringof);
|
||||
return a[0];
|
||||
}
|
||||
|
||||
@property dchar front(A)(A a) if (isNarrowString!A)
|
||||
{
|
||||
assert(a.length, "Attempting to fetch the front of an empty array of " ~
|
||||
typeof(a[0]).stringof);
|
||||
size_t i = 0;
|
||||
return decode(a, i);
|
||||
}
|
||||
|
||||
unittest
|
||||
{
|
||||
auto a = [ 1, 2 ];
|
||||
|
@ -610,6 +597,16 @@ unittest
|
|||
|
||||
immutable b = [ 1, 2 ];
|
||||
assert(b.front == 1);
|
||||
|
||||
int[2] c = [ 1, 2 ];
|
||||
assert(c.front == 1);
|
||||
}
|
||||
|
||||
@property dchar front(T)(T[] a) if (isNarrowString!(T[]))
|
||||
{
|
||||
assert(a.length, "Attempting to fetch the front of an empty array of " ~ T.stringof);
|
||||
size_t i = 0;
|
||||
return decode(a, i);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -631,8 +628,7 @@ assert(a.back == 3);
|
|||
*/
|
||||
@property ref T back(T)(T[] a) if (!isNarrowString!(T[]))
|
||||
{
|
||||
assert(a.length, "Attempting to fetch the back of an empty array of " ~
|
||||
typeof(a[0]).stringof);
|
||||
assert(a.length, "Attempting to fetch the back of an empty array of " ~ T.stringof);
|
||||
return a[$ - 1];
|
||||
}
|
||||
|
||||
|
@ -645,14 +641,15 @@ unittest
|
|||
|
||||
immutable b = [ 1, 2, 3 ];
|
||||
assert(b.back == 3);
|
||||
|
||||
int[3] c = [ 1, 2, 3 ];
|
||||
assert(c.back == 3);
|
||||
}
|
||||
|
||||
// Specialization for strings
|
||||
@property dchar back(A)(A a)
|
||||
if(isDynamicArray!A && isNarrowString!A)
|
||||
@property dchar back(T)(T[] a) if (isNarrowString!(T[]))
|
||||
{
|
||||
assert(a.length, "Attempting to fetch the back of an empty array of " ~
|
||||
typeof(a[0]).stringof);
|
||||
assert(a.length, "Attempting to fetch the back of an empty array of " ~ T.stringof);
|
||||
size_t i = a.length - std.utf.strideBack(a, a.length);
|
||||
return decode(a, i);
|
||||
}
|
||||
|
@ -716,6 +713,25 @@ unittest
|
|||
assert(overlap(c, d.idup).empty);
|
||||
}
|
||||
|
||||
unittest // bugzilla 9836
|
||||
{
|
||||
// range primitives for array should work with alias this types
|
||||
struct Wrapper
|
||||
{
|
||||
int[] data;
|
||||
alias data this;
|
||||
|
||||
@property Wrapper save() { return this; }
|
||||
}
|
||||
auto w = Wrapper([1,2,3,4]);
|
||||
std.array.popFront(w); // should work
|
||||
|
||||
static assert(isInputRange!Wrapper);
|
||||
static assert(isForwardRange!Wrapper);
|
||||
static assert(isBidirectionalRange!Wrapper);
|
||||
static assert(isRandomAccessRange!Wrapper);
|
||||
}
|
||||
|
||||
/+
|
||||
Commented out until the insert which has been deprecated has been removed.
|
||||
I'd love to just remove it in favor of insertInPlace, but then code would then
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue