diff --git a/queues.scad b/queues.scad new file mode 100644 index 0000000..ca0d7b7 --- /dev/null +++ b/queues.scad @@ -0,0 +1,200 @@ +////////////////////////////////////////////////////////////////////// +// LibFile: queues.scad +// Queue data structure implementation. +// To use, add the following lines to the beginning of your file: +// ``` +// use +// use +// ``` +////////////////////////////////////////////////////////////////////// + + +// Section: Queue Data Structure +// A queue is a first-in-first-out collection of items. You can add items onto the tail of the +// queue, or pop items off the head. While you can treat a queue as an opaque data type, using the +// functions below, it's simply implemented as a list. This means that you can use any list +// function to manipulate the queue. The first item in the list is the head queue item. + + +// Function: queue_init() +// Usage: +// queue = queue_init(); +// Description: +// Creates an empty queue/list. +// Example: +// queue = queue_init(); // Return: [] +function queue_init() = []; + + +// Function: queue_empty() +// Usage: +// if (queue_empty(queue)) ... +// Description: +// Returns true if the given queue is empty. +// Arguments: +// queue = The queue to test if empty. +// Example: +// queue = queue_init(); +// is_empty = queue_empty(queue); // Returns: true +// queue2 = queue_add(queue, "foo"); +// is_empty2 = queue_empty(queue2); // Returns: false +function queue_empty(queue) = + assert(is_list(queue)) + len(queue)==0; + + +// Function: queue_size() +// Usage: +// depth = queue_size(queue); +// Description: +// Returns the number of items in the given queue. +// Arguments: +// queue = The queue to get the size of. +// Example: +// queue = queue_init(); +// depth = queue_size(queue); // Returns: 0 +// queue2 = queue_add(queue, "foo"); +// depth2 = queue_size(queue2); // Returns: 1 +// queue3 = queue_add(queue2, ["bar","baz","qux"]); +// depth3 = queue_size(queue3); // Returns: 4 +function queue_size(queue) = + assert(is_list(queue)) + len(queue); + + +// Function: queue_head() +// Usage: +// item = queue_head(queue); +// list = queue_head(queue,n); +// Description: +// If `n` is not given, returns the first item from the head of the queue. +// If `n` is given, returns a list of the first `n` items from the head of the queue. +// Arguments: +// queue = The queue/list to get item(s) from the head of. +// Example: +// queue = [4,5,6,7,8,9]; +// item = queue_head(queue); // Returns: 4 +// list = queue_head(queue,n=3); // Returns: [4,5,6] +function queue_head(queue,n=undef) = + assert(is_list(queue)) + is_undef(n)? ( + queue[0] + ) : ( + let(queuesize = len(queue)) + assert(is_num(n)) + assert(n>=0) + assert(queuesize>=n, "queue underflow") + [for (i=[0:1:n-1]) queue[i]] + ); + + +// Function: queue_tail() +// Usage: +// item = queue_tail(queue); +// list = queue_tail(queue,n); +// Description: +// If `n` is not given, returns the last item from the tail of the queue. +// If `n` is given, returns a list of the last `n` items from the tail of the queue. +// Arguments: +// queue = The queue/list to get item(s) from the tail of. +// Example: +// queue = [4,5,6,7,8,9]; +// item = queue_tail(queue); // Returns: 9 +// list = queue_tail(queue,n=3); // Returns: [7,8,9] +function queue_tail(queue,n=undef) = + assert(is_list(queue)) + let(queuesize = len(queue)) + is_undef(n)? ( + queue[queuesize-1] + ) : ( + assert(is_num(n)) + assert(n>=0) + assert(queuesize>=n, "queue underflow") + [for (i=[0:1:n-1]) queue[queuesize-n+i]] + ); + + +// Function: queue_peek() +// Usage: +// item = queue_peek(queue,[pos]); +// list = queue_peek(queue,pos,n); +// Description: +// If `n` is not given, returns the queue item at position `pos`. +// If `n` is given, returns a list of the `n` queue items at and after position `pos`. +// Arguments: +// queue = The queue to read from. +// pos = The position of the queue item to read. Default: 0 +// n = The number of queue items to return. Default: undef (Return only the queue item at `pos`) +// Example: +// queue = [2,3,4,5,6,7,8,9]; +// item = queue_peek(queue); // Returns: 2 +// item2 = queue_peek(queue, 3); // Returns: 5 +// list = queue_peek(queue, 4, 3); // Returns: [6,7,8] +function queue_peek(queue,pos=0,n=undef) = + assert(is_list(queue)) + assert(is_num(pos)) + assert(pos>0) + let(queuesize = len(queue)) + assert(queuesize>=pos, "queue underflow") + is_undef(n)? ( + queue[pos] + ) : ( + assert(is_num(n)) + assert(n>=0) + assert(n=0) + let(queuesize = len(queue)) + assert(queuesize>=n, "queue underflow") + [for (i = [n:1:queuesize-1]) queue[i]]; + + + +// vim: noexpandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap