/*#io
docCopyright("Steve Dekorte", 2002)
docLicense("BSD revised")
docDescription("""
    Queue - a queue of void pointers
    
    This implementation tries to minimize memory allocations and fragmentation
    by not using a linked list. It uses an array whose top and bottom
    indexes are tracked. It opportunistically moves the bottom index 
    back to the origin of the array when the list is emptied or it's
    bounds are exceeded. When the bounds are exceeded, it will
    move the used chunk of memory to the beginning of the array
    and, if the used ratio is high, resize the array.
""")
*/

#ifndef QUEUE_DEFINED
#define QUEUE_DEFINED 1

#include "Common.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#ifdef __cplusplus
extern "C" {
#endif

#ifdef LOW_MEMORY_SYSTEM
  #define QUEUE_START_SIZE 3
  #define QUEUE_RESIZE_FACTOR 1.5
#else
  #define QUEUE_START_SIZE 8
  #define QUEUE_RESIZE_FACTOR 2
#endif

typedef struct
{
    void **items;
    int size; /* # of pointers that can fit in allocated memory for items */
    int top;
    int bottom;
} Queue;

typedef unsigned char (QueueFirstTrueForWithCallback)(void *, void *);
typedef unsigned char (QueueDoCallback)(void *);

Queue *Queue_new(void);
Queue *Queue_clone(Queue *self);
void Queue_free(Queue *self);
int Queue_length(Queue *self);
void *Queue_at_(Queue *self, int i);

void Queue_compact(Queue *self);
size_t Queue_memorySize(Queue *self);
void Queue_print(Queue *self);

void Queue_do_(Queue *self, QueueDoCallback *callback);
  
void *Queue_firstTrueFor_with_(Queue *self, 
  QueueFirstTrueForWithCallback *callback, void *arg);
  
#include "Queue_inline.h"

#ifdef __cplusplus
}
#endif
#endif
