Skip to content
This repository was archived by the owner on Oct 12, 2022. It is now read-only.
/ druntime Public archive
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 31 additions & 4 deletions src/object.d
Original file line number Diff line number Diff line change
Expand Up @@ -3454,14 +3454,13 @@ if (__traits(isScalar, T))
// comparisons in the semantic analysis phase of CmpExp. The ordering
// comparison is lowered to a call to this template.
int __cmp(T1, T2)(T1[] s1, T2[] s2)
if (!__traits(isScalar, T1))
if (!__traits(isScalar, T1) && !__traits(isScalar, T2))
{
import core.internal.traits : Unqual;
alias U1 = Unqual!T1;
alias U2 = Unqual!T2;
static assert(is(U1 == U2), "Internal error.");

static if (is(U1 == void))
static if (is(U1 == void) && is(U2 == void))
static @trusted ref inout(ubyte) at(inout(void)[] r, size_t i) { return (cast(inout(ubyte)*) r.ptr)[i]; }
else
static @trusted ref R at(R)(R[] r, size_t i) { return r.ptr[i]; }
Expand Down Expand Up @@ -3492,8 +3491,11 @@ if (!__traits(isScalar, T1))
{
// TODO: fix this legacy bad behavior, see
// https://issues.dlang.org/show_bug.cgi?id=17244
static assert(is(U1 == U2), "Internal error.");
import core.stdc.string : memcmp;
return (() @trusted => memcmp(&at(s1, u), &at(s2, u), U1.sizeof))();
auto c = (() @trusted => memcmp(&at(s1, u), &at(s2, u), U1.sizeof))();
if (c != 0)
return c;
}
}
return s1.length < s2.length ? -1 : (s1.length > s2.length);
Expand Down Expand Up @@ -3552,9 +3554,15 @@ if (!__traits(isScalar, T1))
{
T[2] a = [T.max, T.max];
T[2] b = [T.min_normal, T.min_normal];
T[2] c = [T.max, T.min_normal];
T[1] d = [T.max];

assert(__cmp(a, b) > 0);
assert(__cmp(b, a) < 0);
assert(__cmp(a, c) > 0);
assert(__cmp(a, d) > 0);
assert(__cmp(d, c) < 0);
assert(__cmp(c, c) == 0);
}

compareMinMax!real;
Expand Down Expand Up @@ -3588,6 +3596,24 @@ if (!__traits(isScalar, T1))
assert(__cmp(b, a) < 0);
}

// arrays of arrays with mixed modifiers
@safe unittest
{
// https://issues.dlang.org/show_bug.cgi?id=17876
bool less1(immutable size_t[][] a, size_t[][] b) { return a < b; }
bool less2(const void[][] a, void[][] b) { return a < b; }
bool less3(inout size_t[][] a, size_t[][] b) { return a < b; }

immutable size_t[][] a = [[1, 2], [3, 4]];
size_t[][] b = [[1, 2], [3, 5]];
assert(less1(a, b));
assert(less3(a, b));

auto va = [cast(immutable void[])a[0], a[1]];
auto vb = [cast(void[])b[0], b[1]];
assert(less2(va, vb));
}

// objects
@safe unittest
{
Expand Down Expand Up @@ -3628,6 +3654,7 @@ if (!__traits(isScalar, T1))

assert(__cmp([c1, c1][], [c2, c2][]) < 0);
assert(__cmp([c2, c2], [c1, c1]) > 0);
assert(__cmp([c2, c2], [c2, c1]) > 0);
}

// Compiler hook into the runtime implementation of array (vector) operations.
Expand Down