#ifndef ARRAY_H__
#define ARRAY_H__ 1
#include "driver.h"
#include "typedefs.h"
#include "instrs.h" /* F_FILTER_ARRAY, F_MAP_ARRAY, F_INSER_ALIST */
#include "svalue.h"
/* --- Macros --- */
/* vector_t *ref_array(vector_t *a)
* Add another ref to array <a> and return the vector <a>.
*/
#define ref_array(a) ((a)->ref++, (a))
/* void free_array(vector_t *a)
* Subtract one ref from array <a>, and free the array fully if
* the refcount reaches zero.
*/
#define free_array(a) MACRO( if (--((a)->ref) <= 0) _free_vector(a); )
/* p_int deref_array(vector_t *a)
* Subtract one ref from array <a>, but don't check if it needs to
* be freed. Result is the number of refs left.
*/
#define deref_array(a) (--(a)->ref)
/* See array.c for a description of what the following macros do. */
/* Helper for LOCAL_VECn() */
#ifdef DEBUG
# define VEC_DEBUGREF(ref) ref,
#else
# define VEC_DEBUGREF(ref)
#endif
#define VEC_HEAD(size) size, 1, VEC_DEBUGREF(1) NULL
#if defined(DEBUG) && defined(MALLOC_smalloc)
# define VEC_SIZE(v) vec_size(v)
extern p_int vec_size (vector_t *vec);
extern vector_t *static_vector1, *static_vector2;
#else
# define VEC_SIZE(v) ((v)->size)
#endif
#define LOCAL_VEC1(name, type1) \
struct { vector_t v; } name \
= { { VEC_HEAD(1), { { type1, { 0 } } } } }
#define LOCAL_VEC2(name, type1, type2) \
struct { vector_t v; svalue_t item[1]; } name \
= { { VEC_HEAD(2), { { type1, { 0 } } } }, { { type2, { 0 } } } }
#if !defined(MALLOC_TRACE)
# define ALLOC_VECTOR(nelem, file, line) \
(vector_t *)xalloc(sizeof (vector_t) + \
sizeof(svalue_t) * (nelem - 1))
#else
# define ALLOC_VECTOR(nelem, file, line) \
(vector_t *)xalloc_traced(sizeof (vector_t) + \
sizeof(svalue_t) * (nelem - 1), file, line)
#endif /* MALLOC_TRACE */
/* --- Types --- */
/* --- struct vector: the array datatype ---
*
* When smalloc is used, the number of elements can be deduced from
* the memory block size, so the .size entry is not needed.
*/
struct vector_s {
p_int size; /* Number of contained elements */
p_int ref; /* Number of references */
#ifdef DEBUG
p_int extra_ref; /* Second refcount, used to check .ref. */
#endif
wiz_list_t *user; /* Save who made the vector */
svalue_t item[1];
};
/* --- Variables --- */
extern vector_t null_vector;
extern int num_arrays;
extern char *last_insert_alist_shared_string;
extern void (*allocate_array_error_handler) (char *, ...);
extern svalue_t assoc_shared_string_key;
/* --- Prototypes --- */
#if defined(MALLOC_TRACE)
#define allocate_array(n) (_allocate_array(n, __FILE__ "::allocate_array", __LINE__))
#define allocate_array_unlimited(n) (_allocate_array_unlimited(n, __FILE__ "::allocate_array", __LINE__))
#define allocate_uninit_array(n) (_allocate_array(n, __FILE__ "::allocate_uninit_array", __LINE__))
#define implode_string(a,d) (_implode_string(a,d, __FILE__ "::implode_string", __LINE__))
extern vector_t *_allocate_array(mp_int, char *, int);
extern vector_t *_allocate_array_unlimited(mp_int, char *, int);
extern vector_t *_allocate_uninit_array(mp_int, char *, int);
extern char *_implode_string(vector_t *, char *, char *, int);
#else
extern vector_t *allocate_array(mp_int);
extern vector_t *allocate_array_unlimited(mp_int);
extern vector_t *allocate_uninit_array(mp_int);
extern char *implode_string(vector_t *, char *);
#endif /* MALLOC_TRACE */
extern void _free_vector(vector_t *p);
extern void free_empty_vector(vector_t *p);
extern void check_for_destr(vector_t *v);
extern vector_t *explode_string(char *str, char *del);
extern vector_t *old_explode_string(char *str, char *del);
extern vector_t *slice_array(vector_t *p, mp_int from, mp_int to);
extern vector_t *make_unique(vector_t *arr, char *func, svalue_t *skipnum);
extern vector_t *add_array(vector_t *p, vector_t *q);
extern vector_t *subtract_array(vector_t *minuend, vector_t *subtrahend);
extern vector_t *all_inventory(object_t *ob);
extern vector_t *deep_inventory(object_t *ob, Bool take_top);
extern vector_t *order_alist(svalue_t *inlists, int listnum, Bool reuse);
extern int assoc(svalue_t *key, vector_t *list);
extern vector_t *intersect_alist(vector_t *a1, vector_t *a2);
extern int is_alist(vector_t *v);
extern vector_t *intersect_array(vector_t *a1, vector_t *a2);
extern vector_t *match_regexp(vector_t *v, char *pattern);
extern svalue_t *x_filter_array(svalue_t *sp, int num_arg);
extern svalue_t *x_map_array(svalue_t *sp, int num_arg);
extern svalue_t *f_sort_array(svalue_t *sp, int num_arg);
extern svalue_t *f_transpose_array(svalue_t *sp);
extern svalue_t *f_regexplode(svalue_t *sp);
#ifdef F_INSERT_ALIST
extern svalue_t *insert_alist(svalue_t *key, svalue_t *key_data, vector_t *list);
#endif
#ifdef F_FILTER_ARRAY
extern svalue_t *f_filter_array(svalue_t *sp, int num_arg);
#endif
#ifdef F_MAP_ARRAY
extern svalue_t *f_map_array(svalue_t *sp, int num_arg);
#endif
extern svalue_t *f_inherit_list (svalue_t *sp, int num_arg);
extern svalue_t *f_include_list (svalue_t *sp, int num_arg);
extern svalue_t *f_filter_objects(svalue_t *sp, int num_arg);
extern svalue_t *f_map_objects(svalue_t *sp, int num_arg);
extern svalue_t *f_functionlist(svalue_t *sp);
extern void set_vector_user(vector_t *p, object_t *owner);
extern long total_array_size(void);
#if defined(GC_SUPPORT)
extern void clear_array_size (void);
extern void count_array_size (vector_t *vec);
#endif
#endif /* ARRAY_H__ */