Skip to content

Commit 0374a5c

Browse files
committed
Simplify decoding of function signature
This gets rid of the FunctionSignature and FunctionArgs helper classes by using a pointer-to-member-function and being able to get the arguments as a pack directly. As a result the function signature no longer has to be specified explicitly as a template parameter, it's instead determined by the compiler using template type deduction. This further simplifies the C++98 code to be ridiculously straightforward and the C++11 is simpler because it no longer has to be C++98 compatible.
1 parent b9b6fea commit 0374a5c

File tree

6 files changed

+28
-99
lines changed

6 files changed

+28
-99
lines changed

include/cucumber-cpp/internal/RegistrationMacros.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
class class_name : public parent_class { \
2626
public: \
2727
void body() { \
28-
return invokeBodyWithArgs<void args>(*this); \
28+
return invokeWithArgs(*this, &class_name::bodyWithArgs); \
2929
} \
3030
void bodyWithArgs args; \
3131
private: \

include/cucumber-cpp/internal/hook/HookRegistrar.hpp

Lines changed: 3 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,13 @@
44
#include "Tag.hpp"
55
#include "../Scenario.hpp"
66
#include "../step/StepManager.hpp"
7-
#include "../utils/FunctionSignature.hpp"
8-
#include "../utils/IndexSequence.hpp"
97

108
#include <boost/make_shared.hpp>
119
#include <boost/smart_ptr.hpp>
12-
#include <boost/static_assert.hpp>
1310
using boost::shared_ptr;
1411

1512
#include <list>
1613

17-
#ifdef BOOST_STATIC_ASSERT_MSG
18-
#define CUKE_STATIC_ASSERT(cond, msg) BOOST_STATIC_ASSERT_MSG(cond, msg)
19-
#else
20-
#define CUKE_STATIC_ASSERT(cond, msg) BOOST_STATIC_ASSERT(cond)
21-
#endif
22-
2314
namespace cucumber {
2415
namespace internal {
2516

@@ -37,20 +28,9 @@ class Hook {
3728
protected:
3829
bool tagsMatch(Scenario *scenario);
3930

40-
template <typename R, typename Derived>
41-
static R invokeBodyWithIndexedArgs(Derived& that, FunctionArgs<>, index_sequence<>) {
42-
return that.bodyWithArgs();
43-
}
44-
45-
template <typename Signature, typename Derived>
46-
static typename FunctionSignature<Signature>::result_type invokeBodyWithArgs(Derived& that) {
47-
typedef typename FunctionSignature<Signature>::result_type result_type;
48-
typedef typename FunctionSignature<Signature>::args_type args_type;
49-
CUKE_STATIC_ASSERT(args_type::size == 0, "Hooks don't support function arguments.");
50-
return invokeBodyWithIndexedArgs<result_type>(
51-
that,
52-
args_type(),
53-
make_index_sequence<args_type::size>());
31+
template <typename Derived, typename R>
32+
static R invokeWithArgs(Derived& that, R (Derived::* f)()) {
33+
return (that.*f)();
5434
}
5535
private:
5636
shared_ptr<TagExpression> tagExpression;

include/cucumber-cpp/internal/step/StepManager.hpp

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ using boost::shared_ptr;
1818
#endif
1919

2020
#include "../Table.hpp"
21-
#include "../utils/FunctionSignature.hpp"
2221
#include "../utils/IndexSequence.hpp"
2322
#include "../utils/Regex.hpp"
2423

@@ -135,29 +134,27 @@ class BasicStep {
135134

136135
#ifdef BOOST_NO_VARIADIC_TEMPLATES
137136
// Special case for zero arguments, only thing we bother to support on C++98
138-
template <typename R, typename Derived>
139-
static R invokeBodyWithIndexedArgs(Derived& that, FunctionArgs<>, index_sequence<>) {
140-
return that.bodyWithArgs();
137+
template <typename Derived, typename R>
138+
static R invokeWithArgs(Derived& that, R (Derived::* f)()) {
139+
return (that.*f)();
141140
}
142141
#else
143-
template <typename R, typename Derived, typename... Args, std::size_t... N>
144-
static R invokeBodyWithIndexedArgs(Derived& that, FunctionArgs<Args...>, index_sequence<N...>) {
145-
return that.bodyWithArgs(
142+
template <typename Derived, typename R, typename... Args, std::size_t... N>
143+
static R invokeWithIndexedArgs(Derived& that, R (Derived::* f)(Args...), index_sequence<N...>) {
144+
return (that.*f)(
146145
that.pArgs->template getInvokeArg<typename std::decay<Args>::type>(N)...
147146
);
148147
}
149-
#endif
150148

151-
template <typename Signature, typename Derived>
152-
static typename FunctionSignature<Signature>::result_type invokeBodyWithArgs(Derived& that) {
153-
typedef typename FunctionSignature<Signature>::result_type result_type;
154-
typedef typename FunctionSignature<Signature>::args_type args_type;
155-
that.currentArgIndex = args_type::size;
156-
return invokeBodyWithIndexedArgs<result_type>(
149+
template <typename Derived, typename R, typename... Args>
150+
static R invokeWithArgs(Derived& that, R (Derived::* f)(Args...)) {
151+
that.currentArgIndex = sizeof...(Args);
152+
return invokeWithIndexedArgs(
157153
that,
158-
args_type(),
159-
make_index_sequence<args_type::size>());
154+
f,
155+
index_sequence_for<Args...>{});
160156
}
157+
#endif
161158

162159
private:
163160
// FIXME: awful hack because of Boost::Test

include/cucumber-cpp/internal/utils/FunctionSignature.hpp

Lines changed: 0 additions & 44 deletions
This file was deleted.

include/cucumber-cpp/internal/utils/IndexSequence.hpp

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33

44
#include <boost/config.hpp>
55

6-
#if __cplusplus < 201402L && !(_MSC_VER > 1800) || defined(BOOST_NO_VARIADIC_TEMPLATES)
6+
#ifndef BOOST_NO_VARIADIC_TEMPLATES
7+
8+
#if __cplusplus < 201402L && !(_MSC_VER > 1800)
79
#include <cstddef> // for std::size_t
810
#else
911
#include <utility>
@@ -12,18 +14,7 @@
1214
namespace cucumber {
1315
namespace internal {
1416

15-
#ifdef BOOST_NO_VARIADIC_TEMPLATES
16-
// Special case for zero, only thing we bother to support on C++98
17-
template <typename = void>
18-
struct index_sequence {
19-
typedef index_sequence type;
20-
};
21-
22-
template <std::size_t N>
23-
struct make_index_sequence;
24-
25-
template <> struct make_index_sequence<0> : public index_sequence< > {};
26-
#elif __cplusplus < 201402L && !(_MSC_VER > 1800)
17+
#if __cplusplus < 201402L && !(_MSC_VER > 1800)
2718
// Based on https://stackoverflow.com/questions/17424477/implementation-c14-make-integer-sequence
2819

2920
template <std::size_t... N>
@@ -53,12 +44,17 @@ struct make_index_sequence : public concat_index_sequence<
5344

5445
template <> struct make_index_sequence<0> : public index_sequence< > {};
5546
template <> struct make_index_sequence<1> : public index_sequence<0> {};
47+
48+
template <typename... Ts>
49+
using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
5650
#else
5751
using ::std::index_sequence;
58-
using ::std::make_index_sequence;
52+
using ::std::index_sequence_for;
5953
#endif
6054

6155
}
6256
}
6357

58+
#endif /* !BOOST_NO_VARIADIC_TEMPLATES */
59+
6460
#endif /* CUKE_INDEXSEQ_HPP_ */

tests/unit/CukeCommandsTest.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ class CheckAllParametersWithFuncArgs : public CheckAllParameters {
102102
}
103103

104104
void body() {
105-
return invokeBodyWithArgs<void ARGS>(*this);
105+
return invokeWithArgs(*this, &CheckAllParametersWithFuncArgs::bodyWithArgs);
106106
}
107107
#undef ARGS
108108
};

0 commit comments

Comments
 (0)