File: xpostblit.d

package info (click to toggle)
gcc-arm-none-eabi 15%3A14.2.rel1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,099,328 kB
  • sloc: cpp: 3,627,108; ansic: 2,571,498; ada: 834,230; f90: 235,082; makefile: 79,231; asm: 74,984; xml: 51,692; exp: 39,736; sh: 33,298; objc: 15,629; python: 15,069; fortran: 14,429; pascal: 7,003; awk: 5,070; perl: 3,106; ml: 285; lisp: 253; lex: 204; haskell: 135
file content (136 lines) | stat: -rw-r--r-- 2,537 bytes parent folder | download | duplicates (5)
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
// PERMUTE_ARGS:

struct Field
{
    this(this) @safe @nogc pure nothrow {}
}

struct Counter
{
    static size_t cnt;
    this(this) @safe @nogc nothrow { ++cnt; }
}

struct Foo
{
    this(this) @safe @nogc pure nothrow {}
    Field field;
}

void test1() @safe @nogc pure nothrow
{
    Foo foo;
    foo.__xpostblit();
}

static assert(__traits(hasMember, Foo, "__xpostblit"));

//

struct FieldPostblit
{
    Counter counter;
}

struct AggrPostblit
{
    static size_t cnt;
    this(this) @safe @nogc nothrow { ++cnt; }
}

struct MixedPostblit
{
    static size_t cnt;
    Counter counter;
    this(this) @safe @nogc nothrow { ++cnt; }
}

struct SNoPostblit {}
class CNoPostblit {}

static assert(!__traits(hasMember, SNoPostblit, "__xpostblit"));
static assert(!__traits(hasMember, CNoPostblit, "__xpostblit"));

void test2() @safe @nogc nothrow
{
    FieldPostblit a;
    assert(Counter.cnt == 0);
    a.__xpostblit();
    assert(Counter.cnt == 1);
    AggrPostblit b;
    assert(AggrPostblit.cnt == 0);
    b.__xpostblit();
    assert(AggrPostblit.cnt == 1);
    Counter.cnt = 0;
    MixedPostblit c;
    assert(MixedPostblit.cnt == 0);
    assert(Counter.cnt == 0);
    c.__xpostblit();
    assert(MixedPostblit.cnt == 1);
    assert(Counter.cnt == 1);
}

/****************************************************************
 This test is intended to verify the exception safety of field
 postblits
*/
string trace = "";

struct FieldThrow
{
    string name;
    this(string n)
    {
        name = n;
    }

    bool throwExcept;
    this(this)
    {
        if (throwExcept)
        {
            throw new Exception("");
        }
    }

    ~this() { trace ~= name ~ ".dtor"; }
}

struct S
{
    auto f1 = FieldThrow("f1");
    FieldThrow[2] f2f3= [FieldThrow("f2"), FieldThrow("f3")];
    auto f4 = FieldThrow("f4");
}

void test3()
{
    trace = "";

    S s1;

    // Cause `s1.f4`'s postblit to throw
    s1.f4.throwExcept = true;

    try
    {
        // `s`'s postblit will be a combination of `f1`, `f2f3`, and `f4`'s
        // postblit in that order.  However, `f4`'s postblit will throw,
        // causing `s1.f2f3` and `s1.f1`'s destructors to execute in that
        // order
        S s2 = s1;
    }
    catch(Exception ex){ }

    // Confirm the field destructors were called and were called in the
    // corrrect order
    assert(trace == "f3.dtor" ~ "f2.dtor" ~ "f1.dtor");
}
/****************************************************************************/

void main()
{
    test1();
    test2();
    test3();
}