std::list swap

C

Chris Forone

hello group,

is there a function to swap two elements in a std::list that only
changes the pointers/references or ist this standard behavior anyway?

swap and iter_swap seem to change per assignment...

thanx & hand, chris
 
N

Niels Dekker - no return address

Chris said:
is there a function to swap two elements in a std::list that only
changes the pointers/references or ist this standard behavior anyway?

swap and iter_swap seem to change per assignment...

What is your type of elements?

Suppose you have std::list<T> with T = std::string, and your iterators (iter1,
iter2) are of type std::list<T>::iterator. In that case, iter_swap(iter1,
iter2) will use an overloaded version of std::swap for std::string, which is
efficient (has constant-time complexity), and offers the no-throw guarantee
(i.e. it won't throw any exception). The Standard C++ Library has such
overloaded versions of std::swap for all STL container classes.

Does that answer your question?


Kind regards,
 
K

Kai-Uwe Bux

Chris said:
hello group,

is there a function to swap two elements in a std::list that only
changes the pointers/references or ist this standard behavior anyway?

swap and iter_swap seem to change per assignment...

For moving elements and subranges of lists around by pointer magic, the
standard provides the splice() functions. As far as I know, there is no
convenience hack for swapping.


Best

Kai-Uwe Bux
 
C

Chris Forone

Niels said:
What is your type of elements?

Suppose you have std::list<T> with T = std::string, and your iterators (iter1,
iter2) are of type std::list<T>::iterator. In that case, iter_swap(iter1,
iter2) will use an overloaded version of std::swap for std::string, which is
efficient (has constant-time complexity), and offers the no-throw guarantee
(i.e. it won't throw any exception). The Standard C++ Library has such
overloaded versions of std::swap for all STL container classes.

Does that answer your question?


Kind regards,
yes! i think, std::vector/std::valarray in the std::list are swapped
using optimized versions.
http://www.cplusplus.com/reference/algorithm/iter_swap.html say, that
only swap has constant time, but there are also one copy construction
and two assignments.

thanks, chris
 
C

Chris Forone

Kai-Uwe Bux said:
For moving elements and subranges of lists around by pointer magic, the
standard provides the splice() functions. As far as I know, there is no
convenience hack for swapping.


Best

Kai-Uwe Bux
ah, ok. thanks a lot!

chris
 
K

Kai-Uwe Bux

Chris said:
ah, ok. thanks a lot!

Maybe, the following works for you:

template < typename Iter, typename List >
void swap_list_ranges ( Iter from1, Iter to1, List & list1,
Iter from2, Iter to2, List & list2 ) {
if ( to1 == from2 ) {
list2.splice( from2, list1, from1, to1 );
list1.splice( to1, list2, from2, to2 );
} else {
list1.splice( from1, list2, from2, to2 );
list2.splice( to2, list1, from1, to1 );
}
}

(I hope the code handles possibly invalidated iterators for adjacent ranges
correctly. I did not think through all possible cases, though.)


Best

Kai-Uwe Bux
 
N

Niels Dekker - no return address

Chris said:
....
http://www.cplusplus.com/reference/algorithm/iter_swap.html say, that
only swap has constant time, but there are also one copy construction
and two assignments.

Hmm, when you're using an old STL implementation, iter_swap(iter1, iter2) may
not call swap(*iter1, *iter2). Instead, it might indeed do an copy
construction and two assignments, which may be expensive. So I guess you
should call swap(*iter1, *iter2) directly, instead of using iter_swap.

If your list element type is one of your own classes, there's an extra reason
to call swap, instead of iter_swap, because you may have provided your own
swap function for that class...


Kind regards, Niels
 
A

Andrey Tarasevich

Chris said:
is there a function to swap two elements in a std::list that only
changes the pointers/references or ist this standard behavior anyway?

You can swap elements by doing two consecutive 'move' operations using the
'splice(iterator, list, iterator)' method. It is legal to use 'splice' to splice
from one list into the same list.
 
C

Chris Forone

Chris said:
hello group,

is there a function to swap two elements in a std::list that only
changes the pointers/references or ist this standard behavior anyway?

swap and iter_swap seem to change per assignment...

thanx & hand, chris
thanx guys, the splice did it!

theList.splice(theList.end(), theList, theList.begin());
"rotates" the list left and

theList.splice(theList.begin(), theList, --theList.end());
"rotates" the list right...

thats EXACTLY what i need!!!

best regards, chris
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,607
Members
45,240
Latest member
pashute

Latest Threads

Top