Skip to content

Commit

Permalink
Merge branch 'devel' into devel
Browse files Browse the repository at this point in the history
  • Loading branch information
horenmar authored Dec 10, 2023
2 parents 5ca751b + b7d70dd commit 10781ff
Show file tree
Hide file tree
Showing 48 changed files with 1,763 additions and 101 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/linux-meson-builds.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ jobs:
- uses: actions/checkout@v4

- name: Prepare environment
run: sudo apt-get install -y meson ninja-build ${{matrix.other_pkgs}}
run: |
sudo apt-get update
sudo apt-get install -y meson ninja-build ${{matrix.other_pkgs}}
- name: Configure build
env:
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/linux-other-builds.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,9 @@ jobs:
- uses: actions/checkout@v4

- name: Prepare environment
run: sudo apt-get install -y ninja-build ${{matrix.other_pkgs}}
run: |
sudo apt-get update
sudo apt-get install -y ninja-build ${{matrix.other_pkgs}}
- name: Configure build
working-directory: ${{runner.workspace}}
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/linux-simple-builds.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,9 @@ jobs:
if: ${{ matrix.cxx == 'g++-5' || matrix.cxx == 'g++-6' }}

- name: Prepare environment
run: sudo apt-get install -y ninja-build ${{matrix.other_pkgs}}
run: |
sudo apt-get update
sudo apt-get install -y ninja-build ${{matrix.other_pkgs}}
- name: Configure build
working-directory: ${{runner.workspace}}
Expand Down
11 changes: 0 additions & 11 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,3 @@ environment:
additional_flags: "/permissive- /std:c++latest"
platform: x64
configuration: Debug

- FLAVOR: VS 2017 x64 Debug
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
platform: x64
configuration: Debug

- FLAVOR: VS 2017 x64 Release Coverage
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
coverage: 1
platform: x64
configuration: Debug
2 changes: 1 addition & 1 deletion docs/ci-and-misc.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ variable set to "1".

### CodeCoverage module (GCOV, LCOV...)

If you are using GCOV tool to get testing coverage of your code, and are not sure how to integrate it with CMake and Catch, there should be an external example over at https://github.com/fkromer/catch_cmake_coverage
If you are using GCOV tool to get testing coverage of your code, and are not sure how to integrate it with CMake and Catch, there should be an external example over at https://github.com/claremacrae/catch_cmake_coverage


### pkg-config
Expand Down
11 changes: 8 additions & 3 deletions docs/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,14 @@ and it is also generally repeatable across versions, but we might break
it from time to time. E.g. we broke repeatability with previous versions
in v2.13.4 so that test cases with similar names are shuffled better.

Random generators currently rely on platform's stdlib, specifically
the distributions from `<random>`. We thus provide no extra guarantee
above what your platform does. **Important: `<random>`'s distributions
Since Catch2 vX.Y.Z the random generators use custom distributions,
that should be repeatable across different platforms, with few caveats.
For details see the section on random generators in the [Generator
documentation](generators.md#random-number-generators-details).

Before this version, random generators relied on distributions from
platform's stdlib. We thus can provide no extra guarantee on top of the
ones given by your platform. **Important: `<random>`'s distributions
are not specified to be repeatable across different platforms.**


Expand Down
25 changes: 25 additions & 0 deletions docs/generators.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,31 @@ TEST_CASE("type conversion", "[generators]") {
}
```
### Random number generators: details
> This section applies from Catch2 vX.Y.Z. Before that, random generators
> were a thin wrapper around distributions from `<random>`.
All of the `random(a, b)` generators in Catch2 currently generate uniformly
distributed number in closed interval \[a; b\]. This is different from
`std::uniform_real_distribution`, which should return numbers in interval
\[a; b) (but due to rounding can end up returning b anyway), but the
difference is intentional, so that `random(a, a)` makes sense. If there is
enough interest from users, we can provide API to pick any of CC, CO, OC,
or OO ranges.
Unlike `std::uniform_int_distribution`, Catch2's generators also support
various single-byte integral types, such as `char` or `bool`.
Given the same seed, the output from the integral generators is
reproducible across different platforms. For floating point generators,
we only promise reproducibility on platforms that obey the IEEE 754
standard, and where `float` is 4 bytes and `double` is 8 bytes. We provide
no guarantees for `long double`, as the internals of `long double` can
vary wildly across different platforms.
## Generator interface
You can also implement your own generators, by deriving from the
Expand Down
4 changes: 4 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ set(IMPL_HEADERS
${SOURCES_DIR}/internal/catch_polyfills.hpp
${SOURCES_DIR}/internal/catch_preprocessor.hpp
${SOURCES_DIR}/internal/catch_preprocessor_remove_parens.hpp
${SOURCES_DIR}/internal/catch_random_floating_point_helpers.hpp
${SOURCES_DIR}/internal/catch_random_integer_helpers.hpp
${SOURCES_DIR}/internal/catch_random_number_generator.hpp
${SOURCES_DIR}/internal/catch_random_seed_generation.hpp
${SOURCES_DIR}/internal/catch_reporter_registry.hpp
Expand Down Expand Up @@ -138,6 +140,8 @@ set(IMPL_HEADERS
${SOURCES_DIR}/internal/catch_textflow.hpp
${SOURCES_DIR}/internal/catch_to_string.hpp
${SOURCES_DIR}/internal/catch_uncaught_exceptions.hpp
${SOURCES_DIR}/internal/catch_uniform_floating_point_distribution.hpp
${SOURCES_DIR}/internal/catch_uniform_integer_distribution.hpp
${SOURCES_DIR}/internal/catch_unique_name.hpp
${SOURCES_DIR}/internal/catch_unique_ptr.hpp
${SOURCES_DIR}/internal/catch_void_type.hpp
Expand Down
38 changes: 11 additions & 27 deletions src/catch2/benchmark/detail/catch_stats.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#include <catch2/benchmark/detail/catch_stats.hpp>

#include <catch2/internal/catch_compiler_capabilities.hpp>
#include <catch2/internal/catch_floating_point_helpers.hpp>
#include <catch2/internal/catch_random_number_generator.hpp>

#include <algorithm>
#include <cassert>
Expand Down Expand Up @@ -184,20 +186,6 @@ namespace Catch {
return std::sqrt( variance );
}

#if defined( __GNUC__ ) || defined( __clang__ )
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// Used when we know we want == comparison of two doubles
// to centralize warning suppression
static bool directCompare( double lhs, double rhs ) {
return lhs == rhs;
}
#if defined( __GNUC__ ) || defined( __clang__ )
# pragma GCC diagnostic pop
#endif


static sample jackknife( double ( *estimator )( double const*,
double const* ),
double* first,
Expand Down Expand Up @@ -234,7 +222,7 @@ namespace Catch {
double g = idx - j;
std::nth_element(first, first + j, last);
auto xj = first[j];
if ( directCompare( g, 0 ) ) {
if ( Catch::Detail::directCompare( g, 0 ) ) {
return xj;
}

Expand Down Expand Up @@ -338,7 +326,7 @@ namespace Catch {
[point]( double x ) { return x < point; } ) /
static_cast<double>( n );
// degenerate case with uniform samples
if ( directCompare( prob_n, 0. ) ) {
if ( Catch::Detail::directCompare( prob_n, 0. ) ) {
return { point, point, point, confidence_level };
}

Expand Down Expand Up @@ -367,21 +355,15 @@ namespace Catch {
unsigned int n_resamples,
double* first,
double* last) {
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
static std::random_device entropy;
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION

auto n = static_cast<int>(last - first); // seriously, one can't use integral types without hell in C++

auto mean = &Detail::mean;
auto stddev = &standard_deviation;

#if defined(CATCH_CONFIG_USE_ASYNC)
auto Estimate = [=](double(*f)(double const*, double const*)) {
auto seed = entropy();
std::random_device rd;
auto seed = rd();
return std::async(std::launch::async, [=] {
std::mt19937 rng(seed);
SimplePcg32 rng( seed );
auto resampled = resample(rng, n_resamples, first, last, f);
return bootstrap(confidence_level, first, last, resampled, f);
});
Expand All @@ -394,8 +376,9 @@ namespace Catch {
auto stddev_estimate = stddev_future.get();
#else
auto Estimate = [=](double(*f)(double const* , double const*)) {
auto seed = entropy();
std::mt19937 rng(seed);
std::random_device rd;
auto seed = rd();
SimplePcg32 rng( seed );
auto resampled = resample(rng, n_resamples, first, last, f);
return bootstrap(confidence_level, first, last, resampled, f);
};
Expand All @@ -404,6 +387,7 @@ namespace Catch {
auto stddev_estimate = Estimate(stddev);
#endif // CATCH_USE_ASYNC

auto n = static_cast<int>(last - first); // seriously, one can't use integral types without hell in C++
double outlier_variance = Detail::outlier_variance(mean_estimate, stddev_estimate, n);

return { mean_estimate, stddev_estimate, outlier_variance };
Expand Down
4 changes: 4 additions & 0 deletions src/catch2/catch_all.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@
#include <catch2/internal/catch_preprocessor.hpp>
#include <catch2/internal/catch_preprocessor_internal_stringify.hpp>
#include <catch2/internal/catch_preprocessor_remove_parens.hpp>
#include <catch2/internal/catch_random_floating_point_helpers.hpp>
#include <catch2/internal/catch_random_integer_helpers.hpp>
#include <catch2/internal/catch_random_number_generator.hpp>
#include <catch2/internal/catch_random_seed_generation.hpp>
#include <catch2/internal/catch_reporter_registry.hpp>
Expand Down Expand Up @@ -120,6 +122,8 @@
#include <catch2/internal/catch_textflow.hpp>
#include <catch2/internal/catch_to_string.hpp>
#include <catch2/internal/catch_uncaught_exceptions.hpp>
#include <catch2/internal/catch_uniform_floating_point_distribution.hpp>
#include <catch2/internal/catch_uniform_integer_distribution.hpp>
#include <catch2/internal/catch_unique_name.hpp>
#include <catch2/internal/catch_unique_ptr.hpp>
#include <catch2/internal/catch_void_type.hpp>
Expand Down
32 changes: 30 additions & 2 deletions src/catch2/generators/catch_generators_random.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,35 @@
// SPDX-License-Identifier: BSL-1.0

#include <catch2/generators/catch_generators_random.hpp>

#include <catch2/internal/catch_context.hpp>

std::uint32_t Catch::Generators::Detail::getSeed() { return sharedRng()(); }
#include <random>

namespace Catch {
namespace Generators {
namespace Detail {
std::uint32_t getSeed() { return sharedRng()(); }
} // namespace Detail

struct RandomFloatingGenerator<long double>::PImpl {
PImpl( long double a, long double b, uint32_t seed ):
rng( seed ), dist( a, b ) {}

Catch::SimplePcg32 rng;
std::uniform_real_distribution<long double> dist;
};

RandomFloatingGenerator<long double>::RandomFloatingGenerator(
long double a, long double b, std::uint32_t seed) :
m_pimpl(Catch::Detail::make_unique<PImpl>(a, b, seed)) {
static_cast<void>( next() );
}

RandomFloatingGenerator<long double>::~RandomFloatingGenerator() =
default;
bool RandomFloatingGenerator<long double>::next() {
m_current_number = m_pimpl->dist( m_pimpl->rng );
return true;
}
} // namespace Generators
} // namespace Catch
34 changes: 22 additions & 12 deletions src/catch2/generators/catch_generators_random.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@
#include <catch2/internal/catch_context.hpp>
#include <catch2/generators/catch_generators.hpp>
#include <catch2/internal/catch_random_number_generator.hpp>

#include <random>
#include <catch2/internal/catch_uniform_integer_distribution.hpp>
#include <catch2/internal/catch_uniform_floating_point_distribution.hpp>
#include <catch2/internal/catch_unique_ptr.hpp>

namespace Catch {
namespace Generators {
Expand All @@ -26,7 +27,7 @@ namespace Detail {
template <typename Float>
class RandomFloatingGenerator final : public IGenerator<Float> {
Catch::SimplePcg32 m_rng;
std::uniform_real_distribution<Float> m_dist;
Catch::uniform_floating_point_distribution<Float> m_dist;
Float m_current_number;
public:
RandomFloatingGenerator( Float a, Float b, std::uint32_t seed ):
Expand All @@ -44,10 +45,27 @@ class RandomFloatingGenerator final : public IGenerator<Float> {
}
};

template <>
class RandomFloatingGenerator<long double> final : public IGenerator<long double> {
// We still rely on <random> for this specialization, but we don't
// want to drag it into the header.
struct PImpl;
Catch::Detail::unique_ptr<PImpl> m_pimpl;
long double m_current_number;

public:
RandomFloatingGenerator( long double a, long double b, std::uint32_t seed );

long double const& get() const override { return m_current_number; }
bool next() override;

~RandomFloatingGenerator() override; // = default
};

template <typename Integer>
class RandomIntegerGenerator final : public IGenerator<Integer> {
Catch::SimplePcg32 m_rng;
std::uniform_int_distribution<Integer> m_dist;
Catch::uniform_integer_distribution<Integer> m_dist;
Integer m_current_number;
public:
RandomIntegerGenerator( Integer a, Integer b, std::uint32_t seed ):
Expand All @@ -68,14 +86,6 @@ class RandomIntegerGenerator final : public IGenerator<Integer> {
template <typename T>
std::enable_if_t<std::is_integral<T>::value, GeneratorWrapper<T>>
random(T a, T b) {
static_assert(
!std::is_same<T, char>::value &&
!std::is_same<T, int8_t>::value &&
!std::is_same<T, uint8_t>::value &&
!std::is_same<T, signed char>::value &&
!std::is_same<T, unsigned char>::value &&
!std::is_same<T, bool>::value,
"The requested type is not supported by the underlying random distributions from std" );
return GeneratorWrapper<T>(
Catch::Detail::make_unique<RandomIntegerGenerator<T>>(a, b, Detail::getSeed())
);
Expand Down
4 changes: 3 additions & 1 deletion src/catch2/internal/catch_compiler_capabilities.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,9 @@

////////////////////////////////////////////////////////////////////////////////
// Assume that some platforms do not support getenv.
#if defined(CATCH_PLATFORM_WINDOWS_UWP) || defined(CATCH_PLATFORM_PLAYSTATION)
#if defined( CATCH_PLATFORM_WINDOWS_UWP ) || \
defined( CATCH_PLATFORM_PLAYSTATION ) || \
defined( _GAMING_XBOX )
# define CATCH_INTERNAL_CONFIG_NO_GETENV
#else
# define CATCH_INTERNAL_CONFIG_GETENV
Expand Down
11 changes: 11 additions & 0 deletions src/catch2/internal/catch_floating_point_helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,17 @@ namespace Catch {
return i;
}

#if defined( __GNUC__ ) || defined( __clang__ )
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
bool directCompare( float lhs, float rhs ) { return lhs == rhs; }
bool directCompare( double lhs, double rhs ) { return lhs == rhs; }
#if defined( __GNUC__ ) || defined( __clang__ )
# pragma GCC diagnostic pop
#endif


} // end namespace Detail
} // end namespace Catch

5 changes: 5 additions & 0 deletions src/catch2/internal/catch_floating_point_helpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ namespace Catch {
uint32_t convertToBits(float f);
uint64_t convertToBits(double d);

// Used when we know we want == comparison of two doubles
// to centralize warning suppression
bool directCompare( float lhs, float rhs );
bool directCompare( double lhs, double rhs );

} // end namespace Detail


Expand Down
8 changes: 8 additions & 0 deletions src/catch2/internal/catch_polyfills.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,12 @@ namespace Catch {
}
#endif

#if !defined( CATCH_CONFIG_GLOBAL_NEXTAFTER )
float nextafter( float x, float y ) { return std::nextafter( x, y ); }
double nextafter( double x, double y ) { return std::nextafter( x, y ); }
#else
float nextafter( float x, float y ) { return ::nextafterf( x, y ); }
double nextafter( double x, double y ) { return ::nextafter( x, y ); }
#endif

} // end namespace Catch
Loading

0 comments on commit 10781ff

Please sign in to comment.