The library provides also some types that, while they are not exactly immutable data-structures, they are very useful when using immutable data-structures and value-oriented design in practice.


template <typename T, typename MemoryPolicy = default_memory_policy>
class immer::atom

Stores for boxed values of type T in a thread-safe manner.


If memory policy used includes thread unsafe reference counting, no thread safety is assumed, and the atom becomes thread unsafe too!


box<T> provides a value based box of type T, this is, we can think about it as a value-based version of std::shared_ptr. In a similar fashion, atom<T> is in spirit the value-based equivalent of C++20 std::atomic_shared_ptr. However, the API does not follow std::atomic interface closely, since it attempts to be a higher level construction, most similar to Clojure’s (atom). It is remarkable in particular that, since box<T> underlying object is immutable, using atom<T> is fully thread-safe in ways that std::atomic_shared_ptr is not. This is so because dereferencing the underlying pointer in a std::atomic_share_ptr may require further synchronization, in particular when invoking non-const methods.


Public Types

using box_type = box<T, MemoryPolicy>
using value_type = T
using memory_policy = MemoryPolicy

Public Functions

atom(const atom&)
void operator=(const atom&)
void operator=(atom&&)
atom(box_type v = {})

Constructs an atom holding a value b;

atom &operator=(box_type b)

Sets a new value in the atom.

operator box_type() const

Reads the currently stored value in a thread-safe manner.

operator value_type() const

Reads the currently stored value in a thread-safe manner.

box_type load() const

Reads the currently stored value in a thread-safe manner.

void store(box_type b)

Stores a new value in a thread-safe manner.

box_type exchange(box_type b)

Stores a new value and returns the old value, in a thread-safe manner.

template <typename Fn>
box_type update(Fn &&fn)

Stores the result of applying fn to the current value atomically and returns the new resulting value.


fn must be a pure function and have no side effects! The function might be evaluated multiple times when multiple threads content to update the value.