Skip to content

Commit

Permalink
docs: extend documentation of InterfaceMock.hpp
Browse files Browse the repository at this point in the history
  • Loading branch information
DNKpp committed Sep 25, 2024
1 parent 54581db commit 38dfc1e
Showing 1 changed file with 127 additions and 48 deletions.
175 changes: 127 additions & 48 deletions include/mimic++/InterfaceMock.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,44 @@ namespace mimicpp
* \defgroup MOCK_INTERFACES_DETAIL detail
* \ingroup MOCK_INTERFACES
*/

/**
* \defgroup MOCK_INTERFACES_DETAIL_STRIP_PARENS strip_parens
* \ingroup MOCK_INTERFACES_DETAIL
* \brief Removes an enclosing pair of (), if present.
*/
}

/**
* \brief Removes an enclosing pair of (), if present.
* \ingroup MOCK_INTERFACES_DETAIL
* \ingroup MOCK_INTERFACES_DETAIL_STRIP_PARENS
* \param x token
* \see Inspired by https://stackoverflow.com/a/62984543
*/
#define MIMICPP_DETAIL_STRIP_PARENS(x) MIMICPP_DETAIL_STRIP_PARENS_OUTER(MIMICPP_DETAIL_STRIP_PARENS_INNER x)

/**
* \brief Black-magic.
* \ingroup MOCK_INTERFACES_DETAIL_STRIP_PARENS
*/
#define MIMICPP_DETAIL_STRIP_PARENS_INNER(...) MIMICPP_DETAIL_STRIP_PARENS_INNER __VA_ARGS__

/**
* \brief Black-magic.
* \ingroup MOCK_INTERFACES_DETAIL_STRIP_PARENS
*/
#define MIMICPP_DETAIL_STRIP_PARENS_OUTER(...) MIMICPP_DETAIL_STRIP_PARENS_OUTER_(__VA_ARGS__)

/**
* \brief Black-magic.
* \ingroup MOCK_INTERFACES_DETAIL_STRIP_PARENS
*/
#define MIMICPP_DETAIL_STRIP_PARENS_OUTER_(...) MIMICPP_DETAIL_STRIP_PARENS_STRIPPED_ ## __VA_ARGS__

/**
* \brief Swallows the leftover token.
* \ingroup MOCK_INTERFACES_DETAIL_STRIP_PARENS
*/
#define MIMICPP_DETAIL_STRIP_PARENS_STRIPPED_MIMICPP_DETAIL_STRIP_PARENS_INNER

namespace mimicpp
Expand All @@ -46,26 +72,74 @@ namespace mimicpp
* \defgroup MOCK_INTERFACES_DETAIL_FOR_EACH for_each
* \ingroup MOCK_INTERFACES_DETAIL
* \brief This is an implementation of a for-loop for the preprocessor.
* \detail This solution is highly inspired by the blog-article of David Mazieres.
* \details This solution is highly inspired by the blog-article of David Mazieres.
* He does a very good job in explaining the dark corners of the macro language, but even now, I do not
* fully understand how this works. Either way, thank you very much!
* \see https://www.scs.stanford.edu/~dm/blog/va-opt.html
* \detail All macros in this group are required to make that work.
* \{
* \details All macros in this group are required to make that work.
*/
}

/**
* \brief Pastes a pair of parentheses.
* \ingroup MOCK_INTERFACES_DETAIL_FOR_EACH
*/
#define MIMICPP_DETAIL_PARENS ()

/**
* \brief Pastes a ,.
* \ingroup MOCK_INTERFACES_DETAIL_FOR_EACH
*/
#define MIMICPP_DETAIL_COMMA_DELIMITER() ,

/**
* \brief Pastes nothing.
* \ingroup MOCK_INTERFACES_DETAIL_FOR_EACH
*/
#define MIMICPP_DETAIL_NO_DELIMITER()

/**
* \brief Pastes all arguments as provided.
* \ingroup MOCK_INTERFACES_DETAIL_FOR_EACH
*/
#define MIMICPP_DETAIL_IDENTITY(...) __VA_ARGS__

/**
* \brief Part of the fake recursion.
* \ingroup MOCK_INTERFACES_DETAIL_FOR_EACH
*/
#define MIMICPP_DETAIL_EXPAND(...) MIMICPP_DETAIL_EXPAND3(MIMICPP_DETAIL_EXPAND3(MIMICPP_DETAIL_EXPAND3(MIMICPP_DETAIL_EXPAND3(__VA_ARGS__))))

/**
* \brief Part of the fake recursion.
* \ingroup MOCK_INTERFACES_DETAIL_FOR_EACH
*/
#define MIMICPP_DETAIL_EXPAND3(...) MIMICPP_DETAIL_EXPAND2(MIMICPP_DETAIL_EXPAND2(MIMICPP_DETAIL_EXPAND2(MIMICPP_DETAIL_EXPAND2(__VA_ARGS__))))

/**
* \brief Part of the fake recursion.
* \ingroup MOCK_INTERFACES_DETAIL_FOR_EACH
*/
#define MIMICPP_DETAIL_EXPAND2(...) MIMICPP_DETAIL_EXPAND1(MIMICPP_DETAIL_EXPAND1(MIMICPP_DETAIL_EXPAND1(MIMICPP_DETAIL_EXPAND1(__VA_ARGS__))))

/**
* \brief Part of the fake recursion.
* \ingroup MOCK_INTERFACES_DETAIL_FOR_EACH
*/
#define MIMICPP_DETAIL_EXPAND1(...) __VA_ARGS__

/**
* \brief Calls the given macro with all other arguments.
* \ingroup MOCK_INTERFACES_DETAIL_FOR_EACH
* \param macro Macro to be called.
* \param sequence First argument.
* \param Others Accepts arbitrary arguments and forwards them.
*/
#define MIMICPP_DETAIL_FOR_EACH_EXT_INDIRECT(macro, sequence, ...) macro(sequence, __VA_ARGS__)

/**
* \brief The starting point of the for-each implementation.
* \ingroup MOCK_INTERFACES_DETAIL_FOR_EACH
* \param macro The strategy to be executed.
* \param token A token, which will be expanded for each element.
* \param delimiter The delimiter, which will added between element.
Expand All @@ -80,32 +154,33 @@ namespace mimicpp
*/
#define MIMICPP_DETAIL_FOR_EACH_EXT(macro, token, delimiter, projection_macro, bound, ...) \
__VA_OPT__(MIMICPP_DETAIL_EXPAND(MIMICPP_DETAIL_FOR_EACH_EXT_HELPER(macro, token, token, delimiter, projection_macro, bound, __VA_ARGS__)))

/**
* \brief Black-magic.
* \ingroup MOCK_INTERFACES_DETAIL_FOR_EACH
*/
#define MIMICPP_DETAIL_FOR_EACH_EXT_HELPER(macro, token, sequence, delimiter, projection_macro, bound, a1, ...) \
MIMICPP_DETAIL_FOR_EACH_EXT_INDIRECT(macro, sequence, MIMICPP_DETAIL_STRIP_PARENS(bound), projection_macro(a1)) \
__VA_OPT__(delimiter() MIMICPP_FOR_EACH_EXT_AGAIN MIMICPP_DETAIL_PARENS (macro, token, sequence##token, delimiter, projection_macro, bound, __VA_ARGS__))
#define MIMICPP_FOR_EACH_EXT_AGAIN() MIMICPP_DETAIL_FOR_EACH_EXT_HELPER

#define MIMICPP_DETAIL_COMMA_DELIMITER() ,
#define MIMICPP_DETAIL_NO_DELIMITER()

#define MIMICPP_DETAIL_IDENTITY(...) __VA_ARGS__
/**
* \brief Black-magic.
* \ingroup MOCK_INTERFACES_DETAIL_FOR_EACH
*/
#define MIMICPP_FOR_EACH_EXT_AGAIN() MIMICPP_DETAIL_FOR_EACH_EXT_HELPER

namespace mimicpp
{
/**
* \}
*/

/**
* \defgroup MOCK_INTERFACES_DETAIL_MAKE_SIGNATURE_LIST make_signature_list
* \ingroup MOCK_INTERFACES_DETAIL
* \brief Converts all given arguments to a signature.
* \{
*/
}

/**
* \brief Converts the given information to a single signature.
* \ingroup MOCK_INTERFACES_DETAIL_MAKE_SIGNATURE_LIST
* \param sequence Unused.
* \param bound_data Unused.
* \param ret The return type.
Expand All @@ -116,6 +191,7 @@ namespace mimicpp

/**
* \brief Converts all given arguments to a signature list (not enclosed by parentheses).
* \ingroup MOCK_INTERFACES_DETAIL_MAKE_SIGNATURE_LIST
*/
#define MIMICPP_DETAIL_MAKE_SIGNATURE_LIST(...) \
MIMICPP_DETAIL_FOR_EACH_EXT( \
Expand All @@ -126,15 +202,9 @@ namespace mimicpp
, \
__VA_ARGS__)

namespace mimicpp
{
/**
* \}
*/
}

/**
* \brief Creates a mimicpp::Mock object for the given signatures.
* \ingroup MOCK_INTERFACES_DETAIL
* \param mock_name The mock name.
* \param signatures The given signatures. Enclosing parentheses will be stripped.
*/
Expand All @@ -147,12 +217,12 @@ namespace mimicpp
* \defgroup MOCK_INTERFACES_DETAIL_MAKE_PARAM_LIST make_param_list
* \ingroup MOCK_INTERFACES_DETAIL
* \brief Converts all given arguments to a parameter-list.
* \{
*/
}

/**
* \brief Converts the given information to a single parameter.
* \ingroup MOCK_INTERFACES_DETAIL_MAKE_PARAM_LIST
* \param sequence A unique sequence, which will be appended to the parameter name (as suffix).
* \param bound_data Unused.
* \param type The type of the parameter. Enclosing parentheses will be stripped.
Expand All @@ -161,6 +231,7 @@ namespace mimicpp

/**
* \brief Converts all given arguments to a parameter-list (not enclosed by parentheses).
* \ingroup MOCK_INTERFACES_DETAIL_MAKE_PARAM_LIST
*/
#define MIMICPP_DETAIL_MAKE_PARAM_LIST(...) \
MIMICPP_DETAIL_FOR_EACH_EXT( \
Expand All @@ -173,20 +244,16 @@ namespace mimicpp

namespace mimicpp
{
/**
* \}
*/

/**
* \defgroup MOCK_INTERFACES_DETAIL_FORWARD_ARGS forward_args
* \ingroup MOCK_INTERFACES_DETAIL
* \brief Creates ``std::forward`` calls for each given argument (not enclosed by parentheses).
* \{
*/
}

/**
* \brief Creates a ``std::forward`` call for the given argument.
* \ingroup MOCK_INTERFACES_DETAIL_FORWARD_ARGS
* \param sequence A unique sequence, which will be appended to the parameter name (as suffix).
* \param bound_data Unused.
* \param type The type of the parameter. Enclosing parentheses will be stripped.
Expand All @@ -196,6 +263,7 @@ namespace mimicpp

/**
* \brief Creates ``std::forward`` calls for each given argument (not enclosed by parentheses).
* \ingroup MOCK_INTERFACES_DETAIL_FORWARD_ARGS
*/
#define MIMICPP_DETAIL_FORWARD_ARGS(...) \
__VA_OPT__(,) \
Expand All @@ -209,37 +277,43 @@ namespace mimicpp

namespace mimicpp
{
/**
* \}
*/

/**
* \defgroup MOCK_INTERFACES_DETAIL_MAKE_OVERLOAD_INFOS make_overload_infos
* \ingroup MOCK_INTERFACES_DETAIL
* \brief Related functions for MIMICPP_ADD_OVERLOAD.
* \{
*/
}

/**
* \brief Base overload, extending the overload info (enclosed by parentheses).
* \ingroup MOCK_INTERFACES_DETAIL_MAKE_OVERLOAD_INFOS
* \param ret The return type.
* \param param_type_list The parameter types.
* \param specs An optional parameter for categories (e.g. ``const``, ``noexcept``, etc.).
*/
#define MIMICPP_DETAIL_MAKE_OVERLOAD_INFOS_SPECS(ret, param_type_list, specs, ...) \
(ret, param_type_list, specs, \
(MIMICPP_DETAIL_MAKE_PARAM_LIST(MIMICPP_DETAIL_STRIP_PARENS(param_type_list))), \
(MIMICPP_DETAIL_FORWARD_ARGS(MIMICPP_DETAIL_STRIP_PARENS(param_type_list))))

/**
* \brief Simple overload, extending the overload info (enclosed by parentheses).
* \ingroup MOCK_INTERFACES_DETAIL_MAKE_OVERLOAD_INFOS
* \param ret The return type.
* \param param_type_list The parameter types.
*/
#define MIMICPP_DETAIL_MAKE_OVERLOAD_INFOS_BASIC(ret, param_type_list, ...) \
MIMICPP_DETAIL_MAKE_OVERLOAD_INFOS_SPECS(ret, param_type_list, )

/**
* \brief Selects the correct overload, depending on the number of arguments.
* \ingroup MOCK_INTERFACES_DETAIL_MAKE_OVERLOAD_INFOS
* \see For an explanation of that pattern: https://stackoverflow.com/a/16683147
*/
#define MIMICPP_DETAIL_SELECT_MAKE_OVERLOAD_INFOS(_1, N, ...) N

namespace mimicpp
{
/**
* \}
*/
}

/**
* \brief Adds an overload to an interface mock.
* \brief Adds an overload to an interface mock. Used only in combination with \ref MIMICPP_MOCK_OVERLOADED_METHOD.
* \ingroup MOCK_INTERFACES
* \param ret The return type.
* \param param_type_list The parameter types.
Expand All @@ -257,10 +331,21 @@ namespace mimicpp
* \defgroup MOCK_INTERFACES_DETAIL_MAKE_METHOD_OVERRIDES make_method_overrides
* \ingroup MOCK_INTERFACES_DETAIL
* \brief Creates all required override overloads.
* \{
*/
}

/**
* \brief Create a single overload for the given information.
* \ingroup MOCK_INTERFACES_DETAIL_MAKE_METHOD_OVERRIDES
* \param ignore Ignored
* \param mock_name The mock name.
* \param fn_name The function name.
* \param ret The return type.
* \param param_type_list The parameter types.
* \param specs Additional specifiers (e.g. ``const``, ``noexcept``, etc.).
* \param param_list Enclosed parameter list.
* \param forward_list Enclosed forward statements.
*/
#define MIMICPP_DETAIL_MAKE_METHOD_OVERRIDE(ignore, mock_name, fn_name, ret, param_type_list, specs, param_list, forward_list, ...) \
inline MIMICPP_DETAIL_STRIP_PARENS(ret) fn_name param_list MIMICPP_DETAIL_STRIP_PARENS(specs) override \
{ \
Expand All @@ -271,6 +356,7 @@ namespace mimicpp

/**
* \brief Creates all overloads for a specific function as overrides.
* \ingroup MOCK_INTERFACES_DETAIL_MAKE_METHOD_OVERRIDES
* \param mock_name The mock name.
* \param fn_name The function name to be overloaded.
*/
Expand All @@ -283,13 +369,6 @@ namespace mimicpp
(mock_name, fn_name), \
__VA_ARGS__)

namespace mimicpp
{
/**
* \}
*/
}

/**
* \brief Starting point for mocking overloaded interface methods.
* \ingroup MOCK_INTERFACES
Expand Down

0 comments on commit 38dfc1e

Please sign in to comment.