Add ULP and margin matcher

Closes #1074
diff --git a/projects/SelfTest/Baselines/xml.sw.approved.txt b/projects/SelfTest/Baselines/xml.sw.approved.txt
index d3ef33c..f8abb18 100644
--- a/projects/SelfTest/Baselines/xml.sw.approved.txt
+++ b/projects/SelfTest/Baselines/xml.sw.approved.txt
@@ -1945,6 +1945,278 @@
       </Expression>
       <OverallResult success="true"/>
     </TestCase>
+    <TestCase name="Floating point matchers: double" tags="[floating-point][matchers]" filename="projects/<exe-name>/MatchersTests.cpp" >
+      <Section name="Margin" filename="projects/<exe-name>/MatchersTests.cpp" >
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
+          <Original>
+            1., WithinAbs(1., 0)
+          </Original>
+          <Expanded>
+            1.0 is within 0.000000 of 1.000000
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
+          <Original>
+            0., WithinAbs(1., 1)
+          </Original>
+          <Expanded>
+            0.0 is within 1.000000 of 1.000000
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
+          <Original>
+            0., !WithinAbs(1., 0.99)
+          </Original>
+          <Expanded>
+            0.0 not is within 0.990000 of 1.000000
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
+          <Original>
+            0., !WithinAbs(1., 0.99)
+          </Original>
+          <Expanded>
+            0.0 not is within 0.990000 of 1.000000
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
+          <Original>
+            NAN, !WithinAbs(NAN, 0)
+          </Original>
+          <Expanded>
+            nanf not is within 0.000000 of nan
+          </Expanded>
+        </Expression>
+        <OverallResults successes="5" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="ULPs" filename="projects/<exe-name>/MatchersTests.cpp" >
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
+          <Original>
+            1., WithinULP(1., 0)
+          </Original>
+          <Expanded>
+            1.0 is within 0 ULPs of 1.000000
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
+          <Original>
+            std::nextafter(1., 2.), WithinULP(1., 1)
+          </Original>
+          <Expanded>
+            1.0 is within 1 ULPs of 1.000000
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
+          <Original>
+            std::nextafter(1., 0.), WithinULP(1., 1)
+          </Original>
+          <Expanded>
+            1.0 is within 1 ULPs of 1.000000
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
+          <Original>
+            std::nextafter(1., 2.), !WithinULP(1., 0)
+          </Original>
+          <Expanded>
+            1.0 not is within 0 ULPs of 1.000000
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
+          <Original>
+            1., WithinULP(1., 0)
+          </Original>
+          <Expanded>
+            1.0 is within 0 ULPs of 1.000000
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
+          <Original>
+            -0., WithinULP(0., 0)
+          </Original>
+          <Expanded>
+            -0.0 is within 0 ULPs of 0.000000
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
+          <Original>
+            NAN, !WithinULP(NAN, 123)
+          </Original>
+          <Expanded>
+            nanf not is within 123 ULPs of nanf
+          </Expanded>
+        </Expression>
+        <OverallResults successes="7" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="Composed" filename="projects/<exe-name>/MatchersTests.cpp" >
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
+          <Original>
+            1., WithinAbs(1., 0.5) || WithinULP(2., 1)
+          </Original>
+          <Expanded>
+            1.0 ( is within 0.500000 of 1.000000 or is within 1 ULPs of 2.000000 )
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
+          <Original>
+            1., WithinAbs(2., 0.5) || WithinULP(1., 0)
+          </Original>
+          <Expanded>
+            1.0 ( is within 0.500000 of 2.000000 or is within 0 ULPs of 1.000000 )
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
+          <Original>
+            NAN, !(WithinAbs(NAN, 100) || WithinULP(NAN, 123))
+          </Original>
+          <Expanded>
+            nanf not ( is within 100.000000 of nan or is within 123 ULPs of nanf )
+          </Expanded>
+        </Expression>
+        <OverallResults successes="3" failures="0" expectedFailures="0"/>
+      </Section>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="Floating point matchers: float" tags="[floating-point][matchers]" filename="projects/<exe-name>/MatchersTests.cpp" >
+      <Section name="Margin" filename="projects/<exe-name>/MatchersTests.cpp" >
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
+          <Original>
+            1.f, WithinAbs(1.f, 0)
+          </Original>
+          <Expanded>
+            1.0f is within 0.000000 of 1.000000
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
+          <Original>
+            0.f, WithinAbs(1.f, 1)
+          </Original>
+          <Expanded>
+            0.0f is within 1.000000 of 1.000000
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
+          <Original>
+            0.f, !WithinAbs(1.f, 0.99f)
+          </Original>
+          <Expanded>
+            0.0f not is within 0.990000 of 1.000000
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
+          <Original>
+            0.f, !WithinAbs(1.f, 0.99f)
+          </Original>
+          <Expanded>
+            0.0f not is within 0.990000 of 1.000000
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
+          <Original>
+            0.f, WithinAbs(-0.f, 0)
+          </Original>
+          <Expanded>
+            0.0f is within 0.000000 of -0.000000
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
+          <Original>
+            NAN, !WithinAbs(NAN, 0)
+          </Original>
+          <Expanded>
+            nanf not is within 0.000000 of nan
+          </Expanded>
+        </Expression>
+        <OverallResults successes="6" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="ULPs" filename="projects/<exe-name>/MatchersTests.cpp" >
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
+          <Original>
+            1.f, WithinULP(1.f, 0)
+          </Original>
+          <Expanded>
+            1.0f is within 0 ULPs of 1.000000f
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
+          <Original>
+            std::nextafter(1.f, 2.f), WithinULP(1.f, 1)
+          </Original>
+          <Expanded>
+            1.0f is within 1 ULPs of 1.000000f
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
+          <Original>
+            std::nextafter(1.f, 0.f), WithinULP(1.f, 1)
+          </Original>
+          <Expanded>
+            1.0f is within 1 ULPs of 1.000000f
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
+          <Original>
+            std::nextafter(1.f, 2.f), !WithinULP(1.f, 0)
+          </Original>
+          <Expanded>
+            1.0f not is within 0 ULPs of 1.000000f
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
+          <Original>
+            1.f, WithinULP(1.f, 0)
+          </Original>
+          <Expanded>
+            1.0f is within 0 ULPs of 1.000000f
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
+          <Original>
+            -0.f, WithinULP(0.f, 0)
+          </Original>
+          <Expanded>
+            -0.0f is within 0 ULPs of 0.000000f
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
+          <Original>
+            NAN, !WithinULP(NAN, 123)
+          </Original>
+          <Expanded>
+            nanf not is within 123 ULPs of nanf
+          </Expanded>
+        </Expression>
+        <OverallResults successes="7" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="Composed" filename="projects/<exe-name>/MatchersTests.cpp" >
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
+          <Original>
+            1.f, WithinAbs(1.f, 0.5) || WithinULP(1.f, 1)
+          </Original>
+          <Expanded>
+            1.0f ( is within 0.500000 of 1.000000 or is within 1 ULPs of 1.000000f )
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
+          <Original>
+            1.f, WithinAbs(2.f, 0.5) || WithinULP(1.f, 0)
+          </Original>
+          <Expanded>
+            1.0f ( is within 0.500000 of 2.000000 or is within 0 ULPs of 1.000000f )
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
+          <Original>
+            NAN, !(WithinAbs(NAN, 100) || WithinULP(NAN, 123))
+          </Original>
+          <Expanded>
+            nanf not ( is within 100.000000 of nan or is within 123 ULPs of nanf )
+          </Expanded>
+        </Expression>
+        <OverallResults successes="3" failures="0" expectedFailures="0"/>
+      </Section>
+      <OverallResult success="true"/>
+    </TestCase>
     <TestCase name="Greater-than inequalities with different epsilons" tags="[Approx]" filename="projects/<exe-name>/ApproxTests.cpp" >
       <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/ApproxTests.cpp" >
         <Original>
@@ -8446,7 +8718,7 @@
       </Section>
       <OverallResult success="true"/>
     </TestCase>
-    <OverallResults successes="783" failures="100" expectedFailures="21"/>
+    <OverallResults successes="814" failures="100" expectedFailures="21"/>
   </Group>
-  <OverallResults successes="783" failures="99" expectedFailures="21"/>
+  <OverallResults successes="814" failures="99" expectedFailures="21"/>
 </Catch>