{"id":19735993,"url":"https://github.com/siddiqsoft/rwlenvelope","last_synced_at":"2026-02-07T12:30:55.940Z","repository":{"id":142736447,"uuid":"388359489","full_name":"SiddiqSoft/rwlenvelope","owner":"SiddiqSoft","description":"Read-write envelope class","archived":false,"fork":false,"pushed_at":"2024-12-07T08:00:18.000Z","size":77,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-08T07:51:18.724Z","etag":null,"topics":["cpp17","lock","locking","nuget","reader-writer","thread-safe","utility-class","utility-classes"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SiddiqSoft.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":"2021-07-22T06:54:04.000Z","updated_at":"2024-12-07T07:56:46.000Z","dependencies_parsed_at":null,"dependency_job_id":"313f8f55-682d-40eb-a34d-450dc85cf10b","html_url":"https://github.com/SiddiqSoft/rwlenvelope","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SiddiqSoft%2Frwlenvelope","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SiddiqSoft%2Frwlenvelope/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SiddiqSoft%2Frwlenvelope/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SiddiqSoft%2Frwlenvelope/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SiddiqSoft","download_url":"https://codeload.github.com/SiddiqSoft/rwlenvelope/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":233394257,"owners_count":18669682,"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":["cpp17","lock","locking","nuget","reader-writer","thread-safe","utility-class","utility-classes"],"created_at":"2024-11-12T01:04:39.910Z","updated_at":"2026-02-07T12:30:55.927Z","avatar_url":"https://github.com/SiddiqSoft.png","language":"C++","readme":"RWLEnvelope : A simple read-writer lock envelope\n-------------------------------------------\n\n[![CodeQL](https://github.com/SiddiqSoft/RWLEnvelope/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/SiddiqSoft/RWLEnvelope/actions/workflows/codeql-analysis.yml)\n[![Build Status](https://dev.azure.com/siddiqsoft/siddiqsoft/_apis/build/status/SiddiqSoft.rwlenvelope?branchName=main)](https://dev.azure.com/siddiqsoft/siddiqsoft/_build/latest?definitionId=7\u0026branchName=main)\n![](https://img.shields.io/nuget/v/SiddiqSoft.RWLEnvelope)\n![](https://img.shields.io/github/v/tag/SiddiqSoft/RWLEnvelope)\n![](https://img.shields.io/azure-devops/tests/siddiqsoft/siddiqsoft/7)\n![](https://img.shields.io/azure-devops/coverage/siddiqsoft/siddiqsoft/7)\n\n# Objective\n- Avoid re-implementing the rw-lock; standard C++ (since C++14) has a good reader-writer lock implementation.\n- Provide a simple, convenience layer atop the underlying [`std::unique_lock`](https://en.cppreference.com/w/cpp/thread/unique_lock) and [`std::shared_lock`](https://en.cppreference.com/w/cpp/thread/shared_lock) access to some type.\n\n\u003cp align=\"right\" width=\"50%\"\u003e\n\u003cb\u003eWE DO NOT IMPLEMENT\u003c/b\u003e a read-writer lock; the standard C++ library has one.\u003cbr/\u003eWe provide a header-only package simplifying the locking code around thread-safe access to your underlying type.\n\u003cbr/\u003e\n\u003ci\u003eNOT a wrapper; an envelope.\u003c/i\u003e\n\u003c/p\u003e\n\n# Requirements\n- You must be able to use [`\u003cshared_mutex\u003e`](https://en.cppreference.com/w/cpp/thread/shared_mutex) and [`\u003cmutex\u003e`](https://en.cppreference.com/w/cpp/thread/mutex).\n- Minimal target is `C++17`.\n- The build and tests are for Visual Studio 2019 under x64.\n- We use [`nlohmann::json`](https://github.com/nlohmann/json) only in our tests and the library is aware to provide a conversion operator if library is detected.\n\n# Usage\n\n- Use the nuget [SiddiqSoft.RWLEnvelope](https://www.nuget.org/packages/SiddiqSoft.RWLEnvelope/)\n- Copy paste..whatever works.\n- The idea is to not \"wrap\" the underlying type forcing you to either inherit or re-implement the types but to take advantage of the underlying type's interface whilst ensuring that we have the necessary locks.\n- Two methods:\n  - Observer/mutator model with callback and custom return to limit access and to focus the where and how to access the underlying type.\n  - Take advantage of [init-statement in if-statement](https://en.cppreference.com/w/cpp/language/if) to get the contained object within a lock and have the compiler auto-release once we leave scope.\n- A sample implementation (say you want a std::map with reader-writer lock)\n  - `using RWLMap = siddiqsoft::RWLEnvelope\u003cstd::map\u003e;`\n\n\n```cpp\n#include \"gtest/gtest.h\"\n#include \"nlohmann/json.hpp\"\n#include \"siddiqsoft/RWLEnvelope.hpp\"\n\n\nTEST(examples, AssignWithCallbacks)\n{\n\tsiddiqsoft::RWLEnvelope\u003cnlohmann::json\u003e docl; // we will assign later\n\tnlohmann::json                          doc2 {{\"baa\", 0x0baa}, {\"fee\", 0x0fee}, {\"bee\", 0x0bee}};\n\n\t// Move assign here post init\n\tdocl.reassign(std::move(doc2));\n\t// Must be empty since we moved it into the envelope\n\tEXPECT_TRUE(doc2.empty());\n\n\t// Check we have pre-change value.. Note that here we return a boolean to avoid data copy\n\tEXPECT_TRUE(docl.observe\u003cbool\u003e([](const auto\u0026 doc) -\u003e bool {\n\t\treturn (doc.value(\"fee\", 0xfa17) == 0x0fee) \u0026\u0026 (doc.value(\"baa\", 0xfa17) == 0x0baa) \u0026\u0026 (doc.value(\"bee\", 0xfa17) == 0x0bee);\n\t}));\n\n\tEXPECT_EQ(3, docl.observe\u003csize_t\u003e([](const auto\u0026 doc) { return doc.size(); }));\n}\n\n\nTEST(examples, AssignWithDirectLocks)\n{\n\tsiddiqsoft::RWLEnvelope\u003cnlohmann::json\u003e docl({{\"foo\", \"bar\"}, {\"few\", \"lar\"}});\n\tnlohmann::json                          doc2 {{\"baa\", 0x0baa}, {\"fee\", 0x0fee}, {\"bee\", 0x0bee}};\n\n\t// Previous document has two items..\n\tif (auto const\u0026 [doc, rl] = docl.readLock(); rl) { EXPECT_EQ(2, doc.size()); }\n\n\t// Modify the item (replace the initial with new)\n\tif (auto [doc, wl] = docl.writeLock(); wl) { doc = std::move(doc2); };\n\n\t//doc2 -\u003e Must be empty since we moved it into the envelope\n\tEXPECT_TRUE(doc2.empty());\n\n\t// Check we have post-change value..\n\tif (const auto\u0026 [doc, rl] = docl.readLock(); rl) { EXPECT_EQ(3, doc.size()); }\n}\n```\n\nAdditional [examples](tests/examples.cpp).\n\n\n\u003csmall align=\"right\"\u003e\n\n\u0026copy; 2021 Siddiq Software LLC. All rights reserved.\n\n\u003c/small\u003e\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsiddiqsoft%2Frwlenvelope","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsiddiqsoft%2Frwlenvelope","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsiddiqsoft%2Frwlenvelope/lists"}