Shared lock objects

#include <x/sharedlock.H>

x::sharedlock lock=x::sharedlock::create();

// ...

{
  x::sharedlock::base::shared shared=lock->create_shared();


}

// ...

{
  x::sharedlock::base::unique unique=lock->create_unique();


}

x::sharedlock is mostly a reference-counted version of std::shared_timed_mutex that also uses reference-counted lock objects. This class uses the terminology of "read lock" and "write lock", instead of "shared lock" and "unique lock" Its create_shared() acquires a shared lock on the underlying object, and create_unique() acquires a unique (exclusive) lock on the underlying object. The underlying locks are also reference-counted objects, that can be freely passed around. The locks are released when the last reference to a lock object goes out of scope and an object gets destroyed. x::sharedlock implements try_shared() and try_unique() which are analogous to a mutex's try_lock().

try_shared_until(), try_shared_for(), try_unique_until(), and try_unique_for() also return a nullable reference pointer to the acquired lock, which is null if the lock cannot be acquired.