Indexed set: reverse

I tried indexed_set with g++ 3.2.3 ("gcc version 3.2 20020903 (Red Hat Linux 8.0 3.2-7)") and it compiled all the examples. The reference docs need an "up" link (back to libs/indexed_set/doc/index.html). Your tutorial did not deal with using an index in reversed order; I think it is worth adding something showing using rbegin()/rend() (I modified basic.cpp to print ages oldest first and it worked first time :-). I found a reverse() function in sequenced.cpp: it seems you apply this to the indexed_set container, not to the index, but when I tried it on the container in basic.cpp I get a compile error. So I tried the sequenced example using rbegin/rend and it worked: tc.reverse(); std::copy(tc.begin(),tc.end(), std::ostream_iterator<std::string>(std::cout," ")); tc.reverse(); /* undo */ std::copy(tc.rbegin(),tc.rend(), std::ostream_iterator<std::string>(std::cout," ")); Can you explain the thinking behind reverse()? Is it any more/less efficient than using rbegin/rend? If not, I think it should either be dropped or extended to regular indices as well. Darren Joaquín Mª López Muñoz wrote:

Hi Darren, Darren Cook ha escrito:
I tried indexed_set with g++ 3.2.3 ("gcc version 3.2 20020903 (Red Hat Linux 8.0 3.2-7)") and it compiled all the examples.
Good! Thanx for trying it.
The reference docs need an "up" link (back to libs/indexed_set/doc/index.html).
Yep, why not. I'll try to add such a link if I have time (review starts 20 and I'll polishing the last details on the docs.)
I've added nothing about rbegin/rend cause they are entirely equivalent to their analogues in STL containers.
reverse is not a member function of indexed_set, but rather of sequenced indices. The line: tc.reverse(); works because the indexed_set inherits the public interface of its first index. So this is but an abbreviation of: tc.get<0>().reverse(); (This particular point of indexed_set inheriting index #0 interface has originated some perplexities in other readers.) Now, reverse is a memfun of sequenced indices for the simple reason that it is also present in std::list (and sequenced indices mimic its interface as closely as possible.) As std::sets do not have a reverse operation, neither do regular indices (furthermore, this op does not make sense for such indices.) So, your options for reverse traversal are: * Regular indices: use rbegin/rend * Sequenced indices: rbegin/rend *or* reverse followed by begin/end. reverse does only affect the sequenced index, it does not alter other indices in any manner. rbegin/rend is more efficient (no modifications to the index required.) Please note that there's nothing new about all this: the options described are exactly the same you have at your disposal when working with std::sets (in the case of regular indices) and std::lists (in the case of sequenced indices.) Does this solve your doubts? If not, please tell me so. Shortly before review (in a couple of days maximum) I'll upload the final version of the docs, which hopefully will shed more light on the different types of indices available. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

That is clever, but the potential for confusion far outweighs any benefit (IMHO). Do you have any strong supporters for the idea?
I think the function makes sense: I can call reverse on the index then call some complex function that uses begin/end, to save having to write a rbegin/rend version. E.g. to process a list from oldest to youngest instead of youngest to oldest. I also think the interface for regular and sequenced indices should be as close as possible, as I'm sure I'm going to want to write generic functions that take either type. Darren

Darren Cook ha escrito:
Not really, apart from me :) The idea is that the first index can be thought of as the *primary* index in some sense. So, the following indexed_set< int, index_list< unique<identity<int> >, sequenced<>
can be treated as a std::set with an aditional sequenced index, while indexed_set< int, index_list< sequenced<>, unique<identity<int> >
puts greater emphasis on the sequenced index, and its "default" interface is that of a std::list.
But you cannot have such a thing as a reverse op for regular indices. Think of std::sets: a reverse() memfun would alter the basic invariant of the set, namely that the elements are arranged in a definite order imposed by the comparison predicate. The same happens with regular indices. The complex function you talk about can be made more generic if it is templatized according to the iterator type, so that it accepts rbegin/rend as well as begin/end --admittedly, this might not be sufficient in some cases.
Ummm... the common subset of operations between regular and sequenced indices is currently: * operator=,get_allocator,empty,size,max_size, * (r)begin/(r)end, * erase,update,modify,clear,swap, The main differences are with respect to insertion, where semantics are very dissimilar (regular indices do have a definite ordering, not so sequenced indices.) Gotta think of it, maybe I can add the following to sequenced indices: insert(const value_type& x); insert(InputIterator first,InputIterator last); with the implied assumption that insertion takes place at the end of the index. This would provide of fair amount of interface commonality between regular and sequenced indices. Comments? Joaquín M López Muñoz Telefónica, Investigación y Desarrollo
participants (2)
-
Darren Cook
-
Joaquín Mª López Muñoz