Skip to content

Commit cf3f7fe

Browse files
committed
modify __equals() so dmd can inline it
1 parent a268ab8 commit cf3f7fe

File tree

1 file changed

+23
-10
lines changed

1 file changed

+23
-10
lines changed

src/core/internal/array/equality.d

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@ bool __equals(T1, T2)(scope const T1[] lhs, scope const T2[] rhs)
2121
@nogc nothrow pure @trusted
2222
if (__traits(isScalar, T1) && __traits(isScalar, T2))
2323
{
24-
if (lhs.length != rhs.length)
25-
return false;
24+
const length = lhs.length;
2625

2726
static if (T1.sizeof == T2.sizeof
2827
// Signedness needs to match for types that promote to int.
@@ -31,20 +30,21 @@ if (__traits(isScalar, T1) && __traits(isScalar, T2))
3130
&& (T1.sizeof >= 4 || __traits(isUnsigned, T1) == __traits(isUnsigned, T2))
3231
&& !__traits(isFloating, T1) && !__traits(isFloating, T2))
3332
{
34-
if (!__ctfe)
33+
if (__ctfe)
34+
return length == rhs.length && isEqual(lhs.ptr, rhs.ptr, length);
35+
else
3536
{
3637
// This would improperly allow equality of integers and pointers
3738
// but the CTFE branch will stop this function from compiling then.
3839
import core.stdc.string : memcmp;
39-
return lhs.length == 0 ||
40-
0 == memcmp(cast(const void*) lhs.ptr, cast(const void*) rhs.ptr, lhs.length * T1.sizeof);
40+
return length == rhs.length &&
41+
(!length || 0 == memcmp(cast(const void*) lhs.ptr, cast(const void*) rhs.ptr, length * T1.sizeof));
4142
}
4243
}
43-
44-
foreach (const i; 0 .. lhs.length)
45-
if (lhs.ptr[i] != rhs.ptr[i])
46-
return false;
47-
return true;
44+
else
45+
{
46+
return length == rhs.length && isEqual(lhs.ptr, rhs.ptr, length);
47+
}
4848
}
4949

5050
bool __equals(T1, T2)(scope T1[] lhs, scope T2[] rhs)
@@ -89,6 +89,19 @@ if (!__traits(isScalar, T1) || !__traits(isScalar, T2))
8989
}
9090
}
9191

92+
/******************************
93+
* Helper function for __equals().
94+
* Outlined to enable __equals() to be inlined, as dmd cannot inline loops.
95+
*/
96+
private
97+
bool isEqual(T1, T2)(scope const T1* t1, scope const T2* t2, size_t length)
98+
{
99+
foreach (const i; 0 .. length)
100+
if (t1[i] != t2[i])
101+
return false;
102+
return true;
103+
}
104+
92105
@safe unittest
93106
{
94107
assert(__equals([], []));

0 commit comments

Comments
 (0)