Part of Kronuz C++ Libraries, a collection of small, reusable C++ libraries.
Atomic shared_ptr for C++20: std::atomic<std::shared_ptr<T>> where the library has it, a
drop-in wrapper elsewhere. Where the standard library defines __cpp_lib_atomic_shared_ptr
(libstdc++, for one), atomic_shared_ptr<T> is a plain alias of the standard type. Where it
does not (Apple clang's libc++), it is a small class over the free std::atomic_* functions
for shared_ptr, with the same member API. Reach for it to publish immutable snapshots to
many threads from code that must build on both.
- The standard member API.
load,store,exchange,compare_exchange_weak,compare_exchange_strongandis_lock_free, each with itsstd::memory_order. - Self-retiring. The alias is chosen by
__cpp_lib_atomic_shared_ptr, so the wrapper disappears from a build as soon as its standard library gains the specialization. - A strict drop-in. The wrapper is neither copyable nor movable and converts to nothing, so code that builds against it also builds against the standard type.
- No dependencies. One header, standard library only.
#include "atomic_shared_ptr.h"
#include <cstdio>
#include <memory>
#include <thread>
struct Config { int version = 0; };
int main() {
atomic_shared_ptr<Config> current{std::make_shared<Config>()};
std::thread writer([&] { // publishes the next snapshot
auto seen = current.load();
auto next = std::make_shared<Config>(Config{seen->version + 1});
while (!current.compare_exchange_weak(seen, next)) {
next = std::make_shared<Config>(Config{seen->version + 1});
}
});
writer.join();
std::printf("version %d\n", current.load()->version); // version 1
}Requires a C++20 compiler; CMake 3.16 or newer for the CMake route. CI builds it on Linux (x86_64, arm64), macOS (arm64, x86_64), and FreeBSD, plus ASan, UBSan, and TSan builds.
include(FetchContent)
FetchContent_Declare(atomic-shared-ptr
GIT_REPOSITORY https://github.com/Kronuz/atomic-shared-ptr.git
GIT_TAG 9a2582ea13a367d03a07390f1a0f8ec93bc17073) # main tracks the tip
FetchContent_MakeAvailable(atomic-shared-ptr)
target_link_libraries(my_app PRIVATE atomic-shared-ptr::atomic-shared-ptr)Then #include "atomic_shared_ptr.h", or copy that one header onto your include path.
It fits immutable snapshots (configurations, routing tables) published by one thread and read by many, in code that has to build on standard libraries with and without the specialization.
Not for:
- Code that only targets libraries with the specialization. Use
std::atomic<std::shared_ptr<T>>directly. - Lock-free paths. Neither branch is lock-free on libc++ or libstdc++;
is_lock_free()returnsfalsethere.
- ARCHITECTURE.md: the two branches and why both are drop-ins.
- AGENTS.md: repository map.
- Catalog entry in Kronuz C++ Libraries.
cmake -B build && cmake --build build && ctest --test-dir buildThe test covers each operation and runs an eight-thread smoke test.
Issues and pull requests are welcome. Read AGENTS.md and the catalog's rules of engagement first; CI must pass on every platform.
MIT, Copyright (c) 2026 Germán Méndez Bravo and (c) 2015-2020 Dubalu LLC. See LICENSE. Extracted from Xapiand.