Changeset 47bd204
- Timestamp:
- Feb 5, 2024, 2:17:51 AM (10 months ago)
- Branches:
- master
- Children:
- c17dc80, e11cdc0
- Parents:
- a55ebcc (diff), be4335b (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/proposals/enum.tex
ra55ebcc r47bd204 121 121 Naming values is a common practice in mathematics and engineering, e.g., $\pi$, $\tau$ (2$\pi$), $\phi$ (golden ratio), MHz (1E6), etc. 122 122 Naming is also commonly used to represent many other numerical phenomenon, such as days of the week, months of a year, floors of a building (basement), time (noon, New Years). 123 Many programming languages capture this important capability through a mechanism called an \newterm{enumeration}.123 Many programming languages capture this important software-engineering capability through a mechanism called an \newterm{enumeration}. 124 124 An enumeration is similar to other programming-language types by providing a set of constrained values, but adds the ability to name \emph{all} the values in its set. 125 125 Note, all enumeration names must be unique but different names can represent the same value (eight note, quaver), which are synonyms. 126 126 127 Specifically, an enumerated type is a type whose values are restrictedto a fixed set of named constants.127 Specifically, an enumerated type restricts its values to a fixed set of named constants. 128 128 Fundamentally, all types are restricted to a fixed set of values because of the underlying von Neumann architecture, and hence, to a corresponding set of constants, e.g., @3@, @3.5@, @3.5+2.1i@, @'c'@, @"abc"@, etc. 129 129 However, the values for basic types are not named, other than the programming-language supplied constants. … … 132 132 \section{C-Style Enum} 133 133 134 The C-Style enumeration has the following syntax and semantics .134 The C-Style enumeration has the following syntax and semantics, and is representative of enumerations in many other programming languages (see Section~\ref{s:RelatedWork}). 135 135 \begin{lstlisting}[label=lst:weekday] 136 136 enum Weekday { Monday, Tuesday, Wednesday, Thursday@ = 10@, Friday, Saturday, Sunday }; … … 139 139 \end{lstlisting} 140 140 Here, the enumeration type @Weekday@ defines the ordered \newterm{enumerator}s @Monday@, @Tuesday@, @Wednesday@, @Thursday@, @Friday@, @Saturday@ and @Sunday@. 141 The successor of @Tuesday@ is @Monday@ and the predecessor of @Tuesday@ is @Wednesday@. 142 A C enumeration is implemented by an integral type, with consecutive enumerator values assigned by the compiler starting at zero or the next explicitly initialized value. 143 For example, @Monday@ to @Wednesday@ have values 0--2 implicitly set by the compiler, @Thursday@ is explicitly set to @10@, and @Friday@ to @Sunday@ have values 11--13 implicitly set by the compiler. 144 145 There are 3 attributes for an enumeration: \newterm{position}, \newterm{label}, and \newterm{value}: 141 By convention, the successor of @Tuesday@ is @Monday@ and the predecessor of @Tuesday@ is @Wednesday@, independent of the associated enumerator constants. 142 Because an enumerator is a constant, it cannot appear in a mutable context, e.g. @Mon = Sun@ is meaningless, and has no address, it is an rvalue\footnote{ 143 The term rvalue defines an expression that can only appear on the right-hand side of an assignment.}. 144 Enumerators without explicitly designated constants are auto-initialized by the compiler: from left to right, starting at zero or the next explicitly initialized constant, incrementing by @1@. 145 For example, @Monday@ to @Wednesday@ are implicitly assigned with constants 0--2, @Thursday@ is explicitly set to constant @10@, and @Friday@ to @Sunday@ are implicitly assigned with constants 11--13. 146 Hence, there are 3 universal enumeration attributes: \newterm{position}, \newterm{label}, and \newterm{value}: 146 147 \begin{cquote} 147 148 \small\sf\setlength{\tabcolsep}{3pt} 148 149 \begin{tabular}{rccccccccccc} 149 @enum@ Weekday \{ & Monday, & Tuesday, & Wednesday, & Thursday =10,& Friday, & Saturday, & Sunday \}; \\150 \it 151 \it 152 \it 150 @enum@ Weekday \{ & Monday, & Tuesday, & Wednesday, & Thursday = 10,& Friday, & Saturday, & Sunday \}; \\ 151 \it\color{red}position & 0 & 1 & 2 & 3 & 4 & 5 & 6 \\ 152 \it\color{red}label & Monday & Tuesday & Wednesday & Thursday & Friday & Saturday & Sunday \\ 153 \it\color{red}value & 0 & 1 & 2 & {\color{red}10}& 11 & 12 & 13 153 154 \end{tabular} 154 155 \end{cquote} 155 156 The enumerators of an enumeration are unscoped, i.e., enumerators declared inside of an @enum@ are visible in the enclosing scope of the @enum@ type. 156 Finally, C enumerators are \newterm{unscoped}, i.e., enumerators declared inside of an @enum@ are visible in the enclosing scope of the @enum@ type. 157 158 In theory, a C enumeration \emph{variable} is an implementation-defined integral type large enough to hold all enumerated values. 159 In practice, since integral constants in C have type @int@ (unless qualified with a size suffix), C uses @int@ as the underlying type for enumeration variables. 157 160 Furthermore, there is an implicit bidirectional conversion between an enumeration and integral types. 158 161 \begin{lstlisting}[label=lst:enum_scope] 159 162 { 160 163 enum Weekday { ... }; $\C{// enumerators implicitly projected into local scope}$ 161 Weekday weekday = Monday; 164 Weekday weekday = Monday; $\C{// weekday == 0}$ 162 165 weekday = Friday; $\C{// weekday == 11}$ 163 int i = Sunday $\C{// i == 13}$164 weekday = 10000; $\C{// undefined behaviour}$166 int i = Sunday $\C{// implicit conversion to int, i == 13}$ 167 weekday = 10000; $\C{// UNDEFINED! implicit conversion to Weekday}$ 165 168 } 166 169 int j = Wednesday; $\C{// ERROR! Wednesday is not declared in this scope}$ 167 170 \end{lstlisting} 171 The implicit conversion from @int@ to an enumeration type is an unnecessary source of error. 168 172 169 173 \section{\CFA-Style Enum} … … 175 179 176 180 \CFA extends the enumeration by parameterizing the enumeration with a type for the enumerators, allowing enumerators to be assigned any values from the declared type. 177 \begin{lstlisting}[label=lst:color] 178 enum( @char@ ) Currency { Dollar = '$\textdollar$', Euro = '$\texteuro$', Pound = '$\textsterling$' }; 179 enum( @double@ ) Planet { Venus = 4.87, Earth = 5.97, Mars = 0.642 }; // mass 180 enum( @char *@ ) Colour { Red = "red", Green = "green", Blue = "blue" }; 181 enum( @Currency@ ) Europe { Euro = '$\texteuro$', Pound = '$\textsterling$' }; // intersection 182 \end{lstlisting} 183 The types of the enumerators are @char@, @double@, and @char *@ and each enumerator is initialized with corresponding type values. 184 % Only types with a defined ordering can be automatically initialized (see Section~\ref{s:AutoInitializable}). 185 186 % An instance of \CFA-enum (denoted as @<enum_instance>@) is a label for the defined enum name. 187 % The label can be retrieved by calling the function @label( <enum_instance> )@. 188 % Similarly, the @value()@ function returns the value used to initialize the \CFA-enum. 181 Figure~\ref{f:EumeratorTyping} shows a series of examples illustrating that all \CFA types can be use with an enumeration and each type's constants used to set the enumerators. 182 183 Typed enumerates deals with \emph{harmonizing} problem between an enumeration and its companion data. 184 The following example is from the \CFA compiler, written in \CC. 185 \begin{lstlisting} 186 enum integral_types { chr, schar, uschar, sshort, ushort, sint, usint, ..., NO_OF_ITYPES }; 187 char * integral_names[NO_OF_ITYPES] = { 188 "char", "signed char", "unsigned char", 189 "signed short int", "unsigned short int", 190 "signed int", "unsigned int", 191 ... 192 }; 193 \end{lstlisting} 194 The \emph{harmonizing} problem occurs because the enumeration declaration is in one header file and the names are declared in another translation unit. 195 It is up to the programmer to ensure changes made in one location are harmonized with the other location (by identifying this requirement within a comment). 196 The typed enumeration largely solves this problem by combining and managing the two data types. 197 \begin{lstlisting} 198 enum( char * ) integral_types { 199 chr = "char", schar = "signed char", uschar = "unsigned char", 200 sshort = "signed short int", ushort = "unsigned short int", 201 sint = "signed int", usint = "unsigned int", 202 ... 203 }; 204 \end{lstlisting} 205 206 % \begin{lstlisting}[label=lst:color] 207 % struct S { int i, j; }; 208 % enum( S ) s { A = { 3, 4 }, B = { 7, 8 } }; 209 % enum( @char@ ) Currency { Dollar = '$\textdollar$', Euro = '$\texteuro$', Pound = '$\textsterling$' }; 210 % enum( @double@ ) Planet { Venus = 4.87, Earth = 5.97, Mars = 0.642 }; // mass 211 % enum( @char *@ ) Colour { Red = "red", Green = "green", Blue = "blue" }; 212 % enum( @Currency@ ) Europe { Euro = '$\texteuro$', Pound = '$\textsterling$' }; // intersection 213 % \end{lstlisting} 214 215 \begin{figure} 216 \begin{lstlisting} 217 // integral 218 enum( @char@ ) Currency { Dollar = '$\textdollar$', Euro = '$\texteuro$', Pound = '$\textsterling$' }; 219 enum( @signed char@ ) srgb { Red = -1, Green = 0, Blue = 1 }; 220 enum( @long long int@ ) BigNum { X = 123_456_789_012_345, Y = 345_012_789_456_123 }; 221 // non-integral 222 enum( @double@ ) Math { PI_2 = 1.570796, PI = 3.141597, E = 2.718282 }; 223 enum( @_Complex@ ) Plane { X = 1.5+3.4i, Y = 7+3i, Z = 0+0.5i }; 224 // pointer 225 enum( @char *@ ) Names { Fred = "Fred", Mary = "Mary", Jane = "Jane" }; 226 int i, j, k; 227 enum( @int *@ ) ptr { I = &i, J = &j, K = &k }; 228 enum( @int &@ ) ref { I = i, J = j, K = k }; 229 // tuple 230 enum( @[int, int]@ ) { T = [ 1, 2 ] }; 231 // function 232 void f() {...} void g() {...} 233 enum( @void (*)()@ ) funs { F = f, G = g }; 234 // aggregate 235 struct Person { char * name; int age, height; }; 236 enum( @Person@ ) friends { Liz = { "Elizabeth", 22, 170 }, Beth = Liz, Jon = { "Jonathan", 35, 190 } }; 237 \end{lstlisting} 238 \caption{Enumerator Typing} 239 \label{f:EumeratorTyping} 240 \end{figure} 241 242 \subsection{Pure Enumerators} 243 244 An empty type, @enum()@, implies the enumerators are pure symbols without values; 245 hence, there is no default conversion to @int@. 246 247 \begin{lstlisting} 248 enum() Mode { O_RDONLY, O_WRONLY, O_CREAT, O_TRUNC, O_APPEND }; 249 Mode iomode = O_RDONLY; 250 int i = iomode; $\C{\color{red}// disallowed}$ 251 sout | O_TRUNC; $\C{\color{red}// disallowed}$ 252 \end{lstlisting} 253 254 \subsection{Enumerator Subset} 255 256 If follows from enumerator typing that the type of the enumerators can be another enumerator. 257 \begin{lstlisting} 258 enum( char ) Letter { A = 'A', B = 'B', C = 'C', ..., Z = 'Z' }; 259 enum( Letter ) Greek { Alph = A, Beta = B, ..., Zeta = Z }; // alphabet intersection 260 Letter letter = A; 261 Greak greek = Alph; 262 letter = Alph; $\C{// allowed}$ 263 greek = A; $\C{\color{red}// disallowed}$ 264 \end{lstlisting} 265 Enumeration @Greek@ may have more or less enumerators than @Letter@, but the enumerator values must be from @Letter@. 266 Therefore, @Greek@ enumerators are a subset of type @Letter@ and are type compatible with enumeration @Letter@, but @Letter@ enumerators are not type compatible with enumeration @Greek@. 267 268 \subsection{Enumeration Inheritance} 269 270 \CFA Plan-9 inheritance may be used with enumerations. 271 \begin{lstlisting} 272 enum( char * ) Name2 { @inline Name@, Jack = "Jack", Jill = "Jill" }; 273 enum /* inferred */ Name3 { @inline Name2@, Sue = "Sue", Tom = "Tom" }; 274 \end{lstlisting} 275 Enumeration @Name2@ inherits all the enumerators and their values from enumeration @Name@ by containment, and a @Name@ enumeration is a subtype of enumeration @Name2@. 276 Note, enumerators must be unique in inheritance but enumerator values may be repeated. 277 278 The enumeration type for the inheriting type must be the same as the inherited type; 279 hence the enumeration type may be omitted for the inheriting enumeration and it is inferred from the inherited enumeration, as for @Name3@. 280 When inheriting from integral types, automatic numbering may be used, so the inheritance placement left to right is important. 281 282 Specifically, the inheritance relationship for Names is: 283 \begin{lstlisting} 284 Name $\(\subset\)$ Name2 $\(\subset\)$ Name3 $\(\subset\)$ const char * // enum type of Name 285 \end{lstlisting} 286 For the given function prototypes, the following calls are valid. 287 \begin{cquote} 288 \begin{tabular}{ll} 289 \begin{lstlisting} 290 void f( Name ); 291 void g( Name2 ); 292 void h( Name3 ); 293 void j( const char * ); 294 \end{lstlisting} 295 & 296 \begin{lstlisting} 297 f( Fred ); 298 g( Fred ); g( Jill ); 299 h( Fred ); h( Jill ); h( Sue ); 300 j( Fred ); j( Jill ); j( Sue ); j( "Will" ); 301 \end{lstlisting} 302 \end{tabular} 303 \end{cquote} 304 Note, the validity of calls is the same for call-by-reference as for call-by-value, and const restrictions are the same as for other types. 189 305 190 306 \subsection{Enumerator Scoping} … … 220 336 Enumeration Greek may have more or less enumerators than Letter, but the enumerator values must be from Letter. 221 337 Therefore, Greek enumerators are a subset of type Letter and are type compatible with enumeration Letter, but Letter enumerators are not type compatible with enumeration Greek. 338 339 % An instance of \CFA-enum (denoted as @<enum_instance>@) is a label for the defined enum name. 340 % The label can be retrieved by calling the function @label( <enum_instance> )@. 341 % Similarly, the @value()@ function returns the value used to initialize the \CFA-enum. 222 342 223 343 \subsubsection{\lstinline{enumerate()}} … … 926 1046 927 1047 \section{Related Work} 928 929 Enumerations exist in many popular programming languages, e.g., Pascal, Ada, \Csharp, \CC, Go, Java, Modula-3, Rust, Swift, Python, and Algebraic data type in functional programming. 930 There are a large set of overlapping features for all the languages, but each language has its own unique restrictions and extensions. 931 932 \subsection{Pascal} 1048 \label{s:RelatedWork} 1049 1050 Enumerations exist in many popular programming languages, e.g., Pascal, Ada, \Csharp, \CC, Go, Java, Modula-3, Rust, Swift, Python, and the algebraic data-type in functional programming. 1051 There are a large set of overlapping features among these languages, but each language has its own unique restrictions and extensions. 1052 1053 \subsection{(Free) Pascal} 1054 1055 Free Pascal is a modern object-oriented version of the classic Pascal programming language. 1056 It allows a C-style enumeration type, where enumerators must be in assigned in ascending numerical order with a constant expression and the range can be non-consecutive. 1057 \begin{lstlisting}[language=pascal,{moredelim=**[is][\color{red}]{@}{@}}] 1058 Type EnumType = ( one, two, three, forty @= 40@, fortyone ); 1059 \end{lstlisting} 1060 Pseudo-functions @Pred@ and @Succ@ can only be used if the range is consecutive. 1061 The underlying type is an implementation-defined integral type large enough to hold all enumerated values; it does not have to be the smallest possible type. 1062 The size underlying integral type can be explicitly specified using compiler directive @$PACKENUM@~$N$, where $N$ is the number of bytes, e.g.: 1063 \begin{lstlisting}[language=pascal,{moredelim=**[is][\color{red}]{@}{@}}] 1064 Type @{$\color{red}\$$PACKENUM 1}@ SmallEnum = ( one, two, three ); 1065 @{$\color{red}\$$PACKENUM 4}@ LargeEnum = ( BigOne, BigTwo, BigThree ); 1066 Var S : SmallEnum; { 1 byte } 1067 L : LargeEnum; { 4 bytes} 1068 \end{lstlisting} 1069 933 1070 934 1071 \subsection{Ada} 935 1072 1073 An enumeration type is defined as a list of possible values: 1074 \begin{lstlisting}[language=ada] 1075 type RGB is (Red, Green, Blue); 1076 \end{lstlisting} 1077 Like for numeric types, where e.g., 1 is an integer literal, @Red@, @Green@ and @Blue@ are called the literals of this type. 1078 There are no other values assignable to objects of this type. 1079 1080 \paragraph{Operators and attributes} ~\newline 1081 Apart from equality (@"="@), the only operators on enumeration types are the ordering operators: @"<"@, @"<="@, @"="@, @"/="@, @">="@, @">"@, where the order relation is given implicitly by the sequence of literals: 1082 Each literal has a position, starting with 0 for the first, incremented by one for each successor. 1083 This position can be queried via the @'Pos@ attribute; the inverse is @'Val@, which returns the corresponding literal. In our example: 1084 \begin{lstlisting}[language=ada] 1085 RGB'Pos (Red) = 0 1086 RGB'Val (0) = Red 1087 \end{lstlisting} 1088 There are two other important attributes: @Image@ and @Value@. 1089 @Image@ returns the string representation of the value (in capital letters), @Value@ is the inverse: 1090 \begin{lstlisting}[language=ada] 1091 RGB'Image ( Red ) = "RED" 1092 RGB'Value ("Red") = Red 1093 \end{lstlisting} 1094 These attributes are important for simple IO (there are more elaborate IO facilities in @Ada.Text_IO@ for enumeration types). 1095 Note that, since Ada is case-insensitive, the string given to @'Value@ can be in any case. 1096 1097 \paragraph{Enumeration literals} ~\newline 1098 Literals are overloadable, i.e. you can have another type with the same literals. 1099 \begin{lstlisting}[language=ada] 1100 type Traffic_Light is (Red, Yellow, Green); 1101 \end{lstlisting} 1102 Overload resolution within the context of use of a literal normally resolves which @Red@ is meant. 1103 Only if you have an unresolvable overloading conflict, you can qualify with special syntax which @Red@ is meant: 1104 \begin{lstlisting}[language=ada] 1105 RGB'(Red) 1106 \end{lstlisting} 1107 Like many other declarative items, enumeration literals can be renamed. 1108 In fact, such a literal is actually a function, so it has to be renamed as such: 1109 \begin{lstlisting}[language=ada] 1110 function Red return P.RGB renames P.Red; 1111 \end{lstlisting} 1112 Here, @RGB@ is assumed to be defined in package @P@, which is visible at the place of the renaming declaration. 1113 Renaming makes @Red@ directly visible without necessity to resort the use-clause. 1114 1115 Note that redeclaration as a function does not affect the staticness of the literal. 1116 1117 \paragraph{Characters as enumeration literals} ~\newline 1118 Rather unique to Ada is the use of character literals as enumeration literals: 1119 \begin{lstlisting}[language=ada] 1120 type ABC is ('A', 'B', 'C'); 1121 \end{lstlisting} 1122 This literal @'A'@ has nothing in common with the literal @'A'@ of the predefined type @Character@ (or @Wide_Character@). 1123 1124 Every type that has at least one character literal is a character type. 1125 For every character type, string literals and the concatenation operator @"&"@ are also implicitly defined. 1126 \begin{lstlisting}[language=ada] 1127 type My_Character is (No_Character, 'a', Literal, 'z'); 1128 type My_String is array (Positive range <>) of My_Character; 1129 1130 S: My_String := "aa" & Literal & "za" & 'z'; 1131 T: My_String := ('a', 'a', Literal, 'z', 'a', 'z'); 1132 \end{lstlisting} 1133 In this example, @S@ and @T@ have the same value. 1134 1135 Ada's @Character@ type is defined that way. 1136 See Ada Programming/Libraries/Standard. 1137 1138 \paragraph{Booleans as enumeration literals} ~\newline 1139 Also Booleans are defined as enumeration types: 1140 \begin{lstlisting}[language=ada] 1141 type Boolean is (False, True); 1142 \end{lstlisting} 1143 There is special semantics implied with this declaration in that objects and expressions of this type can be used as conditions. 1144 Note that the literals @False@ and @True@ are not Ada keywords. 1145 1146 Thus it is not sufficient to declare a type with these literals and then hope objects of this type can be used like so: 1147 \begin{lstlisting}[language=ada] 1148 type My_Boolean is (False, True); 1149 Condition: My_Boolean; 1150 1151 if Condition then -- wrong, won't compile 1152 \end{lstlisting} 1153 1154 If you need your own Booleans (perhaps with special size requirements), you have to derive from the predefined Boolean: 1155 \begin{lstlisting}[language=ada] 1156 type My_Boolean is new Boolean; 1157 Condition: My_Boolean; 1158 1159 if Condition then -- OK 1160 \end{lstlisting} 1161 1162 \paragraph{Enumeration subtypes} ~\newline 1163 You can use range to subtype an enumeration type: 1164 \begin{lstlisting}[language=ada] 1165 subtype Capital_Letter is Character range 'A' .. 'Z'; 1166 type Day_Of_Week is (Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday); 1167 subtype Working_Day is Day_Of_Week range Monday .. Friday; 1168 \end{lstlisting} 1169 1170 \paragraph{Using enumerations} ~\newline 1171 Enumeration types being scalar subtypes, type attributes such as @First@ and @Succ@ will allow stepping through a subsequence of the values. 1172 \begin{lstlisting}[language=ada] 1173 case Day_Of_Week'First is 1174 when Sunday => 1175 ISO (False); 1176 when Day_Of_Week'Succ(Sunday) => 1177 ISO (True); 1178 when Tuesday .. Saturday => 1179 raise Program_Error; 1180 end case; 1181 \end{lstlisting} 1182 A loop will automatically step through the values of the subtype's range. 1183 Filtering week days to include only working days with an even position number: 1184 \begin{lstlisting}[language=ada] 1185 for Day in Working_Day loop 1186 if Day_Of_Week'Pos(Day) mod 2 = 0 then 1187 Work_In_Backyard; 1188 end if; 1189 end loop; 1190 \end{lstlisting} 1191 Enumeration types can be used as array index subtypes, yielding a table feature: 1192 \begin{lstlisting}[language=ada] 1193 type Officer_ID is range 0 .. 50; 1194 type Schedule is array (Working_Day) of Officer_ID; 1195 \end{lstlisting} 1196 1197 \begin{lstlisting}[language=ada] 1198 type Subtype_Name is (Id1, Id2, Id3 ... ); 1199 \end{lstlisting} 1200 where @Id1@, @Id2@, etc. are identifiers or characters literals. 1201 In either case, the legal values of the type are referred to as "enumeration literals." 1202 Each of these values has a "position number" corresponding to its position in the list such that @Id1@ has position 0, @Id2@ has position 1, and the Nth value has position N-1. 1203 1204 \paragraph{Attributes of Enumeration Types} ~\newline 1205 An enumeration type, @T@, has the following attributes: @T'First@, @T'Last@, @T'Range@, @T'Pred@, @T'Succ@, @T'Min@, @T'Max@, @T'Image@, @T'Wide_Image@, @T'Value@, @T'Wide_Value@, @T'Pos@, and @T'Val@ (pronounced "T tick first", "T tick last", etc.). 1206 Most of these are illustrated in the example program given below, and most of them produce what you would intuitively expect based on their names. 1207 1208 @T'Image@ and @T'Value@ form a complementary pair of attributes. 1209 The former takes a value in @T@ and returns a String representation of that value. 1210 The latter takes a @String@ that is a representation of a value in @T@ and returns that value. 1211 1212 @T'Pos@ and @T'Val@ form another complementary pair. 1213 The former takes a value in @T@ and returns its position number. 1214 The latter takes a position number and returns the corresponding value of type @T@. 1215 1216 936 1217 \subsection{\Csharp} 937 1218 938 1219 \subsection{\CC} 939 1220 940 Because \CC is backwards compatible with C, it inherited C's enumerations, except there is no implicit conversion from an integral value to an enumeration; 941 hence, the values in a \CC enumeration can only be its enumerators. 942 943 \CC{11} extended enumeration with a scoped enumeration, \lstinline[language=c++]{enum class} (or \lstinline[language=c++]{enum struct}), where the enumerators are local to the enumeration and are accessed using type qualification, e.g., @Weekday::Monday@. 1221 \CC is backwards compatible with C, so it inherited C's enumerations, except there is no implicit conversion from an integral value to an enumeration; 1222 hence, the values in a \CC enumeration can only be its enumerators (without a cast). 1223 There is no mechanism to iterate through an enumeration. 1224 1225 \CC{11} added a scoped enumeration, \lstinline[language=c++]{enum class} (or \lstinline[language=c++]{enum struct}), so the enumerators are local to the enumeration and must be accessed using type qualification, e.g., @Weekday::Monday@. 944 1226 \CC{20} supports unscoped access with a \lstinline[language=c++]{using enum} declaration. 945 1227 946 For both unscoped and scoped enumerations, the underlying type is an implementation-defined integral type that islarge enough to hold all enumerated values; it does not have to be the smallest possible type.947 The underlying integral type can be explicitly specified:1228 For both unscoped and scoped enumerations, the underlying type is an implementation-defined integral type large enough to hold all enumerated values; it does not have to be the smallest possible type. 1229 In \CC{11}, the underlying integral type can be explicitly specified: 948 1230 \begin{lstlisting}[language=c++,{moredelim=**[is][\color{red}]{@}{@}}] 949 1231 enum class RGB : @long@ { Red, Green, Blue }; 950 1232 enum class rgb : @char@ { Red = 'r', Green = 'g', Blue = 'b' }; 951 1233 enum class srgb : @signed char@ { Red = -1, Green = 0, Blue = 1 }; 1234 RGB colour1 = @RGB::@Red; 1235 rgb colour2 = @rgb::@Red; 1236 srgb colour3 = @srgb::@Red; 952 1237 \end{lstlisting} 953 1238 -
src/GenPoly/Box.cpp
ra55ebcc r47bd204 25 25 #include "AST/GenericSubstitution.hpp" // for genericSubstitution 26 26 #include "CodeGen/OperatorTable.h" // for isAssignment 27 #include "Common/Iterate.hpp" // for group_iterate 27 28 #include "Common/ScopedMap.h" // for ScopedMap 29 #include "Common/ToString.hpp" // for toCString 28 30 #include "Common/UniqueName.h" // for UniqueName 29 #include "Common/utility.h" // for toCString, group_iterate30 31 #include "GenPoly/FindFunction.h" // for findFunction 31 32 #include "GenPoly/GenPoly.h" // for getFunctionType, ... … … 236 237 ) ); 237 238 // TODO: Polymorphic types will be out of the struct declaration scope. 238 // Should be removed by PolyGenericCalculator.239 // This breaks invariants until it is corrected later. 239 240 for ( auto const & member : enumerate( decl->members ) ) { 240 241 auto dwt = member.val.strict_as<ast::DeclWithType>(); … … 309 310 ) ); 310 311 // TODO: Polymorphic types will be out of the union declaration scope. 312 // This breaks invariants until it is corrected later. 311 313 for ( auto const & member : decl->members ) { 312 314 auto dwt = member.strict_as<ast::DeclWithType>(); … … 575 577 if ( adapters.contains( mangleName ) ) continue; 576 578 std::string adapterName = makeAdapterName( mangleName ); 577 // TODO: The forwarding here is problematic because these578 // declarations are not rooted anywhere in the translation unit.579 // NODE: This creates floating nodes, breaking invariants. 580 // This is corrected in the RewireAdapters sub-pass. 579 581 adapters.insert( 580 582 mangleName, … … 639 641 640 642 TypeVarMap exprTypeVars; 641 // TODO: Should this take into account the variables already bound in642 // scopeTypeVars ([ex] remove them from exprTypeVars)?643 643 makeTypeVarMap( function, exprTypeVars ); 644 644 auto dynRetType = isDynRet( function, exprTypeVars ); … … 1521 1521 1522 1522 // -------------------------------------------------------------------------- 1523 // TODO: Ideally, there would be no floating nodes at all.1524 1523 /// Corrects the floating nodes created in CallAdapter. 1525 1524 struct RewireAdapters final : public ast::WithGuards { … … 1837 1836 1838 1837 // Not all members of a polymorphic type are themselves of a polymorphic 1839 // type; in this cas the member expression should be wrapped and1838 // type; in this case the member expression should be wrapped and 1840 1839 // dereferenced to form an lvalue. 1841 1840 if ( !isPolyType( memberType, scopeTypeVars ) ) {
Note: See TracChangeset
for help on using the changeset viewer.