summaryrefslogtreecommitdiffstats
path: root/tests/language-feature/generics/where-optional-3.slang
blob: f8b3a490757da8d2c88d43ff33d93c1a39eb3b53 (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
//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=CHECK): -shaderobj
//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=CHECK): -vk -shaderobj
//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=CHECK): -cpu -shaderobj

//TEST_INPUT:ubuffer(data=[0 0 0 0 0 0 0 0], stride=4):out,name=outputBuffer
RWStructuredBuffer<int> outputBuffer;

interface IReleaseable
{
    [mutating]
    void release();
}

struct Container<K, V>
    where optional K : IReleaseable
    where optional V : IReleaseable
{
    K k[2];
    V v[2];

    [mutating]
    void erase(int index)
    {
        if (K is IReleaseable)
            k[index].release();
        if (V is IReleaseable)
            v[index].release();
    }
}

struct HeavyEntry: IReleaseable
{
    int index;
    int value;

    [mutating]
    void release()
    {
        outputBuffer[index] = value;
    }
};

struct LightEntry
{
    int value;
};

[numthreads(1, 1, 1)]
void computeMain(int3 dispatchThreadID: SV_DispatchThreadID)
{
    { // Neither is IReleaseable
        var c = Container<LightEntry, LightEntry>();
        c.k[0] = LightEntry(1);
        c.k[1] = LightEntry(2);
        c.v[0] = LightEntry(3);
        c.v[1] = LightEntry(4);
        c.erase(0);
        c.erase(1);
    }
    { // K is IReleaseable
        var c = Container<HeavyEntry, LightEntry>();
        c.k[0] = HeavyEntry(0,1);
        c.k[1] = HeavyEntry(1,2);
        c.v[0] = LightEntry(3);
        c.v[1] = LightEntry(4);
        // CHECK: 1
        c.erase(0);
        // CHECK-NEXT: 2
        c.erase(1);
    }
    { // V is IReleaseable
        var c = Container<LightEntry, HeavyEntry>();
        c.k[0] = LightEntry(1);
        c.k[1] = LightEntry(2);
        c.v[0] = HeavyEntry(2,3);
        c.v[1] = HeavyEntry(3,4);
        // CHECK-NEXT: 3
        c.erase(0);
        // CHECK-NEXT: 4
        c.erase(1);
    }
    { // K and V are IReleaseable
        var c = Container<HeavyEntry, HeavyEntry>();
        c.k[0] = HeavyEntry(4,5);
        c.k[1] = HeavyEntry(6,7);
        c.v[0] = HeavyEntry(5,6);
        c.v[1] = HeavyEntry(7,8);
        // CHECK-NEXT: 5
        // CHECK-NEXT: 6
        c.erase(0);
        // CHECK-NEXT: 7
        // CHECK-NEXT: 8
        c.erase(1);
    }
}