Skip to content

Commit

Permalink
Sanitize Appender constraints a bit.
Browse files Browse the repository at this point in the history
  • Loading branch information
monarchdodra committed May 21, 2014
1 parent 15234c3 commit 452eab0
Showing 1 changed file with 45 additions and 8 deletions.
53 changes: 45 additions & 8 deletions std/array.d
Expand Up @@ -2265,8 +2265,10 @@ app2.put([ 4, 5, 6 ]);
assert(app2.data == [ 1, 2, 3, 4, 5, 6 ]);
----
*/
struct Appender(A : T[], T)
struct Appender(A)
if (isDynamicArray!A)
{
private alias T = ElementEncodingType!A;
private struct Data
{
size_t capacity;
Expand Down Expand Up @@ -2623,11 +2625,13 @@ private size_t appenderNewCapacity(size_t TSizeOf)(size_t curLen, size_t reqLen)
* underlying appender implementation. Any calls made to the appender also update
* the pointer to the original array passed in.
*/
struct RefAppender(A : T[], T)
struct RefAppender(A)
if (isDynamicArray!A)
{
private
{
Appender!(A, T) impl;
alias T = ElementEncodingType!A;
Appender!A impl;
T[] *arr;
}

Expand All @@ -2643,7 +2647,7 @@ struct RefAppender(A : T[], T)
*/
this(T[] *arr)
{
impl = Appender!(A, T)(*arr);
impl = Appender!A(*arr);
this.arr = arr;
}

Expand All @@ -2654,7 +2658,7 @@ struct RefAppender(A : T[], T)
mixin("return impl." ~ fn ~ "(args);");
}

private alias AppenderType = Appender!(A, T);
private alias AppenderType = Appender!A;

/**
* Appends one item to the managed array.
Expand Down Expand Up @@ -2704,13 +2708,17 @@ struct RefAppender(A : T[], T)
Convenience function that returns an $(D Appender!A) object initialized
with $(D array).
+/
Appender!(E[]) appender(A : E[], E)()
Appender!A appender(A)()
if (isDynamicArray!A)
{
return Appender!(E[])(null);
return Appender!A(null);
}
/// ditto
Appender!(E[]) appender(A : E[], E)(A array)
Appender!(E[]) appender(A : E[], E)(auto ref A array)
{
static assert (!isStaticArray!A || __traits(isRef, array),
"Cannot create Appender from an rvalue static array");

return Appender!(E[])(array);
}

Expand Down Expand Up @@ -3017,6 +3025,35 @@ unittest // check against .clear UFCS hijacking
"Remove me when object.clear is removed!");
}

unittest
{
static struct D//dynamic
{
int[] i;
alias i this;
}
static struct S//static
{
int[5] i;
alias i this;
}
static assert(!is(Appender!(char[5])));
static assert(!is(Appender!D));
static assert(!is(Appender!S));

enum int[5] a = [];
int[5] b;
D d;
S s;
int[5] foo(){return a;}

static assert(!is(typeof(appender(a))));
static assert( is(typeof(appender(b))));
static assert( is(typeof(appender(d))));
static assert( is(typeof(appender(s))));
static assert(!is(typeof(appender(foo()))));
}

/++
Convenience function that returns a $(D RefAppender!A) object initialized
with $(D array). Don't use null for the $(D array) pointer, use the other
Expand Down

0 comments on commit 452eab0

Please sign in to comment.