1 /++ Algorithms that either improve or complement std.algorithm.comparison.` 2 +/ 3 module nxt.algorithm.comparison; 4 5 // version = unittestAsBetterC; // Run_As: dmd -betterC -unittest -run $(__FILE__).d 6 7 import std.range.primitives : isInputRange, isInfinite, ElementType; 8 9 // Use until `std.algorithm.comparison.equal` supports uncopyable parameters. 10 bool equal(T, U)(scope T a, scope U b) 11 if (!(isInfinite!T && 12 isInfinite!U)) { 13 static if ((is(T == TE[M], TE, size_t M)) && 14 (is(U == UE[N], UE, size_t N)) && 15 is(typeof(TE.init == UE.init) : bool)) /+ static array +/ { 16 static if (M != N) 17 return false; 18 else { 19 foreach (const i; 0 .. M) 20 if (a[i] != b[i]) 21 return false; 22 return true; 23 } 24 } else static if ((is(T == TA[], TA)) && 25 (is(U == UA[], UA)) && 26 is(typeof(TA.init == UA.init) : bool)) /+ dynamic array +/ { 27 if (a.length != b.length) 28 return false; 29 const N = a.length; 30 foreach (const i; 0 .. N) 31 if (a[i] != b[i]) 32 return false; 33 return true; 34 } else static if (is(typeof(ElementType!T.init == ElementType!U.init) : bool)) { 35 static if (is(typeof(a[size_t.init]))) { 36 import std.algorithm.mutation : move; 37 size_t i = 0; 38 foreach (const ref be; move(b)) 39 if (a[i++] != be) 40 return false; 41 return true; 42 } else static if (is(typeof(b[size_t.init]))) { 43 import std.algorithm.mutation : move; 44 size_t i = 0; 45 foreach (const ref ae; move(a)) 46 if (ae != b[i++]) 47 return false; 48 return true; 49 } else { 50 while (true) { 51 if (a.empty()) 52 return b.empty(); 53 if (b.empty()) 54 return a.empty(); 55 if (a.front != b.front) 56 return false; 57 a.popFront(); 58 b.popFront(); 59 } 60 } 61 } else 62 static assert(0, "Cannot compare " ~ T.stringof ~ "with" ~ U.stringof); 63 } 64 /// ditto 65 bool equal(T, U)(scope const(T)[] a, scope const(U)[] b) 66 if (is(typeof(T.init == U.init) : bool)) { 67 } 68 69 /// dynamic arrays 70 pure nothrow @safe @nogc unittest { 71 assert(!equal([1, 2 ].s[], [1, 2, 3].s[])); 72 assert(!equal([1, 2, 3].s[], [1, 2, ].s[])); 73 assert( equal([1, 2, 3].s[], [1, 2, 3].s[])); 74 } 75 76 /// static arrays 77 pure nothrow @safe @nogc unittest { 78 assert(!equal([1, 2 ].s, [1, 2, 3].s)); 79 assert(!equal([1, 2, 3].s, [1, 2, ].s)); 80 assert( equal([1, 2, 3].s, [1, 2, 3].s)); 81 } 82 83 version (unittest) { 84 import nxt.array_help : s; 85 } 86 87 // See_Also: https://dlang.org/spec/betterc.html#unittests 88 version (unittestAsBetterC) 89 extern(C) void main() { 90 static foreach (u; __traits(getUnitTests, __traits(parent, main))) { 91 u(); 92 } 93 }