|
5 | 5 | #include "cucumber_cpp/library/engine/FailureHandler.hpp" |
6 | 6 | #include "cucumber_cpp/library/engine/StringTo.hpp" |
7 | 7 | #include <cstddef> |
8 | | -#include <functional> |
9 | 8 | #include <gtest/gtest.h> |
10 | 9 |
|
11 | 10 | #undef GTEST_MESSAGE_AT_ |
|
21 | 20 |
|
22 | 21 | #define BODY_STRUCT CONCAT(BodyImpl, __LINE__) |
23 | 22 |
|
24 | | -#define BODY(matcher, type, targs, registration, base) \ |
25 | | - namespace \ |
26 | | - { \ |
27 | | - struct BODY_STRUCT : cucumber_cpp::library::Body \ |
28 | | - , base \ |
29 | | - { \ |
30 | | - /* Workaround namespaces in `base`. For example `base` = Foo::Bar. */ \ |
31 | | - /* Then the result would be Foo::Bar::Foo::Bar which is invalid */ \ |
32 | | - using myBase = base; \ |
33 | | - using myBase::myBase; \ |
34 | | - \ |
35 | | - void Execute(const std::variant<std::vector<std::string>, std::vector<std::any>>& args) override \ |
36 | | - { \ |
37 | | - cucumber_cpp::library::SetUpTearDownWrapper wrapper{ *this }; \ |
38 | | - EXPECT_NO_THROW(ExecuteWithArgs(args, std::function<void targs>{})); \ |
39 | | - } \ |
40 | | - \ |
41 | | - template<class... TArgs> \ |
42 | | - void ExecuteWithArgs(const std::variant<std::vector<std::string>, std::vector<std::any>>& args, std::function<void(TArgs...)> /*unused*/) \ |
43 | | - { \ |
44 | | - \ |
45 | | - if (std::holds_alternative<std::vector<std::string>>(args)) \ |
46 | | - ExecuteWithArgs<TArgs...>(std::get<std::vector<std::string>>(args), std::make_index_sequence<sizeof...(TArgs)>{}); \ |
47 | | - else \ |
48 | | - ExecuteWithArgs<TArgs...>(std::get<std::vector<std::any>>(args), std::make_index_sequence<sizeof...(TArgs)>{}); \ |
49 | | - } \ |
50 | | - \ |
51 | | - template<class... TArgs, std::size_t... I> \ |
52 | | - void ExecuteWithArgs(const std::vector<std::string>& args, std::index_sequence<I...> /*unused*/) \ |
53 | | - { \ |
54 | | - ExecuteWithArgs(cucumber_cpp::library::engine::StringTo<std::remove_cvref_t<TArgs>>(args[I])...); \ |
55 | | - } \ |
56 | | - \ |
57 | | - template<class... TArgs, std::size_t... I> \ |
58 | | - void ExecuteWithArgs(const std::vector<std::any>& args, std::index_sequence<I...> /*unused*/) \ |
59 | | - { \ |
60 | | - ExecuteWithArgs(std::any_cast<std::remove_cvref_t<TArgs>>(args[I])...); \ |
61 | | - } \ |
62 | | - \ |
63 | | - private: \ |
64 | | - void ExecuteWithArgs targs; \ |
65 | | - static const std::size_t ID; \ |
66 | | - }; \ |
67 | | - } \ |
68 | | - const std::size_t BODY_STRUCT::ID = registration<BODY_STRUCT>(matcher, type); \ |
| 23 | +#define BODY(matcher, type, targs, registration, base) \ |
| 24 | + namespace \ |
| 25 | + { \ |
| 26 | + struct BODY_STRUCT : cucumber_cpp::library::Body \ |
| 27 | + , base \ |
| 28 | + { \ |
| 29 | + /* Workaround namespaces in `base`. For example `base` = Foo::Bar. */ \ |
| 30 | + /* Then the result would be Foo::Bar::Foo::Bar which is invalid */ \ |
| 31 | + using myBase = base; \ |
| 32 | + using myBase::myBase; \ |
| 33 | + \ |
| 34 | + void Execute(const std::variant<std::vector<std::string>, std::vector<std::any>>& args) override \ |
| 35 | + { \ |
| 36 | + cucumber_cpp::library::SetUpTearDownWrapper wrapper{ *this }; \ |
| 37 | + EXPECT_NO_THROW(ExecuteWithArgs(args, static_cast<void(*) targs>(nullptr))); \ |
| 38 | + } \ |
| 39 | + \ |
| 40 | + template<class... TArgs> \ |
| 41 | + void ExecuteWithArgs(const std::variant<std::vector<std::string>, std::vector<std::any>>& args, void (* /* unused */)(TArgs...)) \ |
| 42 | + { \ |
| 43 | + if (std::holds_alternative<std::vector<std::string>>(args)) \ |
| 44 | + ExecuteWithArgs<TArgs...>(std::get<std::vector<std::string>>(args), std::make_index_sequence<sizeof...(TArgs)>{}); \ |
| 45 | + else \ |
| 46 | + ExecuteWithArgs<TArgs...>(std::get<std::vector<std::any>>(args), std::make_index_sequence<sizeof...(TArgs)>{}); \ |
| 47 | + } \ |
| 48 | + \ |
| 49 | + template<class... TArgs, std::size_t... I> \ |
| 50 | + void ExecuteWithArgs(const std::vector<std::string>& args, std::index_sequence<I...> /*unused*/) \ |
| 51 | + { \ |
| 52 | + ExecuteWithArgs(cucumber_cpp::library::engine::StringTo<std::remove_cvref_t<TArgs>>(args[I])...); \ |
| 53 | + } \ |
| 54 | + \ |
| 55 | + template<class... TArgs, std::size_t... I> \ |
| 56 | + void ExecuteWithArgs(const std::vector<std::any>& args, std::index_sequence<I...> /*unused*/) \ |
| 57 | + { \ |
| 58 | + ExecuteWithArgs(std::any_cast<std::remove_cvref_t<TArgs>>(args[I])...); \ |
| 59 | + } \ |
| 60 | + \ |
| 61 | + private: \ |
| 62 | + void ExecuteWithArgs targs; \ |
| 63 | + static const std::size_t ID; \ |
| 64 | + }; \ |
| 65 | + } \ |
| 66 | + const std::size_t BODY_STRUCT::ID = registration<BODY_STRUCT>(matcher, type); \ |
69 | 67 | void BODY_STRUCT::ExecuteWithArgs targs |
70 | 68 |
|
71 | 69 | #endif |
0 commit comments