const assert = @import("std").debug.assert; const mem = @import("std").mem; test "enum type" { const foo1 = Foo{ .One = 13}; const foo2 = Foo{. Two = Point { .x = 1234, .y = 5678, }}; const bar = Bar.B; assert(bar == Bar.B); assert(@memberCount(Foo) == 3); assert(@memberCount(Bar) == 4); assert(@sizeOf(Foo) == @sizeOf(FooNoVoid)); assert(@sizeOf(Bar) == 1); } test "enum as return value" { switch (returnAnInt(13)) { Foo.One => |value| assert(value == 13), else => unreachable, } } const Point = struct { x: u64, y: u64, }; const Foo = union(enum) { One: i32, Two: Point, Three: void, }; const FooNoVoid = union(enum) { One: i32, Two: Point, }; const Bar = enum { A, B, C, D, }; fn returnAnInt(x: i32) -> Foo { Foo { .One = x } } test "constant enum with payload" { var empty = AnEnumWithPayload {.Empty = {}}; var full = AnEnumWithPayload {.Full = 13}; shouldBeEmpty(empty); shouldBeNotEmpty(full); } fn shouldBeEmpty(x: &const AnEnumWithPayload) { switch (*x) { AnEnumWithPayload.Empty => {}, else => unreachable, } } fn shouldBeNotEmpty(x: &const AnEnumWithPayload) { switch (*x) { AnEnumWithPayload.Empty => unreachable, else => {}, } } const AnEnumWithPayload = union(enum) { Empty: void, Full: i32, }; const Number = enum { Zero, One, Two, Three, Four, }; test "enum to int" { shouldEqual(Number.Zero, 0); shouldEqual(Number.One, 1); shouldEqual(Number.Two, 2); shouldEqual(Number.Three, 3); shouldEqual(Number.Four, 4); } fn shouldEqual(n: Number, expected: u3) { assert(u3(n) == expected); } test "int to enum" { testIntToEnumEval(3); } fn testIntToEnumEval(x: i32) { assert(IntToEnumNumber(u3(x)) == IntToEnumNumber.Three); } const IntToEnumNumber = enum { Zero, One, Two, Three, Four, }; test "@tagName" { assert(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three")); comptime assert(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three")); } fn testEnumTagNameBare(n: BareNumber) -> []const u8 { return @tagName(n); } const BareNumber = enum { One, Two, Three, }; test "enum alignment" { comptime { assert(@alignOf(AlignTestEnum) >= @alignOf([9]u8)); assert(@alignOf(AlignTestEnum) >= @alignOf(u64)); } } const AlignTestEnum = union(enum) { A: [9]u8, B: u64, }; const ValueCount1 = enum { I0 }; const ValueCount2 = enum { I0, I1 }; const ValueCount256 = enum { I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13, I14, I15, I16, I17, I18, I19, I20, I21, I22, I23, I24, I25, I26, I27, I28, I29, I30, I31, I32, I33, I34, I35, I36, I37, I38, I39, I40, I41, I42, I43, I44, I45, I46, I47, I48, I49, I50, I51, I52, I53, I54, I55, I56, I57, I58, I59, I60, I61, I62, I63, I64, I65, I66, I67, I68, I69, I70, I71, I72, I73, I74, I75, I76, I77, I78, I79, I80, I81, I82, I83, I84, I85, I86, I87, I88, I89, I90, I91, I92, I93, I94, I95, I96, I97, I98, I99, I100, I101, I102, I103, I104, I105, I106, I107, I108, I109, I110, I111, I112, I113, I114, I115, I116, I117, I118, I119, I120, I121, I122, I123, I124, I125, I126, I127, I128, I129, I130, I131, I132, I133, I134, I135, I136, I137, I138, I139, I140, I141, I142, I143, I144, I145, I146, I147, I148, I149, I150, I151, I152, I153, I154, I155, I156, I157, I158, I159, I160, I161, I162, I163, I164, I165, I166, I167, I168, I169, I170, I171, I172, I173, I174, I175, I176, I177, I178, I179, I180, I181, I182, I183, I184, I185, I186, I187, I188, I189, I190, I191, I192, I193, I194, I195, I196, I197, I198, I199, I200, I201, I202, I203, I204, I205, I206, I207, I208, I209, I210, I211, I212, I213, I214, I215, I216, I217, I218, I219, I220, I221, I222, I223, I224, I225, I226, I227, I228, I229, I230, I231, I232, I233, I234, I235, I236, I237, I238, I239, I240, I241, I242, I243, I244, I245, I246, I247, I248, I249, I250, I251, I252, I253, I254, I255 }; const ValueCount257 = enum { I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13, I14, I15, I16, I17, I18, I19, I20, I21, I22, I23, I24, I25, I26, I27, I28, I29, I30, I31, I32, I33, I34, I35, I36, I37, I38, I39, I40, I41, I42, I43, I44, I45, I46, I47, I48, I49, I50, I51, I52, I53, I54, I55, I56, I57, I58, I59, I60, I61, I62, I63, I64, I65, I66, I67, I68, I69, I70, I71, I72, I73, I74, I75, I76, I77, I78, I79, I80, I81, I82, I83, I84, I85, I86, I87, I88, I89, I90, I91, I92, I93, I94, I95, I96, I97, I98, I99, I100, I101, I102, I103, I104, I105, I106, I107, I108, I109, I110, I111, I112, I113, I114, I115, I116, I117, I118, I119, I120, I121, I122, I123, I124, I125, I126, I127, I128, I129, I130, I131, I132, I133, I134, I135, I136, I137, I138, I139, I140, I141, I142, I143, I144, I145, I146, I147, I148, I149, I150, I151, I152, I153, I154, I155, I156, I157, I158, I159, I160, I161, I162, I163, I164, I165, I166, I167, I168, I169, I170, I171, I172, I173, I174, I175, I176, I177, I178, I179, I180, I181, I182, I183, I184, I185, I186, I187, I188, I189, I190, I191, I192, I193, I194, I195, I196, I197, I198, I199, I200, I201, I202, I203, I204, I205, I206, I207, I208, I209, I210, I211, I212, I213, I214, I215, I216, I217, I218, I219, I220, I221, I222, I223, I224, I225, I226, I227, I228, I229, I230, I231, I232, I233, I234, I235, I236, I237, I238, I239, I240, I241, I242, I243, I244, I245, I246, I247, I248, I249, I250, I251, I252, I253, I254, I255, I256 }; test "enum sizes" { comptime { assert(@sizeOf(ValueCount1) == 0); assert(@sizeOf(ValueCount2) == 1); assert(@sizeOf(ValueCount256) == 1); assert(@sizeOf(ValueCount257) == 2); } } const Small2 = enum (u2) { One, Two, }; const Small = enum (u2) { One, Two, Three, Four, }; test "set enum tag type" { { var x = Small.One; x = Small.Two; comptime assert(@EnumTagType(Small) == u2); } { var x = Small2.One; x = Small2.Two; comptime assert(@EnumTagType(Small2) == u2); } } const A = enum (u3) { One, Two, Three, Four, One2, Two2, Three2, Four2, }; const B = enum (u3) { One3, Two3, Three3, Four3, One23, Two23, Three23, Four23, }; const C = enum (u2) { One4, Two4, Three4, Four4, }; const BitFieldOfEnums = packed struct { a: A, b: B, c: C, }; const bit_field_1 = BitFieldOfEnums { .a = A.Two, .b = B.Three3, .c = C.Four4, }; test "bit field access with enum fields" { var data = bit_field_1; assert(getA(&data) == A.Two); assert(getB(&data) == B.Three3); assert(getC(&data) == C.Four4); comptime assert(@sizeOf(BitFieldOfEnums) == 1); data.b = B.Four3; assert(data.b == B.Four3); data.a = A.Three; assert(data.a == A.Three); assert(data.b == B.Four3); } fn getA(data: &const BitFieldOfEnums) -> A { return data.a; } fn getB(data: &const BitFieldOfEnums) -> B { return data.b; } fn getC(data: &const BitFieldOfEnums) -> C { return data.c; } test "casting enum to its tag type" { testCastEnumToTagType(Small2.Two); comptime testCastEnumToTagType(Small2.Two); } fn testCastEnumToTagType(value: Small2) { assert(u2(value) == 1); } const MultipleChoice = enum(u32) { A = 20, B = 40, C = 60, D = 1000, }; test "enum with specified tag values" { testEnumWithSpecifiedTagValues(MultipleChoice.C); comptime testEnumWithSpecifiedTagValues(MultipleChoice.C); } fn testEnumWithSpecifiedTagValues(x: MultipleChoice) { assert(u32(x) == 60); assert(1234 == switch (x) { MultipleChoice.A => 1, MultipleChoice.B => 2, MultipleChoice.C => u32(1234), MultipleChoice.D => 4, }); } const MultipleChoice2 = enum(u32) { Unspecified1, A = 20, Unspecified2, B = 40, Unspecified3, C = 60, Unspecified4, D = 1000, Unspecified5, }; test "enum with specified and unspecified tag values" { testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2.D); comptime testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2.D); } fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: MultipleChoice2) { assert(u32(x) == 1000); assert(1234 == switch (x) { MultipleChoice2.A => 1, MultipleChoice2.B => 2, MultipleChoice2.C => 3, MultipleChoice2.D => u32(1234), MultipleChoice2.Unspecified1 => 5, MultipleChoice2.Unspecified2 => 6, MultipleChoice2.Unspecified3 => 7, MultipleChoice2.Unspecified4 => 8, MultipleChoice2.Unspecified5 => 9, }); }