Really fix use of std::result_of when invoke_result is available

Closes #1934
This commit is contained in:
Martin Hořeňovský 2020-05-21 21:39:19 +02:00
parent ddc9f4c61d
commit 77dc8cfc45
No known key found for this signature in database
GPG Key ID: DE48307B8B0D381A
5 changed files with 15 additions and 15 deletions

View File

@ -46,15 +46,15 @@ namespace Catch {
// invoke and not return void :( // invoke and not return void :(
template <typename Fun, typename... Args> template <typename Fun, typename... Args>
CompleteType_t<FunctionReturnType<Fun(Args...)>> complete_invoke(Fun&& fun, Args&&... args) { CompleteType_t<FunctionReturnType<Fun, Args...>> complete_invoke(Fun&& fun, Args&&... args) {
return CompleteInvoker<FunctionReturnType<Fun(Args...)>>::invoke(std::forward<Fun>(fun), std::forward<Args>(args)...); return CompleteInvoker<FunctionReturnType<Fun, Args...>>::invoke(std::forward<Fun>(fun), std::forward<Args>(args)...);
} }
const std::string benchmarkErrorMsg = "a benchmark failed to run successfully"; const std::string benchmarkErrorMsg = "a benchmark failed to run successfully";
} // namespace Detail } // namespace Detail
template <typename Fun> template <typename Fun>
Detail::CompleteType_t<FunctionReturnType<Fun()>> user_code(Fun&& fun) { Detail::CompleteType_t<FunctionReturnType<Fun>> user_code(Fun&& fun) {
CATCH_TRY{ CATCH_TRY{
return Detail::complete_invoke(std::forward<Fun>(fun)); return Detail::complete_invoke(std::forward<Fun>(fun));
} CATCH_CATCH_ALL{ } CATCH_CATCH_ALL{

View File

@ -21,7 +21,7 @@ namespace Catch {
namespace Benchmark { namespace Benchmark {
namespace Detail { namespace Detail {
template <typename Clock, typename Fun, typename... Args> template <typename Clock, typename Fun, typename... Args>
TimingOf<Clock, Fun(Args...)> measure(Fun&& fun, Args&&... args) { TimingOf<Clock, Fun, Args...> measure(Fun&& fun, Args&&... args) {
auto start = Clock::now(); auto start = Clock::now();
auto&& r = Detail::complete_invoke(fun, std::forward<Args>(args)...); auto&& r = Detail::complete_invoke(fun, std::forward<Args>(args)...);
auto end = Clock::now(); auto end = Clock::now();

View File

@ -25,11 +25,11 @@ namespace Catch {
namespace Benchmark { namespace Benchmark {
namespace Detail { namespace Detail {
template <typename Clock, typename Fun> template <typename Clock, typename Fun>
TimingOf<Clock, Fun(int)> measure_one(Fun&& fun, int iters, std::false_type) { TimingOf<Clock, Fun, int> measure_one(Fun&& fun, int iters, std::false_type) {
return Detail::measure<Clock>(fun, iters); return Detail::measure<Clock>(fun, iters);
} }
template <typename Clock, typename Fun> template <typename Clock, typename Fun>
TimingOf<Clock, Fun(Chronometer)> measure_one(Fun&& fun, int iters, std::true_type) { TimingOf<Clock, Fun, Chronometer> measure_one(Fun&& fun, int iters, std::true_type) {
Detail::ChronometerModel<Clock> meter; Detail::ChronometerModel<Clock> meter;
auto&& result = Detail::complete_invoke(fun, Chronometer(meter, iters)); auto&& result = Detail::complete_invoke(fun, Chronometer(meter, iters));
@ -46,7 +46,7 @@ namespace Catch {
}; };
template <typename Clock, typename Fun> template <typename Clock, typename Fun>
TimingOf<Clock, Fun(run_for_at_least_argument_t<Clock, Fun>)> run_for_at_least(ClockDuration<Clock> how_long, int seed, Fun&& fun) { TimingOf<Clock, Fun, run_for_at_least_argument_t<Clock, Fun>> run_for_at_least(ClockDuration<Clock> how_long, int seed, Fun&& fun) {
auto iters = seed; auto iters = seed;
while (iters < (1 << 30)) { while (iters < (1 << 30)) {
auto&& Timing = measure_one<Clock>(fun, iters, is_callable<Fun(Chronometer)>()); auto&& Timing = measure_one<Clock>(fun, iters, is_callable<Fun(Chronometer)>());

View File

@ -25,8 +25,8 @@ namespace Catch {
Result result; Result result;
int iterations; int iterations;
}; };
template <typename Clock, typename Sig> template <typename Clock, typename Func, typename... Args>
using TimingOf = Timing<ClockDuration<Clock>, Detail::CompleteType_t<FunctionReturnType<Sig>>>; using TimingOf = Timing<ClockDuration<Clock>, Detail::CompleteType_t<FunctionReturnType<Func, Args...>>>;
} // namespace Benchmark } // namespace Benchmark
} // namespace Catch } // namespace Catch

View File

@ -32,13 +32,13 @@ namespace Catch {
#if defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703 #if defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703
// std::result_of is deprecated in C++17 and removed in C++20. Hence, it is // std::result_of is deprecated in C++17 and removed in C++20. Hence, it is
// replaced with std::invoke_result here. Also *_t format is preferred over // replaced with std::invoke_result here.
// typename *::type format. template <typename Func, typename... U>
template <typename Func, typename U> using FunctionReturnType = std::remove_reference_t<std::remove_cv_t<std::invoke_result_t<Func, U...>>>;
using FunctionReturnType = std::remove_reference_t<std::remove_cv_t<std::invoke_result_t<Func, U>>>;
#else #else
template <typename Func, typename U> // Keep ::type here because we still support C++11
using FunctionReturnType = typename std::remove_reference<typename std::remove_cv<typename std::result_of<Func(U)>::type>::type>::type; template <typename Func, typename... U>
using FunctionReturnType = typename std::remove_reference<typename std::remove_cv<typename std::result_of<Func(U...)>::type>::type>::type;
#endif #endif
} // namespace Catch } // namespace Catch