From 7de34a384b9d2e24dbbf3707aa01fad53b7df4e6 Mon Sep 17 00:00:00 2001
From: Stephane Del Pino <stephane.delpino44@gmail.com>
Date: Sun, 20 Oct 2019 19:22:59 +0200
Subject: [PATCH] git subrepo pull packages/Catch2

subrepo:
  subdir:   "packages/Catch2"
  merged:   "060a41ec7"
upstream:
  origin:   "git@github.com:catchorg/Catch2.git"
  branch:   "master"
  commit:   "060a41ec7"
git-subrepo:
  version:  "0.4.0"
  origin:   "git@github.com:ingydotnet/git-subrepo.git"
  commit:   "5d6aba9"
---
 packages/Catch2/.github/FUNDING.yml           |    1 +
 packages/Catch2/.gitrepo                      |    4 +-
 packages/Catch2/.travis.yml                   |   25 +-
 packages/Catch2/CMakeLists.txt                |   31 +-
 packages/Catch2/README.md                     |    9 +-
 packages/Catch2/artwork/catch2-c-logo.png     |  Bin 18222 -> 10636 bytes
 packages/Catch2/artwork/catch2-hand-logo.png  |  Bin 57969 -> 33761 bytes
 packages/Catch2/artwork/catch2-logo-small.png |  Bin 29025 -> 20939 bytes
 packages/Catch2/conanfile.py                  |    2 +-
 packages/Catch2/contrib/CatchAddTests.cmake   |    7 +-
 .../contrib/ParseAndAddCatchTests.cmake       |    5 +
 packages/Catch2/docs/Readme.md                |    1 +
 packages/Catch2/docs/assertions.md            |    2 +-
 packages/Catch2/docs/benchmarks.md            |  256 +
 packages/Catch2/docs/command-line.md          |   61 +-
 packages/Catch2/docs/commercial-users.md      |    1 +
 packages/Catch2/docs/configuration.md         |   19 +-
 packages/Catch2/docs/contributing.md          |   92 +-
 packages/Catch2/docs/deprecations.md          |    5 +
 packages/Catch2/docs/event-listeners.md       |    6 +-
 packages/Catch2/docs/generators.md            |   27 +-
 packages/Catch2/docs/logging.md               |    4 +
 packages/Catch2/docs/matchers.md              |   85 +-
 packages/Catch2/docs/opensource-users.md      |    9 +-
 packages/Catch2/docs/other-macros.md          |    4 +
 packages/Catch2/docs/release-notes.md         |  150 +-
 packages/Catch2/docs/slow-compiles.md         |    5 +-
 .../Catch2/docs/test-cases-and-sections.md    |   85 +-
 packages/Catch2/docs/test-fixtures.md         |   54 +
 packages/Catch2/docs/tostring.md              |   67 +-
 .../examples/210-Evt-EventListeners.cpp       |   18 +-
 packages/Catch2/include/catch.hpp             |   88 +-
 .../internal/benchmark/catch_benchmark.hpp    |  122 +
 .../internal/benchmark/catch_chronometer.hpp  |   71 +
 .../internal/benchmark/catch_clock.hpp        |   40 +
 .../internal/benchmark/catch_constructor.hpp  |   73 +
 .../internal/benchmark/catch_environment.hpp  |   38 +
 .../internal/benchmark/catch_estimate.hpp     |   31 +
 .../benchmark/catch_execution_plan.hpp        |   58 +
 .../internal/benchmark/catch_optimizer.hpp    |   68 +
 .../catch_outlier_classification.hpp          |   29 +
 .../benchmark/catch_sample_analysis.hpp       |   50 +
 .../benchmark/detail/catch_analyse.hpp        |   78 +
 .../detail/catch_benchmark_function.hpp       |  105 +
 .../detail/catch_complete_invoke.hpp          |   69 +
 .../benchmark/detail/catch_estimate_clock.hpp |  113 +
 .../benchmark/detail/catch_measure.hpp        |   35 +
 .../benchmark/detail/catch_repeat.hpp         |   37 +
 .../detail/catch_run_for_at_least.hpp         |   65 +
 .../internal/benchmark/detail/catch_stats.cpp |  223 +
 .../internal/benchmark/detail/catch_stats.hpp |  158 +
 .../benchmark/detail/catch_timing.hpp         |   33 +
 .../Catch2/include/internal/catch_approx.cpp  |   19 +-
 .../internal/catch_assertionresult.cpp        |   20 +-
 .../include/internal/catch_benchmark.cpp      |   36 -
 .../Catch2/include/internal/catch_benchmark.h |   57 -
 .../include/internal/catch_capture_matchers.h |    1 +
 .../include/internal/catch_commandline.cpp    |   26 +-
 .../Catch2/include/internal/catch_common.cpp  |    3 -
 .../Catch2/include/internal/catch_common.h    |    2 +-
 .../internal/catch_compiler_capabilities.h    |  130 +-
 .../Catch2/include/internal/catch_config.cpp  |   24 +-
 .../Catch2/include/internal/catch_config.hpp  |   13 +-
 .../include/internal/catch_console_colour.cpp |   12 +-
 .../Catch2/include/internal/catch_context.cpp |   22 +-
 .../Catch2/include/internal/catch_context.h   |    4 +
 .../include/internal/catch_debug_console.cpp  |   12 +-
 .../Catch2/include/internal/catch_enforce.cpp |   21 +
 .../Catch2/include/internal/catch_enforce.h   |   35 +-
 .../internal/catch_enum_values_registry.cpp   |   75 +
 .../internal/catch_enum_values_registry.h     |   35 +
 .../catch_exception_translator_registry.h     |    2 +-
 .../internal/catch_fatal_condition.cpp        |    2 +-
 .../include/internal/catch_generators.hpp     |    3 +
 .../internal/catch_generators_generic.hpp     |   15 +-
 .../internal/catch_generators_specific.hpp    |   54 +-
 .../internal/catch_interfaces_capture.h       |   15 +-
 .../internal/catch_interfaces_config.cpp      |    2 +-
 .../internal/catch_interfaces_config.h        |    9 +-
 .../catch_interfaces_enum_values_registry.h   |   46 +
 .../internal/catch_interfaces_exception.cpp   |    2 +-
 .../catch_interfaces_registry_hub.cpp         |    2 +-
 .../internal/catch_interfaces_registry_hub.h  |    4 +-
 .../internal/catch_interfaces_reporter.h      |   50 +-
 .../internal/catch_interfaces_runner.cpp      |    2 +-
 .../internal/catch_interfaces_testcase.cpp    |    2 +-
 .../internal/catch_interfaces_testcase.h      |    1 +
 .../Catch2/include/internal/catch_list.cpp    |   15 +-
 .../Catch2/include/internal/catch_matchers.h  |    9 +
 .../internal/catch_matchers_exception.cpp     |   30 +
 .../internal/catch_matchers_exception.hpp     |   36 +
 .../internal/catch_matchers_floating.cpp      |  203 +-
 .../internal/catch_matchers_floating.h        |   31 +-
 .../include/internal/catch_matchers_vector.h  |   87 +-
 .../Catch2/include/internal/catch_message.cpp |   18 +-
 .../Catch2/include/internal/catch_meta.hpp    |   71 +-
 .../Catch2/include/internal/catch_objc.hpp    |   10 +-
 .../include/internal/catch_preprocessor.hpp   |  167 +-
 .../catch_random_number_generator.cpp         |   62 +-
 .../internal/catch_random_number_generator.h  |   49 +-
 .../include/internal/catch_registry_hub.cpp   |    5 +
 .../internal/catch_reporter_registrars.hpp    |    8 +-
 .../include/internal/catch_run_context.cpp    |   27 +-
 .../include/internal/catch_run_context.h      |    8 +-
 .../Catch2/include/internal/catch_session.cpp |   99 +-
 .../Catch2/include/internal/catch_session.h   |    2 +-
 .../Catch2/include/internal/catch_stream.cpp  |    8 +-
 .../include/internal/catch_string_manip.cpp   |   29 +
 .../include/internal/catch_string_manip.h     |    9 +
 .../include/internal/catch_stringref.cpp      |   53 +-
 .../Catch2/include/internal/catch_stringref.h |   20 +-
 .../include/internal/catch_test_case_info.cpp |    5 +-
 .../catch_test_case_registry_impl.cpp         |   10 +-
 .../internal/catch_test_case_registry_impl.h  |    2 +
 .../internal/catch_test_case_tracker.cpp      |   23 +-
 .../internal/catch_test_case_tracker.h        |    3 +-
 .../include/internal/catch_test_registry.h    |  279 +-
 .../include/internal/catch_test_spec.cpp      |   80 +-
 .../Catch2/include/internal/catch_test_spec.h |   36 +-
 .../internal/catch_test_spec_parser.cpp       |  175 +-
 .../include/internal/catch_test_spec_parser.h |   41 +-
 .../include/internal/catch_tostring.cpp       |   15 +-
 .../Catch2/include/internal/catch_tostring.h  |   25 +-
 .../include/internal/catch_type_traits.hpp    |   40 -
 .../Catch2/include/internal/catch_version.cpp |    2 +-
 .../internal/catch_wildcard_pattern.cpp       |   16 +-
 .../include/internal/catch_wildcard_pattern.h |    2 +-
 .../reporters/catch_reporter_bases.hpp        |    4 +-
 .../reporters/catch_reporter_compact.cpp      |   15 +-
 .../reporters/catch_reporter_console.cpp      |  145 +-
 .../reporters/catch_reporter_console.h        |   11 +-
 .../reporters/catch_reporter_listening.cpp    |   28 +-
 .../reporters/catch_reporter_listening.h      |   12 +-
 .../reporters/catch_reporter_teamcity.hpp     |    3 +-
 .../include/reporters/catch_reporter_xml.cpp  |   45 +
 .../include/reporters/catch_reporter_xml.h    |    7 +
 .../misc/appveyorMergeCoverageScript.py       |    4 +-
 packages/Catch2/misc/coverage-helper.cpp      |   26 +-
 packages/Catch2/projects/CMakeLists.txt       |  131 +-
 .../Catch2/projects/ExtraTests/CMakeLists.txt |   23 +
 .../ExtraTests/X01-PrefixedMacros.cpp         |    1 +
 .../ExtraTests/X20-BenchmarkingMacros.cpp     |  133 +
 .../ExtraTests/X90-WindowsHeaderInclusion.cpp |   12 +
 .../Baselines/compact.sw.approved.txt         |  366 +-
 .../Baselines/console.std.approved.txt        |  113 +-
 .../Baselines/console.sw.approved.txt         | 2492 ++++++++--
 .../Baselines/console.swa4.approved.txt       |   20 +-
 .../SelfTest/Baselines/junit.sw.approved.txt  |  133 +-
 .../SelfTest/Baselines/xml.sw.approved.txt    | 2712 +++++++++--
 .../IntrospectiveTests/CmdLine.tests.cpp      |   48 +
 .../IntrospectiveTests/Details.tests.cpp      |   23 +
 .../GeneratorsImpl.tests.cpp                  |   27 +-
 .../InternalBenchmark.tests.cpp               |  405 ++
 .../IntrospectiveTests/PartTracker.tests.cpp  |   30 +-
 .../RandomNumberGeneration.tests.cpp          |   45 +
 .../IntrospectiveTests/String.tests.cpp       |   65 +-
 .../IntrospectiveTests/StringManip.tests.cpp  |   67 +
 .../IntrospectiveTests/ToString.tests.cpp     |   42 +
 .../SelfTest/Misc/invalid-test-names.input    |    1 +
 .../SelfTest/Misc/plain-old-tests.input       |    2 +
 .../Misc/special-characters-in-file.input     |    1 +
 .../SelfTest/UsageTests/Approx.tests.cpp      |    7 +-
 .../SelfTest/UsageTests/Benchmark.tests.cpp   |  141 +-
 .../SelfTest/UsageTests/Class.tests.cpp       |   34 +
 .../SelfTest/UsageTests/Compilation.tests.cpp |   27 +-
 .../UsageTests/EnumToString.tests.cpp         |   35 +-
 .../SelfTest/UsageTests/Generators.tests.cpp  |   54 +-
 .../SelfTest/UsageTests/Matchers.tests.cpp    |  161 +-
 .../SelfTest/UsageTests/Message.tests.cpp     |   13 +-
 .../SelfTest/UsageTests/Misc.tests.cpp        |   87 +-
 .../UsageTests/ToStringByte.tests.cpp         |   15 +
 .../UsageTests/ToStringGeneral.tests.cpp      |   34 +
 .../SelfTest/UsageTests/Tricky.tests.cpp      |   26 -
 .../projects/SelfTest/WarnAboutNoTests.cmake  |   19 +
 .../projects/Where did the projects go.txt    |   13 -
 .../extractFeaturesFromReleaseNotes.py        |   94 +
 .../Catch2/scripts/generateSingleHeader.py    |    2 +-
 packages/Catch2/scripts/releaseCommon.py      |   53 +-
 .../Catch2/single_include/catch2/catch.hpp    | 4173 +++++++++++++----
 .../catch2/catch_reporter_teamcity.hpp        |    3 +-
 180 files changed, 14612 insertions(+), 2758 deletions(-)
 create mode 100644 packages/Catch2/.github/FUNDING.yml
 create mode 100644 packages/Catch2/docs/benchmarks.md
 create mode 100644 packages/Catch2/include/internal/benchmark/catch_benchmark.hpp
 create mode 100644 packages/Catch2/include/internal/benchmark/catch_chronometer.hpp
 create mode 100644 packages/Catch2/include/internal/benchmark/catch_clock.hpp
 create mode 100644 packages/Catch2/include/internal/benchmark/catch_constructor.hpp
 create mode 100644 packages/Catch2/include/internal/benchmark/catch_environment.hpp
 create mode 100644 packages/Catch2/include/internal/benchmark/catch_estimate.hpp
 create mode 100644 packages/Catch2/include/internal/benchmark/catch_execution_plan.hpp
 create mode 100644 packages/Catch2/include/internal/benchmark/catch_optimizer.hpp
 create mode 100644 packages/Catch2/include/internal/benchmark/catch_outlier_classification.hpp
 create mode 100644 packages/Catch2/include/internal/benchmark/catch_sample_analysis.hpp
 create mode 100644 packages/Catch2/include/internal/benchmark/detail/catch_analyse.hpp
 create mode 100644 packages/Catch2/include/internal/benchmark/detail/catch_benchmark_function.hpp
 create mode 100644 packages/Catch2/include/internal/benchmark/detail/catch_complete_invoke.hpp
 create mode 100644 packages/Catch2/include/internal/benchmark/detail/catch_estimate_clock.hpp
 create mode 100644 packages/Catch2/include/internal/benchmark/detail/catch_measure.hpp
 create mode 100644 packages/Catch2/include/internal/benchmark/detail/catch_repeat.hpp
 create mode 100644 packages/Catch2/include/internal/benchmark/detail/catch_run_for_at_least.hpp
 create mode 100644 packages/Catch2/include/internal/benchmark/detail/catch_stats.cpp
 create mode 100644 packages/Catch2/include/internal/benchmark/detail/catch_stats.hpp
 create mode 100644 packages/Catch2/include/internal/benchmark/detail/catch_timing.hpp
 delete mode 100644 packages/Catch2/include/internal/catch_benchmark.cpp
 delete mode 100644 packages/Catch2/include/internal/catch_benchmark.h
 create mode 100644 packages/Catch2/include/internal/catch_enum_values_registry.cpp
 create mode 100644 packages/Catch2/include/internal/catch_enum_values_registry.h
 create mode 100644 packages/Catch2/include/internal/catch_interfaces_enum_values_registry.h
 create mode 100644 packages/Catch2/include/internal/catch_matchers_exception.cpp
 create mode 100644 packages/Catch2/include/internal/catch_matchers_exception.hpp
 delete mode 100644 packages/Catch2/include/internal/catch_type_traits.hpp
 create mode 100644 packages/Catch2/projects/ExtraTests/X20-BenchmarkingMacros.cpp
 create mode 100644 packages/Catch2/projects/ExtraTests/X90-WindowsHeaderInclusion.cpp
 create mode 100644 packages/Catch2/projects/SelfTest/IntrospectiveTests/Details.tests.cpp
 create mode 100644 packages/Catch2/projects/SelfTest/IntrospectiveTests/InternalBenchmark.tests.cpp
 create mode 100644 packages/Catch2/projects/SelfTest/IntrospectiveTests/RandomNumberGeneration.tests.cpp
 create mode 100644 packages/Catch2/projects/SelfTest/IntrospectiveTests/StringManip.tests.cpp
 create mode 100644 packages/Catch2/projects/SelfTest/IntrospectiveTests/ToString.tests.cpp
 create mode 100644 packages/Catch2/projects/SelfTest/Misc/invalid-test-names.input
 create mode 100644 packages/Catch2/projects/SelfTest/Misc/plain-old-tests.input
 create mode 100644 packages/Catch2/projects/SelfTest/Misc/special-characters-in-file.input
 create mode 100644 packages/Catch2/projects/SelfTest/UsageTests/ToStringByte.tests.cpp
 create mode 100644 packages/Catch2/projects/SelfTest/WarnAboutNoTests.cmake
 delete mode 100644 packages/Catch2/projects/Where did the projects go.txt
 create mode 100644 packages/Catch2/scripts/extractFeaturesFromReleaseNotes.py

diff --git a/packages/Catch2/.github/FUNDING.yml b/packages/Catch2/.github/FUNDING.yml
new file mode 100644
index 000000000..01d384e82
--- /dev/null
+++ b/packages/Catch2/.github/FUNDING.yml
@@ -0,0 +1 @@
+patreon: horenmar
diff --git a/packages/Catch2/.gitrepo b/packages/Catch2/.gitrepo
index a2720b741..81212f2a7 100644
--- a/packages/Catch2/.gitrepo
+++ b/packages/Catch2/.gitrepo
@@ -6,7 +6,7 @@
 [subrepo]
 	remote = git@github.com:catchorg/Catch2.git
 	branch = master
-	commit = 36fb8561633cca30a66d47314e5da9c61c6a756b
-	parent = da523f3d6fb1784863693f1a678839df16f5084f
+	commit = 060a41ec7b954cf6a556a88035f04b771680916b
+	parent = df97ccdd26a1350902ae665b134949710d78071e
 	cmdver = 0.4.0
 	method = merge
diff --git a/packages/Catch2/.travis.yml b/packages/Catch2/.travis.yml
index 345edfbb3..0fe2abb19 100644
--- a/packages/Catch2/.travis.yml
+++ b/packages/Catch2/.travis.yml
@@ -9,8 +9,8 @@ common_sources: &all_sources
   - llvm-toolchain-trusty
   - llvm-toolchain-trusty-3.9
   - llvm-toolchain-trusty-4.0
-  - llvm-toolchain-trusty-5.0
-  - llvm-toolchain-trusty-6.0
+  - llvm-toolchain-xenial-5.0
+  - llvm-toolchain-xenial-6.0
 
 matrix:
   include:
@@ -60,6 +60,7 @@ matrix:
       env: COMPILER='clang++-4.0'
 
     - os: linux
+      dist: xenial
       compiler: clang
       addons:
           apt:
@@ -68,6 +69,7 @@ matrix:
       env: COMPILER='clang++-5.0'
 
     - os: linux
+      dist: xenial
       compiler: clang
       addons:
           apt:
@@ -153,6 +155,7 @@ matrix:
       env: COMPILER='clang++-4.0' CPP14=1
 
     - os: linux
+      dist: xenial
       compiler: clang
       addons:
           apt:
@@ -161,6 +164,7 @@ matrix:
       env: COMPILER='clang++-5.0' CPP14=1
 
     - os: linux
+      dist: xenial
       compiler: clang
       addons:
           apt:
@@ -255,6 +259,7 @@ matrix:
       env: COMPILER='g++-7' EXAMPLES=1 COVERAGE=1 EXTRAS=1 CPP17=1
 
     - os: linux
+      dist: xenial
       compiler: clang
       addons:
           apt:
@@ -263,6 +268,7 @@ matrix:
       env: COMPILER='clang++-6.0' CPP17=1
 
     - os: linux
+      dist: xenial
       compiler: clang
       addons:
           apt:
@@ -276,7 +282,7 @@ matrix:
         - "3.7"
       dist: xenial
       install:
-        - pip install conan==1.10.2 conan-package-tools
+        - pip install conan-package-tools
       env:
         - CONAN_GCC_VERSIONS=8
         - CONAN_DOCKER_IMAGE=conanio/gcc8
@@ -301,10 +307,19 @@ before_script:
   # Regenerate single header file, so it is tested in the examples...
   - python scripts/generateSingleHeader.py
 
+  - |
+    if [[ ${CPP17} -eq 1 ]]; then
+      export CPP_STANDARD=17
+    elif [[ ${CPP14} -eq 1 ]]; then
+      export CPP_STANDARD=14
+    else
+      export CPP_STANDARD=11
+    fi
+
     # Use Debug builds for running Valgrind and building examples
-  - 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}
+  - cmake -H. -BBuild-Debug -DCMAKE_BUILD_TYPE=Debug -Wdev -DCATCH_USE_VALGRIND=${VALGRIND} -DCATCH_BUILD_EXAMPLES=${EXAMPLES} -DCATCH_ENABLE_COVERAGE=${COVERAGE} -DCATCH_BUILD_EXTRA_TESTS=${EXTRAS} -DCMAKE_CXX_STANDARD=${CPP_STANDARD} -DCMAKE_CXX_STANDARD_REQUIRED=On -DCMAKE_CXX_EXTENSIONS=OFF
     # Don't bother with release build for coverage build
-  - cmake -H. -BBuild-Release -DCMAKE_BUILD_TYPE=Release -Wdev -DUSE_CPP14=${CPP14} -DUSE_CPP17=${CPP17}
+  - cmake -H. -BBuild-Release -DCMAKE_BUILD_TYPE=Release -Wdev -DCMAKE_CXX_STANDARD=${CPP_STANDARD} -DCMAKE_CXX_STANDARD_REQUIRED=On -DCMAKE_CXX_EXTENSIONS=OFF
 
 
 script:
diff --git a/packages/Catch2/CMakeLists.txt b/packages/Catch2/CMakeLists.txt
index 660910469..2ead67597 100644
--- a/packages/Catch2/CMakeLists.txt
+++ b/packages/Catch2/CMakeLists.txt
@@ -6,7 +6,15 @@ if(NOT DEFINED PROJECT_NAME)
   set(NOT_SUBPROJECT ON)
 endif()
 
-project(Catch2 LANGUAGES CXX VERSION 2.7.1)
+# Catch2's build breaks if done in-tree. You probably should not build
+# things in tree anyway, but we can allow projects that include Catch2
+# as a subproject to build in-tree as long as it is not in our tree.
+if (CMAKE_BINARY_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
+    message(FATAL_ERROR "Building in-source is not supported! Create a build dir and remove ${CMAKE_SOURCE_DIR}/CMakeCache.txt")
+endif()
+
+
+project(Catch2 LANGUAGES CXX VERSION 2.10.0)
 
 # Provide path for scripts
 list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake")
@@ -88,6 +96,10 @@ target_include_directories(Catch2
     $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
 )
 
+if (ANDROID)
+    target_link_libraries(Catch2 INTERFACE log)
+endif()
+
 # provide a namespaced alias for clients to 'link' against if catch is included as a sub-project
 add_library(Catch2::Catch2 ALIAS Catch2)
 
@@ -132,9 +144,11 @@ if (NOT_SUBPROJECT)
     #
     # 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`.
+    # indirectly by temporarily redefining `CMAKE_SIZEOF_VOID_P` to an
+    # empty string. Note that just undefining the variable could be
+    # insufficient in cases where the variable was already in CMake cache
     set(CATCH2_CMAKE_SIZEOF_VOID_P ${CMAKE_SIZEOF_VOID_P})
-    unset(CMAKE_SIZEOF_VOID_P)
+    set(CMAKE_SIZEOF_VOID_P "")
     write_basic_package_version_file(
       "${CMAKE_CURRENT_BINARY_DIR}/Catch2ConfigVersion.cmake"
       COMPATIBILITY
@@ -205,4 +219,15 @@ if (NOT_SUBPROJECT)
         ${PKGCONFIG_INSTALL_DIR}
     )
 
+    # CPack/CMake started taking the package version from project version 3.12
+    # So we need to set the version manually for older CMake versions
+    if(${CMAKE_VERSION} VERSION_LESS "3.12.0")
+        set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
+    endif()
+
+    set(CPACK_PACKAGE_CONTACT "https://github.com/catchorg/Catch2/")
+
+
+    include( CPack )
+
 endif(NOT_SUBPROJECT)
diff --git a/packages/Catch2/README.md b/packages/Catch2/README.md
index a09ad44bb..2b806cd4d 100644
--- a/packages/Catch2/README.md
+++ b/packages/Catch2/README.md
@@ -5,11 +5,11 @@
 [![Build Status](https://travis-ci.org/catchorg/Catch2.svg?branch=master)](https://travis-ci.org/catchorg/Catch2)
 [![Build status](https://ci.appveyor.com/api/projects/status/github/catchorg/Catch2?svg=true)](https://ci.appveyor.com/project/catchorg/catch2)
 [![codecov](https://codecov.io/gh/catchorg/Catch2/branch/master/graph/badge.svg)](https://codecov.io/gh/catchorg/Catch2)
-[![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://wandbox.org/permlink/ZFBZ5XbLA9F1gzKi)
+[![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://wandbox.org/permlink/00GdTUbFWaV3bNah)
 [![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.7.1/catch.hpp">The latest version of the single header can be downloaded directly using this link</a>
+<a href="https://github.com/catchorg/Catch2/releases/download/v2.10.0/catch.hpp">The latest version of the single header can be downloaded directly using this link</a>
 
 ## Catch2 is released!
 
@@ -19,9 +19,8 @@ before moving to Catch2. You might also like to read [this blog post](https://le
 
 ## What's the Catch?
 
-Catch2 stands for C++ Automated Test Cases in a Header and is a
-multi-paradigm test framework for C++. which also supports Objective-C
-(and maybe C).
+Catch2 is a multi-paradigm test framework for C++. which also supports
+Objective-C (and maybe C).
 It is primarily distributed as a single header file, although certain
 extensions may require additional headers.
 
diff --git a/packages/Catch2/artwork/catch2-c-logo.png b/packages/Catch2/artwork/catch2-c-logo.png
index bab400f91a822bbd14b8712d5815111d4d1b6bea..b1066b8ee7edda10ec0b70d9e207e7c19062ace8 100644
GIT binary patch
literal 10636
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
JWt~$(69E1s?T7#X

literal 18222
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%0D~xxS?{o=F|4
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

diff --git a/packages/Catch2/artwork/catch2-hand-logo.png b/packages/Catch2/artwork/catch2-hand-logo.png
index 5a5e142d2b8537f0cc7d8c4d66ea28c3310be37d..ab857eaab75d6159d251fa7e50f989edeab193f9 100644
GIT binary patch
literal 33761
zcmeAS@N?(olHy`uVBq!ia0y~yV0K|(U_QXX#=yWJYO(VH0|Ns~x}&cn1H;CC?mvmF
z3=GXPJY5_^DsH{Kn>r)z>dy9$)sMV58WlVhjD(q59>{fhH#`Vi;-KjoZL*_<c}qah
zk{!FZdn^<w*SPiQosfcn;t^xx_dhqZ9Z0$7=@xghdj0S6*#EC<ES@u+Ta&(a@BH%j
zd&N8^iOhFx2yI;3aJS)aqjE#w0mB0q4=5h6J5Y8Y%AtP2+IlO`Nh+S17kO_mSP1P9
ztl*x(_9SY?%mcR%=$7(cdF3Ge|I8#6&q<RO$ZnAPP=CPqz?v`<d*8Dx57ZK*7c@I7
zcurDTImPO#sq%HE$KDqh&T2ny*xay>uUo})(vqZ=3}!6rn3ql2$$4se<N?tGllZ2B
z#GN9!EO>wDH2MbY^I`wTQ&Rdu#dDI%Ru|R{oCW3qb0@iFysP2Mc^}|4NyRg3mEVEJ
z1G_bIn?5~_Z+W|0)pL@H=K6UDI1g->%xbBdnc1?r@0R5ikQ?hRNn1$&FkIYw;Z7xQ
z#KFYrDxQ-bZ8Jz*{YvGXSooVW4Bxi1fUN)Vh2@`%jepCtshf4#LB{dPHZE@9G;{h|
zG;OJ(=OmTXaOnr;OP=#AEJ`sy?J`Nl^VGbr4gYU`IAi{}F>V^jYg2f=8MohlVWPb}
z(rl87XV9)vMnBa#JCi40-c!RG65#|Av&!wg&$-o1JIW2j+oi*LC)qf7!k=?RAh%vx
zXj{NzaMf*D!q3gAAU~<z&pPnh%z*X0=(K4no|C4;#5Nc@Y(488_^I66XOfDi*D~J5
z{+y_;S?xN;AU8+uVw`?+%@h^?=sb||MQiwLk`@PT+LLk;6rWG8v;L3{$etW@X;1b`
zu)tQe5Btt~Mt<sjs_r>SWvYAh1Ccw9>*mZ%lmvzHQge<U{k)z^mo64fQSqGQ^?dt*
zelw*`Pk-;ANh+RN`{WM1HB;#H4)+cQao3p^TIcRp1o=ZLm{ErL%(kB%Dfc$HsCrIX
z@+d;2;>0rLi#yL5f#RAg-!@?lulu9V(%zvUt#h~@MA$@Y=-%i5x*-Lm{!j$Rj`MEH
zraKQ#0;^9heGojm=gJbXh<lqr0#W()hhB%9NxeL|b=q1L&q-ITWE-_}^@66qZ#=3K
z4@!Mcr?JFs+Ub#6wy6eW;I!KkKh7OfnreCe6IlN{i912oYj^Tzq;q;tQt>={UG_)2
zuWQz4lM6?UKp{OVU-E(M?5-=%3Ky(S)$yF9VtSwNKnh5pY{6uRfIn-2)I$b;>FyG_
zJymXZEkGfb)%Nayt(oY`vnmPErz1cKb)VORT#z=&1Wl;G*@jLt(UoUP5=1UsgV^<6
z!zNy1ZKa4r4%9K6J1#C$nkvctCJQW}ds)2V<}szxm2CgmbP^y!oB2NUo^^foNom8T
zr>l*k7$W*UoPD_Oz{vxw2hJX7KH%NbJjZ@*bh6sjRHhHMA51^g-R(E*7d&@r7lXyd
zck{PfZm`*~pgzlUQix79qj9cY(Dtd{4mwDm4p+U<w&C%UvICq4wjS7gV29C_zpD?#
z9*A%F+fdpV$2U>MGwY@Axkxkdm8Z`hNSe03Yl-c{m5=`&nA);@LU6Ew{ys&UiB`fl
zB)89=uHyOmqUes>&y-4MtMzOt2~Fr`vSxbDc%IqV$RvHA+McFzgAH4pbv-B5UF!dE
ztJBx5sz~<2<x8QAI*e~PV_bifsV}SiqFJE0L2%whRnMR;*AAQ&zBFZhgRXA$RwwgA
zlaGFG+&(AxYurX_@rY|e6IC?jb~9eyE9m9B?%>?5SB$0}NIY<ON1|6Szwx~*n<lDg
z?$&Df|9P3Z=})m6r#6KeKmT#-fW!ma=K<ZHSvE|1s^S^6t%U8}2RC)oo%}CyZ?59J
z#VE}zE^KzE;Gc-v=GS!&pQM#NCmAIe9$MIO?}>{2<%VXR$g}R!3Cs_Q683yvwxUwt
zMdC@%NmJrZ3zmg^I;Qrsl2sz<WR_f*dJe;fsh^iFshqq)d%23I*UVlH^<CA@liyqs
z;+vS0e^RTz?f~bJ?WSdyK1mwfD4L?8Y5R>atx|Y$mu|iJ#u(G-dI#iM?mo<#quy!t
z;Oa7uNlRK*Gx&WzrYc(5@}YM6m&sEby&F%S>p$|$J3-SsbkdTPR~&bq@OnQA=AGm6
z!yxVz+naXj`AanOnQe7rJts{{ReYeC9}@KO^{4eZ;f$vrUtVDHT=CAN=t)bCNVK#Y
zEK~f?B(^PP@inm<jRhZ;7c2d>ygO-{%E~|2nD%`>rgCwm;v1o`#GP*0f)6Sla6fl`
z_H3JfjjE^C;<cRYl~u`;?$mJSWUO?{)+kUlxVv-0%^HT1O;=Pswf6qylz(3BJn4=N
zvrghlx8+PXWGXIL3i$eMe52~ArMvyAU)?#zTal{*U-JB!w}E+PvBEl^gSuZ-J+(T^
z4qUxgqhe(*U^gq=Mr`%(iHGukJ~}6{yh+9L=vC1j_h<LHJl9Rg^fr~!X1dO3ytbD4
z4~Nc!EfZ8$T2wt=*z0*-wuRYjYOd&kumj20_MDvjcdpVT7121=4-3tuI(<zIP8pru
zQ+8n9f!Wvg%ygeuw8~>rNW^O9$9qnC<Q!v^j#xJHny7`yk26)~z8<`C`*b{m4(52>
z*m+`hPs%ga1@lv9MRGGQXL`K0^zxY<E4x%YSvPPSoR;oB@{DW2;?!B5e;c_QR$kkg
znRqAHZ_<)5tBw!1TFu2yp7!~ZVYRxA(VS`X+TzQnY#x+MQd#-b?_-+MMoI29shw%(
z3htb{Ct~*AYORWA);_KWPWdWAv(p=o>R$G_$*}#L+0m0K%crY&p1mx$<LK;;BhM!7
zG7K`yVY5k&ovoBM?Xu6LCCgrWRouTbyW>eJ+lOdx6Js|f{iy59SXP$p@|<+Vgq!jI
z$7hNYe@-f3n{sJw(+1X0|JP&&AMz=D<vGcu-kTx6^6`Wllb?xibqQX}yFvTIvadO(
zCiKr~nxt~}cEc|2W#)V*Pq+Tq8!&4t>o=Bro2U6oe(nekoV4T^ui~D*r@qdg_KDxR
z{mEx7*P+B??;}pDF<M^M)btFh(`J0UC(<KkA4Aw?o8au|2c@rXsAx!A>#BNYW#k^Z
zDRNIoMcbcYukQJfTTB&4rOY@_mpfQ5U#{Z$HP`1x>518`DNk$iV}h*b-<f++#k9Vx
z%WG1|eY2ML!FvKd{FX6RN6cEeS?|M=uh~L#G<P^JRq_1#hV9HZHO0W6ED;wk`Aju!
zXkQaMxoOUelBp^$)AzGy?Q!%7kz=ZgoVC)BWyj@RrkW@J7o4v1ob=4%%<SePPjwDS
zntJWCJ0R+?wKO|uQm4bx;P6RH9%SV62~Cx6l+`^Q5;38m?zGA4YfChY3uotoG+vzD
z?DEt$A@a1*M=Qp~4V>53cqSTeSsNTNX~_c<kjC8&tU9M%vbo=QTS#1=Wtw?9B|&)k
zMitM4k@sX&)JzY2bZAYTnQ@ybKYG2|(w__w=Q4FXg9_G}vv*o4-iyzfoa_6*GW+Th
z3-d>p(>*6Od|-K`l+PzLS-eqI_w<oh{CBeE&Js!2+0YyuIcdoP-o)sHe4$AbPdD^U
zOI6Z!xM7*sR+<$wE3(C$vC3kus^_nrlDp2$ZgEMG+OS=9rbligb7SGPm7bYd4bdNJ
z6g?+NnK)msUOZt&|E%y0D#Dp8AEudR1<ks7fOkjgeihHk*^2XdRMWk4<KsQ&J#A!P
z>p%HYjr$G5E%QOP|2cbM>pcUNN7HWyPD_5I!xh6961`ZhwNmH?^M2<kDw*@nUNF69
zGQ~EY@pV*R=OsCdNd*o|O|vdd$>;EIX0z^9^_*32T(Z@iKlQw_L;h*QKr`lhTg`mC
zjJiMUdV9^mdie$w&(GnEF;9J6ZkAX6+P~{q$Vmf%9mj8(Xr5Yq;Nia&N}fTVXD`&=
zJ5eM17~|}SuFi|17P9Asjb2u&zLUAr88m5$n7OmuuBd<gbEa<)5l#+&!2SA?icN6i
z?1r<P&l5Z+EfF(wo?e|Cxa|s4dWG?1iNmjE1!rGYF}>Qd_Fg@6N%1MKNmr`GE1Cnh
z)p-91h=00Wpg=Hhaqgtq;tkH6(fhn7En%{}J-cVqQ^SNpZv(+^N;UgaV`nXSn)|>d
zVZ!B*NlOk{pPk*iY45utu6Ih)Sxz(hM^08t{K;Y=Z0<fmW#tOL56c$o{1l2f|4Dnd
zUJJ8UdgNp^MM>^C>}y_rnWD1tN8g8Mi*<ggUpW0qdv|Wb`8Dp78+w@a7_S{yKQ>8a
z>KVs-EmLfa8|<U1Qn!c1250%sDoV3?xM#a>LAs~sB(J>qLt^LeO_`$io=H2ZD)p+I
z#k7LBZqv+D6FU!VJ<zeMYKn?y>IUn8$Gx7O#i|#sUeaFum1B2FWdE`&KN)w(-Qarh
zAY_Wl$~|QVHivr6<UG(fEjCh@BPLOImQcD;f$|2^3l}prJcEpK*v@=$TbfcS^dkM{
z)T@05u3uZEnJ8Q$oVdBq&(9uIFIm)?2d+A!mXrF<FYxJQ_8qsQOjJ+wA2@qpo0;Pz
z71irr2UPN7ye55bysEQv(@F+Dm72|owzHDV9Je#vzRBV_X-bVV$Mfh4;ov_pebVYv
zc3+#njn8+Y5$g`o8*(q+luTC9l%2-3?}OX27eD(xoNYL@*tS6EVUPOjiz2%?clB<N
z?Dd_X;;Fe=;zOgkiR<~=1B<3b-(17FCsTG7Q<_$Rb)s{ho}Z!Tq)RK+KkPC$bN&DH
z$M<PbH%r*g9sIn-C((%a2m1!@ec!Y^gI<*~&->1{d_|?0M9RvkXRTV!YOis<JnM|Y
z8<!o?cXw%ePBL1c{Gr3#%JsC*gNg-fmxhVWZQTDTSn={M%NqR+>Kht@y(TTm$z;Cs
zkk|j>C#elhsbOZ>kAoF2e=0uskM|9)&Wn&qDw@0XJ|0`Hv6Af^gH=RQ>ce2g%ag7!
z^b79${Q9ZMBo)oyeqY&EXjF<v9R8#=du!wOHO`lhToKy${x@^tbYIU&BAv~91+`AC
zKmGi{PUWW{%jfK2kzxH({0h`PoVzzur{bRao1|r*BADlM&HVX1_kqiTOPY&WUbtAi
zODarY*ub;lPmE+#`1;z$*23y?Ppyt#PHVNw;wQlibu!#5zHYu1Wzzd3_<_%zJ1$4J
zC&UVGX8jQTAmTyH1GNW<4^j^ueEzs0a_x$jkq5T7T;DujHK(UU?qTQia|gOAEH<c^
zW`#a*&!14EHAT={IIen=*x5Uh>@gAM_S$o_v?l1asGHqpa%U1}<`<f0qxSYz6nBl^
z4ZS)O1ECjh1-!cMKG-#zC4U;%=H@#$e}t@v(c-v&z<0CQS^ZDU1-cs~AD&!zC5W5x
zFz0UGdC}Lu)XbY$`AM!o^n>)DI=`TlX$pJH9{C2p{>-*vmTKs=sJaVQCVy%YUfCY-
zYk6<D<XJ}W_vD9uEy+UfnD_PM@YOn4)FoRlXjfI#TrI{B_x0Gyt214HgdHtzJ(ZrG
zuxINFvzrGlA7E^W|Fm@3tN87Gb9ikU*H3tE-SdO<&~}ezU2)IIi*gl5T=yy5{>-;|
z&Z%YW1&d2x@D(2TSZcoY(w`E>YwUgu|5$6D%Vd?^WBJD)ajt06lrYf)ym~Lzo(g%u
zv0&}f5HsmXbIZT`em0&~u<eSMAM4rUN(cH{^6TPMY~B{|iR!IqT>RlflBee9bny>i
zPaO~K6wvDbb|A9l`r<Xmf7EsCV7$@tp|^d?`9lZz4zRYUORf`LTD|sNUPADlgMmSZ
zWS=a$`>4kMMy>l(<Bkv9>%U4|FL&%`tY*GDhw0Q}=?$t6_sqSX+aNTtyy0&{-?ZgR
zmfW0H5V4}W^mDQG!>!y?&(AxMl5IF^kM|F~3{UU);!O56taEs5Twn7UnI1hWUTS}2
z+x8q))q_zLX5QXLayPDi(p>%S$JuC~&u^6yN>9fXOESqg-SGO${@hE8U;F+kqiG?2
z-okO;ivsiF<e0>^*PO~Kec+sJ`1!u<9cPQzN7lanI@z`HZbLSQzvLY4n<r!)^iM|z
zS?X!Y@8&SqHf;$v{FAY}MynzDL+A{h=embxs&z-bQ+jh_Ctrcphxk8y8mE7DeYn=8
zGSx-=55wM_KgDjGxTLxI=*ONlYtn=YH1`QDpI^V>H*bNq!NH$`p=k`aEm&1Vqop6{
ziQi3oD!O3((%`V@M~a=1cU0dc9(wIRSLfr4_1@V+d|zrf=QAChH}gQ1AGhbxlD_WT
z%|+4=J7=9*EIUtk%GMg6imz8<A3fS;uz|fmxbAe8)HCUt+_0dD71shj*X^}CIZ1Q%
zz5~YBlG5UucS_z6;7{whnQ-WPqW|MS{<MFU2Q-yeUf9O4DmG#EpB;7P-pkgQ9S?u9
zX@Ys<;ezigBDOMKQ?q$md;DiY)P(z%y(*%ox(@W~t?@nOl2GftEaw(e`UCBv%yS_R
zvhL_=g~c|kZCuSU`=W)qPqtCxhpMG2TfO8Tc#B_Edup6u>Afsx8pFITe8ID)H!?S{
z>O6h%h3%W_9O<Wy_m^GRc|ucdrRgrl^}A-6Y34unD|))6bHCd1vfXdG8>i|#eDQ^q
zk9FRm_l-V<#@sL7Pnmp0D7W!<tjFvr;vc2ki!zz#yy6Yjn$PyO+uGpRGW!CR5Aro@
zuTC)&xB9EH^+>DU0^d{0E$W$Cd+!}sd@W(sKHgni5mztudWja~#0tN$F?f1Pq((M8
z$av@8vdcyM7cLfQcAI{@z0G8=-!JzB$J1s~rv>_CE6)Bh=RB1^ch;m?S;-08xS!V)
zTVJ?Wq}k2P5j{J){bXJG|FAoShHB0n>(}qg{X4tmSaGL{>B&nixr<{hp3i;Fc|T(1
z7AwZ<QT3hYmLDjraH`Rn#?r_3Fa7OokrcKIH#4;}<HVTk3J%W6U#C!WV*RC8{C}?h
z@=nQWWN%zMM>_BYuMCe(v$XPzFR8K1H!L}}g<Y<A;hcOuW-XoRlWy}!<o{LGo7~9F
z;XiF^E;mE<b<=%UukG_J<SVuE&N}l{Z<3iaX9(k*j_53P-S<rG40m-e`n=|O!*a*7
z;_8W8=6U;dH8=B>H_pk|+b*fKQ?4cU&zk)yOW1aZ-?*}K!cTd{YsxwOb~ksKOP;Zx
z^K8<yZLRzFnZKN^n9tyyZTX-!TVHS{M-L-g)U=sltaI3ElFrWVc`mqo_mZ9YR)1Lw
z?(IC6w&KaQZF<5J%^UAC$LgFs^NRBgzfJny*&Ux&1jk>}*Kd*EWpK`T`=e{OmX<NS
zi<;UJ?{B_c#CWx=fzS@-{oF={&*G*tdS1Ev#Qw=5i}QCv%O5Ye^n&S5+TE#N1+Kns
z6xBI;CW_O7Um|_)>=VVkryEroiem+y&-~rUH_h{;PG`H-G;Mo^bjDhp!#+_H3gRX_
zFPHpW>{paIVaxRHhc=&8<|V~?y=J-}Rjzt|`+<)wbN@`ywSOyA&TMcu%6ysQw$hms
z9&KaWXKc5APs{UFQ!c&dT%Q$Lz4Y|*me0*Ozc!~AK8Se0{QAy}$~4aD+?sLT49T$^
z(r2R`^iMBQxy2|RS*&{Y_JRBlyLYU~^uD3+P%dFxX`avIbzdhbT@|c2*t+3j%^Q6;
z)yv!!cV=lv-eV|ZycJP3(}?58Wcwn?%WwYNeCphFy;QHM_gS`0!KRRD$JXBSo_f7O
z_9M?)olNc=W}AlS%hH!G@sw&#d{olHov?T&3(sa3uO#M#Ce!dQfB0{lbJGYGQ-9O-
zwe@SR&+1Q8PIrnd=WWaqKe%V6+l_}lN4M+e%?s!Xf4pt;6{GES_Z#oCNd~XTdALdG
zXu9VEYw-hnX8QgRh&&qVXz}>iEbX{^>}7}ZTQ(&*J_vXan|*sm(=)^A;+l4I8>YuH
zNS}?H=5eu<@n7Ov(bC^<Y74LLSQ8<-gKI`su5|DebEj1?X-j^@JZ8F)(YMv6E3fd-
zOuuW<4?pu37+g4L<h}P>%kt`X3|T&fo9CbI6`9{0^GE9JeVzVA(Tw*0^xV{#)tO^;
zH(q(|dqd@*?&e<2I=!-!6CZ6htJ`xgBJcQnovvK%2kzNx7tCah2`Cp{TN2&*;Y(dx
zX|9iFQTO#)O}p;j-N}n9=M-41?Ru`T;8>J)L{?)oCwqa`-djx80^5FXUDvA_yKc?w
z`bkQc<SLG_Zn*fiqdG##HQ3SO=j|x%n0YESDeJ#Paac(GI8$Y|Y{^PCx1B7Wg}Y9;
z8szU|`4uJSdYN&@MJw$HJC<$R*97HeJ_x#_du~S2+kHQ^rz>juRqy0@c9#FZr)lmN
zbr@{2=8CEaH!2rC-(eChzN7uas>P<cKAFMJKdu!qPFK?OJIwL>^=<{TKLWMNrx$1Z
zVpt!U&T6Uf!)d{E)u~>&jk1NebCOTZZ0D4o=F#;-{1<-=&*wD$(~C2vG23lF7B#oM
zAysF2$SWrc?pMmMZ_L<a<|MsC#&g$YR>OS1Z6;l5wTE8EUW+{anRCP3rBl4RnU*s?
zUYneJYEov)-N!XbDx3|AV<bL5v+`b?QO24UmArP>g!w!ro2CS%a}-$4lTY#4xsSg}
z=!a~bvdT;GYpONX51b<H{U5l$JX)kur*m)CAK8dgMqYETHtb$gn|$gM^QFHB8V@At
zxlVevO+s$pEdBRPwz~a`EH3}b3XR>h)BRVD!w<WIQfA9aq|ey+TU^cyUa<M}geAwe
zsM@d=eq1xZ@PNbV#TsABmVUju$cNqUi2Ah5AjTe+f60HPg1`7E%G@^C_0E0qIz7ip
zvtH?lU)*CpFFR6-^}3+>+l<V2+a3L5AOFvOP?~*x#-gXi55gYwAJB5Jo-XI9yRnx$
ztN99(b+i=gb=itDzp~2qsm$?QT=Ih9O}o3eL~zgh`gx4UuB`2>jmc9HJ;ZS5l|_8t
zRuir~!3U|?t0Pykonzb;X}9u%sKuUjja%z_Gyn2W&KEALu<iKpW%=IIJxh}Qbp2e^
zo!1<bnJIE7=s@+gu+5*eHmq7Yd6rv-$ivyr+1F=GduseZzSQ0$uj6)tx7NhZF%8mB
z4C@=UcBKA2y65Kob+X;>58mdGoP4*3^&jUPrX0pEWtI~|_-^l1Fh9Y5z-gMB<66d^
z?b~L}Io_ysT1~X~!bLNuV<tO)?&P<ay5aUCAw9)OlMcLZlS)(Cuw`jrfV9vy`>p$C
zh1Ks@&N;6mt(bgimVQGuhkxBRCb9CH6Q;P-nNRtDVVkc`Z_}-&53i<wHT{3*v2Szl
z1Vha;#}C|ZeB5~U<5qJ|&7yhT70og^ks??44(Pnj+BcKoP2$caiv)k2t1=Z_&Q`&`
zgVUnx!<YTbPd6{w@@e<Nww)I?X{@m2h<1&RwiET*+;?E%f$i5;b?R(x_|F*5+|Ka&
z%3lKo&zTR(oq0bCyn7Prv48z<)r+@geGgt}t2^~bmiv!suZy#<x=hGCz<ofqrMV?s
zaZi}O=gcc|`=w`Dzh~f%l432MVQPB+kMMjh)lk+A+8_3nW*N<rZ&2r4fA&9{1lN|*
zSKeJGZ^rSwO0@~dj1)QZ@!Ay|W62xGjXc+^<!FBpwOY;Fe~~=nzo6?c!XNTYo20Z|
zGT=4qqI-Qs(h*{;#cigh=WSTOZ1)k$tbJgaePxNw;|BHydq!)axc=!Xe-ADC5%}Sb
z<%vxiGd{0b?q)1(!IqIcQ{`ONfy38UcxHb7od3WiA$r05%aN0wt!>(n*&se~esO1N
zpn-UlfA2Hj1XpjBLN@0A8|-|&KFK~jd0w(bHfeeZmv_)-*|)4q<K`*k=q<cveoH*k
zzcQG6j`NL8ktZ+iUYC|0y;yDGOpl7JpX!G!^Smu{RabruJKk*g+|IW;@$@2vvlotD
z3%=LGYPQWqXeoDrP+~B5_7xS?;KuZZ;>NoLhnYRKx>y_f_q;fBQY4`gtU>i!@Vz_i
zI!T=>ZqbKkY9+7r4SsfpDUMN(^&4y3!?5d<LWH(g2(J3hb@|)0ma_p9jhHR2eDatw
z@j&#oWeaQamG3ag@U7u3Df03PdinPnchKHBS)L+GBzIkjI#s>leb+Siq&0pPC6{iQ
zEIp-i=$Pwr!E>8ly)~J#<dd{dh3y&c&=avg;>r|fEj+zuDcjCTA8NZ!<ueq_HqGps
zlXd9f-sue0jLv)Zc?5mh!XEc&QE2|{$9dCSSI=H}dhODxnLKZjGF6<)ADnNwF1FS;
z_(c!<Kh`-6IWNAtOuF>&eB6O&DNF_@CT)<^Du`2k!?yHOmUD&akL>JAA{wR#UbifN
zSk3JH__DmG*W9nK#7gvY9=_i&Q}tq&+^#75@CU~)dPctfmu)*MERE{}$3yAMz8uz@
zy(R_aI6f%WFDN!TH7R4O;kCfM(#vgiIyXr({JC3YqI>3g>DOY34O$n@X{vhOELttT
z+j8g8qKvJV*DSWI<c>HtNn`c912ccjosfAiko&#ByjSm9*ZX@1J^OpCJAUtb>pNdp
zm-cP$d-lZY^~yE31o$@oITmGd=D+F7@P^`s+=e(mdC#un4u|@};{*=pIWX&VhFPAm
zQer>D!naB0RMy&E(lM_uJ~^H9pz?uE0{5SP?voZ>6{|SM{dmr1MYD}6QK|K>J7hkD
z-aWhH)ME1j-iK4wUtjz)Me@Mq120RnYr~g!sc<H25%)9?)R?e$52Gr(4XaL;<&?MV
z^X!=>uW@#+@cJEcw=}Qz&fP%H$<n^F?{J8nTzl-;&cvQmys18Ul6mKJ51-wcx>Lt|
z%Eg^iC1>8AV7K$)mXG>sqQ_sgELV!NIQ;TU*3Q^9sznEW?sy%ta}D>NG+wv=Q~tXi
zdL}vh(e`SuIOZ#Q+r>^lZ!<~@6BRBFeKKpRqRq_c)`vUiq(^(UUSh2{&#htkfVZY}
zk?A(YJ>BxfyuPeun?+6~6+UpgzA>Y`v0B!G|Ay3yha~}zW-VCza$fYry~WKxm)zvN
zu*Yc1#hrpBU-Wgho^y@!Imsy8=yiJGQL_WNJ@#yEkzA_R<t&8ETRL^$Gf!u*X6&}$
zopM4g!{lv|_J-nvvlsm7y(kgCd~#HpvHq&!y4X9HiZV8a?v;GXnULtc@QInqoVQP`
z#EzevznytM^R!K0roM2?aQ^kAtswv6>;*NEGbi>nTq&{Tv`(m8*cz<UE+)-XBVPG8
z#;L+<;iZ?ncOKlD`m<MH9z!2{7<2v4FfOTup%QjmRqwNiT6uq7bzj`mw|KR9Owobb
z2a7H`{cSj}yl(EzihThqLm7TE3dig=nz^0xK4Wg@{bDWO-V0edHhb^*2JGu8E0)iU
zt9#ozUFL)0h6PVAD0MTucZ;#UFT8Jd&`TcHd8Kzx-Pt~SJL7MLTHV5>>ja}(A9m)n
z<a90h`Reid)x~AZpP7G5d&##)rts|^MxHG^Udy->e?N&_7d`XD>;sVp))!<~E#1g@
zDsZCoxd-x-K4isQHo6!%`PFI$xlc_#d^heEWlZ!t@L2Hr*}bK_3%!!L9|&JxeWjlJ
zOa23gJ3Nk=xlL}DRJSu(KcDvO>J$^lubX+yt-CIr=ll4`hi}J$pp1#z4%`*Ie)i{&
z#PXFojCUSJO??&qFpsJ18#~L=ZJbiRyYHOp(K$Ko=F$@dY}TuSERxe#iD%6_EPF6&
z5z`K{OS4w4`)%lW^!l=Q`G1?ULtlMTEl}LBF?&tWU5;GO^LLEy%;{8nF<tVEdf&P|
zCmYiDBz)F=D6M6Bf4=hCnercdRs}_Fd&kZ_yZg(N;s-GavUk=7XXdw<EjfQ?%RZs&
zS8_c4-J=Yx4{@7c-Ju=fE$gypf5rM2AH-v;AE+GKu4X2A^1S*1i3Hx+3aN_(r4B01
z%x|eXW#DG{sO##b110*8WRf+voY>~z+w%2O{GoCkt#wx$uE)+7n!mB-bK|uQDN|K9
zPkXvaLuz6Ck-+etTTJJx4WH}PpUj!KwJ}rh+UdO&8Yvq~+0Loi?A-d$BTbDVoI(0g
zn$oEmccy)rBNM6oWT#8l&5dzaelomB)HJz$>A(+;*H0(yk{1fGkrv={-S*NWZW;4-
zrf6naozT>aZ$c&Jb#Ikir8GTy{=cxsq)jpg%AdM_n<TJ$FT5$Hd~S1mU-66XRqO?p
z0ojiy?y%u~^Ss~v)UNbx%c`%O4G`UVr!7x!X~h=ixNl15?@e>sT&iAUFC0Ag4BNM&
z7u{Le545i@ae3<eKqO(o)0Gi5Rz1y&@;k!PmP}m`G3UwAdD^<oY1#ZXB9U`_7~L$s
zxLy|Caqz1~;MY1+gFBZ(dhEPj<rOvmR59-f-1(5_94P7x+;(1`bHz%VVYAZy7ytQR
zq-dJlE}eMwB=Z3+zUqrPjsC5ZCOzj|f24G~j_79nNmm4TpH04Vs^?7ag5-Vwulcio
z_6+>D_poG+s>bVEg7;th6{iasoCwO;7OcE#V&nluzRHU_4i!$>%0c&P*ylL^m=_}S
z;ikYl-D+i%DTX`OKL7vt$oJJ7H_q1b&@J9$&X|)fX>wa`qUjlFt0%6T4L|IB9T551
zVgvU(A$8M$WBDCw&%)AD@=7jm-ym;2NpExa$NQU9ZP&7--Za{=`cAxVbDA{YnVuzf
z$C#XDKP`H}7Sm&WVyd<<C;M`~jUr2riN0NVdQV(;bobNfFY>b&Cpi_KQ~VTTm>MSi
zz<%O=0UP%lA`ZUh96#(P{rVvw@nC}Z(W(Q-%~VrQav!j3Y0gtUd!EC}Pe0W7$|biI
zJ9sa;bUQ?rxjZpvz0dqtr#bB<=N@U#+C98F?<R=Hq#p|AoX<7&--j#N4O4X;SN^n<
zJ2k^3CwuPgN%L6$=Sv^j8`iLC)uaN3%r)lhTX*CZ6>nvi>t13P$0}BMf;%ttf$i+c
zlb&%ODqqAMT^FR?vmiNe-`U7%r@4Mw-P*$YGWf&)W1_b618;^f+6eyiJv3jZIc>Mq
zq+37qFPwg;w_@7?&X&VDxj|l&mp9Jk*xli!)!@%vd(J;QzF+%j{bFe?jl+Chf7~9f
z+$C*ddUxZ*E621CIPsM`@-ocZ>Zs|NCKT5leR9*}uE*V4YGO-HM$8TE{&@d;sNuY%
zrz;AcOf~gpw0EmH{DJqvaiffBvYn5s`~NrXZxX$6??8(5)J5qw1#ESn)kN=S-15!)
zJJV@#_s99)?iR3#Km5H=UA83kVzc0VlNxS0ooha;g^q7eTmNYCLZ?@(f9|?1RoSf|
z$5gWQ$&yPab3M;rtMLz6^M9Rx+lQ2c(u<UAPfj|OdA=iGCacj`w=pe}=Z8_#tqNIt
z3;iX&jq7v5x@M&}zCBp%xTMI;Rrgj`_1{N-465S|%cg(+qnLU@=}2*z&%Qrrg)*k~
zwHVLZ6es?kVXy4FrWY)8`fq27e|Dc+-MCfPR8!II!pGUqYJ#^gS&P56f4W)mPIQm#
z2bq-Av%Z4&J!*Q^PcaGSu|8GHpz|<5{D{E=-`Ud^rI-~c8(cA(JV|pqll6JM$E(xh
z`x7QEvXQ-YA%ERe-P!JS&Ko;bFX*(p1_;k*^0vCdS}5@Fg8%I4hvb)3875A*^Xz=z
zwc^Cuqn|)k{&th~&!#=QdMDu6ld!~!jq%pnH_nysKa*fr7%){e_I2LBq`fP5TolTf
z*4y~1=lYR|gbB`fvuqo8=frT$lW(wR?v6^D^z8ZOg*|$wE-ws~co!cYS(JCgTuk`m
z?+MRVu&AZ%QQOBnt#n0nuEmF)XT1+zUwv`M*WF9hex=m@5??B*^~kRx$Z`$a6_=Xk
z!U?JuQtmcxH;Ut*+%Q%4RahqT9G7qNm8Ka9zxub#R!85{*KC%VaMu-{omaPQT4MVl
z>WI1I`UlgtoZWfyZ~C#<iCRB??4SCJ!T-hq5uN+Y$C<e!q9)DC&M`bE!!`2-$YC`{
z%%!#-h??dwdG5rIRWmqqo*8UE<?-m=w*42@=gKjcY+j?X^~m?b7AqpwpL*J6d}IHH
zO^dpAl-KUMCX})1tx+8J)dPHd#oeVUb97UbgJ*=B`77<2r{$?@lwBI88)a<LqW+g#
z+gq;l$FgLj4Kq|Ps5En0N2TtR`&K$5I!EE*)!^APucdN*P`{(&7^MAl+mh#Rl1!aL
zpA<#^ZtmTbeEvkfUEemASxdBU+IxJ~Xy18so9dgYH0R5^id)VdovWuRdWgfyPcO~b
zWXi>V6Q_!DGd@<@$M}=sMS`Ts$+eQ}TkS26=w9NJNH)H_>I{<}qkqNp5QW8=pK}do
zD{j9Tb}UBlXYYw^(;Ozt%=>7y<Bnq9#C-=go0+V=b>^wrp~|>PAsf<OtX492&ReoT
zM>4M5vF~fzlR)nUo^`Be&K1c1Va|AMV19d9%iZ%iIZ@M&A1Jm~5sm2UT4e5gx@cy7
zMyhM|rvJ7l_5?AnNsv5qUFd+hWPX>m)tR%G*es^*;4jGYjbk?3-lHPASn}7hu1?GN
zsgq~D*>NJ@Yuy%>SyxQbf0nKYFR*_6?3M2w>!59F^M%YdeEg8^*&5z;{mH5mPq&qP
z_f9?TkPvmmT+RNG*=^rK$F}ST%y&+%-g%An*sU8|Ug#`b{K0d{k}c-W+Qygcw{3dT
zcp^W*ZxhS2?Cm`L|F4(YbFFy!&tuzuW$kN>`^A~LqwOYj-Qd~!dz;AF3j*)H_OI2s
zsrqU5l=TgI(+=A3s@b@ne)Qu%!<rWY=8@?S+-A>Cdw&1GrfL1JLVl<R7(Q{kQ0SyN
zOL4z+(6N&B*&Ipx0&gBSnz7vPz-md^-!l)i@fA+yJyD=5qMiS+jngoLJ4CQ7>W}S1
zp3Ty)q#jOh=x_XZK;)2Quzl`EJKh-#HGF#*?r_F%$S|#Ow-67=iZb3}dUyHs6_TfN
z-+teAYFe@K{>VyR`;2+>Pa9c%+uE{xan`J}ukv2x6wR9UzM;9`_cxta9BX)G7-PI|
z^rTh^X1`2+pmm5%#{0+faJ$Q9OU}OuGId^UaA*IHO(_y}%n$UpfByEGr~hvvU;g9}
zhU1T?-8%cz?*&tWqqn-T)%Cv$25dk0AD%3-tUpoNS71<P-|oh+b8CcM_^PxFiN$}q
zwX@AF&%4w;{<I<0z`wciq@?Wc&9e8@UiwwE9(P-wS-I(5yV}zG4i8T3dVQp)<ytgv
zfxUsy{gRGrJyRtkH>G88`2P|QzxGD>XRo*JhDoUxR_N55ml)SwxFh1+P@YpXYl=Rn
zfAG|Qv+N~*#B*hT2tK4eEAOe?#5)FjT9L+2)VNM9n0H{uiTs4TO+3$DUh3)lo$SEg
zUcPUe>TZ8_?!B7F=Qrj}^U2cnxpCmZQ6AIh?E-uk!`f<h^O#THBzdZL!_Ba7F^_zC
zn01=n-p;yMSTFnH;fHhAJzLaQnAv>3@3#9?k>}dphW(#E_vJ^Pu09~fSIqWw#f%Lm
z>!)pzyftawzlT#zS3f*{@p&X$?<%F){%reLep&7Le1&z#S-0h$TemEJI?2nn!MU+q
zdDZoLMsKSxHx0^EV%4T>5?rM;UHV+Y|4*l8nYDZtNZL1ZX3z2?=F4n96uBL*VQnv;
z_e*da-?oP{zrQPd-k6@hBtZU<o0h#x&E4N~Qzzu9-t|29cI(ta_Nw5+p3@u`|C@C1
z<2>IRdf~m%+&_+OO`KOLXrAb~Sn+^q%J;21rtNul^Y$i>MB^<=)zkM#Mm5g;ds@4@
z>fyq!`wX$Vt$WOrX5a7qvHHcHx4uQ&Mf{x91k2tPc|R^$$&`2G`r*${wG(8$RczIG
z9^RW|?yS9Odwpf<)zml+iyKB6TO$8yH9xN1<$Qa^wgd68!q0Zw{!W_awTg#fo$8)@
z8NBCzpZxi7n)jxs+m=<I+%L|>zFzK0e0=2AP5Y;OG|Y3pHDkB2#Xa+fk<Ps@9V<$Y
zNgqCTohyE`&-B)YVh-z$sKdVJQyr{Nt2ds#pv7~3>SD=HCnp%KVX8RSI^R~Obr0W(
z2NCv->Aa@Px^|S^$a=SoGnr%eTTNLjCU+*`HTT16!=Jb*avCLTB<Hj(IduCp>-_5<
zr5kFdF)mBZS#zK9ym!Wt^&hMc9s4A;VU_A6t!M`Mh~2CwwOhiMhx#qfG|w}be}l)f
zbvwg5xv9)<QCz$w4F9HYEd0kO@#4a>t?K*yrs&5rs6TqWCDVvu$MIXb755m#w(dEl
zyxs2a^685Oi_9%uAIXSU{!5m036wT2c)sM=oL5#C6y%w#AC#wMUfQ>=a&F#Vv9FxJ
zg{DPy&R&=(GetYxc#D*@HPfkGshrj)kL){;pP*^7LG$MAq}%yNq+WU4h&d#^cfK*V
z1@DWL$|a|yTGS=36@2_`w$CnnkzYsGN#}}9IcG1t+NZY0!sgMTbBCunGTS!l8=IZ`
z|9pel27?bh*$&O`Ri<q>30kUMAop%kR9|z)?#MdVH?3w%{BOohTn$c@?v92xF0#&*
z*)VJA1&3?%B<^&rw>_Jic}P2P9i#pHokd1@`g6=)3vF}Q-gbJjJE#B5&=+Yd=Bz&v
zI`MRGf}p#j;R}|US4rpYPIG!D{q*_AtIKz;?T;4tZ}k4ryTZ)Nf<L(JM7^BWZI|KB
zFnOz{b9QxVZkt=xnubS(le#Uo{>VCWM@;q2p=nbM|A~~l%(@-dlAp3?BKJ;_^CDie
zML$L_T=KNy^ro*x*&F}7DKc|v{;4wkb1v7>#ry_GS?A2wZDsp6bK%FiJUpcye-)QZ
ztl`f|_FUq{S|E|fJO7HjMEM4n=!-m4UoW^i->9Wpmi6c}H}U*c2m4u{Z}M+Dww>+#
z)L%=t9Y{U*+p==cyLQE;#}6H-y_UDgxOGGE+F6%Dy-v=jIW4PBJZ&>PH8CLPno4!F
z=603vXs)k1tbZmf{AhbjaqeR7n^m8#-;#IoW4aX~wsI5WhpAs@&w9IKchn}|oVHVY
z3!83dX$OfO;MTiwhUr%{-`7`<HuChYm;doEC-Kn2!}nGk6mO9|Ic43}mlby`4qm^w
z`5H&>lG95L)&zY^%kZwUlIpq`r+4K^gSSp=72nwlH|+YO5By7E_%QGDT$zWV+WZrJ
zrn5Fyuf2OEt=@ab#Iy|7GQDbLlNR;6HjW!#vGtTrOk=xny=X?Vfq|}a@^8@%JDj-=
zoH}5Bt~`y|{h?$?=4PP}6Ti-W<-@v4=jr@jS<mV6r}xe+`w{m-!QI*L_hfDp%Lg^y
ziG5rTUh<gk%C=a-ki+)pMa*;Vgxu4LrDe>^qW8}{!Ci5|aKeP;PN7eVUjN?N@W^bz
zyEembM=PZ^%y?>WTv1Z$_Ffsk6~C>|l&vea-={R)EVp6vn!9IGORn@@xK`qSWV@4d
zg^~HKvnfmV@79>i{4Y!M%tn!$m0b^l_dm#ZZee<$^G8?AtuGA!QvarX+j@2CqMWu#
z8=7N8ci!Q8^F~PdV1f7(%je2pw#huJFi?K{OJ(1r#{Fw1Gw)+H+aeN_F7To6>+F|*
z%$Jo~ZC9*SQ&}h|bw+*X#FE0!iHFuN(cdL8nfcrnnP(?XF|LWf@#K=&j!Qq!UOph?
z_x4I8`;T+KdX;Y4OY6BGU6Z;~N6^1DEG2)s_{;R&yE!H+?~&TJ;VDB)><zWF1fO(<
z)vk8aWIvSNkSXA^Q}tOK`|<X*8Afw?-djzNZhg3U@&yjvv#aeyC%t;jQ}a&Ar*FgI
zc}=^GjF$a&wd=dv;I1_P`sBvBb1tncVG4M?RdbikjGb;8nzPkHCZ1k<s9?I7=6}}X
ztQL1ncHR!z;O%zo%c~Q|H;N}(-=6XO>+J&q%S&EuVb%M-OQdw$c^~5`Q`T;2H@f8<
zw)BtK;bM=vQ<Bq|1>z)SrZ;~4qklp3QQ;frJ)%G7>}&qe;`8#7<c{0fL0^9IT>9x1
zuIKKWSNrREn~|De?*)N*XL5bZr;DvD4BzqMT&2~P2~Qag@JdRY_dIZ*<M;-yA104}
z#_-BK4e?t#?|^aKWS>|+e_vsfNqV3mM%AZVcg!#AzdgZDPy5myUgbGQA1<1`$aVV(
zvr{K3^29$%tn;`LW_4|+4d0CeE9ZFCeq6aMbH_oa{Y%8(Em>m2xhm<=9A4pT%lCVC
zT`}R`edAZj3vnx^_vr~X=X)!7!r9eaY^KNi96mew(<+sB%V#b77&HILp}$s{XD=k!
zom}hx|BlD5CvLk}FEg=^-f`mB+Y2#%XAeZ!@o(ub`EzY;_PgY{$HT9he)XEa@WA!B
zZXe~9tYKbB5Bp?2rytoPXTCozlf(a6n~~afrRwKli4~wA*|w}Y&*bf$49AUG+<P7>
zy*^j8e}jpE@zZ2WP6>gRKXQ3|dQ14uGw~I0Ex-2aK*f63G`mWR&ZE}3&cBu{QOx>v
z)5Up*x%rff#Zt>3@|^2Un7B*bFE?h>6xH9mc2vE)5F>Z~K*T$lmp5`fE6&>;`}v!<
zVxC*qTK_x#roNvy#a-g6s0rG3S?_onuXBabcAe=@+YGhL=N#Or`|{<aWhO6~YMvhQ
z>f3O4hktv*dY+!Aq7(b>err)z*;uE4<@(FnQPRwp_wdb3dvbD#=*RD?Hx^Fey|`!F
zce#hFPkXfs$A&zAqI0@2?m)Sw{PFLN>jeAmzH52AG<nYM>w@1UgEO~lezd!4vi7u_
zr`D6-+m<Zv4VcH1zTxzoNo&ma&HE6%jHx?9C}!%X!a2S_*c8ov3q7Cqb91Bf+-)n(
zm}WdQJ+Z~WUw!QY`+u3`=E3%>H?KN9chV~*@ynKy$(9@R62H$g>3^&#*mqk|QeykG
zC)PIc8gI8L{hhsi#;5eRDxzP@4@>4SU-5AJad`8j^n$zVSL-c%xc958^7{6&CI1<Y
zgunXtzvJY?iRW&HA9Q95&f}h~7`))l<Smc>l}RklY50`?{q3dYOLks%E%7_IS;j)?
zX|e@(gxw}XYn@9!f0aM_<EG<ncJTTWpTzU3QEG+07me=ZFi%lmy>X-Wf=Nla;ukDu
zGU^Cc+UjuqneeI5=4P5k*X()02br0J^J?$-o^#o>`NfaaooCcmB*w5!6*<4F;@ruj
z)0nR>tKqrNXmx`pweIrdxpP*nG?$t2sPwpq;$?-I&+k1+vYnj~7pc9=+-i!$?HvWz
zs?TPfJn=eF_tJmIf4>BKuP+olclmtd)R<kt`KEWSUJ)^OSKIodSo%`>rrrzZBWH!j
z3WfURdj4<!+<Io}#Ouz|hul~)<qprzZ8MsiUU+!2P6VICd(-10mhx9)uM26LPq}F3
zQYtz3&BmZ@Zyz^Vs$V^@;Kb|1|5N%OmLzD-UU=r2)Q6VOJQ5r|UuPwIP4S&<r&y%?
za+36^884(4eZ8w0^7LZohgY54X(zr;ynfi}z;{jg!~0!~!s>f+@~$zs?@UQQBy`|-
zT)q!yv3FLQdtcX`0=DOEhFaTs%t0f?F+T0P)*ULC?lJZ7M7=3r^L9+@+#`3XPUF4F
zg6(Gmo*A*;xb@UZxay(ytz|a(d^$6}orKI)SUuaeBt6ffxp=jK4JaG78Cii$Z2ORs
zXE1-sE=8$R8Ph$dM)B9w|DL{6`BPQI#1E$y>}FQG{cqyg)B3Nnf?r-|t+<!ns~ODK
zley_>QOFaw%X;RM^mYpBOp5M)TC8ncbZ+wUC1!r}+?N<x9A@1Vm$d(7l@)XHj;v$H
zGyE^@{~cfaNod0k?^3lb%>SO29-Cr#-h%hDiJ$U|8K9Yxsgg6LPtDk5?xh@YBrs4@
z*U#ecVOOIk_fEV{e9qJJ@U*1-;<+CGh4(yr^4=kR`l~ZLuD$NjEY51&=XX@i#B*`x
z<mmbTb}sCh7y9b`^gF43s%4$s$$QsG7V4HT*_}NgkvHq1;jOL$yD**4AN?I#PnV?4
zd1<<Afh7ALzly&fJRgKU(EhLId+MRzaWNB*=u5`tJ%N|I@AB|I^!$HIYpGVkHtxrB
zY@{k}=gep{tWiAtc(b8_@}!*>!Z%K<S_LQFk=i#w`tKic3-%kb5%VhZE%!@2%=~YA
z<g3X}%b)$ho2H(<Sit75do8;(`qJh78@yhMi65=HY49j2qG>~O_^smww|n}|?>h21
z>orS)?eyn9H}}0;cJH;%=Q@!cyWh1pwnly29?!Mo;{Nn|*Pn?MXNfH^jB0(zTAO6j
z)BI=kswr)P*WGV^KK*&(^}|~wB@Q2%?{v>;HS=WUneFn7-n(tmPt9t{{jm3(iEh5o
zw#)BB9~4IPZwOvo|9Jl9^_Mp{^j<XJ%PKYAQuWN-C5Y+n>!b*MW#x6PqDG%yzkMhv
zJDc;!XRhwuT&brO4wdW0B|n?r-gvglMs6?XeW{<{`F38`jC!%Iqw5aW8=Jj9{af9h
z7S-vm`t&F1dD4&KIOTWz+vU$3knmexx_+w4#R(mGYXALiTyeg6k-Osl>(e!#B{ukR
z9$(6wSN$)zZq4uN6%u<dwtYFtn;eqI;s5LqU#VjAPZdx)4NJ-2el2XL?K7tc{oQUc
z+_O_sc-Ei4vEvJ~U4P2Ix$JrCXBo<Jrtht&&9r&XpnS^0j^BdqNyFE<>w@N(l`*cF
z&fl<Y;x#AM5Bqz19<xbGO>cdjH!bOg<>|Hgn@{%tc>Xu!QNba`txvDWR-FEru;p@S
z*X7T84PQ6KAKAJg+wItg<V~MXC6_-~%JJ+jPlEgO$39jkUwbXy$sb|lm>kOK(^KPP
z^WLrNf?3>zS5LJc)z<IO{SfDN?BkQ39#8i}kr9#e%Y_@`cgmz+^4n3Jx$lod(fO;l
zG(T;e$yrkN%Ijl>v&F?*-Ivc>Dm|*YVXmAU;cbzw%+34CUTH>gJi}>_zN{U4%l6q!
zZ8Cke?ZojD@)=7y-aKnv8F!5NuF~38z60q$b~#Uq5j;4jn)}7;pgEqkjqCTWGx@Rc
zS;?i3y;=GXc6S`lni3q*<!pWE8Drd%KNEx=9N_6q7Td>YZQS(po6ODIVzG|t4@B2%
ze*I*7)INB{1-_1oJ?{#nybEs}=MLHHv+%?6hUKp8n>Nq=%#(0%O8@ad!86-`H|psf
zo>{v2`jo0lS&0dU3Uj#k2)>+A`_5$AruDXo;(Gca_RsHhyiVND)BE^-u$@@7yTSFm
zHPOvee2-VzuAE-a5F2bWZ?>yV8MpP^r8&R%im$Ai>AL5>;TBfAQx_ugW`C0IzbQFC
zTYS>ow->HnnAWm+$)0sBbLLL0`tQHw@%DYeQK#1F?3D{$5hGh@`)1a{LK*+6?LP6H
z1s2KEp5K(z+dtE+Wy91h*F{#S)l8o$8tr1$*KV<P=^LvX-J#8~^=&RO{E@#t{Jb=!
z&#`{fe(CEM_4dx(#&FZ}@EU>phIz9O8rE4J+PLS+O5N08^+N|2$8D)QH&^ib;a`%{
zrypv{G`BXC8~tlOd{A%i%rM3~kGHnS7)ahwSp0a8d&}dWOD;#BT6TC(g6Rn<!Rv=(
zC8dt{d)(jsYi>ijk<Iq3hWk6;q}}U`bAPsH({8V}<2#u@<fbJ5YP}qNYM$N!^SCXq
zo_2P;PW0UL_2Xwv&ELPbE55Ot`ZO)WfBM}s(v7n<o^Y_wSSN6>;(vU~<0$Tul3Ct2
zjZSrkHTQJvkn=l#!&N&sz2=YZ<Fgm!^mfiP7nt#&v?agcsgmU9eS&5Ooaej>Dl1w2
zoAtEXi|2d93T?Nr?mO~*&uP`u?CXD}Xz<0px_05ldgaFrsmjv7+m)mrpPlnAs7&T@
z>uSfc{vC2=XKzHjo4jcM-*qkOQIWNKQ}U<Z)`)p++Vb(p$60soly&FKiM_m}=S7!)
z`?GWE4!b+DAI;+FeagS&xyX-F&gf5RrExoF$H;v9EOm(gz^aLT_34kS@?S+P-!p~R
zz4~L;1bdel{@mAfH_x1kh?_KN|L+GqfA8+i?6~Z8;LC~i@|PRGDy?sRtt9pS^PF!%
zze-j2JkAmRQoK)n&wshqp+;u&w3j`|zsLPU;c)S*nCZ7PbUbd{vwQaXcuqpLcjH9C
z-k)drwoj>ZPh>VJ_v_uG#&_yM#J(9#`^()QyyQ8*JlgaAPyZ}C{&?P-r-No}UU&4<
ztvi4Dwol26?RYP+^=GQo29GDD6PLbkubbVpzkFJ}ZYAIO7ags~%?^B==4fl~YV_{B
z#g(94vM*WJIO=WEsZdc)w&Z&;<-`838ztv?&u8won!9L&*u&6`GuF#ak7DC}BXIJ@
z{&xZ1FR!*1M9lHMaDF8lTcp&UsS`iS%>A(c^R<-n>bH>xviz26=&;m?{oMN4?ogV^
zs{F=XTNPeE{=d>$cj<LOGY8(H-KmT%y2mfuO*3w|$N5j1pH(frLa(<-%2oN>`?fe`
znVfZh<oXw|9kV(UWL0`>x%1CQ`nL{NOG=zxE%fJmY)8)fBVSGO77278R@$Fd!~113
z&oj-o{L}l2XQ=8YMV=I%c2q`x^1pET>3%QnZ`1vd(DwXd&ZUiKcShx#KB|z-ij)4Z
zCQtIr^&-J5hg8}lz2^5Fm~Q64yJ_iC!{ci;<xjsB{<GcI`0?i#2Fv|L#2D=Q{><7q
zJM}_JvT+=DuuPI>E#HQpnG?2u5S<@y)mmb|aD~r{`=!5o&M)3Q$Lit^%TL+I;&mF+
zPX79Kd$LTDX6&trz5LITZB{Rva?Sf=MBLm9`!iK<+AaB@y<mE<I#;!O-QEg@jATiZ
z)B7aXcjn6`X~urr`19m$Yae#+#q+*t?ya29_{IOh{msH3>}#HeybO1(u+_Ns`e^%s
zrfH6wdCyeD*1Qw&etA)>;y&97$G*)bpLQv=CjYGG{2LuN@1teO+{>z5vJK%%`@(#f
z!#40ly}8VD{TMsn`YCd|Z~l4mS76ifr4z4nX-c2==eT`R{p@;UyY^!bR~K!R5dQf!
z$=`cHXx^EE+&vFJc)bi@+>^<CMd5k0)aR1=u46^BS^oX~HTmuPwxR=Zev>tFxURU>
ztle=#C}V50QH;F5#hxIml-lyu)8>U5AGkDQdFtzbexCBDtA&4T&*rw7{?YOY<C?-3
zuHUx%&I^w__TGm(@hH#r6S92kr||vX%9u6bwr;nY=dWy|$BjpYf0SEWHpz>$S=uft
zNI!DD)3b$_F=U2(r&{_JKfR)grB7~OdZwO#ZG*|ICCVSNnvNH?xBL^b(tiB;xy^Dn
zkxlzzKmFOXS2ZA@KV^%bUtz}5C)LNEslQ)sm$gf=CEjbYS>JQD5BXOaD|8=!ejdG`
z{j$<$twwp}eSSZBGavqqcgs$#Zx8d@7Ju{4le62VxoysM*)*@p#?L}uGt;jl;oqNg
zFDF#KZTRm})B8jI;maLd*)DFcQ<Xtl>TmyfVyk~3_*nF_>nh2UTeo{Yd)U$3@KSQV
z{d$Y~MFv)nvX6))WO^^q5L24HTl8CT#?mKIC!eY3^KCPUO0`Z%lRW<3c|pF@f3xqd
z2K8;$tVa2v31vsFcifL+a{Zcj>{Y7NyKS1Px89oB^BOU}NXp!DtE%O_hnH>Ld-WgF
zcl0XFu-_i>Yvy&%3iU_XN7hbrxEMQo<E+ZFic=?L8w4aXUs0&vWWu$Kf9c%~k0lRP
zYIsilYTUl;QMRI?h5Dn{hs7QIy%)Urb~57bohK8#PL@tR>)(8aY1#%8u2sAR8V~3G
zPI~`s$`k%M*LxEF?O2=hZLPc6{`VPPS&h6pjgwx?-+1fiVrMPY;P_4TY+l|)dzS{9
z{B2mR`KOJ0K11}92mk-iHnuCbW44NZHuKuvynRQjYAtRHX{_uw4zZq>siAtM(#*bc
z^P;7JCEm>8LUu;EXCr#q{d`XPR;YLVZ&`Ea=FLmz_Gl~bGuz{4Vehka^3?4SX;Ice
zM!G%~*YC5fsFT}j;<ZY>K;nbV*=pA3st@=bwu}7zzbo|E^K;45il61mecYO;wxLNi
zplJU&kH0q01H4X_tUBv|FDEr~%GpT=91qAI*s<&548|H}8}Ev%@3tRknDXzxx!U2+
zX=WSdsLsjc7BCa;_<E~gk7~d+`LnBx1MKUfHB|$`53P1HbNKpMZl2%-5z&<Q0q5I|
zZOYGWOflAf7XEY|`>iOZ)XyPoSsA76fnM{RbL&1mQ}A|n{SxZ-{Ot9X<?N@{`6}<z
z^HG-ZU--$=>Zz%TUbFoN&z0BvHV9AQ4LIB!u{%mmYtc)|xz@X_w#?kd@S*a^^)_Xl
z#!b;`Pfeek+Zx35Hu3Xh^YkbwtwrA?=bHa7%P@Zbsbf9&`G@+yJwLj2z0Tln_xGB2
zJ-6;toxr{8mjVR0GG-Z><u99bk5})CiL_fy><m8(Ifs)4PF}BHNFSPQIY}smd-nW2
zJ8xbJ;Pg3jV~^!6#j{(^9cUMf7k7(f>I|BB$*SnEq-Nv14L=LNi%&fpEji10{e$)M
zBFoE;TyGIC4Bx3zW!SoP%c8?-s;8yQ?Bu2`+q6qlxj2n&p5>I%)f0L*$45<yJYe9h
zFtKj_rl_iGijyZj_nSR`&&`{c0y<?n*9&R>yv6vx`^T(;U8)lz?l#B=hj`z%ObOb=
zqgE|nBCa(5akjnI+*Bij^mzwkw{Lp4qhmeidnQ@kMi=kX>)PM%4)Z!$yz*?ne5<zL
zJ@1b-GkJK5IE>d$dNXgj>HaHBhjkl|L@TO(EopF8RXu&EW%9P%2B|#BJC{ENbk3dd
z$a3@K!_zDIU2A-IoO$TqTd%%nnjMpsg-_6?IVqnfn~O(FX<g<Q$^66mkEvbnb6NL~
zst>#y7N|~;dab@^URhzsl9ZPb+b`T^Fs(67>Ug@)$n&=L8vRG>=SE%^{$chg`_Q^+
z4zFycUx=z=Tv1T5B<1JYv;OyN5;9lxh$-7ztJbpXJe`nwFEx&TiqUJeE%UCGW-NJ9
zdHI=ozFUNp)@I>g1OK!~?#~P(W`DS1b1eIyNx}lv2~q!jB5Y${Pw+Uod1tTxy*=&y
zn?vi~dVY)4-+DlfFZkJ3=D7YJRRxPwCuE(z^0#2}l;tnEtyO|P9oZ9oVNcP9r3+gk
z`kv%%C}=q>+<I8~f8m+@$Cut;X}L1FeUCTimOZ`x_k5J*l<2A+eaAUReYurRV8on)
zZ6Rx}H}~o``n+J+6Z$M_*UiKUlU_#6p1;TP_@w}*xm{-`c)efNv7U9i#h;m*xC|Ei
zZ2e+*;jrR_N$G`?KKtcP3Tl==ueI~s!aw(UWZxOMB>(ML&pP?_y2+=e{XHGvZTxDM
zp(kfa+gbm6cak$T9{vkiw$qT8U#Q2^`qclfK+EDKsuLo^r|y_`r^3x^h2DXR+4A?r
z!?WHxXU6~iArf)YzB;6@=ZDn?v&44y)Zpj`?}V;i()_n`=@Y9H$JF!hZ8Djnlr3=2
zTmRdh9h?yt?8`%{nC)F^bZ?vxI<cqk!2a$S_vb&;r%hVT`(fW%|9dhSl^UtL7{!C<
zFdN&mZu{&nvovUb(3B;2-hFUiEL-3@@zsl*|9gTq<t9JA{37gjtS<l3E4L1OW}U@-
zpYb^3+`pUMGDQzPGct^0U&i!Tr}2eMjQO|L6$@`3Q2gh)^hx!pXUErWo9ZcgVBLY)
zx^tNIh2xgLeKg-F>%3cyti{QP{b8yfGPGYmKfFtRxr*wYEHk^jt!p);7Ee6z_rUWf
z^>f#;{b1N3{DaxxhW%`hXN(7yo>F&E_g1KS&D?)s&-DrQ3OVy0^m_(*-AVd9+5G<&
zlPQUF8|@BUIv|i>cxdI@OZugZ`+9y@ZD>|q5dXs4qWJB(UGmeOt(&e{+I!it;=!sZ
zTHZqUa<?*O&G6Ob_nc_0`Y8KAGT;7Zi<viQ7<3dQ<hRxfY0f=%<HwV;yY+G=DQ#zY
zDE?kzJ>%5_pQbgaq{fFQEIR9d@6W+c6GV2dR^G=J^X!9nkPP3Jk0)oJJis)qeM!e!
zhdsA*{MGibsd{!Dh&HpYEMB-&QM0JurH0qy+{5WhEOK%lU(T4e(MH8J=XA&Q|K|&4
z=X!P>vo*7;{JdeQqGnQVgSpZ^wm-LoCM>bwQMgxr`1$l)9ez*2+t!c1{;#|f8!~Cp
z$8hQSdwz;!WLJ80g{Xg$H<R?fwv9zalP_=U-HN`gHY%=fR&-qde_OWBv+FpcnO&tZ
zbHtHP6GT?BHhvUb|DRch(X*>PI`{ecuhZI=bo{k^^!2|!-+q;&$;#66-8Q#9Rn!dX
zW(ro0{e7I-7OvJCq;{_S$6xhJ4(oe<ELi>a*yimZrGGi@UpTVkTYX>q2CtwHaM*p1
z6Hs-1^Qq(d|5}+k&n|cIJ6X5;GgVjab3E|I<N81IMzd)RDo2y+rRVQi$;uWbH%Y0~
z`N-@4*FcVV>I*8a?_ZiAvhtuq>5}aK#vsw7Yqv?C51ZD$#3NSz<E{ODhxI)Rciujx
zo^N;b`*GEyE4wP@^ZmX2aQc!RJFb>Jw!8-NZMJgk_w0tJAQzmz2?_;aa40NvJo3Bb
zMO1tIq(_%HCGtN{Ha7>mpmfRWe>rzTLnbZSJiXU{apdh!6GRrOHbzcd_dDF;&m@ug
z&vR=&Ju~%o4qEchZO?j7{ih$igJQxqeatjrkC2<Bw1vY!_fqNqB#^<yprXr%ZCAA1
zB&8C!C9nVSEa(S0Ig()pDB(^Aso$&T(^YcU{{BPp18*;s{R-ll5qnha>eN4G<{iRW
zT01u^n<QO4_0H_oPd?uAnzwfCqoccQX0Cp6-*oDou;7!HI~`>rV^8`Svm1WVeeobZ
z#A};#PL0%AgVWAIEq%QuXXmr&Jo|9`d11zM=@YAVYVn;7EsD(*UH^2|jG3#I!WW!5
z7y7Ym-K5t=Q)Nt6Pnw$FzU|-BrB5m@A5+htx79?&bp^A5*`?C@p2PC}^5V%8Uuk_i
z8Cq1nu1k|Or*76XFSVyyJFU$-?9WNKELB#TdVW2~?s?PNmvFolemTpYmH)xHJ@UUc
z1+1HNI9t0?E!@-h<m?5NOSW~DXKP7LUY(-5;LycMUeCoq=~(VXMx{qrz?yvCIWI4y
zhvzA*e!6OhTKLH?DyELTX6{pK0)tQP+}XJ1)eFy~S7#SoYvK(!JSVr(qwB)6BfsAU
z<hR>br-g5d%oWvNvXFDu@yUzJi>At$Z<Y79SQPY7HvREr^Q{h3pDJoP^}FnPH~;yC
zbniTc)z7plP0scP%**dvRXp|2<|>8go;I_-O;@UN8~k(XK0Olzg=1Jx$=UgwUrK*$
zPW&XK6BB&&>`t#N<EuQTXO8c5?3s0AKC5i$%BR~le9Sbl1|^{q-zC}qp7Pb2g@kYN
zT{kJ;_#VgExtgX^V=R(A*`gSOKHtrLJlXs{!&^|<6Uj0|@Zqd@-g_R)?*3?vSg@=s
zTRFQ$YM)>DQC(y9in>KtLcAGGK?MjXLprIu?Rs|q!G-0wzx?}hKJ-)Cm9qhVkF78Z
zKN)MR9eM55glBJgK)H$W7bwYHmiy6VVSXX<*hByIF{;^aKe}RqjkV1?7OxRn`H}m+
zImp!gpdi`bS913MZs+-NSDSB`>85i{HQv11;%?SNsar>nEx(wP3<~AqiR*r9TYh<I
zQY|q1`KlS2hc9ml3Ewn1RQc-nmR|pRHJn>OB~IE=kL!Qxt-rjSB7I=jPOoJ*Uzog3
zxc**^XG!~2W!BTTewfS(*5&sU+@*8Lv|hR0t~QM~q4kzm-G-By7t^@aqaA|^=Jon7
zo~@~qS?ST`Q~uyM$Mrw|Ex)`pu2U2{5&Eg|tZ%pUqVu2rM253lMZ|V_x+m-bRjBD8
zCpu1C_j9-PmzR@QKjD*}eJ%AE!?by?&sW(Qh*|K}EcGkwC>3A0EF~Khr*ZuSd;iO1
zJioBq`>X=r#)X<Eo^dHZ|8-gJfA`Lhx*PZd5|3)0mfQTX(3sV8)n>mX+5aZ;)$a0<
zKQU>i*Rop|L>4GY9a&fWx3d3)vHLt`wus78i@XjomY6x@EmQDh2zTFc?>~digA2>O
z*LBt3I5TC7;weVqj~YU$7v|^I-0^Xo^s0n?nahr6^WR=re)^4<+181g-p*fw-6C60
zb(I~sZe|ZMru18P!QT0-UrJvDFI}{4()OH`Q?~@39(cQJD(~%EKX%M)Qu%x6v*5b#
z<`!>W2F0E<Gc)YW==k%^Z{`PmP=?|vmzpFp|EW^!=kU@OmzQpv^gJg?=(0d4^K9{i
zh}#U^%y-umObv=ZRBmMEz+1cvln&~93-<o+KRi!wC*zuI=E*DCUM%kwi~4mdQ$4}N
zVBx#@q1-mCYcjX47V+Em@#O5NJ3&D~HMfMGn=h3+GHYAgib>Kr2}0Keo;FlR8_apz
z@LT%l^Rp~wTOWn`<Tm(&dI^f4pf>{rz1WKf7nUCvuYEaZ^`qlKrktC#Px?xP*l+f}
zv1H1p`|%BJ8tiYboKgHM``Mm<)8eV?lWv|lwme~S<fKgxmT_GFeOcyP$;x#p$Aj!l
zcWx;@yvwrwWX`|e+*btl`hVuzQoo4v|CzIEYD7=p&#n2CCUfE5rwJl6-yOJe;@a<<
z4)X1Gu|-q=?481U(e&=A+X7QR-H%@YvhQNcLK&VptY<O~+2_}5#~-~gyWm+9?*#VG
zo<axi39kEIZt>=&k<_gxS~F9er~GJpan-GDgYgFS4=Kj~D{n{q)oKegv+GUU01C){
zmmT;1pGx$f9?2ZB@QO6=4S}r{b!$I#*PrV;;My|x#jM}wXExj}SnY9d^T(63)pdD2
z1*4`E^m+Ka{`;D*`qvenM*`A|u9&z?XJTj2f2=pbYr$7|(JCwRu<E@zXJ$@^*3PqS
z8m7E~!Sx;YHotS9dAcEU|Bw5%JUQ7{S4ZS+_?Y>{VdFVaX>2Qdv&x<|;y|MR{20;v
z+X74XDgJ8PFw-e?p5i+;9ey50tu+;*-u?-@&idbrNdXnZ@rM$x7_R*uZvAFu$i&qt
zyLbb&q!(p9usb9?ziis3Q*Q-8O@v7xuO6*aRqKqro#;P5bLtn}QsWfoE3dvjlzzZ+
z=UyD==UJe(ds3!H*Ohvu==b-_PF&UuKUrnwvNF5l-S(oXCfc`un9O1Zl?bn#Yu2BZ
zeYjzH@K=Sht%_c;&QJISyykG{)O<>lx^Ng&3*RW4KAThL&4%S$6jwbdZ{6{7eynHS
zp#{rQe<>8Dm*z!y|G%#O=l!f-=V#7cP+#9Ey-0p-jH)O5gKAJy;vA?g;I16~KEM3L
zW$o~z3y)Sk3VQSBQ>Wj~|9?|&gdDv4Xo`e2sDLU3JIA%AePiCM4a;{ZN*&>B&FIk6
zEp{%-tl<p|UmfmQI3MJ%e2~BFCa(QHpD9=7+m}@<pM=a8Sh`6u>cXo~Asw-Y>l=K}
zZUi+}?#kY*s&8|im$%ca?;|HDDEq?JPfD25>%X|YMK=!=;O+@tDcS#w_^NkZ<#{y0
z$;8F{t48hL*v%<L|Ng4xb*x$&qk0t7j{NKoYI&IT=j{Ez-g#c#)zCM=E8Z?m4>x=G
zf8D$P&;Ho#-ZS^=dddImSpNO?z9CSX{Zxzd8mMZz4XT<-6H{LAP3KQtsJJS{{k)>r
zT}zkq(L24GymM+kJ(FHA7u1lO@3!UM^#`vn&YU29;1xKg<c^&62}zsV&}n90`C0t5
zbI_7Dw{7?A-%Ln9{KW3dCQw{WVcy5^kN-u!=xUj=tsgT@oOSp;Ct7K3`dX*oZev|E
z)d#HVOK?_Wd&AsDzOc<+PaUP_@2R|YX@bbccBQEI%Ng&=etNTF?UPjLMOVyR_Ma&~
zV0mEE{vYMKJTg8%j(v<tFxHM+dv*GUds}z|4!;4ndD9cBTwedp<*VFwC8TgBZ(x?x
zqWs2{zCZR?^I5P;%zs}0J%7RMsq3d%-8-h9zwAf$!X+KKVmD{)Z+4!idv)rYMCU29
z+FmduFecPLSQ_@HIB(mht3mH?|9NtD>oib<c<PS0>91c+NI(7M-<R!*Uarn2%r7jj
z+h?;rU`lY}{#V(&w$Ajrm6=`dvv5$8f3M)hs`}-J=lX7)T9XJaAeL3~B&sKrKPWup
z#_jv_`P<y5t9PygbrSd+xj>;PmU--~yV$1P&hvatr^dvbYI||X$lPW6vh|9qSf^z_
zDhOjrp8etcpS4rhKYPLCv+d`}*}|ZtdE0Q&*E+QehZWB+yTfozH`Tc$_<Nga*~>{c
z|9lr;p}1@BOy{a#;eRtvNBzv|v(2rMvR%1n{!>NGByra*&+fl3NRM(|89%#Ql{KSd
z*@ZvM5#cPWo_{>Q=lG=XV%x0Glg;^~q$VkS4|B=hcU(Iq##c2tCqd|@fb6|Pig$be
zxHH*s>!ciAZTU;^`tOHlPwIiZ{<SY-?|L<v4=Z?PZ&YC}o*Hudh{`I(Dv^xKU5T+m
z7P33IcktcVI`zMe>#GRq`FmzElxzWYe3o}y`*U3OoyC(?JC3TU8S-9qchFxQ<SB6Z
zwZPevN2j$dIWbrK;;i~9hh^I%r>;p6p4`#)!g|)e)pJ5Zz~#nOP$H`~Tx5D*dUMB<
zRXfhREnCBT(fpjH>dBp;j?^?zmuqfg<is^U=Ud(>oM|{=Rg9={ZrZ6!0(;qcwsB1r
z$$f2ABE6tZGPTm9>rR#6+Mm;{?tGjXds5QOST(;Rk9k*gt=A+$GrQh*CR=7aRn#mx
z?z-h&{@a4%>2HKePKJJ($?MA~waBY%p1<=K-3`-2m#gf$`Aj|k-DVS&&U&{^&(5>#
zvb<AxDs<Dl+XdV0HnVT~7*l_1^6O{Uc@90(v0Y=P8d#nH8nAnlQRyL+tQ`4SzHr6j
z{I0&uD>Gy3WL)0w{I{l_(T`bd>!B$r)i-}UIa{%y8RU#wrKs=y1v?gpPh9<^PI~sV
zrQ5om>nbk2stjt<EnKSTnIn90m;IH8*Z6BAHNsEMHnY(ERhQwf?UDKS>H1^O)bqo(
z+NgA1R*L+*pIJ*LkI^T#>u9$2&kJhHBmLX|nM>V@u=QHJIJd^8+GEnQhm9WB{_eNF
z@@whKzc1sXPl}sa`+BGbr}L#$u6E1(3L4Om$<6c-64-X4H}UTOX6Lm#&q}zY=BmEG
z{pHMN$ysr>6Li;#Exp=hX4gB<c1z1sMNb{Ei?`mdzkTX;`#znJ=%bU(>?>z4<S&}K
zCUvUD*?-_f7$G%@<-oFuYkuE<{M~t0`}PIS>n6R<X?phL^c{tN9~euvSWQXG?R*~7
z`Rv*CY3(YE1tBW0|IOvwI%`pt!2Xk=Mw-vmolKj5?CqWK=c@kgpNubZDm{c4%w0Bp
z`+sp^Sg^0O%l;Tqe)nz7cP?LLzFD_r_lc9;F(Nw;U7E1OGOj!2ZT!K7VaA~$;h%Qj
z(mIy*BlE(R7}4uzq>gCuZQry)+u-Ok_58MIxk)T7@lEM28{YY=?s3yIy?sOV#U$w?
zoLi^<nXu69#n~9u_P-aVx5^}@-kb+Yk)Wt4=IKg#TYqX{Shnvw=k>F^{>4NeE!WI#
z*|&b>lSMK0*9uHTyCe8+X6N~BG*QXy(^ZcA{r^?K>HxcjzN=H;L`I*i7y2I?plbg_
zYv;mUlP2mrSG)TgzVx+7KhCxy5!8z|ao4dv^Y&H1YKgS3=|^X2`K@02Xe*1U<NWI(
zMTK7-wiPV5IQk|5RQle!G+{~Ax}KE3@=pR*-&pp2d3~Nh{h83Bde7}|*QF$_n^avC
zDq~eF;4I6jS#j-|dj7Y~CMqlEEmw~Cecbwt*4B#`(w;d?TQ7Gc&UEUW*{dHtyrpG#
zGBoJ&sb}dixvKtGLW&Z<Dtw!DbG~B5gAG>>1Uak)4ZkypZLv{VIZuM`ecge?u%JDx
zvLKt+P1?GOeN%0z>i)B#MHTBNP0n6rkz1ykes0~9Gcl^mpRgION)z}U9=`GF8n3Wf
zciQ9ru`XR^33624c95gaO<ePTx#g8fBGV)IZe-_e+XNDPsucOZykv#y$?oVklI&YH
zgY2C+F$T1^M^#g9IjF4vIjv2_v>=1!^?x0kYS&4NK21F9e{W4vrbiI-bGHru_P;dn
z4zjtn;p55K+jV(8Prc^56W~5+isEyS-oj~ZDo?-Guv~8lmPzyMa*lqGJ$pXeO4eyx
zY*aMY>nrczd-KG=J4nV1RCcTD@OqwFtsBs5ea3T=(Ic(d^Y{FmyHwG$@~dj!b`~qk
zE0d<w$~Jm}=0TWWBvyI^#jSQLko|EhaoQ4#ob1n&&C4UCCS6&ftF(j9<~_*NyzM_v
z&R(m_>zQ@so?r}nUhxc7&ELD2FXz-rJ*l>t88hkG(-$1;SnCTx;@`IXJUP2thu3q~
zaznuwZoV>*;5(2BTfu^_m3D~bfc&~mm*>p3pP3W-LBi{+m3GMKfNb0L_ue!0e80^m
zDw+G{^*pG$a656@lAP)*pllE!HOVA?y=#GO#&ZMjpt7%Qt8(k4o}_v^Pnz}Qa!)+J
zn&pv6Q*zlslTQypp?y;2&%BUHQ<D5|{4w$1-LPY+qNi`r<d4~hy7@M$q+Wj{7;_?O
zQai|FlllZ>gx{6VP}SW1FX8iK^Xh1+Nmo>Cm3OG!c>uD?Huv*oh06`BI=r4)lT?*<
z=*579&Au{b<u*t?F$1|^jZxF<LlW(gTD!Os1QQfCh+H^q-|6+x05mp#?9zlKYSDI0
zuMbJ`Z4N15Zur~qy1~3bvhvwImIn)WRbOlUJ9(wVyv;u|Cv-ZngG|eL%CU}jxy6|v
z#}KB)uca1DtGQI5b>W`<Vy;xrnpnN~bsJ1nRz`+(Ke$z}=CIDz2=)YXuJ3n$8UL`F
z%k{(qWaoiP6PBb!8aHJh7UbJ}C5M|)o$0<<qMse(me2lcu2mg;w%l<a(=AX`>%4X;
zsI|C}IBnJ%^8zyi*7<j|4*miqJ4;X?-mVgik^fdaW9iRVoO4)xbT96i)3g5EO3^-0
zS_=gQ-nOsGJM7-PH}LL#<x&x4ypgB)GylJzSA+C#|1mjHJ*`z`>xqJzRKKpP>l^(~
zTbR!;;J6~xoKyEHZOc+cPhFwI%edMt&ji_O2keM_95q?e!M)x2Z0Ve{{`YvcnW(IE
z4eNa%RoHV_hj9Z#0b{`21wSp%BnB4m&H8*<K|fk-(v>7_w}QDAhZCpWV3nAC;OEY@
z&WoQ(<b0lN?j9*M=}MBb@(#b42L{?ne;evmE9(B;Qw%DelkoYn!q!sZ*hyE6oRxNj
z#k@Drb`ovjb*=OH@yF)Q!l2?m*V$G$&fBD;vNCj9&x5Fs`R$PtB|UB&)aCvB*`wY2
ztY(h%f;P(&mnJL;dntKv>!Z;2$cZZ$_!yT}=r7liO8tCU;pzdUX>BT7y>@e~6TfeD
zrpqDz!9$UA=jX~=nO@~KbKw27AXU+m)o|{c`utas>Zdl{ZS2&XJ3rg9CabHiw0oy-
zz~48ynI1uoJ>3sxZR|O`h9`>Uhx@7LY5eVhzJ)W+`rn(}JJ(@Sh=jar!Ci@$2HMHn
z&L8NPl(*{1TD2UMDD_S|P2y5(i}ksC(kt?!@D5Go&!42)gMBwz?9+SBUNI>ohTo;&
z?gt&E)PvIw+~7HTI#xEw^yooQvB3HQR4g5gkw3Wgv1xmx<~D|c&|}Y@`26|f==)^`
zZ$R^%q)3k-$KK8dw+y+<X9Zj3veisGX!(=BJ<N9_$HO(Uvlslj2}<)#T~F8SE|tw%
z>Y@K&7ti_QYh{v5kJg#l^L}FfcSzl{bz8W~^$Cw<vX&mvYhiBPY$a~bbj#vQRu?<S
z16Cjp<Zbp?r})2Y#ngh@#%kpm-Sq`4u8P=lzPG;3a`n8}v^EvdI}<$CDPC^y<J&H@
zg2`gS2Q{B-&mUet=WKfQ9>_0p8TpwWK?h6wUPKukdKh*{hu22*qRf|<6K1`!lU~5K
z^U$UVOBVf9o0NUhm2a!i7w01{Tiz~D-Z}j@L;amFVO@qZ8yK@D^y>0@YR!7CymML&
z_m<Kfp=r^K^6nM-&(9TQZMvIVx2M4~sPnGWMbp&a_UP12Dh1(7z88JB_><LVo!d}z
z)Nzv68-Kyr;JlI@p-FEWlN(k}ym$Ps!wpCOtV!!yVheJbUZvZ5J5TD$I^VHQ)3~8k
zwrJ{!Uk7eaynp=fIirB$Hz}VlD<psXpy#QzZL0F_Z9PRNLR0=WTJP!q9BOHL|E%8}
zww(t+-gwP(#ib<oC)0}u8&-4dVoYbayth4B$F4WjxRgQ7vQjD~*4ufK*Q3KH*6IJY
zdZM*}D`EXEwFAG+SFqKkMy}XtR{qK4M0hE8kIKp)|0HjkK6ADac5U5g_F>WY+^<Dj
zQWs9!apvS@h3C;?lR}KrT`K1OY(Bg$OoHLgqrXwjcd{~9sNNDdulexoNvmmXDpSvx
z3C5-GW3ICJlC{j0!~WK}FL7%f;}~~EC}nk)&T*);ulQPO>8UmMsPf)>F)uEx?%c(w
z&OCXqfA*Jqxtyn6bWM+WUQu`+B{nIfDBh)F?@GpNMK4VG-!?XX$es67cAwRmpup^!
zCoWk6`hJr_s{VI;ne~}(-?PPSw-|N{-RJAkwR}@id)jra;hD}W3iBVnE}9g=cig4s
z?an(7uj@-KjBVJyM?L$}w_CTPjk4AT&+*|c>PuDhOcnfXzIJyMlbMs5ldqrd!#Aoc
zuf~-+{oFN2Mb)J`!RyHN`I!f_rZx6X$PD7!QWC<!Jjdsqp1LRJ=l3VpJI6EC>NIO?
zVXezmzOqOr>F0`oz5*xH6P43iRi<9mSns-rS0_g^B~1L#!aegNUhAGZIBf#g%S`pD
z?Hj#<4y}2#HRBxPWLw>KpGX!9(I5AI<$V<U`a9B1YstOR)~77LE#twy$jjZ6IA`+p
z#-lo&SEN~De15o{*_9WW#=JY)OKZ#DIWfGS%uhQ_5_)L0-m~}<V?d_o5<k`rh6U#T
z81CNkVc)iGNeIt(>w{7$u^?56)$2XK8Zq8DvB{&AmE%79-t4<#Dw7-HBg3?=rObV)
zvU>W)mg^=eo=>m$7W~?Cefh8TJiUj)cTdi;Jd|B%AGMnG@07$DOP40yyy|&PK|Dfi
z(iDyVpKeVt=V$7UlIy%MwZP!T<ZG!1KdW6hFBEKe_nAxfgs(c>o?cV#SLbG#JZ`)n
zp_CfvSkd}At41nhjSZJh#>$m5tgITPpG4Qh`c0aYrdYGLx~`HV;#iPor)uNm2L83X
z7d_Kju=nY*B<Y7K*%Q2Vxjns>?B45U`ttT7?vD!BlU^|YnOKmQymo8Y7vr|RjZZ?f
zrdz#~N=XKJH<NvRpzpc<1CcF<?XMPj-(Z<)Gr4i%w0T}jn>Hl3PhS78`o>!wUQe$j
zeFt3Dhn_tZ@<1t}<LTv;(@gF+S*EJWGdk-!PQCQXZx7qfTbm{<aoK$*JG48<`^T{i
z@dcApL;S-J33qxo_^+M1sg8O3gr_TltnZ$@t`H3hmyFdFYqLt#n5Hw%7I@D7`fa0W
z<KowOhio6O`eVtR@%q!UqKd<uHy(U>%r~u7MfG0&o;1-dmb(~l%zZO2{R-<10SVt5
zhbmV+p10zCYgvhB@J^l*A+r;`(^^%Q9+HdO-1RN$ZgxxTt1@P`B^%6kF}`MK7uc5b
zPv7A5M&FcsOw-CNgDqv>x#Ud91%+2@-vNvD(W)oQTb64*XQ*b*p4>C{wb<I<`9FCJ
zv>s0Q`MprM#pEx?-K$G|o_^agd1Kr%hPfbpy~caWrv5ek{Gai=keRZD;1Aox>@Qy%
zo;Lm~JsT{3=-js6O#g~an++bWnV<UlpQJS-`*l+raprQS^^Y1qWu7ZZu%E84deF&X
z>*P&wdE0eVG()SHFYl>a`tHJwm!<Yj{{qbGO#j6$I$3>yOE1=|%XaP*-c8-9ik>Tr
z_g&Xd4x0Fy!=G{KksrH-H^-$h+y%L4?!E&)>ywYEnAr=}bxapps=Tk-y8PW%9Tm;3
z>pobe`6zu>3V12BR7L6`OYVePP|91|xMS@mLr*W>59$l%o}N7ERgikt-Vo-!Ai1rd
z_so-=+)?9pLovW>4c7y0_3XViS&<$=uf8hfFuyH5JLA*Sss-(*Cr-*URnKmg$%*s`
zQj>XXdUnR96q|=<G&Dv1$}e5>*4@yOs^~fM0_TrA*|QB*&(<DD(zExPY(8hl*H7}^
zPLqsM+1KYDo1!wgu{O47iW&3VJ-kMzHceP^X6N<SvkhI(9zGDHXX>^1@SFp@Mkhex
zkz6xgnVy@m$VT+meO0&2Z!3g%#>H(`QPJG&Ryo&r*@8-rh)YXdGp{l8ubpkZSeM)L
z)S9vb-f^#cGE3E%_Lq7FioJQ%k~cvVB(vq<k5_XH*Pgt4;E|r{sV?a`SH6DgR8{m0
zv^bDG&+zQI@D^F=rDrm{EeuX`{wqGWQAb5n>U-r~<7J*J8TDAi3T_5mTl1PFe?oku
z*d&qOdoA&M_WqN+ToK0_R=zVJ?C(*}IQ_>BX46_#TvK!J#GIH>Gm}fk^+t!wsWs(u
z-h3@u3bM-TMD_y1uSN258&+}f6m2p;F%6{tb=3OiV;>kdOg-J0R5)YuzPLITt0=Ka
zB5VB)e2(MyT{4qN=K0<UNuO6t-XE8@T}4H+ikta;wXey<r)mrOFUN0u*(g8Z+}!wR
zu}Lb2w4dIuiZu~@Qh%Ue`JSY$-Q5m*&#cN8QuSnt=>5Po@w&(4qcyy5+O1z}6`Ajn
zxN_QgT8m1i-fV`;d);R7JavDNvS9V)=#AOjJ>`KbrZ?+ydj`qPW;EX8H)~3|SpnyU
z6~R$l*GdyJCe%%9Raq&hoYUpgRV=<?%jJkw@AdWgzJA)Is^~eZU-!dT%gO6(TBX%I
zdaI7RE{gNpq@v>KyFt(3;_GFe74w+Q%6576t}a=aF(DCTQ0Fw}eIIUR3e6C2JUe&M
zr9ZOIngaFZqlG3dNqfb;=cVZt6_x+2ZdSTWmsOu>T^x6AtBQ)J?gi!@*I%#DOpasN
zR;uN7b~D36h9L2Y^EdBHRrJhS$dzCc@cQeODF*yZ(iVT0OuKo}bxGVY;d3dIR92e0
zF-_jHZkEzAwjI0?H(#o4J-1a)<7?4gRYgy&30@B>*RNf6U?yWsSa|%TsFh4Vj<qh0
zE8C)@;>miY?*mut*6R_MPt~x_;m~=sWfE6<srdA&nVcotbyPfEH>iDRydHJA$%gw)
z)b$u|tqsAkDX*R~dOJ-Dafxl*&#-y#GpT3)qwbU*(DIXBxg)OZ;L7REI-H(CoI3tL
zuHMgHKhyd>)8dAEe!?q%h#l5-eC}s|+G$dVlIVf=4TW*_i_eD~QVTykS1c&=?={vH
z2RqMAQkfc6{=g)m>-wV?pM*BpKlJhNO#Q$wzNktv*VALtsSLvhLVxyYy#6WiL)hTT
zr0J(t+Zx<-T^VO{#b?qKmZ>eqX=xR?=X~}t{&TyL84%=@^W;&8etd+`q$Mqpb2cc?
zwNF@Pe4ja-QJOhdH(j&xT;al1)4O#!J%gNdIb>M(y#H$T@#l(na@n@C6*Pa|E55jD
z`dN^74uuNb`>;cH#?!6Vf-70$So{v;H!TTSS;Dw_`p1_1RVtod-L8#?8^!nZO}B{`
z<ny^Zd4piv5)rE_N7uxy10@wrGX@K>imTaGfuEEM;_v>wTr_R=6kh(FJFcGIHmyZP
z)A{VhgQeylg7+TV{)6*^Y>Rq9_Je4Zpl2n_X}fNmJ-KGr{!SIo$jhA{df!MKT3uRK
ze#OAJVR|EX<K2dT(|V`W-ro7+>gmfMlZ0X$cpD}+us0M=jQzZyS#D*vz;}h5rVHmb
zO?Xti)Hh)7oHS35NlM#T44OXhURrx#_JNX1f1e$%KCrjt?RtKdIm}m%FP!#evVLyU
ztJGj`r%6kyv>Nsu_;q04f%%QI8;>`XH+ZJ*O1sXG+&I0Vnj@WK9><&Da$EV9^#2~S
z__yEAt0+6bG_6&|^X#>m8yXL1wQQcajr|+jKaUF4_dXBSANX0?ds_5>=>gu-|DTNx
zm0Le&N@rZoyqv-PnrWi-mA}Q|E3-?gZocu*YN^d_di6Bd8+7+n*YQ*{$FD_eRYA8|
z9eu1hdqI`ug-H`Y_hEfp>l?6lO_ry}Bo)uX4Cfmz2i!DL%r0Eq1eU#UT5Scmfc2cT
zq~gm~&Q;U1bvQjIsc6b|-)6abS{};bzQuC&bOFSw(>&6OMJ;DlcSZ7nE~1LD+a#&P
zz9(H1WWmRs*V8&=3RW*w@SL=S=>_W=rX0REEII6J+<(-?bC%3HD`5FR!rO6@is#u2
zk`c@n3_C<B*k+vgbKlEKHsXqXd{Iu8u?ydg6G0PHJcE?QSk0LG*z#EJF|CR&d~Ydh
zA(!!d{<c56uJL-jk=D}509m=xk97mz2lEGimF~6Mv48n?KDO?E*B-@R2ZSc5cnWPW
zc&HhmX)gDhMdHQ$eS5xj?NQuy6C~3WCHl~MLD62zubLOmCu+=pci>8g^rFMMjGmL0
zXz((>W5^OJ@c*TE;j*IU{A}gCj%x)!R6Qpx+Qd|#{xJHJ%H8R9EL%z|P9@Lvn7#0&
z1ABY?Bo$4rX3ppSYHJ05rJgI8aq9V54(Ub9Wy(A!Ejja=ImYw#wo`gf`A*EXNO@Wq
z(ZYLizARYkRbcskbKTVME8-dV%Iv!o-IG!i5Oyl(<p%FbDye?e4+0+i7P-It-YbJ?
z$GHVfoi{h+@$FRc3|f}sUdSJ;o4T#s!u!3_pE^+Bzua7O_iya9cj5ch_Iz6|^efnf
z_o64?b`{T{SGs&LzMIPXKF|IxVyVBVEkn0GdXkFfRx76C%=T%2=6$WUnZ07ky1pfn
zn>MI;PP&v`{UG_#PsMuQ_B|ze-Ah)iD_WuIIVmW;@<HGuYprMB`D$Orh<XP07J!A5
z6(2ZVD%_A|ShPnq!0Ne6K)~b%KEACgo<WbcGV&?hea<PW<Q~DbwAh1%wY2%Lj_0H)
z6|b4ryWQjXJLRrU`=y_uEUa5Mg2f|h8)oM;y-Mv!4Ya!3FjG=*8Gi#;d*mb)%|a`N
z<CFg8Zkav1@ZSDu_x?)itq9~>53-|&;T~wr&0Dws(rxR-M@^U`Zakc-;_21nc)&il
z>e<YP(>!06vg|vTU>N)Sg4ZM!RVVQWC5QO0nc4O}-#^Xkr_9`qNvjyA6-KCfPCAvR
z{-AjFT(#8j(@SftnBJ$Zn2}fP0g}kFd|)_xj@onILzX^Ti+LMv@rYd3S#as$6ctac
zZn*=M2Xbc5NlVrCR+scU>0mhbwSm_pm8mhHYZ0PBN5(jwR*!70Devlj>Ahh0VGYko
zAwk&;`nPUusYrjaRCi&@%ZTesmu+0&W>qsu#Zz^&Mgi~5A8!`LNajka2B$x`H%0Wa
zE8lDt&mhk&?0pP%8y04Mb>ouNS^gx8c@D=JA4kKz3?)S;R6Hkj<pn>Gojo&bxm3j6
zBCqz;Ms}eXpZUz)mOhhIJY7RM?<6Y+Z}@X`lGl7*k9%>S;u%BvdR07wE|##LQ<BZ+
zU8?&2;cefQ+l&fi4fdXC{j%{aC?j4BVff7ufBS%liRl5WY2jvHSoqlHE&O8LZNsVa
zM!;i|is;c>2fWSnT~Gd;7H;;Hxlbi0FW}6x46y>H3)k#H$@Sn@*1S!bno)MFyCTzW
zUYEYHInSsz`~cG~X^BVk!zZb%d|<__&KR5<)io<uXX}qGjA0CXtFkB9Wu{&9VP2<J
zvt7k=(vm}~6#h*3+j`dP;^&5^%jWBF<*@ZIty8Mu{~~G7yrKH!=>tm-Y;zF*9|Q90
zM!h=qkX2WN<b*svUp;2usNxwE$jkIEadOb5n4FuQlT<vPZdLdYZsWh=N+r*Wgr8uM
zi*i4hKkPm0dGfPC9g~vhB$cUW`40RxQ%gPR`y&OE#k9H~9w;_bO}*{#FvU9nbidu+
z)P~(TUZ<v=thfd$P(zCTavYx-a(l`Y-Fyb`=q^wR`BI0ahjH2M2~$k3KYGRq5;<9-
zUbEcjWZIH7Gnw9`T7s^ZTY6DaqBS~0UGe|X@FyVOPI|#1!_>1?(DR61QT<Wft)Q#!
zCYd;~GsoZRP*I9!l#ZSTx{t3nAZKUqhR#-y7NwV5GL7qxscH&0-qrQ>oTRd{LX5@l
z&{?5L)7TsLO<S(wIVnV@mh(A>@3x;FA$2T#8*D(PK9XRI;XkwKr$>w&J6psekOLF9
zGP*JG-!4)4HsNY>BNy~4Ke+=B54fAjcAj1QBLo~8D@+?#H?B03={(DS;2%`1qqWhV
zVg2nK6}#_`_=-S=tuAFMWBb=RTV;vjea799+dyKcOPR}<^3?W}r7oV>cgLrq3v@~0
z%9+zx|8d-5_u0PFBh-$0+m;rP^On8jTf;8HdWWlL>q?K*tcK4V{$Er)C#jrWs=YyK
zgZKyW2k{5g9oC+8dG$H#?hQ~_n%Ny#Wo8$cB2}Ps;oPR_DxN_(R!rIqyP4C4_I=;@
zu~VI&sd)|?=$gk}+YTfoR6j_0!1q9Q!L4Nqr)qfr+{#q+oU}ye6>|@R8{>7x|3_o*
zojE^SErv<wg~>z}&!AhSiZv|z^$YAiSQy-!UFZCGw%VGPTfj0Q49pF=4U;+6@80YF
zW9xnCTI2nHIAl6!t9eXP(PXs}EGz#lTcG%X$KdAds>_G&_*Jw9fo^)7<J#cMasSsH
zmOZVrWo8_D!kiGid<OUq&ZZ4pKl&YzY%#9g_i5Q(5yi`#yE)2AZh@j!<`%<gfpcGf
zY9}sk_Pn=Zw$PKfgayH%G`aK=p9I?*-aow`_MR8XKjYi^S#ZPD%Yl<rJda)xi;%m)
zzC)ryaK^*4J2aD*3C8ume)46Cif52wC_^*n`n_|#D?S-tl`fdP;127T@>O1wR8|U1
zV=7}g$0T<&zs{%VGv9`p!C{kBJaxA+Y!EE4Dd7LmYkpIW^(UhRQ^tFdX)2yU!CP6w
z80z?ASod&VsVL43nsRH`t+#JWrm1*d`lG{^<6rUhE$5w&XO~$2XACQi@}8ukIp3^h
zxjj3RxxhBLZ)&$v6z2<@eOXa3%X^Z_OLf}@-^Pmv4j)L#pW}PXNYsM$#ha4pDxQ~u
z4#*u?df@esxBVx-l{;N$uATF3l8R^HDu!u{-`Mk5>^`gAbeWXia5a_*)C#&Z?Zd_&
z4-d>eP<~Hh_K8o58=AdAMS{#N=4@tl27V^{D(4)fv)>OSI<QY?^_;ZiO&0qaMw#gA
z3_JgB?X<njdHbOLi%$xklcw0_HiR}TZm56AS8(jl6sZSN3+A700o^djqguoK#Xn(^
z`MzT&C+;37(i5Ge;(2oe%Leg>0$0}Wy=l7aq7BoUr;`*tCr!z_+pxCbbHnyMCry`m
zMrW*le+eY&m&>_7Yd((+>zPk%*Jr3bwLh>-4|M0|%gquGO?N~$a^AZkb$N|Vt}^Jl
zP`$Se4-ZHlsBetQ&+5%Ad&ge)v`EQw(iA>#hW)I0>}plU**@Lp1$S{p+*5U(q@sCK
ztKn+n<%aOR6HS+eRtj4Py?A;Fq&_CLVQr&!fp<=F)NJvFz?RM1K&A(HGwf%7r@H6d
z<K8ufy62a-<iBp)vBhJOit6>Q1DXd;?@(+qTzhu=0oRsZH?5dBP+DEi6d^6aT=Rx^
zjp5pJ-w!-J;MTGkRBTT%c-zq1*xk7C-T|r0uWFcM*mA<m_k%1kn9DI+DTce}JKMDx
zO*O(Ld>iyG98-0hq@r1A#cVBfj{Vm~>4@a0x#1l5Z>)Xt3FKNISx*0^yiJ@&%M{v|
z{^Pb_c<~q_{<cxD<@!UlO5tpu)t@8_I1Pkeyn@K&a_)|ZZM@GSd3n|uCOLJPDZA!)
zcdK{?ZCcA0<6v?B$n41EsA>HiyLIxIOUffBs(5;BV?5w_p!(hksmqIe*#2?K@PzDI
z0`hvie?t9(%>1<8%(67*^9+j{OF!g*+PNVw7;@O}aGv?H?Ana9r@jwr4yAGIV^jB>
zG(~B((7yB;4}8}e`kre)@btjC1B>*OC#iV8yu@uGQgK!~I(gO}*>9x>?j4u}iRsI1
zH+Xi)#&;U0)%}#&A$OyF!^RF3&q+a93I$PjdFPq$I`-uJ@s`7_-&f8y29+Ee`3|ga
zJl+tMU)GyBp}g^Q!`;R@JxNf)Ghna~mUzy)-mo}`caPHz);#w+ERK^@G=pz3MKgbA
zHof;p>Tt;e&Icuj%8T=wbv-9daqMPRf3)54SP%0%wmzn7N_&j7JSQ#bxh1fJdB)q`
z4V@<M8N(U(vra4XoS@=)YM<VLe+Q!P@ytG9H1)%;+w&VH9yp}OK1s#%;|up2Dv5i{
zkEu<nVY|chhcSXR<GGQ7=OmH&TRGWR{EC`$vM7z|KjS&YH~+S^1cMsRac>)K8>a6G
zG?P3#{eV5kZ22|JB_+4KC#hsA9?C0B-kWG9dCKI0WCG6yVYxbxqju`JT4)q?nV(l<
z{>iX|(Sjvn>W3qsn`*NXSRc6ku{*KEd~!p3!{r9u!sq6o8(t5x9bmraGkZ#^*axlx
z&JE@pbOIiN3Z$UmEs8bv58XJ`bboeic>6W6<u0GKWv{B|q$@FR8~--&?>%V7d9LEY
z{R0^Z+%;c)C#iU@y&`Bap<u@n^E+yuGx==T=dizF3$cn-^_&!<F}J~9=v?H-XSb(V
zUp?^pK<I&g2fQ4tm#<XuoW!-3yMX1xR`Z8#pX$CBYZs_&(7SMTr6%ao<X3Dm%srpe
z?o6?`&+wf|opCnv-Z_1sw#C$S2MP~-zc*vHP>Rq8jt}Vx)eGi>OZcZ31T92<T$^1I
zyu^ojo@!3j25SR}^S?oL(9EsO-&pOwx7`&nu$L{X%8ae$Wxi!~7nI*bKwC$C-`g`g
zY#Cbx_YN@&mWbvLM?m$0*OIlMlEHjS-tp~=8@_T#7l5kw&h2&&A9&@z@(nf?+re%j
zc!Q_BX0nQB5SOm=jbk^YYmC?XFvu~TW7x*}%c2xyL0UJ{bcU<<-pt-<BwE2{!T!TE
z;AIKOQDG%)ehg~WkMkRD9{AsIy5auAzI;&iyTa^1+yQYj#=z&!57HhOB+T8#76}sH
z(#zq`n8Wet)b|5_4`?3Xxbwwfl8WcVl}zt88+IreH;OmxXWY%$tW)nfN#*D&>4LPo
zzMIZEnSIuLxM%+12Gfrlf;}gxaB}#w@7t7kA|#FBJX1RJZRYOiXP~A>tu}-IO`8;@
z#|^t17B_5d;F|_6rtUi(aIKgZFw0nMN8^UKUoTDDqT)Hpq&~NSnZvsCX2_EF4=(@a
zxc^@#T@!q(@Mf+Ln|fVeZ9A|}>;~KUe-l+aCq*rhF3{U2H+@=-d&S&B<^^k?YI{yn
z*?Pz9fVi1t=XsL{VhP#{_NIab{o)VxC7Vf~JQsW*u4Q=zs3jM*Qnx_E;AWcg#-Cz8
zxZm-BT128(PVLBa3JT`7VR_TA{)p!!6;IZyoga=I^c9{oUA|%e!^`0NxHYaZ-P`)n
zBjz3(-=X|wP*ZTx3!WavtQ<R`sqBruy8fUBL&Y`5dz*iH_@psiXE+@_3ltO|OW4jG
zT<+v~(&Yh9LLv07=Z6Q_%@jLNL?nn@xVs5-Ids=*;R3nD+i9~WetPEo;JbtSX;7<0
zYoBQ2_8gZ}^UND!Iot1n+Fe?k%v!=XrQPb8V!B?4FKF!s6;S)_(hGK*Jma8idw6n^
zK~<N^)NAWGt*76dGDTgVF*>RZ<dDp-40&4=HD9kTyd41+c=?y>$C+hIbSk-TaK`se
z23=9TPPafxZc|j>9{x9eH}-%=J%T!Q8Eq1igFe-GTDY&6tEvHNu^&%6U@?30q%@lX
zk%tqaK_QlUf$xWKKz4J`ravAPx`m9V{Xv;){=Ng3%`{X`=R8nK2=oREt=DaMpBv;g
z&ALJBv>!;#`mzJ@A4GQsJ@riBg^27w+K`?T<TYt~<HTumKxv*Qn>jf*q-$P&BXc2l
zE@<S$kdGzp<{A;x%bdHv?kol?5}4bNofFnIE9wE;g85I?JSVBB9-nmJw3&|U+2R9P
z(`JDT(vfDoe{+L~Zal+oW>Kin;)X2HLBCQ3S{IHQfdXODQsaWvzTOv$v>%$ffc(a}
z+2X?@U+=(AMh16;z$!9RA9zboZ+b5MV7r4f^d|AQjVsOcS<m`B@L90?Dfsg7>mOT;
z3v!aUrdKyQP6OSFJtan#lfCiQ0TDfUhUkbWP^4`7swTshB^*4%N6{wpbw(!0zLVQ*
zKCJZhIanlp;rb>}s-2Xt{D6J-jHV~D3C`Z2MBvqaw=vSph_%x8UB-gFsvz5z9yZ)D
zIYzO_dY>F9Q7?6qe&8fMGwiu-g79gOp<eyx4#b)nuRT@rK;@1tDCE7S#vRyfX0rCw
z{)R?yH)o0-b3=J<M%0}1jc;|8LBU)b#<p+c%FMtt=6cp$k>D%Wf34|G=h<p<o>?1u
zA$u>wvYR(dtc4qyId*>p+q7`*#{*ZVJxNOlJnasuK-b@AG&M6nd&>R5vT1#wXvlNF
zdB>#sa*Mt2xpa{KrX(%D{lG-~JmcwT$i?rW4B|H)m{{5~us>V|?##W~%Dis-$;_g6
zOur()N`7r+|Cc!V@{$_XocxoZg7oGE&K>97()X=o)ngUgkOIn|IWKr@QZ^gk-^0Bo
zdnZ`UMbU~gY3cK3y51;UzxXMr^O?F@vg%M<`n*cP?Uz7Nl+&hkI^==Jg0)M*vfknk
z3TMxA`z&E_!U$CSY+5e-p~Khzo)1%9dMDV(D~vntA5+hNca%8{lo8Klao@>&d|BZ>
z^X^DFPz0BSGF%5OTzPvyX<9qT^SR<T{#-e2e&8Eud~(v1+T}MGuAc5a-~{FVzRhs<
zWJE$XWE}9YnZwpz0n0<*gKc%eLxy~-nS*m%B)D@@EkV|QjOf~s+2G$=qXp`%xh|Fd
z;P#~V!u20(LH%Trxm*w4otV9Fb|JeZC^o&+-S2SpGM8;&0fml5F3S~{TRe9;zifl>
zb=~I7*6?BZRstG@Te9P>c%tzafeY6cP6xH^x0R>#UI=-RaEMI^6k|%)dUwQ4oz1!C
z6=)32lgXlY$2>mSw-Z3ccGHKFj3Sq_7aluEx5rLW@f14Hcx3DB82fh6n879gxV{yN
zx2`?}1@@Q8u8p@mW-XMK%>yNz{af5s&R$sVzz-TY^Sq=#SJu%ugm=x`0FbG(Zrci)
zxTss60a^d4QuFcI3zK&o1vR9Xxb2ztFfGI8!gWQEp;u;@8{HAeef|NIQD#j)Zgh($
z_7!MM%5&EI*+w^b_VSgKWq@+b+4G!|*==<Ut7O7Jw)<`jJSMg1t!xmOb5(Z6%!z3)
za@s*Ho}l8pvm4W1FfLf@tO+XRch*h*l=dPv!Lc1wu?KmVD9R+wI+m89WN<?fRG43p
zTE2XP<SfQD&o6)s%UbK&C?9-<=PHA>RSwAcT&lk5LVpiF1hGRr<~H;PU*M5_9sp9S
z)mGZ@ipAVn-NFSV+x7B)P8%p{kFMe^2yc>Fn3Yi9?g~m*D@z#Td>o8TSZ|zq2#V~G
zEN-Ur(>F@~Vu?7K2o})0+o*o(0?*yh>k~jG2SsjW*V7DCHsSrTxV{J^;<;J>;p}-y
zrq29K&3}wRf$X))@qjUFUP~P7wlDsmI#iSQ7Q=7G$59tqt_scL*x3v!X_th&a<n+|
zRrOG$<LB(AWla2x?aY7wd<L0#s!Oj$cT+hdA7dY59~&RTHr8p3w|;{1xYnBg?Cw`p
WQmz@^?`L3OVDNPHb6Mw<&;$S+Xejgm

literal 57969
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
E0PydafB*mh

diff --git a/packages/Catch2/artwork/catch2-logo-small.png b/packages/Catch2/artwork/catch2-logo-small.png
index f2118bee09cf296a9f0598980f5a7c94b8e9f077..742e81e15ce43f13b1c0fd0f4b3225e76b624382 100644
GIT binary patch
literal 20939
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
U!nSfSFfcH9y85}Sb4q9e0Kwx(5&!@I

literal 29025
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%0A|pipmqtBA-fs=)7S%-8gZr*H%8>$NUFNw(`7U
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%0AI6&Y@*ro#=LwNjI+Ug#bDVAVONucYnT^mgw<
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
DtfXey

diff --git a/packages/Catch2/conanfile.py b/packages/Catch2/conanfile.py
index a7cebb922..8d407bafd 100644
--- a/packages/Catch2/conanfile.py
+++ b/packages/Catch2/conanfile.py
@@ -18,7 +18,7 @@ class CatchConan(ConanFile):
         cmake.definitions["BUILD_TESTING"] = "OFF"
         cmake.definitions["CATCH_INSTALL_DOCS"] = "OFF"
         cmake.definitions["CATCH_INSTALL_HELPERS"] = "ON"
-        cmake.configure()
+        cmake.configure(build_folder='build')
         cmake.install()
 
         self.copy(pattern="LICENSE.txt", dst="licenses")
diff --git a/packages/Catch2/contrib/CatchAddTests.cmake b/packages/Catch2/contrib/CatchAddTests.cmake
index 2220ce3ac..156d55ffe 100644
--- a/packages/Catch2/contrib/CatchAddTests.cmake
+++ b/packages/Catch2/contrib/CatchAddTests.cmake
@@ -51,8 +51,11 @@ string(REPLACE "\n" ";" output "${output}")
 # Parse output
 foreach(line ${output})
   set(test ${line})
-  # use escape commas to handle properly test cases with commans inside the name
-  string(REPLACE "," "\\," test_name ${test})
+  # Escape characters in test case names that would be parsed by Catch2
+  set(test_name ${test})
+  foreach(char , [ ])
+    string(REPLACE ${char} "\\${char}" test_name ${test_name})
+  endforeach(char)
   # ...and add to script
   add_command(add_test
     "${prefix}${test}${suffix}"
diff --git a/packages/Catch2/contrib/ParseAndAddCatchTests.cmake b/packages/Catch2/contrib/ParseAndAddCatchTests.cmake
index dac1dc926..925d93281 100644
--- a/packages/Catch2/contrib/ParseAndAddCatchTests.cmake
+++ b/packages/Catch2/contrib/ParseAndAddCatchTests.cmake
@@ -88,6 +88,11 @@ endfunction()
 
 # Worker function
 function(ParseAndAddCatchTests_ParseFile SourceFile TestTarget)
+    # If SourceFile is an object library, do not scan it (as it is not a file). Exit without giving a warning about a missing file.
+    if(SourceFile MATCHES "\\\$<TARGET_OBJECTS:.+>")
+        ParseAndAddCatchTests_PrintDebugMessage("Detected OBJECT library: ${SourceFile} this will not be scanned for tests.")
+        return()
+    endif()
     # According to CMake docs EXISTS behavior is well-defined only for full paths.
     get_filename_component(SourceFile ${SourceFile} ABSOLUTE)
     if(NOT EXISTS ${SourceFile})
diff --git a/packages/Catch2/docs/Readme.md b/packages/Catch2/docs/Readme.md
index 721880ab7..582540f4e 100644
--- a/packages/Catch2/docs/Readme.md
+++ b/packages/Catch2/docs/Readme.md
@@ -14,6 +14,7 @@ Writing tests:
 * [Event Listeners](event-listeners.md#top)
 * [Data Generators](generators.md#top)
 * [Other macros](other-macros.md#top)
+* [Micro benchmarking](benchmarks.md#top)
 
 Fine tuning:
 * [Supplying your own main()](own-main.md#top)
diff --git a/packages/Catch2/docs/assertions.md b/packages/Catch2/docs/assertions.md
index 07d2484e7..682eb6e7c 100644
--- a/packages/Catch2/docs/assertions.md
+++ b/packages/Catch2/docs/assertions.md
@@ -136,7 +136,7 @@ REQUIRE_THROWS_WITH( dismantleHal(), "My mind is going" );
 * **REQUIRE_THROWS_MATCHES(** _expression_, _exception type_, _matcher for given exception type_ **)** and
 * **CHECK_THROWS_MATCHES(** _expression_, _exception type_, _matcher for given exception type_ **)**
 
-Expects that exception of _exception type_ is thrown and it matches provided matcher (see next section for Matchers).
+Expects that exception of _exception type_ is thrown and it matches provided matcher (see the [documentation for Matchers](matchers.md#top)).
 
 
 _Please note that the `THROW` family of assertions expects to be passed a single expression, not a statement or series of statements. If you want to check a more complicated sequence of operations, you can use a C++11 lambda function._
diff --git a/packages/Catch2/docs/benchmarks.md b/packages/Catch2/docs/benchmarks.md
new file mode 100644
index 000000000..295bba300
--- /dev/null
+++ b/packages/Catch2/docs/benchmarks.md
@@ -0,0 +1,256 @@
+<a id="top"></a>
+# Authoring benchmarks
+
+> [Introduced](https://github.com/catchorg/Catch2/issues/1616) in Catch 2.9.0.
+
+_Note that benchmarking support is disabled by default and to enable it,
+you need to define `CATCH_CONFIG_ENABLE_BENCHMARKING`. For more details,
+see the [compile-time configuration documentation](configuration.md#top)._
+
+Writing benchmarks is not easy. Catch simplifies certain aspects but you'll
+always need to take care about various aspects. Understanding a few things about
+the way Catch runs your code will be very helpful when writing your benchmarks.
+
+First off, let's go over some terminology that will be used throughout this
+guide.
+
+- *User code*: user code is the code that the user provides to be measured.
+- *Run*: one run is one execution of the user code.
+- *Sample*: one sample is one data point obtained by measuring the time it takes
+  to perform a certain number of runs. One sample can consist of more than one
+  run if the clock available does not have enough resolution to accurately
+  measure a single run. All samples for a given benchmark execution are obtained
+  with the same number of runs.
+
+## Execution procedure
+
+Now I can explain how a benchmark is executed in Catch. There are three main
+steps, though the first does not need to be repeated for every benchmark.
+
+1. *Environmental probe*: before any benchmarks can be executed, the clock's
+resolution is estimated. A few other environmental artifacts are also estimated
+at this point, like the cost of calling the clock function, but they almost
+never have any impact in the results.
+
+2. *Estimation*: the user code is executed a few times to obtain an estimate of
+the amount of runs that should be in each sample. This also has the potential
+effect of bringing relevant code and data into the caches before the actual
+measurement starts.
+
+3. *Measurement*: all the samples are collected sequentially by performing the
+number of runs estimated in the previous step for each sample.
+
+This already gives us one important rule for writing benchmarks for Catch: the
+benchmarks must be repeatable. The user code will be executed several times, and
+the number of times it will be executed during the estimation step cannot be
+known beforehand since it depends on the time it takes to execute the code.
+User code that cannot be executed repeatedly will lead to bogus results or
+crashes.
+
+## Benchmark specification
+
+Benchmarks can be specified anywhere inside a Catch test case.
+There is a simple and a slightly more advanced version of the `BENCHMARK` macro.
+
+Let's have a look how a naive Fibonacci implementation could be benchmarked:
+```c++
+std::uint64_t Fibonacci(std::uint64_t number) {
+    return number < 2 ? 1 : Fibonacci(number - 1) + Fibonacci(number - 2);
+}
+```
+Now the most straight forward way to benchmark this function, is just adding a `BENCHMARK` macro to our test case:
+```c++
+TEST_CASE("Fibonacci") {
+    CHECK(Fibonacci(0) == 1);
+    // some more asserts..
+    CHECK(Fibonacci(5) == 8);
+    // some more asserts..
+
+    // now let's benchmark:
+    BENCHMARK("Fibonacci 20") {
+        return Fibonacci(20);
+    };
+
+    BENCHMARK("Fibonacci 25") {
+        return Fibonacci(25);
+    };
+
+    BENCHMARK("Fibonacci 30") {
+        return Fibonacci(30);
+    };
+
+    BENCHMARK("Fibonacci 35") {
+        return Fibonacci(35);
+    };
+}
+```
+There's a few things to note:
+- As `BENCHMARK` expands to a lambda expression it is necessary to add a semicolon after
+ the closing brace (as opposed to the first experimental version).
+- The `return` is a handy way to avoid the compiler optimizing away the benchmark code.
+
+Running this already runs the benchmarks and outputs something similar to:
+```
+-------------------------------------------------------------------------------
+Fibonacci
+-------------------------------------------------------------------------------
+C:\path\to\Catch2\Benchmark.tests.cpp(10)
+...............................................................................
+benchmark name                                  samples       iterations    estimated
+                                                mean          low mean      high mean
+                                                std dev       low std dev   high std dev
+-------------------------------------------------------------------------------
+Fibonacci 20                                            100       416439   83.2878 ms
+                                                       2 ns         2 ns         2 ns
+                                                       0 ns         0 ns         0 ns
+
+Fibonacci 25                                            100       400776   80.1552 ms
+                                                       3 ns         3 ns         3 ns
+                                                       0 ns         0 ns         0 ns
+
+Fibonacci 30                                            100       396873   79.3746 ms
+                                                      17 ns        17 ns        17 ns
+                                                       0 ns         0 ns         0 ns
+
+Fibonacci 35                                            100       145169   87.1014 ms
+                                                     468 ns       464 ns       473 ns
+                                                      21 ns        15 ns        34 ns
+```
+
+### Advanced benchmarking
+The simplest use case shown above, takes no arguments and just runs the user code that needs to be measured.
+However, if using the `BENCHMARK_ADVANCED` macro and adding a `Catch::Benchmark::Chronometer` argument after
+the macro, some advanced features are available. The contents of the simple benchmarks are invoked once per run,
+while the blocks of the advanced benchmarks are invoked exactly twice:
+once during the estimation phase, and another time during the execution phase.
+
+```c++
+BENCHMARK("simple"){ return long_computation(); };
+
+BENCHMARK_ADVANCED("advanced")(Catch::Benchmark::Chronometer meter) {
+    set_up();
+    meter.measure([] { return long_computation(); });
+};
+```
+
+These advanced benchmarks no longer consist entirely of user code to be measured.
+In these cases, the code to be measured is provided via the
+`Catch::Benchmark::Chronometer::measure` member function. This allows you to set up any
+kind of state that might be required for the benchmark but is not to be included
+in the measurements, like making a vector of random integers to feed to a
+sorting algorithm.
+
+A single call to `Catch::Benchmark::Chronometer::measure` performs the actual measurements
+by invoking the callable object passed in as many times as necessary. Anything
+that needs to be done outside the measurement can be done outside the call to
+`measure`.
+
+The callable object passed in to `measure` can optionally accept an `int`
+parameter.
+
+```c++
+meter.measure([](int i) { return long_computation(i); });
+```
+
+If it accepts an `int` parameter, the sequence number of each run will be passed
+in, starting with 0. This is useful if you want to measure some mutating code,
+for example. The number of runs can be known beforehand by calling
+`Catch::Benchmark::Chronometer::runs`; with this one can set up a different instance to be
+mutated by each run.
+
+```c++
+std::vector<std::string> v(meter.runs());
+std::fill(v.begin(), v.end(), test_string());
+meter.measure([&v](int i) { in_place_escape(v[i]); });
+```
+
+Note that it is not possible to simply use the same instance for different runs
+and resetting it between each run since that would pollute the measurements with
+the resetting code.
+
+It is also possible to just provide an argument name to the simple `BENCHMARK` macro to get 
+the same semantics as providing a callable to `meter.measure` with `int` argument:
+
+```c++
+BENCHMARK("indexed", i){ return long_computation(i); };
+```
+
+### Constructors and destructors
+
+All of these tools give you a lot mileage, but there are two things that still
+need special handling: constructors and destructors. The problem is that if you
+use automatic objects they get destroyed by the end of the scope, so you end up
+measuring the time for construction and destruction together. And if you use
+dynamic allocation instead, you end up including the time to allocate memory in
+the measurements.
+
+To solve this conundrum, Catch provides class templates that let you manually
+construct and destroy objects without dynamic allocation and in a way that lets
+you measure construction and destruction separately.
+
+```c++
+BENCHMARK_ADVANCED("construct")(Catch::Benchmark::Chronometer meter)
+{
+    std::vector<Catch::Benchmark::storage_for<std::string>> storage(meter.runs());
+    meter.measure([&](int i) { storage[i].construct("thing"); });
+})
+
+BENCHMARK_ADVANCED("destroy", [](Catch::Benchmark::Chronometer meter)
+{
+    std::vector<Catch::Benchmark::destructable_object<std::string>> storage(meter.runs());
+    for(auto&& o : storage)
+        o.construct("thing");
+    meter.measure([&](int i) { storage[i].destruct(); });
+})
+```
+
+`Catch::Benchmark::storage_for<T>` objects are just pieces of raw storage suitable for `T`
+objects. You can use the `Catch::Benchmark::storage_for::construct` member function to call a constructor and
+create an object in that storage. So if you want to measure the time it takes
+for a certain constructor to run, you can just measure the time it takes to run
+this function.
+
+When the lifetime of a `Catch::Benchmark::storage_for<T>` object ends, if an actual object was
+constructed there it will be automatically destroyed, so nothing leaks.
+
+If you want to measure a destructor, though, we need to use
+`Catch::Benchmark::destructable_object<T>`. These objects are similar to
+`Catch::Benchmark::storage_for<T>` in that construction of the `T` object is manual, but
+it does not destroy anything automatically. Instead, you are required to call
+the `Catch::Benchmark::destructable_object::destruct` member function, which is what you
+can use to measure the destruction time.
+
+### The optimizer
+
+Sometimes the optimizer will optimize away the very code that you want to
+measure. There are several ways to use results that will prevent the optimiser
+from removing them. You can use the `volatile` keyword, or you can output the
+value to standard output or to a file, both of which force the program to
+actually generate the value somehow.
+
+Catch adds a third option. The values returned by any function provided as user
+code are guaranteed to be evaluated and not optimised out. This means that if
+your user code consists of computing a certain value, you don't need to bother
+with using `volatile` or forcing output. Just `return` it from the function.
+That helps with keeping the code in a natural fashion.
+
+Here's an example:
+
+```c++
+// may measure nothing at all by skipping the long calculation since its
+// result is not used
+BENCHMARK("no return"){ long_calculation(); };
+
+// the result of long_calculation() is guaranteed to be computed somehow
+BENCHMARK("with return"){ return long_calculation(); };
+```
+
+However, there's no other form of control over the optimizer whatsoever. It is
+up to you to write a benchmark that actually measures what you want and doesn't
+just measure the time to do a whole bunch of nothing.
+
+To sum up, there are two simple rules: whatever you would do in handwritten code
+to control optimization still works in Catch; and Catch makes return values
+from user code into observable effects that can't be optimized away.
+
+<i>Adapted from nonius' documentation.</i>
diff --git a/packages/Catch2/docs/command-line.md b/packages/Catch2/docs/command-line.md
index f68c84ca8..d204da0e5 100644
--- a/packages/Catch2/docs/command-line.md
+++ b/packages/Catch2/docs/command-line.md
@@ -20,7 +20,10 @@
 [Specify a seed for the Random Number Generator](#specify-a-seed-for-the-random-number-generator)<br>
 [Identify framework and version according to the libIdentify standard](#identify-framework-and-version-according-to-the-libidentify-standard)<br>
 [Wait for key before continuing](#wait-for-key-before-continuing)<br>
-[Specify multiples of clock resolution to run benchmarks for](#specify-multiples-of-clock-resolution-to-run-benchmarks-for)<br>
+[Specify the number of benchmark samples to collect](#specify-the-number-of-benchmark-samples-to-collect)<br>
+[Specify the number of resamples for bootstrapping](#specify-the-number-of-resamples-for-bootstrapping)<br>
+[Specify the confidence-interval for bootstrapping](#specify-the-confidence-interval-for-bootstrapping)<br>
+[Disable statistical analysis of collected benchmark samples](#disable-statistical-analysis-of-collected-benchmark-samples)<br>
 [Usage](#usage)<br>
 [Specify the section to run](#specify-the-section-to-run)<br>
 [Filenames as tags](#filenames-as-tags)<br>
@@ -57,7 +60,10 @@ Click one of the following links to take you straight to that option - or scroll
 <a href="#rng-seed">                                    `    --rng-seed`</a><br />
 <a href="#libidentify">                                 `    --libidentify`</a><br />
 <a href="#wait-for-keypress">                           `    --wait-for-keypress`</a><br />
-<a href="#benchmark-resolution-multiple">               `    --benchmark-resolution-multiple`</a><br />
+<a href="#benchmark-samples">                           `    --benchmark-samples`</a><br />
+<a href="#benchmark-resamples">                         `    --benchmark-resamples`</a><br />
+<a href="#benchmark-confidence-interval">               `    --benchmark-confidence-interval`</a><br />
+<a href="#benchmark-no-analysis">                       `    --benchmark-no-analysis`</a><br />
 <a href="#use-colour">                                  `    --use-colour`</a><br />
 
 </br>
@@ -236,7 +242,7 @@ Test cases are ordered one of three ways:
 
 
 ### decl
-Declaration order. The order the tests were originally declared in. Note that ordering between files is not guaranteed and is implementation dependent.
+Declaration order (this is the default order if no --order argument is provided). The order the tests were originally declared in. Note that ordering between files is not guaranteed and is implementation dependent.
 
 ### lex
 Lexicographically sorted. Tests are sorted, alpha-numerically, by name.
@@ -250,7 +256,7 @@ Randomly sorted. Test names are sorted using ```std::random_shuffle()```. By def
 
 Sets a seed for the random number generator using ```std::srand()```. 
 If a number is provided this is used directly as the seed so the random pattern is repeatable.
-Alternatively if the keyword ```time``` is provided then the result of calling ```std::time(0)``` is used and so the pattern becomes unpredictable.
+Alternatively if the keyword ```time``` is provided then the result of calling ```std::time(0)``` is used and so the pattern becomes unpredictable. In some cases, you might need to pass the keyword ```time``` in double quotes instead of single quotes.
 
 In either case the actual value for the seed is printed as part of Catch's output so if an issue is discovered that is sensitive to test ordering the ordering can be reproduced - even if it was originally seeded from ```std::time(0)```.
 
@@ -267,13 +273,48 @@ See [The LibIdentify repo for more information and examples](https://github.com/
 Will cause the executable to print a message and wait until the return/ enter key is pressed before continuing -
 either before running any tests, after running all tests - or both, depending on the argument.
 
-<a id="benchmark-resolution-multiple"></a>
-## Specify multiples of clock resolution to run benchmarks for
-<pre>--benchmark-resolution-multiple &lt;multiplier&gt;</pre>
+<a id="benchmark-samples"></a>
+## Specify the number of benchmark samples to collect
+<pre>--benchmark-samples &lt;# of samples&gt;</pre>
 
-When running benchmarks the clock resolution is estimated. Benchmarks are then run for exponentially increasing
-numbers of iterations until some multiple of the estimated resolution is exceed. By default that multiple is 100, but 
-it can be overridden here.
+> [Introduced](https://github.com/catchorg/Catch2/issues/1616) in Catch 2.9.0.
+
+When running benchmarks a number of "samples" is collected. This is the base data for later statistical analysis.
+Per sample a clock resolution dependent number of iterations of the user code is run, which is independent of the number of samples. Defaults to 100.
+
+<a id="benchmark-resamples"></a>
+## Specify the number of resamples for bootstrapping
+<pre>--benchmark-resamples &lt;# of resamples&gt;</pre>
+
+> [Introduced](https://github.com/catchorg/Catch2/issues/1616) in Catch 2.9.0.
+
+After the measurements are performed, statistical [bootstrapping] is performed
+on the samples. The number of resamples for that bootstrapping is configurable
+but defaults to 100000. Due to the bootstrapping it is possible to give
+estimates for the mean and standard deviation. The estimates come with a lower
+bound and an upper bound, and the confidence interval (which is configurable but
+defaults to 95%).
+
+ [bootstrapping]: http://en.wikipedia.org/wiki/Bootstrapping_%28statistics%29
+
+<a id="benchmark-confidence-interval"></a>
+## Specify the confidence-interval for bootstrapping
+<pre>--benchmark-confidence-interval &lt;confidence-interval&gt;</pre>
+
+> [Introduced](https://github.com/catchorg/Catch2/issues/1616) in Catch 2.9.0.
+
+The confidence-interval is used for statistical bootstrapping on the samples to
+calculate the upper and lower bounds of mean and standard deviation.
+Must be between 0 and 1 and defaults to 0.95.
+
+<a id="benchmark-no-analysis"></a>
+## Disable statistical analysis of collected benchmark samples
+<pre>--benchmark-no-analysis</pre>
+
+> [Introduced](https://github.com/catchorg/Catch2/issues/1616) in Catch 2.9.0.
+
+When this flag is specified no bootstrapping or any other statistical analysis is performed.
+Instead the user code is only measured and the plain mean from the samples is reported.
 
 <a id="usage"></a>
 ## Usage
diff --git a/packages/Catch2/docs/commercial-users.md b/packages/Catch2/docs/commercial-users.md
index 4f98f759f..2b17e0c39 100644
--- a/packages/Catch2/docs/commercial-users.md
+++ b/packages/Catch2/docs/commercial-users.md
@@ -17,3 +17,4 @@ fact then please let us know - either directly, via a PR or
  - NASA
  - [Inscopix Inc.](https://www.inscopix.com/)
  - [Makimo](https://makimo.pl/)
+ - [UX3D] (https://ux3d.io)
diff --git a/packages/Catch2/docs/configuration.md b/packages/Catch2/docs/configuration.md
index c01d7f5e6..599bb9ae4 100644
--- a/packages/Catch2/docs/configuration.md
+++ b/packages/Catch2/docs/configuration.md
@@ -127,8 +127,12 @@ 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_CONFIG_CPP17_STRING_VIEW          // Override std::string_view support detection(Catch provides a StringMaker specialization by default)
+    CATCH_CONFIG_CPP17_VARIANT              // Override std::variant support detection (checked by CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER)
+    CATCH_CONFIG_CPP17_OPTIONAL             // Override std::optional support detection (checked by CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER)
+    CATCH_CONFIG_CPP17_BYTE                 // Override std::byte support detection (Catch provides a StringMaker specialization by default)
+
+> `CATCH_CONFIG_CPP17_STRING_VIEW` was [introduced](https://github.com/catchorg/Catch2/issues/1376) in Catch 2.4.1.
 
 Catch contains basic compiler/standard detection and attempts to use
 some C++17 features whenever appropriate. This automatic detection
@@ -149,6 +153,12 @@ by using `_NO_` in the macro, e.g. `CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS`.
     CATCH_CONFIG_DISABLE                    // Disables assertions and test case registration
     CATCH_CONFIG_WCHAR                      // Enables use of wchart_t
     CATCH_CONFIG_EXPERIMENTAL_REDIRECT      // Enables the new (experimental) way of capturing stdout/stderr
+    CATCH_CONFIG_ENABLE_BENCHMARKING        // Enables the integrated benchmarking features (has a significant effect on compilation speed)
+    CATCH_CONFIG_USE_ASYNC                  // Force parallel statistical processing of samples during benchmarking
+    CATCH_CONFIG_ANDROID_LOGWRITE           // Use android's logging system for debug output
+    CATCH_CONFIG_GLOBAL_NEXTAFTER           // Use nextafter{,f,l} instead of std::nextafter
+
+> [`CATCH_CONFIG_ANDROID_LOGWRITE`](https://github.com/catchorg/Catch2/issues/1743) and [`CATCH_CONFIG_GLOBAL_NEXTAFTER`](https://github.com/catchorg/Catch2/pull/1739) were introduced in Catch 2.10.0
 
 Currently Catch enables `CATCH_CONFIG_WINDOWS_SEH` only when compiled with MSVC, because some versions of MinGW do not have the necessary Win32 API support.
 
@@ -207,9 +217,14 @@ By default, Catch does not stringify some types from the standard library. This
     CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER // Provide StringMaker specialization for std::optional (on C++17)
     CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS     // Defines all of the above
 
+> `CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER` was [introduced](https://github.com/catchorg/Catch2/issues/1380) in Catch 2.4.1.
+
+> `CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER` was [introduced](https://github.com/catchorg/Catch2/issues/1510) in Catch 2.6.0.
 
 ## Disabling exceptions
 
+> Introduced in Catch 2.4.0.
+
 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
diff --git a/packages/Catch2/docs/contributing.md b/packages/Catch2/docs/contributing.md
index 21bbad14c..5429bf9dc 100644
--- a/packages/Catch2/docs/contributing.md
+++ b/packages/Catch2/docs/contributing.md
@@ -1,6 +1,13 @@
 <a id="top"></a>
 # Contributing to Catch
 
+**Contents**<br>
+[Branches](#branches)<br>
+[Directory structure](#directory-structure)<br>
+[Testing your changes](#testing-your-changes)<br>
+[Documenting your code](#documenting-your-code)<br>
+[Code constructs to watch out for](#code-constructs-to-watch-out-for)<br>
+
 So you want to contribute something to Catch? That's great! Whether it's a bug fix, a new feature, support for
 additional compilers - or just a fix to the documentation - all contributions are very welcome and very much appreciated.
 Of course so are bug reports and other comments and questions.
@@ -63,6 +70,10 @@ locally takes just a few minutes.
 $ cd debug-build
 $ ctest -j 2 --output-on-failure
 ```
+__Note:__ When running your tests with multi-configuration generators like
+Visual Studio, you might get errors "Test not available without configuration."
+You then have to pick one configuration (e.g. ` -C Debug`) in the `ctest` call.
+
 If you added new tests, approval tests are very likely to fail. If they
 do not, it means that your changes weren't run as part of them. This
 _might_ be intentional, but usually is not.
@@ -75,8 +86,87 @@ before you do so, you need to check that the introduced changes are indeed
 intentional.
 
 
+## Documenting your code
+
+If you have added new feature to Catch2, it needs documentation, so that
+other people can use it as well. This section collects some technical
+information that you will need for updating Catch2's documentation, and
+possibly some generic advise as well.
+
+First, the technicalities:
+
+* We introduced version tags to the documentation, which show users in
+which version a specific feature was introduced. This means that newly
+written documentation should be tagged with a placeholder, that will
+be replaced with the actual version upon release. There are 2 styles
+of placeholders used through the documentation, you should pick one that
+fits your text better (if in doubt, take a look at the existing version
+tags for other features).
+  * `> [Introduced](link-to-issue-or-PR) in Catch X.Y.Z` - this
+  placeholder is usually used after a section heading
+  * `> X (Y and Z) was [introduced](link-to-issue-or-PR) in Catch X.Y.Z`
+  - this placeholder is used when you need to tag a subpart of something,
+  e.g. list
+* Crosslinks to different pages should target the `top` anchor, like this
+`[link to contributing](contributing.md#top)`.
+* If you have introduced a new document, there is a simple template you
+should use. It provides you with the top anchor mentioned above, and also
+with a backlink to the top of the documentation:
+```markdown
+<a id="top"></a>
+# Cool feature
+
+Text that explains how to use the cool feature.
+
+
+---
+
+[Home](Readme.md#top)
+```
+* For pages with more than 4 subheadings, we provide a table of contents
+(ToC) at the top of the page. Because GitHub markdown does not support
+automatic generation of ToC, it has to be handled semi-manually. Thus,
+if you've added a new subheading to some page, you should add it to the
+ToC. This can be done either manually, or by running the
+`updateDocumentToC.py` script in the `scripts/` folder.
+
+
+Now, for the generic tips:
+  * Usage examples are good
+  * Don't be afraid to introduce new pages
+  * Try to be reasonably consistent with the surrounding documentation
+
+
+
+
+## Code constructs to watch out for
+
+This section is a (sadly incomplete) listing of various constructs that
+are problematic and are not always caught by our CI infrastructure.
+
+### Naked exceptions and exceptions-related function
+
+If you are throwing an exception, it should be done via `CATCH_ERROR`
+or `CATCH_RUNTIME_ERROR` in `catch_enforce.h`. These macros will handle
+the differences between compilation with or without exceptions for you.
+However, some platforms (IAR) also have problems with exceptions-related
+functions, such as `std::current_exceptions`. We do not have IAR in our
+CI, but luckily there should not be too many reasons to use these.
+However, if you do, they should be kept behind a
+`CATCH_CONFIG_DISABLE_EXCEPTIONS` macro.
+
+### Unqualified usage of functions from C's stdlib
+
+If you are using a function from C's stdlib, please include the header
+as `<cfoo>` and call the function qualified. The common knowledge that
+there is no difference is wrong, QNX and VxWorks won't compile if you
+include the header as `<cfoo>` and call the function unqualified.
+
+
+----
 
- *this document is still in-progress...*
+_This documentation will always be in-progress as new information comes
+up, but we are trying to keep it as up to date as possible._
 
 ---
 
diff --git a/packages/Catch2/docs/deprecations.md b/packages/Catch2/docs/deprecations.md
index 0489e1ff8..77830298b 100644
--- a/packages/Catch2/docs/deprecations.md
+++ b/packages/Catch2/docs/deprecations.md
@@ -39,6 +39,11 @@ apart from writing it out for `--list-tests -v high`.
 Because it isn't actually used nor documented, and brings complications
 to Catch2's internals, description support will be removed.
 
+### SourceLineInfo::empty()
+
+There should be no reason to ever have an empty `SourceLineInfo`, so the
+method will be removed.
+
 
 ## Planned changes
 
diff --git a/packages/Catch2/docs/event-listeners.md b/packages/Catch2/docs/event-listeners.md
index c6625a2e0..623110066 100644
--- a/packages/Catch2/docs/event-listeners.md
+++ b/packages/Catch2/docs/event-listeners.md
@@ -29,13 +29,13 @@ struct MyListener : Catch::TestEventListenerBase {
 
     using TestEventListenerBase::TestEventListenerBase; // inherit constructor
 
-    virtual void testCaseStarting( Catch::TestCaseInfo const& testInfo ) override {
+    void testCaseStarting( Catch::TestCaseInfo const& testInfo ) override {
         // Perform some setup before a test case is run
     }
     
-    virtual void testCaseEnded( Catch::TestCaseStats const& testCaseStats ) override {
+    void testCaseEnded( Catch::TestCaseStats const& testCaseStats ) override {
         // Tear-down after a test case is run
-    }    
+    }
 };
 CATCH_REGISTER_LISTENER( MyListener )
 ```
diff --git a/packages/Catch2/docs/generators.md b/packages/Catch2/docs/generators.md
index 57fdf44bb..61276f3cc 100644
--- a/packages/Catch2/docs/generators.md
+++ b/packages/Catch2/docs/generators.md
@@ -1,6 +1,8 @@
 <a id="top"></a>
 # Data Generators
 
+> Introduced in Catch 2.6.0.
+
 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
@@ -34,8 +36,8 @@ Catch2's provided generator functionality consists of three parts,
 * `GENERATE` macro,  that serves to integrate generator expression with
 a test case,
 * 2 fundamental generators
-  * `ValueGenerator<T>` -- contains only single element
-  * `ValuesGenerator<T>` -- contains multiple elements
+  * `SingleValueGenerator<T>` -- contains only single element
+  * `FixedValuesGenerator<T>` -- contains multiple elements
 * 5 generic generators that modify other generators
   * `FilterGenerator<T, Predicate>` -- filters out elements from a generator
   for which the predicate returns "false"
@@ -44,16 +46,22 @@ a test case,
   * `MapGenerator<T, U, Func>` -- returns the result of applying `Func`
   on elements from a different generator
   * `ChunkGenerator<T>` -- returns chunks (inside `std::vector`) of n elements from a generator
-* 3 specific purpose generators
+* 4 specific purpose generators
   * `RandomIntegerGenerator<Integral>` -- generates random Integrals from range
   * `RandomFloatGenerator<Float>` -- generates random Floats from range
   * `RangeGenerator<T>` -- generates all values inside a specific range
+  * `IteratorGenerator<T>` -- copies and returns values from an iterator range
+
+> `ChunkGenerator<T>`, `RandomIntegerGenerator<Integral>`, `RandomFloatGenerator<Float>` and `RangeGenerator<T>` were introduced in Catch 2.7.0.
+
+> `IteratorGenerator<T>` was introduced in Catch 2.10.0.
 
 The generators also have associated helper functions that infer their
 type, making their usage much nicer. These are
 
-* `value(T&&)` for `ValueGenerator<T>`
-* `values(std::initializer_list<T>)` for `ValuesGenerator<T>`
+* `value(T&&)` for `SingleValueGenerator<T>`
+* `values(std::initializer_list<T>)` for `FixedValuesGenerator<T>`
+* `table<Ts...>(std::initializer_list<std::tuple<Ts...>>)` for `FixedValuesGenerator<std::tuple<Ts...>>`
 * `filter(predicate, GeneratorWrapper<T>&&)` for `FilterGenerator<T, Predicate>`
 * `take(count, GeneratorWrapper<T>&&)` for `TakeGenerator<T>`
 * `repeat(repeats, GeneratorWrapper<T>&&)` for `RepeatGenerator<T>`
@@ -63,7 +71,12 @@ type, making their usage much nicer. These are
 * `random(IntegerOrFloat a, IntegerOrFloat b)` for `RandomIntegerGenerator` or `RandomFloatGenerator`
 * `range(start, end)` for `RangeGenerator<T>` with a step size of `1`
 * `range(start, end, step)` for `RangeGenerator<T>` with a custom step size
+* `from_range(InputIterator from, InputIterator to)` for `IteratorGenerator<T>`
+* `from_range(Container const&)` for `IteratorGenerator<T>`
 
+> `chunk()`, `random()` and both `range()` functions were introduced in Catch 2.7.0.
+
+> `from_range` has been introduced in Catch 2.10.0
 
 And can be used as shown in the example below to create a generator
 that returns 100 odd random number:
@@ -84,7 +97,7 @@ Apart from registering generators with Catch2, the `GENERATE` macro has
 one more purpose, and that is to provide simple way of generating trivial
 generators, as seen in the first example on this page, where we used it
 as `auto i = GENERATE(1, 2, 3);`. This usage converted each of the three
-literals into a single `ValueGenerator<int>` and then placed them all in
+literals into a single `SingleValueGenerator<int>` and then placed them all in
 a special generator that concatenates other generators. It can also be
 used with other generators as arguments, such as `auto i = GENERATE(0, 2,
 take(100, random(300, 3000)));`. This is useful e.g. if you know that
@@ -96,6 +109,8 @@ scope and thus capturing references is dangerous. If you need to use
 variables inside the generator expression, make sure you thought through
 the lifetime implications and use `GENERATE_COPY` or `GENERATE_REF`.**
 
+> `GENERATE_COPY` and `GENERATE_REF` were introduced in Catch 2.7.1.
+
 You can also override the inferred type by using `as<type>` as the first
 argument to the macro. This can be useful when dealing with string literals,
 if you want them to come out as `std::string`:
diff --git a/packages/Catch2/docs/logging.md b/packages/Catch2/docs/logging.md
index 7b5c6c4b7..476b1e084 100644
--- a/packages/Catch2/docs/logging.md
+++ b/packages/Catch2/docs/logging.md
@@ -30,6 +30,8 @@ When the last `CHECK` fails in the "Bar" test case, then only one message will b
 
 ## Logging without local scope
 
+> [Introduced](https://github.com/catchorg/Catch2/issues/1522) in Catch 2.7.0.
+
 `UNSCOPED_INFO` is similar to `INFO` with two key differences:
 
 - Lifetime of an unscoped message is not tied to its own scope.
@@ -104,6 +106,8 @@ This semicolon will be removed with next major version. It is highly advised to
 
 **UNSCOPED_INFO(** _message expression_ **)**
 
+> [Introduced](https://github.com/catchorg/Catch2/issues/1522) in Catch 2.7.0.
+
 Similar to `INFO`, but messages are not limited to their own scope: They are removed from the buffer after each assertion, section or test case, whichever comes first.
 
 **WARN(** _message expression_ **)**
diff --git a/packages/Catch2/docs/matchers.md b/packages/Catch2/docs/matchers.md
index e3d936bd5..af2071e37 100644
--- a/packages/Catch2/docs/matchers.md
+++ b/packages/Catch2/docs/matchers.md
@@ -12,11 +12,11 @@ The first argument is the thing (object or value) under test. The second part is
 which consists of either a single matcher or one or more matchers combined using `&&`, `||` or `!` operators.
 
 For example, to assert that a string ends with a certain substring:
- 
+
  ```c++
 using Catch::Matchers::EndsWith; // or Catch::EndsWith
 std::string str = getStringFromSomewhere();
-REQUIRE_THAT( str, EndsWith( "as a service" ) ); 
+REQUIRE_THAT( str, EndsWith( "as a service" ) );
  ```
 
 The matcher objects can take multiple arguments, allowing more fine tuning.
@@ -24,19 +24,29 @@ The built-in string matchers, for example, take a second argument specifying whe
 case sensitive or not:
 
 ```c++
-REQUIRE_THAT( str, EndsWith( "as a service", Catch::CaseSensitive::No ) ); 
+REQUIRE_THAT( str, EndsWith( "as a service", Catch::CaseSensitive::No ) );
  ```
 
 And matchers can be combined:
 
 ```c++
-REQUIRE_THAT( str, 
-    EndsWith( "as a service" ) || 
-    (StartsWith( "Big data" ) && !Contains( "web scale" ) ) ); 
+REQUIRE_THAT( str,
+    EndsWith( "as a service" ) ||
+    (StartsWith( "Big data" ) && !Contains( "web scale" ) ) );
 ```
 
 ## Built in matchers
-Catch currently provides some matchers, they are in the `Catch::Matchers` and `Catch` namespaces.
+Catch2 provides some matchers by default. They can be found in the
+`Catch::Matchers::foo` namespace and are imported into the `Catch`
+namespace as well.
+
+There are two parts to each of the built-in matchers, the matcher
+type itself and a helper function that provides template argument
+deduction when creating templated matchers. As an example, the matcher
+for checking that two instances of `std::vector` are identical is
+`EqualsMatcher<T>`, but the user is expected to use the `Equals`
+helper function instead.
+
 
 ### String matchers
 The string matchers are `StartsWith`, `EndsWith`, `Contains`, `Equals` and `Matches`. The first four match a literal (sub)string against a result, while `Matches` takes and matches an ECMAScript regex. Do note that `Matches` matches the string as a whole, meaning that "abc" will not match against "abcd", but "abc.*" will.
@@ -45,13 +55,42 @@ Each of the provided `std::string` matchers also takes an optional second argume
 
 
 ### Vector matchers
-The vector matchers are `Contains`, `VectorContains` and `Equals`. `VectorContains` looks for a single element in the matched vector, `Contains` looks for a set (vector) of elements inside the matched vector.
+Catch2 currently provides 5 built-in matchers that work on `std::vector`.
+These are
 
-### Floating point matchers
-The floating point matchers are `WithinULP` and `WithinAbs`. `WithinAbs` accepts floating point numbers that are within a certain margin of target. `WithinULP` performs an [ULP](https://en.wikipedia.org/wiki/Unit_in_the_last_place)-based comparison of two floating point numbers and accepts them if they are less than certain number of ULPs apart.
+ * `Contains` which checks whether a specified vector is present in the result
+ * `VectorContains` which checks whether a specified element is present in the result
+ * `Equals` which checks whether the result is exactly equal (order matters) to a specific vector
+ * `UnorderedEquals` which checks whether the result is equal to a specific vector under a permutation
+ * `Approx` which checks whether the result is "approx-equal" (order matters, but comparison is done via `Approx`) to a specific vector
+> Approx matcher was [introduced](https://github.com/catchorg/Catch2/issues/1499) in Catch 2.7.2.
 
-Do note that ULP-based checks only make sense when both compared numbers are of the same type and `WithinULP` will use type of its argument as the target type. This means that `WithinULP(1.f, 1)` will expect to compare `float`s, but `WithinULP(1., 1)` will expect to compare `double`s.
 
+### Floating point matchers
+Catch2 provides 3 matchers for working with floating point numbers. These
+are `WithinAbsMatcher`, `WithinUlpsMatcher` and `WithinRelMatcher`.
+
+The `WithinAbsMatcher` matcher accepts floating point numbers that are
+within a certain distance of target. It should be constructed with the
+`WithinAbs(double target, double margin)` helper.
+
+The `WithinUlpsMatcher` matcher accepts floating point numbers that are
+within a certain number of [ULPs](https://en.wikipedia.org/wiki/Unit_in_the_last_place)
+of the target. Because ULP comparisons need to be done differently for
+`float`s and for `double`s, there are two overloads of the helpers for
+this matcher, `WithinULP(float target, int64_t ULPs)`, and
+`WithinULP(double target, int64_t ULPs)`.
+
+The `WithinRelMatcher` matcher accepts floating point numbers that are
+_approximately equal_ with the target number with some specific tolerance.
+In other words, it checks that `|lhs - rhs| <= epsilon * max(|lhs|, |rhs|)`,
+with special casing for `INFINITY` and `NaN`. There are _4_ overloads of
+the helpers for this matcher, `WithinRel(double target, double margin)`,
+`WithinRel(float target, float margin)`, `WithinRel(double target)`, and
+`WithinRel(float target)`. The latter two provide a default epsilon of
+machine epsilon * 100.
+
+> `WithinRel` matcher was introduced in Catch 2.10.0
 
 ### Generic matchers
 Catch also aims to provide a set of generic matchers. Currently this set
@@ -72,13 +111,29 @@ The second argument is an optional description of the predicate, and is
 used only during reporting of the result.
 
 
+### Exception matchers
+Catch2 also provides an exception matcher that can be used to verify
+that an exception's message exactly matches desired string. The matcher
+is `ExceptionMessageMatcher`, and we also provide a helper function
+`Message`.
+
+The matched exception must publicly derive from `std::exception` and
+the message matching is done _exactly_, including case.
+
+> `ExceptionMessageMatcher` was introduced in Catch 2.10.0
+
+Example use:
+```cpp
+REQUIRE_THROWS_MATCHES(throwsDerivedException(),  DerivedException,  Message("DerivedException::what"));
+```
+
 ## Custom matchers
 It's easy to provide your own matchers to extend Catch or just to work with your own types.
 
-You need to provide two things: 
+You need to provide two things:
 1. A matcher class, derived from `Catch::MatcherBase<T>` - where `T` is the type being tested.
 The constructor takes and stores any arguments needed (e.g. something to compare against) and you must
-override two methods: `match()` and `describe()`. 
+override two methods: `match()` and `describe()`.
 2. A simple builder function. This is what is actually called from the test code and allows overloading.
 
 Here's an example for asserting that an integer falls within a given range
@@ -92,7 +147,7 @@ public:
     IntRange( int begin, int end ) : m_begin( begin ), m_end( end ) {}
 
     // Performs the test for this matcher
-    virtual bool match( int const& i ) const override {
+    bool match( int const& i ) const override {
         return i >= m_begin && i <= m_end;
     }
 
@@ -123,7 +178,7 @@ TEST_CASE("Integers are within a range")
 ```
 
 Running this test gives the following in the console:
- 
+
 ```
 /**/TestFile.cpp:123: FAILED:
   CHECK_THAT( 100, IsBetween( 1, 10 ) )
diff --git a/packages/Catch2/docs/opensource-users.md b/packages/Catch2/docs/opensource-users.md
index 489bbdcc6..36c0db64f 100644
--- a/packages/Catch2/docs/opensource-users.md
+++ b/packages/Catch2/docs/opensource-users.md
@@ -23,6 +23,9 @@ C++11 implementation of Approval Tests, for quick, convenient testing of legacy
 ### [Azmq](https://github.com/zeromq/azmq)
 Boost Asio style bindings for ZeroMQ.
 
+### [Cataclysm: Dark Days Ahead](https://github.com/CleverRaven/Cataclysm-DDA)
+Post-apocalyptic survival RPG.
+
 ### [ChakraCore](https://github.com/Microsoft/ChakraCore)
 The core part of the Chakra JavaScript engine that powers Microsoft Edge.
 
@@ -50,9 +53,6 @@ Open source Oracle Tuxedo-like XATMI middleware for C and C++.
 ### [Inja](https://github.com/pantor/inja)
 A header-only template engine for modern C++.
 
-### [JSON for Modern C++](https://github.com/nlohmann/json)
-A, single-header, JSON parsing library that takes advantage of what C++ has to offer.
-
 ### [libcluon](https://github.com/chrberger/libcluon)
 A single-header-only library written in C++14 to glue distributed software components (UDP, TCP, shared memory) supporting natively Protobuf, LCM/ZCM, MsgPack, and JSON for dynamic message transformations in-between. 
 
@@ -112,6 +112,9 @@ SpECTRE is a code for multi-scale, multi-physics problems in astrophysics and gr
 ### [Standardese](https://github.com/foonathan/standardese)
 Standardese aims to be a nextgen Doxygen.
 
+### [PopHead](https://github.com/SPC-Some-Polish-Coders/PopHead)
+A 2D, Zombie, RPG game which is being made on our own engine.
+
 ---
 
 [Home](Readme.md#top)
diff --git a/packages/Catch2/docs/other-macros.md b/packages/Catch2/docs/other-macros.md
index 345234d55..994115f16 100644
--- a/packages/Catch2/docs/other-macros.md
+++ b/packages/Catch2/docs/other-macros.md
@@ -59,6 +59,8 @@ TEST_CASE( "SUCCEED showcase" ) {
 
 * `STATIC_REQUIRE`
 
+> [Introduced](https://github.com/catchorg/Catch2/issues/1362) in Catch 2.4.2.
+
 `STATIC_REQUIRE( expr )` is a macro that can be used the same way as a
 `static_assert`, but also registers the success with Catch2, so it is
 reported as a success at runtime. The whole check can also be deferred
@@ -132,6 +134,8 @@ ANON_TEST_CASE() {
 
 * `DYNAMIC_SECTION`
 
+> Introduced in Catch 2.3.0.
+
 `DYNAMIC_SECTION` is a `SECTION` where the user can use `operator<<` to
 create the final name for that section. This can be useful with e.g.
 generators, or when creating a `SECTION` dynamically, within a loop.
diff --git a/packages/Catch2/docs/release-notes.md b/packages/Catch2/docs/release-notes.md
index 528f6cf12..0af35c679 100644
--- a/packages/Catch2/docs/release-notes.md
+++ b/packages/Catch2/docs/release-notes.md
@@ -2,6 +2,12 @@
 
 # Release notes
 **Contents**<br>
+[2.10.0](#2100)<br>
+[2.9.2](#292)<br>
+[2.9.1](#291)<br>
+[2.9.0](#290)<br>
+[2.8.0](#280)<br>
+[2.7.2](#272)<br>
 [2.7.1](#271)<br>
 [2.7.0](#270)<br>
 [2.6.1](#261)<br>
@@ -22,11 +28,153 @@
 [Older versions](#older-versions)<br>
 [Even Older versions](#even-older-versions)<br>
 
+
+
+## 2.10.0
+
+### Fixes
+* `TEMPLATE_LIST_TEST_CASE` now properly handles non-copyable and non-movable types (#1729)
+* Fixed compilation error on Solaris caused by a system header defining macro `TT` (#1722, #1723)
+* `REGISTER_ENUM` will now fail at compilation time if the registered enum is too large
+* Removed use of `std::is_same_v` in C++17 mode (#1757)
+* Fixed parsing of escaped special characters when reading test specs from a file (#1767, #1769)
+
+
+### Improvements
+* Trailing and leading whitespace in test/section specs are now ignored.
+* Writing to Android debug log now uses `__android_log_write` instead of `__android_log_print`
+* Android logging support can now be turned on/off at compile time (#1743)
+  * The toggle is `CATCH_CONFIG_ANDROID_LOGWRITE`
+* Added a generator that returns elements of a range
+  * Use via `from_range(from, to)` or `from_range(container)`
+* Added support for CRTs that do not provide `std::nextafter` (#1739)
+  * They must still provide global `nextafter{f,l,}`
+  * Enabled via `CATCH_CONFIG_GLOBAL_NEXTAFTER`
+* Special cased `Approx(inf)` not to match non-infinite values
+  * Very strictly speaking this might be a breaking change, but it should match user expectations better
+* The output of benchmarking through the Console reporter when `--benchmark-no-analysis` is set is now much simpler (#1768)
+* Added a matcher that can be used for checking an exceptions message (#1649, #1728)
+  * The matcher helper function is called `Message`
+  * The exception must publicly derive from `std::exception`
+  * The matching is done exactly, including case and whitespace
+* Added a matcher that can be used for checking relative equality of floating point numbers (#1746)
+  * Unlike `Approx`, it considers both sides when determining the allowed margin
+  * Special cases `NaN` and `INFINITY` to match user expectations
+  * The matcher helper function is called `WithinRel`
+* The ULP matcher now allows for any possible distance between the two numbers
+* The random number generators now use Catch-global instance of RNG (#1734, #1736)
+  * This means that nested random number generators actually generate different numbers
+
+
+### Miscellaneous
+* In-repo PNGs have been optimized to lower overhead of using Catch2 via git clone
+* Catch2 now uses its own implementation of the URBG concept
+  * In the future we also plan to use our own implementation of the distributions from `<random>` to provide cross-platform repeatability of random results
+
+
+
+## 2.9.2
+
+### Fixes
+* `ChunkGenerator` can now be used with chunks of size 0 (#1671)
+* Nested subsections are now run properly when specific section is run via the `-c` argument (#1670, #1673)
+* Catch2 now consistently uses `_WIN32` to detect Windows platform (#1676)
+* `TEMPLATE_LIST_TEST_CASE` now support non-default constructible type lists (#1697)
+* Fixed a crash in the XMLReporter when a benchmark throws exception during warmup (#1706)
+* Fixed a possible infinite loop in CompactReporter (#1715)
+* Fixed `-w NoTests` returning 0 even when no tests were matched (#1449, #1683, #1684)
+* Fixed matcher compilation under Obj-C++ (#1661)
+
+### Improvements
+* `RepeatGenerator` and `FixedValuesGenerator` now fail to compile when used with `bool` (#1692)
+  * Previously they would fail at runtime.
+* Catch2 now supports Android's debug logging for its debug output (#1710)
+* Catch2 now detects and configures itself for the RTX platform (#1693)
+  * You still need to pass `--benchmark-no-analysis` if you are using benchmarking under RTX
+* Removed a "storage class is not first" warning when compiling Catch2 with PGI compiler (#1717)
+
+### Miscellaneous
+* Documentation now contains indication when a specific feature was introduced (#1695)
+  * These start with Catch2 v2.3.0, (a bit over a year ago).
+  * `docs/contributing.md` has been updated to provide contributors guidance on how to add these to newly written documentation
+* Various other documentation improvements
+  * ToC fixes
+  * Documented `--order` and `--rng-seed` command line options
+  * Benchmarking documentation now clearly states that it requires opt-in
+  * Documented `CATCH_CONFIG_CPP17_OPTIONAL` and `CATCH_CONFIG_CPP17_BYTE` macros
+  * Properly documented built-in vector matchers
+  * Improved `*_THROWS_MATCHES` documentation a bit
+* CMake config file is now arch-independent even if `CMAKE_SIZEOF_VOID_P` is in CMake cache (#1660)
+* `CatchAddTests` now properly escapes `[` and `]` in test names (#1634, #1698)
+* Reverted `CatchAddTests` adding tags as CTest labels (#1658)
+  * The script broke when test names were too long
+  * Overwriting `LABELS` caused trouble for users who set them manually
+  * CMake does not let users append to `LABELS` if the test name has spaces
+
+
+## 2.9.1
+
+### Fixes
+* Fix benchmarking compilation failure in files without `CATCH_CONFIG_EXTERNAL_INTERFACES` (or implementation)
+
+## 2.9.0
+
+### Improvements
+* The experimental benchmarking support has been replaced by integrating Nonius code (#1616)
+  * This provides a much more featurefull micro-benchmarking support.
+  * Due to the compilation cost, it is disabled by default. See the documentation for details.
+  * As far as backwards compatibility is concerned, this feature is still considered experimental in that we might change the interface based on user feedback.
+* `WithinULP` matcher now shows the acceptable range (#1581)
+* Template test cases now support type lists (#1627)
+
+
+## 2.8.0
+
+### Improvements
+* Templated test cases no longer check whether the provided types are unique (#1628)
+  * This allows you to e.g. test over `uint32_t`, `uint64_t`, and `size_t` without compilation failing
+* The precision of floating point stringification can be modified by user (#1612, #1614)
+* We now provide `REGISTER_ENUM` convenience macro for generating `StringMaker` specializations for enums
+  * See the "String conversion" documentation for details
+* Added new set of macros for template test cases that enables the use of NTTPs (#1531, #1609)
+  * See "Test cases and sections" documentation for details
+
+### Fixes
+* `UNSCOPED_INFO` macro now has a prefixed/disabled/prefixed+disabled versions (#1611)
+* Reporting errors at startup should no longer cause a segfault under certain circumstances (#1626)
+
+
+### Miscellaneous
+* CMake will now prevent you from attempting in-tree build (#1636, #1638)
+  * Previously it would break with an obscure error message during the build step
+
+
+## 2.7.2
+
+### Improvements
+* Added an approximate vector matcher (#1499)
+
+### Fixes
+* Filters will no longer be shown if there were none
+* Fixed compilation error when using Homebrew GCC on OS X (#1588, #1589)
+* Fixed the console reporter not showing messages that start with a newline (#1455, #1470)
+* Modified JUnit reporter's output so that rng seed and filters are reported according to the JUnit schema (#1598)
+* Fixed some obscure warnings and static analysis passes
+
+### Miscellaneous
+* Various improvements to `ParseAndAddCatchTests` (#1559, #1601)
+  * When a target is parsed, it receives `ParseAndAddCatchTests_TESTS` property which summarizes found tests
+  * Fixed problem with tests not being found if the `OptionalCatchTestLauncher` variables is used
+  * Including the script will no longer forcefully modify `CMAKE_MINIMUM_REQUIRED_VERSION`
+  * CMake object libraries are ignored when parsing to avoid needless warnings
+* `CatchAddTests` now adds test's tags to their CTest labels (#1600)
+* Added basic CPack support to our build
+
 ## 2.7.1
 
 ### Improvements
 * Reporters now print out the filters applied to test cases (#1550, #1585)
-* Added `GENERATE_COPY` and `GENERATE_VAR` macros that can use variables inside the generator expression
+* Added `GENERATE_COPY` and `GENERATE_REF` macros that can use variables inside the generator expression
   * Because of the significant danger of lifetime issues, the default `GENERATE` macro still does not allow variables
 * The `map` generator helper now deduces the mapped return type (#1576)
 
diff --git a/packages/Catch2/docs/slow-compiles.md b/packages/Catch2/docs/slow-compiles.md
index 0853b6619..366adf291 100644
--- a/packages/Catch2/docs/slow-compiles.md
+++ b/packages/Catch2/docs/slow-compiles.md
@@ -51,14 +51,15 @@ After compiling `tests-main.cpp` once, it is enough to link it with separately c
 
 ```
 $ g++ tests-main.cpp -c
-$ g++ tests-main.o tests-factorial.cpp -o tests && ./tests -r compact
+$ g++ factorial.cpp -c
+$ g++ tests-main.o factorial.o tests-factorial.cpp -o tests && ./tests -r compact
 Passed 1 test case with 4 assertions.
 ```
 
 Now, the next time we change the file `tests-factorial.cpp` (say we add `REQUIRE( Factorial(0) == 1)`), it is enough to recompile the tests instead of recompiling main as well:
 
 ```
-$ g++ tests-main.o tests-factorial.cpp -o tests && ./tests -r compact
+$ g++ tests-main.o factorial.o tests-factorial.cpp -o tests && ./tests -r compact
 tests-factorial.cpp:11: failed: Factorial(0) == 1 for: 0 == 1
 Failed 1 test case, failed 1 assertion.
 ```
diff --git a/packages/Catch2/docs/test-cases-and-sections.md b/packages/Catch2/docs/test-cases-and-sections.md
index 62a805f49..53f9e1504 100644
--- a/packages/Catch2/docs/test-cases-and-sections.md
+++ b/packages/Catch2/docs/test-cases-and-sections.md
@@ -6,6 +6,7 @@
 [Tag aliases](#tag-aliases)<br>
 [BDD-style test cases](#bdd-style-test-cases)<br>
 [Type parametrised test cases](#type-parametrised-test-cases)<br>
+[Signature based parametrised test cases](#signature-based-parametrised-test-cases)<br>
 
 While Catch fully supports the traditional, xUnit, style of class-based fixtures containing test case methods this is not the preferred style.
 
@@ -83,10 +84,13 @@ This macro maps onto ```TEST_CASE``` and works in the same way, except that the
 
 These macros map onto ```SECTION```s except that the section names are the _something_s prefixed by "given: ", "when: " or "then: " respectively.
 
+* **AND_GIVEN(** _something_ **)**
 * **AND_WHEN(** _something_ **)**
 * **AND_THEN(** _something_ **)**
 
-Similar to ```WHEN``` and ```THEN``` except that the prefixes start with "and ". These are used to chain ```WHEN```s and ```THEN```s together.
+Similar to ```GIVEN```, ```WHEN``` and ```THEN``` except that the prefixes start with "and ". These are used to chain ```GIVEN```s, ```WHEN```s and ```THEN```s together.
+
+> `AND_GIVEN` was [introduced](https://github.com/catchorg/Catch2/issues/1360) in Catch 2.4.0.
 
 When any of these macros are used the console reporter recognises them and formats the test case header such that the Givens, Whens and Thens are aligned to aid readability.
 
@@ -95,11 +99,13 @@ Other than the additional prefixes and the formatting in the console reporter th
 ## Type parametrised test cases
 
 In addition to `TEST_CASE`s, Catch2 also supports test cases parametrised
-by types, in the form of `TEMPLATE_TEST_CASE` and
-`TEMPLATE_PRODUCT_TEST_CASE`.
+by types, in the form of `TEMPLATE_TEST_CASE`,
+`TEMPLATE_PRODUCT_TEST_CASE` and `TEMPLATE_LIST_TEST_CASE`.
 
 * **TEMPLATE_TEST_CASE(** _test name_ , _tags_,  _type1_, _type2_, ..., _typen_ **)**
 
+> [Introduced](https://github.com/catchorg/Catch2/issues/1437) in Catch 2.5.0.
+
 _test name_ and _tag_ are exactly the same as they are in `TEST_CASE`,
 with the difference that the tag string must be provided (however, it
 can be empty). _type1_ through _typen_ is the list of types for which
@@ -150,6 +156,8 @@ TEMPLATE_TEST_CASE( "vectors can be sized and resized", "[vector][template]", in
 
 * **TEMPLATE_PRODUCT_TEST_CASE(** _test name_ , _tags_, (_template-type1_, _template-type2_, ..., _template-typen_), (_template-arg1_, _template-arg2_, ..., _template-argm_) **)**
 
+> [Introduced](https://github.com/catchorg/Catch2/issues/1468) in Catch 2.6.0.
+
 _template-type1_ through _template-typen_ is list of template template
 types which should be combined with each of _template-arg1_ through
  _template-argm_, resulting in _n * m_ test cases. Inside the test case,
@@ -191,6 +199,77 @@ _While there is an upper limit on the number of types you can specify
 in single `TEMPLATE_TEST_CASE` or `TEMPLATE_PRODUCT_TEST_CASE`, the limit
 is very high and should not be encountered in practice._
 
+* **TEMPLATE_LIST_TEST_CASE(** _test name_, _tags_, _type list_ **)**
+
+> [Introduced](https://github.com/catchorg/Catch2/issues/1627) in Catch 2.9.0.
+
+_type list_ is a generic list of types on which test case should be instantiated.
+List can be `std::tuple`, `boost::mpl::list`, `boost::mp11::mp_list` or anything with
+`template <typename...>` signature.
+
+This allows you to reuse the _type list_ in multiple test cases.
+
+Example:
+```cpp
+using MyTypes = std::tuple<int, char, float>;
+TEMPLATE_LIST_TEST_CASE("Template test case with test types specified inside std::tuple", "[template][list]", MyTypes)
+{
+    REQUIRE(sizeof(TestType) > 0);
+}
+```
+
+
+## Signature based parametrised test cases
+
+> [Introduced](https://github.com/catchorg/Catch2/issues/1609) in Catch 2.8.0.
+
+In addition to [type parametrised test cases](#type-parametrised-test-cases) Catch2 also supports
+signature base parametrised test cases, in form of `TEMPLATE_TEST_CASE_SIG` and `TEMPLATE_PRODUCT_TEST_CASE_SIG`.
+These test cases have similar syntax like [type parametrised test cases](#type-parametrised-test-cases), with one
+additional positional argument which specifies the signature.
+
+### Signature
+Signature has some strict rules for these tests cases to work properly:
+* signature with multiple template parameters e.g. `typename T, size_t S` must have this format in test case declaration
+  `((typename T, size_t S), T, S)`
+* signature with variadic template arguments e.g. `typename T, size_t S, typename...Ts` must have this format in test case declaration
+  `((typename T, size_t S, typename...Ts), T, S, Ts...)`
+* signature with single non type template parameter e.g. `int V` must have this format in test case declaration `((int V), V)`
+* signature with single type template parameter e.g. `typename T` should not be used as it is in fact `TEMPLATE_TEST_CASE`
+
+Currently Catch2 support up to 11 template parameters in signature
+
+### Examples
+
+* **TEMPLATE_TEST_CASE_SIG(** _test name_ , _tags_,  _signature_, _type1_, _type2_, ..., _typen_ **)**
+
+Inside `TEMPLATE_TEST_CASE_SIG` test case you can use the names of template parameters as defined in _signature_. 
+
+```cpp
+TEMPLATE_TEST_CASE_SIG("TemplateTestSig: arrays can be created from NTTP arguments", "[vector][template][nttp]",
+  ((typename T, int V), T, V), (int,5), (float,4), (std::string,15), ((std::tuple<int, float>), 6)) {
+
+    std::array<T, V> v;
+    REQUIRE(v.size() > 1);
+}
+```
+
+* **TEMPLATE_PRODUCT_TEST_CASE_SIG(** _test name_ , _tags_, _signature_, (_template-type1_, _template-type2_, ..., _template-typen_), (_template-arg1_, _template-arg2_, ..., _template-argm_) **)**
+
+```cpp
+
+template<typename T, size_t S>
+struct Bar {
+    size_t size() { return S; }
+};
+
+TEMPLATE_PRODUCT_TEST_CASE_SIG("A Template product test case with array signature", "[template][product][nttp]", ((typename T, size_t S), T, S), (std::array, Bar), ((int, 9), (float, 42))) {
+    TestType x;
+    REQUIRE(x.size() > 0);
+}
+```
+
+
 ---
 
 [Home](Readme.md#top)
diff --git a/packages/Catch2/docs/test-fixtures.md b/packages/Catch2/docs/test-fixtures.md
index 6b29ce68b..832bba128 100644
--- a/packages/Catch2/docs/test-fixtures.md
+++ b/packages/Catch2/docs/test-fixtures.md
@@ -1,6 +1,8 @@
 <a id="top"></a>
 # Test fixtures
 
+## Defining test fixtures
+
 Although Catch allows you to group tests together as sections within a test case, it can still be convenient, sometimes, to group them using a more traditional test fixture. Catch fully supports this too. You define the test fixture as a simple structure:
 
 ```c++
@@ -84,6 +86,58 @@ _While there is an upper limit on the number of types you can specify
 in single `TEMPLATE_TEST_CASE_METHOD` or `TEMPLATE_PRODUCT_TEST_CASE_METHOD`,
 the limit is very high and should not be encountered in practice._
 
+## Signature-based parametrised test fixtures
+
+> [Introduced](https://github.com/catchorg/Catch2/issues/1609) in Catch 2.8.0.
+
+Catch2 also provides `TEMPLATE_TEST_CASE_METHOD_SIG` and `TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG` to support
+fixtures using non-type template parameters. These test cases work similar to `TEMPLATE_TEST_CASE_METHOD` and `TEMPLATE_PRODUCT_TEST_CASE_METHOD`,
+with additional positional argument for [signature](test-cases-and-sections.md#signature-based-parametrised-test-cases).
+
+Example:
+```cpp
+template <int V>
+struct Nttp_Fixture{
+    int value = V;
+};
+
+TEMPLATE_TEST_CASE_METHOD_SIG(Nttp_Fixture, "A TEMPLATE_TEST_CASE_METHOD_SIG based test run that succeeds", "[class][template][nttp]",((int V), V), 1, 3, 6) {
+    REQUIRE(Nttp_Fixture<V>::value > 0);
+}
+
+template<typename T>
+struct Template_Fixture_2 {
+    Template_Fixture_2() {}
+
+    T m_a;
+};
+
+template< typename T, size_t V>
+struct Template_Foo_2 {
+    size_t size() { return V; }
+};
+
+TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG(Template_Fixture_2, "A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that succeeds", "[class][template][product][nttp]", ((typename T, size_t S), T, S),(std::array, Template_Foo_2), ((int,2), (float,6)))
+{
+    REQUIRE(Template_Fixture_2<TestType>{}.m_a.size() >= 2);
+}
+```
+
+## Template fixtures with types specified in template type lists
+
+Catch2 also provides `TEMPLATE_LIST_TEST_CASE_METHOD` to support template fixtures with types specified in
+template type lists like `std::tuple`, `boost::mpl::list` or `boost::mp11::mp_list`. This test case works the same as `TEMPLATE_TEST_CASE_METHOD`,
+only difference is the source of types. This allows you to reuse the template type list in multiple test cases.
+
+Example:
+```cpp
+using MyTypes = std::tuple<int, char, double>;
+TEMPLATE_LIST_TEST_CASE_METHOD(Template_Fixture, "Template test case method with test types specified inside std::tuple", "[class][template][list]", MyTypes)
+{
+    REQUIRE( Template_Fixture<TestType>::m_a == 1 );
+}
+```
+
 ---
 
 [Home](Readme.md#top)
diff --git a/packages/Catch2/docs/tostring.md b/packages/Catch2/docs/tostring.md
index 933f2e619..156c895a6 100644
--- a/packages/Catch2/docs/tostring.md
+++ b/packages/Catch2/docs/tostring.md
@@ -6,6 +6,9 @@
 [Catch::StringMaker specialisation](#catchstringmaker-specialisation)<br>
 [Catch::is_range specialisation](#catchis_range-specialisation)<br>
 [Exceptions](#exceptions)<br>
+[Enums](#enums)<br>
+[Floating point precision](#floating-point-precision)<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.
@@ -14,7 +17,7 @@ Most built-in or std types are supported out of the box but there are two ways t
 
 This is the standard way of providing string conversions in C++ - and the chances are you may already provide this for your own purposes. If you're not familiar with this idiom it involves writing a free function of the form:
 
-```
+```cpp
 std::ostream& operator << ( std::ostream& os, T const& value ) {
     os << convertMyTypeToString( value );
     return os;
@@ -28,7 +31,7 @@ You should put this function in the same namespace as your type, or the global n
 ## 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>`:
 
-```
+```cpp
 namespace Catch {
     template<>
     struct StringMaker<T> {
@@ -60,12 +63,70 @@ namespace Catch {
 
 By default all exceptions deriving from `std::exception` will be translated to strings by calling the `what()` method. For exception types that do not derive from `std::exception` - or if `what()` does not return a suitable string - use `CATCH_TRANSLATE_EXCEPTION`. This defines a function that takes your exception type, by reference, and returns a string. It can appear anywhere in the code - it doesn't have to be in the same translation unit. For example:
 
-```
+```cpp
 CATCH_TRANSLATE_EXCEPTION( MyType& ex ) {
     return ex.message();
 }
 ```
 
+## Enums
+
+> Introduced in Catch 2.8.0.
+
+Enums that already have a `<<` overload for `std::ostream` will convert to strings as expected.
+If you only need to convert enums to strings for test reporting purposes you can provide a `StringMaker` specialisations as any other type.
+However, as a convenience, Catch provides the `REGISTER_ENUM` helper macro that will generate the `StringMaker` specialiation for you with minimal code.
+Simply provide it the (qualified) enum name, followed by all the enum values, and you're done!
+
+E.g.
+
+```cpp
+enum class Fruits { Banana, Apple, Mango };
+
+CATCH_REGISTER_ENUM( Fruits, Fruits::Banana, Fruits::Apple, Fruits::Mango )
+
+TEST_CASE() {
+    REQUIRE( Fruits::Mango == Fruits::Apple );
+}
+```
+
+... or if the enum is in a namespace:
+```cpp
+namespace Bikeshed {
+    enum class Colours { Red, Green, Blue };
+}
+
+// Important!: This macro must appear at top level scope - not inside a namespace
+// You can fully qualify the names, or use a using if you prefer
+CATCH_REGISTER_ENUM( Bikeshed::Colours,
+    Bikeshed::Colours::Red,
+    Bikeshed::Colours::Green,
+    Bikeshed::Colours::Blue )
+
+TEST_CASE() {
+    REQUIRE( Bikeshed::Colours::Red == Bikeshed::Colours::Blue );
+}
+```
+
+## Floating point precision
+
+> [Introduced](https://github.com/catchorg/Catch2/issues/1614) in Catch 2.8.0.
+
+Catch provides a built-in `StringMaker` specialization for both `float`
+and `double`. By default, it uses what we think is a reasonable precision,
+but you can customize it by modifying the `precision` static variable
+inside the `StringMaker` specialization, like so:
+
+```cpp
+        Catch::StringMaker<float>::precision = 15;
+        const float testFloat1 = 1.12345678901234567899f;
+        const float testFloat2 = 1.12345678991234567899f;
+        REQUIRE(testFloat1 == testFloat2);
+```
+
+This assertion will fail and print out the `testFloat1` and `testFloat2`
+to 15 decimal places.
+
 ---
 
 [Home](Readme.md#top)
diff --git a/packages/Catch2/examples/210-Evt-EventListeners.cpp b/packages/Catch2/examples/210-Evt-EventListeners.cpp
index fde51c7ea..2d5fdb287 100644
--- a/packages/Catch2/examples/210-Evt-EventListeners.cpp
+++ b/packages/Catch2/examples/210-Evt-EventListeners.cpp
@@ -305,7 +305,7 @@ struct MyListener : Catch::TestEventListenerBase {
     ~MyListener();
 
     // The whole test run starting
-    virtual void testRunStarting( Catch::TestRunInfo const& testRunInfo ) override {
+    void testRunStarting( Catch::TestRunInfo const& testRunInfo ) override {
         std::cout
             << std::boolalpha
             << "\nEvent: testRunStarting:\n";
@@ -313,7 +313,7 @@ struct MyListener : Catch::TestEventListenerBase {
     }
 
     // The whole test run ending
-    virtual void testRunEnded( Catch::TestRunStats const& testRunStats ) override {
+    void testRunEnded( Catch::TestRunStats const& testRunStats ) override {
         std::cout
             << dashed_line
             << "\nEvent: testRunEnded:\n";
@@ -321,7 +321,7 @@ struct MyListener : Catch::TestEventListenerBase {
     }
 
     // A test is being skipped (because it is "hidden")
-    virtual void skipTest( Catch::TestCaseInfo const& testInfo ) override {
+    void skipTest( Catch::TestCaseInfo const& testInfo ) override {
         std::cout
             << dashed_line
             << "\nEvent: skipTest:\n";
@@ -329,7 +329,7 @@ struct MyListener : Catch::TestEventListenerBase {
     }
 
     // Test cases starting
-    virtual void testCaseStarting( Catch::TestCaseInfo const& testInfo ) override {
+    void testCaseStarting( Catch::TestCaseInfo const& testInfo ) override {
         std::cout
             << dashed_line
             << "\nEvent: testCaseStarting:\n";
@@ -337,30 +337,30 @@ struct MyListener : Catch::TestEventListenerBase {
     }
 
     // Test cases ending
-    virtual void testCaseEnded( Catch::TestCaseStats const& testCaseStats ) override {
+    void testCaseEnded( Catch::TestCaseStats const& testCaseStats ) override {
         std::cout << "\nEvent: testCaseEnded:\n";
         print( std::cout, 1, "testCaseStats", testCaseStats );
     }
 
     // Sections starting
-    virtual void sectionStarting( Catch::SectionInfo const& sectionInfo ) override {
+    void sectionStarting( Catch::SectionInfo const& sectionInfo ) override {
         std::cout << "\nEvent: sectionStarting:\n";
         print( std::cout, 1, "- sectionInfo", sectionInfo );
     }
 
     // Sections ending
-    virtual void sectionEnded( Catch::SectionStats const& sectionStats ) override {
+    void sectionEnded( Catch::SectionStats const& sectionStats ) override {
         std::cout << "\nEvent: sectionEnded:\n";
         print( std::cout, 1, "- sectionStats", sectionStats );
     }
 
     // Assertions before/ after
-    virtual void assertionStarting( Catch::AssertionInfo const& assertionInfo ) override {
+    void assertionStarting( Catch::AssertionInfo const& assertionInfo ) override {
         std::cout << "\nEvent: assertionStarting:\n";
         print( std::cout, 1, "- assertionInfo", assertionInfo );
     }
 
-    virtual bool assertionEnded( Catch::AssertionStats const& assertionStats ) override {
+    bool assertionEnded( Catch::AssertionStats const& assertionStats ) override {
         std::cout << "\nEvent: assertionEnded:\n";
         print( std::cout, 1, "- assertionStats", assertionStats );
         return true;
diff --git a/packages/Catch2/include/catch.hpp b/packages/Catch2/include/catch.hpp
index 5ee7ffdd9..5d38092e0 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 7
-#define CATCH_VERSION_PATCH 1
+#define CATCH_VERSION_MINOR 10
+#define CATCH_VERSION_PATCH 0
 
 #ifdef __clang__
 #    pragma clang system_header
@@ -53,7 +53,6 @@
 #include "internal/catch_test_registry.h"
 #include "internal/catch_capture.hpp"
 #include "internal/catch_section.h"
-#include "internal/catch_benchmark.h"
 #include "internal/catch_interfaces_exception.h"
 #include "internal/catch_approx.h"
 #include "internal/catch_compiler_capabilities.h"
@@ -75,10 +74,15 @@
 #include "internal/catch_objc.hpp"
 #endif
 
-#ifdef CATCH_CONFIG_EXTERNAL_INTERFACES
+// Benchmarking needs the externally-facing parts of reporters to work
+#if defined(CATCH_CONFIG_EXTERNAL_INTERFACES) || defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
 #include "internal/catch_external_interfaces.h"
 #endif
 
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+#include "internal/benchmark/catch_benchmark.hpp"
+#endif
+
 #endif // ! CATCH_CONFIG_IMPL_ONLY
 
 #ifdef CATCH_IMPL
@@ -89,6 +93,7 @@
 #include "internal/catch_default_main.hpp"
 #endif
 
+
 #if !defined(CATCH_CONFIG_IMPL_ONLY)
 
 #ifdef CLARA_CONFIG_MAIN_NOT_DEFINED
@@ -132,6 +137,7 @@
 #endif // CATCH_CONFIG_DISABLE_MATCHERS
 
 #define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg )
+#define CATCH_UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( "CATCH_UNSCOPED_INFO", msg )
 #define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( "CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
 #define CATCH_CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CATCH_CAPTURE",__VA_ARGS__ )
 
@@ -149,14 +155,22 @@
 
 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
 #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
+#define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ )
 #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
+#define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ )
+#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ )
 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ )
+#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
 #else
 #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) )
+#define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ ) )
 #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
+#define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) )
+#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ ) )
 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
+#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
 #endif
 
 
@@ -179,6 +193,13 @@
 #define CATCH_THEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     Then: " << desc )
 #define CATCH_AND_THEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( "      And: " << desc )
 
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+#define CATCH_BENCHMARK(...) \
+    INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,))
+#define CATCH_BENCHMARK_ADVANCED(name) \
+    INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), name)
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
+
 // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
 #else
 
@@ -232,14 +253,26 @@
 
 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
 #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
+#define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ )
 #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
+#define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
 #define TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ )
+#define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ )
 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ )
+#define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
+#define TEMPLATE_LIST_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(__VA_ARGS__)
+#define TEMPLATE_LIST_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, __VA_ARGS__ )
 #else
 #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) )
+#define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ ) )
 #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
+#define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
 #define TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) )
+#define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ ) )
 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
+#define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
+#define TEMPLATE_LIST_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE( __VA_ARGS__ ) )
+#define TEMPLATE_LIST_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
 #endif
 
 
@@ -266,6 +299,13 @@
 #define THEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     Then: " << desc )
 #define AND_THEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( "      And: " << desc )
 
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+#define BENCHMARK(...) \
+    INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,))
+#define BENCHMARK_ADVANCED(name) \
+    INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), name)
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
+
 using Catch::Detail::Approx;
 
 #else // CATCH_CONFIG_DISABLE
@@ -305,9 +345,10 @@ using Catch::Detail::Approx;
 #define CATCH_REQUIRE_THAT( arg, matcher ) (void)(0)
 #endif // CATCH_CONFIG_DISABLE_MATCHERS
 
-#define CATCH_INFO( msg )    (void)(0)
-#define CATCH_WARN( msg )    (void)(0)
-#define CATCH_CAPTURE( msg ) (void)(0)
+#define CATCH_INFO( msg )          (void)(0)
+#define CATCH_UNSCOPED_INFO( msg ) (void)(0)
+#define CATCH_WARN( msg )          (void)(0)
+#define CATCH_CAPTURE( msg )       (void)(0)
 
 #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
 #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
@@ -322,15 +363,23 @@ using Catch::Detail::Approx;
 #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
 
 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
-#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) )
-#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), className )
+#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__)
+#define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__)
+#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__)
+#define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ )
 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
+#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
+#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
 #else
-#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) ) )
-#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), className ) )
+#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) )
+#define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__) )
+#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__ ) )
+#define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ ) )
 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
+#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
+#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
 #endif
 
 // "BDD-style" convenience wrappers
@@ -382,6 +431,7 @@ using Catch::Detail::Approx;
 #endif // CATCH_CONFIG_DISABLE_MATCHERS
 
 #define INFO( msg ) (void)(0)
+#define UNSCOPED_INFO( msg ) (void)(0)
 #define WARN( msg ) (void)(0)
 #define CAPTURE( msg ) (void)(0)
 
@@ -397,15 +447,23 @@ using Catch::Detail::Approx;
 #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
 
 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
-#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) )
-#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), className )
+#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__)
+#define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__)
+#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__)
+#define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ )
 #define TEMPLATE_PRODUCT_TEST_CASE( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
+#define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
+#define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
 #else
-#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) ) )
-#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), className ) )
+#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) )
+#define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__) )
+#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__ ) )
+#define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ ) )
 #define TEMPLATE_PRODUCT_TEST_CASE( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
+#define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
+#define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
 #endif
 
 #define STATIC_REQUIRE( ... )       (void)(0)
diff --git a/packages/Catch2/include/internal/benchmark/catch_benchmark.hpp b/packages/Catch2/include/internal/benchmark/catch_benchmark.hpp
new file mode 100644
index 000000000..3c0612107
--- /dev/null
+++ b/packages/Catch2/include/internal/benchmark/catch_benchmark.hpp
@@ -0,0 +1,122 @@
+/*
+ *  Created by Joachim on 16/04/2019.
+ *  Adapted from donated nonius code.
+ *
+ *  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)
+ */
+
+ // Benchmark
+#ifndef TWOBLUECUBES_CATCH_BENCHMARK_HPP_INCLUDED
+#define TWOBLUECUBES_CATCH_BENCHMARK_HPP_INCLUDED
+
+#include "../catch_config.hpp"
+#include "../catch_context.h"
+#include "../catch_interfaces_reporter.h"
+#include "../catch_test_registry.h"
+
+#include "catch_chronometer.hpp"
+#include "catch_clock.hpp"
+#include "catch_environment.hpp"
+#include "catch_execution_plan.hpp"
+#include "detail/catch_estimate_clock.hpp"
+#include "detail/catch_complete_invoke.hpp"
+#include "detail/catch_analyse.hpp"
+#include "detail/catch_benchmark_function.hpp"
+#include "detail/catch_run_for_at_least.hpp"
+
+#include <algorithm>
+#include <functional>
+#include <string>
+#include <vector>
+#include <cmath>
+
+namespace Catch {
+    namespace Benchmark {
+        struct Benchmark {
+            Benchmark(std::string &&name)
+                : name(std::move(name)) {}
+
+            template <class FUN>
+            Benchmark(std::string &&name, FUN &&func)
+                : fun(std::move(func)), name(std::move(name)) {}
+
+            template <typename Clock>
+            ExecutionPlan<FloatDuration<Clock>> prepare(const IConfig &cfg, Environment<FloatDuration<Clock>> env) const {
+                auto min_time = env.clock_resolution.mean * Detail::minimum_ticks;
+                auto run_time = std::max(min_time, std::chrono::duration_cast<decltype(min_time)>(Detail::warmup_time));
+                auto&& test = Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(run_time), 1, fun);
+                int new_iters = static_cast<int>(std::ceil(min_time * test.iterations / test.elapsed));
+                return { new_iters, test.elapsed / test.iterations * new_iters * cfg.benchmarkSamples(), fun, std::chrono::duration_cast<FloatDuration<Clock>>(Detail::warmup_time), Detail::warmup_iterations };
+            }
+
+            template <typename Clock = default_clock>
+            void run() {
+                IConfigPtr cfg = getCurrentContext().getConfig();
+
+                auto env = Detail::measure_environment<Clock>();
+
+                getResultCapture().benchmarkPreparing(name);
+                CATCH_TRY{
+                    auto plan = user_code([&] {
+                        return prepare<Clock>(*cfg, env);
+                    });
+
+                    BenchmarkInfo info {
+                        name,
+                        plan.estimated_duration.count(),
+                        plan.iterations_per_sample,
+                        cfg->benchmarkSamples(),
+                        cfg->benchmarkResamples(),
+                        env.clock_resolution.mean.count(),
+                        env.clock_cost.mean.count()
+                    };
+
+                    getResultCapture().benchmarkStarting(info);
+
+                    auto samples = user_code([&] {
+                        return plan.template run<Clock>(*cfg, env);
+                    });
+
+                    auto analysis = Detail::analyse(*cfg, env, samples.begin(), samples.end());
+                    BenchmarkStats<std::chrono::duration<double, std::nano>> stats{ info, analysis.samples, analysis.mean, analysis.standard_deviation, analysis.outliers, analysis.outlier_variance };
+                    getResultCapture().benchmarkEnded(stats);
+
+                } CATCH_CATCH_ALL{
+                    if (translateActiveException() != Detail::benchmarkErrorMsg) // benchmark errors have been reported, otherwise rethrow.
+                        std::rethrow_exception(std::current_exception());
+                }
+            }
+
+            // sets lambda to be used in fun *and* executes benchmark!
+            template <typename Fun,
+                typename std::enable_if<!Detail::is_related<Fun, Benchmark>::value, int>::type = 0>
+                Benchmark & operator=(Fun func) {
+                fun = Detail::BenchmarkFunction(func);
+                run();
+                return *this;
+            }
+
+            explicit operator bool() {
+                return true;
+            }
+
+        private:
+            Detail::BenchmarkFunction fun;
+            std::string name;
+        };
+    }
+} // namespace Catch
+
+#define INTERNAL_CATCH_GET_1_ARG(arg1, arg2, ...) arg1
+#define INTERNAL_CATCH_GET_2_ARG(arg1, arg2, ...) arg2
+
+#define INTERNAL_CATCH_BENCHMARK(BenchmarkName, name, benchmarkIndex)\
+    if( Catch::Benchmark::Benchmark BenchmarkName{name} ) \
+        BenchmarkName = [&](int benchmarkIndex)
+
+#define INTERNAL_CATCH_BENCHMARK_ADVANCED(BenchmarkName, name)\
+    if( Catch::Benchmark::Benchmark BenchmarkName{name} ) \
+        BenchmarkName = [&]
+
+#endif // TWOBLUECUBES_CATCH_BENCHMARK_HPP_INCLUDED
diff --git a/packages/Catch2/include/internal/benchmark/catch_chronometer.hpp b/packages/Catch2/include/internal/benchmark/catch_chronometer.hpp
new file mode 100644
index 000000000..1022017d0
--- /dev/null
+++ b/packages/Catch2/include/internal/benchmark/catch_chronometer.hpp
@@ -0,0 +1,71 @@
+/*
+ *  Created by Joachim on 16/04/2019.
+ *  Adapted from donated nonius code.
+ *
+ *  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)
+ */
+
+// User-facing chronometer
+
+#ifndef TWOBLUECUBES_CATCH_CHRONOMETER_HPP_INCLUDED
+#define TWOBLUECUBES_CATCH_CHRONOMETER_HPP_INCLUDED
+
+#include "catch_clock.hpp"
+#include "catch_optimizer.hpp"
+#include "detail/catch_complete_invoke.hpp"
+#include "../catch_meta.hpp"
+
+namespace Catch {
+    namespace Benchmark {
+        namespace Detail {
+            struct ChronometerConcept {
+                virtual void start() = 0;
+                virtual void finish() = 0;
+                virtual ~ChronometerConcept() = default;
+            };
+            template <typename Clock>
+            struct ChronometerModel final : public ChronometerConcept {
+                void start() override { started = Clock::now(); }
+                void finish() override { finished = Clock::now(); }
+
+                ClockDuration<Clock> elapsed() const { return finished - started; }
+
+                TimePoint<Clock> started;
+                TimePoint<Clock> finished;
+            };
+        } // namespace Detail
+
+        struct Chronometer {
+        public:
+            template <typename Fun>
+            void measure(Fun&& fun) { measure(std::forward<Fun>(fun), is_callable<Fun(int)>()); }
+
+            int runs() const { return k; }
+
+            Chronometer(Detail::ChronometerConcept& meter, int k)
+                : impl(&meter)
+                , k(k) {}
+
+        private:
+            template <typename Fun>
+            void measure(Fun&& fun, std::false_type) {
+                measure([&fun](int) { return fun(); }, std::true_type());
+            }
+
+            template <typename Fun>
+            void measure(Fun&& fun, std::true_type) {
+                Detail::optimizer_barrier();
+                impl->start();
+                for (int i = 0; i < k; ++i) invoke_deoptimized(fun, i);
+                impl->finish();
+                Detail::optimizer_barrier();
+            }
+
+            Detail::ChronometerConcept* impl;
+            int k;
+        };
+    } // namespace Benchmark
+} // namespace Catch
+
+#endif // TWOBLUECUBES_CATCH_CHRONOMETER_HPP_INCLUDED
diff --git a/packages/Catch2/include/internal/benchmark/catch_clock.hpp b/packages/Catch2/include/internal/benchmark/catch_clock.hpp
new file mode 100644
index 000000000..32a3e868b
--- /dev/null
+++ b/packages/Catch2/include/internal/benchmark/catch_clock.hpp
@@ -0,0 +1,40 @@
+/*
+ *  Created by Joachim on 16/04/2019.
+ *  Adapted from donated nonius code.
+ *
+ *  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)
+ */
+
+// Clocks
+
+#ifndef TWOBLUECUBES_CATCH_CLOCK_HPP_INCLUDED
+#define TWOBLUECUBES_CATCH_CLOCK_HPP_INCLUDED
+
+#include <chrono>
+#include <ratio>
+
+namespace Catch {
+    namespace Benchmark {
+        template <typename Clock>
+        using ClockDuration = typename Clock::duration;
+        template <typename Clock>
+        using FloatDuration = std::chrono::duration<double, typename Clock::period>;
+
+        template <typename Clock>
+        using TimePoint = typename Clock::time_point;
+
+        using default_clock = std::chrono::steady_clock;
+
+        template <typename Clock>
+        struct now {
+            TimePoint<Clock> operator()() const {
+                return Clock::now();
+            }
+        };
+
+        using fp_seconds = std::chrono::duration<double, std::ratio<1>>;
+    } // namespace Benchmark
+} // namespace Catch
+
+#endif // TWOBLUECUBES_CATCH_CLOCK_HPP_INCLUDED
diff --git a/packages/Catch2/include/internal/benchmark/catch_constructor.hpp b/packages/Catch2/include/internal/benchmark/catch_constructor.hpp
new file mode 100644
index 000000000..bf6dfec99
--- /dev/null
+++ b/packages/Catch2/include/internal/benchmark/catch_constructor.hpp
@@ -0,0 +1,73 @@
+/*
+ *  Created by Joachim on 16/04/2019.
+ *  Adapted from donated nonius code.
+ *
+ *  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)
+ */
+
+// Constructor and destructor helpers
+
+#ifndef TWOBLUECUBES_CATCH_CONSTRUCTOR_HPP_INCLUDED
+#define TWOBLUECUBES_CATCH_CONSTRUCTOR_HPP_INCLUDED
+
+#include <type_traits>
+
+namespace Catch {
+    namespace Detail {
+        template <typename T, bool Destruct>
+        struct ObjectStorage
+        {
+            using TStorage = typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type;
+
+            ObjectStorage() : data() {}
+
+            ObjectStorage(const ObjectStorage& other)
+            {
+                new(&data) T(other.stored_object());
+            }
+
+            ObjectStorage(ObjectStorage&& other)
+            {
+                new(&data) T(std::move(other.stored_object()));
+            }
+
+            ~ObjectStorage() { destruct_on_exit<T>(); }
+
+            template <typename... Args>
+            void construct(Args&&... args)
+            {
+                new (&data) T(std::forward<Args>(args)...);
+            }
+
+            template <bool AllowManualDestruction = !Destruct>
+            typename std::enable_if<AllowManualDestruction>::type destruct()
+            {
+                stored_object().~T();
+            }
+
+        private:
+            // If this is a constructor benchmark, destruct the underlying object
+            template <typename U>
+            void destruct_on_exit(typename std::enable_if<Destruct, U>::type* = 0) { destruct<true>(); }
+            // Otherwise, don't
+            template <typename U>
+            void destruct_on_exit(typename std::enable_if<!Destruct, U>::type* = 0) { }
+
+            T& stored_object()
+            {
+                return *static_cast<T*>(static_cast<void*>(&data));
+            }
+
+            TStorage data;
+        };
+    }
+
+    template <typename T>
+    using storage_for = Detail::ObjectStorage<T, true>;
+
+    template <typename T>
+    using destructable_object = Detail::ObjectStorage<T, false>;
+}
+
+#endif // TWOBLUECUBES_CATCH_CONSTRUCTOR_HPP_INCLUDED
diff --git a/packages/Catch2/include/internal/benchmark/catch_environment.hpp b/packages/Catch2/include/internal/benchmark/catch_environment.hpp
new file mode 100644
index 000000000..559512498
--- /dev/null
+++ b/packages/Catch2/include/internal/benchmark/catch_environment.hpp
@@ -0,0 +1,38 @@
+/*
+ *  Created by Joachim on 16/04/2019.
+ *  Adapted from donated nonius code.
+ *
+ *  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)
+ */
+
+// Environment information
+
+#ifndef TWOBLUECUBES_CATCH_ENVIRONMENT_HPP_INCLUDED
+#define TWOBLUECUBES_CATCH_ENVIRONMENT_HPP_INCLUDED
+
+#include "catch_clock.hpp"
+#include "catch_outlier_classification.hpp"
+
+namespace Catch {
+    namespace Benchmark {
+        template <typename Duration>
+        struct EnvironmentEstimate {
+            Duration mean;
+            OutlierClassification outliers;
+
+            template <typename Duration2>
+            operator EnvironmentEstimate<Duration2>() const {
+                return { mean, outliers };
+            }
+        };
+        template <typename Clock>
+        struct Environment {
+            using clock_type = Clock;
+            EnvironmentEstimate<FloatDuration<Clock>> clock_resolution;
+            EnvironmentEstimate<FloatDuration<Clock>> clock_cost;
+        };
+    } // namespace Benchmark
+} // namespace Catch
+
+#endif // TWOBLUECUBES_CATCH_ENVIRONMENT_HPP_INCLUDED
diff --git a/packages/Catch2/include/internal/benchmark/catch_estimate.hpp b/packages/Catch2/include/internal/benchmark/catch_estimate.hpp
new file mode 100644
index 000000000..a3c913ce6
--- /dev/null
+++ b/packages/Catch2/include/internal/benchmark/catch_estimate.hpp
@@ -0,0 +1,31 @@
+/*
+ *  Created by Joachim on 16/04/2019.
+ *  Adapted from donated nonius code.
+ *
+ *  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)
+ */
+
+ // Statistics estimates
+
+#ifndef TWOBLUECUBES_CATCH_ESTIMATE_HPP_INCLUDED
+#define TWOBLUECUBES_CATCH_ESTIMATE_HPP_INCLUDED
+
+namespace Catch {
+    namespace Benchmark {
+        template <typename Duration>
+        struct Estimate {
+            Duration point;
+            Duration lower_bound;
+            Duration upper_bound;
+            double confidence_interval;
+
+            template <typename Duration2>
+            operator Estimate<Duration2>() const {
+                return { point, lower_bound, upper_bound, confidence_interval };
+            }
+        };
+    } // namespace Benchmark
+} // namespace Catch
+
+#endif // TWOBLUECUBES_CATCH_ESTIMATE_HPP_INCLUDED
diff --git a/packages/Catch2/include/internal/benchmark/catch_execution_plan.hpp b/packages/Catch2/include/internal/benchmark/catch_execution_plan.hpp
new file mode 100644
index 000000000..e56c83aa7
--- /dev/null
+++ b/packages/Catch2/include/internal/benchmark/catch_execution_plan.hpp
@@ -0,0 +1,58 @@
+/*
+ *  Created by Joachim on 16/04/2019.
+ *  Adapted from donated nonius code.
+ *
+ *  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)
+ */
+
+ // Execution plan
+
+#ifndef TWOBLUECUBES_CATCH_EXECUTION_PLAN_HPP_INCLUDED
+#define TWOBLUECUBES_CATCH_EXECUTION_PLAN_HPP_INCLUDED
+
+#include "../catch_config.hpp"
+#include "catch_clock.hpp"
+#include "catch_environment.hpp"
+#include "detail/catch_benchmark_function.hpp"
+#include "detail/catch_repeat.hpp"
+#include "detail/catch_run_for_at_least.hpp"
+
+#include <algorithm>
+
+namespace Catch {
+    namespace Benchmark {
+        template <typename Duration>
+        struct ExecutionPlan {
+            int iterations_per_sample;
+            Duration estimated_duration;
+            Detail::BenchmarkFunction benchmark;
+            Duration warmup_time;
+            int warmup_iterations;
+
+            template <typename Duration2>
+            operator ExecutionPlan<Duration2>() const {
+                return { iterations_per_sample, estimated_duration, benchmark, warmup_time, warmup_iterations };
+            }
+
+            template <typename Clock>
+            std::vector<FloatDuration<Clock>> run(const IConfig &cfg, Environment<FloatDuration<Clock>> env) const {
+                // warmup a bit
+                Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(warmup_time), warmup_iterations, Detail::repeat(now<Clock>{}));
+
+                std::vector<FloatDuration<Clock>> times;
+                times.reserve(cfg.benchmarkSamples());
+                std::generate_n(std::back_inserter(times), cfg.benchmarkSamples(), [this, env] {
+                    Detail::ChronometerModel<Clock> model;
+                    this->benchmark(Chronometer(model, iterations_per_sample));
+                    auto sample_time = model.elapsed() - env.clock_cost.mean;
+                    if (sample_time < FloatDuration<Clock>::zero()) sample_time = FloatDuration<Clock>::zero();
+                    return sample_time / iterations_per_sample;
+                });
+                return times;
+            }
+        };
+    } // namespace Benchmark
+} // namespace Catch
+
+#endif // TWOBLUECUBES_CATCH_EXECUTION_PLAN_HPP_INCLUDED
diff --git a/packages/Catch2/include/internal/benchmark/catch_optimizer.hpp b/packages/Catch2/include/internal/benchmark/catch_optimizer.hpp
new file mode 100644
index 000000000..bda7c6d7e
--- /dev/null
+++ b/packages/Catch2/include/internal/benchmark/catch_optimizer.hpp
@@ -0,0 +1,68 @@
+/*
+ *  Created by Joachim on 16/04/2019.
+ *  Adapted from donated nonius code.
+ *
+ *  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)
+ */
+
+ // Hinting the optimizer
+
+#ifndef TWOBLUECUBES_CATCH_OPTIMIZER_HPP_INCLUDED
+#define TWOBLUECUBES_CATCH_OPTIMIZER_HPP_INCLUDED
+
+#if defined(_MSC_VER)
+#   include <atomic> // atomic_thread_fence
+#endif
+
+namespace Catch {
+    namespace Benchmark {
+#if defined(__GNUC__) || defined(__clang__)
+        template <typename T>
+        inline void keep_memory(T* p) {
+            asm volatile("" : : "g"(p) : "memory");
+        }
+        inline void keep_memory() {
+            asm volatile("" : : : "memory");
+        }
+
+        namespace Detail {
+            inline void optimizer_barrier() { keep_memory(); }
+        } // namespace Detail
+#elif defined(_MSC_VER)
+
+#pragma optimize("", off)
+        template <typename T>
+        inline void keep_memory(T* p) {
+            // thanks @milleniumbug
+            *reinterpret_cast<char volatile*>(p) = *reinterpret_cast<char const volatile*>(p);
+        }
+        // TODO equivalent keep_memory()
+#pragma optimize("", on)
+
+        namespace Detail {
+            inline void optimizer_barrier() {
+                std::atomic_thread_fence(std::memory_order_seq_cst);
+            }
+        } // namespace Detail
+
+#endif
+
+        template <typename T>
+        inline void deoptimize_value(T&& x) {
+            keep_memory(&x);
+        }
+
+        template <typename Fn, typename... Args>
+        inline auto invoke_deoptimized(Fn&& fn, Args&&... args) -> typename std::enable_if<!std::is_same<void, decltype(fn(args...))>::value>::type {
+            deoptimize_value(std::forward<Fn>(fn) (std::forward<Args...>(args...)));
+        }
+
+        template <typename Fn, typename... Args>
+        inline auto invoke_deoptimized(Fn&& fn, Args&&... args) -> typename std::enable_if<std::is_same<void, decltype(fn(args...))>::value>::type {
+            std::forward<Fn>(fn) (std::forward<Args...>(args...));
+        }
+    } // namespace Benchmark
+} // namespace Catch
+
+#endif // TWOBLUECUBES_CATCH_OPTIMIZER_HPP_INCLUDED
diff --git a/packages/Catch2/include/internal/benchmark/catch_outlier_classification.hpp b/packages/Catch2/include/internal/benchmark/catch_outlier_classification.hpp
new file mode 100644
index 000000000..66a0adf57
--- /dev/null
+++ b/packages/Catch2/include/internal/benchmark/catch_outlier_classification.hpp
@@ -0,0 +1,29 @@
+/*
+ *  Created by Joachim on 16/04/2019.
+ *  Adapted from donated nonius code.
+ *
+ *  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)
+ */
+
+// Outlier information
+#ifndef TWOBLUECUBES_CATCH_OUTLIERS_HPP_INCLUDED
+#define TWOBLUECUBES_CATCH_OUTLIERS_HPP_INCLUDED
+
+namespace Catch {
+    namespace Benchmark {
+        struct OutlierClassification {
+            int samples_seen = 0;
+            int low_severe = 0;     // more than 3 times IQR below Q1
+            int low_mild = 0;       // 1.5 to 3 times IQR below Q1
+            int high_mild = 0;      // 1.5 to 3 times IQR above Q3
+            int high_severe = 0;    // more than 3 times IQR above Q3
+
+            int total() const {
+                return low_severe + low_mild + high_mild + high_severe;
+            }
+        };
+    } // namespace Benchmark
+} // namespace Catch
+
+#endif // TWOBLUECUBES_CATCH_OUTLIERS_HPP_INCLUDED
diff --git a/packages/Catch2/include/internal/benchmark/catch_sample_analysis.hpp b/packages/Catch2/include/internal/benchmark/catch_sample_analysis.hpp
new file mode 100644
index 000000000..4550d0bc4
--- /dev/null
+++ b/packages/Catch2/include/internal/benchmark/catch_sample_analysis.hpp
@@ -0,0 +1,50 @@
+/*
+ *  Created by Joachim on 16/04/2019.
+ *  Adapted from donated nonius code.
+ *
+ *  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)
+ */
+
+// Benchmark results
+
+#ifndef TWOBLUECUBES_CATCH_BENCHMARK_RESULTS_HPP_INCLUDED
+#define TWOBLUECUBES_CATCH_BENCHMARK_RESULTS_HPP_INCLUDED
+
+#include "catch_clock.hpp"
+#include "catch_estimate.hpp"
+#include "catch_outlier_classification.hpp"
+
+#include <algorithm>
+#include <vector>
+#include <string>
+#include <iterator>
+
+namespace Catch {
+    namespace Benchmark {
+        template <typename Duration>
+        struct SampleAnalysis {
+            std::vector<Duration> samples;
+            Estimate<Duration> mean;
+            Estimate<Duration> standard_deviation;
+            OutlierClassification outliers;
+            double outlier_variance;
+
+            template <typename Duration2>
+            operator SampleAnalysis<Duration2>() const {
+                std::vector<Duration2> samples2;
+                samples2.reserve(samples.size());
+                std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](Duration d) { return Duration2(d); });
+                return {
+                    std::move(samples2),
+                    mean,
+                    standard_deviation,
+                    outliers,
+                    outlier_variance,
+                };
+            }
+        };
+    } // namespace Benchmark
+} // namespace Catch
+
+#endif // TWOBLUECUBES_CATCH_BENCHMARK_RESULTS_HPP_INCLUDED
diff --git a/packages/Catch2/include/internal/benchmark/detail/catch_analyse.hpp b/packages/Catch2/include/internal/benchmark/detail/catch_analyse.hpp
new file mode 100644
index 000000000..a3becbe4d
--- /dev/null
+++ b/packages/Catch2/include/internal/benchmark/detail/catch_analyse.hpp
@@ -0,0 +1,78 @@
+/*
+ *  Created by Joachim on 16/04/2019.
+ *  Adapted from donated nonius code.
+ *
+ *  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)
+ */
+
+ // Run and analyse one benchmark
+
+#ifndef TWOBLUECUBES_CATCH_DETAIL_ANALYSE_HPP_INCLUDED
+#define TWOBLUECUBES_CATCH_DETAIL_ANALYSE_HPP_INCLUDED
+
+#include "../catch_clock.hpp"
+#include "../catch_sample_analysis.hpp"
+#include "catch_stats.hpp"
+
+#include <algorithm>
+#include <iterator>
+#include <vector>
+
+namespace Catch {
+    namespace Benchmark {
+        namespace Detail {
+            template <typename Duration, typename Iterator>
+            SampleAnalysis<Duration> analyse(const IConfig &cfg, Environment<Duration>, Iterator first, Iterator last) {
+                if (!cfg.benchmarkNoAnalysis()) {
+                    std::vector<double> samples;
+                    samples.reserve(last - first);
+                    std::transform(first, last, std::back_inserter(samples), [](Duration d) { return d.count(); });
+
+                    auto analysis = Catch::Benchmark::Detail::analyse_samples(cfg.benchmarkConfidenceInterval(), cfg.benchmarkResamples(), samples.begin(), samples.end());
+                    auto outliers = Catch::Benchmark::Detail::classify_outliers(samples.begin(), samples.end());
+
+                    auto wrap_estimate = [](Estimate<double> e) {
+                        return Estimate<Duration> {
+                            Duration(e.point),
+                                Duration(e.lower_bound),
+                                Duration(e.upper_bound),
+                                e.confidence_interval,
+                        };
+                    };
+                    std::vector<Duration> samples2;
+                    samples2.reserve(samples.size());
+                    std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](double d) { return Duration(d); });
+                    return {
+                        std::move(samples2),
+                        wrap_estimate(analysis.mean),
+                        wrap_estimate(analysis.standard_deviation),
+                        outliers,
+                        analysis.outlier_variance,
+                    };
+                } else {
+                    std::vector<Duration> samples; 
+                    samples.reserve(last - first);
+
+                    Duration mean = Duration(0);
+                    int i = 0;
+                    for (auto it = first; it < last; ++it, ++i) {
+                        samples.push_back(Duration(*it));
+                        mean += Duration(*it);
+                    }
+                    mean /= i;
+
+                    return {
+                        std::move(samples),
+                        Estimate<Duration>{mean, mean, mean, 0.0},
+                        Estimate<Duration>{Duration(0), Duration(0), Duration(0), 0.0},
+                        OutlierClassification{},
+                        0.0
+                    };
+                }
+            }
+        } // namespace Detail
+    } // namespace Benchmark
+} // namespace Catch
+
+#endif // TWOBLUECUBES_CATCH_DETAIL_ANALYSE_HPP_INCLUDED
diff --git a/packages/Catch2/include/internal/benchmark/detail/catch_benchmark_function.hpp b/packages/Catch2/include/internal/benchmark/detail/catch_benchmark_function.hpp
new file mode 100644
index 000000000..60c7f1d69
--- /dev/null
+++ b/packages/Catch2/include/internal/benchmark/detail/catch_benchmark_function.hpp
@@ -0,0 +1,105 @@
+    /*
+ *  Created by Joachim on 16/04/2019.
+ *  Adapted from donated nonius code.
+ *
+ *  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)
+ */
+
+ // Dumb std::function implementation for consistent call overhead
+
+#ifndef TWOBLUECUBES_CATCH_DETAIL_BENCHMARK_FUNCTION_HPP_INCLUDED
+#define TWOBLUECUBES_CATCH_DETAIL_BENCHMARK_FUNCTION_HPP_INCLUDED
+
+#include "../catch_chronometer.hpp"
+#include "catch_complete_invoke.hpp"
+#include "../../catch_meta.hpp"
+
+#include <cassert>
+#include <type_traits>
+#include <utility>
+#include <memory>
+
+namespace Catch {
+    namespace Benchmark {
+        namespace Detail {
+            template <typename T>
+            using Decay = typename std::decay<T>::type;
+            template <typename T, typename U>
+            struct is_related
+                : std::is_same<Decay<T>, Decay<U>> {};
+
+            /// We need to reinvent std::function because every piece of code that might add overhead
+            /// in a measurement context needs to have consistent performance characteristics so that we
+            /// can account for it in the measurement.
+            /// Implementations of std::function with optimizations that aren't always applicable, like
+            /// small buffer optimizations, are not uncommon.
+            /// This is effectively an implementation of std::function without any such optimizations;
+            /// it may be slow, but it is consistently slow.
+            struct BenchmarkFunction {
+            private:
+                struct callable {
+                    virtual void call(Chronometer meter) const = 0;
+                    virtual callable* clone() const = 0;
+                    virtual ~callable() = default;
+                };
+                template <typename Fun>
+                struct model : public callable {
+                    model(Fun&& fun) : fun(std::move(fun)) {}
+                    model(Fun const& fun) : fun(fun) {}
+
+                    model<Fun>* clone() const override { return new model<Fun>(*this); }
+
+                    void call(Chronometer meter) const override {
+                        call(meter, is_callable<Fun(Chronometer)>());
+                    }
+                    void call(Chronometer meter, std::true_type) const {
+                        fun(meter);
+                    }
+                    void call(Chronometer meter, std::false_type) const {
+                        meter.measure(fun);
+                    }
+
+                    Fun fun;
+                };
+
+                struct do_nothing { void operator()() const {} };
+
+                template <typename T>
+                BenchmarkFunction(model<T>* c) : f(c) {}
+
+            public:
+                BenchmarkFunction()
+                    : f(new model<do_nothing>{ {} }) {}
+
+                template <typename Fun,
+                    typename std::enable_if<!is_related<Fun, BenchmarkFunction>::value, int>::type = 0>
+                    BenchmarkFunction(Fun&& fun)
+                    : f(new model<typename std::decay<Fun>::type>(std::forward<Fun>(fun))) {}
+
+                BenchmarkFunction(BenchmarkFunction&& that)
+                    : f(std::move(that.f)) {}
+
+                BenchmarkFunction(BenchmarkFunction const& that)
+                    : f(that.f->clone()) {}
+
+                BenchmarkFunction& operator=(BenchmarkFunction&& that) {
+                    f = std::move(that.f);
+                    return *this;
+                }
+
+                BenchmarkFunction& operator=(BenchmarkFunction const& that) {
+                    f.reset(that.f->clone());
+                    return *this;
+                }
+
+                void operator()(Chronometer meter) const { f->call(meter); }
+
+            private:
+                std::unique_ptr<callable> f;
+            };
+        } // namespace Detail
+    } // namespace Benchmark
+} // namespace Catch
+
+#endif // TWOBLUECUBES_CATCH_DETAIL_BENCHMARK_FUNCTION_HPP_INCLUDED
diff --git a/packages/Catch2/include/internal/benchmark/detail/catch_complete_invoke.hpp b/packages/Catch2/include/internal/benchmark/detail/catch_complete_invoke.hpp
new file mode 100644
index 000000000..abeb2ac71
--- /dev/null
+++ b/packages/Catch2/include/internal/benchmark/detail/catch_complete_invoke.hpp
@@ -0,0 +1,69 @@
+/*
+ *  Created by Joachim on 16/04/2019.
+ *  Adapted from donated nonius code.
+ *
+ *  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)
+ */
+
+// Invoke with a special case for void
+
+#ifndef TWOBLUECUBES_CATCH_DETAIL_COMPLETE_INVOKE_HPP_INCLUDED
+#define TWOBLUECUBES_CATCH_DETAIL_COMPLETE_INVOKE_HPP_INCLUDED
+
+#include "../../catch_enforce.h"
+
+#include <type_traits>
+#include <utility>
+
+namespace Catch {
+    namespace Benchmark {
+        namespace Detail {
+            template <typename T>
+            struct CompleteType { using type = T; };
+            template <>
+            struct CompleteType<void> { struct type {}; };
+
+            template <typename T>
+            using CompleteType_t = typename CompleteType<T>::type;
+
+            template <typename Result>
+            struct CompleteInvoker {
+                template <typename Fun, typename... Args>
+                static Result invoke(Fun&& fun, Args&&... args) {
+                    return std::forward<Fun>(fun)(std::forward<Args>(args)...);
+                }
+            };
+            template <>
+            struct CompleteInvoker<void> {
+                template <typename Fun, typename... Args>
+                static CompleteType_t<void> invoke(Fun&& fun, Args&&... args) {
+                    std::forward<Fun>(fun)(std::forward<Args>(args)...);
+                    return {};
+                }
+            };
+            template <typename Sig>
+            using ResultOf_t = typename std::result_of<Sig>::type;
+
+            // invoke and not return void :(
+            template <typename Fun, typename... Args>
+            CompleteType_t<ResultOf_t<Fun(Args...)>> complete_invoke(Fun&& fun, Args&&... args) {
+                return CompleteInvoker<ResultOf_t<Fun(Args...)>>::invoke(std::forward<Fun>(fun), std::forward<Args>(args)...);
+            }
+
+            const std::string benchmarkErrorMsg = "a benchmark failed to run successfully";
+        } // namespace Detail
+
+        template <typename Fun>
+        Detail::CompleteType_t<Detail::ResultOf_t<Fun()>> user_code(Fun&& fun) {
+            CATCH_TRY{
+                return Detail::complete_invoke(std::forward<Fun>(fun));
+            } CATCH_CATCH_ALL{
+                getResultCapture().benchmarkFailed(translateActiveException());
+                CATCH_RUNTIME_ERROR(Detail::benchmarkErrorMsg);
+            }
+        }
+    } // namespace Benchmark
+} // namespace Catch
+
+#endif // TWOBLUECUBES_CATCH_DETAIL_COMPLETE_INVOKE_HPP_INCLUDED
diff --git a/packages/Catch2/include/internal/benchmark/detail/catch_estimate_clock.hpp b/packages/Catch2/include/internal/benchmark/detail/catch_estimate_clock.hpp
new file mode 100644
index 000000000..055c58250
--- /dev/null
+++ b/packages/Catch2/include/internal/benchmark/detail/catch_estimate_clock.hpp
@@ -0,0 +1,113 @@
+/*
+ *  Created by Joachim on 16/04/2019.
+ *  Adapted from donated nonius code.
+ *
+ *  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)
+ */
+
+ // Environment measurement
+
+#ifndef TWOBLUECUBES_CATCH_DETAIL_ESTIMATE_CLOCK_HPP_INCLUDED
+#define TWOBLUECUBES_CATCH_DETAIL_ESTIMATE_CLOCK_HPP_INCLUDED
+
+#include "../catch_clock.hpp"
+#include "../catch_environment.hpp"
+#include "catch_stats.hpp"
+#include "catch_measure.hpp"
+#include "catch_run_for_at_least.hpp"
+#include "../catch_clock.hpp"
+
+#include <algorithm>
+#include <iterator>
+#include <tuple>
+#include <vector>
+#include <cmath>
+
+namespace Catch {
+    namespace Benchmark {
+        namespace Detail {
+            template <typename Clock>
+            std::vector<double> resolution(int k) {
+                std::vector<TimePoint<Clock>> times;
+                times.reserve(k + 1);
+                std::generate_n(std::back_inserter(times), k + 1, now<Clock>{});
+
+                std::vector<double> deltas;
+                deltas.reserve(k);
+                std::transform(std::next(times.begin()), times.end(), times.begin(),
+                    std::back_inserter(deltas),
+                    [](TimePoint<Clock> a, TimePoint<Clock> b) { return static_cast<double>((a - b).count()); });
+
+                return deltas;
+            }
+
+            const auto warmup_iterations = 10000;
+            const auto warmup_time = std::chrono::milliseconds(100);
+            const auto minimum_ticks = 1000;
+            const auto warmup_seed = 10000;
+            const auto clock_resolution_estimation_time = std::chrono::milliseconds(500);
+            const auto clock_cost_estimation_time_limit = std::chrono::seconds(1);
+            const auto clock_cost_estimation_tick_limit = 100000;
+            const auto clock_cost_estimation_time = std::chrono::milliseconds(10);
+            const auto clock_cost_estimation_iterations = 10000;
+
+            template <typename Clock>
+            int warmup() {
+                return run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(warmup_time), warmup_seed, &resolution<Clock>)
+                    .iterations;
+            }
+            template <typename Clock>
+            EnvironmentEstimate<FloatDuration<Clock>> estimate_clock_resolution(int iterations) {
+                auto r = run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(clock_resolution_estimation_time), iterations, &resolution<Clock>)
+                    .result;
+                return {
+                    FloatDuration<Clock>(mean(r.begin(), r.end())),
+                    classify_outliers(r.begin(), r.end()),
+                };
+            }
+            template <typename Clock>
+            EnvironmentEstimate<FloatDuration<Clock>> estimate_clock_cost(FloatDuration<Clock> resolution) {
+                auto time_limit = std::min(resolution * clock_cost_estimation_tick_limit, FloatDuration<Clock>(clock_cost_estimation_time_limit));
+                auto time_clock = [](int k) {
+                    return Detail::measure<Clock>([k] {
+                        for (int i = 0; i < k; ++i) {
+                            volatile auto ignored = Clock::now();
+                            (void)ignored;
+                        }
+                    }).elapsed;
+                };
+                time_clock(1);
+                int iters = clock_cost_estimation_iterations;
+                auto&& r = run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(clock_cost_estimation_time), iters, time_clock);
+                std::vector<double> times;
+                int nsamples = static_cast<int>(std::ceil(time_limit / r.elapsed));
+                times.reserve(nsamples);
+                std::generate_n(std::back_inserter(times), nsamples, [time_clock, &r] {
+                    return static_cast<double>((time_clock(r.iterations) / r.iterations).count());
+                });
+                return {
+                    FloatDuration<Clock>(mean(times.begin(), times.end())),
+                    classify_outliers(times.begin(), times.end()),
+                };
+            }
+
+            template <typename Clock>
+            Environment<FloatDuration<Clock>> measure_environment() {
+                static Environment<FloatDuration<Clock>>* env = nullptr;
+                if (env) {
+                    return *env;
+                }
+
+                auto iters = Detail::warmup<Clock>();
+                auto resolution = Detail::estimate_clock_resolution<Clock>(iters);
+                auto cost = Detail::estimate_clock_cost<Clock>(resolution.mean);
+
+                env = new Environment<FloatDuration<Clock>>{ resolution, cost };
+                return *env;
+            }
+        } // namespace Detail
+    } // namespace Benchmark
+} // namespace Catch
+
+#endif // TWOBLUECUBES_CATCH_DETAIL_ESTIMATE_CLOCK_HPP_INCLUDED
diff --git a/packages/Catch2/include/internal/benchmark/detail/catch_measure.hpp b/packages/Catch2/include/internal/benchmark/detail/catch_measure.hpp
new file mode 100644
index 000000000..62ed28096
--- /dev/null
+++ b/packages/Catch2/include/internal/benchmark/detail/catch_measure.hpp
@@ -0,0 +1,35 @@
+/*
+ *  Created by Joachim on 16/04/2019.
+ *  Adapted from donated nonius code.
+ *
+ *  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)
+ */
+
+// Measure
+
+#ifndef TWOBLUECUBES_CATCH_DETAIL_MEASURE_HPP_INCLUDED
+#define TWOBLUECUBES_CATCH_DETAIL_MEASURE_HPP_INCLUDED
+
+#include "../catch_clock.hpp"
+#include "catch_complete_invoke.hpp"
+#include "catch_timing.hpp"
+
+#include <utility>
+
+namespace Catch {
+    namespace Benchmark {
+        namespace Detail {
+            template <typename Clock, typename Fun, typename... Args>
+            TimingOf<Clock, Fun(Args...)> measure(Fun&& fun, Args&&... args) {
+                auto start = Clock::now();
+                auto&& r = Detail::complete_invoke(fun, std::forward<Args>(args)...);
+                auto end = Clock::now();
+                auto delta = end - start;
+                return { delta, std::forward<decltype(r)>(r), 1 };
+            }
+        } // namespace Detail
+    } // namespace Benchmark
+} // namespace Catch
+
+#endif // TWOBLUECUBES_CATCH_DETAIL_MEASURE_HPP_INCLUDED
diff --git a/packages/Catch2/include/internal/benchmark/detail/catch_repeat.hpp b/packages/Catch2/include/internal/benchmark/detail/catch_repeat.hpp
new file mode 100644
index 000000000..ab240792b
--- /dev/null
+++ b/packages/Catch2/include/internal/benchmark/detail/catch_repeat.hpp
@@ -0,0 +1,37 @@
+/*
+ *  Created by Joachim on 16/04/2019.
+ *  Adapted from donated nonius code.
+ *
+ *  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)
+ */
+
+// repeat algorithm
+
+#ifndef TWOBLUECUBES_CATCH_DETAIL_REPEAT_HPP_INCLUDED
+#define TWOBLUECUBES_CATCH_DETAIL_REPEAT_HPP_INCLUDED
+
+#include <type_traits>
+#include <utility>
+
+namespace Catch {
+    namespace Benchmark {
+        namespace Detail {
+            template <typename Fun>
+            struct repeater {
+                void operator()(int k) const {
+                    for (int i = 0; i < k; ++i) {
+                        fun();
+                    }
+                }
+                Fun fun;
+            };
+            template <typename Fun>
+            repeater<typename std::decay<Fun>::type> repeat(Fun&& fun) {
+                return { std::forward<Fun>(fun) };
+            }
+        } // namespace Detail
+    } // namespace Benchmark
+} // namespace Catch
+
+#endif // TWOBLUECUBES_CATCH_DETAIL_REPEAT_HPP_INCLUDED
diff --git a/packages/Catch2/include/internal/benchmark/detail/catch_run_for_at_least.hpp b/packages/Catch2/include/internal/benchmark/detail/catch_run_for_at_least.hpp
new file mode 100644
index 000000000..a41c6b461
--- /dev/null
+++ b/packages/Catch2/include/internal/benchmark/detail/catch_run_for_at_least.hpp
@@ -0,0 +1,65 @@
+/*
+ *  Created by Joachim on 16/04/2019.
+ *  Adapted from donated nonius code.
+ *
+ *  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)
+ */
+
+// Run a function for a minimum amount of time
+
+#ifndef TWOBLUECUBES_CATCH_RUN_FOR_AT_LEAST_HPP_INCLUDED
+#define TWOBLUECUBES_CATCH_RUN_FOR_AT_LEAST_HPP_INCLUDED
+
+#include "../catch_clock.hpp"
+#include "../catch_chronometer.hpp"
+#include "catch_measure.hpp"
+#include "catch_complete_invoke.hpp"
+#include "catch_timing.hpp"
+#include "../../catch_meta.hpp"
+
+#include <utility>
+#include <type_traits>
+
+namespace Catch {
+    namespace Benchmark {
+        namespace Detail {
+            template <typename Clock, typename Fun>
+            TimingOf<Clock, Fun(int)> measure_one(Fun&& fun, int iters, std::false_type) {
+                return Detail::measure<Clock>(fun, iters);
+            }
+            template <typename Clock, typename Fun>
+            TimingOf<Clock, Fun(Chronometer)> measure_one(Fun&& fun, int iters, std::true_type) {
+                Detail::ChronometerModel<Clock> meter;
+                auto&& result = Detail::complete_invoke(fun, Chronometer(meter, iters));
+
+                return { meter.elapsed(), std::move(result), iters };
+            }
+
+            template <typename Clock, typename Fun>
+            using run_for_at_least_argument_t = typename std::conditional<is_callable<Fun(Chronometer)>::value, Chronometer, int>::type;
+
+            struct optimized_away_error : std::exception {
+                const char* what() const noexcept override {
+                    return "could not measure benchmark, maybe it was optimized away";
+                }
+            };
+
+            template <typename Clock, typename Fun>
+            TimingOf<Clock, Fun(run_for_at_least_argument_t<Clock, Fun>)> run_for_at_least(ClockDuration<Clock> how_long, int seed, Fun&& fun) {
+                auto iters = seed;
+                while (iters < (1 << 30)) {
+                    auto&& Timing = measure_one<Clock>(fun, iters, is_callable<Fun(Chronometer)>());
+
+                    if (Timing.elapsed >= how_long) {
+                        return { Timing.elapsed, std::move(Timing.result), iters };
+                    }
+                    iters *= 2;
+                }
+                throw optimized_away_error{};
+            }
+        } // namespace Detail
+    } // namespace Benchmark
+} // namespace Catch
+
+#endif // TWOBLUECUBES_CATCH_RUN_FOR_AT_LEAST_HPP_INCLUDED
diff --git a/packages/Catch2/include/internal/benchmark/detail/catch_stats.cpp b/packages/Catch2/include/internal/benchmark/detail/catch_stats.cpp
new file mode 100644
index 000000000..40e0ea984
--- /dev/null
+++ b/packages/Catch2/include/internal/benchmark/detail/catch_stats.cpp
@@ -0,0 +1,223 @@
+/*
+ *  Created by Martin on 15/06/2019.
+ *  Adapted from donated nonius code.
+ *
+ *  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)
+ */
+
+// Statistical analysis tools
+
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+
+#include "catch_stats.hpp"
+
+#include "../../catch_compiler_capabilities.h"
+
+#include <cassert>
+#include <random>
+
+
+#if defined(CATCH_CONFIG_USE_ASYNC)
+#include <future>
+#endif
+
+namespace {
+    double erf_inv(double x) {
+        // Code accompanying the article "Approximating the erfinv function" in GPU Computing Gems, Volume 2
+        double w, p;
+
+        w = -log((1.0 - x) * (1.0 + x));
+
+        if (w < 6.250000) {
+            w = w - 3.125000;
+            p = -3.6444120640178196996e-21;
+            p = -1.685059138182016589e-19 + p * w;
+            p = 1.2858480715256400167e-18 + p * w;
+            p = 1.115787767802518096e-17 + p * w;
+            p = -1.333171662854620906e-16 + p * w;
+            p = 2.0972767875968561637e-17 + p * w;
+            p = 6.6376381343583238325e-15 + p * w;
+            p = -4.0545662729752068639e-14 + p * w;
+            p = -8.1519341976054721522e-14 + p * w;
+            p = 2.6335093153082322977e-12 + p * w;
+            p = -1.2975133253453532498e-11 + p * w;
+            p = -5.4154120542946279317e-11 + p * w;
+            p = 1.051212273321532285e-09 + p * w;
+            p = -4.1126339803469836976e-09 + p * w;
+            p = -2.9070369957882005086e-08 + p * w;
+            p = 4.2347877827932403518e-07 + p * w;
+            p = -1.3654692000834678645e-06 + p * w;
+            p = -1.3882523362786468719e-05 + p * w;
+            p = 0.0001867342080340571352 + p * w;
+            p = -0.00074070253416626697512 + p * w;
+            p = -0.0060336708714301490533 + p * w;
+            p = 0.24015818242558961693 + p * w;
+            p = 1.6536545626831027356 + p * w;
+        } else if (w < 16.000000) {
+            w = sqrt(w) - 3.250000;
+            p = 2.2137376921775787049e-09;
+            p = 9.0756561938885390979e-08 + p * w;
+            p = -2.7517406297064545428e-07 + p * w;
+            p = 1.8239629214389227755e-08 + p * w;
+            p = 1.5027403968909827627e-06 + p * w;
+            p = -4.013867526981545969e-06 + p * w;
+            p = 2.9234449089955446044e-06 + p * w;
+            p = 1.2475304481671778723e-05 + p * w;
+            p = -4.7318229009055733981e-05 + p * w;
+            p = 6.8284851459573175448e-05 + p * w;
+            p = 2.4031110387097893999e-05 + p * w;
+            p = -0.0003550375203628474796 + p * w;
+            p = 0.00095328937973738049703 + p * w;
+            p = -0.0016882755560235047313 + p * w;
+            p = 0.0024914420961078508066 + p * w;
+            p = -0.0037512085075692412107 + p * w;
+            p = 0.005370914553590063617 + p * w;
+            p = 1.0052589676941592334 + p * w;
+            p = 3.0838856104922207635 + p * w;
+        } else {
+            w = sqrt(w) - 5.000000;
+            p = -2.7109920616438573243e-11;
+            p = -2.5556418169965252055e-10 + p * w;
+            p = 1.5076572693500548083e-09 + p * w;
+            p = -3.7894654401267369937e-09 + p * w;
+            p = 7.6157012080783393804e-09 + p * w;
+            p = -1.4960026627149240478e-08 + p * w;
+            p = 2.9147953450901080826e-08 + p * w;
+            p = -6.7711997758452339498e-08 + p * w;
+            p = 2.2900482228026654717e-07 + p * w;
+            p = -9.9298272942317002539e-07 + p * w;
+            p = 4.5260625972231537039e-06 + p * w;
+            p = -1.9681778105531670567e-05 + p * w;
+            p = 7.5995277030017761139e-05 + p * w;
+            p = -0.00021503011930044477347 + p * w;
+            p = -0.00013871931833623122026 + p * w;
+            p = 1.0103004648645343977 + p * w;
+            p = 4.8499064014085844221 + p * w;
+        }
+        return p * x;
+    }
+
+    double standard_deviation(std::vector<double>::iterator first, std::vector<double>::iterator last) {
+        auto m = Catch::Benchmark::Detail::mean(first, last);
+        double variance = std::accumulate(first, last, 0., [m](double a, double b) {
+            double diff = b - m;
+            return a + diff * diff;
+            }) / (last - first);
+            return std::sqrt(variance);
+    }
+
+}
+
+namespace Catch {
+    namespace Benchmark {
+        namespace Detail {
+
+            double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last) {
+                auto count = last - first;
+                double idx = (count - 1) * k / static_cast<double>(q);
+                int j = static_cast<int>(idx);
+                double g = idx - j;
+                std::nth_element(first, first + j, last);
+                auto xj = first[j];
+                if (g == 0) return xj;
+
+                auto xj1 = *std::min_element(first + (j + 1), last);
+                return xj + g * (xj1 - xj);
+            }
+
+
+            double erfc_inv(double x) {
+                return erf_inv(1.0 - x);
+            }
+
+            double normal_quantile(double p) {
+                static const double ROOT_TWO = std::sqrt(2.0);
+
+                double result = 0.0;
+                assert(p >= 0 && p <= 1);
+                if (p < 0 || p > 1) {
+                    return result;
+                }
+
+                result = -erfc_inv(2.0 * p);
+                // result *= normal distribution standard deviation (1.0) * sqrt(2)
+                result *= /*sd * */ ROOT_TWO;
+                // result += normal disttribution mean (0)
+                return result;
+            }
+
+
+            double outlier_variance(Estimate<double> mean, Estimate<double> stddev, int n) {
+                double sb = stddev.point;
+                double mn = mean.point / n;
+                double mg_min = mn / 2.;
+                double sg = std::min(mg_min / 4., sb / std::sqrt(n));
+                double sg2 = sg * sg;
+                double sb2 = sb * sb;
+
+                auto c_max = [n, mn, sb2, sg2](double x) -> double {
+                    double k = mn - x;
+                    double d = k * k;
+                    double nd = n * d;
+                    double k0 = -n * nd;
+                    double k1 = sb2 - n * sg2 + nd;
+                    double det = k1 * k1 - 4 * sg2 * k0;
+                    return (int)(-2. * k0 / (k1 + std::sqrt(det)));
+                };
+
+                auto var_out = [n, sb2, sg2](double c) {
+                    double nc = n - c;
+                    return (nc / n) * (sb2 - nc * sg2);
+                };
+
+                return std::min(var_out(1), var_out(std::min(c_max(0.), c_max(mg_min)))) / sb2;
+            }
+
+
+            bootstrap_analysis analyse_samples(double confidence_level, int n_resamples, std::vector<double>::iterator first, std::vector<double>::iterator last) {
+                CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
+                static std::random_device entropy;
+                CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
+
+                auto n = static_cast<int>(last - first); // seriously, one can't use integral types without hell in C++
+
+                auto mean = &Detail::mean<std::vector<double>::iterator>;
+                auto stddev = &standard_deviation;
+
+#if defined(CATCH_CONFIG_USE_ASYNC)
+                auto Estimate = [=](double(*f)(std::vector<double>::iterator, std::vector<double>::iterator)) {
+                    auto seed = entropy();
+                    return std::async(std::launch::async, [=] {
+                        std::mt19937 rng(seed);
+                        auto resampled = resample(rng, n_resamples, first, last, f);
+                        return bootstrap(confidence_level, first, last, resampled, f);
+                    });
+                };
+
+                auto mean_future = Estimate(mean);
+                auto stddev_future = Estimate(stddev);
+
+                auto mean_estimate = mean_future.get();
+                auto stddev_estimate = stddev_future.get();
+#else
+                auto Estimate = [=](double(*f)(std::vector<double>::iterator, std::vector<double>::iterator)) {
+                    auto seed = entropy();
+                    std::mt19937 rng(seed);
+                    auto resampled = resample(rng, n_resamples, first, last, f);
+                    return bootstrap(confidence_level, first, last, resampled, f);
+                };
+
+                auto mean_estimate = Estimate(mean);
+                auto stddev_estimate = Estimate(stddev);
+#endif // CATCH_USE_ASYNC
+
+                double outlier_variance = Detail::outlier_variance(mean_estimate, stddev_estimate, n);
+
+                return { mean_estimate, stddev_estimate, outlier_variance };
+            }
+        } // namespace Detail
+    } // namespace Benchmark
+} // namespace Catch
+
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
diff --git a/packages/Catch2/include/internal/benchmark/detail/catch_stats.hpp b/packages/Catch2/include/internal/benchmark/detail/catch_stats.hpp
new file mode 100644
index 000000000..e686c1aa5
--- /dev/null
+++ b/packages/Catch2/include/internal/benchmark/detail/catch_stats.hpp
@@ -0,0 +1,158 @@
+/*
+ *  Created by Joachim on 16/04/2019.
+ *  Adapted from donated nonius code.
+ *
+ *  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)
+ */
+
+// Statistical analysis tools
+
+#ifndef TWOBLUECUBES_CATCH_DETAIL_ANALYSIS_HPP_INCLUDED
+#define TWOBLUECUBES_CATCH_DETAIL_ANALYSIS_HPP_INCLUDED
+
+#include "../catch_clock.hpp"
+#include "../catch_estimate.hpp"
+#include "../catch_outlier_classification.hpp"
+
+#include <algorithm>
+#include <functional>
+#include <vector>
+#include <numeric>
+#include <tuple>
+#include <cmath>
+#include <utility>
+#include <cstddef>
+
+namespace Catch {
+    namespace Benchmark {
+        namespace Detail {
+            using sample = std::vector<double>;
+
+            double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last);
+
+            template <typename Iterator>
+            OutlierClassification classify_outliers(Iterator first, Iterator last) {
+                std::vector<double> copy(first, last);
+
+                auto q1 = weighted_average_quantile(1, 4, copy.begin(), copy.end());
+                auto q3 = weighted_average_quantile(3, 4, copy.begin(), copy.end());
+                auto iqr = q3 - q1;
+                auto los = q1 - (iqr * 3.);
+                auto lom = q1 - (iqr * 1.5);
+                auto him = q3 + (iqr * 1.5);
+                auto his = q3 + (iqr * 3.);
+
+                OutlierClassification o;
+                for (; first != last; ++first) {
+                    auto&& t = *first;
+                    if (t < los) ++o.low_severe;
+                    else if (t < lom) ++o.low_mild;
+                    else if (t > his) ++o.high_severe;
+                    else if (t > him) ++o.high_mild;
+                    ++o.samples_seen;
+                }
+                return o;
+            }
+
+            template <typename Iterator>
+            double mean(Iterator first, Iterator last) {
+                auto count = last - first;
+                double sum = std::accumulate(first, last, 0.);
+                return sum / count;
+            }
+
+            template <typename URng, typename Iterator, typename Estimator>
+            sample resample(URng& rng, int resamples, Iterator first, Iterator last, Estimator& estimator) {
+                auto n = last - first;
+                std::uniform_int_distribution<decltype(n)> dist(0, n - 1);
+
+                sample out;
+                out.reserve(resamples);
+                std::generate_n(std::back_inserter(out), resamples, [n, first, &estimator, &dist, &rng] {
+                    std::vector<double> resampled;
+                    resampled.reserve(n);
+                    std::generate_n(std::back_inserter(resampled), n, [first, &dist, &rng] { return first[dist(rng)]; });
+                    return estimator(resampled.begin(), resampled.end());
+                });
+                std::sort(out.begin(), out.end());
+                return out;
+            }
+
+            template <typename Estimator, typename Iterator>
+            sample jackknife(Estimator&& estimator, Iterator first, Iterator last) {
+                auto n = last - first;
+                auto second = std::next(first);
+                sample results;
+                results.reserve(n);
+
+                for (auto it = first; it != last; ++it) {
+                    std::iter_swap(it, first);
+                    results.push_back(estimator(second, last));
+                }
+
+                return results;
+            }
+
+            inline double normal_cdf(double x) {
+                return std::erfc(-x / std::sqrt(2.0)) / 2.0;
+            }
+
+            double erfc_inv(double x);
+
+            double normal_quantile(double p);
+
+            template <typename Iterator, typename Estimator>
+            Estimate<double> bootstrap(double confidence_level, Iterator first, Iterator last, sample const& resample, Estimator&& estimator) {
+                auto n_samples = last - first;
+
+                double point = estimator(first, last);
+                // Degenerate case with a single sample
+                if (n_samples == 1) return { point, point, point, confidence_level };
+
+                sample jack = jackknife(estimator, first, last);
+                double jack_mean = mean(jack.begin(), jack.end());
+                double sum_squares, sum_cubes;
+                std::tie(sum_squares, sum_cubes) = std::accumulate(jack.begin(), jack.end(), std::make_pair(0., 0.), [jack_mean](std::pair<double, double> sqcb, double x) -> std::pair<double, double> {
+                    auto d = jack_mean - x;
+                    auto d2 = d * d;
+                    auto d3 = d2 * d;
+                    return { sqcb.first + d2, sqcb.second + d3 };
+                });
+
+                double accel = sum_cubes / (6 * std::pow(sum_squares, 1.5));
+                int n = static_cast<int>(resample.size());
+                double prob_n = std::count_if(resample.begin(), resample.end(), [point](double x) { return x < point; }) / (double)n;
+                // degenerate case with uniform samples
+                if (prob_n == 0) return { point, point, point, confidence_level };
+
+                double bias = normal_quantile(prob_n);
+                double z1 = normal_quantile((1. - confidence_level) / 2.);
+
+                auto cumn = [n](double x) -> int {
+                    return std::lround(normal_cdf(x) * n); };
+                auto a = [bias, accel](double b) { return bias + b / (1. - accel * b); };
+                double b1 = bias + z1;
+                double b2 = bias - z1;
+                double a1 = a(b1);
+                double a2 = a(b2);
+                auto lo = std::max(cumn(a1), 0);
+                auto hi = std::min(cumn(a2), n - 1);
+
+                return { point, resample[lo], resample[hi], confidence_level };
+            }
+
+            double outlier_variance(Estimate<double> mean, Estimate<double> stddev, int n);
+
+            struct bootstrap_analysis {
+                Estimate<double> mean;
+                Estimate<double> standard_deviation;
+                double outlier_variance;
+            };
+
+            bootstrap_analysis analyse_samples(double confidence_level, int n_resamples, std::vector<double>::iterator first, std::vector<double>::iterator last);
+        } // namespace Detail
+    } // namespace Benchmark
+} // namespace Catch
+
+#endif // TWOBLUECUBES_CATCH_DETAIL_ANALYSIS_HPP_INCLUDED
diff --git a/packages/Catch2/include/internal/benchmark/detail/catch_timing.hpp b/packages/Catch2/include/internal/benchmark/detail/catch_timing.hpp
new file mode 100644
index 000000000..073cb7427
--- /dev/null
+++ b/packages/Catch2/include/internal/benchmark/detail/catch_timing.hpp
@@ -0,0 +1,33 @@
+/*
+ *  Created by Joachim on 16/04/2019.
+ *  Adapted from donated nonius code.
+ *
+ *  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)
+ */
+
+// Timing
+
+#ifndef TWOBLUECUBES_CATCH_DETAIL_TIMING_HPP_INCLUDED
+#define TWOBLUECUBES_CATCH_DETAIL_TIMING_HPP_INCLUDED
+
+#include "../catch_clock.hpp"
+#include "catch_complete_invoke.hpp"
+
+#include <tuple>
+#include <type_traits>
+
+namespace Catch {
+    namespace Benchmark {
+        template <typename Duration, typename Result>
+        struct Timing {
+            Duration elapsed;
+            Result result;
+            int iterations;
+        };
+        template <typename Clock, typename Sig>
+        using TimingOf = Timing<ClockDuration<Clock>, Detail::CompleteType_t<Detail::ResultOf_t<Sig>>>;
+    } // namespace Benchmark
+} // namespace Catch
+
+#endif // TWOBLUECUBES_CATCH_DETAIL_TIMING_HPP_INCLUDED
diff --git a/packages/Catch2/include/internal/catch_approx.cpp b/packages/Catch2/include/internal/catch_approx.cpp
index a7d7111ca..32b5e0437 100644
--- a/packages/Catch2/include/internal/catch_approx.cpp
+++ b/packages/Catch2/include/internal/catch_approx.cpp
@@ -52,21 +52,22 @@ namespace Detail {
     bool Approx::equalityComparisonImpl(const double other) const {
         // First try with fixed margin, then compute margin based on epsilon, scale and Approx's value
         // Thanks to Richard Harris for his help refining the scaled margin value
-        return marginComparison(m_value, other, m_margin) || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(m_value)));
+        return marginComparison(m_value, other, m_margin)
+            || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(std::isinf(m_value)? 0 : m_value)));
     }
 
-    void Approx::setMargin(double margin) {
-        CATCH_ENFORCE(margin >= 0,
-            "Invalid Approx::margin: " << margin << '.'
+    void Approx::setMargin(double newMargin) {
+        CATCH_ENFORCE(newMargin >= 0,
+            "Invalid Approx::margin: " << newMargin << '.'
             << " Approx::Margin has to be non-negative.");
-        m_margin = margin;
+        m_margin = newMargin;
     }
 
-    void Approx::setEpsilon(double epsilon) {
-        CATCH_ENFORCE(epsilon >= 0 && epsilon <= 1.0,
-            "Invalid Approx::epsilon: " << epsilon << '.'
+    void Approx::setEpsilon(double newEpsilon) {
+        CATCH_ENFORCE(newEpsilon >= 0 && newEpsilon <= 1.0,
+            "Invalid Approx::epsilon: " << newEpsilon << '.'
             << " Approx::epsilon has to be in [0, 1]");
-        m_epsilon = epsilon;
+        m_epsilon = newEpsilon;
     }
 
 } // end namespace Detail
diff --git a/packages/Catch2/include/internal/catch_assertionresult.cpp b/packages/Catch2/include/internal/catch_assertionresult.cpp
index 4ce071876..608a9add6 100644
--- a/packages/Catch2/include/internal/catch_assertionresult.cpp
+++ b/packages/Catch2/include/internal/catch_assertionresult.cpp
@@ -45,7 +45,7 @@ namespace Catch {
     }
 
     bool AssertionResult::hasExpression() const {
-        return m_info.capturedExpression[0] != 0;
+        return !m_info.capturedExpression.empty();
     }
 
     bool AssertionResult::hasMessage() const {
@@ -53,16 +53,22 @@ namespace Catch {
     }
 
     std::string AssertionResult::getExpression() const {
-        if( isFalseTest( m_info.resultDisposition ) )
-            return "!(" + m_info.capturedExpression + ")";
-        else
-            return m_info.capturedExpression;
+        // Possibly overallocating by 3 characters should be basically free
+        std::string expr; expr.reserve(m_info.capturedExpression.size() + 3);
+        if (isFalseTest(m_info.resultDisposition)) {
+            expr += "!(";
+        }
+        expr += m_info.capturedExpression;
+        if (isFalseTest(m_info.resultDisposition)) {
+            expr += ')';
+        }
+        return expr;
     }
 
     std::string AssertionResult::getExpressionInMacro() const {
         std::string expr;
-        if( m_info.macroName[0] == 0 )
-            expr = m_info.capturedExpression;
+        if( m_info.macroName.empty() )
+            expr = static_cast<std::string>(m_info.capturedExpression);
         else {
             expr.reserve( m_info.macroName.size() + m_info.capturedExpression.size() + 4 );
             expr += m_info.macroName;
diff --git a/packages/Catch2/include/internal/catch_benchmark.cpp b/packages/Catch2/include/internal/catch_benchmark.cpp
deleted file mode 100644
index 742418f7f..000000000
--- a/packages/Catch2/include/internal/catch_benchmark.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- *  Created by Phil on 04/07/2017.
- *  Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
- *
- *  Distributed under the Boost Software License, Version 1.0. (See accompanying
- *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- */
-
-#include "catch_benchmark.h"
-#include "catch_capture.hpp"
-#include "catch_interfaces_reporter.h"
-#include "catch_context.h"
-
-namespace Catch {
-
-    auto BenchmarkLooper::getResolution() -> uint64_t {
-        return getEstimatedClockResolution() * getCurrentContext().getConfig()->benchmarkResolutionMultiple();
-    }
-
-    void BenchmarkLooper::reportStart() {
-        getResultCapture().benchmarkStarting( { m_name } );
-    }
-    auto BenchmarkLooper::needsMoreIterations() -> bool {
-        auto elapsed = m_timer.getElapsedNanoseconds();
-
-        // Exponentially increasing iterations until we're confident in our timer resolution
-        if( elapsed < m_resolution ) {
-            m_iterationsToRun *= 10;
-            return true;
-        }
-
-        getResultCapture().benchmarkEnded( { { m_name }, m_count, elapsed } );
-        return false;
-    }
-
-} // end namespace Catch
diff --git a/packages/Catch2/include/internal/catch_benchmark.h b/packages/Catch2/include/internal/catch_benchmark.h
deleted file mode 100644
index e546713cf..000000000
--- a/packages/Catch2/include/internal/catch_benchmark.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- *  Created by Phil on 04/07/2017.
- *  Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
- *
- *  Distributed under the Boost Software License, Version 1.0. (See accompanying
- *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- */
-#ifndef TWOBLUECUBES_CATCH_BENCHMARK_H_INCLUDED
-#define TWOBLUECUBES_CATCH_BENCHMARK_H_INCLUDED
-
-#include "catch_stringref.h"
-#include "catch_timer.h"
-
-#include <cstdint>
-#include <string>
-
-namespace Catch {
-
-    class BenchmarkLooper {
-
-        std::string m_name;
-        std::size_t m_count = 0;
-        std::size_t m_iterationsToRun = 1;
-        uint64_t m_resolution;
-        Timer m_timer;
-
-        static auto getResolution() -> uint64_t;
-    public:
-        // Keep most of this inline as it's on the code path that is being timed
-        BenchmarkLooper( StringRef name )
-        :   m_name( name ),
-            m_resolution( getResolution() )
-        {
-            reportStart();
-            m_timer.start();
-        }
-
-        explicit operator bool() {
-            if( m_count < m_iterationsToRun )
-                return true;
-            return needsMoreIterations();
-        }
-
-        void increment() {
-            ++m_count;
-        }
-
-        void reportStart();
-        auto needsMoreIterations() -> bool;
-    };
-
-} // end namespace Catch
-
-#define BENCHMARK( name ) \
-    for( Catch::BenchmarkLooper looper( name ); looper; looper.increment() )
-
-#endif // TWOBLUECUBES_CATCH_BENCHMARK_H_INCLUDED
diff --git a/packages/Catch2/include/internal/catch_capture_matchers.h b/packages/Catch2/include/internal/catch_capture_matchers.h
index 0ced01d57..5386e5e17 100644
--- a/packages/Catch2/include/internal/catch_capture_matchers.h
+++ b/packages/Catch2/include/internal/catch_capture_matchers.h
@@ -10,6 +10,7 @@
 
 #include "catch_capture.hpp"
 #include "catch_matchers.h"
+#include "catch_matchers_exception.hpp"
 #include "catch_matchers_floating.h"
 #include "catch_matchers_generic.hpp"
 #include "catch_matchers_string.h"
diff --git a/packages/Catch2/include/internal/catch_commandline.cpp b/packages/Catch2/include/internal/catch_commandline.cpp
index 66759ebbf..365a3c9d6 100644
--- a/packages/Catch2/include/internal/catch_commandline.cpp
+++ b/packages/Catch2/include/internal/catch_commandline.cpp
@@ -49,9 +49,15 @@ namespace Catch {
                     if( !line.empty() && !startsWith( line, '#' ) ) {
                         if( !startsWith( line, '"' ) )
                             line = '"' + line + '"';
-                        config.testsOrTags.push_back( line + ',' );
+                        config.testsOrTags.push_back( line );
+                        config.testsOrTags.push_back( "," );
+                        
                     }
                 }
+                //Remove comma in the end
+                if(!config.testsOrTags.empty())
+                    config.testsOrTags.erase( config.testsOrTags.end()-1 );
+                
                 return ParserResult::ok( ParseResultType::Matched );
             };
         auto const setTestOrder = [&]( std::string const& order ) {
@@ -196,11 +202,19 @@ namespace Catch {
             | Opt( setWaitForKeypress, "start|exit|both" )
                 ["--wait-for-keypress"]
                 ( "waits for a keypress before exiting" )
-            | Opt( config.benchmarkResolutionMultiple, "multiplier" )
-                ["--benchmark-resolution-multiple"]
-                ( "multiple of clock resolution to run benchmarks" )
-
-            | Arg( config.testsOrTags, "test name|pattern|tags" )
+            | Opt( config.benchmarkSamples, "samples" )
+                ["--benchmark-samples"]
+                ( "number of samples to collect (default: 100)" )
+            | Opt( config.benchmarkResamples, "resamples" )
+                ["--benchmark-resamples"]
+                ( "number of resamples for the bootstrap (default: 100000)" )
+            | Opt( config.benchmarkConfidenceInterval, "confidence interval" )
+                ["--benchmark-confidence-interval"]
+                ( "confidence interval for the bootstrap (between 0 and 1, default: 0.95)" )
+            | Opt( config.benchmarkNoAnalysis )
+                ["--benchmark-no-analysis"]
+                ( "perform only measurements; do not perform any analysis" )
+			| Arg( config.testsOrTags, "test name|pattern|tags" )
                 ( "which test or tests to use" );
 
         return cli;
diff --git a/packages/Catch2/include/internal/catch_common.cpp b/packages/Catch2/include/internal/catch_common.cpp
index b2fca4c4c..790acbe53 100644
--- a/packages/Catch2/include/internal/catch_common.cpp
+++ b/packages/Catch2/include/internal/catch_common.cpp
@@ -15,9 +15,6 @@
 
 namespace Catch {
 
-    bool SourceLineInfo::empty() const noexcept {
-        return file[0] == '\0';
-    }
     bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const noexcept {
         return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0);
     }
diff --git a/packages/Catch2/include/internal/catch_common.h b/packages/Catch2/include/internal/catch_common.h
index e47456220..5e097fbf8 100644
--- a/packages/Catch2/include/internal/catch_common.h
+++ b/packages/Catch2/include/internal/catch_common.h
@@ -57,7 +57,7 @@ namespace Catch {
         SourceLineInfo( SourceLineInfo&& )              noexcept = default;
         SourceLineInfo& operator = ( SourceLineInfo&& ) noexcept = default;
 
-        bool empty() const noexcept;
+        bool empty() const noexcept { return file[0] == '\0'; }
         bool operator == ( SourceLineInfo const& other ) const noexcept;
         bool operator < ( SourceLineInfo const& other ) const noexcept;
 
diff --git a/packages/Catch2/include/internal/catch_compiler_capabilities.h b/packages/Catch2/include/internal/catch_compiler_capabilities.h
index 012bf462a..4daa5e8ff 100644
--- a/packages/Catch2/include/internal/catch_compiler_capabilities.h
+++ b/packages/Catch2/include/internal/catch_compiler_capabilities.h
@@ -64,6 +64,17 @@
 #       define CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS \
             _Pragma( "clang diagnostic pop" )
 
+#       define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
+            _Pragma( "clang diagnostic push" ) \
+            _Pragma( "clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"" )
+#       define CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS \
+            _Pragma( "clang diagnostic pop" )
+
+#       define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
+            _Pragma( "clang diagnostic push" ) \
+            _Pragma( "clang diagnostic ignored \"-Wunused-template\"" )
+#       define CATCH_INTERNAL_UNSUPPRESS_UNUSED_TEMPLATE_WARNINGS \
+            _Pragma( "clang diagnostic pop" )
 #endif // __clang__
 
 
@@ -88,6 +99,7 @@
 // Android somehow still does not support std::to_string
 #if defined(__ANDROID__)
 #    define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
+#    define CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE
 #endif
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -109,12 +121,12 @@
 // 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. 
+// 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))
+           && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))
 
-#	define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
+#    define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
 
 # endif
 #endif // __CYGWIN__
@@ -142,7 +154,11 @@
 #  if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL)
 #    define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
 #  endif
+#endif // _MSC_VER
 
+#if defined(_REENTRANT) || defined(_MSC_VER)
+// Enable async processing, as -pthread is specified or no additional linking is required
+# define CATCH_INTERNAL_CONFIG_USE_ASYNC
 #endif // _MSC_VER
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -174,41 +190,55 @@
     #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
+
+// RTX is a special version of Windows that is real time.
+// This means that it is detected as Windows, but does not provide
+// the same set of capabilities as real Windows does.
+#if defined(UNDER_RTSS) || defined(RTX64_BUILD)
+    #define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
+    #define CATCH_INTERNAL_CONFIG_NO_ASYNC
+    #define CATCH_CONFIG_COLOUR_NONE
 #endif
 
-////////////////////////////////////////////////////////////////////////////////
-// Check if optional is available and usable
-#if defined(__has_include)
-#  if __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
-#    define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL
-#  endif // __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
-#endif // __has_include
+#if defined(__UCLIBC__)
+#define CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER
+#endif
 
-////////////////////////////////////////////////////////////////////////////////
-// Check if variant is available and usable
+// Various stdlib support checks that require __has_include
 #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)
-#    else
-#      define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
-#    endif // defined(__clang__) && (__clang_major__ < 8)
-#  endif // __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
-#endif // __has_include
+  // Check if string_view is available and usable
+  #if __has_include(<string_view>) && defined(CATCH_CPP17_OR_GREATER)
+  #    define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW
+  #endif
+
+  // Check if optional is available and usable
+  #  if __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
+  #    define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL
+  #  endif // __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
+
+  // Check if byte is available and usable
+  #  if __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
+  #    define CATCH_INTERNAL_CONFIG_CPP17_BYTE
+  #  endif // __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
+
+  // Check if variant is available and usable
+  #  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)
+  #    else
+  #      define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
+  #    endif // defined(__clang__) && (__clang_major__ < 8)
+  #  endif // __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
+#endif // defined(__has_include)
 
 
 #if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
@@ -246,6 +276,11 @@
 #  define CATCH_CONFIG_CPP17_VARIANT
 #endif
 
+#if defined(CATCH_INTERNAL_CONFIG_CPP17_BYTE) && !defined(CATCH_CONFIG_NO_CPP17_BYTE) && !defined(CATCH_CONFIG_CPP17_BYTE)
+#  define CATCH_CONFIG_CPP17_BYTE
+#endif
+
+
 #if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
 #  define CATCH_INTERNAL_CONFIG_NEW_CAPTURE
 #endif
@@ -262,6 +297,18 @@
 #  define CATCH_CONFIG_POLYFILL_ISNAN
 #endif
 
+#if defined(CATCH_INTERNAL_CONFIG_USE_ASYNC)  && !defined(CATCH_INTERNAL_CONFIG_NO_ASYNC) && !defined(CATCH_CONFIG_NO_USE_ASYNC) && !defined(CATCH_CONFIG_USE_ASYNC)
+#  define CATCH_CONFIG_USE_ASYNC
+#endif
+
+#if defined(CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_NO_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_ANDROID_LOGWRITE)
+#  define CATCH_CONFIG_ANDROID_LOGWRITE
+#endif
+
+#if defined(CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_NO_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
+#  define CATCH_CONFIG_GLOBAL_NEXTAFTER
+#endif
+
 #if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
 #   define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
 #   define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS
@@ -274,6 +321,23 @@
 #   define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS
 #   define CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS
 #endif
+#if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS)
+#   define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS
+#   define CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS
+#endif
+
+#if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10)
+#   undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
+#   undef CATCH_INTERNAL_UNSUPPRESS_UNUSED_TEMPLATE_WARNINGS
+#elif defined(__clang__) && (__clang_major__ < 5)
+#   undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
+#   undef CATCH_INTERNAL_UNSUPPRESS_UNUSED_TEMPLATE_WARNINGS
+#endif
+
+#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS)
+#   define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
+#   define CATCH_INTERNAL_UNSUPPRESS_UNUSED_TEMPLATE_WARNINGS
+#endif
 
 #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
 #define CATCH_TRY if ((true))
diff --git a/packages/Catch2/include/internal/catch_config.cpp b/packages/Catch2/include/internal/catch_config.cpp
index d9ee9182b..e222328b9 100644
--- a/packages/Catch2/include/internal/catch_config.cpp
+++ b/packages/Catch2/include/internal/catch_config.cpp
@@ -15,11 +15,23 @@ namespace Catch {
     :   m_data( data ),
         m_stream( openStream() )
     {
+        // We need to trim filter specs to avoid trouble with superfluous
+        // whitespace (esp. important for bdd macros, as those are manually
+        // aligned with whitespace).
+
+        for (auto& elem : m_data.testsOrTags) {
+            elem = trim(elem);
+        }
+        for (auto& elem : m_data.sectionsToRun) {
+            elem = trim(elem);
+        }
+
         TestSpecParser parser(ITagAliasRegistry::get());
-        if (!data.testsOrTags.empty()) {
+        if (!m_data.testsOrTags.empty()) {
             m_hasTestFilters = true;
-            for( auto const& testOrTags : data.testsOrTags )
-                parser.parse( testOrTags );
+            for (auto const& testOrTags : m_data.testsOrTags) {
+                parser.parse(testOrTags);
+            }
         }
         m_testSpec = parser.testSpec();
     }
@@ -54,13 +66,17 @@ namespace Catch {
     ShowDurations::OrNot Config::showDurations() const { return m_data.showDurations; }
     RunTests::InWhatOrder Config::runOrder() const     { return m_data.runOrder; }
     unsigned int Config::rngSeed() const               { return m_data.rngSeed; }
-    int Config::benchmarkResolutionMultiple() const    { return m_data.benchmarkResolutionMultiple; }
     UseColour::YesOrNo Config::useColour() const       { return m_data.useColour; }
     bool Config::shouldDebugBreak() const              { return m_data.shouldDebugBreak; }
     int Config::abortAfter() const                     { return m_data.abortAfter; }
     bool Config::showInvisibles() const                { return m_data.showInvisibles; }
     Verbosity Config::verbosity() const                { return m_data.verbosity; }
 
+    bool Config::benchmarkNoAnalysis() const           { return m_data.benchmarkNoAnalysis; }
+    int Config::benchmarkSamples() const               { return m_data.benchmarkSamples; }
+    double Config::benchmarkConfidenceInterval() const { return m_data.benchmarkConfidenceInterval; }
+    unsigned int Config::benchmarkResamples() const    { return m_data.benchmarkResamples; }
+
     IStream const* Config::openStream() {
         return Catch::makeStream(m_data.outputFilename);
     }
diff --git a/packages/Catch2/include/internal/catch_config.hpp b/packages/Catch2/include/internal/catch_config.hpp
index 953badbdc..95b67d25f 100644
--- a/packages/Catch2/include/internal/catch_config.hpp
+++ b/packages/Catch2/include/internal/catch_config.hpp
@@ -42,7 +42,11 @@ namespace Catch {
 
         int abortAfter = -1;
         unsigned int rngSeed = 0;
-        int benchmarkResolutionMultiple = 100;
+
+        bool benchmarkNoAnalysis = false;
+        unsigned int benchmarkSamples = 100;
+        double benchmarkConfidenceInterval = 0.95;
+        unsigned int benchmarkResamples = 100000;
 
         Verbosity verbosity = Verbosity::Normal;
         WarnAbout::What warnings = WarnAbout::Nothing;
@@ -85,7 +89,7 @@ namespace Catch {
         std::vector<std::string> const& getTestsOrTags() const override;
         std::vector<std::string> const& getSectionsToRun() const override;
 
-        virtual TestSpec const& testSpec() const override;
+        TestSpec const& testSpec() const override;
         bool hasTestFilters() const override;
 
         bool showHelp() const;
@@ -100,12 +104,15 @@ namespace Catch {
         ShowDurations::OrNot showDurations() const override;
         RunTests::InWhatOrder runOrder() const override;
         unsigned int rngSeed() const override;
-        int benchmarkResolutionMultiple() const override;
         UseColour::YesOrNo useColour() const override;
         bool shouldDebugBreak() const override;
         int abortAfter() const override;
         bool showInvisibles() const override;
         Verbosity verbosity() const override;
+        bool benchmarkNoAnalysis() const override;
+        int benchmarkSamples() const override;
+        double benchmarkConfidenceInterval() const override;
+        unsigned int benchmarkResamples() const override;
 
     private:
 
diff --git a/packages/Catch2/include/internal/catch_console_colour.cpp b/packages/Catch2/include/internal/catch_console_colour.cpp
index 07072db6f..1c4799f82 100644
--- a/packages/Catch2/include/internal/catch_console_colour.cpp
+++ b/packages/Catch2/include/internal/catch_console_colour.cpp
@@ -69,7 +69,7 @@ namespace {
             originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY );
         }
 
-        virtual void use( Colour::Code _colourCode ) override {
+        void use( Colour::Code _colourCode ) override {
             switch( _colourCode ) {
                 case Colour::None:      return setTextAttribute( originalForegroundAttributes );
                 case Colour::White:     return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
@@ -132,7 +132,7 @@ namespace {
     // https://github.com/philsquared/Catch/pull/131
     class PosixColourImpl : public IColourImpl {
     public:
-        virtual void use( Colour::Code _colourCode ) override {
+        void use( Colour::Code _colourCode ) override {
             switch( _colourCode ) {
                 case Colour::None:
                 case Colour::White:     return setColour( "[0m" );
@@ -222,7 +222,13 @@ namespace Catch {
 
     void Colour::use( Code _colourCode ) {
         static IColourImpl* impl = platformColourInstance();
-        impl->use( _colourCode );
+        // Strictly speaking, this cannot possibly happen.
+        // However, under some conditions it does happen (see #1626),
+        // and this change is small enough that we can let practicality
+        // triumph over purity in this case.
+        if (impl != NULL) {
+            impl->use( _colourCode );
+        }
     }
 
     std::ostream& operator << ( std::ostream& os, Colour const& ) {
diff --git a/packages/Catch2/include/internal/catch_context.cpp b/packages/Catch2/include/internal/catch_context.cpp
index e116f28f5..e444a6b3f 100644
--- a/packages/Catch2/include/internal/catch_context.cpp
+++ b/packages/Catch2/include/internal/catch_context.cpp
@@ -7,33 +7,34 @@
  */
 #include "catch_context.h"
 #include "catch_common.h"
+#include "catch_random_number_generator.h"
 
 namespace Catch {
 
     class Context : public IMutableContext, NonCopyable {
 
     public: // IContext
-        virtual IResultCapture* getResultCapture() override {
+        IResultCapture* getResultCapture() override {
             return m_resultCapture;
         }
-        virtual IRunner* getRunner() override {
+        IRunner* getRunner() override {
             return m_runner;
         }
 
-        virtual IConfigPtr const& getConfig() const override {
+        IConfigPtr const& getConfig() const override {
             return m_config;
         }
 
-        virtual ~Context() override;
+        ~Context() override;
 
     public: // IMutableContext
-        virtual void setResultCapture( IResultCapture* resultCapture ) override {
+        void setResultCapture( IResultCapture* resultCapture ) override {
             m_resultCapture = resultCapture;
         }
-        virtual void setRunner( IRunner* runner ) override {
+        void setRunner( IRunner* runner ) override {
             m_runner = runner;
         }
-        virtual void setConfig( IConfigPtr const& config ) override {
+        void setConfig( IConfigPtr const& config ) override {
             m_config = config;
         }
 
@@ -59,4 +60,11 @@ namespace Catch {
     IContext::~IContext() = default;
     IMutableContext::~IMutableContext() = default;
     Context::~Context() = default;
+
+
+    SimplePcg32& rng() {
+        static SimplePcg32 s_rng;
+        return s_rng;
+    }
+
 }
diff --git a/packages/Catch2/include/internal/catch_context.h b/packages/Catch2/include/internal/catch_context.h
index 3d3c6bad4..c579c3992 100644
--- a/packages/Catch2/include/internal/catch_context.h
+++ b/packages/Catch2/include/internal/catch_context.h
@@ -46,6 +46,7 @@ namespace Catch {
     {
         if( !IMutableContext::currentContext )
             IMutableContext::createContext();
+        // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn)
         return *IMutableContext::currentContext;
     }
 
@@ -55,6 +56,9 @@ namespace Catch {
     }
 
     void cleanUpContext();
+
+    class SimplePcg32;
+    SimplePcg32& rng();
 }
 
 #endif // TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED
diff --git a/packages/Catch2/include/internal/catch_debug_console.cpp b/packages/Catch2/include/internal/catch_debug_console.cpp
index 5d25f651c..a341d8108 100644
--- a/packages/Catch2/include/internal/catch_debug_console.cpp
+++ b/packages/Catch2/include/internal/catch_debug_console.cpp
@@ -7,11 +7,21 @@
  */
 
 #include "catch_debug_console.h"
+#include "catch_compiler_capabilities.h"
 #include "catch_stream.h"
 #include "catch_platform.h"
 #include "catch_windows_h_proxy.h"
 
-#ifdef CATCH_PLATFORM_WINDOWS
+#if defined(CATCH_CONFIG_ANDROID_LOGWRITE)
+#include <android/log.h>
+
+    namespace Catch {
+        void writeToDebugConsole( std::string const& text ) {
+            __android_log_write( ANDROID_LOG_DEBUG, "Catch", text.c_str() );
+        }
+    }
+
+#elif defined(CATCH_PLATFORM_WINDOWS)
 
     namespace Catch {
         void writeToDebugConsole( std::string const& text ) {
diff --git a/packages/Catch2/include/internal/catch_enforce.cpp b/packages/Catch2/include/internal/catch_enforce.cpp
index f4db1c150..903d43be2 100644
--- a/packages/Catch2/include/internal/catch_enforce.cpp
+++ b/packages/Catch2/include/internal/catch_enforce.cpp
@@ -7,6 +7,9 @@
 
 #include "catch_enforce.h"
 
+#include <stdexcept>
+
+
 namespace Catch {
 #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS_CUSTOM_HANDLER)
     [[noreturn]]
@@ -16,4 +19,22 @@ namespace Catch {
         std::terminate();
     }
 #endif
+
+    [[noreturn]]
+    void throw_logic_error(std::string const& msg) {
+        throw_exception(std::logic_error(msg));
+    }
+
+    [[noreturn]]
+    void throw_domain_error(std::string const& msg) {
+        throw_exception(std::domain_error(msg));
+    }
+
+    [[noreturn]]
+    void throw_runtime_error(std::string const& msg) {
+        throw_exception(std::runtime_error(msg));
+    }
+
+
+
 } // namespace Catch;
diff --git a/packages/Catch2/include/internal/catch_enforce.h b/packages/Catch2/include/internal/catch_enforce.h
index 006940230..0484724d2 100644
--- a/packages/Catch2/include/internal/catch_enforce.h
+++ b/packages/Catch2/include/internal/catch_enforce.h
@@ -11,8 +11,7 @@
 #include "catch_compiler_capabilities.h"
 #include "catch_stream.h"
 
-
-#include <stdexcept>
+#include <exception>
 
 namespace Catch {
 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
@@ -25,18 +24,30 @@ namespace Catch {
     [[noreturn]]
     void throw_exception(std::exception const& e);
 #endif
+
+    [[noreturn]]
+    void throw_logic_error(std::string const& msg);
+    [[noreturn]]
+    void throw_domain_error(std::string const& msg);
+    [[noreturn]]
+    void throw_runtime_error(std::string const& msg);
+
 } // 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)
+#define CATCH_MAKE_MSG(...) \
+    (Catch::ReusableStringStream() << __VA_ARGS__).str()
+
+#define CATCH_INTERNAL_ERROR(...) \
+    Catch::throw_logic_error(CATCH_MAKE_MSG( CATCH_INTERNAL_LINEINFO << ": Internal Catch2 error: " << __VA_ARGS__))
+
+#define CATCH_ERROR(...) \
+    Catch::throw_domain_error(CATCH_MAKE_MSG( __VA_ARGS__ ))
+
+#define CATCH_RUNTIME_ERROR(...) \
+    Catch::throw_runtime_error(CATCH_MAKE_MSG( __VA_ARGS__ ))
+
+#define CATCH_ENFORCE( condition, ... ) \
+    do{ if( !(condition) ) CATCH_ERROR( __VA_ARGS__ ); } while(false)
 
 
 #endif // TWOBLUECUBES_CATCH_ENFORCE_H_INCLUDED
diff --git a/packages/Catch2/include/internal/catch_enum_values_registry.cpp b/packages/Catch2/include/internal/catch_enum_values_registry.cpp
new file mode 100644
index 000000000..fb060f5b4
--- /dev/null
+++ b/packages/Catch2/include/internal/catch_enum_values_registry.cpp
@@ -0,0 +1,75 @@
+/*
+ *  Created by Phil on 4/4/2019.
+ *  Copyright 2019 Two Blue Cubes Ltd. All rights reserved.
+ *
+ *  Distributed under the Boost Software License, Version 1.0. (See accompanying
+ *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+#include "catch_enum_values_registry.h"
+#include "catch_string_manip.h"
+#include "catch_stream.h"
+
+#include <map>
+#include <cassert>
+
+namespace Catch {
+
+    IMutableEnumValuesRegistry::~IMutableEnumValuesRegistry() {}
+
+    namespace Detail {
+
+        namespace {
+            // Extracts the actual name part of an enum instance
+            // In other words, it returns the Blue part of Bikeshed::Colour::Blue
+            StringRef extractInstanceName(StringRef enumInstance) {
+                // Find last occurence of ":"
+                size_t name_start = enumInstance.size();
+                while (name_start > 0 && enumInstance[name_start - 1] != ':') {
+                    --name_start;
+                }
+                return enumInstance.substr(name_start, enumInstance.size() - name_start);
+            }
+        }
+
+        std::vector<StringRef> parseEnums( StringRef enums ) {
+            auto enumValues = splitStringRef( enums, ',' );
+            std::vector<StringRef> parsed;
+            parsed.reserve( enumValues.size() );
+            for( auto const& enumValue : enumValues ) {
+                parsed.push_back(trim(extractInstanceName(enumValue)));
+            }
+            return parsed;
+        }
+
+        EnumInfo::~EnumInfo() {}
+
+        StringRef EnumInfo::lookup( int value ) const {
+            for( auto const& valueToName : m_values ) {
+                if( valueToName.first == value )
+                    return valueToName.second;
+            }
+            return "{** unexpected enum value **}"_sr;
+        }
+
+        std::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) {
+            std::unique_ptr<EnumInfo> enumInfo( new EnumInfo );
+            enumInfo->m_name = enumName;
+            enumInfo->m_values.reserve( values.size() );
+
+            const auto valueNames = Catch::Detail::parseEnums( allValueNames );
+            assert( valueNames.size() == values.size() );
+            std::size_t i = 0;
+            for( auto value : values )
+                enumInfo->m_values.push_back({ value, valueNames[i++] });
+
+            return enumInfo;
+        }
+
+        EnumInfo const& EnumValuesRegistry::registerEnum( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) {
+            m_enumInfos.push_back(makeEnumInfo(enumName, allValueNames, values));
+            return *m_enumInfos.back();
+        }
+
+    } // Detail
+} // Catch
+
diff --git a/packages/Catch2/include/internal/catch_enum_values_registry.h b/packages/Catch2/include/internal/catch_enum_values_registry.h
new file mode 100644
index 000000000..ae252fbf3
--- /dev/null
+++ b/packages/Catch2/include/internal/catch_enum_values_registry.h
@@ -0,0 +1,35 @@
+/*
+ *  Created by Phil on 4/4/2019.
+ *  Copyright 2019 Two Blue Cubes Ltd. All rights reserved.
+ *
+ *  Distributed under the Boost Software License, Version 1.0. (See accompanying
+ *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+#ifndef TWOBLUECUBES_CATCH_ENUMVALUESREGISTRY_H_INCLUDED
+#define TWOBLUECUBES_CATCH_ENUMVALUESREGISTRY_H_INCLUDED
+
+#include "catch_interfaces_enum_values_registry.h"
+
+#include <vector>
+#include <memory>
+
+namespace Catch {
+
+    namespace Detail {
+
+        std::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values );
+
+        class EnumValuesRegistry : public IMutableEnumValuesRegistry {
+
+            std::vector<std::unique_ptr<EnumInfo>> m_enumInfos;
+
+            EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector<int> const& values) override;
+        };
+
+        std::vector<StringRef> parseEnums( StringRef enums );
+
+    } // Detail
+
+} // Catch
+
+#endif //TWOBLUECUBES_CATCH_ENUMVALUESREGISTRY_H_INCLUDED
\ No newline at end of file
diff --git a/packages/Catch2/include/internal/catch_exception_translator_registry.h b/packages/Catch2/include/internal/catch_exception_translator_registry.h
index da2f4f12f..bb07c1313 100644
--- a/packages/Catch2/include/internal/catch_exception_translator_registry.h
+++ b/packages/Catch2/include/internal/catch_exception_translator_registry.h
@@ -19,7 +19,7 @@ namespace Catch {
     public:
         ~ExceptionTranslatorRegistry();
         virtual void registerTranslator( const IExceptionTranslator* translator );
-        virtual std::string translateActiveException() const override;
+        std::string translateActiveException() const override;
         std::string tryTranslators() const;
 
     private:
diff --git a/packages/Catch2/include/internal/catch_fatal_condition.cpp b/packages/Catch2/include/internal/catch_fatal_condition.cpp
index cea271f38..1eb6bb875 100644
--- a/packages/Catch2/include/internal/catch_fatal_condition.cpp
+++ b/packages/Catch2/include/internal/catch_fatal_condition.cpp
@@ -97,7 +97,7 @@ namespace Catch {
     
     // 32kb for the alternate stack seems to be sufficient. However, this value
     // is experimentally determined, so that's not guaranteed.
-    constexpr static std::size_t sigStackSize = 32768 >= MINSIGSTKSZ ? 32768 : MINSIGSTKSZ;
+    static constexpr std::size_t sigStackSize = 32768 >= MINSIGSTKSZ ? 32768 : MINSIGSTKSZ;
 
     static SignalDefs signalDefs[] = {
         { SIGINT,  "SIGINT - Terminal interrupt signal" },
diff --git a/packages/Catch2/include/internal/catch_generators.hpp b/packages/Catch2/include/internal/catch_generators.hpp
index 8f06b8c6c..ea575c85c 100644
--- a/packages/Catch2/include/internal/catch_generators.hpp
+++ b/packages/Catch2/include/internal/catch_generators.hpp
@@ -70,6 +70,9 @@ namespace Generators {
 
     template<typename T>
     class FixedValuesGenerator final : public IGenerator<T> {
+        static_assert(!std::is_same<T, bool>::value,
+            "FixedValuesGenerator does not support bools because of std::vector<bool>"
+            "specialization, use SingleValue Generator instead.");
         std::vector<T> m_values;
         size_t m_idx = 0;
     public:
diff --git a/packages/Catch2/include/internal/catch_generators_generic.hpp b/packages/Catch2/include/internal/catch_generators_generic.hpp
index 2903ba69d..81fd38578 100644
--- a/packages/Catch2/include/internal/catch_generators_generic.hpp
+++ b/packages/Catch2/include/internal/catch_generators_generic.hpp
@@ -91,6 +91,9 @@ namespace Generators {
 
     template <typename T>
     class RepeatGenerator : public IGenerator<T> {
+        static_assert(!std::is_same<T, bool>::value,
+            "RepeatGenerator currently does not support bools"
+            "because of std::vector<bool> specialization");
         GeneratorWrapper<T> m_generator;
         mutable std::vector<T> m_returned;
         size_t m_target_repeats;
@@ -205,12 +208,14 @@ namespace Generators {
             m_chunk_size(size), m_generator(std::move(generator))
         {
             m_chunk.reserve(m_chunk_size);
-            m_chunk.push_back(m_generator.get());
-            for (size_t i = 1; i < m_chunk_size; ++i) {
-                if (!m_generator.next()) {
-                    Catch::throw_exception(GeneratorException("Not enough values to initialize the first chunk"));
-                }
+            if (m_chunk_size != 0) {
                 m_chunk.push_back(m_generator.get());
+                for (size_t i = 1; i < m_chunk_size; ++i) {
+                    if (!m_generator.next()) {
+                        Catch::throw_exception(GeneratorException("Not enough values to initialize the first chunk"));
+                    }
+                    m_chunk.push_back(m_generator.get());
+                }
             }
         }
         std::vector<T> const& get() const override {
diff --git a/packages/Catch2/include/internal/catch_generators_specific.hpp b/packages/Catch2/include/internal/catch_generators_specific.hpp
index 7aae06bd5..f57d29b62 100644
--- a/packages/Catch2/include/internal/catch_generators_specific.hpp
+++ b/packages/Catch2/include/internal/catch_generators_specific.hpp
@@ -10,6 +10,7 @@
 #include "catch_context.h"
 #include "catch_generators.hpp"
 #include "catch_interfaces_config.h"
+#include "catch_random_number_generator.h"
 
 #include <random>
 
@@ -18,14 +19,13 @@ namespace Generators {
 
 template <typename Float>
 class RandomFloatingGenerator final : public IGenerator<Float> {
-    // FIXME: What is the right seed?
-    std::minstd_rand m_rand;
+    Catch::SimplePcg32& m_rng;
     std::uniform_real_distribution<Float> m_dist;
     Float m_current_number;
 public:
 
     RandomFloatingGenerator(Float a, Float b):
-        m_rand(getCurrentContext().getConfig()->rngSeed()),
+        m_rng(rng()),
         m_dist(a, b) {
         static_cast<void>(next());
     }
@@ -34,20 +34,20 @@ public:
         return m_current_number;
     }
     bool next() override {
-        m_current_number = m_dist(m_rand);
+        m_current_number = m_dist(m_rng);
         return true;
     }
 };
 
 template <typename Integer>
 class RandomIntegerGenerator final : public IGenerator<Integer> {
-    std::minstd_rand m_rand;
+    Catch::SimplePcg32& m_rng;
     std::uniform_int_distribution<Integer> m_dist;
     Integer m_current_number;
 public:
 
     RandomIntegerGenerator(Integer a, Integer b):
-        m_rand(getCurrentContext().getConfig()->rngSeed()),
+        m_rng(rng()),
         m_dist(a, b) {
         static_cast<void>(next());
     }
@@ -56,7 +56,7 @@ public:
         return m_current_number;
     }
     bool next() override {
-        m_current_number = m_dist(m_rand);
+        m_current_number = m_dist(m_rng);
         return true;
     }
 };
@@ -128,6 +128,46 @@ GeneratorWrapper<T> range(T const& start, T const& end) {
 }
 
 
+template <typename T>
+class IteratorGenerator final : public IGenerator<T> {
+    static_assert(!std::is_same<T, bool>::value,
+        "IteratorGenerator currently does not support bools"
+        "because of std::vector<bool> specialization");
+
+    std::vector<T> m_elems;
+    size_t m_current = 0;
+public:
+    template <typename InputIterator, typename InputSentinel>
+    IteratorGenerator(InputIterator first, InputSentinel last):m_elems(first, last) {
+        if (m_elems.empty()) {
+            Catch::throw_exception(GeneratorException("IteratorGenerator received no valid values"));
+        }
+    }
+
+    T const& get() const override {
+        return m_elems[m_current];
+    }
+
+    bool next() override {
+        ++m_current;
+        return m_current != m_elems.size();
+    }
+};
+
+template <typename InputIterator,
+          typename InputSentinel,
+          typename ResultType = typename std::iterator_traits<InputIterator>::value_type>
+GeneratorWrapper<ResultType> from_range(InputIterator from, InputSentinel to) {
+    return GeneratorWrapper<ResultType>(pf::make_unique<IteratorGenerator<ResultType>>(from, to));
+}
+
+template <typename Container,
+          typename ResultType = typename Container::value_type>
+GeneratorWrapper<ResultType> from_range(Container const& cnt) {
+    return GeneratorWrapper<ResultType>(pf::make_unique<IteratorGenerator<ResultType>>(cnt.begin(), cnt.end()));
+}
+
+
 } // namespace Generators
 } // namespace Catch
 
diff --git a/packages/Catch2/include/internal/catch_interfaces_capture.h b/packages/Catch2/include/internal/catch_interfaces_capture.h
index 36f27a331..8c25c8cf7 100644
--- a/packages/Catch2/include/internal/catch_interfaces_capture.h
+++ b/packages/Catch2/include/internal/catch_interfaces_capture.h
@@ -9,6 +9,7 @@
 #define TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED
 
 #include <string>
+#include <chrono>
 
 #include "catch_stringref.h"
 #include "catch_result_type.h"
@@ -22,14 +23,18 @@ namespace Catch {
     struct MessageInfo;
     struct MessageBuilder;
     struct Counts;
-    struct BenchmarkInfo;
-    struct BenchmarkStats;
     struct AssertionReaction;
     struct SourceLineInfo;
 
     struct ITransientExpression;
     struct IGeneratorTracker;
 
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+    struct BenchmarkInfo;
+    template <typename Duration = std::chrono::duration<double, std::nano>>
+    struct BenchmarkStats;
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
+
     struct IResultCapture {
 
         virtual ~IResultCapture();
@@ -41,8 +46,12 @@ namespace Catch {
 
         virtual auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& = 0;
 
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+        virtual void benchmarkPreparing( std::string const& name ) = 0;
         virtual void benchmarkStarting( BenchmarkInfo const& info ) = 0;
-        virtual void benchmarkEnded( BenchmarkStats const& stats ) = 0;
+        virtual void benchmarkEnded( BenchmarkStats<> const& stats ) = 0;
+        virtual void benchmarkFailed( std::string const& error ) = 0;
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
 
         virtual void pushScopedMessage( MessageInfo const& message ) = 0;
         virtual void popScopedMessage( MessageInfo const& message ) = 0;
diff --git a/packages/Catch2/include/internal/catch_interfaces_config.cpp b/packages/Catch2/include/internal/catch_interfaces_config.cpp
index b6f5daa2d..6617da691 100644
--- a/packages/Catch2/include/internal/catch_interfaces_config.cpp
+++ b/packages/Catch2/include/internal/catch_interfaces_config.cpp
@@ -1,4 +1,4 @@
-#include "internal/catch_interfaces_config.h"
+#include "catch_interfaces_config.h"
 
 namespace Catch {
     IConfig::~IConfig() = default;
diff --git a/packages/Catch2/include/internal/catch_interfaces_config.h b/packages/Catch2/include/internal/catch_interfaces_config.h
index 341bb7420..f8cbf71c8 100644
--- a/packages/Catch2/include/internal/catch_interfaces_config.h
+++ b/packages/Catch2/include/internal/catch_interfaces_config.h
@@ -9,6 +9,7 @@
 #define TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED
 
 #include "catch_common.h"
+#include "catch_option.hpp"
 
 #include <iosfwd>
 #include <string>
@@ -50,7 +51,7 @@ namespace Catch {
         BeforeExit = 2,
         BeforeStartAndExit = BeforeStart | BeforeExit
     }; };
-
+    
     class TestSpec;
 
     struct IConfig : NonCopyable {
@@ -72,10 +73,14 @@ namespace Catch {
         virtual std::vector<std::string> const& getTestsOrTags() const = 0;
         virtual RunTests::InWhatOrder runOrder() const = 0;
         virtual unsigned int rngSeed() const = 0;
-        virtual int benchmarkResolutionMultiple() const = 0;
         virtual UseColour::YesOrNo useColour() const = 0;
         virtual std::vector<std::string> const& getSectionsToRun() const = 0;
         virtual Verbosity verbosity() const = 0;
+
+        virtual bool benchmarkNoAnalysis() const = 0;
+        virtual int benchmarkSamples() const = 0;
+        virtual double benchmarkConfidenceInterval() const = 0;
+        virtual unsigned int benchmarkResamples() const = 0;
     };
 
     using IConfigPtr = std::shared_ptr<IConfig const>;
diff --git a/packages/Catch2/include/internal/catch_interfaces_enum_values_registry.h b/packages/Catch2/include/internal/catch_interfaces_enum_values_registry.h
new file mode 100644
index 000000000..81592c9bd
--- /dev/null
+++ b/packages/Catch2/include/internal/catch_interfaces_enum_values_registry.h
@@ -0,0 +1,46 @@
+/*
+ *  Created by Phil on 4/4/2019.
+ *  Copyright 2019 Two Blue Cubes Ltd. All rights reserved.
+ *
+ *  Distributed under the Boost Software License, Version 1.0. (See accompanying
+ *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+#ifndef TWOBLUECUBES_CATCH_INTERFACESENUMVALUESREGISTRY_H_INCLUDED
+#define TWOBLUECUBES_CATCH_INTERFACESENUMVALUESREGISTRY_H_INCLUDED
+
+#include "catch_stringref.h"
+
+#include <vector>
+
+namespace Catch {
+
+    namespace Detail {
+        struct EnumInfo {
+            StringRef m_name;
+            std::vector<std::pair<int, StringRef>> m_values;
+
+            ~EnumInfo();
+
+            StringRef lookup( int value ) const;
+        };
+    } // namespace Detail
+
+    struct IMutableEnumValuesRegistry {
+        virtual ~IMutableEnumValuesRegistry();
+
+        virtual Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector<int> const& values ) = 0;
+
+        template<typename E>
+        Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::initializer_list<E> values ) {
+            static_assert(sizeof(int) >= sizeof(E), "Cannot serialize enum to int");
+            std::vector<int> intValues;
+            intValues.reserve( values.size() );
+            for( auto enumValue : values )
+                intValues.push_back( static_cast<int>( enumValue ) );
+            return registerEnum( enumName, allEnums, intValues );
+        }
+    };
+
+} // Catch
+
+#endif //TWOBLUECUBES_CATCH_INTERFACESENUMVALUESREGISTRY_H_INCLUDED
diff --git a/packages/Catch2/include/internal/catch_interfaces_exception.cpp b/packages/Catch2/include/internal/catch_interfaces_exception.cpp
index 8494a2ccd..705d8c87a 100644
--- a/packages/Catch2/include/internal/catch_interfaces_exception.cpp
+++ b/packages/Catch2/include/internal/catch_interfaces_exception.cpp
@@ -1,4 +1,4 @@
-#include "internal/catch_interfaces_exception.h"
+#include "catch_interfaces_exception.h"
 
 namespace Catch {
     IExceptionTranslator::~IExceptionTranslator() = default;
diff --git a/packages/Catch2/include/internal/catch_interfaces_registry_hub.cpp b/packages/Catch2/include/internal/catch_interfaces_registry_hub.cpp
index bd5b8082c..7a22d649e 100644
--- a/packages/Catch2/include/internal/catch_interfaces_registry_hub.cpp
+++ b/packages/Catch2/include/internal/catch_interfaces_registry_hub.cpp
@@ -1,4 +1,4 @@
-#include "internal/catch_interfaces_registry_hub.h"
+#include "catch_interfaces_registry_hub.h"
 
 namespace Catch {
     IRegistryHub::~IRegistryHub() = default;
diff --git a/packages/Catch2/include/internal/catch_interfaces_registry_hub.h b/packages/Catch2/include/internal/catch_interfaces_registry_hub.h
index 8e1da61e0..19ffbf263 100644
--- a/packages/Catch2/include/internal/catch_interfaces_registry_hub.h
+++ b/packages/Catch2/include/internal/catch_interfaces_registry_hub.h
@@ -22,6 +22,8 @@ namespace Catch {
     struct IReporterRegistry;
     struct IReporterFactory;
     struct ITagAliasRegistry;
+    struct IMutableEnumValuesRegistry;
+
     class StartupExceptionRegistry;
 
     using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;
@@ -32,7 +34,6 @@ namespace Catch {
         virtual IReporterRegistry const& getReporterRegistry() const = 0;
         virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
         virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0;
-
         virtual IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const = 0;
 
 
@@ -47,6 +48,7 @@ namespace Catch {
         virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;
         virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) = 0;
         virtual void registerStartupException() noexcept = 0;
+        virtual IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() = 0;
     };
 
     IRegistryHub const& getRegistryHub();
diff --git a/packages/Catch2/include/internal/catch_interfaces_reporter.h b/packages/Catch2/include/internal/catch_interfaces_reporter.h
index e5fbf8bb0..751ef2c24 100644
--- a/packages/Catch2/include/internal/catch_interfaces_reporter.h
+++ b/packages/Catch2/include/internal/catch_interfaces_reporter.h
@@ -18,12 +18,18 @@
 #include "catch_option.hpp"
 #include "catch_stringref.h"
 
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+#include "benchmark/catch_estimate.hpp"
+#include "benchmark/catch_outlier_classification.hpp"
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
+
 
 #include <string>
 #include <iosfwd>
 #include <map>
 #include <set>
 #include <memory>
+#include <algorithm>
 
 namespace Catch {
 
@@ -159,14 +165,43 @@ namespace Catch {
         bool aborting;
     };
 
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
     struct BenchmarkInfo {
         std::string name;
+        double estimatedDuration;
+        int iterations;
+        int samples;
+        unsigned int resamples;
+        double clockResolution;
+        double clockCost;
     };
+
+    template <class Duration>
     struct BenchmarkStats {
         BenchmarkInfo info;
-        std::size_t iterations;
-        uint64_t elapsedTimeInNanoseconds;
+
+        std::vector<Duration> samples;
+        Benchmark::Estimate<Duration> mean;
+        Benchmark::Estimate<Duration> standardDeviation;
+        Benchmark::OutlierClassification outliers;
+        double outlierVariance;
+
+        template <typename Duration2>
+        operator BenchmarkStats<Duration2>() const {
+            std::vector<Duration2> samples2;
+            samples2.reserve(samples.size());
+            std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](Duration d) { return Duration2(d); });
+            return {
+                info,
+                std::move(samples2),
+                mean,
+                standardDeviation,
+                outliers,
+                outlierVariance,
+            };
+        }
     };
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
 
     struct IStreamingReporter {
         virtual ~IStreamingReporter() = default;
@@ -179,23 +214,26 @@ namespace Catch {
 
         virtual void noMatchingTestCases( std::string const& spec ) = 0;
 
+        virtual void reportInvalidArguments(std::string const&) {}
+        
         virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;
         virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0;
 
         virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0;
         virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0;
 
-        // *** experimental ***
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+        virtual void benchmarkPreparing( std::string const& ) {}
         virtual void benchmarkStarting( BenchmarkInfo const& ) {}
+        virtual void benchmarkEnded( BenchmarkStats<> const& ) {}
+        virtual void benchmarkFailed( std::string const& ) {}
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
 
         virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0;
 
         // The return value indicates if the messages buffer should be cleared:
         virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0;
 
-        // *** experimental ***
-        virtual void benchmarkEnded( BenchmarkStats const& ) {}
-
         virtual void sectionEnded( SectionStats const& sectionStats ) = 0;
         virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;
         virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;
diff --git a/packages/Catch2/include/internal/catch_interfaces_runner.cpp b/packages/Catch2/include/internal/catch_interfaces_runner.cpp
index 2b052eb80..8d419a144 100644
--- a/packages/Catch2/include/internal/catch_interfaces_runner.cpp
+++ b/packages/Catch2/include/internal/catch_interfaces_runner.cpp
@@ -1,4 +1,4 @@
-#include "internal/catch_interfaces_runner.h"
+#include "catch_interfaces_runner.h"
 
 namespace Catch {
     IRunner::~IRunner() = default;
diff --git a/packages/Catch2/include/internal/catch_interfaces_testcase.cpp b/packages/Catch2/include/internal/catch_interfaces_testcase.cpp
index 35c3db082..9b35e0342 100644
--- a/packages/Catch2/include/internal/catch_interfaces_testcase.cpp
+++ b/packages/Catch2/include/internal/catch_interfaces_testcase.cpp
@@ -1,4 +1,4 @@
-#include "internal/catch_interfaces_testcase.h"
+#include "catch_interfaces_testcase.h"
 
 namespace Catch {
     ITestInvoker::~ITestInvoker() = default;
diff --git a/packages/Catch2/include/internal/catch_interfaces_testcase.h b/packages/Catch2/include/internal/catch_interfaces_testcase.h
index f57cc8fe7..2492c07de 100644
--- a/packages/Catch2/include/internal/catch_interfaces_testcase.h
+++ b/packages/Catch2/include/internal/catch_interfaces_testcase.h
@@ -28,6 +28,7 @@ namespace Catch {
         virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const = 0;
     };
 
+    bool isThrowSafe( TestCase const& testCase, IConfig const& config );
     bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
     std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
     std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
diff --git a/packages/Catch2/include/internal/catch_list.cpp b/packages/Catch2/include/internal/catch_list.cpp
index e1d99222e..11e551404 100644
--- a/packages/Catch2/include/internal/catch_list.cpp
+++ b/packages/Catch2/include/internal/catch_list.cpp
@@ -84,9 +84,18 @@ namespace Catch {
     }
 
     std::string TagInfo::all() const {
-        std::string out;
-        for( auto const& spelling : spellings )
-            out += "[" + spelling + "]";
+        size_t size = 0;
+        for (auto const& spelling : spellings) {
+            // Add 2 for the brackes
+            size += spelling.size() + 2;
+        }
+
+        std::string out; out.reserve(size);
+        for (auto const& spelling : spellings) {
+            out += '[';
+            out += spelling;
+            out += ']';
+        }
         return out;
     }
 
diff --git a/packages/Catch2/include/internal/catch_matchers.h b/packages/Catch2/include/internal/catch_matchers.h
index aebd4c239..5b69c4a82 100644
--- a/packages/Catch2/include/internal/catch_matchers.h
+++ b/packages/Catch2/include/internal/catch_matchers.h
@@ -44,6 +44,15 @@ namespace Matchers {
             virtual bool match( ObjectT const& arg ) const = 0;
         };
 
+#if defined(__OBJC__)
+        // Hack to fix Catch GH issue #1661. Could use id for generic Object support.
+        // use of const for Object pointers is very uncommon and under ARC it causes some kind of signature mismatch that breaks compilation
+        template<>
+        struct MatcherMethod<NSString*> {
+            virtual bool match( NSString* arg ) const = 0;
+        };
+#endif
+
 #ifdef __clang__
 #    pragma clang diagnostic pop
 #endif
diff --git a/packages/Catch2/include/internal/catch_matchers_exception.cpp b/packages/Catch2/include/internal/catch_matchers_exception.cpp
new file mode 100644
index 000000000..b18810e82
--- /dev/null
+++ b/packages/Catch2/include/internal/catch_matchers_exception.cpp
@@ -0,0 +1,30 @@
+/*
+ *  Created by Martin Hořeňovský on 13/10/2019.
+ *
+ * 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_matchers_exception.hpp"
+
+
+namespace Catch {
+namespace Matchers {
+namespace Exception {
+
+bool ExceptionMessageMatcher::match(std::exception const& ex) const {
+    return ex.what() == m_message;
+}
+
+std::string ExceptionMessageMatcher::describe() const {
+    return "exception message matches \"" + m_message + "\"";
+}
+
+}
+Exception::ExceptionMessageMatcher Message(std::string const& message) {
+    return Exception::ExceptionMessageMatcher(message);
+}
+
+// namespace Exception
+} // namespace Matchers
+} // namespace Catch
diff --git a/packages/Catch2/include/internal/catch_matchers_exception.hpp b/packages/Catch2/include/internal/catch_matchers_exception.hpp
new file mode 100644
index 000000000..a80b3607b
--- /dev/null
+++ b/packages/Catch2/include/internal/catch_matchers_exception.hpp
@@ -0,0 +1,36 @@
+/*
+ *  Created by Martin Hořeňovský on 13/10/2019.
+ *
+ * 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_MATCHERS_EXCEPTION_HPP_INCLUDED
+#define TWOBLUECUBES_CATCH_MATCHERS_EXCEPTION_HPP_INCLUDED
+
+#include "catch_matchers.h"
+
+namespace Catch {
+namespace Matchers {
+namespace Exception {
+
+class ExceptionMessageMatcher : public MatcherBase<std::exception> {
+    std::string m_message;
+public:
+
+    ExceptionMessageMatcher(std::string const& message):
+        m_message(message)
+    {}
+
+    bool match(std::exception const& ex) const override;
+
+    std::string describe() const override;
+};
+
+} // namespace Exception
+
+Exception::ExceptionMessageMatcher Message(std::string const& message);
+
+} // namespace Matchers
+} // namespace Catch
+
+#endif // TWOBLUECUBES_CATCH_MATCHERS_EXCEPTION_HPP_INCLUDED
diff --git a/packages/Catch2/include/internal/catch_matchers_floating.cpp b/packages/Catch2/include/internal/catch_matchers_floating.cpp
index 9bc082ede..68fd1bda0 100644
--- a/packages/Catch2/include/internal/catch_matchers_floating.cpp
+++ b/packages/Catch2/include/internal/catch_matchers_floating.cpp
@@ -11,75 +11,120 @@
 #include "catch_to_string.hpp"
 #include "catch_tostring.h"
 
+#include <algorithm>
+#include <cmath>
 #include <cstdlib>
 #include <cstdint>
 #include <cstring>
+#include <sstream>
+#include <type_traits>
+#include <iomanip>
+#include <limits>
 
-namespace Catch {
-namespace Matchers {
-namespace Floating {
-enum class FloatingPointKind : uint8_t {
-    Float,
-    Double
-};
-}
-}
-}
 
+namespace Catch {
 namespace {
 
-template <typename T>
-struct Converter;
-
-template <>
-struct Converter<float> {
-    static_assert(sizeof(float) == sizeof(int32_t), "Important ULP matcher assumption violated");
-    Converter(float f) {
+    int32_t convert(float f) {
+        static_assert(sizeof(float) == sizeof(int32_t), "Important ULP matcher assumption violated");
+        int32_t i;
         std::memcpy(&i, &f, sizeof(f));
+        return i;
     }
-    int32_t i;
-};
 
-template <>
-struct Converter<double> {
-    static_assert(sizeof(double) == sizeof(int64_t), "Important ULP matcher assumption violated");
-    Converter(double d) {
+    int64_t convert(double d) {
+        static_assert(sizeof(double) == sizeof(int64_t), "Important ULP matcher assumption violated");
+        int64_t i;
         std::memcpy(&i, &d, sizeof(d));
+        return i;
     }
-    int64_t i;
-};
 
-template <typename T>
-auto convert(T t) -> Converter<T> {
-    return Converter<T>(t);
-}
+    template <typename FP>
+    bool almostEqualUlps(FP lhs, FP rhs, uint64_t maxUlpDiff) {
+        // Comparison with NaN should always be false.
+        // This way we can rule it out before getting into the ugly details
+        if (Catch::isnan(lhs) || Catch::isnan(rhs)) {
+            return false;
+        }
 
-template <typename FP>
-bool almostEqualUlps(FP lhs, FP rhs, int maxUlpDiff) {
-    // Comparison with NaN should always be false.
-    // This way we can rule it out before getting into the ugly details
-    if (Catch::isnan(lhs) || Catch::isnan(rhs)) {
-        return false;
+        auto lc = convert(lhs);
+        auto rc = convert(rhs);
+
+        if ((lc < 0) != (rc < 0)) {
+            // Potentially we can have +0 and -0
+            return lhs == rhs;
+        }
+
+        auto ulpDiff = std::abs(lc - rc);
+        return static_cast<uint64_t>(ulpDiff) <= maxUlpDiff;
+    }
+
+} //end anonymous namespace
+
+#if defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
+
+#if defined(__clang__)
+#pragma clang diagnostic push
+// The long double overload is currently unused
+#pragma clang diagnostic ignored "-Wunused-function"
+#endif
+
+    float nextafter(float x, float y) {
+        return ::nextafterf(x, y);
     }
 
-    auto lc = convert(lhs);
-    auto rc = convert(rhs);
+    double nextafter(double x, double y) {
+        return ::nextafter(x, y);
+    }
+
+    long double nextafter(long double x, long double y) {
+        return ::nextafterl(x, y);
+    }
+
+#if defined(__clang__)
+#pragma clang diagnostic pop
+#endif
+
+#endif // ^^^ CATCH_CONFIG_GLOBAL_NEXTAFTER ^^^
 
-    if ((lc.i < 0) != (rc.i < 0)) {
-        // Potentially we can have +0 and -0
-        return lhs == rhs;
+namespace {
+
+template <typename FP>
+FP step(FP start, FP direction, uint64_t steps) {
+    for (uint64_t i = 0; i < steps; ++i) {
+#if defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
+        start = Catch::nextafter(start, direction);
+#else
+        start = std::nextafter(start, direction);
+#endif
     }
+    return start;
+}
 
-    auto ulpDiff = std::abs(lc.i - rc.i);
-    return ulpDiff <= maxUlpDiff;
+// Performs equivalent check of std::fabs(lhs - rhs) <= margin
+// But without the subtraction to allow for INFINITY in comparison
+bool marginComparison(double lhs, double rhs, double margin) {
+    return (lhs + margin >= rhs) && (rhs + margin >= lhs);
 }
 
+template <typename FloatingPoint>
+void write(std::ostream& out, FloatingPoint num) {
+    out << std::scientific
+        << std::setprecision(std::numeric_limits<FloatingPoint>::max_digits10 - 1)
+        << num;
 }
 
+} // end anonymous namespace
 
-namespace Catch {
 namespace Matchers {
 namespace Floating {
+
+    enum class FloatingPointKind : uint8_t {
+        Float,
+        Double
+    };
+
+
     WithinAbsMatcher::WithinAbsMatcher(double target, double margin)
         :m_target{ target }, m_margin{ margin } {
         CATCH_ENFORCE(margin >= 0, "Invalid margin: " << margin << '.'
@@ -97,10 +142,11 @@ namespace Floating {
     }
 
 
-    WithinUlpsMatcher::WithinUlpsMatcher(double target, int ulps, FloatingPointKind baseType)
+    WithinUlpsMatcher::WithinUlpsMatcher(double target, uint64_t ulps, FloatingPointKind baseType)
         :m_target{ target }, m_ulps{ ulps }, m_type{ baseType } {
-        CATCH_ENFORCE(ulps >= 0, "Invalid ULP setting: " << ulps << '.'
-            << " ULPs have to be non-negative.");
+        CATCH_ENFORCE(m_type == FloatingPointKind::Double
+                   || m_ulps < (std::numeric_limits<uint32_t>::max)(),
+            "Provided ULP is impossibly large for a float comparison.");
     }
 
 #if defined(__clang__)
@@ -125,18 +171,60 @@ namespace Floating {
 #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" : "");
+        std::stringstream ret;
+
+        ret << "is within " << m_ulps << " ULPs of ";
+
+        if (m_type == FloatingPointKind::Float) {
+            write(ret, static_cast<float>(m_target));
+            ret << 'f';
+        } else {
+            write(ret, m_target);
+        }
+
+        ret << " ([";
+        if (m_type == FloatingPointKind::Double) {
+            write(ret, step(m_target, static_cast<double>(-INFINITY), m_ulps));
+            ret << ", ";
+            write(ret, step(m_target, static_cast<double>( INFINITY), m_ulps));
+        } else {
+            write(ret, step(static_cast<float>(m_target), -INFINITY, m_ulps));
+            ret << ", ";
+            write(ret, step(static_cast<float>(m_target),  INFINITY, m_ulps));
+        }
+        ret << "])";
+
+        return ret.str();
+    }
+
+    WithinRelMatcher::WithinRelMatcher(double target, double epsilon):
+        m_target(target),
+        m_epsilon(epsilon){
+        CATCH_ENFORCE(m_epsilon >= 0., "Relative comparison with epsilon <  0 does not make sense.");
+        CATCH_ENFORCE(m_epsilon  < 1., "Relative comparison with epsilon >= 1 does not make sense.");
+    }
+
+    bool WithinRelMatcher::match(double const& matchee) const {
+        const auto relMargin = m_epsilon * (std::max)(std::fabs(matchee), std::fabs(m_target));
+        return marginComparison(matchee, m_target,
+                                std::isinf(relMargin)? 0 : relMargin);
+    }
+
+    std::string WithinRelMatcher::describe() const {
+        Catch::ReusableStringStream sstr;
+        sstr << "and " << m_target << " are within " << m_epsilon * 100. << "% of each other";
+        return sstr.str();
     }
 
 }// namespace Floating
 
 
 
-Floating::WithinUlpsMatcher WithinULP(double target, int maxUlpDiff) {
+Floating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff) {
     return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Double);
 }
 
-Floating::WithinUlpsMatcher WithinULP(float target, int maxUlpDiff) {
+Floating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff) {
     return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Float);
 }
 
@@ -144,6 +232,23 @@ Floating::WithinAbsMatcher WithinAbs(double target, double margin) {
     return Floating::WithinAbsMatcher(target, margin);
 }
 
+Floating::WithinRelMatcher WithinRel(double target, double eps) {
+    return Floating::WithinRelMatcher(target, eps);
+}
+
+Floating::WithinRelMatcher WithinRel(double target) {
+    return Floating::WithinRelMatcher(target, std::numeric_limits<double>::epsilon() * 100);
+}
+
+Floating::WithinRelMatcher WithinRel(float target, float eps) {
+    return Floating::WithinRelMatcher(target, eps);
+}
+
+Floating::WithinRelMatcher WithinRel(float target) {
+    return Floating::WithinRelMatcher(target, std::numeric_limits<float>::epsilon() * 100);
+}
+
+
 } // namespace Matchers
 } // namespace Catch
 
diff --git a/packages/Catch2/include/internal/catch_matchers_floating.h b/packages/Catch2/include/internal/catch_matchers_floating.h
index ee077526b..0f2ff49ff 100644
--- a/packages/Catch2/include/internal/catch_matchers_floating.h
+++ b/packages/Catch2/include/internal/catch_matchers_floating.h
@@ -9,9 +9,6 @@
 
 #include "catch_matchers.h"
 
-#include <type_traits>
-#include <cmath>
-
 namespace Catch {
 namespace Matchers {
 
@@ -29,23 +26,43 @@ namespace Matchers {
         };
 
         struct WithinUlpsMatcher : MatcherBase<double> {
-            WithinUlpsMatcher(double target, int ulps, FloatingPointKind baseType);
+            WithinUlpsMatcher(double target, uint64_t ulps, FloatingPointKind baseType);
             bool match(double const& matchee) const override;
             std::string describe() const override;
         private:
             double m_target;
-            int m_ulps;
+            uint64_t m_ulps;
             FloatingPointKind m_type;
         };
 
+        // Given IEEE-754 format for floats and doubles, we can assume
+        // that float -> double promotion is lossless. Given this, we can
+        // assume that if we do the standard relative comparison of
+        // |lhs - rhs| <= epsilon * max(fabs(lhs), fabs(rhs)), then we get
+        // the same result if we do this for floats, as if we do this for
+        // doubles that were promoted from floats.
+        struct WithinRelMatcher : MatcherBase<double> {
+            WithinRelMatcher(double target, double epsilon);
+            bool match(double const& matchee) const override;
+            std::string describe() const override;
+        private:
+            double m_target;
+            double m_epsilon;
+        };
 
     } // namespace Floating
 
     // The following functions create the actual matcher objects.
     // This allows the types to be inferred
-    Floating::WithinUlpsMatcher WithinULP(double target, int maxUlpDiff);
-    Floating::WithinUlpsMatcher WithinULP(float target, int maxUlpDiff);
+    Floating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff);
+    Floating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff);
     Floating::WithinAbsMatcher WithinAbs(double target, double margin);
+    Floating::WithinRelMatcher WithinRel(double target, double eps);
+    // defaults epsilon to 100*numeric_limits<double>::epsilon()
+    Floating::WithinRelMatcher WithinRel(double target);
+    Floating::WithinRelMatcher WithinRel(float target, float eps);
+    // defaults epsilon to 100*numeric_limits<float>::epsilon()
+    Floating::WithinRelMatcher WithinRel(float target);
 
 } // namespace Matchers
 } // namespace Catch
diff --git a/packages/Catch2/include/internal/catch_matchers_vector.h b/packages/Catch2/include/internal/catch_matchers_vector.h
index 1e29cc940..2dc8a7150 100644
--- a/packages/Catch2/include/internal/catch_matchers_vector.h
+++ b/packages/Catch2/include/internal/catch_matchers_vector.h
@@ -9,6 +9,7 @@
 #define TWOBLUECUBES_CATCH_MATCHERS_VECTOR_H_INCLUDED
 
 #include "catch_matchers.h"
+#include "catch_approx.h"
 
 #include <algorithm>
 
@@ -16,28 +17,6 @@ namespace Catch {
 namespace Matchers {
 
     namespace Vector {
-        namespace Detail {
-            template <typename InputIterator, typename T>
-            size_t count(InputIterator first, InputIterator last, T const& item) {
-                size_t cnt = 0;
-                for (; first != last; ++first) {
-                    if (*first == item) {
-                        ++cnt;
-                    }
-                }
-                return cnt;
-            }
-            template <typename InputIterator, typename T>
-            bool contains(InputIterator first, InputIterator last, T const& item) {
-                for (; first != last; ++first) {
-                    if (*first == item) {
-                        return true;
-                    }
-                }
-                return false;
-            }
-        }
-
         template<typename T>
         struct ContainsElementMatcher : MatcherBase<std::vector<T>> {
 
@@ -112,6 +91,42 @@ namespace Matchers {
             std::vector<T> const& m_comparator;
         };
 
+        template<typename T>
+        struct ApproxMatcher : MatcherBase<std::vector<T>> {
+
+            ApproxMatcher(std::vector<T> const& comparator) : m_comparator( comparator ) {}
+
+            bool match(std::vector<T> const &v) const override {
+                if (m_comparator.size() != v.size())
+                    return false;
+                for (std::size_t i = 0; i < v.size(); ++i)
+                    if (m_comparator[i] != approx(v[i]))
+                        return false;
+                return true;
+            }
+            std::string describe() const override {
+                return "is approx: " + ::Catch::Detail::stringify( m_comparator );
+            }
+            template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+            ApproxMatcher& epsilon( T const& newEpsilon ) {
+                approx.epsilon(newEpsilon);
+                return *this;
+            }
+            template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+            ApproxMatcher& margin( T const& newMargin ) {
+                approx.margin(newMargin);
+                return *this;
+            }
+            template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+            ApproxMatcher& scale( T const& newScale ) {
+                approx.scale(newScale);
+                return *this;
+            }
+
+            std::vector<T> const& m_comparator;
+            mutable Catch::Detail::Approx approx = Catch::Detail::Approx::custom();
+        };
+
         template<typename T>
         struct UnorderedEqualsMatcher : MatcherBase<std::vector<T>> {
             UnorderedEqualsMatcher(std::vector<T> const& target) : m_target(target) {}
@@ -121,28 +136,7 @@ namespace Matchers {
                 if (m_target.size() != vec.size()) {
                     return false;
                 }
-                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) {
-                    ++lfirst; ++rfirst;
-                }
-                if (lfirst == llast) {
-                    return true;
-                }
-
-                for (auto mid = lfirst; mid != llast; ++mid) {
-                    // Skip already counted items
-                    if (Detail::contains(lfirst, mid, *mid)) {
-                        continue;
-                    }
-                    size_t num_vec = Detail::count(rfirst, rlast, *mid);
-                    if (num_vec == 0 || Detail::count(lfirst, llast, *mid) != num_vec) {
-                        return false;
-                    }
-                }
-
-                return true;
+                return std::is_permutation(m_target.begin(), m_target.end(), vec.begin());
             }
 
             std::string describe() const override {
@@ -172,6 +166,11 @@ namespace Matchers {
         return Vector::EqualsMatcher<T>( comparator );
     }
 
+    template<typename T>
+    Vector::ApproxMatcher<T> Approx( std::vector<T> const& comparator ) {
+        return Vector::ApproxMatcher<T>( comparator );
+    }
+
     template<typename T>
     Vector::UnorderedEqualsMatcher<T> UnorderedEquals(std::vector<T> const& target) {
         return Vector::UnorderedEqualsMatcher<T>(target);
diff --git a/packages/Catch2/include/internal/catch_message.cpp b/packages/Catch2/include/internal/catch_message.cpp
index fa7e87461..8f391bcb2 100644
--- a/packages/Catch2/include/internal/catch_message.cpp
+++ b/packages/Catch2/include/internal/catch_message.cpp
@@ -9,6 +9,7 @@
 #include "catch_message.h"
 #include "catch_interfaces_capture.h"
 #include "catch_uncaught_exceptions.h"
+#include "catch_enforce.h"
 
 #include <cassert>
 #include <stack>
@@ -76,6 +77,15 @@ namespace Catch {
             }
             return names.substr(start, end - start + 1);
         };
+        auto skipq = [&] (size_t start, char quote) {
+            for (auto i = start + 1; i < names.size() ; ++i) {
+                if (names[i] == quote)
+                    return i;
+                if (names[i] == '\\')
+                    ++i;
+            }
+            CATCH_INTERNAL_ERROR("CAPTURE parsing encountered unmatched quote");
+        };
 
         size_t start = 0;
         std::stack<char> openings;
@@ -96,10 +106,14 @@ namespace Catch {
 //           case '>':
                 openings.pop();
                 break;
+            case '"':
+            case '\'':
+                pos = skipq(pos, c);
+                break;
             case ',':
                 if (start != pos && openings.size() == 0) {
                     m_messages.emplace_back(macroName, lineInfo, resultType);
-                    m_messages.back().message = trimmed(start, pos);
+                    m_messages.back().message = static_cast<std::string>(trimmed(start, pos));
                     m_messages.back().message += " := ";
                     start = pos;
                 }
@@ -107,7 +121,7 @@ namespace Catch {
         }
         assert(openings.size() == 0 && "Mismatched openings");
         m_messages.emplace_back(macroName, lineInfo, resultType);
-        m_messages.back().message = trimmed(start, names.size() - 1);
+        m_messages.back().message = static_cast<std::string>(trimmed(start, names.size() - 1));
         m_messages.back().message += " := ";
     }
     Capturer::~Capturer() {
diff --git a/packages/Catch2/include/internal/catch_meta.hpp b/packages/Catch2/include/internal/catch_meta.hpp
index 3508a46f7..8529766da 100644
--- a/packages/Catch2/include/internal/catch_meta.hpp
+++ b/packages/Catch2/include/internal/catch_meta.hpp
@@ -12,66 +12,27 @@
 #include <type_traits>
 
 namespace Catch {
-template< typename... >
-struct TypeList {};
-
-template< typename... >
-struct append;
-
-template< template<typename...> class L1
-    , typename...E1
-    , template<typename...> class L2
-    , typename...E2
->
-struct append< L1<E1...>, L2<E2...> > {
-    using type = L1<E1..., E2...>;
-};
-
-template< template<typename...> class L1
-    , typename...E1
-    , template<typename...> class L2
-    , typename...E2
-    , typename...Rest
->
-struct append< L1<E1...>, L2<E2...>, Rest...> {
-    using type = typename append< L1<E1..., E2...>, Rest... >::type;
-};
-
-template< template<typename...> class
-    , typename...
->
-struct rewrap;
-
-template< template<typename...> class Container
-    , template<typename...> class List
-    , typename...elems
->
-struct rewrap<Container, List<elems...>> {
-    using type = TypeList< Container< elems... > >;
-};
+template<typename T>
+struct always_false : std::false_type {};
 
-template< template<typename...> class Container
-    , template<typename...> class List
-    , class...Elems
-    , typename...Elements>
-    struct rewrap<Container, List<Elems...>, Elements...> {
-    using type = typename append<TypeList<Container<Elems...>>, typename rewrap<Container, Elements...>::type>::type;
+template <typename> struct true_given : std::true_type {};
+struct is_callable_tester {
+    template <typename Fun, typename... Args>
+    true_given<decltype(std::declval<Fun>()(std::declval<Args>()...))> static test(int);
+    template <typename...>
+    std::false_type static test(...);
 };
 
-template< template<typename...> class...Containers >
-struct combine {
-    template< typename...Types >
-    struct with_types {
-        template< template <typename...> class Final >
-        struct into {
-            using type = typename append<Final<>, typename rewrap<Containers, Types...>::type...>::type;
-        };
-    };
-};
+template <typename T>
+struct is_callable;
 
-template<typename T>
-struct always_false : std::false_type {};
+template <typename Fun, typename... Args>
+struct is_callable<Fun(Args...)> : decltype(is_callable_tester::test<Fun, Args...>(0)) {};
 
 } // namespace Catch
 
+namespace mpl_{
+    struct na;
+}
+
 #endif // TWOBLUECUBES_CATCH_META_HPP_INCLUDED
diff --git a/packages/Catch2/include/internal/catch_objc.hpp b/packages/Catch2/include/internal/catch_objc.hpp
index f927e0d3d..a1c8e0740 100644
--- a/packages/Catch2/include/internal/catch_objc.hpp
+++ b/packages/Catch2/include/internal/catch_objc.hpp
@@ -116,7 +116,7 @@ namespace Catch {
                     arcSafeRelease( m_substr );
                 }
 
-                bool match( NSString* const& str ) const override {
+                bool match( NSString* str ) const override {
                     return false;
                 }
 
@@ -126,7 +126,7 @@ namespace Catch {
             struct Equals : StringHolder {
                 Equals( NSString* substr ) : StringHolder( substr ){}
 
-                bool match( NSString* const& str ) const override {
+                bool match( NSString* str ) const override {
                     return  (str != nil || m_substr == nil ) &&
                             [str isEqualToString:m_substr];
                 }
@@ -139,7 +139,7 @@ namespace Catch {
             struct Contains : StringHolder {
                 Contains( NSString* substr ) : StringHolder( substr ){}
 
-                bool match( NSString* const& str ) const override {
+                bool match( NSString* str ) const override {
                     return  (str != nil || m_substr == nil ) &&
                             [str rangeOfString:m_substr].location != NSNotFound;
                 }
@@ -152,7 +152,7 @@ namespace Catch {
             struct StartsWith : StringHolder {
                 StartsWith( NSString* substr ) : StringHolder( substr ){}
 
-                bool match( NSString* const& str ) const override {
+                bool match( NSString* str ) const override {
                     return  (str != nil || m_substr == nil ) &&
                             [str rangeOfString:m_substr].location == 0;
                 }
@@ -164,7 +164,7 @@ namespace Catch {
             struct EndsWith : StringHolder {
                 EndsWith( NSString* substr ) : StringHolder( substr ){}
 
-                bool match( NSString* const& str ) const override {
+                bool match( NSString* str ) const override {
                     return  (str != nil || m_substr == nil ) &&
                             [str rangeOfString:m_substr].location == [str length] - [m_substr length];
                 }
diff --git a/packages/Catch2/include/internal/catch_preprocessor.hpp b/packages/Catch2/include/internal/catch_preprocessor.hpp
index faf41e6b3..f1bd0905b 100644
--- a/packages/Catch2/include/internal/catch_preprocessor.hpp
+++ b/packages/Catch2/include/internal/catch_preprocessor.hpp
@@ -68,22 +68,169 @@
 #define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) (INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) + 1)
 #endif
 
+#define INTERNAL_CATCH_MAKE_NAMESPACE2(...) ns_##__VA_ARGS__
+#define INTERNAL_CATCH_MAKE_NAMESPACE(name) INTERNAL_CATCH_MAKE_NAMESPACE2(name)
+
 #define INTERNAL_CATCH_REMOVE_PARENS(...) INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF __VA_ARGS__)
 
-#define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME2(Name, ...) INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME3(Name, __VA_ARGS__)
 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
-#define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME3(Name,...) Name " - " #__VA_ARGS__
-#define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME(Name,...) INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME2(Name, INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))
+#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>())
+#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))
 #else
-// MSVC is adding extra space and needs more calls to properly remove ()
-#define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME3(Name,...) Name " -" #__VA_ARGS__
-#define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME1(Name, ...) INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME2(Name, __VA_ARGS__)
-#define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME(Name, ...) INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME1(Name, INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)))
+#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) INTERNAL_CATCH_EXPAND_VARGS(decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>()))
+#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)))
 #endif
 
-#define INTERNAL_CATCH_MAKE_TYPE_LIST(types) Catch::TypeList<INTERNAL_CATCH_REMOVE_PARENS(types)>
+#define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(...)\
+    CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST,__VA_ARGS__)
+
+#define INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_0) INTERNAL_CATCH_REMOVE_PARENS(_0)
+#define INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_0, _1) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_1)
+#define INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_0, _1, _2) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_1, _2)
+#define INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_0, _1, _2, _3) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_1, _2, _3)
+#define INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_0, _1, _2, _3, _4) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_1, _2, _3, _4)
+#define INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_0, _1, _2, _3, _4, _5) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_1, _2, _3, _4, _5)
+#define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _4, _5, _6)
+#define INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_0, _1, _2, _3, _4, _5, _6, _7) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_1, _2, _3, _4, _5, _6, _7)
+#define INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_1, _2, _3, _4, _5, _6, _7, _8)
+#define INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9)
+#define INTERNAL_CATCH_REMOVE_PARENS_11_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10)
+
+#define INTERNAL_CATCH_VA_NARGS_IMPL(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
+
+#define INTERNAL_CATCH_TYPE_GEN\
+    template<typename...> struct TypeList {};\
+    template<typename...Ts>\
+    constexpr auto get_wrapper() noexcept -> TypeList<Ts...> { return {}; }\
+    template<template<typename...> class...> struct TemplateTypeList{};\
+    template<template<typename...> class...Cs>\
+    constexpr auto get_wrapper() noexcept -> TemplateTypeList<Cs...> { return {}; }\
+    template<typename...>\
+    struct append;\
+    template<typename...>\
+    struct rewrap;\
+    template<template<typename...> class, typename...>\
+    struct create;\
+    template<template<typename...> class, typename>\
+    struct convert;\
+    \
+    template<typename T> \
+    struct append<T> { using type = T; };\
+    template< template<typename...> class L1, typename...E1, template<typename...> class L2, typename...E2, typename...Rest>\
+    struct append<L1<E1...>, L2<E2...>, Rest...> { using type = typename append<L1<E1...,E2...>, Rest...>::type; };\
+    template< template<typename...> class L1, typename...E1, typename...Rest>\
+    struct append<L1<E1...>, TypeList<mpl_::na>, Rest...> { using type = L1<E1...>; };\
+    \
+    template< template<typename...> class Container, template<typename...> class List, typename...elems>\
+    struct rewrap<TemplateTypeList<Container>, List<elems...>> { using type = TypeList<Container<elems...>>; };\
+    template< template<typename...> class Container, template<typename...> class List, class...Elems, typename...Elements>\
+    struct rewrap<TemplateTypeList<Container>, List<Elems...>, Elements...> { using type = typename append<TypeList<Container<Elems...>>, typename rewrap<TemplateTypeList<Container>, Elements...>::type>::type; };\
+    \
+    template<template <typename...> class Final, template< typename...> class...Containers, typename...Types>\
+    struct create<Final, TemplateTypeList<Containers...>, TypeList<Types...>> { using type = typename append<Final<>, typename rewrap<TemplateTypeList<Containers>, Types...>::type...>::type; };\
+    template<template <typename...> class Final, template <typename...> class List, typename...Ts>\
+    struct convert<Final, List<Ts...>> { using type = typename append<Final<>,TypeList<Ts>...>::type; };
+
+#define INTERNAL_CATCH_NTTP_1(signature, ...)\
+    template<INTERNAL_CATCH_REMOVE_PARENS(signature)> struct Nttp{};\
+    template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
+    constexpr auto get_wrapper() noexcept -> Nttp<__VA_ARGS__> { return {}; } \
+    template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...> struct NttpTemplateTypeList{};\
+    template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...Cs>\
+    constexpr auto get_wrapper() noexcept -> NttpTemplateTypeList<Cs...> { return {}; } \
+    \
+    template< template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature)>\
+    struct rewrap<NttpTemplateTypeList<Container>, List<__VA_ARGS__>> { using type = TypeList<Container<__VA_ARGS__>>; };\
+    template< template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature), typename...Elements>\
+    struct rewrap<NttpTemplateTypeList<Container>, List<__VA_ARGS__>, Elements...> { using type = typename append<TypeList<Container<__VA_ARGS__>>, typename rewrap<NttpTemplateTypeList<Container>, Elements...>::type>::type; };\
+    template<template <typename...> class Final, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...Containers, typename...Types>\
+    struct create<Final, NttpTemplateTypeList<Containers...>, TypeList<Types...>> { using type = typename append<Final<>, typename rewrap<NttpTemplateTypeList<Containers>, Types...>::type...>::type; };
+
+#define INTERNAL_CATCH_DECLARE_SIG_TEST0(TestName)
+#define INTERNAL_CATCH_DECLARE_SIG_TEST1(TestName, signature)\
+    template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
+    static void TestName()
+#define INTERNAL_CATCH_DECLARE_SIG_TEST_X(TestName, signature, ...)\
+    template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
+    static void TestName()
+
+#define INTERNAL_CATCH_DEFINE_SIG_TEST0(TestName)
+#define INTERNAL_CATCH_DEFINE_SIG_TEST1(TestName, signature)\
+    template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
+    static void TestName()
+#define INTERNAL_CATCH_DEFINE_SIG_TEST_X(TestName, signature,...)\
+    template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
+    static void TestName()
+
+#define INTERNAL_CATCH_NTTP_REGISTER0(TestFunc, signature)\
+    template<typename Type>\
+    void reg_test(TypeList<Type>, Catch::NameAndTags nameAndTags)\
+    {\
+        Catch::AutoReg( Catch::makeTestInvoker(&TestFunc<Type>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), nameAndTags);\
+    }
+
+#define INTERNAL_CATCH_NTTP_REGISTER(TestFunc, signature, ...)\
+    template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
+    void reg_test(Nttp<__VA_ARGS__>, Catch::NameAndTags nameAndTags)\
+    {\
+        Catch::AutoReg( Catch::makeTestInvoker(&TestFunc<__VA_ARGS__>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), nameAndTags);\
+    }
+
+#define INTERNAL_CATCH_NTTP_REGISTER_METHOD0(TestName, signature, ...)\
+    template<typename Type>\
+    void reg_test(TypeList<Type>, Catch::StringRef className, Catch::NameAndTags nameAndTags)\
+    {\
+        Catch::AutoReg( Catch::makeTestInvoker(&TestName<Type>::test), CATCH_INTERNAL_LINEINFO, className, nameAndTags);\
+    }
+
+#define INTERNAL_CATCH_NTTP_REGISTER_METHOD(TestName, signature, ...)\
+    template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
+    void reg_test(Nttp<__VA_ARGS__>, Catch::StringRef className, Catch::NameAndTags nameAndTags)\
+    {\
+        Catch::AutoReg( Catch::makeTestInvoker(&TestName<__VA_ARGS__>::test), CATCH_INTERNAL_LINEINFO, className, nameAndTags);\
+    }
+
+#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0(TestName, ClassName)
+#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1(TestName, ClassName, signature)\
+    template<typename TestType> \
+    struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName)<TestType> { \
+        void test();\
+    }
+
+#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X(TestName, ClassName, signature, ...)\
+    template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
+    struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName)<__VA_ARGS__> { \
+        void test();\
+    }
+
+#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0(TestName)
+#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1(TestName, signature)\
+    template<typename TestType> \
+    void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName<TestType>::test()
+#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X(TestName, signature, ...)\
+    template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
+    void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName<__VA_ARGS__>::test()
 
-#define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(types)\
-    CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST,INTERNAL_CATCH_REMOVE_PARENS(types))
+#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+#define INTERNAL_CATCH_NTTP_0
+#define INTERNAL_CATCH_NTTP_GEN(...) INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__),INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_0)
+#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0)(TestName, __VA_ARGS__)
+#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0)(TestName, ClassName, __VA_ARGS__)
+#define INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD0, INTERNAL_CATCH_NTTP_REGISTER_METHOD0)(TestName, __VA_ARGS__)
+#define INTERNAL_CATCH_NTTP_REG_GEN(TestFunc, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER0, INTERNAL_CATCH_NTTP_REGISTER0)(TestFunc, __VA_ARGS__)
+#define INTERNAL_CATCH_DEFINE_SIG_TEST(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST1, INTERNAL_CATCH_DEFINE_SIG_TEST0)(TestName, __VA_ARGS__)
+#define INTERNAL_CATCH_DECLARE_SIG_TEST(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST1, INTERNAL_CATCH_DECLARE_SIG_TEST0)(TestName, __VA_ARGS__)
+#define INTERNAL_CATCH_REMOVE_PARENS_GEN(...) INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_REMOVE_PARENS_11_ARG,INTERNAL_CATCH_REMOVE_PARENS_10_ARG,INTERNAL_CATCH_REMOVE_PARENS_9_ARG,INTERNAL_CATCH_REMOVE_PARENS_8_ARG,INTERNAL_CATCH_REMOVE_PARENS_7_ARG,INTERNAL_CATCH_REMOVE_PARENS_6_ARG,INTERNAL_CATCH_REMOVE_PARENS_5_ARG,INTERNAL_CATCH_REMOVE_PARENS_4_ARG,INTERNAL_CATCH_REMOVE_PARENS_3_ARG,INTERNAL_CATCH_REMOVE_PARENS_2_ARG,INTERNAL_CATCH_REMOVE_PARENS_1_ARG)(__VA_ARGS__)
+#else
+#define INTERNAL_CATCH_NTTP_0(signature)
+#define INTERNAL_CATCH_NTTP_GEN(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1,INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_0)( __VA_ARGS__))
+#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0)(TestName, __VA_ARGS__))
+#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0)(TestName, ClassName, __VA_ARGS__))
+#define INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD0, INTERNAL_CATCH_NTTP_REGISTER_METHOD0)(TestName, __VA_ARGS__))
+#define INTERNAL_CATCH_NTTP_REG_GEN(TestFunc, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER0, INTERNAL_CATCH_NTTP_REGISTER0)(TestFunc, __VA_ARGS__))
+#define INTERNAL_CATCH_DEFINE_SIG_TEST(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST1, INTERNAL_CATCH_DEFINE_SIG_TEST0)(TestName, __VA_ARGS__))
+#define INTERNAL_CATCH_DECLARE_SIG_TEST(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST1, INTERNAL_CATCH_DECLARE_SIG_TEST0)(TestName, __VA_ARGS__))
+#define INTERNAL_CATCH_REMOVE_PARENS_GEN(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_REMOVE_PARENS_11_ARG,INTERNAL_CATCH_REMOVE_PARENS_10_ARG,INTERNAL_CATCH_REMOVE_PARENS_9_ARG,INTERNAL_CATCH_REMOVE_PARENS_8_ARG,INTERNAL_CATCH_REMOVE_PARENS_7_ARG,INTERNAL_CATCH_REMOVE_PARENS_6_ARG,INTERNAL_CATCH_REMOVE_PARENS_5_ARG,INTERNAL_CATCH_REMOVE_PARENS_4_ARG,INTERNAL_CATCH_REMOVE_PARENS_3_ARG,INTERNAL_CATCH_REMOVE_PARENS_2_ARG,INTERNAL_CATCH_REMOVE_PARENS_1_ARG)(__VA_ARGS__))
+#endif
 
 #endif // TWOBLUECUBES_CATCH_PREPROCESSOR_HPP_INCLUDED
diff --git a/packages/Catch2/include/internal/catch_random_number_generator.cpp b/packages/Catch2/include/internal/catch_random_number_generator.cpp
index ec8a5eb96..1ef08d4c4 100644
--- a/packages/Catch2/include/internal/catch_random_number_generator.cpp
+++ b/packages/Catch2/include/internal/catch_random_number_generator.cpp
@@ -7,23 +7,67 @@
 
 #include "catch_random_number_generator.h"
 #include "catch_context.h"
+#include "catch_run_context.h"
 #include "catch_interfaces_config.h"
 
 namespace Catch {
 
-    std::mt19937& rng() {
-        static std::mt19937 s_rng;
-        return s_rng;
+namespace {
+
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable:4146) // we negate uint32 during the rotate
+#endif
+        // Safe rotr implementation thanks to John Regehr
+        uint32_t rotate_right(uint32_t val, uint32_t count) {
+            const uint32_t mask = 31;
+            count &= mask;
+            return (val >> count) | (val << (-count & mask));
+        }
+
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+
+}
+
+
+    SimplePcg32::SimplePcg32(result_type seed_) {
+        seed(seed_);
+    }
+
+
+    void SimplePcg32::seed(result_type seed_) {
+        m_state = 0;
+        (*this)();
+        m_state += seed_;
+        (*this)();
     }
 
-    void seedRng( IConfig const& config ) {
-        if( config.rngSeed() != 0 ) {
-            std::srand( config.rngSeed() );
-            rng().seed( config.rngSeed() );
+    void SimplePcg32::discard(uint64_t skip) {
+        // We could implement this to run in O(log n) steps, but this
+        // should suffice for our use case.
+        for (uint64_t s = 0; s < skip; ++s) {
+            static_cast<void>((*this)());
         }
     }
 
-    unsigned int rngSeed() {
-        return getCurrentContext().getConfig()->rngSeed();
+    SimplePcg32::result_type SimplePcg32::operator()() {
+        // prepare the output value
+        const uint32_t xorshifted = static_cast<uint32_t>(((m_state >> 18u) ^ m_state) >> 27u);
+        const auto output = rotate_right(xorshifted, m_state >> 59u);
+
+        // advance state
+        m_state = m_state * 6364136223846793005ULL + s_inc;
+
+        return output;
+    }
+
+    bool operator==(SimplePcg32 const& lhs, SimplePcg32 const& rhs) {
+        return lhs.m_state == rhs.m_state;
+    }
+
+    bool operator!=(SimplePcg32 const& lhs, SimplePcg32 const& rhs) {
+        return lhs.m_state != rhs.m_state;
     }
 }
diff --git a/packages/Catch2/include/internal/catch_random_number_generator.h b/packages/Catch2/include/internal/catch_random_number_generator.h
index 817b7841a..79d627941 100644
--- a/packages/Catch2/include/internal/catch_random_number_generator.h
+++ b/packages/Catch2/include/internal/catch_random_number_generator.h
@@ -7,17 +7,52 @@
 #ifndef TWOBLUECUBES_CATCH_RANDOM_NUMBER_GENERATOR_H_INCLUDED
 #define TWOBLUECUBES_CATCH_RANDOM_NUMBER_GENERATOR_H_INCLUDED
 
-#include <algorithm>
-#include <random>
+#include <cstdint>
 
 namespace Catch {
 
-    struct IConfig;
+    // This is a simple implementation of C++11 Uniform Random Number
+    // Generator. It does not provide all operators, because Catch2
+    // does not use it, but it should behave as expected inside stdlib's
+    // distributions.
+    // The implementation is based on the PCG family (http://pcg-random.org)
+    class SimplePcg32 {
+        using state_type = std::uint64_t;
+    public:
+        using result_type = std::uint32_t;
+        static constexpr result_type (min)() {
+            return 0;
+        }
+        static constexpr result_type (max)() {
+            return static_cast<result_type>(-1);
+        }
 
-    std::mt19937& rng();
-    void seedRng( IConfig const& config );
-    unsigned int rngSeed();
+        // Provide some default initial state for the default constructor
+        SimplePcg32():SimplePcg32(0xed743cc4U) {}
 
-}
+        explicit SimplePcg32(result_type seed_);
+
+        void seed(result_type seed_);
+        void discard(uint64_t skip);
+
+        result_type operator()();
+
+    private:
+        friend bool operator==(SimplePcg32 const& lhs, SimplePcg32 const& rhs);
+        friend bool operator!=(SimplePcg32 const& lhs, SimplePcg32 const& rhs);
+
+        // In theory we also need operator<< and operator>>
+        // In practice we do not use them, so we will skip them for now
+
+
+        std::uint64_t m_state;
+        // This part of the state determines which "stream" of the numbers
+        // is chosen -- we take it as a constant for Catch2, so we only
+        // need to deal with seeding the main state.
+        // Picked by reading 8 bytes from `/dev/random` :-)
+        static const std::uint64_t s_inc = (0x13ed0cc53f939476ULL << 1ULL) | 1ULL;
+    };
+
+} // end namespace Catch
 
 #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 a50623985..8a3c7a979 100644
--- a/packages/Catch2/include/internal/catch_registry_hub.cpp
+++ b/packages/Catch2/include/internal/catch_registry_hub.cpp
@@ -15,6 +15,7 @@
 #include "catch_tag_alias_registry.h"
 #include "catch_startup_exception_registry.h"
 #include "catch_singletons.hpp"
+#include "catch_enum_values_registry.h"
 
 namespace Catch {
 
@@ -60,6 +61,9 @@ namespace Catch {
             void registerStartupException() noexcept override {
                 m_exceptionRegistry.add(std::current_exception());
             }
+            IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() override {
+                return m_enumValuesRegistry;
+            }
 
         private:
             TestRegistry m_testCaseRegistry;
@@ -67,6 +71,7 @@ namespace Catch {
             ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
             TagAliasRegistry m_tagAliasRegistry;
             StartupExceptionRegistry m_exceptionRegistry;
+            Detail::EnumValuesRegistry m_enumValuesRegistry;
         };
     }
 
diff --git a/packages/Catch2/include/internal/catch_reporter_registrars.hpp b/packages/Catch2/include/internal/catch_reporter_registrars.hpp
index 943fba651..660f554ab 100644
--- a/packages/Catch2/include/internal/catch_reporter_registrars.hpp
+++ b/packages/Catch2/include/internal/catch_reporter_registrars.hpp
@@ -18,11 +18,11 @@ namespace Catch {
 
         class ReporterFactory : public IReporterFactory {
 
-            virtual IStreamingReporterPtr create( ReporterConfig const& config ) const override {
+            IStreamingReporterPtr create( ReporterConfig const& config ) const override {
                 return std::unique_ptr<T>( new T( config ) );
             }
 
-            virtual std::string getDescription() const override {
+            std::string getDescription() const override {
                 return T::getDescription();
             }
         };
@@ -39,10 +39,10 @@ namespace Catch {
 
         class ListenerFactory : public IReporterFactory {
 
-            virtual IStreamingReporterPtr create( ReporterConfig const& config ) const override {
+            IStreamingReporterPtr create( ReporterConfig const& config ) const override {
                 return std::unique_ptr<T>( new T( config ) );
             }
-            virtual std::string getDescription() const override {
+            std::string getDescription() const override {
                 return std::string();
             }
         };
diff --git a/packages/Catch2/include/internal/catch_run_context.cpp b/packages/Catch2/include/internal/catch_run_context.cpp
index bc3a51512..2eb84fb9a 100644
--- a/packages/Catch2/include/internal/catch_run_context.cpp
+++ b/packages/Catch2/include/internal/catch_run_context.cpp
@@ -230,12 +230,21 @@ namespace Catch {
 
         m_unfinishedSections.push_back(endInfo);
     }
+
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+    void RunContext::benchmarkPreparing(std::string const& name) {
+		m_reporter->benchmarkPreparing(name);
+	}
     void RunContext::benchmarkStarting( BenchmarkInfo const& info ) {
         m_reporter->benchmarkStarting( info );
     }
-    void RunContext::benchmarkEnded( BenchmarkStats const& stats ) {
+    void RunContext::benchmarkEnded( BenchmarkStats<> const& stats ) {
         m_reporter->benchmarkEnded( stats );
     }
+	void RunContext::benchmarkFailed(std::string const & error) {
+		m_reporter->benchmarkFailed(error);
+	}
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
 
     void RunContext::pushScopedMessage(MessageInfo const & message) {
         m_messages.push_back(message);
@@ -270,7 +279,7 @@ namespace Catch {
         // Don't rebuild the result -- the stringification itself can cause more fatal errors
         // Instead, fake a result data.
         AssertionResultData tempResult( ResultWas::FatalErrorCondition, { false } );
-        tempResult.message = message;
+        tempResult.message = static_cast<std::string>(message);
         AssertionResult result(m_lastAssertionInfo, tempResult);
 
         assertionEnded(result);
@@ -433,7 +442,7 @@ namespace Catch {
         m_lastAssertionInfo = info;
 
         AssertionResultData data( resultType, LazyExpression( false ) );
-        data.message = message;
+        data.message = static_cast<std::string>(message);
         AssertionResult assertionResult{ m_lastAssertionInfo, data };
         assertionEnded( assertionResult );
         if( !assertionResult.isOk() )
@@ -497,4 +506,16 @@ namespace Catch {
         else
             CATCH_INTERNAL_ERROR("No result capture instance");
     }
+
+    void seedRng(IConfig const& config) {
+        if (config.rngSeed() != 0) {
+            std::srand(config.rngSeed());
+            rng().seed(config.rngSeed());
+        }
+    }
+
+    unsigned int rngSeed() {
+        return getCurrentContext().getConfig()->rngSeed();
+    }
+
 }
diff --git a/packages/Catch2/include/internal/catch_run_context.h b/packages/Catch2/include/internal/catch_run_context.h
index c530a7b2d..2a8e72dca 100644
--- a/packages/Catch2/include/internal/catch_run_context.h
+++ b/packages/Catch2/include/internal/catch_run_context.h
@@ -82,8 +82,12 @@ namespace Catch {
 
         auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& override;
 
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+        void benchmarkPreparing( std::string const& name ) override;
         void benchmarkStarting( BenchmarkInfo const& info ) override;
-        void benchmarkEnded( BenchmarkStats const& stats ) override;
+        void benchmarkEnded( BenchmarkStats<> const& stats ) override;
+        void benchmarkFailed( std::string const& error ) override;
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
 
         void pushScopedMessage( MessageInfo const& message ) override;
         void popScopedMessage( MessageInfo const& message ) override;
@@ -147,6 +151,8 @@ namespace Catch {
         bool m_includeSuccessfulResults;
     };
 
+    void seedRng(IConfig const& config);
+    unsigned int rngSeed();
 } // end namespace Catch
 
 #endif // TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED
diff --git a/packages/Catch2/include/internal/catch_session.cpp b/packages/Catch2/include/internal/catch_session.cpp
index 38b74ef72..b1d7a404b 100644
--- a/packages/Catch2/include/internal/catch_session.cpp
+++ b/packages/Catch2/include/internal/catch_session.cpp
@@ -25,6 +25,8 @@
 
 #include <cstdlib>
 #include <iomanip>
+#include <set>
+#include <iterator>
 
 namespace Catch {
 
@@ -58,46 +60,61 @@ namespace Catch {
             return ret;
         }
 
-
-        Catch::Totals runTests(std::shared_ptr<Config> const& config) {
-            auto reporter = makeReporter(config);
-
-            RunContext context(config, std::move(reporter));
-
-            Totals totals;
-
-            context.testGroupStarting(config->name(), 1, 1);
-
-            TestSpec testSpec = config->testSpec();
-
-            auto const& allTestCases = getAllTestCasesSorted(*config);
-            for (auto const& testCase : allTestCases) {
-                bool matching = (!testSpec.hasFilters() && !testCase.isHidden()) ||
-                                 (testSpec.hasFilters() && matchTest(testCase, testSpec, *config));
-
-                if (!context.aborting() && matching)
-                    totals += context.runTest(testCase);
-                else
-                    context.reporter().skipTest(testCase);
+        class TestGroup {
+        public:
+            explicit TestGroup(std::shared_ptr<Config> const& config)
+            : m_config{config}
+            , m_context{config, makeReporter(config)}
+            {
+                auto const& allTestCases = getAllTestCasesSorted(*m_config);
+                m_matches = m_config->testSpec().matchesByFilter(allTestCases, *m_config);
+                auto const& invalidArgs = m_config->testSpec().getInvalidArgs();
+                
+                if (m_matches.empty() && invalidArgs.empty()) {
+                    for (auto const& test : allTestCases)
+                        if (!test.isHidden())
+                            m_tests.emplace(&test);
+                } else {
+                    for (auto const& match : m_matches)
+                        m_tests.insert(match.tests.begin(), match.tests.end());
+                }
             }
 
-            if (config->warnAboutNoTests() && totals.testCases.total() == 0) {
-                ReusableStringStream testConfig;
-
-                bool first = true;
-                for (const auto& input : config->getTestsOrTags()) {
-                    if (!first) { testConfig << ' '; }
-                    first = false;
-                    testConfig << input;
+            Totals execute() {
+                auto const& invalidArgs = m_config->testSpec().getInvalidArgs();
+                Totals totals;
+                m_context.testGroupStarting(m_config->name(), 1, 1);
+                for (auto const& testCase : m_tests) {
+                    if (!m_context.aborting())
+                        totals += m_context.runTest(*testCase);
+                    else
+                        m_context.reporter().skipTest(*testCase);
                 }
 
-                context.reporter().noMatchingTestCases(testConfig.str());
-                totals.error = -1;
+                for (auto const& match : m_matches) {
+                    if (match.tests.empty()) {
+                        m_context.reporter().noMatchingTestCases(match.name);
+                        totals.error = -1;
+                    }
+                }
+                
+                if (!invalidArgs.empty()) {
+                    for (auto const& invalidArg: invalidArgs)                   
+                         m_context.reporter().reportInvalidArguments(invalidArg);
+                }   
+                
+                m_context.testGroupEnded(m_config->name(), totals, 1, 1);
+                return totals;
             }
 
-            context.testGroupEnded(config->name(), totals, 1, 1);
-            return totals;
-        }
+        private:
+            using Tests = std::set<TestCase const*>;
+
+            std::shared_ptr<Config> m_config;
+            RunContext m_context;
+            Tests m_tests;
+            TestSpec::Matches m_matches;
+        };
 
         void applyFilenamesAsTags(Catch::IConfig const& config) {
             auto& tests = const_cast<std::vector<TestCase>&>(getAllTestCasesSorted(config));
@@ -134,6 +151,9 @@ namespace Catch {
 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
         const auto& exceptions = getRegistryHub().getStartupExceptionRegistry().getExceptions();
         if ( !exceptions.empty() ) {
+            config();
+            getCurrentMutableContext().setConfig(m_config);
+
             m_startupExceptions = true;
             Colour colourGuard( Colour::Red );
             Catch::cerr() << "Errors occurred during startup!" << '\n';
@@ -163,7 +183,7 @@ namespace Catch {
     }
     void Session::libIdentify() {
         Catch::cout()
-                << std::left << std::setw(16) << "description: " << "A Catch test executable\n"
+                << std::left << std::setw(16) << "description: " << "A Catch2 test executable\n"
                 << std::left << std::setw(16) << "category: " << "testframework\n"
                 << std::left << std::setw(16) << "framework: " << "Catch Test\n"
                 << std::left << std::setw(16) << "version: " << libraryVersion() << std::endl;
@@ -194,7 +214,7 @@ namespace Catch {
         return 0;
     }
 
-#if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE)
+#if defined(CATCH_CONFIG_WCHAR) && defined(_WIN32) && defined(UNICODE)
     int Session::applyCommandLine( int argc, wchar_t const * const * argv ) {
 
         char **utf8Argv = new char *[ argc ];
@@ -271,7 +291,12 @@ namespace Catch {
             if( Option<std::size_t> listed = list( m_config ) )
                 return static_cast<int>( *listed );
 
-            auto totals = runTests( m_config );
+            TestGroup tests { m_config };
+            auto const totals = tests.execute();
+
+            if( m_config->warnAboutNoTests() && totals.error == -1 )
+                return 2;
+
             // Note that on unices only the lower 8 bits are usually used, clamping
             // the return value to 255 prevents false negative when some multiple
             // of 256 tests has failed
diff --git a/packages/Catch2/include/internal/catch_session.h b/packages/Catch2/include/internal/catch_session.h
index af820da44..4e83d5204 100644
--- a/packages/Catch2/include/internal/catch_session.h
+++ b/packages/Catch2/include/internal/catch_session.h
@@ -26,7 +26,7 @@ namespace Catch {
         void libIdentify();
 
         int applyCommandLine( int argc, char const * const * argv );
-    #if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE)
+    #if defined(CATCH_CONFIG_WCHAR) && defined(_WIN32) && defined(UNICODE)
         int applyCommandLine( int argc, wchar_t const * const * argv );
     #endif
 
diff --git a/packages/Catch2/include/internal/catch_stream.cpp b/packages/Catch2/include/internal/catch_stream.cpp
index ba2d2be25..3e907c63b 100644
--- a/packages/Catch2/include/internal/catch_stream.cpp
+++ b/packages/Catch2/include/internal/catch_stream.cpp
@@ -25,7 +25,7 @@ namespace Catch {
 
     Catch::IStream::~IStream() = default;
 
-    namespace detail { namespace {
+    namespace Detail { namespace {
         template<typename WriterF, std::size_t bufferSize=256>
         class StreamBufImpl : public std::streambuf {
             char data[bufferSize];
@@ -124,15 +124,15 @@ namespace Catch {
 
     auto makeStream( StringRef const &filename ) -> IStream const* {
         if( filename.empty() )
-            return new detail::CoutStream();
+            return new Detail::CoutStream();
         else if( filename[0] == '%' ) {
             if( filename == "%debug" )
-                return new detail::DebugOutStream();
+                return new Detail::DebugOutStream();
             else
                 CATCH_ERROR( "Unrecognised stream: '" << filename << "'" );
         }
         else
-            return new detail::FileStream( filename );
+            return new Detail::FileStream( filename );
     }
 
 
diff --git a/packages/Catch2/include/internal/catch_string_manip.cpp b/packages/Catch2/include/internal/catch_string_manip.cpp
index 904d10138..65be34d03 100644
--- a/packages/Catch2/include/internal/catch_string_manip.cpp
+++ b/packages/Catch2/include/internal/catch_string_manip.cpp
@@ -6,11 +6,13 @@
  */
 
 #include "catch_string_manip.h"
+#include "catch_stringref.h"
 
 #include <algorithm>
 #include <ostream>
 #include <cstring>
 #include <cctype>
+#include <vector>
 
 namespace Catch {
 
@@ -51,6 +53,18 @@ namespace Catch {
         return start != std::string::npos ? str.substr( start, 1+end-start ) : std::string();
     }
 
+    StringRef trim(StringRef ref) {
+        const auto is_ws = [](char c) {
+            return c == ' ' || c == '\t' || c == '\n' || c == '\r';
+        };
+        size_t real_begin = 0;
+        while (real_begin < ref.size() && is_ws(ref[real_begin])) { ++real_begin; }
+        size_t real_end = ref.size();
+        while (real_end > real_begin && is_ws(ref[real_end - 1])) { --real_end; }
+
+        return ref.substr(real_begin, real_end - real_begin);
+    }
+
     bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {
         bool replaced = false;
         std::size_t i = str.find( replaceThis );
@@ -65,6 +79,21 @@ namespace Catch {
         return replaced;
     }
 
+    std::vector<StringRef> splitStringRef( StringRef str, char delimiter ) {
+        std::vector<StringRef> subStrings;
+        std::size_t start = 0;
+        for(std::size_t pos = 0; pos < str.size(); ++pos ) {
+            if( str[pos] == delimiter ) {
+                if( pos - start > 1 )
+                    subStrings.push_back( str.substr( start, pos-start ) );
+                start = pos+1;
+            }
+        }
+        if( start < str.size() )
+            subStrings.push_back( str.substr( start, str.size()-start ) );
+        return subStrings;
+    }
+
     pluralise::pluralise( std::size_t count, std::string const& label )
     :   m_count( count ),
         m_label( label )
diff --git a/packages/Catch2/include/internal/catch_string_manip.h b/packages/Catch2/include/internal/catch_string_manip.h
index 6292cd576..cdb7be5fe 100644
--- a/packages/Catch2/include/internal/catch_string_manip.h
+++ b/packages/Catch2/include/internal/catch_string_manip.h
@@ -7,8 +7,11 @@
 #ifndef TWOBLUECUBES_CATCH_STRING_MANIP_H_INCLUDED
 #define TWOBLUECUBES_CATCH_STRING_MANIP_H_INCLUDED
 
+#include "catch_stringref.h"
+
 #include <string>
 #include <iosfwd>
+#include <vector>
 
 namespace Catch {
 
@@ -19,7 +22,13 @@ namespace Catch {
     bool contains( std::string const& s, std::string const& infix );
     void toLowerInPlace( std::string& s );
     std::string toLower( std::string const& s );
+    //! Returns a new string without whitespace at the start/end
     std::string trim( std::string const& str );
+    //! Returns a substring of the original ref without whitespace. Beware lifetimes!
+    StringRef trim(StringRef ref);
+
+    // !!! Be aware, returns refs into original string - make sure original string outlives them
+    std::vector<StringRef> splitStringRef( StringRef str, char delimiter );
     bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );
 
     struct pluralise {
diff --git a/packages/Catch2/include/internal/catch_stringref.cpp b/packages/Catch2/include/internal/catch_stringref.cpp
index 9e9095e4b..b46414ac3 100644
--- a/packages/Catch2/include/internal/catch_stringref.cpp
+++ b/packages/Catch2/include/internal/catch_stringref.cpp
@@ -17,21 +17,11 @@
 #include <cstring>
 #include <cstdint>
 
-namespace {
-    const uint32_t byte_2_lead = 0xC0;
-    const uint32_t byte_3_lead = 0xE0;
-    const uint32_t byte_4_lead = 0xF0;
-}
-
 namespace Catch {
     StringRef::StringRef( char const* rawChars ) noexcept
     : StringRef( rawChars, static_cast<StringRef::size_type>(std::strlen(rawChars) ) )
     {}
 
-    StringRef::operator std::string() const {
-        return std::string( m_start, m_size );
-    }
-
     void StringRef::swap( StringRef& other ) noexcept {
         std::swap( m_start, other.m_start );
         std::swap( m_size, other.m_size );
@@ -39,9 +29,11 @@ namespace Catch {
     }
 
     auto StringRef::c_str() const -> char const* {
-        if( isSubstring() )
-           const_cast<StringRef*>( this )->takeOwnership();
-        return m_start;
+        if( !isSubstring() )
+            return m_start;
+
+        const_cast<StringRef *>( this )->takeOwnership();
+        return m_data;
     }
     auto StringRef::currentData() const noexcept -> char const* {
         return m_start;
@@ -59,7 +51,6 @@ namespace Catch {
             m_data = new char[m_size+1];
             memcpy( m_data, m_start, m_size );
             m_data[m_size] = '\0';
-            m_start = m_data;
         }
     }
     auto StringRef::substr( size_type start, size_type size ) const noexcept -> StringRef {
@@ -77,40 +68,6 @@ namespace Catch {
         return !operator==( other );
     }
 
-    auto StringRef::operator[](size_type index) const noexcept -> char {
-        return m_start[index];
-    }
-
-    auto StringRef::numberOfCharacters() const noexcept -> size_type {
-        size_type noChars = m_size;
-        // Make adjustments for uft encodings
-        for( size_type i=0; i < m_size; ++i ) {
-            char c = m_start[i];
-            if( ( c & byte_2_lead ) == byte_2_lead ) {
-                noChars--;
-                if (( c & byte_3_lead ) == byte_3_lead )
-                    noChars--;
-                if( ( c & byte_4_lead ) == byte_4_lead )
-                    noChars--;
-            }
-        }
-        return noChars;
-    }
-
-    auto operator + ( StringRef const& lhs, StringRef const& rhs ) -> std::string {
-        std::string str;
-        str.reserve( lhs.size() + rhs.size() );
-        str += lhs;
-        str += rhs;
-        return str;
-    }
-    auto operator + ( StringRef const& lhs, const char* rhs ) -> std::string {
-        return std::string( lhs ) + std::string( rhs );
-    }
-    auto operator + ( char const* lhs, StringRef const& rhs ) -> std::string {
-        return std::string( lhs ) + std::string( rhs );
-    }
-
     auto operator << ( std::ostream& os, StringRef const& str ) -> std::ostream& {
         return os.write(str.currentData(), str.size());
     }
diff --git a/packages/Catch2/include/internal/catch_stringref.h b/packages/Catch2/include/internal/catch_stringref.h
index 64f595b36..a45147da1 100644
--- a/packages/Catch2/include/internal/catch_stringref.h
+++ b/packages/Catch2/include/internal/catch_stringref.h
@@ -10,6 +10,7 @@
 #include <cstddef>
 #include <string>
 #include <iosfwd>
+#include <cassert>
 
 namespace Catch {
 
@@ -23,6 +24,7 @@ namespace Catch {
     class StringRef {
     public:
         using size_type = std::size_t;
+        using const_iterator = const char*;
 
     private:
         friend struct StringRefTestAccess;
@@ -78,7 +80,9 @@ namespace Catch {
             return *this;
         }
 
-        operator std::string() const;
+        explicit operator std::string() const {
+            return std::string(m_start, m_size);
+        }
 
         void swap( StringRef& other ) noexcept;
 
@@ -86,7 +90,10 @@ namespace Catch {
         auto operator == ( StringRef const& other ) const noexcept -> bool;
         auto operator != ( StringRef const& other ) const noexcept -> bool;
 
-        auto operator[] ( size_type index ) const noexcept -> char;
+        auto operator[] ( size_type index ) const noexcept -> char {
+            assert(index < m_size);
+            return m_start[index];
+        }
 
     public: // named queries
         auto empty() const noexcept -> bool {
@@ -96,7 +103,6 @@ namespace Catch {
             return m_size;
         }
 
-        auto numberOfCharacters() const noexcept -> size_type;
         auto c_str() const -> char const*;
 
     public: // substrings and searches
@@ -106,15 +112,15 @@ namespace Catch {
         // Note that the pointer can change when if the StringRef is a substring
         auto currentData() const noexcept -> char const*;
 
+    public: // iterators
+        const_iterator begin() const { return m_start; }
+        const_iterator end() const { return m_start + m_size; }
+
     private: // ownership queries - may not be consistent between calls
         auto isOwned() const noexcept -> bool;
         auto isSubstring() const noexcept -> bool;
     };
 
-    auto operator + ( StringRef const& lhs, StringRef const& rhs ) -> std::string;
-    auto operator + ( StringRef const& lhs, char const* rhs ) -> std::string;
-    auto operator + ( char const* lhs, StringRef const& rhs ) -> std::string;
-
     auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&;
     auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&;
 
diff --git a/packages/Catch2/include/internal/catch_test_case_info.cpp b/packages/Catch2/include/internal/catch_test_case_info.cpp
index 4baa9d4bd..685ee30f3 100644
--- a/packages/Catch2/include/internal/catch_test_case_info.cpp
+++ b/packages/Catch2/include/internal/catch_test_case_info.cpp
@@ -59,8 +59,7 @@ namespace Catch {
         std::vector<std::string> tags;
         std::string desc, tag;
         bool inTag = false;
-        std::string _descOrTags = nameAndTags.tags;
-        for (char c : _descOrTags) {
+        for (char c : nameAndTags.tags) {
             if( !inTag ) {
                 if( c == '[' )
                     inTag = true;
@@ -93,7 +92,7 @@ namespace Catch {
             tags.push_back( "." );
         }
 
-        TestCaseInfo info( nameAndTags.name, _className, desc, tags, _lineInfo );
+        TestCaseInfo info( static_cast<std::string>(nameAndTags.name), _className, desc, tags, _lineInfo );
         return TestCase( _testCase, std::move(info) );
     }
 
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 a85d0edf6..b254ca08e 100644
--- a/packages/Catch2/include/internal/catch_test_case_registry_impl.cpp
+++ b/packages/Catch2/include/internal/catch_test_case_registry_impl.cpp
@@ -11,6 +11,7 @@
 #include "catch_enforce.h"
 #include "catch_interfaces_registry_hub.h"
 #include "catch_random_number_generator.h"
+#include "catch_run_context.h"
 #include "catch_string_manip.h"
 #include "catch_test_case_info.h"
 
@@ -36,8 +37,13 @@ namespace Catch {
         }
         return sorted;
     }
+
+    bool isThrowSafe( TestCase const& testCase, IConfig const& config ) {
+        return !testCase.throws() || config.allowThrows();
+    }
+
     bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) {
-        return testSpec.matches( testCase ) && ( config.allowThrows() || !testCase.throws() );
+        return testSpec.matches( testCase ) && isThrowSafe( testCase, config );
     }
 
     void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions ) {
@@ -100,7 +106,7 @@ namespace Catch {
     }
 
     std::string extractClassName( StringRef const& classOrQualifiedMethodName ) {
-        std::string className = classOrQualifiedMethodName;
+        std::string className(classOrQualifiedMethodName);
         if( startsWith( className, '&' ) )
         {
             std::size_t lastColons = className.rfind( "::" );
diff --git a/packages/Catch2/include/internal/catch_test_case_registry_impl.h b/packages/Catch2/include/internal/catch_test_case_registry_impl.h
index 8dc5b0fe3..359ac3e38 100644
--- a/packages/Catch2/include/internal/catch_test_case_registry_impl.h
+++ b/packages/Catch2/include/internal/catch_test_case_registry_impl.h
@@ -23,6 +23,8 @@ namespace Catch {
     struct IConfig;
 
     std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases );
+
+    bool isThrowSafe( TestCase const& testCase, IConfig const& config );
     bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
 
     void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions );
diff --git a/packages/Catch2/include/internal/catch_test_case_tracker.cpp b/packages/Catch2/include/internal/catch_test_case_tracker.cpp
index 210f27305..77bd65cbb 100644
--- a/packages/Catch2/include/internal/catch_test_case_tracker.cpp
+++ b/packages/Catch2/include/internal/catch_test_case_tracker.cpp
@@ -8,6 +8,7 @@
 #include "catch_test_case_tracker.h"
 
 #include "catch_enforce.h"
+#include "catch_string_manip.h"
 
 #include <algorithm>
 #include <cassert>
@@ -32,11 +33,6 @@ namespace TestCaseTracking {
     ITracker::~ITracker() = default;
 
 
-    TrackerContext& TrackerContext::instance() {
-        static TrackerContext s_instance;
-        return s_instance;
-    }
-
     ITracker& TrackerContext::startRun() {
         m_rootTracker = std::make_shared<SectionTracker>( NameAndLocation( "{root}", CATCH_INTERNAL_LINEINFO ), *this, nullptr );
         m_currentTracker = nullptr;
@@ -144,7 +140,7 @@ namespace TestCaseTracking {
                 m_runState = CompletedSuccessfully;
                 break;
             case ExecutingChildren:
-                if( m_children.empty() || m_children.back()->isComplete() )
+                if( std::all_of(m_children.begin(), m_children.end(), [](ITrackerPtr const& t){ return t->isComplete(); }) )
                     m_runState = CompletedSuccessfully;
                 break;
 
@@ -179,7 +175,8 @@ namespace TestCaseTracking {
     }
 
     SectionTracker::SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
-    :   TrackerBase( nameAndLocation, ctx, parent )
+    :   TrackerBase( nameAndLocation, ctx, parent ),
+        m_trimmed_name(trim(nameAndLocation.name))
     {
         if( parent ) {
             while( !parent->isSectionTracker() )
@@ -193,12 +190,11 @@ namespace TestCaseTracking {
     bool SectionTracker::isComplete() const {
         bool complete = true;
 
-        if ((m_filters.empty() || m_filters[0] == "") ||
-             std::find(m_filters.begin(), m_filters.end(),
-                       m_nameAndLocation.name) != m_filters.end())
+        if ((m_filters.empty() || m_filters[0] == "")
+            || std::find(m_filters.begin(), m_filters.end(), m_trimmed_name) != m_filters.end()) {
             complete = TrackerBase::isComplete();
+        }
         return complete;
-
     }
 
     bool SectionTracker::isSectionTracker() const { return true; }
@@ -222,12 +218,13 @@ namespace TestCaseTracking {
     }
 
     void SectionTracker::tryOpen() {
-        if( !isComplete() && (m_filters.empty() || m_filters[0].empty() ||  m_filters[0] == m_nameAndLocation.name ) )
+        if( !isComplete() )
             open();
     }
 
     void SectionTracker::addInitialFilters( std::vector<std::string> const& filters ) {
         if( !filters.empty() ) {
+            m_filters.reserve( m_filters.size() + filters.size() + 2 );
             m_filters.push_back(""); // Root - should never be consulted
             m_filters.push_back(""); // Test Case - not a section filter
             m_filters.insert( m_filters.end(), filters.begin(), filters.end() );
@@ -235,7 +232,7 @@ namespace TestCaseTracking {
     }
     void SectionTracker::addNextFilters( std::vector<std::string> const& filters ) {
         if( filters.size() > 1 )
-            m_filters.insert( m_filters.end(), ++filters.begin(), filters.end() );
+            m_filters.insert( m_filters.end(), filters.begin()+1, filters.end() );
     }
 
 } // namespace TestCaseTracking
diff --git a/packages/Catch2/include/internal/catch_test_case_tracker.h b/packages/Catch2/include/internal/catch_test_case_tracker.h
index 172760017..563dbef2c 100644
--- a/packages/Catch2/include/internal/catch_test_case_tracker.h
+++ b/packages/Catch2/include/internal/catch_test_case_tracker.h
@@ -71,8 +71,6 @@ namespace TestCaseTracking {
 
     public:
 
-        static TrackerContext& instance();
-
         ITracker& startRun();
         void endRun();
 
@@ -135,6 +133,7 @@ namespace TestCaseTracking {
 
     class SectionTracker : public TrackerBase {
         std::vector<std::string> m_filters;
+        std::string m_trimmed_name;
     public:
         SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
 
diff --git a/packages/Catch2/include/internal/catch_test_registry.h b/packages/Catch2/include/internal/catch_test_registry.h
index 0e7b53ded..dd1ccfcc8 100644
--- a/packages/Catch2/include/internal/catch_test_registry.h
+++ b/packages/Catch2/include/internal/catch_test_registry.h
@@ -12,7 +12,6 @@
 #include "catch_interfaces_testcase.h"
 #include "catch_compiler_capabilities.h"
 #include "catch_stringref.h"
-#include "catch_type_traits.hpp"
 #include "catch_preprocessor.hpp"
 #include "catch_meta.hpp"
 
@@ -60,18 +59,47 @@ struct AutoReg : NonCopyable {
             };                            \
         }                                 \
         void TestName::test()
-    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION( TestName, ... )  \
-        template<typename TestType>                                             \
-        static void TestName()
-    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... )    \
+    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( TestName, TestFunc, Name, Tags, Signature, ... )  \
+        INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature))
+    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... )    \
         namespace{                                                                                  \
-            template<typename TestType>                                                             \
-            struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) {     \
-                void test();                                                                        \
-            };                                                                                      \
+            namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) {                                      \
+            INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
         }                                                                                           \
-        template<typename TestType>                                                                 \
-        void TestName::test()
+        }                                                                                           \
+        INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))
+
+    #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \
+            INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ )
+    #else
+        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \
+            INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ ) )
+    #endif  
+
+    #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \
+            INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ )
+    #else
+        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \
+            INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) )
+    #endif
+
+    #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \
+            INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ )
+    #else
+        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \
+            INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) )
+    #endif
+
+    #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \
+            INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ )
+    #else
+        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \
+            INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) )
+    #endif
 #endif
 
     ///////////////////////////////////////////////////////////////////////////////
@@ -111,54 +139,64 @@ struct AutoReg : NonCopyable {
         CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
 
     ///////////////////////////////////////////////////////////////////////////////
-    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_2(TestName, TestFunc, Name, Tags, ... )\
+    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_2(TestName, TestFunc, Name, Tags, Signature, ... )\
         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
-        template<typename TestType> \
-        static void TestFunc();\
+        CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
+        CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
+        INTERNAL_CATCH_DECLARE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
         namespace {\
+        namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\
+            INTERNAL_CATCH_TYPE_GEN\
+            INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
+            INTERNAL_CATCH_NTTP_REG_GEN(TestFunc,INTERNAL_CATCH_REMOVE_PARENS(Signature))\
             template<typename...Types> \
             struct TestName{\
-                template<typename...Ts> \
-                TestName(Ts...names){\
-                    CATCH_INTERNAL_CHECK_UNIQUE_TYPES(CATCH_REC_LIST(INTERNAL_CATCH_REMOVE_PARENS, __VA_ARGS__)) \
+                TestName(){\
+                    int index = 0;                                    \
+                    constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\
                     using expander = int[];\
-                    (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFunc<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ names, Tags } ), 0)... };/* NOLINT */ \
+                    (void)expander{(reg_test(Types{}, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++, 0)... };/* NOLINT */ \
                 }\
             };\
-            INTERNAL_CATCH_TEMPLATE_REGISTRY_INITIATE(TestName, Name, __VA_ARGS__) \
+            static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
+            TestName<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>();\
+            return 0;\
+        }();\
+        }\
         }\
         CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
-        template<typename TestType> \
-        static void TestFunc()
-
-#if defined(CATCH_CPP17_OR_GREATER)
-#define CATCH_INTERNAL_CHECK_UNIQUE_TYPES(...) static_assert(Catch::is_unique<__VA_ARGS__>,"Duplicate type detected in declaration of template test case");
-#else
-#define CATCH_INTERNAL_CHECK_UNIQUE_TYPES(...) static_assert(Catch::is_unique<__VA_ARGS__>::value,"Duplicate type detected in declaration of template test case");
-#endif
+        CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS \
+        CATCH_INTERNAL_UNSUPPRESS_UNUSED_TEMPLATE_WARNINGS \
+        INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc,INTERNAL_CATCH_REMOVE_PARENS(Signature))
 
 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
-        INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, __VA_ARGS__ )
+        INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ )
 #else
     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
-        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, __VA_ARGS__ ) )
-#endif
+        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ ) )
+#endif  
 
-    #define INTERNAL_CATCH_TEMPLATE_REGISTRY_INITIATE(TestName, Name, ...)\
-        static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
-            TestName<CATCH_REC_LIST(INTERNAL_CATCH_REMOVE_PARENS, __VA_ARGS__)>(CATCH_REC_LIST_UD(INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME,Name, __VA_ARGS__));\
-            return 0;\
-        }();
+#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \
+        INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ )
+#else
+    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \
+        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) )
+#endif
 
-    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(TestName, TestFuncName, Name, Tags, TmplTypes, TypesList) \
+    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(TestName, TestFuncName, Name, Tags, Signature, TmplTypes, TypesList) \
         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS                      \
+        CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS                \
+        CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS                       \
         template<typename TestType> static void TestFuncName();       \
-        namespace {                                                   \
+        namespace {\
+        namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) {                                     \
+            INTERNAL_CATCH_TYPE_GEN                                                  \
+            INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))         \
             template<typename... Types>                               \
             struct TestName {                                         \
-                TestName() {                                          \
-                    CATCH_INTERNAL_CHECK_UNIQUE_TYPES(Types...)       \
+                void reg_tests() {                                          \
                     int index = 0;                                    \
                     using expander = int[];                           \
                     constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
@@ -168,65 +206,127 @@ struct AutoReg : NonCopyable {
                 }                                                     \
             };                                                        \
             static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
-                using TestInit = Catch::combine<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)> \
-                            ::with_types<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(TypesList)>::into<TestName>::type; \
-                TestInit();                                           \
+                using TestInit = typename create<TestName, decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>()), TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>>::type; \
+                TestInit t;                                           \
+                t.reg_tests();                                        \
                 return 0;                                             \
             }();                                                      \
         }                                                             \
+        }                                                             \
         CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS                    \
+        CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS              \
+        CATCH_INTERNAL_UNSUPPRESS_UNUSED_TEMPLATE_WARNINGS                     \
         template<typename TestType>                                   \
         static void TestFuncName()
 
 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\
-        INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ),Name,Tags,__VA_ARGS__)
+        INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename T,__VA_ARGS__)
 #else
     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\
-        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, __VA_ARGS__ ) )
+        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename T, __VA_ARGS__ ) )
+#endif
+
+#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\
+        INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__)
+#else
+    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\
+        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) )
 #endif
 
-    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, ... ) \
+    #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2(TestName, TestFunc, Name, Tags, TmplList)\
         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
-        namespace{ \
-            template<typename TestType> \
-            struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
-                void test();\
-            };\
+        CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
+        template<typename TestType> static void TestFunc();       \
+        namespace {\
+        namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\
+        INTERNAL_CATCH_TYPE_GEN\
+        template<typename... Types>                               \
+        struct TestName {                                         \
+            void reg_tests() {                                          \
+                int index = 0;                                    \
+                using expander = int[];                           \
+                (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFunc<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++, 0)... };/* NOLINT */\
+            }                                                     \
+        };\
+        static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
+                using TestInit = typename convert<TestName, TmplList>::type; \
+                TestInit t;                                           \
+                t.reg_tests();                                        \
+                return 0;                                             \
+            }();                                                        \
+        }}\
+        CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS                    \
+        CATCH_INTERNAL_UNSUPPRESS_UNUSED_TEMPLATE_WARNINGS \
+        template<typename TestType>                                   \
+        static void TestFunc()
+
+    #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(Name, Tags, TmplList) \
+        INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, TmplList )
+
+
+    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... ) \
+        CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
+        CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
+        CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
+        namespace {\
+        namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){ \
+            INTERNAL_CATCH_TYPE_GEN\
+            INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
+            INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
+            INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))\
             template<typename...Types> \
             struct TestNameClass{\
-                template<typename...Ts> \
-                TestNameClass(Ts...names){\
-                    CATCH_INTERNAL_CHECK_UNIQUE_TYPES(CATCH_REC_LIST(INTERNAL_CATCH_REMOVE_PARENS, __VA_ARGS__)) \
+                TestNameClass(){\
+                    int index = 0;                                    \
+                    constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\
                     using expander = int[];\
-                    (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ names, Tags } ), 0)... };/* NOLINT */ \
+                    (void)expander{(reg_test(Types{}, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++, 0)... };/* NOLINT */ \
                 }\
             };\
-            INTERNAL_CATCH_TEMPLATE_REGISTRY_INITIATE(TestNameClass, Name, __VA_ARGS__)\
+            static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
+                TestNameClass<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>();\
+                return 0;\
+        }();\
+        }\
         }\
         CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS\
-        template<typename TestType> \
-        void TestName<TestType>::test()
+        CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS\
+        CATCH_INTERNAL_UNSUPPRESS_UNUSED_TEMPLATE_WARNINGS\
+        INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))
 
 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
-        INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, __VA_ARGS__ )
+        INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ )
 #else
     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
-        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, __VA_ARGS__ ) )
+        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) )
 #endif
 
-    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(TestNameClass, TestName, ClassName, Name, Tags, TmplTypes, TypesList)\
+#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \
+        INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ )
+#else
+    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \
+        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) )
+#endif
+
+    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(TestNameClass, TestName, ClassName, Name, Tags, Signature, TmplTypes, TypesList)\
         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
+        CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
+        CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
         template<typename TestType> \
             struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
                 void test();\
             };\
         namespace {\
+        namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestNameClass) {\
+            INTERNAL_CATCH_TYPE_GEN                  \
+            INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
             template<typename...Types>\
             struct TestNameClass{\
-                TestNameClass(){\
-                    CATCH_INTERNAL_CHECK_UNIQUE_TYPES(Types...)\
+                void reg_tests(){\
                     int index = 0;\
                     using expander = int[];\
                     constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
@@ -236,22 +336,67 @@ struct AutoReg : NonCopyable {
                 }\
             };\
             static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
-                using TestInit = Catch::combine<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>\
-                            ::with_types<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(TypesList)>::into<TestNameClass>::type;\
-                TestInit();\
+                using TestInit = typename create<TestNameClass, decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>()), TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>>::type;\
+                TestInit t;\
+                t.reg_tests();\
                 return 0;\
             }(); \
         }\
+        }\
         CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
+        CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS \
+        CATCH_INTERNAL_UNSUPPRESS_UNUSED_TEMPLATE_WARNINGS \
         template<typename TestType> \
         void TestName<TestType>::test()
 
 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\
-        INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, __VA_ARGS__ )
+        INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, typename T, __VA_ARGS__ )
 #else
     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\
-        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, __VA_ARGS__ ) )
+        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, typename T,__VA_ARGS__ ) )
+#endif
+
+#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\
+        INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, Signature, __VA_ARGS__ )
+#else
+    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\
+        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, Signature,__VA_ARGS__ ) )
 #endif
 
+    #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, TmplList) \
+        CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
+        CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
+        template<typename TestType> \
+        struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
+            void test();\
+        };\
+        namespace {\
+        namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){ \
+            INTERNAL_CATCH_TYPE_GEN\
+            template<typename...Types>\
+            struct TestNameClass{\
+                void reg_tests(){\
+                    int index = 0;\
+                    using expander = int[];\
+                    (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++, 0)... };/* NOLINT */ \
+                }\
+            };\
+            static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
+                using TestInit = typename convert<TestNameClass, TmplList>::type;\
+                TestInit t;\
+                t.reg_tests();\
+                return 0;\
+            }(); \
+        }}\
+        CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
+        CATCH_INTERNAL_UNSUPPRESS_UNUSED_TEMPLATE_WARNINGS \
+        template<typename TestType> \
+        void TestName<TestType>::test()
+
+#define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD(ClassName, Name, Tags, TmplList) \
+        INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, TmplList )
+
+
 #endif // TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED
diff --git a/packages/Catch2/include/internal/catch_test_spec.cpp b/packages/Catch2/include/internal/catch_test_spec.cpp
index d9c149d50..65d34d0e5 100644
--- a/packages/Catch2/include/internal/catch_test_spec.cpp
+++ b/packages/Catch2/include/internal/catch_test_spec.cpp
@@ -7,6 +7,7 @@
 
 #include "catch_test_spec.h"
 #include "catch_string_manip.h"
+#include "catch_interfaces_config.h"
 
 #include <algorithm>
 #include <string>
@@ -15,45 +16,84 @@
 
 namespace Catch {
 
+    TestSpec::Pattern::Pattern( std::string const& name )
+    : m_name( name )
+    {}
+
     TestSpec::Pattern::~Pattern() = default;
-    TestSpec::NamePattern::~NamePattern() = default;
-    TestSpec::TagPattern::~TagPattern() = default;
-    TestSpec::ExcludedPattern::~ExcludedPattern() = default;
 
-    TestSpec::NamePattern::NamePattern( std::string const& name )
-    : m_wildcardPattern( toLower( name ), CaseSensitive::No )
+    std::string const& TestSpec::Pattern::name() const {
+        return m_name;
+    }
+
+
+    TestSpec::NamePattern::NamePattern( std::string const& name, std::string const& filterString )
+    : Pattern( filterString )
+    , m_wildcardPattern( toLower( name ), CaseSensitive::No )
     {}
+
     bool TestSpec::NamePattern::matches( TestCaseInfo const& testCase ) const {
-        return m_wildcardPattern.matches( toLower( testCase.name ) );
+        return m_wildcardPattern.matches( testCase.name );
     }
 
-    TestSpec::TagPattern::TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {}
+
+    TestSpec::TagPattern::TagPattern( std::string const& tag, std::string const& filterString )
+    : Pattern( filterString )
+    , m_tag( toLower( tag ) )
+    {}
+
     bool TestSpec::TagPattern::matches( TestCaseInfo const& testCase ) const {
         return std::find(begin(testCase.lcaseTags),
                          end(testCase.lcaseTags),
                          m_tag) != end(testCase.lcaseTags);
     }
 
-    TestSpec::ExcludedPattern::ExcludedPattern( PatternPtr const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {}
-    bool TestSpec::ExcludedPattern::matches( TestCaseInfo const& testCase ) const { return !m_underlyingPattern->matches( testCase ); }
+
+    TestSpec::ExcludedPattern::ExcludedPattern( PatternPtr const& underlyingPattern )
+    : Pattern( underlyingPattern->name() )
+    , m_underlyingPattern( underlyingPattern )
+    {}
+
+    bool TestSpec::ExcludedPattern::matches( TestCaseInfo const& testCase ) const {
+        return !m_underlyingPattern->matches( testCase );
+    }
+
 
     bool TestSpec::Filter::matches( TestCaseInfo const& testCase ) const {
-        // All patterns in a filter must match for the filter to be a match
-        for( auto const& pattern : m_patterns ) {
-            if( !pattern->matches( testCase ) )
-                return false;
-        }
-        return true;
+        return std::all_of( m_patterns.begin(), m_patterns.end(), [&]( PatternPtr const& p ){ return p->matches( testCase ); } );
     }
 
+    std::string TestSpec::Filter::name() const {
+        std::string name;
+        for( auto const& p : m_patterns )
+            name += p->name();
+        return name;
+    }
+
+
     bool TestSpec::hasFilters() const {
         return !m_filters.empty();
     }
+
     bool TestSpec::matches( TestCaseInfo const& testCase ) const {
-        // A TestSpec matches if any filter matches
-        for( auto const& filter : m_filters )
-            if( filter.matches( testCase ) )
-                return true;
-        return false;
+        return std::any_of( m_filters.begin(), m_filters.end(), [&]( Filter const& f ){ return f.matches( testCase ); } );
+    }
+
+    TestSpec::Matches TestSpec::matchesByFilter( std::vector<TestCase> const& testCases, IConfig const& config ) const
+    {
+        Matches matches( m_filters.size() );
+        std::transform( m_filters.begin(), m_filters.end(), matches.begin(), [&]( Filter const& filter ){
+            std::vector<TestCase const*> currentMatches;
+            for( auto const& test : testCases )
+                if( isThrowSafe( test, config ) && filter.matches( test ) )
+                    currentMatches.emplace_back( &test );
+            return FilterMatch{ filter.name(), currentMatches };
+        } );
+        return matches;
     }
+    
+    const TestSpec::vectorStrings& TestSpec::getInvalidArgs() const{
+        return  (m_invalidArgs);
+    }
+
 }
diff --git a/packages/Catch2/include/internal/catch_test_spec.h b/packages/Catch2/include/internal/catch_test_spec.h
index baf8b0193..2e5464637 100644
--- a/packages/Catch2/include/internal/catch_test_spec.h
+++ b/packages/Catch2/include/internal/catch_test_spec.h
@@ -22,36 +22,40 @@
 
 namespace Catch {
 
+    struct IConfig;
+
     class TestSpec {
-        struct Pattern {
+        class Pattern {
+        public:
+            explicit Pattern( std::string const& name );
             virtual ~Pattern();
             virtual bool matches( TestCaseInfo const& testCase ) const = 0;
+            std::string const& name() const;
+        private:
+            std::string const m_name;
         };
         using PatternPtr = std::shared_ptr<Pattern>;
 
         class NamePattern : public Pattern {
         public:
-            NamePattern( std::string const& name );
-            virtual ~NamePattern();
-            virtual bool matches( TestCaseInfo const& testCase ) const override;
+            explicit NamePattern( std::string const& name, std::string const& filterString );
+            bool matches( TestCaseInfo const& testCase ) const override;
         private:
             WildcardPattern m_wildcardPattern;
         };
 
         class TagPattern : public Pattern {
         public:
-            TagPattern( std::string const& tag );
-            virtual ~TagPattern();
-            virtual bool matches( TestCaseInfo const& testCase ) const override;
+            explicit TagPattern( std::string const& tag, std::string const& filterString );
+            bool matches( TestCaseInfo const& testCase ) const override;
         private:
             std::string m_tag;
         };
 
         class ExcludedPattern : public Pattern {
         public:
-            ExcludedPattern( PatternPtr const& underlyingPattern );
-            virtual ~ExcludedPattern();
-            virtual bool matches( TestCaseInfo const& testCase ) const override;
+            explicit ExcludedPattern( PatternPtr const& underlyingPattern );
+            bool matches( TestCaseInfo const& testCase ) const override;
         private:
             PatternPtr m_underlyingPattern;
         };
@@ -60,15 +64,25 @@ namespace Catch {
             std::vector<PatternPtr> m_patterns;
 
             bool matches( TestCaseInfo const& testCase ) const;
+            std::string name() const;
         };
 
     public:
+        struct FilterMatch {
+            std::string name;
+            std::vector<TestCase const*> tests;
+        };
+        using Matches = std::vector<FilterMatch>;
+        using vectorStrings = std::vector<std::string>;
+
         bool hasFilters() const;
         bool matches( TestCaseInfo const& testCase ) const;
+        Matches matchesByFilter( std::vector<TestCase> const& testCases, IConfig const& config ) const;
+        const vectorStrings & getInvalidArgs() const;
 
     private:
         std::vector<Filter> m_filters;
-
+        std::vector<std::string> m_invalidArgs;
         friend class TestSpecParser;
     };
 }
diff --git a/packages/Catch2/include/internal/catch_test_spec_parser.cpp b/packages/Catch2/include/internal/catch_test_spec_parser.cpp
index 61c9e4df0..b872b1916 100644
--- a/packages/Catch2/include/internal/catch_test_spec_parser.cpp
+++ b/packages/Catch2/include/internal/catch_test_spec_parser.cpp
@@ -7,6 +7,7 @@
 
 #include "catch_test_spec_parser.h"
 
+
 namespace Catch {
 
     TestSpecParser::TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {}
@@ -14,64 +15,136 @@ namespace Catch {
     TestSpecParser& TestSpecParser::parse( std::string const& arg ) {
         m_mode = None;
         m_exclusion = false;
-        m_start = std::string::npos;
         m_arg = m_tagAliases->expandAliases( arg );
         m_escapeChars.clear();
+        m_substring.reserve(m_arg.size());
+        m_patternName.reserve(m_arg.size());
+        m_realPatternPos = 0;
+        
         for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
-            visitChar( m_arg[m_pos] );
-        if( m_mode == Name )
-            addPattern<TestSpec::NamePattern>();
+          //if visitChar fails
+           if( !visitChar( m_arg[m_pos] ) ){ 
+               m_testSpec.m_invalidArgs.push_back(arg);
+               break;
+           }
+        endMode();
         return *this;
     }
     TestSpec TestSpecParser::testSpec() {
         addFilter();
         return m_testSpec;
     }
+    bool TestSpecParser::visitChar( char c ) {
+        if( (m_mode != EscapedName) && (c == '\\') ) {
+            escape();
+            addCharToPattern(c);
+            return true;
+        }else if((m_mode != EscapedName) && (c == ',') )  {
+            return separate();
+        }
+
+        switch( m_mode ) {
+        case None:
+            if( processNoneChar( c ) )
+                return true;
+            break;
+        case Name:
+            processNameChar( c );
+            break;
+        case EscapedName:
+            endMode();
+            addCharToPattern(c);
+            return true;
+        default:
+        case Tag:
+        case QuotedName:
+            if( processOtherChar( c ) )
+                return true;
+            break;
+        }
 
-    void TestSpecParser::visitChar( char c ) {
-        if( m_mode == None ) {
-            switch( c ) {
-            case ' ': return;
-            case '~': m_exclusion = true; return;
-            case '[': return startNewMode( Tag, ++m_pos );
-            case '"': return startNewMode( QuotedName, ++m_pos );
-            case '\\': return escape();
-            default: startNewMode( Name, m_pos ); break;
-            }
+        m_substring += c;
+        if( !isControlChar( c ) ) {
+            m_patternName += c;
+            m_realPatternPos++;
         }
-        if( m_mode == Name ) {
-            if( c == ',' ) {
-                addPattern<TestSpec::NamePattern>();
-                addFilter();
-            }
-            else if( c == '[' ) {
-                if( subString() == "exclude:" )
-                    m_exclusion = true;
-                else
-                    addPattern<TestSpec::NamePattern>();
-                startNewMode( Tag, ++m_pos );
-            }
-            else if( c == '\\' )
-                escape();
+        return true;
+    }
+    // Two of the processing methods return true to signal the caller to return
+    // without adding the given character to the current pattern strings
+    bool TestSpecParser::processNoneChar( char c ) {
+        switch( c ) {
+        case ' ':
+            return true;
+        case '~':
+            m_exclusion = true;
+            return false;
+        case '[':
+            startNewMode( Tag );
+            return false;
+        case '"':
+            startNewMode( QuotedName );
+            return false;
+        default:
+            startNewMode( Name );
+            return false;
+        }
+    }
+    void TestSpecParser::processNameChar( char c ) {
+        if( c == '[' ) {
+            if( m_substring == "exclude:" )
+                m_exclusion = true;
+            else
+                endMode();
+            startNewMode( Tag );
         }
-        else if( m_mode == EscapedName )
-            m_mode = Name;
-        else if( m_mode == QuotedName && c == '"' )
-            addPattern<TestSpec::NamePattern>();
-        else if( m_mode == Tag && c == ']' )
-            addPattern<TestSpec::TagPattern>();
     }
-    void TestSpecParser::startNewMode( Mode mode, std::size_t start ) {
+    bool TestSpecParser::processOtherChar( char c ) {
+        if( !isControlChar( c ) )
+            return false;
+        m_substring += c;
+        endMode();
+        return true;
+    }
+    void TestSpecParser::startNewMode( Mode mode ) {
         m_mode = mode;
-        m_start = start;
+    }
+    void TestSpecParser::endMode() {
+        switch( m_mode ) {
+        case Name:
+        case QuotedName:
+            return addPattern<TestSpec::NamePattern>();
+        case Tag:
+            return addPattern<TestSpec::TagPattern>();
+        case EscapedName:
+            revertBackToLastMode();
+            return;
+        case None:
+        default:
+            return startNewMode( None );
+        }
     }
     void TestSpecParser::escape() {
-        if( m_mode == None )
-            m_start = m_pos;
+        saveLastMode();
         m_mode = EscapedName;
-        m_escapeChars.push_back( m_pos );
+        m_escapeChars.push_back(m_realPatternPos);
+    }
+    bool TestSpecParser::isControlChar( char c ) const {
+        switch( m_mode ) {
+            default:
+                return false;
+            case None:
+                return c == '~';
+            case Name:
+                return c == '[';
+            case EscapedName:
+                return true;
+            case QuotedName:
+                return c == '"';
+            case Tag:
+                return c == '[' || c == ']';
+        }
     }
-    std::string TestSpecParser::subString() const { return m_arg.substr( m_start, m_pos - m_start ); }
 
     void TestSpecParser::addFilter() {
         if( !m_currentFilter.m_patterns.empty() ) {
@@ -80,6 +153,28 @@ namespace Catch {
         }
     }
 
+    void TestSpecParser::saveLastMode() {
+      lastMode = m_mode;
+    }
+    
+    void TestSpecParser::revertBackToLastMode() {
+      m_mode = lastMode;
+    }
+    
+    bool TestSpecParser::separate() {  
+      if( (m_mode==QuotedName) || (m_mode==Tag) ){
+         //invalid argument, signal failure to previous scope.
+         m_mode = None;
+         m_pos = m_arg.size();
+         m_substring.clear();
+         m_patternName.clear();
+         return false;
+      }
+      endMode();
+      addFilter();
+      return true; //success
+    }
+    
     TestSpec parseTestSpec( std::string const& arg ) {
         return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
     }
diff --git a/packages/Catch2/include/internal/catch_test_spec_parser.h b/packages/Catch2/include/internal/catch_test_spec_parser.h
index 79ce88988..179d3532e 100644
--- a/packages/Catch2/include/internal/catch_test_spec_parser.h
+++ b/packages/Catch2/include/internal/catch_test_spec_parser.h
@@ -22,9 +22,13 @@ namespace Catch {
     class TestSpecParser {
         enum Mode{ None, Name, QuotedName, Tag, EscapedName };
         Mode m_mode = None;
+        Mode lastMode = None;
         bool m_exclusion = false;
-        std::size_t m_start = std::string::npos, m_pos = 0;
+        std::size_t m_pos = 0;
+        std::size_t m_realPatternPos = 0;
         std::string m_arg;
+        std::string m_substring;
+        std::string m_patternName;
         std::vector<std::size_t> m_escapeChars;
         TestSpec::Filter m_currentFilter;
         TestSpec m_testSpec;
@@ -37,32 +41,47 @@ namespace Catch {
         TestSpec testSpec();
 
     private:
-        void visitChar( char c );
-        void startNewMode( Mode mode, std::size_t start );
+        bool visitChar( char c );
+        void startNewMode( Mode mode );
+        bool processNoneChar( char c );
+        void processNameChar( char c );
+        bool processOtherChar( char c );
+        void endMode();
         void escape();
-        std::string subString() const;
-
+        bool isControlChar( char c ) const;
+        void saveLastMode();
+        void revertBackToLastMode();
+        void addFilter();
+        bool separate();
+        
         template<typename T>
         void addPattern() {
-            std::string token = subString();
+            std::string token = m_patternName;
             for( std::size_t i = 0; i < m_escapeChars.size(); ++i )
-                token = token.substr( 0, m_escapeChars[i]-m_start-i ) + token.substr( m_escapeChars[i]-m_start-i+1 );
+                token = token.substr( 0, m_escapeChars[i] - i ) + token.substr( m_escapeChars[i] -i +1 );
             m_escapeChars.clear();
             if( startsWith( token, "exclude:" ) ) {
                 m_exclusion = true;
                 token = token.substr( 8 );
             }
             if( !token.empty() ) {
-                TestSpec::PatternPtr pattern = std::make_shared<T>( token );
+                TestSpec::PatternPtr pattern = std::make_shared<T>( token, m_substring );
                 if( m_exclusion )
                     pattern = std::make_shared<TestSpec::ExcludedPattern>( pattern );
                 m_currentFilter.m_patterns.push_back( pattern );
             }
+            m_substring.clear();
+            m_patternName.clear();
             m_exclusion = false;
             m_mode = None;
         }
-
-        void addFilter();
+        
+        inline void addCharToPattern(char c) {
+            m_substring += c;
+            m_patternName += c;
+            m_realPatternPos++;
+        }
+        
     };
     TestSpec parseTestSpec( std::string const& arg );
 
@@ -72,4 +91,4 @@ namespace Catch {
 #pragma clang diagnostic pop
 #endif
 
-#endif // TWOBLUECUBES_CATCH_TEST_SPEC_PARSER_HPP_INCLUDED
+#endif // TWOBLUECUBES_CATCH_TEST_SPEC_PARSER_HPP_INCLUDED
\ No newline at end of file
diff --git a/packages/Catch2/include/internal/catch_tostring.cpp b/packages/Catch2/include/internal/catch_tostring.cpp
index b857d3fbc..2f66f49dc 100644
--- a/packages/Catch2/include/internal/catch_tostring.cpp
+++ b/packages/Catch2/include/internal/catch_tostring.cpp
@@ -170,6 +170,12 @@ std::string StringMaker<wchar_t *>::convert(wchar_t * str) {
 }
 #endif
 
+#if defined(CATCH_CONFIG_CPP17_BYTE)
+#include <cstddef>
+std::string StringMaker<std::byte>::convert(std::byte value) {
+    return ::Catch::Detail::stringify(std::to_integer<unsigned long long>(value));
+}
+#endif // defined(CATCH_CONFIG_CPP17_BYTE)
 
 std::string StringMaker<int>::convert(int value) {
     return ::Catch::Detail::stringify(static_cast<long long>(value));
@@ -234,11 +240,16 @@ std::string StringMaker<std::nullptr_t>::convert(std::nullptr_t) {
     return "nullptr";
 }
 
+int StringMaker<float>::precision = 5;
+   
 std::string StringMaker<float>::convert(float value) {
-    return fpToString(value, 5) + 'f';
+    return fpToString(value, precision) + 'f';
 }
+
+int StringMaker<double>::precision = 10;
+    
 std::string StringMaker<double>::convert(double value) {
-    return fpToString(value, 10);
+    return fpToString(value, precision);
 }
 
 std::string ratio_string<std::atto>::symbol() { return "a"; }
diff --git a/packages/Catch2/include/internal/catch_tostring.h b/packages/Catch2/include/internal/catch_tostring.h
index 13a43b0c8..640fc8cbd 100644
--- a/packages/Catch2/include/internal/catch_tostring.h
+++ b/packages/Catch2/include/internal/catch_tostring.h
@@ -15,6 +15,7 @@
 #include <string>
 #include "catch_compiler_capabilities.h"
 #include "catch_stream.h"
+#include "catch_interfaces_enum_values_registry.h"
 
 #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
 #include <string_view>
@@ -43,9 +44,9 @@ namespace Catch {
 
         template<typename T>
         class IsStreamInsertable {
-            template<typename SS, typename TT>
+            template<typename Stream, typename U>
             static auto test(int)
-                -> decltype(std::declval<SS&>() << std::declval<TT>(), std::true_type());
+                -> decltype(std::declval<Stream&>() << std::declval<U>(), std::true_type());
 
             template<typename, typename>
             static auto test(...)->std::false_type;
@@ -209,6 +210,12 @@ namespace Catch {
         }
     };
 
+#if defined(CATCH_CONFIG_CPP17_BYTE)
+    template<>
+    struct StringMaker<std::byte> {
+        static std::string convert(std::byte value);
+    };
+#endif // defined(CATCH_CONFIG_CPP17_BYTE)
     template<>
     struct StringMaker<int> {
         static std::string convert(int value);
@@ -260,10 +267,13 @@ namespace Catch {
     template<>
     struct StringMaker<float> {
         static std::string convert(float value);
+        static int precision;
     };
+
     template<>
     struct StringMaker<double> {
         static std::string convert(double value);
+        static int precision;
     };
 
     template <typename T>
@@ -639,6 +649,17 @@ struct ratio_string<std::milli> {
 }
 #endif // CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
 
+#define INTERNAL_CATCH_REGISTER_ENUM( enumName, ... ) \
+namespace Catch { \
+    template<> struct StringMaker<enumName> { \
+        static std::string convert( enumName value ) { \
+            static const auto& enumInfo = ::Catch::getMutableRegistryHub().getMutableEnumValuesRegistry().registerEnum( #enumName, #__VA_ARGS__, { __VA_ARGS__ } ); \
+            return static_cast<std::string>(enumInfo.lookup( static_cast<int>( value ) )); \
+        } \
+    }; \
+}
+
+#define CATCH_REGISTER_ENUM( enumName, ... ) INTERNAL_CATCH_REGISTER_ENUM( enumName, __VA_ARGS__ )
 
 #ifdef _MSC_VER
 #pragma warning(pop)
diff --git a/packages/Catch2/include/internal/catch_type_traits.hpp b/packages/Catch2/include/internal/catch_type_traits.hpp
deleted file mode 100644
index 8edb1ecf0..000000000
--- a/packages/Catch2/include/internal/catch_type_traits.hpp
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- *  Created by Jozef on 12/11/2018.
- *  Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
- *
- *  Distributed under the Boost Software License, Version 1.0. (See accompanying
- *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- */
-
-#ifndef TWOBLUECUBES_CATCH_TYPE_TRAITS_HPP_INCLUDED
-#define TWOBLUECUBES_CATCH_TYPE_TRAITS_HPP_INCLUDED
-
-#include <type_traits>
-
-namespace Catch{
-
-#ifdef CATCH_CPP17_OR_GREATER
-	template <typename...>
-	inline constexpr auto is_unique = std::true_type{};
-
-	template <typename T, typename... Rest>
-	inline constexpr auto is_unique<T, Rest...> = std::bool_constant<
-		(!std::is_same_v<T, Rest> && ...) && is_unique<Rest...>
-	>{};
-#else
-
-template <typename...>
-struct is_unique : std::true_type{};
-
-template <typename T0, typename T1, typename... Rest>
-struct is_unique<T0, T1, Rest...> : std::integral_constant
-<bool,
-     !std::is_same<T0, T1>::value 
-     && is_unique<T0, Rest...>::value 
-     && is_unique<T1, Rest...>::value
->{};
-
-#endif
-}
-
-#endif // TWOBLUECUBES_CATCH_TYPE_TRAITS_HPP_INCLUDED
diff --git a/packages/Catch2/include/internal/catch_version.cpp b/packages/Catch2/include/internal/catch_version.cpp
index 43832053c..bb5b06163 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, 7, 1, "", 0 );
+        static Version version( 2, 10, 0, "", 0 );
         return version;
     }
 
diff --git a/packages/Catch2/include/internal/catch_wildcard_pattern.cpp b/packages/Catch2/include/internal/catch_wildcard_pattern.cpp
index 9bf20f044..95e5d3f0b 100644
--- a/packages/Catch2/include/internal/catch_wildcard_pattern.cpp
+++ b/packages/Catch2/include/internal/catch_wildcard_pattern.cpp
@@ -9,14 +9,12 @@
 #include "catch_enforce.h"
 #include "catch_string_manip.h"
 
-#include <sstream>
-
 namespace Catch {
 
     WildcardPattern::WildcardPattern( std::string const& pattern,
                                       CaseSensitive::Choice caseSensitivity )
     :   m_caseSensitivity( caseSensitivity ),
-        m_pattern( adjustCase( pattern ) )
+        m_pattern( normaliseString( pattern ) )
     {
         if( startsWith( m_pattern, '*' ) ) {
             m_pattern = m_pattern.substr( 1 );
@@ -31,19 +29,19 @@ namespace Catch {
     bool WildcardPattern::matches( std::string const& str ) const {
         switch( m_wildcard ) {
             case NoWildcard:
-                return m_pattern == adjustCase( str );
+                return m_pattern == normaliseString( str );
             case WildcardAtStart:
-                return endsWith( adjustCase( str ), m_pattern );
+                return endsWith( normaliseString( str ), m_pattern );
             case WildcardAtEnd:
-                return startsWith( adjustCase( str ), m_pattern );
+                return startsWith( normaliseString( str ), m_pattern );
             case WildcardAtBothEnds:
-                return contains( adjustCase( str ), m_pattern );
+                return contains( normaliseString( str ), m_pattern );
             default:
                 CATCH_INTERNAL_ERROR( "Unknown enum" );
         }
     }
 
-    std::string WildcardPattern::adjustCase( std::string const& str ) const {
-        return m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str;
+    std::string WildcardPattern::normaliseString( std::string const& str ) const {
+        return trim( m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str );
     }
 }
diff --git a/packages/Catch2/include/internal/catch_wildcard_pattern.h b/packages/Catch2/include/internal/catch_wildcard_pattern.h
index 4dae71714..5d508f7ba 100644
--- a/packages/Catch2/include/internal/catch_wildcard_pattern.h
+++ b/packages/Catch2/include/internal/catch_wildcard_pattern.h
@@ -28,7 +28,7 @@ namespace Catch
         virtual bool matches( std::string const& str ) const;
 
     private:
-        std::string adjustCase( std::string const& str ) const;
+        std::string normaliseString( std::string const& str ) const;
         CaseSensitive::Choice m_caseSensitivity;
         WildcardPosition m_wildcard = NoWildcard;
         std::string m_pattern;
diff --git a/packages/Catch2/include/reporters/catch_reporter_bases.hpp b/packages/Catch2/include/reporters/catch_reporter_bases.hpp
index a9b0640c3..66a891ffd 100644
--- a/packages/Catch2/include/reporters/catch_reporter_bases.hpp
+++ b/packages/Catch2/include/reporters/catch_reporter_bases.hpp
@@ -51,6 +51,8 @@ namespace Catch {
 
         void noMatchingTestCases(std::string const&) override {}
 
+        void reportInvalidArguments(std::string const&) override {}
+        
         void testRunStarting(TestRunInfo const& _testRunInfo) override {
             currentTestRunInfo = _testRunInfo;
         }
@@ -277,4 +279,4 @@ namespace Catch {
 
 } // end namespace Catch
 
-#endif // TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED
+#endif // TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED
\ No newline at end of file
diff --git a/packages/Catch2/include/reporters/catch_reporter_compact.cpp b/packages/Catch2/include/reporters/catch_reporter_compact.cpp
index 65f70266d..017f521f4 100644
--- a/packages/Catch2/include/reporters/catch_reporter_compact.cpp
+++ b/packages/Catch2/include/reporters/catch_reporter_compact.cpp
@@ -8,7 +8,7 @@
 #include "catch_reporter_compact.h"
 
 #include "../internal/catch_reporter_registrars.hpp"
-#include "internal/catch_console_colour.h"
+#include "../internal/catch_console_colour.h"
 
 namespace {
 
@@ -209,24 +209,25 @@ private:
         if (itMessage == messages.end())
             return;
 
-        // using messages.end() directly yields (or auto) compilation error:
-        std::vector<MessageInfo>::const_iterator itEnd = messages.end();
-        const std::size_t N = static_cast<std::size_t>(std::distance(itMessage, itEnd));
+        const auto itEnd = messages.cend();
+        const auto N = static_cast<std::size_t>(std::distance(itMessage, itEnd));
 
         {
             Colour colourGuard(colour);
             stream << " with " << pluralise(N, "message") << ':';
         }
 
-        for (; itMessage != itEnd; ) {
+        while (itMessage != itEnd) {
             // If this assertion is a warning ignore any INFO messages
             if (printInfoMessages || itMessage->type != ResultWas::Info) {
-                stream << " '" << itMessage->message << '\'';
-                if (++itMessage != itEnd) {
+                printMessage();
+                if (itMessage != itEnd) {
                     Colour colourGuard(dimColour());
                     stream << " and";
                 }
+                continue;
             }
+            ++itMessage;
         }
     }
 
diff --git a/packages/Catch2/include/reporters/catch_reporter_console.cpp b/packages/Catch2/include/reporters/catch_reporter_console.cpp
index 53b977eb1..be00d0bdf 100644
--- a/packages/Catch2/include/reporters/catch_reporter_console.cpp
+++ b/packages/Catch2/include/reporters/catch_reporter_console.cpp
@@ -9,7 +9,7 @@
 #include "catch_reporter_console.h"
 
 #include "../internal/catch_reporter_registrars.hpp"
-#include "internal/catch_console_colour.h"
+#include "../internal/catch_console_colour.h"
 #include "../internal/catch_version.h"
 #include "../internal/catch_text.h"
 #include "../internal/catch_stringref.h"
@@ -20,11 +20,17 @@
 #if defined(_MSC_VER)
 #pragma warning(push)
 #pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
- // Note that 4062 (not all labels are handled
- // and default is missing) is enabled
+ // Note that 4062 (not all labels are handled and default is missing) is enabled
+#endif
+
+#if defined(__clang__)
+#  pragma clang diagnostic push
+// For simplicity, benchmarking-only helpers are always enabled
+#  pragma clang diagnostic ignored "-Wunused-function"
 #endif
 
 
+
 namespace Catch {
 
 namespace {
@@ -208,6 +214,10 @@ class Duration {
     Unit m_units;
 
 public:
+	explicit Duration(double inNanoseconds, Unit units = Unit::Auto)
+        : Duration(static_cast<uint64_t>(inNanoseconds), units) {
+    }
+
     explicit Duration(uint64_t inNanoseconds, Unit units = Unit::Auto)
         : m_inNanoseconds(inNanoseconds),
         m_units(units) {
@@ -258,7 +268,7 @@ public:
 
     }
     friend auto operator << (std::ostream& os, Duration const& duration) -> std::ostream& {
-        return os << duration.value() << " " << duration.unitsAsString();
+        return os << duration.value() << ' ' << duration.unitsAsString();
     }
 };
 } // end anon namespace
@@ -283,10 +293,16 @@ public:
         if (!m_isOpen) {
             m_isOpen = true;
             *this << RowBreak();
-            for (auto const& info : m_columnInfos)
-                *this << info.name << ColumnBreak();
-            *this << RowBreak();
-            m_os << Catch::getLineOfChars<'-'>() << "\n";
+
+			Columns headerCols;
+			Spacer spacer(2);
+			for (auto const& info : m_columnInfos) {
+				headerCols += Column(info.name).width(static_cast<std::size_t>(info.width - 2));
+				headerCols += spacer;
+			}
+			m_os << headerCols << '\n';
+
+            m_os << Catch::getLineOfChars<'-'>() << '\n';
         }
     }
     void close() {
@@ -305,30 +321,29 @@ public:
 
     friend TablePrinter& operator << (TablePrinter& tp, ColumnBreak) {
         auto colStr = tp.m_oss.str();
-        // This takes account of utf8 encodings
-        auto strSize = Catch::StringRef(colStr).numberOfCharacters();
+        const auto strSize = colStr.size();
         tp.m_oss.str("");
         tp.open();
         if (tp.m_currentColumn == static_cast<int>(tp.m_columnInfos.size() - 1)) {
             tp.m_currentColumn = -1;
-            tp.m_os << "\n";
+            tp.m_os << '\n';
         }
         tp.m_currentColumn++;
 
         auto colInfo = tp.m_columnInfos[tp.m_currentColumn];
-        auto padding = (strSize + 2 < static_cast<std::size_t>(colInfo.width))
-            ? std::string(colInfo.width - (strSize + 2), ' ')
+        auto padding = (strSize + 1 < static_cast<std::size_t>(colInfo.width))
+            ? std::string(colInfo.width - (strSize + 1), ' ')
             : std::string();
         if (colInfo.justification == ColumnInfo::Left)
-            tp.m_os << colStr << padding << " ";
+            tp.m_os << colStr << padding << ' ';
         else
-            tp.m_os << padding << colStr << " ";
+            tp.m_os << padding << colStr << ' ';
         return tp;
     }
 
     friend TablePrinter& operator << (TablePrinter& tp, RowBreak) {
         if (tp.m_currentColumn > 0) {
-            tp.m_os << "\n";
+            tp.m_os << '\n';
             tp.m_currentColumn = -1;
         }
         return tp;
@@ -338,12 +353,26 @@ public:
 ConsoleReporter::ConsoleReporter(ReporterConfig const& config)
     : StreamingReporterBase(config),
     m_tablePrinter(new TablePrinter(config.stream(),
-    {
-        { "benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 32, ColumnInfo::Left },
-        { "iters", 8, ColumnInfo::Right },
-        { "elapsed ns", 14, ColumnInfo::Right },
-        { "average", 14, ColumnInfo::Right }
-    })) {}
+        [&config]() -> std::vector<ColumnInfo> {
+        if (config.fullConfig()->benchmarkNoAnalysis())
+        {
+            return{
+                { "benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 43, ColumnInfo::Left },
+                { "     samples", 14, ColumnInfo::Right },
+                { "  iterations", 14, ColumnInfo::Right },
+                { "        mean", 14, ColumnInfo::Right }
+            };
+        }
+        else
+        {
+            return{
+                { "benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 32, ColumnInfo::Left },
+                { "samples      mean       std dev", 14, ColumnInfo::Right },
+                { "iterations   low mean   low std dev", 14, ColumnInfo::Right },
+                { "estimated    high mean  high std dev", 14, ColumnInfo::Right }
+            };
+        }
+    }())) {}
 ConsoleReporter::~ConsoleReporter() = default;
 
 std::string ConsoleReporter::getDescription() {
@@ -354,6 +383,10 @@ void ConsoleReporter::noMatchingTestCases(std::string const& spec) {
     stream << "No test cases matched '" << spec << '\'' << std::endl;
 }
 
+void ConsoleReporter::reportInvalidArguments(std::string const&arg){
+    stream << "Invalid Filter: " << arg << std::endl;
+}
+
 void ConsoleReporter::assertionStarting(AssertionInfo const&) {}
 
 bool ConsoleReporter::assertionEnded(AssertionStats const& _assertionStats) {
@@ -374,6 +407,7 @@ bool ConsoleReporter::assertionEnded(AssertionStats const& _assertionStats) {
 }
 
 void ConsoleReporter::sectionStarting(SectionInfo const& _sectionInfo) {
+    m_tablePrinter->close();
     m_headerPrinted = false;
     StreamingReporterBase::sectionStarting(_sectionInfo);
 }
@@ -397,29 +431,53 @@ void ConsoleReporter::sectionEnded(SectionStats const& _sectionStats) {
     StreamingReporterBase::sectionEnded(_sectionStats);
 }
 
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+void ConsoleReporter::benchmarkPreparing(std::string const& name) {
+	lazyPrintWithoutClosingBenchmarkTable();
 
-void ConsoleReporter::benchmarkStarting(BenchmarkInfo const& info) {
-    lazyPrintWithoutClosingBenchmarkTable();
+	auto nameCol = Column(name).width(static_cast<std::size_t>(m_tablePrinter->columnInfos()[0].width - 2));
 
-    auto nameCol = Column( info.name ).width( static_cast<std::size_t>( m_tablePrinter->columnInfos()[0].width - 2 ) );
+	bool firstLine = true;
+	for (auto line : nameCol) {
+		if (!firstLine)
+			(*m_tablePrinter) << ColumnBreak() << ColumnBreak() << ColumnBreak();
+		else
+			firstLine = false;
 
-    bool firstLine = true;
-    for (auto line : nameCol) {
-        if (!firstLine)
-            (*m_tablePrinter) << ColumnBreak() << ColumnBreak() << ColumnBreak();
-        else
-            firstLine = false;
+		(*m_tablePrinter) << line << ColumnBreak();
+	}
+}
 
-        (*m_tablePrinter) << line << ColumnBreak();
+void ConsoleReporter::benchmarkStarting(BenchmarkInfo const& info) {
+    (*m_tablePrinter) << info.samples << ColumnBreak()
+        << info.iterations << ColumnBreak();
+    if (!m_config->benchmarkNoAnalysis())
+        (*m_tablePrinter) << Duration(info.estimatedDuration) << ColumnBreak();
+}
+void ConsoleReporter::benchmarkEnded(BenchmarkStats<> const& stats) {
+    if (m_config->benchmarkNoAnalysis())
+    {
+        (*m_tablePrinter) << Duration(stats.mean.point.count()) << ColumnBreak();
+    }
+    else
+    {
+        (*m_tablePrinter) << ColumnBreak()
+            << Duration(stats.mean.point.count()) << ColumnBreak()
+            << Duration(stats.mean.lower_bound.count()) << ColumnBreak()
+            << Duration(stats.mean.upper_bound.count()) << ColumnBreak() << ColumnBreak()
+            << Duration(stats.standardDeviation.point.count()) << ColumnBreak()
+            << Duration(stats.standardDeviation.lower_bound.count()) << ColumnBreak()
+            << Duration(stats.standardDeviation.upper_bound.count()) << ColumnBreak() << ColumnBreak() << ColumnBreak() << ColumnBreak() << ColumnBreak();
     }
 }
-void ConsoleReporter::benchmarkEnded(BenchmarkStats const& stats) {
-    Duration average(stats.elapsedTimeInNanoseconds / stats.iterations);
+
+void ConsoleReporter::benchmarkFailed(std::string const& error) {
+	Colour colour(Colour::Red);
     (*m_tablePrinter)
-        << stats.iterations << ColumnBreak()
-        << stats.elapsedTimeInNanoseconds << ColumnBreak()
-        << average << ColumnBreak();
+        << "Benchmark failed (" << error << ')'
+        << ColumnBreak() << RowBreak();
 }
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
 
 void ConsoleReporter::testCaseEnded(TestCaseStats const& _testCaseStats) {
     m_tablePrinter->close();
@@ -498,11 +556,10 @@ void ConsoleReporter::printTestCaseAndSectionHeader() {
 
     SourceLineInfo lineInfo = m_sectionStack.back().lineInfo;
 
-    if (!lineInfo.empty()) {
-        stream << getLineOfChars<'-'>() << '\n';
-        Colour colourGuard(Colour::FileName);
-        stream << lineInfo << '\n';
-    }
+
+    stream << getLineOfChars<'-'>() << '\n';
+    Colour colourGuard(Colour::FileName);
+    stream << lineInfo << '\n';
     stream << getLineOfChars<'.'>() << '\n' << std::endl;
 }
 
@@ -638,3 +695,7 @@ CATCH_REGISTER_REPORTER("console", ConsoleReporter)
 #if defined(_MSC_VER)
 #pragma warning(pop)
 #endif
+
+#if defined(__clang__)
+#  pragma clang diagnostic pop
+#endif
\ No newline at end of file
diff --git a/packages/Catch2/include/reporters/catch_reporter_console.h b/packages/Catch2/include/reporters/catch_reporter_console.h
index effa58d34..43024dafd 100644
--- a/packages/Catch2/include/reporters/catch_reporter_console.h
+++ b/packages/Catch2/include/reporters/catch_reporter_console.h
@@ -32,6 +32,8 @@ namespace Catch {
 
         void noMatchingTestCases(std::string const& spec) override;
 
+        void reportInvalidArguments(std::string const&arg) override;
+
         void assertionStarting(AssertionInfo const&) override;
 
         bool assertionEnded(AssertionStats const& _assertionStats) override;
@@ -39,9 +41,12 @@ namespace Catch {
         void sectionStarting(SectionInfo const& _sectionInfo) override;
         void sectionEnded(SectionStats const& _sectionStats) override;
 
-
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+        void benchmarkPreparing(std::string const& name) override;
         void benchmarkStarting(BenchmarkInfo const& info) override;
-        void benchmarkEnded(BenchmarkStats const& stats) override;
+        void benchmarkEnded(BenchmarkStats<> const& stats) override;
+        void benchmarkFailed(std::string const& error) override;
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
 
         void testCaseEnded(TestCaseStats const& _testCaseStats) override;
         void testGroupEnded(TestGroupStats const& _testGroupStats) override;
@@ -81,4 +86,4 @@ namespace Catch {
 #pragma warning(pop)
 #endif
 
-#endif // TWOBLUECUBES_CATCH_REPORTER_CONSOLE_H_INCLUDED
+#endif // TWOBLUECUBES_CATCH_REPORTER_CONSOLE_H_INCLUDED
\ No newline at end of file
diff --git a/packages/Catch2/include/reporters/catch_reporter_listening.cpp b/packages/Catch2/include/reporters/catch_reporter_listening.cpp
index 9ddae2f2e..91e6b39a9 100644
--- a/packages/Catch2/include/reporters/catch_reporter_listening.cpp
+++ b/packages/Catch2/include/reporters/catch_reporter_listening.cpp
@@ -41,20 +41,42 @@ namespace Catch {
         }
         m_reporter->noMatchingTestCases( spec );
     }
-
+    
+    void ListeningReporter::reportInvalidArguments(std::string const&arg){
+        for ( auto const& listener : m_listeners ) {
+            listener->reportInvalidArguments( arg );
+        }
+        m_reporter->reportInvalidArguments( arg );
+    }    
+
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+    void ListeningReporter::benchmarkPreparing( std::string const& name ) {
+		for (auto const& listener : m_listeners) {
+			listener->benchmarkPreparing(name);
+		}
+		m_reporter->benchmarkPreparing(name);
+	}
     void ListeningReporter::benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) {
         for ( auto const& listener : m_listeners ) {
             listener->benchmarkStarting( benchmarkInfo );
         }
         m_reporter->benchmarkStarting( benchmarkInfo );
     }
-    void ListeningReporter::benchmarkEnded( BenchmarkStats const& benchmarkStats ) {
+    void ListeningReporter::benchmarkEnded( BenchmarkStats<> const& benchmarkStats ) {
         for ( auto const& listener : m_listeners ) {
             listener->benchmarkEnded( benchmarkStats );
         }
         m_reporter->benchmarkEnded( benchmarkStats );
     }
 
+	void ListeningReporter::benchmarkFailed( std::string const& error ) {
+		for (auto const& listener : m_listeners) {
+			listener->benchmarkFailed(error);
+		}
+		m_reporter->benchmarkFailed(error);
+	}
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
+
     void ListeningReporter::testRunStarting( TestRunInfo const& testRunInfo ) {
         for ( auto const& listener : m_listeners ) {
             listener->testRunStarting( testRunInfo );
@@ -139,4 +161,4 @@ namespace Catch {
         return true;
     }
 
-} // end namespace Catch
+} // end namespace Catch
\ No newline at end of file
diff --git a/packages/Catch2/include/reporters/catch_reporter_listening.h b/packages/Catch2/include/reporters/catch_reporter_listening.h
index dddd7a518..bfaa3085e 100644
--- a/packages/Catch2/include/reporters/catch_reporter_listening.h
+++ b/packages/Catch2/include/reporters/catch_reporter_listening.h
@@ -28,11 +28,17 @@ namespace Catch {
         ReporterPreferences getPreferences() const override;
 
         void noMatchingTestCases( std::string const& spec ) override;
-
+        
+        void reportInvalidArguments(std::string const&arg) override;
+        
         static std::set<Verbosity> getSupportedVerbosities();
 
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+        void benchmarkPreparing(std::string const& name) override;
         void benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) override;
-        void benchmarkEnded( BenchmarkStats const& benchmarkStats ) override;
+        void benchmarkEnded( BenchmarkStats<> const& benchmarkStats ) override;
+        void benchmarkFailed(std::string const&) override;
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
 
         void testRunStarting( TestRunInfo const& testRunInfo ) override;
         void testGroupStarting( GroupInfo const& groupInfo ) override;
@@ -54,4 +60,4 @@ namespace Catch {
 
 } // end namespace Catch
 
-#endif // TWOBLUECUBES_CATCH_MULTI_REPORTER_H_INCLUDED
+#endif // TWOBLUECUBES_CATCH_MULTI_REPORTER_H_INCLUDED
\ No newline at end of file
diff --git a/packages/Catch2/include/reporters/catch_reporter_teamcity.hpp b/packages/Catch2/include/reporters/catch_reporter_teamcity.hpp
index eca2885cd..47b7e4aac 100644
--- a/packages/Catch2/include/reporters/catch_reporter_teamcity.hpp
+++ b/packages/Catch2/include/reporters/catch_reporter_teamcity.hpp
@@ -183,8 +183,7 @@ namespace Catch {
 
             SourceLineInfo lineInfo = m_sectionStack.front().lineInfo;
 
-            if( !lineInfo.empty() )
-                os << lineInfo << "\n";
+            os << lineInfo << "\n";
             os << getLineOfChars<'.'>() << "\n\n";
         }
 
diff --git a/packages/Catch2/include/reporters/catch_reporter_xml.cpp b/packages/Catch2/include/reporters/catch_reporter_xml.cpp
index c7572d1eb..26ca8918c 100644
--- a/packages/Catch2/include/reporters/catch_reporter_xml.cpp
+++ b/packages/Catch2/include/reporters/catch_reporter_xml.cpp
@@ -219,6 +219,51 @@ namespace Catch {
         m_xml.endElement();
     }
 
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+    void XmlReporter::benchmarkPreparing(std::string const& name) {
+        m_xml.startElement("BenchmarkResults")
+            .writeAttribute("name", name);
+    }
+
+    void XmlReporter::benchmarkStarting(BenchmarkInfo const &info) {
+        m_xml.writeAttribute("samples", info.samples)
+            .writeAttribute("resamples", info.resamples)
+            .writeAttribute("iterations", info.iterations)
+            .writeAttribute("clockResolution", static_cast<uint64_t>(info.clockResolution))
+            .writeAttribute("estimatedDuration", static_cast<uint64_t>(info.estimatedDuration))
+            .writeComment("All values in nano seconds");
+    }
+
+    void XmlReporter::benchmarkEnded(BenchmarkStats<> const& benchmarkStats) {
+        m_xml.startElement("mean")
+            .writeAttribute("value", static_cast<uint64_t>(benchmarkStats.mean.point.count()))
+            .writeAttribute("lowerBound", static_cast<uint64_t>(benchmarkStats.mean.lower_bound.count()))
+            .writeAttribute("upperBound", static_cast<uint64_t>(benchmarkStats.mean.upper_bound.count()))
+            .writeAttribute("ci", benchmarkStats.mean.confidence_interval);
+        m_xml.endElement();
+        m_xml.startElement("standardDeviation")
+            .writeAttribute("value", benchmarkStats.standardDeviation.point.count())
+            .writeAttribute("lowerBound", benchmarkStats.standardDeviation.lower_bound.count())
+            .writeAttribute("upperBound", benchmarkStats.standardDeviation.upper_bound.count())
+            .writeAttribute("ci", benchmarkStats.standardDeviation.confidence_interval);
+        m_xml.endElement();
+        m_xml.startElement("outliers")
+            .writeAttribute("variance", benchmarkStats.outlierVariance)
+            .writeAttribute("lowMild", benchmarkStats.outliers.low_mild)
+            .writeAttribute("lowSevere", benchmarkStats.outliers.low_severe)
+            .writeAttribute("highMild", benchmarkStats.outliers.high_mild)
+            .writeAttribute("highSevere", benchmarkStats.outliers.high_severe);
+        m_xml.endElement();
+        m_xml.endElement();
+    }
+
+    void XmlReporter::benchmarkFailed(std::string const &error) {
+        m_xml.scopedElement("failed").
+            writeAttribute("message", error);
+        m_xml.endElement();
+    }
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
+
     CATCH_REGISTER_REPORTER( "xml", XmlReporter )
 
 } // end namespace Catch
diff --git a/packages/Catch2/include/reporters/catch_reporter_xml.h b/packages/Catch2/include/reporters/catch_reporter_xml.h
index 7926f93a8..5b6ba3105 100644
--- a/packages/Catch2/include/reporters/catch_reporter_xml.h
+++ b/packages/Catch2/include/reporters/catch_reporter_xml.h
@@ -50,6 +50,13 @@ namespace Catch {
 
         void testRunEnded(TestRunStats const& testRunStats) override;
 
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+        void benchmarkPreparing(std::string const& name) override;
+        void benchmarkStarting(BenchmarkInfo const&) override;
+        void benchmarkEnded(BenchmarkStats<> const&) override;
+        void benchmarkFailed(std::string const&) override;
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
+
     private:
         Timer m_testCaseTimer;
         XmlWriter m_xml;
diff --git a/packages/Catch2/misc/appveyorMergeCoverageScript.py b/packages/Catch2/misc/appveyorMergeCoverageScript.py
index a74e6e0e8..93a47fffe 100644
--- a/packages/Catch2/misc/appveyorMergeCoverageScript.py
+++ b/packages/Catch2/misc/appveyorMergeCoverageScript.py
@@ -4,6 +4,6 @@ import glob
 import subprocess
 
 if __name__ == '__main__':
-    cov_files = list(glob.glob('cov-report*.bin'))
+    cov_files = list(glob.glob('projects/cov-report*.bin'))
     base_cmd = ['OpenCppCoverage', '--quiet', '--export_type=cobertura:cobertura.xml'] + ['--input_coverage={}'.format(f) for f in cov_files]
-    subprocess.call(base_cmd)
+    subprocess.check_call(base_cmd)
diff --git a/packages/Catch2/misc/coverage-helper.cpp b/packages/Catch2/misc/coverage-helper.cpp
index a6643838f..a31e927f5 100644
--- a/packages/Catch2/misc/coverage-helper.cpp
+++ b/packages/Catch2/misc/coverage-helper.cpp
@@ -29,7 +29,8 @@ std::string escape_arg(const std::string& arg) {
             escaped.append(num_backslashes * 2, '\\');
             break;
         } else if (*it == '"') {
-            escaped.append(num_backslashes * 2 + 1, '\\');
+            escaped.append((num_backslashes + 1) * 2, '\\');
+            escaped.push_back('"');
             escaped.push_back(*it);
         } else {
             escaped.append(num_backslashes, '\\');
@@ -89,27 +90,30 @@ std::string windowsify_path(std::string path) {
     return path;
 }
 
-void exec_cmd(std::string const& cmd, int log_num, std::string const& path) {
+int exec_cmd(std::string const& cmd, int log_num, std::string const& path) {
     std::array<char, 128> buffer;
-#if defined(_WIN32)
+
     // cmd has already been escaped outside this function.
     auto real_cmd = "OpenCppCoverage --export_type binary:cov-report" + std::to_string(log_num)
         + ".bin --quiet " + "--sources " + escape_arg(path) + " --cover_children -- " + cmd;
     std::cout << "=== Marker ===: Cmd: " << real_cmd << '\n';
-    std::shared_ptr<FILE> pipe(_popen(real_cmd.c_str(), "r"), _pclose);
-#else // Just for testing, in the real world we will always work under WIN32
-    (void)log_num; (void)path;
-    std::shared_ptr<FILE> pipe(popen(cmd.c_str(), "r"), pclose);
-#endif
+    auto pipe = _popen(real_cmd.c_str(), "r");
 
     if (!pipe) {
         throw std::runtime_error("popen() failed!");
     }
-    while (!feof(pipe.get())) {
-        if (fgets(buffer.data(), 128, pipe.get()) != nullptr) {
+    while (!feof(pipe)) {
+        if (fgets(buffer.data(), 128, pipe) != nullptr) {
             std::cout << buffer.data();
         }
     }
+
+    auto ret = _pclose(pipe);
+    if (ret == -1) {
+        throw std::runtime_error("underlying error in pclose()");
+    }
+
+    return ret;
 }
 
 // argv should be:
@@ -124,7 +128,7 @@ int main(int argc, char** argv) {
     assert(sep - begin(args) == 2 && "Structure differs from expected!");
 
     auto num = parse_log_file_arg(args[1]);
-    
+
     auto cmdline = std::accumulate(++sep, end(args), std::string{}, [] (const std::string& lhs, const std::string& rhs) {
         return lhs + ' ' + escape_arg(rhs);
     });
diff --git a/packages/Catch2/projects/CMakeLists.txt b/packages/Catch2/projects/CMakeLists.txt
index 37b0865ae..cbe21fcff 100644
--- a/packages/Catch2/projects/CMakeLists.txt
+++ b/packages/Catch2/projects/CMakeLists.txt
@@ -17,11 +17,16 @@ endif(MSVC) #Temporary workaround
 set(TEST_SOURCES
         ${SELF_TEST_DIR}/TestMain.cpp
         ${SELF_TEST_DIR}/IntrospectiveTests/CmdLine.tests.cpp
+        ${SELF_TEST_DIR}/IntrospectiveTests/Details.tests.cpp
         ${SELF_TEST_DIR}/IntrospectiveTests/GeneratorsImpl.tests.cpp
+        ${SELF_TEST_DIR}/IntrospectiveTests/InternalBenchmark.tests.cpp
         ${SELF_TEST_DIR}/IntrospectiveTests/PartTracker.tests.cpp
+        ${SELF_TEST_DIR}/IntrospectiveTests/RandomNumberGeneration.tests.cpp
         ${SELF_TEST_DIR}/IntrospectiveTests/Tag.tests.cpp
         ${SELF_TEST_DIR}/IntrospectiveTests/String.tests.cpp
+        ${SELF_TEST_DIR}/IntrospectiveTests/StringManip.tests.cpp
         ${SELF_TEST_DIR}/IntrospectiveTests/Xml.tests.cpp
+        ${SELF_TEST_DIR}/IntrospectiveTests/ToString.tests.cpp
         ${SELF_TEST_DIR}/UsageTests/Approx.tests.cpp
         ${SELF_TEST_DIR}/UsageTests/BDD.tests.cpp
         ${SELF_TEST_DIR}/UsageTests/Benchmark.tests.cpp
@@ -34,6 +39,7 @@ set(TEST_SOURCES
         ${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/ToStringByte.tests.cpp
         ${SELF_TEST_DIR}/UsageTests/ToStringChrono.tests.cpp
         ${SELF_TEST_DIR}/UsageTests/ToStringGeneral.tests.cpp
         ${SELF_TEST_DIR}/UsageTests/ToStringOptional.tests.cpp
@@ -78,6 +84,33 @@ CheckFileList(EXTERNAL_HEADERS ${HEADER_DIR}/external)
 
 
 # Please keep these ordered alphabetically
+set(BENCHMARK_HEADERS
+		${HEADER_DIR}/internal/benchmark/catch_benchmark.hpp
+        ${HEADER_DIR}/internal/benchmark/catch_chronometer.hpp
+        ${HEADER_DIR}/internal/benchmark/catch_clock.hpp
+        ${HEADER_DIR}/internal/benchmark/catch_constructor.hpp
+        ${HEADER_DIR}/internal/benchmark/catch_environment.hpp
+        ${HEADER_DIR}/internal/benchmark/catch_estimate.hpp
+        ${HEADER_DIR}/internal/benchmark/catch_execution_plan.hpp
+        ${HEADER_DIR}/internal/benchmark/catch_optimizer.hpp
+        ${HEADER_DIR}/internal/benchmark/catch_outlier_classification.hpp
+        ${HEADER_DIR}/internal/benchmark/catch_sample_analysis.hpp
+        ${HEADER_DIR}/internal/benchmark/detail/catch_analyse.hpp
+        ${HEADER_DIR}/internal/benchmark/detail/catch_benchmark_function.hpp
+        ${HEADER_DIR}/internal/benchmark/detail/catch_complete_invoke.hpp
+        ${HEADER_DIR}/internal/benchmark/detail/catch_estimate_clock.hpp
+        ${HEADER_DIR}/internal/benchmark/detail/catch_measure.hpp
+        ${HEADER_DIR}/internal/benchmark/detail/catch_repeat.hpp
+        ${HEADER_DIR}/internal/benchmark/detail/catch_run_for_at_least.hpp
+        ${HEADER_DIR}/internal/benchmark/detail/catch_stats.hpp
+        ${HEADER_DIR}/internal/benchmark/detail/catch_timing.hpp
+)
+set(BENCHMARK_SOURCES
+    ${HEADER_DIR}/internal/benchmark/detail/catch_stats.cpp
+)
+
+SOURCE_GROUP("benchmark" FILES ${BENCHMARK_HEADERS} ${BENCHMARK_SOURCES})
+
 set(INTERNAL_HEADERS
         ${HEADER_DIR}/internal/catch_approx.h
         ${HEADER_DIR}/internal/catch_assertionhandler.h
@@ -97,6 +130,7 @@ set(INTERNAL_HEADERS
         ${HEADER_DIR}/internal/catch_decomposer.h
         ${HEADER_DIR}/internal/catch_default_main.hpp
         ${HEADER_DIR}/internal/catch_enforce.h
+        ${HEADER_DIR}/internal/catch_enum_values_registry.h
         ${HEADER_DIR}/internal/catch_errno_guard.h
         ${HEADER_DIR}/internal/catch_exception_translator_registry.h
         ${HEADER_DIR}/internal/catch_external_interfaces.h
@@ -107,6 +141,7 @@ set(INTERNAL_HEADERS
         ${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_enum_values_registry.h
         ${HEADER_DIR}/internal/catch_interfaces_exception.h
         ${HEADER_DIR}/internal/catch_interfaces_registry_hub.h
         ${HEADER_DIR}/internal/catch_interfaces_reporter.h
@@ -116,6 +151,7 @@ set(INTERNAL_HEADERS
         ${HEADER_DIR}/internal/catch_leak_detector.h
         ${HEADER_DIR}/internal/catch_list.h
         ${HEADER_DIR}/internal/catch_matchers.h
+        ${HEADER_DIR}/internal/catch_matchers_exception.hpp
         ${HEADER_DIR}/internal/catch_matchers_floating.h
         ${HEADER_DIR}/internal/catch_matchers_generic.hpp
         ${HEADER_DIR}/internal/catch_matchers_string.h
@@ -135,7 +171,6 @@ set(INTERNAL_HEADERS
         ${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
@@ -159,7 +194,6 @@ set(INTERNAL_HEADERS
         ${HEADER_DIR}/internal/catch_to_string.hpp
         ${HEADER_DIR}/internal/catch_tostring.h
         ${HEADER_DIR}/internal/catch_totals.h
-        ${HEADER_DIR}/internal/catch_type_traits.hpp
         ${HEADER_DIR}/internal/catch_uncaught_exceptions.h
         ${HEADER_DIR}/internal/catch_user_interfaces.h
         ${HEADER_DIR}/internal/catch_version.h
@@ -171,7 +205,6 @@ 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
@@ -182,6 +215,7 @@ set(IMPL_SOURCES
         ${HEADER_DIR}/internal/catch_debugger.cpp
         ${HEADER_DIR}/internal/catch_decomposer.cpp
         ${HEADER_DIR}/internal/catch_enforce.cpp
+        ${HEADER_DIR}/internal/catch_enum_values_registry.cpp
         ${HEADER_DIR}/internal/catch_errno_guard.cpp
         ${HEADER_DIR}/internal/catch_exception_translator_registry.cpp
         ${HEADER_DIR}/internal/catch_fatal_condition.cpp
@@ -196,6 +230,7 @@ set(IMPL_SOURCES
         ${HEADER_DIR}/internal/catch_list.cpp
         ${HEADER_DIR}/internal/catch_leak_detector.cpp
         ${HEADER_DIR}/internal/catch_matchers.cpp
+        ${HEADER_DIR}/internal/catch_matchers_exception.cpp
         ${HEADER_DIR}/internal/catch_matchers_floating.cpp
         ${HEADER_DIR}/internal/catch_matchers_generic.cpp
         ${HEADER_DIR}/internal/catch_matchers_string.cpp
@@ -265,7 +300,9 @@ set(HEADERS
         ${EXTERNAL_HEADERS}
         ${INTERNAL_HEADERS}
         ${REPORTER_HEADERS}
-        )
+		${BENCHMARK_HEADERS}
+        ${BENCHMARK_SOURCES}
+)
 
 # Provide some groupings for IDEs
 SOURCE_GROUP("Tests" FILES ${TEST_SOURCES})
@@ -276,19 +313,31 @@ 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()
+# It took CMake until 3.8 to abandon the doomed approach of enumerating
+# required features so we just list C++11 features to support older ones.
+target_compile_features(SelfTest
+  PRIVATE
+    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
+)
 
-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)
@@ -302,7 +351,7 @@ endif()
 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)
+        target_compile_options( SelfTest PRIVATE -Werror )
     endif()
 endif()
 # Clang specific options go here
@@ -322,6 +371,9 @@ endif()
 
 # configure unit tests via CTest
 add_test(NAME RunTests COMMAND $<TARGET_FILE:SelfTest>)
+set_tests_properties(RunTests PROPERTIES
+    FAIL_REGULAR_EXPRESSION "Filters:"
+)
 
 add_test(NAME ListTests COMMAND $<TARGET_FILE:SelfTest> --list-tests --verbosity high)
 set_tests_properties(ListTests PROPERTIES 
@@ -345,8 +397,19 @@ set_tests_properties(ListTestNamesOnly PROPERTIES
 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")
+add_test(NAME NoTest COMMAND $<TARGET_FILE:SelfTest> Tracker, "___nonexistent_test___")
+set_tests_properties(NoTest PROPERTIES
+    PASS_REGULAR_EXPRESSION "No test cases matched '___nonexistent_test___'"
+    FAIL_REGULAR_EXPRESSION "No tests ran"
+)
+
+add_test(NAME WarnAboutNoTests COMMAND ${CMAKE_COMMAND} -P ${CATCH_DIR}/projects/SelfTest/WarnAboutNoTests.cmake $<TARGET_FILE:SelfTest>)
+
+add_test(NAME UnmatchedOutputFilter COMMAND $<TARGET_FILE:SelfTest> [this-tag-does-not-exist] -w NoTests)
+set_tests_properties(UnmatchedOutputFilter
+  PROPERTIES
+    PASS_REGULAR_EXPRESSION "No test cases matched '\\[this-tag-does-not-exist\\]'"
+)
 
 add_test(NAME FilteredSection-1 COMMAND $<TARGET_FILE:SelfTest> \#1394 -c RunSection)
 set_tests_properties(FilteredSection-1 PROPERTIES FAIL_REGULAR_EXPRESSION "No tests ran")
@@ -357,6 +420,36 @@ set_tests_properties(FilteredSection-2 PROPERTIES FAIL_REGULAR_EXPRESSION "No te
 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")
 
+add_test(NAME RegressionCheck-1670 COMMAND $<TARGET_FILE:SelfTest> "#1670 regression check" -c A -r compact)
+set_tests_properties(RegressionCheck-1670 PROPERTIES PASS_REGULAR_EXPRESSION "Passed 1 test case with 2 assertions.")
+
+add_test(NAME VersionCheck COMMAND $<TARGET_FILE:SelfTest> -h)
+set_tests_properties(VersionCheck PROPERTIES PASS_REGULAR_EXPRESSION "Catch v${PROJECT_VERSION}")
+
+add_test(NAME LibIdentityTest COMMAND $<TARGET_FILE:SelfTest> --libidentify)
+set_tests_properties(LibIdentityTest PROPERTIES PASS_REGULAR_EXPRESSION "description:    A Catch2 test executable")
+
+add_test(NAME FilenameAsTagsTest COMMAND $<TARGET_FILE:SelfTest> -\# --list-tags)
+set_tests_properties(FilenameAsTagsTest PROPERTIES PASS_REGULAR_EXPRESSION "\\[#Approx.tests\\]")
+
+add_test(NAME EscapeSpecialCharactersInTestNames COMMAND $<TARGET_FILE:SelfTest> "Test with special\\, characters \"in name")
+set_tests_properties(EscapeSpecialCharactersInTestNames PROPERTIES PASS_REGULAR_EXPRESSION "1 assertion in 1 test case")
+
+add_test(NAME TestsInFile::SimpleSpecs COMMAND $<TARGET_FILE:SelfTest> "-f ${CATCH_DIR}/projects/SelfTest/Misc/plain-old-tests.input")
+set_tests_properties(TestsInFile::SimpleSpecs PROPERTIES PASS_REGULAR_EXPRESSION "6 assertions in 2 test cases")
+
+add_test(NAME TestsInFile::EscapeSpecialCharacters COMMAND $<TARGET_FILE:SelfTest> "-f ${CATCH_DIR}/projects/SelfTest/Misc/special-characters-in-file.input")
+set_tests_properties(TestsInFile::EscapeSpecialCharacters PROPERTIES PASS_REGULAR_EXPRESSION "1 assertion in 1 test case")
+
+# CTest does not allow us to create an AND of required regular expressions,
+# so we have to split the test into 2 parts and look for parts of the expected
+# output separately.
+add_test(NAME TestsInFile::InvalidTestNames-1 COMMAND $<TARGET_FILE:SelfTest> "-f ${CATCH_DIR}/projects/SelfTest/Misc/invalid-test-names.input")
+set_tests_properties(TestsInFile::InvalidTestNames-1 PROPERTIES PASS_REGULAR_EXPRESSION "Invalid Filter: \"Test with special, characters in \\\\\" name\"")
+
+add_test(NAME TestsInFile::InvalidTestNames-2 COMMAND $<TARGET_FILE:SelfTest> "-f ${CATCH_DIR}/projects/SelfTest/Misc/invalid-test-names.input")
+set_tests_properties(TestsInFile::InvalidTestNames-2 PROPERTIES PASS_REGULAR_EXPRESSION "No tests ran")
+
 
 if (CATCH_USE_VALGRIND)
     add_test(NAME ValgrindRunTests COMMAND valgrind --leak-check=full --error-exitcode=1 $<TARGET_FILE:SelfTest>)
diff --git a/packages/Catch2/projects/ExtraTests/CMakeLists.txt b/packages/Catch2/projects/ExtraTests/CMakeLists.txt
index c0dd82d8f..13b02870d 100644
--- a/packages/Catch2/projects/ExtraTests/CMakeLists.txt
+++ b/packages/Catch2/projects/ExtraTests/CMakeLists.txt
@@ -116,6 +116,27 @@ set_tests_properties(
 )
 
 
+add_executable(BenchmarkingMacros ${TESTS_DIR}/X20-BenchmarkingMacros.cpp)
+target_compile_definitions( BenchmarkingMacros PRIVATE CATCH_CONFIG_ENABLE_BENCHMARKING )
+
+add_test(NAME BenchmarkingMacros COMMAND BenchmarkingMacros -r console -s)
+set_tests_properties(
+    BenchmarkingMacros
+  PROPERTIES
+    PASS_REGULAR_EXPRESSION "benchmark name                                  samples       iterations    estimated"
+)
+
+# This test touches windows.h, so it should only be compiled under msvc
+if (MSVC)
+    # This test fails if it does not compile and succeeds otherwise
+    add_executable(WindowsHeader ${TESTS_DIR}/X90-WindowsHeaderInclusion.cpp)
+    set_property( TARGET WindowsHeader PROPERTY CXX_STANDARD 11 )
+    set_property( TARGET WindowsHeader PROPERTY CXX_STANDARD_REQUIRED ON )
+    set_property( TARGET WindowsHeader PROPERTY CXX_EXTENSIONS OFF )
+    target_include_directories( WindowsHeader PRIVATE ${SINGLE_INCLUDE_PATH} )
+    add_test(NAME WindowsHeader COMMAND WindowsHeader -r compact)
+endif()
+
 set( EXTRA_TEST_BINARIES
     PrefixedMacros
     DisabledMacros
@@ -123,6 +144,7 @@ set( EXTRA_TEST_BINARIES
     DisabledExceptions-CustomHandler
     FallbackStringifier
     DisableStringification
+    BenchmarkingMacros
 )
 
 # Shared config
@@ -133,3 +155,4 @@ foreach( test ${EXTRA_TEST_BINARIES} )
     target_include_directories( ${test} PRIVATE ${SINGLE_INCLUDE_PATH} )
 endforeach()
 
+
diff --git a/packages/Catch2/projects/ExtraTests/X01-PrefixedMacros.cpp b/packages/Catch2/projects/ExtraTests/X01-PrefixedMacros.cpp
index 7671cbc4d..3d2ab9c16 100644
--- a/packages/Catch2/projects/ExtraTests/X01-PrefixedMacros.cpp
+++ b/packages/Catch2/projects/ExtraTests/X01-PrefixedMacros.cpp
@@ -48,6 +48,7 @@ CATCH_TEST_CASE("PrefixedMacros") {
     CATCH_CHECK_THAT("bdef", Equals("bdef"));
 
     CATCH_INFO( "some info" );
+    CATCH_UNSCOPED_INFO( "some info" );
     CATCH_WARN( "some warn" );
     CATCH_SECTION("some section") {
         int i = 1;
diff --git a/packages/Catch2/projects/ExtraTests/X20-BenchmarkingMacros.cpp b/packages/Catch2/projects/ExtraTests/X20-BenchmarkingMacros.cpp
new file mode 100644
index 000000000..e76af0c71
--- /dev/null
+++ b/packages/Catch2/projects/ExtraTests/X20-BenchmarkingMacros.cpp
@@ -0,0 +1,133 @@
+// X20-BenchmarkingMacros.cpp
+// Test that the benchmarking support macros compile properly with the single header
+
+#define CATCH_CONFIG_MAIN
+#include <catch2/catch.hpp>
+
+namespace {
+std::uint64_t factorial(std::uint64_t number) {
+    if (number < 2) {
+        return 1;
+    }
+    return number * factorial(number - 1);
+}
+}
+
+TEST_CASE("Benchmark factorial", "[benchmark]") {
+    CHECK(factorial(0) == 1);
+    // some more asserts..
+    CHECK(factorial(10) == 3628800);
+
+    BENCHMARK("factorial 10") {
+        return factorial(10);
+    };
+
+    CHECK(factorial(14) == 87178291200ull);
+    BENCHMARK("factorial 14") {
+        return factorial(14);
+    };
+//
+//    BENCHMARK("factorial 20") {
+//        return factorial(20);
+//    };
+//
+//    BENCHMARK("factorial 35") {
+//        return factorial(35);
+//    };
+}
+
+TEST_CASE("Benchmark containers", "[.][benchmark]") {
+    static const int size = 100;
+
+    std::vector<int> v;
+    std::map<int, int> m;
+
+    SECTION("without generator") {
+        BENCHMARK("Load up a vector") {
+            v = std::vector<int>();
+            for (int i = 0; i < size; ++i)
+                v.push_back(i);
+        };
+        REQUIRE(v.size() == size);
+
+        // test optimizer control
+        BENCHMARK("Add up a vector's content") {
+            uint64_t add = 0;
+            for (int i = 0; i < size; ++i)
+                add += v[i];
+            return add;
+        };
+
+        BENCHMARK("Load up a map") {
+            m = std::map<int, int>();
+            for (int i = 0; i < size; ++i)
+                m.insert({ i, i + 1 });
+        };
+        REQUIRE(m.size() == size);
+
+        BENCHMARK("Reserved vector") {
+            v = std::vector<int>();
+            v.reserve(size);
+            for (int i = 0; i < size; ++i)
+                v.push_back(i);
+        };
+        REQUIRE(v.size() == size);
+
+        BENCHMARK("Resized vector") {
+            v = std::vector<int>();
+            v.resize(size);
+            for (int i = 0; i < size; ++i)
+                v[i] = i;
+        };
+        REQUIRE(v.size() == size);
+
+        int array[size];
+        BENCHMARK("A fixed size array that should require no allocations") {
+            for (int i = 0; i < size; ++i)
+                array[i] = i;
+        };
+        int sum = 0;
+        for (int i = 0; i < size; ++i)
+            sum += array[i];
+        REQUIRE(sum > size);
+
+        SECTION("XYZ") {
+
+            BENCHMARK_ADVANCED("Load up vector with chronometer")(Catch::Benchmark::Chronometer meter) {
+                std::vector<int> k;
+                meter.measure([&](int idx) {
+                    k = std::vector<int>();
+                    for (int i = 0; i < size; ++i)
+                        k.push_back(idx);
+                });
+                REQUIRE(k.size() == size);
+            };
+
+            int runs = 0;
+            BENCHMARK("Fill vector indexed", benchmarkIndex) {
+                v = std::vector<int>();
+                v.resize(size);
+                for (int i = 0; i < size; ++i)
+                    v[i] = benchmarkIndex;
+                runs = benchmarkIndex;
+            };
+
+            for (size_t i = 0; i < v.size(); ++i) {
+                REQUIRE(v[i] == runs);
+            }
+        }
+    }
+
+    SECTION("with generator") {
+        auto generated = GENERATE(range(0, 10));
+        BENCHMARK("Fill vector generated") {
+            v = std::vector<int>();
+            v.resize(size);
+            for (int i = 0; i < size; ++i)
+                v[i] = generated;
+        };
+        for (size_t i = 0; i < v.size(); ++i) {
+            REQUIRE(v[i] == generated);
+        }
+    }
+}
diff --git a/packages/Catch2/projects/ExtraTests/X90-WindowsHeaderInclusion.cpp b/packages/Catch2/projects/ExtraTests/X90-WindowsHeaderInclusion.cpp
new file mode 100644
index 000000000..2b7a074ee
--- /dev/null
+++ b/packages/Catch2/projects/ExtraTests/X90-WindowsHeaderInclusion.cpp
@@ -0,0 +1,12 @@
+// X90-WindowsHeaderInclusion.cpp
+// Test that the Catch2 header compiles even after including windows.h
+// without defining NOMINMAX first. As an FYI, if you do that, you are
+// wrong.
+
+#include <windows.h>
+#define CATCH_CONFIG_MAIN
+#include <catch2/catch.hpp>
+
+TEST_CASE("Catch2 did survive compilation with windows.h", "[compile-test]") {
+    SUCCEED();
+}
diff --git a/packages/Catch2/projects/SelfTest/Baselines/compact.sw.approved.txt b/packages/Catch2/projects/SelfTest/Baselines/compact.sw.approved.txt
index 99eca94da..311183bc7 100644
--- a/packages/Catch2/projects/SelfTest/Baselines/compact.sw.approved.txt
+++ b/packages/Catch2/projects/SelfTest/Baselines/compact.sw.approved.txt
@@ -3,6 +3,8 @@ Decomposition.tests.cpp:<line number>: passed: fptr == 0 for: 0 == 0
 Decomposition.tests.cpp:<line number>: passed: fptr == 0l for: 0 == 0
 Compilation.tests.cpp:<line number>: passed: y.v == 0 for: 0 == 0
 Compilation.tests.cpp:<line number>: passed: 0 == y.v for: 0 == 0
+Compilation.tests.cpp:<line number>: passed: y.v == 0 for: 0 == 0
+Compilation.tests.cpp:<line number>: passed: 0 == y.v for: 0 == 0
 Compilation.tests.cpp:<line number>: passed: t1 == t2 for: {?} == {?}
 Compilation.tests.cpp:<line number>: passed: t1 != t2 for: {?} != {?}
 Compilation.tests.cpp:<line number>: passed: t1 < t2 for: {?} < {?}
@@ -155,18 +157,36 @@ Class.tests.cpp:<line number>: passed: Template_Fixture_2<TestType>::m_a.size()
 Class.tests.cpp:<line number>: passed: Template_Fixture_2<TestType>::m_a.size() == 0 for: 0 == 0
 Class.tests.cpp:<line number>: passed: Template_Fixture_2<TestType>::m_a.size() == 0 for: 0 == 0
 Class.tests.cpp:<line number>: passed: Template_Fixture_2<TestType>::m_a.size() == 0 for: 0 == 0
+Class.tests.cpp:<line number>: failed: Template_Fixture_2<TestType>{}.m_a.size() < 2 for: 6 < 2
+Class.tests.cpp:<line number>: failed: Template_Fixture_2<TestType>{}.m_a.size() < 2 for: 2 < 2
+Class.tests.cpp:<line number>: failed: Template_Fixture_2<TestType>{}.m_a.size() < 2 for: 6 < 2
+Class.tests.cpp:<line number>: failed: Template_Fixture_2<TestType>{}.m_a.size() < 2 for: 2 < 2
+Class.tests.cpp:<line number>: passed: Template_Fixture_2<TestType>{}.m_a.size() >= 2 for: 6 >= 2
+Class.tests.cpp:<line number>: passed: Template_Fixture_2<TestType>{}.m_a.size() >= 2 for: 2 >= 2
+Class.tests.cpp:<line number>: passed: Template_Fixture_2<TestType>{}.m_a.size() >= 2 for: 6 >= 2
+Class.tests.cpp:<line number>: passed: Template_Fixture_2<TestType>{}.m_a.size() >= 2 for: 2 >= 2
 Class.tests.cpp:<line number>: failed: Template_Fixture<TestType>::m_a == 2 for: 1.0 == 2
 Class.tests.cpp:<line number>: failed: Template_Fixture<TestType>::m_a == 2 for: 1.0f == 2
 Class.tests.cpp:<line number>: failed: Template_Fixture<TestType>::m_a == 2 for: 1 == 2
 Class.tests.cpp:<line number>: passed: Template_Fixture<TestType>::m_a == 1 for: 1.0 == 1
 Class.tests.cpp:<line number>: passed: Template_Fixture<TestType>::m_a == 1 for: 1.0f == 1
 Class.tests.cpp:<line number>: passed: Template_Fixture<TestType>::m_a == 1 for: 1 == 1
+Class.tests.cpp:<line number>: failed: Nttp_Fixture<V>::value == 0 for: 1 == 0
+Class.tests.cpp:<line number>: failed: Nttp_Fixture<V>::value == 0 for: 3 == 0
+Class.tests.cpp:<line number>: failed: Nttp_Fixture<V>::value == 0 for: 6 == 0
+Class.tests.cpp:<line number>: passed: Nttp_Fixture<V>::value > 0 for: 1 > 0
+Class.tests.cpp:<line number>: passed: Nttp_Fixture<V>::value > 0 for: 3 > 0
+Class.tests.cpp:<line number>: passed: Nttp_Fixture<V>::value > 0 for: 6 > 0
 Class.tests.cpp:<line number>: failed: m_a == 2 for: 1 == 2
 Class.tests.cpp:<line number>: passed: m_a == 1 for: 1 == 1
 Misc.tests.cpp:<line number>: passed: x.size() == 0 for: 0 == 0
 Misc.tests.cpp:<line number>: passed: x.size() == 0 for: 0 == 0
 Misc.tests.cpp:<line number>: passed: x.size() == 0 for: 0 == 0
 Misc.tests.cpp:<line number>: passed: x.size() == 0 for: 0 == 0
+Misc.tests.cpp:<line number>: passed: x.size() > 0 for: 42 > 0
+Misc.tests.cpp:<line number>: passed: x.size() > 0 for: 9 > 0
+Misc.tests.cpp:<line number>: passed: x.size() > 0 for: 42 > 0
+Misc.tests.cpp:<line number>: passed: x.size() > 0 for: 9 > 0
 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 )
@@ -223,13 +243,9 @@ Tricky.tests.cpp:<line number>: passed: true
 Tricky.tests.cpp:<line number>: passed: true
 Tricky.tests.cpp:<line number>: passed: true
 Tricky.tests.cpp:<line number>: passed: true
-Approx.tests.cpp:<line number>: passed: INFINITY == Approx(INFINITY) for: inff == Approx( inf )
-Approx.tests.cpp:<line number>: passed: NAN != Approx(NAN) for: nanf != Approx( nan )
-Approx.tests.cpp:<line number>: passed: !(NAN == Approx(NAN)) for: !(nanf == Approx( nan ))
-Tricky.tests.cpp:<line number>: passed: y.v == 0 for: 0 == 0
-Tricky.tests.cpp:<line number>: passed: 0 == y.v for: 0 == 0
 Message.tests.cpp:<line number>: passed: with 7 messages: 'a := 1' and 'b := 2' and 'c := 3' and 'a + b := 3' and 'a+b := 3' and 'c > b := true' and 'a == 1 := true'
 Message.tests.cpp:<line number>: passed: with 7 messages: 'std::vector<int>{1, 2, 3}[0, 1, 2] := 3' and 'std::vector<int>{1, 2, 3}[(0, 1)] := 2' and 'std::vector<int>{1, 2, 3}[0] := 1' and '(helper_1436<int, int>{12, -12}) := { 12, -12 }' and '(helper_1436<int, int>(-12, 12)) := { -12, 12 }' and '(1, 2) := 2' and '(2, 3) := 3'
+Message.tests.cpp:<line number>: passed: with 11 messages: '("comma, in string", "escaped, \", ") := "escaped, ", "' and '"single quote in string,'," := "single quote in string,',"' and '"some escapes, \\,\\\\" := "some escapes, \,\\"' and '"some, ), unmatched, } prenheses {[<" := "some, ), unmatched, } prenheses {[<"' and ''"' := '"'' and ''\'' := '''' and '',' := ','' and ''}' := '}'' and '')' := ')'' and ''(' := '('' and ''{' := '{''
 ToStringGeneral.tests.cpp:<line number>: passed: true with 1 message: 'i := 2'
 ToStringGeneral.tests.cpp:<line number>: passed: true with 1 message: '3'
 ToStringGeneral.tests.cpp:<line number>: passed: tab == '\t' for: '\t' == '\t'
@@ -260,6 +276,10 @@ Tricky.tests.cpp:<line number>: passed: true
 Tricky.tests.cpp:<line number>: passed: std::vector<int>{1, 2} == std::vector<int>{1, 2} for: { 1, 2 } == { 1, 2 }
 Tricky.tests.cpp:<line number>: passed: a for: 0x<hex digits>
 Tricky.tests.cpp:<line number>: passed: a == &foo for: 0x<hex digits> == 0x<hex digits>
+RandomNumberGeneration.tests.cpp:<line number>: passed: SimplePcg32{} == SimplePcg32{} for: {?} == {?}
+RandomNumberGeneration.tests.cpp:<line number>: passed: SimplePcg32{ 0 } != SimplePcg32{} for: {?} != {?}
+RandomNumberGeneration.tests.cpp:<line number>: passed: !(SimplePcg32{ 1 } == SimplePcg32{ 2 }) for: !({?} == {?})
+RandomNumberGeneration.tests.cpp:<line number>: passed: !(SimplePcg32{ 1 } != SimplePcg32{ 1 }) for: !({?} != {?})
 Approx.tests.cpp:<line number>: passed: td == Approx(10.0) for: StrongDoubleTypedef(10) == Approx( 10.0 )
 Approx.tests.cpp:<line number>: passed: Approx(10.0) == td for: Approx( 10.0 ) == StrongDoubleTypedef(10)
 Approx.tests.cpp:<line number>: passed: td != Approx(11.0) for: StrongDoubleTypedef(10) != Approx( 11.0 )
@@ -294,13 +314,41 @@ Condition.tests.cpp:<line number>: passed: 6 == uc for: 6 == 6
 Condition.tests.cpp:<line number>: passed: (std::numeric_limits<uint32_t>::max)() > ul for: 4294967295 (0x<hex digits>) > 4
 Matchers.tests.cpp:<line number>: failed: testStringForMatching(), Contains("not there", Catch::CaseSensitive::No) for: "this string contains 'abc' as a substring" contains: "not there" (case insensitive)
 Matchers.tests.cpp:<line number>: failed: testStringForMatching(), Contains("STRING") for: "this string contains 'abc' as a substring" contains: "STRING"
+Generators.tests.cpp:<line number>: passed: elem % 2 == 1 for: 1 == 1
+Generators.tests.cpp:<line number>: passed: elem % 2 == 1 for: 1 == 1
+Generators.tests.cpp:<line number>: passed: elem % 2 == 1 for: 1 == 1
+Generators.tests.cpp:<line number>: passed: elem % 2 == 1 for: 1 == 1
+Generators.tests.cpp:<line number>: passed: elem % 2 == 1 for: 1 == 1
+Generators.tests.cpp:<line number>: passed: elem % 2 == 1 for: 1 == 1
+Generators.tests.cpp:<line number>: passed: elem % 2 == 1 for: 1 == 1
+Generators.tests.cpp:<line number>: passed: elem % 2 == 1 for: 1 == 1
+Generators.tests.cpp:<line number>: passed: elem % 2 == 1 for: 1 == 1
+Generators.tests.cpp:<line number>: passed: elem % 2 == 1 for: 1 == 1
+Generators.tests.cpp:<line number>: passed: elem % 2 == 1 for: 1 == 1
+Generators.tests.cpp:<line number>: passed: elem % 2 == 1 for: 1 == 1
+Generators.tests.cpp:<line number>: passed: call_count == 1 for: 1 == 1
+Generators.tests.cpp:<line number>: passed: make_data().size() == test_count for: 6 == 6
 Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'custom exception - not std'; expression was: throwCustom()
 Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'custom exception - not std'; expression was: throwCustom(), std::exception
 Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'custom std exception'
 Approx.tests.cpp:<line number>: passed: 101.000001 != Approx(100).epsilon(0.01) for: 101.000001 != Approx( 100.0 )
 Approx.tests.cpp:<line number>: passed: std::pow(10, -5) != Approx(std::pow(10, -7)) for: 0.00001 != Approx( 0.0000001 )
+ToString.tests.cpp:<line number>: passed: enumInfo->lookup(0) == "Value1" for: Value1 == "Value1"
+ToString.tests.cpp:<line number>: passed: enumInfo->lookup(1) == "Value2" for: Value2 == "Value2"
+ToString.tests.cpp:<line number>: passed: enumInfo->lookup(3) == "{** unexpected enum value **}" for: {** unexpected enum value **}
+==
+"{** unexpected enum value **}"
 Matchers.tests.cpp:<line number>: failed: testStringForMatching(), EndsWith("Substring") for: "this string contains 'abc' as a substring" ends with: "Substring"
 Matchers.tests.cpp:<line number>: failed: testStringForMatching(), EndsWith("this", Catch::CaseSensitive::No) for: "this string contains 'abc' as a substring" ends with: "this" (case insensitive)
+EnumToString.tests.cpp:<line number>: passed: stringify( EnumClass3::Value1 ) == "Value1" for: "Value1" == "Value1"
+EnumToString.tests.cpp:<line number>: passed: stringify( EnumClass3::Value2 ) == "Value2" for: "Value2" == "Value2"
+EnumToString.tests.cpp:<line number>: passed: stringify( EnumClass3::Value3 ) == "Value3" for: "Value3" == "Value3"
+EnumToString.tests.cpp:<line number>: passed: stringify( EnumClass3::Value4 ) == "{** unexpected enum value **}" for: "{** unexpected enum value **}"
+==
+"{** unexpected enum value **}"
+EnumToString.tests.cpp:<line number>: passed: stringify( ec3 ) == "Value2" for: "Value2" == "Value2"
+EnumToString.tests.cpp:<line number>: passed: stringify( Bikeshed::Colours::Red ) == "Red" for: "Red" == "Red"
+EnumToString.tests.cpp:<line number>: passed: stringify( Bikeshed::Colours::Blue ) == "Blue" for: "Blue" == "Blue"
 Approx.tests.cpp:<line number>: passed: 101.01 != Approx(100).epsilon(0.01) for: 101.01 != Approx( 100.0 )
 Condition.tests.cpp:<line number>: failed: data.int_seven == 6 for: 7 == 6
 Condition.tests.cpp:<line number>: failed: data.int_seven == 8 for: 7 == 8
@@ -337,16 +385,20 @@ Matchers.tests.cpp:<line number>: failed: expected exception, got none; expressi
 Matchers.tests.cpp:<line number>: failed: expected exception, got none; expression was: doesNotThrow(), SpecialException, ExceptionMatcher{1}
 Matchers.tests.cpp:<line number>: failed: unexpected exception with message: 'Unknown exception'; expression was: throwsAsInt(1), SpecialException, ExceptionMatcher{1}
 Matchers.tests.cpp:<line number>: failed: unexpected exception with message: 'Unknown exception'; expression was: throwsAsInt(1), SpecialException, ExceptionMatcher{1}
-Matchers.tests.cpp:<line number>: failed: throws(3), SpecialException, ExceptionMatcher{1} for: SpecialException::what special exception has value of 1
-Matchers.tests.cpp:<line number>: failed: throws(4), SpecialException, ExceptionMatcher{1} for: SpecialException::what special exception has value of 1
-Matchers.tests.cpp:<line number>: passed: throws(1), SpecialException, ExceptionMatcher{1} for: SpecialException::what special exception has value of 1
-Matchers.tests.cpp:<line number>: passed: throws(2), SpecialException, ExceptionMatcher{2} for: SpecialException::what special exception has value of 2
+Matchers.tests.cpp:<line number>: failed: throwsSpecialException(3), SpecialException, ExceptionMatcher{1} for: SpecialException::what special exception has value of 1
+Matchers.tests.cpp:<line number>: failed: throwsSpecialException(4), SpecialException, ExceptionMatcher{1} for: SpecialException::what special exception has value of 1
+Matchers.tests.cpp:<line number>: passed: throwsSpecialException(1), SpecialException, ExceptionMatcher{1} for: SpecialException::what special exception has value of 1
+Matchers.tests.cpp:<line number>: passed: throwsSpecialException(2), SpecialException, ExceptionMatcher{2} for: SpecialException::what special exception has value of 2
 Exception.tests.cpp:<line number>: passed: thisThrows(), "expected exception" for: "expected exception" equals: "expected exception"
 Exception.tests.cpp:<line number>: passed: thisThrows(), Equals( "expecteD Exception", Catch::CaseSensitive::No ) for: "expected exception" equals: "expected exception" (case insensitive)
 Exception.tests.cpp:<line number>: passed: thisThrows(), StartsWith( "expected" ) for: "expected exception" starts with: "expected"
 Exception.tests.cpp:<line number>: passed: thisThrows(), EndsWith( "exception" ) for: "expected exception" ends with: "exception"
 Exception.tests.cpp:<line number>: passed: thisThrows(), Contains( "except" ) for: "expected exception" contains: "except"
 Exception.tests.cpp:<line number>: passed: thisThrows(), Contains( "exCept", Catch::CaseSensitive::No ) for: "expected exception" contains: "except" (case insensitive)
+Matchers.tests.cpp:<line number>: passed: throwsDerivedException(), DerivedException, Message("DerivedException::what") for: DerivedException::what exception message matches "DerivedException::what"
+Matchers.tests.cpp:<line number>: passed: throwsDerivedException(), DerivedException, !Message("derivedexception::what") for: DerivedException::what not exception message matches "derivedexception::what"
+Matchers.tests.cpp:<line number>: passed: throwsSpecialException(2), SpecialException, !Message("DerivedException::what") for: SpecialException::what not exception message matches "DerivedException::what"
+Matchers.tests.cpp:<line number>: passed: throwsSpecialException(2), SpecialException, Message("SpecialException::what") for: SpecialException::what exception message matches "SpecialException::what"
 Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'expected exception'; expression was: thisThrows(), std::string
 Exception.tests.cpp:<line number>: failed: expected exception, got none; expression was: thisDoesntThrow(), std::domain_error
 Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'expected exception'; expression was: thisThrows()
@@ -359,53 +411,66 @@ Misc.tests.cpp:<line number>: passed: Factorial(1) == 1 for: 1 == 1
 Misc.tests.cpp:<line number>: passed: Factorial(2) == 2 for: 2 == 2
 Misc.tests.cpp:<line number>: passed: Factorial(3) == 6 for: 6 == 6
 Misc.tests.cpp:<line number>: passed: Factorial(10) == 3628800 for: 3628800 (0x<hex digits>) == 3628800 (0x<hex digits>)
+Matchers.tests.cpp:<line number>: passed: 10., WithinRel(11.1, 0.1) for: 10.0 and 11.1 are within 10% of each other
+Matchers.tests.cpp:<line number>: passed: 10., !WithinRel(11.2, 0.1) for: 10.0 not and 11.2 are within 10% of each other
+Matchers.tests.cpp:<line number>: passed: 1., !WithinRel(0., 0.99) for: 1.0 not and 0 are within 99% of each other
+Matchers.tests.cpp:<line number>: passed: -0., WithinRel(0.) for: -0.0 and 0 are within 2.22045e-12% of each other
+Matchers.tests.cpp:<line number>: passed: v1, WithinRel(v2) for: 0.0 and 2.22507e-308 are within 2.22045e-12% of each other
 Matchers.tests.cpp:<line number>: passed: 1., WithinAbs(1., 0) for: 1.0 is within 0.0 of 1.0
 Matchers.tests.cpp:<line number>: passed: 0., WithinAbs(1., 1) for: 0.0 is within 1.0 of 1.0
 Matchers.tests.cpp:<line number>: passed: 0., !WithinAbs(1., 0.99) for: 0.0 not is within 0.99 of 1.0
 Matchers.tests.cpp:<line number>: passed: 0., !WithinAbs(1., 0.99) for: 0.0 not is within 0.99 of 1.0
-Matchers.tests.cpp:<line number>: passed: NAN, !WithinAbs(NAN, 0) for: nanf not is within 0.0 of nan
 Matchers.tests.cpp:<line number>: passed: 11., !WithinAbs(10., 0.5) for: 11.0 not is within 0.5 of 10.0
 Matchers.tests.cpp:<line number>: passed: 10., !WithinAbs(11., 0.5) for: 10.0 not is within 0.5 of 11.0
 Matchers.tests.cpp:<line number>: passed: -10., WithinAbs(-10., 0.5) for: -10.0 is within 0.5 of -10.0
 Matchers.tests.cpp:<line number>: passed: -10., WithinAbs(-9.6, 0.5) for: -10.0 is within 0.5 of -9.6
-Matchers.tests.cpp:<line number>: passed: 1., WithinULP(1., 0) for: 1.0 is within 0 ULPs of 1.0
-Matchers.tests.cpp:<line number>: passed: nextafter(1., 2.), WithinULP(1., 1) for: 1.0 is within 1 ULPs of 1.0
-Matchers.tests.cpp:<line number>: passed: nextafter(1., 0.), WithinULP(1., 1) for: 1.0 is within 1 ULPs of 1.0
-Matchers.tests.cpp:<line number>: passed: nextafter(1., 2.), !WithinULP(1., 0) for: 1.0 not is within 0 ULPs of 1.0
-Matchers.tests.cpp:<line number>: passed: 1., WithinULP(1., 0) for: 1.0 is within 0 ULPs of 1.0
-Matchers.tests.cpp:<line number>: passed: -0., WithinULP(0., 0) for: -0.0 is within 0 ULPs of 0.0
-Matchers.tests.cpp:<line number>: passed: NAN, !WithinULP(NAN, 123) for: nanf not is within 123 ULPs of nanf
-Matchers.tests.cpp:<line number>: passed: 1., WithinAbs(1., 0.5) || WithinULP(2., 1) for: 1.0 ( is within 0.5 of 1.0 or is within 1 ULPs of 2.0 )
-Matchers.tests.cpp:<line number>: passed: 1., WithinAbs(2., 0.5) || WithinULP(1., 0) for: 1.0 ( is within 0.5 of 2.0 or is within 0 ULPs of 1.0 )
-Matchers.tests.cpp:<line number>: passed: NAN, !(WithinAbs(NAN, 100) || WithinULP(NAN, 123)) for: nanf not ( is within 100.0 of nan or is within 123 ULPs of nanf )
+Matchers.tests.cpp:<line number>: passed: 1., WithinULP(1., 0) for: 1.0 is within 0 ULPs of 1.0000000000000000e+00 ([1.0000000000000000e+00, 1.0000000000000000e+00])
+Matchers.tests.cpp:<line number>: passed: nextafter(1., 2.), WithinULP(1., 1) for: 1.0 is within 1 ULPs of 1.0000000000000000e+00 ([9.9999999999999989e-01, 1.0000000000000002e+00])
+Matchers.tests.cpp:<line number>: passed: 0., WithinULP(nextafter(0., 1.), 1) for: 0.0 is within 1 ULPs of 4.9406564584124654e-324 ([0.0000000000000000e+00, 9.8813129168249309e-324])
+Matchers.tests.cpp:<line number>: passed: 1., WithinULP(nextafter(1., 0.), 1) for: 1.0 is within 1 ULPs of 9.9999999999999989e-01 ([9.9999999999999978e-01, 1.0000000000000000e+00])
+Matchers.tests.cpp:<line number>: passed: 1., !WithinULP(nextafter(1., 2.), 0) for: 1.0 not is within 0 ULPs of 1.0000000000000002e+00 ([1.0000000000000002e+00, 1.0000000000000002e+00])
+Matchers.tests.cpp:<line number>: passed: 1., WithinULP(1., 0) for: 1.0 is within 0 ULPs of 1.0000000000000000e+00 ([1.0000000000000000e+00, 1.0000000000000000e+00])
+Matchers.tests.cpp:<line number>: passed: -0., WithinULP(0., 0) for: -0.0 is within 0 ULPs of 0.0000000000000000e+00 ([0.0000000000000000e+00, 0.0000000000000000e+00])
+Matchers.tests.cpp:<line number>: passed: 1., WithinAbs(1., 0.5) || WithinULP(2., 1) for: 1.0 ( is within 0.5 of 1.0 or is within 1 ULPs of 2.0000000000000000e+00 ([1.9999999999999998e+00, 2.0000000000000004e+00]) )
+Matchers.tests.cpp:<line number>: passed: 1., WithinAbs(2., 0.5) || WithinULP(1., 0) for: 1.0 ( is within 0.5 of 2.0 or is within 0 ULPs of 1.0000000000000000e+00 ([1.0000000000000000e+00, 1.0000000000000000e+00]) )
+Matchers.tests.cpp:<line number>: passed: 0.0001, WithinAbs(0., 0.001) || WithinRel(0., 0.1) for: 0.0001 ( is within 0.001 of 0.0 or and 0 are within 10% of each other )
 Matchers.tests.cpp:<line number>: passed: WithinAbs(1., 0.)
 Matchers.tests.cpp:<line number>: passed: WithinAbs(1., -1.), std::domain_error
 Matchers.tests.cpp:<line number>: passed: WithinULP(1., 0)
-Matchers.tests.cpp:<line number>: passed: WithinULP(1., -1), std::domain_error
+Matchers.tests.cpp:<line number>: passed: WithinRel(1., 0.)
+Matchers.tests.cpp:<line number>: passed: WithinRel(1., -0.2), std::domain_error
+Matchers.tests.cpp:<line number>: passed: WithinRel(1., 1.), std::domain_error
+Matchers.tests.cpp:<line number>: passed: 10.f, WithinRel(11.1f, 0.1f) for: 10.0f and 11.1 are within 10% of each other
+Matchers.tests.cpp:<line number>: passed: 10.f, !WithinRel(11.2f, 0.1f) for: 10.0f not and 11.2 are within 10% of each other
+Matchers.tests.cpp:<line number>: passed: 1.f, !WithinRel(0.f, 0.99f) for: 1.0f not and 0 are within 99% of each other
+Matchers.tests.cpp:<line number>: passed: -0.f, WithinRel(0.f) for: -0.0f and 0 are within 0.00119209% of each other
+Matchers.tests.cpp:<line number>: passed: v1, WithinRel(v2) for: 0.0f and 1.17549e-38 are within 0.00119209% of each other
 Matchers.tests.cpp:<line number>: passed: 1.f, WithinAbs(1.f, 0) for: 1.0f is within 0.0 of 1.0
 Matchers.tests.cpp:<line number>: passed: 0.f, WithinAbs(1.f, 1) for: 0.0f is within 1.0 of 1.0
 Matchers.tests.cpp:<line number>: passed: 0.f, !WithinAbs(1.f, 0.99f) for: 0.0f not is within 0.9900000095 of 1.0
 Matchers.tests.cpp:<line number>: passed: 0.f, !WithinAbs(1.f, 0.99f) for: 0.0f not is within 0.9900000095 of 1.0
 Matchers.tests.cpp:<line number>: passed: 0.f, WithinAbs(-0.f, 0) for: 0.0f is within 0.0 of -0.0
-Matchers.tests.cpp:<line number>: passed: NAN, !WithinAbs(NAN, 0) for: nanf not is within 0.0 of nan
 Matchers.tests.cpp:<line number>: passed: 11.f, !WithinAbs(10.f, 0.5f) for: 11.0f not is within 0.5 of 10.0
 Matchers.tests.cpp:<line number>: passed: 10.f, !WithinAbs(11.f, 0.5f) for: 10.0f not is within 0.5 of 11.0
 Matchers.tests.cpp:<line number>: passed: -10.f, WithinAbs(-10.f, 0.5f) for: -10.0f is within 0.5 of -10.0
 Matchers.tests.cpp:<line number>: passed: -10.f, WithinAbs(-9.6f, 0.5f) for: -10.0f is within 0.5 of -9.6000003815
-Matchers.tests.cpp:<line number>: passed: 1.f, WithinULP(1.f, 0) for: 1.0f is within 0 ULPs of 1.0f
-Matchers.tests.cpp:<line number>: passed: nextafter(1.f, 2.f), WithinULP(1.f, 1) for: 1.0f is within 1 ULPs of 1.0f
-Matchers.tests.cpp:<line number>: passed: nextafter(1.f, 0.f), WithinULP(1.f, 1) for: 1.0f is within 1 ULPs of 1.0f
-Matchers.tests.cpp:<line number>: passed: nextafter(1.f, 2.f), !WithinULP(1.f, 0) for: 1.0f not is within 0 ULPs of 1.0f
-Matchers.tests.cpp:<line number>: passed: 1.f, WithinULP(1.f, 0) for: 1.0f is within 0 ULPs of 1.0f
-Matchers.tests.cpp:<line number>: passed: -0.f, WithinULP(0.f, 0) for: -0.0f is within 0 ULPs of 0.0f
-Matchers.tests.cpp:<line number>: passed: NAN, !WithinULP(NAN, 123) for: nanf not is within 123 ULPs of nanf
-Matchers.tests.cpp:<line number>: passed: 1.f, WithinAbs(1.f, 0.5) || WithinULP(1.f, 1) for: 1.0f ( is within 0.5 of 1.0 or is within 1 ULPs of 1.0f )
-Matchers.tests.cpp:<line number>: passed: 1.f, WithinAbs(2.f, 0.5) || WithinULP(1.f, 0) for: 1.0f ( is within 0.5 of 2.0 or is within 0 ULPs of 1.0f )
-Matchers.tests.cpp:<line number>: passed: NAN, !(WithinAbs(NAN, 100) || WithinULP(NAN, 123)) for: nanf not ( is within 100.0 of nan or is within 123 ULPs of nanf )
+Matchers.tests.cpp:<line number>: passed: 1.f, WithinULP(1.f, 0) for: 1.0f is within 0 ULPs of 1.00000000e+00f ([1.00000000e+00, 1.00000000e+00])
+Matchers.tests.cpp:<line number>: passed: nextafter(1.f, 2.f), WithinULP(1.f, 1) for: 1.0f is within 1 ULPs of 1.00000000e+00f ([9.99999940e-01, 1.00000012e+00])
+Matchers.tests.cpp:<line number>: passed: 0.f, WithinULP(nextafter(0.f, 1.f), 1) for: 0.0f is within 1 ULPs of 1.40129846e-45f ([0.00000000e+00, 2.80259693e-45])
+Matchers.tests.cpp:<line number>: passed: 1.f, WithinULP(nextafter(1.f, 0.f), 1) for: 1.0f is within 1 ULPs of 9.99999940e-01f ([9.99999881e-01, 1.00000000e+00])
+Matchers.tests.cpp:<line number>: passed: 1.f, !WithinULP(nextafter(1.f, 2.f), 0) for: 1.0f not is within 0 ULPs of 1.00000012e+00f ([1.00000012e+00, 1.00000012e+00])
+Matchers.tests.cpp:<line number>: passed: 1.f, WithinULP(1.f, 0) for: 1.0f is within 0 ULPs of 1.00000000e+00f ([1.00000000e+00, 1.00000000e+00])
+Matchers.tests.cpp:<line number>: passed: -0.f, WithinULP(0.f, 0) for: -0.0f is within 0 ULPs of 0.00000000e+00f ([0.00000000e+00, 0.00000000e+00])
+Matchers.tests.cpp:<line number>: passed: 1.f, WithinAbs(1.f, 0.5) || WithinULP(1.f, 1) for: 1.0f ( is within 0.5 of 1.0 or is within 1 ULPs of 1.00000000e+00f ([9.99999940e-01, 1.00000012e+00]) )
+Matchers.tests.cpp:<line number>: passed: 1.f, WithinAbs(2.f, 0.5) || WithinULP(1.f, 0) for: 1.0f ( is within 0.5 of 2.0 or is within 0 ULPs of 1.00000000e+00f ([1.00000000e+00, 1.00000000e+00]) )
+Matchers.tests.cpp:<line number>: passed: 0.0001f, WithinAbs(0.f, 0.001f) || WithinRel(0.f, 0.1f) for: 0.0001f ( is within 0.001 of 0.0 or and 0 are within 10% of each other )
 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
+Matchers.tests.cpp:<line number>: passed: WithinULP(1.f, static_cast<uint64_t>(-1)), std::domain_error
+Matchers.tests.cpp:<line number>: passed: WithinRel(1.f, 0.f)
+Matchers.tests.cpp:<line number>: passed: WithinRel(1.f, -0.2f), std::domain_error
+Matchers.tests.cpp:<line number>: passed: WithinRel(1.f, 1.f), std::domain_error
 Generators.tests.cpp:<line number>: passed: i % 2 == 0 for: 0 == 0
 Generators.tests.cpp:<line number>: passed: i % 2 == 0 for: 0 == 0
 Generators.tests.cpp:<line number>: passed: i % 2 == 0 for: 0 == 0
@@ -440,6 +505,9 @@ Generators.tests.cpp:<line number>: passed: chunk2.front() < 3 for: 1 < 3
 Generators.tests.cpp:<line number>: passed: chunk2.size() == 2 for: 2 == 2
 Generators.tests.cpp:<line number>: passed: chunk2.front() == chunk2.back() for: 2 == 2
 Generators.tests.cpp:<line number>: passed: chunk2.front() < 3 for: 2 < 3
+Generators.tests.cpp:<line number>: passed: chunk2.size() == 0 for: 0 == 0
+Generators.tests.cpp:<line number>: passed: chunk2.size() == 0 for: 0 == 0
+Generators.tests.cpp:<line number>: passed: chunk2.size() == 0 for: 0 == 0
 Generators.tests.cpp:<line number>: passed: chunk(2, value(1)), Catch::GeneratorException
 Generators.tests.cpp:<line number>: passed: j < i for: -3 < 1
 Generators.tests.cpp:<line number>: passed: j < i for: -2 < 1
@@ -699,6 +767,51 @@ Condition.tests.cpp:<line number>: passed: data.str_hello < "hellp" for: "hello"
 Condition.tests.cpp:<line number>: passed: data.str_hello < "zebra" for: "hello" < "zebra"
 Condition.tests.cpp:<line number>: passed: data.str_hello > "hellm" for: "hello" > "hellm"
 Condition.tests.cpp:<line number>: passed: data.str_hello > "a" for: "hello" > "a"
+RandomNumberGeneration.tests.cpp:<line number>: passed: rng() == 0x<hex digits> for: 4242248763 (0x<hex digits>)
+==
+4242248763 (0x<hex digits>)
+RandomNumberGeneration.tests.cpp:<line number>: passed: rng() == 0x<hex digits> for: 1867888929 (0x<hex digits>)
+==
+1867888929 (0x<hex digits>)
+RandomNumberGeneration.tests.cpp:<line number>: passed: rng() == 0x<hex digits> for: 1276619030 (0x<hex digits>)
+==
+1276619030 (0x<hex digits>)
+RandomNumberGeneration.tests.cpp:<line number>: passed: rng() == 0x<hex digits> for: 1911218783 (0x<hex digits>)
+==
+1911218783 (0x<hex digits>)
+RandomNumberGeneration.tests.cpp:<line number>: passed: rng() == 0x<hex digits> for: 1827115164 (0x<hex digits>)
+==
+1827115164 (0x<hex digits>)
+RandomNumberGeneration.tests.cpp:<line number>: passed: rng() == 0x<hex digits> for: 1472234645 (0x<hex digits>)
+==
+1472234645 (0x<hex digits>)
+RandomNumberGeneration.tests.cpp:<line number>: passed: rng() == 0x<hex digits> for: 868832940 (0x<hex digits>)
+==
+868832940 (0x<hex digits>)
+RandomNumberGeneration.tests.cpp:<line number>: passed: rng() == 0x<hex digits> for: 570883446 (0x<hex digits>)
+==
+570883446 (0x<hex digits>)
+RandomNumberGeneration.tests.cpp:<line number>: passed: rng() == 0x<hex digits> for: 889299803 (0x<hex digits>)
+==
+889299803 (0x<hex digits>)
+RandomNumberGeneration.tests.cpp:<line number>: passed: rng() == 0x<hex digits> for: 4261393167 (0x<hex digits>)
+==
+4261393167 (0x<hex digits>)
+RandomNumberGeneration.tests.cpp:<line number>: passed: rng() == 0x<hex digits> for: 1472234645 (0x<hex digits>)
+==
+1472234645 (0x<hex digits>)
+RandomNumberGeneration.tests.cpp:<line number>: passed: rng() == 0x<hex digits> for: 868832940 (0x<hex digits>)
+==
+868832940 (0x<hex digits>)
+RandomNumberGeneration.tests.cpp:<line number>: passed: rng() == 0x<hex digits> for: 570883446 (0x<hex digits>)
+==
+570883446 (0x<hex digits>)
+RandomNumberGeneration.tests.cpp:<line number>: passed: rng() == 0x<hex digits> for: 889299803 (0x<hex digits>)
+==
+889299803 (0x<hex digits>)
+RandomNumberGeneration.tests.cpp:<line number>: passed: rng() == 0x<hex digits> for: 4261393167 (0x<hex digits>)
+==
+4261393167 (0x<hex digits>)
 Message.tests.cpp:<line number>: failed: explicitly with 1 message: 'Message from section one'
 Message.tests.cpp:<line number>: failed: explicitly with 1 message: 'Message from section two'
 CmdLine.tests.cpp:<line number>: passed: spec.hasFilters() == false for: false == false
@@ -836,6 +949,16 @@ 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
+CmdLine.tests.cpp:<line number>: passed: spec.matches( fakeTestCase( "  aardvark " ) ) for: true
+CmdLine.tests.cpp:<line number>: passed: spec.matches( fakeTestCase( "  aardvark" ) ) for: true
+CmdLine.tests.cpp:<line number>: passed: spec.matches( fakeTestCase( " aardvark " ) ) for: true
+CmdLine.tests.cpp:<line number>: passed: spec.matches( fakeTestCase( "aardvark " ) ) for: true
+CmdLine.tests.cpp:<line number>: passed: spec.matches( fakeTestCase( "aardvark" ) ) for: true
+CmdLine.tests.cpp:<line number>: passed: spec.matches( fakeTestCase( "  aardvark " ) ) for: true
+CmdLine.tests.cpp:<line number>: passed: spec.matches( fakeTestCase( "  aardvark" ) ) for: true
+CmdLine.tests.cpp:<line number>: passed: spec.matches( fakeTestCase( " aardvark " ) ) for: true
+CmdLine.tests.cpp:<line number>: passed: spec.matches( fakeTestCase( "aardvark " ) ) for: true
+CmdLine.tests.cpp:<line number>: passed: spec.matches( fakeTestCase( "aardvark" ) ) for: true
 Condition.tests.cpp:<line number>: passed: p == 0 for: 0 == 0
 Condition.tests.cpp:<line number>: passed: p == pNULL for: 0 == 0
 Condition.tests.cpp:<line number>: passed: p != 0 for: 0x<hex digits> != 0
@@ -844,6 +967,10 @@ Condition.tests.cpp:<line number>: passed: cpc != 0 for: 0x<hex digits> != 0
 Condition.tests.cpp:<line number>: passed: returnsNull() == 0 for: {null string} == 0
 Condition.tests.cpp:<line number>: passed: returnsConstNull() == 0 for: {null string} == 0
 Condition.tests.cpp:<line number>: passed: 0 != p for: 0 != 0x<hex digits>
+ToStringGeneral.tests.cpp:<line number>: passed: str1.size() == 3 + 5 for: 8 == 8
+ToStringGeneral.tests.cpp:<line number>: passed: str2.size() == 3 + 10 for: 13 == 13
+ToStringGeneral.tests.cpp:<line number>: passed: str1.size() == 2 + 5 for: 7 == 7
+ToStringGeneral.tests.cpp:<line number>: passed: str2.size() == 2 + 15 for: 17 == 17
 Matchers.tests.cpp:<line number>: passed: "foo", Predicate<const char*>([] (const char* const&) { return true; }) for: "foo" matches undescribed predicate
 CmdLine.tests.cpp:<line number>: passed: result for: {?}
 CmdLine.tests.cpp:<line number>: passed: config.processName == "" for: "" == ""
@@ -907,6 +1034,14 @@ CmdLine.tests.cpp:<line number>: passed: cli.parse({"test", "--use-colour", "no"
 CmdLine.tests.cpp:<line number>: passed: config.useColour == UseColour::No for: 2 == 2
 CmdLine.tests.cpp:<line number>: passed: !result for: true
 CmdLine.tests.cpp:<line number>: passed: result.errorMessage(), Contains( "colour mode must be one of" ) for: "colour mode must be one of: auto, yes or no. 'wrong' not recognised" contains: "colour mode must be one of"
+CmdLine.tests.cpp:<line number>: passed: cli.parse({ "test", "--benchmark-samples=200" }) for: {?}
+CmdLine.tests.cpp:<line number>: passed: config.benchmarkSamples == 200 for: 200 == 200
+CmdLine.tests.cpp:<line number>: passed: cli.parse({ "test", "--benchmark-resamples=20000" }) for: {?}
+CmdLine.tests.cpp:<line number>: passed: config.benchmarkResamples == 20000 for: 20000 (0x<hex digits>) == 20000 (0x<hex digits>)
+CmdLine.tests.cpp:<line number>: passed: cli.parse({ "test", "--benchmark-confidence-interval=0.99" }) for: {?}
+CmdLine.tests.cpp:<line number>: passed: config.benchmarkConfidenceInterval == Catch::Detail::Approx(0.99) for: 0.99 == Approx( 0.99 )
+CmdLine.tests.cpp:<line number>: passed: cli.parse({ "test", "--benchmark-no-analysis" }) for: {?}
+CmdLine.tests.cpp:<line number>: passed: config.benchmarkNoAnalysis for: true
 Misc.tests.cpp:<line number>: passed: std::tuple_size<TestType>::value >= 1 for: 3 >= 1
 Misc.tests.cpp:<line number>: passed: std::tuple_size<TestType>::value >= 1 for: 2 >= 1
 Misc.tests.cpp:<line number>: passed: std::tuple_size<TestType>::value >= 1 for: 1 >= 1
@@ -941,7 +1076,6 @@ 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
-Approx.tests.cpp:<line number>: passed: INFINITY == Approx(INFINITY) for: inff == Approx( inf )
 Message from section one
 Message from section two
 Matchers.tests.cpp:<line number>: failed: testStringForMatching(), StartsWith("This String") for: "this string contains 'abc' as a substring" starts with: "This String"
@@ -972,7 +1106,6 @@ String.tests.cpp:<line number>: passed: isOwned( s ) == false for: false == fals
 String.tests.cpp:<line number>: passed: original == "original"
 String.tests.cpp:<line number>: passed: isSubstring( original ) for: true
 String.tests.cpp:<line number>: passed: isOwned( original ) == false for: false == false
-String.tests.cpp:<line number>: passed: isSubstring( original ) == false for: false == false
 String.tests.cpp:<line number>: passed: isOwned( original ) for: true
 String.tests.cpp:<line number>: passed: ss.empty() == false for: false == false
 String.tests.cpp:<line number>: passed: ss.size() == 5 for: 5 == 5
@@ -982,13 +1115,15 @@ String.tests.cpp:<line number>: passed: isSubstring( ss ) for: true
 String.tests.cpp:<line number>: passed: isOwned( ss ) == false for: false == false
 String.tests.cpp:<line number>: passed: rawChars == s.currentData() for: "hello world!" == "hello world!"
 String.tests.cpp:<line number>: passed: ss.c_str() != rawChars for: "hello" != "hello world!"
-String.tests.cpp:<line number>: passed: isSubstring( ss ) == false for: false == false
 String.tests.cpp:<line number>: passed: isOwned( ss ) for: true
-String.tests.cpp:<line number>: passed: ss.currentData() != s.currentData() for: "hello" != "hello world!"
+String.tests.cpp:<line number>: passed: isOwned(ss) == false for: false == false
+String.tests.cpp:<line number>: passed: ss == "hello" for: hello == "hello"
+String.tests.cpp:<line number>: passed: rawChars == ss.currentData() for: "hello world!" == "hello world!"
 String.tests.cpp:<line number>: passed: ss.size() == 6 for: 6 == 6
 String.tests.cpp:<line number>: passed: std::strcmp( ss.c_str(), "world!" ) == 0 for: 0 == 0
 String.tests.cpp:<line number>: passed: s.c_str() == s2.c_str() for: "hello world!" == "hello world!"
 String.tests.cpp:<line number>: passed: s.c_str() != ss.c_str() for: "hello world!" != "hello"
+String.tests.cpp:<line number>: passed: s.substr(s.size() + 1, 123).empty() for: true
 String.tests.cpp:<line number>: passed: StringRef("hello") == StringRef("hello") for: hello == hello
 String.tests.cpp:<line number>: passed: StringRef("hello") != StringRef("cello") for: hello != cello
 String.tests.cpp:<line number>: passed: sr == "a standard string" for: a standard string == "a standard string"
@@ -1001,11 +1136,6 @@ String.tests.cpp:<line number>: passed: stdStr == "a stringref" for: "a stringre
 String.tests.cpp:<line number>: passed: stdStr.size() == sr.size() for: 11 == 11
 String.tests.cpp:<line number>: passed: stdStr == "a stringref" for: "a stringref" == "a stringref"
 String.tests.cpp:<line number>: passed: stdStr.size() == sr.size() for: 11 == 11
-String.tests.cpp:<line number>: passed: stdStr == "a stringref" for: "a stringref" == "a stringref"
-String.tests.cpp:<line number>: passed: stdStr.size() == sr.size() for: 11 == 11
-String.tests.cpp:<line number>: passed: ascii.numberOfCharacters() == ascii.size() for: 39 == 39
-String.tests.cpp:<line number>: passed: simpleu8.numberOfCharacters() == 30 for: 30 == 30
-String.tests.cpp:<line number>: passed: emojis.numberOfCharacters() == 9 for: 9 == 9
 ToStringChrono.tests.cpp:<line number>: passed: minute == seconds for: 1 m == 60 s
 ToStringChrono.tests.cpp:<line number>: passed: hour != seconds for: 1 h != 60 s
 ToStringChrono.tests.cpp:<line number>: passed: micro != milli for: 1 us != 1 ms
@@ -1039,6 +1169,16 @@ Tag.tests.cpp:<line number>: passed: registry.add( "[no ampersat]", "", Catch::S
 Tag.tests.cpp:<line number>: passed: registry.add( "[the @ is not at the start]", "", Catch::SourceLineInfo( "file", 3 ) )
 Tag.tests.cpp:<line number>: passed: registry.add( "@no square bracket at start]", "", Catch::SourceLineInfo( "file", 3 ) )
 Tag.tests.cpp:<line number>: passed: registry.add( "[@no square bracket at end", "", Catch::SourceLineInfo( "file", 3 ) )
+Class.tests.cpp:<line number>: passed: Template_Fixture<TestType>::m_a == 1 for: 1 == 1
+Class.tests.cpp:<line number>: passed: Template_Fixture<TestType>::m_a == 1 for: 1 == 1
+Class.tests.cpp:<line number>: passed: Template_Fixture<TestType>::m_a == 1 for: 1.0 == 1
+Misc.tests.cpp:<line number>: passed: sizeof(TestType) > 0 for: 1 > 0
+Misc.tests.cpp:<line number>: passed: sizeof(TestType) > 0 for: 4 > 0
+Misc.tests.cpp:<line number>: passed: sizeof(TestType) > 0 for: 1 > 0
+Misc.tests.cpp:<line number>: passed: sizeof(TestType) > 0 for: 4 > 0
+Misc.tests.cpp:<line number>: passed: sizeof(TestType) > 0 for: 4 > 0
+Misc.tests.cpp:<line number>: passed: sizeof(TestType) > 0 for: 1 > 0
+Misc.tests.cpp:<line number>: passed: sizeof(TestType) > 0 for: 4 > 0
 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: v.size() == 10 for: 10 == 10
@@ -1107,8 +1247,77 @@ 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: v.size() == 5 for: 5 == 5
 Misc.tests.cpp:<line number>: passed: v.capacity() >= 5 for: 5 >= 5
+Misc.tests.cpp:<line number>: passed: v.size() == V for: 6 == 6
+Misc.tests.cpp:<line number>: passed: v.capacity() >= V for: 6 >= 6
+Misc.tests.cpp:<line number>: passed: v.size() == 2 * V for: 12 == 12
+Misc.tests.cpp:<line number>: passed: v.capacity() >= 2 * V for: 12 >= 12
+Misc.tests.cpp:<line number>: passed: v.size() == V for: 6 == 6
+Misc.tests.cpp:<line number>: passed: v.capacity() >= V for: 6 >= 6
+Misc.tests.cpp:<line number>: passed: v.size() == 0 for: 0 == 0
+Misc.tests.cpp:<line number>: passed: v.capacity() >= V for: 6 >= 6
+Misc.tests.cpp:<line number>: passed: v.capacity() == 0 for: 0 == 0
+Misc.tests.cpp:<line number>: passed: v.size() == V for: 6 == 6
+Misc.tests.cpp:<line number>: passed: v.capacity() >= V for: 6 >= 6
+Misc.tests.cpp:<line number>: passed: v.size() == V for: 6 == 6
+Misc.tests.cpp:<line number>: passed: v.capacity() >= 2 * V for: 12 >= 12
+Misc.tests.cpp:<line number>: passed: v.size() == V for: 6 == 6
+Misc.tests.cpp:<line number>: passed: v.capacity() >= V for: 6 >= 6
+Misc.tests.cpp:<line number>: passed: v.size() == V for: 6 == 6
+Misc.tests.cpp:<line number>: passed: v.capacity() >= V for: 6 >= 6
+Misc.tests.cpp:<line number>: passed: v.size() == V for: 4 == 4
+Misc.tests.cpp:<line number>: passed: v.capacity() >= V for: 4 >= 4
+Misc.tests.cpp:<line number>: passed: v.size() == 2 * V for: 8 == 8
+Misc.tests.cpp:<line number>: passed: v.capacity() >= 2 * V for: 8 >= 8
+Misc.tests.cpp:<line number>: passed: v.size() == V for: 4 == 4
+Misc.tests.cpp:<line number>: passed: v.capacity() >= V for: 4 >= 4
+Misc.tests.cpp:<line number>: passed: v.size() == 0 for: 0 == 0
+Misc.tests.cpp:<line number>: passed: v.capacity() >= V for: 4 >= 4
+Misc.tests.cpp:<line number>: passed: v.capacity() == 0 for: 0 == 0
+Misc.tests.cpp:<line number>: passed: v.size() == V for: 4 == 4
+Misc.tests.cpp:<line number>: passed: v.capacity() >= V for: 4 >= 4
+Misc.tests.cpp:<line number>: passed: v.size() == V for: 4 == 4
+Misc.tests.cpp:<line number>: passed: v.capacity() >= 2 * V for: 8 >= 8
+Misc.tests.cpp:<line number>: passed: v.size() == V for: 4 == 4
+Misc.tests.cpp:<line number>: passed: v.capacity() >= V for: 4 >= 4
+Misc.tests.cpp:<line number>: passed: v.size() == V for: 4 == 4
+Misc.tests.cpp:<line number>: passed: v.capacity() >= V for: 4 >= 4
+Misc.tests.cpp:<line number>: passed: v.size() == V for: 5 == 5
+Misc.tests.cpp:<line number>: passed: v.capacity() >= V for: 5 >= 5
+Misc.tests.cpp:<line number>: passed: v.size() == 2 * V for: 10 == 10
+Misc.tests.cpp:<line number>: passed: v.capacity() >= 2 * V for: 10 >= 10
+Misc.tests.cpp:<line number>: passed: v.size() == V for: 5 == 5
+Misc.tests.cpp:<line number>: passed: v.capacity() >= V for: 5 >= 5
+Misc.tests.cpp:<line number>: passed: v.size() == 0 for: 0 == 0
+Misc.tests.cpp:<line number>: passed: v.capacity() >= V for: 5 >= 5
+Misc.tests.cpp:<line number>: passed: v.capacity() == 0 for: 0 == 0
+Misc.tests.cpp:<line number>: passed: v.size() == V for: 5 == 5
+Misc.tests.cpp:<line number>: passed: v.capacity() >= V for: 5 >= 5
+Misc.tests.cpp:<line number>: passed: v.size() == V for: 5 == 5
+Misc.tests.cpp:<line number>: passed: v.capacity() >= 2 * V for: 10 >= 10
+Misc.tests.cpp:<line number>: passed: v.size() == V for: 5 == 5
+Misc.tests.cpp:<line number>: passed: v.capacity() >= V for: 5 >= 5
+Misc.tests.cpp:<line number>: passed: v.size() == V for: 5 == 5
+Misc.tests.cpp:<line number>: passed: v.capacity() >= V for: 5 >= 5
+Misc.tests.cpp:<line number>: passed: v.size() == V for: 15 == 15
+Misc.tests.cpp:<line number>: passed: v.capacity() >= V for: 15 >= 15
+Misc.tests.cpp:<line number>: passed: v.size() == 2 * V for: 30 == 30
+Misc.tests.cpp:<line number>: passed: v.capacity() >= 2 * V for: 30 >= 30
+Misc.tests.cpp:<line number>: passed: v.size() == V for: 15 == 15
+Misc.tests.cpp:<line number>: passed: v.capacity() >= V for: 15 >= 15
+Misc.tests.cpp:<line number>: passed: v.size() == 0 for: 0 == 0
+Misc.tests.cpp:<line number>: passed: v.capacity() >= V for: 15 >= 15
+Misc.tests.cpp:<line number>: passed: v.capacity() == 0 for: 0 == 0
+Misc.tests.cpp:<line number>: passed: v.size() == V for: 15 == 15
+Misc.tests.cpp:<line number>: passed: v.capacity() >= V for: 15 >= 15
+Misc.tests.cpp:<line number>: passed: v.size() == V for: 15 == 15
+Misc.tests.cpp:<line number>: passed: v.capacity() >= 2 * V for: 30 >= 30
+Misc.tests.cpp:<line number>: passed: v.size() == V for: 15 == 15
+Misc.tests.cpp:<line number>: passed: v.capacity() >= V for: 15 >= 15
+Misc.tests.cpp:<line number>: passed: v.size() == V for: 15 == 15
+Misc.tests.cpp:<line number>: passed: v.capacity() >= V for: 15 >= 15
 VariadicMacros.tests.cpp:<line number>: passed: with 1 message: 'no assertions'
 Tricky.tests.cpp:<line number>: passed: 0x<hex digits> == bit30and31 for: 3221225472 (0x<hex digits>) == 3221225472
+CmdLine.tests.cpp:<line number>: passed:
 Message.tests.cpp:<line number>: failed - but was ok: 1 == 2
 Misc.tests.cpp:<line number>: passed: with 1 message: 'oops!'
 Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'For some reason someone is throwing a string literal!'
@@ -1179,6 +1388,30 @@ PartTracker.tests.cpp:<line number>: passed: s1.isComplete() == false for: false
 PartTracker.tests.cpp:<line number>: passed: s1.isComplete() for: true
 PartTracker.tests.cpp:<line number>: passed: testCase.isComplete() == false for: false == false
 PartTracker.tests.cpp:<line number>: passed: testCase.isComplete() for: true
+StringManip.tests.cpp:<line number>: passed: trim(std::string(no_whitespace)) == no_whitespace for: "There is no extra whitespace here"
+==
+"There is no extra whitespace here"
+StringManip.tests.cpp:<line number>: passed: trim(std::string(leading_whitespace)) == no_whitespace for: "There is no extra whitespace here"
+==
+"There is no extra whitespace here"
+StringManip.tests.cpp:<line number>: passed: trim(std::string(trailing_whitespace)) == no_whitespace for: "There is no extra whitespace here"
+==
+"There is no extra whitespace here"
+StringManip.tests.cpp:<line number>: passed: trim(std::string(whitespace_at_both_ends)) == no_whitespace for: "There is no extra whitespace here"
+==
+"There is no extra whitespace here"
+StringManip.tests.cpp:<line number>: passed: trim(StringRef(no_whitespace)) == StringRef(no_whitespace) for: There is no extra whitespace here
+==
+There is no extra whitespace here
+StringManip.tests.cpp:<line number>: passed: trim(StringRef(leading_whitespace)) == StringRef(no_whitespace) for: There is no extra whitespace here
+==
+There is no extra whitespace here
+StringManip.tests.cpp:<line number>: passed: trim(StringRef(trailing_whitespace)) == StringRef(no_whitespace) for: There is no extra whitespace here
+==
+There is no extra whitespace here
+StringManip.tests.cpp:<line number>: passed: trim(StringRef(whitespace_at_both_ends)) == StringRef(no_whitespace) for: There is no extra whitespace here
+==
+There is no extra whitespace here
 Exception.tests.cpp:<line number>: failed: unexpected exception with message: '3.14'
 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 )
@@ -1189,6 +1422,15 @@ Approx.tests.cpp:<line number>: passed: approx( d ) == 1.22 for: Approx( 1.23 )
 Approx.tests.cpp:<line number>: passed: approx( d ) == 1.24 for: Approx( 1.23 ) == 1.24
 Approx.tests.cpp:<line number>: passed: approx( d ) != 1.25 for: Approx( 1.23 ) != 1.25
 VariadicMacros.tests.cpp:<line number>: passed: with 1 message: 'no assertions'
+Matchers.tests.cpp:<line number>: passed: empty, Approx(empty) for: {  } is approx: {  }
+Matchers.tests.cpp:<line number>: passed: v1, Approx(v1) for: { 1.0, 2.0, 3.0 } is approx: { 1.0, 2.0, 3.0 }
+Matchers.tests.cpp:<line number>: passed: v1, !Approx(temp) for: { 1.0, 2.0, 3.0 } not is approx: { 1.0, 2.0, 3.0, 4.0 }
+Matchers.tests.cpp:<line number>: passed: v1, !Approx(v2) for: { 1.0, 2.0, 3.0 } not is approx: { 1.5, 2.5, 3.5 }
+Matchers.tests.cpp:<line number>: passed: v1, Approx(v2).margin(0.5) for: { 1.0, 2.0, 3.0 } is approx: { 1.5, 2.5, 3.5 }
+Matchers.tests.cpp:<line number>: passed: v1, Approx(v2).epsilon(0.5) for: { 1.0, 2.0, 3.0 } is approx: { 1.5, 2.5, 3.5 }
+Matchers.tests.cpp:<line number>: passed: v1, Approx(v2).epsilon(0.1).scale(500) for: { 1.0, 2.0, 3.0 } is approx: { 1.5, 2.5, 3.5 }
+Matchers.tests.cpp:<line number>: failed: empty, Approx(t1) for: {  } is approx: { 1.0, 2.0 }
+Matchers.tests.cpp:<line number>: failed: v1, Approx(v2) for: { 2.0, 4.0, 6.0 } is approx: { 1.0, 3.0, 5.0 }
 Matchers.tests.cpp:<line number>: passed: v, VectorContains(1) for: { 1, 2, 3 } Contains: 1
 Matchers.tests.cpp:<line number>: passed: v, VectorContains(2) for: { 1, 2, 3 } Contains: 2
 Matchers.tests.cpp:<line number>: passed: v, Contains(v2) for: { 1, 2, 3 } Contains: { 1, 2 }
@@ -1355,6 +1597,13 @@ Tricky.tests.cpp:<line number>: passed: ptr.get() == 0 for: 0 == 0
 ToStringPair.tests.cpp:<line number>: passed: ::Catch::Detail::stringify( pair ) == "{ { 42, \"Arthur\" }, { \"Ford\", 24 } }" for: "{ { 42, "Arthur" }, { "Ford", 24 } }"
 ==
 "{ { 42, "Arthur" }, { "Ford", 24 } }"
+ToString.tests.cpp:<line number>: passed: parseEnums( "" ), Equals( std::vector<Catch::StringRef>{} ) for: {  } Equals: {  }
+ToString.tests.cpp:<line number>: passed: parseEnums( "ClassName::EnumName::Value1" ), Equals(std::vector<Catch::StringRef>{"Value1"} ) for: { Value1 } Equals: { Value1 }
+ToString.tests.cpp:<line number>: passed: parseEnums( "Value1" ), Equals( std::vector<Catch::StringRef>{"Value1"} ) for: { Value1 } Equals: { Value1 }
+ToString.tests.cpp:<line number>: passed: parseEnums( "EnumName::Value1" ), Equals(std::vector<Catch::StringRef>{"Value1"} ) for: { Value1 } Equals: { Value1 }
+ToString.tests.cpp:<line number>: passed: parseEnums( "ClassName::EnumName::Value1, ClassName::EnumName::Value2" ), Equals( std::vector<Catch::StringRef>{"Value1", "Value2"} ) for: { Value1, Value2 } Equals: { Value1, Value2 }
+ToString.tests.cpp:<line number>: passed: parseEnums( "ClassName::EnumName::Value1, ClassName::EnumName::Value2, ClassName::EnumName::Value3" ), Equals( std::vector<Catch::StringRef>{"Value1", "Value2", "Value3"} ) for: { Value1, Value2, Value3 } Equals: { Value1, Value2, Value3 }
+ToString.tests.cpp:<line number>: passed: parseEnums( "ClassName::EnumName::Value1,ClassName::EnumName::Value2 , ClassName::EnumName::Value3" ), Equals( std::vector<Catch::StringRef>{"Value1", "Value2", "Value3"} ) for: { Value1, Value2, Value3 } Equals: { Value1, Value2, Value3 }
 Tricky.tests.cpp:<line number>: passed: p == 0 for: 0 == 0
 Message.tests.cpp:<line number>: passed: true with 1 message: 'this MAY be seen IF info is printed for passing assertions'
 Message.tests.cpp:<line number>: failed: false with 2 messages: 'this SHOULD be seen' and 'this SHOULD also be seen'
@@ -1365,23 +1614,26 @@ Message.tests.cpp:<line number>: passed: true
 Misc.tests.cpp:<line number>: passed: a != b for: 1 != 2
 Misc.tests.cpp:<line number>: passed: b != a for: 2 != 1
 Misc.tests.cpp:<line number>: passed: a != b for: 1 != 2
-String.tests.cpp:<line number>: passed: Catch::replaceInPlace( letters, "b", "z" ) for: true
-String.tests.cpp:<line number>: passed: letters == "azcdefcg" for: "azcdefcg" == "azcdefcg"
-String.tests.cpp:<line number>: passed: Catch::replaceInPlace( letters, "c", "z" ) for: true
-String.tests.cpp:<line number>: passed: letters == "abzdefzg" for: "abzdefzg" == "abzdefzg"
-String.tests.cpp:<line number>: passed: Catch::replaceInPlace( letters, "a", "z" ) for: true
-String.tests.cpp:<line number>: passed: letters == "zbcdefcg" for: "zbcdefcg" == "zbcdefcg"
-String.tests.cpp:<line number>: passed: Catch::replaceInPlace( letters, "g", "z" ) for: true
-String.tests.cpp:<line number>: passed: letters == "abcdefcz" for: "abcdefcz" == "abcdefcz"
-String.tests.cpp:<line number>: passed: Catch::replaceInPlace( letters, letters, "replaced" ) for: true
-String.tests.cpp:<line number>: passed: letters == "replaced" for: "replaced" == "replaced"
-String.tests.cpp:<line number>: passed: !(Catch::replaceInPlace( letters, "x", "z" )) for: !false
-String.tests.cpp:<line number>: passed: letters == letters for: "abcdefcg" == "abcdefcg"
-String.tests.cpp:<line number>: passed: Catch::replaceInPlace( s, "'", "|'" ) for: true
-String.tests.cpp:<line number>: passed: s == "didn|'t" for: "didn|'t" == "didn|'t"
+StringManip.tests.cpp:<line number>: passed: Catch::replaceInPlace(letters, "b", "z") for: true
+StringManip.tests.cpp:<line number>: passed: letters == "azcdefcg" for: "azcdefcg" == "azcdefcg"
+StringManip.tests.cpp:<line number>: passed: Catch::replaceInPlace(letters, "c", "z") for: true
+StringManip.tests.cpp:<line number>: passed: letters == "abzdefzg" for: "abzdefzg" == "abzdefzg"
+StringManip.tests.cpp:<line number>: passed: Catch::replaceInPlace(letters, "a", "z") for: true
+StringManip.tests.cpp:<line number>: passed: letters == "zbcdefcg" for: "zbcdefcg" == "zbcdefcg"
+StringManip.tests.cpp:<line number>: passed: Catch::replaceInPlace(letters, "g", "z") for: true
+StringManip.tests.cpp:<line number>: passed: letters == "abcdefcz" for: "abcdefcz" == "abcdefcz"
+StringManip.tests.cpp:<line number>: passed: Catch::replaceInPlace(letters, letters, "replaced") for: true
+StringManip.tests.cpp:<line number>: passed: letters == "replaced" for: "replaced" == "replaced"
+StringManip.tests.cpp:<line number>: passed: !(Catch::replaceInPlace(letters, "x", "z")) for: !false
+StringManip.tests.cpp:<line number>: passed: letters == letters for: "abcdefcg" == "abcdefcg"
+StringManip.tests.cpp:<line number>: passed: Catch::replaceInPlace(s, "'", "|'") for: true
+StringManip.tests.cpp:<line number>: passed: s == "didn|'t" for: "didn|'t" == "didn|'t"
 Misc.tests.cpp:<line number>: failed: false with 1 message: '3'
 Message.tests.cpp:<line number>: failed: false with 2 messages: 'hi' and 'i := 7'
 Tag.tests.cpp:<line number>: passed: testcase.tags, Catch::VectorContains(std::string("magic-tag")) && Catch::VectorContains(std::string(".")) for: { ".", "magic-tag" } ( Contains: "magic-tag" and Contains: "." )
+StringManip.tests.cpp:<line number>: passed: splitStringRef("", ','), Equals(std::vector<StringRef>()) for: {  } Equals: {  }
+StringManip.tests.cpp:<line number>: passed: splitStringRef("abc", ','), Equals(std::vector<StringRef>{"abc"}) for: { abc } Equals: { abc }
+StringManip.tests.cpp:<line number>: passed: splitStringRef("abc,def", ','), Equals(std::vector<StringRef>{"abc", "def"}) for: { abc, def } Equals: { abc, def }
 Message.tests.cpp:<line number>: failed: false with 4 messages: 'Count 1 to 3...' and '1' and '2' and '3'
 Message.tests.cpp:<line number>: failed: false with 4 messages: 'Count 4 to 6...' and '4' and '5' and '6'
 ToStringGeneral.tests.cpp:<line number>: passed: Catch::Detail::stringify( emptyMap ) == "{  }" for: "{  }" == "{  }"
@@ -1505,5 +1757,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 78 test cases, failed 139 assertions.
+Failed 86 test cases, failed 148 assertions.
 
diff --git a/packages/Catch2/projects/SelfTest/Baselines/console.std.approved.txt b/packages/Catch2/projects/SelfTest/Baselines/console.std.approved.txt
index 3b6f20684..fd405a84f 100644
--- a/packages/Catch2/projects/SelfTest/Baselines/console.std.approved.txt
+++ b/packages/Catch2/projects/SelfTest/Baselines/console.std.approved.txt
@@ -163,6 +163,54 @@ Class.tests.cpp:<line number>: FAILED:
 with expansion:
   0 == 1
 
+-------------------------------------------------------------------------------
+A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that fails -
+Template_Foo_2<float, 6>
+-------------------------------------------------------------------------------
+Class.tests.cpp:<line number>
+...............................................................................
+
+Class.tests.cpp:<line number>: FAILED:
+  REQUIRE( Template_Fixture_2<TestType>{}.m_a.size() < 2 )
+with expansion:
+  6 < 2
+
+-------------------------------------------------------------------------------
+A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that fails -
+Template_Foo_2<int, 2>
+-------------------------------------------------------------------------------
+Class.tests.cpp:<line number>
+...............................................................................
+
+Class.tests.cpp:<line number>: FAILED:
+  REQUIRE( Template_Fixture_2<TestType>{}.m_a.size() < 2 )
+with expansion:
+  2 < 2
+
+-------------------------------------------------------------------------------
+A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that fails - std::array
+<float, 6>
+-------------------------------------------------------------------------------
+Class.tests.cpp:<line number>
+...............................................................................
+
+Class.tests.cpp:<line number>: FAILED:
+  REQUIRE( Template_Fixture_2<TestType>{}.m_a.size() < 2 )
+with expansion:
+  6 < 2
+
+-------------------------------------------------------------------------------
+A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that fails - std::array
+<int, 2>
+-------------------------------------------------------------------------------
+Class.tests.cpp:<line number>
+...............................................................................
+
+Class.tests.cpp:<line number>: FAILED:
+  REQUIRE( Template_Fixture_2<TestType>{}.m_a.size() < 2 )
+with expansion:
+  2 < 2
+
 -------------------------------------------------------------------------------
 A TEMPLATE_TEST_CASE_METHOD based test run that fails - double
 -------------------------------------------------------------------------------
@@ -196,6 +244,39 @@ Class.tests.cpp:<line number>: FAILED:
 with expansion:
   1 == 2
 
+-------------------------------------------------------------------------------
+A TEMPLATE_TEST_CASE_METHOD_SIG based test run that fails - 1
+-------------------------------------------------------------------------------
+Class.tests.cpp:<line number>
+...............................................................................
+
+Class.tests.cpp:<line number>: FAILED:
+  REQUIRE( Nttp_Fixture<V>::value == 0 )
+with expansion:
+  1 == 0
+
+-------------------------------------------------------------------------------
+A TEMPLATE_TEST_CASE_METHOD_SIG based test run that fails - 3
+-------------------------------------------------------------------------------
+Class.tests.cpp:<line number>
+...............................................................................
+
+Class.tests.cpp:<line number>: FAILED:
+  REQUIRE( Nttp_Fixture<V>::value == 0 )
+with expansion:
+  3 == 0
+
+-------------------------------------------------------------------------------
+A TEMPLATE_TEST_CASE_METHOD_SIG based test run that fails - 6
+-------------------------------------------------------------------------------
+Class.tests.cpp:<line number>
+...............................................................................
+
+Class.tests.cpp:<line number>: FAILED:
+  REQUIRE( Nttp_Fixture<V>::value == 0 )
+with expansion:
+  6 == 0
+
 -------------------------------------------------------------------------------
 A TEST_CASE_METHOD based test run that fails
 -------------------------------------------------------------------------------
@@ -439,12 +520,12 @@ Matchers.tests.cpp:<line number>
 ...............................................................................
 
 Matchers.tests.cpp:<line number>: FAILED:
-  CHECK_THROWS_MATCHES( throws(3), SpecialException, ExceptionMatcher{1} )
+  CHECK_THROWS_MATCHES( throwsSpecialException(3), SpecialException, ExceptionMatcher{1} )
 with expansion:
   SpecialException::what special exception has value of 1
 
 Matchers.tests.cpp:<line number>: FAILED:
-  REQUIRE_THROWS_MATCHES( throws(4), SpecialException, ExceptionMatcher{1} )
+  REQUIRE_THROWS_MATCHES( throwsSpecialException(4), SpecialException, ExceptionMatcher{1} )
 with expansion:
   SpecialException::what special exception has value of 1
 
@@ -861,6 +942,30 @@ Exception.tests.cpp:<line number>: FAILED:
 due to unexpected exception with message:
   3.14
 
+-------------------------------------------------------------------------------
+Vector Approx matcher -- failing
+  Empty and non empty vectors are not approx equal
+-------------------------------------------------------------------------------
+Matchers.tests.cpp:<line number>
+...............................................................................
+
+Matchers.tests.cpp:<line number>: FAILED:
+  CHECK_THAT( empty, Approx(t1) )
+with expansion:
+  {  } is approx: { 1.0, 2.0 }
+
+-------------------------------------------------------------------------------
+Vector Approx matcher -- failing
+  Just different vectors
+-------------------------------------------------------------------------------
+Matchers.tests.cpp:<line number>
+...............................................................................
+
+Matchers.tests.cpp:<line number>: FAILED:
+  CHECK_THAT( v1, Approx(v2) )
+with expansion:
+  { 2.0, 4.0, 6.0 } is approx: { 1.0, 3.0, 5.0 }
+
 -------------------------------------------------------------------------------
 Vector matchers that fail
   Contains (element)
@@ -1275,6 +1380,6 @@ due to unexpected exception with message:
   Why would you throw a std::string?
 
 ===============================================================================
-test cases:  258 |  192 passed |  62 failed |  4 failed as expected
-assertions: 1419 | 1276 passed | 122 failed | 21 failed as expected
+test cases:  304 |  230 passed |  70 failed |  4 failed as expected
+assertions: 1621 | 1469 passed | 131 failed | 21 failed as expected
 
diff --git a/packages/Catch2/projects/SelfTest/Baselines/console.sw.approved.txt b/packages/Catch2/projects/SelfTest/Baselines/console.sw.approved.txt
index c63de78ac..f234f8824 100644
--- a/packages/Catch2/projects/SelfTest/Baselines/console.sw.approved.txt
+++ b/packages/Catch2/projects/SelfTest/Baselines/console.sw.approved.txt
@@ -39,6 +39,22 @@ with expansion:
 Compilation.tests.cpp:<line number>
 ...............................................................................
 
+Compilation.tests.cpp:<line number>: PASSED:
+  REQUIRE( y.v == 0 )
+with expansion:
+  0 == 0
+
+Compilation.tests.cpp:<line number>: PASSED:
+  REQUIRE( 0 == y.v )
+with expansion:
+  0 == 0
+
+-------------------------------------------------------------------------------
+#1027: Bitfields can be captured
+-------------------------------------------------------------------------------
+Compilation.tests.cpp:<line number>
+...............................................................................
+
 Compilation.tests.cpp:<line number>: PASSED:
   REQUIRE( y.v == 0 )
 with expansion:
@@ -1179,6 +1195,102 @@ Class.tests.cpp:<line number>: PASSED:
 with expansion:
   0 == 0
 
+-------------------------------------------------------------------------------
+A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that fails -
+Template_Foo_2<float, 6>
+-------------------------------------------------------------------------------
+Class.tests.cpp:<line number>
+...............................................................................
+
+Class.tests.cpp:<line number>: FAILED:
+  REQUIRE( Template_Fixture_2<TestType>{}.m_a.size() < 2 )
+with expansion:
+  6 < 2
+
+-------------------------------------------------------------------------------
+A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that fails -
+Template_Foo_2<int, 2>
+-------------------------------------------------------------------------------
+Class.tests.cpp:<line number>
+...............................................................................
+
+Class.tests.cpp:<line number>: FAILED:
+  REQUIRE( Template_Fixture_2<TestType>{}.m_a.size() < 2 )
+with expansion:
+  2 < 2
+
+-------------------------------------------------------------------------------
+A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that fails - std::array
+<float, 6>
+-------------------------------------------------------------------------------
+Class.tests.cpp:<line number>
+...............................................................................
+
+Class.tests.cpp:<line number>: FAILED:
+  REQUIRE( Template_Fixture_2<TestType>{}.m_a.size() < 2 )
+with expansion:
+  6 < 2
+
+-------------------------------------------------------------------------------
+A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that fails - std::array
+<int, 2>
+-------------------------------------------------------------------------------
+Class.tests.cpp:<line number>
+...............................................................................
+
+Class.tests.cpp:<line number>: FAILED:
+  REQUIRE( Template_Fixture_2<TestType>{}.m_a.size() < 2 )
+with expansion:
+  2 < 2
+
+-------------------------------------------------------------------------------
+A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that succeeds -
+Template_Foo_2<float,6>
+-------------------------------------------------------------------------------
+Class.tests.cpp:<line number>
+...............................................................................
+
+Class.tests.cpp:<line number>: PASSED:
+  REQUIRE( Template_Fixture_2<TestType>{}.m_a.size() >= 2 )
+with expansion:
+  6 >= 2
+
+-------------------------------------------------------------------------------
+A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that succeeds -
+Template_Foo_2<int,2>
+-------------------------------------------------------------------------------
+Class.tests.cpp:<line number>
+...............................................................................
+
+Class.tests.cpp:<line number>: PASSED:
+  REQUIRE( Template_Fixture_2<TestType>{}.m_a.size() >= 2 )
+with expansion:
+  2 >= 2
+
+-------------------------------------------------------------------------------
+A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that succeeds - std::
+array<float,6>
+-------------------------------------------------------------------------------
+Class.tests.cpp:<line number>
+...............................................................................
+
+Class.tests.cpp:<line number>: PASSED:
+  REQUIRE( Template_Fixture_2<TestType>{}.m_a.size() >= 2 )
+with expansion:
+  6 >= 2
+
+-------------------------------------------------------------------------------
+A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that succeeds - std::
+array<int,2>
+-------------------------------------------------------------------------------
+Class.tests.cpp:<line number>
+...............................................................................
+
+Class.tests.cpp:<line number>: PASSED:
+  REQUIRE( Template_Fixture_2<TestType>{}.m_a.size() >= 2 )
+with expansion:
+  2 >= 2
+
 -------------------------------------------------------------------------------
 A TEMPLATE_TEST_CASE_METHOD based test run that fails - double
 -------------------------------------------------------------------------------
@@ -1245,6 +1357,72 @@ Class.tests.cpp:<line number>: PASSED:
 with expansion:
   1 == 1
 
+-------------------------------------------------------------------------------
+A TEMPLATE_TEST_CASE_METHOD_SIG based test run that fails - 1
+-------------------------------------------------------------------------------
+Class.tests.cpp:<line number>
+...............................................................................
+
+Class.tests.cpp:<line number>: FAILED:
+  REQUIRE( Nttp_Fixture<V>::value == 0 )
+with expansion:
+  1 == 0
+
+-------------------------------------------------------------------------------
+A TEMPLATE_TEST_CASE_METHOD_SIG based test run that fails - 3
+-------------------------------------------------------------------------------
+Class.tests.cpp:<line number>
+...............................................................................
+
+Class.tests.cpp:<line number>: FAILED:
+  REQUIRE( Nttp_Fixture<V>::value == 0 )
+with expansion:
+  3 == 0
+
+-------------------------------------------------------------------------------
+A TEMPLATE_TEST_CASE_METHOD_SIG based test run that fails - 6
+-------------------------------------------------------------------------------
+Class.tests.cpp:<line number>
+...............................................................................
+
+Class.tests.cpp:<line number>: FAILED:
+  REQUIRE( Nttp_Fixture<V>::value == 0 )
+with expansion:
+  6 == 0
+
+-------------------------------------------------------------------------------
+A TEMPLATE_TEST_CASE_METHOD_SIG based test run that succeeds - 1
+-------------------------------------------------------------------------------
+Class.tests.cpp:<line number>
+...............................................................................
+
+Class.tests.cpp:<line number>: PASSED:
+  REQUIRE( Nttp_Fixture<V>::value > 0 )
+with expansion:
+  1 > 0
+
+-------------------------------------------------------------------------------
+A TEMPLATE_TEST_CASE_METHOD_SIG based test run that succeeds - 3
+-------------------------------------------------------------------------------
+Class.tests.cpp:<line number>
+...............................................................................
+
+Class.tests.cpp:<line number>: PASSED:
+  REQUIRE( Nttp_Fixture<V>::value > 0 )
+with expansion:
+  3 > 0
+
+-------------------------------------------------------------------------------
+A TEMPLATE_TEST_CASE_METHOD_SIG based test run that succeeds - 6
+-------------------------------------------------------------------------------
+Class.tests.cpp:<line number>
+...............................................................................
+
+Class.tests.cpp:<line number>: PASSED:
+  REQUIRE( Nttp_Fixture<V>::value > 0 )
+with expansion:
+  6 > 0
+
 -------------------------------------------------------------------------------
 A TEST_CASE_METHOD based test run that fails
 -------------------------------------------------------------------------------
@@ -1311,6 +1489,50 @@ Misc.tests.cpp:<line number>: PASSED:
 with expansion:
   0 == 0
 
+-------------------------------------------------------------------------------
+A Template product test case with array signature - Bar<float, 42>
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( x.size() > 0 )
+with expansion:
+  42 > 0
+
+-------------------------------------------------------------------------------
+A Template product test case with array signature - Bar<int, 9>
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( x.size() > 0 )
+with expansion:
+  9 > 0
+
+-------------------------------------------------------------------------------
+A Template product test case with array signature - std::array<float, 42>
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( x.size() > 0 )
+with expansion:
+  42 > 0
+
+-------------------------------------------------------------------------------
+A Template product test case with array signature - std::array<int, 9>
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( x.size() > 0 )
+with expansion:
+  9 > 0
+
 -------------------------------------------------------------------------------
 A comparison that uses literals instead of the normal constructor
 -------------------------------------------------------------------------------
@@ -1717,43 +1939,6 @@ 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 can deal with complex expressions
 -------------------------------------------------------------------------------
@@ -1786,6 +1971,27 @@ with messages:
   (1, 2) := 2
   (2, 3) := 3
 
+-------------------------------------------------------------------------------
+CAPTURE parses string and character constants
+-------------------------------------------------------------------------------
+Message.tests.cpp:<line number>
+...............................................................................
+
+Message.tests.cpp:<line number>: PASSED:
+with messages:
+  ("comma, in string", "escaped, \", ") := "escaped, ", "
+  "single quote in string,'," := "single quote in string,',"
+  "some escapes, \\,\\\\" := "some escapes, \,\\"
+  "some, ), unmatched, } prenheses {[<" := "some, ), unmatched, } prenheses {[
+  <"
+  '"' := '"'
+  '\'' := '''
+  ',' := ','
+  '}' := '}'
+  ')' := ')'
+  '(' := '('
+  '{' := '{'
+
 -------------------------------------------------------------------------------
 Capture and info messages
   Capture should stringify like assertions
@@ -1973,6 +2179,32 @@ Tricky.tests.cpp:<line number>: PASSED:
 with expansion:
   0x<hex digits> == 0x<hex digits>
 
+-------------------------------------------------------------------------------
+Comparison ops
+-------------------------------------------------------------------------------
+RandomNumberGeneration.tests.cpp:<line number>
+...............................................................................
+
+RandomNumberGeneration.tests.cpp:<line number>: PASSED:
+  REQUIRE( SimplePcg32{} == SimplePcg32{} )
+with expansion:
+  {?} == {?}
+
+RandomNumberGeneration.tests.cpp:<line number>: PASSED:
+  REQUIRE( SimplePcg32{ 0 } != SimplePcg32{} )
+with expansion:
+  {?} != {?}
+
+RandomNumberGeneration.tests.cpp:<line number>: PASSED:
+  REQUIRE_FALSE( SimplePcg32{ 1 } == SimplePcg32{ 2 } )
+with expansion:
+  !({?} == {?})
+
+RandomNumberGeneration.tests.cpp:<line number>: PASSED:
+  REQUIRE_FALSE( SimplePcg32{ 1 } != SimplePcg32{ 1 } )
+with expansion:
+  !({?} != {?})
+
 -------------------------------------------------------------------------------
 Comparison with explicitly convertible types
 -------------------------------------------------------------------------------
@@ -2176,55 +2408,239 @@ with expansion:
   "this string contains 'abc' as a substring" contains: "STRING"
 
 -------------------------------------------------------------------------------
-Custom exceptions can be translated when testing for nothrow
+Copy and then generate a range
+  from var and iterators
 -------------------------------------------------------------------------------
-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:
+  REQUIRE( elem % 2 == 1 )
+with expansion:
+  1 == 1
 
 -------------------------------------------------------------------------------
-Custom exceptions can be translated when testing for throwing as something else
+Copy and then generate a range
+  from var and iterators
 -------------------------------------------------------------------------------
-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:
+  REQUIRE( elem % 2 == 1 )
+with expansion:
+  1 == 1
 
 -------------------------------------------------------------------------------
-Custom std-exceptions can be custom translated
+Copy and then generate a range
+  from var and iterators
 -------------------------------------------------------------------------------
-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:
+  REQUIRE( elem % 2 == 1 )
+with expansion:
+  1 == 1
 
 -------------------------------------------------------------------------------
-Default scale is invisible to comparison
+Copy and then generate a range
+  from var and iterators
 -------------------------------------------------------------------------------
-Approx.tests.cpp:<line number>
+Generators.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)) )
+Generators.tests.cpp:<line number>: PASSED:
+  REQUIRE( elem % 2 == 1 )
 with expansion:
-  0.00001 != Approx( 0.0000001 )
+  1 == 1
 
 -------------------------------------------------------------------------------
-EndsWith string matcher
+Copy and then generate a range
+  from var and iterators
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>: PASSED:
+  REQUIRE( elem % 2 == 1 )
+with expansion:
+  1 == 1
+
+-------------------------------------------------------------------------------
+Copy and then generate a range
+  from var and iterators
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>: PASSED:
+  REQUIRE( elem % 2 == 1 )
+with expansion:
+  1 == 1
+
+-------------------------------------------------------------------------------
+Copy and then generate a range
+  From a temporary container
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>: PASSED:
+  REQUIRE( elem % 2 == 1 )
+with expansion:
+  1 == 1
+
+-------------------------------------------------------------------------------
+Copy and then generate a range
+  From a temporary container
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>: PASSED:
+  REQUIRE( elem % 2 == 1 )
+with expansion:
+  1 == 1
+
+-------------------------------------------------------------------------------
+Copy and then generate a range
+  From a temporary container
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>: PASSED:
+  REQUIRE( elem % 2 == 1 )
+with expansion:
+  1 == 1
+
+-------------------------------------------------------------------------------
+Copy and then generate a range
+  From a temporary container
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>: PASSED:
+  REQUIRE( elem % 2 == 1 )
+with expansion:
+  1 == 1
+
+-------------------------------------------------------------------------------
+Copy and then generate a range
+  From a temporary container
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>: PASSED:
+  REQUIRE( elem % 2 == 1 )
+with expansion:
+  1 == 1
+
+-------------------------------------------------------------------------------
+Copy and then generate a range
+  From a temporary container
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>: PASSED:
+  REQUIRE( elem % 2 == 1 )
+with expansion:
+  1 == 1
+
+-------------------------------------------------------------------------------
+Copy and then generate a range
+  Final validation
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>: PASSED:
+  REQUIRE( call_count == 1 )
+with expansion:
+  1 == 1
+
+Generators.tests.cpp:<line number>: PASSED:
+  REQUIRE( make_data().size() == test_count )
+with expansion:
+  6 == 6
+
+-------------------------------------------------------------------------------
+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 )
+
+-------------------------------------------------------------------------------
+Directly creating an EnumInfo
+-------------------------------------------------------------------------------
+ToString.tests.cpp:<line number>
+...............................................................................
+
+ToString.tests.cpp:<line number>: PASSED:
+  CHECK( enumInfo->lookup(0) == "Value1" )
+with expansion:
+  Value1 == "Value1"
+
+ToString.tests.cpp:<line number>: PASSED:
+  CHECK( enumInfo->lookup(1) == "Value2" )
+with expansion:
+  Value2 == "Value2"
+
+ToString.tests.cpp:<line number>: PASSED:
+  CHECK( enumInfo->lookup(3) == "{** unexpected enum value **}" )
+with expansion:
+  {** unexpected enum value **}
+  ==
+  "{** unexpected enum value **}"
+
+-------------------------------------------------------------------------------
+EndsWith string matcher
 -------------------------------------------------------------------------------
 Matchers.tests.cpp:<line number>
 ...............................................................................
@@ -2240,6 +2656,56 @@ with expansion:
   "this string contains 'abc' as a substring" ends with: "this" (case
   insensitive)
 
+-------------------------------------------------------------------------------
+Enums can quickly have stringification enabled using REGISTER_ENUM
+-------------------------------------------------------------------------------
+EnumToString.tests.cpp:<line number>
+...............................................................................
+
+EnumToString.tests.cpp:<line number>: PASSED:
+  REQUIRE( stringify( EnumClass3::Value1 ) == "Value1" )
+with expansion:
+  "Value1" == "Value1"
+
+EnumToString.tests.cpp:<line number>: PASSED:
+  REQUIRE( stringify( EnumClass3::Value2 ) == "Value2" )
+with expansion:
+  "Value2" == "Value2"
+
+EnumToString.tests.cpp:<line number>: PASSED:
+  REQUIRE( stringify( EnumClass3::Value3 ) == "Value3" )
+with expansion:
+  "Value3" == "Value3"
+
+EnumToString.tests.cpp:<line number>: PASSED:
+  REQUIRE( stringify( EnumClass3::Value4 ) == "{** unexpected enum value **}" )
+with expansion:
+  "{** unexpected enum value **}"
+  ==
+  "{** unexpected enum value **}"
+
+EnumToString.tests.cpp:<line number>: PASSED:
+  REQUIRE( stringify( ec3 ) == "Value2" )
+with expansion:
+  "Value2" == "Value2"
+
+-------------------------------------------------------------------------------
+Enums in namespaces can quickly have stringification enabled using
+REGISTER_ENUM
+-------------------------------------------------------------------------------
+EnumToString.tests.cpp:<line number>
+...............................................................................
+
+EnumToString.tests.cpp:<line number>: PASSED:
+  REQUIRE( stringify( Bikeshed::Colours::Red ) == "Red" )
+with expansion:
+  "Red" == "Red"
+
+EnumToString.tests.cpp:<line number>: PASSED:
+  REQUIRE( stringify( Bikeshed::Colours::Blue ) == "Blue" )
+with expansion:
+  "Blue" == "Blue"
+
 -------------------------------------------------------------------------------
 Epsilon only applies to Approx's value
 -------------------------------------------------------------------------------
@@ -2464,12 +2930,12 @@ Matchers.tests.cpp:<line number>
 ...............................................................................
 
 Matchers.tests.cpp:<line number>: FAILED:
-  CHECK_THROWS_MATCHES( throws(3), SpecialException, ExceptionMatcher{1} )
+  CHECK_THROWS_MATCHES( throwsSpecialException(3), SpecialException, ExceptionMatcher{1} )
 with expansion:
   SpecialException::what special exception has value of 1
 
 Matchers.tests.cpp:<line number>: FAILED:
-  REQUIRE_THROWS_MATCHES( throws(4), SpecialException, ExceptionMatcher{1} )
+  REQUIRE_THROWS_MATCHES( throwsSpecialException(4), SpecialException, ExceptionMatcher{1} )
 with expansion:
   SpecialException::what special exception has value of 1
 
@@ -2480,12 +2946,12 @@ Matchers.tests.cpp:<line number>
 ...............................................................................
 
 Matchers.tests.cpp:<line number>: PASSED:
-  CHECK_THROWS_MATCHES( throws(1), SpecialException, ExceptionMatcher{1} )
+  CHECK_THROWS_MATCHES( throwsSpecialException(1), SpecialException, ExceptionMatcher{1} )
 with expansion:
   SpecialException::what special exception has value of 1
 
 Matchers.tests.cpp:<line number>: PASSED:
-  REQUIRE_THROWS_MATCHES( throws(2), SpecialException, ExceptionMatcher{2} )
+  REQUIRE_THROWS_MATCHES( throwsSpecialException(2), SpecialException, ExceptionMatcher{2} )
 with expansion:
   SpecialException::what special exception has value of 2
 
@@ -2540,6 +3006,32 @@ Exception.tests.cpp:<line number>: PASSED:
 with expansion:
   "expected exception" contains: "except" (case insensitive)
 
+-------------------------------------------------------------------------------
+Exceptions matchers
+-------------------------------------------------------------------------------
+Matchers.tests.cpp:<line number>
+...............................................................................
+
+Matchers.tests.cpp:<line number>: PASSED:
+  REQUIRE_THROWS_MATCHES( throwsDerivedException(), DerivedException, Message("DerivedException::what") )
+with expansion:
+  DerivedException::what exception message matches "DerivedException::what"
+
+Matchers.tests.cpp:<line number>: PASSED:
+  REQUIRE_THROWS_MATCHES( throwsDerivedException(), DerivedException, !Message("derivedexception::what") )
+with expansion:
+  DerivedException::what not exception message matches "derivedexception::what"
+
+Matchers.tests.cpp:<line number>: PASSED:
+  REQUIRE_THROWS_MATCHES( throwsSpecialException(2), SpecialException, !Message("DerivedException::what") )
+with expansion:
+  SpecialException::what not exception message matches "DerivedException::what"
+
+Matchers.tests.cpp:<line number>: PASSED:
+  REQUIRE_THROWS_MATCHES( throwsSpecialException(2), SpecialException, Message("SpecialException::what") )
+with expansion:
+  SpecialException::what exception message matches "SpecialException::what"
+
 -------------------------------------------------------------------------------
 Expected exceptions that don't throw or unexpected exceptions fail the test
 -------------------------------------------------------------------------------
@@ -2622,6 +3114,46 @@ Misc.tests.cpp:<line number>: PASSED:
 with expansion:
   3628800 (0x<hex digits>) == 3628800 (0x<hex digits>)
 
+-------------------------------------------------------------------------------
+Floating point matchers: double
+  Relative
+-------------------------------------------------------------------------------
+Matchers.tests.cpp:<line number>
+...............................................................................
+
+Matchers.tests.cpp:<line number>: PASSED:
+  REQUIRE_THAT( 10., WithinRel(11.1, 0.1) )
+with expansion:
+  10.0 and 11.1 are within 10% of each other
+
+Matchers.tests.cpp:<line number>: PASSED:
+  REQUIRE_THAT( 10., !WithinRel(11.2, 0.1) )
+with expansion:
+  10.0 not and 11.2 are within 10% of each other
+
+Matchers.tests.cpp:<line number>: PASSED:
+  REQUIRE_THAT( 1., !WithinRel(0., 0.99) )
+with expansion:
+  1.0 not and 0 are within 99% of each other
+
+Matchers.tests.cpp:<line number>: PASSED:
+  REQUIRE_THAT( -0., WithinRel(0.) )
+with expansion:
+  -0.0 and 0 are within 2.22045e-12% of each other
+
+-------------------------------------------------------------------------------
+Floating point matchers: double
+  Relative
+  Some subnormal values
+-------------------------------------------------------------------------------
+Matchers.tests.cpp:<line number>
+...............................................................................
+
+Matchers.tests.cpp:<line number>: PASSED:
+  REQUIRE_THAT( v1, WithinRel(v2) )
+with expansion:
+  0.0 and 2.22507e-308 are within 2.22045e-12% of each other
+
 -------------------------------------------------------------------------------
 Floating point matchers: double
   Margin
@@ -2649,11 +3181,6 @@ Matchers.tests.cpp:<line number>: PASSED:
 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:
@@ -2684,37 +3211,44 @@ 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
+  1.0 is within 0 ULPs of 1.0000000000000000e+00 ([1.0000000000000000e+00, 1.
+  0000000000000000e+00])
 
 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
+  1.0 is within 1 ULPs of 1.0000000000000000e+00 ([9.9999999999999989e-01, 1.
+  0000000000000002e+00])
 
 Matchers.tests.cpp:<line number>: PASSED:
-  REQUIRE_THAT( nextafter(1., 0.), WithinULP(1., 1) )
+  REQUIRE_THAT( 0., WithinULP(nextafter(0., 1.), 1) )
 with expansion:
-  1.0 is within 1 ULPs of 1.0
+  0.0 is within 1 ULPs of 4.9406564584124654e-324 ([0.0000000000000000e+00, 9.
+  8813129168249309e-324])
 
 Matchers.tests.cpp:<line number>: PASSED:
-  REQUIRE_THAT( nextafter(1., 2.), !WithinULP(1., 0) )
+  REQUIRE_THAT( 1., WithinULP(nextafter(1., 0.), 1) )
 with expansion:
-  1.0 not is within 0 ULPs of 1.0
+  1.0 is within 1 ULPs of 9.9999999999999989e-01 ([9.9999999999999978e-01, 1.
+  0000000000000000e+00])
 
 Matchers.tests.cpp:<line number>: PASSED:
-  REQUIRE_THAT( 1., WithinULP(1., 0) )
+  REQUIRE_THAT( 1., !WithinULP(nextafter(1., 2.), 0) )
 with expansion:
-  1.0 is within 0 ULPs of 1.0
+  1.0 not is within 0 ULPs of 1.0000000000000002e+00 ([1.0000000000000002e+00,
+  1.0000000000000002e+00])
 
 Matchers.tests.cpp:<line number>: PASSED:
-  REQUIRE_THAT( -0., WithinULP(0., 0) )
+  REQUIRE_THAT( 1., WithinULP(1., 0) )
 with expansion:
-  -0.0 is within 0 ULPs of 0.0
+  1.0 is within 0 ULPs of 1.0000000000000000e+00 ([1.0000000000000000e+00, 1.
+  0000000000000000e+00])
 
 Matchers.tests.cpp:<line number>: PASSED:
-  REQUIRE_THAT( NAN, !WithinULP(NAN, 123) )
+  REQUIRE_THAT( -0., WithinULP(0., 0) )
 with expansion:
-  nanf not is within 123 ULPs of nanf
+  -0.0 is within 0 ULPs of 0.0000000000000000e+00 ([0.0000000000000000e+00, 0.
+  0000000000000000e+00])
 
 -------------------------------------------------------------------------------
 Floating point matchers: double
@@ -2726,17 +3260,19 @@ 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 )
+  1.0 ( is within 0.5 of 1.0 or is within 1 ULPs of 2.0000000000000000e+00 ([1.
+  9999999999999998e+00, 2.0000000000000004e+00]) )
 
 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 )
+  1.0 ( is within 0.5 of 2.0 or is within 0 ULPs of 1.0000000000000000e+00 ([1.
+  0000000000000000e+00, 1.0000000000000000e+00]) )
 
 Matchers.tests.cpp:<line number>: PASSED:
-  REQUIRE_THAT( NAN, !(WithinAbs(NAN, 100) || WithinULP(NAN, 123)) )
+  REQUIRE_THAT( 0.0001, WithinAbs(0., 0.001) || WithinRel(0., 0.1) )
 with expansion:
-  nanf not ( is within 100.0 of nan or is within 123 ULPs of nanf )
+  0.0001 ( is within 0.001 of 0.0 or and 0 are within 10% of each other )
 
 -------------------------------------------------------------------------------
 Floating point matchers: double
@@ -2755,51 +3291,92 @@ 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 )
+  REQUIRE_NOTHROW( WithinRel(1., 0.) )
+
+Matchers.tests.cpp:<line number>: PASSED:
+  REQUIRE_THROWS_AS( WithinRel(1., -0.2), std::domain_error )
+
+Matchers.tests.cpp:<line number>: PASSED:
+  REQUIRE_THROWS_AS( WithinRel(1., 1.), std::domain_error )
 
 -------------------------------------------------------------------------------
 Floating point matchers: float
-  Margin
+  Relative
 -------------------------------------------------------------------------------
 Matchers.tests.cpp:<line number>
 ...............................................................................
 
 Matchers.tests.cpp:<line number>: PASSED:
-  REQUIRE_THAT( 1.f, WithinAbs(1.f, 0) )
-with expansion:
-  1.0f is within 0.0 of 1.0
-
-Matchers.tests.cpp:<line number>: PASSED:
-  REQUIRE_THAT( 0.f, WithinAbs(1.f, 1) )
+  REQUIRE_THAT( 10.f, WithinRel(11.1f, 0.1f) )
 with expansion:
-  0.0f is within 1.0 of 1.0
+  10.0f and 11.1 are within 10% of each other
 
 Matchers.tests.cpp:<line number>: PASSED:
-  REQUIRE_THAT( 0.f, !WithinAbs(1.f, 0.99f) )
+  REQUIRE_THAT( 10.f, !WithinRel(11.2f, 0.1f) )
 with expansion:
-  0.0f not is within 0.9900000095 of 1.0
+  10.0f not and 11.2 are within 10% of each other
 
 Matchers.tests.cpp:<line number>: PASSED:
-  REQUIRE_THAT( 0.f, !WithinAbs(1.f, 0.99f) )
+  REQUIRE_THAT( 1.f, !WithinRel(0.f, 0.99f) )
 with expansion:
-  0.0f not is within 0.9900000095 of 1.0
+  1.0f not and 0 are within 99% of each other
 
 Matchers.tests.cpp:<line number>: PASSED:
-  REQUIRE_THAT( 0.f, WithinAbs(-0.f, 0) )
+  REQUIRE_THAT( -0.f, WithinRel(0.f) )
 with expansion:
-  0.0f is within 0.0 of -0.0
+  -0.0f and 0 are within 0.00119209% of each other
 
-Matchers.tests.cpp:<line number>: PASSED:
-  REQUIRE_THAT( NAN, !WithinAbs(NAN, 0) )
-with expansion:
-  nanf not is within 0.0 of nan
+-------------------------------------------------------------------------------
+Floating point matchers: float
+  Relative
+  Some subnormal values
+-------------------------------------------------------------------------------
+Matchers.tests.cpp:<line number>
+...............................................................................
 
 Matchers.tests.cpp:<line number>: PASSED:
-  REQUIRE_THAT( 11.f, !WithinAbs(10.f, 0.5f) )
+  REQUIRE_THAT( v1, WithinRel(v2) )
 with expansion:
-  11.0f not is within 0.5 of 10.0
+  0.0f and 1.17549e-38 are within 0.00119209% of each other
 
-Matchers.tests.cpp:<line number>: PASSED:
+-------------------------------------------------------------------------------
+Floating point matchers: float
+  Margin
+-------------------------------------------------------------------------------
+Matchers.tests.cpp:<line number>
+...............................................................................
+
+Matchers.tests.cpp:<line number>: PASSED:
+  REQUIRE_THAT( 1.f, WithinAbs(1.f, 0) )
+with expansion:
+  1.0f is within 0.0 of 1.0
+
+Matchers.tests.cpp:<line number>: PASSED:
+  REQUIRE_THAT( 0.f, WithinAbs(1.f, 1) )
+with expansion:
+  0.0f is within 1.0 of 1.0
+
+Matchers.tests.cpp:<line number>: PASSED:
+  REQUIRE_THAT( 0.f, !WithinAbs(1.f, 0.99f) )
+with expansion:
+  0.0f not is within 0.9900000095 of 1.0
+
+Matchers.tests.cpp:<line number>: PASSED:
+  REQUIRE_THAT( 0.f, !WithinAbs(1.f, 0.99f) )
+with expansion:
+  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:
+  REQUIRE_THAT( 11.f, !WithinAbs(10.f, 0.5f) )
+with expansion:
+  11.0f not is within 0.5 of 10.0
+
+Matchers.tests.cpp:<line number>: PASSED:
   REQUIRE_THAT( 10.f, !WithinAbs(11.f, 0.5f) )
 with expansion:
   10.0f not is within 0.5 of 11.0
@@ -2824,37 +3401,38 @@ Matchers.tests.cpp:<line number>
 Matchers.tests.cpp:<line number>: PASSED:
   REQUIRE_THAT( 1.f, WithinULP(1.f, 0) )
 with expansion:
-  1.0f is within 0 ULPs of 1.0f
+  1.0f is within 0 ULPs of 1.00000000e+00f ([1.00000000e+00, 1.00000000e+00])
 
 Matchers.tests.cpp:<line number>: PASSED:
   REQUIRE_THAT( nextafter(1.f, 2.f), WithinULP(1.f, 1) )
 with expansion:
-  1.0f is within 1 ULPs of 1.0f
+  1.0f is within 1 ULPs of 1.00000000e+00f ([9.99999940e-01, 1.00000012e+00])
 
 Matchers.tests.cpp:<line number>: PASSED:
-  REQUIRE_THAT( nextafter(1.f, 0.f), WithinULP(1.f, 1) )
+  REQUIRE_THAT( 0.f, WithinULP(nextafter(0.f, 1.f), 1) )
 with expansion:
-  1.0f is within 1 ULPs of 1.0f
+  0.0f is within 1 ULPs of 1.40129846e-45f ([0.00000000e+00, 2.80259693e-45])
 
 Matchers.tests.cpp:<line number>: PASSED:
-  REQUIRE_THAT( nextafter(1.f, 2.f), !WithinULP(1.f, 0) )
+  REQUIRE_THAT( 1.f, WithinULP(nextafter(1.f, 0.f), 1) )
 with expansion:
-  1.0f not is within 0 ULPs of 1.0f
+  1.0f is within 1 ULPs of 9.99999940e-01f ([9.99999881e-01, 1.00000000e+00])
 
 Matchers.tests.cpp:<line number>: PASSED:
-  REQUIRE_THAT( 1.f, WithinULP(1.f, 0) )
+  REQUIRE_THAT( 1.f, !WithinULP(nextafter(1.f, 2.f), 0) )
 with expansion:
-  1.0f is within 0 ULPs of 1.0f
+  1.0f not is within 0 ULPs of 1.00000012e+00f ([1.00000012e+00, 1.00000012e+
+  00])
 
 Matchers.tests.cpp:<line number>: PASSED:
-  REQUIRE_THAT( -0.f, WithinULP(0.f, 0) )
+  REQUIRE_THAT( 1.f, WithinULP(1.f, 0) )
 with expansion:
-  -0.0f is within 0 ULPs of 0.0f
+  1.0f is within 0 ULPs of 1.00000000e+00f ([1.00000000e+00, 1.00000000e+00])
 
 Matchers.tests.cpp:<line number>: PASSED:
-  REQUIRE_THAT( NAN, !WithinULP(NAN, 123) )
+  REQUIRE_THAT( -0.f, WithinULP(0.f, 0) )
 with expansion:
-  nanf not is within 123 ULPs of nanf
+  -0.0f is within 0 ULPs of 0.00000000e+00f ([0.00000000e+00, 0.00000000e+00])
 
 -------------------------------------------------------------------------------
 Floating point matchers: float
@@ -2866,17 +3444,19 @@ Matchers.tests.cpp:<line number>
 Matchers.tests.cpp:<line number>: PASSED:
   REQUIRE_THAT( 1.f, WithinAbs(1.f, 0.5) || WithinULP(1.f, 1) )
 with expansion:
-  1.0f ( is within 0.5 of 1.0 or is within 1 ULPs of 1.0f )
+  1.0f ( is within 0.5 of 1.0 or is within 1 ULPs of 1.00000000e+00f ([9.
+  99999940e-01, 1.00000012e+00]) )
 
 Matchers.tests.cpp:<line number>: PASSED:
   REQUIRE_THAT( 1.f, WithinAbs(2.f, 0.5) || WithinULP(1.f, 0) )
 with expansion:
-  1.0f ( is within 0.5 of 2.0 or is within 0 ULPs of 1.0f )
+  1.0f ( is within 0.5 of 2.0 or is within 0 ULPs of 1.00000000e+00f ([1.
+  00000000e+00, 1.00000000e+00]) )
 
 Matchers.tests.cpp:<line number>: PASSED:
-  REQUIRE_THAT( NAN, !(WithinAbs(NAN, 100) || WithinULP(NAN, 123)) )
+  REQUIRE_THAT( 0.0001f, WithinAbs(0.f, 0.001f) || WithinRel(0.f, 0.1f) )
 with expansion:
-  nanf not ( is within 100.0 of nan or is within 123 ULPs of nanf )
+  0.0001f ( is within 0.001 of 0.0 or and 0 are within 10% of each other )
 
 -------------------------------------------------------------------------------
 Floating point matchers: float
@@ -2895,7 +3475,16 @@ Matchers.tests.cpp:<line number>: PASSED:
   REQUIRE_NOTHROW( WithinULP(1.f, 0) )
 
 Matchers.tests.cpp:<line number>: PASSED:
-  REQUIRE_THROWS_AS( WithinULP(1.f, -1), std::domain_error )
+  REQUIRE_THROWS_AS( WithinULP(1.f, static_cast<uint64_t>(-1)), std::domain_error )
+
+Matchers.tests.cpp:<line number>: PASSED:
+  REQUIRE_NOTHROW( WithinRel(1.f, 0.f) )
+
+Matchers.tests.cpp:<line number>: PASSED:
+  REQUIRE_THROWS_AS( WithinRel(1.f, -0.2f), std::domain_error )
+
+Matchers.tests.cpp:<line number>: PASSED:
+  REQUIRE_THROWS_AS( WithinRel(1.f, 1.f), std::domain_error )
 
 -------------------------------------------------------------------------------
 Generators -- adapters
@@ -3272,6 +3861,45 @@ Generators.tests.cpp:<line number>: PASSED:
 with expansion:
   2 < 3
 
+-------------------------------------------------------------------------------
+Generators -- adapters
+  Chunking a generator into sized pieces
+  Chunk size of zero
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>: PASSED:
+  REQUIRE( chunk2.size() == 0 )
+with expansion:
+  0 == 0
+
+-------------------------------------------------------------------------------
+Generators -- adapters
+  Chunking a generator into sized pieces
+  Chunk size of zero
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>: PASSED:
+  REQUIRE( chunk2.size() == 0 )
+with expansion:
+  0 == 0
+
+-------------------------------------------------------------------------------
+Generators -- adapters
+  Chunking a generator into sized pieces
+  Chunk size of zero
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>: PASSED:
+  REQUIRE( chunk2.size() == 0 )
+with expansion:
+  0 == 0
+
 -------------------------------------------------------------------------------
 Generators -- adapters
   Chunking a generator into sized pieces
@@ -5138,6 +5766,125 @@ Condition.tests.cpp:<line number>: PASSED:
 with expansion:
   "hello" > "a"
 
+-------------------------------------------------------------------------------
+Our PCG implementation provides expected results for known seeds
+  Default seeded
+-------------------------------------------------------------------------------
+RandomNumberGeneration.tests.cpp:<line number>
+...............................................................................
+
+RandomNumberGeneration.tests.cpp:<line number>: PASSED:
+  REQUIRE( rng() == 0x<hex digits> )
+with expansion:
+  4242248763 (0x<hex digits>)
+  ==
+  4242248763 (0x<hex digits>)
+
+RandomNumberGeneration.tests.cpp:<line number>: PASSED:
+  REQUIRE( rng() == 0x<hex digits> )
+with expansion:
+  1867888929 (0x<hex digits>)
+  ==
+  1867888929 (0x<hex digits>)
+
+RandomNumberGeneration.tests.cpp:<line number>: PASSED:
+  REQUIRE( rng() == 0x<hex digits> )
+with expansion:
+  1276619030 (0x<hex digits>)
+  ==
+  1276619030 (0x<hex digits>)
+
+RandomNumberGeneration.tests.cpp:<line number>: PASSED:
+  REQUIRE( rng() == 0x<hex digits> )
+with expansion:
+  1911218783 (0x<hex digits>)
+  ==
+  1911218783 (0x<hex digits>)
+
+RandomNumberGeneration.tests.cpp:<line number>: PASSED:
+  REQUIRE( rng() == 0x<hex digits> )
+with expansion:
+  1827115164 (0x<hex digits>)
+  ==
+  1827115164 (0x<hex digits>)
+
+-------------------------------------------------------------------------------
+Our PCG implementation provides expected results for known seeds
+  Specific seed
+-------------------------------------------------------------------------------
+RandomNumberGeneration.tests.cpp:<line number>
+...............................................................................
+
+RandomNumberGeneration.tests.cpp:<line number>: PASSED:
+  REQUIRE( rng() == 0x<hex digits> )
+with expansion:
+  1472234645 (0x<hex digits>)
+  ==
+  1472234645 (0x<hex digits>)
+
+RandomNumberGeneration.tests.cpp:<line number>: PASSED:
+  REQUIRE( rng() == 0x<hex digits> )
+with expansion:
+  868832940 (0x<hex digits>)
+  ==
+  868832940 (0x<hex digits>)
+
+RandomNumberGeneration.tests.cpp:<line number>: PASSED:
+  REQUIRE( rng() == 0x<hex digits> )
+with expansion:
+  570883446 (0x<hex digits>)
+  ==
+  570883446 (0x<hex digits>)
+
+RandomNumberGeneration.tests.cpp:<line number>: PASSED:
+  REQUIRE( rng() == 0x<hex digits> )
+with expansion:
+  889299803 (0x<hex digits>)
+  ==
+  889299803 (0x<hex digits>)
+
+RandomNumberGeneration.tests.cpp:<line number>: PASSED:
+  REQUIRE( rng() == 0x<hex digits> )
+with expansion:
+  4261393167 (0x<hex digits>)
+  ==
+  4261393167 (0x<hex digits>)
+
+RandomNumberGeneration.tests.cpp:<line number>: PASSED:
+  REQUIRE( rng() == 0x<hex digits> )
+with expansion:
+  1472234645 (0x<hex digits>)
+  ==
+  1472234645 (0x<hex digits>)
+
+RandomNumberGeneration.tests.cpp:<line number>: PASSED:
+  REQUIRE( rng() == 0x<hex digits> )
+with expansion:
+  868832940 (0x<hex digits>)
+  ==
+  868832940 (0x<hex digits>)
+
+RandomNumberGeneration.tests.cpp:<line number>: PASSED:
+  REQUIRE( rng() == 0x<hex digits> )
+with expansion:
+  570883446 (0x<hex digits>)
+  ==
+  570883446 (0x<hex digits>)
+
+RandomNumberGeneration.tests.cpp:<line number>: PASSED:
+  REQUIRE( rng() == 0x<hex digits> )
+with expansion:
+  889299803 (0x<hex digits>)
+  ==
+  889299803 (0x<hex digits>)
+
+RandomNumberGeneration.tests.cpp:<line number>: PASSED:
+  REQUIRE( rng() == 0x<hex digits> )
+with expansion:
+  4261393167 (0x<hex digits>)
+  ==
+  4261393167 (0x<hex digits>)
+
 -------------------------------------------------------------------------------
 Output from all sections is reported
   one
@@ -6052,6 +6799,70 @@ CmdLine.tests.cpp:<line number>: PASSED:
 with expansion:
   true == true
 
+-------------------------------------------------------------------------------
+Parse test names and tags
+  Leading and trailing spaces in test spec
+-------------------------------------------------------------------------------
+CmdLine.tests.cpp:<line number>
+...............................................................................
+
+CmdLine.tests.cpp:<line number>: PASSED:
+  CHECK( spec.matches( fakeTestCase( "  aardvark " ) ) )
+with expansion:
+  true
+
+CmdLine.tests.cpp:<line number>: PASSED:
+  CHECK( spec.matches( fakeTestCase( "  aardvark" ) ) )
+with expansion:
+  true
+
+CmdLine.tests.cpp:<line number>: PASSED:
+  CHECK( spec.matches( fakeTestCase( " aardvark " ) ) )
+with expansion:
+  true
+
+CmdLine.tests.cpp:<line number>: PASSED:
+  CHECK( spec.matches( fakeTestCase( "aardvark " ) ) )
+with expansion:
+  true
+
+CmdLine.tests.cpp:<line number>: PASSED:
+  CHECK( spec.matches( fakeTestCase( "aardvark" ) ) )
+with expansion:
+  true
+
+-------------------------------------------------------------------------------
+Parse test names and tags
+  Leading and trailing spaces in test name
+-------------------------------------------------------------------------------
+CmdLine.tests.cpp:<line number>
+...............................................................................
+
+CmdLine.tests.cpp:<line number>: PASSED:
+  CHECK( spec.matches( fakeTestCase( "  aardvark " ) ) )
+with expansion:
+  true
+
+CmdLine.tests.cpp:<line number>: PASSED:
+  CHECK( spec.matches( fakeTestCase( "  aardvark" ) ) )
+with expansion:
+  true
+
+CmdLine.tests.cpp:<line number>: PASSED:
+  CHECK( spec.matches( fakeTestCase( " aardvark " ) ) )
+with expansion:
+  true
+
+CmdLine.tests.cpp:<line number>: PASSED:
+  CHECK( spec.matches( fakeTestCase( "aardvark " ) ) )
+with expansion:
+  true
+
+CmdLine.tests.cpp:<line number>: PASSED:
+  CHECK( spec.matches( fakeTestCase( "aardvark" ) ) )
+with expansion:
+  true
+
 -------------------------------------------------------------------------------
 Pointers can be compared to null
 -------------------------------------------------------------------------------
@@ -6098,6 +6909,40 @@ Condition.tests.cpp:<line number>: PASSED:
 with expansion:
   0 != 0x<hex digits>
 
+-------------------------------------------------------------------------------
+Precision of floating point stringification can be set
+  Floats
+-------------------------------------------------------------------------------
+ToStringGeneral.tests.cpp:<line number>
+...............................................................................
+
+ToStringGeneral.tests.cpp:<line number>: PASSED:
+  CHECK( str1.size() == 3 + 5 )
+with expansion:
+  8 == 8
+
+ToStringGeneral.tests.cpp:<line number>: PASSED:
+  REQUIRE( str2.size() == 3 + 10 )
+with expansion:
+  13 == 13
+
+-------------------------------------------------------------------------------
+Precision of floating point stringification can be set
+  Double
+-------------------------------------------------------------------------------
+ToStringGeneral.tests.cpp:<line number>
+...............................................................................
+
+ToStringGeneral.tests.cpp:<line number>: PASSED:
+  CHECK( str1.size() == 2 + 5 )
+with expansion:
+  7 == 7
+
+ToStringGeneral.tests.cpp:<line number>: PASSED:
+  REQUIRE( str2.size() == 2 + 15 )
+with expansion:
+  17 == 17
+
 -------------------------------------------------------------------------------
 Predicate matcher can accept const char*
 -------------------------------------------------------------------------------
@@ -6621,48 +7466,120 @@ with expansion:
   contains: "colour mode must be one of"
 
 -------------------------------------------------------------------------------
-Product with differing arities - std::tuple<int, double, float>
+Process can be configured on command line
+  Benchmark options
+  samples
 -------------------------------------------------------------------------------
-Misc.tests.cpp:<line number>
+CmdLine.tests.cpp:<line number>
 ...............................................................................
 
-Misc.tests.cpp:<line number>: PASSED:
-  REQUIRE( std::tuple_size<TestType>::value >= 1 )
+CmdLine.tests.cpp:<line number>: PASSED:
+  CHECK( cli.parse({ "test", "--benchmark-samples=200" }) )
 with expansion:
-  3 >= 1
+  {?}
+
+CmdLine.tests.cpp:<line number>: PASSED:
+  REQUIRE( config.benchmarkSamples == 200 )
+with expansion:
+  200 == 200
 
 -------------------------------------------------------------------------------
-Product with differing arities - std::tuple<int, double>
+Process can be configured on command line
+  Benchmark options
+  resamples
 -------------------------------------------------------------------------------
-Misc.tests.cpp:<line number>
+CmdLine.tests.cpp:<line number>
 ...............................................................................
 
-Misc.tests.cpp:<line number>: PASSED:
-  REQUIRE( std::tuple_size<TestType>::value >= 1 )
+CmdLine.tests.cpp:<line number>: PASSED:
+  CHECK( cli.parse({ "test", "--benchmark-resamples=20000" }) )
 with expansion:
-  2 >= 1
+  {?}
+
+CmdLine.tests.cpp:<line number>: PASSED:
+  REQUIRE( config.benchmarkResamples == 20000 )
+with expansion:
+  20000 (0x<hex digits>) == 20000 (0x<hex digits>)
 
 -------------------------------------------------------------------------------
-Product with differing arities - std::tuple<int>
+Process can be configured on command line
+  Benchmark options
+  resamples
 -------------------------------------------------------------------------------
-Misc.tests.cpp:<line number>
+CmdLine.tests.cpp:<line number>
 ...............................................................................
 
-Misc.tests.cpp:<line number>: PASSED:
-  REQUIRE( std::tuple_size<TestType>::value >= 1 )
+CmdLine.tests.cpp:<line number>: PASSED:
+  CHECK( cli.parse({ "test", "--benchmark-confidence-interval=0.99" }) )
 with expansion:
-  1 >= 1
+  {?}
+
+CmdLine.tests.cpp:<line number>: PASSED:
+  REQUIRE( config.benchmarkConfidenceInterval == Catch::Detail::Approx(0.99) )
+with expansion:
+  0.99 == Approx( 0.99 )
 
 -------------------------------------------------------------------------------
-Reconstruction should be based on stringification: #914
+Process can be configured on command line
+  Benchmark options
+  resamples
 -------------------------------------------------------------------------------
-Decomposition.tests.cpp:<line number>
+CmdLine.tests.cpp:<line number>
 ...............................................................................
 
-Decomposition.tests.cpp:<line number>: FAILED:
-  CHECK( truthy(false) )
+CmdLine.tests.cpp:<line number>: PASSED:
+  CHECK( cli.parse({ "test", "--benchmark-no-analysis" }) )
 with expansion:
-  Hey, its truthy!
+  {?}
+
+CmdLine.tests.cpp:<line number>: PASSED:
+  REQUIRE( config.benchmarkNoAnalysis )
+with expansion:
+  true
+
+-------------------------------------------------------------------------------
+Product with differing arities - std::tuple<int, double, float>
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( std::tuple_size<TestType>::value >= 1 )
+with expansion:
+  3 >= 1
+
+-------------------------------------------------------------------------------
+Product with differing arities - std::tuple<int, double>
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( std::tuple_size<TestType>::value >= 1 )
+with expansion:
+  2 >= 1
+
+-------------------------------------------------------------------------------
+Product with differing arities - std::tuple<int>
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( std::tuple_size<TestType>::value >= 1 )
+with expansion:
+  1 >= 1
+
+-------------------------------------------------------------------------------
+Reconstruction should be based on stringification: #914
+-------------------------------------------------------------------------------
+Decomposition.tests.cpp:<line number>
+...............................................................................
+
+Decomposition.tests.cpp:<line number>: FAILED:
+  CHECK( truthy(false) )
+with expansion:
+  Hey, its truthy!
 
 -------------------------------------------------------------------------------
 Regex string matcher
@@ -6934,11 +7851,6 @@ Approx.tests.cpp:<line number>: PASSED:
 with expansion:
   Approx( 1.23 ) != 1.24
 
-Approx.tests.cpp:<line number>: PASSED:
-  REQUIRE( INFINITY == Approx(INFINITY) )
-with expansion:
-  inff == Approx( inf )
-
 Message from section one
 -------------------------------------------------------------------------------
 Standard output from all sections is reported
@@ -7158,11 +8070,6 @@ String.tests.cpp:<line number>: PASSED:
 with expansion:
   false == false
 
-String.tests.cpp:<line number>: PASSED:
-  REQUIRE( isSubstring( original ) == false )
-with expansion:
-  false == false
-
 String.tests.cpp:<line number>: PASSED:
   REQUIRE( isOwned( original ) )
 with expansion:
@@ -7225,19 +8132,33 @@ with expansion:
   "hello" != "hello world!"
 
 String.tests.cpp:<line number>: PASSED:
-  REQUIRE( isSubstring( ss ) == false )
+  REQUIRE( isOwned( ss ) )
+with expansion:
+  true
+
+-------------------------------------------------------------------------------
+StringRef
+  Substrings
+  c_str() causes copy
+  Self-assignment after substring
+-------------------------------------------------------------------------------
+String.tests.cpp:<line number>
+...............................................................................
+
+String.tests.cpp:<line number>: PASSED:
+  REQUIRE( isOwned(ss) == false )
 with expansion:
   false == false
 
 String.tests.cpp:<line number>: PASSED:
-  REQUIRE( isOwned( ss ) )
+  REQUIRE( ss == "hello" )
 with expansion:
-  true
+  hello == "hello"
 
 String.tests.cpp:<line number>: PASSED:
-  REQUIRE( ss.currentData() != s.currentData() )
+  REQUIRE( rawChars == ss.currentData() )
 with expansion:
-  "hello" != "hello world!"
+  "hello world!" == "hello world!"
 
 -------------------------------------------------------------------------------
 StringRef
@@ -7283,6 +8204,19 @@ String.tests.cpp:<line number>: PASSED:
 with expansion:
   "hello world!" != "hello"
 
+-------------------------------------------------------------------------------
+StringRef
+  Substrings
+  Past the end substring
+-------------------------------------------------------------------------------
+String.tests.cpp:<line number>
+...............................................................................
+
+String.tests.cpp:<line number>: PASSED:
+  REQUIRE( s.substr(s.size() + 1, 123).empty() )
+with expansion:
+  true
+
 -------------------------------------------------------------------------------
 StringRef
   Comparisons
@@ -7354,24 +8288,6 @@ String.tests.cpp:<line number>: PASSED:
 with expansion:
   17 == 17
 
--------------------------------------------------------------------------------
-StringRef
-  to std::string
-  implicitly constructed
--------------------------------------------------------------------------------
-String.tests.cpp:<line number>
-...............................................................................
-
-String.tests.cpp:<line number>: PASSED:
-  REQUIRE( stdStr == "a stringref" )
-with expansion:
-  "a stringref" == "a stringref"
-
-String.tests.cpp:<line number>: PASSED:
-  REQUIRE( stdStr.size() == sr.size() )
-with expansion:
-  11 == 11
-
 -------------------------------------------------------------------------------
 StringRef
   to std::string
@@ -7408,28 +8324,6 @@ String.tests.cpp:<line number>: PASSED:
 with expansion:
   11 == 11
 
--------------------------------------------------------------------------------
-StringRef
-  Counting utf-8 codepoints
--------------------------------------------------------------------------------
-String.tests.cpp:<line number>
-...............................................................................
-
-String.tests.cpp:<line number>: PASSED:
-  REQUIRE( ascii.numberOfCharacters() == ascii.size() )
-with expansion:
-  39 == 39
-
-String.tests.cpp:<line number>: PASSED:
-  REQUIRE( simpleu8.numberOfCharacters() == 30 )
-with expansion:
-  30 == 30
-
-String.tests.cpp:<line number>: PASSED:
-  REQUIRE( emojis.numberOfCharacters() == 9 )
-with expansion:
-  9 == 9
-
 -------------------------------------------------------------------------------
 Stringifying std::chrono::duration helpers
 -------------------------------------------------------------------------------
@@ -7557,6 +8451,123 @@ Tag.tests.cpp:<line number>: PASSED:
 Tag.tests.cpp:<line number>: PASSED:
   CHECK_THROWS( registry.add( "[@no square bracket at end", "", Catch::SourceLineInfo( "file", 3 ) ) )
 
+-------------------------------------------------------------------------------
+Template test case method with test types specified inside std::tuple - MyTypes
+- 0
+-------------------------------------------------------------------------------
+Class.tests.cpp:<line number>
+...............................................................................
+
+Class.tests.cpp:<line number>: PASSED:
+  REQUIRE( Template_Fixture<TestType>::m_a == 1 )
+with expansion:
+  1 == 1
+
+-------------------------------------------------------------------------------
+Template test case method with test types specified inside std::tuple - MyTypes
+- 1
+-------------------------------------------------------------------------------
+Class.tests.cpp:<line number>
+...............................................................................
+
+Class.tests.cpp:<line number>: PASSED:
+  REQUIRE( Template_Fixture<TestType>::m_a == 1 )
+with expansion:
+  1 == 1
+
+-------------------------------------------------------------------------------
+Template test case method with test types specified inside std::tuple - MyTypes
+- 2
+-------------------------------------------------------------------------------
+Class.tests.cpp:<line number>
+...............................................................................
+
+Class.tests.cpp:<line number>: PASSED:
+  REQUIRE( Template_Fixture<TestType>::m_a == 1 )
+with expansion:
+  1.0 == 1
+
+-------------------------------------------------------------------------------
+Template test case with test types specified inside non-copyable and non-
+movable std::tuple - NonCopyableAndNonMovableTypes - 0
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( sizeof(TestType) > 0 )
+with expansion:
+  1 > 0
+
+-------------------------------------------------------------------------------
+Template test case with test types specified inside non-copyable and non-
+movable std::tuple - NonCopyableAndNonMovableTypes - 1
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( sizeof(TestType) > 0 )
+with expansion:
+  4 > 0
+
+-------------------------------------------------------------------------------
+Template test case with test types specified inside non-default-constructible
+std::tuple - MyNonDefaultConstructibleTypes - 0
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( sizeof(TestType) > 0 )
+with expansion:
+  1 > 0
+
+-------------------------------------------------------------------------------
+Template test case with test types specified inside non-default-constructible
+std::tuple - MyNonDefaultConstructibleTypes - 1
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( sizeof(TestType) > 0 )
+with expansion:
+  4 > 0
+
+-------------------------------------------------------------------------------
+Template test case with test types specified inside std::tuple - MyTypes - 0
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( sizeof(TestType) > 0 )
+with expansion:
+  4 > 0
+
+-------------------------------------------------------------------------------
+Template test case with test types specified inside std::tuple - MyTypes - 1
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( sizeof(TestType) > 0 )
+with expansion:
+  1 > 0
+
+-------------------------------------------------------------------------------
+Template test case with test types specified inside std::tuple - MyTypes - 2
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( sizeof(TestType) > 0 )
+with expansion:
+  4 > 0
+
 -------------------------------------------------------------------------------
 TemplateTest: vectors can be sized and resized - float
 -------------------------------------------------------------------------------
@@ -7716,43 +8727,623 @@ with expansion:
 Misc.tests.cpp:<line number>: PASSED:
   REQUIRE( v.capacity() >= 5 )
 with expansion:
-  5 >= 5
+  5 >= 5
+
+-------------------------------------------------------------------------------
+TemplateTest: vectors can be sized and resized - int
+  resizing bigger changes size and capacity
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.size() == 10 )
+with expansion:
+  10 == 10
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.capacity() >= 10 )
+with expansion:
+  10 >= 10
+
+-------------------------------------------------------------------------------
+TemplateTest: vectors can be sized and resized - int
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.size() == 5 )
+with expansion:
+  5 == 5
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.capacity() >= 5 )
+with expansion:
+  5 >= 5
+
+-------------------------------------------------------------------------------
+TemplateTest: vectors can be sized and resized - int
+  resizing smaller changes size but not capacity
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.size() == 0 )
+with expansion:
+  0 == 0
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.capacity() >= 5 )
+with expansion:
+  5 >= 5
+
+-------------------------------------------------------------------------------
+TemplateTest: vectors can be sized and resized - int
+  resizing smaller changes size but not capacity
+  We can use the 'swap trick' to reset the capacity
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.capacity() == 0 )
+with expansion:
+  0 == 0
+
+-------------------------------------------------------------------------------
+TemplateTest: vectors can be sized and resized - int
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.size() == 5 )
+with expansion:
+  5 == 5
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.capacity() >= 5 )
+with expansion:
+  5 >= 5
+
+-------------------------------------------------------------------------------
+TemplateTest: vectors can be sized and resized - int
+  reserving bigger changes capacity but not size
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.size() == 5 )
+with expansion:
+  5 == 5
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.capacity() >= 10 )
+with expansion:
+  10 >= 10
+
+-------------------------------------------------------------------------------
+TemplateTest: vectors can be sized and resized - int
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.size() == 5 )
+with expansion:
+  5 == 5
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.capacity() >= 5 )
+with expansion:
+  5 >= 5
+
+-------------------------------------------------------------------------------
+TemplateTest: vectors can be sized and resized - int
+  reserving smaller does not change size or capacity
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.size() == 5 )
+with expansion:
+  5 == 5
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.capacity() >= 5 )
+with expansion:
+  5 >= 5
+
+-------------------------------------------------------------------------------
+TemplateTest: vectors can be sized and resized - std::string
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.size() == 5 )
+with expansion:
+  5 == 5
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.capacity() >= 5 )
+with expansion:
+  5 >= 5
+
+-------------------------------------------------------------------------------
+TemplateTest: vectors can be sized and resized - std::string
+  resizing bigger changes size and capacity
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.size() == 10 )
+with expansion:
+  10 == 10
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.capacity() >= 10 )
+with expansion:
+  10 >= 10
+
+-------------------------------------------------------------------------------
+TemplateTest: vectors can be sized and resized - std::string
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.size() == 5 )
+with expansion:
+  5 == 5
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.capacity() >= 5 )
+with expansion:
+  5 >= 5
+
+-------------------------------------------------------------------------------
+TemplateTest: vectors can be sized and resized - std::string
+  resizing smaller changes size but not capacity
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.size() == 0 )
+with expansion:
+  0 == 0
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.capacity() >= 5 )
+with expansion:
+  5 >= 5
+
+-------------------------------------------------------------------------------
+TemplateTest: vectors can be sized and resized - std::string
+  resizing smaller changes size but not capacity
+  We can use the 'swap trick' to reset the capacity
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.capacity() == 0 )
+with expansion:
+  0 == 0
+
+-------------------------------------------------------------------------------
+TemplateTest: vectors can be sized and resized - std::string
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.size() == 5 )
+with expansion:
+  5 == 5
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.capacity() >= 5 )
+with expansion:
+  5 >= 5
+
+-------------------------------------------------------------------------------
+TemplateTest: vectors can be sized and resized - std::string
+  reserving bigger changes capacity but not size
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.size() == 5 )
+with expansion:
+  5 == 5
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.capacity() >= 10 )
+with expansion:
+  10 >= 10
+
+-------------------------------------------------------------------------------
+TemplateTest: vectors can be sized and resized - std::string
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.size() == 5 )
+with expansion:
+  5 == 5
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.capacity() >= 5 )
+with expansion:
+  5 >= 5
+
+-------------------------------------------------------------------------------
+TemplateTest: vectors can be sized and resized - std::string
+  reserving smaller does not change size or capacity
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.size() == 5 )
+with expansion:
+  5 == 5
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.capacity() >= 5 )
+with expansion:
+  5 >= 5
+
+-------------------------------------------------------------------------------
+TemplateTest: vectors can be sized and resized - std::tuple<int,float>
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.size() == 5 )
+with expansion:
+  5 == 5
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.capacity() >= 5 )
+with expansion:
+  5 >= 5
+
+-------------------------------------------------------------------------------
+TemplateTest: vectors can be sized and resized - std::tuple<int,float>
+  resizing bigger changes size and capacity
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.size() == 10 )
+with expansion:
+  10 == 10
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.capacity() >= 10 )
+with expansion:
+  10 >= 10
+
+-------------------------------------------------------------------------------
+TemplateTest: vectors can be sized and resized - std::tuple<int,float>
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.size() == 5 )
+with expansion:
+  5 == 5
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.capacity() >= 5 )
+with expansion:
+  5 >= 5
+
+-------------------------------------------------------------------------------
+TemplateTest: vectors can be sized and resized - std::tuple<int,float>
+  resizing smaller changes size but not capacity
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.size() == 0 )
+with expansion:
+  0 == 0
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.capacity() >= 5 )
+with expansion:
+  5 >= 5
+
+-------------------------------------------------------------------------------
+TemplateTest: vectors can be sized and resized - std::tuple<int,float>
+  resizing smaller changes size but not capacity
+  We can use the 'swap trick' to reset the capacity
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.capacity() == 0 )
+with expansion:
+  0 == 0
+
+-------------------------------------------------------------------------------
+TemplateTest: vectors can be sized and resized - std::tuple<int,float>
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.size() == 5 )
+with expansion:
+  5 == 5
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.capacity() >= 5 )
+with expansion:
+  5 >= 5
+
+-------------------------------------------------------------------------------
+TemplateTest: vectors can be sized and resized - std::tuple<int,float>
+  reserving bigger changes capacity but not size
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.size() == 5 )
+with expansion:
+  5 == 5
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.capacity() >= 10 )
+with expansion:
+  10 >= 10
+
+-------------------------------------------------------------------------------
+TemplateTest: vectors can be sized and resized - std::tuple<int,float>
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.size() == 5 )
+with expansion:
+  5 == 5
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.capacity() >= 5 )
+with expansion:
+  5 >= 5
+
+-------------------------------------------------------------------------------
+TemplateTest: vectors can be sized and resized - std::tuple<int,float>
+  reserving smaller does not change size or capacity
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.size() == 5 )
+with expansion:
+  5 == 5
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.capacity() >= 5 )
+with expansion:
+  5 >= 5
+
+-------------------------------------------------------------------------------
+TemplateTestSig: vectors can be sized and resized - (std::tuple<int, float>), 6
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.size() == V )
+with expansion:
+  6 == 6
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.capacity() >= V )
+with expansion:
+  6 >= 6
+
+-------------------------------------------------------------------------------
+TemplateTestSig: vectors can be sized and resized - (std::tuple<int, float>), 6
+  resizing bigger changes size and capacity
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.size() == 2 * V )
+with expansion:
+  12 == 12
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.capacity() >= 2 * V )
+with expansion:
+  12 >= 12
+
+-------------------------------------------------------------------------------
+TemplateTestSig: vectors can be sized and resized - (std::tuple<int, float>), 6
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.size() == V )
+with expansion:
+  6 == 6
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.capacity() >= V )
+with expansion:
+  6 >= 6
+
+-------------------------------------------------------------------------------
+TemplateTestSig: vectors can be sized and resized - (std::tuple<int, float>), 6
+  resizing smaller changes size but not capacity
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.size() == 0 )
+with expansion:
+  0 == 0
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.capacity() >= V )
+with expansion:
+  6 >= 6
+
+-------------------------------------------------------------------------------
+TemplateTestSig: vectors can be sized and resized - (std::tuple<int, float>), 6
+  resizing smaller changes size but not capacity
+  We can use the 'swap trick' to reset the capacity
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.capacity() == 0 )
+with expansion:
+  0 == 0
+
+-------------------------------------------------------------------------------
+TemplateTestSig: vectors can be sized and resized - (std::tuple<int, float>), 6
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.size() == V )
+with expansion:
+  6 == 6
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.capacity() >= V )
+with expansion:
+  6 >= 6
+
+-------------------------------------------------------------------------------
+TemplateTestSig: vectors can be sized and resized - (std::tuple<int, float>), 6
+  reserving bigger changes capacity but not size
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.size() == V )
+with expansion:
+  6 == 6
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.capacity() >= 2 * V )
+with expansion:
+  12 >= 12
+
+-------------------------------------------------------------------------------
+TemplateTestSig: vectors can be sized and resized - (std::tuple<int, float>), 6
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.size() == V )
+with expansion:
+  6 == 6
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.capacity() >= V )
+with expansion:
+  6 >= 6
+
+-------------------------------------------------------------------------------
+TemplateTestSig: vectors can be sized and resized - (std::tuple<int, float>), 6
+  reserving smaller does not change size or capacity
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.size() == V )
+with expansion:
+  6 == 6
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.capacity() >= V )
+with expansion:
+  6 >= 6
+
+-------------------------------------------------------------------------------
+TemplateTestSig: vectors can be sized and resized - float,4
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.size() == V )
+with expansion:
+  4 == 4
+
+Misc.tests.cpp:<line number>: PASSED:
+  REQUIRE( v.capacity() >= V )
+with expansion:
+  4 >= 4
 
 -------------------------------------------------------------------------------
-TemplateTest: vectors can be sized and resized - int
+TemplateTestSig: vectors can be sized and resized - float,4
   resizing bigger changes size and capacity
 -------------------------------------------------------------------------------
 Misc.tests.cpp:<line number>
 ...............................................................................
 
 Misc.tests.cpp:<line number>: PASSED:
-  REQUIRE( v.size() == 10 )
+  REQUIRE( v.size() == 2 * V )
 with expansion:
-  10 == 10
+  8 == 8
 
 Misc.tests.cpp:<line number>: PASSED:
-  REQUIRE( v.capacity() >= 10 )
+  REQUIRE( v.capacity() >= 2 * V )
 with expansion:
-  10 >= 10
+  8 >= 8
 
 -------------------------------------------------------------------------------
-TemplateTest: vectors can be sized and resized - int
+TemplateTestSig: vectors can be sized and resized - float,4
 -------------------------------------------------------------------------------
 Misc.tests.cpp:<line number>
 ...............................................................................
 
 Misc.tests.cpp:<line number>: PASSED:
-  REQUIRE( v.size() == 5 )
+  REQUIRE( v.size() == V )
 with expansion:
-  5 == 5
+  4 == 4
 
 Misc.tests.cpp:<line number>: PASSED:
-  REQUIRE( v.capacity() >= 5 )
+  REQUIRE( v.capacity() >= V )
 with expansion:
-  5 >= 5
+  4 >= 4
 
 -------------------------------------------------------------------------------
-TemplateTest: vectors can be sized and resized - int
+TemplateTestSig: vectors can be sized and resized - float,4
   resizing smaller changes size but not capacity
 -------------------------------------------------------------------------------
 Misc.tests.cpp:<line number>
@@ -7764,12 +9355,12 @@ with expansion:
   0 == 0
 
 Misc.tests.cpp:<line number>: PASSED:
-  REQUIRE( v.capacity() >= 5 )
+  REQUIRE( v.capacity() >= V )
 with expansion:
-  5 >= 5
+  4 >= 4
 
 -------------------------------------------------------------------------------
-TemplateTest: vectors can be sized and resized - int
+TemplateTestSig: vectors can be sized and resized - float,4
   resizing smaller changes size but not capacity
   We can use the 'swap trick' to reset the capacity
 -------------------------------------------------------------------------------
@@ -7782,122 +9373,122 @@ with expansion:
   0 == 0
 
 -------------------------------------------------------------------------------
-TemplateTest: vectors can be sized and resized - int
+TemplateTestSig: vectors can be sized and resized - float,4
 -------------------------------------------------------------------------------
 Misc.tests.cpp:<line number>
 ...............................................................................
 
 Misc.tests.cpp:<line number>: PASSED:
-  REQUIRE( v.size() == 5 )
+  REQUIRE( v.size() == V )
 with expansion:
-  5 == 5
+  4 == 4
 
 Misc.tests.cpp:<line number>: PASSED:
-  REQUIRE( v.capacity() >= 5 )
+  REQUIRE( v.capacity() >= V )
 with expansion:
-  5 >= 5
+  4 >= 4
 
 -------------------------------------------------------------------------------
-TemplateTest: vectors can be sized and resized - int
+TemplateTestSig: vectors can be sized and resized - float,4
   reserving bigger changes capacity but not size
 -------------------------------------------------------------------------------
 Misc.tests.cpp:<line number>
 ...............................................................................
 
 Misc.tests.cpp:<line number>: PASSED:
-  REQUIRE( v.size() == 5 )
+  REQUIRE( v.size() == V )
 with expansion:
-  5 == 5
+  4 == 4
 
 Misc.tests.cpp:<line number>: PASSED:
-  REQUIRE( v.capacity() >= 10 )
+  REQUIRE( v.capacity() >= 2 * V )
 with expansion:
-  10 >= 10
+  8 >= 8
 
 -------------------------------------------------------------------------------
-TemplateTest: vectors can be sized and resized - int
+TemplateTestSig: vectors can be sized and resized - float,4
 -------------------------------------------------------------------------------
 Misc.tests.cpp:<line number>
 ...............................................................................
 
 Misc.tests.cpp:<line number>: PASSED:
-  REQUIRE( v.size() == 5 )
+  REQUIRE( v.size() == V )
 with expansion:
-  5 == 5
+  4 == 4
 
 Misc.tests.cpp:<line number>: PASSED:
-  REQUIRE( v.capacity() >= 5 )
+  REQUIRE( v.capacity() >= V )
 with expansion:
-  5 >= 5
+  4 >= 4
 
 -------------------------------------------------------------------------------
-TemplateTest: vectors can be sized and resized - int
+TemplateTestSig: vectors can be sized and resized - float,4
   reserving smaller does not change size or capacity
 -------------------------------------------------------------------------------
 Misc.tests.cpp:<line number>
 ...............................................................................
 
 Misc.tests.cpp:<line number>: PASSED:
-  REQUIRE( v.size() == 5 )
+  REQUIRE( v.size() == V )
 with expansion:
-  5 == 5
+  4 == 4
 
 Misc.tests.cpp:<line number>: PASSED:
-  REQUIRE( v.capacity() >= 5 )
+  REQUIRE( v.capacity() >= V )
 with expansion:
-  5 >= 5
+  4 >= 4
 
 -------------------------------------------------------------------------------
-TemplateTest: vectors can be sized and resized - std::string
+TemplateTestSig: vectors can be sized and resized - int,5
 -------------------------------------------------------------------------------
 Misc.tests.cpp:<line number>
 ...............................................................................
 
 Misc.tests.cpp:<line number>: PASSED:
-  REQUIRE( v.size() == 5 )
+  REQUIRE( v.size() == V )
 with expansion:
   5 == 5
 
 Misc.tests.cpp:<line number>: PASSED:
-  REQUIRE( v.capacity() >= 5 )
+  REQUIRE( v.capacity() >= V )
 with expansion:
   5 >= 5
 
 -------------------------------------------------------------------------------
-TemplateTest: vectors can be sized and resized - std::string
+TemplateTestSig: vectors can be sized and resized - int,5
   resizing bigger changes size and capacity
 -------------------------------------------------------------------------------
 Misc.tests.cpp:<line number>
 ...............................................................................
 
 Misc.tests.cpp:<line number>: PASSED:
-  REQUIRE( v.size() == 10 )
+  REQUIRE( v.size() == 2 * V )
 with expansion:
   10 == 10
 
 Misc.tests.cpp:<line number>: PASSED:
-  REQUIRE( v.capacity() >= 10 )
+  REQUIRE( v.capacity() >= 2 * V )
 with expansion:
   10 >= 10
 
 -------------------------------------------------------------------------------
-TemplateTest: vectors can be sized and resized - std::string
+TemplateTestSig: vectors can be sized and resized - int,5
 -------------------------------------------------------------------------------
 Misc.tests.cpp:<line number>
 ...............................................................................
 
 Misc.tests.cpp:<line number>: PASSED:
-  REQUIRE( v.size() == 5 )
+  REQUIRE( v.size() == V )
 with expansion:
   5 == 5
 
 Misc.tests.cpp:<line number>: PASSED:
-  REQUIRE( v.capacity() >= 5 )
+  REQUIRE( v.capacity() >= V )
 with expansion:
   5 >= 5
 
 -------------------------------------------------------------------------------
-TemplateTest: vectors can be sized and resized - std::string
+TemplateTestSig: vectors can be sized and resized - int,5
   resizing smaller changes size but not capacity
 -------------------------------------------------------------------------------
 Misc.tests.cpp:<line number>
@@ -7909,12 +9500,12 @@ with expansion:
   0 == 0
 
 Misc.tests.cpp:<line number>: PASSED:
-  REQUIRE( v.capacity() >= 5 )
+  REQUIRE( v.capacity() >= V )
 with expansion:
   5 >= 5
 
 -------------------------------------------------------------------------------
-TemplateTest: vectors can be sized and resized - std::string
+TemplateTestSig: vectors can be sized and resized - int,5
   resizing smaller changes size but not capacity
   We can use the 'swap trick' to reset the capacity
 -------------------------------------------------------------------------------
@@ -7927,122 +9518,122 @@ with expansion:
   0 == 0
 
 -------------------------------------------------------------------------------
-TemplateTest: vectors can be sized and resized - std::string
+TemplateTestSig: vectors can be sized and resized - int,5
 -------------------------------------------------------------------------------
 Misc.tests.cpp:<line number>
 ...............................................................................
 
 Misc.tests.cpp:<line number>: PASSED:
-  REQUIRE( v.size() == 5 )
+  REQUIRE( v.size() == V )
 with expansion:
   5 == 5
 
 Misc.tests.cpp:<line number>: PASSED:
-  REQUIRE( v.capacity() >= 5 )
+  REQUIRE( v.capacity() >= V )
 with expansion:
   5 >= 5
 
 -------------------------------------------------------------------------------
-TemplateTest: vectors can be sized and resized - std::string
+TemplateTestSig: vectors can be sized and resized - int,5
   reserving bigger changes capacity but not size
 -------------------------------------------------------------------------------
 Misc.tests.cpp:<line number>
 ...............................................................................
 
 Misc.tests.cpp:<line number>: PASSED:
-  REQUIRE( v.size() == 5 )
+  REQUIRE( v.size() == V )
 with expansion:
   5 == 5
 
 Misc.tests.cpp:<line number>: PASSED:
-  REQUIRE( v.capacity() >= 10 )
+  REQUIRE( v.capacity() >= 2 * V )
 with expansion:
   10 >= 10
 
 -------------------------------------------------------------------------------
-TemplateTest: vectors can be sized and resized - std::string
+TemplateTestSig: vectors can be sized and resized - int,5
 -------------------------------------------------------------------------------
 Misc.tests.cpp:<line number>
 ...............................................................................
 
 Misc.tests.cpp:<line number>: PASSED:
-  REQUIRE( v.size() == 5 )
+  REQUIRE( v.size() == V )
 with expansion:
   5 == 5
 
 Misc.tests.cpp:<line number>: PASSED:
-  REQUIRE( v.capacity() >= 5 )
+  REQUIRE( v.capacity() >= V )
 with expansion:
   5 >= 5
 
 -------------------------------------------------------------------------------
-TemplateTest: vectors can be sized and resized - std::string
+TemplateTestSig: vectors can be sized and resized - int,5
   reserving smaller does not change size or capacity
 -------------------------------------------------------------------------------
 Misc.tests.cpp:<line number>
 ...............................................................................
 
 Misc.tests.cpp:<line number>: PASSED:
-  REQUIRE( v.size() == 5 )
+  REQUIRE( v.size() == V )
 with expansion:
   5 == 5
 
 Misc.tests.cpp:<line number>: PASSED:
-  REQUIRE( v.capacity() >= 5 )
+  REQUIRE( v.capacity() >= V )
 with expansion:
   5 >= 5
 
 -------------------------------------------------------------------------------
-TemplateTest: vectors can be sized and resized - std::tuple<int,float>
+TemplateTestSig: vectors can be sized and resized - std::string,15
 -------------------------------------------------------------------------------
 Misc.tests.cpp:<line number>
 ...............................................................................
 
 Misc.tests.cpp:<line number>: PASSED:
-  REQUIRE( v.size() == 5 )
+  REQUIRE( v.size() == V )
 with expansion:
-  5 == 5
+  15 == 15
 
 Misc.tests.cpp:<line number>: PASSED:
-  REQUIRE( v.capacity() >= 5 )
+  REQUIRE( v.capacity() >= V )
 with expansion:
-  5 >= 5
+  15 >= 15
 
 -------------------------------------------------------------------------------
-TemplateTest: vectors can be sized and resized - std::tuple<int,float>
+TemplateTestSig: vectors can be sized and resized - std::string,15
   resizing bigger changes size and capacity
 -------------------------------------------------------------------------------
 Misc.tests.cpp:<line number>
 ...............................................................................
 
 Misc.tests.cpp:<line number>: PASSED:
-  REQUIRE( v.size() == 10 )
+  REQUIRE( v.size() == 2 * V )
 with expansion:
-  10 == 10
+  30 == 30
 
 Misc.tests.cpp:<line number>: PASSED:
-  REQUIRE( v.capacity() >= 10 )
+  REQUIRE( v.capacity() >= 2 * V )
 with expansion:
-  10 >= 10
+  30 >= 30
 
 -------------------------------------------------------------------------------
-TemplateTest: vectors can be sized and resized - std::tuple<int,float>
+TemplateTestSig: vectors can be sized and resized - std::string,15
 -------------------------------------------------------------------------------
 Misc.tests.cpp:<line number>
 ...............................................................................
 
 Misc.tests.cpp:<line number>: PASSED:
-  REQUIRE( v.size() == 5 )
+  REQUIRE( v.size() == V )
 with expansion:
-  5 == 5
+  15 == 15
 
 Misc.tests.cpp:<line number>: PASSED:
-  REQUIRE( v.capacity() >= 5 )
+  REQUIRE( v.capacity() >= V )
 with expansion:
-  5 >= 5
+  15 >= 15
 
 -------------------------------------------------------------------------------
-TemplateTest: vectors can be sized and resized - std::tuple<int,float>
+TemplateTestSig: vectors can be sized and resized - std::string,15
   resizing smaller changes size but not capacity
 -------------------------------------------------------------------------------
 Misc.tests.cpp:<line number>
@@ -8054,12 +9645,12 @@ with expansion:
   0 == 0
 
 Misc.tests.cpp:<line number>: PASSED:
-  REQUIRE( v.capacity() >= 5 )
+  REQUIRE( v.capacity() >= V )
 with expansion:
-  5 >= 5
+  15 >= 15
 
 -------------------------------------------------------------------------------
-TemplateTest: vectors can be sized and resized - std::tuple<int,float>
+TemplateTestSig: vectors can be sized and resized - std::string,15
   resizing smaller changes size but not capacity
   We can use the 'swap trick' to reset the capacity
 -------------------------------------------------------------------------------
@@ -8072,70 +9663,70 @@ with expansion:
   0 == 0
 
 -------------------------------------------------------------------------------
-TemplateTest: vectors can be sized and resized - std::tuple<int,float>
+TemplateTestSig: vectors can be sized and resized - std::string,15
 -------------------------------------------------------------------------------
 Misc.tests.cpp:<line number>
 ...............................................................................
 
 Misc.tests.cpp:<line number>: PASSED:
-  REQUIRE( v.size() == 5 )
+  REQUIRE( v.size() == V )
 with expansion:
-  5 == 5
+  15 == 15
 
 Misc.tests.cpp:<line number>: PASSED:
-  REQUIRE( v.capacity() >= 5 )
+  REQUIRE( v.capacity() >= V )
 with expansion:
-  5 >= 5
+  15 >= 15
 
 -------------------------------------------------------------------------------
-TemplateTest: vectors can be sized and resized - std::tuple<int,float>
+TemplateTestSig: vectors can be sized and resized - std::string,15
   reserving bigger changes capacity but not size
 -------------------------------------------------------------------------------
 Misc.tests.cpp:<line number>
 ...............................................................................
 
 Misc.tests.cpp:<line number>: PASSED:
-  REQUIRE( v.size() == 5 )
+  REQUIRE( v.size() == V )
 with expansion:
-  5 == 5
+  15 == 15
 
 Misc.tests.cpp:<line number>: PASSED:
-  REQUIRE( v.capacity() >= 10 )
+  REQUIRE( v.capacity() >= 2 * V )
 with expansion:
-  10 >= 10
+  30 >= 30
 
 -------------------------------------------------------------------------------
-TemplateTest: vectors can be sized and resized - std::tuple<int,float>
+TemplateTestSig: vectors can be sized and resized - std::string,15
 -------------------------------------------------------------------------------
 Misc.tests.cpp:<line number>
 ...............................................................................
 
 Misc.tests.cpp:<line number>: PASSED:
-  REQUIRE( v.size() == 5 )
+  REQUIRE( v.size() == V )
 with expansion:
-  5 == 5
+  15 == 15
 
 Misc.tests.cpp:<line number>: PASSED:
-  REQUIRE( v.capacity() >= 5 )
+  REQUIRE( v.capacity() >= V )
 with expansion:
-  5 >= 5
+  15 >= 15
 
 -------------------------------------------------------------------------------
-TemplateTest: vectors can be sized and resized - std::tuple<int,float>
+TemplateTestSig: vectors can be sized and resized - std::string,15
   reserving smaller does not change size or capacity
 -------------------------------------------------------------------------------
 Misc.tests.cpp:<line number>
 ...............................................................................
 
 Misc.tests.cpp:<line number>: PASSED:
-  REQUIRE( v.size() == 5 )
+  REQUIRE( v.size() == V )
 with expansion:
-  5 == 5
+  15 == 15
 
 Misc.tests.cpp:<line number>: PASSED:
-  REQUIRE( v.capacity() >= 5 )
+  REQUIRE( v.capacity() >= V )
 with expansion:
-  5 >= 5
+  15 >= 15
 
 -------------------------------------------------------------------------------
 Test case with one argument
@@ -8158,6 +9749,14 @@ Tricky.tests.cpp:<line number>: PASSED:
 with expansion:
   3221225472 (0x<hex digits>) == 3221225472
 
+-------------------------------------------------------------------------------
+Test with special, characters "in name
+-------------------------------------------------------------------------------
+CmdLine.tests.cpp:<line number>
+...............................................................................
+
+CmdLine.tests.cpp:<line number>: PASSED:
+
 -------------------------------------------------------------------------------
 The NO_FAIL macro reports a failure but does not fail the test
 -------------------------------------------------------------------------------
@@ -8653,6 +10252,68 @@ PartTracker.tests.cpp:<line number>: PASSED:
 with expansion:
   true
 
+-------------------------------------------------------------------------------
+Trim strings
+-------------------------------------------------------------------------------
+StringManip.tests.cpp:<line number>
+...............................................................................
+
+StringManip.tests.cpp:<line number>: PASSED:
+  REQUIRE( trim(std::string(no_whitespace)) == no_whitespace )
+with expansion:
+  "There is no extra whitespace here"
+  ==
+  "There is no extra whitespace here"
+
+StringManip.tests.cpp:<line number>: PASSED:
+  REQUIRE( trim(std::string(leading_whitespace)) == no_whitespace )
+with expansion:
+  "There is no extra whitespace here"
+  ==
+  "There is no extra whitespace here"
+
+StringManip.tests.cpp:<line number>: PASSED:
+  REQUIRE( trim(std::string(trailing_whitespace)) == no_whitespace )
+with expansion:
+  "There is no extra whitespace here"
+  ==
+  "There is no extra whitespace here"
+
+StringManip.tests.cpp:<line number>: PASSED:
+  REQUIRE( trim(std::string(whitespace_at_both_ends)) == no_whitespace )
+with expansion:
+  "There is no extra whitespace here"
+  ==
+  "There is no extra whitespace here"
+
+StringManip.tests.cpp:<line number>: PASSED:
+  REQUIRE( trim(StringRef(no_whitespace)) == StringRef(no_whitespace) )
+with expansion:
+  There is no extra whitespace here
+  ==
+  There is no extra whitespace here
+
+StringManip.tests.cpp:<line number>: PASSED:
+  REQUIRE( trim(StringRef(leading_whitespace)) == StringRef(no_whitespace) )
+with expansion:
+  There is no extra whitespace here
+  ==
+  There is no extra whitespace here
+
+StringManip.tests.cpp:<line number>: PASSED:
+  REQUIRE( trim(StringRef(trailing_whitespace)) == StringRef(no_whitespace) )
+with expansion:
+  There is no extra whitespace here
+  ==
+  There is no extra whitespace here
+
+StringManip.tests.cpp:<line number>: PASSED:
+  REQUIRE( trim(StringRef(whitespace_at_both_ends)) == StringRef(no_whitespace) )
+with expansion:
+  There is no extra whitespace here
+  ==
+  There is no extra whitespace here
+
 -------------------------------------------------------------------------------
 Unexpected exceptions can be translated
 -------------------------------------------------------------------------------
@@ -8720,6 +10381,96 @@ VariadicMacros.tests.cpp:<line number>: PASSED:
 with message:
   no assertions
 
+-------------------------------------------------------------------------------
+Vector Approx matcher
+  Empty vector is roughly equal to an empty vector
+-------------------------------------------------------------------------------
+Matchers.tests.cpp:<line number>
+...............................................................................
+
+Matchers.tests.cpp:<line number>: PASSED:
+  REQUIRE_THAT( empty, Approx(empty) )
+with expansion:
+  {  } is approx: {  }
+
+-------------------------------------------------------------------------------
+Vector Approx matcher
+  Vectors with elements
+  A vector is approx equal to itself
+-------------------------------------------------------------------------------
+Matchers.tests.cpp:<line number>
+...............................................................................
+
+Matchers.tests.cpp:<line number>: PASSED:
+  REQUIRE_THAT( v1, Approx(v1) )
+with expansion:
+  { 1.0, 2.0, 3.0 } is approx: { 1.0, 2.0, 3.0 }
+
+-------------------------------------------------------------------------------
+Vector Approx matcher
+  Vectors with elements
+  Different length
+-------------------------------------------------------------------------------
+Matchers.tests.cpp:<line number>
+...............................................................................
+
+Matchers.tests.cpp:<line number>: PASSED:
+  REQUIRE_THAT( v1, !Approx(temp) )
+with expansion:
+  { 1.0, 2.0, 3.0 } not is approx: { 1.0, 2.0, 3.0, 4.0 }
+
+-------------------------------------------------------------------------------
+Vector Approx matcher
+  Vectors with elements
+  Same length, different elements
+-------------------------------------------------------------------------------
+Matchers.tests.cpp:<line number>
+...............................................................................
+
+Matchers.tests.cpp:<line number>: PASSED:
+  REQUIRE_THAT( v1, !Approx(v2) )
+with expansion:
+  { 1.0, 2.0, 3.0 } not is approx: { 1.5, 2.5, 3.5 }
+
+Matchers.tests.cpp:<line number>: PASSED:
+  REQUIRE_THAT( v1, Approx(v2).margin(0.5) )
+with expansion:
+  { 1.0, 2.0, 3.0 } is approx: { 1.5, 2.5, 3.5 }
+
+Matchers.tests.cpp:<line number>: PASSED:
+  REQUIRE_THAT( v1, Approx(v2).epsilon(0.5) )
+with expansion:
+  { 1.0, 2.0, 3.0 } is approx: { 1.5, 2.5, 3.5 }
+
+Matchers.tests.cpp:<line number>: PASSED:
+  REQUIRE_THAT( v1, Approx(v2).epsilon(0.1).scale(500) )
+with expansion:
+  { 1.0, 2.0, 3.0 } is approx: { 1.5, 2.5, 3.5 }
+
+-------------------------------------------------------------------------------
+Vector Approx matcher -- failing
+  Empty and non empty vectors are not approx equal
+-------------------------------------------------------------------------------
+Matchers.tests.cpp:<line number>
+...............................................................................
+
+Matchers.tests.cpp:<line number>: FAILED:
+  CHECK_THAT( empty, Approx(t1) )
+with expansion:
+  {  } is approx: { 1.0, 2.0 }
+
+-------------------------------------------------------------------------------
+Vector Approx matcher -- failing
+  Just different vectors
+-------------------------------------------------------------------------------
+Matchers.tests.cpp:<line number>
+...............................................................................
+
+Matchers.tests.cpp:<line number>: FAILED:
+  CHECK_THAT( v1, Approx(v2) )
+with expansion:
+  { 2.0, 4.0, 6.0 } is approx: { 1.0, 3.0, 5.0 }
+
 -------------------------------------------------------------------------------
 Vector matchers
   Contains (element)
@@ -10040,6 +11791,62 @@ with expansion:
   ==
   "{ { 42, "Arthur" }, { "Ford", 24 } }"
 
+-------------------------------------------------------------------------------
+parseEnums
+  No enums
+-------------------------------------------------------------------------------
+ToString.tests.cpp:<line number>
+...............................................................................
+
+ToString.tests.cpp:<line number>: PASSED:
+  CHECK_THAT( parseEnums( "" ), Equals( std::vector<Catch::StringRef>{} ) )
+with expansion:
+  {  } Equals: {  }
+
+-------------------------------------------------------------------------------
+parseEnums
+  One enum value
+-------------------------------------------------------------------------------
+ToString.tests.cpp:<line number>
+...............................................................................
+
+ToString.tests.cpp:<line number>: PASSED:
+  CHECK_THAT( parseEnums( "ClassName::EnumName::Value1" ), Equals(std::vector<Catch::StringRef>{"Value1"} ) )
+with expansion:
+  { Value1 } Equals: { Value1 }
+
+ToString.tests.cpp:<line number>: PASSED:
+  CHECK_THAT( parseEnums( "Value1" ), Equals( std::vector<Catch::StringRef>{"Value1"} ) )
+with expansion:
+  { Value1 } Equals: { Value1 }
+
+ToString.tests.cpp:<line number>: PASSED:
+  CHECK_THAT( parseEnums( "EnumName::Value1" ), Equals(std::vector<Catch::StringRef>{"Value1"} ) )
+with expansion:
+  { Value1 } Equals: { Value1 }
+
+-------------------------------------------------------------------------------
+parseEnums
+  Multiple enum values
+-------------------------------------------------------------------------------
+ToString.tests.cpp:<line number>
+...............................................................................
+
+ToString.tests.cpp:<line number>: PASSED:
+  CHECK_THAT( parseEnums( "ClassName::EnumName::Value1, ClassName::EnumName::Value2" ), Equals( std::vector<Catch::StringRef>{"Value1", "Value2"} ) )
+with expansion:
+  { Value1, Value2 } Equals: { Value1, Value2 }
+
+ToString.tests.cpp:<line number>: PASSED:
+  CHECK_THAT( parseEnums( "ClassName::EnumName::Value1, ClassName::EnumName::Value2, ClassName::EnumName::Value3" ), Equals( std::vector<Catch::StringRef>{"Value1", "Value2", "Value3"} ) )
+with expansion:
+  { Value1, Value2, Value3 } Equals: { Value1, Value2, Value3 }
+
+ToString.tests.cpp:<line number>: PASSED:
+  CHECK_THAT( parseEnums( "ClassName::EnumName::Value1,ClassName::EnumName::Value2 , ClassName::EnumName::Value3" ), Equals( std::vector<Catch::StringRef>{"Value1", "Value2", "Value3"} ) )
+with expansion:
+  { Value1, Value2, Value3 } Equals: { Value1, Value2, Value3 }
+
 -------------------------------------------------------------------------------
 pointer to class
 -------------------------------------------------------------------------------
@@ -10129,15 +11936,15 @@ with expansion:
 replaceInPlace
   replace single char
 -------------------------------------------------------------------------------
-String.tests.cpp:<line number>
+StringManip.tests.cpp:<line number>
 ...............................................................................
 
-String.tests.cpp:<line number>: PASSED:
-  CHECK( Catch::replaceInPlace( letters, "b", "z" ) )
+StringManip.tests.cpp:<line number>: PASSED:
+  CHECK( Catch::replaceInPlace(letters, "b", "z") )
 with expansion:
   true
 
-String.tests.cpp:<line number>: PASSED:
+StringManip.tests.cpp:<line number>: PASSED:
   CHECK( letters == "azcdefcg" )
 with expansion:
   "azcdefcg" == "azcdefcg"
@@ -10146,15 +11953,15 @@ with expansion:
 replaceInPlace
   replace two chars
 -------------------------------------------------------------------------------
-String.tests.cpp:<line number>
+StringManip.tests.cpp:<line number>
 ...............................................................................
 
-String.tests.cpp:<line number>: PASSED:
-  CHECK( Catch::replaceInPlace( letters, "c", "z" ) )
+StringManip.tests.cpp:<line number>: PASSED:
+  CHECK( Catch::replaceInPlace(letters, "c", "z") )
 with expansion:
   true
 
-String.tests.cpp:<line number>: PASSED:
+StringManip.tests.cpp:<line number>: PASSED:
   CHECK( letters == "abzdefzg" )
 with expansion:
   "abzdefzg" == "abzdefzg"
@@ -10163,15 +11970,15 @@ with expansion:
 replaceInPlace
   replace first char
 -------------------------------------------------------------------------------
-String.tests.cpp:<line number>
+StringManip.tests.cpp:<line number>
 ...............................................................................
 
-String.tests.cpp:<line number>: PASSED:
-  CHECK( Catch::replaceInPlace( letters, "a", "z" ) )
+StringManip.tests.cpp:<line number>: PASSED:
+  CHECK( Catch::replaceInPlace(letters, "a", "z") )
 with expansion:
   true
 
-String.tests.cpp:<line number>: PASSED:
+StringManip.tests.cpp:<line number>: PASSED:
   CHECK( letters == "zbcdefcg" )
 with expansion:
   "zbcdefcg" == "zbcdefcg"
@@ -10180,15 +11987,15 @@ with expansion:
 replaceInPlace
   replace last char
 -------------------------------------------------------------------------------
-String.tests.cpp:<line number>
+StringManip.tests.cpp:<line number>
 ...............................................................................
 
-String.tests.cpp:<line number>: PASSED:
-  CHECK( Catch::replaceInPlace( letters, "g", "z" ) )
+StringManip.tests.cpp:<line number>: PASSED:
+  CHECK( Catch::replaceInPlace(letters, "g", "z") )
 with expansion:
   true
 
-String.tests.cpp:<line number>: PASSED:
+StringManip.tests.cpp:<line number>: PASSED:
   CHECK( letters == "abcdefcz" )
 with expansion:
   "abcdefcz" == "abcdefcz"
@@ -10197,15 +12004,15 @@ with expansion:
 replaceInPlace
   replace all chars
 -------------------------------------------------------------------------------
-String.tests.cpp:<line number>
+StringManip.tests.cpp:<line number>
 ...............................................................................
 
-String.tests.cpp:<line number>: PASSED:
-  CHECK( Catch::replaceInPlace( letters, letters, "replaced" ) )
+StringManip.tests.cpp:<line number>: PASSED:
+  CHECK( Catch::replaceInPlace(letters, letters, "replaced") )
 with expansion:
   true
 
-String.tests.cpp:<line number>: PASSED:
+StringManip.tests.cpp:<line number>: PASSED:
   CHECK( letters == "replaced" )
 with expansion:
   "replaced" == "replaced"
@@ -10214,15 +12021,15 @@ with expansion:
 replaceInPlace
   replace no chars
 -------------------------------------------------------------------------------
-String.tests.cpp:<line number>
+StringManip.tests.cpp:<line number>
 ...............................................................................
 
-String.tests.cpp:<line number>: PASSED:
-  CHECK_FALSE( Catch::replaceInPlace( letters, "x", "z" ) )
+StringManip.tests.cpp:<line number>: PASSED:
+  CHECK_FALSE( Catch::replaceInPlace(letters, "x", "z") )
 with expansion:
   !false
 
-String.tests.cpp:<line number>: PASSED:
+StringManip.tests.cpp:<line number>: PASSED:
   CHECK( letters == letters )
 with expansion:
   "abcdefcg" == "abcdefcg"
@@ -10231,15 +12038,15 @@ with expansion:
 replaceInPlace
   escape '
 -------------------------------------------------------------------------------
-String.tests.cpp:<line number>
+StringManip.tests.cpp:<line number>
 ...............................................................................
 
-String.tests.cpp:<line number>: PASSED:
-  CHECK( Catch::replaceInPlace( s, "'", "|'" ) )
+StringManip.tests.cpp:<line number>: PASSED:
+  CHECK( Catch::replaceInPlace(s, "'", "|'") )
 with expansion:
   true
 
-String.tests.cpp:<line number>: PASSED:
+StringManip.tests.cpp:<line number>: PASSED:
   CHECK( s == "didn|'t" )
 with expansion:
   "didn|'t" == "didn|'t"
@@ -10287,6 +12094,27 @@ Tag.tests.cpp:<line number>: PASSED:
 with expansion:
   { ".", "magic-tag" } ( Contains: "magic-tag" and Contains: "." )
 
+-------------------------------------------------------------------------------
+splitString
+-------------------------------------------------------------------------------
+StringManip.tests.cpp:<line number>
+...............................................................................
+
+StringManip.tests.cpp:<line number>: PASSED:
+  CHECK_THAT( splitStringRef("", ','), Equals(std::vector<StringRef>()) )
+with expansion:
+  {  } Equals: {  }
+
+StringManip.tests.cpp:<line number>: PASSED:
+  CHECK_THAT( splitStringRef("abc", ','), Equals(std::vector<StringRef>{"abc"}) )
+with expansion:
+  { abc } Equals: { abc }
+
+StringManip.tests.cpp:<line number>: PASSED:
+  CHECK_THAT( splitStringRef("abc,def", ','), Equals(std::vector<StringRef>{"abc", "def"}) )
+with expansion:
+  { abc, def } Equals: { abc, def }
+
 -------------------------------------------------------------------------------
 stacks unscoped info in loops
 -------------------------------------------------------------------------------
@@ -11128,6 +12956,6 @@ Misc.tests.cpp:<line number>
 Misc.tests.cpp:<line number>: PASSED:
 
 ===============================================================================
-test cases:  258 |  176 passed |  78 failed |  4 failed as expected
-assertions: 1436 | 1276 passed | 139 failed | 21 failed as expected
+test cases:  304 |  214 passed |  86 failed |  4 failed as expected
+assertions: 1638 | 1469 passed | 148 failed | 21 failed as expected
 
diff --git a/packages/Catch2/projects/SelfTest/Baselines/console.swa4.approved.txt b/packages/Catch2/projects/SelfTest/Baselines/console.swa4.approved.txt
index bfa667506..322b81586 100644
--- a/packages/Catch2/projects/SelfTest/Baselines/console.swa4.approved.txt
+++ b/packages/Catch2/projects/SelfTest/Baselines/console.swa4.approved.txt
@@ -39,6 +39,22 @@ with expansion:
 Compilation.tests.cpp:<line number>
 ...............................................................................
 
+Compilation.tests.cpp:<line number>: PASSED:
+  REQUIRE( y.v == 0 )
+with expansion:
+  0 == 0
+
+Compilation.tests.cpp:<line number>: PASSED:
+  REQUIRE( 0 == y.v )
+with expansion:
+  0 == 0
+
+-------------------------------------------------------------------------------
+#1027: Bitfields can be captured
+-------------------------------------------------------------------------------
+Compilation.tests.cpp:<line number>
+...............................................................................
+
 Compilation.tests.cpp:<line number>: PASSED:
   REQUIRE( y.v == 0 )
 with expansion:
@@ -352,6 +368,6 @@ Condition.tests.cpp:<line number>: FAILED:
   CHECK( true != true )
 
 ===============================================================================
-test cases: 18 | 13 passed | 3 failed | 2 failed as expected
-assertions: 40 | 33 passed | 4 failed | 3 failed as expected
+test cases: 19 | 14 passed | 3 failed | 2 failed as expected
+assertions: 42 | 35 passed | 4 failed | 3 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 43c78d7ea..bfacb0330 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="123" tests="1437" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
+  <testsuite name="<exe-name>" errors="17" failures="132" tests="1639" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
     <properties>
       <property name="filters" value="~[!nonportable]~[!benchmark]~[approvals]"/>
       <property name="random-seed" value="1"/>
@@ -9,6 +9,7 @@
     <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}"/>
+    <testcase classname="<exe-name>.global" name="#1027: Bitfields can be captured" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="#1147" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="#1175 - Hidden Test" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="#1238" time="{duration}"/>
@@ -119,6 +120,30 @@ Class.tests.cpp:<line number>
     <testcase classname="<exe-name>.Template_Fixture_2" name="A TEMPLATE_PRODUCT_TEST_CASE_METHOD based test run that succeeds - Template_Foo&lt;int>" time="{duration}"/>
     <testcase classname="<exe-name>.Template_Fixture_2" name="A TEMPLATE_PRODUCT_TEST_CASE_METHOD based test run that succeeds - std::vector&lt;float>" time="{duration}"/>
     <testcase classname="<exe-name>.Template_Fixture_2" name="A TEMPLATE_PRODUCT_TEST_CASE_METHOD based test run that succeeds - std::vector&lt;int>" time="{duration}"/>
+    <testcase classname="<exe-name>.Template_Fixture_2" name="A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that fails - Template_Foo_2&lt;float, 6>" time="{duration}">
+      <failure message="6 &lt; 2" type="REQUIRE">
+Class.tests.cpp:<line number>
+      </failure>
+    </testcase>
+    <testcase classname="<exe-name>.Template_Fixture_2" name="A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that fails - Template_Foo_2&lt;int, 2>" time="{duration}">
+      <failure message="2 &lt; 2" type="REQUIRE">
+Class.tests.cpp:<line number>
+      </failure>
+    </testcase>
+    <testcase classname="<exe-name>.Template_Fixture_2" name="A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that fails - std::array&lt;float, 6>" time="{duration}">
+      <failure message="6 &lt; 2" type="REQUIRE">
+Class.tests.cpp:<line number>
+      </failure>
+    </testcase>
+    <testcase classname="<exe-name>.Template_Fixture_2" name="A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that fails - std::array&lt;int, 2>" time="{duration}">
+      <failure message="2 &lt; 2" type="REQUIRE">
+Class.tests.cpp:<line number>
+      </failure>
+    </testcase>
+    <testcase classname="<exe-name>.Template_Fixture_2" name="A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that succeeds - Template_Foo_2&lt;float,6>" time="{duration}"/>
+    <testcase classname="<exe-name>.Template_Fixture_2" name="A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that succeeds - Template_Foo_2&lt;int,2>" time="{duration}"/>
+    <testcase classname="<exe-name>.Template_Fixture_2" name="A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that succeeds - std::array&lt;float,6>" time="{duration}"/>
+    <testcase classname="<exe-name>.Template_Fixture_2" name="A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that succeeds - std::array&lt;int,2>" time="{duration}"/>
     <testcase classname="<exe-name>.Template_Fixture" name="A TEMPLATE_TEST_CASE_METHOD based test run that fails - double" time="{duration}">
       <failure message="1.0 == 2" type="REQUIRE">
 Class.tests.cpp:<line number>
@@ -137,6 +162,24 @@ Class.tests.cpp:<line number>
     <testcase classname="<exe-name>.Template_Fixture" name="A TEMPLATE_TEST_CASE_METHOD based test run that succeeds - double" time="{duration}"/>
     <testcase classname="<exe-name>.Template_Fixture" name="A TEMPLATE_TEST_CASE_METHOD based test run that succeeds - float" time="{duration}"/>
     <testcase classname="<exe-name>.Template_Fixture" name="A TEMPLATE_TEST_CASE_METHOD based test run that succeeds - int" time="{duration}"/>
+    <testcase classname="<exe-name>.Nttp_Fixture" name="A TEMPLATE_TEST_CASE_METHOD_SIG based test run that fails - 1" time="{duration}">
+      <failure message="1 == 0" type="REQUIRE">
+Class.tests.cpp:<line number>
+      </failure>
+    </testcase>
+    <testcase classname="<exe-name>.Nttp_Fixture" name="A TEMPLATE_TEST_CASE_METHOD_SIG based test run that fails - 3" time="{duration}">
+      <failure message="3 == 0" type="REQUIRE">
+Class.tests.cpp:<line number>
+      </failure>
+    </testcase>
+    <testcase classname="<exe-name>.Nttp_Fixture" name="A TEMPLATE_TEST_CASE_METHOD_SIG based test run that fails - 6" time="{duration}">
+      <failure message="6 == 0" type="REQUIRE">
+Class.tests.cpp:<line number>
+      </failure>
+    </testcase>
+    <testcase classname="<exe-name>.Nttp_Fixture" name="A TEMPLATE_TEST_CASE_METHOD_SIG based test run that succeeds - 1" time="{duration}"/>
+    <testcase classname="<exe-name>.Nttp_Fixture" name="A TEMPLATE_TEST_CASE_METHOD_SIG based test run that succeeds - 3" time="{duration}"/>
+    <testcase classname="<exe-name>.Nttp_Fixture" name="A TEMPLATE_TEST_CASE_METHOD_SIG based test run that succeeds - 6" time="{duration}"/>
     <testcase classname="<exe-name>.Fixture" name="A TEST_CASE_METHOD based test run that fails" time="{duration}">
       <failure message="1 == 2" type="REQUIRE">
 Class.tests.cpp:<line number>
@@ -147,6 +190,10 @@ Class.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="A Template product test case - Foo&lt;int>" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="A Template product test case - std::vector&lt;float>" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="A Template product test case - std::vector&lt;int>" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="A Template product test case with array signature - Bar&lt;float, 42>" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="A Template product test case with array signature - Bar&lt;int, 9>" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="A Template product test case with array signature - std::array&lt;float, 42>" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="A Template product test case with array signature - std::array&lt;int, 9>" 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">
@@ -185,10 +232,9 @@ Exception.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="Assertions then sections/A section" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Assertions then sections/A section/Another section" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Assertions then sections/A section/Another other section" time="{duration}"/>
-    <testcase classname="<exe-name>.global" name="Assorted miscellaneous tests" time="{duration}"/>
-    <testcase classname="<exe-name>.global" name="Bitfields can be captured (#1027)" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="CAPTURE can deal with complex expressions" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="CAPTURE can deal with complex expressions involving commas" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="CAPTURE parses string and character constants" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Capture and info messages/Capture should stringify like assertions" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Capture and info messages/Info should NOT stringify the way assertions do" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Character pretty printing/Specifically escaped" time="{duration}"/>
@@ -196,6 +242,7 @@ Exception.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="Character pretty printing/Low ASCII" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Commas in various macros are allowed" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Comparing function pointers" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Comparison ops" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Comparison with explicitly convertible types" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Comparisons between ints where one side is computed" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Comparisons between unsigned ints and negative signed ints match c++ standard behaviour" time="{duration}"/>
@@ -208,6 +255,9 @@ Matchers.tests.cpp:<line number>
 Matchers.tests.cpp:<line number>
       </failure>
     </testcase>
+    <testcase classname="<exe-name>.global" name="Copy and then generate a range/from var and iterators" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Copy and then generate a range/From a temporary container" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Copy and then generate a range/Final validation" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Custom exceptions can be translated when testing for nothrow" time="{duration}">
       <error message="throwCustom()" type="REQUIRE_NOTHROW">
 custom exception - not std
@@ -227,6 +277,7 @@ Exception.tests.cpp:<line number>
       </error>
     </testcase>
     <testcase classname="<exe-name>.global" name="Default scale is invisible to comparison" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Directly creating an EnumInfo" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="EndsWith string matcher" time="{duration}">
       <failure message="&quot;this string contains 'abc' as a substring&quot; ends with: &quot;Substring&quot;" type="CHECK_THAT">
 Matchers.tests.cpp:<line number>
@@ -235,6 +286,8 @@ Matchers.tests.cpp:<line number>
 Matchers.tests.cpp:<line number>
       </failure>
     </testcase>
+    <testcase classname="<exe-name>.global" name="Enums can quickly have stringification enabled using REGISTER_ENUM" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Enums in namespaces can quickly have stringification enabled using REGISTER_ENUM" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Epsilon only applies to Approx's value" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Equality checks that should fail" time="{duration}">
       <failure message="7 == 6" type="CHECK">
@@ -318,6 +371,7 @@ Matchers.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="Exception messages can be tested for/exact match" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Exception messages can be tested for/different case" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Exception messages can be tested for/wildcarded" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Exceptions matchers" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Expected exceptions that don't throw or unexpected exceptions fail the test" time="{duration}">
       <error message="thisThrows(), std::string" type="CHECK_THROWS_AS">
 expected exception
@@ -349,10 +403,14 @@ Message.tests.cpp:<line number>
       </failure>
     </testcase>
     <testcase classname="<exe-name>.global" name="Factorials are computed" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Floating point matchers: double/Relative" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Floating point matchers: double/Relative/Some subnormal values" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Floating point matchers: double/Margin" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Floating point matchers: double/ULPs" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Floating point matchers: double/Composed" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Floating point matchers: double/Constructor validation" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Floating point matchers: float/Relative" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Floating point matchers: float/Relative/Some subnormal values" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Floating point matchers: float/Margin" time="{duration}"/>
     <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}"/>
@@ -366,6 +424,7 @@ Message.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="Generators -- adapters/Repeating a generator" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Generators -- adapters/Chunking a generator into sized pieces/Number of elements in source is divisible by chunk size" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Generators -- adapters/Chunking a generator into sized pieces/Number of elements in source is not divisible by chunk size" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Generators -- adapters/Chunking a generator into sized pieces/Chunk size of zero" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Generators -- adapters/Chunking a generator into sized pieces/Throws on too small generators" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Generators -- simple/one" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Generators -- simple/two" time="{duration}"/>
@@ -526,6 +585,8 @@ Condition.tests.cpp:<line number>
       </failure>
     </testcase>
     <testcase classname="<exe-name>.global" name="Ordering comparison checks that should succeed" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Our PCG implementation provides expected results for known seeds/Default seeded" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Our PCG implementation provides expected results for known seeds/Specific seed" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Output from all sections is reported/one" time="{duration}">
       <failure type="FAIL">
 Message from section one
@@ -569,7 +630,11 @@ 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="Parse test names and tags/Leading and trailing spaces in test spec" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Parse test names and tags/Leading and trailing spaces in test name" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Pointers can be compared to null" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Precision of floating point stringification can be set/Floats" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Precision of floating point stringification can be set/Double" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Predicate matcher can accept const char*" 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}"/>
@@ -596,6 +661,10 @@ Message.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="Process can be configured on command line/use-colour/yes" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Process can be configured on command line/use-colour/no" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Process can be configured on command line/use-colour/error" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Process can be configured on command line/Benchmark options/samples" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Process can be configured on command line/Benchmark options/resamples" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Process can be configured on command line/Benchmark options/resamples" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Process can be configured on command line/Benchmark options/resamples" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Product with differing arities - std::tuple&lt;int, double, float>" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Product with differing arities - std::tuple&lt;int, double>" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Product with differing arities - std::tuple&lt;int>" time="{duration}"/>
@@ -661,17 +730,17 @@ Matchers.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="StringRef/From sub-string" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="StringRef/Substrings/zero-based substring" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="StringRef/Substrings/c_str() causes copy" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="StringRef/Substrings/c_str() causes copy/Self-assignment after substring" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="StringRef/Substrings/non-zero-based substring" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="StringRef/Substrings/Pointer values of full refs should match" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="StringRef/Substrings/Pointer values of substring refs should not match" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="StringRef/Substrings/Past the end substring" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="StringRef/Comparisons" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="StringRef/from std::string/implicitly constructed" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="StringRef/from std::string/explicitly constructed" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="StringRef/from std::string/assigned" time="{duration}"/>
-    <testcase classname="<exe-name>.global" name="StringRef/to std::string/implicitly constructed" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="StringRef/to std::string/explicitly constructed" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="StringRef/to std::string/assigned" time="{duration}"/>
-    <testcase classname="<exe-name>.global" name="StringRef/Counting utf-8 codepoints" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Stringifying std::chrono::duration helpers" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Stringifying std::chrono::duration with weird ratios" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Stringifying std::chrono::time_point&lt;system_clock>" time="{duration}"/>
@@ -689,6 +758,16 @@ Misc.tests.cpp:<line number>
     </testcase>
     <testcase classname="<exe-name>.global" name="Tag alias can be registered against tag patterns/The same tag alias can only be registered once" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Tag alias can be registered against tag patterns/Tag aliases must be of the form [@name]" time="{duration}"/>
+    <testcase classname="<exe-name>.Template_Fixture" name="Template test case method with test types specified inside std::tuple - MyTypes - 0" time="{duration}"/>
+    <testcase classname="<exe-name>.Template_Fixture" name="Template test case method with test types specified inside std::tuple - MyTypes - 1" time="{duration}"/>
+    <testcase classname="<exe-name>.Template_Fixture" name="Template test case method with test types specified inside std::tuple - MyTypes - 2" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Template test case with test types specified inside non-copyable and non-movable std::tuple - NonCopyableAndNonMovableTypes - 0" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Template test case with test types specified inside non-copyable and non-movable std::tuple - NonCopyableAndNonMovableTypes - 1" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Template test case with test types specified inside non-default-constructible std::tuple - MyNonDefaultConstructibleTypes - 0" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Template test case with test types specified inside non-default-constructible std::tuple - MyNonDefaultConstructibleTypes - 1" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Template test case with test types specified inside std::tuple - MyTypes - 0" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Template test case with test types specified inside std::tuple - MyTypes - 1" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Template test case with test types specified inside std::tuple - MyTypes - 2" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="TemplateTest: vectors can be sized and resized - float" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="TemplateTest: vectors can be sized and resized - float/resizing bigger changes size and capacity" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="TemplateTest: vectors can be sized and resized - float/resizing smaller changes size but not capacity" time="{duration}"/>
@@ -713,8 +792,33 @@ Misc.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="TemplateTest: vectors can be sized and resized - std::tuple&lt;int,float>/resizing smaller changes size but not capacity/We can use the 'swap trick' to reset the capacity" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="TemplateTest: vectors can be sized and resized - std::tuple&lt;int,float>/reserving bigger changes capacity but not size" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="TemplateTest: vectors can be sized and resized - std::tuple&lt;int,float>/reserving smaller does not change size or capacity" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="TemplateTestSig: vectors can be sized and resized - (std::tuple&lt;int, float>), 6" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="TemplateTestSig: vectors can be sized and resized - (std::tuple&lt;int, float>), 6/resizing bigger changes size and capacity" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="TemplateTestSig: vectors can be sized and resized - (std::tuple&lt;int, float>), 6/resizing smaller changes size but not capacity" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="TemplateTestSig: vectors can be sized and resized - (std::tuple&lt;int, float>), 6/resizing smaller changes size but not capacity/We can use the 'swap trick' to reset the capacity" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="TemplateTestSig: vectors can be sized and resized - (std::tuple&lt;int, float>), 6/reserving bigger changes capacity but not size" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="TemplateTestSig: vectors can be sized and resized - (std::tuple&lt;int, float>), 6/reserving smaller does not change size or capacity" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="TemplateTestSig: vectors can be sized and resized - float,4" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="TemplateTestSig: vectors can be sized and resized - float,4/resizing bigger changes size and capacity" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="TemplateTestSig: vectors can be sized and resized - float,4/resizing smaller changes size but not capacity" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="TemplateTestSig: vectors can be sized and resized - float,4/resizing smaller changes size but not capacity/We can use the 'swap trick' to reset the capacity" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="TemplateTestSig: vectors can be sized and resized - float,4/reserving bigger changes capacity but not size" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="TemplateTestSig: vectors can be sized and resized - float,4/reserving smaller does not change size or capacity" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="TemplateTestSig: vectors can be sized and resized - int,5" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="TemplateTestSig: vectors can be sized and resized - int,5/resizing bigger changes size and capacity" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="TemplateTestSig: vectors can be sized and resized - int,5/resizing smaller changes size but not capacity" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="TemplateTestSig: vectors can be sized and resized - int,5/resizing smaller changes size but not capacity/We can use the 'swap trick' to reset the capacity" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="TemplateTestSig: vectors can be sized and resized - int,5/reserving bigger changes capacity but not size" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="TemplateTestSig: vectors can be sized and resized - int,5/reserving smaller does not change size or capacity" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="TemplateTestSig: vectors can be sized and resized - std::string,15" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="TemplateTestSig: vectors can be sized and resized - std::string,15/resizing bigger changes size and capacity" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="TemplateTestSig: vectors can be sized and resized - std::string,15/resizing smaller changes size but not capacity" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="TemplateTestSig: vectors can be sized and resized - std::string,15/resizing smaller changes size but not capacity/We can use the 'swap trick' to reset the capacity" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="TemplateTestSig: vectors can be sized and resized - std::string,15/reserving bigger changes capacity but not size" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="TemplateTestSig: vectors can be sized and resized - std::string,15/reserving smaller does not change size or capacity" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Test case with one argument" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Test enum bit values" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Test with special, characters &quot;in name" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="The NO_FAIL macro reports a failure but does not fail the test" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="This test 'should' fail but doesn't" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Thrown string literals are translated" time="{duration}">
@@ -733,6 +837,7 @@ Exception.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="Tracker/successfully close one section, then find another/Re-enter - skips S1 and enters S2/Successfully close S2" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Tracker/successfully close one section, then find another/Re-enter - skips S1 and enters S2/fail S2" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Tracker/open a nested section" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Trim strings" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Unexpected exceptions can be translated" time="{duration}">
       <error type="TEST_CASE">
 3.14
@@ -741,6 +846,20 @@ Exception.tests.cpp:<line number>
     </testcase>
     <testcase classname="<exe-name>.global" name="Use a custom approx" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Variadic macros/Section with one argument" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Vector Approx matcher/Empty vector is roughly equal to an empty vector" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Vector Approx matcher/Vectors with elements/A vector is approx equal to itself" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Vector Approx matcher/Vectors with elements/Different length" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Vector Approx matcher/Vectors with elements/Same length, different elements" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Vector Approx matcher -- failing/Empty and non empty vectors are not approx equal" time="{duration}">
+      <failure message="{  } is approx: { 1.0, 2.0 }" type="CHECK_THAT">
+Matchers.tests.cpp:<line number>
+      </failure>
+    </testcase>
+    <testcase classname="<exe-name>.global" name="Vector Approx matcher -- failing/Just different vectors" time="{duration}">
+      <failure message="{ 2.0, 4.0, 6.0 } is approx: { 1.0, 3.0, 5.0 }" type="CHECK_THAT">
+Matchers.tests.cpp:<line number>
+      </failure>
+    </testcase>
     <testcase classname="<exe-name>.global" name="Vector matchers/Contains (element)" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Vector matchers/Contains (vector)" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Vector matchers/Contains (element), composed" time="{duration}"/>
@@ -946,6 +1065,9 @@ Message.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="null strings" time="{duration}"/>
     <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="parseEnums/No enums" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="parseEnums/One enum value" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="parseEnums/Multiple enum values" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="pointer to class" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="print unscoped info if passing unscoped info is printed" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="prints unscoped info on failure" time="{duration}">
@@ -984,6 +1106,7 @@ Message.tests.cpp:<line number>
       </failure>
     </testcase>
     <testcase classname="<exe-name>.global" name="shortened hide tags are split apart" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="splitString" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="stacks unscoped info in loops" time="{duration}">
       <failure message="false" type="CHECK">
 Count 1 to 3...
diff --git a/packages/Catch2/projects/SelfTest/Baselines/xml.sw.approved.txt b/packages/Catch2/projects/SelfTest/Baselines/xml.sw.approved.txt
index b526a5f7f..6193dfb3c 100644
--- a/packages/Catch2/projects/SelfTest/Baselines/xml.sw.approved.txt
+++ b/packages/Catch2/projects/SelfTest/Baselines/xml.sw.approved.txt
@@ -43,6 +43,25 @@
       </Expression>
       <OverallResult success="true"/>
     </TestCase>
+    <TestCase name="#1027: Bitfields can be captured" filename="projects/<exe-name>/UsageTests/Compilation.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Compilation.tests.cpp" >
+        <Original>
+          y.v == 0
+        </Original>
+        <Expanded>
+          0 == 0
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Compilation.tests.cpp" >
+        <Original>
+          0 == y.v
+        </Original>
+        <Expanded>
+          0 == 0
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
     <TestCase name="#1147" filename="projects/<exe-name>/UsageTests/Compilation.tests.cpp" >
       <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Compilation.tests.cpp" >
         <Original>
@@ -1318,6 +1337,94 @@ Nor would this
       </Expression>
       <OverallResult success="true"/>
     </TestCase>
+    <TestCase name="A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that fails - Template_Foo_2&lt;float, 6>" tags="[.][class][failing][nttp][product][template]" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+      <Expression success="false" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+        <Original>
+          Template_Fixture_2&lt;TestType>{}.m_a.size() &lt; 2
+        </Original>
+        <Expanded>
+          6 &lt; 2
+        </Expanded>
+      </Expression>
+      <OverallResult success="false"/>
+    </TestCase>
+    <TestCase name="A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that fails - Template_Foo_2&lt;int, 2>" tags="[.][class][failing][nttp][product][template]" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+      <Expression success="false" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+        <Original>
+          Template_Fixture_2&lt;TestType>{}.m_a.size() &lt; 2
+        </Original>
+        <Expanded>
+          2 &lt; 2
+        </Expanded>
+      </Expression>
+      <OverallResult success="false"/>
+    </TestCase>
+    <TestCase name="A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that fails - std::array&lt;float, 6>" tags="[.][class][failing][nttp][product][template]" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+      <Expression success="false" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+        <Original>
+          Template_Fixture_2&lt;TestType>{}.m_a.size() &lt; 2
+        </Original>
+        <Expanded>
+          6 &lt; 2
+        </Expanded>
+      </Expression>
+      <OverallResult success="false"/>
+    </TestCase>
+    <TestCase name="A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that fails - std::array&lt;int, 2>" tags="[.][class][failing][nttp][product][template]" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+      <Expression success="false" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+        <Original>
+          Template_Fixture_2&lt;TestType>{}.m_a.size() &lt; 2
+        </Original>
+        <Expanded>
+          2 &lt; 2
+        </Expanded>
+      </Expression>
+      <OverallResult success="false"/>
+    </TestCase>
+    <TestCase name="A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that succeeds - Template_Foo_2&lt;float,6>" tags="[class][nttp][product][template]" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+        <Original>
+          Template_Fixture_2&lt;TestType>{}.m_a.size() >= 2
+        </Original>
+        <Expanded>
+          6 >= 2
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that succeeds - Template_Foo_2&lt;int,2>" tags="[class][nttp][product][template]" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+        <Original>
+          Template_Fixture_2&lt;TestType>{}.m_a.size() >= 2
+        </Original>
+        <Expanded>
+          2 >= 2
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that succeeds - std::array&lt;float,6>" tags="[class][nttp][product][template]" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+        <Original>
+          Template_Fixture_2&lt;TestType>{}.m_a.size() >= 2
+        </Original>
+        <Expanded>
+          6 >= 2
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that succeeds - std::array&lt;int,2>" tags="[class][nttp][product][template]" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+        <Original>
+          Template_Fixture_2&lt;TestType>{}.m_a.size() >= 2
+        </Original>
+        <Expanded>
+          2 >= 2
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
     <TestCase name="A TEMPLATE_TEST_CASE_METHOD based test run that fails - double" tags="[.][class][failing][template]" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
       <Expression success="false" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
         <Original>
@@ -1384,6 +1491,72 @@ Nor would this
       </Expression>
       <OverallResult success="true"/>
     </TestCase>
+    <TestCase name="A TEMPLATE_TEST_CASE_METHOD_SIG based test run that fails - 1" tags="[.][class][failing][nttp][template]" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+      <Expression success="false" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+        <Original>
+          Nttp_Fixture&lt;V>::value == 0
+        </Original>
+        <Expanded>
+          1 == 0
+        </Expanded>
+      </Expression>
+      <OverallResult success="false"/>
+    </TestCase>
+    <TestCase name="A TEMPLATE_TEST_CASE_METHOD_SIG based test run that fails - 3" tags="[.][class][failing][nttp][template]" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+      <Expression success="false" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+        <Original>
+          Nttp_Fixture&lt;V>::value == 0
+        </Original>
+        <Expanded>
+          3 == 0
+        </Expanded>
+      </Expression>
+      <OverallResult success="false"/>
+    </TestCase>
+    <TestCase name="A TEMPLATE_TEST_CASE_METHOD_SIG based test run that fails - 6" tags="[.][class][failing][nttp][template]" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+      <Expression success="false" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+        <Original>
+          Nttp_Fixture&lt;V>::value == 0
+        </Original>
+        <Expanded>
+          6 == 0
+        </Expanded>
+      </Expression>
+      <OverallResult success="false"/>
+    </TestCase>
+    <TestCase name="A TEMPLATE_TEST_CASE_METHOD_SIG based test run that succeeds - 1" tags="[class][nttp][template]" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+        <Original>
+          Nttp_Fixture&lt;V>::value > 0
+        </Original>
+        <Expanded>
+          1 > 0
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="A TEMPLATE_TEST_CASE_METHOD_SIG based test run that succeeds - 3" tags="[class][nttp][template]" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+        <Original>
+          Nttp_Fixture&lt;V>::value > 0
+        </Original>
+        <Expanded>
+          3 > 0
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="A TEMPLATE_TEST_CASE_METHOD_SIG based test run that succeeds - 6" tags="[class][nttp][template]" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+        <Original>
+          Nttp_Fixture&lt;V>::value > 0
+        </Original>
+        <Expanded>
+          6 > 0
+        </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>
@@ -1450,6 +1623,50 @@ Nor would this
       </Expression>
       <OverallResult success="true"/>
     </TestCase>
+    <TestCase name="A Template product test case with array signature - Bar&lt;float, 42>" tags="[nttp][product][template]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Original>
+          x.size() > 0
+        </Original>
+        <Expanded>
+          42 > 0
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="A Template product test case with array signature - Bar&lt;int, 9>" tags="[nttp][product][template]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Original>
+          x.size() > 0
+        </Original>
+        <Expanded>
+          9 > 0
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="A Template product test case with array signature - std::array&lt;float, 42>" tags="[nttp][product][template]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Original>
+          x.size() > 0
+        </Original>
+        <Expanded>
+          42 > 0
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="A Template product test case with array signature - std::array&lt;int, 9>" tags="[nttp][product][template]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Original>
+          x.size() > 0
+        </Original>
+        <Expanded>
+          9 > 0
+        </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>
@@ -1955,52 +2172,6 @@ Nor would this
       </Section>
       <OverallResult success="true"/>
     </TestCase>
-    <TestCase name="Assorted miscellaneous tests" tags="[Approx]" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
-        <Original>
-          INFINITY == Approx(INFINITY)
-        </Original>
-        <Expanded>
-          inff == Approx( inf )
-        </Expanded>
-      </Expression>
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
-        <Original>
-          NAN != Approx(NAN)
-        </Original>
-        <Expanded>
-          nanf != Approx( nan )
-        </Expanded>
-      </Expression>
-      <Expression success="true" type="REQUIRE_FALSE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
-        <Original>
-          !(NAN == Approx(NAN))
-        </Original>
-        <Expanded>
-          !(nanf == Approx( nan ))
-        </Expanded>
-      </Expression>
-      <OverallResult success="true"/>
-    </TestCase>
-    <TestCase name="Bitfields can be captured (#1027)" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
-        <Original>
-          y.v == 0
-        </Original>
-        <Expanded>
-          0 == 0
-        </Expanded>
-      </Expression>
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
-        <Original>
-          0 == y.v
-        </Original>
-        <Expanded>
-          0 == 0
-        </Expanded>
-      </Expression>
-      <OverallResult success="true"/>
-    </TestCase>
     <TestCase name="CAPTURE can deal with complex expressions" tags="[capture][messages]" filename="projects/<exe-name>/UsageTests/Message.tests.cpp" >
       <Info>
         a := 1
@@ -2049,6 +2220,42 @@ Nor would this
       </Info>
       <OverallResult success="true"/>
     </TestCase>
+    <TestCase name="CAPTURE parses string and character constants" tags="[capture][messages]" filename="projects/<exe-name>/UsageTests/Message.tests.cpp" >
+      <Info>
+        ("comma, in string", "escaped, \", ") := "escaped, ", "
+      </Info>
+      <Info>
+        "single quote in string,'," := "single quote in string,',"
+      </Info>
+      <Info>
+        "some escapes, \\,\\\\" := "some escapes, \,\\"
+      </Info>
+      <Info>
+        "some, ), unmatched, } prenheses {[&lt;" := "some, ), unmatched, } prenheses {[&lt;"
+      </Info>
+      <Info>
+        '"' := '"'
+      </Info>
+      <Info>
+        '\'' := '''
+      </Info>
+      <Info>
+        ',' := ','
+      </Info>
+      <Info>
+        '}' := '}'
+      </Info>
+      <Info>
+        ')' := ')'
+      </Info>
+      <Info>
+        '(' := '('
+      </Info>
+      <Info>
+        '{' := '{'
+      </Info>
+      <OverallResult success="true"/>
+    </TestCase>
     <TestCase name="Capture and info messages" filename="projects/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
       <Section name="Capture should stringify like assertions" filename="projects/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
         <Info>
@@ -2322,6 +2529,41 @@ Nor would this
       </Expression>
       <OverallResult success="true"/>
     </TestCase>
+    <TestCase name="Comparison ops" tags="[rng]" filename="projects/<exe-name>/IntrospectiveTests/RandomNumberGeneration.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/RandomNumberGeneration.tests.cpp" >
+        <Original>
+          SimplePcg32{} == SimplePcg32{}
+        </Original>
+        <Expanded>
+          {?} == {?}
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/RandomNumberGeneration.tests.cpp" >
+        <Original>
+          SimplePcg32{ 0 } != SimplePcg32{}
+        </Original>
+        <Expanded>
+          {?} != {?}
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE_FALSE" filename="projects/<exe-name>/IntrospectiveTests/RandomNumberGeneration.tests.cpp" >
+        <Original>
+          !(SimplePcg32{ 1 } == SimplePcg32{ 2 })
+        </Original>
+        <Expanded>
+          !({?} == {?})
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE_FALSE" filename="projects/<exe-name>/IntrospectiveTests/RandomNumberGeneration.tests.cpp" >
+        <Original>
+          !(SimplePcg32{ 1 } != SimplePcg32{ 1 })
+        </Original>
+        <Expanded>
+          !({?} != {?})
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
     <TestCase name="Comparison with explicitly convertible 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>
@@ -2609,13 +2851,167 @@ Nor would this
       </Expression>
       <OverallResult success="false"/>
     </TestCase>
-    <TestCase name="Custom exceptions can be translated when testing for nothrow" tags="[!throws][.][failing]" filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" >
-      <Expression success="false" type="REQUIRE_NOTHROW" filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" >
-        <Original>
-          throwCustom()
-        </Original>
-        <Expanded>
-          throwCustom()
+    <TestCase name="Copy and then generate a range" tags="[generators]" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+      <Section name="from var and iterators" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+          <Original>
+            elem % 2 == 1
+          </Original>
+          <Expanded>
+            1 == 1
+          </Expanded>
+        </Expression>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="from var and iterators" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+          <Original>
+            elem % 2 == 1
+          </Original>
+          <Expanded>
+            1 == 1
+          </Expanded>
+        </Expression>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="from var and iterators" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+          <Original>
+            elem % 2 == 1
+          </Original>
+          <Expanded>
+            1 == 1
+          </Expanded>
+        </Expression>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="from var and iterators" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+          <Original>
+            elem % 2 == 1
+          </Original>
+          <Expanded>
+            1 == 1
+          </Expanded>
+        </Expression>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="from var and iterators" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+          <Original>
+            elem % 2 == 1
+          </Original>
+          <Expanded>
+            1 == 1
+          </Expanded>
+        </Expression>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="from var and iterators" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+          <Original>
+            elem % 2 == 1
+          </Original>
+          <Expanded>
+            1 == 1
+          </Expanded>
+        </Expression>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="From a temporary container" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+          <Original>
+            elem % 2 == 1
+          </Original>
+          <Expanded>
+            1 == 1
+          </Expanded>
+        </Expression>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="From a temporary container" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+          <Original>
+            elem % 2 == 1
+          </Original>
+          <Expanded>
+            1 == 1
+          </Expanded>
+        </Expression>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="From a temporary container" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+          <Original>
+            elem % 2 == 1
+          </Original>
+          <Expanded>
+            1 == 1
+          </Expanded>
+        </Expression>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="From a temporary container" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+          <Original>
+            elem % 2 == 1
+          </Original>
+          <Expanded>
+            1 == 1
+          </Expanded>
+        </Expression>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="From a temporary container" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+          <Original>
+            elem % 2 == 1
+          </Original>
+          <Expanded>
+            1 == 1
+          </Expanded>
+        </Expression>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="From a temporary container" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+          <Original>
+            elem % 2 == 1
+          </Original>
+          <Expanded>
+            1 == 1
+          </Expanded>
+        </Expression>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="Final validation" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+          <Original>
+            call_count == 1
+          </Original>
+          <Expanded>
+            1 == 1
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+          <Original>
+            make_data().size() == test_count
+          </Original>
+          <Expanded>
+            6 == 6
+          </Expanded>
+        </Expression>
+        <OverallResults successes="2" failures="0" expectedFailures="0"/>
+      </Section>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="Custom exceptions can be translated when testing for nothrow" tags="[!throws][.][failing]" filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" >
+      <Expression success="false" type="REQUIRE_NOTHROW" filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" >
+        <Original>
+          throwCustom()
+        </Original>
+        <Expanded>
+          throwCustom()
         </Expanded>
         <Exception filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" >
           custom exception - not std
@@ -2662,6 +3058,35 @@ Nor would this
       </Expression>
       <OverallResult success="true"/>
     </TestCase>
+    <TestCase name="Directly creating an EnumInfo" filename="projects/<exe-name>/IntrospectiveTests/ToString.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/ToString.tests.cpp" >
+        <Original>
+          enumInfo->lookup(0) == "Value1"
+        </Original>
+        <Expanded>
+          Value1 == "Value1"
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/ToString.tests.cpp" >
+        <Original>
+          enumInfo->lookup(1) == "Value2"
+        </Original>
+        <Expanded>
+          Value2 == "Value2"
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/ToString.tests.cpp" >
+        <Original>
+          enumInfo->lookup(3) == "{** unexpected enum value **}"
+        </Original>
+        <Expanded>
+          {** unexpected enum value **}
+==
+"{** unexpected enum value **}"
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
     <TestCase name="EndsWith string matcher" tags="[.][failing][matchers]" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
       <Expression success="false" type="CHECK_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
         <Original>
@@ -2681,6 +3106,70 @@ Nor would this
       </Expression>
       <OverallResult success="false"/>
     </TestCase>
+    <TestCase name="Enums can quickly have stringification enabled using REGISTER_ENUM" filename="projects/<exe-name>/UsageTests/EnumToString.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/EnumToString.tests.cpp" >
+        <Original>
+          stringify( EnumClass3::Value1 ) == "Value1"
+        </Original>
+        <Expanded>
+          "Value1" == "Value1"
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/EnumToString.tests.cpp" >
+        <Original>
+          stringify( EnumClass3::Value2 ) == "Value2"
+        </Original>
+        <Expanded>
+          "Value2" == "Value2"
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/EnumToString.tests.cpp" >
+        <Original>
+          stringify( EnumClass3::Value3 ) == "Value3"
+        </Original>
+        <Expanded>
+          "Value3" == "Value3"
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/EnumToString.tests.cpp" >
+        <Original>
+          stringify( EnumClass3::Value4 ) == "{** unexpected enum value **}"
+        </Original>
+        <Expanded>
+          "{** unexpected enum value **}"
+==
+"{** unexpected enum value **}"
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/EnumToString.tests.cpp" >
+        <Original>
+          stringify( ec3 ) == "Value2"
+        </Original>
+        <Expanded>
+          "Value2" == "Value2"
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="Enums in namespaces can quickly have stringification enabled using REGISTER_ENUM" filename="projects/<exe-name>/UsageTests/EnumToString.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/EnumToString.tests.cpp" >
+        <Original>
+          stringify( Bikeshed::Colours::Red ) == "Red"
+        </Original>
+        <Expanded>
+          "Red" == "Red"
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/EnumToString.tests.cpp" >
+        <Original>
+          stringify( Bikeshed::Colours::Blue ) == "Blue"
+        </Original>
+        <Expanded>
+          "Blue" == "Blue"
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
     <TestCase name="Epsilon only applies to Approx's value" tags="[Approx]" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
       <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
         <Original>
@@ -2975,7 +3464,7 @@ Nor would this
       <Section name="Contents are wrong" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
         <Expression success="false" type="CHECK_THROWS_MATCHES" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            throws(3), SpecialException, ExceptionMatcher{1}
+            throwsSpecialException(3), SpecialException, ExceptionMatcher{1}
           </Original>
           <Expanded>
             SpecialException::what special exception has value of 1
@@ -2983,7 +3472,7 @@ Nor would this
         </Expression>
         <Expression success="false" type="REQUIRE_THROWS_MATCHES" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            throws(4), SpecialException, ExceptionMatcher{1}
+            throwsSpecialException(4), SpecialException, ExceptionMatcher{1}
           </Original>
           <Expanded>
             SpecialException::what special exception has value of 1
@@ -2996,7 +3485,7 @@ Nor would this
     <TestCase name="Exception matchers that succeed" tags="[!throws][exceptions][matchers]" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
       <Expression success="true" type="CHECK_THROWS_MATCHES" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
         <Original>
-          throws(1), SpecialException, ExceptionMatcher{1}
+          throwsSpecialException(1), SpecialException, ExceptionMatcher{1}
         </Original>
         <Expanded>
           SpecialException::what special exception has value of 1
@@ -3004,7 +3493,7 @@ Nor would this
       </Expression>
       <Expression success="true" type="REQUIRE_THROWS_MATCHES" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
         <Original>
-          throws(2), SpecialException, ExceptionMatcher{2}
+          throwsSpecialException(2), SpecialException, ExceptionMatcher{2}
         </Original>
         <Expanded>
           SpecialException::what special exception has value of 2
@@ -3072,6 +3561,41 @@ Nor would this
       </Section>
       <OverallResult success="true"/>
     </TestCase>
+    <TestCase name="Exceptions matchers" tags="[!throws][exceptions][matchers]" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+      <Expression success="true" type="REQUIRE_THROWS_MATCHES" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Original>
+          throwsDerivedException(), DerivedException, Message("DerivedException::what")
+        </Original>
+        <Expanded>
+          DerivedException::what exception message matches "DerivedException::what"
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE_THROWS_MATCHES" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Original>
+          throwsDerivedException(), DerivedException, !Message("derivedexception::what")
+        </Original>
+        <Expanded>
+          DerivedException::what not exception message matches "derivedexception::what"
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE_THROWS_MATCHES" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Original>
+          throwsSpecialException(2), SpecialException, !Message("DerivedException::what")
+        </Original>
+        <Expanded>
+          SpecialException::what not exception message matches "DerivedException::what"
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE_THROWS_MATCHES" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Original>
+          throwsSpecialException(2), SpecialException, Message("SpecialException::what")
+        </Original>
+        <Expanded>
+          SpecialException::what exception message matches "SpecialException::what"
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
     <TestCase name="Expected exceptions that don't throw or unexpected exceptions fail the test" tags="[!throws][.][failing]" filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" >
       <Expression success="false" type="CHECK_THROWS_AS" filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" >
         <Original>
@@ -3168,6 +3692,52 @@ Nor would this
       <OverallResult success="true"/>
     </TestCase>
     <TestCase name="Floating point matchers: double" tags="[floating-point][matchers]" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+      <Section name="Relative" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            10., WithinRel(11.1, 0.1)
+          </Original>
+          <Expanded>
+            10.0 and 11.1 are within 10% of each other
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            10., !WithinRel(11.2, 0.1)
+          </Original>
+          <Expanded>
+            10.0 not and 11.2 are within 10% of each other
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            1., !WithinRel(0., 0.99)
+          </Original>
+          <Expanded>
+            1.0 not and 0 are within 99% of each other
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            -0., WithinRel(0.)
+          </Original>
+          <Expanded>
+            -0.0 and 0 are within 2.22045e-12% of each other
+          </Expanded>
+        </Expression>
+        <Section name="Some subnormal values" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+            <Original>
+              v1, WithinRel(v2)
+            </Original>
+            <Expanded>
+              0.0 and 2.22507e-308 are within 2.22045e-12% of each other
+            </Expanded>
+          </Expression>
+          <OverallResults successes="1" failures="0" expectedFailures="0"/>
+        </Section>
+        <OverallResults successes="5" failures="0" expectedFailures="0"/>
+      </Section>
       <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>
@@ -3201,14 +3771,6 @@ Nor would this
             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)
@@ -3241,7 +3803,7 @@ Nor would this
             -10.0 is within 0.5 of -9.6
           </Expanded>
         </Expression>
-        <OverallResults successes="9" failures="0" expectedFailures="0"/>
+        <OverallResults successes="8" 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" >
@@ -3249,7 +3811,7 @@ Nor would this
             1., WithinULP(1., 0)
           </Original>
           <Expanded>
-            1.0 is within 0 ULPs of 1.0
+            1.0 is within 0 ULPs of 1.0000000000000000e+00 ([1.0000000000000000e+00, 1.0000000000000000e+00])
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
@@ -3257,47 +3819,47 @@ Nor would this
             nextafter(1., 2.), WithinULP(1., 1)
           </Original>
           <Expanded>
-            1.0 is within 1 ULPs of 1.0
+            1.0 is within 1 ULPs of 1.0000000000000000e+00 ([9.9999999999999989e-01, 1.0000000000000002e+00])
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            nextafter(1., 0.), WithinULP(1., 1)
+            0., WithinULP(nextafter(0., 1.), 1)
           </Original>
           <Expanded>
-            1.0 is within 1 ULPs of 1.0
+            0.0 is within 1 ULPs of 4.9406564584124654e-324 ([0.0000000000000000e+00, 9.8813129168249309e-324])
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            nextafter(1., 2.), !WithinULP(1., 0)
+            1., WithinULP(nextafter(1., 0.), 1)
           </Original>
           <Expanded>
-            1.0 not is within 0 ULPs of 1.0
+            1.0 is within 1 ULPs of 9.9999999999999989e-01 ([9.9999999999999978e-01, 1.0000000000000000e+00])
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            1., WithinULP(1., 0)
+            1., !WithinULP(nextafter(1., 2.), 0)
           </Original>
           <Expanded>
-            1.0 is within 0 ULPs of 1.0
+            1.0 not is within 0 ULPs of 1.0000000000000002e+00 ([1.0000000000000002e+00, 1.0000000000000002e+00])
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            -0., WithinULP(0., 0)
+            1., WithinULP(1., 0)
           </Original>
           <Expanded>
-            -0.0 is within 0 ULPs of 0.0
+            1.0 is within 0 ULPs of 1.0000000000000000e+00 ([1.0000000000000000e+00, 1.0000000000000000e+00])
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            NAN, !WithinULP(NAN, 123)
+            -0., WithinULP(0., 0)
           </Original>
           <Expanded>
-            nanf not is within 123 ULPs of nanf
+            -0.0 is within 0 ULPs of 0.0000000000000000e+00 ([0.0000000000000000e+00, 0.0000000000000000e+00])
           </Expanded>
         </Expression>
         <OverallResults successes="7" failures="0" expectedFailures="0"/>
@@ -3308,7 +3870,7 @@ Nor would this
             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 )
+            1.0 ( is within 0.5 of 1.0 or is within 1 ULPs of 2.0000000000000000e+00 ([1.9999999999999998e+00, 2.0000000000000004e+00]) )
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
@@ -3316,15 +3878,15 @@ Nor would this
             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 )
+            1.0 ( is within 0.5 of 2.0 or is within 0 ULPs of 1.0000000000000000e+00 ([1.0000000000000000e+00, 1.0000000000000000e+00]) )
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            NAN, !(WithinAbs(NAN, 100) || WithinULP(NAN, 123))
+            0.0001, WithinAbs(0., 0.001) || WithinRel(0., 0.1)
           </Original>
           <Expanded>
-            nanf not ( is within 100.0 of nan or is within 123 ULPs of nanf )
+            0.0001 ( is within 0.001 of 0.0 or and 0 are within 10% of each other )
           </Expanded>
         </Expression>
         <OverallResults successes="3" failures="0" expectedFailures="0"/>
@@ -3354,19 +3916,81 @@ Nor would this
             WithinULP(1., 0)
           </Expanded>
         </Expression>
+        <Expression success="true" type="REQUIRE_NOTHROW" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            WithinRel(1., 0.)
+          </Original>
+          <Expanded>
+            WithinRel(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
+            WithinRel(1., -0.2), std::domain_error
           </Original>
           <Expanded>
-            WithinULP(1., -1), std::domain_error
+            WithinRel(1., -0.2), std::domain_error
           </Expanded>
         </Expression>
-        <OverallResults successes="4" failures="0" expectedFailures="0"/>
+        <Expression success="true" type="REQUIRE_THROWS_AS" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            WithinRel(1., 1.), std::domain_error
+          </Original>
+          <Expanded>
+            WithinRel(1., 1.), std::domain_error
+          </Expanded>
+        </Expression>
+        <OverallResults successes="6" 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="Relative" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            10.f, WithinRel(11.1f, 0.1f)
+          </Original>
+          <Expanded>
+            10.0f and 11.1 are within 10% of each other
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            10.f, !WithinRel(11.2f, 0.1f)
+          </Original>
+          <Expanded>
+            10.0f not and 11.2 are within 10% of each other
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            1.f, !WithinRel(0.f, 0.99f)
+          </Original>
+          <Expanded>
+            1.0f not and 0 are within 99% of each other
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            -0.f, WithinRel(0.f)
+          </Original>
+          <Expanded>
+            -0.0f and 0 are within 0.00119209% of each other
+          </Expanded>
+        </Expression>
+        <Section name="Some subnormal values" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+            <Original>
+              v1, WithinRel(v2)
+            </Original>
+            <Expanded>
+              0.0f and 1.17549e-38 are within 0.00119209% of each other
+            </Expanded>
+          </Expression>
+          <OverallResults successes="1" failures="0" expectedFailures="0"/>
+        </Section>
+        <OverallResults successes="5" failures="0" expectedFailures="0"/>
+      </Section>
       <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>
@@ -3408,14 +4032,6 @@ Nor would this
             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" >
-          <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.f, !WithinAbs(10.f, 0.5f)
@@ -3448,7 +4064,7 @@ Nor would this
             -10.0f is within 0.5 of -9.6000003815
           </Expanded>
         </Expression>
-        <OverallResults successes="10" failures="0" expectedFailures="0"/>
+        <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" >
@@ -3456,7 +4072,7 @@ Nor would this
             1.f, WithinULP(1.f, 0)
           </Original>
           <Expanded>
-            1.0f is within 0 ULPs of 1.0f
+            1.0f is within 0 ULPs of 1.00000000e+00f ([1.00000000e+00, 1.00000000e+00])
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
@@ -3464,47 +4080,47 @@ Nor would this
             nextafter(1.f, 2.f), WithinULP(1.f, 1)
           </Original>
           <Expanded>
-            1.0f is within 1 ULPs of 1.0f
+            1.0f is within 1 ULPs of 1.00000000e+00f ([9.99999940e-01, 1.00000012e+00])
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            nextafter(1.f, 0.f), WithinULP(1.f, 1)
+            0.f, WithinULP(nextafter(0.f, 1.f), 1)
           </Original>
           <Expanded>
-            1.0f is within 1 ULPs of 1.0f
+            0.0f is within 1 ULPs of 1.40129846e-45f ([0.00000000e+00, 2.80259693e-45])
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            nextafter(1.f, 2.f), !WithinULP(1.f, 0)
+            1.f, WithinULP(nextafter(1.f, 0.f), 1)
           </Original>
           <Expanded>
-            1.0f not is within 0 ULPs of 1.0f
+            1.0f is within 1 ULPs of 9.99999940e-01f ([9.99999881e-01, 1.00000000e+00])
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            1.f, WithinULP(1.f, 0)
+            1.f, !WithinULP(nextafter(1.f, 2.f), 0)
           </Original>
           <Expanded>
-            1.0f is within 0 ULPs of 1.0f
+            1.0f not is within 0 ULPs of 1.00000012e+00f ([1.00000012e+00, 1.00000012e+00])
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            -0.f, WithinULP(0.f, 0)
+            1.f, WithinULP(1.f, 0)
           </Original>
           <Expanded>
-            -0.0f is within 0 ULPs of 0.0f
+            1.0f is within 0 ULPs of 1.00000000e+00f ([1.00000000e+00, 1.00000000e+00])
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            NAN, !WithinULP(NAN, 123)
+            -0.f, WithinULP(0.f, 0)
           </Original>
           <Expanded>
-            nanf not is within 123 ULPs of nanf
+            -0.0f is within 0 ULPs of 0.00000000e+00f ([0.00000000e+00, 0.00000000e+00])
           </Expanded>
         </Expression>
         <OverallResults successes="7" failures="0" expectedFailures="0"/>
@@ -3515,7 +4131,7 @@ Nor would this
             1.f, WithinAbs(1.f, 0.5) || WithinULP(1.f, 1)
           </Original>
           <Expanded>
-            1.0f ( is within 0.5 of 1.0 or is within 1 ULPs of 1.0f )
+            1.0f ( is within 0.5 of 1.0 or is within 1 ULPs of 1.00000000e+00f ([9.99999940e-01, 1.00000012e+00]) )
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
@@ -3523,15 +4139,15 @@ Nor would this
             1.f, WithinAbs(2.f, 0.5) || WithinULP(1.f, 0)
           </Original>
           <Expanded>
-            1.0f ( is within 0.5 of 2.0 or is within 0 ULPs of 1.0f )
+            1.0f ( is within 0.5 of 2.0 or is within 0 ULPs of 1.00000000e+00f ([1.00000000e+00, 1.00000000e+00]) )
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            NAN, !(WithinAbs(NAN, 100) || WithinULP(NAN, 123))
+            0.0001f, WithinAbs(0.f, 0.001f) || WithinRel(0.f, 0.1f)
           </Original>
           <Expanded>
-            nanf not ( is within 100.0 of nan or is within 123 ULPs of nanf )
+            0.0001f ( is within 0.001 of 0.0 or and 0 are within 10% of each other )
           </Expanded>
         </Expression>
         <OverallResults successes="3" failures="0" expectedFailures="0"/>
@@ -3563,13 +4179,37 @@ Nor would this
         </Expression>
         <Expression success="true" type="REQUIRE_THROWS_AS" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            WithinULP(1.f, -1), std::domain_error
+            WithinULP(1.f, static_cast&lt;uint64_t>(-1)), std::domain_error
           </Original>
           <Expanded>
-            WithinULP(1.f, -1), std::domain_error
+            WithinULP(1.f, static_cast&lt;uint64_t>(-1)), std::domain_error
           </Expanded>
         </Expression>
-        <OverallResults successes="4" failures="0" expectedFailures="0"/>
+        <Expression success="true" type="REQUIRE_NOTHROW" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            WithinRel(1.f, 0.f)
+          </Original>
+          <Expanded>
+            WithinRel(1.f, 0.f)
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THROWS_AS" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            WithinRel(1.f, -0.2f), std::domain_error
+          </Original>
+          <Expanded>
+            WithinRel(1.f, -0.2f), std::domain_error
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THROWS_AS" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            WithinRel(1.f, 1.f), std::domain_error
+          </Original>
+          <Expanded>
+            WithinRel(1.f, 1.f), std::domain_error
+          </Expanded>
+        </Expression>
+        <OverallResults successes="7" failures="0" expectedFailures="0"/>
       </Section>
       <OverallResult success="true"/>
     </TestCase>
@@ -3981,6 +4621,48 @@ Nor would this
         </Section>
         <OverallResults successes="3" failures="0" expectedFailures="0"/>
       </Section>
+      <Section name="Chunking a generator into sized pieces" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Section name="Chunk size of zero" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+          <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+            <Original>
+              chunk2.size() == 0
+            </Original>
+            <Expanded>
+              0 == 0
+            </Expanded>
+          </Expression>
+          <OverallResults successes="1" failures="0" expectedFailures="0"/>
+        </Section>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="Chunking a generator into sized pieces" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Section name="Chunk size of zero" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+          <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+            <Original>
+              chunk2.size() == 0
+            </Original>
+            <Expanded>
+              0 == 0
+            </Expanded>
+          </Expression>
+          <OverallResults successes="1" failures="0" expectedFailures="0"/>
+        </Section>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="Chunking a generator into sized pieces" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Section name="Chunk size of zero" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+          <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+            <Original>
+              chunk2.size() == 0
+            </Original>
+            <Expanded>
+              0 == 0
+            </Expanded>
+          </Expression>
+          <OverallResults successes="1" failures="0" expectedFailures="0"/>
+        </Section>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
       <Section name="Chunking a generator into sized pieces" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Section name="Throws on too small generators" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
           <Expression success="true" type="REQUIRE_THROWS_AS" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
@@ -6391,6 +7073,165 @@ Nor would this
       </Expression>
       <OverallResult success="true"/>
     </TestCase>
+    <TestCase name="Our PCG implementation provides expected results for known seeds" tags="[rng]" filename="projects/<exe-name>/IntrospectiveTests/RandomNumberGeneration.tests.cpp" >
+      <Section name="Default seeded" filename="projects/<exe-name>/IntrospectiveTests/RandomNumberGeneration.tests.cpp" >
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/RandomNumberGeneration.tests.cpp" >
+          <Original>
+            rng() == 0x<hex digits>
+          </Original>
+          <Expanded>
+            4242248763 (0x<hex digits>)
+==
+4242248763 (0x<hex digits>)
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/RandomNumberGeneration.tests.cpp" >
+          <Original>
+            rng() == 0x<hex digits>
+          </Original>
+          <Expanded>
+            1867888929 (0x<hex digits>)
+==
+1867888929 (0x<hex digits>)
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/RandomNumberGeneration.tests.cpp" >
+          <Original>
+            rng() == 0x<hex digits>
+          </Original>
+          <Expanded>
+            1276619030 (0x<hex digits>)
+==
+1276619030 (0x<hex digits>)
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/RandomNumberGeneration.tests.cpp" >
+          <Original>
+            rng() == 0x<hex digits>
+          </Original>
+          <Expanded>
+            1911218783 (0x<hex digits>)
+==
+1911218783 (0x<hex digits>)
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/RandomNumberGeneration.tests.cpp" >
+          <Original>
+            rng() == 0x<hex digits>
+          </Original>
+          <Expanded>
+            1827115164 (0x<hex digits>)
+==
+1827115164 (0x<hex digits>)
+          </Expanded>
+        </Expression>
+        <OverallResults successes="5" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="Specific seed" filename="projects/<exe-name>/IntrospectiveTests/RandomNumberGeneration.tests.cpp" >
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/RandomNumberGeneration.tests.cpp" >
+          <Original>
+            rng() == 0x<hex digits>
+          </Original>
+          <Expanded>
+            1472234645 (0x<hex digits>)
+==
+1472234645 (0x<hex digits>)
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/RandomNumberGeneration.tests.cpp" >
+          <Original>
+            rng() == 0x<hex digits>
+          </Original>
+          <Expanded>
+            868832940 (0x<hex digits>)
+==
+868832940 (0x<hex digits>)
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/RandomNumberGeneration.tests.cpp" >
+          <Original>
+            rng() == 0x<hex digits>
+          </Original>
+          <Expanded>
+            570883446 (0x<hex digits>)
+==
+570883446 (0x<hex digits>)
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/RandomNumberGeneration.tests.cpp" >
+          <Original>
+            rng() == 0x<hex digits>
+          </Original>
+          <Expanded>
+            889299803 (0x<hex digits>)
+==
+889299803 (0x<hex digits>)
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/RandomNumberGeneration.tests.cpp" >
+          <Original>
+            rng() == 0x<hex digits>
+          </Original>
+          <Expanded>
+            4261393167 (0x<hex digits>)
+==
+4261393167 (0x<hex digits>)
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/RandomNumberGeneration.tests.cpp" >
+          <Original>
+            rng() == 0x<hex digits>
+          </Original>
+          <Expanded>
+            1472234645 (0x<hex digits>)
+==
+1472234645 (0x<hex digits>)
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/RandomNumberGeneration.tests.cpp" >
+          <Original>
+            rng() == 0x<hex digits>
+          </Original>
+          <Expanded>
+            868832940 (0x<hex digits>)
+==
+868832940 (0x<hex digits>)
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/RandomNumberGeneration.tests.cpp" >
+          <Original>
+            rng() == 0x<hex digits>
+          </Original>
+          <Expanded>
+            570883446 (0x<hex digits>)
+==
+570883446 (0x<hex digits>)
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/RandomNumberGeneration.tests.cpp" >
+          <Original>
+            rng() == 0x<hex digits>
+          </Original>
+          <Expanded>
+            889299803 (0x<hex digits>)
+==
+889299803 (0x<hex digits>)
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/RandomNumberGeneration.tests.cpp" >
+          <Original>
+            rng() == 0x<hex digits>
+          </Original>
+          <Expanded>
+            4261393167 (0x<hex digits>)
+==
+4261393167 (0x<hex digits>)
+          </Expanded>
+        </Expression>
+        <OverallResults successes="10" failures="0" expectedFailures="0"/>
+      </Section>
+      <OverallResult success="true"/>
+    </TestCase>
     <TestCase name="Output from all sections is reported" tags="[.][failing][messages]" filename="projects/<exe-name>/UsageTests/Message.tests.cpp" >
       <Section name="one" filename="projects/<exe-name>/UsageTests/Message.tests.cpp" >
         <Failure filename="projects/<exe-name>/UsageTests/Message.tests.cpp" >
@@ -7580,46 +8421,132 @@ Nor would this
         </Expression>
         <OverallResults successes="5" failures="0" expectedFailures="0"/>
       </Section>
-      <OverallResult success="true"/>
-    </TestCase>
-    <TestCase name="Pointers can be compared to null" filename="projects/<exe-name>/UsageTests/Condition.tests.cpp" >
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Condition.tests.cpp" >
-        <Original>
-          p == 0
-        </Original>
-        <Expanded>
-          0 == 0
-        </Expanded>
-      </Expression>
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Condition.tests.cpp" >
-        <Original>
-          p == pNULL
-        </Original>
-        <Expanded>
-          0 == 0
-        </Expanded>
-      </Expression>
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Condition.tests.cpp" >
-        <Original>
-          p != 0
-        </Original>
-        <Expanded>
-          0x<hex digits> != 0
-        </Expanded>
-      </Expression>
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Condition.tests.cpp" >
-        <Original>
-          cp != 0
-        </Original>
-        <Expanded>
-          0x<hex digits> != 0
-        </Expanded>
-      </Expression>
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Condition.tests.cpp" >
-        <Original>
-          cpc != 0
-        </Original>
-        <Expanded>
+      <Section name="Leading and trailing spaces in test spec" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
+          <Original>
+            spec.matches( fakeTestCase( "  aardvark " ) )
+          </Original>
+          <Expanded>
+            true
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
+          <Original>
+            spec.matches( fakeTestCase( "  aardvark" ) )
+          </Original>
+          <Expanded>
+            true
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
+          <Original>
+            spec.matches( fakeTestCase( " aardvark " ) )
+          </Original>
+          <Expanded>
+            true
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
+          <Original>
+            spec.matches( fakeTestCase( "aardvark " ) )
+          </Original>
+          <Expanded>
+            true
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
+          <Original>
+            spec.matches( fakeTestCase( "aardvark" ) )
+          </Original>
+          <Expanded>
+            true
+          </Expanded>
+        </Expression>
+        <OverallResults successes="5" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="Leading and trailing spaces in test name" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
+          <Original>
+            spec.matches( fakeTestCase( "  aardvark " ) )
+          </Original>
+          <Expanded>
+            true
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
+          <Original>
+            spec.matches( fakeTestCase( "  aardvark" ) )
+          </Original>
+          <Expanded>
+            true
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
+          <Original>
+            spec.matches( fakeTestCase( " aardvark " ) )
+          </Original>
+          <Expanded>
+            true
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
+          <Original>
+            spec.matches( fakeTestCase( "aardvark " ) )
+          </Original>
+          <Expanded>
+            true
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
+          <Original>
+            spec.matches( fakeTestCase( "aardvark" ) )
+          </Original>
+          <Expanded>
+            true
+          </Expanded>
+        </Expression>
+        <OverallResults successes="5" failures="0" expectedFailures="0"/>
+      </Section>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="Pointers can be compared to null" filename="projects/<exe-name>/UsageTests/Condition.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Condition.tests.cpp" >
+        <Original>
+          p == 0
+        </Original>
+        <Expanded>
+          0 == 0
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Condition.tests.cpp" >
+        <Original>
+          p == pNULL
+        </Original>
+        <Expanded>
+          0 == 0
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Condition.tests.cpp" >
+        <Original>
+          p != 0
+        </Original>
+        <Expanded>
+          0x<hex digits> != 0
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Condition.tests.cpp" >
+        <Original>
+          cp != 0
+        </Original>
+        <Expanded>
+          0x<hex digits> != 0
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Condition.tests.cpp" >
+        <Original>
+          cpc != 0
+        </Original>
+        <Expanded>
           0x<hex digits> != 0
         </Expanded>
       </Expression>
@@ -7649,6 +8576,47 @@ Nor would this
       </Expression>
       <OverallResult success="true"/>
     </TestCase>
+    <TestCase name="Precision of floating point stringification can be set" tags="[floatingPoint][toString]" filename="projects/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
+      <Section name="Floats" filename="projects/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
+          <Original>
+            str1.size() == 3 + 5
+          </Original>
+          <Expanded>
+            8 == 8
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
+          <Original>
+            str2.size() == 3 + 10
+          </Original>
+          <Expanded>
+            13 == 13
+          </Expanded>
+        </Expression>
+        <OverallResults successes="2" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="Double" filename="projects/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
+          <Original>
+            str1.size() == 2 + 5
+          </Original>
+          <Expanded>
+            7 == 7
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
+          <Original>
+            str2.size() == 2 + 15
+          </Original>
+          <Expanded>
+            17 == 17
+          </Expanded>
+        </Expression>
+        <OverallResults successes="2" failures="0" expectedFailures="0"/>
+      </Section>
+      <OverallResult success="true"/>
+    </TestCase>
     <TestCase name="Predicate matcher can accept const char*" tags="[compilation][matchers]" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
       <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
         <Original>
@@ -8301,6 +9269,94 @@ Nor would this
         </Section>
         <OverallResults successes="2" failures="0" expectedFailures="0"/>
       </Section>
+      <Section name="Benchmark options" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
+        <Section name="samples" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
+          <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
+            <Original>
+              cli.parse({ "test", "--benchmark-samples=200" })
+            </Original>
+            <Expanded>
+              {?}
+            </Expanded>
+          </Expression>
+          <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
+            <Original>
+              config.benchmarkSamples == 200
+            </Original>
+            <Expanded>
+              200 == 200
+            </Expanded>
+          </Expression>
+          <OverallResults successes="2" failures="0" expectedFailures="0"/>
+        </Section>
+        <OverallResults successes="2" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="Benchmark options" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
+        <Section name="resamples" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
+          <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
+            <Original>
+              cli.parse({ "test", "--benchmark-resamples=20000" })
+            </Original>
+            <Expanded>
+              {?}
+            </Expanded>
+          </Expression>
+          <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
+            <Original>
+              config.benchmarkResamples == 20000
+            </Original>
+            <Expanded>
+              20000 (0x<hex digits>) == 20000 (0x<hex digits>)
+            </Expanded>
+          </Expression>
+          <OverallResults successes="2" failures="0" expectedFailures="0"/>
+        </Section>
+        <OverallResults successes="2" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="Benchmark options" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
+        <Section name="resamples" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
+          <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
+            <Original>
+              cli.parse({ "test", "--benchmark-confidence-interval=0.99" })
+            </Original>
+            <Expanded>
+              {?}
+            </Expanded>
+          </Expression>
+          <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
+            <Original>
+              config.benchmarkConfidenceInterval == Catch::Detail::Approx(0.99)
+            </Original>
+            <Expanded>
+              0.99 == Approx( 0.99 )
+            </Expanded>
+          </Expression>
+          <OverallResults successes="2" failures="0" expectedFailures="0"/>
+        </Section>
+        <OverallResults successes="2" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="Benchmark options" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
+        <Section name="resamples" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
+          <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
+            <Original>
+              cli.parse({ "test", "--benchmark-no-analysis" })
+            </Original>
+            <Expanded>
+              {?}
+            </Expanded>
+          </Expression>
+          <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
+            <Original>
+              config.benchmarkNoAnalysis
+            </Original>
+            <Expanded>
+              true
+            </Expanded>
+          </Expression>
+          <OverallResults successes="2" failures="0" expectedFailures="0"/>
+        </Section>
+        <OverallResults successes="2" failures="0" expectedFailures="0"/>
+      </Section>
       <OverallResult success="true"/>
     </TestCase>
     <TestCase name="Product with differing arities - std::tuple&lt;int, double, float>" tags="[product][template]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
@@ -8632,14 +9688,6 @@ A string sent to stderr via clog
           Approx( 1.23 ) != 1.24
         </Expanded>
       </Expression>
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
-        <Original>
-          INFINITY == Approx(INFINITY)
-        </Original>
-        <Expanded>
-          inff == Approx( inf )
-        </Expanded>
-      </Expression>
       <OverallResult success="true"/>
     </TestCase>
     <TestCase name="Standard output from all sections is reported" tags="[.][messages]" filename="projects/<exe-name>/UsageTests/Message.tests.cpp" >
@@ -8895,14 +9943,6 @@ Message from section two
             false == false
           </Expanded>
         </Expression>
-        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
-          <Original>
-            isSubstring( original ) == false
-          </Original>
-          <Expanded>
-            false == false
-          </Expanded>
-        </Expression>
         <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
           <Original>
             isOwned( original )
@@ -8911,7 +9951,7 @@ Message from section two
             true
           </Expanded>
         </Expression>
-        <OverallResults successes="5" failures="0" expectedFailures="0"/>
+        <OverallResults successes="4" failures="0" expectedFailures="0"/>
       </Section>
       <Section name="Substrings" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
         <Section name="zero-based substring" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
@@ -8987,37 +10027,48 @@ Message from section two
           </Expression>
           <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
             <Original>
-              isSubstring( ss ) == false
+              isOwned( ss )
             </Original>
             <Expanded>
-              false == false
+              true
             </Expanded>
           </Expression>
+          <Section name="Self-assignment after substring" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
+            <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
+              <Original>
+                isOwned(ss) == false
+              </Original>
+              <Expanded>
+                false == false
+              </Expanded>
+            </Expression>
+            <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
+              <Original>
+                ss == "hello"
+              </Original>
+              <Expanded>
+                hello == "hello"
+              </Expanded>
+            </Expression>
+            <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
+              <Original>
+                rawChars == ss.currentData()
+              </Original>
+              <Expanded>
+                "hello world!" == "hello world!"
+              </Expanded>
+            </Expression>
+            <OverallResults successes="3" failures="0" expectedFailures="0"/>
+          </Section>
+          <OverallResults successes="8" failures="0" expectedFailures="0"/>
+        </Section>
+        <OverallResults successes="8" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="Substrings" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
+        <Section name="non-zero-based substring" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
           <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
             <Original>
-              isOwned( ss )
-            </Original>
-            <Expanded>
-              true
-            </Expanded>
-          </Expression>
-          <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
-            <Original>
-              ss.currentData() != s.currentData()
-            </Original>
-            <Expanded>
-              "hello" != "hello world!"
-            </Expanded>
-          </Expression>
-          <OverallResults successes="7" failures="0" expectedFailures="0"/>
-        </Section>
-        <OverallResults successes="7" failures="0" expectedFailures="0"/>
-      </Section>
-      <Section name="Substrings" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
-        <Section name="non-zero-based substring" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
-          <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
-            <Original>
-              ss.size() == 6
+              ss.size() == 6
             </Original>
             <Expanded>
               6 == 6
@@ -9063,6 +10114,20 @@ Message from section two
         </Section>
         <OverallResults successes="1" failures="0" expectedFailures="0"/>
       </Section>
+      <Section name="Substrings" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
+        <Section name="Past the end substring" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
+          <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
+            <Original>
+              s.substr(s.size() + 1, 123).empty()
+            </Original>
+            <Expanded>
+              true
+            </Expanded>
+          </Expression>
+          <OverallResults successes="1" failures="0" expectedFailures="0"/>
+        </Section>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
       <Section name="Comparisons" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
         <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
           <Original>
@@ -9148,28 +10213,6 @@ Message from section two
         </Section>
         <OverallResults successes="2" failures="0" expectedFailures="0"/>
       </Section>
-      <Section name="to std::string" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
-        <Section name="implicitly constructed" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
-          <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
-            <Original>
-              stdStr == "a stringref"
-            </Original>
-            <Expanded>
-              "a stringref" == "a stringref"
-            </Expanded>
-          </Expression>
-          <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
-            <Original>
-              stdStr.size() == sr.size()
-            </Original>
-            <Expanded>
-              11 == 11
-            </Expanded>
-          </Expression>
-          <OverallResults successes="2" failures="0" expectedFailures="0"/>
-        </Section>
-        <OverallResults successes="2" failures="0" expectedFailures="0"/>
-      </Section>
       <Section name="to std::string" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
         <Section name="explicitly constructed" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
           <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
@@ -9214,33 +10257,6 @@ Message from section two
         </Section>
         <OverallResults successes="2" failures="0" expectedFailures="0"/>
       </Section>
-      <Section name="Counting utf-8 codepoints" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
-        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
-          <Original>
-            ascii.numberOfCharacters() == ascii.size()
-          </Original>
-          <Expanded>
-            39 == 39
-          </Expanded>
-        </Expression>
-        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
-          <Original>
-            simpleu8.numberOfCharacters() == 30
-          </Original>
-          <Expanded>
-            30 == 30
-          </Expanded>
-        </Expression>
-        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
-          <Original>
-            emojis.numberOfCharacters() == 9
-          </Original>
-          <Expanded>
-            9 == 9
-          </Expanded>
-        </Expression>
-        <OverallResults successes="3" failures="0" expectedFailures="0"/>
-      </Section>
       <OverallResult success="true"/>
     </TestCase>
     <TestCase name="Stringifying std::chrono::duration helpers" tags="[chrono][toString]" filename="projects/<exe-name>/UsageTests/ToStringChrono.tests.cpp" >
@@ -9409,6 +10425,116 @@ Message from section two
       </Section>
       <OverallResult success="true"/>
     </TestCase>
+    <TestCase name="Template test case method with test types specified inside std::tuple - MyTypes - 0" tags="[class][list][template]" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+        <Original>
+          Template_Fixture&lt;TestType>::m_a == 1
+        </Original>
+        <Expanded>
+          1 == 1
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="Template test case method with test types specified inside std::tuple - MyTypes - 1" tags="[class][list][template]" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+        <Original>
+          Template_Fixture&lt;TestType>::m_a == 1
+        </Original>
+        <Expanded>
+          1 == 1
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="Template test case method with test types specified inside std::tuple - MyTypes - 2" tags="[class][list][template]" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+        <Original>
+          Template_Fixture&lt;TestType>::m_a == 1
+        </Original>
+        <Expanded>
+          1.0 == 1
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="Template test case with test types specified inside non-copyable and non-movable std::tuple - NonCopyableAndNonMovableTypes - 0" tags="[list][template]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Original>
+          sizeof(TestType) > 0
+        </Original>
+        <Expanded>
+          1 > 0
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="Template test case with test types specified inside non-copyable and non-movable std::tuple - NonCopyableAndNonMovableTypes - 1" tags="[list][template]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Original>
+          sizeof(TestType) > 0
+        </Original>
+        <Expanded>
+          4 > 0
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="Template test case with test types specified inside non-default-constructible std::tuple - MyNonDefaultConstructibleTypes - 0" tags="[list][template]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Original>
+          sizeof(TestType) > 0
+        </Original>
+        <Expanded>
+          1 > 0
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="Template test case with test types specified inside non-default-constructible std::tuple - MyNonDefaultConstructibleTypes - 1" tags="[list][template]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Original>
+          sizeof(TestType) > 0
+        </Original>
+        <Expanded>
+          4 > 0
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="Template test case with test types specified inside std::tuple - MyTypes - 0" tags="[list][template]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Original>
+          sizeof(TestType) > 0
+        </Original>
+        <Expanded>
+          4 > 0
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="Template test case with test types specified inside std::tuple - MyTypes - 1" tags="[list][template]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Original>
+          sizeof(TestType) > 0
+        </Original>
+        <Expanded>
+          1 > 0
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="Template test case with test types specified inside std::tuple - MyTypes - 2" tags="[list][template]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Original>
+          sizeof(TestType) > 0
+        </Original>
+        <Expanded>
+          4 > 0
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
     <TestCase name="TemplateTest: vectors can be sized and resized - float" tags="[template][vector]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
       <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
         <Original>
@@ -9609,10 +10735,626 @@ Message from section two
       </Expression>
       <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
         <Original>
-          v.capacity() >= 5
+          v.capacity() >= 5
+        </Original>
+        <Expanded>
+          5 >= 5
+        </Expanded>
+      </Expression>
+      <Section name="resizing smaller changes size but not capacity" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            v.size() == 0
+          </Original>
+          <Expanded>
+            0 == 0
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            v.capacity() >= 5
+          </Original>
+          <Expanded>
+            5 >= 5
+          </Expanded>
+        </Expression>
+        <Section name="We can use the 'swap trick' to reset the capacity" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+            <Original>
+              v.capacity() == 0
+            </Original>
+            <Expanded>
+              0 == 0
+            </Expanded>
+          </Expression>
+          <OverallResults successes="1" failures="0" expectedFailures="0"/>
+        </Section>
+        <OverallResults successes="3" failures="0" expectedFailures="0"/>
+      </Section>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Original>
+          v.size() == 5
+        </Original>
+        <Expanded>
+          5 == 5
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Original>
+          v.capacity() >= 5
+        </Original>
+        <Expanded>
+          5 >= 5
+        </Expanded>
+      </Expression>
+      <Section name="reserving bigger changes capacity but not size" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            v.size() == 5
+          </Original>
+          <Expanded>
+            5 == 5
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            v.capacity() >= 10
+          </Original>
+          <Expanded>
+            10 >= 10
+          </Expanded>
+        </Expression>
+        <OverallResults successes="2" failures="0" expectedFailures="0"/>
+      </Section>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Original>
+          v.size() == 5
+        </Original>
+        <Expanded>
+          5 == 5
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Original>
+          v.capacity() >= 5
+        </Original>
+        <Expanded>
+          5 >= 5
+        </Expanded>
+      </Expression>
+      <Section name="reserving smaller does not change size or capacity" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            v.size() == 5
+          </Original>
+          <Expanded>
+            5 == 5
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            v.capacity() >= 5
+          </Original>
+          <Expanded>
+            5 >= 5
+          </Expanded>
+        </Expression>
+        <OverallResults successes="2" failures="0" expectedFailures="0"/>
+      </Section>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="TemplateTest: vectors can be sized and resized - std::string" tags="[template][vector]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Original>
+          v.size() == 5
+        </Original>
+        <Expanded>
+          5 == 5
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Original>
+          v.capacity() >= 5
+        </Original>
+        <Expanded>
+          5 >= 5
+        </Expanded>
+      </Expression>
+      <Section name="resizing bigger changes size and capacity" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            v.size() == 10
+          </Original>
+          <Expanded>
+            10 == 10
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            v.capacity() >= 10
+          </Original>
+          <Expanded>
+            10 >= 10
+          </Expanded>
+        </Expression>
+        <OverallResults successes="2" failures="0" expectedFailures="0"/>
+      </Section>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Original>
+          v.size() == 5
+        </Original>
+        <Expanded>
+          5 == 5
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Original>
+          v.capacity() >= 5
+        </Original>
+        <Expanded>
+          5 >= 5
+        </Expanded>
+      </Expression>
+      <Section name="resizing smaller changes size but not capacity" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            v.size() == 0
+          </Original>
+          <Expanded>
+            0 == 0
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            v.capacity() >= 5
+          </Original>
+          <Expanded>
+            5 >= 5
+          </Expanded>
+        </Expression>
+        <Section name="We can use the 'swap trick' to reset the capacity" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+            <Original>
+              v.capacity() == 0
+            </Original>
+            <Expanded>
+              0 == 0
+            </Expanded>
+          </Expression>
+          <OverallResults successes="1" failures="0" expectedFailures="0"/>
+        </Section>
+        <OverallResults successes="3" failures="0" expectedFailures="0"/>
+      </Section>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Original>
+          v.size() == 5
+        </Original>
+        <Expanded>
+          5 == 5
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Original>
+          v.capacity() >= 5
+        </Original>
+        <Expanded>
+          5 >= 5
+        </Expanded>
+      </Expression>
+      <Section name="reserving bigger changes capacity but not size" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            v.size() == 5
+          </Original>
+          <Expanded>
+            5 == 5
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            v.capacity() >= 10
+          </Original>
+          <Expanded>
+            10 >= 10
+          </Expanded>
+        </Expression>
+        <OverallResults successes="2" failures="0" expectedFailures="0"/>
+      </Section>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Original>
+          v.size() == 5
+        </Original>
+        <Expanded>
+          5 == 5
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Original>
+          v.capacity() >= 5
+        </Original>
+        <Expanded>
+          5 >= 5
+        </Expanded>
+      </Expression>
+      <Section name="reserving smaller does not change size or capacity" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            v.size() == 5
+          </Original>
+          <Expanded>
+            5 == 5
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            v.capacity() >= 5
+          </Original>
+          <Expanded>
+            5 >= 5
+          </Expanded>
+        </Expression>
+        <OverallResults successes="2" failures="0" expectedFailures="0"/>
+      </Section>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="TemplateTest: vectors can be sized and resized - std::tuple&lt;int,float>" tags="[template][vector]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Original>
+          v.size() == 5
+        </Original>
+        <Expanded>
+          5 == 5
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Original>
+          v.capacity() >= 5
+        </Original>
+        <Expanded>
+          5 >= 5
+        </Expanded>
+      </Expression>
+      <Section name="resizing bigger changes size and capacity" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            v.size() == 10
+          </Original>
+          <Expanded>
+            10 == 10
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            v.capacity() >= 10
+          </Original>
+          <Expanded>
+            10 >= 10
+          </Expanded>
+        </Expression>
+        <OverallResults successes="2" failures="0" expectedFailures="0"/>
+      </Section>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Original>
+          v.size() == 5
+        </Original>
+        <Expanded>
+          5 == 5
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Original>
+          v.capacity() >= 5
+        </Original>
+        <Expanded>
+          5 >= 5
+        </Expanded>
+      </Expression>
+      <Section name="resizing smaller changes size but not capacity" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            v.size() == 0
+          </Original>
+          <Expanded>
+            0 == 0
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            v.capacity() >= 5
+          </Original>
+          <Expanded>
+            5 >= 5
+          </Expanded>
+        </Expression>
+        <Section name="We can use the 'swap trick' to reset the capacity" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+            <Original>
+              v.capacity() == 0
+            </Original>
+            <Expanded>
+              0 == 0
+            </Expanded>
+          </Expression>
+          <OverallResults successes="1" failures="0" expectedFailures="0"/>
+        </Section>
+        <OverallResults successes="3" failures="0" expectedFailures="0"/>
+      </Section>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Original>
+          v.size() == 5
+        </Original>
+        <Expanded>
+          5 == 5
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Original>
+          v.capacity() >= 5
+        </Original>
+        <Expanded>
+          5 >= 5
+        </Expanded>
+      </Expression>
+      <Section name="reserving bigger changes capacity but not size" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            v.size() == 5
+          </Original>
+          <Expanded>
+            5 == 5
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            v.capacity() >= 10
+          </Original>
+          <Expanded>
+            10 >= 10
+          </Expanded>
+        </Expression>
+        <OverallResults successes="2" failures="0" expectedFailures="0"/>
+      </Section>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Original>
+          v.size() == 5
+        </Original>
+        <Expanded>
+          5 == 5
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Original>
+          v.capacity() >= 5
+        </Original>
+        <Expanded>
+          5 >= 5
+        </Expanded>
+      </Expression>
+      <Section name="reserving smaller does not change size or capacity" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            v.size() == 5
+          </Original>
+          <Expanded>
+            5 == 5
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            v.capacity() >= 5
+          </Original>
+          <Expanded>
+            5 >= 5
+          </Expanded>
+        </Expression>
+        <OverallResults successes="2" failures="0" expectedFailures="0"/>
+      </Section>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="TemplateTestSig: vectors can be sized and resized - (std::tuple&lt;int, float>), 6" tags="[nttp][template][vector]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Original>
+          v.size() == V
+        </Original>
+        <Expanded>
+          6 == 6
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Original>
+          v.capacity() >= V
+        </Original>
+        <Expanded>
+          6 >= 6
+        </Expanded>
+      </Expression>
+      <Section name="resizing bigger changes size and capacity" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            v.size() == 2 * V
+          </Original>
+          <Expanded>
+            12 == 12
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            v.capacity() >= 2 * V
+          </Original>
+          <Expanded>
+            12 >= 12
+          </Expanded>
+        </Expression>
+        <OverallResults successes="2" failures="0" expectedFailures="0"/>
+      </Section>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Original>
+          v.size() == V
+        </Original>
+        <Expanded>
+          6 == 6
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Original>
+          v.capacity() >= V
+        </Original>
+        <Expanded>
+          6 >= 6
+        </Expanded>
+      </Expression>
+      <Section name="resizing smaller changes size but not capacity" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            v.size() == 0
+          </Original>
+          <Expanded>
+            0 == 0
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            v.capacity() >= V
+          </Original>
+          <Expanded>
+            6 >= 6
+          </Expanded>
+        </Expression>
+        <Section name="We can use the 'swap trick' to reset the capacity" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+            <Original>
+              v.capacity() == 0
+            </Original>
+            <Expanded>
+              0 == 0
+            </Expanded>
+          </Expression>
+          <OverallResults successes="1" failures="0" expectedFailures="0"/>
+        </Section>
+        <OverallResults successes="3" failures="0" expectedFailures="0"/>
+      </Section>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Original>
+          v.size() == V
+        </Original>
+        <Expanded>
+          6 == 6
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Original>
+          v.capacity() >= V
+        </Original>
+        <Expanded>
+          6 >= 6
+        </Expanded>
+      </Expression>
+      <Section name="reserving bigger changes capacity but not size" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            v.size() == V
+          </Original>
+          <Expanded>
+            6 == 6
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            v.capacity() >= 2 * V
+          </Original>
+          <Expanded>
+            12 >= 12
+          </Expanded>
+        </Expression>
+        <OverallResults successes="2" failures="0" expectedFailures="0"/>
+      </Section>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Original>
+          v.size() == V
+        </Original>
+        <Expanded>
+          6 == 6
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Original>
+          v.capacity() >= V
+        </Original>
+        <Expanded>
+          6 >= 6
+        </Expanded>
+      </Expression>
+      <Section name="reserving smaller does not change size or capacity" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            v.size() == V
+          </Original>
+          <Expanded>
+            6 == 6
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            v.capacity() >= V
+          </Original>
+          <Expanded>
+            6 >= 6
+          </Expanded>
+        </Expression>
+        <OverallResults successes="2" failures="0" expectedFailures="0"/>
+      </Section>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="TemplateTestSig: vectors can be sized and resized - float,4" tags="[nttp][template][vector]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Original>
+          v.size() == V
+        </Original>
+        <Expanded>
+          4 == 4
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Original>
+          v.capacity() >= V
+        </Original>
+        <Expanded>
+          4 >= 4
+        </Expanded>
+      </Expression>
+      <Section name="resizing bigger changes size and capacity" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            v.size() == 2 * V
+          </Original>
+          <Expanded>
+            8 == 8
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            v.capacity() >= 2 * V
+          </Original>
+          <Expanded>
+            8 >= 8
+          </Expanded>
+        </Expression>
+        <OverallResults successes="2" failures="0" expectedFailures="0"/>
+      </Section>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Original>
+          v.size() == V
+        </Original>
+        <Expanded>
+          4 == 4
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Original>
+          v.capacity() >= V
         </Original>
         <Expanded>
-          5 >= 5
+          4 >= 4
         </Expanded>
       </Expression>
       <Section name="resizing smaller changes size but not capacity" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
@@ -9626,10 +11368,10 @@ Message from section two
         </Expression>
         <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
           <Original>
-            v.capacity() >= 5
+            v.capacity() >= V
           </Original>
           <Expanded>
-            5 >= 5
+            4 >= 4
           </Expanded>
         </Expression>
         <Section name="We can use the 'swap trick' to reset the capacity" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
@@ -9647,80 +11389,80 @@ Message from section two
       </Section>
       <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
         <Original>
-          v.size() == 5
+          v.size() == V
         </Original>
         <Expanded>
-          5 == 5
+          4 == 4
         </Expanded>
       </Expression>
       <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
         <Original>
-          v.capacity() >= 5
+          v.capacity() >= V
         </Original>
         <Expanded>
-          5 >= 5
+          4 >= 4
         </Expanded>
       </Expression>
       <Section name="reserving bigger changes capacity but not size" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
         <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
           <Original>
-            v.size() == 5
+            v.size() == V
           </Original>
           <Expanded>
-            5 == 5
+            4 == 4
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
           <Original>
-            v.capacity() >= 10
+            v.capacity() >= 2 * V
           </Original>
           <Expanded>
-            10 >= 10
+            8 >= 8
           </Expanded>
         </Expression>
         <OverallResults successes="2" failures="0" expectedFailures="0"/>
       </Section>
       <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
         <Original>
-          v.size() == 5
+          v.size() == V
         </Original>
         <Expanded>
-          5 == 5
+          4 == 4
         </Expanded>
       </Expression>
       <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
         <Original>
-          v.capacity() >= 5
+          v.capacity() >= V
         </Original>
         <Expanded>
-          5 >= 5
+          4 >= 4
         </Expanded>
       </Expression>
       <Section name="reserving smaller does not change size or capacity" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
         <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
           <Original>
-            v.size() == 5
+            v.size() == V
           </Original>
           <Expanded>
-            5 == 5
+            4 == 4
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
           <Original>
-            v.capacity() >= 5
+            v.capacity() >= V
           </Original>
           <Expanded>
-            5 >= 5
+            4 >= 4
           </Expanded>
         </Expression>
         <OverallResults successes="2" failures="0" expectedFailures="0"/>
       </Section>
       <OverallResult success="true"/>
     </TestCase>
-    <TestCase name="TemplateTest: vectors can be sized and resized - std::string" tags="[template][vector]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+    <TestCase name="TemplateTestSig: vectors can be sized and resized - int,5" tags="[nttp][template][vector]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
       <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
         <Original>
-          v.size() == 5
+          v.size() == V
         </Original>
         <Expanded>
           5 == 5
@@ -9728,7 +11470,7 @@ Message from section two
       </Expression>
       <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
         <Original>
-          v.capacity() >= 5
+          v.capacity() >= V
         </Original>
         <Expanded>
           5 >= 5
@@ -9737,7 +11479,7 @@ Message from section two
       <Section name="resizing bigger changes size and capacity" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
         <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
           <Original>
-            v.size() == 10
+            v.size() == 2 * V
           </Original>
           <Expanded>
             10 == 10
@@ -9745,7 +11487,7 @@ Message from section two
         </Expression>
         <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
           <Original>
-            v.capacity() >= 10
+            v.capacity() >= 2 * V
           </Original>
           <Expanded>
             10 >= 10
@@ -9755,7 +11497,7 @@ Message from section two
       </Section>
       <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
         <Original>
-          v.size() == 5
+          v.size() == V
         </Original>
         <Expanded>
           5 == 5
@@ -9763,7 +11505,7 @@ Message from section two
       </Expression>
       <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
         <Original>
-          v.capacity() >= 5
+          v.capacity() >= V
         </Original>
         <Expanded>
           5 >= 5
@@ -9780,7 +11522,7 @@ Message from section two
         </Expression>
         <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
           <Original>
-            v.capacity() >= 5
+            v.capacity() >= V
           </Original>
           <Expanded>
             5 >= 5
@@ -9801,7 +11543,7 @@ Message from section two
       </Section>
       <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
         <Original>
-          v.size() == 5
+          v.size() == V
         </Original>
         <Expanded>
           5 == 5
@@ -9809,7 +11551,7 @@ Message from section two
       </Expression>
       <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
         <Original>
-          v.capacity() >= 5
+          v.capacity() >= V
         </Original>
         <Expanded>
           5 >= 5
@@ -9818,7 +11560,7 @@ Message from section two
       <Section name="reserving bigger changes capacity but not size" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
         <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
           <Original>
-            v.size() == 5
+            v.size() == V
           </Original>
           <Expanded>
             5 == 5
@@ -9826,7 +11568,7 @@ Message from section two
         </Expression>
         <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
           <Original>
-            v.capacity() >= 10
+            v.capacity() >= 2 * V
           </Original>
           <Expanded>
             10 >= 10
@@ -9836,7 +11578,7 @@ Message from section two
       </Section>
       <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
         <Original>
-          v.size() == 5
+          v.size() == V
         </Original>
         <Expanded>
           5 == 5
@@ -9844,7 +11586,7 @@ Message from section two
       </Expression>
       <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
         <Original>
-          v.capacity() >= 5
+          v.capacity() >= V
         </Original>
         <Expanded>
           5 >= 5
@@ -9853,7 +11595,7 @@ Message from section two
       <Section name="reserving smaller does not change size or capacity" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
         <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
           <Original>
-            v.size() == 5
+            v.size() == V
           </Original>
           <Expanded>
             5 == 5
@@ -9861,7 +11603,7 @@ Message from section two
         </Expression>
         <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
           <Original>
-            v.capacity() >= 5
+            v.capacity() >= V
           </Original>
           <Expanded>
             5 >= 5
@@ -9871,56 +11613,56 @@ Message from section two
       </Section>
       <OverallResult success="true"/>
     </TestCase>
-    <TestCase name="TemplateTest: vectors can be sized and resized - std::tuple&lt;int,float>" tags="[template][vector]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+    <TestCase name="TemplateTestSig: vectors can be sized and resized - std::string,15" tags="[nttp][template][vector]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
       <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
         <Original>
-          v.size() == 5
+          v.size() == V
         </Original>
         <Expanded>
-          5 == 5
+          15 == 15
         </Expanded>
       </Expression>
       <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
         <Original>
-          v.capacity() >= 5
+          v.capacity() >= V
         </Original>
         <Expanded>
-          5 >= 5
+          15 >= 15
         </Expanded>
       </Expression>
       <Section name="resizing bigger changes size and capacity" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
         <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
           <Original>
-            v.size() == 10
+            v.size() == 2 * V
           </Original>
           <Expanded>
-            10 == 10
+            30 == 30
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
           <Original>
-            v.capacity() >= 10
+            v.capacity() >= 2 * V
           </Original>
           <Expanded>
-            10 >= 10
+            30 >= 30
           </Expanded>
         </Expression>
         <OverallResults successes="2" failures="0" expectedFailures="0"/>
       </Section>
       <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
         <Original>
-          v.size() == 5
+          v.size() == V
         </Original>
         <Expanded>
-          5 == 5
+          15 == 15
         </Expanded>
       </Expression>
       <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
         <Original>
-          v.capacity() >= 5
+          v.capacity() >= V
         </Original>
         <Expanded>
-          5 >= 5
+          15 >= 15
         </Expanded>
       </Expression>
       <Section name="resizing smaller changes size but not capacity" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
@@ -9934,10 +11676,10 @@ Message from section two
         </Expression>
         <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
           <Original>
-            v.capacity() >= 5
+            v.capacity() >= V
           </Original>
           <Expanded>
-            5 >= 5
+            15 >= 15
           </Expanded>
         </Expression>
         <Section name="We can use the 'swap trick' to reset the capacity" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
@@ -9955,70 +11697,70 @@ Message from section two
       </Section>
       <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
         <Original>
-          v.size() == 5
+          v.size() == V
         </Original>
         <Expanded>
-          5 == 5
+          15 == 15
         </Expanded>
       </Expression>
       <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
         <Original>
-          v.capacity() >= 5
+          v.capacity() >= V
         </Original>
         <Expanded>
-          5 >= 5
+          15 >= 15
         </Expanded>
       </Expression>
       <Section name="reserving bigger changes capacity but not size" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
         <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
           <Original>
-            v.size() == 5
+            v.size() == V
           </Original>
           <Expanded>
-            5 == 5
+            15 == 15
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
           <Original>
-            v.capacity() >= 10
+            v.capacity() >= 2 * V
           </Original>
           <Expanded>
-            10 >= 10
+            30 >= 30
           </Expanded>
         </Expression>
         <OverallResults successes="2" failures="0" expectedFailures="0"/>
       </Section>
       <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
         <Original>
-          v.size() == 5
+          v.size() == V
         </Original>
         <Expanded>
-          5 == 5
+          15 == 15
         </Expanded>
       </Expression>
       <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
         <Original>
-          v.capacity() >= 5
+          v.capacity() >= V
         </Original>
         <Expanded>
-          5 >= 5
+          15 >= 15
         </Expanded>
       </Expression>
       <Section name="reserving smaller does not change size or capacity" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
         <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
           <Original>
-            v.size() == 5
+            v.size() == V
           </Original>
           <Expanded>
-            5 == 5
+            15 == 15
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
           <Original>
-            v.capacity() >= 5
+            v.capacity() >= V
           </Original>
           <Expanded>
-            5 >= 5
+            15 >= 15
           </Expanded>
         </Expression>
         <OverallResults successes="2" failures="0" expectedFailures="0"/>
@@ -10039,6 +11781,9 @@ Message from section two
       </Expression>
       <OverallResult success="true"/>
     </TestCase>
+    <TestCase name="Test with special, characters &quot;in name" tags="[cli][regression]" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
+      <OverallResult success="true"/>
+    </TestCase>
     <TestCase name="The NO_FAIL macro reports a failure but does not fail the test" tags="[messages]" filename="projects/<exe-name>/UsageTests/Message.tests.cpp" >
       <Expression success="false" type="CHECK_NOFAIL" filename="projects/<exe-name>/UsageTests/Message.tests.cpp" >
         <Original>
@@ -10634,6 +12379,89 @@ Message from section two
       </Section>
       <OverallResult success="true"/>
     </TestCase>
+    <TestCase name="Trim strings" tags="[string-manip]" filename="projects/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
+        <Original>
+          trim(std::string(no_whitespace)) == no_whitespace
+        </Original>
+        <Expanded>
+          "There is no extra whitespace here"
+==
+"There is no extra whitespace here"
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
+        <Original>
+          trim(std::string(leading_whitespace)) == no_whitespace
+        </Original>
+        <Expanded>
+          "There is no extra whitespace here"
+==
+"There is no extra whitespace here"
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
+        <Original>
+          trim(std::string(trailing_whitespace)) == no_whitespace
+        </Original>
+        <Expanded>
+          "There is no extra whitespace here"
+==
+"There is no extra whitespace here"
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
+        <Original>
+          trim(std::string(whitespace_at_both_ends)) == no_whitespace
+        </Original>
+        <Expanded>
+          "There is no extra whitespace here"
+==
+"There is no extra whitespace here"
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
+        <Original>
+          trim(StringRef(no_whitespace)) == StringRef(no_whitespace)
+        </Original>
+        <Expanded>
+          There is no extra whitespace here
+==
+There is no extra whitespace here
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
+        <Original>
+          trim(StringRef(leading_whitespace)) == StringRef(no_whitespace)
+        </Original>
+        <Expanded>
+          There is no extra whitespace here
+==
+There is no extra whitespace here
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
+        <Original>
+          trim(StringRef(trailing_whitespace)) == StringRef(no_whitespace)
+        </Original>
+        <Expanded>
+          There is no extra whitespace here
+==
+There is no extra whitespace here
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
+        <Original>
+          trim(StringRef(whitespace_at_both_ends)) == StringRef(no_whitespace)
+        </Original>
+        <Expanded>
+          There is no extra whitespace here
+==
+There is no extra whitespace here
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
     <TestCase name="Unexpected exceptions can be translated" tags="[!throws][.][failing]" filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" >
       <Exception filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" >
         3.14
@@ -10713,6 +12541,111 @@ Message from section two
       </Section>
       <OverallResult success="true"/>
     </TestCase>
+    <TestCase name="Vector Approx matcher" tags="[approx][matchers][vector]" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+      <Section name="Empty vector is roughly equal to an empty vector" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            empty, Approx(empty)
+          </Original>
+          <Expanded>
+            {  } is approx: {  }
+          </Expanded>
+        </Expression>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="Vectors with elements" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Section name="A vector is approx equal to itself" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+            <Original>
+              v1, Approx(v1)
+            </Original>
+            <Expanded>
+              { 1.0, 2.0, 3.0 } is approx: { 1.0, 2.0, 3.0 }
+            </Expanded>
+          </Expression>
+          <OverallResults successes="1" failures="0" expectedFailures="0"/>
+        </Section>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="Vectors with elements" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Section name="Different length" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+            <Original>
+              v1, !Approx(temp)
+            </Original>
+            <Expanded>
+              { 1.0, 2.0, 3.0 } not is approx: { 1.0, 2.0, 3.0, 4.0 }
+            </Expanded>
+          </Expression>
+          <OverallResults successes="1" failures="0" expectedFailures="0"/>
+        </Section>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="Vectors with elements" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Section name="Same length, different elements" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+            <Original>
+              v1, !Approx(v2)
+            </Original>
+            <Expanded>
+              { 1.0, 2.0, 3.0 } not is approx: { 1.5, 2.5, 3.5 }
+            </Expanded>
+          </Expression>
+          <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+            <Original>
+              v1, Approx(v2).margin(0.5)
+            </Original>
+            <Expanded>
+              { 1.0, 2.0, 3.0 } is approx: { 1.5, 2.5, 3.5 }
+            </Expanded>
+          </Expression>
+          <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+            <Original>
+              v1, Approx(v2).epsilon(0.5)
+            </Original>
+            <Expanded>
+              { 1.0, 2.0, 3.0 } is approx: { 1.5, 2.5, 3.5 }
+            </Expanded>
+          </Expression>
+          <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+            <Original>
+              v1, Approx(v2).epsilon(0.1).scale(500)
+            </Original>
+            <Expanded>
+              { 1.0, 2.0, 3.0 } is approx: { 1.5, 2.5, 3.5 }
+            </Expanded>
+          </Expression>
+          <OverallResults successes="4" failures="0" expectedFailures="0"/>
+        </Section>
+        <OverallResults successes="4" failures="0" expectedFailures="0"/>
+      </Section>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="Vector Approx matcher -- failing" tags="[.][approx][failing][matchers][vector]" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+      <Section name="Empty and non empty vectors are not approx equal" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="false" type="CHECK_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            empty, Approx(t1)
+          </Original>
+          <Expanded>
+            {  } is approx: { 1.0, 2.0 }
+          </Expanded>
+        </Expression>
+        <OverallResults successes="0" failures="1" expectedFailures="0"/>
+      </Section>
+      <Section name="Just different vectors" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="false" type="CHECK_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            v1, Approx(v2)
+          </Original>
+          <Expanded>
+            { 2.0, 4.0, 6.0 } is approx: { 1.0, 3.0, 5.0 }
+          </Expanded>
+        </Expression>
+        <OverallResults successes="0" failures="1" expectedFailures="0"/>
+      </Section>
+      <OverallResult success="false"/>
+    </TestCase>
     <TestCase name="Vector matchers" tags="[matchers][vector]" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
       <Section name="Contains (element)" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
         <Expression success="true" type="CHECK_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
@@ -12208,6 +14141,74 @@ loose text artifact
       </Expression>
       <OverallResult success="true"/>
     </TestCase>
+    <TestCase name="parseEnums" tags="[Strings][enums]" filename="projects/<exe-name>/IntrospectiveTests/ToString.tests.cpp" >
+      <Section name="No enums" filename="projects/<exe-name>/IntrospectiveTests/ToString.tests.cpp" >
+        <Expression success="true" type="CHECK_THAT" filename="projects/<exe-name>/IntrospectiveTests/ToString.tests.cpp" >
+          <Original>
+            parseEnums( "" ), Equals( std::vector&lt;Catch::StringRef>{} )
+          </Original>
+          <Expanded>
+            {  } Equals: {  }
+          </Expanded>
+        </Expression>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="One enum value" filename="projects/<exe-name>/IntrospectiveTests/ToString.tests.cpp" >
+        <Expression success="true" type="CHECK_THAT" filename="projects/<exe-name>/IntrospectiveTests/ToString.tests.cpp" >
+          <Original>
+            parseEnums( "ClassName::EnumName::Value1" ), Equals(std::vector&lt;Catch::StringRef>{"Value1"} )
+          </Original>
+          <Expanded>
+            { Value1 } Equals: { Value1 }
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="CHECK_THAT" filename="projects/<exe-name>/IntrospectiveTests/ToString.tests.cpp" >
+          <Original>
+            parseEnums( "Value1" ), Equals( std::vector&lt;Catch::StringRef>{"Value1"} )
+          </Original>
+          <Expanded>
+            { Value1 } Equals: { Value1 }
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="CHECK_THAT" filename="projects/<exe-name>/IntrospectiveTests/ToString.tests.cpp" >
+          <Original>
+            parseEnums( "EnumName::Value1" ), Equals(std::vector&lt;Catch::StringRef>{"Value1"} )
+          </Original>
+          <Expanded>
+            { Value1 } Equals: { Value1 }
+          </Expanded>
+        </Expression>
+        <OverallResults successes="3" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="Multiple enum values" filename="projects/<exe-name>/IntrospectiveTests/ToString.tests.cpp" >
+        <Expression success="true" type="CHECK_THAT" filename="projects/<exe-name>/IntrospectiveTests/ToString.tests.cpp" >
+          <Original>
+            parseEnums( "ClassName::EnumName::Value1, ClassName::EnumName::Value2" ), Equals( std::vector&lt;Catch::StringRef>{"Value1", "Value2"} )
+          </Original>
+          <Expanded>
+            { Value1, Value2 } Equals: { Value1, Value2 }
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="CHECK_THAT" filename="projects/<exe-name>/IntrospectiveTests/ToString.tests.cpp" >
+          <Original>
+            parseEnums( "ClassName::EnumName::Value1, ClassName::EnumName::Value2, ClassName::EnumName::Value3" ), Equals( std::vector&lt;Catch::StringRef>{"Value1", "Value2", "Value3"} )
+          </Original>
+          <Expanded>
+            { Value1, Value2, Value3 } Equals: { Value1, Value2, Value3 }
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="CHECK_THAT" filename="projects/<exe-name>/IntrospectiveTests/ToString.tests.cpp" >
+          <Original>
+            parseEnums( "ClassName::EnumName::Value1,ClassName::EnumName::Value2 , ClassName::EnumName::Value3" ), Equals( std::vector&lt;Catch::StringRef>{"Value1", "Value2", "Value3"} )
+          </Original>
+          <Expanded>
+            { Value1, Value2, Value3 } Equals: { Value1, Value2, Value3 }
+          </Expanded>
+        </Expression>
+        <OverallResults successes="3" failures="0" expectedFailures="0"/>
+      </Section>
+      <OverallResult success="true"/>
+    </TestCase>
     <TestCase name="pointer to class" tags="[Tricky]" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
       <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
         <Original>
@@ -12324,17 +14325,17 @@ loose text artifact
       </Section>
       <OverallResult success="true"/>
     </TestCase>
-    <TestCase name="replaceInPlace" tags="[StringManip][Strings]" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
-      <Section name="replace single char" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
-        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
+    <TestCase name="replaceInPlace" tags="[string-manip]" filename="projects/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
+      <Section name="replace single char" filename="projects/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
           <Original>
-            Catch::replaceInPlace( letters, "b", "z" )
+            Catch::replaceInPlace(letters, "b", "z")
           </Original>
           <Expanded>
             true
           </Expanded>
         </Expression>
-        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
           <Original>
             letters == "azcdefcg"
           </Original>
@@ -12344,16 +14345,16 @@ loose text artifact
         </Expression>
         <OverallResults successes="2" failures="0" expectedFailures="0"/>
       </Section>
-      <Section name="replace two chars" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
-        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
+      <Section name="replace two chars" filename="projects/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
           <Original>
-            Catch::replaceInPlace( letters, "c", "z" )
+            Catch::replaceInPlace(letters, "c", "z")
           </Original>
           <Expanded>
             true
           </Expanded>
         </Expression>
-        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
           <Original>
             letters == "abzdefzg"
           </Original>
@@ -12363,16 +14364,16 @@ loose text artifact
         </Expression>
         <OverallResults successes="2" failures="0" expectedFailures="0"/>
       </Section>
-      <Section name="replace first char" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
-        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
+      <Section name="replace first char" filename="projects/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
           <Original>
-            Catch::replaceInPlace( letters, "a", "z" )
+            Catch::replaceInPlace(letters, "a", "z")
           </Original>
           <Expanded>
             true
           </Expanded>
         </Expression>
-        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
           <Original>
             letters == "zbcdefcg"
           </Original>
@@ -12382,16 +14383,16 @@ loose text artifact
         </Expression>
         <OverallResults successes="2" failures="0" expectedFailures="0"/>
       </Section>
-      <Section name="replace last char" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
-        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
+      <Section name="replace last char" filename="projects/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
           <Original>
-            Catch::replaceInPlace( letters, "g", "z" )
+            Catch::replaceInPlace(letters, "g", "z")
           </Original>
           <Expanded>
             true
           </Expanded>
         </Expression>
-        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
           <Original>
             letters == "abcdefcz"
           </Original>
@@ -12401,16 +14402,16 @@ loose text artifact
         </Expression>
         <OverallResults successes="2" failures="0" expectedFailures="0"/>
       </Section>
-      <Section name="replace all chars" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
-        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
+      <Section name="replace all chars" filename="projects/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
           <Original>
-            Catch::replaceInPlace( letters, letters, "replaced" )
+            Catch::replaceInPlace(letters, letters, "replaced")
           </Original>
           <Expanded>
             true
           </Expanded>
         </Expression>
-        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
           <Original>
             letters == "replaced"
           </Original>
@@ -12420,16 +14421,16 @@ loose text artifact
         </Expression>
         <OverallResults successes="2" failures="0" expectedFailures="0"/>
       </Section>
-      <Section name="replace no chars" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
-        <Expression success="true" type="CHECK_FALSE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
+      <Section name="replace no chars" filename="projects/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
+        <Expression success="true" type="CHECK_FALSE" filename="projects/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
           <Original>
-            !(Catch::replaceInPlace( letters, "x", "z" ))
+            !(Catch::replaceInPlace(letters, "x", "z"))
           </Original>
           <Expanded>
             !false
           </Expanded>
         </Expression>
-        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
           <Original>
             letters == letters
           </Original>
@@ -12439,16 +14440,16 @@ loose text artifact
         </Expression>
         <OverallResults successes="2" failures="0" expectedFailures="0"/>
       </Section>
-      <Section name="escape '" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
-        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
+      <Section name="escape '" filename="projects/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
           <Original>
-            Catch::replaceInPlace( s, "'", "|'" )
+            Catch::replaceInPlace(s, "'", "|'")
           </Original>
           <Expanded>
             true
           </Expanded>
         </Expression>
-        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
           <Original>
             s == "didn|'t"
           </Original>
@@ -12505,6 +14506,33 @@ loose text artifact
       </Expression>
       <OverallResult success="true"/>
     </TestCase>
+    <TestCase name="splitString" tags="[string-manip]" filename="projects/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
+      <Expression success="true" type="CHECK_THAT" filename="projects/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
+        <Original>
+          splitStringRef("", ','), Equals(std::vector&lt;StringRef>())
+        </Original>
+        <Expanded>
+          {  } Equals: {  }
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK_THAT" filename="projects/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
+        <Original>
+          splitStringRef("abc", ','), Equals(std::vector&lt;StringRef>{"abc"})
+        </Original>
+        <Expanded>
+          { abc } Equals: { abc }
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK_THAT" filename="projects/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
+        <Original>
+          splitStringRef("abc,def", ','), Equals(std::vector&lt;StringRef>{"abc", "def"})
+        </Original>
+        <Expanded>
+          { abc, def } Equals: { abc, def }
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
     <TestCase name="stacks unscoped info in loops" tags="[.][failing][info][unscoped]" filename="projects/<exe-name>/UsageTests/Message.tests.cpp" >
       <Info>
         Count 1 to 3...
@@ -13399,7 +15427,7 @@ loose text artifact
       </Section>
       <OverallResult success="true"/>
     </TestCase>
-    <OverallResults successes="1276" failures="140" expectedFailures="21"/>
+    <OverallResults successes="1469" failures="149" expectedFailures="21"/>
   </Group>
-  <OverallResults successes="1276" failures="139" expectedFailures="21"/>
+  <OverallResults successes="1469" failures="148" expectedFailures="21"/>
 </Catch>
diff --git a/packages/Catch2/projects/SelfTest/IntrospectiveTests/CmdLine.tests.cpp b/packages/Catch2/projects/SelfTest/IntrospectiveTests/CmdLine.tests.cpp
index 9b5b0ed7c..60eb97af9 100644
--- a/packages/Catch2/projects/SelfTest/IntrospectiveTests/CmdLine.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/IntrospectiveTests/CmdLine.tests.cpp
@@ -262,7 +262,24 @@ TEST_CASE( "Parse test names and tags" ) {
         CHECK( spec.matches( tcC ) == false );
         CHECK( spec.matches( tcD ) == true );
     }
+    SECTION( "Leading and trailing spaces in test spec" ) {
+        TestSpec spec = parseTestSpec( "\"  aardvark \"" );
+        CHECK( spec.matches( fakeTestCase( "  aardvark " ) ) );
+        CHECK( spec.matches( fakeTestCase( "  aardvark" ) ) );
+        CHECK( spec.matches( fakeTestCase( " aardvark " ) ) );
+        CHECK( spec.matches( fakeTestCase( "aardvark " ) ) );
+        CHECK( spec.matches( fakeTestCase( "aardvark" ) ) );
 
+    }
+    SECTION( "Leading and trailing spaces in test name" ) {
+        TestSpec spec = parseTestSpec( "aardvark" );
+        CHECK( spec.matches( fakeTestCase( "  aardvark " ) ) );
+        CHECK( spec.matches( fakeTestCase( "  aardvark" ) ) );
+        CHECK( spec.matches( fakeTestCase( " aardvark " ) ) );
+        CHECK( spec.matches( fakeTestCase( "aardvark " ) ) );
+        CHECK( spec.matches( fakeTestCase( "aardvark" ) ) );
+
+    }
 }
 
 TEST_CASE( "Process can be configured on command line", "[config][command-line]" ) {
@@ -462,4 +479,35 @@ TEST_CASE( "Process can be configured on command line", "[config][command-line]"
 #endif
         }
     }
+
+    SECTION("Benchmark options") {
+        SECTION("samples") {
+            CHECK(cli.parse({ "test", "--benchmark-samples=200" }));
+
+            REQUIRE(config.benchmarkSamples == 200);
+        }
+        
+        SECTION("resamples") {
+            CHECK(cli.parse({ "test", "--benchmark-resamples=20000" }));
+
+            REQUIRE(config.benchmarkResamples == 20000);
+        }
+
+        SECTION("resamples") {
+            CHECK(cli.parse({ "test", "--benchmark-confidence-interval=0.99" }));
+
+            REQUIRE(config.benchmarkConfidenceInterval == Catch::Detail::Approx(0.99));
+        }
+
+        SECTION("resamples") {
+            CHECK(cli.parse({ "test", "--benchmark-no-analysis" }));
+
+            REQUIRE(config.benchmarkNoAnalysis);
+        }
+    }
+}
+
+TEST_CASE("Test with special, characters \"in name", "[cli][regression]") {
+    // This test case succeeds if we can invoke it from the CLI
+    SUCCEED();
 }
diff --git a/packages/Catch2/projects/SelfTest/IntrospectiveTests/Details.tests.cpp b/packages/Catch2/projects/SelfTest/IntrospectiveTests/Details.tests.cpp
new file mode 100644
index 000000000..75054fb3b
--- /dev/null
+++ b/packages/Catch2/projects/SelfTest/IntrospectiveTests/Details.tests.cpp
@@ -0,0 +1,23 @@
+/*
+ *  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"
+
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable:4702) // unreachable code in the macro expansions
+#endif
+
+TEST_CASE("Check that our error handling macros throw the right exceptions", "[!throws][internals][approvals]") {
+    REQUIRE_THROWS_AS(CATCH_INTERNAL_ERROR(""), std::logic_error);
+    REQUIRE_THROWS_AS(CATCH_ERROR(""), std::domain_error);
+    REQUIRE_THROWS_AS(CATCH_RUNTIME_ERROR(""), std::runtime_error);
+    REQUIRE_THROWS_AS([](){CATCH_ENFORCE(false, "");}(), std::domain_error);
+    REQUIRE_NOTHROW([](){CATCH_ENFORCE(true, "");}());
+}
+
+#if defined(_MSC_VER)
+#pragma warning(pop) // unreachable code in the macro expansions
+#endif
diff --git a/packages/Catch2/projects/SelfTest/IntrospectiveTests/GeneratorsImpl.tests.cpp b/packages/Catch2/projects/SelfTest/IntrospectiveTests/GeneratorsImpl.tests.cpp
index dbc1d9578..076c91a9b 100644
--- a/packages/Catch2/projects/SelfTest/IntrospectiveTests/GeneratorsImpl.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/IntrospectiveTests/GeneratorsImpl.tests.cpp
@@ -250,7 +250,7 @@ int const& TestGen::get() const {
 
 }
 
-TEST_CASE("GENERATE capture macros", "[generators][internals][.approvals]") {
+TEST_CASE("GENERATE capture macros", "[generators][internals][approvals]") {
     auto value = GENERATE(take(10, random(0, 10)));
 
     non_copyable nc; nc.value = value;
@@ -258,3 +258,28 @@ TEST_CASE("GENERATE capture macros", "[generators][internals][.approvals]") {
     auto value2 = GENERATE_REF(Catch::Generators::GeneratorWrapper<int>(std::unique_ptr<Catch::Generators::IGenerator<int>>(new TestGen(nc))));
     REQUIRE(value == value2);
 }
+
+TEST_CASE("Multiple random generators in one test case output different values", "[generators][internals][approvals]") {
+    SECTION("Integer") {
+        auto random1 = Catch::Generators::random(0, 1000);
+        auto random2 = Catch::Generators::random(0, 1000);
+        size_t same = 0;
+        for (size_t i = 0; i < 1000; ++i) {
+            same += random1.get() == random2.get();
+            random1.next(); random2.next();
+        }
+        // 0.5% seems like a sane bound for random identical elements within 1000 runs
+        REQUIRE(same < 5);
+    }
+    SECTION("Float") {
+        auto random1 = Catch::Generators::random(0., 1000.);
+        auto random2 = Catch::Generators::random(0., 1000.);
+        size_t same = 0;
+        for (size_t i = 0; i < 1000; ++i) {
+            same += random1.get() == random2.get();
+            random1.next(); random2.next();
+        }
+        // 0.5% seems like a sane bound for random identical elements within 1000 runs
+        REQUIRE(same < 5);
+    }
+}
diff --git a/packages/Catch2/projects/SelfTest/IntrospectiveTests/InternalBenchmark.tests.cpp b/packages/Catch2/projects/SelfTest/IntrospectiveTests/InternalBenchmark.tests.cpp
new file mode 100644
index 000000000..d17998d87
--- /dev/null
+++ b/packages/Catch2/projects/SelfTest/IntrospectiveTests/InternalBenchmark.tests.cpp
@@ -0,0 +1,405 @@
+/*
+ *  Created by Joachim on 16/04/2019.
+ *  Adapted from donated nonius code.
+ *
+ *  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"
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+namespace {
+    struct manual_clock {
+    public:
+        using duration = std::chrono::nanoseconds;
+        using time_point = std::chrono::time_point<manual_clock, duration>;
+        using rep = duration::rep;
+        using period = duration::period;
+        enum { is_steady = true };
+
+        static time_point now() {
+            return time_point(duration(tick()));
+        }
+
+        static void advance(int ticks = 1) {
+            tick() += ticks;
+        }
+
+    private:
+        static rep& tick() {
+            static rep the_tick = 0;
+            return the_tick;
+        }
+    };
+
+    struct counting_clock {
+    public:
+        using duration = std::chrono::nanoseconds;
+        using time_point = std::chrono::time_point<counting_clock, duration>;
+        using rep = duration::rep;
+        using period = duration::period;
+        enum { is_steady = true };
+
+        static time_point now() {
+            static rep ticks = 0;
+            return time_point(duration(ticks += rate()));
+        }
+
+        static void set_rate(rep new_rate) { rate() = new_rate; }
+
+    private:
+        static rep& rate() {
+            static rep the_rate = 1;
+            return the_rate;
+        }
+    };
+
+    struct TestChronometerModel : Catch::Benchmark::Detail::ChronometerConcept {
+        int started = 0;
+        int finished = 0;
+
+        void start() override { ++started; }
+        void finish() override { ++finished; }
+    };
+} // namespace
+
+TEST_CASE("warmup", "[benchmark]") {
+    auto rate = 1000;
+    counting_clock::set_rate(rate);
+
+    auto start = counting_clock::now();
+    auto iterations = Catch::Benchmark::Detail::warmup<counting_clock>();
+    auto end = counting_clock::now();
+
+    REQUIRE((iterations * rate) > Catch::Benchmark::Detail::warmup_time.count());
+    REQUIRE((end - start) > Catch::Benchmark::Detail::warmup_time);
+}
+
+TEST_CASE("resolution", "[benchmark]") {
+    auto rate = 1000;
+    counting_clock::set_rate(rate);
+
+    size_t count = 10;
+    auto res = Catch::Benchmark::Detail::resolution<counting_clock>(static_cast<int>(count));
+
+    REQUIRE(res.size() == count);
+
+    for (size_t i = 1; i < count; ++i) {
+        REQUIRE(res[i] == rate);
+    }
+}
+
+TEST_CASE("estimate_clock_resolution", "[benchmark]") {
+    auto rate = 1000;
+    counting_clock::set_rate(rate);
+
+    int iters = 160000;
+    auto res = Catch::Benchmark::Detail::estimate_clock_resolution<counting_clock>(iters);
+
+    REQUIRE(res.mean.count() == rate);
+    REQUIRE(res.outliers.total() == 0);
+}
+
+TEST_CASE("benchmark function call", "[benchmark]") {
+    SECTION("without chronometer") {
+        auto called = 0;
+        auto model = TestChronometerModel{};
+        auto meter = Catch::Benchmark::Chronometer{ model, 1 };
+        auto fn = Catch::Benchmark::Detail::BenchmarkFunction{ [&] {
+                CHECK(model.started == 1);
+                CHECK(model.finished == 0);
+                ++called;
+            } };
+
+        fn(meter);
+
+        CHECK(model.started == 1);
+        CHECK(model.finished == 1);
+        CHECK(called == 1);
+    }
+
+    SECTION("with chronometer") {
+        auto called = 0;
+        auto model = TestChronometerModel{};
+        auto meter = Catch::Benchmark::Chronometer{ model, 1 };
+        auto fn = Catch::Benchmark::Detail::BenchmarkFunction{ [&](Catch::Benchmark::Chronometer) {
+                CHECK(model.started == 0);
+                CHECK(model.finished == 0);
+                ++called;
+            } };
+
+        fn(meter);
+
+        CHECK(model.started == 0);
+        CHECK(model.finished == 0);
+        CHECK(called == 1);
+    }
+}
+
+TEST_CASE("uniform samples", "[benchmark]") {
+    std::vector<double> samples(100);
+    std::fill(samples.begin(), samples.end(), 23);
+
+    using it = std::vector<double>::iterator;
+    auto e = Catch::Benchmark::Detail::bootstrap(0.95, samples.begin(), samples.end(), samples, [](it a, it b) {
+        auto sum = std::accumulate(a, b, 0.);
+        return sum / (b - a);
+    });
+    CHECK(e.point == 23);
+    CHECK(e.upper_bound == 23);
+    CHECK(e.lower_bound == 23);
+    CHECK(e.confidence_interval == 0.95);
+}
+
+
+TEST_CASE("normal_cdf", "[benchmark]") {
+    using Catch::Benchmark::Detail::normal_cdf;
+    CHECK(normal_cdf(0.000000) == Approx(0.50000000000000000));
+    CHECK(normal_cdf(1.000000) == Approx(0.84134474606854293));
+    CHECK(normal_cdf(-1.000000) == Approx(0.15865525393145705));
+    CHECK(normal_cdf(2.809729) == Approx(0.99752083845315409));
+    CHECK(normal_cdf(-1.352570) == Approx(0.08809652095066035));
+}
+
+TEST_CASE("erfc_inv", "[benchmark]") {
+    using Catch::Benchmark::Detail::erfc_inv;
+    CHECK(erfc_inv(1.103560) == Approx(-0.09203687623843015));
+    CHECK(erfc_inv(1.067400) == Approx(-0.05980291115763361));
+    CHECK(erfc_inv(0.050000) == Approx(1.38590382434967796));
+}
+
+TEST_CASE("normal_quantile", "[benchmark]") {
+    using Catch::Benchmark::Detail::normal_quantile;
+    CHECK(normal_quantile(0.551780) == Approx(0.13015979861484198));
+    CHECK(normal_quantile(0.533700) == Approx(0.08457408802851875));
+    CHECK(normal_quantile(0.025000) == Approx(-1.95996398454005449));
+}
+
+
+TEST_CASE("mean", "[benchmark]") {
+    std::vector<double> x{ 10., 20., 14., 16., 30., 24. };
+
+    auto m = Catch::Benchmark::Detail::mean(x.begin(), x.end());
+
+    REQUIRE(m == 19.);
+}
+
+TEST_CASE("weighted_average_quantile", "[benchmark]") {
+    std::vector<double> x{ 10., 20., 14., 16., 30., 24. };
+
+    auto q1 = Catch::Benchmark::Detail::weighted_average_quantile(1, 4, x.begin(), x.end());
+    auto med = Catch::Benchmark::Detail::weighted_average_quantile(1, 2, x.begin(), x.end());
+    auto q3 = Catch::Benchmark::Detail::weighted_average_quantile(3, 4, x.begin(), x.end());
+
+    REQUIRE(q1 == 14.5);
+    REQUIRE(med == 18.);
+    REQUIRE(q3 == 23.);
+}
+
+TEST_CASE("classify_outliers", "[benchmark]") {
+    auto require_outliers = [](Catch::Benchmark::OutlierClassification o, int los, int lom, int him, int his) {
+        REQUIRE(o.low_severe == los);
+        REQUIRE(o.low_mild == lom);
+        REQUIRE(o.high_mild == him);
+        REQUIRE(o.high_severe == his);
+        REQUIRE(o.total() == los + lom + him + his);
+    };
+
+    SECTION("none") {
+        std::vector<double> x{ 10., 20., 14., 16., 30., 24. };
+
+        auto o = Catch::Benchmark::Detail::classify_outliers(x.begin(), x.end());
+
+        REQUIRE(o.samples_seen == static_cast<int>(x.size()));
+        require_outliers(o, 0, 0, 0, 0);
+    }
+    SECTION("low severe") {
+        std::vector<double> x{ -12., 20., 14., 16., 30., 24. };
+
+        auto o = Catch::Benchmark::Detail::classify_outliers(x.begin(), x.end());
+
+        REQUIRE(o.samples_seen == static_cast<int>(x.size()));
+        require_outliers(o, 1, 0, 0, 0);
+    }
+    SECTION("low mild") {
+        std::vector<double> x{ 1., 20., 14., 16., 30., 24. };
+
+        auto o = Catch::Benchmark::Detail::classify_outliers(x.begin(), x.end());
+
+        REQUIRE(o.samples_seen == static_cast<int>(x.size()));
+        require_outliers(o, 0, 1, 0, 0);
+    }
+    SECTION("high mild") {
+        std::vector<double> x{ 10., 20., 14., 16., 36., 24. };
+
+        auto o = Catch::Benchmark::Detail::classify_outliers(x.begin(), x.end());
+
+        REQUIRE(o.samples_seen == static_cast<int>(x.size()));
+        require_outliers(o, 0, 0, 1, 0);
+    }
+    SECTION("high severe") {
+        std::vector<double> x{ 10., 20., 14., 16., 49., 24. };
+
+        auto o = Catch::Benchmark::Detail::classify_outliers(x.begin(), x.end());
+
+        REQUIRE(o.samples_seen == static_cast<int>(x.size()));
+        require_outliers(o, 0, 0, 0, 1);
+    }
+    SECTION("mixed") {
+        std::vector<double> x{ -20., 20., 14., 16., 39., 24. };
+
+        auto o = Catch::Benchmark::Detail::classify_outliers(x.begin(), x.end());
+
+        REQUIRE(o.samples_seen == static_cast<int>(x.size()));
+        require_outliers(o, 1, 0, 1, 0);
+    }
+}
+
+TEST_CASE("analyse", "[benchmark]") {
+    Catch::ConfigData data{};
+    data.benchmarkConfidenceInterval = 0.95;
+    data.benchmarkNoAnalysis = false;
+    data.benchmarkResamples = 1000;
+    data.benchmarkSamples = 99;
+    Catch::Config config{data};
+
+    using Duration = Catch::Benchmark::FloatDuration<Catch::Benchmark::default_clock>;
+
+    Catch::Benchmark::Environment<Duration> env;
+    std::vector<Duration> samples(99);
+    for (size_t i = 0; i < samples.size(); ++i) {
+        samples[i] = Duration(23 + (i % 3 - 1));
+    }
+
+    auto analysis = Catch::Benchmark::Detail::analyse(config, env, samples.begin(), samples.end());
+    CHECK(analysis.mean.point.count() == 23);
+    CHECK(analysis.mean.lower_bound.count() < 23);
+    CHECK(analysis.mean.lower_bound.count() > 22);
+    CHECK(analysis.mean.upper_bound.count() > 23);
+    CHECK(analysis.mean.upper_bound.count() < 24);
+
+    CHECK(analysis.standard_deviation.point.count() > 0.5);
+    CHECK(analysis.standard_deviation.point.count() < 1);
+    CHECK(analysis.standard_deviation.lower_bound.count() > 0.5);
+    CHECK(analysis.standard_deviation.lower_bound.count() < 1);
+    CHECK(analysis.standard_deviation.upper_bound.count() > 0.5);
+    CHECK(analysis.standard_deviation.upper_bound.count() < 1);
+
+    CHECK(analysis.outliers.total() == 0);
+    CHECK(analysis.outliers.low_mild == 0);
+    CHECK(analysis.outliers.low_severe == 0);
+    CHECK(analysis.outliers.high_mild == 0);
+    CHECK(analysis.outliers.high_severe == 0);
+    CHECK(analysis.outliers.samples_seen == samples.size());
+
+    CHECK(analysis.outlier_variance < 0.5);
+    CHECK(analysis.outlier_variance > 0);
+}
+
+TEST_CASE("analyse no analysis", "[benchmark]") {
+    Catch::ConfigData data{};
+    data.benchmarkConfidenceInterval = 0.95;
+    data.benchmarkNoAnalysis = true;
+    data.benchmarkResamples = 1000;
+    data.benchmarkSamples = 99;
+    Catch::Config config{ data };
+
+    using Duration = Catch::Benchmark::FloatDuration<Catch::Benchmark::default_clock>;
+
+    Catch::Benchmark::Environment<Duration> env;
+    std::vector<Duration> samples(99);
+    for (size_t i = 0; i < samples.size(); ++i) {
+        samples[i] = Duration(23 + (i % 3 - 1));
+    }
+
+    auto analysis = Catch::Benchmark::Detail::analyse(config, env, samples.begin(), samples.end());
+    CHECK(analysis.mean.point.count() == 23);
+    CHECK(analysis.mean.lower_bound.count() == 23);
+    CHECK(analysis.mean.upper_bound.count() == 23);
+
+    CHECK(analysis.standard_deviation.point.count() == 0);
+    CHECK(analysis.standard_deviation.lower_bound.count() == 0);
+    CHECK(analysis.standard_deviation.upper_bound.count() == 0);
+
+    CHECK(analysis.outliers.total() == 0);
+    CHECK(analysis.outliers.low_mild == 0);
+    CHECK(analysis.outliers.low_severe == 0);
+    CHECK(analysis.outliers.high_mild == 0);
+    CHECK(analysis.outliers.high_severe == 0);
+    CHECK(analysis.outliers.samples_seen == 0);
+
+    CHECK(analysis.outlier_variance == 0);
+}
+
+TEST_CASE("run_for_at_least, int", "[benchmark]") {
+    manual_clock::duration time(100);
+
+    int old_x = 1;
+    auto Timing = Catch::Benchmark::Detail::run_for_at_least<manual_clock>(time, 1, [&old_x](int x) -> int {
+        CHECK(x >= old_x);
+        manual_clock::advance(x);
+        old_x = x;
+        return x + 17;
+    });
+
+    REQUIRE(Timing.elapsed >= time);
+    REQUIRE(Timing.result == Timing.iterations + 17);
+    REQUIRE(Timing.iterations >= time.count());
+}
+
+TEST_CASE("run_for_at_least, chronometer", "[benchmark]") {
+    manual_clock::duration time(100);
+
+    int old_runs = 1;
+    auto Timing = Catch::Benchmark::Detail::run_for_at_least<manual_clock>(time, 1, [&old_runs](Catch::Benchmark::Chronometer meter) -> int {
+        CHECK(meter.runs() >= old_runs);
+        manual_clock::advance(100);
+        meter.measure([] {
+            manual_clock::advance(1);
+        });
+        old_runs = meter.runs();
+        return meter.runs() + 17;
+    });
+
+    REQUIRE(Timing.elapsed >= time);
+    REQUIRE(Timing.result == Timing.iterations + 17);
+    REQUIRE(Timing.iterations >= time.count());
+}
+
+
+TEST_CASE("measure", "[benchmark]") {
+    auto r = Catch::Benchmark::Detail::measure<manual_clock>([](int x) -> int {
+        CHECK(x == 17);
+        manual_clock::advance(42);
+        return 23;
+    }, 17);
+    auto s = Catch::Benchmark::Detail::measure<manual_clock>([](int x) -> int {
+        CHECK(x == 23);
+        manual_clock::advance(69);
+        return 17;
+    }, 23);
+
+    CHECK(r.elapsed.count() == 42);
+    CHECK(r.result == 23);
+    CHECK(r.iterations == 1);
+
+    CHECK(s.elapsed.count() == 69);
+    CHECK(s.result == 17);
+    CHECK(s.iterations == 1);
+}
+
+TEST_CASE("run benchmark", "[benchmark]") {
+    counting_clock::set_rate(1000);
+    auto start = counting_clock::now();
+    
+    Catch::Benchmark::Benchmark bench{ "Test Benchmark", [](Catch::Benchmark::Chronometer meter) {
+        counting_clock::set_rate(100000);
+        meter.measure([] { return counting_clock::now(); });
+    } };
+
+    bench.run<counting_clock>();
+    auto end = counting_clock::now();
+
+    CHECK((end - start).count() == 2867251000);
+}
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
diff --git a/packages/Catch2/projects/SelfTest/IntrospectiveTests/PartTracker.tests.cpp b/packages/Catch2/projects/SelfTest/IntrospectiveTests/PartTracker.tests.cpp
index 9372b1c3b..837d3661b 100644
--- a/packages/Catch2/projects/SelfTest/IntrospectiveTests/PartTracker.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/IntrospectiveTests/PartTracker.tests.cpp
@@ -8,21 +8,6 @@
 #include "internal/catch_suppress_warnings.h"
 #include "internal/catch_test_case_tracker.h"
 
-
-namespace Catch
-{
-    class LocalContext {
-
-    public:
-        TrackerContext& operator()() const {
-            return TrackerContext::instance();
-        }
-    };
-
-} // namespace Catch
-
-// -------------------
-
 #include "catch.hpp"
 
 using namespace Catch;
@@ -204,3 +189,18 @@ TEST_CASE( "#1394 nested", "[.][approvals][tracker]" ) {
         REQUIRE(1 == 0);
     }
 }
+
+// Selecting a "not last" section inside a test case via -c "section" would
+// previously only run the first subsection, instead of running all of them.
+// This allows us to check that `"#1670 regression check" -c A` leads to
+// 2 successful assertions.
+TEST_CASE("#1670 regression check", "[.approvals][tracker]") {
+    SECTION("A") {
+        SECTION("1") SUCCEED();
+        SECTION("2") SUCCEED();
+    }
+    SECTION("B") {
+        SECTION("1") SUCCEED();
+        SECTION("2") SUCCEED();
+    }
+}
diff --git a/packages/Catch2/projects/SelfTest/IntrospectiveTests/RandomNumberGeneration.tests.cpp b/packages/Catch2/projects/SelfTest/IntrospectiveTests/RandomNumberGeneration.tests.cpp
new file mode 100644
index 000000000..f8085dbf2
--- /dev/null
+++ b/packages/Catch2/projects/SelfTest/IntrospectiveTests/RandomNumberGeneration.tests.cpp
@@ -0,0 +1,45 @@
+/*
+ *  Created by Martin on 06/10/2019.
+ *
+ *  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 "internal/catch_random_number_generator.h"
+
+TEST_CASE("Our PCG implementation provides expected results for known seeds", "[rng]") {
+    Catch::SimplePcg32 rng;
+    SECTION("Default seeded") {
+        REQUIRE(rng() == 0xfcdb943b);
+        REQUIRE(rng() == 0x6f55b921);
+        REQUIRE(rng() == 0x4c17a916);
+        REQUIRE(rng() == 0x71eae25f);
+        REQUIRE(rng() == 0x6ce7909c);
+    }
+    SECTION("Specific seed") {
+        rng.seed(0xabcd1234);
+        REQUIRE(rng() == 0x57c08495);
+        REQUIRE(rng() == 0x33c956ac);
+        REQUIRE(rng() == 0x2206fd76);
+        REQUIRE(rng() == 0x3501a35b);
+        REQUIRE(rng() == 0xfdffb30f);
+
+        // Also check repeated output after reseeding
+        rng.seed(0xabcd1234);
+        REQUIRE(rng() == 0x57c08495);
+        REQUIRE(rng() == 0x33c956ac);
+        REQUIRE(rng() == 0x2206fd76);
+        REQUIRE(rng() == 0x3501a35b);
+        REQUIRE(rng() == 0xfdffb30f);
+    }
+}
+
+TEST_CASE("Comparison ops", "[rng]") {
+    using Catch::SimplePcg32;
+    REQUIRE(SimplePcg32{} == SimplePcg32{});
+    REQUIRE(SimplePcg32{ 0 } != SimplePcg32{});
+    REQUIRE_FALSE(SimplePcg32{ 1 } == SimplePcg32{ 2 });
+    REQUIRE_FALSE(SimplePcg32{ 1 } != SimplePcg32{ 1 });
+}
diff --git a/packages/Catch2/projects/SelfTest/IntrospectiveTests/String.tests.cpp b/packages/Catch2/projects/SelfTest/IntrospectiveTests/String.tests.cpp
index ae21bb3ce..456dd4a7d 100644
--- a/packages/Catch2/projects/SelfTest/IntrospectiveTests/String.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/IntrospectiveTests/String.tests.cpp
@@ -65,7 +65,6 @@ TEST_CASE( "StringRef", "[Strings][StringRef]" ) {
 
         original.c_str(); // Forces it to take ownership
 
-        REQUIRE( isSubstring( original ) == false );
         REQUIRE( isOwned( original ) );
     }
 
@@ -88,10 +87,14 @@ TEST_CASE( "StringRef", "[Strings][StringRef]" ) {
             REQUIRE( rawChars == s.currentData() ); // same pointer value
             REQUIRE( ss.c_str() != rawChars );
 
-            REQUIRE( isSubstring( ss ) == false );
             REQUIRE( isOwned( ss ) );
 
-            REQUIRE( ss.currentData() != s.currentData() ); // different pointer value
+            SECTION( "Self-assignment after substring" ) {
+                ss = *&ss; // the *& are there to suppress warnings (see: "Improvements to Clang's diagnostics" in https://rev.ng/gitlab/revng-bar-2019/clang/raw/master/docs/ReleaseNotes.rst)
+                REQUIRE( isOwned(ss) == false );
+                REQUIRE( ss == "hello" );
+                REQUIRE( rawChars == ss.currentData() ); // same pointer value
+            }
         }
 
         SECTION( "non-zero-based substring") {
@@ -108,6 +111,10 @@ TEST_CASE( "StringRef", "[Strings][StringRef]" ) {
         SECTION( "Pointer values of substring refs should not match" ) {
             REQUIRE( s.c_str() != ss.c_str() );
         }
+
+        SECTION("Past the end substring") {
+            REQUIRE(s.substr(s.size() + 1, 123).empty());
+        }
     }
 
     SECTION( "Comparisons" ) {
@@ -139,11 +146,6 @@ TEST_CASE( "StringRef", "[Strings][StringRef]" ) {
     SECTION( "to std::string" ) {
         StringRef sr = "a stringref";
 
-        SECTION( "implicitly constructed" ) {
-            std::string stdStr = sr;
-            REQUIRE( stdStr == "a stringref" );
-            REQUIRE( stdStr.size() == sr.size() );
-        }
         SECTION( "explicitly constructed" ) {
             std::string stdStr( sr );
             REQUIRE( stdStr == "a stringref" );
@@ -151,54 +153,9 @@ TEST_CASE( "StringRef", "[Strings][StringRef]" ) {
         }
         SECTION( "assigned" ) {
             std::string stdStr;
-            stdStr = sr;
+            stdStr = static_cast<std::string>(sr);
             REQUIRE( stdStr == "a stringref" );
             REQUIRE( stdStr.size() == sr.size() );
         }
     }
-
-    SECTION( "Counting utf-8 codepoints" ) {
-        StringRef ascii = "just a plain old boring ascii string...";
-        REQUIRE(ascii.numberOfCharacters() == ascii.size());
-
-        StringRef simpleu8 = u8"Trocha češtiny nikoho nezabila";
-        REQUIRE(simpleu8.numberOfCharacters() == 30);
-
-        StringRef emojis = u8"Here be 👾";
-        REQUIRE(emojis.numberOfCharacters() == 9);
-    }
-
-}
-
-TEST_CASE( "replaceInPlace", "[Strings][StringManip]" ) {
-    std::string letters = "abcdefcg";
-    SECTION( "replace single char" ) {
-        CHECK( Catch::replaceInPlace( letters, "b", "z" ) );
-        CHECK( letters == "azcdefcg" );
-    }
-    SECTION( "replace two chars" ) {
-        CHECK( Catch::replaceInPlace( letters, "c", "z" ) );
-        CHECK( letters == "abzdefzg" );
-    }
-    SECTION( "replace first char" ) {
-        CHECK( Catch::replaceInPlace( letters, "a", "z" ) );
-        CHECK( letters == "zbcdefcg" );
-    }
-    SECTION( "replace last char" ) {
-        CHECK( Catch::replaceInPlace( letters, "g", "z" ) );
-        CHECK( letters == "abcdefcz" );
-    }
-    SECTION( "replace all chars" ) {
-        CHECK( Catch::replaceInPlace( letters, letters, "replaced" ) );
-        CHECK( letters == "replaced" );
-    }
-    SECTION( "replace no chars" ) {
-        CHECK_FALSE( Catch::replaceInPlace( letters, "x", "z" ) );
-        CHECK( letters == letters );
-    }
-    SECTION( "escape '" ) {
-        std::string s = "didn't";
-        CHECK( Catch::replaceInPlace( s, "'", "|'" ) );
-        CHECK( s == "didn|'t" );
-    }
 }
diff --git a/packages/Catch2/projects/SelfTest/IntrospectiveTests/StringManip.tests.cpp b/packages/Catch2/projects/SelfTest/IntrospectiveTests/StringManip.tests.cpp
new file mode 100644
index 000000000..b817f3729
--- /dev/null
+++ b/packages/Catch2/projects/SelfTest/IntrospectiveTests/StringManip.tests.cpp
@@ -0,0 +1,67 @@
+#include "internal/catch_string_manip.h"
+
+#include "catch.hpp"
+
+static const char * const no_whitespace = "There is no extra whitespace here";
+static const char * const leading_whitespace = " \r \t\n There is no extra whitespace here";
+static const char * const trailing_whitespace = "There is no extra whitespace here \t \n \r ";
+static const char * const whitespace_at_both_ends = " \r\n \t There is no extra whitespace here  \t\t\t \n";
+
+TEST_CASE("Trim strings", "[string-manip]") {
+    using Catch::trim; using Catch::StringRef;
+    static_assert(std::is_same<std::string, decltype(trim(std::string{}))>::value, "Trimming std::string should return std::string");
+    static_assert(std::is_same<StringRef, decltype(trim(StringRef{}))>::value, "Trimming StringRef should return StringRef");
+
+    REQUIRE(trim(std::string(no_whitespace)) == no_whitespace);
+    REQUIRE(trim(std::string(leading_whitespace)) == no_whitespace);
+    REQUIRE(trim(std::string(trailing_whitespace)) == no_whitespace);
+    REQUIRE(trim(std::string(whitespace_at_both_ends)) == no_whitespace);
+
+    REQUIRE(trim(StringRef(no_whitespace)) == StringRef(no_whitespace));
+    REQUIRE(trim(StringRef(leading_whitespace)) == StringRef(no_whitespace));
+    REQUIRE(trim(StringRef(trailing_whitespace)) == StringRef(no_whitespace));
+    REQUIRE(trim(StringRef(whitespace_at_both_ends)) == StringRef(no_whitespace));
+}
+
+TEST_CASE("replaceInPlace", "[string-manip]") {
+    std::string letters = "abcdefcg";
+    SECTION("replace single char") {
+        CHECK(Catch::replaceInPlace(letters, "b", "z"));
+        CHECK(letters == "azcdefcg");
+    }
+    SECTION("replace two chars") {
+        CHECK(Catch::replaceInPlace(letters, "c", "z"));
+        CHECK(letters == "abzdefzg");
+    }
+    SECTION("replace first char") {
+        CHECK(Catch::replaceInPlace(letters, "a", "z"));
+        CHECK(letters == "zbcdefcg");
+    }
+    SECTION("replace last char") {
+        CHECK(Catch::replaceInPlace(letters, "g", "z"));
+        CHECK(letters == "abcdefcz");
+    }
+    SECTION("replace all chars") {
+        CHECK(Catch::replaceInPlace(letters, letters, "replaced"));
+        CHECK(letters == "replaced");
+    }
+    SECTION("replace no chars") {
+        CHECK_FALSE(Catch::replaceInPlace(letters, "x", "z"));
+        CHECK(letters == letters);
+    }
+    SECTION("escape '") {
+        std::string s = "didn't";
+        CHECK(Catch::replaceInPlace(s, "'", "|'"));
+        CHECK(s == "didn|'t");
+    }
+}
+
+TEST_CASE("splitString", "[string-manip]") {
+    using namespace Catch::Matchers;
+    using Catch::splitStringRef;
+    using Catch::StringRef;
+
+    CHECK_THAT(splitStringRef("", ','), Equals(std::vector<StringRef>()));
+    CHECK_THAT(splitStringRef("abc", ','), Equals(std::vector<StringRef>{"abc"}));
+    CHECK_THAT(splitStringRef("abc,def", ','), Equals(std::vector<StringRef>{"abc", "def"}));
+}
diff --git a/packages/Catch2/projects/SelfTest/IntrospectiveTests/ToString.tests.cpp b/packages/Catch2/projects/SelfTest/IntrospectiveTests/ToString.tests.cpp
new file mode 100644
index 000000000..caa924f52
--- /dev/null
+++ b/packages/Catch2/projects/SelfTest/IntrospectiveTests/ToString.tests.cpp
@@ -0,0 +1,42 @@
+#include "catch.hpp"
+
+#include "internal/catch_enum_values_registry.h"
+
+enum class EnumClass3 { Value1, Value2, Value3, Value4 };
+
+
+TEST_CASE( "parseEnums", "[Strings][enums]" ) {
+    using namespace Catch::Matchers;
+    using Catch::Detail::parseEnums;
+
+    SECTION( "No enums" )
+        CHECK_THAT( parseEnums( "" ), Equals( std::vector<Catch::StringRef>{} ) );
+
+    SECTION( "One enum value" ) {
+        CHECK_THAT( parseEnums( "ClassName::EnumName::Value1" ),
+                Equals(std::vector<Catch::StringRef>{"Value1"} ) );
+        CHECK_THAT( parseEnums( "Value1" ),
+                Equals( std::vector<Catch::StringRef>{"Value1"} ) );
+        CHECK_THAT( parseEnums( "EnumName::Value1" ),
+                Equals(std::vector<Catch::StringRef>{"Value1"} ) );
+    }
+
+    SECTION( "Multiple enum values" ) {
+        CHECK_THAT( parseEnums( "ClassName::EnumName::Value1, ClassName::EnumName::Value2" ),
+                    Equals( std::vector<Catch::StringRef>{"Value1", "Value2"} ) );
+        CHECK_THAT( parseEnums( "ClassName::EnumName::Value1, ClassName::EnumName::Value2, ClassName::EnumName::Value3" ),
+                    Equals( std::vector<Catch::StringRef>{"Value1", "Value2", "Value3"} ) );
+        CHECK_THAT( parseEnums( "ClassName::EnumName::Value1,ClassName::EnumName::Value2 , ClassName::EnumName::Value3" ),
+                    Equals( std::vector<Catch::StringRef>{"Value1", "Value2", "Value3"} ) );
+    }
+}
+
+TEST_CASE( "Directly creating an EnumInfo" ) {
+
+    using namespace Catch::Detail;
+    std::unique_ptr<EnumInfo> enumInfo = makeEnumInfo( "EnumName", "EnumName::Value1, EnumName::Value2", {0, 1} );
+
+    CHECK( enumInfo->lookup(0) == "Value1" );
+    CHECK( enumInfo->lookup(1) == "Value2" );
+    CHECK( enumInfo->lookup(3) == "{** unexpected enum value **}" );
+}
diff --git a/packages/Catch2/projects/SelfTest/Misc/invalid-test-names.input b/packages/Catch2/projects/SelfTest/Misc/invalid-test-names.input
new file mode 100644
index 000000000..e2bc88ece
--- /dev/null
+++ b/packages/Catch2/projects/SelfTest/Misc/invalid-test-names.input
@@ -0,0 +1 @@
+Test with special, characters in \" name
diff --git a/packages/Catch2/projects/SelfTest/Misc/plain-old-tests.input b/packages/Catch2/projects/SelfTest/Misc/plain-old-tests.input
new file mode 100644
index 000000000..ae6d9f1b7
--- /dev/null
+++ b/packages/Catch2/projects/SelfTest/Misc/plain-old-tests.input
@@ -0,0 +1,2 @@
+random SECTION tests
+nested SECTION tests
diff --git a/packages/Catch2/projects/SelfTest/Misc/special-characters-in-file.input b/packages/Catch2/projects/SelfTest/Misc/special-characters-in-file.input
new file mode 100644
index 000000000..b68a6bfda
--- /dev/null
+++ b/packages/Catch2/projects/SelfTest/Misc/special-characters-in-file.input
@@ -0,0 +1 @@
+Test with special\, characters \"in name
diff --git a/packages/Catch2/projects/SelfTest/UsageTests/Approx.tests.cpp b/packages/Catch2/projects/SelfTest/UsageTests/Approx.tests.cpp
index b95394a06..4029223a2 100644
--- a/packages/Catch2/projects/SelfTest/UsageTests/Approx.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/UsageTests/Approx.tests.cpp
@@ -61,8 +61,6 @@ TEST_CASE( "Some simple comparisons between doubles", "[Approx]" ) {
     REQUIRE( Approx( d ) == 1.23 );
     REQUIRE( Approx( d ) != 1.22 );
     REQUIRE( Approx( d ) != 1.24 );
-
-    REQUIRE(INFINITY == Approx(INFINITY));
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -183,8 +181,11 @@ TEST_CASE("Epsilon only applies to Approx's value", "[Approx]") {
     REQUIRE(101.01 != Approx(100).epsilon(0.01));
 }
 
-TEST_CASE("Assorted miscellaneous tests", "[Approx]") {
+TEST_CASE("Assorted miscellaneous tests", "[Approx][approvals]") {
     REQUIRE(INFINITY == Approx(INFINITY));
+    REQUIRE(-INFINITY != Approx(INFINITY));
+    REQUIRE(1 != Approx(INFINITY));
+    REQUIRE(INFINITY != Approx(1));
     REQUIRE(NAN != Approx(NAN));
     REQUIRE_FALSE(NAN == Approx(NAN));
 }
diff --git a/packages/Catch2/projects/SelfTest/UsageTests/Benchmark.tests.cpp b/packages/Catch2/projects/SelfTest/UsageTests/Benchmark.tests.cpp
index ddf695045..24fda0133 100644
--- a/packages/Catch2/projects/SelfTest/UsageTests/Benchmark.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/UsageTests/Benchmark.tests.cpp
@@ -2,42 +2,129 @@
 
 #include <map>
 
-TEST_CASE( "benchmarked", "[!benchmark]" ) {
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+namespace {
+    std::uint64_t Fibonacci(std::uint64_t number) {
+        return number < 2 ? 1 : Fibonacci(number - 1) + Fibonacci(number - 2);
+    }
+}
+
+TEST_CASE("Benchmark Fibonacci", "[!benchmark]") {
+    CHECK(Fibonacci(0) == 1);
+    // some more asserts..
+    CHECK(Fibonacci(5) == 8);
+    // some more asserts..
+
+    BENCHMARK("Fibonacci 20") {
+        return Fibonacci(20);
+    };
+
+    BENCHMARK("Fibonacci 25") {
+        return Fibonacci(25);
+    };
 
+    BENCHMARK("Fibonacci 30") {
+        return Fibonacci(30);
+    };
+
+    BENCHMARK("Fibonacci 35") {
+        return Fibonacci(35);
+    };
+}
+
+TEST_CASE("Benchmark containers", "[!benchmark]") {
     static const int size = 100;
 
     std::vector<int> v;
     std::map<int, int> m;
 
-    BENCHMARK( "Load up a vector" ) {
-        v = std::vector<int>();
-        for(int i =0; i < size; ++i )
-            v.push_back( i );
-    }
-    REQUIRE( v.size() == size );
+    SECTION("without generator") {
+        BENCHMARK("Load up a vector") {
+            v = std::vector<int>();
+            for (int i = 0; i < size; ++i)
+                v.push_back(i);
+        };
+        REQUIRE(v.size() == size);
 
-    BENCHMARK( "Load up a map" ) {
-        m = std::map<int, int>();
-        for(int i =0; i < size; ++i )
-            m.insert( { i, i+1 } );
-    }
-    REQUIRE( m.size() == size );
+        // test optimizer control
+        BENCHMARK("Add up a vector's content") {
+            uint64_t add = 0;
+            for (int i = 0; i < size; ++i)
+                add += v[i];
+            return add;
+        };
+
+        BENCHMARK("Load up a map") {
+            m = std::map<int, int>();
+            for (int i = 0; i < size; ++i)
+                m.insert({ i, i + 1 });
+        };
+        REQUIRE(m.size() == size);
+
+        BENCHMARK("Reserved vector") {
+            v = std::vector<int>();
+            v.reserve(size);
+            for (int i = 0; i < size; ++i)
+                v.push_back(i);
+        };
+        REQUIRE(v.size() == size);
+
+        BENCHMARK("Resized vector") {
+            v = std::vector<int>();
+            v.resize(size);
+            for (int i = 0; i < size; ++i)
+                v[i] = i;
+        };
+        REQUIRE(v.size() == size);
+
+        int array[size];
+        BENCHMARK("A fixed size array that should require no allocations") {
+            for (int i = 0; i < size; ++i)
+                array[i] = i;
+        };
+        int sum = 0;
+        for (int i = 0; i < size; ++i)
+            sum += array[i];
+        REQUIRE(sum > size);
+
+        SECTION("XYZ") {
+
+            BENCHMARK_ADVANCED("Load up vector with chronometer")(Catch::Benchmark::Chronometer meter) {
+                std::vector<int> k;
+                meter.measure([&](int idx) {
+                    k = std::vector<int>();
+                    for (int i = 0; i < size; ++i)
+                        k.push_back(idx);
+                });
+                REQUIRE(k.size() == size);
+            };
+
+            int runs = 0;
+            BENCHMARK("Fill vector indexed", benchmarkIndex) {
+                v = std::vector<int>();
+                v.resize(size);
+                for (int i = 0; i < size; ++i)
+                    v[i] = benchmarkIndex;
+                runs = benchmarkIndex;
+            };
 
-    BENCHMARK( "Reserved vector" ) {
-        v = std::vector<int>();
-        v.reserve(size);
-        for(int i =0; i < size; ++i )
-            v.push_back( i );
+            for (size_t i = 0; i < v.size(); ++i) {
+                REQUIRE(v[i] == runs);
+            }
+        }
     }
-    REQUIRE( v.size() == size );
 
-    int array[size];
-    BENCHMARK( "A fixed size array that should require no allocations" ) {
-        for(int i =0; i < size; ++i )
-            array[i] = i;
+    SECTION("with generator") {
+        auto generated = GENERATE(range(0, 10));
+        BENCHMARK("Fill vector generated") {
+            v = std::vector<int>();
+            v.resize(size);
+            for (int i = 0; i < size; ++i)
+                v[i] = generated;
+        };
+        for (size_t i = 0; i < v.size(); ++i) {
+            REQUIRE(v[i] == generated);
+        }
     }
-    int sum = 0;
-    for(int i =0; i < size; ++i )
-        sum += array[i];
-    REQUIRE( sum > size );
 }
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
diff --git a/packages/Catch2/projects/SelfTest/UsageTests/Class.tests.cpp b/packages/Catch2/projects/SelfTest/UsageTests/Class.tests.cpp
index 3bde1d82a..f658fc199 100644
--- a/packages/Catch2/projects/SelfTest/UsageTests/Class.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/UsageTests/Class.tests.cpp
@@ -7,6 +7,7 @@
  */
 
 #include "catch.hpp"
+#include <array>
 
 namespace{ namespace ClassTests {
 
@@ -58,6 +59,15 @@ struct Template_Foo {
     size_t size() { return 0; }
 };
 
+template< typename T, size_t V>
+struct Template_Foo_2 {
+    size_t size() { return V; }
+};
+
+template <int V>
+struct Nttp_Fixture{
+    int value = V;
+};
 #endif
 
 
@@ -74,11 +84,26 @@ TEMPLATE_TEST_CASE_METHOD(Template_Fixture, "A TEMPLATE_TEST_CASE_METHOD based t
     REQUIRE( Template_Fixture<TestType>::m_a == 1 );
 }
 
+TEMPLATE_TEST_CASE_METHOD_SIG(Nttp_Fixture, "A TEMPLATE_TEST_CASE_METHOD_SIG based test run that succeeds", "[class][template][nttp]",((int V), V), 1, 3, 6) {
+    REQUIRE(Nttp_Fixture<V>::value > 0);
+}
+
 TEMPLATE_PRODUCT_TEST_CASE_METHOD(Template_Fixture_2, "A TEMPLATE_PRODUCT_TEST_CASE_METHOD based test run that succeeds","[class][template][product]",(std::vector,Template_Foo),(int,float))
 {
     REQUIRE( Template_Fixture_2<TestType>::m_a.size() == 0 );
 }
 
+TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG(Template_Fixture_2, "A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that succeeds", "[class][template][product][nttp]", ((typename T, size_t S), T, S),(std::array, Template_Foo_2), ((int,2), (float,6)))
+{
+    REQUIRE(Template_Fixture_2<TestType>{}.m_a.size() >= 2);
+}
+
+using MyTypes = std::tuple<int, char, double>;
+TEMPLATE_LIST_TEST_CASE_METHOD(Template_Fixture, "Template test case method with test types specified inside std::tuple", "[class][template][list]", MyTypes)
+{
+    REQUIRE( Template_Fixture<TestType>::m_a == 1 );
+}
+
 // We should be able to write our tests within a different namespace
 namespace Inner
 {
@@ -92,10 +117,19 @@ namespace Inner
         REQUIRE( Template_Fixture<TestType>::m_a == 2 );
     }
 
+    TEMPLATE_TEST_CASE_METHOD_SIG(Nttp_Fixture, "A TEMPLATE_TEST_CASE_METHOD_SIG based test run that fails", "[.][class][template][nttp][failing]", ((int V), V), 1, 3, 6) {
+        REQUIRE(Nttp_Fixture<V>::value == 0);
+    }
+
     TEMPLATE_PRODUCT_TEST_CASE_METHOD(Template_Fixture_2, "A TEMPLATE_PRODUCT_TEST_CASE_METHOD based test run that fails","[.][class][template][product][failing]",(std::vector,Template_Foo),(int,float))
     {
         REQUIRE( Template_Fixture_2<TestType>::m_a.size() == 1 );
     }
+
+    TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG(Template_Fixture_2, "A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that fails", "[.][class][template][product][nttp][failing]", ((typename T, size_t S), T, S), (std::array, Template_Foo_2), ((int, 2), (float, 6)))
+    {
+        REQUIRE(Template_Fixture_2<TestType>{}.m_a.size() < 2);
+    }
 }
 
 
diff --git a/packages/Catch2/projects/SelfTest/UsageTests/Compilation.tests.cpp b/packages/Catch2/projects/SelfTest/UsageTests/Compilation.tests.cpp
index 7f2ad8bc9..11d136a46 100644
--- a/packages/Catch2/projects/SelfTest/UsageTests/Compilation.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/UsageTests/Compilation.tests.cpp
@@ -194,6 +194,31 @@ namespace { namespace CompilationTests {
         REQUIRE(std::is_same<TypeList<int>, TypeList<int>>::value);
     }
 
-}} // namespace CompilationTests
+    // #925
+    using signal_t = void (*) (void*);
+
+    struct TestClass {
+        signal_t testMethod_uponComplete_arg = nullptr;
+    };
 
+    namespace utility {
+        inline static void synchronizing_callback( void * ) { }
+    }
+
+    TEST_CASE("#925: comparing function pointer to function address failed to compile", "[!nonportable]" ) {
+        TestClass test;
+        REQUIRE(utility::synchronizing_callback != test.testMethod_uponComplete_arg);
+    }
+
+    TEST_CASE( "#1027: Bitfields can be captured" ) {
+        struct Y {
+            uint32_t v : 1;
+        };
+        Y y{ 0 };
+        REQUIRE( y.v == 0 );
+        REQUIRE( 0 == y.v );
+    }
+
+
+}} // namespace CompilationTests
 
diff --git a/packages/Catch2/projects/SelfTest/UsageTests/EnumToString.tests.cpp b/packages/Catch2/projects/SelfTest/UsageTests/EnumToString.tests.cpp
index 0b188a826..7f27916ef 100644
--- a/packages/Catch2/projects/SelfTest/UsageTests/EnumToString.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/UsageTests/EnumToString.tests.cpp
@@ -61,6 +61,39 @@ TEST_CASE( "toString(enum class w/operator<<)", "[toString][enum][enumClass]" )
     EnumClass2 e1 = EnumClass2::EnumClass2Value1;
     CHECK( ::Catch::Detail::stringify(e1) == "E2/V1" );
 
-    EnumClass2 e3 = static_cast<EnumClass2>(10);
+    auto e3 = static_cast<EnumClass2>(10);
     CHECK( ::Catch::Detail::stringify(e3) == "Unknown enum value 10" );
 }
+
+enum class EnumClass3 { Value1, Value2, Value3, Value4 };
+
+CATCH_REGISTER_ENUM( EnumClass3, EnumClass3::Value1, EnumClass3::Value2, EnumClass3::Value3 )
+
+
+TEST_CASE( "Enums can quickly have stringification enabled using REGISTER_ENUM" ) {
+    using Catch::Detail::stringify;
+    REQUIRE( stringify( EnumClass3::Value1 ) == "Value1" );
+    REQUIRE( stringify( EnumClass3::Value2 ) == "Value2" );
+    REQUIRE( stringify( EnumClass3::Value3 ) == "Value3" );
+    REQUIRE( stringify( EnumClass3::Value4 ) == "{** unexpected enum value **}" );
+
+    EnumClass3 ec3 = EnumClass3 ::Value2;
+    REQUIRE( stringify( ec3 ) == "Value2" );
+}
+
+namespace Bikeshed {
+    enum class Colours { Red, Green, Blue };
+}
+
+// Important!: This macro must appear at top level scope - not inside a namespace
+// You can fully qualify the names, or use a using if you prefer
+CATCH_REGISTER_ENUM( Bikeshed::Colours,
+                     Bikeshed::Colours::Red,
+                     Bikeshed::Colours::Green,
+                     Bikeshed::Colours::Blue )
+
+TEST_CASE( "Enums in namespaces can quickly have stringification enabled using REGISTER_ENUM" ) {
+    using Catch::Detail::stringify;
+    REQUIRE( stringify( Bikeshed::Colours::Red ) == "Red" );
+    REQUIRE( stringify( Bikeshed::Colours::Blue ) == "Blue" );
+}
diff --git a/packages/Catch2/projects/SelfTest/UsageTests/Generators.tests.cpp b/packages/Catch2/projects/SelfTest/UsageTests/Generators.tests.cpp
index f5e3f6a53..0e39bd5cb 100644
--- a/packages/Catch2/projects/SelfTest/UsageTests/Generators.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/UsageTests/Generators.tests.cpp
@@ -167,6 +167,10 @@ TEST_CASE("Generators -- adapters", "[generators][generic]") {
             REQUIRE(chunk2.front() == chunk2.back());
             REQUIRE(chunk2.front() < 3);
         }
+        SECTION("Chunk size of zero") {
+            auto chunk2 = GENERATE(take(3, chunk(0, value(1))));
+            REQUIRE(chunk2.size() == 0);
+        }
         SECTION("Throws on too small generators") {
             using namespace Catch::Generators;
             REQUIRE_THROWS_AS(chunk(2, value(1)), Catch::GeneratorException);
@@ -176,16 +180,18 @@ TEST_CASE("Generators -- adapters", "[generators][generic]") {
 
 // Note that because of the non-reproducibility of distributions,
 // anything involving the random generators cannot be part of approvals
-TEST_CASE("Random generator", "[generators][.][approvals]") {
+TEST_CASE("Random generator", "[generators][approvals]") {
     SECTION("Infer int from integral arguments") {
         auto val = GENERATE(take(4, random(0, 1)));
         STATIC_REQUIRE(std::is_same<decltype(val), int>::value);
-        static_cast<void>(val); // Silence VS 2015 unused variable warning
+        REQUIRE(0 <= val);
+        REQUIRE(val <= 1);
     }
     SECTION("Infer double from double arguments") {
         auto val = GENERATE(take(4, random(0., 1.)));
         STATIC_REQUIRE(std::is_same<decltype(val), double>::value);
-        static_cast<void>(val); // Silence VS 2015 unused variable warning
+        REQUIRE(0. <= val);
+        REQUIRE(val < 1);
     }
 }
 
@@ -206,3 +212,45 @@ TEST_CASE("Nested generators and captured variables", "[generators]") {
     auto values = GENERATE_COPY(range(from, to));
     REQUIRE(values > -6);
 }
+
+namespace {
+    size_t call_count = 0;
+    size_t test_count = 0;
+    std::vector<int> make_data() {
+        return { 1, 3, 5, 7, 9, 11 };
+    }
+    std::vector<int> make_data_counted() {
+        ++call_count;
+        return make_data();
+    }
+}
+
+#if defined(__clang__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wexit-time-destructors"
+#endif
+
+TEST_CASE("Copy and then generate a range", "[generators]") {
+    SECTION("from var and iterators") {
+        static auto data = make_data();
+
+        // It is important to notice that a generator is only initialized
+        // **once** per run. What this means is that modifying data will not
+        // modify the underlying generator.
+        auto elem = GENERATE_REF(from_range(data.begin(), data.end()));
+        REQUIRE(elem % 2 == 1);
+    }
+    SECTION("From a temporary container") {
+        auto elem = GENERATE(from_range(make_data_counted()));
+        ++test_count;
+        REQUIRE(elem % 2 == 1);
+    }
+    SECTION("Final validation") {
+        REQUIRE(call_count == 1);
+        REQUIRE(make_data().size() == test_count);
+    }
+}
+
+#if defined(__clang__)
+#pragma clang diagnostic pop
+#endif
diff --git a/packages/Catch2/projects/SelfTest/UsageTests/Matchers.tests.cpp b/packages/Catch2/projects/SelfTest/UsageTests/Matchers.tests.cpp
index f07481d46..80e0420fe 100644
--- a/packages/Catch2/projects/SelfTest/UsageTests/Matchers.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/UsageTests/Matchers.tests.cpp
@@ -52,10 +52,16 @@ namespace { namespace MatchersTests {
         int i;
     };
 
+    struct DerivedException : std::exception {
+        char const* what() const noexcept override {
+            return "DerivedException::what";
+        }
+    };
+
     void doesNotThrow() {}
 
     [[noreturn]]
-    void throws(int i) {
+    void throwsSpecialException(int i) {
         throw SpecialException{i};
     }
 
@@ -64,6 +70,11 @@ namespace { namespace MatchersTests {
         throw i;
     }
 
+    [[noreturn]]
+    void throwsDerivedException() {
+        throw DerivedException{};
+    }
+
     class ExceptionMatcher : public Catch::MatcherBase<SpecialException> {
         int m_expected;
     public:
@@ -213,6 +224,16 @@ namespace { namespace MatchersTests {
             v2.push_back(1);
             v2.push_back(2);
 
+            std::vector<double> v3;
+            v3.push_back(1);
+            v3.push_back(2);
+            v3.push_back(3);
+
+            std::vector<double> v4;
+            v4.push_back(1 + 1e-8);
+            v4.push_back(2 + 1e-8);
+            v4.push_back(3 + 1e-8);
+
             std::vector<int> empty;
 
             SECTION("Contains (element)") {
@@ -265,6 +286,16 @@ namespace { namespace MatchersTests {
             v2.push_back(1);
             v2.push_back(2);
 
+            std::vector<double> v3;
+            v3.push_back(1);
+            v3.push_back(2);
+            v3.push_back(3);
+
+            std::vector<double> v4;
+            v4.push_back(1.1);
+            v4.push_back(2.1);
+            v4.push_back(3.1);
+
             std::vector<int> empty;
 
             SECTION("Contains (element)") {
@@ -299,8 +330,8 @@ namespace { namespace MatchersTests {
         }
 
         TEST_CASE("Exception matchers that succeed", "[matchers][exceptions][!throws]") {
-            CHECK_THROWS_MATCHES(throws(1), SpecialException, ExceptionMatcher{1});
-            REQUIRE_THROWS_MATCHES(throws(2), SpecialException, ExceptionMatcher{2});
+            CHECK_THROWS_MATCHES(throwsSpecialException(1), SpecialException, ExceptionMatcher{1});
+            REQUIRE_THROWS_MATCHES(throwsSpecialException(2), SpecialException, ExceptionMatcher{2});
         }
 
         TEST_CASE("Exception matchers that fail", "[matchers][exceptions][!throws][.failing]") {
@@ -313,12 +344,26 @@ namespace { namespace MatchersTests {
                 REQUIRE_THROWS_MATCHES(throwsAsInt(1), SpecialException, ExceptionMatcher{1});
             }
             SECTION("Contents are wrong") {
-                CHECK_THROWS_MATCHES(throws(3), SpecialException, ExceptionMatcher{1});
-                REQUIRE_THROWS_MATCHES(throws(4), SpecialException, ExceptionMatcher{1});
+                CHECK_THROWS_MATCHES(throwsSpecialException(3), SpecialException, ExceptionMatcher{1});
+                REQUIRE_THROWS_MATCHES(throwsSpecialException(4), SpecialException, ExceptionMatcher{1});
             }
         }
 
         TEST_CASE("Floating point matchers: float", "[matchers][floating-point]") {
+            SECTION("Relative") {
+                REQUIRE_THAT(10.f,  WithinRel(11.1f, 0.1f));
+                REQUIRE_THAT(10.f, !WithinRel(11.2f, 0.1f));
+                REQUIRE_THAT( 1.f, !WithinRel(0.f, 0.99f));
+                REQUIRE_THAT(-0.f,  WithinRel(0.f));
+                SECTION("Some subnormal values") {
+                    auto v1 = std::numeric_limits<float>::min();
+                    auto v2 = v1;
+                    for (int i = 0; i < 5; ++i) {
+                        v2 = std::nextafter(v1, 0.f);
+                    }
+                    REQUIRE_THAT(v1, WithinRel(v2));
+                }
+            }
             SECTION("Margin") {
                 REQUIRE_THAT(1.f, WithinAbs(1.f, 0));
                 REQUIRE_THAT(0.f, WithinAbs(1.f, 1));
@@ -327,7 +372,6 @@ namespace { namespace MatchersTests {
                 REQUIRE_THAT(0.f, !WithinAbs(1.f, 0.99f));
 
                 REQUIRE_THAT(0.f, WithinAbs(-0.f, 0));
-                REQUIRE_THAT(NAN, !WithinAbs(NAN, 0));
 
                 REQUIRE_THAT(11.f, !WithinAbs(10.f, 0.5f));
                 REQUIRE_THAT(10.f, !WithinAbs(11.f, 0.5f));
@@ -338,30 +382,46 @@ namespace { namespace MatchersTests {
                 REQUIRE_THAT(1.f, WithinULP(1.f, 0));
 
                 REQUIRE_THAT(nextafter(1.f, 2.f), WithinULP(1.f, 1));
-                REQUIRE_THAT(nextafter(1.f, 0.f), WithinULP(1.f, 1));
-                REQUIRE_THAT(nextafter(1.f, 2.f), !WithinULP(1.f, 0));
+                REQUIRE_THAT(0.f, WithinULP(nextafter(0.f, 1.f), 1));
+                REQUIRE_THAT(1.f, WithinULP(nextafter(1.f, 0.f), 1));
+                REQUIRE_THAT(1.f, !WithinULP(nextafter(1.f, 2.f), 0));
 
                 REQUIRE_THAT(1.f, WithinULP(1.f, 0));
                 REQUIRE_THAT(-0.f, WithinULP(0.f, 0));
-
-                REQUIRE_THAT(NAN, !WithinULP(NAN, 123));
             }
             SECTION("Composed") {
                 REQUIRE_THAT(1.f, WithinAbs(1.f, 0.5) || WithinULP(1.f, 1));
                 REQUIRE_THAT(1.f, WithinAbs(2.f, 0.5) || WithinULP(1.f, 0));
-
-                REQUIRE_THAT(NAN, !(WithinAbs(NAN, 100) || WithinULP(NAN, 123)));
+                REQUIRE_THAT(0.0001f, WithinAbs(0.f, 0.001f) || WithinRel(0.f, 0.1f));
             }
             SECTION("Constructor validation") {
                 REQUIRE_NOTHROW(WithinAbs(1.f, 0.f));
                 REQUIRE_THROWS_AS(WithinAbs(1.f, -1.f), std::domain_error);
 
                 REQUIRE_NOTHROW(WithinULP(1.f, 0));
-                REQUIRE_THROWS_AS(WithinULP(1.f, -1), std::domain_error);
+                REQUIRE_THROWS_AS(WithinULP(1.f, static_cast<uint64_t>(-1)), std::domain_error);
+
+                REQUIRE_NOTHROW(WithinRel(1.f, 0.f));
+                REQUIRE_THROWS_AS(WithinRel(1.f, -0.2f), std::domain_error);
+                REQUIRE_THROWS_AS(WithinRel(1.f, 1.f), std::domain_error);
             }
         }
 
         TEST_CASE("Floating point matchers: double", "[matchers][floating-point]") {
+            SECTION("Relative") {
+                REQUIRE_THAT(10., WithinRel(11.1, 0.1));
+                REQUIRE_THAT(10., !WithinRel(11.2, 0.1));
+                REQUIRE_THAT(1., !WithinRel(0., 0.99));
+                REQUIRE_THAT(-0., WithinRel(0.));
+                SECTION("Some subnormal values") {
+                    auto v1 = std::numeric_limits<double>::min();
+                    auto v2 = v1;
+                    for (int i = 0; i < 5; ++i) {
+                        v2 = std::nextafter(v1, 0);
+                    }
+                    REQUIRE_THAT(v1, WithinRel(v2));
+                }
+            }
             SECTION("Margin") {
                 REQUIRE_THAT(1., WithinAbs(1., 0));
                 REQUIRE_THAT(0., WithinAbs(1., 1));
@@ -369,8 +429,6 @@ namespace { namespace MatchersTests {
                 REQUIRE_THAT(0., !WithinAbs(1., 0.99));
                 REQUIRE_THAT(0., !WithinAbs(1., 0.99));
 
-                REQUIRE_THAT(NAN, !WithinAbs(NAN, 0));
-
                 REQUIRE_THAT(11., !WithinAbs(10., 0.5));
                 REQUIRE_THAT(10., !WithinAbs(11., 0.5));
                 REQUIRE_THAT(-10., WithinAbs(-10., 0.5));
@@ -380,29 +438,43 @@ namespace { namespace MatchersTests {
                 REQUIRE_THAT(1., WithinULP(1., 0));
 
                 REQUIRE_THAT(nextafter(1., 2.), WithinULP(1., 1));
-                REQUIRE_THAT(nextafter(1., 0.), WithinULP(1., 1));
-                REQUIRE_THAT(nextafter(1., 2.), !WithinULP(1., 0));
+                REQUIRE_THAT(0.,  WithinULP(nextafter(0., 1.), 1));
+                REQUIRE_THAT(1.,  WithinULP(nextafter(1., 0.), 1));
+                REQUIRE_THAT(1., !WithinULP(nextafter(1., 2.), 0));
 
                 REQUIRE_THAT(1., WithinULP(1., 0));
                 REQUIRE_THAT(-0., WithinULP(0., 0));
-
-                REQUIRE_THAT(NAN, !WithinULP(NAN, 123));
             }
             SECTION("Composed") {
                 REQUIRE_THAT(1., WithinAbs(1., 0.5) || WithinULP(2., 1));
                 REQUIRE_THAT(1., WithinAbs(2., 0.5) || WithinULP(1., 0));
-
-                REQUIRE_THAT(NAN, !(WithinAbs(NAN, 100) || WithinULP(NAN, 123)));
+                REQUIRE_THAT(0.0001, WithinAbs(0., 0.001) || WithinRel(0., 0.1));
             }
             SECTION("Constructor validation") {
                 REQUIRE_NOTHROW(WithinAbs(1., 0.));
                 REQUIRE_THROWS_AS(WithinAbs(1., -1.), std::domain_error);
 
                 REQUIRE_NOTHROW(WithinULP(1., 0));
-                REQUIRE_THROWS_AS(WithinULP(1., -1), std::domain_error);
+
+                REQUIRE_NOTHROW(WithinRel(1., 0.));
+                REQUIRE_THROWS_AS(WithinRel(1., -0.2), std::domain_error);
+                REQUIRE_THROWS_AS(WithinRel(1., 1.), std::domain_error);
             }
         }
 
+        TEST_CASE("Floating point matchers that are problematic in approvals", "[approvals][matchers][floating-point]") {
+            REQUIRE_THAT(NAN, !WithinAbs(NAN, 0));
+            REQUIRE_THAT(NAN, !(WithinAbs(NAN, 100) || WithinULP(NAN, 123)));
+            REQUIRE_THAT(NAN, !WithinULP(NAN, 123));
+            REQUIRE_THAT(INFINITY, WithinRel(INFINITY));
+            REQUIRE_THAT(-INFINITY, !WithinRel(INFINITY));
+            REQUIRE_THAT(1., !WithinRel(INFINITY));
+            REQUIRE_THAT(INFINITY, !WithinRel(1.));
+            REQUIRE_THAT(NAN, !WithinRel(NAN));
+            REQUIRE_THAT(1., !WithinRel(NAN));
+            REQUIRE_THAT(NAN, !WithinRel(1.));
+        }
+
         TEST_CASE("Arbitrary predicate matcher", "[matchers][generic]") {
             SECTION("Function pointer") {
                 REQUIRE_THAT(1,  Predicate<int>(alwaysTrue, "always true"));
@@ -436,6 +508,51 @@ namespace { namespace MatchersTests {
             REQUIRE_THAT("foo", Predicate<const char*>([] (const char* const&) { return true; }));
         }
 
+        TEST_CASE("Vector Approx matcher", "[matchers][approx][vector]") {
+            using Catch::Matchers::Approx;
+            SECTION("Empty vector is roughly equal to an empty vector") {
+                std::vector<double> empty;
+                REQUIRE_THAT(empty, Approx(empty));
+            }
+            SECTION("Vectors with elements") {
+                std::vector<double> v1({1., 2., 3.});
+                SECTION("A vector is approx equal to itself") {
+                    REQUIRE_THAT(v1, Approx(v1));
+                }
+                std::vector<double> v2({1.5, 2.5, 3.5});
+                SECTION("Different length") {
+                    auto temp(v1);
+                    temp.push_back(4);
+                    REQUIRE_THAT(v1, !Approx(temp));
+                }
+                SECTION("Same length, different elements") {
+                    REQUIRE_THAT(v1, !Approx(v2));
+                    REQUIRE_THAT(v1, Approx(v2).margin(0.5));
+                    REQUIRE_THAT(v1, Approx(v2).epsilon(0.5));
+                    REQUIRE_THAT(v1, Approx(v2).epsilon(0.1).scale(500));
+                }
+            }
+        }
+
+        TEST_CASE("Vector Approx matcher -- failing", "[matchers][approx][vector][.failing]") {
+            using Catch::Matchers::Approx;
+            SECTION("Empty and non empty vectors are not approx equal") {
+                std::vector<double> empty, t1({1, 2});
+                CHECK_THAT(empty, Approx(t1));
+            }
+            SECTION("Just different vectors") {
+                std::vector<double> v1({2., 4., 6.}), v2({1., 3., 5.});
+                CHECK_THAT(v1, Approx(v2));
+            }
+        }
+
+        TEST_CASE("Exceptions matchers", "[matchers][exceptions][!throws]") {
+            REQUIRE_THROWS_MATCHES(throwsDerivedException(),  DerivedException,  Message("DerivedException::what"));
+            REQUIRE_THROWS_MATCHES(throwsDerivedException(),  DerivedException, !Message("derivedexception::what"));
+            REQUIRE_THROWS_MATCHES(throwsSpecialException(2), SpecialException, !Message("DerivedException::what"));
+            REQUIRE_THROWS_MATCHES(throwsSpecialException(2), SpecialException,  Message("SpecialException::what"));
+        }
+
 } } // namespace MatchersTests
 
 #endif // CATCH_CONFIG_DISABLE_MATCHERS
diff --git a/packages/Catch2/projects/SelfTest/UsageTests/Message.tests.cpp b/packages/Catch2/projects/SelfTest/UsageTests/Message.tests.cpp
index 50992cebb..933470845 100644
--- a/packages/Catch2/projects/SelfTest/UsageTests/Message.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/UsageTests/Message.tests.cpp
@@ -227,9 +227,9 @@ TEST_CASE( "CAPTURE can deal with complex expressions", "[messages][capture]" )
 
 template <typename T1, typename T2>
 struct helper_1436 {
-    helper_1436(T1 t1, T2 t2):
-        t1{ t1 },
-        t2{ t2 }
+    helper_1436(T1 t1_, T2 t2_):
+        t1{ t1_ },
+        t2{ t2_ }
     {}
     T1 t1;
     T2 t2;
@@ -251,6 +251,13 @@ TEST_CASE("CAPTURE can deal with complex expressions involving commas", "[messag
     SUCCEED();
 }
 
+TEST_CASE("CAPTURE parses string and character constants", "[messages][capture]") {
+    CAPTURE(("comma, in string", "escaped, \", "), "single quote in string,',", "some escapes, \\,\\\\");
+    CAPTURE("some, ), unmatched, } prenheses {[<");
+    CAPTURE('"', '\'', ',', '}', ')', '(', '{');
+    SUCCEED();
+}
+
 #ifdef __clang__
 #pragma clang diagnostic pop
 #endif
diff --git a/packages/Catch2/projects/SelfTest/UsageTests/Misc.tests.cpp b/packages/Catch2/projects/SelfTest/UsageTests/Misc.tests.cpp
index 4de6f1aa0..188bc2d7c 100644
--- a/packages/Catch2/projects/SelfTest/UsageTests/Misc.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/UsageTests/Misc.tests.cpp
@@ -18,6 +18,7 @@
 #include <cerrno>
 #include <limits>
 #include <sstream>
+#include <array>
 
 namespace { namespace MiscTests {
 
@@ -66,6 +67,10 @@ struct Foo {
     size_t size() { return 0; }
 };
 
+template<typename T, size_t S>
+struct Bar {
+    size_t size() { return S; }
+};
 #endif
 
 TEST_CASE( "random SECTION tests", "[.][sections][failing]" ) {
@@ -306,15 +311,91 @@ TEMPLATE_TEST_CASE( "TemplateTest: vectors can be sized and resized", "[vector][
     }
 }
 
+TEMPLATE_TEST_CASE_SIG("TemplateTestSig: vectors can be sized and resized", "[vector][template][nttp]", ((typename TestType, int V), TestType, V), (int,5), (float,4), (std::string,15), ((std::tuple<int, float>), 6)) {
+
+    std::vector<TestType> v(V);
+
+    REQUIRE(v.size() == V);
+    REQUIRE(v.capacity() >= V);
+
+    SECTION("resizing bigger changes size and capacity") {
+        v.resize(2 * V);
+
+        REQUIRE(v.size() == 2 * V);
+        REQUIRE(v.capacity() >= 2 * V);
+    }
+    SECTION("resizing smaller changes size but not capacity") {
+        v.resize(0);
+
+        REQUIRE(v.size() == 0);
+        REQUIRE(v.capacity() >= V);
+
+        SECTION("We can use the 'swap trick' to reset the capacity") {
+            std::vector<TestType> empty;
+            empty.swap(v);
+
+            REQUIRE(v.capacity() == 0);
+        }
+    }
+    SECTION("reserving bigger changes capacity but not size") {
+        v.reserve(2 * V);
+
+        REQUIRE(v.size() == V);
+        REQUIRE(v.capacity() >= 2 * V);
+    }
+    SECTION("reserving smaller does not change size or capacity") {
+        v.reserve(0);
+
+        REQUIRE(v.size() == V);
+        REQUIRE(v.capacity() >= V);
+    }
+}
+
 TEMPLATE_PRODUCT_TEST_CASE("A Template product test case", "[template][product]", (std::vector, Foo), (int, float)) {
     TestType x;
     REQUIRE(x.size() == 0);
 }
 
+TEMPLATE_PRODUCT_TEST_CASE_SIG("A Template product test case with array signature", "[template][product][nttp]", ((typename T, size_t S), T, S), (std::array, Bar), ((int, 9), (float, 42))) {
+    TestType x;
+    REQUIRE(x.size() > 0);
+}
+
 TEMPLATE_PRODUCT_TEST_CASE("Product with differing arities", "[template][product]", std::tuple, (int, (int, double), (int, double, float))) {
     REQUIRE(std::tuple_size<TestType>::value >= 1);
 }
 
+using MyTypes = std::tuple<int, char, float>;
+TEMPLATE_LIST_TEST_CASE("Template test case with test types specified inside std::tuple", "[template][list]", MyTypes)
+{
+    REQUIRE(sizeof(TestType) > 0);
+}
+
+struct NonDefaultConstructibleType {
+    NonDefaultConstructibleType() = delete;
+};
+
+using MyNonDefaultConstructibleTypes = std::tuple<NonDefaultConstructibleType, float>;
+TEMPLATE_LIST_TEST_CASE("Template test case with test types specified inside non-default-constructible std::tuple", "[template][list]", MyNonDefaultConstructibleTypes)
+{
+    REQUIRE(sizeof(TestType) > 0);
+}
+
+struct NonCopyableAndNonMovableType {
+    NonCopyableAndNonMovableType() = default;
+
+    NonCopyableAndNonMovableType(NonCopyableAndNonMovableType const &) = delete;
+    NonCopyableAndNonMovableType(NonCopyableAndNonMovableType &&) = delete;
+    auto operator=(NonCopyableAndNonMovableType const &) -> NonCopyableAndNonMovableType & = delete;
+    auto operator=(NonCopyableAndNonMovableType &&) -> NonCopyableAndNonMovableType & = delete;
+};
+
+using NonCopyableAndNonMovableTypes = std::tuple<NonCopyableAndNonMovableType, float>;
+TEMPLATE_LIST_TEST_CASE("Template test case with test types specified inside non-copyable and non-movable std::tuple", "[template][list]", NonCopyableAndNonMovableTypes)
+{
+    REQUIRE(sizeof(TestType) > 0);
+}
+
 // https://github.com/philsquared/Catch/issues/166
 TEST_CASE("A couple of nested sections followed by a failure", "[failing][.]") {
     SECTION("Outer")
@@ -374,12 +455,6 @@ TEST_CASE( "long long" ) {
     REQUIRE( l == std::numeric_limits<long long>::max() );
 }
 
-//TEST_CASE( "Divide by Zero signal handler", "[.][sig]" ) {
-//    int i = 0;
-//    int x = 10/i; // This should cause the signal to fire
-//    CHECK( x == 0 );
-//}
-
 TEST_CASE( "This test 'should' fail but doesn't", "[.][failing][!shouldfail]" ) {
     SUCCEED( "oops!" );
 }
diff --git a/packages/Catch2/projects/SelfTest/UsageTests/ToStringByte.tests.cpp b/packages/Catch2/projects/SelfTest/UsageTests/ToStringByte.tests.cpp
new file mode 100644
index 000000000..0aad679f3
--- /dev/null
+++ b/packages/Catch2/projects/SelfTest/UsageTests/ToStringByte.tests.cpp
@@ -0,0 +1,15 @@
+#include "catch.hpp"
+
+#if defined(CATCH_CONFIG_CPP17_BYTE)
+
+TEST_CASE( "std::byte -> toString", "[toString][byte][approvals]" ) {
+    using type = std::byte;
+    REQUIRE( "0" == ::Catch::Detail::stringify( type{ 0 } ) );
+}
+
+TEST_CASE( "std::vector<std::byte> -> toString", "[toString][byte][approvals]" ) {
+    using type = std::vector<std::byte>;
+    REQUIRE( "{ 0, 1, 2 }" == ::Catch::Detail::stringify( type{ std::byte{0}, std::byte{1}, std::byte{2} } ) );
+}
+
+#endif // CATCH_INTERNAL_CONFIG_CPP17_BYTE
diff --git a/packages/Catch2/projects/SelfTest/UsageTests/ToStringGeneral.tests.cpp b/packages/Catch2/projects/SelfTest/UsageTests/ToStringGeneral.tests.cpp
index 09ac30451..69d6320d9 100644
--- a/packages/Catch2/projects/SelfTest/UsageTests/ToStringGeneral.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/UsageTests/ToStringGeneral.tests.cpp
@@ -128,6 +128,40 @@ TEST_CASE("String views are stringified like other strings", "[toString][approva
 
 #endif
 
+TEST_CASE("Precision of floating point stringification can be set", "[toString][floatingPoint]") {
+    SECTION("Floats") {
+        using sm = Catch::StringMaker<float>;
+        const auto oldPrecision = sm::precision;
+
+        const float testFloat = 1.12345678901234567899f;
+        auto str1 = sm::convert(testFloat);
+        sm::precision = 5;
+        // "1." prefix = 2 chars, f suffix is another char
+        CHECK(str1.size() == 3 + 5);
+
+        sm::precision = 10;
+        auto str2 = sm::convert(testFloat);
+        REQUIRE(str2.size() == 3 + 10);
+        sm::precision = oldPrecision;
+    }
+    SECTION("Double") {
+        using sm = Catch::StringMaker<double>;
+        const auto oldPrecision = sm::precision;
+
+        const double testDouble = 1.123456789012345678901234567899;
+        sm::precision = 5;
+        auto str1 = sm::convert(testDouble);
+        // "1." prefix = 2 chars
+        CHECK(str1.size() == 2 + 5);
+
+        sm::precision = 15;
+        auto str2 = sm::convert(testDouble);
+        REQUIRE(str2.size() == 2 + 15);
+
+        sm::precision = oldPrecision;
+    }
+}
+
 namespace {
 
 struct WhatException : std::exception {
diff --git a/packages/Catch2/projects/SelfTest/UsageTests/Tricky.tests.cpp b/packages/Catch2/projects/SelfTest/UsageTests/Tricky.tests.cpp
index ea507a888..d8e5465bb 100644
--- a/packages/Catch2/projects/SelfTest/UsageTests/Tricky.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/UsageTests/Tricky.tests.cpp
@@ -402,32 +402,6 @@ TEST_CASE( "non-copyable objects", "[.][failing]" ) {
     CHECK( ti == typeid(int) );
 }
 
-// #925
-using signal_t = void (*) (void*);
-
-struct TestClass {
-    signal_t testMethod_uponComplete_arg = nullptr;
-};
-
-namespace utility {
-    inline static void synchronizing_callback( void * ) { }
-}
-
-TEST_CASE("#925: comparing function pointer to function address failed to compile", "[!nonportable]" ) {
-
-    TestClass test;
-    REQUIRE(utility::synchronizing_callback != test.testMethod_uponComplete_arg);
-}
-
-TEST_CASE( "Bitfields can be captured (#1027)" ) {
-    struct Y {
-        uint32_t v : 1;
-    };
-    Y y{ 0 };
-    REQUIRE( y.v == 0 );
-    REQUIRE( 0 == y.v );
-}
-
 TEST_CASE("#1514: stderr/stdout is not captured in tests aborted by an exception", "[output-capture][regression][.]") {
     std::cout << "This would not be caught previously\n" << std::flush;
     std::clog << "Nor would this\n" << std::flush;
diff --git a/packages/Catch2/projects/SelfTest/WarnAboutNoTests.cmake b/packages/Catch2/projects/SelfTest/WarnAboutNoTests.cmake
new file mode 100644
index 000000000..4637e3f3c
--- /dev/null
+++ b/packages/Catch2/projects/SelfTest/WarnAboutNoTests.cmake
@@ -0,0 +1,19 @@
+# Workaround for a peculiarity where CTest disregards the return code from a
+# test command if a PASS_REGULAR_EXPRESSION is also set
+execute_process(
+    COMMAND ${CMAKE_ARGV3} -w NoTests "___nonexistent_test___"
+    RESULT_VARIABLE ret
+    OUTPUT_VARIABLE out
+)
+
+message("${out}")
+
+if(NOT ${ret} MATCHES "^[0-9]+$")
+    message(FATAL_ERROR "${ret}")
+endif()
+
+if(${ret} EQUAL 0)
+    message(FATAL_ERROR "Expected nonzero return code")
+elseif(${out} MATCHES "Helper failed with")
+    message(FATAL_ERROR "Helper failed")
+endif()
diff --git a/packages/Catch2/projects/Where did the projects go.txt b/packages/Catch2/projects/Where did the projects go.txt
deleted file mode 100644
index c7b011d55..000000000
--- a/packages/Catch2/projects/Where did the projects go.txt	
+++ /dev/null
@@ -1,13 +0,0 @@
-The canonical project format is now CMake.
-To generate an XCode or Visual Studio project you'll need CMake, which you can download from https://cmake.org if necessary.
-
-To generate the project files open a terminal/ console within the projects directory (where this file is located), create a directory called "Generated" (using mkdir or md), cd into it, then type:
-
-CMake -G <project format> ../..
-
-Where <project format> is XCode for XCode projects, or "Visual Studio 14" for Visual Studio 2015 (replace 14 with the major version number for any other supported Visual Studio version - or execute CMake -help for the full list)
-
-Remember to re-run CMake any time you pull from GitHub.
-Note that the projects/Generated folder is excluded in .gitignore. So it is recommended to use this.
-
-CMake can also generate make files or projects for other build systems. Run CMake -help for the full set of options.
diff --git a/packages/Catch2/scripts/extractFeaturesFromReleaseNotes.py b/packages/Catch2/scripts/extractFeaturesFromReleaseNotes.py
new file mode 100644
index 000000000..090f4772a
--- /dev/null
+++ b/packages/Catch2/scripts/extractFeaturesFromReleaseNotes.py
@@ -0,0 +1,94 @@
+#!/usr/bin/env python
+
+#
+# extractFeaturesFromReleaseNotes.py
+#
+# Read the release notes - docs/release-notes.md - and generate text
+# for pasting in to individual documentation pages, to indicate which
+# versions recent features were released in.
+#
+# Using the output of the file is easier than manually constructing
+# the text to paste in to documentation pages.
+#
+# One way to use this:
+# - run this script, saving the output to some temporary file
+# - diff this output with the actual release notes page
+# - the differences are Markdown text that can be pasted in to the
+#   appropriate documentation pages in the docs/ directory.
+# - each release also has a github link to show which documentation files
+#   were changed in it.
+#   This can be helpful to see which documentation pages
+#   to add the 'Introduced in Catch ...' snippets to the relevant pages.
+#
+
+from __future__ import print_function
+
+import re
+
+
+def create_introduced_in_text(version, bug_number = None):
+    """Generate text to paste in to documentation file"""
+    if bug_number:
+        return '> [Introduced](https://github.com/catchorg/Catch2/issues/%s) in Catch %s.' % (bug_number, version)
+    else:
+        # Use this text for changes that don't have issue numbers
+        return '> Introduced in Catch %s.' % version
+
+
+def link_to_changes_in_release(release, releases):
+    """
+    Markdown text for a hyperlink showing all edits in a release, or empty string
+
+    :param release: A release version, as a string 
+    :param releases: A container of releases, in descending order - newest to oldest
+    :return: Markdown text for a hyperlink showing the differences between the give release and the prior one,
+             or empty string, if the previous release is not known
+    """
+
+    if release == releases[-1]:
+        # This is the earliest release we know about
+        return ''
+    index = releases.index(release)
+    previous_release = releases[index + 1]
+    return '\n[Changes in %s](https://github.com/catchorg/Catch2/compare/v%s...v%s)' % (release, previous_release, release)
+
+
+def write_recent_release_notes_with_introduced_text():
+    current_version = None
+    release_toc_regex = r'\[(\d.\d.\d)\]\(#\d+\)<br>'
+    issue_number_regex = r'#[0-9]+'
+    releases = []
+    with open('../docs/release-notes.md') as release_notes:
+        for line in release_notes:
+            line = line[:-1]
+            print(line)
+
+            # Extract version number from table of contents
+            match = re.search(release_toc_regex, line)
+            if match:
+                release_name = match.group(1)
+                releases.append(release_name)
+
+            if line.startswith('## '):
+                # It's a section with version number
+                current_version = line.replace('## ', '')
+
+                # We decided not to add released-date info for older versions
+                if current_version == 'Older versions':
+                    break
+
+                print(create_introduced_in_text(current_version))
+                print(link_to_changes_in_release(current_version, releases))
+
+            # Not yet found a version number, so to avoid picking up hyperlinks to
+            # version numbers in the index, keep going
+            if not current_version:
+                continue
+
+            for bug_link in re.findall(issue_number_regex, line):
+                bug_number = bug_link.replace('#', '')
+                print(create_introduced_in_text(current_version, bug_number))
+
+
+if __name__ == '__main__':
+    write_recent_release_notes_with_introduced_text()
diff --git a/packages/Catch2/scripts/generateSingleHeader.py b/packages/Catch2/scripts/generateSingleHeader.py
index 31033d683..f89687743 100755
--- a/packages/Catch2/scripts/generateSingleHeader.py
+++ b/packages/Catch2/scripts/generateSingleHeader.py
@@ -53,7 +53,7 @@ def generate(v):
             out.write( line )
 
     def insertCpps():
-        dirs = [os.path.join( rootPath, s) for s in ['', 'internal', 'reporters']]
+        dirs = [os.path.join( rootPath, s) for s in ['', 'internal', 'reporters', 'internal/benchmark', 'internal/benchmark/detail']]
         cppFiles = []
         for dir in dirs:
             cppFiles += glob(os.path.join(dir, '*.cpp'))
diff --git a/packages/Catch2/scripts/releaseCommon.py b/packages/Catch2/scripts/releaseCommon.py
index 9cdc4f6c1..102fe46a0 100644
--- a/packages/Catch2/scripts/releaseCommon.py
+++ b/packages/Catch2/scripts/releaseCommon.py
@@ -4,6 +4,8 @@ import os
 import sys
 import re
 import string
+import glob
+import fnmatch
 
 from scriptCommon import catchPath
 
@@ -98,29 +100,47 @@ def updateReadmeFile(version):
 
 
 def updateCmakeFile(version):
-    with open(cmakePath, 'r') as file:
+    with open(cmakePath, 'rb') as file:
         lines = file.readlines()
-    with open(cmakePath, 'w') as file:
+    replacementRegex = re.compile(b'project\\(Catch2 LANGUAGES CXX VERSION \\d+\\.\\d+\\.\\d+\\)')
+    replacement = 'project(Catch2 LANGUAGES CXX VERSION {0})'.format(version.getVersionString()).encode('ascii')
+    with open(cmakePath, 'wb') as file:
         for line in lines:
-            if 'project(Catch2 LANGUAGES CXX VERSION ' in line:
-                file.write('project(Catch2 LANGUAGES CXX VERSION {0})\n'.format(version.getVersionString()))
-            else:
-                file.write(line)
+            file.write(replacementRegex.sub(replacement, line))
 
 
 def updateVersionDefine(version):
-    with open(definePath, 'r') as file:
+    # First member of the tuple is the compiled regex object, the second is replacement if it matches
+    replacementRegexes = [(re.compile(b'#define CATCH_VERSION_MAJOR \\d+'),'#define CATCH_VERSION_MAJOR {}'.format(version.majorVersion).encode('ascii')),
+                          (re.compile(b'#define CATCH_VERSION_MINOR \\d+'),'#define CATCH_VERSION_MINOR {}'.format(version.minorVersion).encode('ascii')),
+                          (re.compile(b'#define CATCH_VERSION_PATCH \\d+'),'#define CATCH_VERSION_PATCH {}'.format(version.patchNumber).encode('ascii')),
+                         ]
+    with open(definePath, 'rb') as file:
         lines = file.readlines()
-    with open(definePath, 'w') as file:
+    with open(definePath, 'wb') as file:
         for line in lines:
-            if '#define CATCH_VERSION_MAJOR' in line:
-                file.write('#define CATCH_VERSION_MAJOR {}\n'.format(version.majorVersion))
-            elif '#define CATCH_VERSION_MINOR' in line:
-                file.write('#define CATCH_VERSION_MINOR {}\n'.format(version.minorVersion))
-            elif '#define CATCH_VERSION_PATCH' in line:
-                file.write('#define CATCH_VERSION_PATCH {}\n'.format(version.patchNumber))
-            else:
-                file.write(line)
+            for replacement in replacementRegexes:
+                line = replacement[0].sub(replacement[1], line)
+            file.write(line)
+
+
+def updateVersionPlaceholder(filename, version):
+    with open(filename, 'rb') as file:
+        lines = file.readlines()
+    placeholderRegex = re.compile(b' in Catch X.Y.Z')
+    replacement = ' in Catch {}.{}.{}'.format(version.majorVersion, version.minorVersion, version.patchNumber).encode('ascii')
+    with open(filename, 'wb') as file:
+        for line in lines:
+            file.write(placeholderRegex.sub(replacement, line))
+
+
+def updateDocumentationVersionPlaceholders(version):
+    print('Updating version placeholder in documentation')
+    docsPath = os.path.join(catchPath, 'docs/')
+    for basePath, _, files in os.walk(docsPath):
+        for file in files:
+            if fnmatch.fnmatch(file, "*.md") and "contributing.md" != file:
+                updateVersionPlaceholder(os.path.join(basePath, file), version)
 
 
 def performUpdates(version):
@@ -143,3 +163,4 @@ def performUpdates(version):
 
     updateReadmeFile(version)
     updateCmakeFile(version)
+    updateDocumentationVersionPlaceholders(version)
diff --git a/packages/Catch2/single_include/catch2/catch.hpp b/packages/Catch2/single_include/catch2/catch.hpp
index 98672c07d..391db530f 100644
--- a/packages/Catch2/single_include/catch2/catch.hpp
+++ b/packages/Catch2/single_include/catch2/catch.hpp
@@ -1,6 +1,6 @@
 /*
- *  Catch v2.7.1
- *  Generated: 2019-04-05 18:22:37.720122
+ *  Catch v2.10.0
+ *  Generated: 2019-10-13 22:24:46.755734
  *  ----------------------------------------------------------
  *  This file has been merged from multiple headers. Please don't edit it directly
  *  Copyright (c) 2019 Two Blue Cubes Ltd. All rights reserved.
@@ -14,8 +14,8 @@
 
 
 #define CATCH_VERSION_MAJOR 2
-#define CATCH_VERSION_MINOR 7
-#define CATCH_VERSION_PATCH 1
+#define CATCH_VERSION_MINOR 10
+#define CATCH_VERSION_PATCH 0
 
 #ifdef __clang__
 #    pragma clang system_header
@@ -157,6 +157,12 @@ namespace Catch {
 #       define CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS \
             _Pragma( "clang diagnostic pop" )
 
+#       define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
+            _Pragma( "clang diagnostic push" ) \
+            _Pragma( "clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"" )
+#       define CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS \
+            _Pragma( "clang diagnostic pop" )
+
 #endif // __clang__
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -180,6 +186,7 @@ namespace Catch {
 // Android somehow still does not support std::to_string
 #if defined(__ANDROID__)
 #    define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
+#    define CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE
 #endif
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -204,9 +211,9 @@ namespace Catch {
 // 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))
+           && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))
 
-#	define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
+#    define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
 
 # endif
 #endif // __CYGWIN__
@@ -233,7 +240,11 @@ namespace Catch {
 #  if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL)
 #    define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
 #  endif
+#endif // _MSC_VER
 
+#if defined(_REENTRANT) || defined(_MSC_VER)
+// Enable async processing, as -pthread is specified or no additional linking is required
+# define CATCH_INTERNAL_CONFIG_USE_ASYNC
 #endif // _MSC_VER
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -266,40 +277,53 @@ namespace Catch {
 #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
+
+// RTX is a special version of Windows that is real time.
+// This means that it is detected as Windows, but does not provide
+// the same set of capabilities as real Windows does.
+#if defined(UNDER_RTSS) || defined(RTX64_BUILD)
+    #define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
+    #define CATCH_INTERNAL_CONFIG_NO_ASYNC
+    #define CATCH_CONFIG_COLOUR_NONE
 #endif
 
-////////////////////////////////////////////////////////////////////////////////
-// Check if optional is available and usable
-#if defined(__has_include)
-#  if __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
-#    define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL
-#  endif // __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
-#endif // __has_include
+#if defined(__UCLIBC__)
+#define CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER
+#endif
 
-////////////////////////////////////////////////////////////////////////////////
-// Check if variant is available and usable
+// Various stdlib support checks that require __has_include
 #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)
-#    else
-#      define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
-#    endif // defined(__clang__) && (__clang_major__ < 8)
-#  endif // __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
-#endif // __has_include
+  // Check if string_view is available and usable
+  #if __has_include(<string_view>) && defined(CATCH_CPP17_OR_GREATER)
+  #    define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW
+  #endif
+
+  // Check if optional is available and usable
+  #  if __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
+  #    define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL
+  #  endif // __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
+
+  // Check if byte is available and usable
+  #  if __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
+  #    define CATCH_INTERNAL_CONFIG_CPP17_BYTE
+  #  endif // __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
+
+  // Check if variant is available and usable
+  #  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)
+  #    else
+  #      define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
+  #    endif // defined(__clang__) && (__clang_major__ < 8)
+  #  endif // __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
+#endif // defined(__has_include)
 
 #if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
 #   define CATCH_CONFIG_COUNTER
@@ -336,6 +360,10 @@ namespace Catch {
 #  define CATCH_CONFIG_CPP17_VARIANT
 #endif
 
+#if defined(CATCH_INTERNAL_CONFIG_CPP17_BYTE) && !defined(CATCH_CONFIG_NO_CPP17_BYTE) && !defined(CATCH_CONFIG_CPP17_BYTE)
+#  define CATCH_CONFIG_CPP17_BYTE
+#endif
+
 #if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
 #  define CATCH_INTERNAL_CONFIG_NEW_CAPTURE
 #endif
@@ -352,6 +380,18 @@ namespace Catch {
 #  define CATCH_CONFIG_POLYFILL_ISNAN
 #endif
 
+#if defined(CATCH_INTERNAL_CONFIG_USE_ASYNC)  && !defined(CATCH_INTERNAL_CONFIG_NO_ASYNC) && !defined(CATCH_CONFIG_NO_USE_ASYNC) && !defined(CATCH_CONFIG_USE_ASYNC)
+#  define CATCH_CONFIG_USE_ASYNC
+#endif
+
+#if defined(CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_NO_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_ANDROID_LOGWRITE)
+#  define CATCH_CONFIG_ANDROID_LOGWRITE
+#endif
+
+#if defined(CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_NO_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
+#  define CATCH_CONFIG_GLOBAL_NEXTAFTER
+#endif
+
 #if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
 #   define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
 #   define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS
@@ -364,6 +404,10 @@ namespace Catch {
 #   define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS
 #   define CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS
 #endif
+#if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS)
+#   define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS
+#   define CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS
+#endif
 
 #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
 #define CATCH_TRY if ((true))
@@ -427,7 +471,7 @@ namespace Catch {
         SourceLineInfo( SourceLineInfo&& )              noexcept = default;
         SourceLineInfo& operator = ( SourceLineInfo&& ) noexcept = default;
 
-        bool empty() const noexcept;
+        bool empty() const noexcept { return file[0] == '\0'; }
         bool operator == ( SourceLineInfo const& other ) const noexcept;
         bool operator < ( SourceLineInfo const& other ) const noexcept;
 
@@ -497,6 +541,7 @@ namespace Catch {
         virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const = 0;
     };
 
+    bool isThrowSafe( TestCase const& testCase, IConfig const& config );
     bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
     std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
     std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
@@ -509,6 +554,7 @@ namespace Catch {
 #include <cstddef>
 #include <string>
 #include <iosfwd>
+#include <cassert>
 
 namespace Catch {
 
@@ -522,6 +568,7 @@ namespace Catch {
     class StringRef {
     public:
         using size_type = std::size_t;
+        using const_iterator = const char*;
 
     private:
         friend struct StringRefTestAccess;
@@ -577,7 +624,9 @@ namespace Catch {
             return *this;
         }
 
-        operator std::string() const;
+        explicit operator std::string() const {
+            return std::string(m_start, m_size);
+        }
 
         void swap( StringRef& other ) noexcept;
 
@@ -585,7 +634,10 @@ namespace Catch {
         auto operator == ( StringRef const& other ) const noexcept -> bool;
         auto operator != ( StringRef const& other ) const noexcept -> bool;
 
-        auto operator[] ( size_type index ) const noexcept -> char;
+        auto operator[] ( size_type index ) const noexcept -> char {
+            assert(index < m_size);
+            return m_start[index];
+        }
 
     public: // named queries
         auto empty() const noexcept -> bool {
@@ -595,7 +647,6 @@ namespace Catch {
             return m_size;
         }
 
-        auto numberOfCharacters() const noexcept -> size_type;
         auto c_str() const -> char const*;
 
     public: // substrings and searches
@@ -605,15 +656,15 @@ namespace Catch {
         // Note that the pointer can change when if the StringRef is a substring
         auto currentData() const noexcept -> char const*;
 
+    public: // iterators
+        const_iterator begin() const { return m_start; }
+        const_iterator end() const { return m_start + m_size; }
+
     private: // ownership queries - may not be consistent between calls
         auto isOwned() const noexcept -> bool;
         auto isSubstring() const noexcept -> bool;
     };
 
-    auto operator + ( StringRef const& lhs, StringRef const& rhs ) -> std::string;
-    auto operator + ( StringRef const& lhs, char const* rhs ) -> std::string;
-    auto operator + ( char const* lhs, StringRef const& rhs ) -> std::string;
-
     auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&;
     auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&;
 
@@ -628,38 +679,6 @@ inline auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noex
 }
 
 // end catch_stringref.h
-// start catch_type_traits.hpp
-
-
-#include <type_traits>
-
-namespace Catch{
-
-#ifdef CATCH_CPP17_OR_GREATER
-	template <typename...>
-	inline constexpr auto is_unique = std::true_type{};
-
-	template <typename T, typename... Rest>
-	inline constexpr auto is_unique<T, Rest...> = std::bool_constant<
-		(!std::is_same_v<T, Rest> && ...) && is_unique<Rest...>
-	>{};
-#else
-
-template <typename...>
-struct is_unique : std::true_type{};
-
-template <typename T0, typename T1, typename... Rest>
-struct is_unique<T0, T1, Rest...> : std::integral_constant
-<bool,
-     !std::is_same<T0, T1>::value
-     && is_unique<T0, Rest...>::value
-     && is_unique<T1, Rest...>::value
->{};
-
-#endif
-}
-
-// end catch_type_traits.hpp
 // start catch_preprocessor.hpp
 
 
@@ -722,23 +741,156 @@ struct is_unique<T0, T1, Rest...> : std::integral_constant
 #define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) (INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) + 1)
 #endif
 
+#define INTERNAL_CATCH_MAKE_NAMESPACE2(...) ns_##__VA_ARGS__
+#define INTERNAL_CATCH_MAKE_NAMESPACE(name) INTERNAL_CATCH_MAKE_NAMESPACE2(name)
+
 #define INTERNAL_CATCH_REMOVE_PARENS(...) INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF __VA_ARGS__)
 
-#define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME2(Name, ...) INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME3(Name, __VA_ARGS__)
 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
-#define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME3(Name,...) Name " - " #__VA_ARGS__
-#define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME(Name,...) INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME2(Name, INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))
+#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>())
+#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))
 #else
-// MSVC is adding extra space and needs more calls to properly remove ()
-#define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME3(Name,...) Name " -" #__VA_ARGS__
-#define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME1(Name, ...) INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME2(Name, __VA_ARGS__)
-#define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME(Name, ...) INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME1(Name, INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)))
+#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) INTERNAL_CATCH_EXPAND_VARGS(decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>()))
+#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)))
 #endif
 
-#define INTERNAL_CATCH_MAKE_TYPE_LIST(types) Catch::TypeList<INTERNAL_CATCH_REMOVE_PARENS(types)>
+#define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(...)\
+    CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST,__VA_ARGS__)
+
+#define INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_0) INTERNAL_CATCH_REMOVE_PARENS(_0)
+#define INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_0, _1) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_1)
+#define INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_0, _1, _2) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_1, _2)
+#define INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_0, _1, _2, _3) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_1, _2, _3)
+#define INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_0, _1, _2, _3, _4) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_1, _2, _3, _4)
+#define INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_0, _1, _2, _3, _4, _5) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_1, _2, _3, _4, _5)
+#define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _4, _5, _6)
+#define INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_0, _1, _2, _3, _4, _5, _6, _7) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_1, _2, _3, _4, _5, _6, _7)
+#define INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_1, _2, _3, _4, _5, _6, _7, _8)
+#define INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9)
+#define INTERNAL_CATCH_REMOVE_PARENS_11_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10)
+
+#define INTERNAL_CATCH_VA_NARGS_IMPL(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
+
+#define INTERNAL_CATCH_TYPE_GEN\
+    template<typename...> struct TypeList {};\
+    template<typename...Ts>\
+    constexpr auto get_wrapper() noexcept -> TypeList<Ts...> { return {}; }\
+    \
+    template<template<typename...> class L1, typename...E1, template<typename...> class L2, typename...E2> \
+    constexpr auto append(L1<E1...>, L2<E2...>) noexcept -> L1<E1...,E2...> { return {}; }\
+    template< template<typename...> class L1, typename...E1, template<typename...> class L2, typename...E2, typename...Rest>\
+    constexpr auto append(L1<E1...>, L2<E2...>, Rest...) noexcept -> decltype(append(L1<E1...,E2...>{}, Rest{}...)) { return {}; }\
+    template< template<typename...> class L1, typename...E1, typename...Rest>\
+    constexpr auto append(L1<E1...>, TypeList<mpl_::na>, Rest...) noexcept -> L1<E1...> { return {}; }\
+    \
+    template< template<typename...> class Container, template<typename...> class List, typename...elems>\
+    constexpr auto rewrap(List<elems...>) noexcept -> TypeList<Container<elems...>> { return {}; }\
+    template< template<typename...> class Container, template<typename...> class List, class...Elems, typename...Elements>\
+    constexpr auto rewrap(List<Elems...>,Elements...) noexcept -> decltype(append(TypeList<Container<Elems...>>{}, rewrap<Container>(Elements{}...))) { return {}; }\
+    \
+    template<template <typename...> class Final, template< typename...> class...Containers, typename...Types>\
+    constexpr auto create(TypeList<Types...>) noexcept -> decltype(append(Final<>{}, rewrap<Containers>(Types{}...)...)) { return {}; }\
+    template<template <typename...> class Final, template <typename...> class List, typename...Ts>\
+    constexpr auto convert(const List<Ts...>& ) noexcept -> decltype(append(Final<>{},TypeList<Ts>{}...)) { return {}; }
+
+#define INTERNAL_CATCH_NTTP_1(signature, ...)\
+    template<INTERNAL_CATCH_REMOVE_PARENS(signature)> struct Nttp{};\
+    template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
+    constexpr auto get_wrapper() noexcept -> Nttp<__VA_ARGS__> { return {}; } \
+    \
+    template< template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature)>\
+    constexpr auto rewrap(List<__VA_ARGS__>) noexcept -> TypeList<Container<__VA_ARGS__>> { return {}; }\
+    template< template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature), typename...Elements>\
+    constexpr auto rewrap(List<__VA_ARGS__>,Elements...elems) noexcept -> decltype(append(TypeList<Container<__VA_ARGS__>>{}, rewrap<Container>(elems...))) { return {}; }\
+    template<template <typename...> class Final, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...Containers, typename...Types>\
+    constexpr auto create(TypeList<Types...>) noexcept -> decltype(append(Final<>{}, rewrap<Containers>(Types{}...)...)) { return {}; }
+
+#define INTERNAL_CATCH_DECLARE_SIG_TEST0(TestName)
+#define INTERNAL_CATCH_DECLARE_SIG_TEST1(TestName, signature)\
+    template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
+    static void TestName()
+#define INTERNAL_CATCH_DECLARE_SIG_TEST_X(TestName, signature, ...)\
+    template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
+    static void TestName()
+
+#define INTERNAL_CATCH_DEFINE_SIG_TEST0(TestName)
+#define INTERNAL_CATCH_DEFINE_SIG_TEST1(TestName, signature)\
+    template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
+    static void TestName()
+#define INTERNAL_CATCH_DEFINE_SIG_TEST_X(TestName, signature,...)\
+    template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
+    static void TestName()
+
+#define INTERNAL_CATCH_NTTP_REGISTER0(TestFunc, signature)\
+    template<typename Type>\
+    void reg_test(TypeList<Type>, Catch::NameAndTags nameAndTags)\
+    {\
+        Catch::AutoReg( Catch::makeTestInvoker(&TestFunc<Type>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), nameAndTags);\
+    }
+
+#define INTERNAL_CATCH_NTTP_REGISTER(TestFunc, signature, ...)\
+    template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
+    void reg_test(Nttp<__VA_ARGS__>, Catch::NameAndTags nameAndTags)\
+    {\
+        Catch::AutoReg( Catch::makeTestInvoker(&TestFunc<__VA_ARGS__>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), nameAndTags);\
+    }
+
+#define INTERNAL_CATCH_NTTP_REGISTER_METHOD0(TestName, signature, ...)\
+    template<typename Type>\
+    void reg_test(TypeList<Type>, Catch::StringRef className, Catch::NameAndTags nameAndTags)\
+    {\
+        Catch::AutoReg( Catch::makeTestInvoker(&TestName<Type>::test), CATCH_INTERNAL_LINEINFO, className, nameAndTags);\
+    }
+
+#define INTERNAL_CATCH_NTTP_REGISTER_METHOD(TestName, signature, ...)\
+    template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
+    void reg_test(Nttp<__VA_ARGS__>, Catch::StringRef className, Catch::NameAndTags nameAndTags)\
+    {\
+        Catch::AutoReg( Catch::makeTestInvoker(&TestName<__VA_ARGS__>::test), CATCH_INTERNAL_LINEINFO, className, nameAndTags);\
+    }
+
+#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0(TestName, ClassName)
+#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1(TestName, ClassName, signature)\
+    template<typename TestType> \
+    struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName)<TestType> { \
+        void test();\
+    }
+
+#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X(TestName, ClassName, signature, ...)\
+    template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
+    struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName)<__VA_ARGS__> { \
+        void test();\
+    }
+
+#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0(TestName)
+#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1(TestName, signature)\
+    template<typename TestType> \
+    void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName<TestType>::test()
+#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X(TestName, signature, ...)\
+    template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
+    void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName<__VA_ARGS__>::test()
 
-#define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(types)\
-    CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST,INTERNAL_CATCH_REMOVE_PARENS(types))
+#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+#define INTERNAL_CATCH_NTTP_0
+#define INTERNAL_CATCH_NTTP_GEN(...) INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__),INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_0)
+#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0)(TestName, __VA_ARGS__)
+#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0)(TestName, ClassName, __VA_ARGS__)
+#define INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD0, INTERNAL_CATCH_NTTP_REGISTER_METHOD0)(TestName, __VA_ARGS__)
+#define INTERNAL_CATCH_NTTP_REG_GEN(TestFunc, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER0, INTERNAL_CATCH_NTTP_REGISTER0)(TestFunc, __VA_ARGS__)
+#define INTERNAL_CATCH_DEFINE_SIG_TEST(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST1, INTERNAL_CATCH_DEFINE_SIG_TEST0)(TestName, __VA_ARGS__)
+#define INTERNAL_CATCH_DECLARE_SIG_TEST(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST1, INTERNAL_CATCH_DECLARE_SIG_TEST0)(TestName, __VA_ARGS__)
+#define INTERNAL_CATCH_REMOVE_PARENS_GEN(...) INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_REMOVE_PARENS_11_ARG,INTERNAL_CATCH_REMOVE_PARENS_10_ARG,INTERNAL_CATCH_REMOVE_PARENS_9_ARG,INTERNAL_CATCH_REMOVE_PARENS_8_ARG,INTERNAL_CATCH_REMOVE_PARENS_7_ARG,INTERNAL_CATCH_REMOVE_PARENS_6_ARG,INTERNAL_CATCH_REMOVE_PARENS_5_ARG,INTERNAL_CATCH_REMOVE_PARENS_4_ARG,INTERNAL_CATCH_REMOVE_PARENS_3_ARG,INTERNAL_CATCH_REMOVE_PARENS_2_ARG,INTERNAL_CATCH_REMOVE_PARENS_1_ARG)(__VA_ARGS__)
+#else
+#define INTERNAL_CATCH_NTTP_0(signature)
+#define INTERNAL_CATCH_NTTP_GEN(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1,INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_0)( __VA_ARGS__))
+#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0)(TestName, __VA_ARGS__))
+#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0)(TestName, ClassName, __VA_ARGS__))
+#define INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD0, INTERNAL_CATCH_NTTP_REGISTER_METHOD0)(TestName, __VA_ARGS__))
+#define INTERNAL_CATCH_NTTP_REG_GEN(TestFunc, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER0, INTERNAL_CATCH_NTTP_REGISTER0)(TestFunc, __VA_ARGS__))
+#define INTERNAL_CATCH_DEFINE_SIG_TEST(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST1, INTERNAL_CATCH_DEFINE_SIG_TEST0)(TestName, __VA_ARGS__))
+#define INTERNAL_CATCH_DECLARE_SIG_TEST(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST1, INTERNAL_CATCH_DECLARE_SIG_TEST0)(TestName, __VA_ARGS__))
+#define INTERNAL_CATCH_REMOVE_PARENS_GEN(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_REMOVE_PARENS_11_ARG,INTERNAL_CATCH_REMOVE_PARENS_10_ARG,INTERNAL_CATCH_REMOVE_PARENS_9_ARG,INTERNAL_CATCH_REMOVE_PARENS_8_ARG,INTERNAL_CATCH_REMOVE_PARENS_7_ARG,INTERNAL_CATCH_REMOVE_PARENS_6_ARG,INTERNAL_CATCH_REMOVE_PARENS_5_ARG,INTERNAL_CATCH_REMOVE_PARENS_4_ARG,INTERNAL_CATCH_REMOVE_PARENS_3_ARG,INTERNAL_CATCH_REMOVE_PARENS_2_ARG,INTERNAL_CATCH_REMOVE_PARENS_1_ARG)(__VA_ARGS__))
+#endif
 
 // end catch_preprocessor.hpp
 // start catch_meta.hpp
@@ -747,68 +899,29 @@ struct is_unique<T0, T1, Rest...> : std::integral_constant
 #include <type_traits>
 
 namespace Catch {
-template< typename... >
-struct TypeList {};
-
-template< typename... >
-struct append;
-
-template< template<typename...> class L1
-    , typename...E1
-    , template<typename...> class L2
-    , typename...E2
->
-struct append< L1<E1...>, L2<E2...> > {
-    using type = L1<E1..., E2...>;
-};
-
-template< template<typename...> class L1
-    , typename...E1
-    , template<typename...> class L2
-    , typename...E2
-    , typename...Rest
->
-struct append< L1<E1...>, L2<E2...>, Rest...> {
-    using type = typename append< L1<E1..., E2...>, Rest... >::type;
-};
-
-template< template<typename...> class
-    , typename...
->
-struct rewrap;
-
-template< template<typename...> class Container
-    , template<typename...> class List
-    , typename...elems
->
-struct rewrap<Container, List<elems...>> {
-    using type = TypeList< Container< elems... > >;
-};
+template<typename T>
+struct always_false : std::false_type {};
 
-template< template<typename...> class Container
-    , template<typename...> class List
-    , class...Elems
-    , typename...Elements>
-    struct rewrap<Container, List<Elems...>, Elements...> {
-    using type = typename append<TypeList<Container<Elems...>>, typename rewrap<Container, Elements...>::type>::type;
+template <typename> struct true_given : std::true_type {};
+struct is_callable_tester {
+    template <typename Fun, typename... Args>
+    true_given<decltype(std::declval<Fun>()(std::declval<Args>()...))> static test(int);
+    template <typename...>
+    std::false_type static test(...);
 };
 
-template< template<typename...> class...Containers >
-struct combine {
-    template< typename...Types >
-    struct with_types {
-        template< template <typename...> class Final >
-        struct into {
-            using type = typename append<Final<>, typename rewrap<Containers, Types...>::type...>::type;
-        };
-    };
-};
+template <typename T>
+struct is_callable;
 
-template<typename T>
-struct always_false : std::false_type {};
+template <typename Fun, typename... Args>
+struct is_callable<Fun(Args...)> : decltype(is_callable_tester::test<Fun, Args...>(0)) {};
 
 } // namespace Catch
 
+namespace mpl_{
+    struct na;
+}
+
 // end catch_meta.hpp
 namespace Catch {
 
@@ -854,18 +967,47 @@ struct AutoReg : NonCopyable {
             };                            \
         }                                 \
         void TestName::test()
-    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION( TestName, ... )  \
-        template<typename TestType>                                             \
-        static void TestName()
-    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... )    \
+    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( TestName, TestFunc, Name, Tags, Signature, ... )  \
+        INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature))
+    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... )    \
         namespace{                                                                                  \
-            template<typename TestType>                                                             \
-            struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) {     \
-                void test();                                                                        \
-            };                                                                                      \
+            namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) {                                      \
+            INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
         }                                                                                           \
-        template<typename TestType>                                                                 \
-        void TestName::test()
+        }                                                                                           \
+        INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))
+
+    #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \
+            INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ )
+    #else
+        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \
+            INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ ) )
+    #endif
+
+    #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \
+            INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ )
+    #else
+        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \
+            INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) )
+    #endif
+
+    #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \
+            INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ )
+    #else
+        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \
+            INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) )
+    #endif
+
+    #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \
+            INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ )
+    #else
+        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \
+            INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) )
+    #endif
 #endif
 
     ///////////////////////////////////////////////////////////////////////////////
@@ -905,54 +1047,61 @@ struct AutoReg : NonCopyable {
         CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
 
     ///////////////////////////////////////////////////////////////////////////////
-    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_2(TestName, TestFunc, Name, Tags, ... )\
+    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_2(TestName, TestFunc, Name, Tags, Signature, ... )\
         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
-        template<typename TestType> \
-        static void TestFunc();\
+        CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
+        INTERNAL_CATCH_DECLARE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
         namespace {\
+        namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\
+            INTERNAL_CATCH_TYPE_GEN\
+            INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
+            INTERNAL_CATCH_NTTP_REG_GEN(TestFunc,INTERNAL_CATCH_REMOVE_PARENS(Signature))\
             template<typename...Types> \
             struct TestName{\
-                template<typename...Ts> \
-                TestName(Ts...names){\
-                    CATCH_INTERNAL_CHECK_UNIQUE_TYPES(CATCH_REC_LIST(INTERNAL_CATCH_REMOVE_PARENS, __VA_ARGS__)) \
+                TestName(){\
+                    int index = 0;                                    \
+                    constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\
                     using expander = int[];\
-                    (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFunc<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ names, Tags } ), 0)... };/* NOLINT */ \
+                    (void)expander{(reg_test(Types{}, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++, 0)... };/* NOLINT */ \
                 }\
             };\
-            INTERNAL_CATCH_TEMPLATE_REGISTRY_INITIATE(TestName, Name, __VA_ARGS__) \
+            static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
+            TestName<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>();\
+            return 0;\
+        }();\
+        }\
         }\
         CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
-        template<typename TestType> \
-        static void TestFunc()
-
-#if defined(CATCH_CPP17_OR_GREATER)
-#define CATCH_INTERNAL_CHECK_UNIQUE_TYPES(...) static_assert(Catch::is_unique<__VA_ARGS__>,"Duplicate type detected in declaration of template test case");
-#else
-#define CATCH_INTERNAL_CHECK_UNIQUE_TYPES(...) static_assert(Catch::is_unique<__VA_ARGS__>::value,"Duplicate type detected in declaration of template test case");
-#endif
+        CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS \
+        INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc,INTERNAL_CATCH_REMOVE_PARENS(Signature))
 
 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
-        INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, __VA_ARGS__ )
+        INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ )
 #else
     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
-        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, __VA_ARGS__ ) )
+        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ ) )
 #endif
 
-    #define INTERNAL_CATCH_TEMPLATE_REGISTRY_INITIATE(TestName, Name, ...)\
-        static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
-            TestName<CATCH_REC_LIST(INTERNAL_CATCH_REMOVE_PARENS, __VA_ARGS__)>(CATCH_REC_LIST_UD(INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME,Name, __VA_ARGS__));\
-            return 0;\
-        }();
+#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \
+        INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ )
+#else
+    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \
+        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) )
+#endif
 
-    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(TestName, TestFuncName, Name, Tags, TmplTypes, TypesList) \
+    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(TestName, TestFuncName, Name, Tags, Signature, TmplTypes, TypesList) \
         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS                      \
+        CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS                \
         template<typename TestType> static void TestFuncName();       \
-        namespace {                                                   \
+        namespace {\
+        namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) {                                     \
+            INTERNAL_CATCH_TYPE_GEN                                                  \
+            INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))         \
             template<typename... Types>                               \
             struct TestName {                                         \
-                TestName() {                                          \
-                    CATCH_INTERNAL_CHECK_UNIQUE_TYPES(Types...)       \
+                void reg_tests() {                                          \
                     int index = 0;                                    \
                     using expander = int[];                           \
                     constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
@@ -962,65 +1111,120 @@ struct AutoReg : NonCopyable {
                 }                                                     \
             };                                                        \
             static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
-                using TestInit = Catch::combine<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)> \
-                            ::with_types<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(TypesList)>::into<TestName>::type; \
-                TestInit();                                           \
+                using TestInit = decltype(create<TestName, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>(TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>{})); \
+                TestInit t;                                           \
+                t.reg_tests();                                        \
                 return 0;                                             \
             }();                                                      \
         }                                                             \
+        }                                                             \
         CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS                    \
+        CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS              \
         template<typename TestType>                                   \
         static void TestFuncName()
 
 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\
-        INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ),Name,Tags,__VA_ARGS__)
+        INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename T,__VA_ARGS__)
 #else
     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\
-        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, __VA_ARGS__ ) )
+        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename T, __VA_ARGS__ ) )
+#endif
+
+#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\
+        INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__)
+#else
+    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\
+        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) )
 #endif
 
-    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, ... ) \
+    #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2(TestName, TestFunc, Name, Tags, TmplList)\
         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
-        namespace{ \
-            template<typename TestType> \
-            struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
-                void test();\
-            };\
+        template<typename TestType> static void TestFunc();       \
+        namespace {\
+        namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\
+        INTERNAL_CATCH_TYPE_GEN\
+        template<typename... Types>                               \
+        struct TestName {                                         \
+            void reg_tests() {                                          \
+                int index = 0;                                    \
+                using expander = int[];                           \
+                (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFunc<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++, 0)... };/* NOLINT */\
+            }                                                     \
+        };\
+        static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
+                using TestInit = decltype(convert<TestName>(std::declval<TmplList>())); \
+                TestInit t;                                           \
+                t.reg_tests();                                        \
+                return 0;                                             \
+            }();                                                        \
+        }}\
+        CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS                    \
+        template<typename TestType>                                   \
+        static void TestFunc()
+
+    #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(Name, Tags, TmplList) \
+        INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, TmplList )
+
+    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... ) \
+        CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
+        CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
+        namespace {\
+        namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){ \
+            INTERNAL_CATCH_TYPE_GEN\
+            INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
+            INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
+            INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))\
             template<typename...Types> \
             struct TestNameClass{\
-                template<typename...Ts> \
-                TestNameClass(Ts...names){\
-                    CATCH_INTERNAL_CHECK_UNIQUE_TYPES(CATCH_REC_LIST(INTERNAL_CATCH_REMOVE_PARENS, __VA_ARGS__)) \
+                TestNameClass(){\
+                    int index = 0;                                    \
+                    constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\
                     using expander = int[];\
-                    (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ names, Tags } ), 0)... };/* NOLINT */ \
+                    (void)expander{(reg_test(Types{}, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++, 0)... };/* NOLINT */ \
                 }\
             };\
-            INTERNAL_CATCH_TEMPLATE_REGISTRY_INITIATE(TestNameClass, Name, __VA_ARGS__)\
+            static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
+                TestNameClass<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>();\
+                return 0;\
+        }();\
+        }\
         }\
         CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS\
-        template<typename TestType> \
-        void TestName<TestType>::test()
+        CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS\
+        INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))
 
 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
-        INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, __VA_ARGS__ )
+        INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ )
 #else
     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
-        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, __VA_ARGS__ ) )
+        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) )
+#endif
+
+#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \
+        INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ )
+#else
+    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \
+        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) )
 #endif
 
-    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(TestNameClass, TestName, ClassName, Name, Tags, TmplTypes, TypesList)\
+    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(TestNameClass, TestName, ClassName, Name, Tags, Signature, TmplTypes, TypesList)\
         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
+        CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
         template<typename TestType> \
             struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
                 void test();\
             };\
         namespace {\
+        namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestNameClass) {\
+            INTERNAL_CATCH_TYPE_GEN                  \
+            INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
             template<typename...Types>\
             struct TestNameClass{\
-                TestNameClass(){\
-                    CATCH_INTERNAL_CHECK_UNIQUE_TYPES(Types...)\
+                void reg_tests(){\
                     int index = 0;\
                     using expander = int[];\
                     constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
@@ -1030,24 +1234,65 @@ struct AutoReg : NonCopyable {
                 }\
             };\
             static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
-                using TestInit = Catch::combine<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>\
-                            ::with_types<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(TypesList)>::into<TestNameClass>::type;\
-                TestInit();\
+                using TestInit = decltype(create<TestNameClass, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>(TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>{}));\
+                TestInit t;\
+                t.reg_tests();\
                 return 0;\
             }(); \
         }\
+        }\
         CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
+        CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS \
         template<typename TestType> \
         void TestName<TestType>::test()
 
 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\
-        INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, __VA_ARGS__ )
+        INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, typename T, __VA_ARGS__ )
 #else
     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\
-        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, __VA_ARGS__ ) )
+        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, typename T,__VA_ARGS__ ) )
+#endif
+
+#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\
+        INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, Signature, __VA_ARGS__ )
+#else
+    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\
+        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, Signature,__VA_ARGS__ ) )
 #endif
 
+    #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, TmplList) \
+        CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
+        template<typename TestType> \
+        struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
+            void test();\
+        };\
+        namespace {\
+        namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){ \
+            INTERNAL_CATCH_TYPE_GEN\
+            template<typename...Types>\
+            struct TestNameClass{\
+                void reg_tests(){\
+                    int index = 0;\
+                    using expander = int[];\
+                    (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++, 0)... };/* NOLINT */ \
+                }\
+            };\
+            static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
+                using TestInit = decltype(convert<TestNameClass>(std::declval<TmplList>()));\
+                TestInit t;\
+                t.reg_tests();\
+                return 0;\
+            }(); \
+        }}\
+        CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
+        template<typename TestType> \
+        void TestName<TestType>::test()
+
+#define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD(ClassName, Name, Tags, TmplList) \
+        INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, TmplList )
+
 // end catch_test_registry.h
 // start catch_capture.hpp
 
@@ -1166,6 +1411,42 @@ namespace Catch {
 }
 
 // end catch_stream.h
+// start catch_interfaces_enum_values_registry.h
+
+#include <vector>
+
+namespace Catch {
+
+    namespace Detail {
+        struct EnumInfo {
+            StringRef m_name;
+            std::vector<std::pair<int, StringRef>> m_values;
+
+            ~EnumInfo();
+
+            StringRef lookup( int value ) const;
+        };
+    } // namespace Detail
+
+    struct IMutableEnumValuesRegistry {
+        virtual ~IMutableEnumValuesRegistry();
+
+        virtual Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector<int> const& values ) = 0;
+
+        template<typename E>
+        Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::initializer_list<E> values ) {
+            static_assert(sizeof(int) >= sizeof(E), "Cannot serialize enum to int");
+            std::vector<int> intValues;
+            intValues.reserve( values.size() );
+            for( auto enumValue : values )
+                intValues.push_back( static_cast<int>( enumValue ) );
+            return registerEnum( enumName, allEnums, intValues );
+        }
+    };
+
+} // Catch
+
+// end catch_interfaces_enum_values_registry.h
 
 #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
 #include <string_view>
@@ -1236,9 +1517,9 @@ namespace Catch {
 
         template<typename T>
         class IsStreamInsertable {
-            template<typename SS, typename TT>
+            template<typename Stream, typename U>
             static auto test(int)
-                -> decltype(std::declval<SS&>() << std::declval<TT>(), std::true_type());
+                -> decltype(std::declval<Stream&>() << std::declval<U>(), std::true_type());
 
             template<typename, typename>
             static auto test(...)->std::false_type;
@@ -1400,6 +1681,12 @@ namespace Catch {
         }
     };
 
+#if defined(CATCH_CONFIG_CPP17_BYTE)
+    template<>
+    struct StringMaker<std::byte> {
+        static std::string convert(std::byte value);
+    };
+#endif // defined(CATCH_CONFIG_CPP17_BYTE)
     template<>
     struct StringMaker<int> {
         static std::string convert(int value);
@@ -1451,10 +1738,13 @@ namespace Catch {
     template<>
     struct StringMaker<float> {
         static std::string convert(float value);
+        static int precision;
     };
+
     template<>
     struct StringMaker<double> {
         static std::string convert(double value);
+        static int precision;
     };
 
     template <typename T>
@@ -1827,6 +2117,18 @@ struct ratio_string<std::milli> {
 }
 #endif // CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
 
+#define INTERNAL_CATCH_REGISTER_ENUM( enumName, ... ) \
+namespace Catch { \
+    template<> struct StringMaker<enumName> { \
+        static std::string convert( enumName value ) { \
+            static const auto& enumInfo = ::Catch::getMutableRegistryHub().getMutableEnumValuesRegistry().registerEnum( #enumName, #__VA_ARGS__, { __VA_ARGS__ } ); \
+            return static_cast<std::string>(enumInfo.lookup( static_cast<int>( value ) )); \
+        } \
+    }; \
+}
+
+#define CATCH_REGISTER_ENUM( enumName, ... ) INTERNAL_CATCH_REGISTER_ENUM( enumName, __VA_ARGS__ )
+
 #ifdef _MSC_VER
 #pragma warning(pop)
 #endif
@@ -2066,6 +2368,7 @@ namespace Catch {
 // start catch_interfaces_capture.h
 
 #include <string>
+#include <chrono>
 
 namespace Catch {
 
@@ -2076,14 +2379,18 @@ namespace Catch {
     struct MessageInfo;
     struct MessageBuilder;
     struct Counts;
-    struct BenchmarkInfo;
-    struct BenchmarkStats;
     struct AssertionReaction;
     struct SourceLineInfo;
 
     struct ITransientExpression;
     struct IGeneratorTracker;
 
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+    struct BenchmarkInfo;
+    template <typename Duration = std::chrono::duration<double, std::nano>>
+    struct BenchmarkStats;
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
+
     struct IResultCapture {
 
         virtual ~IResultCapture();
@@ -2095,8 +2402,12 @@ namespace Catch {
 
         virtual auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& = 0;
 
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+        virtual void benchmarkPreparing( std::string const& name ) = 0;
         virtual void benchmarkStarting( BenchmarkInfo const& info ) = 0;
-        virtual void benchmarkEnded( BenchmarkStats const& stats ) = 0;
+        virtual void benchmarkEnded( BenchmarkStats<> const& stats ) = 0;
+        virtual void benchmarkFailed( std::string const& error ) = 0;
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
 
         virtual void pushScopedMessage( MessageInfo const& message ) = 0;
         virtual void popScopedMessage( MessageInfo const& message ) = 0;
@@ -2562,52 +2873,6 @@ namespace Catch {
     CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS
 
 // end catch_section.h
-// start catch_benchmark.h
-
-#include <cstdint>
-#include <string>
-
-namespace Catch {
-
-    class BenchmarkLooper {
-
-        std::string m_name;
-        std::size_t m_count = 0;
-        std::size_t m_iterationsToRun = 1;
-        uint64_t m_resolution;
-        Timer m_timer;
-
-        static auto getResolution() -> uint64_t;
-    public:
-        // Keep most of this inline as it's on the code path that is being timed
-        BenchmarkLooper( StringRef name )
-        :   m_name( name ),
-            m_resolution( getResolution() )
-        {
-            reportStart();
-            m_timer.start();
-        }
-
-        explicit operator bool() {
-            if( m_count < m_iterationsToRun )
-                return true;
-            return needsMoreIterations();
-        }
-
-        void increment() {
-            ++m_count;
-        }
-
-        void reportStart();
-        auto needsMoreIterations() -> bool;
-    };
-
-} // end namespace Catch
-
-#define BENCHMARK( name ) \
-    for( Catch::BenchmarkLooper looper( name ); looper; looper.increment() )
-
-// end catch_benchmark.h
 // start catch_interfaces_exception.h
 
 // start catch_interfaces_registry_hub.h
@@ -2624,6 +2889,8 @@ namespace Catch {
     struct IReporterRegistry;
     struct IReporterFactory;
     struct ITagAliasRegistry;
+    struct IMutableEnumValuesRegistry;
+
     class StartupExceptionRegistry;
 
     using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;
@@ -2634,7 +2901,6 @@ namespace Catch {
         virtual IReporterRegistry const& getReporterRegistry() const = 0;
         virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
         virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0;
-
         virtual IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const = 0;
 
         virtual StartupExceptionRegistry const& getStartupExceptionRegistry() const = 0;
@@ -2648,6 +2914,7 @@ namespace Catch {
         virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;
         virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) = 0;
         virtual void registerStartupException() noexcept = 0;
+        virtual IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() = 0;
     };
 
     IRegistryHub const& getRegistryHub();
@@ -2854,6 +3121,7 @@ struct StringMaker<Catch::Detail::Approx> {
 
 #include <string>
 #include <iosfwd>
+#include <vector>
 
 namespace Catch {
 
@@ -2864,7 +3132,13 @@ namespace Catch {
     bool contains( std::string const& s, std::string const& infix );
     void toLowerInPlace( std::string& s );
     std::string toLower( std::string const& s );
+    //! Returns a new string without whitespace at the start/end
     std::string trim( std::string const& str );
+    //! Returns a substring of the original ref without whitespace. Beware lifetimes!
+    StringRef trim(StringRef ref);
+
+    // !!! Be aware, returns refs into original string - make sure original string outlives them
+    std::vector<StringRef> splitStringRef( StringRef str, char delimiter );
     bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );
 
     struct pluralise {
@@ -2917,6 +3191,15 @@ namespace Matchers {
             virtual bool match( ObjectT const& arg ) const = 0;
         };
 
+#if defined(__OBJC__)
+        // Hack to fix Catch GH issue #1661. Could use id for generic Object support.
+        // use of const for Object pointers is very uncommon and under ARC it causes some kind of signature mismatch that breaks compilation
+        template<>
+        struct MatcherMethod<NSString*> {
+            virtual bool match( NSString* arg ) const = 0;
+        };
+#endif
+
 #ifdef __clang__
 #    pragma clang diagnostic pop
 #endif
@@ -3033,10 +3316,34 @@ using Matchers::Impl::MatcherBase;
 } // namespace Catch
 
 // end catch_matchers.h
-// start catch_matchers_floating.h
+// start catch_matchers_exception.hpp
 
-#include <type_traits>
-#include <cmath>
+namespace Catch {
+namespace Matchers {
+namespace Exception {
+
+class ExceptionMessageMatcher : public MatcherBase<std::exception> {
+    std::string m_message;
+public:
+
+    ExceptionMessageMatcher(std::string const& message):
+        m_message(message)
+    {}
+
+    bool match(std::exception const& ex) const override;
+
+    std::string describe() const override;
+};
+
+} // namespace Exception
+
+Exception::ExceptionMessageMatcher Message(std::string const& message);
+
+} // namespace Matchers
+} // namespace Catch
+
+// end catch_matchers_exception.hpp
+// start catch_matchers_floating.h
 
 namespace Catch {
 namespace Matchers {
@@ -3055,22 +3362,43 @@ namespace Matchers {
         };
 
         struct WithinUlpsMatcher : MatcherBase<double> {
-            WithinUlpsMatcher(double target, int ulps, FloatingPointKind baseType);
+            WithinUlpsMatcher(double target, uint64_t ulps, FloatingPointKind baseType);
             bool match(double const& matchee) const override;
             std::string describe() const override;
         private:
             double m_target;
-            int m_ulps;
+            uint64_t m_ulps;
             FloatingPointKind m_type;
         };
 
+        // Given IEEE-754 format for floats and doubles, we can assume
+        // that float -> double promotion is lossless. Given this, we can
+        // assume that if we do the standard relative comparison of
+        // |lhs - rhs| <= epsilon * max(fabs(lhs), fabs(rhs)), then we get
+        // the same result if we do this for floats, as if we do this for
+        // doubles that were promoted from floats.
+        struct WithinRelMatcher : MatcherBase<double> {
+            WithinRelMatcher(double target, double epsilon);
+            bool match(double const& matchee) const override;
+            std::string describe() const override;
+        private:
+            double m_target;
+            double m_epsilon;
+        };
+
     } // namespace Floating
 
     // The following functions create the actual matcher objects.
     // This allows the types to be inferred
-    Floating::WithinUlpsMatcher WithinULP(double target, int maxUlpDiff);
-    Floating::WithinUlpsMatcher WithinULP(float target, int maxUlpDiff);
+    Floating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff);
+    Floating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff);
     Floating::WithinAbsMatcher WithinAbs(double target, double margin);
+    Floating::WithinRelMatcher WithinRel(double target, double eps);
+    // defaults epsilon to 100*numeric_limits<double>::epsilon()
+    Floating::WithinRelMatcher WithinRel(double target);
+    Floating::WithinRelMatcher WithinRel(float target, float eps);
+    // defaults epsilon to 100*numeric_limits<float>::epsilon()
+    Floating::WithinRelMatcher WithinRel(float target);
 
 } // namespace Matchers
 } // namespace Catch
@@ -3113,7 +3441,7 @@ public:
 
     // The following functions create the actual matcher objects.
     // The user has to explicitly specify type to the function, because
-    // infering std::function<bool(T const&)> is hard (but possible) and
+    // inferring std::function<bool(T const&)> is hard (but possible) and
     // requires a lot of TMP.
     template<typename T>
     Generic::PredicateMatcher<T> Predicate(std::function<bool(T const&)> const& predicate, std::string const& description = "") {
@@ -3201,28 +3529,6 @@ namespace Catch {
 namespace Matchers {
 
     namespace Vector {
-        namespace Detail {
-            template <typename InputIterator, typename T>
-            size_t count(InputIterator first, InputIterator last, T const& item) {
-                size_t cnt = 0;
-                for (; first != last; ++first) {
-                    if (*first == item) {
-                        ++cnt;
-                    }
-                }
-                return cnt;
-            }
-            template <typename InputIterator, typename T>
-            bool contains(InputIterator first, InputIterator last, T const& item) {
-                for (; first != last; ++first) {
-                    if (*first == item) {
-                        return true;
-                    }
-                }
-                return false;
-            }
-        }
-
         template<typename T>
         struct ContainsElementMatcher : MatcherBase<std::vector<T>> {
 
@@ -3298,37 +3604,52 @@ namespace Matchers {
         };
 
         template<typename T>
-        struct UnorderedEqualsMatcher : MatcherBase<std::vector<T>> {
-            UnorderedEqualsMatcher(std::vector<T> const& target) : m_target(target) {}
-            bool match(std::vector<T> const& vec) const override {
-                // Note: This is a reimplementation of std::is_permutation,
-                //       because I don't want to include <algorithm> inside the common path
-                if (m_target.size() != vec.size()) {
-                    return false;
-                }
-                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) {
-                    ++lfirst; ++rfirst;
-                }
-                if (lfirst == llast) {
-                    return true;
-                }
+        struct ApproxMatcher : MatcherBase<std::vector<T>> {
 
-                for (auto mid = lfirst; mid != llast; ++mid) {
-                    // Skip already counted items
-                    if (Detail::contains(lfirst, mid, *mid)) {
-                        continue;
-                    }
-                    size_t num_vec = Detail::count(rfirst, rlast, *mid);
-                    if (num_vec == 0 || Detail::count(lfirst, llast, *mid) != num_vec) {
-                        return false;
-                    }
-                }
+            ApproxMatcher(std::vector<T> const& comparator) : m_comparator( comparator ) {}
 
+            bool match(std::vector<T> const &v) const override {
+                if (m_comparator.size() != v.size())
+                    return false;
+                for (std::size_t i = 0; i < v.size(); ++i)
+                    if (m_comparator[i] != approx(v[i]))
+                        return false;
                 return true;
             }
+            std::string describe() const override {
+                return "is approx: " + ::Catch::Detail::stringify( m_comparator );
+            }
+            template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+            ApproxMatcher& epsilon( T const& newEpsilon ) {
+                approx.epsilon(newEpsilon);
+                return *this;
+            }
+            template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+            ApproxMatcher& margin( T const& newMargin ) {
+                approx.margin(newMargin);
+                return *this;
+            }
+            template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+            ApproxMatcher& scale( T const& newScale ) {
+                approx.scale(newScale);
+                return *this;
+            }
+
+            std::vector<T> const& m_comparator;
+            mutable Catch::Detail::Approx approx = Catch::Detail::Approx::custom();
+        };
+
+        template<typename T>
+        struct UnorderedEqualsMatcher : MatcherBase<std::vector<T>> {
+            UnorderedEqualsMatcher(std::vector<T> const& target) : m_target(target) {}
+            bool match(std::vector<T> const& vec) const override {
+                // Note: This is a reimplementation of std::is_permutation,
+                //       because I don't want to include <algorithm> inside the common path
+                if (m_target.size() != vec.size()) {
+                    return false;
+                }
+                return std::is_permutation(m_target.begin(), m_target.end(), vec.begin());
+            }
 
             std::string describe() const override {
                 return "UnorderedEquals: " + ::Catch::Detail::stringify(m_target);
@@ -3357,6 +3678,11 @@ namespace Matchers {
         return Vector::EqualsMatcher<T>( comparator );
     }
 
+    template<typename T>
+    Vector::ApproxMatcher<T> Approx( std::vector<T> const& comparator ) {
+        return Vector::ApproxMatcher<T>( comparator );
+    }
+
     template<typename T>
     Vector::UnorderedEqualsMatcher<T> UnorderedEquals(std::vector<T> const& target) {
         return Vector::UnorderedEqualsMatcher<T>(target);
@@ -3470,7 +3796,7 @@ namespace Catch {
 // end catch_interfaces_generatortracker.h
 // start catch_enforce.h
 
-#include <stdexcept>
+#include <exception>
 
 namespace Catch {
 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
@@ -3483,18 +3809,30 @@ namespace Catch {
     [[noreturn]]
     void throw_exception(std::exception const& e);
 #endif
+
+    [[noreturn]]
+    void throw_logic_error(std::string const& msg);
+    [[noreturn]]
+    void throw_domain_error(std::string const& msg);
+    [[noreturn]]
+    void throw_runtime_error(std::string const& msg);
+
 } // 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)
+#define CATCH_MAKE_MSG(...) \
+    (Catch::ReusableStringStream() << __VA_ARGS__).str()
+
+#define CATCH_INTERNAL_ERROR(...) \
+    Catch::throw_logic_error(CATCH_MAKE_MSG( CATCH_INTERNAL_LINEINFO << ": Internal Catch2 error: " << __VA_ARGS__))
+
+#define CATCH_ERROR(...) \
+    Catch::throw_domain_error(CATCH_MAKE_MSG( __VA_ARGS__ ))
+
+#define CATCH_RUNTIME_ERROR(...) \
+    Catch::throw_runtime_error(CATCH_MAKE_MSG( __VA_ARGS__ ))
+
+#define CATCH_ENFORCE( condition, ... ) \
+    do{ if( !(condition) ) CATCH_ERROR( __VA_ARGS__ ); } while(false)
 
 // end catch_enforce.h
 #include <memory>
@@ -3556,6 +3894,9 @@ namespace Generators {
 
     template<typename T>
     class FixedValuesGenerator final : public IGenerator<T> {
+        static_assert(!std::is_same<T, bool>::value,
+            "FixedValuesGenerator does not support bools because of std::vector<bool>"
+            "specialization, use SingleValue Generator instead.");
         std::vector<T> m_values;
         size_t m_idx = 0;
     public:
@@ -3775,6 +4116,9 @@ namespace Generators {
 
     template <typename T>
     class RepeatGenerator : public IGenerator<T> {
+        static_assert(!std::is_same<T, bool>::value,
+            "RepeatGenerator currently does not support bools"
+            "because of std::vector<bool> specialization");
         GeneratorWrapper<T> m_generator;
         mutable std::vector<T> m_returned;
         size_t m_target_repeats;
@@ -3889,12 +4233,14 @@ namespace Generators {
             m_chunk_size(size), m_generator(std::move(generator))
         {
             m_chunk.reserve(m_chunk_size);
-            m_chunk.push_back(m_generator.get());
-            for (size_t i = 1; i < m_chunk_size; ++i) {
-                if (!m_generator.next()) {
-                    Catch::throw_exception(GeneratorException("Not enough values to initialize the first chunk"));
-                }
+            if (m_chunk_size != 0) {
                 m_chunk.push_back(m_generator.get());
+                for (size_t i = 1; i < m_chunk_size; ++i) {
+                    if (!m_generator.next()) {
+                        Catch::throw_exception(GeneratorException("Not enough values to initialize the first chunk"));
+                    }
+                    m_chunk.push_back(m_generator.get());
+                }
             }
         }
         std::vector<T> const& get() const override {
@@ -3974,11 +4320,79 @@ namespace Catch {
     }
 
     void cleanUpContext();
+
+    class SimplePcg32;
+    SimplePcg32& rng();
 }
 
 // end catch_context.h
 // start catch_interfaces_config.h
 
+// start catch_option.hpp
+
+namespace Catch {
+
+    // An optional type
+    template<typename T>
+    class Option {
+    public:
+        Option() : nullableValue( nullptr ) {}
+        Option( T const& _value )
+        : nullableValue( new( storage ) T( _value ) )
+        {}
+        Option( Option const& _other )
+        : nullableValue( _other ? new( storage ) T( *_other ) : nullptr )
+        {}
+
+        ~Option() {
+            reset();
+        }
+
+        Option& operator= ( Option const& _other ) {
+            if( &_other != this ) {
+                reset();
+                if( _other )
+                    nullableValue = new( storage ) T( *_other );
+            }
+            return *this;
+        }
+        Option& operator = ( T const& _value ) {
+            reset();
+            nullableValue = new( storage ) T( _value );
+            return *this;
+        }
+
+        void reset() {
+            if( nullableValue )
+                nullableValue->~T();
+            nullableValue = nullptr;
+        }
+
+        T& operator*() { return *nullableValue; }
+        T const& operator*() const { return *nullableValue; }
+        T* operator->() { return nullableValue; }
+        const T* operator->() const { return nullableValue; }
+
+        T valueOr( T const& defaultValue ) const {
+            return nullableValue ? *nullableValue : defaultValue;
+        }
+
+        bool some() const { return nullableValue != nullptr; }
+        bool none() const { return nullableValue == nullptr; }
+
+        bool operator !() const { return nullableValue == nullptr; }
+        explicit operator bool() const {
+            return some();
+        }
+
+    private:
+        T *nullableValue;
+        alignas(alignof(T)) char storage[sizeof(T)];
+    };
+
+} // end namespace Catch
+
+// end catch_option.hpp
 #include <iosfwd>
 #include <string>
 #include <vector>
@@ -4041,16 +4455,70 @@ namespace Catch {
         virtual std::vector<std::string> const& getTestsOrTags() const = 0;
         virtual RunTests::InWhatOrder runOrder() const = 0;
         virtual unsigned int rngSeed() const = 0;
-        virtual int benchmarkResolutionMultiple() const = 0;
         virtual UseColour::YesOrNo useColour() const = 0;
         virtual std::vector<std::string> const& getSectionsToRun() const = 0;
         virtual Verbosity verbosity() const = 0;
+
+        virtual bool benchmarkNoAnalysis() const = 0;
+        virtual int benchmarkSamples() const = 0;
+        virtual double benchmarkConfidenceInterval() const = 0;
+        virtual unsigned int benchmarkResamples() const = 0;
     };
 
     using IConfigPtr = std::shared_ptr<IConfig const>;
 }
 
 // end catch_interfaces_config.h
+// start catch_random_number_generator.h
+
+#include <cstdint>
+
+namespace Catch {
+
+    // This is a simple implementation of C++11 Uniform Random Number
+    // Generator. It does not provide all operators, because Catch2
+    // does not use it, but it should behave as expected inside stdlib's
+    // distributions.
+    // The implementation is based on the PCG family (http://pcg-random.org)
+    class SimplePcg32 {
+        using state_type = std::uint64_t;
+    public:
+        using result_type = std::uint32_t;
+        static constexpr result_type min() {
+            return 0;
+        }
+        static constexpr result_type max() {
+            return static_cast<result_type>(-1);
+        }
+
+        // Provide some default initial state for the default constructor
+        SimplePcg32():SimplePcg32(0xed743cc4U) {}
+
+        explicit SimplePcg32(result_type seed_);
+
+        void seed(result_type seed_);
+        void discard(uint64_t skip);
+
+        result_type operator()();
+
+    private:
+        friend bool operator==(SimplePcg32 const& lhs, SimplePcg32 const& rhs);
+        friend bool operator!=(SimplePcg32 const& lhs, SimplePcg32 const& rhs);
+
+        // In theory we also need operator<< and operator>>
+        // In practice we do not use them, so we will skip them for now
+
+        std::uint64_t m_state;
+        // This part of the state determines which "stream" of the numbers
+        // is chosen -- we take it as a constant for Catch2, so we only
+        // need to deal with seeding the main state.
+        // Picked by reading 8 bytes from `/dev/random` :-)
+        static const std::uint64_t s_inc = (0x13ed0cc53f939476ULL << 1ULL) | 1ULL;
+    };
+
+} // end namespace Catch
+
+// end catch_random_number_generator.h
 #include <random>
 
 namespace Catch {
@@ -4058,14 +4526,13 @@ namespace Generators {
 
 template <typename Float>
 class RandomFloatingGenerator final : public IGenerator<Float> {
-    // FIXME: What is the right seed?
-    std::minstd_rand m_rand;
+    Catch::SimplePcg32& m_rng;
     std::uniform_real_distribution<Float> m_dist;
     Float m_current_number;
 public:
 
     RandomFloatingGenerator(Float a, Float b):
-        m_rand(getCurrentContext().getConfig()->rngSeed()),
+        m_rng(rng()),
         m_dist(a, b) {
         static_cast<void>(next());
     }
@@ -4074,20 +4541,20 @@ public:
         return m_current_number;
     }
     bool next() override {
-        m_current_number = m_dist(m_rand);
+        m_current_number = m_dist(m_rng);
         return true;
     }
 };
 
 template <typename Integer>
 class RandomIntegerGenerator final : public IGenerator<Integer> {
-    std::minstd_rand m_rand;
+    Catch::SimplePcg32& m_rng;
     std::uniform_int_distribution<Integer> m_dist;
     Integer m_current_number;
 public:
 
     RandomIntegerGenerator(Integer a, Integer b):
-        m_rand(getCurrentContext().getConfig()->rngSeed()),
+        m_rng(rng()),
         m_dist(a, b) {
         static_cast<void>(next());
     }
@@ -4096,7 +4563,7 @@ public:
         return m_current_number;
     }
     bool next() override {
-        m_current_number = m_dist(m_rand);
+        m_current_number = m_dist(m_rng);
         return true;
     }
 };
@@ -4166,6 +4633,45 @@ GeneratorWrapper<T> range(T const& start, T const& end) {
     return GeneratorWrapper<T>(pf::make_unique<RangeGenerator<T>>(start, end));
 }
 
+template <typename T>
+class IteratorGenerator final : public IGenerator<T> {
+    static_assert(!std::is_same<T, bool>::value,
+        "IteratorGenerator currently does not support bools"
+        "because of std::vector<bool> specialization");
+
+    std::vector<T> m_elems;
+    size_t m_current = 0;
+public:
+    template <typename InputIterator, typename InputSentinel>
+    IteratorGenerator(InputIterator first, InputSentinel last):m_elems(first, last) {
+        if (m_elems.empty()) {
+            Catch::throw_exception(GeneratorException("IteratorGenerator received no valid values"));
+        }
+    }
+
+    T const& get() const override {
+        return m_elems[m_current];
+    }
+
+    bool next() override {
+        ++m_current;
+        return m_current != m_elems.size();
+    }
+};
+
+template <typename InputIterator,
+          typename InputSentinel,
+          typename ResultType = typename std::iterator_traits<InputIterator>::value_type>
+GeneratorWrapper<ResultType> from_range(InputIterator from, InputSentinel to) {
+    return GeneratorWrapper<ResultType>(pf::make_unique<IteratorGenerator<ResultType>>(from, to));
+}
+
+template <typename Container,
+          typename ResultType = typename Container::value_type>
+GeneratorWrapper<ResultType> from_range(Container const& cnt) {
+    return GeneratorWrapper<ResultType>(pf::make_unique<IteratorGenerator<ResultType>>(cnt.begin(), cnt.end()));
+}
+
 } // namespace Generators
 } // namespace Catch
 
@@ -4369,7 +4875,7 @@ namespace Catch {
                     arcSafeRelease( m_substr );
                 }
 
-                bool match( NSString* const& str ) const override {
+                bool match( NSString* str ) const override {
                     return false;
                 }
 
@@ -4379,7 +4885,7 @@ namespace Catch {
             struct Equals : StringHolder {
                 Equals( NSString* substr ) : StringHolder( substr ){}
 
-                bool match( NSString* const& str ) const override {
+                bool match( NSString* str ) const override {
                     return  (str != nil || m_substr == nil ) &&
                             [str isEqualToString:m_substr];
                 }
@@ -4392,7 +4898,7 @@ namespace Catch {
             struct Contains : StringHolder {
                 Contains( NSString* substr ) : StringHolder( substr ){}
 
-                bool match( NSString* const& str ) const override {
+                bool match( NSString* str ) const override {
                     return  (str != nil || m_substr == nil ) &&
                             [str rangeOfString:m_substr].location != NSNotFound;
                 }
@@ -4405,7 +4911,7 @@ namespace Catch {
             struct StartsWith : StringHolder {
                 StartsWith( NSString* substr ) : StringHolder( substr ){}
 
-                bool match( NSString* const& str ) const override {
+                bool match( NSString* str ) const override {
                     return  (str != nil || m_substr == nil ) &&
                             [str rangeOfString:m_substr].location == 0;
                 }
@@ -4417,7 +4923,7 @@ namespace Catch {
             struct EndsWith : StringHolder {
                 EndsWith( NSString* substr ) : StringHolder( substr ){}
 
-                bool match( NSString* const& str ) const override {
+                bool match( NSString* str ) const override {
                     return  (str != nil || m_substr == nil ) &&
                             [str rangeOfString:m_substr].location == [str length] - [m_substr length];
                 }
@@ -4468,7 +4974,8 @@ return @ desc; \
 // end catch_objc.hpp
 #endif
 
-#ifdef CATCH_CONFIG_EXTERNAL_INTERFACES
+// Benchmarking needs the externally-facing parts of reporters to work
+#if defined(CATCH_CONFIG_EXTERNAL_INTERFACES) || defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
 // start catch_external_interfaces.h
 
 // start catch_reporter_bases.hpp
@@ -4510,7 +5017,7 @@ namespace Catch
         virtual bool matches( std::string const& str ) const;
 
     private:
-        std::string adjustCase( std::string const& str ) const;
+        std::string normaliseString( std::string const& str ) const;
         CaseSensitive::Choice m_caseSensitivity;
         WildcardPosition m_wildcard = NoWildcard;
         std::string m_pattern;
@@ -4524,36 +5031,40 @@ namespace Catch
 
 namespace Catch {
 
+    struct IConfig;
+
     class TestSpec {
-        struct Pattern {
+        class Pattern {
+        public:
+            explicit Pattern( std::string const& name );
             virtual ~Pattern();
             virtual bool matches( TestCaseInfo const& testCase ) const = 0;
+            std::string const& name() const;
+        private:
+            std::string const m_name;
         };
         using PatternPtr = std::shared_ptr<Pattern>;
 
         class NamePattern : public Pattern {
         public:
-            NamePattern( std::string const& name );
-            virtual ~NamePattern();
-            virtual bool matches( TestCaseInfo const& testCase ) const override;
+            explicit NamePattern( std::string const& name, std::string const& filterString );
+            bool matches( TestCaseInfo const& testCase ) const override;
         private:
             WildcardPattern m_wildcardPattern;
         };
 
         class TagPattern : public Pattern {
         public:
-            TagPattern( std::string const& tag );
-            virtual ~TagPattern();
-            virtual bool matches( TestCaseInfo const& testCase ) const override;
+            explicit TagPattern( std::string const& tag, std::string const& filterString );
+            bool matches( TestCaseInfo const& testCase ) const override;
         private:
             std::string m_tag;
         };
 
         class ExcludedPattern : public Pattern {
         public:
-            ExcludedPattern( PatternPtr const& underlyingPattern );
-            virtual ~ExcludedPattern();
-            virtual bool matches( TestCaseInfo const& testCase ) const override;
+            explicit ExcludedPattern( PatternPtr const& underlyingPattern );
+            bool matches( TestCaseInfo const& testCase ) const override;
         private:
             PatternPtr m_underlyingPattern;
         };
@@ -4562,11 +5073,19 @@ namespace Catch {
             std::vector<PatternPtr> m_patterns;
 
             bool matches( TestCaseInfo const& testCase ) const;
+            std::string name() const;
         };
 
     public:
+        struct FilterMatch {
+            std::string name;
+            std::vector<TestCase const*> tests;
+        };
+        using Matches = std::vector<FilterMatch>;
+
         bool hasFilters() const;
         bool matches( TestCaseInfo const& testCase ) const;
+        Matches matchesByFilter( std::vector<TestCase> const& testCases, IConfig const& config ) const;
 
     private:
         std::vector<Filter> m_filters;
@@ -4605,9 +5124,13 @@ namespace Catch {
     class TestSpecParser {
         enum Mode{ None, Name, QuotedName, Tag, EscapedName };
         Mode m_mode = None;
+        Mode lastMode = None;
         bool m_exclusion = false;
-        std::size_t m_start = std::string::npos, m_pos = 0;
+        std::size_t m_pos = 0;
+        std::size_t m_realPatternPos = 0;
         std::string m_arg;
+        std::string m_substring;
+        std::string m_patternName;
         std::vector<std::size_t> m_escapeChars;
         TestSpec::Filter m_currentFilter;
         TestSpec m_testSpec;
@@ -4621,26 +5144,34 @@ namespace Catch {
 
     private:
         void visitChar( char c );
-        void startNewMode( Mode mode, std::size_t start );
+        void startNewMode( Mode mode );
+        bool processNoneChar( char c );
+        void processNameChar( char c );
+        bool processOtherChar( char c );
+        void endMode();
         void escape();
-        std::string subString() const;
+        bool isControlChar( char c ) const;
+        void saveLastMode();
+        void revertBackToLastMode();
 
         template<typename T>
         void addPattern() {
-            std::string token = subString();
+            std::string token = m_patternName;
             for( std::size_t i = 0; i < m_escapeChars.size(); ++i )
-                token = token.substr( 0, m_escapeChars[i]-m_start-i ) + token.substr( m_escapeChars[i]-m_start-i+1 );
+                token = token.substr( 0, m_escapeChars[i] - i ) + token.substr( m_escapeChars[i] -i +1 );
             m_escapeChars.clear();
             if( startsWith( token, "exclude:" ) ) {
                 m_exclusion = true;
                 token = token.substr( 8 );
             }
             if( !token.empty() ) {
-                TestSpec::PatternPtr pattern = std::make_shared<T>( token );
+                TestSpec::PatternPtr pattern = std::make_shared<T>( token, m_substring );
                 if( m_exclusion )
                     pattern = std::make_shared<TestSpec::ExcludedPattern>( pattern );
                 m_currentFilter.m_patterns.push_back( pattern );
             }
+            m_substring.clear();
+            m_patternName.clear();
             m_exclusion = false;
             m_mode = None;
         }
@@ -4686,7 +5217,11 @@ namespace Catch {
 
         int abortAfter = -1;
         unsigned int rngSeed = 0;
-        int benchmarkResolutionMultiple = 100;
+
+        bool benchmarkNoAnalysis = false;
+        unsigned int benchmarkSamples = 100;
+        double benchmarkConfidenceInterval = 0.95;
+        unsigned int benchmarkResamples = 100000;
 
         Verbosity verbosity = Verbosity::Normal;
         WarnAbout::What warnings = WarnAbout::Nothing;
@@ -4728,7 +5263,7 @@ namespace Catch {
         std::vector<std::string> const& getTestsOrTags() const override;
         std::vector<std::string> const& getSectionsToRun() const override;
 
-        virtual TestSpec const& testSpec() const override;
+        TestSpec const& testSpec() const override;
         bool hasTestFilters() const override;
 
         bool showHelp() const;
@@ -4743,12 +5278,15 @@ namespace Catch {
         ShowDurations::OrNot showDurations() const override;
         RunTests::InWhatOrder runOrder() const override;
         unsigned int rngSeed() const override;
-        int benchmarkResolutionMultiple() const override;
         UseColour::YesOrNo useColour() const override;
         bool shouldDebugBreak() const override;
         int abortAfter() const override;
         bool showInvisibles() const override;
         Verbosity verbosity() const override;
+        bool benchmarkNoAnalysis() const override;
+        int benchmarkSamples() const override;
+        double benchmarkConfidenceInterval() const override;
+        unsigned int benchmarkResamples() const override;
 
     private:
 
@@ -4809,76 +5347,59 @@ namespace Catch {
 } // end namespace Catch
 
 // end catch_assertionresult.h
-// start catch_option.hpp
-
-namespace Catch {
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+// start catch_estimate.hpp
 
-    // An optional type
-    template<typename T>
-    class Option {
-    public:
-        Option() : nullableValue( nullptr ) {}
-        Option( T const& _value )
-        : nullableValue( new( storage ) T( _value ) )
-        {}
-        Option( Option const& _other )
-        : nullableValue( _other ? new( storage ) T( *_other ) : nullptr )
-        {}
+ // Statistics estimates
 
-        ~Option() {
-            reset();
-        }
 
-        Option& operator= ( Option const& _other ) {
-            if( &_other != this ) {
-                reset();
-                if( _other )
-                    nullableValue = new( storage ) T( *_other );
+namespace Catch {
+    namespace Benchmark {
+        template <typename Duration>
+        struct Estimate {
+            Duration point;
+            Duration lower_bound;
+            Duration upper_bound;
+            double confidence_interval;
+
+            template <typename Duration2>
+            operator Estimate<Duration2>() const {
+                return { point, lower_bound, upper_bound, confidence_interval };
             }
-            return *this;
-        }
-        Option& operator = ( T const& _value ) {
-            reset();
-            nullableValue = new( storage ) T( _value );
-            return *this;
-        }
-
-        void reset() {
-            if( nullableValue )
-                nullableValue->~T();
-            nullableValue = nullptr;
-        }
-
-        T& operator*() { return *nullableValue; }
-        T const& operator*() const { return *nullableValue; }
-        T* operator->() { return nullableValue; }
-        const T* operator->() const { return nullableValue; }
-
-        T valueOr( T const& defaultValue ) const {
-            return nullableValue ? *nullableValue : defaultValue;
-        }
+        };
+    } // namespace Benchmark
+} // namespace Catch
 
-        bool some() const { return nullableValue != nullptr; }
-        bool none() const { return nullableValue == nullptr; }
+// end catch_estimate.hpp
+// start catch_outlier_classification.hpp
 
-        bool operator !() const { return nullableValue == nullptr; }
-        explicit operator bool() const {
-            return some();
-        }
+// Outlier information
 
-    private:
-        T *nullableValue;
-        alignas(alignof(T)) char storage[sizeof(T)];
-    };
+namespace Catch {
+    namespace Benchmark {
+        struct OutlierClassification {
+            int samples_seen = 0;
+            int low_severe = 0;     // more than 3 times IQR below Q1
+            int low_mild = 0;       // 1.5 to 3 times IQR below Q1
+            int high_mild = 0;      // 1.5 to 3 times IQR above Q3
+            int high_severe = 0;    // more than 3 times IQR above Q3
+
+            int total() const {
+                return low_severe + low_mild + high_mild + high_severe;
+            }
+        };
+    } // namespace Benchmark
+} // namespace Catch
 
-} // end namespace Catch
+// end catch_outlier_classification.hpp
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
 
-// end catch_option.hpp
 #include <string>
 #include <iosfwd>
 #include <map>
 #include <set>
 #include <memory>
+#include <algorithm>
 
 namespace Catch {
 
@@ -5014,14 +5535,43 @@ namespace Catch {
         bool aborting;
     };
 
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
     struct BenchmarkInfo {
         std::string name;
+        double estimatedDuration;
+        int iterations;
+        int samples;
+        unsigned int resamples;
+        double clockResolution;
+        double clockCost;
     };
+
+    template <class Duration>
     struct BenchmarkStats {
         BenchmarkInfo info;
-        std::size_t iterations;
-        uint64_t elapsedTimeInNanoseconds;
+
+        std::vector<Duration> samples;
+        Benchmark::Estimate<Duration> mean;
+        Benchmark::Estimate<Duration> standardDeviation;
+        Benchmark::OutlierClassification outliers;
+        double outlierVariance;
+
+        template <typename Duration2>
+        operator BenchmarkStats<Duration2>() const {
+            std::vector<Duration2> samples2;
+            samples2.reserve(samples.size());
+            std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](Duration d) { return Duration2(d); });
+            return {
+                info,
+                std::move(samples2),
+                mean,
+                standardDeviation,
+                outliers,
+                outlierVariance,
+            };
+        }
     };
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
 
     struct IStreamingReporter {
         virtual ~IStreamingReporter() = default;
@@ -5040,17 +5590,18 @@ namespace Catch {
         virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0;
         virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0;
 
-        // *** experimental ***
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+        virtual void benchmarkPreparing( std::string const& ) {}
         virtual void benchmarkStarting( BenchmarkInfo const& ) {}
+        virtual void benchmarkEnded( BenchmarkStats<> const& ) {}
+        virtual void benchmarkFailed( std::string const& ) {}
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
 
         virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0;
 
         // The return value indicates if the messages buffer should be cleared:
         virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0;
 
-        // *** experimental ***
-        virtual void benchmarkEnded( BenchmarkStats const& ) {}
-
         virtual void sectionEnded( SectionStats const& sectionStats ) = 0;
         virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;
         virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;
@@ -5419,11 +5970,11 @@ namespace Catch {
 
         class ReporterFactory : public IReporterFactory {
 
-            virtual IStreamingReporterPtr create( ReporterConfig const& config ) const override {
+            IStreamingReporterPtr create( ReporterConfig const& config ) const override {
                 return std::unique_ptr<T>( new T( config ) );
             }
 
-            virtual std::string getDescription() const override {
+            std::string getDescription() const override {
                 return T::getDescription();
             }
         };
@@ -5440,10 +5991,10 @@ namespace Catch {
 
         class ListenerFactory : public IReporterFactory {
 
-            virtual IStreamingReporterPtr create( ReporterConfig const& config ) const override {
+            IStreamingReporterPtr create( ReporterConfig const& config ) const override {
                 return std::unique_ptr<T>( new T( config ) );
             }
-            virtual std::string getDescription() const override {
+            std::string getDescription() const override {
                 return std::string();
             }
         };
@@ -5535,8 +6086,12 @@ namespace Catch {
         void sectionStarting(SectionInfo const& _sectionInfo) override;
         void sectionEnded(SectionStats const& _sectionStats) override;
 
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+        void benchmarkPreparing(std::string const& name) override;
         void benchmarkStarting(BenchmarkInfo const& info) override;
-        void benchmarkEnded(BenchmarkStats const& stats) override;
+        void benchmarkEnded(BenchmarkStats<> const& stats) override;
+        void benchmarkFailed(std::string const& error) override;
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
 
         void testCaseEnded(TestCaseStats const& _testCaseStats) override;
         void testGroupEnded(TestGroupStats const& _testGroupStats) override;
@@ -5758,6 +6313,13 @@ namespace Catch {
 
         void testRunEnded(TestRunStats const& testRunStats) override;
 
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+        void benchmarkPreparing(std::string const& name) override;
+        void benchmarkStarting(BenchmarkInfo const&) override;
+        void benchmarkEnded(BenchmarkStats<> const&) override;
+        void benchmarkFailed(std::string const&) override;
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
+
     private:
         Timer m_testCaseTimer;
         XmlWriter m_xml;
@@ -5771,39 +6333,985 @@ namespace Catch {
 // end catch_external_interfaces.h
 #endif
 
-#endif // ! CATCH_CONFIG_IMPL_ONLY
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+// start catch_benchmark.hpp
 
-#ifdef CATCH_IMPL
-// start catch_impl.hpp
+ // Benchmark
 
-#ifdef __clang__
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wweak-vtables"
-#endif
+// start catch_chronometer.hpp
 
-// Keep these here for external reporters
-// start catch_test_case_tracker.h
+// User-facing chronometer
 
-#include <string>
-#include <vector>
-#include <memory>
 
-namespace Catch {
-namespace TestCaseTracking {
+// start catch_clock.hpp
 
-    struct NameAndLocation {
-        std::string name;
-        SourceLineInfo location;
+// Clocks
 
-        NameAndLocation( std::string const& _name, SourceLineInfo const& _location );
-    };
 
-    struct ITracker;
+#include <chrono>
+#include <ratio>
 
-    using ITrackerPtr = std::shared_ptr<ITracker>;
+namespace Catch {
+    namespace Benchmark {
+        template <typename Clock>
+        using ClockDuration = typename Clock::duration;
+        template <typename Clock>
+        using FloatDuration = std::chrono::duration<double, typename Clock::period>;
 
-    struct ITracker {
-        virtual ~ITracker();
+        template <typename Clock>
+        using TimePoint = typename Clock::time_point;
+
+        using default_clock = std::chrono::steady_clock;
+
+        template <typename Clock>
+        struct now {
+            TimePoint<Clock> operator()() const {
+                return Clock::now();
+            }
+        };
+
+        using fp_seconds = std::chrono::duration<double, std::ratio<1>>;
+    } // namespace Benchmark
+} // namespace Catch
+
+// end catch_clock.hpp
+// start catch_optimizer.hpp
+
+ // Hinting the optimizer
+
+
+#if defined(_MSC_VER)
+#   include <atomic> // atomic_thread_fence
+#endif
+
+namespace Catch {
+    namespace Benchmark {
+#if defined(__GNUC__) || defined(__clang__)
+        template <typename T>
+        inline void keep_memory(T* p) {
+            asm volatile("" : : "g"(p) : "memory");
+        }
+        inline void keep_memory() {
+            asm volatile("" : : : "memory");
+        }
+
+        namespace Detail {
+            inline void optimizer_barrier() { keep_memory(); }
+        } // namespace Detail
+#elif defined(_MSC_VER)
+
+#pragma optimize("", off)
+        template <typename T>
+        inline void keep_memory(T* p) {
+            // thanks @milleniumbug
+            *reinterpret_cast<char volatile*>(p) = *reinterpret_cast<char const volatile*>(p);
+        }
+        // TODO equivalent keep_memory()
+#pragma optimize("", on)
+
+        namespace Detail {
+            inline void optimizer_barrier() {
+                std::atomic_thread_fence(std::memory_order_seq_cst);
+            }
+        } // namespace Detail
+
+#endif
+
+        template <typename T>
+        inline void deoptimize_value(T&& x) {
+            keep_memory(&x);
+        }
+
+        template <typename Fn, typename... Args>
+        inline auto invoke_deoptimized(Fn&& fn, Args&&... args) -> typename std::enable_if<!std::is_same<void, decltype(fn(args...))>::value>::type {
+            deoptimize_value(std::forward<Fn>(fn) (std::forward<Args...>(args...)));
+        }
+
+        template <typename Fn, typename... Args>
+        inline auto invoke_deoptimized(Fn&& fn, Args&&... args) -> typename std::enable_if<std::is_same<void, decltype(fn(args...))>::value>::type {
+            std::forward<Fn>(fn) (std::forward<Args...>(args...));
+        }
+    } // namespace Benchmark
+} // namespace Catch
+
+// end catch_optimizer.hpp
+// start catch_complete_invoke.hpp
+
+// Invoke with a special case for void
+
+
+#include <type_traits>
+#include <utility>
+
+namespace Catch {
+    namespace Benchmark {
+        namespace Detail {
+            template <typename T>
+            struct CompleteType { using type = T; };
+            template <>
+            struct CompleteType<void> { struct type {}; };
+
+            template <typename T>
+            using CompleteType_t = typename CompleteType<T>::type;
+
+            template <typename Result>
+            struct CompleteInvoker {
+                template <typename Fun, typename... Args>
+                static Result invoke(Fun&& fun, Args&&... args) {
+                    return std::forward<Fun>(fun)(std::forward<Args>(args)...);
+                }
+            };
+            template <>
+            struct CompleteInvoker<void> {
+                template <typename Fun, typename... Args>
+                static CompleteType_t<void> invoke(Fun&& fun, Args&&... args) {
+                    std::forward<Fun>(fun)(std::forward<Args>(args)...);
+                    return {};
+                }
+            };
+            template <typename Sig>
+            using ResultOf_t = typename std::result_of<Sig>::type;
+
+            // invoke and not return void :(
+            template <typename Fun, typename... Args>
+            CompleteType_t<ResultOf_t<Fun(Args...)>> complete_invoke(Fun&& fun, Args&&... args) {
+                return CompleteInvoker<ResultOf_t<Fun(Args...)>>::invoke(std::forward<Fun>(fun), std::forward<Args>(args)...);
+            }
+
+            const std::string benchmarkErrorMsg = "a benchmark failed to run successfully";
+        } // namespace Detail
+
+        template <typename Fun>
+        Detail::CompleteType_t<Detail::ResultOf_t<Fun()>> user_code(Fun&& fun) {
+            CATCH_TRY{
+                return Detail::complete_invoke(std::forward<Fun>(fun));
+            } CATCH_CATCH_ALL{
+                getResultCapture().benchmarkFailed(translateActiveException());
+                CATCH_RUNTIME_ERROR(Detail::benchmarkErrorMsg);
+            }
+        }
+    } // namespace Benchmark
+} // namespace Catch
+
+// end catch_complete_invoke.hpp
+namespace Catch {
+    namespace Benchmark {
+        namespace Detail {
+            struct ChronometerConcept {
+                virtual void start() = 0;
+                virtual void finish() = 0;
+                virtual ~ChronometerConcept() = default;
+            };
+            template <typename Clock>
+            struct ChronometerModel final : public ChronometerConcept {
+                void start() override { started = Clock::now(); }
+                void finish() override { finished = Clock::now(); }
+
+                ClockDuration<Clock> elapsed() const { return finished - started; }
+
+                TimePoint<Clock> started;
+                TimePoint<Clock> finished;
+            };
+        } // namespace Detail
+
+        struct Chronometer {
+        public:
+            template <typename Fun>
+            void measure(Fun&& fun) { measure(std::forward<Fun>(fun), is_callable<Fun(int)>()); }
+
+            int runs() const { return k; }
+
+            Chronometer(Detail::ChronometerConcept& meter, int k)
+                : impl(&meter)
+                , k(k) {}
+
+        private:
+            template <typename Fun>
+            void measure(Fun&& fun, std::false_type) {
+                measure([&fun](int) { return fun(); }, std::true_type());
+            }
+
+            template <typename Fun>
+            void measure(Fun&& fun, std::true_type) {
+                Detail::optimizer_barrier();
+                impl->start();
+                for (int i = 0; i < k; ++i) invoke_deoptimized(fun, i);
+                impl->finish();
+                Detail::optimizer_barrier();
+            }
+
+            Detail::ChronometerConcept* impl;
+            int k;
+        };
+    } // namespace Benchmark
+} // namespace Catch
+
+// end catch_chronometer.hpp
+// start catch_environment.hpp
+
+// Environment information
+
+
+namespace Catch {
+    namespace Benchmark {
+        template <typename Duration>
+        struct EnvironmentEstimate {
+            Duration mean;
+            OutlierClassification outliers;
+
+            template <typename Duration2>
+            operator EnvironmentEstimate<Duration2>() const {
+                return { mean, outliers };
+            }
+        };
+        template <typename Clock>
+        struct Environment {
+            using clock_type = Clock;
+            EnvironmentEstimate<FloatDuration<Clock>> clock_resolution;
+            EnvironmentEstimate<FloatDuration<Clock>> clock_cost;
+        };
+    } // namespace Benchmark
+} // namespace Catch
+
+// end catch_environment.hpp
+// start catch_execution_plan.hpp
+
+ // Execution plan
+
+
+// start catch_benchmark_function.hpp
+
+ // Dumb std::function implementation for consistent call overhead
+
+
+#include <cassert>
+#include <type_traits>
+#include <utility>
+#include <memory>
+
+namespace Catch {
+    namespace Benchmark {
+        namespace Detail {
+            template <typename T>
+            using Decay = typename std::decay<T>::type;
+            template <typename T, typename U>
+            struct is_related
+                : std::is_same<Decay<T>, Decay<U>> {};
+
+            /// We need to reinvent std::function because every piece of code that might add overhead
+            /// in a measurement context needs to have consistent performance characteristics so that we
+            /// can account for it in the measurement.
+            /// Implementations of std::function with optimizations that aren't always applicable, like
+            /// small buffer optimizations, are not uncommon.
+            /// This is effectively an implementation of std::function without any such optimizations;
+            /// it may be slow, but it is consistently slow.
+            struct BenchmarkFunction {
+            private:
+                struct callable {
+                    virtual void call(Chronometer meter) const = 0;
+                    virtual callable* clone() const = 0;
+                    virtual ~callable() = default;
+                };
+                template <typename Fun>
+                struct model : public callable {
+                    model(Fun&& fun) : fun(std::move(fun)) {}
+                    model(Fun const& fun) : fun(fun) {}
+
+                    model<Fun>* clone() const override { return new model<Fun>(*this); }
+
+                    void call(Chronometer meter) const override {
+                        call(meter, is_callable<Fun(Chronometer)>());
+                    }
+                    void call(Chronometer meter, std::true_type) const {
+                        fun(meter);
+                    }
+                    void call(Chronometer meter, std::false_type) const {
+                        meter.measure(fun);
+                    }
+
+                    Fun fun;
+                };
+
+                struct do_nothing { void operator()() const {} };
+
+                template <typename T>
+                BenchmarkFunction(model<T>* c) : f(c) {}
+
+            public:
+                BenchmarkFunction()
+                    : f(new model<do_nothing>{ {} }) {}
+
+                template <typename Fun,
+                    typename std::enable_if<!is_related<Fun, BenchmarkFunction>::value, int>::type = 0>
+                    BenchmarkFunction(Fun&& fun)
+                    : f(new model<typename std::decay<Fun>::type>(std::forward<Fun>(fun))) {}
+
+                BenchmarkFunction(BenchmarkFunction&& that)
+                    : f(std::move(that.f)) {}
+
+                BenchmarkFunction(BenchmarkFunction const& that)
+                    : f(that.f->clone()) {}
+
+                BenchmarkFunction& operator=(BenchmarkFunction&& that) {
+                    f = std::move(that.f);
+                    return *this;
+                }
+
+                BenchmarkFunction& operator=(BenchmarkFunction const& that) {
+                    f.reset(that.f->clone());
+                    return *this;
+                }
+
+                void operator()(Chronometer meter) const { f->call(meter); }
+
+            private:
+                std::unique_ptr<callable> f;
+            };
+        } // namespace Detail
+    } // namespace Benchmark
+} // namespace Catch
+
+// end catch_benchmark_function.hpp
+// start catch_repeat.hpp
+
+// repeat algorithm
+
+
+#include <type_traits>
+#include <utility>
+
+namespace Catch {
+    namespace Benchmark {
+        namespace Detail {
+            template <typename Fun>
+            struct repeater {
+                void operator()(int k) const {
+                    for (int i = 0; i < k; ++i) {
+                        fun();
+                    }
+                }
+                Fun fun;
+            };
+            template <typename Fun>
+            repeater<typename std::decay<Fun>::type> repeat(Fun&& fun) {
+                return { std::forward<Fun>(fun) };
+            }
+        } // namespace Detail
+    } // namespace Benchmark
+} // namespace Catch
+
+// end catch_repeat.hpp
+// start catch_run_for_at_least.hpp
+
+// Run a function for a minimum amount of time
+
+
+// start catch_measure.hpp
+
+// Measure
+
+
+// start catch_timing.hpp
+
+// Timing
+
+
+#include <tuple>
+#include <type_traits>
+
+namespace Catch {
+    namespace Benchmark {
+        template <typename Duration, typename Result>
+        struct Timing {
+            Duration elapsed;
+            Result result;
+            int iterations;
+        };
+        template <typename Clock, typename Sig>
+        using TimingOf = Timing<ClockDuration<Clock>, Detail::CompleteType_t<Detail::ResultOf_t<Sig>>>;
+    } // namespace Benchmark
+} // namespace Catch
+
+// end catch_timing.hpp
+#include <utility>
+
+namespace Catch {
+    namespace Benchmark {
+        namespace Detail {
+            template <typename Clock, typename Fun, typename... Args>
+            TimingOf<Clock, Fun(Args...)> measure(Fun&& fun, Args&&... args) {
+                auto start = Clock::now();
+                auto&& r = Detail::complete_invoke(fun, std::forward<Args>(args)...);
+                auto end = Clock::now();
+                auto delta = end - start;
+                return { delta, std::forward<decltype(r)>(r), 1 };
+            }
+        } // namespace Detail
+    } // namespace Benchmark
+} // namespace Catch
+
+// end catch_measure.hpp
+#include <utility>
+#include <type_traits>
+
+namespace Catch {
+    namespace Benchmark {
+        namespace Detail {
+            template <typename Clock, typename Fun>
+            TimingOf<Clock, Fun(int)> measure_one(Fun&& fun, int iters, std::false_type) {
+                return Detail::measure<Clock>(fun, iters);
+            }
+            template <typename Clock, typename Fun>
+            TimingOf<Clock, Fun(Chronometer)> measure_one(Fun&& fun, int iters, std::true_type) {
+                Detail::ChronometerModel<Clock> meter;
+                auto&& result = Detail::complete_invoke(fun, Chronometer(meter, iters));
+
+                return { meter.elapsed(), std::move(result), iters };
+            }
+
+            template <typename Clock, typename Fun>
+            using run_for_at_least_argument_t = typename std::conditional<is_callable<Fun(Chronometer)>::value, Chronometer, int>::type;
+
+            struct optimized_away_error : std::exception {
+                const char* what() const noexcept override {
+                    return "could not measure benchmark, maybe it was optimized away";
+                }
+            };
+
+            template <typename Clock, typename Fun>
+            TimingOf<Clock, Fun(run_for_at_least_argument_t<Clock, Fun>)> run_for_at_least(ClockDuration<Clock> how_long, int seed, Fun&& fun) {
+                auto iters = seed;
+                while (iters < (1 << 30)) {
+                    auto&& Timing = measure_one<Clock>(fun, iters, is_callable<Fun(Chronometer)>());
+
+                    if (Timing.elapsed >= how_long) {
+                        return { Timing.elapsed, std::move(Timing.result), iters };
+                    }
+                    iters *= 2;
+                }
+                throw optimized_away_error{};
+            }
+        } // namespace Detail
+    } // namespace Benchmark
+} // namespace Catch
+
+// end catch_run_for_at_least.hpp
+#include <algorithm>
+
+namespace Catch {
+    namespace Benchmark {
+        template <typename Duration>
+        struct ExecutionPlan {
+            int iterations_per_sample;
+            Duration estimated_duration;
+            Detail::BenchmarkFunction benchmark;
+            Duration warmup_time;
+            int warmup_iterations;
+
+            template <typename Duration2>
+            operator ExecutionPlan<Duration2>() const {
+                return { iterations_per_sample, estimated_duration, benchmark, warmup_time, warmup_iterations };
+            }
+
+            template <typename Clock>
+            std::vector<FloatDuration<Clock>> run(const IConfig &cfg, Environment<FloatDuration<Clock>> env) const {
+                // warmup a bit
+                Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(warmup_time), warmup_iterations, Detail::repeat(now<Clock>{}));
+
+                std::vector<FloatDuration<Clock>> times;
+                times.reserve(cfg.benchmarkSamples());
+                std::generate_n(std::back_inserter(times), cfg.benchmarkSamples(), [this, env] {
+                    Detail::ChronometerModel<Clock> model;
+                    this->benchmark(Chronometer(model, iterations_per_sample));
+                    auto sample_time = model.elapsed() - env.clock_cost.mean;
+                    if (sample_time < FloatDuration<Clock>::zero()) sample_time = FloatDuration<Clock>::zero();
+                    return sample_time / iterations_per_sample;
+                });
+                return times;
+            }
+        };
+    } // namespace Benchmark
+} // namespace Catch
+
+// end catch_execution_plan.hpp
+// start catch_estimate_clock.hpp
+
+ // Environment measurement
+
+
+// start catch_stats.hpp
+
+// Statistical analysis tools
+
+
+#include <algorithm>
+#include <functional>
+#include <vector>
+#include <numeric>
+#include <tuple>
+#include <cmath>
+#include <utility>
+#include <cstddef>
+
+namespace Catch {
+    namespace Benchmark {
+        namespace Detail {
+            using sample = std::vector<double>;
+
+            double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last);
+
+            template <typename Iterator>
+            OutlierClassification classify_outliers(Iterator first, Iterator last) {
+                std::vector<double> copy(first, last);
+
+                auto q1 = weighted_average_quantile(1, 4, copy.begin(), copy.end());
+                auto q3 = weighted_average_quantile(3, 4, copy.begin(), copy.end());
+                auto iqr = q3 - q1;
+                auto los = q1 - (iqr * 3.);
+                auto lom = q1 - (iqr * 1.5);
+                auto him = q3 + (iqr * 1.5);
+                auto his = q3 + (iqr * 3.);
+
+                OutlierClassification o;
+                for (; first != last; ++first) {
+                    auto&& t = *first;
+                    if (t < los) ++o.low_severe;
+                    else if (t < lom) ++o.low_mild;
+                    else if (t > his) ++o.high_severe;
+                    else if (t > him) ++o.high_mild;
+                    ++o.samples_seen;
+                }
+                return o;
+            }
+
+            template <typename Iterator>
+            double mean(Iterator first, Iterator last) {
+                auto count = last - first;
+                double sum = std::accumulate(first, last, 0.);
+                return sum / count;
+            }
+
+            template <typename URng, typename Iterator, typename Estimator>
+            sample resample(URng& rng, int resamples, Iterator first, Iterator last, Estimator& estimator) {
+                auto n = last - first;
+                std::uniform_int_distribution<decltype(n)> dist(0, n - 1);
+
+                sample out;
+                out.reserve(resamples);
+                std::generate_n(std::back_inserter(out), resamples, [n, first, &estimator, &dist, &rng] {
+                    std::vector<double> resampled;
+                    resampled.reserve(n);
+                    std::generate_n(std::back_inserter(resampled), n, [first, &dist, &rng] { return first[dist(rng)]; });
+                    return estimator(resampled.begin(), resampled.end());
+                });
+                std::sort(out.begin(), out.end());
+                return out;
+            }
+
+            template <typename Estimator, typename Iterator>
+            sample jackknife(Estimator&& estimator, Iterator first, Iterator last) {
+                auto n = last - first;
+                auto second = std::next(first);
+                sample results;
+                results.reserve(n);
+
+                for (auto it = first; it != last; ++it) {
+                    std::iter_swap(it, first);
+                    results.push_back(estimator(second, last));
+                }
+
+                return results;
+            }
+
+            inline double normal_cdf(double x) {
+                return std::erfc(-x / std::sqrt(2.0)) / 2.0;
+            }
+
+            double erfc_inv(double x);
+
+            double normal_quantile(double p);
+
+            template <typename Iterator, typename Estimator>
+            Estimate<double> bootstrap(double confidence_level, Iterator first, Iterator last, sample const& resample, Estimator&& estimator) {
+                auto n_samples = last - first;
+
+                double point = estimator(first, last);
+                // Degenerate case with a single sample
+                if (n_samples == 1) return { point, point, point, confidence_level };
+
+                sample jack = jackknife(estimator, first, last);
+                double jack_mean = mean(jack.begin(), jack.end());
+                double sum_squares, sum_cubes;
+                std::tie(sum_squares, sum_cubes) = std::accumulate(jack.begin(), jack.end(), std::make_pair(0., 0.), [jack_mean](std::pair<double, double> sqcb, double x) -> std::pair<double, double> {
+                    auto d = jack_mean - x;
+                    auto d2 = d * d;
+                    auto d3 = d2 * d;
+                    return { sqcb.first + d2, sqcb.second + d3 };
+                });
+
+                double accel = sum_cubes / (6 * std::pow(sum_squares, 1.5));
+                int n = static_cast<int>(resample.size());
+                double prob_n = std::count_if(resample.begin(), resample.end(), [point](double x) { return x < point; }) / (double)n;
+                // degenerate case with uniform samples
+                if (prob_n == 0) return { point, point, point, confidence_level };
+
+                double bias = normal_quantile(prob_n);
+                double z1 = normal_quantile((1. - confidence_level) / 2.);
+
+                auto cumn = [n](double x) -> int {
+                    return std::lround(normal_cdf(x) * n); };
+                auto a = [bias, accel](double b) { return bias + b / (1. - accel * b); };
+                double b1 = bias + z1;
+                double b2 = bias - z1;
+                double a1 = a(b1);
+                double a2 = a(b2);
+                auto lo = std::max(cumn(a1), 0);
+                auto hi = std::min(cumn(a2), n - 1);
+
+                return { point, resample[lo], resample[hi], confidence_level };
+            }
+
+            double outlier_variance(Estimate<double> mean, Estimate<double> stddev, int n);
+
+            struct bootstrap_analysis {
+                Estimate<double> mean;
+                Estimate<double> standard_deviation;
+                double outlier_variance;
+            };
+
+            bootstrap_analysis analyse_samples(double confidence_level, int n_resamples, std::vector<double>::iterator first, std::vector<double>::iterator last);
+        } // namespace Detail
+    } // namespace Benchmark
+} // namespace Catch
+
+// end catch_stats.hpp
+#include <algorithm>
+#include <iterator>
+#include <tuple>
+#include <vector>
+#include <cmath>
+
+namespace Catch {
+    namespace Benchmark {
+        namespace Detail {
+            template <typename Clock>
+            std::vector<double> resolution(int k) {
+                std::vector<TimePoint<Clock>> times;
+                times.reserve(k + 1);
+                std::generate_n(std::back_inserter(times), k + 1, now<Clock>{});
+
+                std::vector<double> deltas;
+                deltas.reserve(k);
+                std::transform(std::next(times.begin()), times.end(), times.begin(),
+                    std::back_inserter(deltas),
+                    [](TimePoint<Clock> a, TimePoint<Clock> b) { return static_cast<double>((a - b).count()); });
+
+                return deltas;
+            }
+
+            const auto warmup_iterations = 10000;
+            const auto warmup_time = std::chrono::milliseconds(100);
+            const auto minimum_ticks = 1000;
+            const auto warmup_seed = 10000;
+            const auto clock_resolution_estimation_time = std::chrono::milliseconds(500);
+            const auto clock_cost_estimation_time_limit = std::chrono::seconds(1);
+            const auto clock_cost_estimation_tick_limit = 100000;
+            const auto clock_cost_estimation_time = std::chrono::milliseconds(10);
+            const auto clock_cost_estimation_iterations = 10000;
+
+            template <typename Clock>
+            int warmup() {
+                return run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(warmup_time), warmup_seed, &resolution<Clock>)
+                    .iterations;
+            }
+            template <typename Clock>
+            EnvironmentEstimate<FloatDuration<Clock>> estimate_clock_resolution(int iterations) {
+                auto r = run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(clock_resolution_estimation_time), iterations, &resolution<Clock>)
+                    .result;
+                return {
+                    FloatDuration<Clock>(mean(r.begin(), r.end())),
+                    classify_outliers(r.begin(), r.end()),
+                };
+            }
+            template <typename Clock>
+            EnvironmentEstimate<FloatDuration<Clock>> estimate_clock_cost(FloatDuration<Clock> resolution) {
+                auto time_limit = std::min(resolution * clock_cost_estimation_tick_limit, FloatDuration<Clock>(clock_cost_estimation_time_limit));
+                auto time_clock = [](int k) {
+                    return Detail::measure<Clock>([k] {
+                        for (int i = 0; i < k; ++i) {
+                            volatile auto ignored = Clock::now();
+                            (void)ignored;
+                        }
+                    }).elapsed;
+                };
+                time_clock(1);
+                int iters = clock_cost_estimation_iterations;
+                auto&& r = run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(clock_cost_estimation_time), iters, time_clock);
+                std::vector<double> times;
+                int nsamples = static_cast<int>(std::ceil(time_limit / r.elapsed));
+                times.reserve(nsamples);
+                std::generate_n(std::back_inserter(times), nsamples, [time_clock, &r] {
+                    return static_cast<double>((time_clock(r.iterations) / r.iterations).count());
+                });
+                return {
+                    FloatDuration<Clock>(mean(times.begin(), times.end())),
+                    classify_outliers(times.begin(), times.end()),
+                };
+            }
+
+            template <typename Clock>
+            Environment<FloatDuration<Clock>> measure_environment() {
+                static Environment<FloatDuration<Clock>>* env = nullptr;
+                if (env) {
+                    return *env;
+                }
+
+                auto iters = Detail::warmup<Clock>();
+                auto resolution = Detail::estimate_clock_resolution<Clock>(iters);
+                auto cost = Detail::estimate_clock_cost<Clock>(resolution.mean);
+
+                env = new Environment<FloatDuration<Clock>>{ resolution, cost };
+                return *env;
+            }
+        } // namespace Detail
+    } // namespace Benchmark
+} // namespace Catch
+
+// end catch_estimate_clock.hpp
+// start catch_analyse.hpp
+
+ // Run and analyse one benchmark
+
+
+// start catch_sample_analysis.hpp
+
+// Benchmark results
+
+
+#include <algorithm>
+#include <vector>
+#include <string>
+#include <iterator>
+
+namespace Catch {
+    namespace Benchmark {
+        template <typename Duration>
+        struct SampleAnalysis {
+            std::vector<Duration> samples;
+            Estimate<Duration> mean;
+            Estimate<Duration> standard_deviation;
+            OutlierClassification outliers;
+            double outlier_variance;
+
+            template <typename Duration2>
+            operator SampleAnalysis<Duration2>() const {
+                std::vector<Duration2> samples2;
+                samples2.reserve(samples.size());
+                std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](Duration d) { return Duration2(d); });
+                return {
+                    std::move(samples2),
+                    mean,
+                    standard_deviation,
+                    outliers,
+                    outlier_variance,
+                };
+            }
+        };
+    } // namespace Benchmark
+} // namespace Catch
+
+// end catch_sample_analysis.hpp
+#include <algorithm>
+#include <iterator>
+#include <vector>
+
+namespace Catch {
+    namespace Benchmark {
+        namespace Detail {
+            template <typename Duration, typename Iterator>
+            SampleAnalysis<Duration> analyse(const IConfig &cfg, Environment<Duration>, Iterator first, Iterator last) {
+                if (!cfg.benchmarkNoAnalysis()) {
+                    std::vector<double> samples;
+                    samples.reserve(last - first);
+                    std::transform(first, last, std::back_inserter(samples), [](Duration d) { return d.count(); });
+
+                    auto analysis = Catch::Benchmark::Detail::analyse_samples(cfg.benchmarkConfidenceInterval(), cfg.benchmarkResamples(), samples.begin(), samples.end());
+                    auto outliers = Catch::Benchmark::Detail::classify_outliers(samples.begin(), samples.end());
+
+                    auto wrap_estimate = [](Estimate<double> e) {
+                        return Estimate<Duration> {
+                            Duration(e.point),
+                                Duration(e.lower_bound),
+                                Duration(e.upper_bound),
+                                e.confidence_interval,
+                        };
+                    };
+                    std::vector<Duration> samples2;
+                    samples2.reserve(samples.size());
+                    std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](double d) { return Duration(d); });
+                    return {
+                        std::move(samples2),
+                        wrap_estimate(analysis.mean),
+                        wrap_estimate(analysis.standard_deviation),
+                        outliers,
+                        analysis.outlier_variance,
+                    };
+                } else {
+                    std::vector<Duration> samples;
+                    samples.reserve(last - first);
+
+                    Duration mean = Duration(0);
+                    int i = 0;
+                    for (auto it = first; it < last; ++it, ++i) {
+                        samples.push_back(Duration(*it));
+                        mean += Duration(*it);
+                    }
+                    mean /= i;
+
+                    return {
+                        std::move(samples),
+                        Estimate<Duration>{mean, mean, mean, 0.0},
+                        Estimate<Duration>{Duration(0), Duration(0), Duration(0), 0.0},
+                        OutlierClassification{},
+                        0.0
+                    };
+                }
+            }
+        } // namespace Detail
+    } // namespace Benchmark
+} // namespace Catch
+
+// end catch_analyse.hpp
+#include <algorithm>
+#include <functional>
+#include <string>
+#include <vector>
+#include <cmath>
+
+namespace Catch {
+    namespace Benchmark {
+        struct Benchmark {
+            Benchmark(std::string &&name)
+                : name(std::move(name)) {}
+
+            template <class FUN>
+            Benchmark(std::string &&name, FUN &&func)
+                : fun(std::move(func)), name(std::move(name)) {}
+
+            template <typename Clock>
+            ExecutionPlan<FloatDuration<Clock>> prepare(const IConfig &cfg, Environment<FloatDuration<Clock>> env) const {
+                auto min_time = env.clock_resolution.mean * Detail::minimum_ticks;
+                auto run_time = std::max(min_time, std::chrono::duration_cast<decltype(min_time)>(Detail::warmup_time));
+                auto&& test = Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(run_time), 1, fun);
+                int new_iters = static_cast<int>(std::ceil(min_time * test.iterations / test.elapsed));
+                return { new_iters, test.elapsed / test.iterations * new_iters * cfg.benchmarkSamples(), fun, std::chrono::duration_cast<FloatDuration<Clock>>(Detail::warmup_time), Detail::warmup_iterations };
+            }
+
+            template <typename Clock = default_clock>
+            void run() {
+                IConfigPtr cfg = getCurrentContext().getConfig();
+
+                auto env = Detail::measure_environment<Clock>();
+
+                getResultCapture().benchmarkPreparing(name);
+                CATCH_TRY{
+                    auto plan = user_code([&] {
+                        return prepare<Clock>(*cfg, env);
+                    });
+
+                    BenchmarkInfo info {
+                        name,
+                        plan.estimated_duration.count(),
+                        plan.iterations_per_sample,
+                        cfg->benchmarkSamples(),
+                        cfg->benchmarkResamples(),
+                        env.clock_resolution.mean.count(),
+                        env.clock_cost.mean.count()
+                    };
+
+                    getResultCapture().benchmarkStarting(info);
+
+                    auto samples = user_code([&] {
+                        return plan.template run<Clock>(*cfg, env);
+                    });
+
+                    auto analysis = Detail::analyse(*cfg, env, samples.begin(), samples.end());
+                    BenchmarkStats<std::chrono::duration<double, std::nano>> stats{ info, analysis.samples, analysis.mean, analysis.standard_deviation, analysis.outliers, analysis.outlier_variance };
+                    getResultCapture().benchmarkEnded(stats);
+
+                } CATCH_CATCH_ALL{
+                    if (translateActiveException() != Detail::benchmarkErrorMsg) // benchmark errors have been reported, otherwise rethrow.
+                        std::rethrow_exception(std::current_exception());
+                }
+            }
+
+            // sets lambda to be used in fun *and* executes benchmark!
+            template <typename Fun,
+                typename std::enable_if<!Detail::is_related<Fun, Benchmark>::value, int>::type = 0>
+                Benchmark & operator=(Fun func) {
+                fun = Detail::BenchmarkFunction(func);
+                run();
+                return *this;
+            }
+
+            explicit operator bool() {
+                return true;
+            }
+
+        private:
+            Detail::BenchmarkFunction fun;
+            std::string name;
+        };
+    }
+} // namespace Catch
+
+#define INTERNAL_CATCH_GET_1_ARG(arg1, arg2, ...) arg1
+#define INTERNAL_CATCH_GET_2_ARG(arg1, arg2, ...) arg2
+
+#define INTERNAL_CATCH_BENCHMARK(BenchmarkName, name, benchmarkIndex)\
+    if( Catch::Benchmark::Benchmark BenchmarkName{name} ) \
+        BenchmarkName = [&](int benchmarkIndex)
+
+#define INTERNAL_CATCH_BENCHMARK_ADVANCED(BenchmarkName, name)\
+    if( Catch::Benchmark::Benchmark BenchmarkName{name} ) \
+        BenchmarkName = [&]
+
+// end catch_benchmark.hpp
+#endif
+
+#endif // ! CATCH_CONFIG_IMPL_ONLY
+
+#ifdef CATCH_IMPL
+// start catch_impl.hpp
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wweak-vtables"
+#endif
+
+// Keep these here for external reporters
+// start catch_test_case_tracker.h
+
+#include <string>
+#include <vector>
+#include <memory>
+
+namespace Catch {
+namespace TestCaseTracking {
+
+    struct NameAndLocation {
+        std::string name;
+        SourceLineInfo location;
+
+        NameAndLocation( std::string const& _name, SourceLineInfo const& _location );
+    };
+
+    struct ITracker;
+
+    using ITrackerPtr = std::shared_ptr<ITracker>;
+
+    struct ITracker {
+        virtual ~ITracker();
 
         // static queries
         virtual NameAndLocation const& nameAndLocation() const = 0;
@@ -5844,8 +7352,6 @@ namespace TestCaseTracking {
 
     public:
 
-        static TrackerContext& instance();
-
         ITracker& startRun();
         void endRun();
 
@@ -5900,50 +7406,261 @@ namespace TestCaseTracking {
         void fail() override;
         void markAsNeedingAnotherRun() override;
 
-    private:
-        void moveToParent();
-        void moveToThis();
-    };
+    private:
+        void moveToParent();
+        void moveToThis();
+    };
+
+    class SectionTracker : public TrackerBase {
+        std::vector<std::string> m_filters;
+        std::string m_trimmed_name;
+    public:
+        SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
+
+        bool isSectionTracker() const override;
+
+        bool isComplete() const override;
+
+        static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation );
+
+        void tryOpen();
+
+        void addInitialFilters( std::vector<std::string> const& filters );
+        void addNextFilters( std::vector<std::string> const& filters );
+    };
+
+} // namespace TestCaseTracking
+
+using TestCaseTracking::ITracker;
+using TestCaseTracking::TrackerContext;
+using TestCaseTracking::SectionTracker;
+
+} // namespace Catch
+
+// end catch_test_case_tracker.h
+
+// start catch_leak_detector.h
+
+namespace Catch {
+
+    struct LeakDetector {
+        LeakDetector();
+        ~LeakDetector();
+    };
+
+}
+// end catch_leak_detector.h
+// Cpp files will be included in the single-header file here
+// start catch_stats.cpp
+
+// Statistical analysis tools
+
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+
+#include <cassert>
+#include <random>
+
+#if defined(CATCH_CONFIG_USE_ASYNC)
+#include <future>
+#endif
+
+namespace {
+    double erf_inv(double x) {
+        // Code accompanying the article "Approximating the erfinv function" in GPU Computing Gems, Volume 2
+        double w, p;
+
+        w = -log((1.0 - x) * (1.0 + x));
+
+        if (w < 6.250000) {
+            w = w - 3.125000;
+            p = -3.6444120640178196996e-21;
+            p = -1.685059138182016589e-19 + p * w;
+            p = 1.2858480715256400167e-18 + p * w;
+            p = 1.115787767802518096e-17 + p * w;
+            p = -1.333171662854620906e-16 + p * w;
+            p = 2.0972767875968561637e-17 + p * w;
+            p = 6.6376381343583238325e-15 + p * w;
+            p = -4.0545662729752068639e-14 + p * w;
+            p = -8.1519341976054721522e-14 + p * w;
+            p = 2.6335093153082322977e-12 + p * w;
+            p = -1.2975133253453532498e-11 + p * w;
+            p = -5.4154120542946279317e-11 + p * w;
+            p = 1.051212273321532285e-09 + p * w;
+            p = -4.1126339803469836976e-09 + p * w;
+            p = -2.9070369957882005086e-08 + p * w;
+            p = 4.2347877827932403518e-07 + p * w;
+            p = -1.3654692000834678645e-06 + p * w;
+            p = -1.3882523362786468719e-05 + p * w;
+            p = 0.0001867342080340571352 + p * w;
+            p = -0.00074070253416626697512 + p * w;
+            p = -0.0060336708714301490533 + p * w;
+            p = 0.24015818242558961693 + p * w;
+            p = 1.6536545626831027356 + p * w;
+        } else if (w < 16.000000) {
+            w = sqrt(w) - 3.250000;
+            p = 2.2137376921775787049e-09;
+            p = 9.0756561938885390979e-08 + p * w;
+            p = -2.7517406297064545428e-07 + p * w;
+            p = 1.8239629214389227755e-08 + p * w;
+            p = 1.5027403968909827627e-06 + p * w;
+            p = -4.013867526981545969e-06 + p * w;
+            p = 2.9234449089955446044e-06 + p * w;
+            p = 1.2475304481671778723e-05 + p * w;
+            p = -4.7318229009055733981e-05 + p * w;
+            p = 6.8284851459573175448e-05 + p * w;
+            p = 2.4031110387097893999e-05 + p * w;
+            p = -0.0003550375203628474796 + p * w;
+            p = 0.00095328937973738049703 + p * w;
+            p = -0.0016882755560235047313 + p * w;
+            p = 0.0024914420961078508066 + p * w;
+            p = -0.0037512085075692412107 + p * w;
+            p = 0.005370914553590063617 + p * w;
+            p = 1.0052589676941592334 + p * w;
+            p = 3.0838856104922207635 + p * w;
+        } else {
+            w = sqrt(w) - 5.000000;
+            p = -2.7109920616438573243e-11;
+            p = -2.5556418169965252055e-10 + p * w;
+            p = 1.5076572693500548083e-09 + p * w;
+            p = -3.7894654401267369937e-09 + p * w;
+            p = 7.6157012080783393804e-09 + p * w;
+            p = -1.4960026627149240478e-08 + p * w;
+            p = 2.9147953450901080826e-08 + p * w;
+            p = -6.7711997758452339498e-08 + p * w;
+            p = 2.2900482228026654717e-07 + p * w;
+            p = -9.9298272942317002539e-07 + p * w;
+            p = 4.5260625972231537039e-06 + p * w;
+            p = -1.9681778105531670567e-05 + p * w;
+            p = 7.5995277030017761139e-05 + p * w;
+            p = -0.00021503011930044477347 + p * w;
+            p = -0.00013871931833623122026 + p * w;
+            p = 1.0103004648645343977 + p * w;
+            p = 4.8499064014085844221 + p * w;
+        }
+        return p * x;
+    }
+
+    double standard_deviation(std::vector<double>::iterator first, std::vector<double>::iterator last) {
+        auto m = Catch::Benchmark::Detail::mean(first, last);
+        double variance = std::accumulate(first, last, 0., [m](double a, double b) {
+            double diff = b - m;
+            return a + diff * diff;
+            }) / (last - first);
+            return std::sqrt(variance);
+    }
+
+}
+
+namespace Catch {
+    namespace Benchmark {
+        namespace Detail {
+
+            double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last) {
+                auto count = last - first;
+                double idx = (count - 1) * k / static_cast<double>(q);
+                int j = static_cast<int>(idx);
+                double g = idx - j;
+                std::nth_element(first, first + j, last);
+                auto xj = first[j];
+                if (g == 0) return xj;
+
+                auto xj1 = *std::min_element(first + (j + 1), last);
+                return xj + g * (xj1 - xj);
+            }
 
-    class SectionTracker : public TrackerBase {
-        std::vector<std::string> m_filters;
-    public:
-        SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
+            double erfc_inv(double x) {
+                return erf_inv(1.0 - x);
+            }
 
-        bool isSectionTracker() const override;
+            double normal_quantile(double p) {
+                static const double ROOT_TWO = std::sqrt(2.0);
 
-        bool isComplete() const override;
+                double result = 0.0;
+                assert(p >= 0 && p <= 1);
+                if (p < 0 || p > 1) {
+                    return result;
+                }
 
-        static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation );
+                result = -erfc_inv(2.0 * p);
+                // result *= normal distribution standard deviation (1.0) * sqrt(2)
+                result *= /*sd * */ ROOT_TWO;
+                // result += normal disttribution mean (0)
+                return result;
+            }
 
-        void tryOpen();
+            double outlier_variance(Estimate<double> mean, Estimate<double> stddev, int n) {
+                double sb = stddev.point;
+                double mn = mean.point / n;
+                double mg_min = mn / 2.;
+                double sg = std::min(mg_min / 4., sb / std::sqrt(n));
+                double sg2 = sg * sg;
+                double sb2 = sb * sb;
+
+                auto c_max = [n, mn, sb2, sg2](double x) -> double {
+                    double k = mn - x;
+                    double d = k * k;
+                    double nd = n * d;
+                    double k0 = -n * nd;
+                    double k1 = sb2 - n * sg2 + nd;
+                    double det = k1 * k1 - 4 * sg2 * k0;
+                    return (int)(-2. * k0 / (k1 + std::sqrt(det)));
+                };
+
+                auto var_out = [n, sb2, sg2](double c) {
+                    double nc = n - c;
+                    return (nc / n) * (sb2 - nc * sg2);
+                };
+
+                return std::min(var_out(1), var_out(std::min(c_max(0.), c_max(mg_min)))) / sb2;
+            }
 
-        void addInitialFilters( std::vector<std::string> const& filters );
-        void addNextFilters( std::vector<std::string> const& filters );
-    };
+            bootstrap_analysis analyse_samples(double confidence_level, int n_resamples, std::vector<double>::iterator first, std::vector<double>::iterator last) {
+                CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
+                static std::random_device entropy;
+                CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
 
-} // namespace TestCaseTracking
+                auto n = static_cast<int>(last - first); // seriously, one can't use integral types without hell in C++
 
-using TestCaseTracking::ITracker;
-using TestCaseTracking::TrackerContext;
-using TestCaseTracking::SectionTracker;
+                auto mean = &Detail::mean<std::vector<double>::iterator>;
+                auto stddev = &standard_deviation;
 
-} // namespace Catch
+#if defined(CATCH_CONFIG_USE_ASYNC)
+                auto Estimate = [=](double(*f)(std::vector<double>::iterator, std::vector<double>::iterator)) {
+                    auto seed = entropy();
+                    return std::async(std::launch::async, [=] {
+                        std::mt19937 rng(seed);
+                        auto resampled = resample(rng, n_resamples, first, last, f);
+                        return bootstrap(confidence_level, first, last, resampled, f);
+                    });
+                };
 
-// end catch_test_case_tracker.h
+                auto mean_future = Estimate(mean);
+                auto stddev_future = Estimate(stddev);
 
-// start catch_leak_detector.h
+                auto mean_estimate = mean_future.get();
+                auto stddev_estimate = stddev_future.get();
+#else
+                auto Estimate = [=](double(*f)(std::vector<double>::iterator, std::vector<double>::iterator)) {
+                    auto seed = entropy();
+                    std::mt19937 rng(seed);
+                    auto resampled = resample(rng, n_resamples, first, last, f);
+                    return bootstrap(confidence_level, first, last, resampled, f);
+                };
 
-namespace Catch {
+                auto mean_estimate = Estimate(mean);
+                auto stddev_estimate = Estimate(stddev);
+#endif // CATCH_USE_ASYNC
 
-    struct LeakDetector {
-        LeakDetector();
-        ~LeakDetector();
-    };
+                double outlier_variance = Detail::outlier_variance(mean_estimate, stddev_estimate, n);
 
-}
-// end catch_leak_detector.h
-// Cpp files will be included in the single-header file here
+                return { mean_estimate, stddev_estimate, outlier_variance };
+            }
+        } // namespace Detail
+    } // namespace Benchmark
+} // namespace Catch
+
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
+// end catch_stats.cpp
 // start catch_approx.cpp
 
 #include <cmath>
@@ -5988,21 +7705,22 @@ namespace Detail {
     bool Approx::equalityComparisonImpl(const double other) const {
         // First try with fixed margin, then compute margin based on epsilon, scale and Approx's value
         // Thanks to Richard Harris for his help refining the scaled margin value
-        return marginComparison(m_value, other, m_margin) || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(m_value)));
+        return marginComparison(m_value, other, m_margin)
+            || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(std::isinf(m_value)? 0 : m_value)));
     }
 
-    void Approx::setMargin(double margin) {
-        CATCH_ENFORCE(margin >= 0,
-            "Invalid Approx::margin: " << margin << '.'
+    void Approx::setMargin(double newMargin) {
+        CATCH_ENFORCE(newMargin >= 0,
+            "Invalid Approx::margin: " << newMargin << '.'
             << " Approx::Margin has to be non-negative.");
-        m_margin = margin;
+        m_margin = newMargin;
     }
 
-    void Approx::setEpsilon(double epsilon) {
-        CATCH_ENFORCE(epsilon >= 0 && epsilon <= 1.0,
-            "Invalid Approx::epsilon: " << epsilon << '.'
+    void Approx::setEpsilon(double newEpsilon) {
+        CATCH_ENFORCE(newEpsilon >= 0 && newEpsilon <= 1.0,
+            "Invalid Approx::epsilon: " << newEpsilon << '.'
             << " Approx::epsilon has to be in [0, 1]");
-        m_epsilon = epsilon;
+        m_epsilon = newEpsilon;
     }
 
 } // end namespace Detail
@@ -6204,8 +7922,12 @@ namespace Catch {
 
         auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& override;
 
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+        void benchmarkPreparing( std::string const& name ) override;
         void benchmarkStarting( BenchmarkInfo const& info ) override;
-        void benchmarkEnded( BenchmarkStats const& stats ) override;
+        void benchmarkEnded( BenchmarkStats<> const& stats ) override;
+        void benchmarkFailed( std::string const& error ) override;
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
 
         void pushScopedMessage( MessageInfo const& message ) override;
         void popScopedMessage( MessageInfo const& message ) override;
@@ -6269,6 +7991,8 @@ namespace Catch {
         bool m_includeSuccessfulResults;
     };
 
+    void seedRng(IConfig const& config);
+    unsigned int rngSeed();
 } // end namespace Catch
 
 // end catch_run_context.h
@@ -6415,7 +8139,7 @@ namespace Catch {
     }
 
     bool AssertionResult::hasExpression() const {
-        return m_info.capturedExpression[0] != 0;
+        return !m_info.capturedExpression.empty();
     }
 
     bool AssertionResult::hasMessage() const {
@@ -6423,16 +8147,22 @@ namespace Catch {
     }
 
     std::string AssertionResult::getExpression() const {
-        if( isFalseTest( m_info.resultDisposition ) )
-            return "!(" + m_info.capturedExpression + ")";
-        else
-            return m_info.capturedExpression;
+        // Possibly overallocating by 3 characters should be basically free
+        std::string expr; expr.reserve(m_info.capturedExpression.size() + 3);
+        if (isFalseTest(m_info.resultDisposition)) {
+            expr += "!(";
+        }
+        expr += m_info.capturedExpression;
+        if (isFalseTest(m_info.resultDisposition)) {
+            expr += ')';
+        }
+        return expr;
     }
 
     std::string AssertionResult::getExpressionInMacro() const {
         std::string expr;
-        if( m_info.macroName[0] == 0 )
-            expr = m_info.capturedExpression;
+        if( m_info.macroName.empty() )
+            expr = static_cast<std::string>(m_info.capturedExpression);
         else {
             expr.reserve( m_info.macroName.size() + m_info.capturedExpression.size() + 4 );
             expr += m_info.macroName;
@@ -6467,32 +8197,6 @@ namespace Catch {
 
 } // end namespace Catch
 // end catch_assertionresult.cpp
-// start catch_benchmark.cpp
-
-namespace Catch {
-
-    auto BenchmarkLooper::getResolution() -> uint64_t {
-        return getEstimatedClockResolution() * getCurrentContext().getConfig()->benchmarkResolutionMultiple();
-    }
-
-    void BenchmarkLooper::reportStart() {
-        getResultCapture().benchmarkStarting( { m_name } );
-    }
-    auto BenchmarkLooper::needsMoreIterations() -> bool {
-        auto elapsed = m_timer.getElapsedNanoseconds();
-
-        // Exponentially increasing iterations until we're confident in our timer resolution
-        if( elapsed < m_resolution ) {
-            m_iterationsToRun *= 10;
-            return true;
-        }
-
-        getResultCapture().benchmarkEnded( { { m_name }, m_count, elapsed } );
-        return false;
-    }
-
-} // end namespace Catch
-// end catch_benchmark.cpp
 // start catch_capture_matchers.cpp
 
 namespace Catch {
@@ -6638,6 +8342,9 @@ public:
 			m_suffix = false;
 			auto width = m_column.m_width - indent();
 			m_end = m_pos;
+			if (line()[m_pos] == '\n') {
+				++m_end;
+			}
 			while (m_end < line().size() && line()[m_end] != '\n')
 				++m_end;
 
@@ -7984,11 +9691,19 @@ namespace Catch {
             | Opt( setWaitForKeypress, "start|exit|both" )
                 ["--wait-for-keypress"]
                 ( "waits for a keypress before exiting" )
-            | Opt( config.benchmarkResolutionMultiple, "multiplier" )
-                ["--benchmark-resolution-multiple"]
-                ( "multiple of clock resolution to run benchmarks" )
-
-            | Arg( config.testsOrTags, "test name|pattern|tags" )
+            | Opt( config.benchmarkSamples, "samples" )
+                ["--benchmark-samples"]
+                ( "number of samples to collect (default: 100)" )
+            | Opt( config.benchmarkResamples, "resamples" )
+                ["--benchmark-resamples"]
+                ( "number of resamples for the bootstrap (default: 100000)" )
+            | Opt( config.benchmarkConfidenceInterval, "confidence interval" )
+                ["--benchmark-confidence-interval"]
+                ( "confidence interval for the bootstrap (between 0 and 1, default: 0.95)" )
+            | Opt( config.benchmarkNoAnalysis )
+                ["--benchmark-no-analysis"]
+                ( "perform only measurements; do not perform any analysis" )
+			| Arg( config.testsOrTags, "test name|pattern|tags" )
                 ( "which test or tests to use" );
 
         return cli;
@@ -8003,9 +9718,6 @@ namespace Catch {
 
 namespace Catch {
 
-    bool SourceLineInfo::empty() const noexcept {
-        return file[0] == '\0';
-    }
     bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const noexcept {
         return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0);
     }
@@ -8041,14 +9753,23 @@ namespace Catch {
     :   m_data( data ),
         m_stream( openStream() )
     {
-        TestSpecParser parser(ITagAliasRegistry::get());
-        if (data.testsOrTags.empty()) {
-            parser.parse("~[.]"); // All not hidden tests
+        // We need to trim filter specs to avoid trouble with superfluous
+        // whitespace (esp. important for bdd macros, as those are manually
+        // aligned with whitespace).
+
+        for (auto& elem : m_data.testsOrTags) {
+            elem = trim(elem);
         }
-        else {
+        for (auto& elem : m_data.sectionsToRun) {
+            elem = trim(elem);
+        }
+
+        TestSpecParser parser(ITagAliasRegistry::get());
+        if (!m_data.testsOrTags.empty()) {
             m_hasTestFilters = true;
-            for( auto const& testOrTags : data.testsOrTags )
-                parser.parse( testOrTags );
+            for (auto const& testOrTags : m_data.testsOrTags) {
+                parser.parse(testOrTags);
+            }
         }
         m_testSpec = parser.testSpec();
     }
@@ -8083,13 +9804,17 @@ namespace Catch {
     ShowDurations::OrNot Config::showDurations() const { return m_data.showDurations; }
     RunTests::InWhatOrder Config::runOrder() const     { return m_data.runOrder; }
     unsigned int Config::rngSeed() const               { return m_data.rngSeed; }
-    int Config::benchmarkResolutionMultiple() const    { return m_data.benchmarkResolutionMultiple; }
     UseColour::YesOrNo Config::useColour() const       { return m_data.useColour; }
     bool Config::shouldDebugBreak() const              { return m_data.shouldDebugBreak; }
     int Config::abortAfter() const                     { return m_data.abortAfter; }
     bool Config::showInvisibles() const                { return m_data.showInvisibles; }
     Verbosity Config::verbosity() const                { return m_data.verbosity; }
 
+    bool Config::benchmarkNoAnalysis() const           { return m_data.benchmarkNoAnalysis; }
+    int Config::benchmarkSamples() const               { return m_data.benchmarkSamples; }
+    double Config::benchmarkConfidenceInterval() const { return m_data.benchmarkConfidenceInterval; }
+    unsigned int Config::benchmarkResamples() const    { return m_data.benchmarkResamples; }
+
     IStream const* Config::openStream() {
         return Catch::makeStream(m_data.outputFilename);
     }
@@ -8163,7 +9888,7 @@ namespace {
             originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY );
         }
 
-        virtual void use( Colour::Code _colourCode ) override {
+        void use( Colour::Code _colourCode ) override {
             switch( _colourCode ) {
                 case Colour::None:      return setTextAttribute( originalForegroundAttributes );
                 case Colour::White:     return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
@@ -8226,7 +9951,7 @@ namespace {
     // https://github.com/philsquared/Catch/pull/131
     class PosixColourImpl : public IColourImpl {
     public:
-        virtual void use( Colour::Code _colourCode ) override {
+        void use( Colour::Code _colourCode ) override {
             switch( _colourCode ) {
                 case Colour::None:
                 case Colour::White:     return setColour( "[0m" );
@@ -8316,7 +10041,13 @@ namespace Catch {
 
     void Colour::use( Code _colourCode ) {
         static IColourImpl* impl = platformColourInstance();
-        impl->use( _colourCode );
+        // Strictly speaking, this cannot possibly happen.
+        // However, under some conditions it does happen (see #1626),
+        // and this change is small enough that we can let practicality
+        // triumph over purity in this case.
+        if (impl != NULL) {
+            impl->use( _colourCode );
+        }
     }
 
     std::ostream& operator << ( std::ostream& os, Colour const& ) {
@@ -8337,27 +10068,27 @@ namespace Catch {
     class Context : public IMutableContext, NonCopyable {
 
     public: // IContext
-        virtual IResultCapture* getResultCapture() override {
+        IResultCapture* getResultCapture() override {
             return m_resultCapture;
         }
-        virtual IRunner* getRunner() override {
+        IRunner* getRunner() override {
             return m_runner;
         }
 
-        virtual IConfigPtr const& getConfig() const override {
+        IConfigPtr const& getConfig() const override {
             return m_config;
         }
 
-        virtual ~Context() override;
+        ~Context() override;
 
     public: // IMutableContext
-        virtual void setResultCapture( IResultCapture* resultCapture ) override {
+        void setResultCapture( IResultCapture* resultCapture ) override {
             m_resultCapture = resultCapture;
         }
-        virtual void setRunner( IRunner* runner ) override {
+        void setRunner( IRunner* runner ) override {
             m_runner = runner;
         }
-        virtual void setConfig( IConfigPtr const& config ) override {
+        void setConfig( IConfigPtr const& config ) override {
             m_config = config;
         }
 
@@ -8383,6 +10114,12 @@ namespace Catch {
     IContext::~IContext() = default;
     IMutableContext::~IMutableContext() = default;
     Context::~Context() = default;
+
+    SimplePcg32& rng() {
+        static SimplePcg32 s_rng;
+        return s_rng;
+    }
+
 }
 // end catch_context.cpp
 // start catch_debug_console.cpp
@@ -8396,7 +10133,16 @@ namespace Catch {
 }
 
 // end catch_debug_console.h
-#ifdef CATCH_PLATFORM_WINDOWS
+#if defined(CATCH_CONFIG_ANDROID_LOGWRITE)
+#include <android/log.h>
+
+    namespace Catch {
+        void writeToDebugConsole( std::string const& text ) {
+            __android_log_write( ANDROID_LOG_DEBUG, "Catch", text.c_str() );
+        }
+    }
+
+#elif defined(CATCH_PLATFORM_WINDOWS)
 
     namespace Catch {
         void writeToDebugConsole( std::string const& text ) {
@@ -8423,19 +10169,23 @@ namespace Catch {
 #  include <stdbool.h>
 #  include <sys/types.h>
 #  include <unistd.h>
-#  include <sys/sysctl.h>
 #  include <cstddef>
 #  include <ostream>
 
-namespace Catch {
+#ifdef __apple_build_version__
+    // These headers will only compile with AppleClang (XCode)
+    // For other compilers (Clang, GCC, ... ) we need to exclude them
+#  include <sys/sysctl.h>
+#endif
 
+    namespace Catch {
+        #ifdef __apple_build_version__
         // The following function is taken directly from the following technical note:
-        // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html
+        // https://developer.apple.com/library/archive/qa/qa1361/_index.html
 
         // Returns true if the current process is being debugged (either
         // running under the debugger or has a debugger attached post facto).
         bool isDebuggerActive(){
-
             int                 mib[4];
             struct kinfo_proc   info;
             std::size_t         size;
@@ -8465,6 +10215,12 @@ namespace Catch {
 
             return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
         }
+        #else
+        bool isDebuggerActive() {
+            // We need to find another way to determine this for non-appleclang compilers on macOS
+            return false;
+        }
+        #endif
     } // namespace Catch
 
 #elif defined(CATCH_PLATFORM_LINUX)
@@ -8535,6 +10291,8 @@ namespace Catch {
 // end catch_decomposer.cpp
 // start catch_enforce.cpp
 
+#include <stdexcept>
+
 namespace Catch {
 #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS_CUSTOM_HANDLER)
     [[noreturn]]
@@ -8544,8 +10302,116 @@ namespace Catch {
         std::terminate();
     }
 #endif
+
+    [[noreturn]]
+    void throw_logic_error(std::string const& msg) {
+        throw_exception(std::logic_error(msg));
+    }
+
+    [[noreturn]]
+    void throw_domain_error(std::string const& msg) {
+        throw_exception(std::domain_error(msg));
+    }
+
+    [[noreturn]]
+    void throw_runtime_error(std::string const& msg) {
+        throw_exception(std::runtime_error(msg));
+    }
+
 } // namespace Catch;
 // end catch_enforce.cpp
+// start catch_enum_values_registry.cpp
+// start catch_enum_values_registry.h
+
+#include <vector>
+#include <memory>
+
+namespace Catch {
+
+    namespace Detail {
+
+        std::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values );
+
+        class EnumValuesRegistry : public IMutableEnumValuesRegistry {
+
+            std::vector<std::unique_ptr<EnumInfo>> m_enumInfos;
+
+            EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector<int> const& values) override;
+        };
+
+        std::vector<StringRef> parseEnums( StringRef enums );
+
+    } // Detail
+
+} // Catch
+
+// end catch_enum_values_registry.h
+
+#include <map>
+#include <cassert>
+
+namespace Catch {
+
+    IMutableEnumValuesRegistry::~IMutableEnumValuesRegistry() {}
+
+    namespace Detail {
+
+        namespace {
+            // Extracts the actual name part of an enum instance
+            // In other words, it returns the Blue part of Bikeshed::Colour::Blue
+            StringRef extractInstanceName(StringRef enumInstance) {
+                // Find last occurence of ":"
+                size_t name_start = enumInstance.size();
+                while (name_start > 0 && enumInstance[name_start - 1] != ':') {
+                    --name_start;
+                }
+                return enumInstance.substr(name_start, enumInstance.size() - name_start);
+            }
+        }
+
+        std::vector<StringRef> parseEnums( StringRef enums ) {
+            auto enumValues = splitStringRef( enums, ',' );
+            std::vector<StringRef> parsed;
+            parsed.reserve( enumValues.size() );
+            for( auto const& enumValue : enumValues ) {
+                parsed.push_back(trim(extractInstanceName(enumValue)));
+            }
+            return parsed;
+        }
+
+        EnumInfo::~EnumInfo() {}
+
+        StringRef EnumInfo::lookup( int value ) const {
+            for( auto const& valueToName : m_values ) {
+                if( valueToName.first == value )
+                    return valueToName.second;
+            }
+            return "{** unexpected enum value **}"_sr;
+        }
+
+        std::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) {
+            std::unique_ptr<EnumInfo> enumInfo( new EnumInfo );
+            enumInfo->m_name = enumName;
+            enumInfo->m_values.reserve( values.size() );
+
+            const auto valueNames = Catch::Detail::parseEnums( allValueNames );
+            assert( valueNames.size() == values.size() );
+            std::size_t i = 0;
+            for( auto value : values )
+                enumInfo->m_values.push_back({ value, valueNames[i++] });
+
+            return enumInfo;
+        }
+
+        EnumInfo const& EnumValuesRegistry::registerEnum( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) {
+            m_enumInfos.push_back(makeEnumInfo(enumName, allValueNames, values));
+            return *m_enumInfos.back();
+        }
+
+    } // Detail
+} // Catch
+
+// end catch_enum_values_registry.cpp
 // start catch_errno_guard.cpp
 
 #include <cerrno>
@@ -8569,7 +10435,7 @@ namespace Catch {
     public:
         ~ExceptionTranslatorRegistry();
         virtual void registerTranslator( const IExceptionTranslator* translator );
-        virtual std::string translateActiveException() const override;
+        std::string translateActiveException() const override;
         std::string tryTranslators() const;
 
     private:
@@ -8740,7 +10606,7 @@ namespace Catch {
 
     // 32kb for the alternate stack seems to be sufficient. However, this value
     // is experimentally determined, so that's not guaranteed.
-    constexpr static std::size_t sigStackSize = 32768 >= MINSIGSTKSZ ? 32768 : MINSIGSTKSZ;
+    static constexpr std::size_t sigStackSize = 32768 >= MINSIGSTKSZ ? 32768 : MINSIGSTKSZ;
 
     static SignalDefs signalDefs[] = {
         { SIGINT,  "SIGINT - Terminal interrupt signal" },
@@ -8817,22 +10683,6 @@ namespace Catch {
 // 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>
 
@@ -8907,8 +10757,12 @@ namespace Catch {
 
         static std::set<Verbosity> getSupportedVerbosities();
 
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+        void benchmarkPreparing(std::string const& name) override;
         void benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) override;
-        void benchmarkEnded( BenchmarkStats const& benchmarkStats ) override;
+        void benchmarkEnded( BenchmarkStats<> const& benchmarkStats ) override;
+        void benchmarkFailed(std::string const&) override;
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
 
         void testRunStarting( TestRunInfo const& testRunInfo ) override;
         void testGroupStarting( GroupInfo const& groupInfo ) override;
@@ -9174,9 +11028,18 @@ namespace Catch {
     }
 
     std::string TagInfo::all() const {
-        std::string out;
-        for( auto const& spelling : spellings )
-            out += "[" + spelling + "]";
+        size_t size = 0;
+        for (auto const& spelling : spellings) {
+            // Add 2 for the brackes
+            size += spelling.size() + 2;
+        }
+
+        std::string out; out.reserve(size);
+        for (auto const& spelling : spellings) {
+            out += '[';
+            out += spelling;
+            out += ']';
+        }
         return out;
     }
 
@@ -9275,6 +11138,29 @@ using Matchers::Impl::MatcherBase;
 
 } // namespace Catch
 // end catch_matchers.cpp
+// start catch_matchers_exception.cpp
+
+namespace Catch {
+namespace Matchers {
+namespace Exception {
+
+bool ExceptionMessageMatcher::match(std::exception const& ex) const {
+    return ex.what() == m_message;
+}
+
+std::string ExceptionMessageMatcher::describe() const {
+    return "exception message matches \"" + m_message + "\"";
+}
+
+}
+Exception::ExceptionMessageMatcher Message(std::string const& message) {
+    return Exception::ExceptionMessageMatcher(message);
+}
+
+// namespace Exception
+} // namespace Matchers
+} // namespace Catch
+// end catch_matchers_exception.cpp
 // start catch_matchers_floating.cpp
 
 // start catch_polyfills.hpp
@@ -9303,74 +11189,115 @@ namespace Catch {
 } // end namespace Catch
 
 // end catch_to_string.hpp
+#include <algorithm>
+#include <cmath>
 #include <cstdlib>
 #include <cstdint>
 #include <cstring>
+#include <sstream>
+#include <type_traits>
+#include <iomanip>
+#include <limits>
 
 namespace Catch {
-namespace Matchers {
-namespace Floating {
-enum class FloatingPointKind : uint8_t {
-    Float,
-    Double
-};
-}
-}
-}
-
 namespace {
 
-template <typename T>
-struct Converter;
-
-template <>
-struct Converter<float> {
-    static_assert(sizeof(float) == sizeof(int32_t), "Important ULP matcher assumption violated");
-    Converter(float f) {
+    int32_t convert(float f) {
+        static_assert(sizeof(float) == sizeof(int32_t), "Important ULP matcher assumption violated");
+        int32_t i;
         std::memcpy(&i, &f, sizeof(f));
+        return i;
     }
-    int32_t i;
-};
 
-template <>
-struct Converter<double> {
-    static_assert(sizeof(double) == sizeof(int64_t), "Important ULP matcher assumption violated");
-    Converter(double d) {
+    int64_t convert(double d) {
+        static_assert(sizeof(double) == sizeof(int64_t), "Important ULP matcher assumption violated");
+        int64_t i;
         std::memcpy(&i, &d, sizeof(d));
+        return i;
     }
-    int64_t i;
-};
 
-template <typename T>
-auto convert(T t) -> Converter<T> {
-    return Converter<T>(t);
-}
+    template <typename FP>
+    bool almostEqualUlps(FP lhs, FP rhs, uint64_t maxUlpDiff) {
+        // Comparison with NaN should always be false.
+        // This way we can rule it out before getting into the ugly details
+        if (Catch::isnan(lhs) || Catch::isnan(rhs)) {
+            return false;
+        }
 
-template <typename FP>
-bool almostEqualUlps(FP lhs, FP rhs, int maxUlpDiff) {
-    // Comparison with NaN should always be false.
-    // This way we can rule it out before getting into the ugly details
-    if (Catch::isnan(lhs) || Catch::isnan(rhs)) {
-        return false;
+        auto lc = convert(lhs);
+        auto rc = convert(rhs);
+
+        if ((lc < 0) != (rc < 0)) {
+            // Potentially we can have +0 and -0
+            return lhs == rhs;
+        }
+
+        auto ulpDiff = std::abs(lc - rc);
+        return static_cast<uint64_t>(ulpDiff) <= maxUlpDiff;
+    }
+
+} //end anonymous namespace
+
+#if defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
+
+#if defined(__clang__)
+#pragma clang diagnostic push
+// The long double overload is currently unused
+#pragma clang diagnostic ignored "-Wunused-function"
+#endif
+
+    float nextafter(float x, float y) {
+        return ::nextafterf(x, y);
     }
 
-    auto lc = convert(lhs);
-    auto rc = convert(rhs);
+    double nextafter(double x, double y) {
+        return ::nextafter(x, y);
+    }
 
-    if ((lc.i < 0) != (rc.i < 0)) {
-        // Potentially we can have +0 and -0
-        return lhs == rhs;
+    long double nextafter(long double x, long double y) {
+        return ::nextafterl(x, y);
     }
 
-    auto ulpDiff = std::abs(lc.i - rc.i);
-    return ulpDiff <= maxUlpDiff;
+#if defined(__clang__)
+#pragma clang diagnostic pop
+#endif
+
+#endif // ^^^ CATCH_CONFIG_GLOBAL_NEXTAFTER ^^^
+
+namespace {
+
+template <typename FP>
+FP step(FP start, FP direction, uint64_t steps) {
+    for (uint64_t i = 0; i < steps; ++i) {
+#if defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
+        start = Catch::nextafter(start, direction);
+#else
+        start = std::nextafter(start, direction);
+#endif
+    }
+    return start;
 }
 
+namespace {
+
+    // Performs equivalent check of std::fabs(lhs - rhs) <= margin
+    // But without the subtraction to allow for INFINITY in comparison
+    bool marginComparison(double lhs, double rhs, double margin) {
+        return (lhs + margin >= rhs) && (rhs + margin >= lhs);
+    }
+
 }
 
-namespace Catch {
+} // end anonymous namespace
+
 namespace Matchers {
 namespace Floating {
+
+    enum class FloatingPointKind : uint8_t {
+        Float,
+        Double
+    };
+
     WithinAbsMatcher::WithinAbsMatcher(double target, double margin)
         :m_target{ target }, m_margin{ margin } {
         CATCH_ENFORCE(margin >= 0, "Invalid margin: " << margin << '.'
@@ -9387,10 +11314,11 @@ namespace Floating {
         return "is within " + ::Catch::Detail::stringify(m_margin) + " of " + ::Catch::Detail::stringify(m_target);
     }
 
-    WithinUlpsMatcher::WithinUlpsMatcher(double target, int ulps, FloatingPointKind baseType)
+    WithinUlpsMatcher::WithinUlpsMatcher(double target, uint64_t ulps, FloatingPointKind baseType)
         :m_target{ target }, m_ulps{ ulps }, m_type{ baseType } {
-        CATCH_ENFORCE(ulps >= 0, "Invalid ULP setting: " << ulps << '.'
-            << " ULPs have to be non-negative.");
+        CATCH_ENFORCE(m_type == FloatingPointKind::Double
+                   || m_ulps < std::numeric_limits<uint32_t>::max(),
+            "Provided ULP is impossibly large for a float comparison.");
     }
 
 #if defined(__clang__)
@@ -9410,21 +11338,62 @@ namespace Floating {
         }
     }
 
-#if defined(__clang__)
-#pragma clang diagnostic pop
-#endif
+#if defined(__clang__)
+#pragma clang diagnostic pop
+#endif
+
+    std::string WithinUlpsMatcher::describe() const {
+        std::stringstream ret;
+
+        ret << "is within " << m_ulps << " ULPs of " << ::Catch::Detail::stringify(m_target);
+
+        if (m_type == FloatingPointKind::Float) {
+            ret << 'f';
+        }
+
+        ret << " ([";
+        ret << std::fixed << std::setprecision(std::numeric_limits<double>::max_digits10);
+        if (m_type == FloatingPointKind::Double) {
+            ret << step(m_target, static_cast<double>(-INFINITY), m_ulps)
+                << ", "
+                << step(m_target, static_cast<double>(INFINITY), m_ulps);
+        } else {
+            ret << step<float>(static_cast<float>(m_target), -INFINITY, m_ulps)
+                << ", "
+                << step<float>(static_cast<float>(m_target), INFINITY, m_ulps);
+        }
+        ret << "])";
+
+        return ret.str();
+        //return "is within " + Catch::to_string(m_ulps) + " ULPs of " + ::Catch::Detail::stringify(m_target) + ((m_type == FloatingPointKind::Float)? "f" : "");
+    }
+
+    WithinRelMatcher::WithinRelMatcher(double target, double epsilon):
+        m_target(target),
+        m_epsilon(epsilon){
+        CATCH_ENFORCE(m_epsilon >= 0., "Relative comparison with epsilon <  0 does not make sense.");
+        CATCH_ENFORCE(m_epsilon  < 1., "Relative comparison with epsilon >= 1 does not make sense.");
+    }
+
+    bool WithinRelMatcher::match(double const& matchee) const {
+        const auto relMargin = m_epsilon * std::max(std::fabs(matchee), std::fabs(m_target));
+        return marginComparison(matchee, m_target,
+                                std::isinf(relMargin)? 0 : relMargin);
+    }
 
-    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" : "");
+    std::string WithinRelMatcher::describe() const {
+        Catch::ReusableStringStream sstr;
+        sstr << "and " << m_target << " are within " << m_epsilon * 100. << "% of each other";
+        return sstr.str();
     }
 
 }// namespace Floating
 
-Floating::WithinUlpsMatcher WithinULP(double target, int maxUlpDiff) {
+Floating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff) {
     return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Double);
 }
 
-Floating::WithinUlpsMatcher WithinULP(float target, int maxUlpDiff) {
+Floating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff) {
     return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Float);
 }
 
@@ -9432,6 +11401,22 @@ Floating::WithinAbsMatcher WithinAbs(double target, double margin) {
     return Floating::WithinAbsMatcher(target, margin);
 }
 
+Floating::WithinRelMatcher WithinRel(double target, double eps) {
+    return Floating::WithinRelMatcher(target, eps);
+}
+
+Floating::WithinRelMatcher WithinRel(double target) {
+    return Floating::WithinRelMatcher(target, std::numeric_limits<double>::epsilon() * 100);
+}
+
+Floating::WithinRelMatcher WithinRel(float target, float eps) {
+    return Floating::WithinRelMatcher(target, eps);
+}
+
+Floating::WithinRelMatcher WithinRel(float target) {
+    return Floating::WithinRelMatcher(target, std::numeric_limits<float>::epsilon() * 100);
+}
+
 } // namespace Matchers
 } // namespace Catch
 
@@ -9620,6 +11605,15 @@ namespace Catch {
             }
             return names.substr(start, end - start + 1);
         };
+        auto skipq = [&] (size_t start, char quote) {
+            for (auto i = start + 1; i < names.size() ; ++i) {
+                if (names[i] == quote)
+                    return i;
+                if (names[i] == '\\')
+                    ++i;
+            }
+            CATCH_INTERNAL_ERROR("CAPTURE parsing encountered unmatched quote");
+        };
 
         size_t start = 0;
         std::stack<char> openings;
@@ -9640,10 +11634,14 @@ namespace Catch {
 //           case '>':
                 openings.pop();
                 break;
+            case '"':
+            case '\'':
+                pos = skipq(pos, c);
+                break;
             case ',':
                 if (start != pos && openings.size() == 0) {
                     m_messages.emplace_back(macroName, lineInfo, resultType);
-                    m_messages.back().message = trimmed(start, pos);
+                    m_messages.back().message = static_cast<std::string>(trimmed(start, pos));
                     m_messages.back().message += " := ";
                     start = pos;
                 }
@@ -9651,7 +11649,7 @@ namespace Catch {
         }
         assert(openings.size() == 0 && "Mismatched openings");
         m_messages.emplace_back(macroName, lineInfo, resultType);
-        m_messages.back().message = trimmed(start, names.size() - 1);
+        m_messages.back().message = static_cast<std::string>(trimmed(start, names.size() - 1));
         m_messages.back().message += " := ";
     }
     Capturer::~Capturer() {
@@ -9842,7 +11840,7 @@ namespace Catch {
             if (strerror_s(buffer, errno)) {
                 CATCH_RUNTIME_ERROR("Could not translate errno to a string");
             }
-            CATCH_RUNTIME_ERROR("Coul dnot open the temp file: '" << m_buffer << "' because: " << buffer);
+            CATCH_RUNTIME_ERROR("Could not open the temp file: '" << m_buffer << "' because: " << buffer);
         }
     }
 #else
@@ -9945,20 +11943,61 @@ namespace Catch {
 
 namespace Catch {
 
-    std::mt19937& rng() {
-        static std::mt19937 s_rng;
-        return s_rng;
+namespace {
+
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable:4146) // we negate uint32 during the rotate
+#endif
+        // Safe rotr implementation thanks to John Regehr
+        uint32_t rotate_right(uint32_t val, uint32_t count) {
+            const uint32_t mask = 31;
+            count &= mask;
+            return (val >> count) | (val << (-count & mask));
+        }
+
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+
+}
+
+    SimplePcg32::SimplePcg32(result_type seed_) {
+        seed(seed_);
+    }
+
+    void SimplePcg32::seed(result_type seed_) {
+        m_state = 0;
+        (*this)();
+        m_state += seed_;
+        (*this)();
     }
 
-    void seedRng( IConfig const& config ) {
-        if( config.rngSeed() != 0 ) {
-            std::srand( config.rngSeed() );
-            rng().seed( config.rngSeed() );
+    void SimplePcg32::discard(uint64_t skip) {
+        // We could implement this to run in O(log n) steps, but this
+        // should suffice for our use case.
+        for (uint64_t s = 0; s < skip; ++s) {
+            static_cast<void>((*this)());
         }
     }
 
-    unsigned int rngSeed() {
-        return getCurrentContext().getConfig()->rngSeed();
+    SimplePcg32::result_type SimplePcg32::operator()() {
+        // prepare the output value
+        const uint32_t xorshifted = static_cast<uint32_t>(((m_state >> 18u) ^ m_state) >> 27u);
+        const auto output = rotate_right(xorshifted, m_state >> 59u);
+
+        // advance state
+        m_state = m_state * 6364136223846793005ULL + s_inc;
+
+        return output;
+    }
+
+    bool operator==(SimplePcg32 const& lhs, SimplePcg32 const& rhs) {
+        return lhs.m_state == rhs.m_state;
+    }
+
+    bool operator!=(SimplePcg32 const& lhs, SimplePcg32 const& rhs) {
+        return lhs.m_state != rhs.m_state;
     }
 }
 // end catch_random_number_generator.cpp
@@ -9977,6 +12016,8 @@ namespace Catch {
     struct IConfig;
 
     std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases );
+
+    bool isThrowSafe( TestCase const& testCase, IConfig const& config );
     bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
 
     void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions );
@@ -10178,6 +12219,9 @@ namespace Catch {
             void registerStartupException() noexcept override {
                 m_exceptionRegistry.add(std::current_exception());
             }
+            IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() override {
+                return m_enumValuesRegistry;
+            }
 
         private:
             TestRegistry m_testCaseRegistry;
@@ -10185,6 +12229,7 @@ namespace Catch {
             ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
             TagAliasRegistry m_tagAliasRegistry;
             StartupExceptionRegistry m_exceptionRegistry;
+            Detail::EnumValuesRegistry m_enumValuesRegistry;
         };
     }
 
@@ -10480,12 +12525,21 @@ namespace Catch {
 
         m_unfinishedSections.push_back(endInfo);
     }
+
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+    void RunContext::benchmarkPreparing(std::string const& name) {
+		m_reporter->benchmarkPreparing(name);
+	}
     void RunContext::benchmarkStarting( BenchmarkInfo const& info ) {
         m_reporter->benchmarkStarting( info );
     }
-    void RunContext::benchmarkEnded( BenchmarkStats const& stats ) {
+    void RunContext::benchmarkEnded( BenchmarkStats<> const& stats ) {
         m_reporter->benchmarkEnded( stats );
     }
+	void RunContext::benchmarkFailed(std::string const & error) {
+		m_reporter->benchmarkFailed(error);
+	}
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
 
     void RunContext::pushScopedMessage(MessageInfo const & message) {
         m_messages.push_back(message);
@@ -10520,7 +12574,7 @@ namespace Catch {
         // Don't rebuild the result -- the stringification itself can cause more fatal errors
         // Instead, fake a result data.
         AssertionResultData tempResult( ResultWas::FatalErrorCondition, { false } );
-        tempResult.message = message;
+        tempResult.message = static_cast<std::string>(message);
         AssertionResult result(m_lastAssertionInfo, tempResult);
 
         assertionEnded(result);
@@ -10683,7 +12737,7 @@ namespace Catch {
         m_lastAssertionInfo = info;
 
         AssertionResultData data( resultType, LazyExpression( false ) );
-        data.message = message;
+        data.message = static_cast<std::string>(message);
         AssertionResult assertionResult{ m_lastAssertionInfo, data };
         assertionEnded( assertionResult );
         if( !assertionResult.isOk() )
@@ -10746,6 +12800,18 @@ namespace Catch {
         else
             CATCH_INTERNAL_ERROR("No result capture instance");
     }
+
+    void seedRng(IConfig const& config) {
+        if (config.rngSeed() != 0) {
+            std::srand(config.rngSeed());
+            rng().seed(config.rngSeed());
+        }
+    }
+
+    unsigned int rngSeed() {
+        return getCurrentContext().getConfig()->rngSeed();
+    }
+
 }
 // end catch_run_context.cpp
 // start catch_section.cpp
@@ -10807,7 +12873,7 @@ namespace Catch {
         void libIdentify();
 
         int applyCommandLine( int argc, char const * const * argv );
-    #if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE)
+    #if defined(CATCH_CONFIG_WCHAR) && defined(_WIN32) && defined(UNICODE)
         int applyCommandLine( int argc, wchar_t const * const * argv );
     #endif
 
@@ -10874,6 +12940,8 @@ namespace Catch {
 // end catch_version.h
 #include <cstdlib>
 #include <iomanip>
+#include <set>
+#include <iterator>
 
 namespace Catch {
 
@@ -10907,42 +12975,53 @@ namespace Catch {
             return ret;
         }
 
-        Catch::Totals runTests(std::shared_ptr<Config> const& config) {
-            auto reporter = makeReporter(config);
-
-            RunContext context(config, std::move(reporter));
-
-            Totals totals;
-
-            context.testGroupStarting(config->name(), 1, 1);
-
-            TestSpec testSpec = config->testSpec();
+        class TestGroup {
+        public:
+            explicit TestGroup(std::shared_ptr<Config> const& config)
+            : m_config{config}
+            , m_context{config, makeReporter(config)}
+            {
+                auto const& allTestCases = getAllTestCasesSorted(*m_config);
+                m_matches = m_config->testSpec().matchesByFilter(allTestCases, *m_config);
 
-            auto const& allTestCases = getAllTestCasesSorted(*config);
-            for (auto const& testCase : allTestCases) {
-                if (!context.aborting() && matchTest(testCase, testSpec, *config))
-                    totals += context.runTest(testCase);
-                else
-                    context.reporter().skipTest(testCase);
+                if (m_matches.empty()) {
+                    for (auto const& test : allTestCases)
+                        if (!test.isHidden())
+                            m_tests.emplace(&test);
+                } else {
+                    for (auto const& match : m_matches)
+                        m_tests.insert(match.tests.begin(), match.tests.end());
+                }
             }
 
-            if (config->warnAboutNoTests() && totals.testCases.total() == 0) {
-                ReusableStringStream testConfig;
-
-                bool first = true;
-                for (const auto& input : config->getTestsOrTags()) {
-                    if (!first) { testConfig << ' '; }
-                    first = false;
-                    testConfig << input;
+            Totals execute() {
+                Totals totals;
+                m_context.testGroupStarting(m_config->name(), 1, 1);
+                for (auto const& testCase : m_tests) {
+                    if (!m_context.aborting())
+                        totals += m_context.runTest(*testCase);
+                    else
+                        m_context.reporter().skipTest(*testCase);
                 }
 
-                context.reporter().noMatchingTestCases(testConfig.str());
-                totals.error = -1;
+                for (auto const& match : m_matches) {
+                    if (match.tests.empty()) {
+                        m_context.reporter().noMatchingTestCases(match.name);
+                        totals.error = -1;
+                    }
+                }
+                m_context.testGroupEnded(m_config->name(), totals, 1, 1);
+                return totals;
             }
 
-            context.testGroupEnded(config->name(), totals, 1, 1);
-            return totals;
-        }
+        private:
+            using Tests = std::set<TestCase const*>;
+
+            std::shared_ptr<Config> m_config;
+            RunContext m_context;
+            Tests m_tests;
+            TestSpec::Matches m_matches;
+        };
 
         void applyFilenamesAsTags(Catch::IConfig const& config) {
             auto& tests = const_cast<std::vector<TestCase>&>(getAllTestCasesSorted(config));
@@ -10979,6 +13058,9 @@ namespace Catch {
 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
         const auto& exceptions = getRegistryHub().getStartupExceptionRegistry().getExceptions();
         if ( !exceptions.empty() ) {
+            config();
+            getCurrentMutableContext().setConfig(m_config);
+
             m_startupExceptions = true;
             Colour colourGuard( Colour::Red );
             Catch::cerr() << "Errors occurred during startup!" << '\n';
@@ -11008,7 +13090,7 @@ namespace Catch {
     }
     void Session::libIdentify() {
         Catch::cout()
-                << std::left << std::setw(16) << "description: " << "A Catch test executable\n"
+                << std::left << std::setw(16) << "description: " << "A Catch2 test executable\n"
                 << std::left << std::setw(16) << "category: " << "testframework\n"
                 << std::left << std::setw(16) << "framework: " << "Catch Test\n"
                 << std::left << std::setw(16) << "version: " << libraryVersion() << std::endl;
@@ -11039,7 +13121,7 @@ namespace Catch {
         return 0;
     }
 
-#if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE)
+#if defined(CATCH_CONFIG_WCHAR) && defined(_WIN32) && defined(UNICODE)
     int Session::applyCommandLine( int argc, wchar_t const * const * argv ) {
 
         char **utf8Argv = new char *[ argc ];
@@ -11116,7 +13198,12 @@ namespace Catch {
             if( Option<std::size_t> listed = list( m_config ) )
                 return static_cast<int>( *listed );
 
-            auto totals = runTests( m_config );
+            TestGroup tests { m_config };
+            auto const totals = tests.execute();
+
+            if( m_config->warnAboutNoTests() && totals.error == -1 )
+                return 2;
+
             // Note that on unices only the lower 8 bits are usually used, clamping
             // the return value to 255 prevents false negative when some multiple
             // of 256 tests has failed
@@ -11193,7 +13280,7 @@ namespace Catch {
 
     Catch::IStream::~IStream() = default;
 
-    namespace detail { namespace {
+    namespace Detail { namespace {
         template<typename WriterF, std::size_t bufferSize=256>
         class StreamBufImpl : public std::streambuf {
             char data[bufferSize];
@@ -11292,15 +13379,15 @@ namespace Catch {
 
     auto makeStream( StringRef const &filename ) -> IStream const* {
         if( filename.empty() )
-            return new detail::CoutStream();
+            return new Detail::CoutStream();
         else if( filename[0] == '%' ) {
             if( filename == "%debug" )
-                return new detail::DebugOutStream();
+                return new Detail::DebugOutStream();
             else
                 CATCH_ERROR( "Unrecognised stream: '" << filename << "'" );
         }
         else
-            return new detail::FileStream( filename );
+            return new Detail::FileStream( filename );
     }
 
     // This class encapsulates the idea of a pool of ostringstreams that can be reused.
@@ -11357,6 +13444,7 @@ namespace Catch {
 #include <ostream>
 #include <cstring>
 #include <cctype>
+#include <vector>
 
 namespace Catch {
 
@@ -11397,6 +13485,18 @@ namespace Catch {
         return start != std::string::npos ? str.substr( start, 1+end-start ) : std::string();
     }
 
+    StringRef trim(StringRef ref) {
+        const auto is_ws = [](char c) {
+            return c == ' ' || c == '\t' || c == '\n' || c == '\r';
+        };
+        size_t real_begin = 0;
+        while (real_begin < ref.size() && is_ws(ref[real_begin])) { ++real_begin; }
+        size_t real_end = ref.size();
+        while (real_end > real_begin && is_ws(ref[real_end - 1])) { --real_end; }
+
+        return ref.substr(real_begin, real_end - real_begin);
+    }
+
     bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {
         bool replaced = false;
         std::size_t i = str.find( replaceThis );
@@ -11411,6 +13511,21 @@ namespace Catch {
         return replaced;
     }
 
+    std::vector<StringRef> splitStringRef( StringRef str, char delimiter ) {
+        std::vector<StringRef> subStrings;
+        std::size_t start = 0;
+        for(std::size_t pos = 0; pos < str.size(); ++pos ) {
+            if( str[pos] == delimiter ) {
+                if( pos - start > 1 )
+                    subStrings.push_back( str.substr( start, pos-start ) );
+                start = pos+1;
+            }
+        }
+        if( start < str.size() )
+            subStrings.push_back( str.substr( start, str.size()-start ) );
+        return subStrings;
+    }
+
     pluralise::pluralise( std::size_t count, std::string const& label )
     :   m_count( count ),
         m_label( label )
@@ -11436,21 +13551,11 @@ namespace Catch {
 #include <cstring>
 #include <cstdint>
 
-namespace {
-    const uint32_t byte_2_lead = 0xC0;
-    const uint32_t byte_3_lead = 0xE0;
-    const uint32_t byte_4_lead = 0xF0;
-}
-
 namespace Catch {
     StringRef::StringRef( char const* rawChars ) noexcept
     : StringRef( rawChars, static_cast<StringRef::size_type>(std::strlen(rawChars) ) )
     {}
 
-    StringRef::operator std::string() const {
-        return std::string( m_start, m_size );
-    }
-
     void StringRef::swap( StringRef& other ) noexcept {
         std::swap( m_start, other.m_start );
         std::swap( m_size, other.m_size );
@@ -11458,9 +13563,11 @@ namespace Catch {
     }
 
     auto StringRef::c_str() const -> char const* {
-        if( isSubstring() )
-           const_cast<StringRef*>( this )->takeOwnership();
-        return m_start;
+        if( !isSubstring() )
+            return m_start;
+
+        const_cast<StringRef *>( this )->takeOwnership();
+        return m_data;
     }
     auto StringRef::currentData() const noexcept -> char const* {
         return m_start;
@@ -11478,7 +13585,6 @@ namespace Catch {
             m_data = new char[m_size+1];
             memcpy( m_data, m_start, m_size );
             m_data[m_size] = '\0';
-            m_start = m_data;
         }
     }
     auto StringRef::substr( size_type start, size_type size ) const noexcept -> StringRef {
@@ -11496,40 +13602,6 @@ namespace Catch {
         return !operator==( other );
     }
 
-    auto StringRef::operator[](size_type index) const noexcept -> char {
-        return m_start[index];
-    }
-
-    auto StringRef::numberOfCharacters() const noexcept -> size_type {
-        size_type noChars = m_size;
-        // Make adjustments for uft encodings
-        for( size_type i=0; i < m_size; ++i ) {
-            char c = m_start[i];
-            if( ( c & byte_2_lead ) == byte_2_lead ) {
-                noChars--;
-                if (( c & byte_3_lead ) == byte_3_lead )
-                    noChars--;
-                if( ( c & byte_4_lead ) == byte_4_lead )
-                    noChars--;
-            }
-        }
-        return noChars;
-    }
-
-    auto operator + ( StringRef const& lhs, StringRef const& rhs ) -> std::string {
-        std::string str;
-        str.reserve( lhs.size() + rhs.size() );
-        str += lhs;
-        str += rhs;
-        return str;
-    }
-    auto operator + ( StringRef const& lhs, const char* rhs ) -> std::string {
-        return std::string( lhs ) + std::string( rhs );
-    }
-    auto operator + ( char const* lhs, StringRef const& rhs ) -> std::string {
-        return std::string( lhs ) + std::string( rhs );
-    }
-
     auto operator << ( std::ostream& os, StringRef const& str ) -> std::ostream& {
         return os.write(str.currentData(), str.size());
     }
@@ -11646,7 +13718,7 @@ namespace Catch {
         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"
+                          << "Tag names starting with non alphanumeric characters are reserved\n"
                           << _lineInfo );
         }
     }
@@ -11662,8 +13734,7 @@ namespace Catch {
         std::vector<std::string> tags;
         std::string desc, tag;
         bool inTag = false;
-        std::string _descOrTags = nameAndTags.tags;
-        for (char c : _descOrTags) {
+        for (char c : nameAndTags.tags) {
             if( !inTag ) {
                 if( c == '[' )
                     inTag = true;
@@ -11696,7 +13767,7 @@ namespace Catch {
             tags.push_back( "." );
         }
 
-        TestCaseInfo info( nameAndTags.name, _className, desc, tags, _lineInfo );
+        TestCaseInfo info( static_cast<std::string>(nameAndTags.name), _className, desc, tags, _lineInfo );
         return TestCase( _testCase, std::move(info) );
     }
 
@@ -11810,8 +13881,13 @@ namespace Catch {
         }
         return sorted;
     }
+
+    bool isThrowSafe( TestCase const& testCase, IConfig const& config ) {
+        return !testCase.throws() || config.allowThrows();
+    }
+
     bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) {
-        return testSpec.matches( testCase ) && ( config.allowThrows() || !testCase.throws() );
+        return testSpec.matches( testCase ) && isThrowSafe( testCase, config );
     }
 
     void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions ) {
@@ -11828,9 +13904,12 @@ namespace Catch {
     std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ) {
         std::vector<TestCase> filtered;
         filtered.reserve( testCases.size() );
-        for( auto const& testCase : testCases )
-            if( matchTest( testCase, testSpec, config ) )
-                filtered.push_back( testCase );
+        for (auto const& testCase : testCases) {
+            if ((!testSpec.hasFilters() && !testCase.isHidden()) ||
+                (testSpec.hasFilters() && matchTest(testCase, testSpec, config))) {
+                filtered.push_back(testCase);
+            }
+        }
         return filtered;
     }
     std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config ) {
@@ -11869,7 +13948,7 @@ namespace Catch {
     }
 
     std::string extractClassName( StringRef const& classOrQualifiedMethodName ) {
-        std::string className = classOrQualifiedMethodName;
+        std::string className(classOrQualifiedMethodName);
         if( startsWith( className, '&' ) )
         {
             std::size_t lastColons = className.rfind( "::" );
@@ -11906,11 +13985,6 @@ namespace TestCaseTracking {
 
     ITracker::~ITracker() = default;
 
-    TrackerContext& TrackerContext::instance() {
-        static TrackerContext s_instance;
-        return s_instance;
-    }
-
     ITracker& TrackerContext::startRun() {
         m_rootTracker = std::make_shared<SectionTracker>( NameAndLocation( "{root}", CATCH_INTERNAL_LINEINFO ), *this, nullptr );
         m_currentTracker = nullptr;
@@ -12016,7 +14090,7 @@ namespace TestCaseTracking {
                 m_runState = CompletedSuccessfully;
                 break;
             case ExecutingChildren:
-                if( m_children.empty() || m_children.back()->isComplete() )
+                if( std::all_of(m_children.begin(), m_children.end(), [](ITrackerPtr const& t){ return t->isComplete(); }) )
                     m_runState = CompletedSuccessfully;
                 break;
 
@@ -12051,7 +14125,8 @@ namespace TestCaseTracking {
     }
 
     SectionTracker::SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
-    :   TrackerBase( nameAndLocation, ctx, parent )
+    :   TrackerBase( nameAndLocation, ctx, parent ),
+        m_trimmed_name(trim(nameAndLocation.name))
     {
         if( parent ) {
             while( !parent->isSectionTracker() )
@@ -12065,12 +14140,11 @@ namespace TestCaseTracking {
     bool SectionTracker::isComplete() const {
         bool complete = true;
 
-        if ((m_filters.empty() || m_filters[0] == "") ||
-             std::find(m_filters.begin(), m_filters.end(),
-                       m_nameAndLocation.name) != m_filters.end())
+        if ((m_filters.empty() || m_filters[0] == "")
+            || std::find(m_filters.begin(), m_filters.end(), m_trimmed_name) != m_filters.end()) {
             complete = TrackerBase::isComplete();
+        }
         return complete;
-
     }
 
     bool SectionTracker::isSectionTracker() const { return true; }
@@ -12094,12 +14168,13 @@ namespace TestCaseTracking {
     }
 
     void SectionTracker::tryOpen() {
-        if( !isComplete() && (m_filters.empty() || m_filters[0].empty() ||  m_filters[0] == m_nameAndLocation.name ) )
+        if( !isComplete() )
             open();
     }
 
     void SectionTracker::addInitialFilters( std::vector<std::string> const& filters ) {
         if( !filters.empty() ) {
+            m_filters.reserve( m_filters.size() + filters.size() + 2 );
             m_filters.push_back(""); // Root - should never be consulted
             m_filters.push_back(""); // Test Case - not a section filter
             m_filters.insert( m_filters.end(), filters.begin(), filters.end() );
@@ -12107,7 +14182,7 @@ namespace TestCaseTracking {
     }
     void SectionTracker::addNextFilters( std::vector<std::string> const& filters ) {
         if( filters.size() > 1 )
-            m_filters.insert( m_filters.end(), ++filters.begin(), filters.end() );
+            m_filters.insert( m_filters.end(), filters.begin()+1, filters.end() );
     }
 
 } // namespace TestCaseTracking
@@ -12159,47 +14234,77 @@ namespace Catch {
 
 namespace Catch {
 
+    TestSpec::Pattern::Pattern( std::string const& name )
+    : m_name( name )
+    {}
+
     TestSpec::Pattern::~Pattern() = default;
-    TestSpec::NamePattern::~NamePattern() = default;
-    TestSpec::TagPattern::~TagPattern() = default;
-    TestSpec::ExcludedPattern::~ExcludedPattern() = default;
 
-    TestSpec::NamePattern::NamePattern( std::string const& name )
-    : m_wildcardPattern( toLower( name ), CaseSensitive::No )
+    std::string const& TestSpec::Pattern::name() const {
+        return m_name;
+    }
+
+    TestSpec::NamePattern::NamePattern( std::string const& name, std::string const& filterString )
+    : Pattern( filterString )
+    , m_wildcardPattern( toLower( name ), CaseSensitive::No )
     {}
+
     bool TestSpec::NamePattern::matches( TestCaseInfo const& testCase ) const {
-        return m_wildcardPattern.matches( toLower( testCase.name ) );
+        return m_wildcardPattern.matches( testCase.name );
     }
 
-    TestSpec::TagPattern::TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {}
+    TestSpec::TagPattern::TagPattern( std::string const& tag, std::string const& filterString )
+    : Pattern( filterString )
+    , m_tag( toLower( tag ) )
+    {}
+
     bool TestSpec::TagPattern::matches( TestCaseInfo const& testCase ) const {
         return std::find(begin(testCase.lcaseTags),
                          end(testCase.lcaseTags),
                          m_tag) != end(testCase.lcaseTags);
     }
 
-    TestSpec::ExcludedPattern::ExcludedPattern( PatternPtr const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {}
-    bool TestSpec::ExcludedPattern::matches( TestCaseInfo const& testCase ) const { return !m_underlyingPattern->matches( testCase ); }
+    TestSpec::ExcludedPattern::ExcludedPattern( PatternPtr const& underlyingPattern )
+    : Pattern( underlyingPattern->name() )
+    , m_underlyingPattern( underlyingPattern )
+    {}
+
+    bool TestSpec::ExcludedPattern::matches( TestCaseInfo const& testCase ) const {
+        return !m_underlyingPattern->matches( testCase );
+    }
 
     bool TestSpec::Filter::matches( TestCaseInfo const& testCase ) const {
-        // All patterns in a filter must match for the filter to be a match
-        for( auto const& pattern : m_patterns ) {
-            if( !pattern->matches( testCase ) )
-                return false;
-        }
-        return true;
+        return std::all_of( m_patterns.begin(), m_patterns.end(), [&]( PatternPtr const& p ){ return p->matches( testCase ); } );
+    }
+
+    std::string TestSpec::Filter::name() const {
+        std::string name;
+        for( auto const& p : m_patterns )
+            name += p->name();
+        return name;
     }
 
     bool TestSpec::hasFilters() const {
         return !m_filters.empty();
     }
+
     bool TestSpec::matches( TestCaseInfo const& testCase ) const {
-        // A TestSpec matches if any filter matches
-        for( auto const& filter : m_filters )
-            if( filter.matches( testCase ) )
-                return true;
-        return false;
+        return std::any_of( m_filters.begin(), m_filters.end(), [&]( Filter const& f ){ return f.matches( testCase ); } );
+    }
+
+    TestSpec::Matches TestSpec::matchesByFilter( std::vector<TestCase> const& testCases, IConfig const& config ) const
+    {
+        Matches matches( m_filters.size() );
+        std::transform( m_filters.begin(), m_filters.end(), matches.begin(), [&]( Filter const& filter ){
+            std::vector<TestCase const*> currentMatches;
+            for( auto const& test : testCases )
+                if( isThrowSafe( test, config ) && filter.matches( test ) )
+                    currentMatches.emplace_back( &test );
+            return FilterMatch{ filter.name(), currentMatches };
+        } );
+        return matches;
     }
+
 }
 // end catch_test_spec.cpp
 // start catch_test_spec_parser.cpp
@@ -12211,64 +14316,136 @@ namespace Catch {
     TestSpecParser& TestSpecParser::parse( std::string const& arg ) {
         m_mode = None;
         m_exclusion = false;
-        m_start = std::string::npos;
         m_arg = m_tagAliases->expandAliases( arg );
         m_escapeChars.clear();
+        m_substring.reserve(m_arg.size());
+        m_patternName.reserve(m_arg.size());
+        m_realPatternPos = 0;
         for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
             visitChar( m_arg[m_pos] );
-        if( m_mode == Name )
-            addPattern<TestSpec::NamePattern>();
+        endMode();
         return *this;
     }
     TestSpec TestSpecParser::testSpec() {
         addFilter();
         return m_testSpec;
     }
-
     void TestSpecParser::visitChar( char c ) {
-        if( m_mode == None ) {
-            switch( c ) {
-            case ' ': return;
-            case '~': m_exclusion = true; return;
-            case '[': return startNewMode( Tag, ++m_pos );
-            case '"': return startNewMode( QuotedName, ++m_pos );
-            case '\\': return escape();
-            default: startNewMode( Name, m_pos ); break;
-            }
-        }
-        if( m_mode == Name ) {
-            if( c == ',' ) {
-                addPattern<TestSpec::NamePattern>();
-                addFilter();
-            }
-            else if( c == '[' ) {
-                if( subString() == "exclude:" )
-                    m_exclusion = true;
-                else
-                    addPattern<TestSpec::NamePattern>();
-                startNewMode( Tag, ++m_pos );
-            }
-            else if( c == '\\' )
-                escape();
+        if( (m_mode != EscapedName) && (c == '\\') ) {
+            escape();
+            m_substring += c;
+            m_patternName += c;
+            m_realPatternPos++;
+            return;
+        }else if((m_mode != EscapedName) && (c == ',') )  {
+            endMode();
+            addFilter();
+            return;
+        }
+
+        switch( m_mode ) {
+        case None:
+            if( processNoneChar( c ) )
+                return;
+            break;
+        case Name:
+            processNameChar( c );
+            break;
+        case EscapedName:
+            endMode();
+            m_substring += c;
+            m_patternName += c;
+            m_realPatternPos++;
+            return;
+        default:
+        case Tag:
+        case QuotedName:
+            if( processOtherChar( c ) )
+                return;
+            break;
+        }
+
+        m_substring += c;
+        if( !isControlChar( c ) ) {
+            m_patternName += c;
+            m_realPatternPos++;
+        }
+    }
+    // Two of the processing methods return true to signal the caller to return
+    // without adding the given character to the current pattern strings
+    bool TestSpecParser::processNoneChar( char c ) {
+        switch( c ) {
+        case ' ':
+            return true;
+        case '~':
+            m_exclusion = true;
+            return false;
+        case '[':
+            startNewMode( Tag );
+            return false;
+        case '"':
+            startNewMode( QuotedName );
+            return false;
+        default:
+            startNewMode( Name );
+            return false;
         }
-        else if( m_mode == EscapedName )
-            m_mode = Name;
-        else if( m_mode == QuotedName && c == '"' )
-            addPattern<TestSpec::NamePattern>();
-        else if( m_mode == Tag && c == ']' )
-            addPattern<TestSpec::TagPattern>();
     }
-    void TestSpecParser::startNewMode( Mode mode, std::size_t start ) {
+    void TestSpecParser::processNameChar( char c ) {
+        if( c == '[' ) {
+            if( m_substring == "exclude:" )
+                m_exclusion = true;
+            else
+                endMode();
+            startNewMode( Tag );
+        }
+    }
+    bool TestSpecParser::processOtherChar( char c ) {
+        if( !isControlChar( c ) )
+            return false;
+        m_substring += c;
+        endMode();
+        return true;
+    }
+    void TestSpecParser::startNewMode( Mode mode ) {
         m_mode = mode;
-        m_start = start;
+    }
+    void TestSpecParser::endMode() {
+        switch( m_mode ) {
+        case Name:
+        case QuotedName:
+            return addPattern<TestSpec::NamePattern>();
+        case Tag:
+            return addPattern<TestSpec::TagPattern>();
+        case EscapedName:
+            revertBackToLastMode();
+            return;
+        case None:
+        default:
+            return startNewMode( None );
+        }
     }
     void TestSpecParser::escape() {
-        if( m_mode == None )
-            m_start = m_pos;
+        saveLastMode();
         m_mode = EscapedName;
-        m_escapeChars.push_back( m_pos );
+        m_escapeChars.push_back(m_realPatternPos);
+    }
+    bool TestSpecParser::isControlChar( char c ) const {
+        switch( m_mode ) {
+            default:
+                return false;
+            case None:
+                return c == '~';
+            case Name:
+                return c == '[';
+            case EscapedName:
+                return true;
+            case QuotedName:
+                return c == '"';
+            case Tag:
+                return c == '[' || c == ']';
+        }
     }
-    std::string TestSpecParser::subString() const { return m_arg.substr( m_start, m_pos - m_start ); }
 
     void TestSpecParser::addFilter() {
         if( !m_currentFilter.m_patterns.empty() ) {
@@ -12277,6 +14454,14 @@ namespace Catch {
         }
     }
 
+    void TestSpecParser::saveLastMode() {
+      lastMode = m_mode;
+    }
+
+    void TestSpecParser::revertBackToLastMode() {
+      m_mode = lastMode;
+    }
+
     TestSpec parseTestSpec( std::string const& arg ) {
         return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
     }
@@ -12508,6 +14693,13 @@ std::string StringMaker<wchar_t *>::convert(wchar_t * str) {
 }
 #endif
 
+#if defined(CATCH_CONFIG_CPP17_BYTE)
+#include <cstddef>
+std::string StringMaker<std::byte>::convert(std::byte value) {
+    return ::Catch::Detail::stringify(std::to_integer<unsigned long long>(value));
+}
+#endif // defined(CATCH_CONFIG_CPP17_BYTE)
+
 std::string StringMaker<int>::convert(int value) {
     return ::Catch::Detail::stringify(static_cast<long long>(value));
 }
@@ -12570,11 +14762,16 @@ std::string StringMaker<std::nullptr_t>::convert(std::nullptr_t) {
     return "nullptr";
 }
 
+int StringMaker<float>::precision = 5;
+
 std::string StringMaker<float>::convert(float value) {
-    return fpToString(value, 5) + 'f';
+    return fpToString(value, precision) + 'f';
 }
+
+int StringMaker<double>::precision = 10;
+
 std::string StringMaker<double>::convert(double value) {
-    return fpToString(value, 10);
+    return fpToString(value, precision);
 }
 
 std::string ratio_string<std::atto>::symbol() { return "a"; }
@@ -12692,7 +14889,7 @@ namespace Catch {
     }
 
     Version const& libraryVersion() {
-        static Version version( 2, 7, 1, "", 0 );
+        static Version version( 2, 10, 0, "", 0 );
         return version;
     }
 
@@ -12700,14 +14897,12 @@ namespace Catch {
 // end catch_version.cpp
 // start catch_wildcard_pattern.cpp
 
-#include <sstream>
-
 namespace Catch {
 
     WildcardPattern::WildcardPattern( std::string const& pattern,
                                       CaseSensitive::Choice caseSensitivity )
     :   m_caseSensitivity( caseSensitivity ),
-        m_pattern( adjustCase( pattern ) )
+        m_pattern( normaliseString( pattern ) )
     {
         if( startsWith( m_pattern, '*' ) ) {
             m_pattern = m_pattern.substr( 1 );
@@ -12722,20 +14917,20 @@ namespace Catch {
     bool WildcardPattern::matches( std::string const& str ) const {
         switch( m_wildcard ) {
             case NoWildcard:
-                return m_pattern == adjustCase( str );
+                return m_pattern == normaliseString( str );
             case WildcardAtStart:
-                return endsWith( adjustCase( str ), m_pattern );
+                return endsWith( normaliseString( str ), m_pattern );
             case WildcardAtEnd:
-                return startsWith( adjustCase( str ), m_pattern );
+                return startsWith( normaliseString( str ), m_pattern );
             case WildcardAtBothEnds:
-                return contains( adjustCase( str ), m_pattern );
+                return contains( normaliseString( str ), m_pattern );
             default:
                 CATCH_INTERNAL_ERROR( "Unknown enum" );
         }
     }
 
-    std::string WildcardPattern::adjustCase( std::string const& str ) const {
-        return m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str;
+    std::string WildcardPattern::normaliseString( std::string const& str ) const {
+        return trim( m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str );
     }
 }
 // end catch_wildcard_pattern.cpp
@@ -13279,24 +15474,25 @@ private:
         if (itMessage == messages.end())
             return;
 
-        // using messages.end() directly yields (or auto) compilation error:
-        std::vector<MessageInfo>::const_iterator itEnd = messages.end();
-        const std::size_t N = static_cast<std::size_t>(std::distance(itMessage, itEnd));
+        const auto itEnd = messages.cend();
+        const auto N = static_cast<std::size_t>(std::distance(itMessage, itEnd));
 
         {
             Colour colourGuard(colour);
             stream << " with " << pluralise(N, "message") << ':';
         }
 
-        for (; itMessage != itEnd; ) {
+        while (itMessage != itEnd) {
             // If this assertion is a warning ignore any INFO messages
             if (printInfoMessages || itMessage->type != ResultWas::Info) {
-                stream << " '" << itMessage->message << '\'';
-                if (++itMessage != itEnd) {
+                printMessage();
+                if (itMessage != itEnd) {
                     Colour colourGuard(dimColour());
                     stream << " and";
                 }
+                continue;
             }
+            ++itMessage;
         }
     }
 
@@ -13369,8 +15565,13 @@ private:
 #if defined(_MSC_VER)
 #pragma warning(push)
 #pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
- // Note that 4062 (not all labels are handled
- // and default is missing) is enabled
+ // Note that 4062 (not all labels are handled and default is missing) is enabled
+#endif
+
+#if defined(__clang__)
+#  pragma clang diagnostic push
+// For simplicity, benchmarking-only helpers are always enabled
+#  pragma clang diagnostic ignored "-Wunused-function"
 #endif
 
 namespace Catch {
@@ -13556,6 +15757,10 @@ class Duration {
     Unit m_units;
 
 public:
+	explicit Duration(double inNanoseconds, Unit units = Unit::Auto)
+        : Duration(static_cast<uint64_t>(inNanoseconds), units) {
+    }
+
     explicit Duration(uint64_t inNanoseconds, Unit units = Unit::Auto)
         : m_inNanoseconds(inNanoseconds),
         m_units(units) {
@@ -13606,7 +15811,7 @@ public:
 
     }
     friend auto operator << (std::ostream& os, Duration const& duration) -> std::ostream& {
-        return os << duration.value() << " " << duration.unitsAsString();
+        return os << duration.value() << ' ' << duration.unitsAsString();
     }
 };
 } // end anon namespace
@@ -13631,10 +15836,16 @@ public:
         if (!m_isOpen) {
             m_isOpen = true;
             *this << RowBreak();
-            for (auto const& info : m_columnInfos)
-                *this << info.name << ColumnBreak();
-            *this << RowBreak();
-            m_os << Catch::getLineOfChars<'-'>() << "\n";
+
+			Columns headerCols;
+			Spacer spacer(2);
+			for (auto const& info : m_columnInfos) {
+				headerCols += Column(info.name).width(static_cast<std::size_t>(info.width - 2));
+				headerCols += spacer;
+			}
+			m_os << headerCols << '\n';
+
+            m_os << Catch::getLineOfChars<'-'>() << '\n';
         }
     }
     void close() {
@@ -13653,30 +15864,29 @@ public:
 
     friend TablePrinter& operator << (TablePrinter& tp, ColumnBreak) {
         auto colStr = tp.m_oss.str();
-        // This takes account of utf8 encodings
-        auto strSize = Catch::StringRef(colStr).numberOfCharacters();
+        const auto strSize = colStr.size();
         tp.m_oss.str("");
         tp.open();
         if (tp.m_currentColumn == static_cast<int>(tp.m_columnInfos.size() - 1)) {
             tp.m_currentColumn = -1;
-            tp.m_os << "\n";
+            tp.m_os << '\n';
         }
         tp.m_currentColumn++;
 
         auto colInfo = tp.m_columnInfos[tp.m_currentColumn];
-        auto padding = (strSize + 2 < static_cast<std::size_t>(colInfo.width))
-            ? std::string(colInfo.width - (strSize + 2), ' ')
+        auto padding = (strSize + 1 < static_cast<std::size_t>(colInfo.width))
+            ? std::string(colInfo.width - (strSize + 1), ' ')
             : std::string();
         if (colInfo.justification == ColumnInfo::Left)
-            tp.m_os << colStr << padding << " ";
+            tp.m_os << colStr << padding << ' ';
         else
-            tp.m_os << padding << colStr << " ";
+            tp.m_os << padding << colStr << ' ';
         return tp;
     }
 
     friend TablePrinter& operator << (TablePrinter& tp, RowBreak) {
         if (tp.m_currentColumn > 0) {
-            tp.m_os << "\n";
+            tp.m_os << '\n';
             tp.m_currentColumn = -1;
         }
         return tp;
@@ -13686,12 +15896,26 @@ public:
 ConsoleReporter::ConsoleReporter(ReporterConfig const& config)
     : StreamingReporterBase(config),
     m_tablePrinter(new TablePrinter(config.stream(),
-    {
-        { "benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 32, ColumnInfo::Left },
-        { "iters", 8, ColumnInfo::Right },
-        { "elapsed ns", 14, ColumnInfo::Right },
-        { "average", 14, ColumnInfo::Right }
-    })) {}
+        [&config]() -> std::vector<ColumnInfo> {
+        if (config.fullConfig()->benchmarkNoAnalysis())
+        {
+            return{
+                { "benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 43, ColumnInfo::Left },
+                { "     samples", 14, ColumnInfo::Right },
+                { "  iterations", 14, ColumnInfo::Right },
+                { "        mean", 14, ColumnInfo::Right }
+            };
+        }
+        else
+        {
+            return{
+                { "benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 32, ColumnInfo::Left },
+                { "samples      mean       std dev", 14, ColumnInfo::Right },
+                { "iterations   low mean   low std dev", 14, ColumnInfo::Right },
+                { "estimated    high mean  high std dev", 14, ColumnInfo::Right }
+            };
+        }
+    }())) {}
 ConsoleReporter::~ConsoleReporter() = default;
 
 std::string ConsoleReporter::getDescription() {
@@ -13722,6 +15946,7 @@ bool ConsoleReporter::assertionEnded(AssertionStats const& _assertionStats) {
 }
 
 void ConsoleReporter::sectionStarting(SectionInfo const& _sectionInfo) {
+    m_tablePrinter->close();
     m_headerPrinted = false;
     StreamingReporterBase::sectionStarting(_sectionInfo);
 }
@@ -13745,28 +15970,53 @@ void ConsoleReporter::sectionEnded(SectionStats const& _sectionStats) {
     StreamingReporterBase::sectionEnded(_sectionStats);
 }
 
-void ConsoleReporter::benchmarkStarting(BenchmarkInfo const& info) {
-    lazyPrintWithoutClosingBenchmarkTable();
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+void ConsoleReporter::benchmarkPreparing(std::string const& name) {
+	lazyPrintWithoutClosingBenchmarkTable();
 
-    auto nameCol = Column( info.name ).width( static_cast<std::size_t>( m_tablePrinter->columnInfos()[0].width - 2 ) );
+	auto nameCol = Column(name).width(static_cast<std::size_t>(m_tablePrinter->columnInfos()[0].width - 2));
 
-    bool firstLine = true;
-    for (auto line : nameCol) {
-        if (!firstLine)
-            (*m_tablePrinter) << ColumnBreak() << ColumnBreak() << ColumnBreak();
-        else
-            firstLine = false;
+	bool firstLine = true;
+	for (auto line : nameCol) {
+		if (!firstLine)
+			(*m_tablePrinter) << ColumnBreak() << ColumnBreak() << ColumnBreak();
+		else
+			firstLine = false;
+
+		(*m_tablePrinter) << line << ColumnBreak();
+	}
+}
 
-        (*m_tablePrinter) << line << ColumnBreak();
+void ConsoleReporter::benchmarkStarting(BenchmarkInfo const& info) {
+    (*m_tablePrinter) << info.samples << ColumnBreak()
+        << info.iterations << ColumnBreak();
+    if (!m_config->benchmarkNoAnalysis())
+        (*m_tablePrinter) << Duration(info.estimatedDuration) << ColumnBreak();
+}
+void ConsoleReporter::benchmarkEnded(BenchmarkStats<> const& stats) {
+    if (m_config->benchmarkNoAnalysis())
+    {
+        (*m_tablePrinter) << Duration(stats.mean.point.count()) << ColumnBreak();
+    }
+    else
+    {
+        (*m_tablePrinter) << ColumnBreak()
+            << Duration(stats.mean.point.count()) << ColumnBreak()
+            << Duration(stats.mean.lower_bound.count()) << ColumnBreak()
+            << Duration(stats.mean.upper_bound.count()) << ColumnBreak() << ColumnBreak()
+            << Duration(stats.standardDeviation.point.count()) << ColumnBreak()
+            << Duration(stats.standardDeviation.lower_bound.count()) << ColumnBreak()
+            << Duration(stats.standardDeviation.upper_bound.count()) << ColumnBreak() << ColumnBreak() << ColumnBreak() << ColumnBreak() << ColumnBreak();
     }
 }
-void ConsoleReporter::benchmarkEnded(BenchmarkStats const& stats) {
-    Duration average(stats.elapsedTimeInNanoseconds / stats.iterations);
+
+void ConsoleReporter::benchmarkFailed(std::string const& error) {
+	Colour colour(Colour::Red);
     (*m_tablePrinter)
-        << stats.iterations << ColumnBreak()
-        << stats.elapsedTimeInNanoseconds << ColumnBreak()
-        << average << ColumnBreak();
+        << "Benchmark failed (" << error << ')'
+        << ColumnBreak() << RowBreak();
 }
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
 
 void ConsoleReporter::testCaseEnded(TestCaseStats const& _testCaseStats) {
     m_tablePrinter->close();
@@ -13845,11 +16095,9 @@ void ConsoleReporter::printTestCaseAndSectionHeader() {
 
     SourceLineInfo lineInfo = m_sectionStack.back().lineInfo;
 
-    if (!lineInfo.empty()) {
-        stream << getLineOfChars<'-'>() << '\n';
-        Colour colourGuard(Colour::FileName);
-        stream << lineInfo << '\n';
-    }
+    stream << getLineOfChars<'-'>() << '\n';
+    Colour colourGuard(Colour::FileName);
+    stream << lineInfo << '\n';
     stream << getLineOfChars<'.'>() << '\n' << std::endl;
 }
 
@@ -13985,6 +16233,10 @@ CATCH_REGISTER_REPORTER("console", ConsoleReporter)
 #if defined(_MSC_VER)
 #pragma warning(pop)
 #endif
+
+#if defined(__clang__)
+#  pragma clang diagnostic pop
+#endif
 // end catch_reporter_console.cpp
 // start catch_reporter_junit.cpp
 
@@ -14051,22 +16303,6 @@ namespace Catch {
     void JunitReporter::testRunStarting( TestRunInfo const& runInfo )  {
         CumulativeReporterBase::testRunStarting( runInfo );
         xml.startElement( "testsuites" );
-
-        if ( m_config->hasTestFilters() || m_config->rngSeed() != 0 )
-            xml.startElement("properties");
-
-        if ( m_config->hasTestFilters() ) {
-            xml.scopedElement( "property" )
-                .writeAttribute( "name" , "filters" )
-                .writeAttribute( "value" , serializeFilters( m_config->getTestsOrTags() ) );
-        }
-
-        if( m_config->rngSeed() != 0 ) {
-            xml.scopedElement( "property" )
-                .writeAttribute( "name", "random-seed" )
-                .writeAttribute( "value", m_config->rngSeed() );
-            xml.endElement();
-        }
     }
 
     void JunitReporter::testGroupStarting( GroupInfo const& groupInfo ) {
@@ -14105,6 +16341,7 @@ namespace Catch {
 
     void JunitReporter::writeGroup( TestGroupNode const& groupNode, double suiteTime ) {
         XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" );
+
         TestGroupStats const& stats = groupNode.value;
         xml.writeAttribute( "name", stats.groupInfo.name );
         xml.writeAttribute( "errors", unexpectedExceptions );
@@ -14117,6 +16354,21 @@ namespace Catch {
             xml.writeAttribute( "time", suiteTime );
         xml.writeAttribute( "timestamp", getCurrentTimestamp() );
 
+        // Write properties if there are any
+        if (m_config->hasTestFilters() || m_config->rngSeed() != 0) {
+            auto properties = xml.scopedElement("properties");
+            if (m_config->hasTestFilters()) {
+                xml.scopedElement("property")
+                    .writeAttribute("name", "filters")
+                    .writeAttribute("value", serializeFilters(m_config->getTestsOrTags()));
+            }
+            if (m_config->rngSeed() != 0) {
+                xml.scopedElement("property")
+                    .writeAttribute("name", "random-seed")
+                    .writeAttribute("value", m_config->rngSeed());
+            }
+        }
+
         // Write test cases
         for( auto const& child : groupNode.children )
             writeTestCase( *child );
@@ -14274,19 +16526,34 @@ namespace Catch {
         m_reporter->noMatchingTestCases( spec );
     }
 
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+    void ListeningReporter::benchmarkPreparing( std::string const& name ) {
+		for (auto const& listener : m_listeners) {
+			listener->benchmarkPreparing(name);
+		}
+		m_reporter->benchmarkPreparing(name);
+	}
     void ListeningReporter::benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) {
         for ( auto const& listener : m_listeners ) {
             listener->benchmarkStarting( benchmarkInfo );
         }
         m_reporter->benchmarkStarting( benchmarkInfo );
     }
-    void ListeningReporter::benchmarkEnded( BenchmarkStats const& benchmarkStats ) {
+    void ListeningReporter::benchmarkEnded( BenchmarkStats<> const& benchmarkStats ) {
         for ( auto const& listener : m_listeners ) {
             listener->benchmarkEnded( benchmarkStats );
         }
         m_reporter->benchmarkEnded( benchmarkStats );
     }
 
+	void ListeningReporter::benchmarkFailed( std::string const& error ) {
+		for (auto const& listener : m_listeners) {
+			listener->benchmarkFailed(error);
+		}
+		m_reporter->benchmarkFailed(error);
+	}
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
+
     void ListeningReporter::testRunStarting( TestRunInfo const& testRunInfo ) {
         for ( auto const& listener : m_listeners ) {
             listener->testRunStarting( testRunInfo );
@@ -14580,6 +16847,51 @@ namespace Catch {
         m_xml.endElement();
     }
 
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+    void XmlReporter::benchmarkPreparing(std::string const& name) {
+        m_xml.startElement("BenchmarkResults")
+            .writeAttribute("name", name);
+    }
+
+    void XmlReporter::benchmarkStarting(BenchmarkInfo const &info) {
+        m_xml.writeAttribute("samples", info.samples)
+            .writeAttribute("resamples", info.resamples)
+            .writeAttribute("iterations", info.iterations)
+            .writeAttribute("clockResolution", static_cast<uint64_t>(info.clockResolution))
+            .writeAttribute("estimatedDuration", static_cast<uint64_t>(info.estimatedDuration))
+            .writeComment("All values in nano seconds");
+    }
+
+    void XmlReporter::benchmarkEnded(BenchmarkStats<> const& benchmarkStats) {
+        m_xml.startElement("mean")
+            .writeAttribute("value", static_cast<uint64_t>(benchmarkStats.mean.point.count()))
+            .writeAttribute("lowerBound", static_cast<uint64_t>(benchmarkStats.mean.lower_bound.count()))
+            .writeAttribute("upperBound", static_cast<uint64_t>(benchmarkStats.mean.upper_bound.count()))
+            .writeAttribute("ci", benchmarkStats.mean.confidence_interval);
+        m_xml.endElement();
+        m_xml.startElement("standardDeviation")
+            .writeAttribute("value", benchmarkStats.standardDeviation.point.count())
+            .writeAttribute("lowerBound", benchmarkStats.standardDeviation.lower_bound.count())
+            .writeAttribute("upperBound", benchmarkStats.standardDeviation.upper_bound.count())
+            .writeAttribute("ci", benchmarkStats.standardDeviation.confidence_interval);
+        m_xml.endElement();
+        m_xml.startElement("outliers")
+            .writeAttribute("variance", benchmarkStats.outlierVariance)
+            .writeAttribute("lowMild", benchmarkStats.outliers.low_mild)
+            .writeAttribute("lowSevere", benchmarkStats.outliers.low_severe)
+            .writeAttribute("highMild", benchmarkStats.outliers.high_mild)
+            .writeAttribute("highSevere", benchmarkStats.outliers.high_severe);
+        m_xml.endElement();
+        m_xml.endElement();
+    }
+
+    void XmlReporter::benchmarkFailed(std::string const &error) {
+        m_xml.scopedElement("failed").
+            writeAttribute("message", error);
+        m_xml.endElement();
+    }
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
+
     CATCH_REGISTER_REPORTER( "xml", XmlReporter )
 
 } // end namespace Catch
@@ -14682,6 +16994,7 @@ int main (int argc, char * const argv[]) {
 #endif // CATCH_CONFIG_DISABLE_MATCHERS
 
 #define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg )
+#define CATCH_UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( "CATCH_UNSCOPED_INFO", msg )
 #define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( "CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
 #define CATCH_CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CATCH_CAPTURE",__VA_ARGS__ )
 
@@ -14699,14 +17012,22 @@ int main (int argc, char * const argv[]) {
 
 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
 #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
+#define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ )
 #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
+#define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ )
+#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ )
 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ )
+#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
 #else
 #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) )
+#define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ ) )
 #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
+#define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) )
+#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ ) )
 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
+#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
 #endif
 
 #if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
@@ -14727,6 +17048,13 @@ int main (int argc, char * const argv[]) {
 #define CATCH_THEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     Then: " << desc )
 #define CATCH_AND_THEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( "      And: " << desc )
 
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+#define CATCH_BENCHMARK(...) \
+    INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,))
+#define CATCH_BENCHMARK_ADVANCED(name) \
+    INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), name)
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
+
 // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
 #else
 
@@ -14779,14 +17107,26 @@ int main (int argc, char * const argv[]) {
 
 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
 #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
+#define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ )
 #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
+#define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
 #define TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ )
+#define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ )
 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ )
+#define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
+#define TEMPLATE_LIST_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(__VA_ARGS__)
+#define TEMPLATE_LIST_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, __VA_ARGS__ )
 #else
 #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) )
+#define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ ) )
 #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
+#define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
 #define TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) )
+#define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ ) )
 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
+#define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
+#define TEMPLATE_LIST_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE( __VA_ARGS__ ) )
+#define TEMPLATE_LIST_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
 #endif
 
 #if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
@@ -14812,6 +17152,13 @@ int main (int argc, char * const argv[]) {
 #define THEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     Then: " << desc )
 #define AND_THEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( "      And: " << desc )
 
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+#define BENCHMARK(...) \
+    INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,))
+#define BENCHMARK_ADVANCED(name) \
+    INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), name)
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
+
 using Catch::Detail::Approx;
 
 #else // CATCH_CONFIG_DISABLE
@@ -14851,9 +17198,10 @@ using Catch::Detail::Approx;
 #define CATCH_REQUIRE_THAT( arg, matcher ) (void)(0)
 #endif // CATCH_CONFIG_DISABLE_MATCHERS
 
-#define CATCH_INFO( msg )    (void)(0)
-#define CATCH_WARN( msg )    (void)(0)
-#define CATCH_CAPTURE( msg ) (void)(0)
+#define CATCH_INFO( msg )          (void)(0)
+#define CATCH_UNSCOPED_INFO( msg ) (void)(0)
+#define CATCH_WARN( msg )          (void)(0)
+#define CATCH_CAPTURE( msg )       (void)(0)
 
 #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
 #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
@@ -14868,15 +17216,23 @@ using Catch::Detail::Approx;
 #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
 
 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
-#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) )
-#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), className )
+#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__)
+#define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__)
+#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__)
+#define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ )
 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
+#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
+#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
 #else
-#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) ) )
-#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), className ) )
+#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) )
+#define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__) )
+#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__ ) )
+#define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ ) )
 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
+#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
+#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
 #endif
 
 // "BDD-style" convenience wrappers
@@ -14927,6 +17283,7 @@ using Catch::Detail::Approx;
 #endif // CATCH_CONFIG_DISABLE_MATCHERS
 
 #define INFO( msg ) (void)(0)
+#define UNSCOPED_INFO( msg ) (void)(0)
 #define WARN( msg ) (void)(0)
 #define CAPTURE( msg ) (void)(0)
 
@@ -14942,15 +17299,23 @@ using Catch::Detail::Approx;
 #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
 
 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
-#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) )
-#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), className )
+#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__)
+#define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__)
+#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__)
+#define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ )
 #define TEMPLATE_PRODUCT_TEST_CASE( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
+#define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
+#define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
 #else
-#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) ) )
-#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), className ) )
+#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) )
+#define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__) )
+#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__ ) )
+#define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ ) )
 #define TEMPLATE_PRODUCT_TEST_CASE( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
+#define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
+#define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
 #endif
 
 #define STATIC_REQUIRE( ... )       (void)(0)
diff --git a/packages/Catch2/single_include/catch2/catch_reporter_teamcity.hpp b/packages/Catch2/single_include/catch2/catch_reporter_teamcity.hpp
index eca2885cd..47b7e4aac 100644
--- a/packages/Catch2/single_include/catch2/catch_reporter_teamcity.hpp
+++ b/packages/Catch2/single_include/catch2/catch_reporter_teamcity.hpp
@@ -183,8 +183,7 @@ namespace Catch {
 
             SourceLineInfo lineInfo = m_sectionStack.front().lineInfo;
 
-            if( !lineInfo.empty() )
-                os << lineInfo << "\n";
+            os << lineInfo << "\n";
             os << getLineOfChars<'.'>() << "\n\n";
         }
 
-- 
GitLab