/*
 * Copyright 2008-2009 Katholieke Universiteit Leuven
 * Copyright 2011      INRIA Saclay
 *
 * Use of this software is governed by the GNU LGPLv2.1 license
 *
 * Written by Sven Verdoolaege, K.U.Leuven, Departement
 * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
 * and INRIA Saclay - Ile-de-France, Parc Club Orsay Universite,
 * ZAC des vignes, 4 rue Jacques Monod, 91893 Orsay, France
 */

#define xCAT(A,B) A ## B
#define CAT(A,B) xCAT(A,B)
#undef EL
#define EL CAT(isl_,BASE)
#define xFN(TYPE,NAME) TYPE ## _ ## NAME
#define FN(TYPE,NAME) xFN(TYPE,NAME)
#define xLIST(EL) EL ## _list
#define LIST(EL) xLIST(EL)

isl_ctx *FN(LIST(EL),get_ctx)(__isl_keep LIST(EL) *list)
{
	return list ? list->ctx : NULL;
}

__isl_give LIST(EL) *FN(LIST(EL),alloc)(isl_ctx *ctx, int n)
{
	LIST(EL) *list;

	if (n < 0)
		isl_die(ctx, isl_error_invalid,
			"cannot create list of negative length",
			return NULL);
	list = isl_alloc(ctx, LIST(EL),
			 sizeof(LIST(EL)) + (n - 1) * sizeof(struct EL *));
	if (!list)
		return NULL;

	list->ctx = ctx;
	isl_ctx_ref(ctx);
	list->ref = 1;
	list->size = n;
	list->n = 0;
	return list;
}

__isl_give LIST(EL) *FN(LIST(EL),copy)(__isl_keep LIST(EL) *list)
{
	if (!list)
		return NULL;

	list->ref++;
	return list;
}

__isl_give LIST(EL) *FN(LIST(EL),dup)(__isl_keep LIST(EL) *list)
{
	int i;
	LIST(EL) *dup;

	if (!list)
		return NULL;

	dup = FN(LIST(EL),alloc)(FN(LIST(EL),get_ctx)(list), list->n);
	if (!dup)
		return NULL;
	for (i = 0; i < list->n; ++i)
		dup = FN(LIST(EL),add)(dup, FN(EL,copy)(list->p[i]));
	return dup;
}

__isl_give LIST(EL) *FN(LIST(EL),add)(__isl_take LIST(EL) *list,
	__isl_take struct EL *el)
{
	if (!list || !el)
		goto error;
	isl_assert(list->ctx, list->n < list->size, goto error);
	list->p[list->n] = el;
	list->n++;
	return list;
error:
	FN(EL,free)(el);
	FN(LIST(EL),free)(list);
	return NULL;
}

void FN(LIST(EL),free)(__isl_take LIST(EL) *list)
{
	int i;

	if (!list)
		return;

	if (--list->ref > 0)
		return;

	isl_ctx_deref(list->ctx);
	for (i = 0; i < list->n; ++i)
		FN(EL,free)(list->p[i]);
	free(list);
}

int FN(FN(LIST(EL),n),BASE)(__isl_keep LIST(EL) *list)
{
	return list ? list->n : 0;
}

__isl_give EL *FN(FN(LIST(EL),get),BASE)(__isl_keep LIST(EL) *list, int index)
{
	if (!list)
		return NULL;
	if (index < 0 || index >= list->n)
		isl_die(list->ctx, isl_error_invalid,
			"index out of bounds", return NULL);
	return FN(EL,copy)(list->p[index]);
}

int FN(LIST(EL),foreach)(__isl_keep LIST(EL) *list,
	int (*fn)(__isl_take EL *el, void *user), void *user)
{
	int i;

	if (!list)
		return -1;

	for (i = 0; i < list->n; ++i) {
		EL *el = FN(EL,copy(list->p[i]));
		if (!el)
			return -1;
		if (fn(el, user) < 0)
			return -1;
	}

	return 0;
}

__isl_give isl_printer *CAT(isl_printer_print_,LIST(BASE))(
	__isl_take isl_printer *p, __isl_keep LIST(EL) *list)
{
	int i;

	if (!p || !list)
		goto error;
	p = isl_printer_print_str(p, "(");
	for (i = 0; i < list->n; ++i) {
		if (i)
			p = isl_printer_print_str(p, ",");
		p = CAT(isl_printer_print_,BASE)(p, list->p[i]);
	}
	p = isl_printer_print_str(p, ")");
	return p;
error:
	isl_printer_free(p);
	return NULL;
}

void FN(LIST(EL),dump)(__isl_keep LIST(EL) *list)
{
	isl_printer *printer;

	if (!list)
		return;

	printer = isl_printer_to_file(FN(LIST(EL),get_ctx)(list), stderr);
	printer = CAT(isl_printer_print_,LIST(BASE))(printer, list);
	printer = isl_printer_end_line(printer);

	isl_printer_free(printer);
}
