{"id":29892972,"url":"https://github.com/red0124/sgc","last_synced_at":"2025-08-01T02:20:40.412Z","repository":{"id":41815154,"uuid":"465858911","full_name":"red0124/sgc","owner":"red0124","description":"Generic Algorithms and Data Structures in C","archived":false,"fork":false,"pushed_at":"2025-07-06T10:29:23.000Z","size":3631,"stargazers_count":35,"open_issues_count":1,"forks_count":0,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-07-06T10:31:42.083Z","etag":null,"topics":["algorithms","c","data-structures","embedded","header-only"],"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/red0124.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":"2022-03-03T19:34:00.000Z","updated_at":"2025-06-05T16:24:25.000Z","dependencies_parsed_at":"2025-07-06T10:24:47.551Z","dependency_job_id":"5c3a4511-2f6f-4dea-939b-fec2d69693ae","html_url":"https://github.com/red0124/sgc","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/red0124/sgc","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/red0124%2Fsgc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/red0124%2Fsgc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/red0124%2Fsgc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/red0124%2Fsgc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/red0124","download_url":"https://codeload.github.com/red0124/sgc/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/red0124%2Fsgc/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268157911,"owners_count":24204768,"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-08-01T02:00:08.611Z","response_time":67,"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":["algorithms","c","data-structures","embedded","header-only"],"created_at":"2025-08-01T02:20:36.945Z","updated_at":"2025-08-01T02:20:40.402Z","avatar_url":"https://github.com/red0124.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"﻿\n```\n   ____  ___________\n  / ___// ____/ ____/\n  \\__ \\/ / __/ /     \n ___/ / /_/ / /___   \n/____/\\____/\\____/   \n```\n\n[![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT)\n[![ubuntu-latest-gcc](https://github.com/red0124/sgc/actions/workflows/ubuntu-latest-gcc.yml/badge.svg?branch=master)](https://github.com/red0124/sgc/actions/workflows/ubuntu-latest-gcc.yml)\n[![ubuntu-latest-clang](https://github.com/red0124/sgc/actions/workflows/ubuntu-latest-clang.yml/badge.svg?branch=master)](https://github.com/red0124/sgc/actions/workflows/ubuntu-latest-clang.yml)\n[![windows-msys2-gcc](https://github.com/red0124/sgc/actions/workflows/win-msys2-gcc.yml/badge.svg?branch=master)](https://github.com/red0124/sgc/actions/workflows/win-msys2-gcc.yml)\n[![windows-msys2-clang](https://github.com/red0124/sgc/actions/workflows/win-msys2-clang.yml/badge.svg?branch=master)](https://github.com/red0124/sgc/actions/workflows/win-msys2-clang.yml)\n[![macos-apple-clang](https://github.com/red0124/sgc/actions/workflows/macos-apple-clang.yml/badge.svg?branch=master)](https://github.com/red0124/sgc/actions/workflows/macos-apple-clang.yml)\n[![windows-msvc](https://github.com/red0124/sgc/actions/workflows/win-msvc.yml/badge.svg?branch=master)](https://github.com/red0124/sgc/actions/workflows/win-msvc.yml)\n\nA header only library for algorithms and data structures written in **`C`** using macros.\nThe data structures are meant to be similar to the **`C++ STL`**.\n\n# Simple Example\n```c\n#include \u003csgc/vector.h\u003e\n#include \u003cstdio.h\u003e\n\n// vec \u003c=\u003e vector\u003cint\u003e\nSGC_INIT(VECTOR, int, vec)\n\nint main(void) {\n    vec v;\n    vec_init(\u0026v);\n\n    vec_push_back(\u0026v, 1);\n    vec_push_back(\u0026v, 5);\n\n    *vec_at(\u0026v, 0) = 2;\n\n    for_each(i IN v AS vec) {\n        printf(\"%d \", *i);\n    }\n\n    vec_free(\u0026v);\n    return 0;\n}\n```\nOutput:\n```bash\n$ ./vector\n2 5\n```\n\n# Features\n\n * Easy to use\n * No dependencies\n * Able to work with any type\n * Data structures and algorithms can be separated into headers and source files\n * Gives access to fixed size data structures which invoke no allocations convenient for **embedded** environments\n * Gives access to memory sharing and 'move semantics'\n * Allows for the usage of custom allocators and error handlers\n * Fast\n\n# Content\n * [Usage](#usage)\n * [Fixed size data structures](#fixed-size-data-structures)\n * [Data Structures](#data-structures)\n * [Iterators](#iterators)\n * [Algorithms](#algorithms)\n * [Benchmarks](#benchmarks)\n * [Installation](#installation)\n\n# Usage\n\nTo initialize the vector we simply used the **`SGC_INIT`** macro. It will generate\nthe **`vec`** structure and corresponding functions which all start with **vec_**.\n\n*Note: the macro will also generate some functions with the \\_p\\_ prefix.\nThose functions are meant to be private and should only be invoked internally.*\n\nIn order to generate a vector of a type some functions may need to exist\nso the library can know how to work with the type. For **`int`** those functions\nare **`int_copy`** and **`int_free`** and they are generated by the library along with function for many other primitive types.\n\n*More examples on how to use the library can be found in the examples directory.*\n\n## Map Example\n```c\n#include \u003csgc/map.h\u003e\n#include \u003cstdio.h\u003e\n\n// map \u003c=\u003e map\u003cint, double\u003e\nSGC_INIT_DICT(MAP, char, double, map)\n\nint main(void) {\n    map m;\n    map_init(\u0026m);\n\n    map_set(\u0026m, 'a', 10.0);\n    *map_at(\u0026m, 'b') = 11.1;\n\n    map_it it = map_find(\u0026m, 'c');\n    if (map_it_valid(\u0026it)) {\n        return 1;\n    }\n\n    for_each(i IN m AS map) {\n        printf(\"%c -\u003e %.2f\\n\", i-\u003ekey, i-\u003evalue);\n    }\n\n    map_free(\u0026m);\n    return 0;\n}\n```\nOutput:\n```bash\n$ ./map\na -\u003e 10.00\nb -\u003e 11.10\n```\nTo initialize dictionary type data structures the **`SGC_INIT_DICT`** macro should be used.\nIt is identical to **`SGC_INIT`** but takes one more type parameter for the key.\n\n# Fixed Size Data Structures\n\nThe library supports a few fixed size (fs) data structures. Most have identical implementations to their dynamic\ncounterparts.\n\nAll fixed size containers are named with the **`fs_`** prefix. To use a fixed size vector identical to the one above the\n**`SGC_INIT_FS`** macro can be used:\n```c\n#include \u003csgc/fs_vector.h\u003e\n\n// vec \u003c=\u003e vector\u003cint\u003e with capacity 100\nSGC_INIT_FS(FS_VECTOR, int, 100, vec)\n```\nSimilar to the fixed size vector, a fixed size unordered map can be initialized using the\n**`SGC_INIT_FS_DICT`** macro:\n```c\n#include \u003csgc/fs_unordered_map.h\u003e\n\n// umap \u003c=\u003e unordered_map\u003cchar, double\u003e with capacity 100\nSGC_INIT_FS_DICT(FS_UNORDERED_MAP, char, double, 100, umap)\n```\nFixed size containers ignore insertions if they are already full.\nThis behavior can be modified, see **error.c** within the examples directory.\n\n# Data Structures\n\nEvery data structure defines the following functions:\n**`init`** **`copy`** **`free`** **`size`** **`empty`** **`set_sharing`** and **`set_owning`**\n\nDictionary data structures also have:\n**`set_sharing_key`** and **`set_owning_key`**\n\nFixed size data structures also have:\n**`max`**\n\nNow follows a table showing which data structures have which functionalities defined:\n\n|              | vector | deque | list | forward\u003cbr\u003elist | queue | stack | priority\u003cbr\u003equeue | map | unordered\u003cbr\u003emap | set | unordered\u003cbr\u003eset |\n| ------------ | :----: | :---: | :--: | :-------------: | :---: | :---: | :---------------: | :-: | :--------------: | :-: | :--------------: |\n| push_back    | **x**      | **x**     | **x**    | **x**               |       |       |                   |     |                  |     |                  |\n| push_forward |        | **x**     | **x**    | **x**               |       |       |                   |     |                  |     |                  |\n| insert       | **x**      | **x**     |      |                 |       |       |                   |     |                  | **x**   | **x**                |\n|              |        |       |      |                 |       |       |                   |     |                  |     |                  |\n| pop_back     | **x**      | **x**     | **x**    |                 |       |       |                   |     |                  |     |                  |\n| pop_front    |        | **x**     | **x**    | **x**               |       |       |                   |     |                  |     |                  |\n| erase        | **x**      | **x**     |      |                 |       |       |                   | **x**   | **x**                | **x**   | **x**                |\n|              |        |       |      |                 |       |       |                   |     |                  |     |                  |\n| back         | **x**      | **x**     | **x**    | **x**               | **x**     |       |                   |     |                  |     |                  |\n| front        | **x**      | **x**     | **x**    | **x**               | **x**     |       |                   |     |                  |     |                  |\n| at           | **x**      | **x**     |      |                 |       |       |                   | **x**   | **x**                |     |                  |\n|              |        |       |      |                 |       |       |                   |     |                  |     |                  |\n| set_back     | **x**      | **x**     | **x**    | **x**               | **x**     |       |                   |     |                  |     |                  |\n| set_front    | **x**      | **x**     | **x**    | **x**               | **x**     |       |                   |     |                  |     |                  |\n| set          | **x**      | **x**     |      |                 |       |       |                   | **x**   | **x**                |     |                  |\n|              |        |       |      |                 |       |       |                   |     |                  |     |                  |\n| push         |        |       |      |                 | **x**     | **x**     | **x**                 |     |                  |     |                  |\n| pop          |        |       |      |                 | **x**     | **x**     | **x**                 |     |                  |     |                  |\n| top          |        |       |      |                 |       | **x**     | **x**                 |     |                  |     |                  |\n|              |        |       |      |                 |       |       |                   |     |                  |     |                  |\n| find         |        |       |      |                 |       |       |                   | **x**   | **x**                | **x**   | **x**                |\n| erase_it     |        |       |      |                 |       |       |                   | **x**   | **x**                | **x**   | **x**                |\n|              |        |       |      |                 |       |       |                   |     |                  |     |                  |\n| array        | **x**      | **x**     |      |                 |       |       |                   |     |                  |     |                  |\n| from_array   | **x**      |       |      |                 |       |       | **x**                 |     |                  |     |                  |\n\nThe functions are mostly identical to methods within the **`C++ STL`** with a few exceptions.\nThe **`at`** functions correspond to **`operator[]`**.\n**`insert`**, **`erase`**, **`at`** and **`set`** for **`vector`** and **`deque`** are used to insert\nelement at specified position as opposed to **`map`** and **`unordered_map`** functions\nwhich work with keys.\n\n# Iterators\n\nSome data structures have iterators bound to them, there is three types of iterators, \n**random access iterator**, **bidirectional iterator** and **forward iterator**. The iterator\nstructure for the associated data structure had the same name as the data structure\nwith **_it** attacked to the end of it, eg for **vec** it would be **vec_it**.\n\nFunctions starting with **`it`** take the iterator as input parameter instead of the data structure\n- **Forward iterator** is associated with the following functions:\n**`begin`** **`cbegin`** **`end`** **`cend`** **`it_data`** **`it_go_next`** **`it_eq`** and **`it_valid`**\n- **Bidirectional iterator** is associated with all the function from forward iterator and also the following:\n**`it_go_prev`**\n- **Random access iterator** is associated with all the function from bidirectional iterator and also the following:\n**`from`** **`cfrom`** **`it_move`** and **`it_diff`**\n\nThis table shows which data structure has access to which iterator:\n\n|               | random access iterator | bidirectional iterator | forward iterator |\n| ------------- | :--------------------: | :--------------------: | :--------------: |\n| vector        | **x**                      |                        |                  |\n| deque         | **x**                      |                        |                  |\n| list          |                        | **x**                      |                  |\n| forward_list  |                        |                        | **x**                |\n| map           |                        | **x**                      |                  |\n| unordered_map |                        | **x**                      |                  |\n| set           |                        | **x**                      |                  |\n| unordered_set |                        | **x**                      |                  |\n\n# Algorithms\n\nThe library gives access to some algorithms most of which require an iterator to be able to work.\nIf we for example wanted to initialize the vector to have access to **`qsort`** and **`eq`** functions they could be initialized like this:\n```c\n#include \u003csgc/vector.h\u003e\n#include \u003csgc/algorithm.h\u003e\nSGC_INIT(VECTOR, int, vec, QSORT, EQ)\n```\nThe **`SGC_INIT`** function may take additional argument which represent algorithms we want to use.\nThis will generate functions such as **`vec_qsort`** and **`vec_eq`** among others.\nThis table shows which algorithms are generated with which initializer group:\n\n\n| Algorighm                                                                   | Group              | Minimal Requirements                    |\n| --------------------------------------------------------------------------- | :----------------: | --------------------------------------- |\n| eq\u003cbr\u003ecount                                                                 | EQ                 | forward iterator                        |\n| compare                                                                     | COMPARE            | forward iterator, element compare       |\n| qsort\u003cbr\u003eqsort_default\u003cbr\u003e                                                  | QSORT              | container array function                |\n| foreach\u003cbr\u003eaccumulate                                                       | ITERATE            | forward iterator                        |\n| find_el\u003cbr\u003efind_it                                                          | FIND               | forward iterator                        |\n| binary_find_el\u003cbr\u003ebinary_find_it                                            | BINARY_FIND        | random access iterator, element compare |\n\nThe qsort algorithm does not require an iterator but an array function instead.\n\n# Benchmarks \n\nA few simple benchmarks are made to compare the performance of the library with \nthe **`C++ stl`** implementations of **`clang`** and **`gcc`**.\n\nThe benchmarks were ran using *hyperfine* on *openSUSE Tumbleweed 20220413*, *AMD Ryzen 5 3600*:\u003cbr\u003e\n\n![](https://github.com/red0124/sgc/blob/master/benchmark/img/gcc.png)\n*gcc 11.2*.1\u003cbr\u003e\n\n![](https://github.com/red0124/sgc/blob/master/benchmark/img/clang.png)\n*clang 14.0*\u003cbr\u003e\n\nThe code for the benchmarks can be found in the benchmarks directory.\n\n# Installation \n```shell\n$ git clone https://github.com/red0124/sgc\n$ cd sgc\n$ cmake -B build\n$ cd build\n$ sudo make install\n```\nThe library also supports CMake and meson build systems\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fred0124%2Fsgc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fred0124%2Fsgc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fred0124%2Fsgc/lists"}