tags:

views:

797

answers:

5

I see qCopy, and qCopybackward but neither seems to let me make a copy in reverse order. qCopybackward only copies it in reverse order, but keeps the darn elements in the same order! All I want to do is return a copy of the list in reverse order. There has to be a function for that, right?

+2  A: 

For standard library lists it would look like this

std::list<X> result;
std::copy(list.rbegin(), list.rend(), result.back_inserter());

Unfortunately, Qt doesn't have rbegin and rend functions that return reverse iterators (the ones that go from the end of the container to its begnning). You may write them, or you can just write copying function on your own -- reversing a list is a nice excersize. Or you can note that QList is actually an array, what makes writing such a function trivial. Or you can convert the list to std::list, and use rbegin and rend. Choose whatever you like.

Pavel Shved
Well, I have written my own function in the meantime, but this bothers me greatly. How could they have left that out? I was indeed looking for rbegin and rend but they seem to have left those out too (muttering something about bidirectional iterators?), even though they implemented everything else from STL.
Mark
+4  A: 

If you don't like the QTL, just use the STL. They might not have a Qt-ish API, but the STL API is rock-stable :) That said, qCopyBackward is just std::copy_backward, so at least they're consistent.

Answering your question:

template <typename T>
QList<T> reversed( const QList<T> & in ) {
    QList<T> result;
    std::reverse_copy( in.begin(), in.end(), std::back_inserter( result ) );
    return result;
}
As long as the STL library works on the QList, that's fine. I just don't want to have to use an STL list. I think I tried this before, but I didn't know about the back_inserter so maybe that's what I was doing wrong.
Mark
Yes, all Qt containers are STL `Sequence`s (though they might not meet higher-level concepts, due to missing functionality).
And `QList` has nothing to do with `std::list`. The former is a vector with efficient `push_front()` (a bit like `std::deque` and `std::vector` combined), and funny properties when `sizeof(T)>sizeof(void*)`, the latter is a doubly-linked list (`QLinkedList` in Qt speak). Go figure :/
Yeah... that through me off a bit at first. I was a bit hesitant to use QLists because I figured they'd have poor random access... but that's not really the case :)
Mark
+1  A: 

Reversing a QList is going to be O(n) however you do it, since QList isn't guaranteed to have its data stored contiguously in memory (unlike QVector). You might consider just traversing the list in backwards order where you need to, or use something like a QStack which lets you retrieve the elements in the opposite order they were added.

Colin
Well I wasn't concerned about run-time, just thought a function should already exist so that I didn't have to write my own. Should be `n/2` though I think... not that the `/2` matters in Big-O.
Mark
+2  A: 

You can use the Java style iterator. Complete example here (http://doc.trolltech.com/2.3/collection.html). Look for the word "reverse".

QList<int> list; // initial list

list << 1;
list << 2;
list << 3;

QList<int> rlist; // reverse list+

QListIterator<int> it(list); 
for ( it.toLast(); it.current(); --it) ) {
    rlist << it.current();
}
Xavier Decoret