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>
51   bgl_range_9 = vertices(g); 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,
55   true) : false;
56          ++bgl_range_9.first)
57 
58  */
59 
60 #define BGL_FORALL_VERTICES_T(VNAME, GNAME, GraphType)                    \
61     for (std::pair<                                                       \
62              typename boost::graph_traits< GraphType >::vertex_iterator,  \
63              typename boost::graph_traits< GraphType >::vertex_iterator > \
64              BGL_RANGE(__LINE__)                                          \
65          = vertices(GNAME);                                               \
66          BGL_FIRST(__LINE__) != BGL_LAST(__LINE__);                       \
67          BGL_FIRST(__LINE__) = BGL_LAST(__LINE__))                        \
68         for (typename boost::graph_traits< GraphType >::vertex_descriptor \
69                  VNAME;                                                   \
70              BGL_FIRST(__LINE__) != BGL_LAST(__LINE__)                    \
71                  ? (VNAME = *BGL_FIRST(__LINE__), true)                   \
72                  : false;                                                 \
73              ++BGL_FIRST(__LINE__))
74 
75 #define BGL_FORALL_VERTICES(VNAME, GNAME, GraphType)                    \
76     for (std::pair< boost::graph_traits< GraphType >::vertex_iterator,  \
77              boost::graph_traits< GraphType >::vertex_iterator >        \
78              BGL_RANGE(__LINE__)                                        \
79          = vertices(GNAME);                                             \
80          BGL_FIRST(__LINE__) != BGL_LAST(__LINE__);                     \
81          BGL_FIRST(__LINE__) = BGL_LAST(__LINE__))                      \
82         for (boost::graph_traits< GraphType >::vertex_descriptor VNAME; \
83              BGL_FIRST(__LINE__) != BGL_LAST(__LINE__)                  \
84                  ? (VNAME = *BGL_FIRST(__LINE__), true)                 \
85                  : false;                                               \
86              ++BGL_FIRST(__LINE__))
87 
88 #define BGL_FORALL_EDGES_T(ENAME, GNAME, GraphType)                            \
89     for (std::pair< typename boost::graph_traits< GraphType >::edge_iterator,  \
90              typename boost::graph_traits< GraphType >::edge_iterator >        \
91              BGL_RANGE(__LINE__)                                               \
92          = edges(GNAME);                                                       \
93          BGL_FIRST(__LINE__) != BGL_LAST(__LINE__);                            \
94          BGL_FIRST(__LINE__) = BGL_LAST(__LINE__))                             \
95         for (typename boost::graph_traits< GraphType >::edge_descriptor ENAME; \
96              BGL_FIRST(__LINE__) != BGL_LAST(__LINE__)                         \
97                  ? (ENAME = *BGL_FIRST(__LINE__), true)                        \
98                  : false;                                                      \
99              ++BGL_FIRST(__LINE__))
100 
101 #define BGL_FORALL_EDGES(ENAME, GNAME, GraphType)                     \
102     for (std::pair< boost::graph_traits< GraphType >::edge_iterator,  \
103              boost::graph_traits< GraphType >::edge_iterator >        \
104              BGL_RANGE(__LINE__)                                      \
105          = edges(GNAME);                                              \
106          BGL_FIRST(__LINE__) != BGL_LAST(__LINE__);                   \
107          BGL_FIRST(__LINE__) = BGL_LAST(__LINE__))                    \
108         for (boost::graph_traits< GraphType >::edge_descriptor ENAME; \
109              BGL_FIRST(__LINE__) != BGL_LAST(__LINE__)                \
110                  ? (ENAME = *BGL_FIRST(__LINE__), true)               \
111                  : false;                                             \
112              ++BGL_FIRST(__LINE__))
113 
114 #define BGL_FORALL_ADJ_T(UNAME, VNAME, GNAME, GraphType)                     \
115     for (std::pair<                                                          \
116              typename boost::graph_traits< GraphType >::adjacency_iterator,  \
117              typename boost::graph_traits< GraphType >::adjacency_iterator > \
118              BGL_RANGE(__LINE__)                                             \
119          = adjacent_vertices(UNAME, GNAME);                                  \
120          BGL_FIRST(__LINE__) != BGL_LAST(__LINE__);                          \
121          BGL_FIRST(__LINE__) = BGL_LAST(__LINE__))                           \
122         for (typename boost::graph_traits< GraphType >::vertex_descriptor    \
123                  VNAME;                                                      \
124              BGL_FIRST(__LINE__) != BGL_LAST(__LINE__)                       \
125                  ? (VNAME = *BGL_FIRST(__LINE__), true)                      \
126                  : false;                                                    \
127              ++BGL_FIRST(__LINE__))
128 
129 #define BGL_FORALL_ADJ(UNAME, VNAME, GNAME, GraphType)                    \
130     for (std::pair< boost::graph_traits< GraphType >::adjacency_iterator, \
131              boost::graph_traits< GraphType >::adjacency_iterator >       \
132              BGL_RANGE(__LINE__)                                          \
133          = adjacent_vertices(UNAME, GNAME);                               \
134          BGL_FIRST(__LINE__) != BGL_LAST(__LINE__);                       \
135          BGL_FIRST(__LINE__) = BGL_LAST(__LINE__))                        \
136         for (boost::graph_traits< GraphType >::vertex_descriptor VNAME;   \
137              BGL_FIRST(__LINE__) != BGL_LAST(__LINE__)                    \
138                  ? (VNAME = *BGL_FIRST(__LINE__), true)                   \
139                  : false;                                                 \
140              ++BGL_FIRST(__LINE__))
141 
142 #define BGL_FORALL_OUTEDGES_T(UNAME, ENAME, GNAME, GraphType)                  \
143     for (std::pair<                                                            \
144              typename boost::graph_traits< GraphType >::out_edge_iterator,     \
145              typename boost::graph_traits< GraphType >::out_edge_iterator >    \
146              BGL_RANGE(__LINE__)                                               \
147          = out_edges(UNAME, GNAME);                                            \
148          BGL_FIRST(__LINE__) != BGL_LAST(__LINE__);                            \
149          BGL_FIRST(__LINE__) = BGL_LAST(__LINE__))                             \
150         for (typename boost::graph_traits< GraphType >::edge_descriptor ENAME; \
151              BGL_FIRST(__LINE__) != BGL_LAST(__LINE__)                         \
152                  ? (ENAME = *BGL_FIRST(__LINE__), true)                        \
153                  : false;                                                      \
154              ++BGL_FIRST(__LINE__))
155 
156 #define BGL_FORALL_OUTEDGES(UNAME, ENAME, GNAME, GraphType)              \
157     for (std::pair< boost::graph_traits< GraphType >::out_edge_iterator, \
158              boost::graph_traits< GraphType >::out_edge_iterator >       \
159              BGL_RANGE(__LINE__)                                         \
160          = out_edges(UNAME, GNAME);                                      \
161          BGL_FIRST(__LINE__) != BGL_LAST(__LINE__);                      \
162          BGL_FIRST(__LINE__) = BGL_LAST(__LINE__))                       \
163         for (boost::graph_traits< GraphType >::edge_descriptor ENAME;    \
164              BGL_FIRST(__LINE__) != BGL_LAST(__LINE__)                   \
165                  ? (ENAME = *BGL_FIRST(__LINE__), true)                  \
166                  : false;                                                \
167              ++BGL_FIRST(__LINE__))
168 
169 #define BGL_FORALL_INEDGES_T(UNAME, ENAME, GNAME, GraphType)                   \
170     for (std::pair<                                                            \
171              typename boost::graph_traits< GraphType >::in_edge_iterator,      \
172              typename boost::graph_traits< GraphType >::in_edge_iterator >     \
173              BGL_RANGE(__LINE__)                                               \
174          = in_edges(UNAME, GNAME);                                             \
175          BGL_FIRST(__LINE__) != BGL_LAST(__LINE__);                            \
176          BGL_FIRST(__LINE__) = BGL_LAST(__LINE__))                             \
177         for (typename boost::graph_traits< GraphType >::edge_descriptor ENAME; \
178              BGL_FIRST(__LINE__) != BGL_LAST(__LINE__)                         \
179                  ? (ENAME = *BGL_FIRST(__LINE__), true)                        \
180                  : false;                                                      \
181              ++BGL_FIRST(__LINE__))
182 
183 #define BGL_FORALL_INEDGES(UNAME, ENAME, GNAME, GraphType)              \
184     for (std::pair< boost::graph_traits< GraphType >::in_edge_iterator, \
185              boost::graph_traits< GraphType >::in_edge_iterator >       \
186              BGL_RANGE(__LINE__)                                        \
187          = in_edges(UNAME, GNAME);                                      \
188          BGL_FIRST(__LINE__) != BGL_LAST(__LINE__);                     \
189          BGL_FIRST(__LINE__) = BGL_LAST(__LINE__))                      \
190         for (boost::graph_traits< GraphType >::edge_descriptor ENAME;   \
191              BGL_FIRST(__LINE__) != BGL_LAST(__LINE__)                  \
192                  ? (ENAME = *BGL_FIRST(__LINE__), true)                 \
193                  : false;                                               \
194              ++BGL_FIRST(__LINE__))
195 
196 #endif // BOOST_GRAPH_ITERATION_MACROS_HPP
197