{"id":19693000,"url":"https://github.com/magnetrwn/runtime-bitset-cpp","last_synced_at":"2025-02-27T09:57:42.623Z","repository":{"id":191641264,"uuid":"685067576","full_name":"magnetrwn/runtime-bitset-cpp","owner":"magnetrwn","description":"Very compact header-only C++ bitset library for creating bitsets at runtime.","archived":false,"fork":false,"pushed_at":"2023-08-31T20:35:55.000Z","size":30,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-10T09:11:09.227Z","etag":null,"topics":["bitset","data-structures","header-only","runtime"],"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/magnetrwn.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}},"created_at":"2023-08-30T12:56:30.000Z","updated_at":"2023-08-30T13:52:44.000Z","dependencies_parsed_at":"2023-08-30T22:42:23.086Z","dependency_job_id":null,"html_url":"https://github.com/magnetrwn/runtime-bitset-cpp","commit_stats":null,"previous_names":["magnetrwn/runtime-bitset-cpp"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/magnetrwn%2Fruntime-bitset-cpp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/magnetrwn%2Fruntime-bitset-cpp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/magnetrwn%2Fruntime-bitset-cpp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/magnetrwn%2Fruntime-bitset-cpp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/magnetrwn","download_url":"https://codeload.github.com/magnetrwn/runtime-bitset-cpp/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241001917,"owners_count":19892076,"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","data-structures","header-only","runtime"],"created_at":"2024-11-11T19:14:58.500Z","updated_at":"2025-02-27T09:57:42.600Z","avatar_url":"https://github.com/magnetrwn.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Runtime Bitset CPP\n**This is a very compact header-only library for creating bitsets like `std::bitset` at runtime.**\n\n```cpp\n#include \"rbitset.hpp\"\nusing RB::RuntimeBitset;\n\n// Simple syntax...\nRuntimeBitset\u003c\u003e p(20);\n\n// ...templated for selectable underlying types...\nRuntimeBitset\u003cuint32_t\u003e q(20);\n\n// ...with overloaded constructors...\nRuntimeBitset\u003c\u003e r;\nr = RuntimeBitset\u003c\u003e(20);\n\n// ...and fill on creation...\nRuntimeBitset\u003c\u003e s(20, true); // All true!\n\n// ...as well as move and copy assignments.\nr = s;            // Copy!\ns = std::move(p); // Move!\n```\n\n# Installation\n\nTo use the library, you can:\n```sh\ncd lib\ngit clone https://github.com/magnetrwn/runtime-bitset-cpp\n```\nand include the library from its location, usually from inside `lib/` in your project root.\n\nThe library contains just two classes:\n+ `RuntimeBitset` → Main wrapper for bitsets\n+ `BitReference` → Friend class, returned by accessing a bit in the bitset\n\n# Operations\n\nWhen working with a RuntimeBitset, index accessing has a bit of a quirk:\n```cpp\n#include \"rbitset.hpp\"\nusing RB::RuntimeBitset;\n\nbool demonstratingBitsets() {\n    RuntimeBitset\u003c\u003e bs(20);\n\n    bs[0] = true;\n    // Calls operator[] on RuntimeBitset instance, which returns BitReference.\n    // BitReference operator= is then called to set the value.\n\n    auto firstIndexRef = bs[0];\n    // This might be confused as getting the bool rvalue, but\n    // it's actually returning a BitReference to the requested bit!\n\n    return (bool) bs[0] == (bool) firstIndexRef;\n    // To actually get the rvalue, casting to bool through BitReference's\n    // operator bool() is required.\n}\n\n```\n\nBitReference is able to act on a single bit by using a bit mask stored in the instance, together with a block index to locate the block where the bit is located.\n\n# Includes\n\nHere are the includes used by the library:\n+ `\u003ccstring\u003e` → Used for `memset()` and `memcpy()`. You can change the precompiler define `RUNTIME_BITSET_USE_CSTRING_` to false if necessary, which will adjust the code to `for` loop alternatives.\n+ `\u003ccstddef\u003e` → Used only for standard C types, specifically `size_t`.\n\n# Speed\n\n`benchmark.cpp` basically has simple benchmarks to test speed against other possible implementations of data structures using bitsets and arrays, and more. Cache linearity is a relevant factor here, so the benchmark tries to be a little randomic as well.\n\n**Note:** keep in mind using a one-dimensional data structure with index offsetting is not being benchmarked here, but quite likely to improve speed and memory footprint.\n\nHere is a sample run from running `benchmark.cpp`:\n```\nRunning 4 rounds with 1000 rows and 1000 cols.\nRound: Done\n------------------------------------------------------------------\nRuntimeBitset\u003c\u003e(cols)[rows]              | 326710 us    | Baseline\nstd::array\u003cstd::bitset\u003ccols\u003e, rows\u003e      | 300917 us    | -7.9%\nstd::deque\u003cstd::deque\u003cbool\u003e\u003e             | 538531 us    | +64.8%\nstd::array\u003cstd::array\u003cbool, cols\u003e, rows\u003e | 229400 us    | -29.8%\nbool[rows][cols]                         | 220894 us    | -32.4%\n------------------------------------------------------------------\n```\nOf course time results on different machines will change, but there is consistency between results from runs, and similarities on performance deltas between implementations.\n\n# Examples\n\nThis is a simple way to implement a memory efficient grid (although I guess it can be improved even more by making it all fit in a single big bitset and then offset indexes?):\n```cpp\n#include \u003ccstdio\u003e\n#include \u003ccstddef\u003e\n#include \u003cmemory\u003e\n\n#include \"rbitset.hpp\"\n\nusing RB::RuntimeBitset;\n\n\nstd::unique_ptr\u003cRuntimeBitset\u003c\u003e[]\u003e bitsetGridGen(const size_t rows, const size_t cols) {\n    auto grid = std::make_unique\u003cRuntimeBitset\u003c\u003e[]\u003e(rows);\n\n    for (size_t i = 0; i \u003c rows; i++) {\n        grid[i] = RuntimeBitset\u003c\u003e(cols, false);\n    }\n\n    return grid;\n}\n\nint main() {\n    const size_t rows = 8, cols = 30;\n\n    auto grid = bitsetGridGen(rows, cols);\n\n    for (size_t i = 0; i \u003c rows; i++) {\n        for (size_t j = 0; j \u003c cols; j++) {\n            grid[i][j] = (i%2 == j%2);\n            printf(\"%hhx \", (bool) grid[i][j]);\n        }\n        printf(\"\\n\");\n    }\n\n    return 0;\n}\n```\nWhen run:\n```\n$ ./example\n1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0\n0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1\n1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0\n0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1\n1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0\n0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1\n1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0\n0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1\n```\n\n# Contributing and License\n\nAll code is under MIT, enjoy. Feel free to help, report issues, fork or send PRs if you want!\n\n**Note:** I created this because I needed a runtime bitset with a simple implementation, and reasonably small memory footprint, for my other project at `magnetrwn/margolus-cpp`, but it's still inefficient in access time versus compile-time `std::bitset`. It's also missing some relevant features like counting and bitwise operations for now.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmagnetrwn%2Fruntime-bitset-cpp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmagnetrwn%2Fruntime-bitset-cpp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmagnetrwn%2Fruntime-bitset-cpp/lists"}