diff --git a/include/turtle/constraint.hpp b/include/turtle/constraint.hpp index 8dddb22..2eb7cf5 100644 --- a/include/turtle/constraint.hpp +++ b/include/turtle/constraint.hpp @@ -1,6 +1,7 @@ // http://turtle.sourceforge.net // // Copyright Mathieu Champlon 2008 +// Copyright 2020-2025 Alexander Grund // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at @@ -17,6 +18,7 @@ #include #include #include +#include #include #include #include diff --git a/include/turtle/detail/mock_impl.hpp b/include/turtle/detail/mock_impl.hpp index 211e81c..59fe4e0 100644 --- a/include/turtle/detail/mock_impl.hpp +++ b/include/turtle/detail/mock_impl.hpp @@ -1,6 +1,7 @@ // http://turtle.sourceforge.net // // Copyright Mathieu Champlon 2008 +// Copyright 2022-2025 Alexander Grund // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at @@ -14,7 +15,7 @@ #include "signature.hpp" #include "signature_traits.hpp" #include "type_name.hpp" -#include +#include #include #include @@ -49,47 +50,47 @@ namespace mock { namespace detail { return t##_mock_; \ } -#define MOCK_PARAM(S) mock::detail::parameter_t < S -#define MOCK_DECL_PARAM(z, n, d) BOOST_PP_COMMA_IF(n) d, n > p##n -#define MOCK_DECL_PARAMS(n, S) BOOST_PP_REPEAT(n, MOCK_DECL_PARAM, MOCK_PARAM(S)) -#define MOCK_DECL(M, n, S, c) mock::detail::result_type_t M(MOCK_DECL_PARAMS(n, S)) c +#define MOCK_PARAM(S, n) mock::detail::parameter_t -#define MOCK_FORWARD_PARAM(z, n, d) BOOST_PP_COMMA_IF(n) d, n >> (p##n) -#define MOCK_FORWARD_PARAMS(n, S) BOOST_PP_REPEAT(n, MOCK_FORWARD_PARAM, std::forward < MOCK_PARAM(S)) -#define MOCK_METHOD_AUX(M, n, S, t, c) \ - static_assert(n == mock::detail::function_arity_t::value, "Arity mismatch"); \ - MOCK_DECL(M, n, S, c) { return MOCK_ANONYMOUS_HELPER(t)(MOCK_FORWARD_PARAMS(n, S)); } +#define MOCK_DECL_PARAM(z, n, S) MOCK_PARAM(S, n) p##n +#define MOCK_DECL_PARAMS(n, S) BOOST_PP_ENUM(n, MOCK_DECL_PARAM, S) +#define MOCK_DECL(name, arity, signature, qualifier) \ + mock::detail::result_type_t name(MOCK_DECL_PARAMS(arity, signature)) qualifier -#define MOCK_METHOD_EXT(M, n, S, t) \ - MOCK_METHOD_AUX(M, n, S, t, ) \ - MOCK_METHOD_AUX(M, n, S, t, const) \ - MOCK_METHOD_HELPER(S, t) -#define MOCK_CONST_METHOD_EXT(M, n, S, t) \ - MOCK_METHOD_AUX(M, n, S, t, const) \ - MOCK_METHOD_HELPER(S, t) -#define MOCK_NON_CONST_METHOD_EXT(M, n, S, t) \ - MOCK_METHOD_AUX(M, n, S, t, ) \ - MOCK_METHOD_HELPER(S, t) - -#define MOCK_FUNCTION_HELPER(S, t, s) \ - s mock::detail::function& t##_mock(mock::detail::context& context, boost::unit_test::const_string instance) \ - { \ - static mock::detail::function f; \ - return f(context, instance); \ +#define MOCK_FORWARD_PARAM(z, n, S) std::forward(p##n) +#define MOCK_FORWARD_PARAMS(n, S) BOOST_PP_ENUM(n, MOCK_FORWARD_PARAM, S) +#define MOCK_METHOD_AUX(name, arity, signature, identifier, qualifier) \ + MOCK_DECL(name, arity, signature, qualifier) \ + { \ + return MOCK_ANONYMOUS_HELPER(identifier)(MOCK_FORWARD_PARAMS(arity, signature)); \ } -#define MOCK_CONSTRUCTOR_AUX(T, n, A, t) \ - T(MOCK_DECL_PARAMS(n, void A)) { MOCK_HELPER(t)(MOCK_FORWARD_PARAMS(n, void A)); } \ - MOCK_FUNCTION_HELPER(void A, t, static) +#define MOCK_METHOD_EXT(name, arity, signature, identifier) \ + MOCK_METHOD_AUX(name, arity, signature, identifier, ) \ + MOCK_METHOD_AUX(name, arity, signature, identifier, const) \ + MOCK_METHOD_HELPER(signature, identifier) +#define MOCK_CONST_METHOD_EXT(name, arity, signature, identifier) \ + MOCK_METHOD_AUX(name, arity, signature, identifier, const) \ + MOCK_METHOD_HELPER(signature, identifier) +#define MOCK_NON_CONST_METHOD_EXT(name, arity, signature, identifier) \ + MOCK_METHOD_AUX(name, arity, signature, identifier, ) \ + MOCK_METHOD_HELPER(signature, identifier) -#define MOCK_FUNCTION_AUX(F, n, S, t, s) \ - MOCK_FUNCTION_HELPER(S, t, s) \ - static_assert(n == mock::detail::function_arity_t::value, "Arity mismatch"); \ - s MOCK_DECL(F, n, S, ) { return MOCK_HELPER(t)(MOCK_FORWARD_PARAMS(n, S)); } +#define MOCK_FUNCTION_HELPER(signature, identifier, prefix) \ + prefix mock::detail::function& identifier##_mock(mock::detail::context& context, \ + boost::unit_test::const_string instance) \ + { \ + static mock::detail::function f; \ + return f(context, instance); \ + } -#define MOCK_VARIADIC_ELEM_0(e0, ...) e0 -#define MOCK_VARIADIC_ELEM_1(e0, e1, ...) e1 -#define MOCK_VARIADIC_ELEM_2(e0, e1, e2, ...) e2 +#define MOCK_FUNCTION_AUX(name, arity, signature, identifier, prefix) \ + MOCK_FUNCTION_HELPER(signature, identifier, prefix) \ + static_assert(arity == mock::detail::function_arity_t::value, "Arity mismatch"); \ + prefix MOCK_DECL(name, arity, signature, ) \ + { \ + return MOCK_HELPER(identifier)(MOCK_FORWARD_PARAMS(arity, signature)); \ + } #define MOCK_REPLACED_MACRO_ERROR(oldName, newName) static_assert(false, #oldName " has been replaced by " #newName) // Replaced macros diff --git a/include/turtle/mock.hpp b/include/turtle/mock.hpp index 9e78a4f..31d5dc8 100644 --- a/include/turtle/mock.hpp +++ b/include/turtle/mock.hpp @@ -1,6 +1,7 @@ // http://turtle.sourceforge.net // // Copyright Mathieu Champlon 2008 +// Copyright 2022-2025 Alexander Grund // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at @@ -15,6 +16,7 @@ #include "object.hpp" #include "reset.hpp" #include "verify.hpp" +#include /// MOCK_CLASS( name ) /// Define a class @@ -51,7 +53,12 @@ /// MOCK_CONSTRUCTOR( [calling convention] name, arity, parameters, identifier ) /// As constructors do not have a return type, the usual signature gets restricted here to just the parameters. -#define MOCK_CONSTRUCTOR(T, arity, parameters, identifier) MOCK_CONSTRUCTOR_AUX(T, arity, parameters, identifier) +#define MOCK_CONSTRUCTOR(T, arity, parameters, identifier) \ + T(MOCK_DECL_PARAMS(arity, void parameters)) \ + { \ + MOCK_HELPER(identifier)(MOCK_FORWARD_PARAMS(arity, void parameters)); \ + } \ + MOCK_FUNCTION_HELPER(void parameters, identifier, static) /// MOCK_DESTRUCTOR( [calling convention] ~name, identifier ) #define MOCK_DESTRUCTOR(T, identifier) \ @@ -69,39 +76,41 @@ /// generates both const and non-const methods /// The 'signature' can be omitted if it can be uniquely identified from the base class /// if 'identifier' is omitted it will default to 'name' -#define MOCK_METHOD(M, ...) \ - MOCK_METHOD_EXT(M, \ - MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), \ - MOCK_VARIADIC_ELEM_1(__VA_ARGS__, MOCK_SIGNATURE(M), ), \ - MOCK_VARIADIC_ELEM_2(__VA_ARGS__, M, M, )) +#define MOCK_METHOD(M, ...) \ + MOCK_METHOD_EXT(M, \ + BOOST_PP_VARIADIC_ELEM(0, __VA_ARGS__, ), \ + BOOST_PP_VARIADIC_ELEM(1, __VA_ARGS__, MOCK_SIGNATURE(M), ), \ + BOOST_PP_VARIADIC_ELEM(2, __VA_ARGS__, M, M, )) /// MOCK_CONST_METHOD( [calling convention] name, arity[, signature[, identifier]] ) /// generates only the const version of the method /// The 'signature' can be omitted if it can be uniquely identified from the base class /// if 'identifier' is omitted it will default to 'name' -#define MOCK_CONST_METHOD(M, ...) \ - MOCK_CONST_METHOD_EXT(M, \ - MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), \ - MOCK_VARIADIC_ELEM_1(__VA_ARGS__, MOCK_SIGNATURE(M), ), \ - MOCK_VARIADIC_ELEM_2(__VA_ARGS__, M, M, )) +#define MOCK_CONST_METHOD(M, ...) \ + MOCK_CONST_METHOD_EXT(M, \ + BOOST_PP_VARIADIC_ELEM(0, __VA_ARGS__, ), \ + BOOST_PP_VARIADIC_ELEM(1, __VA_ARGS__, MOCK_SIGNATURE(M), ), \ + BOOST_PP_VARIADIC_ELEM(2, __VA_ARGS__, M, M, )) /// MOCK_NON_CONST_METHOD( [calling convention] name, arity[, signature[, identifier]] ) /// generates only the non-const version of the method /// The 'signature' can be omitted if it can be uniquely identified from the base class /// if 'identifier' is omitted it will default to 'name' -#define MOCK_NON_CONST_METHOD(M, ...) \ - MOCK_NON_CONST_METHOD_EXT(M, \ - MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), \ - MOCK_VARIADIC_ELEM_1(__VA_ARGS__, MOCK_SIGNATURE(M), ), \ - MOCK_VARIADIC_ELEM_2(__VA_ARGS__, M, M, )) +#define MOCK_NON_CONST_METHOD(M, ...) \ + MOCK_NON_CONST_METHOD_EXT(M, \ + BOOST_PP_VARIADIC_ELEM(0, __VA_ARGS__, ), \ + BOOST_PP_VARIADIC_ELEM(1, __VA_ARGS__, MOCK_SIGNATURE(M), ), \ + BOOST_PP_VARIADIC_ELEM(2, __VA_ARGS__, M, M, )) /// MOCK_FUNCTION( [calling convention] name, arity, signature[, identifier] ) /// if 'identifier' is omitted it will default to 'name' #define MOCK_FUNCTION(F, arity, ...) \ - MOCK_FUNCTION_AUX(F, arity, MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), MOCK_VARIADIC_ELEM_1(__VA_ARGS__, F, ), inline) + MOCK_FUNCTION_AUX( \ + F, arity, BOOST_PP_VARIADIC_ELEM(0, __VA_ARGS__, ), BOOST_PP_VARIADIC_ELEM(1, __VA_ARGS__, F, ), inline) /// MOCK_STATIC_METHOD( [calling convention] name, arity, signature[, identifier] ) /// if 'identifier' is omitted it will default to 'name' #define MOCK_STATIC_METHOD(F, arity, ...) \ - MOCK_FUNCTION_AUX(F, arity, MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), MOCK_VARIADIC_ELEM_1(__VA_ARGS__, F, ), static) + MOCK_FUNCTION_AUX( \ + F, arity, BOOST_PP_VARIADIC_ELEM(0, __VA_ARGS__, ), BOOST_PP_VARIADIC_ELEM(1, __VA_ARGS__, F, ), static) /// MOCK_EXPECT( identifier ) /// Begin setting up expectation for the identifier