[8c267cf] | 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. |
---|