|
@@ -434,19 +434,24 @@ unsigned int rngSeed();
|
|
|
#include <cstdint>
|
|
|
|
|
|
// We need a dummy global operator<< so we can bring it into Catch namespace later
|
|
|
-struct Catch_global_namespace_dummy {};
|
|
|
+struct Catch_global_namespace_dummy
|
|
|
+{
|
|
|
+};
|
|
|
std::ostream &operator<<(std::ostream &, Catch_global_namespace_dummy);
|
|
|
|
|
|
namespace Catch {
|
|
|
|
|
|
-struct CaseSensitive {
|
|
|
- enum Choice {
|
|
|
+struct CaseSensitive
|
|
|
+{
|
|
|
+ enum Choice
|
|
|
+ {
|
|
|
Yes,
|
|
|
No
|
|
|
};
|
|
|
};
|
|
|
|
|
|
-class NonCopyable {
|
|
|
+class NonCopyable
|
|
|
+{
|
|
|
NonCopyable(NonCopyable const &) = delete;
|
|
|
NonCopyable(NonCopyable &&) = delete;
|
|
|
NonCopyable &operator=(NonCopyable const &) = delete;
|
|
@@ -457,12 +462,14 @@ protected:
|
|
|
virtual ~NonCopyable();
|
|
|
};
|
|
|
|
|
|
-struct SourceLineInfo {
|
|
|
+struct SourceLineInfo
|
|
|
+{
|
|
|
|
|
|
SourceLineInfo() = delete;
|
|
|
SourceLineInfo(char const *_file, std::size_t _line) noexcept
|
|
|
: file(_file),
|
|
|
- line(_line) {}
|
|
|
+ line(_line)
|
|
|
+ {}
|
|
|
|
|
|
SourceLineInfo(SourceLineInfo const &other) = default;
|
|
|
SourceLineInfo &operator=(SourceLineInfo const &) = default;
|
|
@@ -488,11 +495,13 @@ using ::operator<<;
|
|
|
// >> +StreamEndStop
|
|
|
// as well as
|
|
|
// >> stuff +StreamEndStop
|
|
|
-struct StreamEndStop {
|
|
|
+struct StreamEndStop
|
|
|
+{
|
|
|
std::string operator+() const;
|
|
|
};
|
|
|
template<typename T>
|
|
|
-T const &operator+(T const &value, StreamEndStop) {
|
|
|
+T const &operator+(T const &value, StreamEndStop)
|
|
|
+{
|
|
|
return value;
|
|
|
}
|
|
|
}
|
|
@@ -503,7 +512,8 @@ T const &operator+(T const &value, StreamEndStop) {
|
|
|
// end catch_common.h
|
|
|
namespace Catch {
|
|
|
|
|
|
-struct RegistrarForTagAliases {
|
|
|
+struct RegistrarForTagAliases
|
|
|
+{
|
|
|
RegistrarForTagAliases(char const *alias, char const *tag, SourceLineInfo const &lineInfo);
|
|
|
};
|
|
|
|
|
@@ -525,7 +535,8 @@ namespace Catch {
|
|
|
|
|
|
class TestSpec;
|
|
|
|
|
|
-struct ITestInvoker {
|
|
|
+struct ITestInvoker
|
|
|
+{
|
|
|
virtual void invoke() const = 0;
|
|
|
virtual ~ITestInvoker();
|
|
|
};
|
|
@@ -533,7 +544,8 @@ struct ITestInvoker {
|
|
|
class TestCase;
|
|
|
struct IConfig;
|
|
|
|
|
|
-struct ITestCaseRegistry {
|
|
|
+struct ITestCaseRegistry
|
|
|
+{
|
|
|
virtual ~ITestCaseRegistry();
|
|
|
virtual std::vector<TestCase> const &getAllTests() const = 0;
|
|
|
virtual std::vector<TestCase> const &getAllTestsSorted(IConfig const &config) const = 0;
|
|
@@ -564,7 +576,8 @@ namespace Catch {
|
|
|
/// (taking a copy), if necessary. In theory this ownership is not externally
|
|
|
/// visible - but it does mean (substring) StringRefs should not be shared between
|
|
|
/// threads.
|
|
|
-class StringRef {
|
|
|
+class StringRef
|
|
|
+{
|
|
|
public:
|
|
|
using size_type = std::size_t;
|
|
|
|
|
@@ -582,16 +595,19 @@ private:
|
|
|
|
|
|
public: // construction/ assignment
|
|
|
StringRef() noexcept
|
|
|
- : StringRef(s_empty, 0) {}
|
|
|
+ : StringRef(s_empty, 0)
|
|
|
+ {}
|
|
|
|
|
|
StringRef(StringRef const &other) noexcept
|
|
|
: m_start(other.m_start),
|
|
|
- m_size(other.m_size) {}
|
|
|
+ m_size(other.m_size)
|
|
|
+ {}
|
|
|
|
|
|
StringRef(StringRef &&other) noexcept
|
|
|
: m_start(other.m_start),
|
|
|
m_size(other.m_size),
|
|
|
- m_data(other.m_data) {
|
|
|
+ m_data(other.m_data)
|
|
|
+ {
|
|
|
other.m_data = nullptr;
|
|
|
}
|
|
|
|
|
@@ -599,17 +615,21 @@ public: // construction/ assignment
|
|
|
|
|
|
StringRef(char const *rawChars, size_type size) noexcept
|
|
|
: m_start(rawChars),
|
|
|
- m_size(size) {}
|
|
|
+ m_size(size)
|
|
|
+ {}
|
|
|
|
|
|
StringRef(std::string const &stdString) noexcept
|
|
|
: m_start(stdString.c_str()),
|
|
|
- m_size(stdString.size()) {}
|
|
|
+ m_size(stdString.size())
|
|
|
+ {}
|
|
|
|
|
|
- ~StringRef() noexcept {
|
|
|
+ ~StringRef() noexcept
|
|
|
+ {
|
|
|
delete[] m_data;
|
|
|
}
|
|
|
|
|
|
- auto operator=(StringRef const &other) noexcept -> StringRef & {
|
|
|
+ auto operator=(StringRef const &other) noexcept -> StringRef &
|
|
|
+ {
|
|
|
delete[] m_data;
|
|
|
m_data = nullptr;
|
|
|
m_start = other.m_start;
|
|
@@ -628,10 +648,12 @@ public: // operators
|
|
|
auto operator[](size_type index) const noexcept -> char;
|
|
|
|
|
|
public: // named queries
|
|
|
- auto empty() const noexcept -> bool {
|
|
|
+ auto empty() const noexcept -> bool
|
|
|
+ {
|
|
|
return m_size == 0;
|
|
|
}
|
|
|
- auto size() const noexcept -> size_type {
|
|
|
+ auto size() const noexcept -> size_type
|
|
|
+ {
|
|
|
return m_size;
|
|
|
}
|
|
|
|
|
@@ -657,14 +679,16 @@ auto operator+(char const *lhs, StringRef const &rhs) -> std::string;
|
|
|
auto operator+=(std::string &lhs, StringRef const &sr) -> std::string &;
|
|
|
auto operator<<(std::ostream &os, StringRef const &sr) -> std::ostream &;
|
|
|
|
|
|
-inline auto operator "" _sr(char const *rawChars, std::size_t size) noexcept -> StringRef {
|
|
|
+inline auto operator "" _sr(char const *rawChars, std::size_t size) noexcept -> StringRef
|
|
|
+{
|
|
|
return StringRef(rawChars, size);
|
|
|
}
|
|
|
|
|
|
} // namespace Catch
|
|
|
|
|
|
inline auto operator "" _catch_sr(char const *rawChars,
|
|
|
- std::size_t size) noexcept -> Catch::StringRef {
|
|
|
+ std::size_t size) noexcept -> Catch::StringRef
|
|
|
+{
|
|
|
return Catch::StringRef(rawChars, size);
|
|
|
}
|
|
|
|
|
@@ -687,7 +711,9 @@ namespace Catch {
|
|
|
#else
|
|
|
|
|
|
template<typename...>
|
|
|
-struct is_unique : std::true_type {};
|
|
|
+struct is_unique : std::true_type
|
|
|
+{
|
|
|
+};
|
|
|
|
|
|
template<typename T0, typename T1, typename... Rest>
|
|
|
struct is_unique<T0, T1, Rest...> : std::integral_constant
|
|
@@ -695,7 +721,8 @@ struct is_unique<T0, T1, Rest...> : std::integral_constant
|
|
|
!std::is_same<T0, T1>::value
|
|
|
&& is_unique<T0, Rest...>::value
|
|
|
&& is_unique<T1, Rest...>::value
|
|
|
- > {
|
|
|
+ >
|
|
|
+{
|
|
|
};
|
|
|
|
|
|
#endif
|
|
@@ -923,10 +950,15 @@ struct is_unique<T0, T1, Rest...> : std::integral_constant
|
|
|
|
|
|
namespace Catch {
|
|
|
template<typename T>
|
|
|
-struct always_false : std::false_type {};
|
|
|
+struct always_false : std::false_type
|
|
|
+{
|
|
|
+};
|
|
|
|
|
|
-template<typename> struct true_given : std::true_type {};
|
|
|
-struct is_callable_tester {
|
|
|
+template<typename> struct true_given : std::true_type
|
|
|
+{
|
|
|
+};
|
|
|
+struct is_callable_tester
|
|
|
+{
|
|
|
template<typename Fun, typename... Args>
|
|
|
true_given<decltype(std::declval<Fun>()(std::declval<Args>()...))> static test(int);
|
|
|
template<typename...>
|
|
@@ -937,7 +969,9 @@ template<typename T>
|
|
|
struct is_callable;
|
|
|
|
|
|
template<typename Fun, typename... Args>
|
|
|
-struct is_callable<Fun(Args...)> : decltype(is_callable_tester::test<Fun, Args...>(0)) {};
|
|
|
+struct is_callable<Fun(Args...)> : decltype(is_callable_tester::test<Fun, Args...>(0))
|
|
|
+{
|
|
|
+};
|
|
|
|
|
|
} // namespace Catch
|
|
|
|
|
@@ -949,12 +983,15 @@ struct na;
|
|
|
namespace Catch {
|
|
|
|
|
|
template<typename C>
|
|
|
-class TestInvokerAsMethod : public ITestInvoker {
|
|
|
+class TestInvokerAsMethod : public ITestInvoker
|
|
|
+{
|
|
|
void (C::*m_testAsMethod)();
|
|
|
public:
|
|
|
- TestInvokerAsMethod(void (C::*testAsMethod)()) noexcept : m_testAsMethod(testAsMethod) {}
|
|
|
+ TestInvokerAsMethod(void (C::*testAsMethod)()) noexcept : m_testAsMethod(testAsMethod)
|
|
|
+ {}
|
|
|
|
|
|
- void invoke() const override {
|
|
|
+ void invoke() const override
|
|
|
+ {
|
|
|
C obj;
|
|
|
(obj.*m_testAsMethod)();
|
|
|
}
|
|
@@ -963,18 +1000,21 @@ public:
|
|
|
auto makeTestInvoker(void(*testAsFunction)()) noexcept -> ITestInvoker *;
|
|
|
|
|
|
template<typename C>
|
|
|
-auto makeTestInvoker(void (C::*testAsMethod)()) noexcept -> ITestInvoker * {
|
|
|
+auto makeTestInvoker(void (C::*testAsMethod)()) noexcept -> ITestInvoker *
|
|
|
+{
|
|
|
return new(std::nothrow)
|
|
|
TestInvokerAsMethod<C>( testAsMethod );
|
|
|
}
|
|
|
|
|
|
-struct NameAndTags {
|
|
|
+struct NameAndTags
|
|
|
+{
|
|
|
NameAndTags(StringRef const &name_ = StringRef(), StringRef const &tags_ = StringRef()) noexcept;
|
|
|
StringRef name;
|
|
|
StringRef tags;
|
|
|
};
|
|
|
|
|
|
-struct AutoReg : NonCopyable {
|
|
|
+struct AutoReg : NonCopyable
|
|
|
+{
|
|
|
AutoReg(ITestInvoker *invoker,
|
|
|
SourceLineInfo const &lineInfo,
|
|
|
StringRef const &classOrMethod,
|
|
@@ -1332,8 +1372,10 @@ struct AutoReg : NonCopyable {
|
|
|
namespace Catch {
|
|
|
|
|
|
// ResultWas::OfType enum
|
|
|
-struct ResultWas {
|
|
|
- enum OfType {
|
|
|
+struct ResultWas
|
|
|
+{
|
|
|
+ enum OfType
|
|
|
+ {
|
|
|
Unknown = -1,
|
|
|
Ok = 0,
|
|
|
Info = 1,
|
|
@@ -1358,8 +1400,10 @@ bool isOk(ResultWas::OfType resultType);
|
|
|
bool isJustInfo(int flags);
|
|
|
|
|
|
// ResultDisposition::Flags enum
|
|
|
-struct ResultDisposition {
|
|
|
- enum Flags {
|
|
|
+struct ResultDisposition
|
|
|
+{
|
|
|
+ enum Flags
|
|
|
+ {
|
|
|
Normal = 0x01,
|
|
|
|
|
|
ContinueOnFailure = 0x02, // Failures fail test, but execution continues
|
|
@@ -1371,7 +1415,8 @@ struct ResultDisposition {
|
|
|
ResultDisposition::Flags operator|(ResultDisposition::Flags lhs, ResultDisposition::Flags rhs);
|
|
|
|
|
|
bool shouldContinueOnFailure(int flags);
|
|
|
-inline bool isFalseTest(int flags) { return (flags & ResultDisposition::FalseTest) != 0; }
|
|
|
+inline bool isFalseTest(int flags)
|
|
|
+{ return (flags & ResultDisposition::FalseTest) != 0; }
|
|
|
bool shouldSuppressFailure(int flags);
|
|
|
|
|
|
} // end namespace Catch
|
|
@@ -1379,7 +1424,8 @@ bool shouldSuppressFailure(int flags);
|
|
|
// end catch_result_type.h
|
|
|
namespace Catch {
|
|
|
|
|
|
-struct AssertionInfo {
|
|
|
+struct AssertionInfo
|
|
|
+{
|
|
|
StringRef macroName;
|
|
|
SourceLineInfo lineInfo;
|
|
|
StringRef capturedExpression;
|
|
@@ -1415,14 +1461,16 @@ std::ostream &clog();
|
|
|
|
|
|
class StringRef;
|
|
|
|
|
|
-struct IStream {
|
|
|
+struct IStream
|
|
|
+{
|
|
|
virtual ~IStream();
|
|
|
virtual std::ostream &stream() const = 0;
|
|
|
};
|
|
|
|
|
|
auto makeStream(StringRef const &filename) -> IStream const *;
|
|
|
|
|
|
-class ReusableStringStream {
|
|
|
+class ReusableStringStream
|
|
|
+{
|
|
|
std::size_t m_index;
|
|
|
std::ostream *m_oss;
|
|
|
public:
|
|
@@ -1432,11 +1480,13 @@ public:
|
|
|
auto str() const -> std::string;
|
|
|
|
|
|
template<typename T>
|
|
|
- auto operator<<(T const &value) -> ReusableStringStream & {
|
|
|
+ auto operator<<(T const &value) -> ReusableStringStream &
|
|
|
+ {
|
|
|
*m_oss << value;
|
|
|
return *this;
|
|
|
}
|
|
|
- auto get() -> std::ostream & { return *m_oss; }
|
|
|
+ auto get() -> std::ostream &
|
|
|
+ { return *m_oss; }
|
|
|
};
|
|
|
}
|
|
|
|
|
@@ -1448,7 +1498,8 @@ public:
|
|
|
namespace Catch {
|
|
|
|
|
|
namespace Detail {
|
|
|
-struct EnumInfo {
|
|
|
+struct EnumInfo
|
|
|
+{
|
|
|
StringRef m_name;
|
|
|
std::vector<std::pair<int, std::string>> m_values;
|
|
|
|
|
@@ -1458,7 +1509,8 @@ struct EnumInfo {
|
|
|
};
|
|
|
} // namespace Detail
|
|
|
|
|
|
-struct IMutableEnumValuesRegistry {
|
|
|
+struct IMutableEnumValuesRegistry
|
|
|
+{
|
|
|
virtual ~IMutableEnumValuesRegistry();
|
|
|
|
|
|
virtual Detail::EnumInfo const ®isterEnum(StringRef enumName,
|
|
@@ -1468,7 +1520,8 @@ struct IMutableEnumValuesRegistry {
|
|
|
template<typename E>
|
|
|
Detail::EnumInfo const ®isterEnum(StringRef enumName,
|
|
|
StringRef allEnums,
|
|
|
- std::initializer_list<E> values) {
|
|
|
+ std::initializer_list<E> values)
|
|
|
+ {
|
|
|
std::vector<int> intValues;
|
|
|
intValues.reserve(values.size());
|
|
|
for (auto enumValue : values)
|
|
@@ -1544,12 +1597,14 @@ extern const std::string unprintableString;
|
|
|
std::string rawMemoryToString(const void *object, std::size_t size);
|
|
|
|
|
|
template<typename T>
|
|
|
-std::string rawMemoryToString(const T &object) {
|
|
|
+std::string rawMemoryToString(const T &object)
|
|
|
+{
|
|
|
return rawMemoryToString(&object, sizeof(object));
|
|
|
}
|
|
|
|
|
|
template<typename T>
|
|
|
-class IsStreamInsertable {
|
|
|
+class IsStreamInsertable
|
|
|
+{
|
|
|
template<typename SS, typename TT>
|
|
|
static auto test(int)
|
|
|
-> decltype(std::declval<SS &>() << std::declval<TT>(), std::true_type());
|
|
@@ -1567,19 +1622,22 @@ std::string convertUnknownEnumToString(E e);
|
|
|
template<typename T>
|
|
|
typename std::enable_if<
|
|
|
!std::is_enum<T>::value && !std::is_base_of<std::exception, T>::value,
|
|
|
- std::string>::type convertUnstreamable(T const &) {
|
|
|
+ std::string>::type convertUnstreamable(T const &)
|
|
|
+{
|
|
|
return Detail::unprintableString;
|
|
|
}
|
|
|
template<typename T>
|
|
|
typename std::enable_if<
|
|
|
!std::is_enum<T>::value && std::is_base_of<std::exception, T>::value,
|
|
|
- std::string>::type convertUnstreamable(T const &ex) {
|
|
|
+ std::string>::type convertUnstreamable(T const &ex)
|
|
|
+{
|
|
|
return ex.what();
|
|
|
}
|
|
|
|
|
|
template<typename T>
|
|
|
typename std::enable_if<
|
|
|
- std::is_enum<T>::value, std::string>::type convertUnstreamable(T const &value) {
|
|
|
+ std::is_enum<T>::value, std::string>::type convertUnstreamable(T const &value)
|
|
|
+{
|
|
|
return convertUnknownEnumToString(value);
|
|
|
}
|
|
|
|
|
@@ -1599,11 +1657,13 @@ typename std::enable_if<
|
|
|
|
|
|
// If we decide for C++14, change these to enable_if_ts
|
|
|
template<typename T, typename = void>
|
|
|
-struct StringMaker {
|
|
|
+struct StringMaker
|
|
|
+{
|
|
|
template<typename Fake = T>
|
|
|
static
|
|
|
typename std::enable_if<::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
|
|
|
- convert(const Fake &value) {
|
|
|
+ convert(const Fake &value)
|
|
|
+ {
|
|
|
ReusableStringStream rss;
|
|
|
// NB: call using the function-like syntax to avoid ambiguity with
|
|
|
// user-defined templated operator<< under clang.
|
|
@@ -1614,7 +1674,8 @@ struct StringMaker {
|
|
|
template<typename Fake = T>
|
|
|
static
|
|
|
typename std::enable_if<!::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
|
|
|
- convert(const Fake &value) {
|
|
|
+ convert(const Fake &value)
|
|
|
+ {
|
|
|
#if !defined(CATCH_CONFIG_FALLBACK_STRINGIFIER)
|
|
|
return Detail::convertUnstreamable(value);
|
|
|
#else
|
|
@@ -1628,13 +1689,15 @@ namespace Detail {
|
|
|
// This function dispatches all stringification requests inside of Catch.
|
|
|
// Should be preferably called fully qualified, like ::Catch::Detail::stringify
|
|
|
template<typename T>
|
|
|
-std::string stringify(const T &e) {
|
|
|
+std::string stringify(const T &e)
|
|
|
+{
|
|
|
return ::Catch::StringMaker<typename std::remove_cv<typename std::remove_reference<T>::type>::type>::convert(
|
|
|
e);
|
|
|
}
|
|
|
|
|
|
template<typename E>
|
|
|
-std::string convertUnknownEnumToString(E e) {
|
|
|
+std::string convertUnknownEnumToString(E e)
|
|
|
+{
|
|
|
return ::Catch::Detail::stringify(static_cast<typename std::underlying_type<E>::type>(e));
|
|
|
}
|
|
|
|
|
@@ -1650,7 +1713,8 @@ std::string convertUnknownEnumToString(E e) {
|
|
|
// Some predefined specializations
|
|
|
|
|
|
template<>
|
|
|
-struct StringMaker<std::string> {
|
|
|
+struct StringMaker<std::string>
|
|
|
+{
|
|
|
static std::string convert(const std::string &str);
|
|
|
};
|
|
|
|
|
@@ -1662,17 +1726,20 @@ struct StringMaker<std::string> {
|
|
|
#endif
|
|
|
|
|
|
template<>
|
|
|
-struct StringMaker<char const *> {
|
|
|
+struct StringMaker<char const *>
|
|
|
+{
|
|
|
static std::string convert(char const *str);
|
|
|
};
|
|
|
template<>
|
|
|
-struct StringMaker<char *> {
|
|
|
+struct StringMaker<char *>
|
|
|
+{
|
|
|
static std::string convert(char *str);
|
|
|
};
|
|
|
|
|
|
#ifdef CATCH_CONFIG_WCHAR
|
|
|
template<>
|
|
|
-struct StringMaker<std::wstring> {
|
|
|
+struct StringMaker<std::wstring>
|
|
|
+{
|
|
|
static std::string convert(const std::wstring &wstr);
|
|
|
};
|
|
|
|
|
@@ -1684,11 +1751,13 @@ struct StringMaker<std::wstring> {
|
|
|
# endif
|
|
|
|
|
|
template<>
|
|
|
-struct StringMaker<wchar_t const *> {
|
|
|
+struct StringMaker<wchar_t const *>
|
|
|
+{
|
|
|
static std::string convert(wchar_t const *str);
|
|
|
};
|
|
|
template<>
|
|
|
-struct StringMaker<wchar_t *> {
|
|
|
+struct StringMaker<wchar_t *>
|
|
|
+{
|
|
|
static std::string convert(wchar_t *str);
|
|
|
};
|
|
|
#endif
|
|
@@ -1696,20 +1765,26 @@ struct StringMaker<wchar_t *> {
|
|
|
// TBD: Should we use `strnlen` to ensure that we don't go out of the buffer,
|
|
|
// while keeping string semantics?
|
|
|
template<int SZ>
|
|
|
-struct StringMaker<char[SZ]> {
|
|
|
- static std::string convert(char const *str) {
|
|
|
+struct StringMaker<char[SZ]>
|
|
|
+{
|
|
|
+ static std::string convert(char const *str)
|
|
|
+ {
|
|
|
return ::Catch::Detail::stringify(std::string{str});
|
|
|
}
|
|
|
};
|
|
|
template<int SZ>
|
|
|
-struct StringMaker<signed char[SZ]> {
|
|
|
- static std::string convert(signed char const *str) {
|
|
|
+struct StringMaker<signed char[SZ]>
|
|
|
+{
|
|
|
+ static std::string convert(signed char const *str)
|
|
|
+ {
|
|
|
return ::Catch::Detail::stringify(std::string{reinterpret_cast<char const *>(str)});
|
|
|
}
|
|
|
};
|
|
|
template<int SZ>
|
|
|
-struct StringMaker<unsigned char[SZ]> {
|
|
|
- static std::string convert(unsigned char const *str) {
|
|
|
+struct StringMaker<unsigned char[SZ]>
|
|
|
+{
|
|
|
+ static std::string convert(unsigned char const *str)
|
|
|
+ {
|
|
|
return ::Catch::Detail::stringify(std::string{reinterpret_cast<char const *>(str)});
|
|
|
}
|
|
|
};
|
|
@@ -1721,69 +1796,84 @@ struct StringMaker<unsigned char[SZ]> {
|
|
|
};
|
|
|
#endif // defined(CATCH_CONFIG_CPP17_BYTE)
|
|
|
template<>
|
|
|
-struct StringMaker<int> {
|
|
|
+struct StringMaker<int>
|
|
|
+{
|
|
|
static std::string convert(int value);
|
|
|
};
|
|
|
template<>
|
|
|
-struct StringMaker<long> {
|
|
|
+struct StringMaker<long>
|
|
|
+{
|
|
|
static std::string convert(long value);
|
|
|
};
|
|
|
template<>
|
|
|
-struct StringMaker<long long> {
|
|
|
+struct StringMaker<long long>
|
|
|
+{
|
|
|
static std::string convert(long long value);
|
|
|
};
|
|
|
template<>
|
|
|
-struct StringMaker<unsigned int> {
|
|
|
+struct StringMaker<unsigned int>
|
|
|
+{
|
|
|
static std::string convert(unsigned int value);
|
|
|
};
|
|
|
template<>
|
|
|
-struct StringMaker<unsigned long> {
|
|
|
+struct StringMaker<unsigned long>
|
|
|
+{
|
|
|
static std::string convert(unsigned long value);
|
|
|
};
|
|
|
template<>
|
|
|
-struct StringMaker<unsigned long long> {
|
|
|
+struct StringMaker<unsigned long long>
|
|
|
+{
|
|
|
static std::string convert(unsigned long long value);
|
|
|
};
|
|
|
|
|
|
template<>
|
|
|
-struct StringMaker<bool> {
|
|
|
+struct StringMaker<bool>
|
|
|
+{
|
|
|
static std::string convert(bool b);
|
|
|
};
|
|
|
|
|
|
template<>
|
|
|
-struct StringMaker<char> {
|
|
|
+struct StringMaker<char>
|
|
|
+{
|
|
|
static std::string convert(char c);
|
|
|
};
|
|
|
template<>
|
|
|
-struct StringMaker<signed char> {
|
|
|
+struct StringMaker<signed char>
|
|
|
+{
|
|
|
static std::string convert(signed char c);
|
|
|
};
|
|
|
template<>
|
|
|
-struct StringMaker<unsigned char> {
|
|
|
+struct StringMaker<unsigned char>
|
|
|
+{
|
|
|
static std::string convert(unsigned char c);
|
|
|
};
|
|
|
|
|
|
template<>
|
|
|
-struct StringMaker<std::nullptr_t> {
|
|
|
+struct StringMaker<std::nullptr_t>
|
|
|
+{
|
|
|
static std::string convert(std::nullptr_t);
|
|
|
};
|
|
|
|
|
|
template<>
|
|
|
-struct StringMaker<float> {
|
|
|
+struct StringMaker<float>
|
|
|
+{
|
|
|
static std::string convert(float value);
|
|
|
static int precision;
|
|
|
};
|
|
|
|
|
|
template<>
|
|
|
-struct StringMaker<double> {
|
|
|
+struct StringMaker<double>
|
|
|
+{
|
|
|
static std::string convert(double value);
|
|
|
static int precision;
|
|
|
};
|
|
|
|
|
|
template<typename T>
|
|
|
-struct StringMaker<T *> {
|
|
|
+struct StringMaker<T *>
|
|
|
+{
|
|
|
template<typename U>
|
|
|
- static std::string convert(U *p) {
|
|
|
+ static std::string convert(U *p)
|
|
|
+ {
|
|
|
if (p) {
|
|
|
return ::Catch::Detail::rawMemoryToString(p);
|
|
|
} else {
|
|
@@ -1793,8 +1883,10 @@ struct StringMaker<T *> {
|
|
|
};
|
|
|
|
|
|
template<typename R, typename C>
|
|
|
-struct StringMaker<R C::*> {
|
|
|
- static std::string convert(R C::* p) {
|
|
|
+struct StringMaker<R C::*>
|
|
|
+{
|
|
|
+ static std::string convert(R C::* p)
|
|
|
+ {
|
|
|
if (p) {
|
|
|
return ::Catch::Detail::rawMemoryToString(p);
|
|
|
} else {
|
|
@@ -1814,7 +1906,8 @@ struct StringMaker<R C::*> {
|
|
|
|
|
|
namespace Detail {
|
|
|
template<typename InputIterator>
|
|
|
-std::string rangeToString(InputIterator first, InputIterator last) {
|
|
|
+std::string rangeToString(InputIterator first, InputIterator last)
|
|
|
+{
|
|
|
ReusableStringStream rss;
|
|
|
rss << "{ ";
|
|
|
if (first != last) {
|
|
@@ -1972,7 +2065,9 @@ namespace Catch {
|
|
|
#endif // CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
|
|
|
|
|
|
namespace Catch {
|
|
|
-struct not_this_one {}; // Tag type for detecting which begin/ end are being selected
|
|
|
+struct not_this_one
|
|
|
+{
|
|
|
+}; // Tag type for detecting which begin/ end are being selected
|
|
|
|
|
|
// Import begin/ end from std here so they are considered alongside the fallback (...) overloads in this namespace
|
|
|
using std::begin;
|
|
@@ -1982,7 +2077,8 @@ not_this_one begin(...);
|
|
|
not_this_one end(...);
|
|
|
|
|
|
template<typename T>
|
|
|
-struct is_range {
|
|
|
+struct is_range
|
|
|
+{
|
|
|
static const bool value =
|
|
|
!std::is_same<decltype(begin(std::declval<T>())), not_this_one>::value &&
|
|
|
!std::is_same<decltype(end(std::declval<T>())), not_this_one>::value;
|
|
@@ -1996,13 +2092,15 @@ struct is_range {
|
|
|
#endif
|
|
|
|
|
|
template<typename Range>
|
|
|
-std::string rangeToString(Range const &range) {
|
|
|
+std::string rangeToString(Range const &range)
|
|
|
+{
|
|
|
return ::Catch::Detail::rangeToString(begin(range), end(range));
|
|
|
}
|
|
|
|
|
|
// Handle vector<bool> specially
|
|
|
template<typename Allocator>
|
|
|
-std::string rangeToString(std::vector<bool, Allocator> const &v) {
|
|
|
+std::string rangeToString(std::vector<bool, Allocator> const &v)
|
|
|
+{
|
|
|
ReusableStringStream rss;
|
|
|
rss << "{ ";
|
|
|
bool first = true;
|
|
@@ -2020,15 +2118,19 @@ std::string rangeToString(std::vector<bool, Allocator> const &v) {
|
|
|
template<typename R>
|
|
|
struct StringMaker<R,
|
|
|
typename std::enable_if<is_range<R>::value
|
|
|
- && !::Catch::Detail::IsStreamInsertable<R>::value>::type> {
|
|
|
- static std::string convert(R const &range) {
|
|
|
+ && !::Catch::Detail::IsStreamInsertable<R>::value>::type>
|
|
|
+{
|
|
|
+ static std::string convert(R const &range)
|
|
|
+ {
|
|
|
return rangeToString(range);
|
|
|
}
|
|
|
};
|
|
|
|
|
|
template<typename T, int SZ>
|
|
|
-struct StringMaker<T[SZ]> {
|
|
|
- static std::string convert(T const(&arr)[SZ]) {
|
|
|
+struct StringMaker<T[SZ]>
|
|
|
+{
|
|
|
+ static std::string convert(T const(&arr)[SZ])
|
|
|
+ {
|
|
|
return rangeToString(arr);
|
|
|
}
|
|
|
};
|
|
@@ -2182,14 +2284,18 @@ namespace Catch { \
|
|
|
|
|
|
namespace Catch {
|
|
|
|
|
|
-struct ITransientExpression {
|
|
|
- auto isBinaryExpression() const -> bool { return m_isBinaryExpression; }
|
|
|
- auto getResult() const -> bool { return m_result; }
|
|
|
+struct ITransientExpression
|
|
|
+{
|
|
|
+ auto isBinaryExpression() const -> bool
|
|
|
+ { return m_isBinaryExpression; }
|
|
|
+ auto getResult() const -> bool
|
|
|
+ { return m_result; }
|
|
|
virtual void streamReconstructedExpression(std::ostream &os) const = 0;
|
|
|
|
|
|
ITransientExpression(bool isBinaryExpression, bool result)
|
|
|
: m_isBinaryExpression(isBinaryExpression),
|
|
|
- m_result(result) {}
|
|
|
+ m_result(result)
|
|
|
+ {}
|
|
|
|
|
|
// We don't actually need a virtual destructor, but many static analysers
|
|
|
// complain if it's not here :-(
|
|
@@ -2206,12 +2312,14 @@ void formatReconstructedExpression(std::ostream &os,
|
|
|
std::string const &rhs);
|
|
|
|
|
|
template<typename LhsT, typename RhsT>
|
|
|
-class BinaryExpr : public ITransientExpression {
|
|
|
+class BinaryExpr : public ITransientExpression
|
|
|
+{
|
|
|
LhsT m_lhs;
|
|
|
StringRef m_op;
|
|
|
RhsT m_rhs;
|
|
|
|
|
|
- void streamReconstructedExpression(std::ostream &os) const override {
|
|
|
+ void streamReconstructedExpression(std::ostream &os) const override
|
|
|
+ {
|
|
|
formatReconstructedExpression
|
|
|
(os, Catch::Detail::stringify(m_lhs), m_op, Catch::Detail::stringify(m_rhs));
|
|
|
}
|
|
@@ -2221,59 +2329,68 @@ public:
|
|
|
: ITransientExpression{true, comparisonResult},
|
|
|
m_lhs(lhs),
|
|
|
m_op(op),
|
|
|
- m_rhs(rhs) {}
|
|
|
+ m_rhs(rhs)
|
|
|
+ {}
|
|
|
|
|
|
template<typename T>
|
|
|
- auto operator&&(T) const -> BinaryExpr<LhsT, RhsT const &> const {
|
|
|
+ auto operator&&(T) const -> BinaryExpr<LhsT, RhsT const &> const
|
|
|
+ {
|
|
|
static_assert(always_false<T>::value,
|
|
|
"chained comparisons are not supported inside assertions, "
|
|
|
"wrap the expression inside parentheses, or decompose it");
|
|
|
}
|
|
|
|
|
|
template<typename T>
|
|
|
- auto operator||(T) const -> BinaryExpr<LhsT, RhsT const &> const {
|
|
|
+ auto operator||(T) const -> BinaryExpr<LhsT, RhsT const &> const
|
|
|
+ {
|
|
|
static_assert(always_false<T>::value,
|
|
|
"chained comparisons are not supported inside assertions, "
|
|
|
"wrap the expression inside parentheses, or decompose it");
|
|
|
}
|
|
|
|
|
|
template<typename T>
|
|
|
- auto operator==(T) const -> BinaryExpr<LhsT, RhsT const &> const {
|
|
|
+ auto operator==(T) const -> BinaryExpr<LhsT, RhsT const &> const
|
|
|
+ {
|
|
|
static_assert(always_false<T>::value,
|
|
|
"chained comparisons are not supported inside assertions, "
|
|
|
"wrap the expression inside parentheses, or decompose it");
|
|
|
}
|
|
|
|
|
|
template<typename T>
|
|
|
- auto operator!=(T) const -> BinaryExpr<LhsT, RhsT const &> const {
|
|
|
+ auto operator!=(T) const -> BinaryExpr<LhsT, RhsT const &> const
|
|
|
+ {
|
|
|
static_assert(always_false<T>::value,
|
|
|
"chained comparisons are not supported inside assertions, "
|
|
|
"wrap the expression inside parentheses, or decompose it");
|
|
|
}
|
|
|
|
|
|
template<typename T>
|
|
|
- auto operator>(T) const -> BinaryExpr<LhsT, RhsT const &> const {
|
|
|
+ auto operator>(T) const -> BinaryExpr<LhsT, RhsT const &> const
|
|
|
+ {
|
|
|
static_assert(always_false<T>::value,
|
|
|
"chained comparisons are not supported inside assertions, "
|
|
|
"wrap the expression inside parentheses, or decompose it");
|
|
|
}
|
|
|
|
|
|
template<typename T>
|
|
|
- auto operator<(T) const -> BinaryExpr<LhsT, RhsT const &> const {
|
|
|
+ auto operator<(T) const -> BinaryExpr<LhsT, RhsT const &> const
|
|
|
+ {
|
|
|
static_assert(always_false<T>::value,
|
|
|
"chained comparisons are not supported inside assertions, "
|
|
|
"wrap the expression inside parentheses, or decompose it");
|
|
|
}
|
|
|
|
|
|
template<typename T>
|
|
|
- auto operator>=(T) const -> BinaryExpr<LhsT, RhsT const &> const {
|
|
|
+ auto operator>=(T) const -> BinaryExpr<LhsT, RhsT const &> const
|
|
|
+ {
|
|
|
static_assert(always_false<T>::value,
|
|
|
"chained comparisons are not supported inside assertions, "
|
|
|
"wrap the expression inside parentheses, or decompose it");
|
|
|
}
|
|
|
|
|
|
template<typename T>
|
|
|
- auto operator<=(T) const -> BinaryExpr<LhsT, RhsT const &> const {
|
|
|
+ auto operator<=(T) const -> BinaryExpr<LhsT, RhsT const &> const
|
|
|
+ {
|
|
|
static_assert(always_false<T>::value,
|
|
|
"chained comparisons are not supported inside assertions, "
|
|
|
"wrap the expression inside parentheses, or decompose it");
|
|
@@ -2281,114 +2398,140 @@ public:
|
|
|
};
|
|
|
|
|
|
template<typename LhsT>
|
|
|
-class UnaryExpr : public ITransientExpression {
|
|
|
+class UnaryExpr : public ITransientExpression
|
|
|
+{
|
|
|
LhsT m_lhs;
|
|
|
|
|
|
- void streamReconstructedExpression(std::ostream &os) const override {
|
|
|
+ void streamReconstructedExpression(std::ostream &os) const override
|
|
|
+ {
|
|
|
os << Catch::Detail::stringify(m_lhs);
|
|
|
}
|
|
|
|
|
|
public:
|
|
|
explicit UnaryExpr(LhsT lhs)
|
|
|
: ITransientExpression{false, static_cast<bool>(lhs)},
|
|
|
- m_lhs(lhs) {}
|
|
|
+ m_lhs(lhs)
|
|
|
+ {}
|
|
|
};
|
|
|
|
|
|
// Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int)
|
|
|
template<typename LhsT, typename RhsT>
|
|
|
-auto compareEqual(LhsT const &lhs, RhsT const &rhs) -> bool {
|
|
|
+auto compareEqual(LhsT const &lhs, RhsT const &rhs) -> bool
|
|
|
+{
|
|
|
return static_cast<bool>(lhs == rhs);
|
|
|
}
|
|
|
template<typename T>
|
|
|
-auto compareEqual(T *const &lhs, int rhs) -> bool {
|
|
|
+auto compareEqual(T *const &lhs, int rhs) -> bool
|
|
|
+{
|
|
|
return lhs == reinterpret_cast<void const *>( rhs );
|
|
|
}
|
|
|
template<typename T>
|
|
|
-auto compareEqual(T *const &lhs, long rhs) -> bool {
|
|
|
+auto compareEqual(T *const &lhs, long rhs) -> bool
|
|
|
+{
|
|
|
return lhs == reinterpret_cast<void const *>( rhs );
|
|
|
}
|
|
|
template<typename T>
|
|
|
-auto compareEqual(int lhs, T *const &rhs) -> bool {
|
|
|
+auto compareEqual(int lhs, T *const &rhs) -> bool
|
|
|
+{
|
|
|
return reinterpret_cast<void const *>( lhs ) == rhs;
|
|
|
}
|
|
|
template<typename T>
|
|
|
-auto compareEqual(long lhs, T *const &rhs) -> bool {
|
|
|
+auto compareEqual(long lhs, T *const &rhs) -> bool
|
|
|
+{
|
|
|
return reinterpret_cast<void const *>( lhs ) == rhs;
|
|
|
}
|
|
|
|
|
|
template<typename LhsT, typename RhsT>
|
|
|
-auto compareNotEqual(LhsT const &lhs, RhsT &&rhs) -> bool { return static_cast<bool>(lhs != rhs); }
|
|
|
+auto compareNotEqual(LhsT const &lhs, RhsT &&rhs) -> bool
|
|
|
+{ return static_cast<bool>(lhs != rhs); }
|
|
|
template<typename T>
|
|
|
-auto compareNotEqual(T *const &lhs, int rhs) -> bool {
|
|
|
+auto compareNotEqual(T *const &lhs, int rhs) -> bool
|
|
|
+{
|
|
|
return lhs != reinterpret_cast<void const *>( rhs );
|
|
|
}
|
|
|
template<typename T>
|
|
|
-auto compareNotEqual(T *const &lhs, long rhs) -> bool {
|
|
|
+auto compareNotEqual(T *const &lhs, long rhs) -> bool
|
|
|
+{
|
|
|
return lhs != reinterpret_cast<void const *>( rhs );
|
|
|
}
|
|
|
template<typename T>
|
|
|
-auto compareNotEqual(int lhs, T *const &rhs) -> bool {
|
|
|
+auto compareNotEqual(int lhs, T *const &rhs) -> bool
|
|
|
+{
|
|
|
return reinterpret_cast<void const *>( lhs ) != rhs;
|
|
|
}
|
|
|
template<typename T>
|
|
|
-auto compareNotEqual(long lhs, T *const &rhs) -> bool {
|
|
|
+auto compareNotEqual(long lhs, T *const &rhs) -> bool
|
|
|
+{
|
|
|
return reinterpret_cast<void const *>( lhs ) != rhs;
|
|
|
}
|
|
|
|
|
|
template<typename LhsT>
|
|
|
-class ExprLhs {
|
|
|
+class ExprLhs
|
|
|
+{
|
|
|
LhsT m_lhs;
|
|
|
public:
|
|
|
- explicit ExprLhs(LhsT lhs) : m_lhs(lhs) {}
|
|
|
+ explicit ExprLhs(LhsT lhs) : m_lhs(lhs)
|
|
|
+ {}
|
|
|
|
|
|
template<typename RhsT>
|
|
|
- auto operator==(RhsT const &rhs) -> BinaryExpr<LhsT, RhsT const &> const {
|
|
|
+ auto operator==(RhsT const &rhs) -> BinaryExpr<LhsT, RhsT const &> const
|
|
|
+ {
|
|
|
return {compareEqual(m_lhs, rhs), m_lhs, "==", rhs};
|
|
|
}
|
|
|
- auto operator==(bool rhs) -> BinaryExpr<LhsT, bool> const {
|
|
|
+ auto operator==(bool rhs) -> BinaryExpr<LhsT, bool> const
|
|
|
+ {
|
|
|
return {m_lhs == rhs, m_lhs, "==", rhs};
|
|
|
}
|
|
|
|
|
|
template<typename RhsT>
|
|
|
- auto operator!=(RhsT const &rhs) -> BinaryExpr<LhsT, RhsT const &> const {
|
|
|
+ auto operator!=(RhsT const &rhs) -> BinaryExpr<LhsT, RhsT const &> const
|
|
|
+ {
|
|
|
return {compareNotEqual(m_lhs, rhs), m_lhs, "!=", rhs};
|
|
|
}
|
|
|
- auto operator!=(bool rhs) -> BinaryExpr<LhsT, bool> const {
|
|
|
+ auto operator!=(bool rhs) -> BinaryExpr<LhsT, bool> const
|
|
|
+ {
|
|
|
return {m_lhs != rhs, m_lhs, "!=", rhs};
|
|
|
}
|
|
|
|
|
|
template<typename RhsT>
|
|
|
- auto operator>(RhsT const &rhs) -> BinaryExpr<LhsT, RhsT const &> const {
|
|
|
+ auto operator>(RhsT const &rhs) -> BinaryExpr<LhsT, RhsT const &> const
|
|
|
+ {
|
|
|
return {static_cast<bool>(m_lhs > rhs), m_lhs, ">", rhs};
|
|
|
}
|
|
|
template<typename RhsT>
|
|
|
- auto operator<(RhsT const &rhs) -> BinaryExpr<LhsT, RhsT const &> const {
|
|
|
+ auto operator<(RhsT const &rhs) -> BinaryExpr<LhsT, RhsT const &> const
|
|
|
+ {
|
|
|
return {static_cast<bool>(m_lhs < rhs), m_lhs, "<", rhs};
|
|
|
}
|
|
|
template<typename RhsT>
|
|
|
- auto operator>=(RhsT const &rhs) -> BinaryExpr<LhsT, RhsT const &> const {
|
|
|
+ auto operator>=(RhsT const &rhs) -> BinaryExpr<LhsT, RhsT const &> const
|
|
|
+ {
|
|
|
return {static_cast<bool>(m_lhs >= rhs), m_lhs, ">=", rhs};
|
|
|
}
|
|
|
template<typename RhsT>
|
|
|
- auto operator<=(RhsT const &rhs) -> BinaryExpr<LhsT, RhsT const &> const {
|
|
|
+ auto operator<=(RhsT const &rhs) -> BinaryExpr<LhsT, RhsT const &> const
|
|
|
+ {
|
|
|
return {static_cast<bool>(m_lhs <= rhs), m_lhs, "<=", rhs};
|
|
|
}
|
|
|
|
|
|
template<typename RhsT>
|
|
|
- auto operator&&(RhsT const &) -> BinaryExpr<LhsT, RhsT const &> const {
|
|
|
+ auto operator&&(RhsT const &) -> BinaryExpr<LhsT, RhsT const &> const
|
|
|
+ {
|
|
|
static_assert(always_false<RhsT>::value,
|
|
|
"operator&& is not supported inside assertions, "
|
|
|
"wrap the expression inside parentheses, or decompose it");
|
|
|
}
|
|
|
|
|
|
template<typename RhsT>
|
|
|
- auto operator||(RhsT const &) -> BinaryExpr<LhsT, RhsT const &> const {
|
|
|
+ auto operator||(RhsT const &) -> BinaryExpr<LhsT, RhsT const &> const
|
|
|
+ {
|
|
|
static_assert(always_false<RhsT>::value,
|
|
|
"operator|| is not supported inside assertions, "
|
|
|
"wrap the expression inside parentheses, or decompose it");
|
|
|
}
|
|
|
|
|
|
- auto makeUnaryExpr() const -> UnaryExpr<LhsT> {
|
|
|
+ auto makeUnaryExpr() const -> UnaryExpr<LhsT>
|
|
|
+ {
|
|
|
return UnaryExpr<LhsT>{m_lhs};
|
|
|
}
|
|
|
};
|
|
@@ -2396,17 +2539,21 @@ public:
|
|
|
void handleExpression(ITransientExpression const &expr);
|
|
|
|
|
|
template<typename T>
|
|
|
-void handleExpression(ExprLhs<T> const &expr) {
|
|
|
+void handleExpression(ExprLhs<T> const &expr)
|
|
|
+{
|
|
|
handleExpression(expr.makeUnaryExpr());
|
|
|
}
|
|
|
|
|
|
-struct Decomposer {
|
|
|
+struct Decomposer
|
|
|
+{
|
|
|
template<typename T>
|
|
|
- auto operator<=(T const &lhs) -> ExprLhs<T const &> {
|
|
|
+ auto operator<=(T const &lhs) -> ExprLhs<T const &>
|
|
|
+ {
|
|
|
return ExprLhs<T const &>{lhs};
|
|
|
}
|
|
|
|
|
|
- auto operator<=(bool value) -> ExprLhs<bool> {
|
|
|
+ auto operator<=(bool value) -> ExprLhs<bool>
|
|
|
+ {
|
|
|
return ExprLhs<bool>{value};
|
|
|
}
|
|
|
};
|
|
@@ -2444,7 +2591,8 @@ struct IGeneratorTracker;
|
|
|
struct BenchmarkStats;
|
|
|
#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
|
|
|
|
|
|
-struct IResultCapture {
|
|
|
+struct IResultCapture
|
|
|
+{
|
|
|
|
|
|
virtual ~IResultCapture();
|
|
|
|
|
@@ -2507,12 +2655,15 @@ IResultCapture &getResultCapture();
|
|
|
// end catch_interfaces_capture.h
|
|
|
namespace Catch {
|
|
|
|
|
|
-struct TestFailureException {};
|
|
|
+struct TestFailureException
|
|
|
+{
|
|
|
+};
|
|
|
struct AssertionResultData;
|
|
|
struct IResultCapture;
|
|
|
class RunContext;
|
|
|
|
|
|
-class LazyExpression {
|
|
|
+class LazyExpression
|
|
|
+{
|
|
|
friend class AssertionHandler;
|
|
|
friend struct AssertionStats;
|
|
|
friend class RunContext;
|
|
@@ -2529,12 +2680,14 @@ public:
|
|
|
friend auto operator<<(std::ostream &os, LazyExpression const &lazyExpr) -> std::ostream &;
|
|
|
};
|
|
|
|
|
|
-struct AssertionReaction {
|
|
|
+struct AssertionReaction
|
|
|
+{
|
|
|
bool shouldDebugBreak = false;
|
|
|
bool shouldThrow = false;
|
|
|
};
|
|
|
|
|
|
-class AssertionHandler {
|
|
|
+class AssertionHandler
|
|
|
+{
|
|
|
AssertionInfo m_assertionInfo;
|
|
|
AssertionReaction m_reaction;
|
|
|
bool m_completed = false;
|
|
@@ -2546,14 +2699,16 @@ public:
|
|
|
SourceLineInfo const &lineInfo,
|
|
|
StringRef capturedExpression,
|
|
|
ResultDisposition::Flags resultDisposition);
|
|
|
- ~AssertionHandler() {
|
|
|
+ ~AssertionHandler()
|
|
|
+ {
|
|
|
if (!m_completed) {
|
|
|
m_resultCapture.handleIncomplete(m_assertionInfo);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
template<typename T>
|
|
|
- void handleExpr(ExprLhs<T> const &expr) {
|
|
|
+ void handleExpr(ExprLhs<T> const &expr)
|
|
|
+ {
|
|
|
handleExpr(expr.makeUnaryExpr());
|
|
|
}
|
|
|
void handleExpr(ITransientExpression const &expr);
|
|
@@ -2587,7 +2742,8 @@ void handleExceptionMatchExpr(AssertionHandler &handler,
|
|
|
|
|
|
namespace Catch {
|
|
|
|
|
|
-struct MessageInfo {
|
|
|
+struct MessageInfo
|
|
|
+{
|
|
|
MessageInfo(StringRef const &_macroName,
|
|
|
SourceLineInfo const &_lineInfo,
|
|
|
ResultWas::OfType _type);
|
|
@@ -2604,10 +2760,12 @@ private:
|
|
|
static unsigned int globalCount;
|
|
|
};
|
|
|
|
|
|
-struct MessageStream {
|
|
|
+struct MessageStream
|
|
|
+{
|
|
|
|
|
|
template<typename T>
|
|
|
- MessageStream &operator<<(T const &value) {
|
|
|
+ MessageStream &operator<<(T const &value)
|
|
|
+ {
|
|
|
m_stream << value;
|
|
|
return *this;
|
|
|
}
|
|
@@ -2615,13 +2773,15 @@ struct MessageStream {
|
|
|
ReusableStringStream m_stream;
|
|
|
};
|
|
|
|
|
|
-struct MessageBuilder : MessageStream {
|
|
|
+struct MessageBuilder : MessageStream
|
|
|
+{
|
|
|
MessageBuilder(StringRef const ¯oName,
|
|
|
SourceLineInfo const &lineInfo,
|
|
|
ResultWas::OfType type);
|
|
|
|
|
|
template<typename T>
|
|
|
- MessageBuilder &operator<<(T const &value) {
|
|
|
+ MessageBuilder &operator<<(T const &value)
|
|
|
+ {
|
|
|
m_stream << value;
|
|
|
return *this;
|
|
|
}
|
|
@@ -2629,7 +2789,8 @@ struct MessageBuilder : MessageStream {
|
|
|
MessageInfo m_info;
|
|
|
};
|
|
|
|
|
|
-class ScopedMessage {
|
|
|
+class ScopedMessage
|
|
|
+{
|
|
|
public:
|
|
|
explicit ScopedMessage(MessageBuilder const &builder);
|
|
|
ScopedMessage(ScopedMessage &duplicate) = delete;
|
|
@@ -2640,7 +2801,8 @@ public:
|
|
|
bool m_moved;
|
|
|
};
|
|
|
|
|
|
-class Capturer {
|
|
|
+class Capturer
|
|
|
+{
|
|
|
std::vector<MessageInfo> m_messages;
|
|
|
IResultCapture &m_resultCapture = getResultCapture();
|
|
|
size_t m_captured = 0;
|
|
@@ -2654,12 +2816,14 @@ public:
|
|
|
void captureValue(size_t index, std::string const &value);
|
|
|
|
|
|
template<typename T>
|
|
|
- void captureValues(size_t index, T const &value) {
|
|
|
+ void captureValues(size_t index, T const &value)
|
|
|
+ {
|
|
|
captureValue(index, Catch::Detail::stringify(value));
|
|
|
}
|
|
|
|
|
|
template<typename T, typename... Ts>
|
|
|
- void captureValues(size_t index, T const &value, Ts const &... values) {
|
|
|
+ void captureValues(size_t index, T const &value, Ts const &... values)
|
|
|
+ {
|
|
|
captureValue(index, Catch::Detail::stringify(value));
|
|
|
captureValues(index + 1, values...);
|
|
|
}
|
|
@@ -2819,7 +2983,8 @@ public:
|
|
|
|
|
|
namespace Catch {
|
|
|
|
|
|
-struct Counts {
|
|
|
+struct Counts
|
|
|
+{
|
|
|
Counts operator-(Counts const &other) const;
|
|
|
Counts &operator+=(Counts const &other);
|
|
|
|
|
@@ -2832,7 +2997,8 @@ struct Counts {
|
|
|
std::size_t failedButOk = 0;
|
|
|
};
|
|
|
|
|
|
-struct Totals {
|
|
|
+struct Totals
|
|
|
+{
|
|
|
|
|
|
Totals operator-(Totals const &other) const;
|
|
|
Totals &operator+=(Totals const &other);
|
|
@@ -2850,7 +3016,8 @@ struct Totals {
|
|
|
|
|
|
namespace Catch {
|
|
|
|
|
|
-struct SectionInfo {
|
|
|
+struct SectionInfo
|
|
|
+{
|
|
|
SectionInfo
|
|
|
(SourceLineInfo const &_lineInfo,
|
|
|
std::string const &_name);
|
|
@@ -2859,14 +3026,16 @@ struct SectionInfo {
|
|
|
SectionInfo
|
|
|
(SourceLineInfo const &_lineInfo,
|
|
|
std::string const &_name,
|
|
|
- std::string const &) : SectionInfo(_lineInfo, _name) {}
|
|
|
+ std::string const &) : SectionInfo(_lineInfo, _name)
|
|
|
+ {}
|
|
|
|
|
|
std::string name;
|
|
|
std::string description; // !Deprecated: this will always be empty
|
|
|
SourceLineInfo lineInfo;
|
|
|
};
|
|
|
|
|
|
-struct SectionEndInfo {
|
|
|
+struct SectionEndInfo
|
|
|
+{
|
|
|
SectionInfo sectionInfo;
|
|
|
Counts prevAssertions;
|
|
|
double durationInSeconds;
|
|
@@ -2884,7 +3053,8 @@ namespace Catch {
|
|
|
auto getCurrentNanosecondsSinceEpoch() -> uint64_t;
|
|
|
auto getEstimatedClockResolution() -> uint64_t;
|
|
|
|
|
|
-class Timer {
|
|
|
+class Timer
|
|
|
+{
|
|
|
uint64_t m_nanoseconds = 0;
|
|
|
public:
|
|
|
void start();
|
|
@@ -2901,7 +3071,8 @@ public:
|
|
|
|
|
|
namespace Catch {
|
|
|
|
|
|
-class Section : NonCopyable {
|
|
|
+class Section : NonCopyable
|
|
|
+{
|
|
|
public:
|
|
|
Section(SectionInfo const &info);
|
|
|
~Section();
|
|
@@ -2953,7 +3124,8 @@ class StartupExceptionRegistry;
|
|
|
|
|
|
using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;
|
|
|
|
|
|
-struct IRegistryHub {
|
|
|
+struct IRegistryHub
|
|
|
+{
|
|
|
virtual ~IRegistryHub();
|
|
|
|
|
|
virtual IReporterRegistry const &getReporterRegistry() const = 0;
|
|
@@ -2964,7 +3136,8 @@ struct IRegistryHub {
|
|
|
virtual StartupExceptionRegistry const &getStartupExceptionRegistry() const = 0;
|
|
|
};
|
|
|
|
|
|
-struct IMutableRegistryHub {
|
|
|
+struct IMutableRegistryHub
|
|
|
+{
|
|
|
virtual ~IMutableRegistryHub();
|
|
|
virtual void registerReporter(std::string const &name, IReporterFactoryPtr const &factory) = 0;
|
|
|
virtual void registerListener(IReporterFactoryPtr const &factory) = 0;
|
|
@@ -3000,28 +3173,34 @@ using exceptionTranslateFunction = std::string(*)();
|
|
|
struct IExceptionTranslator;
|
|
|
using ExceptionTranslators = std::vector<std::unique_ptr<IExceptionTranslator const>>;
|
|
|
|
|
|
-struct IExceptionTranslator {
|
|
|
+struct IExceptionTranslator
|
|
|
+{
|
|
|
virtual ~IExceptionTranslator();
|
|
|
virtual std::string translate(ExceptionTranslators::const_iterator it,
|
|
|
ExceptionTranslators::const_iterator itEnd) const = 0;
|
|
|
};
|
|
|
|
|
|
-struct IExceptionTranslatorRegistry {
|
|
|
+struct IExceptionTranslatorRegistry
|
|
|
+{
|
|
|
virtual ~IExceptionTranslatorRegistry();
|
|
|
|
|
|
virtual std::string translateActiveException() const = 0;
|
|
|
};
|
|
|
|
|
|
-class ExceptionTranslatorRegistrar {
|
|
|
+class ExceptionTranslatorRegistrar
|
|
|
+{
|
|
|
template<typename T>
|
|
|
- class ExceptionTranslator : public IExceptionTranslator {
|
|
|
+ class ExceptionTranslator : public IExceptionTranslator
|
|
|
+ {
|
|
|
public:
|
|
|
|
|
|
ExceptionTranslator(std::string(*translateFunction)(T &))
|
|
|
- : m_translateFunction(translateFunction) {}
|
|
|
+ : m_translateFunction(translateFunction)
|
|
|
+ {}
|
|
|
|
|
|
std::string translate(ExceptionTranslators::const_iterator it,
|
|
|
- ExceptionTranslators::const_iterator itEnd) const override {
|
|
|
+ ExceptionTranslators::const_iterator itEnd) const override
|
|
|
+ {
|
|
|
try {
|
|
|
if (it == itEnd)
|
|
|
std::rethrow_exception(std::current_exception());
|
|
@@ -3039,7 +3218,8 @@ class ExceptionTranslatorRegistrar {
|
|
|
|
|
|
public:
|
|
|
template<typename T>
|
|
|
- ExceptionTranslatorRegistrar(std::string(*translateFunction)(T &)) {
|
|
|
+ ExceptionTranslatorRegistrar(std::string(*translateFunction)(T &))
|
|
|
+ {
|
|
|
getMutableRegistryHub().registerTranslator
|
|
|
(new ExceptionTranslator<T>(translateFunction));
|
|
|
}
|
|
@@ -3064,7 +3244,8 @@ public:
|
|
|
namespace Catch {
|
|
|
namespace Detail {
|
|
|
|
|
|
-class Approx {
|
|
|
+class Approx
|
|
|
+{
|
|
|
private:
|
|
|
bool equalityComparisonImpl(double other) const;
|
|
|
// Validates the new margin (margin >= 0)
|
|
@@ -3083,7 +3264,8 @@ public:
|
|
|
|
|
|
template<typename T, typename = typename std::enable_if<std::is_constructible<double,
|
|
|
T>::value>::type>
|
|
|
- Approx operator()(T const &value) {
|
|
|
+ Approx operator()(T const &value)
|
|
|
+ {
|
|
|
Approx approx(static_cast<double>(value));
|
|
|
approx.m_epsilon = m_epsilon;
|
|
|
approx.m_margin = m_margin;
|
|
@@ -3093,60 +3275,70 @@ public:
|
|
|
|
|
|
template<typename T, typename = typename std::enable_if<std::is_constructible<double,
|
|
|
T>::value>::type>
|
|
|
- explicit Approx(T const &value): Approx(static_cast<double>(value)) {}
|
|
|
+ explicit Approx(T const &value): Approx(static_cast<double>(value))
|
|
|
+ {}
|
|
|
|
|
|
template<typename T, typename = typename std::enable_if<std::is_constructible<double,
|
|
|
T>::value>::type>
|
|
|
- friend bool operator==(const T &lhs, Approx const &rhs) {
|
|
|
+ friend bool operator==(const T &lhs, Approx const &rhs)
|
|
|
+ {
|
|
|
auto lhs_v = static_cast<double>(lhs);
|
|
|
return rhs.equalityComparisonImpl(lhs_v);
|
|
|
}
|
|
|
|
|
|
template<typename T, typename = typename std::enable_if<std::is_constructible<double,
|
|
|
T>::value>::type>
|
|
|
- friend bool operator==(Approx const &lhs, const T &rhs) {
|
|
|
+ friend bool operator==(Approx const &lhs, const T &rhs)
|
|
|
+ {
|
|
|
return operator==(rhs, lhs);
|
|
|
}
|
|
|
|
|
|
template<typename T, typename = typename std::enable_if<std::is_constructible<double,
|
|
|
T>::value>::type>
|
|
|
- friend bool operator!=(T const &lhs, Approx const &rhs) {
|
|
|
+ friend bool operator!=(T const &lhs, Approx const &rhs)
|
|
|
+ {
|
|
|
return !operator==(lhs, rhs);
|
|
|
}
|
|
|
|
|
|
template<typename T, typename = typename std::enable_if<std::is_constructible<double,
|
|
|
T>::value>::type>
|
|
|
- friend bool operator!=(Approx const &lhs, T const &rhs) {
|
|
|
+ friend bool operator!=(Approx const &lhs, T const &rhs)
|
|
|
+ {
|
|
|
return !operator==(rhs, lhs);
|
|
|
}
|
|
|
|
|
|
template<typename T, typename = typename std::enable_if<std::is_constructible<double,
|
|
|
T>::value>::type>
|
|
|
- friend bool operator<=(T const &lhs, Approx const &rhs) {
|
|
|
+ friend bool operator<=(T const &lhs, Approx const &rhs)
|
|
|
+ {
|
|
|
return static_cast<double>(lhs) < rhs.m_value || lhs == rhs;
|
|
|
}
|
|
|
|
|
|
template<typename T, typename = typename std::enable_if<std::is_constructible<double,
|
|
|
T>::value>::type>
|
|
|
- friend bool operator<=(Approx const &lhs, T const &rhs) {
|
|
|
+ friend bool operator<=(Approx const &lhs, T const &rhs)
|
|
|
+ {
|
|
|
return lhs.m_value < static_cast<double>(rhs) || lhs == rhs;
|
|
|
}
|
|
|
|
|
|
template<typename T, typename = typename std::enable_if<std::is_constructible<double,
|
|
|
T>::value>::type>
|
|
|
- friend bool operator>=(T const &lhs, Approx const &rhs) {
|
|
|
+ friend bool operator>=(T const &lhs, Approx const &rhs)
|
|
|
+ {
|
|
|
return static_cast<double>(lhs) > rhs.m_value || lhs == rhs;
|
|
|
}
|
|
|
|
|
|
template<typename T, typename = typename std::enable_if<std::is_constructible<double,
|
|
|
T>::value>::type>
|
|
|
- friend bool operator>=(Approx const &lhs, T const &rhs) {
|
|
|
+ friend bool operator>=(Approx const &lhs, T const &rhs)
|
|
|
+ {
|
|
|
return lhs.m_value > static_cast<double>(rhs) || lhs == rhs;
|
|
|
}
|
|
|
|
|
|
template<typename T, typename = typename std::enable_if<std::is_constructible<double,
|
|
|
T>::value>::type>
|
|
|
- Approx &epsilon(T const &newEpsilon) {
|
|
|
+ Approx &epsilon(T const &newEpsilon)
|
|
|
+ {
|
|
|
double epsilonAsDouble = static_cast<double>(newEpsilon);
|
|
|
setEpsilon(epsilonAsDouble);
|
|
|
return *this;
|
|
@@ -3154,7 +3346,8 @@ public:
|
|
|
|
|
|
template<typename T, typename = typename std::enable_if<std::is_constructible<double,
|
|
|
T>::value>::type>
|
|
|
- Approx &margin(T const &newMargin) {
|
|
|
+ Approx &margin(T const &newMargin)
|
|
|
+ {
|
|
|
double marginAsDouble = static_cast<double>(newMargin);
|
|
|
setMargin(marginAsDouble);
|
|
|
return *this;
|
|
@@ -3162,7 +3355,8 @@ public:
|
|
|
|
|
|
template<typename T, typename = typename std::enable_if<std::is_constructible<double,
|
|
|
T>::value>::type>
|
|
|
- Approx &scale(T const &newScale) {
|
|
|
+ Approx &scale(T const &newScale)
|
|
|
+ {
|
|
|
m_scale = static_cast<double>(newScale);
|
|
|
return *this;
|
|
|
}
|
|
@@ -3183,7 +3377,8 @@ Detail::Approx operator "" _a(unsigned long long val);
|
|
|
} // end namespace literals
|
|
|
|
|
|
template<>
|
|
|
-struct StringMaker<Catch::Detail::Approx> {
|
|
|
+struct StringMaker<Catch::Detail::Approx>
|
|
|
+{
|
|
|
static std::string convert(Catch::Detail::Approx const &value);
|
|
|
};
|
|
|
|
|
@@ -3211,7 +3406,8 @@ std::string trim(std::string const &str);
|
|
|
std::vector<StringRef> splitStringRef(StringRef str, char delimiter);
|
|
|
bool replaceInPlace(std::string &str, std::string const &replaceThis, std::string const &withThis);
|
|
|
|
|
|
-struct pluralise {
|
|
|
+struct pluralise
|
|
|
+{
|
|
|
pluralise(std::size_t count, std::string const &label);
|
|
|
|
|
|
friend std::ostream &operator<<(std::ostream &os, pluralise const &pluraliser);
|
|
@@ -3238,7 +3434,8 @@ template<typename ArgT> struct MatchAllOf;
|
|
|
template<typename ArgT> struct MatchAnyOf;
|
|
|
template<typename ArgT> struct MatchNotOf;
|
|
|
|
|
|
-class MatcherUntypedBase {
|
|
|
+class MatcherUntypedBase
|
|
|
+{
|
|
|
public:
|
|
|
MatcherUntypedBase() = default;
|
|
|
MatcherUntypedBase(MatcherUntypedBase const &) = default;
|
|
@@ -3257,7 +3454,8 @@ protected:
|
|
|
#endif
|
|
|
|
|
|
template<typename ObjectT>
|
|
|
-struct MatcherMethod {
|
|
|
+struct MatcherMethod
|
|
|
+{
|
|
|
virtual bool match(ObjectT const &arg) const = 0;
|
|
|
};
|
|
|
|
|
@@ -3275,7 +3473,8 @@ struct MatcherMethod {
|
|
|
#endif
|
|
|
|
|
|
template<typename T>
|
|
|
-struct MatcherBase : MatcherUntypedBase, MatcherMethod<T> {
|
|
|
+struct MatcherBase : MatcherUntypedBase, MatcherMethod<T>
|
|
|
+{
|
|
|
|
|
|
MatchAllOf<T> operator&&(MatcherBase const &other) const;
|
|
|
MatchAnyOf<T> operator||(MatcherBase const &other) const;
|
|
@@ -3283,15 +3482,18 @@ struct MatcherBase : MatcherUntypedBase, MatcherMethod<T> {
|
|
|
};
|
|
|
|
|
|
template<typename ArgT>
|
|
|
-struct MatchAllOf : MatcherBase<ArgT> {
|
|
|
- bool match(ArgT const &arg) const override {
|
|
|
+struct MatchAllOf : MatcherBase<ArgT>
|
|
|
+{
|
|
|
+ bool match(ArgT const &arg) const override
|
|
|
+ {
|
|
|
for (auto matcher : m_matchers) {
|
|
|
if (!matcher->match(arg))
|
|
|
return false;
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
- std::string describe() const override {
|
|
|
+ std::string describe() const override
|
|
|
+ {
|
|
|
std::string description;
|
|
|
description.reserve(4 + m_matchers.size() * 32);
|
|
|
description += "( ";
|
|
@@ -3307,7 +3509,8 @@ struct MatchAllOf : MatcherBase<ArgT> {
|
|
|
return description;
|
|
|
}
|
|
|
|
|
|
- MatchAllOf<ArgT> &operator&&(MatcherBase<ArgT> const &other) {
|
|
|
+ MatchAllOf<ArgT> &operator&&(MatcherBase<ArgT> const &other)
|
|
|
+ {
|
|
|
m_matchers.push_back(&other);
|
|
|
return *this;
|
|
|
}
|
|
@@ -3315,16 +3518,19 @@ struct MatchAllOf : MatcherBase<ArgT> {
|
|
|
std::vector<MatcherBase<ArgT> const *> m_matchers;
|
|
|
};
|
|
|
template<typename ArgT>
|
|
|
-struct MatchAnyOf : MatcherBase<ArgT> {
|
|
|
+struct MatchAnyOf : MatcherBase<ArgT>
|
|
|
+{
|
|
|
|
|
|
- bool match(ArgT const &arg) const override {
|
|
|
+ bool match(ArgT const &arg) const override
|
|
|
+ {
|
|
|
for (auto matcher : m_matchers) {
|
|
|
if (matcher->match(arg))
|
|
|
return true;
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
|
- std::string describe() const override {
|
|
|
+ std::string describe() const override
|
|
|
+ {
|
|
|
std::string description;
|
|
|
description.reserve(4 + m_matchers.size() * 32);
|
|
|
description += "( ";
|
|
@@ -3340,7 +3546,8 @@ struct MatchAnyOf : MatcherBase<ArgT> {
|
|
|
return description;
|
|
|
}
|
|
|
|
|
|
- MatchAnyOf<ArgT> &operator||(MatcherBase<ArgT> const &other) {
|
|
|
+ MatchAnyOf<ArgT> &operator||(MatcherBase<ArgT> const &other)
|
|
|
+ {
|
|
|
m_matchers.push_back(&other);
|
|
|
return *this;
|
|
|
}
|
|
@@ -3349,30 +3556,37 @@ struct MatchAnyOf : MatcherBase<ArgT> {
|
|
|
};
|
|
|
|
|
|
template<typename ArgT>
|
|
|
-struct MatchNotOf : MatcherBase<ArgT> {
|
|
|
+struct MatchNotOf : MatcherBase<ArgT>
|
|
|
+{
|
|
|
|
|
|
- MatchNotOf(MatcherBase<ArgT> const &underlyingMatcher) : m_underlyingMatcher(underlyingMatcher) {}
|
|
|
+ MatchNotOf(MatcherBase<ArgT> const &underlyingMatcher) : m_underlyingMatcher(underlyingMatcher)
|
|
|
+ {}
|
|
|
|
|
|
- bool match(ArgT const &arg) const override {
|
|
|
+ bool match(ArgT const &arg) const override
|
|
|
+ {
|
|
|
return !m_underlyingMatcher.match(arg);
|
|
|
}
|
|
|
|
|
|
- std::string describe() const override {
|
|
|
+ std::string describe() const override
|
|
|
+ {
|
|
|
return "not " + m_underlyingMatcher.toString();
|
|
|
}
|
|
|
MatcherBase<ArgT> const &m_underlyingMatcher;
|
|
|
};
|
|
|
|
|
|
template<typename T>
|
|
|
-MatchAllOf<T> MatcherBase<T>::operator&&(MatcherBase const &other) const {
|
|
|
+MatchAllOf<T> MatcherBase<T>::operator&&(MatcherBase const &other) const
|
|
|
+{
|
|
|
return MatchAllOf<T>() && *this && other;
|
|
|
}
|
|
|
template<typename T>
|
|
|
-MatchAnyOf<T> MatcherBase<T>::operator||(MatcherBase const &other) const {
|
|
|
+MatchAnyOf<T> MatcherBase<T>::operator||(MatcherBase const &other) const
|
|
|
+{
|
|
|
return MatchAnyOf<T>() || *this || other;
|
|
|
}
|
|
|
template<typename T>
|
|
|
-MatchNotOf<T> MatcherBase<T>::operator!() const {
|
|
|
+MatchNotOf<T> MatcherBase<T>::operator!() const
|
|
|
+{
|
|
|
return MatchNotOf<T>(*this);
|
|
|
}
|
|
|
|
|
@@ -3398,7 +3612,8 @@ namespace Floating {
|
|
|
|
|
|
enum class FloatingPointKind : uint8_t;
|
|
|
|
|
|
-struct WithinAbsMatcher : MatcherBase<double> {
|
|
|
+struct WithinAbsMatcher : MatcherBase<double>
|
|
|
+{
|
|
|
WithinAbsMatcher(double target, double margin);
|
|
|
bool match(double const &matchee) const override;
|
|
|
std::string describe() const override;
|
|
@@ -3407,7 +3622,8 @@ private:
|
|
|
double m_margin;
|
|
|
};
|
|
|
|
|
|
-struct WithinUlpsMatcher : MatcherBase<double> {
|
|
|
+struct WithinUlpsMatcher : MatcherBase<double>
|
|
|
+{
|
|
|
WithinUlpsMatcher(double target, int ulps, FloatingPointKind baseType);
|
|
|
bool match(double const &matchee) const override;
|
|
|
std::string describe() const override;
|
|
@@ -3443,20 +3659,24 @@ std::string finalizeDescription(const std::string &desc);
|
|
|
}
|
|
|
|
|
|
template<typename T>
|
|
|
-class PredicateMatcher : public MatcherBase<T> {
|
|
|
+class PredicateMatcher : public MatcherBase<T>
|
|
|
+{
|
|
|
std::function<bool(T const &)> m_predicate;
|
|
|
std::string m_description;
|
|
|
public:
|
|
|
|
|
|
PredicateMatcher(std::function<bool(T const &)> const &elem, std::string const &descr)
|
|
|
: m_predicate(std::move(elem)),
|
|
|
- m_description(Detail::finalizeDescription(descr)) {}
|
|
|
+ m_description(Detail::finalizeDescription(descr))
|
|
|
+ {}
|
|
|
|
|
|
- bool match(T const &item) const override {
|
|
|
+ bool match(T const &item) const override
|
|
|
+ {
|
|
|
return m_predicate(item);
|
|
|
}
|
|
|
|
|
|
- std::string describe() const override {
|
|
|
+ std::string describe() const override
|
|
|
+ {
|
|
|
return m_description;
|
|
|
}
|
|
|
};
|
|
@@ -3469,7 +3689,8 @@ public:
|
|
|
// requires a lot of TMP.
|
|
|
template<typename T>
|
|
|
Generic::PredicateMatcher<T> Predicate(std::function<bool(T const &)> const &predicate,
|
|
|
- std::string const &description = "") {
|
|
|
+ std::string const &description = "")
|
|
|
+{
|
|
|
return Generic::PredicateMatcher<T>(predicate, description);
|
|
|
}
|
|
|
|
|
@@ -3486,7 +3707,8 @@ namespace Matchers {
|
|
|
|
|
|
namespace StdString {
|
|
|
|
|
|
-struct CasedString {
|
|
|
+struct CasedString
|
|
|
+{
|
|
|
CasedString(std::string const &str, CaseSensitive::Choice caseSensitivity);
|
|
|
std::string adjustString(std::string const &str) const;
|
|
|
std::string caseSensitivitySuffix() const;
|
|
@@ -3495,7 +3717,8 @@ struct CasedString {
|
|
|
std::string m_str;
|
|
|
};
|
|
|
|
|
|
-struct StringMatcherBase : MatcherBase<std::string> {
|
|
|
+struct StringMatcherBase : MatcherBase<std::string>
|
|
|
+{
|
|
|
StringMatcherBase(std::string const &operation, CasedString const &comparator);
|
|
|
std::string describe() const override;
|
|
|
|
|
@@ -3503,24 +3726,29 @@ struct StringMatcherBase : MatcherBase<std::string> {
|
|
|
std::string m_operation;
|
|
|
};
|
|
|
|
|
|
-struct EqualsMatcher : StringMatcherBase {
|
|
|
+struct EqualsMatcher : StringMatcherBase
|
|
|
+{
|
|
|
EqualsMatcher(CasedString const &comparator);
|
|
|
bool match(std::string const &source) const override;
|
|
|
};
|
|
|
-struct ContainsMatcher : StringMatcherBase {
|
|
|
+struct ContainsMatcher : StringMatcherBase
|
|
|
+{
|
|
|
ContainsMatcher(CasedString const &comparator);
|
|
|
bool match(std::string const &source) const override;
|
|
|
};
|
|
|
-struct StartsWithMatcher : StringMatcherBase {
|
|
|
+struct StartsWithMatcher : StringMatcherBase
|
|
|
+{
|
|
|
StartsWithMatcher(CasedString const &comparator);
|
|
|
bool match(std::string const &source) const override;
|
|
|
};
|
|
|
-struct EndsWithMatcher : StringMatcherBase {
|
|
|
+struct EndsWithMatcher : StringMatcherBase
|
|
|
+{
|
|
|
EndsWithMatcher(CasedString const &comparator);
|
|
|
bool match(std::string const &source) const override;
|
|
|
};
|
|
|
|
|
|
-struct RegexMatcher : MatcherBase<std::string> {
|
|
|
+struct RegexMatcher : MatcherBase<std::string>
|
|
|
+{
|
|
|
RegexMatcher(std::string regex, CaseSensitive::Choice caseSensitivity);
|
|
|
bool match(std::string const &matchee) const override;
|
|
|
std::string describe() const override;
|
|
@@ -3559,11 +3787,14 @@ namespace Matchers {
|
|
|
|
|
|
namespace Vector {
|
|
|
template<typename T>
|
|
|
-struct ContainsElementMatcher : MatcherBase<std::vector<T>> {
|
|
|
+struct ContainsElementMatcher : MatcherBase<std::vector<T>>
|
|
|
+{
|
|
|
|
|
|
- ContainsElementMatcher(T const &comparator) : m_comparator(comparator) {}
|
|
|
+ ContainsElementMatcher(T const &comparator) : m_comparator(comparator)
|
|
|
+ {}
|
|
|
|
|
|
- bool match(std::vector<T> const &v) const override {
|
|
|
+ bool match(std::vector<T> const &v) const override
|
|
|
+ {
|
|
|
for (auto const &el : v) {
|
|
|
if (el == m_comparator) {
|
|
|
return true;
|
|
@@ -3572,7 +3803,8 @@ struct ContainsElementMatcher : MatcherBase<std::vector<T>> {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
- std::string describe() const override {
|
|
|
+ std::string describe() const override
|
|
|
+ {
|
|
|
return "Contains: " + ::Catch::Detail::stringify(m_comparator);
|
|
|
}
|
|
|
|
|
@@ -3580,11 +3812,14 @@ struct ContainsElementMatcher : MatcherBase<std::vector<T>> {
|
|
|
};
|
|
|
|
|
|
template<typename T>
|
|
|
-struct ContainsMatcher : MatcherBase<std::vector<T>> {
|
|
|
+struct ContainsMatcher : MatcherBase<std::vector<T>>
|
|
|
+{
|
|
|
|
|
|
- ContainsMatcher(std::vector<T> const &comparator) : m_comparator(comparator) {}
|
|
|
+ ContainsMatcher(std::vector<T> const &comparator) : m_comparator(comparator)
|
|
|
+ {}
|
|
|
|
|
|
- bool match(std::vector<T> const &v) const override {
|
|
|
+ bool match(std::vector<T> const &v) const override
|
|
|
+ {
|
|
|
// !TBD: see note in EqualsMatcher
|
|
|
if (m_comparator.size() > v.size())
|
|
|
return false;
|
|
@@ -3602,7 +3837,8 @@ struct ContainsMatcher : MatcherBase<std::vector<T>> {
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
- std::string describe() const override {
|
|
|
+ std::string describe() const override
|
|
|
+ {
|
|
|
return "Contains: " + ::Catch::Detail::stringify(m_comparator);
|
|
|
}
|
|
|
|
|
@@ -3610,11 +3846,14 @@ struct ContainsMatcher : MatcherBase<std::vector<T>> {
|
|
|
};
|
|
|
|
|
|
template<typename T>
|
|
|
-struct EqualsMatcher : MatcherBase<std::vector<T>> {
|
|
|
+struct EqualsMatcher : MatcherBase<std::vector<T>>
|
|
|
+{
|
|
|
|
|
|
- EqualsMatcher(std::vector<T> const &comparator) : m_comparator(comparator) {}
|
|
|
+ EqualsMatcher(std::vector<T> const &comparator) : m_comparator(comparator)
|
|
|
+ {}
|
|
|
|
|
|
- bool match(std::vector<T> const &v) const override {
|
|
|
+ bool match(std::vector<T> const &v) const override
|
|
|
+ {
|
|
|
// !TBD: This currently works if all elements can be compared using !=
|
|
|
// - a more general approach would be via a compare template that defaults
|
|
|
// to using !=. but could be specialised for, e.g. std::vector<T> etc
|
|
@@ -3626,18 +3865,22 @@ struct EqualsMatcher : MatcherBase<std::vector<T>> {
|
|
|
return false;
|
|
|
return true;
|
|
|
}
|
|
|
- std::string describe() const override {
|
|
|
+ std::string describe() const override
|
|
|
+ {
|
|
|
return "Equals: " + ::Catch::Detail::stringify(m_comparator);
|
|
|
}
|
|
|
std::vector<T> const &m_comparator;
|
|
|
};
|
|
|
|
|
|
template<typename T>
|
|
|
-struct ApproxMatcher : MatcherBase<std::vector<T>> {
|
|
|
+struct ApproxMatcher : MatcherBase<std::vector<T>>
|
|
|
+{
|
|
|
|
|
|
- ApproxMatcher(std::vector<T> const &comparator) : m_comparator(comparator) {}
|
|
|
+ ApproxMatcher(std::vector<T> const &comparator) : m_comparator(comparator)
|
|
|
+ {}
|
|
|
|
|
|
- bool match(std::vector<T> const &v) const override {
|
|
|
+ bool match(std::vector<T> const &v) const override
|
|
|
+ {
|
|
|
if (m_comparator.size() != v.size())
|
|
|
return false;
|
|
|
for (std::size_t i = 0; i < v.size(); ++i)
|
|
@@ -3645,21 +3888,25 @@ struct ApproxMatcher : MatcherBase<std::vector<T>> {
|
|
|
return false;
|
|
|
return true;
|
|
|
}
|
|
|
- std::string describe() const override {
|
|
|
+ std::string describe() const override
|
|
|
+ {
|
|
|
return "is approx: " + ::Catch::Detail::stringify(m_comparator);
|
|
|
}
|
|
|
template<typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
|
|
- ApproxMatcher &epsilon(T const &newEpsilon) {
|
|
|
+ ApproxMatcher &epsilon(T const &newEpsilon)
|
|
|
+ {
|
|
|
approx.epsilon(newEpsilon);
|
|
|
return *this;
|
|
|
}
|
|
|
template<typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
|
|
- ApproxMatcher &margin(T const &newMargin) {
|
|
|
+ ApproxMatcher &margin(T const &newMargin)
|
|
|
+ {
|
|
|
approx.margin(newMargin);
|
|
|
return *this;
|
|
|
}
|
|
|
template<typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
|
|
- ApproxMatcher &scale(T const &newScale) {
|
|
|
+ ApproxMatcher &scale(T const &newScale)
|
|
|
+ {
|
|
|
approx.scale(newScale);
|
|
|
return *this;
|
|
|
}
|
|
@@ -3669,9 +3916,12 @@ struct ApproxMatcher : MatcherBase<std::vector<T>> {
|
|
|
};
|
|
|
|
|
|
template<typename T>
|
|
|
-struct UnorderedEqualsMatcher : MatcherBase<std::vector<T>> {
|
|
|
- UnorderedEqualsMatcher(std::vector<T> const &target) : m_target(target) {}
|
|
|
- bool match(std::vector<T> const &vec) const override {
|
|
|
+struct UnorderedEqualsMatcher : MatcherBase<std::vector<T>>
|
|
|
+{
|
|
|
+ UnorderedEqualsMatcher(std::vector<T> const &target) : m_target(target)
|
|
|
+ {}
|
|
|
+ bool match(std::vector<T> const &vec) const override
|
|
|
+ {
|
|
|
// Note: This is a reimplementation of std::is_permutation,
|
|
|
// because I don't want to include <algorithm> inside the common path
|
|
|
if (m_target.size() != vec.size()) {
|
|
@@ -3680,7 +3930,8 @@ struct UnorderedEqualsMatcher : MatcherBase<std::vector<T>> {
|
|
|
return std::is_permutation(m_target.begin(), m_target.end(), vec.begin());
|
|
|
}
|
|
|
|
|
|
- std::string describe() const override {
|
|
|
+ std::string describe() const override
|
|
|
+ {
|
|
|
return "UnorderedEquals: " + ::Catch::Detail::stringify(m_target);
|
|
|
}
|
|
|
private:
|
|
@@ -3693,27 +3944,32 @@ private:
|
|
|
// This allows the types to be inferred
|
|
|
|
|
|
template<typename T>
|
|
|
-Vector::ContainsMatcher<T> Contains(std::vector<T> const &comparator) {
|
|
|
+Vector::ContainsMatcher<T> Contains(std::vector<T> const &comparator)
|
|
|
+{
|
|
|
return Vector::ContainsMatcher<T>(comparator);
|
|
|
}
|
|
|
|
|
|
template<typename T>
|
|
|
-Vector::ContainsElementMatcher<T> VectorContains(T const &comparator) {
|
|
|
+Vector::ContainsElementMatcher<T> VectorContains(T const &comparator)
|
|
|
+{
|
|
|
return Vector::ContainsElementMatcher<T>(comparator);
|
|
|
}
|
|
|
|
|
|
template<typename T>
|
|
|
-Vector::EqualsMatcher<T> Equals(std::vector<T> const &comparator) {
|
|
|
+Vector::EqualsMatcher<T> Equals(std::vector<T> const &comparator)
|
|
|
+{
|
|
|
return Vector::EqualsMatcher<T>(comparator);
|
|
|
}
|
|
|
|
|
|
template<typename T>
|
|
|
-Vector::ApproxMatcher<T> Approx(std::vector<T> const &comparator) {
|
|
|
+Vector::ApproxMatcher<T> Approx(std::vector<T> const &comparator)
|
|
|
+{
|
|
|
return Vector::ApproxMatcher<T>(comparator);
|
|
|
}
|
|
|
|
|
|
template<typename T>
|
|
|
-Vector::UnorderedEqualsMatcher<T> UnorderedEquals(std::vector<T> const &target) {
|
|
|
+Vector::UnorderedEqualsMatcher<T> UnorderedEquals(std::vector<T> const &target)
|
|
|
+{
|
|
|
return Vector::UnorderedEqualsMatcher<T>(target);
|
|
|
}
|
|
|
|
|
@@ -3724,7 +3980,8 @@ Vector::UnorderedEqualsMatcher<T> UnorderedEquals(std::vector<T> const &target)
|
|
|
namespace Catch {
|
|
|
|
|
|
template<typename ArgT, typename MatcherT>
|
|
|
-class MatchExpr : public ITransientExpression {
|
|
|
+class MatchExpr : public ITransientExpression
|
|
|
+{
|
|
|
ArgT const &m_arg;
|
|
|
MatcherT m_matcher;
|
|
|
StringRef m_matcherString;
|
|
@@ -3733,9 +3990,11 @@ public:
|
|
|
: ITransientExpression{true, matcher.match(arg)},
|
|
|
m_arg(arg),
|
|
|
m_matcher(matcher),
|
|
|
- m_matcherString(matcherString) {}
|
|
|
+ m_matcherString(matcherString)
|
|
|
+ {}
|
|
|
|
|
|
- void streamReconstructedExpression(std::ostream &os) const override {
|
|
|
+ void streamReconstructedExpression(std::ostream &os) const override
|
|
|
+ {
|
|
|
auto matcherAsString = m_matcher.toString();
|
|
|
os << Catch::Detail::stringify(m_arg) << ' ';
|
|
|
if (matcherAsString == Detail::unprintableString)
|
|
@@ -3754,7 +4013,8 @@ void handleExceptionMatchExpr(AssertionHandler &handler,
|
|
|
template<typename ArgT, typename MatcherT>
|
|
|
auto makeMatchExpr(ArgT const &arg,
|
|
|
MatcherT const &matcher,
|
|
|
- StringRef const &matcherString) -> MatchExpr<ArgT, MatcherT> {
|
|
|
+ StringRef const &matcherString) -> MatchExpr<ArgT, MatcherT>
|
|
|
+{
|
|
|
return MatchExpr<ArgT, MatcherT>(arg, matcher, matcherString);
|
|
|
}
|
|
|
|
|
@@ -3802,7 +4062,8 @@ auto makeMatchExpr(ArgT const &arg,
|
|
|
namespace Catch {
|
|
|
|
|
|
namespace Generators {
|
|
|
-class GeneratorUntypedBase {
|
|
|
+class GeneratorUntypedBase
|
|
|
+{
|
|
|
public:
|
|
|
GeneratorUntypedBase() = default;
|
|
|
virtual ~GeneratorUntypedBase();
|
|
@@ -3816,7 +4077,8 @@ using GeneratorBasePtr = std::unique_ptr<GeneratorUntypedBase>;
|
|
|
|
|
|
} // namespace Generators
|
|
|
|
|
|
-struct IGeneratorTracker {
|
|
|
+struct IGeneratorTracker
|
|
|
+{
|
|
|
virtual ~IGeneratorTracker();
|
|
|
virtual auto hasGenerator() const -> bool = 0;
|
|
|
virtual auto getGenerator() const -> Generators::GeneratorBasePtr const & = 0;
|
|
@@ -3834,7 +4096,8 @@ namespace Catch {
|
|
|
#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
|
|
|
template<typename Ex>
|
|
|
[[noreturn]]
|
|
|
-void throw_exception(Ex const &e) {
|
|
|
+void throw_exception(Ex const &e)
|
|
|
+{
|
|
|
throw e;
|
|
|
}
|
|
|
#else // ^^ Exceptions are enabled // Exceptions are disabled vv
|
|
@@ -3876,12 +4139,14 @@ void throw_runtime_error(std::string const &msg);
|
|
|
|
|
|
namespace Catch {
|
|
|
|
|
|
-class GeneratorException : public std::exception {
|
|
|
+class GeneratorException : public std::exception
|
|
|
+{
|
|
|
const char *const m_msg = "";
|
|
|
|
|
|
public:
|
|
|
GeneratorException(const char *msg) :
|
|
|
- m_msg(msg) {}
|
|
|
+ m_msg(msg)
|
|
|
+ {}
|
|
|
|
|
|
const char *what() const noexcept override final;
|
|
|
};
|
|
@@ -3891,13 +4156,15 @@ namespace Generators {
|
|
|
// !TBD move this into its own location?
|
|
|
namespace pf {
|
|
|
template<typename T, typename... Args>
|
|
|
-std::unique_ptr<T> make_unique(Args &&... args) {
|
|
|
+std::unique_ptr<T> make_unique(Args &&... args)
|
|
|
+{
|
|
|
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
template<typename T>
|
|
|
-struct IGenerator : GeneratorUntypedBase {
|
|
|
+struct IGenerator : GeneratorUntypedBase
|
|
|
+{
|
|
|
virtual ~IGenerator() = default;
|
|
|
|
|
|
// Returns the current element of the generator
|
|
@@ -3909,95 +4176,118 @@ struct IGenerator : GeneratorUntypedBase {
|
|
|
};
|
|
|
|
|
|
template<typename T>
|
|
|
-class SingleValueGenerator final : public IGenerator<T> {
|
|
|
+class SingleValueGenerator final : public IGenerator<T>
|
|
|
+{
|
|
|
T m_value;
|
|
|
public:
|
|
|
- SingleValueGenerator(T const &value) : m_value(value) {}
|
|
|
- SingleValueGenerator(T &&value) : m_value(std::move(value)) {}
|
|
|
+ SingleValueGenerator(T const &value) : m_value(value)
|
|
|
+ {}
|
|
|
+ SingleValueGenerator(T &&value) : m_value(std::move(value))
|
|
|
+ {}
|
|
|
|
|
|
- T const &get() const override {
|
|
|
+ T const &get() const override
|
|
|
+ {
|
|
|
return m_value;
|
|
|
}
|
|
|
- bool next() override {
|
|
|
+ bool next() override
|
|
|
+ {
|
|
|
return false;
|
|
|
}
|
|
|
};
|
|
|
|
|
|
template<typename T>
|
|
|
-class FixedValuesGenerator final : public IGenerator<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>"
|
|
|
"specialization, use SingleValue Generator instead.");
|
|
|
std::vector<T> m_values;
|
|
|
size_t m_idx = 0;
|
|
|
public:
|
|
|
- FixedValuesGenerator(std::initializer_list<T> values) : m_values(values) {}
|
|
|
+ FixedValuesGenerator(std::initializer_list<T> values) : m_values(values)
|
|
|
+ {}
|
|
|
|
|
|
- T const &get() const override {
|
|
|
+ T const &get() const override
|
|
|
+ {
|
|
|
return m_values[m_idx];
|
|
|
}
|
|
|
- bool next() override {
|
|
|
+ bool next() override
|
|
|
+ {
|
|
|
++m_idx;
|
|
|
return m_idx < m_values.size();
|
|
|
}
|
|
|
};
|
|
|
|
|
|
template<typename T>
|
|
|
-class GeneratorWrapper final {
|
|
|
+class GeneratorWrapper final
|
|
|
+{
|
|
|
std::unique_ptr<IGenerator<T>> m_generator;
|
|
|
public:
|
|
|
GeneratorWrapper(std::unique_ptr<IGenerator<T>> generator) :
|
|
|
- m_generator(std::move(generator)) {}
|
|
|
- T const &get() const {
|
|
|
+ m_generator(std::move(generator))
|
|
|
+ {}
|
|
|
+ T const &get() const
|
|
|
+ {
|
|
|
return m_generator->get();
|
|
|
}
|
|
|
- bool next() {
|
|
|
+ bool next()
|
|
|
+ {
|
|
|
return m_generator->next();
|
|
|
}
|
|
|
};
|
|
|
|
|
|
template<typename T>
|
|
|
-GeneratorWrapper<T> value(T &&value) {
|
|
|
+GeneratorWrapper<T> value(T &&value)
|
|
|
+{
|
|
|
return GeneratorWrapper<T>(pf::make_unique<SingleValueGenerator<T>>(std::forward<T>(value)));
|
|
|
}
|
|
|
template<typename T>
|
|
|
-GeneratorWrapper<T> values(std::initializer_list<T> values) {
|
|
|
+GeneratorWrapper<T> values(std::initializer_list<T> values)
|
|
|
+{
|
|
|
return GeneratorWrapper<T>(pf::make_unique<FixedValuesGenerator<T>>(values));
|
|
|
}
|
|
|
|
|
|
template<typename T>
|
|
|
-class Generators : public IGenerator<T> {
|
|
|
+class Generators : public IGenerator<T>
|
|
|
+{
|
|
|
std::vector<GeneratorWrapper<T>> m_generators;
|
|
|
size_t m_current = 0;
|
|
|
|
|
|
- void populate(GeneratorWrapper<T> &&generator) {
|
|
|
+ void populate(GeneratorWrapper<T> &&generator)
|
|
|
+ {
|
|
|
m_generators.emplace_back(std::move(generator));
|
|
|
}
|
|
|
- void populate(T &&val) {
|
|
|
+ void populate(T &&val)
|
|
|
+ {
|
|
|
m_generators.emplace_back(value(std::move(val)));
|
|
|
}
|
|
|
template<typename U>
|
|
|
- void populate(U &&val) {
|
|
|
+ void populate(U &&val)
|
|
|
+ {
|
|
|
populate(T(std::move(val)));
|
|
|
}
|
|
|
template<typename U, typename... Gs>
|
|
|
- void populate(U &&valueOrGenerator, Gs... moreGenerators) {
|
|
|
+ void populate(U &&valueOrGenerator, Gs... moreGenerators)
|
|
|
+ {
|
|
|
populate(std::forward<U>(valueOrGenerator));
|
|
|
populate(std::forward<Gs>(moreGenerators)...);
|
|
|
}
|
|
|
|
|
|
public:
|
|
|
template<typename... Gs>
|
|
|
- Generators(Gs... moreGenerators) {
|
|
|
+ Generators(Gs... moreGenerators)
|
|
|
+ {
|
|
|
m_generators.reserve(sizeof...(Gs));
|
|
|
populate(std::forward<Gs>(moreGenerators)...);
|
|
|
}
|
|
|
|
|
|
- T const &get() const override {
|
|
|
+ T const &get() const override
|
|
|
+ {
|
|
|
return m_generators[m_current].get();
|
|
|
}
|
|
|
|
|
|
- bool next() override {
|
|
|
+ bool next() override
|
|
|
+ {
|
|
|
if (m_current >= m_generators.size()) {
|
|
|
return false;
|
|
|
}
|
|
@@ -4010,28 +4300,35 @@ public:
|
|
|
};
|
|
|
|
|
|
template<typename... Ts>
|
|
|
-GeneratorWrapper<std::tuple<Ts...>> table(std::initializer_list<std::tuple<typename std::decay<Ts>::type...>> tuples) {
|
|
|
+GeneratorWrapper<std::tuple<Ts...>> table(std::initializer_list<std::tuple<typename std::decay<Ts>::type...>> tuples)
|
|
|
+{
|
|
|
return values<std::tuple<Ts...>>(tuples);
|
|
|
}
|
|
|
|
|
|
// Tag type to signal that a generator sequence should convert arguments to a specific type
|
|
|
template<typename T>
|
|
|
-struct as {};
|
|
|
+struct as
|
|
|
+{
|
|
|
+};
|
|
|
|
|
|
template<typename T, typename... Gs>
|
|
|
-auto makeGenerators(GeneratorWrapper<T> &&generator, Gs... moreGenerators) -> Generators<T> {
|
|
|
+auto makeGenerators(GeneratorWrapper<T> &&generator, Gs... moreGenerators) -> Generators<T>
|
|
|
+{
|
|
|
return Generators<T>(std::move(generator), std::forward<Gs>(moreGenerators)...);
|
|
|
}
|
|
|
template<typename T>
|
|
|
-auto makeGenerators(GeneratorWrapper<T> &&generator) -> Generators<T> {
|
|
|
+auto makeGenerators(GeneratorWrapper<T> &&generator) -> Generators<T>
|
|
|
+{
|
|
|
return Generators<T>(std::move(generator));
|
|
|
}
|
|
|
template<typename T, typename... Gs>
|
|
|
-auto makeGenerators(T &&val, Gs... moreGenerators) -> Generators<T> {
|
|
|
+auto makeGenerators(T &&val, Gs... moreGenerators) -> Generators<T>
|
|
|
+{
|
|
|
return makeGenerators(value(std::forward<T>(val)), std::forward<Gs>(moreGenerators)...);
|
|
|
}
|
|
|
template<typename T, typename U, typename... Gs>
|
|
|
-auto makeGenerators(as<T>, U &&val, Gs... moreGenerators) -> Generators<T> {
|
|
|
+auto makeGenerators(as<T>, U &&val, Gs... moreGenerators) -> Generators<T>
|
|
|
+{
|
|
|
return makeGenerators(value(T(std::forward<U>(val))), std::forward<Gs>(moreGenerators)...);
|
|
|
}
|
|
|
|
|
@@ -4043,7 +4340,8 @@ template<typename L>
|
|
|
// return type. Yeah.
|
|
|
auto generate(SourceLineInfo const &lineInfo,
|
|
|
L const &generatorExpression) -> decltype(std::declval<decltype(generatorExpression())>()
|
|
|
- .get()) {
|
|
|
+ .get())
|
|
|
+{
|
|
|
using UnderlyingType = typename decltype(generatorExpression())::type;
|
|
|
|
|
|
IGeneratorTracker &tracker = acquireGeneratorTracker(lineInfo);
|
|
@@ -4072,20 +4370,24 @@ namespace Catch {
|
|
|
namespace Generators {
|
|
|
|
|
|
template<typename T>
|
|
|
-class TakeGenerator : public IGenerator<T> {
|
|
|
+class TakeGenerator : public IGenerator<T>
|
|
|
+{
|
|
|
GeneratorWrapper<T> m_generator;
|
|
|
size_t m_returned = 0;
|
|
|
size_t m_target;
|
|
|
public:
|
|
|
TakeGenerator(size_t target, GeneratorWrapper<T> &&generator) :
|
|
|
m_generator(std::move(generator)),
|
|
|
- m_target(target) {
|
|
|
+ m_target(target)
|
|
|
+ {
|
|
|
assert(target != 0 && "Empty generators are not allowed");
|
|
|
}
|
|
|
- T const &get() const override {
|
|
|
+ T const &get() const override
|
|
|
+ {
|
|
|
return m_generator.get();
|
|
|
}
|
|
|
- bool next() override {
|
|
|
+ bool next() override
|
|
|
+ {
|
|
|
++m_returned;
|
|
|
if (m_returned >= m_target) {
|
|
|
return false;
|
|
@@ -4102,19 +4404,22 @@ public:
|
|
|
};
|
|
|
|
|
|
template<typename T>
|
|
|
-GeneratorWrapper<T> take(size_t target, GeneratorWrapper<T> &&generator) {
|
|
|
+GeneratorWrapper<T> take(size_t target, GeneratorWrapper<T> &&generator)
|
|
|
+{
|
|
|
return GeneratorWrapper<T>(pf::make_unique<TakeGenerator<T>>(target, std::move(generator)));
|
|
|
}
|
|
|
|
|
|
template<typename T, typename Predicate>
|
|
|
-class FilterGenerator : public IGenerator<T> {
|
|
|
+class FilterGenerator : public IGenerator<T>
|
|
|
+{
|
|
|
GeneratorWrapper<T> m_generator;
|
|
|
Predicate m_predicate;
|
|
|
public:
|
|
|
template<typename P = Predicate>
|
|
|
FilterGenerator(P &&pred, GeneratorWrapper<T> &&generator):
|
|
|
m_generator(std::move(generator)),
|
|
|
- m_predicate(std::forward<P>(pred)) {
|
|
|
+ m_predicate(std::forward<P>(pred))
|
|
|
+ {
|
|
|
if (!m_predicate(m_generator.get())) {
|
|
|
// It might happen that there are no values that pass the
|
|
|
// filter. In that case we throw an exception.
|
|
@@ -4125,11 +4430,13 @@ public:
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- T const &get() const override {
|
|
|
+ T const &get() const override
|
|
|
+ {
|
|
|
return m_generator.get();
|
|
|
}
|
|
|
|
|
|
- bool next() override {
|
|
|
+ bool next() override
|
|
|
+ {
|
|
|
bool success = m_generator.next();
|
|
|
if (!success) {
|
|
|
return false;
|
|
@@ -4140,7 +4447,8 @@ public:
|
|
|
};
|
|
|
|
|
|
template<typename T, typename Predicate>
|
|
|
-GeneratorWrapper<T> filter(Predicate &&pred, GeneratorWrapper<T> &&generator) {
|
|
|
+GeneratorWrapper<T> filter(Predicate &&pred, GeneratorWrapper<T> &&generator)
|
|
|
+{
|
|
|
return GeneratorWrapper<T>(std::unique_ptr<IGenerator<T>>(pf::make_unique<FilterGenerator<T,
|
|
|
Predicate>>(
|
|
|
std::forward<Predicate>(pred),
|
|
@@ -4148,7 +4456,8 @@ GeneratorWrapper<T> filter(Predicate &&pred, GeneratorWrapper<T> &&generator) {
|
|
|
}
|
|
|
|
|
|
template<typename T>
|
|
|
-class RepeatGenerator : public IGenerator<T> {
|
|
|
+class RepeatGenerator : public IGenerator<T>
|
|
|
+{
|
|
|
static_assert(!std::is_same<T, bool>::value,
|
|
|
"RepeatGenerator currently does not support bools"
|
|
|
"because of std::vector<bool> specialization");
|
|
@@ -4160,11 +4469,13 @@ class RepeatGenerator : public IGenerator<T> {
|
|
|
public:
|
|
|
RepeatGenerator(size_t repeats, GeneratorWrapper<T> &&generator) :
|
|
|
m_generator(std::move(generator)),
|
|
|
- m_target_repeats(repeats) {
|
|
|
+ m_target_repeats(repeats)
|
|
|
+ {
|
|
|
assert(m_target_repeats > 0 && "Repeat generator must repeat at least once");
|
|
|
}
|
|
|
|
|
|
- T const &get() const override {
|
|
|
+ T const &get() const override
|
|
|
+ {
|
|
|
if (m_current_repeat == 0) {
|
|
|
m_returned.push_back(m_generator.get());
|
|
|
return m_returned.back();
|
|
@@ -4172,7 +4483,8 @@ public:
|
|
|
return m_returned[m_repeat_index];
|
|
|
}
|
|
|
|
|
|
- bool next() override {
|
|
|
+ bool next() override
|
|
|
+ {
|
|
|
// There are 2 basic cases:
|
|
|
// 1) We are still reading the generator
|
|
|
// 2) We are reading our own cache
|
|
@@ -4198,12 +4510,14 @@ public:
|
|
|
};
|
|
|
|
|
|
template<typename T>
|
|
|
-GeneratorWrapper<T> repeat(size_t repeats, GeneratorWrapper<T> &&generator) {
|
|
|
+GeneratorWrapper<T> repeat(size_t repeats, GeneratorWrapper<T> &&generator)
|
|
|
+{
|
|
|
return GeneratorWrapper<T>(pf::make_unique<RepeatGenerator<T>>(repeats, std::move(generator)));
|
|
|
}
|
|
|
|
|
|
template<typename T, typename U, typename Func>
|
|
|
-class MapGenerator : public IGenerator<T> {
|
|
|
+class MapGenerator : public IGenerator<T>
|
|
|
+{
|
|
|
// TBD: provide static assert for mapping function, for friendly error message
|
|
|
GeneratorWrapper<U> m_generator;
|
|
|
Func m_function;
|
|
@@ -4214,12 +4528,15 @@ public:
|
|
|
MapGenerator(F2 &&function, GeneratorWrapper<U> &&generator) :
|
|
|
m_generator(std::move(generator)),
|
|
|
m_function(std::forward<F2>(function)),
|
|
|
- m_cache(m_function(m_generator.get())) {}
|
|
|
+ m_cache(m_function(m_generator.get()))
|
|
|
+ {}
|
|
|
|
|
|
- T const &get() const override {
|
|
|
+ T const &get() const override
|
|
|
+ {
|
|
|
return m_cache;
|
|
|
}
|
|
|
- bool next() override {
|
|
|
+ bool next() override
|
|
|
+ {
|
|
|
const auto success = m_generator.next();
|
|
|
if (success) {
|
|
|
m_cache = m_function(m_generator.get());
|
|
@@ -4241,28 +4558,32 @@ using MapFunctionReturnType = typename std::remove_reference<typename std::remov
|
|
|
#endif
|
|
|
|
|
|
template<typename Func, typename U, typename T = MapFunctionReturnType<Func, U>>
|
|
|
-GeneratorWrapper<T> map(Func &&function, GeneratorWrapper<U> &&generator) {
|
|
|
+GeneratorWrapper<T> map(Func &&function, GeneratorWrapper<U> &&generator)
|
|
|
+{
|
|
|
return GeneratorWrapper<T>(
|
|
|
pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator))
|
|
|
);
|
|
|
}
|
|
|
|
|
|
template<typename T, typename U, typename Func>
|
|
|
-GeneratorWrapper<T> map(Func &&function, GeneratorWrapper<U> &&generator) {
|
|
|
+GeneratorWrapper<T> map(Func &&function, GeneratorWrapper<U> &&generator)
|
|
|
+{
|
|
|
return GeneratorWrapper<T>(
|
|
|
pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator))
|
|
|
);
|
|
|
}
|
|
|
|
|
|
template<typename T>
|
|
|
-class ChunkGenerator final : public IGenerator<std::vector<T>> {
|
|
|
+class ChunkGenerator final : public IGenerator<std::vector<T>>
|
|
|
+{
|
|
|
std::vector<T> m_chunk;
|
|
|
size_t m_chunk_size;
|
|
|
GeneratorWrapper<T> m_generator;
|
|
|
bool m_used_up = false;
|
|
|
public:
|
|
|
ChunkGenerator(size_t size, GeneratorWrapper<T> generator) :
|
|
|
- m_chunk_size(size), m_generator(std::move(generator)) {
|
|
|
+ m_chunk_size(size), m_generator(std::move(generator))
|
|
|
+ {
|
|
|
m_chunk.reserve(m_chunk_size);
|
|
|
if (m_chunk_size != 0) {
|
|
|
m_chunk.push_back(m_generator.get());
|
|
@@ -4275,10 +4596,12 @@ public:
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- std::vector<T> const &get() const override {
|
|
|
+ std::vector<T> const &get() const override
|
|
|
+ {
|
|
|
return m_chunk;
|
|
|
}
|
|
|
- bool next() override {
|
|
|
+ bool next() override
|
|
|
+ {
|
|
|
m_chunk.clear();
|
|
|
for (size_t idx = 0; idx < m_chunk_size; ++idx) {
|
|
|
if (!m_generator.next()) {
|
|
@@ -4291,7 +4614,8 @@ public:
|
|
|
};
|
|
|
|
|
|
template<typename T>
|
|
|
-GeneratorWrapper<std::vector<T>> chunk(size_t size, GeneratorWrapper<T> &&generator) {
|
|
|
+GeneratorWrapper<std::vector<T>> chunk(size_t size, GeneratorWrapper<T> &&generator)
|
|
|
+{
|
|
|
return GeneratorWrapper<std::vector<T>>(
|
|
|
pf::make_unique<ChunkGenerator<T>>(size, std::move(generator))
|
|
|
);
|
|
@@ -4316,7 +4640,8 @@ struct IMutableContext;
|
|
|
|
|
|
using IConfigPtr = std::shared_ptr<IConfig const>;
|
|
|
|
|
|
-struct IContext {
|
|
|
+struct IContext
|
|
|
+{
|
|
|
virtual ~IContext();
|
|
|
|
|
|
virtual IResultCapture *getResultCapture() = 0;
|
|
@@ -4324,7 +4649,8 @@ struct IContext {
|
|
|
virtual IConfigPtr const &getConfig() const = 0;
|
|
|
};
|
|
|
|
|
|
-struct IMutableContext : IContext {
|
|
|
+struct IMutableContext : IContext
|
|
|
+{
|
|
|
virtual ~IMutableContext();
|
|
|
virtual void setResultCapture(IResultCapture *resultCapture) = 0;
|
|
|
virtual void setRunner(IRunner *runner) = 0;
|
|
@@ -4337,13 +4663,15 @@ private:
|
|
|
static void createContext();
|
|
|
};
|
|
|
|
|
|
-inline IMutableContext &getCurrentMutableContext() {
|
|
|
+inline IMutableContext &getCurrentMutableContext()
|
|
|
+{
|
|
|
if (!IMutableContext::currentContext)
|
|
|
IMutableContext::createContext();
|
|
|
return *IMutableContext::currentContext;
|
|
|
}
|
|
|
|
|
|
-inline IContext &getCurrentContext() {
|
|
|
+inline IContext &getCurrentContext()
|
|
|
+{
|
|
|
return getCurrentMutableContext();
|
|
|
}
|
|
|
|
|
@@ -4359,19 +4687,25 @@ namespace Catch {
|
|
|
|
|
|
// An optional type
|
|
|
template<typename T>
|
|
|
-class Option {
|
|
|
+class Option
|
|
|
+{
|
|
|
public:
|
|
|
- Option() : nullableValue(nullptr) {}
|
|
|
+ Option() : nullableValue(nullptr)
|
|
|
+ {}
|
|
|
Option(T const &_value)
|
|
|
- : nullableValue(new(storage) T(_value)) {}
|
|
|
+ : nullableValue(new(storage) T(_value))
|
|
|
+ {}
|
|
|
Option(Option const &_other)
|
|
|
- : nullableValue(_other ? new(storage) T(*_other) : nullptr) {}
|
|
|
+ : nullableValue(_other ? new(storage) T(*_other) : nullptr)
|
|
|
+ {}
|
|
|
|
|
|
- ~Option() {
|
|
|
+ ~Option()
|
|
|
+ {
|
|
|
reset();
|
|
|
}
|
|
|
|
|
|
- Option &operator=(Option const &_other) {
|
|
|
+ Option &operator=(Option const &_other)
|
|
|
+ {
|
|
|
if (&_other != this) {
|
|
|
reset();
|
|
|
if (_other)
|
|
@@ -4379,32 +4713,43 @@ public:
|
|
|
}
|
|
|
return *this;
|
|
|
}
|
|
|
- Option &operator=(T const &_value) {
|
|
|
+ Option &operator=(T const &_value)
|
|
|
+ {
|
|
|
reset();
|
|
|
nullableValue = new(storage) T(_value);
|
|
|
return *this;
|
|
|
}
|
|
|
|
|
|
- void reset() {
|
|
|
+ void reset()
|
|
|
+ {
|
|
|
if (nullableValue)
|
|
|
nullableValue->~T();
|
|
|
nullableValue = nullptr;
|
|
|
}
|
|
|
|
|
|
- T &operator*() { return *nullableValue; }
|
|
|
- T const &operator*() const { return *nullableValue; }
|
|
|
- T *operator->() { return nullableValue; }
|
|
|
- const T *operator->() const { return nullableValue; }
|
|
|
-
|
|
|
- T valueOr(T const &defaultValue) const {
|
|
|
+ T &operator*()
|
|
|
+ { return *nullableValue; }
|
|
|
+ T const &operator*() const
|
|
|
+ { return *nullableValue; }
|
|
|
+ T *operator->()
|
|
|
+ { return nullableValue; }
|
|
|
+ const T *operator->() const
|
|
|
+ { return nullableValue; }
|
|
|
+
|
|
|
+ T valueOr(T const &defaultValue) const
|
|
|
+ {
|
|
|
return nullableValue ? *nullableValue : defaultValue;
|
|
|
}
|
|
|
|
|
|
- bool some() const { return nullableValue != nullptr; }
|
|
|
- bool none() const { return nullableValue == nullptr; }
|
|
|
+ bool some() const
|
|
|
+ { return nullableValue != nullptr; }
|
|
|
+ bool none() const
|
|
|
+ { return nullableValue == nullptr; }
|
|
|
|
|
|
- bool operator!() const { return nullableValue == nullptr; }
|
|
|
- explicit operator bool() const {
|
|
|
+ bool operator!() const
|
|
|
+ { return nullableValue == nullptr; }
|
|
|
+ explicit operator bool() const
|
|
|
+ {
|
|
|
return some();
|
|
|
}
|
|
|
|
|
@@ -4423,43 +4768,54 @@ private:
|
|
|
|
|
|
namespace Catch {
|
|
|
|
|
|
-enum class Verbosity {
|
|
|
+enum class Verbosity
|
|
|
+{
|
|
|
Quiet = 0,
|
|
|
Normal,
|
|
|
High
|
|
|
};
|
|
|
|
|
|
-struct WarnAbout {
|
|
|
- enum What {
|
|
|
+struct WarnAbout
|
|
|
+{
|
|
|
+ enum What
|
|
|
+ {
|
|
|
Nothing = 0x00,
|
|
|
NoAssertions = 0x01,
|
|
|
NoTests = 0x02
|
|
|
};
|
|
|
};
|
|
|
|
|
|
-struct ShowDurations {
|
|
|
- enum OrNot {
|
|
|
+struct ShowDurations
|
|
|
+{
|
|
|
+ enum OrNot
|
|
|
+ {
|
|
|
DefaultForReporter,
|
|
|
Always,
|
|
|
Never
|
|
|
};
|
|
|
};
|
|
|
-struct RunTests {
|
|
|
- enum InWhatOrder {
|
|
|
+struct RunTests
|
|
|
+{
|
|
|
+ enum InWhatOrder
|
|
|
+ {
|
|
|
InDeclarationOrder,
|
|
|
InLexicographicalOrder,
|
|
|
InRandomOrder
|
|
|
};
|
|
|
};
|
|
|
-struct UseColour {
|
|
|
- enum YesOrNo {
|
|
|
+struct UseColour
|
|
|
+{
|
|
|
+ enum YesOrNo
|
|
|
+ {
|
|
|
Auto,
|
|
|
Yes,
|
|
|
No
|
|
|
};
|
|
|
};
|
|
|
-struct WaitForKeypress {
|
|
|
- enum When {
|
|
|
+struct WaitForKeypress
|
|
|
+{
|
|
|
+ enum When
|
|
|
+ {
|
|
|
Never,
|
|
|
BeforeStart = 1,
|
|
|
BeforeExit = 2,
|
|
@@ -4469,7 +4825,8 @@ struct WaitForKeypress {
|
|
|
|
|
|
class TestSpec;
|
|
|
|
|
|
-struct IConfig : NonCopyable {
|
|
|
+struct IConfig : NonCopyable
|
|
|
+{
|
|
|
|
|
|
virtual ~IConfig();
|
|
|
|
|
@@ -4508,7 +4865,8 @@ namespace Catch {
|
|
|
namespace Generators {
|
|
|
|
|
|
template<typename Float>
|
|
|
-class RandomFloatingGenerator final : public IGenerator<Float> {
|
|
|
+class RandomFloatingGenerator final : public IGenerator<Float>
|
|
|
+{
|
|
|
// FIXME: What is the right seed?
|
|
|
std::minstd_rand m_rand;
|
|
|
std::uniform_real_distribution<Float> m_dist;
|
|
@@ -4517,21 +4875,25 @@ public:
|
|
|
|
|
|
RandomFloatingGenerator(Float a, Float b) :
|
|
|
m_rand(getCurrentContext().getConfig()->rngSeed()),
|
|
|
- m_dist(a, b) {
|
|
|
+ m_dist(a, b)
|
|
|
+ {
|
|
|
static_cast<void>(next());
|
|
|
}
|
|
|
|
|
|
- Float const &get() const override {
|
|
|
+ Float const &get() const override
|
|
|
+ {
|
|
|
return m_current_number;
|
|
|
}
|
|
|
- bool next() override {
|
|
|
+ bool next() override
|
|
|
+ {
|
|
|
m_current_number = m_dist(m_rand);
|
|
|
return true;
|
|
|
}
|
|
|
};
|
|
|
|
|
|
template<typename Integer>
|
|
|
-class RandomIntegerGenerator final : public IGenerator<Integer> {
|
|
|
+class RandomIntegerGenerator final : public IGenerator<Integer>
|
|
|
+{
|
|
|
std::minstd_rand m_rand;
|
|
|
std::uniform_int_distribution<Integer> m_dist;
|
|
|
Integer m_current_number;
|
|
@@ -4539,14 +4901,17 @@ public:
|
|
|
|
|
|
RandomIntegerGenerator(Integer a, Integer b) :
|
|
|
m_rand(getCurrentContext().getConfig()->rngSeed()),
|
|
|
- m_dist(a, b) {
|
|
|
+ m_dist(a, b)
|
|
|
+ {
|
|
|
static_cast<void>(next());
|
|
|
}
|
|
|
|
|
|
- Integer const &get() const override {
|
|
|
+ Integer const &get() const override
|
|
|
+ {
|
|
|
return m_current_number;
|
|
|
}
|
|
|
- bool next() override {
|
|
|
+ bool next() override
|
|
|
+ {
|
|
|
m_current_number = m_dist(m_rand);
|
|
|
return true;
|
|
|
}
|
|
@@ -4557,7 +4922,8 @@ public:
|
|
|
template<typename T>
|
|
|
typename std::enable_if<std::is_integral<T>::value && !std::is_same<T, bool>::value,
|
|
|
GeneratorWrapper<T>>::type
|
|
|
-random(T a, T b) {
|
|
|
+random(T a, T b)
|
|
|
+{
|
|
|
return GeneratorWrapper<T>(
|
|
|
pf::make_unique<RandomIntegerGenerator<T>>(a, b)
|
|
|
);
|
|
@@ -4566,14 +4932,16 @@ random(T a, T b) {
|
|
|
template<typename T>
|
|
|
typename std::enable_if<std::is_floating_point<T>::value,
|
|
|
GeneratorWrapper<T>>::type
|
|
|
-random(T a, T b) {
|
|
|
+random(T a, T b)
|
|
|
+{
|
|
|
return GeneratorWrapper<T>(
|
|
|
pf::make_unique<RandomFloatingGenerator<T>>(a, b)
|
|
|
);
|
|
|
}
|
|
|
|
|
|
template<typename T>
|
|
|
-class RangeGenerator final : public IGenerator<T> {
|
|
|
+class RangeGenerator final : public IGenerator<T>
|
|
|
+{
|
|
|
T m_current;
|
|
|
T m_end;
|
|
|
T m_step;
|
|
@@ -4584,7 +4952,8 @@ public:
|
|
|
m_current(start),
|
|
|
m_end(end),
|
|
|
m_step(step),
|
|
|
- m_positive(m_step > T(0)) {
|
|
|
+ m_positive(m_step > T(0))
|
|
|
+ {
|
|
|
assert(m_current != m_end && "Range start and end cannot be equal");
|
|
|
assert(m_step != T(0) && "Step size cannot be zero");
|
|
|
assert(((m_positive && m_current <= m_end) || (!m_positive && m_current >= m_end))
|
|
@@ -4592,27 +4961,32 @@ public:
|
|
|
}
|
|
|
|
|
|
RangeGenerator(T const &start, T const &end) :
|
|
|
- RangeGenerator(start, end, (start < end) ? T(1) : T(-1)) {}
|
|
|
+ RangeGenerator(start, end, (start < end) ? T(1) : T(-1))
|
|
|
+ {}
|
|
|
|
|
|
- T const &get() const override {
|
|
|
+ T const &get() const override
|
|
|
+ {
|
|
|
return m_current;
|
|
|
}
|
|
|
|
|
|
- bool next() override {
|
|
|
+ bool next() override
|
|
|
+ {
|
|
|
m_current += m_step;
|
|
|
return (m_positive) ? (m_current < m_end) : (m_current > m_end);
|
|
|
}
|
|
|
};
|
|
|
|
|
|
template<typename T>
|
|
|
-GeneratorWrapper<T> range(T const &start, T const &end, T const &step) {
|
|
|
+GeneratorWrapper<T> range(T const &start, T const &end, T const &step)
|
|
|
+{
|
|
|
static_assert(std::is_integral<T>::value && !std::is_same<T, bool>::value,
|
|
|
"Type must be an integer");
|
|
|
return GeneratorWrapper<T>(pf::make_unique<RangeGenerator<T>>(start, end, step));
|
|
|
}
|
|
|
|
|
|
template<typename T>
|
|
|
-GeneratorWrapper<T> range(T const &start, T const &end) {
|
|
|
+GeneratorWrapper<T> range(T const &start, T const &end)
|
|
|
+{
|
|
|
static_assert(std::is_integral<T>::value && !std::is_same<T, bool>::value,
|
|
|
"Type must be an integer");
|
|
|
return GeneratorWrapper<T>(pf::make_unique<RangeGenerator<T>>(start, end));
|
|
@@ -4640,8 +5014,10 @@ namespace Catch {
|
|
|
|
|
|
struct ITestInvoker;
|
|
|
|
|
|
-struct TestCaseInfo {
|
|
|
- enum SpecialProperties {
|
|
|
+struct TestCaseInfo
|
|
|
+{
|
|
|
+ enum SpecialProperties
|
|
|
+ {
|
|
|
None = 0,
|
|
|
IsHidden = 1 << 1,
|
|
|
ShouldFail = 1 << 2,
|
|
@@ -4675,7 +5051,8 @@ struct TestCaseInfo {
|
|
|
SpecialProperties properties;
|
|
|
};
|
|
|
|
|
|
-class TestCase : public TestCaseInfo {
|
|
|
+class TestCase : public TestCaseInfo
|
|
|
+{
|
|
|
public:
|
|
|
|
|
|
TestCase(ITestInvoker *testCase, TestCaseInfo &&info);
|
|
@@ -4708,7 +5085,8 @@ TestCase makeTestCase(ITestInvoker *testCase,
|
|
|
|
|
|
namespace Catch {
|
|
|
|
|
|
-struct IRunner {
|
|
|
+struct IRunner
|
|
|
+{
|
|
|
virtual ~IRunner();
|
|
|
virtual bool aborting() const = 0;
|
|
|
};
|