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

/* streamiterator.vala
 *
 * Copyright (C) 2013  Maciej Piechotka
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.

 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.

 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
 *
 * Author:
 * 	Maciej Piechotka <uzytkownik2@gmail.com>
 */

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

#define GEE_TYPE_STREAM_ITERATOR (gee_stream_iterator_get_type ())
#define GEE_STREAM_ITERATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEE_TYPE_STREAM_ITERATOR, GeeStreamIterator))
#define GEE_STREAM_ITERATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEE_TYPE_STREAM_ITERATOR, GeeStreamIteratorClass))
#define GEE_IS_STREAM_ITERATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEE_TYPE_STREAM_ITERATOR))
#define GEE_IS_STREAM_ITERATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEE_TYPE_STREAM_ITERATOR))
#define GEE_STREAM_ITERATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEE_TYPE_STREAM_ITERATOR, GeeStreamIteratorClass))

typedef struct _GeeStreamIterator GeeStreamIterator;
typedef struct _GeeStreamIteratorClass GeeStreamIteratorClass;
typedef struct _GeeStreamIteratorPrivate GeeStreamIteratorPrivate;
enum  {
	GEE_STREAM_ITERATOR_0_PROPERTY,
	GEE_STREAM_ITERATOR_A_TYPE,
	GEE_STREAM_ITERATOR_A_DUP_FUNC,
	GEE_STREAM_ITERATOR_A_DESTROY_FUNC,
	GEE_STREAM_ITERATOR_G_TYPE,
	GEE_STREAM_ITERATOR_G_DUP_FUNC,
	GEE_STREAM_ITERATOR_G_DESTROY_FUNC,
	GEE_STREAM_ITERATOR_VALID_PROPERTY,
	GEE_STREAM_ITERATOR_READ_ONLY_PROPERTY,
	GEE_STREAM_ITERATOR_NUM_PROPERTIES
};
static GParamSpec* gee_stream_iterator_properties[GEE_STREAM_ITERATOR_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _gee_lazy_unref0(var) ((var == NULL) ? NULL : (var = (gee_lazy_unref (var), NULL)))
typedef struct _Block12Data Block12Data;
#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 _GeeStreamIterator {
	GObject parent_instance;
	GeeStreamIteratorPrivate * priv;
};

struct _GeeStreamIteratorClass {
	GObjectClass parent_class;
};

struct _GeeStreamIteratorPrivate {
	GType a_type;
	GBoxedCopyFunc a_dup_func;
	GDestroyNotify a_destroy_func;
	GType g_type;
	GBoxedCopyFunc g_dup_func;
	GDestroyNotify g_destroy_func;
	GeeIterator* _outer;
	GeeStreamFunc _func;
	gpointer _func_target;
	GDestroyNotify _func_target_destroy_notify;
	GeeLazy* _outer_value;
	GeeLazy* _current;
	GeeLazy* _next;
	GeeTraversableStream _state;
	gboolean _need_next;
	gboolean _finished;
};

struct _Block12Data {
	int _ref_count_;
	GType a_type;
	GBoxedCopyFunc a_dup_func;
	GDestroyNotify a_destroy_func;
	GType g_type;
	GBoxedCopyFunc g_dup_func;
	GDestroyNotify g_destroy_func;
	GeeIterator* outer;
};

static gint GeeStreamIterator_private_offset;
static gpointer gee_stream_iterator_parent_class = NULL;
static GeeTraversableIface * gee_stream_iterator_gee_traversable_parent_iface = NULL;
static GeeIteratorIface * gee_stream_iterator_gee_iterator_parent_iface = NULL;

 G_GNUC_INTERNAL GType gee_stream_iterator_get_type (void) G_GNUC_CONST  G_GNUC_UNUSED ;
 G_GNUC_INTERNAL GeeStreamIterator* gee_stream_iterator_new (GType a_type,
                                            GBoxedCopyFunc a_dup_func,
                                            GDestroyNotify a_destroy_func,
                                            GType g_type,
                                            GBoxedCopyFunc g_dup_func,
                                            GDestroyNotify g_destroy_func,
                                            GeeIterator* outer,
                                            GeeStreamFunc func,
                                            gpointer func_target,
                                            GDestroyNotify func_target_destroy_notify);
 G_GNUC_INTERNAL GeeStreamIterator* gee_stream_iterator_construct (GType object_type,
                                                  GType a_type,
                                                  GBoxedCopyFunc a_dup_func,
                                                  GDestroyNotify a_destroy_func,
                                                  GType g_type,
                                                  GBoxedCopyFunc g_dup_func,
                                                  GDestroyNotify g_destroy_func,
                                                  GeeIterator* outer,
                                                  GeeStreamFunc func,
                                                  gpointer func_target,
                                                  GDestroyNotify func_target_destroy_notify);
static gpointer ____lambda8_ (GeeStreamIterator* self);
static gpointer _____lambda8__gee_lazy_func (gpointer self);
static gboolean gee_stream_iterator_real_foreach (GeeTraversable* base,
                                           GeeForallFunc f,
                                           gpointer f_target);
static inline GeeLazy* gee_stream_iterator_yield_next (GType a_type,
                                         GBoxedCopyFunc a_dup_func,
                                         GDestroyNotify a_destroy_func,
                                         GType g_type,
                                         GBoxedCopyFunc g_dup_func,
                                         GDestroyNotify g_destroy_func,
                                         GeeIterator* outer,
                                         GeeStreamFunc func,
                                         gpointer func_target,
                                         GeeTraversableStream* state,
                                         gboolean* need_next,
                                         GeeLazy** outer_value);
static gboolean gee_stream_iterator_real_next (GeeIterator* base);
static gboolean gee_stream_iterator_real_has_next (GeeIterator* base);
static gpointer gee_stream_iterator_real_get (GeeIterator* base);
static void gee_stream_iterator_real_remove (GeeIterator* base);
static Block12Data* block12_data_ref (Block12Data* _data12_);
static void block12_data_unref (void * _userdata_);
static gpointer _____lambda9_ (Block12Data* _data12_);
static gpointer ______lambda9__gee_lazy_func (gpointer self);
static gpointer _____lambda10_ (Block12Data* _data12_);
static gpointer ______lambda10__gee_lazy_func (gpointer self);
static void gee_stream_iterator_finalize (GObject * obj);
static GType gee_stream_iterator_get_type_once (void);
static void _vala_gee_stream_iterator_get_property (GObject * object,
                                             guint property_id,
                                             GValue * value,
                                             GParamSpec * pspec);
static void _vala_gee_stream_iterator_set_property (GObject * object,
                                             guint property_id,
                                             const GValue * value,
                                             GParamSpec * pspec);

static inline gpointer
gee_stream_iterator_get_instance_private (GeeStreamIterator* self)
{
	return G_STRUCT_MEMBER_P (self, GeeStreamIterator_private_offset);
}

static gpointer
_g_object_ref0 (gpointer self)
{
	return self ? g_object_ref (self) : NULL;
}

static gpointer
____lambda8_ (GeeStreamIterator* self)
{
	GeeIterator* _tmp0_;
	gpointer _tmp1_;
	gpointer result;
	_tmp0_ = self->priv->_outer;
	_tmp1_ = gee_iterator_get (_tmp0_);
	result = _tmp1_;
	return result;
}

static gpointer
_____lambda8__gee_lazy_func (gpointer self)
{
	gpointer result;
	result = ____lambda8_ ((GeeStreamIterator*) self);
	return result;
}

 G_GNUC_INTERNAL GeeStreamIterator*
gee_stream_iterator_construct (GType object_type,
                               GType a_type,
                               GBoxedCopyFunc a_dup_func,
                               GDestroyNotify a_destroy_func,
                               GType g_type,
                               GBoxedCopyFunc g_dup_func,
                               GDestroyNotify g_destroy_func,
                               GeeIterator* outer,
                               GeeStreamFunc func,
                               gpointer func_target,
                               GDestroyNotify func_target_destroy_notify)
{
	GeeStreamIterator * self = NULL;
	GeeIterator* _tmp0_;
	GeeStreamFunc _tmp1_;
	gpointer _tmp1__target;
	GDestroyNotify _tmp1__target_destroy_notify;
	GeeStreamFunc _tmp2_;
	gpointer _tmp2__target;
	GeeLazy* _tmp3_ = NULL;
	GeeTraversableStream _tmp4_;
	g_return_val_if_fail (outer != NULL, NULL);
	self = (GeeStreamIterator*) g_object_new (object_type, "a-type", a_type, "a-dup-func", a_dup_func, "a-destroy-func", a_destroy_func, "g-type", g_type, "g-dup-func", g_dup_func, "g-destroy-func", g_destroy_func, NULL);
	self->priv->a_type = a_type;
	self->priv->a_dup_func = a_dup_func;
	self->priv->a_destroy_func = a_destroy_func;
	self->priv->g_type = g_type;
	self->priv->g_dup_func = g_dup_func;
	self->priv->g_destroy_func = g_destroy_func;
	_tmp0_ = _g_object_ref0 (outer);
	_g_object_unref0 (self->priv->_outer);
	self->priv->_outer = _tmp0_;
	_tmp1_ = func;
	_tmp1__target = func_target;
	_tmp1__target_destroy_notify = func_target_destroy_notify;
	func = NULL;
	func_target = NULL;
	func_target_destroy_notify = NULL;
	(self->priv->_func_target_destroy_notify == NULL) ? NULL : (self->priv->_func_target_destroy_notify (self->priv->_func_target), NULL);
	self->priv->_func = NULL;
	self->priv->_func_target = NULL;
	self->priv->_func_target_destroy_notify = NULL;
	self->priv->_func = _tmp1_;
	self->priv->_func_target = _tmp1__target;
	self->priv->_func_target_destroy_notify = _tmp1__target_destroy_notify;
	_gee_lazy_unref0 (self->priv->_current);
	self->priv->_current = NULL;
	self->priv->_need_next = TRUE;
	self->priv->_finished = FALSE;
	_tmp2_ = self->priv->_func;
	_tmp2__target = self->priv->_func_target;
	_tmp4_ = _tmp2_ (GEE_TRAVERSABLE_STREAM_YIELD, NULL, &_tmp3_, _tmp2__target);
	_gee_lazy_unref0 (self->priv->_current);
	self->priv->_current = _tmp3_;
	self->priv->_state = _tmp4_;
	switch (self->priv->_state) {
		case GEE_TRAVERSABLE_STREAM_WAIT:
		case GEE_TRAVERSABLE_STREAM_YIELD:
		{
			GeeIterator* _tmp5_;
			gboolean _tmp6_;
			gboolean _tmp7_;
			_tmp5_ = self->priv->_outer;
			_tmp6_ = gee_iterator_get_valid (_tmp5_);
			_tmp7_ = _tmp6_;
			self->priv->_need_next = !_tmp7_;
			break;
		}
		case GEE_TRAVERSABLE_STREAM_CONTINUE:
		{
			GeeIterator* _tmp8_;
			gboolean _tmp9_;
			gboolean _tmp10_;
			_tmp8_ = self->priv->_outer;
			_tmp9_ = gee_iterator_get_valid (_tmp8_);
			_tmp10_ = _tmp9_;
			if (_tmp10_) {
				GeeStreamFunc _tmp11_;
				gpointer _tmp11__target;
				GeeLazy* _tmp12_;
				GeeLazy* _tmp13_ = NULL;
				GeeTraversableStream _tmp14_;
				_tmp11_ = self->priv->_func;
				_tmp11__target = self->priv->_func_target;
				_tmp12_ = gee_lazy_new (g_type, (GBoxedCopyFunc) g_dup_func, (GDestroyNotify) g_destroy_func, _____lambda8__gee_lazy_func, g_object_ref (self), g_object_unref);
				_tmp14_ = _tmp11_ (self->priv->_state, _tmp12_, &_tmp13_, _tmp11__target);
				_gee_lazy_unref0 (self->priv->_current);
				self->priv->_current = _tmp13_;
				self->priv->_state = _tmp14_;
				switch (self->priv->_state) {
					case GEE_TRAVERSABLE_STREAM_YIELD:
					case GEE_TRAVERSABLE_STREAM_CONTINUE:
					case GEE_TRAVERSABLE_STREAM_WAIT:
					{
						break;
					}
					case GEE_TRAVERSABLE_STREAM_END:
					{
						self->priv->_finished = TRUE;
						(func_target_destroy_notify == NULL) ? NULL : (func_target_destroy_notify (func_target), NULL);
						func = NULL;
						func_target = NULL;
						func_target_destroy_notify = NULL;
						return self;
					}
					default:
					{
						g_assert_not_reached ();
					}
				}
			}
			break;
		}
		case GEE_TRAVERSABLE_STREAM_END:
		{
			self->priv->_finished = TRUE;
			(func_target_destroy_notify == NULL) ? NULL : (func_target_destroy_notify (func_target), NULL);
			func = NULL;
			func_target = NULL;
			func_target_destroy_notify = NULL;
			return self;
		}
		default:
		break;
	}
	(func_target_destroy_notify == NULL) ? NULL : (func_target_destroy_notify (func_target), NULL);
	func = NULL;
	func_target = NULL;
	func_target_destroy_notify = NULL;
	return self;
}

 G_GNUC_INTERNAL GeeStreamIterator*
gee_stream_iterator_new (GType a_type,
                         GBoxedCopyFunc a_dup_func,
                         GDestroyNotify a_destroy_func,
                         GType g_type,
                         GBoxedCopyFunc g_dup_func,
                         GDestroyNotify g_destroy_func,
                         GeeIterator* outer,
                         GeeStreamFunc func,
                         gpointer func_target,
                         GDestroyNotify func_target_destroy_notify)
{
	return gee_stream_iterator_construct (GEE_TYPE_STREAM_ITERATOR, a_type, a_dup_func, a_destroy_func, g_type, g_dup_func, g_destroy_func, outer, func, func_target, func_target_destroy_notify);
}

static gpointer
_gee_lazy_ref0 (gpointer self)
{
	return self ? gee_lazy_ref (self) : NULL;
}

static gboolean
gee_stream_iterator_real_foreach (GeeTraversable* base,
                                  GeeForallFunc f,
                                  gpointer f_target)
{
	GeeStreamIterator * self;
	GeeLazy* current = NULL;
	GeeLazy* _tmp0_;
	GeeLazy* _tmp5_;
	GeeIterator* outer = NULL;
	GeeIterator* _tmp11_;
	GeeStreamFunc func = NULL;
	GeeStreamFunc _tmp12_;
	gpointer _tmp12__target;
	gpointer func_target;
	GeeTraversableStream state = 0;
	gboolean need_next = FALSE;
	gboolean _result_ = FALSE;
	GeeLazy* next_current = NULL;
	GeeLazy* outer_value = NULL;
	GeeLazy* _tmp13_;
	GeeLazy* _tmp14_;
	GeeLazy* _tmp24_;
	GeeLazy* _tmp25_;
	gboolean result;
	self = (GeeStreamIterator*) base;
	current = NULL;
	_tmp0_ = self->priv->_current;
	if (_tmp0_ != NULL) {
		GeeLazy* _tmp1_;
		gconstpointer _tmp2_;
		gconstpointer _tmp3_;
		gpointer _tmp4_;
		_tmp1_ = self->priv->_current;
		_tmp2_ = gee_lazy_get_value (_tmp1_);
		_tmp3_ = _tmp2_;
		_tmp4_ = ((_tmp3_ != NULL) && (self->priv->a_dup_func != NULL)) ? self->priv->a_dup_func ((gpointer) _tmp3_) : ((gpointer) _tmp3_);
		if (!f (_tmp4_, f_target)) {
			result = FALSE;
			_gee_lazy_unref0 (current);
			return result;
		}
	}
	_tmp5_ = self->priv->_next;
	if (_tmp5_ != NULL) {
		GeeLazy* _tmp6_;
		GeeLazy* _tmp7_;
		gconstpointer _tmp8_;
		gconstpointer _tmp9_;
		gpointer _tmp10_;
		_tmp6_ = self->priv->_next;
		self->priv->_next = NULL;
		_gee_lazy_unref0 (current);
		current = _tmp6_;
		_tmp7_ = current;
		_tmp8_ = gee_lazy_get_value (_tmp7_);
		_tmp9_ = _tmp8_;
		_tmp10_ = ((_tmp9_ != NULL) && (self->priv->a_dup_func != NULL)) ? self->priv->a_dup_func ((gpointer) _tmp9_) : ((gpointer) _tmp9_);
		if (!f (_tmp10_, f_target)) {
			result = FALSE;
			_gee_lazy_unref0 (current);
			return result;
		}
	} else {
		if (self->priv->_finished) {
			result = TRUE;
			_gee_lazy_unref0 (current);
			return result;
		}
	}
	_tmp11_ = self->priv->_outer;
	outer = _tmp11_;
	_tmp12_ = self->priv->_func;
	_tmp12__target = self->priv->_func_target;
	func = _tmp12_;
	func_target = _tmp12__target;
	state = self->priv->_state;
	need_next = self->priv->_need_next;
	_result_ = TRUE;
	_tmp13_ = self->priv->_outer_value;
	_tmp14_ = _gee_lazy_ref0 (_tmp13_);
	outer_value = _tmp14_;
	while (TRUE) {
		GeeIterator* _tmp15_;
		GeeStreamFunc _tmp16_;
		gpointer _tmp16__target;
		GeeLazy* _tmp17_;
		GeeLazy* _tmp18_;
		GeeLazy* _tmp19_;
		GeeLazy* _tmp20_;
		gconstpointer _tmp21_;
		gconstpointer _tmp22_;
		gpointer _tmp23_;
		_tmp15_ = outer;
		_tmp16_ = func;
		_tmp16__target = func_target;
		_tmp17_ = gee_stream_iterator_yield_next (self->priv->a_type, (GBoxedCopyFunc) self->priv->a_dup_func, (GDestroyNotify) self->priv->a_destroy_func, self->priv->g_type, (GBoxedCopyFunc) self->priv->g_dup_func, (GDestroyNotify) self->priv->g_destroy_func, _tmp15_, _tmp16_, _tmp16__target, &state, &need_next, &outer_value);
		_gee_lazy_unref0 (next_current);
		next_current = _tmp17_;
		_tmp18_ = next_current;
		if (!(_tmp18_ != NULL)) {
			break;
		}
		_tmp19_ = next_current;
		next_current = NULL;
		_gee_lazy_unref0 (current);
		current = _tmp19_;
		_tmp20_ = current;
		_tmp21_ = gee_lazy_get_value (_tmp20_);
		_tmp22_ = _tmp21_;
		_tmp23_ = ((_tmp22_ != NULL) && (self->priv->a_dup_func != NULL)) ? self->priv->a_dup_func ((gpointer) _tmp22_) : ((gpointer) _tmp22_);
		if (!f (_tmp23_, f_target)) {
			_result_ = FALSE;
			break;
		}
	}
	self->priv->_state = state;
	self->priv->_need_next = need_next;
	self->priv->_finished = _result_;
	_tmp24_ = current;
	current = NULL;
	_gee_lazy_unref0 (self->priv->_current);
	self->priv->_current = _tmp24_;
	_tmp25_ = outer_value;
	outer_value = NULL;
	_gee_lazy_unref0 (self->priv->_outer_value);
	self->priv->_outer_value = _tmp25_;
	result = _result_;
	_gee_lazy_unref0 (outer_value);
	_gee_lazy_unref0 (next_current);
	_gee_lazy_unref0 (current);
	return result;
}

static gboolean
gee_stream_iterator_real_next (GeeIterator* base)
{
	GeeStreamIterator * self;
	gboolean result;
	self = (GeeStreamIterator*) base;
	if (gee_iterator_has_next ((GeeIterator*) self)) {
		GeeLazy* _tmp0_;
		GeeLazy* _tmp2_;
		_tmp0_ = self->priv->_current;
		if (_tmp0_ != NULL) {
			GeeLazy* _tmp1_;
			_tmp1_ = self->priv->_current;
			gee_lazy_eval (_tmp1_);
		}
		_tmp2_ = self->priv->_next;
		self->priv->_next = NULL;
		_gee_lazy_unref0 (self->priv->_current);
		self->priv->_current = _tmp2_;
		result = TRUE;
		return result;
	} else {
		result = FALSE;
		return result;
	}
}

static gboolean
gee_stream_iterator_real_has_next (GeeIterator* base)
{
	GeeStreamIterator * self;
	GeeLazy* _tmp0_;
	GeeIterator* _tmp1_;
	GeeStreamFunc _tmp2_;
	gpointer _tmp2__target;
	GeeLazy* _tmp3_;
	GeeLazy* _tmp4_;
	gboolean result;
	self = (GeeStreamIterator*) base;
	if (self->priv->_finished) {
		result = FALSE;
		return result;
	}
	_tmp0_ = self->priv->_next;
	if (_tmp0_ != NULL) {
		result = TRUE;
		return result;
	}
	_tmp1_ = self->priv->_outer;
	_tmp2_ = self->priv->_func;
	_tmp2__target = self->priv->_func_target;
	_tmp3_ = gee_stream_iterator_yield_next (self->priv->a_type, (GBoxedCopyFunc) self->priv->a_dup_func, (GDestroyNotify) self->priv->a_destroy_func, self->priv->g_type, (GBoxedCopyFunc) self->priv->g_dup_func, (GDestroyNotify) self->priv->g_destroy_func, _tmp1_, _tmp2_, _tmp2__target, &self->priv->_state, &self->priv->_need_next, &self->priv->_outer_value);
	_gee_lazy_unref0 (self->priv->_next);
	self->priv->_next = _tmp3_;
	_tmp4_ = self->priv->_next;
	self->priv->_finished = _tmp4_ == NULL;
	result = !self->priv->_finished;
	return result;
}

static gpointer
gee_stream_iterator_real_get (GeeIterator* base)
{
	GeeStreamIterator * self;
	GeeLazy* _tmp0_;
	GeeLazy* _tmp1_;
	gconstpointer _tmp2_;
	gconstpointer _tmp3_;
	gpointer _tmp4_;
	gpointer result;
	self = (GeeStreamIterator*) base;
	_tmp0_ = self->priv->_current;
	_vala_assert (_tmp0_ != NULL, "_current != null");
	_tmp1_ = self->priv->_current;
	_tmp2_ = gee_lazy_get_value (_tmp1_);
	_tmp3_ = _tmp2_;
	_tmp4_ = ((_tmp3_ != NULL) && (self->priv->a_dup_func != NULL)) ? self->priv->a_dup_func ((gpointer) _tmp3_) : ((gpointer) _tmp3_);
	result = _tmp4_;
	return result;
}

static void
gee_stream_iterator_real_remove (GeeIterator* base)
{
	GeeStreamIterator * self;
	self = (GeeStreamIterator*) base;
	g_assert_not_reached ();
}

static Block12Data*
block12_data_ref (Block12Data* _data12_)
{
	g_atomic_int_inc (&_data12_->_ref_count_);
	return _data12_;
}

static void
block12_data_unref (void * _userdata_)
{
	Block12Data* _data12_;
	_data12_ = (Block12Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data12_->_ref_count_)) {
		GType a_type;
		GBoxedCopyFunc a_dup_func;
		GDestroyNotify a_destroy_func;
		GType g_type;
		GBoxedCopyFunc g_dup_func;
		GDestroyNotify g_destroy_func;
		a_type = _data12_->a_type;
		a_dup_func = _data12_->a_dup_func;
		a_destroy_func = _data12_->a_destroy_func;
		g_type = _data12_->g_type;
		g_dup_func = _data12_->g_dup_func;
		g_destroy_func = _data12_->g_destroy_func;
		_g_object_unref0 (_data12_->outer);
		g_slice_free (Block12Data, _data12_);
	}
}

static gpointer
_____lambda9_ (Block12Data* _data12_)
{
	GType a_type;
	GBoxedCopyFunc a_dup_func;
	GDestroyNotify a_destroy_func;
	GType g_type;
	GBoxedCopyFunc g_dup_func;
	GDestroyNotify g_destroy_func;
	gpointer _tmp0_;
	gpointer result;
	a_type = _data12_->a_type;
	a_dup_func = _data12_->a_dup_func;
	a_destroy_func = _data12_->a_destroy_func;
	g_type = _data12_->g_type;
	g_dup_func = _data12_->g_dup_func;
	g_destroy_func = _data12_->g_destroy_func;
	_vala_assert (gee_iterator_next (_data12_->outer), "outer.next ()");
	_tmp0_ = gee_iterator_get (_data12_->outer);
	result = _tmp0_;
	return result;
}

static gpointer
______lambda9__gee_lazy_func (gpointer self)
{
	gpointer result;
	result = _____lambda9_ (self);
	return result;
}

static gpointer
_____lambda10_ (Block12Data* _data12_)
{
	GType a_type;
	GBoxedCopyFunc a_dup_func;
	GDestroyNotify a_destroy_func;
	GType g_type;
	GBoxedCopyFunc g_dup_func;
	GDestroyNotify g_destroy_func;
	gpointer _tmp0_;
	gpointer result;
	a_type = _data12_->a_type;
	a_dup_func = _data12_->a_dup_func;
	a_destroy_func = _data12_->a_destroy_func;
	g_type = _data12_->g_type;
	g_dup_func = _data12_->g_dup_func;
	g_destroy_func = _data12_->g_destroy_func;
	_tmp0_ = gee_iterator_get (_data12_->outer);
	result = _tmp0_;
	return result;
}

static gpointer
______lambda10__gee_lazy_func (gpointer self)
{
	gpointer result;
	result = _____lambda10_ (self);
	return result;
}

static inline GeeLazy*
gee_stream_iterator_yield_next (GType a_type,
                                GBoxedCopyFunc a_dup_func,
                                GDestroyNotify a_destroy_func,
                                GType g_type,
                                GBoxedCopyFunc g_dup_func,
                                GDestroyNotify g_destroy_func,
                                GeeIterator* outer,
                                GeeStreamFunc func,
                                gpointer func_target,
                                GeeTraversableStream* state,
                                gboolean* need_next,
                                GeeLazy** outer_value)
{
	Block12Data* _data12_;
	GeeIterator* _tmp0_;
	GeeLazy* value = NULL;
	GeeLazy* result;
	g_return_val_if_fail (outer != NULL, NULL);
	_data12_ = g_slice_new0 (Block12Data);
	_data12_->_ref_count_ = 1;
	_data12_->a_type = a_type;
	_data12_->a_dup_func = a_dup_func;
	_data12_->a_destroy_func = a_destroy_func;
	_data12_->g_type = g_type;
	_data12_->g_dup_func = g_dup_func;
	_data12_->g_destroy_func = g_destroy_func;
	_tmp0_ = _g_object_ref0 (outer);
	_g_object_unref0 (_data12_->outer);
	_data12_->outer = _tmp0_;
	value = NULL;
	if ((*state) != GEE_TRAVERSABLE_STREAM_CONTINUE) {
		GeeLazy* _tmp1_ = NULL;
		GeeTraversableStream _tmp2_;
		_tmp2_ = func (*state, NULL, &_tmp1_, func_target);
		_gee_lazy_unref0 (value);
		value = _tmp1_;
		*state = _tmp2_;
	}
	while (TRUE) {
		switch (*state) {
			case GEE_TRAVERSABLE_STREAM_YIELD:
			{
				result = value;
				block12_data_unref (_data12_);
				_data12_ = NULL;
				return result;
			}
			case GEE_TRAVERSABLE_STREAM_CONTINUE:
			{
				GeeLazy* _tmp7_;
				GeeLazy* _tmp8_ = NULL;
				GeeTraversableStream _tmp9_;
				if ((*outer_value) != NULL) {
					gee_lazy_eval (*outer_value);
				}
				if (*need_next) {
					GeeLazy* _tmp5_;
					if (!gee_iterator_has_next (_data12_->outer)) {
						GeeLazy* _tmp3_ = NULL;
						GeeTraversableStream _tmp4_;
						_tmp4_ = func (GEE_TRAVERSABLE_STREAM_END, NULL, &_tmp3_, func_target);
						_gee_lazy_unref0 (value);
						value = _tmp3_;
						*state = _tmp4_;
						continue;
					}
					_tmp5_ = gee_lazy_new (g_type, (GBoxedCopyFunc) g_dup_func, (GDestroyNotify) g_destroy_func, ______lambda9__gee_lazy_func, block12_data_ref (_data12_), block12_data_unref);
					_gee_lazy_unref0 (*outer_value);
					*outer_value = _tmp5_;
				} else {
					GeeLazy* _tmp6_;
					*need_next = TRUE;
					_tmp6_ = gee_lazy_new (g_type, (GBoxedCopyFunc) g_dup_func, (GDestroyNotify) g_destroy_func, ______lambda10__gee_lazy_func, block12_data_ref (_data12_), block12_data_unref);
					_gee_lazy_unref0 (*outer_value);
					*outer_value = _tmp6_;
				}
				_tmp7_ = _gee_lazy_ref0 (*outer_value);
				_tmp9_ = func (*state, _tmp7_, &_tmp8_, func_target);
				_gee_lazy_unref0 (value);
				value = _tmp8_;
				*state = _tmp9_;
				break;
			}
			case GEE_TRAVERSABLE_STREAM_WAIT:
			{
				GeeLazy* _tmp10_ = NULL;
				GeeTraversableStream _tmp11_;
				_tmp11_ = func (*state, NULL, &_tmp10_, func_target);
				_gee_lazy_unref0 (value);
				value = _tmp10_;
				*state = _tmp11_;
				break;
			}
			case GEE_TRAVERSABLE_STREAM_END:
			{
				result = NULL;
				_gee_lazy_unref0 (value);
				block12_data_unref (_data12_);
				_data12_ = NULL;
				return result;
			}
			default:
			{
				g_assert_not_reached ();
			}
		}
	}
}

static gboolean
gee_stream_iterator_real_get_valid (GeeIterator* base)
{
	gboolean result;
	GeeStreamIterator* self;
	GeeLazy* _tmp0_;
	self = (GeeStreamIterator*) base;
	_tmp0_ = self->priv->_current;
	result = _tmp0_ != NULL;
	return result;
}

static gboolean
gee_stream_iterator_real_get_read_only (GeeIterator* base)
{
	gboolean result;
	GeeStreamIterator* self;
	self = (GeeStreamIterator*) base;
	result = TRUE;
	return result;
}

static void
gee_stream_iterator_class_init (GeeStreamIteratorClass * klass,
                                gpointer klass_data)
{
	gee_stream_iterator_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &GeeStreamIterator_private_offset);
	G_OBJECT_CLASS (klass)->get_property = _vala_gee_stream_iterator_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_gee_stream_iterator_set_property;
	G_OBJECT_CLASS (klass)->finalize = gee_stream_iterator_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEE_STREAM_ITERATOR_A_TYPE, g_param_spec_gtype ("a-type", "type", "type", G_TYPE_NONE, G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEE_STREAM_ITERATOR_A_DUP_FUNC, g_param_spec_pointer ("a-dup-func", "dup func", "dup func", G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEE_STREAM_ITERATOR_A_DESTROY_FUNC, g_param_spec_pointer ("a-destroy-func", "destroy func", "destroy func", G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEE_STREAM_ITERATOR_G_TYPE, g_param_spec_gtype ("g-type", "type", "type", G_TYPE_NONE, G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEE_STREAM_ITERATOR_G_DUP_FUNC, g_param_spec_pointer ("g-dup-func", "dup func", "dup func", G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEE_STREAM_ITERATOR_G_DESTROY_FUNC, g_param_spec_pointer ("g-destroy-func", "destroy func", "destroy func", G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEE_STREAM_ITERATOR_VALID_PROPERTY, gee_stream_iterator_properties[GEE_STREAM_ITERATOR_VALID_PROPERTY] = g_param_spec_boolean ("valid", "valid", "valid", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEE_STREAM_ITERATOR_READ_ONLY_PROPERTY, gee_stream_iterator_properties[GEE_STREAM_ITERATOR_READ_ONLY_PROPERTY] = g_param_spec_boolean ("read-only", "read-only", "read-only", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
}

static GType
gee_stream_iterator_gee_traversable_get_g_type (GeeStreamIterator* self)
{
	return self->priv->a_type;
}

static GBoxedCopyFunc
gee_stream_iterator_gee_traversable_get_g_dup_func (GeeStreamIterator* self)
{
	return self->priv->a_dup_func;
}

static GDestroyNotify
gee_stream_iterator_gee_traversable_get_g_destroy_func (GeeStreamIterator* self)
{
	return self->priv->a_destroy_func;
}

static void
gee_stream_iterator_gee_traversable_interface_init (GeeTraversableIface * iface,
                                                    gpointer iface_data)
{
	gee_stream_iterator_gee_traversable_parent_iface = g_type_interface_peek_parent (iface);
	iface->foreach = (gboolean (*) (GeeTraversable*, GeeForallFunc, gpointer)) gee_stream_iterator_real_foreach;
	iface->get_g_type = (GType (*) (GeeTraversable *)) gee_stream_iterator_gee_traversable_get_g_type;
	iface->get_g_dup_func = (GBoxedCopyFunc (*) (GeeTraversable *)) gee_stream_iterator_gee_traversable_get_g_dup_func;
	iface->get_g_destroy_func = (GDestroyNotify (*) (GeeTraversable *)) gee_stream_iterator_gee_traversable_get_g_destroy_func;
}

static void
gee_stream_iterator_gee_iterator_interface_init (GeeIteratorIface * iface,
                                                 gpointer iface_data)
{
	gee_stream_iterator_gee_iterator_parent_iface = g_type_interface_peek_parent (iface);
	iface->next = (gboolean (*) (GeeIterator*)) gee_stream_iterator_real_next;
	iface->has_next = (gboolean (*) (GeeIterator*)) gee_stream_iterator_real_has_next;
	iface->get = (gpointer (*) (GeeIterator*)) gee_stream_iterator_real_get;
	iface->remove = (void (*) (GeeIterator*)) gee_stream_iterator_real_remove;
	iface->get_valid = gee_stream_iterator_real_get_valid;
	iface->get_read_only = gee_stream_iterator_real_get_read_only;
}

static void
gee_stream_iterator_instance_init (GeeStreamIterator * self,
                                   gpointer klass)
{
	self->priv = gee_stream_iterator_get_instance_private (self);
}

static void
gee_stream_iterator_finalize (GObject * obj)
{
	GeeStreamIterator * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, GEE_TYPE_STREAM_ITERATOR, GeeStreamIterator);
	_g_object_unref0 (self->priv->_outer);
	(self->priv->_func_target_destroy_notify == NULL) ? NULL : (self->priv->_func_target_destroy_notify (self->priv->_func_target), NULL);
	self->priv->_func = NULL;
	self->priv->_func_target = NULL;
	self->priv->_func_target_destroy_notify = NULL;
	_gee_lazy_unref0 (self->priv->_outer_value);
	_gee_lazy_unref0 (self->priv->_current);
	_gee_lazy_unref0 (self->priv->_next);
	G_OBJECT_CLASS (gee_stream_iterator_parent_class)->finalize (obj);
}

static GType
gee_stream_iterator_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (GeeStreamIteratorClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) gee_stream_iterator_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (GeeStreamIterator), 0, (GInstanceInitFunc) gee_stream_iterator_instance_init, NULL };
	static const GInterfaceInfo gee_traversable_info = { (GInterfaceInitFunc) gee_stream_iterator_gee_traversable_interface_init, (GInterfaceFinalizeFunc) NULL, NULL};
	static const GInterfaceInfo gee_iterator_info = { (GInterfaceInitFunc) gee_stream_iterator_gee_iterator_interface_init, (GInterfaceFinalizeFunc) NULL, NULL};
	GType gee_stream_iterator_type_id;
	gee_stream_iterator_type_id = g_type_register_static (G_TYPE_OBJECT, "GeeStreamIterator", &g_define_type_info, 0);
	g_type_add_interface_static (gee_stream_iterator_type_id, GEE_TYPE_TRAVERSABLE, &gee_traversable_info);
	g_type_add_interface_static (gee_stream_iterator_type_id, GEE_TYPE_ITERATOR, &gee_iterator_info);
	GeeStreamIterator_private_offset = g_type_add_instance_private (gee_stream_iterator_type_id, sizeof (GeeStreamIteratorPrivate));
	return gee_stream_iterator_type_id;
}

 G_GNUC_INTERNAL GType
gee_stream_iterator_get_type (void)
{
	static volatile gsize gee_stream_iterator_type_id__once = 0;
	if (g_once_init_enter (&gee_stream_iterator_type_id__once)) {
		GType gee_stream_iterator_type_id;
		gee_stream_iterator_type_id = gee_stream_iterator_get_type_once ();
		g_once_init_leave (&gee_stream_iterator_type_id__once, gee_stream_iterator_type_id);
	}
	return gee_stream_iterator_type_id__once;
}

static void
_vala_gee_stream_iterator_get_property (GObject * object,
                                        guint property_id,
                                        GValue * value,
                                        GParamSpec * pspec)
{
	GeeStreamIterator * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, GEE_TYPE_STREAM_ITERATOR, GeeStreamIterator);
	switch (property_id) {
		case GEE_STREAM_ITERATOR_VALID_PROPERTY:
		g_value_set_boolean (value, gee_iterator_get_valid ((GeeIterator*) self));
		break;
		case GEE_STREAM_ITERATOR_READ_ONLY_PROPERTY:
		g_value_set_boolean (value, gee_iterator_get_read_only ((GeeIterator*) self));
		break;
		case GEE_STREAM_ITERATOR_A_TYPE:
		g_value_set_gtype (value, self->priv->a_type);
		break;
		case GEE_STREAM_ITERATOR_A_DUP_FUNC:
		g_value_set_pointer (value, self->priv->a_dup_func);
		break;
		case GEE_STREAM_ITERATOR_A_DESTROY_FUNC:
		g_value_set_pointer (value, self->priv->a_destroy_func);
		break;
		case GEE_STREAM_ITERATOR_G_TYPE:
		g_value_set_gtype (value, self->priv->g_type);
		break;
		case GEE_STREAM_ITERATOR_G_DUP_FUNC:
		g_value_set_pointer (value, self->priv->g_dup_func);
		break;
		case GEE_STREAM_ITERATOR_G_DESTROY_FUNC:
		g_value_set_pointer (value, self->priv->g_destroy_func);
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_gee_stream_iterator_set_property (GObject * object,
                                        guint property_id,
                                        const GValue * value,
                                        GParamSpec * pspec)
{
	GeeStreamIterator * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, GEE_TYPE_STREAM_ITERATOR, GeeStreamIterator);
	switch (property_id) {
		case GEE_STREAM_ITERATOR_A_TYPE:
		self->priv->a_type = g_value_get_gtype (value);
		break;
		case GEE_STREAM_ITERATOR_A_DUP_FUNC:
		self->priv->a_dup_func = g_value_get_pointer (value);
		break;
		case GEE_STREAM_ITERATOR_A_DESTROY_FUNC:
		self->priv->a_destroy_func = g_value_get_pointer (value);
		break;
		case GEE_STREAM_ITERATOR_G_TYPE:
		self->priv->g_type = g_value_get_gtype (value);
		break;
		case GEE_STREAM_ITERATOR_G_DUP_FUNC:
		self->priv->g_dup_func = g_value_get_pointer (value);
		break;
		case GEE_STREAM_ITERATOR_G_DESTROY_FUNC:
		self->priv->g_destroy_func = g_value_get_pointer (value);
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

