blob: 117070dfe5e1af873fe2aead782433b9cdb51f89 [file] [log] [blame]
// REQUIRED_ARGS: -preview=dip1000 -preview=in
void main ()
{
testWithAllAttributes();
testForeach();
}
void testWithAllAttributes() @safe pure nothrow @nogc
{
// Used to test dtors
bool isTestOver = false;
// rvalues
testin1(42);
testin2((ulong[64]).init);
testin3(ValueT(42));
testin3(RefT(42));
testin4((ValueT[64]).init);
testin4([RefT(42), RefT(84), RefT(126), RefT(4)]);
testin5(NonCopyable(true));
testin6(WithPostblit(true));
testin7(WithCopyCtor(true));
isTestOver = false;
testin8(WithDtor(&isTestOver), &isTestOver);
isTestOver = false;
// lvalues
uint a1;
ulong[64] a2;
ValueT a3;
ValueT[64] a4;
RefT a5;
RefT[4] a6;
NonCopyable a7 = NonCopyable(true);
WithPostblit a8;
WithCopyCtor a9;
WithDtor a10 = WithDtor(&isTestOver);
testin1(a1);
testin2(a2);
testin3(a3);
testin3(a5);
testin4(a4);
testin4(a6);
testin5(a7);
testin6(a8);
testin7(a9);
isTestOver = false;
testin8(a10, null);
// Arguments are all values, no `ref` needed
testin9(int.init);
testin9(char.init, ubyte.init, short.init, int.init, size_t.init);
// Arguments are all refs
testin9(a2, a4, a5, a6, a7, a8, a9, a10);
testin9(NonCopyable(true), WithPostblit(true), WithCopyCtor(true));
// Mixed values and ref
testin9(char.init, ubyte.init, a2, a4, a5, a6, a7, a8, a9, a10, size_t.init);
// With dtor
isTestOver = false;
testin10(&isTestOver, NonCopyable(true), WithPostblit(true),
WithCopyCtor(true), WithDtor(&isTestOver));
isTestOver = true;
}
void testForeach() @safe pure
{
int testCallNC (in NonCopyable k, in NonCopyable v)
{
assert(k == v);
return k.value - v.value;
}
NonCopyable[NonCopyable] nc;
nc[NonCopyable(0)] = NonCopyable(0);
nc[NonCopyable(42)] = NonCopyable(42);
nc[NonCopyable(int.min)] = NonCopyable(int.min);
nc[NonCopyable(int.max)] = NonCopyable(int.max);
foreach (ref k, const ref v; nc)
{
assert(k.value == v.value);
assert(testCallNC(k, v) == 0);
}
assert(nc == nc);
assert(nc.length == 4);
RefT[RefT] rt;
rt[RefT(42)] = RefT(42);
rt[RefT(4)] = RefT(4);
rt[RefT(242)] = RefT(242);
rt[RefT(24)] = RefT(24);
foreach (k, v; rt)
assert(k.value == v.value);
assert(rt == rt);
static struct Msg
{
ubyte[3] value;
const(char)[] msg;
}
static void testMsg (in Msg k_func, in Msg v_func)
{
assert(k_func.value == v_func.value);
assert(k_func.msg == v_func.msg);
assert(k_func == v_func);
}
Msg[Msg] msg;
msg[Msg([1, 2, 3], "123")] = Msg([1, 2, 3], "123");
msg[Msg([42, 4, 2], "4242")] = Msg([42, 4, 2], "4242");
msg[Msg([242, 4, 0], "2424")] = Msg([242, 4, 0], "2424");
foreach (ref k_loop, ref v_loop; msg)
testMsg(k_loop, v_loop);
}
struct ValueT { int value; }
struct RefT { ulong[64] value; }
struct NonCopyable
{
@safe pure nothrow @nogc:
int value;
this(int b) { this.value = b; }
@disable this(this);
@disable this(ref NonCopyable);
}
struct WithPostblit
{
int value;
this(this) @safe pure nothrow @nogc { assert(0); }
}
struct WithCopyCtor
{
@safe pure nothrow @nogc:
int value;
this(int b) { this.value = b; }
this(ref WithCopyCtor) { assert(0); }
}
struct WithDtor
{
bool* value;
~this() scope @safe pure nothrow @nogc { assert(*value); }
}
@safe pure nothrow @nogc:
// By value
void testin1(in uint p) { static assert(!__traits(isRef, p)); }
// By ref because of size
void testin2(in ulong[64] p) { static assert(__traits(isRef, p)); }
// By value or ref depending on size (or structs always passed by reference)
void testin3(in ValueT p) { static assert(!__traits(isRef, p) || true); }
void testin3(in RefT p) { static assert(__traits(isRef, p)); }
// By ref because of size (or arrays always passed by reference)
void testin4(in ValueT[64] p) { static assert(__traits(isRef, p)); }
void testin4(in RefT[4] p) { static assert(__traits(isRef, p)); }
// By ref because of non-copyability
void testin5(in NonCopyable noncopy) { static assert(__traits(isRef, noncopy)); }
static assert(testin5.mangleof == "_D9previewin7testin5FNaNbNiNfIKSQBe11NonCopyableZv"); // incl. `ref`
// By ref because of postblit
void testin6(in WithPostblit withpostblit) { static assert(__traits(isRef, withpostblit)); }
// By ref because of copy ctor
void testin7(in WithCopyCtor withcopy) { static assert(__traits(isRef, withcopy)); }
// By ref because of dtor
void testin8(in WithDtor withdtor, scope bool* isTestOver)
{
static assert(__traits(isRef, withdtor));
if (isTestOver)
*isTestOver = true;
}
// Allow to test various tuples (e.g. `(int, int)` and `(int, WithDtor)`)
// `ref` is only applied to the members which need it
void testin9(T...)(in T args) {}
void testin10(T...)(scope bool* isTestOver, in T args)
{
if (isTestOver)
*isTestOver = true;
}