) {
+ (p_instance->*p_method)(PtrToArg::convert(p_args[Is])...);
+}
+
+template
+void call_with_ptr_argsc_helper(T *p_instance, void (T::*p_method)(P...) const, const GDExtensionConstTypePtr *p_args, IndexSequence) {
+ (p_instance->*p_method)(PtrToArg::convert(p_args[Is])...);
+}
+
+template
+void call_with_ptr_args_ret_helper(T *p_instance, R (T::*p_method)(P...), const GDExtensionConstTypePtr *p_args, void *r_ret, IndexSequence) {
+ PtrToArg::encode((p_instance->*p_method)(PtrToArg::convert(p_args[Is])...), r_ret);
+}
+
+template
+void call_with_ptr_args_retc_helper(T *p_instance, R (T::*p_method)(P...) const, const GDExtensionConstTypePtr *p_args, void *r_ret, IndexSequence) {
+ PtrToArg::encode((p_instance->*p_method)(PtrToArg::convert(p_args[Is])...), r_ret);
+}
+
+template
+void call_with_ptr_args(T *p_instance, void (T::*p_method)(P...), const GDExtensionConstTypePtr *p_args, void * /*ret*/) {
+ call_with_ptr_args_helper(p_instance, p_method, p_args, BuildIndexSequence{});
+}
+
+template
+void call_with_ptr_args(T *p_instance, void (T::*p_method)(P...) const, const GDExtensionConstTypePtr *p_args, void * /*ret*/) {
+ call_with_ptr_argsc_helper(p_instance, p_method, p_args, BuildIndexSequence{});
+}
+
+template
+void call_with_ptr_args(T *p_instance, R (T::*p_method)(P...), const GDExtensionConstTypePtr *p_args, void *r_ret) {
+ call_with_ptr_args_ret_helper(p_instance, p_method, p_args, r_ret, BuildIndexSequence{});
+}
+
+template
+void call_with_ptr_args(T *p_instance, R (T::*p_method)(P...) const, const GDExtensionConstTypePtr *p_args, void *r_ret) {
+ call_with_ptr_args_retc_helper(p_instance, p_method, p_args, r_ret, BuildIndexSequence{});
+}
+
+template
+void call_with_variant_args_helper(T *p_instance, void (T::*p_method)(P...), const Variant **p_args, GDExtensionCallError &r_error, IndexSequence) {
+ r_error.error = GDEXTENSION_CALL_OK;
+
+#ifdef DEBUG_METHODS_ENABLED
+ (p_instance->*p_method)(VariantCasterAndValidate::cast(p_args, Is, r_error)...);
+#else
+ (p_instance->*p_method)(VariantCaster
::cast(*p_args[Is])...);
+#endif
+ (void)(p_args); // Avoid warning.
+}
+
+template
+void call_with_variant_argsc_helper(T *p_instance, void (T::*p_method)(P...) const, const Variant **p_args, GDExtensionCallError &r_error, IndexSequence) {
+ r_error.error = GDEXTENSION_CALL_OK;
+
+#ifdef DEBUG_METHODS_ENABLED
+ (p_instance->*p_method)(VariantCasterAndValidate::cast(p_args, Is, r_error)...);
+#else
+ (p_instance->*p_method)(VariantCaster
::cast(*p_args[Is])...);
+#endif
+ (void)(p_args); // Avoid warning.
+}
+
+template
+void call_with_variant_args_ret_helper(T *p_instance, R (T::*p_method)(P...), const Variant **p_args, Variant &r_ret, GDExtensionCallError &r_error, IndexSequence) {
+ r_error.error = GDEXTENSION_CALL_OK;
+
+#ifdef DEBUG_METHODS_ENABLED
+ r_ret = (p_instance->*p_method)(VariantCasterAndValidate::cast(p_args, Is, r_error)...);
+#else
+ r_ret = (p_instance->*p_method)(VariantCaster
::cast(*p_args[Is])...);
+#endif
+}
+
+template
+void call_with_variant_args_retc_helper(T *p_instance, R (T::*p_method)(P...) const, const Variant **p_args, Variant &r_ret, GDExtensionCallError &r_error, IndexSequence) {
+ r_error.error = GDEXTENSION_CALL_OK;
+
+#ifdef DEBUG_METHODS_ENABLED
+ r_ret = (p_instance->*p_method)(VariantCasterAndValidate::cast(p_args, Is, r_error)...);
+#else
+ r_ret = (p_instance->*p_method)(VariantCaster
::cast(*p_args[Is])...);
+#endif
+ (void)p_args;
+}
+
+template
+void call_with_variant_args_dv(T *p_instance, void (T::*p_method)(P...), const GDExtensionConstVariantPtr *p_args, int p_argcount, GDExtensionCallError &r_error, const std::vector &default_values) {
+#ifdef DEBUG_ENABLED
+ if ((size_t)p_argcount > sizeof...(P)) {
+ r_error.error = GDEXTENSION_CALL_ERROR_TOO_MANY_ARGUMENTS;
+ r_error.argument = (int32_t)sizeof...(P);
+ return;
+ }
+#endif
+
+ int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount;
+
+ int32_t dvs = (int32_t)default_values.size();
+#ifdef DEBUG_ENABLED
+ if (missing > dvs) {
+ r_error.error = GDEXTENSION_CALL_ERROR_TOO_FEW_ARGUMENTS;
+ r_error.argument = (int32_t)sizeof...(P);
+ return;
+ }
+#endif
+
+ Variant args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; // Avoid zero sized array.
+ std::array argsp;
+ for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) {
+ if (i < p_argcount) {
+ args[i] = Variant(p_args[i]);
+ } else {
+ args[i] = default_values[i - p_argcount + (dvs - missing)];
+ }
+ argsp[i] = &args[i];
+ }
+
+ call_with_variant_args_helper(p_instance, p_method, argsp.data(), r_error, BuildIndexSequence{});
+}
+
+template
+void call_with_variant_argsc_dv(T *p_instance, void (T::*p_method)(P...) const, const GDExtensionConstVariantPtr *p_args, int p_argcount, GDExtensionCallError &r_error, const std::vector