mirror of
				https://github.com/catchorg/Catch2.git
				synced 2025-10-31 20:27:11 +01:00 
			
		
		
		
	Use variable templates
This commit is contained in:
		| @@ -97,7 +97,7 @@ namespace Catch { | |||||||
|             } |             } | ||||||
|  |  | ||||||
|             // sets lambda to be used in fun *and* executes benchmark! |             // 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) { |                 Benchmark & operator=(Fun func) { | ||||||
|                 auto const* cfg = getCurrentContext().getConfig(); |                 auto const* cfg = getCurrentContext().getConfig(); | ||||||
|                 if (!cfg->skipBenchmarks()) { |                 if (!cfg->skipBenchmarks()) { | ||||||
|   | |||||||
| @@ -21,8 +21,7 @@ namespace Catch { | |||||||
|     namespace Benchmark { |     namespace Benchmark { | ||||||
|         namespace Detail { |         namespace Detail { | ||||||
|             template <typename T, typename U> |             template <typename T, typename U> | ||||||
|             struct is_related |             static constexpr bool is_related_v = std::is_same<std::decay_t<T>, std::decay_t<U>>::value; | ||||||
|                 : std::is_same<std::decay_t<T>, std::decay_t<U>> {}; |  | ||||||
|  |  | ||||||
|             /// We need to reinvent std::function because every piece of code that might add overhead |             /// 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 |             /// in a measurement context needs to have consistent performance characteristics so that we | ||||||
| @@ -63,7 +62,7 @@ namespace Catch { | |||||||
|                 BenchmarkFunction(); |                 BenchmarkFunction(); | ||||||
|  |  | ||||||
|                 template <typename Fun, |                 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) |                     BenchmarkFunction(Fun&& fun) | ||||||
|                     : f(new model<std::decay_t<Fun>>(CATCH_FORWARD(fun))) {} |                     : f(new model<std::decay_t<Fun>>(CATCH_FORWARD(fun))) {} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -64,18 +64,14 @@ namespace Catch { | |||||||
|           return rawMemoryToString( &object, sizeof(object) ); |           return rawMemoryToString( &object, sizeof(object) ); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         template<typename T> |         template<typename T,typename = void> | ||||||
|         class IsStreamInsertable { |         static constexpr bool IsStreamInsertable_v = false; | ||||||
|             template<typename Stream, typename U> |  | ||||||
|             static auto test(int) |  | ||||||
|                 -> decltype(std::declval<Stream&>() << std::declval<U>(), std::true_type()); |  | ||||||
|  |  | ||||||
|             template<typename, typename> |         template <typename T> | ||||||
|             static auto test(...)->std::false_type; |         static constexpr bool IsStreamInsertable_v< | ||||||
|  |             T, | ||||||
|         public: |             decltype( void( std::declval<std::ostream&>() << std::declval<T>() ) )> = | ||||||
|             static const bool value = decltype(test<std::ostream, const T&>(0))::value; |             true; | ||||||
|         }; |  | ||||||
|  |  | ||||||
|         template<typename E> |         template<typename E> | ||||||
|         std::string convertUnknownEnumToString( E e ); |         std::string convertUnknownEnumToString( E e ); | ||||||
| @@ -120,7 +116,7 @@ namespace Catch { | |||||||
|     struct StringMaker { |     struct StringMaker { | ||||||
|         template <typename Fake = T> |         template <typename Fake = T> | ||||||
|         static |         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) { |             convert(const Fake& value) { | ||||||
|                 ReusableStringStream rss; |                 ReusableStringStream rss; | ||||||
|                 // NB: call using the function-like syntax to avoid ambiguity with |                 // NB: call using the function-like syntax to avoid ambiguity with | ||||||
| @@ -131,7 +127,7 @@ namespace Catch { | |||||||
|  |  | ||||||
|         template <typename Fake = T> |         template <typename Fake = T> | ||||||
|         static |         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 ) { |             convert( const Fake& value ) { | ||||||
| #if !defined(CATCH_CONFIG_FALLBACK_STRINGIFIER) | #if !defined(CATCH_CONFIG_FALLBACK_STRINGIFIER) | ||||||
|             return Detail::convertUnstreamable(value); |             return Detail::convertUnstreamable(value); | ||||||
| @@ -523,7 +519,7 @@ namespace Catch { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     template<typename R> |     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 ) { |         static std::string convert( R const& range ) { | ||||||
|             return rangeToString( range ); |             return rangeToString( range ); | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -79,7 +79,7 @@ namespace Catch { | |||||||
|         //! Creates a matcher that accepts ranges/containers with specific size |         //! Creates a matcher that accepts ranges/containers with specific size | ||||||
|         HasSizeMatcher SizeIs(std::size_t sz); |         HasSizeMatcher SizeIs(std::size_t sz); | ||||||
|         template <typename Matcher> |         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) { |         SizeMatchesMatcher<Matcher>> SizeIs(Matcher&& m) { | ||||||
|             return SizeMatchesMatcher<Matcher>{CATCH_FORWARD(m)}; |             return SizeMatchesMatcher<Matcher>{CATCH_FORWARD(m)}; | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -73,14 +73,14 @@ namespace Catch { | |||||||
|          * Uses `std::equal_to` to do the comparison |          * Uses `std::equal_to` to do the comparison | ||||||
|          */ |          */ | ||||||
|         template <typename T> |         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) { |         ContainsElementMatcher<T, std::equal_to<>>> Contains(T&& elem) { | ||||||
|             return { CATCH_FORWARD(elem), std::equal_to<>{} }; |             return { CATCH_FORWARD(elem), std::equal_to<>{} }; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         //! Creates a matcher that checks whether a range contains element matching a matcher |         //! Creates a matcher that checks whether a range contains element matching a matcher | ||||||
|         template <typename 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) { |         ContainsMatcherMatcher<Matcher>> Contains(Matcher&& matcher) { | ||||||
|             return { CATCH_FORWARD(matcher) }; |             return { CATCH_FORWARD(matcher) }; | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -58,19 +58,19 @@ namespace Matchers { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         template<typename T> |         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, |             Catch::Matchers::MatcherGenericBase, | ||||||
|             std::remove_cv_t<std::remove_reference_t<T>> |             std::remove_cv_t<std::remove_reference_t<T>> | ||||||
|         >; |         >::value; | ||||||
|  |  | ||||||
|         template<typename... Ts> |         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> |         template<typename T> | ||||||
|         using is_matcher = std::is_base_of< |         static constexpr bool is_matcher_v = std::is_base_of< | ||||||
|             Catch::Matchers::MatcherUntypedBase, |             Catch::Matchers::MatcherUntypedBase, | ||||||
|             std::remove_cv_t<std::remove_reference_t<T>> |             std::remove_cv_t<std::remove_reference_t<T>> | ||||||
|         >; |         >::value; | ||||||
|  |  | ||||||
|  |  | ||||||
|         template<std::size_t N, typename Arg> |         template<std::size_t N, typename Arg> | ||||||
| @@ -143,7 +143,7 @@ namespace Matchers { | |||||||
|  |  | ||||||
|             //! Avoids type nesting for `GenericAllOf && some matcher` case |             //! Avoids type nesting for `GenericAllOf && some matcher` case | ||||||
|             template<typename MatcherRHS> |             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..., MatcherRHS>> operator && ( | ||||||
|                     MatchAllOfGeneric<MatcherTs...>&& lhs, |                     MatchAllOfGeneric<MatcherTs...>&& lhs, | ||||||
|                     MatcherRHS const& rhs) { |                     MatcherRHS const& rhs) { | ||||||
| @@ -152,7 +152,7 @@ namespace Matchers { | |||||||
|  |  | ||||||
|             //! Avoids type nesting for `some matcher && GenericAllOf` case |             //! Avoids type nesting for `some matcher && GenericAllOf` case | ||||||
|             template<typename MatcherLHS> |             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 && ( |             MatchAllOfGeneric<MatcherLHS, MatcherTs...>> operator && ( | ||||||
|                     MatcherLHS const& lhs, |                     MatcherLHS const& lhs, | ||||||
|                     MatchAllOfGeneric<MatcherTs...>&& rhs) { |                     MatchAllOfGeneric<MatcherTs...>&& rhs) { | ||||||
| @@ -197,7 +197,7 @@ namespace Matchers { | |||||||
|  |  | ||||||
|             //! Avoids type nesting for `GenericAnyOf || some matcher` case |             //! Avoids type nesting for `GenericAnyOf || some matcher` case | ||||||
|             template<typename MatcherRHS> |             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..., MatcherRHS>> operator || ( | ||||||
|                     MatchAnyOfGeneric<MatcherTs...>&& lhs, |                     MatchAnyOfGeneric<MatcherTs...>&& lhs, | ||||||
|                     MatcherRHS const& rhs) { |                     MatcherRHS const& rhs) { | ||||||
| @@ -206,7 +206,7 @@ namespace Matchers { | |||||||
|  |  | ||||||
|             //! Avoids type nesting for `some matcher || GenericAnyOf` case |             //! Avoids type nesting for `some matcher || GenericAnyOf` case | ||||||
|             template<typename MatcherLHS> |             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 || ( |             MatchAnyOfGeneric<MatcherLHS, MatcherTs...>> operator || ( | ||||||
|                 MatcherLHS const& lhs, |                 MatcherLHS const& lhs, | ||||||
|                 MatchAnyOfGeneric<MatcherTs...>&& rhs) { |                 MatchAnyOfGeneric<MatcherTs...>&& rhs) { | ||||||
| @@ -246,20 +246,20 @@ namespace Matchers { | |||||||
|  |  | ||||||
|     // compose only generic matchers |     // compose only generic matchers | ||||||
|     template<typename MatcherLHS, typename MatcherRHS> |     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) { |         operator && (MatcherLHS const& lhs, MatcherRHS const& rhs) { | ||||||
|         return { lhs, rhs }; |         return { lhs, rhs }; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     template<typename MatcherLHS, typename MatcherRHS> |     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) { |         operator || (MatcherLHS const& lhs, MatcherRHS const& rhs) { | ||||||
|         return { lhs, rhs }; |         return { lhs, rhs }; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     //! Wrap provided generic matcher in generic negator |     //! Wrap provided generic matcher in generic negator | ||||||
|     template<typename MatcherT> |     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) { |         operator ! (MatcherT const& matcher) { | ||||||
|         return Detail::MatchNotOfGeneric<MatcherT>{matcher}; |         return Detail::MatchNotOfGeneric<MatcherT>{matcher}; | ||||||
|     } |     } | ||||||
| @@ -267,25 +267,25 @@ namespace Matchers { | |||||||
|  |  | ||||||
|     // compose mixed generic and non-generic matchers |     // compose mixed generic and non-generic matchers | ||||||
|     template<typename MatcherLHS, typename ArgRHS> |     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) { |         operator && (MatcherLHS const& lhs, MatcherBase<ArgRHS> const& rhs) { | ||||||
|         return { lhs, rhs }; |         return { lhs, rhs }; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     template<typename ArgLHS, typename MatcherRHS> |     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) { |         operator && (MatcherBase<ArgLHS> const& lhs, MatcherRHS const& rhs) { | ||||||
|         return { lhs, rhs }; |         return { lhs, rhs }; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     template<typename MatcherLHS, typename ArgRHS> |     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) { |         operator || (MatcherLHS const& lhs, MatcherBase<ArgRHS> const& rhs) { | ||||||
|         return { lhs, rhs }; |         return { lhs, rhs }; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     template<typename ArgLHS, typename MatcherRHS> |     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) { |         operator || (MatcherBase<ArgLHS> const& lhs, MatcherRHS const& rhs) { | ||||||
|         return { lhs, rhs }; |         return { lhs, rhs }; | ||||||
|     } |     } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 ZXShady
					ZXShady