Skip to content
This repository was archived by the owner on Oct 12, 2022. It is now read-only.

Commit 2b6673f

Browse files
authored
Merge pull request #2356 from jpf91/hash
[GDC] Do not include padding when hashing floating point types merged-on-behalf-of: Nicholas Wilson <thewilsonator@users.noreply.github.com>
2 parents 86b0d3c + 4c12f34 commit 2b6673f

File tree

2 files changed

+29
-1
lines changed

2 files changed

+29
-1
lines changed

src/core/internal/convert.d

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,7 @@ private struct Float
232232

233233
private template FloatTraits(T) if (floatFormat!T == FloatFormat.Float)
234234
{
235+
enum DATASIZE = 4;
235236
enum EXPONENT = 8;
236237
enum MANTISSA = 23;
237238
enum ZERO = Float(0, 0, 0);
@@ -244,6 +245,7 @@ private template FloatTraits(T) if (floatFormat!T == FloatFormat.Float)
244245

245246
private template FloatTraits(T) if (floatFormat!T == FloatFormat.Double)
246247
{
248+
enum DATASIZE = 8;
247249
enum EXPONENT = 11;
248250
enum MANTISSA = 52;
249251
enum ZERO = Float(0, 0, 0);
@@ -256,6 +258,7 @@ private template FloatTraits(T) if (floatFormat!T == FloatFormat.Double)
256258

257259
private template FloatTraits(T) if (floatFormat!T == FloatFormat.Real80)
258260
{
261+
enum DATASIZE = 10;
259262
enum EXPONENT = 15;
260263
enum MANTISSA = 64;
261264
enum ZERO = Float(0, 0, 0);
@@ -268,6 +271,7 @@ private template FloatTraits(T) if (floatFormat!T == FloatFormat.Real80)
268271

269272
private template FloatTraits(T) if (floatFormat!T == FloatFormat.DoubleDouble) //Unsupported in CTFE
270273
{
274+
enum DATASIZE = 16;
271275
enum EXPONENT = 11;
272276
enum MANTISSA = 106;
273277
enum ZERO = Float(0, 0, 0);
@@ -280,6 +284,7 @@ private template FloatTraits(T) if (floatFormat!T == FloatFormat.DoubleDouble) /
280284

281285
private template FloatTraits(T) if (floatFormat!T == FloatFormat.Quadruple)
282286
{
287+
enum DATASIZE = 16;
283288
enum EXPONENT = 15;
284289
enum MANTISSA = 112;
285290
enum ZERO = Float(0, 0, 0);
@@ -567,6 +572,11 @@ template floatFormat(T) if (is(T:real) || is(T:ireal))
567572

568573
}
569574

575+
package template floatSize(T) if (is(T:real) || is(T:ireal))
576+
{
577+
enum floatSize = FloatTraits!(T).DATASIZE;
578+
}
579+
570580
// all toUbyte functions must be evaluable at compile time
571581
@trusted pure nothrow @nogc
572582
const(ubyte)[] toUbyte(T)(const T[] arr) if (T.sizeof == 1)

src/core/internal/hash.d

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,8 @@ size_t hashOf(T)(scope const T val, size_t seed = 0) if (!is(T == enum) && __tra
385385
{
386386
static if (__traits(isFloating, val))
387387
{
388+
import core.internal.convert : floatSize;
389+
388390
static if (floatCoalesceZeroes || floatCoalesceNaNs)
389391
{
390392
import core.internal.traits : Unqual;
@@ -412,7 +414,23 @@ size_t hashOf(T)(scope const T val, size_t seed = 0) if (!is(T == enum) && __tra
412414
else static if (T.mant_dig == double.mant_dig && T.sizeof == ulong.sizeof)
413415
return hashOf(*cast(const ulong*) &data, seed);
414416
else
415-
return bytesHashWithExactSizeAndAlignment!T(toUbyte(data), seed);
417+
{
418+
static if (is(T : creal) && T.sizeof != 2 * floatSize!(typeof(T.re)))
419+
{
420+
auto h1 = hashOf(data.re);
421+
return hashOf(data.im, h1);
422+
}
423+
else static if (is(T : real) || is(T : ireal))
424+
{
425+
// Ignore trailing padding
426+
auto bytes = toUbyte(data)[0 .. floatSize!T];
427+
return bytesHashWithExactSizeAndAlignment!T(bytes, seed);
428+
}
429+
else
430+
{
431+
return bytesHashWithExactSizeAndAlignment!T(toUbyte(data), seed);
432+
}
433+
}
416434
}
417435
else
418436
{

0 commit comments

Comments
 (0)