C,
pasted
on Oct 30:
|
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LIST_STRUCT(T) T *members; size_t length, capacity;
#define LIST_INIT(l) ((l)->length = (l)->capacity = 0, (l)->members = NULL)
#define LIST_DEINIT(l) ((l)->capacity ? free((l)->members) : 0)
#define LIST_PUSH(l,x) (_LIST_EXPAND(l), ((l)->members[(l)->length++] = (x)))
#define LIST_POP(l) ((l)->members[--(l)->length])
#define LIST_CLEAR(l) ((l)->length = 0)
#define LIST_SPLICE(l,i,c)\
(memmove(\
(l)->members + (i), (l)->members + (i) + (c),\
((l)->length - (i) - (c)) * sizeof(*(l)->members)\
),\
(l)->length -= (c))
#define LIST_INSERT(l,i,x)\
(_LIST_EXPAND(l), memmove(\
(l)->members + (i) + 1, (l)->members + (i),\
((l)->length - (i)) * sizeof(*(l)->members)\
),\
(l)->length++, (l)->members[(i)] = (x))
#define LIST_SORT(l,f) qsort((l)->members, (l)->length,\
sizeof(*(l)->members), (f))
#define LIST_SWAP(l,a,b)\
(_LIST_EXPAND(l),\
((l)->members[(l)->length] = (l)->members[(b)]),\
((l)->members[(b)] = (l)->members[(a)]),\
((l)->members[(a)] = (l)->members[(l)->length]))
#define LIST_FOREACH(l,v,i)\
for ((i) = 0;\
(v) = (l)->members[(i)], (i) < (l)->length; ++(i))
#define _LIST_REALLOC(l)\
((l)->members = realloc(\
(l)->members, (l)->capacity * sizeof(*(l)->members)))
#define _LIST_EXPAND(l) ((l)->length + 1 > (l)->capacity\
? (((l)->capacity && ((l)->capacity <<= 1))\
? 0 : ((l)->capacity = 1)),\
_LIST_REALLOC(l) : 0)
int compare_string_ptr(const void *a, const void *b) {
return strcmp(*(char**)a, *(char**)b);
}
int compare_float_ptr(const void *a, const void *b) {
return *(float*)a < *(float*)b ? -1 : *(float*)a > *(float*)b;
}
void test_string(void) {
int i;
char *str;
struct { LIST_STRUCT(char*) } l;
LIST_INIT(&l);
/* Add initial values to the list */
LIST_PUSH(&l, "Hello");
LIST_PUSH(&l, "World");
LIST_PUSH(&l, "How's");
LIST_PUSH(&l, "It");
LIST_PUSH(&l, "Going");
LIST_PUSH(&l, "Today?");
printf("Original : ");
LIST_FOREACH(&l, str, i) printf("'%s', ", str);
printf("\n");
/* Remove some values and add some others at different places in the list */
LIST_SPLICE(&l, 0, 2);
LIST_SPLICE(&l, l.length - 1, 1);
LIST_INSERT(&l, 0, "Hi");
LIST_INSERT(&l, l.length - 2, "All");
printf("Modified : ");
LIST_FOREACH(&l, str, i) printf("'%s', ", str);
printf("\n");
/* Sort the list, ascending alphabetical order */
LIST_SORT(&l, compare_string_ptr);
printf("Sorted : ");
LIST_FOREACH(&l, str, i) printf("'%s', ", str);
printf("\n");
/* Reverse the list */
for (i = 0; i < l.length / 2; i++) {
LIST_SWAP(&l, i, l.length - 1 - i);
}
printf("Reversed : ");
LIST_FOREACH(&l, str, i) printf("'%s', ", str);
printf("\n");
/* Print the list's ending length/capacity and deinit it */
printf("Capacity : %d\n", l.capacity);
printf("Length : %d\n", l.length);
LIST_DEINIT(&l);
}
void test_float(void) {
int i;
struct { LIST_STRUCT(float) } l;
LIST_INIT(&l);
/* Add 100,000 random numbers */
for (i = 0; i < 100000; i++) {
LIST_PUSH(&l, rand());
}
/* Sort the numbers */
LIST_SORT(&l, compare_float_ptr);
/* Print smallest 5 values */
printf("Smallest : ");
for (i = 0; i < 5; i++) {
printf("%.0f, ", l.members[i]);
}
printf("\n");
/* Print largest 5 values */
printf("Largest : ");
for (i = l.length - 1; i > l.length - 6; i--) {
printf("%.0f, ", l.members[i]);
}
printf("\n");
/* Print the list's ending length/capacity and deinit it */
printf("Capacity : %d\n", l.capacity);
printf("Length : %d\n", l.length);
LIST_DEINIT(&l);
}
int main(void) {
printf("--- STRING TEST\n");
test_string();
printf("--- FLOAT TEST\n");
test_float();
return 0;
}
|
Output:
|
--- STRING TEST
Original : 'Hello', 'World', 'How's', 'It', 'Going', 'Today?',
Modified : 'Hi', 'How's', 'It', 'All', 'Going',
Sorted : 'All', 'Going', 'Hi', 'How's', 'It',
Reversed : 'It', 'How's', 'Hi', 'Going', 'All',
Capacity : 8
Length : 5
--- FLOAT TEST
Smallest : 3722, 31756, 35554, 56172, 61089,
Largest : 2147469824, 2147466240, 2147414144, 2147378048, 2147316992,
Capacity : 131072
Length : 100000
|
|