{"id":32448607,"url":"https://github.com/daniilalpha/vec","last_synced_at":"2025-10-26T05:58:57.279Z","repository":{"id":234258934,"uuid":"727831902","full_name":"DaniilAlpha/vec","owner":"DaniilAlpha","description":"Plain C typesafe vector data structure.","archived":false,"fork":false,"pushed_at":"2025-05-25T17:01:27.000Z","size":43,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-05-25T17:30:53.403Z","etag":null,"topics":["c","c11","c17","data-structures","data-structures-c","dynamic-array","vector"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DaniilAlpha.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-12-05T17:02:02.000Z","updated_at":"2025-05-25T17:01:30.000Z","dependencies_parsed_at":"2024-04-28T16:30:30.308Z","dependency_job_id":"d920432c-5340-4aee-8aa4-12fc14cad0dd","html_url":"https://github.com/DaniilAlpha/vec","commit_stats":null,"previous_names":["daniilalpha/vec"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/DaniilAlpha/vec","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DaniilAlpha%2Fvec","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DaniilAlpha%2Fvec/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DaniilAlpha%2Fvec/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DaniilAlpha%2Fvec/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DaniilAlpha","download_url":"https://codeload.github.com/DaniilAlpha/vec/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DaniilAlpha%2Fvec/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":281064201,"owners_count":26437785,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-26T02:00:06.575Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c","c11","c17","data-structures","data-structures-c","dynamic-array","vector"],"created_at":"2025-10-26T05:57:30.054Z","updated_at":"2025-10-26T05:58:57.271Z","avatar_url":"https://github.com/DaniilAlpha.png","language":"C","readme":"# vec\n\nTypesafe vector data structure, written in plain C.\n\n\n## Usage\n\nTo provide type safety, struct name and type (and optionally a function prefix) should be provided before inclusion of the header file:\n\n```c\n#define Self VecOfFloat // vector struct name\n#define T    float // element type\n#define PREFIX vec_of_float // you can also redefine the function prefix to follow your naming style\n#include \u003cvec.h\u003e \n// `Self`, `T` and `PREFIX` have been undefined in `vec.h`\n```\n\nThis setup must only be done a single time. If you need to use the same vec type in multiple header files, you'll need to create a separate header, excllusive for your vec and mark it with either include guards or `#pragma once`. This cannot be done in the library, because the same file `vec.h` is shared between multiple vector types.\n\nAfter that setup you will be able to use the vec:\n\n```c\n// all functions that may fail, return `enum Result` representing the error that can occure\n// you can use the `UNROLL` macro, which will return only if result is not equal to `Ok`\nVecOfFloat vec;\nUNROLL(vec_of_float_init(\u0026vec));\n\nUNROLL(vec_of_float_push(\u0026vec, 0)); \nUNROLL(vec_of_float_push(\u0026vec, 1)); \nUNROLL(vec_of_float_push(\u0026vec, 2)); \n\n// if vec is empty, `start` and `end` functions will return `NULL`s, so loop will exit immediately\nfor(float *el_ptr = vec_of_float_start(\u0026vec); el_ptr \u003c vec_of_float_end(\u0026vec); el_ptr++) \n    *el_ptr++;\n\nvec_of_float_uninit(\u0026vec); \n// watch out: using uninitialized vec may cause undefined behaviour\n```\n\nSee [`test.c`](./test.c) for more examples.\n\n\u003e [!note]\n\u003e You may wonder, what if someone wants to change the vec's type, but don't want to rename a bunch of functions all througout the code? There is actually a pretty elegant solution. In languages, where vector is built in, it is usually used as a generic with a type parameter. This is defenetely not a bad thing, but sometimes can be a little bit messy, especially with longer or nested type names. Also this is not really a good suit for C.\n\u003e\n\u003e So, my advice is naming vecs not based on the element type, but based on their purpose, for example:\n\u003e\n\u003e ```c\n\u003e #define Self VecOfConstCharPtr // bad\n\u003e #define Self VecOfEnvVar // good\n\u003e #define T char const *\n\u003e #include \u003cvec.h\u003e\n\u003e \n\u003e #define Self VecOfConstCharPtr // not again!\n\u003e #define Self ExcludedHttpHeaders // you can even omit 'vec' entirely!\n\u003e #define T char const *\n\u003e #include \u003cvec.h\u003e\n\u003e ```\n\u003e\n\u003e When you get used to it, you'll see that this actually makes code much cleaner. As a nice bonus, library will protect you from inconsistencies, e.g. using `VecOfEnvVar_init` with an `ExcludedHttpHeaders` vec.\n\n\n## Performance\n\nAt the moment, performance is slightly worse than the `std::vector` from C++, most likely due to a different memory resizing strategy. On the other hand, the resulting code size will be much smaller, as all functions are implemented only once, instead of generated for the each type. This make it suitable for more restricted enviroments (especially when custom allocators will be supported).\n\n\n## ToDo\n - come up with better name;\n - add support for custom allocator;\n - add an ability for reserving vec capacit;\n - improve performance (possibly storing store end pointer and data end pointer, instead of `len` and `cap` will help).\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdaniilalpha%2Fvec","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdaniilalpha%2Fvec","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdaniilalpha%2Fvec/lists"}