Merge pull request #5147 from wilzbach/static_if_std_algorithm_comparison

[Static if] Replace overload constraints with static if (comparison.d)
merged-on-behalf-of: Sebastian Wilzbach <sebi.wilzbach@gmail.com>
This commit is contained in:
The Dlang Bot 2017-11-20 16:41:02 +01:00 committed by GitHub
commit d15447fb44
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -606,85 +606,85 @@ Returns:
*/ */
int cmp(alias pred = "a < b", R1, R2)(R1 r1, R2 r2) int cmp(alias pred = "a < b", R1, R2)(R1 r1, R2 r2)
if (isInputRange!R1 && isInputRange!R2 && !(isSomeString!R1 && isSomeString!R2)) if (isInputRange!R1 && isInputRange!R2)
{ {
for (;; r1.popFront(), r2.popFront()) static if (!(isSomeString!R1 && isSomeString!R2))
{ {
if (r1.empty) return -cast(int)!r2.empty; for (;; r1.popFront(), r2.popFront())
if (r2.empty) return !r1.empty;
auto a = r1.front, b = r2.front;
if (binaryFun!pred(a, b)) return -1;
if (binaryFun!pred(b, a)) return 1;
}
}
/// ditto
int cmp(alias pred = "a < b", R1, R2)(R1 r1, R2 r2)
if (isSomeString!R1 && isSomeString!R2)
{
import core.stdc.string : memcmp;
import std.utf : decode;
static if (is(typeof(pred) : string))
enum isLessThan = pred == "a < b";
else
enum isLessThan = false;
// For speed only
static int threeWay(size_t a, size_t b)
{
static if (size_t.sizeof == int.sizeof && isLessThan)
return a - b;
else
return binaryFun!pred(b, a) ? 1 : binaryFun!pred(a, b) ? -1 : 0;
}
// For speed only
// @@@BUG@@@ overloading should be allowed for nested functions
static int threeWayInt(int a, int b)
{
static if (isLessThan)
return a - b;
else
return binaryFun!pred(b, a) ? 1 : binaryFun!pred(a, b) ? -1 : 0;
}
static if (typeof(r1[0]).sizeof == typeof(r2[0]).sizeof && isLessThan)
{
static if (typeof(r1[0]).sizeof == 1)
{ {
immutable len = min(r1.length, r2.length); if (r1.empty) return -cast(int)!r2.empty;
immutable result = __ctfe ? if (r2.empty) return !r1.empty;
{ auto a = r1.front, b = r2.front;
foreach (i; 0 .. len) if (binaryFun!pred(a, b)) return -1;
{ if (binaryFun!pred(b, a)) return 1;
if (r1[i] != r2[i])
return threeWayInt(r1[i], r2[i]);
}
return 0;
}()
: () @trusted { return memcmp(r1.ptr, r2.ptr, len); }();
if (result) return result;
} }
}
else
{
import core.stdc.string : memcmp;
import std.utf : decode;
static if (is(typeof(pred) : string))
enum isLessThan = pred == "a < b";
else else
enum isLessThan = false;
// For speed only
static int threeWay(size_t a, size_t b)
{ {
auto p1 = r1.ptr, p2 = r2.ptr, static if (size_t.sizeof == int.sizeof && isLessThan)
pEnd = p1 + min(r1.length, r2.length); return a - b;
for (; p1 != pEnd; ++p1, ++p2) else
return binaryFun!pred(b, a) ? 1 : binaryFun!pred(a, b) ? -1 : 0;
}
// For speed only
// @@@BUG@@@ overloading should be allowed for nested functions
static int threeWayInt(int a, int b)
{
static if (isLessThan)
return a - b;
else
return binaryFun!pred(b, a) ? 1 : binaryFun!pred(a, b) ? -1 : 0;
}
static if (typeof(r1[0]).sizeof == typeof(r2[0]).sizeof && isLessThan)
{
static if (typeof(r1[0]).sizeof == 1)
{ {
if (*p1 != *p2) return threeWayInt(cast(int) *p1, cast(int) *p2); immutable len = min(r1.length, r2.length);
immutable result = __ctfe ?
{
foreach (i; 0 .. len)
{
if (r1[i] != r2[i])
return threeWayInt(r1[i], r2[i]);
}
return 0;
}()
: () @trusted { return memcmp(r1.ptr, r2.ptr, len); }();
if (result) return result;
} }
else
{
auto p1 = r1.ptr, p2 = r2.ptr,
pEnd = p1 + min(r1.length, r2.length);
for (; p1 != pEnd; ++p1, ++p2)
{
if (*p1 != *p2) return threeWayInt(cast(int) *p1, cast(int) *p2);
}
}
return threeWay(r1.length, r2.length);
} }
return threeWay(r1.length, r2.length); else
}
else
{
for (size_t i1, i2;;)
{ {
if (i1 == r1.length) return threeWay(i2, r2.length); for (size_t i1, i2;;)
if (i2 == r2.length) return threeWay(r1.length, i1); {
immutable c1 = decode(r1, i1), if (i1 == r1.length) return threeWay(i2, r2.length);
c2 = decode(r2, i2); if (i2 == r2.length) return threeWay(r1.length, i1);
if (c1 != c2) return threeWayInt(cast(int) c1, cast(int) c2); immutable c1 = decode(r1, i1),
c2 = decode(r2, i2);
if (c1 != c2) return threeWayInt(cast(int) c1, cast(int) c2);
}
} }
} }
} }