| ... | ... | @@ -143,12 +143,15 @@ pub const Int = struct { |
| 143 | 143 | /// Clones an Int and returns a new Int with the same value. The new Int is a deep copy and |
| 144 | 144 | /// can be modified separately from the original. |
| 145 | 145 | pub fn clone(other: Int) !Int { |
| 146 | | other.assertWritable(); |
| 146 | return other.clone2(other.allocator.?); |
| 147 | } |
| 148 | |
| 149 | pub fn clone2(other: Int, allocator: *Allocator) !Int { |
| 147 | 150 | return Int{ |
| 148 | | .allocator = other.allocator, |
| 151 | .allocator = allocator, |
| 149 | 152 | .metadata = other.metadata, |
| 150 | 153 | .limbs = block: { |
| 151 | | var limbs = try other.allocator.?.alloc(Limb, other.len()); |
| 154 | var limbs = try allocator.alloc(Limb, other.len()); |
| 152 | 155 | mem.copy(Limb, limbs[0..], other.limbs[0..other.len()]); |
| 153 | 156 | break :block limbs; |
| 154 | 157 | }, |
| ... | ... | @@ -470,8 +473,8 @@ pub const Int = struct { |
| 470 | 473 | break; |
| 471 | 474 | } |
| 472 | 475 | } |
| 473 | | } // Non power-of-two: batch divisions per word size. |
| 474 | | else { |
| 476 | } else { |
| 477 | // Non power-of-two: batch divisions per word size. |
| 475 | 478 | const digits_per_limb = math.log(Limb, base, maxInt(Limb)); |
| 476 | 479 | var limb_base: Limb = 1; |
| 477 | 480 | var j: usize = 0; |
| ... | ... | @@ -479,7 +482,7 @@ pub const Int = struct { |
| 479 | 482 | limb_base *= base; |
| 480 | 483 | } |
| 481 | 484 | |
| 482 | | var q = try self.clone(); |
| 485 | var q = try self.clone2(allocator); |
| 483 | 486 | defer q.deinit(); |
| 484 | 487 | q.abs(); |
| 485 | 488 | var r = try Int.init(allocator); |
| ... | ... | @@ -522,15 +525,13 @@ pub const Int = struct { |
| 522 | 525 | |
| 523 | 526 | /// To allow `std.fmt.printf` to work with Int. |
| 524 | 527 | /// TODO make this non-allocating |
| 528 | /// TODO support read-only fixed integers |
| 525 | 529 | pub fn format( |
| 526 | 530 | self: Int, |
| 527 | 531 | comptime fmt: []const u8, |
| 528 | 532 | options: std.fmt.FormatOptions, |
| 529 | 533 | out_stream: var, |
| 530 | 534 | ) !void { |
| 531 | | self.assertWritable(); |
| 532 | | // TODO support read-only fixed integers |
| 533 | | |
| 534 | 535 | comptime var radix = 10; |
| 535 | 536 | comptime var uppercase = false; |
| 536 | 537 | |
| ... | ... | @@ -550,8 +551,9 @@ pub const Int = struct { |
| 550 | 551 | @compileError("Unknown format string: '" ++ fmt ++ "'"); |
| 551 | 552 | } |
| 552 | 553 | |
| 553 | | const str = self.toString(self.allocator.?, radix, uppercase) catch @panic("TODO make this non allocating"); |
| 554 | | defer self.allocator.?.free(str); |
| 554 | var buf: [4096]u8 = undefined; |
| 555 | var fba = std.heap.FixedBufferAllocator.init(&buf); |
| 556 | const str = self.toString(&fba.allocator, radix, uppercase) catch @panic("TODO make this non allocating"); |
| 555 | 557 | return out_stream.writeAll(str); |
| 556 | 558 | } |
| 557 | 559 | |