From 0efa1d3bf92bcaa6c4a99cad0b574185a537906a Mon Sep 17 00:00:00 2001 From: Cauterite Date: Sun, 8 Nov 2015 05:44:05 +1100 Subject: [PATCH] workaround for bug 11135 (typecons.Nullable) --- std/typecons.d | 47 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/std/typecons.d b/std/typecons.d index 62cf0fb6b..43cdda112 100644 --- a/std/typecons.d +++ b/std/typecons.d @@ -2450,7 +2450,28 @@ Params: */ struct Nullable(T, T nullValue) { - private T _value = nullValue; + static if (_useNanWorkaround && is(T == float) && nullValue is T.init) + union + { + private uint _raw = 0x7fa00000; // float.init + private T _value; + } + else static if (_useNanWorkaround && is(T == double) && nullValue is T.init) + union + { + private ulong _raw = 0x7ff4000000000000UL; // double.init + private T _value; + } + else + private T _value = nullValue; + + // workaround for bug 15316 + version (X86_64) + private enum _useNanWorkaround = true; + else version (OSX) + private enum _useNanWorkaround = true; + else + private enum _useNanWorkaround = false; /** Constructor initializing $(D this) with $(D value). @@ -2494,6 +2515,12 @@ Returns: { return _value is nullValue; } + //Need to use 'is' if T is a float type + //because NaN != NaN + else static if (isFloatingPoint!T) + { + return _value is nullValue; + } else { return _value == nullValue; @@ -2511,6 +2538,24 @@ Returns: assert(!ni.isNull); } +// Bugzilla 11135 +unittest +{ + foreach (T; AliasSeq!(float, double, real)) + { + Nullable!(T, T.init) nf; + //Initialized to "null" state + assert(nf.isNull); + assert(nf is typeof(nf).init); + + nf = 0; + assert(!nf.isNull); + + nf.nullify(); + assert(nf.isNull); + } +} + /** Forces $(D this) to the null state. */