/* ------------------------------------------------------------------------ */
/*                                                                          */
/* [olist.h]                  Type: Operational List                        */
/*                                                                          */
/* Copyright (c) 1993 by D\olle, Manns                                      */
/* ------------------------------------------------------------------------ */

/* File generated by 'ctoh'. Don't change manually. */

#ifndef olist_INCL
#define olist_INCL


#include "standard.h"
#include "prim.h"      /* for primitive types */


#ifdef __cplusplus
extern "C" {
#endif


/* ------------------------- Types ---------------------------------------- */

/*  
   This module implements an operational, double linked list data type.
   In distinction from functional lists operational lists consist of
   a header and the double linked elements.
   Beside element type information the header contains references to the
   first, last and current element.
*/

AbstractType(OL_Lst); /* Abstract operational list type */
AbstractType(OL_Obj); /* Abstract list element type     */

/* ---------------------- Creation and basic access ------------------------- */

OL_Lst OL_create
       (                                         /* function parameter:  */
         OL_Obj (*copy)(OL_Obj obj),             /* copies an element    */
         void (*del)(OL_Obj obj),                /* frees an element     */
         c_bool (*equal)(OL_Obj lobj, OL_Obj robj) /* equality on elements */
       )
#define OL_CREATE(type,cpy,del,equ)                \
        OL_create                                  \
        (                                          \
          (OL_Obj (*)(OL_Obj obj))           cpy,  \
          (void (*)(OL_Obj obj))             del,  \
          (c_bool (*)(OL_Obj lobj, OL_Obj robj)) equ \
        )
#define OL_CREATE_ADT(type) OL_CREATE(type,primCopy,primFree,primEqual)
/** creates an operational list */
;

void OL_init(OL_Lst objlist)
#define OL_INIT OL_init
/* resets / initializes list 'objlist' */
;

INT OL_cnt(OL_Lst objlist)
#define OL_CNT OL_cnt
/* number of elements in list 'objlist' */
;


/* --------------------- List copy as reading cursor ------------------------ */

OL_Lst OL_copyL(OL_Lst dst, OL_Lst src)
#define OL_COPY_L OL_copyL
/* copies list 'src';
   fills list 'dst' with references to elements in 'src'
*/
;

void OL_delC(OL_Lst objlist)
#define OL_DEL_C OL_delC
/* removes list 'objlist' only - without elements */
;


/* --------------------------- Get & Search --------------------------------- */

OL_Obj OL_first(OL_Lst objlist)
#define OL_FIRST(type,lst) ( ABS_CAST(type,OL_first(lst)) )
/* first element of list 'objlist' */
;

OL_Obj OL_last(OL_Lst objlist)
#define OL_LAST(type,lst) ( ABS_CAST(type,OL_last(lst)) )
/* last element of list 'objlist' */
;

OL_Obj OL_next(OL_Lst objlist)
#define OL_NEXT(type,lst) ( ABS_CAST(type,OL_next(lst)) )
/* next element of list 'objlist' */
;

OL_Obj OL_prev(OL_Lst objlist)
#define OL_PREV(type,lst) ( ABS_CAST(type,OL_prev(lst)) )
/* previous element of list 'objlist' */
;

OL_Obj OL_curr(OL_Lst objlist)
#define OL_CURR(type,lst) ( ABS_CAST(type,OL_curr(lst)) )
/* current element of list 'objlist' */
;

INT OL_find(OL_Lst objlist, OL_Obj obj, c_bool (*cmp)(OL_Obj lobj, OL_Obj obj))
#define OL_FIND_EQ(lst,obj)  \
        OL_find(lst,ABS_CAST(OL_Obj,obj),(c_bool (*)(OL_Obj lobj, OL_Obj Obj))NULL)
#define OL_FIND(lst,obj,cmp) \
        OL_find(lst,ABS_CAST(OL_Obj,obj),(c_bool (*)(OL_Obj lobj, OL_Obj Obj)) cmp)
/* position of key element 'obj' in list 'objlist' or 0 ( linear search ) */
;


/* --------------------------- Insert & Update ------------------------------ */

OL_Obj OL_h_ins(OL_Lst objlist, OL_Obj newobj)
#define OL_H_INS(type,lst,obj) \
        ( ABS_CAST(type,OL_h_ins(lst,ABS_CAST(OL_Obj,obj))) )
/* inserts 'newobj' as first element in list 'objlist' */
;

OL_Obj OL_t_ins(OL_Lst objlist, OL_Obj newobj)
#define OL_T_INS(type,lst,obj) \
        ( ABS_CAST(type,OL_t_ins(lst,ABS_CAST(OL_Obj,obj))) )
/* inserts 'newobj' as last element in list 'objlist' */
;

OL_Obj OL_c_ins(OL_Lst objlist, OL_Obj newobj)
#define OL_C_INS(type,lst,obj) \
        ( ABS_CAST(type,OL_c_ins(lst,ABS_CAST(OL_Obj,obj))) )
/* inserts 'newobj' before current element in list 'objlist'
   ( or as last element, if 'objlist' is empty )
*/
;

OL_Obj OL_s_ins(OL_Lst objlist, OL_Obj newobj,
                c_bool (*cmpLE)(OL_Obj lobj, OL_Obj newobj))
#define OL_S_INS(type,lst,obj,cmpLE)                    \
        (                                               \
          ABS_CAST(type,OL_s_ins                        \
          (lst,ABS_CAST(OL_Obj,obj),                    \
          (c_bool (*)(OL_Obj lobj, OL_Obj newobj))cmpLE)) \
        )
/* inserts element 'newobj' in list 'objlist' ( sorted ) */
;

OL_Obj OL_upd(OL_Lst objlist, OL_Obj newobj)
#define OL_UPD(type,lst,obj) \
        ( ABS_CAST(type,OL_upd(lst,ABS_CAST(OL_Obj,obj))) )
/* updates current element in list 'objlist' with 'newobj' */
;


/* ----------------------------- Copy & Append ------------------------------ */

OL_Lst OL_copy(OL_Lst objlist)
#define OL_COPY OL_copy
/* copies list 'objlist' */
;

OL_Lst OL_append(OL_Lst dst, OL_Lst src)
#define OL_APPEND OL_append
/* appends list 'src' to list 'dst'; 'src' won't be removed */
;


/* ------------------------------ Delete ------------------------------------ */

void OL_clear(OL_Lst objlist)
#define OL_CLEAR OL_clear
/* clears list 'objlist'; removes all elements */
;

void OL_delL(OL_Lst objlist)
#define OL_DEL_L OL_delL
/* removes list 'objlist */
;

void OL_delE(OL_Lst objlist)
#define OL_DEL_E OL_delE
/* removes current element in list 'objlist' */
;


/* ----------------------------- Printing ----------------------------------- */

void OL_print(OL_Lst objlist, void (*pMbr)(OL_Obj obj), int cols, int indent)
#define OL_PRINT(lst,pMbr,cols,ind) \
        OL_print(lst,(void (*)(OL_Obj obj)) pMbr,(cols),(ind))
/* prints list 'objlist' to stdout */
;

void OL_print_ex
     (
       OL_Lst objlist,
       void (*pMbr)(OL_Obj obj,Any_T any,int nl,c_bool last),
       Any_T any, int cols, int indent
     )
#define OL_PRINT_EX(lst,pMbr,any,cols,ind) \
        OL_print_ex(lst, \
                    (void (*)(OL_Obj o,Any_T any,int nl,c_bool last))pMbr, \
                    (any),(cols),(ind))
/* prints list 'objlist' to stdout */
;


/* ---------------------- Predicates on lists & Mapping --------------------- */

c_bool OL_equal(OL_Lst left,OL_Lst right)
#define OL_EQUAL OL_equal
/* left = right ? */
;

StdCPtr OL_map
        (                                         /* function parameter:    */
          int argcnt,                             /* number of arguments    */
          void (*fun)(OL_Obj* objs, StdCPtr any), /* element map function   */
          StdCPtr any,                            /* any additional context */
          OL_Lst objlist, ...                     /* operational lists      */
        )
#define OL_MAP_F OL_map
/** executes 'fun' on each element in all lists */
;

c_bool OL_forall
     (                                         /* function parameter:    */
       int argcnt,                             /* number of arguments    */
       c_bool (*fun)(OL_Obj* objs, StdCPtr any), /* element map function   */
       StdCPtr any,                            /* any additional context */
       OL_Lst objlist, ...                     /* operational lists      */
     )
#define OL_FORALL_P OL_forall
/** executes 'fun' on each element in all lists;
*   on false execution stops
*/
;

c_bool OL_exists
     (                                         /* function parameter:    */
       int argcnt,                             /* number of arguments    */
       c_bool (*fun)(OL_Obj* objs, StdCPtr any), /* element map function   */
       StdCPtr any,                            /* any additional context */
       OL_Lst objlist, ...                     /* operational lists      */
     )
#define OL_EXISTS_P OL_exists
/** executes 'fun' on each element in all lists;
*   on true execution stops
*/
;



#ifdef __cplusplus
}
#endif

#endif
