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