4 ms·
If anyone is interested, I'm in the process of back porting the STL to C99: https://github.com/glouw/ctl https://github.com/glouw/ctl The gist of its workings
by glouwbug 6y ago
If anyone is interested, I'm in the process of back porting the STL to C99: https://github.com/glouw/ctl https://github.com/glouw/ctl
The gist of its workings is including a header and defining its type:
#define T int
#include <vec.h>
#define T float
#include <lst.h>
#define T str
#include <deq.h>
For more complex types, copy, free, and default constructors are supported, given they're defined before the inclusion of the container:
typedef struct { void* data; } blob;
blob blob_copy(blob* self) { ... } // Copy constructor
void blob_free(blob* self) { ... } // Destructor
blob blob_init(void* data) { ... } // Constructor
blob blob_init_default(void) { ... } // Default constructor
#define T blob
#include <vec.h>
int main(void)
{
vec_blob blobs = vec_blob_init();
vec_bloc_push_back(&blobs, blob_init(...)); // Invokes constructor, element 0, passed by value
vec_blob_resize(&blobs, 42); // Invokes default constructor for elements 1-42.
vec_blob copy = vec_blob_copy(&blobs); // Invokes copy constructor for elements 0-42.
vec_blob_free(&blobs); // Invokes destructor for elements 0-42.
vec_blob_free(©);
}
The motivation for starting this project was to provide C++ like functionality to C, but provide hugely reduced build times.
- dleslie 6y agoAs a hobby experiment I did something similar: ported generic containers and algorithms to C89. Unsurprisingly, what I found was that it was an uphill battle to replicate behaviour and performance that would be found under a better type system. Things like "aggregate values matching this predicate with this folding lambda into this target container" were clumsy as hell. But I like your approach of abusing preprocessor definitions prior to including the container header. Neat! https://github.com/dleslie/dl/tree/master/include https://github.com/dleslie/dl/tree/master/include https://github.com/dleslie/dl/blob/master/src/test_dl_algorithms.c https://github.com/dleslie/dl/blob/master/src/test_dl_algori...
- glouwbug 6y agoThe alternative would be to rely on void* for all data types, which was really nicely presented in Mastering Algorithms with C by Kyle Loudon, but after working through it the lack of type safety for even basic types was a huge pain. At least with a bit of pre-processor magic, type safety and contiguous data is promised. Also, getting crafty with precompiled headers, one could dump all the expansions into a single templates.h, compile a .gch, and reap the benefits of hundreds of containered types with instantaneous compile times.
- dleslie 6y agoI went with void* in order to avoid having separate algorithms for every container.
- adrift 6y agoI'd use something like Sean Barrett's stretchy buffer [1] instead. [1] https://github.com/nothings/stb/blob/master/stretchy_buffer.h https://github.com/nothings/stb/blob/master/stretchy_buffer....