Use auto ref for templated overloaded functions
This commit is contained in:
parent
f437dafa6b
commit
061cd6264b
@ -23,7 +23,7 @@ import tanya.memory;
|
|||||||
*/
|
*/
|
||||||
struct Integer
|
struct Integer
|
||||||
{
|
{
|
||||||
private RefCounted!(ubyte[]) rep;
|
private ubyte[] rep;
|
||||||
private bool sign;
|
private bool sign;
|
||||||
private shared Allocator allocator;
|
private shared Allocator allocator;
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ struct Integer
|
|||||||
*
|
*
|
||||||
* Precondition: $(D_INLINECODE allocator !is null)
|
* Precondition: $(D_INLINECODE allocator !is null)
|
||||||
*/
|
*/
|
||||||
this(T)(in T value, shared Allocator allocator = defaultAllocator)
|
this(T)(in auto ref T value, shared Allocator allocator = defaultAllocator)
|
||||||
nothrow @safe @nogc
|
nothrow @safe @nogc
|
||||||
if (isIntegral!T || is(T == Integer))
|
if (isIntegral!T || is(T == Integer))
|
||||||
{
|
{
|
||||||
@ -53,10 +53,10 @@ struct Integer
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rep = RefCounted!(ubyte[])(() @trusted {
|
rep = () @trusted {
|
||||||
return cast(ubyte[]) allocator.allocate(value.length);
|
return cast(ubyte[]) allocator.allocate(value.length);
|
||||||
}(), allocator);
|
}();
|
||||||
value.rep.get.copy(rep.get);
|
value.rep.copy(rep);
|
||||||
sign = value.sign;
|
sign = value.sign;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -85,6 +85,24 @@ struct Integer
|
|||||||
assert(h2.sign);
|
assert(h2.sign);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~this() nothrow @safe @nogc
|
||||||
|
in
|
||||||
|
{
|
||||||
|
assert(allocator !is null || !rep.length);
|
||||||
|
}
|
||||||
|
body
|
||||||
|
{
|
||||||
|
if (allocator !is null)
|
||||||
|
{
|
||||||
|
allocator.dispose(rep);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private @nogc unittest
|
||||||
|
{
|
||||||
|
Integer h; // allocator isn't set, but the destructor should work
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Figures out the minimum amount of space this value will take
|
* Figures out the minimum amount of space this value will take
|
||||||
* up in bytes and resizes the internal storage. Sets the sign.
|
* up in bytes and resizes the internal storage. Sets the sign.
|
||||||
@ -121,13 +139,13 @@ struct Integer
|
|||||||
}
|
}
|
||||||
if (rep.count)
|
if (rep.count)
|
||||||
{
|
{
|
||||||
allocator.resizeArray(rep.get, size);
|
allocator.resizeArray(rep, size);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rep = RefCounted!(ubyte[])(() @trusted {
|
rep = () @trusted {
|
||||||
return cast(ubyte[]) allocator.allocate(size);
|
return cast(ubyte[]) allocator.allocate(size);
|
||||||
}(), allocator);
|
}();
|
||||||
}
|
}
|
||||||
/* Work backward through the int, masking off each byte (up to the
|
/* Work backward through the int, masking off each byte (up to the
|
||||||
first 0 byte) and copy it into the internal representation in
|
first 0 byte) and copy it into the internal representation in
|
||||||
@ -149,33 +167,20 @@ struct Integer
|
|||||||
*
|
*
|
||||||
* Returns: $(D_KEYWORD this).
|
* Returns: $(D_KEYWORD this).
|
||||||
*/
|
*/
|
||||||
ref Integer opAssign(T)(in T value) nothrow @safe @nogc
|
ref Integer opAssign(T)(in auto ref T value) nothrow @safe @nogc
|
||||||
if (isIntegral!T || is(T == Integer))
|
if (isIntegral!T || is(T == Integer))
|
||||||
{
|
{
|
||||||
if (allocator is null)
|
initialize();
|
||||||
{
|
|
||||||
allocator = defaultAllocator;
|
|
||||||
}
|
|
||||||
static if (isIntegral!T)
|
static if (isIntegral!T)
|
||||||
{
|
{
|
||||||
assignInt(value);
|
assignInt(value);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (rep.count)
|
allocator.resizeArray(rep, value.length);
|
||||||
{
|
value.rep.copy(rep);
|
||||||
allocator.resizeArray(rep, value.length);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rep = RefCounted!(ubyte[])(() @trusted {
|
|
||||||
return cast(ubyte[]) allocator.allocate(value.length);
|
|
||||||
}(), allocator);
|
|
||||||
}
|
|
||||||
value.rep.get.copy(rep.get);
|
|
||||||
sign = value.sign;
|
sign = value.sign;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,7 +207,7 @@ struct Integer
|
|||||||
*/
|
*/
|
||||||
@property size_t length() const pure nothrow @safe @nogc
|
@property size_t length() const pure nothrow @safe @nogc
|
||||||
{
|
{
|
||||||
return rep.get.length;
|
return rep.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -216,6 +221,12 @@ struct Integer
|
|||||||
return rep == h.rep;
|
return rep == h.rep;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Ditto.
|
||||||
|
bool opEquals(in ref Integer h) const nothrow @safe @nogc
|
||||||
|
{
|
||||||
|
return rep == h.rep;
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
@ -232,7 +243,7 @@ struct Integer
|
|||||||
* Returns: A positive number if $(D_INLINECODE this > h), a negative
|
* Returns: A positive number if $(D_INLINECODE this > h), a negative
|
||||||
* number if $(D_INLINECODE this > h), `0` otherwise.
|
* number if $(D_INLINECODE this > h), `0` otherwise.
|
||||||
*/
|
*/
|
||||||
int opCmp(in Integer h) const nothrow @safe @nogc
|
int opCmp(in ref Integer h) const nothrow @safe @nogc
|
||||||
{
|
{
|
||||||
if (length > h.length)
|
if (length > h.length)
|
||||||
{
|
{
|
||||||
@ -262,6 +273,12 @@ struct Integer
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Ditto.
|
||||||
|
int opCmp(in Integer h) const nothrow @safe @nogc
|
||||||
|
{
|
||||||
|
return opCmp(h);
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
@ -276,7 +293,7 @@ struct Integer
|
|||||||
assert(h1 > h2);
|
assert(h1 > h2);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void add(in ref RefCounted!(ubyte[]) h) nothrow @safe @nogc
|
private void add(in ref ubyte[] h) nothrow @safe @nogc
|
||||||
{
|
{
|
||||||
uint sum;
|
uint sum;
|
||||||
uint carry = 0;
|
uint carry = 0;
|
||||||
@ -319,7 +336,7 @@ struct Integer
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void subtract(in ref RefCounted!(ubyte[]) h) nothrow @safe @nogc
|
private void subtract(in ref ubyte[] h) nothrow @safe @nogc
|
||||||
{
|
{
|
||||||
auto i = rep.length;
|
auto i = rep.length;
|
||||||
auto j = h.length;
|
auto j = h.length;
|
||||||
@ -350,7 +367,7 @@ struct Integer
|
|||||||
}
|
}
|
||||||
// Go through the representation array and see how many of the
|
// Go through the representation array and see how many of the
|
||||||
// left-most bytes are unused. Remove them and resize the array.
|
// left-most bytes are unused. Remove them and resize the array.
|
||||||
immutable offset = rep.get.countUntil!((const ref a) => a != 0);
|
immutable offset = rep.countUntil!((const ref a) => a != 0);
|
||||||
if (offset > 0)
|
if (offset > 0)
|
||||||
{
|
{
|
||||||
ubyte[] tmp = allocator.makeArray!ubyte(rep.length - offset);
|
ubyte[] tmp = allocator.makeArray!ubyte(rep.length - offset);
|
||||||
@ -372,7 +389,7 @@ struct Integer
|
|||||||
*
|
*
|
||||||
* Returns: $(D_KEYWORD this).
|
* Returns: $(D_KEYWORD this).
|
||||||
*/
|
*/
|
||||||
ref Integer opOpAssign(string op)(in Integer h) nothrow @safe @nogc
|
ref Integer opOpAssign(string op)(in auto ref Integer h) nothrow @safe @nogc
|
||||||
if ((op == "+") || (op == "-"))
|
if ((op == "+") || (op == "-"))
|
||||||
out
|
out
|
||||||
{
|
{
|
||||||
@ -485,7 +502,7 @@ struct Integer
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Ditto.
|
/// Ditto.
|
||||||
ref Integer opOpAssign(string op)(in Integer h) nothrow @safe @nogc
|
ref Integer opOpAssign(string op)(in auto ref Integer h) nothrow @safe @nogc
|
||||||
if (op == "*")
|
if (op == "*")
|
||||||
out
|
out
|
||||||
{
|
{
|
||||||
@ -526,7 +543,7 @@ struct Integer
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Ditto.
|
/// Ditto.
|
||||||
ref Integer opOpAssign(string op)(in Integer h) nothrow @safe @nogc
|
ref Integer opOpAssign(string op)(in auto ref Integer h) nothrow @safe @nogc
|
||||||
if ((op == "/") || (op == "%"))
|
if ((op == "/") || (op == "%"))
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
@ -576,7 +593,8 @@ struct Integer
|
|||||||
|
|
||||||
static if (op == "/")
|
static if (op == "/")
|
||||||
{
|
{
|
||||||
rep = quotient;
|
swap(rep, quotient);
|
||||||
|
allocator.dispose(quotient);
|
||||||
sign = sign == h.sign ? false : true;
|
sign = sign == h.sign ? false : true;
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
@ -607,7 +625,7 @@ struct Integer
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Ditto.
|
/// Ditto.
|
||||||
ref Integer opOpAssign(string op)(in Integer exp) nothrow @safe @nogc
|
ref Integer opOpAssign(string op)(in auto ref Integer exp) nothrow @safe @nogc
|
||||||
if (op == "^^")
|
if (op == "^^")
|
||||||
out
|
out
|
||||||
{
|
{
|
||||||
@ -674,7 +692,7 @@ struct Integer
|
|||||||
}
|
}
|
||||||
else static if (op == "~")
|
else static if (op == "~")
|
||||||
{
|
{
|
||||||
h.rep.get.each!((ref a) => a = ~a);
|
h.rep.each!((ref a) => a = ~a);
|
||||||
}
|
}
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
@ -712,7 +730,7 @@ struct Integer
|
|||||||
|
|
||||||
private void decrement() nothrow @safe @nogc
|
private void decrement() nothrow @safe @nogc
|
||||||
{
|
{
|
||||||
immutable size = rep.get.retro.countUntil!((const ref a) => a != 0);
|
immutable size = rep.retro.countUntil!((const ref a) => a != 0);
|
||||||
if (rep[0] == 1)
|
if (rep[0] == 1)
|
||||||
{
|
{
|
||||||
allocator.resizeArray(rep, rep.length - 1);
|
allocator.resizeArray(rep, rep.length - 1);
|
||||||
@ -728,13 +746,12 @@ struct Integer
|
|||||||
private void increment() nothrow @safe @nogc
|
private void increment() nothrow @safe @nogc
|
||||||
{
|
{
|
||||||
auto size = rep
|
auto size = rep
|
||||||
.get
|
|
||||||
.retro
|
.retro
|
||||||
.countUntil!((const ref a) => a != typeof(rep[0]).max);
|
.countUntil!((const ref a) => a != typeof(rep[0]).max);
|
||||||
if (size == -1)
|
if (size == -1)
|
||||||
{
|
{
|
||||||
size = length;
|
size = length;
|
||||||
allocator.resizeArray(rep.get, rep.length + 1);
|
allocator.resizeArray(rep, rep.length + 1);
|
||||||
rep[0] = 1;
|
rep[0] = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -838,10 +855,6 @@ struct Integer
|
|||||||
{
|
{
|
||||||
allocator = defaultAllocator;
|
allocator = defaultAllocator;
|
||||||
}
|
}
|
||||||
if (!rep.count)
|
|
||||||
{
|
|
||||||
rep = allocator.refCounted!(ubyte[])(0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -901,7 +914,7 @@ struct Integer
|
|||||||
*
|
*
|
||||||
* Returns: An $(D_PSYMBOL Integer) shifted by $(D_PARAM n) bits.
|
* Returns: An $(D_PSYMBOL Integer) shifted by $(D_PARAM n) bits.
|
||||||
*/
|
*/
|
||||||
ref Integer opOpAssign(string op)(in size_t n) nothrow @safe @nogc
|
ref Integer opOpAssign(string op)(in auto ref size_t n) nothrow @safe @nogc
|
||||||
if (op == ">>")
|
if (op == ">>")
|
||||||
out
|
out
|
||||||
{
|
{
|
||||||
@ -978,7 +991,7 @@ struct Integer
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Ditto.
|
/// Ditto.
|
||||||
ref Integer opOpAssign(string op)(in size_t n) nothrow @safe @nogc
|
ref Integer opOpAssign(string op)(in auto ref size_t n) nothrow @safe @nogc
|
||||||
if (op == "<<")
|
if (op == "<<")
|
||||||
out
|
out
|
||||||
{
|
{
|
||||||
@ -1027,7 +1040,7 @@ struct Integer
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Ditto.
|
/// Ditto.
|
||||||
Integer opBinary(string op)(in size_t n) nothrow @safe @nogc
|
Integer opBinary(string op)(in auto ref size_t n) nothrow @safe @nogc
|
||||||
if (op == "<<" || op == ">>" || op == "+" || op == "-" || op == "/"
|
if (op == "<<" || op == ">>" || op == "+" || op == "-" || op == "/"
|
||||||
|| op == "*" || op == "^^" || op == "%")
|
|| op == "*" || op == "^^" || op == "%")
|
||||||
{
|
{
|
||||||
@ -1049,7 +1062,7 @@ struct Integer
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Ditto.
|
/// Ditto.
|
||||||
Integer opBinary(string op)(in Integer h) nothrow @safe @nogc
|
Integer opBinary(string op)(in auto ref Integer h) nothrow @safe @nogc
|
||||||
if (op == "+" || op == "-" || op == "/"
|
if (op == "+" || op == "-" || op == "/"
|
||||||
|| op == "*" || op == "^^" || op == "%")
|
|| op == "*" || op == "^^" || op == "%")
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user