Skip to content

Instantly share code, notes, and snippets.

@cthom06
Created July 14, 2011 13:26
Show Gist options
  • Save cthom06/1082442 to your computer and use it in GitHub Desktop.
Save cthom06/1082442 to your computer and use it in GitHub Desktop.
Abusing the C preprocessor a bit
#include <stdlib.h>
#include <string.h>
#define QUICKSLICE(SLICETYPE, SLICENAME) \
typedef struct SLICENAME { \
unsigned int len, cap; \
SLICETYPE *data; \
} SLICENAME; \
typedef SLICETYPE (SLICENAME ## _mapper) (SLICETYPE); \
typedef char (SLICENAME ## _folder) (SLICETYPE); \
SLICENAME SLICENAME ## _create (int cap) { \
SLICENAME s; \
s.len = 0; \
s.cap = cap; \
s.data = (SLICETYPE *)malloc(sizeof(SLICETYPE) * cap); \
return s; \
} \
void SLICENAME ## _append (SLICENAME *s, SLICETYPE v) { \
if (s->len >= s->cap) \
s->data = (SLICETYPE *)realloc(s->data, sizeof(SLICETYPE) * (s->cap *= 2)); \
s->data[s->len++] = v; \
} \
void SLICENAME ## _remove (SLICENAME *s, int index) { \
if (index < s->len) { \
memcpy(s->data + index, s->data + index + 1, sizeof(SLICETYPE) * (s->len - (index + 1))); \
s->len--; \
} \
} \
void SLICENAME ## _free (SLICENAME *s) { \
free((void *)s->data); \
s->len = s->cap = 0; \
s->data = NULL; \
} \
void SLICENAME ## _map (SLICENAME s, SLICENAME ## _mapper f) { \
int i; \
for (i = 0; i < s.len; i++) \
s.data[i] = f(s.data[i]); \
} \
SLICENAME SLICENAME ## _fold (SLICENAME s, SLICENAME ## _folder f) { \
int i; \
SLICENAME n = SLICENAME ## _create(s.len); \
for (i = 0; i < s.len; i++) \
if (f(s.data[i])) \
SLICENAME ## _append(&n, s.data[i]); \
return n; \
}
#include <stdio.h>
#include "quickslice.h"
QUICKSLICE(int, ints)
QUICKSLICE(char *, strings);
int power2(int x) {
return 1 << x;
}
char notW(char *s) {
return s[0] != 'W';
}
int main() {
int i;
ints list = ints_create(5);
strings words = strings_create(5);
strings words2;
for (i = 0; i < 20; i++)
ints_append(&list, i);
ints_map(list, power2);
strings_append(&words, "Hello");
strings_append(&words, "Bonjour");
strings_append(&words, "Wilkommen");
strings_append(&words, "Buenos dias");
words2 = strings_fold(words, notW);
for (i = 0; i < list.len; i++)
printf("2 ** %d = %d\n", i, list.data[i]);
for (i = 0; i < words2.len; i++)
printf("%s\n", words2.data[i]);
ints_free(&list);
strings_free(&words);
strings_free(&words2);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment