{"id":31363793,"url":"https://github.com/mguludag/synchronized_value","last_synced_at":"2025-09-27T05:21:11.074Z","repository":{"id":316805657,"uuid":"1062876403","full_name":"mguludag/synchronized_value","owner":"mguludag","description":"A modern C++ thread-safe value wrapper with flexible locking strategies and convenient RAII guards.","archived":false,"fork":false,"pushed_at":"2025-09-26T21:12:32.000Z","size":50,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-26T21:19:03.731Z","etag":null,"topics":["cpp","cpp11","cpp17","cpp20","thread-safety","thread-synchronization"],"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/mguludag.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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-23T21:19:38.000Z","updated_at":"2025-09-26T21:12:36.000Z","dependencies_parsed_at":"2025-09-26T21:21:27.900Z","dependency_job_id":"8ff9c8bc-eba5-467c-98ea-55a6d9886ae9","html_url":"https://github.com/mguludag/synchronized_value","commit_stats":null,"previous_names":["mguludag/synchronized_value"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/mguludag/synchronized_value","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mguludag%2Fsynchronized_value","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mguludag%2Fsynchronized_value/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mguludag%2Fsynchronized_value/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mguludag%2Fsynchronized_value/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mguludag","download_url":"https://codeload.github.com/mguludag/synchronized_value/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mguludag%2Fsynchronized_value/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":277184144,"owners_count":25775286,"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-09-27T02:00:08.978Z","response_time":73,"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":["cpp","cpp11","cpp17","cpp20","thread-safety","thread-synchronization"],"created_at":"2025-09-27T05:21:09.636Z","updated_at":"2025-09-27T05:21:11.069Z","avatar_url":"https://github.com/mguludag.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# mgutility::thread::synchronized_value\n\nA modern C++ thread-safe value wrapper with flexible locking strategies and convenient RAII guards.\n\n## Features\n\n- Encapsulates any value type `T` with internal mutex synchronization.\n- Supports customizable lock policies to use `std::unique_lock`, `std::shared_lock`, or user-defined lock types.\n- Provides read and write lock guards with transparent pointer-like and dereference semantics.\n- Automatically select read or write locks based on constness. (const -\u003e read_lock, non-const -\u003e write_lock)\n- Callable interface supporting thread-safe access with lambdas.\n- Customizable operator support for wrapped values via specialization of `operators` template.\n- Safe simultaneous locking of multiple `synchronized_value` instances without deadlock.\n\n## C++ Version Compatibility\n\n- Compatible with **C++11** as a minimum.\n- If compiled with **C++17** or later, additional features such as `std::shared_mutex`, `std::shared_lock` are automatically enabled.\n\n## [Usage](https://godbolt.org/z/E147Tbx54)\n\n```c++\n#include \u003cmgutility/thread/synchronized_value.hpp\u003e\n#include \u003ciostream\u003e\n#include \u003cstring\u003e\n#include \u003cshared_mutex\u003e\n\nint main() {\n    mgutility::thread::synchronized_value\u003cint\u003e sv(42);\n\n    // Read access\n    sv([](const int\u0026 val) {\n        std::cout \u003c\u003c \"Value is \" \u003c\u003c val \u003c\u003c \"\\n\";\n    });\n\n    // Write access\n    sv([](int\u0026 val) {\n        val = 100;\n    });\n\n    // Classic lock guard style\n    {\n        auto guard = sv.synchronize(/* [optional] additional args for guard object like std::adopt_lock_t{} etc. */);\n        std::cout \u003c\u003c \"Read with lock: \" \u003c\u003c *guard \u003c\u003c \"\\n\";\n        guard = 50; // assign new value directly (same as *guard = 50)\n    }\n}\n```\n\n## Customization Points\n\n### Specializing `lock_policy`\n\nYou can customize which lock types are used for reading and writing by specializing the `lock_policy` for your own mutex-like types. This allows transparent use of shared mutexes, custom spinlocks, or other synchronization primitives.\n\nExample - specialize for a custom shared mutex:\n\n```c++\n#include \u003cmgutility/thread/synchronized_value.hpp\u003e\n\nstruct MySharedMutex {\n    void lock() { /* exclusive lock implementation */ }\n    void unlock() { /* exclusive unlock */ }\n    void lock_shared() { /* shared lock */ }\n    void unlock_shared() { /* shared unlock */ }\n};\n\ntemplate \u003c\u003e\nstruct mgutility::thread::lock_policy\u003cMySharedMutex\u003e {\n    using read_lock = std::shared_lock\u003cMySharedMutex\u003e;\n    using write_lock = std::unique_lock\u003cMySharedMutex\u003e;\n};\n\nint main() {\n    mgutility::thread::synchronized_value\u003cint, MySharedMutex\u003e sv(42);\n\n}\n\n```\n\n### Specializing `operators`\n\nThe `operators\u003cT\u003e` template provides default equality and inequality operators that operate on the wrapped reference of type `T`. Users can specialize or inherit from this template to add or override operators for custom or complex types.\n\nExample specialization for `std::filesystem::path` demonstrating custom comparison and path concatenation:\n\n```c++\n#include \u003cmgutility/thread/synchronized_value.hpp\u003e\n#include \u003ciostream\u003e\n#include \u003cfilesystem\u003e\n\ntemplate \u003c\u003e\nclass mgutility::thread::operators\u003cstd::filesystem::path\u003e : public ref_wrapper\u003cstd::filesystem::path\u003e {\npublic:\n    using ref_wrapper\u003cstd::filesystem::path\u003e::value;\n\n    explicit operators(std::filesystem::path\u0026 p) noexcept\n        : ref_wrapper\u003cstd::filesystem::path\u003e(p) {}\n\n    auto operator==(const std::filesystem::path\u0026 rhs) const -\u003e bool {\n        return std::filesystem::equivalent(value(), rhs);\n    }\n\n    auto operator!=(const std::filesystem::path\u0026 rhs) const -\u003e bool {\n        return !(*this == rhs);\n    }\n\n    auto operator/(const std::filesystem::path\u0026 rhs) const -\u003e std::filesystem::path {\n        return value() / rhs;\n    }\n\n    auto operator/=(const std::filesystem::path\u0026 rhs) -\u003e std::filesystem::path\u0026 {\n        return (value() /= rhs);\n    }\n\n    friend auto operator\u003c\u003c(std::ostream\u0026 os, operators\u003cstd::filesystem::path\u003e\u0026 val) -\u003e std::ostream\u0026\n    {\n        return os \u003c\u003c val.value();\n    }\n};\n\nint main() {\n    mgutility::thread::synchronized_value\u003cstd::filesystem::path\u003e sv(\"/usr/local\");\n\n    {\n        auto\u0026\u0026 path = sv.synchronize();\n        path /= \"bin\";\n        std::cout \u003c\u003c \"bin folder: \" \u003c\u003c path \u003c\u003c \"\\n\"; // uses operator\u003c\u003c from user defined specialization\n    }\n\n    // or...\n\n    mgutility::thread::synchronized_value\u003cstd::filesystem::path\u003e sv_path(\"/usr/local\");\n\n    std::cout \u003c\u003c \"bin folder: \" \u003c\u003c (*sv_path /= \"bin\") \u003c\u003c \"\\n\";\n\n   // or use operator() with lambda\n\n}\n```\n\n## Related Libraries and work\n* [Boost synchronized_value](https://www.boost.org/doc/libs/latest/doc/html/thread/sds.html)\n* [CsLibGuarded](https://github.com/copperspice/cs_libguarded)\n* [Folly Synchronized\u003cT\u003e](https://github.com/facebook/folly/blob/main/folly/docs/Synchronized.md)\n* C++ proposals [P0290R4](https://wg21.link/P0290R4) and [N4033](https://wg21.link/N4033).\n\n## License\n\nMIT License, see the [LICENSE](LICENSE) file.\n\n## Contribution\n\nContributions, bug reports, and feature requests are welcome! Feel free to check the issues page.\n\n---\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmguludag%2Fsynchronized_value","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmguludag%2Fsynchronized_value","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmguludag%2Fsynchronized_value/lists"}