1
0
mirror of https://github.com/catchorg/Catch2.git synced 2025-04-29 04:03:51 +00:00

Use variable templates

This commit is contained in:
ZXShady 2025-04-27 20:55:56 +02:00 committed by Chris Thrasher
parent dde8220613
commit 4ff57aba42
6 changed files with 32 additions and 37 deletions

View File

@ -97,7 +97,7 @@ namespace Catch {
}
// sets lambda to be used in fun *and* executes benchmark!
template <typename Fun, std::enable_if_t<!Detail::is_related<Fun, Benchmark>::value, int> = 0>
template <typename Fun, std::enable_if_t<!Detail::is_related_v<Fun, Benchmark>, int> = 0>
Benchmark & operator=(Fun func) {
auto const* cfg = getCurrentContext().getConfig();
if (!cfg->skipBenchmarks()) {

View File

@ -21,8 +21,7 @@ namespace Catch {
namespace Benchmark {
namespace Detail {
template <typename T, typename U>
struct is_related
: std::is_same<std::decay_t<T>, std::decay_t<U>> {};
static constexpr bool is_related_v = std::is_same<std::decay_t<T>, std::decay_t<U>>::value;
/// We need to reinvent std::function because every piece of code that might add overhead
/// in a measurement context needs to have consistent performance characteristics so that we
@ -63,7 +62,7 @@ namespace Catch {
BenchmarkFunction();
template <typename Fun,
std::enable_if_t<!is_related<Fun, BenchmarkFunction>::value, int> = 0>
std::enable_if_t<!is_related_v<Fun, BenchmarkFunction>, int> = 0>
BenchmarkFunction(Fun&& fun)
: f(new model<std::decay_t<Fun>>(CATCH_FORWARD(fun))) {}

View File

@ -64,18 +64,14 @@ namespace Catch {
return rawMemoryToString( &object, sizeof(object) );
}
template<typename T>
class IsStreamInsertable {
template<typename Stream, typename U>
static auto test(int)
-> decltype(std::declval<Stream&>() << std::declval<U>(), std::true_type());
template<typename T,typename = void>
static constexpr bool IsStreamInsertable_v = false;
template<typename, typename>
static auto test(...)->std::false_type;
public:
static const bool value = decltype(test<std::ostream, const T&>(0))::value;
};
template <typename T>
static constexpr bool IsStreamInsertable_v<
T,
decltype( void( std::declval<std::ostream&>() << std::declval<T>() ) )> =
true;
template<typename E>
std::string convertUnknownEnumToString( E e );
@ -120,7 +116,7 @@ namespace Catch {
struct StringMaker {
template <typename Fake = T>
static
std::enable_if_t<::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>
std::enable_if_t<::Catch::Detail::IsStreamInsertable_v<Fake>, std::string>
convert(const Fake& value) {
ReusableStringStream rss;
// NB: call using the function-like syntax to avoid ambiguity with
@ -131,7 +127,7 @@ namespace Catch {
template <typename Fake = T>
static
std::enable_if_t<!::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>
std::enable_if_t<!::Catch::Detail::IsStreamInsertable_v<Fake>, std::string>
convert( const Fake& value ) {
#if !defined(CATCH_CONFIG_FALLBACK_STRINGIFIER)
return Detail::convertUnstreamable(value);
@ -523,7 +519,7 @@ namespace Catch {
}
template<typename R>
struct StringMaker<R, std::enable_if_t<is_range<R>::value && !::Catch::Detail::IsStreamInsertable<R>::value>> {
struct StringMaker<R, std::enable_if_t<is_range<R>::value && !::Catch::Detail::IsStreamInsertable_v<R>>> {
static std::string convert( R const& range ) {
return rangeToString( range );
}

View File

@ -79,7 +79,7 @@ namespace Catch {
//! Creates a matcher that accepts ranges/containers with specific size
HasSizeMatcher SizeIs(std::size_t sz);
template <typename Matcher>
std::enable_if_t<Detail::is_matcher<Matcher>::value,
std::enable_if_t<Detail::is_matcher_v<Matcher>,
SizeMatchesMatcher<Matcher>> SizeIs(Matcher&& m) {
return SizeMatchesMatcher<Matcher>{CATCH_FORWARD(m)};
}

View File

@ -73,14 +73,14 @@ namespace Catch {
* Uses `std::equal_to` to do the comparison
*/
template <typename T>
std::enable_if_t<!Detail::is_matcher<T>::value,
std::enable_if_t<!Detail::is_matcher_v<T>,
ContainsElementMatcher<T, std::equal_to<>>> Contains(T&& elem) {
return { CATCH_FORWARD(elem), std::equal_to<>{} };
}
//! Creates a matcher that checks whether a range contains element matching a matcher
template <typename Matcher>
std::enable_if_t<Detail::is_matcher<Matcher>::value,
std::enable_if_t<Detail::is_matcher_v<Matcher>,
ContainsMatcherMatcher<Matcher>> Contains(Matcher&& matcher) {
return { CATCH_FORWARD(matcher) };
}

View File

@ -58,19 +58,19 @@ namespace Matchers {
}
template<typename T>
using is_generic_matcher = std::is_base_of<
static constexpr bool is_generic_matcher_v = std::is_base_of<
Catch::Matchers::MatcherGenericBase,
std::remove_cv_t<std::remove_reference_t<T>>
>;
>::value;
template<typename... Ts>
using are_generic_matchers = Catch::Detail::conjunction<is_generic_matcher<Ts>...>;
static constexpr bool are_generic_matchers_v = Catch::Detail::conjunction<std::integral_constant<bool,is_generic_matcher_v<Ts>>...>::value;
template<typename T>
using is_matcher = std::is_base_of<
static constexpr bool is_matcher_v = std::is_base_of<
Catch::Matchers::MatcherUntypedBase,
std::remove_cv_t<std::remove_reference_t<T>>
>;
>::value;
template<std::size_t N, typename Arg>
@ -143,7 +143,7 @@ namespace Matchers {
//! Avoids type nesting for `GenericAllOf && some matcher` case
template<typename MatcherRHS>
friend std::enable_if_t<is_matcher<MatcherRHS>::value,
friend std::enable_if_t<is_matcher_v<MatcherRHS>,
MatchAllOfGeneric<MatcherTs..., MatcherRHS>> operator && (
MatchAllOfGeneric<MatcherTs...>&& lhs,
MatcherRHS const& rhs) {
@ -152,7 +152,7 @@ namespace Matchers {
//! Avoids type nesting for `some matcher && GenericAllOf` case
template<typename MatcherLHS>
friend std::enable_if_t<is_matcher<MatcherLHS>::value,
friend std::enable_if_t<is_matcher_v<MatcherLHS>,
MatchAllOfGeneric<MatcherLHS, MatcherTs...>> operator && (
MatcherLHS const& lhs,
MatchAllOfGeneric<MatcherTs...>&& rhs) {
@ -197,7 +197,7 @@ namespace Matchers {
//! Avoids type nesting for `GenericAnyOf || some matcher` case
template<typename MatcherRHS>
friend std::enable_if_t<is_matcher<MatcherRHS>::value,
friend std::enable_if_t<is_matcher_v<MatcherRHS>,
MatchAnyOfGeneric<MatcherTs..., MatcherRHS>> operator || (
MatchAnyOfGeneric<MatcherTs...>&& lhs,
MatcherRHS const& rhs) {
@ -206,7 +206,7 @@ namespace Matchers {
//! Avoids type nesting for `some matcher || GenericAnyOf` case
template<typename MatcherLHS>
friend std::enable_if_t<is_matcher<MatcherLHS>::value,
friend std::enable_if_t<is_matcher_v<MatcherLHS>,
MatchAnyOfGeneric<MatcherLHS, MatcherTs...>> operator || (
MatcherLHS const& lhs,
MatchAnyOfGeneric<MatcherTs...>&& rhs) {
@ -246,20 +246,20 @@ namespace Matchers {
// compose only generic matchers
template<typename MatcherLHS, typename MatcherRHS>
std::enable_if_t<Detail::are_generic_matchers<MatcherLHS, MatcherRHS>::value, Detail::MatchAllOfGeneric<MatcherLHS, MatcherRHS>>
std::enable_if_t<Detail::are_generic_matchers_v<MatcherLHS, MatcherRHS>, Detail::MatchAllOfGeneric<MatcherLHS, MatcherRHS>>
operator && (MatcherLHS const& lhs, MatcherRHS const& rhs) {
return { lhs, rhs };
}
template<typename MatcherLHS, typename MatcherRHS>
std::enable_if_t<Detail::are_generic_matchers<MatcherLHS, MatcherRHS>::value, Detail::MatchAnyOfGeneric<MatcherLHS, MatcherRHS>>
std::enable_if_t<Detail::are_generic_matchers_v<MatcherLHS, MatcherRHS>, Detail::MatchAnyOfGeneric<MatcherLHS, MatcherRHS>>
operator || (MatcherLHS const& lhs, MatcherRHS const& rhs) {
return { lhs, rhs };
}
//! Wrap provided generic matcher in generic negator
template<typename MatcherT>
std::enable_if_t<Detail::is_generic_matcher<MatcherT>::value, Detail::MatchNotOfGeneric<MatcherT>>
std::enable_if_t<Detail::is_generic_matcher_v<MatcherT>, Detail::MatchNotOfGeneric<MatcherT>>
operator ! (MatcherT const& matcher) {
return Detail::MatchNotOfGeneric<MatcherT>{matcher};
}
@ -267,25 +267,25 @@ namespace Matchers {
// compose mixed generic and non-generic matchers
template<typename MatcherLHS, typename ArgRHS>
std::enable_if_t<Detail::is_generic_matcher<MatcherLHS>::value, Detail::MatchAllOfGeneric<MatcherLHS, MatcherBase<ArgRHS>>>
std::enable_if_t<Detail::is_generic_matcher_v<MatcherLHS>, Detail::MatchAllOfGeneric<MatcherLHS, MatcherBase<ArgRHS>>>
operator && (MatcherLHS const& lhs, MatcherBase<ArgRHS> const& rhs) {
return { lhs, rhs };
}
template<typename ArgLHS, typename MatcherRHS>
std::enable_if_t<Detail::is_generic_matcher<MatcherRHS>::value, Detail::MatchAllOfGeneric<MatcherBase<ArgLHS>, MatcherRHS>>
std::enable_if_t<Detail::is_generic_matcher_v<MatcherRHS>, Detail::MatchAllOfGeneric<MatcherBase<ArgLHS>, MatcherRHS>>
operator && (MatcherBase<ArgLHS> const& lhs, MatcherRHS const& rhs) {
return { lhs, rhs };
}
template<typename MatcherLHS, typename ArgRHS>
std::enable_if_t<Detail::is_generic_matcher<MatcherLHS>::value, Detail::MatchAnyOfGeneric<MatcherLHS, MatcherBase<ArgRHS>>>
std::enable_if_t<Detail::is_generic_matcher_v<MatcherLHS>, Detail::MatchAnyOfGeneric<MatcherLHS, MatcherBase<ArgRHS>>>
operator || (MatcherLHS const& lhs, MatcherBase<ArgRHS> const& rhs) {
return { lhs, rhs };
}
template<typename ArgLHS, typename MatcherRHS>
std::enable_if_t<Detail::is_generic_matcher<MatcherRHS>::value, Detail::MatchAnyOfGeneric<MatcherBase<ArgLHS>, MatcherRHS>>
std::enable_if_t<Detail::is_generic_matcher_v<MatcherRHS>, Detail::MatchAnyOfGeneric<MatcherBase<ArgLHS>, MatcherRHS>>
operator || (MatcherBase<ArgLHS> const& lhs, MatcherRHS const& rhs) {
return { lhs, rhs };
}