/* methods_closures.c generated by valac, the Vala compiler
 * generated from methods_closures.vala, do not modify */

#include <glib.h>
#include <glib-object.h>

#if !defined(VALA_STRICT_C)
#if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ >= 14)
#pragma GCC diagnostic warning "-Wincompatible-pointer-types"
#elif defined(__clang__) && (__clang_major__ >= 16)
#pragma clang diagnostic ignored "-Wincompatible-function-pointer-types"
#pragma clang diagnostic ignored "-Wincompatible-pointer-types"
#endif
#endif
#if !defined(VALA_EXTERN)
#if defined(_MSC_VER)
#define VALA_EXTERN __declspec(dllexport) extern
#elif __GNUC__ >= 4
#define VALA_EXTERN __attribute__((visibility("default"))) extern
#else
#define VALA_EXTERN extern
#endif
#endif

typedef gint (*Func) (gpointer user_data);

#define TYPE_FOO (foo_get_type ())
#define FOO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_FOO, Foo))
#define FOO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_FOO, FooClass))
#define IS_FOO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_FOO))
#define IS_FOO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_FOO))
#define FOO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_FOO, FooClass))

typedef struct _Foo Foo;
typedef struct _FooClass FooClass;
typedef struct _FooPrivate FooPrivate;
enum  {
	FOO_0_PROPERTY,
	FOO_NUM_PROPERTIES
};
static GParamSpec* foo_properties[FOO_NUM_PROPERTIES];
#define _g_main_loop_unref0(var) ((var == NULL) ? NULL : (var = (g_main_loop_unref (var), NULL)))
typedef struct _Block1Data Block1Data;
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
typedef void (*NoTargetFunc) (void);
typedef struct _Block2Data Block2Data;
typedef struct _Block3Data Block3Data;
#define _vala_assert(expr, msg) if G_LIKELY (expr) ; else g_assertion_message_expr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
#define _vala_return_if_fail(expr, msg) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return; }
#define _vala_return_val_if_fail(expr, msg, val) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return val; }
#define _vala_warn_if_fail(expr, msg) if G_LIKELY (expr) ; else g_warn_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);

struct _Foo {
	GObject parent_instance;
	FooPrivate * priv;
};

struct _FooClass {
	GObjectClass parent_class;
};

struct _Block1Data {
	int _ref_count_;
	Foo* self;
	GObject* o;
	GMainLoop* loop;
};

struct _Block2Data {
	int _ref_count_;
	Func B;
	gpointer B_target;
	GDestroyNotify B_target_destroy_notify;
	gint k;
	Func x1;
	gpointer x1_target;
	Func x2;
	gpointer x2_target;
	Func x3;
	gpointer x3_target;
	Func x4;
	gpointer x4_target;
};

struct _Block3Data {
	int _ref_count_;
	gint* array;
	NoTargetFunc func;
};

static gpointer foo_parent_class = NULL;

VALA_EXTERN GType foo_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (Foo, g_object_unref)
VALA_EXTERN void foo_bar (Foo* self,
              GMainLoop* loop);
static Block1Data* block1_data_ref (Block1Data* _data1_);
static void block1_data_unref (void * _userdata_);
static gboolean __lambda4_ (Block1Data* _data1_);
static gboolean ___lambda4__gsource_func (gpointer self);
VALA_EXTERN Foo* foo_new (void);
VALA_EXTERN Foo* foo_construct (GType object_type);
static GType foo_get_type_once (void);
VALA_EXTERN gint A (gint k,
        Func x1,
        gpointer x1_target,
        Func x2,
        gpointer x2_target,
        Func x3,
        gpointer x3_target,
        Func x4,
        gpointer x4_target,
        Func x5,
        gpointer x5_target);
static Block2Data* block2_data_ref (Block2Data* _data2_);
static void block2_data_unref (void * _userdata_);
static gint __lambda5_ (Block2Data* _data2_);
static gint ___lambda5__func (gpointer self);
VALA_EXTERN void B (gint* array,
        NoTargetFunc func);
static Block3Data* block3_data_ref (Block3Data* _data3_);
static void block3_data_unref (void * _userdata_);
static gint __lambda6_ (Block3Data* _data3_);
static gint ___lambda6__func (gpointer self);
static void _vala_main (void);
static gint __lambda7_ (void);
static gint ___lambda7__func (gpointer self);
static gint __lambda8_ (void);
static gint ___lambda8__func (gpointer self);
static gint __lambda9_ (void);
static gint ___lambda9__func (gpointer self);
static gint __lambda10_ (void);
static gint ___lambda10__func (gpointer self);
static gint __lambda11_ (void);
static gint ___lambda11__func (gpointer self);
static gssize _vala_array_length (gpointer array);

static gpointer
_g_main_loop_ref0 (gpointer self)
{
	return self ? g_main_loop_ref (self) : NULL;
}

static Block1Data*
block1_data_ref (Block1Data* _data1_)
{
	g_atomic_int_inc (&_data1_->_ref_count_);
	return _data1_;
}

static void
block1_data_unref (void * _userdata_)
{
	Block1Data* _data1_;
	_data1_ = (Block1Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data1_->_ref_count_)) {
		Foo* self;
		self = _data1_->self;
		_g_object_unref0 (_data1_->o);
		_g_main_loop_unref0 (_data1_->loop);
		_g_object_unref0 (self);
		g_slice_free (Block1Data, _data1_);
	}
}

static gboolean
__lambda4_ (Block1Data* _data1_)
{
	Foo* self;
	gboolean result;
	self = _data1_->self;
	_g_object_unref0 (_data1_->o);
	_data1_->o = NULL;
	g_main_loop_quit (_data1_->loop);
	result = FALSE;
	return result;
}

static gboolean
___lambda4__gsource_func (gpointer self)
{
	gboolean result;
	result = __lambda4_ (self);
	return result;
}

void
foo_bar (Foo* self,
         GMainLoop* loop)
{
	Block1Data* _data1_;
	GMainLoop* _tmp0_;
	GObject* _tmp1_;
	GSourceFunc f = NULL;
	gpointer f_target;
	GDestroyNotify f_target_destroy_notify;
	GSourceFunc _tmp2_;
	gpointer _tmp2__target;
	GDestroyNotify _tmp2__target_destroy_notify;
	g_return_if_fail (IS_FOO (self));
	g_return_if_fail (loop != NULL);
	_data1_ = g_slice_new0 (Block1Data);
	_data1_->_ref_count_ = 1;
	_data1_->self = g_object_ref (self);
	_tmp0_ = _g_main_loop_ref0 (loop);
	_g_main_loop_unref0 (_data1_->loop);
	_data1_->loop = _tmp0_;
	_tmp1_ = g_object_new (G_TYPE_OBJECT, NULL);
	_data1_->o = _tmp1_;
	f = ___lambda4__gsource_func;
	f_target = block1_data_ref (_data1_);
	f_target_destroy_notify = block1_data_unref;
	_tmp2_ = f;
	_tmp2__target = f_target;
	_tmp2__target_destroy_notify = f_target_destroy_notify;
	f = NULL;
	f_target = NULL;
	f_target_destroy_notify = NULL;
	g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, _tmp2_, _tmp2__target, _tmp2__target_destroy_notify);
	(f_target_destroy_notify == NULL) ? NULL : (f_target_destroy_notify (f_target), NULL);
	f = NULL;
	f_target = NULL;
	f_target_destroy_notify = NULL;
	block1_data_unref (_data1_);
	_data1_ = NULL;
}

Foo*
foo_construct (GType object_type)
{
	Foo * self = NULL;
	self = (Foo*) g_object_new (object_type, NULL);
	return self;
}

Foo*
foo_new (void)
{
	return foo_construct (TYPE_FOO);
}

static void
foo_class_init (FooClass * klass,
                gpointer klass_data)
{
	foo_parent_class = g_type_class_peek_parent (klass);
}

static void
foo_instance_init (Foo * self,
                   gpointer klass)
{
}

static GType
foo_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (FooClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) foo_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (Foo), 0, (GInstanceInitFunc) foo_instance_init, NULL };
	GType foo_type_id;
	foo_type_id = g_type_register_static (G_TYPE_OBJECT, "Foo", &g_define_type_info, 0);
	return foo_type_id;
}

GType
foo_get_type (void)
{
	static volatile gsize foo_type_id__once = 0;
	if (g_once_init_enter (&foo_type_id__once)) {
		GType foo_type_id;
		foo_type_id = foo_get_type_once ();
		g_once_init_leave (&foo_type_id__once, foo_type_id);
	}
	return foo_type_id__once;
}

static Block2Data*
block2_data_ref (Block2Data* _data2_)
{
	g_atomic_int_inc (&_data2_->_ref_count_);
	return _data2_;
}

static void
block2_data_unref (void * _userdata_)
{
	Block2Data* _data2_;
	_data2_ = (Block2Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data2_->_ref_count_)) {
		(_data2_->B_target_destroy_notify == NULL) ? NULL : (_data2_->B_target_destroy_notify (_data2_->B_target), NULL);
		_data2_->B = NULL;
		_data2_->B_target = NULL;
		_data2_->B_target_destroy_notify = NULL;
		g_slice_free (Block2Data, _data2_);
	}
}

static gint
__lambda5_ (Block2Data* _data2_)
{
	Func _tmp0_;
	gpointer _tmp0__target;
	gint result;
	_data2_->k = _data2_->k - 1;
	_tmp0_ = _data2_->B;
	_tmp0__target = _data2_->B_target;
	result = A (_data2_->k, _tmp0_, _tmp0__target, _data2_->x1, _data2_->x1_target, _data2_->x2, _data2_->x2_target, _data2_->x3, _data2_->x3_target, _data2_->x4, _data2_->x4_target);
	return result;
}

static gint
___lambda5__func (gpointer self)
{
	gint result;
	result = __lambda5_ (self);
	return result;
}

gint
A (gint k,
   Func x1,
   gpointer x1_target,
   Func x2,
   gpointer x2_target,
   Func x3,
   gpointer x3_target,
   Func x4,
   gpointer x4_target,
   Func x5,
   gpointer x5_target)
{
	Block2Data* _data2_;
	gint _tmp0_ = 0;
	gint result;
	_data2_ = g_slice_new0 (Block2Data);
	_data2_->_ref_count_ = 1;
	_data2_->k = k;
	_data2_->x1 = x1;
	_data2_->x1_target = x1_target;
	_data2_->x2 = x2;
	_data2_->x2_target = x2_target;
	_data2_->x3 = x3;
	_data2_->x3_target = x3_target;
	_data2_->x4 = x4;
	_data2_->x4_target = x4_target;
	_data2_->B = NULL;
	_data2_->B_target = NULL;
	_data2_->B_target_destroy_notify = NULL;
	(_data2_->B_target_destroy_notify == NULL) ? NULL : (_data2_->B_target_destroy_notify (_data2_->B_target), NULL);
	_data2_->B = NULL;
	_data2_->B_target = NULL;
	_data2_->B_target_destroy_notify = NULL;
	_data2_->B = ___lambda5__func;
	_data2_->B_target = block2_data_ref (_data2_);
	_data2_->B_target_destroy_notify = block2_data_unref;
	if (_data2_->k <= 0) {
		_tmp0_ = _data2_->x4 (_data2_->x4_target) + x5 (x5_target);
	} else {
		Func _tmp1_;
		gpointer _tmp1__target;
		_tmp1_ = _data2_->B;
		_tmp1__target = _data2_->B_target;
		_tmp0_ = _tmp1_ (_tmp1__target);
	}
	result = _tmp0_;
	block2_data_unref (_data2_);
	_data2_ = NULL;
	return result;
}

static Block3Data*
block3_data_ref (Block3Data* _data3_)
{
	g_atomic_int_inc (&_data3_->_ref_count_);
	return _data3_;
}

static void
block3_data_unref (void * _userdata_)
{
	Block3Data* _data3_;
	_data3_ = (Block3Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data3_->_ref_count_)) {
		g_slice_free (Block3Data, _data3_);
	}
}

static gint
__lambda6_ (Block3Data* _data3_)
{
	gint result;
	_data3_->array = NULL;
	_data3_->func ();
	result = 0;
	return result;
}

static gint
___lambda6__func (gpointer self)
{
	gint result;
	result = __lambda6_ (self);
	return result;
}

void
B (gint* array,
   NoTargetFunc func)
{
	Block3Data* _data3_;
	Func C = NULL;
	gpointer C_target;
	GDestroyNotify C_target_destroy_notify;
	_data3_ = g_slice_new0 (Block3Data);
	_data3_->_ref_count_ = 1;
	_data3_->array = array;
	_data3_->func = func;
	C = ___lambda6__func;
	C_target = block3_data_ref (_data3_);
	C_target_destroy_notify = block3_data_unref;
	(C_target_destroy_notify == NULL) ? NULL : (C_target_destroy_notify (C_target), NULL);
	C = NULL;
	C_target = NULL;
	C_target_destroy_notify = NULL;
	block3_data_unref (_data3_);
	_data3_ = NULL;
}

static gint
__lambda7_ (void)
{
	gint result;
	result = 1;
	return result;
}

static gint
___lambda7__func (gpointer self)
{
	gint result;
	result = __lambda7_ ();
	return result;
}

static gint
__lambda8_ (void)
{
	gint result;
	result = -1;
	return result;
}

static gint
___lambda8__func (gpointer self)
{
	gint result;
	result = __lambda8_ ();
	return result;
}

static gint
__lambda9_ (void)
{
	gint result;
	result = -1;
	return result;
}

static gint
___lambda9__func (gpointer self)
{
	gint result;
	result = __lambda9_ ();
	return result;
}

static gint
__lambda10_ (void)
{
	gint result;
	result = 1;
	return result;
}

static gint
___lambda10__func (gpointer self)
{
	gint result;
	result = __lambda10_ ();
	return result;
}

static gint
__lambda11_ (void)
{
	gint result;
	result = 0;
	return result;
}

static gint
___lambda11__func (gpointer self)
{
	gint result;
	result = __lambda11_ ();
	return result;
}

static void
_vala_main (void)
{
	gint _result_ = 0;
	Foo* foo = NULL;
	Foo* _tmp0_;
	GMainLoop* loop = NULL;
	GMainLoop* _tmp1_;
	_result_ = A (10, ___lambda7__func, NULL, ___lambda8__func, NULL, ___lambda9__func, NULL, ___lambda10__func, NULL, ___lambda11__func, NULL);
	_vala_assert (_result_ == -67, "result == -67");
	_tmp0_ = foo_new ();
	foo = _tmp0_;
	_tmp1_ = g_main_loop_new (NULL, FALSE);
	loop = _tmp1_;
	foo_bar (foo, loop);
	g_main_loop_run (loop);
	_vala_assert (G_TYPE_CHECK_INSTANCE_CAST (foo, G_TYPE_OBJECT, GObject)->ref_count == ((guint) 1), "foo.ref_count == 1");
	_g_main_loop_unref0 (loop);
	_g_object_unref0 (foo);
}

int
main (int argc,
      char ** argv)
{
	_vala_main ();
	return 0;
}

static gssize
_vala_array_length (gpointer array)
{
	gssize length;
	length = 0;
	if (array) {
		while (((gpointer*) array)[length]) {
			length++;
		}
	}
	return length;
}

