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.
|
---|