Menu

Enums

Will Pittenger

Enums in ASIL come in two forms: primitive-based and struct-based.

Primitive-based Enums

These enums are the simplest type of enum supported by ASIL. The syntax is similar to that in C++. Generally, primitve-based enums are more efficient and require less coding than those based on structures.

Letting the compiler pick values

Below is a sample of code declaring an enum that lets the compiler the numeric values behind each value in the enum type. You would reference the values in this manner: MyEnumType.left. Enums of this type can't be compared to any other type.

enum MyEnumType
  left
  both
  right

Note, if you need to be able to combine enum values, use this option and apply the CombinableEnumAttribute attribute. For more on attributes, see that section, [Attributes].

Specifying the base type

The above sample uses int as the base type. This means the number of possible values varies with the size of a word. If you want to change that, use the syntax below. Any integer type, signed or unsigned, will work. Enums of this type also can't be compared to any other type unless you manually assign values to entries as shown in the next section. In that case, comparisons are subject to the usual number conversion rules. Even though you're specifying one type, the real base type is "System.Enums.PrimitiveBased<TypeName>" where "TypeName" is the type given. If you leave extends clause out, you're deriving from "System.Enums.PrimitiveBased<int>". The type listed can be any primitive type declared by ASIL or a struct with only one field that isn't abstract. That field must be a primitive.

enum AnotherEnumType
    extends int64
  left
  right
  top
  bottom

Manually controlling the hidden integer values

Some enum types need to match the values used in external code. Suppose you have a C++ enum type to match. Enums of this type can be compared to number types using the normal number comparison rules. Use this syntax:

enum ExternalEnumType
  outside = 3 ' Any entries before the first entry with an explicit value gets a value chosen by the compiler that doesn't conflict with the values of any other entries.  Such values can't be compared and have no value for increment, decrement, or comparison operators (except the equality and inequality operators).
  inside = 4
  somethingElse ' If you don't specify a value for an item after the first item, the value for the previous item, plus 1, will be used

Using Increment/Decrement operators with primitive-based enum types

You can't use ++ or -- with primitive-based enum types unless the first value manually specifies a value. If you let the compiler pick the values, the values are considered to be unordered. This means you also can't do any comparisons other than equality and inequality. While primitive-based enum types that have manually assigned values can be used with ++ and --, the code below would throw a NoNumbericValueInEnumInstanceError. (This type is derived from Error and doesn't need to be caught or declared.)

enum BadType
  a ' No defined value!
  b = 3 ' Only entries after b have a value that can be referenced as b is the first entry with an explicit value

var BadType badEnum = BadType.a

badEnum ++ ' <<< Throws an exception as BadType.a has no defined value relative to the other values in BadType

BadEnum = BadType.bb
BadEnum ++ ' This won't change the value stored as there's only one value with a explicit value.

Allowing null values

If you need to allow a null value, explicitly list the null keyword as an entry with no explicit value. The ? type modifier is invalid for enum types.

Struct-based enums

Enums in java are more complex. You have more flexibility, but matching a C++ enum type is tough at best. ASIL lets you do either. Note the specialized syntax. Please note enum values of this type have no internal value until you provide one!!! You're also expected to provide any operators required except the equality and inequality operators. (Those are generated for you, but can be provided manually anyway when needed.) Enum constructors are implicitly private. Enum types of this type derive from "System.Enums.StructBased". Non-enum types can derive from "System.Enums.StructBased" as long as they're declared as "abstract struct" and not as an enum**.

enum structure MyStructEnum
  values
    left "left"
    top "top"
    right "right"
    bottom "bottom"

  public var readonly String strValue

  constructor var const String strValue
    self.strValue = strValue

Using custom base types for your enum

Non-enum types can derive from "System.Enums.StructBased" as long as they're declared as "abstract structure" and not as an enum. Now you can add a extends clause to your enum type. The first type in that extends clause must be derived an abstract structure derived from "System.Enums.StructBased". Other types listed can be any needed structure.

abstract structure MyEnumBaseType
    extends System.Enums.StructBased
  ' Add some extra members, methods, and properties.

enum structure MyEnumType
    extends MyEnumBaseType
  values
    left "left"
    top "top"
    right "right"
    bottom "bottom"

  public var readonly String strValue

  constructor var const String strValue
    self.strValue = strValue

Using Increment/Decrement operators with struct-based enum types

Struct-based enum types can't be used with ++ or -- unless you implement the operators in the type. Ditto for all comparison operators other than equality and inequality. See [Custom operators] for information on how to do that.

Allowing null values

Once again, if you need to allow a null value, explicitly list the null keyword as an entry with no parameters (you aren't calling a constructor). The ? type modifier is invalid for enum types.

Behind the scenes

Even though the same of this type of enum is "structure-based enums", they are a reference type. Your enum type will never have more instances than listed in by the values keyword.


Related

Wiki: Attributes
Wiki: Custom operators
Wiki: Home
Wiki: Keywords
Wiki: The basics (pun intended)
Wiki: When is it a procedure, command, function, property, property accessor, method, complex statement, or type cast?
Wiki: keywords-abstract
Wiki: keywords-enum
Wiki: keywords-extends
Wiki: keywords-null
Wiki: keywords-structure
Wiki: keywords-values
Wiki: operators-dec
Wiki: operators-inc