/* gcalc-math-term.c generated by valac 0.56.18-dirty, the Vala compiler
 * generated from gcalc-math-term.vala, do not modify */

/* gcalc-math-term.vala
 *
 * Copyright (C) 2018  Daniel Espinosa <esodan@gmail.com>
 *
 * 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *      Daniel Espinosa <esodan@gmail.com>
 */

#include "gcalc/gcalc.h"
#include <glib.h>
#include <gio/gio.h>
#include <gee.h>
#include <glib-object.h>
#include <glib/gi18n-lib.h>
#include "gcalc.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

#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))

static GCalcMathExpression* gcalc_math_term_real_add (GCalcMathTerm* self,
                                               GCalcMathTerm* t,
                                               GError** error);
static GCalcMathExpression* gcalc_math_term_real_evaluate (GCalcMathTerm* self,
                                                    GError** error);
static GType gcalc_math_term_get_type_once (void);

/**
   * Add a child term
   */
static GCalcMathExpression*
gcalc_math_term_real_add (GCalcMathTerm* self,
                          GCalcMathTerm* t,
                          GError** error)
{
	GCalcExpressionContainer* _tmp0_;
	GCalcExpressionContainer* _tmp1_;
	GCalcMathExpression* res = NULL;
	GCalcErrorExpression* _tmp3_;
	GCalcMathExpression* e = NULL;
	GCalcMathExpression* _tmp4_;
	GCalcMathExpression* e2 = NULL;
	GCalcMathExpression* _tmp5_;
	gboolean _tmp6_ = FALSE;
	GCalcMathExpression* _tmp7_;
	GError* _inner_error0_ = NULL;
	GCalcMathExpression* result;
	g_return_val_if_fail (t != NULL, NULL);
	_tmp0_ = gcalc_math_expression_get_expressions ((GCalcMathExpression*) t);
	_tmp1_ = _tmp0_;
	if (g_list_model_get_n_items ((GListModel*) _tmp1_) == ((guint) 0)) {
		GCalcConstant* _tmp2_;
		_tmp2_ = gcalc_constant_new_double (1.0);
		result = (GCalcMathExpression*) _tmp2_;
		return result;
	}
	_tmp3_ = gcalc_error_expression_new ();
	res = (GCalcMathExpression*) _tmp3_;
	_tmp4_ = gcalc_math_term_evaluate (self, &_inner_error0_);
	e = _tmp4_;
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		_g_object_unref0 (res);
		return NULL;
	}
	_tmp5_ = gcalc_math_term_evaluate (t, &_inner_error0_);
	e2 = _tmp5_;
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		_g_object_unref0 (e);
		_g_object_unref0 (res);
		return NULL;
	}
	_tmp7_ = e;
	if (GCALC_IS_MATH_CONSTANT (_tmp7_)) {
		GCalcMathExpression* _tmp8_;
		_tmp8_ = e2;
		_tmp6_ = GCALC_IS_MATH_CONSTANT (_tmp8_);
	} else {
		_tmp6_ = FALSE;
	}
	if (_tmp6_) {
		GCalcMathExpression* _tmp9_;
		GCalcMathExpression* _tmp10_;
		GCalcMathConstant* _tmp11_;
		_tmp9_ = e;
		_tmp10_ = e2;
		_tmp11_ = gcalc_math_constant_add (G_TYPE_CHECK_INSTANCE_CAST (_tmp9_, GCALC_TYPE_MATH_CONSTANT, GCalcMathConstant), G_TYPE_CHECK_INSTANCE_CAST (_tmp10_, GCALC_TYPE_MATH_CONSTANT, GCalcMathConstant));
		_g_object_unref0 (res);
		res = (GCalcMathExpression*) _tmp11_;
	}
	result = res;
	_g_object_unref0 (e2);
	_g_object_unref0 (e);
	return result;
}

GCalcMathExpression*
gcalc_math_term_add (GCalcMathTerm* self,
                     GCalcMathTerm* t,
                     GError** error)
{
	GCalcMathTermIface* _iface_;
	g_return_val_if_fail (self != NULL, NULL);
	_iface_ = GCALC_MATH_TERM_GET_INTERFACE (self);
	if (_iface_->add) {
		return _iface_->add (self, t, error);
	}
	return NULL;
}

/**
   * Evaluates the term an returns the resulting {@link MathExpression}
   */
static gpointer
_g_object_ref0 (gpointer self)
{
	return self ? g_object_ref (self) : NULL;
}

static GCalcMathExpression*
gcalc_math_term_real_evaluate (GCalcMathTerm* self,
                               GError** error)
{
	GCalcMathExpression* current = NULL;
	GCalcMathOperator* current_operator = NULL;
	gboolean first = FALSE;
	GCalcMathExpression* _tmp82_;
	GError* _inner_error0_ = NULL;
	GCalcMathExpression* result;
	current = NULL;
	current_operator = NULL;
	first = TRUE;
	{
		GCalcExpressionContainer* _e_list = NULL;
		GCalcExpressionContainer* _tmp0_;
		GCalcExpressionContainer* _tmp1_;
		gint _e_size = 0;
		GCalcExpressionContainer* _tmp2_;
		gint _tmp3_;
		gint _tmp4_;
		gint _e_index = 0;
		_tmp0_ = gcalc_math_expression_get_expressions ((GCalcMathExpression*) self);
		_tmp1_ = _tmp0_;
		_e_list = _tmp1_;
		_tmp2_ = _e_list;
		_tmp3_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp2_);
		_tmp4_ = _tmp3_;
		_e_size = _tmp4_;
		_e_index = -1;
		while (TRUE) {
			gint _tmp5_;
			gint _tmp6_;
			GCalcMathExpression* e = NULL;
			GCalcExpressionContainer* _tmp7_;
			gpointer _tmp8_;
			GCalcMathExpression* _tmp9_;
			_e_index = _e_index + 1;
			_tmp5_ = _e_index;
			_tmp6_ = _e_size;
			if (!(_tmp5_ < _tmp6_)) {
				break;
			}
			_tmp7_ = _e_list;
			_tmp8_ = gee_abstract_list_get ((GeeAbstractList*) _tmp7_, _e_index);
			e = (GCalcMathExpression*) _tmp8_;
			_tmp9_ = e;
			if (GCALC_IS_MATH_OPERATOR (_tmp9_)) {
				gboolean _tmp10_ = FALSE;
				gboolean _tmp11_ = FALSE;
				GCalcMathExpression* _tmp12_;
				gboolean _tmp15_ = FALSE;
				GCalcMathExpression* _tmp16_;
				GCalcMathExpression* _tmp20_;
				GCalcMathOperator* _tmp21_;
				_tmp12_ = e;
				if (GCALC_IS_MATH_MINUS (_tmp12_)) {
					_tmp11_ = TRUE;
				} else {
					GCalcMathExpression* _tmp13_;
					_tmp13_ = e;
					_tmp11_ = GCALC_IS_MATH_PLUS (_tmp13_);
				}
				if (!_tmp11_) {
					_tmp10_ = first;
				} else {
					_tmp10_ = FALSE;
				}
				if (_tmp10_) {
					GError* _tmp14_;
					_tmp14_ = g_error_new_literal (GCALC_TERM_ERROR, GCALC_TERM_ERROR_INVALID_OPERATOR, _ ("Incorrect position for operator in expression"));
					_inner_error0_ = _tmp14_;
					g_propagate_error (error, _inner_error0_);
					_g_object_unref0 (e);
					_g_object_unref0 (current_operator);
					_g_object_unref0 (current);
					return NULL;
				}
				_tmp16_ = e;
				if (GCALC_IS_MATH_MINUS (_tmp16_)) {
					_tmp15_ = first;
				} else {
					_tmp15_ = FALSE;
				}
				if (_tmp15_) {
					GCalcConstant* c = NULL;
					GCalcConstant* _tmp17_;
					GCalcConstant* _tmp18_;
					GCalcMathExpression* _tmp19_;
					_tmp17_ = gcalc_constant_new_double (-1.0);
					c = _tmp17_;
					_tmp18_ = c;
					_tmp19_ = _g_object_ref0 ((GCalcMathExpression*) _tmp18_);
					_g_object_unref0 (current);
					current = _tmp19_;
					first = FALSE;
					_g_object_unref0 (c);
				}
				_tmp20_ = e;
				_tmp21_ = _g_object_ref0 (GCALC_IS_MATH_OPERATOR (_tmp20_) ? ((GCalcMathOperator*) _tmp20_) : NULL);
				_g_object_unref0 (current_operator);
				current_operator = _tmp21_;
				_g_object_unref0 (e);
				continue;
			} else {
				GCalcMathExpression* _tmp22_;
				_tmp22_ = e;
				if (GCALC_IS_MATH_CONSTANT (_tmp22_)) {
					GCalcMathExpression* _tmp23_;
					_tmp23_ = current;
					if (_tmp23_ == NULL) {
						GCalcMathExpression* _tmp24_;
						GCalcMathExpression* _tmp25_;
						_tmp24_ = e;
						_tmp25_ = _g_object_ref0 (_tmp24_);
						_g_object_unref0 (current);
						current = _tmp25_;
						first = FALSE;
					} else {
						GCalcMathExpression* _tmp26_;
						_tmp26_ = current;
						if (GCALC_IS_MATH_CONSTANT (_tmp26_)) {
							GCalcMathOperator* _tmp27_;
							_tmp27_ = current_operator;
							if (_tmp27_ != NULL) {
								GCalcMathExpression* _tmp28_ = NULL;
								GCalcMathExpression* _tmp29_;
								GCalcMathExpression* _tmp30_;
								GCalcMathOperator* _tmp31_;
								GCalcMathExpression* _tmp32_;
								GCalcMathExpression* _tmp33_;
								_tmp29_ = current;
								_tmp30_ = e;
								_tmp31_ = current_operator;
								_tmp32_ = gcalc_math_term_evaluate_constants (G_TYPE_CHECK_INSTANCE_CAST (_tmp29_, GCALC_TYPE_MATH_CONSTANT, GCalcMathConstant), G_TYPE_CHECK_INSTANCE_CAST (_tmp30_, GCALC_TYPE_MATH_CONSTANT, GCalcMathConstant), _tmp31_, &_inner_error0_);
								_tmp28_ = _tmp32_;
								if (G_UNLIKELY (_inner_error0_ != NULL)) {
									g_propagate_error (error, _inner_error0_);
									_g_object_unref0 (e);
									_g_object_unref0 (current_operator);
									_g_object_unref0 (current);
									return NULL;
								}
								_tmp33_ = _tmp28_;
								_tmp28_ = NULL;
								_g_object_unref0 (current);
								current = _tmp33_;
								_g_object_unref0 (_tmp28_);
							}
						}
					}
				} else {
					GCalcMathExpression* _tmp34_;
					_tmp34_ = e;
					if (GCALC_IS_MATH_GROUP (_tmp34_)) {
						GCalcMathExpression* ev = NULL;
						GCalcMathExpression* _tmp35_;
						GCalcMathExpression* _tmp36_;
						GCalcMathExpression* _tmp37_;
						_tmp35_ = e;
						_tmp36_ = gcalc_math_group_evaluate (G_TYPE_CHECK_INSTANCE_CAST (_tmp35_, GCALC_TYPE_MATH_GROUP, GCalcMathGroup), &_inner_error0_);
						ev = _tmp36_;
						if (G_UNLIKELY (_inner_error0_ != NULL)) {
							g_propagate_error (error, _inner_error0_);
							_g_object_unref0 (e);
							_g_object_unref0 (current_operator);
							_g_object_unref0 (current);
							return NULL;
						}
						_tmp37_ = current;
						if (_tmp37_ == NULL) {
							GCalcMathExpression* _tmp38_;
							GCalcMathExpression* _tmp39_;
							_tmp38_ = ev;
							_tmp39_ = _g_object_ref0 (_tmp38_);
							_g_object_unref0 (current);
							current = _tmp39_;
							first = FALSE;
						} else {
							gboolean _tmp40_ = FALSE;
							GCalcMathExpression* _tmp41_;
							_tmp41_ = current;
							if (GCALC_IS_MATH_CONSTANT (_tmp41_)) {
								GCalcMathExpression* _tmp42_;
								_tmp42_ = ev;
								_tmp40_ = GCALC_IS_MATH_CONSTANT (_tmp42_);
							} else {
								_tmp40_ = FALSE;
							}
							if (_tmp40_) {
								GCalcMathOperator* _tmp43_;
								_tmp43_ = current_operator;
								if (_tmp43_ != NULL) {
									GCalcMathExpression* _tmp44_ = NULL;
									GCalcMathExpression* _tmp45_;
									GCalcMathExpression* _tmp46_;
									GCalcMathOperator* _tmp47_;
									GCalcMathExpression* _tmp48_;
									GCalcMathExpression* _tmp49_;
									_tmp45_ = current;
									_tmp46_ = ev;
									_tmp47_ = current_operator;
									_tmp48_ = gcalc_math_term_evaluate_constants (G_TYPE_CHECK_INSTANCE_CAST (_tmp45_, GCALC_TYPE_MATH_CONSTANT, GCalcMathConstant), G_TYPE_CHECK_INSTANCE_CAST (_tmp46_, GCALC_TYPE_MATH_CONSTANT, GCalcMathConstant), _tmp47_, &_inner_error0_);
									_tmp44_ = _tmp48_;
									if (G_UNLIKELY (_inner_error0_ != NULL)) {
										g_propagate_error (error, _inner_error0_);
										_g_object_unref0 (ev);
										_g_object_unref0 (e);
										_g_object_unref0 (current_operator);
										_g_object_unref0 (current);
										return NULL;
									}
									_tmp49_ = _tmp44_;
									_tmp44_ = NULL;
									_g_object_unref0 (current);
									current = _tmp49_;
									_g_object_unref0 (_tmp44_);
								}
							}
						}
						_g_object_unref0 (ev);
					} else {
						GCalcMathExpression* _tmp50_;
						_tmp50_ = e;
						if (GCALC_IS_MATH_FUNCTION (_tmp50_)) {
							GCalcMathExpression* ev = NULL;
							GCalcMathExpression* _tmp51_;
							GCalcMathExpression* _tmp52_;
							GCalcMathExpression* _tmp53_;
							_tmp51_ = e;
							_tmp52_ = gcalc_math_function_evaluate (G_TYPE_CHECK_INSTANCE_CAST (_tmp51_, GCALC_TYPE_MATH_FUNCTION, GCalcMathFunction), &_inner_error0_);
							ev = _tmp52_;
							if (G_UNLIKELY (_inner_error0_ != NULL)) {
								g_propagate_error (error, _inner_error0_);
								_g_object_unref0 (e);
								_g_object_unref0 (current_operator);
								_g_object_unref0 (current);
								return NULL;
							}
							_tmp53_ = current;
							if (_tmp53_ == NULL) {
								GCalcMathExpression* _tmp54_;
								GCalcMathExpression* _tmp55_;
								_tmp54_ = ev;
								_tmp55_ = _g_object_ref0 (_tmp54_);
								_g_object_unref0 (current);
								current = _tmp55_;
								first = FALSE;
							} else {
								gboolean _tmp56_ = FALSE;
								GCalcMathExpression* _tmp57_;
								_tmp57_ = current;
								if (GCALC_IS_MATH_CONSTANT (_tmp57_)) {
									GCalcMathExpression* _tmp58_;
									_tmp58_ = ev;
									_tmp56_ = GCALC_IS_MATH_CONSTANT (_tmp58_);
								} else {
									_tmp56_ = FALSE;
								}
								if (_tmp56_) {
									GCalcMathOperator* _tmp59_;
									_tmp59_ = current_operator;
									if (_tmp59_ != NULL) {
										GCalcMathExpression* _tmp60_ = NULL;
										GCalcMathExpression* _tmp61_;
										GCalcMathExpression* _tmp62_;
										GCalcMathOperator* _tmp63_;
										GCalcMathExpression* _tmp64_;
										GCalcMathExpression* _tmp65_;
										_tmp61_ = current;
										_tmp62_ = ev;
										_tmp63_ = current_operator;
										_tmp64_ = gcalc_math_term_evaluate_constants (G_TYPE_CHECK_INSTANCE_CAST (_tmp61_, GCALC_TYPE_MATH_CONSTANT, GCalcMathConstant), G_TYPE_CHECK_INSTANCE_CAST (_tmp62_, GCALC_TYPE_MATH_CONSTANT, GCalcMathConstant), _tmp63_, &_inner_error0_);
										_tmp60_ = _tmp64_;
										if (G_UNLIKELY (_inner_error0_ != NULL)) {
											g_propagate_error (error, _inner_error0_);
											_g_object_unref0 (ev);
											_g_object_unref0 (e);
											_g_object_unref0 (current_operator);
											_g_object_unref0 (current);
											return NULL;
										}
										_tmp65_ = _tmp60_;
										_tmp60_ = NULL;
										_g_object_unref0 (current);
										current = _tmp65_;
										_g_object_unref0 (_tmp60_);
									}
								}
							}
							_g_object_unref0 (ev);
						} else {
							GCalcMathExpression* _tmp66_;
							_tmp66_ = e;
							if (GCALC_IS_MATH_VARIABLE (_tmp66_)) {
								GCalcMathExpression* ev = NULL;
								GCalcMathExpression* _tmp67_;
								GCalcMathExpression* _tmp68_;
								GCalcMathExpression* _tmp69_;
								_tmp67_ = e;
								_tmp68_ = gcalc_math_variable_evaluate (G_TYPE_CHECK_INSTANCE_CAST (_tmp67_, GCALC_TYPE_MATH_VARIABLE, GCalcMathVariable), &_inner_error0_);
								ev = _tmp68_;
								if (G_UNLIKELY (_inner_error0_ != NULL)) {
									g_propagate_error (error, _inner_error0_);
									_g_object_unref0 (e);
									_g_object_unref0 (current_operator);
									_g_object_unref0 (current);
									return NULL;
								}
								_tmp69_ = current;
								if (_tmp69_ == NULL) {
									GCalcMathExpression* _tmp70_;
									GCalcMathExpression* _tmp71_;
									_tmp70_ = ev;
									_tmp71_ = _g_object_ref0 (_tmp70_);
									_g_object_unref0 (current);
									current = _tmp71_;
									first = FALSE;
								} else {
									gboolean _tmp72_ = FALSE;
									GCalcMathExpression* _tmp73_;
									_tmp73_ = current;
									if (GCALC_IS_MATH_CONSTANT (_tmp73_)) {
										GCalcMathExpression* _tmp74_;
										_tmp74_ = ev;
										_tmp72_ = GCALC_IS_MATH_CONSTANT (_tmp74_);
									} else {
										_tmp72_ = FALSE;
									}
									if (_tmp72_) {
										GCalcMathOperator* _tmp75_;
										_tmp75_ = current_operator;
										if (_tmp75_ != NULL) {
											GCalcMathExpression* _tmp76_ = NULL;
											GCalcMathExpression* _tmp77_;
											GCalcMathExpression* _tmp78_;
											GCalcMathOperator* _tmp79_;
											GCalcMathExpression* _tmp80_;
											GCalcMathExpression* _tmp81_;
											_tmp77_ = current;
											_tmp78_ = ev;
											_tmp79_ = current_operator;
											_tmp80_ = gcalc_math_term_evaluate_constants (G_TYPE_CHECK_INSTANCE_CAST (_tmp77_, GCALC_TYPE_MATH_CONSTANT, GCalcMathConstant), G_TYPE_CHECK_INSTANCE_CAST (_tmp78_, GCALC_TYPE_MATH_CONSTANT, GCalcMathConstant), _tmp79_, &_inner_error0_);
											_tmp76_ = _tmp80_;
											if (G_UNLIKELY (_inner_error0_ != NULL)) {
												g_propagate_error (error, _inner_error0_);
												_g_object_unref0 (ev);
												_g_object_unref0 (e);
												_g_object_unref0 (current_operator);
												_g_object_unref0 (current);
												return NULL;
											}
											_tmp81_ = _tmp76_;
											_tmp76_ = NULL;
											_g_object_unref0 (current);
											current = _tmp81_;
											_g_object_unref0 (_tmp76_);
										}
									}
								}
								_g_object_unref0 (ev);
							}
						}
					}
				}
			}
			_g_object_unref0 (e);
		}
	}
	_tmp82_ = current;
	if (_tmp82_ == NULL) {
		GError* _tmp83_;
		_tmp83_ = g_error_new_literal (GCALC_TERM_ERROR, GCALC_TERM_ERROR_EVALUATION_FAIL, _ ("Evaluation fail on Term"));
		_inner_error0_ = _tmp83_;
		g_propagate_error (error, _inner_error0_);
		_g_object_unref0 (current_operator);
		_g_object_unref0 (current);
		return NULL;
	}
	result = current;
	_g_object_unref0 (current_operator);
	return result;
}

GCalcMathExpression*
gcalc_math_term_evaluate (GCalcMathTerm* self,
                          GError** error)
{
	GCalcMathTermIface* _iface_;
	g_return_val_if_fail (self != NULL, NULL);
	_iface_ = GCALC_MATH_TERM_GET_INTERFACE (self);
	if (_iface_->evaluate) {
		return _iface_->evaluate (self, error);
	}
	return NULL;
}

/**
   * Take two {@link MathConstant} and evaluate them using the given {@link MathOperator}
   */
GCalcMathExpression*
gcalc_math_term_evaluate_constants (GCalcMathConstant* c1,
                                    GCalcMathConstant* c2,
                                    GCalcMathOperator* op,
                                    GError** error)
{
	GCalcMathExpression* res = NULL;
	GCalcMathExpression* _tmp4_;
	GError* _inner_error0_ = NULL;
	GCalcMathExpression* result;
	g_return_val_if_fail (c1 != NULL, NULL);
	g_return_val_if_fail (c2 != NULL, NULL);
	g_return_val_if_fail (op != NULL, NULL);
	res = NULL;
	if (GCALC_IS_MATH_MINUS (op)) {
		GCalcMathConstant* _tmp0_;
		_tmp0_ = gcalc_math_constant_multiply (c1, c2);
		_g_object_unref0 (res);
		res = (GCalcMathExpression*) _tmp0_;
	}
	if (GCALC_IS_MATH_MULTIPLY (op)) {
		GCalcMathConstant* _tmp1_;
		_tmp1_ = gcalc_math_constant_multiply (c1, c2);
		_g_object_unref0 (res);
		res = (GCalcMathExpression*) _tmp1_;
	}
	if (GCALC_IS_MATH_DIVISION (op)) {
		GCalcMathConstant* _tmp2_;
		_tmp2_ = gcalc_math_constant_divide (c1, c2);
		_g_object_unref0 (res);
		res = (GCalcMathExpression*) _tmp2_;
	}
	if (GCALC_IS_MATH_POW (op)) {
		GCalcMathConstant* _tmp3_;
		_tmp3_ = gcalc_math_constant_pow (c1, c2);
		_g_object_unref0 (res);
		res = (GCalcMathExpression*) _tmp3_;
	}
	_tmp4_ = res;
	if (_tmp4_ == NULL) {
		GError* _tmp5_;
		_tmp5_ = g_error_new_literal (GCALC_TERM_ERROR, GCALC_TERM_ERROR_INVALID_OPERATOR, _ ("Unsupported operator in term's expression"));
		_inner_error0_ = _tmp5_;
		g_propagate_error (error, _inner_error0_);
		_g_object_unref0 (res);
		return NULL;
	}
	result = res;
	return result;
}

static void
gcalc_math_term_default_init (GCalcMathTermIface * iface,
                              gpointer iface_data)
{
	iface->add = gcalc_math_term_real_add;
	iface->evaluate = gcalc_math_term_real_evaluate;
}

/**
 * A term in a math expression.
 *
 * Is a container of other terms.
 */
static GType
gcalc_math_term_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (GCalcMathTermIface), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) gcalc_math_term_default_init, (GClassFinalizeFunc) NULL, NULL, 0, 0, (GInstanceInitFunc) NULL, NULL };
	GType gcalc_math_term_type_id;
	gcalc_math_term_type_id = g_type_register_static (G_TYPE_INTERFACE, "GCalcMathTerm", &g_define_type_info, 0);
	g_type_interface_add_prerequisite (gcalc_math_term_type_id, G_TYPE_OBJECT);
	g_type_interface_add_prerequisite (gcalc_math_term_type_id, GCALC_TYPE_MATH_EXPRESSION);
	return gcalc_math_term_type_id;
}

GType
gcalc_math_term_get_type (void)
{
	static volatile gsize gcalc_math_term_type_id__once = 0;
	if (g_once_init_enter (&gcalc_math_term_type_id__once)) {
		GType gcalc_math_term_type_id;
		gcalc_math_term_type_id = gcalc_math_term_get_type_once ();
		g_once_init_leave (&gcalc_math_term_type_id__once, gcalc_math_term_type_id);
	}
	return gcalc_math_term_type_id__once;
}

GQuark
gcalc_term_error_quark (void)
{
	return g_quark_from_static_string ("gcalc-term-error-quark");
}

static GType
gcalc_term_error_get_type_once (void)
{
	static const GEnumValue values[] = {{GCALC_TERM_ERROR_INVALID_OPERATOR, "GCALC_TERM_ERROR_INVALID_OPERATOR", "invalid-operator"}, {GCALC_TERM_ERROR_EVALUATION_FAIL, "GCALC_TERM_ERROR_EVALUATION_FAIL", "evaluation-fail"}, {0, NULL, NULL}};
	GType gcalc_term_error_type_id;
	gcalc_term_error_type_id = g_enum_register_static ("GCalcTermError", values);
	return gcalc_term_error_type_id;
}

GType
gcalc_term_error_get_type (void)
{
	static volatile gsize gcalc_term_error_type_id__once = 0;
	if (g_once_init_enter (&gcalc_term_error_type_id__once)) {
		GType gcalc_term_error_type_id;
		gcalc_term_error_type_id = gcalc_term_error_get_type_once ();
		g_once_init_leave (&gcalc_term_error_type_id__once, gcalc_term_error_type_id);
	}
	return gcalc_term_error_type_id__once;
}

