const io = @import("./io.zig"); const math = @import("./math.zig"); /// /// [PrintError.WriteFailure] occurs when the underlying [io.Writer] implementation failed to write /// the entirety of a the requested print operation. /// pub const PrintError = error { WriteFailure, }; /// /// Number formatting modes supported by [printInt]. /// pub const Radix = enum { binary, tinary, quaternary, quinary, senary, septenary, octal, nonary, decimal, undecimal, duodecimal, tridecimal, tetradecimal, pentadecimal, hexadecimal, }; /// /// Writes `value` as a ASCII / UTF-8 encoded integer to `writer`, returning `true` if the full /// sequence was successfully written, otherwise `false`. /// /// The `radix` argument identifies which base system to format `value` as. /// pub fn printInt(writer: io.Writer, radix: Radix, value: anytype) PrintError!void { const Int = @TypeOf(value); switch (@typeInfo(Int)) { .Int => |int_info| { if (value == 0) return writer.apply("0"); const base = @enumToInt(radix); const is_signed = (int_info.signedness == .signed); var buffer = [_]u8{0} ** (math.ceil(math.log(math. maxInt(Int), base)) + @boolToInt(is_signed)); var buffer_count: usize = 0; var n1 = value; if (is_signed and (value < 0)) { // Negative value. n1 = -value; buffer[0] = '-'; buffer_count += 1; } while (n1 != 0) { buffer[buffer_count] = @intCast(u8, (n1 % base) + '0'); n1 = (n1 / base); buffer_count += 1; } for (buffer[0 .. (buffer_count / 2)]) |_, i| io.swap(u8, &buffer[i], &buffer[buffer_count - i - 1]); if (writer.call(buffer[0 .. buffer_count]) != buffer_count) return error.WriteFailure; }, // Cast comptime int into known-size integer and try again. .ComptimeInt => return printInt(writer, radix, @intCast(math.IntFittingRange(value, value), value)), else => @compileError("`value` must be of type int or comptime_int"), } } test "Print 64-bit signed integer" { // TODO: implement. }