C++11x Range Based for loops

Here is a first pass at using C++11x range based for loops to over states and arcs in an OpenFst Fst. It also uses type inference (new use of the auto keyword.)

Requires the compiler has the relevant C++11x support, this code was tested using Visual Studio 11 Beta

#include <iostream>

#include <fst/vector-fst.h>

 

using namespace fst;

using namespace std;

 

template<class F>

class StateRange {

 public:

   explicit StateRange(const F& f) : f_(f) { }  

   template<class F>  

   class Iterator {  

    typedef typename F::StateId StateId;

    public:

     explicit Iterator (const F& f) : si_(f) {  }

 

     bool operator != (const Iterator & other) const {       

       return !si_.Done();

     }   

 

     StateId operator* () const {

       return si_.Value();

     }

 

     const Iterator& operator++ () {    

       si_.Next();

       return *this;

     }  

   StateIterator<F> si_;

 };

public:

 Iterator<F> begin() const { return Iterator<F>(f_); }

 Iterator<F> end() const { return Iterator<F>(f_); }

 const F& f_;

};

 

template<class F>

StateRange<F> States(const F& f) {

  return StateRange<F>(f);

}

 

 

template<class F>

class ArcRange {

public:

  typedef typename F::StateId StateId;

  ArcRange(const F& f, StateId s) : f_(f), s_(s) {   }

  template<class F>  

  class Iterator {  

    typedef typename F::Arc Arc;

    typedef typename F::StateId StateId;

  public:

    Iterator (const F& f, StateId s) : ai_(f, s) {  }

    bool operator != (const Iterator & other) const {       

      return !ai_.Done();

    }   

 

    const Arc& operator* () const {

      return ai_.Value();

    }

 

    const Iterator& operator++ () {    

      ai_.Next();

      return *this;

    }  

    ArcIterator<F> ai_;

  };

public:

  Iterator<F> begin() const { return Iterator<F>(f_, s_); }

  Iterator<F> end() const { return Iterator<F>(f_, s_); }

  const F& f_;

  const StateId s_;

};

 

template<class F>

ArcRange<F> Arcs(const F& f, typename F::StateId s) {

  return ArcRange<F>(f, s);

}

 

 

int main() {   

  StdVectorFst fst;

  fst.AddState(); 

  fst.AddState();

  fst.SetStart(0);

  fst.SetFinal(1, TropicalWeight::One());

  fst.AddArc(0, StdArc(0, 0, 0, 1));

  fst.AddArc(0, StdArc(1, 0, 0, 1));

  fst.AddArc(0, StdArc(2, 0, 0, 1));

 

  for (auto s : States(fst))

    for (auto a : Arcs(fst, s))

      printf("%d %d %d %d %f\n", s, a.nextstate, a.ilabel, a.olabel, a.weight.Value());       

}