Enumerations

Making it easier to work with shaders


Enumerations

Syntax

Enumeration declaration:

enum-decl =
    [modifier-list]
    'enum' ['class'] [enum-identifier]
        [':' tag-type]
    '{' [enum-case-decl (',' enum-case-decl)*] '}'

Enumeration case declaration:

enum-case-decl =
    enum-const-identifier ['=' expr]

📝 Remark: The parser currently accepts generic parameters for an enumeration declaration, but the parameters are not usable. See GitHub issue #10078 for details.

Parameters

  • modifier-list is an optional list of modifiers:
    • [Flags] specifies that the enumeration defines flags for a bit field.
    • See also Remark 1 in the Description section below.
  • 'class' is a compatibility feature that allows the same enumeration declarations to be shared between C/C++ and Slang.
    • See Remark 2 in the Description section below.
  • enum-identifier is the identifier for the declared enumeration type.
    • While the syntax currently allows declaring anonymous enumerations, it is recommended that all enumerations be named. See Remark 1 in the Description section below.
  • tag-type specifies the underlying type of the enumeration. If omitted, the default is int.
  • enum-const-identifier is an identifier for an enumerator, i.e., an enumerated constant.
  • expr is a link-time constant, specifying the numeric value for the enumerator. If omitted, a value is generated by the compiler. See the description below for details.

Description

An enumeration is a scalar type that holds a value and may contain named constants, called enumerators. An enumeration has an underlying type that serves as both its storage type and the type of its enumerators.

The underlying type of an enumeration must be a Boolean or an integer type. If no underlying type is specified, the default is int.

Enumerations are scoped. The named constants of a scoped enumeration are accessed within the enumeration namespace using the EnumType.ENUM_CONST form.

If an enumerator is not assigned a value, one is provided. By default, the value is the previous enumerator’s value incremented by 1. If the value for the first enumerator is unspecified, the default is 0. However, if [Flags] is specified for the enumeration, the provided value is the previous enumerator’s value left-shifted by 1, and the default value for the first enumerator is 1.

Multiple enumerators may share the same numeric value.

An enumeration may be extended using the extension syntax. An extension can be used to add member functions, constructors, interface conformances, and similar features to the enumeration.

📝 Remark 1: Slang currently supports unscoped enumerations, in which the named constants are defined in the same namespace as the enumeration type. The enumerators of an unscoped enumeration can also be accessed using the scoped form.

There are three ways to declare an unscoped enumeration:

  • The slangc command-line option -unscoped-enum makes all named enumerations unscoped, except those that are declared using 'enum class'.
  • The [UnscopedEnum] attribute in the modifier list explicitly declares an unscoped enumeration.
  • An anonymous enumeration is unscoped.

However, please note that unscoped enumerations are subject to deprecation and removal, and should therefore be avoided in new Slang programs. See GitHub issue #11175 for details.

📝 Remark 2: Currently, 'enum class' is always a scoped enumeration whereas 'enum' can be either scoped or unscoped. If unscoped enumerations are removed from Slang, there will be no difference between 'enum' and 'enum class'. New code should prefer 'enum'.

Examples

enum TestEnum
{
    Zero,                    // value 0
    One,                     // value 1
    AnotherOne = One,        // value 1
    Three = One + One + One, // value 3
    Max = 2147483647,
}

RWStructuredBuffer<TestEnum> output1;

[numthreads(1,1,1)]
void main(uint3 threadId : SV_DispatchThreadID)
{
    output1[0] = TestEnum.Zero;       // 0
    output1[1] = TestEnum.One;        // 1
    output1[2] = TestEnum.AnotherOne; // 1
    output1[3] = TestEnum.Three;      // 3
    output1[4] = TestEnum.Max;        // 2147483647
}