Implement auto-decoding free equal comparison

Fix #39.
This commit is contained in:
Eugen Wissner 2018-06-12 20:19:06 +02:00
parent 15f7994187
commit a86b6690f0
7 changed files with 70 additions and 5 deletions

View File

@ -47,6 +47,7 @@ _D5tanya6memory2op9cmpMemoryFNaNbNixAvxAvZi:
aligned_1: // Compare the remaining bytes
mov %rdx, %rcx
cmp $0x0, %rcx
repe cmpsb
jl less

View File

@ -16,6 +16,7 @@ module tanya.algorithm.comparison;
import tanya.algorithm.mutation;
import tanya.math : isNaN;
import tanya.memory.op;
import tanya.meta.metafunction;
import tanya.meta.trait;
import tanya.meta.transform;
@ -270,3 +271,63 @@ if (isForwardRange!Range && isOrderingComparable!(ElementType!Range))
assert(max(s2, s3).s == 3);
}
}
/**
* Compares element-wise two ranges for equality.
*
* If the ranges have different lengths, they aren't equal.
*
* Params:
* R1 = First range type.
* R2 = Second range type.
* range1 = First range.
* range2 = Second range.
*
* Returns: $(D_KEYWORD true) if both ranges are equal, $(D_KEYWORD false)
* otherwise.
*/
bool equal(R1, R2)(R1 r1, R2 r2)
if (allSatisfy!(isInputRange, R1, R2) && is(typeof(r1.front == r2.front)))
{
static if (isDynamicArray!R1
&& is(R1 == R2)
&& __traits(isPOD, ElementType!R1))
{
return cmp(r1, r2) == 0;
}
else
{
static if (hasLength!R1 && hasLength!R2)
{
if (r1.length != r2.length)
{
return false;
}
}
for (; !r1.empty && !r2.empty; r1.popFront(), r2.popFront())
{
if (r1.front != r2.front)
{
return false;
}
}
static if (hasLength!R1 && hasLength!R2)
{
return true;
}
else
{
return r1.empty && r2.empty;
}
}
}
///
@nogc nothrow pure @safe unittest
{
int[2] range1 = [1, 2];
assert(equal(range1[], range1[]));
int[3] range2 = [1, 2, 3];
assert(!equal(range1[], range2[]));
}

View File

@ -15,7 +15,6 @@
module tanya.container.array;
import core.checkedint;
import std.algorithm.comparison : equal;
import std.algorithm.mutation : bringToFront,
copy,
fill,

View File

@ -15,7 +15,6 @@
*/
module tanya.container.list;
import std.algorithm.comparison : equal;
import std.algorithm.searching;
import tanya.algorithm.comparison;
import tanya.algorithm.mutation;
@ -574,7 +573,7 @@ struct SList(T)
*/
bool opEquals()(auto ref typeof(this) that) inout
{
return equal(this[], that[]);
return equal(opIndex(), that[]);
}
///

View File

@ -26,7 +26,7 @@
*/
module tanya.container.string;
import std.algorithm.comparison : cmp, equal;
import std.algorithm.comparison : cmp;
import std.algorithm.mutation : bringToFront, copy;
import std.algorithm.searching;
import tanya.algorithm.comparison;

View File

@ -14,7 +14,7 @@
*/
module tanya.math.mp;
import std.algorithm.comparison : cmp, equal;
import std.algorithm.comparison : cmp;
import std.algorithm.mutation : copy, fill, reverse;
import std.range;
import tanya.algorithm.comparison;

View File

@ -40,6 +40,11 @@ version (TanyaNative)
fillMemory(buffer[1 .. $], 0);
assert(buffer[0] == 1 && buffer[1] == 0);
}
@nogc nothrow pure @safe unittest
{
assert(cmp(null, null) == 0);
}
}
private enum alignMask = size_t.sizeof - 1;