@@ -2756,21 +2756,67 @@ test "recursive format function" {
2756
2756
2757
2757
pub const hex_charset = "0123456789abcdef" ;
2758
2758
2759
- /// Converts an unsigned integer of any multiple of u8 to an array of lowercase
2760
- /// hex bytes, little endian.
2761
- pub fn hex (x : anytype ) [@sizeOf (@TypeOf (x )) * 2 ]u8 {
2762
- comptime assert (@typeInfo (@TypeOf (x )).int .signedness == .unsigned );
2763
- var result : [@sizeOf (@TypeOf (x )) * 2 ]u8 = undefined ;
2764
- var i : usize = 0 ;
2765
- while (i < result .len / 2 ) : (i += 1 ) {
2766
- const byte : u8 = @truncate (x >> @intCast (8 * i ));
2767
- result [i * 2 + 0 ] = hex_charset [byte >> 4 ];
2768
- result [i * 2 + 1 ] = hex_charset [byte & 15 ];
2769
- }
2759
+ /// Deprecated, use `std.fmt.hexOptions(x, .{ .endianness = .little })` instead.
2760
+ pub fn hex (x : anytype ) HexOptionsResult (@TypeOf (x ), .{ .endianness = .little }) {
2761
+ return hexOptions (x , .{ .endianness = .little });
2762
+ }
2763
+
2764
+ /// Converts an integer to an array of hex characters.
2765
+ pub fn hexOptions (x : anytype , comptime options : HexOptions ) HexOptionsResult (@TypeOf (x ), options ) {
2766
+ var result : HexOptionsResult (@TypeOf (x ), options ) = undefined ;
2767
+
2768
+ comptime switch (@typeInfo (@TypeOf (x ))) {
2769
+ .comptime_int = > if (! (x >= - (1 << (4 * result .len - 1 )) and x < 1 << (4 * result .len )))
2770
+ @compileError ("out of bounds" ),
2771
+ .int = > | int | if (int .bits > 4 * result .len ) @compileError ("out of bounds" ),
2772
+ else = > @compileError ("x is not an integer" ),
2773
+ };
2774
+
2775
+ const table = switch (options .case ) {
2776
+ .lower = > "0123456789abcdef" ,
2777
+ .upper = > "0123456789ABCDEF" ,
2778
+ };
2779
+
2780
+ _ = switch (options .endianness ) {
2781
+ .little = > {
2782
+ inline for (0.. result .len / 2 ) | i | {
2783
+ result [2 * i ] = table [@as (u4 , @truncate (math .shr (@TypeOf (x ), x , 4 * (2 * i + 1 ))))];
2784
+ result [2 * i + 1 ] = table [@as (u4 , @truncate (math .shr (@TypeOf (x ), x , 4 * 2 * i )))];
2785
+ }
2786
+ },
2787
+ .big = > .{inline for (0.. result .len ) | i | {
2788
+ result [i ] = table [@as (u4 , @truncate (math .shr (@TypeOf (x ), x , 4 * (result .len - 1 - i ))))];
2789
+ }},
2790
+ };
2791
+
2770
2792
return result ;
2771
2793
}
2772
2794
2795
+ pub fn HexOptionsResult (x : type , comptime options : HexOptions ) type {
2796
+ const hex_count = 2 * (options .octet_count orelse comptime switch (@typeInfo (x )) {
2797
+ .int = > | int | (int .bits + 7 ) / 8 ,
2798
+ .comptime_int = > @compileError ("std.fmt.hexOptions on comptime_int must have options.octet_count set" ),
2799
+ else = > @compileError ("type must be an integer" ),
2800
+ });
2801
+
2802
+ return [hex_count ]u8 ;
2803
+ }
2804
+
2805
+ pub const HexOptions = struct {
2806
+ /// Whether octets are ordered little-endian or big-endian
2807
+ endianness : std.builtin.Endian = .big ,
2808
+ case : enum { lower , upper } = .lower ,
2809
+ /// Sign pads the result to the number of octets.
2810
+ /// Required for `comptime_int`.
2811
+ octet_count : ? usize = null ,
2812
+ };
2813
+
2773
2814
test hex {
2815
+ {
2816
+ const x = hex (@as (u48 , 0x1234_5678_abcd ));
2817
+ try std .testing .expect (x .len == 12 );
2818
+ try std .testing .expectEqualStrings ("cdab78563412" , & x );
2819
+ }
2774
2820
{
2775
2821
const x = hex (@as (u32 , 0xdeadbeef ));
2776
2822
try std .testing .expect (x .len == 8 );
@@ -2783,6 +2829,24 @@ test hex {
2783
2829
}
2784
2830
}
2785
2831
2832
+ test hexOptions {
2833
+ {
2834
+ const x = hexOptions (@as (u48 , 0x1234_5678_abcd ), .{ .octet_count = 8 });
2835
+ try std .testing .expect (x .len == 16 );
2836
+ try std .testing .expectEqualStrings ("000012345678abcd" , & x );
2837
+ }
2838
+ {
2839
+ const x = hexOptions (@as (u32 , 0xdeadbeef ), .{ .endianness = .little , .case = .upper });
2840
+ try std .testing .expect (x .len == 8 );
2841
+ try std .testing .expectEqualStrings ("EFBEADDE" , & x );
2842
+ }
2843
+ {
2844
+ const x = hexOptions (-0x3047abed , .{ .octet_count = 8 , .endianness = .little });
2845
+ try std .testing .expect (x .len == 16 );
2846
+ try std .testing .expectEqualStrings ("1354b8cfffffffff" , & x );
2847
+ }
2848
+ }
2849
+
2786
2850
test "parser until" {
2787
2851
{ // return substring till ':'
2788
2852
var parser : Parser = .{
0 commit comments