// -*- c++ -*-
#ifndef FOR_EACH_MACROS_H
#define FOR_EACH_MACROS_H

namespace hugo {

#define FOR_EACH_GLOB(e, g) for((g).first((e)); (g).valid((e)); (g).next((e)))
#define FOR_EACH_INC_GLOB(e, g, v) for((g).first((e), (v)); (g).valid((e)); (g).next((e)))

#define FOR_EACH_EDGE_GLOB(e, g) for((g).first((e)); (g).valid((e)); (g).next((e)))
#define FOR_EACH_NODE_GLOB(e, g) for((g).first((e)); (g).valid((e)); (g).next((e)))
#define FOR_EACH_INEDGE_GLOB(e, g, v) for((g).first((e), (v)); (g).valid((e)); (g).next((e)))
#define FOR_EACH_OUTEDGE_GLOB(e, g, v) for((g).first((e), (v)); (g).valid((e)); (g).next((e)))

//   template<typename It, typename Graph> 
//   It loopFirst(const Graph& g) const {
//     It e; g.first(e); return e; 
//   }

//   template<typename It, typename Graph> 
//   It loopFirst(const Graph& g, const Node& v) const {
//     It e; g.first(e, v); return e; 
//   }

//   template<typename Graph> 
//   typename Graph::NodeIt loopFirstNode(const Graph& g) const {
//     typename Graph::NodeIt e; g.first(e); return e; 
//   }
//   template<typename Graph> 
//   typename Graph::EdgeIt loopFirstEdge(const Graph& g) const {
//     typename Graph::EdgeIt e; g.first(e); return e; 
//   }
//   template<typename Graph> 
//   typename Graph::OutEdgeIt 
//   loopFirstOutEdge(const Graph& g, const Node& n) const {
//     typename Graph::OutEdgeIt e; g.first(e, n); return e; 
//   }
//   template<typename Graph> 
//   typename Graph::InEdgeIt 
//   loopFirstIn Edge(const Graph& g, const Node& n) const {
//     typename Graph::InEdgeIt e; g.first(e, n); return e; 
//   }

//FIXME ezt hogy a gorcsbe birja levezetni. Csak ugy leveszi a const-ot??
  template<typename It, typename Graph> 
  It loopFirst(const It&, const Graph& g) {
    It e; g.first(e); return e; 
  }

  template<typename It, typename Graph, typename Node> 
  It loopFirst(const It&, const Graph& g, const Node& v) {
    It e; g.first(e, v); return e; 
  }

//   template<typename Graph> 
//   typename Graph::NodeIt loopFirstNode(const Graph& g) const {
//     typename Graph::NodeIt e; g.first(e); return e; 
//   }
//   template<typename Graph> 
//   typename Graph::EdgeIt loopFirstEdge(const Graph& g) const {
//     typename Graph::EdgeIt e; g.first(e); return e; 
//   }
//   template<typename Graph> 
//   typename Graph::OutEdgeIt 
//   loopFirstOutEdge(const Graph& g, const Node& n) const {
//     typename Graph::OutEdgeIt e; g.first(e, n); return e; 
//   }
//   template<typename Graph> 
//   typename Graph::InEdgeIt 
//   loopFirstIn Edge(const Graph& g, const Node& n) const {
//     typename Graph::InEdgeIt e; g.first(e, n); return e; 
//   }

#define FOR_EACH_LOC(Ittype, e, g) for(Ittype e=loopFirst(Ittype(), (g)); (g).valid(e); (g).next(e))
#define FOR_EACH_INC_LOC(Ittype, e, g, v) for(Ittype e=loopFirst(Ittype(), (g), (v)); (g).valid(e); (g).next(e))

// #define FOR_EACH_EDGE_LOC(e, g) ezt nem tom hogy kell for((g).first((e)); (g).valid((e)); (g).next((e)))
// #define FOR_EACH_NODE_LOC(e, g) for((g).first((e)); (g).valid((e)); (g).next((e)))
// #define FOR_EACH_INEDGE_LOC(e, g, v) for((g).first((e), (v)); (g).valid((e)); (g).next((e)))
// #define FOR_EACH_OUTEDGE_LOC(e, g, v) for((g).first((e), (v)); (g).valid((e)); (g).next((e)))


} //namespace hugo

#endif //FOR_EACH_MACROS_H
