@@ -2756,21 +2756,71 @@ 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
+ const x_bits = if (@TypeOf (x ) == comptime_int ) 4 * result .len else @typeInfo (@TypeOf (x )).int .bits ;
2769
+
2770
+ comptime switch (@typeInfo (@TypeOf (x ))) {
2771
+ .comptime_int = > if (! (x >= - (1 << (4 * result .len - 1 )) and x < 1 << (4 * result .len )))
2772
+ @compileError ("out of bounds" ),
2773
+ .int = > | int | if (int .bits > 4 * result .len ) @compileError ("out of bounds" ),
2774
+ else = > @compileError ("x is not an integer" ),
2775
+ };
2776
+
2777
+ const table = switch (options .case ) {
2778
+ .lower = > "0123456789abcdef" ,
2779
+ .upper = > "0123456789ABCDEF" ,
2780
+ };
2781
+
2782
+ _ = switch (options .endianness ) {
2783
+ .little = > {
2784
+ inline for (0.. result .len / 2 ) | i | {
2785
+ result [2 * i ] = table [@as (u4 , @truncate (x >> @min (4 * (2 * i + 1 ), x_bits - 1 )))];
2786
+ result [2 * i + 1 ] = table [@as (u4 , @truncate (x >> @min (4 * 2 * i , x_bits - 1 )))];
2787
+ }
2788
+ },
2789
+ .big = > .{inline for (0.. result .len ) | i | {
2790
+ result [i ] = table [@as (u4 , @truncate (x >> @min (4 * (result .len - 1 - i ), x_bits - 1 )))];
2791
+ }},
2792
+ };
2793
+
2770
2794
return result ;
2771
2795
}
2772
2796
2797
+ pub fn HexOptionsResult (x : type , comptime options : HexOptions ) type {
2798
+ const info = @typeInfo (x );
2799
+
2800
+ const hex_count = 2 * (options .octet_count orelse comptime switch (info ) {
2801
+ .int = > | int | (int .bits + 7 ) / 8 ,
2802
+ .comptime_int = > @compileError ("std.fmt.hex on comptime_int must have a known size" ),
2803
+ else = > @compileError ("type must be an integer" ),
2804
+ });
2805
+
2806
+ return [hex_count ]u8 ;
2807
+ }
2808
+
2809
+ pub const HexOptions = struct {
2810
+ /// Whether octets are ordered little-endian or big-endian
2811
+ endianness : std.builtin.Endian = .big ,
2812
+ case : enum { lower , upper } = .lower ,
2813
+ /// Sign pads the result to the number of octets.
2814
+ /// Required for `comptime_int`.
2815
+ octet_count : ? usize = null ,
2816
+ };
2817
+
2773
2818
test hex {
2819
+ {
2820
+ const x = hex (@as (u48 , 0x1234_5678_abcd ));
2821
+ try std .testing .expect (x .len == 12 );
2822
+ try std .testing .expectEqualStrings ("cdab78563412" , & x );
2823
+ }
2774
2824
{
2775
2825
const x = hex (@as (u32 , 0xdeadbeef ));
2776
2826
try std .testing .expect (x .len == 8 );
@@ -2783,6 +2833,24 @@ test hex {
2783
2833
}
2784
2834
}
2785
2835
2836
+ test hexOptions {
2837
+ {
2838
+ const x = hexOptions (@as (u48 , 0x1234_5678_abcd ), .{ .octet_count = 8 });
2839
+ try std .testing .expect (x .len == 16 );
2840
+ try std .testing .expectEqualStrings ("000012345678abcd" , & x );
2841
+ }
2842
+ {
2843
+ const x = hexOptions (@as (u32 , 0xdeadbeef ), .{ .endianness = .little , .case = .upper });
2844
+ try std .testing .expect (x .len == 8 );
2845
+ try std .testing .expectEqualStrings ("EFBEADDE" , & x );
2846
+ }
2847
+ {
2848
+ const x = hexOptions (-0x3047abed , .{ .octet_count = 8 , .endianness = .little });
2849
+ try std .testing .expect (x .len == 16 );
2850
+ try std .testing .expectEqualStrings ("1354b8cfffffffff" , & x );
2851
+ }
2852
+ }
2853
+
2786
2854
test "parser until" {
2787
2855
{ // return substring till ':'
2788
2856
var parser : Parser = .{
0 commit comments