source: tests/array-collections/array-raii.hfa @ cfbc56ec

Last change on this file since cfbc56ec was cfbc56ec, checked in by Michael Brooks <mlbrooks@…>, 5 months ago

Enable array RAII and provide uninit(-), a uNoCtor equivalent.

Enable construction/destruction of "new" CFA array elements,
which was previously deactivated to avoid a compiler performance issue.
The enabled RAII steps more carefully around the performance issue.

Provide uninit(-), with tests covering the typical use case:

struct Foo;
void ?{}( Foo & this, int i ) { printf( "ctor at %d\n", i ); }
uninit(Foo) a[10]; no prints
for (i; 10) (a[i]){ i };
prints
array(uninit(Foo), 10) b; no prints
for (i; 10) (b[i]){ i };
prints

  • Property mode set to 100644
File size: 4.8 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2023 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// array-raii.hfa -- combined test implementation for both -c and -cfa versions
8//
9// Author           : Mike Brooks
10// Created On       : Fri Sep 22 15:00:00 2023
11// Last Modified By :
12// Last Modified On :
13// Update Count     :
14//
15
16
17#include <raii.hfa>
18
19// To keep C- vs CFA-array compatibility simple. these tests
20// - use only single-place subscripting, like `m[1][2]`, while deferring
21//   equivalence of m[1][2] vs m[1,2] to array-md-sbscr-cases
22// - declare arrays via test-specific ADECL macros
23
24
25
26volatile bool checkme = false;
27char junkref[] = "junk";
28extern "C" {
29    char* strcpy(char* destination, const char* source);
30}
31
32// Array of built-in type does not get zeroed
33//   (Surprised?)
34//   Because it has nothing to do with arrays.
35//   Built-in types have no-op ctors.
36//   (Still surprised?  Me too.)
37// If pigs flew and built-ins zeroed themselves, then
38//   Array of built-in type gets zeroed
39//   Array of user-defined type with autogen ctors gets wrapped builtins zeroed (intended purpose of case2 when originally written)
40//   Expected outcome becomes "all zero" twice
41// As is
42//   case1 pretty much just shows the summary statement above and
43//   verifying the case2-wrapper behaviour is just silly, so
44//   the quality of respecting autogens is checked (for real this time) under test_custom
45void test_builtins() {
46    void writeJunkOnStack(int depth) {
47        if (depth == 0) return;
48        char junk[5];
49        strcpy(junk, junkref);
50        writeJunkOnStack(depth-1);
51        if (checkme) printf("%s\n", junk);
52    }
53    void checkzero(float f0, float f1, float f2, float f3, float f4) {
54        if (f0 == 0.f && f1 == 0.f && f2 == 0.f && f3 == 0.f && f4 == 0.f) {
55            printf("all zero\n");
56        } else {
57            printf("some nonzero\n");
58          //printf("%f %f %f %f %f\n", f0, f1, f2, f3, f4);
59        }
60    }
61    void case1() {
62        ADECL1(x, float, 5)
63        checkzero(x[0], x[1], x[2], x[3], x[4]);
64    }
65    struct ffloat { float f; };
66    void case2() {
67        ADECL1(x, ffloat, 5)
68        checkzero(x[0].f, x[1].f, x[2].f, x[3].f, x[4].f);
69    }
70
71    writeJunkOnStack(5);
72    case1();
73    printf("silly: ");
74    writeJunkOnStack(5);
75    case2();
76}
77
78// Array of type with custom raii sees cdtors called
79// Array of user-defined type with autogen cdtors gets wrapped cdtors called
80void test_custom() {
81    int nctorcalls;
82    struct thing { int mem; };
83    void ?{}( thing & this ) {
84        (this.mem){ nctorcalls++ };
85        printf("ctor %d\n", this.mem);
86    }
87    void ^?{}( thing & this ) {
88        printf("dtor %d\n", this.mem);
89    }
90    struct wrapper1 { thing inner; };
91    forall( T ) struct wrapper2 { T inner; };
92    printf(" [1]\n");
93    {
94        nctorcalls = 0;
95        ADECL1(a, thing, 5)
96        for(i; 5) printf("func %d\n", a[i].mem);
97    }
98    printf(" [2]\n");
99    {
100        // White-box note: For the CFA array, the array cdtor is satisfying
101        // its own assertion, in a two-level recursive setup.
102        nctorcalls = 0;
103        ADECL2(a, thing, 2, 3)
104        for(i; 2) for(j; 3) printf("func %d at (%d, %d)\n", a[i][j].mem, i, j);
105    }
106    printf(" [3]\n");
107    {
108        nctorcalls = 0;
109        ADECL1(a, wrapper1, 5)
110        for(i; 5) printf("func %d\n", a[i].inner.mem);
111    }
112    printf(" [4]\n");
113    {
114        nctorcalls = 0;
115        ADECL1(a, wrapper2(thing), 5)
116        for(i; 5) printf("func %d\n", a[i].inner.mem);
117    }
118}
119
120// Array of uninits sees explicit ctor calls (only), and implied dtor calls
121void test_uninit() {
122    struct thing { int mem; };
123    void ?{}( thing & this, int i ) {
124        (this.mem){ i };
125        printf("ctor %d\n", this.mem);
126    }
127    void ?{}( thing & this ) {
128        (this){ 999 };
129    }
130    void ^?{}( thing & this ) {
131        printf("dtor %d\n", this.mem);
132    }
133    printf(" [1]\n");
134    {
135        ADECL1(a, uninit(thing), 5)
136        printf("before ctors\n");
137        for(i; 5) {
138            if (i == 1)
139                emplace(a[i]);
140            else if (i == 2)
141                emplace(a[i], 888);
142            else
143                (a[i]){i};
144        }
145        for(i; 5) printf("func %d\n", a[i].mem);
146    }
147    printf(" [2]\n");
148    {
149        ADECL2(a, uninit(thing), 2, 3)
150        printf("before ctors\n");
151        for(i; 2) for(j; 3) {
152            if (i == 1 && j == 1)
153                emplace(a[i][j]);
154            else if (i == 1 && j == 2)
155                emplace(a[i][j], 888);
156            else
157                (a[i][j]){100 + 10 * i + j};
158        }
159        for(i; 2) for(j; 3) {
160            printf("func %d at (%d, %d)\n", a[i][j].mem, i, j);
161        }
162    }
163}
164
165int main() {
166    printf("=== builtins\n");
167    test_builtins();
168
169    printf("=== custom\n");
170    test_custom();
171
172    printf("=== uninit\n");
173    test_uninit();
174}
Note: See TracBrowser for help on using the repository browser.