summaryrefslogtreecommitdiff
path: root/gcc/testsuite/gdc.test/runnable/previewin.d
blob: 117070dfe5e1af873fe2aead782433b9cdb51f89 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
// 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;
}