RWLEnvelope is a header-only C++ template library that provides a simple, convenient envelope-access model for thread-safe access to objects using reader-writer locks.
#include "siddiqsoft/RWLEnvelope.hpp"
// Declare a map as container and initialize it with some values
// Using initializer list constructor for convenient initialization.
Note the brace-count as we use brace initializer to construct the RWLEnvelope
// while constructing its internal storage with the std::map initializer!
siddiqsoft::RWLEnvelope<std::map<std::string, int>> data({
{"key", 1010},
{"key2", 2020},
{"key3", 3030}
});
// Read-only access
auto val = data.observe([](const auto& m) noexcept -> auto {
return m.value("key", 0);
});
// Read-write access
data.mutate([](auto& m) noexcept {
m["key"] = 42;
});
std::println(std::cerr, "Contents: {}", data.snapshot());- Automatic Lock Management: No manual lock/unlock needed
- Clear Intent:
observe()for reads,mutate()for writes - Exception Safe: Locks released properly even if callbacks throw
- Zero Overhead: Header-only, no runtime cost beyond std::shared_mutex
- Works with Any Type: Not limited to specific containers
- Convenient Initialization: Supports initializer lists for easy construction
The full documentation includes:
- Detailed API reference
- Usage patterns and examples
- Performance considerations
- Thread safety guarantees
- Requirements and limitations
Install-Package SiddiqSoft.RWLEnvelope
Copy include/siddiqsoft/RWLEnvelope.hpp to your project.
- C++ Standard: C++20 or later (requires C++20 concepts support)
- Compiler: Must support
[[nodiscard]]attribute and C++20 concepts - Headers:
<shared_mutex>,<functional>,<tuple>,<utility>,<concepts> - Optional: nlohmann/json library for JSON serialization support
// Multiple threads can read simultaneously
data.observe([](const auto& m) noexcept {
return m.at("key");
});// Only one thread can write at a time
data.mutate([](auto& m) noexcept {
m["key"] = 42;
});// For complex operations
if (auto [map, lock] = data.writeLock(); lock) {
map["key"] = 42;
map.erase("old_key");
}// Get a copy to process outside the lock
std::vector<int> copy = data.snapshot();
std::sort(copy.begin(), copy.end());// Construct with initializer list - works with any container supporting std::initializer_list
siddiqsoft::RWLEnvelope<std::vector<int>> vec({1, 2, 3, 4, 5});
// Maps and other associative containers
siddiqsoft::RWLEnvelope<std::map<std::string, int>> map({
{"key1", 1},
{"key2", 2},
{"key3", 3}
});
// JSON objects
siddiqsoft::RWLEnvelope<nlohmann::json> doc({
{"name", "John"},
{"age", 30},
{"active", true}
});siddiqsoft::RWLEnvelope<AppConfig> config;
// Multiple threads reading config
auto url = config.observe([](const auto& cfg) noexcept {
return cfg.databaseUrl;
});
// Single thread updating config
config.mutate([](auto& cfg) noexcept {
cfg.databaseUrl = "new_url";
});siddiqsoft::RWLEnvelope<std::unordered_map<std::string, CacheEntry>> cache;
// Fast concurrent reads
auto val = cache.observe([](const auto& c) noexcept {
return c.at("key").value;
});
// Exclusive writes
cache.mutate([](auto& c) noexcept {
c["key"] = {"computed_value", now()};
});// Initialize a cache with pre-populated data
siddiqsoft::RWLEnvelope<std::map<std::string, std::string>> cache({
{"user:1", "Alice"},
{"user:2", "Bob"},
{"user:3", "Charlie"}
});
// Initialize a JSON document with structured data
siddiqsoft::RWLEnvelope<nlohmann::json> config({
{"database", {{"host", "localhost"}, {"port", 5432}}},
{"cache", {{"ttl", 3600}, {"enabled", true}}}
});The library includes comprehensive test coverage with 38+ tests covering:
- Basic functionality (observe, mutate, readLock, writeLock)
- Initializer list construction
- Edge cases and exception safety
- Concurrent access patterns
- Data integrity under contention
Run tests:
cmake --preset Apple-Debug
cmake --build --preset Apple-Debug
ctest --preset Apple-DebugBSD 3-Clause License - See LICENSE file for details
- Full API Documentation - Complete reference and examples
- GitHub Repository - Source code and issues
- C++ std::shared_mutex - Standard library reference
© 2021 Abdulkareem Siddiq. All rights reserved.