This is the mail archive of the libstdc++@sourceware.cygnus.com mailing list for the libstdc++ project. See the libstdc++ home page for more information.


[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index] [Subject Index] [Author Index] [Thread Index]

Re: Iterator class for vector and basic_string



Thanks for the comments.

Below the rewritten version.
I used a third class `iterator_base' as base class for `iterator'
and `const_iterator'.
Now we can use `iterator_base' (and the comparision operators)
as the base for vector::iterator and basic_string::iterator.

Ryszard Kabatek
--
Martin-Luther University Halle-Wittenberg
Department of Physical Chemistry
Geusaer Str. 88, 06217 Merseburg, Germany  
Tel. +49 3461 46 2487 Fax. +49 3461 46 2129

/***********************************************************************/

template<typename _Tp, typename _Dist, typename _Ptr, typename _Ref>
class iterator_base;

template<typename _Tp, typename _Dist, typename _Ptr, typename _Ref>
bool
operator==(iterator_base<_Tp, _Dist, _Ptr, _Ref>,
           iterator_base<_Tp, _Dist, _Ptr, _Ref>);

template<typename _Tp, typename _Dist, typename _Ptr, typename _Ref>
bool
operator!=(iterator_base<_Tp, _Dist, _Ptr, _Ref>,
           iterator_base<_Tp, _Dist, _Ptr, _Ref>);

template<typename _Tp, typename _Dist, typename _Ptr, typename _Ref>
bool
operator<(iterator_base<_Tp, _Dist, _Ptr, _Ref>,
          iterator_base<_Tp, _Dist, _Ptr, _Ref>);

template<typename _Tp, typename _Dist, typename _Ptr, typename _Ref>
bool
operator>(iterator_base<_Tp, _Dist, _Ptr, _Ref>,
          iterator_base<_Tp, _Dist, _Ptr, _Ref>);

template<typename _Tp, typename _Dist, typename _Ptr, typename _Ref>
bool
operator<=(iterator_base<_Tp, _Dist, _Ptr, _Ref>,
           iterator_base<_Tp, _Dist, _Ptr, _Ref>);

template<typename _Tp, typename _Dist, typename _Ptr, typename _Ref>
bool
operator>=(iterator_base<_Tp, _Dist, _Ptr, _Ref>,
           iterator_base<_Tp, _Dist, _Ptr, _Ref>);



template<typename _Tp, typename _Dist = ptrdiff_t,
         typename _Ptr = _Tp*, typename _Ref = _Tp&>
class iterator_base : public iterator<random_access_iterator_tag, 
                                      _Tp, _Dist, _Ptr, _Ref> {
    friend bool operator==<>(iterator_base, iterator_base);
    friend bool operator!=<>(iterator_base, iterator_base);
    friend bool operator< <>(iterator_base, iterator_base);
    friend bool operator> <>(iterator_base, iterator_base);
    friend bool operator<=<>(iterator_base, iterator_base);
    friend bool operator>=<>(iterator_base, iterator_base);

  public:
    typedef const _Ptr const_pointer;
    typedef const _Ref const_reference;

  protected:
    explicit iterator_base(pointer __p = 0);

  protected:
    pointer _M_data;
};

template<typename _Tp, typename _Dist = ptrdiff_t,
         typename _Ptr = _Tp*, typename _Ref = _Tp&>
class iterator : public iterator_base<_Tp, _Dist, _Ptr, _Ref> {
  private:
    explicit iterator(pointer __p);

  public:
    iterator();

    reference operator*() const;

    pointer   operator->() const;

    iterator& operator++();

    iterator  operator++(int);

    iterator& operator--();

    iterator  operator--(int);

    iterator& operator+=(difference_type __n);

    iterator& operator-=(difference_type __n);

    reference operator[](difference_type __pos) const;
};


template<typename _Tp, typename _Dist = ptrdiff_t,
         typename _Ptr = _Tp*, typename _Ref = _Tp&>
class const_iterator : public iterator_base<_Tp, _Dist, _Ptr, _Ref> {
  private:
    explicit const_iterator(pointer __p);

  public:
    const_iterator();

    const_iterator(const iterator<_Tp, _Dist, _Ptr, _Ref>& __rhs);

    const_reference operator*() const;

    const_pointer   operator->() const;

    const_iterator& operator++();

    const_iterator  operator++(int);

    const_iterator& operator--();

    const_iterator  operator--(int);

    const_iterator& operator+=(difference_type __n);

    const_iterator& operator-=(difference_type __n);

    const_reference operator[](difference_type __pos) const;
};



///////////////////
// inline functions
///////////////////

// iterator_base
template<typename _Tp, typename _Dist, typename _Ptr, typename _Ref>
inline
iterator_base<_Tp, _Dist, _Ptr, _Ref>::iterator_base(pointer __p) 
: _M_data(__p) 
{
}

// const_iterator
template<typename _Tp, typename _Dist, typename _Ptr, typename _Ref>
inline
iterator<_Tp, _Dist, _Ptr, _Ref>::iterator(pointer __p) 
: iterator_base(__p) 
{
}

template<typename _Tp, typename _Dist, typename _Ptr, typename _Ref>
inline
iterator<_Tp, _Dist, _Ptr, _Ref>::iterator()
{
}

template<typename _Tp, typename _Dist, typename _Ptr, typename _Ref>
inline typename iterator<_Tp, _Dist, _Ptr, _Ref>::reference
iterator<_Tp, _Dist, _Ptr, _Ref>::operator*() const 
{
  return *_M_data;
}

template<typename _Tp, typename _Dist, typename _Ptr, typename _Ref>
inline typename iterator<_Tp, _Dist, _Ptr, _Ref>::pointer
iterator<_Tp, _Dist, _Ptr, _Ref>::operator->() const 
{
  return _M_data;
}

template<typename _Tp, typename _Dist, typename _Ptr, typename _Ref>
inline iterator<_Tp, _Dist, _Ptr, _Ref>&
iterator<_Tp, _Dist, _Ptr, _Ref>::operator++() 
{
  ++_M_data; 
  return *this;
}

template<typename _Tp, typename _Dist, typename _Ptr, typename _Ref>
inline iterator<_Tp, _Dist, _Ptr, _Ref>
iterator<_Tp, _Dist, _Ptr, _Ref>::operator++(int) 
{
  return iterator(_M_data++);
}

template<typename _Tp, typename _Dist, typename _Ptr, typename _Ref>
inline iterator<_Tp, _Dist, _Ptr, _Ref>&
iterator<_Tp, _Dist, _Ptr, _Ref>::operator--() 
{
  --_M_data; 
  return *this;
}

template<typename _Tp, typename _Dist, typename _Ptr, typename _Ref>
inline iterator<_Tp, _Dist, _Ptr, _Ref>
iterator<_Tp, _Dist, _Ptr, _Ref>::operator--(int) 
{
  return iterator(_M_data--);
}

template<typename _Tp, typename _Dist, typename _Ptr, typename _Ref>
inline iterator<_Tp, _Dist, _Ptr, _Ref>&
iterator<_Tp, _Dist, _Ptr, _Ref>::operator+=(difference_type __n) 
{
  _M_data += __n; 
  return *this;
}

template<typename _Tp, typename _Dist, typename _Ptr, typename _Ref>
inline iterator<_Tp, _Dist, _Ptr, _Ref>&
iterator<_Tp, _Dist, _Ptr, _Ref>::operator-=(difference_type __n) 
{
  _M_data -= __n; 
  return *this;
}

template<typename _Tp, typename _Dist, typename _Ptr, typename _Ref>
inline iterator<_Tp, _Dist, _Ptr, _Ref>::reference
iterator<_Tp, _Dist, _Ptr, _Ref>::operator[](difference_type __pos) const 
{
  return *(_M_data + __pos);
}

// const_iterator
template<typename _Tp, typename _Dist, typename _Ptr, typename _Ref>
inline
const_iterator<_Tp, _Dist, _Ptr, _Ref>::const_iterator(pointer __p) 
: iterator_base(__p) 
{
}

template<typename _Tp, typename _Dist, typename _Ptr, typename _Ref>
inline
const_iterator<_Tp, _Dist, _Ptr, _Ref>::const_iterator()
{
}

template<typename _Tp, typename _Dist, typename _Ptr, typename _Ref>
inline
const_iterator<_Tp, _Dist, _Ptr, _Ref>::
const_iterator(const iterator<_Tp, _Dist, _Ptr, _Ref>& __rhs) 
: iterator_base(__rhs) 
{
}

template<typename _Tp, typename _Dist, typename _Ptr, typename _Ref>
inline typename const_iterator<_Tp, _Dist, _Ptr, _Ref>::const_reference
const_iterator<_Tp, _Dist, _Ptr, _Ref>::operator*() const 
{
  return *_M_data;
}

template<typename _Tp, typename _Dist, typename _Ptr, typename _Ref>
inline typename const_iterator<_Tp, _Dist, _Ptr, _Ref>::const_pointer
const_iterator<_Tp, _Dist, _Ptr, _Ref>::operator->() const 
{
  return _M_data;
}

template<typename _Tp, typename _Dist, typename _Ptr, typename _Ref>
inline const_iterator<_Tp, _Dist, _Ptr, _Ref>&
const_iterator<_Tp, _Dist, _Ptr, _Ref>::operator++() 
{
  ++_M_data; 
  return *this;
}

template<typename _Tp, typename _Dist, typename _Ptr, typename _Ref>
inline const_iterator<_Tp, _Dist, _Ptr, _Ref>
const_iterator<_Tp, _Dist, _Ptr, _Ref>::operator++(int) 
{
  return const_iterator(_M_data++);
}

template<typename _Tp, typename _Dist, typename _Ptr, typename _Ref>
inline const_iterator<_Tp, _Dist, _Ptr, _Ref>&
const_iterator<_Tp, _Dist, _Ptr, _Ref>::operator--() 
{
  --_M_data; 
  return *this;
}

template<typename _Tp, typename _Dist, typename _Ptr, typename _Ref>
inline const_iterator<_Tp, _Dist, _Ptr, _Ref>
const_iterator<_Tp, _Dist, _Ptr, _Ref>::operator--(int) 
{
  return const_iterator(_M_data--);
}

template<typename _Tp, typename _Dist, typename _Ptr, typename _Ref>
inline const_iterator<_Tp, _Dist, _Ptr, _Ref>&
const_iterator<_Tp, _Dist, _Ptr, _Ref>::operator+=(difference_type __n) 
{
  _M_data += __n; 
  return *this;
}

template<typename _Tp, typename _Dist, typename _Ptr, typename _Ref>
inline const_iterator<_Tp, _Dist, _Ptr, _Ref>&
const_iterator<_Tp, _Dist, _Ptr, _Ref>::operator-=(difference_type __n) 
{
  _M_data -= __n; 
  return *this;
}

template<typename _Tp, typename _Dist, typename _Ptr, typename _Ref>
inline const_iterator<_Tp, _Dist, _Ptr, _Ref>::const_reference
const_iterator<_Tp, _Dist, _Ptr, _Ref>::operator[](difference_type __pos)
const 
{
  return *(_M_data + __pos);
}

// non-member functions
template<typename _Tp, typename _Dist, typename _Ptr, typename _Ref>
inline typename iterator_base<_Tp, _Dist, _Ptr, _Ref>::difference_type
operator-(iterator_base<_Tp, _Dist, _Ptr, _Ref&> __lhs,
          iterator_base<_Tp, _Dist, _Ptr, _Ref&> __rhs)
{
  return __lhs._M_data - __rhs._M_data;
}

template<typename _Tp, typename _Dist, typename _Ptr, typename _Ref>
inline iterator<_Tp, _Dist, _Ptr, _Ref>
operator+(iterator<_Tp, _Dist, _Ptr, _Ref> __iter, _Dist __n)
{
  return __iter += __n;
}

template<typename _Tp, typename _Dist, typename _Ptr, typename _Ref>
inline iterator<_Tp, _Dist, _Ptr, _Ref>
operator+(_Dist __n, iterator<_Tp, _Dist, _Ptr, _Ref> __iter)
{
  return __iter += __n;
}

template<typename _Tp, typename _Dist, typename _Ptr, typename _Ref>
inline const_iterator<_Tp, _Dist, _Ptr, _Ref>
operator+(const_iterator<_Tp, _Dist, _Ptr, _Ref> __iter, _Dist __n)
{
  return __iter += __n;
}

template<typename _Tp, typename _Dist, typename _Ptr, typename _Ref>
inline const_iterator<_Tp, _Dist, _Ptr, _Ref>
operator+(_Dist __n, const_iterator<_Tp, _Dist, _Ptr, _Ref> __iter)
{
  return __iter += __n;
}

template<typename _Tp, typename _Dist, typename _Ptr, typename _Ref>
inline iterator<_Tp, _Dist, _Ptr, _Ref>
operator-(iterator<_Tp, _Dist, _Ptr, _Ref> __iter, _Dist __n)
{
  return __iter -= __n;
}

template<typename _Tp, typename _Dist, typename _Ptr, typename _Ref>
inline iterator<_Tp, _Dist, _Ptr, _Ref>
operator-(_Dist __n, iterator<_Tp, _Dist, _Ptr, _Ref> __iter)
{
  return __iter -= __n;
}

template<typename _Tp, typename _Dist, typename _Ptr, typename _Ref>
inline const_iterator<_Tp, _Dist, _Ptr, _Ref>
operator-(const_iterator<_Tp, _Dist, _Ptr, _Ref> __iter, _Dist __n)
{
  return __iter -= __n;
}

template<typename _Tp, typename _Dist, typename _Ptr, typename _Ref>
inline const_iterator<_Tp, _Dist, _Ptr, _Ref>
operator-(_Dist __n, const_iterator<_Tp, _Dist, _Ptr, _Ref> __iter)
{
  return __iter -= __n;
}


template<typename _Tp, typename _Dist, typename _Ptr, typename _Ref>
inline bool
operator==(iterator_base<_Tp, _Dist, _Ptr, _Ref> __lhs,
           iterator_base<_Tp, _Dist, _Ptr, _Ref> __rhs)
{
  return __lhs._M_data == __rhs._M_data;
}

template<typename _Tp, typename _Dist, typename _Ptr, typename _Ref>
inline bool
operator!=(iterator_base<_Tp, _Dist, _Ptr, _Ref> __lhs,
           iterator_base<_Tp, _Dist, _Ptr, _Ref> __rhs)
{
  return __lhs._M_data != __rhs._M_data;
}

template<typename _Tp, typename _Dist, typename _Ptr, typename _Ref>
inline bool
operator<(iterator_base<_Tp, _Dist, _Ptr, _Ref> __lhs,
          iterator_base<_Tp, _Dist, _Ptr, _Ref> __rhs)
{
  return __lhs._M_data < __rhs._M_data;
}

template<typename _Tp, typename _Dist, typename _Ptr, typename _Ref>
inline bool
operator>(iterator_base<_Tp, _Dist, _Ptr, _Ref> __lhs,
          iterator_base<_Tp, _Dist, _Ptr, _Ref> __rhs)
{
  return __lhs._M_data > __rhs._M_data;
}

template<typename _Tp, typename _Dist, typename _Ptr, typename _Ref>
inline bool
operator<=(iterator_base<_Tp, _Dist, _Ptr, _Ref> __lhs,
           iterator_base<_Tp, _Dist, _Ptr, _Ref> __rhs)
{
  return __lhs._M_data <= __rhs._M_data;
}

template<typename _Tp, typename _Dist, typename _Ptr, typename _Ref>
inline bool
operator>=(iterator_base<_Tp, _Dist, _Ptr, _Ref> __lhs,
           iterator_base<_Tp, _Dist, _Ptr, _Ref> __rhs)
{
  return __lhs._M_data >= __rhs._M_data;
}

/***********************************************************************/