@@ -14,15 +14,15 @@ private noreturn assumeAllAttrAndCall(scope const void delegate() t)
14
14
}
15
15
16
16
// /
17
- struct ShouldApprox (T)
18
- if (__traits(isFloating, T))
17
+ struct ShouldApprox (T, F = T )
18
+ if (( __traits(isFloating, T) || __traits(hasMember, T, "approxEqual")) && __traits(isFloating, F ))
19
19
{
20
20
// /
21
21
T value;
22
22
// /
23
- T maxRelDiff = 0x1p- 20f ;
23
+ F maxRelDiff = 0x1p- 20f ;
24
24
// /
25
- T maxAbsDiff = 0x1p- 20f ;
25
+ F maxAbsDiff = 0x1p- 20f ;
26
26
27
27
// /
28
28
void opEquals (T expected, string file = __FILE__ , int line = __LINE__ ) @safe pure nothrow @nogc
@@ -59,6 +59,28 @@ unittest
59
59
shouldApprox(1 + 9e-7 , 1e-6 , 1e-6 ) == 1 ;
60
60
}
61
61
62
+ // / ditto
63
+ ShouldApprox! (T, F) shouldApprox(T, F)(const T value, const F maxRelDiff = double (0x1p- 20f ), const F maxAbsDiff = double (0x1p- 20f ))
64
+ if (__traits(hasMember, T, " approxEqual" ) && __traits(isFloating, F))
65
+ {
66
+ return typeof (return )(value, maxRelDiff, maxAbsDiff);
67
+ }
68
+
69
+ // /
70
+ version (mir_test)
71
+ unittest
72
+ {
73
+ static struct C {
74
+ double re, im;
75
+ auto approxEqual (C rhs, double maxRelDiff, double maxAbsDiff)
76
+ {
77
+ import mir.math.common: approxEqual;
78
+ return approxEqual (re, rhs.re, maxRelDiff, maxAbsDiff) && approxEqual(im, rhs.im, maxRelDiff, maxAbsDiff);
79
+ }
80
+ }
81
+ C(1.0 , 1.0 ).shouldApprox == C(1 + 9e-7 , 1 - 9e-7 );
82
+ }
83
+
62
84
// /
63
85
struct Should (T)
64
86
{
0 commit comments