Mercurial > almixer_isolated
diff CircularQueue.h @ 0:01e39f9f58d5
Bitkeeper era.
author | Eric Wing <ewing . public |-at-| gmail . com> |
---|---|
date | Wed, 27 Oct 2010 16:50:19 -0700 |
parents | |
children | a8a8fe374984 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CircularQueue.h Wed Oct 27 16:50:19 2010 -0700 @@ -0,0 +1,448 @@ +/* + CircularQueue + Copyright (C) 2002 Eric Wing + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef C_CIRCULAR_QUEUE_H +#define C_CIRCULAR_QUEUE_H + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file + * This is a C-based Circular queue class. + * This class provides very simple circular queue functionality, + * with an API similar to the C++ STL queue class. + * Currently, a queue cannot be resized. + * Because C doesn't do templates and I really don't want + * to write my own polymorphism, you must select the proper queue + * for your data types. + * I currently provide an unisigned int version + * and a void* version. The void* version will let you use any type, + * but remember that you are responsible for casting and maintaining + * your own type safety. I have found the unsigned int version to be + * very useful because if you have a map somewhere that associates + * unique identifier numbers to data (e.g. OpenGL displaylists/textures), + * then you can just deal with the id numbers and don't have to deal with + * the casting and typesafety issues. I recommend you don't overlook the + * usefulness of this version. + * + * @warning Do not mix the CircularQueues created from the different versions. + * They are incompatible. Use only CircularQueueUnsignedInt objects with + * CircularQueueUnsignedInt_* functions, etc. + * + * Example Usage: + * @code + * CircularQueueUnsignedInt* myqueue; + * unsigned int ret_val; + * + * myqueue = CircularQueueUnsignedInt_CreateQueue(3); + * if(NULL == myqueue) + * { + * fprintf(stderr, "Error, could not create queue\n"); + * return 0; + * } + * + * + * ret_val = CircularQueueUnsignedInt_PushBack(myqueue, 1); + * ret_val = CircularQueueUnsignedInt_PushBack(myqueue, 2); + * ret_val = CircularQueueUnsignedInt_PushBack(myqueue, 3); + * if(0 == ret_val) + * { + * fprintf(stderr, "Error, Could not pushback\n"); + * exit(1); + * } + * + * ret_val = CircularQueueUnsignedInt_PopBack(myqueue); + * if(0 == ret_val) + * { + * fprintf(stderr, "Error, Could not popback\n"); + * exit(2); + * } + * + * fprintf(stderr, "Testing queue, should have 1,2\n"); + * CircularQueueUnsignedInt_Print(myqueue); + * + * ret_val = CircularQueueUnsignedInt_PushFront(myqueue, 4); + * if(0 == ret_val) + * { + * fprintf(stderr, "Error, Could not pushfront\n"); + * exit(1); + * } + * fprintf(stderr, "Testing queue, should have 4,1,2\n"); + * CircularQueueUnsignedInt_Print(myqueue); + * + * @endcode + */ + +/** + * This is the essentially the CircularQueue object. + * This contains all the data associated with a CircularQueue instance. + * This version is for unsigned int data types. In the future, I suppose + * I could add a void* data type at the very least and maybe some + * other data types. + * This should be considered an opaque data type. + */ +typedef struct +{ + unsigned int maxSize; /**< Max size of the queue. */ + unsigned int currentSize; /**< Current number of entries in the queue. */ + unsigned int headIndex; /**< The index of where the current head is. */ + unsigned int tailIndex; /**< The index of where the current tail is. */ + unsigned int* internalQueue; /**< The array representing the queue. */ +} CircularQueueUnsignedInt; + +/** + * This creates a new CircularQueue (for unsigned int) instance. + * This will create a new circular queue instance which holds + * unsigned int's in its queue. + * + * @note This implementation does not allow a circular queue to be resized. + * + * @param max_size This specifies the maximum number of elements the circular + * can hold. + * + * @return Returns a pointer to a CircularQueue which is the + * instance variable (if successful) or NULL on failure. + * + * @see CircularQueueUnsignedInt_FreeQueue + */ +CircularQueueUnsignedInt* CircularQueueUnsignedInt_CreateQueue(unsigned int max_size); + +/** + * This destroys a CircularQueue instance. + * This will destroy the memory associated with the circular queue instance. + * Whenever you create a CircularQueue instance, you should always to + * remember to balance it with a FreeQueue. + * + * @param queue The pointer to the CircularQueue instance. + * + * @see CircularQueueUnsignedInt_CreateQueue + */ +void CircularQueueUnsignedInt_FreeQueue(CircularQueueUnsignedInt* queue); + +/** + * This pushes a new value into the back of the queue. + * If the queue is full, the function will fail and return 0. + * + * @param queue The pointer to the CircularQueue instance. + * @param value The value you want to push into the queue. + * + * @return Returns 1 on success, or 0 on failure. + */ +unsigned int CircularQueueUnsignedInt_PushBack(CircularQueueUnsignedInt* queue, unsigned int value); + +/** + * This pushes a new value into the front of the queue. + * If the queue is full, the function will fail and return 0. + * + * @param queue The pointer to the CircularQueue instance. + * @param value The value you want to push into the queue. + * + * @return Returns 1 on success, or 0 on failure. + */ +unsigned int CircularQueueUnsignedInt_PushFront(CircularQueueUnsignedInt* queue, unsigned int value); + +/** + * This removes the value at the front of the queue. + * If the queue is empty, the function will return 0. + * Note that this function does not return the value popped, but + * an error flag. If you need the value, you must call Front() + * to retrieve the value before popping it. + * + * @param queue The pointer to the CircularQueue instance. + * + * @return Returns 1 on success, or 0 on failure. + * @see CircularQueueUnsignedInt_Front + */ +unsigned int CircularQueueUnsignedInt_PopFront(CircularQueueUnsignedInt* queue); + +/** + * This removes the value at the back of the queue. + * If the queue is empty, the function will return 0. + * Note that this function does not return the value popped, but + * an error flag. If you need the value, you must call Back() + * to retrieve the value before popping it. + * + * @param queue The pointer to the CircularQueue instance. + * + * @return Returns 1 on success, or 0 on failure. + * @see CircularQueueUnsignedInt_Back + */ +unsigned int CircularQueueUnsignedInt_PopBack(CircularQueueUnsignedInt* queue); + +/** + * This gets the value at the front of the queue. + * If the queue is empty, the value returned will be 0. + * Because this 0 return value is ambiguous because it could also could + * be a legitimate value in the queue, if you need more robust error + * checking for if the queue is empty, you should get the size of the + * queue using the Size() function. + * + * @param queue The pointer to the CircularQueue instance. + * + * @return Returns the value stored at the queue or 0 if the queue is empty + * (or if there is an error). + * + * @see CircularQueueUnsignedInt_Size + */ +unsigned int CircularQueueUnsignedInt_Front(CircularQueueUnsignedInt* queue); + +/** + * This gets the value at the back of the queue. + * If the queue is empty, the value returned will be 0. + * Because this 0 return value is ambiguous because it could also could + * be a legitimate value in the queue, if you need more robust error + * checking for if the queue is empty, you should get the size of the + * queue using the Size() function. + * + * @param queue The pointer to the CircularQueue instance. + * + * @return Returns the value stored at the queue or 0 if the queue is empty + * (or 0 if there is an error). + * + * @see CircularQueueUnsignedInt_Size + */ +unsigned int CircularQueueUnsignedInt_Back(CircularQueueUnsignedInt* queue); + +/** + * This gets the current number of entries that are in the queue. + * This is number is not to be confused with the MaxSize. + * + * @param queue The pointer to the CircularQueue instance. + * + * @return Returns the number of entries currently in queue, or 0 if + * there is an error. + * + */ +unsigned int CircularQueueUnsignedInt_Size(CircularQueueUnsignedInt* queue); + +/** + * This gets the maximum number of entries that are allowed in the queue at + * a given time. + * This is the number that you used in the CreateQueue function. + * + * @param queue The pointer to the CircularQueue instance. + * + * @return Returns the maximum number of entries allowed in the queue. + */ +unsigned int CircularQueueUnsignedInt_MaxSize(CircularQueueUnsignedInt* queue); +/** + * This empties the entire queue. + * This will remove all entries that are in the queue. + * This does not destroy any memory. Use FreeQueue() to actually destroy + * the queue. + * + * @param queue The pointer to the CircularQueue instance. + */ +void CircularQueueUnsignedInt_Clear(CircularQueueUnsignedInt* queue); + +/** + * This is a debugging function that will print all the elements in the + * queue to stderr. + * This function is provided as convenience, but should not be considered + * as part of the standard API. Treat this function as deprecated + * as it's implementation may change or be removed entirely. + * + * @param queue The pointer to the CircularQueue instance. + */ +void CircularQueueUnsignedInt_Print(CircularQueueUnsignedInt* queue); + + +/** + * This is the essentially the CircularQueue object. + * This contains all the data associated with a CircularQueue instance. + * This version is for unsigned int data types. In the future, I suppose + * I could add a void* data type at the very least and maybe some + * other data types. + * This should be considered an opaque data type. + */ +typedef struct +{ + unsigned int maxSize; /**< Max size of the queue. */ + unsigned int currentSize; /**< Current number of entries in the queue. */ + unsigned int headIndex; /**< The index of where the current head is. */ + unsigned int tailIndex; /**< The index of where the current tail is. */ + void** internalQueue; /**< The array representing the queue. */ +} CircularQueueVoid; + +/** + * This creates a new CircularQueue (for void* ) instance. + * This will create a new circular queue instance which holds + * unsigned int's in its queue. + * + * @note This implementation does not allow a circular queue to be resized. + * + * @param max_size This specifies the maximum number of elements the circular + * can hold. + * + * @return Returns a pointer to a CircularQueue which is the + * instance variable (if successful) or NULL on failure. + * + * @see CircularQueueVoid_FreeQueue + */ +CircularQueueVoid* CircularQueueVoid_CreateQueue(unsigned int max_size); + +/** + * This destroys a CircularQueue instance. + * This will destroy the memory associated with the circular queue instance. + * Whenever you create a CircularQueue instance, you should always to + * remember to balance it with a FreeQueue. + * + * @param queue The pointer to the CircularQueue instance. + * + * @see CircularQueueVoid_CreateQueue + */ +void CircularQueueVoid_FreeQueue(CircularQueueVoid* queue); + +/** + * This pushes a new value into the back of the queue. + * If the queue is full, the function will fail and return 0. + * + * @param queue The pointer to the CircularQueue instance. + * @param value The value you want to push into the queue. + * + * @return Returns 1 on success, or 0 on failure. + */ +unsigned int CircularQueueVoid_PushBack(CircularQueueVoid* queue, void* value); + +/** + * This pushes a new value into the front of the queue. + * If the queue is full, the function will fail and return 0. + * + * @param queue The pointer to the CircularQueue instance. + * @param value The value you want to push into the queue. + * + * @return Returns 1 on success, or 0 on failure. + */ +unsigned int CircularQueueVoid_PushFront(CircularQueueVoid* queue, void* value); + +/** + * This removes the value at the front of the queue. + * If the queue is empty, the function will return 0. + * Note that this function does not return the value popped, but + * an error flag. If you need the value, you must call Front() + * to retrieve the value before popping it. + * + * @param queue The pointer to the CircularQueue instance. + * + * @return Returns 1 on success, or 0 on failure. + * @see CircularQueueVoid_Front + */ +unsigned int CircularQueueVoid_PopFront(CircularQueueVoid* queue); + +/** + * This removes the value at the back of the queue. + * If the queue is empty, the function will return 0. + * Note that this function does not return the value popped, but + * an error flag. If you need the value, you must call Back() + * to retrieve the value before popping it. + * + * @param queue The pointer to the CircularQueue instance. + * + * @return Returns 1 on success, or 0 on failure. + * @see CircularQueueVoid_Back + */ +unsigned int CircularQueueVoid_PopBack(CircularQueueVoid* queue); + +/** + * This gets the value at the front of the queue. + * If the queue is empty, the value returned will be 0. + * Because this 0 return value is ambiguous because it could also could + * be a legitimate value in the queue, if you need more robust error + * checking for if the queue is empty, you should get the size of the + * queue using the Size() function. + * + * @param queue The pointer to the CircularQueue instance. + * + * @return Returns the value stored at the queue or 0 if the queue is empty + * (or if there is an error). + * + * @see CircularQueueVoid_Size + */ +void* CircularQueueVoid_Front(CircularQueueVoid* queue); + +/** + * This gets the value at the back of the queue. + * If the queue is empty, the value returned will be 0. + * Because this 0 return value is ambiguous because it could also could + * be a legitimate value in the queue, if you need more robust error + * checking for if the queue is empty, you should get the size of the + * queue using the Size() function. + * + * @param queue The pointer to the CircularQueue instance. + * + * @return Returns the value stored at the queue or 0 if the queue is empty + * (or 0 if there is an error). + * + * @see CircularQueueVoid_Size + */ +void* CircularQueueVoid_Back(CircularQueueVoid* queue); + +/** + * This gets the current number of entries that are in the queue. + * This is number is not to be confused with the MaxSize. + * + * @param queue The pointer to the CircularQueue instance. + * + * @return Returns the number of entries currently in queue, or 0 if + * there is an error. + * + */ +unsigned int CircularQueueVoid_Size(CircularQueueVoid* queue); + +/** + * This gets the maximum number of entries that are allowed in the queue at + * a given time. + * This is the number that you used in the CreateQueue function. + * + * @param queue The pointer to the CircularQueue instance. + * + * @return Returns the maximum number of entries allowed in the queue. + */ +unsigned int CircularQueueVoid_MaxSize(CircularQueueVoid* queue); +/** + * This empties the entire queue. + * This will remove all entries that are in the queue. + * This does not destroy any memory. Use FreeQueue() to actually destroy + * the queue. + * + * @param queue The pointer to the CircularQueue instance. + */ +void CircularQueueVoid_Clear(CircularQueueVoid* queue); + +/* Not implemented for void* */ +/* +void CircularQueueVoid_Print(CircularQueueVoid* queue); +*/ + + + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif + + + +#endif /* C_CIRCULAR_QUEUE_H */ +