| ... | @@ -316,7 +316,9 @@ pub const Mutable = struct { | ... | @@ -316,7 +316,9 @@ pub const Mutable = struct { |
| 316 | } | 316 | } |
| 317 | | 317 | |
| 318 | if (a.limbs.len == 1 and b.limbs.len == 1 and a.positive == b.positive) { | 318 | if (a.limbs.len == 1 and b.limbs.len == 1 and a.positive == b.positive) { |
| 319 | if (!@addWithOverflow(Limb, a.limbs[0], b.limbs[0], &r.limbs[0])) { | 319 | var o: Limb = undefined; |
| | 320 | if (!@addWithOverflow(Limb, a.limbs[0], b.limbs[0], &o)) { |
| | 321 | r.limbs[0] = o; |
| 320 | r.len = 1; | 322 | r.len = 1; |
| 321 | r.positive = a.positive; | 323 | r.positive = a.positive; |
| 322 | return; | 324 | return; |
| ... | @@ -333,10 +335,10 @@ pub const Mutable = struct { | ... | @@ -333,10 +335,10 @@ pub const Mutable = struct { |
| 333 | } | 335 | } |
| 334 | } else { | 336 | } else { |
| 335 | if (a.limbs.len >= b.limbs.len) { | 337 | if (a.limbs.len >= b.limbs.len) { |
| 336 | lladd(r.limbs[0..], a.limbs[0..a.limbs.len], b.limbs[0..b.limbs.len]); | 338 | lladd(r.limbs[0..], a.limbs, b.limbs); |
| 337 | r.normalize(a.limbs.len + 1); | 339 | r.normalize(a.limbs.len + 1); |
| 338 | } else { | 340 | } else { |
| 339 | lladd(r.limbs[0..], b.limbs[0..b.limbs.len], a.limbs[0..a.limbs.len]); | 341 | lladd(r.limbs[0..], b.limbs, a.limbs); |
| 340 | r.normalize(b.limbs.len + 1); | 342 | r.normalize(b.limbs.len + 1); |
| 341 | } | 343 | } |
| 342 | | 344 | |
| ... | @@ -1683,12 +1685,14 @@ pub const Managed = struct { | ... | @@ -1683,12 +1685,14 @@ pub const Managed = struct { |
| 1683 | | 1685 | |
| 1684 | /// r = a + scalar | 1686 | /// r = a + scalar |
| 1685 | /// | 1687 | /// |
| 1686 | /// r and a may be aliases. | 1688 | /// r and a may be aliases. If r aliases a, then caller must call |
| | 1689 | /// `r.ensureAddScalarCapacity` prior to calling `add`. |
| 1687 | /// scalar is a primitive integer type. | 1690 | /// scalar is a primitive integer type. |
| 1688 | /// | 1691 | /// |
| 1689 | /// Returns an error if memory could not be allocated. | 1692 | /// Returns an error if memory could not be allocated. |
| 1690 | pub fn addScalar(r: *Managed, a: Const, scalar: anytype) Allocator.Error!void { | 1693 | pub fn addScalar(r: *Managed, a: Const, scalar: anytype) Allocator.Error!void { |
| 1691 | try r.ensureCapacity(math.max(a.limbs.len, calcLimbLen(scalar)) + 1); | 1694 | assert((r.limbs.ptr != a.limbs.ptr) or r.limbs.len >= math.max(a.limbs.len, calcLimbLen(scalar)) + 1); |
| | 1695 | try r.ensureAddScalarCapacity(a, scalar); |
| 1692 | var m = r.toMutable(); | 1696 | var m = r.toMutable(); |
| 1693 | m.addScalar(a, scalar); | 1697 | m.addScalar(a, scalar); |
| 1694 | r.setMetadata(m.positive, m.len); | 1698 | r.setMetadata(m.positive, m.len); |
| ... | @@ -1696,11 +1700,13 @@ pub const Managed = struct { | ... | @@ -1696,11 +1700,13 @@ pub const Managed = struct { |
| 1696 | | 1700 | |
| 1697 | /// r = a + b | 1701 | /// r = a + b |
| 1698 | /// | 1702 | /// |
| 1699 | /// r, a and b may be aliases. | 1703 | /// r, a and b may be aliases. If r aliases a or b, then caller must call |
| | 1704 | /// `r.ensureAddCapacity` prior to calling `add`. |
| 1700 | /// | 1705 | /// |
| 1701 | /// Returns an error if memory could not be allocated. | 1706 | /// Returns an error if memory could not be allocated. |
| 1702 | pub fn add(r: *Managed, a: Const, b: Const) Allocator.Error!void { | 1707 | pub fn add(r: *Managed, a: Const, b: Const) Allocator.Error!void { |
| 1703 | try r.ensureCapacity(math.max(a.limbs.len, b.limbs.len) + 1); | 1708 | assert((r.limbs.ptr != a.limbs.ptr and r.limbs.ptr != b.limbs.ptr) or r.limbs.len >= math.max(a.limbs.len, b.limbs.len) + 1); |
| | 1709 | try r.ensureAddCapacity(a, b); |
| 1704 | var m = r.toMutable(); | 1710 | var m = r.toMutable(); |
| 1705 | m.add(a, b); | 1711 | m.add(a, b); |
| 1706 | r.setMetadata(m.positive, m.len); | 1712 | r.setMetadata(m.positive, m.len); |
| ... | @@ -1746,6 +1752,14 @@ pub const Managed = struct { | ... | @@ -1746,6 +1752,14 @@ pub const Managed = struct { |
| 1746 | rma.setMetadata(m.positive, m.len); | 1752 | rma.setMetadata(m.positive, m.len); |
| 1747 | } | 1753 | } |
| 1748 | | 1754 | |
| | 1755 | pub fn ensureAddScalarCapacity(r: *Managed, a: Const, scalar: anytype) !void { |
| | 1756 | try r.ensureCapacity(math.max(a.limbs.len, calcLimbLen(scalar)) + 1); |
| | 1757 | } |
| | 1758 | |
| | 1759 | pub fn ensureAddCapacity(r: *Managed, a: Const, b: Const) !void { |
| | 1760 | try r.ensureCapacity(math.max(a.limbs.len, b.limbs.len) + 1); |
| | 1761 | } |
| | 1762 | |
| 1749 | pub fn ensureMulCapacity(rma: *Managed, a: Const, b: Const) !void { | 1763 | pub fn ensureMulCapacity(rma: *Managed, a: Const, b: Const) !void { |
| 1750 | try rma.ensureCapacity(a.limbs.len + b.limbs.len + 1); | 1764 | try rma.ensureCapacity(a.limbs.len + b.limbs.len + 1); |
| 1751 | } | 1765 | } |