convergence_best #27
5
.gitmodules
vendored
5
.gitmodules
vendored
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -75,4 +75,4 @@ make sample fname=tests/data/glass.arff
|
||||
|
||||
## Coverage report
|
||||
|
||||
[Coverage report](html/index.html)
|
||||
### [Coverage report](docs/coverage.pdf)
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
BIN
docs/coverage.pdf
Normal file
Binary file not shown.
@ -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;
|
||||
}
|
@ -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();
|
||||
|
@ -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
|
44
tests/lib/catch2/.github/workflows/mac-builds-m1.yml
vendored
Normal file
44
tests/lib/catch2/.github/workflows/mac-builds-m1.yml
vendored
Normal 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`
|
1
tests/lib/catch2/.gitignore
vendored
1
tests/lib/catch2/.gitignore
vendored
@ -27,6 +27,7 @@ benchmark-dir
|
||||
.conan/test_package/build
|
||||
.conan/test_package/CMakeUserPresets.json
|
||||
bazel-*
|
||||
MODULE.bazel.lock
|
||||
build-fuzzers
|
||||
debug-build
|
||||
.vscode
|
||||
|
@ -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)
|
||||
|
@ -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")
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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());
|
||||
|
@ -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`.
|
||||
|
@ -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',
|
||||
)
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 };
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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());
|
||||
|
@ -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`.
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
83
tests/lib/catch2/tests/BUILD.bazel
Normal file
83
tests/lib/catch2/tests/BUILD.bazel
Normal 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",
|
||||
],
|
||||
)
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
}
|
@ -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 )
|
||||
|
@ -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 )
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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"/>
|
||||
|
@ -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"/>
|
||||
|
@ -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 );
|
||||
|
||||
|
@ -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
|
||||
|
@ -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( < )
|
||||
|
@ -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 (
|
||||
|
Loading…
Reference in New Issue
Block a user