Enums - D Programming Language (original) (raw)

Contents

  1. Named Enums
    1. Enum Member Values
    2. Enum Properties
    3. Enum Copying and Assignment
  2. Anonymous Enums
  3. Single Member Anonymous Enum
  4. Manifest Constants

EnumDeclaration: enum Identifier EnumBody enum Identifier : EnumBaseType EnumBody AnonymousEnumDeclaration

EnumBaseType: Type

EnumBody: { EnumMembers } ;

EnumMembers: EnumMember EnumMember , EnumMember , EnumMembers

EnumMember: EnumMemberAttributesopt Identifier EnumMemberAttributesopt Identifier = AssignExpression

EnumMemberAttributes: EnumMemberAttribute EnumMemberAttribute EnumMemberAttributes

EnumMemberAttribute: DeprecatedAttribute UserDefinedAttribute @ disable

AnonymousEnumDeclaration: enum : EnumBaseType { EnumMembers } enum { AnonymousEnumMembers }

AnonymousEnumMembers: AnonymousEnumMember AnonymousEnumMember , AnonymousEnumMember , AnonymousEnumMembers

AnonymousEnumMember: EnumMember EnumMemberAttributesopt Type Identifier = AssignExpression

Enum declarations are used to define a group of constants.

Named Enums

Named enums are used to declare related constants and group them by giving them a unique type. The EnumMembers are declared in the scope of the named enum. The named enum declares a new type, and all the EnumMembers have that type.

This defines a new type X which has valuesX.A = 0, X.B = 1, X.C = 2:

enum X { A, B, C }

A variable can be of named enum type. Its default initializer is the first member defined for the enum type.

enum X { A = 3, B, C }

X x; assert(x == X.A); x |= X.B; assert(x & X.A);

The result type of a binary operation on a named enum is definedhere.

If the EnumBaseType is not explicitly set, and the first_EnumMember_ has an AssignExpression, it is set to the type of that_AssignExpression_. Otherwise, it defaults to type int.

enum Foo { E }

Foo f; int i; i = f; f = i; f = cast(Foo)i; f = 0; f = Foo.E;

A named enum member cannot declare its own Type.

See also: final switch on a named enum.

Enum Member Values

The value of an EnumMember is given by its AssignExpression if present. If there is no AssignExpression and it is the first EnumMember, its value is converted to EnumBaseType from 0. If there is no AssignExpression and it is not the first EnumMember, it is given the value of the previous EnumMember + 1:

enum E : char { a, b = char.max, c }

static assert(E.a == 0);

All _EnumMember_s are in scope for the _AssignExpression_s.

enum A = 3; enum B { A = A } enum C { A = B, B = D, C = 3, D } enum E : C { E1 = C.D, E2 }

An empty enum body signifies an opaque enum - the enum members are unknown.

enum X; writeln(X.init);

Enum Properties

Enum properties only exist for named enums.

Named Enum Properties

.init First enum member value
.min Smallest enum member value
.max Largest enum member value
.sizeof Size of storage for an enumerated value

For example:

enum X { A = 3, B = 1, C = 4, D, E = 2 } X.init X.min X.max X.sizeof

The EnumBaseType of named enums must support comparison in order to compute the .max and .min properties.

Enum Copying and Assignment

A named enum type never has acopy constructor,postblit, oridentity assignment overload, even if one is defined by its EnumBaseType.

When copying a named enum value whose base type is a struct with a copy constructor, the copy constructor is not called:

struct S { this(ref S rhs) { assert(0); } }

enum E : S { A = S.init }

void main() { E e1; E e2 = e1; }

When copying a named enum value whose base type is a struct with a postblit, the postblit is not called:

struct S { this(this) { assert(0); } }

enum E : S { A = S.init }

void main() { E e1; E e2 = e1; }

When assigning a named enum value to another object of the same type, if the base type of those values is a struct with an identity assignment overload, the identity assignment overload is not called:

struct S { void opAssign(S rhs) { assert(0); } }

enum E : S { A = S.init }

void main() { E e1, e2; e2 = e1; }

Anonymous Enums

If the enum Identifier is not present, then the enum is an anonymous enum, and the EnumMembers are declared in the scope the EnumDeclaration appears in. No new type is created.

The EnumMembers can have different types. Those types are given by the first of:

  1. The Type, if present. Types are not permitted when anEnumBaseType is present.
  2. The EnumBaseType, if present.
  3. The type of the AssignExpression, if present.
  4. The type of the previous EnumMember, if present.
  5. int

enum { A, B, C }

Defines the constants A = 0, B = 1, C = 2, all of type int.

Enums must have at least one member.

The value of an EnumMember is given by its AssignExpression if present. If there is no AssignExpression and it is the first EnumMember, its value is the .init property of the EnumMember's type. If there is no AssignExpression and it is not the first EnumMember, it is given the value of the previous EnumMember + 1:

All _EnumMember_s are in scope for the _AssignExpression_s.

enum { A, B = 5 + 7, C, D = 8 + C, E }

Sets A = 0, B = 12, C = 13, D = 21, and E = 22, all of type int.

enum : long { A = 3, B }

Sets A = 3 and B = 4, both of type long.

enum : string { A = "hello", B = "betty", C }

enum { A = 1.2f, B, int C = 3, D }

Single Member Anonymous Enum

If there is only one member of an anonymous enum, the { } can be omitted. Gramatically speaking, this is an AutoDeclaration.

enum i = 4; enum long l = 3;

Manifest Constants

Enum members are manifest constants, which exist only at compile-time.

Manifest constants are not lvalues, meaning their address cannot be taken. They exist only in the memory of the compiler.

enum size = __traits(classInstanceSize, Foo);

The initializer for a manifest constant is evaluated using compile-time function evaluation.

template Foo(T) { const size_t size = T.sizeof;
}

template Bar(T) { enum size_t size = T.sizeof;

    auto p = &Foo!T.size;

}

Copyright © 1999-2025 by the D Language Foundation | Page generated byDdoc on Fri May 2 11:41:56 2025