• Stars
    star
    123
  • Rank 290,145 (Top 6 %)
  • Language
    C
  • License
    MIT License
  • Created about 4 years ago
  • Updated over 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Pottery - A container and algorithm template library in C

Pottery

A container and algorithm template library in C.

Unit Tests

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

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.