| ... | @@ -2158,15 +2158,27 @@ pub const Managed = struct { | ... | @@ -2158,15 +2158,27 @@ pub const Managed = struct { |
| 2158 | r.setMetadata(m.positive, m.len); | 2158 | r.setMetadata(m.positive, m.len); |
| 2159 | } | 2159 | } |
| 2160 | | 2160 | |
| | 2161 | /// r = a + b with 2s-complement wrapping semantics. |
| | 2162 | /// |
| | 2163 | /// r, a and b may be aliases. If r aliases a or b, then caller must call |
| | 2164 | /// `r.ensureTwosCompCapacity` prior to calling `add`. |
| | 2165 | /// |
| | 2166 | /// Returns an error if memory could not be allocated. |
| 2161 | pub fn addWrap(r: *Managed, a: Const, b: Const, signedness: std.builtin.Signedness, bit_count: usize) Allocator.Error!void { | 2167 | pub fn addWrap(r: *Managed, a: Const, b: Const, signedness: std.builtin.Signedness, bit_count: usize) Allocator.Error!void { |
| 2162 | try r.ensureCapacity(calcTwosCompLimbCount(bit_count)); | 2168 | try r.ensureTwosCompCapacity(bit_count); |
| 2163 | var m = r.toMutable(); | 2169 | var m = r.toMutable(); |
| 2164 | m.addWrap(a, b, signedness, bit_count); | 2170 | m.addWrap(a, b, signedness, bit_count); |
| 2165 | r.setMetadata(m.positive, m.len); | 2171 | r.setMetadata(m.positive, m.len); |
| 2166 | } | 2172 | } |
| 2167 | | 2173 | |
| | 2174 | /// r = a + b with 2s-complement saturating semantics. |
| | 2175 | /// |
| | 2176 | /// r, a and b may be aliases. If r aliases a or b, then caller must call |
| | 2177 | /// `r.ensureTwosCompCapacity` prior to calling `add`. |
| | 2178 | /// |
| | 2179 | /// Returns an error if memory could not be allocated. |
| 2168 | pub fn addSat(r: *Managed, a: Const, b: Const, signedness: std.builtin.Signedness, bit_count: usize) Allocator.Error!void { | 2180 | pub fn addSat(r: *Managed, a: Const, b: Const, signedness: std.builtin.Signedness, bit_count: usize) Allocator.Error!void { |
| 2169 | try r.ensureCapacity(calcTwosCompLimbCount(bit_count)); | 2181 | try r.ensureTwosCompCapacity(bit_count); |
| 2170 | var m = r.toMutable(); | 2182 | var m = r.toMutable(); |
| 2171 | m.addSat(a, b, signedness, bit_count); | 2183 | m.addSat(a, b, signedness, bit_count); |
| 2172 | r.setMetadata(m.positive, m.len); | 2184 | r.setMetadata(m.positive, m.len); |
| ... | @@ -2184,15 +2196,27 @@ pub const Managed = struct { | ... | @@ -2184,15 +2196,27 @@ pub const Managed = struct { |
| 2184 | r.setMetadata(m.positive, m.len); | 2196 | r.setMetadata(m.positive, m.len); |
| 2185 | } | 2197 | } |
| 2186 | | 2198 | |
| | 2199 | /// r = a - b with 2s-complement wrapping semantics. |
| | 2200 | /// |
| | 2201 | /// r, a and b may be aliases. If r aliases a or b, then caller must call |
| | 2202 | /// `r.ensureTwosCompCapacity` prior to calling `add`. |
| | 2203 | /// |
| | 2204 | /// Returns an error if memory could not be allocated. |
| 2187 | pub fn subWrap(r: *Managed, a: Const, b: Const, signedness: std.builtin.Signedness, bit_count: usize) Allocator.Error!void { | 2205 | pub fn subWrap(r: *Managed, a: Const, b: Const, signedness: std.builtin.Signedness, bit_count: usize) Allocator.Error!void { |
| 2188 | try r.ensureCapacity(calcTwosCompLimbCount(bit_count)); | 2206 | try r.ensureTwosCompCapacity(bit_count); |
| 2189 | var m = r.toMutable(); | 2207 | var m = r.toMutable(); |
| 2190 | m.subWrap(a, b, signedness, bit_count); | 2208 | m.subWrap(a, b, signedness, bit_count); |
| 2191 | r.setMetadata(m.positive, m.len); | 2209 | r.setMetadata(m.positive, m.len); |
| 2192 | } | 2210 | } |
| 2193 | | 2211 | |
| | 2212 | /// r = a - b with 2s-complement saturating semantics. |
| | 2213 | /// |
| | 2214 | /// r, a and b may be aliases. If r aliases a or b, then caller must call |
| | 2215 | /// `r.ensureTwosCompCapacity` prior to calling `add`. |
| | 2216 | /// |
| | 2217 | /// Returns an error if memory could not be allocated. |
| 2194 | pub fn subSat(r: *Managed, a: Const, b: Const, signedness: std.builtin.Signedness, bit_count: usize) Allocator.Error!void { | 2218 | pub fn subSat(r: *Managed, a: Const, b: Const, signedness: std.builtin.Signedness, bit_count: usize) Allocator.Error!void { |
| 2195 | try r.ensureCapacity(calcTwosCompLimbCount(bit_count)); | 2219 | try r.ensureTwosCompCapacity(bit_count); |
| 2196 | var m = r.toMutable(); | 2220 | var m = r.toMutable(); |
| 2197 | m.subSat(a, b, signedness, bit_count); | 2221 | m.subSat(a, b, signedness, bit_count); |
| 2198 | r.setMetadata(m.positive, m.len); | 2222 | r.setMetadata(m.positive, m.len); |
| ... | @@ -2229,7 +2253,7 @@ pub const Managed = struct { | ... | @@ -2229,7 +2253,7 @@ pub const Managed = struct { |
| 2229 | /// rma = a * b with 2s-complement wrapping semantics. | 2253 | /// rma = a * b with 2s-complement wrapping semantics. |
| 2230 | /// | 2254 | /// |
| 2231 | /// rma, a and b may be aliases. However, it is more efficient if rma does not alias a or b. | 2255 | /// rma, a and b may be aliases. However, it is more efficient if rma does not alias a or b. |
| 2232 | /// If rma aliases a or b, then caller must call `rma.ensureCapacity(calcTwosCompLimbCount(bit_count))` | 2256 | /// If rma aliases a or b, then caller must call `ensureTwosCompCapacity` |
| 2233 | /// prior to calling `mul`. | 2257 | /// prior to calling `mul`. |
| 2234 | /// | 2258 | /// |
| 2235 | /// Returns an error if memory could not be allocated. | 2259 | /// Returns an error if memory could not be allocated. |
| ... | @@ -2242,7 +2266,7 @@ pub const Managed = struct { | ... | @@ -2242,7 +2266,7 @@ pub const Managed = struct { |
| 2242 | if (rma.limbs.ptr == b.limbs.ptr) | 2266 | if (rma.limbs.ptr == b.limbs.ptr) |
| 2243 | alias_count += 1; | 2267 | alias_count += 1; |
| 2244 | | 2268 | |
| 2245 | try rma.ensureCapacity(calcTwosCompLimbCount(bit_count)); | 2269 | try rma.ensureTwosCompCapacity(bit_count); |
| 2246 | var m = rma.toMutable(); | 2270 | var m = rma.toMutable(); |
| 2247 | if (alias_count == 0) { | 2271 | if (alias_count == 0) { |
| 2248 | m.mulWrapNoAlias(a, b, signedness, bit_count, rma.allocator); | 2272 | m.mulWrapNoAlias(a, b, signedness, bit_count, rma.allocator); |
| ... | @@ -2255,6 +2279,10 @@ pub const Managed = struct { | ... | @@ -2255,6 +2279,10 @@ pub const Managed = struct { |
| 2255 | rma.setMetadata(m.positive, m.len); | 2279 | rma.setMetadata(m.positive, m.len); |
| 2256 | } | 2280 | } |
| 2257 | | 2281 | |
| | 2282 | pub fn ensureTwosCompCapacity(r: *Managed, bit_count: usize) !void { |
| | 2283 | try r.ensureCapacity(calcTwosCompLimbCount(bit_count)); |
| | 2284 | } |
| | 2285 | |
| 2258 | pub fn ensureAddScalarCapacity(r: *Managed, a: Const, scalar: anytype) !void { | 2286 | pub fn ensureAddScalarCapacity(r: *Managed, a: Const, scalar: anytype) !void { |
| 2259 | try r.ensureCapacity(math.max(a.limbs.len, calcLimbLen(scalar)) + 1); | 2287 | try r.ensureCapacity(math.max(a.limbs.len, calcLimbLen(scalar)) + 1); |
| 2260 | } | 2288 | } |