diff options
| author | Eugen Wissner <belka@caraus.de> | 2018-10-02 08:55:29 +0200 |
|---|---|---|
| committer | Eugen Wissner <belka@caraus.de> | 2018-10-02 08:55:29 +0200 |
| commit | 772e87739c848a10a014d3118ff14bd0ca48b2d0 (patch) | |
| tree | b567a3c6fb03d45fb7048632bdb66501e42e65d8 /source | |
| parent | 2a90a812db53728d29a3a821cb292c032437d806 (diff) | |
| download | tanya-772e87739c848a10a014d3118ff14bd0ca48b2d0.tar.gz | |
Replace memory.op.cmp with optimized equal version
Deprecate cmp.
Fix #68.
Diffstat (limited to 'source')
| -rw-r--r-- | source/tanya/algorithm/comparison.d | 6 | ||||
| -rw-r--r-- | source/tanya/format.d | 18 | ||||
| -rw-r--r-- | source/tanya/memory/op.d | 136 |
3 files changed, 91 insertions, 69 deletions
diff --git a/source/tanya/algorithm/comparison.d b/source/tanya/algorithm/comparison.d index 88f6860..904f045 100644 --- a/source/tanya/algorithm/comparison.d +++ b/source/tanya/algorithm/comparison.d @@ -15,8 +15,8 @@ module tanya.algorithm.comparison; import tanya.algorithm.mutation; -import tanya.math : isNaN; -import tanya.memory.op; +import tanya.math; +static import tanya.memory.op; import tanya.meta.metafunction; import tanya.meta.trait; import tanya.meta.transform; @@ -296,7 +296,7 @@ if (allSatisfy!(isInputRange, R1, R2) && is(R1 == R2) && __traits(isPOD, ElementType!R1)) { - return cmp(r1, r2) == 0; + return tanya.memory.op.equal(r1, r2); } else { diff --git a/source/tanya/format.d b/source/tanya/format.d index 2a30822..fa46945 100644 --- a/source/tanya/format.d +++ b/source/tanya/format.d @@ -43,7 +43,7 @@ import tanya.algorithm.comparison; import tanya.container.string; import tanya.encoding.ascii; import tanya.math; -import tanya.memory.op; +static import tanya.memory.op; import tanya.meta.metafunction; import tanya.meta.trait; import tanya.meta.transform; @@ -1351,7 +1351,7 @@ do intSlice.popBack(); } const begin = buffer.length - intSlice.length; - copy(intSlice, buffer[begin .. $]); + tanya.memory.op.copy(intSlice, buffer[begin .. $]); exponent = cast(int) (intSlice.length + mismatch); @@ -1388,7 +1388,7 @@ do char[21] intBuffer; auto intSlice = integral2String(decimal, intBuffer); - copy(intSlice, buffer); + tanya.memory.op.copy(intSlice, buffer); exponent = cast(int) intSlice.length; size_t position = exponent; @@ -1903,7 +1903,7 @@ private char[] errol3(double value, if (pathologies[middle].representation == bits.integral) { exponent = pathologies[middle].exponent; - copy(pathologies[middle].digits, buffer); + tanya.memory.op.copy(pathologies[middle].digits, buffer); return buffer[0 .. pathologies[middle].digits.length]; } else if (pathologies[middle].representation < bits.integral) @@ -2054,7 +2054,7 @@ if (isFloatingPoint!T) { length = precision + 1; } - realString[1 .. length].copy(bufferSlice); + tanya.memory.op.copy(realString[1 .. length], bufferSlice); bufferSlice.popFrontExactly(length - 1); // Dump the exponent. @@ -2116,7 +2116,7 @@ if (isFloatingPoint!T) n = precision; } - fill!'0'(bufferSlice[0 .. n]); + tanya.memory.op.fill!'0'(bufferSlice[0 .. n]); bufferSlice.popFrontExactly(n); if ((length + n) > precision) @@ -2124,7 +2124,7 @@ if (isFloatingPoint!T) length = precision - n; } - realString[0 .. length].copy(bufferSlice); + tanya.memory.op.copy(realString[0 .. length], bufferSlice); bufferSlice.popFrontExactly(length); } else if (cast(uint) decimalPoint >= length) @@ -2142,7 +2142,7 @@ if (isFloatingPoint!T) { n = decimalPoint - n; - fill!'0'(bufferSlice[0 .. n]); + tanya.memory.op.fill!'0'(bufferSlice[0 .. n]); bufferSlice.popFrontExactly(n); } if (precision != 0) @@ -2173,7 +2173,7 @@ if (isFloatingPoint!T) length = precision + decimalPoint; } - realString[n .. length].copy(bufferSlice); + tanya.memory.op.copy(realString[n .. length], bufferSlice); bufferSlice.popFrontExactly(length - n); } } diff --git a/source/tanya/memory/op.d b/source/tanya/memory/op.d index 8e56c80..b411ed7 100644 --- a/source/tanya/memory/op.d +++ b/source/tanya/memory/op.d @@ -24,7 +24,7 @@ version (TanyaNative) extern private void moveMemory(const void[], void[]) pure nothrow @system @nogc; - extern private int cmpMemory(const void[], const void[]) + extern private bool equalMemory(const void[], const void[]) pure nothrow @system @nogc; } else @@ -43,7 +43,7 @@ version (TanyaNative) @nogc nothrow pure @safe unittest { - assert(cmp(null, null) == 0); + assert(equal(null, null)); } } @@ -91,7 +91,7 @@ do ubyte[9] source = [1, 2, 3, 4, 5, 6, 7, 8, 9]; ubyte[9] target; source.copy(target); - assert(cmp(source, target) == 0); + assert(equal(source, target)); } @nogc nothrow pure @safe unittest @@ -110,7 +110,7 @@ do ubyte[8] source = [1, 2, 3, 4, 5, 6, 7, 8]; ubyte[8] target; source.copy(target); - assert(cmp(source, target) == 0); + assert(equal(source, target)); } } @@ -212,7 +212,7 @@ do ubyte[6] expected = [ 'a', 'a', 'a', 'a', 'b', 'b' ]; copyBackward(mem[0 .. 4], mem[2 .. $]); - assert(cmp(expected, mem) == 0); + assert(equal(expected, mem)); } @nogc nothrow pure @safe unittest @@ -221,7 +221,7 @@ do ubyte[9] r2; copyBackward(r1, r2); - assert(cmp(r1, r2) == 0); + assert(equal(r1, r2)); } /** @@ -241,6 +241,7 @@ do * negative integer if $(D_INLINECODE r2 > r1), * `0` if $(D_INLINECODE r1 == r2). */ +deprecated("Use tanya.memory.op.equal() or tanya.algorithm.comparison.compare() instead") int cmp(const void[] r1, const void[] r2) @nogc nothrow pure @trusted in { @@ -249,48 +250,13 @@ in } do { - version (TanyaNative) + import core.stdc.string : memcmp; + + if (r1.length > r2.length) { - return cmpMemory(r1, r2); - } - else - { - if (r1.length > r2.length) - { - return 1; - } - return r1.length < r2.length ? -1 : memcmp(r1.ptr, r2.ptr, r1.length); + return 1; } -} - -/// -@nogc nothrow pure @safe unittest -{ - ubyte[4] r1 = [ 'a', 'b', 'c', 'd' ]; - ubyte[3] r2 = [ 'c', 'a', 'b' ]; - - assert(cmp(r1[0 .. 3], r2[]) < 0); - assert(cmp(r2[], r1[0 .. 3]) > 0); - - assert(cmp(r1, r2) > 0); - assert(cmp(r2, r1) < 0); -} - -@nogc nothrow pure @safe unittest -{ - ubyte[16] r1 = [ - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', - 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', - ]; - ubyte[16] r2 = [ - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', - 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', - ]; - - assert(cmp(r1, r2) == 0); - assert(cmp(r1[1 .. $], r2[1 .. $]) == 0); - assert(cmp(r1[0 .. $ - 1], r2[0 .. $ - 1]) == 0); - assert(cmp(r1[0 .. 8], r2[0 .. 8]) == 0); + return r1.length < r2.length ? -1 : memcmp(r1.ptr, r2.ptr, r1.length); } /** @@ -362,13 +328,13 @@ do { const ubyte[9] haystack = ['a', 'b', 'c', 'd', 'e', 'f', 'b', 'g', 'h']; - assert(cmp(find(haystack, 'a'), haystack[]) == 0); - assert(cmp(find(haystack, 'b'), haystack[1 .. $]) == 0); - assert(cmp(find(haystack, 'c'), haystack[2 .. $]) == 0); - assert(cmp(find(haystack, 'd'), haystack[3 .. $]) == 0); - assert(cmp(find(haystack, 'e'), haystack[4 .. $]) == 0); - assert(cmp(find(haystack, 'f'), haystack[5 .. $]) == 0); - assert(cmp(find(haystack, 'h'), haystack[8 .. $]) == 0); + assert(equal(find(haystack, 'a'), haystack[])); + assert(equal(find(haystack, 'b'), haystack[1 .. $])); + assert(equal(find(haystack, 'c'), haystack[2 .. $])); + assert(equal(find(haystack, 'd'), haystack[3 .. $])); + assert(equal(find(haystack, 'e'), haystack[4 .. $])); + assert(equal(find(haystack, 'f'), haystack[5 .. $])); + assert(equal(find(haystack, 'h'), haystack[8 .. $])); assert(find(haystack, 'i').length == 0); assert(find(null, 'a').length == 0); @@ -441,10 +407,66 @@ do /// @nogc nothrow pure @safe unittest { - assert(cmp(findNullTerminated("abcdef\0gh"), "abcdef") == 0); - assert(cmp(findNullTerminated("\0garbage"), "") == 0); - assert(cmp(findNullTerminated("\0"), "") == 0); - assert(cmp(findNullTerminated("cstring\0"), "cstring") == 0); + assert(equal(findNullTerminated("abcdef\0gh"), "abcdef")); + assert(equal(findNullTerminated("\0garbage"), "")); + assert(equal(findNullTerminated("\0"), "")); + assert(equal(findNullTerminated("cstring\0"), "cstring")); assert(findNullTerminated(null) is null); assert(findNullTerminated("abcdef") is null); } + +/** + * Compares two memory areas $(D_PARAM r1) and $(D_PARAM r2) for equality. + * + * Params: + * haystack = First memory block. + * needle = First memory block. + * + * Returns: $(D_KEYWORD true) if $(D_PARAM r1) and $(D_PARAM r2) are equal, + * $(D_KEYWORD false) otherwise. + */ +bool equal(const void[] r1, const void[] r2) @nogc nothrow pure @trusted +in +{ + assert(r1.length == 0 || r1.ptr !is null); + assert(r2.length == 0 || r2.ptr !is null); +} +do +{ + version (TanyaNative) + { + return equalMemory(r1, r2); + } + else + { + return r1.length == r2.length + && memcmp(r1.ptr, r2.ptr, r1.length) == 0; + } +} + +/// +@nogc nothrow pure @safe unittest +{ + assert(equal("asdf", "asdf")); + assert(!equal("asd", "asdf")); + assert(!equal("asdf", "asd")); + assert(!equal("asdf", "qwer")); +} + +// Compares unanligned memory +@nogc nothrow pure @safe unittest +{ + ubyte[16] r1 = [ + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', + 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', + ]; + ubyte[16] r2 = [ + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', + 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', + ]; + + assert(equal(r1, r2)); + assert(equal(r1[1 .. $], r2[1 .. $])); + assert(equal(r1[0 .. $ - 1], r2[0 .. $ - 1])); + assert(equal(r1[0 .. 8], r2[0 .. 8])); +} |
