diff --git a/randomx.sln b/randomx.sln
index f50aa70..ddf3010 100644
--- a/randomx.sln
+++ b/randomx.sln
@@ -13,6 +13,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "superscalar-init", "vcxproj
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "superscalar-stats", "vcxproj\superscalar-stats.vcxproj", "{0173D560-8C12-46B3-B467-0C6E7573AA0B}"
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "benchmark", "vcxproj\benchmark.vcxproj", "{1E8A2E2F-9F9F-43AA-BB19-9107FEC64A70}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "api-example1", "vcxproj\api-example1.vcxproj", "{83EA3E54-5D91-4E01-8EF6-C1E718334F83}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "api-example2", "vcxproj\api-example2.vcxproj", "{44947B9C-E6B1-4C06-BD01-F8EF43B59223}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "code-generator", "vcxproj\code-generator.vcxproj", "{3E490DEC-1874-43AA-92DA-1AC57C217EAC}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
@@ -53,6 +61,38 @@ Global
{0173D560-8C12-46B3-B467-0C6E7573AA0B}.Release|x64.Build.0 = Release|x64
{0173D560-8C12-46B3-B467-0C6E7573AA0B}.Release|x86.ActiveCfg = Release|Win32
{0173D560-8C12-46B3-B467-0C6E7573AA0B}.Release|x86.Build.0 = Release|Win32
+ {1E8A2E2F-9F9F-43AA-BB19-9107FEC64A70}.Debug|x64.ActiveCfg = Debug|x64
+ {1E8A2E2F-9F9F-43AA-BB19-9107FEC64A70}.Debug|x64.Build.0 = Debug|x64
+ {1E8A2E2F-9F9F-43AA-BB19-9107FEC64A70}.Debug|x86.ActiveCfg = Debug|Win32
+ {1E8A2E2F-9F9F-43AA-BB19-9107FEC64A70}.Debug|x86.Build.0 = Debug|Win32
+ {1E8A2E2F-9F9F-43AA-BB19-9107FEC64A70}.Release|x64.ActiveCfg = Release|x64
+ {1E8A2E2F-9F9F-43AA-BB19-9107FEC64A70}.Release|x64.Build.0 = Release|x64
+ {1E8A2E2F-9F9F-43AA-BB19-9107FEC64A70}.Release|x86.ActiveCfg = Release|Win32
+ {1E8A2E2F-9F9F-43AA-BB19-9107FEC64A70}.Release|x86.Build.0 = Release|Win32
+ {83EA3E54-5D91-4E01-8EF6-C1E718334F83}.Debug|x64.ActiveCfg = Debug|x64
+ {83EA3E54-5D91-4E01-8EF6-C1E718334F83}.Debug|x64.Build.0 = Debug|x64
+ {83EA3E54-5D91-4E01-8EF6-C1E718334F83}.Debug|x86.ActiveCfg = Debug|Win32
+ {83EA3E54-5D91-4E01-8EF6-C1E718334F83}.Debug|x86.Build.0 = Debug|Win32
+ {83EA3E54-5D91-4E01-8EF6-C1E718334F83}.Release|x64.ActiveCfg = Release|x64
+ {83EA3E54-5D91-4E01-8EF6-C1E718334F83}.Release|x64.Build.0 = Release|x64
+ {83EA3E54-5D91-4E01-8EF6-C1E718334F83}.Release|x86.ActiveCfg = Release|Win32
+ {83EA3E54-5D91-4E01-8EF6-C1E718334F83}.Release|x86.Build.0 = Release|Win32
+ {44947B9C-E6B1-4C06-BD01-F8EF43B59223}.Debug|x64.ActiveCfg = Debug|x64
+ {44947B9C-E6B1-4C06-BD01-F8EF43B59223}.Debug|x64.Build.0 = Debug|x64
+ {44947B9C-E6B1-4C06-BD01-F8EF43B59223}.Debug|x86.ActiveCfg = Debug|Win32
+ {44947B9C-E6B1-4C06-BD01-F8EF43B59223}.Debug|x86.Build.0 = Debug|Win32
+ {44947B9C-E6B1-4C06-BD01-F8EF43B59223}.Release|x64.ActiveCfg = Release|x64
+ {44947B9C-E6B1-4C06-BD01-F8EF43B59223}.Release|x64.Build.0 = Release|x64
+ {44947B9C-E6B1-4C06-BD01-F8EF43B59223}.Release|x86.ActiveCfg = Release|Win32
+ {44947B9C-E6B1-4C06-BD01-F8EF43B59223}.Release|x86.Build.0 = Release|Win32
+ {3E490DEC-1874-43AA-92DA-1AC57C217EAC}.Debug|x64.ActiveCfg = Debug|x64
+ {3E490DEC-1874-43AA-92DA-1AC57C217EAC}.Debug|x64.Build.0 = Debug|x64
+ {3E490DEC-1874-43AA-92DA-1AC57C217EAC}.Debug|x86.ActiveCfg = Debug|Win32
+ {3E490DEC-1874-43AA-92DA-1AC57C217EAC}.Debug|x86.Build.0 = Debug|Win32
+ {3E490DEC-1874-43AA-92DA-1AC57C217EAC}.Release|x64.ActiveCfg = Release|x64
+ {3E490DEC-1874-43AA-92DA-1AC57C217EAC}.Release|x64.Build.0 = Release|x64
+ {3E490DEC-1874-43AA-92DA-1AC57C217EAC}.Release|x86.ActiveCfg = Release|Win32
+ {3E490DEC-1874-43AA-92DA-1AC57C217EAC}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -61,6 +101,10 @@ Global
{CF34A7EF-7DC9-4077-94A5-76F5425EA938} = {4A4A689F-86AF-41C0-A974-1080506D0923}
{E59DC709-9B12-4A53-BAF3-79398821C376} = {4A4A689F-86AF-41C0-A974-1080506D0923}
{0173D560-8C12-46B3-B467-0C6E7573AA0B} = {4A4A689F-86AF-41C0-A974-1080506D0923}
+ {1E8A2E2F-9F9F-43AA-BB19-9107FEC64A70} = {4A4A689F-86AF-41C0-A974-1080506D0923}
+ {83EA3E54-5D91-4E01-8EF6-C1E718334F83} = {4A4A689F-86AF-41C0-A974-1080506D0923}
+ {44947B9C-E6B1-4C06-BD01-F8EF43B59223} = {4A4A689F-86AF-41C0-A974-1080506D0923}
+ {3E490DEC-1874-43AA-92DA-1AC57C217EAC} = {4A4A689F-86AF-41C0-A974-1080506D0923}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {4EBC03DB-AE37-4141-8147-692F16E0ED02}
diff --git a/src/TestAluFpu.cpp b/src/TestAluFpu.cpp
deleted file mode 100644
index de90083..0000000
--- a/src/TestAluFpu.cpp
+++ /dev/null
@@ -1,401 +0,0 @@
-/*
-Copyright (c) 2018 tevador
-
-This file is part of RandomX.
-
-RandomX is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-RandomX is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with RandomX. If not, see.
-*/
-
-#include
-#include
-#include
-#include "instructions.hpp"
-//#define DEBUG
-
-using namespace RandomX;
-
-typedef void(*FpuOperation)(convertible_t&, fpu_reg_t&, fpu_reg_t&);
-
-#define CATCH_CONFIG_MAIN
-#include "catch.hpp"
-
-uint64_t rxRound(uint32_t mode, int64_t x, int64_t y, FpuOperation op, bool hiEqualsLo = true) {
- convertible_t a;
- fpu_reg_t b, c;
- a.u64 = mode;
- FPROUND(a, b, c);
- if (hiEqualsLo) {
- a.i32lo = x;
- a.i32hi = x;
- }
- else {
- a.i64 = x;
- }
- b.lo.i64 = y;
- b.hi.i64 = y;
- op(a, b, c);
- if (hiEqualsLo) {
- CHECK(c.lo.u64 == c.hi.u64);
- }
- return c.lo.u64;
-}
-
-#define RX_EXECUTE_U64(va, vb, INST) do { \
- a.u64 = va; \
- b.u64 = vb; \
- INST(a, b, c); \
- } while(false)
-
-#define RX_EXECUTE_I64(va, vb, INST) do { \
- a.i64 = va; \
- b.i64 = vb; \
- INST(a, b, c); \
- } while(false)
-
-TEST_CASE("Integer addition (64-bit)", "[ADD_64]") {
- convertible_t a, b, c;
-
- RX_EXECUTE_U64(0xFFFFFFFF, 0x1, ADD_64);
- CHECK(c.u64 == 0x100000000);
-
- RX_EXECUTE_U64(0x8000000000000000, 0x8000000000000000, ADD_64);
- CHECK(c.u64 == 0x0);
-}
-
-TEST_CASE("Integer addition (32-bit)", "[ADD_32]") {
- convertible_t a, b, c;
-
- RX_EXECUTE_U64(0xFFFFFFFF, 0x1, ADD_32);
- CHECK(c.u64 == 0);
-
- RX_EXECUTE_U64(0xFF00000000000001, 0x0000000100000001, ADD_32);
- CHECK(c.u64 == 2);
-}
-
-TEST_CASE("Integer subtraction (64-bit)", "[SUB_64]") {
- convertible_t a, b, c;
-
- RX_EXECUTE_U64(1, 0xFFFFFFFF, SUB_64);
- CHECK(c.u64 == 0xFFFFFFFF00000002);
-}
-
-TEST_CASE("Integer subtraction (32-bit)", "[SUB_32]") {
- convertible_t a, b, c;
-
- RX_EXECUTE_U64(1, 0xFFFFFFFF, SUB_32);
- CHECK(c.u64 == 2);
-}
-
-TEST_CASE("Unsigned multiplication (64-bit, low half)", "[MUL_64]") {
- convertible_t a, b, c;
-
- RX_EXECUTE_U64(0xBC550E96BA88A72B, 0xF5391FA9F18D6273, MUL_64);
- CHECK(c.u64 == 0x28723424A9108E51);
-}
-
-TEST_CASE("Unsigned multiplication (64-bit, high half)", "[MULH_64]") {
- convertible_t a, b, c;
-
- RX_EXECUTE_U64(0xBC550E96BA88A72B, 0xF5391FA9F18D6273, MULH_64);
- CHECK(c.u64 == 0xB4676D31D2B34883);
-}
-
-TEST_CASE("Unsigned multiplication (32-bit x 32-bit -> 64-bit)", "[MUL_32]") {
- convertible_t a, b, c;
-
- RX_EXECUTE_U64(0xBC550E96BA88A72B, 0xF5391FA9F18D6273, MUL_32);
- CHECK(c.u64 == 0xB001AA5FA9108E51);
-}
-
-TEST_CASE("Signed multiplication (32-bit x 32-bit -> 64-bit)", "[IMUL_32]") {
- convertible_t a, b, c;
-
- RX_EXECUTE_U64(0xBC550E96BA88A72B, 0xF5391FA9F18D6273, IMUL_32);
- CHECK(c.u64 == 0x03EBA0C1A9108E51);
-}
-
-TEST_CASE("Signed multiplication (64-bit, high half)", "[IMULH_64]") {
- convertible_t a, b, c;
-
- RX_EXECUTE_U64(0xBC550E96BA88A72B, 0xF5391FA9F18D6273, IMULH_64);
- CHECK(c.u64 == 0x02D93EF1269D3EE5);
-}
-
-TEST_CASE("Unsigned division (64-bit / 32-bit -> 32-bit)", "[DIV_64]") {
- convertible_t a, b, c;
-
- RX_EXECUTE_U64(8774217225983458895, 3014068202, DIV_64);
- CHECK(c.u64 == 2911087818);
-
- RX_EXECUTE_U64(8774217225983458895, 0, DIV_64);
- CHECK(c.u64 == 8774217225983458895);
-
- RX_EXECUTE_U64(3014068202, 8774217225983458895, DIV_64);
- CHECK(c.u64 == 2);
-}
-
-TEST_CASE("Signed division (64-bit / 32-bit -> 32-bit)", "[IDIV_64]") {
- convertible_t a, b, c;
-
- RX_EXECUTE_U64(8774217225983458895, 3014068202, IDIV_64);
- CHECK(c.u64 == 0xFFFFFFFE67B4994E);
-
- RX_EXECUTE_U64(5, 0xFFFFFFFFFFFFFFFF, IDIV_64);
- CHECK(c.u64 == 0xFFFFFFFFFFFFFFFB);
-
- RX_EXECUTE_U64(8774217225983458895, 0, IDIV_64);
- CHECK(c.u64 == 8774217225983458895);
-
- RX_EXECUTE_U64(0x8000000000000000, 0xFFFFFFFFFFFFFFFF, IDIV_64);
- CHECK(c.u64 == 0x8000000000000000);
-
- RX_EXECUTE_U64(0x8000000000000000, 0x93D1FFFFFFFFFFFF, IDIV_64);
- CHECK(c.u64 == 0x8000000000000000);
-
- RX_EXECUTE_U64(0xFFFFFFFFB3A707EA, 8774217225983458895, IDIV_64);
- CHECK(c.u64 == 0xFFFFFFFFFFFFFFFF);
-}
-
-TEST_CASE("Bitwise AND (64-bit)", "[AND_64]") {
- convertible_t a, b, c;
-
- RX_EXECUTE_U64(0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA, AND_64);
- CHECK(c.u64 == 0x8888888888888888);
-}
-
-TEST_CASE("Bitwise AND (32-bit)", "[AND_32]") {
- convertible_t a, b, c;
-
- RX_EXECUTE_U64(0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA, AND_32);
- CHECK(c.u64 == 0x88888888);
-}
-
-TEST_CASE("Bitwise OR (64-bit)", "[OR_64]") {
- convertible_t a, b, c;
-
- RX_EXECUTE_U64(0x4444444444444444, 0xAAAAAAAAAAAAAAAA, OR_64);
- CHECK(c.u64 == 0xEEEEEEEEEEEEEEEE);
-}
-
-TEST_CASE("Bitwise OR (32-bit)", "[OR_32]") {
- convertible_t a, b, c;
-
- RX_EXECUTE_U64(0x4444444444444444, 0xAAAAAAAAAAAAAAAA, OR_32);
- CHECK(c.u64 == 0xEEEEEEEE);
-}
-
-TEST_CASE("Bitwise XOR (64-bit)", "[XOR_64]") {
- convertible_t a, b, c;
-
- RX_EXECUTE_U64(0x8888888888888888, 0xAAAAAAAAAAAAAAAA, XOR_64);
- CHECK(c.u64 == 0x2222222222222222);
-}
-
-TEST_CASE("Bitwise XOR (32-bit)", "[XOR_32]") {
- convertible_t a, b, c;
-
- RX_EXECUTE_U64(0x8888888888888888, 0xAAAAAAAAAAAAAAAA, XOR_32);
- CHECK(c.u64 == 0x22222222);
-}
-
-TEST_CASE("Logical left shift (64-bit)", "[SHL_64]") {
- convertible_t a, b, c;
-
- RX_EXECUTE_U64(0x3, 52, SHL_64);
- CHECK(c.u64 == 0x30000000000000);
-
- RX_EXECUTE_U64(953360005391419562, 4569451684712230561, SHL_64);
- CHECK(c.u64 == 6978065200108797952);
-
- RX_EXECUTE_U64(0x8000000000000000, 1, SHL_64);
- CHECK(c.u64 == 0);
-}
-
-TEST_CASE("Logical right shift (64-bit)", "[SHR_64]") {
- convertible_t a, b, c;
-
- RX_EXECUTE_U64(0x3, 52, SHR_64);
- CHECK(c.u64 == 0);
-
- RX_EXECUTE_U64(953360005391419562, 4569451684712230561, SHR_64);
- CHECK(c.u64 == 110985711);
-
- RX_EXECUTE_U64(0x8000000000000000, 1, SHR_64);
- CHECK(c.u64 == 0x4000000000000000);
-}
-
-TEST_CASE("Arithmetic right shift (64-bit)", "[SAR_64]") {
- convertible_t a, b, c;
-
- RX_EXECUTE_I64(-9, 2, SAR_64);
- CHECK(c.i64 == -3);
-
- RX_EXECUTE_I64(INT64_MIN, 63, SAR_64);
- CHECK(c.i64 == -1);
-
- RX_EXECUTE_I64(INT64_MAX, 163768499474606398, SAR_64);
- CHECK(c.i64 == 1);
-}
-
-TEST_CASE("Circular left shift (64-bit)", "[ROL_64]") {
- convertible_t a, b, c;
-
- RX_EXECUTE_U64(0x3, 52, ROL_64);
- CHECK(c.u64 == 0x30000000000000);
-
- RX_EXECUTE_U64(953360005391419562, 4569451684712230561, ROL_64);
- CHECK(c.u64 == 6978065200552740799);
-
- RX_EXECUTE_U64(0x8000000000000000, 1, ROL_64);
- CHECK(c.u64 == 1);
-}
-
-TEST_CASE("Circular right shift (64-bit)", "[ROR_64]") {
- convertible_t a, b, c;
-
- RX_EXECUTE_U64(0x3, 52, ROR_64);
- CHECK(c.u64 == 12288);
-
- RX_EXECUTE_U64(953360005391419562, 4569451684712230561, ROR_64);
- CHECK(c.u64 == 0xD835C455069D81EF);
-
- RX_EXECUTE_U64(0x8000000000000000, 1, ROR_64);
- CHECK(c.u64 == 0x4000000000000000);
-}
-
-TEST_CASE("Denormal results are not produced", "[FTZ]") {
- FPINIT();
- convertible_t a;
- fpu_reg_t b;
- a.i64 = 1;
- b.lo.f64 = DBL_MAX;
- FPDIV(a, b, b);
-#ifdef DEBUG
- std::cout << a.i64 << " / " << DBL_MAX << " = " << std::hex << b.lo.u64 << std::endl;
-#endif
- CHECK(std::fpclassify(b.lo.f64) != FP_SUBNORMAL);
- a.i64 = 0;
- FPSUB(a, b, b);
-#ifdef DEBUG
- std::cout << a.i64 << " - " << b.lo.f64 << " = " << std::hex << b.lo.u64 << std::endl;
-#endif
- CHECK(std::fpclassify(b.lo.f64) != FP_SUBNORMAL);
-}
-
-TEST_CASE("NaN results are not produced", "[NAN]") {
- FPINIT();
- convertible_t a;
- fpu_reg_t b;
- a.i64 = 0;
- b.lo.f64 = 0;
- FPDIV(a, b, b);
- CHECK(std::fpclassify(b.lo.f64) != FP_NAN);
- b.lo.f64 = std::numeric_limits::infinity();
- FPMUL(a, b, b);
- CHECK(std::fpclassify(b.lo.f64) != FP_NAN);
-}
-
-volatile int64_t fpRounda = 7379480244170225589;
-volatile int32_t fpAdda = -2110701072;
-volatile int64_t fpAddb = 5822431907862180274;
-volatile int32_t fpSuba = -1651770302;
-volatile int64_t fpSubb = 4982086006202596504;
-volatile int32_t fpMula1 = 122885310;
-volatile int64_t fpMulb1 = 6036690890763685020;
-volatile int32_t fpMula2 = -1952486466;
-volatile int64_t fpMulb2 = 5693689137909219638;
-volatile int32_t fpDiva1 = -1675630642;
-volatile int64_t fpDivb1 = -3959960229647489051;
-volatile int32_t fpDiva2 = -1651770302;
-volatile int64_t fpDivb2 = 4982086006202596504;
-volatile int32_t fpSqrta1 = 440505508;
-volatile int32_t fpSqrta2 = -2147483648;
-
-TEST_CASE("IEEE-754 compliance", "[FPU]") {
- FPINIT();
- convertible_t a;
- fpu_reg_t b, c;
- b.lo.f64 = 0.0;
-
- a.i64 = 1;
- FPDIV(a, b, c);
- CHECK(c.lo.f64 == std::numeric_limits::infinity());
-
- a.i64 = -1;
- FPDIV(a, b, c);
- CHECK(c.lo.f64 == -std::numeric_limits::infinity());
-
-#ifdef DEBUG
- std::cout << "FPROUND" << std::endl;
-#endif
- CHECK(rxRound(RoundToNearest, fpRounda, 0, &FPROUND, false) == 0x43d99a4b8bc531dcU);
- CHECK(rxRound(RoundDown, fpRounda, 0, &FPROUND, false) == 0x43d99a4b8bc531dcU);
- CHECK(rxRound(RoundUp, fpRounda, 0, &FPROUND, false) == 0x43d99a4b8bc531dcU);
- CHECK(rxRound(RoundToZero, fpRounda, 0, &FPROUND, false) == 0x43d99a4b8bc531dcU);
-
-#ifdef DEBUG
- std::cout << "FPADD" << std::endl;
-#endif
- CHECK(rxRound(RoundToNearest, fpAdda, fpAddb, &FPADD) == 0x50cd6ef8bd0671b2U);
- CHECK(rxRound(RoundDown, fpAdda, fpAddb, &FPADD) == 0x50cd6ef8bd0671b1U);
- CHECK(rxRound(RoundUp, fpAdda, fpAddb, &FPADD) == 0x50cd6ef8bd0671b2U);
- CHECK(rxRound(RoundToZero, fpAdda, fpAddb, &FPADD) == 0x50cd6ef8bd0671b1U);
-
-#ifdef DEBUG
- std::cout << "FPSUB" << std::endl;
-#endif
- CHECK(rxRound(RoundToNearest, fpSuba, fpSubb, &FPSUB) == 0xc523ecd390267c99U);
- CHECK(rxRound(RoundDown, fpSuba, fpSubb, &FPSUB) == 0xc523ecd390267c99U);
- CHECK(rxRound(RoundUp, fpSuba, fpSubb, &FPSUB) == 0xc523ecd390267c98U);
- CHECK(rxRound(RoundToZero, fpSuba, fpSubb, &FPSUB) == 0xc523ecd390267c98U);
-
-#ifdef DEBUG
- std::cout << "FPMUL" << std::endl;
-#endif
- CHECK(rxRound(RoundToNearest, fpMula1, fpMulb1, &FPMUL) == 0x5574b924d2f24542U);
- CHECK(rxRound(RoundDown, fpMula1, fpMulb1, &FPMUL) == 0x5574b924d2f24541U);
- CHECK(rxRound(RoundUp, fpMula1, fpMulb1, &FPMUL) == 0x5574b924d2f24542U);
- CHECK(rxRound(RoundToZero, fpMula1, fpMulb1, &FPMUL) == 0x5574b924d2f24541U);
-
- CHECK(rxRound(RoundToNearest, fpMula2, fpMulb2, &FPMUL) == 0xd0f23a18891a7470U);
- CHECK(rxRound(RoundDown, fpMula2, fpMulb2, &FPMUL) == 0xd0f23a18891a7470U);
- CHECK(rxRound(RoundUp, fpMula2, fpMulb2, &FPMUL) == 0xd0f23a18891a746fU);
- CHECK(rxRound(RoundToZero, fpMula2, fpMulb2, &FPMUL) == 0xd0f23a18891a746fU);
-
-#ifdef DEBUG
- std::cout << "FPDIV" << std::endl;
-#endif
- CHECK(rxRound(RoundToNearest, fpDiva1, fpDivb1, &FPDIV) == 0x38bd2a7732b5eb0aU);
- CHECK(rxRound(RoundDown, fpDiva1, fpDivb1, &FPDIV) == 0x38bd2a7732b5eb09U);
- CHECK(rxRound(RoundUp, fpDiva1, fpDivb1, &FPDIV) == 0x38bd2a7732b5eb0aU);
- CHECK(rxRound(RoundToZero, fpDiva1, fpDivb1, &FPDIV) == 0x38bd2a7732b5eb09U);
-
- CHECK(rxRound(RoundToNearest, fpDiva2, fpDivb2, &FPDIV) == 0xbca3c3c039ccc71cU);
- CHECK(rxRound(RoundDown, fpDiva2, fpDivb2, &FPDIV) == 0xbca3c3c039ccc71cU);
- CHECK(rxRound(RoundUp, fpDiva2, fpDivb2, &FPDIV) == 0xbca3c3c039ccc71bU);
- CHECK(rxRound(RoundToZero, fpDiva2, fpDivb2, &FPDIV) == 0xbca3c3c039ccc71bU);
-
-#ifdef DEBUG
- std::cout << "FPSQRT" << std::endl;
-#endif
- CHECK(rxRound(RoundToNearest, fpSqrta1, 0, &FPSQRT) == 0x40d47f0e46ebc19dU);
- CHECK(rxRound(RoundDown, fpSqrta1, 0, &FPSQRT) == 0x40d47f0e46ebc19cU);
- CHECK(rxRound(RoundUp, fpSqrta1, 0, &FPSQRT) == 0x40d47f0e46ebc19dU);
- CHECK(rxRound(RoundToZero, fpSqrta1, 0, &FPSQRT) == 0x40d47f0e46ebc19cU);
-
- CHECK(rxRound(RoundToNearest, fpSqrta2, 0, &FPSQRT) == 0x40e6a09e667f3bcdU);
- CHECK(rxRound(RoundDown, fpSqrta2, 0, &FPSQRT) == 0x40e6a09e667f3bccU);
- CHECK(rxRound(RoundUp, fpSqrta2, 0, &FPSQRT) == 0x40e6a09e667f3bcdU);
- CHECK(rxRound(RoundToZero, fpSqrta2, 0, &FPSQRT) == 0x40e6a09e667f3bccU);
-}
diff --git a/src/catch.hpp b/src/catch.hpp
deleted file mode 100644
index b324e56..0000000
--- a/src/catch.hpp
+++ /dev/null
@@ -1,14075 +0,0 @@
-/*
- * Catch v2.4.2
- * Generated: 2018-10-26 21:12:29.223927
- * ----------------------------------------------------------
- * This file has been merged from multiple headers. Please don't edit it directly
- * Copyright (c) 2018 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_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
-#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
-// start catch.hpp
-
-
-#define CATCH_VERSION_MAJOR 2
-#define CATCH_VERSION_MINOR 4
-#define CATCH_VERSION_PATCH 2
-
-#ifdef __clang__
-# pragma clang system_header
-#elif defined __GNUC__
-# pragma GCC system_header
-#endif
-
-// start catch_suppress_warnings.h
-
-#ifdef __clang__
-# ifdef __ICC // icpc defines the __clang__ macro
-# pragma warning(push)
-# pragma warning(disable: 161 1682)
-# else // __ICC
-# pragma clang diagnostic push
-# pragma clang diagnostic ignored "-Wpadded"
-# pragma clang diagnostic ignored "-Wswitch-enum"
-# pragma clang diagnostic ignored "-Wcovered-switch-default"
-# endif
-#elif defined __GNUC__
- // GCC likes to warn on REQUIREs, and we cannot suppress them
- // locally because g++'s support for _Pragma is lacking in older,
- // still supported, versions
-# pragma GCC diagnostic ignored "-Wparentheses"
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wunused-variable"
-# pragma GCC diagnostic ignored "-Wpadded"
-#endif
-// end catch_suppress_warnings.h
-#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)
-# define CATCH_IMPL
-# define CATCH_CONFIG_ALL_PARTS
-#endif
-
-// In the impl file, we want to have access to all parts of the headers
-// Can also be used to sanely support PCHs
-#if defined(CATCH_CONFIG_ALL_PARTS)
-# define CATCH_CONFIG_EXTERNAL_INTERFACES
-# if defined(CATCH_CONFIG_DISABLE_MATCHERS)
-# undef CATCH_CONFIG_DISABLE_MATCHERS
-# endif
-# if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
-# define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
-# endif
-#endif
-
-#if !defined(CATCH_CONFIG_IMPL_ONLY)
-// start catch_platform.h
-
-#ifdef __APPLE__
-# include
-# if TARGET_OS_OSX == 1
-# define CATCH_PLATFORM_MAC
-# elif TARGET_OS_IPHONE == 1
-# define CATCH_PLATFORM_IPHONE
-# endif
-
-#elif defined(linux) || defined(__linux) || defined(__linux__)
-# define CATCH_PLATFORM_LINUX
-
-#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__)
-# define CATCH_PLATFORM_WINDOWS
-#endif
-
-// end catch_platform.h
-
-#ifdef CATCH_IMPL
-# ifndef CLARA_CONFIG_MAIN
-# define CLARA_CONFIG_MAIN_NOT_DEFINED
-# define CLARA_CONFIG_MAIN
-# endif
-#endif
-
-// start catch_user_interfaces.h
-
-namespace Catch {
- unsigned int rngSeed();
-}
-
-// end catch_user_interfaces.h
-// start catch_tag_alias_autoregistrar.h
-
-// start catch_common.h
-
-// start catch_compiler_capabilities.h
-
-// Detect a number of compiler features - by compiler
-// The following features are defined:
-//
-// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?
-// CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported?
-// CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported?
-// CATCH_CONFIG_DISABLE_EXCEPTIONS : Are exceptions enabled?
-// ****************
-// Note to maintainers: if new toggles are added please document them
-// in configuration.md, too
-// ****************
-
-// In general each macro has a _NO_ form
-// (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature.
-// Many features, at point of detection, define an _INTERNAL_ macro, so they
-// can be combined, en-mass, with the _NO_ forms later.
-
-#ifdef __cplusplus
-
-# if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
-# define CATCH_CPP14_OR_GREATER
-# endif
-
-# if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
-# define CATCH_CPP17_OR_GREATER
-# endif
-
-#endif
-
-#if defined(CATCH_CPP17_OR_GREATER)
-# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
-#endif
-
-#ifdef __clang__
-
-# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
- _Pragma( "clang diagnostic push" ) \
- _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \
- _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"")
-# define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
- _Pragma( "clang diagnostic pop" )
-
-# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
- _Pragma( "clang diagnostic push" ) \
- _Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
-# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
- _Pragma( "clang diagnostic pop" )
-
-# define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
- _Pragma( "clang diagnostic push" ) \
- _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" )
-# define CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS \
- _Pragma( "clang diagnostic pop" )
-
-#endif // __clang__
-
-////////////////////////////////////////////////////////////////////////////////
-// Assume that non-Windows platforms support posix signals by default
-#if !defined(CATCH_PLATFORM_WINDOWS)
- #define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS
-#endif
-
-////////////////////////////////////////////////////////////////////////////////
-// We know some environments not to support full POSIX signals
-#if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__)
- #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
-#endif
-
-#ifdef __OS400__
-# define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
-# define CATCH_CONFIG_COLOUR_NONE
-#endif
-
-////////////////////////////////////////////////////////////////////////////////
-// Android somehow still does not support std::to_string
-#if defined(__ANDROID__)
-# define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
-#endif
-
-////////////////////////////////////////////////////////////////////////////////
-// Not all Windows environments support SEH properly
-#if defined(__MINGW32__)
-# define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
-#endif
-
-////////////////////////////////////////////////////////////////////////////////
-// PS4
-#if defined(__ORBIS__)
-# define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE
-#endif
-
-////////////////////////////////////////////////////////////////////////////////
-// Cygwin
-#ifdef __CYGWIN__
-
-// Required for some versions of Cygwin to declare gettimeofday
-// see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin
-# define _BSD_SOURCE
-// some versions of cygwin (most) do not support std::to_string. Use the libstd check.
-// https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html line 2812-2813
-# if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \
- && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))
-
-# define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
-
-# endif
-#endif // __CYGWIN__
-
-////////////////////////////////////////////////////////////////////////////////
-// Visual C++
-#ifdef _MSC_VER
-
-# if _MSC_VER >= 1900 // Visual Studio 2015 or newer
-# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
-# endif
-
-// Universal Windows platform does not support SEH
-// Or console colours (or console at all...)
-# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
-# define CATCH_CONFIG_COLOUR_NONE
-# else
-# define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
-# endif
-
-#endif // _MSC_VER
-
-////////////////////////////////////////////////////////////////////////////////
-// Check if we are compiled with -fno-exceptions or equivalent
-#if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND)
-# define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED
-#endif
-
-////////////////////////////////////////////////////////////////////////////////
-// DJGPP
-#ifdef __DJGPP__
-# define CATCH_INTERNAL_CONFIG_NO_WCHAR
-#endif // __DJGPP__
-
-////////////////////////////////////////////////////////////////////////////////
-
-// Use of __COUNTER__ is suppressed during code analysis in
-// CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly
-// handled by it.
-// Otherwise all supported compilers support COUNTER macro,
-// but user still might want to turn it off
-#if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L )
- #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() && defined(CATCH_CPP17_OR_GREATER)
-# define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW
-#endif
-#endif
-
-////////////////////////////////////////////////////////////////////////////////
-// Check if variant is available and usable
-#if defined(__has_include)
-# if __has_include() && 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
-# if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
-# define CATCH_CONFIG_NO_CPP17_VARIANT
-# else
-# define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
-# endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
-# endif // defined(__clang__) && (__clang_major__ < 8)
-# endif // __has_include() && defined(CATCH_CPP17_OR_GREATER)
-#endif // __has_include
-
-#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
-# define CATCH_CONFIG_COUNTER
-#endif
-#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) && !defined(CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH)
-# define CATCH_CONFIG_WINDOWS_SEH
-#endif
-// This is set by default, because we assume that unix compilers are posix-signal-compatible by default.
-#if defined(CATCH_INTERNAL_CONFIG_POSIX_SIGNALS) && !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS)
-# define CATCH_CONFIG_POSIX_SIGNALS
-#endif
-// This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions.
-#if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR)
-# define CATCH_CONFIG_WCHAR
-#endif
-
-#if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING)
-# define CATCH_CONFIG_CPP11_TO_STRING
-#endif
-
-#if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
-# define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
-#endif
-
-#if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW)
-# define CATCH_CONFIG_CPP17_STRING_VIEW
-#endif
-
-#if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT)
-# define CATCH_CONFIG_CPP17_VARIANT
-#endif
-
-#if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
-# define CATCH_INTERNAL_CONFIG_NEW_CAPTURE
-#endif
-
-#if defined(CATCH_INTERNAL_CONFIG_NEW_CAPTURE) && !defined(CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NEW_CAPTURE)
-# define CATCH_CONFIG_NEW_CAPTURE
-#endif
-
-#if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
-# define CATCH_CONFIG_DISABLE_EXCEPTIONS
-#endif
-
-#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
-# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
-# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS
-#endif
-#if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS)
-# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
-# define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
-#endif
-#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS)
-# define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS
-# define CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS
-#endif
-
-#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
-#define CATCH_TRY if ((true))
-#define CATCH_CATCH_ALL if ((false))
-#define CATCH_CATCH_ANON(type) if ((false))
-#else
-#define CATCH_TRY try
-#define CATCH_CATCH_ALL catch (...)
-#define CATCH_CATCH_ANON(type) catch (type)
-#endif
-
-// end catch_compiler_capabilities.h
-#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
-#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
-#ifdef CATCH_CONFIG_COUNTER
-# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ )
-#else
-# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
-#endif
-
-#include
-#include
-#include
-
-// We need a dummy global operator<< so we can bring it into Catch namespace later
-struct Catch_global_namespace_dummy {};
-std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy);
-
-namespace Catch {
-
- struct CaseSensitive { enum Choice {
- Yes,
- No
- }; };
-
- class NonCopyable {
- NonCopyable( NonCopyable const& ) = delete;
- NonCopyable( NonCopyable && ) = delete;
- NonCopyable& operator = ( NonCopyable const& ) = delete;
- NonCopyable& operator = ( NonCopyable && ) = delete;
-
- protected:
- NonCopyable();
- virtual ~NonCopyable();
- };
-
- struct SourceLineInfo {
-
- SourceLineInfo() = delete;
- SourceLineInfo( char const* _file, std::size_t _line ) noexcept
- : file( _file ),
- line( _line )
- {}
-
- SourceLineInfo( SourceLineInfo const& other ) = default;
- SourceLineInfo( SourceLineInfo && ) = default;
- SourceLineInfo& operator = ( SourceLineInfo const& ) = default;
- SourceLineInfo& operator = ( SourceLineInfo && ) = default;
-
- bool empty() const noexcept;
- bool operator == ( SourceLineInfo const& other ) const noexcept;
- bool operator < ( SourceLineInfo const& other ) const noexcept;
-
- char const* file;
- std::size_t line;
- };
-
- std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
-
- // Bring in operator<< from global namespace into Catch namespace
- // This is necessary because the overload of operator<< above makes
- // lookup stop at namespace Catch
- using ::operator<<;
-
- // Use this in variadic streaming macros to allow
- // >> +StreamEndStop
- // as well as
- // >> stuff +StreamEndStop
- struct StreamEndStop {
- std::string operator+() const;
- };
- template
- T const& operator + ( T const& value, StreamEndStop ) {
- return value;
- }
-}
-
-#define CATCH_INTERNAL_LINEINFO \
- ::Catch::SourceLineInfo( __FILE__, static_cast( __LINE__ ) )
-
-// end catch_common.h
-namespace Catch {
-
- struct RegistrarForTagAliases {
- RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
- };
-
-} // end namespace Catch
-
-#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \
- CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
- namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \
- CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
-
-// end catch_tag_alias_autoregistrar.h
-// start catch_test_registry.h
-
-// start catch_interfaces_testcase.h
-
-#include
-#include
-
-namespace Catch {
-
- class TestSpec;
-
- struct ITestInvoker {
- virtual void invoke () const = 0;
- virtual ~ITestInvoker();
- };
-
- using ITestCasePtr = std::shared_ptr;
-
- class TestCase;
- struct IConfig;
-
- struct ITestCaseRegistry {
- virtual ~ITestCaseRegistry();
- virtual std::vector const& getAllTests() const = 0;
- virtual std::vector const& getAllTestsSorted( IConfig const& config ) const = 0;
- };
-
- bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
- std::vector filterTests( std::vector const& testCases, TestSpec const& testSpec, IConfig const& config );
- std::vector const& getAllTestCasesSorted( IConfig const& config );
-
-}
-
-// end catch_interfaces_testcase.h
-// start catch_stringref.h
-
-#include
-#include
-#include
-
-namespace Catch {
-
- class StringData;
-
- /// A non-owning string class (similar to the forthcoming std::string_view)
- /// Note that, because a StringRef may be a substring of another string,
- /// it may not be null terminated. c_str() must return a null terminated
- /// string, however, and so the StringRef will internally take ownership
- /// (taking a copy), if necessary. In theory this ownership is not externally
- /// visible - but it does mean (substring) StringRefs should not be shared between
- /// threads.
- class StringRef {
- public:
- using size_type = std::size_t;
-
- private:
- friend struct StringRefTestAccess;
-
- char const* m_start;
- size_type m_size;
-
- char* m_data = nullptr;
-
- void takeOwnership();
-
- static constexpr char const* const s_empty = "";
-
- public: // construction/ assignment
- StringRef() noexcept
- : StringRef( s_empty, 0 )
- {}
-
- StringRef( StringRef const& other ) noexcept
- : m_start( other.m_start ),
- m_size( other.m_size )
- {}
-
- StringRef( StringRef&& other ) noexcept
- : m_start( other.m_start ),
- m_size( other.m_size ),
- m_data( other.m_data )
- {
- other.m_data = nullptr;
- }
-
- StringRef( char const* rawChars ) noexcept;
-
- StringRef( char const* rawChars, size_type size ) noexcept
- : m_start( rawChars ),
- m_size( size )
- {}
-
- StringRef( std::string const& stdString ) noexcept
- : m_start( stdString.c_str() ),
- m_size( stdString.size() )
- {}
-
- ~StringRef() noexcept {
- delete[] m_data;
- }
-
- auto operator = ( StringRef const &other ) noexcept -> StringRef& {
- delete[] m_data;
- m_data = nullptr;
- m_start = other.m_start;
- m_size = other.m_size;
- return *this;
- }
-
- operator std::string() const;
-
- void swap( StringRef& other ) noexcept;
-
- public: // operators
- auto operator == ( StringRef const& other ) const noexcept -> bool;
- auto operator != ( StringRef const& other ) const noexcept -> bool;
-
- auto operator[] ( size_type index ) const noexcept -> char;
-
- public: // named queries
- auto empty() const noexcept -> bool {
- return m_size == 0;
- }
- auto size() const noexcept -> size_type {
- return m_size;
- }
-
- auto numberOfCharacters() const noexcept -> size_type;
- auto c_str() const -> char const*;
-
- public: // substrings and searches
- auto substr( size_type start, size_type size ) const noexcept -> StringRef;
-
- // Returns the current start pointer.
- // Note that the pointer can change when if the StringRef is a substring
- auto currentData() const noexcept -> char const*;
-
- 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&;
-
- inline auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef {
- return StringRef( rawChars, size );
- }
-
-} // namespace Catch
-
-inline auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef {
- return Catch::StringRef( rawChars, size );
-}
-
-// end catch_stringref.h
-namespace Catch {
-
-template
-class TestInvokerAsMethod : public ITestInvoker {
- void (C::*m_testAsMethod)();
-public:
- TestInvokerAsMethod( void (C::*testAsMethod)() ) noexcept : m_testAsMethod( testAsMethod ) {}
-
- void invoke() const override {
- C obj;
- (obj.*m_testAsMethod)();
- }
-};
-
-auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker*;
-
-template
-auto makeTestInvoker( void (C::*testAsMethod)() ) noexcept -> ITestInvoker* {
- return new(std::nothrow) TestInvokerAsMethod( testAsMethod );
-}
-
-struct NameAndTags {
- NameAndTags( StringRef const& name_ = StringRef(), StringRef const& tags_ = StringRef() ) noexcept;
- StringRef name;
- StringRef tags;
-};
-
-struct AutoReg : NonCopyable {
- AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept;
- ~AutoReg();
-};
-
-} // end namespace Catch
-
-#define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param)
-#define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__
-#define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__
-#define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
-
-#if defined(CATCH_CONFIG_DISABLE)
- #define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION( TestName, ... ) \
- static void TestName()
- #define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \
- namespace{ \
- struct TestName : INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF ClassName) { \
- void test(); \
- }; \
- } \
- void TestName::test()
-
-#endif
-
- ///////////////////////////////////////////////////////////////////////////////
- #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
- static void TestName(); \
- CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
- namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
- CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
- static void TestName()
- #define INTERNAL_CATCH_TESTCASE( ... ) \
- INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ )
-
- ///////////////////////////////////////////////////////////////////////////////
- #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
- CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
- namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, "&" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
- CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
-
- ///////////////////////////////////////////////////////////////////////////////
- #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
- CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
- namespace{ \
- struct TestName : INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF ClassName) { \
- void test(); \
- }; \
- Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
- } \
- CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
- void TestName::test()
- #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
- INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ )
-
- ///////////////////////////////////////////////////////////////////////////////
- #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
- CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
- Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
- CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
-
-// end catch_test_registry.h
-// start catch_capture.hpp
-
-// start catch_assertionhandler.h
-
-// start catch_assertioninfo.h
-
-// start catch_result_type.h
-
-namespace Catch {
-
- // ResultWas::OfType enum
- struct ResultWas { enum OfType {
- Unknown = -1,
- Ok = 0,
- Info = 1,
- Warning = 2,
-
- FailureBit = 0x10,
-
- ExpressionFailed = FailureBit | 1,
- ExplicitFailure = FailureBit | 2,
-
- Exception = 0x100 | FailureBit,
-
- ThrewException = Exception | 1,
- DidntThrowException = Exception | 2,
-
- FatalErrorCondition = 0x200 | FailureBit
-
- }; };
-
- bool isOk( ResultWas::OfType resultType );
- bool isJustInfo( int flags );
-
- // ResultDisposition::Flags enum
- struct ResultDisposition { enum Flags {
- Normal = 0x01,
-
- ContinueOnFailure = 0x02, // Failures fail test, but execution continues
- FalseTest = 0x04, // Prefix expression with !
- SuppressFail = 0x08 // Failures are reported but do not fail the test
- }; };
-
- ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs );
-
- bool shouldContinueOnFailure( int flags );
- inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; }
- bool shouldSuppressFailure( int flags );
-
-} // end namespace Catch
-
-// end catch_result_type.h
-namespace Catch {
-
- struct AssertionInfo
- {
- StringRef macroName;
- SourceLineInfo lineInfo;
- StringRef capturedExpression;
- ResultDisposition::Flags resultDisposition;
-
- // We want to delete this constructor but a compiler bug in 4.8 means
- // the struct is then treated as non-aggregate
- //AssertionInfo() = delete;
- };
-
-} // end namespace Catch
-
-// end catch_assertioninfo.h
-// start catch_decomposer.h
-
-// start catch_tostring.h
-
-#include
-#include
-#include
-#include
-// start catch_stream.h
-
-#include
-#include
-#include
-
-namespace Catch {
-
- std::ostream& cout();
- std::ostream& cerr();
- std::ostream& clog();
-
- class StringRef;
-
- struct IStream {
- virtual ~IStream();
- virtual std::ostream& stream() const = 0;
- };
-
- auto makeStream( StringRef const &filename ) -> IStream const*;
-
- class ReusableStringStream {
- std::size_t m_index;
- std::ostream* m_oss;
- public:
- ReusableStringStream();
- ~ReusableStringStream();
-
- auto str() const -> std::string;
-
- template
- auto operator << ( T const& value ) -> ReusableStringStream& {
- *m_oss << value;
- return *this;
- }
- auto get() -> std::ostream& { return *m_oss; }
- };
-}
-
-// end catch_stream.h
-
-#ifdef CATCH_CONFIG_CPP17_STRING_VIEW
-#include
-#endif
-
-#ifdef __OBJC__
-// start catch_objc_arc.hpp
-
-#import
-
-#ifdef __has_feature
-#define CATCH_ARC_ENABLED __has_feature(objc_arc)
-#else
-#define CATCH_ARC_ENABLED 0
-#endif
-
-void arcSafeRelease( NSObject* obj );
-id performOptionalSelector( id obj, SEL sel );
-
-#if !CATCH_ARC_ENABLED
-inline void arcSafeRelease( NSObject* obj ) {
- [obj release];
-}
-inline id performOptionalSelector( id obj, SEL sel ) {
- if( [obj respondsToSelector: sel] )
- return [obj performSelector: sel];
- return nil;
-}
-#define CATCH_UNSAFE_UNRETAINED
-#define CATCH_ARC_STRONG
-#else
-inline void arcSafeRelease( NSObject* ){}
-inline id performOptionalSelector( id obj, SEL sel ) {
-#ifdef __clang__
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
-#endif
- if( [obj respondsToSelector: sel] )
- return [obj performSelector: sel];
-#ifdef __clang__
-#pragma clang diagnostic pop
-#endif
- return nil;
-}
-#define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
-#define CATCH_ARC_STRONG __strong
-#endif
-
-// end catch_objc_arc.hpp
-#endif
-
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable:4180) // We attempt to stream a function (address) by const&, which MSVC complains about but is harmless
-#endif
-
-namespace Catch {
- namespace Detail {
-
- extern const std::string unprintableString;
-
- std::string rawMemoryToString( const void *object, std::size_t size );
-
- template
- std::string rawMemoryToString( const T& object ) {
- return rawMemoryToString( &object, sizeof(object) );
- }
-
- template
- class IsStreamInsertable {
- template
- static auto test(int)
- -> decltype(std::declval() << std::declval(), std::true_type());
-
- template
- static auto test(...)->std::false_type;
-
- public:
- static const bool value = decltype(test(0))::value;
- };
-
- template
- std::string convertUnknownEnumToString( E e );
-
- template
- typename std::enable_if<
- !std::is_enum::value && !std::is_base_of::value,
- std::string>::type convertUnstreamable( T const& ) {
- return Detail::unprintableString;
- }
- template
- typename std::enable_if<
- !std::is_enum::value && std::is_base_of::value,
- std::string>::type convertUnstreamable(T const& ex) {
- return ex.what();
- }
-
- template
- typename std::enable_if<
- std::is_enum::value
- , std::string>::type convertUnstreamable( T const& value ) {
- return convertUnknownEnumToString( value );
- }
-
-#if defined(_MANAGED)
- //! Convert a CLR string to a utf8 std::string
- template
- std::string clrReferenceToString( T^ ref ) {
- if (ref == nullptr)
- return std::string("null");
- auto bytes = System::Text::Encoding::UTF8->GetBytes(ref->ToString());
- cli::pin_ptr p = &bytes[0];
- return std::string(reinterpret_cast(p), bytes->Length);
- }
-#endif
-
- } // namespace Detail
-
- // If we decide for C++14, change these to enable_if_ts
- template
- struct StringMaker {
- template
- static
- typename std::enable_if<::Catch::Detail::IsStreamInsertable::value, std::string>::type
- convert(const Fake& value) {
- ReusableStringStream rss;
- // NB: call using the function-like syntax to avoid ambiguity with
- // user-defined templated operator<< under clang.
- rss.operator<<(value);
- return rss.str();
- }
-
- template
- static
- typename std::enable_if::value, std::string>::type
- convert( const Fake& value ) {
-#if !defined(CATCH_CONFIG_FALLBACK_STRINGIFIER)
- return Detail::convertUnstreamable(value);
-#else
- return CATCH_CONFIG_FALLBACK_STRINGIFIER(value);
-#endif
- }
- };
-
- namespace Detail {
-
- // This function dispatches all stringification requests inside of Catch.
- // Should be preferably called fully qualified, like ::Catch::Detail::stringify
- template
- std::string stringify(const T& e) {
- return ::Catch::StringMaker::type>::type>::convert(e);
- }
-
- template
- std::string convertUnknownEnumToString( E e ) {
- return ::Catch::Detail::stringify(static_cast::type>(e));
- }
-
-#if defined(_MANAGED)
- template
- std::string stringify( T^ e ) {
- return ::Catch::StringMaker::convert(e);
- }
-#endif
-
- } // namespace Detail
-
- // Some predefined specializations
-
- template<>
- struct StringMaker {
- static std::string convert(const std::string& str);
- };
-
-#ifdef CATCH_CONFIG_CPP17_STRING_VIEW
- template<>
- struct StringMaker {
- static std::string convert(std::string_view str);
- };
-#endif
-
- template<>
- struct StringMaker {
- static std::string convert(char const * str);
- };
- template<>
- struct StringMaker {
- static std::string convert(char * str);
- };
-
-#ifdef CATCH_CONFIG_WCHAR
- template<>
- struct StringMaker {
- static std::string convert(const std::wstring& wstr);
- };
-
-# ifdef CATCH_CONFIG_CPP17_STRING_VIEW
- template<>
- struct StringMaker {
- static std::string convert(std::wstring_view str);
- };
-# endif
-
- template<>
- struct StringMaker {
- static std::string convert(wchar_t const * str);
- };
- template<>
- struct StringMaker {
- static std::string convert(wchar_t * str);
- };
-#endif
-
- // TBD: Should we use `strnlen` to ensure that we don't go out of the buffer,
- // while keeping string semantics?
- template
- struct StringMaker {
- static std::string convert(char const* str) {
- return ::Catch::Detail::stringify(std::string{ str });
- }
- };
- template
- struct StringMaker {
- static std::string convert(signed char const* str) {
- return ::Catch::Detail::stringify(std::string{ reinterpret_cast(str) });
- }
- };
- template
- struct StringMaker {
- static std::string convert(unsigned char const* str) {
- return ::Catch::Detail::stringify(std::string{ reinterpret_cast(str) });
- }
- };
-
- template<>
- struct StringMaker {
- static std::string convert(int value);
- };
- template<>
- struct StringMaker {
- static std::string convert(long value);
- };
- template<>
- struct StringMaker {
- static std::string convert(long long value);
- };
- template<>
- struct StringMaker {
- static std::string convert(unsigned int value);
- };
- template<>
- struct StringMaker {
- static std::string convert(unsigned long value);
- };
- template<>
- struct StringMaker {
- static std::string convert(unsigned long long value);
- };
-
- template<>
- struct StringMaker {
- static std::string convert(bool b);
- };
-
- template<>
- struct StringMaker {
- static std::string convert(char c);
- };
- template<>
- struct StringMaker {
- static std::string convert(signed char c);
- };
- template<>
- struct StringMaker {
- static std::string convert(unsigned char c);
- };
-
- template<>
- struct StringMaker {
- static std::string convert(std::nullptr_t);
- };
-
- template<>
- struct StringMaker {
- static std::string convert(float value);
- };
- template<>
- struct StringMaker {
- static std::string convert(double value);
- };
-
- template
- struct StringMaker {
- template
- static std::string convert(U* p) {
- if (p) {
- return ::Catch::Detail::rawMemoryToString(p);
- } else {
- return "nullptr";
- }
- }
- };
-
- template
- struct StringMaker {
- static std::string convert(R C::* p) {
- if (p) {
- return ::Catch::Detail::rawMemoryToString(p);
- } else {
- return "nullptr";
- }
- }
- };
-
-#if defined(_MANAGED)
- template
- struct StringMaker {
- static std::string convert( T^ ref ) {
- return ::Catch::Detail::clrReferenceToString(ref);
- }
- };
-#endif
-
- namespace Detail {
- template
- std::string rangeToString(InputIterator first, InputIterator last) {
- ReusableStringStream rss;
- rss << "{ ";
- if (first != last) {
- rss << ::Catch::Detail::stringify(*first);
- for (++first; first != last; ++first)
- rss << ", " << ::Catch::Detail::stringify(*first);
- }
- rss << " }";
- return rss.str();
- }
- }
-
-#ifdef __OBJC__
- template<>
- struct StringMaker {
- static std::string convert(NSString * nsstring) {
- if (!nsstring)
- return "nil";
- return std::string("@") + [nsstring UTF8String];
- }
- };
- template<>
- struct StringMaker {
- static std::string convert(NSObject* nsObject) {
- return ::Catch::Detail::stringify([nsObject description]);
- }
-
- };
- namespace Detail {
- inline std::string stringify( NSString* nsstring ) {
- return StringMaker::convert( nsstring );
- }
-
- } // namespace Detail
-#endif // __OBJC__
-
-} // namespace Catch
-
-//////////////////////////////////////////////////////
-// Separate std-lib types stringification, so it can be selectively enabled
-// This means that we do not bring in
-
-#if defined(CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS)
-# define CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
-# define CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
-# define CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
-# define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
-#endif
-
-// Separate std::pair specialization
-#if defined(CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER)
-#include
-namespace Catch {
- template
- struct StringMaker > {
- static std::string convert(const std::pair& pair) {
- ReusableStringStream rss;
- rss << "{ "
- << ::Catch::Detail::stringify(pair.first)
- << ", "
- << ::Catch::Detail::stringify(pair.second)
- << " }";
- return rss.str();
- }
- };
-}
-#endif // CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
-
-// Separate std::tuple specialization
-#if defined(CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER)
-#include
-namespace Catch {
- namespace Detail {
- template<
- typename Tuple,
- std::size_t N = 0,
- bool = (N < std::tuple_size::value)
- >
- struct TupleElementPrinter {
- static void print(const Tuple& tuple, std::ostream& os) {
- os << (N ? ", " : " ")
- << ::Catch::Detail::stringify(std::get(tuple));
- TupleElementPrinter::print(tuple, os);
- }
- };
-
- template<
- typename Tuple,
- std::size_t N
- >
- struct TupleElementPrinter {
- static void print(const Tuple&, std::ostream&) {}
- };
-
- }
-
- template
- struct StringMaker> {
- static std::string convert(const std::tuple& tuple) {
- ReusableStringStream rss;
- rss << '{';
- Detail::TupleElementPrinter>::print(tuple, rss.get());
- rss << " }";
- return rss.str();
- }
- };
-}
-#endif // CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
-
-#if defined(CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_VARIANT)
-#include
-namespace Catch {
- template<>
- struct StringMaker {
- static std::string convert(const std::monostate&) {
- return "{ }";
- }
- };
-
- template
- struct StringMaker> {
- static std::string convert(const std::variant& variant) {
- if (variant.valueless_by_exception()) {
- return "{valueless variant}";
- } else {
- return std::visit(
- [](const auto& value) {
- return ::Catch::Detail::stringify(value);
- },
- variant
- );
- }
- }
- };
-}
-#endif // CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
-
-namespace Catch {
- struct not_this_one {}; // Tag type for detecting which begin/ end are being selected
-
- // Import begin/ end from std here so they are considered alongside the fallback (...) overloads in this namespace
- using std::begin;
- using std::end;
-
- not_this_one begin( ... );
- not_this_one end( ... );
-
- template
- struct is_range {
- static const bool value =
- !std::is_same())), not_this_one>::value &&
- !std::is_same())), not_this_one>::value;
- };
-
-#if defined(_MANAGED) // Managed types are never ranges
- template
- struct is_range {
- static const bool value = false;
- };
-#endif
-
- template
- std::string rangeToString( Range const& range ) {
- return ::Catch::Detail::rangeToString( begin( range ), end( range ) );
- }
-
- // Handle vector specially
- template
- std::string rangeToString( std::vector const& v ) {
- ReusableStringStream rss;
- rss << "{ ";
- bool first = true;
- for( bool b : v ) {
- if( first )
- first = false;
- else
- rss << ", ";
- rss << ::Catch::Detail::stringify( b );
- }
- rss << " }";
- return rss.str();
- }
-
- template
- struct StringMaker::value && !::Catch::Detail::IsStreamInsertable::value>::type> {
- static std::string convert( R const& range ) {
- return rangeToString( range );
- }
- };
-
- template
- struct StringMaker {
- static std::string convert(T const(&arr)[SZ]) {
- return rangeToString(arr);
- }
- };
-
-} // namespace Catch
-
-// Separate std::chrono::duration specialization
-#if defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
-#include
-#include
-#include
-
-namespace Catch {
-
-template
-struct ratio_string {
- static std::string symbol();
-};
-
-template
-std::string ratio_string::symbol() {
- Catch::ReusableStringStream rss;
- rss << '[' << Ratio::num << '/'
- << Ratio::den << ']';
- return rss.str();
-}
-template <>
-struct ratio_string {
- static std::string symbol();
-};
-template <>
-struct ratio_string {
- static std::string symbol();
-};
-template <>
-struct ratio_string {
- static std::string symbol();
-};
-template <>
-struct ratio_string {
- static std::string symbol();
-};
-template <>
-struct ratio_string {
- static std::string symbol();
-};
-template <>
-struct ratio_string {
- static std::string symbol();
-};
-
- ////////////
- // std::chrono::duration specializations
- template
- struct StringMaker> {
- static std::string convert(std::chrono::duration const& duration) {
- ReusableStringStream rss;
- rss << duration.count() << ' ' << ratio_string::symbol() << 's';
- return rss.str();
- }
- };
- template
- struct StringMaker>> {
- static std::string convert(std::chrono::duration> const& duration) {
- ReusableStringStream rss;
- rss << duration.count() << " s";
- return rss.str();
- }
- };
- template
- struct StringMaker>> {
- static std::string convert(std::chrono::duration> const& duration) {
- ReusableStringStream rss;
- rss << duration.count() << " m";
- return rss.str();
- }
- };
- template
- struct StringMaker>> {
- static std::string convert(std::chrono::duration> const& duration) {
- ReusableStringStream rss;
- rss << duration.count() << " h";
- return rss.str();
- }
- };
-
- ////////////
- // std::chrono::time_point specialization
- // Generic time_point cannot be specialized, only std::chrono::time_point
- template
- struct StringMaker> {
- static std::string convert(std::chrono::time_point const& time_point) {
- return ::Catch::Detail::stringify(time_point.time_since_epoch()) + " since epoch";
- }
- };
- // std::chrono::time_point specialization
- template
- struct StringMaker> {
- static std::string convert(std::chrono::time_point const& time_point) {
- auto converted = std::chrono::system_clock::to_time_t(time_point);
-
-#ifdef _MSC_VER
- std::tm timeInfo = {};
- gmtime_s(&timeInfo, &converted);
-#else
- std::tm* timeInfo = std::gmtime(&converted);
-#endif
-
- auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
- char timeStamp[timeStampSize];
- const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
-
-#ifdef _MSC_VER
- std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
-#else
- std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
-#endif
- return std::string(timeStamp);
- }
- };
-}
-#endif // CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
-
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-
-// end catch_tostring.h
-#include
-
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable:4389) // '==' : signed/unsigned mismatch
-#pragma warning(disable:4018) // more "signed/unsigned mismatch"
-#pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform)
-#pragma warning(disable:4180) // qualifier applied to function type has no meaning
-#endif
-
-namespace Catch {
-
- struct ITransientExpression {
- auto isBinaryExpression() const -> bool { return m_isBinaryExpression; }
- auto getResult() const -> bool { return m_result; }
- virtual void streamReconstructedExpression( std::ostream &os ) const = 0;
-
- ITransientExpression( bool isBinaryExpression, bool result )
- : m_isBinaryExpression( isBinaryExpression ),
- m_result( result )
- {}
-
- // We don't actually need a virtual destructor, but many static analysers
- // complain if it's not here :-(
- virtual ~ITransientExpression();
-
- bool m_isBinaryExpression;
- bool m_result;
-
- };
-
- void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs );
-
- template
- class BinaryExpr : public ITransientExpression {
- LhsT m_lhs;
- StringRef m_op;
- RhsT m_rhs;
-
- void streamReconstructedExpression( std::ostream &os ) const override {
- formatReconstructedExpression
- ( os, Catch::Detail::stringify( m_lhs ), m_op, Catch::Detail::stringify( m_rhs ) );
- }
-
- public:
- BinaryExpr( bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs )
- : ITransientExpression{ true, comparisonResult },
- m_lhs( lhs ),
- m_op( op ),
- m_rhs( rhs )
- {}
- };
-
- template
- class UnaryExpr : public ITransientExpression {
- LhsT m_lhs;
-
- void streamReconstructedExpression( std::ostream &os ) const override {
- os << Catch::Detail::stringify( m_lhs );
- }
-
- public:
- explicit UnaryExpr( LhsT lhs )
- : ITransientExpression{ false, lhs ? true : false },
- m_lhs( lhs )
- {}
- };
-
- // Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int)
- template
- auto compareEqual( LhsT const& lhs, RhsT const& rhs ) -> bool { return static_cast(lhs == rhs); }
- template
- auto compareEqual( T* const& lhs, int rhs ) -> bool { return lhs == reinterpret_cast( rhs ); }
- template
- auto compareEqual( T* const& lhs, long rhs ) -> bool { return lhs == reinterpret_cast( rhs ); }
- template
- auto compareEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast( lhs ) == rhs; }
- template
- auto compareEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast( lhs ) == rhs; }
-
- template
- auto compareNotEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return static_cast(lhs != rhs); }
- template
- auto compareNotEqual( T* const& lhs, int rhs ) -> bool { return lhs != reinterpret_cast( rhs ); }
- template
- auto compareNotEqual( T* const& lhs, long rhs ) -> bool { return lhs != reinterpret_cast( rhs ); }
- template
- auto compareNotEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast( lhs ) != rhs; }
- template
- auto compareNotEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast( lhs ) != rhs; }
-
- template
- class ExprLhs {
- LhsT m_lhs;
- public:
- explicit ExprLhs( LhsT lhs ) : m_lhs( lhs ) {}
-
- template
- auto operator == ( RhsT const& rhs ) -> BinaryExpr const {
- return { compareEqual( m_lhs, rhs ), m_lhs, "==", rhs };
- }
- auto operator == ( bool rhs ) -> BinaryExpr const {
- return { m_lhs == rhs, m_lhs, "==", rhs };
- }
-
- template
- auto operator != ( RhsT const& rhs ) -> BinaryExpr const {
- return { compareNotEqual( m_lhs, rhs ), m_lhs, "!=", rhs };
- }
- auto operator != ( bool rhs ) -> BinaryExpr const {
- return { m_lhs != rhs, m_lhs, "!=", rhs };
- }
-
- template
- auto operator > ( RhsT const& rhs ) -> BinaryExpr const {
- return { static_cast(m_lhs > rhs), m_lhs, ">", rhs };
- }
- template
- auto operator < ( RhsT const& rhs ) -> BinaryExpr const {
- return { static_cast(m_lhs < rhs), m_lhs, "<", rhs };
- }
- template
- auto operator >= ( RhsT const& rhs ) -> BinaryExpr const {
- return { static_cast(m_lhs >= rhs), m_lhs, ">=", rhs };
- }
- template
- auto operator <= ( RhsT const& rhs ) -> BinaryExpr const {
- return { static_cast(m_lhs <= rhs), m_lhs, "<=", rhs };
- }
-
- auto makeUnaryExpr() const -> UnaryExpr {
- return UnaryExpr{ m_lhs };
- }
- };
-
- void handleExpression( ITransientExpression const& expr );
-
- template
- void handleExpression( ExprLhs const& expr ) {
- handleExpression( expr.makeUnaryExpr() );
- }
-
- struct Decomposer {
- template
- auto operator <= ( T const& lhs ) -> ExprLhs {
- return ExprLhs{ lhs };
- }
-
- auto operator <=( bool value ) -> ExprLhs {
- return ExprLhs{ value };
- }
- };
-
-} // end namespace Catch
-
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-
-// end catch_decomposer.h
-// start catch_interfaces_capture.h
-
-#include
-
-namespace Catch {
-
- class AssertionResult;
- struct AssertionInfo;
- struct SectionInfo;
- struct SectionEndInfo;
- struct MessageInfo;
- struct Counts;
- struct BenchmarkInfo;
- struct BenchmarkStats;
- struct AssertionReaction;
- struct SourceLineInfo;
-
- struct ITransientExpression;
- struct IGeneratorTracker;
-
- struct IResultCapture {
-
- virtual ~IResultCapture();
-
- virtual bool sectionStarted( SectionInfo const& sectionInfo,
- Counts& assertions ) = 0;
- virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;
- virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;
-
- virtual auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& = 0;
-
- virtual void benchmarkStarting( BenchmarkInfo const& info ) = 0;
- virtual void benchmarkEnded( BenchmarkStats const& stats ) = 0;
-
- virtual void pushScopedMessage( MessageInfo const& message ) = 0;
- virtual void popScopedMessage( MessageInfo const& message ) = 0;
-
- virtual void handleFatalErrorCondition( StringRef message ) = 0;
-
- virtual void handleExpr
- ( AssertionInfo const& info,
- ITransientExpression const& expr,
- AssertionReaction& reaction ) = 0;
- virtual void handleMessage
- ( AssertionInfo const& info,
- ResultWas::OfType resultType,
- StringRef const& message,
- AssertionReaction& reaction ) = 0;
- virtual void handleUnexpectedExceptionNotThrown
- ( AssertionInfo const& info,
- AssertionReaction& reaction ) = 0;
- virtual void handleUnexpectedInflightException
- ( AssertionInfo const& info,
- std::string const& message,
- AssertionReaction& reaction ) = 0;
- virtual void handleIncomplete
- ( AssertionInfo const& info ) = 0;
- virtual void handleNonExpr
- ( AssertionInfo const &info,
- ResultWas::OfType resultType,
- AssertionReaction &reaction ) = 0;
-
- virtual bool lastAssertionPassed() = 0;
- virtual void assertionPassed() = 0;
-
- // Deprecated, do not use:
- virtual std::string getCurrentTestName() const = 0;
- virtual const AssertionResult* getLastResult() const = 0;
- virtual void exceptionEarlyReported() = 0;
- };
-
- IResultCapture& getResultCapture();
-}
-
-// end catch_interfaces_capture.h
-namespace Catch {
-
- struct TestFailureException{};
- struct AssertionResultData;
- struct IResultCapture;
- class RunContext;
-
- class LazyExpression {
- friend class AssertionHandler;
- friend struct AssertionStats;
- friend class RunContext;
-
- ITransientExpression const* m_transientExpression = nullptr;
- bool m_isNegated;
- public:
- LazyExpression( bool isNegated );
- LazyExpression( LazyExpression const& other );
- LazyExpression& operator = ( LazyExpression const& ) = delete;
-
- explicit operator bool() const;
-
- friend auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream&;
- };
-
- struct AssertionReaction {
- bool shouldDebugBreak = false;
- bool shouldThrow = false;
- };
-
- class AssertionHandler {
- AssertionInfo m_assertionInfo;
- AssertionReaction m_reaction;
- bool m_completed = false;
- IResultCapture& m_resultCapture;
-
- public:
- AssertionHandler
- ( StringRef const& macroName,
- SourceLineInfo const& lineInfo,
- StringRef capturedExpression,
- ResultDisposition::Flags resultDisposition );
- ~AssertionHandler() {
- if ( !m_completed ) {
- m_resultCapture.handleIncomplete( m_assertionInfo );
- }
- }
-
- template
- void handleExpr( ExprLhs const& expr ) {
- handleExpr( expr.makeUnaryExpr() );
- }
- void handleExpr( ITransientExpression const& expr );
-
- void handleMessage(ResultWas::OfType resultType, StringRef const& message);
-
- void handleExceptionThrownAsExpected();
- void handleUnexpectedExceptionNotThrown();
- void handleExceptionNotThrownAsExpected();
- void handleThrowingCallSkipped();
- void handleUnexpectedInflightException();
-
- void complete();
- void setCompleted();
-
- // query
- auto allowThrows() const -> bool;
- };
-
- void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString );
-
-} // namespace Catch
-
-// end catch_assertionhandler.h
-// start catch_message.h
-
-#include
-#include
-
-namespace Catch {
-
- struct MessageInfo {
- MessageInfo( StringRef const& _macroName,
- SourceLineInfo const& _lineInfo,
- ResultWas::OfType _type );
-
- StringRef macroName;
- std::string message;
- SourceLineInfo lineInfo;
- ResultWas::OfType type;
- unsigned int sequence;
-
- bool operator == ( MessageInfo const& other ) const;
- bool operator < ( MessageInfo const& other ) const;
- private:
- static unsigned int globalCount;
- };
-
- struct MessageStream {
-
- template
- MessageStream& operator << ( T const& value ) {
- m_stream << value;
- return *this;
- }
-
- ReusableStringStream m_stream;
- };
-
- struct MessageBuilder : MessageStream {
- MessageBuilder( StringRef const& macroName,
- SourceLineInfo const& lineInfo,
- ResultWas::OfType type );
-
- template
- MessageBuilder& operator << ( T const& value ) {
- m_stream << value;
- return *this;
- }
-
- MessageInfo m_info;
- };
-
- class ScopedMessage {
- public:
- explicit ScopedMessage( MessageBuilder const& builder );
- ~ScopedMessage();
-
- MessageInfo m_info;
- };
-
- class Capturer {
- std::vector m_messages;
- IResultCapture& m_resultCapture = getResultCapture();
- size_t m_captured = 0;
- public:
- Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names );
- ~Capturer();
-
- void captureValue( size_t index, StringRef value );
-
- template
- void captureValues( size_t index, T&& value ) {
- captureValue( index, Catch::Detail::stringify( value ) );
- }
-
- template
- void captureValues( size_t index, T&& value, Ts&&... values ) {
- captureValues( index, value );
- captureValues( index+1, values... );
- }
- };
-
-} // end namespace Catch
-
-// end catch_message.h
-#if !defined(CATCH_CONFIG_DISABLE)
-
-#if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION)
- #define CATCH_INTERNAL_STRINGIFY(...) #__VA_ARGS__
-#else
- #define CATCH_INTERNAL_STRINGIFY(...) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION"
-#endif
-
-#if defined(CATCH_CONFIG_FAST_COMPILE) || defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
-
-///////////////////////////////////////////////////////////////////////////////
-// Another way to speed-up compilation is to omit local try-catch for REQUIRE*
-// macros.
-#define INTERNAL_CATCH_TRY
-#define INTERNAL_CATCH_CATCH( capturer )
-
-#else // CATCH_CONFIG_FAST_COMPILE
-
-#define INTERNAL_CATCH_TRY try
-#define INTERNAL_CATCH_CATCH( handler ) catch(...) { handler.handleUnexpectedInflightException(); }
-
-#endif
-
-#define INTERNAL_CATCH_REACT( handler ) handler.complete();
-
-///////////////////////////////////////////////////////////////////////////////
-#define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \
- do { \
- Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
- INTERNAL_CATCH_TRY { \
- CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
- catchAssertionHandler.handleExpr( Catch::Decomposer() <= __VA_ARGS__ ); \
- CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
- } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
- INTERNAL_CATCH_REACT( catchAssertionHandler ) \
- } while( (void)0, false && static_cast( !!(__VA_ARGS__) ) ) // the expression here is never evaluated at runtime but it forces the compiler to give it a look
- // The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&.
-
-///////////////////////////////////////////////////////////////////////////////
-#define INTERNAL_CATCH_IF( macroName, resultDisposition, ... ) \
- INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
- if( Catch::getResultCapture().lastAssertionPassed() )
-
-///////////////////////////////////////////////////////////////////////////////
-#define INTERNAL_CATCH_ELSE( macroName, resultDisposition, ... ) \
- INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
- if( !Catch::getResultCapture().lastAssertionPassed() )
-
-///////////////////////////////////////////////////////////////////////////////
-#define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, ... ) \
- do { \
- Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
- try { \
- static_cast(__VA_ARGS__); \
- catchAssertionHandler.handleExceptionNotThrownAsExpected(); \
- } \
- catch( ... ) { \
- catchAssertionHandler.handleUnexpectedInflightException(); \
- } \
- INTERNAL_CATCH_REACT( catchAssertionHandler ) \
- } while( false )
-
-///////////////////////////////////////////////////////////////////////////////
-#define INTERNAL_CATCH_THROWS( macroName, resultDisposition, ... ) \
- do { \
- Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \
- if( catchAssertionHandler.allowThrows() ) \
- try { \
- static_cast(__VA_ARGS__); \
- catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
- } \
- catch( ... ) { \
- catchAssertionHandler.handleExceptionThrownAsExpected(); \
- } \
- else \
- catchAssertionHandler.handleThrowingCallSkipped(); \
- INTERNAL_CATCH_REACT( catchAssertionHandler ) \
- } while( false )
-
-///////////////////////////////////////////////////////////////////////////////
-#define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \
- do { \
- Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \
- if( catchAssertionHandler.allowThrows() ) \
- try { \
- static_cast(expr); \
- catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
- } \
- catch( exceptionType const& ) { \
- catchAssertionHandler.handleExceptionThrownAsExpected(); \
- } \
- catch( ... ) { \
- catchAssertionHandler.handleUnexpectedInflightException(); \
- } \
- else \
- catchAssertionHandler.handleThrowingCallSkipped(); \
- INTERNAL_CATCH_REACT( catchAssertionHandler ) \
- } while( false )
-
-///////////////////////////////////////////////////////////////////////////////
-#define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \
- do { \
- Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::StringRef(), resultDisposition ); \
- catchAssertionHandler.handleMessage( messageType, ( Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop() ).m_stream.str() ); \
- INTERNAL_CATCH_REACT( catchAssertionHandler ) \
- } while( false )
-
-///////////////////////////////////////////////////////////////////////////////
-#define INTERNAL_CATCH_CAPTURE( varName, macroName, ... ) \
- auto varName = Catch::Capturer( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info, #__VA_ARGS__ ); \
- varName.captureValues( 0, __VA_ARGS__ )
-
-///////////////////////////////////////////////////////////////////////////////
-#define INTERNAL_CATCH_INFO( macroName, log ) \
- Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log );
-
-///////////////////////////////////////////////////////////////////////////////
-// Although this is matcher-based, it can be used with just a string
-#define INTERNAL_CATCH_THROWS_STR_MATCHES( macroName, resultDisposition, matcher, ... ) \
- do { \
- Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
- if( catchAssertionHandler.allowThrows() ) \
- try { \
- static_cast(__VA_ARGS__); \
- catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
- } \
- catch( ... ) { \
- Catch::handleExceptionMatchExpr( catchAssertionHandler, matcher, #matcher##_catch_sr ); \
- } \
- else \
- catchAssertionHandler.handleThrowingCallSkipped(); \
- INTERNAL_CATCH_REACT( catchAssertionHandler ) \
- } while( false )
-
-#endif // CATCH_CONFIG_DISABLE
-
-// end catch_capture.hpp
-// start catch_section.h
-
-// start catch_section_info.h
-
-// start catch_totals.h
-
-#include
-
-namespace Catch {
-
- struct Counts {
- Counts operator - ( Counts const& other ) const;
- Counts& operator += ( Counts const& other );
-
- std::size_t total() const;
- bool allPassed() const;
- bool allOk() const;
-
- std::size_t passed = 0;
- std::size_t failed = 0;
- std::size_t failedButOk = 0;
- };
-
- struct Totals {
-
- Totals operator - ( Totals const& other ) const;
- Totals& operator += ( Totals const& other );
-
- Totals delta( Totals const& prevTotals ) const;
-
- int error = 0;
- Counts assertions;
- Counts testCases;
- };
-}
-
-// end catch_totals.h
-#include
-
-namespace Catch {
-
- struct SectionInfo {
- SectionInfo
- ( SourceLineInfo const& _lineInfo,
- std::string const& _name );
-
- // Deprecated
- SectionInfo
- ( SourceLineInfo const& _lineInfo,
- std::string const& _name,
- std::string const& ) : SectionInfo( _lineInfo, _name ) {}
-
- std::string name;
- std::string description; // !Deprecated: this will always be empty
- SourceLineInfo lineInfo;
- };
-
- struct SectionEndInfo {
- SectionInfo sectionInfo;
- Counts prevAssertions;
- double durationInSeconds;
- };
-
-} // end namespace Catch
-
-// end catch_section_info.h
-// start catch_timer.h
-
-#include
-
-namespace Catch {
-
- auto getCurrentNanosecondsSinceEpoch() -> uint64_t;
- auto getEstimatedClockResolution() -> uint64_t;
-
- class Timer {
- uint64_t m_nanoseconds = 0;
- public:
- void start();
- auto getElapsedNanoseconds() const -> uint64_t;
- auto getElapsedMicroseconds() const -> uint64_t;
- auto getElapsedMilliseconds() const -> unsigned int;
- auto getElapsedSeconds() const -> double;
- };
-
-} // namespace Catch
-
-// end catch_timer.h
-#include
-
-namespace Catch {
-
- class Section : NonCopyable {
- public:
- Section( SectionInfo const& info );
- ~Section();
-
- // This indicates whether the section should be executed or not
- explicit operator bool() const;
-
- private:
- SectionInfo m_info;
-
- std::string m_name;
- Counts m_assertions;
- bool m_sectionIncluded;
- Timer m_timer;
- };
-
-} // end namespace Catch
-
-#define INTERNAL_CATCH_SECTION( ... ) \
- CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
- if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) \
- CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS
-
-#define INTERNAL_CATCH_DYNAMIC_SECTION( ... ) \
- CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
- if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, (Catch::ReusableStringStream() << __VA_ARGS__).str() ) ) \
- CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS
-
-// end catch_section.h
-// start catch_benchmark.h
-
-#include
-#include
-
-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
-
-#include
-#include
-
-namespace Catch {
-
- class TestCase;
- struct ITestCaseRegistry;
- struct IExceptionTranslatorRegistry;
- struct IExceptionTranslator;
- struct IReporterRegistry;
- struct IReporterFactory;
- struct ITagAliasRegistry;
- class StartupExceptionRegistry;
-
- using IReporterFactoryPtr = std::shared_ptr;
-
- struct IRegistryHub {
- virtual ~IRegistryHub();
-
- 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;
- };
-
- struct IMutableRegistryHub {
- virtual ~IMutableRegistryHub();
- virtual void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) = 0;
- virtual void registerListener( IReporterFactoryPtr const& factory ) = 0;
- virtual void registerTest( TestCase const& testInfo ) = 0;
- 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;
- };
-
- IRegistryHub const& getRegistryHub();
- IMutableRegistryHub& getMutableRegistryHub();
- void cleanUp();
- std::string translateActiveException();
-
-}
-
-// end catch_interfaces_registry_hub.h
-#if defined(CATCH_CONFIG_DISABLE)
- #define INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( translatorName, signature) \
- static std::string translatorName( signature )
-#endif
-
-#include
-#include
-#include
-
-namespace Catch {
- using exceptionTranslateFunction = std::string(*)();
-
- struct IExceptionTranslator;
- using ExceptionTranslators = std::vector>;
-
- struct IExceptionTranslator {
- virtual ~IExceptionTranslator();
- virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0;
- };
-
- struct IExceptionTranslatorRegistry {
- virtual ~IExceptionTranslatorRegistry();
-
- virtual std::string translateActiveException() const = 0;
- };
-
- class ExceptionTranslatorRegistrar {
- template