Re: basic questions about enums and enum types

new topic     » goto parent     » topic index » view thread      » older message » newer message

being lazy here... I will just paste what Pete Lomax has said for Phix

There are a few small differences between oE and Phix on this (will have to work up a comparison sometime.)

_tom


Enum

An enum declaration can be used to define automatically-incrementing constants. The default behaviour is for the first item to be 1 and each subsequent item incremented by 1. An explict value may be specified for any item. Enums may currrently only take integer values (see below). Such values must always be numeric literals, as opposed to expressions or other variables or constants. Subsequent values default to the previous value plus one, unless they too are assigned a default value.

enum ONE=1, TWO, THREE, ABC=10, DEF, XYZ 
-- ONE is 1, TWO is 2, THREE is 3 
-- ABC is 10, DEF is 11, XYZ is 12 

Note that C enums start at 0 by default, and you should remember to specify "=0" on the first element when (manually) translating C to Phix, unless of course the enum is just being used to guarantee uniqueness and as such the actual values do not really matter.

It is not a bad idea to always explicitly specify the starting value of an enum, even if it is 1, to avoid confusing anyone more accustomed to the way enums behave in some other programming language.

As with other declarations, enums can be terminated with a $ for ease of editing enum lists that change frequently during development.

enum 
    YES, 
    NO, 
--  MAYBE, 
--  EITHER, 
--  SOMETIMES, 
    OFTEN, 
--  RARELY, 
    $ 
<eucode> 
 
 

You can also use $ to replicate the last value, eg

( =$ syntax is Phix only )

enum ONE,TWO,THREE,ALL=$ 
?{ONE,TWO,THREE,ALL}            -- {1,2,3,3} 
enum UN,UNO=$,DUO,TRE,TRES=$ 
?{UN,UNO,DUO,TRE,TRES}          -- {1,1,2,3,3} 

Obviously attempts to use $ on the very first enum trigger a compilation error ("no prior value").

Sequences use integer indexes, but with enum you may write code like this:

enum X, Y 
sequence point = { 0,0 } 
point[X] = 3 
point[Y] = 4 

enum type

There is also a special form of enum, an enum type. This is a simple way to write a user-defined type based on the set of values in a specific enum group.

The type created this way can be used anywhere a normal user-defined type can be used.

enum type RGBA RED, GREEN, BLUE, ALPHA end type 
-- Only allow values of RED, GREEN, BLUE, or ALPHA as parameters 
function xyz(RGBA x, RGBA y) 
    return 
end function 

The above enum statement is in fact (apart from the parameter being named "i") equivalent to:

enum RED, GREEN, BLUE, ALPHA  
type RGBA(integer i) return find(i,{RED, GREEN, BLUE, ALPHA}) end type 

You may have spotted that there is one significant difference concerning enum types. Normal type functions return either 1 or 0, whereas enum type functions return a positive integer index when the argument is a member, or 0 if not.

The value returned is the ordinal number of the member in the enum definition, regardless of what the member value is. Should two enums share the same value, they will share the same ordinal number. The ordinal numbers of enums surrounding these continue to increment as if every enum had a unique ordinal number, causing some numbers to be skipped. Lastly, although only applicable for enum type routines that are likely to be invoked more than 106 times, it would be remiss of me not to mention that the use of find in enum types may be slower than say i>=RED and i<=ALPHA, especially for enum types with several dozen or a few hundred or maybe even thousands of elements, however it is no big deal to replace such with a faster explicit type much as above, should that be a significant concern.

enum type color RED=4, GREEN=7, BLACK=1, BLUE=3 , PINK=10 end type 
? color(RED)   -- 1 
? color(GREEN) -- 2 
? color(BLACK) -- 3 
? color(BLUE)  -- 4 
? color(PINK)  -- 5 
constant color_names = {"rouge", "vert", "noir", "bleu", "rose"} 
puts(1, color_names[color(BLUE)]) -- bleu 

However if RED and BLACK were (for some unknown reason) given the same value:

enum type color RED, GREEN=7, BLACK=1, BLUE=3 , PINK=10 end type 
? color(RED)   -- 1 
? color(GREEN) -- 2 
? color(BLACK) -- 1 
? color(BLUE)  -- 4 
? color(PINK)  -- 5 

Note that none of the enums have an ordinal number with a value of 3. This is simply skipped. Unless an enum member is being set to a specific value, it defaults to 1 more than the previous member.

This default increment can be overridden. The syntax is:

enum [type name] by DELTA member1, member2, ... ,memberN 

where 'DELTA' is a literal number with an optional +, -, or * operator preceding it. Also, for the same reasons that floating point for loops are prohibited, phix only supports integer enums, and hence only integer deltas, and is unlikely to ever support "by /N".

enum by 2 A,B,C=6,D      -- values are 1,3,6,8 
enum by * 2 A,B,C,D,E    -- values are 1,2,4,8,16 

Should both be present, a "by amount" clause must follow rather than precede "type name".

new topic     » goto parent     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu