#ifndef _ARRAY_
#define _ARRAY_ 
#include "memory.h"
#include "list.h"
#include "misc.h"
typedef void (*ARRAY_DELETE_ELEM_FCT)(MEMORY,intptr_t);
typedef intptr_t *ARRAY;
void array_Init(void);
void array_Free(void);
ARRAY array_Create(MEMORY, int);
ARRAY array_CreateNoInit(MEMORY, int);
void array_Claim(ARRAY);
intptr_t array_GetSize(ARRAY);
BOOL array_IsEmpty(ARRAY ar);
intptr_t array_GetCapacity(ARRAY);
void array_SetSize(ARRAY,intptr_t);
void array_SetCapacity(ARRAY,intptr_t);
ARRAY array_RemoveIndex(ARRAY, int);
ARRAY array_RemoveIndexSwap(ARRAY, int);
ARRAY array_RemoveSwap(ARRAY, intptr_t*);
ARRAY array_Clean(ARRAY);
ARRAY array_Copy(MEMORY, ARRAY);
ARRAY array_CopyBySize(MEMORY, ARRAY);
ARRAY array_CopyWithElement(MEMORY, const ARRAY ar, intptr_t (*)(MEMORY, intptr_t));
ARRAY array_Add(MEMORY, ARRAY, intptr_t);
void array_AddNoGrow(ARRAY, intptr_t);
void array_AddToArrayAtIndex(MEMORY, ARRAY, int, intptr_t);
ARRAY array_Extend(MEMORY, ARRAY, intptr_t);
ARRAY array_Reserve(MEMORY, ARRAY, intptr_t);
ARRAY array_Append(MEMORY, ARRAY, ARRAY);
ARRAY array_Union(MEMORY, ARRAY, ARRAY);
ARRAY array_AddAtIndex(MEMORY, ARRAY, int, intptr_t);
void array_NAddAtIndex(ARRAY, int, intptr_t);
void array_RemoveAtIndex(ARRAY, int);
ARRAY array_AddGetIndex(MEMORY,ARRAY, intptr_t, int *);
intptr_t array_GetElement(ARRAY, int);
void array_SetElement(ARRAY, int, intptr_t);
BOOL array_ContainsElement(ARRAY, intptr_t, int *);
BOOL array_Member(ARRAY ar, intptr_t, BOOL (*)(intptr_t, intptr_t));
BOOL array_HasElement(ARRAY, intptr_t);
ARRAY array_Sort(ARRAY, int (*) ( const void *, const void * ));
int array_BSearch(ARRAY, const void *, int (*) ( const void *, const void * ));
size_t array_BSearch_r(ARRAY, const void *, COMPARE_FUNC, void *);
intptr_t array_Top(ARRAY);
intptr_t array_Pop(ARRAY);
ARRAY array_Push(MEMORY Memory, ARRAY ar, intptr_t el);
ARRAY array_Nconc(MEMORY, ARRAY, ARRAY);
void array_Reverse(ARRAY);
ARRAY array_AddList(MEMORY, ARRAY, LIST);
LIST array_ToList(MEMORY, ARRAY);
void array_PointerRemoveElement(ARRAY, intptr_t);
void array_RemoveElementIndex(ARRAY ar, unsigned i, intptr_t Element, BOOL (*Equal)(intptr_t, intptr_t));
ARRAY array_DeleteElementIfFree(ARRAY, BOOL (*)(intptr_t), void (*)(intptr_t));
void array_DeleteWithElement(MEMORY Memory, ARRAY ar, void* FreeState, void (*Free)(void*, intptr_t));
void array_DeleteElementFreeIndex(ARRAY ar, unsigned i, intptr_t Element, BOOL (*Equal)(intptr_t, intptr_t), void* FreeState, void (*Free)(void*, intptr_t));
ARRAY array_RemoveDuplicates(MEMORY, ARRAY Ar, BOOL (*Equal)(intptr_t, intptr_t));
void array_RemoveDuplicatesSorted(ARRAY Ar, BOOL (*Equal)(intptr_t, intptr_t));
void array_DeleteDuplicates(ARRAY Ar, BOOL (*Equal)(intptr_t, intptr_t),
    void* FreeState, void (*Free)(void*, intptr_t));
void array_DeleteDuplicatesSorted(ARRAY Ar, BOOL (*Equal)(intptr_t, intptr_t),
          void* FreeState, void (*Free)(void* , intptr_t));
void array_Delete(MEMORY,ARRAY);
void array_NMap(ARRAY ar, intptr_t (*ElementFunc)(intptr_t));
void array_Apply(void (*Function)(intptr_t), ARRAY ar);
ARRAY array_PairCreate(MEMORY mem, intptr_t p1, intptr_t p2);
void array_PairDelete(MEMORY mem, intptr_t ar);
intptr_t array_PairFirst(ARRAY ar);
intptr_t array_PairSecond(ARRAY ar);
void array_PairRplacSecond(ARRAY ar, intptr_t p);
ARRAY array_TripleCreate(MEMORY, intptr_t , intptr_t, intptr_t);
void array_TripleDelete(MEMORY, ARRAY);
intptr_t array_TripleFirst(ARRAY);
intptr_t array_TripleSecond(ARRAY);
intptr_t array_TripleThird(ARRAY);
ARRAY array_QTupleCreate(MEMORY, intptr_t , intptr_t, intptr_t, intptr_t);
void array_QTupleDelete(MEMORY, ARRAY);
intptr_t array_QTupleFirst(ARRAY);
intptr_t array_QTupleSecond(ARRAY);
intptr_t array_QTupleThird(ARRAY);
intptr_t array_QTupleFourth(ARRAY);
ARRAY array_STupleCreate(MEMORY, intptr_t , intptr_t, intptr_t, intptr_t, intptr_t, intptr_t);
void array_STupleDelete(MEMORY, ARRAY);
intptr_t array_STupleFirst(ARRAY);
intptr_t array_STupleSecond(ARRAY);
intptr_t array_STupleThird(ARRAY);
intptr_t array_STupleFourth(ARRAY);
intptr_t array_STupleFifth(ARRAY);
intptr_t array_STupleSixth(ARRAY);
void array_DeleteDistribution(MEMORY mem, ARRAY ar);
ARRAY array_AssocAdd(MEMORY mem, ARRAY ar, intptr_t key, intptr_t value);
ARRAY array_AssocArrayPair(ARRAY ar, intptr_t Key);
ARRAY array_MultisetDistribution(MEMORY Memory, ARRAY Multiset);
int array_CompareElementDistribution(ARRAY leftPair, ARRAY rightPair);
int array_CompareDistributions(ARRAY left, ARRAY right);
int array_CompareMultisetsByElementDistribution(MEMORY mem, ARRAY left, ARRAY right);
int array_CompareLexicographical(ARRAY left, ARRAY right, COMPARE_FUNC compare, void *arg) ;
int array_CompareLexicographical_func(const void *left, const void *right, void *arg_packed);
BOOL array_Exist(ARRAY ar);
unsigned array_Bytes(ARRAY ar);
#endif
