mimic++ v6
Loading...
Searching...
No Matches
InterfaceMock.hpp
Go to the documentation of this file.
1// Copyright Dominic (DNKpp) Koepke 2024 - 2025.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at
4// https://www.boost.org/LICENSE_1_0.txt)
5
6#ifndef MIMICPP_INTERFACE_MOCK_HPP
7#define MIMICPP_INTERFACE_MOCK_HPP
8
9#pragma once
10
11#include "mimic++/Fwd.hpp"
12#include "mimic++/Mock.hpp"
13#include "mimic++/Utility.hpp"
14
15#include <type_traits>
16#include <utility>
17
18namespace mimicpp
19{
56
63
69}
70
77#define MIMICPP_DETAIL_STRIP_PARENS(x) MIMICPP_DETAIL_STRIP_PARENS_OUTER(MIMICPP_DETAIL_STRIP_PARENS_INNER x)
78
83#define MIMICPP_DETAIL_STRIP_PARENS_INNER(...) MIMICPP_DETAIL_STRIP_PARENS_INNER __VA_ARGS__
84
89#define MIMICPP_DETAIL_STRIP_PARENS_OUTER(...) MIMICPP_DETAIL_STRIP_PARENS_OUTER_(__VA_ARGS__)
90
95#define MIMICPP_DETAIL_STRIP_PARENS_OUTER_(...) MIMICPP_DETAIL_STRIP_PARENS_STRIPPED_##__VA_ARGS__
96
101#define MIMICPP_DETAIL_STRIP_PARENS_STRIPPED_MIMICPP_DETAIL_STRIP_PARENS_INNER
102
103namespace mimicpp
104{
115}
116
121#define MIMICPP_DETAIL_PARENS ()
122
127#define MIMICPP_DETAIL_COMMA_DELIMITER() ,
128
133#define MIMICPP_DETAIL_NO_DELIMITER()
134
139#define MIMICPP_DETAIL_IDENTITY(...) __VA_ARGS__
140
145#define MIMICPP_DETAIL_EXPAND(...) MIMICPP_DETAIL_EXPAND3(MIMICPP_DETAIL_EXPAND3(MIMICPP_DETAIL_EXPAND3(MIMICPP_DETAIL_EXPAND3(__VA_ARGS__))))
146
151#define MIMICPP_DETAIL_EXPAND3(...) MIMICPP_DETAIL_EXPAND2(MIMICPP_DETAIL_EXPAND2(MIMICPP_DETAIL_EXPAND2(MIMICPP_DETAIL_EXPAND2(__VA_ARGS__))))
152
157#define MIMICPP_DETAIL_EXPAND2(...) MIMICPP_DETAIL_EXPAND1(MIMICPP_DETAIL_EXPAND1(MIMICPP_DETAIL_EXPAND1(MIMICPP_DETAIL_EXPAND1(__VA_ARGS__))))
158
163#define MIMICPP_DETAIL_EXPAND1(...) __VA_ARGS__
164
172#define MIMICPP_DETAIL_FOR_EACH_EXT_INDIRECT(macro, sequence, ...) macro(sequence, __VA_ARGS__)
173
189#define MIMICPP_DETAIL_FOR_EACH_EXT(macro, token, delimiter, projection_macro, bound, ...) \
190 __VA_OPT__(MIMICPP_DETAIL_EXPAND(MIMICPP_DETAIL_FOR_EACH_EXT_HELPER(macro, token, token, delimiter, projection_macro, bound, __VA_ARGS__)))
191
196#define MIMICPP_DETAIL_FOR_EACH_EXT_HELPER(macro, token, sequence, delimiter, projection_macro, bound, a1, ...) \
197 MIMICPP_DETAIL_FOR_EACH_EXT_INDIRECT(macro, sequence, MIMICPP_DETAIL_STRIP_PARENS(bound), projection_macro(a1)) \
198 __VA_OPT__(delimiter() MIMICPP_FOR_EACH_EXT_AGAIN MIMICPP_DETAIL_PARENS(macro, token, sequence##token, delimiter, projection_macro, bound, __VA_ARGS__))
199
204#define MIMICPP_FOR_EACH_EXT_AGAIN() MIMICPP_DETAIL_FOR_EACH_EXT_HELPER
205
206namespace mimicpp
207{
213}
214
225#define MIMICPP_DETAIL_MAKE_SIGNATURE(sequence, bound_data, ret, call_convention, param_type_list, specs, ...) \
226 MIMICPP_DETAIL_STRIP_PARENS(ret) \
227 call_convention param_type_list specs
228
233#define MIMICPP_DETAIL_MAKE_SIGNATURE_LIST(...) \
234 MIMICPP_DETAIL_FOR_EACH_EXT( \
235 MIMICPP_DETAIL_MAKE_SIGNATURE, \
236 , \
237 MIMICPP_DETAIL_COMMA_DELIMITER, \
238 MIMICPP_DETAIL_STRIP_PARENS, \
239 , \
240 __VA_ARGS__)
241
242namespace mimicpp::detail
243{
244 // Removes the following stacktrace-entries from stacktraces generated by interface mocks:
245 // * detail::indirectly_apply_mock
246 // * detail::indirectly_apply_mock::lambda
247 // * the generated interface implementation
248 inline constexpr std::size_t interfaceMockStacktraceSkip{3u};
249}
250
257#define MIMICPP_DETAIL_MAKE_OVERLOADED_MOCK(mock_name, signatures) \
258 ::mimicpp::Mock<MIMICPP_DETAIL_STRIP_PARENS(signatures)> mock_name \
259 { \
260 ::mimicpp::detail::interfaceMockStacktraceSkip \
261 }
262
263namespace mimicpp
264{
270}
271
279#define MIMICPP_DETAIL_MAKE_PARAM(sequence, bound_data, type) MIMICPP_DETAIL_STRIP_PARENS(type) arg_##sequence
280
285#define MIMICPP_DETAIL_MAKE_PARAM_LIST(...) \
286 MIMICPP_DETAIL_FOR_EACH_EXT( \
287 MIMICPP_DETAIL_MAKE_PARAM, \
288 i, \
289 MIMICPP_DETAIL_COMMA_DELIMITER, \
290 MIMICPP_DETAIL_IDENTITY, \
291 , \
292 __VA_ARGS__)
293
294namespace mimicpp
295{
315}
316
324#define MIMICPP_DETAIL_FORWARD_ARG_AS_TUPLE(sequence, bound_data, param_type) \
325 [&]<typename... Type>([[maybe_unused]] const ::mimicpp::type_list<Type...>) noexcept { \
326 return ::std::forward_as_tuple( \
327 ::std::forward<Type>(arg_##sequence)...); \
328 }(::mimicpp::type_list<MIMICPP_DETAIL_STRIP_PARENS(param_type)>{})
329
334#define MIMICPP_DETAIL_FORWARD_ARGS_AS_TUPLE(...) \
335 MIMICPP_DETAIL_FOR_EACH_EXT( \
336 MIMICPP_DETAIL_FORWARD_ARG_AS_TUPLE, \
337 i, \
338 MIMICPP_DETAIL_COMMA_DELIMITER, \
339 MIMICPP_DETAIL_IDENTITY, \
340 , \
341 __VA_ARGS__)
342
343namespace mimicpp
344{
350}
351
363#define MIMICPP_DETAIL_MAKE_OVERLOAD_INFOS_ALL(ret, param_type_list, specs, call_convention, ...) \
364 ( \
365 ret, \
366 MIMICPP_DETAIL_STRIP_PARENS(call_convention), \
367 param_type_list, \
368 MIMICPP_DETAIL_STRIP_PARENS(specs), \
369 (MIMICPP_DETAIL_MAKE_PARAM_LIST(MIMICPP_DETAIL_STRIP_PARENS(param_type_list))), \
370 (MIMICPP_DETAIL_FORWARD_ARGS_AS_TUPLE(MIMICPP_DETAIL_STRIP_PARENS(param_type_list))))
371
379#define MIMICPP_DETAIL_MAKE_OVERLOAD_INFOS_SPECS(ret, param_type_list, specs, ...) \
380 MIMICPP_DETAIL_MAKE_OVERLOAD_INFOS_ALL(ret, param_type_list, specs, )
381
388#define MIMICPP_DETAIL_MAKE_OVERLOAD_INFOS_BASIC(ret, param_type_list, ...) \
389 MIMICPP_DETAIL_MAKE_OVERLOAD_INFOS_ALL(ret, param_type_list, , )
390
396#define MIMICPP_DETAIL_SELECT_MAKE_OVERLOAD_INFOS(_1, _2, N, ...) N
397
405#define MIMICPP_ADD_OVERLOAD(ret, param_type_list, ...) \
406 MIMICPP_DETAIL_SELECT_MAKE_OVERLOAD_INFOS( \
407 __VA_ARGS__, \
408 MIMICPP_DETAIL_MAKE_OVERLOAD_INFOS_ALL, \
409 MIMICPP_DETAIL_MAKE_OVERLOAD_INFOS_SPECS, \
410 MIMICPP_DETAIL_MAKE_OVERLOAD_INFOS_BASIC)(ret, param_type_list, __VA_ARGS__, ) // clangCl doesn't compile without that extra ,
411
412namespace mimicpp
413{
419}
420
421namespace mimicpp::detail
422{
431 template <typename Signature, typename Mock, typename... Args>
432 constexpr signature_return_type_t<Signature> indirectly_apply_mock(Mock& mock, std::tuple<Args...>&& args)
433 {
434 using mock_ref_t = std::conditional_t<
436 Mock&&,
437 Mock&>;
438 const auto forward_apply = [&]<std::size_t... indices>([[maybe_unused]] const std::index_sequence<indices...>)
440 return static_cast<mock_ref_t>(mock)(
441 std::forward<Args>(std::get<indices>(args))...);
442 };
443
444 constexpr auto sequence = std::index_sequence_for<Args...>{};
445 return forward_apply(sequence);
446 };
447}
448
461#define MIMICPP_DETAIL_MAKE_METHOD_OVERRIDE(ignore, mock_name, fn_name, ret, call_convention, param_type_list, specs, param_list, forward_list, ...) \
462 inline MIMICPP_DETAIL_STRIP_PARENS(ret) call_convention fn_name param_list specs override \
463 { \
464 using SignatureT = MIMICPP_DETAIL_STRIP_PARENS(ret) param_type_list specs; \
465 return ::mimicpp::detail::indirectly_apply_mock<SignatureT>( \
466 mock_name, \
467 ::std::tuple_cat(MIMICPP_DETAIL_STRIP_PARENS(forward_list))); \
468 }
469
476#define MIMICPP_DETAIL_MAKE_METHOD_OVERRIDES(mock_name, fn_name, ...) \
477 MIMICPP_DETAIL_FOR_EACH_EXT( \
478 MIMICPP_DETAIL_MAKE_METHOD_OVERRIDE, \
479 , \
480 MIMICPP_DETAIL_NO_DELIMITER, \
481 MIMICPP_DETAIL_STRIP_PARENS, \
482 (mock_name, fn_name), \
483 __VA_ARGS__)
484
495#define MIMICPP_MOCK_OVERLOADED_METHOD(fn_name, ...) \
496 MIMICPP_DETAIL_MAKE_METHOD_OVERRIDES(fn_name##_, fn_name, __VA_ARGS__) \
497 MIMICPP_DETAIL_MAKE_OVERLOADED_MOCK( \
498 fn_name##_, \
499 (MIMICPP_DETAIL_MAKE_SIGNATURE_LIST(__VA_ARGS__)))
500
511#define MIMICPP_MOCK_METHOD(fn_name, ret, param_type_list, ...) \
512 MIMICPP_MOCK_OVERLOADED_METHOD( \
513 fn_name, \
514 MIMICPP_ADD_OVERLOAD(ret, param_type_list __VA_OPT__(, ) __VA_ARGS__))
515
516#ifndef MIMICPP_CONFIG_ONLY_PREFIXED_MACROS
517
522 #define MOCK_METHOD MIMICPP_MOCK_METHOD
523
528 #define MOCK_OVERLOADED_METHOD MIMICPP_MOCK_OVERLOADED_METHOD
529
534 #define ADD_OVERLOAD MIMICPP_ADD_OVERLOAD
535
536#endif
537
538#endif
constexpr ValueCategory signature_ref_qualification_v
Convenience constant, exposing the value member of the actual type-trait.
Definition Fwd.hpp:205
typename signature_return_type< Signature >::type signature_return_type_t
Convenience alias, exposing the type member alias of the actual type-trait.
Definition Fwd.hpp:173
Definition BoostTest.hpp:20
@ rvalue
Definition Fwd.hpp:34