c++ - gcc list node swap implementation overcomplicated? -
i'm using sgi stl (gcc) reference custom library, , while digging std::list::swap()
came across following implementation,
note: method not handle adjacent nodes properly.
// namespace std { // namespace __detail { void _list_node_base::swap(_list_node_base& __x, _list_node_base& __y) throw() { if ( __x._m_next != &__x ) { if ( __y._m_next != &__y ) { // both __x , __y not empty. std::swap(__x._m_next,__y._m_next); std::swap(__x._m_prev,__y._m_prev); __x._m_next->_m_prev = __x._m_prev->_m_next = &__x; __y._m_next->_m_prev = __y._m_prev->_m_next = &__y; } else { // __x not empty, __y empty. __y._m_next = __x._m_next; __y._m_prev = __x._m_prev; __y._m_next->_m_prev = __y._m_prev->_m_next = &__y; __x._m_next = __x._m_prev = &__x; } } else if ( __y._m_next != &__y ) { // __x empty, __y not empty. __x._m_next = __y._m_next; __x._m_prev = __y._m_prev; __x._m_next->_m_prev = __x._m_prev->_m_next = &__x; __y._m_next = __y._m_prev = &__y; } }
this looks me if simplified to,
void _list_node_base::swap(_list_node_base& __x, _list_node_base& __y) throw() { _list_node_base* __xnext = __x._m_next; _list_node_base* __xprev = __x._m_prev; _list_node_base* __ynext = __y._m_next; _list_node_base* __yprev = __y._m_prev; __xnext->_m_prev = __xprev->_m_next = &__y; __ynext->_m_prev = __yprev->_m_next = &__x; std::swap(__x._m_next,__y._m_next); std::swap(__x._m_prev,__y._m_prev); }
i've tested cases (empty/empty, empty/not-empty, etc.), including __x
, __y
referencing same node, , seems work, however, trust in sgi codebase making me doubt myself.
so question is: correct? , if there benefit using longer version?
thank you.
self-assignment checks rage. they're known pessimizations , bug-hiding now. may want find more modern source of inspiration.
Comments
Post a Comment