Abdelrazak Younes <[EMAIL PROTECTED]> writes:

| #ifndef IT_VECTOR_H
| #define IT_VECTOR_H
| 
| #include <vector>
| #include <algorithm>
| 
| #include "debug.h"

Please change order of includes. The rule is: most specific first,
most general last.

| /// vector of container iterator.
| /**
| This templatized class provide a std::vector like interface but with another 
Container
| underneath. An important property is that it keeps the Container iterator 
interface.
| A typical use would be:
| 
|       typedef it_vector<std::list<some_class> > MyContainer;

I am not sure this is the best interface...

I think I would prefere:

        typedef it_vector<some_class> MyContainer;

 
| template <class Container>
| class it_vector

Thus:

  template <class ValueType, class Container = std::list>
  class it_vector

| {
| protected:
|       typedef typename Container::const_iterator base_cit;
|       typedef typename Container::iterator base_it;
|       
| public:
| 
|       typedef typename Container::value_type value_type;
|       typedef typename Container::difference_type difference_type;
|       typedef size_t size_type;
| 
|       ///     
|       class iterator: public Container::iterator
|       {
|       public:
|               iterator() {
|               }
|               iterator(base_it  const & it) {

You have a coule of places with double-spaces.

|                       Container::iterator::operator=(it);
|               }
|               inline iterator & operator+= (difference_type pos) {

Please no space before the paren in a function name.
(yes, for operators as well)

And please drop the inline keyword on in-class methods, they are
implicit anyway.

|                       std::advance(*this, pos);
|                       return *this;
|               }
|               inline iterator operator+ (difference_type pos) const {
|                       iterator it=*this;
|                       std::advance(it, pos);
|                       return it;
|               }
|               inline difference_type operator- (iterator it2) const {
|                       return std::distance(*this, it2);
|               }

I agree with the criticism against these functions. They should both
do the same thing: move iterators forward and backwards.

|               inline const iterator & operator= (base_it  const & it) {
|                       Container::const_iterator::operator=(it);
|                       return *this;
|               }

This looks wrong... a bit... 

I think the iterator class should be built from ground up, and not
inherit from the Container::iterator. With several operations you miss
the faster iterator operations a the vector can give.

(You have the vector, and can thus get O(1) operator+, but not if you
use the list::iterator.)

|       ///
|       it_vector()     {

Way too many spaces.

|       }
| 
|       /// Construct a new it_vector by copying externalItVector.

You don't really have to comment this :-)
We do know what a copy constructor is.

|       it_vector(it_vector const & externalItVector) {
|               for (const_iterator it = externalItVector.begin(); it != 
externalItVector.end(); ++it)
|                       push_back(*it);
|       }

|       /// Construct a new it_vector by copying externalItVector from start to 
end.
|       it_vector(it_vector const & externalItVector, size_t start, size_t end) 
{
|               for (size_t i = start; i != end; ++i)
|                       push_back(externalItVector[i]);
|       }

(pos, length)
 
|       /// Construct a new it_vector by copying elements pointed from it_start 
to it_end.
|       it_vector(const_iterator it_start, const_iterator it_end) {
|               for (const_iterator it = it_start; it != it_end; ++it)
|                       push_back(*it);
|       }

Template.

| 
|       /// Copy externalItVector.
|       inline void copy(it_vector const & externalItVector) {
|               copy(externalItVector, 0, externalItVector.size()); 
|       }
| 
|       /// Copy externalItVector from it_start to it_end.
|       void copy(const_iterator it_start, const_iterator it_end) {
|               clear();
|               for (const_iterator it = it_start; it != it_end; ++it)
|                       push_back(*it);
|       }

Copy is the wrong name for this. In the other containers this is
called 'assign'.

And if you make the ones taking iterators a template instead, you only
need one to cover both const and non-const iterators.
(and will be able to assign form other containes than it_vector)

|       /// Copy externalItVector from start to end.
|       void copy(it_vector const & externalItVector, size_t start,
|       size_t end) {

Other containers use "pos, length" don't they?

|       inline value_type & at(size_t pos) {
|               if (pos >= ItVector_.size()) {
|                       lyxerr[Debug::ACTION] << "trying to access element " << 
pos << " while size is "<< size() << endl;
|                       return *ItVector_[size()-1];
|               }
|               BOOST_ASSERT(pos < ItVector_.size());
|               return *ItVector_[pos];
|       }
| 
|       inline value_type const & at(size_t pos) const {
|               if (pos >= ItVector_.size()) {
|                       lyxerr[Debug::ACTION] << "trying to access element " << 
pos << " while size is "<< size() << endl;
|                       return *ItVector_[size()-1];
|               }
|               BOOST_ASSERT(pos < ItVector_.size());
|               return *ItVector_[pos];
|       }

Do we really need these checked functions? Won't the gcc debug lib do
this for us? (and where is operator[]?)

|       /// Erases the paragraphs from start to end.
|       /**
|       \todo This could be optimized...
|       */
|       bool erase(size_t start, size_t end) {
|               bool result=true;
|               for (size_t i = start; i != end; ++i)
|                       result = result && erase(i);
|               
|               return result;
|       }               

Hmm... (pos, length)?


Ok, got tired.
Will do more later.

I think you should think of ItVector as just and implemention detail,
and keep it away from naming. Also and invalidation and rebuilding
from ground up of ItVector, but in some cases be a better option that
having the two containers walk in step.

F.ex. the operation of inserting a list into the container is now a
2 x O(n) operation. At least with list and splice it should be
possible to have this as O(1) + O(n).

I also think that it_vector really should be a RandomAccessList, tuned
for only working with std::list as the main container and std::vector
as its 'iterator cache'

-- 
        Lgb

Reply via email to