Pottery - A container and algorithm template library in C

Related tags

Algorithms pottery
Overview

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. Use Pottery to make containers in C!

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:

name); } // map destroys its values with person_delete() person_map_destroy(&map); ">
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.

You might also like...
Basic algorithm developed in C++
Basic algorithm developed in C++

Sequential Search Algorithm O(n) Algoritmo Comportamento Funcional Se o valor que deseja pesquisar dentro do array de fato existir, então a função ret

haha - huh? another hashing algorithm

haha - huh? another hashing algorithm 📙 haha is a hashing algorithm I've written as an exercise and as something to use for myself. It's decently fas

A C++ implementation of the graph algorithm of finding all strongly connected components with DFS

SinkSCC A C++ implementation of the graph algorithm of finding all strongly connected components with DFS. Details Each SCC of a graph can be treated

The Implementation of quadtree-based multi-thread tiled pyramid building algorithm.

tile-map-parallel-builder Quadtree-based multi-thread tiled pyramid building algorithm. Core Concept NOTE: The level is different from TMS zoom level.

C implementation of a sudoku solver with backtracking algorithm
C implementation of a sudoku solver with backtracking algorithm

SUDOKU SOLVER Sudoku solver using backtracking algorithm Sudoku game To solve a sudoku, you need a sudoku. So i made a basic implmentation of one with

Blazing fast ⚡⚡⚡ Secure Hash Algorithm solution for React Native with direct C++ bindings
Blazing fast ⚡⚡⚡ Secure Hash Algorithm solution for React Native with direct C++ bindings

React Native SHA library ⚡ ⚡ ⚡ React-native-sha is a blazing fast ⚡ solution for performing Secure Hashing Algorithm in React Native. Main reason this

I implement what i learned about banker's algorithm in OS course at my uni.
I implement what i learned about banker's algorithm in OS course at my uni.

Banker-s-Algorithm The banker’s algorithm is a resource allocation and deadlock avoidance algorithm that tests for safety by simulating the allocation

This program uses genetic algorithm to find the best route possible given the conditions.
This program uses genetic algorithm to find the best route possible given the conditions.

Genetic Algorithm Table Of Contents Table Of Contents Installation About Terms The Algorithm Default values for the conditions Example result Installa

Implementation of Dijkstra's algorithm for finding the shortest paths between nodes in a graph using Priority Queue data structure in C

Implementation of Dijkstra's algorithm for finding the shortest paths between nodes in a graph using Priority Queue data structure in C. File "airport

Comments
  • Use MALLOCX_ZERO instead of ALLOCM_ZERO

    Use MALLOCX_ZERO instead of ALLOCM_ZERO

    It seems like ALLOCM_ZERO was renamed to MALLOCX_ZERO 7 years ago. Look at https://github.com/jemalloc/jemalloc/commit/d82a5e6a34f20698ab9368bb2b4953b81d175552.

    opened by cglogic 4
  • Wrong length of strings returned by string_append_vformat

    Wrong length of strings returned by string_append_vformat

    For the following code, I was expecting the length computed by string_length and by strlen to be the same:

    #include <stdio.h>
    #include "util/pottery/string/string.h"
    int main(void)
    {
      string_t s;
      string_init(&s);
      string_append_format(&s,"%u",245234345);
      printf("S=%s L0=%zu L1=%zu\n",
             string_cstr(&s),
             string_length(&s),
             strlen(string_cstr(&s)));
      string_clear(&s);
      return 0;
    }
    

    whereas it outputs: S=245234345 L0=10 L1=9 i.e. the output of string_length is one too many.

    opened by P-p-H-d 3
  • Cannot create two instances of Open Hash Map in the same file

    Cannot create two instances of Open Hash Map in the same file

    When I try to create two instances of Open Hash Map in the same file as per the following file, I get errors on type redefinition whereas I was expected to be able to do it:

    typedef struct bar_s {
      unsigned long key;
      unsigned long value;
    } bar_t;
    
    #define POTTERY_OPEN_HASH_MAP_PREFIX map_ulong
    
    #define POTTERY_OPEN_HASH_MAP_VALUE_TYPE bar_t
    #define POTTERY_OPEN_HASH_MAP_KEY_TYPE unsigned long
    #define POTTERY_OPEN_HASH_MAP_REF_KEY(v) v->key
    #define POTTERY_OPEN_HASH_MAP_KEY_HASH(x) (x)
    #define POTTERY_OPEN_HASH_MAP_KEY_EQUAL(x, y) (x == y)
    #define POTTERY_OPEN_HASH_MAP_LIFECYCLE_MOVE(p,q) memcpy(p, q, sizeof (bar_t))
    
    #include "pottery/open_hash_map/pottery_open_hash_map_static.t.h"
    
    #define POTTERY_OPEN_HASH_MAP_PREFIX map_ulong2
    
    #define POTTERY_OPEN_HASH_MAP_VALUE_TYPE bar_t
    #define POTTERY_OPEN_HASH_MAP_KEY_TYPE unsigned long
    #define POTTERY_OPEN_HASH_MAP_REF_KEY(v) v->key
    #define POTTERY_OPEN_HASH_MAP_KEY_HASH(x) (x)
    #define POTTERY_OPEN_HASH_MAP_KEY_EQUAL(x, y) (x == y)
    #define POTTERY_OPEN_HASH_MAP_LIFECYCLE_MOVE(p,q) memcpy(p, q, sizeof (bar_t))
    
    #include "pottery/open_hash_map/pottery_open_hash_map_static.t.h"
    

    Here are the first errors:

    include/pottery/open_hash_map/impl/pottery_open_hash_map_forward.t.h:30:14: error: nested redefinition of ‘enum pottery_ohm_bucket_state_t’
     typedef enum pottery_ohm_bucket_state_t {
                  ^
    include/pottery/open_hash_map/impl/pottery_open_hash_map_forward.t.h:30:14: error: redeclaration of ‘enum pottery_ohm_bucket_state_t’
    
    opened by P-p-H-d 2
Owner
Nicholas Fraser
Nicholas Fraser
Knapsack Encryption Algorithm is the first general public key cryptography algorithm.

Knapsack Encryption Algorithm is the first general public key cryptography algorithm. It is developed by Ralph Merkle and Mertin Hellman in 1978. As it is a Public key cryptography, it needs two different keys. One is Public key which is used for Encryption process and the other one is Private key which is used for Decryption process.

Farhan Izzaturrahman Andiejanto 1 Nov 10, 2021
My attempt at implementing the fast voxel traversal algorithm by Amanatides and Woo using OpenGL

Attempt at implementing the fast voxel traversal algorithm Works on both Linux and Windows. Recommended software: Linux: Visual Studio Code / Windows:

Niklas Mäckle 2 Sep 24, 2021
Quick sort is a highly efficient sorting algorithm and is based on partitioning of array of data into smaller arrays.

Quick sort is a highly efficient sorting algorithm and is based on partitioning of array of data into smaller arrays. A large array is partitioned into two arrays one of which holds values smaller than the specified value, say pivot, based on which the partition is made and another array holds values greater than the pivot value.

Lakshan Sandanayaka 4 Jan 2, 2023
C++ and SFML Project that simulates dijkstra algorithm on a non oriented Graph

Dijkstra-Simulator Table of Contents About The Project Built With Getting Started Prerequisites Roadmap Acknowledgments About The Project This is one

David 2 Mar 26, 2022
C++17 (-O2) template for competitive programming algorithms, which contains numerous math algorithms.

cpplibForCP C++17 (-O2) template for competitive programming algorithms, which contains numerous math algorithms. Aims: build a stable, fast, easy-to-

null 33 Nov 25, 2022
CComp: A Parallel Compression Algorithm for Compressed Word Search

The goal of CComp is to achieve better compressed search times while achieving the same compression-decompression speed as other parallel compression algorithms. CComp achieves this by splitting both the word dictionaries and the input stream, processing them in parallel.

Emir Öztürk 4 Sep 30, 2021
C Program showing line drawing using DDA algorithm.

Draw-Line-Using-DDA-algorithm C Program showing line drawing using DDA algorithm. How it works ? ??

CodAffection 2 Sep 28, 2021
This project implemented the Mean Value Coordinates in 3D algorithm in c++

Mean Value Coordinates in 3D [c++] | Paper link on Sciencedirect | Pdf version link | This project implemented the Mean Value Coordinates in 3D algori

null 3 Nov 22, 2022
Based on the spatial resection theory, the algorithm solves the camera position by solving the homography matrix.

Based on the spatial resection theory, the algorithm solves the camera position by solving the homography matrix.

null 1 Nov 13, 2021
Final Project for Multicore Processors Course at NYU: Parallel Ray Tracing Algorithm

Multicore_ParallelRayTracing Final Project for Multicore Processors Course at NYU: Parallel Ray Tracing Algorithm Team Member: Hanlin He, Yaowei Zong,

Hanlin || Herlin 1 Dec 1, 2021