@@ -299,7 +299,9 @@ struct Caster(bool isExplicit, alias bailoutOverride = null) {
299299 return CastKind.UPad;
300300 }
301301
302- return CastKind.Invalid;
302+ return isFloat (bt)
303+ ? CastKind.UnsignedToFloat
304+ : CastKind.Invalid;
303305
304306 case Char:
305307 t = integralOfChar(t);
@@ -319,6 +321,12 @@ struct Caster(bool isExplicit, alias bailoutOverride = null) {
319321 return CastKind.IntToBool;
320322 }
321323
324+ if (isFloat(bt)) {
325+ return isSigned (t)
326+ ? CastKind.SignedToFloat
327+ : CastKind.UnsignedToFloat;
328+ }
329+
322330 if (! isIntegral(bt)) {
323331 return CastKind.Invalid;
324332 }
@@ -336,7 +344,23 @@ struct Caster(bool isExplicit, alias bailoutOverride = null) {
336344 }
337345
338346 case Float, Double, Real:
339- assert (0 , " Floating point casts are not implemented" );
347+ // cast from a float to a float
348+ if (isFloat(bt)) {
349+ assert (bt != t);
350+ return bt < t ? CastKind.FloatTrunc : CastKind.FloatExtend;
351+ }
352+
353+ if (isExplicit) {
354+ if (isIntegral(bt) && canConvertToIntegral(bt)) {
355+ return isSigned (isChar(bt) ? integralOfChar(bt) : bt)
356+ ? CastKind.FloatToSigned
357+ : CastKind.FloatToUnsigned;
358+ } else {
359+ return CastKind.Invalid;
360+ }
361+ } else {
362+ return bailout (t);
363+ }
340364
341365 case Null:
342366 return CastKind.Invalid;
@@ -650,3 +674,93 @@ struct Caster(bool isExplicit, alias bailoutOverride = null) {
650674 return CastKind.Invalid;
651675 }
652676}
677+
678+ version (unittest ) {
679+ BuiltinType[] floatTypes =
680+ [BuiltinType.Float, BuiltinType.Double, BuiltinType.Real];
681+ BuiltinType[] signedTypes =
682+ [BuiltinType.Byte, BuiltinType.Short, BuiltinType.Int, BuiltinType.Long,
683+ BuiltinType.Cent];
684+ BuiltinType[] unsignedTypes =
685+ [BuiltinType.Ubyte, BuiltinType.Ushort, BuiltinType.Uint,
686+ BuiltinType.Ulong, BuiltinType.Ucent];
687+ void checkCastKind (
688+ const BuiltinType from,
689+ const BuiltinType to,
690+ const CastKind explicitShouldBe,
691+ const CastKind implicitShouldBe
692+ ) {
693+ Type fromAsType = Type.get (from);
694+ Type toAsType = Type.get (to);
695+ import std.format : format;
696+ const explicitResult = explicitCastFrom(null , fromAsType, toAsType);
697+ assert (
698+ explicitResult == explicitShouldBe,
699+ format(" Explicit cast yielded `%s`, when `%s` was expected" ,
700+ explicitResult, explicitShouldBe)
701+ );
702+ const implicitResult = implicitCastFrom(null , fromAsType, toAsType);
703+ assert (
704+ implicitResult == implicitShouldBe,
705+ format(" Implicit cast yielded `%s`, when `%s` was expected" ,
706+ implicitResult, implicitShouldBe)
707+ );
708+ }
709+ }
710+
711+ @(" Float to float casts" )
712+ unittest {
713+ foreach (from; floatTypes)
714+ foreach (to; floatTypes) {
715+ const shouldBe = from == to
716+ ? CastKind.Exact
717+ : (from < to ? CastKind.FloatExtend : CastKind.FloatTrunc);
718+ checkCastKind(from, to, shouldBe, shouldBe);
719+ }
720+ }
721+
722+ @(" Bools can be casted to floats" )
723+ unittest {
724+ foreach (to; floatTypes) {
725+ checkCastKind(BuiltinType.Bool, to, CastKind.UnsignedToFloat,
726+ CastKind.UnsignedToFloat);
727+ }
728+ }
729+
730+ @(" Signed types can be casted to floats" )
731+ unittest {
732+ foreach (from; signedTypes) {
733+ foreach (to; floatTypes) {
734+ checkCastKind(from, to, CastKind.SignedToFloat,
735+ CastKind.SignedToFloat);
736+ }
737+ }
738+ }
739+
740+ @(" Unsigned types can be casted to floats" )
741+ unittest {
742+ foreach (from; unsignedTypes) {
743+ foreach (to; floatTypes) {
744+ checkCastKind(from, to, CastKind.UnsignedToFloat,
745+ CastKind.UnsignedToFloat);
746+ }
747+ }
748+ }
749+
750+ @(" Float casts to signed types" )
751+ unittest {
752+ foreach (from; floatTypes) {
753+ foreach (to; signedTypes) {
754+ checkCastKind(from, to, CastKind.FloatToSigned, CastKind.Invalid);
755+ }
756+ }
757+ }
758+
759+ @(" Float casts to unsigned types" )
760+ unittest {
761+ foreach (from; floatTypes) {
762+ foreach (to; unsignedTypes) {
763+ checkCastKind(from, to, CastKind.FloatToUnsigned, CastKind.Invalid);
764+ }
765+ }
766+ }
0 commit comments