mimic++ v5
Loading...
Searching...
No Matches
InterfaceMock.hpp
Go to the documentation of this file.
1// // Copyright Dominic (DNKpp) Koepke 2024 - 2024.
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{
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
248#define MIMICPP_DETAIL_MAKE_OVERLOADED_MOCK(mock_name, signatures) \
249 ::mimicpp::Mock<MIMICPP_DETAIL_STRIP_PARENS(signatures)> mock_name \
250 { \
251 }
252
253namespace mimicpp
254{
260}
261
269#define MIMICPP_DETAIL_MAKE_PARAM(sequence, bound_data, type) MIMICPP_DETAIL_STRIP_PARENS(type) arg_##sequence
270
275#define MIMICPP_DETAIL_MAKE_PARAM_LIST(...) \
276 MIMICPP_DETAIL_FOR_EACH_EXT( \
277 MIMICPP_DETAIL_MAKE_PARAM, \
278 i, \
279 MIMICPP_DETAIL_COMMA_DELIMITER, \
280 MIMICPP_DETAIL_IDENTITY, \
281 , \
282 __VA_ARGS__)
283
284namespace mimicpp
285{
305}
306
314#define MIMICPP_DETAIL_FORWARD_ARG_AS_TUPLE(sequence, bound_data, param_type) \
315 [&]<typename... Type>([[maybe_unused]] const ::mimicpp::type_list<Type...>) noexcept { \
316 return ::std::forward_as_tuple( \
317 ::std::forward<Type>(arg_##sequence)...); \
318 }(::mimicpp::type_list<MIMICPP_DETAIL_STRIP_PARENS(param_type)>{})
319
324#define MIMICPP_DETAIL_FORWARD_ARGS_AS_TUPLE(...) \
325 MIMICPP_DETAIL_FOR_EACH_EXT( \
326 MIMICPP_DETAIL_FORWARD_ARG_AS_TUPLE, \
327 i, \
328 MIMICPP_DETAIL_COMMA_DELIMITER, \
329 MIMICPP_DETAIL_IDENTITY, \
330 , \
331 __VA_ARGS__)
332
333namespace mimicpp
334{
340}
341
353#define MIMICPP_DETAIL_MAKE_OVERLOAD_INFOS_ALL(ret, param_type_list, specs, call_convention, ...) \
354 ( \
355 ret, \
356 MIMICPP_DETAIL_STRIP_PARENS(call_convention), \
357 param_type_list, \
358 MIMICPP_DETAIL_STRIP_PARENS(specs), \
359 (MIMICPP_DETAIL_MAKE_PARAM_LIST(MIMICPP_DETAIL_STRIP_PARENS(param_type_list))), \
360 (MIMICPP_DETAIL_FORWARD_ARGS_AS_TUPLE(MIMICPP_DETAIL_STRIP_PARENS(param_type_list))))
361
369#define MIMICPP_DETAIL_MAKE_OVERLOAD_INFOS_SPECS(ret, param_type_list, specs, ...) \
370 MIMICPP_DETAIL_MAKE_OVERLOAD_INFOS_ALL(ret, param_type_list, specs, )
371
378#define MIMICPP_DETAIL_MAKE_OVERLOAD_INFOS_BASIC(ret, param_type_list, ...) \
379 MIMICPP_DETAIL_MAKE_OVERLOAD_INFOS_ALL(ret, param_type_list, , )
380
386#define MIMICPP_DETAIL_SELECT_MAKE_OVERLOAD_INFOS(_1, _2, N, ...) N
387
395#define MIMICPP_ADD_OVERLOAD(ret, param_type_list, ...) \
396 MIMICPP_DETAIL_SELECT_MAKE_OVERLOAD_INFOS( \
397 __VA_ARGS__, \
398 MIMICPP_DETAIL_MAKE_OVERLOAD_INFOS_ALL, \
399 MIMICPP_DETAIL_MAKE_OVERLOAD_INFOS_SPECS, \
400 MIMICPP_DETAIL_MAKE_OVERLOAD_INFOS_BASIC)(ret, param_type_list, __VA_ARGS__, ) // clangCl doesn't compile without that extra ,
401
402namespace mimicpp
403{
409}
410
411namespace mimicpp::detail
412{
413 template <typename Signature>
414 constexpr auto indirectly_apply_mock = []<typename... Args>(auto& mock, Args&&... args)
416 // we get the mock either as const or non-const ref.
417 // But we must respect, whether the mock shall be called as lvalue or rvalue-ref.
418
420 {
421 return std::move(mock)(std::forward<Args>(args)...);
422 }
423 else
424 {
425 return mock(std::forward<Args>(args)...);
426 }
427 };
428}
429
444#define MIMICPP_DETAIL_MAKE_METHOD_OVERRIDE(ignore, mock_name, fn_name, ret, call_convention, param_type_list, specs, param_list, forward_list, ...) \
445 inline MIMICPP_DETAIL_STRIP_PARENS(ret) call_convention fn_name param_list specs override \
446 { \
447 using SignatureT = MIMICPP_DETAIL_STRIP_PARENS(ret) param_type_list specs; \
448 return ::std::apply( \
449 ::mimicpp::detail::indirectly_apply_mock<SignatureT>, \
450 ::std::tuple_cat( \
451 ::std::make_tuple(::std::ref(mock_name)), \
452 ::std::tuple_cat(MIMICPP_DETAIL_STRIP_PARENS(forward_list)))); \
453 }
454
461#define MIMICPP_DETAIL_MAKE_METHOD_OVERRIDES(mock_name, fn_name, ...) \
462 MIMICPP_DETAIL_FOR_EACH_EXT( \
463 MIMICPP_DETAIL_MAKE_METHOD_OVERRIDE, \
464 , \
465 MIMICPP_DETAIL_NO_DELIMITER, \
466 MIMICPP_DETAIL_STRIP_PARENS, \
467 (mock_name, fn_name), \
468 __VA_ARGS__)
469
480#define MIMICPP_MOCK_OVERLOADED_METHOD(fn_name, ...) \
481 MIMICPP_DETAIL_MAKE_METHOD_OVERRIDES(fn_name##_, fn_name, __VA_ARGS__) \
482 MIMICPP_DETAIL_MAKE_OVERLOADED_MOCK( \
483 fn_name##_, \
484 (MIMICPP_DETAIL_MAKE_SIGNATURE_LIST(__VA_ARGS__)))
485
496#define MIMICPP_MOCK_METHOD(fn_name, ret, param_type_list, ...) \
497 MIMICPP_MOCK_OVERLOADED_METHOD( \
498 fn_name, \
499 MIMICPP_ADD_OVERLOAD(ret, param_type_list __VA_OPT__(, ) __VA_ARGS__))
500
501#ifndef MIMICPP_CONFIG_ONLY_PREFIXED_MACROS
502
507 #define MOCK_METHOD MIMICPP_MOCK_METHOD
508
513 #define MOCK_OVERLOADED_METHOD MIMICPP_MOCK_OVERLOADED_METHOD
514
519 #define ADD_OVERLOAD MIMICPP_ADD_OVERLOAD
520
521#endif
522
523#endif
constexpr ValueCategory signature_ref_qualification_v
Convenience constant, exposing the value member of the actual type-trait.
Definition Fwd.hpp:203
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:171
Definition BoostTest.hpp:20