1 //=======================================================================
2 // Copyright 2001 Indiana University
3 // Author: Jeremy G. Siek
4 //
5 // Distributed under the Boost Software License, Version 1.0. (See
6 // accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt)
8 //=======================================================================
9 
10 #ifndef BOOST_GRAPH_ITERATION_MACROS_HPP
11 #define BOOST_GRAPH_ITERATION_MACROS_HPP
12 
13 #include <utility>
14 
15 #define BGL_CAT(x,y) x ## y
16 #define BGL_RANGE(linenum) BGL_CAT(bgl_range_,linenum)
17 #define BGL_FIRST(linenum) (BGL_RANGE(linenum).first)
18 #define BGL_LAST(linenum) (BGL_RANGE(linenum).second)
19 
20 /*
21   BGL_FORALL_VERTICES_T(v, g, graph_t)  // This is on line 9
22   expands to the following, but all on the same line
23 
24   for (typename boost::graph_traits<graph_t>::vertex_iterator
25            bgl_first_9 = vertices(g).first, bgl_last_9 = vertices(g).second;
26        bgl_first_9 != bgl_last_9; bgl_first_9 = bgl_last_9)
27     for (typename boost::graph_traits<graph_t>::vertex_descriptor v;
28          bgl_first_9 != bgl_last_9 ? (v = *bgl_first_9, true) : false;
29          ++bgl_first_9)
30 
31   The purpose of having two for-loops is just to provide a place to
32   declare both the iterator and value variables. There is really only
33   one loop. The stopping condition gets executed two more times than it
34   usually would be, oh well. The reason for the bgl_first_9 = bgl_last_9
35   in the outer for-loop is in case the user puts a break statement
36   in the inner for-loop.
37 
38   The other macros work in a similar fashion.
39 
40   Use the _T versions when the graph type is a template parameter or
41   dependent on a template parameter. Otherwise use the non _T versions.
42 
43   -----------------------
44   6/9/09 THK
45 
46   The above contains two calls to the vertices function. I modified these
47   macros to expand to
48 
49     for (std::pair<typename boost::graph_traits<graph_t>::vertex_iterator,
50                    typename boost::graph_traits<graph_t>::vertex_iterator> bgl_range_9 = vertices(g);
51        bgl_range_9.first != bgl_range_9.second;
52        bgl_range_9.first = bgl_range_9.second)
53     for (typename boost::graph_traits<graph_t>::vertex_descriptor v;
54          bgl_range_9.first != bgl_range_9.second ? (v = *bgl_range_9.first, true) : false;
55          ++bgl_range_9.first)
56 
57  */
58 
59 
60 #define BGL_FORALL_VERTICES_T(VNAME, GNAME, GraphType) \
61 for (std::pair<typename boost::graph_traits<GraphType>::vertex_iterator, \
62                typename boost::graph_traits<GraphType>::vertex_iterator> BGL_RANGE(__LINE__) = vertices(GNAME); \
63   BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \
64   for (typename boost::graph_traits<GraphType>::vertex_descriptor VNAME; \
65     BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (VNAME = *BGL_FIRST(__LINE__), true):false; \
66      ++BGL_FIRST(__LINE__))
67 
68 #define BGL_FORALL_VERTICES(VNAME, GNAME, GraphType) \
69 for (std::pair<boost::graph_traits<GraphType>::vertex_iterator, \
70                boost::graph_traits<GraphType>::vertex_iterator> BGL_RANGE(__LINE__) = vertices(GNAME); \
71   BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \
72   for (boost::graph_traits<GraphType>::vertex_descriptor VNAME; \
73     BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (VNAME = *BGL_FIRST(__LINE__), true):false; \
74      ++BGL_FIRST(__LINE__))
75 
76 #define BGL_FORALL_EDGES_T(ENAME, GNAME, GraphType) \
77 for (std::pair<typename boost::graph_traits<GraphType>::edge_iterator, \
78                typename boost::graph_traits<GraphType>::edge_iterator> BGL_RANGE(__LINE__) = edges(GNAME); \
79   BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \
80   for (typename boost::graph_traits<GraphType>::edge_descriptor ENAME; \
81     BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (ENAME = *BGL_FIRST(__LINE__), true):false; \
82      ++BGL_FIRST(__LINE__))
83 
84 #define BGL_FORALL_EDGES(ENAME, GNAME, GraphType) \
85 for (std::pair<boost::graph_traits<GraphType>::edge_iterator, \
86                boost::graph_traits<GraphType>::edge_iterator> BGL_RANGE(__LINE__) = edges(GNAME); \
87   BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \
88   for (boost::graph_traits<GraphType>::edge_descriptor ENAME; \
89      BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (ENAME = *BGL_FIRST(__LINE__), true):false; \
90      ++BGL_FIRST(__LINE__))
91 
92 #define BGL_FORALL_ADJ_T(UNAME, VNAME, GNAME, GraphType) \
93 for (std::pair<typename boost::graph_traits<GraphType>::adjacency_iterator, \
94                typename boost::graph_traits<GraphType>::adjacency_iterator> BGL_RANGE(__LINE__) = adjacent_vertices(UNAME, GNAME); \
95   BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \
96 for (typename boost::graph_traits<GraphType>::vertex_descriptor VNAME; \
97   BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (VNAME = *BGL_FIRST(__LINE__), true) : false; \
98    ++BGL_FIRST(__LINE__))
99 
100 #define BGL_FORALL_ADJ(UNAME, VNAME, GNAME, GraphType) \
101 for (std::pair<boost::graph_traits<GraphType>::adjacency_iterator, \
102                boost::graph_traits<GraphType>::adjacency_iterator> BGL_RANGE(__LINE__) = adjacent_vertices(UNAME, GNAME); \
103   BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \
104 for (boost::graph_traits<GraphType>::vertex_descriptor VNAME; \
105   BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (VNAME = *BGL_FIRST(__LINE__), true) : false; \
106    ++BGL_FIRST(__LINE__))
107 
108 #define BGL_FORALL_OUTEDGES_T(UNAME, ENAME, GNAME, GraphType) \
109 for (std::pair<typename boost::graph_traits<GraphType>::out_edge_iterator, \
110                typename boost::graph_traits<GraphType>::out_edge_iterator> BGL_RANGE(__LINE__) = out_edges(UNAME, GNAME); \
111   BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \
112 for (typename boost::graph_traits<GraphType>::edge_descriptor ENAME; \
113   BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (ENAME = *BGL_FIRST(__LINE__), true) : false; \
114    ++BGL_FIRST(__LINE__))
115 
116 #define BGL_FORALL_OUTEDGES(UNAME, ENAME, GNAME, GraphType) \
117 for (std::pair<boost::graph_traits<GraphType>::out_edge_iterator, \
118                boost::graph_traits<GraphType>::out_edge_iterator> BGL_RANGE(__LINE__) = out_edges(UNAME, GNAME); \
119   BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \
120 for (boost::graph_traits<GraphType>::edge_descriptor ENAME; \
121   BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (ENAME = *BGL_FIRST(__LINE__), true) : false; \
122    ++BGL_FIRST(__LINE__))
123 
124 #define BGL_FORALL_INEDGES_T(UNAME, ENAME, GNAME, GraphType) \
125 for (std::pair<typename boost::graph_traits<GraphType>::in_edge_iterator, \
126                typename boost::graph_traits<GraphType>::in_edge_iterator> BGL_RANGE(__LINE__) = in_edges(UNAME, GNAME); \
127   BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \
128 for (typename boost::graph_traits<GraphType>::edge_descriptor ENAME; \
129   BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (ENAME = *BGL_FIRST(__LINE__), true) : false; \
130    ++BGL_FIRST(__LINE__))
131 
132 #define BGL_FORALL_INEDGES(UNAME, ENAME, GNAME, GraphType) \
133 for (std::pair<boost::graph_traits<GraphType>::in_edge_iterator, \
134                boost::graph_traits<GraphType>::in_edge_iterator> BGL_RANGE(__LINE__) = in_edges(UNAME, GNAME); \
135   BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \
136 for (boost::graph_traits<GraphType>::edge_descriptor ENAME; \
137   BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (ENAME = *BGL_FIRST(__LINE__), true) : false; \
138    ++BGL_FIRST(__LINE__))
139 
140 #endif // BOOST_GRAPH_ITERATION_MACROS_HPP
141