Read-only mirrors. Development, issues and pull requests are on GitHub.

summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMartin Hořeňovský2019-10-13 23:44:18 +0200
committerMartin Hořeňovský2019-10-13 23:44:18 +0200
commit7c9f92bc1c6e82ad5b6af8dff9f97af880fae9c6 (patch)
treed8bc58457176ac973c4a4c8f60c34cdb154af151
parenta92a7d02290eae896413a7d96e4875587c0dcd42 (diff)
downloadcatch3-2.10.0.tar.gz
v2.10.0v2.10.0
-rw-r--r--CMakeLists.txt2
-rw-r--r--README.md4
-rw-r--r--docs/configuration.md2
-rw-r--r--docs/generators.md4
-rw-r--r--docs/matchers.md4
-rw-r--r--docs/release-notes.md45
-rw-r--r--include/catch.hpp4
-rw-r--r--include/internal/catch_version.cpp2
-rw-r--r--single_include/catch2/catch.hpp930
-rw-r--r--single_include/catch2/catch_reporter_teamcity.hpp3
10 files changed, 665 insertions, 335 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0abdbe82..edb91c43 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -6,7 +6,7 @@ if(NOT DEFINED PROJECT_NAME)
set(NOT_SUBPROJECT ON)
endif()
-project(Catch2 LANGUAGES CXX VERSION 2.9.2)
+project(Catch2 LANGUAGES CXX VERSION 2.10.0)
if (CMAKE_BINARY_DIR STREQUAL CMAKE_SOURCE_DIR)
message(FATAL_ERROR "Building in-source is not supported! Create a build dir and remove ${CMAKE_SOURCE_DIR}/CMakeCache.txt")
diff --git a/README.md b/README.md
index 98a95034..2b806cd4 100644
--- a/README.md
+++ b/README.md
@@ -5,11 +5,11 @@
[![Build Status](https://travis-ci.org/catchorg/Catch2.svg?branch=master)](https://travis-ci.org/catchorg/Catch2)
[![Build status](https://ci.appveyor.com/api/projects/status/github/catchorg/Catch2?svg=true)](https://ci.appveyor.com/project/catchorg/catch2)
[![codecov](https://codecov.io/gh/catchorg/Catch2/branch/master/graph/badge.svg)](https://codecov.io/gh/catchorg/Catch2)
-[![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://wandbox.org/permlink/8YrGVqYqqSC4Sc5R)
+[![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://wandbox.org/permlink/00GdTUbFWaV3bNah)
[![Join the chat in Discord: https://discord.gg/4CWS9zD](https://img.shields.io/badge/Discord-Chat!-brightgreen.svg)](https://discord.gg/4CWS9zD)
-<a href="https://github.com/catchorg/Catch2/releases/download/v2.9.2/catch.hpp">The latest version of the single header can be downloaded directly using this link</a>
+<a href="https://github.com/catchorg/Catch2/releases/download/v2.10.0/catch.hpp">The latest version of the single header can be downloaded directly using this link</a>
## Catch2 is released!
diff --git a/docs/configuration.md b/docs/configuration.md
index ec042c23..599bb9ae 100644
--- a/docs/configuration.md
+++ b/docs/configuration.md
@@ -158,7 +158,7 @@ by using `_NO_` in the macro, e.g. `CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS`.
CATCH_CONFIG_ANDROID_LOGWRITE // Use android's logging system for debug output
CATCH_CONFIG_GLOBAL_NEXTAFTER // Use nextafter{,f,l} instead of std::nextafter
-> [`CATCH_CONFIG_ANDROID_LOGWRITE`](https://github.com/catchorg/Catch2/issues/1743) and [`CATCH_CONFIG_GLOBAL_NEXTAFTER`](https://github.com/catchorg/Catch2/pull/1739) were introduced in Catch X.Y.Z
+> [`CATCH_CONFIG_ANDROID_LOGWRITE`](https://github.com/catchorg/Catch2/issues/1743) and [`CATCH_CONFIG_GLOBAL_NEXTAFTER`](https://github.com/catchorg/Catch2/pull/1739) were introduced in Catch 2.10.0
Currently Catch enables `CATCH_CONFIG_WINDOWS_SEH` only when compiled with MSVC, because some versions of MinGW do not have the necessary Win32 API support.
diff --git a/docs/generators.md b/docs/generators.md
index 34565a50..61276f3c 100644
--- a/docs/generators.md
+++ b/docs/generators.md
@@ -54,7 +54,7 @@ a test case,
> `ChunkGenerator<T>`, `RandomIntegerGenerator<Integral>`, `RandomFloatGenerator<Float>` and `RangeGenerator<T>` were introduced in Catch 2.7.0.
-> `IteratorGenerator<T>` was introduced in Catch X.Y.Z.
+> `IteratorGenerator<T>` was introduced in Catch 2.10.0.
The generators also have associated helper functions that infer their
type, making their usage much nicer. These are
@@ -76,7 +76,7 @@ type, making their usage much nicer. These are
> `chunk()`, `random()` and both `range()` functions were introduced in Catch 2.7.0.
-> `from_range` has been introduced in Catch X.Y.Z
+> `from_range` has been introduced in Catch 2.10.0
And can be used as shown in the example below to create a generator
that returns 100 odd random number:
diff --git a/docs/matchers.md b/docs/matchers.md
index f10ae918..af2071e3 100644
--- a/docs/matchers.md
+++ b/docs/matchers.md
@@ -90,7 +90,7 @@ the helpers for this matcher, `WithinRel(double target, double margin)`,
`WithinRel(float target)`. The latter two provide a default epsilon of
machine epsilon * 100.
-> `WithinRel` matcher was introduced in Catch X.Y.Z
+> `WithinRel` matcher was introduced in Catch 2.10.0
### Generic matchers
Catch also aims to provide a set of generic matchers. Currently this set
@@ -120,7 +120,7 @@ is `ExceptionMessageMatcher`, and we also provide a helper function
The matched exception must publicly derive from `std::exception` and
the message matching is done _exactly_, including case.
-> `ExceptionMessageMatcher` was introduced in Catch X.Y.Z
+> `ExceptionMessageMatcher` was introduced in Catch 2.10.0
Example use:
```cpp
diff --git a/docs/release-notes.md b/docs/release-notes.md
index 204cea34..0af35c67 100644
--- a/docs/release-notes.md
+++ b/docs/release-notes.md
@@ -2,6 +2,7 @@
# Release notes
**Contents**<br>
+[2.10.0](#2100)<br>
[2.9.2](#292)<br>
[2.9.1](#291)<br>
[2.9.0](#290)<br>
@@ -28,6 +29,50 @@
[Even Older versions](#even-older-versions)<br>
+
+## 2.10.0
+
+### Fixes
+* `TEMPLATE_LIST_TEST_CASE` now properly handles non-copyable and non-movable types (#1729)
+* Fixed compilation error on Solaris caused by a system header defining macro `TT` (#1722, #1723)
+* `REGISTER_ENUM` will now fail at compilation time if the registered enum is too large
+* Removed use of `std::is_same_v` in C++17 mode (#1757)
+* Fixed parsing of escaped special characters when reading test specs from a file (#1767, #1769)
+
+
+### Improvements
+* Trailing and leading whitespace in test/section specs are now ignored.
+* Writing to Android debug log now uses `__android_log_write` instead of `__android_log_print`
+* Android logging support can now be turned on/off at compile time (#1743)
+ * The toggle is `CATCH_CONFIG_ANDROID_LOGWRITE`
+* Added a generator that returns elements of a range
+ * Use via `from_range(from, to)` or `from_range(container)`
+* Added support for CRTs that do not provide `std::nextafter` (#1739)
+ * They must still provide global `nextafter{f,l,}`
+ * Enabled via `CATCH_CONFIG_GLOBAL_NEXTAFTER`
+* Special cased `Approx(inf)` not to match non-infinite values
+ * Very strictly speaking this might be a breaking change, but it should match user expectations better
+* The output of benchmarking through the Console reporter when `--benchmark-no-analysis` is set is now much simpler (#1768)
+* Added a matcher that can be used for checking an exceptions message (#1649, #1728)
+ * The matcher helper function is called `Message`
+ * The exception must publicly derive from `std::exception`
+ * The matching is done exactly, including case and whitespace
+* Added a matcher that can be used for checking relative equality of floating point numbers (#1746)
+ * Unlike `Approx`, it considers both sides when determining the allowed margin
+ * Special cases `NaN` and `INFINITY` to match user expectations
+ * The matcher helper function is called `WithinRel`
+* The ULP matcher now allows for any possible distance between the two numbers
+* The random number generators now use Catch-global instance of RNG (#1734, #1736)
+ * This means that nested random number generators actually generate different numbers
+
+
+### Miscellaneous
+* In-repo PNGs have been optimized to lower overhead of using Catch2 via git clone
+* Catch2 now uses its own implementation of the URBG concept
+ * In the future we also plan to use our own implementation of the distributions from `<random>` to provide cross-platform repeatability of random results
+
+
+
## 2.9.2
### Fixes
diff --git a/include/catch.hpp b/include/catch.hpp
index dba005ad..5d38092e 100644
--- a/include/catch.hpp
+++ b/include/catch.hpp
@@ -10,8 +10,8 @@
#define TWOBLUECUBES_CATCH_HPP_INCLUDED
#define CATCH_VERSION_MAJOR 2
-#define CATCH_VERSION_MINOR 9
-#define CATCH_VERSION_PATCH 2
+#define CATCH_VERSION_MINOR 10
+#define CATCH_VERSION_PATCH 0
#ifdef __clang__
# pragma clang system_header
diff --git a/include/internal/catch_version.cpp b/include/internal/catch_version.cpp
index 03fded91..bb5b0616 100644
--- a/include/internal/catch_version.cpp
+++ b/include/internal/catch_version.cpp
@@ -37,7 +37,7 @@ namespace Catch {
}
Version const& libraryVersion() {
- static Version version( 2, 9, 2, "", 0 );
+ static Version version( 2, 10, 0, "", 0 );
return version;
}
diff --git a/single_include/catch2/catch.hpp b/single_include/catch2/catch.hpp
index 5feb2a4b..391db530 100644
--- a/single_include/catch2/catch.hpp
+++ b/single_include/catch2/catch.hpp
@@ -1,6 +1,6 @@
/*
- * Catch v2.9.2
- * Generated: 2019-08-08 13:35:12.279703
+ * Catch v2.10.0
+ * Generated: 2019-10-13 22:24:46.755734
* ----------------------------------------------------------
* This file has been merged from multiple headers. Please don't edit it directly
* Copyright (c) 2019 Two Blue Cubes Ltd. All rights reserved.
@@ -14,8 +14,8 @@
#define CATCH_VERSION_MAJOR 2
-#define CATCH_VERSION_MINOR 9
-#define CATCH_VERSION_PATCH 2
+#define CATCH_VERSION_MINOR 10
+#define CATCH_VERSION_PATCH 0
#ifdef __clang__
# pragma clang system_header
@@ -186,6 +186,7 @@ namespace Catch {
// Android somehow still does not support std::to_string
#if defined(__ANDROID__)
# define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
+# define CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE
#endif
////////////////////////////////////////////////////////////////////////////////
@@ -286,49 +287,43 @@ namespace Catch {
#define CATCH_CONFIG_COLOUR_NONE
#endif
-////////////////////////////////////////////////////////////////////////////////
-// Check if string_view is available and usable
-// The check is split apart to work around v140 (VS2015) preprocessor issue...
-#if defined(__has_include)
-#if __has_include(<string_view>) && defined(CATCH_CPP17_OR_GREATER)
-# define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW
-#endif
+#if defined(__UCLIBC__)
+#define CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER
#endif
-////////////////////////////////////////////////////////////////////////////////
-// Check if optional is available and usable
-#if defined(__has_include)
-# if __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
-# define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL
-# endif // __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
-#endif // __has_include
-
-////////////////////////////////////////////////////////////////////////////////
-// Check if byte is available and usable
+// Various stdlib support checks that require __has_include
#if defined(__has_include)
-# if __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
-# define CATCH_INTERNAL_CONFIG_CPP17_BYTE
-# endif // __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
-#endif // __has_include
-
-////////////////////////////////////////////////////////////////////////////////
-// Check if variant is available and usable
-#if defined(__has_include)
-# if __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
-# if defined(__clang__) && (__clang_major__ < 8)
- // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852
- // fix should be in clang 8, workaround in libstdc++ 8.2
-# include <ciso646>
-# if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
-# define CATCH_CONFIG_NO_CPP17_VARIANT
-# else
-# define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
-# endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
-# else
-# define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
-# endif // defined(__clang__) && (__clang_major__ < 8)
-# endif // __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
-#endif // __has_include
+ // Check if string_view is available and usable
+ #if __has_include(<string_view>) && defined(CATCH_CPP17_OR_GREATER)
+ # define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW
+ #endif
+
+ // Check if optional is available and usable
+ # if __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
+ # define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL
+ # endif // __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
+
+ // Check if byte is available and usable
+ # if __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
+ # define CATCH_INTERNAL_CONFIG_CPP17_BYTE
+ # endif // __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
+
+ // Check if variant is available and usable
+ # if __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
+ # if defined(__clang__) && (__clang_major__ < 8)
+ // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852
+ // fix should be in clang 8, workaround in libstdc++ 8.2
+ # include <ciso646>
+ # if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
+ # define CATCH_CONFIG_NO_CPP17_VARIANT
+ # else
+ # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
+ # endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
+ # else
+ # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
+ # endif // defined(__clang__) && (__clang_major__ < 8)
+ # endif // __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
+#endif // defined(__has_include)
#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
# define CATCH_CONFIG_COUNTER
@@ -389,6 +384,14 @@ namespace Catch {
# define CATCH_CONFIG_USE_ASYNC
#endif
+#if defined(CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_NO_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_ANDROID_LOGWRITE)
+# define CATCH_CONFIG_ANDROID_LOGWRITE
+#endif
+
+#if defined(CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_NO_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
+# define CATCH_CONFIG_GLOBAL_NEXTAFTER
+#endif
+
#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS
@@ -468,7 +471,7 @@ namespace Catch {
SourceLineInfo( SourceLineInfo&& ) noexcept = default;
SourceLineInfo& operator = ( SourceLineInfo&& ) noexcept = default;
- bool empty() const noexcept;
+ bool empty() const noexcept { return file[0] == '\0'; }
bool operator == ( SourceLineInfo const& other ) const noexcept;
bool operator < ( SourceLineInfo const& other ) const noexcept;
@@ -551,6 +554,7 @@ namespace Catch {
#include <cstddef>
#include <string>
#include <iosfwd>
+#include <cassert>
namespace Catch {
@@ -564,6 +568,7 @@ namespace Catch {
class StringRef {
public:
using size_type = std::size_t;
+ using const_iterator = const char*;
private:
friend struct StringRefTestAccess;
@@ -619,7 +624,9 @@ namespace Catch {
return *this;
}
- operator std::string() const;
+ explicit operator std::string() const {
+ return std::string(m_start, m_size);
+ }
void swap( StringRef& other ) noexcept;
@@ -627,7 +634,10 @@ namespace Catch {
auto operator == ( StringRef const& other ) const noexcept -> bool;
auto operator != ( StringRef const& other ) const noexcept -> bool;
- auto operator[] ( size_type index ) const noexcept -> char;
+ auto operator[] ( size_type index ) const noexcept -> char {
+ assert(index < m_size);
+ return m_start[index];
+ }
public: // named queries
auto empty() const noexcept -> bool {
@@ -637,7 +647,6 @@ namespace Catch {
return m_size;
}
- auto numberOfCharacters() const noexcept -> size_type;
auto c_str() const -> char const*;
public: // substrings and searches
@@ -647,15 +656,15 @@ namespace Catch {
// Note that the pointer can change when if the StringRef is a substring
auto currentData() const noexcept -> char const*;
+ public: // iterators
+ const_iterator begin() const { return m_start; }
+ const_iterator end() const { return m_start + m_size; }
+
private: // ownership queries - may not be consistent between calls
auto isOwned() const noexcept -> bool;
auto isSubstring() const noexcept -> bool;
};
- auto operator + ( StringRef const& lhs, StringRef const& rhs ) -> std::string;
- auto operator + ( StringRef const& lhs, char const* rhs ) -> std::string;
- auto operator + ( char const* lhs, StringRef const& rhs ) -> std::string;
-
auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&;
auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&;
@@ -670,38 +679,6 @@ inline auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noex
}
// end catch_stringref.h
-// start catch_type_traits.hpp
-
-
-#include <type_traits>
-
-namespace Catch{
-
-#ifdef CATCH_CPP17_OR_GREATER
- template <typename...>
- inline constexpr auto is_unique = std::true_type{};
-
- template <typename T, typename... Rest>
- inline constexpr auto is_unique<T, Rest...> = std::bool_constant<
- (!std::is_same_v<T, Rest> && ...) && is_unique<Rest...>
- >{};
-#else
-
-template <typename...>
-struct is_unique : std::true_type{};
-
-template <typename T0, typename T1, typename... Rest>
-struct is_unique<T0, T1, Rest...> : std::integral_constant
-<bool,
- !std::is_same<T0, T1>::value
- && is_unique<T0, Rest...>::value
- && is_unique<T1, Rest...>::value
->{};
-
-#endif
-}
-
-// end catch_type_traits.hpp
// start catch_preprocessor.hpp
@@ -814,7 +791,7 @@ struct is_unique<T0, T1, Rest...> : std::integral_constant
template<template <typename...> class Final, template< typename...> class...Containers, typename...Types>\
constexpr auto create(TypeList<Types...>) noexcept -> decltype(append(Final<>{}, rewrap<Containers>(Types{}...)...)) { return {}; }\
template<template <typename...> class Final, template <typename...> class List, typename...Ts>\
- constexpr auto convert(List<Ts...>) noexcept -> decltype(append(Final<>{},TypeList<Ts>{}...)) { return {}; }
+ constexpr auto convert(const List<Ts...>& ) noexcept -> decltype(append(Final<>{},TypeList<Ts>{}...)) { return {}; }
#define INTERNAL_CATCH_NTTP_1(signature, ...)\
template<INTERNAL_CATCH_REMOVE_PARENS(signature)> struct Nttp{};\
@@ -1443,7 +1420,7 @@ namespace Catch {
namespace Detail {
struct EnumInfo {
StringRef m_name;
- std::vector<std::pair<int, std::string>> m_values;
+ std::vector<std::pair<int, StringRef>> m_values;
~EnumInfo();
@@ -1458,6 +1435,7 @@ namespace Catch {
template<typename E>
Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::initializer_list<E> values ) {
+ static_assert(sizeof(int) >= sizeof(E), "Cannot serialize enum to int");
std::vector<int> intValues;
intValues.reserve( values.size() );
for( auto enumValue : values )
@@ -1539,9 +1517,9 @@ namespace Catch {
template<typename T>
class IsStreamInsertable {
- template<typename SS, typename TT>
+ template<typename Stream, typename U>
static auto test(int)
- -> decltype(std::declval<SS&>() << std::declval<TT>(), std::true_type());
+ -> decltype(std::declval<Stream&>() << std::declval<U>(), std::true_type());
template<typename, typename>
static auto test(...)->std::false_type;
@@ -2144,7 +2122,7 @@ namespace Catch { \
template<> struct StringMaker<enumName> { \
static std::string convert( enumName value ) { \
static const auto& enumInfo = ::Catch::getMutableRegistryHub().getMutableEnumValuesRegistry().registerEnum( #enumName, #__VA_ARGS__, { __VA_ARGS__ } ); \
- return enumInfo.lookup( static_cast<int>( value ) ); \
+ return static_cast<std::string>(enumInfo.lookup( static_cast<int>( value ) )); \
} \
}; \
}
@@ -3154,7 +3132,10 @@ namespace Catch {
bool contains( std::string const& s, std::string const& infix );
void toLowerInPlace( std::string& s );
std::string toLower( std::string const& s );
+ //! Returns a new string without whitespace at the start/end
std::string trim( std::string const& str );
+ //! Returns a substring of the original ref without whitespace. Beware lifetimes!
+ StringRef trim(StringRef ref);
// !!! Be aware, returns refs into original string - make sure original string outlives them
std::vector<StringRef> splitStringRef( StringRef str, char delimiter );
@@ -3335,10 +3316,34 @@ using Matchers::Impl::MatcherBase;
} // namespace Catch
// end catch_matchers.h
-// start catch_matchers_floating.h
+// start catch_matchers_exception.hpp
-#include <type_traits>
-#include <cmath>
+namespace Catch {
+namespace Matchers {
+namespace Exception {
+
+class ExceptionMessageMatcher : public MatcherBase<std::exception> {
+ std::string m_message;
+public:
+
+ ExceptionMessageMatcher(std::string const& message):
+ m_message(message)
+ {}
+
+ bool match(std::exception const& ex) const override;
+
+ std::string describe() const override;
+};
+
+} // namespace Exception
+
+Exception::ExceptionMessageMatcher Message(std::string const& message);
+
+} // namespace Matchers
+} // namespace Catch
+
+// end catch_matchers_exception.hpp
+// start catch_matchers_floating.h
namespace Catch {
namespace Matchers {
@@ -3357,22 +3362,43 @@ namespace Matchers {
};
struct WithinUlpsMatcher : MatcherBase<double> {
- WithinUlpsMatcher(double target, int ulps, FloatingPointKind baseType);
+ WithinUlpsMatcher(double target, uint64_t ulps, FloatingPointKind baseType);
bool match(double const& matchee) const override;
std::string describe() const override;
private:
double m_target;
- int m_ulps;
+ uint64_t m_ulps;
FloatingPointKind m_type;
};
+ // Given IEEE-754 format for floats and doubles, we can assume
+ // that float -> double promotion is lossless. Given this, we can
+ // assume that if we do the standard relative comparison of
+ // |lhs - rhs| <= epsilon * max(fabs(lhs), fabs(rhs)), then we get
+ // the same result if we do this for floats, as if we do this for
+ // doubles that were promoted from floats.
+ struct WithinRelMatcher : MatcherBase<double> {
+ WithinRelMatcher(double target, double epsilon);
+ bool match(double const& matchee) const override;
+ std::string describe() const override;
+ private:
+ double m_target;
+ double m_epsilon;
+ };
+
} // namespace Floating
// The following functions create the actual matcher objects.
// This allows the types to be inferred
- Floating::WithinUlpsMatcher WithinULP(double target, int maxUlpDiff);
- Floating::WithinUlpsMatcher WithinULP(float target, int maxUlpDiff);
+ Floating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff);
+ Floating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff);
Floating::WithinAbsMatcher WithinAbs(double target, double margin);
+ Floating::WithinRelMatcher WithinRel(double target, double eps);
+ // defaults epsilon to 100*numeric_limits<double>::epsilon()
+ Floating::WithinRelMatcher WithinRel(double target);
+ Floating::WithinRelMatcher WithinRel(float target, float eps);
+ // defaults epsilon to 100*numeric_limits<float>::epsilon()
+ Floating::WithinRelMatcher WithinRel(float target);
} // namespace Matchers
} // namespace Catch
@@ -3797,13 +3823,13 @@ namespace Catch {
(Catch::ReusableStringStream() << __VA_ARGS__).str()
#define CATCH_INTERNAL_ERROR(...) \
- Catch::throw_logic_error(CATCH_MAKE_MSG( CATCH_INTERNAL_LINEINFO << ": Internal Catch2 error: " << __VA_ARGS__));
+ Catch::throw_logic_error(CATCH_MAKE_MSG( CATCH_INTERNAL_LINEINFO << ": Internal Catch2 error: " << __VA_ARGS__))
#define CATCH_ERROR(...) \
- Catch::throw_domain_error(CATCH_MAKE_MSG( __VA_ARGS__ ));
+ Catch::throw_domain_error(CATCH_MAKE_MSG( __VA_ARGS__ ))
#define CATCH_RUNTIME_ERROR(...) \
- Catch::throw_runtime_error(CATCH_MAKE_MSG( __VA_ARGS__ ));
+ Catch::throw_runtime_error(CATCH_MAKE_MSG( __VA_ARGS__ ))
#define CATCH_ENFORCE( condition, ... ) \
do{ if( !(condition) ) CATCH_ERROR( __VA_ARGS__ ); } while(false)
@@ -3869,7 +3895,7 @@ namespace Generators {
template<typename T>
class FixedValuesGenerator final : public IGenerator<T> {
static_assert(!std::is_same<T, bool>::value,
- "ValuesGenerator does not support bools because of std::vector<bool>"
+ "FixedValuesGenerator does not support bools because of std::vector<bool>"
"specialization, use SingleValue Generator instead.");
std::vector<T> m_values;
size_t m_idx = 0;
@@ -4294,6 +4320,9 @@ namespace Catch {
}
void cleanUpContext();
+
+ class SimplePcg32;
+ SimplePcg32& rng();
}
// end catch_context.h
@@ -4440,6 +4469,56 @@ namespace Catch {
}
// end catch_interfaces_config.h
+// start catch_random_number_generator.h
+
+#include <cstdint>
+
+namespace Catch {
+
+ // This is a simple implementation of C++11 Uniform Random Number
+ // Generator. It does not provide all operators, because Catch2
+ // does not use it, but it should behave as expected inside stdlib's
+ // distributions.
+ // The implementation is based on the PCG family (http://pcg-random.org)
+ class SimplePcg32 {
+ using state_type = std::uint64_t;
+ public:
+ using result_type = std::uint32_t;
+ static constexpr result_type min() {
+ return 0;
+ }
+ static constexpr result_type max() {
+ return static_cast<result_type>(-1);
+ }
+
+ // Provide some default initial state for the default constructor
+ SimplePcg32():SimplePcg32(0xed743cc4U) {}
+
+ explicit SimplePcg32(result_type seed_);
+
+ void seed(result_type seed_);
+ void discard(uint64_t skip);
+
+ result_type operator()();
+
+ private:
+ friend bool operator==(SimplePcg32 const& lhs, SimplePcg32 const& rhs);
+ friend bool operator!=(SimplePcg32 const& lhs, SimplePcg32 const& rhs);
+
+ // In theory we also need operator<< and operator>>
+ // In practice we do not use them, so we will skip them for now
+
+ std::uint64_t m_state;
+ // This part of the state determines which "stream" of the numbers
+ // is chosen -- we take it as a constant for Catch2, so we only
+ // need to deal with seeding the main state.
+ // Picked by reading 8 bytes from `/dev/random` :-)
+ static const std::uint64_t s_inc = (0x13ed0cc53f939476ULL << 1ULL) | 1ULL;
+ };
+
+} // end namespace Catch
+
+// end catch_random_number_generator.h
#include <random>
namespace Catch {
@@ -4447,14 +4526,13 @@ namespace Generators {
template <typename Float>
class RandomFloatingGenerator final : public IGenerator<Float> {
- // FIXME: What is the right seed?
- std::minstd_rand m_rand;
+ Catch::SimplePcg32& m_rng;
std::uniform_real_distribution<Float> m_dist;
Float m_current_number;
public:
RandomFloatingGenerator(Float a, Float b):
- m_rand(getCurrentContext().getConfig()->rngSeed()),
+ m_rng(rng()),
m_dist(a, b) {
static_cast<void>(next());
}
@@ -4463,20 +4541,20 @@ public:
return m_current_number;
}
bool next() override {
- m_current_number = m_dist(m_rand);
+ m_current_number = m_dist(m_rng);
return true;
}
};
template <typename Integer>
class RandomIntegerGenerator final : public IGenerator<Integer> {
- std::minstd_rand m_rand;
+ Catch::SimplePcg32& m_rng;
std::uniform_int_distribution<Integer> m_dist;
Integer m_current_number;
public:
RandomIntegerGenerator(Integer a, Integer b):
- m_rand(getCurrentContext().getConfig()->rngSeed()),
+ m_rng(rng()),
m_dist(a, b) {
static_cast<void>(next());
}
@@ -4485,7 +4563,7 @@ public:
return m_current_number;
}
bool next() override {
- m_current_number = m_dist(m_rand);
+ m_current_number = m_dist(m_rng);
return true;
}
};
@@ -4555,6 +4633,45 @@ GeneratorWrapper<T> range(T const& start, T const& end) {
return GeneratorWrapper<T>(pf::make_unique<RangeGenerator<T>>(start, end));
}
+template <typename T>
+class IteratorGenerator final : public IGenerator<T> {
+ static_assert(!std::is_same<T, bool>::value,
+ "IteratorGenerator currently does not support bools"
+ "because of std::vector<bool> specialization");
+
+ std::vector<T> m_elems;
+ size_t m_current = 0;
+public:
+ template <typename InputIterator, typename InputSentinel>
+ IteratorGenerator(InputIterator first, InputSentinel last):m_elems(first, last) {
+ if (m_elems.empty()) {
+ Catch::throw_exception(GeneratorException("IteratorGenerator received no valid values"));
+ }
+ }
+
+ T const& get() const override {
+ return m_elems[m_current];
+ }
+
+ bool next() override {
+ ++m_current;
+ return m_current != m_elems.size();
+ }
+};
+
+template <typename InputIterator,
+ typename InputSentinel,
+ typename ResultType = typename std::iterator_traits<InputIterator>::value_type>
+GeneratorWrapper<ResultType> from_range(InputIterator from, InputSentinel to) {
+ return GeneratorWrapper<ResultType>(pf::make_unique<IteratorGenerator<ResultType>>(from, to));
+}
+
+template <typename Container,
+ typename ResultType = typename Container::value_type>
+GeneratorWrapper<ResultType> from_range(Container const& cnt) {
+ return GeneratorWrapper<ResultType>(pf::make_unique<IteratorGenerator<ResultType>>(cnt.begin(), cnt.end()));
+}
+
} // namespace Generators
} // namespace Catch
@@ -4900,7 +5017,7 @@ namespace Catch
virtual bool matches( std::string const& str ) const;
private:
- std::string adjustCase( std::string const& str ) const;
+ std::string normaliseString( std::string const& str ) const;
CaseSensitive::Choice m_caseSensitivity;
WildcardPosition m_wildcard = NoWildcard;
std::string m_pattern;
@@ -5007,8 +5124,10 @@ namespace Catch {
class TestSpecParser {
enum Mode{ None, Name, QuotedName, Tag, EscapedName };
Mode m_mode = None;
+ Mode lastMode = None;
bool m_exclusion = false;
std::size_t m_pos = 0;
+ std::size_t m_realPatternPos = 0;
std::string m_arg;
std::string m_substring;
std::string m_patternName;
@@ -5032,6 +5151,8 @@ namespace Catch {
void endMode();
void escape();
bool isControlChar( char c ) const;
+ void saveLastMode();
+ void revertBackToLastMode();
template<typename T>
void addPattern() {
@@ -7292,6 +7413,7 @@ namespace TestCaseTracking {
class SectionTracker : public TrackerBase {
std::vector<std::string> m_filters;
+ std::string m_trimmed_name;
public:
SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
@@ -7583,7 +7705,8 @@ namespace Detail {
bool Approx::equalityComparisonImpl(const double other) const {
// First try with fixed margin, then compute margin based on epsilon, scale and Approx's value
// Thanks to Richard Harris for his help refining the scaled margin value
- return marginComparison(m_value, other, m_margin) || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(m_value)));
+ return marginComparison(m_value, other, m_margin)
+ || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(std::isinf(m_value)? 0 : m_value)));
}
void Approx::setMargin(double newMargin) {
@@ -7868,6 +7991,8 @@ namespace Catch {
bool m_includeSuccessfulResults;
};
+ void seedRng(IConfig const& config);
+ unsigned int rngSeed();
} // end namespace Catch
// end catch_run_context.h
@@ -8014,7 +8139,7 @@ namespace Catch {
}
bool AssertionResult: