| ... | ... | @@ -214,6 +214,63 @@ pub fn Writable(T: type, this_kind: enum { _var, _const, _bare }) type { |
| 214 | 214 | comptime std.debug.assert(@typeInfo(@TypeOf(value)).Struct.layout != .Auto); |
| 215 | 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 | |