/*
 * list.h
 * A package for managing doubly-linked lists.
 */

/* Representation of a list element: */
struct _Element
{
  struct _Element  *p_prev;    /* Points to the previous element
                                 (or NULL in case of the list head). */
  double           value;      /* The stored value. */
  struct _Element  *p_next;    /* Points to the next element
                                 (or NULL in case of the list tail). */
};

typedef struct _Element Element;

/* Representation of a doubly-linked list: */
struct _List
{
  Element          *p_head;    /* Points to the list head
                                 (or NULL if the list is empty). */
  Element          *p_tail;    /* Points to the list tail
                                 (or NULL if the list is empty). */
  int              size;       /* The list size. */
};

typedef struct _List List;

/* ------------------------------------------------------------------------
 * Function: list_init
 * Purpose:  Initialize a doubly-linked list.
 * Returns:  A pointer to an allocated list.
 *           Note that this pointer should eventually be freed using 
 *           list_reset() and then free().
 */
List *list_init ();

/* ------------------------------------------------------------------------
 * Function: list_prepend
 * Purpose:  Insert a value as the list head.
 * Input:    p_list - The list.
 *           x      - The inserted value.
 * Returns:  Nothing.
 */
void list_prepend (List *p_list, double x);

/* ------------------------------------------------------------------------
 * Function: list_append
 * Purpose:  Insert a value as the list tail.
 * Input:    p_list - The list.
 *           x      - The inserted value.
 * Returns:  Nothing.
 */
void list_append (List *p_list, double x);

/* ------------------------------------------------------------------------
 * Function: list_find
 * Purpose:  Find a value in the list.
 * Input:    p_list - The list.
 *           x      - The queried value.
 * Returns:  A pointer to the list element that contains the queried value,
 *           or NULL if the value is not found in the list.
 */
const Element *list_find (const List *p_list, double x);

/* ------------------------------------------------------------------------
 * Function: list_delete
 * Purpose:  Delete a value from a list.
 * Input:    p_list - The list.
 *           x      - The value to be deleted.
 * Returns:  Non-zero in case the value was successfully deleted,
 *           or 0 if the value is not found in the list.
 */
int list_delete (List *p_list, double x);

/* ------------------------------------------------------------------------
 * Function: list_pop_first
 * Purpose:  Pop the first value from a list (and delete it).
 *           The list must not be empty.
 * Input:    p_list - The list.
 * Returns:  The value stored at the first element.
 */
double list_pop_first (List *p_list);

/* ------------------------------------------------------------------------
 * Function: list_pop_last
 * Purpose:  Pop the last value from a list (and delete it).
 *           The list must not be empty.
 * Input:    p_list - The list.
 * Returns:  The value stored at the last element.
 */
double list_pop_last (List *p_list);

/* ------------------------------------------------------------------------
 * Function: list_reset
 * Purpose:  Delete all objects from a list.
 * Input:    p_list - The list.
 * Returns:  Nothing.
 */
void list_reset (List *p_list);

