hierclass::base::writerlock lock=h->create_writelock();
A writer lock implements all methods that
a reader lock does, and is
type-convertible to a reader lock. The sole exception is that the
writer lock's
clone
() throws an exception (this applies
to the writer lock that gets accessed as a reader lock, too).
Only one writer lock can exist at a time,
create_writelock
() waits until no other
reader or writer locks exist, before it returns. This is why
its clone
() throws an exception, since
another lock cannot exist until the writer lock itself goes away.
bool flag=lock->insert([] { return valueRef::create(); }, key, [] (valueRef &&existing) { return false; });
insert
() adds or replaces a value in the
hierarchical container. The second parameter is a hierarchical key
relative to the writer lock's current node.
create_writelock
(), like
create_readlock
(), constructs a lock initially
referring to the hierarchy's root node, in which case the key specifies
the absolute container key.
However, the writer lock implements all of reader lock's
to_child
() and
to_parent
() methods, to reposition the writer
lock to any existing key in the container. The key parameter to
insert
() gets interpreted relative to the
writer lock's current node position. An empty list refers to the
writer lock's current position.
The first parameter to insert
() is a lambda or
a functor that returns the new value for the container, an
x::ref
value.
insert
() calls it to obtain the value to
install for the referenced key.
If the referenced key already has a value, the third parameter determines
whether the existing value gets replaced, or not.
The third parameter to insert
() is
also a lambda or a functor. It receives the key's existing value,
as an rvalue reference. Returning
true
replaces the existing value in the container.
The first lambda/functor gets called to obtain the new value for the key.
Returning
false
does not replace the existing value in the
container.
The first lamba/functor parameter to
insert
() does not get invoked if there's
already an existing value for the referenced key, and the third
lambda/functor parameter returns false
.
bool flag=lock->erase(key); bool flag=lock->prune(key); bool flag=lock->prune_if(key, [] (valueRef &&value, const key &name) { return true; });
erase
() removes an existing key from the
container.
key
specifies a hierarchical key, relative to the
writer lock's current node (an empty list for the current node).
erase
() returns
false
if the referenced key did not have a value
in the container. If the key had a value,
erase
() returns true
after changing the writer node's current position to the removed key's
closest parent node that has a value, or to the container's
root node.
erase
() removes only the referenced key's value,
and does not remove the values for any existing
inferior child nodes (the referenced key becomes an intermediate node).
prune
() removes all inferior nodes of the
referenced key, but does not erase the value for the referenced key.
If the referenced key exists, when
prune
() returns the writer lock's current node
becomes the referenced key, otherwise it current node becomes the
closest parent with a value (or the root node).
prune_if
() calls the lambda/functor before
pruning each individual inferior node, with two parameters: the value
itself, and its full container key.
If the lamba/functor returns
true
the value gets removed, otherwise it
does not get removed from the container.
prune
() is equivalent to
prune_if
() with the functor always returning
true
.
bool flag=lock->erase(); bool flag=lock->prune();
This is equivalent to specifying a key that's an empty list: the erasure/prune for the writer lock's current node.