# ifndef __DPA_H__
# define __DPA_H__
/*
 * $Header: /home/rockware/cvs-main/operator/c-src/dpa.h,v 1.1 1995/03/16 11:28:13 erez Exp $
 * ----------------------------------------------------------------------------
 * Dynamic Pointers Array.
 * This new general array type has the following structure:
 * First the dpa struct then right after it in memory (without any alignment
 * problems) the pointers.
 *
 * Note:
 *   The return value is a pointer to the first element of the array.
 *   And not to the dpa structure.
 *
 * Written by Erez Strauss. 1994.
 *
 * $Log: dpa.h,v $
 * Revision 1.1  1995/03/16  11:28:13  erez
 * Initial revision
 *
 * Revision 2.2  1994/12/14  16:40:33  erez
 * (1)(U) missing variable name, was added.
 *
 * Revision 2.1  1994/11/01  15:17:42  erez
 * (1)(BGFX) spelling drive ==> derive.
 *
 * Revision 2.0  1994/07/31  09:47:24  erez
 * This is a new version that moved to the tool library.
 *
 * Revision 1.1  1994/07/31  08:02:33  erez
 * (1)(U) More comments. (2) Moved to library. (3) Templates like macros
 *   were added
 *
 * Revision 1.6  1994/05/23  10:25:25  erez
 * (1) (N) insert function was written to insert a value in specific location
 *   in the array (moves up some other elements).
 * (2) (N) remove_no_order function - remove an entry in constant time.
 *   By moving the last entry to the place of the one to be removed.
 *
 * Revision 1.5  1994/05/13  08:19:53  erez
 * (1) (N) The dpa_dup were added to the header file.
 * (2) (U) The memcpy also copy the last null entry.
 *
 * Revision 1.4  1994/05/09  10:59:13  erez
 * (1) (BG-FX) The dpa_bsearch function returns now index into the dpa.
 *
 * Revision 1.3  1994/05/04  12:08:18  erez
 * (1) dpa indexes are long from now on (maybe non portable),
 * (2) new indentation.
 *
 * Revision 1.2  1994/04/24  06:56:59  erez
 * New dpa function: dpa_merge() - the function create a new dpa that contains
 * the values from both arrays.
 *
 * Revision 1.1.1.1  1994/04/17  15:48:27  erez
 *
 * ----------------------------------------------------------------------------
 */

# if ! defined ( NO_IDENT )
#   if defined ( __GNUC__ )
#     ident "@(#)$Id: dpa.h,v 1.1 1995/03/16 11:28:13 erez Exp $"
#   else /* __GNUC__ */
      static const char dpa_h_id[] = "@(#)$Id: dpa.h,v 1.1 1995/03/16 11:28:13 erez Exp $";
#   endif /* __GNUC__ */
# endif /* NO_IDENT */

typedef struct
    {
    long allocated;   /* Number of pointers in this array */
    long in_use;      /* Number of pointers that are used by any application */
    } dpa;

/* dpa prototypes. */

extern void** dpa_add (void** vp, void* a); 
extern long   dpa_bsearch (void** vp, void* value, int (*compare_function) (void** , void** )); 
extern void   dpa_delete (void** vp); 
extern void** dpa_dup (void** vp);
extern long   dpa_in_use (void** vp); 
extern void** dpa_insert (void** vp, long index, void* a);
extern void** dpa_merge (void** vp_a, void** vp_b);
extern void** dpa_new (long count); 
extern void** dpa_remove (void** vp, long index); 
extern void** dpa_remove_no_order (void** vp, long index);
extern long   dpa_search (void** vp, void* val); 
extern void   dpa_sort (void** vp, int (*sort_function) (void** , void** )); 


/* Templete part - with the extern decleration and a global definitions. */

# define TKN(A,B) A##_##B

# define DERIVE_DPA(TYPE) \
EXTERN_DERIVE_DPA (TYPE) \
TKN (TYPE, dpa) TKN (TYPE, dpa_new) (long count) \
    { return (TKN (TYPE, dpa))dpa_new (count); } \
void TKN (TYPE, dpa_delete) (TKN (TYPE, dpa) tvp) \
    { dpa_delete ((void**)tvp); } \
TKN (TYPE, dpa) TKN (TYPE, dpa_add) (TKN (TYPE, dpa) tvp, TYPE* ta) \
    { return (TKN (TYPE, dpa))dpa_add ((void**)tvp, (void*)ta); } \
long TKN (TYPE, dpa_bsearch) (TKN (TYPE, dpa) tvp, TYPE* tvalue, int (*compare_function) (TKN (TYPE, dpa), TKN (TYPE, dpa))) \
    { return dpa_bsearch ((void**)tvp, (void*)tvalue, (int (*)(void**, void**))compare_function); } \
long TKN (TYPE, dpa_in_use) (TKN (TYPE, dpa) tvp) \
    { return dpa_in_use ((void**)tvp); } \
TKN (TYPE, dpa) TKN (TYPE, dpa_dup) (TKN (TYPE, dpa) tvp) \
    { return (TKN (TYPE, dpa))dpa_dup ((void**)tvp); } \
TKN (TYPE, dpa) TKN (TYPE, dpa_insert) (TKN (TYPE, dpa) tvp, long index, TYPE* ta) \
    { return (TKN (TYPE, dpa))dpa_insert ((void**)tvp, index, (void*)ta); } \
TKN (TYPE, dpa) TKN (TYPE, dpa_merge) (TKN (TYPE, dpa) tvp_a, TKN (TYPE, dpa) tvp_b) \
    { return (TKN (TYPE, dpa))dpa_merge ((void**)tvp_a, (void**)tvp_b); } \
TKN (TYPE, dpa) TKN (TYPE, dpa_remove) (TKN (TYPE, dpa) tvp, long index) \
    { return (TKN (TYPE, dpa))dpa_remove ((void**)tvp, index); } \
TKN (TYPE, dpa) TKN (TYPE, dpa_remove_no_order) (TKN (TYPE, dpa) tvp, long index) \
    { return (TKN (TYPE, dpa))dpa_remove_no_order ((void**)tvp, index); } \
long TKN (TYPE, dpa_search) (TKN (TYPE, dpa) tvp, TYPE* ta) \
    { return dpa_search ((void**)tvp, (void*)ta); } \
void TKN (TYPE, dpa_sort) (TKN (TYPE, dpa) tvp, int (*compare_function) (TKN (TYPE, dpa), TKN (TYPE, dpa))) \
    { dpa_sort ((void**)tvp, (int (*)(void**, void**))compare_function); }

/* External decleration of the new typed DPA functions */

# define EXTERN_DERIVE_DPA(TYPE) \
typedef TYPE** TKN (TYPE, dpa); \
extern TKN (TYPE, dpa) TKN (TYPE, dpa_new) (long count); \
extern void TKN (TYPE, dpa_delete) (TKN (TYPE, dpa) tvp); \
extern TKN (TYPE, dpa) TKN (TYPE, dpa_add) (TKN (TYPE, dpa) tvp, TYPE* ta); \
extern long TKN (TYPE, dpa_bsearch) (TKN (TYPE, dpa) tvp, TYPE* tvalue, int (*compare_function) (TKN (TYPE, dpa), TKN (TYPE, dpa))); \
extern long TKN (TYPE, dpa_in_use) (TKN (TYPE, dpa) tvp); \
extern TKN (TYPE, dpa) TKN (TYPE, dpa_dup) (TKN (TYPE, dpa) tvp); \
extern TKN (TYPE, dpa) TKN (TYPE, dpa_insert) (TKN (TYPE, dpa) tvp, long index, TYPE* ta); \
extern TKN (TYPE, dpa) TKN (TYPE, dpa_merge) (TKN (TYPE, dpa) tvp_a, TKN (TYPE, dpa) tvp_b); \
extern TKN (TYPE, dpa) TKN (TYPE, dpa_remove) (TKN (TYPE, dpa) tvp, long index); \
extern TKN (TYPE, dpa) TKN (TYPE, dpa_remove_no_order) (TKN (TYPE, dpa) tvp, long index); \
extern long TKN (TYPE, dpa_search) (TKN (TYPE, dpa) tvp, TYPE* ta); \
extern void TKN (TYPE, dpa_sort) (TKN (TYPE, dpa) tvp, int (*compare_function) (TKN (TYPE, dpa), TKN (TYPE, dpa)));

/* End of Templete part. */

# endif /* define __DPA_H__ */

/* End of file: dpa.h ______________________________________________________ */
