From a8f0253753ef1fa996a91b36c0b84e27cf662dfb Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Sun, 20 Apr 2025 14:36:30 +0200 Subject: [PATCH] Take modifiers as tuple --- include/turtle/detail/mock_impl.hpp | 19 ++++++++++--------- include/turtle/detail/pp_foreach.hpp | 11 ++++++++--- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/include/turtle/detail/mock_impl.hpp b/include/turtle/detail/mock_impl.hpp index cbf5976..bfa82a7 100644 --- a/include/turtle/detail/mock_impl.hpp +++ b/include/turtle/detail/mock_impl.hpp @@ -77,20 +77,21 @@ namespace mock { namespace detail { BOOST_PP_TUPLE_ELEM(3, M_n_S_t), \ qualifier) -/// MOCK_METHOD_EXT_IMPL( name, arity, signature, identifier, qualifiers... ) -#define MOCK_METHOD_EXT_IMPL(name, arity, signature, identifier, ...) \ +#define MOCK_METHOD_EXT_IMPL(name, arity, signature, identifier, qualifiers) \ static_assert(arity == mock::detail::function_arity_t::value, "Arity mismatch"); \ - MOCK_PP_FOR_EACH(MOCK_METHOD_ITER, (name, arity, signature, identifier), __VA_ARGS__) \ + MOCK_PP_TUPLE_FOR_EACH(MOCK_METHOD_ITER, (name, arity, signature, identifier), qualifiers) \ MOCK_METHOD_HELPER(signature, identifier) -/// MOCK_METHOD_EXT( name, arity, signature, identifier [ , qualifiers...] ) +/// MOCK_METHOD_EXT( name, arity, signature, identifier [ , qualifiers] ) /// If qualifiers is not given, defaults to (const, ), i.e. const and non-const -#define MOCK_METHOD_EXT(...) \ - MOCK_METHOD_EXT_IMPL \ - BOOST_PP_IF(BOOST_PP_LESS_EQUAL(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), 4), (__VA_ARGS__, const, ), (__VA_ARGS__)) +#define MOCK_METHOD_EXT(name, arity, signature, ...) \ + MOCK_METHOD_EXT_IMPL \ + BOOST_PP_IF(BOOST_PP_LESS_EQUAL(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), 1), \ + (name, arity, signature, __VA_ARGS__, (const, )), \ + (name, arity, signature, __VA_ARGS__)) -#define MOCK_CONST_METHOD_EXT(M, n, S, t) MOCK_METHOD_EXT(M, n, S, t, const) -#define MOCK_NON_CONST_METHOD_EXT(M, n, S, t) MOCK_METHOD_EXT(M, n, S, t, ) +#define MOCK_CONST_METHOD_EXT(M, n, S, t) MOCK_METHOD_EXT(M, n, S, t, (const)) +#define MOCK_NON_CONST_METHOD_EXT(M, n, S, t) MOCK_METHOD_EXT(M, n, S, t, ()) #define MOCK_FUNCTION_HELPER(signature, identifier, prefix) \ prefix mock::detail::function& identifier##_mock(mock::detail::context& context, \ diff --git a/include/turtle/detail/pp_foreach.hpp b/include/turtle/detail/pp_foreach.hpp index e5579dc..c10e0dd 100644 --- a/include/turtle/detail/pp_foreach.hpp +++ b/include/turtle/detail/pp_foreach.hpp @@ -9,12 +9,17 @@ #ifndef MOCK_PP_FOREACH_HPP_INCLUDED #define MOCK_PP_FOREACH_HPP_INCLUDED -#include +#include +#include #include +#include -/// Expand to `macro(data, elem)` for each element passed, similar to BOOST_PP_*_FOR_EACH -/// It supports empty arguments, +/// Expand to `macro(data, elem)` for each element in the tuple. +/// Same as BOOST_PP_TUPLE_FOR_EACH but supports empty elements, /// without causing a C4003 "not enough arguments for function-like macro invocation" warning on MSVC +#define MOCK_PP_TUPLE_FOR_EACH(macro, data, tuple) MOCK_PP_FOR_EACH(macro, data, BOOST_PP_REM tuple) + +/// Expand to `macro(data, elem)` for each variadic element passed #if BOOST_PP_VARIADICS_MSVC # define MOCK_PP_FOR_EACH(macro, data, ...) \ BOOST_PP_CAT(BOOST_PP_OVERLOAD(MOCK_PP_INVOKE_, __VA_ARGS__)(macro, data, __VA_ARGS__), BOOST_PP_EMPTY())