1/**************************************************************************/
2/* binder_common.h */
3/**************************************************************************/
4/* This file is part of: */
5/* GODOT ENGINE */
6/* https://godotengine.org */
7/**************************************************************************/
8/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10/* */
11/* Permission is hereby granted, free of charge, to any person obtaining */
12/* a copy of this software and associated documentation files (the */
13/* "Software"), to deal in the Software without restriction, including */
14/* without limitation the rights to use, copy, modify, merge, publish, */
15/* distribute, sublicense, and/or sell copies of the Software, and to */
16/* permit persons to whom the Software is furnished to do so, subject to */
17/* the following conditions: */
18/* */
19/* The above copyright notice and this permission notice shall be */
20/* included in all copies or substantial portions of the Software. */
21/* */
22/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29/**************************************************************************/
30
31#ifndef BINDER_COMMON_H
32#define BINDER_COMMON_H
33
34#include "core/input/input_enums.h"
35#include "core/object/object.h"
36#include "core/os/keyboard.h"
37#include "core/templates/list.h"
38#include "core/templates/simple_type.h"
39#include "core/typedefs.h"
40#include "core/variant/method_ptrcall.h"
41#include "core/variant/type_info.h"
42#include "core/variant/variant.h"
43#include "core/variant/variant_internal.h"
44
45#include <stdio.h>
46
47// Variant cannot define an implicit cast operator for every Object subclass, so the
48// casting is done here, to allow binding methods with parameters more specific than Object *
49
50template <class T>
51struct VariantCaster {
52 static _FORCE_INLINE_ T cast(const Variant &p_variant) {
53 using TStripped = std::remove_pointer_t<T>;
54 if constexpr (std::is_base_of<Object, TStripped>::value) {
55 return Object::cast_to<TStripped>(p_variant);
56 } else {
57 return p_variant;
58 }
59 }
60};
61
62template <class T>
63struct VariantCaster<T &> {
64 static _FORCE_INLINE_ T cast(const Variant &p_variant) {
65 using TStripped = std::remove_pointer_t<T>;
66 if constexpr (std::is_base_of<Object, TStripped>::value) {
67 return Object::cast_to<TStripped>(p_variant);
68 } else {
69 return p_variant;
70 }
71 }
72};
73
74template <class T>
75struct VariantCaster<const T &> {
76 static _FORCE_INLINE_ T cast(const Variant &p_variant) {
77 using TStripped = std::remove_pointer_t<T>;
78 if constexpr (std::is_base_of<Object, TStripped>::value) {
79 return Object::cast_to<TStripped>(p_variant);
80 } else {
81 return p_variant;
82 }
83 }
84};
85
86#define VARIANT_ENUM_CAST(m_enum) \
87 MAKE_ENUM_TYPE_INFO(m_enum) \
88 template <> \
89 struct VariantCaster<m_enum> { \
90 static _FORCE_INLINE_ m_enum cast(const Variant &p_variant) { \
91 return (m_enum)p_variant.operator int64_t(); \
92 } \
93 }; \
94 template <> \
95 struct PtrToArg<m_enum> { \
96 _FORCE_INLINE_ static m_enum convert(const void *p_ptr) { \
97 return m_enum(*reinterpret_cast<const int64_t *>(p_ptr)); \
98 } \
99 typedef int64_t EncodeT; \
100 _FORCE_INLINE_ static void encode(m_enum p_val, const void *p_ptr) { \
101 *(int64_t *)p_ptr = (int64_t)p_val; \
102 } \
103 }; \
104 template <> \
105 struct ZeroInitializer<m_enum> { \
106 static void initialize(m_enum &value) { value = (m_enum)0; } \
107 }; \
108 template <> \
109 struct VariantInternalAccessor<m_enum> { \
110 static _FORCE_INLINE_ m_enum get(const Variant *v) { return m_enum(*VariantInternal::get_int(v)); } \
111 static _FORCE_INLINE_ void set(Variant *v, m_enum p_value) { *VariantInternal::get_int(v) = (int64_t)p_value; } \
112 };
113
114#define VARIANT_BITFIELD_CAST(m_enum) \
115 MAKE_BITFIELD_TYPE_INFO(m_enum) \
116 template <> \
117 struct VariantCaster<BitField<m_enum>> { \
118 static _FORCE_INLINE_ BitField<m_enum> cast(const Variant &p_variant) { \
119 return BitField<m_enum>(p_variant.operator int64_t()); \
120 } \
121 }; \
122 template <> \
123 struct PtrToArg<BitField<m_enum>> { \
124 _FORCE_INLINE_ static BitField<m_enum> convert(const void *p_ptr) { \
125 return BitField<m_enum>(*reinterpret_cast<const int64_t *>(p_ptr)); \
126 } \
127 typedef int64_t EncodeT; \
128 _FORCE_INLINE_ static void encode(BitField<m_enum> p_val, const void *p_ptr) { \
129 *(int64_t *)p_ptr = p_val; \
130 } \
131 }; \
132 template <> \
133 struct ZeroInitializer<BitField<m_enum>> { \
134 static void initialize(BitField<m_enum> &value) { value = 0; } \
135 }; \
136 template <> \
137 struct VariantInternalAccessor<BitField<m_enum>> { \
138 static _FORCE_INLINE_ BitField<m_enum> get(const Variant *v) { return BitField<m_enum>(*VariantInternal::get_int(v)); } \
139 static _FORCE_INLINE_ void set(Variant *v, BitField<m_enum> p_value) { *VariantInternal::get_int(v) = p_value.operator int64_t(); } \
140 };
141
142// Object enum casts must go here
143VARIANT_ENUM_CAST(Object::ConnectFlags);
144
145VARIANT_ENUM_CAST(Vector2::Axis);
146VARIANT_ENUM_CAST(Vector2i::Axis);
147VARIANT_ENUM_CAST(Vector3::Axis);
148VARIANT_ENUM_CAST(Vector3i::Axis);
149VARIANT_ENUM_CAST(Vector4::Axis);
150VARIANT_ENUM_CAST(Vector4i::Axis);
151VARIANT_ENUM_CAST(EulerOrder);
152VARIANT_ENUM_CAST(Projection::Planes);
153
154VARIANT_ENUM_CAST(Error);
155VARIANT_ENUM_CAST(Side);
156VARIANT_ENUM_CAST(ClockDirection);
157VARIANT_ENUM_CAST(Corner);
158VARIANT_ENUM_CAST(HatDir);
159VARIANT_BITFIELD_CAST(HatMask);
160VARIANT_ENUM_CAST(JoyAxis);
161VARIANT_ENUM_CAST(JoyButton);
162
163VARIANT_ENUM_CAST(MIDIMessage);
164VARIANT_ENUM_CAST(MouseButton);
165VARIANT_BITFIELD_CAST(MouseButtonMask);
166VARIANT_ENUM_CAST(Orientation);
167VARIANT_ENUM_CAST(HorizontalAlignment);
168VARIANT_ENUM_CAST(VerticalAlignment);
169VARIANT_ENUM_CAST(InlineAlignment);
170VARIANT_ENUM_CAST(PropertyHint);
171VARIANT_BITFIELD_CAST(PropertyUsageFlags);
172VARIANT_ENUM_CAST(Variant::Type);
173VARIANT_ENUM_CAST(Variant::Operator);
174
175// Key
176
177VARIANT_ENUM_CAST(Key);
178VARIANT_BITFIELD_CAST(KeyModifierMask);
179
180static inline Key &operator|=(Key &a, BitField<KeyModifierMask> b) {
181 a = static_cast<Key>(static_cast<int>(a) | static_cast<int>(b.operator int64_t()));
182 return a;
183}
184
185static inline Key &operator&=(Key &a, BitField<KeyModifierMask> b) {
186 a = static_cast<Key>(static_cast<int>(a) & static_cast<int>(b.operator int64_t()));
187 return a;
188}
189
190static inline Key operator|(Key a, BitField<KeyModifierMask> b) {
191 return (Key)((int)a | (int)b.operator int64_t());
192}
193
194static inline Key operator&(Key a, BitField<KeyModifierMask> b) {
195 return (Key)((int)a & (int)b.operator int64_t());
196}
197
198static inline Key operator+(BitField<KeyModifierMask> a, Key b) {
199 return (Key)((int)a.operator int64_t() + (int)b);
200}
201
202static inline Key operator|(BitField<KeyModifierMask> a, Key b) {
203 return (Key)((int)a.operator int64_t() | (int)b);
204}
205
206template <>
207struct VariantCaster<char32_t> {
208 static _FORCE_INLINE_ char32_t cast(const Variant &p_variant) {
209 return (char32_t)p_variant.operator int();
210 }
211};
212
213template <>
214struct PtrToArg<char32_t> {
215 _FORCE_INLINE_ static char32_t convert(const void *p_ptr) {
216 return char32_t(*reinterpret_cast<const int *>(p_ptr));
217 }
218 typedef int64_t EncodeT;
219 _FORCE_INLINE_ static void encode(char32_t p_val, const void *p_ptr) {
220 *(int *)p_ptr = p_val;
221 }
222};
223
224template <typename T>
225struct VariantObjectClassChecker {
226 static _FORCE_INLINE_ bool check(const Variant &p_variant) {
227 using TStripped = std::remove_pointer_t<T>;
228 if constexpr (std::is_base_of<Object, TStripped>::value) {
229 Object *obj = p_variant;
230 return Object::cast_to<TStripped>(p_variant) || !obj;
231 } else {
232 return true;
233 }
234 }
235};
236
237template <typename T>
238class Ref;
239
240template <typename T>
241struct VariantObjectClassChecker<const Ref<T> &> {
242 static _FORCE_INLINE_ bool check(const Variant &p_variant) {
243 Object *obj = p_variant;
244 const Ref<T> node = p_variant;
245 return node.ptr() || !obj;
246 }
247};
248
249#ifdef DEBUG_METHODS_ENABLED
250
251template <class T>
252struct VariantCasterAndValidate {
253 static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, Callable::CallError &r_error) {
254 Variant::Type argtype = GetTypeInfo<T>::VARIANT_TYPE;
255 if (!Variant::can_convert_strict(p_args[p_arg_idx]->get_type(), argtype) ||
256 !VariantObjectClassChecker<T>::check(*p_args[p_arg_idx])) {
257 r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
258 r_error.argument = p_arg_idx;
259 r_error.expected = argtype;
260 }
261
262 return VariantCaster<T>::cast(*p_args[p_arg_idx]);
263 }
264};
265
266template <class T>
267struct VariantCasterAndValidate<T &> {
268 static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, Callable::CallError &r_error) {
269 Variant::Type argtype = GetTypeInfo<T>::VARIANT_TYPE;
270 if (!Variant::can_convert_strict(p_args[p_arg_idx]->get_type(), argtype) ||
271 !VariantObjectClassChecker<T>::check(*p_args[p_arg_idx])) {
272 r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
273 r_error.argument = p_arg_idx;
274 r_error.expected = argtype;
275 }
276
277 return VariantCaster<T>::cast(*p_args[p_arg_idx]);
278 }
279};
280
281template <class T>
282struct VariantCasterAndValidate<const T &> {
283 static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, Callable::CallError &r_error) {
284 Variant::Type argtype = GetTypeInfo<T>::VARIANT_TYPE;
285 if (!Variant::can_convert_strict(p_args[p_arg_idx]->get_type(), argtype) ||
286 !VariantObjectClassChecker<T>::check(*p_args[p_arg_idx])) {
287 r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
288 r_error.argument = p_arg_idx;
289 r_error.expected = argtype;
290 }
291
292 return VariantCaster<T>::cast(*p_args[p_arg_idx]);
293 }
294};
295
296#endif // DEBUG_METHODS_ENABLED
297
298template <class T, class... P, size_t... Is>
299void call_with_variant_args_helper(T *p_instance, void (T::*p_method)(P...), const Variant **p_args, Callable::CallError &r_error, IndexSequence<Is...>) {
300 r_error.error = Callable::CallError::CALL_OK;
301
302#ifdef DEBUG_METHODS_ENABLED
303 (p_instance->*p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
304#else
305 (p_instance->*p_method)(VariantCaster<P>::cast(*p_args[Is])...);
306#endif
307 (void)(p_args); //avoid warning
308}
309
310template <class T, class... P, size_t... Is>
311void call_with_variant_argsc_helper(T *p_instance, void (T::*p_method)(P...) const, const Variant **p_args, Callable::CallError &r_error, IndexSequence<Is...>) {
312 r_error.error = Callable::CallError::CALL_OK;
313
314#ifdef DEBUG_METHODS_ENABLED
315 (p_instance->*p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
316#else
317 (p_instance->*p_method)(VariantCaster<P>::cast(*p_args[Is])...);
318#endif
319 (void)(p_args); //avoid warning
320}
321
322template <class T, class... P, size_t... Is>
323void call_with_ptr_args_helper(T *p_instance, void (T::*p_method)(P...), const void **p_args, IndexSequence<Is...>) {
324 (p_instance->*p_method)(PtrToArg<P>::convert(p_args[Is])...);
325}
326
327template <class T, class... P, size_t... Is>
328void call_with_ptr_argsc_helper(T *p_instance, void (T::*p_method)(P...) const, const void **p_args, IndexSequence<Is...>) {
329 (p_instance->*p_method)(PtrToArg<P>::convert(p_args[Is])...);
330}
331
332template <class T, class R, class... P, size_t... Is>
333void call_with_ptr_args_ret_helper(T *p_instance, R (T::*p_method)(P...), const void **p_args, void *r_ret, IndexSequence<Is...>) {
334 PtrToArg<R>::encode((p_instance->*p_method)(PtrToArg<P>::convert(p_args[Is])...), r_ret);
335}
336
337template <class T, class R, class... P, size_t... Is>
338void call_with_ptr_args_retc_helper(T *p_instance, R (T::*p_method)(P...) const, const void **p_args, void *r_ret, IndexSequence<Is...>) {
339 PtrToArg<R>::encode((p_instance->*p_method)(PtrToArg<P>::convert(p_args[Is])...), r_ret);
340}
341
342template <class T, class... P, size_t... Is>
343void call_with_ptr_args_static_helper(T *p_instance, void (*p_method)(T *, P...), const void **p_args, IndexSequence<Is...>) {
344 p_method(p_instance, PtrToArg<P>::convert(p_args[Is])...);
345}
346
347template <class T, class R, class... P, size_t... Is>
348void call_with_ptr_args_static_retc_helper(T *p_instance, R (*p_method)(T *, P...), const void **p_args, void *r_ret, IndexSequence<Is...>) {
349 PtrToArg<R>::encode(p_method(p_instance, PtrToArg<P>::convert(p_args[Is])...), r_ret);
350}
351
352template <class R, class... P, size_t... Is>
353void call_with_ptr_args_static_method_ret_helper(R (*p_method)(P...), const void **p_args, void *r_ret, IndexSequence<Is...>) {
354 PtrToArg<R>::encode(p_method(PtrToArg<P>::convert(p_args[Is])...), r_ret);
355}
356
357template <class... P, size_t... Is>
358void call_with_ptr_args_static_method_helper(void (*p_method)(P...), const void **p_args, IndexSequence<Is...>) {
359 p_method(PtrToArg<P>::convert(p_args[Is])...);
360}
361
362template <class T, class... P, size_t... Is>
363void call_with_validated_variant_args_helper(T *p_instance, void (T::*p_method)(P...), const Variant **p_args, IndexSequence<Is...>) {
364 (p_instance->*p_method)((VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...);
365}
366
367template <class T, class... P, size_t... Is>
368void call_with_validated_variant_argsc_helper(T *p_instance, void (T::*p_method)(P...) const, const Variant **p_args, IndexSequence<Is...>) {
369 (p_instance->*p_method)((VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...);
370}
371
372template <class T, class R, class... P, size_t... Is>
373void call_with_validated_variant_args_ret_helper(T *p_instance, R (T::*p_method)(P...), const Variant **p_args, Variant *r_ret, IndexSequence<Is...>) {
374 VariantInternalAccessor<typename GetSimpleTypeT<R>::type_t>::set(r_ret, (p_instance->*p_method)((VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...));
375}
376
377template <class T, class R, class... P, size_t... Is>
378void call_with_validated_variant_args_retc_helper(T *p_instance, R (T::*p_method)(P...) const, const Variant **p_args, Variant *r_ret, IndexSequence<Is...>) {
379 VariantInternalAccessor<typename GetSimpleTypeT<R>::type_t>::set(r_ret, (p_instance->*p_method)((VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...));
380}
381
382template <class T, class R, class... P, size_t... Is>
383void call_with_validated_variant_args_static_retc_helper(T *p_instance, R (*p_method)(T *, P...), const Variant **p_args, Variant *r_ret, IndexSequence<Is...>) {
384 VariantInternalAccessor<typename GetSimpleTypeT<R>::type_t>::set(r_ret, p_method(p_instance, (VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...));
385}
386
387template <class T, class... P, size_t... Is>
388void call_with_validated_variant_args_static_helper(T *p_instance, void (*p_method)(T *, P...), const Variant **p_args, IndexSequence<Is...>) {
389 p_method(p_instance, (VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...);
390}
391
392template <class R, class... P, size_t... Is>
393void call_with_validated_variant_args_static_method_ret_helper(R (*p_method)(P...), const Variant **p_args, Variant *r_ret, IndexSequence<Is...>) {
394 VariantInternalAccessor<typename GetSimpleTypeT<R>::type_t>::set(r_ret, p_method((VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...));
395}
396
397template <class... P, size_t... Is>
398void call_with_validated_variant_args_static_method_helper(void (*p_method)(P...), const Variant **p_args, IndexSequence<Is...>) {
399 p_method((VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...);
400}
401
402template <class T, class... P>
403void call_with_variant_args(T *p_instance, void (T::*p_method)(P...), const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
404#ifdef DEBUG_METHODS_ENABLED
405 if ((size_t)p_argcount > sizeof...(P)) {
406 r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
407 r_error.argument = sizeof...(P);
408 return;
409 }
410
411 if ((size_t)p_argcount < sizeof...(P)) {
412 r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
413 r_error.argument = sizeof...(P);
414 return;
415 }
416#endif
417 call_with_variant_args_helper<T, P...>(p_instance, p_method, p_args, r_error, BuildIndexSequence<sizeof...(P)>{});
418}
419
420template <class T, class... P>
421void call_with_variant_args_dv(T *p_instance, void (T::*p_method)(P...), const Variant **p_args, int p_argcount, Callable::CallError &r_error, const Vector<Variant> &default_values) {
422#ifdef DEBUG_ENABLED
423 if ((size_t)p_argcount > sizeof...(P)) {
424 r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
425 r_error.argument = sizeof...(P);
426 return;
427 }
428#endif
429
430 int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount;
431
432 int32_t dvs = default_values.size();
433#ifdef DEBUG_ENABLED
434 if (missing > dvs) {
435 r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
436 r_error.argument = sizeof...(P);
437 return;
438 }
439#endif
440
441 const Variant *args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; //avoid zero sized array
442 for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) {
443 if (i < p_argcount) {
444 args[i] = p_args[i];
445 } else {
446 args[i] = &default_values[i - p_argcount + (dvs - missing)];
447 }
448 }
449
450 call_with_variant_args_helper(p_instance, p_method, args, r_error, BuildIndexSequence<sizeof...(P)>{});
451}
452
453template <class T, class... P>
454void call_with_variant_argsc(T *p_instance, void (T::*p_method)(P...) const, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
455#ifdef DEBUG_METHODS_ENABLED
456 if ((size_t)p_argcount > sizeof...(P)) {
457 r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
458 r_error.argument = sizeof...(P);
459 return;
460 }
461
462 if ((size_t)p_argcount < sizeof...(P)) {
463 r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
464 r_error.argument = sizeof...(P);
465 return;
466 }
467#endif
468 call_with_variant_args_helper<T, P...>(p_instance, p_method, p_args, r_error, BuildIndexSequence<sizeof...(P)>{});
469}
470
471template <class T, class... P>
472void call_with_variant_argsc_dv(T *p_instance, void (T::*p_method)(P...) const, const Variant **p_args, int p_argcount, Callable::CallError &r_error, const Vector<Variant> &default_values) {
473#ifdef DEBUG_ENABLED
474 if ((size_t)p_argcount > sizeof...(P)) {
475 r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
476 r_error.argument = sizeof...(P);
477 return;
478 }
479#endif
480
481 int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount;
482
483 int32_t dvs = default_values.size();
484#ifdef DEBUG_ENABLED
485 if (missing > dvs) {
486 r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
487 r_error.argument = sizeof...(P);
488 return;
489 }
490#endif
491
492 const Variant *args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; //avoid zero sized array
493 for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) {
494 if (i < p_argcount) {
495 args[i] = p_args[i];
496 } else {
497 args[i] = &default_values[i - p_argcount + (dvs - missing)];
498 }
499 }
500
501 call_with_variant_argsc_helper(p_instance, p_method, args, r_error, BuildIndexSequence<sizeof...(P)>{});
502}
503
504template <class T, class R, class... P>
505void call_with_variant_args_ret_dv(T *p_instance, R (T::*p_method)(P...), const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error, const Vector<Variant> &default_values) {
506#ifdef DEBUG_ENABLED
507 if ((size_t)p_argcount > sizeof...(P)) {
508 r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
509 r_error.argument = sizeof...(P);
510 return;
511 }
512#endif
513
514 int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount;
515
516 int32_t dvs = default_values.size();
517#ifdef DEBUG_ENABLED
518 if (missing > dvs) {
519 r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
520 r_error.argument = sizeof...(P);
521 return;
522 }
523#endif
524
525 const Variant *args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; //avoid zero sized array
526 for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) {
527 if (i < p_argcount) {
528 args[i] = p_args[i];
529 } else {
530 args[i] = &default_values[i - p_argcount + (dvs - missing)];
531 }
532 }
533
534 call_with_variant_args_ret_helper(p_instance, p_method, args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
535}
536
537template <class T, class R, class... P>
538void call_with_variant_args_retc_dv(T *p_instance, R (T::*p_method)(P...) const, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error, const Vector<Variant> &default_values) {
539#ifdef DEBUG_ENABLED
540 if ((size_t)p_argcount > sizeof...(P)) {
541 r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
542 r_error.argument = sizeof...(P);
543 return;
544 }
545#endif
546
547 int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount;
548
549 int32_t dvs = default_values.size();
550#ifdef DEBUG_ENABLED
551 if (missing > dvs) {
552 r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
553 r_error.argument = sizeof...(P);
554 return;
555 }
556#endif
557
558 const Variant *args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; //avoid zero sized array
559 for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) {
560 if (i < p_argcount) {
561 args[i] = p_args[i];
562 } else {
563 args[i] = &default_values[i - p_argcount + (dvs - missing)];
564 }
565 }
566
567 call_with_variant_args_retc_helper(p_instance, p_method, args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
568}
569
570template <class T, class... P>
571void call_with_ptr_args(T *p_instance, void (T::*p_method)(P...), const void **p_args) {
572 call_with_ptr_args_helper<T, P...>(p_instance, p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
573}
574
575template <class T, class... P>
576void call_with_ptr_argsc(T *p_instance, void (T::*p_method)(P...) const, const void **p_args) {
577 call_with_ptr_argsc_helper<T, P...>(p_instance, p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
578}
579
580template <class T, class R, class... P>
581void call_with_ptr_args_ret(T *p_instance, R (T::*p_method)(P...), const void **p_args, void *r_ret) {
582 call_with_ptr_args_ret_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
583}
584
585template <class T, class R, class... P>
586void call_with_ptr_args_retc(T *p_instance, R (T::*p_method)(P...) const, const void **p_args, void *r_ret) {
587 call_with_ptr_args_retc_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
588}
589
590template <class T, class... P>
591void call_with_ptr_args_static(T *p_instance, void (*p_method)(T *, P...), const void **p_args) {
592 call_with_ptr_args_static_helper<T, P...>(p_instance, p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
593}
594
595template <class T, class R, class... P>
596void call_with_ptr_args_static_retc(T *p_instance, R (*p_method)(T *, P...), const void **p_args, void *r_ret) {
597 call_with_ptr_args_static_retc_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
598}
599
600template <class R, class... P>
601void call_with_ptr_args_static_method_ret(R (*p_method)(P...), const void **p_args, void *r_ret) {
602 call_with_ptr_args_static_method_ret_helper<R, P...>(p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
603}
604
605template <class... P>
606void call_with_ptr_args_static_method(void (*p_method)(P...), const void **p_args) {
607 call_with_ptr_args_static_method_helper<P...>(p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
608}
609
610// Validated
611
612template <class T, class... P>
613void call_with_validated_variant_args(Variant *base, void (T::*p_method)(P...), const Variant **p_args) {
614 call_with_validated_variant_args_helper<T, P...>(VariantGetInternalPtr<T>::get_ptr(base), p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
615}
616
617template <class T, class R, class... P>
618void call_with_validated_variant_args_ret(Variant *base, R (T::*p_method)(P...), const Variant **p_args, Variant *r_ret) {
619 call_with_validated_variant_args_ret_helper<T, R, P...>(VariantGetInternalPtr<T>::get_ptr(base), p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
620}
621
622template <class T, class R, class... P>
623void call_with_validated_variant_args_retc(Variant *base, R (T::*p_method)(P...) const, const Variant **p_args, Variant *r_ret) {
624 call_with_validated_variant_args_retc_helper<T, R, P...>(VariantGetInternalPtr<T>::get_ptr(base), p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
625}
626
627template <class T, class... P>
628void call_with_validated_variant_args_static(Variant *base, void (*p_method)(T *, P...), const Variant **p_args) {
629 call_with_validated_variant_args_static_helper<T, P...>(VariantGetInternalPtr<T>::get_ptr(base), p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
630}
631
632template <class T, class R, class... P>
633void call_with_validated_variant_args_static_retc(Variant *base, R (*p_method)(T *, P...), const Variant **p_args, Variant *r_ret) {
634 call_with_validated_variant_args_static_retc_helper<T, R, P...>(VariantGetInternalPtr<T>::get_ptr(base), p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
635}
636
637template <class... P>
638void call_with_validated_variant_args_static_method(void (*p_method)(P...), const Variant **p_args) {
639 call_with_validated_variant_args_static_method_helper<P...>(p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
640}
641
642template <class R, class... P>
643void call_with_validated_variant_args_static_method_ret(R (*p_method)(P...), const Variant **p_args, Variant *r_ret) {
644 call_with_validated_variant_args_static_method_ret_helper<R, P...>(p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
645}
646
647// Validated Object
648
649template <class T, class... P>
650void call_with_validated_object_instance_args(T *base, void (T::*p_method)(P...), const Variant **p_args) {
651 call_with_validated_variant_args_helper<T, P...>(base, p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
652}
653
654template <class T, class... P>
655void call_with_validated_object_instance_argsc(T *base, void (T::*p_method)(P...) const, const Variant **p_args) {
656 call_with_validated_variant_argsc_helper<T, P...>(base, p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
657}
658
659template <class T, class R, class... P>
660void call_with_validated_object_instance_args_ret(T *base, R (T::*p_method)(P...), const Variant **p_args, Variant *r_ret) {
661 call_with_validated_variant_args_ret_helper<T, R, P...>(base, p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
662}
663
664template <class T, class R, class... P>
665void call_with_validated_object_instance_args_retc(T *base, R (T::*p_method)(P...) const, const Variant **p_args, Variant *r_ret) {
666 call_with_validated_variant_args_retc_helper<T, R, P...>(base, p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
667}
668
669template <class T, class... P>
670void call_with_validated_object_instance_args_static(T *base, void (*p_method)(T *, P...), const Variant **p_args) {
671 call_with_validated_variant_args_static_helper<T, P...>(base, p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
672}
673
674template <class T, class R, class... P>
675void call_with_validated_object_instance_args_static_retc(T *base, R (*p_method)(T *, P...), const Variant **p_args, Variant *r_ret) {
676 call_with_validated_variant_args_static_retc_helper<T, R, P...>(base, p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
677}
678
679// GCC raises "parameter 'p_args' set but not used" when P = {},
680// it's not clever enough to treat other P values as making this branch valid.
681#if defined(__GNUC__) && !defined(__clang__)
682#pragma GCC diagnostic push
683#pragma GCC diagnostic ignored "-Wunused-but-set-parameter"
684#endif
685
686template <class Q>
687void call_get_argument_type_helper(int p_arg, int &index, Variant::Type &type) {
688 if (p_arg == index) {
689 type = GetTypeInfo<Q>::VARIANT_TYPE;
690 }
691 index++;
692}
693
694template <class... P>
695Variant::Type call_get_argument_type(int p_arg) {
696 Variant::Type type = Variant::NIL;
697 int index = 0;
698 // I think rocket science is simpler than modern C++.
699 using expand_type = int[];
700 expand_type a{ 0, (call_get_argument_type_helper<P>(p_arg, index, type), 0)... };
701 (void)a; // Suppress (valid, but unavoidable) -Wunused-variable warning.
702 (void)index; // Suppress GCC warning.
703 return type;
704}
705
706template <class Q>
707void call_get_argument_type_info_helper(int p_arg, int &index, PropertyInfo &info) {
708 if (p_arg == index) {
709 info = GetTypeInfo<Q>::get_class_info();
710 }
711 index++;
712}
713
714template <class... P>
715void call_get_argument_type_info(int p_arg, PropertyInfo &info) {
716 int index = 0;
717 // I think rocket science is simpler than modern C++.
718 using expand_type = int[];
719 expand_type a{ 0, (call_get_argument_type_info_helper<P>(p_arg, index, info), 0)... };
720 (void)a; // Suppress (valid, but unavoidable) -Wunused-variable warning.
721 (void)index; // Suppress GCC warning.
722}
723
724#ifdef DEBUG_METHODS_ENABLED
725template <class Q>
726void call_get_argument_metadata_helper(int p_arg, int &index, GodotTypeInfo::Metadata &md) {
727 if (p_arg == index) {
728 md = GetTypeInfo<Q>::METADATA;
729 }
730 index++;
731}
732
733template <class... P>
734GodotTypeInfo::Metadata call_get_argument_metadata(int p_arg) {
735 GodotTypeInfo::Metadata md = GodotTypeInfo::METADATA_NONE;
736
737 int index = 0;
738 // I think rocket science is simpler than modern C++.
739 using expand_type = int[];
740 expand_type a{ 0, (call_get_argument_metadata_helper<P>(p_arg, index, md), 0)... };
741 (void)a; // Suppress (valid, but unavoidable) -Wunused-variable warning.
742 (void)index;
743 return md;
744}
745
746#endif // DEBUG_METHODS_ENABLED
747
748//////////////////////
749
750template <class T, class R, class... P, size_t... Is>
751void call_with_variant_args_ret_helper(T *p_instance, R (T::*p_method)(P...), const Variant **p_args, Variant &r_ret, Callable::CallError &r_error, IndexSequence<Is...>) {
752 r_error.error = Callable::CallError::CALL_OK;
753
754#ifdef DEBUG_METHODS_ENABLED
755 r_ret = (p_instance->*p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
756#else
757 r_ret = (p_instance->*p_method)(VariantCaster<P>::cast(*p_args[Is])...);
758#endif
759}
760
761template <class R, class... P, size_t... Is>
762void call_with_variant_args_static_ret(R (*p_method)(P...), const Variant **p_args, Variant &r_ret, Callable::CallError &r_error, IndexSequence<Is...>) {
763 r_error.error = Callable::CallError::CALL_OK;
764
765#ifdef DEBUG_METHODS_ENABLED
766 r_ret = (p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
767#else
768 r_ret = (p_method)(VariantCaster<P>::cast(*p_args[Is])...);
769#endif
770}
771
772template <class... P, size_t... Is>
773void call_with_variant_args_static(void (*p_method)(P...), const Variant **p_args, Callable::CallError &r_error, IndexSequence<Is...>) {
774 r_error.error = Callable::CallError::CALL_OK;
775
776#ifdef DEBUG_METHODS_ENABLED
777 (p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
778#else
779 (p_method)(VariantCaster<P>::cast(*p_args[Is])...);
780#endif
781}
782
783template <class T, class R, class... P>
784void call_with_variant_args_ret(T *p_instance, R (T::*p_method)(P...), const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
785#ifdef DEBUG_METHODS_ENABLED
786 if ((size_t)p_argcount > sizeof...(P)) {
787 r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
788 r_error.argument = sizeof...(P);
789 return;
790 }
791
792 if ((size_t)p_argcount < sizeof...(P)) {
793 r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
794 r_error.argument = sizeof...(P);
795 return;
796 }
797#endif
798 call_with_variant_args_ret_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
799}
800
801template <class T, class R, class... P, size_t... Is>
802void call_with_variant_args_retc_helper(T *p_instance, R (T::*p_method)(P...) const, const Variant **p_args, Variant &r_ret, Callable::CallError &r_error, IndexSequence<Is...>) {
803 r_error.error = Callable::CallError::CALL_OK;
804
805#ifdef DEBUG_METHODS_ENABLED
806 r_ret = (p_instance->*p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
807#else
808 r_ret = (p_instance->*p_method)(VariantCaster<P>::cast(*p_args[Is])...);
809#endif
810 (void)p_args;
811}
812
813template <class R, class... P>
814void call_with_variant_args_static_ret(R (*p_method)(P...), const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
815#ifdef DEBUG_METHODS_ENABLED
816 if ((size_t)p_argcount > sizeof...(P)) {
817 r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
818 r_error.argument = sizeof...(P);
819 return;
820 }
821
822 if ((size_t)p_argcount < sizeof...(P)) {
823 r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
824 r_error.argument = sizeof...(P);
825 return;
826 }
827#endif
828 call_with_variant_args_static_ret<R, P...>(p_method, p_args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
829}
830
831template <class... P>
832void call_with_variant_args_static_ret(void (*p_method)(P...), const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
833#ifdef DEBUG_METHODS_ENABLED
834 if ((size_t)p_argcount > sizeof...(P)) {
835 r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
836 r_error.argument = sizeof...(P);
837 return;
838 }
839
840 if ((size_t)p_argcount < sizeof...(P)) {
841 r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
842 r_error.argument = sizeof...(P);
843 return;
844 }
845#endif
846 call_with_variant_args_static<P...>(p_method, p_args, r_error, BuildIndexSequence<sizeof...(P)>{});
847}
848
849template <class T, class R, class... P>
850void call_with_variant_args_retc(T *p_instance, R (T::*p_method)(P...) const, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
851#ifdef DEBUG_METHODS_ENABLED
852 if ((size_t)p_argcount > sizeof...(P)) {
853 r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
854 r_error.argument = sizeof...(P);
855 return;
856 }
857
858 if ((size_t)p_argcount < sizeof...(P)) {
859 r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
860 r_error.argument = sizeof...(P);
861 return;
862 }
863#endif
864 call_with_variant_args_retc_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
865}
866
867template <class T, class R, class... P, size_t... Is>
868void call_with_variant_args_retc_static_helper(T *p_instance, R (*p_method)(T *, P...), const Variant **p_args, Variant &r_ret, Callable::CallError &r_error, IndexSequence<Is...>) {
869 r_error.error = Callable::CallError::CALL_OK;
870
871#ifdef DEBUG_METHODS_ENABLED
872 r_ret = (p_method)(p_instance, VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
873#else
874 r_ret = (p_method)(p_instance, VariantCaster<P>::cast(*p_args[Is])...);
875#endif
876
877 (void)p_args;
878}
879
880template <class T, class R, class... P>
881void call_with_variant_args_retc_static_helper_dv(T *p_instance, R (*p_method)(T *, P...), const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &default_values, Callable::CallError &r_error) {
882#ifdef DEBUG_ENABLED
883 if ((size_t)p_argcount > sizeof...(P)) {
884 r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
885 r_error.argument = sizeof...(P);
886 return;
887 }
888#endif
889
890 int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount;
891
892 int32_t dvs = default_values.size();
893#ifdef DEBUG_ENABLED
894 if (missing > dvs) {
895 r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
896 r_error.argument = sizeof...(P);
897 return;
898 }
899#endif
900
901 const Variant *args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; //avoid zero sized array
902 for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) {
903 if (i < p_argcount) {
904 args[i] = p_args[i];
905 } else {
906 args[i] = &default_values[i - p_argcount + (dvs - missing)];
907 }
908 }
909
910 call_with_variant_args_retc_static_helper(p_instance, p_method, args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
911}
912
913template <class T, class... P, size_t... Is>
914void call_with_variant_args_static_helper(T *p_instance, void (*p_method)(T *, P...), const Variant **p_args, Callable::CallError &r_error, IndexSequence<Is...>) {
915 r_error.error = Callable::CallError::CALL_OK;
916
917#ifdef DEBUG_METHODS_ENABLED
918 (p_method)(p_instance, VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
919#else
920 (p_method)(p_instance, VariantCaster<P>::cast(*p_args[Is])...);
921#endif
922
923 (void)p_args;
924}
925
926template <class T, class... P>
927void call_with_variant_args_static_helper_dv(T *p_instance, void (*p_method)(T *, P...), const Variant **p_args, int p_argcount, const Vector<Variant> &default_values, Callable::CallError &r_error) {
928#ifdef DEBUG_ENABLED
929 if ((size_t)p_argcount > sizeof...(P)) {
930 r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
931 r_error.argument = sizeof...(P);
932 return;
933 }
934#endif
935
936 int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount;
937
938 int32_t dvs = default_values.size();
939#ifdef DEBUG_ENABLED
940 if (missing > dvs) {
941 r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
942 r_error.argument = sizeof...(P);
943 return;
944 }
945#endif
946
947 const Variant *args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; //avoid zero sized array
948 for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) {
949 if (i < p_argcount) {
950 args[i] = p_args[i];
951 } else {
952 args[i] = &default_values[i - p_argcount + (dvs - missing)];
953 }
954 }
955
956 call_with_variant_args_static_helper(p_instance, p_method, args, r_error, BuildIndexSequence<sizeof...(P)>{});
957}
958
959template <class R, class... P>
960void call_with_variant_args_static_ret_dv(R (*p_method)(P...), const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error, const Vector<Variant> &default_values) {
961#ifdef DEBUG_ENABLED
962 if ((size_t)p_argcount > sizeof...(P)) {
963 r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
964 r_error.argument = sizeof...(P);
965 return;
966 }
967#endif
968
969 int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount;
970
971 int32_t dvs = default_values.size();
972#ifdef DEBUG_ENABLED
973 if (missing > dvs) {
974 r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
975 r_error.argument = sizeof...(P);
976 return;
977 }
978#endif
979
980 const Variant *args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; //avoid zero sized array
981 for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) {
982 if (i < p_argcount) {
983 args[i] = p_args[i];
984 } else {
985 args[i] = &default_values[i - p_argcount + (dvs - missing)];
986 }
987 }
988
989 call_with_variant_args_static_ret(p_method, args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
990}
991
992template <class... P>
993void call_with_variant_args_static_dv(void (*p_method)(P...), const Variant **p_args, int p_argcount, Callable::CallError &r_error, const Vector<Variant> &default_values) {
994#ifdef DEBUG_ENABLED
995 if ((size_t)p_argcount > sizeof...(P)) {
996 r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
997 r_error.argument = sizeof...(P);
998 return;
999 }
1000#endif
1001
1002 int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount;
1003
1004 int32_t dvs = default_values.size();
1005#ifdef DEBUG_ENABLED
1006 if (missing > dvs) {
1007 r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
1008 r_error.argument = sizeof...(P);
1009 return;
1010 }
1011#endif
1012
1013 const Variant *args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; //avoid zero sized array
1014 for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) {
1015 if (i < p_argcount) {
1016 args[i] = p_args[i];
1017 } else {
1018 args[i] = &default_values[i - p_argcount + (dvs - missing)];
1019 }
1020 }
1021
1022 call_with_variant_args_static(p_method, args, r_error, BuildIndexSequence<sizeof...(P)>{});
1023}
1024
1025#if defined(__GNUC__) && !defined(__clang__)
1026#pragma GCC diagnostic pop
1027#endif
1028
1029#endif // BINDER_COMMON_H
1030