| ... | @@ -214,6 +214,63 @@ pub fn Writable(T: type, this_kind: enum { _var, _const, _bare }) type { | ... | @@ -214,6 +214,63 @@ pub fn Writable(T: type, this_kind: enum { _var, _const, _bare }) type { |
| 214 | comptime std.debug.assert(@typeInfo(@TypeOf(value)).Struct.layout != .Auto); | 214 | comptime std.debug.assert(@typeInfo(@TypeOf(value)).Struct.layout != .Auto); |
| 215 | return writeAll(self, std.mem.asBytes(&value)); | 215 | return writeAll(self, std.mem.asBytes(&value)); |
| 216 | } | 216 | } |
| | 217 | |
| | 218 | pub fn writeIntPretty(self: Self, value: anytype, base: u8, case: std.fmt.Case) !void { |
| | 219 | std.debug.assert(base >= 2); |
| | 220 | |
| | 221 | const int_value = if (@TypeOf(value) == comptime_int) @as(std.math.IntFittingRange(value, value), value) else value; |
| | 222 | const value_info = @typeInfo(@TypeOf(int_value)).int; |
| | 223 | |
| | 224 | // The type must have the same size as `base` or be wider in order for the division to work |
| | 225 | const min_int_bits = comptime @max(value_info.bits, 8); |
| | 226 | const MinInt = std.meta.Int(.unsigned, min_int_bits); |
| | 227 | |
| | 228 | const abs_value = @abs(int_value); |
| | 229 | // The worst case in terms of space needed is base 2, plus 1 for the sign |
| | 230 | var buf: [1 + @max(@as(comptime_int, value_info.bits), 1)]u8 = undefined; |
| | 231 | |
| | 232 | var a: MinInt = abs_value; |
| | 233 | var index: usize = buf.len; |
| | 234 | |
| | 235 | if (base == 10) { |
| | 236 | while (a >= 100) : (a = @divTrunc(a, 100)) { |
| | 237 | index -= 2; |
| | 238 | buf[index..][0..2].* = std.fmt.digits2(@intCast(a % 100)); |
| | 239 | } |
| | 240 | if (a < 10) { |
| | 241 | index -= 1; |
| | 242 | buf[index] = '0' + @as(u8, @intCast(a)); |
| | 243 | } else { |
| | 244 | index -= 2; |
| | 245 | buf[index..][0..2].* = std.fmt.digits2(@intCast(a)); |
| | 246 | } |
| | 247 | } else { |
| | 248 | while (true) { |
| | 249 | const digit = a % base; |
| | 250 | index -= 1; |
| | 251 | buf[index] = std.fmt.digitToChar(@intCast(digit), case); |
| | 252 | a /= base; |
| | 253 | if (a == 0) break; |
| | 254 | } |
| | 255 | } |
| | 256 | |
| | 257 | if (value_info.signedness == .signed) { |
| | 258 | if (value < 0) { |
| | 259 | // Negative integer |
| | 260 | index -= 1; |
| | 261 | buf[index] = '-'; |
| | 262 | } else if (true) { |
| | 263 | // Positive integer, omit the plus sign |
| | 264 | // if (options.width == null or options.width.? == 0) |
| | 265 | } else { |
| | 266 | // Positive integer |
| | 267 | index -= 1; |
| | 268 | buf[index] = '+'; |
| | 269 | } |
| | 270 | } |
| | 271 | |
| | 272 | return writeAll(self, buf[index..]); |
| | 273 | } |
| 217 | }; | 274 | }; |
| 218 | } | 275 | } |
| 219 | | 276 | |