{"id":15049298,"url":"https://github.com/hu55a1n1/dod","last_synced_at":"2025-04-10T02:05:46.066Z","repository":{"id":86482625,"uuid":"194557236","full_name":"hu55a1n1/dod","owner":"hu55a1n1","description":"Tools to facilitate data-oriented design in C99. ","archived":false,"fork":false,"pushed_at":"2020-08-18T21:03:54.000Z","size":78,"stargazers_count":41,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-02T17:42:44.193Z","etag":null,"topics":["bitset","byte-manipulation-utils","c99","data-oriented-design","vector"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hu55a1n1.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}},"created_at":"2019-06-30T20:15:59.000Z","updated_at":"2024-01-04T16:35:20.000Z","dependencies_parsed_at":"2023-03-13T19:59:38.429Z","dependency_job_id":null,"html_url":"https://github.com/hu55a1n1/dod","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hu55a1n1%2Fdod","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hu55a1n1%2Fdod/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hu55a1n1%2Fdod/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hu55a1n1%2Fdod/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hu55a1n1","download_url":"https://codeload.github.com/hu55a1n1/dod/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239114224,"owners_count":19583985,"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","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":["bitset","byte-manipulation-utils","c99","data-oriented-design","vector"],"created_at":"2024-09-24T21:19:36.114Z","updated_at":"2025-02-16T09:31:49.926Z","avatar_url":"https://github.com/hu55a1n1.png","language":"C","funding_links":[],"categories":["C"],"sub_categories":[],"readme":"# dod\nTools to facilitate data-oriented design in C99.\n\nIf you are new to data-oriented design, [this](https://github.com/dbartolini/data-oriented-design) is a good place to start.\n\n__Note: This library is still a WIP; using it in production isn't recommended until there is an official release.__\n\nThis library provides a collection of tools that are used frequently in data-oriented design. It currently offers the following header-only utilities -\n* [dodbytes.h](#dodbytesh---byte-manipulation-utils) - Byte manipulation utils\n* [dodvec.h](#dodvech---a-feature-rich-generic-vector-implementation) - A feature-rich generic vector implementation\n* [dodbs.h](#dodbsh---a-feature-rich-bitset-implementation) - A feature-rich bitset implementation\n* [dodarr.h](#dodarrh---generic-array-with-value-semantics) - Generic array with value semantics and optional bounds checking\n\nIn short, use the vector (`dodvec_t`) for grouping data members that are frequently accessed together.\nBools have a particularly bad information density, so group them toghether in a bitset (`dodbs_t`). (Note C++ offers a template specialization for std::vector\u003cbool\u003e so use that instead of a bitset in C++).\nFor data sets where size is known at compile time, use the array (`dodarr.h`).\n\n\n## dodbytes.h - Byte manipulation utils\nThis is a byte array that can grow in a logarithmic manner.\nIt is implemented as the backend for the vector library and is not intended to be used in isolation.\nIf you choose to use it as a standalone library make sure you understand *alignment* and its implications.\n\n\n\n## dodvec.h - A feature-rich generic vector implementation\nThe API is (almost) complaint with C++ STL's `std::vector` with a few exceptions (see notes section below).\nThe implementation tries to stick to the STL implementation unless otherwise specified.\n\n\n### Usage\nFor more examples see `test_dodvec.c`.\n```c\ndodvec_t *v = dodvec_new(int, 10);                          // Create vector of ints and reserve space for 10 ints\nfor (int i = 0; i \u003c 5; ++i)                                 // Push back 5 ints\n  dodvec_push_back(v, \u0026i);                                  // \u003e\u003e {0, 1, 2, 3, 4}\nassert(*dodvec_at(v, 2) == 2);                              // Check element at pos 2 is 2\ndodvec_pop_back(v);                                         // Pop back \u003e\u003e {0, 1, 2, 3}\ndodvec_erase(v, 0);                                         // Erase at pos 0 \u003e\u003e {1, 2, 3}\nint vals[] = {501, 502, 503};                               // Insert range using array\ndodvec_insert_range(v, dodvec_front(v), vals, vals + 3);    // at front \u003e\u003e {501, 502, 503, 1, 2, 3}\ndodvec_free(v);                                             // free after use\n```\n\n\n### Constructors\nUnlike the STL `std::vector`, only a single constructor is implemented.\nCreate a vector by specifying type and initial (reserve) size. The result is an empty container, with no elements.\nThe vector must be freed after use.\n```c\ndodvec_t *v = dodvec_new(int, 10);\n/* ... */\ndodvec_free(v);\n```\n\n\n### Iterators\nOnly `begin` and `end` are implemented as `dodvec_begin()` and `dodvec_end()` are implemented respectively.\nNote also that these iterators are actually pointers to the beginning and just past the end of the vector data.\n\n\n### Capacity\n| Function      | Use                                       | Equivalent function in dodvec.h | Notes                                                                                                                                                |\n|---------------|-------------------------------------------|---------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------|\n| size          | Return size                               | `dodvec_size(v)`                |\n| max_size      | Return maximum size                       | `dodvec_max_size(v)`            | This an implementation limitation, the vector is by no means guaranteed to be able to reach this size.\n| resize        | Change size                               | `dodvec_resize(v, n, val)`      | `val` is a pointer to the value that must be used for initialization of new elements.\n| capacity      | Return size of allocated storage capacity | `dodvec_capacity(v)`            |\n| empty         | Test whether vector is empty              | `dodvec_empty(v)`               |\n| reserve       | Request a change in capacity              | `dodvec_reserve(v, n)`          |\n| shrink_to_fit | Shrink to fit                             | `dodvec_shrink_to_fit(v)`       |\n\n\n### Element access\n| Function   | Use                  | Equivalent function in dodbs.h | Notes                                                                                                                               |\n|------------|----------------------|--------------------------------|-------------------------------------------------------------------------------------------------------------------------------------|\n| operator[] | Access element       | Not implemented                | This functions uses C++ features (references and operator overloading) that are non-existent in C. Use `dodvec_at(v, pos)` instead. |\n| at         | Access element       | `dodvec_at(v, pos)`            | Returns a pointer to the element at pos.                                                                                            |\n| front      | Access first element | `dodvec_front(v)`              | Returns a pointer to the first element. Same as `dodvec_begin(v)`                                                                   |\n| back       | Access last element  | `dodvec_back(v)`               | Returns a pointer to the last element.                                                                                              |\n| data       | Access data          | `dodvec_data(v)`               |                                                                                                                                     |\n\n\n### Modifiers\n| Function     | Use                                     | Equivalent function in dodbs.h                                          | Notes                                                                                                                               |\n|--------------|-----------------------------------------|-------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------|\n| assign       | Assign vector content                   | `dodvec_assign_range(v, start, end)`, `dodvec_assign_fill(v, n, val)`   | `start`, `end` and `val` are pointers.\n| push_back    | Add element at the end                  | `dodvec_push_back(v, val)`                                              | `val` is a pointer to the value to be pushed. Returns `DODRET_OK` on success.\n| pop_back     | Delete last element                     | `dodvec_pop_back(v)`                                                    |\n| insert       | Insert elements                         | `dodvec_insert(v, pos, val)`, `dodvec_insert_range(v, pos, start, end)` | `pos`, `start`, `end` and `val` are pointers. Returns `DODRET_OK` on success.\n| erase        | Erase elements                          | `dodvec_erase(v, pos)`                                                  | Returns `DODRET_OK` on success.\n| swap         | Swap content                            | `dodvec_swap(v1, v2)`                                                   |\n| clear        | Clear content                           | `dodvec_clear(v)`                                                       |\n| emplace      | Construct and insert element            | Not implemented                                                         |\n| emplace_back | Construct and insert element at the end | Not implemented                                                         |\n\n\n\n## dodbs.h - A feature-rich bitset implementation\nThe API is (almost) complaint with C++ STL's `std::bitset` with a few exceptions (see notes section below).\nThe implementation tries to stick to the STL implementation unless otherwise specified.\n\n\n### Usage\nFor more examples see `test_dodbs.c`.\n```c\ndodbs_t_decl(bs1, 16);              // Create bitset of length 16\ndodbs_init(bs1, 43690U);            // Initialize by value - 43690 == b1010101010101010\ndodbs_flipall(bs);                  // Flip all bits\nassert(dodbs_any(bs) == true);      // Check if any bit is set\nassert(dodbs_none(bs) == false);    // Check if no bit is set\ndodbs_setall(bs);                   // Set all bits\nassert(dodbs_all(bs) == true);      // Check if all bits are set\n```\n\n\n### Constructors\n`std::bitset` provides 3 types of constructors -\n* default constructor - The object is initialized with zeros.\nFor this, the library provides 2 methods, one for stack and the other for heap initialization.\nNote: The library relies on the declaration to zero initialize the storage, hence the unorthodox method of creation.\nIf you do not prefer the `*decl*` macros, then by all means use the manual declaration method.\n```c\n// Create a bitset of length 16 on the stack\ndodbs_t_decl(bs, 16);\n// Equivalent manual decl\n// dodbs_t(16) bs = {.bytes = {0}, .len = 16 };\n\n// Create a bitset of length 16 on the heap\ndodbs_t_decl_ptr(bsptr, 16);\n// Equivalent manual decl\n// dodbs_t(16) *bsptr = malloc(sizeof(*bsptr));\n// bsptr-\u003ebytes = {0};\n// bsptr-\u003elen = 16\n/* ... */\ndodbs_free(bsptr);\n```\n\n* initialization from integer value - Initializes the object with the bit values of val.\nThis is the `dodbs_init()` function.\n```c\ndodbs_t_decl(bs, 16);\ndodbs_init(bs, 43690U); // 43690 == b1010101010101010\n```\n\n* initialization from string. This is the `dodbs_init_str()` function.\n```c\ndodbs_t_decl(bs2, 16);\ndodbs_init_str(bs2, \"1010101010101010\");\n```\n\n\n### Bit access\n| Function   | Use                      | Equivalent function in dodbs.h | Notes                                                                                                                                                  |\n|------------|--------------------------|--------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------|\n| operator[] | Access bit               | Not implemented                | This functions uses C++ features (references and operator overloading) that are non-existent in C. Use dodbs_test()/dodbs_set()/dodbs_reset() instead. |\n| count      | Count bits set           | `dodbs_count(bs)`              |                                                                                                                                                        |\n| size       | Return size              | `dodbs_size(bs)`               |                                                                                                                                                        |\n| test       | Return bit value         | `dodbs_test(bs, pos)`          |                                                                                                                                                        |\n| any        | Test if any bit is set   | `dodbs_any(bs)`                |                                                                                                                                                        |\n| none       | Test if no bit is set    | `dodbs_none(bs)`               | Opposite of `dodbs_any(bs)`.                                                                                                                           |\n| all        | Test if all bits are set | `dodbs_all(bs)`                |                                                                                                                                                        |\n\n\n### Bit operations\n| Function | Use        | Equivalent function in dodbs.h                   | Notes                                                                                                                                                                                                              |\n|----------|------------|--------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| set      | Set bits   | `dodbs_set(bs, pos)`/`dodbs_setall(bs)`          | `bitset\u0026 set() noexcept;` is equivalent to `dodbs_setall(bs)`. Note also that `dodbs_set(bs, pos)` has no `val` default arg unlike its c++ counterpart. These functions return void unlike their C++ counterparts. |\n| reset    | Reset bits | `dodbs_reset(bs, pos)`/`dodbs_resetall(bs, pos)` | `bitset\u0026 reset() noexcept;` is equivalent to `dodbs_resetall(bs)`. These functions return void unlike their C++ counterparts.                                                                                      |\n| flip     | Flip bits  | `dodbs_flip(bs, pos)`/`dodbs_flipall(bs)`        | `bitset\u0026 flip() noexcept;` is equivalent to `dodbs_flipall(bs)`. These functions return void unlike their C++ counterparts.                                                                                        |\n\n\n### Bitset operations\n| Function  | Use                              | Equivalent function in dodbs.h | Notes                                                                                                                  |\n|-----------|----------------------------------|--------------------------------|------------------------------------------------------------------------------------------------------------------------|\n| to_string | Convert to string                | `dodbs_to_string(bs)`          | Returns a `char *` that must be freed after usage.                                                                     |\n| to_ulong  | Convert to unsigned long integer | `dodbs_to_ulong(bs)`           | Internally creates a temporary `unsigned long` variable and reads to it using `memcpy` to avoid alignment issues.      |\n| to_ullong | Convert to unsigned long long    | `dodbs_to_ullong(bs, pos)`     | Internally creates a temporary `unsigned long long` variable and reads to it using `memcpy` to avoid alignment issues. |\n\n\n**Note:** Direct use of bitwise operators is unsupported.\n\n\n### Internals\nThis implementation is inspired by `llvm-libc++`'s `std::bitset`.\nThe backend storage for bits comprises of an array of `size_t`s. This can be changed by modifying the `dodbs_storage_t` typedef.\nMost functions are macros that delegate to other functions, this allows for generic functions that can handle bitsets of all sizes.\nIt also provides a convenient API where you don't have to always pass the length of the bitset.\n\n\n\n## dodarr.h - Generic array with value semantics\nWIP\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhu55a1n1%2Fdod","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhu55a1n1%2Fdod","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhu55a1n1%2Fdod/lists"}