Mutex-protected references

#include <x/mp.H>

class mpobject {

public:
    int v;
};

x::mp<mpobject> mpv{4};

int nv=mpv->v;

auto old=mpv.get();

mpv.update([=](auto &v){v.v=nv+1;});

x::mp's template parameter must be a class that implements a copy-constructor. x::mp's constructor's parameters get forwarded to the class, constructing an internal mutex-protected reference-counted object containing this class;

get()() returns an x::const_ref to the wrapped object, with ->() overloaded as an alias for get(). The internal mutex lock is acquired only for the duration of get()().

Modifying the object requires passing a lambda or a functor to update()(). The lambda receives a mutable reference to the object. The reference gets copy-constructed first, so any outstanding get()s do not get impacted. An internally lock gets held for the duration of the update()() blocking any new get()s, and the internally-wrapped reference gets updated after the lambda returns, and before releasing the lock. A thrown exception in the lambda results in any changes to the object getting discarded, and the unmodified object getting unlocked.

Nested update()s (made during the execution of the lambda) are allowed, but each update() lambda receives a reference to a separate copy of the original object, with changes to the initial update() getting unlocked, when it returns.