1 | Alternate Enumeration Types |
---|
2 | =========================== |
---|
3 | A proposal to rework enumeration types. |
---|
4 | |
---|
5 | This is a new design for enumerations in Cforall. |
---|
6 | They are based around extending C enumerations focusing on the logical |
---|
7 | view of enumerations, keeping the underlying representation opaque. |
---|
8 | |
---|
9 | This does replace some of the existing features of Cforall; so implementing |
---|
10 | it will require redoing some work. However, while I do think the improvement |
---|
11 | will be worth it, I have included notes about how to regain some of the |
---|
12 | functionality/ease-of-use of typed enumerations. Because many of these uses |
---|
13 | were in the area of "enums as macros", some are not even enumeration features. |
---|
14 | |
---|
15 | Note that all the new syntax and names are only examples; |
---|
16 | in addition to any functionally changes that could happen. |
---|
17 | |
---|
18 | Sequential Enumerations |
---|
19 | ---------------------- |
---|
20 | The sequential enumeration is the most basic form of enumeration. |
---|
21 | |
---|
22 | ```cfa |
---|
23 | enum Colour seq { |
---|
24 | Red, |
---|
25 | Purple, |
---|
26 | Violet = Purple, |
---|
27 | Blue, |
---|
28 | Green, |
---|
29 | Yellow, |
---|
30 | Orange, |
---|
31 | }; |
---|
32 | ``` |
---|
33 | |
---|
34 | Uses traditional enum declaration syntax, where each label is uninitialized |
---|
35 | or initialized to another label in the enumeration (no cycles, possibly |
---|
36 | limited to previous labels). |
---|
37 | |
---|
38 | Uninitialized labels introduce a new possible value into the enumeration. |
---|
39 | This value has no representation beyond the label(s) that represents it. |
---|
40 | Initialized labels are simple aliases to an existing value. |
---|
41 | |
---|
42 | A type created this way automatically supports: copy construction, |
---|
43 | copy assignment, destruction and equality, inequality and ordering with |
---|
44 | itself. Each value is equal only to itself, so labels are equal to themselves |
---|
45 | and other labels via aliasing. Values are ordered low to high by first to |
---|
46 | last appearance of the uninitialized label. |
---|
47 | They can also be used in a switch statement with the labels used in case |
---|
48 | labels. |
---|
49 | (Default construction could be added by picking one of the labels - say the |
---|
50 | first - to be the default.) |
---|
51 | |
---|
52 | Note: This does not add the enumeration labels to the enclosing scope. Use |
---|
53 | qualification to access it or write `inline enum Colour seq ...` to begin |
---|
54 | the enumeration. |
---|
55 | This is dependent on the module and namespacing system design. |
---|
56 | |
---|
57 | Enumerated Arrays |
---|
58 | ----------------- |
---|
59 | Arrays that use an enumeration as their index. The entire enumeration type |
---|
60 | (instead of a subset of int) is used in the index operation. |
---|
61 | |
---|
62 | ```cfa |
---|
63 | extern string colourNames[Colour]; |
---|
64 | ``` |
---|
65 | |
---|
66 | This example is a forward declaration that declares the symbol but does not |
---|
67 | give the values or allocate any storage. This is used in header files. |
---|
68 | The type of colourNames would be a new type `string[Colour]`. |
---|
69 | |
---|
70 | In implementation tiles it is safe to give the array's values; |
---|
71 | whether it the array has been previously forward declared or not. |
---|
72 | ```cfa |
---|
73 | string colourNames[Colour] = { |
---|
74 | "red", |
---|
75 | "violet", |
---|
76 | "blue", |
---|
77 | // Or without worrying about ordering: |
---|
78 | [Green] = "green", |
---|
79 | [Orange] = "orange", |
---|
80 | [Yellow] = "yellow", |
---|
81 | }; |
---|
82 | ``` |
---|
83 | |
---|
84 | The forward declaration and full definition variants allow the user to manage |
---|
85 | memory themselves, following the same rules as `extern` variables. |
---|
86 | The user can use `const` to fix the values in the array. |
---|
87 | |
---|
88 | Except for the index type (and that the size of the array is fixed per |
---|
89 | index type, as it always covers the whole enumeration) it should be the same |
---|
90 | as a traditional array. |
---|
91 | |
---|
92 | Or one of the new safer Cforall arrays, as the features could be combined. |
---|
93 | |
---|
94 | Combined Declaration |
---|
95 | -------------------- |
---|
96 | People have requested, as a convenience feature, the ability to declare the |
---|
97 | enumeration and the array in one go. I say "People have requested" because |
---|
98 | I'm still working on the details, from storage to syntax, but a rough sketch |
---|
99 | of the feature would look like this: |
---|
100 | |
---|
101 | ```cfa |
---|
102 | string colourNames[inline enum Colour] = { |
---|
103 | Red = "red", |
---|
104 | Purple = "violet", |
---|
105 | Blue = "blue", |
---|
106 | Green = "green", |
---|
107 | Yellow = "yellow", |
---|
108 | Orange = "orange", |
---|
109 | }; |
---|
110 | ``` |
---|
111 | |
---|
112 | This should possibly be implemented as an extension. |
---|
113 | |
---|
114 | Enumeration Iteration |
---|
115 | --------------------- |
---|
116 | Iterate through all values in a sequential enumeration. |
---|
117 | |
---|
118 | The design very dependent on the overall design of the for-each loop and |
---|
119 | iterators in general (when added to the language). |
---|
120 | However, the behaviour should just go over every value in the enumeration in |
---|
121 | order of the initial appearance in the declaration. |
---|
122 | |
---|
123 | Flag Set Enumerations |
---|
124 | --------------------- |
---|
125 | Another common use of enumerations is as a named bitset. |
---|
126 | |
---|
127 | ```cfa |
---|
128 | enum Directions flag { |
---|
129 | Up, |
---|
130 | Down, |
---|
131 | Left, |
---|
132 | Right, |
---|
133 | Upwards = Up, |
---|
134 | Vertical = Up | Down, |
---|
135 | }; |
---|
136 | ``` |
---|
137 | |
---|
138 | Uses the existing enumeration syntax, except that all initializers must be |
---|
139 | bitwise expressions, using only the operators |, & and ~ and, as leaf values, |
---|
140 | other labels from the enumeration (no cycles) and 0. |
---|
141 | |
---|
142 | Each uninitialized label creates a new flag. Every instance of the |
---|
143 | enumeration will have each flag be set or unset. The labels act as instances |
---|
144 | of the enumeration with only that flag set. |
---|
145 | |
---|
146 | A type created this way automatically supports: default construction, |
---|
147 | from zero_t construction, copy construction, copy assignment, destruction, |
---|
148 | equality, inequality and bitwise and (&), or (|) and not (~). |
---|
149 | Default construction and from zero_t construction create an instance with no |
---|
150 | flags set. Two instances are the same if the same flags are set. |
---|
151 | Bitwise operations act on the individual flags in the set. |
---|
152 | |
---|
153 | In addition the type can be converted to a Boolean. |
---|
154 | An flag set is truthy if any flags are set and falsy if no flags are set. |
---|
155 | This is not a primitive operation, but comes from combining the zero_t |
---|
156 | constructor and inequality. |
---|
157 | |
---|
158 | Note: Scoping rules are also waiting on the namespacing and module system. |
---|
159 | |
---|
160 | Named Literal |
---|
161 | ------------- |
---|
162 | (Replacing the "enum as macros" uses of typed enumerations.) |
---|
163 | |
---|
164 | A new storage class specifier called `literal`. It specifies that the value |
---|
165 | is not stored but it is inlined at each use. These can be used like a macro |
---|
166 | except they respect scoping rules and are resolved and evaluated once. |
---|
167 | |
---|
168 | A variable with literal storage allocates no memory and does not define |
---|
169 | any symbols for the linker. They must be initialized with a constant |
---|
170 | expression. All uses of a literal variable are rvalues (that is to say, they |
---|
171 | are treated as literals, you may not assign to them or get their address). |
---|
172 | |
---|
173 | ```cfa |
---|
174 | literal int two = 2; |
---|
175 | ``` |
---|
176 | |
---|
177 | To allow this, there may have to be restrictions on the types that can be |
---|
178 | used with literal storage class. Some more implementation details will have |
---|
179 | to be known to decide what those are. |
---|