mimic++ v9.2.1
Loading...
Searching...
No Matches
Facade.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_MACROS_FACADE_HPP
7#define MIMICPP_MACROS_FACADE_HPP
8
9#pragma once
10
12
13namespace mimicpp::facade
14{
21
27}
28
39#define MIMICPP_DETAIL_MAKE_SIGNATURE(sequence, bound_data, ret, call_convention, param_type_list, specs, ...) \
40 ::mimicpp::facade::detail::apply_normalized_specs_t< \
41 MIMICPP_DETAIL_STRIP_PARENS(ret) call_convention param_type_list, \
42 ::mimicpp::util::StaticString{#specs}>
43
48#define MIMICPP_DETAIL_MAKE_SIGNATURE_LIST(...) \
49 MIMICPP_DETAIL_FOR_EACH_EXT( \
50 MIMICPP_DETAIL_MAKE_SIGNATURE, \
51 , \
52 MIMICPP_DETAIL_COMMA_DELIMITER, \
53 MIMICPP_DETAIL_STRIP_PARENS, \
54 , \
55 __VA_ARGS__)
56
57namespace mimicpp::facade
58{
64}
65
73#define MIMICPP_DETAIL_MAKE_PARAM(sequence, bound_data, type) MIMICPP_DETAIL_STRIP_PARENS(type) arg_##sequence
74
79#define MIMICPP_DETAIL_MAKE_PARAM_LIST(...) \
80 MIMICPP_DETAIL_FOR_EACH_EXT( \
81 MIMICPP_DETAIL_MAKE_PARAM, \
82 i, \
83 MIMICPP_DETAIL_COMMA_DELIMITER, \
84 MIMICPP_DETAIL_IDENTITY, \
85 , \
86 __VA_ARGS__)
87
88namespace mimicpp::facade
89{
111}
112
120#define MIMICPP_DETAIL_FORWARD_ARG_AS_TUPLE(sequence, bound_data, param_type) \
121 [&]<typename... Type>([[maybe_unused]] ::mimicpp::util::type_list<Type...> const) noexcept { \
122 return ::std::forward_as_tuple(::std::forward<Type>(arg_##sequence)...); \
123 }(::mimicpp::util::type_list<MIMICPP_DETAIL_STRIP_PARENS(param_type)>{})
124
129#define MIMICPP_DETAIL_FORWARD_ARGS_AS_TUPLE(...) \
130 MIMICPP_DETAIL_FOR_EACH_EXT( \
131 MIMICPP_DETAIL_FORWARD_ARG_AS_TUPLE, \
132 i, \
133 MIMICPP_DETAIL_COMMA_DELIMITER, \
134 MIMICPP_DETAIL_IDENTITY, \
135 , \
136 __VA_ARGS__)
137
138namespace mimicpp
139{
145}
146
158#define MIMICPP_DETAIL_MAKE_OVERLOAD_INFOS_ALL(ret, param_type_list, specs, call_convention, ...) \
159 ( \
160 ret, \
161 MIMICPP_DETAIL_STRIP_PARENS(call_convention), \
162 param_type_list, \
163 MIMICPP_DETAIL_STRIP_PARENS(specs), \
164 (MIMICPP_DETAIL_MAKE_PARAM_LIST(MIMICPP_DETAIL_STRIP_PARENS(param_type_list))), \
165 (MIMICPP_DETAIL_FORWARD_ARGS_AS_TUPLE(MIMICPP_DETAIL_STRIP_PARENS(param_type_list))))
166
174#define MIMICPP_DETAIL_MAKE_OVERLOAD_INFOS_SPECS(ret, param_type_list, specs, ...) \
175 MIMICPP_DETAIL_MAKE_OVERLOAD_INFOS_ALL(ret, param_type_list, specs, )
176
183#define MIMICPP_DETAIL_MAKE_OVERLOAD_INFOS_BASIC(ret, param_type_list, ...) \
184 MIMICPP_DETAIL_MAKE_OVERLOAD_INFOS_ALL(ret, param_type_list, , )
185
191#define MIMICPP_DETAIL_SELECT_MAKE_OVERLOAD_INFOS(_1, _2, N, ...) N
192
193namespace mimicpp
194{
200}
201
211#define MIMICPP_DETAIL_GENERATE_FACADE_TARGET(traits, target_name, fn_name, linkage, signatures) \
212 linkage typename traits::template target_type<MIMICPP_DETAIL_STRIP_PARENS(signatures)> target_name \
213 { \
214 [&]<typename T = traits>() { \
215 if constexpr (::mimicpp::facade::detail::is_member_v<T>) \
216 { \
217 return T::make_settings(this, #fn_name); \
218 } \
219 else \
220 { \
221 return T::make_settings(#fn_name); \
222 } \
223 }() \
224 }
225
241#define MIMICPP_DETAIL_GENERATE_FACADE_FUNCTION(ignore, traits, target_name, fn_name, linkage, ret, call_convention, param_type_list, specs, param_list, forward_list, ...) \
242 linkage MIMICPP_DETAIL_STRIP_PARENS(ret) \
243 call_convention fn_name param_list specs \
244 { \
245 using Signature = ::mimicpp::facade::detail::apply_normalized_specs_t< \
246 MIMICPP_DETAIL_STRIP_PARENS(ret) param_type_list, \
247 ::mimicpp::util::StaticString{#specs}>; \
248 auto args = ::std::tuple_cat(MIMICPP_DETAIL_STRIP_PARENS(forward_list)); \
249 \
250 return [&]<typename T = traits>() -> decltype(auto) { \
251 if constexpr (::mimicpp::facade::detail::is_member_v<T>) \
252 { \
253 return T::template invoke<Signature>(target_name, this, ::std::move(args)); \
254 } \
255 else \
256 { \
257 return T::template invoke<Signature>(target_name, ::std::move(args)); \
258 } \
259 }(); \
260 }
261
271#define MIMICPP_DETAIL_GENERATE_FACADE_OVERLOADS(op, traits, target_name, fn_name, linkage, ...) \
272 MIMICPP_DETAIL_FOR_EACH_EXT( \
273 op, \
274 , \
275 MIMICPP_DETAIL_NO_DELIMITER, \
276 MIMICPP_DETAIL_STRIP_PARENS, \
277 (traits, target_name, fn_name, linkage), \
278 __VA_ARGS__)
279
288#define MIMICPP_DETAIL_GENERATE_FACADE(fn_op, traits, target_name, fn_name, linkage, ...) \
289 MIMICPP_DETAIL_GENERATE_FACADE_OVERLOADS(fn_op, traits, target_name, fn_name, linkage, __VA_ARGS__) \
290 MIMICPP_DETAIL_GENERATE_FACADE_TARGET( \
291 traits, \
292 target_name, \
293 fn_name, \
294 linkage, \
295 (MIMICPP_DETAIL_MAKE_SIGNATURE_LIST(__VA_ARGS__)))
296
306#define MIMICPP_ADD_OVERLOAD(ret, param_type_list, ...) \
307 MIMICPP_DETAIL_SELECT_MAKE_OVERLOAD_INFOS( \
308 __VA_ARGS__, \
309 MIMICPP_DETAIL_MAKE_OVERLOAD_INFOS_ALL, \
310 MIMICPP_DETAIL_MAKE_OVERLOAD_INFOS_SPECS, \
311 MIMICPP_DETAIL_MAKE_OVERLOAD_INFOS_BASIC)(ret, param_type_list, __VA_ARGS__, ) // clangCl doesn't compile without that extra `,`
312
313#ifndef MIMICPP_CONFIG_ONLY_PREFIXED_MACROS
319 #define ADD_OVERLOAD MIMICPP_ADD_OVERLOAD
320#endif
321
335#define MIMICPP_MAKE_OVERLOADED_FACADE_EXT(traits, target_name, fn_name, linkage, ...) \
336 MIMICPP_DETAIL_GENERATE_FACADE( \
337 MIMICPP_DETAIL_GENERATE_FACADE_FUNCTION, \
338 traits, \
339 target_name, \
340 fn_name, \
341 linkage, \
342 __VA_ARGS__)
343
344#ifndef MIMICPP_CONFIG_ONLY_PREFIXED_MACROS
350 #define MAKE_OVERLOADED_FACADE_EXT MIMICPP_MAKE_OVERLOADED_FACADE_EXT
351#endif
352
368#define MIMICPP_MAKE_FACADE_EXT(traits, target_name, fn_name, linkage, ret, param_type_list, ...) \
369 MIMICPP_MAKE_OVERLOADED_FACADE_EXT( \
370 traits, \
371 target_name, \
372 fn_name, \
373 linkage, \
374 MIMICPP_ADD_OVERLOAD(ret, param_type_list __VA_OPT__(, ) __VA_ARGS__))
375
376#ifndef MIMICPP_CONFIG_ONLY_PREFIXED_MACROS
382 #define MAKE_FACADE_EXT MIMICPP_MAKE_FACADE_EXT
383#endif
384
399#define MIMICPP_MAKE_OVERLOADED_MEMBER_MOCK(fn_name, ...) \
400 MIMICPP_MAKE_OVERLOADED_FACADE_EXT( \
401 ::mimicpp::facade::mock_as_member, \
402 fn_name##_, \
403 fn_name, \
404 , \
405 __VA_ARGS__)
406
407#ifndef MIMICPP_CONFIG_ONLY_PREFIXED_MACROS
413 #define MAKE_OVERLOADED_MEMBER_MOCK MIMICPP_MAKE_OVERLOADED_MEMBER_MOCK
414#endif
415
433#define MIMICPP_MAKE_MEMBER_MOCK(fn_name, ret, param_type_list, ...) \
434 MIMICPP_MAKE_OVERLOADED_MEMBER_MOCK( \
435 fn_name, \
436 MIMICPP_ADD_OVERLOAD(ret, param_type_list __VA_OPT__(, ) __VA_ARGS__))
437
438#ifndef MIMICPP_CONFIG_ONLY_PREFIXED_MACROS
444 #define MAKE_MEMBER_MOCK MIMICPP_MAKE_MEMBER_MOCK
445#endif
446
466#define MIMICPP_MAKE_OVERLOADED_MEMBER_MOCK_WITH_THIS(fn_name, ...) \
467 MIMICPP_MAKE_OVERLOADED_FACADE_EXT( \
468 ::mimicpp::facade::mock_as_member_with_this<self_type>, \
469 fn_name##_, \
470 fn_name, \
471 , \
472 __VA_ARGS__)
473
474#ifndef MIMICPP_CONFIG_ONLY_PREFIXED_MACROS
480 #define MAKE_OVERLOADED_MEMBER_MOCK_WITH_THIS MIMICPP_MAKE_OVERLOADED_MEMBER_MOCK_WITH_THIS
481#endif
482
505#define MIMICPP_MAKE_MEMBER_MOCK_WITH_THIS(fn_name, ret, param_type_list, ...) \
506 MIMICPP_MAKE_OVERLOADED_MEMBER_MOCK_WITH_THIS( \
507 fn_name, \
508 MIMICPP_ADD_OVERLOAD(ret, param_type_list __VA_OPT__(, ) __VA_ARGS__))
509
510#ifndef MIMICPP_CONFIG_ONLY_PREFIXED_MACROS
516 #define MAKE_MEMBER_MOCK_WITH_THIS MIMICPP_MAKE_MEMBER_MOCK_WITH_THIS
517#endif
518
519#endif
Definition Facade.hpp:75
Definition Call.hpp:24