|
2 | 2 | #define CUCUMBER_CPP_BODYMACRO_HPP |
3 | 3 |
|
4 | 4 | #include "cucumber_cpp/library/Body.hpp" |
| 5 | +#include "cucumber_cpp/library/cucumber_expression/ParameterRegistry.hpp" |
5 | 6 | #include "cucumber_cpp/library/engine/StringTo.hpp" |
6 | 7 | #include <cstddef> |
7 | 8 | #include <gtest/gtest.h> |
|
14 | 15 |
|
15 | 16 | #define BODY_STRUCT CONCAT(BodyImpl, __LINE__) |
16 | 17 |
|
17 | | -#define BODY(matcher, type, targs, registration, base) \ |
18 | | - namespace \ |
19 | | - { \ |
20 | | - struct BODY_STRUCT : cucumber_cpp::library::Body \ |
21 | | - , base \ |
22 | | - { \ |
23 | | - /* Workaround namespaces in `base`. For example `base` = Foo::Bar. */ \ |
24 | | - /* Then the result would be Foo::Bar::Foo::Bar which is invalid */ \ |
25 | | - using myBase = base; \ |
26 | | - using myBase::myBase; \ |
27 | | - \ |
28 | | - void Execute(const std::variant<std::vector<std::string>, std::vector<std::any>>& args) override \ |
29 | | - { \ |
30 | | - cucumber_cpp::library::SetUpTearDownWrapper wrapper{ *this }; \ |
31 | | - /* ASSERT_NO_THROW(ExecuteWithArgs(args, static_cast<void(*) targs>(nullptr))); */ \ |
32 | | - ExecuteWithArgs(args, static_cast<void(*) targs>(nullptr)); \ |
33 | | - } \ |
34 | | - \ |
35 | | - template<class... TArgs> \ |
36 | | - void ExecuteWithArgs(const std::variant<std::vector<std::string>, std::vector<std::any>>& args, void (* /* unused */)(TArgs...)) \ |
37 | | - { \ |
38 | | - if (std::holds_alternative<std::vector<std::string>>(args)) \ |
39 | | - ExecuteWithArgs<TArgs...>(std::get<std::vector<std::string>>(args), std::make_index_sequence<sizeof...(TArgs)>{}); \ |
40 | | - else \ |
41 | | - ExecuteWithArgs<TArgs...>(std::get<std::vector<std::any>>(args), std::make_index_sequence<sizeof...(TArgs)>{}); \ |
42 | | - } \ |
43 | | - \ |
44 | | - template<class... TArgs, std::size_t... I> \ |
45 | | - void ExecuteWithArgs(const std::vector<std::string>& args, std::index_sequence<I...> /*unused*/) \ |
46 | | - { \ |
47 | | - ExecuteWithArgs(cucumber_cpp::library::engine::StringTo<std::remove_cvref_t<TArgs>>(args[I])...); \ |
48 | | - } \ |
49 | | - \ |
50 | | - template<class... TArgs, std::size_t... I> \ |
51 | | - void ExecuteWithArgs(const std::vector<std::any>& args, std::index_sequence<I...> /*unused*/) \ |
52 | | - { \ |
53 | | - ExecuteWithArgs(std::any_cast<std::remove_cvref_t<TArgs>>(args[I])...); \ |
54 | | - } \ |
55 | | - \ |
56 | | - private: \ |
57 | | - void ExecuteWithArgs targs; \ |
58 | | - static const std::size_t ID; \ |
59 | | - }; \ |
60 | | - } \ |
61 | | - const std::size_t BODY_STRUCT::ID = registration<BODY_STRUCT>(matcher, type); \ |
| 18 | +#define BODY(matcher, type, targs, registration, base) \ |
| 19 | + namespace \ |
| 20 | + { \ |
| 21 | + struct BODY_STRUCT : cucumber_cpp::library::Body \ |
| 22 | + , base \ |
| 23 | + { \ |
| 24 | + /* Workaround namespaces in `base`. For example `base` = Foo::Bar. */ \ |
| 25 | + /* Then the result would be Foo::Bar::Foo::Bar which is invalid */ \ |
| 26 | + using myBase = base; \ |
| 27 | + using myBase::myBase; \ |
| 28 | + \ |
| 29 | + void Execute(const cucumber::messages::step_match_arguments_list& args) override \ |
| 30 | + { \ |
| 31 | + cucumber_cpp::library::SetUpTearDownWrapper wrapper{ *this }; \ |
| 32 | + /* ASSERT_NO_THROW(ExecuteWithArgs(args, static_cast<void(*) targs>(nullptr))); */ \ |
| 33 | + ExecuteWithArgs(args, static_cast<void(*) targs>(nullptr)); \ |
| 34 | + } \ |
| 35 | + \ |
| 36 | + template<class... TArgs> \ |
| 37 | + void ExecuteWithArgs(const cucumber::messages::step_match_arguments_list& args, void (* /* unused */)(TArgs...)) \ |
| 38 | + { \ |
| 39 | + ExecuteWithArgs<TArgs...>(args, std::make_index_sequence<sizeof...(TArgs)>{}); \ |
| 40 | + } \ |
| 41 | + \ |
| 42 | + template<class... TArgs, std::size_t... I> \ |
| 43 | + void ExecuteWithArgs(const cucumber::messages::step_match_arguments_list& args, std::index_sequence<I...> /*unused*/) \ |
| 44 | + { \ |
| 45 | + ExecuteWithArgs(cucumber_cpp::library::cucumber_expression::ConverterTypeMap<std::remove_cvref_t<TArgs>>::Instance().at(args.step_match_arguments[I].parameter_type_name.value())(args.step_match_arguments[I].group)...); \ |
| 46 | + } \ |
| 47 | + \ |
| 48 | + private: \ |
| 49 | + void ExecuteWithArgs targs; \ |
| 50 | + static const std::size_t ID; \ |
| 51 | + }; \ |
| 52 | + } \ |
| 53 | + const std::size_t BODY_STRUCT::ID = registration<BODY_STRUCT>(matcher, type); \ |
62 | 54 | void BODY_STRUCT::ExecuteWithArgs targs |
63 | 55 |
|
64 | 56 | #endif |
0 commit comments