Skip to content

Commit c24cc46

Browse files
committed
fix: update BODY macro to use static_cast for function pointer type in Execute method
1 parent 6f6670e commit c24cc46

File tree

1 file changed

+44
-46
lines changed

1 file changed

+44
-46
lines changed

cucumber_cpp/library/BodyMacro.hpp

Lines changed: 44 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
#include "cucumber_cpp/library/engine/FailureHandler.hpp"
66
#include "cucumber_cpp/library/engine/StringTo.hpp"
77
#include <cstddef>
8-
#include <functional>
98
#include <gtest/gtest.h>
109

1110
#undef GTEST_MESSAGE_AT_
@@ -21,51 +20,50 @@
2120

2221
#define BODY_STRUCT CONCAT(BodyImpl, __LINE__)
2322

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); \
6967
void BODY_STRUCT::ExecuteWithArgs targs
7068

7169
#endif

0 commit comments

Comments
 (0)