Pottery
A container and algorithm template library in C.
Introduction
Pottery is a collection of templates for instantiating strongly typed containers and container algorithms in C. It provides vectors, hash tables, binary search trees, priority queues, sort algorithms, etc.
Pottery is modern C code written in the ultra-portable intersection of C11, gnu89 and C++11 with no mandatory dependencies (not even libc.) Pottery supports many compilers including GCC, Clang, MSVC and various toy compilers. It supports (or intends to support) any modern C platform from microcontrollers to OS kernels to WebAssembly.
Pottery does not use void pointer casts, function pointers, code block macros, compiler extensions, or any other inefficiencies or messyness of typical C containers. Pottery's templates are clean, composable, fast, strongly typed, and highly configurable. The templates are header files only; just put include/
on your include path to use them.
Take a look at the template listing or the utilities to see what Pottery has to offer.
Documentation
- Features
- How It Works
- Examples
- Glossary
- Template Listing
- Utilities
- Integration Guide
- Lifecycle Style
- Meta-templates
- C++ Bindings
- Testing
- FAQ
Examples
Int Vector
Suppose you want a growable array of int
. Let's call it int_vector
. Instantiate it like this:
#define POTTERY_VECTOR_PREFIX int_vector
#define POTTERY_VECTOR_VALUE_TYPE int
#define POTTERY_VECTOR_LIFECYCLE_BY_VALUE 1
#include "pottery/vector/pottery_vector_static.t.h"
This gives you an int_vector_t
:
int_vector_t vector;
int_vector_init(&vector);
int_vector_insert_first(&vector, 10);
int_vector_insert_last(&vector, 20);
int_vector_insert_at(&vector, 1, 15);
int_vector_remove_at(&vector, 0);
for (size_t i = 0; i < int_vector_count(&vector); ++i)
printf("%i\n", *int_vector_at(&vector, i));
int_vector_destroy(&vector);
See the full example here.
StringโObject Map
Suppose you want a map of names to person pointers for this struct:
typedef struct person_t {
char* name;
// other stuff
} person_t;
person_t* person_new(const char* name);
void person_delete(person_t* person);
// other functions
Instantiate a red-black tree map like this:
#define POTTERY_TREE_MAP_PREFIX person_map
#define POTTERY_TREE_MAP_KEY_TYPE const char*
#define POTTERY_TREE_MAP_COMPARE_THREE_WAY strcmp
#define POTTERY_TREE_MAP_VALUE_TYPE person_t*
#define POTTERY_TREE_MAP_REF_KEY(person) (*person)->name
#define POTTERY_TREE_MAP_LIFECYCLE_MOVE_BY_VALUE 1
#define POTTERY_TREE_MAP_LIFECYCLE_DESTROY(person) person_delete(*person)
#include "pottery/tree_map/pottery_tree_map_static.t.h"
This gives you a person_map_t
:
person_map_t map;
person_map_init(&map);
person_map_insert(&map, person_new("alice"));
person_map_insert(&map, person_new("bob"));
person_t** eve = person_map_find(&map, "eve");
if (eve == NULL) {
// not found!
}
// for-each loop works on any container
person_t** ref;
POTTERY_FOR_EACH(ref, person_map, &map) {
printf("%s\n", (*ref)->name);
}
// map destroys its values with person_delete()
person_map_destroy(&map);
See the full example here.
Sort Strings
Suppose you want to sort an array of C strings:
#define POTTERY_INTRO_SORT_PREFIX sort_strings
#define POTTERY_INTRO_SORT_VALUE_TYPE const char*
#define POTTERY_INTRO_SORT_LIFECYCLE_MOVE_BY_VALUE 1
#define POTTERY_INTRO_SORT_COMPARE_THREE_WAY(x, y) strcmp(*x, *y)
#include "pottery/intro_sort/pottery_intro_sort_static.t.h"
This gives you a function called sort_strings()
:
const char* players[] = {
"fred", "quincy", "alice", "eve", "zack", "ned", "paul", "bob", "gary",
"ursula", "yves", "carl", "olivia", "steve", "rob", "mike", "wade", "dave",
"jake", "helen", "xavier", "karen", "tammy", "laura", "isaac", "vick",
};
size_t count = sizeof(players) / sizeof(*players);
// introsorts a string array with inline comparator, competitive with C++ std::sort
sort_strings(players, count);
for (size_t i = 0; i < count; ++i)
puts(players[i]);
See the full example here.
Additional Examples
There are more examples in the examples/
folder and many more that still need to be written. Have a look at what's there so far to learn more ways you can use Pottery.
Take a look at Clayfish to see various uses of Pottery in a real application.