@@ -940,7 +940,11 @@ public:
940
940
uint [] wasteful = new BigDigit[x.data.length];
941
941
wasteful[] = x.data[];
942
942
immutable rem = multibyteDivAssign(wasteful, y, 0 );
943
- () @trusted { GC .free(wasteful.ptr); } ();
943
+ if (! __ctfe)
944
+ {
945
+ // use free only at runtime
946
+ () @trusted { GC .free(wasteful.ptr); } ();
947
+ }
944
948
return rem;
945
949
}
946
950
}
@@ -1279,6 +1283,13 @@ pure @safe unittest
1279
1283
assert (s == 5 );
1280
1284
}
1281
1285
1286
+ pure @safe unittest
1287
+ { // evaluate mod at compile time
1288
+ enum BigUint r = BigUint([5 ]);
1289
+ enum BigUint t = BigUint([7 ]);
1290
+ enum BigUint s = BigUint.mod(r, t);
1291
+ static assert (s == 5 );
1292
+ }
1282
1293
1283
1294
@safe pure unittest
1284
1295
{
@@ -1725,7 +1736,11 @@ void mulInternal(BigDigit[] result, const(BigDigit)[] x, const(BigDigit)[] y)
1725
1736
mulKaratsuba(result[half .. $], y, x[half .. $], scratchbuff);
1726
1737
BigDigit c = addAssignSimple(result[half .. half + y.length], partial);
1727
1738
if (c) multibyteIncrementAssign! (' +' )(result[half + y.length.. $], c);
1728
- () @trusted { GC .free(scratchbuff.ptr); } ();
1739
+ if (! __ctfe)
1740
+ {
1741
+ // use free only at runtime
1742
+ () @trusted { GC .free(scratchbuff.ptr); } ();
1743
+ }
1729
1744
}
1730
1745
else
1731
1746
{
@@ -1784,15 +1799,23 @@ void mulInternal(BigDigit[] result, const(BigDigit)[] x, const(BigDigit)[] y)
1784
1799
addAssignSimple(result[done .. done + y.length + chunksize], partial);
1785
1800
done += chunksize;
1786
1801
}
1787
- () @trusted { GC .free(scratchbuff.ptr); } ();
1802
+ if (! __ctfe)
1803
+ {
1804
+ // use free only at runtime
1805
+ () @trusted { GC .free(scratchbuff.ptr); } ();
1806
+ }
1788
1807
}
1789
1808
}
1790
1809
else
1791
1810
{
1792
1811
// Balanced. Use Karatsuba directly.
1793
1812
BigDigit [] scratchbuff = new BigDigit[karatsubaRequiredBuffSize(x.length)];
1794
1813
mulKaratsuba(result, x, y, scratchbuff);
1795
- () @trusted { GC .free(scratchbuff.ptr); } ();
1814
+ if (! __ctfe)
1815
+ {
1816
+ // use free only at runtime
1817
+ () @trusted { GC .free(scratchbuff.ptr); } ();
1818
+ }
1796
1819
}
1797
1820
}
1798
1821
@@ -1828,24 +1851,28 @@ void mulInternal(BigDigit[] result, const(BigDigit)[] x, const(BigDigit)[] y)
1828
1851
*/
1829
1852
void squareInternal (BigDigit[] result, const BigDigit[] x) pure nothrow @safe
1830
1853
{
1831
- import core.memory : GC ;
1832
- // Squaring is potentially half a multiply, plus add the squares of
1833
- // the diagonal elements.
1834
- assert (result.length == 2 * x.length,
1835
- " result needs to have twice the capacity of x" );
1836
- if (x.length <= KARATSUBASQUARELIMIT )
1837
- {
1838
- if (x.length == 1 )
1839
- {
1840
- result[1 ] = multibyteMul(result[0 .. 1 ], x, x[0 ], 0 );
1841
- return ;
1842
- }
1843
- return squareSimple (result, x);
1844
- }
1845
- // The nice thing about squaring is that it always stays balanced
1846
- BigDigit [] scratchbuff = new BigDigit[karatsubaRequiredBuffSize(x.length)];
1847
- squareKaratsuba(result, x, scratchbuff);
1848
- () @trusted { GC .free(scratchbuff.ptr); } ();
1854
+ import core.memory : GC ;
1855
+ // Squaring is potentially half a multiply, plus add the squares of
1856
+ // the diagonal elements.
1857
+ assert (result.length == 2 * x.length,
1858
+ " result needs to have twice the capacity of x" );
1859
+ if (x.length <= KARATSUBASQUARELIMIT )
1860
+ {
1861
+ if (x.length == 1 )
1862
+ {
1863
+ result[1 ] = multibyteMul(result[0 .. 1 ], x, x[0 ], 0 );
1864
+ return ;
1865
+ }
1866
+ return squareSimple (result, x);
1867
+ }
1868
+ // The nice thing about squaring is that it always stays balanced
1869
+ BigDigit [] scratchbuff = new BigDigit[karatsubaRequiredBuffSize(x.length)];
1870
+ squareKaratsuba(result, x, scratchbuff);
1871
+ if (! __ctfe)
1872
+ {
1873
+ // use free only at runtime
1874
+ () @trusted { GC .free(scratchbuff.ptr); } ();
1875
+ }
1849
1876
}
1850
1877
1851
1878
@@ -1897,7 +1924,11 @@ void divModInternal(BigDigit [] quotient, BigDigit[] remainder, const BigDigit [
1897
1924
if (s == 0 ) remainder[] = un[0 .. vn.length];
1898
1925
else multibyteShr(remainder, un[0 .. vn.length+ 1 ], s);
1899
1926
}
1900
- () @trusted { GC .free(un.ptr); GC .free(vn.ptr); } ();
1927
+ if (! __ctfe)
1928
+ {
1929
+ // use free only at runtime
1930
+ () @trusted { GC .free(un.ptr); GC .free(vn.ptr); } ();
1931
+ }
1901
1932
}
1902
1933
1903
1934
pure @safe unittest
@@ -2842,7 +2873,11 @@ pure nothrow @safe
2842
2873
m -= v.length;
2843
2874
}
2844
2875
recursiveDivMod(quotient[0 .. m], u[0 .. m + v.length], v, scratch);
2845
- () @trusted { GC .free(scratch.ptr); } ();
2876
+ if (! __ctfe)
2877
+ {
2878
+ // use free only at runtime
2879
+ () @trusted { GC .free(scratch.ptr); } ();
2880
+ }
2846
2881
}
2847
2882
2848
2883
@system unittest
0 commit comments