Go back to Richel Bilderbeek's homepage.

Go back to Richel Bilderbeek's C++ page.

 

 

 

 

 

(C++) Iterator (Design Pattern)

 

The Iterator is a Design Pattern to 'provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation' [1]

 

 

 

 

 

Example: IntVectorIterator

 

 

 

 

 

 

Technical facts

 

Application type(s)

Operating system(s) or programming environment(s)

IDE(s):

Project type:

C++ standard:

Compiler(s):

Libraries used:

 

 

 

 

 

Qt project file: CppDesignPatternIterator.pro

 

#-------------------------------------------------
#
# Project created by QtCreator 2011-06-01T06:16:13
#
#-------------------------------------------------
QT       += core
QT       -= gui
TARGET = CppDesignPatternIterator
CONFIG   += console
CONFIG   -= app_bundle
TEMPLATE = app
SOURCES += main.cpp \
    intvectoriterator.cpp
HEADERS += \
    intvectoriterator.h

 

 

 

 

 

intvectoriterator.cpp

 

//---------------------------------------------------------------------------
#include <cassert>
//---------------------------------------------------------------------------
#include "intvectoriterator.h"
//---------------------------------------------------------------------------
///IntVectorIterator is initialized by ranges
IntVectorIterator::IntVectorIterator(const std::vector<IntRange>& ranges)
  : m_ranges(ranges)
{
  First();
}
//---------------------------------------------------------------------------
///Set the IntVectorIterator back to the first element.
void IntVectorIterator::First()
{
  m_current_range = m_ranges.begin();
  m_current_int = m_current_range->first;
}
//---------------------------------------------------------------------------
///Go to the next element.
void IntVectorIterator::Next()
{
  assert(!IsDone());

  ++m_current_int;
  if (m_current_int == m_current_range->second)
  {
    ++m_current_range;
    if (m_current_range != m_ranges.end())
    {
      m_current_int = m_current_range->first;
    }
  }
}
//---------------------------------------------------------------------------
///Check if there are still elements left to iterator over.
bool IntVectorIterator::IsDone() const
{
  return m_current_range == m_ranges.end();
}
//---------------------------------------------------------------------------
///Get the current item
std::vector<int>::iterator IntVectorIterator::CurrentItem() const
{
  return m_current_int;
}
//---------------------------------------------------------------------------

 

 

 

 

 

intvectoriterator.h

 

#ifndef INTVECTORITERATOR_H
#define INTVECTORITERATOR_H
//---------------------------------------------------------------------------
#include <vector>
//---------------------------------------------------------------------------
///IntVectorIterator iterates over multiple std::vector<int>s
///
///\note
///This Iterator Design Pattern is very limited in usability,
///as it can only iterate over std::vector<int>s.
//From http://www.richelbilderbeek.nl/CppDesignPatternIterator.htm
struct IntVectorIterator
{
  ///Define an IntRange as a std::pair containing the begin and end of a std::vector.
  typedef std::pair<std::vector<int>::iterator,std::vector<int>::iterator> IntRange;

  ///IntVectorIterator is initialized by ranges
  IntVectorIterator(const std::vector<IntRange>& ranges);

  ///Set the IntVectorIterator back to the first element.
  void First();

  ///Go to the next element.
  void Next();

  ///Check if there are still elements left to iterator over.
  bool IsDone() const;

  ///Get the current item
  std::vector<int>::iterator CurrentItem() const;

  private:

  ///The ranges iterated over
  std::vector<IntRange> m_ranges;

  ///The current range iterating over
  std::vector<IntRange>::iterator m_current_range;

  ///The current position in the current range
  std::vector<int>::iterator m_current_int;
};
//---------------------------------------------------------------------------
#endif // INTVECTORITERATOR_H

 

 

 

 

 

main.cpp

 

#include <iostream>
#include "intvectoriterator.h"

int main()
{
  ///Create the std::vectors
  std::vector<int> v1;
  std::vector<int> v2;
  std::vector<int> v3;
  v1.push_back(1);
  v1.push_back(2);
  v1.push_back(3);
  v2.push_back(4);
  v2.push_back(5);
  v2.push_back(6);
  v3.push_back(7);
  v3.push_back(8);
  v3.push_back(9);

  ///Create the ranges
  std::vector<std::pair<std::vector<int>::iterator,std::vector<int>::iterator> > ranges;
  ranges.push_back(std::make_pair(v1.begin(),v1.end()));
  ranges.push_back(std::make_pair(v2.begin(),v2.end()));
  ranges.push_back(std::make_pair(v3.begin(),v3.end()));

  ///Create the IntVectorIterator
  IntVectorIterator i(ranges);

  ///Iterator through the std::vectors
  while (!i.IsDone())
  {
    std::cout << *i.CurrentItem() << '\n';
    i.Next();
  }
}

 

 

 

 

 

References

 

  1. Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides. Design Patterns. 1995. ISBN: 0201633612.

 

 

 

 

 

Go back to Richel Bilderbeek's C++ page.

Go back to Richel Bilderbeek's homepage.

 

Valid XHTML 1.0 Strict