-
Notifications
You must be signed in to change notification settings - Fork 118
deq
#include <deq.h>The CTL deq, analogous to the STL std::<deque>, is a container specializing in paged allocations. A deq can be used in place of a vec when push_front and pop_front is desired, or when the collection of elements is large enough to warrant a copy-free reallocation less prone to receiving the C equivalent of a bad_alloc. The performance of a deq is similar to that of a vec with O(1) access time to elements within the deq, but does not guarantee a contiguous array of elements like that of a vec. Pointers to elements within a deq are valid as the deq grows with push_back and push_front, but invalidated when an element is inserted or erased from the middle of the deq.
A deq can inserted elements at the back of the container, like vec, but also supports fast element insertion at the front of the container:
#include <stdlib.h>
#include <stdio.h>
#define P
#define T int
#include <deq.h>
int compare(int* a, int* b) { return *b < *a; }
int main(void)
{
deq_int a = deq_int_init();
for(int i = 0; i < 16; i++)
{
deq_int_push_back(&a, rand() % 1024);
deq_int_push_front(&a, rand() % 1024);
}
deq_int_sort(&a, compare);
int sum = 0;
foreach(deq_int, &a, it)
{
printf("%d\n", *it.ref);
sum += *it.ref;
}
printf("sum: %d\n", sum);
deq_int_free(&a);
}As per usual, #define P states no per-element cleanup is necessary once the deq is freed. A deq offers O(1) access time to any element within a deq, given access is performed with _at. The foreach statement above can be replaced with a conventional for loop:
int sum = 0;
for(size_t i = 0; i < a.size; i++)
{
int* ref = deq_int_at(&a, i);
printf("%d\n", *ref);
sum += *ref;
}The deq container serves as an ideal double ended queue. By enqueuing random IP addresses to the back of a deq, the front of the deq can be popped, inspected, and re-inserted, all within O(1) time.
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include <str.h>
#define T str
#include <deq.h>
int main(void)
{
deq_str a = deq_str_init();
for(size_t i = 0; i < 32; i++)
{
str ip = str_init("");
size_t max = 4;
for(size_t j = 0; j < max; j++)
{
char sub[16];
sprintf(sub, "%03d", rand() % UINT8_MAX);
str_append(&ip, sub);
if(j != max - 1)
str_append(&ip, ".");
}
deq_str_push_back(&a, ip);
}
str s = str_copy(deq_str_front(&a));
deq_str_pop_front(&a);
puts(str_c_str(&s));
deq_str_push_front(&a, s);
deq_str_free(&a);
}The deq_str container omits the #define P directive, and inherits _copy and _free from the str type provided by the #include <str.h> line. At time of freeing, each str element of the deq is correctly freed.