• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Created by Joachim on 16/04/2019.
3  *  Adapted from donated nonius code.
4  *
5  *  Distributed under the Boost Software License, Version 1.0. (See accompanying
6  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7  */
8 
9 // Invoke with a special case for void
10 
11 #ifndef TWOBLUECUBES_CATCH_DETAIL_COMPLETE_INVOKE_HPP_INCLUDED
12 #define TWOBLUECUBES_CATCH_DETAIL_COMPLETE_INVOKE_HPP_INCLUDED
13 
14 #include "../../catch_enforce.h"
15 
16 #include <type_traits>
17 #include <utility>
18 
19 namespace Catch {
20     namespace Benchmark {
21         namespace Detail {
22             template <typename T>
23             struct CompleteType { using type = T; };
24             template <>
25             struct CompleteType<void> { struct type {}; };
26 
27             template <typename T>
28             using CompleteType_t = typename CompleteType<T>::type;
29 
30             template <typename Result>
31             struct CompleteInvoker {
32                 template <typename Fun, typename... Args>
invokeCatch::Benchmark::Detail::CompleteInvoker33                 static Result invoke(Fun&& fun, Args&&... args) {
34                     return std::forward<Fun>(fun)(std::forward<Args>(args)...);
35                 }
36             };
37             template <>
38             struct CompleteInvoker<void> {
39                 template <typename Fun, typename... Args>
invokeCatch::Benchmark::Detail::CompleteInvoker40                 static CompleteType_t<void> invoke(Fun&& fun, Args&&... args) {
41                     std::forward<Fun>(fun)(std::forward<Args>(args)...);
42                     return {};
43                 }
44             };
45             template <typename Sig>
46             using ResultOf_t = typename std::result_of<Sig>::type;
47 
48             // invoke and not return void :(
49             template <typename Fun, typename... Args>
complete_invoke(Fun && fun,Args &&...args)50             CompleteType_t<ResultOf_t<Fun(Args...)>> complete_invoke(Fun&& fun, Args&&... args) {
51                 return CompleteInvoker<ResultOf_t<Fun(Args...)>>::invoke(std::forward<Fun>(fun), std::forward<Args>(args)...);
52             }
53 
54             const std::string benchmarkErrorMsg = "a benchmark failed to run successfully";
55         } // namespace Detail
56 
57         template <typename Fun>
user_code(Fun && fun)58         Detail::CompleteType_t<Detail::ResultOf_t<Fun()>> user_code(Fun&& fun) {
59             CATCH_TRY{
60                 return Detail::complete_invoke(std::forward<Fun>(fun));
61             } CATCH_CATCH_ALL{
62                 getResultCapture().benchmarkFailed(translateActiveException());
63                 CATCH_RUNTIME_ERROR(Detail::benchmarkErrorMsg);
64             }
65         }
66     } // namespace Benchmark
67 } // namespace Catch
68 
69 #endif // TWOBLUECUBES_CATCH_DETAIL_COMPLETE_INVOKE_HPP_INCLUDED
70