diff --git a/packages/Catch2/.gitrepo b/packages/Catch2/.gitrepo
index 81212f2a76c2e84ebd308d585037e06a5a17f25c..adc0df81e8c95b703a4a5d417f3597e7907ee86c 100644
--- a/packages/Catch2/.gitrepo
+++ b/packages/Catch2/.gitrepo
@@ -6,7 +6,7 @@
 [subrepo]
 	remote = git@github.com:catchorg/Catch2.git
 	branch = master
-	commit = 060a41ec7b954cf6a556a88035f04b771680916b
-	parent = df97ccdd26a1350902ae665b134949710d78071e
+	commit = 930f49a641aa6a495d264d7b5e7c007734da0b0c
+	parent = 5c9d332c93a9e1253e960d8d5fb38ed777f315fa
 	cmdver = 0.4.0
 	method = merge
diff --git a/packages/Catch2/CMakeLists.txt b/packages/Catch2/CMakeLists.txt
index 2ead67597f2262e8e54bd23f7be47a267b5c73ea..8aa5b58b92cf1aa8bf78f57a815e22ed4df07e4b 100644
--- a/packages/Catch2/CMakeLists.txt
+++ b/packages/Catch2/CMakeLists.txt
@@ -14,7 +14,7 @@ if (CMAKE_BINARY_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
 endif()
 
 
-project(Catch2 LANGUAGES CXX VERSION 2.10.0)
+project(Catch2 LANGUAGES CXX VERSION 2.10.2)
 
 # Provide path for scripts
 list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake")
diff --git a/packages/Catch2/README.md b/packages/Catch2/README.md
index 2b806cd4d69923cd68f864fb24ec9966ab2dd0b7..ebf619051642889bae0c8baf1990c2ef55be03e0 100644
--- a/packages/Catch2/README.md
+++ b/packages/Catch2/README.md
@@ -5,11 +5,11 @@
 [![Build Status](https://travis-ci.org/catchorg/Catch2.svg?branch=master)](https://travis-ci.org/catchorg/Catch2)
 [![Build status](https://ci.appveyor.com/api/projects/status/github/catchorg/Catch2?svg=true)](https://ci.appveyor.com/project/catchorg/catch2)
 [![codecov](https://codecov.io/gh/catchorg/Catch2/branch/master/graph/badge.svg)](https://codecov.io/gh/catchorg/Catch2)
-[![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://wandbox.org/permlink/00GdTUbFWaV3bNah)
+[![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://wandbox.org/permlink/LzYWgcPrcy9yQmed)
 [![Join the chat in Discord: https://discord.gg/4CWS9zD](https://img.shields.io/badge/Discord-Chat!-brightgreen.svg)](https://discord.gg/4CWS9zD)
 
 
-<a href="https://github.com/catchorg/Catch2/releases/download/v2.10.0/catch.hpp">The latest version of the single header can be downloaded directly using this link</a>
+<a href="https://github.com/catchorg/Catch2/releases/download/v2.10.2/catch.hpp">The latest version of the single header can be downloaded directly using this link</a>
 
 ## Catch2 is released!
 
diff --git a/packages/Catch2/codecov.yml b/packages/Catch2/codecov.yml
index 94d88d8331eec87994d49c0802a08a794617c8f8..75809ee2e8d5a6292b166238d506ccee8c91294b 100644
--- a/packages/Catch2/codecov.yml
+++ b/packages/Catch2/codecov.yml
@@ -14,6 +14,7 @@ coverage:
     - "**/catch_reporter_tap.hpp"
     - "**/catch_reporter_automake.hpp"
     - "**/catch_reporter_teamcity.hpp"
+    - "**/catch_reporter_sonarqube.hpp"
     - "**/external/clara.hpp"
 
 
diff --git a/packages/Catch2/docs/ci-and-misc.md b/packages/Catch2/docs/ci-and-misc.md
index 8c330872565517e4b21f2ad78a3fd096e6b1ae13..40b7cec9270010cd631bc19b130a852544222a9d 100644
--- a/packages/Catch2/docs/ci-and-misc.md
+++ b/packages/Catch2/docs/ci-and-misc.md
@@ -12,7 +12,7 @@ Build Systems may refer to low-level tools, like CMake, or larger systems that r
 
 ## Continuous Integration systems
 
-Probably the most important aspect to using Catch with a build server is the use of different reporters. Catch comes bundled with three reporters that should cover the majority of build servers out there - although adding more for better integration with some is always a possibility (currently we also offer TeamCity, TAP and Automake reporters).
+Probably the most important aspect to using Catch with a build server is the use of different reporters. Catch comes bundled with three reporters that should cover the majority of build servers out there - although adding more for better integration with some is always a possibility (currently we also offer TeamCity, TAP, Automake and SonarQube reporters).
 
 Two of these reporters are built in (XML and JUnit) and the third (TeamCity) is included as a separate header. It's possible that the other two may be split out in the future too - as that would make the core of Catch smaller for those that don't need them.
 
@@ -65,6 +65,10 @@ The Automake Reporter writes out the [meta tags](https://www.gnu.org/software/au
 
 Because of the incremental nature of Catch's test suites and ability to run specific tests, our implementation of TAP reporter writes out the number of tests in a suite last.
 
+### SonarQube Reporter
+```-r sonarqube```
+[SonarQube Generic Test Data](https://docs.sonarqube.org/latest/analysis/generic-test/) XML format for tests metrics.
+
 ## Low-level tools
 
 ### Precompiled headers (PCHs)
diff --git a/packages/Catch2/docs/command-line.md b/packages/Catch2/docs/command-line.md
index d204da0e5bba36d62aeac05f6578e9bdb7e1f271..742d84b6602bdde58b423e194cc7dde2e353c50c 100644
--- a/packages/Catch2/docs/command-line.md
+++ b/packages/Catch2/docs/command-line.md
@@ -99,6 +99,7 @@ exclude:notThis         Matches all tests except, 'notThis'
 ~*private*              Matches all tests except those that contain 'private'
 a* ~ab* abc             Matches all tests that start with 'a', except those that
                         start with 'ab', except 'abc', which is included
+-# [#somefile]          Matches all tests from the file 'somefile.cpp'
 </pre>
 
 Names within square brackets are interpreted as tags.
diff --git a/packages/Catch2/docs/deprecations.md b/packages/Catch2/docs/deprecations.md
index 77830298be66b228518e6213ceb4723d99cb37af..c2b178e22778626ee296ba436397a6f11cd2cd2f 100644
--- a/packages/Catch2/docs/deprecations.md
+++ b/packages/Catch2/docs/deprecations.md
@@ -93,6 +93,17 @@ positively match a testspec.
 The API for Catch2's console colour will be changed to take an extra
 argument, the stream to which the colour code should be applied.
 
+
+### Type erasure in the `PredicateMatcher`
+
+Currently, the `PredicateMatcher` uses `std::function` for type erasure,
+so that type of the matcher is always `PredicateMatcher<T>`, regardless
+of the type of the predicate. Because of the high compilation overhead
+of `std::function`, and the fact that the type erasure is used only rarely,
+`PredicateMatcher` will no longer be type erased in the future. Instead,
+the predicate type will be made part of the PredicateMatcher's type.
+
+
 ---
 
 [Home](Readme.md#top)
diff --git a/packages/Catch2/docs/generators.md b/packages/Catch2/docs/generators.md
index 61276f3cca6e72e73d34bb599eefab036313a49e..d0147d7f0638034598313d8417215974f216780d 100644
--- a/packages/Catch2/docs/generators.md
+++ b/packages/Catch2/docs/generators.md
@@ -49,7 +49,7 @@ a test case,
 * 4 specific purpose generators
   * `RandomIntegerGenerator<Integral>` -- generates random Integrals from range
   * `RandomFloatGenerator<Float>` -- generates random Floats from range
-  * `RangeGenerator<T>` -- generates all values inside a specific range
+  * `RangeGenerator<T>` -- generates all values inside an arithmetic range
   * `IteratorGenerator<T>` -- copies and returns values from an iterator range
 
 > `ChunkGenerator<T>`, `RandomIntegerGenerator<Integral>`, `RandomFloatGenerator<Float>` and `RangeGenerator<T>` were introduced in Catch 2.7.0.
@@ -69,8 +69,8 @@ type, making their usage much nicer. These are
 * `map<T>(func, GeneratorWrapper<U>&&)` for `MapGenerator<T, U, Func>` (map `U` to `T`)
 * `chunk(chunk-size, GeneratorWrapper<T>&&)` for `ChunkGenerator<T>`
 * `random(IntegerOrFloat a, IntegerOrFloat b)` for `RandomIntegerGenerator` or `RandomFloatGenerator`
-* `range(start, end)` for `RangeGenerator<T>` with a step size of `1`
-* `range(start, end, step)` for `RangeGenerator<T>` with a custom step size
+* `range(Arithemtic start, Arithmetic end)` for `RangeGenerator<Arithmetic>` with a step size of `1`
+* `range(Arithmetic start, Arithmetic end, Arithmetic step)` for `RangeGenerator<Arithmetic>` with a custom step size
 * `from_range(InputIterator from, InputIterator to)` for `IteratorGenerator<T>`
 * `from_range(Container const&)` for `IteratorGenerator<T>`
 
@@ -78,6 +78,8 @@ type, making their usage much nicer. These are
 
 > `from_range` has been introduced in Catch 2.10.0
 
+> `range()` for floating point numbers has been introduced in Catch X.Y.Z
+
 And can be used as shown in the example below to create a generator
 that returns 100 odd random number:
 
diff --git a/packages/Catch2/docs/limitations.md b/packages/Catch2/docs/limitations.md
index b95cd87f2c4511cc62ecc506ae28a65a5ba5cea9..65483b87bbd0873f7e07e79f39de08e5a55e190f 100644
--- a/packages/Catch2/docs/limitations.md
+++ b/packages/Catch2/docs/limitations.md
@@ -45,6 +45,15 @@ the `REQUIRE` family of macros), Catch2 does not know that there are no
 more sections in that test case and must run the test case again.
 
 
+### MinGW/CygWin compilation (linking) is extremely slow
+
+Compiling Catch2 with MinGW can be exceedingly slow, especially during
+the linking step. As far as we can tell, this is caused by deficiencies
+in its default linker. If you can tell MinGW to instead use lld, via
+`-fuse-ld=lld`, the link time should drop down to reasonable length
+again.
+
+
 ## Features
 This section outlines some missing features, what is their status and their possible workarounds.
 
diff --git a/packages/Catch2/docs/matchers.md b/packages/Catch2/docs/matchers.md
index af2071e375e7ecafcf26e7b3053512ee4cf5bf3c..bdb7dac473534bbf12663d7ba104e65b1ecef512 100644
--- a/packages/Catch2/docs/matchers.md
+++ b/packages/Catch2/docs/matchers.md
@@ -17,7 +17,7 @@ For example, to assert that a string ends with a certain substring:
 using Catch::Matchers::EndsWith; // or Catch::EndsWith
 std::string str = getStringFromSomewhere();
 REQUIRE_THAT( str, EndsWith( "as a service" ) );
- ```
+```
 
 The matcher objects can take multiple arguments, allowing more fine tuning.
 The built-in string matchers, for example, take a second argument specifying whether the comparison is
@@ -35,6 +35,22 @@ REQUIRE_THAT( str,
     (StartsWith( "Big data" ) && !Contains( "web scale" ) ) );
 ```
 
+_The combining operators do not take ownership of the matcher objects.
+This means that if you store the combined object, you have to ensure that
+the matcher objects outlive its last use. What this means is that code
+like this leads to a use-after-free and (hopefully) a crash:_
+
+```cpp
+TEST_CASE("Bugs, bugs, bugs", "[Bug]"){
+    std::string str = "Bugs as a service";
+
+    auto match_expression = Catch::EndsWith( "as a service" ) ||
+        (Catch::StartsWith( "Big data" ) && !Catch::Contains( "web scale" ) );
+    REQUIRE_THAT(str, match_expression);
+}
+```
+
+
 ## Built in matchers
 Catch2 provides some matchers by default. They can be found in the
 `Catch::Matchers::foo` namespace and are imported into the `Catch`
diff --git a/packages/Catch2/docs/release-notes.md b/packages/Catch2/docs/release-notes.md
index 0af35c679808971f638333f3b98458b0d0f80722..aef09bf095c7114e6bead21f7389b666503aaed7 100644
--- a/packages/Catch2/docs/release-notes.md
+++ b/packages/Catch2/docs/release-notes.md
@@ -2,6 +2,8 @@
 
 # Release notes
 **Contents**<br>
+[2.10.2](#2102)<br>
+[2.10.1](#2101)<br>
 [2.10.0](#2100)<br>
 [2.9.2](#292)<br>
 [2.9.1](#291)<br>
@@ -29,6 +31,34 @@
 [Even Older versions](#even-older-versions)<br>
 
 
+## 2.10.2
+
+### Improvements
+* Catch2 will now compile on platform where `INFINITY` is double (#1782)
+
+
+### Fixes
+* Warning suppressed during listener registration will no longer leak
+
+
+
+## 2.10.1
+
+### Improvements
+* Catch2 now guards itself against `min` and `max` macros from `windows.h` (#1772)
+* Templated tests will now compile with ICC (#1748)
+* `WithinULP` matcher now uses scientific notation for stringification (#1760)
+
+
+### Fixes
+* Templated tests no longer trigger `-Wunused-templates` (#1762)
+* Suppressed clang-analyzer false positive in context getter (#1230, #1735)
+
+
+### Miscellaneous
+* CMake no longer prohibits in-tree build when Catch2 is used as a subproject (#1773, #1774)
+
+
 
 ## 2.10.0
 
diff --git a/packages/Catch2/docs/release-process.md b/packages/Catch2/docs/release-process.md
index 7fa5f7e170e76e3a92488a44289b8f13a566424e..ca48da033056e4836d491b42bc97b81571d6799b 100644
--- a/packages/Catch2/docs/release-process.md
+++ b/packages/Catch2/docs/release-process.md
@@ -42,8 +42,8 @@ Tag version and release title should be same as the new version,
 description should contain the release notes for the current release.
 Single header version of `catch.hpp` *needs* to be attached as a binary,
 as that is where the official download link links to. Preferably
-it should use linux line endings. All non-bundled reporters (Automake,
-TAP, TeamCity) should also be attached as binaries, as they might be
+it should use linux line endings. All non-bundled reporters (Automake, TAP,
+TeamCity, SonarQube) should also be attached as binaries, as they might be
 dependent on a specific version of the single-include header.
 
 Since 2.5.0, the release tag and the "binaries" (headers) should be PGP
diff --git a/packages/Catch2/docs/reporters.md b/packages/Catch2/docs/reporters.md
index 32b3419b5a5ae795fec67da9b5fd04a311577d07..a33e55bf11bf296986105f94e9127eff8c11f684 100644
--- a/packages/Catch2/docs/reporters.md
+++ b/packages/Catch2/docs/reporters.md
@@ -29,6 +29,7 @@ Do this in one source file - the same one you have `CATCH_CONFIG_MAIN` or `CATCH
 Use this when building as part of a TeamCity build to see results as they happen ([code example](../examples/207-Rpt-TeamCityReporter.cpp)).
 * `tap` writes in the TAP ([Test Anything Protocol](https://en.wikipedia.org/wiki/Test_Anything_Protocol)) format.
 * `automake` writes in a format that correspond to [automake  .trs](https://www.gnu.org/software/automake/manual/html_node/Log-files-generation-and-test-results-recording.html) files
+* `sonarqube` writes the [SonarQube Generic Test Data](https://docs.sonarqube.org/latest/analysis/generic-test/) XML format.
 
 You see what reporters are available from the command line by running with `--list-reporters`.
 
diff --git a/packages/Catch2/examples/231-Cfg-OutputStreams.cpp b/packages/Catch2/examples/231-Cfg-OutputStreams.cpp
index efa9997193f2abe1c065e6a2aa3f4b012206e6b3..2f42c297363ccf8fe9a4ec42eaa88de1f1c266b8 100644
--- a/packages/Catch2/examples/231-Cfg-OutputStreams.cpp
+++ b/packages/Catch2/examples/231-Cfg-OutputStreams.cpp
@@ -10,11 +10,12 @@
 #define CATCH_CONFIG_MAIN
 #include <catch2/catch.hpp>
 
+
 class out_buff : public std::stringbuf {
     std::FILE* m_stream;
 public:
-    out_buff(std::FILE* stream) :m_stream(stream) {}
-    ~out_buff() { pubsync(); }
+    out_buff(std::FILE* stream):m_stream(stream) {}
+    ~out_buff();
     int sync() {
         int ret = 0;
         for (unsigned char c : str()) {
@@ -29,6 +30,12 @@ public:
     }
 };
 
+out_buff::~out_buff() { pubsync(); }
+
+#if defined(__clang__)
+#pragma clang diagnostic ignored "-Wexit-time-destructors" // static variables in cout/cerr/clog
+#endif
+
 namespace Catch {
     std::ostream& cout() {
         static std::ostream ret(new out_buff(stdout));
diff --git a/packages/Catch2/examples/301-Gen-MapTypeConversion.cpp b/packages/Catch2/examples/301-Gen-MapTypeConversion.cpp
index b6377e99dda2da8f9b3a2a098497297e5b127abf..88772971444e0cdb520139aeef16c224b16bddad 100644
--- a/packages/Catch2/examples/301-Gen-MapTypeConversion.cpp
+++ b/packages/Catch2/examples/301-Gen-MapTypeConversion.cpp
@@ -22,15 +22,17 @@ public:
         }
     }
 
-    std::string const& get() const override {
-        return m_line;
-    }
+    std::string const& get() const override;
     
     bool next() override {
         return !!std::getline(m_stream, m_line);
     }
 };
 
+std::string const& LineGenerator::get() const {
+    return m_line;
+}
+
 // This helper function provides a nicer UX when instantiating the generator
 // Notice that it returns an instance of GeneratorWrapper<std::string>, which
 // is a value-wrapper around std::unique_ptr<IGenerator<std::string>>.
diff --git a/packages/Catch2/include/catch.hpp b/packages/Catch2/include/catch.hpp
index 5d38092e0bc2dbe697b12a91eb7f545d74429018..805939ae18958e1d76904e276938f5300b81c963 100644
--- a/packages/Catch2/include/catch.hpp
+++ b/packages/Catch2/include/catch.hpp
@@ -11,7 +11,7 @@
 
 #define CATCH_VERSION_MAJOR 2
 #define CATCH_VERSION_MINOR 10
-#define CATCH_VERSION_PATCH 0
+#define CATCH_VERSION_PATCH 2
 
 #ifdef __clang__
 #    pragma clang system_header
diff --git a/packages/Catch2/include/internal/benchmark/catch_benchmark.hpp b/packages/Catch2/include/internal/benchmark/catch_benchmark.hpp
index 3c061210798a8db1a16f32a84e75db62d4bf7a7d..d9887eba75c18ad4804ae956a834713a26f65f17 100644
--- a/packages/Catch2/include/internal/benchmark/catch_benchmark.hpp
+++ b/packages/Catch2/include/internal/benchmark/catch_benchmark.hpp
@@ -79,7 +79,7 @@ namespace Catch {
                     });
 
                     auto analysis = Detail::analyse(*cfg, env, samples.begin(), samples.end());
-                    BenchmarkStats<std::chrono::duration<double, std::nano>> stats{ info, analysis.samples, analysis.mean, analysis.standard_deviation, analysis.outliers, analysis.outlier_variance };
+                    BenchmarkStats<FloatDuration<Clock>> stats{ info, analysis.samples, analysis.mean, analysis.standard_deviation, analysis.outliers, analysis.outlier_variance };
                     getResultCapture().benchmarkEnded(stats);
 
                 } CATCH_CATCH_ALL{
diff --git a/packages/Catch2/include/internal/benchmark/detail/catch_stats.cpp b/packages/Catch2/include/internal/benchmark/detail/catch_stats.cpp
index 40e0ea9842e26f5ebf4a4e5a6f5a34e65918154e..b85b740ea3b2100d2d19467ec49140df8ba2274a 100644
--- a/packages/Catch2/include/internal/benchmark/detail/catch_stats.cpp
+++ b/packages/Catch2/include/internal/benchmark/detail/catch_stats.cpp
@@ -176,9 +176,10 @@ namespace Catch {
 
 
             bootstrap_analysis analyse_samples(double confidence_level, int n_resamples, std::vector<double>::iterator first, std::vector<double>::iterator last) {
+                CATCH_INTERNAL_START_WARNINGS_SUPPRESSION
                 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
                 static std::random_device entropy;
-                CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
+                CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
 
                 auto n = static_cast<int>(last - first); // seriously, one can't use integral types without hell in C++
 
diff --git a/packages/Catch2/include/internal/catch_capture.hpp b/packages/Catch2/include/internal/catch_capture.hpp
index 303e891ac27ed67b9ebea48e9cd664df2a468831..ba842c3efd2e78a95d56854b8f4c1bfa64ad0055 100644
--- a/packages/Catch2/include/internal/catch_capture.hpp
+++ b/packages/Catch2/include/internal/catch_capture.hpp
@@ -43,9 +43,10 @@
     do { \
         Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
         INTERNAL_CATCH_TRY { \
+            CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
             CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
             catchAssertionHandler.handleExpr( Catch::Decomposer() <= __VA_ARGS__ ); \
-            CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
+            CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
         } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
     } while( (void)0, (false) && static_cast<bool>( !!(__VA_ARGS__) ) ) // the expression here is never evaluated at runtime but it forces the compiler to give it a look
diff --git a/packages/Catch2/include/internal/catch_compiler_capabilities.h b/packages/Catch2/include/internal/catch_compiler_capabilities.h
index 4daa5e8ffaec9d07e0bdb2e296334ca8ba2928e8..18128a836d8ce45f9dd42349c0770e09359f481a 100644
--- a/packages/Catch2/include/internal/catch_compiler_capabilities.h
+++ b/packages/Catch2/include/internal/catch_compiler_capabilities.h
@@ -43,38 +43,34 @@
 #  define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
 #endif
 
-#ifdef __clang__
-
-#       define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
-            _Pragma( "clang diagnostic push" ) \
-            _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \
-            _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"")
-#       define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
-            _Pragma( "clang diagnostic pop" )
-
-#       define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
-            _Pragma( "clang diagnostic push" ) \
-            _Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
-#       define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
-            _Pragma( "clang diagnostic pop" )
-
-#       define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
-            _Pragma( "clang diagnostic push" ) \
-            _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" )
-#       define CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS \
-            _Pragma( "clang diagnostic pop" )
-
-#       define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
-            _Pragma( "clang diagnostic push" ) \
-            _Pragma( "clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"" )
-#       define CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS \
-            _Pragma( "clang diagnostic pop" )
-
-#       define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
-            _Pragma( "clang diagnostic push" ) \
-            _Pragma( "clang diagnostic ignored \"-Wunused-template\"" )
-#       define CATCH_INTERNAL_UNSUPPRESS_UNUSED_TEMPLATE_WARNINGS \
-            _Pragma( "clang diagnostic pop" )
+// We have to avoid both ICC and Clang, because they try to mask themselves
+// as gcc, and we want only GCC in this block
+#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC)
+#    define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic push" )
+#    define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION  _Pragma( "GCC diagnostic pop" )
+#endif
+
+#if defined(__clang__)
+
+#    define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic push" )
+#    define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION  _Pragma( "clang diagnostic pop" )
+
+#    define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
+         _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \
+         _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"")
+
+#    define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
+         _Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
+
+#    define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
+         _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" )
+
+#    define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
+         _Pragma( "clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"" )
+
+#    define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
+         _Pragma( "clang diagnostic ignored \"-Wunused-template\"" )
+
 #endif // __clang__
 
 
@@ -133,8 +129,10 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 // Visual C++
-#ifdef _MSC_VER
+#if defined(_MSC_VER)
 
+#  define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) )
+#  define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION  __pragma( warning(pop) )
 
 #  if _MSC_VER >= 1900 // Visual Studio 2015 or newer
 #    define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
@@ -309,34 +307,37 @@
 #  define CATCH_CONFIG_GLOBAL_NEXTAFTER
 #endif
 
+
+// Even if we do not think the compiler has that warning, we still have
+// to provide a macro that can be used by the code.
+#if !defined(CATCH_INTERNAL_START_WARNINGS_SUPPRESSION)
+#   define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION
+#endif
+#if !defined(CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION)
+#   define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
+#endif
 #if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
 #   define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
-#   define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS
 #endif
 #if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS)
 #   define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
-#   define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
 #endif
 #if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS)
 #   define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS
-#   define CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS
 #endif
 #if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS)
 #   define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS
-#   define CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS
 #endif
 
+
 #if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10)
 #   undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
-#   undef CATCH_INTERNAL_UNSUPPRESS_UNUSED_TEMPLATE_WARNINGS
 #elif defined(__clang__) && (__clang_major__ < 5)
 #   undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
-#   undef CATCH_INTERNAL_UNSUPPRESS_UNUSED_TEMPLATE_WARNINGS
 #endif
 
 #if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS)
 #   define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
-#   define CATCH_INTERNAL_UNSUPPRESS_UNUSED_TEMPLATE_WARNINGS
 #endif
 
 #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
diff --git a/packages/Catch2/include/internal/catch_generators_generic.hpp b/packages/Catch2/include/internal/catch_generators_generic.hpp
index 81fd38578834e5e8b5063acc75f3d609b8e68c92..c34101479584b97c7e2cde0b92fd46592573875c 100644
--- a/packages/Catch2/include/internal/catch_generators_generic.hpp
+++ b/packages/Catch2/include/internal/catch_generators_generic.hpp
@@ -8,6 +8,7 @@
 #define TWOBLUECUBES_CATCH_GENERATORS_GENERIC_HPP_INCLUDED
 
 #include "catch_generators.hpp"
+#include "catch_meta.hpp"
 
 namespace Catch {
 namespace Generators {
@@ -172,18 +173,7 @@ namespace Generators {
         }
     };
 
-#if defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703
-    // std::result_of is deprecated in C++17 and removed in C++20. Hence, it is
-    // replaced with std::invoke_result here. Also *_t format is preferred over
-    // typename *::type format.
-    template <typename Func, typename U>
-    using MapFunctionReturnType = std::remove_reference_t<std::remove_cv_t<std::invoke_result_t<Func, U>>>;
-#else
-    template <typename Func, typename U>
-    using MapFunctionReturnType = typename std::remove_reference<typename std::remove_cv<typename std::result_of<Func(U)>::type>::type>::type;
-#endif
-
-    template <typename Func, typename U, typename T = MapFunctionReturnType<Func, U>>
+    template <typename Func, typename U, typename T = FunctionReturnType<Func, U>>
     GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) {
         return GeneratorWrapper<T>(
             pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator))
diff --git a/packages/Catch2/include/internal/catch_generators_specific.hpp b/packages/Catch2/include/internal/catch_generators_specific.hpp
index f57d29b6214063c2e672d1505bf68b26c696e78d..dee8e711ab12e636052125879e3d1a4cad667446 100644
--- a/packages/Catch2/include/internal/catch_generators_specific.hpp
+++ b/packages/Catch2/include/internal/catch_generators_specific.hpp
@@ -117,7 +117,7 @@ public:
 
 template <typename T>
 GeneratorWrapper<T> range(T const& start, T const& end, T const& step) {
-    static_assert(std::is_integral<T>::value && !std::is_same<T, bool>::value, "Type must be an integer");
+    static_assert(std::is_arithmetic<T>::value && !std::is_same<T, bool>::value, "Type must be numeric");
     return GeneratorWrapper<T>(pf::make_unique<RangeGenerator<T>>(start, end, step));
 }
 
diff --git a/packages/Catch2/include/internal/catch_interfaces_exception.h b/packages/Catch2/include/internal/catch_interfaces_exception.h
index 430701cb8028cf9d04dd39c80e0792b59075813a..d3254d5f244cda720125d823589556f80c404c91 100644
--- a/packages/Catch2/include/internal/catch_interfaces_exception.h
+++ b/packages/Catch2/include/internal/catch_interfaces_exception.h
@@ -73,9 +73,10 @@ namespace Catch {
 ///////////////////////////////////////////////////////////////////////////////
 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \
     static std::string translatorName( signature ); \
+    CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
     CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
     namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); } \
-    CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
+    CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
     static std::string translatorName( signature )
 
 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
diff --git a/packages/Catch2/include/internal/catch_matchers_floating.cpp b/packages/Catch2/include/internal/catch_matchers_floating.cpp
index 68fd1bda0541b93bf62e4f04b1eaeb4cb4ddb340..c226fc56c9eda58ebb96c45c55ae9d761fe7f026 100644
--- a/packages/Catch2/include/internal/catch_matchers_floating.cpp
+++ b/packages/Catch2/include/internal/catch_matchers_floating.cpp
@@ -188,9 +188,10 @@ namespace Floating {
             ret << ", ";
             write(ret, step(m_target, static_cast<double>( INFINITY), m_ulps));
         } else {
-            write(ret, step(static_cast<float>(m_target), -INFINITY, m_ulps));
+            // We have to cast INFINITY to float because of MinGW, see #1782
+            write(ret, step(static_cast<float>(m_target), static_cast<float>(-INFINITY), m_ulps));
             ret << ", ";
-            write(ret, step(static_cast<float>(m_target),  INFINITY, m_ulps));
+            write(ret, step(static_cast<float>(m_target), static_cast<float>( INFINITY), m_ulps));
         }
         ret << "])";
 
diff --git a/packages/Catch2/include/internal/catch_meta.hpp b/packages/Catch2/include/internal/catch_meta.hpp
index 8529766da4ea576fb5fcafe700f0f61b9caaf9f3..4eca7efc2043079d773477c15bfb52b2f2666262 100644
--- a/packages/Catch2/include/internal/catch_meta.hpp
+++ b/packages/Catch2/include/internal/catch_meta.hpp
@@ -12,22 +12,34 @@
 #include <type_traits>
 
 namespace Catch {
-template<typename T>
-struct always_false : std::false_type {};
+    template<typename T>
+    struct always_false : std::false_type {};
 
-template <typename> struct true_given : std::true_type {};
-struct is_callable_tester {
-    template <typename Fun, typename... Args>
-    true_given<decltype(std::declval<Fun>()(std::declval<Args>()...))> static test(int);
-    template <typename...>
-    std::false_type static test(...);
-};
+    template <typename> struct true_given : std::true_type {};
+    struct is_callable_tester {
+        template <typename Fun, typename... Args>
+        true_given<decltype(std::declval<Fun>()(std::declval<Args>()...))> static test(int);
+        template <typename...>
+        std::false_type static test(...);
+    };
 
-template <typename T>
-struct is_callable;
+    template <typename T>
+    struct is_callable;
 
-template <typename Fun, typename... Args>
-struct is_callable<Fun(Args...)> : decltype(is_callable_tester::test<Fun, Args...>(0)) {};
+    template <typename Fun, typename... Args>
+    struct is_callable<Fun(Args...)> : decltype(is_callable_tester::test<Fun, Args...>(0)) {};
+
+
+#if defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703
+    // std::result_of is deprecated in C++17 and removed in C++20. Hence, it is
+    // replaced with std::invoke_result here. Also *_t format is preferred over
+    // typename *::type format.
+    template <typename Func, typename U>
+    using FunctionReturnType = std::remove_reference_t<std::remove_cv_t<std::invoke_result_t<Func, U>>>;
+#else
+    template <typename Func, typename U>
+    using FunctionReturnType = typename std::remove_reference<typename std::remove_cv<typename std::result_of<Func(U)>::type>::type>::type;
+#endif
 
 } // namespace Catch
 
diff --git a/packages/Catch2/include/internal/catch_reporter_registrars.hpp b/packages/Catch2/include/internal/catch_reporter_registrars.hpp
index 660f554ababe5f2a9728126d80df2433f81c4134..a1950536621e6935e4baf124d1a90dd49eae1d30 100644
--- a/packages/Catch2/include/internal/catch_reporter_registrars.hpp
+++ b/packages/Catch2/include/internal/catch_reporter_registrars.hpp
@@ -58,14 +58,16 @@ namespace Catch {
 #if !defined(CATCH_CONFIG_DISABLE)
 
 #define CATCH_REGISTER_REPORTER( name, reporterType ) \
+    CATCH_INTERNAL_START_WARNINGS_SUPPRESSION         \
     CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS          \
     namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); } \
-    CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
+    CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
 
 #define CATCH_REGISTER_LISTENER( listenerType ) \
-     CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS   \
-     namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; } \
-     CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
+    CATCH_INTERNAL_START_WARNINGS_SUPPRESSION   \
+    CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS    \
+    namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; } \
+    CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
 #else // CATCH_CONFIG_DISABLE
 
 #define CATCH_REGISTER_REPORTER(name, reporterType)
diff --git a/packages/Catch2/include/internal/catch_section.h b/packages/Catch2/include/internal/catch_section.h
index 00c254b67168d6f310b0da60858f38c7d8c99be2..cc2b323dd5f63334f77c2b41e9d539d4a2c4c0e3 100644
--- a/packages/Catch2/include/internal/catch_section.h
+++ b/packages/Catch2/include/internal/catch_section.h
@@ -37,13 +37,15 @@ namespace Catch {
 } // end namespace Catch
 
 #define INTERNAL_CATCH_SECTION( ... ) \
+    CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
     CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
     if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) \
-    CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS
+    CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
 
 #define INTERNAL_CATCH_DYNAMIC_SECTION( ... ) \
+    CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
     CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
     if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, (Catch::ReusableStringStream() << __VA_ARGS__).str() ) ) \
-    CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS
+    CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
 
 #endif // TWOBLUECUBES_CATCH_SECTION_H_INCLUDED
diff --git a/packages/Catch2/include/internal/catch_stream.h b/packages/Catch2/include/internal/catch_stream.h
index 2b41adbd9ed28ba30311b827e9ddd7fcdfcec163..999849c9cc05ea52e3c4d13cbe582616c5c3160b 100644
--- a/packages/Catch2/include/internal/catch_stream.h
+++ b/packages/Catch2/include/internal/catch_stream.h
@@ -9,6 +9,8 @@
 #ifndef TWOBLUECUBES_CATCH_STREAM_H_INCLUDED
 #define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED
 
+#include "catch_common.h"
+
 #include <iosfwd>
 #include <cstddef>
 #include <ostream>
@@ -28,7 +30,7 @@ namespace Catch {
 
     auto makeStream( StringRef const &filename ) -> IStream const*;
 
-    class ReusableStringStream {
+    class ReusableStringStream : NonCopyable {
         std::size_t m_index;
         std::ostream* m_oss;
     public:
diff --git a/packages/Catch2/include/internal/catch_stringref.cpp b/packages/Catch2/include/internal/catch_stringref.cpp
index b46414ac350455119e1e6781ba079ff108eeb634..215feef3cf0882c9420f7093ca5c1ea44fb2f558 100644
--- a/packages/Catch2/include/internal/catch_stringref.cpp
+++ b/packages/Catch2/include/internal/catch_stringref.cpp
@@ -5,14 +5,10 @@
  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  */
 
-
-#if defined(__clang__)
-#    pragma clang diagnostic push
-#    pragma clang diagnostic ignored "-Wexit-time-destructors"
-#endif
-
+#include "catch_enforce.h"
 #include "catch_stringref.h"
 
+#include <algorithm>
 #include <ostream>
 #include <cstring>
 #include <cstdint>
@@ -22,63 +18,33 @@ namespace Catch {
     : StringRef( rawChars, static_cast<StringRef::size_type>(std::strlen(rawChars) ) )
     {}
 
-    void StringRef::swap( StringRef& other ) noexcept {
-        std::swap( m_start, other.m_start );
-        std::swap( m_size, other.m_size );
-        std::swap( m_data, other.m_data );
-    }
-
     auto StringRef::c_str() const -> char const* {
-        if( !isSubstring() )
-            return m_start;
-
-        const_cast<StringRef *>( this )->takeOwnership();
-        return m_data;
-    }
-    auto StringRef::currentData() const noexcept -> char const* {
+        CATCH_ENFORCE(isNullTerminated(), "Called StringRef::c_str() on a non-null-terminated instance");
         return m_start;
     }
-
-    auto StringRef::isOwned() const noexcept -> bool {
-        return m_data != nullptr;
-    }
-    auto StringRef::isSubstring() const noexcept -> bool {
-        return m_start[m_size] != '\0';
+    auto StringRef::data() const noexcept -> char const* {
+        return m_start;
     }
 
-    void StringRef::takeOwnership() {
-        if( !isOwned() ) {
-            m_data = new char[m_size+1];
-            memcpy( m_data, m_start, m_size );
-            m_data[m_size] = '\0';
-        }
-    }
     auto StringRef::substr( size_type start, size_type size ) const noexcept -> StringRef {
-        if( start < m_size )
-            return StringRef( m_start+start, size );
-        else
+        if (start < m_size) {
+            return StringRef(m_start + start, (std::min)(m_size - start, size));
+        } else {
             return StringRef();
+        }
     }
     auto StringRef::operator == ( StringRef const& other ) const noexcept -> bool {
-        return
-            size() == other.size() &&
-            (std::strncmp( m_start, other.m_start, size() ) == 0);
-    }
-    auto StringRef::operator != ( StringRef const& other ) const noexcept -> bool {
-        return !operator==( other );
+        return m_size == other.m_size
+            && (std::memcmp( m_start, other.m_start, m_size ) == 0);
     }
 
     auto operator << ( std::ostream& os, StringRef const& str ) -> std::ostream& {
-        return os.write(str.currentData(), str.size());
+        return os.write(str.data(), str.size());
     }
 
     auto operator+=( std::string& lhs, StringRef const& rhs ) -> std::string& {
-        lhs.append(rhs.currentData(), rhs.size());
+        lhs.append(rhs.data(), rhs.size());
         return lhs;
     }
 
 } // namespace Catch
-
-#if defined(__clang__)
-#    pragma clang diagnostic pop
-#endif
diff --git a/packages/Catch2/include/internal/catch_stringref.h b/packages/Catch2/include/internal/catch_stringref.h
index a45147da1d3b687233dd3d3c22a3ce5f0aa9f351..dc2e748c760205a5b34f764759015bcc3794aa2e 100644
--- a/packages/Catch2/include/internal/catch_stringref.h
+++ b/packages/Catch2/include/internal/catch_stringref.h
@@ -16,49 +16,24 @@ namespace Catch {
 
     /// A non-owning string class (similar to the forthcoming std::string_view)
     /// Note that, because a StringRef may be a substring of another string,
-    /// it may not be null terminated. c_str() must return a null terminated
-    /// string, however, and so the StringRef will internally take ownership
-    /// (taking a copy), if necessary. In theory this ownership is not externally
-    /// visible - but it does mean (substring) StringRefs should not be shared between
-    /// threads.
+    /// it may not be null terminated.
     class StringRef {
     public:
         using size_type = std::size_t;
         using const_iterator = const char*;
 
     private:
-        friend struct StringRefTestAccess;
-
-        char const* m_start;
-        size_type m_size;
-
-        char* m_data = nullptr;
-
-        void takeOwnership();
-
         static constexpr char const* const s_empty = "";
 
-    public: // construction/ assignment
-        StringRef() noexcept
-        :   StringRef( s_empty, 0 )
-        {}
+        char const* m_start = s_empty;
+        size_type m_size = 0;
 
-        StringRef( StringRef const& other ) noexcept
-        :   m_start( other.m_start ),
-            m_size( other.m_size )
-        {}
-
-        StringRef( StringRef&& other ) noexcept
-        :   m_start( other.m_start ),
-            m_size( other.m_size ),
-            m_data( other.m_data )
-        {
-            other.m_data = nullptr;
-        }
+    public: // construction
+        constexpr StringRef() noexcept = default;
 
         StringRef( char const* rawChars ) noexcept;
 
-        StringRef( char const* rawChars, size_type size ) noexcept
+        constexpr StringRef( char const* rawChars, size_type size ) noexcept
         :   m_start( rawChars ),
             m_size( size )
         {}
@@ -68,27 +43,15 @@ namespace Catch {
             m_size( stdString.size() )
         {}
 
-        ~StringRef() noexcept {
-            delete[] m_data;
-        }
-
-        auto operator = ( StringRef const &other ) noexcept -> StringRef& {
-            delete[] m_data;
-            m_data = nullptr;
-            m_start = other.m_start;
-            m_size = other.m_size;
-            return *this;
-        }
-
         explicit operator std::string() const {
             return std::string(m_start, m_size);
         }
 
-        void swap( StringRef& other ) noexcept;
-
     public: // operators
         auto operator == ( StringRef const& other ) const noexcept -> bool;
-        auto operator != ( StringRef const& other ) const noexcept -> bool;
+        auto operator != (StringRef const& other) const noexcept -> bool {
+            return !(*this == other);
+        }
 
         auto operator[] ( size_type index ) const noexcept -> char {
             assert(index < m_size);
@@ -96,42 +59,45 @@ namespace Catch {
         }
 
     public: // named queries
-        auto empty() const noexcept -> bool {
+        constexpr auto empty() const noexcept -> bool {
             return m_size == 0;
         }
-        auto size() const noexcept -> size_type {
+        constexpr auto size() const noexcept -> size_type {
             return m_size;
         }
 
+        // Returns the current start pointer. If the StringRef is not
+        // null-terminated, throws std::domain_exception
         auto c_str() const -> char const*;
 
     public: // substrings and searches
-        auto substr( size_type start, size_type size ) const noexcept -> StringRef;
+        // Returns a substring of [start, start + length).
+        // If start + length > size(), then the substring is [start, size()).
+        // If start > size(), then the substring is empty.
+        auto substr( size_type start, size_type length ) const noexcept -> StringRef;
 
-        // Returns the current start pointer.
-        // Note that the pointer can change when if the StringRef is a substring
-        auto currentData() const noexcept -> char const*;
+        // Returns the current start pointer. May not be null-terminated.
+        auto data() const noexcept -> char const*;
 
-    public: // iterators
-        const_iterator begin() const { return m_start; }
-        const_iterator end() const { return m_start + m_size; }
+        constexpr auto isNullTerminated() const noexcept -> bool {
+            return m_start[m_size] == '\0';
+        }
 
-    private: // ownership queries - may not be consistent between calls
-        auto isOwned() const noexcept -> bool;
-        auto isSubstring() const noexcept -> bool;
+    public: // iterators
+        constexpr const_iterator begin() const { return m_start; }
+        constexpr const_iterator end() const { return m_start + m_size; }
     };
 
     auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&;
     auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&;
 
 
-    inline auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef {
+    constexpr auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef {
         return StringRef( rawChars, size );
     }
-
 } // namespace Catch
 
-inline auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef {
+constexpr auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef {
     return Catch::StringRef( rawChars, size );
 }
 
diff --git a/packages/Catch2/include/internal/catch_tag_alias_autoregistrar.h b/packages/Catch2/include/internal/catch_tag_alias_autoregistrar.h
index 32a5734eff6c9d5647121a66931797a55b42f0b7..ebba8e25b2fb37da0adc4fc4aa982a5e2a39c37f 100644
--- a/packages/Catch2/include/internal/catch_tag_alias_autoregistrar.h
+++ b/packages/Catch2/include/internal/catch_tag_alias_autoregistrar.h
@@ -18,8 +18,9 @@ namespace Catch {
 } // end namespace Catch
 
 #define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \
+    CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
     CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
     namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \
-    CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
+    CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
 
 #endif // TWOBLUECUBES_CATCH_TAG_ALIAS_AUTOREGISTRAR_H_INCLUDED
diff --git a/packages/Catch2/include/internal/catch_test_registry.h b/packages/Catch2/include/internal/catch_test_registry.h
index dd1ccfcc87daeded23775b90b9a021830923f0bd..c9624fc7d12e44bc89ded3c40ef98d7ed75c1859 100644
--- a/packages/Catch2/include/internal/catch_test_registry.h
+++ b/packages/Catch2/include/internal/catch_test_registry.h
@@ -75,7 +75,7 @@ struct AutoReg : NonCopyable {
     #else
         #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \
             INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ ) )
-    #endif  
+    #endif
 
     #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
         #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \
@@ -105,21 +105,24 @@ struct AutoReg : NonCopyable {
     ///////////////////////////////////////////////////////////////////////////////
     #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
         static void TestName(); \
+        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
         namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
-        CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
+        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
         static void TestName()
     #define INTERNAL_CATCH_TESTCASE( ... ) \
         INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ )
 
     ///////////////////////////////////////////////////////////////////////////////
     #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
+        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
         namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, "&" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
-        CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
+        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
 
     ///////////////////////////////////////////////////////////////////////////////
     #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
+        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
         namespace{ \
             struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
@@ -127,19 +130,21 @@ struct AutoReg : NonCopyable {
             }; \
             Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
         } \
-        CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
+        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
         void TestName::test()
     #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
         INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ )
 
     ///////////////////////////////////////////////////////////////////////////////
     #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
+        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
         Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
-        CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
+        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
 
     ///////////////////////////////////////////////////////////////////////////////
     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_2(TestName, TestFunc, Name, Tags, Signature, ... )\
+        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
         CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
         CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
@@ -164,9 +169,7 @@ struct AutoReg : NonCopyable {
         }();\
         }\
         }\
-        CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
-        CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS \
-        CATCH_INTERNAL_UNSUPPRESS_UNUSED_TEMPLATE_WARNINGS \
+        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
         INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc,INTERNAL_CATCH_REMOVE_PARENS(Signature))
 
 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
@@ -175,7 +178,7 @@ struct AutoReg : NonCopyable {
 #else
     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
         INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ ) )
-#endif  
+#endif
 
 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \
@@ -186,9 +189,10 @@ struct AutoReg : NonCopyable {
 #endif
 
     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(TestName, TestFuncName, Name, Tags, Signature, TmplTypes, TypesList) \
+        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION                      \
         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS                      \
         CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS                \
-        CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS                       \
+        CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS              \
         template<typename TestType> static void TestFuncName();       \
         namespace {\
         namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) {                                     \
@@ -213,9 +217,7 @@ struct AutoReg : NonCopyable {
             }();                                                      \
         }                                                             \
         }                                                             \
-        CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS                    \
-        CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS              \
-        CATCH_INTERNAL_UNSUPPRESS_UNUSED_TEMPLATE_WARNINGS                     \
+        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION                       \
         template<typename TestType>                                   \
         static void TestFuncName()
 
@@ -236,6 +238,7 @@ struct AutoReg : NonCopyable {
 #endif
 
     #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2(TestName, TestFunc, Name, Tags, TmplList)\
+        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
         CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
         template<typename TestType> static void TestFunc();       \
@@ -255,10 +258,9 @@ struct AutoReg : NonCopyable {
                 TestInit t;                                           \
                 t.reg_tests();                                        \
                 return 0;                                             \
-            }();                                                        \
+            }();                                                      \
         }}\
-        CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS                    \
-        CATCH_INTERNAL_UNSUPPRESS_UNUSED_TEMPLATE_WARNINGS \
+        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION                       \
         template<typename TestType>                                   \
         static void TestFunc()
 
@@ -267,6 +269,7 @@ struct AutoReg : NonCopyable {
 
 
     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... ) \
+        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
         CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
         CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
@@ -291,9 +294,7 @@ struct AutoReg : NonCopyable {
         }();\
         }\
         }\
-        CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS\
-        CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS\
-        CATCH_INTERNAL_UNSUPPRESS_UNUSED_TEMPLATE_WARNINGS\
+        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
         INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))
 
 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
@@ -313,6 +314,7 @@ struct AutoReg : NonCopyable {
 #endif
 
     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(TestNameClass, TestName, ClassName, Name, Tags, Signature, TmplTypes, TypesList)\
+        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
         CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
         CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
@@ -343,9 +345,7 @@ struct AutoReg : NonCopyable {
             }(); \
         }\
         }\
-        CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
-        CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS \
-        CATCH_INTERNAL_UNSUPPRESS_UNUSED_TEMPLATE_WARNINGS \
+        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
         template<typename TestType> \
         void TestName<TestType>::test()
 
@@ -366,6 +366,7 @@ struct AutoReg : NonCopyable {
 #endif
 
     #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, TmplList) \
+        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
         CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
         template<typename TestType> \
@@ -390,8 +391,7 @@ struct AutoReg : NonCopyable {
                 return 0;\
             }(); \
         }}\
-        CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
-        CATCH_INTERNAL_UNSUPPRESS_UNUSED_TEMPLATE_WARNINGS \
+        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
         template<typename TestType> \
         void TestName<TestType>::test()
 
diff --git a/packages/Catch2/include/internal/catch_test_spec_parser.cpp b/packages/Catch2/include/internal/catch_test_spec_parser.cpp
index b872b19163ac01742ecac05206b46919cb75c498..dad15c01c9a9d32eb3b076af3d6ff01040748fea 100644
--- a/packages/Catch2/include/internal/catch_test_spec_parser.cpp
+++ b/packages/Catch2/include/internal/catch_test_spec_parser.cpp
@@ -20,10 +20,10 @@ namespace Catch {
         m_substring.reserve(m_arg.size());
         m_patternName.reserve(m_arg.size());
         m_realPatternPos = 0;
-        
+
         for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
           //if visitChar fails
-           if( !visitChar( m_arg[m_pos] ) ){ 
+           if( !visitChar( m_arg[m_pos] ) ){
                m_testSpec.m_invalidArgs.push_back(arg);
                break;
            }
@@ -113,9 +113,9 @@ namespace Catch {
         switch( m_mode ) {
         case Name:
         case QuotedName:
-            return addPattern<TestSpec::NamePattern>();
+            return addNamePattern();
         case Tag:
-            return addPattern<TestSpec::TagPattern>();
+            return addTagPattern();
         case EscapedName:
             revertBackToLastMode();
             return;
@@ -156,12 +156,12 @@ namespace Catch {
     void TestSpecParser::saveLastMode() {
       lastMode = m_mode;
     }
-    
+
     void TestSpecParser::revertBackToLastMode() {
       m_mode = lastMode;
     }
-    
-    bool TestSpecParser::separate() {  
+
+    bool TestSpecParser::separate() {
       if( (m_mode==QuotedName) || (m_mode==Tag) ){
          //invalid argument, signal failure to previous scope.
          m_mode = None;
@@ -174,7 +174,63 @@ namespace Catch {
       addFilter();
       return true; //success
     }
-    
+
+    std::string TestSpecParser::preprocessPattern() {
+        std::string token = m_patternName;
+        for (std::size_t i = 0; i < m_escapeChars.size(); ++i)
+            token = token.substr(0, m_escapeChars[i] - i) + token.substr(m_escapeChars[i] - i + 1);
+        m_escapeChars.clear();
+        if (startsWith(token, "exclude:")) {
+            m_exclusion = true;
+            token = token.substr(8);
+        }
+
+        m_patternName.clear();
+
+        return token;
+    }
+
+    void TestSpecParser::addNamePattern() {
+        auto token = preprocessPattern();
+
+        if (!token.empty()) {
+            TestSpec::PatternPtr pattern = std::make_shared<TestSpec::NamePattern>(token, m_substring);
+            if (m_exclusion)
+                pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);
+            m_currentFilter.m_patterns.push_back(pattern);
+        }
+        m_substring.clear();
+        m_exclusion = false;
+        m_mode = None;
+    }
+
+    void TestSpecParser::addTagPattern() {
+        auto token = preprocessPattern();
+
+        if (!token.empty()) {
+            // If the tag pattern is the "hide and tag" shorthand (e.g. [.foo])
+            // we have to create a separate hide tag and shorten the real one
+            if (token.size() > 1 && token[0] == '.') {
+                token.erase(token.begin());
+                TestSpec::PatternPtr pattern = std::make_shared<TestSpec::TagPattern>(".", m_substring);
+                if (m_exclusion) {
+                    pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);
+                }
+                m_currentFilter.m_patterns.push_back(pattern);
+            }
+
+            TestSpec::PatternPtr pattern = std::make_shared<TestSpec::TagPattern>(token, m_substring);
+
+            if (m_exclusion) {
+                pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);
+            }
+            m_currentFilter.m_patterns.push_back(pattern);
+        }
+        m_substring.clear();
+        m_exclusion = false;
+        m_mode = None;
+    }
+
     TestSpec parseTestSpec( std::string const& arg ) {
         return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
     }
diff --git a/packages/Catch2/include/internal/catch_test_spec_parser.h b/packages/Catch2/include/internal/catch_test_spec_parser.h
index 179d3532e56894a38350ef69ee02d231ddd52079..250d7c163b00448c6c30a73bd6c25e53b9578deb 100644
--- a/packages/Catch2/include/internal/catch_test_spec_parser.h
+++ b/packages/Catch2/include/internal/catch_test_spec_parser.h
@@ -53,35 +53,20 @@ namespace Catch {
         void revertBackToLastMode();
         void addFilter();
         bool separate();
-        
-        template<typename T>
-        void addPattern() {
-            std::string token = m_patternName;
-            for( std::size_t i = 0; i < m_escapeChars.size(); ++i )
-                token = token.substr( 0, m_escapeChars[i] - i ) + token.substr( m_escapeChars[i] -i +1 );
-            m_escapeChars.clear();
-            if( startsWith( token, "exclude:" ) ) {
-                m_exclusion = true;
-                token = token.substr( 8 );
-            }
-            if( !token.empty() ) {
-                TestSpec::PatternPtr pattern = std::make_shared<T>( token, m_substring );
-                if( m_exclusion )
-                    pattern = std::make_shared<TestSpec::ExcludedPattern>( pattern );
-                m_currentFilter.m_patterns.push_back( pattern );
-            }
-            m_substring.clear();
-            m_patternName.clear();
-            m_exclusion = false;
-            m_mode = None;
-        }
-        
+
+        // Handles common preprocessing of the pattern for name/tag patterns
+        std::string preprocessPattern();
+        // Adds the current pattern as a test name
+        void addNamePattern();
+        // Adds the current pattern as a tag
+        void addTagPattern();
+
         inline void addCharToPattern(char c) {
             m_substring += c;
             m_patternName += c;
             m_realPatternPos++;
         }
-        
+
     };
     TestSpec parseTestSpec( std::string const& arg );
 
diff --git a/packages/Catch2/include/internal/catch_tostring.cpp b/packages/Catch2/include/internal/catch_tostring.cpp
index 2f66f49dc5cb9c08faf047e89eaadbd931f5f07f..a289c341d5a7e42cc7f7ba1dc3b0169b33147ed2 100644
--- a/packages/Catch2/include/internal/catch_tostring.cpp
+++ b/packages/Catch2/include/internal/catch_tostring.cpp
@@ -38,13 +38,11 @@ namespace Detail {
             enum Arch { Big, Little };
 
             static Arch which() {
-                union _{
-                    int asInt;
-                    char asChar[sizeof (int)];
-                } u;
-
-                u.asInt = 1;
-                return ( u.asChar[sizeof(int)-1] == 1 ) ? Big : Little;
+                int one = 1;
+                // If the lowest byte we read is non-zero, we can assume
+                // that little endian format is used.
+                auto value = *reinterpret_cast<char*>(&one);
+                return value ? Little : Big;
             }
         };
     }
@@ -241,13 +239,13 @@ std::string StringMaker<std::nullptr_t>::convert(std::nullptr_t) {
 }
 
 int StringMaker<float>::precision = 5;
-   
+
 std::string StringMaker<float>::convert(float value) {
     return fpToString(value, precision) + 'f';
 }
 
 int StringMaker<double>::precision = 10;
-    
+
 std::string StringMaker<double>::convert(double value) {
     return fpToString(value, precision);
 }
diff --git a/packages/Catch2/include/internal/catch_version.cpp b/packages/Catch2/include/internal/catch_version.cpp
index bb5b06163e67f1a8778324be1e679884fecb4b5f..625e11501cc8b5be6e2b0256a18ea2472f8cf4dc 100644
--- a/packages/Catch2/include/internal/catch_version.cpp
+++ b/packages/Catch2/include/internal/catch_version.cpp
@@ -37,7 +37,7 @@ namespace Catch {
     }
 
     Version const& libraryVersion() {
-        static Version version( 2, 10, 0, "", 0 );
+        static Version version( 2, 10, 2, "", 0 );
         return version;
     }
 
diff --git a/packages/Catch2/include/internal/catch_xmlwriter.cpp b/packages/Catch2/include/internal/catch_xmlwriter.cpp
index 5354efa7cd19e205b538c467d584f88197f4ba7b..b0d81ab7f95acf97c632bf37612348983aff5237 100644
--- a/packages/Catch2/include/internal/catch_xmlwriter.cpp
+++ b/packages/Catch2/include/internal/catch_xmlwriter.cpp
@@ -10,6 +10,7 @@
 #include "catch_enforce.h"
 
 #include <iomanip>
+#include <type_traits>
 
 using uchar = unsigned char;
 
@@ -51,8 +52,31 @@ namespace {
         os.flags(f);
     }
 
+    bool shouldNewline(XmlFormatting fmt) {
+        return !!(static_cast<std::underlying_type<XmlFormatting>::type>(fmt & XmlFormatting::Newline));
+    }
+
+    bool shouldIndent(XmlFormatting fmt) {
+        return !!(static_cast<std::underlying_type<XmlFormatting>::type>(fmt & XmlFormatting::Indent));
+    }
+
 } // anonymous namespace
 
+    XmlFormatting operator | (XmlFormatting lhs, XmlFormatting rhs) {
+        return static_cast<XmlFormatting>(
+            static_cast<std::underlying_type<XmlFormatting>::type>(lhs) |
+            static_cast<std::underlying_type<XmlFormatting>::type>(rhs)
+        );
+    }
+
+    XmlFormatting operator & (XmlFormatting lhs, XmlFormatting rhs) {
+        return static_cast<XmlFormatting>(
+            static_cast<std::underlying_type<XmlFormatting>::type>(lhs) &
+            static_cast<std::underlying_type<XmlFormatting>::type>(rhs)
+        );
+    }
+
+
     XmlEncode::XmlEncode( std::string const& str, ForWhat forWhat )
     :   m_str( str ),
         m_forWhat( forWhat )
@@ -157,13 +181,17 @@ namespace {
         return os;
     }
 
-    XmlWriter::ScopedElement::ScopedElement( XmlWriter* writer )
-    :   m_writer( writer )
+    XmlWriter::ScopedElement::ScopedElement( XmlWriter* writer, XmlFormatting fmt )
+    :   m_writer( writer ),
+        m_fmt(fmt)
     {}
 
     XmlWriter::ScopedElement::ScopedElement( ScopedElement&& other ) noexcept
-    :   m_writer( other.m_writer ){
+    :   m_writer( other.m_writer ),
+        m_fmt(other.m_fmt)
+    {
         other.m_writer = nullptr;
+        other.m_fmt = XmlFormatting::None;
     }
     XmlWriter::ScopedElement& XmlWriter::ScopedElement::operator=( ScopedElement&& other ) noexcept {
         if ( m_writer ) {
@@ -171,17 +199,20 @@ namespace {
         }
         m_writer = other.m_writer;
         other.m_writer = nullptr;
+        m_fmt = other.m_fmt;
+        other.m_fmt = XmlFormatting::None;
         return *this;
     }
 
 
     XmlWriter::ScopedElement::~ScopedElement() {
-        if( m_writer )
-            m_writer->endElement();
+        if (m_writer) {
+            m_writer->endElement(m_fmt);
+        }
     }
 
-    XmlWriter::ScopedElement& XmlWriter::ScopedElement::writeText( std::string const& text, bool indent ) {
-        m_writer->writeText( text, indent );
+    XmlWriter::ScopedElement& XmlWriter::ScopedElement::writeText( std::string const& text, XmlFormatting fmt ) {
+        m_writer->writeText( text, fmt );
         return *this;
     }
 
@@ -191,37 +222,47 @@ namespace {
     }
 
     XmlWriter::~XmlWriter() {
-        while( !m_tags.empty() )
+        while (!m_tags.empty()) {
             endElement();
+        }
+        newlineIfNecessary();
     }
 
-    XmlWriter& XmlWriter::startElement( std::string const& name ) {
+    XmlWriter& XmlWriter::startElement( std::string const& name, XmlFormatting fmt ) {
         ensureTagClosed();
         newlineIfNecessary();
-        m_os << m_indent << '<' << name;
+        if (shouldIndent(fmt)) {
+            m_os << m_indent;
+            m_indent += "  ";
+        }
+        m_os << '<' << name;
         m_tags.push_back( name );
-        m_indent += "  ";
         m_tagIsOpen = true;
+        applyFormatting(fmt);
         return *this;
     }
 
-    XmlWriter::ScopedElement XmlWriter::scopedElement( std::string const& name ) {
-        ScopedElement scoped( this );
-        startElement( name );
+    XmlWriter::ScopedElement XmlWriter::scopedElement( std::string const& name, XmlFormatting fmt ) {
+        ScopedElement scoped( this, fmt );
+        startElement( name, fmt );
         return scoped;
     }
 
-    XmlWriter& XmlWriter::endElement() {
-        newlineIfNecessary();
-        m_indent = m_indent.substr( 0, m_indent.size()-2 );
+    XmlWriter& XmlWriter::endElement(XmlFormatting fmt) {
+        m_indent = m_indent.substr(0, m_indent.size() - 2);
+
         if( m_tagIsOpen ) {
             m_os << "/>";
             m_tagIsOpen = false;
+        } else {
+            newlineIfNecessary();
+            if (shouldIndent(fmt)) {
+                m_os << m_indent;
+            }
+            m_os << "</" << m_tags.back() << ">";
         }
-        else {
-            m_os << m_indent << "</" << m_tags.back() << ">";
-        }
-        m_os << std::endl;
+        m_os << std::flush;
+        applyFormatting(fmt);
         m_tags.pop_back();
         return *this;
     }
@@ -237,22 +278,26 @@ namespace {
         return *this;
     }
 
-    XmlWriter& XmlWriter::writeText( std::string const& text, bool indent ) {
+    XmlWriter& XmlWriter::writeText( std::string const& text, XmlFormatting fmt) {
         if( !text.empty() ){
             bool tagWasOpen = m_tagIsOpen;
             ensureTagClosed();
-            if( tagWasOpen && indent )
+            if (tagWasOpen && shouldIndent(fmt)) {
                 m_os << m_indent;
+            }
             m_os << XmlEncode( text );
-            m_needsNewline = true;
+            applyFormatting(fmt);
         }
         return *this;
     }
 
-    XmlWriter& XmlWriter::writeComment( std::string const& text ) {
+    XmlWriter& XmlWriter::writeComment( std::string const& text, XmlFormatting fmt) {
         ensureTagClosed();
-        m_os << m_indent << "<!--" << text << "-->";
-        m_needsNewline = true;
+        if (shouldIndent(fmt)) {
+            m_os << m_indent;
+        }
+        m_os << "<!--" << text << "-->";
+        applyFormatting(fmt);
         return *this;
     }
 
@@ -268,11 +313,16 @@ namespace {
 
     void XmlWriter::ensureTagClosed() {
         if( m_tagIsOpen ) {
-            m_os << ">" << std::endl;
+            m_os << '>' << std::flush;
+            newlineIfNecessary();
             m_tagIsOpen = false;
         }
     }
 
+    void XmlWriter::applyFormatting(XmlFormatting fmt) {
+        m_needsNewline = shouldNewline(fmt);
+    }
+
     void XmlWriter::writeDeclaration() {
         m_os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
     }
diff --git a/packages/Catch2/include/internal/catch_xmlwriter.h b/packages/Catch2/include/internal/catch_xmlwriter.h
index c4b1c035abaf1bdc019cee8e259acca400bd3326..f551b2331f825492d71e483ba5ba1631e2376f26 100644
--- a/packages/Catch2/include/internal/catch_xmlwriter.h
+++ b/packages/Catch2/include/internal/catch_xmlwriter.h
@@ -14,6 +14,14 @@
 #include <vector>
 
 namespace Catch {
+    enum class XmlFormatting {
+        None = 0x00,
+        Indent = 0x01,
+        Newline = 0x02,
+    };
+
+    XmlFormatting operator | (XmlFormatting lhs, XmlFormatting rhs);
+    XmlFormatting operator & (XmlFormatting lhs, XmlFormatting rhs);
 
     class XmlEncode {
     public:
@@ -35,14 +43,14 @@ namespace Catch {
 
         class ScopedElement {
         public:
-            ScopedElement( XmlWriter* writer );
+            ScopedElement( XmlWriter* writer, XmlFormatting fmt );
 
             ScopedElement( ScopedElement&& other ) noexcept;
             ScopedElement& operator=( ScopedElement&& other ) noexcept;
 
             ~ScopedElement();
 
-            ScopedElement& writeText( std::string const& text, bool indent = true );
+            ScopedElement& writeText( std::string const& text, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent );
 
             template<typename T>
             ScopedElement& writeAttribute( std::string const& name, T const& attribute ) {
@@ -52,6 +60,7 @@ namespace Catch {
 
         private:
             mutable XmlWriter* m_writer = nullptr;
+            XmlFormatting m_fmt;
         };
 
         XmlWriter( std::ostream& os = Catch::cout() );
@@ -60,11 +69,11 @@ namespace Catch {
         XmlWriter( XmlWriter const& ) = delete;
         XmlWriter& operator=( XmlWriter const& ) = delete;
 
-        XmlWriter& startElement( std::string const& name );
+        XmlWriter& startElement( std::string const& name, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
 
-        ScopedElement scopedElement( std::string const& name );
+        ScopedElement scopedElement( std::string const& name, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
 
-        XmlWriter& endElement();
+        XmlWriter& endElement(XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
 
         XmlWriter& writeAttribute( std::string const& name, std::string const& attribute );
 
@@ -77,9 +86,9 @@ namespace Catch {
             return writeAttribute( name, rss.str() );
         }
 
-        XmlWriter& writeText( std::string const& text, bool indent = true );
+        XmlWriter& writeText( std::string const& text, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
 
-        XmlWriter& writeComment( std::string const& text );
+        XmlWriter& writeComment(std::string const& text, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
 
         void writeStylesheetRef( std::string const& url );
 
@@ -89,6 +98,8 @@ namespace Catch {
 
     private:
 
+        void applyFormatting(XmlFormatting fmt);
+
         void writeDeclaration();
 
         void newlineIfNecessary();
diff --git a/packages/Catch2/include/reporters/catch_reporter_junit.cpp b/packages/Catch2/include/reporters/catch_reporter_junit.cpp
index e837586223773aeffdefa26335804e94707f250c..820b574fdd2de326fb55c17f3e5c8aa31c671090 100644
--- a/packages/Catch2/include/reporters/catch_reporter_junit.cpp
+++ b/packages/Catch2/include/reporters/catch_reporter_junit.cpp
@@ -12,6 +12,7 @@
 
 #include "../internal/catch_tostring.h"
 #include "../internal/catch_reporter_registrars.hpp"
+#include "../internal/catch_text.h"
 
 #include <cassert>
 #include <sstream>
@@ -146,8 +147,8 @@ namespace Catch {
         for( auto const& child : groupNode.children )
             writeTestCase( *child );
 
-        xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite ), false );
-        xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite ), false );
+        xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite ), XmlFormatting::Newline );
+        xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite ), XmlFormatting::Newline );
     }
 
     void JunitReporter::writeTestCase( TestCaseNode const& testCaseNode ) {
@@ -196,9 +197,9 @@ namespace Catch {
             writeAssertions( sectionNode );
 
             if( !sectionNode.stdOut.empty() )
-                xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), false );
+                xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), XmlFormatting::Newline );
             if( !sectionNode.stdErr.empty() )
-                xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), false );
+                xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), XmlFormatting::Newline );
         }
         for( auto const& childNode : sectionNode.childSections )
             if( className.empty() )
@@ -244,10 +245,25 @@ namespace Catch {
 
             XmlWriter::ScopedElement e = xml.scopedElement( elementName );
 
-            xml.writeAttribute( "message", result.getExpandedExpression() );
+            xml.writeAttribute( "message", result.getExpression() );
             xml.writeAttribute( "type", result.getTestMacroName() );
 
             ReusableStringStream rss;
+            if (stats.totals.assertions.total() > 0) {
+                rss << "FAILED" << ":\n";
+                if (result.hasExpression()) {
+                    rss << "  ";
+                    rss << result.getExpressionInMacro();
+                    rss << '\n';
+                }
+                if (result.hasExpandedExpression()) {
+                    rss << "with expansion:\n";
+                    rss << Column(result.getExpandedExpression()).indent(2) << '\n';
+                }
+            } else {
+                rss << '\n';
+            }
+
             if( !result.getMessage().empty() )
                 rss << result.getMessage() << '\n';
             for( auto const& msg : stats.infoMessages )
@@ -255,7 +271,7 @@ namespace Catch {
                     rss << msg.message << '\n';
 
             rss << "at " << result.getSourceInfo();
-            xml.writeText( rss.str(), false );
+            xml.writeText( rss.str(), XmlFormatting::Newline );
         }
     }
 
diff --git a/packages/Catch2/include/reporters/catch_reporter_sonarqube.hpp b/packages/Catch2/include/reporters/catch_reporter_sonarqube.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..bf7d9299a50ab6651633b8f5b7a369618f45aece
--- /dev/null
+++ b/packages/Catch2/include/reporters/catch_reporter_sonarqube.hpp
@@ -0,0 +1,181 @@
+/*
+ *  Created by Daniel Garcia on 2018-12-04.
+ *  Copyright Social Point SL. All rights reserved.
+ *
+ *  Distributed under the Boost Software License, Version 1.0. (See accompanying
+ *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+#ifndef CATCH_REPORTER_SONARQUBE_HPP_INCLUDED
+#define CATCH_REPORTER_SONARQUBE_HPP_INCLUDED
+
+
+// Don't #include any Catch headers here - we can assume they are already
+// included before this header.
+// This is not good practice in general but is necessary in this case so this
+// file can be distributed as a single header that works with the main
+// Catch single header.
+
+#include <map>
+
+namespace Catch {
+
+    struct SonarQubeReporter : CumulativeReporterBase<SonarQubeReporter> {
+
+        SonarQubeReporter(ReporterConfig const& config)
+        : CumulativeReporterBase(config)
+        , xml(config.stream()) {
+            m_reporterPrefs.shouldRedirectStdOut = true;
+            m_reporterPrefs.shouldReportAllAssertions = true;
+        }
+
+        ~SonarQubeReporter() override;
+
+        static std::string getDescription() {
+            return "Reports test results in the Generic Test Data SonarQube XML format";
+        }
+
+        static std::set<Verbosity> getSupportedVerbosities() {
+            return { Verbosity::Normal };
+        }
+
+        void noMatchingTestCases(std::string const& /*spec*/) override {}
+
+        void testRunStarting(TestRunInfo const& testRunInfo) override {
+            CumulativeReporterBase::testRunStarting(testRunInfo);
+            xml.startElement("testExecutions");
+            xml.writeAttribute("version", "1");
+        }
+
+        void testGroupEnded(TestGroupStats const& testGroupStats) override {
+            CumulativeReporterBase::testGroupEnded(testGroupStats);
+            writeGroup(*m_testGroups.back());
+        }
+
+        void testRunEndedCumulative() override {
+            xml.endElement();
+        }
+
+        void writeGroup(TestGroupNode const& groupNode) {
+            std::map<std::string, TestGroupNode::ChildNodes> testsPerFile;
+            for(auto const& child : groupNode.children)
+                testsPerFile[child->value.testInfo.lineInfo.file].push_back(child);
+
+            for(auto const& kv : testsPerFile)
+                writeTestFile(kv.first.c_str(), kv.second);
+        }
+
+        void writeTestFile(const char* filename, TestGroupNode::ChildNodes const& testCaseNodes) {
+            XmlWriter::ScopedElement e = xml.scopedElement("file");
+            xml.writeAttribute("path", filename);
+
+            for(auto const& child : testCaseNodes)
+                writeTestCase(*child);
+        }
+
+        void writeTestCase(TestCaseNode const& testCaseNode) {
+            // All test cases have exactly one section - which represents the
+            // test case itself. That section may have 0-n nested sections
+            assert(testCaseNode.children.size() == 1);
+            SectionNode const& rootSection = *testCaseNode.children.front();
+            writeSection("", rootSection, testCaseNode.value.testInfo.okToFail());
+        }
+
+        void writeSection(std::string const& rootName, SectionNode const& sectionNode, bool okToFail) {
+            std::string name = trim(sectionNode.stats.sectionInfo.name);
+            if(!rootName.empty())
+                name = rootName + '/' + name;
+
+            if(!sectionNode.assertions.empty() || !sectionNode.stdOut.empty() || !sectionNode.stdErr.empty()) {
+                XmlWriter::ScopedElement e = xml.scopedElement("testCase");
+                xml.writeAttribute("name", name);
+                xml.writeAttribute("duration", static_cast<long>(sectionNode.stats.durationInSeconds * 1000));
+
+                writeAssertions(sectionNode, okToFail);
+            }
+
+            for(auto const& childNode : sectionNode.childSections)
+                writeSection(name, *childNode, okToFail);
+        }
+
+        void writeAssertions(SectionNode const& sectionNode, bool okToFail) {
+            for(auto const& assertion : sectionNode.assertions)
+                writeAssertion( assertion, okToFail);
+        }
+
+        void writeAssertion(AssertionStats const& stats, bool okToFail) {
+            AssertionResult const& result = stats.assertionResult;
+            if(!result.isOk()) {
+                std::string elementName;
+                if(okToFail) {
+                    elementName = "skipped";
+                }
+                else {
+                    switch(result.getResultType()) {
+                        case ResultWas::ThrewException:
+                        case ResultWas::FatalErrorCondition:
+                            elementName = "error";
+                            break;
+                        case ResultWas::ExplicitFailure:
+                            elementName = "failure";
+                            break;
+                        case ResultWas::ExpressionFailed:
+                            elementName = "failure";
+                            break;
+                        case ResultWas::DidntThrowException:
+                            elementName = "failure";
+                            break;
+
+                            // We should never see these here:
+                        case ResultWas::Info:
+                        case ResultWas::Warning:
+                        case ResultWas::Ok:
+                        case ResultWas::Unknown:
+                        case ResultWas::FailureBit:
+                        case ResultWas::Exception:
+                            elementName = "internalError";
+                            break;
+                    }
+                }
+
+                XmlWriter::ScopedElement e = xml.scopedElement(elementName);
+
+                ReusableStringStream messageRss;
+                messageRss << result.getTestMacroName() << "(" << result.getExpression() << ")";
+                xml.writeAttribute("message", messageRss.str());
+
+                ReusableStringStream textRss;
+                if (stats.totals.assertions.total() > 0) {
+                    textRss << "FAILED:\n";
+                    if (result.hasExpression()) {
+                        textRss << "\t" << result.getExpressionInMacro() << "\n";
+                    }
+                    if (result.hasExpandedExpression()) {
+                        textRss << "with expansion:\n\t" << result.getExpandedExpression() << "\n";
+                    }
+                }
+
+                if(!result.getMessage().empty())
+                    textRss << result.getMessage() << "\n";
+
+                for(auto const& msg : stats.infoMessages)
+                    if(msg.type == ResultWas::Info)
+                        textRss << msg.message << "\n";
+
+                textRss << "at " << result.getSourceInfo();
+                xml.writeText(textRss.str(), XmlFormatting::Newline);
+            }
+        }
+
+    private:
+        XmlWriter xml;
+    };
+
+#ifdef CATCH_IMPL
+    SonarQubeReporter::~SonarQubeReporter() {}
+#endif
+
+    CATCH_REGISTER_REPORTER( "sonarqube", SonarQubeReporter )
+
+} // end namespace Catch
+
+#endif // CATCH_REPORTER_SONARQUBE_HPP_INCLUDED
\ No newline at end of file
diff --git a/packages/Catch2/include/reporters/catch_reporter_xml.cpp b/packages/Catch2/include/reporters/catch_reporter_xml.cpp
index 26ca8918ce51ad5e3b5fbce2708d7bb2f730815d..e110317c46e3bec6130f3a47971f4d77bc449cb2 100644
--- a/packages/Catch2/include/reporters/catch_reporter_xml.cpp
+++ b/packages/Catch2/include/reporters/catch_reporter_xml.cpp
@@ -193,9 +193,9 @@ namespace Catch {
             e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() );
 
         if( !testCaseStats.stdOut.empty() )
-            m_xml.scopedElement( "StdOut" ).writeText( trim( testCaseStats.stdOut ), false );
+            m_xml.scopedElement( "StdOut" ).writeText( trim( testCaseStats.stdOut ), XmlFormatting::Newline );
         if( !testCaseStats.stdErr.empty() )
-            m_xml.scopedElement( "StdErr" ).writeText( trim( testCaseStats.stdErr ), false );
+            m_xml.scopedElement( "StdErr" ).writeText( trim( testCaseStats.stdErr ), XmlFormatting::Newline );
 
         m_xml.endElement();
     }
diff --git a/packages/Catch2/projects/CMakeLists.txt b/packages/Catch2/projects/CMakeLists.txt
index cbe21fcff5a95649e6bbe283b6d9449dc3f9d9eb..0aafc1780d708cb75d5e77cbef5392d5ceb7aad6 100644
--- a/packages/Catch2/projects/CMakeLists.txt
+++ b/packages/Catch2/projects/CMakeLists.txt
@@ -282,6 +282,7 @@ set(REPORTER_HEADERS
         ${HEADER_DIR}/reporters/catch_reporter_tap.hpp
         ${HEADER_DIR}/reporters/catch_reporter_teamcity.hpp
         ${HEADER_DIR}/reporters/catch_reporter_xml.h
+        ${HEADER_DIR}/reporters/catch_reporter_sonarqube.hpp
         )
 set(REPORTER_SOURCES
         ${HEADER_DIR}/reporters/catch_reporter_bases.cpp
diff --git a/packages/Catch2/projects/SelfTest/Baselines/compact.sw.approved.txt b/packages/Catch2/projects/SelfTest/Baselines/compact.sw.approved.txt
index 311183bc753fda05eed786d21ab8af535ed03690..a74faf9be09b3d2c970bc4b3cc84763bbb516a09 100644
--- a/packages/Catch2/projects/SelfTest/Baselines/compact.sw.approved.txt
+++ b/packages/Catch2/projects/SelfTest/Baselines/compact.sw.approved.txt
@@ -631,6 +631,74 @@ GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == 2 for: 2 == 2
 GeneratorsImpl.tests.cpp:<line number>: passed: gen.next() for: true
 GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == 5 for: 5 == 5
 GeneratorsImpl.tests.cpp:<line number>: passed: !(gen.next()) for: !false
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == Approx(expected) for: -1.0 == Approx( -1.0 ) with 1 message: 'Current expected value is -1'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.next() for: true with 1 message: 'Current expected value is -1'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == Approx(expected) for: -0.9 == Approx( -0.9 ) with 1 message: 'Current expected value is -0.9'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.next() for: true with 1 message: 'Current expected value is -0.9'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == Approx(expected) for: -0.8 == Approx( -0.8 ) with 1 message: 'Current expected value is -0.8'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.next() for: true with 1 message: 'Current expected value is -0.8'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == Approx(expected) for: -0.7 == Approx( -0.7 ) with 1 message: 'Current expected value is -0.7'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.next() for: true with 1 message: 'Current expected value is -0.7'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == Approx(expected) for: -0.6 == Approx( -0.6 ) with 1 message: 'Current expected value is -0.6'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.next() for: true with 1 message: 'Current expected value is -0.6'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == Approx(expected) for: -0.5 == Approx( -0.5 ) with 1 message: 'Current expected value is -0.5'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.next() for: true with 1 message: 'Current expected value is -0.5'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == Approx(expected) for: -0.4 == Approx( -0.4 ) with 1 message: 'Current expected value is -0.4'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.next() for: true with 1 message: 'Current expected value is -0.4'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == Approx(expected) for: -0.3 == Approx( -0.3 ) with 1 message: 'Current expected value is -0.3'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.next() for: true with 1 message: 'Current expected value is -0.3'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == Approx(expected) for: -0.2 == Approx( -0.2 ) with 1 message: 'Current expected value is -0.2'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.next() for: true with 1 message: 'Current expected value is -0.2'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == Approx(expected) for: -0.1 == Approx( -0.1 ) with 1 message: 'Current expected value is -0.1'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.next() for: true with 1 message: 'Current expected value is -0.1'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == Approx(expected) for: -0.0 == Approx( -0.0 ) with 1 message: 'Current expected value is -1.38778e-16'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.next() for: true with 1 message: 'Current expected value is -1.38778e-16'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == Approx(expected) for: 0.1 == Approx( 0.1 ) with 1 message: 'Current expected value is 0.1'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.next() for: true with 1 message: 'Current expected value is 0.1'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == Approx(expected) for: 0.2 == Approx( 0.2 ) with 1 message: 'Current expected value is 0.2'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.next() for: true with 1 message: 'Current expected value is 0.2'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == Approx(expected) for: 0.3 == Approx( 0.3 ) with 1 message: 'Current expected value is 0.3'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.next() for: true with 1 message: 'Current expected value is 0.3'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == Approx(expected) for: 0.4 == Approx( 0.4 ) with 1 message: 'Current expected value is 0.4'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.next() for: true with 1 message: 'Current expected value is 0.4'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == Approx(expected) for: 0.5 == Approx( 0.5 ) with 1 message: 'Current expected value is 0.5'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.next() for: true with 1 message: 'Current expected value is 0.5'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == Approx(expected) for: 0.6 == Approx( 0.6 ) with 1 message: 'Current expected value is 0.6'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.next() for: true with 1 message: 'Current expected value is 0.6'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == Approx(expected) for: 0.7 == Approx( 0.7 ) with 1 message: 'Current expected value is 0.7'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.next() for: true with 1 message: 'Current expected value is 0.7'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == Approx(expected) for: 0.8 == Approx( 0.8 ) with 1 message: 'Current expected value is 0.8'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.next() for: true with 1 message: 'Current expected value is 0.8'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == Approx(expected) for: 0.9 == Approx( 0.9 ) with 1 message: 'Current expected value is 0.9'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.next() for: true with 1 message: 'Current expected value is 0.9'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == Approx( rangeEnd ) for: 1.0 == Approx( 1.0 )
+GeneratorsImpl.tests.cpp:<line number>: passed: !(gen.next()) for: !false
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == Approx(expected) for: -1.0 == Approx( -1.0 ) with 1 message: 'Current expected value is -1'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.next() for: true with 1 message: 'Current expected value is -1'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == Approx(expected) for: -0.7 == Approx( -0.7 ) with 1 message: 'Current expected value is -0.7'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.next() for: true with 1 message: 'Current expected value is -0.7'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == Approx(expected) for: -0.4 == Approx( -0.4 ) with 1 message: 'Current expected value is -0.4'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.next() for: true with 1 message: 'Current expected value is -0.4'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == Approx(expected) for: -0.1 == Approx( -0.1 ) with 1 message: 'Current expected value is -0.1'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.next() for: true with 1 message: 'Current expected value is -0.1'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == Approx(expected) for: 0.2 == Approx( 0.2 ) with 1 message: 'Current expected value is 0.2'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.next() for: true with 1 message: 'Current expected value is 0.2'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == Approx(expected) for: 0.5 == Approx( 0.5 ) with 1 message: 'Current expected value is 0.5'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.next() for: true with 1 message: 'Current expected value is 0.5'
+GeneratorsImpl.tests.cpp:<line number>: passed: !(gen.next()) for: !false
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == Approx(expected) for: -1.0 == Approx( -1.0 ) with 1 message: 'Current expected value is -1'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.next() for: true with 1 message: 'Current expected value is -1'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == Approx(expected) for: -0.7 == Approx( -0.7 ) with 1 message: 'Current expected value is -0.7'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.next() for: true with 1 message: 'Current expected value is -0.7'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == Approx(expected) for: -0.4 == Approx( -0.4 ) with 1 message: 'Current expected value is -0.4'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.next() for: true with 1 message: 'Current expected value is -0.4'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == Approx(expected) for: -0.1 == Approx( -0.1 ) with 1 message: 'Current expected value is -0.1'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.next() for: true with 1 message: 'Current expected value is -0.1'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == Approx(expected) for: 0.2 == Approx( 0.2 ) with 1 message: 'Current expected value is 0.2'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.next() for: true with 1 message: 'Current expected value is 0.2'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == Approx(expected) for: 0.5 == Approx( 0.5 ) with 1 message: 'Current expected value is 0.5'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.next() for: true with 1 message: 'Current expected value is 0.5'
+GeneratorsImpl.tests.cpp:<line number>: passed: !(gen.next()) for: !false
 GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == 5 for: 5 == 5
 GeneratorsImpl.tests.cpp:<line number>: passed: gen.next() for: true
 GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == 2 for: 2 == 2
@@ -959,6 +1027,12 @@ CmdLine.tests.cpp:<line number>: passed: spec.matches( fakeTestCase( "  aardvark
 CmdLine.tests.cpp:<line number>: passed: spec.matches( fakeTestCase( " aardvark " ) ) for: true
 CmdLine.tests.cpp:<line number>: passed: spec.matches( fakeTestCase( "aardvark " ) ) for: true
 CmdLine.tests.cpp:<line number>: passed: spec.matches( fakeTestCase( "aardvark" ) ) for: true
+CmdLine.tests.cpp:<line number>: passed: spec.matches(fakeTestCase("hidden and foo", "[.][foo]")) for: true
+CmdLine.tests.cpp:<line number>: passed: !(spec.matches(fakeTestCase("only foo", "[foo]"))) for: !false
+CmdLine.tests.cpp:<line number>: passed: !(spec.matches(fakeTestCase("hidden and foo", "[.][foo]"))) for: !false
+CmdLine.tests.cpp:<line number>: passed: !(spec.matches(fakeTestCase("only foo", "[foo]"))) for: !false
+CmdLine.tests.cpp:<line number>: passed: !(spec.matches(fakeTestCase("only hidden", "[.]"))) for: !false
+CmdLine.tests.cpp:<line number>: passed: spec.matches(fakeTestCase("neither foo nor hidden", "[bar]")) for: true
 Condition.tests.cpp:<line number>: passed: p == 0 for: 0 == 0
 Condition.tests.cpp:<line number>: passed: p == pNULL for: 0 == 0
 Condition.tests.cpp:<line number>: passed: p != 0 for: 0x<hex digits> != 0
@@ -1095,37 +1169,32 @@ Matchers.tests.cpp:<line number>: passed: testStringForMatching(), EndsWith("sub
 Matchers.tests.cpp:<line number>: passed: testStringForMatching(), EndsWith(" SuBsTrInG", Catch::CaseSensitive::No) for: "this string contains 'abc' as a substring" ends with: " substring" (case insensitive)
 String.tests.cpp:<line number>: passed: empty.empty() for: true
 String.tests.cpp:<line number>: passed: empty.size() == 0 for: 0 == 0
+String.tests.cpp:<line number>: passed: empty.isNullTerminated() for: true
 String.tests.cpp:<line number>: passed: std::strcmp( empty.c_str(), "" ) == 0 for: 0 == 0
 String.tests.cpp:<line number>: passed: s.empty() == false for: false == false
 String.tests.cpp:<line number>: passed: s.size() == 5 for: 5 == 5
-String.tests.cpp:<line number>: passed: isSubstring( s ) == false for: false == false
+String.tests.cpp:<line number>: passed: s.isNullTerminated() for: true
 String.tests.cpp:<line number>: passed: std::strcmp( rawChars, "hello" ) == 0 for: 0 == 0
-String.tests.cpp:<line number>: passed: isOwned( s ) == false for: false == false
+String.tests.cpp:<line number>: passed: s.c_str()
 String.tests.cpp:<line number>: passed: s.c_str() == rawChars for: "hello" == "hello"
-String.tests.cpp:<line number>: passed: isOwned( s ) == false for: false == false
+String.tests.cpp:<line number>: passed: s.data() == rawChars for: "hello" == "hello"
 String.tests.cpp:<line number>: passed: original == "original"
-String.tests.cpp:<line number>: passed: isSubstring( original ) for: true
-String.tests.cpp:<line number>: passed: isOwned( original ) == false for: false == false
-String.tests.cpp:<line number>: passed: isOwned( original ) for: true
+String.tests.cpp:<line number>: passed: !(original.isNullTerminated()) for: !false
+String.tests.cpp:<line number>: passed: original.c_str()
+String.tests.cpp:<line number>: passed: original.data()
 String.tests.cpp:<line number>: passed: ss.empty() == false for: false == false
 String.tests.cpp:<line number>: passed: ss.size() == 5 for: 5 == 5
-String.tests.cpp:<line number>: passed: std::strcmp( ss.c_str(), "hello" ) == 0 for: 0 == 0
-String.tests.cpp:<line number>: passed: ss == "hello" for: hello == "hello"
-String.tests.cpp:<line number>: passed: isSubstring( ss ) for: true
-String.tests.cpp:<line number>: passed: isOwned( ss ) == false for: false == false
-String.tests.cpp:<line number>: passed: rawChars == s.currentData() for: "hello world!" == "hello world!"
-String.tests.cpp:<line number>: passed: ss.c_str() != rawChars for: "hello" != "hello world!"
-String.tests.cpp:<line number>: passed: isOwned( ss ) for: true
-String.tests.cpp:<line number>: passed: isOwned(ss) == false for: false == false
+String.tests.cpp:<line number>: passed: std::strncmp( ss.data(), "hello", 5 ) == 0 for: 0 == 0
 String.tests.cpp:<line number>: passed: ss == "hello" for: hello == "hello"
-String.tests.cpp:<line number>: passed: rawChars == ss.currentData() for: "hello world!" == "hello world!"
 String.tests.cpp:<line number>: passed: ss.size() == 6 for: 6 == 6
 String.tests.cpp:<line number>: passed: std::strcmp( ss.c_str(), "world!" ) == 0 for: 0 == 0
-String.tests.cpp:<line number>: passed: s.c_str() == s2.c_str() for: "hello world!" == "hello world!"
-String.tests.cpp:<line number>: passed: s.c_str() != ss.c_str() for: "hello world!" != "hello"
+String.tests.cpp:<line number>: passed: s.data() == s2.data() for: "hello world!" == "hello world!"
+String.tests.cpp:<line number>: passed: s.data() == ss.data() for: "hello world!" == "hello world!"
 String.tests.cpp:<line number>: passed: s.substr(s.size() + 1, 123).empty() for: true
-String.tests.cpp:<line number>: passed: StringRef("hello") == StringRef("hello") for: hello == hello
-String.tests.cpp:<line number>: passed: StringRef("hello") != StringRef("cello") for: hello != cello
+String.tests.cpp:<line number>: passed: std::strcmp(ss.c_str(), "world!") == 0 for: 0 == 0
+String.tests.cpp:<line number>: passed: (char*)buffer1 != (char*)buffer2 for: "Hello" != "Hello"
+String.tests.cpp:<line number>: passed: left == right for: Hello == Hello
+String.tests.cpp:<line number>: passed: left != left.substr(0, 3) for: Hello != Hel
 String.tests.cpp:<line number>: passed: sr == "a standard string" for: a standard string == "a standard string"
 String.tests.cpp:<line number>: passed: sr.size() == stdStr.size() for: 17 == 17
 String.tests.cpp:<line number>: passed: sr == "a standard string" for: a standard string == "a standard string"
@@ -1136,6 +1205,17 @@ String.tests.cpp:<line number>: passed: stdStr == "a stringref" for: "a stringre
 String.tests.cpp:<line number>: passed: stdStr.size() == sr.size() for: 11 == 11
 String.tests.cpp:<line number>: passed: stdStr == "a stringref" for: "a stringref" == "a stringref"
 String.tests.cpp:<line number>: passed: stdStr.size() == sr.size() for: 11 == 11
+String.tests.cpp:<line number>: passed: with 1 message: 'StringRef{}.size() == 0'
+String.tests.cpp:<line number>: passed: with 1 message: 'StringRef{ "abc", 3 }.size() == 3'
+String.tests.cpp:<line number>: passed: with 1 message: 'StringRef{ "abc", 3 }.isNullTerminated()'
+String.tests.cpp:<line number>: passed: with 1 message: 'StringRef{ "abc", 2 }.size() == 2'
+String.tests.cpp:<line number>: passed: with 1 message: '!(StringRef{ "abc", 2 }.isNullTerminated())'
+String.tests.cpp:<line number>: passed: with 1 message: '!(sr1.empty())'
+String.tests.cpp:<line number>: passed: with 1 message: 'sr1.size() == 3'
+String.tests.cpp:<line number>: passed: with 1 message: 'sr1.isNullTerminated()'
+String.tests.cpp:<line number>: passed: with 1 message: 'sr2.empty()'
+String.tests.cpp:<line number>: passed: with 1 message: 'sr2.size() == 0'
+String.tests.cpp:<line number>: passed: with 1 message: 'sr2.isNullTerminated()'
 ToStringChrono.tests.cpp:<line number>: passed: minute == seconds for: 1 m == 60 s
 ToStringChrono.tests.cpp:<line number>: passed: hour != seconds for: 1 h != 60 s
 ToStringChrono.tests.cpp:<line number>: passed: micro != milli for: 1 us != 1 ms
@@ -1487,48 +1567,6 @@ Xml.tests.cpp:<line number>: passed: encode( stringWithQuotes, Catch::XmlEncode:
 "don't &quot;quote&quot; me on that"
 Xml.tests.cpp:<line number>: passed: encode( "[\x01]" ) == "[\\x01]" for: "[\x01]" == "[\x01]"
 Xml.tests.cpp:<line number>: passed: encode( "[\x7F]" ) == "[\\x7F]" for: "[\x7F]" == "[\x7F]"
-Xml.tests.cpp:<line number>: passed: encode(u8"Here be 👾") == u8"Here be 👾" for: "Here be 👾" == "Here be 👾"
-Xml.tests.cpp:<line number>: passed: encode(u8"šš") == u8"šš" for: "šš" == "šš"
-Xml.tests.cpp:<line number>: passed: encode("\xDF\xBF") == "\xDF\xBF" for: "߿" == "߿"
-Xml.tests.cpp:<line number>: passed: encode("\xE0\xA0\x80") == "\xE0\xA0\x80" for: "ࠀ" == "ࠀ"
-Xml.tests.cpp:<line number>: passed: encode("\xED\x9F\xBF") == "\xED\x9F\xBF" for: "퟿" == "퟿"
-Xml.tests.cpp:<line number>: passed: encode("\xEE\x80\x80") == "\xEE\x80\x80" for: "" == ""
-Xml.tests.cpp:<line number>: passed: encode("\xEF\xBF\xBF") == "\xEF\xBF\xBF" for: "￿" == "￿"
-Xml.tests.cpp:<line number>: passed: encode("\xF0\x90\x80\x80") == "\xF0\x90\x80\x80" for: "𐀀" == "𐀀"
-Xml.tests.cpp:<line number>: passed: encode("\xF4\x8F\xBF\xBF") == "\xF4\x8F\xBF\xBF" for: "􏿿" == "􏿿"
-Xml.tests.cpp:<line number>: passed: encode("Here \xFF be 👾") == u8"Here \\xFF be 👾" for: "Here \xFF be 👾" == "Here \xFF be 👾"
-Xml.tests.cpp:<line number>: passed: encode("\xFF") == "\\xFF" for: "\xFF" == "\xFF"
-Xml.tests.cpp:<line number>: passed: encode("\xC5\xC5\xA0") == u8"\\xC5Š" for: "\xC5Š" == "\xC5Š"
-Xml.tests.cpp:<line number>: passed: encode("\xF4\x90\x80\x80") == u8"\\xF4\\x90\\x80\\x80" for: "\xF4\x90\x80\x80" == "\xF4\x90\x80\x80"
-Xml.tests.cpp:<line number>: passed: encode("\xC0\x80") == u8"\\xC0\\x80" for: "\xC0\x80" == "\xC0\x80"
-Xml.tests.cpp:<line number>: passed: encode("\xF0\x80\x80\x80") == u8"\\xF0\\x80\\x80\\x80" for: "\xF0\x80\x80\x80" == "\xF0\x80\x80\x80"
-Xml.tests.cpp:<line number>: passed: encode("\xC1\xBF") == u8"\\xC1\\xBF" for: "\xC1\xBF" == "\xC1\xBF"
-Xml.tests.cpp:<line number>: passed: encode("\xE0\x9F\xBF") == u8"\\xE0\\x9F\\xBF" for: "\xE0\x9F\xBF" == "\xE0\x9F\xBF"
-Xml.tests.cpp:<line number>: passed: encode("\xF0\x8F\xBF\xBF") == u8"\\xF0\\x8F\\xBF\\xBF" for: "\xF0\x8F\xBF\xBF" == "\xF0\x8F\xBF\xBF"
-Xml.tests.cpp:<line number>: passed: encode("\xED\xA0\x80") == "\xED\xA0\x80" for: "���" == "���"
-Xml.tests.cpp:<line number>: passed: encode("\xED\xAF\xBF") == "\xED\xAF\xBF" for: "���" == "���"
-Xml.tests.cpp:<line number>: passed: encode("\xED\xB0\x80") == "\xED\xB0\x80" for: "���" == "���"
-Xml.tests.cpp:<line number>: passed: encode("\xED\xBF\xBF") == "\xED\xBF\xBF" for: "���" == "���"
-Xml.tests.cpp:<line number>: passed: encode("\x80") == u8"\\x80" for: "\x80" == "\x80"
-Xml.tests.cpp:<line number>: passed: encode("\x81") == u8"\\x81" for: "\x81" == "\x81"
-Xml.tests.cpp:<line number>: passed: encode("\xBC") == u8"\\xBC" for: "\xBC" == "\xBC"
-Xml.tests.cpp:<line number>: passed: encode("\xBF") == u8"\\xBF" for: "\xBF" == "\xBF"
-Xml.tests.cpp:<line number>: passed: encode("\xF5\x80\x80\x80") == u8"\\xF5\\x80\\x80\\x80" for: "\xF5\x80\x80\x80" == "\xF5\x80\x80\x80"
-Xml.tests.cpp:<line number>: passed: encode("\xF6\x80\x80\x80") == u8"\\xF6\\x80\\x80\\x80" for: "\xF6\x80\x80\x80" == "\xF6\x80\x80\x80"
-Xml.tests.cpp:<line number>: passed: encode("\xF7\x80\x80\x80") == u8"\\xF7\\x80\\x80\\x80" for: "\xF7\x80\x80\x80" == "\xF7\x80\x80\x80"
-Xml.tests.cpp:<line number>: passed: encode("\xDE") == u8"\\xDE" for: "\xDE" == "\xDE"
-Xml.tests.cpp:<line number>: passed: encode("\xDF") == u8"\\xDF" for: "\xDF" == "\xDF"
-Xml.tests.cpp:<line number>: passed: encode("\xE0") == u8"\\xE0" for: "\xE0" == "\xE0"
-Xml.tests.cpp:<line number>: passed: encode("\xEF") == u8"\\xEF" for: "\xEF" == "\xEF"
-Xml.tests.cpp:<line number>: passed: encode("\xF0") == u8"\\xF0" for: "\xF0" == "\xF0"
-Xml.tests.cpp:<line number>: passed: encode("\xF4") == u8"\\xF4" for: "\xF4" == "\xF4"
-Xml.tests.cpp:<line number>: passed: encode("\xE0\x80") == u8"\\xE0\\x80" for: "\xE0\x80" == "\xE0\x80"
-Xml.tests.cpp:<line number>: passed: encode("\xE0\xBF") == u8"\\xE0\\xBF" for: "\xE0\xBF" == "\xE0\xBF"
-Xml.tests.cpp:<line number>: passed: encode("\xE1\x80") == u8"\\xE1\\x80" for: "\xE1\x80" == "\xE1\x80"
-Xml.tests.cpp:<line number>: passed: encode("\xF0\x80") == u8"\\xF0\\x80" for: "\xF0\x80" == "\xF0\x80"
-Xml.tests.cpp:<line number>: passed: encode("\xF4\x80") == u8"\\xF4\\x80" for: "\xF4\x80" == "\xF4\x80"
-Xml.tests.cpp:<line number>: passed: encode("\xF0\x80\x80") == u8"\\xF0\\x80\\x80" for: "\xF0\x80\x80" == "\xF0\x80\x80"
-Xml.tests.cpp:<line number>: passed: encode("\xF4\x80\x80") == u8"\\xF4\\x80\\x80" for: "\xF4\x80\x80" == "\xF4\x80\x80"
 ToStringVector.tests.cpp:<line number>: passed: Catch::Detail::stringify( empty ) == "{  }" for: "{  }" == "{  }"
 ToStringVector.tests.cpp:<line number>: passed: Catch::Detail::stringify( oneValue ) == "{ 42 }" for: "{ 42 }" == "{ 42 }"
 ToStringVector.tests.cpp:<line number>: passed: Catch::Detail::stringify( twoValues ) == "{ 42, 250 }" for: "{ 42, 250 }" == "{ 42, 250 }"
diff --git a/packages/Catch2/projects/SelfTest/Baselines/console.std.approved.txt b/packages/Catch2/projects/SelfTest/Baselines/console.std.approved.txt
index fd405a84ffaa0c93c475e7a9523155630d1056bb..4db2b90a44e6bd79ba63d3ef00b9d5cb78a1e284 100644
--- a/packages/Catch2/projects/SelfTest/Baselines/console.std.approved.txt
+++ b/packages/Catch2/projects/SelfTest/Baselines/console.std.approved.txt
@@ -1381,5 +1381,5 @@ due to unexpected exception with message:
 
 ===============================================================================
 test cases:  304 |  230 passed |  70 failed |  4 failed as expected
-assertions: 1621 | 1469 passed | 131 failed | 21 failed as expected
+assertions: 1659 | 1507 passed | 131 failed | 21 failed as expected
 
diff --git a/packages/Catch2/projects/SelfTest/Baselines/console.sw.approved.txt b/packages/Catch2/projects/SelfTest/Baselines/console.sw.approved.txt
index f234f88243245082c1a01e2162daaedaa23fa748..8de4bcaa8040ae7b6c18cebd3548febc233fe719 100644
--- a/packages/Catch2/projects/SelfTest/Baselines/console.sw.approved.txt
+++ b/packages/Catch2/projects/SelfTest/Baselines/console.sw.approved.txt
@@ -4774,6 +4774,504 @@ GeneratorsImpl.tests.cpp:<line number>: PASSED:
 with expansion:
   !false
 
+-------------------------------------------------------------------------------
+Generators internals
+  Range
+  Positive manual step
+  Floating Point
+  Exact
+-------------------------------------------------------------------------------
+GeneratorsImpl.tests.cpp:<line number>
+...............................................................................
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.get() == Approx(expected) )
+with expansion:
+  -1.0 == Approx( -1.0 )
+with message:
+  Current expected value is -1
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.next() )
+with expansion:
+  true
+with message:
+  Current expected value is -1
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.get() == Approx(expected) )
+with expansion:
+  -0.9 == Approx( -0.9 )
+with message:
+  Current expected value is -0.9
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.next() )
+with expansion:
+  true
+with message:
+  Current expected value is -0.9
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.get() == Approx(expected) )
+with expansion:
+  -0.8 == Approx( -0.8 )
+with message:
+  Current expected value is -0.8
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.next() )
+with expansion:
+  true
+with message:
+  Current expected value is -0.8
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.get() == Approx(expected) )
+with expansion:
+  -0.7 == Approx( -0.7 )
+with message:
+  Current expected value is -0.7
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.next() )
+with expansion:
+  true
+with message:
+  Current expected value is -0.7
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.get() == Approx(expected) )
+with expansion:
+  -0.6 == Approx( -0.6 )
+with message:
+  Current expected value is -0.6
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.next() )
+with expansion:
+  true
+with message:
+  Current expected value is -0.6
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.get() == Approx(expected) )
+with expansion:
+  -0.5 == Approx( -0.5 )
+with message:
+  Current expected value is -0.5
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.next() )
+with expansion:
+  true
+with message:
+  Current expected value is -0.5
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.get() == Approx(expected) )
+with expansion:
+  -0.4 == Approx( -0.4 )
+with message:
+  Current expected value is -0.4
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.next() )
+with expansion:
+  true
+with message:
+  Current expected value is -0.4
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.get() == Approx(expected) )
+with expansion:
+  -0.3 == Approx( -0.3 )
+with message:
+  Current expected value is -0.3
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.next() )
+with expansion:
+  true
+with message:
+  Current expected value is -0.3
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.get() == Approx(expected) )
+with expansion:
+  -0.2 == Approx( -0.2 )
+with message:
+  Current expected value is -0.2
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.next() )
+with expansion:
+  true
+with message:
+  Current expected value is -0.2
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.get() == Approx(expected) )
+with expansion:
+  -0.1 == Approx( -0.1 )
+with message:
+  Current expected value is -0.1
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.next() )
+with expansion:
+  true
+with message:
+  Current expected value is -0.1
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.get() == Approx(expected) )
+with expansion:
+  -0.0 == Approx( -0.0 )
+with message:
+  Current expected value is -1.38778e-16
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.next() )
+with expansion:
+  true
+with message:
+  Current expected value is -1.38778e-16
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.get() == Approx(expected) )
+with expansion:
+  0.1 == Approx( 0.1 )
+with message:
+  Current expected value is 0.1
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.next() )
+with expansion:
+  true
+with message:
+  Current expected value is 0.1
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.get() == Approx(expected) )
+with expansion:
+  0.2 == Approx( 0.2 )
+with message:
+  Current expected value is 0.2
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.next() )
+with expansion:
+  true
+with message:
+  Current expected value is 0.2
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.get() == Approx(expected) )
+with expansion:
+  0.3 == Approx( 0.3 )
+with message:
+  Current expected value is 0.3
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.next() )
+with expansion:
+  true
+with message:
+  Current expected value is 0.3
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.get() == Approx(expected) )
+with expansion:
+  0.4 == Approx( 0.4 )
+with message:
+  Current expected value is 0.4
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.next() )
+with expansion:
+  true
+with message:
+  Current expected value is 0.4
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.get() == Approx(expected) )
+with expansion:
+  0.5 == Approx( 0.5 )
+with message:
+  Current expected value is 0.5
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.next() )
+with expansion:
+  true
+with message:
+  Current expected value is 0.5
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.get() == Approx(expected) )
+with expansion:
+  0.6 == Approx( 0.6 )
+with message:
+  Current expected value is 0.6
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.next() )
+with expansion:
+  true
+with message:
+  Current expected value is 0.6
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.get() == Approx(expected) )
+with expansion:
+  0.7 == Approx( 0.7 )
+with message:
+  Current expected value is 0.7
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.next() )
+with expansion:
+  true
+with message:
+  Current expected value is 0.7
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.get() == Approx(expected) )
+with expansion:
+  0.8 == Approx( 0.8 )
+with message:
+  Current expected value is 0.8
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.next() )
+with expansion:
+  true
+with message:
+  Current expected value is 0.8
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.get() == Approx(expected) )
+with expansion:
+  0.9 == Approx( 0.9 )
+with message:
+  Current expected value is 0.9
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.next() )
+with expansion:
+  true
+with message:
+  Current expected value is 0.9
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.get() == Approx( rangeEnd ) )
+with expansion:
+  1.0 == Approx( 1.0 )
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE_FALSE( gen.next() )
+with expansion:
+  !false
+
+-------------------------------------------------------------------------------
+Generators internals
+  Range
+  Positive manual step
+  Floating Point
+  Slightly over end
+-------------------------------------------------------------------------------
+GeneratorsImpl.tests.cpp:<line number>
+...............................................................................
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.get() == Approx(expected) )
+with expansion:
+  -1.0 == Approx( -1.0 )
+with message:
+  Current expected value is -1
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.next() )
+with expansion:
+  true
+with message:
+  Current expected value is -1
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.get() == Approx(expected) )
+with expansion:
+  -0.7 == Approx( -0.7 )
+with message:
+  Current expected value is -0.7
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.next() )
+with expansion:
+  true
+with message:
+  Current expected value is -0.7
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.get() == Approx(expected) )
+with expansion:
+  -0.4 == Approx( -0.4 )
+with message:
+  Current expected value is -0.4
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.next() )
+with expansion:
+  true
+with message:
+  Current expected value is -0.4
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.get() == Approx(expected) )
+with expansion:
+  -0.1 == Approx( -0.1 )
+with message:
+  Current expected value is -0.1
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.next() )
+with expansion:
+  true
+with message:
+  Current expected value is -0.1
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.get() == Approx(expected) )
+with expansion:
+  0.2 == Approx( 0.2 )
+with message:
+  Current expected value is 0.2
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.next() )
+with expansion:
+  true
+with message:
+  Current expected value is 0.2
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.get() == Approx(expected) )
+with expansion:
+  0.5 == Approx( 0.5 )
+with message:
+  Current expected value is 0.5
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.next() )
+with expansion:
+  true
+with message:
+  Current expected value is 0.5
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE_FALSE( gen.next() )
+with expansion:
+  !false
+
+-------------------------------------------------------------------------------
+Generators internals
+  Range
+  Positive manual step
+  Floating Point
+  Slightly under end
+-------------------------------------------------------------------------------
+GeneratorsImpl.tests.cpp:<line number>
+...............................................................................
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.get() == Approx(expected) )
+with expansion:
+  -1.0 == Approx( -1.0 )
+with message:
+  Current expected value is -1
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.next() )
+with expansion:
+  true
+with message:
+  Current expected value is -1
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.get() == Approx(expected) )
+with expansion:
+  -0.7 == Approx( -0.7 )
+with message:
+  Current expected value is -0.7
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.next() )
+with expansion:
+  true
+with message:
+  Current expected value is -0.7
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.get() == Approx(expected) )
+with expansion:
+  -0.4 == Approx( -0.4 )
+with message:
+  Current expected value is -0.4
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.next() )
+with expansion:
+  true
+with message:
+  Current expected value is -0.4
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.get() == Approx(expected) )
+with expansion:
+  -0.1 == Approx( -0.1 )
+with message:
+  Current expected value is -0.1
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.next() )
+with expansion:
+  true
+with message:
+  Current expected value is -0.1
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.get() == Approx(expected) )
+with expansion:
+  0.2 == Approx( 0.2 )
+with message:
+  Current expected value is 0.2
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.next() )
+with expansion:
+  true
+with message:
+  Current expected value is 0.2
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.get() == Approx(expected) )
+with expansion:
+  0.5 == Approx( 0.5 )
+with message:
+  Current expected value is 0.5
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE( gen.next() )
+with expansion:
+  true
+with message:
+  Current expected value is 0.5
+
+GeneratorsImpl.tests.cpp:<line number>: PASSED:
+  REQUIRE_FALSE( gen.next() )
+with expansion:
+  !false
+
 -------------------------------------------------------------------------------
 Generators internals
   Range
@@ -6863,6 +7361,50 @@ CmdLine.tests.cpp:<line number>: PASSED:
 with expansion:
   true
 
+-------------------------------------------------------------------------------
+Parse test names and tags
+  Shortened hide tags are split apart when parsing
+-------------------------------------------------------------------------------
+CmdLine.tests.cpp:<line number>
+...............................................................................
+
+CmdLine.tests.cpp:<line number>: PASSED:
+  CHECK( spec.matches(fakeTestCase("hidden and foo", "[.][foo]")) )
+with expansion:
+  true
+
+CmdLine.tests.cpp:<line number>: PASSED:
+  CHECK_FALSE( spec.matches(fakeTestCase("only foo", "[foo]")) )
+with expansion:
+  !false
+
+-------------------------------------------------------------------------------
+Parse test names and tags
+  Shortened hide tags also properly handle exclusion
+-------------------------------------------------------------------------------
+CmdLine.tests.cpp:<line number>
+...............................................................................
+
+CmdLine.tests.cpp:<line number>: PASSED:
+  CHECK_FALSE( spec.matches(fakeTestCase("hidden and foo", "[.][foo]")) )
+with expansion:
+  !false
+
+CmdLine.tests.cpp:<line number>: PASSED:
+  CHECK_FALSE( spec.matches(fakeTestCase("only foo", "[foo]")) )
+with expansion:
+  !false
+
+CmdLine.tests.cpp:<line number>: PASSED:
+  CHECK_FALSE( spec.matches(fakeTestCase("only hidden", "[.]")) )
+with expansion:
+  !false
+
+CmdLine.tests.cpp:<line number>: PASSED:
+  CHECK( spec.matches(fakeTestCase("neither foo nor hidden", "[bar]")) )
+with expansion:
+  true
+
 -------------------------------------------------------------------------------
 Pointers can be compared to null
 -------------------------------------------------------------------------------
@@ -7995,6 +8537,11 @@ String.tests.cpp:<line number>: PASSED:
 with expansion:
   0 == 0
 
+String.tests.cpp:<line number>: PASSED:
+  REQUIRE( empty.isNullTerminated() )
+with expansion:
+  true
+
 String.tests.cpp:<line number>: PASSED:
   REQUIRE( std::strcmp( empty.c_str(), "" ) == 0 )
 with expansion:
@@ -8018,147 +8565,76 @@ with expansion:
   5 == 5
 
 String.tests.cpp:<line number>: PASSED:
-  REQUIRE( isSubstring( s ) == false )
-with expansion:
-  false == false
-
-String.tests.cpp:<line number>: PASSED:
-  REQUIRE( std::strcmp( rawChars, "hello" ) == 0 )
-with expansion:
-  0 == 0
-
--------------------------------------------------------------------------------
-StringRef
-  From string literal
-  c_str() does not cause copy
--------------------------------------------------------------------------------
-String.tests.cpp:<line number>
-...............................................................................
-
-String.tests.cpp:<line number>: PASSED:
-  REQUIRE( isOwned( s ) == false )
-with expansion:
-  false == false
-
-String.tests.cpp:<line number>: PASSED:
-  REQUIRE( s.c_str() == rawChars )
-with expansion:
-  "hello" == "hello"
-
-String.tests.cpp:<line number>: PASSED:
-  REQUIRE( isOwned( s ) == false )
-with expansion:
-  false == false
-
--------------------------------------------------------------------------------
-StringRef
-  From sub-string
--------------------------------------------------------------------------------
-String.tests.cpp:<line number>
-...............................................................................
-
-String.tests.cpp:<line number>: PASSED:
-  REQUIRE( original == "original" )
-
-String.tests.cpp:<line number>: PASSED:
-  REQUIRE( isSubstring( original ) )
-with expansion:
-  true
-
-String.tests.cpp:<line number>: PASSED:
-  REQUIRE( isOwned( original ) == false )
-with expansion:
-  false == false
-
-String.tests.cpp:<line number>: PASSED:
-  REQUIRE( isOwned( original ) )
-with expansion:
-  true
-
--------------------------------------------------------------------------------
-StringRef
-  Substrings
-  zero-based substring
--------------------------------------------------------------------------------
-String.tests.cpp:<line number>
-...............................................................................
-
-String.tests.cpp:<line number>: PASSED:
-  REQUIRE( ss.empty() == false )
+  REQUIRE( s.isNullTerminated() )
 with expansion:
-  false == false
+  true
 
 String.tests.cpp:<line number>: PASSED:
-  REQUIRE( ss.size() == 5 )
+  REQUIRE( std::strcmp( rawChars, "hello" ) == 0 )
 with expansion:
-  5 == 5
+  0 == 0
+
+String.tests.cpp:<line number>: PASSED:
+  REQUIRE_NOTHROW( s.c_str() )
 
 String.tests.cpp:<line number>: PASSED:
-  REQUIRE( std::strcmp( ss.c_str(), "hello" ) == 0 )
+  REQUIRE( s.c_str() == rawChars )
 with expansion:
-  0 == 0
+  "hello" == "hello"
 
 String.tests.cpp:<line number>: PASSED:
-  REQUIRE( ss == "hello" )
+  REQUIRE( s.data() == rawChars )
 with expansion:
-  hello == "hello"
+  "hello" == "hello"
 
 -------------------------------------------------------------------------------
 StringRef
-  Substrings
-  c_str() causes copy
+  From sub-string
 -------------------------------------------------------------------------------
 String.tests.cpp:<line number>
 ...............................................................................
 
 String.tests.cpp:<line number>: PASSED:
-  REQUIRE( isSubstring( ss ) )
-with expansion:
-  true
-
-String.tests.cpp:<line number>: PASSED:
-  REQUIRE( isOwned( ss ) == false )
-with expansion:
-  false == false
+  REQUIRE( original == "original" )
 
 String.tests.cpp:<line number>: PASSED:
-  REQUIRE( rawChars == s.currentData() )
+  REQUIRE_FALSE( original.isNullTerminated() )
 with expansion:
-  "hello world!" == "hello world!"
+  !false
 
 String.tests.cpp:<line number>: PASSED:
-  REQUIRE( ss.c_str() != rawChars )
-with expansion:
-  "hello" != "hello world!"
+  REQUIRE_THROWS( original.c_str() )
 
 String.tests.cpp:<line number>: PASSED:
-  REQUIRE( isOwned( ss ) )
-with expansion:
-  true
+  REQUIRE_NOTHROW( original.data() )
 
 -------------------------------------------------------------------------------
 StringRef
   Substrings
-  c_str() causes copy
-  Self-assignment after substring
+  zero-based substring
 -------------------------------------------------------------------------------
 String.tests.cpp:<line number>
 ...............................................................................
 
 String.tests.cpp:<line number>: PASSED:
-  REQUIRE( isOwned(ss) == false )
+  REQUIRE( ss.empty() == false )
 with expansion:
   false == false
 
 String.tests.cpp:<line number>: PASSED:
-  REQUIRE( ss == "hello" )
+  REQUIRE( ss.size() == 5 )
 with expansion:
-  hello == "hello"
+  5 == 5
 
 String.tests.cpp:<line number>: PASSED:
-  REQUIRE( rawChars == ss.currentData() )
+  REQUIRE( std::strncmp( ss.data(), "hello", 5 ) == 0 )
 with expansion:
-  "hello world!" == "hello world!"
+  0 == 0
+
+String.tests.cpp:<line number>: PASSED:
+  REQUIRE( ss == "hello" )
+with expansion:
+  hello == "hello"
 
 -------------------------------------------------------------------------------
 StringRef
@@ -8187,22 +8663,22 @@ String.tests.cpp:<line number>
 ...............................................................................
 
 String.tests.cpp:<line number>: PASSED:
-  REQUIRE( s.c_str() == s2.c_str() )
+  REQUIRE( s.data() == s2.data() )
 with expansion:
   "hello world!" == "hello world!"
 
 -------------------------------------------------------------------------------
 StringRef
   Substrings
-  Pointer values of substring refs should not match
+  Pointer values of substring refs should also match
 -------------------------------------------------------------------------------
 String.tests.cpp:<line number>
 ...............................................................................
 
 String.tests.cpp:<line number>: PASSED:
-  REQUIRE( s.c_str() != ss.c_str() )
+  REQUIRE( s.data() == ss.data() )
 with expansion:
-  "hello world!" != "hello"
+  "hello world!" == "hello world!"
 
 -------------------------------------------------------------------------------
 StringRef
@@ -8219,20 +8695,38 @@ with expansion:
 
 -------------------------------------------------------------------------------
 StringRef
-  Comparisons
+  Substrings
+  Substring off the end are trimmed
+-------------------------------------------------------------------------------
+String.tests.cpp:<line number>
+...............................................................................
+
+String.tests.cpp:<line number>: PASSED:
+  REQUIRE( std::strcmp(ss.c_str(), "world!") == 0 )
+with expansion:
+  0 == 0
+
+-------------------------------------------------------------------------------
+StringRef
+  Comparisons are deep
 -------------------------------------------------------------------------------
 String.tests.cpp:<line number>
 ...............................................................................
 
 String.tests.cpp:<line number>: PASSED:
-  REQUIRE( StringRef("hello") == StringRef("hello") )
+  CHECK( (char*)buffer1 != (char*)buffer2 )
+with expansion:
+  "Hello" != "Hello"
+
+String.tests.cpp:<line number>: PASSED:
+  REQUIRE( left == right )
 with expansion:
-  hello == hello
+  Hello == Hello
 
 String.tests.cpp:<line number>: PASSED:
-  REQUIRE( StringRef("hello") != StringRef("cello") )
+  REQUIRE( left != left.substr(0, 3) )
 with expansion:
-  hello != cello
+  Hello != Hel
 
 -------------------------------------------------------------------------------
 StringRef
@@ -8324,6 +8818,64 @@ String.tests.cpp:<line number>: PASSED:
 with expansion:
   11 == 11
 
+-------------------------------------------------------------------------------
+StringRef at compilation time
+  Simple constructors
+-------------------------------------------------------------------------------
+String.tests.cpp:<line number>
+...............................................................................
+
+String.tests.cpp:<line number>: PASSED:
+with message:
+  StringRef{}.size() == 0
+
+String.tests.cpp:<line number>: PASSED:
+with message:
+  StringRef{ "abc", 3 }.size() == 3
+
+String.tests.cpp:<line number>: PASSED:
+with message:
+  StringRef{ "abc", 3 }.isNullTerminated()
+
+String.tests.cpp:<line number>: PASSED:
+with message:
+  StringRef{ "abc", 2 }.size() == 2
+
+String.tests.cpp:<line number>: PASSED:
+with message:
+  !(StringRef{ "abc", 2 }.isNullTerminated())
+
+-------------------------------------------------------------------------------
+StringRef at compilation time
+  UDL construction
+-------------------------------------------------------------------------------
+String.tests.cpp:<line number>
+...............................................................................
+
+String.tests.cpp:<line number>: PASSED:
+with message:
+  !(sr1.empty())
+
+String.tests.cpp:<line number>: PASSED:
+with message:
+  sr1.size() == 3
+
+String.tests.cpp:<line number>: PASSED:
+with message:
+  sr1.isNullTerminated()
+
+String.tests.cpp:<line number>: PASSED:
+with message:
+  sr2.empty()
+
+String.tests.cpp:<line number>: PASSED:
+with message:
+  sr2.size() == 0
+
+String.tests.cpp:<line number>: PASSED:
+with message:
+  sr2.isNullTerminated()
+
 -------------------------------------------------------------------------------
 Stringifying std::chrono::duration helpers
 -------------------------------------------------------------------------------
@@ -10913,263 +11465,6 @@ Xml.tests.cpp:<line number>: PASSED:
 with expansion:
   "[\x7F]" == "[\x7F]"
 
--------------------------------------------------------------------------------
-XmlEncode: UTF-8
-  Valid utf-8 strings
--------------------------------------------------------------------------------
-Xml.tests.cpp:<line number>
-...............................................................................
-
-Xml.tests.cpp:<line number>: PASSED:
-  CHECK( encode(u8"Here be 👾") == u8"Here be 👾" )
-with expansion:
-  "Here be 👾" == "Here be 👾"
-
-Xml.tests.cpp:<line number>: PASSED:
-  CHECK( encode(u8"šš") == u8"šš" )
-with expansion:
-  "šš" == "šš"
-
-Xml.tests.cpp:<line number>: PASSED:
-  CHECK( encode("\xDF\xBF") == "\xDF\xBF" )
-with expansion:
-  "߿" == "߿"
-
-Xml.tests.cpp:<line number>: PASSED:
-  CHECK( encode("\xE0\xA0\x80") == "\xE0\xA0\x80" )
-with expansion:
-  "ࠀ" == "ࠀ"
-
-Xml.tests.cpp:<line number>: PASSED:
-  CHECK( encode("\xED\x9F\xBF") == "\xED\x9F\xBF" )
-with expansion:
-  "퟿" == "퟿"
-
-Xml.tests.cpp:<line number>: PASSED:
-  CHECK( encode("\xEE\x80\x80") == "\xEE\x80\x80" )
-with expansion:
-  "" == ""
-
-Xml.tests.cpp:<line number>: PASSED:
-  CHECK( encode("\xEF\xBF\xBF") == "\xEF\xBF\xBF" )
-with expansion:
-  "￿" == "￿"
-
-Xml.tests.cpp:<line number>: PASSED:
-  CHECK( encode("\xF0\x90\x80\x80") == "\xF0\x90\x80\x80" )
-with expansion:
-  "𐀀" == "𐀀"
-
-Xml.tests.cpp:<line number>: PASSED:
-  CHECK( encode("\xF4\x8F\xBF\xBF") == "\xF4\x8F\xBF\xBF" )
-with expansion:
-  "􏿿" == "􏿿"
-
--------------------------------------------------------------------------------
-XmlEncode: UTF-8
-  Invalid utf-8 strings
-  Various broken strings
--------------------------------------------------------------------------------
-Xml.tests.cpp:<line number>
-...............................................................................
-
-Xml.tests.cpp:<line number>: PASSED:
-  CHECK( encode("Here \xFF be 👾") == u8"Here \\xFF be 👾" )
-with expansion:
-  "Here \xFF be 👾" == "Here \xFF be 👾"
-
-Xml.tests.cpp:<line number>: PASSED:
-  CHECK( encode("\xFF") == "\\xFF" )
-with expansion:
-  "\xFF" == "\xFF"
-
-Xml.tests.cpp:<line number>: PASSED:
-  CHECK( encode("\xC5\xC5\xA0") == u8"\\xC5Š" )
-with expansion:
-  "\xC5Š" == "\xC5Š"
-
-Xml.tests.cpp:<line number>: PASSED:
-  CHECK( encode("\xF4\x90\x80\x80") == u8"\\xF4\\x90\\x80\\x80" )
-with expansion:
-  "\xF4\x90\x80\x80" == "\xF4\x90\x80\x80"
-
--------------------------------------------------------------------------------
-XmlEncode: UTF-8
-  Invalid utf-8 strings
-  Overlong encodings
--------------------------------------------------------------------------------
-Xml.tests.cpp:<line number>
-...............................................................................
-
-Xml.tests.cpp:<line number>: PASSED:
-  CHECK( encode("\xC0\x80") == u8"\\xC0\\x80" )
-with expansion:
-  "\xC0\x80" == "\xC0\x80"
-
-Xml.tests.cpp:<line number>: PASSED:
-  CHECK( encode("\xF0\x80\x80\x80") == u8"\\xF0\\x80\\x80\\x80" )
-with expansion:
-  "\xF0\x80\x80\x80" == "\xF0\x80\x80\x80"
-
-Xml.tests.cpp:<line number>: PASSED:
-  CHECK( encode("\xC1\xBF") == u8"\\xC1\\xBF" )
-with expansion:
-  "\xC1\xBF" == "\xC1\xBF"
-
-Xml.tests.cpp:<line number>: PASSED:
-  CHECK( encode("\xE0\x9F\xBF") == u8"\\xE0\\x9F\\xBF" )
-with expansion:
-  "\xE0\x9F\xBF" == "\xE0\x9F\xBF"
-
-Xml.tests.cpp:<line number>: PASSED:
-  CHECK( encode("\xF0\x8F\xBF\xBF") == u8"\\xF0\\x8F\\xBF\\xBF" )
-with expansion:
-  "\xF0\x8F\xBF\xBF" == "\xF0\x8F\xBF\xBF"
-
--------------------------------------------------------------------------------
-XmlEncode: UTF-8
-  Invalid utf-8 strings
-  Surrogate pairs
--------------------------------------------------------------------------------
-Xml.tests.cpp:<line number>
-...............................................................................
-
-Xml.tests.cpp:<line number>: PASSED:
-  CHECK( encode("\xED\xA0\x80") == "\xED\xA0\x80" )
-with expansion:
-  "���" == "���"
-
-Xml.tests.cpp:<line number>: PASSED:
-  CHECK( encode("\xED\xAF\xBF") == "\xED\xAF\xBF" )
-with expansion:
-  "���" == "���"
-
-Xml.tests.cpp:<line number>: PASSED:
-  CHECK( encode("\xED\xB0\x80") == "\xED\xB0\x80" )
-with expansion:
-  "���" == "���"
-
-Xml.tests.cpp:<line number>: PASSED:
-  CHECK( encode("\xED\xBF\xBF") == "\xED\xBF\xBF" )
-with expansion:
-  "���" == "���"
-
--------------------------------------------------------------------------------
-XmlEncode: UTF-8
-  Invalid utf-8 strings
-  Invalid start byte
--------------------------------------------------------------------------------
-Xml.tests.cpp:<line number>
-...............................................................................
-
-Xml.tests.cpp:<line number>: PASSED:
-  CHECK( encode("\x80") == u8"\\x80" )
-with expansion:
-  "\x80" == "\x80"
-
-Xml.tests.cpp:<line number>: PASSED:
-  CHECK( encode("\x81") == u8"\\x81" )
-with expansion:
-  "\x81" == "\x81"
-
-Xml.tests.cpp:<line number>: PASSED:
-  CHECK( encode("\xBC") == u8"\\xBC" )
-with expansion:
-  "\xBC" == "\xBC"
-
-Xml.tests.cpp:<line number>: PASSED:
-  CHECK( encode("\xBF") == u8"\\xBF" )
-with expansion:
-  "\xBF" == "\xBF"
-
-Xml.tests.cpp:<line number>: PASSED:
-  CHECK( encode("\xF5\x80\x80\x80") == u8"\\xF5\\x80\\x80\\x80" )
-with expansion:
-  "\xF5\x80\x80\x80" == "\xF5\x80\x80\x80"
-
-Xml.tests.cpp:<line number>: PASSED:
-  CHECK( encode("\xF6\x80\x80\x80") == u8"\\xF6\\x80\\x80\\x80" )
-with expansion:
-  "\xF6\x80\x80\x80" == "\xF6\x80\x80\x80"
-
-Xml.tests.cpp:<line number>: PASSED:
-  CHECK( encode("\xF7\x80\x80\x80") == u8"\\xF7\\x80\\x80\\x80" )
-with expansion:
-  "\xF7\x80\x80\x80" == "\xF7\x80\x80\x80"
-
--------------------------------------------------------------------------------
-XmlEncode: UTF-8
-  Invalid utf-8 strings
-  Missing continuation byte(s)
--------------------------------------------------------------------------------
-Xml.tests.cpp:<line number>
-...............................................................................
-
-Xml.tests.cpp:<line number>: PASSED:
-  CHECK( encode("\xDE") == u8"\\xDE" )
-with expansion:
-  "\xDE" == "\xDE"
-
-Xml.tests.cpp:<line number>: PASSED:
-  CHECK( encode("\xDF") == u8"\\xDF" )
-with expansion:
-  "\xDF" == "\xDF"
-
-Xml.tests.cpp:<line number>: PASSED:
-  CHECK( encode("\xE0") == u8"\\xE0" )
-with expansion:
-  "\xE0" == "\xE0"
-
-Xml.tests.cpp:<line number>: PASSED:
-  CHECK( encode("\xEF") == u8"\\xEF" )
-with expansion:
-  "\xEF" == "\xEF"
-
-Xml.tests.cpp:<line number>: PASSED:
-  CHECK( encode("\xF0") == u8"\\xF0" )
-with expansion:
-  "\xF0" == "\xF0"
-
-Xml.tests.cpp:<line number>: PASSED:
-  CHECK( encode("\xF4") == u8"\\xF4" )
-with expansion:
-  "\xF4" == "\xF4"
-
-Xml.tests.cpp:<line number>: PASSED:
-  CHECK( encode("\xE0\x80") == u8"\\xE0\\x80" )
-with expansion:
-  "\xE0\x80" == "\xE0\x80"
-
-Xml.tests.cpp:<line number>: PASSED:
-  CHECK( encode("\xE0\xBF") == u8"\\xE0\\xBF" )
-with expansion:
-  "\xE0\xBF" == "\xE0\xBF"
-
-Xml.tests.cpp:<line number>: PASSED:
-  CHECK( encode("\xE1\x80") == u8"\\xE1\\x80" )
-with expansion:
-  "\xE1\x80" == "\xE1\x80"
-
-Xml.tests.cpp:<line number>: PASSED:
-  CHECK( encode("\xF0\x80") == u8"\\xF0\\x80" )
-with expansion:
-  "\xF0\x80" == "\xF0\x80"
-
-Xml.tests.cpp:<line number>: PASSED:
-  CHECK( encode("\xF4\x80") == u8"\\xF4\\x80" )
-with expansion:
-  "\xF4\x80" == "\xF4\x80"
-
-Xml.tests.cpp:<line number>: PASSED:
-  CHECK( encode("\xF0\x80\x80") == u8"\\xF0\\x80\\x80" )
-with expansion:
-  "\xF0\x80\x80" == "\xF0\x80\x80"
-
-Xml.tests.cpp:<line number>: PASSED:
-  CHECK( encode("\xF4\x80\x80") == u8"\\xF4\\x80\\x80" )
-with expansion:
-  "\xF4\x80\x80" == "\xF4\x80\x80"
-
 -------------------------------------------------------------------------------
 array<int, N> -> toString
 -------------------------------------------------------------------------------
@@ -12957,5 +13252,5 @@ Misc.tests.cpp:<line number>: PASSED:
 
 ===============================================================================
 test cases:  304 |  214 passed |  86 failed |  4 failed as expected
-assertions: 1638 | 1469 passed | 148 failed | 21 failed as expected
+assertions: 1676 | 1507 passed | 148 failed | 21 failed as expected
 
diff --git a/packages/Catch2/projects/SelfTest/Baselines/junit.sw.approved.txt b/packages/Catch2/projects/SelfTest/Baselines/junit.sw.approved.txt
index bfacb0330b8a0c2613e11e391ba2ca57808c06c0..41065c4e6a391537b6ab910426350e668bea7f0c 100644
--- a/packages/Catch2/projects/SelfTest/Baselines/junit.sw.approved.txt
+++ b/packages/Catch2/projects/SelfTest/Baselines/junit.sw.approved.txt
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <testsuitesloose text artifact
 >
-  <testsuite name="<exe-name>" errors="17" failures="132" tests="1639" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
+  <testsuite name="<exe-name>" errors="17" failures="132" tests="1677" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
     <properties>
       <property name="filters" value="~[!nonportable]~[!benchmark]~[approvals]"/>
       <property name="random-seed" value="1"/>
@@ -18,6 +18,7 @@
     <testcase classname="<exe-name>.global" name="#1455 - INFO and WARN can start with a linebreak" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="#1514: stderr/stdout is not captured in tests aborted by an exception" time="{duration}">
       <failure type="FAIL">
+FAILED:
 1514
 Tricky.tests.cpp:<line number>
       </failure>
@@ -31,6 +32,7 @@ Nor would this
     <testcase classname="<exe-name>.global" name="#1548" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="#748 - captures with unexpected exceptions/outside assertions" time="{duration}">
       <error type="TEST_CASE">
+FAILED:
 expected exception
 answer := 42
 Exception.tests.cpp:<line number>
@@ -38,6 +40,8 @@ Exception.tests.cpp:<line number>
     </testcase>
     <testcase classname="<exe-name>.global" name="#748 - captures with unexpected exceptions/inside REQUIRE_NOTHROW" time="{duration}">
       <error message="thisThrows()" type="REQUIRE_NOTHROW">
+FAILED:
+  REQUIRE_NOTHROW( thisThrows() )
 expected exception
 answer := 42
 Exception.tests.cpp:<line number>
@@ -47,7 +51,11 @@ Exception.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="#809" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="#833" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="#835 -- errno should not be touched by Catch" time="{duration}">
-      <failure message="1 == 0" type="CHECK">
+      <failure message="f() == 0" type="CHECK">
+FAILED:
+  CHECK( f() == 0 )
+with expansion:
+  1 == 0
 Misc.tests.cpp:<line number>
       </failure>
     </testcase>
@@ -59,27 +67,53 @@ Misc.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="#961 -- Dynamically created sections should all be reported/Looped section 4" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="'Not' checks that should fail" time="{duration}">
       <failure message="false != false" type="CHECK">
+FAILED:
+  CHECK( false != false )
 Condition.tests.cpp:<line number>
       </failure>
       <failure message="true != true" type="CHECK">
+FAILED:
+  CHECK( true != true )
 Condition.tests.cpp:<line number>
       </failure>
-      <failure message="false" type="CHECK">
+      <failure message="!true" type="CHECK">
+FAILED:
+  CHECK( !true )
+with expansion:
+  false
 Condition.tests.cpp:<line number>
       </failure>
-      <failure message="!true" type="CHECK_FALSE">
+      <failure message="!(true)" type="CHECK_FALSE">
+FAILED:
+  CHECK_FALSE( true )
+with expansion:
+  !true
 Condition.tests.cpp:<line number>
       </failure>
-      <failure message="false" type="CHECK">
+      <failure message="!trueValue" type="CHECK">
+FAILED:
+  CHECK( !trueValue )
+with expansion:
+  false
 Condition.tests.cpp:<line number>
       </failure>
-      <failure message="!true" type="CHECK_FALSE">
+      <failure message="!(trueValue)" type="CHECK_FALSE">
+FAILED:
+  CHECK_FALSE( trueValue )
+with expansion:
+  !true
 Condition.tests.cpp:<line number>
       </failure>
-      <failure message="false" type="CHECK">
+      <failure message="!(1 == 1)" type="CHECK">
+FAILED:
+  CHECK( !(1 == 1) )
+with expansion:
+  false
 Condition.tests.cpp:<line number>
       </failure>
       <failure message="!(1 == 1)" type="CHECK_FALSE">
+FAILED:
+  CHECK_FALSE( 1 == 1 )
 Condition.tests.cpp:<line number>
       </failure>
     </testcase>
@@ -91,28 +125,48 @@ Condition.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="(unimplemented) static bools can be evaluated/direct" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="3x3x3 ints" time="{duration}"/>
     <testcase classname="<exe-name>.TestClass" name="A METHOD_AS_TEST_CASE based test run that fails" time="{duration}">
-      <failure message="&quot;hello&quot; == &quot;world&quot;" type="REQUIRE">
+      <failure message="s == &quot;world&quot;" type="REQUIRE">
+FAILED:
+  REQUIRE( s == "world" )
+with expansion:
+  "hello" == "world"
 Class.tests.cpp:<line number>
       </failure>
     </testcase>
     <testcase classname="<exe-name>.TestClass" name="A METHOD_AS_TEST_CASE based test run that succeeds" time="{duration}"/>
     <testcase classname="<exe-name>.Template_Fixture_2" name="A TEMPLATE_PRODUCT_TEST_CASE_METHOD based test run that fails - Template_Foo&lt;float>" time="{duration}">
-      <failure message="0 == 1" type="REQUIRE">
+      <failure message="Template_Fixture_2&lt;TestType>::m_a.size() == 1" type="REQUIRE">
+FAILED:
+  REQUIRE( Template_Fixture_2&lt;TestType>::m_a.size() == 1 )
+with expansion:
+  0 == 1
 Class.tests.cpp:<line number>
       </failure>
     </testcase>
     <testcase classname="<exe-name>.Template_Fixture_2" name="A TEMPLATE_PRODUCT_TEST_CASE_METHOD based test run that fails - Template_Foo&lt;int>" time="{duration}">
-      <failure message="0 == 1" type="REQUIRE">
+      <failure message="Template_Fixture_2&lt;TestType>::m_a.size() == 1" type="REQUIRE">
+FAILED:
+  REQUIRE( Template_Fixture_2&lt;TestType>::m_a.size() == 1 )
+with expansion:
+  0 == 1
 Class.tests.cpp:<line number>
       </failure>
     </testcase>
     <testcase classname="<exe-name>.Template_Fixture_2" name="A TEMPLATE_PRODUCT_TEST_CASE_METHOD based test run that fails - std::vector&lt;float>" time="{duration}">
-      <failure message="0 == 1" type="REQUIRE">
+      <failure message="Template_Fixture_2&lt;TestType>::m_a.size() == 1" type="REQUIRE">
+FAILED:
+  REQUIRE( Template_Fixture_2&lt;TestType>::m_a.size() == 1 )
+with expansion:
+  0 == 1
 Class.tests.cpp:<line number>
       </failure>
     </testcase>
     <testcase classname="<exe-name>.Template_Fixture_2" name="A TEMPLATE_PRODUCT_TEST_CASE_METHOD based test run that fails - std::vector&lt;int>" time="{duration}">
-      <failure message="0 == 1" type="REQUIRE">
+      <failure message="Template_Fixture_2&lt;TestType>::m_a.size() == 1" type="REQUIRE">
+FAILED:
+  REQUIRE( Template_Fixture_2&lt;TestType>::m_a.size() == 1 )
+with expansion:
+  0 == 1
 Class.tests.cpp:<line number>
       </failure>
     </testcase>
@@ -121,22 +175,38 @@ Class.tests.cpp:<line number>
     <testcase classname="<exe-name>.Template_Fixture_2" name="A TEMPLATE_PRODUCT_TEST_CASE_METHOD based test run that succeeds - std::vector&lt;float>" time="{duration}"/>
     <testcase classname="<exe-name>.Template_Fixture_2" name="A TEMPLATE_PRODUCT_TEST_CASE_METHOD based test run that succeeds - std::vector&lt;int>" time="{duration}"/>
     <testcase classname="<exe-name>.Template_Fixture_2" name="A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that fails - Template_Foo_2&lt;float, 6>" time="{duration}">
-      <failure message="6 &lt; 2" type="REQUIRE">
+      <failure message="Template_Fixture_2&lt;TestType>{}.m_a.size() &lt; 2" type="REQUIRE">
+FAILED:
+  REQUIRE( Template_Fixture_2&lt;TestType>{}.m_a.size() &lt; 2 )
+with expansion:
+  6 &lt; 2
 Class.tests.cpp:<line number>
       </failure>
     </testcase>
     <testcase classname="<exe-name>.Template_Fixture_2" name="A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that fails - Template_Foo_2&lt;int, 2>" time="{duration}">
-      <failure message="2 &lt; 2" type="REQUIRE">
+      <failure message="Template_Fixture_2&lt;TestType>{}.m_a.size() &lt; 2" type="REQUIRE">
+FAILED:
+  REQUIRE( Template_Fixture_2&lt;TestType>{}.m_a.size() &lt; 2 )
+with expansion:
+  2 &lt; 2
 Class.tests.cpp:<line number>
       </failure>
     </testcase>
     <testcase classname="<exe-name>.Template_Fixture_2" name="A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that fails - std::array&lt;float, 6>" time="{duration}">
-      <failure message="6 &lt; 2" type="REQUIRE">
+      <failure message="Template_Fixture_2&lt;TestType>{}.m_a.size() &lt; 2" type="REQUIRE">
+FAILED:
+  REQUIRE( Template_Fixture_2&lt;TestType>{}.m_a.size() &lt; 2 )
+with expansion:
+  6 &lt; 2
 Class.tests.cpp:<line number>
       </failure>
     </testcase>
     <testcase classname="<exe-name>.Template_Fixture_2" name="A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that fails - std::array&lt;int, 2>" time="{duration}">
-      <failure message="2 &lt; 2" type="REQUIRE">
+      <failure message="Template_Fixture_2&lt;TestType>{}.m_a.size() &lt; 2" type="REQUIRE">
+FAILED:
+  REQUIRE( Template_Fixture_2&lt;TestType>{}.m_a.size() &lt; 2 )
+with expansion:
+  2 &lt; 2
 Class.tests.cpp:<line number>
       </failure>
     </testcase>
@@ -145,17 +215,29 @@ Class.tests.cpp:<line number>
     <testcase classname="<exe-name>.Template_Fixture_2" name="A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that succeeds - std::array&lt;float,6>" time="{duration}"/>
     <testcase classname="<exe-name>.Template_Fixture_2" name="A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that succeeds - std::array&lt;int,2>" time="{duration}"/>
     <testcase classname="<exe-name>.Template_Fixture" name="A TEMPLATE_TEST_CASE_METHOD based test run that fails - double" time="{duration}">
-      <failure message="1.0 == 2" type="REQUIRE">
+      <failure message="Template_Fixture&lt;TestType>::m_a == 2" type="REQUIRE">
+FAILED:
+  REQUIRE( Template_Fixture&lt;TestType>::m_a == 2 )
+with expansion:
+  1.0 == 2
 Class.tests.cpp:<line number>
       </failure>
     </testcase>
     <testcase classname="<exe-name>.Template_Fixture" name="A TEMPLATE_TEST_CASE_METHOD based test run that fails - float" time="{duration}">
-      <failure message="1.0f == 2" type="REQUIRE">
+      <failure message="Template_Fixture&lt;TestType>::m_a == 2" type="REQUIRE">
+FAILED:
+  REQUIRE( Template_Fixture&lt;TestType>::m_a == 2 )
+with expansion:
+  1.0f == 2
 Class.tests.cpp:<line number>
       </failure>
     </testcase>
     <testcase classname="<exe-name>.Template_Fixture" name="A TEMPLATE_TEST_CASE_METHOD based test run that fails - int" time="{duration}">
-      <failure message="1 == 2" type="REQUIRE">
+      <failure message="Template_Fixture&lt;TestType>::m_a == 2" type="REQUIRE">
+FAILED:
+  REQUIRE( Template_Fixture&lt;TestType>::m_a == 2 )
+with expansion:
+  1 == 2
 Class.tests.cpp:<line number>
       </failure>
     </testcase>
@@ -163,17 +245,29 @@ Class.tests.cpp:<line number>
     <testcase classname="<exe-name>.Template_Fixture" name="A TEMPLATE_TEST_CASE_METHOD based test run that succeeds - float" time="{duration}"/>
     <testcase classname="<exe-name>.Template_Fixture" name="A TEMPLATE_TEST_CASE_METHOD based test run that succeeds - int" time="{duration}"/>
     <testcase classname="<exe-name>.Nttp_Fixture" name="A TEMPLATE_TEST_CASE_METHOD_SIG based test run that fails - 1" time="{duration}">
-      <failure message="1 == 0" type="REQUIRE">
+      <failure message="Nttp_Fixture&lt;V>::value == 0" type="REQUIRE">
+FAILED:
+  REQUIRE( Nttp_Fixture&lt;V>::value == 0 )
+with expansion:
+  1 == 0
 Class.tests.cpp:<line number>
       </failure>
     </testcase>
     <testcase classname="<exe-name>.Nttp_Fixture" name="A TEMPLATE_TEST_CASE_METHOD_SIG based test run that fails - 3" time="{duration}">
-      <failure message="3 == 0" type="REQUIRE">
+      <failure message="Nttp_Fixture&lt;V>::value == 0" type="REQUIRE">
+FAILED:
+  REQUIRE( Nttp_Fixture&lt;V>::value == 0 )
+with expansion:
+  3 == 0
 Class.tests.cpp:<line number>
       </failure>
     </testcase>
     <testcase classname="<exe-name>.Nttp_Fixture" name="A TEMPLATE_TEST_CASE_METHOD_SIG based test run that fails - 6" time="{duration}">
-      <failure message="6 == 0" type="REQUIRE">
+      <failure message="Nttp_Fixture&lt;V>::value == 0" type="REQUIRE">
+FAILED:
+  REQUIRE( Nttp_Fixture&lt;V>::value == 0 )
+with expansion:
+  6 == 0
 Class.tests.cpp:<line number>
       </failure>
     </testcase>
@@ -181,7 +275,11 @@ Class.tests.cpp:<line number>
     <testcase classname="<exe-name>.Nttp_Fixture" name="A TEMPLATE_TEST_CASE_METHOD_SIG based test run that succeeds - 3" time="{duration}"/>
     <testcase classname="<exe-name>.Nttp_Fixture" name="A TEMPLATE_TEST_CASE_METHOD_SIG based test run that succeeds - 6" time="{duration}"/>
     <testcase classname="<exe-name>.Fixture" name="A TEST_CASE_METHOD based test run that fails" time="{duration}">
-      <failure message="1 == 2" type="REQUIRE">
+      <failure message="m_a == 2" type="REQUIRE">
+FAILED:
+  REQUIRE( m_a == 2 )
+with expansion:
+  1 == 2
 Class.tests.cpp:<line number>
       </failure>
     </testcase>
@@ -197,16 +295,25 @@ Class.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="A comparison that uses literals instead of the normal constructor" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="A couple of nested sections followed by a failure" time="{duration}">
       <failure type="FAIL">
+FAILED:
 to infinity and beyond
 Misc.tests.cpp:<line number>
       </failure>
     </testcase>
     <testcase classname="<exe-name>.global" name="A couple of nested sections followed by a failure/Outer/Inner" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="A failing expression with a non streamable type is still captured" time="{duration}">
-      <failure message="0x<hex digits> == 0x<hex digits>" type="CHECK">
+      <failure message="&amp;o1 == &amp;o2" type="CHECK">
+FAILED:
+  CHECK( &amp;o1 == &amp;o2 )
+with expansion:
+  0x<hex digits> == 0x<hex digits>
 Tricky.tests.cpp:<line number>
       </failure>
-      <failure message="{?} == {?}" type="CHECK">
+      <failure message="o1 == o2" type="CHECK">
+FAILED:
+  CHECK( o1 == o2 )
+with expansion:
+  {?} == {?}
 Tricky.tests.cpp:<line number>
       </failure>
     </testcase>
@@ -214,6 +321,8 @@ Tricky.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="An expression with side-effects should only be evaluated once" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="An unchecked exception reports the line of the last assertion" time="{duration}">
       <error message="{Unknown expression after the reported line}">
+FAILED:
+  {Unknown expression after the reported line}
 unexpected exception
 Exception.tests.cpp:<line number>
       </error>
@@ -248,10 +357,19 @@ Exception.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="Comparisons between unsigned ints and negative signed ints match c++ standard behaviour" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Comparisons with int literals don't warn when mixing signed/ unsigned" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Contains string matcher" time="{duration}">
-      <failure message="&quot;this string contains 'abc' as a substring&quot; contains: &quot;not there&quot; (case insensitive)" type="CHECK_THAT">
+      <failure message="testStringForMatching(), Contains(&quot;not there&quot;, Catch::CaseSensitive::No)" type="CHECK_THAT">
+FAILED:
+  CHECK_THAT( testStringForMatching(), Contains("not there", Catch::CaseSensitive::No) )
+with expansion:
+  "this string contains 'abc' as a substring" contains: "not there" (case
+  insensitive)
 Matchers.tests.cpp:<line number>
       </failure>
-      <failure message="&quot;this string contains 'abc' as a substring&quot; contains: &quot;STRING&quot;" type="CHECK_THAT">
+      <failure message="testStringForMatching(), Contains(&quot;STRING&quot;)" type="CHECK_THAT">
+FAILED:
+  CHECK_THAT( testStringForMatching(), Contains("STRING") )
+with expansion:
+  "this string contains 'abc' as a substring" contains: "STRING"
 Matchers.tests.cpp:<line number>
       </failure>
     </testcase>
@@ -260,18 +378,23 @@ Matchers.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="Copy and then generate a range/Final validation" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Custom exceptions can be translated when testing for nothrow" time="{duration}">
       <error message="throwCustom()" type="REQUIRE_NOTHROW">
+FAILED:
+  REQUIRE_NOTHROW( throwCustom() )
 custom exception - not std
 Exception.tests.cpp:<line number>
       </error>
     </testcase>
     <testcase classname="<exe-name>.global" name="Custom exceptions can be translated when testing for throwing as something else" time="{duration}">
       <error message="throwCustom(), std::exception" type="REQUIRE_THROWS_AS">
+FAILED:
+  REQUIRE_THROWS_AS( throwCustom(), std::exception )
 custom exception - not std
 Exception.tests.cpp:<line number>
       </error>
     </testcase>
     <testcase classname="<exe-name>.global" name="Custom std-exceptions can be custom translated" time="{duration}">
       <error type="TEST_CASE">
+FAILED:
 custom std exception
 Exception.tests.cpp:<line number>
       </error>
@@ -279,10 +402,19 @@ Exception.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="Default scale is invisible to comparison" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Directly creating an EnumInfo" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="EndsWith string matcher" time="{duration}">
-      <failure message="&quot;this string contains 'abc' as a substring&quot; ends with: &quot;Substring&quot;" type="CHECK_THAT">
+      <failure message="testStringForMatching(), EndsWith(&quot;Substring&quot;)" type="CHECK_THAT">
+FAILED:
+  CHECK_THAT( testStringForMatching(), EndsWith("Substring") )
+with expansion:
+  "this string contains 'abc' as a substring" ends with: "Substring"
 Matchers.tests.cpp:<line number>
       </failure>
-      <failure message="&quot;this string contains 'abc' as a substring&quot; ends with: &quot;this&quot; (case insensitive)" type="CHECK_THAT">
+      <failure message="testStringForMatching(), EndsWith(&quot;this&quot;, Catch::CaseSensitive::No)" type="CHECK_THAT">
+FAILED:
+  CHECK_THAT( testStringForMatching(), EndsWith("this", Catch::CaseSensitive::No) )
+with expansion:
+  "this string contains 'abc' as a substring" ends with: "this" (case
+  insensitive)
 Matchers.tests.cpp:<line number>
       </failure>
     </testcase>
@@ -290,80 +422,158 @@ Matchers.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="Enums in namespaces can quickly have stringification enabled using REGISTER_ENUM" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Epsilon only applies to Approx's value" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Equality checks that should fail" time="{duration}">
-      <failure message="7 == 6" type="CHECK">
+      <failure message="data.int_seven == 6" type="CHECK">
+FAILED:
+  CHECK( data.int_seven == 6 )
+with expansion:
+  7 == 6
 Condition.tests.cpp:<line number>
       </failure>
-      <failure message="7 == 8" type="CHECK">
+      <failure message="data.int_seven == 8" type="CHECK">
+FAILED:
+  CHECK( data.int_seven == 8 )
+with expansion:
+  7 == 8
 Condition.tests.cpp:<line number>
       </failure>
-      <failure message="7 == 0" type="CHECK">
+      <failure message="data.int_seven == 0" type="CHECK">
+FAILED:
+  CHECK( data.int_seven == 0 )
+with expansion:
+  7 == 0
 Condition.tests.cpp:<line number>
       </failure>
-      <failure message="9.1f == Approx( 9.1099996567 )" type="CHECK">
+      <failure message="data.float_nine_point_one == Approx( 9.11f )" type="CHECK">
+FAILED:
+  CHECK( data.float_nine_point_one == Approx( 9.11f ) )
+with expansion:
+  9.1f == Approx( 9.1099996567 )
 Condition.tests.cpp:<line number>
       </failure>
-      <failure message="9.1f == Approx( 9.0 )" type="CHECK">
+      <failure message="data.float_nine_point_one == Approx( 9.0f )" type="CHECK">
+FAILED:
+  CHECK( data.float_nine_point_one == Approx( 9.0f ) )
+with expansion:
+  9.1f == Approx( 9.0 )
 Condition.tests.cpp:<line number>
       </failure>
-      <failure message="9.1f == Approx( 1.0 )" type="CHECK">
+      <failure message="data.float_nine_point_one == Approx( 1 )" type="CHECK">
+FAILED:
+  CHECK( data.float_nine_point_one == Approx( 1 ) )
+with expansion:
+  9.1f == Approx( 1.0 )
 Condition.tests.cpp:<line number>
       </failure>
-      <failure message="9.1f == Approx( 0.0 )" type="CHECK">
+      <failure message="data.float_nine_point_one == Approx( 0 )" type="CHECK">
+FAILED:
+  CHECK( data.float_nine_point_one == Approx( 0 ) )
+with expansion:
+  9.1f == Approx( 0.0 )
 Condition.tests.cpp:<line number>
       </failure>
-      <failure message="3.1415926535 == Approx( 3.1415 )" type="CHECK">
+      <failure message="data.double_pi == Approx( 3.1415 )" type="CHECK">
+FAILED:
+  CHECK( data.double_pi == Approx( 3.1415 ) )
+with expansion:
+  3.1415926535 == Approx( 3.1415 )
 Condition.tests.cpp:<line number>
       </failure>
-      <failure message="&quot;hello&quot; == &quot;goodbye&quot;" type="CHECK">
+      <failure message="data.str_hello == &quot;goodbye&quot;" type="CHECK">
+FAILED:
+  CHECK( data.str_hello == "goodbye" )
+with expansion:
+  "hello" == "goodbye"
 Condition.tests.cpp:<line number>
       </failure>
-      <failure message="&quot;hello&quot; == &quot;hell&quot;" type="CHECK">
+      <failure message="data.str_hello == &quot;hell&quot;" type="CHECK">
+FAILED:
+  CHECK( data.str_hello == "hell" )
+with expansion:
+  "hello" == "hell"
 Condition.tests.cpp:<line number>
       </failure>
-      <failure message="&quot;hello&quot; == &quot;hello1&quot;" type="CHECK">
+      <failure message="data.str_hello == &quot;hello1&quot;" type="CHECK">
+FAILED:
+  CHECK( data.str_hello == "hello1" )
+with expansion:
+  "hello" == "hello1"
 Condition.tests.cpp:<line number>
       </failure>
-      <failure message="5 == 6" type="CHECK">
+      <failure message="data.str_hello.size() == 6" type="CHECK">
+FAILED:
+  CHECK( data.str_hello.size() == 6 )
+with expansion:
+  5 == 6
 Condition.tests.cpp:<line number>
       </failure>
-      <failure message="1.3 == Approx( 1.301 )" type="CHECK">
+      <failure message="x == Approx( 1.301 )" type="CHECK">
+FAILED:
+  CHECK( x == Approx( 1.301 ) )
+with expansion:
+  1.3 == Approx( 1.301 )
 Condition.tests.cpp:<line number>
       </failure>
     </testcase>
     <testcase classname="<exe-name>.global" name="Equality checks that should succeed" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Equals" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Equals string matcher" time="{duration}">
-      <failure message="&quot;this string contains 'abc' as a substring&quot; equals: &quot;this string contains 'ABC' as a substring&quot;" type="CHECK_THAT">
+      <failure message="testStringForMatching(), Equals(&quot;this string contains 'ABC' as a substring&quot;)" type="CHECK_THAT">
+FAILED:
+  CHECK_THAT( testStringForMatching(), Equals("this string contains 'ABC' as a substring") )
+with expansion:
+  "this string contains 'abc' as a substring" equals: "this string contains
+  'ABC' as a substring"
 Matchers.tests.cpp:<line number>
       </failure>
-      <failure message="&quot;this string contains 'abc' as a substring&quot; equals: &quot;something else&quot; (case insensitive)" type="CHECK_THAT">
+      <failure message="testStringForMatching(), Equals(&quot;something else&quot;, Catch::CaseSensitive::No)" type="CHECK_THAT">
+FAILED:
+  CHECK_THAT( testStringForMatching(), Equals("something else", Catch::CaseSensitive::No) )
+with expansion:
+  "this string contains 'abc' as a substring" equals: "something else" (case
+  insensitive)
 Matchers.tests.cpp:<line number>
       </failure>
     </testcase>
     <testcase classname="<exe-name>.global" name="Exception as a value (e.g. in REQUIRE_THROWS_MATCHES) can be stringified" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Exception matchers that fail/No exception" time="{duration}">
       <failure message="doesNotThrow(), SpecialException, ExceptionMatcher{1}" type="CHECK_THROWS_MATCHES">
+FAILED:
+  CHECK_THROWS_MATCHES( doesNotThrow(), SpecialException, ExceptionMatcher{1} )
 Matchers.tests.cpp:<line number>
       </failure>
       <failure message="doesNotThrow(), SpecialException, ExceptionMatcher{1}" type="REQUIRE_THROWS_MATCHES">
+FAILED:
+  REQUIRE_THROWS_MATCHES( doesNotThrow(), SpecialException, ExceptionMatcher{1} )
 Matchers.tests.cpp:<line number>
       </failure>
     </testcase>
     <testcase classname="<exe-name>.global" name="Exception matchers that fail/Type mismatch" time="{duration}">
       <error message="throwsAsInt(1), SpecialException, ExceptionMatcher{1}" type="CHECK_THROWS_MATCHES">
+FAILED:
+  CHECK_THROWS_MATCHES( throwsAsInt(1), SpecialException, ExceptionMatcher{1} )
 Unknown exception
 Matchers.tests.cpp:<line number>
       </error>
       <error message="throwsAsInt(1), SpecialException, ExceptionMatcher{1}" type="REQUIRE_THROWS_MATCHES">
+FAILED:
+  REQUIRE_THROWS_MATCHES( throwsAsInt(1), SpecialException, ExceptionMatcher{1} )
 Unknown exception
 Matchers.tests.cpp:<line number>
       </error>
     </testcase>
     <testcase classname="<exe-name>.global" name="Exception matchers that fail/Contents are wrong" time="{duration}">
-      <failure message="SpecialException::what special exception has value of 1" type="CHECK_THROWS_MATCHES">
+      <failure message="throwsSpecialException(3), SpecialException, ExceptionMatcher{1}" type="CHECK_THROWS_MATCHES">
+FAILED:
+  CHECK_THROWS_MATCHES( throwsSpecialException(3), SpecialException, ExceptionMatcher{1} )
+with expansion:
+  SpecialException::what special exception has value of 1
 Matchers.tests.cpp:<line number>
       </failure>
-      <failure message="SpecialException::what special exception has value of 1" type="REQUIRE_THROWS_MATCHES">
+      <failure message="throwsSpecialException(4), SpecialException, ExceptionMatcher{1}" type="REQUIRE_THROWS_MATCHES">
+FAILED:
+  REQUIRE_THROWS_MATCHES( throwsSpecialException(4), SpecialException, ExceptionMatcher{1} )
+with expansion:
+  SpecialException::what special exception has value of 1
 Matchers.tests.cpp:<line number>
       </failure>
     </testcase>
@@ -374,30 +584,39 @@ Matchers.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="Exceptions matchers" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Expected exceptions that don't throw or unexpected exceptions fail the test" time="{duration}">
       <error message="thisThrows(), std::string" type="CHECK_THROWS_AS">
+FAILED:
+  CHECK_THROWS_AS( thisThrows(), std::string )
 expected exception
 Exception.tests.cpp:<line number>
       </error>
       <failure message="thisDoesntThrow(), std::domain_error" type="CHECK_THROWS_AS">
+FAILED:
+  CHECK_THROWS_AS( thisDoesntThrow(), std::domain_error )
 Exception.tests.cpp:<line number>
       </failure>
       <error message="thisThrows()" type="CHECK_NOTHROW">
+FAILED:
+  CHECK_NOTHROW( thisThrows() )
 expected exception
 Exception.tests.cpp:<line number>
       </error>
     </testcase>
     <testcase classname="<exe-name>.global" name="FAIL aborts the test" time="{duration}">
       <failure type="FAIL">
+FAILED:
 This is a failure
 Message.tests.cpp:<line number>
       </failure>
     </testcase>
     <testcase classname="<exe-name>.global" name="FAIL does not require an argument" time="{duration}">
       <failure type="FAIL">
+FAILED:
 Message.tests.cpp:<line number>
       </failure>
     </testcase>
     <testcase classname="<exe-name>.global" name="FAIL_CHECK does not abort the test" time="{duration}">
       <failure type="FAIL_CHECK">
+FAILED:
 This is a failure
 Message.tests.cpp:<line number>
       </failure>
@@ -444,25 +663,40 @@ Message.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="Generators internals/Range/Positive manual step/Integer/Exact" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Generators internals/Range/Positive manual step/Integer/Slightly over end" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Generators internals/Range/Positive manual step/Integer/Slightly under end" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Generators internals/Range/Positive manual step/Floating Point/Exact" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Generators internals/Range/Positive manual step/Floating Point/Slightly over end" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Generators internals/Range/Positive manual step/Floating Point/Slightly under end" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Generators internals/Range/Negative manual step/Integer/Exact" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Generators internals/Range/Negative manual step/Integer/Slightly over end" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Generators internals/Range/Negative manual step/Integer/Slightly under end" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Greater-than inequalities with different epsilons" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="INFO and WARN do not abort tests" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="INFO gets logged on failure" time="{duration}">
-      <failure message="2 == 1" type="REQUIRE">
+      <failure message="a == 1" type="REQUIRE">
+FAILED:
+  REQUIRE( a == 1 )
+with expansion:
+  2 == 1
 this message should be logged
 so should this
 Message.tests.cpp:<line number>
       </failure>
     </testcase>
     <testcase classname="<exe-name>.global" name="INFO gets logged on failure, even if captured before successful assertions" time="{duration}">
-      <failure message="2 == 1" type="CHECK">
+      <failure message="a == 1" type="CHECK">
+FAILED:
+  CHECK( a == 1 )
+with expansion:
+  2 == 1
 this message may be logged later
 this message should be logged
 Message.tests.cpp:<line number>
       </failure>
-      <failure message="2 == 0" type="CHECK">
+      <failure message="a == 0" type="CHECK">
+FAILED:
+  CHECK( a == 0 )
+with expansion:
+  2 == 0
 this message may be logged later
 this message should be logged
 and this, but later
@@ -470,26 +704,50 @@ Message.tests.cpp:<line number>
       </failure>
     </testcase>
     <testcase classname="<exe-name>.global" name="INFO is reset for each loop" time="{duration}">
-      <failure message="10 &lt; 10" type="REQUIRE">
+      <failure message="i &lt; 10" type="REQUIRE">
+FAILED:
+  REQUIRE( i &lt; 10 )
+with expansion:
+  10 &lt; 10
 current counter 10
 i := 10
 Message.tests.cpp:<line number>
       </failure>
     </testcase>
     <testcase classname="<exe-name>.global" name="Inequality checks that should fail" time="{duration}">
-      <failure message="7 != 7" type="CHECK">
+      <failure message="data.int_seven != 7" type="CHECK">
+FAILED:
+  CHECK( data.int_seven != 7 )
+with expansion:
+  7 != 7
 Condition.tests.cpp:<line number>
       </failure>
-      <failure message="9.1f != Approx( 9.1000003815 )" type="CHECK">
+      <failure message="data.float_nine_point_one != Approx( 9.1f )" type="CHECK">
+FAILED:
+  CHECK( data.float_nine_point_one != Approx( 9.1f ) )
+with expansion:
+  9.1f != Approx( 9.1000003815 )
 Condition.tests.cpp:<line number>
       </failure>
-      <failure message="3.1415926535 != Approx( 3.1415926535 )" type="CHECK">
+      <failure message="data.double_pi != Approx( 3.1415926535 )" type="CHECK">
+FAILED:
+  CHECK( data.double_pi != Approx( 3.1415926535 ) )
+with expansion:
+  3.1415926535 != Approx( 3.1415926535 )
 Condition.tests.cpp:<line number>
       </failure>
-      <failure message="&quot;hello&quot; != &quot;hello&quot;" type="CHECK">
+      <failure message="data.str_hello != &quot;hello&quot;" type="CHECK">
+FAILED:
+  CHECK( data.str_hello != "hello" )
+with expansion:
+  "hello" != "hello"
 Condition.tests.cpp:<line number>
       </failure>
-      <failure message="5 != 5" type="CHECK">
+      <failure message="data.str_hello.size() != 5" type="CHECK">
+FAILED:
+  CHECK( data.str_hello.size() != 5 )
+with expansion:
+  5 != 5
 Condition.tests.cpp:<line number>
       </failure>
     </testcase>
@@ -500,18 +758,31 @@ Condition.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="Matchers can be (AnyOf) composed with the || operator" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Matchers can be composed with both &amp;&amp; and ||" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Matchers can be composed with both &amp;&amp; and || - failing" time="{duration}">
-      <failure message="&quot;this string contains 'abc' as a substring&quot; ( ( contains: &quot;string&quot; or contains: &quot;different&quot; ) and contains: &quot;random&quot; )" type="CHECK_THAT">
+      <failure message="testStringForMatching(), (Contains(&quot;string&quot;) || Contains(&quot;different&quot;)) &amp;&amp; Contains(&quot;random&quot;)" type="CHECK_THAT">
+FAILED:
+  CHECK_THAT( testStringForMatching(), (Contains("string") || Contains("different")) &amp;&amp; Contains("random") )
+with expansion:
+  "this string contains 'abc' as a substring" ( ( contains: "string" or
+  contains: "different" ) and contains: "random" )
 Matchers.tests.cpp:<line number>
       </failure>
     </testcase>
     <testcase classname="<exe-name>.global" name="Matchers can be negated (Not) with the ! operator" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Matchers can be negated (Not) with the ! operator - failing" time="{duration}">
-      <failure message="&quot;this string contains 'abc' as a substring&quot; not contains: &quot;substring&quot;" type="CHECK_THAT">
+      <failure message="testStringForMatching(), !Contains(&quot;substring&quot;)" type="CHECK_THAT">
+FAILED:
+  CHECK_THAT( testStringForMatching(), !Contains("substring") )
+with expansion:
+  "this string contains 'abc' as a substring" not contains: "substring"
 Matchers.tests.cpp:<line number>
       </failure>
     </testcase>
     <testcase classname="<exe-name>.global" name="Mismatching exception messages failing the test" time="{duration}">
-      <failure message="&quot;expected exception&quot; equals: &quot;should fail&quot;" type="REQUIRE_THROWS_WITH">
+      <failure message="thisThrows(), &quot;should fail&quot;" type="REQUIRE_THROWS_WITH">
+FAILED:
+  REQUIRE_THROWS_WITH( thisThrows(), "should fail" )
+with expansion:
+  "expected exception" equals: "should fail"
 Exception.tests.cpp:<line number>
       </failure>
     </testcase>
@@ -519,6 +790,7 @@ Exception.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="Nice descriptive name" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Non-std exceptions can be translated" time="{duration}">
       <error type="TEST_CASE">
+FAILED:
 custom exception
 Exception.tests.cpp:<line number>
       </error>
@@ -526,61 +798,137 @@ Exception.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="Objects that evaluated in boolean contexts can be checked" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Optionally static assertions" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Ordering comparison checks that should fail" time="{duration}">
-      <failure message="7 > 7" type="CHECK">
+      <failure message="data.int_seven > 7" type="CHECK">
+FAILED:
+  CHECK( data.int_seven > 7 )
+with expansion:
+  7 > 7
 Condition.tests.cpp:<line number>
       </failure>
-      <failure message="7 &lt; 7" type="CHECK">
+      <failure message="data.int_seven &lt; 7" type="CHECK">
+FAILED:
+  CHECK( data.int_seven &lt; 7 )
+with expansion:
+  7 &lt; 7
 Condition.tests.cpp:<line number>
       </failure>
-      <failure message="7 > 8" type="CHECK">
+      <failure message="data.int_seven > 8" type="CHECK">
+FAILED:
+  CHECK( data.int_seven > 8 )
+with expansion:
+  7 > 8
 Condition.tests.cpp:<line number>
       </failure>
-      <failure message="7 &lt; 6" type="CHECK">
+      <failure message="data.int_seven &lt; 6" type="CHECK">
+FAILED:
+  CHECK( data.int_seven &lt; 6 )
+with expansion:
+  7 &lt; 6
 Condition.tests.cpp:<line number>
       </failure>
-      <failure message="7 &lt; 0" type="CHECK">
+      <failure message="data.int_seven &lt; 0" type="CHECK">
+FAILED:
+  CHECK( data.int_seven &lt; 0 )
+with expansion:
+  7 &lt; 0
 Condition.tests.cpp:<line number>
       </failure>
-      <failure message="7 &lt; -1" type="CHECK">
+      <failure message="data.int_seven &lt; -1" type="CHECK">
+FAILED:
+  CHECK( data.int_seven &lt; -1 )
+with expansion:
+  7 &lt; -1
 Condition.tests.cpp:<line number>
       </failure>
-      <failure message="7 >= 8" type="CHECK">
+      <failure message="data.int_seven >= 8" type="CHECK">
+FAILED:
+  CHECK( data.int_seven >= 8 )
+with expansion:
+  7 >= 8
 Condition.tests.cpp:<line number>
       </failure>
-      <failure message="7 &lt;= 6" type="CHECK">
+      <failure message="data.int_seven &lt;= 6" type="CHECK">
+FAILED:
+  CHECK( data.int_seven &lt;= 6 )
+with expansion:
+  7 &lt;= 6
 Condition.tests.cpp:<line number>
       </failure>
-      <failure message="9.1f &lt; 9" type="CHECK">
+      <failure message="data.float_nine_point_one &lt; 9" type="CHECK">
+FAILED:
+  CHECK( data.float_nine_point_one &lt; 9 )
+with expansion:
+  9.1f &lt; 9
 Condition.tests.cpp:<line number>
       </failure>
-      <failure message="9.1f > 10" type="CHECK">
+      <failure message="data.float_nine_point_one > 10" type="CHECK">
+FAILED:
+  CHECK( data.float_nine_point_one > 10 )
+with expansion:
+  9.1f > 10
 Condition.tests.cpp:<line number>
       </failure>
-      <failure message="9.1f > 9.2" type="CHECK">
+      <failure message="data.float_nine_point_one > 9.2" type="CHECK">
+FAILED:
+  CHECK( data.float_nine_point_one > 9.2 )
+with expansion:
+  9.1f > 9.2
 Condition.tests.cpp:<line number>
       </failure>
-      <failure message="&quot;hello&quot; > &quot;hello&quot;" type="CHECK">
+      <failure message="data.str_hello > &quot;hello&quot;" type="CHECK">
+FAILED:
+  CHECK( data.str_hello > "hello" )
+with expansion:
+  "hello" > "hello"
 Condition.tests.cpp:<line number>
       </failure>
-      <failure message="&quot;hello&quot; &lt; &quot;hello&quot;" type="CHECK">
+      <failure message="data.str_hello &lt; &quot;hello&quot;" type="CHECK">
+FAILED:
+  CHECK( data.str_hello &lt; "hello" )
+with expansion:
+  "hello" &lt; "hello"
 Condition.tests.cpp:<line number>
       </failure>
-      <failure message="&quot;hello&quot; > &quot;hellp&quot;" type="CHECK">
+      <failure message="data.str_hello > &quot;hellp&quot;" type="CHECK">
+FAILED:
+  CHECK( data.str_hello > "hellp" )
+with expansion:
+  "hello" > "hellp"
 Condition.tests.cpp:<line number>
       </failure>
-      <failure message="&quot;hello&quot; > &quot;z&quot;" type="CHECK">
+      <failure message="data.str_hello > &quot;z&quot;" type="CHECK">
+FAILED:
+  CHECK( data.str_hello > "z" )
+with expansion:
+  "hello" > "z"
 Condition.tests.cpp:<line number>
       </failure>
-      <failure message="&quot;hello&quot; &lt; &quot;hellm&quot;" type="CHECK">
+      <failure message="data.str_hello &lt; &quot;hellm&quot;" type="CHECK">
+FAILED:
+  CHECK( data.str_hello &lt; "hellm" )
+with expansion:
+  "hello" &lt; "hellm"
 Condition.tests.cpp:<line number>
       </failure>
-      <failure message="&quot;hello&quot; &lt; &quot;a&quot;" type="CHECK">
+      <failure message="data.str_hello &lt; &quot;a&quot;" type="CHECK">
+FAILED:
+  CHECK( data.str_hello &lt; "a" )
+with expansion:
+  "hello" &lt; "a"
 Condition.tests.cpp:<line number>
       </failure>
-      <failure message="&quot;hello&quot; >= &quot;z&quot;" type="CHECK">
+      <failure message="data.str_hello >= &quot;z&quot;" type="CHECK">
+FAILED:
+  CHECK( data.str_hello >= "z" )
+with expansion:
+  "hello" >= "z"
 Condition.tests.cpp:<line number>
       </failure>
-      <failure message="&quot;hello&quot; &lt;= &quot;a&quot;" type="CHECK">
+      <failure message="data.str_hello &lt;= &quot;a&quot;" type="CHECK">
+FAILED:
+  CHECK( data.str_hello &lt;= "a" )
+with expansion:
+  "hello" &lt;= "a"
 Condition.tests.cpp:<line number>
       </failure>
     </testcase>
@@ -589,12 +937,14 @@ Condition.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="Our PCG implementation provides expected results for known seeds/Specific seed" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Output from all sections is reported/one" time="{duration}">
       <failure type="FAIL">
+FAILED:
 Message from section one
 Message.tests.cpp:<line number>
       </failure>
     </testcase>
     <testcase classname="<exe-name>.global" name="Output from all sections is reported/two" time="{duration}">
       <failure type="FAIL">
+FAILED:
 Message from section two
 Message.tests.cpp:<line number>
       </failure>
@@ -632,6 +982,8 @@ Message.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="Parse test names and tags/quoted string followed by tag exclusion" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Parse test names and tags/Leading and trailing spaces in test spec" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Parse test names and tags/Leading and trailing spaces in test name" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Parse test names and tags/Shortened hide tags are split apart when parsing" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Parse test names and tags/Shortened hide tags also properly handle exclusion" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Pointers can be compared to null" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Precision of floating point stringification can be set/Floats" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Precision of floating point stringification can be set/Double" time="{duration}"/>
@@ -669,18 +1021,37 @@ Message.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="Product with differing arities - std::tuple&lt;int, double>" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Product with differing arities - std::tuple&lt;int>" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Reconstruction should be based on stringification: #914" time="{duration}">
-      <failure message="Hey, its truthy!" type="CHECK">
+      <failure message="truthy(false)" type="CHECK">
+FAILED:
+  CHECK( truthy(false) )
+with expansion:
+  Hey, its truthy!
 Decomposition.tests.cpp:<line number>
       </failure>
     </testcase>
     <testcase classname="<exe-name>.global" name="Regex string matcher" time="{duration}">
-      <failure message="&quot;this string contains 'abc' as a substring&quot; matches &quot;this STRING contains 'abc' as a substring&quot; case sensitively" type="CHECK_THAT">
+      <failure message="testStringForMatching(), Matches(&quot;this STRING contains 'abc' as a substring&quot;)" type="CHECK_THAT">
+FAILED:
+  CHECK_THAT( testStringForMatching(), Matches("this STRING contains 'abc' as a substring") )
+with expansion:
+  "this string contains 'abc' as a substring" matches "this STRING contains
+  'abc' as a substring" case sensitively
 Matchers.tests.cpp:<line number>
       </failure>
-      <failure message="&quot;this string contains 'abc' as a substring&quot; matches &quot;contains 'abc' as a substring&quot; case sensitively" type="CHECK_THAT">
+      <failure message="testStringForMatching(), Matches(&quot;contains 'abc' as a substring&quot;)" type="CHECK_THAT">
+FAILED:
+  CHECK_THAT( testStringForMatching(), Matches("contains 'abc' as a substring") )
+with expansion:
+  "this string contains 'abc' as a substring" matches "contains 'abc' as a
+  substring" case sensitively
 Matchers.tests.cpp:<line number>
       </failure>
-      <failure message="&quot;this string contains 'abc' as a substring&quot; matches &quot;this string contains 'abc' as a&quot; case sensitively" type="CHECK_THAT">
+      <failure message="testStringForMatching(), Matches(&quot;this string contains 'abc' as a&quot;)" type="CHECK_THAT">
+FAILED:
+  CHECK_THAT( testStringForMatching(), Matches("this string contains 'abc' as a") )
+with expansion:
+  "this string contains 'abc' as a substring" matches "this string contains
+  'abc' as a" case sensitively
 Matchers.tests.cpp:<line number>
       </failure>
     </testcase>
@@ -713,10 +1084,19 @@ Message from section two
       </system-out>
     </testcase>
     <testcase classname="<exe-name>.global" name="StartsWith string matcher" time="{duration}">
-      <failure message="&quot;this string contains 'abc' as a substring&quot; starts with: &quot;This String&quot;" type="CHECK_THAT">
+      <failure message="testStringForMatching(), StartsWith(&quot;This String&quot;)" type="CHECK_THAT">
+FAILED:
+  CHECK_THAT( testStringForMatching(), StartsWith("This String") )
+with expansion:
+  "this string contains 'abc' as a substring" starts with: "This String"
 Matchers.tests.cpp:<line number>
       </failure>
-      <failure message="&quot;this string contains 'abc' as a substring&quot; starts with: &quot;string&quot; (case insensitive)" type="CHECK_THAT">
+      <failure message="testStringForMatching(), StartsWith(&quot;string&quot;, Catch::CaseSensitive::No)" type="CHECK_THAT">
+FAILED:
+  CHECK_THAT( testStringForMatching(), StartsWith("string", Catch::CaseSensitive::No) )
+with expansion:
+  "this string contains 'abc' as a substring" starts with: "string" (case
+  insensitive)
 Matchers.tests.cpp:<line number>
       </failure>
     </testcase>
@@ -726,33 +1106,37 @@ Matchers.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="String matchers" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="StringRef/Empty string" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="StringRef/From string literal" time="{duration}"/>
-    <testcase classname="<exe-name>.global" name="StringRef/From string literal/c_str() does not cause copy" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="StringRef/From sub-string" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="StringRef/Substrings/zero-based substring" time="{duration}"/>
-    <testcase classname="<exe-name>.global" name="StringRef/Substrings/c_str() causes copy" time="{duration}"/>
-    <testcase classname="<exe-name>.global" name="StringRef/Substrings/c_str() causes copy/Self-assignment after substring" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="StringRef/Substrings/non-zero-based substring" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="StringRef/Substrings/Pointer values of full refs should match" time="{duration}"/>
-    <testcase classname="<exe-name>.global" name="StringRef/Substrings/Pointer values of substring refs should not match" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="StringRef/Substrings/Pointer values of substring refs should also match" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="StringRef/Substrings/Past the end substring" time="{duration}"/>
-    <testcase classname="<exe-name>.global" name="StringRef/Comparisons" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="StringRef/Substrings/Substring off the end are trimmed" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="StringRef/Comparisons are deep" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="StringRef/from std::string/implicitly constructed" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="StringRef/from std::string/explicitly constructed" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="StringRef/from std::string/assigned" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="StringRef/to std::string/explicitly constructed" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="StringRef/to std::string/assigned" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="StringRef at compilation time/Simple constructors" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="StringRef at compilation time/UDL construction" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Stringifying std::chrono::duration helpers" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Stringifying std::chrono::duration with weird ratios" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Stringifying std::chrono::time_point&lt;system_clock>" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Tabs and newlines show in output" time="{duration}">
-      <failure message="&quot;if ($b == 10) {
-		$a	= 20;
-}&quot;
-==
-&quot;if ($b == 10) {
-	$a = 20;
-}
-&quot;" type="CHECK">
+      <failure message="s1 == s2" type="CHECK">
+FAILED:
+  CHECK( s1 == s2 )
+with expansion:
+  "if ($b == 10) {
+  		$a	= 20;
+  }"
+  ==
+  "if ($b == 10) {
+  	$a = 20;
+  }
+  "
 Misc.tests.cpp:<line number>
       </failure>
     </testcase>
@@ -823,6 +1207,7 @@ Misc.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="This test 'should' fail but doesn't" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Thrown string literals are translated" time="{duration}">
       <error type="TEST_CASE">
+FAILED:
 For some reason someone is throwing a string literal!
 Exception.tests.cpp:<line number>
       </error>
@@ -840,6 +1225,7 @@ Exception.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="Trim strings" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Unexpected exceptions can be translated" time="{duration}">
       <error type="TEST_CASE">
+FAILED:
 3.14
 Exception.tests.cpp:<line number>
       </error>
@@ -851,12 +1237,20 @@ Exception.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="Vector Approx matcher/Vectors with elements/Different length" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Vector Approx matcher/Vectors with elements/Same length, different elements" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Vector Approx matcher -- failing/Empty and non empty vectors are not approx equal" time="{duration}">
-      <failure message="{  } is approx: { 1.0, 2.0 }" type="CHECK_THAT">
+      <failure message="empty, Approx(t1)" type="CHECK_THAT">
+FAILED:
+  CHECK_THAT( empty, Approx(t1) )
+with expansion:
+  {  } is approx: { 1.0, 2.0 }
 Matchers.tests.cpp:<line number>
       </failure>
     </testcase>
     <testcase classname="<exe-name>.global" name="Vector Approx matcher -- failing/Just different vectors" time="{duration}">
-      <failure message="{ 2.0, 4.0, 6.0 } is approx: { 1.0, 3.0, 5.0 }" type="CHECK_THAT">
+      <failure message="v1, Approx(v2)" type="CHECK_THAT">
+FAILED:
+  CHECK_THAT( v1, Approx(v2) )
+with expansion:
+  { 2.0, 4.0, 6.0 } is approx: { 1.0, 3.0, 5.0 }
 Matchers.tests.cpp:<line number>
       </failure>
     </testcase>
@@ -866,76 +1260,132 @@ Matchers.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="Vector matchers/Equals" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Vector matchers/UnorderedEquals" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Vector matchers that fail/Contains (element)" time="{duration}">
-      <failure message="{ 1, 2, 3 } Contains: -1" type="CHECK_THAT">
+      <failure message="v, VectorContains(-1)" type="CHECK_THAT">
+FAILED:
+  CHECK_THAT( v, VectorContains(-1) )
+with expansion:
+  { 1, 2, 3 } Contains: -1
 Matchers.tests.cpp:<line number>
       </failure>
-      <failure message="{  } Contains: 1" type="CHECK_THAT">
+      <failure message="empty, VectorContains(1)" type="CHECK_THAT">
+FAILED:
+  CHECK_THAT( empty, VectorContains(1) )
+with expansion:
+  {  } Contains: 1
 Matchers.tests.cpp:<line number>
       </failure>
     </testcase>
     <testcase classname="<exe-name>.global" name="Vector matchers that fail/Contains (vector)" time="{duration}">
-      <failure message="{  } Contains: { 1, 2, 3 }" type="CHECK_THAT">
+      <failure message="empty, Contains(v)" type="CHECK_THAT">
+FAILED:
+  CHECK_THAT( empty, Contains(v) )
+with expansion:
+  {  } Contains: { 1, 2, 3 }
 Matchers.tests.cpp:<line number>
       </failure>
-      <failure message="{ 1, 2, 3 } Contains: { 1, 2, 4 }" type="CHECK_THAT">
+      <failure message="v, Contains(v2)" type="CHECK_THAT">
+FAILED:
+  CHECK_THAT( v, Contains(v2) )
+with expansion:
+  { 1, 2, 3 } Contains: { 1, 2, 4 }
 Matchers.tests.cpp:<line number>
       </failure>
     </testcase>
     <testcase classname="<exe-name>.global" name="Vector matchers that fail/Equals" time="{duration}">
-      <failure message="{ 1, 2, 3 } Equals: { 1, 2 }" type="CHECK_THAT">
+      <failure message="v, Equals(v2)" type="CHECK_THAT">
+FAILED:
+  CHECK_THAT( v, Equals(v2) )
+with expansion:
+  { 1, 2, 3 } Equals: { 1, 2 }
 Matchers.tests.cpp:<line number>
       </failure>
-      <failure message="{ 1, 2 } Equals: { 1, 2, 3 }" type="CHECK_THAT">
+      <failure message="v2, Equals(v)" type="CHECK_THAT">
+FAILED:
+  CHECK_THAT( v2, Equals(v) )
+with expansion:
+  { 1, 2 } Equals: { 1, 2, 3 }
 Matchers.tests.cpp:<line number>
       </failure>
-      <failure message="{  } Equals: { 1, 2, 3 }" type="CHECK_THAT">
+      <failure message="empty, Equals(v)" type="CHECK_THAT">
+FAILED:
+  CHECK_THAT( empty, Equals(v) )
+with expansion:
+  {  } Equals: { 1, 2, 3 }
 Matchers.tests.cpp:<line number>
       </failure>
-      <failure message="{ 1, 2, 3 } Equals: {  }" type="CHECK_THAT">
+      <failure message="v, Equals(empty)" type="CHECK_THAT">
+FAILED:
+  CHECK_THAT( v, Equals(empty) )
+with expansion:
+  { 1, 2, 3 } Equals: {  }
 Matchers.tests.cpp:<line number>
       </failure>
     </testcase>
     <testcase classname="<exe-name>.global" name="Vector matchers that fail/UnorderedEquals" time="{duration}">
-      <failure message="{ 1, 2, 3 } UnorderedEquals: {  }" type="CHECK_THAT">
+      <failure message="v, UnorderedEquals(empty)" type="CHECK_THAT">
+FAILED:
+  CHECK_THAT( v, UnorderedEquals(empty) )
+with expansion:
+  { 1, 2, 3 } UnorderedEquals: {  }
 Matchers.tests.cpp:<line number>
       </failure>
-      <failure message="{  } UnorderedEquals: { 1, 2, 3 }" type="CHECK_THAT">
+      <failure message="empty, UnorderedEquals(v)" type="CHECK_THAT">
+FAILED:
+  CHECK_THAT( empty, UnorderedEquals(v) )
+with expansion:
+  {  } UnorderedEquals: { 1, 2, 3 }
 Matchers.tests.cpp:<line number>
       </failure>
-      <failure message="{ 1, 3 } UnorderedEquals: { 1, 2, 3 }" type="CHECK_THAT">
+      <failure message="permuted, UnorderedEquals(v)" type="CHECK_THAT">
+FAILED:
+  CHECK_THAT( permuted, UnorderedEquals(v) )
+with expansion:
+  { 1, 3 } UnorderedEquals: { 1, 2, 3 }
 Matchers.tests.cpp:<line number>
       </failure>
-      <failure message="{ 3, 1 } UnorderedEquals: { 1, 2, 3 }" type="CHECK_THAT">
+      <failure message="permuted, UnorderedEquals(v)" type="CHECK_THAT">
+FAILED:
+  CHECK_THAT( permuted, UnorderedEquals(v) )
+with expansion:
+  { 3, 1 } UnorderedEquals: { 1, 2, 3 }
 Matchers.tests.cpp:<line number>
       </failure>
     </testcase>
     <testcase classname="<exe-name>.global" name="When checked exceptions are thrown they can be expected or unexpected" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="When unchecked exceptions are thrown directly they are always failures" time="{duration}">
       <error type="TEST_CASE">
+FAILED:
 unexpected exception
 Exception.tests.cpp:<line number>
       </error>
     </testcase>
     <testcase classname="<exe-name>.global" name="When unchecked exceptions are thrown during a CHECK the test should continue" time="{duration}">
       <error message="thisThrows() == 0" type="CHECK">
+FAILED:
+  CHECK( thisThrows() == 0 )
 expected exception
 Exception.tests.cpp:<line number>
       </error>
     </testcase>
     <testcase classname="<exe-name>.global" name="When unchecked exceptions are thrown during a REQUIRE the test should abort fail" time="{duration}">
       <error message="thisThrows() == 0" type="REQUIRE">
+FAILED:
+  REQUIRE( thisThrows() == 0 )
 expected exception
 Exception.tests.cpp:<line number>
       </error>
     </testcase>
     <testcase classname="<exe-name>.global" name="When unchecked exceptions are thrown from functions they are always failures" time="{duration}">
       <error message="thisThrows() == 0" type="CHECK">
+FAILED:
+  CHECK( thisThrows() == 0 )
 expected exception
 Exception.tests.cpp:<line number>
       </error>
     </testcase>
     <testcase classname="<exe-name>.global" name="When unchecked exceptions are thrown from sections they are always failures/section name" time="{duration}">
       <error type="TEST_CASE">
+FAILED:
 unexpected exception
 Exception.tests.cpp:<line number>
       </error>
@@ -954,30 +1404,40 @@ Exception.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="XmlEncode/string with quotes" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="XmlEncode/string with control char (1)" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="XmlEncode/string with control char (x7F)" time="{duration}"/>
-    <testcase classname="<exe-name>.global" name="XmlEncode: UTF-8/Valid utf-8 strings" time="{duration}"/>
-    <testcase classname="<exe-name>.global" name="XmlEncode: UTF-8/Invalid utf-8 strings/Various broken strings" time="{duration}"/>
-    <testcase classname="<exe-name>.global" name="XmlEncode: UTF-8/Invalid utf-8 strings/Overlong encodings" time="{duration}"/>
-    <testcase classname="<exe-name>.global" name="XmlEncode: UTF-8/Invalid utf-8 strings/Surrogate pairs" time="{duration}"/>
-    <testcase classname="<exe-name>.global" name="XmlEncode: UTF-8/Invalid utf-8 strings/Invalid start byte" time="{duration}"/>
-    <testcase classname="<exe-name>.global" name="XmlEncode: UTF-8/Invalid utf-8 strings/Missing continuation byte(s)" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="array&lt;int, N> -> toString" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="atomic if" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="boolean member" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="checkedElse" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="checkedElse, failing" time="{duration}">
-      <failure message="false" type="CHECKED_ELSE">
+      <failure message="flag" type="CHECKED_ELSE">
+FAILED:
+  CHECKED_ELSE( flag )
+with expansion:
+  false
 Misc.tests.cpp:<line number>
       </failure>
-      <failure message="false" type="REQUIRE">
+      <failure message="testCheckedElse( false )" type="REQUIRE">
+FAILED:
+  REQUIRE( testCheckedElse( false ) )
+with expansion:
+  false
 Misc.tests.cpp:<line number>
       </failure>
     </testcase>
     <testcase classname="<exe-name>.global" name="checkedIf" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="checkedIf, failing" time="{duration}">
-      <failure message="false" type="CHECKED_IF">
+      <failure message="flag" type="CHECKED_IF">
+FAILED:
+  CHECKED_IF( flag )
+with expansion:
+  false
 Misc.tests.cpp:<line number>
       </failure>
-      <failure message="false" type="REQUIRE">
+      <failure message="testCheckedIf( false )" type="REQUIRE">
+FAILED:
+  REQUIRE( testCheckedIf( false ) )
+with expansion:
+  false
 Misc.tests.cpp:<line number>
       </failure>
     </testcase>
@@ -988,24 +1448,34 @@ Misc.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="even more nested SECTION tests/f (leaf)" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="just failure" time="{duration}">
       <failure type="FAIL">
+FAILED:
 Previous info should not be seen
 Message.tests.cpp:<line number>
       </failure>
     </testcase>
     <testcase classname="<exe-name>.global" name="just failure after unscoped info" time="{duration}">
       <failure type="FAIL">
+FAILED:
 previous unscoped info SHOULD not be seen
 Message.tests.cpp:<line number>
       </failure>
     </testcase>
     <testcase classname="<exe-name>.global" name="long long" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="looped SECTION tests/b is currently: 0" time="{duration}">
-      <failure message="0 > 1" type="CHECK">
+      <failure message="b > a" type="CHECK">
+FAILED:
+  CHECK( b > a )
+with expansion:
+  0 > 1
 Misc.tests.cpp:<line number>
       </failure>
     </testcase>
     <testcase classname="<exe-name>.global" name="looped SECTION tests/b is currently: 1" time="{duration}">
-      <failure message="1 > 1" type="CHECK">
+      <failure message="b > a" type="CHECK">
+FAILED:
+  CHECK( b > a )
+with expansion:
+  1 > 1
 Misc.tests.cpp:<line number>
       </failure>
     </testcase>
@@ -1018,34 +1488,62 @@ Misc.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="looped SECTION tests/b is currently: 8" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="looped SECTION tests/b is currently: 9" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="looped tests" time="{duration}">
-      <failure message="1 == 0" type="CHECK">
+      <failure message="( fib[i] % 2 ) == 0" type="CHECK">
+FAILED:
+  CHECK( ( fib[i] % 2 ) == 0 )
+with expansion:
+  1 == 0
 Testing if fib[0] (1) is even
 Misc.tests.cpp:<line number>
       </failure>
-      <failure message="1 == 0" type="CHECK">
+      <failure message="( fib[i] % 2 ) == 0" type="CHECK">
+FAILED:
+  CHECK( ( fib[i] % 2 ) == 0 )
+with expansion:
+  1 == 0
 Testing if fib[1] (1) is even
 Misc.tests.cpp:<line number>
       </failure>
-      <failure message="1 == 0" type="CHECK">
+      <failure message="( fib[i] % 2 ) == 0" type="CHECK">
+FAILED:
+  CHECK( ( fib[i] % 2 ) == 0 )
+with expansion:
+  1 == 0
 Testing if fib[3] (3) is even
 Misc.tests.cpp:<line number>
       </failure>
-      <failure message="1 == 0" type="CHECK">
+      <failure message="( fib[i] % 2 ) == 0" type="CHECK">
+FAILED:
+  CHECK( ( fib[i] % 2 ) == 0 )
+with expansion:
+  1 == 0
 Testing if fib[4] (5) is even
 Misc.tests.cpp:<line number>
       </failure>
-      <failure message="1 == 0" type="CHECK">
+      <failure message="( fib[i] % 2 ) == 0" type="CHECK">
+FAILED:
+  CHECK( ( fib[i] % 2 ) == 0 )
+with expansion:
+  1 == 0
 Testing if fib[6] (13) is even
 Misc.tests.cpp:<line number>
       </failure>
-      <failure message="1 == 0" type="CHECK">
+      <failure message="( fib[i] % 2 ) == 0" type="CHECK">
+FAILED:
+  CHECK( ( fib[i] % 2 ) == 0 )
+with expansion:
+  1 == 0
 Testing if fib[7] (21) is even
 Misc.tests.cpp:<line number>
       </failure>
     </testcase>
     <testcase classname="<exe-name>.global" name="mix info, unscoped info and warning" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="more nested SECTION tests/equal/doesn't equal" time="{duration}">
-      <failure message="1 == 2" type="REQUIRE">
+      <failure message="a == b" type="REQUIRE">
+FAILED:
+  REQUIRE( a == b )
+with expansion:
+  1 == 2
 Misc.tests.cpp:<line number>
       </failure>
     </testcase>
@@ -1058,6 +1556,8 @@ Misc.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="not allowed" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="not prints unscoped info from previous failures" time="{duration}">
       <failure message="false" type="REQUIRE">
+FAILED:
+  REQUIRE( false )
 this SHOULD be seen
 Message.tests.cpp:<line number>
       </failure>
@@ -1072,6 +1572,8 @@ Message.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="print unscoped info if passing unscoped info is printed" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="prints unscoped info on failure" time="{duration}">
       <failure message="false" type="REQUIRE">
+FAILED:
+  REQUIRE( false )
 this SHOULD be seen
 this SHOULD also be seen
 Message.tests.cpp:<line number>
@@ -1079,6 +1581,8 @@ Message.tests.cpp:<line number>
     </testcase>
     <testcase classname="<exe-name>.global" name="prints unscoped info only for the first assertion" time="{duration}">
       <failure message="false" type="CHECK">
+FAILED:
+  CHECK( false )
 this SHOULD be seen only ONCE
 Message.tests.cpp:<line number>
       </failure>
@@ -1094,12 +1598,16 @@ Message.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="replaceInPlace/escape '" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="send a single char to INFO" time="{duration}">
       <failure message="false" type="REQUIRE">
+FAILED:
+  REQUIRE( false )
 3
 Misc.tests.cpp:<line number>
       </failure>
     </testcase>
     <testcase classname="<exe-name>.global" name="sends information to INFO" time="{duration}">
       <failure message="false" type="REQUIRE">
+FAILED:
+  REQUIRE( false )
 hi
 i := 7
 Message.tests.cpp:<line number>
@@ -1109,6 +1617,8 @@ Message.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="splitString" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="stacks unscoped info in loops" time="{duration}">
       <failure message="false" type="CHECK">
+FAILED:
+  CHECK( false )
 Count 1 to 3...
 1
 2
@@ -1116,6 +1626,8 @@ Count 1 to 3...
 Message.tests.cpp:<line number>
       </failure>
       <failure message="false" type="CHECK">
+FAILED:
+  CHECK( false )
 Count 4 to 6...
 4
 5
@@ -1133,7 +1645,11 @@ Message.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="std::set is convertible string/several items" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="std::vector&lt;std::pair&lt;std::string,int> > -> toString" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="string literals of different sizes can be compared" time="{duration}">
-      <failure message="&quot;first&quot; == &quot;second&quot;" type="REQUIRE">
+      <failure message="std::string( &quot;first&quot; ) == &quot;second&quot;" type="REQUIRE">
+FAILED:
+  REQUIRE( std::string( "first" ) == "second" )
+with expansion:
+  "first" == "second"
 Tricky.tests.cpp:<line number>
       </failure>
     </testcase>
@@ -1150,6 +1666,7 @@ Tricky.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="tables" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="thrown std::strings are translated" time="{duration}">
       <error type="TEST_CASE">
+FAILED:
 Why would you throw a std::string?
 Exception.tests.cpp:<line number>
       </error>
diff --git a/packages/Catch2/projects/SelfTest/Baselines/sonarqube.sw.approved.txt b/packages/Catch2/projects/SelfTest/Baselines/sonarqube.sw.approved.txt
new file mode 100644
index 0000000000000000000000000000000000000000..f1b9fe9838f70606d53baa8d45e45f9b5b629554
--- /dev/null
+++ b/packages/Catch2/projects/SelfTest/Baselines/sonarqube.sw.approved.txt
@@ -0,0 +1,1726 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<testExecutions version="1"loose text artifact
+>
+  <file path="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp">
+    <testCase name="Parse test names and tags/Empty test spec should have no filters" duration="{duration}"/>
+    <testCase name="Parse test names and tags/Test spec from empty string should have no filters" duration="{duration}"/>
+    <testCase name="Parse test names and tags/Test spec from just a comma should have no filters" duration="{duration}"/>
+    <testCase name="Parse test names and tags/Test spec from name should have one filter" duration="{duration}"/>
+    <testCase name="Parse test names and tags/Test spec from quoted name should have one filter" duration="{duration}"/>
+    <testCase name="Parse test names and tags/Test spec from name should have one filter" duration="{duration}"/>
+    <testCase name="Parse test names and tags/Wildcard at the start" duration="{duration}"/>
+    <testCase name="Parse test names and tags/Wildcard at the end" duration="{duration}"/>
+    <testCase name="Parse test names and tags/Wildcard at both ends" duration="{duration}"/>
+    <testCase name="Parse test names and tags/Redundant wildcard at the start" duration="{duration}"/>
+    <testCase name="Parse test names and tags/Redundant wildcard at the end" duration="{duration}"/>
+    <testCase name="Parse test names and tags/Redundant wildcard at both ends" duration="{duration}"/>
+    <testCase name="Parse test names and tags/Wildcard at both ends, redundant at start" duration="{duration}"/>
+    <testCase name="Parse test names and tags/Just wildcard" duration="{duration}"/>
+    <testCase name="Parse test names and tags/Single tag" duration="{duration}"/>
+    <testCase name="Parse test names and tags/Single tag, two matches" duration="{duration}"/>
+    <testCase name="Parse test names and tags/Two tags" duration="{duration}"/>
+    <testCase name="Parse test names and tags/Two tags, spare separated" duration="{duration}"/>
+    <testCase name="Parse test names and tags/Wildcarded name and tag" duration="{duration}"/>
+    <testCase name="Parse test names and tags/Single tag exclusion" duration="{duration}"/>
+    <testCase name="Parse test names and tags/One tag exclusion and one tag inclusion" duration="{duration}"/>
+    <testCase name="Parse test names and tags/One tag exclusion and one wldcarded name inclusion" duration="{duration}"/>
+    <testCase name="Parse test names and tags/One tag exclusion, using exclude:, and one wldcarded name inclusion" duration="{duration}"/>
+    <testCase name="Parse test names and tags/name exclusion" duration="{duration}"/>
+    <testCase name="Parse test names and tags/wildcarded name exclusion" duration="{duration}"/>
+    <testCase name="Parse test names and tags/wildcarded name exclusion with tag inclusion" duration="{duration}"/>
+    <testCase name="Parse test names and tags/wildcarded name exclusion, using exclude:, with tag inclusion" duration="{duration}"/>
+    <testCase name="Parse test names and tags/two wildcarded names" duration="{duration}"/>
+    <testCase name="Parse test names and tags/empty tag" duration="{duration}"/>
+    <testCase name="Parse test names and tags/empty quoted name" duration="{duration}"/>
+    <testCase name="Parse test names and tags/quoted string followed by tag exclusion" duration="{duration}"/>
+    <testCase name="Parse test names and tags/Leading and trailing spaces in test spec" duration="{duration}"/>
+    <testCase name="Parse test names and tags/Leading and trailing spaces in test name" duration="{duration}"/>
+    <testCase name="Parse test names and tags/Shortened hide tags are split apart when parsing" duration="{duration}"/>
+    <testCase name="Parse test names and tags/Shortened hide tags also properly handle exclusion" duration="{duration}"/>
+    <testCase name="Process can be configured on command line/empty args don't cause a crash" duration="{duration}"/>
+    <testCase name="Process can be configured on command line/default - no arguments" duration="{duration}"/>
+    <testCase name="Process can be configured on command line/test lists/Specify one test case using" duration="{duration}"/>
+    <testCase name="Process can be configured on command line/test lists/Specify one test case exclusion using exclude:" duration="{duration}"/>
+    <testCase name="Process can be configured on command line/test lists/Specify one test case exclusion using ~" duration="{duration}"/>
+    <testCase name="Process can be configured on command line/reporter/-r/console" duration="{duration}"/>
+    <testCase name="Process can be configured on command line/reporter/-r/xml" duration="{duration}"/>
+    <testCase name="Process can be configured on command line/reporter/--reporter/junit" duration="{duration}"/>
+    <testCase name="Process can be configured on command line/reporter/Only one reporter is accepted" duration="{duration}"/>
+    <testCase name="Process can be configured on command line/reporter/must match one of the available ones" duration="{duration}"/>
+    <testCase name="Process can be configured on command line/debugger/-b" duration="{duration}"/>
+    <testCase name="Process can be configured on command line/debugger/--break" duration="{duration}"/>
+    <testCase name="Process can be configured on command line/abort/-a aborts after first failure" duration="{duration}"/>
+    <testCase name="Process can be configured on command line/abort/-x 2 aborts after two failures" duration="{duration}"/>
+    <testCase name="Process can be configured on command line/abort/-x must be numeric" duration="{duration}"/>
+    <testCase name="Process can be configured on command line/nothrow/-e" duration="{duration}"/>
+    <testCase name="Process can be configured on command line/nothrow/--nothrow" duration="{duration}"/>
+    <testCase name="Process can be configured on command line/output filename/-o filename" duration="{duration}"/>
+    <testCase name="Process can be configured on command line/output filename/--out" duration="{duration}"/>
+    <testCase name="Process can be configured on command line/combinations/Single character flags can be combined" duration="{duration}"/>
+    <testCase name="Process can be configured on command line/use-colour/without option" duration="{duration}"/>
+    <testCase name="Process can be configured on command line/use-colour/auto" duration="{duration}"/>
+    <testCase name="Process can be configured on command line/use-colour/yes" duration="{duration}"/>
+    <testCase name="Process can be configured on command line/use-colour/no" duration="{duration}"/>
+    <testCase name="Process can be configured on command line/use-colour/error" duration="{duration}"/>
+    <testCase name="Process can be configured on command line/Benchmark options/samples" duration="{duration}"/>
+    <testCase name="Process can be configured on command line/Benchmark options/resamples" duration="{duration}"/>
+    <testCase name="Process can be configured on command line/Benchmark options/resamples" duration="{duration}"/>
+    <testCase name="Process can be configured on command line/Benchmark options/resamples" duration="{duration}"/>
+    <testCase name="Test with special, characters &quot;in name" duration="{duration}"/>
+  </file>
+  <file path="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp">
+    <testCase name="Generators internals/Single value" duration="{duration}"/>
+    <testCase name="Generators internals/Preset values" duration="{duration}"/>
+    <testCase name="Generators internals/Generator combinator" duration="{duration}"/>
+    <testCase name="Generators internals/Explicitly typed generator sequence" duration="{duration}"/>
+    <testCase name="Generators internals/Filter generator" duration="{duration}"/>
+    <testCase name="Generators internals/Take generator/Take less" duration="{duration}"/>
+    <testCase name="Generators internals/Take generator/Take more" duration="{duration}"/>
+    <testCase name="Generators internals/Map with explicit return type" duration="{duration}"/>
+    <testCase name="Generators internals/Map with deduced return type" duration="{duration}"/>
+    <testCase name="Generators internals/Repeat/Singular repeat" duration="{duration}"/>
+    <testCase name="Generators internals/Repeat/Actual repeat" duration="{duration}"/>
+    <testCase name="Generators internals/Range/Positive auto step/Integer" duration="{duration}"/>
+    <testCase name="Generators internals/Range/Negative auto step/Integer" duration="{duration}"/>
+    <testCase name="Generators internals/Range/Positive manual step/Integer/Exact" duration="{duration}"/>
+    <testCase name="Generators internals/Range/Positive manual step/Integer/Slightly over end" duration="{duration}"/>
+    <testCase name="Generators internals/Range/Positive manual step/Integer/Slightly under end" duration="{duration}"/>
+    <testCase name="Generators internals/Range/Positive manual step/Floating Point/Exact" duration="{duration}"/>
+    <testCase name="Generators internals/Range/Positive manual step/Floating Point/Slightly over end" duration="{duration}"/>
+    <testCase name="Generators internals/Range/Positive manual step/Floating Point/Slightly under end" duration="{duration}"/>
+    <testCase name="Generators internals/Range/Negative manual step/Integer/Exact" duration="{duration}"/>
+    <testCase name="Generators internals/Range/Negative manual step/Integer/Slightly over end" duration="{duration}"/>
+    <testCase name="Generators internals/Range/Negative manual step/Integer/Slightly under end" duration="{duration}"/>
+  </file>
+  <file path="projects/<exe-name>/IntrospectiveTests/PartTracker.tests.cpp">
+    <testCase name="Tracker" duration="{duration}"/>
+    <testCase name="Tracker/successfully close one section" duration="{duration}"/>
+    <testCase name="Tracker/fail one section" duration="{duration}"/>
+    <testCase name="Tracker/fail one section/re-enter after failed section" duration="{duration}"/>
+    <testCase name="Tracker/fail one section/re-enter after failed section and find next section" duration="{duration}"/>
+    <testCase name="Tracker/successfully close one section, then find another" duration="{duration}"/>
+    <testCase name="Tracker/successfully close one section, then find another/Re-enter - skips S1 and enters S2" duration="{duration}"/>
+    <testCase name="Tracker/successfully close one section, then find another/Re-enter - skips S1 and enters S2/Successfully close S2" duration="{duration}"/>
+    <testCase name="Tracker/successfully close one section, then find another/Re-enter - skips S1 and enters S2/fail S2" duration="{duration}"/>
+    <testCase name="Tracker/open a nested section" duration="{duration}"/>
+  </file>
+  <file path="projects/<exe-name>/IntrospectiveTests/RandomNumberGeneration.tests.cpp">
+    <testCase name="Comparison ops" duration="{duration}"/>
+    <testCase name="Our PCG implementation provides expected results for known seeds/Default seeded" duration="{duration}"/>
+    <testCase name="Our PCG implementation provides expected results for known seeds/Specific seed" duration="{duration}"/>
+  </file>
+  <file path="projects/<exe-name>/IntrospectiveTests/String.tests.cpp">
+    <testCase name="StringRef/Empty string" duration="{duration}"/>
+    <testCase name="StringRef/From string literal" duration="{duration}"/>
+    <testCase name="StringRef/From sub-string" duration="{duration}"/>
+    <testCase name="StringRef/Substrings/zero-based substring" duration="{duration}"/>
+    <testCase name="StringRef/Substrings/non-zero-based substring" duration="{duration}"/>
+    <testCase name="StringRef/Substrings/Pointer values of full refs should match" duration="{duration}"/>
+    <testCase name="StringRef/Substrings/Pointer values of substring refs should also match" duration="{duration}"/>
+    <testCase name="StringRef/Substrings/Past the end substring" duration="{duration}"/>
+    <testCase name="StringRef/Substrings/Substring off the end are trimmed" duration="{duration}"/>
+    <testCase name="StringRef/Comparisons are deep" duration="{duration}"/>
+    <testCase name="StringRef/from std::string/implicitly constructed" duration="{duration}"/>
+    <testCase name="StringRef/from std::string/explicitly constructed" duration="{duration}"/>
+    <testCase name="StringRef/from std::string/assigned" duration="{duration}"/>
+    <testCase name="StringRef/to std::string/explicitly constructed" duration="{duration}"/>
+    <testCase name="StringRef/to std::string/assigned" duration="{duration}"/>
+    <testCase name="StringRef at compilation time/Simple constructors" duration="{duration}"/>
+    <testCase name="StringRef at compilation time/UDL construction" duration="{duration}"/>
+  </file>
+  <file path="projects/<exe-name>/IntrospectiveTests/StringManip.tests.cpp">
+    <testCase name="Trim strings" duration="{duration}"/>
+    <testCase name="replaceInPlace/replace single char" duration="{duration}"/>
+    <testCase name="replaceInPlace/replace two chars" duration="{duration}"/>
+    <testCase name="replaceInPlace/replace first char" duration="{duration}"/>
+    <testCase name="replaceInPlace/replace last char" duration="{duration}"/>
+    <testCase name="replaceInPlace/replace all chars" duration="{duration}"/>
+    <testCase name="replaceInPlace/replace no chars" duration="{duration}"/>
+    <testCase name="replaceInPlace/escape '" duration="{duration}"/>
+    <testCase name="splitString" duration="{duration}"/>
+  </file>
+  <file path="projects/<exe-name>/IntrospectiveTests/Tag.tests.cpp">
+    <testCase name="Tag alias can be registered against tag patterns/The same tag alias can only be registered once" duration="{duration}"/>
+    <testCase name="Tag alias can be registered against tag patterns/Tag aliases must be of the form [@name]" duration="{duration}"/>
+    <testCase name="shortened hide tags are split apart" duration="{duration}"/>
+  </file>
+  <file path="projects/<exe-name>/IntrospectiveTests/ToString.tests.cpp">
+    <testCase name="Directly creating an EnumInfo" duration="{duration}"/>
+    <testCase name="parseEnums/No enums" duration="{duration}"/>
+    <testCase name="parseEnums/One enum value" duration="{duration}"/>
+    <testCase name="parseEnums/Multiple enum values" duration="{duration}"/>
+  </file>
+  <file path="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp">
+    <testCase name="XmlEncode/normal string" duration="{duration}"/>
+    <testCase name="XmlEncode/empty string" duration="{duration}"/>
+    <testCase name="XmlEncode/string with ampersand" duration="{duration}"/>
+    <testCase name="XmlEncode/string with less-than" duration="{duration}"/>
+    <testCase name="XmlEncode/string with greater-than" duration="{duration}"/>
+    <testCase name="XmlEncode/string with quotes" duration="{duration}"/>
+    <testCase name="XmlEncode/string with control char (1)" duration="{duration}"/>
+    <testCase name="XmlEncode/string with control char (x7F)" duration="{duration}"/>
+  </file>
+  <file path="projects/<exe-name>/UsageTests/Approx.tests.cpp">
+    <testCase name="A comparison that uses literals instead of the normal constructor" duration="{duration}"/>
+    <testCase name="Absolute margin" duration="{duration}"/>
+    <testCase name="Approx setters validate their arguments" duration="{duration}"/>
+    <testCase name="Approx with exactly-representable margin" duration="{duration}"/>
+    <testCase name="Approximate PI" duration="{duration}"/>
+    <testCase name="Approximate comparisons with different epsilons" duration="{duration}"/>
+    <testCase name="Approximate comparisons with floats" duration="{duration}"/>
+    <testCase name="Approximate comparisons with ints" duration="{duration}"/>
+    <testCase name="Approximate comparisons with mixed numeric types" duration="{duration}"/>
+    <testCase name="Comparison with explicitly convertible types" duration="{duration}"/>
+    <testCase name="Default scale is invisible to comparison" duration="{duration}"/>
+    <testCase name="Epsilon only applies to Approx's value" duration="{duration}"/>
+    <testCase name="Greater-than inequalities with different epsilons" duration="{duration}"/>
+    <testCase name="Less-than inequalities with different epsilons" duration="{duration}"/>
+    <testCase name="Some simple comparisons between doubles" duration="{duration}"/>
+    <testCase name="Use a custom approx" duration="{duration}"/>
+  </file>
+  <file path="projects/<exe-name>/UsageTests/BDD.tests.cpp">
+    <testCase name="Scenario: BDD tests requiring Fixtures to provide commonly-accessed data or methods/Given: No operations precede me" duration="{duration}"/>
+    <testCase name="Scenario: BDD tests requiring Fixtures to provide commonly-accessed data or methods/Given: No operations precede me/When: We get the count/Then: Subsequently values are higher" duration="{duration}"/>
+    <testCase name="Scenario: Do that thing with the thing/Given: This stuff exists/And given: And some assumption/When: I do this/Then: it should do this" duration="{duration}"/>
+    <testCase name="Scenario: Do that thing with the thing/Given: This stuff exists/And given: And some assumption/When: I do this/Then: it should do this/And: do that" duration="{duration}"/>
+    <testCase name="Scenario: This is a really long scenario name to see how the list command deals with wrapping/Given: A section name that is so long that it cannot fit in a single console width/When: The test headers are printed as part of the normal running of the scenario/Then: The, deliberately very long and overly verbose (you see what I did there?) section names must wrap, along with an indent" duration="{duration}"/>
+    <testCase name="Scenario: Vector resizing affects size and capacity/Given: an empty vector" duration="{duration}"/>
+    <testCase name="Scenario: Vector resizing affects size and capacity/Given: an empty vector/When: it is made larger/Then: the size and capacity go up" duration="{duration}"/>
+    <testCase name="Scenario: Vector resizing affects size and capacity/Given: an empty vector/When: it is made larger/Then: the size and capacity go up/And when: it is made smaller again/Then: the size goes down but the capacity stays the same" duration="{duration}"/>
+    <testCase name="Scenario: Vector resizing affects size and capacity/Given: an empty vector/When: we reserve more space/Then: The capacity is increased but the size remains the same" duration="{duration}"/>
+  </file>
+  <file path="projects/<exe-name>/UsageTests/Class.tests.cpp">
+    <testCase name="A METHOD_AS_TEST_CASE based test run that fails" duration="{duration}">
+      <failure message="REQUIRE(s == &quot;world&quot;)">
+FAILED:
+	REQUIRE( s == "world" )
+with expansion:
+	"hello" == "world"
+Class.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="A METHOD_AS_TEST_CASE based test run that succeeds" duration="{duration}"/>
+    <testCase name="A TEMPLATE_PRODUCT_TEST_CASE_METHOD based test run that fails - Template_Foo&lt;float>" duration="{duration}">
+      <failure message="REQUIRE(Template_Fixture_2&lt;TestType>::m_a.size() == 1)">
+FAILED:
+	REQUIRE( Template_Fixture_2&lt;TestType>::m_a.size() == 1 )
+with expansion:
+	0 == 1
+Class.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="A TEMPLATE_PRODUCT_TEST_CASE_METHOD based test run that fails - Template_Foo&lt;int>" duration="{duration}">
+      <failure message="REQUIRE(Template_Fixture_2&lt;TestType>::m_a.size() == 1)">
+FAILED:
+	REQUIRE( Template_Fixture_2&lt;TestType>::m_a.size() == 1 )
+with expansion:
+	0 == 1
+Class.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="A TEMPLATE_PRODUCT_TEST_CASE_METHOD based test run that fails - std::vector&lt;float>" duration="{duration}">
+      <failure message="REQUIRE(Template_Fixture_2&lt;TestType>::m_a.size() == 1)">
+FAILED:
+	REQUIRE( Template_Fixture_2&lt;TestType>::m_a.size() == 1 )
+with expansion:
+	0 == 1
+Class.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="A TEMPLATE_PRODUCT_TEST_CASE_METHOD based test run that fails - std::vector&lt;int>" duration="{duration}">
+      <failure message="REQUIRE(Template_Fixture_2&lt;TestType>::m_a.size() == 1)">
+FAILED:
+	REQUIRE( Template_Fixture_2&lt;TestType>::m_a.size() == 1 )
+with expansion:
+	0 == 1
+Class.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="A TEMPLATE_PRODUCT_TEST_CASE_METHOD based test run that succeeds - Template_Foo&lt;float>" duration="{duration}"/>
+    <testCase name="A TEMPLATE_PRODUCT_TEST_CASE_METHOD based test run that succeeds - Template_Foo&lt;int>" duration="{duration}"/>
+    <testCase name="A TEMPLATE_PRODUCT_TEST_CASE_METHOD based test run that succeeds - std::vector&lt;float>" duration="{duration}"/>
+    <testCase name="A TEMPLATE_PRODUCT_TEST_CASE_METHOD based test run that succeeds - std::vector&lt;int>" duration="{duration}"/>
+    <testCase name="A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that fails - Template_Foo_2&lt;float, 6>" duration="{duration}">
+      <failure message="REQUIRE(Template_Fixture_2&lt;TestType>{}.m_a.size() &lt; 2)">
+FAILED:
+	REQUIRE( Template_Fixture_2&lt;TestType>{}.m_a.size() &lt; 2 )
+with expansion:
+	6 &lt; 2
+Class.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that fails - Template_Foo_2&lt;int, 2>" duration="{duration}">
+      <failure message="REQUIRE(Template_Fixture_2&lt;TestType>{}.m_a.size() &lt; 2)">
+FAILED:
+	REQUIRE( Template_Fixture_2&lt;TestType>{}.m_a.size() &lt; 2 )
+with expansion:
+	2 &lt; 2
+Class.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that fails - std::array&lt;float, 6>" duration="{duration}">
+      <failure message="REQUIRE(Template_Fixture_2&lt;TestType>{}.m_a.size() &lt; 2)">
+FAILED:
+	REQUIRE( Template_Fixture_2&lt;TestType>{}.m_a.size() &lt; 2 )
+with expansion:
+	6 &lt; 2
+Class.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that fails - std::array&lt;int, 2>" duration="{duration}">
+      <failure message="REQUIRE(Template_Fixture_2&lt;TestType>{}.m_a.size() &lt; 2)">
+FAILED:
+	REQUIRE( Template_Fixture_2&lt;TestType>{}.m_a.size() &lt; 2 )
+with expansion:
+	2 &lt; 2
+Class.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that succeeds - Template_Foo_2&lt;float,6>" duration="{duration}"/>
+    <testCase name="A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that succeeds - Template_Foo_2&lt;int,2>" duration="{duration}"/>
+    <testCase name="A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that succeeds - std::array&lt;float,6>" duration="{duration}"/>
+    <testCase name="A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that succeeds - std::array&lt;int,2>" duration="{duration}"/>
+    <testCase name="A TEMPLATE_TEST_CASE_METHOD based test run that fails - double" duration="{duration}">
+      <failure message="REQUIRE(Template_Fixture&lt;TestType>::m_a == 2)">
+FAILED:
+	REQUIRE( Template_Fixture&lt;TestType>::m_a == 2 )
+with expansion:
+	1.0 == 2
+Class.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="A TEMPLATE_TEST_CASE_METHOD based test run that fails - float" duration="{duration}">
+      <failure message="REQUIRE(Template_Fixture&lt;TestType>::m_a == 2)">
+FAILED:
+	REQUIRE( Template_Fixture&lt;TestType>::m_a == 2 )
+with expansion:
+	1.0f == 2
+Class.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="A TEMPLATE_TEST_CASE_METHOD based test run that fails - int" duration="{duration}">
+      <failure message="REQUIRE(Template_Fixture&lt;TestType>::m_a == 2)">
+FAILED:
+	REQUIRE( Template_Fixture&lt;TestType>::m_a == 2 )
+with expansion:
+	1 == 2
+Class.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="A TEMPLATE_TEST_CASE_METHOD based test run that succeeds - double" duration="{duration}"/>
+    <testCase name="A TEMPLATE_TEST_CASE_METHOD based test run that succeeds - float" duration="{duration}"/>
+    <testCase name="A TEMPLATE_TEST_CASE_METHOD based test run that succeeds - int" duration="{duration}"/>
+    <testCase name="A TEMPLATE_TEST_CASE_METHOD_SIG based test run that fails - 1" duration="{duration}">
+      <failure message="REQUIRE(Nttp_Fixture&lt;V>::value == 0)">
+FAILED:
+	REQUIRE( Nttp_Fixture&lt;V>::value == 0 )
+with expansion:
+	1 == 0
+Class.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="A TEMPLATE_TEST_CASE_METHOD_SIG based test run that fails - 3" duration="{duration}">
+      <failure message="REQUIRE(Nttp_Fixture&lt;V>::value == 0)">
+FAILED:
+	REQUIRE( Nttp_Fixture&lt;V>::value == 0 )
+with expansion:
+	3 == 0
+Class.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="A TEMPLATE_TEST_CASE_METHOD_SIG based test run that fails - 6" duration="{duration}">
+      <failure message="REQUIRE(Nttp_Fixture&lt;V>::value == 0)">
+FAILED:
+	REQUIRE( Nttp_Fixture&lt;V>::value == 0 )
+with expansion:
+	6 == 0
+Class.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="A TEMPLATE_TEST_CASE_METHOD_SIG based test run that succeeds - 1" duration="{duration}"/>
+    <testCase name="A TEMPLATE_TEST_CASE_METHOD_SIG based test run that succeeds - 3" duration="{duration}"/>
+    <testCase name="A TEMPLATE_TEST_CASE_METHOD_SIG based test run that succeeds - 6" duration="{duration}"/>
+    <testCase name="A TEST_CASE_METHOD based test run that fails" duration="{duration}">
+      <failure message="REQUIRE(m_a == 2)">
+FAILED:
+	REQUIRE( m_a == 2 )
+with expansion:
+	1 == 2
+Class.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="A TEST_CASE_METHOD based test run that succeeds" duration="{duration}"/>
+    <testCase name="Template test case method with test types specified inside std::tuple - MyTypes - 0" duration="{duration}"/>
+    <testCase name="Template test case method with test types specified inside std::tuple - MyTypes - 1" duration="{duration}"/>
+    <testCase name="Template test case method with test types specified inside std::tuple - MyTypes - 2" duration="{duration}"/>
+  </file>
+  <file path="projects/<exe-name>/UsageTests/Compilation.tests.cpp">
+    <testCase name="#1027" duration="{duration}"/>
+    <testCase name="#1027: Bitfields can be captured" duration="{duration}"/>
+    <testCase name="#1147" duration="{duration}"/>
+    <testCase name="#1238" duration="{duration}"/>
+    <testCase name="#1245" duration="{duration}"/>
+    <testCase name="#1403" duration="{duration}"/>
+    <testCase name="#1548" duration="{duration}"/>
+    <testCase name="#809" duration="{duration}"/>
+    <testCase name="#833" duration="{duration}"/>
+    <testCase name="#872" duration="{duration}"/>
+    <testCase name="Optionally static assertions" duration="{duration}"/>
+  </file>
+  <file path="projects/<exe-name>/UsageTests/Condition.tests.cpp">
+    <testCase name="'Not' checks that should fail" duration="{duration}">
+      <failure message="CHECK(false != false)">
+FAILED:
+	CHECK( false != false )
+Condition.tests.cpp:<line number>
+      </failure>
+      <failure message="CHECK(true != true)">
+FAILED:
+	CHECK( true != true )
+Condition.tests.cpp:<line number>
+      </failure>
+      <failure message="CHECK(!true)">
+FAILED:
+	CHECK( !true )
+with expansion:
+	false
+Condition.tests.cpp:<line number>
+      </failure>
+      <failure message="CHECK_FALSE(!(true))">
+FAILED:
+	CHECK_FALSE( true )
+with expansion:
+	!true
+Condition.tests.cpp:<line number>
+      </failure>
+      <failure message="CHECK(!trueValue)">
+FAILED:
+	CHECK( !trueValue )
+with expansion:
+	false
+Condition.tests.cpp:<line number>
+      </failure>
+      <failure message="CHECK_FALSE(!(trueValue))">
+FAILED:
+	CHECK_FALSE( trueValue )
+with expansion:
+	!true
+Condition.tests.cpp:<line number>
+      </failure>
+      <failure message="CHECK(!(1 == 1))">
+FAILED:
+	CHECK( !(1 == 1) )
+with expansion:
+	false
+Condition.tests.cpp:<line number>
+      </failure>
+      <failure message="CHECK_FALSE(!(1 == 1))">
+FAILED:
+	CHECK_FALSE( 1 == 1 )
+Condition.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="'Not' checks that should succeed" duration="{duration}"/>
+    <testCase name="Comparisons between ints where one side is computed" duration="{duration}"/>
+    <testCase name="Comparisons between unsigned ints and negative signed ints match c++ standard behaviour" duration="{duration}"/>
+    <testCase name="Comparisons with int literals don't warn when mixing signed/ unsigned" duration="{duration}"/>
+    <testCase name="Equality checks that should fail" duration="{duration}">
+      <skipped message="CHECK(data.int_seven == 6)">
+FAILED:
+	CHECK( data.int_seven == 6 )
+with expansion:
+	7 == 6
+Condition.tests.cpp:<line number>
+      </skipped>
+      <skipped message="CHECK(data.int_seven == 8)">
+FAILED:
+	CHECK( data.int_seven == 8 )
+with expansion:
+	7 == 8
+Condition.tests.cpp:<line number>
+      </skipped>
+      <skipped message="CHECK(data.int_seven == 0)">
+FAILED:
+	CHECK( data.int_seven == 0 )
+with expansion:
+	7 == 0
+Condition.tests.cpp:<line number>
+      </skipped>
+      <skipped message="CHECK(data.float_nine_point_one == Approx( 9.11f ))">
+FAILED:
+	CHECK( data.float_nine_point_one == Approx( 9.11f ) )
+with expansion:
+	9.1f == Approx( 9.1099996567 )
+Condition.tests.cpp:<line number>
+      </skipped>
+      <skipped message="CHECK(data.float_nine_point_one == Approx( 9.0f ))">
+FAILED:
+	CHECK( data.float_nine_point_one == Approx( 9.0f ) )
+with expansion:
+	9.1f == Approx( 9.0 )
+Condition.tests.cpp:<line number>
+      </skipped>
+      <skipped message="CHECK(data.float_nine_point_one == Approx( 1 ))">
+FAILED:
+	CHECK( data.float_nine_point_one == Approx( 1 ) )
+with expansion:
+	9.1f == Approx( 1.0 )
+Condition.tests.cpp:<line number>
+      </skipped>
+      <skipped message="CHECK(data.float_nine_point_one == Approx( 0 ))">
+FAILED:
+	CHECK( data.float_nine_point_one == Approx( 0 ) )
+with expansion:
+	9.1f == Approx( 0.0 )
+Condition.tests.cpp:<line number>
+      </skipped>
+      <skipped message="CHECK(data.double_pi == Approx( 3.1415 ))">
+FAILED:
+	CHECK( data.double_pi == Approx( 3.1415 ) )
+with expansion:
+	3.1415926535 == Approx( 3.1415 )
+Condition.tests.cpp:<line number>
+      </skipped>
+      <skipped message="CHECK(data.str_hello == &quot;goodbye&quot;)">
+FAILED:
+	CHECK( data.str_hello == "goodbye" )
+with expansion:
+	"hello" == "goodbye"
+Condition.tests.cpp:<line number>
+      </skipped>
+      <skipped message="CHECK(data.str_hello == &quot;hell&quot;)">
+FAILED:
+	CHECK( data.str_hello == "hell" )
+with expansion:
+	"hello" == "hell"
+Condition.tests.cpp:<line number>
+      </skipped>
+      <skipped message="CHECK(data.str_hello == &quot;hello1&quot;)">
+FAILED:
+	CHECK( data.str_hello == "hello1" )
+with expansion:
+	"hello" == "hello1"
+Condition.tests.cpp:<line number>
+      </skipped>
+      <skipped message="CHECK(data.str_hello.size() == 6)">
+FAILED:
+	CHECK( data.str_hello.size() == 6 )
+with expansion:
+	5 == 6
+Condition.tests.cpp:<line number>
+      </skipped>
+      <skipped message="CHECK(x == Approx( 1.301 ))">
+FAILED:
+	CHECK( x == Approx( 1.301 ) )
+with expansion:
+	1.3 == Approx( 1.301 )
+Condition.tests.cpp:<line number>
+      </skipped>
+    </testCase>
+    <testCase name="Equality checks that should succeed" duration="{duration}"/>
+    <testCase name="Inequality checks that should fail" duration="{duration}">
+      <skipped message="CHECK(data.int_seven != 7)">
+FAILED:
+	CHECK( data.int_seven != 7 )
+with expansion:
+	7 != 7
+Condition.tests.cpp:<line number>
+      </skipped>
+      <skipped message="CHECK(data.float_nine_point_one != Approx( 9.1f ))">
+FAILED:
+	CHECK( data.float_nine_point_one != Approx( 9.1f ) )
+with expansion:
+	9.1f != Approx( 9.1000003815 )
+Condition.tests.cpp:<line number>
+      </skipped>
+      <skipped message="CHECK(data.double_pi != Approx( 3.1415926535 ))">
+FAILED:
+	CHECK( data.double_pi != Approx( 3.1415926535 ) )
+with expansion:
+	3.1415926535 != Approx( 3.1415926535 )
+Condition.tests.cpp:<line number>
+      </skipped>
+      <skipped message="CHECK(data.str_hello != &quot;hello&quot;)">
+FAILED:
+	CHECK( data.str_hello != "hello" )
+with expansion:
+	"hello" != "hello"
+Condition.tests.cpp:<line number>
+      </skipped>
+      <skipped message="CHECK(data.str_hello.size() != 5)">
+FAILED:
+	CHECK( data.str_hello.size() != 5 )
+with expansion:
+	5 != 5
+Condition.tests.cpp:<line number>
+      </skipped>
+    </testCase>
+    <testCase name="Inequality checks that should succeed" duration="{duration}"/>
+    <testCase name="Ordering comparison checks that should fail" duration="{duration}">
+      <failure message="CHECK(data.int_seven > 7)">
+FAILED:
+	CHECK( data.int_seven > 7 )
+with expansion:
+	7 > 7
+Condition.tests.cpp:<line number>
+      </failure>
+      <failure message="CHECK(data.int_seven &lt; 7)">
+FAILED:
+	CHECK( data.int_seven &lt; 7 )
+with expansion:
+	7 &lt; 7
+Condition.tests.cpp:<line number>
+      </failure>
+      <failure message="CHECK(data.int_seven > 8)">
+FAILED:
+	CHECK( data.int_seven > 8 )
+with expansion:
+	7 > 8
+Condition.tests.cpp:<line number>
+      </failure>
+      <failure message="CHECK(data.int_seven &lt; 6)">
+FAILED:
+	CHECK( data.int_seven &lt; 6 )
+with expansion:
+	7 &lt; 6
+Condition.tests.cpp:<line number>
+      </failure>
+      <failure message="CHECK(data.int_seven &lt; 0)">
+FAILED:
+	CHECK( data.int_seven &lt; 0 )
+with expansion:
+	7 &lt; 0
+Condition.tests.cpp:<line number>
+      </failure>
+      <failure message="CHECK(data.int_seven &lt; -1)">
+FAILED:
+	CHECK( data.int_seven &lt; -1 )
+with expansion:
+	7 &lt; -1
+Condition.tests.cpp:<line number>
+      </failure>
+      <failure message="CHECK(data.int_seven >= 8)">
+FAILED:
+	CHECK( data.int_seven >= 8 )
+with expansion:
+	7 >= 8
+Condition.tests.cpp:<line number>
+      </failure>
+      <failure message="CHECK(data.int_seven &lt;= 6)">
+FAILED:
+	CHECK( data.int_seven &lt;= 6 )
+with expansion:
+	7 &lt;= 6
+Condition.tests.cpp:<line number>
+      </failure>
+      <failure message="CHECK(data.float_nine_point_one &lt; 9)">
+FAILED:
+	CHECK( data.float_nine_point_one &lt; 9 )
+with expansion:
+	9.1f &lt; 9
+Condition.tests.cpp:<line number>
+      </failure>
+      <failure message="CHECK(data.float_nine_point_one > 10)">
+FAILED:
+	CHECK( data.float_nine_point_one > 10 )
+with expansion:
+	9.1f > 10
+Condition.tests.cpp:<line number>
+      </failure>
+      <failure message="CHECK(data.float_nine_point_one > 9.2)">
+FAILED:
+	CHECK( data.float_nine_point_one > 9.2 )
+with expansion:
+	9.1f > 9.2
+Condition.tests.cpp:<line number>
+      </failure>
+      <failure message="CHECK(data.str_hello > &quot;hello&quot;)">
+FAILED:
+	CHECK( data.str_hello > "hello" )
+with expansion:
+	"hello" > "hello"
+Condition.tests.cpp:<line number>
+      </failure>
+      <failure message="CHECK(data.str_hello &lt; &quot;hello&quot;)">
+FAILED:
+	CHECK( data.str_hello &lt; "hello" )
+with expansion:
+	"hello" &lt; "hello"
+Condition.tests.cpp:<line number>
+      </failure>
+      <failure message="CHECK(data.str_hello > &quot;hellp&quot;)">
+FAILED:
+	CHECK( data.str_hello > "hellp" )
+with expansion:
+	"hello" > "hellp"
+Condition.tests.cpp:<line number>
+      </failure>
+      <failure message="CHECK(data.str_hello > &quot;z&quot;)">
+FAILED:
+	CHECK( data.str_hello > "z" )
+with expansion:
+	"hello" > "z"
+Condition.tests.cpp:<line number>
+      </failure>
+      <failure message="CHECK(data.str_hello &lt; &quot;hellm&quot;)">
+FAILED:
+	CHECK( data.str_hello &lt; "hellm" )
+with expansion:
+	"hello" &lt; "hellm"
+Condition.tests.cpp:<line number>
+      </failure>
+      <failure message="CHECK(data.str_hello &lt; &quot;a&quot;)">
+FAILED:
+	CHECK( data.str_hello &lt; "a" )
+with expansion:
+	"hello" &lt; "a"
+Condition.tests.cpp:<line number>
+      </failure>
+      <failure message="CHECK(data.str_hello >= &quot;z&quot;)">
+FAILED:
+	CHECK( data.str_hello >= "z" )
+with expansion:
+	"hello" >= "z"
+Condition.tests.cpp:<line number>
+      </failure>
+      <failure message="CHECK(data.str_hello &lt;= &quot;a&quot;)">
+FAILED:
+	CHECK( data.str_hello &lt;= "a" )
+with expansion:
+	"hello" &lt;= "a"
+Condition.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="Ordering comparison checks that should succeed" duration="{duration}"/>
+    <testCase name="Pointers can be compared to null" duration="{duration}"/>
+    <testCase name="comparisons between const int variables" duration="{duration}"/>
+    <testCase name="comparisons between int variables" duration="{duration}"/>
+  </file>
+  <file path="projects/<exe-name>/UsageTests/Decomposition.tests.cpp">
+    <testCase name="#1005: Comparing pointer to int and long (NULL can be either on various systems)" duration="{duration}"/>
+    <testCase name="Reconstruction should be based on stringification: #914" duration="{duration}">
+      <failure message="CHECK(truthy(false))">
+FAILED:
+	CHECK( truthy(false) )
+with expansion:
+	Hey, its truthy!
+Decomposition.tests.cpp:<line number>
+      </failure>
+    </testCase>
+  </file>
+  <file path="projects/<exe-name>/UsageTests/EnumToString.tests.cpp">
+    <testCase name="Enums can quickly have stringification enabled using REGISTER_ENUM" duration="{duration}"/>
+    <testCase name="Enums in namespaces can quickly have stringification enabled using REGISTER_ENUM" duration="{duration}"/>
+    <testCase name="toString(enum class w/operator&lt;&lt;)" duration="{duration}"/>
+    <testCase name="toString(enum class)" duration="{duration}"/>
+    <testCase name="toString(enum w/operator&lt;&lt;)" duration="{duration}"/>
+    <testCase name="toString(enum)" duration="{duration}"/>
+  </file>
+  <file path="projects/<exe-name>/UsageTests/Exception.tests.cpp">
+    <testCase name="#748 - captures with unexpected exceptions/outside assertions" duration="{duration}">
+      <skipped message="TEST_CASE()">
+FAILED:
+expected exception
+answer := 42
+Exception.tests.cpp:<line number>
+      </skipped>
+    </testCase>
+    <testCase name="#748 - captures with unexpected exceptions/inside REQUIRE_NOTHROW" duration="{duration}">
+      <skipped message="REQUIRE_NOTHROW(thisThrows())">
+FAILED:
+	REQUIRE_NOTHROW( thisThrows() )
+expected exception
+answer := 42
+Exception.tests.cpp:<line number>
+      </skipped>
+    </testCase>
+    <testCase name="#748 - captures with unexpected exceptions/inside REQUIRE_THROWS" duration="{duration}"/>
+    <testCase name="An unchecked exception reports the line of the last assertion" duration="{duration}">
+      <error message="({Unknown expression after the reported line})">
+FAILED:
+	{Unknown expression after the reported line}
+unexpected exception
+Exception.tests.cpp:<line number>
+      </error>
+    </testCase>
+    <testCase name="Custom exceptions can be translated when testing for nothrow" duration="{duration}">
+      <error message="REQUIRE_NOTHROW(throwCustom())">
+FAILED:
+	REQUIRE_NOTHROW( throwCustom() )
+custom exception - not std
+Exception.tests.cpp:<line number>
+      </error>
+    </testCase>
+    <testCase name="Custom exceptions can be translated when testing for throwing as something else" duration="{duration}">
+      <error message="REQUIRE_THROWS_AS(throwCustom(), std::exception)">
+FAILED:
+	REQUIRE_THROWS_AS( throwCustom(), std::exception )
+custom exception - not std
+Exception.tests.cpp:<line number>
+      </error>
+    </testCase>
+    <testCase name="Custom std-exceptions can be custom translated" duration="{duration}">
+      <error message="TEST_CASE()">
+FAILED:
+custom std exception
+Exception.tests.cpp:<line number>
+      </error>
+    </testCase>
+    <testCase name="Exception messages can be tested for/exact match" duration="{duration}"/>
+    <testCase name="Exception messages can be tested for/different case" duration="{duration}"/>
+    <testCase name="Exception messages can be tested for/wildcarded" duration="{duration}"/>
+    <testCase name="Expected exceptions that don't throw or unexpected exceptions fail the test" duration="{duration}">
+      <error message="CHECK_THROWS_AS(thisThrows(), std::string)">
+FAILED:
+	CHECK_THROWS_AS( thisThrows(), std::string )
+expected exception
+Exception.tests.cpp:<line number>
+      </error>
+      <failure message="CHECK_THROWS_AS(thisDoesntThrow(), std::domain_error)">
+FAILED:
+	CHECK_THROWS_AS( thisDoesntThrow(), std::domain_error )
+Exception.tests.cpp:<line number>
+      </failure>
+      <error message="CHECK_NOTHROW(thisThrows())">
+FAILED:
+	CHECK_NOTHROW( thisThrows() )
+expected exception
+Exception.tests.cpp:<line number>
+      </error>
+    </testCase>
+    <testCase name="Mismatching exception messages failing the test" duration="{duration}">
+      <failure message="REQUIRE_THROWS_WITH(thisThrows(), &quot;should fail&quot;)">
+FAILED:
+	REQUIRE_THROWS_WITH( thisThrows(), "should fail" )
+with expansion:
+	"expected exception" equals: "should fail"
+Exception.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="Non-std exceptions can be translated" duration="{duration}">
+      <error message="TEST_CASE()">
+FAILED:
+custom exception
+Exception.tests.cpp:<line number>
+      </error>
+    </testCase>
+    <testCase name="Thrown string literals are translated" duration="{duration}">
+      <error message="TEST_CASE()">
+FAILED:
+For some reason someone is throwing a string literal!
+Exception.tests.cpp:<line number>
+      </error>
+    </testCase>
+    <testCase name="Unexpected exceptions can be translated" duration="{duration}">
+      <error message="TEST_CASE()">
+FAILED:
+3.14
+Exception.tests.cpp:<line number>
+      </error>
+    </testCase>
+    <testCase name="When checked exceptions are thrown they can be expected or unexpected" duration="{duration}"/>
+    <testCase name="When unchecked exceptions are thrown directly they are always failures" duration="{duration}">
+      <error message="TEST_CASE()">
+FAILED:
+unexpected exception
+Exception.tests.cpp:<line number>
+      </error>
+    </testCase>
+    <testCase name="When unchecked exceptions are thrown during a CHECK the test should continue" duration="{duration}">
+      <error message="CHECK(thisThrows() == 0)">
+FAILED:
+	CHECK( thisThrows() == 0 )
+expected exception
+Exception.tests.cpp:<line number>
+      </error>
+    </testCase>
+    <testCase name="When unchecked exceptions are thrown during a REQUIRE the test should abort fail" duration="{duration}">
+      <error message="REQUIRE(thisThrows() == 0)">
+FAILED:
+	REQUIRE( thisThrows() == 0 )
+expected exception
+Exception.tests.cpp:<line number>
+      </error>
+    </testCase>
+    <testCase name="When unchecked exceptions are thrown from functions they are always failures" duration="{duration}">
+      <error message="CHECK(thisThrows() == 0)">
+FAILED:
+	CHECK( thisThrows() == 0 )
+expected exception
+Exception.tests.cpp:<line number>
+      </error>
+    </testCase>
+    <testCase name="When unchecked exceptions are thrown from sections they are always failures/section name" duration="{duration}">
+      <error message="TEST_CASE()">
+FAILED:
+unexpected exception
+Exception.tests.cpp:<line number>
+      </error>
+    </testCase>
+    <testCase name="thrown std::strings are translated" duration="{duration}">
+      <error message="TEST_CASE()">
+FAILED:
+Why would you throw a std::string?
+Exception.tests.cpp:<line number>
+      </error>
+    </testCase>
+  </file>
+  <file path="projects/<exe-name>/UsageTests/Generators.tests.cpp">
+    <testCase name="3x3x3 ints" duration="{duration}"/>
+    <testCase name="Copy and then generate a range/from var and iterators" duration="{duration}"/>
+    <testCase name="Copy and then generate a range/From a temporary container" duration="{duration}"/>
+    <testCase name="Copy and then generate a range/Final validation" duration="{duration}"/>
+    <testCase name="Generators -- adapters/Filtering by predicate/Basic usage" duration="{duration}"/>
+    <testCase name="Generators -- adapters/Filtering by predicate/Throws if there are no matching values" duration="{duration}"/>
+    <testCase name="Generators -- adapters/Shortening a range" duration="{duration}"/>
+    <testCase name="Generators -- adapters/Transforming elements/Same type" duration="{duration}"/>
+    <testCase name="Generators -- adapters/Transforming elements/Different type" duration="{duration}"/>
+    <testCase name="Generators -- adapters/Transforming elements/Different deduced type" duration="{duration}"/>
+    <testCase name="Generators -- adapters/Repeating a generator" duration="{duration}"/>
+    <testCase name="Generators -- adapters/Chunking a generator into sized pieces/Number of elements in source is divisible by chunk size" duration="{duration}"/>
+    <testCase name="Generators -- adapters/Chunking a generator into sized pieces/Number of elements in source is not divisible by chunk size" duration="{duration}"/>
+    <testCase name="Generators -- adapters/Chunking a generator into sized pieces/Chunk size of zero" duration="{duration}"/>
+    <testCase name="Generators -- adapters/Chunking a generator into sized pieces/Throws on too small generators" duration="{duration}"/>
+    <testCase name="Generators -- simple/one" duration="{duration}"/>
+    <testCase name="Generators -- simple/two" duration="{duration}"/>
+    <testCase name="Nested generators and captured variables" duration="{duration}"/>
+    <testCase name="strlen3" duration="{duration}"/>
+    <testCase name="tables" duration="{duration}"/>
+  </file>
+  <file path="projects/<exe-name>/UsageTests/Matchers.tests.cpp">
+    <testCase name="Arbitrary predicate matcher/Function pointer" duration="{duration}"/>
+    <testCase name="Arbitrary predicate matcher/Lambdas + different type" duration="{duration}"/>
+    <testCase name="Contains string matcher" duration="{duration}">
+      <failure message="CHECK_THAT(testStringForMatching(), Contains(&quot;not there&quot;, Catch::CaseSensitive::No))">
+FAILED:
+	CHECK_THAT( testStringForMatching(), Contains("not there", Catch::CaseSensitive::No) )
+with expansion:
+	"this string contains 'abc' as a substring" contains: "not there" (case insensitive)
+Matchers.tests.cpp:<line number>
+      </failure>
+      <failure message="CHECK_THAT(testStringForMatching(), Contains(&quot;STRING&quot;))">
+FAILED:
+	CHECK_THAT( testStringForMatching(), Contains("STRING") )
+with expansion:
+	"this string contains 'abc' as a substring" contains: "STRING"
+Matchers.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="EndsWith string matcher" duration="{duration}">
+      <failure message="CHECK_THAT(testStringForMatching(), EndsWith(&quot;Substring&quot;))">
+FAILED:
+	CHECK_THAT( testStringForMatching(), EndsWith("Substring") )
+with expansion:
+	"this string contains 'abc' as a substring" ends with: "Substring"
+Matchers.tests.cpp:<line number>
+      </failure>
+      <failure message="CHECK_THAT(testStringForMatching(), EndsWith(&quot;this&quot;, Catch::CaseSensitive::No))">
+FAILED:
+	CHECK_THAT( testStringForMatching(), EndsWith("this", Catch::CaseSensitive::No) )
+with expansion:
+	"this string contains 'abc' as a substring" ends with: "this" (case insensitive)
+Matchers.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="Equals" duration="{duration}"/>
+    <testCase name="Equals string matcher" duration="{duration}">
+      <failure message="CHECK_THAT(testStringForMatching(), Equals(&quot;this string contains 'ABC' as a substring&quot;))">
+FAILED:
+	CHECK_THAT( testStringForMatching(), Equals("this string contains 'ABC' as a substring") )
+with expansion:
+	"this string contains 'abc' as a substring" equals: "this string contains 'ABC' as a substring"
+Matchers.tests.cpp:<line number>
+      </failure>
+      <failure message="CHECK_THAT(testStringForMatching(), Equals(&quot;something else&quot;, Catch::CaseSensitive::No))">
+FAILED:
+	CHECK_THAT( testStringForMatching(), Equals("something else", Catch::CaseSensitive::No) )
+with expansion:
+	"this string contains 'abc' as a substring" equals: "something else" (case insensitive)
+Matchers.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="Exception matchers that fail/No exception" duration="{duration}">
+      <failure message="CHECK_THROWS_MATCHES(doesNotThrow(), SpecialException, ExceptionMatcher{1})">
+FAILED:
+	CHECK_THROWS_MATCHES( doesNotThrow(), SpecialException, ExceptionMatcher{1} )
+Matchers.tests.cpp:<line number>
+      </failure>
+      <failure message="REQUIRE_THROWS_MATCHES(doesNotThrow(), SpecialException, ExceptionMatcher{1})">
+FAILED:
+	REQUIRE_THROWS_MATCHES( doesNotThrow(), SpecialException, ExceptionMatcher{1} )
+Matchers.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="Exception matchers that fail/Type mismatch" duration="{duration}">
+      <error message="CHECK_THROWS_MATCHES(throwsAsInt(1), SpecialException, ExceptionMatcher{1})">
+FAILED:
+	CHECK_THROWS_MATCHES( throwsAsInt(1), SpecialException, ExceptionMatcher{1} )
+Unknown exception
+Matchers.tests.cpp:<line number>
+      </error>
+      <error message="REQUIRE_THROWS_MATCHES(throwsAsInt(1), SpecialException, ExceptionMatcher{1})">
+FAILED:
+	REQUIRE_THROWS_MATCHES( throwsAsInt(1), SpecialException, ExceptionMatcher{1} )
+Unknown exception
+Matchers.tests.cpp:<line number>
+      </error>
+    </testCase>
+    <testCase name="Exception matchers that fail/Contents are wrong" duration="{duration}">
+      <failure message="CHECK_THROWS_MATCHES(throwsSpecialException(3), SpecialException, ExceptionMatcher{1})">
+FAILED:
+	CHECK_THROWS_MATCHES( throwsSpecialException(3), SpecialException, ExceptionMatcher{1} )
+with expansion:
+	SpecialException::what special exception has value of 1
+Matchers.tests.cpp:<line number>
+      </failure>
+      <failure message="REQUIRE_THROWS_MATCHES(throwsSpecialException(4), SpecialException, ExceptionMatcher{1})">
+FAILED:
+	REQUIRE_THROWS_MATCHES( throwsSpecialException(4), SpecialException, ExceptionMatcher{1} )
+with expansion:
+	SpecialException::what special exception has value of 1
+Matchers.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="Exception matchers that succeed" duration="{duration}"/>
+    <testCase name="Exceptions matchers" duration="{duration}"/>
+    <testCase name="Floating point matchers: double/Relative" duration="{duration}"/>
+    <testCase name="Floating point matchers: double/Relative/Some subnormal values" duration="{duration}"/>
+    <testCase name="Floating point matchers: double/Margin" duration="{duration}"/>
+    <testCase name="Floating point matchers: double/ULPs" duration="{duration}"/>
+    <testCase name="Floating point matchers: double/Composed" duration="{duration}"/>
+    <testCase name="Floating point matchers: double/Constructor validation" duration="{duration}"/>
+    <testCase name="Floating point matchers: float/Relative" duration="{duration}"/>
+    <testCase name="Floating point matchers: float/Relative/Some subnormal values" duration="{duration}"/>
+    <testCase name="Floating point matchers: float/Margin" duration="{duration}"/>
+    <testCase name="Floating point matchers: float/ULPs" duration="{duration}"/>
+    <testCase name="Floating point matchers: float/Composed" duration="{duration}"/>
+    <testCase name="Floating point matchers: float/Constructor validation" duration="{duration}"/>
+    <testCase name="Matchers can be (AllOf) composed with the &amp;&amp; operator" duration="{duration}"/>
+    <testCase name="Matchers can be (AnyOf) composed with the || operator" duration="{duration}"/>
+    <testCase name="Matchers can be composed with both &amp;&amp; and ||" duration="{duration}"/>
+    <testCase name="Matchers can be composed with both &amp;&amp; and || - failing" duration="{duration}">
+      <failure message="CHECK_THAT(testStringForMatching(), (Contains(&quot;string&quot;) || Contains(&quot;different&quot;)) &amp;&amp; Contains(&quot;random&quot;))">
+FAILED:
+	CHECK_THAT( testStringForMatching(), (Contains("string") || Contains("different")) &amp;&amp; Contains("random") )
+with expansion:
+	"this string contains 'abc' as a substring" ( ( contains: "string" or contains: "different" ) and contains: "random" )
+Matchers.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="Matchers can be negated (Not) with the ! operator" duration="{duration}"/>
+    <testCase name="Matchers can be negated (Not) with the ! operator - failing" duration="{duration}">
+      <failure message="CHECK_THAT(testStringForMatching(), !Contains(&quot;substring&quot;))">
+FAILED:
+	CHECK_THAT( testStringForMatching(), !Contains("substring") )
+with expansion:
+	"this string contains 'abc' as a substring" not contains: "substring"
+Matchers.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="Predicate matcher can accept const char*" duration="{duration}"/>
+    <testCase name="Regex string matcher" duration="{duration}">
+      <failure message="CHECK_THAT(testStringForMatching(), Matches(&quot;this STRING contains 'abc' as a substring&quot;))">
+FAILED:
+	CHECK_THAT( testStringForMatching(), Matches("this STRING contains 'abc' as a substring") )
+with expansion:
+	"this string contains 'abc' as a substring" matches "this STRING contains 'abc' as a substring" case sensitively
+Matchers.tests.cpp:<line number>
+      </failure>
+      <failure message="CHECK_THAT(testStringForMatching(), Matches(&quot;contains 'abc' as a substring&quot;))">
+FAILED:
+	CHECK_THAT( testStringForMatching(), Matches("contains 'abc' as a substring") )
+with expansion:
+	"this string contains 'abc' as a substring" matches "contains 'abc' as a substring" case sensitively
+Matchers.tests.cpp:<line number>
+      </failure>
+      <failure message="CHECK_THAT(testStringForMatching(), Matches(&quot;this string contains 'abc' as a&quot;))">
+FAILED:
+	CHECK_THAT( testStringForMatching(), Matches("this string contains 'abc' as a") )
+with expansion:
+	"this string contains 'abc' as a substring" matches "this string contains 'abc' as a" case sensitively
+Matchers.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="Regression test #1" duration="{duration}"/>
+    <testCase name="StartsWith string matcher" duration="{duration}">
+      <failure message="CHECK_THAT(testStringForMatching(), StartsWith(&quot;This String&quot;))">
+FAILED:
+	CHECK_THAT( testStringForMatching(), StartsWith("This String") )
+with expansion:
+	"this string contains 'abc' as a substring" starts with: "This String"
+Matchers.tests.cpp:<line number>
+      </failure>
+      <failure message="CHECK_THAT(testStringForMatching(), StartsWith(&quot;string&quot;, Catch::CaseSensitive::No))">
+FAILED:
+	CHECK_THAT( testStringForMatching(), StartsWith("string", Catch::CaseSensitive::No) )
+with expansion:
+	"this string contains 'abc' as a substring" starts with: "string" (case insensitive)
+Matchers.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="String matchers" duration="{duration}"/>
+    <testCase name="Vector Approx matcher/Empty vector is roughly equal to an empty vector" duration="{duration}"/>
+    <testCase name="Vector Approx matcher/Vectors with elements/A vector is approx equal to itself" duration="{duration}"/>
+    <testCase name="Vector Approx matcher/Vectors with elements/Different length" duration="{duration}"/>
+    <testCase name="Vector Approx matcher/Vectors with elements/Same length, different elements" duration="{duration}"/>
+    <testCase name="Vector Approx matcher -- failing/Empty and non empty vectors are not approx equal" duration="{duration}">
+      <failure message="CHECK_THAT(empty, Approx(t1))">
+FAILED:
+	CHECK_THAT( empty, Approx(t1) )
+with expansion:
+	{  } is approx: { 1.0, 2.0 }
+Matchers.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="Vector Approx matcher -- failing/Just different vectors" duration="{duration}">
+      <failure message="CHECK_THAT(v1, Approx(v2))">
+FAILED:
+	CHECK_THAT( v1, Approx(v2) )
+with expansion:
+	{ 2.0, 4.0, 6.0 } is approx: { 1.0, 3.0, 5.0 }
+Matchers.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="Vector matchers/Contains (element)" duration="{duration}"/>
+    <testCase name="Vector matchers/Contains (vector)" duration="{duration}"/>
+    <testCase name="Vector matchers/Contains (element), composed" duration="{duration}"/>
+    <testCase name="Vector matchers/Equals" duration="{duration}"/>
+    <testCase name="Vector matchers/UnorderedEquals" duration="{duration}"/>
+    <testCase name="Vector matchers that fail/Contains (element)" duration="{duration}">
+      <failure message="CHECK_THAT(v, VectorContains(-1))">
+FAILED:
+	CHECK_THAT( v, VectorContains(-1) )
+with expansion:
+	{ 1, 2, 3 } Contains: -1
+Matchers.tests.cpp:<line number>
+      </failure>
+      <failure message="CHECK_THAT(empty, VectorContains(1))">
+FAILED:
+	CHECK_THAT( empty, VectorContains(1) )
+with expansion:
+	{  } Contains: 1
+Matchers.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="Vector matchers that fail/Contains (vector)" duration="{duration}">
+      <failure message="CHECK_THAT(empty, Contains(v))">
+FAILED:
+	CHECK_THAT( empty, Contains(v) )
+with expansion:
+	{  } Contains: { 1, 2, 3 }
+Matchers.tests.cpp:<line number>
+      </failure>
+      <failure message="CHECK_THAT(v, Contains(v2))">
+FAILED:
+	CHECK_THAT( v, Contains(v2) )
+with expansion:
+	{ 1, 2, 3 } Contains: { 1, 2, 4 }
+Matchers.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="Vector matchers that fail/Equals" duration="{duration}">
+      <failure message="CHECK_THAT(v, Equals(v2))">
+FAILED:
+	CHECK_THAT( v, Equals(v2) )
+with expansion:
+	{ 1, 2, 3 } Equals: { 1, 2 }
+Matchers.tests.cpp:<line number>
+      </failure>
+      <failure message="CHECK_THAT(v2, Equals(v))">
+FAILED:
+	CHECK_THAT( v2, Equals(v) )
+with expansion:
+	{ 1, 2 } Equals: { 1, 2, 3 }
+Matchers.tests.cpp:<line number>
+      </failure>
+      <failure message="CHECK_THAT(empty, Equals(v))">
+FAILED:
+	CHECK_THAT( empty, Equals(v) )
+with expansion:
+	{  } Equals: { 1, 2, 3 }
+Matchers.tests.cpp:<line number>
+      </failure>
+      <failure message="CHECK_THAT(v, Equals(empty))">
+FAILED:
+	CHECK_THAT( v, Equals(empty) )
+with expansion:
+	{ 1, 2, 3 } Equals: {  }
+Matchers.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="Vector matchers that fail/UnorderedEquals" duration="{duration}">
+      <failure message="CHECK_THAT(v, UnorderedEquals(empty))">
+FAILED:
+	CHECK_THAT( v, UnorderedEquals(empty) )
+with expansion:
+	{ 1, 2, 3 } UnorderedEquals: {  }
+Matchers.tests.cpp:<line number>
+      </failure>
+      <failure message="CHECK_THAT(empty, UnorderedEquals(v))">
+FAILED:
+	CHECK_THAT( empty, UnorderedEquals(v) )
+with expansion:
+	{  } UnorderedEquals: { 1, 2, 3 }
+Matchers.tests.cpp:<line number>
+      </failure>
+      <failure message="CHECK_THAT(permuted, UnorderedEquals(v))">
+FAILED:
+	CHECK_THAT( permuted, UnorderedEquals(v) )
+with expansion:
+	{ 1, 3 } UnorderedEquals: { 1, 2, 3 }
+Matchers.tests.cpp:<line number>
+      </failure>
+      <failure message="CHECK_THAT(permuted, UnorderedEquals(v))">
+FAILED:
+	CHECK_THAT( permuted, UnorderedEquals(v) )
+with expansion:
+	{ 3, 1 } UnorderedEquals: { 1, 2, 3 }
+Matchers.tests.cpp:<line number>
+      </failure>
+    </testCase>
+  </file>
+  <file path="projects/<exe-name>/UsageTests/Message.tests.cpp">
+    <testCase name="#1455 - INFO and WARN can start with a linebreak" duration="{duration}"/>
+    <testCase name="CAPTURE can deal with complex expressions" duration="{duration}"/>
+    <testCase name="CAPTURE can deal with complex expressions involving commas" duration="{duration}"/>
+    <testCase name="CAPTURE parses string and character constants" duration="{duration}"/>
+    <testCase name="FAIL aborts the test" duration="{duration}">
+      <failure message="FAIL()">
+FAILED:
+This is a failure
+Message.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="FAIL does not require an argument" duration="{duration}">
+      <failure message="FAIL()">
+FAILED:
+Message.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="FAIL_CHECK does not abort the test" duration="{duration}">
+      <failure message="FAIL_CHECK()">
+FAILED:
+This is a failure
+Message.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="INFO and WARN do not abort tests" duration="{duration}"/>
+    <testCase name="INFO gets logged on failure" duration="{duration}">
+      <failure message="REQUIRE(a == 1)">
+FAILED:
+	REQUIRE( a == 1 )
+with expansion:
+	2 == 1
+this message should be logged
+so should this
+Message.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="INFO gets logged on failure, even if captured before successful assertions" duration="{duration}">
+      <failure message="CHECK(a == 1)">
+FAILED:
+	CHECK( a == 1 )
+with expansion:
+	2 == 1
+this message may be logged later
+this message should be logged
+Message.tests.cpp:<line number>
+      </failure>
+      <failure message="CHECK(a == 0)">
+FAILED:
+	CHECK( a == 0 )
+with expansion:
+	2 == 0
+this message may be logged later
+this message should be logged
+and this, but later
+Message.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="INFO is reset for each loop" duration="{duration}">
+      <failure message="REQUIRE(i &lt; 10)">
+FAILED:
+	REQUIRE( i &lt; 10 )
+with expansion:
+	10 &lt; 10
+current counter 10
+i := 10
+Message.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="Output from all sections is reported/one" duration="{duration}">
+      <failure message="FAIL()">
+FAILED:
+Message from section one
+Message.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="Output from all sections is reported/two" duration="{duration}">
+      <failure message="FAIL()">
+FAILED:
+Message from section two
+Message.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="SUCCEED counts as a test pass" duration="{duration}"/>
+    <testCase name="SUCCEED does not require an argument" duration="{duration}"/>
+    <testCase name="Standard output from all sections is reported/two" duration="{duration}"/>
+    <testCase name="The NO_FAIL macro reports a failure but does not fail the test" duration="{duration}"/>
+    <testCase name="just failure" duration="{duration}">
+      <failure message="FAIL()">
+FAILED:
+Previous info should not be seen
+Message.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="just failure after unscoped info" duration="{duration}">
+      <failure message="FAIL()">
+FAILED:
+previous unscoped info SHOULD not be seen
+Message.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="mix info, unscoped info and warning" duration="{duration}"/>
+    <testCase name="not prints unscoped info from previous failures" duration="{duration}">
+      <failure message="REQUIRE(false)">
+FAILED:
+	REQUIRE( false )
+this SHOULD be seen
+Message.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="print unscoped info if passing unscoped info is printed" duration="{duration}"/>
+    <testCase name="prints unscoped info on failure" duration="{duration}">
+      <failure message="REQUIRE(false)">
+FAILED:
+	REQUIRE( false )
+this SHOULD be seen
+this SHOULD also be seen
+Message.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="prints unscoped info only for the first assertion" duration="{duration}">
+      <failure message="CHECK(false)">
+FAILED:
+	CHECK( false )
+this SHOULD be seen only ONCE
+Message.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="sends information to INFO" duration="{duration}">
+      <failure message="REQUIRE(false)">
+FAILED:
+	REQUIRE( false )
+hi
+i := 7
+Message.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="stacks unscoped info in loops" duration="{duration}">
+      <failure message="CHECK(false)">
+FAILED:
+	CHECK( false )
+Count 1 to 3...
+1
+2
+3
+Message.tests.cpp:<line number>
+      </failure>
+      <failure message="CHECK(false)">
+FAILED:
+	CHECK( false )
+Count 4 to 6...
+4
+5
+6
+Message.tests.cpp:<line number>
+      </failure>
+    </testCase>
+  </file>
+  <file path="projects/<exe-name>/UsageTests/Misc.tests.cpp">
+    <testCase name="# A test name that starts with a #" duration="{duration}"/>
+    <testCase name="#1175 - Hidden Test" duration="{duration}"/>
+    <testCase name="#835 -- errno should not be touched by Catch" duration="{duration}">
+      <skipped message="CHECK(f() == 0)">
+FAILED:
+	CHECK( f() == 0 )
+with expansion:
+	1 == 0
+Misc.tests.cpp:<line number>
+      </skipped>
+    </testCase>
+    <testCase name="#961 -- Dynamically created sections should all be reported/Looped section 0" duration="{duration}"/>
+    <testCase name="#961 -- Dynamically created sections should all be reported/Looped section 1" duration="{duration}"/>
+    <testCase name="#961 -- Dynamically created sections should all be reported/Looped section 2" duration="{duration}"/>
+    <testCase name="#961 -- Dynamically created sections should all be reported/Looped section 3" duration="{duration}"/>
+    <testCase name="#961 -- Dynamically created sections should all be reported/Looped section 4" duration="{duration}"/>
+    <testCase name="A Template product test case - Foo&lt;float>" duration="{duration}"/>
+    <testCase name="A Template product test case - Foo&lt;int>" duration="{duration}"/>
+    <testCase name="A Template product test case - std::vector&lt;float>" duration="{duration}"/>
+    <testCase name="A Template product test case - std::vector&lt;int>" duration="{duration}"/>
+    <testCase name="A Template product test case with array signature - Bar&lt;float, 42>" duration="{duration}"/>
+    <testCase name="A Template product test case with array signature - Bar&lt;int, 9>" duration="{duration}"/>
+    <testCase name="A Template product test case with array signature - std::array&lt;float, 42>" duration="{duration}"/>
+    <testCase name="A Template product test case with array signature - std::array&lt;int, 9>" duration="{duration}"/>
+    <testCase name="A couple of nested sections followed by a failure" duration="{duration}">
+      <failure message="FAIL()">
+FAILED:
+to infinity and beyond
+Misc.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="A couple of nested sections followed by a failure/Outer/Inner" duration="{duration}"/>
+    <testCase name="Factorials are computed" duration="{duration}"/>
+    <testCase name="ManuallyRegistered" duration="{duration}"/>
+    <testCase name="Nice descriptive name" duration="{duration}"/>
+    <testCase name="Product with differing arities - std::tuple&lt;int, double, float>" duration="{duration}"/>
+    <testCase name="Product with differing arities - std::tuple&lt;int, double>" duration="{duration}"/>
+    <testCase name="Product with differing arities - std::tuple&lt;int>" duration="{duration}"/>
+    <testCase name="Sends stuff to stdout and stderr" duration="{duration}"/>
+    <testCase name="Tabs and newlines show in output" duration="{duration}">
+      <failure message="CHECK(s1 == s2)">
+FAILED:
+	CHECK( s1 == s2 )
+with expansion:
+	"if ($b == 10) {
+		$a	= 20;
+}"
+==
+"if ($b == 10) {
+	$a = 20;
+}
+"
+Misc.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="Template test case with test types specified inside non-copyable and non-movable std::tuple - NonCopyableAndNonMovableTypes - 0" duration="{duration}"/>
+    <testCase name="Template test case with test types specified inside non-copyable and non-movable std::tuple - NonCopyableAndNonMovableTypes - 1" duration="{duration}"/>
+    <testCase name="Template test case with test types specified inside non-default-constructible std::tuple - MyNonDefaultConstructibleTypes - 0" duration="{duration}"/>
+    <testCase name="Template test case with test types specified inside non-default-constructible std::tuple - MyNonDefaultConstructibleTypes - 1" duration="{duration}"/>
+    <testCase name="Template test case with test types specified inside std::tuple - MyTypes - 0" duration="{duration}"/>
+    <testCase name="Template test case with test types specified inside std::tuple - MyTypes - 1" duration="{duration}"/>
+    <testCase name="Template test case with test types specified inside std::tuple - MyTypes - 2" duration="{duration}"/>
+    <testCase name="TemplateTest: vectors can be sized and resized - float" duration="{duration}"/>
+    <testCase name="TemplateTest: vectors can be sized and resized - float/resizing bigger changes size and capacity" duration="{duration}"/>
+    <testCase name="TemplateTest: vectors can be sized and resized - float/resizing smaller changes size but not capacity" duration="{duration}"/>
+    <testCase name="TemplateTest: vectors can be sized and resized - float/resizing smaller changes size but not capacity/We can use the 'swap trick' to reset the capacity" duration="{duration}"/>
+    <testCase name="TemplateTest: vectors can be sized and resized - float/reserving bigger changes capacity but not size" duration="{duration}"/>
+    <testCase name="TemplateTest: vectors can be sized and resized - float/reserving smaller does not change size or capacity" duration="{duration}"/>
+    <testCase name="TemplateTest: vectors can be sized and resized - int" duration="{duration}"/>
+    <testCase name="TemplateTest: vectors can be sized and resized - int/resizing bigger changes size and capacity" duration="{duration}"/>
+    <testCase name="TemplateTest: vectors can be sized and resized - int/resizing smaller changes size but not capacity" duration="{duration}"/>
+    <testCase name="TemplateTest: vectors can be sized and resized - int/resizing smaller changes size but not capacity/We can use the 'swap trick' to reset the capacity" duration="{duration}"/>
+    <testCase name="TemplateTest: vectors can be sized and resized - int/reserving bigger changes capacity but not size" duration="{duration}"/>
+    <testCase name="TemplateTest: vectors can be sized and resized - int/reserving smaller does not change size or capacity" duration="{duration}"/>
+    <testCase name="TemplateTest: vectors can be sized and resized - std::string" duration="{duration}"/>
+    <testCase name="TemplateTest: vectors can be sized and resized - std::string/resizing bigger changes size and capacity" duration="{duration}"/>
+    <testCase name="TemplateTest: vectors can be sized and resized - std::string/resizing smaller changes size but not capacity" duration="{duration}"/>
+    <testCase name="TemplateTest: vectors can be sized and resized - std::string/resizing smaller changes size but not capacity/We can use the 'swap trick' to reset the capacity" duration="{duration}"/>
+    <testCase name="TemplateTest: vectors can be sized and resized - std::string/reserving bigger changes capacity but not size" duration="{duration}"/>
+    <testCase name="TemplateTest: vectors can be sized and resized - std::string/reserving smaller does not change size or capacity" duration="{duration}"/>
+    <testCase name="TemplateTest: vectors can be sized and resized - std::tuple&lt;int,float>" duration="{duration}"/>
+    <testCase name="TemplateTest: vectors can be sized and resized - std::tuple&lt;int,float>/resizing bigger changes size and capacity" duration="{duration}"/>
+    <testCase name="TemplateTest: vectors can be sized and resized - std::tuple&lt;int,float>/resizing smaller changes size but not capacity" duration="{duration}"/>
+    <testCase name="TemplateTest: vectors can be sized and resized - std::tuple&lt;int,float>/resizing smaller changes size but not capacity/We can use the 'swap trick' to reset the capacity" duration="{duration}"/>
+    <testCase name="TemplateTest: vectors can be sized and resized - std::tuple&lt;int,float>/reserving bigger changes capacity but not size" duration="{duration}"/>
+    <testCase name="TemplateTest: vectors can be sized and resized - std::tuple&lt;int,float>/reserving smaller does not change size or capacity" duration="{duration}"/>
+    <testCase name="TemplateTestSig: vectors can be sized and resized - (std::tuple&lt;int, float>), 6" duration="{duration}"/>
+    <testCase name="TemplateTestSig: vectors can be sized and resized - (std::tuple&lt;int, float>), 6/resizing bigger changes size and capacity" duration="{duration}"/>
+    <testCase name="TemplateTestSig: vectors can be sized and resized - (std::tuple&lt;int, float>), 6/resizing smaller changes size but not capacity" duration="{duration}"/>
+    <testCase name="TemplateTestSig: vectors can be sized and resized - (std::tuple&lt;int, float>), 6/resizing smaller changes size but not capacity/We can use the 'swap trick' to reset the capacity" duration="{duration}"/>
+    <testCase name="TemplateTestSig: vectors can be sized and resized - (std::tuple&lt;int, float>), 6/reserving bigger changes capacity but not size" duration="{duration}"/>
+    <testCase name="TemplateTestSig: vectors can be sized and resized - (std::tuple&lt;int, float>), 6/reserving smaller does not change size or capacity" duration="{duration}"/>
+    <testCase name="TemplateTestSig: vectors can be sized and resized - float,4" duration="{duration}"/>
+    <testCase name="TemplateTestSig: vectors can be sized and resized - float,4/resizing bigger changes size and capacity" duration="{duration}"/>
+    <testCase name="TemplateTestSig: vectors can be sized and resized - float,4/resizing smaller changes size but not capacity" duration="{duration}"/>
+    <testCase name="TemplateTestSig: vectors can be sized and resized - float,4/resizing smaller changes size but not capacity/We can use the 'swap trick' to reset the capacity" duration="{duration}"/>
+    <testCase name="TemplateTestSig: vectors can be sized and resized - float,4/reserving bigger changes capacity but not size" duration="{duration}"/>
+    <testCase name="TemplateTestSig: vectors can be sized and resized - float,4/reserving smaller does not change size or capacity" duration="{duration}"/>
+    <testCase name="TemplateTestSig: vectors can be sized and resized - int,5" duration="{duration}"/>
+    <testCase name="TemplateTestSig: vectors can be sized and resized - int,5/resizing bigger changes size and capacity" duration="{duration}"/>
+    <testCase name="TemplateTestSig: vectors can be sized and resized - int,5/resizing smaller changes size but not capacity" duration="{duration}"/>
+    <testCase name="TemplateTestSig: vectors can be sized and resized - int,5/resizing smaller changes size but not capacity/We can use the 'swap trick' to reset the capacity" duration="{duration}"/>
+    <testCase name="TemplateTestSig: vectors can be sized and resized - int,5/reserving bigger changes capacity but not size" duration="{duration}"/>
+    <testCase name="TemplateTestSig: vectors can be sized and resized - int,5/reserving smaller does not change size or capacity" duration="{duration}"/>
+    <testCase name="TemplateTestSig: vectors can be sized and resized - std::string,15" duration="{duration}"/>
+    <testCase name="TemplateTestSig: vectors can be sized and resized - std::string,15/resizing bigger changes size and capacity" duration="{duration}"/>
+    <testCase name="TemplateTestSig: vectors can be sized and resized - std::string,15/resizing smaller changes size but not capacity" duration="{duration}"/>
+    <testCase name="TemplateTestSig: vectors can be sized and resized - std::string,15/resizing smaller changes size but not capacity/We can use the 'swap trick' to reset the capacity" duration="{duration}"/>
+    <testCase name="TemplateTestSig: vectors can be sized and resized - std::string,15/reserving bigger changes capacity but not size" duration="{duration}"/>
+    <testCase name="TemplateTestSig: vectors can be sized and resized - std::string,15/reserving smaller does not change size or capacity" duration="{duration}"/>
+    <testCase name="This test 'should' fail but doesn't" duration="{duration}"/>
+    <testCase name="atomic if" duration="{duration}"/>
+    <testCase name="checkedElse" duration="{duration}"/>
+    <testCase name="checkedElse, failing" duration="{duration}">
+      <failure message="CHECKED_ELSE(flag)">
+FAILED:
+	CHECKED_ELSE( flag )
+with expansion:
+	false
+Misc.tests.cpp:<line number>
+      </failure>
+      <failure message="REQUIRE(testCheckedElse( false ))">
+FAILED:
+	REQUIRE( testCheckedElse( false ) )
+with expansion:
+	false
+Misc.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="checkedIf" duration="{duration}"/>
+    <testCase name="checkedIf, failing" duration="{duration}">
+      <failure message="CHECKED_IF(flag)">
+FAILED:
+	CHECKED_IF( flag )
+with expansion:
+	false
+Misc.tests.cpp:<line number>
+      </failure>
+      <failure message="REQUIRE(testCheckedIf( false ))">
+FAILED:
+	REQUIRE( testCheckedIf( false ) )
+with expansion:
+	false
+Misc.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="even more nested SECTION tests/c/d (leaf)" duration="{duration}"/>
+    <testCase name="even more nested SECTION tests/c/e (leaf)" duration="{duration}"/>
+    <testCase name="even more nested SECTION tests/f (leaf)" duration="{duration}"/>
+    <testCase name="long long" duration="{duration}"/>
+    <testCase name="looped SECTION tests/b is currently: 0" duration="{duration}">
+      <failure message="CHECK(b > a)">
+FAILED:
+	CHECK( b > a )
+with expansion:
+	0 > 1
+Misc.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="looped SECTION tests/b is currently: 1" duration="{duration}">
+      <failure message="CHECK(b > a)">
+FAILED:
+	CHECK( b > a )
+with expansion:
+	1 > 1
+Misc.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="looped SECTION tests/b is currently: 2" duration="{duration}"/>
+    <testCase name="looped SECTION tests/b is currently: 3" duration="{duration}"/>
+    <testCase name="looped SECTION tests/b is currently: 4" duration="{duration}"/>
+    <testCase name="looped SECTION tests/b is currently: 5" duration="{duration}"/>
+    <testCase name="looped SECTION tests/b is currently: 6" duration="{duration}"/>
+    <testCase name="looped SECTION tests/b is currently: 7" duration="{duration}"/>
+    <testCase name="looped SECTION tests/b is currently: 8" duration="{duration}"/>
+    <testCase name="looped SECTION tests/b is currently: 9" duration="{duration}"/>
+    <testCase name="looped tests" duration="{duration}">
+      <failure message="CHECK(( fib[i] % 2 ) == 0)">
+FAILED:
+	CHECK( ( fib[i] % 2 ) == 0 )
+with expansion:
+	1 == 0
+Testing if fib[0] (1) is even
+Misc.tests.cpp:<line number>
+      </failure>
+      <failure message="CHECK(( fib[i] % 2 ) == 0)">
+FAILED:
+	CHECK( ( fib[i] % 2 ) == 0 )
+with expansion:
+	1 == 0
+Testing if fib[1] (1) is even
+Misc.tests.cpp:<line number>
+      </failure>
+      <failure message="CHECK(( fib[i] % 2 ) == 0)">
+FAILED:
+	CHECK( ( fib[i] % 2 ) == 0 )
+with expansion:
+	1 == 0
+Testing if fib[3] (3) is even
+Misc.tests.cpp:<line number>
+      </failure>
+      <failure message="CHECK(( fib[i] % 2 ) == 0)">
+FAILED:
+	CHECK( ( fib[i] % 2 ) == 0 )
+with expansion:
+	1 == 0
+Testing if fib[4] (5) is even
+Misc.tests.cpp:<line number>
+      </failure>
+      <failure message="CHECK(( fib[i] % 2 ) == 0)">
+FAILED:
+	CHECK( ( fib[i] % 2 ) == 0 )
+with expansion:
+	1 == 0
+Testing if fib[6] (13) is even
+Misc.tests.cpp:<line number>
+      </failure>
+      <failure message="CHECK(( fib[i] % 2 ) == 0)">
+FAILED:
+	CHECK( ( fib[i] % 2 ) == 0 )
+with expansion:
+	1 == 0
+Testing if fib[7] (21) is even
+Misc.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="more nested SECTION tests/equal/doesn't equal" duration="{duration}">
+      <failure message="REQUIRE(a == b)">
+FAILED:
+	REQUIRE( a == b )
+with expansion:
+	1 == 2
+Misc.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="more nested SECTION tests/doesn't equal/not equal" duration="{duration}"/>
+    <testCase name="more nested SECTION tests/doesn't equal/less than" duration="{duration}"/>
+    <testCase name="nested SECTION tests/doesn't equal" duration="{duration}"/>
+    <testCase name="nested SECTION tests/doesn't equal/not equal" duration="{duration}"/>
+    <testCase name="not allowed" duration="{duration}"/>
+    <testCase name="null strings" duration="{duration}"/>
+    <testCase name="random SECTION tests/doesn't equal" duration="{duration}"/>
+    <testCase name="random SECTION tests/not equal" duration="{duration}"/>
+    <testCase name="send a single char to INFO" duration="{duration}">
+      <failure message="REQUIRE(false)">
+FAILED:
+	REQUIRE( false )
+3
+Misc.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="toString on const wchar_t const pointer returns the string contents" duration="{duration}"/>
+    <testCase name="toString on const wchar_t pointer returns the string contents" duration="{duration}"/>
+    <testCase name="toString on wchar_t const pointer returns the string contents" duration="{duration}"/>
+    <testCase name="toString on wchar_t returns the string contents" duration="{duration}"/>
+    <testCase name="vectors can be sized and resized" duration="{duration}"/>
+    <testCase name="vectors can be sized and resized/resizing bigger changes size and capacity" duration="{duration}"/>
+    <testCase name="vectors can be sized and resized/resizing smaller changes size but not capacity" duration="{duration}"/>
+    <testCase name="vectors can be sized and resized/resizing smaller changes size but not capacity/We can use the 'swap trick' to reset the capacity" duration="{duration}"/>
+    <testCase name="vectors can be sized and resized/reserving bigger changes capacity but not size" duration="{duration}"/>
+    <testCase name="vectors can be sized and resized/reserving smaller does not change size or capacity" duration="{duration}"/>
+    <testCase name="xmlentitycheck/embedded xml: &lt;test>it should be possible to embed xml characters, such as &lt;, &quot; or &amp;, or even whole &lt;xml>documents&lt;/xml> within an attribute&lt;/test>" duration="{duration}"/>
+    <testCase name="xmlentitycheck/encoded chars: these should all be encoded: &amp;&amp;&amp;&quot;&quot;&quot;&lt;&lt;&lt;&amp;&quot;&lt;&lt;&amp;&quot;" duration="{duration}"/>
+  </file>
+  <file path="projects/<exe-name>/UsageTests/ToStringChrono.tests.cpp">
+    <testCase name="Stringifying std::chrono::duration helpers" duration="{duration}"/>
+    <testCase name="Stringifying std::chrono::duration with weird ratios" duration="{duration}"/>
+    <testCase name="Stringifying std::chrono::time_point&lt;system_clock>" duration="{duration}"/>
+  </file>
+  <file path="projects/<exe-name>/UsageTests/ToStringGeneral.tests.cpp">
+    <testCase name="Capture and info messages/Capture should stringify like assertions" duration="{duration}"/>
+    <testCase name="Capture and info messages/Info should NOT stringify the way assertions do" duration="{duration}"/>
+    <testCase name="Character pretty printing/Specifically escaped" duration="{duration}"/>
+    <testCase name="Character pretty printing/General chars" duration="{duration}"/>
+    <testCase name="Character pretty printing/Low ASCII" duration="{duration}"/>
+    <testCase name="Exception as a value (e.g. in REQUIRE_THROWS_MATCHES) can be stringified" duration="{duration}"/>
+    <testCase name="Precision of floating point stringification can be set/Floats" duration="{duration}"/>
+    <testCase name="Precision of floating point stringification can be set/Double" duration="{duration}"/>
+    <testCase name="Static arrays are convertible to string/Single item" duration="{duration}"/>
+    <testCase name="Static arrays are convertible to string/Multiple" duration="{duration}"/>
+    <testCase name="Static arrays are convertible to string/Non-trivial inner items" duration="{duration}"/>
+    <testCase name="std::map is convertible string/empty" duration="{duration}"/>
+    <testCase name="std::map is convertible string/single item" duration="{duration}"/>
+    <testCase name="std::map is convertible string/several items" duration="{duration}"/>
+    <testCase name="std::set is convertible string/empty" duration="{duration}"/>
+    <testCase name="std::set is convertible string/single item" duration="{duration}"/>
+    <testCase name="std::set is convertible string/several items" duration="{duration}"/>
+  </file>
+  <file path="projects/<exe-name>/UsageTests/ToStringPair.tests.cpp">
+    <testCase name="pair&lt;pair&lt;int,const char *,pair&lt;std::string,int> > -> toString" duration="{duration}"/>
+    <testCase name="std::pair&lt;int,const std::string> -> toString" duration="{duration}"/>
+    <testCase name="std::pair&lt;int,std::string> -> toString" duration="{duration}"/>
+    <testCase name="std::vector&lt;std::pair&lt;std::string,int> > -> toString" duration="{duration}"/>
+  </file>
+  <file path="projects/<exe-name>/UsageTests/ToStringTuple.tests.cpp">
+    <testCase name="tuple&lt;>" duration="{duration}"/>
+    <testCase name="tuple&lt;float,int>" duration="{duration}"/>
+    <testCase name="tuple&lt;int>" duration="{duration}"/>
+    <testCase name="tuple&lt;0,int,const char *>" duration="{duration}"/>
+    <testCase name="tuple&lt;string,string>" duration="{duration}"/>
+    <testCase name="tuple&lt;tuple&lt;int>,tuple&lt;>,float>" duration="{duration}"/>
+  </file>
+  <file path="projects/<exe-name>/UsageTests/ToStringVector.tests.cpp">
+    <testCase name="array&lt;int, N> -> toString" duration="{duration}"/>
+    <testCase name="vec&lt;vec&lt;string,alloc>> -> toString" duration="{duration}"/>
+    <testCase name="vector&lt;bool> -> toString" duration="{duration}"/>
+    <testCase name="vector&lt;int,allocator> -> toString" duration="{duration}"/>
+    <testCase name="vector&lt;int> -> toString" duration="{duration}"/>
+    <testCase name="vector&lt;string> -> toString" duration="{duration}"/>
+  </file>
+  <file path="projects/<exe-name>/UsageTests/ToStringWhich.tests.cpp">
+    <testCase name="stringify ranges" duration="{duration}"/>
+    <testCase name="stringify( has_maker )" duration="{duration}"/>
+    <testCase name="stringify( has_maker_and_operator )" duration="{duration}"/>
+    <testCase name="stringify( has_neither )" duration="{duration}"/>
+    <testCase name="stringify( has_operator )" duration="{duration}"/>
+    <testCase name="stringify( has_template_operator )" duration="{duration}"/>
+    <testCase name="stringify( vectors&lt;has_maker> )" duration="{duration}"/>
+    <testCase name="stringify( vectors&lt;has_maker_and_operator> )" duration="{duration}"/>
+    <testCase name="stringify( vectors&lt;has_operator> )" duration="{duration}"/>
+  </file>
+  <file path="projects/<exe-name>/UsageTests/Tricky.tests.cpp">
+    <testCase name="#1514: stderr/stdout is not captured in tests aborted by an exception" duration="{duration}">
+      <failure message="FAIL()">
+FAILED:
+1514
+Tricky.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="(unimplemented) static bools can be evaluated/compare to true" duration="{duration}"/>
+    <testCase name="(unimplemented) static bools can be evaluated/compare to false" duration="{duration}"/>
+    <testCase name="(unimplemented) static bools can be evaluated/negation" duration="{duration}"/>
+    <testCase name="(unimplemented) static bools can be evaluated/double negation" duration="{duration}"/>
+    <testCase name="(unimplemented) static bools can be evaluated/direct" duration="{duration}"/>
+    <testCase name="A failing expression with a non streamable type is still captured" duration="{duration}">
+      <failure message="CHECK(&amp;o1 == &amp;o2)">
+FAILED:
+	CHECK( &amp;o1 == &amp;o2 )
+with expansion:
+	0x<hex digits> == 0x<hex digits>
+Tricky.tests.cpp:<line number>
+      </failure>
+      <failure message="CHECK(o1 == o2)">
+FAILED:
+	CHECK( o1 == o2 )
+with expansion:
+	{?} == {?}
+Tricky.tests.cpp:<line number>
+      </failure>
+    </testCase>
+    <testCase name="An expression with side-effects should only be evaluated once" duration="{duration}"/>
+    <testCase name="Assertions then sections" duration="{duration}"/>
+    <testCase name="Assertions then sections/A section" duration="{duration}"/>
+    <testCase name="Assertions then sections/A section/Another section" duration="{duration}"/>
+    <testCase name="Assertions then sections/A section/Another other section" duration="{duration}"/>
+    <testCase name="Commas in various macros are allowed" duration="{duration}"/>
+    <testCase name="Comparing function pointers" duration="{duration}"/>
+    <testCase name="Objects that evaluated in boolean contexts can be checked" duration="{duration}"/>
+    <testCase name="Test enum bit values" duration="{duration}"/>
+    <testCase name="Where the LHS is not a simple value" duration="{duration}"/>
+    <testCase name="Where there is more to the expression after the RHS" duration="{duration}"/>
+    <testCase name="X/level/0/a" duration="{duration}"/>
+    <testCase name="X/level/0/b" duration="{duration}"/>
+    <testCase name="X/level/1/a" duration="{duration}"/>
+    <testCase name="X/level/1/b" duration="{duration}"/>
+    <testCase name="boolean member" duration="{duration}"/>
+    <testCase name="non streamable - with conv. op" duration="{duration}"/>
+    <testCase name="non-copyable objects" duration="{duration}"/>
+    <testCase name="null_ptr" duration="{duration}"/>
+    <testCase name="pointer to class" duration="{duration}"/>
+    <testCase name="string literals of different sizes can be compared" duration="{duration}">
+      <failure message="REQUIRE(std::string( &quot;first&quot; ) == &quot;second&quot;)">
+FAILED:
+	REQUIRE( std::string( "first" ) == "second" )
+with expansion:
+	"first" == "second"
+Tricky.tests.cpp:<line number>
+      </failure>
+    </testCase>
+  </file>
+  <file path="projects/<exe-name>/UsageTests/VariadicMacros.tests.cpp">
+    <testCase name="Anonymous test case 1" duration="{duration}"/>
+    <testCase name="Test case with one argument" duration="{duration}"/>
+    <testCase name="Variadic macros/Section with one argument" duration="{duration}"/>
+  </file>
+</testExecutions>
diff --git a/packages/Catch2/projects/SelfTest/Baselines/xml.sw.approved.txt b/packages/Catch2/projects/SelfTest/Baselines/xml.sw.approved.txt
index 6193dfb3c18174a1a5706eb50dc02597fdd37660..cf7413e33a0e8ae0817ac8127b3d34c724c501c8 100644
--- a/packages/Catch2/projects/SelfTest/Baselines/xml.sw.approved.txt
+++ b/packages/Catch2/projects/SelfTest/Baselines/xml.sw.approved.txt
@@ -5812,6 +5812,778 @@ Nor would this
         </Section>
         <OverallResults successes="10" failures="0" expectedFailures="0"/>
       </Section>
+      <Section name="Range" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+        <Section name="Positive manual step" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+          <Section name="Floating Point" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+            <Section name="Exact" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+              <Info>
+                Current expected value is -1
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.get() == Approx(expected)
+                </Original>
+                <Expanded>
+                  -1.0 == Approx( -1.0 )
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is -1
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.next()
+                </Original>
+                <Expanded>
+                  true
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is -0.9
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.get() == Approx(expected)
+                </Original>
+                <Expanded>
+                  -0.9 == Approx( -0.9 )
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is -0.9
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.next()
+                </Original>
+                <Expanded>
+                  true
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is -0.8
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.get() == Approx(expected)
+                </Original>
+                <Expanded>
+                  -0.8 == Approx( -0.8 )
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is -0.8
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.next()
+                </Original>
+                <Expanded>
+                  true
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is -0.7
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.get() == Approx(expected)
+                </Original>
+                <Expanded>
+                  -0.7 == Approx( -0.7 )
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is -0.7
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.next()
+                </Original>
+                <Expanded>
+                  true
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is -0.6
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.get() == Approx(expected)
+                </Original>
+                <Expanded>
+                  -0.6 == Approx( -0.6 )
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is -0.6
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.next()
+                </Original>
+                <Expanded>
+                  true
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is -0.5
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.get() == Approx(expected)
+                </Original>
+                <Expanded>
+                  -0.5 == Approx( -0.5 )
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is -0.5
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.next()
+                </Original>
+                <Expanded>
+                  true
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is -0.4
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.get() == Approx(expected)
+                </Original>
+                <Expanded>
+                  -0.4 == Approx( -0.4 )
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is -0.4
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.next()
+                </Original>
+                <Expanded>
+                  true
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is -0.3
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.get() == Approx(expected)
+                </Original>
+                <Expanded>
+                  -0.3 == Approx( -0.3 )
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is -0.3
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.next()
+                </Original>
+                <Expanded>
+                  true
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is -0.2
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.get() == Approx(expected)
+                </Original>
+                <Expanded>
+                  -0.2 == Approx( -0.2 )
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is -0.2
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.next()
+                </Original>
+                <Expanded>
+                  true
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is -0.1
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.get() == Approx(expected)
+                </Original>
+                <Expanded>
+                  -0.1 == Approx( -0.1 )
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is -0.1
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.next()
+                </Original>
+                <Expanded>
+                  true
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is -1.38778e-16
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.get() == Approx(expected)
+                </Original>
+                <Expanded>
+                  -0.0 == Approx( -0.0 )
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is -1.38778e-16
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.next()
+                </Original>
+                <Expanded>
+                  true
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is 0.1
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.get() == Approx(expected)
+                </Original>
+                <Expanded>
+                  0.1 == Approx( 0.1 )
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is 0.1
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.next()
+                </Original>
+                <Expanded>
+                  true
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is 0.2
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.get() == Approx(expected)
+                </Original>
+                <Expanded>
+                  0.2 == Approx( 0.2 )
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is 0.2
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.next()
+                </Original>
+                <Expanded>
+                  true
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is 0.3
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.get() == Approx(expected)
+                </Original>
+                <Expanded>
+                  0.3 == Approx( 0.3 )
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is 0.3
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.next()
+                </Original>
+                <Expanded>
+                  true
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is 0.4
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.get() == Approx(expected)
+                </Original>
+                <Expanded>
+                  0.4 == Approx( 0.4 )
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is 0.4
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.next()
+                </Original>
+                <Expanded>
+                  true
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is 0.5
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.get() == Approx(expected)
+                </Original>
+                <Expanded>
+                  0.5 == Approx( 0.5 )
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is 0.5
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.next()
+                </Original>
+                <Expanded>
+                  true
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is 0.6
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.get() == Approx(expected)
+                </Original>
+                <Expanded>
+                  0.6 == Approx( 0.6 )
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is 0.6
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.next()
+                </Original>
+                <Expanded>
+                  true
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is 0.7
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.get() == Approx(expected)
+                </Original>
+                <Expanded>
+                  0.7 == Approx( 0.7 )
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is 0.7
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.next()
+                </Original>
+                <Expanded>
+                  true
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is 0.8
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.get() == Approx(expected)
+                </Original>
+                <Expanded>
+                  0.8 == Approx( 0.8 )
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is 0.8
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.next()
+                </Original>
+                <Expanded>
+                  true
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is 0.9
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.get() == Approx(expected)
+                </Original>
+                <Expanded>
+                  0.9 == Approx( 0.9 )
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is 0.9
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.next()
+                </Original>
+                <Expanded>
+                  true
+                </Expanded>
+              </Expression>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.get() == Approx( rangeEnd )
+                </Original>
+                <Expanded>
+                  1.0 == Approx( 1.0 )
+                </Expanded>
+              </Expression>
+              <Expression success="true" type="REQUIRE_FALSE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  !(gen.next())
+                </Original>
+                <Expanded>
+                  !false
+                </Expanded>
+              </Expression>
+              <OverallResults successes="42" failures="0" expectedFailures="0"/>
+            </Section>
+            <OverallResults successes="42" failures="0" expectedFailures="0"/>
+          </Section>
+          <OverallResults successes="42" failures="0" expectedFailures="0"/>
+        </Section>
+        <OverallResults successes="42" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="Range" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+        <Section name="Positive manual step" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+          <Section name="Floating Point" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+            <Section name="Slightly over end" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+              <Info>
+                Current expected value is -1
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.get() == Approx(expected)
+                </Original>
+                <Expanded>
+                  -1.0 == Approx( -1.0 )
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is -1
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.next()
+                </Original>
+                <Expanded>
+                  true
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is -0.7
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.get() == Approx(expected)
+                </Original>
+                <Expanded>
+                  -0.7 == Approx( -0.7 )
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is -0.7
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.next()
+                </Original>
+                <Expanded>
+                  true
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is -0.4
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.get() == Approx(expected)
+                </Original>
+                <Expanded>
+                  -0.4 == Approx( -0.4 )
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is -0.4
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.next()
+                </Original>
+                <Expanded>
+                  true
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is -0.1
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.get() == Approx(expected)
+                </Original>
+                <Expanded>
+                  -0.1 == Approx( -0.1 )
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is -0.1
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.next()
+                </Original>
+                <Expanded>
+                  true
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is 0.2
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.get() == Approx(expected)
+                </Original>
+                <Expanded>
+                  0.2 == Approx( 0.2 )
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is 0.2
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.next()
+                </Original>
+                <Expanded>
+                  true
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is 0.5
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.get() == Approx(expected)
+                </Original>
+                <Expanded>
+                  0.5 == Approx( 0.5 )
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is 0.5
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.next()
+                </Original>
+                <Expanded>
+                  true
+                </Expanded>
+              </Expression>
+              <Expression success="true" type="REQUIRE_FALSE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  !(gen.next())
+                </Original>
+                <Expanded>
+                  !false
+                </Expanded>
+              </Expression>
+              <OverallResults successes="13" failures="0" expectedFailures="0"/>
+            </Section>
+            <OverallResults successes="13" failures="0" expectedFailures="0"/>
+          </Section>
+          <OverallResults successes="13" failures="0" expectedFailures="0"/>
+        </Section>
+        <OverallResults successes="13" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="Range" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+        <Section name="Positive manual step" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+          <Section name="Floating Point" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+            <Section name="Slightly under end" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+              <Info>
+                Current expected value is -1
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.get() == Approx(expected)
+                </Original>
+                <Expanded>
+                  -1.0 == Approx( -1.0 )
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is -1
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.next()
+                </Original>
+                <Expanded>
+                  true
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is -0.7
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.get() == Approx(expected)
+                </Original>
+                <Expanded>
+                  -0.7 == Approx( -0.7 )
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is -0.7
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.next()
+                </Original>
+                <Expanded>
+                  true
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is -0.4
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.get() == Approx(expected)
+                </Original>
+                <Expanded>
+                  -0.4 == Approx( -0.4 )
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is -0.4
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.next()
+                </Original>
+                <Expanded>
+                  true
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is -0.1
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.get() == Approx(expected)
+                </Original>
+                <Expanded>
+                  -0.1 == Approx( -0.1 )
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is -0.1
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.next()
+                </Original>
+                <Expanded>
+                  true
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is 0.2
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.get() == Approx(expected)
+                </Original>
+                <Expanded>
+                  0.2 == Approx( 0.2 )
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is 0.2
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.next()
+                </Original>
+                <Expanded>
+                  true
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is 0.5
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.get() == Approx(expected)
+                </Original>
+                <Expanded>
+                  0.5 == Approx( 0.5 )
+                </Expanded>
+              </Expression>
+              <Info>
+                Current expected value is 0.5
+              </Info>
+              <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  gen.next()
+                </Original>
+                <Expanded>
+                  true
+                </Expanded>
+              </Expression>
+              <Expression success="true" type="REQUIRE_FALSE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+                <Original>
+                  !(gen.next())
+                </Original>
+                <Expanded>
+                  !false
+                </Expanded>
+              </Expression>
+              <OverallResults successes="13" failures="0" expectedFailures="0"/>
+            </Section>
+            <OverallResults successes="13" failures="0" expectedFailures="0"/>
+          </Section>
+          <OverallResults successes="13" failures="0" expectedFailures="0"/>
+        </Section>
+        <OverallResults successes="13" failures="0" expectedFailures="0"/>
+      </Section>
       <Section name="Range" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
         <Section name="Negative manual step" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Section name="Integer" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
@@ -7247,7 +8019,7 @@ Nor would this
       </Section>
       <OverallResult success="false"/>
     </TestCase>
-    <TestCase name="Parse test names and tags" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
+    <TestCase name="Parse test names and tags" tags="[command-line][test-spec]" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
       <Section name="Empty test spec should have no filters" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
         <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
           <Original>
@@ -8507,6 +9279,60 @@ Nor would this
         </Expression>
         <OverallResults successes="5" failures="0" expectedFailures="0"/>
       </Section>
+      <Section name="Shortened hide tags are split apart when parsing" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
+          <Original>
+            spec.matches(fakeTestCase("hidden and foo", "[.][foo]"))
+          </Original>
+          <Expanded>
+            true
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="CHECK_FALSE" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
+          <Original>
+            !(spec.matches(fakeTestCase("only foo", "[foo]")))
+          </Original>
+          <Expanded>
+            !false
+          </Expanded>
+        </Expression>
+        <OverallResults successes="2" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="Shortened hide tags also properly handle exclusion" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
+        <Expression success="true" type="CHECK_FALSE" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
+          <Original>
+            !(spec.matches(fakeTestCase("hidden and foo", "[.][foo]")))
+          </Original>
+          <Expanded>
+            !false
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="CHECK_FALSE" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
+          <Original>
+            !(spec.matches(fakeTestCase("only foo", "[foo]")))
+          </Original>
+          <Expanded>
+            !false
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="CHECK_FALSE" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
+          <Original>
+            !(spec.matches(fakeTestCase("only hidden", "[.]")))
+          </Original>
+          <Expanded>
+            !false
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
+          <Original>
+            spec.matches(fakeTestCase("neither foo nor hidden", "[bar]"))
+          </Original>
+          <Expanded>
+            true
+          </Expanded>
+        </Expression>
+        <OverallResults successes="4" failures="0" expectedFailures="0"/>
+      </Section>
       <OverallResult success="true"/>
     </TestCase>
     <TestCase name="Pointers can be compared to null" filename="projects/<exe-name>/UsageTests/Condition.tests.cpp" >
@@ -9846,6 +10672,14 @@ Message from section two
             0 == 0
           </Expanded>
         </Expression>
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
+          <Original>
+            empty.isNullTerminated()
+          </Original>
+          <Expanded>
+            true
+          </Expanded>
+        </Expression>
         <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
           <Original>
             std::strcmp( empty.c_str(), "" ) == 0
@@ -9854,7 +10688,7 @@ Message from section two
             0 == 0
           </Expanded>
         </Expression>
-        <OverallResults successes="3" failures="0" expectedFailures="0"/>
+        <OverallResults successes="4" failures="0" expectedFailures="0"/>
       </Section>
       <Section name="From string literal" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
         <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
@@ -9875,10 +10709,10 @@ Message from section two
         </Expression>
         <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
           <Original>
-            isSubstring( s ) == false
+            s.isNullTerminated()
           </Original>
           <Expanded>
-            false == false
+            true
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
@@ -9889,33 +10723,30 @@ Message from section two
             0 == 0
           </Expanded>
         </Expression>
-        <Section name="c_str() does not cause copy" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
-          <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
-            <Original>
-              isOwned( s ) == false
-            </Original>
-            <Expanded>
-              false == false
-            </Expanded>
-          </Expression>
-          <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
-            <Original>
-              s.c_str() == rawChars
-            </Original>
-            <Expanded>
-              "hello" == "hello"
-            </Expanded>
-          </Expression>
-          <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
-            <Original>
-              isOwned( s ) == false
-            </Original>
-            <Expanded>
-              false == false
-            </Expanded>
-          </Expression>
-          <OverallResults successes="3" failures="0" expectedFailures="0"/>
-        </Section>
+        <Expression success="true" type="REQUIRE_NOTHROW" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
+          <Original>
+            s.c_str()
+          </Original>
+          <Expanded>
+            s.c_str()
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
+          <Original>
+            s.c_str() == rawChars
+          </Original>
+          <Expanded>
+            "hello" == "hello"
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
+          <Original>
+            s.data() == rawChars
+          </Original>
+          <Expanded>
+            "hello" == "hello"
+          </Expanded>
+        </Expression>
         <OverallResults successes="7" failures="0" expectedFailures="0"/>
       </Section>
       <Section name="From sub-string" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
@@ -9927,28 +10758,28 @@ Message from section two
             original == "original"
           </Expanded>
         </Expression>
-        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
+        <Expression success="true" type="REQUIRE_FALSE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
           <Original>
-            isSubstring( original )
+            !(original.isNullTerminated())
           </Original>
           <Expanded>
-            true
+            !false
           </Expanded>
         </Expression>
-        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
+        <Expression success="true" type="REQUIRE_THROWS" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
           <Original>
-            isOwned( original ) == false
+            original.c_str()
           </Original>
           <Expanded>
-            false == false
+            original.c_str()
           </Expanded>
         </Expression>
-        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
+        <Expression success="true" type="REQUIRE_NOTHROW" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
           <Original>
-            isOwned( original )
+            original.data()
           </Original>
           <Expanded>
-            true
+            original.data()
           </Expanded>
         </Expression>
         <OverallResults successes="4" failures="0" expectedFailures="0"/>
@@ -9973,7 +10804,7 @@ Message from section two
           </Expression>
           <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
             <Original>
-              std::strcmp( ss.c_str(), "hello" ) == 0
+              std::strncmp( ss.data(), "hello", 5 ) == 0
             </Original>
             <Expanded>
               0 == 0
@@ -9992,105 +10823,46 @@ Message from section two
         <OverallResults successes="4" failures="0" expectedFailures="0"/>
       </Section>
       <Section name="Substrings" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
-        <Section name="c_str() causes copy" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
-          <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
-            <Original>
-              isSubstring( ss )
-            </Original>
-            <Expanded>
-              true
-            </Expanded>
-          </Expression>
-          <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
-            <Original>
-              isOwned( ss ) == false
-            </Original>
-            <Expanded>
-              false == false
-            </Expanded>
-          </Expression>
-          <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
-            <Original>
-              rawChars == s.currentData()
-            </Original>
-            <Expanded>
-              "hello world!" == "hello world!"
-            </Expanded>
-          </Expression>
+        <Section name="non-zero-based substring" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
           <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
             <Original>
-              ss.c_str() != rawChars
+              ss.size() == 6
             </Original>
             <Expanded>
-              "hello" != "hello world!"
+              6 == 6
             </Expanded>
           </Expression>
           <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
             <Original>
-              isOwned( ss )
+              std::strcmp( ss.c_str(), "world!" ) == 0
             </Original>
             <Expanded>
-              true
+              0 == 0
             </Expanded>
           </Expression>
-          <Section name="Self-assignment after substring" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
-            <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
-              <Original>
-                isOwned(ss) == false
-              </Original>
-              <Expanded>
-                false == false
-              </Expanded>
-            </Expression>
-            <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
-              <Original>
-                ss == "hello"
-              </Original>
-              <Expanded>
-                hello == "hello"
-              </Expanded>
-            </Expression>
-            <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
-              <Original>
-                rawChars == ss.currentData()
-              </Original>
-              <Expanded>
-                "hello world!" == "hello world!"
-              </Expanded>
-            </Expression>
-            <OverallResults successes="3" failures="0" expectedFailures="0"/>
-          </Section>
-          <OverallResults successes="8" failures="0" expectedFailures="0"/>
+          <OverallResults successes="2" failures="0" expectedFailures="0"/>
         </Section>
-        <OverallResults successes="8" failures="0" expectedFailures="0"/>
+        <OverallResults successes="2" failures="0" expectedFailures="0"/>
       </Section>
       <Section name="Substrings" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
-        <Section name="non-zero-based substring" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
-          <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
-            <Original>
-              ss.size() == 6
-            </Original>
-            <Expanded>
-              6 == 6
-            </Expanded>
-          </Expression>
+        <Section name="Pointer values of full refs should match" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
           <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
             <Original>
-              std::strcmp( ss.c_str(), "world!" ) == 0
+              s.data() == s2.data()
             </Original>
             <Expanded>
-              0 == 0
+              "hello world!" == "hello world!"
             </Expanded>
           </Expression>
-          <OverallResults successes="2" failures="0" expectedFailures="0"/>
+          <OverallResults successes="1" failures="0" expectedFailures="0"/>
         </Section>
-        <OverallResults successes="2" failures="0" expectedFailures="0"/>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
       </Section>
       <Section name="Substrings" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
-        <Section name="Pointer values of full refs should match" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
+        <Section name="Pointer values of substring refs should also match" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
           <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
             <Original>
-              s.c_str() == s2.c_str()
+              s.data() == ss.data()
             </Original>
             <Expanded>
               "hello world!" == "hello world!"
@@ -10101,13 +10873,13 @@ Message from section two
         <OverallResults successes="1" failures="0" expectedFailures="0"/>
       </Section>
       <Section name="Substrings" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
-        <Section name="Pointer values of substring refs should not match" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
+        <Section name="Past the end substring" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
           <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
             <Original>
-              s.c_str() != ss.c_str()
+              s.substr(s.size() + 1, 123).empty()
             </Original>
             <Expanded>
-              "hello world!" != "hello"
+              true
             </Expanded>
           </Expression>
           <OverallResults successes="1" failures="0" expectedFailures="0"/>
@@ -10115,37 +10887,45 @@ Message from section two
         <OverallResults successes="1" failures="0" expectedFailures="0"/>
       </Section>
       <Section name="Substrings" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
-        <Section name="Past the end substring" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
+        <Section name="Substring off the end are trimmed" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
           <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
             <Original>
-              s.substr(s.size() + 1, 123).empty()
+              std::strcmp(ss.c_str(), "world!") == 0
             </Original>
             <Expanded>
-              true
+              0 == 0
             </Expanded>
           </Expression>
           <OverallResults successes="1" failures="0" expectedFailures="0"/>
         </Section>
         <OverallResults successes="1" failures="0" expectedFailures="0"/>
       </Section>
-      <Section name="Comparisons" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
+      <Section name="Comparisons are deep" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
+          <Original>
+            (char*)buffer1 != (char*)buffer2
+          </Original>
+          <Expanded>
+            "Hello" != "Hello"
+          </Expanded>
+        </Expression>
         <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
           <Original>
-            StringRef("hello") == StringRef("hello")
+            left == right
           </Original>
           <Expanded>
-            hello == hello
+            Hello == Hello
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
           <Original>
-            StringRef("hello") != StringRef("cello")
+            left != left.substr(0, 3)
           </Original>
           <Expanded>
-            hello != cello
+            Hello != Hel
           </Expanded>
         </Expression>
-        <OverallResults successes="2" failures="0" expectedFailures="0"/>
+        <OverallResults successes="3" failures="0" expectedFailures="0"/>
       </Section>
       <Section name="from std::string" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
         <Section name="implicitly constructed" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
@@ -10259,6 +11039,15 @@ Message from section two
       </Section>
       <OverallResult success="true"/>
     </TestCase>
+    <TestCase name="StringRef at compilation time" tags="[StringRef][Strings][constexpr]" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
+      <Section name="Simple constructors" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
+        <OverallResults successes="5" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="UDL construction" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
+        <OverallResults successes="6" failures="0" expectedFailures="0"/>
+      </Section>
+      <OverallResult success="true"/>
+    </TestCase>
     <TestCase name="Stringifying std::chrono::duration helpers" tags="[chrono][toString]" filename="projects/<exe-name>/UsageTests/ToStringChrono.tests.cpp" >
       <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/ToStringChrono.tests.cpp" >
         <Original>
@@ -13111,378 +13900,6 @@ There is no extra whitespace here
       </Section>
       <OverallResult success="true"/>
     </TestCase>
-    <TestCase name="XmlEncode: UTF-8" tags="[UTF-8][XML]" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-      <Section name="Valid utf-8 strings" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-          <Original>
-            encode(u8"Here be 👾") == u8"Here be 👾"
-          </Original>
-          <Expanded>
-            "Here be 👾" == "Here be 👾"
-          </Expanded>
-        </Expression>
-        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-          <Original>
-            encode(u8"šš") == u8"šš"
-          </Original>
-          <Expanded>
-            "šš" == "šš"
-          </Expanded>
-        </Expression>
-        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-          <Original>
-            encode("\xDF\xBF") == "\xDF\xBF"
-          </Original>
-          <Expanded>
-            "߿" == "߿"
-          </Expanded>
-        </Expression>
-        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-          <Original>
-            encode("\xE0\xA0\x80") == "\xE0\xA0\x80"
-          </Original>
-          <Expanded>
-            "ࠀ" == "ࠀ"
-          </Expanded>
-        </Expression>
-        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-          <Original>
-            encode("\xED\x9F\xBF") == "\xED\x9F\xBF"
-          </Original>
-          <Expanded>
-            "퟿" == "퟿"
-          </Expanded>
-        </Expression>
-        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-          <Original>
-            encode("\xEE\x80\x80") == "\xEE\x80\x80"
-          </Original>
-          <Expanded>
-            "" == ""
-          </Expanded>
-        </Expression>
-        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-          <Original>
-            encode("\xEF\xBF\xBF") == "\xEF\xBF\xBF"
-          </Original>
-          <Expanded>
-            "￿" == "￿"
-          </Expanded>
-        </Expression>
-        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-          <Original>
-            encode("\xF0\x90\x80\x80") == "\xF0\x90\x80\x80"
-          </Original>
-          <Expanded>
-            "𐀀" == "𐀀"
-          </Expanded>
-        </Expression>
-        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-          <Original>
-            encode("\xF4\x8F\xBF\xBF") == "\xF4\x8F\xBF\xBF"
-          </Original>
-          <Expanded>
-            "􏿿" == "􏿿"
-          </Expanded>
-        </Expression>
-        <OverallResults successes="9" failures="0" expectedFailures="0"/>
-      </Section>
-      <Section name="Invalid utf-8 strings" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-        <Section name="Various broken strings" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-          <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-            <Original>
-              encode("Here \xFF be 👾") == u8"Here \\xFF be 👾"
-            </Original>
-            <Expanded>
-              "Here \xFF be 👾" == "Here \xFF be 👾"
-            </Expanded>
-          </Expression>
-          <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-            <Original>
-              encode("\xFF") == "\\xFF"
-            </Original>
-            <Expanded>
-              "\xFF" == "\xFF"
-            </Expanded>
-          </Expression>
-          <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-            <Original>
-              encode("\xC5\xC5\xA0") == u8"\\xC5Š"
-            </Original>
-            <Expanded>
-              "\xC5Š" == "\xC5Š"
-            </Expanded>
-          </Expression>
-          <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-            <Original>
-              encode("\xF4\x90\x80\x80") == u8"\\xF4\\x90\\x80\\x80"
-            </Original>
-            <Expanded>
-              "\xF4\x90\x80\x80" == "\xF4\x90\x80\x80"
-            </Expanded>
-          </Expression>
-          <OverallResults successes="4" failures="0" expectedFailures="0"/>
-        </Section>
-        <OverallResults successes="4" failures="0" expectedFailures="0"/>
-      </Section>
-      <Section name="Invalid utf-8 strings" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-        <Section name="Overlong encodings" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-          <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-            <Original>
-              encode("\xC0\x80") == u8"\\xC0\\x80"
-            </Original>
-            <Expanded>
-              "\xC0\x80" == "\xC0\x80"
-            </Expanded>
-          </Expression>
-          <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-            <Original>
-              encode("\xF0\x80\x80\x80") == u8"\\xF0\\x80\\x80\\x80"
-            </Original>
-            <Expanded>
-              "\xF0\x80\x80\x80" == "\xF0\x80\x80\x80"
-            </Expanded>
-          </Expression>
-          <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-            <Original>
-              encode("\xC1\xBF") == u8"\\xC1\\xBF"
-            </Original>
-            <Expanded>
-              "\xC1\xBF" == "\xC1\xBF"
-            </Expanded>
-          </Expression>
-          <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-            <Original>
-              encode("\xE0\x9F\xBF") == u8"\\xE0\\x9F\\xBF"
-            </Original>
-            <Expanded>
-              "\xE0\x9F\xBF" == "\xE0\x9F\xBF"
-            </Expanded>
-          </Expression>
-          <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-            <Original>
-              encode("\xF0\x8F\xBF\xBF") == u8"\\xF0\\x8F\\xBF\\xBF"
-            </Original>
-            <Expanded>
-              "\xF0\x8F\xBF\xBF" == "\xF0\x8F\xBF\xBF"
-            </Expanded>
-          </Expression>
-          <OverallResults successes="5" failures="0" expectedFailures="0"/>
-        </Section>
-        <OverallResults successes="5" failures="0" expectedFailures="0"/>
-      </Section>
-      <Section name="Invalid utf-8 strings" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-        <Section name="Surrogate pairs" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-          <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-            <Original>
-              encode("\xED\xA0\x80") == "\xED\xA0\x80"
-            </Original>
-            <Expanded>
-              "���" == "���"
-            </Expanded>
-          </Expression>
-          <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-            <Original>
-              encode("\xED\xAF\xBF") == "\xED\xAF\xBF"
-            </Original>
-            <Expanded>
-              "���" == "���"
-            </Expanded>
-          </Expression>
-          <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-            <Original>
-              encode("\xED\xB0\x80") == "\xED\xB0\x80"
-            </Original>
-            <Expanded>
-              "���" == "���"
-            </Expanded>
-          </Expression>
-          <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-            <Original>
-              encode("\xED\xBF\xBF") == "\xED\xBF\xBF"
-            </Original>
-            <Expanded>
-              "���" == "���"
-            </Expanded>
-          </Expression>
-          <OverallResults successes="4" failures="0" expectedFailures="0"/>
-        </Section>
-        <OverallResults successes="4" failures="0" expectedFailures="0"/>
-      </Section>
-      <Section name="Invalid utf-8 strings" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-        <Section name="Invalid start byte" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-          <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-            <Original>
-              encode("\x80") == u8"\\x80"
-            </Original>
-            <Expanded>
-              "\x80" == "\x80"
-            </Expanded>
-          </Expression>
-          <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-            <Original>
-              encode("\x81") == u8"\\x81"
-            </Original>
-            <Expanded>
-              "\x81" == "\x81"
-            </Expanded>
-          </Expression>
-          <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-            <Original>
-              encode("\xBC") == u8"\\xBC"
-            </Original>
-            <Expanded>
-              "\xBC" == "\xBC"
-            </Expanded>
-          </Expression>
-          <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-            <Original>
-              encode("\xBF") == u8"\\xBF"
-            </Original>
-            <Expanded>
-              "\xBF" == "\xBF"
-            </Expanded>
-          </Expression>
-          <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-            <Original>
-              encode("\xF5\x80\x80\x80") == u8"\\xF5\\x80\\x80\\x80"
-            </Original>
-            <Expanded>
-              "\xF5\x80\x80\x80" == "\xF5\x80\x80\x80"
-            </Expanded>
-          </Expression>
-          <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-            <Original>
-              encode("\xF6\x80\x80\x80") == u8"\\xF6\\x80\\x80\\x80"
-            </Original>
-            <Expanded>
-              "\xF6\x80\x80\x80" == "\xF6\x80\x80\x80"
-            </Expanded>
-          </Expression>
-          <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-            <Original>
-              encode("\xF7\x80\x80\x80") == u8"\\xF7\\x80\\x80\\x80"
-            </Original>
-            <Expanded>
-              "\xF7\x80\x80\x80" == "\xF7\x80\x80\x80"
-            </Expanded>
-          </Expression>
-          <OverallResults successes="7" failures="0" expectedFailures="0"/>
-        </Section>
-        <OverallResults successes="7" failures="0" expectedFailures="0"/>
-      </Section>
-      <Section name="Invalid utf-8 strings" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-        <Section name="Missing continuation byte(s)" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-          <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-            <Original>
-              encode("\xDE") == u8"\\xDE"
-            </Original>
-            <Expanded>
-              "\xDE" == "\xDE"
-            </Expanded>
-          </Expression>
-          <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-            <Original>
-              encode("\xDF") == u8"\\xDF"
-            </Original>
-            <Expanded>
-              "\xDF" == "\xDF"
-            </Expanded>
-          </Expression>
-          <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-            <Original>
-              encode("\xE0") == u8"\\xE0"
-            </Original>
-            <Expanded>
-              "\xE0" == "\xE0"
-            </Expanded>
-          </Expression>
-          <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-            <Original>
-              encode("\xEF") == u8"\\xEF"
-            </Original>
-            <Expanded>
-              "\xEF" == "\xEF"
-            </Expanded>
-          </Expression>
-          <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-            <Original>
-              encode("\xF0") == u8"\\xF0"
-            </Original>
-            <Expanded>
-              "\xF0" == "\xF0"
-            </Expanded>
-          </Expression>
-          <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-            <Original>
-              encode("\xF4") == u8"\\xF4"
-            </Original>
-            <Expanded>
-              "\xF4" == "\xF4"
-            </Expanded>
-          </Expression>
-          <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-            <Original>
-              encode("\xE0\x80") == u8"\\xE0\\x80"
-            </Original>
-            <Expanded>
-              "\xE0\x80" == "\xE0\x80"
-            </Expanded>
-          </Expression>
-          <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-            <Original>
-              encode("\xE0\xBF") == u8"\\xE0\\xBF"
-            </Original>
-            <Expanded>
-              "\xE0\xBF" == "\xE0\xBF"
-            </Expanded>
-          </Expression>
-          <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-            <Original>
-              encode("\xE1\x80") == u8"\\xE1\\x80"
-            </Original>
-            <Expanded>
-              "\xE1\x80" == "\xE1\x80"
-            </Expanded>
-          </Expression>
-          <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-            <Original>
-              encode("\xF0\x80") == u8"\\xF0\\x80"
-            </Original>
-            <Expanded>
-              "\xF0\x80" == "\xF0\x80"
-            </Expanded>
-          </Expression>
-          <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-            <Original>
-              encode("\xF4\x80") == u8"\\xF4\\x80"
-            </Original>
-            <Expanded>
-              "\xF4\x80" == "\xF4\x80"
-            </Expanded>
-          </Expression>
-          <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-            <Original>
-              encode("\xF0\x80\x80") == u8"\\xF0\\x80\\x80"
-            </Original>
-            <Expanded>
-              "\xF0\x80\x80" == "\xF0\x80\x80"
-            </Expanded>
-          </Expression>
-          <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
-            <Original>
-              encode("\xF4\x80\x80") == u8"\\xF4\\x80\\x80"
-            </Original>
-            <Expanded>
-              "\xF4\x80\x80" == "\xF4\x80\x80"
-            </Expanded>
-          </Expression>
-          <OverallResults successes="13" failures="0" expectedFailures="0"/>
-        </Section>
-        <OverallResults successes="13" failures="0" expectedFailures="0"/>
-      </Section>
-      <OverallResult success="true"/>
-    </TestCase>
     <TestCase name="array&lt;int, N> -> toString" tags="[array][containers][toString]" filename="projects/<exe-name>/UsageTests/ToStringVector.tests.cpp" >
       <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/ToStringVector.tests.cpp" >
         <Original>
@@ -15427,7 +15844,7 @@ loose text artifact
       </Section>
       <OverallResult success="true"/>
     </TestCase>
-    <OverallResults successes="1469" failures="149" expectedFailures="21"/>
+    <OverallResults successes="1507" failures="149" expectedFailures="21"/>
   </Group>
-  <OverallResults successes="1469" failures="148" expectedFailures="21"/>
+  <OverallResults successes="1507" failures="148" expectedFailures="21"/>
 </Catch>
diff --git a/packages/Catch2/projects/SelfTest/IntrospectiveTests/CmdLine.tests.cpp b/packages/Catch2/projects/SelfTest/IntrospectiveTests/CmdLine.tests.cpp
index 60eb97af9ae8701c52d23bab0bac6a298cf07ec2..c1fd90e3a90aae0145667bca293aa79c4ccb38fc 100644
--- a/packages/Catch2/projects/SelfTest/IntrospectiveTests/CmdLine.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/IntrospectiveTests/CmdLine.tests.cpp
@@ -17,7 +17,7 @@
 
 inline Catch::TestCase fakeTestCase(const char* name, const char* desc = "") { return Catch::makeTestCase(nullptr, "", { name, desc }, CATCH_INTERNAL_LINEINFO); }
 
-TEST_CASE( "Parse test names and tags" ) {
+TEST_CASE( "Parse test names and tags", "[command-line][test-spec]" ) {
 
     using Catch::parseTestSpec;
     using Catch::TestSpec;
@@ -269,7 +269,6 @@ TEST_CASE( "Parse test names and tags" ) {
         CHECK( spec.matches( fakeTestCase( " aardvark " ) ) );
         CHECK( spec.matches( fakeTestCase( "aardvark " ) ) );
         CHECK( spec.matches( fakeTestCase( "aardvark" ) ) );
-
     }
     SECTION( "Leading and trailing spaces in test name" ) {
         TestSpec spec = parseTestSpec( "aardvark" );
@@ -278,7 +277,18 @@ TEST_CASE( "Parse test names and tags" ) {
         CHECK( spec.matches( fakeTestCase( " aardvark " ) ) );
         CHECK( spec.matches( fakeTestCase( "aardvark " ) ) );
         CHECK( spec.matches( fakeTestCase( "aardvark" ) ) );
-
+    }
+    SECTION("Shortened hide tags are split apart when parsing") {
+        TestSpec spec = parseTestSpec("[.foo]");
+        CHECK(spec.matches(fakeTestCase("hidden and foo", "[.][foo]")));
+        CHECK_FALSE(spec.matches(fakeTestCase("only foo", "[foo]")));
+    }
+    SECTION("Shortened hide tags also properly handle exclusion") {
+        TestSpec spec = parseTestSpec("~[.foo]");
+        CHECK_FALSE(spec.matches(fakeTestCase("hidden and foo", "[.][foo]")));
+        CHECK_FALSE(spec.matches(fakeTestCase("only foo", "[foo]")));
+        CHECK_FALSE(spec.matches(fakeTestCase("only hidden", "[.]")));
+        CHECK(spec.matches(fakeTestCase("neither foo nor hidden", "[bar]")));
     }
 }
 
@@ -486,7 +496,7 @@ TEST_CASE( "Process can be configured on command line", "[config][command-line]"
 
             REQUIRE(config.benchmarkSamples == 200);
         }
-        
+
         SECTION("resamples") {
             CHECK(cli.parse({ "test", "--benchmark-resamples=20000" }));
 
diff --git a/packages/Catch2/projects/SelfTest/IntrospectiveTests/GeneratorsImpl.tests.cpp b/packages/Catch2/projects/SelfTest/IntrospectiveTests/GeneratorsImpl.tests.cpp
index 076c91a9b1cd9be77938ad392e6c2326d9b5e891..9cbe89310f3c3378d2b84a2fc79d9ce45b4d155a 100644
--- a/packages/Catch2/projects/SelfTest/IntrospectiveTests/GeneratorsImpl.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/IntrospectiveTests/GeneratorsImpl.tests.cpp
@@ -173,6 +173,58 @@ TEST_CASE("Generators internals", "[generators][internals]") {
                     REQUIRE_FALSE(gen.next());
                 }
             }
+
+            SECTION("Floating Point") {
+                SECTION("Exact") {
+                    const auto rangeStart = -1.;
+                    const auto rangeEnd = 1.;
+                    const auto step = .1;
+
+                    auto gen = range(rangeStart, rangeEnd, step);
+                    auto expected = rangeStart; 
+                    while( (rangeEnd - expected) > step ) {
+                        INFO( "Current expected value is " << expected )
+                        REQUIRE(gen.get() == Approx(expected));
+                        REQUIRE(gen.next());
+
+                        expected += step;
+                    }
+                    REQUIRE(gen.get() == Approx( rangeEnd ) );
+                    REQUIRE_FALSE(gen.next());
+                }
+                SECTION("Slightly over end") {
+                    const auto rangeStart = -1.;
+                    const auto rangeEnd = 1.;
+                    const auto step = .3;
+
+                    auto gen = range(rangeStart, rangeEnd, step);
+                    auto expected = rangeStart; 
+                    while( (rangeEnd - expected) > step ) {
+                       INFO( "Current expected value is " << expected )
+                       REQUIRE(gen.get() == Approx(expected));
+                       REQUIRE(gen.next());
+
+                       expected += step;
+                    }
+                    REQUIRE_FALSE(gen.next());
+                }
+                SECTION("Slightly under end") {
+                    const auto rangeStart = -1.;
+                    const auto rangeEnd = .9;
+                    const auto step = .3;
+
+                    auto gen = range(rangeStart, rangeEnd, step);
+                    auto expected = rangeStart; 
+                    while( (rangeEnd - expected) > step ) {
+                       INFO( "Current expected value is " << expected )
+                       REQUIRE(gen.get() == Approx(expected));
+                       REQUIRE(gen.next());
+
+                       expected += step;
+                    }
+                    REQUIRE_FALSE(gen.next());
+                }                
+            }
         }
         SECTION("Negative manual step") {
             SECTION("Integer") {
diff --git a/packages/Catch2/projects/SelfTest/IntrospectiveTests/String.tests.cpp b/packages/Catch2/projects/SelfTest/IntrospectiveTests/String.tests.cpp
index 456dd4a7d17ec12d52591b3e979225e8d0aea9d1..3a3086576b892fa0de0ad12785fea3fabb497ee1 100644
--- a/packages/Catch2/projects/SelfTest/IntrospectiveTests/String.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/IntrospectiveTests/String.tests.cpp
@@ -4,39 +4,15 @@
 
 #include <cstring>
 
-namespace Catch {
-
-    // Implementation of test accessors
-    struct StringRefTestAccess {
-        static auto isOwned( StringRef const& stringRef ) -> bool {
-            return stringRef.isOwned();
-        }
-        static auto isSubstring( StringRef const& stringRef ) -> bool {
-            return stringRef.isSubstring();
-        }
-    };
-
-
-    namespace {
-    auto isOwned( StringRef const& stringRef ) -> bool {
-        return StringRefTestAccess::isOwned( stringRef );
-    }
-    auto isSubstring( StringRef const& stringRef ) -> bool {
-        return StringRefTestAccess::isSubstring( stringRef );
-    }
-    } // end anonymous namespace
-
-} // namespace Catch
-
 TEST_CASE( "StringRef", "[Strings][StringRef]" ) {
 
     using Catch::StringRef;
-    using Catch::isOwned; using Catch::isSubstring;
 
     SECTION( "Empty string" ) {
         StringRef empty;
         REQUIRE( empty.empty() );
         REQUIRE( empty.size() == 0 );
+        REQUIRE( empty.isNullTerminated() );
         REQUIRE( std::strcmp( empty.c_str(), "" ) == 0 );
     }
 
@@ -44,28 +20,22 @@ TEST_CASE( "StringRef", "[Strings][StringRef]" ) {
         StringRef s = "hello";
         REQUIRE( s.empty() == false );
         REQUIRE( s.size() == 5 );
-        REQUIRE( isSubstring( s ) == false );
+        REQUIRE( s.isNullTerminated() );
 
-        auto rawChars = s.currentData();
+        auto rawChars = s.data();
         REQUIRE( std::strcmp( rawChars, "hello" ) == 0 );
 
-        SECTION( "c_str() does not cause copy" ) {
-            REQUIRE( isOwned( s ) == false );
-
-            REQUIRE( s.c_str() == rawChars );
-
-            REQUIRE( isOwned( s ) == false );
-        }
+        REQUIRE_NOTHROW(s.c_str());
+        REQUIRE(s.c_str() == rawChars);
+        REQUIRE(s.data() == rawChars);
     }
     SECTION( "From sub-string" ) {
         StringRef original = StringRef( "original string" ).substr(0, 8);
         REQUIRE( original == "original" );
-        REQUIRE( isSubstring( original ) );
-        REQUIRE( isOwned( original ) == false );
 
-        original.c_str(); // Forces it to take ownership
-
-        REQUIRE( isOwned( original ) );
+        REQUIRE_FALSE(original.isNullTerminated());
+        REQUIRE_THROWS(original.c_str());
+        REQUIRE_NOTHROW(original.data());
     }
 
 
@@ -76,26 +46,9 @@ TEST_CASE( "StringRef", "[Strings][StringRef]" ) {
         SECTION( "zero-based substring" ) {
             REQUIRE( ss.empty() == false );
             REQUIRE( ss.size() == 5 );
-            REQUIRE( std::strcmp( ss.c_str(), "hello" ) == 0 );
+            REQUIRE( std::strncmp( ss.data(), "hello", 5 ) == 0 );
             REQUIRE( ss == "hello" );
         }
-        SECTION( "c_str() causes copy" ) {
-            REQUIRE( isSubstring( ss ) );
-            REQUIRE( isOwned( ss ) == false );
-
-            auto rawChars = ss.currentData();
-            REQUIRE( rawChars == s.currentData() ); // same pointer value
-            REQUIRE( ss.c_str() != rawChars );
-
-            REQUIRE( isOwned( ss ) );
-
-            SECTION( "Self-assignment after substring" ) {
-                ss = *&ss; // the *& are there to suppress warnings (see: "Improvements to Clang's diagnostics" in https://rev.ng/gitlab/revng-bar-2019/clang/raw/master/docs/ReleaseNotes.rst)
-                REQUIRE( isOwned(ss) == false );
-                REQUIRE( ss == "hello" );
-                REQUIRE( rawChars == ss.currentData() ); // same pointer value
-            }
-        }
 
         SECTION( "non-zero-based substring") {
             ss = s.substr( 6, 6 );
@@ -105,21 +58,32 @@ TEST_CASE( "StringRef", "[Strings][StringRef]" ) {
 
         SECTION( "Pointer values of full refs should match" ) {
             StringRef s2 = s;
-            REQUIRE( s.c_str() == s2.c_str() );
+            REQUIRE( s.data() == s2.data() );
         }
 
-        SECTION( "Pointer values of substring refs should not match" ) {
-            REQUIRE( s.c_str() != ss.c_str() );
+        SECTION( "Pointer values of substring refs should also match" ) {
+            REQUIRE( s.data() == ss.data() );
         }
 
         SECTION("Past the end substring") {
             REQUIRE(s.substr(s.size() + 1, 123).empty());
         }
+
+        SECTION("Substring off the end are trimmed") {
+            ss = s.substr(6, 123);
+            REQUIRE(std::strcmp(ss.c_str(), "world!") == 0);
+        }
+        // TODO: substring into string + size is longer than end
     }
 
-    SECTION( "Comparisons" ) {
-        REQUIRE( StringRef("hello") == StringRef("hello") );
-        REQUIRE( StringRef("hello") != StringRef("cello") );
+    SECTION( "Comparisons are deep" ) {
+        char buffer1[] = "Hello";
+        char buffer2[] = "Hello";
+        CHECK((char*)buffer1 != (char*)buffer2);
+
+        StringRef left(buffer1), right(buffer2);
+        REQUIRE( left == right );
+        REQUIRE(left != left.substr(0, 3));
     }
 
     SECTION( "from std::string" ) {
@@ -159,3 +123,28 @@ TEST_CASE( "StringRef", "[Strings][StringRef]" ) {
         }
     }
 }
+
+TEST_CASE("StringRef at compilation time", "[Strings][StringRef][constexpr]") {
+    using Catch::StringRef;
+    SECTION("Simple constructors") {
+        STATIC_REQUIRE(StringRef{}.size() == 0);
+
+        STATIC_REQUIRE(StringRef{ "abc", 3 }.size() == 3);
+        STATIC_REQUIRE(StringRef{ "abc", 3 }.isNullTerminated());
+
+        STATIC_REQUIRE(StringRef{ "abc", 2 }.size() == 2);
+        STATIC_REQUIRE_FALSE(StringRef{ "abc", 2 }.isNullTerminated());
+    }
+    SECTION("UDL construction") {
+        constexpr auto sr1 = "abc"_catch_sr;
+        STATIC_REQUIRE_FALSE(sr1.empty());
+        STATIC_REQUIRE(sr1.size() == 3);
+        STATIC_REQUIRE(sr1.isNullTerminated());
+
+        using Catch::operator"" _sr;
+        constexpr auto sr2 = ""_sr;
+        STATIC_REQUIRE(sr2.empty());
+        STATIC_REQUIRE(sr2.size() == 0);
+        STATIC_REQUIRE(sr2.isNullTerminated());
+    }
+}
diff --git a/packages/Catch2/projects/SelfTest/IntrospectiveTests/Xml.tests.cpp b/packages/Catch2/projects/SelfTest/IntrospectiveTests/Xml.tests.cpp
index c3886ab282c5d8d31881eab2cbf16a74b77cf5d6..bf6c86028213aeea47c2651579d6e5da5df1bcb5 100644
--- a/packages/Catch2/projects/SelfTest/IntrospectiveTests/Xml.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/IntrospectiveTests/Xml.tests.cpp
@@ -40,10 +40,11 @@ TEST_CASE( "XmlEncode", "[XML]" ) {
 }
 
 // Thanks to Peter Bindels (dascandy) for some of the tests
-TEST_CASE("XmlEncode: UTF-8", "[XML][UTF-8]") {
+TEST_CASE("XmlEncode: UTF-8", "[XML][UTF-8][approvals]") {
+#define ESC(lit) (char*)(lit)
     SECTION("Valid utf-8 strings") {
-        CHECK(encode(u8"Here be 👾") == u8"Here be 👾");
-        CHECK(encode(u8"šš") == u8"šš");
+        CHECK(encode(ESC(u8"Here be 👾")) == ESC(u8"Here be 👾"));
+        CHECK(encode(ESC(u8"šš")) == ESC(u8"šš"));
 
         CHECK(encode("\xDF\xBF")         == "\xDF\xBF"); // 0x7FF
         CHECK(encode("\xE0\xA0\x80")     == "\xE0\xA0\x80"); // 0x800
@@ -55,18 +56,18 @@ TEST_CASE("XmlEncode: UTF-8", "[XML][UTF-8]") {
     }
     SECTION("Invalid utf-8 strings") {
         SECTION("Various broken strings") {
-            CHECK(encode("Here \xFF be 👾") == u8"Here \\xFF be 👾");
+            CHECK(encode(ESC("Here \xFF be \xF0\x9F\x91\xBE")) == ESC(u8"Here \\xFF be 👾"));
             CHECK(encode("\xFF") == "\\xFF");
-            CHECK(encode("\xC5\xC5\xA0") == u8"\\xC5Š");
-            CHECK(encode("\xF4\x90\x80\x80") == u8"\\xF4\\x90\\x80\\x80"); // 0x110000 -- out of unicode range
+            CHECK(encode("\xC5\xC5\xA0") == ESC(u8"\\xC5Š"));
+            CHECK(encode("\xF4\x90\x80\x80") == ESC(u8"\\xF4\\x90\\x80\\x80")); // 0x110000 -- out of unicode range
         }
 
         SECTION("Overlong encodings") {
-            CHECK(encode("\xC0\x80") == u8"\\xC0\\x80"); // \0
-            CHECK(encode("\xF0\x80\x80\x80") == u8"\\xF0\\x80\\x80\\x80"); // Super-over-long \0
-            CHECK(encode("\xC1\xBF") == u8"\\xC1\\xBF"); // ASCII char as UTF-8 (0x7F)
-            CHECK(encode("\xE0\x9F\xBF") == u8"\\xE0\\x9F\\xBF"); // 0x7FF
-            CHECK(encode("\xF0\x8F\xBF\xBF") == u8"\\xF0\\x8F\\xBF\\xBF"); // 0xFFFF
+            CHECK(encode("\xC0\x80") == "\\xC0\\x80"); // \0
+            CHECK(encode("\xF0\x80\x80\x80") == "\\xF0\\x80\\x80\\x80"); // Super-over-long \0
+            CHECK(encode("\xC1\xBF") == "\\xC1\\xBF"); // ASCII char as UTF-8 (0x7F)
+            CHECK(encode("\xE0\x9F\xBF") == "\\xE0\\x9F\\xBF"); // 0x7FF
+            CHECK(encode("\xF0\x8F\xBF\xBF") == "\\xF0\\x8F\\xBF\\xBF"); // 0xFFFF
         }
 
         // Note that we actually don't modify surrogate pairs, as we do not do strict checking
@@ -78,35 +79,36 @@ TEST_CASE("XmlEncode: UTF-8", "[XML][UTF-8]") {
         }
 
         SECTION("Invalid start byte") {
-            CHECK(encode("\x80") == u8"\\x80");
-            CHECK(encode("\x81") == u8"\\x81");
-            CHECK(encode("\xBC") == u8"\\xBC");
-            CHECK(encode("\xBF") == u8"\\xBF");
+            CHECK(encode("\x80") == "\\x80");
+            CHECK(encode("\x81") == "\\x81");
+            CHECK(encode("\xBC") == "\\xBC");
+            CHECK(encode("\xBF") == "\\xBF");
             // Out of range
-            CHECK(encode("\xF5\x80\x80\x80") == u8"\\xF5\\x80\\x80\\x80");
-            CHECK(encode("\xF6\x80\x80\x80") == u8"\\xF6\\x80\\x80\\x80");
-            CHECK(encode("\xF7\x80\x80\x80") == u8"\\xF7\\x80\\x80\\x80");
+            CHECK(encode("\xF5\x80\x80\x80") == "\\xF5\\x80\\x80\\x80");
+            CHECK(encode("\xF6\x80\x80\x80") == "\\xF6\\x80\\x80\\x80");
+            CHECK(encode("\xF7\x80\x80\x80") == "\\xF7\\x80\\x80\\x80");
         }
 
         SECTION("Missing continuation byte(s)") {
             // Missing first continuation byte
-            CHECK(encode("\xDE") == u8"\\xDE");
-            CHECK(encode("\xDF") == u8"\\xDF");
-            CHECK(encode("\xE0") == u8"\\xE0");
-            CHECK(encode("\xEF") == u8"\\xEF");
-            CHECK(encode("\xF0") == u8"\\xF0");
-            CHECK(encode("\xF4") == u8"\\xF4");
+            CHECK(encode("\xDE") == "\\xDE");
+            CHECK(encode("\xDF") == "\\xDF");
+            CHECK(encode("\xE0") == "\\xE0");
+            CHECK(encode("\xEF") == "\\xEF");
+            CHECK(encode("\xF0") == "\\xF0");
+            CHECK(encode("\xF4") == "\\xF4");
 
             // Missing second continuation byte
-            CHECK(encode("\xE0\x80") == u8"\\xE0\\x80");
-            CHECK(encode("\xE0\xBF") == u8"\\xE0\\xBF");
-            CHECK(encode("\xE1\x80") == u8"\\xE1\\x80");
-            CHECK(encode("\xF0\x80") == u8"\\xF0\\x80");
-            CHECK(encode("\xF4\x80") == u8"\\xF4\\x80");
+            CHECK(encode("\xE0\x80") == "\\xE0\\x80");
+            CHECK(encode("\xE0\xBF") == "\\xE0\\xBF");
+            CHECK(encode("\xE1\x80") == "\\xE1\\x80");
+            CHECK(encode("\xF0\x80") == "\\xF0\\x80");
+            CHECK(encode("\xF4\x80") == "\\xF4\\x80");
 
             // Missing third continuation byte
-            CHECK(encode("\xF0\x80\x80") == u8"\\xF0\\x80\\x80");
-            CHECK(encode("\xF4\x80\x80") == u8"\\xF4\\x80\\x80");
+            CHECK(encode("\xF0\x80\x80") == "\\xF0\\x80\\x80");
+            CHECK(encode("\xF4\x80\x80") == "\\xF4\\x80\\x80");
         }
     }
+#undef ESC
 }
diff --git a/packages/Catch2/projects/SelfTest/TestMain.cpp b/packages/Catch2/projects/SelfTest/TestMain.cpp
index 1c023ce91f80f9871132dccf259dcac6c35dacfa..a16f0c22bdf0581ee50b49b205b28bc2880f7732 100644
--- a/packages/Catch2/projects/SelfTest/TestMain.cpp
+++ b/packages/Catch2/projects/SelfTest/TestMain.cpp
@@ -13,6 +13,7 @@
 #include "reporters/catch_reporter_teamcity.hpp"
 #include "reporters/catch_reporter_tap.hpp"
 #include "reporters/catch_reporter_automake.hpp"
+#include "reporters/catch_reporter_sonarqube.hpp"
 
 
 // Some example tag aliases
diff --git a/packages/Catch2/projects/SelfTest/UsageTests/Misc.tests.cpp b/packages/Catch2/projects/SelfTest/UsageTests/Misc.tests.cpp
index 188bc2d7c7c7ab3d12e9c6df53530be0b97b8a99..808d1d0af13c2e52070d92ee628cd75fa9237c9b 100644
--- a/packages/Catch2/projects/SelfTest/UsageTests/Misc.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/UsageTests/Misc.tests.cpp
@@ -58,9 +58,11 @@ struct AutoTestReg {
         REGISTER_TEST_CASE( manuallyRegisteredTestFunction, "ManuallyRegistered" );
     }
 };
+
+CATCH_INTERNAL_START_WARNINGS_SUPPRESSION
 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
 static AutoTestReg autoTestReg;
-CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
+CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
 
 template<typename T>
 struct Foo {
diff --git a/packages/Catch2/projects/SelfTest/UsageTests/ToStringVariant.tests.cpp b/packages/Catch2/projects/SelfTest/UsageTests/ToStringVariant.tests.cpp
index 60b3f903a7c3fbdeba5cc4ef262b1c8c30e09adc..c6809c0fe10696935d4bc47db4d414cf06bc03ca 100644
--- a/packages/Catch2/projects/SelfTest/UsageTests/ToStringVariant.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/UsageTests/ToStringVariant.tests.cpp
@@ -9,12 +9,12 @@
 // We need 2 types with non-trivial copies/moves
 struct MyType1 {
     MyType1() = default;
-    MyType1(MyType1 const&) { throw 1; }
+    [[noreturn]] MyType1(MyType1 const&) { throw 1; }
     MyType1& operator=(MyType1 const&) { throw 3; }
 };
 struct MyType2 {
     MyType2() = default;
-    MyType2(MyType2 const&) { throw 2; }
+    [[noreturn]] MyType2(MyType2 const&) { throw 2; }
     MyType2& operator=(MyType2 const&) { throw 4; }
 };
 
diff --git a/packages/Catch2/projects/SelfTest/UsageTests/Tricky.tests.cpp b/packages/Catch2/projects/SelfTest/UsageTests/Tricky.tests.cpp
index d8e5465bb0b032e9dfdac435440f46d7ca5f7074..55fe6230a961721ea7df1519e898502e852bad1c 100644
--- a/packages/Catch2/projects/SelfTest/UsageTests/Tricky.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/UsageTests/Tricky.tests.cpp
@@ -390,12 +390,6 @@ TEST_CASE("Commas in various macros are allowed") {
     }
 }
 
-TEST_CASE( "null deref", "[.][failing][!nonportable]" ) {
-    CHECK( false );
-    int *x = NULL;
-    *x = 1;
-}
-
 TEST_CASE( "non-copyable objects", "[.][failing]" ) {
     // Thanks to Agustin Bergé (@k-ballo on the cpplang Slack) for raising this
     std::type_info const& ti = typeid(int);
diff --git a/packages/Catch2/scripts/approvalTests.py b/packages/Catch2/scripts/approvalTests.py
index bb01e6d57063a8e0f04a668d2799d8ea32f8ab25..dad2a96b7f7d6dce75a49be55936c537d2b3465b 100755
--- a/packages/Catch2/scripts/approvalTests.py
+++ b/packages/Catch2/scripts/approvalTests.py
@@ -29,6 +29,7 @@ filelocParser = re.compile(r'''
 lineNumberParser = re.compile(r' line="[0-9]*"')
 hexParser = re.compile(r'\b(0[xX][0-9a-fA-F]+)\b')
 durationsParser = re.compile(r' time="[0-9]*\.[0-9]*"')
+sonarqubeDurationParser = re.compile(r' duration="[0-9]+"')
 timestampsParser = re.compile(r'\d{4}-\d{2}-\d{2}T\d{2}\:\d{2}\:\d{2}Z')
 versionParser = re.compile(r'Catch v[0-9]+\.[0-9]+\.[0-9]+(-develop\.[0-9]+)?')
 nullParser = re.compile(r'\b(__null|nullptr)\b')
@@ -138,6 +139,7 @@ def filterLine(line, isCompact):
 
     # strip durations and timestamps
     line = durationsParser.sub(' time="{duration}"', line)
+    line = sonarqubeDurationParser.sub(' duration="{duration}"', line)
     line = timestampsParser.sub('{iso8601-timestamp}', line)
     line = specialCaseParser.sub('file:\g<1>', line)
     line = errnoParser.sub('errno', line)
@@ -204,6 +206,8 @@ approve("junit.sw", ["~[!nonportable]~[!benchmark]~[approvals]", "-s", "-w", "No
 approve("xml.sw", ["~[!nonportable]~[!benchmark]~[approvals]", "-s", "-w", "NoAssertions", "-r", "xml", "--order", "lex", "--rng-seed", "1"])
 # compact reporter, include passes, warn about No Assertions
 approve('compact.sw', ['~[!nonportable]~[!benchmark]~[approvals]', '-s', '-w', 'NoAssertions', '-r', 'compact', '--order', 'lex', "--rng-seed", "1"])
+# sonarqube reporter, include passes, warn about No Assertions
+approve("sonarqube.sw", ["~[!nonportable]~[!benchmark]~[approvals]", "-s", "-w", "NoAssertions", "-r", "sonarqube", "--order", "lex", "--rng-seed", "1"])
 
 if overallResult != 0:
     print("If these differences are expected, run approve.py to approve new baselines.")
diff --git a/packages/Catch2/scripts/releaseCommon.py b/packages/Catch2/scripts/releaseCommon.py
index 102fe46a09fa12c55a76743c9a5a89e2d0046df3..283337d4090e741474b8ea8994063122aa31eda3 100644
--- a/packages/Catch2/scripts/releaseCommon.py
+++ b/packages/Catch2/scripts/releaseCommon.py
@@ -156,7 +156,7 @@ def performUpdates(version):
     # We probably should have some kind of convention to select which reporters need to be copied automagically,
     # but this works for now
     import shutil
-    for rep in ('automake', 'tap', 'teamcity'):
+    for rep in ('automake', 'tap', 'teamcity', 'sonarqube'):
         sourceFile = os.path.join(catchPath, 'include/reporters/catch_reporter_{}.hpp'.format(rep))
         destFile = os.path.join(catchPath, 'single_include', 'catch2', 'catch_reporter_{}.hpp'.format(rep))
         shutil.copyfile(sourceFile, destFile)
diff --git a/packages/Catch2/scripts/updateWandbox.py b/packages/Catch2/scripts/updateWandbox.py
index 564f94890db0e199a9c12dd4b4234772cb2f92a2..b448713dc590e9b5169116a68a9d62381eff80f5 100644
--- a/packages/Catch2/scripts/updateWandbox.py
+++ b/packages/Catch2/scripts/updateWandbox.py
@@ -41,7 +41,7 @@ def uploadFiles():
         'save': True
     })
 
-    if 'status' in response and 'compiler_error' not in response:
+    if 'url' in response and 'compiler_error' not in response:
         return True, response['url']
     else:
         return False, response
diff --git a/packages/Catch2/single_include/catch2/catch.hpp b/packages/Catch2/single_include/catch2/catch.hpp
index 391db530f212c8dc411722b2e0075cb011a0c38d..1b9b06e17dd176bff69994fd942cb884789cf889 100644
--- a/packages/Catch2/single_include/catch2/catch.hpp
+++ b/packages/Catch2/single_include/catch2/catch.hpp
@@ -1,6 +1,6 @@
 /*
- *  Catch v2.10.0
- *  Generated: 2019-10-13 22:24:46.755734
+ *  Catch v2.10.2
+ *  Generated: 2019-10-24 17:49:11.459934
  *  ----------------------------------------------------------
  *  This file has been merged from multiple headers. Please don't edit it directly
  *  Copyright (c) 2019 Two Blue Cubes Ltd. All rights reserved.
@@ -15,7 +15,7 @@
 
 #define CATCH_VERSION_MAJOR 2
 #define CATCH_VERSION_MINOR 10
-#define CATCH_VERSION_PATCH 0
+#define CATCH_VERSION_PATCH 2
 
 #ifdef __clang__
 #    pragma clang system_header
@@ -163,6 +163,11 @@ namespace Catch {
 #       define CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS \
             _Pragma( "clang diagnostic pop" )
 
+#       define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
+            _Pragma( "clang diagnostic push" ) \
+            _Pragma( "clang diagnostic ignored \"-Wunused-template\"" )
+#       define CATCH_INTERNAL_UNSUPPRESS_UNUSED_TEMPLATE_WARNINGS \
+            _Pragma( "clang diagnostic pop" )
 #endif // __clang__
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -409,6 +414,19 @@ namespace Catch {
 #   define CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS
 #endif
 
+#if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10)
+#   undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
+#   undef CATCH_INTERNAL_UNSUPPRESS_UNUSED_TEMPLATE_WARNINGS
+#elif defined(__clang__) && (__clang_major__ < 5)
+#   undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
+#   undef CATCH_INTERNAL_UNSUPPRESS_UNUSED_TEMPLATE_WARNINGS
+#endif
+
+#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS)
+#   define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
+#   define CATCH_INTERNAL_UNSUPPRESS_UNUSED_TEMPLATE_WARNINGS
+#endif
+
 #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
 #define CATCH_TRY if ((true))
 #define CATCH_CATCH_ALL if ((false))
@@ -775,35 +793,49 @@ inline auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noex
     template<typename...> struct TypeList {};\
     template<typename...Ts>\
     constexpr auto get_wrapper() noexcept -> TypeList<Ts...> { return {}; }\
+    template<template<typename...> class...> struct TemplateTypeList{};\
+    template<template<typename...> class...Cs>\
+    constexpr auto get_wrapper() noexcept -> TemplateTypeList<Cs...> { return {}; }\
+    template<typename...>\
+    struct append;\
+    template<typename...>\
+    struct rewrap;\
+    template<template<typename...> class, typename...>\
+    struct create;\
+    template<template<typename...> class, typename>\
+    struct convert;\
     \
-    template<template<typename...> class L1, typename...E1, template<typename...> class L2, typename...E2> \
-    constexpr auto append(L1<E1...>, L2<E2...>) noexcept -> L1<E1...,E2...> { return {}; }\
+    template<typename T> \
+    struct append<T> { using type = T; };\
     template< template<typename...> class L1, typename...E1, template<typename...> class L2, typename...E2, typename...Rest>\
-    constexpr auto append(L1<E1...>, L2<E2...>, Rest...) noexcept -> decltype(append(L1<E1...,E2...>{}, Rest{}...)) { return {}; }\
+    struct append<L1<E1...>, L2<E2...>, Rest...> { using type = typename append<L1<E1...,E2...>, Rest...>::type; };\
     template< template<typename...> class L1, typename...E1, typename...Rest>\
-    constexpr auto append(L1<E1...>, TypeList<mpl_::na>, Rest...) noexcept -> L1<E1...> { return {}; }\
+    struct append<L1<E1...>, TypeList<mpl_::na>, Rest...> { using type = L1<E1...>; };\
     \
     template< template<typename...> class Container, template<typename...> class List, typename...elems>\
-    constexpr auto rewrap(List<elems...>) noexcept -> TypeList<Container<elems...>> { return {}; }\
+    struct rewrap<TemplateTypeList<Container>, List<elems...>> { using type = TypeList<Container<elems...>>; };\
     template< template<typename...> class Container, template<typename...> class List, class...Elems, typename...Elements>\
-    constexpr auto rewrap(List<Elems...>,Elements...) noexcept -> decltype(append(TypeList<Container<Elems...>>{}, rewrap<Container>(Elements{}...))) { return {}; }\
+    struct rewrap<TemplateTypeList<Container>, List<Elems...>, Elements...> { using type = typename append<TypeList<Container<Elems...>>, typename rewrap<TemplateTypeList<Container>, Elements...>::type>::type; };\
     \
     template<template <typename...> class Final, template< typename...> class...Containers, typename...Types>\
-    constexpr auto create(TypeList<Types...>) noexcept -> decltype(append(Final<>{}, rewrap<Containers>(Types{}...)...)) { return {}; }\
+    struct create<Final, TemplateTypeList<Containers...>, TypeList<Types...>> { using type = typename append<Final<>, typename rewrap<TemplateTypeList<Containers>, Types...>::type...>::type; };\
     template<template <typename...> class Final, template <typename...> class List, typename...Ts>\
-    constexpr auto convert(const List<Ts...>& ) noexcept -> decltype(append(Final<>{},TypeList<Ts>{}...)) { return {}; }
+    struct convert<Final, List<Ts...>> { using type = typename append<Final<>,TypeList<Ts>...>::type; };
 
 #define INTERNAL_CATCH_NTTP_1(signature, ...)\
     template<INTERNAL_CATCH_REMOVE_PARENS(signature)> struct Nttp{};\
     template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
     constexpr auto get_wrapper() noexcept -> Nttp<__VA_ARGS__> { return {}; } \
+    template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...> struct NttpTemplateTypeList{};\
+    template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...Cs>\
+    constexpr auto get_wrapper() noexcept -> NttpTemplateTypeList<Cs...> { return {}; } \
     \
     template< template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature)>\
-    constexpr auto rewrap(List<__VA_ARGS__>) noexcept -> TypeList<Container<__VA_ARGS__>> { return {}; }\
+    struct rewrap<NttpTemplateTypeList<Container>, List<__VA_ARGS__>> { using type = TypeList<Container<__VA_ARGS__>>; };\
     template< template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature), typename...Elements>\
-    constexpr auto rewrap(List<__VA_ARGS__>,Elements...elems) noexcept -> decltype(append(TypeList<Container<__VA_ARGS__>>{}, rewrap<Container>(elems...))) { return {}; }\
+    struct rewrap<NttpTemplateTypeList<Container>, List<__VA_ARGS__>, Elements...> { using type = typename append<TypeList<Container<__VA_ARGS__>>, typename rewrap<NttpTemplateTypeList<Container>, Elements...>::type>::type; };\
     template<template <typename...> class Final, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...Containers, typename...Types>\
-    constexpr auto create(TypeList<Types...>) noexcept -> decltype(append(Final<>{}, rewrap<Containers>(Types{}...)...)) { return {}; }
+    struct create<Final, NttpTemplateTypeList<Containers...>, TypeList<Types...>> { using type = typename append<Final<>, typename rewrap<NttpTemplateTypeList<Containers>, Types...>::type...>::type; };
 
 #define INTERNAL_CATCH_DECLARE_SIG_TEST0(TestName)
 #define INTERNAL_CATCH_DECLARE_SIG_TEST1(TestName, signature)\
@@ -1050,6 +1082,7 @@ struct AutoReg : NonCopyable {
     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_2(TestName, TestFunc, Name, Tags, Signature, ... )\
         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
         CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
+        CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
         INTERNAL_CATCH_DECLARE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
         namespace {\
         namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\
@@ -1073,6 +1106,7 @@ struct AutoReg : NonCopyable {
         }\
         CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
         CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS \
+        CATCH_INTERNAL_UNSUPPRESS_UNUSED_TEMPLATE_WARNINGS \
         INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc,INTERNAL_CATCH_REMOVE_PARENS(Signature))
 
 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
@@ -1094,6 +1128,7 @@ struct AutoReg : NonCopyable {
     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(TestName, TestFuncName, Name, Tags, Signature, TmplTypes, TypesList) \
         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS                      \
         CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS                \
+        CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS                       \
         template<typename TestType> static void TestFuncName();       \
         namespace {\
         namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) {                                     \
@@ -1111,7 +1146,7 @@ struct AutoReg : NonCopyable {
                 }                                                     \
             };                                                        \
             static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
-                using TestInit = decltype(create<TestName, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>(TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>{})); \
+                using TestInit = typename create<TestName, decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>()), TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>>::type; \
                 TestInit t;                                           \
                 t.reg_tests();                                        \
                 return 0;                                             \
@@ -1120,6 +1155,7 @@ struct AutoReg : NonCopyable {
         }                                                             \
         CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS                    \
         CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS              \
+        CATCH_INTERNAL_UNSUPPRESS_UNUSED_TEMPLATE_WARNINGS                     \
         template<typename TestType>                                   \
         static void TestFuncName()
 
@@ -1141,6 +1177,7 @@ struct AutoReg : NonCopyable {
 
     #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2(TestName, TestFunc, Name, Tags, TmplList)\
         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
+        CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
         template<typename TestType> static void TestFunc();       \
         namespace {\
         namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\
@@ -1154,13 +1191,14 @@ struct AutoReg : NonCopyable {
             }                                                     \
         };\
         static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
-                using TestInit = decltype(convert<TestName>(std::declval<TmplList>())); \
+                using TestInit = typename convert<TestName, TmplList>::type; \
                 TestInit t;                                           \
                 t.reg_tests();                                        \
                 return 0;                                             \
             }();                                                        \
         }}\
         CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS                    \
+        CATCH_INTERNAL_UNSUPPRESS_UNUSED_TEMPLATE_WARNINGS \
         template<typename TestType>                                   \
         static void TestFunc()
 
@@ -1170,6 +1208,7 @@ struct AutoReg : NonCopyable {
     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... ) \
         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
         CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
+        CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
         namespace {\
         namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){ \
             INTERNAL_CATCH_TYPE_GEN\
@@ -1193,6 +1232,7 @@ struct AutoReg : NonCopyable {
         }\
         CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS\
         CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS\
+        CATCH_INTERNAL_UNSUPPRESS_UNUSED_TEMPLATE_WARNINGS\
         INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))
 
 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
@@ -1214,6 +1254,7 @@ struct AutoReg : NonCopyable {
     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(TestNameClass, TestName, ClassName, Name, Tags, Signature, TmplTypes, TypesList)\
         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
         CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
+        CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
         template<typename TestType> \
             struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
                 void test();\
@@ -1234,7 +1275,7 @@ struct AutoReg : NonCopyable {
                 }\
             };\
             static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
-                using TestInit = decltype(create<TestNameClass, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>(TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>{}));\
+                using TestInit = typename create<TestNameClass, decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>()), TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>>::type;\
                 TestInit t;\
                 t.reg_tests();\
                 return 0;\
@@ -1243,6 +1284,7 @@ struct AutoReg : NonCopyable {
         }\
         CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
         CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS \
+        CATCH_INTERNAL_UNSUPPRESS_UNUSED_TEMPLATE_WARNINGS \
         template<typename TestType> \
         void TestName<TestType>::test()
 
@@ -1264,6 +1306,7 @@ struct AutoReg : NonCopyable {
 
     #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, TmplList) \
         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
+        CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
         template<typename TestType> \
         struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
             void test();\
@@ -1280,13 +1323,14 @@ struct AutoReg : NonCopyable {
                 }\
             };\
             static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
-                using TestInit = decltype(convert<TestNameClass>(std::declval<TmplList>()));\
+                using TestInit = typename convert<TestNameClass, TmplList>::type;\
                 TestInit t;\
                 t.reg_tests();\
                 return 0;\
             }(); \
         }}\
         CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
+        CATCH_INTERNAL_UNSUPPRESS_UNUSED_TEMPLATE_WARNINGS \
         template<typename TestType> \
         void TestName<TestType>::test()
 
@@ -4311,6 +4355,7 @@ namespace Catch {
     {
         if( !IMutableContext::currentContext )
             IMutableContext::createContext();
+        // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn)
         return *IMutableContext::currentContext;
     }
 
@@ -4484,10 +4529,10 @@ namespace Catch {
         using state_type = std::uint64_t;
     public:
         using result_type = std::uint32_t;
-        static constexpr result_type min() {
+        static constexpr result_type (min)() {
             return 0;
         }
-        static constexpr result_type max() {
+        static constexpr result_type (max)() {
             return static_cast<result_type>(-1);
         }
 
@@ -5082,14 +5127,16 @@ namespace Catch {
             std::vector<TestCase const*> tests;
         };
         using Matches = std::vector<FilterMatch>;
+        using vectorStrings = std::vector<std::string>;
 
         bool hasFilters() const;
         bool matches( TestCaseInfo const& testCase ) const;
         Matches matchesByFilter( std::vector<TestCase> const& testCases, IConfig const& config ) const;
+        const vectorStrings & getInvalidArgs() const;
 
     private:
         std::vector<Filter> m_filters;
-
+        std::vector<std::string> m_invalidArgs;
         friend class TestSpecParser;
     };
 }
@@ -5143,7 +5190,7 @@ namespace Catch {
         TestSpec testSpec();
 
     private:
-        void visitChar( char c );
+        bool visitChar( char c );
         void startNewMode( Mode mode );
         bool processNoneChar( char c );
         void processNameChar( char c );
@@ -5153,6 +5200,8 @@ namespace Catch {
         bool isControlChar( char c ) const;
         void saveLastMode();
         void revertBackToLastMode();
+        void addFilter();
+        bool separate();
 
         template<typename T>
         void addPattern() {
@@ -5176,7 +5225,12 @@ namespace Catch {
             m_mode = None;
         }
 
-        void addFilter();
+        inline void addCharToPattern(char c) {
+            m_substring += c;
+            m_patternName += c;
+            m_realPatternPos++;
+        }
+
     };
     TestSpec parseTestSpec( std::string const& arg );
 
@@ -5584,6 +5638,8 @@ namespace Catch {
 
         virtual void noMatchingTestCases( std::string const& spec ) = 0;
 
+        virtual void reportInvalidArguments(std::string const&) {}
+
         virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;
         virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0;
 
@@ -5676,6 +5732,8 @@ namespace Catch {
 
         void noMatchingTestCases(std::string const&) override {}
 
+        void reportInvalidArguments(std::string const&) override {}
+
         void testRunStarting(TestRunInfo const& _testRunInfo) override {
             currentTestRunInfo = _testRunInfo;
         }
@@ -6015,9 +6073,9 @@ namespace Catch {
     CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
 
 #define CATCH_REGISTER_LISTENER( listenerType ) \
-     CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS   \
-     namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; } \
-     CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
+    CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS   \
+    namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; } \
+    CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
 #else // CATCH_CONFIG_DISABLE
 
 #define CATCH_REGISTER_REPORTER(name, reporterType)
@@ -6079,6 +6137,8 @@ namespace Catch {
 
         void noMatchingTestCases(std::string const& spec) override;
 
+        void reportInvalidArguments(std::string const&arg) override;
+
         void assertionStarting(AssertionInfo const&) override;
 
         bool assertionEnded(AssertionStats const& _assertionStats) override;
@@ -9544,9 +9604,15 @@ namespace Catch {
                     if( !line.empty() && !startsWith( line, '#' ) ) {
                         if( !startsWith( line, '"' ) )
                             line = '"' + line + '"';
-                        config.testsOrTags.push_back( line + ',' );
+                        config.testsOrTags.push_back( line );
+                        config.testsOrTags.push_back( "," );
+
                     }
                 }
+                //Remove comma in the end
+                if(!config.testsOrTags.empty())
+                    config.testsOrTags.erase( config.testsOrTags.end()-1 );
+
                 return ParserResult::ok( ParseResultType::Matched );
             };
         auto const setTestOrder = [&]( std::string const& order ) {
@@ -10755,6 +10821,8 @@ namespace Catch {
 
         void noMatchingTestCases( std::string const& spec ) override;
 
+        void reportInvalidArguments(std::string const&arg) override;
+
         static std::set<Verbosity> getSupportedVerbosities();
 
 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
@@ -11278,14 +11346,17 @@ FP step(FP start, FP direction, uint64_t steps) {
     return start;
 }
 
-namespace {
-
-    // Performs equivalent check of std::fabs(lhs - rhs) <= margin
-    // But without the subtraction to allow for INFINITY in comparison
-    bool marginComparison(double lhs, double rhs, double margin) {
-        return (lhs + margin >= rhs) && (rhs + margin >= lhs);
-    }
+// Performs equivalent check of std::fabs(lhs - rhs) <= margin
+// But without the subtraction to allow for INFINITY in comparison
+bool marginComparison(double lhs, double rhs, double margin) {
+    return (lhs + margin >= rhs) && (rhs + margin >= lhs);
+}
 
+template <typename FloatingPoint>
+void write(std::ostream& out, FloatingPoint num) {
+    out << std::scientific
+        << std::setprecision(std::numeric_limits<FloatingPoint>::max_digits10 - 1)
+        << num;
 }
 
 } // end anonymous namespace
@@ -11317,7 +11388,7 @@ namespace Floating {
     WithinUlpsMatcher::WithinUlpsMatcher(double target, uint64_t ulps, FloatingPointKind baseType)
         :m_target{ target }, m_ulps{ ulps }, m_type{ baseType } {
         CATCH_ENFORCE(m_type == FloatingPointKind::Double
-                   || m_ulps < std::numeric_limits<uint32_t>::max(),
+                   || m_ulps < (std::numeric_limits<uint32_t>::max)(),
             "Provided ULP is impossibly large for a float comparison.");
     }
 
@@ -11345,27 +11416,29 @@ namespace Floating {
     std::string WithinUlpsMatcher::describe() const {
         std::stringstream ret;
 
-        ret << "is within " << m_ulps << " ULPs of " << ::Catch::Detail::stringify(m_target);
+        ret << "is within " << m_ulps << " ULPs of ";
 
         if (m_type == FloatingPointKind::Float) {
+            write(ret, static_cast<float>(m_target));
             ret << 'f';
+        } else {
+            write(ret, m_target);
         }
 
         ret << " ([";
-        ret << std::fixed << std::setprecision(std::numeric_limits<double>::max_digits10);
         if (m_type == FloatingPointKind::Double) {
-            ret << step(m_target, static_cast<double>(-INFINITY), m_ulps)
-                << ", "
-                << step(m_target, static_cast<double>(INFINITY), m_ulps);
+            write(ret, step(m_target, static_cast<double>(-INFINITY), m_ulps));
+            ret << ", ";
+            write(ret, step(m_target, static_cast<double>( INFINITY), m_ulps));
         } else {
-            ret << step<float>(static_cast<float>(m_target), -INFINITY, m_ulps)
-                << ", "
-                << step<float>(static_cast<float>(m_target), INFINITY, m_ulps);
+            // We have to cast INFINITY to float because of MinGW, see #1782
+            write(ret, step(static_cast<float>(m_target), static_cast<float>(-INFINITY), m_ulps));
+            ret << ", ";
+            write(ret, step(static_cast<float>(m_target), static_cast<float>( INFINITY), m_ulps));
         }
         ret << "])";
 
         return ret.str();
-        //return "is within " + Catch::to_string(m_ulps) + " ULPs of " + ::Catch::Detail::stringify(m_target) + ((m_type == FloatingPointKind::Float)? "f" : "");
     }
 
     WithinRelMatcher::WithinRelMatcher(double target, double epsilon):
@@ -11376,7 +11449,7 @@ namespace Floating {
     }
 
     bool WithinRelMatcher::match(double const& matchee) const {
-        const auto relMargin = m_epsilon * std::max(std::fabs(matchee), std::fabs(m_target));
+        const auto relMargin = m_epsilon * (std::max)(std::fabs(matchee), std::fabs(m_target));
         return marginComparison(matchee, m_target,
                                 std::isinf(relMargin)? 0 : relMargin);
     }
@@ -12983,8 +13056,9 @@ namespace Catch {
             {
                 auto const& allTestCases = getAllTestCasesSorted(*m_config);
                 m_matches = m_config->testSpec().matchesByFilter(allTestCases, *m_config);
+                auto const& invalidArgs = m_config->testSpec().getInvalidArgs();
 
-                if (m_matches.empty()) {
+                if (m_matches.empty() && invalidArgs.empty()) {
                     for (auto const& test : allTestCases)
                         if (!test.isHidden())
                             m_tests.emplace(&test);
@@ -12995,6 +13069,7 @@ namespace Catch {
             }
 
             Totals execute() {
+                auto const& invalidArgs = m_config->testSpec().getInvalidArgs();
                 Totals totals;
                 m_context.testGroupStarting(m_config->name(), 1, 1);
                 for (auto const& testCase : m_tests) {
@@ -13010,6 +13085,12 @@ namespace Catch {
                         totals.error = -1;
                     }
                 }
+
+                if (!invalidArgs.empty()) {
+                    for (auto const& invalidArg: invalidArgs)
+                         m_context.reporter().reportInvalidArguments(invalidArg);
+                }
+
                 m_context.testGroupEnded(m_config->name(), totals, 1, 1);
                 return totals;
             }
@@ -14305,6 +14386,10 @@ namespace Catch {
         return matches;
     }
 
+    const TestSpec::vectorStrings& TestSpec::getInvalidArgs() const{
+        return  (m_invalidArgs);
+    }
+
 }
 // end catch_test_spec.cpp
 // start catch_test_spec_parser.cpp
@@ -14321,8 +14406,13 @@ namespace Catch {
         m_substring.reserve(m_arg.size());
         m_patternName.reserve(m_arg.size());
         m_realPatternPos = 0;
+
         for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
-            visitChar( m_arg[m_pos] );
+          //if visitChar fails
+           if( !visitChar( m_arg[m_pos] ) ){
+               m_testSpec.m_invalidArgs.push_back(arg);
+               break;
+           }
         endMode();
         return *this;
     }
@@ -14330,38 +14420,32 @@ namespace Catch {
         addFilter();
         return m_testSpec;
     }
-    void TestSpecParser::visitChar( char c ) {
+    bool TestSpecParser::visitChar( char c ) {
         if( (m_mode != EscapedName) && (c == '\\') ) {
             escape();
-            m_substring += c;
-            m_patternName += c;
-            m_realPatternPos++;
-            return;
+            addCharToPattern(c);
+            return true;
         }else if((m_mode != EscapedName) && (c == ',') )  {
-            endMode();
-            addFilter();
-            return;
+            return separate();
         }
 
         switch( m_mode ) {
         case None:
             if( processNoneChar( c ) )
-                return;
+                return true;
             break;
         case Name:
             processNameChar( c );
             break;
         case EscapedName:
             endMode();
-            m_substring += c;
-            m_patternName += c;
-            m_realPatternPos++;
-            return;
+            addCharToPattern(c);
+            return true;
         default:
         case Tag:
         case QuotedName:
             if( processOtherChar( c ) )
-                return;
+                return true;
             break;
         }
 
@@ -14370,6 +14454,7 @@ namespace Catch {
             m_patternName += c;
             m_realPatternPos++;
         }
+        return true;
     }
     // Two of the processing methods return true to signal the caller to return
     // without adding the given character to the current pattern strings
@@ -14462,6 +14547,20 @@ namespace Catch {
       m_mode = lastMode;
     }
 
+    bool TestSpecParser::separate() {
+      if( (m_mode==QuotedName) || (m_mode==Tag) ){
+         //invalid argument, signal failure to previous scope.
+         m_mode = None;
+         m_pos = m_arg.size();
+         m_substring.clear();
+         m_patternName.clear();
+         return false;
+      }
+      endMode();
+      addFilter();
+      return true; //success
+    }
+
     TestSpec parseTestSpec( std::string const& arg ) {
         return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
     }
@@ -14889,7 +14988,7 @@ namespace Catch {
     }
 
     Version const& libraryVersion() {
-        static Version version( 2, 10, 0, "", 0 );
+        static Version version( 2, 10, 2, "", 0 );
         return version;
     }
 
@@ -15926,6 +16025,10 @@ void ConsoleReporter::noMatchingTestCases(std::string const& spec) {
     stream << "No test cases matched '" << spec << '\'' << std::endl;
 }
 
+void ConsoleReporter::reportInvalidArguments(std::string const&arg){
+    stream << "Invalid Filter: " << arg << std::endl;
+}
+
 void ConsoleReporter::assertionStarting(AssertionInfo const&) {}
 
 bool ConsoleReporter::assertionEnded(AssertionStats const& _assertionStats) {
@@ -16526,6 +16629,13 @@ namespace Catch {
         m_reporter->noMatchingTestCases( spec );
     }
 
+    void ListeningReporter::reportInvalidArguments(std::string const&arg){
+        for ( auto const& listener : m_listeners ) {
+            listener->reportInvalidArguments( arg );
+        }
+        m_reporter->reportInvalidArguments( arg );
+    }
+
 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
     void ListeningReporter::benchmarkPreparing( std::string const& name ) {
 		for (auto const& listener : m_listeners) {