{"id":17252036,"url":"https://github.com/ppetr/refcounted-var-sized-class","last_synced_at":"2025-03-26T07:23:04.025Z","repository":{"id":146160487,"uuid":"317789702","full_name":"ppetr/refcounted-var-sized-class","owner":"ppetr","description":"Type-safe, reference-counted pointers to variable-sized classes ","archived":false,"fork":false,"pushed_at":"2024-09-27T11:03:54.000Z","size":211,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-01-31T08:44:14.122Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/ppetr.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"docs/contributing.md","funding":null,"license":"LICENSE","code_of_conduct":"docs/code-of-conduct.md","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":"2020-12-02T07:57:36.000Z","updated_at":"2024-09-27T11:03:58.000Z","dependencies_parsed_at":null,"dependency_job_id":"d5f81a55-08c1-4812-af3f-00ee12fc2895","html_url":"https://github.com/ppetr/refcounted-var-sized-class","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/ppetr%2Frefcounted-var-sized-class","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ppetr%2Frefcounted-var-sized-class/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ppetr%2Frefcounted-var-sized-class/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ppetr%2Frefcounted-var-sized-class/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ppetr","download_url":"https://codeload.github.com/ppetr/refcounted-var-sized-class/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245606467,"owners_count":20643187,"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":[],"created_at":"2024-10-15T06:52:52.951Z","updated_at":"2025-03-26T07:23:03.997Z","avatar_url":"https://github.com/ppetr.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Type-safe, reference-counted pointers to variable-sized classes\n\n[![Build Status](https://travis-ci.com/ppetr/refcounted-var-sized-class.svg?branch=main)](https://travis-ci.com/ppetr/refcounted-var-sized-class)\n\n_*Disclaimer:* This is not an officially supported Google product._\n\n## Summary\n\n[`MakeUnique(length, args...)`](var_sized.h) creates a new value on the heap\ntogether with an array of size `length` in a **single allocation**. A pointer\nto the array is stored in an output argument. Proper destruction is ensured by\na custom deleter.\n\n[`MakeShared(length, args...)`](var_sized.h) creates a new value on the heap\ntogether with an array of size `length` in a **single allocation** (assuming\n[`std::allocate_shared`] uses a single allocation). A pointer to the array is\nstored in an output argument.  Proper destruction is ensured by a custom\nallocator.\n\n[`std::allocate_shared`]: https://en.cppreference.com/w/cpp/memory/shared_ptr/allocate_shared\n\n**Note:** The `Ref` type below, although slightly more performant, is mostly\nmade obsolete by `MakeShared`.\n\nType [`Ref`](ref.h) manages a reference-counted value on the heap with\ntype-safe sharing:\n\n- `Ref\u003cT\u003e` allows mutable access to `T` and is move-only. Always contains a\n  value (unless moved out).\n- `Ref\u003cconst T\u003e` allows `const`-only access to `T`, but can be freely copied.\n  Always contains a value (unless moved out).\n- `Ref` is very **lightweight**, contain only a single pointer.\n- `Ref\u003cT\u003e` can be always converted to `Ref\u003cconst T\u003e` by its `Share() \u0026\u0026` method\n  and is consumed by the conversion.  The opposite convertion is possible by\n  `AttemptToClaim() \u0026\u0026` if the caller is a sole owner of it.\n\nThese two concepts can be combined together using `MakeRefCounted`, which\ncreates a reference-counted, variable-sized structure with a single memory\nallocation (akin to [`std::allocate_shared`]).\n\n### Benchmarks\n\nBenchmarks comparing `MakeUnique` and `MakeShared` to the standard `std::`\nfunctions are defined in [var_sized_benchmark.cc](var_sized_benchmark.cc).\n\nResults on _Intel(R) Core(TM) i5-3470 CPU @ 3.20GHz_ with\n-DCMAKE_TOOLCHAIN_FILE=\"devel/toolchain-**clang11**.cmake\" -DBENCHMARK_ENABLE_LTO=true -DCMAKE_BUILD_TYPE=Release:\n\n```\nCPU Caches:\n  L1 Data 32 KiB (x4)\n  L1 Instruction 32 KiB (x4)\n  L2 Unified 256 KiB (x4)\n  L3 Unified 6144 KiB (x1)\n----------------------------------------------------------------------------\nBenchmark                                  Time             CPU   Iterations\n----------------------------------------------------------------------------\nBM_VarSizedUniqueString                 1518 ns         1518 ns       462018\nBM_VarSizedSharedString                 2567 ns         2559 ns       275427\nBM_VarSizedRefCountedString             1521 ns         1520 ns       462505\nBM_VarSizedRefCountedSharedString       1553 ns         1553 ns       453952\nBM_MakeUniqueStdString                  1745 ns         1745 ns       401544\nBM_SharedStdString                      6480 ns         6480 ns       107960\nBM_MakeSharedStdString                  5315 ns         5314 ns       130625\n```\n\nResults on _Intel(R) Core(TM) i5-3470 CPU @ 3.20GHz_ with\n-DCMAKE_TOOLCHAIN_FILE=\"devel/toolchain-**gcc**.cmake\" -DBENCHMARK_ENABLE_LTO=true -DCMAKE_BUILD_TYPE=Release:\n\n```\nCPU Caches:\n  L1 Data 32 KiB (x4)\n  L1 Instruction 32 KiB (x4)\n  L2 Unified 256 KiB (x4)\n  L3 Unified 6144 KiB (x1)\n----------------------------------------------------------------------------\nBenchmark                                  Time             CPU   Iterations\n----------------------------------------------------------------------------\nBM_VarSizedUniqueString                 1517 ns         1517 ns       461315\nBM_VarSizedSharedString                 2552 ns         2552 ns       275468\nBM_VarSizedRefCountedString             1572 ns         1572 ns       446478\nBM_VarSizedRefCountedSharedString       1574 ns         1574 ns       444534\nBM_MakeUniqueStdString                  3087 ns         3087 ns       227068\nBM_SharedStdString                      5262 ns         5262 ns       132952\nBM_MakeSharedStdString                  3947 ns         3947 ns       177140\n```\n\n### Copy-on-Write\n\n[`CopyOnWrite`](copy_on_write.h) is an experimental type that manages an\ninstance of `T` on the heap. Copying `CopyOnWrite\u003cT\u003e` is as cheap as copying a\npointer, since copies are allowed to share a single instance. An actual copy of\n`T` is performed only when a mutable reference `T\u0026` is requested.\n\n## Dependencies\n\n- `cmake` (https://cmake.org/).\n- https://github.com/abseil/abseil-cpp (Git submodule)\n\nTesting dependencies:\n\n- https://github.com/google/benchmark (Git submodule)\n- https://github.com/google/googletest (Git submodule)\n\n## Contributions\n\nPlease see [Code of Conduct](docs/code-of-conduct.md) and [Contributing](docs/contributing.md).\n\nIdeas for contributions:\n\n- Add benchmarks with https://github.com/google/benchmark. In particular:\n  - Test the creation and manipulation speed of `Ref\u003cT\u003e` vs\n    `std::unique_ptr\u003cT\u003e` and `Ref\u003cconst T\u003e` vs `std::shared_ptr\u003cT\u003e`.\n  - Test the allocation speed of variable-sized classes vs a regular class and\n    a separately allocated array.\n- Allow arbitrary C++\n  [allocators](https://en.cppreference.com/w/cpp/named_req/Allocator).\n- Improve documentation where needed. This project should ideally have also\n  some didactical value.\n- Popularize the project to be useful to others too.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fppetr%2Frefcounted-var-sized-class","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fppetr%2Frefcounted-var-sized-class","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fppetr%2Frefcounted-var-sized-class/lists"}