/*
 * This file is part of the Poliqarp suite.
 * 
 * Copyright (C) 2004-2009 by Instytut Podstaw Informatyki Polskiej
 * Akademii Nauk (IPI PAN; Institute of Computer Science, Polish
 * Academy of Sciences; cf. www.ipipan.waw.pl).  All rights reserved.
 * 
 * This file may be distributed and/or modified under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation and appearing in the file gpl.txt included in the packaging
 * of this file.  (See http://www.gnu.org/licenses/translations.html for
 * unofficial translations.)
 * 
 * A commercial license is available from IPI PAN (contact
 * Michal.Ciesiolka@ipipan.waw.pl or ipi@ipipan.waw.pl for more
 * information).  Licensees holding a valid commercial license from IPI
 * PAN may use this file in accordance with that license.
 * 
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE.
 */

/**
 * @file list.h
 * @brief Simple singly-linked lists.
 *
 * Declaration of a simple list type (list_t) and functions operating on values of this
 * type.
 */

#ifndef BP_LIST_H
#define BP_LIST_H

#include <poliqarp-config.h>

#include <sakura/common/memory-arena.h>

/** The type of a singly-linked list. */
typedef struct list_item {
   struct list_item *next;
   void *item;
}        *list_t;

/** Returns a list consisting only of a given item. */
list_t list_create(void *item);

/** Reverts a list in-place. */
list_t list_revert(list_t list);

/** Same as list_create, except that this function uses the given memory
 * arena as its memory source. */
list_t list_create_marena(void *item, struct marena *arena);

/** Appends a new element onto the list and returns the new list head. */
list_t list_prepend(list_t head, list_t node);

/** Returns number of elements in the list. */
size_t list_count(list_t head);

/** Calls a function on each argument of the list. */
void list_apply(list_t head, void (*fn) (void *));

/** 
 * Same as list_apply, except that the function takes two arguments, of which
 * the second one needs to be supplied to this function. 
 */
void list_apply2(list_t head, void (*fn) (void *, void *), void *arg);

/** 
 * Searches a list for the first node for which the given predicate function 
 * returns non-zero.
 * @return the corresponding node, or NULL if no such node has been found 
 */
list_t list_find(list_t node, int (*pred) (const void *));

/** 
 * Same as list_find, except that the predicate takes two arguments, of which
 * the second one needs to be supplied to this function.
 * @note Unlike list_find, the comparison function should return zero on success.
 */
list_t list_find2(list_t node, int (*cmp) (const void *, const void *),
   const void *arg);

/** 
 * Same as list_apply, except that the function returns a value which is 
 * subsequently assigned to the original value of the node.
 */
void list_transform(list_t node, void *(*fn) (void *));

/** Creates a vector of all items in the list. */
void **list_to_vector(list_t node);

/** Destroys the entire list.  If fn is non-NULL, it will be called on each item. */
void list_destroy(list_t node, void (*fn) (void *));

#endif /* BP_LIST_H */
