| ... | ... | @@ -2839,81 +2839,81 @@ const mem = @import("std").mem; |
| 2839 | 2839 | |
| 2840 | 2840 | // Declare an enum. |
| 2841 | 2841 | const Type = enum { |
| 2842 | | Ok, |
| 2843 | | NotOk, |
| 2842 | ok, |
| 2843 | not_ok, |
| 2844 | 2844 | }; |
| 2845 | 2845 | |
| 2846 | 2846 | // Declare a specific instance of the enum variant. |
| 2847 | | const c = Type.Ok; |
| 2847 | const c = Type.ok; |
| 2848 | 2848 | |
| 2849 | 2849 | // If you want access to the ordinal value of an enum, you |
| 2850 | 2850 | // can specify the tag type. |
| 2851 | 2851 | const Value = enum(u2) { |
| 2852 | | Zero, |
| 2853 | | One, |
| 2854 | | Two, |
| 2852 | zero, |
| 2853 | one, |
| 2854 | two, |
| 2855 | 2855 | }; |
| 2856 | 2856 | |
| 2857 | 2857 | // Now you can cast between u2 and Value. |
| 2858 | 2858 | // The ordinal value starts from 0, counting up for each member. |
| 2859 | 2859 | test "enum ordinal value" { |
| 2860 | | assert(@enumToInt(Value.Zero) == 0); |
| 2861 | | assert(@enumToInt(Value.One) == 1); |
| 2862 | | assert(@enumToInt(Value.Two) == 2); |
| 2860 | assert(@enumToInt(Value.zero) == 0); |
| 2861 | assert(@enumToInt(Value.one) == 1); |
| 2862 | assert(@enumToInt(Value.two) == 2); |
| 2863 | 2863 | } |
| 2864 | 2864 | |
| 2865 | 2865 | // You can override the ordinal value for an enum. |
| 2866 | 2866 | const Value2 = enum(u32) { |
| 2867 | | Hundred = 100, |
| 2868 | | Thousand = 1000, |
| 2869 | | Million = 1000000, |
| 2867 | hundred = 100, |
| 2868 | thousand = 1000, |
| 2869 | million = 1000000, |
| 2870 | 2870 | }; |
| 2871 | 2871 | test "set enum ordinal value" { |
| 2872 | | assert(@enumToInt(Value2.Hundred) == 100); |
| 2873 | | assert(@enumToInt(Value2.Thousand) == 1000); |
| 2874 | | assert(@enumToInt(Value2.Million) == 1000000); |
| 2872 | assert(@enumToInt(Value2.hundred) == 100); |
| 2873 | assert(@enumToInt(Value2.thousand) == 1000); |
| 2874 | assert(@enumToInt(Value2.million) == 1000000); |
| 2875 | 2875 | } |
| 2876 | 2876 | |
| 2877 | 2877 | // Enums can have methods, the same as structs and unions. |
| 2878 | 2878 | // Enum methods are not special, they are only namespaced |
| 2879 | 2879 | // functions that you can call with dot syntax. |
| 2880 | 2880 | const Suit = enum { |
| 2881 | | Clubs, |
| 2882 | | Spades, |
| 2883 | | Diamonds, |
| 2884 | | Hearts, |
| 2881 | clubs, |
| 2882 | spades, |
| 2883 | diamonds, |
| 2884 | hearts, |
| 2885 | 2885 | |
| 2886 | 2886 | pub fn isClubs(self: Suit) bool { |
| 2887 | | return self == Suit.Clubs; |
| 2887 | return self == Suit.clubs; |
| 2888 | 2888 | } |
| 2889 | 2889 | }; |
| 2890 | 2890 | test "enum method" { |
| 2891 | | const p = Suit.Spades; |
| 2891 | const p = Suit.spades; |
| 2892 | 2892 | assert(!p.isClubs()); |
| 2893 | 2893 | } |
| 2894 | 2894 | |
| 2895 | 2895 | // An enum variant of different types can be switched upon. |
| 2896 | 2896 | const Foo = enum { |
| 2897 | | String, |
| 2898 | | Number, |
| 2899 | | None, |
| 2897 | string, |
| 2898 | number, |
| 2899 | none, |
| 2900 | 2900 | }; |
| 2901 | 2901 | test "enum variant switch" { |
| 2902 | | const p = Foo.Number; |
| 2902 | const p = Foo.number; |
| 2903 | 2903 | const what_is_it = switch (p) { |
| 2904 | | Foo.String => "this is a string", |
| 2905 | | Foo.Number => "this is a number", |
| 2906 | | Foo.None => "this is a none", |
| 2904 | Foo.string => "this is a string", |
| 2905 | Foo.number => "this is a number", |
| 2906 | Foo.none => "this is a none", |
| 2907 | 2907 | }; |
| 2908 | 2908 | assert(mem.eql(u8, what_is_it, "this is a number")); |
| 2909 | 2909 | } |
| 2910 | 2910 | |
| 2911 | 2911 | // @TagType can be used to access the integer tag type of an enum. |
| 2912 | 2912 | const Small = enum { |
| 2913 | | One, |
| 2914 | | Two, |
| 2915 | | Three, |
| 2916 | | Four, |
| 2913 | one, |
| 2914 | two, |
| 2915 | three, |
| 2916 | four, |
| 2917 | 2917 | }; |
| 2918 | 2918 | test "@TagType" { |
| 2919 | 2919 | assert(@TagType(Small) == u2); |
| ... | ... | @@ -2922,12 +2922,12 @@ test "@TagType" { |
| 2922 | 2922 | // @typeInfo tells us the field count and the fields names: |
| 2923 | 2923 | test "@typeInfo" { |
| 2924 | 2924 | assert(@typeInfo(Small).Enum.fields.len == 4); |
| 2925 | | assert(mem.eql(u8, @typeInfo(Small).Enum.fields[1].name, "Two")); |
| 2925 | assert(mem.eql(u8, @typeInfo(Small).Enum.fields[1].name, "two")); |
| 2926 | 2926 | } |
| 2927 | 2927 | |
| 2928 | 2928 | // @tagName gives a []const u8 representation of an enum value: |
| 2929 | 2929 | test "@tagName" { |
| 2930 | | assert(mem.eql(u8, @tagName(Small.Three), "Three")); |
| 2930 | assert(mem.eql(u8, @tagName(Small.three), "three")); |
| 2931 | 2931 | } |
| 2932 | 2932 | {#code_end#} |
| 2933 | 2933 | {#see_also|@typeInfo|@tagName|@sizeOf#} |
| ... | ... | @@ -2937,14 +2937,14 @@ test "@tagName" { |
| 2937 | 2937 | By default, enums are not guaranteed to be compatible with the C ABI: |
| 2938 | 2938 | </p> |
| 2939 | 2939 | {#code_begin|obj_err|parameter of type 'Foo' not allowed in function with calling convention 'C'#} |
| 2940 | | const Foo = enum { A, B, C }; |
| 2940 | const Foo = enum { a, b, c }; |
| 2941 | 2941 | export fn entry(foo: Foo) void { } |
| 2942 | 2942 | {#code_end#} |
| 2943 | 2943 | <p> |
| 2944 | 2944 | For a C-ABI-compatible enum, use {#syntax#}extern enum{#endsyntax#}: |
| 2945 | 2945 | </p> |
| 2946 | 2946 | {#code_begin|obj#} |
| 2947 | | const Foo = extern enum { A, B, C }; |
| 2947 | const Foo = extern enum { a, b, c }; |
| 2948 | 2948 | export fn entry(foo: Foo) void { } |
| 2949 | 2949 | {#code_end#} |
| 2950 | 2950 | {#header_close#} |
| ... | ... | @@ -2958,9 +2958,9 @@ const std = @import("std"); |
| 2958 | 2958 | |
| 2959 | 2959 | test "packed enum" { |
| 2960 | 2960 | const Number = packed enum(u8) { |
| 2961 | | One, |
| 2962 | | Two, |
| 2963 | | Three, |
| 2961 | one, |
| 2962 | two, |
| 2963 | three, |
| 2964 | 2964 | }; |
| 2965 | 2965 | std.debug.assert(@sizeOf(Number) == @sizeOf(u8)); |
| 2966 | 2966 | } |
| ... | ... | @@ -2977,23 +2977,23 @@ const std = @import("std"); |
| 2977 | 2977 | const assert = std.debug.assert; |
| 2978 | 2978 | |
| 2979 | 2979 | const Color = enum { |
| 2980 | | Auto, |
| 2981 | | Off, |
| 2982 | | On, |
| 2980 | auto, |
| 2981 | off, |
| 2982 | on, |
| 2983 | 2983 | }; |
| 2984 | 2984 | |
| 2985 | 2985 | test "enum literals" { |
| 2986 | | const color1: Color = .Auto; |
| 2987 | | const color2 = Color.Auto; |
| 2986 | const color1: Color = .auto; |
| 2987 | const color2 = Color.auto; |
| 2988 | 2988 | assert(color1 == color2); |
| 2989 | 2989 | } |
| 2990 | 2990 | |
| 2991 | 2991 | test "switch using enum literals" { |
| 2992 | | const color = Color.On; |
| 2992 | const color = Color.on; |
| 2993 | 2993 | const result = switch (color) { |
| 2994 | | .Auto => false, |
| 2995 | | .On => true, |
| 2996 | | .Off => false, |
| 2994 | .auto => false, |
| 2995 | .on => true, |
| 2996 | .off => false, |
| 2997 | 2997 | }; |
| 2998 | 2998 | assert(result); |
| 2999 | 2999 | } |
| ... | ... | @@ -3017,23 +3017,23 @@ const std = @import("std"); |
| 3017 | 3017 | const assert = std.debug.assert; |
| 3018 | 3018 | |
| 3019 | 3019 | const Number = enum(u8) { |
| 3020 | | One, |
| 3021 | | Two, |
| 3022 | | Three, |
| 3020 | one, |
| 3021 | two, |
| 3022 | three, |
| 3023 | 3023 | _, |
| 3024 | 3024 | }; |
| 3025 | 3025 | |
| 3026 | 3026 | test "switch on non-exhaustive enum" { |
| 3027 | | const number = Number.One; |
| 3027 | const number = Number.one; |
| 3028 | 3028 | const result = switch (number) { |
| 3029 | | .One => true, |
| 3030 | | .Two, |
| 3031 | | .Three => false, |
| 3029 | .one => true, |
| 3030 | .two, |
| 3031 | .three => false, |
| 3032 | 3032 | _ => false, |
| 3033 | 3033 | }; |
| 3034 | 3034 | assert(result); |
| 3035 | 3035 | const is_one = switch (number) { |
| 3036 | | .One => true, |
| 3036 | .one => true, |
| 3037 | 3037 | else => false, |
| 3038 | 3038 | }; |
| 3039 | 3039 | assert(is_one); |
| ... | ... | @@ -3055,13 +3055,13 @@ test "switch on non-exhaustive enum" { |
| 3055 | 3055 | </p> |
| 3056 | 3056 | {#code_begin|test_err|inactive union field#} |
| 3057 | 3057 | const Payload = union { |
| 3058 | | Int: i64, |
| 3059 | | Float: f64, |
| 3060 | | Bool: bool, |
| 3058 | int: i64, |
| 3059 | float: f64, |
| 3060 | boolean: bool, |
| 3061 | 3061 | }; |
| 3062 | 3062 | test "simple union" { |
| 3063 | | var payload = Payload{ .Int = 1234 }; |
| 3064 | | payload.Float = 12.34; |
| 3063 | var payload = Payload{ .int = 1234 }; |
| 3064 | payload.float = 12.34; |
| 3065 | 3065 | } |
| 3066 | 3066 | {#code_end#} |
| 3067 | 3067 | <p>You can activate another field by assigning the entire union:</p> |
| ... | ... | @@ -3070,15 +3070,15 @@ const std = @import("std"); |
| 3070 | 3070 | const assert = std.debug.assert; |
| 3071 | 3071 | |
| 3072 | 3072 | const Payload = union { |
| 3073 | | Int: i64, |
| 3074 | | Float: f64, |
| 3075 | | Bool: bool, |
| 3073 | int: i64, |
| 3074 | float: f64, |
| 3075 | boolean: bool, |
| 3076 | 3076 | }; |
| 3077 | 3077 | test "simple union" { |
| 3078 | | var payload = Payload{ .Int = 1234 }; |
| 3079 | | assert(payload.Int == 1234); |
| 3080 | | payload = Payload{ .Float = 12.34 }; |
| 3081 | | assert(payload.Float == 12.34); |
| 3078 | var payload = Payload{ .int = 1234 }; |
| 3079 | assert(payload.int == 1234); |
| 3080 | payload = Payload{ .float = 12.34 }; |
| 3081 | assert(payload.float == 12.34); |
| 3082 | 3082 | } |
| 3083 | 3083 | {#code_end#} |
| 3084 | 3084 | <p> |
| ... | ... | @@ -3100,21 +3100,21 @@ const std = @import("std"); |
| 3100 | 3100 | const assert = std.debug.assert; |
| 3101 | 3101 | |
| 3102 | 3102 | const ComplexTypeTag = enum { |
| 3103 | | Ok, |
| 3104 | | NotOk, |
| 3103 | ok, |
| 3104 | not_ok, |
| 3105 | 3105 | }; |
| 3106 | 3106 | const ComplexType = union(ComplexTypeTag) { |
| 3107 | | Ok: u8, |
| 3108 | | NotOk: void, |
| 3107 | ok: u8, |
| 3108 | not_ok: void, |
| 3109 | 3109 | }; |
| 3110 | 3110 | |
| 3111 | 3111 | test "switch on tagged union" { |
| 3112 | | const c = ComplexType{ .Ok = 42 }; |
| 3113 | | assert(@as(ComplexTypeTag, c) == ComplexTypeTag.Ok); |
| 3112 | const c = ComplexType{ .ok = 42 }; |
| 3113 | assert(@as(ComplexTypeTag, c) == ComplexTypeTag.ok); |
| 3114 | 3114 | |
| 3115 | 3115 | switch (c) { |
| 3116 | | ComplexTypeTag.Ok => |value| assert(value == 42), |
| 3117 | | ComplexTypeTag.NotOk => unreachable, |
| 3116 | ComplexTypeTag.ok => |value| assert(value == 42), |
| 3117 | ComplexTypeTag.not_ok => unreachable, |
| 3118 | 3118 | } |
| 3119 | 3119 | } |
| 3120 | 3120 | |
| ... | ... | @@ -3123,11 +3123,11 @@ test "@TagType" { |
| 3123 | 3123 | } |
| 3124 | 3124 | |
| 3125 | 3125 | test "coerce to enum" { |
| 3126 | | const c1 = ComplexType{ .Ok = 42 }; |
| 3127 | | const c2 = ComplexType.NotOk; |
| 3126 | const c1 = ComplexType{ .ok = 42 }; |
| 3127 | const c2 = ComplexType.not_ok; |
| 3128 | 3128 | |
| 3129 | | assert(c1 == .Ok); |
| 3130 | | assert(c2 == .NotOk); |
| 3129 | assert(c1 == .ok); |
| 3130 | assert(c2 == .not_ok); |
| 3131 | 3131 | } |
| 3132 | 3132 | {#code_end#} |
| 3133 | 3133 | <p>In order to modify the payload of a tagged union in a switch expression, |
| ... | ... | @@ -3138,24 +3138,24 @@ const std = @import("std"); |
| 3138 | 3138 | const assert = std.debug.assert; |
| 3139 | 3139 | |
| 3140 | 3140 | const ComplexTypeTag = enum { |
| 3141 | | Ok, |
| 3142 | | NotOk, |
| 3141 | ok, |
| 3142 | not_ok, |
| 3143 | 3143 | }; |
| 3144 | 3144 | const ComplexType = union(ComplexTypeTag) { |
| 3145 | | Ok: u8, |
| 3146 | | NotOk: void, |
| 3145 | ok: u8, |
| 3146 | not_ok: void, |
| 3147 | 3147 | }; |
| 3148 | 3148 | |
| 3149 | 3149 | test "modify tagged union in switch" { |
| 3150 | | var c = ComplexType{ .Ok = 42 }; |
| 3151 | | assert(@as(ComplexTypeTag, c) == ComplexTypeTag.Ok); |
| 3150 | var c = ComplexType{ .ok = 42 }; |
| 3151 | assert(@as(ComplexTypeTag, c) == ComplexTypeTag.ok); |
| 3152 | 3152 | |
| 3153 | 3153 | switch (c) { |
| 3154 | | ComplexTypeTag.Ok => |*value| value.* += 1, |
| 3155 | | ComplexTypeTag.NotOk => unreachable, |
| 3154 | ComplexTypeTag.ok => |*value| value.* += 1, |
| 3155 | ComplexTypeTag.not_ok => unreachable, |
| 3156 | 3156 | } |
| 3157 | 3157 | |
| 3158 | | assert(c.Ok == 43); |
| 3158 | assert(c.ok == 43); |
| 3159 | 3159 | } |
| 3160 | 3160 | {#code_end#} |
| 3161 | 3161 | <p> |
| ... | ... | @@ -3167,24 +3167,24 @@ const std = @import("std"); |
| 3167 | 3167 | const assert = std.debug.assert; |
| 3168 | 3168 | |
| 3169 | 3169 | const Variant = union(enum) { |
| 3170 | | Int: i32, |
| 3171 | | Bool: bool, |
| 3170 | int: i32, |
| 3171 | boolean: bool, |
| 3172 | 3172 | |
| 3173 | 3173 | // void can be omitted when inferring enum tag type. |
| 3174 | | None, |
| 3174 | none, |
| 3175 | 3175 | |
| 3176 | 3176 | fn truthy(self: Variant) bool { |
| 3177 | 3177 | return switch (self) { |
| 3178 | | Variant.Int => |x_int| x_int != 0, |
| 3179 | | Variant.Bool => |x_bool| x_bool, |
| 3180 | | Variant.None => false, |
| 3178 | Variant.int => |x_int| x_int != 0, |
| 3179 | Variant.boolean => |x_bool| x_bool, |
| 3180 | Variant.none => false, |
| 3181 | 3181 | }; |
| 3182 | 3182 | } |
| 3183 | 3183 | }; |
| 3184 | 3184 | |
| 3185 | 3185 | test "union method" { |
| 3186 | | var v1 = Variant{ .Int = 1 }; |
| 3187 | | var v2 = Variant{ .Bool = false }; |
| 3186 | var v1 = Variant{ .int = 1 }; |
| 3187 | var v2 = Variant{ .boolean = false }; |
| 3188 | 3188 | |
| 3189 | 3189 | assert(v1.truthy()); |
| 3190 | 3190 | assert(!v2.truthy()); |
| ... | ... | @@ -3199,12 +3199,12 @@ const std = @import("std"); |
| 3199 | 3199 | const assert = std.debug.assert; |
| 3200 | 3200 | |
| 3201 | 3201 | const Small2 = union(enum) { |
| 3202 | | A: i32, |
| 3203 | | B: bool, |
| 3204 | | C: u8, |
| 3202 | a: i32, |
| 3203 | b: bool, |
| 3204 | c: u8, |
| 3205 | 3205 | }; |
| 3206 | 3206 | test "@tagName" { |
| 3207 | | assert(std.mem.eql(u8, @tagName(Small2.C), "C")); |
| 3207 | assert(std.mem.eql(u8, @tagName(Small2.a), "a")); |
| 3208 | 3208 | } |
| 3209 | 3209 | {#code_end#} |
| 3210 | 3210 | {#header_close#} |
| ... | ... | @@ -3392,33 +3392,33 @@ test "switch on tagged union" { |
| 3392 | 3392 | y: u8, |
| 3393 | 3393 | }; |
| 3394 | 3394 | const Item = union(enum) { |
| 3395 | | A: u32, |
| 3396 | | C: Point, |
| 3397 | | D, |
| 3398 | | E: u32, |
| 3395 | a: u32, |
| 3396 | c: Point, |
| 3397 | d, |
| 3398 | e: u32, |
| 3399 | 3399 | }; |
| 3400 | 3400 | |
| 3401 | | var a = Item{ .C = Point{ .x = 1, .y = 2 } }; |
| 3401 | var a = Item{ .c = Point{ .x = 1, .y = 2 } }; |
| 3402 | 3402 | |
| 3403 | 3403 | // Switching on more complex enums is allowed. |
| 3404 | 3404 | const b = switch (a) { |
| 3405 | 3405 | // A capture group is allowed on a match, and will return the enum |
| 3406 | 3406 | // value matched. If the payload types of both cases are the same |
| 3407 | 3407 | // they can be put into the same switch prong. |
| 3408 | | Item.A, Item.E => |item| item, |
| 3408 | Item.a, Item.e => |item| item, |
| 3409 | 3409 | |
| 3410 | 3410 | // A reference to the matched value can be obtained using `*` syntax. |
| 3411 | | Item.C => |*item| blk: { |
| 3411 | Item.c => |*item| blk: { |
| 3412 | 3412 | item.*.x += 1; |
| 3413 | 3413 | break :blk 6; |
| 3414 | 3414 | }, |
| 3415 | 3415 | |
| 3416 | 3416 | // No else is required if the types cases was exhaustively handled |
| 3417 | | Item.D => 8, |
| 3417 | Item.d => 8, |
| 3418 | 3418 | }; |
| 3419 | 3419 | |
| 3420 | 3420 | assert(b == 6); |
| 3421 | | assert(a.C.x == 2); |
| 3421 | assert(a.c.x == 2); |
| 3422 | 3422 | } |
| 3423 | 3423 | {#code_end#} |
| 3424 | 3424 | {#see_also|comptime|enum|@compileError|Compile Variables#} |
| ... | ... | @@ -3430,16 +3430,16 @@ test "switch on tagged union" { |
| 3430 | 3430 | </p> |
| 3431 | 3431 | {#code_begin|test_err|not handled in switch#} |
| 3432 | 3432 | const Color = enum { |
| 3433 | | Auto, |
| 3434 | | Off, |
| 3435 | | On, |
| 3433 | auto, |
| 3434 | off, |
| 3435 | on, |
| 3436 | 3436 | }; |
| 3437 | 3437 | |
| 3438 | 3438 | test "exhaustive switching" { |
| 3439 | | const color = Color.Off; |
| 3439 | const color = Color.off; |
| 3440 | 3440 | switch (color) { |
| 3441 | | Color.Auto => {}, |
| 3442 | | Color.On => {}, |
| 3441 | Color.auto => {}, |
| 3442 | Color.on => {}, |
| 3443 | 3443 | } |
| 3444 | 3444 | } |
| 3445 | 3445 | {#code_end#} |
| ... | ... | @@ -3455,17 +3455,17 @@ const std = @import("std"); |
| 3455 | 3455 | const assert = std.debug.assert; |
| 3456 | 3456 | |
| 3457 | 3457 | const Color = enum { |
| 3458 | | Auto, |
| 3459 | | Off, |
| 3460 | | On, |
| 3458 | auto, |
| 3459 | off, |
| 3460 | on, |
| 3461 | 3461 | }; |
| 3462 | 3462 | |
| 3463 | 3463 | test "enum literals with switch" { |
| 3464 | | const color = Color.Off; |
| 3464 | const color = Color.off; |
| 3465 | 3465 | const result = switch (color) { |
| 3466 | | .Auto => false, |
| 3467 | | .On => false, |
| 3468 | | .Off => true, |
| 3466 | .auto => false, |
| 3467 | .on => false, |
| 3468 | .off => true, |
| 3469 | 3469 | }; |
| 3470 | 3470 | assert(result); |
| 3471 | 3471 | } |
| ... | ... | @@ -5302,25 +5302,25 @@ const std = @import("std"); |
| 5302 | 5302 | const assert = std.debug.assert; |
| 5303 | 5303 | |
| 5304 | 5304 | const E = enum { |
| 5305 | | One, |
| 5306 | | Two, |
| 5307 | | Three, |
| 5305 | one, |
| 5306 | two, |
| 5307 | three, |
| 5308 | 5308 | }; |
| 5309 | 5309 | |
| 5310 | 5310 | const U = union(E) { |
| 5311 | | One: i32, |
| 5312 | | Two: f32, |
| 5313 | | Three, |
| 5311 | one: i32, |
| 5312 | two: f32, |
| 5313 | three, |
| 5314 | 5314 | }; |
| 5315 | 5315 | |
| 5316 | 5316 | test "coercion between unions and enums" { |
| 5317 | | var u = U{ .Two = 12.34 }; |
| 5317 | var u = U{ .two = 12.34 }; |
| 5318 | 5318 | var e: E = u; |
| 5319 | | assert(e == E.Two); |
| 5319 | assert(e == E.two); |
| 5320 | 5320 | |
| 5321 | | const three = E.Three; |
| 5321 | const three = E.three; |
| 5322 | 5322 | var another_u: U = three; |
| 5323 | | assert(another_u == E.Three); |
| 5323 | assert(another_u == E.three); |
| 5324 | 5324 | } |
| 5325 | 5325 | {#code_end#} |
| 5326 | 5326 | {#see_also|union|enum#} |
| ... | ... | @@ -6096,44 +6096,44 @@ pub fn main() void { |
| 6096 | 6096 | /// Calls print and then flushes the buffer. |
| 6097 | 6097 | pub fn printf(self: *OutStream, comptime format: []const u8, args: anytype) anyerror!void { |
| 6098 | 6098 | const State = enum { |
| 6099 | | Start, |
| 6100 | | OpenBrace, |
| 6101 | | CloseBrace, |
| 6099 | start, |
| 6100 | open_brace, |
| 6101 | close_brace, |
| 6102 | 6102 | }; |
| 6103 | 6103 | |
| 6104 | 6104 | comptime var start_index: usize = 0; |
| 6105 | | comptime var state = State.Start; |
| 6105 | comptime var state = State.start; |
| 6106 | 6106 | comptime var next_arg: usize = 0; |
| 6107 | 6107 | |
| 6108 | 6108 | inline for (format) |c, i| { |
| 6109 | 6109 | switch (state) { |
| 6110 | | State.Start => switch (c) { |
| 6110 | State.start => switch (c) { |
| 6111 | 6111 | '{' => { |
| 6112 | 6112 | if (start_index < i) try self.write(format[start_index..i]); |
| 6113 | | state = State.OpenBrace; |
| 6113 | state = State.open_brace; |
| 6114 | 6114 | }, |
| 6115 | 6115 | '}' => { |
| 6116 | 6116 | if (start_index < i) try self.write(format[start_index..i]); |
| 6117 | | state = State.CloseBrace; |
| 6117 | state = State.close_brace; |
| 6118 | 6118 | }, |
| 6119 | 6119 | else => {}, |
| 6120 | 6120 | }, |
| 6121 | | State.OpenBrace => switch (c) { |
| 6121 | State.open_brace => switch (c) { |
| 6122 | 6122 | '{' => { |
| 6123 | | state = State.Start; |
| 6123 | state = State.start; |
| 6124 | 6124 | start_index = i; |
| 6125 | 6125 | }, |
| 6126 | 6126 | '}' => { |
| 6127 | 6127 | try self.printValue(args[next_arg]); |
| 6128 | 6128 | next_arg += 1; |
| 6129 | | state = State.Start; |
| 6129 | state = State.start; |
| 6130 | 6130 | start_index = i + 1; |
| 6131 | 6131 | }, |
| 6132 | 6132 | else => @compileError("Unknown format character: " ++ c), |
| 6133 | 6133 | }, |
| 6134 | | State.CloseBrace => switch (c) { |
| 6134 | State.close_brace => switch (c) { |
| 6135 | 6135 | '}' => { |
| 6136 | | state = State.Start; |
| 6136 | state = State.start; |
| 6137 | 6137 | start_index = i; |
| 6138 | 6138 | }, |
| 6139 | 6139 | else => @compileError("Single '}' encountered in format string"), |
| ... | ... | @@ -9069,9 +9069,9 @@ pub fn main() void { |
| 9069 | 9069 | <p>At compile-time:</p> |
| 9070 | 9070 | {#code_begin|test_err|has no tag matching integer value 3#} |
| 9071 | 9071 | const Foo = enum { |
| 9072 | | A, |
| 9073 | | B, |
| 9074 | | C, |
| 9072 | a, |
| 9073 | b, |
| 9074 | c, |
| 9075 | 9075 | }; |
| 9076 | 9076 | comptime { |
| 9077 | 9077 | const a: u2 = 3; |
| ... | ... | @@ -9083,9 +9083,9 @@ comptime { |
| 9083 | 9083 | const std = @import("std"); |
| 9084 | 9084 | |
| 9085 | 9085 | const Foo = enum { |
| 9086 | | A, |
| 9087 | | B, |
| 9088 | | C, |
| 9086 | a, |
| 9087 | b, |
| 9088 | c, |
| 9089 | 9089 | }; |
| 9090 | 9090 | |
| 9091 | 9091 | pub fn main() void { |