2017-01-05 00:57:48 -08:00
|
|
|
const assert = @import("std").debug.assert;
|
2017-04-08 14:45:22 -07:00
|
|
|
const mem = @import("std").mem;
|
2017-01-05 00:57:48 -08:00
|
|
|
|
2017-05-23 18:38:31 -07:00
|
|
|
test "enum type" {
|
2017-12-03 17:43:56 -08:00
|
|
|
const foo1 = Foo{ .One = 13};
|
|
|
|
const foo2 = Foo{. Two = Point { .x = 1234, .y = 5678, }};
|
2016-12-19 22:50:32 -08:00
|
|
|
const bar = Bar.B;
|
|
|
|
|
|
|
|
assert(bar == Bar.B);
|
|
|
|
assert(@memberCount(Foo) == 3);
|
|
|
|
assert(@memberCount(Bar) == 4);
|
2017-09-30 20:42:44 -07:00
|
|
|
assert(@sizeOf(Foo) == @sizeOf(FooNoVoid));
|
2016-12-19 22:50:32 -08:00
|
|
|
assert(@sizeOf(Bar) == 1);
|
|
|
|
}
|
2016-12-21 18:49:05 -08:00
|
|
|
|
2017-05-23 18:38:31 -07:00
|
|
|
test "enum as return value" {
|
2016-12-21 18:49:05 -08:00
|
|
|
switch (returnAnInt(13)) {
|
|
|
|
Foo.One => |value| assert(value == 13),
|
2017-03-26 01:58:48 -07:00
|
|
|
else => unreachable,
|
2016-12-21 18:49:05 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-19 22:50:32 -08:00
|
|
|
const Point = struct {
|
|
|
|
x: u64,
|
|
|
|
y: u64,
|
|
|
|
};
|
2017-12-03 17:43:56 -08:00
|
|
|
const Foo = union(enum) {
|
2016-12-19 22:50:32 -08:00
|
|
|
One: i32,
|
|
|
|
Two: Point,
|
|
|
|
Three: void,
|
|
|
|
};
|
2017-12-03 17:43:56 -08:00
|
|
|
const FooNoVoid = union(enum) {
|
2017-09-30 20:42:44 -07:00
|
|
|
One: i32,
|
|
|
|
Two: Point,
|
|
|
|
};
|
2016-12-19 22:50:32 -08:00
|
|
|
const Bar = enum {
|
|
|
|
A,
|
|
|
|
B,
|
|
|
|
C,
|
|
|
|
D,
|
|
|
|
};
|
|
|
|
|
2016-12-21 18:49:05 -08:00
|
|
|
fn returnAnInt(x: i32) -> Foo {
|
2017-12-21 21:50:30 -08:00
|
|
|
return Foo { .One = x };
|
2016-12-21 18:49:05 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-05-23 18:38:31 -07:00
|
|
|
test "constant enum with payload" {
|
2017-12-03 17:43:56 -08:00
|
|
|
var empty = AnEnumWithPayload {.Empty = {}};
|
|
|
|
var full = AnEnumWithPayload {.Full = 13};
|
2016-12-21 22:20:08 -08:00
|
|
|
shouldBeEmpty(empty);
|
|
|
|
shouldBeNotEmpty(full);
|
|
|
|
}
|
|
|
|
|
2017-03-26 00:39:18 -07:00
|
|
|
fn shouldBeEmpty(x: &const AnEnumWithPayload) {
|
|
|
|
switch (*x) {
|
2016-12-21 22:20:08 -08:00
|
|
|
AnEnumWithPayload.Empty => {},
|
2017-03-26 01:58:48 -07:00
|
|
|
else => unreachable,
|
2016-12-21 22:20:08 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-26 00:39:18 -07:00
|
|
|
fn shouldBeNotEmpty(x: &const AnEnumWithPayload) {
|
|
|
|
switch (*x) {
|
2017-03-26 01:58:48 -07:00
|
|
|
AnEnumWithPayload.Empty => unreachable,
|
2016-12-21 22:20:08 -08:00
|
|
|
else => {},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-03 17:43:56 -08:00
|
|
|
const AnEnumWithPayload = union(enum) {
|
|
|
|
Empty: void,
|
2016-12-21 22:20:08 -08:00
|
|
|
Full: i32,
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-12-25 23:36:04 -08:00
|
|
|
const Number = enum {
|
|
|
|
Zero,
|
|
|
|
One,
|
|
|
|
Two,
|
|
|
|
Three,
|
|
|
|
Four,
|
|
|
|
};
|
|
|
|
|
2017-05-23 18:38:31 -07:00
|
|
|
test "enum to int" {
|
2016-12-25 23:36:04 -08:00
|
|
|
shouldEqual(Number.Zero, 0);
|
|
|
|
shouldEqual(Number.One, 1);
|
|
|
|
shouldEqual(Number.Two, 2);
|
|
|
|
shouldEqual(Number.Three, 3);
|
|
|
|
shouldEqual(Number.Four, 4);
|
|
|
|
}
|
|
|
|
|
2017-12-02 14:12:37 -08:00
|
|
|
fn shouldEqual(n: Number, expected: u3) {
|
|
|
|
assert(u3(n) == expected);
|
2016-12-25 23:36:04 -08:00
|
|
|
}
|
|
|
|
|
2016-12-26 00:44:59 -08:00
|
|
|
|
2017-05-23 18:38:31 -07:00
|
|
|
test "int to enum" {
|
2016-12-26 13:34:18 -08:00
|
|
|
testIntToEnumEval(3);
|
|
|
|
}
|
|
|
|
fn testIntToEnumEval(x: i32) {
|
2017-12-02 14:12:37 -08:00
|
|
|
assert(IntToEnumNumber(u3(x)) == IntToEnumNumber.Three);
|
2016-12-26 13:34:18 -08:00
|
|
|
}
|
|
|
|
const IntToEnumNumber = enum {
|
|
|
|
Zero,
|
|
|
|
One,
|
|
|
|
Two,
|
|
|
|
Three,
|
|
|
|
Four,
|
|
|
|
};
|
2017-04-08 14:45:22 -07:00
|
|
|
|
|
|
|
|
2017-12-03 17:43:56 -08:00
|
|
|
test "@tagName" {
|
2017-04-08 14:45:22 -07:00
|
|
|
assert(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three"));
|
|
|
|
comptime assert(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three"));
|
|
|
|
}
|
|
|
|
|
|
|
|
fn testEnumTagNameBare(n: BareNumber) -> []const u8 {
|
2017-12-03 17:43:56 -08:00
|
|
|
return @tagName(n);
|
2017-04-08 14:45:22 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
const BareNumber = enum {
|
|
|
|
One,
|
|
|
|
Two,
|
|
|
|
Three,
|
|
|
|
};
|
2017-06-17 09:30:29 -07:00
|
|
|
|
|
|
|
|
|
|
|
test "enum alignment" {
|
2017-08-26 10:51:51 -07:00
|
|
|
comptime {
|
2017-08-29 04:30:22 -07:00
|
|
|
assert(@alignOf(AlignTestEnum) >= @alignOf([9]u8));
|
|
|
|
assert(@alignOf(AlignTestEnum) >= @alignOf(u64));
|
2017-08-26 10:51:51 -07:00
|
|
|
}
|
2017-06-17 09:30:29 -07:00
|
|
|
}
|
|
|
|
|
2017-12-03 17:43:56 -08:00
|
|
|
const AlignTestEnum = union(enum) {
|
2017-06-17 09:30:29 -07:00
|
|
|
A: [9]u8,
|
|
|
|
B: u64,
|
|
|
|
};
|
2017-11-08 18:44:10 -08:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
2017-11-30 18:46:02 -08:00
|
|
|
|
|
|
|
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;
|
2017-12-03 19:36:01 -08:00
|
|
|
comptime assert(@TagType(Small) == u2);
|
2017-11-30 18:46:02 -08:00
|
|
|
}
|
|
|
|
{
|
|
|
|
var x = Small2.One;
|
|
|
|
x = Small2.Two;
|
2017-12-03 19:36:01 -08:00
|
|
|
comptime assert(@TagType(Small2) == u2);
|
2017-11-30 18:46:02 -08:00
|
|
|
}
|
|
|
|
}
|
2017-11-30 21:34:29 -08:00
|
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2017-12-02 14:12:37 -08:00
|
|
|
test "casting enum to its tag type" {
|
|
|
|
testCastEnumToTagType(Small2.Two);
|
|
|
|
comptime testCastEnumToTagType(Small2.Two);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn testCastEnumToTagType(value: Small2) {
|
|
|
|
assert(u2(value) == 1);
|
|
|
|
}
|
2017-12-02 19:31:42 -08:00
|
|
|
|
|
|
|
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,
|
|
|
|
});
|
|
|
|
}
|
2017-12-05 15:09:22 -08:00
|
|
|
|
|
|
|
test "cast integer literal to enum" {
|
|
|
|
assert(MultipleChoice2(0) == MultipleChoice2.Unspecified1);
|
|
|
|
assert(MultipleChoice2(40) == MultipleChoice2.B);
|
|
|
|
}
|
2017-12-05 19:15:33 -08:00
|
|
|
|
|
|
|
const EnumWithOneMember = enum {
|
|
|
|
Eof,
|
|
|
|
};
|
|
|
|
|
|
|
|
fn doALoopThing(id: EnumWithOneMember) {
|
|
|
|
while (true) {
|
|
|
|
if (id == EnumWithOneMember.Eof) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
@compileError("above if condition should be comptime");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
test "comparison operator on enum with one member is comptime known" {
|
|
|
|
doALoopThing(EnumWithOneMember.Eof);
|
|
|
|
}
|
2017-12-05 19:26:17 -08:00
|
|
|
|
|
|
|
const State = enum {
|
|
|
|
Start,
|
|
|
|
};
|
|
|
|
test "switch on enum with one member is comptime known" {
|
|
|
|
var state = State.Start;
|
|
|
|
switch (state) {
|
|
|
|
State.Start => return,
|
|
|
|
}
|
|
|
|
@compileError("analysis should not reach here");
|
|
|
|
}
|
2018-01-03 13:05:37 -08:00
|
|
|
|
|
|
|
const EnumWithTagValues = enum(u4) {
|
|
|
|
A = 1 << 0,
|
|
|
|
B = 1 << 1,
|
|
|
|
C = 1 << 2,
|
|
|
|
D = 1 << 3,
|
|
|
|
};
|
|
|
|
test "enum with tag values don't require parens" {
|
|
|
|
assert(u4(EnumWithTagValues.C) == 0b0100);
|
|
|
|
}
|