The OpenD Programming Language

testType

///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////

version(CoreUnittest)
pragma(inline, true) pure nothrow @nogc @safe
void
testType
(
T
)
(
T val = T.init + 1
)

Examples

///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////

testType!(bool)();

testType!(byte)();
testType!(ubyte)();

testType!(short)();
testType!(ushort)();

testType!(int)();
testType!(uint)();

///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////

1 testType!(shared int*)();
2 
3 static interface Inter {}
4 static class KlassImpl : Inter {}
5 testXCHG!(shared Inter)(new shared(KlassImpl));
6 testCAS!(shared Inter)(new shared(KlassImpl));
7 
8 static class Klass {}
9 testXCHG!(shared Klass)(new shared(Klass));
10 testCAS!(shared Klass)(new shared(Klass));
11 
12 testXCHG!(shared int)(42);
13 
14 testType!(float)(0.1f);
15 
16 static if (has64BitCAS)
17 {
18     testType!(double)(0.1);
19     testType!(long)();
20     testType!(ulong)();
21 }
22 static if (has128BitCAS)
23 {
24     () @trusted
25     {
26         align(16) struct Big { long a, b; }
27 
28         shared(Big) atom;
29         shared(Big) base;
30         shared(Big) arg;
31         shared(Big) val = Big(1, 2);
32 
33         assert(cas(&atom, arg, val), Big.stringof);
34         assert(atom is val, Big.stringof);
35         assert(!cas(&atom, arg, val), Big.stringof);
36         assert(atom is val, Big.stringof);
37 
38         atom = Big();
39         assert(cas(&atom, &arg, val), Big.stringof);
40         assert(arg is base, Big.stringof);
41         assert(atom is val, Big.stringof);
42 
43         arg = Big();
44         assert(!cas(&atom, &arg, base), Big.stringof);
45         assert(arg is val, Big.stringof);
46         assert(atom is val, Big.stringof);
47     }();
48 }
49 
50 shared(size_t) i;
51 
52 atomicOp!"+="(i, cast(size_t) 1);
53 assert(i == 1);
54 
55 atomicOp!"-="(i, cast(size_t) 1);
56 assert(i == 0);
57 
58 shared float f = 0.1f;
59 atomicOp!"+="(f, 0.1f);
60 assert(f > 0.1999f && f < 0.2001f);
61 
62 static if (has64BitCAS)
63 {
64     shared double d = 0.1;
65     atomicOp!"+="(d, 0.1);
66     assert(d > 0.1999 && d < 0.2001);
67 }

///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////

static if (has128BitCAS)
{
    struct DoubleValue
    {
        long value1;
        long value2;
    }

    align(16) shared DoubleValue a;
    atomicStore(a, DoubleValue(1,2));
    assert(a.value1 == 1 && a.value2 ==2);

    while (!cas(&a, DoubleValue(1,2), DoubleValue(3,4))){}
    assert(a.value1 == 3 && a.value2 ==4);

    align(16) DoubleValue b = atomicLoad(a);
    assert(b.value1 == 3 && b.value2 ==4);
}

static if (hasDWCAS)
{
    static struct List { size_t gen; List* next; }
    shared(List) head;
    assert(cas(&head, shared(List)(0, null), shared(List)(1, cast(List*)1)));
    assert(head.gen == 1);
    assert(cast(size_t)head.next == 1);
}

// https://issues.dlang.org/show_bug.cgi?id=20629
static struct Struct
{
    uint a, b;
}
shared Struct s1 = Struct(1, 2);
atomicStore(s1, Struct(3, 4));
assert(cast(uint) s1.a == 3);
assert(cast(uint) s1.b == 4);

///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////

int a;
if (casWeak!(MemoryOrder.acq_rel, MemoryOrder.raw)(&a, 0, 4))
    assert(a == 4);

///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////

// https://issues.dlang.org/show_bug.cgi?id=17821
{
    shared ulong x = 0x1234_5678_8765_4321;
    atomicStore(x, 0);
    assert(x == 0);
}
{
    struct S
    {
        ulong x;
        alias x this;
    }
    shared S s;
    s = 0x1234_5678_8765_4321;
    atomicStore(s, 0);
    assert(s.x == 0);
}
{
    abstract class Logger {}
    shared Logger s1;
    Logger s2;
    atomicStore(s1, cast(shared) s2);
}

///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////

static struct S { int val; }
auto s = shared(S)(1);

shared(S*) ptr;

// head unshared
shared(S)* ifThis = null;
shared(S)* writeThis = &s;
assert(ptr is null);
assert(cas(&ptr, ifThis, writeThis));
assert(ptr is writeThis);

// head shared
shared(S*) ifThis2 = writeThis;
shared(S*) writeThis2 = null;
assert(cas(&ptr, ifThis2, writeThis2));
assert(ptr is null);

///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////

shared ubyte u8 = 1;
shared ushort u16 = 2;
shared uint u32 = 3;
shared byte i8 = 5;
shared short i16 = 6;
shared int i32 = 7;

assert(atomicOp!"+="(u8, 8) == 9);
assert(atomicOp!"+="(u16, 8) == 10);
assert(atomicOp!"+="(u32, 8) == 11);
assert(atomicOp!"+="(i8, 8) == 13);
assert(atomicOp!"+="(i16, 8) == 14);
assert(atomicOp!"+="(i32, 8) == 15);
version (D_LP64)
{
    shared ulong u64 = 4;
    shared long i64 = 8;
    assert(atomicOp!"+="(u64, 8) == 12);
    assert(atomicOp!"+="(i64, 8) == 16);
}

///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////

byte[10] byteArray = [1, 3, 5, 7, 9, 11, 13, 15, 17, 19];
ulong[10] ulongArray = [2, 4, 6, 8, 10, 12, 14, 16, 19, 20];

{
    auto array = byteArray;
    byte* ptr = &array[0];
    byte* prevPtr = atomicFetchAdd(ptr, 3);
    assert(prevPtr == &array[0]);
    assert(*prevPtr == 1);
    assert(*ptr == 7);
}
{
    auto array = ulongArray;
    ulong* ptr = &array[0];
    ulong* prevPtr = atomicFetchAdd(ptr, 3);
    assert(prevPtr == &array[0]);
    assert(*prevPtr == 2);
    assert(*ptr == 8);
}

///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////

shared ubyte u8 = 1;
shared ushort u16 = 2;
shared uint u32 = 3;
shared byte i8 = 5;
shared short i16 = 6;
shared int i32 = 7;

assert(atomicOp!"-="(u8, 1) == 0);
assert(atomicOp!"-="(u16, 1) == 1);
assert(atomicOp!"-="(u32, 1) == 2);
assert(atomicOp!"-="(i8, 1) == 4);
assert(atomicOp!"-="(i16, 1) == 5);
assert(atomicOp!"-="(i32, 1) == 6);
version (D_LP64)
{
    shared ulong u64 = 4;
    shared long i64 = 8;
    assert(atomicOp!"-="(u64, 1) == 3);
    assert(atomicOp!"-="(i64, 1) == 7);
}

///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////

byte[10] byteArray = [1, 3, 5, 7, 9, 11, 13, 15, 17, 19];
ulong[10] ulongArray = [2, 4, 6, 8, 10, 12, 14, 16, 19, 20];

{
    auto array = byteArray;
    byte* ptr = &array[5];
    byte* prevPtr = atomicFetchSub(ptr, 4);
    assert(prevPtr == &array[5]);
    assert(*prevPtr == 11);
    assert(*ptr == 3); // https://issues.dlang.org/show_bug.cgi?id=21578
}
{
    auto array = ulongArray;
    ulong* ptr = &array[5];
    ulong* prevPtr = atomicFetchSub(ptr, 4);
    assert(prevPtr == &array[5]);
    assert(*prevPtr == 12);
    assert(*ptr == 4); // https://issues.dlang.org/show_bug.cgi?id=21578
}

///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////

shared ulong a = 2;
uint b = 1;
atomicOp!"-="(a, b);
assert(a == 1);

shared uint c = 2;
ubyte d = 1;
atomicOp!"-="(c, d);
assert(c == 1);

///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////

shared int i;
static assert(is(typeof(atomicLoad(i)) == int));

shared int* p;
static assert(is(typeof(atomicLoad(p)) == shared(int)*));

shared int[] a;
static if (__traits(compiles, atomicLoad(a)))
{
    static assert(is(typeof(atomicLoad(a)) == shared(int)[]));
}

static struct S { int* _impl; }
shared S s;
static assert(is(typeof(atomicLoad(s)) : shared S));
static assert(is(typeof(atomicLoad(s)._impl) == shared(int)*));
auto u = atomicLoad(s);
assert(u._impl is null);
u._impl = new shared int(42);
assert(atomicLoad(*u._impl) == 42);

static struct S2 { S s; }
shared S2 s2;
static assert(is(typeof(atomicLoad(s2).s) == TailShared!S));

static struct S3 { size_t head; int* tail; }
shared S3 s3;
static if (__traits(compiles, atomicLoad(s3)))
{
    static assert(is(typeof(atomicLoad(s3).head) == size_t));
    static assert(is(typeof(atomicLoad(s3).tail) == shared(int)*));
}

static class C { int i; }
shared C c;
static assert(is(typeof(atomicLoad(c)) == shared C));

static struct NoIndirections { int i; }
shared NoIndirections n;
static assert(is(typeof(atomicLoad(n)) == NoIndirections));

///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////

shared uint si1 = 45;
shared uint si2 = 38;
shared uint* psi = &si1;

assert((&psi).cas(cast(const) psi, &si2));

Meta