Boost logo

Boost :

From: jsiek_at_[hidden]
Date: 1999-11-26 18:58:13


I've attached my implementation of the iterator ops idea. It uses
friend functions for almost all the operators (including postfix
inc/dec), and uses static casts for the two member functions, op-> and
op[]).

I've compiled with g++ and it should work with SGI CC as well.

I've also attached a short test program.

Cheers,

Jeremy


// (C) Copyright Jeremy Siek 1999. Permission to copy, use, modify,
// sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.

template <class DerivedClass>
struct postfix_inc_operator
{
  friend DerivedClass operator++(DerivedClass& x, int)
  {
    DerivedClass tmp(x);
    ++x;
    return tmp;
  }
};
  

template <class DerivedClass>
struct postfix_dec_operator
{
  friend DerivedClass operator--(DerivedClass& x, int)
  {
    DerivedClass tmp(x);
    --x;
    return tmp;
  }
};

template <class DerivedClass>
struct member_operator
{
  typedef typename std::iterator_traits<DerivedClass>::value_type value_type;
  value_type* operator->() const {
    return &*static_cast<const DerivedClass&>(*this);
  }
};

template <class DerivedClass>
class random_access_operators
{
  typedef typename std::iterator_traits<DerivedClass>::reference Ref;
  typedef typename std::iterator_traits<DerivedClass>::difference_type
    Distance;
public:
  friend DerivedClass operator+(const DerivedClass& x, Distance n)
  {
    DerivedClass tmp = x;
    tmp += n;
    return tmp;
  }

  friend DerivedClass operator+(Distance n, const DerivedClass& x)
  {
    return x + n;
  }

  friend DerivedClass operator-(const DerivedClass& x, Distance n)
  {
    DerivedClass tmp = x;
    tmp -= n;
    return tmp;
  }

  friend DerivedClass operator-(Distance n, const DerivedClass& x)
  {
    return x - n;
  }

  Ref operator[](Distance n) const {
    return *(static_cast<const DerivedClass&>(*this) + n);
  }
};

template <class DerivedClass>
struct foward_iterator_helper :
  public postfix_inc_operator<DerivedClass>,
  public member_operator<DerivedClass> { };

template <class DerivedClass>
struct bidirectional_iterator_helper :
  public postfix_inc_operator<DerivedClass>,
  public postfix_dec_operator<DerivedClass>,
  public member_operator<DerivedClass> { };

template <class DerivedClass>
struct random_access_iterator_helper :
  public postfix_inc_operator<DerivedClass>,
  public postfix_dec_operator<DerivedClass>,
  public member_operator<DerivedClass>,
  public random_access_operators<DerivedClass> { };


// (C) Copyright Jeremy Siek 1999. Permission to copy, use, modify,
// sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.

#include <string>
#include <iostream>
#include <iterator>
#include <boost/array.hpp>
#include <iterator_ops.h>

using namespace std;
using namespace boost;

template <class T>
struct test_iter;

namespace std {
template <class T>
struct iterator_traits< test_iter<T> > {
  typedef bidirectional_iterator_tag iterator_category;
  typedef T& reference;
  typedef T value_type;
  typedef int difference_type;
};
}

template <class T>
struct test_iter : public random_access_iterator_helper< test_iter<T> > {
  typedef test_iter self;
  typedef std::iterator_traits<self>::reference Ref;
  typedef std::iterator_traits<self>::difference_type Dist;
public:
  test_iter(T* i) : _i(i) { }
  test_iter(const self& x) : _i(x._i) { }
  self& operator=(const self& x) { _i = x._i; return *this; }
  Ref operator*() const { return *_i; }
  self& operator++() { ++_i; return *this; }
  self& operator--() { --_i; return *this; }
  self& operator+=(Dist n) { _i += n; return *this; }
  self& operator-=(Dist n) { _i -= n; return *this; }
  friend bool operator==(const self& x, const self& y) { return x._i == y._i; }
  friend bool operator<(const self& x, const self& y) { return x._i < y._i; }
protected:
  T* _i;
};

int
main()
{
  string array[] = { "apple", "orange", "pear", "peach", "grape", "plum" };
  test_iter<string> i = begin(array), ie = end(array);

  // test i++
  while (i != ie)
    cout << *i++ << " ";
  cout << endl;
  i = begin(array);

  // test i--
  while (ie != i) {
    ie--;
    cout << *ie << " ";
  }
  cout << endl;
  ie = end(array);

  // test i->m
  while (i != ie) {
    cout << i->size() << " ";
    ++i;
  }
  cout << endl;
  i = begin(array);

  // test i + n
  while (i < ie) {
    cout << *i << " ";
    i = i + 2;
  }
  cout << endl;
  i = begin(array);

  // test n + i
  while (i < ie) {
    cout << *i << " ";
    i = 2 + i;
  }
  cout << endl;

  i = begin(array);

  // test i - n
  while (ie > i) {
    ie = ie - 2;
    cout << *ie << " ";
  }
  cout << endl;

  ie = end(array);

  // test n - i
  while (ie > i) {
    ie = 2 - ie;
    cout << *ie << " ";
  }
  cout << endl;

  for (int j = 0; j < size(array) ; ++j)
    cout << i[j] << " ";
  cout << endl;

  return 0;
}


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk