binder_common.h 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986
  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. #ifndef BINDER_COMMON_H
  31. #define BINDER_COMMON_H
  32. #include "core/input/input_enums.h"
  33. #include "core/object/object.h"
  34. #include "core/os/keyboard.h"
  35. #include "core/templates/list.h"
  36. #include "core/templates/simple_type.h"
  37. #include "core/typedefs.h"
  38. #include "core/variant/method_ptrcall.h"
  39. #include "core/variant/type_info.h"
  40. #include "core/variant/variant.h"
  41. #include "core/variant/variant_internal.h"
  42. #include <stdio.h>
  43. // Variant cannot define an implicit cast operator for every Object subclass, so the
  44. // casting is done here, to allow binding methods with parameters more specific than Object *
  45. template <class T>
  46. struct VariantCaster {
  47. static _FORCE_INLINE_ T cast(const Variant &p_variant) {
  48. using TStripped = std::remove_pointer_t<T>;
  49. if constexpr (std::is_base_of<Object, TStripped>::value) {
  50. return Object::cast_to<TStripped>(p_variant);
  51. } else {
  52. return p_variant;
  53. }
  54. }
  55. };
  56. template <class T>
  57. struct VariantCaster<T &> {
  58. static _FORCE_INLINE_ T cast(const Variant &p_variant) {
  59. using TStripped = std::remove_pointer_t<T>;
  60. if constexpr (std::is_base_of<Object, TStripped>::value) {
  61. return Object::cast_to<TStripped>(p_variant);
  62. } else {
  63. return p_variant;
  64. }
  65. }
  66. };
  67. template <class T>
  68. struct VariantCaster<const T &> {
  69. static _FORCE_INLINE_ T cast(const Variant &p_variant) {
  70. using TStripped = std::remove_pointer_t<T>;
  71. if constexpr (std::is_base_of<Object, TStripped>::value) {
  72. return Object::cast_to<TStripped>(p_variant);
  73. } else {
  74. return p_variant;
  75. }
  76. }
  77. };
  78. #define VARIANT_ENUM_CAST(m_enum) \
  79. MAKE_ENUM_TYPE_INFO(m_enum) \
  80. template <> \
  81. struct VariantCaster<m_enum> { \
  82. static _FORCE_INLINE_ m_enum cast(const Variant &p_variant) { \
  83. return (m_enum)p_variant.operator int64_t(); \
  84. } \
  85. }; \
  86. template <> \
  87. struct PtrToArg<m_enum> { \
  88. _FORCE_INLINE_ static m_enum convert(const void *p_ptr) { \
  89. return m_enum(*reinterpret_cast<const int64_t *>(p_ptr)); \
  90. } \
  91. typedef int64_t EncodeT; \
  92. _FORCE_INLINE_ static void encode(m_enum p_val, const void *p_ptr) { \
  93. *(int64_t *)p_ptr = (int64_t)p_val; \
  94. } \
  95. }; \
  96. template <> \
  97. struct ZeroInitializer<m_enum> { \
  98. static void initialize(m_enum &value) { value = (m_enum)0; } \
  99. };
  100. #define VARIANT_BITFIELD_CAST(m_enum) \
  101. MAKE_BITFIELD_TYPE_INFO(m_enum) \
  102. template <> \
  103. struct VariantCaster<BitField<m_enum>> { \
  104. static _FORCE_INLINE_ BitField<m_enum> cast(const Variant &p_variant) { \
  105. return BitField<m_enum>(p_variant.operator int64_t()); \
  106. } \
  107. }; \
  108. template <> \
  109. struct PtrToArg<BitField<m_enum>> { \
  110. _FORCE_INLINE_ static BitField<m_enum> convert(const void *p_ptr) { \
  111. return BitField<m_enum>(*reinterpret_cast<const int64_t *>(p_ptr)); \
  112. } \
  113. typedef int64_t EncodeT; \
  114. _FORCE_INLINE_ static void encode(BitField<m_enum> p_val, const void *p_ptr) { \
  115. *(int64_t *)p_ptr = p_val; \
  116. } \
  117. }; \
  118. template <> \
  119. struct ZeroInitializer<BitField<m_enum>> { \
  120. static void initialize(BitField<m_enum> &value) { value = 0; } \
  121. };
  122. // Object enum casts must go here
  123. VARIANT_ENUM_CAST(Object::ConnectFlags);
  124. VARIANT_ENUM_CAST(Vector2::Axis);
  125. VARIANT_ENUM_CAST(Vector2i::Axis);
  126. VARIANT_ENUM_CAST(Vector3::Axis);
  127. VARIANT_ENUM_CAST(Vector3i::Axis);
  128. VARIANT_ENUM_CAST(Vector4::Axis);
  129. VARIANT_ENUM_CAST(Vector4i::Axis);
  130. VARIANT_ENUM_CAST(EulerOrder);
  131. VARIANT_ENUM_CAST(Projection::Planes);
  132. VARIANT_ENUM_CAST(Error);
  133. VARIANT_ENUM_CAST(Side);
  134. VARIANT_ENUM_CAST(ClockDirection);
  135. VARIANT_ENUM_CAST(Corner);
  136. VARIANT_ENUM_CAST(HatDir);
  137. VARIANT_BITFIELD_CAST(HatMask);
  138. VARIANT_ENUM_CAST(JoyAxis);
  139. VARIANT_ENUM_CAST(JoyButton);
  140. VARIANT_ENUM_CAST(MIDIMessage);
  141. VARIANT_ENUM_CAST(MouseButton);
  142. VARIANT_BITFIELD_CAST(MouseButtonMask);
  143. VARIANT_ENUM_CAST(Orientation);
  144. VARIANT_ENUM_CAST(HorizontalAlignment);
  145. VARIANT_ENUM_CAST(VerticalAlignment);
  146. VARIANT_ENUM_CAST(InlineAlignment);
  147. VARIANT_ENUM_CAST(PropertyHint);
  148. VARIANT_BITFIELD_CAST(PropertyUsageFlags);
  149. VARIANT_ENUM_CAST(Variant::Type);
  150. VARIANT_ENUM_CAST(Variant::Operator);
  151. // Key
  152. VARIANT_ENUM_CAST(Key);
  153. VARIANT_BITFIELD_CAST(KeyModifierMask);
  154. static inline Key &operator|=(Key &a, BitField<KeyModifierMask> b) {
  155. a = static_cast<Key>(static_cast<int>(a) | static_cast<int>(b.operator int64_t()));
  156. return a;
  157. }
  158. static inline Key &operator&=(Key &a, BitField<KeyModifierMask> b) {
  159. a = static_cast<Key>(static_cast<int>(a) & static_cast<int>(b.operator int64_t()));
  160. return a;
  161. }
  162. static inline Key operator|(Key a, BitField<KeyModifierMask> b) {
  163. return (Key)((int)a | (int)b.operator int64_t());
  164. }
  165. static inline Key operator&(Key a, BitField<KeyModifierMask> b) {
  166. return (Key)((int)a & (int)b.operator int64_t());
  167. }
  168. static inline Key operator+(BitField<KeyModifierMask> a, Key b) {
  169. return (Key)((int)a.operator int64_t() + (int)b);
  170. }
  171. static inline Key operator|(BitField<KeyModifierMask> a, Key b) {
  172. return (Key)((int)a.operator int64_t() | (int)b);
  173. }
  174. template <>
  175. struct VariantCaster<char32_t> {
  176. static _FORCE_INLINE_ char32_t cast(const Variant &p_variant) {
  177. return (char32_t)p_variant.operator int();
  178. }
  179. };
  180. template <>
  181. struct PtrToArg<char32_t> {
  182. _FORCE_INLINE_ static char32_t convert(const void *p_ptr) {
  183. return char32_t(*reinterpret_cast<const int *>(p_ptr));
  184. }
  185. typedef int64_t EncodeT;
  186. _FORCE_INLINE_ static void encode(char32_t p_val, const void *p_ptr) {
  187. *(int *)p_ptr = p_val;
  188. }
  189. };
  190. template <typename T>
  191. struct VariantObjectClassChecker {
  192. static _FORCE_INLINE_ bool check(const Variant &p_variant) {
  193. using TStripped = std::remove_pointer_t<T>;
  194. if constexpr (std::is_base_of<Object, TStripped>::value) {
  195. Object *obj = p_variant;
  196. return Object::cast_to<TStripped>(p_variant) || !obj;
  197. } else {
  198. return true;
  199. }
  200. }
  201. };
  202. template <typename T>
  203. class Ref;
  204. template <typename T>
  205. struct VariantObjectClassChecker<const Ref<T> &> {
  206. static _FORCE_INLINE_ bool check(const Variant &p_variant) {
  207. Object *obj = p_variant;
  208. const Ref<T> node = p_variant;
  209. return node.ptr() || !obj;
  210. }
  211. };
  212. #ifdef DEBUG_METHODS_ENABLED
  213. template <class T>
  214. struct VariantCasterAndValidate {
  215. static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, Callable::CallError &r_error) {
  216. Variant::Type argtype = GetTypeInfo<T>::VARIANT_TYPE;
  217. if (!Variant::can_convert_strict(p_args[p_arg_idx]->get_type(), argtype) ||
  218. !VariantObjectClassChecker<T>::check(*p_args[p_arg_idx])) {
  219. r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
  220. r_error.argument = p_arg_idx;
  221. r_error.expected = argtype;
  222. }
  223. return VariantCaster<T>::cast(*p_args[p_arg_idx]);
  224. }
  225. };
  226. template <class T>
  227. struct VariantCasterAndValidate<T &> {
  228. static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, Callable::CallError &r_error) {
  229. Variant::Type argtype = GetTypeInfo<T>::VARIANT_TYPE;
  230. if (!Variant::can_convert_strict(p_args[p_arg_idx]->get_type(), argtype) ||
  231. !VariantObjectClassChecker<T>::check(*p_args[p_arg_idx])) {
  232. r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
  233. r_error.argument = p_arg_idx;
  234. r_error.expected = argtype;
  235. }
  236. return VariantCaster<T>::cast(*p_args[p_arg_idx]);
  237. }
  238. };
  239. template <class T>
  240. struct VariantCasterAndValidate<const T &> {
  241. static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, Callable::CallError &r_error) {
  242. Variant::Type argtype = GetTypeInfo<T>::VARIANT_TYPE;
  243. if (!Variant::can_convert_strict(p_args[p_arg_idx]->get_type(), argtype) ||
  244. !VariantObjectClassChecker<T>::check(*p_args[p_arg_idx])) {
  245. r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
  246. r_error.argument = p_arg_idx;
  247. r_error.expected = argtype;
  248. }
  249. return VariantCaster<T>::cast(*p_args[p_arg_idx]);
  250. }
  251. };
  252. #endif // DEBUG_METHODS_ENABLED
  253. template <class T, class... P, size_t... Is>
  254. void call_with_variant_args_helper(T *p_instance, void (T::*p_method)(P...), const Variant **p_args, Callable::CallError &r_error, IndexSequence<Is...>) {
  255. r_error.error = Callable::CallError::CALL_OK;
  256. #ifdef DEBUG_METHODS_ENABLED
  257. (p_instance->*p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
  258. #else
  259. (p_instance->*p_method)(VariantCaster<P>::cast(*p_args[Is])...);
  260. #endif
  261. (void)(p_args); //avoid warning
  262. }
  263. template <class T, class... P, size_t... Is>
  264. void call_with_variant_argsc_helper(T *p_instance, void (T::*p_method)(P...) const, const Variant **p_args, Callable::CallError &r_error, IndexSequence<Is...>) {
  265. r_error.error = Callable::CallError::CALL_OK;
  266. #ifdef DEBUG_METHODS_ENABLED
  267. (p_instance->*p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
  268. #else
  269. (p_instance->*p_method)(VariantCaster<P>::cast(*p_args[Is])...);
  270. #endif
  271. (void)(p_args); //avoid warning
  272. }
  273. template <class T, class... P, size_t... Is>
  274. void call_with_ptr_args_helper(T *p_instance, void (T::*p_method)(P...), const void **p_args, IndexSequence<Is...>) {
  275. (p_instance->*p_method)(PtrToArg<P>::convert(p_args[Is])...);
  276. }
  277. template <class T, class... P, size_t... Is>
  278. void call_with_ptr_argsc_helper(T *p_instance, void (T::*p_method)(P...) const, const void **p_args, IndexSequence<Is...>) {
  279. (p_instance->*p_method)(PtrToArg<P>::convert(p_args[Is])...);
  280. }
  281. template <class T, class R, class... P, size_t... Is>
  282. void call_with_ptr_args_ret_helper(T *p_instance, R (T::*p_method)(P...), const void **p_args, void *r_ret, IndexSequence<Is...>) {
  283. PtrToArg<R>::encode((p_instance->*p_method)(PtrToArg<P>::convert(p_args[Is])...), r_ret);
  284. }
  285. template <class T, class R, class... P, size_t... Is>
  286. void call_with_ptr_args_retc_helper(T *p_instance, R (T::*p_method)(P...) const, const void **p_args, void *r_ret, IndexSequence<Is...>) {
  287. PtrToArg<R>::encode((p_instance->*p_method)(PtrToArg<P>::convert(p_args[Is])...), r_ret);
  288. }
  289. template <class T, class... P, size_t... Is>
  290. void call_with_ptr_args_static_helper(T *p_instance, void (*p_method)(T *, P...), const void **p_args, IndexSequence<Is...>) {
  291. p_method(p_instance, PtrToArg<P>::convert(p_args[Is])...);
  292. }
  293. template <class T, class R, class... P, size_t... Is>
  294. void call_with_ptr_args_static_retc_helper(T *p_instance, R (*p_method)(T *, P...), const void **p_args, void *r_ret, IndexSequence<Is...>) {
  295. PtrToArg<R>::encode(p_method(p_instance, PtrToArg<P>::convert(p_args[Is])...), r_ret);
  296. }
  297. template <class R, class... P, size_t... Is>
  298. void call_with_ptr_args_static_method_ret_helper(R (*p_method)(P...), const void **p_args, void *r_ret, IndexSequence<Is...>) {
  299. PtrToArg<R>::encode(p_method(PtrToArg<P>::convert(p_args[Is])...), r_ret);
  300. }
  301. template <class... P, size_t... Is>
  302. void call_with_ptr_args_static_method_helper(void (*p_method)(P...), const void **p_args, IndexSequence<Is...>) {
  303. p_method(PtrToArg<P>::convert(p_args[Is])...);
  304. }
  305. template <class T, class... P, size_t... Is>
  306. void call_with_validated_variant_args_helper(T *p_instance, void (T::*p_method)(P...), const Variant **p_args, IndexSequence<Is...>) {
  307. (p_instance->*p_method)((VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...);
  308. }
  309. template <class T, class... P, size_t... Is>
  310. void call_with_validated_variant_argsc_helper(T *p_instance, void (T::*p_method)(P...) const, const Variant **p_args, IndexSequence<Is...>) {
  311. (p_instance->*p_method)((VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...);
  312. }
  313. template <class T, class R, class... P, size_t... Is>
  314. void call_with_validated_variant_args_ret_helper(T *p_instance, R (T::*p_method)(P...), const Variant **p_args, Variant *r_ret, IndexSequence<Is...>) {
  315. VariantInternalAccessor<typename GetSimpleTypeT<R>::type_t>::set(r_ret, (p_instance->*p_method)((VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...));
  316. }
  317. template <class T, class R, class... P, size_t... Is>
  318. void 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...>) {
  319. VariantInternalAccessor<typename GetSimpleTypeT<R>::type_t>::set(r_ret, (p_instance->*p_method)((VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...));
  320. }
  321. template <class T, class R, class... P, size_t... Is>
  322. void 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...>) {
  323. VariantInternalAccessor<typename GetSimpleTypeT<R>::type_t>::set(r_ret, p_method(p_instance, (VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...));
  324. }
  325. template <class T, class... P, size_t... Is>
  326. void call_with_validated_variant_args_static_helper(T *p_instance, void (*p_method)(T *, P...), const Variant **p_args, IndexSequence<Is...>) {
  327. p_method(p_instance, (VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...);
  328. }
  329. template <class R, class... P, size_t... Is>
  330. void call_with_validated_variant_args_static_method_ret_helper(R (*p_method)(P...), const Variant **p_args, Variant *r_ret, IndexSequence<Is...>) {
  331. VariantInternalAccessor<typename GetSimpleTypeT<R>::type_t>::set(r_ret, p_method((VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...));
  332. }
  333. template <class... P, size_t... Is>
  334. void call_with_validated_variant_args_static_method_helper(void (*p_method)(P...), const Variant **p_args, IndexSequence<Is...>) {
  335. p_method((VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...);
  336. }
  337. template <class T, class... P>
  338. void call_with_variant_args(T *p_instance, void (T::*p_method)(P...), const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
  339. #ifdef DEBUG_METHODS_ENABLED
  340. if ((size_t)p_argcount > sizeof...(P)) {
  341. r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
  342. r_error.argument = sizeof...(P);
  343. return;
  344. }
  345. if ((size_t)p_argcount < sizeof...(P)) {
  346. r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
  347. r_error.argument = sizeof...(P);
  348. return;
  349. }
  350. #endif
  351. call_with_variant_args_helper<T, P...>(p_instance, p_method, p_args, r_error, BuildIndexSequence<sizeof...(P)>{});
  352. }
  353. template <class T, class... P>
  354. void 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) {
  355. #ifdef DEBUG_ENABLED
  356. if ((size_t)p_argcount > sizeof...(P)) {
  357. r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
  358. r_error.argument = sizeof...(P);
  359. return;
  360. }
  361. #endif
  362. int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount;
  363. int32_t dvs = default_values.size();
  364. #ifdef DEBUG_ENABLED
  365. if (missing > dvs) {
  366. r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
  367. r_error.argument = sizeof...(P);
  368. return;
  369. }
  370. #endif
  371. const Variant *args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; //avoid zero sized array
  372. for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) {
  373. if (i < p_argcount) {
  374. args[i] = p_args[i];
  375. } else {
  376. args[i] = &default_values[i - p_argcount + (dvs - missing)];
  377. }
  378. }
  379. call_with_variant_args_helper(p_instance, p_method, args, r_error, BuildIndexSequence<sizeof...(P)>{});
  380. }
  381. template <class T, class... P>
  382. void call_with_variant_argsc(T *p_instance, void (T::*p_method)(P...) const, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
  383. #ifdef DEBUG_METHODS_ENABLED
  384. if ((size_t)p_argcount > sizeof...(P)) {
  385. r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
  386. r_error.argument = sizeof...(P);
  387. return;
  388. }
  389. if ((size_t)p_argcount < sizeof...(P)) {
  390. r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
  391. r_error.argument = sizeof...(P);
  392. return;
  393. }
  394. #endif
  395. call_with_variant_args_helper<T, P...>(p_instance, p_method, p_args, r_error, BuildIndexSequence<sizeof...(P)>{});
  396. }
  397. template <class T, class... P>
  398. void 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) {
  399. #ifdef DEBUG_ENABLED
  400. if ((size_t)p_argcount > sizeof...(P)) {
  401. r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
  402. r_error.argument = sizeof...(P);
  403. return;
  404. }
  405. #endif
  406. int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount;
  407. int32_t dvs = default_values.size();
  408. #ifdef DEBUG_ENABLED
  409. if (missing > dvs) {
  410. r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
  411. r_error.argument = sizeof...(P);
  412. return;
  413. }
  414. #endif
  415. const Variant *args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; //avoid zero sized array
  416. for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) {
  417. if (i < p_argcount) {
  418. args[i] = p_args[i];
  419. } else {
  420. args[i] = &default_values[i - p_argcount + (dvs - missing)];
  421. }
  422. }
  423. call_with_variant_argsc_helper(p_instance, p_method, args, r_error, BuildIndexSequence<sizeof...(P)>{});
  424. }
  425. template <class T, class R, class... P>
  426. void 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) {
  427. #ifdef DEBUG_ENABLED
  428. if ((size_t)p_argcount > sizeof...(P)) {
  429. r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
  430. r_error.argument = sizeof...(P);
  431. return;
  432. }
  433. #endif
  434. int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount;
  435. int32_t dvs = default_values.size();
  436. #ifdef DEBUG_ENABLED
  437. if (missing > dvs) {
  438. r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
  439. r_error.argument = sizeof...(P);
  440. return;
  441. }
  442. #endif
  443. const Variant *args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; //avoid zero sized array
  444. for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) {
  445. if (i < p_argcount) {
  446. args[i] = p_args[i];
  447. } else {
  448. args[i] = &default_values[i - p_argcount + (dvs - missing)];
  449. }
  450. }
  451. call_with_variant_args_ret_helper(p_instance, p_method, args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
  452. }
  453. template <class T, class R, class... P>
  454. void 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) {
  455. #ifdef DEBUG_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. #endif
  462. int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount;
  463. int32_t dvs = default_values.size();
  464. #ifdef DEBUG_ENABLED
  465. if (missing > dvs) {
  466. r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
  467. r_error.argument = sizeof...(P);
  468. return;
  469. }
  470. #endif
  471. const Variant *args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; //avoid zero sized array
  472. for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) {
  473. if (i < p_argcount) {
  474. args[i] = p_args[i];
  475. } else {
  476. args[i] = &default_values[i - p_argcount + (dvs - missing)];
  477. }
  478. }
  479. call_with_variant_args_retc_helper(p_instance, p_method, args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
  480. }
  481. template <class T, class... P>
  482. void call_with_ptr_args(T *p_instance, void (T::*p_method)(P...), const void **p_args) {
  483. call_with_ptr_args_helper<T, P...>(p_instance, p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
  484. }
  485. template <class T, class... P>
  486. void call_with_ptr_argsc(T *p_instance, void (T::*p_method)(P...) const, const void **p_args) {
  487. call_with_ptr_argsc_helper<T, P...>(p_instance, p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
  488. }
  489. template <class T, class R, class... P>
  490. void call_with_ptr_args_ret(T *p_instance, R (T::*p_method)(P...), const void **p_args, void *r_ret) {
  491. call_with_ptr_args_ret_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
  492. }
  493. template <class T, class R, class... P>
  494. void call_with_ptr_args_retc(T *p_instance, R (T::*p_method)(P...) const, const void **p_args, void *r_ret) {
  495. call_with_ptr_args_retc_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
  496. }
  497. template <class T, class... P>
  498. void call_with_ptr_args_static(T *p_instance, void (*p_method)(T *, P...), const void **p_args) {
  499. call_with_ptr_args_static_helper<T, P...>(p_instance, p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
  500. }
  501. template <class T, class R, class... P>
  502. void call_with_ptr_args_static_retc(T *p_instance, R (*p_method)(T *, P...), const void **p_args, void *r_ret) {
  503. call_with_ptr_args_static_retc_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
  504. }
  505. template <class R, class... P>
  506. void call_with_ptr_args_static_method_ret(R (*p_method)(P...), const void **p_args, void *r_ret) {
  507. call_with_ptr_args_static_method_ret_helper<R, P...>(p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
  508. }
  509. template <class... P>
  510. void call_with_ptr_args_static_method(void (*p_method)(P...), const void **p_args) {
  511. call_with_ptr_args_static_method_helper<P...>(p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
  512. }
  513. template <class T, class... P>
  514. void call_with_validated_variant_args(Variant *base, void (T::*p_method)(P...), const Variant **p_args) {
  515. call_with_validated_variant_args_helper<T, P...>(VariantGetInternalPtr<T>::get_ptr(base), p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
  516. }
  517. template <class T, class R, class... P>
  518. void call_with_validated_variant_args_ret(Variant *base, R (T::*p_method)(P...), const Variant **p_args, Variant *r_ret) {
  519. call_with_validated_variant_args_ret_helper<T, R, P...>(VariantGetInternalPtr<T>::get_ptr(base), p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
  520. }
  521. template <class T, class R, class... P>
  522. void call_with_validated_variant_args_retc(Variant *base, R (T::*p_method)(P...) const, const Variant **p_args, Variant *r_ret) {
  523. call_with_validated_variant_args_retc_helper<T, R, P...>(VariantGetInternalPtr<T>::get_ptr(base), p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
  524. }
  525. template <class T, class... P>
  526. void call_with_validated_variant_args_static(Variant *base, void (*p_method)(T *, P...), const Variant **p_args) {
  527. call_with_validated_variant_args_static_helper<T, P...>(VariantGetInternalPtr<T>::get_ptr(base), p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
  528. }
  529. template <class T, class R, class... P>
  530. void call_with_validated_variant_args_static_retc(Variant *base, R (*p_method)(T *, P...), const Variant **p_args, Variant *r_ret) {
  531. 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)>{});
  532. }
  533. template <class... P>
  534. void call_with_validated_variant_args_static_method(void (*p_method)(P...), const Variant **p_args) {
  535. call_with_validated_variant_args_static_method_helper<P...>(p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
  536. }
  537. template <class R, class... P>
  538. void call_with_validated_variant_args_static_method_ret(R (*p_method)(P...), const Variant **p_args, Variant *r_ret) {
  539. call_with_validated_variant_args_static_method_ret_helper<R, P...>(p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
  540. }
  541. // GCC raises "parameter 'p_args' set but not used" when P = {},
  542. // it's not clever enough to treat other P values as making this branch valid.
  543. #if defined(__GNUC__) && !defined(__clang__)
  544. #pragma GCC diagnostic push
  545. #pragma GCC diagnostic ignored "-Wunused-but-set-parameter"
  546. #endif
  547. template <class Q>
  548. void call_get_argument_type_helper(int p_arg, int &index, Variant::Type &type) {
  549. if (p_arg == index) {
  550. type = GetTypeInfo<Q>::VARIANT_TYPE;
  551. }
  552. index++;
  553. }
  554. template <class... P>
  555. Variant::Type call_get_argument_type(int p_arg) {
  556. Variant::Type type = Variant::NIL;
  557. int index = 0;
  558. // I think rocket science is simpler than modern C++.
  559. using expand_type = int[];
  560. expand_type a{ 0, (call_get_argument_type_helper<P>(p_arg, index, type), 0)... };
  561. (void)a; // Suppress (valid, but unavoidable) -Wunused-variable warning.
  562. (void)index; // Suppress GCC warning.
  563. return type;
  564. }
  565. template <class Q>
  566. void call_get_argument_type_info_helper(int p_arg, int &index, PropertyInfo &info) {
  567. if (p_arg == index) {
  568. info = GetTypeInfo<Q>::get_class_info();
  569. }
  570. index++;
  571. }
  572. template <class... P>
  573. void call_get_argument_type_info(int p_arg, PropertyInfo &info) {
  574. int index = 0;
  575. // I think rocket science is simpler than modern C++.
  576. using expand_type = int[];
  577. expand_type a{ 0, (call_get_argument_type_info_helper<P>(p_arg, index, info), 0)... };
  578. (void)a; // Suppress (valid, but unavoidable) -Wunused-variable warning.
  579. (void)index; // Suppress GCC warning.
  580. }
  581. #ifdef DEBUG_METHODS_ENABLED
  582. template <class Q>
  583. void call_get_argument_metadata_helper(int p_arg, int &index, GodotTypeInfo::Metadata &md) {
  584. if (p_arg == index) {
  585. md = GetTypeInfo<Q>::METADATA;
  586. }
  587. index++;
  588. }
  589. template <class... P>
  590. GodotTypeInfo::Metadata call_get_argument_metadata(int p_arg) {
  591. GodotTypeInfo::Metadata md = GodotTypeInfo::METADATA_NONE;
  592. int index = 0;
  593. // I think rocket science is simpler than modern C++.
  594. using expand_type = int[];
  595. expand_type a{ 0, (call_get_argument_metadata_helper<P>(p_arg, index, md), 0)... };
  596. (void)a; // Suppress (valid, but unavoidable) -Wunused-variable warning.
  597. (void)index;
  598. return md;
  599. }
  600. #endif // DEBUG_METHODS_ENABLED
  601. //////////////////////
  602. template <class T, class R, class... P, size_t... Is>
  603. void 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...>) {
  604. r_error.error = Callable::CallError::CALL_OK;
  605. #ifdef DEBUG_METHODS_ENABLED
  606. r_ret = (p_instance->*p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
  607. #else
  608. r_ret = (p_instance->*p_method)(VariantCaster<P>::cast(*p_args[Is])...);
  609. #endif
  610. }
  611. template <class R, class... P, size_t... Is>
  612. void call_with_variant_args_static_ret(R (*p_method)(P...), const Variant **p_args, Variant &r_ret, Callable::CallError &r_error, IndexSequence<Is...>) {
  613. r_error.error = Callable::CallError::CALL_OK;
  614. #ifdef DEBUG_METHODS_ENABLED
  615. r_ret = (p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
  616. #else
  617. r_ret = (p_method)(VariantCaster<P>::cast(*p_args[Is])...);
  618. #endif
  619. }
  620. template <class... P, size_t... Is>
  621. void call_with_variant_args_static(void (*p_method)(P...), const Variant **p_args, Callable::CallError &r_error, IndexSequence<Is...>) {
  622. r_error.error = Callable::CallError::CALL_OK;
  623. #ifdef DEBUG_METHODS_ENABLED
  624. (p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
  625. #else
  626. (p_method)(VariantCaster<P>::cast(*p_args[Is])...);
  627. #endif
  628. }
  629. template <class T, class R, class... P>
  630. void 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) {
  631. #ifdef DEBUG_METHODS_ENABLED
  632. if ((size_t)p_argcount > sizeof...(P)) {
  633. r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
  634. r_error.argument = sizeof...(P);
  635. return;
  636. }
  637. if ((size_t)p_argcount < sizeof...(P)) {
  638. r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
  639. r_error.argument = sizeof...(P);
  640. return;
  641. }
  642. #endif
  643. call_with_variant_args_ret_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
  644. }
  645. template <class T, class R, class... P, size_t... Is>
  646. void 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...>) {
  647. r_error.error = Callable::CallError::CALL_OK;
  648. #ifdef DEBUG_METHODS_ENABLED
  649. r_ret = (p_instance->*p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
  650. #else
  651. r_ret = (p_instance->*p_method)(VariantCaster<P>::cast(*p_args[Is])...);
  652. #endif
  653. (void)p_args;
  654. }
  655. template <class R, class... P>
  656. void call_with_variant_args_static_ret(R (*p_method)(P...), const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
  657. #ifdef DEBUG_METHODS_ENABLED
  658. if ((size_t)p_argcount > sizeof...(P)) {
  659. r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
  660. r_error.argument = sizeof...(P);
  661. return;
  662. }
  663. if ((size_t)p_argcount < sizeof...(P)) {
  664. r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
  665. r_error.argument = sizeof...(P);
  666. return;
  667. }
  668. #endif
  669. call_with_variant_args_static_ret<R, P...>(p_method, p_args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
  670. }
  671. template <class... P>
  672. void call_with_variant_args_static_ret(void (*p_method)(P...), const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
  673. #ifdef DEBUG_METHODS_ENABLED
  674. if ((size_t)p_argcount > sizeof...(P)) {
  675. r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
  676. r_error.argument = sizeof...(P);
  677. return;
  678. }
  679. if ((size_t)p_argcount < sizeof...(P)) {
  680. r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
  681. r_error.argument = sizeof...(P);
  682. return;
  683. }
  684. #endif
  685. call_with_variant_args_static<P...>(p_method, p_args, r_error, BuildIndexSequence<sizeof...(P)>{});
  686. }
  687. template <class T, class R, class... P>
  688. void 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) {
  689. #ifdef DEBUG_METHODS_ENABLED
  690. if ((size_t)p_argcount > sizeof...(P)) {
  691. r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
  692. r_error.argument = sizeof...(P);
  693. return;
  694. }
  695. if ((size_t)p_argcount < sizeof...(P)) {
  696. r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
  697. r_error.argument = sizeof...(P);
  698. return;
  699. }
  700. #endif
  701. call_with_variant_args_retc_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
  702. }
  703. template <class T, class R, class... P, size_t... Is>
  704. void 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...>) {
  705. r_error.error = Callable::CallError::CALL_OK;
  706. #ifdef DEBUG_METHODS_ENABLED
  707. r_ret = (p_method)(p_instance, VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
  708. #else
  709. r_ret = (p_method)(p_instance, VariantCaster<P>::cast(*p_args[Is])...);
  710. #endif
  711. (void)p_args;
  712. }
  713. template <class T, class R, class... P>
  714. void 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) {
  715. #ifdef DEBUG_ENABLED
  716. if ((size_t)p_argcount > sizeof...(P)) {
  717. r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
  718. r_error.argument = sizeof...(P);
  719. return;
  720. }
  721. #endif
  722. int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount;
  723. int32_t dvs = default_values.size();
  724. #ifdef DEBUG_ENABLED
  725. if (missing > dvs) {
  726. r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
  727. r_error.argument = sizeof...(P);
  728. return;
  729. }
  730. #endif
  731. const Variant *args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; //avoid zero sized array
  732. for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) {
  733. if (i < p_argcount) {
  734. args[i] = p_args[i];
  735. } else {
  736. args[i] = &default_values[i - p_argcount + (dvs - missing)];
  737. }
  738. }
  739. call_with_variant_args_retc_static_helper(p_instance, p_method, args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
  740. }
  741. template <class T, class... P, size_t... Is>
  742. void call_with_variant_args_static_helper(T *p_instance, void (*p_method)(T *, P...), const Variant **p_args, Callable::CallError &r_error, IndexSequence<Is...>) {
  743. r_error.error = Callable::CallError::CALL_OK;
  744. #ifdef DEBUG_METHODS_ENABLED
  745. (p_method)(p_instance, VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
  746. #else
  747. (p_method)(p_instance, VariantCaster<P>::cast(*p_args[Is])...);
  748. #endif
  749. (void)p_args;
  750. }
  751. template <class T, class... P>
  752. void 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) {
  753. #ifdef DEBUG_ENABLED
  754. if ((size_t)p_argcount > sizeof...(P)) {
  755. r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
  756. r_error.argument = sizeof...(P);
  757. return;
  758. }
  759. #endif
  760. int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount;
  761. int32_t dvs = default_values.size();
  762. #ifdef DEBUG_ENABLED
  763. if (missing > dvs) {
  764. r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
  765. r_error.argument = sizeof...(P);
  766. return;
  767. }
  768. #endif
  769. const Variant *args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; //avoid zero sized array
  770. for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) {
  771. if (i < p_argcount) {
  772. args[i] = p_args[i];
  773. } else {
  774. args[i] = &default_values[i - p_argcount + (dvs - missing)];
  775. }
  776. }
  777. call_with_variant_args_static_helper(p_instance, p_method, args, r_error, BuildIndexSequence<sizeof...(P)>{});
  778. }
  779. template <class R, class... P>
  780. void 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) {
  781. #ifdef DEBUG_ENABLED
  782. if ((size_t)p_argcount > sizeof...(P)) {
  783. r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
  784. r_error.argument = sizeof...(P);
  785. return;
  786. }
  787. #endif
  788. int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount;
  789. int32_t dvs = default_values.size();
  790. #ifdef DEBUG_ENABLED
  791. if (missing > dvs) {
  792. r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
  793. r_error.argument = sizeof...(P);
  794. return;
  795. }
  796. #endif
  797. const Variant *args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; //avoid zero sized array
  798. for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) {
  799. if (i < p_argcount) {
  800. args[i] = p_args[i];
  801. } else {
  802. args[i] = &default_values[i - p_argcount + (dvs - missing)];
  803. }
  804. }
  805. call_with_variant_args_static_ret(p_method, args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
  806. }
  807. template <class... P>
  808. void 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) {
  809. #ifdef DEBUG_ENABLED
  810. if ((size_t)p_argcount > sizeof...(P)) {
  811. r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
  812. r_error.argument = sizeof...(P);
  813. return;
  814. }
  815. #endif
  816. int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount;
  817. int32_t dvs = default_values.size();
  818. #ifdef DEBUG_ENABLED
  819. if (missing > dvs) {
  820. r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
  821. r_error.argument = sizeof...(P);
  822. return;
  823. }
  824. #endif
  825. const Variant *args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; //avoid zero sized array
  826. for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) {
  827. if (i < p_argcount) {
  828. args[i] = p_args[i];
  829. } else {
  830. args[i] = &default_values[i - p_argcount + (dvs - missing)];
  831. }
  832. }
  833. call_with_variant_args_static(p_method, args, r_error, BuildIndexSequence<sizeof...(P)>{});
  834. }
  835. #if defined(__GNUC__) && !defined(__clang__)
  836. #pragma GCC diagnostic pop
  837. #endif
  838. #endif // BINDER_COMMON_H