summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/x64/linux/memory/cmp.S1
-rw-r--r--source/tanya/algorithm/comparison.d61
-rw-r--r--source/tanya/container/array.d1
-rw-r--r--source/tanya/container/list.d3
-rw-r--r--source/tanya/container/string.d2
-rw-r--r--source/tanya/math/mp.d2
-rw-r--r--source/tanya/memory/op.d5
7 files changed, 70 insertions, 5 deletions
diff --git a/arch/x64/linux/memory/cmp.S b/arch/x64/linux/memory/cmp.S
index 169e2eb..64d3ca6 100644
--- a/arch/x64/linux/memory/cmp.S
+++ b/arch/x64/linux/memory/cmp.S
@@ -47,6 +47,7 @@ _D5tanya6memory2op9cmpMemoryFNaNbNixAvxAvZi:
aligned_1: // Compare the remaining bytes
mov %rdx, %rcx
+ cmp $0x0, %rcx
repe cmpsb
jl less
diff --git a/source/tanya/algorithm/comparison.d b/source/tanya/algorithm/comparison.d
index f8e1c60..61dbcf6 100644
--- a/source/tanya/algorithm/comparison.d
+++ b/source/tanya/algorithm/comparison.d
@@ -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[]));
+}
diff --git a/source/tanya/container/array.d b/source/tanya/container/array.d
index 8f34847..59cc3fb 100644
--- a/source/tanya/container/array.d
+++ b/source/tanya/container/array.d
@@ -15,7 +15,6 @@
module tanya.container.array;
import core.checkedint;
-import std.algorithm.comparison : equal;
import std.algorithm.mutation : bringToFront,
copy,
fill,
diff --git a/source/tanya/container/list.d b/source/tanya/container/list.d
index 23467e5..64ea740 100644
--- a/source/tanya/container/list.d
+++ b/source/tanya/container/list.d
@@ -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[]);
}
///
diff --git a/source/tanya/container/string.d b/source/tanya/container/string.d
index 54c0200..ad8fa82 100644
--- a/source/tanya/container/string.d
+++ b/source/tanya/container/string.d
@@ -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;
diff --git a/source/tanya/math/mp.d b/source/tanya/math/mp.d
index b98fbd7..ae365de 100644
--- a/source/tanya/math/mp.d
+++ b/source/tanya/math/mp.d
@@ -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;
diff --git a/source/tanya/memory/op.d b/source/tanya/memory/op.d
index 0a73020..ec9bc2e 100644
--- a/source/tanya/memory/op.d
+++ b/source/tanya/memory/op.d
@@ -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;