Skip to content

Instantly share code, notes, and snippets.

@9rnsr
Created July 21, 2012 19:01
Show Gist options
  • Save 9rnsr/3156840 to your computer and use it in GitHub Desktop.
Save 9rnsr/3156840 to your computer and use it in GitHub Desktop.
A library implementation of arr.dup/idup
template isMutable(T)
{
enum isMutable = !is(T == const) && !is(T == immutable) && !is(T == inout);
}
template Unqual(T)
{
static if (is(T U == shared(const U))) alias U Unqual;
else static if (is(T U == const U )) alias U Unqual;
else static if (is(T U == immutable U )) alias U Unqual;
else static if (is(T U == inout U )) alias U Unqual;
else static if (is(T U == shared U )) alias U Unqual;
else alias T Unqual;
}
template hasMutableIndirection(T)
{
enum hasMutableIndirection = !is(typeof({ Unqual!T t = void; immutable T u = t; }));
}
static assert(!hasMutableIndirection!(int));
//static assert(!hasMutableIndirection!(int[3]));
static assert( hasMutableIndirection!(Object));
auto dup(E)(inout(E)[] arr) pure @trusted
{
static if (hasMutableIndirection!E)
{
auto copy = new E[](arr.length);
copy[] = cast(E[])arr[]; // assume constant
return cast(inout(E)[])copy; // assume constant
}
else
{
auto copy = new E[](arr.length);
copy[] = arr[];
return copy;
}
}
void main()
{
void test(E, bool constConv)()
{
E[] marr = [E.init, E.init, E.init];
immutable E[] iarr = [E.init, E.init, E.init];
E[] m2m = marr.dup(); assert(m2m == marr);
immutable E[] i2i = iarr.dup(); assert(i2i == iarr);
static if (constConv)
{ // If dup() hss strong purity, implicit conversion is allowed
immutable E[] m2i = marr.dup(); assert(m2i == marr);
E[] i2m = iarr.dup(); assert(i2m == iarr);
}
else
{
static assert(!is(typeof({ immutable E[] m2i = marr.dup(); })));
static assert(!is(typeof({ E[] i2m = iarr.dup(); })));
}
}
class C {}
test!(int , true )();
//test!(int[3], true )();
test!(C , false)();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment