Changeset 1d5e5601


Ignore:
Timestamp:
Mar 1, 2024, 11:14:23 AM (4 months ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
master
Children:
647e2ea
Parents:
924534e
Message:

more proofreading on the enumeration related-work section

File:
1 edited

Legend:

Unmodified
Added
Removed
  • doc/theses/jiada_liang_MMath/relatedwork.tex

    r924534e r1d5e5601  
    22\label{s:RelatedWork}
    33
    4 An enumeration type exist in many popular programming languages, both past and present, \eg Pascal~\cite{Pascal}, Ada~\cite{Ada}, \Csharp~\cite{Csharp}, \CC, Go~\cite{Go}, Java~\cite{Java}, Modula-3~\cite{Modula-3}, Rust~\cite{Rust}, Swift~\cite{Swift}, Python~\cite{Python}, and the algebraic data-type in functional programming.
     4Enumeration types exist in many popular programming languages, both past and present, \eg Pascal~\cite{Pascal}, Ada~\cite{Ada}, \Csharp~\cite{Csharp}, \CC, Go~\cite{Go}, Java~\cite{Java}, Modula-3~\cite{Modula-3}, Rust~\cite{Rust}, Swift~\cite{Swift}, Python~\cite{Python}, and algebraic data-types in functional programming.
    55Among theses languages, there are a large set of overlapping features, but each language has its own unique extensions and restrictions.
    66
     
    1414                 PI = 3.14159;   Plus = '+';   Fred = 'Fred';
    1515\end{pascal}
    16 The enumerator type is inferred from the constant-expression type.
    17 There is no notion of an ordered set, modulo the \lstinline[language=pascal]{set of} type.
     16Here, there is no enumeration because there is no specific type (pseudo enumeration).
     17Hence, there is no notion of a (possibly ordered) set, modulo the \lstinline[language=pascal]{set of} type.
     18The type of each constant name (enumerator) is inferred from the constant-expression type.
    1819
    1920Free Pascal~\cite[\S~3.1.1]{FreePascal} is a modern, object-oriented version of classic Pascal, with a C-style enumeration type.
     
    3839An Ada enumeration type is an ordered list of constants, called \Newterm{literals} (enumerators).
    3940\begin{ada}
    40 type RGB is ( @Red@, @Green@, Blue ); -- 3 literals (enumerators)
    41 \end{ada}
    42 No other enumerators are assignable to objects of this type.
     41type RGB is ( Red, Green, Blue ); -- 3 literals (enumerators)
     42\end{ada}
     43Object initialization and assignment are restricted to the enumerators of this type.
    4344Enumerators without an explicitly designated constant value are auto-initialized: from left to right, starting at zero or the next explicitly initialized constant, incrementing by 1.
    4445To explicitly set enumerator values, \emph{all} enumerators must be set in \emph{ascending} order, \ie there is no auto-initialization.
     
    5152(0, 10, RED)  (1, 20, GREEN)  (2, 30, BLUE)
    5253\end{ada}
     54Note, Ada is case-\emph{insensitive} so names may appear in multiple forms and still be the same, \eg @Red@ and @RED@ (a questionable design decision).
    5355
    5456Like C, Ada enumerators are unscoped, \ie enumerators declared inside of an enum are visible (projected) into the enclosing scope.
    55 Note, Ada is case-\emph{insensitive} so names may appear in multiple forms and still be the same name (a questionable design decision).
    56 The enumeration operators are the ordering operators, @=@, @<@, @<=@, @=@, @/=@, @>=@, @>@, where the ordering relation is given implicitly by the sequence of enumerators, which is always ascending.
     57The enumeration operators are the ordering operators, @=@, @<@, @<=@, @=@, @/=@, @>=@, @>@, where the ordering relationship is given implicitly by the sequence of enumerators, which is always ascending.
    5758
    5859Ada enumerators are overloadable.
     
    119120\begin{ada}
    120121type Operator is ( '+', '-', '*', '/' );
    121 Op : Operator;
    122122\end{ada}
    123123which is syntactic sugar for the label and not character literals from the predefined type @Character@.
    124 The purpose is readability using character literals rather than names.
    125 \begin{ada}
    126 Op := '+';
    127 case Op is                    -- all enumerators must appear
    128         when '+' => ... ;
    129         when '-' => ... ;
    130         when '*' => ... ;
    131         when '/' => ... ;
    132 end case;
    133 \end{ada}
    134 Arrays of character enumerators can be treated as strings.
     124The purpose is strictly readability using character literals rather than names.
     125\begin{ada}
     126Op : Operator := '+';
     127if Op = '+' or else Op = '-' then ... ;
     128elsif Op = '*' or else Op = '/' then ... ; end if;
     129\end{ada}
     130Interestingly, arrays of character enumerators can be treated as strings.
    135131\begin{ada}
    136132Ops : array( 0..3 ) of Operator;
    137133Ops := @"+-*/"@;            -- string assignment to array elements
    138134Ops := @"+-" & "*/"@;   -- string concatenation and assignment
    139 for Op of Ops loop
    140         Put_Line( Operator'Image( Op ) );
    141 end loop;
    142135\end{ada}
    143136Ada's @Character@ type is defined as a character enumeration across all Latin-1 characters.
    144137
    145 Ada's boolean type is defined as a special enumeration, which can be used in conditions.
     138Ada's boolean type is also a special enumeration, which can be used in conditions.
    146139\begin{ada}
    147140type Boolean is (False, True); -- False / True not keywords
     
    160153Hence, the ordering of the enumerators is crucial to provide the necessary ranges.
    161154
    162 An enumeration type can be used in the Ada \lstinline[language=ada]{case} (switch) and iterating constructs.
     155An enumeration type can be used in the Ada \lstinline[language=ada]{case} (all enumerators must appear or a default) or iterating constructs.
    163156\begin{cquote}
    164157\lstDeleteShortInline@
     
    263256enum class E { A, B, C };
    264257E e = @E::@A;                                                   $\C{// qualified enumerator}$
    265 e = B;                                                                  $\C{// B not in scope}$
     258e = B;                                                                  $\C{// error: B not in scope}$
    266259\end{c++}
    267260\CC{20} supports explicit unscoping with a \lstinline[language=c++]{using enum} declaration.
     
    278271enum class srgb @: signed char@ { Red = -1, Green = 0, Blue = 1 };
    279272\end{c++}
    280 There is no implicit conversion from the \lstinline[language=c++]{enum class} type and to its declared type.
     273There is no implicit conversion from the \lstinline[language=c++]{enum class} type to its declared type.
    281274\begin{c++}
    282275rgb crgb = rgb::Red;
    283 char ch = rgb::Red;   ch = crgb;                $\C{// disallowed}$
     276char ch = rgb::Red;   ch = crgb;                $\C{// error}$
    284277\end{c++}
    285 Finally, there is no mechanism to iterate through an enumeration nor use the enumeration type to declare an array dimension.
     278Finally, enumerations can be used in the @switch@ statement but there is no mechanism to iterate through an enumeration.
     279An enumeration type cannot declare an array dimension but can be used as a subscript.
     280There is no mechanism to subtype or inherit from enumerations.
    286281
    287282
     
    292287% https://www.tutorialsteacher.com/codeeditor?cid=cs-mk8Ojx
    293288
    294 \Csharp is a dynamically-typed programming-language with a scoped, integral enumeration-type similar to C/\CC enumeration.
     289\Csharp is a dynamically-typed programming-language with a scoped, integral enumeration-type similar to the C/\CC enumeration.
    295290\begin{csharp}
    296291enum Weekday : byte { Mon, Tue, Wed, Thu@ = 10@, Fri, Sat, Sun@,@ };
    297292\end{csharp}
    298 The default underlying type is @int@, with auto-incrementing, implicit/explicit initialization, terminator comma, and optional integral typing (default @int@)
     293The default underlying type is @int@, with auto-incrementing, implicit/explicit initialization, terminator comma, and optional integral typing (default @int@).
    299294A method cannot be defined in an enumeration type.
    300295As well, there is an explicit bidirectional conversion between an enumeration and its integral type, and an implicit conversion to the enumerator label in display contexts.
     
    306301\end{csharp}
    307302
    308 The @Enum.GetValues@ pseudo-method retrieves an array of the enumeration constants for looping over an enumeration type or variable.
     303The @Enum.GetValues@ pseudo-method retrieves an array of the enumeration constants for looping over an enumeration type or variable (expensive operation).
    309304\begin{csharp}
    310305foreach ( Weekday constant in @Enum.GetValues@( typeof(Weekday) ) ) {
     
    341336                Mon, Tue, Wed, Thu, Fri, Sat, Sun };
    342337
    343 
    344338        static bool isWeekday( Weekday wd ) {
    345                 return Weekday.Mon <= wd
    346                         && wd <= Weekday.Fri;
     339                return wd <= Weekday.Fri;
    347340        }
    348341        static bool isWeekend( Weekday wd ) {
    349                 return Weekday.Sat <= wd
    350                         && wd <= Weekday.Sun;
     342                return Weekday.Sat <= wd;
    351343        }
    352344
     
    363355\begin{csharp}
    364356public class Program {
    365         public @class@ WeekDay {
    366                 public enum Weekday {
    367                         Mon=-4, Tue=-3, Wed=-2, Thu=-1,
    368                         Fri=0, Sat=1, Sun=2 };
    369                 Weekday day;
     357        public @class@ WeekDay : Enumeration {
     358                public enum Day {
     359                                Mon, Tue, Wed, Thu, Fri, Sat, Sun };
     360                public enum Day2 : Day {
     361                                XXX, YYY };
     362                Day day;
    370363                public bool isWeekday() {
    371                         return day <= 0;
    372 
     364                        return day <= Day.Fri;
    373365                }
    374366                public bool isWeekend() {
    375                         return day > 0
    376 
     367                        return day > Day.Fri;
    377368                }
    378                 public WeekDay( Weekday d ) { day = d; }
     369                public WeekDay( Day d ) { day = d; }
    379370        }
    380371        public static void Main() {
    381372                WeekDay cday = new
    382                                 WeekDay( WeekDay.Weekday.Sat );
     373                                WeekDay( WeekDay.Day.Sat );
    383374                Console.WriteLine( cday.isWeekday() );
    384375                Console.WriteLine( cday.isWeekend() );
     
    396387\lstnewenvironment{Go}[1][]{\lstset{language=Go,escapechar=\$,moredelim=**[is][\color{red}]{@}{@},}\lstset{#1}}{}
    397388
    398 Golang provides a mechanism similar to classic Pascal \lstinline[language=pascal]{const}, binding a name to a constant literal/expression (pseudo enumeration).
     389Golang provides pseudo-enumeration similar to classic Pascal \lstinline[language=pascal]{const}, binding a name to a constant literal/expression.
    399390\begin{Go}
    400391const ( R = 0; G; B )                                   $\C{// implicit: 0 0 0}$
     
    448439
    449440for i := Mon; i <= Sun; i += 1 {
    450     fmt.Println( i )
     441        fmt.Println( i )
    451442}
    452443
     
    457448\lstMakeShortInline@
    458449\end{cquote}
    459 The loop prints the values from 0 to 13 because there is no actual enumeration.
     450However, the loop prints the values from 0 to 13 because there is no actual enumeration.
    460451
    461452
    462453\section{Java}
    463 \lstnewenvironment{Java}[1][]{\lstset{language=Java,escapechar=\$,moredelim=**[is][\color{red}]{!}{!},}\lstset{#1}}{}
     454\lstnewenvironment{Java}[1][]{\lstset{language=Java,morekeywords={enum,assert,strictfp},
     455        escapechar=\$,moredelim=**[is][\color{red}]{!}{!},}\lstset{#1}}{}
    464456
    465457Every enumeration in Java is an enumeration class.
     
    471463the scoped enumerators are an ordered list of @final@ methods of type integer, ordered left to right starting at 0, increasing by 1.
    472464The value of an enumeration instance is restricted to the enumeration's enumerators.
    473 There is an implicit integer variable in the enumeration used to store the value of an enumeration instance.
    474 The position (ordinal) and label are accessible, and the value is the same as the position.
     465There is an implicit @int@ variable in the enumeration used to store the value of an enumeration instance.
     466The position (ordinal) and label are accessible, where the value is the same as the position.
    475467\begin{Java}
    476 System.out.println( !day.ordinal()! + " " + !day! ); // 5 Sat
     468System.out.println( day.!ordinal()! + " " + day.!name()! ); // 5 Sat
     469\end{Java}
     470There is an inverse function @valueOf@ from string to enumerator.
     471\begin{Java}
     472day = Weekday.valueOf( "Wed" );
    477473\end{Java}
    478474There are no implicit conversions to/from an enumerator and its underlying type.
    479 
    480 To explicitly assign enumerator values, the enumeration must specify an explicit type in the enumeration class.
    481 \begin{Java}
    482 enum Weekday {
    483         Mon( -4 ), Tue( -3 ), Wed( -2 ), Thu( -1 ), Fri( 0 ), Sat( 1 ), Sun( 2 ); // must appear first
    484         private int day;                                        $\C{// underlying enumeration type}$
    485         private Weekday( int d ) { day = d; } $\C{// used to initialize enumerators and instances}$
    486 };
    487 Weekday day = Weekday.Sat;                              $\C{// implicit constructor call}$
    488 \end{Java}
    489 The position, value, and label are accessible.
    490 \begin{Java}
    491 System.out.println( !day.ordinal()! + " " + !day.day! + " " + !day! );  // 5 1 Sat
    492 \end{Java}
    493 The constructor is private so only initialization or assignment can be used to set an enumeration, which ensures only corresponding enumerator values are allowed.
    494 
    495475Like \Csharp, \VRef[Figure]{f:JavaFreeVersusClass} shows the same example for an enumeration with free routines for manipulation, and embedding the enumeration and operations into an enumeration class.
    496476
     
    502482\hline
    503483\begin{Java}
    504 public class test {
    505 
    506         enum Weekday {
    507                 Mon, Tue, Wed, Thu, Fri, Sat, Sun };
    508 
    509         static boolean isWeekday( Weekday wd ) {
    510                 return Weekday.Mon.ordinal() <= wd.ordinal()
    511                         && wd.ordinal() <= Weekday.Fri.ordinal();
    512         }
    513         static boolean isWeekend( Weekday wd ) {
    514                 return Weekday.Sat.ordinal() <= wd.ordinal()
    515                         && wd.ordinal() <= Weekday.Sun.ordinal();
    516         }
    517 
    518 
    519         public static void main( String[] args ) {
    520                 Weekday day = Weekday.Sat;
    521                 System.out.println( isWeekday( day ) );
    522                 System.out.println( isWeekend( day ) );
    523         }
     484enum Weekday !{!
     485        Mon, Tue, Wed, Thu, Fri, Sat, Sun !}!;
     486
     487static boolean isWeekday( Weekday wd ) {
     488        return wd.ordinal() <= Weekday.Fri.ordinal();
     489}
     490static boolean isWeekend( Weekday wd ) {
     491        return Weekday.Fri.ordinal() < wd.ordinal();
     492}
     493
     494public static void main( String[] args ) {
     495        Weekday day = Weekday.Sat;
     496        System.out.println( isWeekday( day ) );
     497        System.out.println( isWeekend( day ) );
    524498}
    525499\end{Java}
    526500&
    527501\begin{Java}
    528 public class test {
    529         public !enum! WeekDay {
    530                 Mon(-4), Tue(-3), Wed(-2), Thu(-1),
    531                         Fri(0), Sat(1), Sun(2);
    532                 private int day;
    533                 public boolean isWeekday() {
    534                         return day <= 0;
    535 
    536                 }
    537                 public boolean isWeekend() {
    538                         return day > 0;
    539 
    540                 }
    541                 private WeekDay( int d ) { day = d; }
     502enum Weekday !{!
     503        Mon, Tue, Wed, Thu, Fri, Sat, Sun;
     504
     505        public boolean isWeekday() {
     506                return ordinal() <= Weekday.Fri.ordinal();
    542507        }
    543         public static void main( String[] args ) {
    544                 WeekDay day = WeekDay.Sat;
    545                 System.out.println( day.isWeekday() );
    546                 System.out.println( day.isWeekend() );
     508        public boolean isWeekend() {
     509                return Weekday.Fri.ordinal() < ordinal();
    547510        }
     511!}!
     512public static void main( String[] args ) {
     513        WeekDay day = WeekDay.Sat;
     514        System.out.println( day.isWeekday() );
     515        System.out.println( day.isWeekend() );
    548516}
    549517\end{Java}
     
    553521\label{f:JavaFreeVersusClass}
    554522\end{figure}
     523
     524To explicitly assign enumerator values and/or use a non-@int@ enumeration type (any Java type may be used), the enumeration must specify an explicit type in the enumeration class and a constructor.
     525\begin{Java}
     526enum Weekday {
     527        Mon!(1)!, Tue!(2)!, Wed!(3)!, Thu!(4)!, Fri!(5)!, Sat!(6)!, Sun!(7)!; // must appear first
     528        private !long! day;                                     $\C{// underlying enumeration type}$
     529        private Weekday( !long! d ) { day = d; } $\C{// used to initialize enumerators}$
     530};
     531Weekday day = Weekday.Sat;
     532\end{Java}
     533If an enumerator initialization is a runtime expression, the expression is executed once at the point the enumeration is declaraed.
     534
     535The position, value, and label are accessible.
     536\begin{Java}
     537System.out.println( !day.ordinal()! + " " + !day.day! + " " + !day.name()! );  // 5 6 Sat
     538\end{Java}
     539The constructor is private so only initialization or assignment can be used to set an enumeration, which ensures only corresponding enumerator values are allowed.
    555540
    556541An enumeration can appear in a @switch@ statement, but no ranges.
     
    565550}
    566551\end{Java}
    567 Looping over an enumeration is done using method @values@, which returns the array of enumerator values.
     552Like \Csharp, looping over an enumeration is done using method @values@, which returns the array of enumerator values (expensive operation).
    568553\begin{Java}
    569554for ( Weekday iday : Weekday.values() ) {
    570         System.out.println( iday.ordinal() + " " + iday + " " );
    571 }
     555        System.out.print( iday.ordinal() + iday.day + " " +  iday.name() + ",  " );
     556}
     5570 1 Mon,  1 2 Tue,  2 3 Wed,  3 4 Thu,  4 5 Fri,  5 6 Sat,  6 7 Sun, 
    572558\end{Java}
    573559
     
    581567\section{Modula-3}
    582568
     569
     570
    583571\section{Rust}
     572\lstnewenvironment{rust}[1][]{\lstset{language=Rust,escapechar=\$,moredelim=**[is][\color{red}]{@}{@},}\lstset{#1}}{}
     573
     574Enumerations
     575\begin{rust}
     576        Syntax
     577        Enumeration :
     578           enum IDENTIFIER  GenericParams? WhereClause? { EnumItems? }
     579
     580        EnumItems :
     581           EnumItem ( , EnumItem )* ,?
     582
     583        EnumItem :
     584           OuterAttribute* Visibility?
     585           IDENTIFIER ( EnumItemTuple | EnumItemStruct )? EnumItemDiscriminant?
     586
     587        EnumItemTuple :
     588           ( TupleFields? )
     589
     590        EnumItemStruct :
     591           { StructFields? }
     592
     593        EnumItemDiscriminant :
     594           = Expression
     595\end{rust}
     596An enumeration, also referred to as an enum, is a simultaneous definition of a nominal enumerated type as well as a set of constructors, that can be used to create or pattern-match values of the corresponding enumerated type.
     597
     598Enumerations are declared with the keyword enum.
     599
     600An example of an enum item and its use:
     601\begin{rust}
     602enum Animal {
     603        Dog,
     604        Cat,
     605}
     606
     607let mut a: Animal = Animal::Dog;
     608a = Animal::Cat;
     609\end{rust}
     610Enum constructors can have either named or unnamed fields:
     611\begin{rust}
     612enum Animal {
     613        Dog(String, f64),
     614        Cat { name: String, weight: f64 },
     615}
     616
     617let mut a: Animal = Animal::Dog("Cocoa".to_string(), 37.2);
     618a = Animal::Cat { name: "Spotty".to_string(), weight: 2.7 };
     619\end{rust}
     620In this example, Cat is a struct-like enum variant, whereas Dog is simply called an enum variant.
     621
     622An enum where no constructors contain fields are called a field-less enum. For example, this is a fieldless enum:
     623\begin{rust}
     624enum Fieldless {
     625        Tuple(),
     626        Struct{},
     627        Unit,
     628}
     629\end{rust}
     630If a field-less enum only contains unit variants, the enum is called an unit-only enum. For example:
     631\begin{rust}
     632enum Enum {
     633        Foo = 3,
     634        Bar = 2,
     635        Baz = 1,
     636}
     637\end{rust}
     638
     639\subsection{Discriminants}
     640
     641Each enum instance has a discriminant: an integer logically associated to it that is used to determine which variant it holds.
     642
     643Under the default representation, the discriminant is interpreted as an isize value. However, the compiler is allowed to use a smaller type (or another means of distinguishing variants) in its actual memory layout.
     644
     645\subsection{Assigning discriminant values}
     646
     647\subsection{Explicit discriminants}
     648
     649In two circumstances, the discriminant of a variant may be explicitly set by following the variant name with = and a constant expression:
     650
     651        if the enumeration is "unit-only".
     652
     653        if a primitive representation is used. For example:
     654\begin{rust}
     655        #[repr(u8)]
     656        enum Enum {
     657                Unit = 3,
     658                Tuple(u16),
     659                Struct {
     660                        a: u8,
     661                        b: u16,
     662                } = 1,
     663        }
     664\end{rust}
     665
     666\subsection{Implicit discriminants}
     667
     668If a discriminant for a variant is not specified, then it is set to one higher than the discriminant of the previous variant in the declaration. If the discriminant of the first variant in the declaration is unspecified, then it is set to zero.
     669\begin{rust}
     670enum Foo {
     671        Bar,                    // 0
     672        Baz = 123,        // 123
     673        Quux,              // 124
     674}
     675
     676let baz_discriminant = Foo::Baz as u32;
     677assert_eq!(baz_discriminant, 123);
     678\end{rust}
     679
     680\subsection{Restrictions}
     681
     682It is an error when two variants share the same discriminant.
     683\begin{rust}
     684enum SharedDiscriminantError {
     685        SharedA = 1,
     686        SharedB = 1
     687}
     688
     689enum SharedDiscriminantError2 {
     690        Zero,      // 0
     691        One,            // 1
     692        OneToo = 1  // 1 (collision with previous!)
     693}
     694\end{rust}
     695It is also an error to have an unspecified discriminant where the previous discriminant is the maximum value for the size of the discriminant.
     696\begin{rust}
     697#[repr(u8)]
     698enum OverflowingDiscriminantError {
     699        Max = 255,
     700        MaxPlusOne // Would be 256, but that overflows the enum.
     701}
     702
     703#[repr(u8)]
     704enum OverflowingDiscriminantError2 {
     705        MaxMinusOne = 254, // 254
     706        Max,                       // 255
     707        MaxPlusOne               // Would be 256, but that overflows the enum.
     708}
     709\end{rust}
     710
     711\subsection{Accessing discriminant}
     712
     713\begin{rust}
     714Via mem::discriminant
     715\end{rust}
     716mem::discriminant returns an opaque reference to the discriminant of an enum value which can be compared. This cannot be used to get the value of the discriminant.
     717Casting
     718
     719If an enumeration is unit-only (with no tuple and struct variants), then its discriminant can be directly accessed with a numeric cast; e.g.:
     720\begin{rust}
     721enum Enum {
     722        Foo,
     723        Bar,
     724        Baz,
     725}
     726
     727assert_eq!(0, Enum::Foo as isize);
     728assert_eq!(1, Enum::Bar as isize);
     729assert_eq!(2, Enum::Baz as isize);
     730\end{rust}
     731Field-less enums can be casted if they do not have explicit discriminants, or where only unit variants are explicit.
     732\begin{rust}
     733enum Fieldless {
     734        Tuple(),
     735        Struct{},
     736        Unit,
     737}
     738
     739assert_eq!(0, Fieldless::Tuple() as isize);
     740assert_eq!(1, Fieldless::Struct{} as isize);
     741assert_eq!(2, Fieldless::Unit as isize);
     742\end{rust}
     743\begin{rust}
     744#[repr(u8)]
     745enum FieldlessWithDiscrimants {
     746        First = 10,
     747        Tuple(),
     748        Second = 20,
     749        Struct{},
     750        Unit,
     751}
     752
     753assert_eq!(10, FieldlessWithDiscrimants::First as u8);
     754assert_eq!(11, FieldlessWithDiscrimants::Tuple() as u8);
     755assert_eq!(20, FieldlessWithDiscrimants::Second as u8);
     756assert_eq!(21, FieldlessWithDiscrimants::Struct{} as u8);
     757assert_eq!(22, FieldlessWithDiscrimants::Unit as u8);
     758\end{rust}
     759
     760\subsection{Pointer casting}
     761
     762If the enumeration specifies a primitive representation, then the discriminant may be reliably accessed via unsafe pointer casting:
     763\begin{rust}
     764#[repr(u8)]
     765enum Enum {
     766        Unit,
     767        Tuple(bool),
     768        Struct{a: bool},
     769}
     770
     771impl Enum {
     772        fn discriminant(&self) -> u8 {
     773                unsafe { *(self as *const Self as *const u8) }
     774        }
     775}
     776
     777let unit_like = Enum::Unit;
     778let tuple_like = Enum::Tuple(true);
     779let struct_like = Enum::Struct{a: false};
     780
     781assert_eq!(0, unit_like.discriminant());
     782assert_eq!(1, tuple_like.discriminant());
     783assert_eq!(2, struct_like.discriminant());
     784\end{rust}
     785
     786\subsection{Zero-variant enums}
     787
     788Enums with zero variants are known as zero-variant enums. As they have no valid values, they cannot be instantiated.
     789\begin{rust}
     790enum ZeroVariants {}
     791\end{rust}
     792Zero-variant enums are equivalent to the never type, but they cannot be coerced into other types.
     793\begin{rust}
     794let x: ZeroVariants = panic!();
     795let y: u32 = x; // mismatched type error
     796\end{rust}
     797
     798\subsection{Variant visibility}
     799
     800Enum variants syntactically allow a Visibility annotation, but this is rejected when the enum is validated. This allows items to be parsed with a unified syntax across different contexts where they are used.
     801\begin{rust}
     802macro_rules! mac_variant {
     803        ($vis:vis $name:ident) => {
     804                enum $name {
     805                        $vis Unit,
     806
     807                        $vis Tuple(u8, u16),
     808
     809                        $vis Struct { f: u8 },
     810                }
     811        }
     812}
     813
     814// Empty `vis` is allowed.
     815mac_variant! { E }
     816
     817// This is allowed, since it is removed before being validated.
     818#[cfg(FALSE)]
     819enum E {
     820        pub U,
     821        pub(crate) T(u8),
     822        pub(super) T { f: String }
     823}
     824\end{rust}
    584825
    585826
     
    587828\lstnewenvironment{swift}[1][]{\lstset{language=Swift,escapechar=\$,moredelim=**[is][\color{red}]{@}{@},}\lstset{#1}}{}
    588829
    589 Model custom types that define a list of possible values.
     830% https://www.programiz.com/swift/online-compiler
     831
     832A Swift enumeration provides a heterogenous set of enumerators, like a tagged @union@, where the field name is the enumerator and its list of type parameters form its type.
     833\begin{swift}
     834enum Many {
     835        case Mon, Tue, Wed, Thu, Fri, Sat, Sun // basic enumerator
     836        case code( String ) // string enumerator
     837        case tuple( Int, Int, Int ) // tuple enumerator
     838};
     839var day = Many.Sat; // qualification to resolve type
     840print( day );
     841day = .Wed // no qualification after type resolved
     842print( day );
     843day = .code( "ABC" );
     844print( day );
     845day = .tuple( 1, 2, 3 );
     846print( day );
     847
     848Sat
     849Wed
     850code("ABC")
     851tuple(1, 2, 3)
     852\end{swift}
     853
    590854
    591855An enumeration defines a common type for a group of related values and enables you to work with those values in a type-safe way within your code.
     
    607871\paragraph{Enumeration Syntax}
    608872
    609 You introduce enumerations with the @enum@ keyword and place their entire definition within a pair of braces:
    610 \begin{swift}
    611 enum SomeEnumeration {
    612         // enumeration definition goes here
    613 }
    614 \end{swift}
    615 Here's an example for the four main points of a compass:
    616 \begin{swift}
    617 enum CompassPoint {
    618         case north
    619         case south
    620         case east
    621         case west
    622 }
    623 \end{swift}
    624 The values defined in an enumeration (such as @north@, @south@, @east@, and @west@) are its enumeration cases.
    625 You use the @case@ keyword to introduce new enumeration cases.
    626873
    627874Note:
Note: See TracChangeset for help on using the changeset viewer.