convergence_best #27

Merged
rmontanana merged 5 commits from convergence_best into main 2024-04-30 16:22:09 +00:00
43 changed files with 565 additions and 285 deletions
Showing only changes of commit 23ef0cc5f7 - Show all commits

5
.gitmodules vendored
View File

@ -3,11 +3,6 @@
url = https://github.com/rmontanana/mdlp
main = main
update = merge
[submodule "tests/lib/catch2"]
path = tests/lib/catch2
main = v2.x
update = merge
url = https://github.com/catchorg/Catch2.git
[submodule "lib/json"]
path = lib/json
url = https://github.com/nlohmann/json.git

View File

@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Refactor library ArffFile to limit the number of samples with a parameter.
- Refactor tests libraries location to test/lib
- Refactor loadDataset function in tests.
- Remove conditionalEdgeWeights method in BayesMetrics.
## [1.0.5] 2024-04-20
@ -39,6 +40,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- The worse model count in BoostAODE is reset to 0 every time a new model produces better accuracy, so the tolerance of the model is meant to be the number of **consecutive** models that produce worse accuracy.
- Default hyperparameter values in BoostAODE: bisection is true, maxTolerance is 3, convergence is true
### Removed
- The 'predict_single' hyperparameter from the BoostAODE class.
- The 'repeatSparent' hyperparameter from the BoostAODE class.
## [1.0.4] 2024-03-06
### Added

View File

@ -72,7 +72,7 @@ add_subdirectory(bayesnet)
# -------
if (ENABLE_TESTING)
MESSAGE("Testing enabled")
add_git_submodule("tests/lib/catch2")
add_subdirectory("tests/lib/catch2")
add_subdirectory(tests/lib/Files)
include(CTest)
add_subdirectory(tests)

View File

@ -75,4 +75,4 @@ make sample fname=tests/data/glass.arff
## Coverage report
[Coverage report](html/index.html)
### [Coverage report](docs/coverage.pdf)

View File

@ -11,19 +11,19 @@
#include "bayesnet/feature_selection/FeatureSelect.h"
#include "Ensemble.h"
namespace bayesnet {
struct {
const struct {
std::string CFS = "CFS";
std::string FCBF = "FCBF";
std::string IWSS = "IWSS";
}SelectFeatures;
struct {
const struct {
std::string ASC = "asc";
std::string DESC = "desc";
std::string RAND = "rand";
}Orders;
class BoostAODE : public Ensemble {
public:
BoostAODE(bool predict_voting = false);
explicit BoostAODE(bool predict_voting = false);
virtual ~BoostAODE() = default;
std::vector<std::string> graph(const std::string& title = "BoostAODE") const override;
void setHyperparameters(const nlohmann::json& hyperparameters_) override;

View File

@ -10,17 +10,17 @@ namespace bayesnet {
//samples is n+1xm tensor used to fit the model
Metrics::Metrics(const torch::Tensor& samples, const std::vector<std::string>& features, const std::string& className, const int classNumStates)
: samples(samples)
, features(features)
, className(className)
, features(features)
, classNumStates(classNumStates)
{
}
//samples is n+1xm std::vector used to fit the model
Metrics::Metrics(const std::vector<std::vector<int>>& vsamples, const std::vector<int>& labels, const std::vector<std::string>& features, const std::string& className, const int classNumStates)
: features(features)
: samples(torch::zeros({ static_cast<int>(vsamples.size() + 1), static_cast<int>(vsamples[0].size()) }, torch::kInt32))
, className(className)
, features(features)
, classNumStates(classNumStates)
, samples(torch::zeros({ static_cast<int>(vsamples.size() + 1), static_cast<int>(vsamples[0].size()) }, torch::kInt32))
{
for (int i = 0; i < vsamples.size(); ++i) {
samples.index_put_({ i, "..." }, torch::tensor(vsamples[i], torch::kInt32));
@ -105,14 +105,6 @@ namespace bayesnet {
}
return matrix;
}
// To use in Python
std::vector<float> Metrics::conditionalEdgeWeights(std::vector<float>& weights_)
{
const torch::Tensor weights = torch::tensor(weights_);
auto matrix = conditionalEdge(weights);
std::vector<float> v(matrix.data_ptr<float>(), matrix.data_ptr<float>() + matrix.numel());
return v;
}
double Metrics::entropy(const torch::Tensor& feature, const torch::Tensor& weights)
{
torch::Tensor counts = feature.bincount(weights);

View File

@ -18,7 +18,6 @@ namespace bayesnet {
std::vector<int> SelectKBestWeighted(const torch::Tensor& weights, bool ascending = false, unsigned k = 0);
std::vector<double> getScoresKBest() const;
double mutualInformation(const torch::Tensor& firstFeature, const torch::Tensor& secondFeature, const torch::Tensor& weights);
std::vector<float> conditionalEdgeWeights(std::vector<float>& weights); // To use in Python
torch::Tensor conditionalEdge(const torch::Tensor& weights);
std::vector<std::pair<int, int>> maximumSpanningTree(const std::vector<std::string>& features, const torch::Tensor& weights, const int root);
protected:

BIN
docs/coverage.pdf Normal file

Binary file not shown.

View File

@ -140,21 +140,20 @@ TEST_CASE("Oddities", "[BoostAODE]")
TEST_CASE("Bisection Best", "[BoostAODE]")
{
auto clf = bayesnet::BoostAODE();
auto raw = RawDatasets("mfeat-factors", true, 300, true);
auto raw = RawDatasets("kdd_JapaneseVowels", true, 1200, true, false);
clf.setHyperparameters({
{"bisection", true},
{"maxTolerance", 3},
{"convergence", true},
{"block_update", false},
{"convergence_best", true},
{"convergence_best", false},
});
clf.fit(raw.X_train, raw.y_train, raw.features, raw.className, raw.states);
REQUIRE(clf.getNumberOfNodes() == 434);
REQUIRE(clf.getNumberOfEdges() == 862);
REQUIRE(clf.getNotes().size() == 3);
REQUIRE(clf.getNotes()[0] == "Convergence threshold reached & 15 models eliminated");
REQUIRE(clf.getNotes()[1] == "Used features in train: 16 of 216");
REQUIRE(clf.getNotes()[2] == "Number of models: 1");
REQUIRE(clf.getNumberOfNodes() == 75);
REQUIRE(clf.getNumberOfEdges() == 135);
REQUIRE(clf.getNotes().size() == 2);
REQUIRE(clf.getNotes().at(0) == "Convergence threshold reached & 9 models eliminated");
REQUIRE(clf.getNotes().at(1) == "Number of models: 5");
auto score = clf.score(raw.X_test, raw.y_test);
auto scoret = clf.score(raw.X_test, raw.y_test);
REQUIRE(score == Catch::Approx(1.0f).epsilon(raw.epsilon));
@ -162,11 +161,9 @@ TEST_CASE("Bisection Best", "[BoostAODE]")
}
TEST_CASE("Bisection Best vs Last", "[BoostAODE]")
{
auto raw = RawDatasets("mfeat-factors", true, 500);
auto raw = RawDatasets("kdd_JapaneseVowels", true, 1500, true, false);
auto clf = bayesnet::BoostAODE(true);
auto hyperparameters = nlohmann::json{
{"select_features", "IWSS"},
{"threshold", 0.5},
{"bisection", true},
{"maxTolerance", 3},
{"convergence", true},
@ -175,13 +172,13 @@ TEST_CASE("Bisection Best vs Last", "[BoostAODE]")
clf.setHyperparameters(hyperparameters);
clf.fit(raw.X_train, raw.y_train, raw.features, raw.className, raw.states);
auto score_best = clf.score(raw.X_test, raw.y_test);
REQUIRE(score_best == Catch::Approx(1.0f).epsilon(raw.epsilon));
REQUIRE(score_best == Catch::Approx(0.993355f).epsilon(raw.epsilon));
// Now we will set the hyperparameter to use the last accuracy
hyperparameters["convergence_best"] = false;
clf.setHyperparameters(hyperparameters);
clf.fit(raw.X_train, raw.y_train, raw.features, raw.className, raw.states);
auto score_last = clf.score(raw.X_test, raw.y_test);
REQUIRE(score_last == Catch::Approx(1.0f).epsilon(raw.epsilon));
REQUIRE(score_last == Catch::Approx(0.996678f).epsilon(raw.epsilon));
}
TEST_CASE("Block Update", "[BoostAODE]")
@ -195,14 +192,22 @@ TEST_CASE("Block Update", "[BoostAODE]")
{"convergence", true},
});
clf.fit(raw.X_train, raw.y_train, raw.features, raw.className, raw.states);
REQUIRE(clf.getNumberOfNodes() == 217);
REQUIRE(clf.getNumberOfEdges() == 431);
REQUIRE(clf.getNumberOfNodes() == 868);
REQUIRE(clf.getNumberOfEdges() == 1724);
REQUIRE(clf.getNotes().size() == 3);
REQUIRE(clf.getNotes()[0] == "Convergence threshold reached & 15 models eliminated");
REQUIRE(clf.getNotes()[1] == "Used features in train: 16 of 216");
REQUIRE(clf.getNotes()[2] == "Number of models: 1");
REQUIRE(clf.getNotes()[1] == "Used features in train: 19 of 216");
REQUIRE(clf.getNotes()[2] == "Number of models: 4");
auto score = clf.score(raw.X_test, raw.y_test);
auto scoret = clf.score(raw.X_test, raw.y_test);
REQUIRE(score == Catch::Approx(1.0f).epsilon(raw.epsilon));
REQUIRE(scoret == Catch::Approx(1.0f).epsilon(raw.epsilon));
REQUIRE(score == Catch::Approx(0.99f).epsilon(raw.epsilon));
REQUIRE(scoret == Catch::Approx(0.99f).epsilon(raw.epsilon));
//
// std::cout << "Number of nodes " << clf.getNumberOfNodes() << std::endl;
// std::cout << "Number of edges " << clf.getNumberOfEdges() << std::endl;
// std::cout << "Notes size " << clf.getNotes().size() << std::endl;
// for (auto note : clf.getNotes()) {
// std::cout << note << std::endl;
// }
// std::cout << "Score " << score << std::endl;
}

View File

@ -18,23 +18,23 @@ public:
class ShuffleArffFiles : public ArffFiles {
public:
ShuffleArffFiles(int num_lines = 0, bool shuffle = false) : ArffFiles(), num_lines(num_lines), shuffle(shuffle) {}
ShuffleArffFiles(int num_samples = 0, bool shuffle = false) : ArffFiles(), num_samples(num_samples), shuffle(shuffle) {}
void load(const std::string& file_name, bool class_last = true)
{
ArffFiles::load(file_name, class_last);
if (num_lines > 0) {
if (num_lines > getY().size()) {
if (num_samples > 0) {
if (num_samples > getY().size()) {
throw std::invalid_argument("num_lines must be less than the number of lines in the file");
}
auto indices = std::vector<int>(num_lines);
auto indices = std::vector<int>(num_samples);
std::iota(indices.begin(), indices.end(), 0);
if (shuffle) {
std::mt19937 g{ 173 };
std::shuffle(indices.begin(), indices.end(), g);
}
auto XX = std::vector<std::vector<float>>(attributes.size(), std::vector<float>(num_lines));
auto yy = std::vector<int>(num_lines);
for (int i = 0; i < num_lines; i++) {
auto XX = std::vector<std::vector<float>>(attributes.size(), std::vector<float>(num_samples));
auto yy = std::vector<int>(num_samples);
for (int i = 0; i < num_samples; i++) {
yy[i] = getY()[indices[i]];
for (int j = 0; j < attributes.size(); j++) {
XX[j][i] = X[j][indices[i]];
@ -45,18 +45,18 @@ public:
}
}
private:
int num_lines;
int num_samples;
bool shuffle;
};
RawDatasets::RawDatasets(const std::string& file_name, bool discretize_, int num_lines_, bool shuffle_)
RawDatasets::RawDatasets(const std::string& file_name, bool discretize_, int num_samples_, bool shuffle_, bool class_last, bool debug)
{
num_lines = num_lines_;
num_samples = num_samples_;
shuffle = shuffle_;
discretize = discretize_;
// Xt can be either discretized or not
// Xv is always discretized
loadDataset(file_name);
loadDataset(file_name, class_last);
auto yresized = torch::transpose(yt.view({ yt.size(0), 1 }), 0, 1);
dataset = torch::cat({ Xt, yresized }, 0);
nSamples = dataset.size(1);
@ -72,7 +72,8 @@ RawDatasets::RawDatasets(const std::string& file_name, bool discretize_, int num
y_train = dataset.index({ -1, train_t });
X_test = dataset.index({ torch::indexing::Slice(0, dataset.size(0) - 1), test_t });
y_test = dataset.index({ -1, test_t });
std::cout << to_string();
if (debug)
std::cout << to_string();
}
map<std::string, int> RawDatasets::discretizeDataset(std::vector<mdlp::samples_t>& X)
@ -89,10 +90,10 @@ map<std::string, int> RawDatasets::discretizeDataset(std::vector<mdlp::samples_t
return maxes;
}
void RawDatasets::loadDataset(const std::string& name)
void RawDatasets::loadDataset(const std::string& name, bool class_last)
{
auto handler = ShuffleArffFiles(num_lines, shuffle);
handler.load(Paths::datasets() + static_cast<std::string>(name) + ".arff", true);
auto handler = ShuffleArffFiles(num_samples, shuffle);
handler.load(Paths::datasets() + static_cast<std::string>(name) + ".arff", class_last);
// Get Dataset X, y
std::vector<mdlp::samples_t>& X = handler.getX();
yv = handler.getY();

View File

@ -18,7 +18,7 @@
class RawDatasets {
public:
RawDatasets(const std::string& file_name, bool discretize_, int num_lines_ = 0, bool shuffle_ = false);
RawDatasets(const std::string& file_name, bool discretize_, int num_samples_ = 0, bool shuffle_ = false, bool class_last = true, bool debug = false);
torch::Tensor Xt, yt, dataset, weights;
torch::Tensor X_train, y_train, X_test, y_test;
std::vector<vector<int>> Xv;
@ -30,7 +30,7 @@ public:
int nSamples, classNumStates;
double epsilon = 1e-5;
bool discretize;
int num_lines = 0;
int num_samples = 0;
bool shuffle = false;
private:
std::string to_string()
@ -62,11 +62,9 @@ private:
+ "nSamples: " + std::to_string(nSamples) + "\n"
+ "classNumStates: " + std::to_string(classNumStates) + "\n"
+ "states: " + states_ + "\n";
}
map<std::string, int> discretizeDataset(std::vector<mdlp::samples_t>& X);
void loadDataset(const std::string& name);
void loadDataset(const std::string& name, bool class_last);
};
#endif //TEST_UTILS_H

View File

@ -0,0 +1,44 @@
name: M1 Mac builds
on: [push, pull_request]
jobs:
build:
runs-on: macos-14
strategy:
matrix:
cxx:
- clang++
build_type: [Debug, Release]
std: [14, 17]
include:
- build_type: Debug
examples: ON
extra_tests: ON
steps:
- uses: actions/checkout@v4
- name: Configure build
working-directory: ${{runner.workspace}}
env:
CXX: ${{matrix.cxx}}
CXXFLAGS: ${{matrix.cxxflags}}
run: |
cmake -Bbuild -H$GITHUB_WORKSPACE \
-DCMAKE_BUILD_TYPE=${{matrix.build_type}} \
-DCMAKE_CXX_STANDARD=${{matrix.std}} \
-DCMAKE_CXX_STANDARD_REQUIRED=ON \
-DCATCH_DEVELOPMENT_BUILD=ON \
-DCATCH_BUILD_EXAMPLES=${{matrix.examples}} \
-DCATCH_BUILD_EXTRA_TESTS=${{matrix.examples}}
- name: Build tests + lib
working-directory: ${{runner.workspace}}/build
run: make -j `sysctl -n hw.ncpu`
- name: Run tests
env:
CTEST_OUTPUT_ON_FAILURE: 1
working-directory: ${{runner.workspace}}/build
run: ctest -C ${{matrix.build_type}} -j `sysctl -n hw.ncpu`

View File

@ -27,6 +27,7 @@ benchmark-dir
.conan/test_package/build
.conan/test_package/CMakeUserPresets.json
bazel-*
MODULE.bazel.lock
build-fuzzers
debug-build
.vscode

View File

@ -33,7 +33,7 @@ if (CMAKE_BINARY_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
endif()
project(Catch2
VERSION 3.5.3 # CML version placeholder, don't delete
VERSION 3.5.4 # CML version placeholder, don't delete
LANGUAGES CXX
# HOMEPAGE_URL is not supported until CMake version 3.12, which
# we do not target yet.
@ -76,8 +76,6 @@ endif()
set(CATCH_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(SOURCES_DIR ${CATCH_DIR}/src/catch2)
set(SELF_TEST_DIR ${CATCH_DIR}/tests/SelfTest)
set(BENCHMARK_DIR ${CATCH_DIR}/tests/Benchmark)
set(EXAMPLES_DIR ${CATCH_DIR}/examples)
# We need to bring-in the variables defined there to this scope
add_subdirectory(src)

View File

@ -19,6 +19,7 @@ class CatchConan(ConanFile):
license = "BSL-1.0"
version = "latest"
settings = "os", "compiler", "build_type", "arch"
extension_properties = {"compatibility_cppstd": False}
options = {
"shared": [True, False],
@ -115,6 +116,7 @@ class CatchConan(ConanFile):
# Catch2
self.cpp_info.components["catch2base"].set_property("cmake_file_name", "Catch2::Catch2")
self.cpp_info.components["catch2base"].set_property("cmake_target_name", "Catch2::Catch2")
self.cpp_info.components["catch2base"].set_property("pkg_config_name", "catch2")
self.cpp_info.components["catch2base"].libs = ["Catch2" + lib_suffix]
self.cpp_info.components["catch2base"].builddirs.append("lib/cmake/Catch2")

View File

@ -2,6 +2,7 @@
# Release notes
**Contents**<br>
[3.5.4](#354)<br>
[3.5.3](#353)<br>
[3.5.2](#352)<br>
[3.5.1](#351)<br>
@ -61,6 +62,29 @@
[Even Older versions](#even-older-versions)<br>
## 3.5.4
### Fixes
* Fixed potential compilation error when asked to generate random integers whose type did not match `std::(u)int*_t`.
* This manifested itself when generating random `size_t`s on MacOS
* Added missing outlined destructor causing `Wdelete-incomplete` when compiling against libstdc++ in C++23 mode (#2852)
* Fixed regression where decomposing assertion with const instance of `std::foo_ordering` would not compile
### Improvements
* Reintroduced support for GCC 5 and 6 (#2836)
* As with VS2017, if they start causing trouble again, they will be dropped again.
* Added workaround for targetting newest MacOS (Sonoma) using GCC (#2837, #2839)
* `CATCH_CONFIG_DEFAULT_REPORTER` can now be an arbitrary reporter spec
* Previously it could only be a plain reporter name, so it was impossible to compile in custom arguments to the reporter.
* Improved performance of generating 64bit random integers by 20+%
### Miscellaneous
* Significantly improved Conan in-tree recipe (#2831)
* `DL_PATHS` in `catch_discover_tests` now supports multiple arguments (#2852, #2736)
* Fixed preprocessor logic for checking whether we expect reproducible floating point results in tests.
* Improved the floating point tests structure to avoid `Wunused` when the reproducibility tests are disabled (#2845)
## 3.5.3
### Fixes

View File

@ -43,8 +43,7 @@ set( TARGETS_IDIOMATIC_EXAMPLES ${BASENAMES_IDIOMATIC_EXAMPLES} )
foreach( name ${TARGETS_IDIOMATIC_EXAMPLES} )
add_executable( ${name}
${EXAMPLES_DIR}/${name}.cpp )
add_executable( ${name} ${name}.cpp )
endforeach()
set(ALL_EXAMPLE_TARGETS

View File

@ -6,8 +6,8 @@
// SPDX-License-Identifier: BSL-1.0
// Catch v3.5.3
// Generated: 2024-03-01 22:05:56.038084
// Catch v3.5.4
// Generated: 2024-04-10 12:03:46.281848
// ----------------------------------------------------------
// This file is an amalgamation of multiple different files.
// You probably shouldn't edit it directly.
@ -187,7 +187,7 @@ namespace Catch {
double const* last,
Estimator& estimator ) {
auto n = static_cast<size_t>( last - first );
std::uniform_int_distribution<size_t> dist( 0, n - 1 );
Catch::uniform_integer_distribution<size_t> dist( 0, n - 1 );
sample out;
out.reserve( resamples );
@ -807,14 +807,16 @@ namespace Catch {
// Insert the default reporter if user hasn't asked for a specific one
if ( m_data.reporterSpecifications.empty() ) {
m_data.reporterSpecifications.push_back( {
#if defined( CATCH_CONFIG_DEFAULT_REPORTER )
CATCH_CONFIG_DEFAULT_REPORTER,
const auto default_spec = CATCH_CONFIG_DEFAULT_REPORTER;
#else
"console",
const auto default_spec = "console";
#endif
{}, {}, {}
} );
auto parsed = parseReporterSpec(default_spec);
CATCH_ENFORCE( parsed,
"Cannot parse the provided default reporter spec: '"
<< default_spec << '\'' );
m_data.reporterSpecifications.push_back( std::move( *parsed ) );
}
if ( enableBazelEnvSupport() ) {
@ -2271,7 +2273,7 @@ namespace Catch {
}
Version const& libraryVersion() {
static Version version( 3, 5, 3, "", 0 );
static Version version( 3, 5, 4, "", 0 );
return version;
}
@ -6601,6 +6603,8 @@ namespace Catch {
return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config );
}
TestRegistry::~TestRegistry() = default;
void TestRegistry::registerTest(Detail::unique_ptr<TestCaseInfo> testInfo, Detail::unique_ptr<ITestInvoker> testInvoker) {
m_handles.emplace_back(testInfo.get(), testInvoker.get());
m_viewed_test_infos.push_back(testInfo.get());

View File

@ -6,8 +6,8 @@
// SPDX-License-Identifier: BSL-1.0
// Catch v3.5.3
// Generated: 2024-03-01 22:05:55.031514
// Catch v3.5.4
// Generated: 2024-04-10 12:03:45.785902
// ----------------------------------------------------------
// This file is an amalgamation of multiple different files.
// You probably shouldn't edit it directly.
@ -87,6 +87,9 @@
// See e.g.:
// https://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/TargetConditionals.h.auto.html
#ifdef __APPLE__
# ifndef __has_extension
# define __has_extension(x) 0
# endif
# include <TargetConditionals.h>
# if (defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1) || \
(defined(TARGET_OS_MAC) && TARGET_OS_MAC == 1)
@ -5254,6 +5257,12 @@ namespace Detail {
namespace Catch {
namespace Detail {
// This was added in C++20, but we require only C++14 for now.
template <typename T>
using RemoveCVRef_t = std::remove_cv_t<std::remove_reference_t<T>>;
}
// Note: There is nothing that stops us from extending this,
// e.g. to `std::is_scalar`, but the more encompassing
// traits are usually also more expensive. For now we
@ -5293,14 +5302,13 @@ namespace Catch {
ITransientExpression(ITransientExpression const&) = default;
ITransientExpression& operator=(ITransientExpression const&) = default;
// We don't actually need a virtual destructor, but many static analysers
// complain if it's not here :-(
virtual ~ITransientExpression() = default;
friend std::ostream& operator<<(std::ostream& out, ITransientExpression const& expr) {
expr.streamReconstructedExpression(out);
return out;
}
protected:
~ITransientExpression() = default;
};
void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs );
@ -5406,17 +5414,17 @@ namespace Catch {
#define CATCH_INTERNAL_DEFINE_EXPRESSION_EQUALITY_OPERATOR( id, op ) \
template <typename RhsT> \
constexpr friend auto operator op( ExprLhs&& lhs, RhsT&& rhs ) \
->std::enable_if_t< \
-> std::enable_if_t< \
Detail::conjunction<Detail::is_##id##_comparable<LhsT, RhsT>, \
Detail::negation<capture_by_value< \
std::remove_reference_t<RhsT>>>>::value, \
Detail::RemoveCVRef_t<RhsT>>>>::value, \
BinaryExpr<LhsT, RhsT const&>> { \
return { \
static_cast<bool>( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
} \
template <typename RhsT> \
constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
->std::enable_if_t< \
-> std::enable_if_t< \
Detail::conjunction<Detail::is_##id##_comparable<LhsT, RhsT>, \
capture_by_value<RhsT>>::value, \
BinaryExpr<LhsT, RhsT>> { \
@ -5425,7 +5433,7 @@ namespace Catch {
} \
template <typename RhsT> \
constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
->std::enable_if_t< \
-> std::enable_if_t< \
Detail::conjunction< \
Detail::negation<Detail::is_##id##_comparable<LhsT, RhsT>>, \
Detail::is_eq_0_comparable<LhsT>, \
@ -5439,7 +5447,7 @@ namespace Catch {
} \
template <typename RhsT> \
constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
->std::enable_if_t< \
-> std::enable_if_t< \
Detail::conjunction< \
Detail::negation<Detail::is_##id##_comparable<LhsT, RhsT>>, \
Detail::is_eq_0_comparable<RhsT>, \
@ -5460,17 +5468,17 @@ namespace Catch {
#define CATCH_INTERNAL_DEFINE_EXPRESSION_COMPARISON_OPERATOR( id, op ) \
template <typename RhsT> \
constexpr friend auto operator op( ExprLhs&& lhs, RhsT&& rhs ) \
->std::enable_if_t< \
-> std::enable_if_t< \
Detail::conjunction<Detail::is_##id##_comparable<LhsT, RhsT>, \
Detail::negation<capture_by_value< \
std::remove_reference_t<RhsT>>>>::value, \
Detail::RemoveCVRef_t<RhsT>>>>::value, \
BinaryExpr<LhsT, RhsT const&>> { \
return { \
static_cast<bool>( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
} \
template <typename RhsT> \
constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
->std::enable_if_t< \
-> std::enable_if_t< \
Detail::conjunction<Detail::is_##id##_comparable<LhsT, RhsT>, \
capture_by_value<RhsT>>::value, \
BinaryExpr<LhsT, RhsT>> { \
@ -5479,7 +5487,7 @@ namespace Catch {
} \
template <typename RhsT> \
constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
->std::enable_if_t< \
-> std::enable_if_t< \
Detail::conjunction< \
Detail::negation<Detail::is_##id##_comparable<LhsT, RhsT>>, \
Detail::is_##id##_0_comparable<LhsT>, \
@ -5491,7 +5499,7 @@ namespace Catch {
} \
template <typename RhsT> \
constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
->std::enable_if_t< \
-> std::enable_if_t< \
Detail::conjunction< \
Detail::negation<Detail::is_##id##_comparable<LhsT, RhsT>>, \
Detail::is_##id##_0_comparable<RhsT>, \
@ -5512,16 +5520,16 @@ namespace Catch {
#define CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR( op ) \
template <typename RhsT> \
constexpr friend auto operator op( ExprLhs&& lhs, RhsT&& rhs ) \
->std::enable_if_t< \
!capture_by_value<std::remove_reference_t<RhsT>>::value, \
-> std::enable_if_t< \
!capture_by_value<Detail::RemoveCVRef_t<RhsT>>::value, \
BinaryExpr<LhsT, RhsT const&>> { \
return { \
static_cast<bool>( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
} \
template <typename RhsT> \
constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
->std::enable_if_t<capture_by_value<RhsT>::value, \
BinaryExpr<LhsT, RhsT>> { \
-> std::enable_if_t<capture_by_value<RhsT>::value, \
BinaryExpr<LhsT, RhsT>> { \
return { \
static_cast<bool>( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
}
@ -5553,8 +5561,7 @@ namespace Catch {
struct Decomposer {
template <typename T,
std::enable_if_t<
!capture_by_value<std::remove_reference_t<T>>::value,
std::enable_if_t<!capture_by_value<Detail::RemoveCVRef_t<T>>::value,
int> = 0>
constexpr friend auto operator <= ( Decomposer &&, T && lhs ) -> ExprLhs<T const&> {
return ExprLhs<const T&>{ lhs };
@ -7263,7 +7270,7 @@ namespace Catch {
#define CATCH_VERSION_MAJOR 3
#define CATCH_VERSION_MINOR 5
#define CATCH_VERSION_PATCH 3
#define CATCH_VERSION_PATCH 4
#endif // CATCH_VERSION_MACROS_HPP_INCLUDED
@ -7935,6 +7942,32 @@ namespace Catch {
#include <cstdint>
#include <type_traits>
// Note: We use the usual enable-disable-autodetect dance here even though
// we do not support these in CMake configuration options (yet?).
// It is highly unlikely that we will need to make these actually
// user-configurable, but this will make it simpler if weend up needing
// it, and it provides an escape hatch to the users who need it.
#if defined( __SIZEOF_INT128__ )
# define CATCH_CONFIG_INTERNAL_UINT128
#elif defined( _MSC_VER ) && ( defined( _WIN64 ) || defined( _M_ARM64 ) )
# define CATCH_CONFIG_INTERNAL_MSVC_UMUL128
#endif
#if defined( CATCH_CONFIG_INTERNAL_UINT128 ) && \
!defined( CATCH_CONFIG_NO_UINT128 ) && \
!defined( CATCH_CONFIG_UINT128 )
#define CATCH_CONFIG_UINT128
#endif
#if defined( CATCH_CONFIG_INTERNAL_MSVC_UMUL128 ) && \
!defined( CATCH_CONFIG_NO_MSVC_UMUL128 ) && \
!defined( CATCH_CONFIG_MSVC_UMUL128 )
# define CATCH_CONFIG_MSVC_UMUL128
# include <intrin.h>
# pragma intrinsic( _umul128 )
#endif
namespace Catch {
namespace Detail {
@ -7967,59 +8000,52 @@ namespace Catch {
}
};
// Returns 128 bit result of multiplying lhs and rhs
/**
* Returns 128 bit result of lhs * rhs using portable C++ code
*
* This implementation is almost twice as fast as naive long multiplication,
* and unlike intrinsic-based approach, it supports constexpr evaluation.
*/
constexpr ExtendedMultResult<std::uint64_t>
extendedMult( std::uint64_t lhs, std::uint64_t rhs ) {
// We use the simple long multiplication approach for
// correctness, we can use platform specific builtins
// for performance later.
// Split the lhs and rhs into two 32bit "digits", so that we can
// do 64 bit arithmetic to handle carry bits.
// 32b 32b 32b 32b
// lhs L1 L2
// * rhs R1 R2
// ------------------------
// | R2 * L2 |
// | R2 * L1 |
// | R1 * L2 |
// | R1 * L1 |
// -------------------------
// | a | b | c | d |
extendedMultPortable(std::uint64_t lhs, std::uint64_t rhs) {
#define CarryBits( x ) ( x >> 32 )
#define Digits( x ) ( x & 0xFF'FF'FF'FF )
std::uint64_t lhs_low = Digits( lhs );
std::uint64_t rhs_low = Digits( rhs );
std::uint64_t low_low = ( lhs_low * rhs_low );
std::uint64_t high_high = CarryBits( lhs ) * CarryBits( rhs );
auto r2l2 = Digits( rhs ) * Digits( lhs );
auto r2l1 = Digits( rhs ) * CarryBits( lhs );
auto r1l2 = CarryBits( rhs ) * Digits( lhs );
auto r1l1 = CarryBits( rhs ) * CarryBits( lhs );
// Sum to columns first
auto d = Digits( r2l2 );
auto c = CarryBits( r2l2 ) + Digits( r2l1 ) + Digits( r1l2 );
auto b = CarryBits( r2l1 ) + CarryBits( r1l2 ) + Digits( r1l1 );
auto a = CarryBits( r1l1 );
// Propagate carries between columns
c += CarryBits( d );
b += CarryBits( c );
a += CarryBits( b );
// Remove the used carries
c = Digits( c );
b = Digits( b );
a = Digits( a );
// We add in carry bits from low-low already
std::uint64_t high_low =
( CarryBits( lhs ) * rhs_low ) + CarryBits( low_low );
// Note that we can add only low bits from high_low, to avoid
// overflow with large inputs
std::uint64_t low_high =
( lhs_low * CarryBits( rhs ) ) + Digits( high_low );
return { high_high + CarryBits( high_low ) + CarryBits( low_high ),
( low_high << 32 ) | Digits( low_low ) };
#undef CarryBits
#undef Digits
return {
a << 32 | b, // upper 64 bits
c << 32 | d // lower 64 bits
};
}
//! Returns 128 bit result of lhs * rhs
inline ExtendedMultResult<std::uint64_t>
extendedMult( std::uint64_t lhs, std::uint64_t rhs ) {
#if defined( CATCH_CONFIG_UINT128 )
auto result = __uint128_t( lhs ) * __uint128_t( rhs );
return { static_cast<std::uint64_t>( result >> 64 ),
static_cast<std::uint64_t>( result ) };
#elif defined( CATCH_CONFIG_MSVC_UMUL128 )
std::uint64_t high;
std::uint64_t low = _umul128( lhs, rhs, &high );
return { high, low };
#else
return extendedMultPortable( lhs, rhs );
#endif
}
template <typename UInt>
constexpr ExtendedMultResult<UInt> extendedMult( UInt lhs, UInt rhs ) {
static_assert( std::is_unsigned<UInt>::value,
@ -8123,22 +8149,6 @@ namespace Catch {
namespace Catch {
namespace Detail {
// Indirection to enable make_unsigned<bool> behaviour.
template <typename T>
struct make_unsigned {
using type = std::make_unsigned_t<T>;
};
template <>
struct make_unsigned<bool> {
using type = uint8_t;
};
template <typename T>
using make_unsigned_t = typename make_unsigned<T>::type;
}
/**
* Implementation of uniform distribution on integers.
*
@ -8154,7 +8164,7 @@ template <typename IntegerType>
class uniform_integer_distribution {
static_assert(std::is_integral<IntegerType>::value, "...");
using UnsignedIntegerType = Detail::make_unsigned_t<IntegerType>;
using UnsignedIntegerType = Detail::SizedUnsignedType_t<sizeof(IntegerType)>;
// Only the left bound is stored, and we store it converted to its
// unsigned image. This avoids having to do the conversions inside
@ -10823,6 +10833,8 @@ namespace Catch {
std::vector<TestCaseHandle> const& getAllTests() const override;
std::vector<TestCaseHandle> const& getAllTestsSorted( IConfig const& config ) const override;
~TestRegistry() override; // = default
private:
std::vector<Detail::unique_ptr<TestCaseInfo>> m_owned_test_infos;
// Keeps a materialized vector for `getAllInfos`.

View File

@ -8,7 +8,7 @@
project(
'catch2',
'cpp',
version: '3.5.3', # CML version placeholder, don't delete
version: '3.5.4', # CML version placeholder, don't delete
license: 'BSL-1.0',
meson_version: '>=0.54.1',
)

View File

@ -36,7 +36,7 @@ namespace Catch {
}
Version const& libraryVersion() {
static Version version( 3, 5, 3, "", 0 );
static Version version( 3, 5, 4, "", 0 );
return version;
}

View File

@ -10,6 +10,6 @@
#define CATCH_VERSION_MAJOR 3
#define CATCH_VERSION_MINOR 5
#define CATCH_VERSION_PATCH 3
#define CATCH_VERSION_PATCH 4
#endif // CATCH_VERSION_MACROS_HPP_INCLUDED

View File

@ -125,6 +125,12 @@
namespace Catch {
namespace Detail {
// This was added in C++20, but we require only C++14 for now.
template <typename T>
using RemoveCVRef_t = std::remove_cv_t<std::remove_reference_t<T>>;
}
// Note: There is nothing that stops us from extending this,
// e.g. to `std::is_scalar`, but the more encompassing
// traits are usually also more expensive. For now we
@ -276,17 +282,17 @@ namespace Catch {
#define CATCH_INTERNAL_DEFINE_EXPRESSION_EQUALITY_OPERATOR( id, op ) \
template <typename RhsT> \
constexpr friend auto operator op( ExprLhs&& lhs, RhsT&& rhs ) \
->std::enable_if_t< \
-> std::enable_if_t< \
Detail::conjunction<Detail::is_##id##_comparable<LhsT, RhsT>, \
Detail::negation<capture_by_value< \
std::remove_reference_t<RhsT>>>>::value, \
Detail::RemoveCVRef_t<RhsT>>>>::value, \
BinaryExpr<LhsT, RhsT const&>> { \
return { \
static_cast<bool>( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
} \
template <typename RhsT> \
constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
->std::enable_if_t< \
-> std::enable_if_t< \
Detail::conjunction<Detail::is_##id##_comparable<LhsT, RhsT>, \
capture_by_value<RhsT>>::value, \
BinaryExpr<LhsT, RhsT>> { \
@ -295,7 +301,7 @@ namespace Catch {
} \
template <typename RhsT> \
constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
->std::enable_if_t< \
-> std::enable_if_t< \
Detail::conjunction< \
Detail::negation<Detail::is_##id##_comparable<LhsT, RhsT>>, \
Detail::is_eq_0_comparable<LhsT>, \
@ -309,7 +315,7 @@ namespace Catch {
} \
template <typename RhsT> \
constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
->std::enable_if_t< \
-> std::enable_if_t< \
Detail::conjunction< \
Detail::negation<Detail::is_##id##_comparable<LhsT, RhsT>>, \
Detail::is_eq_0_comparable<RhsT>, \
@ -330,17 +336,17 @@ namespace Catch {
#define CATCH_INTERNAL_DEFINE_EXPRESSION_COMPARISON_OPERATOR( id, op ) \
template <typename RhsT> \
constexpr friend auto operator op( ExprLhs&& lhs, RhsT&& rhs ) \
->std::enable_if_t< \
-> std::enable_if_t< \
Detail::conjunction<Detail::is_##id##_comparable<LhsT, RhsT>, \
Detail::negation<capture_by_value< \
std::remove_reference_t<RhsT>>>>::value, \
Detail::RemoveCVRef_t<RhsT>>>>::value, \
BinaryExpr<LhsT, RhsT const&>> { \
return { \
static_cast<bool>( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
} \
template <typename RhsT> \
constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
->std::enable_if_t< \
-> std::enable_if_t< \
Detail::conjunction<Detail::is_##id##_comparable<LhsT, RhsT>, \
capture_by_value<RhsT>>::value, \
BinaryExpr<LhsT, RhsT>> { \
@ -349,7 +355,7 @@ namespace Catch {
} \
template <typename RhsT> \
constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
->std::enable_if_t< \
-> std::enable_if_t< \
Detail::conjunction< \
Detail::negation<Detail::is_##id##_comparable<LhsT, RhsT>>, \
Detail::is_##id##_0_comparable<LhsT>, \
@ -361,7 +367,7 @@ namespace Catch {
} \
template <typename RhsT> \
constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
->std::enable_if_t< \
-> std::enable_if_t< \
Detail::conjunction< \
Detail::negation<Detail::is_##id##_comparable<LhsT, RhsT>>, \
Detail::is_##id##_0_comparable<RhsT>, \
@ -382,16 +388,16 @@ namespace Catch {
#define CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR( op ) \
template <typename RhsT> \
constexpr friend auto operator op( ExprLhs&& lhs, RhsT&& rhs ) \
->std::enable_if_t< \
!capture_by_value<std::remove_reference_t<RhsT>>::value, \
-> std::enable_if_t< \
!capture_by_value<Detail::RemoveCVRef_t<RhsT>>::value, \
BinaryExpr<LhsT, RhsT const&>> { \
return { \
static_cast<bool>( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
} \
template <typename RhsT> \
constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
->std::enable_if_t<capture_by_value<RhsT>::value, \
BinaryExpr<LhsT, RhsT>> { \
-> std::enable_if_t<capture_by_value<RhsT>::value, \
BinaryExpr<LhsT, RhsT>> { \
return { \
static_cast<bool>( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
}
@ -423,8 +429,7 @@ namespace Catch {
struct Decomposer {
template <typename T,
std::enable_if_t<
!capture_by_value<std::remove_reference_t<T>>::value,
std::enable_if_t<!capture_by_value<Detail::RemoveCVRef_t<T>>::value,
int> = 0>
constexpr friend auto operator <= ( Decomposer &&, T && lhs ) -> ExprLhs<T const&> {
return ExprLhs<const T&>{ lhs };

View File

@ -21,7 +21,10 @@
// it, and it provides an escape hatch to the users who need it.
#if defined( __SIZEOF_INT128__ )
# define CATCH_CONFIG_INTERNAL_UINT128
#elif defined( _MSC_VER ) && ( defined( _WIN64 ) || defined( _M_ARM64 ) )
// Unlike GCC, MSVC does not polyfill umul as mulh + mul pair on ARM machines.
// Currently we do not bother doing this ourselves, but we could if it became
// important for perf.
#elif defined( _MSC_VER ) && defined( _M_X64 )
# define CATCH_CONFIG_INTERNAL_MSVC_UMUL128
#endif
@ -36,7 +39,6 @@
!defined( CATCH_CONFIG_MSVC_UMUL128 )
# define CATCH_CONFIG_MSVC_UMUL128
# include <intrin.h>
# pragma intrinsic( _umul128 )
#endif

View File

@ -450,6 +450,13 @@ namespace Catch {
assertionEnded(CATCH_MOVE(result) );
resetAssertionInfo();
// Best effort cleanup for sections that have not been destructed yet
// Since this is a fatal error, we have not had and won't have the opportunity to destruct them properly
while (!m_activeSections.empty()) {
auto nl = m_activeSections.back()->nameAndLocation();
SectionEndInfo endInfo{ SectionInfo(CATCH_MOVE(nl.location), CATCH_MOVE(nl.name)), {}, 0.0 };
sectionEndedEarly(CATCH_MOVE(endInfo));
}
handleUnfinishedSections();
// Recreate section for test case (as we will lose the one that was in scope)

View File

@ -123,6 +123,8 @@ namespace Catch {
return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config );
}
TestRegistry::~TestRegistry() = default;
void TestRegistry::registerTest(Detail::unique_ptr<TestCaseInfo> testInfo, Detail::unique_ptr<ITestInvoker> testInvoker) {
m_handles.emplace_back(testInfo.get(), testInvoker.get());
m_viewed_test_infos.push_back(testInfo.get());

View File

@ -36,6 +36,8 @@ namespace Catch {
std::vector<TestCaseHandle> const& getAllTests() const override;
std::vector<TestCaseHandle> const& getAllTestsSorted( IConfig const& config ) const override;
~TestRegistry() override; // = default
private:
std::vector<Detail::unique_ptr<TestCaseInfo>> m_owned_test_infos;
// Keeps a materialized vector for `getAllInfos`.

View File

@ -176,7 +176,7 @@ namespace Detail {
std::string WithinRelMatcher::describe() const {
Catch::ReusableStringStream sstr;
sstr << "and " << m_target << " are within " << m_epsilon * 100. << "% of each other";
sstr << "and " << ::Catch::Detail::stringify(m_target) << " are within " << m_epsilon * 100. << "% of each other";
return sstr.str();
}

View File

@ -0,0 +1,83 @@
load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test")
package(default_visibility = ["//visibility:public"])
cc_library(
name = "catch2_self_test_helper",
srcs = ["SelfTest/helpers/parse_test_spec.cpp"],
hdrs = [
"SelfTest/helpers/parse_test_spec.hpp",
"SelfTest/helpers/range_test_helpers.hpp",
"SelfTest/helpers/type_with_lit_0_comparisons.hpp",
],
includes = ["SelfTest"],
deps = [
"//:catch2",
],
)
cc_test(
name = "catch2_self_test",
size = "small",
srcs = [
"SelfTest/IntrospectiveTests/Algorithms.tests.cpp",
"SelfTest/IntrospectiveTests/Clara.tests.cpp",
"SelfTest/IntrospectiveTests/CmdLine.tests.cpp",
"SelfTest/IntrospectiveTests/CmdLineHelpers.tests.cpp",
"SelfTest/IntrospectiveTests/ColourImpl.tests.cpp",
"SelfTest/IntrospectiveTests/Details.tests.cpp",
"SelfTest/IntrospectiveTests/FloatingPoint.tests.cpp",
"SelfTest/IntrospectiveTests/GeneratorsImpl.tests.cpp",
"SelfTest/IntrospectiveTests/Integer.tests.cpp",
"SelfTest/IntrospectiveTests/InternalBenchmark.tests.cpp",
"SelfTest/IntrospectiveTests/Parse.tests.cpp",
"SelfTest/IntrospectiveTests/PartTracker.tests.cpp",
"SelfTest/IntrospectiveTests/RandomNumberGeneration.tests.cpp",
"SelfTest/IntrospectiveTests/Reporters.tests.cpp",
"SelfTest/IntrospectiveTests/Sharding.tests.cpp",
"SelfTest/IntrospectiveTests/Stream.tests.cpp",
"SelfTest/IntrospectiveTests/String.tests.cpp",
"SelfTest/IntrospectiveTests/StringManip.tests.cpp",
"SelfTest/IntrospectiveTests/Tag.tests.cpp",
"SelfTest/IntrospectiveTests/TestCaseInfoHasher.tests.cpp",
"SelfTest/IntrospectiveTests/TestSpec.tests.cpp",
"SelfTest/IntrospectiveTests/TestSpecParser.tests.cpp",
"SelfTest/IntrospectiveTests/TextFlow.tests.cpp",
"SelfTest/IntrospectiveTests/ToString.tests.cpp",
"SelfTest/IntrospectiveTests/Traits.tests.cpp",
"SelfTest/IntrospectiveTests/UniquePtr.tests.cpp",
"SelfTest/IntrospectiveTests/Xml.tests.cpp",
"SelfTest/TestRegistrations.cpp",
"SelfTest/TimingTests/Sleep.tests.cpp",
"SelfTest/UsageTests/Approx.tests.cpp",
"SelfTest/UsageTests/BDD.tests.cpp",
"SelfTest/UsageTests/Benchmark.tests.cpp",
"SelfTest/UsageTests/Class.tests.cpp",
"SelfTest/UsageTests/Compilation.tests.cpp",
"SelfTest/UsageTests/Condition.tests.cpp",
"SelfTest/UsageTests/Decomposition.tests.cpp",
"SelfTest/UsageTests/EnumToString.tests.cpp",
"SelfTest/UsageTests/Exception.tests.cpp",
"SelfTest/UsageTests/Generators.tests.cpp",
"SelfTest/UsageTests/Matchers.tests.cpp",
"SelfTest/UsageTests/MatchersRanges.tests.cpp",
"SelfTest/UsageTests/Message.tests.cpp",
"SelfTest/UsageTests/Misc.tests.cpp",
"SelfTest/UsageTests/ToStringByte.tests.cpp",
"SelfTest/UsageTests/ToStringChrono.tests.cpp",
"SelfTest/UsageTests/ToStringGeneral.tests.cpp",
"SelfTest/UsageTests/ToStringOptional.tests.cpp",
"SelfTest/UsageTests/ToStringPair.tests.cpp",
"SelfTest/UsageTests/ToStringTuple.tests.cpp",
"SelfTest/UsageTests/ToStringVariant.tests.cpp",
"SelfTest/UsageTests/ToStringVector.tests.cpp",
"SelfTest/UsageTests/ToStringWhich.tests.cpp",
"SelfTest/UsageTests/Tricky.tests.cpp",
"SelfTest/UsageTests/VariadicMacros.tests.cpp",
],
deps = [
":catch2_self_test_helper",
"//:catch2",
"//:catch2_main",
],
)

View File

@ -467,6 +467,18 @@ set_tests_properties(
PASS_REGULAR_EXPRESSION "Errors occurred during startup!"
)
add_executable(ReportingCrashWithJunitReporter ${TESTS_DIR}/X36-ReportingCrashWithJunitReporter.cpp)
target_link_libraries(ReportingCrashWithJunitReporter PRIVATE Catch2::Catch2WithMain)
add_test(
NAME Reporters::CrashInJunitReporter
COMMAND ${CMAKE_COMMAND} -E env $<TARGET_FILE:ReportingCrashWithJunitReporter> --reporter JUnit
)
set_tests_properties(
Reporters::CrashInJunitReporter
PROPERTIES
PASS_REGULAR_EXPRESSION "</testsuites>"
LABELS "uses-signals"
)
add_executable(AssertionStartingEventGoesBeforeAssertionIsEvaluated
X20-AssertionStartingEventGoesBeforeAssertionIsEvaluated.cpp

View File

@ -0,0 +1,32 @@
// Copyright Catch2 Authors
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)
// SPDX-License-Identifier: BSL-1.0
/**\file
* Checks that signals/SEH within open section does not hard crash JUnit
* (or similar reporter) while we are trying to report fatal error.
*/
#include <catch2/catch_test_macros.hpp>
#include <csignal>
// On Windows we need to send SEH and not signal to test the
// RunContext::handleFatalErrorCondition code path
#if defined( _MSC_VER )
# include <windows.h>
#endif
TEST_CASE( "raises signal" ) {
SECTION( "section" ) {
#if defined( _MSC_VER )
RaiseException( 0xC0000005, 0, 0, NULL );
#else
std::raise( SIGILL );
#endif
}
}

View File

@ -598,9 +598,9 @@ Misc.tests.cpp:<line number>: passed: Factorial(10) == 3628800 for: 3628800 (0x<
GeneratorsImpl.tests.cpp:<line number>: passed: filter( []( int ) { return false; }, value( 3 ) ), Catch::GeneratorException
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., !WithinRel( 0., 0.99 ) for: 1.0 not and 0.0 are within 99% of each other
Matchers.tests.cpp:<line number>: passed: -0., WithinRel( 0. ) for: -0.0 and 0.0 are within 2.22045e-12% of each other
Matchers.tests.cpp:<line number>: passed: v1, WithinRel( v2 ) for: 0.0 and 0.0 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
@ -618,7 +618,7 @@ Matchers.tests.cpp:<line number>: passed: 1., WithinULP( 1., 0 ) for: 1.0 is wit
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: 0.0001, WithinAbs( 0., 0.001 ) || WithinRel( 0., 0.1 ) for: 0.0001 ( is within 0.001 of 0.0 or and 0.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 )
@ -626,11 +626,11 @@ 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: 1., !IsNaN() for: 1.0 not is NaN
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: 10.f, WithinRel( 11.1f, 0.1f ) for: 10.0f and 11.1000003815 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.1999998093 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.0 are within 99% of each other
Matchers.tests.cpp:<line number>: passed: -0.f, WithinRel( 0.f ) for: -0.0f and 0.0 are within 0.00119209% of each other
Matchers.tests.cpp:<line number>: passed: v1, WithinRel( v2 ) for: 0.0f and 0.0 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
@ -650,7 +650,7 @@ Matchers.tests.cpp:<line number>: passed: 1.f, WithinULP( 1.f, 0 ) for: 1.0f is
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: 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.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 )

View File

@ -596,9 +596,9 @@ Misc.tests.cpp:<line number>: passed: Factorial(10) == 3628800 for: 3628800 (0x<
GeneratorsImpl.tests.cpp:<line number>: passed: filter( []( int ) { return false; }, value( 3 ) ), Catch::GeneratorException
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., !WithinRel( 0., 0.99 ) for: 1.0 not and 0.0 are within 99% of each other
Matchers.tests.cpp:<line number>: passed: -0., WithinRel( 0. ) for: -0.0 and 0.0 are within 2.22045e-12% of each other
Matchers.tests.cpp:<line number>: passed: v1, WithinRel( v2 ) for: 0.0 and 0.0 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
@ -616,7 +616,7 @@ Matchers.tests.cpp:<line number>: passed: 1., WithinULP( 1., 0 ) for: 1.0 is wit
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: 0.0001, WithinAbs( 0., 0.001 ) || WithinRel( 0., 0.1 ) for: 0.0001 ( is within 0.001 of 0.0 or and 0.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 )
@ -624,11 +624,11 @@ 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: 1., !IsNaN() for: 1.0 not is NaN
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: 10.f, WithinRel( 11.1f, 0.1f ) for: 10.0f and 11.1000003815 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.1999998093 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.0 are within 99% of each other
Matchers.tests.cpp:<line number>: passed: -0.f, WithinRel( 0.f ) for: -0.0f and 0.0 are within 0.00119209% of each other
Matchers.tests.cpp:<line number>: passed: v1, WithinRel( v2 ) for: 0.0f and 0.0 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
@ -648,7 +648,7 @@ Matchers.tests.cpp:<line number>: passed: 1.f, WithinULP( 1.f, 0 ) for: 1.0f is
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: 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.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 )

View File

@ -4487,12 +4487,12 @@ with expansion:
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
1.0 not and 0.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
-0.0 and 0.0 are within 2.22045e-12% of each other
-------------------------------------------------------------------------------
Floating point matchers: double
@ -4505,7 +4505,7 @@ 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
0.0 and 0.0 are within 2.22045e-12% of each other
-------------------------------------------------------------------------------
Floating point matchers: double
@ -4625,7 +4625,7 @@ with expansion:
Matchers.tests.cpp:<line number>: PASSED:
REQUIRE_THAT( 0.0001, WithinAbs( 0., 0.001 ) || WithinRel( 0., 0.1 ) )
with expansion:
0.0001 ( is within 0.001 of 0.0 or and 0 are within 10% of each other )
0.0001 ( is within 0.001 of 0.0 or and 0.0 are within 10% of each other )
-------------------------------------------------------------------------------
Floating point matchers: double
@ -4674,22 +4674,22 @@ Matchers.tests.cpp:<line number>
Matchers.tests.cpp:<line number>: PASSED:
REQUIRE_THAT( 10.f, WithinRel( 11.1f, 0.1f ) )
with expansion:
10.0f and 11.1 are within 10% of each other
10.0f and 11.1000003815 are within 10% of each other
Matchers.tests.cpp:<line number>: PASSED:
REQUIRE_THAT( 10.f, !WithinRel( 11.2f, 0.1f ) )
with expansion:
10.0f not and 11.2 are within 10% of each other
10.0f not and 11.1999998093 are within 10% of each other
Matchers.tests.cpp:<line number>: PASSED:
REQUIRE_THAT( 1.f, !WithinRel( 0.f, 0.99f ) )
with expansion:
1.0f not and 0 are within 99% of each other
1.0f not and 0.0 are within 99% of each other
Matchers.tests.cpp:<line number>: PASSED:
REQUIRE_THAT( -0.f, WithinRel( 0.f ) )
with expansion:
-0.0f and 0 are within 0.00119209% of each other
-0.0f and 0.0 are within 0.00119209% of each other
-------------------------------------------------------------------------------
Floating point matchers: float
@ -4702,7 +4702,7 @@ Matchers.tests.cpp:<line number>
Matchers.tests.cpp:<line number>: PASSED:
REQUIRE_THAT( v1, WithinRel( v2 ) )
with expansion:
0.0f and 1.17549e-38 are within 0.00119209% of each other
0.0f and 0.0 are within 0.00119209% of each other
-------------------------------------------------------------------------------
Floating point matchers: float
@ -4827,7 +4827,7 @@ with expansion:
Matchers.tests.cpp:<line number>: PASSED:
REQUIRE_THAT( 0.0001f, WithinAbs( 0.f, 0.001f ) || WithinRel( 0.f, 0.1f ) )
with expansion:
0.0001f ( is within 0.001 of 0.0 or and 0 are within 10% of each other )
0.0001f ( is within 0.001 of 0.0 or and 0.0 are within 10% of each other )
-------------------------------------------------------------------------------
Floating point matchers: float

View File

@ -4485,12 +4485,12 @@ with expansion:
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
1.0 not and 0.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
-0.0 and 0.0 are within 2.22045e-12% of each other
-------------------------------------------------------------------------------
Floating point matchers: double
@ -4503,7 +4503,7 @@ 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
0.0 and 0.0 are within 2.22045e-12% of each other
-------------------------------------------------------------------------------
Floating point matchers: double
@ -4623,7 +4623,7 @@ with expansion:
Matchers.tests.cpp:<line number>: PASSED:
REQUIRE_THAT( 0.0001, WithinAbs( 0., 0.001 ) || WithinRel( 0., 0.1 ) )
with expansion:
0.0001 ( is within 0.001 of 0.0 or and 0 are within 10% of each other )
0.0001 ( is within 0.001 of 0.0 or and 0.0 are within 10% of each other )
-------------------------------------------------------------------------------
Floating point matchers: double
@ -4672,22 +4672,22 @@ Matchers.tests.cpp:<line number>
Matchers.tests.cpp:<line number>: PASSED:
REQUIRE_THAT( 10.f, WithinRel( 11.1f, 0.1f ) )
with expansion:
10.0f and 11.1 are within 10% of each other
10.0f and 11.1000003815 are within 10% of each other
Matchers.tests.cpp:<line number>: PASSED:
REQUIRE_THAT( 10.f, !WithinRel( 11.2f, 0.1f ) )
with expansion:
10.0f not and 11.2 are within 10% of each other
10.0f not and 11.1999998093 are within 10% of each other
Matchers.tests.cpp:<line number>: PASSED:
REQUIRE_THAT( 1.f, !WithinRel( 0.f, 0.99f ) )
with expansion:
1.0f not and 0 are within 99% of each other
1.0f not and 0.0 are within 99% of each other
Matchers.tests.cpp:<line number>: PASSED:
REQUIRE_THAT( -0.f, WithinRel( 0.f ) )
with expansion:
-0.0f and 0 are within 0.00119209% of each other
-0.0f and 0.0 are within 0.00119209% of each other
-------------------------------------------------------------------------------
Floating point matchers: float
@ -4700,7 +4700,7 @@ Matchers.tests.cpp:<line number>
Matchers.tests.cpp:<line number>: PASSED:
REQUIRE_THAT( v1, WithinRel( v2 ) )
with expansion:
0.0f and 1.17549e-38 are within 0.00119209% of each other
0.0f and 0.0 are within 0.00119209% of each other
-------------------------------------------------------------------------------
Floating point matchers: float
@ -4825,7 +4825,7 @@ with expansion:
Matchers.tests.cpp:<line number>: PASSED:
REQUIRE_THAT( 0.0001f, WithinAbs( 0.f, 0.001f ) || WithinRel( 0.f, 0.1f ) )
with expansion:
0.0001f ( is within 0.001 of 0.0 or and 0 are within 10% of each other )
0.0001f ( is within 0.001 of 0.0 or and 0.0 are within 10% of each other )
-------------------------------------------------------------------------------
Floating point matchers: float

View File

@ -1129,11 +1129,11 @@ ok {test-number} - 10., WithinRel( 11.1, 0.1 ) for: 10.0 and 11.1 are within 10%
# Floating point matchers: double
ok {test-number} - 10., !WithinRel( 11.2, 0.1 ) for: 10.0 not and 11.2 are within 10% of each other
# Floating point matchers: double
ok {test-number} - 1., !WithinRel( 0., 0.99 ) for: 1.0 not and 0 are within 99% of each other
ok {test-number} - 1., !WithinRel( 0., 0.99 ) for: 1.0 not and 0.0 are within 99% of each other
# Floating point matchers: double
ok {test-number} - -0., WithinRel( 0. ) for: -0.0 and 0 are within 2.22045e-12% of each other
ok {test-number} - -0., WithinRel( 0. ) for: -0.0 and 0.0 are within 2.22045e-12% of each other
# Floating point matchers: double
ok {test-number} - v1, WithinRel( v2 ) for: 0.0 and 2.22507e-308 are within 2.22045e-12% of each other
ok {test-number} - v1, WithinRel( v2 ) for: 0.0 and 0.0 are within 2.22045e-12% of each other
# Floating point matchers: double
ok {test-number} - 1., WithinAbs( 1., 0 ) for: 1.0 is within 0.0 of 1.0
# Floating point matchers: double
@ -1169,7 +1169,7 @@ ok {test-number} - 1., WithinAbs( 1., 0.5 ) || WithinULP( 2., 1 ) for: 1.0 ( is
# Floating point matchers: double
ok {test-number} - 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]) )
# Floating point matchers: double
ok {test-number} - 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 )
ok {test-number} - 0.0001, WithinAbs( 0., 0.001 ) || WithinRel( 0., 0.1 ) for: 0.0001 ( is within 0.001 of 0.0 or and 0.0 are within 10% of each other )
# Floating point matchers: double
ok {test-number} - WithinAbs( 1., 0. )
# Floating point matchers: double
@ -1185,15 +1185,15 @@ ok {test-number} - WithinRel( 1., 1. ), std::domain_error
# Floating point matchers: double
ok {test-number} - 1., !IsNaN() for: 1.0 not is NaN
# Floating point matchers: float
ok {test-number} - 10.f, WithinRel( 11.1f, 0.1f ) for: 10.0f and 11.1 are within 10% of each other
ok {test-number} - 10.f, WithinRel( 11.1f, 0.1f ) for: 10.0f and 11.1000003815 are within 10% of each other
# Floating point matchers: float
ok {test-number} - 10.f, !WithinRel( 11.2f, 0.1f ) for: 10.0f not and 11.2 are within 10% of each other
ok {test-number} - 10.f, !WithinRel( 11.2f, 0.1f ) for: 10.0f not and 11.1999998093 are within 10% of each other
# Floating point matchers: float
ok {test-number} - 1.f, !WithinRel( 0.f, 0.99f ) for: 1.0f not and 0 are within 99% of each other
ok {test-number} - 1.f, !WithinRel( 0.f, 0.99f ) for: 1.0f not and 0.0 are within 99% of each other
# Floating point matchers: float
ok {test-number} - -0.f, WithinRel( 0.f ) for: -0.0f and 0 are within 0.00119209% of each other
ok {test-number} - -0.f, WithinRel( 0.f ) for: -0.0f and 0.0 are within 0.00119209% of each other
# Floating point matchers: float
ok {test-number} - v1, WithinRel( v2 ) for: 0.0f and 1.17549e-38 are within 0.00119209% of each other
ok {test-number} - v1, WithinRel( v2 ) for: 0.0f and 0.0 are within 0.00119209% of each other
# Floating point matchers: float
ok {test-number} - 1.f, WithinAbs( 1.f, 0 ) for: 1.0f is within 0.0 of 1.0
# Floating point matchers: float
@ -1233,7 +1233,7 @@ ok {test-number} - 1.f, WithinAbs( 1.f, 0.5 ) || WithinULP( 1.f, 1 ) for: 1.0f (
# Floating point matchers: float
ok {test-number} - 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]) )
# Floating point matchers: float
ok {test-number} - 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 )
ok {test-number} - 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.0 are within 10% of each other )
# Floating point matchers: float
ok {test-number} - WithinAbs( 1.f, 0.f )
# Floating point matchers: float

View File

@ -1127,11 +1127,11 @@ ok {test-number} - 10., WithinRel( 11.1, 0.1 ) for: 10.0 and 11.1 are within 10%
# Floating point matchers: double
ok {test-number} - 10., !WithinRel( 11.2, 0.1 ) for: 10.0 not and 11.2 are within 10% of each other
# Floating point matchers: double
ok {test-number} - 1., !WithinRel( 0., 0.99 ) for: 1.0 not and 0 are within 99% of each other
ok {test-number} - 1., !WithinRel( 0., 0.99 ) for: 1.0 not and 0.0 are within 99% of each other
# Floating point matchers: double
ok {test-number} - -0., WithinRel( 0. ) for: -0.0 and 0 are within 2.22045e-12% of each other
ok {test-number} - -0., WithinRel( 0. ) for: -0.0 and 0.0 are within 2.22045e-12% of each other
# Floating point matchers: double
ok {test-number} - v1, WithinRel( v2 ) for: 0.0 and 2.22507e-308 are within 2.22045e-12% of each other
ok {test-number} - v1, WithinRel( v2 ) for: 0.0 and 0.0 are within 2.22045e-12% of each other
# Floating point matchers: double
ok {test-number} - 1., WithinAbs( 1., 0 ) for: 1.0 is within 0.0 of 1.0
# Floating point matchers: double
@ -1167,7 +1167,7 @@ ok {test-number} - 1., WithinAbs( 1., 0.5 ) || WithinULP( 2., 1 ) for: 1.0 ( is
# Floating point matchers: double
ok {test-number} - 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]) )
# Floating point matchers: double
ok {test-number} - 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 )
ok {test-number} - 0.0001, WithinAbs( 0., 0.001 ) || WithinRel( 0., 0.1 ) for: 0.0001 ( is within 0.001 of 0.0 or and 0.0 are within 10% of each other )
# Floating point matchers: double
ok {test-number} - WithinAbs( 1., 0. )
# Floating point matchers: double
@ -1183,15 +1183,15 @@ ok {test-number} - WithinRel( 1., 1. ), std::domain_error
# Floating point matchers: double
ok {test-number} - 1., !IsNaN() for: 1.0 not is NaN
# Floating point matchers: float
ok {test-number} - 10.f, WithinRel( 11.1f, 0.1f ) for: 10.0f and 11.1 are within 10% of each other
ok {test-number} - 10.f, WithinRel( 11.1f, 0.1f ) for: 10.0f and 11.1000003815 are within 10% of each other
# Floating point matchers: float
ok {test-number} - 10.f, !WithinRel( 11.2f, 0.1f ) for: 10.0f not and 11.2 are within 10% of each other
ok {test-number} - 10.f, !WithinRel( 11.2f, 0.1f ) for: 10.0f not and 11.1999998093 are within 10% of each other
# Floating point matchers: float
ok {test-number} - 1.f, !WithinRel( 0.f, 0.99f ) for: 1.0f not and 0 are within 99% of each other
ok {test-number} - 1.f, !WithinRel( 0.f, 0.99f ) for: 1.0f not and 0.0 are within 99% of each other
# Floating point matchers: float
ok {test-number} - -0.f, WithinRel( 0.f ) for: -0.0f and 0 are within 0.00119209% of each other
ok {test-number} - -0.f, WithinRel( 0.f ) for: -0.0f and 0.0 are within 0.00119209% of each other
# Floating point matchers: float
ok {test-number} - v1, WithinRel( v2 ) for: 0.0f and 1.17549e-38 are within 0.00119209% of each other
ok {test-number} - v1, WithinRel( v2 ) for: 0.0f and 0.0 are within 0.00119209% of each other
# Floating point matchers: float
ok {test-number} - 1.f, WithinAbs( 1.f, 0 ) for: 1.0f is within 0.0 of 1.0
# Floating point matchers: float
@ -1231,7 +1231,7 @@ ok {test-number} - 1.f, WithinAbs( 1.f, 0.5 ) || WithinULP( 1.f, 1 ) for: 1.0f (
# Floating point matchers: float
ok {test-number} - 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]) )
# Floating point matchers: float
ok {test-number} - 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 )
ok {test-number} - 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.0 are within 10% of each other )
# Floating point matchers: float
ok {test-number} - WithinAbs( 1.f, 0.f )
# Floating point matchers: float

View File

@ -5022,7 +5022,7 @@ C
1., !WithinRel( 0., 0.99 )
</Original>
<Expanded>
1.0 not and 0 are within 99% of each other
1.0 not and 0.0 are within 99% of each other
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE_THAT" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
@ -5030,7 +5030,7 @@ C
-0., WithinRel( 0. )
</Original>
<Expanded>
-0.0 and 0 are within 2.22045e-12% of each other
-0.0 and 0.0 are within 2.22045e-12% of each other
</Expanded>
</Expression>
<Section name="Some subnormal values" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
@ -5039,7 +5039,7 @@ C
v1, WithinRel( v2 )
</Original>
<Expanded>
0.0 and 2.22507e-308 are within 2.22045e-12% of each other
0.0 and 0.0 are within 2.22045e-12% of each other
</Expanded>
</Expression>
<OverallResults successes="1" failures="0" expectedFailures="0" skipped="false"/>
@ -5194,7 +5194,7 @@ C
0.0001, WithinAbs( 0., 0.001 ) || WithinRel( 0., 0.1 )
</Original>
<Expanded>
0.0001 ( is within 0.001 of 0.0 or and 0 are within 10% of each other )
0.0001 ( is within 0.001 of 0.0 or and 0.0 are within 10% of each other )
</Expanded>
</Expression>
<OverallResults successes="3" failures="0" expectedFailures="0" skipped="false"/>
@ -5270,7 +5270,7 @@ C
10.f, WithinRel( 11.1f, 0.1f )
</Original>
<Expanded>
10.0f and 11.1 are within 10% of each other
10.0f and 11.1000003815 are within 10% of each other
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE_THAT" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
@ -5278,7 +5278,7 @@ C
10.f, !WithinRel( 11.2f, 0.1f )
</Original>
<Expanded>
10.0f not and 11.2 are within 10% of each other
10.0f not and 11.1999998093 are within 10% of each other
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE_THAT" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
@ -5286,7 +5286,7 @@ C
1.f, !WithinRel( 0.f, 0.99f )
</Original>
<Expanded>
1.0f not and 0 are within 99% of each other
1.0f not and 0.0 are within 99% of each other
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE_THAT" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
@ -5294,7 +5294,7 @@ C
-0.f, WithinRel( 0.f )
</Original>
<Expanded>
-0.0f and 0 are within 0.00119209% of each other
-0.0f and 0.0 are within 0.00119209% of each other
</Expanded>
</Expression>
<Section name="Some subnormal values" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
@ -5303,7 +5303,7 @@ C
v1, WithinRel( v2 )
</Original>
<Expanded>
0.0f and 1.17549e-38 are within 0.00119209% of each other
0.0f and 0.0 are within 0.00119209% of each other
</Expanded>
</Expression>
<OverallResults successes="1" failures="0" expectedFailures="0" skipped="false"/>
@ -5474,7 +5474,7 @@ C
0.0001f, WithinAbs( 0.f, 0.001f ) || WithinRel( 0.f, 0.1f )
</Original>
<Expanded>
0.0001f ( is within 0.001 of 0.0 or and 0 are within 10% of each other )
0.0001f ( is within 0.001 of 0.0 or and 0.0 are within 10% of each other )
</Expanded>
</Expression>
<OverallResults successes="3" failures="0" expectedFailures="0" skipped="false"/>

View File

@ -5022,7 +5022,7 @@ C
1., !WithinRel( 0., 0.99 )
</Original>
<Expanded>
1.0 not and 0 are within 99% of each other
1.0 not and 0.0 are within 99% of each other
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE_THAT" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
@ -5030,7 +5030,7 @@ C
-0., WithinRel( 0. )
</Original>
<Expanded>
-0.0 and 0 are within 2.22045e-12% of each other
-0.0 and 0.0 are within 2.22045e-12% of each other
</Expanded>
</Expression>
<Section name="Some subnormal values" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
@ -5039,7 +5039,7 @@ C
v1, WithinRel( v2 )
</Original>
<Expanded>
0.0 and 2.22507e-308 are within 2.22045e-12% of each other
0.0 and 0.0 are within 2.22045e-12% of each other
</Expanded>
</Expression>
<OverallResults successes="1" failures="0" expectedFailures="0" skipped="false"/>
@ -5194,7 +5194,7 @@ C
0.0001, WithinAbs( 0., 0.001 ) || WithinRel( 0., 0.1 )
</Original>
<Expanded>
0.0001 ( is within 0.001 of 0.0 or and 0 are within 10% of each other )
0.0001 ( is within 0.001 of 0.0 or and 0.0 are within 10% of each other )
</Expanded>
</Expression>
<OverallResults successes="3" failures="0" expectedFailures="0" skipped="false"/>
@ -5270,7 +5270,7 @@ C
10.f, WithinRel( 11.1f, 0.1f )
</Original>
<Expanded>
10.0f and 11.1 are within 10% of each other
10.0f and 11.1000003815 are within 10% of each other
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE_THAT" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
@ -5278,7 +5278,7 @@ C
10.f, !WithinRel( 11.2f, 0.1f )
</Original>
<Expanded>
10.0f not and 11.2 are within 10% of each other
10.0f not and 11.1999998093 are within 10% of each other
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE_THAT" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
@ -5286,7 +5286,7 @@ C
1.f, !WithinRel( 0.f, 0.99f )
</Original>
<Expanded>
1.0f not and 0 are within 99% of each other
1.0f not and 0.0 are within 99% of each other
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE_THAT" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
@ -5294,7 +5294,7 @@ C
-0.f, WithinRel( 0.f )
</Original>
<Expanded>
-0.0f and 0 are within 0.00119209% of each other
-0.0f and 0.0 are within 0.00119209% of each other
</Expanded>
</Expression>
<Section name="Some subnormal values" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
@ -5303,7 +5303,7 @@ C
v1, WithinRel( v2 )
</Original>
<Expanded>
0.0f and 1.17549e-38 are within 0.00119209% of each other
0.0f and 0.0 are within 0.00119209% of each other
</Expanded>
</Expression>
<OverallResults successes="1" failures="0" expectedFailures="0" skipped="false"/>
@ -5474,7 +5474,7 @@ C
0.0001f, WithinAbs( 0.f, 0.001f ) || WithinRel( 0.f, 0.1f )
</Original>
<Expanded>
0.0001f ( is within 0.001 of 0.0 or and 0 are within 10% of each other )
0.0001f ( is within 0.001 of 0.0 or and 0.0 are within 10% of each other )
</Expanded>
</Expression>
<OverallResults successes="3" failures="0" expectedFailures="0" skipped="false"/>

View File

@ -495,6 +495,22 @@ TEMPLATE_TEST_CASE( "uniform_integer_distribution is reproducible",
REQUIRE_THAT(generated, Catch::Matchers::RangeEquals(uniform_integer_test_params<TestType>::expected));
}
// The reproducibility tests assume that operations on `float`/`double`
// happen in the same precision as the operated-upon type. This is
// generally true, unless the code is compiled for 32 bit targets without
// SSE2 enabled, in which case the operations are done in the x87 FPU,
// which usually implies doing math in 80 bit floats, and then rounding
// into smaller type when the type is saved into memory. This obviously
// leads to a different answer, than doing the math in the correct precision.
#if ( defined( _MSC_VER ) && _M_IX86_FP < 2 ) || \
( defined( __GNUC__ ) && \
( ( defined( __i386__ ) || defined( __x86_64__ ) ) ) && \
!defined( __SSE2_MATH__ ) )
# define CATCH_TEST_CONFIG_DISABLE_FLOAT_REPRODUCIBILITY_TESTS
#endif
#if !defined( CATCH_TEST_CONFIG_DISABLE_FLOAT_REPRODUCIBILITY_TESTS )
namespace {
template <typename T>
struct uniform_fp_test_params;
@ -552,20 +568,6 @@ namespace {
#endif
} // namespace
// The reproducibility tests assume that operations on `float`/`double`
// happen in the same precision as the operated-upon type. This is
// generally true, unless the code is compiled for 32 bit targets without
// SSE2 enabled, in which case the operations are done in the x87 FPU,
// which usually implies doing math in 80 bit floats, and then rounding
// into smaller type when the type is saved into memory. This obviously
// leads to a different answer, than doing the math in the correct precision.
#if ( defined( _MSC_VER ) && _M_IX86_FP < 2 ) || \
( defined( __GNUC__ ) && !defined( __SSE2_MATH__ ) )
# define CATCH_TEST_CONFIG_DISABLE_FLOAT_REPRODUCIBILITY_TESTS
#endif
#if !defined( CATCH_TEST_CONFIG_DISABLE_FLOAT_REPRODUCIBILITY_TESTS )
TEMPLATE_TEST_CASE( "uniform_floating_point_distribution is reproducible",
"[rng][distribution][floating-point][approvals]",
float,
@ -596,7 +598,7 @@ TEMPLATE_TEST_CASE( "uniform_floating_point_distribution can handle unitary rang
CAPTURE( seed );
Catch::SimplePcg32 pcg( seed );
const auto highest = uniform_fp_test_params<TestType>::highest;
const auto highest = TestType(385.125);
Catch::uniform_floating_point_distribution<TestType> dist( highest,
highest );

View File

@ -357,6 +357,12 @@ namespace {
constexpr friend bool operator op( ZeroLiteralConsteval, \
TypeWithConstevalLit0Comparison ) { \
return false; \
} \
/* std::orderings only have these for ==, but we add them for all \
operators so we can test all overloads for decomposer */ \
constexpr friend bool operator op( TypeWithConstevalLit0Comparison, \
TypeWithConstevalLit0Comparison ) { \
return true; \
}
DEFINE_COMP_OP( < )
@ -394,6 +400,33 @@ TEST_CASE( "#2555 - types that can only be compared with 0 literal implemented a
REQUIRE_FALSE( 0 != TypeWithConstevalLit0Comparison{} );
}
// We check all comparison ops to test, even though orderings, the primary
// motivation for this functionality, only have self-comparison (and thus
// have the ambiguity issue) for `==` and `!=`.
TEST_CASE( "Comparing const instances of type registered with capture_by_value",
"[regression][approvals][compilation]" ) {
SECTION("Type with consteval-int constructor") {
auto const const_Lit0Type_1 = TypeWithConstevalLit0Comparison{};
auto const const_Lit0Type_2 = TypeWithConstevalLit0Comparison{};
REQUIRE( const_Lit0Type_1 == const_Lit0Type_2 );
REQUIRE( const_Lit0Type_1 <= const_Lit0Type_2 );
REQUIRE( const_Lit0Type_1 < const_Lit0Type_2 );
REQUIRE( const_Lit0Type_1 >= const_Lit0Type_2 );
REQUIRE( const_Lit0Type_1 > const_Lit0Type_2 );
REQUIRE( const_Lit0Type_1 != const_Lit0Type_2 );
}
SECTION("Type with constexpr-int constructor") {
auto const const_Lit0Type_1 = TypeWithLit0Comparisons{};
auto const const_Lit0Type_2 = TypeWithLit0Comparisons{};
REQUIRE( const_Lit0Type_1 == const_Lit0Type_2 );
REQUIRE( const_Lit0Type_1 <= const_Lit0Type_2 );
REQUIRE( const_Lit0Type_1 < const_Lit0Type_2 );
REQUIRE( const_Lit0Type_1 >= const_Lit0Type_2 );
REQUIRE( const_Lit0Type_1 > const_Lit0Type_2 );
REQUIRE( const_Lit0Type_1 != const_Lit0Type_2 );
}
}
#endif // C++20 consteval
@ -420,3 +453,17 @@ TEST_CASE("#2571 - tests compile types that have multiple implicit constructors
REQUIRE( mic1 > mic2 );
REQUIRE( mic1 >= mic2 );
}
#if defined( CATCH_CONFIG_CPP20_COMPARE_OVERLOADS )
// This test does not test all the related codepaths, but it is the original
// reproducer
TEST_CASE( "Comparing const std::weak_ordering instances must compile",
"[compilation][approvals][regression]" ) {
auto const const_ordering_1 = std::weak_ordering::less;
auto const const_ordering_2 = std::weak_ordering::less;
auto plain_ordering_1 = std::weak_ordering::less;
REQUIRE( const_ordering_1 == plain_ordering_1 );
REQUIRE( const_ordering_1 == const_ordering_2 );
REQUIRE( plain_ordering_1 == const_ordering_1 );
}
#endif

View File

@ -26,14 +26,20 @@ struct ZeroLiteralAsPointer {
struct TypeWithLit0Comparisons {
#define DEFINE_COMP_OP( op ) \
constexpr friend bool operator op( TypeWithLit0Comparisons, \
ZeroLiteralAsPointer ) { \
return true; \
} \
constexpr friend bool operator op( ZeroLiteralAsPointer, \
TypeWithLit0Comparisons ) { \
return false; \
#define DEFINE_COMP_OP( op ) \
constexpr friend bool operator op( TypeWithLit0Comparisons, \
ZeroLiteralAsPointer ) { \
return true; \
} \
constexpr friend bool operator op( ZeroLiteralAsPointer, \
TypeWithLit0Comparisons ) { \
return false; \
} \
/* std::orderings only have these for ==, but we add them for all \
operators so we can test all overloads for decomposer */ \
constexpr friend bool operator op( TypeWithLit0Comparisons, \
TypeWithLit0Comparisons ) { \
return true; \
}
DEFINE_COMP_OP( < )

View File

@ -5,7 +5,7 @@ reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug\AutoExclusion
cd Build
if "%CONFIGURATION%"=="Debug" (
if "%coverage%"=="1" (
ctest -j 2 -C %CONFIGURATION% -D ExperimentalMemCheck || exit /b !ERRORLEVEL!
ctest -j 2 -C %CONFIGURATION% -D ExperimentalMemCheck -LE uses-signals || exit /b !ERRORLEVEL!
python ..\tools\misc\appveyorMergeCoverageScript.py || exit /b !ERRORLEVEL!
codecov --root .. --no-color --disable gcov -f cobertura.xml -t %CODECOV_TOKEN% || exit /b !ERRORLEVEL!
) else (