From 38771ccb510b84940ebd18147ef89c55ecd9aca2 Mon Sep 17 00:00:00 2001
From: Stephane Del Pino <stephane.delpino44@gmail.com>
Date: Mon, 1 Oct 2018 22:09:04 +0200
Subject: [PATCH] git subrepo pull packages/Catch2 + update configuration

subrepo:
  subdir:   "packages/Catch2"
  merged:   "9e1bdca4"
upstream:
  origin:   "git@github.com:catchorg/Catch2.git"
  branch:   "master"
  commit:   "9e1bdca4"
git-subrepo:
  version:  "0.3.1"
  origin:   "git@github.com:ingydotnet/git-subrepo.git"
  commit:   "a7ee886"
---
 CMakeLists.txt                                |    2 +-
 packages/Catch2/.gitattributes                |    2 +-
 packages/Catch2/.gitrepo                      |    4 +-
 packages/Catch2/.travis.yml                   |   41 +-
 packages/Catch2/CMake/Catch2Config.cmake.in   |   10 +
 packages/Catch2/CMake/MiscFunctions.cmake     |   26 +
 packages/Catch2/CMake/catch2.pc.in            |    7 +
 packages/Catch2/CMakeLists.txt                |  567 +--
 packages/Catch2/README.md                     |    8 +-
 packages/Catch2/appveyor.yml                  |    2 -
 packages/Catch2/catch.pc.in                   |    6 -
 packages/Catch2/conanfile.py                  |   24 +-
 .../contrib/ParseAndAddCatchTests.cmake       |    3 +
 packages/Catch2/docs/Readme.md                |    6 +-
 packages/Catch2/docs/assertions.md            |   30 +-
 .../docs/{build-systems.md => ci-and-misc.md} |  111 +-
 packages/Catch2/docs/cmake-integration.md     |  216 ++
 packages/Catch2/docs/command-line.md          |    6 +-
 packages/Catch2/docs/configuration.md         |   79 +-
 packages/Catch2/docs/generators.md            |   50 +
 packages/Catch2/docs/limitations.md           |   51 +-
 packages/Catch2/docs/list-of-examples.md      |   12 +-
 packages/Catch2/docs/logging.md               |    6 -
 packages/Catch2/docs/opensource-users.md      |    5 +-
 packages/Catch2/docs/own-main.md              |   10 +-
 packages/Catch2/docs/release-notes.md         |  296 +-
 packages/Catch2/docs/reporters.md             |    4 +-
 .../Catch2/docs/test-cases-and-sections.md    |   14 +-
 packages/Catch2/docs/tostring.md              |   22 +-
 packages/Catch2/docs/tutorial.md              |    8 +-
 packages/Catch2/examples/000-CatchMain.cpp    |    2 +-
 packages/Catch2/examples/010-TestCase.cpp     |    2 +-
 packages/Catch2/examples/020-TestCase-1.cpp   |    2 +-
 packages/Catch2/examples/020-TestCase-2.cpp   |    2 +-
 .../Catch2/examples/030-Asn-Require-Check.cpp |    2 +-
 packages/Catch2/examples/100-Fix-Section.cpp  |    2 +-
 .../Catch2/examples/110-Fix-ClassFixture.cpp  |    2 +-
 .../120-Bdd-ScenarioGivenWhenThen.cpp         |    2 +-
 .../Catch2/examples/200-Rpt-CatchMain.cpp     |   27 +
 .../examples/207-Rpt-TeamCityReporter.cpp     |  171 +
 .../examples/210-Evt-EventListeners.cpp       |    5 +-
 .../Catch2/examples/231-Cfg-OutputStreams.cpp |   49 +
 packages/Catch2/examples/CMakeLists.txt       |   65 +-
 packages/Catch2/include/catch.hpp             |   44 +-
 .../Catch2/include/internal/catch_approx.cpp  |   31 +
 .../Catch2/include/internal/catch_approx.h    |   39 +-
 .../internal/catch_assertionhandler.cpp       |   11 +-
 .../include/internal/catch_assertionhandler.h |    4 +-
 .../Catch2/include/internal/catch_capture.hpp |   26 +-
 .../internal/catch_capture_matchers.cpp       |    2 +-
 .../include/internal/catch_capture_matchers.h |   15 +-
 .../Catch2/include/internal/catch_common.cpp  |    4 +-
 .../internal/catch_compiler_capabilities.h    |   89 +-
 .../Catch2/include/internal/catch_enforce.cpp |   19 +
 .../Catch2/include/internal/catch_enforce.h   |   22 +-
 .../catch_exception_translator_registry.cpp   |   12 +-
 .../include/internal/catch_generators.cpp     |   50 +
 .../include/internal/catch_generators.hpp     |  253 ++
 .../internal/catch_interfaces_capture.h       |    4 +
 .../catch_interfaces_generatortracker.h       |   39 +
 .../internal/catch_interfaces_registry_hub.h  |    4 +-
 .../internal/catch_interfaces_reporter.h      |    1 +
 .../include/internal/catch_leak_detector.cpp  |   20 +-
 .../Catch2/include/internal/catch_matchers.h  |    9 +
 .../internal/catch_matchers_floating.cpp      |   24 +-
 .../include/internal/catch_matchers_vector.h  |    2 +-
 .../Catch2/include/internal/catch_message.cpp |   38 +-
 .../Catch2/include/internal/catch_message.h   |   34 +-
 .../internal/catch_output_redirect.cpp        |   40 +-
 .../include/internal/catch_output_redirect.h  |    3 +
 .../catch_random_number_generator.cpp         |   20 +-
 .../internal/catch_random_number_generator.h  |   19 +-
 .../include/internal/catch_registry_hub.cpp   |   23 +-
 .../include/internal/catch_run_context.cpp    |   86 +-
 .../include/internal/catch_run_context.h      |    3 +
 .../Catch2/include/internal/catch_section.cpp |    2 +-
 .../Catch2/include/internal/catch_section.h   |   12 +-
 .../include/internal/catch_section_info.cpp   |    8 +-
 .../include/internal/catch_section_info.h     |   11 +-
 .../Catch2/include/internal/catch_session.cpp |   15 +-
 .../include/internal/catch_singletons.cpp     |   36 +
 .../include/internal/catch_singletons.hpp     |   44 +
 .../catch_startup_exception_registry.cpp      |    8 +-
 .../Catch2/include/internal/catch_stream.cpp  |   34 +-
 .../Catch2/include/internal/catch_stream.h    |    2 -
 .../Catch2/include/internal/catch_stringref.h |    4 +
 .../internal/catch_suppress_warnings.h        |    4 +-
 .../catch_tag_alias_autoregistrar.cpp         |    7 +-
 .../catch_test_case_registry_impl.cpp         |    2 +-
 .../internal/catch_test_case_tracker.cpp      |   15 +-
 .../internal/catch_test_case_tracker.h        |    7 -
 .../include/internal/catch_test_registry.cpp  |    5 +-
 .../include/internal/catch_test_registry.h    |    4 +-
 .../include/internal/catch_tostring.cpp       |   31 +-
 .../Catch2/include/internal/catch_tostring.h  |   52 +-
 .../Catch2/include/internal/catch_version.cpp |    2 +-
 .../reporters/catch_reporter_bases.hpp        |    5 +-
 .../reporters/catch_reporter_compact.cpp      |    4 +-
 .../reporters/catch_reporter_junit.cpp        |    1 +
 .../reporters/catch_reporter_listening.cpp    |    8 +-
 .../reporters/catch_reporter_listening.h      |    3 +
 .../include/reporters/catch_reporter_tap.hpp  |    4 +-
 .../reporters/catch_reporter_teamcity.hpp     |    4 +-
 .../include/reporters/catch_reporter_xml.cpp  |    4 +-
 packages/Catch2/misc/SelfTest.vcxproj.user    |   23 +
 .../misc/appveyorBuildConfigurationScript.bat |   19 +-
 .../Catch2/misc/appveyorTestRunScript.bat     |   12 +-
 .../Catch2/projects/Benchmark/BenchMain.cpp   |    9 -
 .../Benchmark/StringificationBench.cpp        |   46 -
 packages/Catch2/projects/Benchmark/readme.txt |    4 -
 ...cdddd43ba4df9e4846630be6a6a7bd85a07.result |    3 -
 ...841ff500b2f39ccfd4193ae450cb653da05.result |    3 -
 ...0166f7b7196eba2ad518174d1a77165166d.result |    3 -
 ...bec49c5bc58d3604bf1a72cd3f7d129bf2e.result |    3 -
 ...f9646c5ce50758f8582307c99501a932e1a.result |    3 -
 packages/Catch2/projects/CMakeLists.txt       |  353 ++
 .../Catch2/projects/ExtraTests/CMakeLists.txt |  135 +
 packages/Catch2/projects/ExtraTests/ToDo.txt  |   11 +
 .../ExtraTests/X01-PrefixedMacros.cpp         |   76 +
 .../ExtraTests/X02-DisabledMacros.cpp         |   31 +
 .../X03-DisabledExceptions-DefaultHandler.cpp |   23 +
 .../X04-DisabledExceptions-CustomHandler.cpp  |   33 +
 .../ExtraTests/X10-FallbackStringifier.cpp    |   23 +
 .../ExtraTests/X11-DisableStringification.cpp |   16 +
 .../Baselines/compact.sw.approved.txt         |  167 +-
 .../Baselines/console.std.approved.txt        |   22 +-
 .../Baselines/console.sw.approved.txt         | 3316 +++++++++++++----
 .../SelfTest/Baselines/junit.sw.approved.txt  |   54 +-
 .../SelfTest/Baselines/xml.sw.approved.txt    | 2229 ++++++++---
 .../IntrospectiveTests/CmdLine.tests.cpp      |    2 +-
 .../GeneratorsImpl.tests.cpp                  |   93 +
 .../IntrospectiveTests/PartTracker.tests.cpp  |   11 +-
 .../IntrospectiveTests/String.tests.cpp       |    9 +-
 .../SelfTest/UsageTests/Approx.tests.cpp      |   16 +
 .../SelfTest/UsageTests/BDD.tests.cpp         |   13 +-
 .../UsageTests/Decomposition.tests.cpp        |    4 +
 .../UsageTests/EnumToString.tests.cpp         |   37 +-
 .../SelfTest/UsageTests/Exception.tests.cpp   |    1 +
 .../SelfTest/UsageTests/Generators.tests.cpp  |  134 +
 .../SelfTest/UsageTests/Matchers.tests.cpp    |    9 +
 .../SelfTest/UsageTests/Misc.tests.cpp        |   40 +-
 .../UsageTests/ToStringGeneral.tests.cpp      |   16 +
 .../UsageTests/ToStringVariant.tests.cpp      |   84 +
 .../UsageTests/ToStringWhich.tests.cpp        |   20 +
 .../SelfTest/UsageTests/Tricky.tests.cpp      |   32 +-
 packages/Catch2/scripts/approvalTests.py      |   23 +-
 .../Catch2/scripts/generateSingleHeader.py    |    4 +-
 packages/Catch2/scripts/releaseCommon.py      |    2 +-
 packages/Catch2/scripts/scriptCommon.py       |    2 +-
 packages/Catch2/scripts/updateDocumentToC.py  |   28 +-
 packages/Catch2/scripts/updateWandbox.py      |    2 +-
 .../single_include/{ => catch2}/catch.hpp     | 1403 +++++--
 .../{ => catch2}/catch_reporter_automake.hpp  |    0
 .../{ => catch2}/catch_reporter_tap.hpp       |    4 +-
 .../{ => catch2}/catch_reporter_teamcity.hpp  |    4 +-
 packages/Catch2/test_package/MainTest.cpp     |    2 +-
 packages/Catch2/test_package/conanfile.py     |    2 +-
 tests/CMakeLists.txt                          |    4 +-
 158 files changed, 9215 insertions(+), 2692 deletions(-)
 create mode 100644 packages/Catch2/CMake/Catch2Config.cmake.in
 create mode 100644 packages/Catch2/CMake/MiscFunctions.cmake
 create mode 100644 packages/Catch2/CMake/catch2.pc.in
 delete mode 100644 packages/Catch2/catch.pc.in
 rename packages/Catch2/docs/{build-systems.md => ci-and-misc.md} (59%)
 create mode 100644 packages/Catch2/docs/cmake-integration.md
 create mode 100644 packages/Catch2/docs/generators.md
 create mode 100644 packages/Catch2/examples/200-Rpt-CatchMain.cpp
 create mode 100644 packages/Catch2/examples/207-Rpt-TeamCityReporter.cpp
 create mode 100644 packages/Catch2/examples/231-Cfg-OutputStreams.cpp
 create mode 100644 packages/Catch2/include/internal/catch_enforce.cpp
 create mode 100644 packages/Catch2/include/internal/catch_generators.cpp
 create mode 100644 packages/Catch2/include/internal/catch_generators.hpp
 create mode 100644 packages/Catch2/include/internal/catch_interfaces_generatortracker.h
 create mode 100644 packages/Catch2/include/internal/catch_singletons.cpp
 create mode 100644 packages/Catch2/include/internal/catch_singletons.hpp
 create mode 100644 packages/Catch2/misc/SelfTest.vcxproj.user
 delete mode 100644 packages/Catch2/projects/Benchmark/BenchMain.cpp
 delete mode 100644 packages/Catch2/projects/Benchmark/StringificationBench.cpp
 delete mode 100644 packages/Catch2/projects/Benchmark/readme.txt
 delete mode 100644 packages/Catch2/projects/Benchmark/results/2017-01-14T21-53-49-e3659cdddd43ba4df9e4846630be6a6a7bd85a07.result
 delete mode 100644 packages/Catch2/projects/Benchmark/results/2017-01-14T21-59-08-a1e9b841ff500b2f39ccfd4193ae450cb653da05.result
 delete mode 100644 packages/Catch2/projects/Benchmark/results/2017-01-15T09-35-14-3b98a0166f7b7196eba2ad518174d1a77165166d.result
 delete mode 100644 packages/Catch2/projects/Benchmark/results/2017-01-29T22-08-36-60f8ebec49c5bc58d3604bf1a72cd3f7d129bf2e.result
 delete mode 100644 packages/Catch2/projects/Benchmark/results/2017-01-29T23-13-35-bcaa2f9646c5ce50758f8582307c99501a932e1a.result
 create mode 100644 packages/Catch2/projects/CMakeLists.txt
 create mode 100644 packages/Catch2/projects/ExtraTests/CMakeLists.txt
 create mode 100644 packages/Catch2/projects/ExtraTests/ToDo.txt
 create mode 100644 packages/Catch2/projects/ExtraTests/X01-PrefixedMacros.cpp
 create mode 100644 packages/Catch2/projects/ExtraTests/X02-DisabledMacros.cpp
 create mode 100644 packages/Catch2/projects/ExtraTests/X03-DisabledExceptions-DefaultHandler.cpp
 create mode 100644 packages/Catch2/projects/ExtraTests/X04-DisabledExceptions-CustomHandler.cpp
 create mode 100644 packages/Catch2/projects/ExtraTests/X10-FallbackStringifier.cpp
 create mode 100644 packages/Catch2/projects/ExtraTests/X11-DisableStringification.cpp
 create mode 100644 packages/Catch2/projects/SelfTest/IntrospectiveTests/GeneratorsImpl.tests.cpp
 create mode 100644 packages/Catch2/projects/SelfTest/UsageTests/Generators.tests.cpp
 create mode 100644 packages/Catch2/projects/SelfTest/UsageTests/ToStringVariant.tests.cpp
 rename packages/Catch2/single_include/{ => catch2}/catch.hpp (91%)
 rename packages/Catch2/single_include/{ => catch2}/catch_reporter_automake.hpp (100%)
 rename packages/Catch2/single_include/{ => catch2}/catch_reporter_tap.hpp (98%)
 rename packages/Catch2/single_include/{ => catch2}/catch_reporter_teamcity.hpp (98%)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index c93aa25f4..8c03f5d37 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -139,7 +139,7 @@ include_directories(src/scheme)
 # Pastis tests
 
 set(CATCH_MODULE_PATH "${PASTIS_SOURCE_DIR}/packages/Catch2")
-set(CATCH_INCLUDE_PATH "${CATCH_MODULE_PATH}/single_include")
+set(CATCH_INCLUDE_PATH "${CATCH_MODULE_PATH}/single_include/catch2")
 
 include("${CATCH_MODULE_PATH}/contrib/ParseAndAddCatchTests.cmake")
 add_subdirectory("${CATCH_MODULE_PATH}")
diff --git a/packages/Catch2/.gitattributes b/packages/Catch2/.gitattributes
index b5a2cdccd..23f98fffa 100644
--- a/packages/Catch2/.gitattributes
+++ b/packages/Catch2/.gitattributes
@@ -17,6 +17,6 @@
 
 # Keep the single include header with LFs to make sure it is uploaded,
 # hashed etc with LF
-single_include/*.hpp eol=lf
+single_include/**/*.hpp eol=lf
 # Also keep the LICENCE file with LFs for the same reason
 LICENCE.txt eol=lf
diff --git a/packages/Catch2/.gitrepo b/packages/Catch2/.gitrepo
index f0489ed62..5c9fe5b98 100644
--- a/packages/Catch2/.gitrepo
+++ b/packages/Catch2/.gitrepo
@@ -6,6 +6,6 @@
 [subrepo]
 	remote = git@github.com:catchorg/Catch2.git
 	branch = master
-	commit = 1dce91d78eb6764a474badee7559650502f1d2fc
-	parent = 5515dc5466f2c351639c28fdc16cce10cb067e12
+	commit = 9e1bdca4667295fcb16265eae00efa8423f07007
+	parent = cd9b656f2a2e7fe914557e186f30b2123bcb98b4
 	cmdver = 0.3.1
diff --git a/packages/Catch2/.travis.yml b/packages/Catch2/.travis.yml
index b20456039..1d38d8602 100644
--- a/packages/Catch2/.travis.yml
+++ b/packages/Catch2/.travis.yml
@@ -219,7 +219,7 @@ matrix:
         apt:
           sources: *all_sources
           packages: ['lcov', 'g++-7']
-      env: COMPILER='g++-7' CPP14=1 EXAMPLES=1 COVERAGE=1
+      env: COMPILER='g++-7' CPP14=1 EXAMPLES=1 COVERAGE=1 EXTRAS=1
 
     - os: linux
       compiler: clang
@@ -229,7 +229,7 @@ matrix:
           sources:
             - ubuntu-toolchain-r-test
             - llvm-toolchain-trusty
-      env: COMPILER='clang++-3.8' EXAMPLES=1 COVERAGE=1
+      env: COMPILER='clang++-3.8' EXAMPLES=1 COVERAGE=1 EXTRAS=1
 
     - os: linux
       compiler: gcc
@@ -237,19 +237,46 @@ matrix:
         apt:
           sources: *all_sources
           packages: ['valgrind', 'lcov', 'g++-7']
-      env: COMPILER='g++-7' CPP14=1 VALGRIND=1      
-      
+      env: COMPILER='g++-7' CPP14=1 VALGRIND=1
+
     - os: osx
       osx_image: xcode9.1
       compiler: clang
-      env: COMPILER='clang++' CPP14=1 EXAMPLES=1 COVERAGE=1
+      env: COMPILER='clang++' CPP14=1 EXAMPLES=1 COVERAGE=1 EXTRAS=1
+
+    # 7/ C++17 builds
+    - os: linux
+      compiler: gcc
+      addons: *gcc7
+      env: COMPILER='g++-7' CPP17=1
+
+    - os: linux
+      compiler: gcc
+      addons: *gcc7
+      env: COMPILER='g++-7' EXAMPLES=1 COVERAGE=1 EXTRAS=1 CPP17=1
+
+    - os: linux
+      compiler: clang
+      addons:
+          apt:
+              sources: *all_sources
+              packages: ['clang-6.0', 'libstdc++-8-dev']
+      env: COMPILER='clang++-6.0' CPP17=1
+
+    - os: linux
+      compiler: clang
+      addons:
+          apt:
+              sources: *all_sources
+              packages: ['clang-6.0', 'libstdc++-8-dev']
+      env: COMPILER='clang++-6.0' CPP17=1 EXAMPLES=1 COVERAGE=1 EXTRAS=1
 
 install:
   - DEPS_DIR="${TRAVIS_BUILD_DIR}/deps"
   - mkdir -p ${DEPS_DIR} && cd ${DEPS_DIR}
   - |
     if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then
-      CMAKE_URL="http://www.cmake.org/files/v3.3/cmake-3.3.2-Linux-x86_64.tar.gz"
+      CMAKE_URL="http://cmake.org/files/v3.8/cmake-3.8.2-Linux-x86_64.tar.gz"
       mkdir cmake && travis_retry wget --no-check-certificate --quiet -O - ${CMAKE_URL} | tar --strip-components=1 -xz -C cmake
       export PATH=${DEPS_DIR}/cmake/bin:${PATH}
     elif [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then
@@ -263,7 +290,7 @@ before_script:
   - python scripts/generateSingleHeader.py
 
     # Use Debug builds for running Valgrind and building examples
-  - cmake -H. -BBuild-Debug -DCMAKE_BUILD_TYPE=Debug -Wdev -DUSE_CPP14=${CPP14} -DCATCH_USE_VALGRIND=${VALGRIND} -DCATCH_BUILD_EXAMPLES=${EXAMPLES} -DCATCH_ENABLE_COVERAGE=${COVERAGE}
+  - cmake -H. -BBuild-Debug -DCMAKE_BUILD_TYPE=Debug -Wdev -DUSE_CPP14=${CPP14} -DUSE_CPP17=${CPP17} -DCATCH_USE_VALGRIND=${VALGRIND} -DCATCH_BUILD_EXAMPLES=${EXAMPLES} -DCATCH_ENABLE_COVERAGE=${COVERAGE} -DCATCH_BUILD_EXTRA_TESTS=${EXTRAS}
     # Don't bother with release build for coverage build
   - cmake -H. -BBuild-Release -DCMAKE_BUILD_TYPE=Release -Wdev -DUSE_CPP14=${CPP14}
 
diff --git a/packages/Catch2/CMake/Catch2Config.cmake.in b/packages/Catch2/CMake/Catch2Config.cmake.in
new file mode 100644
index 000000000..c485219cd
--- /dev/null
+++ b/packages/Catch2/CMake/Catch2Config.cmake.in
@@ -0,0 +1,10 @@
+@PACKAGE_INIT@
+
+
+# Avoid repeatedly including the targets
+if(NOT TARGET Catch2::Catch2)
+    # Provide path for scripts
+    list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}")
+
+    include(${CMAKE_CURRENT_LIST_DIR}/Catch2Targets.cmake)
+endif()
diff --git a/packages/Catch2/CMake/MiscFunctions.cmake b/packages/Catch2/CMake/MiscFunctions.cmake
new file mode 100644
index 000000000..262f7cd82
--- /dev/null
+++ b/packages/Catch2/CMake/MiscFunctions.cmake
@@ -0,0 +1,26 @@
+#checks that the given hard-coded list contains all headers + sources in the given folder
+function(CheckFileList LIST_VAR FOLDER)
+  set(MESSAGE " should be added to the variable ${LIST_VAR}")
+  set(MESSAGE "${MESSAGE} in ${CMAKE_CURRENT_LIST_FILE}\n")
+  file(GLOB GLOBBED_LIST "${FOLDER}/*.cpp"
+                         "${FOLDER}/*.hpp"
+                         "${FOLDER}/*.h")
+  list(REMOVE_ITEM GLOBBED_LIST ${${LIST_VAR}})
+  foreach(EXTRA_ITEM ${GLOBBED_LIST})
+    string(REPLACE "${CATCH_DIR}/" "" RELATIVE_FILE_NAME "${EXTRA_ITEM}")
+    message(AUTHOR_WARNING "The file \"${RELATIVE_FILE_NAME}\"${MESSAGE}")
+  endforeach()
+endfunction()
+
+function(CheckFileListRec LIST_VAR FOLDER)
+  set(MESSAGE " should be added to the variable ${LIST_VAR}")
+  set(MESSAGE "${MESSAGE} in ${CMAKE_CURRENT_LIST_FILE}\n")
+  file(GLOB_RECURSE GLOBBED_LIST "${FOLDER}/*.cpp"
+                                 "${FOLDER}/*.hpp"
+                                 "${FOLDER}/*.h")
+  list(REMOVE_ITEM GLOBBED_LIST ${${LIST_VAR}})
+  foreach(EXTRA_ITEM ${GLOBBED_LIST})
+    string(REPLACE "${CATCH_DIR}/" "" RELATIVE_FILE_NAME "${EXTRA_ITEM}")
+    message(AUTHOR_WARNING "The file \"${RELATIVE_FILE_NAME}\"${MESSAGE}")
+  endforeach()
+endfunction()
diff --git a/packages/Catch2/CMake/catch2.pc.in b/packages/Catch2/CMake/catch2.pc.in
new file mode 100644
index 000000000..3ac9fbd1a
--- /dev/null
+++ b/packages/Catch2/CMake/catch2.pc.in
@@ -0,0 +1,7 @@
+includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
+
+Name: Catch2
+Description: A modern, C++-native, header-only, test framework for C++11
+URL: https://github.com/catchorg/Catch2
+Version: @Catch2_VERSION@
+Cflags: -I${includedir}
diff --git a/packages/Catch2/CMakeLists.txt b/packages/Catch2/CMakeLists.txt
index 9fdb50866..09793f7b3 100644
--- a/packages/Catch2/CMakeLists.txt
+++ b/packages/Catch2/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.1)
+cmake_minimum_required(VERSION 3.5)
 
 # detect if Catch is being bundled,
 # disable testsuite in that case
@@ -6,14 +6,24 @@ if(NOT DEFINED PROJECT_NAME)
   set(NOT_SUBPROJECT ON)
 endif()
 
-project(Catch2 LANGUAGES CXX VERSION 2.2.3)
+project(Catch2 LANGUAGES CXX VERSION 2.4.1)
+
+# Provide path for scripts
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake")
 
 include(GNUInstallDirs)
+include(CMakePackageConfigHelpers)
+include(CTest)
 
 option(CATCH_USE_VALGRIND "Perform SelfTests with Valgrind" OFF)
+option(CATCH_BUILD_TESTING "Build SelfTest project" ON)
 option(CATCH_BUILD_EXAMPLES "Build documentation examples" OFF)
+option(CATCH_BUILD_EXTRA_TESTS "Build extra tests" OFF)
 option(CATCH_ENABLE_COVERAGE "Generate coverage for codecov.io" OFF)
 option(CATCH_ENABLE_WERROR "Enable all warnings as errors" ON)
+option(CATCH_INSTALL_DOCS "Install documentation alongside library" ON)
+option(CATCH_INSTALL_HELPERS "Install contrib alongside library" ON)
+
 
 set_property(GLOBAL PROPERTY USE_FOLDERS ON)
 
@@ -27,433 +37,172 @@ if(USE_WMAIN)
     set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /ENTRY:wmainCRTStartup")
 endif()
 
-#checks that the given hard-coded list contains all headers + sources in the given folder
-function(CheckFileList LIST_VAR FOLDER)
-  set(MESSAGE " should be added to the variable ${LIST_VAR}")
-  set(MESSAGE "${MESSAGE} in ${CMAKE_CURRENT_LIST_FILE}\n")
-  file(GLOB GLOBBED_LIST "${FOLDER}/*.cpp"
-                         "${FOLDER}/*.hpp"
-                         "${FOLDER}/*.h")
-  list(REMOVE_ITEM GLOBBED_LIST ${${LIST_VAR}})
-  foreach(EXTRA_ITEM ${GLOBBED_LIST})
-    string(REPLACE "${CATCH_DIR}/" "" RELATIVE_FILE_NAME "${EXTRA_ITEM}")
-    message(AUTHOR_WARNING "The file \"${RELATIVE_FILE_NAME}\"${MESSAGE}")
-  endforeach()
-endfunction()
-
-function(CheckFileListRec LIST_VAR FOLDER)
-  set(MESSAGE " should be added to the variable ${LIST_VAR}")
-  set(MESSAGE "${MESSAGE} in ${CMAKE_CURRENT_LIST_FILE}\n")
-  file(GLOB_RECURSE GLOBBED_LIST "${FOLDER}/*.cpp"
-                                 "${FOLDER}/*.hpp"
-                                 "${FOLDER}/*.h")
-  list(REMOVE_ITEM GLOBBED_LIST ${${LIST_VAR}})
-  foreach(EXTRA_ITEM ${GLOBBED_LIST})
-    string(REPLACE "${CATCH_DIR}/" "" RELATIVE_FILE_NAME "${EXTRA_ITEM}")
-    message(AUTHOR_WARNING "The file \"${RELATIVE_FILE_NAME}\"${MESSAGE}")
-  endforeach()
-endfunction()
-
-# define the sources of the self test
-# Please keep these ordered alphabetically
-set(TEST_SOURCES
-        ${SELF_TEST_DIR}/TestMain.cpp
-        ${SELF_TEST_DIR}/IntrospectiveTests/CmdLine.tests.cpp
-        ${SELF_TEST_DIR}/IntrospectiveTests/PartTracker.tests.cpp
-        ${SELF_TEST_DIR}/IntrospectiveTests/TagAlias.tests.cpp
-        ${SELF_TEST_DIR}/IntrospectiveTests/String.tests.cpp
-        ${SELF_TEST_DIR}/IntrospectiveTests/Xml.tests.cpp
-        ${SELF_TEST_DIR}/UsageTests/Approx.tests.cpp
-        ${SELF_TEST_DIR}/UsageTests/BDD.tests.cpp
-        ${SELF_TEST_DIR}/UsageTests/Benchmark.tests.cpp
-        ${SELF_TEST_DIR}/UsageTests/Class.tests.cpp
-        ${SELF_TEST_DIR}/UsageTests/Compilation.tests.cpp
-        ${SELF_TEST_DIR}/UsageTests/Condition.tests.cpp
-        ${SELF_TEST_DIR}/UsageTests/Decomposition.tests.cpp
-        ${SELF_TEST_DIR}/UsageTests/EnumToString.tests.cpp
-        ${SELF_TEST_DIR}/UsageTests/Exception.tests.cpp
-        ${SELF_TEST_DIR}/UsageTests/Message.tests.cpp
-        ${SELF_TEST_DIR}/UsageTests/Misc.tests.cpp
-        ${SELF_TEST_DIR}/UsageTests/ToStringChrono.tests.cpp
-        ${SELF_TEST_DIR}/UsageTests/ToStringGeneral.tests.cpp
-        ${SELF_TEST_DIR}/UsageTests/ToStringPair.tests.cpp
-        ${SELF_TEST_DIR}/UsageTests/ToStringTuple.tests.cpp
-        ${SELF_TEST_DIR}/UsageTests/ToStringVector.tests.cpp
-        ${SELF_TEST_DIR}/UsageTests/ToStringWhich.tests.cpp
-        ${SELF_TEST_DIR}/UsageTests/Tricky.tests.cpp
-        ${SELF_TEST_DIR}/UsageTests/VariadicMacros.tests.cpp
-        ${SELF_TEST_DIR}/UsageTests/Matchers.tests.cpp
-        )
-CheckFileList(TEST_SOURCES ${SELF_TEST_DIR})
-
-# A set of impl files that just #include a single header
-# Please keep these ordered alphabetically
-set(SURROGATE_SOURCES
-        ${SELF_TEST_DIR}/SurrogateCpps/catch_console_colour.cpp
-        ${SELF_TEST_DIR}/SurrogateCpps/catch_debugger.cpp
-        ${SELF_TEST_DIR}/SurrogateCpps/catch_interfaces_reporter.cpp
-        ${SELF_TEST_DIR}/SurrogateCpps/catch_option.cpp
-        ${SELF_TEST_DIR}/SurrogateCpps/catch_stream.cpp
-        ${SELF_TEST_DIR}/SurrogateCpps/catch_test_case_tracker.cpp
-        ${SELF_TEST_DIR}/SurrogateCpps/catch_test_spec.cpp
-        ${SELF_TEST_DIR}/SurrogateCpps/catch_xmlwriter.cpp
-        )
-CheckFileList(SURROGATE_SOURCES ${SELF_TEST_DIR}/SurrogateCpps)
-
-
-# Please keep these ordered alphabetically
-set(TOP_LEVEL_HEADERS
-        ${HEADER_DIR}/catch.hpp
-        ${HEADER_DIR}/catch_with_main.hpp
-        )
-CheckFileList(TOP_LEVEL_HEADERS ${HEADER_DIR})
-
-# Please keep these ordered alphabetically
-set(EXTERNAL_HEADERS
-        ${HEADER_DIR}/external/clara.hpp
-        )
-CheckFileList(EXTERNAL_HEADERS ${HEADER_DIR}/external)
-
-
-# Please keep these ordered alphabetically
-set(INTERNAL_HEADERS
-        ${HEADER_DIR}/internal/catch_approx.h
-        ${HEADER_DIR}/internal/catch_assertionhandler.h
-        ${HEADER_DIR}/internal/catch_assertioninfo.h
-        ${HEADER_DIR}/internal/catch_assertionresult.h
-        ${HEADER_DIR}/internal/catch_capture.hpp
-        ${HEADER_DIR}/internal/catch_capture_matchers.h
-        ${HEADER_DIR}/internal/catch_clara.h
-        ${HEADER_DIR}/internal/catch_commandline.h
-        ${HEADER_DIR}/internal/catch_common.h
-        ${HEADER_DIR}/internal/catch_compiler_capabilities.h
-        ${HEADER_DIR}/internal/catch_config.hpp
-        ${HEADER_DIR}/internal/catch_console_colour.h
-        ${HEADER_DIR}/internal/catch_context.h
-        ${HEADER_DIR}/internal/catch_debug_console.h
-        ${HEADER_DIR}/internal/catch_debugger.h
-        ${HEADER_DIR}/internal/catch_decomposer.h
-        ${HEADER_DIR}/internal/catch_default_main.hpp
-        ${HEADER_DIR}/internal/catch_enforce.h
-        ${HEADER_DIR}/internal/catch_errno_guard.h
-        ${HEADER_DIR}/internal/catch_exception_translator_registry.h
-        ${HEADER_DIR}/internal/catch_external_interfaces.h
-        ${HEADER_DIR}/internal/catch_fatal_condition.h
-        ${HEADER_DIR}/internal/catch_impl.hpp
-        ${HEADER_DIR}/internal/catch_interfaces_capture.h
-        ${HEADER_DIR}/internal/catch_interfaces_config.h
-        ${HEADER_DIR}/internal/catch_interfaces_exception.h
-        ${HEADER_DIR}/internal/catch_interfaces_registry_hub.h
-        ${HEADER_DIR}/internal/catch_interfaces_reporter.h
-        ${HEADER_DIR}/internal/catch_interfaces_runner.h
-        ${HEADER_DIR}/internal/catch_interfaces_tag_alias_registry.h
-        ${HEADER_DIR}/internal/catch_interfaces_testcase.h
-        ${HEADER_DIR}/internal/catch_leak_detector.h
-        ${HEADER_DIR}/internal/catch_list.h
-        ${HEADER_DIR}/internal/catch_matchers.h
-        ${HEADER_DIR}/internal/catch_matchers_floating.h
-        ${HEADER_DIR}/internal/catch_matchers_generic.hpp
-        ${HEADER_DIR}/internal/catch_matchers_string.h
-        ${HEADER_DIR}/internal/catch_matchers_vector.h
-        ${HEADER_DIR}/internal/catch_message.h
-        ${HEADER_DIR}/internal/catch_objc.hpp
-        ${HEADER_DIR}/internal/catch_objc_arc.hpp
-        ${HEADER_DIR}/internal/catch_option.hpp
-        ${HEADER_DIR}/internal/catch_output_redirect.h
-        ${HEADER_DIR}/internal/catch_platform.h
-        ${HEADER_DIR}/internal/catch_random_number_generator.h
-        ${HEADER_DIR}/internal/catch_reenable_warnings.h
-        ${HEADER_DIR}/internal/catch_reporter_registrars.hpp
-        ${HEADER_DIR}/internal/catch_reporter_registry.h
-        ${HEADER_DIR}/internal/catch_result_type.h
-        ${HEADER_DIR}/internal/catch_run_context.h
-        ${HEADER_DIR}/internal/catch_benchmark.h
-        ${HEADER_DIR}/internal/catch_section.h
-        ${HEADER_DIR}/internal/catch_section_info.h
-        ${HEADER_DIR}/internal/catch_session.h
-        ${HEADER_DIR}/internal/catch_startup_exception_registry.h
-        ${HEADER_DIR}/internal/catch_stream.h
-        ${HEADER_DIR}/internal/catch_stringref.h
-        ${HEADER_DIR}/internal/catch_string_manip.h
-        ${HEADER_DIR}/internal/catch_suppress_warnings.h
-        ${HEADER_DIR}/internal/catch_tag_alias.h
-        ${HEADER_DIR}/internal/catch_tag_alias_autoregistrar.h
-        ${HEADER_DIR}/internal/catch_tag_alias_registry.h
-        ${HEADER_DIR}/internal/catch_test_case_info.h
-        ${HEADER_DIR}/internal/catch_test_case_registry_impl.h
-        ${HEADER_DIR}/internal/catch_test_case_tracker.h
-        ${HEADER_DIR}/internal/catch_test_registry.h
-        ${HEADER_DIR}/internal/catch_test_spec.h
-        ${HEADER_DIR}/internal/catch_test_spec_parser.h
-        ${HEADER_DIR}/internal/catch_text.h
-        ${HEADER_DIR}/internal/catch_timer.h
-        ${HEADER_DIR}/internal/catch_to_string.hpp
-        ${HEADER_DIR}/internal/catch_tostring.h
-        ${HEADER_DIR}/internal/catch_totals.h
-        ${HEADER_DIR}/internal/catch_uncaught_exceptions.h
-        ${HEADER_DIR}/internal/catch_user_interfaces.h
-        ${HEADER_DIR}/internal/catch_version.h
-        ${HEADER_DIR}/internal/catch_wildcard_pattern.h
-        ${HEADER_DIR}/internal/catch_windows_h_proxy.h
-        ${HEADER_DIR}/internal/catch_xmlwriter.h
-        )
-set(IMPL_SOURCES
-        ${HEADER_DIR}/internal/catch_approx.cpp
-        ${HEADER_DIR}/internal/catch_assertionhandler.cpp
-        ${HEADER_DIR}/internal/catch_assertionresult.cpp
-        ${HEADER_DIR}/internal/catch_benchmark.cpp
-        ${HEADER_DIR}/internal/catch_capture_matchers.cpp
-        ${HEADER_DIR}/internal/catch_commandline.cpp
-        ${HEADER_DIR}/internal/catch_common.cpp
-        ${HEADER_DIR}/internal/catch_config.cpp
-        ${HEADER_DIR}/internal/catch_console_colour.cpp
-        ${HEADER_DIR}/internal/catch_context.cpp
-        ${HEADER_DIR}/internal/catch_debug_console.cpp
-        ${HEADER_DIR}/internal/catch_debugger.cpp
-        ${HEADER_DIR}/internal/catch_decomposer.cpp
-        ${HEADER_DIR}/internal/catch_errno_guard.cpp
-        ${HEADER_DIR}/internal/catch_exception_translator_registry.cpp
-        ${HEADER_DIR}/internal/catch_fatal_condition.cpp
-        ${HEADER_DIR}/internal/catch_interfaces_capture.cpp
-        ${HEADER_DIR}/internal/catch_interfaces_config.cpp
-        ${HEADER_DIR}/internal/catch_interfaces_exception.cpp
-        ${HEADER_DIR}/internal/catch_interfaces_registry_hub.cpp
-        ${HEADER_DIR}/internal/catch_interfaces_runner.cpp
-        ${HEADER_DIR}/internal/catch_interfaces_testcase.cpp
-        ${HEADER_DIR}/internal/catch_list.cpp
-        ${HEADER_DIR}/internal/catch_leak_detector.cpp
-        ${HEADER_DIR}/internal/catch_matchers.cpp
-        ${HEADER_DIR}/internal/catch_matchers_floating.cpp
-        ${HEADER_DIR}/internal/catch_matchers_generic.cpp
-        ${HEADER_DIR}/internal/catch_matchers_string.cpp
-        ${HEADER_DIR}/internal/catch_message.cpp
-        ${HEADER_DIR}/internal/catch_output_redirect.cpp
-        ${HEADER_DIR}/internal/catch_registry_hub.cpp
-        ${HEADER_DIR}/internal/catch_interfaces_reporter.cpp
-        ${HEADER_DIR}/internal/catch_random_number_generator.cpp
-        ${HEADER_DIR}/internal/catch_reporter_registry.cpp
-        ${HEADER_DIR}/internal/catch_result_type.cpp
-        ${HEADER_DIR}/internal/catch_run_context.cpp
-        ${HEADER_DIR}/internal/catch_section.cpp
-        ${HEADER_DIR}/internal/catch_section_info.cpp
-        ${HEADER_DIR}/internal/catch_session.cpp
-        ${HEADER_DIR}/internal/catch_startup_exception_registry.cpp
-        ${HEADER_DIR}/internal/catch_stream.cpp
-        ${HEADER_DIR}/internal/catch_stringref.cpp
-        ${HEADER_DIR}/internal/catch_string_manip.cpp
-        ${HEADER_DIR}/internal/catch_tag_alias.cpp
-        ${HEADER_DIR}/internal/catch_tag_alias_autoregistrar.cpp
-        ${HEADER_DIR}/internal/catch_tag_alias_registry.cpp
-        ${HEADER_DIR}/internal/catch_test_case_info.cpp
-        ${HEADER_DIR}/internal/catch_test_case_registry_impl.cpp
-        ${HEADER_DIR}/internal/catch_test_case_tracker.cpp
-        ${HEADER_DIR}/internal/catch_test_registry.cpp
-        ${HEADER_DIR}/internal/catch_test_spec.cpp
-        ${HEADER_DIR}/internal/catch_test_spec_parser.cpp
-        ${HEADER_DIR}/internal/catch_timer.cpp
-        ${HEADER_DIR}/internal/catch_tostring.cpp
-        ${HEADER_DIR}/internal/catch_totals.cpp
-        ${HEADER_DIR}/internal/catch_uncaught_exceptions.cpp
-        ${HEADER_DIR}/internal/catch_version.cpp
-        ${HEADER_DIR}/internal/catch_wildcard_pattern.cpp
-        ${HEADER_DIR}/internal/catch_xmlwriter.cpp
-        )
-set(INTERNAL_FILES ${IMPL_SOURCES} ${INTERNAL_HEADERS})
-CheckFileList(INTERNAL_FILES ${HEADER_DIR}/internal)
-
-# Please keep these ordered alphabetically
-set(REPORTER_HEADERS
-        ${HEADER_DIR}/reporters/catch_reporter_automake.hpp
-        ${HEADER_DIR}/reporters/catch_reporter_bases.hpp
-        ${HEADER_DIR}/reporters/catch_reporter_compact.h
-        ${HEADER_DIR}/reporters/catch_reporter_console.h
-        ${HEADER_DIR}/reporters/catch_reporter_junit.h
-        ${HEADER_DIR}/reporters/catch_reporter_listening.h
-        ${HEADER_DIR}/reporters/catch_reporter_tap.hpp
-        ${HEADER_DIR}/reporters/catch_reporter_teamcity.hpp
-        ${HEADER_DIR}/reporters/catch_reporter_xml.h
-        )
-set(REPORTER_SOURCES
-        ${HEADER_DIR}/reporters/catch_reporter_bases.cpp
-        ${HEADER_DIR}/reporters/catch_reporter_compact.cpp
-        ${HEADER_DIR}/reporters/catch_reporter_console.cpp
-        ${HEADER_DIR}/reporters/catch_reporter_junit.cpp
-        ${HEADER_DIR}/reporters/catch_reporter_listening.cpp
-        ${HEADER_DIR}/reporters/catch_reporter_xml.cpp
-        )
-set(REPORTER_FILES ${REPORTER_HEADERS} ${REPORTER_SOURCES})
-CheckFileList(REPORTER_FILES ${HEADER_DIR}/reporters)
-
-# Specify the headers, too, so CLion recognises them as project files
-set(HEADERS
-        ${TOP_LEVEL_HEADERS}
-        ${EXTERNAL_HEADERS}
-        ${INTERNAL_HEADERS}
-        ${REPORTER_HEADERS}
-        )
-
-# Provide some groupings for IDEs
-SOURCE_GROUP("Tests" FILES ${TEST_SOURCES})
-SOURCE_GROUP("Surrogates" FILES ${SURROGATE_SOURCES})
-
-
-# Projects consuming Catch via ExternalProject_Add might want to use install step
-# without building all of our selftests.
-
-if(DEFINED NO_SELFTEST)
-    message(DEPRECATION "*** CMake option NO_SELFTEST is deprecated; use BUILD_TESTING instead")
-    if (NO_SELFTEST)
-        set(BUILD_TESTING OFF CACHE BOOL "Disable Catch2 internal testsuite" FORCE)
-    else()
-        set(BUILD_TESTING ON CACHE BOOL "Disable Catch2 internal testsuite" FORCE)
+if (BUILD_TESTING AND CATCH_BUILD_TESTING AND NOT_SUBPROJECT)
+    find_package(PythonInterp)
+    if (NOT PYTHONINTERP_FOUND)
+        message(FATAL_ERROR "Python not found, but required for tests")
     endif()
+    add_subdirectory(projects)
 endif()
 
-include(CTest)
-
-if (BUILD_TESTING AND NOT_SUBPROJECT)
-    add_executable(SelfTest ${TEST_SOURCES} ${IMPL_SOURCES} ${REPORTER_SOURCES} ${SURROGATE_SOURCES} ${HEADERS})
-    target_include_directories(SelfTest PRIVATE ${HEADER_DIR})
-
-    if(USE_CPP14)
-        message(STATUS "Enabling C++14")
-        set_property(TARGET SelfTest PROPERTY CXX_STANDARD 14)
-    else()
-        message(STATUS "Enabling C++11")
-        set_property(TARGET SelfTest PROPERTY CXX_STANDARD 11)
-    endif()
-
-    set_property(TARGET SelfTest PROPERTY CXX_STANDARD_REQUIRED ON)
-    set_property(TARGET SelfTest PROPERTY CXX_EXTENSIONS OFF)
+if(CATCH_BUILD_EXAMPLES)
+    add_subdirectory(examples)
+endif()
 
-    if (CATCH_ENABLE_COVERAGE)
-        set(ENABLE_COVERAGE ON CACHE BOOL "Enable coverage build." FORCE)
-        list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake")
-        find_package(codecov)
-        add_coverage(SelfTest)
-        list(APPEND LCOV_REMOVE_PATTERNS "'/usr/*'")
-        coverage_evaluate()
-    endif()
+if(CATCH_BUILD_EXTRA_TESTS)
+    add_subdirectory(projects/ExtraTests)
+endif()
 
-    # Add per compiler options
-    if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang|GNU" )
-        target_compile_options( SelfTest PRIVATE -Wall -Wextra -Wunreachable-code -Wpedantic)
-        if (CATCH_ENABLE_WERROR)
-            target_compile_options( SelfTest PRIVATE -Werror)
-        endif()
-    endif()
-    # Clang specific options go here
-    if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
-        target_compile_options( SelfTest PRIVATE -Wweak-vtables -Wexit-time-destructors -Wglobal-constructors -Wmissing-noreturn )
-    endif()
-    if ( CMAKE_CXX_COMPILER_ID MATCHES "MSVC" )
-		STRING(REGEX REPLACE "/W[0-9]" "/W4" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) # override default warning level
-        target_compile_options( SelfTest PRIVATE /w44265 /w44061 /w44062 )
-        if (CATCH_ENABLE_WERROR)
-            target_compile_options( SelfTest PRIVATE /WX)
-        endif()
-        # Force MSVC to consider everything as encoded in utf-8
-        target_compile_options( SelfTest PRIVATE /utf-8 )
-    endif()
+# add catch as a 'linkable' target
+add_library(Catch2 INTERFACE)
+
+
+
+# depend on some obvious c++11 features so the dependency is transitively added dependents
+target_compile_features(Catch2
+  INTERFACE
+    cxx_alignas
+    cxx_alignof
+    cxx_attributes
+    cxx_auto_type
+    cxx_constexpr
+    cxx_defaulted_functions
+    cxx_deleted_functions
+    cxx_final
+    cxx_lambdas
+    cxx_noexcept
+    cxx_override
+    cxx_range_for
+    cxx_rvalue_references
+    cxx_static_assert
+    cxx_strong_enums
+    cxx_trailing_return_types
+    cxx_unicode_literals
+    cxx_user_literals
+    cxx_variadic_macros
+)
+
+target_include_directories(Catch2
+  INTERFACE
+    $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/single_include>
+    $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
+)
 
+# provide a namespaced alias for clients to 'link' against if catch is included as a sub-project
+add_library(Catch2::Catch2 ALIAS Catch2)
+
+# Only perform the installation steps when Catch is not being used as
+# a subproject via `add_subdirectory`, or the destinations will break,
+# see https://github.com/catchorg/Catch2/issues/1373
+if (NOT_SUBPROJECT)
+    set(CATCH_CMAKE_CONFIG_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/Catch2")
+
+    configure_package_config_file(
+        ${CMAKE_CURRENT_LIST_DIR}/CMake/Catch2Config.cmake.in
+        ${CMAKE_CURRENT_BINARY_DIR}/Catch2Config.cmake
+        INSTALL_DESTINATION
+          ${CATCH_CMAKE_CONFIG_DESTINATION}
+    )
 
-    # configure unit tests via CTest
-    include(CTest)
-    add_test(NAME RunTests COMMAND $<TARGET_FILE:SelfTest>)
 
-    add_test(NAME ListTests COMMAND $<TARGET_FILE:SelfTest> --list-tests --verbosity high)
-    set_tests_properties(ListTests PROPERTIES 
-        PASS_REGULAR_EXPRESSION "[0-9]+ test cases"
-        FAIL_REGULAR_EXPRESSION "Hidden Test"
+    # create and install an export set for catch target as Catch2::Catch
+    install(
+      TARGETS
+        Catch2
+      EXPORT
+        Catch2Targets
+      DESTINATION
+        ${CMAKE_INSTALL_LIBDIR}
     )
 
-    add_test(NAME ListTags COMMAND $<TARGET_FILE:SelfTest> --list-tags)
-    set_tests_properties(ListTags PROPERTIES 
-        PASS_REGULAR_EXPRESSION "[0-9]+ tags" 
-        FAIL_REGULAR_EXPRESSION "[.]")
 
-    add_test(NAME ListReporters COMMAND $<TARGET_FILE:SelfTest> --list-reporters)
-    set_tests_properties(ListReporters PROPERTIES PASS_REGULAR_EXPRESSION "Available reporters:")
-
-    add_test(NAME ListTestNamesOnly COMMAND $<TARGET_FILE:SelfTest> --list-test-names-only)
-    set_tests_properties(ListTestNamesOnly PROPERTIES 
-        PASS_REGULAR_EXPRESSION "Regex string matcher"
-        FAIL_REGULAR_EXPRESSION "Hidden Test")
+    install(
+      EXPORT
+        Catch2Targets
+      NAMESPACE
+        Catch2::
+      DESTINATION
+        ${CATCH_CMAKE_CONFIG_DESTINATION}
+    )
 
-    add_test(NAME NoAssertions COMMAND $<TARGET_FILE:SelfTest> -w NoAssertions)
-    set_tests_properties(NoAssertions PROPERTIES PASS_REGULAR_EXPRESSION "No assertions in test case")
+    # By default, FooConfigVersion is tied to architecture that it was
+    # generated on. Because Catch2 is header-only, it is arch-independent
+    # and thus Catch2ConfigVersion should not be tied to the architecture
+    # it was generated on.
+    #
+    # CMake does not provide a direct customization point for this in
+    # `write_basic_package_version_file`, but it can be accomplished
+    # indirectly by temporarily undefining `CMAKE_SIZEOF_VOID_P`.
+    set(CATCH2_CMAKE_SIZEOF_VOID_P ${CMAKE_SIZEOF_VOID_P})
+    unset(CMAKE_SIZEOF_VOID_P)
+    write_basic_package_version_file(
+      "${CMAKE_CURRENT_BINARY_DIR}/Catch2ConfigVersion.cmake"
+      COMPATIBILITY
+        SameMajorVersion
+    )
+    set(CMAKE_SIZEOF_VOID_P ${CATCH2_CMAKE_SIZEOF_VOID_P})
 
-    add_test(NAME NoTest COMMAND $<TARGET_FILE:SelfTest> -w NoTests "___nonexistent_test___")
-    set_tests_properties(NoTest PROPERTIES PASS_REGULAR_EXPRESSION "No test cases matched")
+    install(
+      DIRECTORY
+        "single_include/"
+      DESTINATION
+        "${CMAKE_INSTALL_INCLUDEDIR}"
+    )
 
-    # AppVeyor has a Python 2.7 in path, but doesn't have .py files as autorunnable
-    add_test(NAME ApprovalTests COMMAND python ${CMAKE_CURRENT_SOURCE_DIR}/scripts/approvalTests.py $<TARGET_FILE:SelfTest>)
-    set_tests_properties(ApprovalTests PROPERTIES FAIL_REGULAR_EXPRESSION "Results differed")
+    install(
+      FILES
+        "${CMAKE_CURRENT_BINARY_DIR}/Catch2Config.cmake"
+        "${CMAKE_CURRENT_BINARY_DIR}/Catch2ConfigVersion.cmake"
+      DESTINATION
+        ${CATCH_CMAKE_CONFIG_DESTINATION}
+    )
 
-    if (CATCH_USE_VALGRIND)
-        add_test(NAME ValgrindRunTests COMMAND valgrind --leak-check=full --error-exitcode=1 $<TARGET_FILE:SelfTest>)
-        add_test(NAME ValgrindListTests COMMAND valgrind --leak-check=full --error-exitcode=1 $<TARGET_FILE:SelfTest> --list-tests --verbosity high)
-        set_tests_properties(ValgrindListTests PROPERTIES PASS_REGULAR_EXPRESSION "definitely lost: 0 bytes in 0 blocks")
-        add_test(NAME ValgrindListTags COMMAND valgrind --leak-check=full --error-exitcode=1 $<TARGET_FILE:SelfTest> --list-tags)
-        set_tests_properties(ValgrindListTags PROPERTIES PASS_REGULAR_EXPRESSION "definitely lost: 0 bytes in 0 blocks")
+    # Install documentation
+    if(CATCH_INSTALL_DOCS)
+      install(
+        DIRECTORY
+          docs/
+        DESTINATION
+          "${CMAKE_INSTALL_DOCDIR}"
+      )
     endif()
 
-endif() # !NO_SELFTEST
-
-
-if(CATCH_BUILD_EXAMPLES)
-    add_subdirectory(examples)
-endif()
-
-install(DIRECTORY "single_include/" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/catch")
-
-install(DIRECTORY docs/ DESTINATION "${CMAKE_INSTALL_DOCDIR}")
+    if(CATCH_INSTALL_HELPERS)
+    # Install CMake scripts
+    install(
+      FILES
+        "contrib/ParseAndAddCatchTests.cmake"
+        "contrib/Catch.cmake"
+        "contrib/CatchAddTests.cmake"
+      DESTINATION
+        ${CATCH_CMAKE_CONFIG_DESTINATION}
+    )
 
-## Provide some pkg-config integration
-# Don't bother on Windows
-if(NOT WIN32 OR NOT CMAKE_HOST_SYSTEM_NAME MATCHES Windows)
+    # Install debugger helpers
+    install(
+      FILES
+        "contrib/gdbinit"
+        "contrib/lldbinit"
+      DESTINATION
+        ${CMAKE_INSTALL_DATAROOTDIR}/Catch2
+    )
+    endif()
 
+    ## Provide some pkg-config integration
     set(PKGCONFIG_INSTALL_DIR
         "${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig"
-        CACHE PATH "Path where catch.pc is installed"
+        CACHE PATH "Path where catch2.pc is installed"
+    )
+    configure_file(
+      ${CMAKE_CURRENT_SOURCE_DIR}/CMake/catch2.pc.in
+      ${CMAKE_CURRENT_BINARY_DIR}/catch2.pc
+      @ONLY
+    )
+    install(
+      FILES
+        "${CMAKE_CURRENT_BINARY_DIR}/catch2.pc"
+      DESTINATION
+        ${PKGCONFIG_INSTALL_DIR}
     )
 
-    configure_file(${CMAKE_CURRENT_SOURCE_DIR}/catch.pc.in ${CMAKE_CURRENT_BINARY_DIR}/catch.pc @ONLY)
-    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/catch.pc DESTINATION ${PKGCONFIG_INSTALL_DIR})
-
-endif()
-
-# add catch as a 'linkable' target
-add_library(Catch INTERFACE)
-
-# depend on some obvious c++11 features so the dependency is transitively added dependants
-target_compile_features(Catch INTERFACE cxx_auto_type cxx_constexpr cxx_noexcept)
-
-target_include_directories(Catch
-	INTERFACE
-		$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/single_include>
-		$<INSTALL_INTERFACE:include/catch>
-		$<INSTALL_INTERFACE:include>)
-
-# provide a namespaced alias for clients to 'link' against if catch is included as a sub-project
-add_library(Catch2::Catch ALIAS Catch)
-
-set(CATCH_CMAKE_CONFIG_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/Catch2")
-
-# create and install an export set for catch target as Catch2::Catch
-install(TARGETS Catch EXPORT Catch2Config DESTINATION ${CMAKE_INSTALL_LIBDIR})
-
-install(EXPORT Catch2Config
-	NAMESPACE Catch2::
-	DESTINATION ${CATCH_CMAKE_CONFIG_DESTINATION})
-
-# install Catch2ConfigVersion.cmake file to handle versions in find_package
-include(CMakePackageConfigHelpers)
-
-write_basic_package_version_file(
-	"${CMAKE_CURRENT_BINARY_DIR}/Catch2ConfigVersion.cmake"
-	COMPATIBILITY SameMajorVersion)
-
-install(FILES
-	"${CMAKE_CURRENT_BINARY_DIR}/Catch2ConfigVersion.cmake"
-	DESTINATION ${CATCH_CMAKE_CONFIG_DESTINATION})
+endif(NOT_SUBPROJECT)
diff --git a/packages/Catch2/README.md b/packages/Catch2/README.md
index 7defcd556..73162bbf4 100644
--- a/packages/Catch2/README.md
+++ b/packages/Catch2/README.md
@@ -5,9 +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/u7qF77qgv9YqOr55)
+[![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://wandbox.org/permlink/E0msqwbW7U4PVbHn)
+[![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.2.3/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.4.1/catch.hpp">The latest version of the single header can be downloaded directly using this link</a>
 
 ## Catch2 is released!
 
@@ -32,5 +34,5 @@ This documentation comprises these three parts:
 
 ## More
 * Issues and bugs can be raised on the [Issue tracker on GitHub](https://github.com/catchorg/Catch2/issues)
-* For discussion or questions please use [the dedicated Google Groups forum](https://groups.google.com/forum/?fromgroups#!forum/catch-forum)
+* For discussion or questions please use [the dedicated Google Groups forum](https://groups.google.com/forum/?fromgroups#!forum/catch-forum) or our [Discord](https://discord.gg/4CWS9zD)
 * See [who else is using Catch2](docs/opensource-users.md#top)
diff --git a/packages/Catch2/appveyor.yml b/packages/Catch2/appveyor.yml
index 0e97589b5..53f5b395c 100644
--- a/packages/Catch2/appveyor.yml
+++ b/packages/Catch2/appveyor.yml
@@ -33,8 +33,6 @@ environment:
 
 
 matrix:
-    allow_failures:
-        - os: Visual Studio 2017
     exclude:
         - os: Visual Studio 2015
           additional_flags: "/permissive- /std:c++latest"
diff --git a/packages/Catch2/catch.pc.in b/packages/Catch2/catch.pc.in
deleted file mode 100644
index c2496d29f..000000000
--- a/packages/Catch2/catch.pc.in
+++ /dev/null
@@ -1,6 +0,0 @@
-includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
-
-Name: Catch
-Description: Testing library for C++
-Version: @Catch2_VERSION@
-Cflags: -I${includedir} -I${includedir}/catch
diff --git a/packages/Catch2/conanfile.py b/packages/Catch2/conanfile.py
index 716ca420e..19b2c65e6 100644
--- a/packages/Catch2/conanfile.py
+++ b/packages/Catch2/conanfile.py
@@ -1,19 +1,31 @@
 #!/usr/bin/env python
-from conans import ConanFile
+from conans import ConanFile, CMake
 
 
 class CatchConan(ConanFile):
     name = "Catch"
-    version = "2.2.3"
+    version = "2.4.1"
     description = "A modern, C++-native, header-only, framework for unit-tests, TDD and BDD"
     author = "philsquared"
     generators = "cmake"
-    exports_sources = "single_include/*"
-    url = "https://github.com/philsquared/Catch"
+    # Only needed until conan 1.5 is released
+    settings = "compiler", "arch"
+    exports_sources = "single_include/*", "CMakeLists.txt", "CMake/catch2.pc.in", "LICENSE.txt"
+    url = "https://github.com/catchorg/Catch2"
     license = "Boost Software License - Version 1.0. http://www.boost.org/LICENSE_1_0.txt"
 
+    def build(self):
+        pass
+
     def package(self):
-        self.copy(pattern="catch.hpp", src="single_include", dst="include")
+        cmake = CMake(self)
+        cmake.definitions["BUILD_TESTING"] = "OFF"
+        cmake.definitions["CATCH_INSTALL_DOCS"] = "OFF"
+        cmake.definitions["CATCH_INSTALL_HELPERS"] = "ON"
+        cmake.configure()
+        cmake.install()
+
+        self.copy(pattern="LICENSE.txt", dst="licenses")
 
     def package_id(self):
-            self.info.header_only()
+        self.info.header_only()
diff --git a/packages/Catch2/contrib/ParseAndAddCatchTests.cmake b/packages/Catch2/contrib/ParseAndAddCatchTests.cmake
index cb2846d0a..85c06a0dd 100644
--- a/packages/Catch2/contrib/ParseAndAddCatchTests.cmake
+++ b/packages/Catch2/contrib/ParseAndAddCatchTests.cmake
@@ -143,6 +143,9 @@ function(ParseFile SourceFile TestTarget)
             endif()
             string(REPLACE "]" ";" Tags "${Tags}")
             string(REPLACE "[" "" Tags "${Tags}")
+        else()
+          # unset tags variable from previous loop
+          unset(Tags)
         endif()
 
         list(APPEND Labels ${Tags})
diff --git a/packages/Catch2/docs/Readme.md b/packages/Catch2/docs/Readme.md
index be7d1cd12..908755181 100644
--- a/packages/Catch2/docs/Readme.md
+++ b/packages/Catch2/docs/Readme.md
@@ -12,6 +12,7 @@ Writing tests:
 * [Test fixtures](test-fixtures.md#top)
 * [Reporters](reporters.md#top)
 * [Event Listeners](event-listeners.md#top)
+* [Data Generators](generators.md#top)
 
 Fine tuning:
 * [Supplying your own main()](own-main.md#top)
@@ -20,7 +21,10 @@ Fine tuning:
 
 Running:
 * [Command line](command-line.md#top)
-* [CI and Build system integration](build-systems.md#top)
+
+Odds and ends:
+* [CMake integration](cmake-integration.md#top)
+* [CI and other miscellaneous pieces](ci-and-misc.md#top)
 
 FAQ:
 * [Why are my tests slow to compile?](slow-compiles.md#top)
diff --git a/packages/Catch2/docs/assertions.md b/packages/Catch2/docs/assertions.md
index 90c0856cb..900fd52c0 100644
--- a/packages/Catch2/docs/assertions.md
+++ b/packages/Catch2/docs/assertions.md
@@ -55,33 +55,45 @@ This expression is too complex because of the `||` operator. If you want to chec
 
 When comparing floating point numbers - especially if at least one of them has been computed - great care must be taken to allow for rounding errors and inexact representations.
 
-Catch provides a way to perform tolerant comparisons of floating point values through use of a wrapper class called ```Approx```. ```Approx``` can be used on either side of a comparison expression. It overloads the comparisons operators to take a tolerance into account. Here's a simple example:
+Catch provides a way to perform tolerant comparisons of floating point values through use of a wrapper class called `Approx`. `Approx` can be used on either side of a comparison expression. It overloads the comparisons operators to take a tolerance into account. Here's a simple example:
 
-```
+```cpp
 REQUIRE( performComputation() == Approx( 2.1 ) );
 ```
 
-This way `Approx` is constructed with reasonable defaults, covering most simple cases of rounding errors. If these are insufficient, each `Approx` instance has 3 tuning knobs, that can be used to customize it for your computation.
+Catch also provides a UDL for `Approx`; `_a`. It resides in
+the `Catch::literals` namespace and can be used like so:
+```cpp
+using namespace Catch::literals;
+REQUIRE( performComputation() == 2.1_a );
+```
+
+`Approx` is constructed with defaults that should cover most simple cases.
+For the more complex cases, `Approx` provides 3 customization points:
 
-* __epsilon__ - epsilon serves to set the percentage by which a result can be erroneous, before it is rejected. By default set to `std::numeric_limits<float>::epsilon()*100`.
-* __margin__ - margin serves to set the the absolute value by which a result can be erroneous before it is rejected. By default set to `0.0`.
-* __scale__ - scale serves to adjust the epsilon's multiplicator. By default set to `0.0`.
+* __epsilon__ - epsilon serves to set the coefficient by which a result
+can differ from `Approx`'s value before it is rejected.
+_By default set to `std::numeric_limits<float>::epsilon()*100`._
+* __margin__ - margin serves to set the the absolute value by which
+a result can differ from `Approx`'s value before it is rejected.
+_By default set to `0.0`._
+* __scale__ - scale is used to change the magnitude of `Approx` for relative check.
+_By default set to `0.0`._
 
 #### epsilon example
 ```cpp
 Approx target = Approx(100).epsilon(0.01);
 100.0 == target; // Obviously true
 200.0 == target; // Obviously still false
-100.5 == target; // True, because we set target to allow up to 1% error
+100.5 == target; // True, because we set target to allow up to 1% difference
 ```
 
 #### margin example
-_Margin check is used only if the relative (epsilon and scale based) check fails._
 ```cpp
 Approx target = Approx(100).margin(5);
 100.0 == target; // Obviously true
 200.0 == target; // Obviously still false
-104.0 == target; // True, because we set target to allow absolute error up to 5
+104.0 == target; // True, because we set target to allow absolute difference of at most 5
 ```
 
 #### scale
diff --git a/packages/Catch2/docs/build-systems.md b/packages/Catch2/docs/ci-and-misc.md
similarity index 59%
rename from packages/Catch2/docs/build-systems.md
rename to packages/Catch2/docs/ci-and-misc.md
index 2873bc62a..8c3308725 100644
--- a/packages/Catch2/docs/build-systems.md
+++ b/packages/Catch2/docs/ci-and-misc.md
@@ -1,6 +1,13 @@
 <a id="top"></a>
-# CI and build system integration
+# CI and other odd pieces
 
+**Contents**<br>
+[Continuous Integration systems](#continuous-integration-systems)<br>
+[Other reporters](#other-reporters)<br>
+[Low-level tools](#low-level-tools)<br>
+[CMake](#cmake)<br>
+
+This page talks about how Catch integrates with Continuous Integration 
 Build Systems may refer to low-level tools, like CMake, or larger systems that run on servers, like Jenkins or TeamCity. This page will talk about both.
 
 ## Continuous Integration systems
@@ -71,104 +78,30 @@ Catch offers prototypal support for being included in precompiled headers, but b
   * include "catch.hpp" again
 
 
-### CMake
-
-In general we recommend "vendoring" Catch's single-include releases inside your own repository. If you do this, the following example shows a minimal CMake project:
-```CMake
-cmake_minimum_required(VERSION 3.0)
-
-project(cmake_test)
-
-# Prepare "Catch" library for other executables
-set(CATCH_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/catch)
-add_library(Catch INTERFACE)
-target_include_directories(Catch INTERFACE ${CATCH_INCLUDE_DIR})
-
-# Make test executable
-set(TEST_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp)
-add_executable(tests ${TEST_SOURCES})
-target_link_libraries(tests Catch)
-```
-Note that it assumes that the path to the Catch's header is `catch/catch.hpp` from the `CMakeLists.txt` file.
-
-
-You can also use the following CMake snippet to automatically fetch the entire Catch repository from github and configure it as an external project:
-```CMake
-cmake_minimum_required(VERSION 2.8.8)
-project(catch_builder CXX)
-include(ExternalProject)
-find_package(Git REQUIRED)
-
-ExternalProject_Add(
-    catch
-    PREFIX ${CMAKE_BINARY_DIR}/catch
-    GIT_REPOSITORY https://github.com/philsquared/Catch.git
-    TIMEOUT 10
-    UPDATE_COMMAND ${GIT_EXECUTABLE} pull
-    CONFIGURE_COMMAND ""
-    BUILD_COMMAND ""
-    INSTALL_COMMAND ""
-    LOG_DOWNLOAD ON
-   )
-
-# Expose required variable (CATCH_INCLUDE_DIR) to parent scope
-ExternalProject_Get_Property(catch source_dir)
-set(CATCH_INCLUDE_DIR ${source_dir}/single_include CACHE INTERNAL "Path to include folder for Catch")
-```
-
-If you put it in, e.g., `${PROJECT_SRC_DIR}/${EXT_PROJECTS_DIR}/catch/`, you can use it in your project by adding the following to your root CMake file:
+### CodeCoverage module (GCOV, LCOV...)
 
-```CMake
-# Includes Catch in the project:
-add_subdirectory(${EXT_PROJECTS_DIR}/catch)
-include_directories(${CATCH_INCLUDE_DIR} ${COMMON_INCLUDES})
-enable_testing(true)  # Enables unit-testing.
-```
+If you are using GCOV tool to get testing coverage of your code, and are not sure how to integrate it with CMake and Catch, there should be an external example over at https://github.com/fkromer/catch_cmake_coverage
 
-The advantage of this approach is that you can always automatically update Catch to the latest release. The disadvantage is that it means bringing in lot more than you need.
 
+### pkg-config
 
-### Automatic test registration
-We provide 2 CMake scripts that can automatically register Catch-based
-tests with CTest,
-  * `contrib/ParseAndAddCatchTests.cmake`
-  * `contrib/CatchAddTests.cmake`
+Catch2 provides a rudimentary pkg-config integration, by registering itself
+under the name `catch2`. This means that after Catch2 is installed, you
+can use `pkg-config` to get its include path: `pkg-config --cflags catch2`.
 
-The first is based on parsing the test implementation files, and attempts
-to register all `TEST_CASE`s using their tags as labels. This means that
-these:
+### gdb and lldb scripts
 
-```cpp
-TEST_CASE("Test1", "[unit]") {
-    int a = 1;
-    int b = 2;
-    REQUIRE(a == b);
-}
-
-TEST_CASE("Test2") {
-    int a = 1;
-    int b = 2;
-    REQUIRE(a == b);
-}
-
-TEST_CASE("Test3", "[a][b][c]") {
-    int a = 1;
-    int b = 2;
-    REQUIRE(a == b);
-}
-```
-would be registered as 3 tests, `Test1`, `Test2` and `Test3`,
-and 4 CTest labels would be created, `a`, `b`, `c` and `unit`.
+Catch2's `contrib` folder also contains two simple debugger scripts,
+`gdbinit` for `gdb` and `lldbinit` for `lldb`. If loaded into their
+respective debugger, these will tell it to step over Catch2's internals
+when stepping through code.
 
 
-The second is based on parsing the output of a Catch binary given
-`--list-test-names-only`. This means that it deals with inactive
-(e.g. commented-out) tests better, but requires CMake 3.10 for full
-functionality.
+## CMake
 
-### CodeCoverage module (GCOV, LCOV...)
+[As it has been getting kinda long, the documentation of Catch2's
+integration with CMake has been moved to its own page.](cmake-integration.md#top)
 
-If you are using GCOV tool to get testing coverage of your code, and are not sure how to integrate it with CMake and Catch, there should be an external example over at https://github.com/fkromer/catch_cmake_coverage
 
 ---
 
diff --git a/packages/Catch2/docs/cmake-integration.md b/packages/Catch2/docs/cmake-integration.md
new file mode 100644
index 000000000..a075c040f
--- /dev/null
+++ b/packages/Catch2/docs/cmake-integration.md
@@ -0,0 +1,216 @@
+<a id="top"></a>
+# CMake integration
+
+**Contents**<br>
+[CMake target](#cmake-target)<br>
+[Automatic test registration](#automatic-test-registration)<br>
+[CMake project options](#cmake-project-options)<br>
+[Installing Catch2 from git repository](#installing-catch2-from-git-repository)<br>
+
+Because we use CMake to build Catch2, we also provide a couple of
+integration points for our users.
+
+1) Catch2 exports a (namespaced) CMake target
+2) Catch2's repository contains CMake scripts for automatic registration
+of `TEST_CASE`s in CTest
+
+## CMake target
+
+Catch2's CMake build exports an interface target `Catch2::Catch2`. Linking
+against it will add the proper include path and all necessary capabilities
+to the resulting binary.
+
+This means that if Catch2 has been installed on the system, it should be
+enough to do:
+```cmake
+find_package(Catch2 REQUIRED)
+target_link_libraries(tests Catch2::Catch2)
+```
+
+
+This target is also provided when Catch2 is used as a subdirectory.
+Assuming that Catch2 has been cloned to `lib/Catch2`:
+```cmake
+add_subdirectory(lib/Catch2)
+target_link_libraries(tests Catch2::Catch2)
+```
+
+## Automatic test registration
+
+Catch2's repository also contains two CMake scripts that help users
+with automatically registering their `TEST_CASE`s with CTest. They
+can be found in the `contrib` folder, and are
+
+1) `Catch.cmake` (and its dependency `CatchAddTests.cmake`)
+2) `ParseAndAddCatchTests.cmake`
+
+If Catch2 has been installed in system, both of these can be used after
+doing `find_package(Catch2 REQUIRED)`. Otherwise you need to add them
+to your CMake module path.
+
+### `Catch.cmake` and `AddCatchTests.cmake`
+
+`Catch.cmake` provides function `catch_discover_tests` to get tests from
+a target. This function works by running the resulting executable with
+`--list-test-names-only` flag, and then parsing the output to find all
+existing tests.
+
+#### Usage
+```cmake
+cmake_minimum_required(VERSION 3.5)
+
+project(baz LANGUAGES CXX VERSION 0.0.1)
+
+find_package(Catch2 REQUIRED)
+add_executable(foo test.cpp)
+target_link_libraries(foo Catch2::Catch2)
+
+include(CTest)
+include(Catch)
+catch_discover_tests(foo)
+```
+
+
+#### Customization
+`catch_discover_tests` can be given several extra argumets:
+```cmake
+catch_discover_tests(target
+                     [TEST_SPEC arg1...]
+                     [EXTRA_ARGS arg1...]
+                     [WORKING_DIRECTORY dir]
+                     [TEST_PREFIX prefix]
+                     [TEST_SUFFIX suffix]
+                     [PROPERTIES name1 value1...]
+                     [TEST_LIST var]
+)
+```
+
+* `TEST_SPEC arg1...`
+
+Specifies test cases, wildcarded test cases, tags and tag expressions to
+pass to the Catch executable alongside the `--list-test-names-only` flag.
+
+
+* `EXTRA_ARGS arg1...`
+
+Any extra arguments to pass on the command line to each test case.
+
+
+* `WORKING_DIRECTORY dir`
+
+Specifies the directory in which to run the discovered test cases.  If this
+option is not provided, the current binary directory is used.
+
+
+* `TEST_PREFIX prefix`
+
+Specifies a _prefix_ to be added to the name of each discovered test case.
+This can be useful when the same test executable is being used in multiple
+calls to `catch_discover_tests()`, with different `TEST_SPEC` or `EXTRA_ARGS`.
+
+
+* `TEST_SUFFIX suffix`
+
+Same as `TEST_PREFIX`, except it specific the _suffix_ for the test names.
+Both `TEST_PREFIX` and `TEST_SUFFIX` can be specified at the same time.
+
+
+* `PROPERTIES name1 value1...`
+
+Specifies additional properties to be set on all tests discovered by this
+invocation of `catch_discover_tests`.
+
+
+* `TEST_LIST var`
+
+Make the list of tests available in the variable `var`, rather than the
+default `<target>_TESTS`.  This can be useful when the same test
+executable is being used in multiple calls to `catch_discover_tests()`.
+Note that this variable is only available in CTest.
+
+
+### `ParseAndAddCatchTests.cmake`
+
+`ParseAndAddCatchTests` works by parsing all implementation files
+associated with the provided target, and registering them via CTest's
+`add_test`. This approach has some limitations, such as the fact that
+commented-out tests will be registered anyway.
+
+
+#### Usage
+
+```cmake
+cmake_minimum_required(VERSION 3.5)
+
+project(baz LANGUAGES CXX VERSION 0.0.1)
+
+find_package(Catch2 REQUIRED)
+add_executable(foo test.cpp)
+target_link_libraries(foo Catch2::Catch2)
+
+include(CTest)
+include(ParseAndAddCatchTests)
+ParseAndAddCatchTests(foo)
+```
+
+
+#### Customization
+
+`ParseAndAddCatchTests` provides some customization points:
+* `PARSE_CATCH_TESTS_VERBOSE` -- When `ON`, the script prints debug
+messages. Defaults to `OFF`.
+* `PARSE_CATCH_TESTS_NO_HIDDEN_TESTS` -- When `ON`, hidden tests (tests
+tagged with any of `[!hide]`, `[.]` or `[.foo]`) will not be registered.
+Defaults to `OFF`.
+* `PARSE_CATCH_TESTS_ADD_FIXTURE_IN_TEST_NAME` -- When `ON`, adds fixture
+class name to the test name in CTest. Defaults to `ON`.
+* `PARSE_CATCH_TESTS_ADD_TARGET_IN_TEST_NAME` -- When `ON`, adds target
+name to the test name in CTest. Defaults to `ON`.
+* `PARSE_CATCH_TESTS_ADD_TO_CONFIGURE_DEPENDS` -- When `ON`, adds test
+file to `CMAKE_CONFIGURE_DEPENDS`. This means that the CMake configuration
+step will be re-ran when the test files change, letting new tests be
+automatically discovered. Defaults to `OFF`.
+
+
+## CMake project options
+
+Catch2's CMake project also provides some options for other projects
+that consume it. These are
+
+* `CATCH_BUILD_TESTING` -- When `ON`, Catch2's SelfTest project will be
+built. Defaults to `ON`. Note that Catch2 also obeys `BUILD_TESTING` CMake
+variable, so _both_ of them need to be `ON` for the SelfTest to be built,
+and either of them can be set to `OFF` to disable building SelfTest.
+* `CATCH_BUILD_EXAMPLES` -- When `ON`, Catch2's usage examples will be
+built. Defaults to `OFF`.
+* `CATCH_INSTALL_DOCS` -- When `ON`, Catch2's documentation will be
+included in the installation. Defaults to `ON`.
+* `CATCH_INSTALL_HELPERS` -- When `ON`, Catch2's contrib folder will be
+included in the installation. Defaults to `ON`.
+* `BUILD_TESTING` -- When `ON` and the project is not used as a subproject,
+Catch2's test binary will be built. Defaults to `ON`.
+
+
+## Installing Catch2 from git repository
+
+If you cannot install Catch2 from a package manager (e.g. Ubuntu 16.04
+provides catch only in version 1.2.0) you might want to install it from
+the repository instead. Assuming you have enough rights, you can just
+install it to the default location, like so:
+```
+$ git clone https://github.com/catchorg/Catch2.git
+$ cd Catch2
+$ cmake -Bbuild -H. -DBUILD_TESTING=OFF
+$ sudo cmake --build build/ --target install
+```
+
+If you do not have superuser rights, you will also need to specify
+[CMAKE_INSTALL_PREFIX](https://cmake.org/cmake/help/latest/variable/CMAKE_INSTALL_PREFIX.html)
+when configuring the build, and then modify your calls to
+[find_package](https://cmake.org/cmake/help/latest/command/find_package.html)
+accordingly.
+
+
+---
+
+[Home](Readme.md#top)
diff --git a/packages/Catch2/docs/command-line.md b/packages/Catch2/docs/command-line.md
index 9a095a04d..fc63fe87b 100644
--- a/packages/Catch2/docs/command-line.md
+++ b/packages/Catch2/docs/command-line.md
@@ -24,7 +24,7 @@
 [Usage](#usage)<br>
 [Specify the section to run](#specify-the-section-to-run)<br>
 [Filenames as tags](#filenames-as-tags)<br>
-[Override output colouring](#use-colour)<br>
+[Override output colouring](#override-output-colouring)<br>
 
 Catch works quite nicely without any command line options at all - but for those times when you want greater control the following options are available.
 Click one of the followings links to take you straight to that option - or scroll on to browse the available options.
@@ -124,7 +124,9 @@ The JUnit reporter is an xml format that follows the structure of the JUnit XML
 ## Breaking into the debugger
 <pre>-b, --break</pre>
 
-In some IDEs (currently XCode and Visual Studio) it is possible for Catch to break into the debugger on a test failure. This can be very helpful during debug sessions - especially when there is more than one path through a particular test.
+Under most debuggers Catch2 is capable of automatically breaking on a test
+failure. This allows the user to see the current state of the test during
+failure.
 
 <a id="showing-results-for-successful-tests"></a>
 ## Showing results for successful tests
diff --git a/packages/Catch2/docs/configuration.md b/packages/Catch2/docs/configuration.md
index 81bf292aa..db1ebc728 100644
--- a/packages/Catch2/docs/configuration.md
+++ b/packages/Catch2/docs/configuration.md
@@ -3,15 +3,19 @@
 
 **Contents**<br>
 [main()/ implementation](#main-implementation)<br>
+[Reporter / Listener interfaces](#reporter--listener-interfaces)<br>
 [Prefixing Catch macros](#prefixing-catch-macros)<br>
 [Terminal colour](#terminal-colour)<br>
 [Console width](#console-width)<br>
 [stdout](#stdout)<br>
 [Fallback stringifier](#fallback-stringifier)<br>
 [Default reporter](#default-reporter)<br>
+[C++11 toggles](#c11-toggles)<br>
+[C++17 toggles](#c17-toggles)<br>
 [Other toggles](#other-toggles)<br>
 [Windows header clutter](#windows-header-clutter)<br>
 [Enabling stringification](#enabling-stringification)<br>
+[Disabling exceptions](#disabling-exceptions)<br>
 
 Catch is designed to "just work" as much as possible. For most people the only configuration needed is telling Catch which source file should host all the implementation code (```CATCH_CONFIG_MAIN```).
 
@@ -19,12 +23,12 @@ Nonetheless there are still some occasions where finer control is needed. For th
 
 ## main()/ implementation
 
-	CATCH_CONFIG_MAIN	// Designates this as implementation file and defines main()
-	CATCH_CONFIG_RUNNER	// Designates this as implementation file
+    CATCH_CONFIG_MAIN      // Designates this as implementation file and defines main()
+    CATCH_CONFIG_RUNNER    // Designates this as implementation file
 
 Although Catch is header only it still, internally, maintains a distinction between interface headers and headers that contain implementation. Only one source file in your test project should compile the implementation headers and this is controlled through the use of one of these macros - one of these identifiers should be defined before including Catch in *exactly one implementation file in your project*.
 
-# Reporter / Listener interfaces
+## Reporter / Listener interfaces
 
     CATCH_CONFIG_EXTERNAL_INTERFACES  // Brings in necessary headers for Reporter/Listener implementation
 
@@ -34,16 +38,16 @@ Implied by both `CATCH_CONFIG_MAIN` and `CATCH_CONFIG_RUNNER`.
 
 ## Prefixing Catch macros
 
-	CATCH_CONFIG_PREFIX_ALL
+    CATCH_CONFIG_PREFIX_ALL
 
 To keep test code clean and uncluttered Catch uses short macro names (e.g. ```TEST_CASE``` and ```REQUIRE```). Occasionally these may conflict with identifiers from platform headers or the system under test. In this case the above identifier can be defined. This will cause all the Catch user macros to be prefixed with ```CATCH_``` (e.g. ```CATCH_TEST_CASE``` and ```CATCH_REQUIRE```).
 
 
 ## Terminal colour
 
-	CATCH_CONFIG_COLOUR_NONE	// completely disables all text colouring
-	CATCH_CONFIG_COLOUR_WINDOWS	// forces the Win32 console API to be used
-	CATCH_CONFIG_COLOUR_ANSI	// forces ANSI colour codes to be used
+    CATCH_CONFIG_COLOUR_NONE      // completely disables all text colouring
+    CATCH_CONFIG_COLOUR_WINDOWS   // forces the Win32 console API to be used
+    CATCH_CONFIG_COLOUR_ANSI      // forces ANSI colour codes to be used
 
 Yes, I am English, so I will continue to spell "colour" with a 'u'.
 
@@ -57,22 +61,27 @@ Typically you should place the ```#define``` before #including "catch.hpp" in yo
 
 ## Console width
 
-	CATCH_CONFIG_CONSOLE_WIDTH = x // where x is a number
+    CATCH_CONFIG_CONSOLE_WIDTH = x // where x is a number
 
 Catch formats output intended for the console to fit within a fixed number of characters. This is especially important as indentation is used extensively and uncontrolled line wraps break this.
 By default a console width of 80 is assumed but this can be controlled by defining the above identifier to be a different value.
 
 ## stdout
 
-	CATCH_CONFIG_NOSTDOUT
+    CATCH_CONFIG_NOSTDOUT
 
-Catch does not use ```std::cout```, ```std::cerr``` and ```std::clog``` directly but gets them from ```Catch::cout()```, ```Catch::cerr()``` and ```Catch::clog``` respectively. If the above identifier is defined these functions are left unimplemented and you must implement them yourself. Their signatures are:
+To support platforms that do not provide `std::cout`, `std::cerr` and
+`std::clog`, Catch does not usem the directly, but rather calls
+`Catch::cout`, `Catch::cerr` and `Catch::clog`. You can replace their
+implementation by defining `CATCH_CONFIG_NOSTDOUT` and implementing
+them yourself, their signatures are:
 
     std::ostream& cout();
     std::ostream& cerr();
     std::ostream& clog();
 
-This can be useful on certain platforms that do not provide the standard iostreams, such as certain embedded systems.
+[You can see an example of replacing these functions here.](
+../examples/231-Cfg-OutputStreams.cpp)
 
 
 ## Fallback stringifier
@@ -118,6 +127,8 @@ Catch's selection, by defining either `CATCH_CONFIG_CPP11_TO_STRING` or
 ## C++17 toggles
 
     CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS  // Use std::uncaught_exceptions instead of std::uncaught_exception
+    CATCH_CONFIG_CPP17_STRING_VIEW          // Provide StringMaker specialization for std::string_view
+    CATCH_CONFIG_CPP17_VARIANT              // Override C++17 detection for CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
 
 Catch contains basic compiler/standard detection and attempts to use
 some C++17 features whenever appropriate. This automatic detection
@@ -153,11 +164,14 @@ these toggles can be disabled by using `_NO_` form of the toggle,
 e.g. `CATCH_CONFIG_NO_WINDOWS_SEH`.
 
 ### `CATCH_CONFIG_FAST_COMPILE`
-Defining this flag speeds up compilation of test files by ~20%, by making 2 changes:
-* The `-b` (`--break`) flag no longer makes Catch break into debugger in the same stack frame as the failed test, but rather in a stack frame *below*.
-* Non-exception family of macros ({`REQUIRE`,`CHECK`}{`_`,`_FALSE`, `_THAT`}, no longer use local try-catch block. This disables exception translation, but should not lead to false negatives.
+This compile-time flag speeds up compilation of assertion macros by ~20%,
+by disabling the generation of assertion-local try-catch blocks for
+non-exception family of assertion macros ({`REQUIRE`,`CHECK`}{``,`_FALSE`, `_THAT`}).
+This disables translation of exceptions thrown under these assertions, but
+should not lead to false negatives.
 
-`CATCH_CONFIG_FAST_COMPILE` has to be either defined, or not defined, in all translation units that are linked into single test binary, or the behaviour of setting `-b` flag and throwing unexpected exceptions will be unpredictable.
+`CATCH_CONFIG_FAST_COMPILE` has to be either defined, or not defined,
+in all translation units that are linked into single test binary.
 
 ### `CATCH_CONFIG_DISABLE_MATCHERS`
 When `CATCH_CONFIG_DISABLE_MATCHERS` is defined, all mentions of Catch's Matchers are ifdef-ed away from the translation unit. Doing so will speed up compilation of that TU.
@@ -189,9 +203,44 @@ By default, Catch does not stringify some types from the standard library. This
     CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER    // Provide StringMaker specialization for std::pair
     CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER   // Provide StringMaker specialization for std::tuple
     CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER  // Provide StringMaker specialization for std::chrono::duration, std::chrono::timepoint
+    CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER // Provide StringMaker specialization for std::variant, std::monostate (on C++17)
     CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS    // Defines all of the above
 
 
+## Disabling exceptions
+
+By default, Catch2 uses exceptions to signal errors and to abort tests
+when an assertion from the `REQUIRE` family of assertions fails. We also
+provide an experimental support for disabling exceptions. Catch2 should
+automatically detect when it is compiled with exceptions disabled, but
+it can be forced to compile without exceptions by defining
+
+    CATCH_CONFIG_DISABLE_EXCEPTIONS
+
+Note that when using Catch2 without exceptions, there are 2 major
+limitations:
+
+1) If there is an error that would normally be signalled by an exception,
+the exception's message will instead be written to `Catch::cerr` and
+`std::terminate` will be called.
+2) If an assertion from the `REQUIRE` family of macros fails,
+`std::terminate` will be called after the active reporter returns.
+
+
+There is also a customization point for the exact behaviour of what
+happens instead of exception being thrown. To use it, define
+
+    CATCH_CONFIG_DISABLE_EXCEPTIONS_CUSTOM_HANDLER
+
+and provide a definition for this function:
+
+```cpp
+namespace Catch {
+    [[noreturn]]
+    void throw_exception(std::exception const&);
+}
+```
+
 ---
 
 [Home](Readme.md#top)
diff --git a/packages/Catch2/docs/generators.md b/packages/Catch2/docs/generators.md
new file mode 100644
index 000000000..40b42004e
--- /dev/null
+++ b/packages/Catch2/docs/generators.md
@@ -0,0 +1,50 @@
+<a id="top"></a>
+# Data Generators
+
+_Generators are currently considered an experimental feature and their
+API can change between versions freely._
+
+Data generators (also known as _data driven/parametrized test cases_)
+let you reuse the same set of assertions across different input values.
+In Catch2, this means that they respect the ordering and nesting
+of the `TEST_CASE` and `SECTION` macros.
+
+How does combining generators and test cases work might be better
+explained by an example:
+
+```cpp
+TEST_CASE("Generators") {
+    auto i = GENERATE( range(1, 11) );
+
+    SECTION( "Some section" ) {
+        auto j = GENERATE( range( 11, 21 ) );
+        REQUIRE(i < j);
+    }
+}
+```
+
+the assertion will be checked 100 times, because there are 10 possible
+values for `i` (1, 2, ..., 10) and for each of them, there are 10 possible
+values for `j` (11, 12, ..., 20).
+
+You can also combine multiple generators by concatenation:
+```cpp
+static int square(int x) { return x * x; }
+TEST_CASE("Generators 2") {
+    auto i = GENERATE(0, 1, -1, range(-20, -10), range(10, 20));
+    CAPTURE(i);
+    REQUIRE(square(i) >= 0);
+}
+```
+
+This will call `square` with arguments `0`, `1`, `-1`, `-20`, ..., `-11`,
+`10`, ..., `19`.
+
+----------
+
+Because of the experimental nature of the current Generator implementation,
+we won't list all of the first-party generators in Catch2. Instead you
+should look at our current usage tests in
+[projects/SelfTest/UsageTests/Generators.tests.cpp](/projects/SelfTest/UsageTests/Generators.tests.cpp).
+For implementing your own generators, you can look at their implementation in
+[include/internal/catch_generators.hpp](/include/internal/catch_generators.hpp).
diff --git a/packages/Catch2/docs/limitations.md b/packages/Catch2/docs/limitations.md
index 9acade0e1..b95cd87f2 100644
--- a/packages/Catch2/docs/limitations.md
+++ b/packages/Catch2/docs/limitations.md
@@ -1,12 +1,19 @@
 <a id="top"></a>
 # Known limitations
 
-Catch has some known limitations, that we are not planning to change. Some of these are caused by our desire to support C++98 compilers, some of these are caused by our desire to keep Catch crossplatform, some exist because their priority is seen as low compared to the development effort they would need and some other yet are compiler/runtime bugs.
+Over time, some limitations of Catch2 emerged. Some of these are due
+to implementation details that cannot be easily changed, some of these
+are due to lack of development resources on our part, and some of these
+are due to plain old 3rd party bugs.
+
 
 ## Implementation limits
 ### Sections nested in loops
 
-If you are using `SECTION`s inside loops, you have to create them with different name per loop's iteration. The recommended way to do so is to incorporate the loop's counter into section's name, like so
+If you are using `SECTION`s inside loops, you have to create them with
+different name per loop's iteration. The recommended way to do so is to
+incorporate the loop's counter into section's name, like so:
+
 ```cpp
 TEST_CASE( "Looped section" ) {
     for (char i = '0'; i < '5'; ++i) {
@@ -17,11 +24,34 @@ TEST_CASE( "Looped section" ) {
 }
 ```
 
+or with a `DYNAMIC_SECTION` macro (that was made for exactly this purpose):
+
+```cpp
+TEST_CASE( "Looped section" ) {
+    for (char i = '0'; i < '5'; ++i) {
+        DYNAMIC_SECTION( "Looped section " << i) {
+            SUCCEED( "Everything is OK" );
+        }
+    }
+}
+```
+
+### Tests might be run again if last section fails
+
+If the last section in a test fails, it might be run again. This is because
+Catch2 discovers `SECTION`s dynamically, as they are about to run, and
+if the last section in test case is aborted during execution (e.g. via
+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.
+
+
 ## Features
 This section outlines some missing features, what is their status and their possible workarounds.
 
 ### Thread safe assertions
-Because threading support in standard C++98 is limited (well, non-existent), assertion macros in Catch are not thread safe. This does not mean that you cannot use threads inside Catch's test, but that only single thread can interact with Catch's assertions and other macros.
+Catch2's assertion macros are not thread safe. This does not mean that
+you cannot use threads inside Catch's test, but that only single thread
+can interact with Catch's assertions and other macros.
 
 This means that this is ok
 ```cpp
@@ -49,8 +79,8 @@ because only one thread passes the `REQUIRE` macro and this is not
     REQUIRE(cnt == 16);
 ```
 
-
-_This limitation is highly unlikely to be lifted before Catch 2 is released._
+Because C++11 provides the necessary tools to do this, we are planning
+to remove this limitation in the future.
 
 ### Process isolation in a test
 Catch does not support running tests in isolated (forked) processes. While this might in the future, the fact that Windows does not support forking and only allows full-on process creation and the desire to keep code as similar as possible across platforms, mean that this is likely to take significant development time, that is not currently available.
@@ -135,3 +165,14 @@ If you are seeing a problem like this, i.e. a weird test paths that trigger only
 This is a bug in `libstdc++-4.8`, where all matching methods from `<regex>` return false. Since `Matches` uses `<regex>` internally, if the underlying implementation does not work, it doesn't work either.
 
 Workaround: Use newer version of `libstdc++`.
+
+
+### libstdc++, `_GLIBCXX_DEBUG` macro and random ordering of tests
+
+Running a Catch2 binary compiled against libstdc++ with `_GLIBCXX_DEBUG`
+macro defined with `--order rand` will cause a debug check to trigger and
+abort the run due to self-assignment.
+[This is a known bug inside libstdc++](https://stackoverflow.com/questions/22915325/avoiding-self-assignment-in-stdshuffle/23691322)
+
+Workaround: Don't use `--order rand` when compiling against debug-enabled
+libstdc++.
diff --git a/packages/Catch2/docs/list-of-examples.md b/packages/Catch2/docs/list-of-examples.md
index 81f5a903f..5b538da03 100644
--- a/packages/Catch2/docs/list-of-examples.md
+++ b/packages/Catch2/docs/list-of-examples.md
@@ -3,14 +3,17 @@
 
 ## Already available
 
+- Catch main: [Catch-provided main](../examples/000-CatchMain.cpp)
 - Test Case: [Single-file](../examples/010-TestCase.cpp)
-- Test Case: [Multiple-file 1](../examples/020-TestCase-1.cpp), [2](../examples/020-TestCase-1.cpp)
+- Test Case: [Multiple-file 1](../examples/020-TestCase-1.cpp), [2](../examples/020-TestCase-2.cpp)
 - Assertion: [REQUIRE, CHECK](../examples/030-Asn-Require-Check.cpp)
 - Fixture: [Sections](../examples/100-Fix-Section.cpp)
 - Fixture: [Class-based fixtures](../examples/110-Fix-ClassFixture.cpp)
 - BDD: [SCENARIO, GIVEN, WHEN, THEN](../examples/120-Bdd-ScenarioGivenWhenThen.cpp)
+- Report: [Catch-provided main](../examples/200-Rpt-CatchMain.cpp)
+- Report: [TeamCity reporter](../examples/207-Rpt-TeamCityReporter.cpp)
 - Listener: [Listeners](../examples/210-Evt-EventListeners.cpp)
-
+- Configuration: [Provide your own output streams](../examples/231-Cfg-OutputStreams.cpp)
 
 ## Planned
 
@@ -27,7 +30,10 @@
 - Logging: [FAIL, FAIL_CHECK - Issue message and force failure/continue](../examples/170-Log-Fail.cpp)
 - Logging: [SUCCEED - Issue message and continue](../examples/180-Log-Succeed.cpp)
 - Report: [User-defined type](../examples/190-Rpt-ReportUserDefinedType.cpp)
-- Report: [Reporter](../examples/200-Rpt-UserDefinedReporter.cpp)
+- Report: [User-defined reporter](../examples/202-Rpt-UserDefinedReporter.cpp)
+- Report: [Automake reporter](../examples/205-Rpt-AutomakeReporter.cpp)
+- Report: [TAP reporter](../examples/206-Rpt-TapReporter.cpp)
+- Report: [Multiple reporter](../examples/208-Rpt-MultipleReporters.cpp)
 - Configuration: [Provide your own main()](../examples/220-Cfg-OwnMain.cpp)
 - Configuration: [Compile-time configuration](../examples/230-Cfg-CompileTimeConfiguration.cpp)
 - Configuration: [Run-time configuration](../examples/240-Cfg-RunTimeConfiguration.cpp)
diff --git a/packages/Catch2/docs/logging.md b/packages/Catch2/docs/logging.md
index 7ae54aab5..39ae5c7ac 100644
--- a/packages/Catch2/docs/logging.md
+++ b/packages/Catch2/docs/logging.md
@@ -72,12 +72,6 @@ This would log something like:
 
 <pre>"theAnswer := 42"</pre>
 
-## Deprecated macros
-
-**SCOPED_INFO and SCOPED_CAPTURE**
-
-These macros are now deprecated and are just aliases for INFO and CAPTURE (which were not previously scoped).
-
 ---
 
 [Home](Readme.md#top)
diff --git a/packages/Catch2/docs/opensource-users.md b/packages/Catch2/docs/opensource-users.md
index 86ab82fe4..25e5a437b 100644
--- a/packages/Catch2/docs/opensource-users.md
+++ b/packages/Catch2/docs/opensource-users.md
@@ -36,7 +36,7 @@ The next-generation core storage and query engine for Couchbase Lite
 A High-performance Cluster Computing Engine
 
 ### [forest](https://github.com/xorz57/forest)
-Forest is an open-source, template library of tree data structures written in C++11.
+Template Library of Tree Data Structures
 
 ### [Fuxedo](https://github.com/fuxedo/fuxedo)
 Open source Oracle Tuxedo-like XATMI middleware for C and C++.
@@ -71,6 +71,9 @@ A C++ client library for Consul. Consul is a distributed tool for discovering an
 ### [Reactive-Extensions/ RxCpp](https://github.com/Reactive-Extensions/RxCpp)
 A library of algorithms for values-distributed-in-time
 
+### [thor](https://github.com/xorz57/thor)
+Wrapper Library for CUDA
+
 ### [TextFlowCpp](https://github.com/philsquared/textflowcpp)
 A small, single-header-only, library for wrapping and composing columns of text
 
diff --git a/packages/Catch2/docs/own-main.md b/packages/Catch2/docs/own-main.md
index c74f9f14e..6a9b1aadc 100644
--- a/packages/Catch2/docs/own-main.md
+++ b/packages/Catch2/docs/own-main.md
@@ -1,6 +1,12 @@
 <a id="top"></a>
 # Supplying main() yourself
 
+**Contents**<br>
+[Let Catch take full control of args and config](#let-catch-take-full-control-of-args-and-config)<br>
+[Amending the config](#amending-the-config)<br>
+[Adding your own command line options](#adding-your-own-command-line-options)<br>
+[Version detection](#version-detection)<br>
+
 The easiest way to use Catch is to let it supply ```main()``` for you and handle configuring itself from the command line.
 
 This is achieved by writing ```#define CATCH_CONFIG_MAIN``` before the ```#include "catch.hpp"``` in *exactly one* source file.
@@ -45,7 +51,7 @@ int main( int argc, char* argv[] )
     
   int returnCode = session.applyCommandLine( argc, argv );
   if( returnCode != 0 ) // Indicates a command line error
-  	  return returnCode;
+        return returnCode;
  
   // writing to session.configData() or session.Config() here 
   // overrides command line args
@@ -94,7 +100,7 @@ int main( int argc, char* argv[] )
   // Let Catch (using Clara) parse the command line
   int returnCode = session.applyCommandLine( argc, argv );
   if( returnCode != 0 ) // Indicates a command line error
-  	return returnCode;
+      return returnCode;
 
   // if set on the command line then 'height' is now set at this point
   if( height > 0 )
diff --git a/packages/Catch2/docs/release-notes.md b/packages/Catch2/docs/release-notes.md
index 6ebe4d03d..f31f0e876 100644
--- a/packages/Catch2/docs/release-notes.md
+++ b/packages/Catch2/docs/release-notes.md
@@ -1,11 +1,103 @@
 <a id="top"></a>
 
-# 2.2.3
+# Release notes
+**Contents**<br>
+[2.4.1](#241)<br>
+[2.4.0](#240)<br>
+[2.3.0](#230)<br>
+[2.2.3](#223)<br>
+[2.2.2](#222)<br>
+[2.2.1](#221)<br>
+[2.2.0](#220)<br>
+[2.1.2](#212)<br>
+[2.1.1](#211)<br>
+[2.1.0](#210)<br>
+[2.0.1](#201)<br>
+[Older versions](#older-versions)<br>
+[Even Older versions](#even-older-versions)<br>
+
+
+## 2.4.1
+
+### Improvements
+* Added a StringMaker for `std::(w)string_view` (#1375, #1376)
+* Added a StringMaker for `std::variant` (#1380)
+  * This one is disabled by default to avoid increased compile-time drag
+* Added detection for cygwin environment without `std::to_string` (#1396, #1397)
+
+### Fixes
+* `UnorderedEqualsMatcher` will no longer accept erroneously accept
+vectors that share suffix, but are not permutation of the desired vector
+* Abort after (`-x N`) can no longer be overshot by nested `REQUIRES` and
+subsequently ignored (#1391, #1392)
+
+
+## 2.4.0
+
+**This release brings two new experimental features, generator support
+and a `-fno-exceptions` support. Being experimental means that they
+will not be subject to the usual stability guarantees provided by semver.**
+
+### Improvements
+* Various small runtime performance improvements
+* `CAPTURE` macro is now variadic
+* Added `AND_GIVEN` macro (#1360)
+* Added experimental support for data generators
+  * See [their documentation](generators.md) for details
+* Added support for compiling and running Catch without exceptions
+  * Doing so limits the functionality somewhat
+  * Look [into the documentation](configuration.md#disablingexceptions) for details
+
+### Fixes
+* Suppressed `-Wnon-virtual-dtor` warnings in Matchers (#1357)
+* Suppressed `-Wunreachable-code` warnings in floating point matchers (#1350)
+
+### CMake
+* It is now possible to override which Python is used to run Catch's tests (#1365)
+* Catch now provides infrastructure for adding tests that check compile-time configuration
+* Catch no longer tries to install itself when used as a subproject (#1373)
+* Catch2ConfigVersion.cmake is now generated as arch-independent (#1368)
+  * This means that installing Catch from 32-bit machine and copying it to 64-bit one works
+  * This fixes conan installation of Catch
+
+
+## 2.3.0
+
+**This release changes the include paths provided by our CMake and
+pkg-config integration. The proper include path for the single-header
+when using one of the above is now `<catch2/catch.hpp>`. This change
+also necessitated changes to paths inside the repository, so that the
+single-header version is now at `single_include/catch2/catch.hpp`, rather
+than `single_include/catch.hpp`.**
+
+
+
+### Fixes
+* Fixed Objective-C++ build
+* `-Wunused-variable` suppression no longer leaks from Catch's header under Clang
+* Implementation of the experimental new output capture can now be disabled (#1335)
+  * This allows building Catch2 on platforms that do not provide things like `dup` or `tmpfile`.
+* The JUnit and XML reporters will no longer skip over successful tests when running without `-s`  (#1264, #1267, #1310)
+  * See improvements for more details
+
+### Improvements
+* pkg-config and CMake integration has been rewritten
+  * If you use them, the new include path is `#include <catch2/catch.hpp>`
+  * CMake installation now also installs scripts from `contrib/`
+  * For details see the [new documentation](cmake-integration.md#top)
+* Reporters now have a new customization point, `ReporterPreferences::shouldReportAllAssertions`
+  * When this is set to `false` and the tests are run without `-s`, passing assertions are not sent to the reporter.
+  * Defaults to `false`.
+* Added `DYNAMIC_SECTION`, a section variant that constructs its name using stream
+  * This means that you can do `DYNAMIC_SECTION("For X := " << x)`.
+
+
+## 2.2.3
 
 **To fix some of the bugs, some behavior had to change in potentially breaking manner.**
 **This means that even though this is a patch release, it might not be a drop-in replacement.**
 
-## Fixes
+### Fixes
 * Listeners are now called before reporter
   * This was always documented to be the case, now it actually works that way
 * Catch's commandline will no longer accept multiple reporters
@@ -24,23 +116,23 @@
   * **This has potential to be a breaking change**
 * Fixed compilation error when a type has an `operator<<` with templated lhs (#1285, #1306)
 
-## Improvements
+### Improvements
 * Added a new, experimental, output capture (#1243)
   * This capture can also redirect output written via C apis, e.g. `printf`
   * To opt-in, define `CATCH_CONFIG_EXPERIMENTAL_REDIRECT` in the implementation file
 * Added a new fallback stringifier for classes derived from `std::exception`
   * Both `StringMaker` specialization and `operator<<` overload are given priority
 
-## Miscellaneous
+### Miscellaneous
 * `contrib/` now contains dbg scripts that skip over Catch's internals (#904, #1283)
   * `gdbinit` for gdb `lldbinit` for lldb
 * `CatchAddTests.cmake` no longer strips whitespace from tests (#1265, #1281)
 * Online documentation now describes `--use-colour` option (#1263)
 
 
-# 2.2.2
+## 2.2.2
 
-## Fixes
+### Fixes
 * Fixed bug in `WithinAbs::match()` failing spuriously (#1228)
 * Fixed clang-tidy diagnostic about virtual call in destructor (#1226)
 * Reduced the number of GCC warnings suppression leaking out of the header (#1090, #1091)
@@ -49,7 +141,7 @@
   * On platforms where `std::chrono::high_resolution_clock`'s resolution is low, the calibration would appear stuck
 * Fixed compilation error when stringifying static arrays of `unsigned char`s (#1238)
 
-## Improvements
+### Improvements
 * XML encoder now hex-encodes invalid UTF-8 sequences (#1207)
   * This affects xml and junit reporters
   * Some invalid UTF-8 parts are left as is, e.g. surrogate pairs. This is because certain extensions of UTF-8 allow them, such as WTF-8.
@@ -58,29 +150,29 @@
 * Added `PredicateMatcher`, a matcher that takes an arbitrary predicate function (#1236)
   * See [documentation for details](https://github.com/catchorg/Catch2/blob/master/docs/matchers.md)
 
-## Others
+### Others
 * Modified CMake-installed pkg-config to allow `#include <catch.hpp>`(#1239)
   * The plans to standardize on `#include <catch2/catch.hpp>` are still in effect
 
 
-# 2.2.1
+## 2.2.1
 
-## Fixes
+### Fixes
 * Fixed compilation error when compiling Catch2 with `std=c++17` against libc++ (#1214)
   * Clara (Catch2's CLI parsing library) used `std::optional` without including it explicitly
 * Fixed Catch2 return code always being 0 (#1215)
   * In the words of STL, "We feel superbad about letting this in"
 
 
-# 2.2.0
+## 2.2.0
 
-## Fixes
+### Fixes
 * Hidden tests are not listed by default when listing tests (#1175)
   * This makes `catch_discover_tests` CMake script work better
 * Fixed regression that meant `<windows.h>` could potentially not be included properly (#1197)
 * Fixed installing `Catch2ConfigVersion.cmake` when Catch2 is a subproject.
 
-## Improvements
+### Improvements
 * Added an option to warn (+ exit with error) when no tests were ran (#1158)
   * Use as `-w NoTests`
 * Added provisional support for Emscripten (#1114)
@@ -92,38 +184,38 @@
 * Added support for DJGPP DOS crosscompiler (#1206)
 
 
-# 2.1.2
+## 2.1.2
 
-## Fixes
+### Fixes
 * Fixed compilation error with `-fno-rtti` (#1165)
 * Fixed NoAssertion warnings
 * `operator<<` is used before range-based stringification (#1172)
 * Fixed `-Wpedantic` warnings (extra semicolons and binary literals) (#1173)
 
 
-## Improvements
+### Improvements
 * Added `CATCH_VERSION_{MAJOR,MINOR,PATCH}` macros (#1131)
 * Added `BrightYellow` colour for use in reporters (#979)
   * It is also used by ConsoleReporter for reconstructed expressions
 
-## Other changes
+### Other changes
 * Catch is now exported as a CMake package and linkable target (#1170)
 
-# 2.1.1
+## 2.1.1
 
-## Improvements
+### Improvements
 * Static arrays are now properly stringified like ranges across MSVC/GCC/Clang
 * Embedded newer version of Clara -- v1.1.1
   * This should fix some warnings dragged in from Clara
 * MSVC's CLR exceptions are supported
 
 
-## Fixes
+### Fixes
 * Fixed compilation when comparison operators do not return bool (#1147)
 * Fixed CLR exceptions blowing up the executable during translation (#1138)
 
 
-## Other changes
+### Other changes
 * Many CMake changes
   * `NO_SELFTEST` option is deprecated, use `BUILD_TESTING` instead.
   * Catch specific CMake options were prefixed with `CATCH_` for namespacing purposes
@@ -131,9 +223,9 @@
 
 
 
-# 2.1.0
+## 2.1.0
 
-## Improvements
+### Improvements
 * Various performance improvements
   * On top of the performance regression fixes
 * Experimental support for PCH was added (#1061)
@@ -143,7 +235,7 @@
   * Bugs in g++ 4.x and 5.x mean that some of them have to be left in
 
 
-## Fixes
+### Fixes
 * Fixed performance regression from Catch classic
   * One of the performance improvement patches for Catch classic was not applied to Catch2
 * Fixed platform detection for iOS (#1084)
@@ -156,7 +248,7 @@
 * Fixed `std::uncaught_exception` deprecation warning (#1124)
 
 
-## New features
+### New features
 * New Matchers
   * Regex matcher for strings, `Matches`.
   * Set-equal matcher for vectors, `UnorderedEquals`
@@ -165,15 +257,15 @@
   * Containers are objects that respond to ADL `begin(T)` and `end(T)`.
 
 
-## Other changes
+### Other changes
 * Reporters will now be versioned in the `single_include` folder to ensure their compatibility with the last released version
 
 
 
 
-# 2.0.1
+## 2.0.1
 
-## Breaking changes
+### Breaking changes
 * Removed C++98 support
 * Removed legacy reporter support
 * Removed legacy generator support
@@ -203,7 +295,7 @@
   * `INFINITY == Approx(INFINITY)` returns true
 
 
-## Improvements
+### Improvements
 * Reporters and Listeners can be defined in files different from the main file
   * The file has to define `CATCH_CONFIG_EXTERNAL_INTERFACES` before including catch.hpp.
 * Errors that happen during set up before main are now caught and properly reported once main is entered
@@ -237,7 +329,7 @@
 * Add `pkg-config` support to CMake install command
 
 
-## Fixes
+### Fixes
 * Don't use console colour if running in XCode
 * Explicit constructor in reporter base class
 * Swept out `-Wweak-vtables`, `-Wexit-time-destructors`, `-Wglobal-constructors` warnings
@@ -249,7 +341,7 @@
 * Suppressed C4061 warning under MSVC
 
 
-## Internal changes
+### Internal changes
 * The development version now uses .cpp files instead of header files containing implementation.
   * This makes partial rebuilds much faster during development
 * The expression decomposition layer has been rewritten
@@ -257,13 +349,33 @@
 * New library (TextFlow) is used for formatting text to output
 
 
-# Older versions
+## Older versions
 
-## 1.11.x
+### 1.12.x
 
-### 1.11.0
+#### 1.12.2
+##### Fixes
+* Fixed missing <cassert> include
 
-#### Fixes
+#### 1.12.1
+
+##### Fixes
+* Fixed deprecation warning in `ScopedMessage::~ScopedMessage`
+* All uses of `min` or `max` identifiers are now wrapped in parentheses
+  * This avoids problems when Windows headers define `min` and `max` macros
+
+#### 1.12.0
+
+##### Fixes
+* Fixed compilation for strict C++98 mode (ie not gnu++98) and older compilers (#1103)
+* `INFO` messages are included in the `xml` reporter output even without `-s` specified.
+
+
+### 1.11.x
+
+#### 1.11.0
+
+##### Fixes
 * The original expression in `REQUIRE_FALSE( expr )` is now reporter properly as `!( expr )` (#1051)
   * Previously the parentheses were missing and `x != y` would be expanded as `!x != x`
 * `Approx::Margin` is now inclusive (#952)
@@ -271,7 +383,7 @@
   * This means that `REQUIRE( 0.25f == Approx( 0.0f ).margin( 0.25f ) )` passes, instead of fails
 * `RandomNumberGenerator::result_type` is now unsigned (#1050)
 
-#### Improvements
+##### Improvements
 * `__JETBRAINS_IDE__` macro handling is now CLion version specific (#1017)
   * When CLion 2017.3 or newer is detected, `__COUNTER__` is used instead of
 * TeamCity reporter now explicitly flushes output stream after each report (#1057)
@@ -279,35 +391,35 @@
 * `ParseAndAddCatchTests` now can add test files as dependency to CMake configuration
   * This means you do not have to manually rerun CMake configuration step to detect new tests
 
-## 1.10.x
+### 1.10.x
 
-### 1.10.0
+#### 1.10.0
 
-#### Fixes
+##### Fixes
 * Evaluation layer has been rewritten (backported from Catch 2)
   * The new layer is much simpler and fixes some issues (#981)
 * Implemented workaround for VS 2017 raw string literal stringification bug (#995)
 * Fixed interaction between `[!shouldfail]` and `[!mayfail]` tags and sections
   * Previously sections with failing assertions would be marked as failed, not failed-but-ok
 
-#### Improvements
+##### Improvements
 * Added [libidentify](https://github.com/janwilmans/LibIdentify) support
 * Added "wait-for-keypress" option
 
-## 1.9.x
+### 1.9.x
 
-### 1.9.6
+#### 1.9.6
 
-#### Improvements
+##### Improvements
 * Catch's runtime overhead has been significantly decreased (#937, #939)
 * Added `--list-extra-info` cli option (#934).
   * It lists all tests together with extra information, ie filename, line number and description.
 
 
 
-### 1.9.5
+#### 1.9.5
 
-#### Fixes
+##### Fixes
 * Truthy expressions are now reconstructed properly, not as booleans (#914)
 * Various warnings are no longer erroneously suppressed in test files (files that include `catch.hpp`, but do not define `CATCH_CONFIG_MAIN` or `CATCH_CONFIG_RUNNER`) (#871)
 * Catch no longer fails to link when main is compiled as C++, but linked against Objective-C (#855)
@@ -315,35 +427,35 @@
   * Previously any GCC with minor version less than 3 would be incorrectly classified as not supporting `__COUNTER__`.
 * Suppressed C4996 warning caused by upcoming updated to MSVC 2017, marking `std::uncaught_exception` as deprecated. (#927)
 
-#### Improvements
+##### Improvements
 * CMake integration script now incorporates debug messages and registers tests in an improved way (#911)
 * Various documentation improvements
 
 
 
-### 1.9.4
+#### 1.9.4
 
-#### Fixes
+##### Fixes
 * `CATCH_FAIL` macro no longer causes compilation error without variadic macro support
 * `INFO` messages are no longer cleared after being reported once
 
-#### Improvements and minor changes
+##### Improvements and minor changes
 * Catch now uses `wmain` when compiled under Windows and `UNICODE` is defined.
   * Note that Catch still officially supports only ASCII
 
-### 1.9.3
+#### 1.9.3
 
-#### Fixes
+##### Fixes
 * Completed the fix for (lack of) uint64_t in earlier Visual Studios
 
-### 1.9.2
+#### 1.9.2
 
-#### Improvements and minor changes
+##### Improvements and minor changes
 * All of `Approx`'s member functions now accept strong typedefs in C++11 mode (#888)
   * Previously `Approx::scale`, `Approx::epsilon`, `Approx::margin` and `Approx::operator()` didn't.
 
 
-#### Fixes
+##### Fixes
 * POSIX signals are now disabled by default under QNX (#889)
   * QNX does not support current enough (2001) POSIX specification
 * JUnit no longer counts exceptions as failures if given test case is marked as ok to fail.
@@ -351,22 +463,22 @@
 * Catch no longer attempts to define `uint64_t` on windows (#862)
   * This was causing trouble when compiled under Cygwin
 
-#### Other
+##### Other
 * Catch is now compiled under MSVC 2017 using `std:c++latest` (C++17 mode) in CI
 * We now provide cmake script that autoregisters Catch tests into ctest.
   * See `contrib` folder.
 
 
-### 1.9.1
+#### 1.9.1
 
-#### Fixes
+##### Fixes
 * Unexpected exceptions are no longer ignored by default (#885, #887)
 
 
-### 1.9.0
+#### 1.9.0
 
 
-#### Improvements and minor changes
+##### Improvements and minor changes
 * Catch no longer attempts to ensure the exception type passed by user in `REQUIRE_THROWS_AS` is a constant reference.
   * It was causing trouble when `REQUIRE_THROWS_AS` was used inside templated functions
   * This actually reverts changes made in v1.7.2
@@ -380,7 +492,7 @@
 * When Catch is compiled using C++11, `Approx` is now constructible with anything that can be explicitly converted to `double`.
 * Captured messages are now printed on unexpected exceptions
 
-#### Fixes:
+##### Fixes:
 * Clang's `-Wexit-time-destructors` should be suppressed for Catch's internals
 * GCC's `-Wparentheses` is now suppressed for all TU's that include `catch.hpp`.
   * This is functionally a revert of changes made in 1.8.0, where we tried using `_Pragma` based suppression. This should have kept the suppression local to Catch's assertions, but bugs in GCC's handling of `_Pragma`s in C++ mode meant that it did not always work.
@@ -389,18 +501,18 @@
   * [Details can be found in documentation](configuration.md#catch_config_cpp11_stream_insertable_check)
 
 
-#### Other notes:
+##### Other notes:
 * We have added VS 2017 to our CI
 * Work on Catch 2 should start soon
 
 
 
-## 1.8.x
+### 1.8.x
 
-### 1.8.2
+#### 1.8.2
 
 
-#### Improvements and minor changes
+##### Improvements and minor changes
 * TAP reporter now behaves as if `-s` was always set
   * This should be more consistent with the protocol desired behaviour.
 * Compact reporter now obeys `-d yes` argument (#780)
@@ -414,7 +526,7 @@
   * Listeners provide a way to hook into events generated by running your tests, including start and end of run, every test case, every section and every assertion.
 
 
-#### Fixes:
+##### Fixes:
 * Catch no longer attempts to reconstruct expression that led to a fatal error  (#810)
   * This fixes possible signal/SEH loop when processing expressions, where the signal was triggered by expression decomposition.
 * Fixed (C4265) missing virtual destructor warning in Matchers (#844)
@@ -431,21 +543,21 @@
 * Regression in Objective-C bindings (Matchers) fixed (#854)
 
 
-#### Other notes:
+##### Other notes:
 * We have added VS 2013 and 2015 to our CI
 * Catch Classic (1.x.x) now contains its own, forked, version of Clara (the argument parser).
 
 
 
-### 1.8.1
+#### 1.8.1
 
-#### Fixes
+##### Fixes
 
 Cygwin issue with `gettimeofday` - `#define` was not early enough
 
-### 1.8.0
+#### 1.8.0
 
-#### New features/ minor changes
+##### New features/ minor changes
 
 * Matchers have new, simpler (and documented) interface.
   * Catch provides string and vector matchers.
@@ -465,7 +577,7 @@ Cygwin issue with `gettimeofday` - `#define` was not early enough
 * `Approx` now supports an optional margin of absolute error
   * It has also received [new documentation](assertions.md#top).
 
-#### Fixes
+##### Fixes
 * Silenced C4312 ("conversion from int to 'ClassName *") warnings in the evaluate layer.
 * Fixed C4512 ("assignment operator could not be generated") warnings under VS2013.
 * Cygwin compatibility fixes
@@ -476,15 +588,15 @@ Cygwin issue with `gettimeofday` - `#define` was not early enough
   * Otherwise it is supressed for the whole TU
 * Fixed test spec parser issue (with escapes in multiple names)
 
-#### Other
+##### Other
 * Various documentation fixes and improvements
 
 
-## 1.7.x
+### 1.7.x
 
-### 1.7.2
+#### 1.7.2
 
-#### Fixes and minor improvements
+##### Fixes and minor improvements
 Xml:
 
 (technically the first two are breaking changes but are also fixes and arguably break few if any people)
@@ -503,9 +615,9 @@ Other:
 * Silenced a few more warnings in different circumstances
 * Travis improvements
 
-### 1.7.1
+#### 1.7.1
 
-#### Fixes:
+##### Fixes:
 * Fixed inconsistency in defining `NOMINMAX` and `WIN32_LEAN_AND_MEAN` inside `catch.hpp`.
 * Fixed SEH-related compilation error under older MinGW compilers, by making Windows SEH handling opt-in for compilers other than MSVC.
   * For specifics, look into the [documentation](configuration.md#top).
@@ -515,9 +627,9 @@ Other:
 * Fixed possible infinite recursion in Windows SEH.
 * Fixed possible compilation error caused by Catch's operator overloads being ambiguous in regards to user-defined templated operators.
 
-### 1.7.0
+#### 1.7.0
 
-#### Features/ Changes:
+##### Features/ Changes:
 * Catch now runs significantly faster for passing tests
   * Microbenchmark focused on Catch's overhead went from ~3.4s to ~0.7s.
   * Real world test using [JSON for Modern C++](https://github.com/nlohmann/json)'s test suite went from ~6m 25s to ~4m 14s.
@@ -531,30 +643,30 @@ Other:
 * Certain characters (space, tab, etc) are now pretty printed.
   * This means that a `char c = ' '; REQUIRE(c == '\t');` would be printed as `' ' == '\t'`, instead of ` == 9`.
 
-#### Fixes:
+##### Fixes:
 * Text formatting no longer attempts to access out-of-bounds characters under certain conditions.
 * THROW family of assertions no longer trigger `-Wunused-value` on expressions containing explicit cast.
 * Breaking into debugger under OS X works again and no longer required `DEBUG` to be defined.
 * Compilation no longer breaks under certain compiler if a lambda is used inside assertion macro.
 
-#### Other:
+##### Other:
 * Catch's CMakeLists now defines install command.
 * Catch's CMakeLists now generates projects with warnings enabled.
 
 
-## 1.6.x
+### 1.6.x
 
-### 1.6.1
+#### 1.6.1
 
-#### Features/ Changes:
+##### Features/ Changes:
 * Catch now supports breaking into debugger on Linux
 
-#### Fixes:
+##### Fixes:
 * Generators no longer leak memory (generators are still unsupported in general)
 * JUnit reporter now reports UTC timestamps, instead of "tbd"
 * `CHECK_THAT` macro is now properly defined as `CATCH_CHECK_THAT` when using `CATCH_` prefixed macros
 
-#### Other:
+##### Other:
 * Types with overloaded `&&` operator are no longer evaluated twice when used in an assertion macro.
 * The use of `__COUNTER__` is supressed when Catch is parsed by CLion
   * This change is not active when compiling a binary
@@ -564,28 +676,28 @@ Other:
   * This can be disabled if needed, see [documentation](configuration.md#top) for details.
 
 
-### 1.6.0
+#### 1.6.0
 
-#### Cmake/ projects:
+##### Cmake/ projects:
 * Moved CMakeLists.txt to root, made it friendlier for CLion and generating XCode and VS projects, and removed the manually maintained XCode and VS projects.
 
-#### Features/ Changes:
+##### Features/ Changes:
 * Approx now supports `>=` and `<=`
 * Can now use `\` to escape chars in test names on command line
 * Standardize C++11 feature toggles
 
-#### Fixes:
+##### Fixes:
 * Blue shell colour
 * Missing argument to `CATCH_CHECK_THROWS`
 * Don't encode extended ASCII in XML
 * use `std::shuffle` on more compilers (fixes deprecation warning/error)
 * Use `__COUNTER__` more consistently (where available)
 
-#### Other:
+##### Other:
 * Tweaks and changes to scripts - particularly for Approval test - to make them more portable
 
 
-# Even Older versions
+## Even Older versions
 Release notes were not maintained prior to v1.6.0, but you should be able to work them out from the Git history
 
 ---
diff --git a/packages/Catch2/docs/reporters.md b/packages/Catch2/docs/reporters.md
index 78e78ee92..32b3419b5 100644
--- a/packages/Catch2/docs/reporters.md
+++ b/packages/Catch2/docs/reporters.md
@@ -25,8 +25,8 @@ Because of the way the junit format is structured the run must complete before a
 There are a few additional reporters, for specific build systems, in the Catch repository (in `include\reporters`) which you can `#include` in your project if you would like to make use of them.
 Do this in one source file - the same one you have `CATCH_CONFIG_MAIN` or `CATCH_CONFIG_RUNNER`.
 
-* `teamcity` writes the native, streaming, format that [TeamCity](https://www.jetbrains.com/teamcity/) understands.
-Use this when building as part of a TeamCity build to see results as they happen.
+* `teamcity` writes the native, streaming, format that [TeamCity](https://www.jetbrains.com/teamcity/) understands. 
+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
 
diff --git a/packages/Catch2/docs/test-cases-and-sections.md b/packages/Catch2/docs/test-cases-and-sections.md
index 68944f51c..621d226ee 100644
--- a/packages/Catch2/docs/test-cases-and-sections.md
+++ b/packages/Catch2/docs/test-cases-and-sections.md
@@ -20,10 +20,10 @@ Tags allow an arbitrary number of additional strings to be associated with a tes
 
 As an example - given the following test cases:
 
-	TEST_CASE( "A", "[widget]" ) { /* ... */ }
-	TEST_CASE( "B", "[widget]" ) { /* ... */ }
-	TEST_CASE( "C", "[gadget]" ) { /* ... */ }
-	TEST_CASE( "D", "[widget][gadget]" ) { /* ... */ }
+    TEST_CASE( "A", "[widget]" ) { /* ... */ }
+    TEST_CASE( "B", "[widget]" ) { /* ... */ }
+    TEST_CASE( "C", "[gadget]" ) { /* ... */ }
+    TEST_CASE( "D", "[widget][gadget]" ) { /* ... */ }
 
 The tag expression, ```"[widget]"``` selects A, B & D. ```"[gadget]"``` selects C & D. ```"[widget][gadget]"``` selects just D and ```"[widget],[gadget]"``` selects all four test cases.
 
@@ -37,7 +37,7 @@ All tag names beginning with non-alphanumeric characters are reserved by Catch.
 
 * `[!hide]` or `[.]` - causes test cases to be skipped from the default list (i.e. when no test cases have been explicitly selected through tag expressions or name wildcards). The hide tag is often combined with another, user, tag (for example `[.][integration]` - so all integration tests are excluded from the default run but can be run by passing `[integration]` on the command line). As a short-cut you can combine these by simply prefixing your user tag with a `.` - e.g. `[.integration]`. Because the hide tag has evolved to have several forms, all forms are added as tags if you use one of them.
 
-* `[!throws]`	- lets Catch know that this test is likely to throw an exception even if successful. This causes the test to be excluded when running with `-e` or `--nothrow`.
+* `[!throws]` - lets Catch know that this test is likely to throw an exception even if successful. This causes the test to be excluded when running with `-e` or `--nothrow`.
 
 * `[!mayfail]` - doesn't fail the test if any given assertion fails (but still reports it). This can be useful to flag a work-in-progress, or a known issue that you don't want to immediately fix but still want to track in your tests.
 
@@ -55,11 +55,11 @@ All tag names beginning with non-alphanumeric characters are reserved by Catch.
 
 Between tag expressions and wildcarded test names (as well as combinations of the two) quite complex patterns can be constructed to direct which test cases are run. If a complex pattern is used often it is convenient to be able to create an alias for the expression. This can be done, in code, using the following form:
 
-	CATCH_REGISTER_TAG_ALIAS( <alias string>, <tag expression> )
+    CATCH_REGISTER_TAG_ALIAS( <alias string>, <tag expression> )
 
 Aliases must begin with the `@` character. An example of a tag alias is:
 
-	CATCH_REGISTER_TAG_ALIAS( "[@nhf]", "[failing]~[.]" )
+    CATCH_REGISTER_TAG_ALIAS( "[@nhf]", "[failing]~[.]" )
 
 Now when `[@nhf]` is used on the command line this matches all tests that are tagged `[failing]`, but which are not also hidden.
 
diff --git a/packages/Catch2/docs/tostring.md b/packages/Catch2/docs/tostring.md
index 568c1c275..be79f6e94 100644
--- a/packages/Catch2/docs/tostring.md
+++ b/packages/Catch2/docs/tostring.md
@@ -1,6 +1,12 @@
 <a id="top"></a>
 # String conversions
 
+**Contents**<br>
+[operator << overload for std::ostream](#operator--overload-for-stdostream)<br>
+[Catch::StringMaker specialisation](#catchstringmaker-specialisation)<br>
+[Catch::is_range specialisation](#catchis_range-specialisation)<br>
+[Exceptions](#exceptions)<br>
+
 Catch needs to be able to convert types you use in assertions and logging expressions into strings (for logging and reporting purposes).
 Most built-in or std types are supported out of the box but there are two ways that you can tell Catch how to convert your own types (or other, third-party types) into strings.
 
@@ -10,8 +16,8 @@ This is the standard way of providing string conversions in C++ - and the chance
 
 ```
 std::ostream& operator << ( std::ostream& os, T const& value ) {
-	os << convertMyTypeToString( value );
-	return os;
+    os << convertMyTypeToString( value );
+    return os;
 }
 ```
 
@@ -19,21 +25,21 @@ std::ostream& operator << ( std::ostream& os, T const& value ) {
 
 You should put this function in the same namespace as your type and have it declared before including Catch's header.
 
-## Catch::StringMaker<T> specialisation
+## Catch::StringMaker specialisation
 If you don't want to provide an ```operator <<``` overload, or you want to convert your type differently for testing purposes, you can provide a specialization for `Catch::StringMaker<T>`:
 
 ```
 namespace Catch {
-	template<>
+    template<>
     struct StringMaker<T> {
-    	static std::string convert( T const& value ) {
-        	return convertMyTypeToString( value );
+        static std::string convert( T const& value ) {
+            return convertMyTypeToString( value );
         }
     };
 }
 ```
 
-## Catch::is_range<T> specialisation
+## Catch::is_range specialisation
 As a fallback, Catch attempts to detect if the type can be iterated
 (`begin(T)` and `end(T)` are valid) and if it can be, it is stringified
 as a range. For certain types this can lead to infinite recursion, so
@@ -56,7 +62,7 @@ By default all exceptions deriving from `std::exception` will be translated to s
 
 ```
 CATCH_TRANSLATE_EXCEPTION( MyType& ex ) {
-	return ex.message();
+    return ex.message();
 }
 ```
 
diff --git a/packages/Catch2/docs/tutorial.md b/packages/Catch2/docs/tutorial.md
index d55355c64..387a250a1 100644
--- a/packages/Catch2/docs/tutorial.md
+++ b/packages/Catch2/docs/tutorial.md
@@ -12,7 +12,10 @@
 
 ## Getting Catch2
 
-The simplest way to get Catch2 is to download the latest [single header version](https://raw.githubusercontent.com/CatchOrg/Catch2/master/single_include/catch.hpp). The single header is generated by merging a set of individual headers but it is still just normal source code in a header file.
+The simplest way to get Catch2 is to download the latest [single header version](https://raw.githubusercontent.com/catchorg/Catch2/master/single_include/catch2/catch.hpp). The single header is generated by merging a set of individual headers but it is still just normal source code in a header file.
+
+Alternative ways of getting Catch2 include using your system package
+manager, or installing it using [its CMake package](cmake-integration.md#installing-catch2-from-git-repository).
 
 The full source for Catch2, including test projects, documentation, and other things, is hosted on GitHub. [http://catch-lib.net](http://catch-lib.net) will redirect you there.
 
@@ -23,6 +26,9 @@ Catch2 is header only. All you need to do is drop the file somewhere reachable f
 
 The rest of this tutorial will assume that the Catch2 single-include header (or the include folder) is available unqualified - but you may need to prefix it with a folder name if necessary.
 
+_If you have installed Catch2 from system package manager, or CMake
+package, you need to include the header as `#include <catch2/catch.hpp>`_
+
 ## Writing tests
 
 Let's start with a really simple example ([code](../examples/010-TestCase.cpp)). Say you have written a function to calculate factorials and now you want to test it (let's leave aside TDD for now). 
diff --git a/packages/Catch2/examples/000-CatchMain.cpp b/packages/Catch2/examples/000-CatchMain.cpp
index c8bf91e45..2894d425a 100644
--- a/packages/Catch2/examples/000-CatchMain.cpp
+++ b/packages/Catch2/examples/000-CatchMain.cpp
@@ -6,7 +6,7 @@
 // Let Catch provide main():
 #define CATCH_CONFIG_MAIN
 
-#include "catch.hpp"
+#include <catch2/catch.hpp>
 
 // That's it
 
diff --git a/packages/Catch2/examples/010-TestCase.cpp b/packages/Catch2/examples/010-TestCase.cpp
index 16a212a3e..c00b8a8f3 100644
--- a/packages/Catch2/examples/010-TestCase.cpp
+++ b/packages/Catch2/examples/010-TestCase.cpp
@@ -3,7 +3,7 @@
 // Let Catch provide main():
 #define CATCH_CONFIG_MAIN
 
-#include "catch.hpp"
+#include <catch2/catch.hpp>
 
 int Factorial( int number ) {
    return number <= 1 ? number : Factorial( number - 1 ) * number;  // fail
diff --git a/packages/Catch2/examples/020-TestCase-1.cpp b/packages/Catch2/examples/020-TestCase-1.cpp
index 0d10276c2..ab0249e4d 100644
--- a/packages/Catch2/examples/020-TestCase-1.cpp
+++ b/packages/Catch2/examples/020-TestCase-1.cpp
@@ -6,7 +6,7 @@
 // Let Catch provide main():
 #define CATCH_CONFIG_MAIN
 
-#include "catch.hpp"
+#include <catch2/catch.hpp>
 
 TEST_CASE( "1: All test cases reside in other .cpp files (empty)", "[multi-file:1]" ) {
 }
diff --git a/packages/Catch2/examples/020-TestCase-2.cpp b/packages/Catch2/examples/020-TestCase-2.cpp
index 2cca36212..08b313e0c 100644
--- a/packages/Catch2/examples/020-TestCase-2.cpp
+++ b/packages/Catch2/examples/020-TestCase-2.cpp
@@ -2,7 +2,7 @@
 
 // main() provided by Catch in file 020-TestCase-1.cpp.
 
-#include "catch.hpp"
+#include <catch2/catch.hpp>
 
 int Factorial( int number ) {
    return number <= 1 ? number : Factorial( number - 1 ) * number;  // fail
diff --git a/packages/Catch2/examples/030-Asn-Require-Check.cpp b/packages/Catch2/examples/030-Asn-Require-Check.cpp
index 35f2ff790..f814a1b3c 100644
--- a/packages/Catch2/examples/030-Asn-Require-Check.cpp
+++ b/packages/Catch2/examples/030-Asn-Require-Check.cpp
@@ -10,7 +10,7 @@
 
 // main() provided in 000-CatchMain.cpp
 
-#include "catch.hpp"
+#include <catch2/catch.hpp>
 
 std::string one() {
     return "1";
diff --git a/packages/Catch2/examples/100-Fix-Section.cpp b/packages/Catch2/examples/100-Fix-Section.cpp
index 8cb94bffd..d0b9f2da5 100644
--- a/packages/Catch2/examples/100-Fix-Section.cpp
+++ b/packages/Catch2/examples/100-Fix-Section.cpp
@@ -6,7 +6,7 @@
 
 // main() provided in 000-CatchMain.cpp
 
-#include "catch.hpp"
+#include <catch2/catch.hpp>
 
 TEST_CASE( "vectors can be sized and resized", "[vector]" ) {
 
diff --git a/packages/Catch2/examples/110-Fix-ClassFixture.cpp b/packages/Catch2/examples/110-Fix-ClassFixture.cpp
index 06c2cf329..e42fd1758 100644
--- a/packages/Catch2/examples/110-Fix-ClassFixture.cpp
+++ b/packages/Catch2/examples/110-Fix-ClassFixture.cpp
@@ -6,7 +6,7 @@
 
 // main() provided in 000-CatchMain.cpp
 
-#include "catch.hpp"
+#include <catch2/catch.hpp>
 
 class DBConnection
 {
diff --git a/packages/Catch2/examples/120-Bdd-ScenarioGivenWhenThen.cpp b/packages/Catch2/examples/120-Bdd-ScenarioGivenWhenThen.cpp
index c45f1f260..d1b9ce558 100644
--- a/packages/Catch2/examples/120-Bdd-ScenarioGivenWhenThen.cpp
+++ b/packages/Catch2/examples/120-Bdd-ScenarioGivenWhenThen.cpp
@@ -2,7 +2,7 @@
 
 // main() provided in 000-CatchMain.cpp
 
-#include "catch.hpp"
+#include <catch2/catch.hpp>
 
 SCENARIO( "vectors can be sized and resized", "[vector]" ) {
 
diff --git a/packages/Catch2/examples/200-Rpt-CatchMain.cpp b/packages/Catch2/examples/200-Rpt-CatchMain.cpp
new file mode 100644
index 000000000..b84c804dd
--- /dev/null
+++ b/packages/Catch2/examples/200-Rpt-CatchMain.cpp
@@ -0,0 +1,27 @@
+// 200-Rpt-CatchMain.cpp
+
+// In a Catch project with multiple files, dedicate one file to compile the
+// source code of Catch itself and reuse the resulting object file for linking.
+
+// Let Catch provide main():
+#define CATCH_CONFIG_MAIN
+
+#include <catch2/catch.hpp>
+
+#ifdef   CATCH_EXAMPLE_RPT_1
+#include CATCH_EXAMPLE_RPT_1
+#endif
+
+#ifdef   CATCH_EXAMPLE_RPT_2
+#include CATCH_EXAMPLE_RPT_2
+#endif
+
+#ifdef   CATCH_EXAMPLE_RPT_3
+#include CATCH_EXAMPLE_RPT_3
+#endif
+
+// That's it
+
+// Compile implementation of Catch for use with files that do contain tests:
+// - g++ -std=c++11 -Wall -I$(CATCH_ROOT) -DCATCH_EXAMPLE_RPT_1=\"include/reporters/catch_reporter_teamcity.hpp\" -o 200-Rpt-CatchMainTeamCity.o -c 200-Rpt-CatchMain.cpp
+// cl -EHsc -I%CATCH_ROOT% -DCATCH_EXAMPLE_RPT_1=\"include/reporters/catch_reporter_teamcity.hpp\" -Fo200-Rpt-CatchMainTeamCity.obj -c 200-Rpt-CatchMain.cpp
diff --git a/packages/Catch2/examples/207-Rpt-TeamCityReporter.cpp b/packages/Catch2/examples/207-Rpt-TeamCityReporter.cpp
new file mode 100644
index 000000000..d28460f40
--- /dev/null
+++ b/packages/Catch2/examples/207-Rpt-TeamCityReporter.cpp
@@ -0,0 +1,171 @@
+// 207-Rpt-TeamCityReporter.cpp
+
+// Catch has built-in and external reporters:
+// Built-in:
+// - compact
+// - console
+// - junit
+// - xml
+// External:
+// - automake
+// - tap
+// - teamcity (this example)
+
+// main() and reporter code provided in 200-Rpt-CatchMain.cpp
+
+#include <catch2/catch.hpp>
+
+#ifdef _MSC_VER
+# pragma warning (disable : 4702) // Disable warning: unreachable code
+#endif
+
+TEST_CASE( "TeamCity passes unconditionally succeeding assertion", "[teamcity]" ) {
+
+    SUCCEED();
+}
+
+TEST_CASE( "TeamCity reports unconditionally failing assertion", "[teamcity]" ) {
+
+    FAIL();
+}
+
+TEST_CASE( "TeamCity reports failing check", "[teamcity]" ) {
+
+    REQUIRE( 3 == 7 );
+}
+
+TEST_CASE( "TeamCity reports failing check-false", "[teamcity]" ) {
+
+    REQUIRE_FALSE( 3 == 3 );
+}
+
+TEST_CASE( "TeamCity reports failing check-that", "[teamcity]" ) {
+
+    using namespace Catch;
+
+    REQUIRE_THAT( "hello", Contains( "world" ) );
+}
+
+TEST_CASE( "TeamCity reports unexpected exception", "[teamcity]" ) {
+
+    REQUIRE( (throw std::runtime_error("surprise!"), true) );
+}
+
+TEST_CASE( "TeamCity reports undesired exception", "[teamcity]" ) {
+
+    REQUIRE_NOTHROW( (throw std::runtime_error("surprise!"), true) );
+}
+
+TEST_CASE( "TeamCity reports missing expected exception", "[teamcity]" ) {
+
+    REQUIRE_THROWS( true );
+}
+
+TEST_CASE( "TeamCity reports missing specific expected exception", "[teamcity]" ) {
+
+    REQUIRE_THROWS_AS( throw std::bad_alloc(), std::runtime_error );
+}
+
+TEST_CASE( "TeamCity reports unexpected message in expected exception", "[teamcity]" ) {
+
+    using namespace Catch;
+
+    CHECK_THROWS_WITH( throw std::runtime_error("hello"), "world" );
+    CHECK_THROWS_WITH( throw std::runtime_error("hello"), Contains("world") );
+}
+
+struct MyException: public std::runtime_error
+{
+    MyException( char const * text )
+    : std::runtime_error( text ) {}
+    
+    ~MyException() override;
+};
+
+// prevent -Wweak-vtables:
+MyException::~MyException() = default;
+
+struct MyExceptionMatcher : Catch::MatcherBase< std::runtime_error >
+{
+    std::string m_text;
+
+    MyExceptionMatcher( char const * text )
+    : m_text( text )
+    {}
+
+    ~MyExceptionMatcher() override;
+    
+    bool match( std::runtime_error const & arg ) const override
+    { 
+        return m_text == arg.what() ; 
+    }
+    
+    std::string describe() const override 
+    { 
+        return "it's me";
+    }
+};
+
+// prevent -Wweak-vtables:
+MyExceptionMatcher::~MyExceptionMatcher() = default;
+
+TEST_CASE( "TeamCity failing check-throws-matches", "[teamcity]" ) {
+
+    CHECK_THROWS_MATCHES( throw MyException("hello"), MyException, MyExceptionMatcher("world") );
+}
+
+// [!throws] - lets Catch know that this test is likely to throw an exception even if successful. 
+// This causes the test to be excluded when running with -e or --nothrow.
+
+// No special effects for the reporter.
+
+TEST_CASE( "TeamCity throwing exception with tag [!throws]", "[teamcity][!throws]" ) {
+
+    REQUIRE_THROWS( throw std::runtime_error("unsurprisingly") );
+}
+
+// [!mayfail] - doesn't fail the test if any given assertion fails (but still reports it). This can be useful to flag a work-in-progress, or a known issue that you don't want to immediately fix but still want to track in your tests.
+
+TEST_CASE( "TeamCity failing assertion with tag [!mayfail]", "[teamcity][!mayfail] " ) {
+
+    REQUIRE( 3 == 7 );  // doesn't fail test case this time, reports: testIgnored
+    REQUIRE( 3 == 3 );
+}
+
+// [!shouldfail] - like [!mayfail] but fails the test if it passes. 
+// This can be useful if you want to be notified of accidental, or third-party, fixes.
+
+TEST_CASE( "TeamCity succeeding assertion with tag [!shouldfail]", "[teamcity][!shouldfail]" ) {
+
+    SUCCEED( "Marked [!shouldfail]" );
+}
+
+// Compile & run:
+// - g++ -std=c++11 -Wall -I$(CATCH_ROOT) -DCATCH_EXAMPLE_RPT_1=\"include/reporters/catch_reporter_teamcity.hpp\" -o 200-Rpt-CatchMainTeamCity.o -c 200-Rpt-CatchMain.cpp
+// - g++ -std=c++11 -Wall -I$(CATCH_ROOT) -o 207-Rpt-TeamCityReporter 207-Rpt-TeamCityReporter.cpp 200-Rpt-CatchMainTeamCity.o && 207-Rpt-TeamCityReporter --list-reporters
+//
+// - cl -EHsc -I%CATCH_ROOT% -DCATCH_EXAMPLE_RPT_1=\"include/reporters/catch_reporter_teamcity.hpp\" -Fo200-Rpt-CatchMainTeamCity.obj -c 200-Rpt-CatchMain.cpp
+// - cl -EHsc -I%CATCH_ROOT% 207-Rpt-TeamCityReporter.cpp 200-Rpt-CatchMainTeamCity.o && 207-Rpt-TeamCityReporter --list-reporters
+
+// Compilation output (--list-reporters):
+// Available reporters:
+//   compact:   Reports test results on a single line, suitable for IDEs
+//   console:   Reports test results as plain lines of text
+//   junit:     Reports test results in an XML format that looks like Ant's
+//                junitreport target
+//   teamcity:  Reports test results as TeamCity service messages
+//   xml:       Reports test results as an XML document
+
+// Expected output (abbreviated and broken into shorter lines):
+//
+// prompt> 207-Rpt-TeamCityReporter.exe --reporter teamcity
+// ##teamcity[testSuiteStarted name='207-Rpt-TeamCityReporter.exe']
+// ##teamcity[testStarted name='TeamCity passes unconditionally succeeding assertion']
+// ##teamcity[testFinished name='TeamCity passes unconditionally succeeding assertion' duration='1']
+// ##teamcity[testStarted name='TeamCity reports unconditionally failing assertion']
+// ##teamcity[testFailed name='TeamCity reports unconditionally failing assertion' /
+// message='.../examples/207-Rpt-TeamCityReporter.cpp:23|n/
+// ...............................................................................|n|n/
+// .../examples/207-Rpt-TeamCityReporter.cpp:25|nexplicit failure']
+// ##teamcity[testFinished name='TeamCity reports unconditionally failing assertion' duration='3']
+// ...
diff --git a/packages/Catch2/examples/210-Evt-EventListeners.cpp b/packages/Catch2/examples/210-Evt-EventListeners.cpp
index 8ba360f5f..7df93d715 100644
--- a/packages/Catch2/examples/210-Evt-EventListeners.cpp
+++ b/packages/Catch2/examples/210-Evt-EventListeners.cpp
@@ -10,7 +10,7 @@
 // Let Catch provide the required interfaces:
 #define CATCH_CONFIG_EXTERNAL_INTERFACES
 
-#include "catch.hpp"
+#include <catch2/catch.hpp>
 #include <iostream>
 
 // -----------------------------------------------------------------------
@@ -187,8 +187,7 @@ void print( std::ostream& os, int const level, std::string const& title, Catch::
 
 void print( std::ostream& os, int const level, std::string const& title, Catch::SectionInfo const& info ) {
     os << ws(level  ) << title << ":\n"
-       << ws(level+1) << "- name: "         << info.name << "\n"
-       << ws(level+1) << "- description: '" << info.description << "'\n";
+       << ws(level+1) << "- name: "         << info.name << "\n";
     print( os, level+1 , "- lineInfo", info.lineInfo );
 }
 
diff --git a/packages/Catch2/examples/231-Cfg-OutputStreams.cpp b/packages/Catch2/examples/231-Cfg-OutputStreams.cpp
new file mode 100644
index 000000000..efa999719
--- /dev/null
+++ b/packages/Catch2/examples/231-Cfg-OutputStreams.cpp
@@ -0,0 +1,49 @@
+// 231-Cfg-OutputStreams.cpp
+// Show how to replace the streams with a simple custom made streambuf.
+
+// Note that this reimplementation _does not_ follow `std::cerr`
+// semantic, because it buffers the output. For most uses however,
+// there is no important difference between having `std::cerr` buffered
+// or unbuffered.
+
+#define CATCH_CONFIG_NOSTDOUT
+#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(); }
+    int sync() {
+        int ret = 0;
+        for (unsigned char c : str()) {
+            if (putc(c, m_stream) == EOF) {
+                ret = -1;
+                break;
+            }
+        }
+        // Reset the buffer to avoid printing it multiple times
+        str("");
+        return ret;
+    }
+};
+
+namespace Catch {
+    std::ostream& cout() {
+        static std::ostream ret(new out_buff(stdout));
+        return ret;
+    }
+    std::ostream& clog() {
+        static std::ostream ret(new out_buff(stderr));
+        return ret;
+    }
+    std::ostream& cerr() {
+        return clog();
+    }
+}
+
+
+TEST_CASE("This binary uses putc to write out output", "[compilation-only]") {
+    SUCCEED("Nothing to test.");
+}
diff --git a/packages/Catch2/examples/CMakeLists.txt b/packages/Catch2/examples/CMakeLists.txt
index 7270e933e..2551e77c0 100644
--- a/packages/Catch2/examples/CMakeLists.txt
+++ b/packages/Catch2/examples/CMakeLists.txt
@@ -8,15 +8,19 @@ cmake_minimum_required( VERSION 3.0 )
 
 project( CatchExamples CXX )
 
+message( STATUS "Examples included" )
+
 # define folders used:
 
 set( EXAMPLES_DIR ${CATCH_DIR}/examples )
 set( HEADER_DIR   ${CATCH_DIR}/single_include )
+set( REPORTER_HEADER_DIR ${CATCH_DIR}/include/reporters )
 
 # single-file sources:
 
 set( SOURCES_SINGLE_FILE
     010-TestCase.cpp
+    231-Cfg-OutputStreams.cpp
 )
 
 # multiple-file modules:
@@ -42,6 +46,26 @@ set( SOURCES_IDIOMATIC_TESTS
     210-Evt-EventListeners.cpp
 )
 
+# main-s for reporter-specific test sources:
+
+set( SOURCES_REPORTERS_MAIN
+    200-Rpt-CatchMain.cpp
+)
+
+string( REPLACE ".cpp" "" BASENAMES_REPORTERS_MAIN 200-Rpt-CatchMain.cpp )
+
+set( NAMES_REPORTERS TeamCity )
+
+foreach( reporter ${NAMES_REPORTERS} )
+    list( APPEND SOURCES_SPECIFIC_REPORTERS_MAIN ${BASENAMES_REPORTERS_MAIN}${reporter}.cpp )
+endforeach()
+
+# sources to combine with 200-Rpt-CatchMain{Reporter}.cpp:
+
+set( SOURCES_REPORTERS_TESTS
+    207-Rpt-TeamCityReporter.cpp
+)
+
 # check if all sources are listed, warn if not:
 
 set( SOURCES_ALL
@@ -49,6 +73,8 @@ set( SOURCES_ALL
     ${SOURCES_SINGLE_FILE}
     ${SOURCES_IDIOMATIC_MAIN}
     ${SOURCES_IDIOMATIC_TESTS}
+    ${SOURCES_REPORTERS_MAIN}
+    ${SOURCES_REPORTERS_TESTS}
 )
 
 foreach( name ${SOURCES_ALL} )
@@ -61,29 +87,55 @@ CheckFileList( SOURCES_ALL_PATH ${EXAMPLES_DIR} )
 
 string( REPLACE ".cpp" "" BASENAMES_SINGLE_FILE     "${SOURCES_SINGLE_FILE}" )
 string( REPLACE ".cpp" "" BASENAMES_IDIOMATIC_TESTS "${SOURCES_IDIOMATIC_TESTS}" )
+string( REPLACE ".cpp" "" BASENAMES_REPORTERS_TESTS "${SOURCES_REPORTERS_TESTS}" )
+string( REPLACE ".cpp" "" BASENAMES_REPORTERS_MAIN  "${SOURCES_REPORTERS_MAIN}" )
 
 set( TARGETS_SINGLE_FILE     ${BASENAMES_SINGLE_FILE} )
 set( TARGETS_IDIOMATIC_TESTS ${BASENAMES_IDIOMATIC_TESTS} )
-set( TARGETS_ALL             ${TARGETS_SINGLE_FILE} ${TARGETS_IDIOMATIC_TESTS} 020-TestCase CatchMain )
+set( TARGETS_REPORTERS_TESTS ${BASENAMES_REPORTERS_TESTS} )
+set( TARGETS_REPORTERS_MAIN  ${BASENAMES_REPORTERS_MAIN} )
+
+set( TARGETS_ALL
+    ${TARGETS_SINGLE_FILE}
+    020-TestCase
+    ${TARGETS_IDIOMATIC_TESTS} CatchMain
+    ${TARGETS_REPORTERS_TESTS} CatchMainTeamCity
+)
 
 # define program targets:
 
-add_library( CatchMain OBJECT ${EXAMPLES_DIR}/${SOURCES_IDIOMATIC_MAIN} ${HEADER_DIR}/catch.hpp )
+add_library( CatchMain         OBJECT ${EXAMPLES_DIR}/${SOURCES_IDIOMATIC_MAIN} ${HEADER_DIR}/catch2/catch.hpp )
+#add_library( CatchMainAutomake OBJECT ${EXAMPLES_DIR}/200-Rpt-CatchMain.cpp ${HEADER_DIR}/catch2/catch.hpp )
+#add_library( CatchMainTap      OBJECT ${EXAMPLES_DIR}/200-Rpt-CatchMain.cpp ${HEADER_DIR}/catch2/catch.hpp )
+add_library( CatchMainTeamCity OBJECT ${EXAMPLES_DIR}/200-Rpt-CatchMain.cpp ${HEADER_DIR}/catch2/catch.hpp )
 
-add_executable( 020-TestCase ${EXAMPLES_DIR}/020-TestCase-1.cpp ${EXAMPLES_DIR}/020-TestCase-2.cpp ${HEADER_DIR}/catch.hpp )
+#target_compile_definitions( CatchMainAutomake PRIVATE CATCH_EXAMPLE_RPT_1=\"include/reporters/catch_reporter_automake.hpp\" )
+#target_compile_definitions( CatchMainTap      PRIVATE CATCH_EXAMPLE_RPT_1=\"include/reporters/catch_reporter_tap.hpp\" )
+target_compile_definitions( CatchMainTeamCity PRIVATE CATCH_EXAMPLE_RPT_1=\"include/reporters/catch_reporter_teamcity.hpp\" )
 
 foreach( name ${TARGETS_SINGLE_FILE} )
-    add_executable( ${name} ${EXAMPLES_DIR}/${name}.cpp ${HEADER_DIR}/catch.hpp )
+    add_executable( ${name} ${EXAMPLES_DIR}/${name}.cpp ${HEADER_DIR}/catch2/catch.hpp )
 endforeach()
 
 foreach( name ${TARGETS_IDIOMATIC_TESTS} )
-    add_executable( ${name} ${EXAMPLES_DIR}/${name}.cpp $<TARGET_OBJECTS:CatchMain> ${HEADER_DIR}/catch.hpp )
+    add_executable( ${name} ${EXAMPLES_DIR}/${name}.cpp $<TARGET_OBJECTS:CatchMain> ${HEADER_DIR}/catch2/catch.hpp )
 endforeach()
 
+add_executable( 020-TestCase ${EXAMPLES_DIR}/020-TestCase-1.cpp ${EXAMPLES_DIR}/020-TestCase-2.cpp ${HEADER_DIR}/catch2/catch.hpp )
+
+#add_executable( 207-Rpt-AutomakeReporter ${EXAMPLES_DIR}/207-Rpt-AutomakeReporter.cpp $<TARGET_OBJECTS:CatchMainAutomake> ${HEADER_DIR}/catch2/catch.hpp )
+#add_executable( 207-Rpt-TapReporter      ${EXAMPLES_DIR}/207-Rpt-TapReporter.cpp      $<TARGET_OBJECTS:CatchMainTap>      ${HEADER_DIR}/catch2/catch.hpp )
+add_executable( 207-Rpt-TeamCityReporter ${EXAMPLES_DIR}/207-Rpt-TeamCityReporter.cpp $<TARGET_OBJECTS:CatchMainTeamCity> ${HEADER_DIR}/catch2/catch.hpp )
+
+#foreach( name ${TARGETS_REPORTERS_TESTS} )
+#    add_executable( ${name} ${EXAMPLES_DIR}/${name}.cpp $<TARGET_OBJECTS:CatchMain> ${HEADER_DIR}/catch2/catch.hpp )
+#endforeach()
+
 foreach( name ${TARGETS_ALL} )
-    target_include_directories( ${name} PRIVATE ${HEADER_DIR} )
+    target_include_directories( ${name} PRIVATE ${HEADER_DIR} ${CATCH_DIR} )
 
     set_property(TARGET ${name} PROPERTY CXX_STANDARD 11)
+    set_property(TARGET ${name} PROPERTY CXX_EXTENSIONS OFF)
 
     # Add desired warnings
     if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang|GNU" )
@@ -98,3 +150,4 @@ foreach( name ${TARGETS_ALL} )
         target_compile_options( ${name}  PRIVATE /W4 /w44265 /WX )
     endif()
 endforeach()
+
diff --git a/packages/Catch2/include/catch.hpp b/packages/Catch2/include/catch.hpp
index 0c92ed3af..f8b380c4e 100644
--- a/packages/Catch2/include/catch.hpp
+++ b/packages/Catch2/include/catch.hpp
@@ -10,8 +10,8 @@
 #define TWOBLUECUBES_CATCH_HPP_INCLUDED
 
 #define CATCH_VERSION_MAJOR 2
-#define CATCH_VERSION_MINOR 2
-#define CATCH_VERSION_PATCH 3
+#define CATCH_VERSION_MINOR 4
+#define CATCH_VERSION_PATCH 1
 
 #ifdef __clang__
 #    pragma clang system_header
@@ -33,7 +33,9 @@
 #  if defined(CATCH_CONFIG_DISABLE_MATCHERS)
 #    undef CATCH_CONFIG_DISABLE_MATCHERS
 #  endif
-#  define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
+#  if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
+#    define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
+#  endif
 #endif
 
 #if !defined(CATCH_CONFIG_IMPL_ONLY)
@@ -60,6 +62,7 @@
 #ifndef CATCH_CONFIG_DISABLE_MATCHERS
 #include "internal/catch_capture_matchers.h"
 #endif
+#include "internal/catch_generators.hpp"
 
 // These files are included here so the single_include script doesn't put them
 // in the conditionally compiled sections
@@ -128,13 +131,14 @@
 
 #define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg )
 #define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( "CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
-#define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( "CATCH_CAPTURE", #msg " := " << ::Catch::Detail::stringify(msg) )
+#define CATCH_CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CATCH_CAPTURE",__VA_ARGS__ )
 
 #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
 #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
 #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
 #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
 #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
+#define CATCH_DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )
 #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
 #define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
 #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
@@ -144,11 +148,12 @@
 // "BDD-style" convenience wrappers
 #define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
 #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
-#define CATCH_GIVEN( desc )    CATCH_SECTION( std::string( "Given: ") + desc )
-#define CATCH_WHEN( desc )     CATCH_SECTION( std::string( " When: ") + desc )
-#define CATCH_AND_WHEN( desc ) CATCH_SECTION( std::string( "  And: ") + desc )
-#define CATCH_THEN( desc )     CATCH_SECTION( std::string( " Then: ") + desc )
-#define CATCH_AND_THEN( desc ) CATCH_SECTION( std::string( "  And: ") + desc )
+#define CATCH_GIVEN( desc )     INTERNAL_CATCH_DYNAMIC_SECTION( "    Given: " << desc )
+#define CATCH_AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc )
+#define CATCH_WHEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     When: " << desc )
+#define CATCH_AND_WHEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc )
+#define CATCH_THEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     Then: " << desc )
+#define CATCH_AND_THEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( "      And: " << desc )
 
 // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
 #else
@@ -187,13 +192,14 @@
 
 #define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg )
 #define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
-#define CAPTURE( msg ) INTERNAL_CATCH_INFO( "CAPTURE", #msg " := " << ::Catch::Detail::stringify(msg) )
+#define CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CAPTURE",__VA_ARGS__ )
 
 #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
 #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
 #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
 #define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
 #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
+#define DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )
 #define FAIL( ... ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
 #define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
 #define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
@@ -207,15 +213,17 @@
 #define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
 #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
 
-#define GIVEN( desc )    SECTION( std::string("   Given: ") + desc )
-#define WHEN( desc )     SECTION( std::string("    When: ") + desc )
-#define AND_WHEN( desc ) SECTION( std::string("And when: ") + desc )
-#define THEN( desc )     SECTION( std::string("    Then: ") + desc )
-#define AND_THEN( desc ) SECTION( std::string("     And: ") + desc )
+#define GIVEN( desc )     INTERNAL_CATCH_DYNAMIC_SECTION( "    Given: " << desc )
+#define AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc )
+#define WHEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     When: " << desc )
+#define AND_WHEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc )
+#define THEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     Then: " << desc )
+#define AND_THEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( "      And: " << desc )
 
 using Catch::Detail::Approx;
 
-#else
+#else // CATCH_CONFIG_DISABLE
+
 //////
 // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
 #ifdef CATCH_CONFIG_PREFIX_ALL
@@ -260,6 +268,7 @@ using Catch::Detail::Approx;
 #define CATCH_METHOD_AS_TEST_CASE( method, ... )
 #define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0)
 #define CATCH_SECTION( ... )
+#define CATCH_DYNAMIC_SECTION( ... )
 #define CATCH_FAIL( ... ) (void)(0)
 #define CATCH_FAIL_CHECK( ... ) (void)(0)
 #define CATCH_SUCCEED( ... ) (void)(0)
@@ -270,6 +279,7 @@ using Catch::Detail::Approx;
 #define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
 #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className )
 #define CATCH_GIVEN( desc )
+#define CATCH_AND_GIVEN( desc )
 #define CATCH_WHEN( desc )
 #define CATCH_AND_WHEN( desc )
 #define CATCH_THEN( desc )
@@ -319,6 +329,7 @@ using Catch::Detail::Approx;
 #define METHOD_AS_TEST_CASE( method, ... )
 #define REGISTER_TEST_CASE( Function, ... ) (void)(0)
 #define SECTION( ... )
+#define DYNAMIC_SECTION( ... )
 #define FAIL( ... ) (void)(0)
 #define FAIL_CHECK( ... ) (void)(0)
 #define SUCCEED( ... ) (void)(0)
@@ -333,6 +344,7 @@ using Catch::Detail::Approx;
 #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className )
 
 #define GIVEN( desc )
+#define AND_GIVEN( desc )
 #define WHEN( desc )
 #define AND_WHEN( desc )
 #define THEN( desc )
diff --git a/packages/Catch2/include/internal/catch_approx.cpp b/packages/Catch2/include/internal/catch_approx.cpp
index 20f7b1652..a7d7111ca 100644
--- a/packages/Catch2/include/internal/catch_approx.cpp
+++ b/packages/Catch2/include/internal/catch_approx.cpp
@@ -7,6 +7,7 @@
  */
 
 #include "catch_approx.h"
+#include "catch_enforce.h"
 
 #include <cmath>
 #include <limits>
@@ -35,6 +36,13 @@ namespace Detail {
         return Approx( 0 );
     }
 
+    Approx Approx::operator-() const {
+        auto temp(*this);
+        temp.m_value = -temp.m_value;
+        return temp;
+    }
+
+
     std::string Approx::toString() const {
         ReusableStringStream rss;
         rss << "Approx( " << ::Catch::Detail::stringify( m_value ) << " )";
@@ -47,8 +55,31 @@ namespace Detail {
         return marginComparison(m_value, other, m_margin) || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(m_value)));
     }
 
+    void Approx::setMargin(double margin) {
+        CATCH_ENFORCE(margin >= 0,
+            "Invalid Approx::margin: " << margin << '.'
+            << " Approx::Margin has to be non-negative.");
+        m_margin = margin;
+    }
+
+    void Approx::setEpsilon(double epsilon) {
+        CATCH_ENFORCE(epsilon >= 0 && epsilon <= 1.0,
+            "Invalid Approx::epsilon: " << epsilon << '.'
+            << " Approx::epsilon has to be in [0, 1]");
+        m_epsilon = epsilon;
+    }
+
 } // end namespace Detail
 
+namespace literals {
+    Detail::Approx operator "" _a(long double val) {
+        return Detail::Approx(val);
+    }
+    Detail::Approx operator "" _a(unsigned long long val) {
+        return Detail::Approx(val);
+    }
+} // end namespace literals
+
 std::string StringMaker<Catch::Detail::Approx>::convert(Catch::Detail::Approx const& value) {
     return value.toString();
 }
diff --git a/packages/Catch2/include/internal/catch_approx.h b/packages/Catch2/include/internal/catch_approx.h
index 27068872e..4522e5ad7 100644
--- a/packages/Catch2/include/internal/catch_approx.h
+++ b/packages/Catch2/include/internal/catch_approx.h
@@ -11,7 +11,6 @@
 #include "catch_tostring.h"
 
 #include <type_traits>
-#include <stdexcept>
 
 namespace Catch {
 namespace Detail {
@@ -19,18 +18,26 @@ namespace Detail {
     class Approx {
     private:
         bool equalityComparisonImpl(double other) const;
+        // Validates the new margin (margin >= 0)
+        // out-of-line to avoid including stdexcept in the header
+        void setMargin(double margin);
+        // Validates the new epsilon (0 < epsilon < 1)
+        // out-of-line to avoid including stdexcept in the header
+        void setEpsilon(double epsilon);
 
     public:
         explicit Approx ( double value );
 
         static Approx custom();
 
+        Approx operator-() const;
+
         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
         Approx operator()( T const& value ) {
             Approx approx( static_cast<double>(value) );
-            approx.epsilon( m_epsilon );
-            approx.margin( m_margin );
-            approx.scale( m_scale );
+            approx.m_epsilon = m_epsilon;
+            approx.m_margin = m_margin;
+            approx.m_scale = m_scale;
             return approx;
         }
 
@@ -83,27 +90,14 @@ namespace Detail {
         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
         Approx& epsilon( T const& newEpsilon ) {
             double epsilonAsDouble = static_cast<double>(newEpsilon);
-            if( epsilonAsDouble < 0 || epsilonAsDouble > 1.0 ) {
-                throw std::domain_error
-                    (   "Invalid Approx::epsilon: " +
-                        Catch::Detail::stringify( epsilonAsDouble ) +
-                        ", Approx::epsilon has to be between 0 and 1" );
-            }
-            m_epsilon = epsilonAsDouble;
+            setEpsilon(epsilonAsDouble);
             return *this;
         }
 
         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
         Approx& margin( T const& newMargin ) {
             double marginAsDouble = static_cast<double>(newMargin);
-            if( marginAsDouble < 0 ) {
-                throw std::domain_error
-                    (   "Invalid Approx::margin: " +
-                         Catch::Detail::stringify( marginAsDouble ) +
-                         ", Approx::Margin has to be non-negative." );
-
-            }
-            m_margin = marginAsDouble;
+            setMargin(marginAsDouble);
             return *this;
         }
 
@@ -121,7 +115,12 @@ namespace Detail {
         double m_scale;
         double m_value;
     };
-}
+} // end namespace Detail
+
+namespace literals {
+    Detail::Approx operator "" _a(long double val);
+    Detail::Approx operator "" _a(unsigned long long val);
+} // end namespace literals
 
 template<>
 struct StringMaker<Catch::Detail::Approx> {
diff --git a/packages/Catch2/include/internal/catch_assertionhandler.cpp b/packages/Catch2/include/internal/catch_assertionhandler.cpp
index 28768077a..77c3f1d47 100644
--- a/packages/Catch2/include/internal/catch_assertionhandler.cpp
+++ b/packages/Catch2/include/internal/catch_assertionhandler.cpp
@@ -52,7 +52,7 @@ namespace Catch {
     }
 
     AssertionHandler::AssertionHandler
-        (   StringRef macroName,
+        (   StringRef const& macroName,
             SourceLineInfo const& lineInfo,
             StringRef capturedExpression,
             ResultDisposition::Flags resultDisposition )
@@ -81,8 +81,13 @@ namespace Catch {
             // (To go back to the test and change execution, jump over the throw, next)
             CATCH_BREAK_INTO_DEBUGGER();
         }
-        if( m_reaction.shouldThrow )
+        if (m_reaction.shouldThrow) {
+#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
             throw Catch::TestFailureException();
+#else
+            CATCH_ERROR( "Test failure requires aborting test!" );
+#endif
+        }
     }
     void AssertionHandler::setCompleted() {
         m_completed = true;
@@ -109,7 +114,7 @@ namespace Catch {
 
     // This is the overload that takes a string and infers the Equals matcher from it
     // The more general overload, that takes any string matcher, is in catch_capture_matchers.cpp
-    void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef matcherString  ) {
+    void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString  ) {
         handleExceptionMatchExpr( handler, Matchers::Equals( str ), matcherString );
     }
 
diff --git a/packages/Catch2/include/internal/catch_assertionhandler.h b/packages/Catch2/include/internal/catch_assertionhandler.h
index cadc78f34..3089e662c 100644
--- a/packages/Catch2/include/internal/catch_assertionhandler.h
+++ b/packages/Catch2/include/internal/catch_assertionhandler.h
@@ -49,7 +49,7 @@ namespace Catch {
 
     public:
         AssertionHandler
-            (   StringRef macroName,
+            (   StringRef const& macroName,
                 SourceLineInfo const& lineInfo,
                 StringRef capturedExpression,
                 ResultDisposition::Flags resultDisposition );
@@ -81,7 +81,7 @@ namespace Catch {
         auto allowThrows() const -> bool;
     };
 
-    void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef matcherString );
+    void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString );
 
 } // namespace Catch
 
diff --git a/packages/Catch2/include/internal/catch_capture.hpp b/packages/Catch2/include/internal/catch_capture.hpp
index e4600f7c6..a9c2e0d72 100644
--- a/packages/Catch2/include/internal/catch_capture.hpp
+++ b/packages/Catch2/include/internal/catch_capture.hpp
@@ -9,8 +9,9 @@
 #define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED
 
 #include "catch_assertionhandler.h"
-#include "catch_message.h"
 #include "catch_interfaces_capture.h"
+#include "catch_message.h"
+#include "catch_stringref.h"
 
 #if !defined(CATCH_CONFIG_DISABLE)
 
@@ -20,7 +21,7 @@
   #define CATCH_INTERNAL_STRINGIFY(...) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION"
 #endif
 
-#if defined(CATCH_CONFIG_FAST_COMPILE)
+#if defined(CATCH_CONFIG_FAST_COMPILE) || defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
 
 ///////////////////////////////////////////////////////////////////////////////
 // Another way to speed-up compilation is to omit local try-catch for REQUIRE*
@@ -40,7 +41,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 #define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \
     do { \
-        Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
+        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
         INTERNAL_CATCH_TRY { \
             CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
             catchAssertionHandler.handleExpr( Catch::Decomposer() <= __VA_ARGS__ ); \
@@ -63,7 +64,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 #define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, ... ) \
     do { \
-        Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
+        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
         try { \
             static_cast<void>(__VA_ARGS__); \
             catchAssertionHandler.handleExceptionNotThrownAsExpected(); \
@@ -77,7 +78,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 #define INTERNAL_CATCH_THROWS( macroName, resultDisposition, ... ) \
     do { \
-        Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \
+        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \
         if( catchAssertionHandler.allowThrows() ) \
             try { \
                 static_cast<void>(__VA_ARGS__); \
@@ -94,7 +95,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 #define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \
     do { \
-        Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \
+        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \
         if( catchAssertionHandler.allowThrows() ) \
             try { \
                 static_cast<void>(expr); \
@@ -115,27 +116,32 @@
 ///////////////////////////////////////////////////////////////////////////////
 #define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \
     do { \
-        Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
+        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::StringRef(), resultDisposition ); \
         catchAssertionHandler.handleMessage( messageType, ( Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop() ).m_stream.str() ); \
         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
     } while( false )
 
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_CAPTURE( varName, macroName, ... ) \
+    auto varName = Catch::Capturer( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info, #__VA_ARGS__ ); \
+    varName.captureValues( 0, __VA_ARGS__ )
+
 ///////////////////////////////////////////////////////////////////////////////
 #define INTERNAL_CATCH_INFO( macroName, log ) \
-    Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log );
+    Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log );
 
 ///////////////////////////////////////////////////////////////////////////////
 // Although this is matcher-based, it can be used with just a string
 #define INTERNAL_CATCH_THROWS_STR_MATCHES( macroName, resultDisposition, matcher, ... ) \
     do { \
-        Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
+        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
         if( catchAssertionHandler.allowThrows() ) \
             try { \
                 static_cast<void>(__VA_ARGS__); \
                 catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
             } \
             catch( ... ) { \
-                Catch::handleExceptionMatchExpr( catchAssertionHandler, matcher, #matcher ); \
+                Catch::handleExceptionMatchExpr( catchAssertionHandler, matcher, #matcher##_catch_sr ); \
             } \
         else \
             catchAssertionHandler.handleThrowingCallSkipped(); \
diff --git a/packages/Catch2/include/internal/catch_capture_matchers.cpp b/packages/Catch2/include/internal/catch_capture_matchers.cpp
index a67cc797a..6f320449a 100644
--- a/packages/Catch2/include/internal/catch_capture_matchers.cpp
+++ b/packages/Catch2/include/internal/catch_capture_matchers.cpp
@@ -15,7 +15,7 @@ namespace Catch {
     // This is the general overload that takes a any string matcher
     // There is another overload, in catch_assertionhandler.h/.cpp, that only takes a string and infers
     // the Equals matcher (so the header does not mention matchers)
-    void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef matcherString  ) {
+    void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString  ) {
         std::string exceptionMessage = Catch::translateActiveException();
         MatchExpr<std::string, StringMatcher const&> expr( exceptionMessage, matcher, matcherString );
         handler.handleExpr( expr );
diff --git a/packages/Catch2/include/internal/catch_capture_matchers.h b/packages/Catch2/include/internal/catch_capture_matchers.h
index 9026aebf6..0ced01d57 100644
--- a/packages/Catch2/include/internal/catch_capture_matchers.h
+++ b/packages/Catch2/include/internal/catch_capture_matchers.h
@@ -14,6 +14,7 @@
 #include "catch_matchers_generic.hpp"
 #include "catch_matchers_string.h"
 #include "catch_matchers_vector.h"
+#include "catch_stringref.h"
 
 namespace Catch {
 
@@ -23,7 +24,7 @@ namespace Catch {
         MatcherT m_matcher;
         StringRef m_matcherString;
     public:
-        MatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef matcherString )
+        MatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString )
         :   ITransientExpression{ true, matcher.match( arg ) },
             m_arg( arg ),
             m_matcher( matcher ),
@@ -42,10 +43,10 @@ namespace Catch {
 
     using StringMatcher = Matchers::Impl::MatcherBase<std::string>;
 
-    void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef matcherString  );
+    void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString  );
 
     template<typename ArgT, typename MatcherT>
-    auto makeMatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef matcherString  ) -> MatchExpr<ArgT, MatcherT> {
+    auto makeMatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString  ) -> MatchExpr<ArgT, MatcherT> {
         return MatchExpr<ArgT, MatcherT>( arg, matcher, matcherString );
     }
 
@@ -55,9 +56,9 @@ namespace Catch {
 ///////////////////////////////////////////////////////////////////////////////
 #define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \
     do { \
-        Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
+        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
         INTERNAL_CATCH_TRY { \
-            catchAssertionHandler.handleExpr( Catch::makeMatchExpr( arg, matcher, #matcher ) ); \
+            catchAssertionHandler.handleExpr( Catch::makeMatchExpr( arg, matcher, #matcher##_catch_sr ) ); \
         } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
     } while( false )
@@ -66,14 +67,14 @@ namespace Catch {
 ///////////////////////////////////////////////////////////////////////////////
 #define INTERNAL_CATCH_THROWS_MATCHES( macroName, exceptionType, resultDisposition, matcher, ... ) \
     do { \
-        Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(exceptionType) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
+        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(exceptionType) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
         if( catchAssertionHandler.allowThrows() ) \
             try { \
                 static_cast<void>(__VA_ARGS__ ); \
                 catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
             } \
             catch( exceptionType const& ex ) { \
-                catchAssertionHandler.handleExpr( Catch::makeMatchExpr( ex, matcher, #matcher ) ); \
+                catchAssertionHandler.handleExpr( Catch::makeMatchExpr( ex, matcher, #matcher##_catch_sr ) ); \
             } \
             catch( ... ) { \
                 catchAssertionHandler.handleUnexpectedInflightException(); \
diff --git a/packages/Catch2/include/internal/catch_common.cpp b/packages/Catch2/include/internal/catch_common.cpp
index c271146d7..b2fca4c4c 100644
--- a/packages/Catch2/include/internal/catch_common.cpp
+++ b/packages/Catch2/include/internal/catch_common.cpp
@@ -22,7 +22,9 @@ namespace Catch {
         return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0);
     }
     bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const noexcept {
-        return line < other.line || ( line == other.line && (std::strcmp(file, other.file) < 0));
+        // We can assume that the same file will usually have the same pointer.
+        // Thus, if the pointers are the same, there is no point in calling the strcmp
+        return line < other.line || ( line == other.line && file != other.file && (std::strcmp(file, other.file) < 0));
     }
 
     std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
diff --git a/packages/Catch2/include/internal/catch_compiler_capabilities.h b/packages/Catch2/include/internal/catch_compiler_capabilities.h
index 37f625b28..aa3e599e3 100644
--- a/packages/Catch2/include/internal/catch_compiler_capabilities.h
+++ b/packages/Catch2/include/internal/catch_compiler_capabilities.h
@@ -14,6 +14,7 @@
 // CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?
 // CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported?
 // CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported?
+// CATCH_CONFIG_DISABLE_EXCEPTIONS : Are exceptions enabled?
 // ****************
 // Note to maintainers: if new toggles are added please document them
 // in configuration.md, too
@@ -28,11 +29,11 @@
 
 #ifdef __cplusplus
 
-#  if __cplusplus >= 201402L
+#  if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
 #    define CATCH_CPP14_OR_GREATER
 #  endif
 
-#  if __cplusplus >= 201703L
+#  if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
 #    define CATCH_CPP17_OR_GREATER
 #  endif
 
@@ -57,6 +58,12 @@
 #       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" )
+
 #endif // __clang__
 
 
@@ -89,6 +96,12 @@
 #    define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
 #endif
 
+////////////////////////////////////////////////////////////////////////////////
+// PS4
+#if defined(__ORBIS__)
+#    define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE
+#endif
+
 ////////////////////////////////////////////////////////////////////////////////
 // Cygwin
 #ifdef __CYGWIN__
@@ -96,7 +109,14 @@
 // Required for some versions of Cygwin to declare gettimeofday
 // see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin
 #   define _BSD_SOURCE
+// some versions of cygwin (most) do not support std::to_string. Use the libstd check. 
+// https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html line 2812-2813
+# if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \
+	       && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))
+
+#	define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
 
+# endif
 #endif // __CYGWIN__
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -119,7 +139,12 @@
 #endif // _MSC_VER
 
 ////////////////////////////////////////////////////////////////////////////////
+// Check if we are compiled with -fno-exceptions or equivalent
+#if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND)
+#  define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED
+#endif
 
+////////////////////////////////////////////////////////////////////////////////
 // DJGPP
 #ifdef __DJGPP__
 #  define CATCH_INTERNAL_CONFIG_NO_WCHAR
@@ -136,6 +161,33 @@
     #define CATCH_INTERNAL_CONFIG_COUNTER
 #endif
 
+////////////////////////////////////////////////////////////////////////////////
+// Check if string_view is available and usable
+// The check is split apart to work around v140 (VS2015) preprocessor issue...
+#if defined(__has_include)
+#if __has_include(<string_view>) && defined(CATCH_CPP17_OR_GREATER)
+#    define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW
+#endif
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+// Check if variant is available and usable
+#if defined(__has_include)
+#  if __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
+#    if defined(__clang__) && (__clang_major__ < 8)
+       // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852
+       // fix should be in clang 8, workaround in libstdc++ 8.2
+#      include <ciso646>
+#      if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
+#        define CATCH_CONFIG_NO_CPP17_VARIANT
+#     else
+#        define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
+#      endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
+#    endif // defined(__clang__) && (__clang_major__ < 8)
+#  endif // __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
+#endif // __has_include
+
+
 #if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
 #   define CATCH_CONFIG_COUNTER
 #endif
@@ -159,6 +211,25 @@
 #  define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
 #endif
 
+#if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW)
+#  define CATCH_CONFIG_CPP17_STRING_VIEW
+#endif
+
+#if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT)
+#  define CATCH_CONFIG_CPP17_VARIANT
+#endif
+
+#if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
+#  define CATCH_INTERNAL_CONFIG_NEW_CAPTURE
+#endif
+
+#if defined(CATCH_INTERNAL_CONFIG_NEW_CAPTURE) && !defined(CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NEW_CAPTURE)
+#  define CATCH_CONFIG_NEW_CAPTURE
+#endif
+
+#if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
+#  define CATCH_CONFIG_DISABLE_EXCEPTIONS
+#endif
 
 #if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
 #   define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
@@ -168,6 +239,20 @@
 #   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_CONFIG_DISABLE_EXCEPTIONS)
+#define CATCH_TRY if ((true))
+#define CATCH_CATCH_ALL if ((false))
+#define CATCH_CATCH_ANON(type) if ((false))
+#else
+#define CATCH_TRY try
+#define CATCH_CATCH_ALL catch (...)
+#define CATCH_CATCH_ANON(type) catch (type)
+#endif
 
 
 #endif // TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED
diff --git a/packages/Catch2/include/internal/catch_enforce.cpp b/packages/Catch2/include/internal/catch_enforce.cpp
new file mode 100644
index 000000000..f4db1c150
--- /dev/null
+++ b/packages/Catch2/include/internal/catch_enforce.cpp
@@ -0,0 +1,19 @@
+/*
+ *  Created by Martin on 03/09/2018.
+ *
+ *  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)
+ */
+
+#include "catch_enforce.h"
+
+namespace Catch {
+#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS_CUSTOM_HANDLER)
+    [[noreturn]]
+    void throw_exception(std::exception const& e) {
+        Catch::cerr() << "Catch will terminate because it needed to throw an exception.\n"
+                      << "The message was: " << e.what() << '\n';
+        std::terminate();
+    }
+#endif
+} // namespace Catch;
diff --git a/packages/Catch2/include/internal/catch_enforce.h b/packages/Catch2/include/internal/catch_enforce.h
index 513dcf1c6..006940230 100644
--- a/packages/Catch2/include/internal/catch_enforce.h
+++ b/packages/Catch2/include/internal/catch_enforce.h
@@ -8,17 +8,35 @@
 #define TWOBLUECUBES_CATCH_ENFORCE_H_INCLUDED
 
 #include "catch_common.h"
+#include "catch_compiler_capabilities.h"
 #include "catch_stream.h"
 
+
 #include <stdexcept>
 
+namespace Catch {
+#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
+    template <typename Ex>
+    [[noreturn]]
+    void throw_exception(Ex const& e) {
+        throw e;
+    }
+#else // ^^ Exceptions are enabled //  Exceptions are disabled vv
+    [[noreturn]]
+    void throw_exception(std::exception const& e);
+#endif
+} // namespace Catch;
+
 #define CATCH_PREPARE_EXCEPTION( type, msg ) \
     type( ( Catch::ReusableStringStream() << msg ).str() )
 #define CATCH_INTERNAL_ERROR( msg ) \
-    throw CATCH_PREPARE_EXCEPTION( std::logic_error, CATCH_INTERNAL_LINEINFO << ": Internal Catch error: " << msg);
+    Catch::throw_exception(CATCH_PREPARE_EXCEPTION( std::logic_error, CATCH_INTERNAL_LINEINFO << ": Internal Catch error: " << msg))
 #define CATCH_ERROR( msg ) \
-    throw CATCH_PREPARE_EXCEPTION( std::domain_error, msg )
+    Catch::throw_exception(CATCH_PREPARE_EXCEPTION( std::domain_error, msg ))
+#define CATCH_RUNTIME_ERROR( msg ) \
+    Catch::throw_exception(CATCH_PREPARE_EXCEPTION( std::runtime_error, msg ))
 #define CATCH_ENFORCE( condition, msg ) \
     do{ if( !(condition) ) CATCH_ERROR( msg ); } while(false)
 
+
 #endif // TWOBLUECUBES_CATCH_ENFORCE_H_INCLUDED
diff --git a/packages/Catch2/include/internal/catch_exception_translator_registry.cpp b/packages/Catch2/include/internal/catch_exception_translator_registry.cpp
index 78b9c5733..b836cd9cb 100644
--- a/packages/Catch2/include/internal/catch_exception_translator_registry.cpp
+++ b/packages/Catch2/include/internal/catch_exception_translator_registry.cpp
@@ -6,8 +6,10 @@
  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  */
 
-#include "catch_assertionhandler.h"
 #include "catch_exception_translator_registry.h"
+#include "catch_assertionhandler.h"
+#include "catch_compiler_capabilities.h"
+#include "catch_enforce.h"
 
 #ifdef __OBJC__
 #import "Foundation/Foundation.h"
@@ -22,6 +24,7 @@ namespace Catch {
         m_translators.push_back( std::unique_ptr<const IExceptionTranslator>( translator ) );
     }
 
+#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
     std::string ExceptionTranslatorRegistry::translateActiveException() const {
         try {
 #ifdef __OBJC__
@@ -64,6 +67,13 @@ namespace Catch {
         }
     }
 
+#else // ^^ Exceptions are enabled // Exceptions are disabled vv
+    std::string ExceptionTranslatorRegistry::translateActiveException() const {
+        CATCH_INTERNAL_ERROR("Attempted to translate active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
+    }
+#endif
+
+
     std::string ExceptionTranslatorRegistry::tryTranslators() const {
         if( m_translators.empty() )
             std::rethrow_exception(std::current_exception());
diff --git a/packages/Catch2/include/internal/catch_generators.cpp b/packages/Catch2/include/internal/catch_generators.cpp
new file mode 100644
index 000000000..786da7367
--- /dev/null
+++ b/packages/Catch2/include/internal/catch_generators.cpp
@@ -0,0 +1,50 @@
+/*
+ *  Created by Phil Nash on 15/6/2018.
+ *
+ *  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)
+ */
+
+#include "catch_generators.hpp"
+#include "catch_random_number_generator.h"
+#include "catch_interfaces_capture.h"
+
+#include <limits>
+#include <set>
+
+namespace Catch {
+
+IGeneratorTracker::~IGeneratorTracker() {}
+
+namespace Generators {
+
+    GeneratorBase::~GeneratorBase() {}
+
+    std::vector<size_t> randomiseIndices( size_t selectionSize, size_t sourceSize ) {
+
+        assert( selectionSize <= sourceSize );
+        std::vector<size_t> indices;
+        indices.reserve( selectionSize );
+        std::uniform_int_distribution<size_t> uid( 0, sourceSize-1 );
+
+        std::set<size_t> seen;
+        // !TBD: improve this algorithm
+        while( indices.size() < selectionSize ) {
+            auto index = uid( rng() );
+            if( seen.insert( index ).second )
+                indices.push_back( index );
+        }
+        return indices;
+    }
+
+    auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
+        return getResultCapture().acquireGeneratorTracker( lineInfo );
+    }
+
+    template<>
+    auto all<int>() -> Generator<int> {
+        return range( std::numeric_limits<int>::min(), std::numeric_limits<int>::max() );
+    }
+
+} // namespace Generators
+} // namespace Catch
diff --git a/packages/Catch2/include/internal/catch_generators.hpp b/packages/Catch2/include/internal/catch_generators.hpp
new file mode 100644
index 000000000..4a446be13
--- /dev/null
+++ b/packages/Catch2/include/internal/catch_generators.hpp
@@ -0,0 +1,253 @@
+/*
+ *  Created by Phil Nash on 15/6/2018.
+ *
+ *  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 TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED
+#define TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED
+
+#include "catch_interfaces_generatortracker.h"
+#include "catch_common.h"
+#include "catch_enforce.h"
+
+#include <memory>
+#include <vector>
+#include <cassert>
+
+#include <utility>
+
+namespace Catch {
+namespace Generators {
+
+    // !TBD move this into its own location?
+    namespace pf{
+        template<typename T, typename... Args>
+        std::unique_ptr<T> make_unique( Args&&... args ) {
+            return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
+        }
+    }
+
+    template<typename T>
+    struct IGenerator {
+        virtual ~IGenerator() {}
+        virtual auto get( size_t index ) const -> T = 0;
+    };
+
+    template<typename T>
+    class SingleValueGenerator : public IGenerator<T> {
+        T m_value;
+    public:
+        SingleValueGenerator( T const& value ) : m_value( value ) {}
+
+        auto get( size_t ) const -> T override {
+            return m_value;
+        }
+    };
+
+    template<typename T>
+    class FixedValuesGenerator : public IGenerator<T> {
+        std::vector<T> m_values;
+
+    public:
+        FixedValuesGenerator( std::initializer_list<T> values ) : m_values( values ) {}
+
+        auto get( size_t index ) const -> T override {
+            return m_values[index];
+        }
+    };
+
+    template<typename T>
+    class RangeGenerator : public IGenerator<T> {
+        T const m_first;
+        T const m_last;
+
+    public:
+        RangeGenerator( T const& first, T const& last ) : m_first( first ), m_last( last ) {
+            assert( m_last > m_first );
+        }
+
+        auto get( size_t index ) const -> T override {
+            // ToDo:: introduce a safe cast to catch potential overflows
+            return static_cast<T>(m_first+index);
+        }
+    };
+
+
+    template<typename T>
+    struct NullGenerator : IGenerator<T> {
+        auto get( size_t ) const -> T override {
+            CATCH_INTERNAL_ERROR("A Null Generator is always empty");
+        }
+    };
+
+    template<typename T>
+    class Generator {
+        std::unique_ptr<IGenerator<T>> m_generator;
+        size_t m_size;
+
+    public:
+        Generator( size_t size, std::unique_ptr<IGenerator<T>> generator )
+        :   m_generator( std::move( generator ) ),
+            m_size( size )
+        {}
+
+        auto size() const -> size_t { return m_size; }
+        auto operator[]( size_t index ) const -> T {
+            assert( index < m_size );
+            return m_generator->get( index );
+        }
+    };
+
+    std::vector<size_t> randomiseIndices( size_t selectionSize, size_t sourceSize );
+
+    template<typename T>
+    class GeneratorRandomiser : public IGenerator<T> {
+        Generator<T> m_baseGenerator;
+
+        std::vector<size_t> m_indices;
+    public:
+        GeneratorRandomiser( Generator<T>&& baseGenerator, size_t numberOfItems )
+        :   m_baseGenerator( std::move( baseGenerator ) ),
+            m_indices( randomiseIndices( numberOfItems, m_baseGenerator.size() ) )
+        {}
+
+        auto get( size_t index ) const -> T override {
+            return m_baseGenerator[m_indices[index]];
+        }
+    };
+
+    template<typename T>
+    struct RequiresASpecialisationFor;
+
+    template<typename T>
+    auto all() -> Generator<T> { return RequiresASpecialisationFor<T>(); }
+
+    template<>
+    auto all<int>() -> Generator<int>;
+
+
+    template<typename T>
+    auto range( T const& first, T const& last ) -> Generator<T> {
+        return Generator<T>( (last-first), pf::make_unique<RangeGenerator<T>>( first, last ) );
+    }
+
+    template<typename T>
+    auto random( T const& first, T const& last ) -> Generator<T> {
+        auto gen = range( first, last );
+        auto size = gen.size();
+
+        return Generator<T>( size, pf::make_unique<GeneratorRandomiser<T>>( std::move( gen ), size ) );
+    }
+    template<typename T>
+    auto random( size_t size ) -> Generator<T> {
+        return Generator<T>( size, pf::make_unique<GeneratorRandomiser<T>>( all<T>(), size ) );
+    }
+
+    template<typename T>
+    auto values( std::initializer_list<T> values ) -> Generator<T> {
+        return Generator<T>( values.size(), pf::make_unique<FixedValuesGenerator<T>>( values ) );
+    }
+    template<typename T>
+    auto value( T const& val ) -> Generator<T> {
+        return Generator<T>( 1, pf::make_unique<SingleValueGenerator<T>>( val ) );
+    }
+
+    template<typename T>
+    auto as() -> Generator<T> {
+        return Generator<T>( 0, pf::make_unique<NullGenerator<T>>() );
+    }
+
+    template<typename... Ts>
+    auto table( std::initializer_list<std::tuple<Ts...>>&& tuples ) -> Generator<std::tuple<Ts...>> {
+        return values<std::tuple<Ts...>>( std::forward<std::initializer_list<std::tuple<Ts...>>>( tuples ) );
+    }
+
+
+    template<typename T>
+    struct Generators : GeneratorBase {
+        std::vector<Generator<T>> m_generators;
+
+        using type = T;
+
+        Generators() : GeneratorBase( 0 ) {}
+
+        void populate( T&& val ) {
+            m_size += 1;
+            m_generators.emplace_back( value( std::move( val ) ) );
+        }
+        template<typename U>
+        void populate( U&& val ) {
+            populate( T( std::move( val ) ) );
+        }
+        void populate( Generator<T>&& generator ) {
+            m_size += generator.size();
+            m_generators.emplace_back( std::move( generator ) );
+        }
+
+        template<typename U, typename... Gs>
+        void populate( U&& valueOrGenerator, Gs... moreGenerators ) {
+            populate( std::forward<U>( valueOrGenerator ) );
+            populate( std::forward<Gs>( moreGenerators )... );
+        }
+
+        auto operator[]( size_t index ) const -> T {
+            size_t sizes = 0;
+            for( auto const& gen : m_generators ) {
+                auto localIndex = index-sizes;
+                sizes += gen.size();
+                if( index < sizes )
+                    return gen[localIndex];
+            }
+            CATCH_INTERNAL_ERROR("Index '" << index << "' is out of range (" << sizes << ')');
+        }
+    };
+
+    template<typename T, typename... Gs>
+    auto makeGenerators( Generator<T>&& generator, Gs... moreGenerators ) -> Generators<T> {
+        Generators<T> generators;
+        generators.m_generators.reserve( 1+sizeof...(Gs) );
+        generators.populate( std::move( generator ), std::forward<Gs>( moreGenerators )... );
+        return generators;
+    }
+    template<typename T>
+    auto makeGenerators( Generator<T>&& generator ) -> Generators<T> {
+        Generators<T> generators;
+        generators.populate( std::move( generator ) );
+        return generators;
+    }
+    template<typename T, typename... Gs>
+    auto makeGenerators( T&& val, Gs... moreGenerators ) -> Generators<T> {
+        return makeGenerators( value( std::forward<T>( val ) ), std::forward<Gs>( moreGenerators )... );
+    }
+    template<typename T, typename U, typename... Gs>
+    auto makeGenerators( U&& val, Gs... moreGenerators ) -> Generators<T> {
+        return makeGenerators( value( T( std::forward<U>( val ) ) ), std::forward<Gs>( moreGenerators )... );
+    }
+
+
+    auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker&;
+
+    template<typename L>
+    // Note: The type after -> is weird, because VS2015 cannot parse
+    //       the expression used in the typedef inside, when it is in
+    //       return type. Yeah, ¯\_(ツ)_/¯
+    auto generate( SourceLineInfo const& lineInfo, L const& generatorExpression ) -> decltype(std::declval<decltype(generatorExpression())>()[0]) {
+        using UnderlyingType = typename decltype(generatorExpression())::type;
+
+        IGeneratorTracker& tracker = acquireGeneratorTracker( lineInfo );
+        if( !tracker.hasGenerator() )
+            tracker.setGenerator( pf::make_unique<Generators<UnderlyingType>>( generatorExpression() ) );
+
+        auto const& generator = static_cast<Generators<UnderlyingType> const&>( *tracker.getGenerator() );
+        return generator[tracker.getIndex()];
+    }
+
+} // namespace Generators
+} // namespace Catch
+
+#define GENERATE( ... ) \
+    Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, []{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } )
+
+
+#endif // TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED
diff --git a/packages/Catch2/include/internal/catch_interfaces_capture.h b/packages/Catch2/include/internal/catch_interfaces_capture.h
index 4d091f892..950d498dc 100644
--- a/packages/Catch2/include/internal/catch_interfaces_capture.h
+++ b/packages/Catch2/include/internal/catch_interfaces_capture.h
@@ -24,8 +24,10 @@ namespace Catch {
     struct BenchmarkInfo;
     struct BenchmarkStats;
     struct AssertionReaction;
+    struct SourceLineInfo;
 
     struct ITransientExpression;
+    struct IGeneratorTracker;
 
     struct IResultCapture {
 
@@ -36,6 +38,8 @@ namespace Catch {
         virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;
         virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;
 
+        virtual auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& = 0;
+
         virtual void benchmarkStarting( BenchmarkInfo const& info ) = 0;
         virtual void benchmarkEnded( BenchmarkStats const& stats ) = 0;
 
diff --git a/packages/Catch2/include/internal/catch_interfaces_generatortracker.h b/packages/Catch2/include/internal/catch_interfaces_generatortracker.h
new file mode 100644
index 000000000..2cf6269e4
--- /dev/null
+++ b/packages/Catch2/include/internal/catch_interfaces_generatortracker.h
@@ -0,0 +1,39 @@
+/*
+ *  Created by Phil Nash on 26/6/2018.
+ *
+ *  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 TWOBLUECUBES_CATCH_INTERFACES_GENERATORTRACKER_INCLUDED
+#define TWOBLUECUBES_CATCH_INTERFACES_GENERATORTRACKER_INCLUDED
+
+#include <memory>
+
+namespace Catch {
+
+    namespace Generators {
+        class GeneratorBase {
+        protected:
+            size_t m_size = 0;
+
+        public:
+            GeneratorBase( size_t size ) : m_size( size ) {}
+            virtual ~GeneratorBase();
+            auto size() const -> size_t { return m_size; }
+        };
+        using GeneratorBasePtr = std::unique_ptr<GeneratorBase>;
+
+    } // namespace Generators
+
+    struct IGeneratorTracker {
+        virtual ~IGeneratorTracker();
+        virtual auto hasGenerator() const -> bool = 0;
+        virtual auto getGenerator() const -> Generators::GeneratorBasePtr const& = 0;
+        virtual void setGenerator( Generators::GeneratorBasePtr&& generator ) = 0;
+        virtual auto getIndex() const -> std::size_t = 0;
+    };
+
+} // namespace Catch
+
+#endif //TWOBLUECUBES_CATCH_INTERFACES_GENERATORTRACKER_INCLUDED
diff --git a/packages/Catch2/include/internal/catch_interfaces_registry_hub.h b/packages/Catch2/include/internal/catch_interfaces_registry_hub.h
index 1afbbec78..8e1da61e0 100644
--- a/packages/Catch2/include/internal/catch_interfaces_registry_hub.h
+++ b/packages/Catch2/include/internal/catch_interfaces_registry_hub.h
@@ -33,7 +33,7 @@ namespace Catch {
         virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
         virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0;
 
-        virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0;
+        virtual IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const = 0;
 
 
         virtual StartupExceptionRegistry const& getStartupExceptionRegistry() const = 0;
@@ -49,7 +49,7 @@ namespace Catch {
         virtual void registerStartupException() noexcept = 0;
     };
 
-    IRegistryHub& getRegistryHub();
+    IRegistryHub const& getRegistryHub();
     IMutableRegistryHub& getMutableRegistryHub();
     void cleanUp();
     std::string translateActiveException();
diff --git a/packages/Catch2/include/internal/catch_interfaces_reporter.h b/packages/Catch2/include/internal/catch_interfaces_reporter.h
index 76f5fd5ae..9d99c9814 100644
--- a/packages/Catch2/include/internal/catch_interfaces_reporter.h
+++ b/packages/Catch2/include/internal/catch_interfaces_reporter.h
@@ -42,6 +42,7 @@ namespace Catch {
 
     struct ReporterPreferences {
         bool shouldRedirectStdOut = false;
+        bool shouldReportAllAssertions = false;
     };
 
     template<typename T>
diff --git a/packages/Catch2/include/internal/catch_leak_detector.cpp b/packages/Catch2/include/internal/catch_leak_detector.cpp
index 36aba6abc..dd160d9c4 100644
--- a/packages/Catch2/include/internal/catch_leak_detector.cpp
+++ b/packages/Catch2/include/internal/catch_leak_detector.cpp
@@ -13,16 +13,16 @@
 
 namespace Catch {
 
-	LeakDetector::LeakDetector() {
-		int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
-		flag |= _CRTDBG_LEAK_CHECK_DF;
-		flag |= _CRTDBG_ALLOC_MEM_DF;
-		_CrtSetDbgFlag(flag);
-		_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
-		_CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
-		// Change this to leaking allocation's number to break there
-		_CrtSetBreakAlloc(-1);
-	}
+    LeakDetector::LeakDetector() {
+        int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
+        flag |= _CRTDBG_LEAK_CHECK_DF;
+        flag |= _CRTDBG_ALLOC_MEM_DF;
+        _CrtSetDbgFlag(flag);
+        _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
+        _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
+        // Change this to leaking allocation's number to break there
+        _CrtSetBreakAlloc(-1);
+    }
 }
 
 #else
diff --git a/packages/Catch2/include/internal/catch_matchers.h b/packages/Catch2/include/internal/catch_matchers.h
index f2e3aee9f..29692fc05 100644
--- a/packages/Catch2/include/internal/catch_matchers.h
+++ b/packages/Catch2/include/internal/catch_matchers.h
@@ -34,6 +34,11 @@ namespace Matchers {
             mutable std::string m_cachedToString;
         };
 
+#ifdef __clang__
+#    pragma clang diagnostic push
+#    pragma clang diagnostic ignored "-Wnon-virtual-dtor"
+#endif
+
         template<typename ObjectT>
         struct MatcherMethod {
             virtual bool match( ObjectT const& arg ) const = 0;
@@ -43,6 +48,10 @@ namespace Matchers {
             virtual bool match( PtrT* arg ) const = 0;
         };
 
+#ifdef __clang__
+#    pragma clang diagnostic pop
+#endif
+
         template<typename T>
         struct MatcherBase : MatcherUntypedBase, MatcherMethod<T> {
 
diff --git a/packages/Catch2/include/internal/catch_matchers_floating.cpp b/packages/Catch2/include/internal/catch_matchers_floating.cpp
index 72728a83d..312069867 100644
--- a/packages/Catch2/include/internal/catch_matchers_floating.cpp
+++ b/packages/Catch2/include/internal/catch_matchers_floating.cpp
@@ -6,13 +6,13 @@
  */
 
 #include "catch_matchers_floating.h"
+#include "catch_enforce.h"
 #include "catch_to_string.hpp"
 #include "catch_tostring.h"
 
 #include <cstdlib>
 #include <cstdint>
 #include <cstring>
-#include <stdexcept>
 
 namespace Catch {
 namespace Matchers {
@@ -81,9 +81,8 @@ namespace Matchers {
 namespace Floating {
     WithinAbsMatcher::WithinAbsMatcher(double target, double margin)
         :m_target{ target }, m_margin{ margin } {
-        if (m_margin < 0) {
-            throw std::domain_error("Allowed margin difference has to be >= 0");
-        }
+        CATCH_ENFORCE(margin >= 0, "Invalid margin: " << margin << '.'
+            << " Margin has to be non-negative.");
     }
 
     // Performs equivalent check of std::fabs(lhs - rhs) <= margin
@@ -99,11 +98,16 @@ namespace Floating {
 
     WithinUlpsMatcher::WithinUlpsMatcher(double target, int ulps, FloatingPointKind baseType)
         :m_target{ target }, m_ulps{ ulps }, m_type{ baseType } {
-        if (m_ulps < 0) {
-            throw std::domain_error("Allowed ulp difference has to be >= 0");
-        }
+        CATCH_ENFORCE(ulps >= 0, "Invalid ULP setting: " << ulps << '.'
+            << " ULPs have to be non-negative.");
     }
 
+#if defined(__clang__)
+#pragma clang diagnostic push
+// Clang <3.5 reports on the default branch in the switch below
+#pragma clang diagnostic ignored "-Wunreachable-code"
+#endif
+
     bool WithinUlpsMatcher::match(double const& matchee) const {
         switch (m_type) {
         case FloatingPointKind::Float:
@@ -111,10 +115,14 @@ namespace Floating {
         case FloatingPointKind::Double:
             return almostEqualUlps<double>(matchee, m_target, m_ulps);
         default:
-            throw std::domain_error("Unknown FloatingPointKind value");
+            CATCH_INTERNAL_ERROR( "Unknown FloatingPointKind value" );
         }
     }
 
+#if defined(__clang__)
+#pragma clang diagnostic pop
+#endif
+
     std::string WithinUlpsMatcher::describe() const {
         return "is within " + Catch::to_string(m_ulps) + " ULPs of " + ::Catch::Detail::stringify(m_target) + ((m_type == FloatingPointKind::Float)? "f" : "");
     }
diff --git a/packages/Catch2/include/internal/catch_matchers_vector.h b/packages/Catch2/include/internal/catch_matchers_vector.h
index 833d7dc2c..1e29cc940 100644
--- a/packages/Catch2/include/internal/catch_matchers_vector.h
+++ b/packages/Catch2/include/internal/catch_matchers_vector.h
@@ -124,7 +124,7 @@ namespace Matchers {
                 auto lfirst = m_target.begin(), llast = m_target.end();
                 auto rfirst = vec.begin(), rlast = vec.end();
                 // Cut common prefix to optimize checking of permuted parts
-                while (lfirst != llast && *lfirst != *rfirst) {
+                while (lfirst != llast && *lfirst == *rfirst) {
                     ++lfirst; ++rfirst;
                 }
                 if (lfirst == llast) {
diff --git a/packages/Catch2/include/internal/catch_message.cpp b/packages/Catch2/include/internal/catch_message.cpp
index 8684970a9..df905bf6b 100644
--- a/packages/Catch2/include/internal/catch_message.cpp
+++ b/packages/Catch2/include/internal/catch_message.cpp
@@ -10,9 +10,11 @@
 #include "catch_interfaces_capture.h"
 #include "catch_uncaught_exceptions.h"
 
+#include <cassert>
+
 namespace Catch {
 
-    MessageInfo::MessageInfo(   std::string const& _macroName,
+    MessageInfo::MessageInfo(   StringRef const& _macroName,
                                 SourceLineInfo const& _lineInfo,
                                 ResultWas::OfType _type )
     :   macroName( _macroName ),
@@ -35,7 +37,7 @@ namespace Catch {
 
     ////////////////////////////////////////////////////////////////////////////
 
-    Catch::MessageBuilder::MessageBuilder( std::string const& macroName,
+    Catch::MessageBuilder::MessageBuilder( StringRef const& macroName,
                                            SourceLineInfo const& lineInfo,
                                            ResultWas::OfType type )
         :m_info(macroName, lineInfo, type) {}
@@ -55,4 +57,36 @@ namespace Catch {
             getResultCapture().popScopedMessage(m_info);
         }
     }
+
+
+    Capturer::Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names ) {
+        auto start = std::string::npos;
+        for( size_t pos = 0; pos <= names.size(); ++pos ) {
+            char c = names[pos];
+            if( pos == names.size() || c == ' ' || c == '\t' || c == ',' || c == ']' ) {
+                if( start != std::string::npos ) {
+                    m_messages.push_back( MessageInfo( macroName, lineInfo, resultType ) );
+                    m_messages.back().message = names.substr( start, pos-start) + " := ";
+                    start = std::string::npos;
+                }
+            }
+            else if( c != '[' && c != ']' && start == std::string::npos )
+                start = pos;
+        }
+    }
+    Capturer::~Capturer() {
+        if ( !uncaught_exceptions() ){
+            assert( m_captured == m_messages.size() );
+            for( size_t i = 0; i < m_captured; ++i  )
+                m_resultCapture.popScopedMessage( m_messages[i] );
+        }
+    }
+
+    void Capturer::captureValue( size_t index, StringRef value ) {
+        assert( index < m_messages.size() );
+        m_messages[index].message += value;
+        m_resultCapture.pushScopedMessage( m_messages[index] );
+        m_captured++;
+    }
+
 } // end namespace Catch
diff --git a/packages/Catch2/include/internal/catch_message.h b/packages/Catch2/include/internal/catch_message.h
index 0a512ed57..73f9efd16 100644
--- a/packages/Catch2/include/internal/catch_message.h
+++ b/packages/Catch2/include/internal/catch_message.h
@@ -8,19 +8,23 @@
 #ifndef TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED
 #define TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED
 
-#include <string>
 #include "catch_result_type.h"
 #include "catch_common.h"
 #include "catch_stream.h"
+#include "catch_interfaces_capture.h"
+#include "catch_tostring.h"
+
+#include <string>
+#include <vector>
 
 namespace Catch {
 
     struct MessageInfo {
-        MessageInfo(    std::string const& _macroName,
+        MessageInfo(    StringRef const& _macroName,
                         SourceLineInfo const& _lineInfo,
                         ResultWas::OfType _type );
 
-        std::string macroName;
+        StringRef macroName;
         std::string message;
         SourceLineInfo lineInfo;
         ResultWas::OfType type;
@@ -44,7 +48,7 @@ namespace Catch {
     };
 
     struct MessageBuilder : MessageStream {
-        MessageBuilder( std::string const& macroName,
+        MessageBuilder( StringRef const& macroName,
                         SourceLineInfo const& lineInfo,
                         ResultWas::OfType type );
 
@@ -65,6 +69,28 @@ namespace Catch {
         MessageInfo m_info;
     };
 
+    class Capturer {
+        std::vector<MessageInfo> m_messages;
+        IResultCapture& m_resultCapture = getResultCapture();
+        size_t m_captured = 0;
+    public:
+        Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names );
+        ~Capturer();
+
+        void captureValue( size_t index, StringRef value );
+
+        template<typename T>
+        void captureValues( size_t index, T&& value ) {
+            captureValue( index, Catch::Detail::stringify( value ) );
+        }
+
+        template<typename T, typename... Ts>
+        void captureValues( size_t index, T&& value, Ts&&... values ) {
+            captureValues( index, value );
+            captureValues( index+1, values... );
+        }
+    };
+
 } // end namespace Catch
 
 #endif // TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED
diff --git a/packages/Catch2/include/internal/catch_output_redirect.cpp b/packages/Catch2/include/internal/catch_output_redirect.cpp
index c43dca048..86b0f6a0e 100644
--- a/packages/Catch2/include/internal/catch_output_redirect.cpp
+++ b/packages/Catch2/include/internal/catch_output_redirect.cpp
@@ -6,8 +6,7 @@
  */
 
 #include "catch_output_redirect.h"
-
-
+#include "catch_enforce.h"
 
 #include <cstdio>
 #include <cstring>
@@ -15,15 +14,18 @@
 #include <sstream>
 #include <stdexcept>
 
-#if defined(_MSC_VER)
-#include <io.h>      //_dup and _dup2
-#define dup _dup
-#define dup2 _dup2
-#define fileno _fileno
-#else
-#include <unistd.h>  // dup and dup2
+#if defined(CATCH_CONFIG_NEW_CAPTURE)
+    #if defined(_MSC_VER)
+    #include <io.h>      //_dup and _dup2
+    #define dup _dup
+    #define dup2 _dup2
+    #define fileno _fileno
+    #else
+    #include <unistd.h>  // dup and dup2
+    #endif
 #endif
 
+
 namespace Catch {
 
     RedirectedStream::RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream )
@@ -48,25 +50,26 @@ namespace Catch {
     auto RedirectedStdErr::str() const -> std::string { return m_rss.str(); }
 
 
+#if defined(CATCH_CONFIG_NEW_CAPTURE)
 
 #if defined(_MSC_VER)
     TempFile::TempFile() {
         if (tmpnam_s(m_buffer)) {
-            throw std::runtime_error("Could not get a temp filename");
+            CATCH_RUNTIME_ERROR("Could not get a temp filename");
         }
         if (fopen_s(&m_file, m_buffer, "w")) {
             char buffer[100];
             if (strerror_s(buffer, errno)) {
-                throw std::runtime_error("Could not translate errno to string");
+                CATCH_RUNTIME_ERROR("Could not translate errno to a string");
             }
-            throw std::runtime_error("Could not open the temp file: " + std::string(m_buffer) + buffer);
+            CATCH_RUNTIME_ERROR("Coul dnot open the temp file: '" << m_buffer << "' because: " << buffer);
         }
     }
 #else
     TempFile::TempFile() {
         m_file = std::tmpfile();
         if (!m_file) {
-            throw std::runtime_error("Could not create a temp file.");
+            CATCH_RUNTIME_ERROR("Could not create a temp file.");
         }
     }
 
@@ -122,11 +125,14 @@ namespace Catch {
         m_stderrDest += m_stderrFile.getContents();
     }
 
+#endif // CATCH_CONFIG_NEW_CAPTURE
 
 } // namespace Catch
 
-#if defined(_MSC_VER)
-#undef dup
-#undef dup2
-#undef fileno
+#if defined(CATCH_CONFIG_NEW_CAPTURE)
+    #if defined(_MSC_VER)
+    #undef dup
+    #undef dup2
+    #undef fileno
+    #endif
 #endif
diff --git a/packages/Catch2/include/internal/catch_output_redirect.h b/packages/Catch2/include/internal/catch_output_redirect.h
index f052bd2b3..ac0404055 100644
--- a/packages/Catch2/include/internal/catch_output_redirect.h
+++ b/packages/Catch2/include/internal/catch_output_redirect.h
@@ -47,6 +47,8 @@ namespace Catch {
     };
 
 
+#if defined(CATCH_CONFIG_NEW_CAPTURE)
+
     // Windows's implementation of std::tmpfile is terrible (it tries
     // to create a file inside system folder, thus requiring elevated
     // privileges for the binary), so we have to use tmpnam(_s) and
@@ -92,6 +94,7 @@ namespace Catch {
         std::string& m_stderrDest;
     };
 
+#endif
 
 } // end namespace Catch
 
diff --git a/packages/Catch2/include/internal/catch_random_number_generator.cpp b/packages/Catch2/include/internal/catch_random_number_generator.cpp
index 412faebae..ec8a5eb96 100644
--- a/packages/Catch2/include/internal/catch_random_number_generator.cpp
+++ b/packages/Catch2/include/internal/catch_random_number_generator.cpp
@@ -9,23 +9,21 @@
 #include "catch_context.h"
 #include "catch_interfaces_config.h"
 
-#include <cstdlib>
-
 namespace Catch {
 
+    std::mt19937& rng() {
+        static std::mt19937 s_rng;
+        return s_rng;
+    }
+
     void seedRng( IConfig const& config ) {
-        if( config.rngSeed() != 0 )
+        if( config.rngSeed() != 0 ) {
             std::srand( config.rngSeed() );
+            rng().seed( config.rngSeed() );
+        }
     }
+
     unsigned int rngSeed() {
         return getCurrentContext().getConfig()->rngSeed();
     }
-
-    RandomNumberGenerator::result_type RandomNumberGenerator::operator()( result_type n ) const {
-        return std::rand() % n;
-    }
-    RandomNumberGenerator::result_type RandomNumberGenerator::operator()() const {
-        return std::rand() % (max)();
-    }
-
 }
diff --git a/packages/Catch2/include/internal/catch_random_number_generator.h b/packages/Catch2/include/internal/catch_random_number_generator.h
index d18cffd5e..817b7841a 100644
--- a/packages/Catch2/include/internal/catch_random_number_generator.h
+++ b/packages/Catch2/include/internal/catch_random_number_generator.h
@@ -8,31 +8,16 @@
 #define TWOBLUECUBES_CATCH_RANDOM_NUMBER_GENERATOR_H_INCLUDED
 
 #include <algorithm>
+#include <random>
 
 namespace Catch {
 
     struct IConfig;
 
+    std::mt19937& rng();
     void seedRng( IConfig const& config );
-
     unsigned int rngSeed();
 
-    struct RandomNumberGenerator {
-        using result_type = unsigned int;
-
-        static constexpr result_type (min)() { return 0; }
-        static constexpr result_type (max)() { return 1000000; }
-
-        result_type operator()( result_type n ) const;
-        result_type operator()() const;
-
-        template<typename V>
-        static void shuffle( V& vector ) {
-            RandomNumberGenerator rng;
-            std::shuffle( vector.begin(), vector.end(), rng );
-        }
-    };
-
 }
 
 #endif // TWOBLUECUBES_CATCH_RANDOM_NUMBER_GENERATOR_H_INCLUDED
diff --git a/packages/Catch2/include/internal/catch_registry_hub.cpp b/packages/Catch2/include/internal/catch_registry_hub.cpp
index d98708c58..a50623985 100644
--- a/packages/Catch2/include/internal/catch_registry_hub.cpp
+++ b/packages/Catch2/include/internal/catch_registry_hub.cpp
@@ -14,6 +14,7 @@
 #include "catch_exception_translator_registry.h"
 #include "catch_tag_alias_registry.h"
 #include "catch_startup_exception_registry.h"
+#include "catch_singletons.hpp"
 
 namespace Catch {
 
@@ -30,7 +31,7 @@ namespace Catch {
             ITestCaseRegistry const& getTestCaseRegistry() const override {
                 return m_testCaseRegistry;
             }
-            IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() override {
+            IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const override {
                 return m_exceptionTranslatorRegistry;
             }
             ITagAliasRegistry const& getTagAliasRegistry() const override {
@@ -67,27 +68,19 @@ namespace Catch {
             TagAliasRegistry m_tagAliasRegistry;
             StartupExceptionRegistry m_exceptionRegistry;
         };
-
-        // Single, global, instance
-        RegistryHub*& getTheRegistryHub() {
-            static RegistryHub* theRegistryHub = nullptr;
-            if( !theRegistryHub )
-                theRegistryHub = new RegistryHub();
-            return theRegistryHub;
-        }
     }
 
-    IRegistryHub& getRegistryHub() {
-        return *getTheRegistryHub();
+    using RegistryHubSingleton = Singleton<RegistryHub, IRegistryHub, IMutableRegistryHub>;
+
+    IRegistryHub const& getRegistryHub() {
+        return RegistryHubSingleton::get();
     }
     IMutableRegistryHub& getMutableRegistryHub() {
-        return *getTheRegistryHub();
+        return RegistryHubSingleton::getMutable();
     }
     void cleanUp() {
-        delete getTheRegistryHub();
-        getTheRegistryHub() = nullptr;
+        cleanupSingletons();
         cleanUpContext();
-        ReusableStringStream::cleanup();
     }
     std::string translateActiveException() {
         return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();
diff --git a/packages/Catch2/include/internal/catch_run_context.cpp b/packages/Catch2/include/internal/catch_run_context.cpp
index 97700bef9..ffdd2ebbf 100644
--- a/packages/Catch2/include/internal/catch_run_context.cpp
+++ b/packages/Catch2/include/internal/catch_run_context.cpp
@@ -1,4 +1,5 @@
 #include "catch_run_context.h"
+#include "catch_compiler_capabilities.h"
 #include "catch_context.h"
 #include "catch_enforce.h"
 #include "catch_random_number_generator.h"
@@ -11,13 +12,77 @@
 
 namespace Catch {
 
+    namespace Generators {
+        struct GeneratorTracker : TestCaseTracking::TrackerBase, IGeneratorTracker {
+            size_t m_index = static_cast<size_t>( -1 );
+            GeneratorBasePtr m_generator;
+
+            GeneratorTracker( TestCaseTracking::NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
+            :   TrackerBase( nameAndLocation, ctx, parent )
+            {}
+            ~GeneratorTracker();
+
+            static GeneratorTracker& acquire( TrackerContext& ctx, TestCaseTracking::NameAndLocation const& nameAndLocation ) {
+                std::shared_ptr<GeneratorTracker> tracker;
+
+                ITracker& currentTracker = ctx.currentTracker();
+                if( TestCaseTracking::ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
+                    assert( childTracker );
+                    assert( childTracker->isIndexTracker() );
+                    tracker = std::static_pointer_cast<GeneratorTracker>( childTracker );
+                }
+                else {
+                    tracker = std::make_shared<GeneratorTracker>( nameAndLocation, ctx, &currentTracker );
+                    currentTracker.addChild( tracker );
+                }
+
+                if( !ctx.completedCycle() && !tracker->isComplete() ) {
+                    if( tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun )
+                        tracker->moveNext();
+                    tracker->open();
+                }
+
+                return *tracker;
+            }
+
+            void moveNext() {
+                m_index++;
+                m_children.clear();
+            }
+
+            // TrackerBase interface
+            bool isIndexTracker() const override { return true; }
+            auto hasGenerator() const -> bool override {
+                return !!m_generator;
+            }
+            void close() override {
+                TrackerBase::close();
+                if( m_runState == CompletedSuccessfully && m_index < m_generator->size()-1 )
+                    m_runState = Executing;
+            }
+
+            // IGeneratorTracker interface
+            auto getGenerator() const -> GeneratorBasePtr const& override {
+                return m_generator;
+            }
+            void setGenerator( GeneratorBasePtr&& generator ) override {
+                m_generator = std::move( generator );
+            }
+            auto getIndex() const -> size_t override {
+                return m_index;
+            }
+        };
+        GeneratorTracker::~GeneratorTracker() {}
+    }
+
+
     RunContext::RunContext(IConfigPtr const& _config, IStreamingReporterPtr&& reporter)
     :   m_runInfo(_config->name()),
         m_context(getCurrentMutableContext()),
         m_config(_config),
         m_reporter(std::move(reporter)),
         m_lastAssertionInfo{ StringRef(), SourceLineInfo("",0), StringRef(), ResultDisposition::Normal },
-        m_includeSuccessfulResults( m_config->includeSuccessfulResults() )
+        m_includeSuccessfulResults( m_config->includeSuccessfulResults() || m_reporter->getPreferences().shouldReportAllAssertions )
     {
         m_context.setRunner(this);
         m_context.setConfig(m_config);
@@ -128,6 +193,13 @@ namespace Catch {
 
         return true;
     }
+    auto RunContext::acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
+        using namespace Generators;
+        GeneratorTracker& tracker = GeneratorTracker::acquire( m_trackerContext, TestCaseTracking::NameAndLocation( "generator", lineInfo ) );
+        assert( tracker.isOpen() );
+        m_lastAssertionInfo.lineInfo = lineInfo;
+        return tracker;
+    }
 
     bool RunContext::testForMissingAssertions(Counts& assertions) {
         if (assertions.total() != 0)
@@ -208,7 +280,7 @@ namespace Catch {
 
         // Recreate section for test case (as we will lose the one that was in scope)
         auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
-        SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description);
+        SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
 
         Counts assertions;
         assertions.failed = 1;
@@ -241,12 +313,12 @@ namespace Catch {
     }
 
     bool RunContext::aborting() const {
-        return m_totals.assertions.failed == static_cast<std::size_t>(m_config->abortAfter());
+        return m_totals.assertions.failed >= static_cast<std::size_t>(m_config->abortAfter());
     }
 
     void RunContext::runCurrentTest(std::string & redirectedCout, std::string & redirectedCerr) {
         auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
-        SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description);
+        SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
         m_reporter->sectionStarting(testCaseSection);
         Counts prevAssertions = m_totals.assertions;
         double duration = 0;
@@ -256,7 +328,7 @@ namespace Catch {
         seedRng(*m_config);
 
         Timer timer;
-        try {
+        CATCH_TRY {
             if (m_reporter->getPreferences().shouldRedirectStdOut) {
 #if !defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
                 RedirectedStdOut redirectedStdOut;
@@ -276,9 +348,9 @@ namespace Catch {
                 invokeActiveTestCase();
             }
             duration = timer.getElapsedSeconds();
-        } catch (TestFailureException&) {
+        } CATCH_CATCH_ANON (TestFailureException&) {
             // This just means the test was aborted due to failure
-        } catch (...) {
+        } CATCH_CATCH_ALL {
             // Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions
             // are reported without translation at the point of origin.
             if( m_shouldReportUnexpected ) {
diff --git a/packages/Catch2/include/internal/catch_run_context.h b/packages/Catch2/include/internal/catch_run_context.h
index 6b8941739..952ef1478 100644
--- a/packages/Catch2/include/internal/catch_run_context.h
+++ b/packages/Catch2/include/internal/catch_run_context.h
@@ -8,6 +8,7 @@
 #ifndef TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED
 #define TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED
 
+#include "catch_interfaces_generatortracker.h"
 #include "catch_interfaces_runner.h"
 #include "catch_interfaces_reporter.h"
 #include "catch_interfaces_exception.h"
@@ -79,6 +80,8 @@ namespace Catch {
         void sectionEnded( SectionEndInfo const& endInfo ) override;
         void sectionEndedEarly( SectionEndInfo const& endInfo ) override;
 
+        auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& override;
+
         void benchmarkStarting( BenchmarkInfo const& info ) override;
         void benchmarkEnded( BenchmarkStats const& stats ) override;
 
diff --git a/packages/Catch2/include/internal/catch_section.cpp b/packages/Catch2/include/internal/catch_section.cpp
index 72a57d517..0646d36fe 100644
--- a/packages/Catch2/include/internal/catch_section.cpp
+++ b/packages/Catch2/include/internal/catch_section.cpp
@@ -21,7 +21,7 @@ namespace Catch {
 
     Section::~Section() {
         if( m_sectionIncluded ) {
-            SectionEndInfo endInfo( m_info, m_assertions, m_timer.getElapsedSeconds() );
+            SectionEndInfo endInfo{ m_info, m_assertions, m_timer.getElapsedSeconds() };
             if( uncaught_exceptions() )
                 getResultCapture().sectionEndedEarly( endInfo );
             else
diff --git a/packages/Catch2/include/internal/catch_section.h b/packages/Catch2/include/internal/catch_section.h
index 1e5b1c3ce..00c254b67 100644
--- a/packages/Catch2/include/internal/catch_section.h
+++ b/packages/Catch2/include/internal/catch_section.h
@@ -8,6 +8,7 @@
 #ifndef TWOBLUECUBES_CATCH_SECTION_H_INCLUDED
 #define TWOBLUECUBES_CATCH_SECTION_H_INCLUDED
 
+#include "catch_compiler_capabilities.h"
 #include "catch_section_info.h"
 #include "catch_totals.h"
 #include "catch_timer.h"
@@ -35,7 +36,14 @@ namespace Catch {
 
 } // end namespace Catch
 
-    #define INTERNAL_CATCH_SECTION( ... ) \
-        if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) )
+#define INTERNAL_CATCH_SECTION( ... ) \
+    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
+
+#define INTERNAL_CATCH_DYNAMIC_SECTION( ... ) \
+    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
 
 #endif // TWOBLUECUBES_CATCH_SECTION_H_INCLUDED
diff --git a/packages/Catch2/include/internal/catch_section_info.cpp b/packages/Catch2/include/internal/catch_section_info.cpp
index e2846b8a0..89714e35e 100644
--- a/packages/Catch2/include/internal/catch_section_info.cpp
+++ b/packages/Catch2/include/internal/catch_section_info.cpp
@@ -11,15 +11,9 @@ namespace Catch {
 
     SectionInfo::SectionInfo
         (   SourceLineInfo const& _lineInfo,
-            std::string const& _name,
-            std::string const& _description )
+            std::string const& _name )
     :   name( _name ),
-        description( _description ),
         lineInfo( _lineInfo )
     {}
 
-    SectionEndInfo::SectionEndInfo( SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds )
-    : sectionInfo( _sectionInfo ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds )
-    {}
-
 } // end namespace Catch
diff --git a/packages/Catch2/include/internal/catch_section_info.h b/packages/Catch2/include/internal/catch_section_info.h
index 86681ba70..9cf792e8c 100644
--- a/packages/Catch2/include/internal/catch_section_info.h
+++ b/packages/Catch2/include/internal/catch_section_info.h
@@ -16,19 +16,22 @@
 namespace Catch {
 
     struct SectionInfo {
+        SectionInfo
+            (   SourceLineInfo const& _lineInfo,
+                std::string const& _name );
+
+        // Deprecated
         SectionInfo
             (   SourceLineInfo const& _lineInfo,
                 std::string const& _name,
-                std::string const& _description = std::string() );
+                std::string const& ) : SectionInfo( _lineInfo, _name ) {}
 
         std::string name;
-        std::string description;
+        std::string description; // !Deprecated: this will always be empty
         SourceLineInfo lineInfo;
     };
 
     struct SectionEndInfo {
-        SectionEndInfo( SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds );
-
         SectionInfo sectionInfo;
         Counts prevAssertions;
         double durationInSeconds;
diff --git a/packages/Catch2/include/internal/catch_session.cpp b/packages/Catch2/include/internal/catch_session.cpp
index 2c5fe08e4..5d028ed21 100644
--- a/packages/Catch2/include/internal/catch_session.cpp
+++ b/packages/Catch2/include/internal/catch_session.cpp
@@ -119,10 +119,12 @@ namespace Catch {
     Session::Session() {
         static bool alreadyInstantiated = false;
         if( alreadyInstantiated ) {
-            try         { CATCH_INTERNAL_ERROR( "Only one instance of Catch::Session can ever be used" ); }
-            catch(...)  { getMutableRegistryHub().registerStartupException(); }
+            CATCH_TRY { CATCH_INTERNAL_ERROR( "Only one instance of Catch::Session can ever be used" ); }
+            CATCH_CATCH_ALL { getMutableRegistryHub().registerStartupException(); }
         }
 
+        // There cannot be exceptions at startup in no-exception mode.
+#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
         const auto& exceptions = getRegistryHub().getStartupExceptionRegistry().getExceptions();
         if ( !exceptions.empty() ) {
             m_startupExceptions = true;
@@ -137,6 +139,7 @@ namespace Catch {
                 }
             }
         }
+#endif
 
         alreadyInstantiated = true;
         m_cli = makeCommandLineParser( m_configData );
@@ -251,11 +254,11 @@ namespace Catch {
         if( m_startupExceptions )
             return 1;
 
-        if( m_configData.showHelp || m_configData.libIdentify )
+        if (m_configData.showHelp || m_configData.libIdentify) {
             return 0;
+        }
 
-        try
-        {
+        CATCH_TRY {
             config(); // Force config to be constructed
 
             seedRng( *m_config );
@@ -273,10 +276,12 @@ namespace Catch {
             // of 256 tests has failed
             return (std::min) (MaxExitCode, (std::max) (totals.error, static_cast<int>(totals.assertions.failed)));
         }
+#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
         catch( std::exception& ex ) {
             Catch::cerr() << ex.what() << std::endl;
             return MaxExitCode;
         }
+#endif
     }
 
 } // end namespace Catch
diff --git a/packages/Catch2/include/internal/catch_singletons.cpp b/packages/Catch2/include/internal/catch_singletons.cpp
new file mode 100644
index 000000000..e5367cadc
--- /dev/null
+++ b/packages/Catch2/include/internal/catch_singletons.cpp
@@ -0,0 +1,36 @@
+/*
+ *  Created by Phil Nash on 15/6/2018.
+ *
+ *  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)
+ */
+
+#include "catch_singletons.hpp"
+
+#include <vector>
+
+namespace Catch {
+
+    namespace {
+        static auto getSingletons() -> std::vector<ISingleton*>*& {
+            static std::vector<ISingleton*>* g_singletons = nullptr;
+            if( !g_singletons )
+                g_singletons = new std::vector<ISingleton*>();
+            return g_singletons;
+        }
+    }
+
+    ISingleton::~ISingleton() {}
+
+    void addSingleton(ISingleton* singleton ) {
+        getSingletons()->push_back( singleton );
+    }
+    void cleanupSingletons() {
+        auto& singletons = getSingletons();
+        for( auto singleton : *singletons )
+            delete singleton;
+        delete singletons;
+        singletons = nullptr;
+    }
+
+} // namespace Catch
diff --git a/packages/Catch2/include/internal/catch_singletons.hpp b/packages/Catch2/include/internal/catch_singletons.hpp
new file mode 100644
index 000000000..fbc4b32c4
--- /dev/null
+++ b/packages/Catch2/include/internal/catch_singletons.hpp
@@ -0,0 +1,44 @@
+/*
+ *  Created by Phil Nash on 15/6/2018.
+ *
+ *  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 TWOBLUECUBES_CATCH_SINGLETONS_HPP_INCLUDED
+#define TWOBLUECUBES_CATCH_SINGLETONS_HPP_INCLUDED
+
+namespace Catch {
+
+    struct ISingleton {
+        virtual ~ISingleton();
+    };
+
+
+    void addSingleton( ISingleton* singleton );
+    void cleanupSingletons();
+
+
+    template<typename SingletonImplT, typename InterfaceT = SingletonImplT, typename MutableInterfaceT = InterfaceT>
+    class Singleton : SingletonImplT, public ISingleton {
+
+        static auto getInternal() -> Singleton* {
+            static Singleton* s_instance = nullptr;
+            if( !s_instance ) {
+                s_instance = new Singleton;
+                addSingleton( s_instance );
+            }
+            return s_instance;
+        }
+
+    public:
+        static auto get() -> InterfaceT const& {
+            return *getInternal();
+        }
+        static auto getMutable() -> MutableInterfaceT& {
+            return *getInternal();
+        }
+    };
+
+} // namespace Catch
+
+#endif // TWOBLUECUBES_CATCH_SINGLETONS_HPP_INCLUDED
diff --git a/packages/Catch2/include/internal/catch_startup_exception_registry.cpp b/packages/Catch2/include/internal/catch_startup_exception_registry.cpp
index d58d18a5b..3c5bd22f5 100644
--- a/packages/Catch2/include/internal/catch_startup_exception_registry.cpp
+++ b/packages/Catch2/include/internal/catch_startup_exception_registry.cpp
@@ -7,13 +7,13 @@
  */
 
 #include "catch_startup_exception_registry.h"
+#include "catch_compiler_capabilities.h"
 
 namespace Catch {
-    void StartupExceptionRegistry::add( std::exception_ptr const& exception ) noexcept {
-        try {
+void StartupExceptionRegistry::add( std::exception_ptr const& exception ) noexcept {
+        CATCH_TRY {
             m_exceptions.push_back(exception);
-        }
-        catch(...) {
+        } CATCH_CATCH_ALL {
             // If we run out of memory during start-up there's really not a lot more we can do about it
             std::terminate();
         }
diff --git a/packages/Catch2/include/internal/catch_stream.cpp b/packages/Catch2/include/internal/catch_stream.cpp
index 125fd471e..ba2d2be25 100644
--- a/packages/Catch2/include/internal/catch_stream.cpp
+++ b/packages/Catch2/include/internal/catch_stream.cpp
@@ -12,6 +12,7 @@
 #include "catch_stream.h"
 #include "catch_debug_console.h"
 #include "catch_stringref.h"
+#include "catch_singletons.hpp"
 
 #include <cstdio>
 #include <iostream>
@@ -20,11 +21,6 @@
 #include <vector>
 #include <memory>
 
-#if defined(__clang__)
-#    pragma clang diagnostic push
-#    pragma clang diagnostic ignored "-Wexit-time-destructors"
-#endif
-
 namespace Catch {
 
     Catch::IStream::~IStream() = default;
@@ -145,7 +141,6 @@ namespace Catch {
         std::vector<std::unique_ptr<std::ostringstream>> m_streams;
         std::vector<std::size_t> m_unused;
         std::ostringstream m_referenceStream; // Used for copy state/ flags from
-        static StringStreams* s_instance;
 
         auto add() -> std::size_t {
             if( m_unused.empty() ) {
@@ -163,34 +158,17 @@ namespace Catch {
             m_streams[index]->copyfmt( m_referenceStream ); // Restore initial flags and other state
             m_unused.push_back(index);
         }
-
-        // !TBD: put in TLS
-        static auto instance() -> StringStreams& {
-            if( !s_instance )
-                s_instance = new StringStreams();
-            return *s_instance;
-        }
-        static void cleanup() {
-            delete s_instance;
-            s_instance = nullptr;
-        }
     };
 
-    StringStreams* StringStreams::s_instance = nullptr;
-
-    void ReusableStringStream::cleanup() {
-        StringStreams::cleanup();
-    }
-
     ReusableStringStream::ReusableStringStream()
-    :   m_index( StringStreams::instance().add() ),
-        m_oss( StringStreams::instance().m_streams[m_index].get() )
+    :   m_index( Singleton<StringStreams>::getMutable().add() ),
+        m_oss( Singleton<StringStreams>::getMutable().m_streams[m_index].get() )
     {}
 
     ReusableStringStream::~ReusableStringStream() {
         static_cast<std::ostringstream*>( m_oss )->str("");
         m_oss->clear();
-        StringStreams::instance().release( m_index );
+        Singleton<StringStreams>::getMutable().release( m_index );
     }
 
     auto ReusableStringStream::str() const -> std::string {
@@ -207,7 +185,3 @@ namespace Catch {
     std::ostream& clog() { return std::clog; }
 #endif
 }
-
-#if defined(__clang__)
-#    pragma clang diagnostic pop
-#endif
diff --git a/packages/Catch2/include/internal/catch_stream.h b/packages/Catch2/include/internal/catch_stream.h
index c5e78b226..2b41adbd9 100644
--- a/packages/Catch2/include/internal/catch_stream.h
+++ b/packages/Catch2/include/internal/catch_stream.h
@@ -43,8 +43,6 @@ namespace Catch {
             return *this;
         }
         auto get() -> std::ostream& { return *m_oss; }
-
-        static void cleanup();
     };
 }
 
diff --git a/packages/Catch2/include/internal/catch_stringref.h b/packages/Catch2/include/internal/catch_stringref.h
index 757d70cc1..05206b0b1 100644
--- a/packages/Catch2/include/internal/catch_stringref.h
+++ b/packages/Catch2/include/internal/catch_stringref.h
@@ -127,4 +127,8 @@ namespace Catch {
 
 } // namespace Catch
 
+inline auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef {
+    return Catch::StringRef( rawChars, size );
+}
+
 #endif // CATCH_STRINGREF_H_INCLUDED
diff --git a/packages/Catch2/include/internal/catch_suppress_warnings.h b/packages/Catch2/include/internal/catch_suppress_warnings.h
index 4d0e9bd3f..25d90125b 100644
--- a/packages/Catch2/include/internal/catch_suppress_warnings.h
+++ b/packages/Catch2/include/internal/catch_suppress_warnings.h
@@ -10,13 +10,15 @@
 #       pragma warning(push)
 #       pragma warning(disable: 161 1682)
 #   else // __ICC
-#       pragma clang diagnostic ignored "-Wunused-variable"
 #       pragma clang diagnostic push
 #       pragma clang diagnostic ignored "-Wpadded"
 #       pragma clang diagnostic ignored "-Wswitch-enum"
 #       pragma clang diagnostic ignored "-Wcovered-switch-default"
 #    endif
 #elif defined __GNUC__
+     // GCC likes to warn on REQUIREs, and we cannot suppress them
+     // locally because g++'s support for _Pragma is lacking in older,
+     // still supported, versions
 #    pragma GCC diagnostic ignored "-Wparentheses"
 #    pragma GCC diagnostic push
 #    pragma GCC diagnostic ignored "-Wunused-variable"
diff --git a/packages/Catch2/include/internal/catch_tag_alias_autoregistrar.cpp b/packages/Catch2/include/internal/catch_tag_alias_autoregistrar.cpp
index 35ed059fd..6a292edf0 100644
--- a/packages/Catch2/include/internal/catch_tag_alias_autoregistrar.cpp
+++ b/packages/Catch2/include/internal/catch_tag_alias_autoregistrar.cpp
@@ -1,12 +1,13 @@
 #include "catch_tag_alias_autoregistrar.h"
+#include "catch_compiler_capabilities.h"
 #include "catch_interfaces_registry_hub.h"
 
 namespace Catch {
-    
+
     RegistrarForTagAliases::RegistrarForTagAliases(char const* alias, char const* tag, SourceLineInfo const& lineInfo) {
-        try {
+        CATCH_TRY {
             getMutableRegistryHub().registerTagAlias(alias, tag, lineInfo);
-        } catch (...) {
+        } CATCH_CATCH_ALL {
             // Do not throw when constructing global objects, instead register the exception to be processed later
             getMutableRegistryHub().registerStartupException();
         }
diff --git a/packages/Catch2/include/internal/catch_test_case_registry_impl.cpp b/packages/Catch2/include/internal/catch_test_case_registry_impl.cpp
index b30b112ae..a6b7f5703 100644
--- a/packages/Catch2/include/internal/catch_test_case_registry_impl.cpp
+++ b/packages/Catch2/include/internal/catch_test_case_registry_impl.cpp
@@ -28,7 +28,7 @@ namespace Catch {
                 break;
             case RunTests::InRandomOrder:
                 seedRng( config );
-                RandomNumberGenerator::shuffle( sorted );
+                std::shuffle( sorted.begin(), sorted.end(), rng() );
                 break;
             case RunTests::InDeclarationOrder:
                 // already in declaration order
diff --git a/packages/Catch2/include/internal/catch_test_case_tracker.cpp b/packages/Catch2/include/internal/catch_test_case_tracker.cpp
index 8502b405f..7839a71b4 100644
--- a/packages/Catch2/include/internal/catch_test_case_tracker.cpp
+++ b/packages/Catch2/include/internal/catch_test_case_tracker.cpp
@@ -69,14 +69,6 @@ namespace TestCaseTracking {
     }
 
 
-
-    TrackerBase::TrackerHasName::TrackerHasName( NameAndLocation const& nameAndLocation ) : m_nameAndLocation( nameAndLocation ) {}
-    bool TrackerBase::TrackerHasName::operator ()( ITrackerPtr const& tracker ) const {
-        return
-            tracker->nameAndLocation().name == m_nameAndLocation.name &&
-            tracker->nameAndLocation().location == m_nameAndLocation.location;
-    }
-
     TrackerBase::TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
     :   m_nameAndLocation( nameAndLocation ),
         m_ctx( ctx ),
@@ -105,7 +97,12 @@ namespace TestCaseTracking {
     }
 
     ITrackerPtr TrackerBase::findChild( NameAndLocation const& nameAndLocation ) {
-        auto it = std::find_if( m_children.begin(), m_children.end(), TrackerHasName( nameAndLocation ) );
+        auto it = std::find_if( m_children.begin(), m_children.end(),
+            [&nameAndLocation]( ITrackerPtr const& tracker ){
+                return
+                    tracker->nameAndLocation().location == nameAndLocation.location &&
+                    tracker->nameAndLocation().name == nameAndLocation.name;
+            } );
         return( it != m_children.end() )
             ? *it
             : nullptr;
diff --git a/packages/Catch2/include/internal/catch_test_case_tracker.h b/packages/Catch2/include/internal/catch_test_case_tracker.h
index a4b0440a3..72b506a9f 100644
--- a/packages/Catch2/include/internal/catch_test_case_tracker.h
+++ b/packages/Catch2/include/internal/catch_test_case_tracker.h
@@ -95,13 +95,6 @@ namespace TestCaseTracking {
             Failed
         };
 
-        class TrackerHasName {
-            NameAndLocation m_nameAndLocation;
-        public:
-            TrackerHasName( NameAndLocation const& nameAndLocation );
-            bool operator ()( ITrackerPtr const& tracker ) const;
-        };
-
         using Children = std::vector<ITrackerPtr>;
         NameAndLocation m_nameAndLocation;
         TrackerContext& m_ctx;
diff --git a/packages/Catch2/include/internal/catch_test_registry.cpp b/packages/Catch2/include/internal/catch_test_registry.cpp
index ac83f3332..248bee4ca 100644
--- a/packages/Catch2/include/internal/catch_test_registry.cpp
+++ b/packages/Catch2/include/internal/catch_test_registry.cpp
@@ -6,6 +6,7 @@
  */
 
 #include "catch_test_registry.h"
+#include "catch_compiler_capabilities.h"
 #include "catch_test_case_registry_impl.h"
 #include "catch_interfaces_registry_hub.h"
 
@@ -18,7 +19,7 @@ namespace Catch {
     NameAndTags::NameAndTags( StringRef const& name_ , StringRef const& tags_ ) noexcept : name( name_ ), tags( tags_ ) {}
 
     AutoReg::AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept {
-        try {
+        CATCH_TRY {
             getMutableRegistryHub()
                     .registerTest(
                         makeTestCase(
@@ -26,7 +27,7 @@ namespace Catch {
                             extractClassName( classOrMethod ),
                             nameAndTags,
                             lineInfo));
-        } catch (...) {
+        } CATCH_CATCH_ALL {
             // Do not throw when constructing global objects, instead register the exception to be processed later
             getMutableRegistryHub().registerStartupException();
         }
diff --git a/packages/Catch2/include/internal/catch_test_registry.h b/packages/Catch2/include/internal/catch_test_registry.h
index f7fe32589..713044834 100644
--- a/packages/Catch2/include/internal/catch_test_registry.h
+++ b/packages/Catch2/include/internal/catch_test_registry.h
@@ -69,7 +69,7 @@ struct AutoReg : NonCopyable {
     #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
         static void TestName(); \
         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
-        namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, "", Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
+        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 \
         static void TestName()
     #define INTERNAL_CATCH_TESTCASE( ... ) \
@@ -98,7 +98,7 @@ struct AutoReg : NonCopyable {
     ///////////////////////////////////////////////////////////////////////////////
     #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
-        Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, "", Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
+        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
 
 
diff --git a/packages/Catch2/include/internal/catch_tostring.cpp b/packages/Catch2/include/internal/catch_tostring.cpp
index ee6a815f9..4e0c027d3 100644
--- a/packages/Catch2/include/internal/catch_tostring.cpp
+++ b/packages/Catch2/include/internal/catch_tostring.cpp
@@ -116,14 +116,9 @@ std::string StringMaker<std::string>::convert(const std::string& str) {
     return s;
 }
 
-#ifdef CATCH_CONFIG_WCHAR
-std::string StringMaker<std::wstring>::convert(const std::wstring& wstr) {
-    std::string s;
-    s.reserve(wstr.size());
-    for (auto c : wstr) {
-        s += (c <= 0xff) ? static_cast<char>(c) : '?';
-    }
-    return ::Catch::Detail::stringify(s);
+#ifdef CATCH_CONFIG_CPP17_STRING_VIEW
+std::string StringMaker<std::string_view>::convert(std::string_view str) {
+    return ::Catch::Detail::stringify(std::string{ str });
 }
 #endif
 
@@ -141,7 +136,23 @@ std::string StringMaker<char*>::convert(char* str) {
         return{ "{null string}" };
     }
 }
+
 #ifdef CATCH_CONFIG_WCHAR
+std::string StringMaker<std::wstring>::convert(const std::wstring& wstr) {
+    std::string s;
+    s.reserve(wstr.size());
+    for (auto c : wstr) {
+        s += (c <= 0xff) ? static_cast<char>(c) : '?';
+    }
+    return ::Catch::Detail::stringify(s);
+}
+
+# ifdef CATCH_CONFIG_CPP17_STRING_VIEW
+std::string StringMaker<std::wstring_view>::convert(std::wstring_view str) {
+    return StringMaker<std::wstring>::convert(std::wstring(str));
+}
+# endif
+
 std::string StringMaker<wchar_t const*>::convert(wchar_t const * str) {
     if (str) {
         return ::Catch::Detail::stringify(std::wstring{ str });
@@ -231,8 +242,8 @@ std::string StringMaker<double>::convert(double value) {
 
 std::string ratio_string<std::atto>::symbol() { return "a"; }
 std::string ratio_string<std::femto>::symbol() { return "f"; }
-std::string  ratio_string<std::pico>::symbol() { return "p"; }
-std::string  ratio_string<std::nano>::symbol() { return "n"; }
+std::string ratio_string<std::pico>::symbol() { return "p"; }
+std::string ratio_string<std::nano>::symbol() { return "n"; }
 std::string ratio_string<std::micro>::symbol() { return "u"; }
 std::string ratio_string<std::milli>::symbol() { return "m"; }
 
diff --git a/packages/Catch2/include/internal/catch_tostring.h b/packages/Catch2/include/internal/catch_tostring.h
index 2aa06f442..137d97592 100644
--- a/packages/Catch2/include/internal/catch_tostring.h
+++ b/packages/Catch2/include/internal/catch_tostring.h
@@ -16,6 +16,10 @@
 #include "catch_compiler_capabilities.h"
 #include "catch_stream.h"
 
+#ifdef CATCH_CONFIG_CPP17_STRING_VIEW
+#include <string_view>
+#endif
+
 #ifdef __OBJC__
 #include "catch_objc_arc.hpp"
 #endif
@@ -152,10 +156,11 @@ namespace Catch {
     struct StringMaker<std::string> {
         static std::string convert(const std::string& str);
     };
-#ifdef CATCH_CONFIG_WCHAR
+
+#ifdef CATCH_CONFIG_CPP17_STRING_VIEW
     template<>
-    struct StringMaker<std::wstring> {
-        static std::string convert(const std::wstring& wstr);
+    struct StringMaker<std::string_view> {
+        static std::string convert(std::string_view str);
     };
 #endif
 
@@ -169,6 +174,18 @@ namespace Catch {
     };
 
 #ifdef CATCH_CONFIG_WCHAR
+    template<>
+    struct StringMaker<std::wstring> {
+        static std::string convert(const std::wstring& wstr);
+    };
+
+# ifdef CATCH_CONFIG_CPP17_STRING_VIEW
+    template<>
+    struct StringMaker<std::wstring_view> {
+        static std::string convert(std::wstring_view str);
+    };
+# endif
+
     template<>
     struct StringMaker<wchar_t const *> {
         static std::string convert(wchar_t const * str);
@@ -337,6 +354,7 @@ namespace Catch {
 #if defined(CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS)
 #  define CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
 #  define CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
+#  define CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
 #  define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
 #endif
 
@@ -401,6 +419,34 @@ namespace Catch {
 }
 #endif // CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
 
+#if defined(CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_VARIANT)
+#include <variant>
+namespace Catch {
+    template<>
+    struct StringMaker<std::monostate> {
+        static std::string convert(const std::monostate&) {
+            return "{ }";
+        }
+    };
+
+    template<typename... Elements>
+    struct StringMaker<std::variant<Elements...>> {
+        static std::string convert(const std::variant<Elements...>& variant) {
+            if (variant.valueless_by_exception()) {
+                return "{valueless variant}";
+            } else {
+                return std::visit(
+                    [](const auto& value) {
+                        return ::Catch::Detail::stringify(value);
+                    },
+                    variant
+                );
+            }
+        }
+    };
+}
+#endif // CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
+
 namespace Catch {
     struct not_this_one {}; // Tag type for detecting which begin/ end are being selected
 
diff --git a/packages/Catch2/include/internal/catch_version.cpp b/packages/Catch2/include/internal/catch_version.cpp
index 94e11e085..a57553c0d 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, 2, 3, "", 0 );
+        static Version version( 2, 4, 1, "", 0 );
         return version;
     }
 
diff --git a/packages/Catch2/include/reporters/catch_reporter_bases.hpp b/packages/Catch2/include/reporters/catch_reporter_bases.hpp
index f198d2142..ae1618fe4 100644
--- a/packages/Catch2/include/reporters/catch_reporter_bases.hpp
+++ b/packages/Catch2/include/reporters/catch_reporter_bases.hpp
@@ -8,6 +8,7 @@
 #ifndef TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED
 #define TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED
 
+#include "../internal/catch_enforce.h"
 #include "../internal/catch_interfaces_reporter.h"
 
 #include <algorithm>
@@ -33,7 +34,7 @@ namespace Catch {
         {
             m_reporterPrefs.shouldRedirectStdOut = false;
             if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )
-                throw std::domain_error( "Verbosity level not supported by this reporter" );
+                CATCH_ERROR( "Verbosity level not supported by this reporter" );
         }
 
         ReporterPreferences getPreferences() const override {
@@ -148,7 +149,7 @@ namespace Catch {
         {
             m_reporterPrefs.shouldRedirectStdOut = false;
             if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )
-                throw std::domain_error( "Verbosity level not supported by this reporter" );
+                CATCH_ERROR( "Verbosity level not supported by this reporter" );
         }
         ~CumulativeReporterBase() override = default;
 
diff --git a/packages/Catch2/include/reporters/catch_reporter_compact.cpp b/packages/Catch2/include/reporters/catch_reporter_compact.cpp
index caf4d3f9f..65f70266d 100644
--- a/packages/Catch2/include/reporters/catch_reporter_compact.cpp
+++ b/packages/Catch2/include/reporters/catch_reporter_compact.cpp
@@ -245,9 +245,7 @@ private:
         }
 
         ReporterPreferences CompactReporter::getPreferences() const {
-            ReporterPreferences prefs;
-            prefs.shouldRedirectStdOut = false;
-            return prefs;
+            return m_reporterPrefs;
         }
 
         void CompactReporter::noMatchingTestCases( std::string const& spec ) {
diff --git a/packages/Catch2/include/reporters/catch_reporter_junit.cpp b/packages/Catch2/include/reporters/catch_reporter_junit.cpp
index 55129b767..03dc35c1b 100644
--- a/packages/Catch2/include/reporters/catch_reporter_junit.cpp
+++ b/packages/Catch2/include/reporters/catch_reporter_junit.cpp
@@ -62,6 +62,7 @@ namespace Catch {
             xml( _config.stream() )
         {
             m_reporterPrefs.shouldRedirectStdOut = true;
+            m_reporterPrefs.shouldReportAllAssertions = true;
         }
 
     JunitReporter::~JunitReporter() {}
diff --git a/packages/Catch2/include/reporters/catch_reporter_listening.cpp b/packages/Catch2/include/reporters/catch_reporter_listening.cpp
index cd6251541..9ddae2f2e 100644
--- a/packages/Catch2/include/reporters/catch_reporter_listening.cpp
+++ b/packages/Catch2/include/reporters/catch_reporter_listening.cpp
@@ -11,6 +11,11 @@
 
 namespace Catch {
 
+    ListeningReporter::ListeningReporter() {
+        // We will assume that listeners will always want all assertions
+        m_preferences.shouldReportAllAssertions = true;
+    }
+
     void ListeningReporter::addListener( IStreamingReporterPtr&& listener ) {
         m_listeners.push_back( std::move( listener ) );
     }
@@ -18,10 +23,11 @@ namespace Catch {
     void ListeningReporter::addReporter(IStreamingReporterPtr&& reporter) {
         assert(!m_reporter && "Listening reporter can wrap only 1 real reporter");
         m_reporter = std::move( reporter );
+        m_preferences.shouldRedirectStdOut = m_reporter->getPreferences().shouldRedirectStdOut;
     }
 
     ReporterPreferences ListeningReporter::getPreferences() const {
-        return m_reporter->getPreferences();
+        return m_preferences;
     }
 
     std::set<Verbosity> ListeningReporter::getSupportedVerbosities() {
diff --git a/packages/Catch2/include/reporters/catch_reporter_listening.h b/packages/Catch2/include/reporters/catch_reporter_listening.h
index bf97edef3..dddd7a518 100644
--- a/packages/Catch2/include/reporters/catch_reporter_listening.h
+++ b/packages/Catch2/include/reporters/catch_reporter_listening.h
@@ -15,8 +15,11 @@ namespace Catch {
         using Reporters = std::vector<IStreamingReporterPtr>;
         Reporters m_listeners;
         IStreamingReporterPtr m_reporter = nullptr;
+        ReporterPreferences m_preferences;
 
     public:
+        ListeningReporter();
+
         void addListener( IStreamingReporterPtr&& listener );
         void addReporter( IStreamingReporterPtr&& reporter );
 
diff --git a/packages/Catch2/include/reporters/catch_reporter_tap.hpp b/packages/Catch2/include/reporters/catch_reporter_tap.hpp
index 19e54ed19..ccc4051be 100644
--- a/packages/Catch2/include/reporters/catch_reporter_tap.hpp
+++ b/packages/Catch2/include/reporters/catch_reporter_tap.hpp
@@ -30,9 +30,7 @@ namespace Catch {
         }
 
         ReporterPreferences getPreferences() const override {
-            ReporterPreferences prefs;
-            prefs.shouldRedirectStdOut = false;
-            return prefs;
+            return m_reporterPrefs;
         }
 
         void noMatchingTestCases( std::string const& spec ) override {
diff --git a/packages/Catch2/include/reporters/catch_reporter_teamcity.hpp b/packages/Catch2/include/reporters/catch_reporter_teamcity.hpp
index dbd0db532..eca2885cd 100644
--- a/packages/Catch2/include/reporters/catch_reporter_teamcity.hpp
+++ b/packages/Catch2/include/reporters/catch_reporter_teamcity.hpp
@@ -97,12 +97,12 @@ namespace Catch {
                     case ResultWas::Ok:
                     case ResultWas::Info:
                     case ResultWas::Warning:
-                        throw std::domain_error( "Internal error in TeamCity reporter" );
+                        CATCH_ERROR( "Internal error in TeamCity reporter" );
                     // These cases are here to prevent compiler warnings
                     case ResultWas::Unknown:
                     case ResultWas::FailureBit:
                     case ResultWas::Exception:
-                        throw std::domain_error( "Not implemented" );
+                        CATCH_ERROR( "Not implemented" );
                 }
                 if( assertionStats.infoMessages.size() == 1 )
                     msg << " with message:";
diff --git a/packages/Catch2/include/reporters/catch_reporter_xml.cpp b/packages/Catch2/include/reporters/catch_reporter_xml.cpp
index b721d449e..c32005370 100644
--- a/packages/Catch2/include/reporters/catch_reporter_xml.cpp
+++ b/packages/Catch2/include/reporters/catch_reporter_xml.cpp
@@ -24,6 +24,7 @@ namespace Catch {
         m_xml(_config.stream())
     {
         m_reporterPrefs.shouldRedirectStdOut = true;
+        m_reporterPrefs.shouldReportAllAssertions = true;
     }
 
     XmlReporter::~XmlReporter() = default;
@@ -80,8 +81,7 @@ namespace Catch {
         StreamingReporterBase::sectionStarting( sectionInfo );
         if( m_sectionDepth++ > 0 ) {
             m_xml.startElement( "Section" )
-                .writeAttribute( "name", trim( sectionInfo.name ) )
-                .writeAttribute( "description", sectionInfo.description );
+                .writeAttribute( "name", trim( sectionInfo.name ) );
             writeSourceInfo( sectionInfo.lineInfo );
             m_xml.ensureTagClosed();
         }
diff --git a/packages/Catch2/misc/SelfTest.vcxproj.user b/packages/Catch2/misc/SelfTest.vcxproj.user
new file mode 100644
index 000000000..ffffc5751
--- /dev/null
+++ b/packages/Catch2/misc/SelfTest.vcxproj.user
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <UseFullPaths>false</UseFullPaths>
+    </ClCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <UseFullPaths>false</UseFullPaths>
+    </ClCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <UseFullPaths>false</UseFullPaths>
+    </ClCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <UseFullPaths>false</UseFullPaths>
+    </ClCompile>
+  </ItemDefinitionGroup>
+</Project>
diff --git a/packages/Catch2/misc/appveyorBuildConfigurationScript.bat b/packages/Catch2/misc/appveyorBuildConfigurationScript.bat
index 1e91a588f..f07bb707c 100644
--- a/packages/Catch2/misc/appveyorBuildConfigurationScript.bat
+++ b/packages/Catch2/misc/appveyorBuildConfigurationScript.bat
@@ -1,3 +1,4 @@
+SETLOCAL EnableDelayedExpansion
 
 @REM  # Possibilities:
 @REM  # Debug build + coverage
@@ -7,21 +8,15 @@
 if "%CONFIGURATION%"=="Debug" (
   if "%coverage%"=="1" (
     @REM # coverage needs to build the special helper as well as the main
-    cmake -Hmisc -Bbuild-misc -A%PLATFORM%
-    cmake --build build-misc
-    cmake -H. -BBuild -A%PLATFORM% -DUSE_WMAIN=%wmain% -DMEMORYCHECK_COMMAND=build-misc\Debug\CoverageHelper.exe -DMEMORYCHECK_COMMAND_OPTIONS=--sep-- -DMEMORYCHECK_TYPE=Valgrind
+    cmake -Hmisc -Bbuild-misc -A%PLATFORM% || exit /b !ERRORLEVEL!
+    cmake --build build-misc || exit /b !ERRORLEVEL!
+    cmake -H. -BBuild -A%PLATFORM% -DUSE_WMAIN=%wmain% -DMEMORYCHECK_COMMAND=build-misc\Debug\CoverageHelper.exe -DMEMORYCHECK_COMMAND_OPTIONS=--sep-- -DMEMORYCHECK_TYPE=Valgrind || exit /b !ERRORLEVEL! || exit /b !ERRORLEVEL!
   ) else (
     @REM # We know that coverage is 0
-    if "%examples%"=="1" (
-      @REM # Examples live off the single header, so it needs to be regenerated
-      python scripts\generateSingleHeader.py
-      cmake -H. -BBuild -A%PLATFORM% -DUSE_WMAIN=%wmain% -DCATCH_BUILD_EXAMPLES=ON
-    ) else (
-      @REM # This is just a plain debug build
-      cmake -H. -BBuild -A%PLATFORM% -DUSE_WMAIN=%wmain%
-    )
+    python scripts\generateSingleHeader.py || exit /b !ERRORLEVEL!
+    cmake -H. -BBuild -A%PLATFORM% -DUSE_WMAIN=%wmain% -DCATCH_BUILD_EXAMPLES=%examples% -DCATCH_BUILD_EXTRA_TESTS=%examples% || exit /b !ERRORLEVEL!
   )
 )
 if "%CONFIGURATION%"=="Release" (
-  cmake -H. -BBuild -A%PLATFORM% -DUSE_WMAIN=%wmain%
+  cmake -H. -BBuild -A%PLATFORM% -DUSE_WMAIN=%wmain% || exit /b !ERRORLEVEL!
 )
diff --git a/packages/Catch2/misc/appveyorTestRunScript.bat b/packages/Catch2/misc/appveyorTestRunScript.bat
index 19a364be1..c129d99ea 100644
--- a/packages/Catch2/misc/appveyorTestRunScript.bat
+++ b/packages/Catch2/misc/appveyorTestRunScript.bat
@@ -1,13 +1,15 @@
+SETLOCAL EnableDelayedExpansion
+
 cd Build
 if "%CONFIGURATION%"=="Debug" (
   if "%coverage%"=="1" (
-    ctest -j 2 -C %CONFIGURATION% -D ExperimentalMemCheck
-    python ..\misc\appveyorMergeCoverageScript.py
-    codecov --root .. --no-color --disable gcov -f cobertura.xml -t %CODECOV_TOKEN%
+    ctest -j 2 -C %CONFIGURATION% -D ExperimentalMemCheck || exit /b !ERRORLEVEL!
+    python ..\misc\appveyorMergeCoverageScript.py || exit /b !ERRORLEVEL!
+    codecov --root .. --no-color --disable gcov -f cobertura.xml -t %CODECOV_TOKEN% || exit /b !ERRORLEVEL!
   ) else (
-    ctest -j 2 -C %CONFIGURATION%
+    ctest -j 2 -C %CONFIGURATION% || exit /b !ERRORLEVEL!
   )
 )
 if "%CONFIGURATION%"=="Release" (
-  ctest -j 2 -C %CONFIGURATION%
+  ctest -j 2 -C %CONFIGURATION% || exit /b !ERRORLEVEL!
 )
diff --git a/packages/Catch2/projects/Benchmark/BenchMain.cpp b/packages/Catch2/projects/Benchmark/BenchMain.cpp
deleted file mode 100644
index 32ef4ed9c..000000000
--- a/packages/Catch2/projects/Benchmark/BenchMain.cpp
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
- *  Created by Martin on 16/01/2017.
- *
- *  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)
- */
-
-#define CATCH_CONFIG_MAIN
-#include "catch.hpp"
diff --git a/packages/Catch2/projects/Benchmark/StringificationBench.cpp b/packages/Catch2/projects/Benchmark/StringificationBench.cpp
deleted file mode 100644
index 765b4e965..000000000
--- a/packages/Catch2/projects/Benchmark/StringificationBench.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- *  Created by Martin on 16/01/2017.
- *
- *  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)
- */
-
-#include "catch.hpp"
-
-#include <vector>
-
-///////////////////////////////////////////////////////////////////////////////
-TEST_CASE("Successful tests -- REQUIRE", "[Success]") {
-    const std::size_t sz = 1 * 1024 * 1024;
-
-
-    std::vector<std::size_t> vec; vec.reserve(sz);
-    for (std::size_t i = 0; i < sz; ++i){
-        vec.push_back(i);
-        REQUIRE(vec.back() == i);
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-TEST_CASE("Successful tests -- CHECK", "[Success]") {
-    const std::size_t sz = 1 * 1024 * 1024;
-
-
-    std::vector<std::size_t> vec; vec.reserve(sz);
-    for (std::size_t i = 0; i < sz; ++i){
-        vec.push_back(i);
-        CHECK(vec.back() == i);
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-TEST_CASE("Unsuccessful tests -- CHECK", "[Failure]") {
-    const std::size_t sz = 1024 * 1024;
-
-
-    std::vector<std::size_t> vec; vec.reserve(sz);
-    for (std::size_t i = 0; i < sz; ++i){
-        vec.push_back(i);
-        CHECK(vec.size() == i);
-    }
-}
diff --git a/packages/Catch2/projects/Benchmark/readme.txt b/packages/Catch2/projects/Benchmark/readme.txt
deleted file mode 100644
index c4d2fabd9..000000000
--- a/packages/Catch2/projects/Benchmark/readme.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is very much a work in progress.
-The past results are standardized to a developer's machine,
-the benchmarking script is basic and there are only 3 benchmarks,
-but this should get better in time. For now, at least there is something to go by.
diff --git a/packages/Catch2/projects/Benchmark/results/2017-01-14T21-53-49-e3659cdddd43ba4df9e4846630be6a6a7bd85a07.result b/packages/Catch2/projects/Benchmark/results/2017-01-14T21-53-49-e3659cdddd43ba4df9e4846630be6a6a7bd85a07.result
deleted file mode 100644
index 4b6fc6590..000000000
--- a/packages/Catch2/projects/Benchmark/results/2017-01-14T21-53-49-e3659cdddd43ba4df9e4846630be6a6a7bd85a07.result
+++ /dev/null
@@ -1,3 +0,0 @@
-Successful tests -- CHECK: median: 3.38116 (s), stddev: 0.11567366292001534 (s)
-Successful tests -- REQUIRE: median: 3.479955 (s), stddev: 0.16295972890734556 (s)
-Unsuccessful tests -- CHECK: median: 1.966895 (s), stddev: 0.06323488524716572 (s)
diff --git a/packages/Catch2/projects/Benchmark/results/2017-01-14T21-59-08-a1e9b841ff500b2f39ccfd4193ae450cb653da05.result b/packages/Catch2/projects/Benchmark/results/2017-01-14T21-59-08-a1e9b841ff500b2f39ccfd4193ae450cb653da05.result
deleted file mode 100644
index 98c846017..000000000
--- a/packages/Catch2/projects/Benchmark/results/2017-01-14T21-59-08-a1e9b841ff500b2f39ccfd4193ae450cb653da05.result
+++ /dev/null
@@ -1,3 +0,0 @@
-Successful tests -- CHECK: median: 1.30312 (s), stddev: 0.08759818557862176 (s)
-Successful tests -- REQUIRE: median: 1.341535 (s), stddev: 0.1479193390143576 (s)
-Unsuccessful tests -- CHECK: median: 1.967755 (s), stddev: 0.07921104121269959 (s)
diff --git a/packages/Catch2/projects/Benchmark/results/2017-01-15T09-35-14-3b98a0166f7b7196eba2ad518174d1a77165166d.result b/packages/Catch2/projects/Benchmark/results/2017-01-15T09-35-14-3b98a0166f7b7196eba2ad518174d1a77165166d.result
deleted file mode 100644
index fe6366b89..000000000
--- a/packages/Catch2/projects/Benchmark/results/2017-01-15T09-35-14-3b98a0166f7b7196eba2ad518174d1a77165166d.result
+++ /dev/null
@@ -1,3 +0,0 @@
-Successful tests -- CHECK: median: 1.2982 (s), stddev: 0.019540648829214084 (s)
-Successful tests -- REQUIRE: median: 1.30102 (s), stddev: 0.014758430547392974 (s)
-Unsuccessful tests -- CHECK: median: 15.520199999999999 (s), stddev: 0.09536359426485094 (s)
diff --git a/packages/Catch2/projects/Benchmark/results/2017-01-29T22-08-36-60f8ebec49c5bc58d3604bf1a72cd3f7d129bf2e.result b/packages/Catch2/projects/Benchmark/results/2017-01-29T22-08-36-60f8ebec49c5bc58d3604bf1a72cd3f7d129bf2e.result
deleted file mode 100644
index c9b4d640b..000000000
--- a/packages/Catch2/projects/Benchmark/results/2017-01-29T22-08-36-60f8ebec49c5bc58d3604bf1a72cd3f7d129bf2e.result
+++ /dev/null
@@ -1,3 +0,0 @@
-Successful tests -- CHECK: median: 0.7689014999999999 (s), stddev: 0.02127512078801068 (s)
-Successful tests -- REQUIRE: median: 0.772845 (s), stddev: 0.03011638381365052 (s)
-Unsuccessful tests -- CHECK: median: 15.49 (s), stddev: 0.536088571143903 (s)
diff --git a/packages/Catch2/projects/Benchmark/results/2017-01-29T23-13-35-bcaa2f9646c5ce50758f8582307c99501a932e1a.result b/packages/Catch2/projects/Benchmark/results/2017-01-29T23-13-35-bcaa2f9646c5ce50758f8582307c99501a932e1a.result
deleted file mode 100644
index 5b82330f9..000000000
--- a/packages/Catch2/projects/Benchmark/results/2017-01-29T23-13-35-bcaa2f9646c5ce50758f8582307c99501a932e1a.result
+++ /dev/null
@@ -1,3 +0,0 @@
-Successful tests -- CHECK: median: 0.775769 (s), stddev: 0.014802129132136525 (s)
-Successful tests -- REQUIRE: median: 0.785235 (s), stddev: 0.03532672836834896 (s)
-Unsuccessful tests -- CHECK: median: 15.156600000000001 (s), stddev: 0.2832375673450742 (s)
diff --git a/packages/Catch2/projects/CMakeLists.txt b/packages/Catch2/projects/CMakeLists.txt
new file mode 100644
index 000000000..8e2e4b13e
--- /dev/null
+++ b/packages/Catch2/projects/CMakeLists.txt
@@ -0,0 +1,353 @@
+include(MiscFunctions)
+
+####
+# Temporary workaround for VS toolset changes in 2017
+# We need to disable <UseFullPaths> property, but CMake doesn't support it
+# until 3.13 (not yet released)
+####
+if (MSVC)
+configure_file(${CATCH_DIR}/misc/SelfTest.vcxproj.user
+               ${CMAKE_BINARY_DIR}/projects
+               COPYONLY)
+endif(MSVC) #Temporary workaround
+
+
+# define the sources of the self test
+# Please keep these ordered alphabetically
+set(TEST_SOURCES
+        ${SELF_TEST_DIR}/TestMain.cpp
+        ${SELF_TEST_DIR}/IntrospectiveTests/CmdLine.tests.cpp
+        ${SELF_TEST_DIR}/IntrospectiveTests/GeneratorsImpl.tests.cpp
+        ${SELF_TEST_DIR}/IntrospectiveTests/PartTracker.tests.cpp
+        ${SELF_TEST_DIR}/IntrospectiveTests/TagAlias.tests.cpp
+        ${SELF_TEST_DIR}/IntrospectiveTests/String.tests.cpp
+        ${SELF_TEST_DIR}/IntrospectiveTests/Xml.tests.cpp
+        ${SELF_TEST_DIR}/UsageTests/Approx.tests.cpp
+        ${SELF_TEST_DIR}/UsageTests/BDD.tests.cpp
+        ${SELF_TEST_DIR}/UsageTests/Benchmark.tests.cpp
+        ${SELF_TEST_DIR}/UsageTests/Class.tests.cpp
+        ${SELF_TEST_DIR}/UsageTests/Compilation.tests.cpp
+        ${SELF_TEST_DIR}/UsageTests/Condition.tests.cpp
+        ${SELF_TEST_DIR}/UsageTests/Decomposition.tests.cpp
+        ${SELF_TEST_DIR}/UsageTests/EnumToString.tests.cpp
+        ${SELF_TEST_DIR}/UsageTests/Exception.tests.cpp
+        ${SELF_TEST_DIR}/UsageTests/Generators.tests.cpp
+        ${SELF_TEST_DIR}/UsageTests/Message.tests.cpp
+        ${SELF_TEST_DIR}/UsageTests/Misc.tests.cpp
+        ${SELF_TEST_DIR}/UsageTests/ToStringChrono.tests.cpp
+        ${SELF_TEST_DIR}/UsageTests/ToStringGeneral.tests.cpp
+        ${SELF_TEST_DIR}/UsageTests/ToStringPair.tests.cpp
+        ${SELF_TEST_DIR}/UsageTests/ToStringTuple.tests.cpp
+        ${SELF_TEST_DIR}/UsageTests/ToStringVariant.tests.cpp
+        ${SELF_TEST_DIR}/UsageTests/ToStringVector.tests.cpp
+        ${SELF_TEST_DIR}/UsageTests/ToStringWhich.tests.cpp
+        ${SELF_TEST_DIR}/UsageTests/Tricky.tests.cpp
+        ${SELF_TEST_DIR}/UsageTests/VariadicMacros.tests.cpp
+        ${SELF_TEST_DIR}/UsageTests/Matchers.tests.cpp
+        )
+CheckFileList(TEST_SOURCES ${SELF_TEST_DIR})
+
+# A set of impl files that just #include a single header
+# Please keep these ordered alphabetically
+set(SURROGATE_SOURCES
+        ${SELF_TEST_DIR}/SurrogateCpps/catch_console_colour.cpp
+        ${SELF_TEST_DIR}/SurrogateCpps/catch_debugger.cpp
+        ${SELF_TEST_DIR}/SurrogateCpps/catch_interfaces_reporter.cpp
+        ${SELF_TEST_DIR}/SurrogateCpps/catch_option.cpp
+        ${SELF_TEST_DIR}/SurrogateCpps/catch_stream.cpp
+        ${SELF_TEST_DIR}/SurrogateCpps/catch_test_case_tracker.cpp
+        ${SELF_TEST_DIR}/SurrogateCpps/catch_test_spec.cpp
+        ${SELF_TEST_DIR}/SurrogateCpps/catch_xmlwriter.cpp
+        )
+CheckFileList(SURROGATE_SOURCES ${SELF_TEST_DIR}/SurrogateCpps)
+
+
+# Please keep these ordered alphabetically
+set(TOP_LEVEL_HEADERS
+        ${HEADER_DIR}/catch.hpp
+        ${HEADER_DIR}/catch_with_main.hpp
+        )
+CheckFileList(TOP_LEVEL_HEADERS ${HEADER_DIR})
+
+# Please keep these ordered alphabetically
+set(EXTERNAL_HEADERS
+        ${HEADER_DIR}/external/clara.hpp
+        )
+CheckFileList(EXTERNAL_HEADERS ${HEADER_DIR}/external)
+
+
+# Please keep these ordered alphabetically
+set(INTERNAL_HEADERS
+        ${HEADER_DIR}/internal/catch_approx.h
+        ${HEADER_DIR}/internal/catch_assertionhandler.h
+        ${HEADER_DIR}/internal/catch_assertioninfo.h
+        ${HEADER_DIR}/internal/catch_assertionresult.h
+        ${HEADER_DIR}/internal/catch_capture.hpp
+        ${HEADER_DIR}/internal/catch_capture_matchers.h
+        ${HEADER_DIR}/internal/catch_clara.h
+        ${HEADER_DIR}/internal/catch_commandline.h
+        ${HEADER_DIR}/internal/catch_common.h
+        ${HEADER_DIR}/internal/catch_compiler_capabilities.h
+        ${HEADER_DIR}/internal/catch_config.hpp
+        ${HEADER_DIR}/internal/catch_console_colour.h
+        ${HEADER_DIR}/internal/catch_context.h
+        ${HEADER_DIR}/internal/catch_debug_console.h
+        ${HEADER_DIR}/internal/catch_debugger.h
+        ${HEADER_DIR}/internal/catch_decomposer.h
+        ${HEADER_DIR}/internal/catch_default_main.hpp
+        ${HEADER_DIR}/internal/catch_enforce.h
+        ${HEADER_DIR}/internal/catch_errno_guard.h
+        ${HEADER_DIR}/internal/catch_exception_translator_registry.h
+        ${HEADER_DIR}/internal/catch_external_interfaces.h
+        ${HEADER_DIR}/internal/catch_fatal_condition.h
+        ${HEADER_DIR}/internal/catch_generators.hpp
+        ${HEADER_DIR}/internal/catch_impl.hpp
+        ${HEADER_DIR}/internal/catch_interfaces_capture.h
+        ${HEADER_DIR}/internal/catch_interfaces_config.h
+        ${HEADER_DIR}/internal/catch_interfaces_exception.h
+        ${HEADER_DIR}/internal/catch_interfaces_registry_hub.h
+        ${HEADER_DIR}/internal/catch_interfaces_reporter.h
+        ${HEADER_DIR}/internal/catch_interfaces_runner.h
+        ${HEADER_DIR}/internal/catch_interfaces_tag_alias_registry.h
+        ${HEADER_DIR}/internal/catch_interfaces_testcase.h
+        ${HEADER_DIR}/internal/catch_leak_detector.h
+        ${HEADER_DIR}/internal/catch_list.h
+        ${HEADER_DIR}/internal/catch_matchers.h
+        ${HEADER_DIR}/internal/catch_matchers_floating.h
+        ${HEADER_DIR}/internal/catch_matchers_generic.hpp
+        ${HEADER_DIR}/internal/catch_matchers_string.h
+        ${HEADER_DIR}/internal/catch_matchers_vector.h
+        ${HEADER_DIR}/internal/catch_message.h
+        ${HEADER_DIR}/internal/catch_objc.hpp
+        ${HEADER_DIR}/internal/catch_objc_arc.hpp
+        ${HEADER_DIR}/internal/catch_option.hpp
+        ${HEADER_DIR}/internal/catch_output_redirect.h
+        ${HEADER_DIR}/internal/catch_platform.h
+        ${HEADER_DIR}/internal/catch_random_number_generator.h
+        ${HEADER_DIR}/internal/catch_reenable_warnings.h
+        ${HEADER_DIR}/internal/catch_reporter_registrars.hpp
+        ${HEADER_DIR}/internal/catch_reporter_registry.h
+        ${HEADER_DIR}/internal/catch_result_type.h
+        ${HEADER_DIR}/internal/catch_run_context.h
+        ${HEADER_DIR}/internal/catch_benchmark.h
+        ${HEADER_DIR}/internal/catch_section.h
+        ${HEADER_DIR}/internal/catch_section_info.h
+        ${HEADER_DIR}/internal/catch_session.h
+        ${HEADER_DIR}/internal/catch_singletons.hpp
+        ${HEADER_DIR}/internal/catch_startup_exception_registry.h
+        ${HEADER_DIR}/internal/catch_stream.h
+        ${HEADER_DIR}/internal/catch_stringref.h
+        ${HEADER_DIR}/internal/catch_string_manip.h
+        ${HEADER_DIR}/internal/catch_suppress_warnings.h
+        ${HEADER_DIR}/internal/catch_tag_alias.h
+        ${HEADER_DIR}/internal/catch_tag_alias_autoregistrar.h
+        ${HEADER_DIR}/internal/catch_tag_alias_registry.h
+        ${HEADER_DIR}/internal/catch_test_case_info.h
+        ${HEADER_DIR}/internal/catch_test_case_registry_impl.h
+        ${HEADER_DIR}/internal/catch_test_case_tracker.h
+        ${HEADER_DIR}/internal/catch_test_registry.h
+        ${HEADER_DIR}/internal/catch_test_spec.h
+        ${HEADER_DIR}/internal/catch_test_spec_parser.h
+        ${HEADER_DIR}/internal/catch_text.h
+        ${HEADER_DIR}/internal/catch_timer.h
+        ${HEADER_DIR}/internal/catch_to_string.hpp
+        ${HEADER_DIR}/internal/catch_tostring.h
+        ${HEADER_DIR}/internal/catch_totals.h
+        ${HEADER_DIR}/internal/catch_uncaught_exceptions.h
+        ${HEADER_DIR}/internal/catch_user_interfaces.h
+        ${HEADER_DIR}/internal/catch_version.h
+        ${HEADER_DIR}/internal/catch_wildcard_pattern.h
+        ${HEADER_DIR}/internal/catch_windows_h_proxy.h
+        ${HEADER_DIR}/internal/catch_xmlwriter.h
+        )
+set(IMPL_SOURCES
+        ${HEADER_DIR}/internal/catch_approx.cpp
+        ${HEADER_DIR}/internal/catch_assertionhandler.cpp
+        ${HEADER_DIR}/internal/catch_assertionresult.cpp
+        ${HEADER_DIR}/internal/catch_benchmark.cpp
+        ${HEADER_DIR}/internal/catch_capture_matchers.cpp
+        ${HEADER_DIR}/internal/catch_commandline.cpp
+        ${HEADER_DIR}/internal/catch_common.cpp
+        ${HEADER_DIR}/internal/catch_config.cpp
+        ${HEADER_DIR}/internal/catch_console_colour.cpp
+        ${HEADER_DIR}/internal/catch_context.cpp
+        ${HEADER_DIR}/internal/catch_debug_console.cpp
+        ${HEADER_DIR}/internal/catch_debugger.cpp
+        ${HEADER_DIR}/internal/catch_decomposer.cpp
+        ${HEADER_DIR}/internal/catch_enforce.cpp
+        ${HEADER_DIR}/internal/catch_errno_guard.cpp
+        ${HEADER_DIR}/internal/catch_exception_translator_registry.cpp
+        ${HEADER_DIR}/internal/catch_fatal_condition.cpp
+        ${HEADER_DIR}/internal/catch_generators.cpp
+        ${HEADER_DIR}/internal/catch_interfaces_capture.cpp
+        ${HEADER_DIR}/internal/catch_interfaces_config.cpp
+        ${HEADER_DIR}/internal/catch_interfaces_exception.cpp
+        ${HEADER_DIR}/internal/catch_interfaces_generatortracker.h
+        ${HEADER_DIR}/internal/catch_interfaces_registry_hub.cpp
+        ${HEADER_DIR}/internal/catch_interfaces_runner.cpp
+        ${HEADER_DIR}/internal/catch_interfaces_testcase.cpp
+        ${HEADER_DIR}/internal/catch_list.cpp
+        ${HEADER_DIR}/internal/catch_leak_detector.cpp
+        ${HEADER_DIR}/internal/catch_matchers.cpp
+        ${HEADER_DIR}/internal/catch_matchers_floating.cpp
+        ${HEADER_DIR}/internal/catch_matchers_generic.cpp
+        ${HEADER_DIR}/internal/catch_matchers_string.cpp
+        ${HEADER_DIR}/internal/catch_message.cpp
+        ${HEADER_DIR}/internal/catch_output_redirect.cpp
+        ${HEADER_DIR}/internal/catch_registry_hub.cpp
+        ${HEADER_DIR}/internal/catch_interfaces_reporter.cpp
+        ${HEADER_DIR}/internal/catch_random_number_generator.cpp
+        ${HEADER_DIR}/internal/catch_reporter_registry.cpp
+        ${HEADER_DIR}/internal/catch_result_type.cpp
+        ${HEADER_DIR}/internal/catch_run_context.cpp
+        ${HEADER_DIR}/internal/catch_section.cpp
+        ${HEADER_DIR}/internal/catch_section_info.cpp
+        ${HEADER_DIR}/internal/catch_session.cpp
+        ${HEADER_DIR}/internal/catch_singletons.cpp
+        ${HEADER_DIR}/internal/catch_startup_exception_registry.cpp
+        ${HEADER_DIR}/internal/catch_stream.cpp
+        ${HEADER_DIR}/internal/catch_stringref.cpp
+        ${HEADER_DIR}/internal/catch_string_manip.cpp
+        ${HEADER_DIR}/internal/catch_tag_alias.cpp
+        ${HEADER_DIR}/internal/catch_tag_alias_autoregistrar.cpp
+        ${HEADER_DIR}/internal/catch_tag_alias_registry.cpp
+        ${HEADER_DIR}/internal/catch_test_case_info.cpp
+        ${HEADER_DIR}/internal/catch_test_case_registry_impl.cpp
+        ${HEADER_DIR}/internal/catch_test_case_tracker.cpp
+        ${HEADER_DIR}/internal/catch_test_registry.cpp
+        ${HEADER_DIR}/internal/catch_test_spec.cpp
+        ${HEADER_DIR}/internal/catch_test_spec_parser.cpp
+        ${HEADER_DIR}/internal/catch_timer.cpp
+        ${HEADER_DIR}/internal/catch_tostring.cpp
+        ${HEADER_DIR}/internal/catch_totals.cpp
+        ${HEADER_DIR}/internal/catch_uncaught_exceptions.cpp
+        ${HEADER_DIR}/internal/catch_version.cpp
+        ${HEADER_DIR}/internal/catch_wildcard_pattern.cpp
+        ${HEADER_DIR}/internal/catch_xmlwriter.cpp
+        )
+set(INTERNAL_FILES ${IMPL_SOURCES} ${INTERNAL_HEADERS})
+CheckFileList(INTERNAL_FILES ${HEADER_DIR}/internal)
+
+# Please keep these ordered alphabetically
+set(REPORTER_HEADERS
+        ${HEADER_DIR}/reporters/catch_reporter_automake.hpp
+        ${HEADER_DIR}/reporters/catch_reporter_bases.hpp
+        ${HEADER_DIR}/reporters/catch_reporter_compact.h
+        ${HEADER_DIR}/reporters/catch_reporter_console.h
+        ${HEADER_DIR}/reporters/catch_reporter_junit.h
+        ${HEADER_DIR}/reporters/catch_reporter_listening.h
+        ${HEADER_DIR}/reporters/catch_reporter_tap.hpp
+        ${HEADER_DIR}/reporters/catch_reporter_teamcity.hpp
+        ${HEADER_DIR}/reporters/catch_reporter_xml.h
+        )
+set(REPORTER_SOURCES
+        ${HEADER_DIR}/reporters/catch_reporter_bases.cpp
+        ${HEADER_DIR}/reporters/catch_reporter_compact.cpp
+        ${HEADER_DIR}/reporters/catch_reporter_console.cpp
+        ${HEADER_DIR}/reporters/catch_reporter_junit.cpp
+        ${HEADER_DIR}/reporters/catch_reporter_listening.cpp
+        ${HEADER_DIR}/reporters/catch_reporter_xml.cpp
+        )
+set(REPORTER_FILES ${REPORTER_HEADERS} ${REPORTER_SOURCES})
+CheckFileList(REPORTER_FILES ${HEADER_DIR}/reporters)
+
+# Specify the headers, too, so CLion recognises them as project files
+set(HEADERS
+        ${TOP_LEVEL_HEADERS}
+        ${EXTERNAL_HEADERS}
+        ${INTERNAL_HEADERS}
+        ${REPORTER_HEADERS}
+        )
+
+# Provide some groupings for IDEs
+SOURCE_GROUP("Tests" FILES ${TEST_SOURCES})
+SOURCE_GROUP("Surrogates" FILES ${SURROGATE_SOURCES})
+
+include(CTest)
+
+add_executable(SelfTest ${TEST_SOURCES} ${IMPL_SOURCES} ${REPORTER_SOURCES} ${SURROGATE_SOURCES} ${HEADERS})
+target_include_directories(SelfTest PRIVATE ${HEADER_DIR})
+
+if(USE_CPP17)
+    message(STATUS "Enabling C++17")
+    set_property(TARGET SelfTest PROPERTY CXX_STANDARD 17)
+elseif(USE_CPP14)
+    message(STATUS "Enabling C++14")
+    set_property(TARGET SelfTest PROPERTY CXX_STANDARD 14)
+else()
+    message(STATUS "Enabling C++11")
+    set_property(TARGET SelfTest PROPERTY CXX_STANDARD 11)
+endif()
+
+set_property(TARGET SelfTest PROPERTY CXX_STANDARD_REQUIRED ON)
+set_property(TARGET SelfTest PROPERTY CXX_EXTENSIONS OFF)
+
+if (CATCH_ENABLE_COVERAGE)
+    set(ENABLE_COVERAGE ON CACHE BOOL "Enable coverage build." FORCE)
+    find_package(codecov)
+    add_coverage(SelfTest)
+    list(APPEND LCOV_REMOVE_PATTERNS "'/usr/*'")
+    coverage_evaluate()
+endif()
+
+# Add per compiler options
+if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang|GNU" )
+    target_compile_options( SelfTest PRIVATE -Wall -Wextra -Wunreachable-code -Wpedantic -Wmissing-declarations )
+    if (CATCH_ENABLE_WERROR)
+        target_compile_options( SelfTest PRIVATE -Werror)
+    endif()
+endif()
+# Clang specific options go here
+if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
+    target_compile_options( SelfTest PRIVATE -Wweak-vtables -Wexit-time-destructors -Wglobal-constructors -Wmissing-noreturn )
+endif()
+if ( CMAKE_CXX_COMPILER_ID MATCHES "MSVC" )
+    STRING(REGEX REPLACE "/W[0-9]" "/W4" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) # override default warning level
+    target_compile_options( SelfTest PRIVATE /w44265 /w44061 /w44062 )
+    if (CATCH_ENABLE_WERROR)
+        target_compile_options( SelfTest PRIVATE /WX)
+    endif()
+    # Force MSVC to consider everything as encoded in utf-8
+    target_compile_options( SelfTest PRIVATE /utf-8 )
+endif()
+
+
+# configure unit tests via CTest
+add_test(NAME RunTests COMMAND $<TARGET_FILE:SelfTest>)
+
+add_test(NAME ListTests COMMAND $<TARGET_FILE:SelfTest> --list-tests --verbosity high)
+set_tests_properties(ListTests PROPERTIES 
+    PASS_REGULAR_EXPRESSION "[0-9]+ test cases"
+    FAIL_REGULAR_EXPRESSION "Hidden Test"
+)
+
+add_test(NAME ListTags COMMAND $<TARGET_FILE:SelfTest> --list-tags)
+set_tests_properties(ListTags PROPERTIES 
+    PASS_REGULAR_EXPRESSION "[0-9]+ tags" 
+    FAIL_REGULAR_EXPRESSION "\\[\\.\\]")
+
+add_test(NAME ListReporters COMMAND $<TARGET_FILE:SelfTest> --list-reporters)
+set_tests_properties(ListReporters PROPERTIES PASS_REGULAR_EXPRESSION "Available reporters:")
+
+add_test(NAME ListTestNamesOnly COMMAND $<TARGET_FILE:SelfTest> --list-test-names-only)
+set_tests_properties(ListTestNamesOnly PROPERTIES 
+    PASS_REGULAR_EXPRESSION "Regex string matcher"
+    FAIL_REGULAR_EXPRESSION "Hidden Test")
+
+add_test(NAME NoAssertions COMMAND $<TARGET_FILE:SelfTest> -w NoAssertions)
+set_tests_properties(NoAssertions PROPERTIES PASS_REGULAR_EXPRESSION "No assertions in test case")
+
+add_test(NAME NoTest COMMAND $<TARGET_FILE:SelfTest> -w NoTests "___nonexistent_test___")
+set_tests_properties(NoTest PROPERTIES PASS_REGULAR_EXPRESSION "No test cases matched")
+
+# AppVeyor has a Python 2.7 in path, but doesn't have .py files as autorunnable
+add_test(NAME ApprovalTests COMMAND ${PYTHON_EXECUTABLE} ${CATCH_DIR}/scripts/approvalTests.py $<TARGET_FILE:SelfTest>)
+set_tests_properties(ApprovalTests PROPERTIES FAIL_REGULAR_EXPRESSION "Results differed")
+
+if (CATCH_USE_VALGRIND)
+    add_test(NAME ValgrindRunTests COMMAND valgrind --leak-check=full --error-exitcode=1 $<TARGET_FILE:SelfTest>)
+    add_test(NAME ValgrindListTests COMMAND valgrind --leak-check=full --error-exitcode=1 $<TARGET_FILE:SelfTest> --list-tests --verbosity high)
+    set_tests_properties(ValgrindListTests PROPERTIES PASS_REGULAR_EXPRESSION "definitely lost: 0 bytes in 0 blocks")
+    add_test(NAME ValgrindListTags COMMAND valgrind --leak-check=full --error-exitcode=1 $<TARGET_FILE:SelfTest> --list-tags)
+    set_tests_properties(ValgrindListTags PROPERTIES PASS_REGULAR_EXPRESSION "definitely lost: 0 bytes in 0 blocks")
+endif()
diff --git a/packages/Catch2/projects/ExtraTests/CMakeLists.txt b/packages/Catch2/projects/ExtraTests/CMakeLists.txt
new file mode 100644
index 000000000..c0dd82d8f
--- /dev/null
+++ b/packages/Catch2/projects/ExtraTests/CMakeLists.txt
@@ -0,0 +1,135 @@
+#
+# Build extra tests.
+#
+# Requires CATCH_BUILD_EXTRA_TESTS to be defined 'true', see ../CMakeLists.txt.
+#
+
+cmake_minimum_required( VERSION 3.5 )
+
+project( Catch2ExtraTests LANGUAGES CXX )
+
+message( STATUS "Extra tests included" )
+
+# define folders used:
+
+set( TESTS_DIR   ${CATCH_DIR}/projects/ExtraTests )
+set( SINGLE_INCLUDE_PATH ${CATCH_DIR}/single_include )
+
+
+add_executable(PrefixedMacros ${TESTS_DIR}/X01-PrefixedMacros.cpp)
+target_compile_definitions( PrefixedMacros PRIVATE CATCH_CONFIG_PREFIX_ALL )
+
+add_test(NAME CATCH_CONFIG_PREFIX_ALL COMMAND PrefixedMacros -s)
+set_tests_properties(
+    CATCH_CONFIG_PREFIX_ALL
+  PROPERTIES
+    PASS_REGULAR_EXPRESSION "CATCH_"
+    FAIL_REGULAR_EXPRESSION
+    # The spaces are important -> They disambiguate between CATCH_REQUIRE
+    # and REQUIRE without prefix.
+    " REQUIRE; REQUIRE_FALSE; REQUIRE_THROWS; REQUIRE_THROWS_AS; REQUIRE_THROWS_WITH; REQUIRE_THROWS_MATCHES; REQUIRE_NOTHROW; CHECK; CHECK_FALSE; CHECKED_IF; CHECKED_ELSE; CHECK_NOFAIL; CHECK_THROWS; CHECK_THROWS_AS; CHECK_THROWS_WITH; CHECK_THROWS_MATCHES; CHECK_NOTHROW; REQUIRE_THAT; CHECK_THAT"
+)
+
+add_executable(DisabledMacros ${TESTS_DIR}/X02-DisabledMacros.cpp)
+target_compile_definitions( DisabledMacros PRIVATE CATCH_CONFIG_DISABLE )
+
+add_test(NAME CATCH_CONFIG_DISABLE-1 COMMAND DisabledMacros -s)
+set_tests_properties(
+    CATCH_CONFIG_DISABLE-1
+  PROPERTIES
+    PASS_REGULAR_EXPRESSION "No tests ran"
+    FAIL_REGULAR_EXPRESSION "This should not happen"
+)
+add_test(NAME CATCH_CONFIG_DISABLE-2 COMMAND DisabledMacros --list-tests)
+set_tests_properties(
+    CATCH_CONFIG_DISABLE-2
+  PROPERTIES
+    PASS_REGULAR_EXPRESSION "0 test cases"
+)
+
+
+add_executable( DisabledExceptions-DefaultHandler ${TESTS_DIR}/X03-DisabledExceptions-DefaultHandler.cpp )
+add_executable( DisabledExceptions-CustomHandler ${TESTS_DIR}/X04-DisabledExceptions-CustomHandler.cpp )
+
+foreach(target DisabledExceptions-DefaultHandler DisabledExceptions-CustomHandler)
+target_compile_options( ${target}
+  PRIVATE
+    $<$<CXX_COMPILER_ID:MSVC>:/EHs-c-;/D_HAS_EXCEPTIONS=0>
+    $<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:GNU>,$<CXX_COMPILER_ID:AppleClang>>:-fno-exceptions>
+#    $<$<CXX_COMPILER_ID:Clang>:-fno-exceptions>
+#    $<$<CXX_COMPILER_ID:GNU>:-fno-exceptions>
+)
+endforeach()
+
+
+add_test(NAME CATCH_CONFIG_DISABLE_EXCEPTIONS-1 COMMAND DisabledExceptions-DefaultHandler "Tests that run")
+set_tests_properties(
+    CATCH_CONFIG_DISABLE_EXCEPTIONS-1
+  PROPERTIES
+    PASS_REGULAR_EXPRESSION "assertions: 4 \| 2 passed \| 2 failed"
+    FAIL_REGULAR_EXPRESSION "abort;terminate;fatal"
+)
+
+add_test(NAME CATCH_CONFIG_DISABLE_EXCEPTIONS-2 COMMAND DisabledExceptions-DefaultHandler "Tests that abort")
+set_tests_properties(
+    CATCH_CONFIG_DISABLE_EXCEPTIONS-2
+  PROPERTIES
+    PASS_REGULAR_EXPRESSION "Catch will terminate"
+)
+
+add_test(NAME CATCH_CONFIG_DISABLE_EXCEPTIONS-3 COMMAND DisabledExceptions-CustomHandler "Tests that run")
+set_tests_properties(
+    CATCH_CONFIG_DISABLE_EXCEPTIONS-3
+  PROPERTIES
+    PASS_REGULAR_EXPRESSION "assertions: 4 \| 2 passed \| 2 failed"
+    FAIL_REGULAR_EXPRESSION "====== CUSTOM HANDLER ======"
+)
+
+add_test(NAME CATCH_CONFIG_DISABLE_EXCEPTIONS-4 COMMAND DisabledExceptions-CustomHandler "Tests that abort")
+set_tests_properties(
+    CATCH_CONFIG_DISABLE_EXCEPTIONS-4
+  PROPERTIES
+    PASS_REGULAR_EXPRESSION "====== CUSTOM HANDLER ======"
+)
+
+
+
+add_executable(FallbackStringifier ${TESTS_DIR}/X10-FallbackStringifier.cpp)
+target_compile_definitions( FallbackStringifier PRIVATE CATCH_CONFIG_FALLBACK_STRINGIFIER=fallbackStringifier )
+
+add_test(NAME FallbackStringifier COMMAND FallbackStringifier -r compact -s)
+set_tests_properties(
+    FallbackStringifier
+  PROPERTIES
+    PASS_REGULAR_EXPRESSION "foo{} for: { !!! }"
+)
+
+
+add_executable(DisableStringification ${TESTS_DIR}/X11-DisableStringification.cpp)
+target_compile_definitions( DisableStringification PRIVATE CATCH_CONFIG_DISABLE_STRINGIFICATION )
+add_test(NAME CATCH_CONFIG_DISABLE_STRINGIFICATION COMMAND DisableStringification -r compact -s)
+set_tests_properties(
+    CATCH_CONFIG_DISABLE_STRINGIFICATION
+  PROPERTIES
+    PASS_REGULAR_EXPRESSION "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION"
+    FAIL_REGULAR_EXPRESSION  "Hidden{} == Hidden{}"
+)
+
+
+set( EXTRA_TEST_BINARIES
+    PrefixedMacros
+    DisabledMacros
+    DisabledExceptions-DefaultHandler
+    DisabledExceptions-CustomHandler
+    FallbackStringifier
+    DisableStringification
+)
+
+# Shared config
+foreach( test ${EXTRA_TEST_BINARIES} )
+    set_property( TARGET ${test} PROPERTY CXX_STANDARD 11 )
+    set_property( TARGET ${test} PROPERTY CXX_STANDARD_REQUIRED ON )
+    set_property( TARGET ${test} PROPERTY CXX_EXTENSIONS OFF )
+    target_include_directories( ${test} PRIVATE ${SINGLE_INCLUDE_PATH} )
+endforeach()
+
diff --git a/packages/Catch2/projects/ExtraTests/ToDo.txt b/packages/Catch2/projects/ExtraTests/ToDo.txt
new file mode 100644
index 000000000..ab68bd3e5
--- /dev/null
+++ b/packages/Catch2/projects/ExtraTests/ToDo.txt
@@ -0,0 +1,11 @@
+Configuration options that are left default and thus are not properly tested
+yet:
+
+    CATCH_CONFIG_COUNTER                    // Use __COUNTER__ to generate unique names for test cases
+    CATCH_CONFIG_WINDOWS_SEH                // Enable SEH handling on Windows
+    CATCH_CONFIG_FAST_COMPILE               // Sacrifices some (rather minor) features for compilation speed
+    CATCH_CONFIG_DISABLE_MATCHERS           // Do not compile Matchers in this compilation unit
+    CATCH_CONFIG_POSIX_SIGNALS              // Enable handling POSIX signals
+    CATCH_CONFIG_WINDOWS_CRTDBG             // Enable leak checking using Windows's CRT Debug Heap
+    CATCH_CONFIG_DEFAULT_REPORTER
+    CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS
diff --git a/packages/Catch2/projects/ExtraTests/X01-PrefixedMacros.cpp b/packages/Catch2/projects/ExtraTests/X01-PrefixedMacros.cpp
new file mode 100644
index 000000000..08bf404fb
--- /dev/null
+++ b/packages/Catch2/projects/ExtraTests/X01-PrefixedMacros.cpp
@@ -0,0 +1,76 @@
+// X11-DisableStringification.cpp
+// Test that Catch's prefixed macros compile and run properly.
+
+#define CATCH_CONFIG_MAIN
+#include <catch2/catch.hpp>
+
+#include <stdexcept>
+
+[[noreturn]]
+void this_throws() {
+    throw std::runtime_error("Some msg");
+}
+void this_doesnt_throw() {}
+
+CATCH_TEST_CASE("PrefixedMacros") {
+    using namespace Catch::Matchers;
+
+    CATCH_REQUIRE( 1 == 1 );
+    CATCH_REQUIRE_FALSE( 1 != 1 );
+
+    CATCH_REQUIRE_THROWS(this_throws());
+    CATCH_REQUIRE_THROWS_AS(this_throws(), std::runtime_error);
+    CATCH_REQUIRE_THROWS_WITH(this_throws(), "Some msg");
+    CATCH_REQUIRE_THROWS_MATCHES(this_throws(), std::runtime_error, Predicate<std::runtime_error>([](std::runtime_error const&) { return true; }));
+    CATCH_REQUIRE_NOTHROW(this_doesnt_throw());
+    
+    CATCH_CHECK( 1 == 1 );
+    CATCH_CHECK_FALSE( 1 != 1 );
+    CATCH_CHECKED_IF( 1 == 1 ) {
+        CATCH_SUCCEED("don't care");
+    } CATCH_CHECKED_ELSE ( 1 == 1 ) {
+        CATCH_SUCCEED("don't care");
+    }
+    
+    CATCH_CHECK_NOFAIL(1 == 2);
+    
+    CATCH_CHECK_THROWS(this_throws());
+    CATCH_CHECK_THROWS_AS(this_throws(), std::runtime_error);
+    CATCH_CHECK_THROWS_WITH(this_throws(), "Some msg");
+    CATCH_CHECK_THROWS_MATCHES(this_throws(), std::runtime_error, Predicate<std::runtime_error>([](std::runtime_error const&) { return true; }));
+    CATCH_CHECK_NOTHROW(this_doesnt_throw());    
+    
+    CATCH_REQUIRE_THAT("abcd", Equals("abcd"));
+    CATCH_CHECK_THAT("bdef", Equals("bdef"));
+
+    CATCH_INFO( "some info" );
+    CATCH_WARN( "some warn" );
+    CATCH_SECTION("some section") {
+        int i = 1;
+        CATCH_CAPTURE( i );
+        CATCH_DYNAMIC_SECTION("Dynamic section: " << i) {
+            CATCH_FAIL_CHECK( "failure" );
+        }
+    }
+}
+
+CATCH_ANON_TEST_CASE() {
+    CATCH_FAIL("");
+}
+
+// Missing:
+
+//
+// #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
+// #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
+// #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
+//
+// // "BDD-style" convenience wrappers
+// #define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
+// #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
+// #define CATCH_GIVEN( desc )    INTERNAL_CATCH_DYNAMIC_SECTION( "   Given: " << desc )
+// #define CATCH_WHEN( desc )     INTERNAL_CATCH_DYNAMIC_SECTION( "    When: " << desc )
+// #define CATCH_AND_WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And when: " << desc )
+// #define CATCH_THEN( desc )     INTERNAL_CATCH_DYNAMIC_SECTION( "    Then: " << desc )
+// #define CATCH_AND_THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "     And: " << desc )
+//
diff --git a/packages/Catch2/projects/ExtraTests/X02-DisabledMacros.cpp b/packages/Catch2/projects/ExtraTests/X02-DisabledMacros.cpp
new file mode 100644
index 000000000..3a969d769
--- /dev/null
+++ b/packages/Catch2/projects/ExtraTests/X02-DisabledMacros.cpp
@@ -0,0 +1,31 @@
+// X02-DisabledMacros.cpp
+// Test that CATCH_CONFIG_DISABLE turns off TEST_CASE autoregistration
+// and expressions in assertion macros are not run.
+
+#define CATCH_CONFIG_MAIN
+#include <catch2/catch.hpp>
+
+
+// CATCH_CONFIG_DISABLE also prevents reporter registration.
+// We need to manually register at least one reporter for our tests
+static Catch::ReporterRegistrar<Catch::ConsoleReporter> temporary( "console" );
+
+#include <iostream>
+
+struct foo {
+    foo(){
+        REQUIRE_NOTHROW( print() );
+    }
+    void print() const {
+        std::cout << "This should not happen\n";
+    }
+};
+
+// Construct foo, but `foo::print` should not be run
+foo f;
+
+// This test should not be run, because it won't be registered
+TEST_CASE( "Disabled Macros" ) {
+    std::cout << "This should not happen\n";
+    FAIL();
+}
diff --git a/packages/Catch2/projects/ExtraTests/X03-DisabledExceptions-DefaultHandler.cpp b/packages/Catch2/projects/ExtraTests/X03-DisabledExceptions-DefaultHandler.cpp
new file mode 100644
index 000000000..846c9b0f8
--- /dev/null
+++ b/packages/Catch2/projects/ExtraTests/X03-DisabledExceptions-DefaultHandler.cpp
@@ -0,0 +1,23 @@
+#define CATCH_CONFIG_MAIN
+#include <catch2/catch.hpp>
+
+TEST_CASE("Tests that run") {
+    // All of these should be run and be reported
+    CHECK(1 == 2);
+    CHECK(1 == 1);
+    CHECK(1 != 3);
+    CHECK(1 == 4);
+}
+
+
+
+TEST_CASE("Tests that abort") {
+    // Avoid abort and other exceptional exits -- there is no way
+    // to tell CMake that abort is the desired outcome of a test.
+    std::set_terminate([](){exit(1);});
+    REQUIRE(1 == 1);
+    REQUIRE(1 != 2);
+    REQUIRE(1 == 3);
+    // We should not get here, because the test above aborts
+    REQUIRE(1 != 4);
+}
diff --git a/packages/Catch2/projects/ExtraTests/X04-DisabledExceptions-CustomHandler.cpp b/packages/Catch2/projects/ExtraTests/X04-DisabledExceptions-CustomHandler.cpp
new file mode 100644
index 000000000..96f3ceb84
--- /dev/null
+++ b/packages/Catch2/projects/ExtraTests/X04-DisabledExceptions-CustomHandler.cpp
@@ -0,0 +1,33 @@
+#define CATCH_CONFIG_DISABLE_EXCEPTIONS_CUSTOM_HANDLER
+
+#define CATCH_CONFIG_MAIN
+#include <catch2/catch.hpp>
+
+namespace Catch {
+    [[noreturn]]
+    void throw_exception(std::exception const& e) {
+        Catch::cerr() << "====== CUSTOM HANDLER ====== run terminates because an exception was thrown.\n"
+                      << "The message was: " << e.what() << '\n';
+        // Avoid abort and other exceptional exits -- there is no way
+        // to tell CMake that abort is the desired outcome of a test.
+        exit(1);
+    }
+}
+
+TEST_CASE("Tests that run") {
+    // All of these should be run and be reported
+    CHECK(1 == 2);
+    CHECK(1 == 1);
+    CHECK(1 != 3);
+    CHECK(1 == 4);
+}
+
+
+
+TEST_CASE("Tests that abort") {
+    REQUIRE(1 == 1);
+    REQUIRE(1 != 2);
+    REQUIRE(1 == 3);
+    // We should not get here, because the test above aborts
+    REQUIRE(1 != 4);
+}
diff --git a/packages/Catch2/projects/ExtraTests/X10-FallbackStringifier.cpp b/packages/Catch2/projects/ExtraTests/X10-FallbackStringifier.cpp
new file mode 100644
index 000000000..0522d1af8
--- /dev/null
+++ b/packages/Catch2/projects/ExtraTests/X10-FallbackStringifier.cpp
@@ -0,0 +1,23 @@
+// X10-FallbackStringifier.cpp
+// Test that defining fallbackStringifier compiles
+
+#include <string>
+
+// A catch-all stringifier
+template <typename T>
+std::string fallbackStringifier(T const&) {
+    return "{ !!! }";
+}
+
+#define CATCH_CONFIG_MAIN
+#include <catch2/catch.hpp>
+
+struct foo {
+    explicit operator bool() const {
+        return true;
+    }
+};
+
+TEST_CASE("aa") {
+    REQUIRE(foo{});
+}
diff --git a/packages/Catch2/projects/ExtraTests/X11-DisableStringification.cpp b/packages/Catch2/projects/ExtraTests/X11-DisableStringification.cpp
new file mode 100644
index 000000000..7a93f6e29
--- /dev/null
+++ b/packages/Catch2/projects/ExtraTests/X11-DisableStringification.cpp
@@ -0,0 +1,16 @@
+// X11-DisableStringification.cpp
+// Test that stringification of original expression can be disabled
+// this is a workaround for VS 2017 issue with Raw String literal
+// and preprocessor token pasting. In other words, hopefully this test
+// will be deleted soon :-)
+
+#define CATCH_CONFIG_MAIN
+#include <catch2/catch.hpp>
+
+struct Hidden {};
+
+bool operator==(Hidden, Hidden) { return true; }
+
+TEST_CASE("DisableStringification") {
+    REQUIRE( Hidden{} == Hidden{} );
+}
diff --git a/packages/Catch2/projects/SelfTest/Baselines/compact.sw.approved.txt b/packages/Catch2/projects/SelfTest/Baselines/compact.sw.approved.txt
index 24d9b1b79..2138d26ee 100644
--- a/packages/Catch2/projects/SelfTest/Baselines/compact.sw.approved.txt
+++ b/packages/Catch2/projects/SelfTest/Baselines/compact.sw.approved.txt
@@ -56,10 +56,116 @@ Tricky.tests.cpp:<line number>: passed: !is_true<false>::value for: true
 Tricky.tests.cpp:<line number>: passed: !!is_true<true>::value for: true
 Tricky.tests.cpp:<line number>: passed: is_true<true>::value for: true
 Tricky.tests.cpp:<line number>: passed: !(is_true<false>::value) for: !false
+Generators.tests.cpp:<line number>: passed: x < y for: 1 < 101
+Generators.tests.cpp:<line number>: passed: x < y for: 1 < 102
+Generators.tests.cpp:<line number>: passed: x < y for: 1 < 103
+Generators.tests.cpp:<line number>: passed: x < y for: 1 < 104
+Generators.tests.cpp:<line number>: passed: x < y for: 1 < 105
+Generators.tests.cpp:<line number>: passed: x < y for: 1 < 106
+Generators.tests.cpp:<line number>: passed: x < y for: 1 < 107
+Generators.tests.cpp:<line number>: passed: x < y for: 1 < 108
+Generators.tests.cpp:<line number>: passed: x < y for: 1 < 109
+Generators.tests.cpp:<line number>: passed: x < y for: 1 < 110
+Generators.tests.cpp:<line number>: passed: x < y for: 2 < 101
+Generators.tests.cpp:<line number>: passed: x < y for: 2 < 102
+Generators.tests.cpp:<line number>: passed: x < y for: 2 < 103
+Generators.tests.cpp:<line number>: passed: x < y for: 2 < 104
+Generators.tests.cpp:<line number>: passed: x < y for: 2 < 105
+Generators.tests.cpp:<line number>: passed: x < y for: 2 < 106
+Generators.tests.cpp:<line number>: passed: x < y for: 2 < 107
+Generators.tests.cpp:<line number>: passed: x < y for: 2 < 108
+Generators.tests.cpp:<line number>: passed: x < y for: 2 < 109
+Generators.tests.cpp:<line number>: passed: x < y for: 2 < 110
+Generators.tests.cpp:<line number>: passed: x < y for: 3 < 101
+Generators.tests.cpp:<line number>: passed: x < y for: 3 < 102
+Generators.tests.cpp:<line number>: passed: x < y for: 3 < 103
+Generators.tests.cpp:<line number>: passed: x < y for: 3 < 104
+Generators.tests.cpp:<line number>: passed: x < y for: 3 < 105
+Generators.tests.cpp:<line number>: passed: x < y for: 3 < 106
+Generators.tests.cpp:<line number>: passed: x < y for: 3 < 107
+Generators.tests.cpp:<line number>: passed: x < y for: 3 < 108
+Generators.tests.cpp:<line number>: passed: x < y for: 3 < 109
+Generators.tests.cpp:<line number>: passed: x < y for: 3 < 110
+Generators.tests.cpp:<line number>: passed: x < y for: 4 < 101
+Generators.tests.cpp:<line number>: passed: x < y for: 4 < 102
+Generators.tests.cpp:<line number>: passed: x < y for: 4 < 103
+Generators.tests.cpp:<line number>: passed: x < y for: 4 < 104
+Generators.tests.cpp:<line number>: passed: x < y for: 4 < 105
+Generators.tests.cpp:<line number>: passed: x < y for: 4 < 106
+Generators.tests.cpp:<line number>: passed: x < y for: 4 < 107
+Generators.tests.cpp:<line number>: passed: x < y for: 4 < 108
+Generators.tests.cpp:<line number>: passed: x < y for: 4 < 109
+Generators.tests.cpp:<line number>: passed: x < y for: 4 < 110
+Generators.tests.cpp:<line number>: passed: x < y for: 5 < 101
+Generators.tests.cpp:<line number>: passed: x < y for: 5 < 102
+Generators.tests.cpp:<line number>: passed: x < y for: 5 < 103
+Generators.tests.cpp:<line number>: passed: x < y for: 5 < 104
+Generators.tests.cpp:<line number>: passed: x < y for: 5 < 105
+Generators.tests.cpp:<line number>: passed: x < y for: 5 < 106
+Generators.tests.cpp:<line number>: passed: x < y for: 5 < 107
+Generators.tests.cpp:<line number>: passed: x < y for: 5 < 108
+Generators.tests.cpp:<line number>: passed: x < y for: 5 < 109
+Generators.tests.cpp:<line number>: passed: x < y for: 5 < 110
+Generators.tests.cpp:<line number>: passed: x < y for: 6 < 101
+Generators.tests.cpp:<line number>: passed: x < y for: 6 < 102
+Generators.tests.cpp:<line number>: passed: x < y for: 6 < 103
+Generators.tests.cpp:<line number>: passed: x < y for: 6 < 104
+Generators.tests.cpp:<line number>: passed: x < y for: 6 < 105
+Generators.tests.cpp:<line number>: passed: x < y for: 6 < 106
+Generators.tests.cpp:<line number>: passed: x < y for: 6 < 107
+Generators.tests.cpp:<line number>: passed: x < y for: 6 < 108
+Generators.tests.cpp:<line number>: passed: x < y for: 6 < 109
+Generators.tests.cpp:<line number>: passed: x < y for: 6 < 110
+Generators.tests.cpp:<line number>: passed: x < y for: 7 < 101
+Generators.tests.cpp:<line number>: passed: x < y for: 7 < 102
+Generators.tests.cpp:<line number>: passed: x < y for: 7 < 103
+Generators.tests.cpp:<line number>: passed: x < y for: 7 < 104
+Generators.tests.cpp:<line number>: passed: x < y for: 7 < 105
+Generators.tests.cpp:<line number>: passed: x < y for: 7 < 106
+Generators.tests.cpp:<line number>: passed: x < y for: 7 < 107
+Generators.tests.cpp:<line number>: passed: x < y for: 7 < 108
+Generators.tests.cpp:<line number>: passed: x < y for: 7 < 109
+Generators.tests.cpp:<line number>: passed: x < y for: 7 < 110
+Generators.tests.cpp:<line number>: passed: x < y for: 8 < 101
+Generators.tests.cpp:<line number>: passed: x < y for: 8 < 102
+Generators.tests.cpp:<line number>: passed: x < y for: 8 < 103
+Generators.tests.cpp:<line number>: passed: x < y for: 8 < 104
+Generators.tests.cpp:<line number>: passed: x < y for: 8 < 105
+Generators.tests.cpp:<line number>: passed: x < y for: 8 < 106
+Generators.tests.cpp:<line number>: passed: x < y for: 8 < 107
+Generators.tests.cpp:<line number>: passed: x < y for: 8 < 108
+Generators.tests.cpp:<line number>: passed: x < y for: 8 < 109
+Generators.tests.cpp:<line number>: passed: x < y for: 8 < 110
+Generators.tests.cpp:<line number>: passed: x < y for: 9 < 101
+Generators.tests.cpp:<line number>: passed: x < y for: 9 < 102
+Generators.tests.cpp:<line number>: passed: x < y for: 9 < 103
+Generators.tests.cpp:<line number>: passed: x < y for: 9 < 104
+Generators.tests.cpp:<line number>: passed: x < y for: 9 < 105
+Generators.tests.cpp:<line number>: passed: x < y for: 9 < 106
+Generators.tests.cpp:<line number>: passed: x < y for: 9 < 107
+Generators.tests.cpp:<line number>: passed: x < y for: 9 < 108
+Generators.tests.cpp:<line number>: passed: x < y for: 9 < 109
+Generators.tests.cpp:<line number>: passed: x < y for: 9 < 110
+Generators.tests.cpp:<line number>: passed: x < y for: 10 < 101
+Generators.tests.cpp:<line number>: passed: x < y for: 10 < 102
+Generators.tests.cpp:<line number>: passed: x < y for: 10 < 103
+Generators.tests.cpp:<line number>: passed: x < y for: 10 < 104
+Generators.tests.cpp:<line number>: passed: x < y for: 10 < 105
+Generators.tests.cpp:<line number>: passed: x < y for: 10 < 106
+Generators.tests.cpp:<line number>: passed: x < y for: 10 < 107
+Generators.tests.cpp:<line number>: passed: x < y for: 10 < 108
+Generators.tests.cpp:<line number>: passed: x < y for: 10 < 109
+Generators.tests.cpp:<line number>: passed: x < y for: 10 < 110
 Class.tests.cpp:<line number>: failed: s == "world" for: "hello" == "world"
 Class.tests.cpp:<line number>: passed: s == "hello" for: "hello" == "hello"
 Class.tests.cpp:<line number>: failed: m_a == 2 for: 1 == 2
 Class.tests.cpp:<line number>: passed: m_a == 1 for: 1 == 1
+Approx.tests.cpp:<line number>: passed: d == 1.23_a for: 1.23 == Approx( 1.23 )
+Approx.tests.cpp:<line number>: passed: d != 1.22_a for: 1.23 != Approx( 1.22 )
+Approx.tests.cpp:<line number>: passed: -d == -1.23_a for: -1.23 == Approx( -1.23 )
+Approx.tests.cpp:<line number>: passed: d == 1.2_a .epsilon(.1) for: 1.23 == Approx( 1.2 )
+Approx.tests.cpp:<line number>: passed: d != 1.2_a .epsilon(.001) for: 1.23 != Approx( 1.2 )
+Approx.tests.cpp:<line number>: passed: d == 1_a .epsilon(.3) for: 1.23 == Approx( 1.0 )
 Misc.tests.cpp:<line number>: passed: with 1 message: 'that's not flying - that's failing in style'
 Misc.tests.cpp:<line number>: failed: explicitly with 1 message: 'to infinity and beyond'
 Tricky.tests.cpp:<line number>: failed: &o1 == &o2 for: 0x<hex digits> == 0x<hex digits>
@@ -291,6 +397,48 @@ Matchers.tests.cpp:<line number>: passed: WithinAbs(1.f, 0.f)
 Matchers.tests.cpp:<line number>: passed: WithinAbs(1.f, -1.f), std::domain_error
 Matchers.tests.cpp:<line number>: passed: WithinULP(1.f, 0)
 Matchers.tests.cpp:<line number>: passed: WithinULP(1.f, -1), std::domain_error
+Generators.tests.cpp:<line number>: passed: with 2 messages: 'i := "a"' and 'j := 8'
+Generators.tests.cpp:<line number>: passed: with 2 messages: 'i := "a"' and 'j := 9'
+Generators.tests.cpp:<line number>: passed: with 2 messages: 'i := "a"' and 'j := 10'
+Generators.tests.cpp:<line number>: passed: with 2 messages: 'i := "a"' and 'j := 2'
+Generators.tests.cpp:<line number>: passed: with 2 messages: 'i := "a"' and 'j := 3.141'
+Generators.tests.cpp:<line number>: passed: with 2 messages: 'i := "a"' and 'j := 1.379'
+Generators.tests.cpp:<line number>: passed: with 2 messages: 'i := "b"' and 'j := 8'
+Generators.tests.cpp:<line number>: passed: with 2 messages: 'i := "b"' and 'j := 9'
+Generators.tests.cpp:<line number>: passed: with 2 messages: 'i := "b"' and 'j := 10'
+Generators.tests.cpp:<line number>: passed: with 2 messages: 'i := "b"' and 'j := 2'
+Generators.tests.cpp:<line number>: passed: with 2 messages: 'i := "b"' and 'j := 3.141'
+Generators.tests.cpp:<line number>: passed: with 2 messages: 'i := "b"' and 'j := 1.379'
+Generators.tests.cpp:<line number>: passed: with 2 messages: 'i := "c"' and 'j := 8'
+Generators.tests.cpp:<line number>: passed: with 2 messages: 'i := "c"' and 'j := 9'
+Generators.tests.cpp:<line number>: passed: with 2 messages: 'i := "c"' and 'j := 10'
+Generators.tests.cpp:<line number>: passed: with 2 messages: 'i := "c"' and 'j := 2'
+Generators.tests.cpp:<line number>: passed: with 2 messages: 'i := "c"' and 'j := 3.141'
+Generators.tests.cpp:<line number>: passed: with 2 messages: 'i := "c"' and 'j := 1.379'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.size() == 2 for: 2 == 2
+GeneratorsImpl.tests.cpp:<line number>: passed: gen[0] == 1 for: 1 == 1
+GeneratorsImpl.tests.cpp:<line number>: passed: gen[1] == 2 for: 2 == 2
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.size() == 4 for: 4 == 4
+GeneratorsImpl.tests.cpp:<line number>: passed: gen[0] == 3 for: 3 == 3
+GeneratorsImpl.tests.cpp:<line number>: passed: gen[1] == 1 for: 1 == 1
+GeneratorsImpl.tests.cpp:<line number>: passed: gen[2] == 4 for: 4 == 4
+GeneratorsImpl.tests.cpp:<line number>: passed: gen[3] == 1 for: 1 == 1
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.size() == 4 for: 4 == 4
+GeneratorsImpl.tests.cpp:<line number>: passed: gen[0] == 1 for: 1 == 1
+GeneratorsImpl.tests.cpp:<line number>: passed: gen[1] == 2 for: 2 == 2
+GeneratorsImpl.tests.cpp:<line number>: passed: gen[2] == 9 for: 9 == 9
+GeneratorsImpl.tests.cpp:<line number>: passed: gen[3] == 7 for: 7 == 7
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.size() == 2 for: 2 == 2
+GeneratorsImpl.tests.cpp:<line number>: passed: gen[0] == 3 for: 3 == 3
+GeneratorsImpl.tests.cpp:<line number>: passed: gen[1] == 1 for: 1 == 1
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.size() == 2 for: 2 == 2
+GeneratorsImpl.tests.cpp:<line number>: passed: gen[0] == 3 for: 3 == 3
+GeneratorsImpl.tests.cpp:<line number>: passed: gen[1] == 1 for: 1 == 1
+GeneratorsImpl.tests.cpp:<line number>: passed: base->size() == 4 for: 4 == 4
+GeneratorsImpl.tests.cpp:<line number>: passed: typed for: 0x<hex digits>
+GeneratorsImpl.tests.cpp:<line number>: passed: typed->size() == 4 for: 4 == 4
+GeneratorsImpl.tests.cpp:<line number>: passed: (*typed)[0] == 7 for: 7 == 7
+GeneratorsImpl.tests.cpp:<line number>: passed: (*typed)[3] == 11 for: 11 == 11
 Approx.tests.cpp:<line number>: passed: d >= Approx( 1.22 ) for: 1.23 >= Approx( 1.22 )
 Approx.tests.cpp:<line number>: passed: d >= Approx( 1.23 ) for: 1.23 >= Approx( 1.23 )
 Approx.tests.cpp:<line number>: passed: !(d >= Approx( 1.24 )) for: !(1.23 >= Approx( 1.24 ))
@@ -520,7 +668,6 @@ CmdLine.tests.cpp:<line number>: passed: spec.matches( tcA ) == false for: false
 CmdLine.tests.cpp:<line number>: passed: spec.matches( tcB ) == false for: false == false
 CmdLine.tests.cpp:<line number>: passed: spec.matches( tcC ) == false for: false == false
 CmdLine.tests.cpp:<line number>: passed: spec.matches( tcD ) == true for: true == true
-Tricky.tests.cpp:<line number>: passed: (std::pair<int, int>( 1, 2 )) == aNicePair for: {?} == {?}
 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
@@ -593,6 +740,7 @@ Decomposition.tests.cpp:<line number>: failed: truthy(false) for: Hey, its truth
 Matchers.tests.cpp:<line number>: failed: testStringForMatching(), Matches("this STRING contains 'abc' as a substring") for: "this string contains 'abc' as a substring" matches "this STRING contains 'abc' as a substring" case sensitively
 Matchers.tests.cpp:<line number>: failed: testStringForMatching(), Matches("contains 'abc' as a substring") for: "this string contains 'abc' as a substring" matches "contains 'abc' as a substring" case sensitively
 Matchers.tests.cpp:<line number>: failed: testStringForMatching(), Matches("this string contains 'abc' as a") for: "this string contains 'abc' as a substring" matches "this string contains 'abc' as a" case sensitively
+Matchers.tests.cpp:<line number>: passed: actual, !UnorderedEquals(expected) for: { 'a', 'b' } not UnorderedEquals: { 'c', 'b' }
 Message.tests.cpp:<line number>: passed: with 1 message: 'this is a success'
 Message.tests.cpp:<line number>: passed:
 BDD.tests.cpp:<line number>: passed: before == 0 for: 0 == 0
@@ -614,6 +762,8 @@ A string sent to stderr via clog
 Approx.tests.cpp:<line number>: passed: d == Approx( 1.23 ) for: 1.23 == Approx( 1.23 )
 Approx.tests.cpp:<line number>: passed: d != Approx( 1.22 ) for: 1.23 != Approx( 1.22 )
 Approx.tests.cpp:<line number>: passed: d != Approx( 1.24 ) for: 1.23 != Approx( 1.24 )
+Approx.tests.cpp:<line number>: passed: d == 1.23_a for: 1.23 == Approx( 1.23 )
+Approx.tests.cpp:<line number>: passed: d != 1.22_a for: 1.23 != Approx( 1.22 )
 Approx.tests.cpp:<line number>: passed: Approx( d ) == 1.23 for: Approx( 1.23 ) == 1.23
 Approx.tests.cpp:<line number>: passed: Approx( d ) != 1.22 for: Approx( 1.23 ) != 1.22
 Approx.tests.cpp:<line number>: passed: Approx( d ) != 1.24 for: Approx( 1.23 ) != 1.24
@@ -988,6 +1138,15 @@ Misc.tests.cpp:<line number>: passed: l == std::numeric_limits<long long>::max()
 ==
 9223372036854775807 (0x<hex digits>)
 Misc.tests.cpp:<line number>: failed: b > a for: 0 > 1
+Misc.tests.cpp:<line number>: failed: b > a for: 1 > 1
+Misc.tests.cpp:<line number>: passed: b > a for: 2 > 1
+Misc.tests.cpp:<line number>: passed: b > a for: 3 > 1
+Misc.tests.cpp:<line number>: passed: b > a for: 4 > 1
+Misc.tests.cpp:<line number>: passed: b > a for: 5 > 1
+Misc.tests.cpp:<line number>: passed: b > a for: 6 > 1
+Misc.tests.cpp:<line number>: passed: b > a for: 7 > 1
+Misc.tests.cpp:<line number>: passed: b > a for: 8 > 1
+Misc.tests.cpp:<line number>: passed: b > a for: 9 > 1
 Misc.tests.cpp:<line number>: failed: ( fib[i] % 2 ) == 0 for: 1 == 0 with 1 message: 'Testing if fib[0] (1) is even'
 Misc.tests.cpp:<line number>: failed: ( fib[i] % 2 ) == 0 for: 1 == 0 with 1 message: 'Testing if fib[1] (1) is even'
 Misc.tests.cpp:<line number>: passed: ( fib[i] % 2 ) == 0 for: 0 == 0 with 1 message: 'Testing if fib[2] (2) is even'
@@ -1077,6 +1236,10 @@ ToStringWhich.tests.cpp:<line number>: passed: ::Catch::Detail::stringify( v ) =
 ToStringWhich.tests.cpp:<line number>: passed: ::Catch::Detail::stringify( v ) == "{ operator<<( has_operator ) }" for: "{ operator<<( has_operator ) }"
 ==
 "{ operator<<( has_operator ) }"
+Generators.tests.cpp:<line number>: passed: data.str.size() == data.len for: 3 == 3
+Generators.tests.cpp:<line number>: passed: data.str.size() == data.len for: 3 == 3
+Generators.tests.cpp:<line number>: passed: data.str.size() == data.len for: 5 == 5
+Generators.tests.cpp:<line number>: passed: data.str.size() == data.len for: 4 == 4
 Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'Why would you throw a std::string?'
 Misc.tests.cpp:<line number>: passed: result == "/"wide load/"" for: ""wide load"" == ""wide load""
 Misc.tests.cpp:<line number>: passed: result == "/"wide load/"" for: ""wide load"" == ""wide load""
@@ -1144,5 +1307,5 @@ Misc.tests.cpp:<line number>: passed: v.size() == 5 for: 5 == 5
 Misc.tests.cpp:<line number>: passed: v.capacity() >= 5 for: 5 >= 5
 Misc.tests.cpp:<line number>: passed:
 Misc.tests.cpp:<line number>: passed:
-Failed 62 test cases, failed 121 assertions.
+Failed 62 test cases, failed 122 assertions.
 
diff --git a/packages/Catch2/projects/SelfTest/Baselines/console.std.approved.txt b/packages/Catch2/projects/SelfTest/Baselines/console.std.approved.txt
index 1992fb9fc..24755c802 100644
--- a/packages/Catch2/projects/SelfTest/Baselines/console.std.approved.txt
+++ b/packages/Catch2/projects/SelfTest/Baselines/console.std.approved.txt
@@ -968,7 +968,7 @@ explicitly with message:
 
 -------------------------------------------------------------------------------
 looped SECTION tests
-  s1
+  b is currently: 0
 -------------------------------------------------------------------------------
 Misc.tests.cpp:<line number>
 ...............................................................................
@@ -978,6 +978,18 @@ Misc.tests.cpp:<line number>: FAILED:
 with expansion:
   0 > 1
 
+-------------------------------------------------------------------------------
+looped SECTION tests
+  b is currently: 1
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: FAILED:
+  CHECK( b > a )
+with expansion:
+  1 > 1
+
 -------------------------------------------------------------------------------
 looped tests
 -------------------------------------------------------------------------------
@@ -1028,8 +1040,8 @@ with message:
 
 -------------------------------------------------------------------------------
 more nested SECTION tests
-  s1
-  s2
+  doesn't equal
+  equal
 -------------------------------------------------------------------------------
 Misc.tests.cpp:<line number>
 ...............................................................................
@@ -1084,6 +1096,6 @@ due to unexpected exception with message:
   Why would you throw a std::string?
 
 ===============================================================================
-test cases:  208 | 155 passed |  49 failed |  4 failed as expected
-assertions: 1065 | 937 passed | 107 failed | 21 failed as expected
+test cases:  213 |  160 passed |  49 failed |  4 failed as expected
+assertions: 1228 | 1099 passed | 108 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 047c71637..27fa5c59d 100644
--- a/packages/Catch2/projects/SelfTest/Baselines/console.sw.approved.txt
+++ b/packages/Catch2/projects/SelfTest/Baselines/console.sw.approved.txt
@@ -490,1047 +490,2289 @@ with expansion:
   !false
 
 -------------------------------------------------------------------------------
-A METHOD_AS_TEST_CASE based test run that fails
+10x10 ints
 -------------------------------------------------------------------------------
-Class.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Class.tests.cpp:<line number>: FAILED:
-  REQUIRE( s == "world" )
+Generators.tests.cpp:<line number>:
+PASSED:
+  CHECK( x < y )
 with expansion:
-  "hello" == "world"
+  1 < 101
 
 -------------------------------------------------------------------------------
-A METHOD_AS_TEST_CASE based test run that succeeds
+10x10 ints
 -------------------------------------------------------------------------------
-Class.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Class.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( s == "hello" )
+  CHECK( x < y )
 with expansion:
-  "hello" == "hello"
+  1 < 102
 
 -------------------------------------------------------------------------------
-A TEST_CASE_METHOD based test run that fails
+10x10 ints
 -------------------------------------------------------------------------------
-Class.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Class.tests.cpp:<line number>: FAILED:
-  REQUIRE( m_a == 2 )
+Generators.tests.cpp:<line number>:
+PASSED:
+  CHECK( x < y )
 with expansion:
-  1 == 2
+  1 < 103
 
 -------------------------------------------------------------------------------
-A TEST_CASE_METHOD based test run that succeeds
+10x10 ints
 -------------------------------------------------------------------------------
-Class.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Class.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( m_a == 1 )
+  CHECK( x < y )
 with expansion:
-  1 == 1
+  1 < 104
 
 -------------------------------------------------------------------------------
-A couple of nested sections followed by a failure
-  Outer
-  Inner
+10x10 ints
 -------------------------------------------------------------------------------
-Misc.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Misc.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-with message:
-  that's not flying - that's failing in style
+  CHECK( x < y )
+with expansion:
+  1 < 105
 
 -------------------------------------------------------------------------------
-A couple of nested sections followed by a failure
+10x10 ints
 -------------------------------------------------------------------------------
-Misc.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Misc.tests.cpp:<line number>: FAILED:
-explicitly with message:
-  to infinity and beyond
+Generators.tests.cpp:<line number>:
+PASSED:
+  CHECK( x < y )
+with expansion:
+  1 < 106
 
 -------------------------------------------------------------------------------
-A failing expression with a non streamable type is still captured
+10x10 ints
 -------------------------------------------------------------------------------
-Tricky.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Tricky.tests.cpp:<line number>: FAILED:
-  CHECK( &o1 == &o2 )
-with expansion:
-  0x<hex digits> == 0x<hex digits>
-
-Tricky.tests.cpp:<line number>: FAILED:
-  CHECK( o1 == o2 )
+Generators.tests.cpp:<line number>:
+PASSED:
+  CHECK( x < y )
 with expansion:
-  {?} == {?}
+  1 < 107
 
 -------------------------------------------------------------------------------
-Absolute margin
+10x10 ints
 -------------------------------------------------------------------------------
-Approx.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( 104.0 != Approx(100.0) )
+  CHECK( x < y )
 with expansion:
-  104.0 != Approx( 100.0 )
+  1 < 108
 
-Approx.tests.cpp:<line number>:
-PASSED:
-  REQUIRE( 104.0 == Approx(100.0).margin(5) )
-with expansion:
-  104.0 == Approx( 100.0 )
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( 104.0 == Approx(100.0).margin(4) )
+  CHECK( x < y )
 with expansion:
-  104.0 == Approx( 100.0 )
+  1 < 109
 
-Approx.tests.cpp:<line number>:
-PASSED:
-  REQUIRE( 104.0 != Approx(100.0).margin(3) )
-with expansion:
-  104.0 != Approx( 100.0 )
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( 100.3 != Approx(100.0) )
+  CHECK( x < y )
 with expansion:
-  100.3 != Approx( 100.0 )
+  1 < 110
 
-Approx.tests.cpp:<line number>:
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( 100.3 == Approx(100.0).margin(0.5) )
+  CHECK( x < y )
 with expansion:
-  100.3 == Approx( 100.0 )
+  2 < 101
 
 -------------------------------------------------------------------------------
-An empty test with no assertions
+10x10 ints
 -------------------------------------------------------------------------------
-Misc.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-
-No assertions in test case 'An empty test with no assertions'
+Generators.tests.cpp:<line number>:
+PASSED:
+  CHECK( x < y )
+with expansion:
+  2 < 102
 
 -------------------------------------------------------------------------------
-An expression with side-effects should only be evaluated once
+10x10 ints
 -------------------------------------------------------------------------------
-Tricky.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Tricky.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( i++ == 7 )
+  CHECK( x < y )
 with expansion:
-  7 == 7
+  2 < 103
 
-Tricky.tests.cpp:<line number>:
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( i++ == 8 )
+  CHECK( x < y )
 with expansion:
-  8 == 8
+  2 < 104
 
 -------------------------------------------------------------------------------
-An unchecked exception reports the line of the last assertion
+10x10 ints
 -------------------------------------------------------------------------------
-Exception.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Exception.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  CHECK( 1 == 1 )
-
-Exception.tests.cpp:<line number>: FAILED:
-  {Unknown expression after the reported line}
-due to unexpected exception with message:
-  unexpected exception
+  CHECK( x < y )
+with expansion:
+  2 < 105
 
 -------------------------------------------------------------------------------
-Anonymous test case 1
+10x10 ints
 -------------------------------------------------------------------------------
-VariadicMacros.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-VariadicMacros.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-with message:
-  anonymous test case
+  CHECK( x < y )
+with expansion:
+  2 < 106
 
 -------------------------------------------------------------------------------
-Approx setters validate their arguments
+10x10 ints
 -------------------------------------------------------------------------------
-Approx.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_NOTHROW( Approx(0).margin(0) )
+  CHECK( x < y )
+with expansion:
+  2 < 107
 
-Approx.tests.cpp:<line number>:
-PASSED:
-  REQUIRE_NOTHROW( Approx(0).margin(1234656) )
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THROWS_AS( Approx(0).margin(-2), std::domain_error )
+  CHECK( x < y )
+with expansion:
+  2 < 108
 
-Approx.tests.cpp:<line number>:
-PASSED:
-  REQUIRE_NOTHROW( Approx(0).epsilon(0) )
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_NOTHROW( Approx(0).epsilon(1) )
+  CHECK( x < y )
+with expansion:
+  2 < 109
 
-Approx.tests.cpp:<line number>:
-PASSED:
-  REQUIRE_THROWS_AS( Approx(0).epsilon(-0.001), std::domain_error )
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THROWS_AS( Approx(0).epsilon(1.0001), std::domain_error )
+  CHECK( x < y )
+with expansion:
+  2 < 110
 
 -------------------------------------------------------------------------------
-Approx with exactly-representable margin
+10x10 ints
 -------------------------------------------------------------------------------
-Approx.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  CHECK( 0.25f == Approx(0.0f).margin(0.25f) )
+  CHECK( x < y )
 with expansion:
-  0.25f == Approx( 0.0 )
+  3 < 101
 
-Approx.tests.cpp:<line number>:
-PASSED:
-  CHECK( 0.0f == Approx(0.25f).margin(0.25f) )
-with expansion:
-  0.0f == Approx( 0.25 )
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  CHECK( 0.5f == Approx(0.25f).margin(0.25f) )
+  CHECK( x < y )
 with expansion:
-  0.5f == Approx( 0.25 )
+  3 < 102
 
-Approx.tests.cpp:<line number>:
-PASSED:
-  CHECK( 245.0f == Approx(245.25f).margin(0.25f) )
-with expansion:
-  245.0f == Approx( 245.25 )
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  CHECK( 245.5f == Approx(245.25f).margin(0.25f) )
+  CHECK( x < y )
 with expansion:
-  245.5f == Approx( 245.25 )
+  3 < 103
 
 -------------------------------------------------------------------------------
-Approximate PI
+10x10 ints
 -------------------------------------------------------------------------------
-Approx.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( divide( 22, 7 ) == Approx( 3.141 ).epsilon( 0.001 ) )
+  CHECK( x < y )
 with expansion:
-  3.1428571429 == Approx( 3.141 )
+  3 < 104
 
-Approx.tests.cpp:<line number>:
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( divide( 22, 7 ) != Approx( 3.141 ).epsilon( 0.0001 ) )
+  CHECK( x < y )
 with expansion:
-  3.1428571429 != Approx( 3.141 )
+  3 < 105
 
 -------------------------------------------------------------------------------
-Approximate comparisons with different epsilons
+10x10 ints
 -------------------------------------------------------------------------------
-Approx.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( d != Approx( 1.231 ) )
+  CHECK( x < y )
 with expansion:
-  1.23 != Approx( 1.231 )
+  3 < 106
 
-Approx.tests.cpp:<line number>:
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( d == Approx( 1.231 ).epsilon( 0.1 ) )
+  CHECK( x < y )
 with expansion:
-  1.23 == Approx( 1.231 )
+  3 < 107
 
 -------------------------------------------------------------------------------
-Approximate comparisons with floats
+10x10 ints
 -------------------------------------------------------------------------------
-Approx.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( 1.23f == Approx( 1.23f ) )
+  CHECK( x < y )
 with expansion:
-  1.23f == Approx( 1.2300000191 )
+  3 < 108
 
-Approx.tests.cpp:<line number>:
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( 0.0f == Approx( 0.0f ) )
+  CHECK( x < y )
 with expansion:
-  0.0f == Approx( 0.0 )
+  3 < 109
 
 -------------------------------------------------------------------------------
-Approximate comparisons with ints
+10x10 ints
 -------------------------------------------------------------------------------
-Approx.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( 1 == Approx( 1 ) )
+  CHECK( x < y )
 with expansion:
-  1 == Approx( 1.0 )
+  3 < 110
 
-Approx.tests.cpp:<line number>:
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( 0 == Approx( 0 ) )
+  CHECK( x < y )
 with expansion:
-  0 == Approx( 0.0 )
+  4 < 101
 
 -------------------------------------------------------------------------------
-Approximate comparisons with mixed numeric types
+10x10 ints
 -------------------------------------------------------------------------------
-Approx.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( 1.0f == Approx( 1 ) )
+  CHECK( x < y )
 with expansion:
-  1.0f == Approx( 1.0 )
+  4 < 102
 
-Approx.tests.cpp:<line number>:
-PASSED:
-  REQUIRE( 0 == Approx( dZero) )
-with expansion:
-  0 == Approx( 0.0 )
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( 0 == Approx( dSmall ).margin( 0.001 ) )
+  CHECK( x < y )
 with expansion:
-  0 == Approx( 0.00001 )
+  4 < 103
 
-Approx.tests.cpp:<line number>:
-PASSED:
-  REQUIRE( 1.234f == Approx( dMedium ) )
-with expansion:
-  1.234f == Approx( 1.234 )
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( dMedium == Approx( 1.234f ) )
+  CHECK( x < y )
 with expansion:
-  1.234 == Approx( 1.2339999676 )
+  4 < 104
 
 -------------------------------------------------------------------------------
-Arbitrary predicate matcher
-  Function pointer
+10x10 ints
 -------------------------------------------------------------------------------
-Matchers.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Matchers.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( 1, Predicate<int>(alwaysTrue, "always true") )
+  CHECK( x < y )
 with expansion:
-  1 matches predicate: "always true"
+  4 < 105
 
-Matchers.tests.cpp:<line number>:
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( 1, !Predicate<int>(alwaysFalse, "always false") )
+  CHECK( x < y )
 with expansion:
-  1 not matches predicate: "always false"
+  4 < 106
 
 -------------------------------------------------------------------------------
-Arbitrary predicate matcher
-  Lambdas + different type
+10x10 ints
 -------------------------------------------------------------------------------
-Matchers.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Matchers.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( "Hello olleH", Predicate<std::string>( [] (std::string const& str) -> bool { return str.front() == str.back(); }, "First and last character should be equal") )
+  CHECK( x < y )
 with expansion:
-  "Hello olleH" matches predicate: "First and last character should be equal"
+  4 < 107
 
-Matchers.tests.cpp:<line number>:
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( "This wouldn't pass", !Predicate<std::string>( [] (std::string const& str) -> bool { return str.front() == str.back(); } ) )
+  CHECK( x < y )
 with expansion:
-  "This wouldn't pass" not matches undescribed predicate
+  4 < 108
 
 -------------------------------------------------------------------------------
-Assertions then sections
+10x10 ints
 -------------------------------------------------------------------------------
-Tricky.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Tricky.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( true )
+  CHECK( x < y )
+with expansion:
+  4 < 109
 
 -------------------------------------------------------------------------------
-Assertions then sections
-  A section
+10x10 ints
 -------------------------------------------------------------------------------
-Tricky.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Tricky.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( true )
+  CHECK( x < y )
+with expansion:
+  4 < 110
 
 -------------------------------------------------------------------------------
-Assertions then sections
-  A section
-  Another section
+10x10 ints
 -------------------------------------------------------------------------------
-Tricky.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Tricky.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( true )
+  CHECK( x < y )
+with expansion:
+  5 < 101
 
 -------------------------------------------------------------------------------
-Assertions then sections
+10x10 ints
 -------------------------------------------------------------------------------
-Tricky.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Tricky.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( true )
+  CHECK( x < y )
+with expansion:
+  5 < 102
 
 -------------------------------------------------------------------------------
-Assertions then sections
-  A section
+10x10 ints
 -------------------------------------------------------------------------------
-Tricky.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Tricky.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( true )
+  CHECK( x < y )
+with expansion:
+  5 < 103
 
 -------------------------------------------------------------------------------
-Assertions then sections
-  A section
-  Another other section
+10x10 ints
 -------------------------------------------------------------------------------
-Tricky.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Tricky.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( true )
+  CHECK( x < y )
+with expansion:
+  5 < 104
 
 -------------------------------------------------------------------------------
-Assorted miscellaneous tests
+10x10 ints
 -------------------------------------------------------------------------------
-Approx.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( INFINITY == Approx(INFINITY) )
+  CHECK( x < y )
 with expansion:
-  inff == Approx( inf )
+  5 < 105
 
-Approx.tests.cpp:<line number>:
-PASSED:
-  REQUIRE( NAN != Approx(NAN) )
-with expansion:
-  nanf != Approx( nan )
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_FALSE( NAN == Approx(NAN) )
+  CHECK( x < y )
 with expansion:
-  !(nanf == Approx( nan ))
+  5 < 106
 
 -------------------------------------------------------------------------------
-Bitfields can be captured (#1027)
+10x10 ints
 -------------------------------------------------------------------------------
-Tricky.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Tricky.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( y.v == 0 )
+  CHECK( x < y )
 with expansion:
-  0 == 0
+  5 < 107
 
-Tricky.tests.cpp:<line number>:
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( 0 == y.v )
+  CHECK( x < y )
 with expansion:
-  0 == 0
+  5 < 108
 
 -------------------------------------------------------------------------------
-Capture and info messages
-  Capture should stringify like assertions
+10x10 ints
 -------------------------------------------------------------------------------
-ToStringGeneral.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-ToStringGeneral.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( true )
-with message:
-  i := 2
+  CHECK( x < y )
+with expansion:
+  5 < 109
 
 -------------------------------------------------------------------------------
-Capture and info messages
-  Info should NOT stringify the way assertions do
+10x10 ints
 -------------------------------------------------------------------------------
-ToStringGeneral.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-ToStringGeneral.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( true )
-with message:
-  3
+  CHECK( x < y )
+with expansion:
+  5 < 110
 
 -------------------------------------------------------------------------------
-Character pretty printing
-  Specifically escaped
+10x10 ints
 -------------------------------------------------------------------------------
-ToStringGeneral.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-ToStringGeneral.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  CHECK( tab == '\t' )
+  CHECK( x < y )
 with expansion:
-  '\t' == '\t'
+  6 < 101
 
-ToStringGeneral.tests.cpp:<line number>:
-PASSED:
-  CHECK( newline == '\n' )
-with expansion:
-  '\n' == '\n'
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-ToStringGeneral.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  CHECK( carr_return == '\r' )
+  CHECK( x < y )
 with expansion:
-  '\r' == '\r'
+  6 < 102
 
-ToStringGeneral.tests.cpp:<line number>:
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
 PASSED:
-  CHECK( form_feed == '\f' )
+  CHECK( x < y )
 with expansion:
-  '\f' == '\f'
+  6 < 103
 
 -------------------------------------------------------------------------------
-Character pretty printing
-  General chars
+10x10 ints
 -------------------------------------------------------------------------------
-ToStringGeneral.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-ToStringGeneral.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  CHECK( space == ' ' )
+  CHECK( x < y )
 with expansion:
-  ' ' == ' '
+  6 < 104
 
-ToStringGeneral.tests.cpp:<line number>:
-PASSED:
-  REQUIRE( c == chars[i] )
-with expansion:
-  'a' == 'a'
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-ToStringGeneral.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( c == chars[i] )
+  CHECK( x < y )
 with expansion:
-  'z' == 'z'
+  6 < 105
 
-ToStringGeneral.tests.cpp:<line number>:
-PASSED:
-  REQUIRE( c == chars[i] )
-with expansion:
-  'A' == 'A'
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-ToStringGeneral.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( c == chars[i] )
+  CHECK( x < y )
 with expansion:
-  'Z' == 'Z'
+  6 < 106
 
 -------------------------------------------------------------------------------
-Character pretty printing
-  Low ASCII
+10x10 ints
 -------------------------------------------------------------------------------
-ToStringGeneral.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-ToStringGeneral.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  CHECK( null_terminator == '\0' )
+  CHECK( x < y )
 with expansion:
-  0 == 0
+  6 < 107
 
-ToStringGeneral.tests.cpp:<line number>:
-PASSED:
-  REQUIRE( c == i )
-with expansion:
-  2 == 2
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-ToStringGeneral.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( c == i )
+  CHECK( x < y )
 with expansion:
-  3 == 3
+  6 < 108
 
-ToStringGeneral.tests.cpp:<line number>:
-PASSED:
-  REQUIRE( c == i )
-with expansion:
-  4 == 4
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-ToStringGeneral.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( c == i )
+  CHECK( x < y )
 with expansion:
-  5 == 5
+  6 < 109
 
 -------------------------------------------------------------------------------
-Commas in various macros are allowed
+10x10 ints
 -------------------------------------------------------------------------------
-Tricky.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Tricky.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THROWS( std::vector<constructor_throws>{constructor_throws{}, constructor_throws{}} )
+  CHECK( x < y )
+with expansion:
+  6 < 110
 
-Tricky.tests.cpp:<line number>:
-PASSED:
-  CHECK_THROWS( std::vector<constructor_throws>{constructor_throws{}, constructor_throws{}} )
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Tricky.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_NOTHROW( std::vector<int>{1, 2, 3} == std::vector<int>{1, 2, 3} )
+  CHECK( x < y )
+with expansion:
+  7 < 101
 
-Tricky.tests.cpp:<line number>:
-PASSED:
-  CHECK_NOTHROW( std::vector<int>{1, 2, 3} == std::vector<int>{1, 2, 3} )
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Tricky.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( std::vector<int>{1, 2} == std::vector<int>{1, 2} )
+  CHECK( x < y )
 with expansion:
-  { 1, 2 } == { 1, 2 }
+  7 < 102
 
-Tricky.tests.cpp:<line number>:
-PASSED:
-  CHECK( std::vector<int>{1, 2} == std::vector<int>{1, 2} )
-with expansion:
-  { 1, 2 } == { 1, 2 }
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Tricky.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_FALSE( std::vector<int>{1, 2} == std::vector<int>{1, 2, 3} )
+  CHECK( x < y )
 with expansion:
-  !({ 1, 2 } == { 1, 2, 3 })
+  7 < 103
 
-Tricky.tests.cpp:<line number>:
-PASSED:
-  CHECK_FALSE( std::vector<int>{1, 2} == std::vector<int>{1, 2, 3} )
-with expansion:
-  !({ 1, 2 } == { 1, 2, 3 })
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Tricky.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  CHECK_NOFAIL( std::vector<int>{1, 2} == std::vector<int>{1, 2} )
+  CHECK( x < y )
 with expansion:
-  { 1, 2 } == { 1, 2 }
+  7 < 104
 
-Tricky.tests.cpp:<line number>:
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
 PASSED:
-  CHECKED_IF( std::vector<int>{1, 2} == std::vector<int>{1, 2} )
+  CHECK( x < y )
 with expansion:
-  { 1, 2 } == { 1, 2 }
+  7 < 105
 
-Tricky.tests.cpp:<line number>:
-PASSED:
-  REQUIRE( true )
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Tricky.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  CHECKED_ELSE( std::vector<int>{1, 2} == std::vector<int>{1, 2} )
+  CHECK( x < y )
 with expansion:
-  { 1, 2 } == { 1, 2 }
+  7 < 106
 
 -------------------------------------------------------------------------------
-Comparing function pointers
+10x10 ints
 -------------------------------------------------------------------------------
-Tricky.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Tricky.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( a )
+  CHECK( x < y )
 with expansion:
-  0x<hex digits>
+  7 < 107
 
-Tricky.tests.cpp:<line number>:
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( a == &foo )
+  CHECK( x < y )
 with expansion:
-  0x<hex digits> == 0x<hex digits>
+  7 < 108
 
 -------------------------------------------------------------------------------
-Comparison with explicitly convertible types
+10x10 ints
 -------------------------------------------------------------------------------
-Approx.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( td == Approx(10.0) )
+  CHECK( x < y )
 with expansion:
-  StrongDoubleTypedef(10) == Approx( 10.0 )
+  7 < 109
 
-Approx.tests.cpp:<line number>:
-PASSED:
-  REQUIRE( Approx(10.0) == td )
-with expansion:
-  Approx( 10.0 ) == StrongDoubleTypedef(10)
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( td != Approx(11.0) )
+  CHECK( x < y )
 with expansion:
-  StrongDoubleTypedef(10) != Approx( 11.0 )
+  7 < 110
 
-Approx.tests.cpp:<line number>:
-PASSED:
-  REQUIRE( Approx(11.0) != td )
-with expansion:
-  Approx( 11.0 ) != StrongDoubleTypedef(10)
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( td <= Approx(10.0) )
+  CHECK( x < y )
 with expansion:
-  StrongDoubleTypedef(10) <= Approx( 10.0 )
+  8 < 101
 
-Approx.tests.cpp:<line number>:
-PASSED:
-  REQUIRE( td <= Approx(11.0) )
-with expansion:
-  StrongDoubleTypedef(10) <= Approx( 11.0 )
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( Approx(10.0) <= td )
+  CHECK( x < y )
 with expansion:
-  Approx( 10.0 ) <= StrongDoubleTypedef(10)
+  8 < 102
 
-Approx.tests.cpp:<line number>:
-PASSED:
-  REQUIRE( Approx(9.0) <= td )
-with expansion:
-  Approx( 9.0 ) <= StrongDoubleTypedef(10)
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( td >= Approx(9.0) )
+  CHECK( x < y )
 with expansion:
-  StrongDoubleTypedef(10) >= Approx( 9.0 )
+  8 < 103
 
-Approx.tests.cpp:<line number>:
-PASSED:
-  REQUIRE( td >= Approx(td) )
-with expansion:
-  StrongDoubleTypedef(10) >= Approx( 10.0 )
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( Approx(td) >= td )
+  CHECK( x < y )
 with expansion:
-  Approx( 10.0 ) >= StrongDoubleTypedef(10)
+  8 < 104
 
-Approx.tests.cpp:<line number>:
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( Approx(11.0) >= td )
+  CHECK( x < y )
 with expansion:
-  Approx( 11.0 ) >= StrongDoubleTypedef(10)
+  8 < 105
 
 -------------------------------------------------------------------------------
-Comparisons between ints where one side is computed
+10x10 ints
 -------------------------------------------------------------------------------
-Condition.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Condition.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  CHECK( 54 == 6*9 )
+  CHECK( x < y )
 with expansion:
-  54 == 54
+  8 < 106
 
 -------------------------------------------------------------------------------
-Comparisons between unsigned ints and negative signed ints match c++ standard
-behaviour
+10x10 ints
 -------------------------------------------------------------------------------
-Condition.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Condition.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  CHECK( ( -1 > 2u ) )
+  CHECK( x < y )
 with expansion:
-  true
+  8 < 107
 
-Condition.tests.cpp:<line number>:
-PASSED:
-  CHECK( -1 > 2u )
-with expansion:
-  -1 > 2
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Condition.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  CHECK( ( 2u < -1 ) )
+  CHECK( x < y )
 with expansion:
-  true
+  8 < 108
 
-Condition.tests.cpp:<line number>:
-PASSED:
-  CHECK( 2u < -1 )
-with expansion:
-  2 < -1
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Condition.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  CHECK( ( minInt > 2u ) )
+  CHECK( x < y )
 with expansion:
-  true
+  8 < 109
 
-Condition.tests.cpp:<line number>:
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
 PASSED:
-  CHECK( minInt > 2u )
+  CHECK( x < y )
 with expansion:
-  -2147483648 > 2
+  8 < 110
 
 -------------------------------------------------------------------------------
-Comparisons with int literals don't warn when mixing signed/ unsigned
+10x10 ints
 -------------------------------------------------------------------------------
-Condition.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Condition.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( i == 1 )
+  CHECK( x < y )
 with expansion:
-  1 == 1
+  9 < 101
 
-Condition.tests.cpp:<line number>:
-PASSED:
-  REQUIRE( ui == 2 )
-with expansion:
-  2 == 2
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Condition.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( l == 3 )
+  CHECK( x < y )
 with expansion:
-  3 == 3
+  9 < 102
 
-Condition.tests.cpp:<line number>:
-PASSED:
-  REQUIRE( ul == 4 )
-with expansion:
-  4 == 4
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Condition.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( c == 5 )
+  CHECK( x < y )
 with expansion:
-  5 == 5
+  9 < 103
 
-Condition.tests.cpp:<line number>:
-PASSED:
-  REQUIRE( uc == 6 )
-with expansion:
-  6 == 6
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Condition.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( 1 == i )
+  CHECK( x < y )
 with expansion:
-  1 == 1
+  9 < 104
 
-Condition.tests.cpp:<line number>:
-PASSED:
-  REQUIRE( 2 == ui )
-with expansion:
-  2 == 2
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Condition.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( 3 == l )
+  CHECK( x < y )
 with expansion:
-  3 == 3
+  9 < 105
 
-Condition.tests.cpp:<line number>:
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( 4 == ul )
+  CHECK( x < y )
 with expansion:
-  4 == 4
+  9 < 106
 
-Condition.tests.cpp:<line number>:
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( 5 == c )
+  CHECK( x < y )
 with expansion:
-  5 == 5
+  9 < 107
 
-Condition.tests.cpp:<line number>:
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( 6 == uc )
+  CHECK( x < y )
 with expansion:
-  6 == 6
+  9 < 108
 
-Condition.tests.cpp:<line number>:
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( (std::numeric_limits<uint32_t>::max)() > ul )
+  CHECK( x < y )
 with expansion:
-  4294967295 (0x<hex digits>) > 4
+  9 < 109
 
 -------------------------------------------------------------------------------
-Contains string matcher
+10x10 ints
 -------------------------------------------------------------------------------
-Matchers.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Matchers.tests.cpp:<line number>: FAILED:
-  CHECK_THAT( testStringForMatching(), Contains("not there", Catch::CaseSensitive::No) )
+Generators.tests.cpp:<line number>:
+PASSED:
+  CHECK( x < y )
 with expansion:
-  "this string contains 'abc' as a substring" contains: "not there" (case
-  insensitive)
+  9 < 110
 
-Matchers.tests.cpp:<line number>: FAILED:
-  CHECK_THAT( testStringForMatching(), Contains("STRING") )
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
+PASSED:
+  CHECK( x < y )
 with expansion:
-  "this string contains 'abc' as a substring" contains: "STRING"
+  10 < 101
 
 -------------------------------------------------------------------------------
-Custom exceptions can be translated when testing for nothrow
+10x10 ints
 -------------------------------------------------------------------------------
-Exception.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Exception.tests.cpp:<line number>: FAILED:
-  REQUIRE_NOTHROW( throwCustom() )
-due to unexpected exception with message:
-  custom exception - not std
+Generators.tests.cpp:<line number>:
+PASSED:
+  CHECK( x < y )
+with expansion:
+  10 < 102
 
 -------------------------------------------------------------------------------
-Custom exceptions can be translated when testing for throwing as something else
+10x10 ints
 -------------------------------------------------------------------------------
-Exception.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Exception.tests.cpp:<line number>: FAILED:
-  REQUIRE_THROWS_AS( throwCustom(), std::exception )
-due to unexpected exception with message:
-  custom exception - not std
+Generators.tests.cpp:<line number>:
+PASSED:
+  CHECK( x < y )
+with expansion:
+  10 < 103
 
 -------------------------------------------------------------------------------
-Custom std-exceptions can be custom translated
+10x10 ints
 -------------------------------------------------------------------------------
-Exception.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Exception.tests.cpp:<line number>: FAILED:
-due to unexpected exception with message:
-  custom std exception
+Generators.tests.cpp:<line number>:
+PASSED:
+  CHECK( x < y )
+with expansion:
+  10 < 104
 
 -------------------------------------------------------------------------------
-Default scale is invisible to comparison
+10x10 ints
 -------------------------------------------------------------------------------
-Approx.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( 101.000001 != Approx(100).epsilon(0.01) )
+  CHECK( x < y )
 with expansion:
-  101.000001 != Approx( 100.0 )
+  10 < 105
 
-Approx.tests.cpp:<line number>:
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( std::pow(10, -5) != Approx(std::pow(10, -7)) )
+  CHECK( x < y )
 with expansion:
-  0.00001 != Approx( 0.0000001 )
+  10 < 106
 
 -------------------------------------------------------------------------------
-EndsWith string matcher
+10x10 ints
 -------------------------------------------------------------------------------
-Matchers.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Matchers.tests.cpp:<line number>: FAILED:
-  CHECK_THAT( testStringForMatching(), EndsWith("Substring") )
+Generators.tests.cpp:<line number>:
+PASSED:
+  CHECK( x < y )
 with expansion:
-  "this string contains 'abc' as a substring" ends with: "Substring"
+  10 < 107
 
-Matchers.tests.cpp:<line number>: FAILED:
-  CHECK_THAT( testStringForMatching(), EndsWith("this", Catch::CaseSensitive::No) )
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
+PASSED:
+  CHECK( x < y )
 with expansion:
-  "this string contains 'abc' as a substring" ends with: "this" (case
-  insensitive)
+  10 < 108
 
 -------------------------------------------------------------------------------
-Epsilon only applies to Approx's value
+10x10 ints
 -------------------------------------------------------------------------------
-Approx.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( 101.01 != Approx(100).epsilon(0.01) )
+  CHECK( x < y )
 with expansion:
-  101.01 != Approx( 100.0 )
+  10 < 109
 
 -------------------------------------------------------------------------------
-Equality checks that should fail
+10x10 ints
 -------------------------------------------------------------------------------
-Condition.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Condition.tests.cpp:<line number>: FAILED:
-  CHECK( data.int_seven == 6 )
+Generators.tests.cpp:<line number>:
+PASSED:
+  CHECK( x < y )
+with expansion:
+  10 < 110
+
+-------------------------------------------------------------------------------
+A METHOD_AS_TEST_CASE based test run that fails
+-------------------------------------------------------------------------------
+Class.tests.cpp:<line number>
+...............................................................................
+
+Class.tests.cpp:<line number>: FAILED:
+  REQUIRE( s == "world" )
+with expansion:
+  "hello" == "world"
+
+-------------------------------------------------------------------------------
+A METHOD_AS_TEST_CASE based test run that succeeds
+-------------------------------------------------------------------------------
+Class.tests.cpp:<line number>
+...............................................................................
+
+Class.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( s == "hello" )
+with expansion:
+  "hello" == "hello"
+
+-------------------------------------------------------------------------------
+A TEST_CASE_METHOD based test run that fails
+-------------------------------------------------------------------------------
+Class.tests.cpp:<line number>
+...............................................................................
+
+Class.tests.cpp:<line number>: FAILED:
+  REQUIRE( m_a == 2 )
+with expansion:
+  1 == 2
+
+-------------------------------------------------------------------------------
+A TEST_CASE_METHOD based test run that succeeds
+-------------------------------------------------------------------------------
+Class.tests.cpp:<line number>
+...............................................................................
+
+Class.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( m_a == 1 )
+with expansion:
+  1 == 1
+
+-------------------------------------------------------------------------------
+A comparison that uses literals instead of the normal constructor
+-------------------------------------------------------------------------------
+Approx.tests.cpp:<line number>
+...............................................................................
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( d == 1.23_a )
+with expansion:
+  1.23 == Approx( 1.23 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( d != 1.22_a )
+with expansion:
+  1.23 != Approx( 1.22 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( -d == -1.23_a )
+with expansion:
+  -1.23 == Approx( -1.23 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( d == 1.2_a .epsilon(.1) )
+with expansion:
+  1.23 == Approx( 1.2 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( d != 1.2_a .epsilon(.001) )
+with expansion:
+  1.23 != Approx( 1.2 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( d == 1_a .epsilon(.3) )
+with expansion:
+  1.23 == Approx( 1.0 )
+
+-------------------------------------------------------------------------------
+A couple of nested sections followed by a failure
+  Outer
+  Inner
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>:
+PASSED:
+with message:
+  that's not flying - that's failing in style
+
+-------------------------------------------------------------------------------
+A couple of nested sections followed by a failure
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: FAILED:
+explicitly with message:
+  to infinity and beyond
+
+-------------------------------------------------------------------------------
+A failing expression with a non streamable type is still captured
+-------------------------------------------------------------------------------
+Tricky.tests.cpp:<line number>
+...............................................................................
+
+Tricky.tests.cpp:<line number>: FAILED:
+  CHECK( &o1 == &o2 )
+with expansion:
+  0x<hex digits> == 0x<hex digits>
+
+Tricky.tests.cpp:<line number>: FAILED:
+  CHECK( o1 == o2 )
+with expansion:
+  {?} == {?}
+
+-------------------------------------------------------------------------------
+Absolute margin
+-------------------------------------------------------------------------------
+Approx.tests.cpp:<line number>
+...............................................................................
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( 104.0 != Approx(100.0) )
+with expansion:
+  104.0 != Approx( 100.0 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( 104.0 == Approx(100.0).margin(5) )
+with expansion:
+  104.0 == Approx( 100.0 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( 104.0 == Approx(100.0).margin(4) )
+with expansion:
+  104.0 == Approx( 100.0 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( 104.0 != Approx(100.0).margin(3) )
+with expansion:
+  104.0 != Approx( 100.0 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( 100.3 != Approx(100.0) )
+with expansion:
+  100.3 != Approx( 100.0 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( 100.3 == Approx(100.0).margin(0.5) )
+with expansion:
+  100.3 == Approx( 100.0 )
+
+-------------------------------------------------------------------------------
+An empty test with no assertions
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+
+No assertions in test case 'An empty test with no assertions'
+
+-------------------------------------------------------------------------------
+An expression with side-effects should only be evaluated once
+-------------------------------------------------------------------------------
+Tricky.tests.cpp:<line number>
+...............................................................................
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( i++ == 7 )
+with expansion:
+  7 == 7
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( i++ == 8 )
+with expansion:
+  8 == 8
+
+-------------------------------------------------------------------------------
+An unchecked exception reports the line of the last assertion
+-------------------------------------------------------------------------------
+Exception.tests.cpp:<line number>
+...............................................................................
+
+Exception.tests.cpp:<line number>:
+PASSED:
+  CHECK( 1 == 1 )
+
+Exception.tests.cpp:<line number>: FAILED:
+  {Unknown expression after the reported line}
+due to unexpected exception with message:
+  unexpected exception
+
+-------------------------------------------------------------------------------
+Anonymous test case 1
+-------------------------------------------------------------------------------
+VariadicMacros.tests.cpp:<line number>
+...............................................................................
+
+VariadicMacros.tests.cpp:<line number>:
+PASSED:
+with message:
+  anonymous test case
+
+-------------------------------------------------------------------------------
+Approx setters validate their arguments
+-------------------------------------------------------------------------------
+Approx.tests.cpp:<line number>
+...............................................................................
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_NOTHROW( Approx(0).margin(0) )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_NOTHROW( Approx(0).margin(1234656) )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THROWS_AS( Approx(0).margin(-2), std::domain_error )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_NOTHROW( Approx(0).epsilon(0) )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_NOTHROW( Approx(0).epsilon(1) )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THROWS_AS( Approx(0).epsilon(-0.001), std::domain_error )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THROWS_AS( Approx(0).epsilon(1.0001), std::domain_error )
+
+-------------------------------------------------------------------------------
+Approx with exactly-representable margin
+-------------------------------------------------------------------------------
+Approx.tests.cpp:<line number>
+...............................................................................
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  CHECK( 0.25f == Approx(0.0f).margin(0.25f) )
+with expansion:
+  0.25f == Approx( 0.0 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  CHECK( 0.0f == Approx(0.25f).margin(0.25f) )
+with expansion:
+  0.0f == Approx( 0.25 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  CHECK( 0.5f == Approx(0.25f).margin(0.25f) )
+with expansion:
+  0.5f == Approx( 0.25 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  CHECK( 245.0f == Approx(245.25f).margin(0.25f) )
+with expansion:
+  245.0f == Approx( 245.25 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  CHECK( 245.5f == Approx(245.25f).margin(0.25f) )
+with expansion:
+  245.5f == Approx( 245.25 )
+
+-------------------------------------------------------------------------------
+Approximate PI
+-------------------------------------------------------------------------------
+Approx.tests.cpp:<line number>
+...............................................................................
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( divide( 22, 7 ) == Approx( 3.141 ).epsilon( 0.001 ) )
+with expansion:
+  3.1428571429 == Approx( 3.141 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( divide( 22, 7 ) != Approx( 3.141 ).epsilon( 0.0001 ) )
+with expansion:
+  3.1428571429 != Approx( 3.141 )
+
+-------------------------------------------------------------------------------
+Approximate comparisons with different epsilons
+-------------------------------------------------------------------------------
+Approx.tests.cpp:<line number>
+...............................................................................
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( d != Approx( 1.231 ) )
+with expansion:
+  1.23 != Approx( 1.231 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( d == Approx( 1.231 ).epsilon( 0.1 ) )
+with expansion:
+  1.23 == Approx( 1.231 )
+
+-------------------------------------------------------------------------------
+Approximate comparisons with floats
+-------------------------------------------------------------------------------
+Approx.tests.cpp:<line number>
+...............................................................................
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( 1.23f == Approx( 1.23f ) )
+with expansion:
+  1.23f == Approx( 1.2300000191 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( 0.0f == Approx( 0.0f ) )
+with expansion:
+  0.0f == Approx( 0.0 )
+
+-------------------------------------------------------------------------------
+Approximate comparisons with ints
+-------------------------------------------------------------------------------
+Approx.tests.cpp:<line number>
+...............................................................................
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( 1 == Approx( 1 ) )
+with expansion:
+  1 == Approx( 1.0 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( 0 == Approx( 0 ) )
+with expansion:
+  0 == Approx( 0.0 )
+
+-------------------------------------------------------------------------------
+Approximate comparisons with mixed numeric types
+-------------------------------------------------------------------------------
+Approx.tests.cpp:<line number>
+...............................................................................
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( 1.0f == Approx( 1 ) )
+with expansion:
+  1.0f == Approx( 1.0 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( 0 == Approx( dZero) )
+with expansion:
+  0 == Approx( 0.0 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( 0 == Approx( dSmall ).margin( 0.001 ) )
+with expansion:
+  0 == Approx( 0.00001 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( 1.234f == Approx( dMedium ) )
+with expansion:
+  1.234f == Approx( 1.234 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( dMedium == Approx( 1.234f ) )
+with expansion:
+  1.234 == Approx( 1.2339999676 )
+
+-------------------------------------------------------------------------------
+Arbitrary predicate matcher
+  Function pointer
+-------------------------------------------------------------------------------
+Matchers.tests.cpp:<line number>
+...............................................................................
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( 1, Predicate<int>(alwaysTrue, "always true") )
+with expansion:
+  1 matches predicate: "always true"
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( 1, !Predicate<int>(alwaysFalse, "always false") )
+with expansion:
+  1 not matches predicate: "always false"
+
+-------------------------------------------------------------------------------
+Arbitrary predicate matcher
+  Lambdas + different type
+-------------------------------------------------------------------------------
+Matchers.tests.cpp:<line number>
+...............................................................................
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( "Hello olleH", Predicate<std::string>( [] (std::string const& str) -> bool { return str.front() == str.back(); }, "First and last character should be equal") )
+with expansion:
+  "Hello olleH" matches predicate: "First and last character should be equal"
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( "This wouldn't pass", !Predicate<std::string>( [] (std::string const& str) -> bool { return str.front() == str.back(); } ) )
+with expansion:
+  "This wouldn't pass" not matches undescribed predicate
+
+-------------------------------------------------------------------------------
+Assertions then sections
+-------------------------------------------------------------------------------
+Tricky.tests.cpp:<line number>
+...............................................................................
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( true )
+
+-------------------------------------------------------------------------------
+Assertions then sections
+  A section
+-------------------------------------------------------------------------------
+Tricky.tests.cpp:<line number>
+...............................................................................
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( true )
+
+-------------------------------------------------------------------------------
+Assertions then sections
+  A section
+  Another section
+-------------------------------------------------------------------------------
+Tricky.tests.cpp:<line number>
+...............................................................................
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( true )
+
+-------------------------------------------------------------------------------
+Assertions then sections
+-------------------------------------------------------------------------------
+Tricky.tests.cpp:<line number>
+...............................................................................
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( true )
+
+-------------------------------------------------------------------------------
+Assertions then sections
+  A section
+-------------------------------------------------------------------------------
+Tricky.tests.cpp:<line number>
+...............................................................................
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( true )
+
+-------------------------------------------------------------------------------
+Assertions then sections
+  A section
+  Another other section
+-------------------------------------------------------------------------------
+Tricky.tests.cpp:<line number>
+...............................................................................
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( true )
+
+-------------------------------------------------------------------------------
+Assorted miscellaneous tests
+-------------------------------------------------------------------------------
+Approx.tests.cpp:<line number>
+...............................................................................
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( INFINITY == Approx(INFINITY) )
+with expansion:
+  inff == Approx( inf )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( NAN != Approx(NAN) )
+with expansion:
+  nanf != Approx( nan )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_FALSE( NAN == Approx(NAN) )
+with expansion:
+  !(nanf == Approx( nan ))
+
+-------------------------------------------------------------------------------
+Bitfields can be captured (#1027)
+-------------------------------------------------------------------------------
+Tricky.tests.cpp:<line number>
+...............................................................................
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( y.v == 0 )
+with expansion:
+  0 == 0
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( 0 == y.v )
+with expansion:
+  0 == 0
+
+-------------------------------------------------------------------------------
+Capture and info messages
+  Capture should stringify like assertions
+-------------------------------------------------------------------------------
+ToStringGeneral.tests.cpp:<line number>
+...............................................................................
+
+ToStringGeneral.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( true )
+with message:
+  i := 2
+
+-------------------------------------------------------------------------------
+Capture and info messages
+  Info should NOT stringify the way assertions do
+-------------------------------------------------------------------------------
+ToStringGeneral.tests.cpp:<line number>
+...............................................................................
+
+ToStringGeneral.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( true )
+with message:
+  3
+
+-------------------------------------------------------------------------------
+Character pretty printing
+  Specifically escaped
+-------------------------------------------------------------------------------
+ToStringGeneral.tests.cpp:<line number>
+...............................................................................
+
+ToStringGeneral.tests.cpp:<line number>:
+PASSED:
+  CHECK( tab == '\t' )
+with expansion:
+  '\t' == '\t'
+
+ToStringGeneral.tests.cpp:<line number>:
+PASSED:
+  CHECK( newline == '\n' )
+with expansion:
+  '\n' == '\n'
+
+ToStringGeneral.tests.cpp:<line number>:
+PASSED:
+  CHECK( carr_return == '\r' )
+with expansion:
+  '\r' == '\r'
+
+ToStringGeneral.tests.cpp:<line number>:
+PASSED:
+  CHECK( form_feed == '\f' )
+with expansion:
+  '\f' == '\f'
+
+-------------------------------------------------------------------------------
+Character pretty printing
+  General chars
+-------------------------------------------------------------------------------
+ToStringGeneral.tests.cpp:<line number>
+...............................................................................
+
+ToStringGeneral.tests.cpp:<line number>:
+PASSED:
+  CHECK( space == ' ' )
+with expansion:
+  ' ' == ' '
+
+ToStringGeneral.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( c == chars[i] )
+with expansion:
+  'a' == 'a'
+
+ToStringGeneral.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( c == chars[i] )
+with expansion:
+  'z' == 'z'
+
+ToStringGeneral.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( c == chars[i] )
+with expansion:
+  'A' == 'A'
+
+ToStringGeneral.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( c == chars[i] )
+with expansion:
+  'Z' == 'Z'
+
+-------------------------------------------------------------------------------
+Character pretty printing
+  Low ASCII
+-------------------------------------------------------------------------------
+ToStringGeneral.tests.cpp:<line number>
+...............................................................................
+
+ToStringGeneral.tests.cpp:<line number>:
+PASSED:
+  CHECK( null_terminator == '\0' )
+with expansion:
+  0 == 0
+
+ToStringGeneral.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( c == i )
+with expansion:
+  2 == 2
+
+ToStringGeneral.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( c == i )
+with expansion:
+  3 == 3
+
+ToStringGeneral.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( c == i )
+with expansion:
+  4 == 4
+
+ToStringGeneral.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( c == i )
+with expansion:
+  5 == 5
+
+-------------------------------------------------------------------------------
+Commas in various macros are allowed
+-------------------------------------------------------------------------------
+Tricky.tests.cpp:<line number>
+...............................................................................
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THROWS( std::vector<constructor_throws>{constructor_throws{}, constructor_throws{}} )
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  CHECK_THROWS( std::vector<constructor_throws>{constructor_throws{}, constructor_throws{}} )
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_NOTHROW( std::vector<int>{1, 2, 3} == std::vector<int>{1, 2, 3} )
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  CHECK_NOTHROW( std::vector<int>{1, 2, 3} == std::vector<int>{1, 2, 3} )
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( std::vector<int>{1, 2} == std::vector<int>{1, 2} )
+with expansion:
+  { 1, 2 } == { 1, 2 }
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  CHECK( std::vector<int>{1, 2} == std::vector<int>{1, 2} )
+with expansion:
+  { 1, 2 } == { 1, 2 }
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_FALSE( std::vector<int>{1, 2} == std::vector<int>{1, 2, 3} )
+with expansion:
+  !({ 1, 2 } == { 1, 2, 3 })
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  CHECK_FALSE( std::vector<int>{1, 2} == std::vector<int>{1, 2, 3} )
+with expansion:
+  !({ 1, 2 } == { 1, 2, 3 })
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  CHECK_NOFAIL( std::vector<int>{1, 2} == std::vector<int>{1, 2} )
+with expansion:
+  { 1, 2 } == { 1, 2 }
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  CHECKED_IF( std::vector<int>{1, 2} == std::vector<int>{1, 2} )
+with expansion:
+  { 1, 2 } == { 1, 2 }
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( true )
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  CHECKED_ELSE( std::vector<int>{1, 2} == std::vector<int>{1, 2} )
+with expansion:
+  { 1, 2 } == { 1, 2 }
+
+-------------------------------------------------------------------------------
+Comparing function pointers
+-------------------------------------------------------------------------------
+Tricky.tests.cpp:<line number>
+...............................................................................
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( a )
+with expansion:
+  0x<hex digits>
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( a == &foo )
+with expansion:
+  0x<hex digits> == 0x<hex digits>
+
+-------------------------------------------------------------------------------
+Comparison with explicitly convertible types
+-------------------------------------------------------------------------------
+Approx.tests.cpp:<line number>
+...............................................................................
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( td == Approx(10.0) )
+with expansion:
+  StrongDoubleTypedef(10) == Approx( 10.0 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( Approx(10.0) == td )
+with expansion:
+  Approx( 10.0 ) == StrongDoubleTypedef(10)
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( td != Approx(11.0) )
+with expansion:
+  StrongDoubleTypedef(10) != Approx( 11.0 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( Approx(11.0) != td )
+with expansion:
+  Approx( 11.0 ) != StrongDoubleTypedef(10)
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( td <= Approx(10.0) )
+with expansion:
+  StrongDoubleTypedef(10) <= Approx( 10.0 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( td <= Approx(11.0) )
+with expansion:
+  StrongDoubleTypedef(10) <= Approx( 11.0 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( Approx(10.0) <= td )
+with expansion:
+  Approx( 10.0 ) <= StrongDoubleTypedef(10)
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( Approx(9.0) <= td )
+with expansion:
+  Approx( 9.0 ) <= StrongDoubleTypedef(10)
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( td >= Approx(9.0) )
+with expansion:
+  StrongDoubleTypedef(10) >= Approx( 9.0 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( td >= Approx(td) )
+with expansion:
+  StrongDoubleTypedef(10) >= Approx( 10.0 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( Approx(td) >= td )
+with expansion:
+  Approx( 10.0 ) >= StrongDoubleTypedef(10)
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( Approx(11.0) >= td )
+with expansion:
+  Approx( 11.0 ) >= StrongDoubleTypedef(10)
+
+-------------------------------------------------------------------------------
+Comparisons between ints where one side is computed
+-------------------------------------------------------------------------------
+Condition.tests.cpp:<line number>
+...............................................................................
+
+Condition.tests.cpp:<line number>:
+PASSED:
+  CHECK( 54 == 6*9 )
+with expansion:
+  54 == 54
+
+-------------------------------------------------------------------------------
+Comparisons between unsigned ints and negative signed ints match c++ standard
+behaviour
+-------------------------------------------------------------------------------
+Condition.tests.cpp:<line number>
+...............................................................................
+
+Condition.tests.cpp:<line number>:
+PASSED:
+  CHECK( ( -1 > 2u ) )
+with expansion:
+  true
+
+Condition.tests.cpp:<line number>:
+PASSED:
+  CHECK( -1 > 2u )
+with expansion:
+  -1 > 2
+
+Condition.tests.cpp:<line number>:
+PASSED:
+  CHECK( ( 2u < -1 ) )
+with expansion:
+  true
+
+Condition.tests.cpp:<line number>:
+PASSED:
+  CHECK( 2u < -1 )
+with expansion:
+  2 < -1
+
+Condition.tests.cpp:<line number>:
+PASSED:
+  CHECK( ( minInt > 2u ) )
+with expansion:
+  true
+
+Condition.tests.cpp:<line number>:
+PASSED:
+  CHECK( minInt > 2u )
+with expansion:
+  -2147483648 > 2
+
+-------------------------------------------------------------------------------
+Comparisons with int literals don't warn when mixing signed/ unsigned
+-------------------------------------------------------------------------------
+Condition.tests.cpp:<line number>
+...............................................................................
+
+Condition.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( i == 1 )
+with expansion:
+  1 == 1
+
+Condition.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( ui == 2 )
+with expansion:
+  2 == 2
+
+Condition.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( l == 3 )
+with expansion:
+  3 == 3
+
+Condition.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( ul == 4 )
+with expansion:
+  4 == 4
+
+Condition.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( c == 5 )
+with expansion:
+  5 == 5
+
+Condition.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( uc == 6 )
+with expansion:
+  6 == 6
+
+Condition.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( 1 == i )
+with expansion:
+  1 == 1
+
+Condition.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( 2 == ui )
+with expansion:
+  2 == 2
+
+Condition.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( 3 == l )
+with expansion:
+  3 == 3
+
+Condition.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( 4 == ul )
+with expansion:
+  4 == 4
+
+Condition.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( 5 == c )
+with expansion:
+  5 == 5
+
+Condition.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( 6 == uc )
+with expansion:
+  6 == 6
+
+Condition.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( (std::numeric_limits<uint32_t>::max)() > ul )
+with expansion:
+  4294967295 (0x<hex digits>) > 4
+
+-------------------------------------------------------------------------------
+Contains string matcher
+-------------------------------------------------------------------------------
+Matchers.tests.cpp:<line number>
+...............................................................................
+
+Matchers.tests.cpp:<line number>: 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>: FAILED:
+  CHECK_THAT( testStringForMatching(), Contains("STRING") )
+with expansion:
+  "this string contains 'abc' as a substring" contains: "STRING"
+
+-------------------------------------------------------------------------------
+Custom exceptions can be translated when testing for nothrow
+-------------------------------------------------------------------------------
+Exception.tests.cpp:<line number>
+...............................................................................
+
+Exception.tests.cpp:<line number>: FAILED:
+  REQUIRE_NOTHROW( throwCustom() )
+due to unexpected exception with message:
+  custom exception - not std
+
+-------------------------------------------------------------------------------
+Custom exceptions can be translated when testing for throwing as something else
+-------------------------------------------------------------------------------
+Exception.tests.cpp:<line number>
+...............................................................................
+
+Exception.tests.cpp:<line number>: FAILED:
+  REQUIRE_THROWS_AS( throwCustom(), std::exception )
+due to unexpected exception with message:
+  custom exception - not std
+
+-------------------------------------------------------------------------------
+Custom std-exceptions can be custom translated
+-------------------------------------------------------------------------------
+Exception.tests.cpp:<line number>
+...............................................................................
+
+Exception.tests.cpp:<line number>: FAILED:
+due to unexpected exception with message:
+  custom std exception
+
+-------------------------------------------------------------------------------
+Default scale is invisible to comparison
+-------------------------------------------------------------------------------
+Approx.tests.cpp:<line number>
+...............................................................................
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( 101.000001 != Approx(100).epsilon(0.01) )
+with expansion:
+  101.000001 != Approx( 100.0 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( std::pow(10, -5) != Approx(std::pow(10, -7)) )
+with expansion:
+  0.00001 != Approx( 0.0000001 )
+
+-------------------------------------------------------------------------------
+EndsWith string matcher
+-------------------------------------------------------------------------------
+Matchers.tests.cpp:<line number>
+...............................................................................
+
+Matchers.tests.cpp:<line number>: FAILED:
+  CHECK_THAT( testStringForMatching(), EndsWith("Substring") )
+with expansion:
+  "this string contains 'abc' as a substring" ends with: "Substring"
+
+Matchers.tests.cpp:<line number>: FAILED:
+  CHECK_THAT( testStringForMatching(), EndsWith("this", Catch::CaseSensitive::No) )
+with expansion:
+  "this string contains 'abc' as a substring" ends with: "this" (case
+  insensitive)
+
+-------------------------------------------------------------------------------
+Epsilon only applies to Approx's value
+-------------------------------------------------------------------------------
+Approx.tests.cpp:<line number>
+...............................................................................
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( 101.01 != Approx(100).epsilon(0.01) )
+with expansion:
+  101.01 != Approx( 100.0 )
+
+-------------------------------------------------------------------------------
+Equality checks that should fail
+-------------------------------------------------------------------------------
+Condition.tests.cpp:<line number>
+...............................................................................
+
+Condition.tests.cpp:<line number>: FAILED:
+  CHECK( data.int_seven == 6 )
 with expansion:
   7 == 6
 
@@ -1921,7 +3163,165 @@ with expansion:
   3628800 (0x<hex digits>) == 3628800 (0x<hex digits>)
 
 -------------------------------------------------------------------------------
-Floating point matchers: double
+Floating point matchers: double
+  Margin
+-------------------------------------------------------------------------------
+Matchers.tests.cpp:<line number>
+...............................................................................
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( 1., WithinAbs(1., 0) )
+with expansion:
+  1.0 is within 0.0 of 1.0
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( 0., WithinAbs(1., 1) )
+with expansion:
+  0.0 is within 1.0 of 1.0
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( 0., !WithinAbs(1., 0.99) )
+with expansion:
+  0.0 not is within 0.99 of 1.0
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( 0., !WithinAbs(1., 0.99) )
+with expansion:
+  0.0 not is within 0.99 of 1.0
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( NAN, !WithinAbs(NAN, 0) )
+with expansion:
+  nanf not is within 0.0 of nan
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( 11., !WithinAbs(10., 0.5) )
+with expansion:
+  11.0 not is within 0.5 of 10.0
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( 10., !WithinAbs(11., 0.5) )
+with expansion:
+  10.0 not is within 0.5 of 11.0
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( -10., WithinAbs(-10., 0.5) )
+with expansion:
+  -10.0 is within 0.5 of -10.0
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( -10., WithinAbs(-9.6, 0.5) )
+with expansion:
+  -10.0 is within 0.5 of -9.6
+
+-------------------------------------------------------------------------------
+Floating point matchers: double
+  ULPs
+-------------------------------------------------------------------------------
+Matchers.tests.cpp:<line number>
+...............................................................................
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( 1., WithinULP(1., 0) )
+with expansion:
+  1.0 is within 0 ULPs of 1.0
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( nextafter(1., 2.), WithinULP(1., 1) )
+with expansion:
+  1.0 is within 1 ULPs of 1.0
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( nextafter(1., 0.), WithinULP(1., 1) )
+with expansion:
+  1.0 is within 1 ULPs of 1.0
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( nextafter(1., 2.), !WithinULP(1., 0) )
+with expansion:
+  1.0 not is within 0 ULPs of 1.0
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( 1., WithinULP(1., 0) )
+with expansion:
+  1.0 is within 0 ULPs of 1.0
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( -0., WithinULP(0., 0) )
+with expansion:
+  -0.0 is within 0 ULPs of 0.0
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( NAN, !WithinULP(NAN, 123) )
+with expansion:
+  nanf not is within 123 ULPs of nanf
+
+-------------------------------------------------------------------------------
+Floating point matchers: double
+  Composed
+-------------------------------------------------------------------------------
+Matchers.tests.cpp:<line number>
+...............................................................................
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( 1., WithinAbs(1., 0.5) || WithinULP(2., 1) )
+with expansion:
+  1.0 ( is within 0.5 of 1.0 or is within 1 ULPs of 2.0 )
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( 1., WithinAbs(2., 0.5) || WithinULP(1., 0) )
+with expansion:
+  1.0 ( is within 0.5 of 2.0 or is within 0 ULPs of 1.0 )
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( NAN, !(WithinAbs(NAN, 100) || WithinULP(NAN, 123)) )
+with expansion:
+  nanf not ( is within 100.0 of nan or is within 123 ULPs of nanf )
+
+-------------------------------------------------------------------------------
+Floating point matchers: double
+  Constructor validation
+-------------------------------------------------------------------------------
+Matchers.tests.cpp:<line number>
+...............................................................................
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_NOTHROW( WithinAbs(1., 0.) )
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THROWS_AS( WithinAbs(1., -1.), std::domain_error )
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_NOTHROW( WithinULP(1., 0) )
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THROWS_AS( WithinULP(1., -1), std::domain_error )
+
+-------------------------------------------------------------------------------
+Floating point matchers: float
   Margin
 -------------------------------------------------------------------------------
 Matchers.tests.cpp:<line number>
@@ -1929,27 +3329,33 @@ Matchers.tests.cpp:<line number>
 
 Matchers.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( 1., WithinAbs(1., 0) )
+  REQUIRE_THAT( 1.f, WithinAbs(1.f, 0) )
 with expansion:
-  1.0 is within 0.0 of 1.0
+  1.0f is within 0.0 of 1.0
 
 Matchers.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( 0., WithinAbs(1., 1) )
+  REQUIRE_THAT( 0.f, WithinAbs(1.f, 1) )
 with expansion:
-  0.0 is within 1.0 of 1.0
+  0.0f is within 1.0 of 1.0
 
 Matchers.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( 0., !WithinAbs(1., 0.99) )
+  REQUIRE_THAT( 0.f, !WithinAbs(1.f, 0.99f) )
 with expansion:
-  0.0 not is within 0.99 of 1.0
+  0.0f not is within 0.9900000095 of 1.0
 
 Matchers.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( 0., !WithinAbs(1., 0.99) )
+  REQUIRE_THAT( 0.f, !WithinAbs(1.f, 0.99f) )
 with expansion:
-  0.0 not is within 0.99 of 1.0
+  0.0f not is within 0.9900000095 of 1.0
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( 0.f, WithinAbs(-0.f, 0) )
+with expansion:
+  0.0f is within 0.0 of -0.0
 
 Matchers.tests.cpp:<line number>:
 PASSED:
@@ -1959,30 +3365,30 @@ with expansion:
 
 Matchers.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( 11., !WithinAbs(10., 0.5) )
+  REQUIRE_THAT( 11.f, !WithinAbs(10.f, 0.5f) )
 with expansion:
-  11.0 not is within 0.5 of 10.0
+  11.0f not is within 0.5 of 10.0
 
 Matchers.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( 10., !WithinAbs(11., 0.5) )
+  REQUIRE_THAT( 10.f, !WithinAbs(11.f, 0.5f) )
 with expansion:
-  10.0 not is within 0.5 of 11.0
+  10.0f not is within 0.5 of 11.0
 
 Matchers.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( -10., WithinAbs(-10., 0.5) )
+  REQUIRE_THAT( -10.f, WithinAbs(-10.f, 0.5f) )
 with expansion:
-  -10.0 is within 0.5 of -10.0
+  -10.0f is within 0.5 of -10.0
 
 Matchers.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( -10., WithinAbs(-9.6, 0.5) )
+  REQUIRE_THAT( -10.f, WithinAbs(-9.6f, 0.5f) )
 with expansion:
-  -10.0 is within 0.5 of -9.6
+  -10.0f is within 0.5 of -9.6000003815
 
 -------------------------------------------------------------------------------
-Floating point matchers: double
+Floating point matchers: float
   ULPs
 -------------------------------------------------------------------------------
 Matchers.tests.cpp:<line number>
@@ -1990,39 +3396,39 @@ Matchers.tests.cpp:<line number>
 
 Matchers.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( 1., WithinULP(1., 0) )
+  REQUIRE_THAT( 1.f, WithinULP(1.f, 0) )
 with expansion:
-  1.0 is within 0 ULPs of 1.0
+  1.0f is within 0 ULPs of 1.0f
 
 Matchers.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( nextafter(1., 2.), WithinULP(1., 1) )
+  REQUIRE_THAT( nextafter(1.f, 2.f), WithinULP(1.f, 1) )
 with expansion:
-  1.0 is within 1 ULPs of 1.0
+  1.0f is within 1 ULPs of 1.0f
 
 Matchers.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( nextafter(1., 0.), WithinULP(1., 1) )
+  REQUIRE_THAT( nextafter(1.f, 0.f), WithinULP(1.f, 1) )
 with expansion:
-  1.0 is within 1 ULPs of 1.0
+  1.0f is within 1 ULPs of 1.0f
 
 Matchers.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( nextafter(1., 2.), !WithinULP(1., 0) )
+  REQUIRE_THAT( nextafter(1.f, 2.f), !WithinULP(1.f, 0) )
 with expansion:
-  1.0 not is within 0 ULPs of 1.0
+  1.0f not is within 0 ULPs of 1.0f
 
 Matchers.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( 1., WithinULP(1., 0) )
+  REQUIRE_THAT( 1.f, WithinULP(1.f, 0) )
 with expansion:
-  1.0 is within 0 ULPs of 1.0
+  1.0f is within 0 ULPs of 1.0f
 
 Matchers.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( -0., WithinULP(0., 0) )
+  REQUIRE_THAT( -0.f, WithinULP(0.f, 0) )
 with expansion:
-  -0.0 is within 0 ULPs of 0.0
+  -0.0f is within 0 ULPs of 0.0f
 
 Matchers.tests.cpp:<line number>:
 PASSED:
@@ -2031,7 +3437,7 @@ with expansion:
   nanf not is within 123 ULPs of nanf
 
 -------------------------------------------------------------------------------
-Floating point matchers: double
+Floating point matchers: float
   Composed
 -------------------------------------------------------------------------------
 Matchers.tests.cpp:<line number>
@@ -2039,15 +3445,15 @@ Matchers.tests.cpp:<line number>
 
 Matchers.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( 1., WithinAbs(1., 0.5) || WithinULP(2., 1) )
+  REQUIRE_THAT( 1.f, WithinAbs(1.f, 0.5) || WithinULP(1.f, 1) )
 with expansion:
-  1.0 ( is within 0.5 of 1.0 or is within 1 ULPs of 2.0 )
+  1.0f ( is within 0.5 of 1.0 or is within 1 ULPs of 1.0f )
 
 Matchers.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( 1., WithinAbs(2., 0.5) || WithinULP(1., 0) )
+  REQUIRE_THAT( 1.f, WithinAbs(2.f, 0.5) || WithinULP(1.f, 0) )
 with expansion:
-  1.0 ( is within 0.5 of 2.0 or is within 0 ULPs of 1.0 )
+  1.0f ( is within 0.5 of 2.0 or is within 0 ULPs of 1.0f )
 
 Matchers.tests.cpp:<line number>:
 PASSED:
@@ -2056,7 +3462,7 @@ with expansion:
   nanf not ( is within 100.0 of nan or is within 123 ULPs of nanf )
 
 -------------------------------------------------------------------------------
-Floating point matchers: double
+Floating point matchers: float
   Constructor validation
 -------------------------------------------------------------------------------
 Matchers.tests.cpp:<line number>
@@ -2064,183 +3470,439 @@ Matchers.tests.cpp:<line number>
 
 Matchers.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_NOTHROW( WithinAbs(1., 0.) )
+  REQUIRE_NOTHROW( WithinAbs(1.f, 0.f) )
 
 Matchers.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THROWS_AS( WithinAbs(1., -1.), std::domain_error )
+  REQUIRE_THROWS_AS( WithinAbs(1.f, -1.f), std::domain_error )
 
 Matchers.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_NOTHROW( WithinULP(1., 0) )
+  REQUIRE_NOTHROW( WithinULP(1.f, 0) )
 
 Matchers.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THROWS_AS( WithinULP(1., -1), std::domain_error )
+  REQUIRE_THROWS_AS( WithinULP(1.f, -1), std::domain_error )
 
 -------------------------------------------------------------------------------
-Floating point matchers: float
-  Margin
+Generators
+  one
 -------------------------------------------------------------------------------
-Matchers.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Matchers.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( 1.f, WithinAbs(1.f, 0) )
-with expansion:
-  1.0f is within 0.0 of 1.0
+with messages:
+  i := "a"
+  j := 8
 
-Matchers.tests.cpp:<line number>:
+-------------------------------------------------------------------------------
+Generators
+  one
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( 0.f, WithinAbs(1.f, 1) )
-with expansion:
-  0.0f is within 1.0 of 1.0
+with messages:
+  i := "a"
+  j := 9
 
-Matchers.tests.cpp:<line number>:
+-------------------------------------------------------------------------------
+Generators
+  one
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( 0.f, !WithinAbs(1.f, 0.99f) )
+with messages:
+  i := "a"
+  j := 10
+
+-------------------------------------------------------------------------------
+Generators
+  one
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
+PASSED:
+with messages:
+  i := "a"
+  j := 2
+
+-------------------------------------------------------------------------------
+Generators
+  two
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
+PASSED:
+with messages:
+  i := "a"
+  j := 3.141
+
+-------------------------------------------------------------------------------
+Generators
+  two
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
+PASSED:
+with messages:
+  i := "a"
+  j := 1.379
+
+-------------------------------------------------------------------------------
+Generators
+  one
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
+PASSED:
+with messages:
+  i := "b"
+  j := 8
+
+-------------------------------------------------------------------------------
+Generators
+  one
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
+PASSED:
+with messages:
+  i := "b"
+  j := 9
+
+-------------------------------------------------------------------------------
+Generators
+  one
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
+PASSED:
+with messages:
+  i := "b"
+  j := 10
+
+-------------------------------------------------------------------------------
+Generators
+  one
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
+PASSED:
+with messages:
+  i := "b"
+  j := 2
+
+-------------------------------------------------------------------------------
+Generators
+  two
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
+PASSED:
+with messages:
+  i := "b"
+  j := 3.141
+
+-------------------------------------------------------------------------------
+Generators
+  two
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
+PASSED:
+with messages:
+  i := "b"
+  j := 1.379
+
+-------------------------------------------------------------------------------
+Generators
+  one
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
+PASSED:
+with messages:
+  i := "c"
+  j := 8
+
+-------------------------------------------------------------------------------
+Generators
+  one
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
+PASSED:
+with messages:
+  i := "c"
+  j := 9
+
+-------------------------------------------------------------------------------
+Generators
+  one
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
+PASSED:
+with messages:
+  i := "c"
+  j := 10
+
+-------------------------------------------------------------------------------
+Generators
+  one
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
+PASSED:
+with messages:
+  i := "c"
+  j := 2
+
+-------------------------------------------------------------------------------
+Generators
+  two
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
+PASSED:
+with messages:
+  i := "c"
+  j := 3.141
+
+-------------------------------------------------------------------------------
+Generators
+  two
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
+PASSED:
+with messages:
+  i := "c"
+  j := 1.379
+
+-------------------------------------------------------------------------------
+Generators impl
+  range
+-------------------------------------------------------------------------------
+GeneratorsImpl.tests.cpp:<line number>
+...............................................................................
+
+GeneratorsImpl.tests.cpp:<line number>:
+PASSED:
+  CHECK( gen.size() == 2 )
 with expansion:
-  0.0f not is within 0.9900000095 of 1.0
+  2 == 2
 
-Matchers.tests.cpp:<line number>:
+GeneratorsImpl.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( 0.f, !WithinAbs(1.f, 0.99f) )
+  CHECK( gen[0] == 1 )
 with expansion:
-  0.0f not is within 0.9900000095 of 1.0
+  1 == 1
 
-Matchers.tests.cpp:<line number>:
+GeneratorsImpl.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( 0.f, WithinAbs(-0.f, 0) )
+  CHECK( gen[1] == 2 )
 with expansion:
-  0.0f is within 0.0 of -0.0
+  2 == 2
+
+-------------------------------------------------------------------------------
+Generators impl
+  fixed values
+-------------------------------------------------------------------------------
+GeneratorsImpl.tests.cpp:<line number>
+...............................................................................
 
-Matchers.tests.cpp:<line number>:
+GeneratorsImpl.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( NAN, !WithinAbs(NAN, 0) )
+  CHECK( gen.size() == 4 )
 with expansion:
-  nanf not is within 0.0 of nan
+  4 == 4
 
-Matchers.tests.cpp:<line number>:
+GeneratorsImpl.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( 11.f, !WithinAbs(10.f, 0.5f) )
+  CHECK( gen[0] == 3 )
 with expansion:
-  11.0f not is within 0.5 of 10.0
+  3 == 3
 
-Matchers.tests.cpp:<line number>:
+GeneratorsImpl.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( 10.f, !WithinAbs(11.f, 0.5f) )
+  CHECK( gen[1] == 1 )
 with expansion:
-  10.0f not is within 0.5 of 11.0
+  1 == 1
 
-Matchers.tests.cpp:<line number>:
+GeneratorsImpl.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( -10.f, WithinAbs(-10.f, 0.5f) )
+  CHECK( gen[2] == 4 )
 with expansion:
-  -10.0f is within 0.5 of -10.0
+  4 == 4
 
-Matchers.tests.cpp:<line number>:
+GeneratorsImpl.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( -10.f, WithinAbs(-9.6f, 0.5f) )
+  CHECK( gen[3] == 1 )
 with expansion:
-  -10.0f is within 0.5 of -9.6000003815
+  1 == 1
 
 -------------------------------------------------------------------------------
-Floating point matchers: float
-  ULPs
+Generators impl
+  combined
 -------------------------------------------------------------------------------
-Matchers.tests.cpp:<line number>
+GeneratorsImpl.tests.cpp:<line number>
 ...............................................................................
 
-Matchers.tests.cpp:<line number>:
+GeneratorsImpl.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( 1.f, WithinULP(1.f, 0) )
+  CHECK( gen.size() == 4 )
 with expansion:
-  1.0f is within 0 ULPs of 1.0f
+  4 == 4
 
-Matchers.tests.cpp:<line number>:
+GeneratorsImpl.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( nextafter(1.f, 2.f), WithinULP(1.f, 1) )
+  CHECK( gen[0] == 1 )
 with expansion:
-  1.0f is within 1 ULPs of 1.0f
+  1 == 1
 
-Matchers.tests.cpp:<line number>:
+GeneratorsImpl.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( nextafter(1.f, 0.f), WithinULP(1.f, 1) )
+  CHECK( gen[1] == 2 )
 with expansion:
-  1.0f is within 1 ULPs of 1.0f
+  2 == 2
 
-Matchers.tests.cpp:<line number>:
+GeneratorsImpl.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( nextafter(1.f, 2.f), !WithinULP(1.f, 0) )
+  CHECK( gen[2] == 9 )
 with expansion:
-  1.0f not is within 0 ULPs of 1.0f
+  9 == 9
 
-Matchers.tests.cpp:<line number>:
+GeneratorsImpl.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( 1.f, WithinULP(1.f, 0) )
+  CHECK( gen[3] == 7 )
 with expansion:
-  1.0f is within 0 ULPs of 1.0f
+  7 == 7
 
-Matchers.tests.cpp:<line number>:
+-------------------------------------------------------------------------------
+Generators impl
+  values
+-------------------------------------------------------------------------------
+GeneratorsImpl.tests.cpp:<line number>
+...............................................................................
+
+GeneratorsImpl.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( -0.f, WithinULP(0.f, 0) )
+  CHECK( gen.size() == 2 )
 with expansion:
-  -0.0f is within 0 ULPs of 0.0f
+  2 == 2
 
-Matchers.tests.cpp:<line number>:
+GeneratorsImpl.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( NAN, !WithinULP(NAN, 123) )
+  CHECK( gen[0] == 3 )
 with expansion:
-  nanf not is within 123 ULPs of nanf
+  3 == 3
+
+GeneratorsImpl.tests.cpp:<line number>:
+PASSED:
+  CHECK( gen[1] == 1 )
+with expansion:
+  1 == 1
 
 -------------------------------------------------------------------------------
-Floating point matchers: float
-  Composed
+Generators impl
+  values2
 -------------------------------------------------------------------------------
-Matchers.tests.cpp:<line number>
+GeneratorsImpl.tests.cpp:<line number>
 ...............................................................................
 
-Matchers.tests.cpp:<line number>:
+GeneratorsImpl.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( 1.f, WithinAbs(1.f, 0.5) || WithinULP(1.f, 1) )
+  CHECK( gen.size() == 2 )
 with expansion:
-  1.0f ( is within 0.5 of 1.0 or is within 1 ULPs of 1.0f )
+  2 == 2
 
-Matchers.tests.cpp:<line number>:
+GeneratorsImpl.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( 1.f, WithinAbs(2.f, 0.5) || WithinULP(1.f, 0) )
+  CHECK( gen[0] == 3 )
 with expansion:
-  1.0f ( is within 0.5 of 2.0 or is within 0 ULPs of 1.0f )
+  3 == 3
 
-Matchers.tests.cpp:<line number>:
+GeneratorsImpl.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( NAN, !(WithinAbs(NAN, 100) || WithinULP(NAN, 123)) )
+  CHECK( gen[1] == 1 )
 with expansion:
-  nanf not ( is within 100.0 of nan or is within 123 ULPs of nanf )
+  1 == 1
 
 -------------------------------------------------------------------------------
-Floating point matchers: float
-  Constructor validation
+Generators impl
+  type erasure
 -------------------------------------------------------------------------------
-Matchers.tests.cpp:<line number>
+GeneratorsImpl.tests.cpp:<line number>
 ...............................................................................
 
-Matchers.tests.cpp:<line number>:
+GeneratorsImpl.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_NOTHROW( WithinAbs(1.f, 0.f) )
+  CHECK( base->size() == 4 )
+with expansion:
+  4 == 4
 
-Matchers.tests.cpp:<line number>:
+GeneratorsImpl.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THROWS_AS( WithinAbs(1.f, -1.f), std::domain_error )
+  REQUIRE( typed )
+with expansion:
+  0x<hex digits>
 
-Matchers.tests.cpp:<line number>:
+GeneratorsImpl.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_NOTHROW( WithinULP(1.f, 0) )
+  CHECK( typed->size() == 4 )
+with expansion:
+  4 == 4
 
-Matchers.tests.cpp:<line number>:
+GeneratorsImpl.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THROWS_AS( WithinULP(1.f, -1), std::domain_error )
+  CHECK( (*typed)[0] == 7 )
+with expansion:
+  7 == 7
+
+GeneratorsImpl.tests.cpp:<line number>:
+PASSED:
+  CHECK( (*typed)[3] == 11 )
+with expansion:
+  11 == 11
 
 -------------------------------------------------------------------------------
 Greater-than inequalities with different epsilons
@@ -3993,18 +5655,6 @@ PASSED:
 with expansion:
   true == true
 
--------------------------------------------------------------------------------
-Parsing a std::pair
--------------------------------------------------------------------------------
-Tricky.tests.cpp:<line number>
-...............................................................................
-
-Tricky.tests.cpp:<line number>:
-PASSED:
-  REQUIRE( (std::pair<int, int>( 1, 2 )) == aNicePair )
-with expansion:
-  {?} == {?}
-
 -------------------------------------------------------------------------------
 Pointers can be compared to null
 -------------------------------------------------------------------------------
@@ -4130,7 +5780,7 @@ with expansion:
 -------------------------------------------------------------------------------
 Process can be configured on command line
   test lists
-  1 test
+  Specify one test case using
 -------------------------------------------------------------------------------
 CmdLine.tests.cpp:<line number>
 ...............................................................................
@@ -4646,6 +6296,18 @@ with expansion:
   "this string contains 'abc' as a substring" matches "this string contains
   'abc' as a" case sensitively
 
+-------------------------------------------------------------------------------
+Regression test #1
+-------------------------------------------------------------------------------
+Matchers.tests.cpp:<line number>
+...............................................................................
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  CHECK_THAT( actual, !UnorderedEquals(expected) )
+with expansion:
+  { 'a', 'b' } not UnorderedEquals: { 'c', 'b' }
+
 -------------------------------------------------------------------------------
 SUCCEED counts as a test pass
 -------------------------------------------------------------------------------
@@ -4669,7 +6331,7 @@ PASSED:
 -------------------------------------------------------------------------------
 Scenario: BDD tests requiring Fixtures to provide commonly-accessed data or
           methods
-     Given: No operations precede me
+      Given: No operations precede me
 -------------------------------------------------------------------------------
 BDD.tests.cpp:<line number>
 ...............................................................................
@@ -4683,9 +6345,9 @@ with expansion:
 -------------------------------------------------------------------------------
 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
+      Given: No operations precede me
+       When: We get the count
+       Then: Subsequently values are higher
 -------------------------------------------------------------------------------
 BDD.tests.cpp:<line number>
 ...............................................................................
@@ -4698,9 +6360,10 @@ with expansion:
 
 -------------------------------------------------------------------------------
 Scenario: Do that thing with the thing
-     Given: This stuff exists
-      When: I do this
-      Then: it should do this
+      Given: This stuff exists
+  And given: And some assumption
+       When: I do this
+       Then: it should do this
 -------------------------------------------------------------------------------
 BDD.tests.cpp:<line number>
 ...............................................................................
@@ -4713,10 +6376,11 @@ with expansion:
 
 -------------------------------------------------------------------------------
 Scenario: Do that thing with the thing
-     Given: This stuff exists
-      When: I do this
-      Then: it should do this
-       And: do that
+      Given: This stuff exists
+  And given: And some assumption
+       When: I do this
+       Then: it should do this
+        And: do that
 -------------------------------------------------------------------------------
 BDD.tests.cpp:<line number>
 ...............................................................................
@@ -4730,12 +6394,12 @@ with expansion:
 -------------------------------------------------------------------------------
 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
+      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
 -------------------------------------------------------------------------------
 BDD.tests.cpp:<line number>
 ...............................................................................
@@ -4747,7 +6411,7 @@ with message:
 
 -------------------------------------------------------------------------------
 Scenario: Vector resizing affects size and capacity
-     Given: an empty vector
+      Given: an empty vector
 -------------------------------------------------------------------------------
 BDD.tests.cpp:<line number>
 ...............................................................................
@@ -4760,9 +6424,9 @@ with expansion:
 
 -------------------------------------------------------------------------------
 Scenario: Vector resizing affects size and capacity
-     Given: an empty vector
-      When: it is made larger
-      Then: the size and capacity go up
+      Given: an empty vector
+       When: it is made larger
+       Then: the size and capacity go up
 -------------------------------------------------------------------------------
 BDD.tests.cpp:<line number>
 ...............................................................................
@@ -4781,11 +6445,11 @@ with expansion:
 
 -------------------------------------------------------------------------------
 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
+      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
 -------------------------------------------------------------------------------
 BDD.tests.cpp:<line number>
 ...............................................................................
@@ -4804,7 +6468,7 @@ with expansion:
 
 -------------------------------------------------------------------------------
 Scenario: Vector resizing affects size and capacity
-     Given: an empty vector
+      Given: an empty vector
 -------------------------------------------------------------------------------
 BDD.tests.cpp:<line number>
 ...............................................................................
@@ -4817,9 +6481,9 @@ with expansion:
 
 -------------------------------------------------------------------------------
 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
+      Given: an empty vector
+       When: we reserve more space
+       Then: The capacity is increased but the size remains the same
 -------------------------------------------------------------------------------
 BDD.tests.cpp:<line number>
 ...............................................................................
@@ -4872,6 +6536,18 @@ PASSED:
 with expansion:
   1.23 != Approx( 1.24 )
 
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( d == 1.23_a )
+with expansion:
+  1.23 == Approx( 1.23 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( d != 1.22_a )
+with expansion:
+  1.23 != Approx( 1.22 )
+
 Approx.tests.cpp:<line number>:
 PASSED:
   REQUIRE( Approx( d ) == 1.23 )
@@ -7754,7 +9430,7 @@ with expansion:
 
 -------------------------------------------------------------------------------
 looped SECTION tests
-  s1
+  b is currently: 0
 -------------------------------------------------------------------------------
 Misc.tests.cpp:<line number>
 ...............................................................................
@@ -7764,6 +9440,122 @@ Misc.tests.cpp:<line number>: FAILED:
 with expansion:
   0 > 1
 
+-------------------------------------------------------------------------------
+looped SECTION tests
+  b is currently: 1
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: FAILED:
+  CHECK( b > a )
+with expansion:
+  1 > 1
+
+-------------------------------------------------------------------------------
+looped SECTION tests
+  b is currently: 2
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>:
+PASSED:
+  CHECK( b > a )
+with expansion:
+  2 > 1
+
+-------------------------------------------------------------------------------
+looped SECTION tests
+  b is currently: 3
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>:
+PASSED:
+  CHECK( b > a )
+with expansion:
+  3 > 1
+
+-------------------------------------------------------------------------------
+looped SECTION tests
+  b is currently: 4
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>:
+PASSED:
+  CHECK( b > a )
+with expansion:
+  4 > 1
+
+-------------------------------------------------------------------------------
+looped SECTION tests
+  b is currently: 5
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>:
+PASSED:
+  CHECK( b > a )
+with expansion:
+  5 > 1
+
+-------------------------------------------------------------------------------
+looped SECTION tests
+  b is currently: 6
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>:
+PASSED:
+  CHECK( b > a )
+with expansion:
+  6 > 1
+
+-------------------------------------------------------------------------------
+looped SECTION tests
+  b is currently: 7
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>:
+PASSED:
+  CHECK( b > a )
+with expansion:
+  7 > 1
+
+-------------------------------------------------------------------------------
+looped SECTION tests
+  b is currently: 8
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>:
+PASSED:
+  CHECK( b > a )
+with expansion:
+  8 > 1
+
+-------------------------------------------------------------------------------
+looped SECTION tests
+  b is currently: 9
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>:
+PASSED:
+  CHECK( b > a )
+with expansion:
+  9 > 1
+
 -------------------------------------------------------------------------------
 looped tests
 -------------------------------------------------------------------------------
@@ -7830,8 +9622,8 @@ with message:
 
 -------------------------------------------------------------------------------
 more nested SECTION tests
-  s1
-  s2
+  doesn't equal
+  equal
 -------------------------------------------------------------------------------
 Misc.tests.cpp:<line number>
 ...............................................................................
@@ -7843,8 +9635,8 @@ with expansion:
 
 -------------------------------------------------------------------------------
 more nested SECTION tests
-  s1
-  s3
+  doesn't equal
+  not equal
 -------------------------------------------------------------------------------
 Misc.tests.cpp:<line number>
 ...............................................................................
@@ -7857,8 +9649,8 @@ with expansion:
 
 -------------------------------------------------------------------------------
 more nested SECTION tests
-  s1
-  s4
+  doesn't equal
+  less than
 -------------------------------------------------------------------------------
 Misc.tests.cpp:<line number>
 ...............................................................................
@@ -7871,7 +9663,7 @@ with expansion:
 
 -------------------------------------------------------------------------------
 nested SECTION tests
-  s1
+  doesn't equal
 -------------------------------------------------------------------------------
 Misc.tests.cpp:<line number>
 ...............................................................................
@@ -7890,8 +9682,8 @@ with expansion:
 
 -------------------------------------------------------------------------------
 nested SECTION tests
-  s1
-  s2
+  doesn't equal
+  not equal
 -------------------------------------------------------------------------------
 Misc.tests.cpp:<line number>
 ...............................................................................
@@ -7993,7 +9785,7 @@ with expansion:
 
 -------------------------------------------------------------------------------
 random SECTION tests
-  s1
+  doesn't equal
 -------------------------------------------------------------------------------
 Misc.tests.cpp:<line number>
 ...............................................................................
@@ -8012,7 +9804,7 @@ with expansion:
 
 -------------------------------------------------------------------------------
 random SECTION tests
-  s2
+  not equal
 -------------------------------------------------------------------------------
 Misc.tests.cpp:<line number>
 ...............................................................................
@@ -8463,6 +10255,54 @@ with expansion:
   ==
   "{ operator<<( has_operator ) }"
 
+-------------------------------------------------------------------------------
+strlen3
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( data.str.size() == data.len )
+with expansion:
+  3 == 3
+
+-------------------------------------------------------------------------------
+strlen3
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( data.str.size() == data.len )
+with expansion:
+  3 == 3
+
+-------------------------------------------------------------------------------
+strlen3
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( data.str.size() == data.len )
+with expansion:
+  5 == 5
+
+-------------------------------------------------------------------------------
+strlen3
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( data.str.size() == data.len )
+with expansion:
+  4 == 4
+
 -------------------------------------------------------------------------------
 thrown std::strings are translated
 -------------------------------------------------------------------------------
@@ -8973,7 +10813,9 @@ with expansion:
 
 -------------------------------------------------------------------------------
 xmlentitycheck
-  embedded xml
+  embedded xml: <test>it should be possible to embed xml characters, such as <,
+                " or &, or even whole <xml>documents</xml> within an attribute</test>
+                </test>
 -------------------------------------------------------------------------------
 Misc.tests.cpp:<line number>
 ...............................................................................
@@ -8983,7 +10825,7 @@ PASSED:
 
 -------------------------------------------------------------------------------
 xmlentitycheck
-  encoded chars
+  encoded chars: these should all be encoded: &&&"""<<<&"<<&"
 -------------------------------------------------------------------------------
 Misc.tests.cpp:<line number>
 ...............................................................................
@@ -8992,6 +10834,6 @@ Misc.tests.cpp:<line number>:
 PASSED:
 
 ===============================================================================
-test cases:  208 | 142 passed |  62 failed |  4 failed as expected
-assertions: 1079 | 937 passed | 121 failed | 21 failed as expected
+test cases:  213 |  147 passed |  62 failed |  4 failed as expected
+assertions: 1242 | 1099 passed | 122 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 62ca90940..ad5caeb17 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="105" tests="1080" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
+  <testsuite name="<exe-name>" errors="17" failures="106" tests="1243" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
     <testcase classname="<exe-name>.global" name="# A test name that starts with a #" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="#1005: Comparing pointer to int and long (NULL can be either on various systems)" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="#1027" time="{duration}"/>
@@ -69,6 +69,7 @@ Condition.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="(unimplemented) static bools can be evaluated/negation" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="(unimplemented) static bools can be evaluated/double negation" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="(unimplemented) static bools can be evaluated/direct" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="10x10 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">
 Class.tests.cpp:<line number>
@@ -81,6 +82,7 @@ Class.tests.cpp:<line number>
       </failure>
     </testcase>
     <testcase classname="<exe-name>.Fixture" name="A TEST_CASE_METHOD based test run that succeeds" time="{duration}"/>
+    <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">
 to infinity and beyond
@@ -288,6 +290,14 @@ Message.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="Floating point matchers: float/ULPs" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Floating point matchers: float/Composed" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Floating point matchers: float/Constructor validation" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Generators/one" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Generators/two" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Generators impl/range" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Generators impl/fixed values" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Generators impl/combined" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Generators impl/values" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Generators impl/values2" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Generators impl/type erasure" 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}">
@@ -467,11 +477,10 @@ Message.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="Parse test names and tags/empty tag" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Parse test names and tags/empty quoted name" time="{duration}"/>
     <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="Parsing a std::pair" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Pointers can be compared to null" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Process can be configured on command line/empty args don't cause a crash" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Process can be configured on command line/default - no arguments" time="{duration}"/>
-    <testcase classname="<exe-name>.global" name="Process can be configured on command line/test lists/1 test" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Process can be configured on command line/test lists/Specify one test case using" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Process can be configured on command line/test lists/Specify one test case exclusion using exclude:" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Process can be configured on command line/test lists/Specify one test case exclusion using ~" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Process can be configured on command line/reporter/-r/console" time="{duration}"/>
@@ -509,12 +518,13 @@ Matchers.tests.cpp:<line number>
 Matchers.tests.cpp:<line number>
       </failure>
     </testcase>
+    <testcase classname="<exe-name>.global" name="Regression test #1" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="SUCCEED counts as a test pass" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="SUCCEED does not require an argument" time="{duration}"/>
     <testcase classname="<exe-name>.Fixture" name="Scenario: BDD tests requiring Fixtures to provide commonly-accessed data or methods/Given: No operations precede me" time="{duration}"/>
     <testcase classname="<exe-name>.Fixture" 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" time="{duration}"/>
-    <testcase classname="<exe-name>.global" name="Scenario: Do that thing with the thing/Given: This stuff exists/When: I do this/Then: it should do this" time="{duration}"/>
-    <testcase classname="<exe-name>.global" name="Scenario: Do that thing with the thing/Given: This stuff exists/When: I do this/Then: it should do this/And: do that" time="{duration}"/>
+    <testcase classname="<exe-name>.global" 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" time="{duration}"/>
+    <testcase classname="<exe-name>.global" 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" time="{duration}"/>
     <testcase classname="<exe-name>.global" 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" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Scenario: Vector resizing affects size and capacity/Given: an empty vector" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Scenario: Vector resizing affects size and capacity/Given: an empty vector/When: it is made larger/Then: the size and capacity go up" time="{duration}"/>
@@ -750,11 +760,24 @@ 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/s1" time="{duration}">
+    <testcase classname="<exe-name>.global" name="looped SECTION tests/b is currently: 0" time="{duration}">
       <failure message="0 > 1" type="CHECK">
 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">
+Misc.tests.cpp:<line number>
+      </failure>
+    </testcase>
+    <testcase classname="<exe-name>.global" name="looped SECTION tests/b is currently: 2" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="looped SECTION tests/b is currently: 3" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="looped SECTION tests/b is currently: 4" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="looped SECTION tests/b is currently: 5" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="looped SECTION tests/b is currently: 6" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="looped SECTION tests/b is currently: 7" time="{duration}"/>
+    <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">
 Testing if fib[0] (1) is even
@@ -781,15 +804,15 @@ Testing if fib[7] (21) is even
 Misc.tests.cpp:<line number>
       </failure>
     </testcase>
-    <testcase classname="<exe-name>.global" name="more nested SECTION tests/s2/s1" time="{duration}">
+    <testcase classname="<exe-name>.global" name="more nested SECTION tests/equal/doesn't equal" time="{duration}">
       <failure message="1 == 2" type="REQUIRE">
 Misc.tests.cpp:<line number>
       </failure>
     </testcase>
-    <testcase classname="<exe-name>.global" name="more nested SECTION tests/s1/s3" time="{duration}"/>
-    <testcase classname="<exe-name>.global" name="more nested SECTION tests/s1/s4" time="{duration}"/>
-    <testcase classname="<exe-name>.global" name="nested SECTION tests/s1" time="{duration}"/>
-    <testcase classname="<exe-name>.global" name="nested SECTION tests/s1/s2" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="more nested SECTION tests/doesn't equal/not equal" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="more nested SECTION tests/doesn't equal/less than" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="nested SECTION tests/doesn't equal" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="nested SECTION tests/doesn't equal/not equal" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="non streamable - with conv. op" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="non-copyable objects" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="not allowed" time="{duration}"/>
@@ -797,8 +820,8 @@ Misc.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="null_ptr" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="pair&lt;pair&lt;int,const char *,pair&lt;std::string,int> > -> toString" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="pointer to class" time="{duration}"/>
-    <testcase classname="<exe-name>.global" name="random SECTION tests/s1" time="{duration}"/>
-    <testcase classname="<exe-name>.global" name="random SECTION tests/s2" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="random SECTION tests/doesn't equal" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="random SECTION tests/not equal" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="replaceInPlace/replace single char" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="replaceInPlace/replace two chars" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="replaceInPlace/replace first char" time="{duration}"/>
@@ -842,6 +865,7 @@ Tricky.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="stringify( vectors&lt;has_maker> )" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="stringify( vectors&lt;has_maker_and_operator> )" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="stringify( vectors&lt;has_operator> )" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="strlen3" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="thrown std::strings are translated" time="{duration}">
       <error type="TEST_CASE">
 Why would you throw a std::string?
@@ -873,8 +897,8 @@ Exception.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="vectors can be sized and resized/resizing smaller changes size but not capacity/We can use the 'swap trick' to reset the capacity" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="vectors can be sized and resized/reserving bigger changes capacity but not size" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="vectors can be sized and resized/reserving smaller does not change size or capacity" time="{duration}"/>
-    <testcase classname="<exe-name>.global" name="xmlentitycheck/embedded xml" time="{duration}"/>
-    <testcase classname="<exe-name>.global" name="xmlentitycheck/encoded chars" time="{duration}"/>
+    <testcase classname="<exe-name>.global" 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>" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="xmlentitycheck/encoded chars: these should all be encoded: &amp;&amp;&amp;&quot;&quot;&quot;&lt;&lt;&lt;&amp;&quot;&lt;&lt;&amp;&quot;" time="{duration}"/>
     <system-out>
 A string sent directly to stdout
 Message from section one
diff --git a/packages/Catch2/projects/SelfTest/Baselines/xml.sw.approved.txt b/packages/Catch2/projects/SelfTest/Baselines/xml.sw.approved.txt
index 5452f2fa3..342878744 100644
--- a/packages/Catch2/projects/SelfTest/Baselines/xml.sw.approved.txt
+++ b/packages/Catch2/projects/SelfTest/Baselines/xml.sw.approved.txt
@@ -510,472 +510,1326 @@
       </Section>
       <OverallResult success="true"/>
     </TestCase>
-    <TestCase name="A METHOD_AS_TEST_CASE based test run that fails" tags="[.][class][failing]" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
-      <Expression success="false" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+    <TestCase name="10x10 ints" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          s == "world"
+          x &lt; y
         </Original>
         <Expanded>
-          "hello" == "world"
+          1 &lt; 101
         </Expanded>
       </Expression>
-      <OverallResult success="false"/>
-    </TestCase>
-    <TestCase name="A METHOD_AS_TEST_CASE based test run that succeeds" tags="[class]" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          s == "hello"
+          x &lt; y
         </Original>
         <Expanded>
-          "hello" == "hello"
+          1 &lt; 102
         </Expanded>
       </Expression>
-      <OverallResult success="true"/>
-    </TestCase>
-    <TestCase name="A TEST_CASE_METHOD based test run that fails" tags="[.][class][failing]" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
-      <Expression success="false" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          m_a == 2
+          x &lt; y
         </Original>
         <Expanded>
-          1 == 2
+          1 &lt; 103
         </Expanded>
       </Expression>
-      <OverallResult success="false"/>
-    </TestCase>
-    <TestCase name="A TEST_CASE_METHOD based test run that succeeds" tags="[class]" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          m_a == 1
+          x &lt; y
         </Original>
         <Expanded>
-          1 == 1
+          1 &lt; 104
         </Expanded>
       </Expression>
-      <OverallResult success="true"/>
-    </TestCase>
-    <TestCase name="A couple of nested sections followed by a failure" tags="[.][failing]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
-      <Section name="Outer" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
-        <Section name="Inner" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
-          <OverallResults successes="1" failures="0" expectedFailures="0"/>
-        </Section>
-        <OverallResults successes="1" failures="0" expectedFailures="0"/>
-      </Section>
-      <Failure filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
-        to infinity and beyond
-      </Failure>
-      <OverallResult success="false"/>
-    </TestCase>
-    <TestCase name="A failing expression with a non streamable type is still captured" tags="[.][Tricky][failing]" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
-      <Expression success="false" type="CHECK" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          &amp;o1 == &amp;o2
+          x &lt; y
         </Original>
         <Expanded>
-          0x<hex digits> == 0x<hex digits>
+          1 &lt; 105
         </Expanded>
       </Expression>
-      <Expression success="false" type="CHECK" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          o1 == o2
+          x &lt; y
         </Original>
         <Expanded>
-          {?} == {?}
+          1 &lt; 106
         </Expanded>
       </Expression>
-      <OverallResult success="false"/>
-    </TestCase>
-    <TestCase name="Absolute margin" tags="[Approx]" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          104.0 != Approx(100.0)
+          x &lt; y
         </Original>
         <Expanded>
-          104.0 != Approx( 100.0 )
+          1 &lt; 107
         </Expanded>
       </Expression>
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          104.0 == Approx(100.0).margin(5)
+          x &lt; y
         </Original>
         <Expanded>
-          104.0 == Approx( 100.0 )
+          1 &lt; 108
         </Expanded>
       </Expression>
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          104.0 == Approx(100.0).margin(4)
+          x &lt; y
         </Original>
         <Expanded>
-          104.0 == Approx( 100.0 )
+          1 &lt; 109
         </Expanded>
       </Expression>
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          104.0 != Approx(100.0).margin(3)
+          x &lt; y
         </Original>
         <Expanded>
-          104.0 != Approx( 100.0 )
+          1 &lt; 110
         </Expanded>
       </Expression>
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          100.3 != Approx(100.0)
+          x &lt; y
         </Original>
         <Expanded>
-          100.3 != Approx( 100.0 )
+          2 &lt; 101
         </Expanded>
       </Expression>
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          100.3 == Approx(100.0).margin(0.5)
+          x &lt; y
         </Original>
         <Expanded>
-          100.3 == Approx( 100.0 )
+          2 &lt; 102
         </Expanded>
       </Expression>
-      <OverallResult success="true"/>
-    </TestCase>
-    <TestCase name="An empty test with no assertions" tags="[empty]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
-      <OverallResult success="false"/>
-    </TestCase>
-    <TestCase name="An expression with side-effects should only be evaluated once" tags="[Tricky]" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          i++ == 7
+          x &lt; y
         </Original>
         <Expanded>
-          7 == 7
+          2 &lt; 103
         </Expanded>
       </Expression>
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          i++ == 8
+          x &lt; y
         </Original>
         <Expanded>
-          8 == 8
+          2 &lt; 104
         </Expanded>
       </Expression>
-      <OverallResult success="true"/>
-    </TestCase>
-    <TestCase name="An unchecked exception reports the line of the last assertion" tags="[!throws][.][failing]" filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" >
-      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          1 == 1
+          x &lt; y
         </Original>
         <Expanded>
-          1 == 1
+          2 &lt; 105
         </Expanded>
       </Expression>
-      <Expression success="false" filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          {Unknown expression after the reported line}
+          x &lt; y
         </Original>
         <Expanded>
-          {Unknown expression after the reported line}
+          2 &lt; 106
         </Expanded>
-        <Exception filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" >
-          unexpected exception
-        </Exception>
       </Expression>
-      <OverallResult success="false"/>
-    </TestCase>
-    <TestCase name="Anonymous test case 1" filename="projects/<exe-name>/UsageTests/VariadicMacros.tests.cpp" >
-      <OverallResult success="true"/>
-    </TestCase>
-    <TestCase name="Approx setters validate their arguments" tags="[Approx]" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
-      <Expression success="true" type="REQUIRE_NOTHROW" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          Approx(0).margin(0)
+          x &lt; y
         </Original>
         <Expanded>
-          Approx(0).margin(0)
+          2 &lt; 107
         </Expanded>
       </Expression>
-      <Expression success="true" type="REQUIRE_NOTHROW" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          Approx(0).margin(1234656)
+          x &lt; y
         </Original>
         <Expanded>
-          Approx(0).margin(1234656)
+          2 &lt; 108
         </Expanded>
       </Expression>
-      <Expression success="true" type="REQUIRE_THROWS_AS" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          Approx(0).margin(-2), std::domain_error
+          x &lt; y
         </Original>
         <Expanded>
-          Approx(0).margin(-2), std::domain_error
+          2 &lt; 109
         </Expanded>
       </Expression>
-      <Expression success="true" type="REQUIRE_NOTHROW" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          Approx(0).epsilon(0)
+          x &lt; y
         </Original>
         <Expanded>
-          Approx(0).epsilon(0)
+          2 &lt; 110
         </Expanded>
       </Expression>
-      <Expression success="true" type="REQUIRE_NOTHROW" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          Approx(0).epsilon(1)
+          x &lt; y
         </Original>
         <Expanded>
-          Approx(0).epsilon(1)
+          3 &lt; 101
         </Expanded>
       </Expression>
-      <Expression success="true" type="REQUIRE_THROWS_AS" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          Approx(0).epsilon(-0.001), std::domain_error
+          x &lt; y
         </Original>
         <Expanded>
-          Approx(0).epsilon(-0.001), std::domain_error
+          3 &lt; 102
         </Expanded>
       </Expression>
-      <Expression success="true" type="REQUIRE_THROWS_AS" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          Approx(0).epsilon(1.0001), std::domain_error
+          x &lt; y
         </Original>
         <Expanded>
-          Approx(0).epsilon(1.0001), std::domain_error
+          3 &lt; 103
         </Expanded>
       </Expression>
-      <OverallResult success="true"/>
-    </TestCase>
-    <TestCase name="Approx with exactly-representable margin" tags="[Approx]" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
-      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          0.25f == Approx(0.0f).margin(0.25f)
+          x &lt; y
         </Original>
         <Expanded>
-          0.25f == Approx( 0.0 )
+          3 &lt; 104
         </Expanded>
       </Expression>
-      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          0.0f == Approx(0.25f).margin(0.25f)
+          x &lt; y
         </Original>
         <Expanded>
-          0.0f == Approx( 0.25 )
+          3 &lt; 105
         </Expanded>
       </Expression>
-      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          0.5f == Approx(0.25f).margin(0.25f)
+          x &lt; y
         </Original>
         <Expanded>
-          0.5f == Approx( 0.25 )
+          3 &lt; 106
         </Expanded>
       </Expression>
-      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          245.0f == Approx(245.25f).margin(0.25f)
+          x &lt; y
         </Original>
         <Expanded>
-          245.0f == Approx( 245.25 )
+          3 &lt; 107
         </Expanded>
       </Expression>
-      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          245.5f == Approx(245.25f).margin(0.25f)
+          x &lt; y
         </Original>
         <Expanded>
-          245.5f == Approx( 245.25 )
+          3 &lt; 108
         </Expanded>
       </Expression>
-      <OverallResult success="true"/>
-    </TestCase>
-    <TestCase name="Approximate PI" tags="[Approx][PI]" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          divide( 22, 7 ) == Approx( 3.141 ).epsilon( 0.001 )
+          x &lt; y
         </Original>
         <Expanded>
-          3.1428571429 == Approx( 3.141 )
+          3 &lt; 109
         </Expanded>
       </Expression>
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          divide( 22, 7 ) != Approx( 3.141 ).epsilon( 0.0001 )
+          x &lt; y
         </Original>
         <Expanded>
-          3.1428571429 != Approx( 3.141 )
+          3 &lt; 110
         </Expanded>
       </Expression>
-      <OverallResult success="true"/>
-    </TestCase>
-    <TestCase name="Approximate comparisons with different epsilons" tags="[Approx]" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          d != Approx( 1.231 )
+          x &lt; y
         </Original>
         <Expanded>
-          1.23 != Approx( 1.231 )
+          4 &lt; 101
         </Expanded>
       </Expression>
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          d == Approx( 1.231 ).epsilon( 0.1 )
+          x &lt; y
         </Original>
         <Expanded>
-          1.23 == Approx( 1.231 )
+          4 &lt; 102
         </Expanded>
       </Expression>
-      <OverallResult success="true"/>
-    </TestCase>
-    <TestCase name="Approximate comparisons with floats" tags="[Approx]" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          1.23f == Approx( 1.23f )
+          x &lt; y
         </Original>
         <Expanded>
-          1.23f == Approx( 1.2300000191 )
+          4 &lt; 103
         </Expanded>
       </Expression>
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          0.0f == Approx( 0.0f )
+          x &lt; y
         </Original>
         <Expanded>
-          0.0f == Approx( 0.0 )
+          4 &lt; 104
         </Expanded>
       </Expression>
-      <OverallResult success="true"/>
-    </TestCase>
-    <TestCase name="Approximate comparisons with ints" tags="[Approx]" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          1 == Approx( 1 )
+          x &lt; y
         </Original>
         <Expanded>
-          1 == Approx( 1.0 )
+          4 &lt; 105
         </Expanded>
       </Expression>
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          0 == Approx( 0 )
+          x &lt; y
         </Original>
         <Expanded>
-          0 == Approx( 0.0 )
+          4 &lt; 106
         </Expanded>
       </Expression>
-      <OverallResult success="true"/>
-    </TestCase>
-    <TestCase name="Approximate comparisons with mixed numeric types" tags="[Approx]" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          1.0f == Approx( 1 )
+          x &lt; y
         </Original>
         <Expanded>
-          1.0f == Approx( 1.0 )
+          4 &lt; 107
         </Expanded>
       </Expression>
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          0 == Approx( dZero)
+          x &lt; y
         </Original>
         <Expanded>
-          0 == Approx( 0.0 )
+          4 &lt; 108
         </Expanded>
       </Expression>
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          0 == Approx( dSmall ).margin( 0.001 )
+          x &lt; y
         </Original>
         <Expanded>
-          0 == Approx( 0.00001 )
+          4 &lt; 109
         </Expanded>
       </Expression>
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          1.234f == Approx( dMedium )
+          x &lt; y
         </Original>
         <Expanded>
-          1.234f == Approx( 1.234 )
+          4 &lt; 110
         </Expanded>
       </Expression>
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          dMedium == Approx( 1.234f )
+          x &lt; y
         </Original>
         <Expanded>
-          1.234 == Approx( 1.2339999676 )
+          5 &lt; 101
         </Expanded>
       </Expression>
-      <OverallResult success="true"/>
-    </TestCase>
-    <TestCase name="Arbitrary predicate matcher" tags="[generic][matchers]" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
-      <Section name="Function pointer" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
-          <Original>
-            1, Predicate&lt;int>(alwaysTrue, "always true")
-          </Original>
-          <Expanded>
-            1 matches predicate: "always true"
-          </Expanded>
-        </Expression>
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
-          <Original>
-            1, !Predicate&lt;int>(alwaysFalse, "always false")
-          </Original>
-          <Expanded>
-            1 not matches predicate: "always false"
-          </Expanded>
-        </Expression>
-        <OverallResults successes="2" failures="0" expectedFailures="0"/>
-      </Section>
-      <Section name="Lambdas + different type" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
-          <Original>
-            "Hello olleH", Predicate&lt;std::string>( [] (std::string const&amp; str) -> bool { return str.front() == str.back(); }, "First and last character should be equal")
-          </Original>
-          <Expanded>
-            "Hello olleH" matches predicate: "First and last character should be equal"
-          </Expanded>
-        </Expression>
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
-          <Original>
-            "This wouldn't pass", !Predicate&lt;std::string>( [] (std::string const&amp; str) -> bool { return str.front() == str.back(); } )
-          </Original>
-          <Expanded>
-            "This wouldn't pass" not matches undescribed predicate
-          </Expanded>
-        </Expression>
-        <OverallResults successes="2" failures="0" expectedFailures="0"/>
-      </Section>
-      <OverallResult success="true"/>
-    </TestCase>
-    <TestCase name="Assertions then sections" tags="[Tricky]" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          true
+          x &lt; y
         </Original>
         <Expanded>
-          true
+          5 &lt; 102
         </Expanded>
       </Expression>
-      <Section name="A section" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
-        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
-          <Original>
-            true
-          </Original>
-          <Expanded>
-            true
-          </Expanded>
-        </Expression>
-        <Section name="Another section" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
-          <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
-            <Original>
-              true
-            </Original>
-            <Expanded>
-              true
-            </Expanded>
-          </Expression>
-          <OverallResults successes="1" failures="0" expectedFailures="0"/>
-        </Section>
-        <OverallResults successes="2" failures="0" expectedFailures="0"/>
-      </Section>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          5 &lt; 103
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          5 &lt; 104
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          5 &lt; 105
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          5 &lt; 106
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          5 &lt; 107
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          5 &lt; 108
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          5 &lt; 109
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          5 &lt; 110
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          6 &lt; 101
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          6 &lt; 102
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          6 &lt; 103
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          6 &lt; 104
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          6 &lt; 105
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          6 &lt; 106
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          6 &lt; 107
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          6 &lt; 108
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          6 &lt; 109
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          6 &lt; 110
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          7 &lt; 101
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          7 &lt; 102
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          7 &lt; 103
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          7 &lt; 104
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          7 &lt; 105
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          7 &lt; 106
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          7 &lt; 107
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          7 &lt; 108
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          7 &lt; 109
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          7 &lt; 110
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          8 &lt; 101
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          8 &lt; 102
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          8 &lt; 103
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          8 &lt; 104
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          8 &lt; 105
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          8 &lt; 106
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          8 &lt; 107
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          8 &lt; 108
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          8 &lt; 109
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          8 &lt; 110
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          9 &lt; 101
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          9 &lt; 102
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          9 &lt; 103
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          9 &lt; 104
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          9 &lt; 105
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          9 &lt; 106
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          9 &lt; 107
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          9 &lt; 108
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          9 &lt; 109
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          9 &lt; 110
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          10 &lt; 101
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          10 &lt; 102
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          10 &lt; 103
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          10 &lt; 104
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          10 &lt; 105
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          10 &lt; 106
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          10 &lt; 107
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          10 &lt; 108
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          10 &lt; 109
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          10 &lt; 110
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="A METHOD_AS_TEST_CASE based test run that fails" tags="[.][class][failing]" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+      <Expression success="false" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+        <Original>
+          s == "world"
+        </Original>
+        <Expanded>
+          "hello" == "world"
+        </Expanded>
+      </Expression>
+      <OverallResult success="false"/>
+    </TestCase>
+    <TestCase name="A METHOD_AS_TEST_CASE based test run that succeeds" tags="[class]" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+        <Original>
+          s == "hello"
+        </Original>
+        <Expanded>
+          "hello" == "hello"
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="A TEST_CASE_METHOD based test run that fails" tags="[.][class][failing]" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+      <Expression success="false" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+        <Original>
+          m_a == 2
+        </Original>
+        <Expanded>
+          1 == 2
+        </Expanded>
+      </Expression>
+      <OverallResult success="false"/>
+    </TestCase>
+    <TestCase name="A TEST_CASE_METHOD based test run that succeeds" tags="[class]" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+        <Original>
+          m_a == 1
+        </Original>
+        <Expanded>
+          1 == 1
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="A comparison that uses literals instead of the normal constructor" tags="[Approx]" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          d == 1.23_a
+        </Original>
+        <Expanded>
+          1.23 == Approx( 1.23 )
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          d != 1.22_a
+        </Original>
+        <Expanded>
+          1.23 != Approx( 1.22 )
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          -d == -1.23_a
+        </Original>
+        <Expanded>
+          -1.23 == Approx( -1.23 )
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          d == 1.2_a .epsilon(.1)
+        </Original>
+        <Expanded>
+          1.23 == Approx( 1.2 )
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          d != 1.2_a .epsilon(.001)
+        </Original>
+        <Expanded>
+          1.23 != Approx( 1.2 )
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          d == 1_a .epsilon(.3)
+        </Original>
+        <Expanded>
+          1.23 == Approx( 1.0 )
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="A couple of nested sections followed by a failure" tags="[.][failing]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+      <Section name="Outer" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Section name="Inner" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <OverallResults successes="1" failures="0" expectedFailures="0"/>
+        </Section>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Failure filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        to infinity and beyond
+      </Failure>
+      <OverallResult success="false"/>
+    </TestCase>
+    <TestCase name="A failing expression with a non streamable type is still captured" tags="[.][Tricky][failing]" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
+      <Expression success="false" type="CHECK" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
+        <Original>
+          &amp;o1 == &amp;o2
+        </Original>
+        <Expanded>
+          0x<hex digits> == 0x<hex digits>
+        </Expanded>
+      </Expression>
+      <Expression success="false" type="CHECK" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
+        <Original>
+          o1 == o2
+        </Original>
+        <Expanded>
+          {?} == {?}
+        </Expanded>
+      </Expression>
+      <OverallResult success="false"/>
+    </TestCase>
+    <TestCase name="Absolute margin" tags="[Approx]" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          104.0 != Approx(100.0)
+        </Original>
+        <Expanded>
+          104.0 != Approx( 100.0 )
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          104.0 == Approx(100.0).margin(5)
+        </Original>
+        <Expanded>
+          104.0 == Approx( 100.0 )
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          104.0 == Approx(100.0).margin(4)
+        </Original>
+        <Expanded>
+          104.0 == Approx( 100.0 )
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          104.0 != Approx(100.0).margin(3)
+        </Original>
+        <Expanded>
+          104.0 != Approx( 100.0 )
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          100.3 != Approx(100.0)
+        </Original>
+        <Expanded>
+          100.3 != Approx( 100.0 )
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          100.3 == Approx(100.0).margin(0.5)
+        </Original>
+        <Expanded>
+          100.3 == Approx( 100.0 )
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="An empty test with no assertions" tags="[empty]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+      <OverallResult success="false"/>
+    </TestCase>
+    <TestCase name="An expression with side-effects should only be evaluated once" tags="[Tricky]" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
+        <Original>
+          i++ == 7
+        </Original>
+        <Expanded>
+          7 == 7
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
+        <Original>
+          i++ == 8
+        </Original>
+        <Expanded>
+          8 == 8
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="An unchecked exception reports the line of the last assertion" tags="[!throws][.][failing]" filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" >
+        <Original>
+          1 == 1
+        </Original>
+        <Expanded>
+          1 == 1
+        </Expanded>
+      </Expression>
+      <Expression success="false" filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" >
+        <Original>
+          {Unknown expression after the reported line}
+        </Original>
+        <Expanded>
+          {Unknown expression after the reported line}
+        </Expanded>
+        <Exception filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" >
+          unexpected exception
+        </Exception>
+      </Expression>
+      <OverallResult success="false"/>
+    </TestCase>
+    <TestCase name="Anonymous test case 1" filename="projects/<exe-name>/UsageTests/VariadicMacros.tests.cpp" >
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="Approx setters validate their arguments" tags="[Approx]" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="REQUIRE_NOTHROW" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          Approx(0).margin(0)
+        </Original>
+        <Expanded>
+          Approx(0).margin(0)
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE_NOTHROW" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          Approx(0).margin(1234656)
+        </Original>
+        <Expanded>
+          Approx(0).margin(1234656)
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE_THROWS_AS" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          Approx(0).margin(-2), std::domain_error
+        </Original>
+        <Expanded>
+          Approx(0).margin(-2), std::domain_error
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE_NOTHROW" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          Approx(0).epsilon(0)
+        </Original>
+        <Expanded>
+          Approx(0).epsilon(0)
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE_NOTHROW" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          Approx(0).epsilon(1)
+        </Original>
+        <Expanded>
+          Approx(0).epsilon(1)
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE_THROWS_AS" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          Approx(0).epsilon(-0.001), std::domain_error
+        </Original>
+        <Expanded>
+          Approx(0).epsilon(-0.001), std::domain_error
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE_THROWS_AS" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          Approx(0).epsilon(1.0001), std::domain_error
+        </Original>
+        <Expanded>
+          Approx(0).epsilon(1.0001), std::domain_error
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="Approx with exactly-representable margin" tags="[Approx]" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          0.25f == Approx(0.0f).margin(0.25f)
+        </Original>
+        <Expanded>
+          0.25f == Approx( 0.0 )
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          0.0f == Approx(0.25f).margin(0.25f)
+        </Original>
+        <Expanded>
+          0.0f == Approx( 0.25 )
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          0.5f == Approx(0.25f).margin(0.25f)
+        </Original>
+        <Expanded>
+          0.5f == Approx( 0.25 )
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          245.0f == Approx(245.25f).margin(0.25f)
+        </Original>
+        <Expanded>
+          245.0f == Approx( 245.25 )
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          245.5f == Approx(245.25f).margin(0.25f)
+        </Original>
+        <Expanded>
+          245.5f == Approx( 245.25 )
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="Approximate PI" tags="[Approx][PI]" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          divide( 22, 7 ) == Approx( 3.141 ).epsilon( 0.001 )
+        </Original>
+        <Expanded>
+          3.1428571429 == Approx( 3.141 )
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          divide( 22, 7 ) != Approx( 3.141 ).epsilon( 0.0001 )
+        </Original>
+        <Expanded>
+          3.1428571429 != Approx( 3.141 )
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="Approximate comparisons with different epsilons" tags="[Approx]" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          d != Approx( 1.231 )
+        </Original>
+        <Expanded>
+          1.23 != Approx( 1.231 )
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          d == Approx( 1.231 ).epsilon( 0.1 )
+        </Original>
+        <Expanded>
+          1.23 == Approx( 1.231 )
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="Approximate comparisons with floats" tags="[Approx]" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          1.23f == Approx( 1.23f )
+        </Original>
+        <Expanded>
+          1.23f == Approx( 1.2300000191 )
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          0.0f == Approx( 0.0f )
+        </Original>
+        <Expanded>
+          0.0f == Approx( 0.0 )
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="Approximate comparisons with ints" tags="[Approx]" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          1 == Approx( 1 )
+        </Original>
+        <Expanded>
+          1 == Approx( 1.0 )
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          0 == Approx( 0 )
+        </Original>
+        <Expanded>
+          0 == Approx( 0.0 )
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="Approximate comparisons with mixed numeric types" tags="[Approx]" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          1.0f == Approx( 1 )
+        </Original>
+        <Expanded>
+          1.0f == Approx( 1.0 )
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          0 == Approx( dZero)
+        </Original>
+        <Expanded>
+          0 == Approx( 0.0 )
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          0 == Approx( dSmall ).margin( 0.001 )
+        </Original>
+        <Expanded>
+          0 == Approx( 0.00001 )
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          1.234f == Approx( dMedium )
+        </Original>
+        <Expanded>
+          1.234f == Approx( 1.234 )
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          dMedium == Approx( 1.234f )
+        </Original>
+        <Expanded>
+          1.234 == Approx( 1.2339999676 )
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="Arbitrary predicate matcher" tags="[generic][matchers]" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+      <Section name="Function pointer" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            1, Predicate&lt;int>(alwaysTrue, "always true")
+          </Original>
+          <Expanded>
+            1 matches predicate: "always true"
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            1, !Predicate&lt;int>(alwaysFalse, "always false")
+          </Original>
+          <Expanded>
+            1 not matches predicate: "always false"
+          </Expanded>
+        </Expression>
+        <OverallResults successes="2" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="Lambdas + different type" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            "Hello olleH", Predicate&lt;std::string>( [] (std::string const&amp; str) -> bool { return str.front() == str.back(); }, "First and last character should be equal")
+          </Original>
+          <Expanded>
+            "Hello olleH" matches predicate: "First and last character should be equal"
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            "This wouldn't pass", !Predicate&lt;std::string>( [] (std::string const&amp; str) -> bool { return str.front() == str.back(); } )
+          </Original>
+          <Expanded>
+            "This wouldn't pass" not matches undescribed predicate
+          </Expanded>
+        </Expression>
+        <OverallResults successes="2" failures="0" expectedFailures="0"/>
+      </Section>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="Assertions then sections" tags="[Tricky]" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
+        <Original>
+          true
+        </Original>
+        <Expanded>
+          true
+        </Expanded>
+      </Expression>
+      <Section name="A section" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
+          <Original>
+            true
+          </Original>
+          <Expanded>
+            true
+          </Expanded>
+        </Expression>
+        <Section name="Another section" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
+          <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
+            <Original>
+              true
+            </Original>
+            <Expanded>
+              true
+            </Expanded>
+          </Expression>
+          <OverallResults successes="1" failures="0" expectedFailures="0"/>
+        </Section>
+        <OverallResults successes="2" failures="0" expectedFailures="0"/>
+      </Section>
       <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
         <Original>
           true
@@ -2172,38 +3026,245 @@
       </Expression>
       <OverallResult success="true"/>
     </TestCase>
-    <TestCase name="Floating point matchers: double" tags="[floating-point][matchers]" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+    <TestCase name="Floating point matchers: double" tags="[floating-point][matchers]" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+      <Section name="Margin" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            1., WithinAbs(1., 0)
+          </Original>
+          <Expanded>
+            1.0 is within 0.0 of 1.0
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            0., WithinAbs(1., 1)
+          </Original>
+          <Expanded>
+            0.0 is within 1.0 of 1.0
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            0., !WithinAbs(1., 0.99)
+          </Original>
+          <Expanded>
+            0.0 not is within 0.99 of 1.0
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            0., !WithinAbs(1., 0.99)
+          </Original>
+          <Expanded>
+            0.0 not is within 0.99 of 1.0
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            NAN, !WithinAbs(NAN, 0)
+          </Original>
+          <Expanded>
+            nanf not is within 0.0 of nan
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            11., !WithinAbs(10., 0.5)
+          </Original>
+          <Expanded>
+            11.0 not is within 0.5 of 10.0
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            10., !WithinAbs(11., 0.5)
+          </Original>
+          <Expanded>
+            10.0 not is within 0.5 of 11.0
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            -10., WithinAbs(-10., 0.5)
+          </Original>
+          <Expanded>
+            -10.0 is within 0.5 of -10.0
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            -10., WithinAbs(-9.6, 0.5)
+          </Original>
+          <Expanded>
+            -10.0 is within 0.5 of -9.6
+          </Expanded>
+        </Expression>
+        <OverallResults successes="9" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="ULPs" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            1., WithinULP(1., 0)
+          </Original>
+          <Expanded>
+            1.0 is within 0 ULPs of 1.0
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            nextafter(1., 2.), WithinULP(1., 1)
+          </Original>
+          <Expanded>
+            1.0 is within 1 ULPs of 1.0
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            nextafter(1., 0.), WithinULP(1., 1)
+          </Original>
+          <Expanded>
+            1.0 is within 1 ULPs of 1.0
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            nextafter(1., 2.), !WithinULP(1., 0)
+          </Original>
+          <Expanded>
+            1.0 not is within 0 ULPs of 1.0
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            1., WithinULP(1., 0)
+          </Original>
+          <Expanded>
+            1.0 is within 0 ULPs of 1.0
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            -0., WithinULP(0., 0)
+          </Original>
+          <Expanded>
+            -0.0 is within 0 ULPs of 0.0
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            NAN, !WithinULP(NAN, 123)
+          </Original>
+          <Expanded>
+            nanf not is within 123 ULPs of nanf
+          </Expanded>
+        </Expression>
+        <OverallResults successes="7" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="Composed" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            1., WithinAbs(1., 0.5) || WithinULP(2., 1)
+          </Original>
+          <Expanded>
+            1.0 ( is within 0.5 of 1.0 or is within 1 ULPs of 2.0 )
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            1., WithinAbs(2., 0.5) || WithinULP(1., 0)
+          </Original>
+          <Expanded>
+            1.0 ( is within 0.5 of 2.0 or is within 0 ULPs of 1.0 )
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            NAN, !(WithinAbs(NAN, 100) || WithinULP(NAN, 123))
+          </Original>
+          <Expanded>
+            nanf not ( is within 100.0 of nan or is within 123 ULPs of nanf )
+          </Expanded>
+        </Expression>
+        <OverallResults successes="3" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="Constructor validation" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="REQUIRE_NOTHROW" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            WithinAbs(1., 0.)
+          </Original>
+          <Expanded>
+            WithinAbs(1., 0.)
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THROWS_AS" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            WithinAbs(1., -1.), std::domain_error
+          </Original>
+          <Expanded>
+            WithinAbs(1., -1.), std::domain_error
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_NOTHROW" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            WithinULP(1., 0)
+          </Original>
+          <Expanded>
+            WithinULP(1., 0)
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THROWS_AS" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            WithinULP(1., -1), std::domain_error
+          </Original>
+          <Expanded>
+            WithinULP(1., -1), std::domain_error
+          </Expanded>
+        </Expression>
+        <OverallResults successes="4" failures="0" expectedFailures="0"/>
+      </Section>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="Floating point matchers: float" tags="[floating-point][matchers]" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
       <Section name="Margin" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            1., WithinAbs(1., 0)
+            1.f, WithinAbs(1.f, 0)
           </Original>
           <Expanded>
-            1.0 is within 0.0 of 1.0
+            1.0f is within 0.0 of 1.0
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            0., WithinAbs(1., 1)
+            0.f, WithinAbs(1.f, 1)
           </Original>
           <Expanded>
-            0.0 is within 1.0 of 1.0
+            0.0f is within 1.0 of 1.0
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            0., !WithinAbs(1., 0.99)
+            0.f, !WithinAbs(1.f, 0.99f)
           </Original>
           <Expanded>
-            0.0 not is within 0.99 of 1.0
+            0.0f not is within 0.9900000095 of 1.0
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            0., !WithinAbs(1., 0.99)
+            0.f, !WithinAbs(1.f, 0.99f)
           </Original>
           <Expanded>
-            0.0 not is within 0.99 of 1.0
+            0.0f not is within 0.9900000095 of 1.0
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            0.f, WithinAbs(-0.f, 0)
+          </Original>
+          <Expanded>
+            0.0f is within 0.0 of -0.0
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
@@ -2216,85 +3277,85 @@
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            11., !WithinAbs(10., 0.5)
+            11.f, !WithinAbs(10.f, 0.5f)
           </Original>
           <Expanded>
-            11.0 not is within 0.5 of 10.0
+            11.0f not is within 0.5 of 10.0
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            10., !WithinAbs(11., 0.5)
+            10.f, !WithinAbs(11.f, 0.5f)
           </Original>
           <Expanded>
-            10.0 not is within 0.5 of 11.0
+            10.0f not is within 0.5 of 11.0
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            -10., WithinAbs(-10., 0.5)
+            -10.f, WithinAbs(-10.f, 0.5f)
           </Original>
           <Expanded>
-            -10.0 is within 0.5 of -10.0
+            -10.0f is within 0.5 of -10.0
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            -10., WithinAbs(-9.6, 0.5)
+            -10.f, WithinAbs(-9.6f, 0.5f)
           </Original>
           <Expanded>
-            -10.0 is within 0.5 of -9.6
+            -10.0f is within 0.5 of -9.6000003815
           </Expanded>
         </Expression>
-        <OverallResults successes="9" failures="0" expectedFailures="0"/>
+        <OverallResults successes="10" failures="0" expectedFailures="0"/>
       </Section>
       <Section name="ULPs" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            1., WithinULP(1., 0)
+            1.f, WithinULP(1.f, 0)
           </Original>
           <Expanded>
-            1.0 is within 0 ULPs of 1.0
+            1.0f is within 0 ULPs of 1.0f
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            nextafter(1., 2.), WithinULP(1., 1)
+            nextafter(1.f, 2.f), WithinULP(1.f, 1)
           </Original>
           <Expanded>
-            1.0 is within 1 ULPs of 1.0
+            1.0f is within 1 ULPs of 1.0f
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            nextafter(1., 0.), WithinULP(1., 1)
+            nextafter(1.f, 0.f), WithinULP(1.f, 1)
           </Original>
           <Expanded>
-            1.0 is within 1 ULPs of 1.0
+            1.0f is within 1 ULPs of 1.0f
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            nextafter(1., 2.), !WithinULP(1., 0)
+            nextafter(1.f, 2.f), !WithinULP(1.f, 0)
           </Original>
           <Expanded>
-            1.0 not is within 0 ULPs of 1.0
+            1.0f not is within 0 ULPs of 1.0f
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            1., WithinULP(1., 0)
+            1.f, WithinULP(1.f, 0)
           </Original>
           <Expanded>
-            1.0 is within 0 ULPs of 1.0
+            1.0f is within 0 ULPs of 1.0f
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            -0., WithinULP(0., 0)
+            -0.f, WithinULP(0.f, 0)
           </Original>
           <Expanded>
-            -0.0 is within 0 ULPs of 0.0
+            -0.0f is within 0 ULPs of 0.0f
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
@@ -2310,18 +3371,18 @@
       <Section name="Composed" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            1., WithinAbs(1., 0.5) || WithinULP(2., 1)
+            1.f, WithinAbs(1.f, 0.5) || WithinULP(1.f, 1)
           </Original>
           <Expanded>
-            1.0 ( is within 0.5 of 1.0 or is within 1 ULPs of 2.0 )
+            1.0f ( is within 0.5 of 1.0 or is within 1 ULPs of 1.0f )
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            1., WithinAbs(2., 0.5) || WithinULP(1., 0)
+            1.f, WithinAbs(2.f, 0.5) || WithinULP(1.f, 0)
           </Original>
           <Expanded>
-            1.0 ( is within 0.5 of 2.0 or is within 0 ULPs of 1.0 )
+            1.0f ( is within 0.5 of 2.0 or is within 0 ULPs of 1.0f )
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
@@ -2337,244 +3398,415 @@
       <Section name="Constructor validation" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
         <Expression success="true" type="REQUIRE_NOTHROW" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            WithinAbs(1., 0.)
+            WithinAbs(1.f, 0.f)
           </Original>
           <Expanded>
-            WithinAbs(1., 0.)
+            WithinAbs(1.f, 0.f)
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THROWS_AS" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            WithinAbs(1., -1.), std::domain_error
+            WithinAbs(1.f, -1.f), std::domain_error
           </Original>
           <Expanded>
-            WithinAbs(1., -1.), std::domain_error
+            WithinAbs(1.f, -1.f), std::domain_error
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_NOTHROW" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            WithinULP(1., 0)
+            WithinULP(1.f, 0)
           </Original>
           <Expanded>
-            WithinULP(1., 0)
+            WithinULP(1.f, 0)
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THROWS_AS" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            WithinULP(1., -1), std::domain_error
+            WithinULP(1.f, -1), std::domain_error
           </Original>
           <Expanded>
-            WithinULP(1., -1), std::domain_error
+            WithinULP(1.f, -1), std::domain_error
           </Expanded>
         </Expression>
         <OverallResults successes="4" failures="0" expectedFailures="0"/>
       </Section>
       <OverallResult success="true"/>
     </TestCase>
-    <TestCase name="Floating point matchers: float" tags="[floating-point][matchers]" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
-      <Section name="Margin" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+    <TestCase name="Generators" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+      <Section name="one" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Info>
+          i := "a"
+        </Info>
+        <Info>
+          j := 8
+        </Info>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="one" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Info>
+          i := "a"
+        </Info>
+        <Info>
+          j := 9
+        </Info>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="one" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Info>
+          i := "a"
+        </Info>
+        <Info>
+          j := 10
+        </Info>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="one" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Info>
+          i := "a"
+        </Info>
+        <Info>
+          j := 2
+        </Info>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="two" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Info>
+          i := "a"
+        </Info>
+        <Info>
+          j := 3.141
+        </Info>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="two" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Info>
+          i := "a"
+        </Info>
+        <Info>
+          j := 1.379
+        </Info>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="one" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Info>
+          i := "b"
+        </Info>
+        <Info>
+          j := 8
+        </Info>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="one" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Info>
+          i := "b"
+        </Info>
+        <Info>
+          j := 9
+        </Info>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="one" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Info>
+          i := "b"
+        </Info>
+        <Info>
+          j := 10
+        </Info>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="one" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Info>
+          i := "b"
+        </Info>
+        <Info>
+          j := 2
+        </Info>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="two" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Info>
+          i := "b"
+        </Info>
+        <Info>
+          j := 3.141
+        </Info>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="two" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Info>
+          i := "b"
+        </Info>
+        <Info>
+          j := 1.379
+        </Info>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="one" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Info>
+          i := "c"
+        </Info>
+        <Info>
+          j := 8
+        </Info>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="one" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Info>
+          i := "c"
+        </Info>
+        <Info>
+          j := 9
+        </Info>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="one" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Info>
+          i := "c"
+        </Info>
+        <Info>
+          j := 10
+        </Info>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="one" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Info>
+          i := "c"
+        </Info>
+        <Info>
+          j := 2
+        </Info>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="two" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Info>
+          i := "c"
+        </Info>
+        <Info>
+          j := 3.141
+        </Info>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="two" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Info>
+          i := "c"
+        </Info>
+        <Info>
+          j := 1.379
+        </Info>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="Generators impl" tags="[impl]" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+      <Section name="range" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            1.f, WithinAbs(1.f, 0)
+            gen.size() == 2
           </Original>
           <Expanded>
-            1.0f is within 0.0 of 1.0
+            2 == 2
           </Expanded>
         </Expression>
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            0.f, WithinAbs(1.f, 1)
+            gen[0] == 1
           </Original>
           <Expanded>
-            0.0f is within 1.0 of 1.0
+            1 == 1
           </Expanded>
         </Expression>
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            0.f, !WithinAbs(1.f, 0.99f)
+            gen[1] == 2
           </Original>
           <Expanded>
-            0.0f not is within 0.9900000095 of 1.0
+            2 == 2
           </Expanded>
         </Expression>
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <OverallResults successes="3" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="fixed values" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            0.f, !WithinAbs(1.f, 0.99f)
+            gen.size() == 4
           </Original>
           <Expanded>
-            0.0f not is within 0.9900000095 of 1.0
+            4 == 4
           </Expanded>
         </Expression>
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            0.f, WithinAbs(-0.f, 0)
+            gen[0] == 3
           </Original>
           <Expanded>
-            0.0f is within 0.0 of -0.0
+            3 == 3
           </Expanded>
         </Expression>
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            NAN, !WithinAbs(NAN, 0)
+            gen[1] == 1
           </Original>
           <Expanded>
-            nanf not is within 0.0 of nan
+            1 == 1
           </Expanded>
         </Expression>
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            11.f, !WithinAbs(10.f, 0.5f)
+            gen[2] == 4
           </Original>
           <Expanded>
-            11.0f not is within 0.5 of 10.0
+            4 == 4
           </Expanded>
         </Expression>
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            10.f, !WithinAbs(11.f, 0.5f)
+            gen[3] == 1
           </Original>
           <Expanded>
-            10.0f not is within 0.5 of 11.0
+            1 == 1
           </Expanded>
         </Expression>
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <OverallResults successes="5" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="combined" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            -10.f, WithinAbs(-10.f, 0.5f)
+            gen.size() == 4
           </Original>
           <Expanded>
-            -10.0f is within 0.5 of -10.0
+            4 == 4
           </Expanded>
         </Expression>
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            -10.f, WithinAbs(-9.6f, 0.5f)
+            gen[0] == 1
           </Original>
           <Expanded>
-            -10.0f is within 0.5 of -9.6000003815
+            1 == 1
           </Expanded>
         </Expression>
-        <OverallResults successes="10" failures="0" expectedFailures="0"/>
-      </Section>
-      <Section name="ULPs" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            1.f, WithinULP(1.f, 0)
+            gen[1] == 2
           </Original>
           <Expanded>
-            1.0f is within 0 ULPs of 1.0f
+            2 == 2
           </Expanded>
         </Expression>
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            nextafter(1.f, 2.f), WithinULP(1.f, 1)
+            gen[2] == 9
           </Original>
           <Expanded>
-            1.0f is within 1 ULPs of 1.0f
+            9 == 9
           </Expanded>
         </Expression>
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            nextafter(1.f, 0.f), WithinULP(1.f, 1)
+            gen[3] == 7
           </Original>
           <Expanded>
-            1.0f is within 1 ULPs of 1.0f
+            7 == 7
           </Expanded>
         </Expression>
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <OverallResults successes="5" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="values" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            nextafter(1.f, 2.f), !WithinULP(1.f, 0)
+            gen.size() == 2
           </Original>
           <Expanded>
-            1.0f not is within 0 ULPs of 1.0f
+            2 == 2
           </Expanded>
         </Expression>
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            1.f, WithinULP(1.f, 0)
+            gen[0] == 3
           </Original>
           <Expanded>
-            1.0f is within 0 ULPs of 1.0f
+            3 == 3
           </Expanded>
         </Expression>
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            -0.f, WithinULP(0.f, 0)
+            gen[1] == 1
           </Original>
           <Expanded>
-            -0.0f is within 0 ULPs of 0.0f
+            1 == 1
           </Expanded>
         </Expression>
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <OverallResults successes="3" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="values2" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            NAN, !WithinULP(NAN, 123)
+            gen.size() == 2
           </Original>
           <Expanded>
-            nanf not is within 123 ULPs of nanf
+            2 == 2
           </Expanded>
         </Expression>
-        <OverallResults successes="7" failures="0" expectedFailures="0"/>
-      </Section>
-      <Section name="Composed" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            1.f, WithinAbs(1.f, 0.5) || WithinULP(1.f, 1)
+            gen[0] == 3
           </Original>
           <Expanded>
-            1.0f ( is within 0.5 of 1.0 or is within 1 ULPs of 1.0f )
+            3 == 3
           </Expanded>
         </Expression>
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            1.f, WithinAbs(2.f, 0.5) || WithinULP(1.f, 0)
+            gen[1] == 1
           </Original>
           <Expanded>
-            1.0f ( is within 0.5 of 2.0 or is within 0 ULPs of 1.0f )
+            1 == 1
           </Expanded>
         </Expression>
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <OverallResults successes="3" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="type erasure" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            NAN, !(WithinAbs(NAN, 100) || WithinULP(NAN, 123))
+            base->size() == 4
           </Original>
           <Expanded>
-            nanf not ( is within 100.0 of nan or is within 123 ULPs of nanf )
+            4 == 4
           </Expanded>
         </Expression>
-        <OverallResults successes="3" failures="0" expectedFailures="0"/>
-      </Section>
-      <Section name="Constructor validation" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
-        <Expression success="true" type="REQUIRE_NOTHROW" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            WithinAbs(1.f, 0.f)
+            typed
           </Original>
           <Expanded>
-            WithinAbs(1.f, 0.f)
+            0x<hex digits>
           </Expanded>
         </Expression>
-        <Expression success="true" type="REQUIRE_THROWS_AS" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            WithinAbs(1.f, -1.f), std::domain_error
+            typed->size() == 4
           </Original>
           <Expanded>
-            WithinAbs(1.f, -1.f), std::domain_error
+            4 == 4
           </Expanded>
         </Expression>
-        <Expression success="true" type="REQUIRE_NOTHROW" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            WithinULP(1.f, 0)
+            (*typed)[0] == 7
           </Original>
           <Expanded>
-            WithinULP(1.f, 0)
+            7 == 7
           </Expanded>
         </Expression>
-        <Expression success="true" type="REQUIRE_THROWS_AS" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            WithinULP(1.f, -1), std::domain_error
+            (*typed)[3] == 11
           </Original>
           <Expanded>
-            WithinULP(1.f, -1), std::domain_error
+            11 == 11
           </Expanded>
         </Expression>
-        <OverallResults successes="4" failures="0" expectedFailures="0"/>
+        <OverallResults successes="5" failures="0" expectedFailures="0"/>
       </Section>
       <OverallResult success="true"/>
     </TestCase>
@@ -4650,17 +5882,6 @@
       </Section>
       <OverallResult success="true"/>
     </TestCase>
-    <TestCase name="Parsing a std::pair" tags="[Tricky][std::pair]" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
-        <Original>
-          (std::pair&lt;int, int>( 1, 2 )) == aNicePair
-        </Original>
-        <Expanded>
-          {?} == {?}
-        </Expanded>
-      </Expression>
-      <OverallResult success="true"/>
-    </TestCase>
     <TestCase name="Pointers can be compared to null" filename="projects/<exe-name>/UsageTests/Condition.tests.cpp" >
       <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Condition.tests.cpp" >
         <Original>
@@ -4808,7 +6029,7 @@
         <OverallResults successes="7" failures="0" expectedFailures="0"/>
       </Section>
       <Section name="test lists" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
-        <Section name="1 test" description="Specify one test case using" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
+        <Section name="Specify one test case using" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
           <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
             <Original>
               result
@@ -5387,6 +6608,17 @@
       </Expression>
       <OverallResult success="false"/>
     </TestCase>
+    <TestCase name="Regression test #1" tags="[matchers][vector]" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+      <Expression success="true" type="CHECK_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Original>
+          actual, !UnorderedEquals(expected)
+        </Original>
+        <Expanded>
+          { 'a', 'b' } not UnorderedEquals: { 'c', 'b' }
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
     <TestCase name="SUCCEED counts as a test pass" tags="[messages]" filename="projects/<exe-name>/UsageTests/Message.tests.cpp" >
       <OverallResult success="true"/>
     </TestCase>
@@ -5423,26 +6655,29 @@
     </TestCase>
     <TestCase name="Scenario: Do that thing with the thing" tags="[Tags]" filename="projects/<exe-name>/UsageTests/BDD.tests.cpp" >
       <Section name="Given: This stuff exists" filename="projects/<exe-name>/UsageTests/BDD.tests.cpp" >
-        <Section name="When: I do this" filename="projects/<exe-name>/UsageTests/BDD.tests.cpp" >
-          <Section name="Then: it should do this" filename="projects/<exe-name>/UsageTests/BDD.tests.cpp" >
-            <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/BDD.tests.cpp" >
-              <Original>
-                itDoesThis()
-              </Original>
-              <Expanded>
-                true
-              </Expanded>
-            </Expression>
-            <Section name="And: do that" filename="projects/<exe-name>/UsageTests/BDD.tests.cpp" >
+        <Section name="And given: And some assumption" filename="projects/<exe-name>/UsageTests/BDD.tests.cpp" >
+          <Section name="When: I do this" filename="projects/<exe-name>/UsageTests/BDD.tests.cpp" >
+            <Section name="Then: it should do this" filename="projects/<exe-name>/UsageTests/BDD.tests.cpp" >
               <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/BDD.tests.cpp" >
                 <Original>
-                  itDoesThat()
+                  itDoesThis()
                 </Original>
                 <Expanded>
                   true
                 </Expanded>
               </Expression>
-              <OverallResults successes="1" failures="0" expectedFailures="0"/>
+              <Section name="And: do that" filename="projects/<exe-name>/UsageTests/BDD.tests.cpp" >
+                <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/BDD.tests.cpp" >
+                  <Original>
+                    itDoesThat()
+                  </Original>
+                  <Expanded>
+                    true
+                  </Expanded>
+                </Expression>
+                <OverallResults successes="1" failures="0" expectedFailures="0"/>
+              </Section>
+              <OverallResults successes="2" failures="0" expectedFailures="0"/>
             </Section>
             <OverallResults successes="2" failures="0" expectedFailures="0"/>
           </Section>
@@ -5591,6 +6826,22 @@ A string sent to stderr via clog
           1.23 != Approx( 1.24 )
         </Expanded>
       </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          d == 1.23_a
+        </Original>
+        <Expanded>
+          1.23 == Approx( 1.23 )
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          d != 1.22_a
+        </Original>
+        <Expanded>
+          1.23 != Approx( 1.22 )
+        </Expanded>
+      </Expression>
       <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
         <Original>
           Approx( d ) == 1.23
@@ -8691,7 +9942,7 @@ loose text artifact
       <OverallResult success="true"/>
     </TestCase>
     <TestCase name="looped SECTION tests" tags="[.][failing][sections]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
-      <Section name="s1" description="b is currently: 0" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+      <Section name="b is currently: 0" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
         <Expression success="false" type="CHECK" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
           <Original>
             b > a
@@ -8702,6 +9953,105 @@ loose text artifact
         </Expression>
         <OverallResults successes="0" failures="1" expectedFailures="0"/>
       </Section>
+      <Section name="b is currently: 1" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Expression success="false" type="CHECK" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            b > a
+          </Original>
+          <Expanded>
+            1 > 1
+          </Expanded>
+        </Expression>
+        <OverallResults successes="0" failures="1" expectedFailures="0"/>
+      </Section>
+      <Section name="b is currently: 2" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            b > a
+          </Original>
+          <Expanded>
+            2 > 1
+          </Expanded>
+        </Expression>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="b is currently: 3" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            b > a
+          </Original>
+          <Expanded>
+            3 > 1
+          </Expanded>
+        </Expression>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="b is currently: 4" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            b > a
+          </Original>
+          <Expanded>
+            4 > 1
+          </Expanded>
+        </Expression>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="b is currently: 5" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            b > a
+          </Original>
+          <Expanded>
+            5 > 1
+          </Expanded>
+        </Expression>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="b is currently: 6" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            b > a
+          </Original>
+          <Expanded>
+            6 > 1
+          </Expanded>
+        </Expression>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="b is currently: 7" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            b > a
+          </Original>
+          <Expanded>
+            7 > 1
+          </Expanded>
+        </Expression>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="b is currently: 8" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            b > a
+          </Original>
+          <Expanded>
+            8 > 1
+          </Expanded>
+        </Expression>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="b is currently: 9" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            b > a
+          </Original>
+          <Expanded>
+            9 > 1
+          </Expanded>
+        </Expression>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
       <OverallResult success="false"/>
     </TestCase>
     <TestCase name="looped tests" tags="[.][failing]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
@@ -8796,8 +10146,8 @@ loose text artifact
       <OverallResult success="false"/>
     </TestCase>
     <TestCase name="more nested SECTION tests" tags="[.][failing][sections]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
-      <Section name="s1" description="doesn't equal" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
-        <Section name="s2" description="equal" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+      <Section name="doesn't equal" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Section name="equal" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
           <Expression success="false" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
             <Original>
               a == b
@@ -8810,8 +10160,8 @@ loose text artifact
         </Section>
         <OverallResults successes="0" failures="1" expectedFailures="0"/>
       </Section>
-      <Section name="s1" description="doesn't equal" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
-        <Section name="s3" description="not equal" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+      <Section name="doesn't equal" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Section name="not equal" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
           <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
             <Original>
               a != b
@@ -8824,8 +10174,8 @@ loose text artifact
         </Section>
         <OverallResults successes="1" failures="0" expectedFailures="0"/>
       </Section>
-      <Section name="s1" description="doesn't equal" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
-        <Section name="s4" description="less than" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+      <Section name="doesn't equal" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Section name="less than" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
           <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
             <Original>
               a &lt; b
@@ -8841,7 +10191,7 @@ loose text artifact
       <OverallResult success="false"/>
     </TestCase>
     <TestCase name="nested SECTION tests" tags="[.][failing][sections]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
-      <Section name="s1" description="doesn't equal" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+      <Section name="doesn't equal" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
         <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
           <Original>
             a != b
@@ -8858,7 +10208,7 @@ loose text artifact
             2 != 1
           </Expanded>
         </Expression>
-        <Section name="s2" description="not equal" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Section name="not equal" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
           <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
             <Original>
               a != b
@@ -8953,7 +10303,7 @@ loose text artifact
       <OverallResult success="true"/>
     </TestCase>
     <TestCase name="random SECTION tests" tags="[.][failing][sections]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
-      <Section name="s1" description="doesn't equal" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+      <Section name="doesn't equal" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
         <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
           <Original>
             a != b
@@ -8972,7 +10322,7 @@ loose text artifact
         </Expression>
         <OverallResults successes="2" failures="0" expectedFailures="0"/>
       </Section>
-      <Section name="s2" description="not equal" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+      <Section name="not equal" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
         <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
           <Original>
             a != b
@@ -9418,6 +10768,41 @@ loose text artifact
       </Expression>
       <OverallResult success="true"/>
     </TestCase>
+    <TestCase name="strlen3" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          data.str.size() == data.len
+        </Original>
+        <Expanded>
+          3 == 3
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          data.str.size() == data.len
+        </Original>
+        <Expanded>
+          3 == 3
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          data.str.size() == data.len
+        </Original>
+        <Expanded>
+          5 == 5
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          data.str.size() == data.len
+        </Original>
+        <Expanded>
+          4 == 4
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
     <TestCase name="thrown std::strings are translated" tags="[!throws][.][failing]" filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" >
       <Exception filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" >
         Why would you throw a std::string?
@@ -9928,15 +11313,15 @@ loose text artifact
       <OverallResult success="true"/>
     </TestCase>
     <TestCase name="xmlentitycheck" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
-      <Section name="embedded xml" description="&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>" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+      <Section name="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>" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
         <OverallResults successes="1" failures="0" expectedFailures="0"/>
       </Section>
-      <Section name="encoded chars" description="these should all be encoded: &amp;&amp;&amp;&quot;&quot;&quot;&lt;&lt;&lt;&amp;&quot;&lt;&lt;&amp;&quot;" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+      <Section name="encoded chars: these should all be encoded: &amp;&amp;&amp;&quot;&quot;&quot;&lt;&lt;&lt;&amp;&quot;&lt;&lt;&amp;&quot;" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
         <OverallResults successes="1" failures="0" expectedFailures="0"/>
       </Section>
       <OverallResult success="true"/>
     </TestCase>
-    <OverallResults successes="937" failures="122" expectedFailures="21"/>
+    <OverallResults successes="1099" failures="123" expectedFailures="21"/>
   </Group>
-  <OverallResults successes="937" failures="121" expectedFailures="21"/>
+  <OverallResults successes="1099" failures="122" expectedFailures="21"/>
 </Catch>
diff --git a/packages/Catch2/projects/SelfTest/IntrospectiveTests/CmdLine.tests.cpp b/packages/Catch2/projects/SelfTest/IntrospectiveTests/CmdLine.tests.cpp
index 1da3fa084..cb635eade 100644
--- a/packages/Catch2/projects/SelfTest/IntrospectiveTests/CmdLine.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/IntrospectiveTests/CmdLine.tests.cpp
@@ -295,7 +295,7 @@ TEST_CASE( "Process can be configured on command line", "[config][command-line]"
     }
 
     SECTION("test lists") {
-        SECTION("1 test", "Specify one test case using") {
+        SECTION("Specify one test case using") {
             auto result = cli.parse({"test", "test1"});
             CHECK(result);
 
diff --git a/packages/Catch2/projects/SelfTest/IntrospectiveTests/GeneratorsImpl.tests.cpp b/packages/Catch2/projects/SelfTest/IntrospectiveTests/GeneratorsImpl.tests.cpp
new file mode 100644
index 000000000..b3074b2e1
--- /dev/null
+++ b/packages/Catch2/projects/SelfTest/IntrospectiveTests/GeneratorsImpl.tests.cpp
@@ -0,0 +1,93 @@
+#include "catch.hpp"
+
+// Tests of generartor implementation details
+
+TEST_CASE("Generators impl", "[impl]") {
+    using namespace Catch::Generators;
+
+    SECTION( "range" ) {
+        auto gen = range(1,3);
+
+        CHECK( gen.size() == 2 );
+
+        CHECK( gen[0] == 1 );
+        CHECK( gen[1] == 2 );
+    }
+    SECTION( "fixed values" ) {
+        auto gen = values( { 3, 1, 4, 1 } );
+
+        CHECK( gen.size() == 4 );
+        CHECK( gen[0] == 3 );
+        CHECK( gen[1] == 1 );
+        CHECK( gen[2] == 4 );
+        CHECK( gen[3] == 1 );
+    }
+    SECTION( "combined" ) {
+        auto gen = makeGenerators( range( 1, 3 ), values( { 9, 7 } ) );
+
+        CHECK( gen.size() == 4 );
+        CHECK( gen[0] == 1 );
+        CHECK( gen[1] == 2 );
+        CHECK( gen[2] == 9 );
+        CHECK( gen[3] == 7 );
+    }
+
+    SECTION( "values" ) {
+        auto gen = makeGenerators( 3, 1 );
+
+        CHECK( gen.size() == 2 );
+        CHECK( gen[0] == 3 );
+        CHECK( gen[1] == 1 );
+    }
+    SECTION( "values2" ) {
+        auto gen = makeGenerators( 3, 1 );
+
+        CHECK( gen.size() == 2 );
+        CHECK( gen[0] == 3 );
+        CHECK( gen[1] == 1 );
+    }
+
+
+    SECTION( "type erasure" ) {
+        auto gen = makeGenerators( range( 7, 10 ), 11 );
+
+        // Make type erased version
+        auto dynCopy = pf::make_unique<Generators<int>>( std::move( gen ) );
+        std::unique_ptr<GeneratorBase const> base = std::move( dynCopy );
+
+        // Only thing we can do is ask for the size
+        CHECK( base->size() == 4 );
+
+        // Restore typed version
+        auto typed = dynamic_cast<Generators<int> const*>( base.get() );
+        REQUIRE( typed );
+        CHECK( typed->size() == 4 );
+        CHECK( (*typed)[0] == 7 );
+        CHECK( (*typed)[3] == 11 );
+    }
+}
+
+TEST_CASE("Generators impl - random", "[approvals]") {
+    using namespace Catch::Generators;
+
+    SECTION( "random range" ) {
+        auto gen = random( 3, 9 );
+
+        CHECK( gen.size() == 6 );
+        for( size_t i = 0; i < 6; ++i ) {
+            CHECK( gen[i] >= 3 );
+            CHECK( gen[i] <= 8 );
+            if( i > 0 )
+                CHECK( gen[i] != gen[i-1] );
+        }
+    }
+    SECTION( "random selection" ) {
+        auto gen = random<int>( 10 );
+
+        CHECK( gen.size() == 10 );
+        for( size_t i = 0; i < 10; ++i ) {
+            if( i > 0 )
+                CHECK( gen[i] != gen[i-1] );
+        }
+    }
+}
diff --git a/packages/Catch2/projects/SelfTest/IntrospectiveTests/PartTracker.tests.cpp b/packages/Catch2/projects/SelfTest/IntrospectiveTests/PartTracker.tests.cpp
index 042c03a71..7e7f14b45 100644
--- a/packages/Catch2/projects/SelfTest/IntrospectiveTests/PartTracker.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/IntrospectiveTests/PartTracker.tests.cpp
@@ -21,24 +21,17 @@ namespace Catch
 
 } // namespace Catch
 
-inline Catch::TrackerContext& C_A_T_C_H_Context() {
-    return Catch::TrackerContext::instance();
-}
-
 // -------------------
 
 #include "catch.hpp"
 
 using namespace Catch;
 
-//inline void testCase( Catch::LocalContext const& C_A_T_C_H_Context ) {
-//
-//    REQUIRE( C_A_T_C_H_Context().i() == 42 );
-//}
-
+namespace {
 Catch::TestCaseTracking::NameAndLocation makeNAL( std::string const& name ) {
     return Catch::TestCaseTracking::NameAndLocation( name, Catch::SourceLineInfo("",0) );
 }
+}
 
 TEST_CASE( "Tracker" ) {
 
diff --git a/packages/Catch2/projects/SelfTest/IntrospectiveTests/String.tests.cpp b/packages/Catch2/projects/SelfTest/IntrospectiveTests/String.tests.cpp
index ee6e4c58e..ae21bb3ce 100644
--- a/packages/Catch2/projects/SelfTest/IntrospectiveTests/String.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/IntrospectiveTests/String.tests.cpp
@@ -16,23 +16,22 @@ namespace Catch {
         }
     };
 
+
+    namespace {
     auto isOwned( StringRef const& stringRef ) -> bool {
         return StringRefTestAccess::isOwned( stringRef );
     }
     auto isSubstring( StringRef const& stringRef ) -> bool {
         return StringRefTestAccess::isSubstring( stringRef );
     }
-} // namespace Catch2
+    } // end anonymous namespace
 
-namespace Catch {
-    inline auto toString( Catch::StringRef const& stringRef ) -> std::string {
-        return std::string( stringRef.currentData(), stringRef.size() );
-    }
 } // namespace Catch
 
 TEST_CASE( "StringRef", "[Strings][StringRef]" ) {
 
     using Catch::StringRef;
+    using Catch::isOwned; using Catch::isSubstring;
 
     SECTION( "Empty string" ) {
         StringRef empty;
diff --git a/packages/Catch2/projects/SelfTest/UsageTests/Approx.tests.cpp b/packages/Catch2/projects/SelfTest/UsageTests/Approx.tests.cpp
index 5930075d1..b95394a06 100644
--- a/packages/Catch2/projects/SelfTest/UsageTests/Approx.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/UsageTests/Approx.tests.cpp
@@ -33,8 +33,21 @@ namespace { namespace ApproxTests {
 
 #endif
 
+using namespace Catch::literals;
 
 ///////////////////////////////////////////////////////////////////////////////
+TEST_CASE( "A comparison that uses literals instead of the normal constructor", "[Approx]" ) {
+    double d = 1.23;
+
+    REQUIRE( d == 1.23_a );
+    REQUIRE( d != 1.22_a );
+    REQUIRE( -d == -1.23_a );
+
+    REQUIRE( d == 1.2_a .epsilon(.1) );
+    REQUIRE( d != 1.2_a .epsilon(.001) );
+    REQUIRE( d == 1_a .epsilon(.3) );
+}
+
 TEST_CASE( "Some simple comparisons between doubles", "[Approx]" ) {
     double d = 1.23;
 
@@ -42,6 +55,9 @@ TEST_CASE( "Some simple comparisons between doubles", "[Approx]" ) {
     REQUIRE( d != Approx( 1.22 ) );
     REQUIRE( d != Approx( 1.24 ) );
 
+    REQUIRE( d == 1.23_a );
+    REQUIRE( d != 1.22_a );
+
     REQUIRE( Approx( d ) == 1.23 );
     REQUIRE( Approx( d ) != 1.22 );
     REQUIRE( Approx( d ) != 1.24 );
diff --git a/packages/Catch2/projects/SelfTest/UsageTests/BDD.tests.cpp b/packages/Catch2/projects/SelfTest/UsageTests/BDD.tests.cpp
index f43fd96dc..d0d3e0387 100644
--- a/packages/Catch2/projects/SelfTest/UsageTests/BDD.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/UsageTests/BDD.tests.cpp
@@ -38,11 +38,14 @@ namespace { namespace BDDTests {
     SCENARIO("Do that thing with the thing", "[Tags]") {
         GIVEN("This stuff exists") {
             // make stuff exist
-            WHEN("I do this") {
-                // do this
-                THEN("it should do this") {
-                    REQUIRE(itDoesThis());
-                    AND_THEN("do that")REQUIRE(itDoesThat());
+            AND_GIVEN("And some assumption") {
+                // Validate assumption
+                WHEN("I do this") {
+                    // do this
+                    THEN("it should do this") {
+                        REQUIRE(itDoesThis());
+                        AND_THEN("do that")REQUIRE(itDoesThat());
+                    }
                 }
             }
         }
diff --git a/packages/Catch2/projects/SelfTest/UsageTests/Decomposition.tests.cpp b/packages/Catch2/projects/SelfTest/UsageTests/Decomposition.tests.cpp
index 1b44b602e..5bb19cd6d 100644
--- a/packages/Catch2/projects/SelfTest/UsageTests/Decomposition.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/UsageTests/Decomposition.tests.cpp
@@ -9,6 +9,8 @@
 #include <iostream>
 #include <cstdio>
 
+namespace {
+
 struct truthy {
     truthy(bool b):m_value(b){}
     operator bool() const {
@@ -22,6 +24,8 @@ std::ostream& operator<<(std::ostream& o, truthy) {
     return o;
 }
 
+} // end anonymous namespace
+
 #include "catch.hpp"
 
 TEST_CASE( "Reconstruction should be based on stringification: #914" , "[Decomposition][failing][.]") {
diff --git a/packages/Catch2/projects/SelfTest/UsageTests/EnumToString.tests.cpp b/packages/Catch2/projects/SelfTest/UsageTests/EnumToString.tests.cpp
index 7d18a292c..0b188a826 100644
--- a/packages/Catch2/projects/SelfTest/UsageTests/EnumToString.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/UsageTests/EnumToString.tests.cpp
@@ -1,22 +1,24 @@
 #include "catch.hpp"
 
 
+namespace {
 // Enum without user-provided stream operator
 enum Enum1 { Enum1Value0, Enum1Value1 };
 
-TEST_CASE( "toString(enum)", "[toString][enum]" ) {
-    Enum1 e0 = Enum1Value0;
-    CHECK( ::Catch::Detail::stringify(e0) == "0" );
-    Enum1 e1 = Enum1Value1;
-    CHECK( ::Catch::Detail::stringify(e1) == "1" );
-}
-
 // Enum with user-provided stream operator
 enum Enum2 { Enum2Value0, Enum2Value1 };
 
 std::ostream& operator<<( std::ostream& os, Enum2 v ) {
     return os << "E2{" << static_cast<int>(v) << "}";
 }
+} // end anonymous namespace
+
+TEST_CASE( "toString(enum)", "[toString][enum]" ) {
+    Enum1 e0 = Enum1Value0;
+    CHECK( ::Catch::Detail::stringify(e0) == "0" );
+    Enum1 e1 = Enum1Value1;
+    CHECK( ::Catch::Detail::stringify(e1) == "1" );
+}
 
 TEST_CASE( "toString(enum w/operator<<)", "[toString][enum]" ) {
     Enum2 e0 = Enum2Value0;
@@ -26,17 +28,11 @@ TEST_CASE( "toString(enum w/operator<<)", "[toString][enum]" ) {
 }
 
 // Enum class without user-provided stream operator
+namespace {
 enum class EnumClass1 { EnumClass1Value0, EnumClass1Value1 };
 
-TEST_CASE( "toString(enum class)", "[toString][enum][enumClass]" ) {
-    EnumClass1 e0 = EnumClass1::EnumClass1Value0;
-    CHECK( ::Catch::Detail::stringify(e0) == "0" );
-    EnumClass1 e1 = EnumClass1::EnumClass1Value1;
-    CHECK( ::Catch::Detail::stringify(e1) == "1" );
-}
-
 // Enum class with user-provided stream operator
-enum class EnumClass2 : short { EnumClass2Value0, EnumClass2Value1 };
+enum class EnumClass2 { EnumClass2Value0, EnumClass2Value1 };
 
 std::ostream& operator<<( std::ostream& os, EnumClass2 e2 ) {
     switch( static_cast<int>( e2 ) ) {
@@ -49,6 +45,16 @@ std::ostream& operator<<( std::ostream& os, EnumClass2 e2 ) {
     }
 }
 
+} // end anonymous namespace
+
+TEST_CASE( "toString(enum class)", "[toString][enum][enumClass]" ) {
+    EnumClass1 e0 = EnumClass1::EnumClass1Value0;
+    CHECK( ::Catch::Detail::stringify(e0) == "0" );
+    EnumClass1 e1 = EnumClass1::EnumClass1Value1;
+    CHECK( ::Catch::Detail::stringify(e1) == "1" );
+}
+
+
 TEST_CASE( "toString(enum class w/operator<<)", "[toString][enum][enumClass]" ) {
     EnumClass2 e0 = EnumClass2::EnumClass2Value0;
     CHECK( ::Catch::Detail::stringify(e0) == "E2/V0" );
@@ -58,4 +64,3 @@ TEST_CASE( "toString(enum class w/operator<<)", "[toString][enum][enumClass]" )
     EnumClass2 e3 = static_cast<EnumClass2>(10);
     CHECK( ::Catch::Detail::stringify(e3) == "Unknown enum value 10" );
 }
-
diff --git a/packages/Catch2/projects/SelfTest/UsageTests/Exception.tests.cpp b/packages/Catch2/projects/SelfTest/UsageTests/Exception.tests.cpp
index f9c73ed53..9c198dfbd 100644
--- a/packages/Catch2/projects/SelfTest/UsageTests/Exception.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/UsageTests/Exception.tests.cpp
@@ -18,6 +18,7 @@
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wweak-vtables"
 #pragma clang diagnostic ignored "-Wmissing-noreturn"
+#pragma clang diagnostic ignored "-Wunreachable-code"
 #endif
 
 namespace { namespace ExceptionTests {
diff --git a/packages/Catch2/projects/SelfTest/UsageTests/Generators.tests.cpp b/packages/Catch2/projects/SelfTest/UsageTests/Generators.tests.cpp
new file mode 100644
index 000000000..9242174a8
--- /dev/null
+++ b/packages/Catch2/projects/SelfTest/UsageTests/Generators.tests.cpp
@@ -0,0 +1,134 @@
+#include "catch.hpp"
+
+// Examples of usage of Generators
+
+// This test doesn't do much - it just shows how you can have several generators, of different
+// types (ie `i` and `j` are different types), can be sequenced using `,` and
+// can be expressed as named generators (like range) or as individual values.
+// Generators can be mixed with SECTIONs.
+// At time of writing the generated values are not automatically reported as part of the test
+// name or associated values - so we explicitly CAPTURE then (run this with `-s` to see them).
+// We could also incorporate them into the section names using DYNAMIC_SECTION. See the BDD
+// example later for more information.
+TEST_CASE("Generators") {
+
+    auto i = GENERATE( as<std::string>(), "a", "b", "c" );
+
+    SECTION( "one" ) {
+        auto j = GENERATE( range( 8, 11 ), 2 );
+
+        CAPTURE( i, j );
+        SUCCEED();
+    }
+    SECTION( "two" ) {
+        auto j = GENERATE( 3.141, 1.379 );
+        CAPTURE( i, j );
+        SUCCEED();
+    }
+}
+
+// This one generates the cross-product of two ranges.
+// It's mostly here to demonstrate the performance which, at time of writing,
+// leaves a lot to be desired.
+TEST_CASE( "100x100 ints", "[.][approvals]" ) {
+    auto x = GENERATE( range( 0,100 ) );
+    auto y = GENERATE( range( 200,300 ) );
+
+    CHECK( x < y );
+}
+
+// smaller version
+TEST_CASE( "10x10 ints" ) {
+    auto x = GENERATE( range( 1,11 ) );
+    auto y = GENERATE( range( 101, 111 ) );
+
+    CHECK( x < y );
+}
+
+// Some of the following tests use structured bindings for convenience and so are
+// conditionally compiled using the de-facto (and soon to be formally) standard
+// feature macros
+
+#ifdef __cpp_structured_bindings
+
+// One way to do pairs of values (actual/ expected?)
+// For a simple case like this I'd recommend writing out a series of REQUIREs
+// but it demonstrates a possible usage.
+// Spelling out the pair like this is a bit verbose, so read on for better examples
+// - the use of structured bindings here is an optional convenience
+TEST_CASE( "strlen", "[approvals]" ) {
+    auto [test_input, expected] = GENERATE( values<std::pair<std::string_view, size_t>>({
+            {"one", 3},
+            {"two", 3},
+            {"three", 5},
+            {"four", 4}
+        }));
+
+    REQUIRE( test_input.size() == expected );
+}
+
+// A nicer way to do pairs (or more) of values - using the table generator.
+// Note, you must specify the types up-front.
+TEST_CASE( "strlen2", "[approvals]" ) {
+    auto [test_input, expected] = GENERATE( table<std::string, size_t>({
+            {"one", 3},
+            {"two", 3},
+            {"three", 5},
+            {"four", 4}
+        }));
+
+    REQUIRE( test_input.size() == expected );
+}
+#endif
+
+// An alternate way of doing data tables without structure bindings
+// - I'd prefer to have the Data class within the test case but gcc 4.x doesn't seem to like it
+struct Data { std::string str; size_t len; };
+
+TEST_CASE( "strlen3" ) {
+    auto data = GENERATE( values<Data>({
+            {"one", 3},
+            {"two", 3},
+            {"three", 5},
+            {"four", 4}
+        }));
+
+    REQUIRE( data.str.size() == data.len );
+}
+
+// A nod towards property-based testing - generate a random selection of numbers
+// in a range and assert on global properties those numbers.
+static auto square( int i ) -> int { return i*i; }
+
+TEST_CASE( "Random numbers in a range", "[.][approvals]" ) {
+    auto x = GENERATE( random( -10000, 10000 ) );
+    CAPTURE( x );
+    REQUIRE( square(x) >= 0 );
+}
+
+#ifdef __cpp_structured_bindings
+
+// Based on example from https://docs.cucumber.io/gherkin/reference/#scenario-outline
+// (thanks to https://github.com/catchorg/Catch2/issues/850#issuecomment-399504851)
+
+// Note that GIVEN, WHEN, and THEN now forward onto DYNAMIC_SECTION instead of SECTION.
+// DYNAMIC_SECTION takes its name as a stringstream-style expression, so can be formatted using
+// variables in scope - such as the generated variables here. This reads quite nicely in the
+// test name output (the full scenario description).
+
+static auto eatCucumbers( int start, int eat ) -> int { return start-eat; }
+
+SCENARIO("Eating cucumbers", "[approvals]") {
+
+    auto [start, eat, left] = GENERATE( table<int,int,int> ({
+            { 12, 5, 7 },
+            { 20, 5, 15 }
+        }));
+
+    GIVEN( "there are " << start << " cucumbers" )
+    WHEN( "I eat " << eat << " cucumbers" )
+    THEN( "I should have " << left << " cucumbers" ) {
+        REQUIRE( eatCucumbers( start, eat ) == left );
+    }
+}
+#endif
diff --git a/packages/Catch2/projects/SelfTest/UsageTests/Matchers.tests.cpp b/packages/Catch2/projects/SelfTest/UsageTests/Matchers.tests.cpp
index 71abb8688..e09dad14e 100644
--- a/packages/Catch2/projects/SelfTest/UsageTests/Matchers.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/UsageTests/Matchers.tests.cpp
@@ -423,6 +423,15 @@ namespace { namespace MatchersTests {
             }
         }
 
+        TEST_CASE("Regression test #1", "[matchers][vector]") {
+            // At some point, UnorderedEqualsMatcher skipped
+            // mismatched prefixed before doing the comparison itself
+            std::vector<char> actual = { 'a', 'b' };
+            std::vector<char> expected = { 'c', 'b' };
+
+            CHECK_THAT(actual, !UnorderedEquals(expected));
+        }
+
 } } // namespace MatchersTests
 
 #endif // CATCH_CONFIG_DISABLE_MATCHERS
diff --git a/packages/Catch2/projects/SelfTest/UsageTests/Misc.tests.cpp b/packages/Catch2/projects/SelfTest/UsageTests/Misc.tests.cpp
index e5059e9f4..820e80197 100644
--- a/packages/Catch2/projects/SelfTest/UsageTests/Misc.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/UsageTests/Misc.tests.cpp
@@ -67,12 +67,12 @@ TEST_CASE( "random SECTION tests", "[.][sections][failing]" ) {
     int a = 1;
     int b = 2;
 
-    SECTION( "s1", "doesn't equal" ) {
+    SECTION( "doesn't equal" ) {
         REQUIRE( a != b );
         REQUIRE( b != a );
     }
 
-    SECTION( "s2", "not equal" ) {
+    SECTION( "not equal" ) {
         REQUIRE( a != b);
     }
 }
@@ -81,11 +81,11 @@ TEST_CASE( "nested SECTION tests", "[.][sections][failing]" ) {
     int a = 1;
     int b = 2;
 
-    SECTION( "s1", "doesn't equal" ) {
+    SECTION( "doesn't equal" ) {
         REQUIRE( a != b );
         REQUIRE( b != a );
 
-        SECTION( "s2", "not equal" ) {
+        SECTION( "not equal" ) {
             REQUIRE( a != b);
         }
     }
@@ -95,15 +95,15 @@ TEST_CASE( "more nested SECTION tests", "[sections][failing][.]" ) {
     int a = 1;
     int b = 2;
 
-    SECTION( "s1", "doesn't equal" ) {
-        SECTION( "s2", "equal" ) {
+    SECTION( "doesn't equal" ) {
+        SECTION( "equal" ) {
             REQUIRE( a == b );
         }
 
-        SECTION( "s3", "not equal" ) {
+        SECTION( "not equal" ) {
             REQUIRE( a != b );
         }
-        SECTION( "s4", "less than" ) {
+        SECTION( "less than" ) {
             REQUIRE( a < b );
         }
     }
@@ -112,16 +112,16 @@ TEST_CASE( "more nested SECTION tests", "[sections][failing][.]" ) {
 TEST_CASE( "even more nested SECTION tests", "[sections]" ) {
     SECTION( "c" ) {
         SECTION( "d (leaf)" ) {
-            SUCCEED(""); // avoid failing due to no tests
+            SUCCEED(); // avoid failing due to no tests
         }
 
         SECTION( "e (leaf)" ) {
-            SUCCEED(""); // avoid failing due to no tests
+            SUCCEED(); // avoid failing due to no tests
         }
     }
 
     SECTION( "f (leaf)" ) {
-        SUCCEED(""); // avoid failing due to no tests
+        SUCCEED(); // avoid failing due to no tests
     }
 }
 
@@ -129,9 +129,7 @@ TEST_CASE( "looped SECTION tests", "[.][failing][sections]" ) {
     int a = 1;
 
     for( int b = 0; b < 10; ++b ) {
-        std::ostringstream oss;
-        oss << "b is currently: " << b;
-        SECTION( "s1", oss.str() ) {
+        DYNAMIC_SECTION( "b is currently: " << b ) {
             CHECK( b > a );
         }
     }
@@ -174,11 +172,11 @@ TEST_CASE( "checkedElse, failing", "[failing][.]" ) {
 }
 
 TEST_CASE( "xmlentitycheck" ) {
-    SECTION( "embedded xml", "<test>it should be possible to embed xml characters, such as <, \" or &, or even whole <xml>documents</xml> within an attribute</test>" ) {
-        SUCCEED(""); // We need this here to stop it failing due to no tests
+    SECTION( "embedded xml: <test>it should be possible to embed xml characters, such as <, \" or &, or even whole <xml>documents</xml> within an attribute</test>" ) {
+        SUCCEED(); // We need this here to stop it failing due to no tests
     }
-    SECTION( "encoded chars", "these should all be encoded: &&&\"\"\"<<<&\"<<&\"" ) {
-        SUCCEED(""); // We need this here to stop it failing due to no tests
+    SECTION( "encoded chars: these should all be encoded: &&&\"\"\"<<<&\"<<&\"" ) {
+        SUCCEED(); // We need this here to stop it failing due to no tests
     }
 }
 
@@ -265,8 +263,8 @@ TEST_CASE( "vectors can be sized and resized", "[vector]" ) {
 
 // https://github.com/philsquared/Catch/issues/166
 TEST_CASE("A couple of nested sections followed by a failure", "[failing][.]") {
-    SECTION("Outer", "")
-        SECTION("Inner", "")
+    SECTION("Outer")
+        SECTION("Inner")
             SUCCEED("that's not flying - that's failing in style");
 
     FAIL("to infinity and beyond");
@@ -274,7 +272,7 @@ TEST_CASE("A couple of nested sections followed by a failure", "[failing][.]") {
 
 TEST_CASE("not allowed", "[!throws]") {
     // This test case should not be included if you run with -e on the command line
-    SUCCEED( "" );
+    SUCCEED();
 }
 
 //TEST_CASE( "Is big endian" ) {
diff --git a/packages/Catch2/projects/SelfTest/UsageTests/ToStringGeneral.tests.cpp b/packages/Catch2/projects/SelfTest/UsageTests/ToStringGeneral.tests.cpp
index a1f8c233a..acddf2238 100644
--- a/packages/Catch2/projects/SelfTest/UsageTests/ToStringGeneral.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/UsageTests/ToStringGeneral.tests.cpp
@@ -116,6 +116,20 @@ TEST_CASE("Static arrays are convertible to string", "[toString]") {
     }
 }
 
+#ifdef CATCH_CONFIG_CPP17_STRING_VIEW
+
+TEST_CASE("String views are stringified like other strings", "[toString][approvals]") {
+    std::string_view view{"abc"};
+    CHECK(Catch::Detail::stringify(view) == R"("abc")");
+
+    std::string_view arr[] { view };
+    CHECK(Catch::Detail::stringify(arr) == R"({ "abc" })");
+}
+
+#endif
+
+namespace {
+
 struct WhatException : std::exception {
     char const* what() const noexcept override {
         return "This exception has overriden what() method";
@@ -136,6 +150,8 @@ struct StringMakerException : std::exception {
     ~StringMakerException() override;
 };
 
+} // end anonymous namespace
+
 namespace Catch {
 template <>
 struct StringMaker<StringMakerException> {
diff --git a/packages/Catch2/projects/SelfTest/UsageTests/ToStringVariant.tests.cpp b/packages/Catch2/projects/SelfTest/UsageTests/ToStringVariant.tests.cpp
new file mode 100644
index 000000000..62f923f06
--- /dev/null
+++ b/packages/Catch2/projects/SelfTest/UsageTests/ToStringVariant.tests.cpp
@@ -0,0 +1,84 @@
+#define CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
+#include "catch.hpp"
+
+#if defined(CATCH_CONFIG_CPP17_VARIANT)
+
+#include <string>
+#include <variant>
+
+TEST_CASE( "variant<std::monostate>", "[toString][variant][approvals]")
+{
+    using type = std::variant<std::monostate>;
+    CHECK( "{ }" == ::Catch::Detail::stringify(type{}) );
+    type value {};
+    CHECK( "{ }" == ::Catch::Detail::stringify(value) );
+    CHECK( "{ }" == ::Catch::Detail::stringify(std::get<0>(value)) );
+}
+
+TEST_CASE( "variant<int>", "[toString][variant][approvals]")
+{
+    using type = std::variant<int>;
+    CHECK( "0" == ::Catch::Detail::stringify(type{0}) );
+}
+
+TEST_CASE( "variant<float, int>", "[toString][variant][approvals]")
+{
+    using type = std::variant<float, int>;
+    CHECK( "0.5f" == ::Catch::Detail::stringify(type{0.5f}) );
+    CHECK( "0" == ::Catch::Detail::stringify(type{0}) );
+
+    SECTION("valueless by exception") {
+        struct sample {
+            operator int() const { throw 42; }
+        };
+
+        type value{1.5f};
+        REQUIRE_THROWS_AS( value.emplace<int>(sample{}), int );
+        REQUIRE( value.valueless_by_exception() );
+        CHECK( "{valueless variant}" == ::Catch::Detail::stringify(value) );
+    }
+}
+
+TEST_CASE( "variant<string, int>", "[toString][variant][approvals]")
+{
+    using type = std::variant<std::string, int>;
+    CHECK( "\"foo\"" == ::Catch::Detail::stringify(type{"foo"}) );
+    CHECK( "0" == ::Catch::Detail::stringify(type{0}) );
+}
+
+TEST_CASE( "variant<variant<float, int>, string>", "[toString][variant][approvals]")
+{
+    using inner = std::variant<float, int>;
+    using type = std::variant<inner, std::string>;
+    CHECK( "0.5f" == ::Catch::Detail::stringify(type{0.5f}) );
+    CHECK( "0" == ::Catch::Detail::stringify(type{0}) );
+    CHECK( "\"foo\"" == ::Catch::Detail::stringify(type{"foo"}) );
+
+    struct sample {
+        operator int() const { throw 42; }
+    };
+
+    SECTION("valueless nested variant") {
+        type value = inner{0.5f};
+        REQUIRE( std::holds_alternative<inner>(value) );
+        REQUIRE( std::holds_alternative<float>(std::get<inner>(value)) );
+
+        REQUIRE_THROWS_AS( std::get<0>(value).emplace<int>(sample{}), int );
+
+        // outer variant is still valid and contains inner
+        REQUIRE( std::holds_alternative<inner>(value) );
+        // inner variant is valueless
+        REQUIRE( std::get<inner>(value).valueless_by_exception() );
+        CHECK( "{valueless variant}" == ::Catch::Detail::stringify(value) );
+    }
+}
+
+TEST_CASE( "variant<nullptr,int,const char *>", "[toString][variant][approvals]" )
+{
+    using type = std::variant<std::nullptr_t,int,const char *>;
+    CHECK( "nullptr" == ::Catch::Detail::stringify(type{nullptr}) );
+    CHECK( "42" == ::Catch::Detail::stringify(type{42}) );
+    CHECK( "\"Catch me\"" == ::Catch::Detail::stringify(type{"Catch me"}) );
+}
+
+#endif // CATCH_INTERNAL_CONFIG_CPP17_VARIANT
diff --git a/packages/Catch2/projects/SelfTest/UsageTests/ToStringWhich.tests.cpp b/packages/Catch2/projects/SelfTest/UsageTests/ToStringWhich.tests.cpp
index 26afa3b12..cd4a15183 100644
--- a/packages/Catch2/projects/SelfTest/UsageTests/ToStringWhich.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/UsageTests/ToStringWhich.tests.cpp
@@ -16,6 +16,16 @@ std::string fallbackStringifier(T const&) {
 #include "catch.hpp"
 
 
+
+#if defined(__GNUC__)
+// This has to be left enabled until end of the TU, because the GCC
+// frontend reports operator<<(std::ostream& os, const has_maker_and_operator&)
+// as unused anyway
+#    pragma GCC diagnostic ignored "-Wunused-function"
+#endif
+
+namespace {
+
 struct has_operator { };
 struct has_maker {};
 struct has_maker_and_operator {};
@@ -38,6 +48,8 @@ StreamT& operator<<(StreamT& os, const has_template_operator&) {
     return os;
 }
 
+} // end anonymous namespace
+
 namespace Catch {
     template<>
     struct StringMaker<has_maker> {
@@ -100,6 +112,8 @@ TEST_CASE( "stringify( vectors<has_maker_and_operator> )", "[toString]" ) {
     REQUIRE( ::Catch::Detail::stringify( v ) == "{ StringMaker<has_maker_and_operator> }" );
 }
 
+namespace {
+
 // Range-based conversion should only be used if other possibilities fail
 struct int_iterator {
     using iterator_category = std::input_iterator_tag;
@@ -139,6 +153,8 @@ struct stringmaker_range {
     int_iterator end() const { return {}; }
 };
 
+} // end anonymous namespace
+
 namespace Catch {
 template <>
 struct StringMaker<stringmaker_range> {
@@ -148,6 +164,8 @@ struct StringMaker<stringmaker_range> {
 };
 }
 
+namespace {
+
 struct just_range {
     int_iterator begin() const { return int_iterator{ 1 }; }
     int_iterator end() const { return {}; }
@@ -158,6 +176,8 @@ struct disabled_range {
     int_iterator end() const { return {}; }
 };
 
+} // end anonymous namespace
+
 namespace Catch {
 template <>
 struct is_range<disabled_range> {
diff --git a/packages/Catch2/projects/SelfTest/UsageTests/Tricky.tests.cpp b/packages/Catch2/projects/SelfTest/UsageTests/Tricky.tests.cpp
index 1c352ce98..b0363d420 100644
--- a/packages/Catch2/projects/SelfTest/UsageTests/Tricky.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/UsageTests/Tricky.tests.cpp
@@ -20,26 +20,6 @@
 #include <stdio.h>
 #include <sstream>
 
-namespace Catch {
-    std::string toString( const std::pair<int, int>& value ) {
-        std::ostringstream oss;
-        oss << "std::pair( " << value.first << ", " << value.second << " )";
-        return oss.str();
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-TEST_CASE
-(
-    "Parsing a std::pair",
-    "[Tricky][std::pair]"
-)
-{
-    std::pair<int, int> aNicePair( 1, 2 );
-
-    REQUIRE( (std::pair<int, int>( 1, 2 )) == aNicePair );
-}
-
 ///////////////////////////////////////////////////////////////////////////////
 TEST_CASE
 (
@@ -175,7 +155,7 @@ namespace ObjectWithConversions
     ///////////////////////////////////////////////////////////////////////////////
     TEST_CASE
     (
-        "Operators at different namespace levels not hijacked by Koenig lookup",
+        "Implicit conversions are supported inside assertion macros",
         "[Tricky][approvals]"
     )
     {
@@ -232,28 +212,28 @@ struct is_true
 
 TEST_CASE( "(unimplemented) static bools can be evaluated", "[Tricky]" )
 {
-    SECTION("compare to true","")
+    SECTION("compare to true")
     {
         REQUIRE( is_true<true>::value == true );
         REQUIRE( true == is_true<true>::value );
     }
-    SECTION("compare to false","")
+    SECTION("compare to false")
     {
         REQUIRE( is_true<false>::value == false );
         REQUIRE( false == is_true<false>::value );
     }
 
-    SECTION("negation", "")
+    SECTION("negation")
     {
         REQUIRE( !is_true<false>::value );
     }
 
-    SECTION("double negation","")
+    SECTION("double negation")
     {
         REQUIRE( !!is_true<true>::value );
     }
 
-    SECTION("direct","")
+    SECTION("direct")
     {
         REQUIRE( is_true<true>::value );
         REQUIRE_FALSE( is_true<false>::value );
diff --git a/packages/Catch2/scripts/approvalTests.py b/packages/Catch2/scripts/approvalTests.py
index 3293c9388..e2b0ce937 100755
--- a/packages/Catch2/scripts/approvalTests.py
+++ b/packages/Catch2/scripts/approvalTests.py
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 
-from  __future__ import print_function
+from __future__ import print_function
 
 import io
 import os
@@ -13,8 +13,8 @@ import scriptCommon
 from scriptCommon import catchPath
 
 if os.name == 'nt':
-	# Enable console colours on windows
-	os.system('')
+    # Enable console colours on windows
+    os.system('')
 
 rootPath = os.path.join(catchPath, 'projects/SelfTest/Baselines')
 
@@ -98,7 +98,6 @@ def filterLine(line, isCompact):
         # go from \ in windows paths to /
         line = line.replace('\\', '/')
 
-
     # strip source line numbers
     m = filelocParser.match(line)
     if m:
@@ -112,7 +111,7 @@ def filterLine(line, isCompact):
     if isCompact:
         line = line.replace(': FAILED', ': failed')
         line = line.replace(': PASSED', ': passed')
-        
+
     # strip Catch version number
     line = versionParser.sub("<version>", line)
 
@@ -180,19 +179,19 @@ print("Running approvals against executable:")
 print("  " + cmdPath)
 
 
-### Keep default reporters here
+# ## Keep default reporters here ##
 # Standard console reporter
-approve("console.std", ["~[!nonportable]~[!benchmark]~[approvals]", "--order", "lex"])
+approve("console.std", ["~[!nonportable]~[!benchmark]~[approvals]", "--order", "lex", "--rng-seed", "0"])
 # console reporter, include passes, warn about No Assertions
-approve("console.sw", ["~[!nonportable]~[!benchmark]~[approvals]", "-s", "-w", "NoAssertions", "--order", "lex"])
+approve("console.sw", ["~[!nonportable]~[!benchmark]~[approvals]", "-s", "-w", "NoAssertions", "--order", "lex", "--rng-seed", "0"])
 # console reporter, include passes, warn about No Assertions, limit failures to first 4
-approve("console.swa4", ["~[!nonportable]~[!benchmark]~[approvals]", "-s", "-w", "NoAssertions", "-x", "4", "--order", "lex"])
+approve("console.swa4", ["~[!nonportable]~[!benchmark]~[approvals]", "-s", "-w", "NoAssertions", "-x", "4", "--order", "lex", "--rng-seed", "0"])
 # junit reporter, include passes, warn about No Assertions
-approve("junit.sw", ["~[!nonportable]~[!benchmark]~[approvals]", "-s", "-w", "NoAssertions", "-r", "junit", "--order", "lex"])
+approve("junit.sw", ["~[!nonportable]~[!benchmark]~[approvals]", "-s", "-w", "NoAssertions", "-r", "junit", "--order", "lex", "--rng-seed", "0"])
 # xml reporter, include passes, warn about No Assertions
-approve("xml.sw", ["~[!nonportable]~[!benchmark]~[approvals]", "-s", "-w", "NoAssertions", "-r", "xml", "--order", "lex"])
+approve("xml.sw", ["~[!nonportable]~[!benchmark]~[approvals]", "-s", "-w", "NoAssertions", "-r", "xml", "--order", "lex", "--rng-seed", "0"])
 # compact reporter, include passes, warn about No Assertions
-approve('compact.sw', ['~[!nonportable]~[!benchmark]~[approvals]', '-s', '-w', 'NoAssertions', '-r', 'compact', '--order', 'lex'])
+approve('compact.sw', ['~[!nonportable]~[!benchmark]~[approvals]', '-s', '-w', 'NoAssertions', '-r', 'compact', '--order', 'lex', "--rng-seed", "0"])
 
 if overallResult != 0:
     print("If these differences are expected, run approve.py to approve new baselines.")
diff --git a/packages/Catch2/scripts/generateSingleHeader.py b/packages/Catch2/scripts/generateSingleHeader.py
index c3ce1aecb..31033d683 100755
--- a/packages/Catch2/scripts/generateSingleHeader.py
+++ b/packages/Catch2/scripts/generateSingleHeader.py
@@ -24,7 +24,7 @@ def generate(v):
 
     seenHeaders = set([])
     rootPath = os.path.join( catchPath, 'include/' )
-    outputPath = os.path.join( catchPath, 'single_include/catch.hpp' )
+    outputPath = os.path.join( catchPath, 'single_include/catch2/catch.hpp' )
 
     globals = {
         'includeImpl' : True,
@@ -46,7 +46,7 @@ def generate(v):
     outDir = os.path.dirname(outputPath)
     if not os.path.exists(outDir):
         os.makedirs(outDir)
-    out = io.open( outputPath, 'w', newline='\n')
+    out = io.open( outputPath, 'w', newline='\n', encoding='utf-8')
 
     def write( line ):
         if globals['includeImpl'] or globals['implIfDefs'] == -1:
diff --git a/packages/Catch2/scripts/releaseCommon.py b/packages/Catch2/scripts/releaseCommon.py
index 6e44da240..1a8ee2c87 100644
--- a/packages/Catch2/scripts/releaseCommon.py
+++ b/packages/Catch2/scripts/releaseCommon.py
@@ -169,7 +169,7 @@ def performUpdates(version):
     import shutil
     for rep in ('automake', 'tap', 'teamcity'):
         sourceFile = os.path.join(catchPath, 'include/reporters/catch_reporter_{}.hpp'.format(rep))
-        destFile = os.path.join(catchPath, 'single_include/catch_reporter_{}.hpp'.format(rep))
+        destFile = os.path.join(catchPath, 'single_include', 'catch2', 'catch_reporter_{}.hpp'.format(rep))
         shutil.copyfile(sourceFile, destFile)
 
     updateReadmeFile(version)
diff --git a/packages/Catch2/scripts/scriptCommon.py b/packages/Catch2/scripts/scriptCommon.py
index 1415be0b7..4b70f9613 100644
--- a/packages/Catch2/scripts/scriptCommon.py
+++ b/packages/Catch2/scripts/scriptCommon.py
@@ -6,7 +6,7 @@ import subprocess
 catchPath = os.path.dirname(os.path.realpath( os.path.dirname(sys.argv[0])))
 
 def getBuildExecutable():
-    dir = os.environ.get('CATCH_DEV_OUT_DIR', "cmake-build-debug/SelfTest")
+    dir = os.environ.get('CATCH_DEV_OUT_DIR', "cmake-build-debug/projects/SelfTest")
     return dir
 
 def runAndCapture( args ):
diff --git a/packages/Catch2/scripts/updateDocumentToC.py b/packages/Catch2/scripts/updateDocumentToC.py
index d3b8bf0ff..325c8a3c2 100644
--- a/packages/Catch2/scripts/updateDocumentToC.py
+++ b/packages/Catch2/scripts/updateDocumentToC.py
@@ -26,7 +26,7 @@ from scriptCommon import catchPath
 minTocEntries = 4
 
 headingExcludeDefault = [1,3,4,5]  # use level 2 headers for at default
-headingExcludeRelease = [2,3,4,5]  # use level 1 headers for release-notes.md
+headingExcludeRelease = [1,3,4,5]  # use level 1 headers for release-notes.md
 
 documentsDefault = os.path.join(os.path.relpath(catchPath), 'docs/*.md')
 releaseNotesName = 'release-notes.md'
@@ -91,18 +91,20 @@ def dashifyHeadline(line):
     level = len(stripped_right) - len(stripped_both)
     stripped_wspace = stripped_both.strip()
 
-    # character replacements
-    replaced_colon = stripped_wspace.replace('.', '')
-    replaced_slash = replaced_colon.replace('/', '')
-    rem_nonvalids = ''.join([c if c in VALIDS
-                             else '-' for c in replaced_slash])
-
-    lowered = rem_nonvalids.lower()
-    dashified = re.sub(r'(-)\1+', r'\1', lowered)  # remove duplicate dashes
-    dashified = dashified.strip('-')  # strip dashes from start and end
-
-    # exception '&' (double-dash in github)
-    dashified = dashified.replace('-&-', '--')
+    # GitHub's sluggification works in an interesting way
+    # 1) '+', '/', '(', ')' and so on are just removed
+    # 2) spaces are converted into '-' directly
+    # 3) multiple -- are not collapsed
+
+    dashified = ''
+    for c in stripped_wspace:
+        if c in VALIDS:
+            dashified += c.lower()
+        elif c.isspace():
+            dashified += '-'
+        else:
+            # Unknown symbols are just removed
+            continue
 
     return [stripped_wspace, dashified, level]
 
diff --git a/packages/Catch2/scripts/updateWandbox.py b/packages/Catch2/scripts/updateWandbox.py
index 5785feb46..564f94890 100644
--- a/packages/Catch2/scripts/updateWandbox.py
+++ b/packages/Catch2/scripts/updateWandbox.py
@@ -34,7 +34,7 @@ def uploadFiles():
         'code': main_file,
         'codes': [{
             'file': 'catch.hpp',
-            'code': open(os.path.join(catchPath, 'single_include', 'catch.hpp')).read()
+            'code': open(os.path.join(catchPath, 'single_include', 'catch2', 'catch.hpp')).read()
         }],
         'options': 'c++11,cpp-no-pedantic,boost-nothing',
         'compiler-option-raw': '-DCATCH_CONFIG_FAST_COMPILE',
diff --git a/packages/Catch2/single_include/catch.hpp b/packages/Catch2/single_include/catch2/catch.hpp
similarity index 91%
rename from packages/Catch2/single_include/catch.hpp
rename to packages/Catch2/single_include/catch2/catch.hpp
index 28448ddb2..4191607a7 100644
--- a/packages/Catch2/single_include/catch.hpp
+++ b/packages/Catch2/single_include/catch2/catch.hpp
@@ -1,6 +1,6 @@
 /*
- *  Catch v2.2.3
- *  Generated: 2018-06-06 23:11:57.601416
+ *  Catch v2.4.1
+ *  Generated: 2018-09-28 15:50:15.645795
  *  ----------------------------------------------------------
  *  This file has been merged from multiple headers. Please don't edit it directly
  *  Copyright (c) 2018 Two Blue Cubes Ltd. All rights reserved.
@@ -14,8 +14,8 @@
 
 
 #define CATCH_VERSION_MAJOR 2
-#define CATCH_VERSION_MINOR 2
-#define CATCH_VERSION_PATCH 3
+#define CATCH_VERSION_MINOR 4
+#define CATCH_VERSION_PATCH 1
 
 #ifdef __clang__
 #    pragma clang system_header
@@ -30,13 +30,15 @@
 #       pragma warning(push)
 #       pragma warning(disable: 161 1682)
 #   else // __ICC
-#       pragma clang diagnostic ignored "-Wunused-variable"
 #       pragma clang diagnostic push
 #       pragma clang diagnostic ignored "-Wpadded"
 #       pragma clang diagnostic ignored "-Wswitch-enum"
 #       pragma clang diagnostic ignored "-Wcovered-switch-default"
 #    endif
 #elif defined __GNUC__
+     // GCC likes to warn on REQUIREs, and we cannot suppress them
+     // locally because g++'s support for _Pragma is lacking in older,
+     // still supported, versions
 #    pragma GCC diagnostic ignored "-Wparentheses"
 #    pragma GCC diagnostic push
 #    pragma GCC diagnostic ignored "-Wunused-variable"
@@ -55,7 +57,9 @@
 #  if defined(CATCH_CONFIG_DISABLE_MATCHERS)
 #    undef CATCH_CONFIG_DISABLE_MATCHERS
 #  endif
-#  define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
+#  if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
+#    define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
+#  endif
 #endif
 
 #if !defined(CATCH_CONFIG_IMPL_ONLY)
@@ -104,6 +108,7 @@ namespace Catch {
 // CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?
 // CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported?
 // CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported?
+// CATCH_CONFIG_DISABLE_EXCEPTIONS : Are exceptions enabled?
 // ****************
 // Note to maintainers: if new toggles are added please document them
 // in configuration.md, too
@@ -116,11 +121,11 @@ namespace Catch {
 
 #ifdef __cplusplus
 
-#  if __cplusplus >= 201402L
+#  if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
 #    define CATCH_CPP14_OR_GREATER
 #  endif
 
-#  if __cplusplus >= 201703L
+#  if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
 #    define CATCH_CPP17_OR_GREATER
 #  endif
 
@@ -145,6 +150,12 @@ namespace Catch {
 #       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" )
+
 #endif // __clang__
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -176,6 +187,12 @@ namespace Catch {
 #    define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
 #endif
 
+////////////////////////////////////////////////////////////////////////////////
+// PS4
+#if defined(__ORBIS__)
+#    define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE
+#endif
+
 ////////////////////////////////////////////////////////////////////////////////
 // Cygwin
 #ifdef __CYGWIN__
@@ -183,7 +200,14 @@ namespace Catch {
 // Required for some versions of Cygwin to declare gettimeofday
 // see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin
 #   define _BSD_SOURCE
+// some versions of cygwin (most) do not support std::to_string. Use the libstd check.
+// https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html line 2812-2813
+# if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \
+	       && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))
+
+#	define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
 
+# endif
 #endif // __CYGWIN__
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -205,7 +229,12 @@ namespace Catch {
 #endif // _MSC_VER
 
 ////////////////////////////////////////////////////////////////////////////////
+// Check if we are compiled with -fno-exceptions or equivalent
+#if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND)
+#  define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED
+#endif
 
+////////////////////////////////////////////////////////////////////////////////
 // DJGPP
 #ifdef __DJGPP__
 #  define CATCH_INTERNAL_CONFIG_NO_WCHAR
@@ -222,6 +251,32 @@ namespace Catch {
     #define CATCH_INTERNAL_CONFIG_COUNTER
 #endif
 
+////////////////////////////////////////////////////////////////////////////////
+// Check if string_view is available and usable
+// The check is split apart to work around v140 (VS2015) preprocessor issue...
+#if defined(__has_include)
+#if __has_include(<string_view>) && defined(CATCH_CPP17_OR_GREATER)
+#    define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW
+#endif
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+// Check if variant is available and usable
+#if defined(__has_include)
+#  if __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
+#    if defined(__clang__) && (__clang_major__ < 8)
+       // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852
+       // fix should be in clang 8, workaround in libstdc++ 8.2
+#      include <ciso646>
+#      if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
+#        define CATCH_CONFIG_NO_CPP17_VARIANT
+#     else
+#        define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
+#      endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
+#    endif // defined(__clang__) && (__clang_major__ < 8)
+#  endif // __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
+#endif // __has_include
+
 #if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
 #   define CATCH_CONFIG_COUNTER
 #endif
@@ -245,6 +300,26 @@ namespace Catch {
 #  define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
 #endif
 
+#if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW)
+#  define CATCH_CONFIG_CPP17_STRING_VIEW
+#endif
+
+#if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT)
+#  define CATCH_CONFIG_CPP17_VARIANT
+#endif
+
+#if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
+#  define CATCH_INTERNAL_CONFIG_NEW_CAPTURE
+#endif
+
+#if defined(CATCH_INTERNAL_CONFIG_NEW_CAPTURE) && !defined(CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NEW_CAPTURE)
+#  define CATCH_CONFIG_NEW_CAPTURE
+#endif
+
+#if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
+#  define CATCH_CONFIG_DISABLE_EXCEPTIONS
+#endif
+
 #if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
 #   define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
 #   define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS
@@ -253,6 +328,20 @@ namespace Catch {
 #   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_CONFIG_DISABLE_EXCEPTIONS)
+#define CATCH_TRY if ((true))
+#define CATCH_CATCH_ALL if ((false))
+#define CATCH_CATCH_ANON(type) if ((false))
+#else
+#define CATCH_TRY try
+#define CATCH_CATCH_ALL catch (...)
+#define CATCH_CATCH_ANON(type) catch (type)
+#endif
 
 // end catch_compiler_capabilities.h
 #define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
@@ -494,6 +583,10 @@ namespace Catch {
 
 } // namespace Catch
 
+inline auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef {
+    return Catch::StringRef( rawChars, size );
+}
+
 // end catch_stringref.h
 namespace Catch {
 
@@ -551,7 +644,7 @@ struct AutoReg : NonCopyable {
     #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
         static void TestName(); \
         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
-        namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, "", Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
+        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 \
         static void TestName()
     #define INTERNAL_CATCH_TESTCASE( ... ) \
@@ -580,7 +673,7 @@ struct AutoReg : NonCopyable {
     ///////////////////////////////////////////////////////////////////////////////
     #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
-        Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, "", Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
+        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
 
 // end catch_test_registry.h
@@ -697,13 +790,15 @@ namespace Catch {
             return *this;
         }
         auto get() -> std::ostream& { return *m_oss; }
-
-        static void cleanup();
     };
 }
 
 // end catch_stream.h
 
+#ifdef CATCH_CONFIG_CPP17_STRING_VIEW
+#include <string_view>
+#endif
+
 #ifdef __OBJC__
 // start catch_objc_arc.hpp
 
@@ -879,10 +974,11 @@ namespace Catch {
     struct StringMaker<std::string> {
         static std::string convert(const std::string& str);
     };
-#ifdef CATCH_CONFIG_WCHAR
+
+#ifdef CATCH_CONFIG_CPP17_STRING_VIEW
     template<>
-    struct StringMaker<std::wstring> {
-        static std::string convert(const std::wstring& wstr);
+    struct StringMaker<std::string_view> {
+        static std::string convert(std::string_view str);
     };
 #endif
 
@@ -896,6 +992,18 @@ namespace Catch {
     };
 
 #ifdef CATCH_CONFIG_WCHAR
+    template<>
+    struct StringMaker<std::wstring> {
+        static std::string convert(const std::wstring& wstr);
+    };
+
+# ifdef CATCH_CONFIG_CPP17_STRING_VIEW
+    template<>
+    struct StringMaker<std::wstring_view> {
+        static std::string convert(std::wstring_view str);
+    };
+# endif
+
     template<>
     struct StringMaker<wchar_t const *> {
         static std::string convert(wchar_t const * str);
@@ -1064,6 +1172,7 @@ namespace Catch {
 #if defined(CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS)
 #  define CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
 #  define CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
+#  define CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
 #  define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
 #endif
 
@@ -1127,6 +1236,34 @@ namespace Catch {
 }
 #endif // CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
 
+#if defined(CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_VARIANT)
+#include <variant>
+namespace Catch {
+    template<>
+    struct StringMaker<std::monostate> {
+        static std::string convert(const std::monostate&) {
+            return "{ }";
+        }
+    };
+
+    template<typename... Elements>
+    struct StringMaker<std::variant<Elements...>> {
+        static std::string convert(const std::variant<Elements...>& variant) {
+            if (variant.valueless_by_exception()) {
+                return "{valueless variant}";
+            } else {
+                return std::visit(
+                    [](const auto& value) {
+                        return ::Catch::Detail::stringify(value);
+                    },
+                    variant
+                );
+            }
+        }
+    };
+}
+#endif // CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
+
 namespace Catch {
     struct not_this_one {}; // Tag type for detecting which begin/ end are being selected
 
@@ -1486,8 +1623,10 @@ namespace Catch {
     struct BenchmarkInfo;
     struct BenchmarkStats;
     struct AssertionReaction;
+    struct SourceLineInfo;
 
     struct ITransientExpression;
+    struct IGeneratorTracker;
 
     struct IResultCapture {
 
@@ -1498,6 +1637,8 @@ namespace Catch {
         virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;
         virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;
 
+        virtual auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& = 0;
+
         virtual void benchmarkStarting( BenchmarkInfo const& info ) = 0;
         virtual void benchmarkEnded( BenchmarkStats const& stats ) = 0;
 
@@ -1579,7 +1720,7 @@ namespace Catch {
 
     public:
         AssertionHandler
-            (   StringRef macroName,
+            (   StringRef const& macroName,
                 SourceLineInfo const& lineInfo,
                 StringRef capturedExpression,
                 ResultDisposition::Flags resultDisposition );
@@ -1610,7 +1751,7 @@ namespace Catch {
         auto allowThrows() const -> bool;
     };
 
-    void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef matcherString );
+    void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString );
 
 } // namespace Catch
 
@@ -1618,15 +1759,16 @@ namespace Catch {
 // start catch_message.h
 
 #include <string>
+#include <vector>
 
 namespace Catch {
 
     struct MessageInfo {
-        MessageInfo(    std::string const& _macroName,
+        MessageInfo(    StringRef const& _macroName,
                         SourceLineInfo const& _lineInfo,
                         ResultWas::OfType _type );
 
-        std::string macroName;
+        StringRef macroName;
         std::string message;
         SourceLineInfo lineInfo;
         ResultWas::OfType type;
@@ -1650,7 +1792,7 @@ namespace Catch {
     };
 
     struct MessageBuilder : MessageStream {
-        MessageBuilder( std::string const& macroName,
+        MessageBuilder( StringRef const& macroName,
                         SourceLineInfo const& lineInfo,
                         ResultWas::OfType type );
 
@@ -1671,6 +1813,28 @@ namespace Catch {
         MessageInfo m_info;
     };
 
+    class Capturer {
+        std::vector<MessageInfo> m_messages;
+        IResultCapture& m_resultCapture = getResultCapture();
+        size_t m_captured = 0;
+    public:
+        Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names );
+        ~Capturer();
+
+        void captureValue( size_t index, StringRef value );
+
+        template<typename T>
+        void captureValues( size_t index, T&& value ) {
+            captureValue( index, Catch::Detail::stringify( value ) );
+        }
+
+        template<typename T, typename... Ts>
+        void captureValues( size_t index, T&& value, Ts&&... values ) {
+            captureValues( index, value );
+            captureValues( index+1, values... );
+        }
+    };
+
 } // end namespace Catch
 
 // end catch_message.h
@@ -1682,7 +1846,7 @@ namespace Catch {
   #define CATCH_INTERNAL_STRINGIFY(...) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION"
 #endif
 
-#if defined(CATCH_CONFIG_FAST_COMPILE)
+#if defined(CATCH_CONFIG_FAST_COMPILE) || defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
 
 ///////////////////////////////////////////////////////////////////////////////
 // Another way to speed-up compilation is to omit local try-catch for REQUIRE*
@@ -1702,7 +1866,7 @@ namespace Catch {
 ///////////////////////////////////////////////////////////////////////////////
 #define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \
     do { \
-        Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
+        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
         INTERNAL_CATCH_TRY { \
             CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
             catchAssertionHandler.handleExpr( Catch::Decomposer() <= __VA_ARGS__ ); \
@@ -1725,7 +1889,7 @@ namespace Catch {
 ///////////////////////////////////////////////////////////////////////////////
 #define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, ... ) \
     do { \
-        Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
+        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
         try { \
             static_cast<void>(__VA_ARGS__); \
             catchAssertionHandler.handleExceptionNotThrownAsExpected(); \
@@ -1739,7 +1903,7 @@ namespace Catch {
 ///////////////////////////////////////////////////////////////////////////////
 #define INTERNAL_CATCH_THROWS( macroName, resultDisposition, ... ) \
     do { \
-        Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \
+        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \
         if( catchAssertionHandler.allowThrows() ) \
             try { \
                 static_cast<void>(__VA_ARGS__); \
@@ -1756,7 +1920,7 @@ namespace Catch {
 ///////////////////////////////////////////////////////////////////////////////
 #define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \
     do { \
-        Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \
+        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \
         if( catchAssertionHandler.allowThrows() ) \
             try { \
                 static_cast<void>(expr); \
@@ -1776,27 +1940,32 @@ namespace Catch {
 ///////////////////////////////////////////////////////////////////////////////
 #define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \
     do { \
-        Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
+        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::StringRef(), resultDisposition ); \
         catchAssertionHandler.handleMessage( messageType, ( Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop() ).m_stream.str() ); \
         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
     } while( false )
 
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_CAPTURE( varName, macroName, ... ) \
+    auto varName = Catch::Capturer( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info, #__VA_ARGS__ ); \
+    varName.captureValues( 0, __VA_ARGS__ )
+
 ///////////////////////////////////////////////////////////////////////////////
 #define INTERNAL_CATCH_INFO( macroName, log ) \
-    Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log );
+    Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log );
 
 ///////////////////////////////////////////////////////////////////////////////
 // Although this is matcher-based, it can be used with just a string
 #define INTERNAL_CATCH_THROWS_STR_MATCHES( macroName, resultDisposition, matcher, ... ) \
     do { \
-        Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
+        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
         if( catchAssertionHandler.allowThrows() ) \
             try { \
                 static_cast<void>(__VA_ARGS__); \
                 catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
             } \
             catch( ... ) { \
-                Catch::handleExceptionMatchExpr( catchAssertionHandler, matcher, #matcher ); \
+                Catch::handleExceptionMatchExpr( catchAssertionHandler, matcher, #matcher##_catch_sr ); \
             } \
         else \
             catchAssertionHandler.handleThrowingCallSkipped(); \
@@ -1848,19 +2017,22 @@ namespace Catch {
 namespace Catch {
 
     struct SectionInfo {
+        SectionInfo
+            (   SourceLineInfo const& _lineInfo,
+                std::string const& _name );
+
+        // Deprecated
         SectionInfo
             (   SourceLineInfo const& _lineInfo,
                 std::string const& _name,
-                std::string const& _description = std::string() );
+                std::string const& ) : SectionInfo( _lineInfo, _name ) {}
 
         std::string name;
-        std::string description;
+        std::string description; // !Deprecated: this will always be empty
         SourceLineInfo lineInfo;
     };
 
     struct SectionEndInfo {
-        SectionEndInfo( SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds );
-
         SectionInfo sectionInfo;
         Counts prevAssertions;
         double durationInSeconds;
@@ -1914,8 +2086,15 @@ namespace Catch {
 
 } // end namespace Catch
 
-    #define INTERNAL_CATCH_SECTION( ... ) \
-        if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) )
+#define INTERNAL_CATCH_SECTION( ... ) \
+    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
+
+#define INTERNAL_CATCH_DYNAMIC_SECTION( ... ) \
+    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
 
 // end catch_section.h
 // start catch_benchmark.h
@@ -1991,7 +2170,7 @@ namespace Catch {
         virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
         virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0;
 
-        virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0;
+        virtual IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const = 0;
 
         virtual StartupExceptionRegistry const& getStartupExceptionRegistry() const = 0;
     };
@@ -2006,7 +2185,7 @@ namespace Catch {
         virtual void registerStartupException() noexcept = 0;
     };
 
-    IRegistryHub& getRegistryHub();
+    IRegistryHub const& getRegistryHub();
     IMutableRegistryHub& getMutableRegistryHub();
     void cleanUp();
     std::string translateActiveException();
@@ -2088,7 +2267,6 @@ namespace Catch {
 // start catch_approx.h
 
 #include <type_traits>
-#include <stdexcept>
 
 namespace Catch {
 namespace Detail {
@@ -2096,18 +2274,26 @@ namespace Detail {
     class Approx {
     private:
         bool equalityComparisonImpl(double other) const;
+        // Validates the new margin (margin >= 0)
+        // out-of-line to avoid including stdexcept in the header
+        void setMargin(double margin);
+        // Validates the new epsilon (0 < epsilon < 1)
+        // out-of-line to avoid including stdexcept in the header
+        void setEpsilon(double epsilon);
 
     public:
         explicit Approx ( double value );
 
         static Approx custom();
 
+        Approx operator-() const;
+
         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
         Approx operator()( T const& value ) {
             Approx approx( static_cast<double>(value) );
-            approx.epsilon( m_epsilon );
-            approx.margin( m_margin );
-            approx.scale( m_scale );
+            approx.m_epsilon = m_epsilon;
+            approx.m_margin = m_margin;
+            approx.m_scale = m_scale;
             return approx;
         }
 
@@ -2159,27 +2345,14 @@ namespace Detail {
         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
         Approx& epsilon( T const& newEpsilon ) {
             double epsilonAsDouble = static_cast<double>(newEpsilon);
-            if( epsilonAsDouble < 0 || epsilonAsDouble > 1.0 ) {
-                throw std::domain_error
-                    (   "Invalid Approx::epsilon: " +
-                        Catch::Detail::stringify( epsilonAsDouble ) +
-                        ", Approx::epsilon has to be between 0 and 1" );
-            }
-            m_epsilon = epsilonAsDouble;
+            setEpsilon(epsilonAsDouble);
             return *this;
         }
 
         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
         Approx& margin( T const& newMargin ) {
             double marginAsDouble = static_cast<double>(newMargin);
-            if( marginAsDouble < 0 ) {
-                throw std::domain_error
-                    (   "Invalid Approx::margin: " +
-                         Catch::Detail::stringify( marginAsDouble ) +
-                         ", Approx::Margin has to be non-negative." );
-
-            }
-            m_margin = marginAsDouble;
+            setMargin(marginAsDouble);
             return *this;
         }
 
@@ -2197,7 +2370,12 @@ namespace Detail {
         double m_scale;
         double m_value;
     };
-}
+} // end namespace Detail
+
+namespace literals {
+    Detail::Approx operator "" _a(long double val);
+    Detail::Approx operator "" _a(unsigned long long val);
+} // end namespace literals
 
 template<>
 struct StringMaker<Catch::Detail::Approx> {
@@ -2264,6 +2442,11 @@ namespace Matchers {
             mutable std::string m_cachedToString;
         };
 
+#ifdef __clang__
+#    pragma clang diagnostic push
+#    pragma clang diagnostic ignored "-Wnon-virtual-dtor"
+#endif
+
         template<typename ObjectT>
         struct MatcherMethod {
             virtual bool match( ObjectT const& arg ) const = 0;
@@ -2273,6 +2456,10 @@ namespace Matchers {
             virtual bool match( PtrT* arg ) const = 0;
         };
 
+#ifdef __clang__
+#    pragma clang diagnostic pop
+#endif
+
         template<typename T>
         struct MatcherBase : MatcherUntypedBase, MatcherMethod<T> {
 
@@ -2661,7 +2848,7 @@ namespace Matchers {
                 auto lfirst = m_target.begin(), llast = m_target.end();
                 auto rfirst = vec.begin(), rlast = vec.end();
                 // Cut common prefix to optimize checking of permuted parts
-                while (lfirst != llast && *lfirst != *rfirst) {
+                while (lfirst != llast && *lfirst == *rfirst) {
                     ++lfirst; ++rfirst;
                 }
                 if (lfirst == llast) {
@@ -2726,7 +2913,7 @@ namespace Catch {
         MatcherT m_matcher;
         StringRef m_matcherString;
     public:
-        MatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef matcherString )
+        MatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString )
         :   ITransientExpression{ true, matcher.match( arg ) },
             m_arg( arg ),
             m_matcher( matcher ),
@@ -2745,10 +2932,10 @@ namespace Catch {
 
     using StringMatcher = Matchers::Impl::MatcherBase<std::string>;
 
-    void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef matcherString  );
+    void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString  );
 
     template<typename ArgT, typename MatcherT>
-    auto makeMatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef matcherString  ) -> MatchExpr<ArgT, MatcherT> {
+    auto makeMatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString  ) -> MatchExpr<ArgT, MatcherT> {
         return MatchExpr<ArgT, MatcherT>( arg, matcher, matcherString );
     }
 
@@ -2757,9 +2944,9 @@ namespace Catch {
 ///////////////////////////////////////////////////////////////////////////////
 #define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \
     do { \
-        Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
+        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
         INTERNAL_CATCH_TRY { \
-            catchAssertionHandler.handleExpr( Catch::makeMatchExpr( arg, matcher, #matcher ) ); \
+            catchAssertionHandler.handleExpr( Catch::makeMatchExpr( arg, matcher, #matcher##_catch_sr ) ); \
         } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
     } while( false )
@@ -2767,14 +2954,14 @@ namespace Catch {
 ///////////////////////////////////////////////////////////////////////////////
 #define INTERNAL_CATCH_THROWS_MATCHES( macroName, exceptionType, resultDisposition, matcher, ... ) \
     do { \
-        Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(exceptionType) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
+        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(exceptionType) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
         if( catchAssertionHandler.allowThrows() ) \
             try { \
                 static_cast<void>(__VA_ARGS__ ); \
                 catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
             } \
             catch( exceptionType const& ex ) { \
-                catchAssertionHandler.handleExpr( Catch::makeMatchExpr( ex, matcher, #matcher ) ); \
+                catchAssertionHandler.handleExpr( Catch::makeMatchExpr( ex, matcher, #matcher##_catch_sr ) ); \
             } \
             catch( ... ) { \
                 catchAssertionHandler.handleUnexpectedInflightException(); \
@@ -2786,6 +2973,304 @@ namespace Catch {
 
 // end catch_capture_matchers.h
 #endif
+// start catch_generators.hpp
+
+// start catch_interfaces_generatortracker.h
+
+
+#include <memory>
+
+namespace Catch {
+
+    namespace Generators {
+        class GeneratorBase {
+        protected:
+            size_t m_size = 0;
+
+        public:
+            GeneratorBase( size_t size ) : m_size( size ) {}
+            virtual ~GeneratorBase();
+            auto size() const -> size_t { return m_size; }
+        };
+        using GeneratorBasePtr = std::unique_ptr<GeneratorBase>;
+
+    } // namespace Generators
+
+    struct IGeneratorTracker {
+        virtual ~IGeneratorTracker();
+        virtual auto hasGenerator() const -> bool = 0;
+        virtual auto getGenerator() const -> Generators::GeneratorBasePtr const& = 0;
+        virtual void setGenerator( Generators::GeneratorBasePtr&& generator ) = 0;
+        virtual auto getIndex() const -> std::size_t = 0;
+    };
+
+} // namespace Catch
+
+// end catch_interfaces_generatortracker.h
+// start catch_enforce.h
+
+#include <stdexcept>
+
+namespace Catch {
+#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
+    template <typename Ex>
+    [[noreturn]]
+    void throw_exception(Ex const& e) {
+        throw e;
+    }
+#else // ^^ Exceptions are enabled //  Exceptions are disabled vv
+    [[noreturn]]
+    void throw_exception(std::exception const& e);
+#endif
+} // namespace Catch;
+
+#define CATCH_PREPARE_EXCEPTION( type, msg ) \
+    type( ( Catch::ReusableStringStream() << msg ).str() )
+#define CATCH_INTERNAL_ERROR( msg ) \
+    Catch::throw_exception(CATCH_PREPARE_EXCEPTION( std::logic_error, CATCH_INTERNAL_LINEINFO << ": Internal Catch error: " << msg))
+#define CATCH_ERROR( msg ) \
+    Catch::throw_exception(CATCH_PREPARE_EXCEPTION( std::domain_error, msg ))
+#define CATCH_RUNTIME_ERROR( msg ) \
+    Catch::throw_exception(CATCH_PREPARE_EXCEPTION( std::runtime_error, msg ))
+#define CATCH_ENFORCE( condition, msg ) \
+    do{ if( !(condition) ) CATCH_ERROR( msg ); } while(false)
+
+// end catch_enforce.h
+#include <memory>
+#include <vector>
+#include <cassert>
+
+#include <utility>
+
+namespace Catch {
+namespace Generators {
+
+    // !TBD move this into its own location?
+    namespace pf{
+        template<typename T, typename... Args>
+        std::unique_ptr<T> make_unique( Args&&... args ) {
+            return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
+        }
+    }
+
+    template<typename T>
+    struct IGenerator {
+        virtual ~IGenerator() {}
+        virtual auto get( size_t index ) const -> T = 0;
+    };
+
+    template<typename T>
+    class SingleValueGenerator : public IGenerator<T> {
+        T m_value;
+    public:
+        SingleValueGenerator( T const& value ) : m_value( value ) {}
+
+        auto get( size_t ) const -> T override {
+            return m_value;
+        }
+    };
+
+    template<typename T>
+    class FixedValuesGenerator : public IGenerator<T> {
+        std::vector<T> m_values;
+
+    public:
+        FixedValuesGenerator( std::initializer_list<T> values ) : m_values( values ) {}
+
+        auto get( size_t index ) const -> T override {
+            return m_values[index];
+        }
+    };
+
+    template<typename T>
+    class RangeGenerator : public IGenerator<T> {
+        T const m_first;
+        T const m_last;
+
+    public:
+        RangeGenerator( T const& first, T const& last ) : m_first( first ), m_last( last ) {
+            assert( m_last > m_first );
+        }
+
+        auto get( size_t index ) const -> T override {
+            // ToDo:: introduce a safe cast to catch potential overflows
+            return static_cast<T>(m_first+index);
+        }
+    };
+
+    template<typename T>
+    struct NullGenerator : IGenerator<T> {
+        auto get( size_t ) const -> T override {
+            CATCH_INTERNAL_ERROR("A Null Generator is always empty");
+        }
+    };
+
+    template<typename T>
+    class Generator {
+        std::unique_ptr<IGenerator<T>> m_generator;
+        size_t m_size;
+
+    public:
+        Generator( size_t size, std::unique_ptr<IGenerator<T>> generator )
+        :   m_generator( std::move( generator ) ),
+            m_size( size )
+        {}
+
+        auto size() const -> size_t { return m_size; }
+        auto operator[]( size_t index ) const -> T {
+            assert( index < m_size );
+            return m_generator->get( index );
+        }
+    };
+
+    std::vector<size_t> randomiseIndices( size_t selectionSize, size_t sourceSize );
+
+    template<typename T>
+    class GeneratorRandomiser : public IGenerator<T> {
+        Generator<T> m_baseGenerator;
+
+        std::vector<size_t> m_indices;
+    public:
+        GeneratorRandomiser( Generator<T>&& baseGenerator, size_t numberOfItems )
+        :   m_baseGenerator( std::move( baseGenerator ) ),
+            m_indices( randomiseIndices( numberOfItems, m_baseGenerator.size() ) )
+        {}
+
+        auto get( size_t index ) const -> T override {
+            return m_baseGenerator[m_indices[index]];
+        }
+    };
+
+    template<typename T>
+    struct RequiresASpecialisationFor;
+
+    template<typename T>
+    auto all() -> Generator<T> { return RequiresASpecialisationFor<T>(); }
+
+    template<>
+    auto all<int>() -> Generator<int>;
+
+    template<typename T>
+    auto range( T const& first, T const& last ) -> Generator<T> {
+        return Generator<T>( (last-first), pf::make_unique<RangeGenerator<T>>( first, last ) );
+    }
+
+    template<typename T>
+    auto random( T const& first, T const& last ) -> Generator<T> {
+        auto gen = range( first, last );
+        auto size = gen.size();
+
+        return Generator<T>( size, pf::make_unique<GeneratorRandomiser<T>>( std::move( gen ), size ) );
+    }
+    template<typename T>
+    auto random( size_t size ) -> Generator<T> {
+        return Generator<T>( size, pf::make_unique<GeneratorRandomiser<T>>( all<T>(), size ) );
+    }
+
+    template<typename T>
+    auto values( std::initializer_list<T> values ) -> Generator<T> {
+        return Generator<T>( values.size(), pf::make_unique<FixedValuesGenerator<T>>( values ) );
+    }
+    template<typename T>
+    auto value( T const& val ) -> Generator<T> {
+        return Generator<T>( 1, pf::make_unique<SingleValueGenerator<T>>( val ) );
+    }
+
+    template<typename T>
+    auto as() -> Generator<T> {
+        return Generator<T>( 0, pf::make_unique<NullGenerator<T>>() );
+    }
+
+    template<typename... Ts>
+    auto table( std::initializer_list<std::tuple<Ts...>>&& tuples ) -> Generator<std::tuple<Ts...>> {
+        return values<std::tuple<Ts...>>( std::forward<std::initializer_list<std::tuple<Ts...>>>( tuples ) );
+    }
+
+    template<typename T>
+    struct Generators : GeneratorBase {
+        std::vector<Generator<T>> m_generators;
+
+        using type = T;
+
+        Generators() : GeneratorBase( 0 ) {}
+
+        void populate( T&& val ) {
+            m_size += 1;
+            m_generators.emplace_back( value( std::move( val ) ) );
+        }
+        template<typename U>
+        void populate( U&& val ) {
+            populate( T( std::move( val ) ) );
+        }
+        void populate( Generator<T>&& generator ) {
+            m_size += generator.size();
+            m_generators.emplace_back( std::move( generator ) );
+        }
+
+        template<typename U, typename... Gs>
+        void populate( U&& valueOrGenerator, Gs... moreGenerators ) {
+            populate( std::forward<U>( valueOrGenerator ) );
+            populate( std::forward<Gs>( moreGenerators )... );
+        }
+
+        auto operator[]( size_t index ) const -> T {
+            size_t sizes = 0;
+            for( auto const& gen : m_generators ) {
+                auto localIndex = index-sizes;
+                sizes += gen.size();
+                if( index < sizes )
+                    return gen[localIndex];
+            }
+            CATCH_INTERNAL_ERROR("Index '" << index << "' is out of range (" << sizes << ')');
+        }
+    };
+
+    template<typename T, typename... Gs>
+    auto makeGenerators( Generator<T>&& generator, Gs... moreGenerators ) -> Generators<T> {
+        Generators<T> generators;
+        generators.m_generators.reserve( 1+sizeof...(Gs) );
+        generators.populate( std::move( generator ), std::forward<Gs>( moreGenerators )... );
+        return generators;
+    }
+    template<typename T>
+    auto makeGenerators( Generator<T>&& generator ) -> Generators<T> {
+        Generators<T> generators;
+        generators.populate( std::move( generator ) );
+        return generators;
+    }
+    template<typename T, typename... Gs>
+    auto makeGenerators( T&& val, Gs... moreGenerators ) -> Generators<T> {
+        return makeGenerators( value( std::forward<T>( val ) ), std::forward<Gs>( moreGenerators )... );
+    }
+    template<typename T, typename U, typename... Gs>
+    auto makeGenerators( U&& val, Gs... moreGenerators ) -> Generators<T> {
+        return makeGenerators( value( T( std::forward<U>( val ) ) ), std::forward<Gs>( moreGenerators )... );
+    }
+
+    auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker&;
+
+    template<typename L>
+    // Note: The type after -> is weird, because VS2015 cannot parse
+    //       the expression used in the typedef inside, when it is in
+    //       return type. Yeah, ¯\_(ツ)_/¯
+    auto generate( SourceLineInfo const& lineInfo, L const& generatorExpression ) -> decltype(std::declval<decltype(generatorExpression())>()[0]) {
+        using UnderlyingType = typename decltype(generatorExpression())::type;
+
+        IGeneratorTracker& tracker = acquireGeneratorTracker( lineInfo );
+        if( !tracker.hasGenerator() )
+            tracker.setGenerator( pf::make_unique<Generators<UnderlyingType>>( generatorExpression() ) );
+
+        auto const& generator = static_cast<Generators<UnderlyingType> const&>( *tracker.getGenerator() );
+        return generator[tracker.getIndex()];
+    }
+
+} // namespace Generators
+} // namespace Catch
+
+#define GENERATE( ... ) \
+    Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, []{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } )
+
+// end catch_generators.hpp
 
 // These files are included here so the single_include script doesn't put them
 // in the conditionally compiled sections
@@ -2962,7 +3447,7 @@ namespace Catch {
                         std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
                         const char* className = class_getName( cls );
 
-                        getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, name.c_str(), desc.c_str(), SourceLineInfo("",0) ) );
+                        getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, NameAndTags( name.c_str(), desc.c_str() ), SourceLineInfo("",0) ) );
                         noTestMethods++;
                     }
                 }
@@ -3586,6 +4071,7 @@ namespace Catch {
 
     struct ReporterPreferences {
         bool shouldRedirectStdOut = false;
+        bool shouldReportAllAssertions = false;
     };
 
     template<typename T>
@@ -3796,7 +4282,7 @@ namespace Catch {
         {
             m_reporterPrefs.shouldRedirectStdOut = false;
             if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )
-                throw std::domain_error( "Verbosity level not supported by this reporter" );
+                CATCH_ERROR( "Verbosity level not supported by this reporter" );
         }
 
         ReporterPreferences getPreferences() const override {
@@ -3910,7 +4396,7 @@ namespace Catch {
         {
             m_reporterPrefs.shouldRedirectStdOut = false;
             if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )
-                throw std::domain_error( "Verbosity level not supported by this reporter" );
+                CATCH_ERROR( "Verbosity level not supported by this reporter" );
         }
         ~CumulativeReporterBase() override = default;
 
@@ -4550,13 +5036,6 @@ namespace TestCaseTracking {
             Failed
         };
 
-        class TrackerHasName {
-            NameAndLocation m_nameAndLocation;
-        public:
-            TrackerHasName( NameAndLocation const& nameAndLocation );
-            bool operator ()( ITrackerPtr const& tracker ) const;
-        };
-
         using Children = std::vector<ITrackerPtr>;
         NameAndLocation m_nameAndLocation;
         TrackerContext& m_ctx;
@@ -4676,6 +5155,12 @@ namespace Detail {
         return Approx( 0 );
     }
 
+    Approx Approx::operator-() const {
+        auto temp(*this);
+        temp.m_value = -temp.m_value;
+        return temp;
+    }
+
     std::string Approx::toString() const {
         ReusableStringStream rss;
         rss << "Approx( " << ::Catch::Detail::stringify( m_value ) << " )";
@@ -4688,8 +5173,31 @@ namespace Detail {
         return marginComparison(m_value, other, m_margin) || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(m_value)));
     }
 
+    void Approx::setMargin(double margin) {
+        CATCH_ENFORCE(margin >= 0,
+            "Invalid Approx::margin: " << margin << '.'
+            << " Approx::Margin has to be non-negative.");
+        m_margin = margin;
+    }
+
+    void Approx::setEpsilon(double epsilon) {
+        CATCH_ENFORCE(epsilon >= 0 && epsilon <= 1.0,
+            "Invalid Approx::epsilon: " << epsilon << '.'
+            << " Approx::epsilon has to be in [0, 1]");
+        m_epsilon = epsilon;
+    }
+
 } // end namespace Detail
 
+namespace literals {
+    Detail::Approx operator "" _a(long double val) {
+        return Detail::Approx(val);
+    }
+    Detail::Approx operator "" _a(unsigned long long val) {
+        return Detail::Approx(val);
+    }
+} // end namespace literals
+
 std::string StringMaker<Catch::Detail::Approx>::convert(Catch::Detail::Approx const& value) {
     return value.toString();
 }
@@ -4931,6 +5439,8 @@ namespace Catch {
         void sectionEnded( SectionEndInfo const& endInfo ) override;
         void sectionEndedEarly( SectionEndInfo const& endInfo ) override;
 
+        auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& override;
+
         void benchmarkStarting( BenchmarkInfo const& info ) override;
         void benchmarkEnded( BenchmarkStats const& stats ) override;
 
@@ -4998,9 +5508,11 @@ namespace Catch {
 // end catch_run_context.h
 namespace Catch {
 
-    auto operator <<( std::ostream& os, ITransientExpression const& expr ) -> std::ostream& {
-        expr.streamReconstructedExpression( os );
-        return os;
+    namespace {
+        auto operator <<( std::ostream& os, ITransientExpression const& expr ) -> std::ostream& {
+            expr.streamReconstructedExpression( os );
+            return os;
+        }
     }
 
     LazyExpression::LazyExpression( bool isNegated )
@@ -5030,7 +5542,7 @@ namespace Catch {
     }
 
     AssertionHandler::AssertionHandler
-        (   StringRef macroName,
+        (   StringRef const& macroName,
             SourceLineInfo const& lineInfo,
             StringRef capturedExpression,
             ResultDisposition::Flags resultDisposition )
@@ -5059,8 +5571,13 @@ namespace Catch {
             // (To go back to the test and change execution, jump over the throw, next)
             CATCH_BREAK_INTO_DEBUGGER();
         }
-        if( m_reaction.shouldThrow )
-            throw Catch::TestFailureException();
+        if (m_reaction.shouldThrow) {
+#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
+            throw Catch::TestFailureException();
+#else
+            CATCH_ERROR( "Test failure requires aborting test!" );
+#endif
+        }
     }
     void AssertionHandler::setCompleted() {
         m_completed = true;
@@ -5087,7 +5604,7 @@ namespace Catch {
 
     // This is the overload that takes a string and infers the Equals matcher from it
     // The more general overload, that takes any string matcher, is in catch_capture_matchers.cpp
-    void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef matcherString  ) {
+    void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString  ) {
         handleExceptionMatchExpr( handler, Matchers::Equals( str ), matcherString );
     }
 
@@ -5219,7 +5736,7 @@ namespace Catch {
     // This is the general overload that takes a any string matcher
     // There is another overload, in catch_assertionhandler.h/.cpp, that only takes a string and infers
     // the Equals matcher (so the header does not mention matchers)
-    void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef matcherString  ) {
+    void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString  ) {
         std::string exceptionMessage = Catch::translateActiveException();
         MatchExpr<std::string, StringMatcher const&> expr( exceptionMessage, matcher, matcherString );
         handler.handleExpr( expr );
@@ -6704,7 +7221,9 @@ namespace Catch {
         return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0);
     }
     bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const noexcept {
-        return line < other.line || ( line == other.line && (std::strcmp(file, other.file) < 0));
+        // We can assume that the same file will usually have the same pointer.
+        // Thus, if the pointers are the same, there is no point in calling the strcmp
+        return line < other.line || ( line == other.line && file != other.file && (std::strcmp(file, other.file) < 0));
     }
 
     std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
@@ -6727,20 +7246,6 @@ namespace Catch {
 // end catch_common.cpp
 // start catch_config.cpp
 
-// start catch_enforce.h
-
-#include <stdexcept>
-
-#define CATCH_PREPARE_EXCEPTION( type, msg ) \
-    type( ( Catch::ReusableStringStream() << msg ).str() )
-#define CATCH_INTERNAL_ERROR( msg ) \
-    throw CATCH_PREPARE_EXCEPTION( std::logic_error, CATCH_INTERNAL_LINEINFO << ": Internal Catch error: " << msg);
-#define CATCH_ERROR( msg ) \
-    throw CATCH_PREPARE_EXCEPTION( std::domain_error, msg )
-#define CATCH_ENFORCE( condition, msg ) \
-    do{ if( !(condition) ) CATCH_ERROR( msg ); } while(false)
-
-// end catch_enforce.h
 namespace Catch {
 
     Config::Config( ConfigData const& data )
@@ -7238,6 +7743,19 @@ namespace Catch {
     }
 }
 // end catch_decomposer.cpp
+// start catch_enforce.cpp
+
+namespace Catch {
+#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS_CUSTOM_HANDLER)
+    [[noreturn]]
+    void throw_exception(std::exception const& e) {
+        Catch::cerr() << "Catch will terminate because it needed to throw an exception.\n"
+                      << "The message was: " << e.what() << '\n';
+        std::terminate();
+    }
+#endif
+} // namespace Catch;
+// end catch_enforce.cpp
 // start catch_errno_guard.cpp
 
 #include <cerrno>
@@ -7283,6 +7801,7 @@ namespace Catch {
         m_translators.push_back( std::unique_ptr<const IExceptionTranslator>( translator ) );
     }
 
+#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
     std::string ExceptionTranslatorRegistry::translateActiveException() const {
         try {
 #ifdef __OBJC__
@@ -7325,6 +7844,12 @@ namespace Catch {
         }
     }
 
+#else // ^^ Exceptions are enabled // Exceptions are disabled vv
+    std::string ExceptionTranslatorRegistry::translateActiveException() const {
+        CATCH_INTERNAL_ERROR("Attempted to translate active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
+    }
+#endif
+
     std::string ExceptionTranslatorRegistry::tryTranslators() const {
         if( m_translators.empty() )
             std::rethrow_exception(std::current_exception());
@@ -7494,6 +8019,64 @@ namespace Catch {
 #    pragma GCC diagnostic pop
 #endif
 // end catch_fatal_condition.cpp
+// start catch_generators.cpp
+
+// start catch_random_number_generator.h
+
+#include <algorithm>
+#include <random>
+
+namespace Catch {
+
+    struct IConfig;
+
+    std::mt19937& rng();
+    void seedRng( IConfig const& config );
+    unsigned int rngSeed();
+
+}
+
+// end catch_random_number_generator.h
+#include <limits>
+#include <set>
+
+namespace Catch {
+
+IGeneratorTracker::~IGeneratorTracker() {}
+
+namespace Generators {
+
+    GeneratorBase::~GeneratorBase() {}
+
+    std::vector<size_t> randomiseIndices( size_t selectionSize, size_t sourceSize ) {
+
+        assert( selectionSize <= sourceSize );
+        std::vector<size_t> indices;
+        indices.reserve( selectionSize );
+        std::uniform_int_distribution<size_t> uid( 0, sourceSize-1 );
+
+        std::set<size_t> seen;
+        // !TBD: improve this algorithm
+        while( indices.size() < selectionSize ) {
+            auto index = uid( rng() );
+            if( seen.insert( index ).second )
+                indices.push_back( index );
+        }
+        return indices;
+    }
+
+    auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
+        return getResultCapture().acquireGeneratorTracker( lineInfo );
+    }
+
+    template<>
+    auto all<int>() -> Generator<int> {
+        return range( std::numeric_limits<int>::min(), std::numeric_limits<int>::max() );
+    }
+
+} // namespace Generators
+} // namespace Catch
+// end catch_generators.cpp
 // start catch_interfaces_capture.cpp
 
 namespace Catch {
@@ -7530,8 +8113,11 @@ namespace Catch {
         using Reporters = std::vector<IStreamingReporterPtr>;
         Reporters m_listeners;
         IStreamingReporterPtr m_reporter = nullptr;
+        ReporterPreferences m_preferences;
 
     public:
+        ListeningReporter();
+
         void addListener( IStreamingReporterPtr&& listener );
         void addReporter( IStreamingReporterPtr&& reporter );
 
@@ -7689,16 +8275,16 @@ namespace Catch {
 
 namespace Catch {
 
-	LeakDetector::LeakDetector() {
-		int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
-		flag |= _CRTDBG_LEAK_CHECK_DF;
-		flag |= _CRTDBG_ALLOC_MEM_DF;
-		_CrtSetDbgFlag(flag);
-		_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
-		_CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
-		// Change this to leaking allocation's number to break there
-		_CrtSetBreakAlloc(-1);
-	}
+    LeakDetector::LeakDetector() {
+        int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
+        flag |= _CRTDBG_LEAK_CHECK_DF;
+        flag |= _CRTDBG_ALLOC_MEM_DF;
+        _CrtSetDbgFlag(flag);
+        _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
+        _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
+        // Change this to leaking allocation's number to break there
+        _CrtSetBreakAlloc(-1);
+    }
 }
 
 #else
@@ -7929,7 +8515,6 @@ namespace Catch {
 #include <cstdlib>
 #include <cstdint>
 #include <cstring>
-#include <stdexcept>
 
 namespace Catch {
 namespace Matchers {
@@ -7997,9 +8582,8 @@ namespace Matchers {
 namespace Floating {
     WithinAbsMatcher::WithinAbsMatcher(double target, double margin)
         :m_target{ target }, m_margin{ margin } {
-        if (m_margin < 0) {
-            throw std::domain_error("Allowed margin difference has to be >= 0");
-        }
+        CATCH_ENFORCE(margin >= 0, "Invalid margin: " << margin << '.'
+            << " Margin has to be non-negative.");
     }
 
     // Performs equivalent check of std::fabs(lhs - rhs) <= margin
@@ -8014,11 +8598,16 @@ namespace Floating {
 
     WithinUlpsMatcher::WithinUlpsMatcher(double target, int ulps, FloatingPointKind baseType)
         :m_target{ target }, m_ulps{ ulps }, m_type{ baseType } {
-        if (m_ulps < 0) {
-            throw std::domain_error("Allowed ulp difference has to be >= 0");
-        }
+        CATCH_ENFORCE(ulps >= 0, "Invalid ULP setting: " << ulps << '.'
+            << " ULPs have to be non-negative.");
     }
 
+#if defined(__clang__)
+#pragma clang diagnostic push
+// Clang <3.5 reports on the default branch in the switch below
+#pragma clang diagnostic ignored "-Wunreachable-code"
+#endif
+
     bool WithinUlpsMatcher::match(double const& matchee) const {
         switch (m_type) {
         case FloatingPointKind::Float:
@@ -8026,10 +8615,14 @@ namespace Floating {
         case FloatingPointKind::Double:
             return almostEqualUlps<double>(matchee, m_target, m_ulps);
         default:
-            throw std::domain_error("Unknown FloatingPointKind value");
+            CATCH_INTERNAL_ERROR( "Unknown FloatingPointKind value" );
         }
     }
 
+#if defined(__clang__)
+#pragma clang diagnostic pop
+#endif
+
     std::string WithinUlpsMatcher::describe() const {
         return "is within " + Catch::to_string(m_ulps) + " ULPs of " + ::Catch::Detail::stringify(m_target) + ((m_type == FloatingPointKind::Float)? "f" : "");
     }
@@ -8173,9 +8766,11 @@ namespace Catch {
 } // end namespace Catch
 
 // end catch_uncaught_exceptions.h
+#include <cassert>
+
 namespace Catch {
 
-    MessageInfo::MessageInfo(   std::string const& _macroName,
+    MessageInfo::MessageInfo(   StringRef const& _macroName,
                                 SourceLineInfo const& _lineInfo,
                                 ResultWas::OfType _type )
     :   macroName( _macroName ),
@@ -8197,7 +8792,7 @@ namespace Catch {
 
     ////////////////////////////////////////////////////////////////////////////
 
-    Catch::MessageBuilder::MessageBuilder( std::string const& macroName,
+    Catch::MessageBuilder::MessageBuilder( StringRef const& macroName,
                                            SourceLineInfo const& lineInfo,
                                            ResultWas::OfType type )
         :m_info(macroName, lineInfo, type) {}
@@ -8216,6 +8811,37 @@ namespace Catch {
             getResultCapture().popScopedMessage(m_info);
         }
     }
+
+    Capturer::Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names ) {
+        auto start = std::string::npos;
+        for( size_t pos = 0; pos <= names.size(); ++pos ) {
+            char c = names[pos];
+            if( pos == names.size() || c == ' ' || c == '\t' || c == ',' || c == ']' ) {
+                if( start != std::string::npos ) {
+                    m_messages.push_back( MessageInfo( macroName, lineInfo, resultType ) );
+                    m_messages.back().message = names.substr( start, pos-start) + " := ";
+                    start = std::string::npos;
+                }
+            }
+            else if( c != '[' && c != ']' && start == std::string::npos )
+                start = pos;
+        }
+    }
+    Capturer::~Capturer() {
+        if ( !uncaught_exceptions() ){
+            assert( m_captured == m_messages.size() );
+            for( size_t i = 0; i < m_captured; ++i  )
+                m_resultCapture.popScopedMessage( m_messages[i] );
+        }
+    }
+
+    void Capturer::captureValue( size_t index, StringRef value ) {
+        assert( index < m_messages.size() );
+        m_messages[index].message += value;
+        m_resultCapture.pushScopedMessage( m_messages[index] );
+        m_captured++;
+    }
+
 } // end namespace Catch
 // end catch_message.cpp
 // start catch_output_redirect.cpp
@@ -8260,6 +8886,8 @@ namespace Catch {
         auto str() const -> std::string;
     };
 
+#if defined(CATCH_CONFIG_NEW_CAPTURE)
+
     // Windows's implementation of std::tmpfile is terrible (it tries
     // to create a file inside system folder, thus requiring elevated
     // privileges for the binary), so we have to use tmpnam(_s) and
@@ -8303,6 +8931,8 @@ namespace Catch {
         std::string& m_stderrDest;
     };
 
+#endif
+
 } // end namespace Catch
 
 #endif // TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
@@ -8313,13 +8943,15 @@ namespace Catch {
 #include <sstream>
 #include <stdexcept>
 
-#if defined(_MSC_VER)
-#include <io.h>      //_dup and _dup2
-#define dup _dup
-#define dup2 _dup2
-#define fileno _fileno
-#else
-#include <unistd.h>  // dup and dup2
+#if defined(CATCH_CONFIG_NEW_CAPTURE)
+    #if defined(_MSC_VER)
+    #include <io.h>      //_dup and _dup2
+    #define dup _dup
+    #define dup2 _dup2
+    #define fileno _fileno
+    #else
+    #include <unistd.h>  // dup and dup2
+    #endif
 #endif
 
 namespace Catch {
@@ -8345,24 +8977,26 @@ namespace Catch {
     {}
     auto RedirectedStdErr::str() const -> std::string { return m_rss.str(); }
 
+#if defined(CATCH_CONFIG_NEW_CAPTURE)
+
 #if defined(_MSC_VER)
     TempFile::TempFile() {
         if (tmpnam_s(m_buffer)) {
-            throw std::runtime_error("Could not get a temp filename");
+            CATCH_RUNTIME_ERROR("Could not get a temp filename");
         }
         if (fopen_s(&m_file, m_buffer, "w")) {
             char buffer[100];
             if (strerror_s(buffer, errno)) {
-                throw std::runtime_error("Could not translate errno to string");
+                CATCH_RUNTIME_ERROR("Could not translate errno to a string");
             }
-            throw std::runtime_error("Could not open the temp file: " + std::string(m_buffer) + buffer);
+            CATCH_RUNTIME_ERROR("Coul dnot open the temp file: '" << m_buffer << "' because: " << buffer);
         }
     }
 #else
     TempFile::TempFile() {
         m_file = std::tmpfile();
         if (!m_file) {
-            throw std::runtime_error("Could not create a temp file.");
+            CATCH_RUNTIME_ERROR("Could not create a temp file.");
         }
     }
 
@@ -8417,66 +9051,37 @@ namespace Catch {
         m_stderrDest += m_stderrFile.getContents();
     }
 
+#endif // CATCH_CONFIG_NEW_CAPTURE
+
 } // namespace Catch
 
-#if defined(_MSC_VER)
-#undef dup
-#undef dup2
-#undef fileno
+#if defined(CATCH_CONFIG_NEW_CAPTURE)
+    #if defined(_MSC_VER)
+    #undef dup
+    #undef dup2
+    #undef fileno
+    #endif
 #endif
 // end catch_output_redirect.cpp
 // start catch_random_number_generator.cpp
 
-// start catch_random_number_generator.h
-
-#include <algorithm>
-
 namespace Catch {
 
-    struct IConfig;
-
-    void seedRng( IConfig const& config );
-
-    unsigned int rngSeed();
-
-    struct RandomNumberGenerator {
-        using result_type = unsigned int;
-
-        static constexpr result_type (min)() { return 0; }
-        static constexpr result_type (max)() { return 1000000; }
-
-        result_type operator()( result_type n ) const;
-        result_type operator()() const;
-
-        template<typename V>
-        static void shuffle( V& vector ) {
-            RandomNumberGenerator rng;
-            std::shuffle( vector.begin(), vector.end(), rng );
-        }
-    };
-
-}
-
-// end catch_random_number_generator.h
-#include <cstdlib>
-
-namespace Catch {
+    std::mt19937& rng() {
+        static std::mt19937 s_rng;
+        return s_rng;
+    }
 
     void seedRng( IConfig const& config ) {
-        if( config.rngSeed() != 0 )
+        if( config.rngSeed() != 0 ) {
             std::srand( config.rngSeed() );
+            rng().seed( config.rngSeed() );
+        }
     }
+
     unsigned int rngSeed() {
         return getCurrentContext().getConfig()->rngSeed();
     }
-
-    RandomNumberGenerator::result_type RandomNumberGenerator::operator()( result_type n ) const {
-        return std::rand() % n;
-    }
-    RandomNumberGenerator::result_type RandomNumberGenerator::operator()() const {
-        return std::rand() % (max)();
-    }
-
 }
 // end catch_random_number_generator.cpp
 // start catch_registry_hub.cpp
@@ -8616,6 +9221,41 @@ namespace Catch {
 } // end namespace Catch
 
 // end catch_startup_exception_registry.h
+// start catch_singletons.hpp
+
+namespace Catch {
+
+    struct ISingleton {
+        virtual ~ISingleton();
+    };
+
+    void addSingleton( ISingleton* singleton );
+    void cleanupSingletons();
+
+    template<typename SingletonImplT, typename InterfaceT = SingletonImplT, typename MutableInterfaceT = InterfaceT>
+    class Singleton : SingletonImplT, public ISingleton {
+
+        static auto getInternal() -> Singleton* {
+            static Singleton* s_instance = nullptr;
+            if( !s_instance ) {
+                s_instance = new Singleton;
+                addSingleton( s_instance );
+            }
+            return s_instance;
+        }
+
+    public:
+        static auto get() -> InterfaceT const& {
+            return *getInternal();
+        }
+        static auto getMutable() -> MutableInterfaceT& {
+            return *getInternal();
+        }
+    };
+
+} // namespace Catch
+
+// end catch_singletons.hpp
 namespace Catch {
 
     namespace {
@@ -8631,7 +9271,7 @@ namespace Catch {
             ITestCaseRegistry const& getTestCaseRegistry() const override {
                 return m_testCaseRegistry;
             }
-            IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() override {
+            IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const override {
                 return m_exceptionTranslatorRegistry;
             }
             ITagAliasRegistry const& getTagAliasRegistry() const override {
@@ -8668,27 +9308,19 @@ namespace Catch {
             TagAliasRegistry m_tagAliasRegistry;
             StartupExceptionRegistry m_exceptionRegistry;
         };
-
-        // Single, global, instance
-        RegistryHub*& getTheRegistryHub() {
-            static RegistryHub* theRegistryHub = nullptr;
-            if( !theRegistryHub )
-                theRegistryHub = new RegistryHub();
-            return theRegistryHub;
-        }
     }
 
-    IRegistryHub& getRegistryHub() {
-        return *getTheRegistryHub();
+    using RegistryHubSingleton = Singleton<RegistryHub, IRegistryHub, IMutableRegistryHub>;
+
+    IRegistryHub const& getRegistryHub() {
+        return RegistryHubSingleton::get();
     }
     IMutableRegistryHub& getMutableRegistryHub() {
-        return *getTheRegistryHub();
+        return RegistryHubSingleton::getMutable();
     }
     void cleanUp() {
-        delete getTheRegistryHub();
-        getTheRegistryHub() = nullptr;
+        cleanupSingletons();
         cleanUpContext();
-        ReusableStringStream::cleanup();
     }
     std::string translateActiveException() {
         return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();
@@ -8753,13 +9385,76 @@ namespace Catch {
 
 namespace Catch {
 
+    namespace Generators {
+        struct GeneratorTracker : TestCaseTracking::TrackerBase, IGeneratorTracker {
+            size_t m_index = static_cast<size_t>( -1 );
+            GeneratorBasePtr m_generator;
+
+            GeneratorTracker( TestCaseTracking::NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
+            :   TrackerBase( nameAndLocation, ctx, parent )
+            {}
+            ~GeneratorTracker();
+
+            static GeneratorTracker& acquire( TrackerContext& ctx, TestCaseTracking::NameAndLocation const& nameAndLocation ) {
+                std::shared_ptr<GeneratorTracker> tracker;
+
+                ITracker& currentTracker = ctx.currentTracker();
+                if( TestCaseTracking::ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
+                    assert( childTracker );
+                    assert( childTracker->isIndexTracker() );
+                    tracker = std::static_pointer_cast<GeneratorTracker>( childTracker );
+                }
+                else {
+                    tracker = std::make_shared<GeneratorTracker>( nameAndLocation, ctx, &currentTracker );
+                    currentTracker.addChild( tracker );
+                }
+
+                if( !ctx.completedCycle() && !tracker->isComplete() ) {
+                    if( tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun )
+                        tracker->moveNext();
+                    tracker->open();
+                }
+
+                return *tracker;
+            }
+
+            void moveNext() {
+                m_index++;
+                m_children.clear();
+            }
+
+            // TrackerBase interface
+            bool isIndexTracker() const override { return true; }
+            auto hasGenerator() const -> bool override {
+                return !!m_generator;
+            }
+            void close() override {
+                TrackerBase::close();
+                if( m_runState == CompletedSuccessfully && m_index < m_generator->size()-1 )
+                    m_runState = Executing;
+            }
+
+            // IGeneratorTracker interface
+            auto getGenerator() const -> GeneratorBasePtr const& override {
+                return m_generator;
+            }
+            void setGenerator( GeneratorBasePtr&& generator ) override {
+                m_generator = std::move( generator );
+            }
+            auto getIndex() const -> size_t override {
+                return m_index;
+            }
+        };
+        GeneratorTracker::~GeneratorTracker() {}
+    }
+
     RunContext::RunContext(IConfigPtr const& _config, IStreamingReporterPtr&& reporter)
     :   m_runInfo(_config->name()),
         m_context(getCurrentMutableContext()),
         m_config(_config),
         m_reporter(std::move(reporter)),
         m_lastAssertionInfo{ StringRef(), SourceLineInfo("",0), StringRef(), ResultDisposition::Normal },
-        m_includeSuccessfulResults( m_config->includeSuccessfulResults() )
+        m_includeSuccessfulResults( m_config->includeSuccessfulResults() || m_reporter->getPreferences().shouldReportAllAssertions )
     {
         m_context.setRunner(this);
         m_context.setConfig(m_config);
@@ -8869,6 +9564,13 @@ namespace Catch {
 
         return true;
     }
+    auto RunContext::acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
+        using namespace Generators;
+        GeneratorTracker& tracker = GeneratorTracker::acquire( m_trackerContext, TestCaseTracking::NameAndLocation( "generator", lineInfo ) );
+        assert( tracker.isOpen() );
+        m_lastAssertionInfo.lineInfo = lineInfo;
+        return tracker;
+    }
 
     bool RunContext::testForMissingAssertions(Counts& assertions) {
         if (assertions.total() != 0)
@@ -8949,7 +9651,7 @@ namespace Catch {
 
         // Recreate section for test case (as we will lose the one that was in scope)
         auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
-        SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description);
+        SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
 
         Counts assertions;
         assertions.failed = 1;
@@ -8982,12 +9684,12 @@ namespace Catch {
     }
 
     bool RunContext::aborting() const {
-        return m_totals.assertions.failed == static_cast<std::size_t>(m_config->abortAfter());
+        return m_totals.assertions.failed >= static_cast<std::size_t>(m_config->abortAfter());
     }
 
     void RunContext::runCurrentTest(std::string & redirectedCout, std::string & redirectedCerr) {
         auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
-        SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description);
+        SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
         m_reporter->sectionStarting(testCaseSection);
         Counts prevAssertions = m_totals.assertions;
         double duration = 0;
@@ -8997,7 +9699,7 @@ namespace Catch {
         seedRng(*m_config);
 
         Timer timer;
-        try {
+        CATCH_TRY {
             if (m_reporter->getPreferences().shouldRedirectStdOut) {
 #if !defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
                 RedirectedStdOut redirectedStdOut;
@@ -9017,9 +9719,9 @@ namespace Catch {
                 invokeActiveTestCase();
             }
             duration = timer.getElapsedSeconds();
-        } catch (TestFailureException&) {
+        } CATCH_CATCH_ANON (TestFailureException&) {
             // This just means the test was aborted due to failure
-        } catch (...) {
+        } CATCH_CATCH_ALL {
             // Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions
             // are reported without translation at the point of origin.
             if( m_shouldReportUnexpected ) {
@@ -9182,7 +9884,7 @@ namespace Catch {
 
     Section::~Section() {
         if( m_sectionIncluded ) {
-            SectionEndInfo endInfo( m_info, m_assertions, m_timer.getElapsedSeconds() );
+            SectionEndInfo endInfo{ m_info, m_assertions, m_timer.getElapsedSeconds() };
             if( uncaught_exceptions() )
                 getResultCapture().sectionEndedEarly( endInfo );
             else
@@ -9203,17 +9905,11 @@ namespace Catch {
 
     SectionInfo::SectionInfo
         (   SourceLineInfo const& _lineInfo,
-            std::string const& _name,
-            std::string const& _description )
+            std::string const& _name )
     :   name( _name ),
-        description( _description ),
         lineInfo( _lineInfo )
     {}
 
-    SectionEndInfo::SectionEndInfo( SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds )
-    : sectionInfo( _sectionInfo ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds )
-    {}
-
 } // end namespace Catch
 // end catch_section_info.cpp
 // start catch_session.cpp
@@ -9386,10 +10082,12 @@ namespace Catch {
     Session::Session() {
         static bool alreadyInstantiated = false;
         if( alreadyInstantiated ) {
-            try         { CATCH_INTERNAL_ERROR( "Only one instance of Catch::Session can ever be used" ); }
-            catch(...)  { getMutableRegistryHub().registerStartupException(); }
+            CATCH_TRY { CATCH_INTERNAL_ERROR( "Only one instance of Catch::Session can ever be used" ); }
+            CATCH_CATCH_ALL { getMutableRegistryHub().registerStartupException(); }
         }
 
+        // There cannot be exceptions at startup in no-exception mode.
+#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
         const auto& exceptions = getRegistryHub().getStartupExceptionRegistry().getExceptions();
         if ( !exceptions.empty() ) {
             m_startupExceptions = true;
@@ -9404,6 +10102,7 @@ namespace Catch {
                 }
             }
         }
+#endif
 
         alreadyInstantiated = true;
         m_cli = makeCommandLineParser( m_configData );
@@ -9518,11 +10217,11 @@ namespace Catch {
         if( m_startupExceptions )
             return 1;
 
-        if( m_configData.showHelp || m_configData.libIdentify )
+        if (m_configData.showHelp || m_configData.libIdentify) {
             return 0;
+        }
 
-        try
-        {
+        CATCH_TRY {
             config(); // Force config to be constructed
 
             seedRng( *m_config );
@@ -9540,22 +10239,53 @@ namespace Catch {
             // of 256 tests has failed
             return (std::min) (MaxExitCode, (std::max) (totals.error, static_cast<int>(totals.assertions.failed)));
         }
+#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
         catch( std::exception& ex ) {
             Catch::cerr() << ex.what() << std::endl;
             return MaxExitCode;
         }
+#endif
     }
 
 } // end namespace Catch
 // end catch_session.cpp
+// start catch_singletons.cpp
+
+#include <vector>
+
+namespace Catch {
+
+    namespace {
+        static auto getSingletons() -> std::vector<ISingleton*>*& {
+            static std::vector<ISingleton*>* g_singletons = nullptr;
+            if( !g_singletons )
+                g_singletons = new std::vector<ISingleton*>();
+            return g_singletons;
+        }
+    }
+
+    ISingleton::~ISingleton() {}
+
+    void addSingleton(ISingleton* singleton ) {
+        getSingletons()->push_back( singleton );
+    }
+    void cleanupSingletons() {
+        auto& singletons = getSingletons();
+        for( auto singleton : *singletons )
+            delete singleton;
+        delete singletons;
+        singletons = nullptr;
+    }
+
+} // namespace Catch
+// end catch_singletons.cpp
 // start catch_startup_exception_registry.cpp
 
 namespace Catch {
-    void StartupExceptionRegistry::add( std::exception_ptr const& exception ) noexcept {
-        try {
+void StartupExceptionRegistry::add( std::exception_ptr const& exception ) noexcept {
+        CATCH_TRY {
             m_exceptions.push_back(exception);
-        }
-        catch(...) {
+        } CATCH_CATCH_ALL {
             // If we run out of memory during start-up there's really not a lot more we can do about it
             std::terminate();
         }
@@ -9576,11 +10306,6 @@ namespace Catch {
 #include <vector>
 #include <memory>
 
-#if defined(__clang__)
-#    pragma clang diagnostic push
-#    pragma clang diagnostic ignored "-Wexit-time-destructors"
-#endif
-
 namespace Catch {
 
     Catch::IStream::~IStream() = default;
@@ -9700,7 +10425,6 @@ namespace Catch {
         std::vector<std::unique_ptr<std::ostringstream>> m_streams;
         std::vector<std::size_t> m_unused;
         std::ostringstream m_referenceStream; // Used for copy state/ flags from
-        static StringStreams* s_instance;
 
         auto add() -> std::size_t {
             if( m_unused.empty() ) {
@@ -9718,34 +10442,17 @@ namespace Catch {
             m_streams[index]->copyfmt( m_referenceStream ); // Restore initial flags and other state
             m_unused.push_back(index);
         }
-
-        // !TBD: put in TLS
-        static auto instance() -> StringStreams& {
-            if( !s_instance )
-                s_instance = new StringStreams();
-            return *s_instance;
-        }
-        static void cleanup() {
-            delete s_instance;
-            s_instance = nullptr;
-        }
     };
 
-    StringStreams* StringStreams::s_instance = nullptr;
-
-    void ReusableStringStream::cleanup() {
-        StringStreams::cleanup();
-    }
-
     ReusableStringStream::ReusableStringStream()
-    :   m_index( StringStreams::instance().add() ),
-        m_oss( StringStreams::instance().m_streams[m_index].get() )
+    :   m_index( Singleton<StringStreams>::getMutable().add() ),
+        m_oss( Singleton<StringStreams>::getMutable().m_streams[m_index].get() )
     {}
 
     ReusableStringStream::~ReusableStringStream() {
         static_cast<std::ostringstream*>( m_oss )->str("");
         m_oss->clear();
-        StringStreams::instance().release( m_index );
+        Singleton<StringStreams>::getMutable().release( m_index );
     }
 
     auto ReusableStringStream::str() const -> std::string {
@@ -9760,10 +10467,6 @@ namespace Catch {
     std::ostream& clog() { return std::clog; }
 #endif
 }
-
-#if defined(__clang__)
-#    pragma clang diagnostic pop
-#endif
 // end catch_stream.cpp
 // start catch_string_manip.cpp
 
@@ -9774,6 +10477,12 @@ namespace Catch {
 
 namespace Catch {
 
+    namespace {
+        char toLowerCh(char c) {
+            return static_cast<char>( std::tolower( c ) );
+        }
+    }
+
     bool startsWith( std::string const& s, std::string const& prefix ) {
         return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin());
     }
@@ -9789,9 +10498,6 @@ namespace Catch {
     bool contains( std::string const& s, std::string const& infix ) {
         return s.find( infix ) != std::string::npos;
     }
-    char toLowerCh(char c) {
-        return static_cast<char>( std::tolower( c ) );
-    }
     void toLowerInPlace( std::string& s ) {
         std::transform( s.begin(), s.end(), s.begin(), toLowerCh );
     }
@@ -9967,9 +10673,9 @@ namespace Catch {
 namespace Catch {
 
     RegistrarForTagAliases::RegistrarForTagAliases(char const* alias, char const* tag, SourceLineInfo const& lineInfo) {
-        try {
+        CATCH_TRY {
             getMutableRegistryHub().registerTagAlias(alias, tag, lineInfo);
-        } catch (...) {
+        } CATCH_CATCH_ALL {
             // Do not throw when constructing global objects, instead register the exception to be processed later
             getMutableRegistryHub().registerStartupException();
         }
@@ -10033,31 +10739,33 @@ namespace Catch {
 
 namespace Catch {
 
-    TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
-        if( startsWith( tag, '.' ) ||
-            tag == "!hide" )
-            return TestCaseInfo::IsHidden;
-        else if( tag == "!throws" )
-            return TestCaseInfo::Throws;
-        else if( tag == "!shouldfail" )
-            return TestCaseInfo::ShouldFail;
-        else if( tag == "!mayfail" )
-            return TestCaseInfo::MayFail;
-        else if( tag == "!nonportable" )
-            return TestCaseInfo::NonPortable;
-        else if( tag == "!benchmark" )
-            return static_cast<TestCaseInfo::SpecialProperties>( TestCaseInfo::Benchmark | TestCaseInfo::IsHidden );
-        else
-            return TestCaseInfo::None;
-    }
-    bool isReservedTag( std::string const& tag ) {
-        return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( static_cast<unsigned char>(tag[0]) );
-    }
-    void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
-        CATCH_ENFORCE( !isReservedTag(tag),
-                      "Tag name: [" << tag << "] is not allowed.\n"
-                      << "Tag names starting with non alpha-numeric characters are reserved\n"
-                      << _lineInfo );
+    namespace {
+        TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
+            if( startsWith( tag, '.' ) ||
+                tag == "!hide" )
+                return TestCaseInfo::IsHidden;
+            else if( tag == "!throws" )
+                return TestCaseInfo::Throws;
+            else if( tag == "!shouldfail" )
+                return TestCaseInfo::ShouldFail;
+            else if( tag == "!mayfail" )
+                return TestCaseInfo::MayFail;
+            else if( tag == "!nonportable" )
+                return TestCaseInfo::NonPortable;
+            else if( tag == "!benchmark" )
+                return static_cast<TestCaseInfo::SpecialProperties>( TestCaseInfo::Benchmark | TestCaseInfo::IsHidden );
+            else
+                return TestCaseInfo::None;
+        }
+        bool isReservedTag( std::string const& tag ) {
+            return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( static_cast<unsigned char>(tag[0]) );
+        }
+        void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
+            CATCH_ENFORCE( !isReservedTag(tag),
+                          "Tag name: [" << tag << "] is not allowed.\n"
+                          << "Tag names starting with non alpha-numeric characters are reserved\n"
+                          << _lineInfo );
+        }
     }
 
     TestCase makeTestCase(  ITestInvoker* _testCase,
@@ -10205,7 +10913,7 @@ namespace Catch {
                 break;
             case RunTests::InRandomOrder:
                 seedRng( config );
-                RandomNumberGenerator::shuffle( sorted );
+                std::shuffle( sorted.begin(), sorted.end(), rng() );
                 break;
             case RunTests::InDeclarationOrder:
                 // already in declaration order
@@ -10345,13 +11053,6 @@ namespace TestCaseTracking {
         m_currentTracker = tracker;
     }
 
-    TrackerBase::TrackerHasName::TrackerHasName( NameAndLocation const& nameAndLocation ) : m_nameAndLocation( nameAndLocation ) {}
-    bool TrackerBase::TrackerHasName::operator ()( ITrackerPtr const& tracker ) const {
-        return
-            tracker->nameAndLocation().name == m_nameAndLocation.name &&
-            tracker->nameAndLocation().location == m_nameAndLocation.location;
-    }
-
     TrackerBase::TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
     :   m_nameAndLocation( nameAndLocation ),
         m_ctx( ctx ),
@@ -10379,7 +11080,12 @@ namespace TestCaseTracking {
     }
 
     ITrackerPtr TrackerBase::findChild( NameAndLocation const& nameAndLocation ) {
-        auto it = std::find_if( m_children.begin(), m_children.end(), TrackerHasName( nameAndLocation ) );
+        auto it = std::find_if( m_children.begin(), m_children.end(),
+            [&nameAndLocation]( ITrackerPtr const& tracker ){
+                return
+                    tracker->nameAndLocation().location == nameAndLocation.location &&
+                    tracker->nameAndLocation().name == nameAndLocation.name;
+            } );
         return( it != m_children.end() )
             ? *it
             : nullptr;
@@ -10571,7 +11277,7 @@ namespace Catch {
     NameAndTags::NameAndTags( StringRef const& name_ , StringRef const& tags_ ) noexcept : name( name_ ), tags( tags_ ) {}
 
     AutoReg::AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept {
-        try {
+        CATCH_TRY {
             getMutableRegistryHub()
                     .registerTest(
                         makeTestCase(
@@ -10579,7 +11285,7 @@ namespace Catch {
                             extractClassName( classOrMethod ),
                             nameAndTags,
                             lineInfo));
-        } catch (...) {
+        } CATCH_CATCH_ALL {
             // Do not throw when constructing global objects, instead register the exception to be processed later
             getMutableRegistryHub().registerStartupException();
         }
@@ -10733,34 +11439,36 @@ namespace Catch {
         return std::chrono::duration_cast<std::chrono::nanoseconds>( std::chrono::high_resolution_clock::now().time_since_epoch() ).count();
     }
 
-    auto estimateClockResolution() -> uint64_t {
-        uint64_t sum = 0;
-        static const uint64_t iterations = 1000000;
+    namespace {
+        auto estimateClockResolution() -> uint64_t {
+            uint64_t sum = 0;
+            static const uint64_t iterations = 1000000;
 
-        auto startTime = getCurrentNanosecondsSinceEpoch();
+            auto startTime = getCurrentNanosecondsSinceEpoch();
 
-        for( std::size_t i = 0; i < iterations; ++i ) {
+            for( std::size_t i = 0; i < iterations; ++i ) {
 
-            uint64_t ticks;
-            uint64_t baseTicks = getCurrentNanosecondsSinceEpoch();
-            do {
-                ticks = getCurrentNanosecondsSinceEpoch();
-            } while( ticks == baseTicks );
+                uint64_t ticks;
+                uint64_t baseTicks = getCurrentNanosecondsSinceEpoch();
+                do {
+                    ticks = getCurrentNanosecondsSinceEpoch();
+                } while( ticks == baseTicks );
 
-            auto delta = ticks - baseTicks;
-            sum += delta;
+                auto delta = ticks - baseTicks;
+                sum += delta;
 
-            // If we have been calibrating for over 3 seconds -- the clock
-            // is terrible and we should move on.
-            // TBD: How to signal that the measured resolution is probably wrong?
-            if (ticks > startTime + 3 * nanosecondsInSecond) {
-                return sum / i;
+                // If we have been calibrating for over 3 seconds -- the clock
+                // is terrible and we should move on.
+                // TBD: How to signal that the measured resolution is probably wrong?
+                if (ticks > startTime + 3 * nanosecondsInSecond) {
+                    return sum / i;
+                }
             }
-        }
 
-        // We're just taking the mean, here. To do better we could take the std. dev and exclude outliers
-        // - and potentially do more iterations if there's a high variance.
-        return sum/iterations;
+            // We're just taking the mean, here. To do better we could take the std. dev and exclude outliers
+            // - and potentially do more iterations if there's a high variance.
+            return sum/iterations;
+        }
     }
     auto getEstimatedClockResolution() -> uint64_t {
         static auto s_resolution = estimateClockResolution();
@@ -10891,14 +11599,9 @@ std::string StringMaker<std::string>::convert(const std::string& str) {
     return s;
 }
 
-#ifdef CATCH_CONFIG_WCHAR
-std::string StringMaker<std::wstring>::convert(const std::wstring& wstr) {
-    std::string s;
-    s.reserve(wstr.size());
-    for (auto c : wstr) {
-        s += (c <= 0xff) ? static_cast<char>(c) : '?';
-    }
-    return ::Catch::Detail::stringify(s);
+#ifdef CATCH_CONFIG_CPP17_STRING_VIEW
+std::string StringMaker<std::string_view>::convert(std::string_view str) {
+    return ::Catch::Detail::stringify(std::string{ str });
 }
 #endif
 
@@ -10916,7 +11619,23 @@ std::string StringMaker<char*>::convert(char* str) {
         return{ "{null string}" };
     }
 }
+
 #ifdef CATCH_CONFIG_WCHAR
+std::string StringMaker<std::wstring>::convert(const std::wstring& wstr) {
+    std::string s;
+    s.reserve(wstr.size());
+    for (auto c : wstr) {
+        s += (c <= 0xff) ? static_cast<char>(c) : '?';
+    }
+    return ::Catch::Detail::stringify(s);
+}
+
+# ifdef CATCH_CONFIG_CPP17_STRING_VIEW
+std::string StringMaker<std::wstring_view>::convert(std::wstring_view str) {
+    return StringMaker<std::wstring>::convert(std::wstring(str));
+}
+# endif
+
 std::string StringMaker<wchar_t const*>::convert(wchar_t const * str) {
     if (str) {
         return ::Catch::Detail::stringify(std::wstring{ str });
@@ -11004,8 +11723,8 @@ std::string StringMaker<double>::convert(double value) {
 
 std::string ratio_string<std::atto>::symbol() { return "a"; }
 std::string ratio_string<std::femto>::symbol() { return "f"; }
-std::string  ratio_string<std::pico>::symbol() { return "p"; }
-std::string  ratio_string<std::nano>::symbol() { return "n"; }
+std::string ratio_string<std::pico>::symbol() { return "p"; }
+std::string ratio_string<std::nano>::symbol() { return "n"; }
 std::string ratio_string<std::micro>::symbol() { return "u"; }
 std::string ratio_string<std::milli>::symbol() { return "m"; }
 
@@ -11117,7 +11836,7 @@ namespace Catch {
     }
 
     Version const& libraryVersion() {
-        static Version version( 2, 2, 3, "", 0 );
+        static Version version( 2, 4, 1, "", 0 );
         return version;
     }
 
@@ -11719,9 +12438,7 @@ private:
         }
 
         ReporterPreferences CompactReporter::getPreferences() const {
-            ReporterPreferences prefs;
-            prefs.shouldRedirectStdOut = false;
-            return prefs;
+            return m_reporterPrefs;
         }
 
         void CompactReporter::noMatchingTestCases( std::string const& spec ) {
@@ -12436,6 +13153,7 @@ namespace Catch {
             xml( _config.stream() )
         {
             m_reporterPrefs.shouldRedirectStdOut = true;
+            m_reporterPrefs.shouldReportAllAssertions = true;
         }
 
     JunitReporter::~JunitReporter() {}
@@ -12626,6 +13344,11 @@ namespace Catch {
 
 namespace Catch {
 
+    ListeningReporter::ListeningReporter() {
+        // We will assume that listeners will always want all assertions
+        m_preferences.shouldReportAllAssertions = true;
+    }
+
     void ListeningReporter::addListener( IStreamingReporterPtr&& listener ) {
         m_listeners.push_back( std::move( listener ) );
     }
@@ -12633,10 +13356,11 @@ namespace Catch {
     void ListeningReporter::addReporter(IStreamingReporterPtr&& reporter) {
         assert(!m_reporter && "Listening reporter can wrap only 1 real reporter");
         m_reporter = std::move( reporter );
+        m_preferences.shouldRedirectStdOut = m_reporter->getPreferences().shouldRedirectStdOut;
     }
 
     ReporterPreferences ListeningReporter::getPreferences() const {
-        return m_reporter->getPreferences();
+        return m_preferences;
     }
 
     std::set<Verbosity> ListeningReporter::getSupportedVerbosities() {
@@ -12762,6 +13486,7 @@ namespace Catch {
         m_xml(_config.stream())
     {
         m_reporterPrefs.shouldRedirectStdOut = true;
+        m_reporterPrefs.shouldReportAllAssertions = true;
     }
 
     XmlReporter::~XmlReporter() = default;
@@ -12818,8 +13543,7 @@ namespace Catch {
         StreamingReporterBase::sectionStarting( sectionInfo );
         if( m_sectionDepth++ > 0 ) {
             m_xml.startElement( "Section" )
-                .writeAttribute( "name", trim( sectionInfo.name ) )
-                .writeAttribute( "description", sectionInfo.description );
+                .writeAttribute( "name", trim( sectionInfo.name ) );
             writeSourceInfo( sectionInfo.lineInfo );
             m_xml.ensureTagClosed();
         }
@@ -13054,13 +13778,14 @@ int main (int argc, char * const argv[]) {
 
 #define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg )
 #define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( "CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
-#define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( "CATCH_CAPTURE", #msg " := " << ::Catch::Detail::stringify(msg) )
+#define CATCH_CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CATCH_CAPTURE",__VA_ARGS__ )
 
 #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
 #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
 #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
 #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
 #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
+#define CATCH_DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )
 #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
 #define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
 #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
@@ -13070,11 +13795,12 @@ int main (int argc, char * const argv[]) {
 // "BDD-style" convenience wrappers
 #define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
 #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
-#define CATCH_GIVEN( desc )    CATCH_SECTION( std::string( "Given: ") + desc )
-#define CATCH_WHEN( desc )     CATCH_SECTION( std::string( " When: ") + desc )
-#define CATCH_AND_WHEN( desc ) CATCH_SECTION( std::string( "  And: ") + desc )
-#define CATCH_THEN( desc )     CATCH_SECTION( std::string( " Then: ") + desc )
-#define CATCH_AND_THEN( desc ) CATCH_SECTION( std::string( "  And: ") + desc )
+#define CATCH_GIVEN( desc )     INTERNAL_CATCH_DYNAMIC_SECTION( "    Given: " << desc )
+#define CATCH_AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc )
+#define CATCH_WHEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     When: " << desc )
+#define CATCH_AND_WHEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc )
+#define CATCH_THEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     Then: " << desc )
+#define CATCH_AND_THEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( "      And: " << desc )
 
 // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
 #else
@@ -13112,13 +13838,14 @@ int main (int argc, char * const argv[]) {
 
 #define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg )
 #define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
-#define CAPTURE( msg ) INTERNAL_CATCH_INFO( "CAPTURE", #msg " := " << ::Catch::Detail::stringify(msg) )
+#define CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CAPTURE",__VA_ARGS__ )
 
 #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
 #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
 #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
 #define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
 #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
+#define DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )
 #define FAIL( ... ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
 #define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
 #define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
@@ -13132,15 +13859,17 @@ int main (int argc, char * const argv[]) {
 #define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
 #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
 
-#define GIVEN( desc )    SECTION( std::string("   Given: ") + desc )
-#define WHEN( desc )     SECTION( std::string("    When: ") + desc )
-#define AND_WHEN( desc ) SECTION( std::string("And when: ") + desc )
-#define THEN( desc )     SECTION( std::string("    Then: ") + desc )
-#define AND_THEN( desc ) SECTION( std::string("     And: ") + desc )
+#define GIVEN( desc )     INTERNAL_CATCH_DYNAMIC_SECTION( "    Given: " << desc )
+#define AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc )
+#define WHEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     When: " << desc )
+#define AND_WHEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc )
+#define THEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     Then: " << desc )
+#define AND_THEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( "      And: " << desc )
 
 using Catch::Detail::Approx;
 
-#else
+#else // CATCH_CONFIG_DISABLE
+
 //////
 // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
 #ifdef CATCH_CONFIG_PREFIX_ALL
@@ -13185,6 +13914,7 @@ using Catch::Detail::Approx;
 #define CATCH_METHOD_AS_TEST_CASE( method, ... )
 #define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0)
 #define CATCH_SECTION( ... )
+#define CATCH_DYNAMIC_SECTION( ... )
 #define CATCH_FAIL( ... ) (void)(0)
 #define CATCH_FAIL_CHECK( ... ) (void)(0)
 #define CATCH_SUCCEED( ... ) (void)(0)
@@ -13195,6 +13925,7 @@ using Catch::Detail::Approx;
 #define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
 #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className )
 #define CATCH_GIVEN( desc )
+#define CATCH_AND_GIVEN( desc )
 #define CATCH_WHEN( desc )
 #define CATCH_AND_WHEN( desc )
 #define CATCH_THEN( desc )
@@ -13243,6 +13974,7 @@ using Catch::Detail::Approx;
 #define METHOD_AS_TEST_CASE( method, ... )
 #define REGISTER_TEST_CASE( Function, ... ) (void)(0)
 #define SECTION( ... )
+#define DYNAMIC_SECTION( ... )
 #define FAIL( ... ) (void)(0)
 #define FAIL_CHECK( ... ) (void)(0)
 #define SUCCEED( ... ) (void)(0)
@@ -13257,6 +13989,7 @@ using Catch::Detail::Approx;
 #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className )
 
 #define GIVEN( desc )
+#define AND_GIVEN( desc )
 #define WHEN( desc )
 #define AND_WHEN( desc )
 #define THEN( desc )
diff --git a/packages/Catch2/single_include/catch_reporter_automake.hpp b/packages/Catch2/single_include/catch2/catch_reporter_automake.hpp
similarity index 100%
rename from packages/Catch2/single_include/catch_reporter_automake.hpp
rename to packages/Catch2/single_include/catch2/catch_reporter_automake.hpp
diff --git a/packages/Catch2/single_include/catch_reporter_tap.hpp b/packages/Catch2/single_include/catch2/catch_reporter_tap.hpp
similarity index 98%
rename from packages/Catch2/single_include/catch_reporter_tap.hpp
rename to packages/Catch2/single_include/catch2/catch_reporter_tap.hpp
index 19e54ed19..ccc4051be 100644
--- a/packages/Catch2/single_include/catch_reporter_tap.hpp
+++ b/packages/Catch2/single_include/catch2/catch_reporter_tap.hpp
@@ -30,9 +30,7 @@ namespace Catch {
         }
 
         ReporterPreferences getPreferences() const override {
-            ReporterPreferences prefs;
-            prefs.shouldRedirectStdOut = false;
-            return prefs;
+            return m_reporterPrefs;
         }
 
         void noMatchingTestCases( std::string const& spec ) override {
diff --git a/packages/Catch2/single_include/catch_reporter_teamcity.hpp b/packages/Catch2/single_include/catch2/catch_reporter_teamcity.hpp
similarity index 98%
rename from packages/Catch2/single_include/catch_reporter_teamcity.hpp
rename to packages/Catch2/single_include/catch2/catch_reporter_teamcity.hpp
index dbd0db532..eca2885cd 100644
--- a/packages/Catch2/single_include/catch_reporter_teamcity.hpp
+++ b/packages/Catch2/single_include/catch2/catch_reporter_teamcity.hpp
@@ -97,12 +97,12 @@ namespace Catch {
                     case ResultWas::Ok:
                     case ResultWas::Info:
                     case ResultWas::Warning:
-                        throw std::domain_error( "Internal error in TeamCity reporter" );
+                        CATCH_ERROR( "Internal error in TeamCity reporter" );
                     // These cases are here to prevent compiler warnings
                     case ResultWas::Unknown:
                     case ResultWas::FailureBit:
                     case ResultWas::Exception:
-                        throw std::domain_error( "Not implemented" );
+                        CATCH_ERROR( "Not implemented" );
                 }
                 if( assertionStats.infoMessages.size() == 1 )
                     msg << " with message:";
diff --git a/packages/Catch2/test_package/MainTest.cpp b/packages/Catch2/test_package/MainTest.cpp
index b8ed744e5..010feba21 100644
--- a/packages/Catch2/test_package/MainTest.cpp
+++ b/packages/Catch2/test_package/MainTest.cpp
@@ -6,7 +6,7 @@
  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  */
 #define CATCH_CONFIG_MAIN
-#include "catch.hpp"
+#include <catch2/catch.hpp>
 
 unsigned int Factorial( unsigned int number ) {
   return number > 1 ? Factorial(number-1)*number : 1;
diff --git a/packages/Catch2/test_package/conanfile.py b/packages/Catch2/test_package/conanfile.py
index 7ed77b5ca..e8d50f9a8 100644
--- a/packages/Catch2/test_package/conanfile.py
+++ b/packages/Catch2/test_package/conanfile.py
@@ -10,7 +10,7 @@ class CatchConanTest(ConanFile):
     settings = "os", "compiler", "arch", "build_type"
     username = getenv("CONAN_USERNAME", "philsquared")
     channel = getenv("CONAN_CHANNEL", "testing")
-    requires = "Catch/2.2.3@%s/%s" % (username, channel)
+    requires = "Catch/2.4.1@%s/%s" % (username, channel)
 
     def build(self):
         cmake = CMake(self)
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index c36e9a2d5..94118a24d 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -13,12 +13,12 @@ add_executable (unit_tests
   test_TinyVector.cpp
   )
 
-target_include_directories(Catch INTERFACE ${CATCH_INCLUDE_DIR})
+target_include_directories(Catch2 INTERFACE ${CATCH_INCLUDE_DIR})
 
 target_link_libraries (unit_tests
   PastisUtils
   kokkos
-  Catch
+  Catch2
   )
 
 enable_testing()
-- 
GitLab