-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make Node move constructor and assignment operator noexcept (#809) #810
base: master
Are you sure you want to change the base?
Conversation
bb1d6df
to
c66a0f7
Compare
This one probably needs reading through once or twice more. I'll be testing it at work tomorrow. For some reason I'm not catching as many linting problems at home. |
4267ca1
to
4498486
Compare
Making move assignment |
4498486
to
aa2e381
Compare
Add check that a move assigned Node gets the same representation as the moved-from Node had before the move. Signed-off-by: Ted Lyngmo <ted@lyncon.se>
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>
aa2e381
to
5fe7752
Compare
Hi, what's the status on this PR? It seems like it is not only making the move special functions noexcept, but actually defining them for the first time. It would be great if this library supported moves. |
Howdy and thanks for showing interest in this one!
It's ongoing (even though it's not been updated for a some time). I'm on a rebase mission to prepare for this change actually, so I've put it on hold for now, but I will need to face it soon. I have a library with classes carrying a I think (@jbeder will have to pitch in) that the move constructor in this PR will never destroy any existing functionality, so that part of the PR could be separated and submitted on its own so that the complicated move assignment operator would be the only one left. Perhaps that'd be a way to take a step forward? I've also been thinking about making a lot of test cases for things that this PR (or something like it) could break and deliver those long before this PR - but the thing is that don't have that deep knowledge of the inner workings of this lib that I wish I had, so the test cases I come up with is stuff that I sort of stumbe on while trying out new approaches and fix anyway. I'd be good if someone else wrote them. If you have ideas for tests etc., please do PR's to this branch in my fork and we can make an effort together. |
Another PR would be one that makes a deliberate breaking change so that moving really means moving. There are one or two test cases (regarding Aliases) that refuses that - but I could make an outline for such a change. It'd break those test cases and perhaps programs making use of the functionality though. As it is, it feels (for lack of better words) that any program using the copy magic when moving relies on side effects that should not be trusted in the first place, but I could be wrong. I'd like such a PR better because it'd make moving a |
This PR might resolve #1209 and #721. I think there are a number of assumptions made by std:: algorithms about how move constructors behave which are not met by YAML::Nodes at present. I briefly looked into adding |
Move constructor:
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 new 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 bothm_pNodes
are notnullptr is done, using a new member function,
AssignNodeDetail()
.Signed-off-by: Ted Lyngmo ted@lyncon.se