Move constructor:
* m_isValid (bool) exchange(rhs.m_isValid, true)
* m_invalidKey (std::string) std::move()
* m_pMemory (shared_memory_holder) std::move()
* m_pNode (node*) exchange(rhs.m_pNode, nullptr)
This leaves the moved-from Node as if it was just default constructed.
Move assignment:
A sanity test is performed to check if it's a valid move, and
if not: *this is returned (with an added assert() for debugging).
A temporary Node is move constructed (using the move constructor), leaving
the moved-from Node as if it was just default constructed.
If this->m_pNode == nullptr, the same operation as AssignNode would do is done
and *this is returned.
if temporary.m_pNode == nullptr:
m_pNode->set_null()
swap(*this, temporary)
return *this;
Otherwise the merge step that AssignNode would do if both m_pNodes are not
nullptr is done, using a new member function, AssignNodeDetail().
Signed-off-by: Ted Lyngmo <ted@lyncon.se>