Chris@16
|
1 //=======================================================================
|
Chris@16
|
2 // Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
|
Chris@16
|
3 // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
|
Chris@16
|
4 //
|
Chris@16
|
5 // Distributed under the Boost Software License, Version 1.0. (See
|
Chris@16
|
6 // accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
7 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
8 //=======================================================================
|
Chris@16
|
9 #ifndef BOOST_SELF_AVOIDING_WALK_HPP
|
Chris@16
|
10 #define BOOST_SELF_AVOIDING_WALK_HPP
|
Chris@16
|
11
|
Chris@16
|
12 /*
|
Chris@16
|
13 This file defines necessary components for SAW.
|
Chris@16
|
14
|
Chris@16
|
15 mesh language: (defined by myself to clearify what is what)
|
Chris@16
|
16 A triangle in mesh is called an triangle.
|
Chris@16
|
17 An edge in mesh is called an line.
|
Chris@16
|
18 A vertex in mesh is called a point.
|
Chris@16
|
19
|
Chris@16
|
20 A triangular mesh corresponds to a graph in which a vertex is a
|
Chris@16
|
21 triangle and an edge(u, v) stands for triangle u and triangle v
|
Chris@16
|
22 share an line.
|
Chris@16
|
23
|
Chris@16
|
24 After this point, a vertex always refers to vertex in graph,
|
Chris@16
|
25 therefore it is a traingle in mesh.
|
Chris@16
|
26
|
Chris@16
|
27 */
|
Chris@16
|
28
|
Chris@16
|
29 #include <utility>
|
Chris@16
|
30 #include <boost/config.hpp>
|
Chris@16
|
31 #include <boost/graph/graph_traits.hpp>
|
Chris@16
|
32 #include <boost/property_map/property_map.hpp>
|
Chris@16
|
33
|
Chris@16
|
34 #define SAW_SENTINAL -1
|
Chris@16
|
35
|
Chris@16
|
36 namespace boost {
|
Chris@16
|
37
|
Chris@16
|
38 template <class T1, class T2, class T3>
|
Chris@16
|
39 struct triple {
|
Chris@16
|
40 T1 first;
|
Chris@16
|
41 T2 second;
|
Chris@16
|
42 T3 third;
|
Chris@16
|
43 triple(const T1& a, const T2& b, const T3& c) : first(a), second(b), third(c) {}
|
Chris@16
|
44 triple() : first(SAW_SENTINAL), second(SAW_SENTINAL), third(SAW_SENTINAL) {}
|
Chris@16
|
45 };
|
Chris@16
|
46
|
Chris@16
|
47 typedef triple<int, int, int> Triple;
|
Chris@16
|
48
|
Chris@16
|
49 /* Define a vertex property which has a triangle inside. Triangle is
|
Chris@16
|
50 represented by a triple. */
|
Chris@16
|
51 struct triangle_tag { enum { num = 100 }; };
|
Chris@16
|
52 typedef property<triangle_tag,Triple> triangle_property;
|
Chris@16
|
53
|
Chris@16
|
54 /* Define an edge property with a line. A line is represented by a
|
Chris@16
|
55 pair. This is not required for SAW though.
|
Chris@16
|
56 */
|
Chris@16
|
57 struct line_tag { enum { num = 101 }; };
|
Chris@16
|
58 template <class T> struct line_property
|
Chris@16
|
59 : public property<line_tag, std::pair<T,T> > { };
|
Chris@16
|
60
|
Chris@16
|
61 /*Precondition: Points in a Triangle are in order */
|
Chris@16
|
62 template <class Triangle, class Line>
|
Chris@16
|
63 inline void get_sharing(const Triangle& a, const Triangle& b, Line& l)
|
Chris@16
|
64 {
|
Chris@16
|
65 l.first = SAW_SENTINAL;
|
Chris@16
|
66 l.second = SAW_SENTINAL;
|
Chris@16
|
67
|
Chris@16
|
68 if ( a.first == b.first ) {
|
Chris@16
|
69 l.first = a.first;
|
Chris@16
|
70 if ( a.second == b.second || a.second == b.third )
|
Chris@16
|
71 l.second = a.second;
|
Chris@16
|
72 else if ( a.third == b.second || a.third == b.third )
|
Chris@16
|
73 l.second = a.third;
|
Chris@16
|
74
|
Chris@16
|
75 } else if ( a.first == b.second ) {
|
Chris@16
|
76 l.first = a.first;
|
Chris@16
|
77 if ( a.second == b.third )
|
Chris@16
|
78 l.second = a.second;
|
Chris@16
|
79 else if ( a.third == b.third )
|
Chris@16
|
80 l.second = a.third;
|
Chris@16
|
81
|
Chris@16
|
82 } else if ( a.first == b.third ) {
|
Chris@16
|
83 l.first = a.first;
|
Chris@16
|
84
|
Chris@16
|
85
|
Chris@16
|
86 } else if ( a.second == b.first ) {
|
Chris@16
|
87 l.first = a.second;
|
Chris@16
|
88 if ( a.third == b.second || a.third == b.third )
|
Chris@16
|
89 l.second = a.third;
|
Chris@16
|
90
|
Chris@16
|
91 } else if ( a.second == b.second ) {
|
Chris@16
|
92 l.first = a.second;
|
Chris@16
|
93 if ( a.third == b.third )
|
Chris@16
|
94 l.second = a.third;
|
Chris@16
|
95
|
Chris@16
|
96 } else if ( a.second == b.third ) {
|
Chris@16
|
97 l.first = a.second;
|
Chris@16
|
98
|
Chris@16
|
99
|
Chris@16
|
100 } else if ( a.third == b.first
|
Chris@16
|
101 || a.third == b.second
|
Chris@16
|
102 || a.third == b.third )
|
Chris@16
|
103 l.first = a.third;
|
Chris@16
|
104
|
Chris@16
|
105 /*Make it in order*/
|
Chris@16
|
106 if ( l.first > l.second ) {
|
Chris@16
|
107 typename Line::first_type i = l.first;
|
Chris@16
|
108 l.first = l.second;
|
Chris@16
|
109 l.second = i;
|
Chris@16
|
110 }
|
Chris@16
|
111
|
Chris@16
|
112 }
|
Chris@16
|
113
|
Chris@16
|
114 template <class TriangleDecorator, class Vertex, class Line>
|
Chris@16
|
115 struct get_vertex_sharing {
|
Chris@16
|
116 typedef std::pair<Vertex, Line> Pair;
|
Chris@16
|
117 get_vertex_sharing(const TriangleDecorator& _td) : td(_td) {}
|
Chris@16
|
118 inline Line operator()(const Vertex& u, const Vertex& v) const {
|
Chris@16
|
119 Line l;
|
Chris@16
|
120 get_sharing(td[u], td[v], l);
|
Chris@16
|
121 return l;
|
Chris@16
|
122 }
|
Chris@16
|
123 inline Line operator()(const Pair& u, const Vertex& v) const {
|
Chris@16
|
124 Line l;
|
Chris@16
|
125 get_sharing(td[u.first], td[v], l);
|
Chris@16
|
126 return l;
|
Chris@16
|
127 }
|
Chris@16
|
128 inline Line operator()(const Pair& u, const Pair& v) const {
|
Chris@16
|
129 Line l;
|
Chris@16
|
130 get_sharing(td[u.first], td[v.first], l);
|
Chris@16
|
131 return l;
|
Chris@16
|
132 }
|
Chris@16
|
133 TriangleDecorator td;
|
Chris@16
|
134 };
|
Chris@16
|
135
|
Chris@16
|
136 /* HList has to be a handle of data holder so that pass-by-value is
|
Chris@16
|
137 * in right logic.
|
Chris@16
|
138 *
|
Chris@16
|
139 * The element of HList is a pair of vertex and line. (remember a
|
Chris@16
|
140 * line is a pair of two ints.). That indicates the walk w from
|
Chris@16
|
141 * current vertex is across line. (If the first of line is -1, it is
|
Chris@16
|
142 * a point though.
|
Chris@16
|
143 */
|
Chris@16
|
144 template < class TriangleDecorator, class HList, class IteratorD>
|
Chris@16
|
145 class SAW_visitor
|
Chris@16
|
146 : public bfs_visitor<>, public dfs_visitor<>
|
Chris@16
|
147 {
|
Chris@16
|
148 typedef typename boost::property_traits<IteratorD>::value_type iter;
|
Chris@16
|
149 /*use boost shared_ptr*/
|
Chris@16
|
150 typedef typename HList::element_type::value_type::second_type Line;
|
Chris@16
|
151 public:
|
Chris@16
|
152
|
Chris@16
|
153 typedef tree_edge_tag category;
|
Chris@16
|
154
|
Chris@16
|
155 inline SAW_visitor(TriangleDecorator _td, HList _hlist, IteratorD ia)
|
Chris@16
|
156 : td(_td), hlist(_hlist), iter_d(ia) {}
|
Chris@16
|
157
|
Chris@16
|
158 template <class Vertex, class Graph>
|
Chris@16
|
159 inline void start_vertex(Vertex v, Graph&) {
|
Chris@16
|
160 Line l1;
|
Chris@16
|
161 l1.first = SAW_SENTINAL;
|
Chris@16
|
162 l1.second = SAW_SENTINAL;
|
Chris@16
|
163 hlist->push_front(std::make_pair(v, l1));
|
Chris@16
|
164 iter_d[v] = hlist->begin();
|
Chris@16
|
165 }
|
Chris@16
|
166
|
Chris@16
|
167 /*Several symbols:
|
Chris@16
|
168 w(i): i-th triangle in walk w
|
Chris@16
|
169 w(i) |- w(i+1): w enter w(i+1) from w(i) over a line
|
Chris@16
|
170 w(i) ~> w(i+1): w enter w(i+1) from w(i) over a point
|
Chris@16
|
171 w(i) -> w(i+1): w enter w(i+1) from w(i)
|
Chris@16
|
172 w(i) ^ w(i+1): the line or point w go over from w(i) to w(i+1)
|
Chris@16
|
173 */
|
Chris@16
|
174 template <class Edge, class Graph>
|
Chris@16
|
175 bool tree_edge(Edge e, Graph& G) {
|
Chris@16
|
176 using std::make_pair;
|
Chris@16
|
177 typedef typename boost::graph_traits<Graph>::vertex_descriptor Vertex;
|
Chris@16
|
178 Vertex tau = target(e, G);
|
Chris@16
|
179 Vertex i = source(e, G);
|
Chris@16
|
180
|
Chris@16
|
181 get_vertex_sharing<TriangleDecorator, Vertex, Line> get_sharing_line(td);
|
Chris@16
|
182
|
Chris@16
|
183 Line tau_i = get_sharing_line(tau, i);
|
Chris@16
|
184
|
Chris@16
|
185 iter w_end = hlist->end();
|
Chris@16
|
186
|
Chris@16
|
187 iter w_i = iter_d[i];
|
Chris@16
|
188
|
Chris@16
|
189 iter w_i_m_1 = w_i;
|
Chris@16
|
190 iter w_i_p_1 = w_i;
|
Chris@16
|
191
|
Chris@16
|
192 /*----------------------------------------------------------
|
Chris@16
|
193 * true false
|
Chris@16
|
194 *==========================================================
|
Chris@16
|
195 *a w(i-1) |- w(i) w(i-1) ~> w(i) or w(i-1) is null
|
Chris@16
|
196 *----------------------------------------------------------
|
Chris@16
|
197 *b w(i) |- w(i+1) w(i) ~> w(i+1) or no w(i+1) yet
|
Chris@16
|
198 *----------------------------------------------------------
|
Chris@16
|
199 */
|
Chris@16
|
200
|
Chris@16
|
201 bool a = false, b = false;
|
Chris@16
|
202
|
Chris@16
|
203 --w_i_m_1;
|
Chris@16
|
204 ++w_i_p_1;
|
Chris@16
|
205 b = ( w_i->second.first != SAW_SENTINAL );
|
Chris@16
|
206
|
Chris@16
|
207 if ( w_i_m_1 != w_end ) {
|
Chris@16
|
208 a = ( w_i_m_1->second.first != SAW_SENTINAL );
|
Chris@16
|
209 }
|
Chris@16
|
210
|
Chris@16
|
211 if ( a ) {
|
Chris@16
|
212
|
Chris@16
|
213 if ( b ) {
|
Chris@16
|
214 /*Case 1:
|
Chris@16
|
215
|
Chris@16
|
216 w(i-1) |- w(i) |- w(i+1)
|
Chris@16
|
217 */
|
Chris@16
|
218 Line l1 = get_sharing_line(*w_i_m_1, tau);
|
Chris@16
|
219
|
Chris@16
|
220 iter w_i_m_2 = w_i_m_1;
|
Chris@16
|
221 --w_i_m_2;
|
Chris@16
|
222
|
Chris@16
|
223 bool c = true;
|
Chris@16
|
224
|
Chris@16
|
225 if ( w_i_m_2 != w_end ) {
|
Chris@16
|
226 c = w_i_m_2->second != l1;
|
Chris@16
|
227 }
|
Chris@16
|
228
|
Chris@16
|
229 if ( c ) { /* w(i-1) ^ tau != w(i-2) ^ w(i-1) */
|
Chris@16
|
230 /*extension: w(i-1) -> tau |- w(i) */
|
Chris@16
|
231 w_i_m_1->second = l1;
|
Chris@16
|
232 /*insert(pos, const T&) is to insert before pos*/
|
Chris@16
|
233 iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i));
|
Chris@16
|
234
|
Chris@16
|
235 } else { /* w(i-1) ^ tau == w(i-2) ^ w(i-1) */
|
Chris@16
|
236 /*must be w(i-2) ~> w(i-1) */
|
Chris@16
|
237
|
Chris@16
|
238 bool d = true;
|
Chris@16
|
239 //need to handle the case when w_i_p_1 is null
|
Chris@16
|
240 Line l3 = get_sharing_line(*w_i_p_1, tau);
|
Chris@16
|
241 if ( w_i_p_1 != w_end )
|
Chris@16
|
242 d = w_i_p_1->second != l3;
|
Chris@16
|
243 if ( d ) { /* w(i+1) ^ tau != w(i+1) ^ w(i+2) */
|
Chris@16
|
244 /*extension: w(i) |- tau -> w(i+1) */
|
Chris@16
|
245 w_i->second = tau_i;
|
Chris@16
|
246 iter_d[tau] = hlist->insert(w_i_p_1, make_pair(tau, l3));
|
Chris@16
|
247 } else { /* w(i+1) ^ tau == w(i+1) ^ w(i+2) */
|
Chris@16
|
248 /*must be w(1+1) ~> w(i+2) */
|
Chris@16
|
249 Line l5 = get_sharing_line(*w_i_m_1, *w_i_p_1);
|
Chris@16
|
250 if ( l5 != w_i_p_1->second ) { /* w(i-1) ^ w(i+1) != w(i+1) ^ w(i+2) */
|
Chris@16
|
251 /*extension: w(i-2) -> tau |- w(i) |- w(i-1) -> w(i+1) */
|
Chris@16
|
252 w_i_m_2->second = get_sharing_line(*w_i_m_2, tau);
|
Chris@16
|
253 iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i));
|
Chris@16
|
254 w_i->second = w_i_m_1->second;
|
Chris@16
|
255 w_i_m_1->second = l5;
|
Chris@16
|
256 iter_d[w_i_m_1->first] = hlist->insert(w_i_p_1, *w_i_m_1);
|
Chris@16
|
257 hlist->erase(w_i_m_1);
|
Chris@16
|
258 } else {
|
Chris@16
|
259 /*mesh is tetrahedral*/
|
Chris@16
|
260 // dont know what that means.
|
Chris@16
|
261 ;
|
Chris@16
|
262 }
|
Chris@16
|
263 }
|
Chris@16
|
264
|
Chris@16
|
265 }
|
Chris@16
|
266 } else {
|
Chris@16
|
267 /*Case 2:
|
Chris@16
|
268
|
Chris@16
|
269 w(i-1) |- w(i) ~> w(1+1)
|
Chris@16
|
270 */
|
Chris@16
|
271
|
Chris@16
|
272 if ( w_i->second.second == tau_i.first
|
Chris@16
|
273 || w_i->second.second == tau_i.second ) { /*w(i) ^ w(i+1) < w(i) ^ tau*/
|
Chris@16
|
274 /*extension: w(i) |- tau -> w(i+1) */
|
Chris@16
|
275 w_i->second = tau_i;
|
Chris@16
|
276 Line l1 = get_sharing_line(*w_i_p_1, tau);
|
Chris@16
|
277 iter_d[tau] = hlist->insert(w_i_p_1, make_pair(tau, l1));
|
Chris@16
|
278 } else { /*w(i) ^ w(i+1) !< w(i) ^ tau*/
|
Chris@16
|
279 Line l1 = get_sharing_line(*w_i_m_1, tau);
|
Chris@16
|
280 bool c = true;
|
Chris@16
|
281 iter w_i_m_2 = w_i_m_1;
|
Chris@16
|
282 --w_i_m_2;
|
Chris@16
|
283 if ( w_i_m_2 != w_end )
|
Chris@16
|
284 c = l1 != w_i_m_2->second;
|
Chris@16
|
285 if (c) { /*w(i-1) ^ tau != w(i-2) ^ w(i-1)*/
|
Chris@16
|
286 /*extension: w(i-1) -> tau |- w(i)*/
|
Chris@16
|
287 w_i_m_1->second = l1;
|
Chris@16
|
288 iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i));
|
Chris@16
|
289 } else { /*w(i-1) ^ tau == w(i-2) ^ w(i-1)*/
|
Chris@16
|
290 /*must be w(i-2)~>w(i-1)*/
|
Chris@16
|
291 /*extension: w(i-2) -> tau |- w(i) |- w(i-1) -> w(i+1)*/
|
Chris@16
|
292 w_i_m_2->second = get_sharing_line(*w_i_m_2, tau);
|
Chris@16
|
293 iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i));
|
Chris@16
|
294 w_i->second = w_i_m_1->second;
|
Chris@16
|
295 w_i_m_1->second = get_sharing_line(*w_i_m_1, *w_i_p_1);
|
Chris@16
|
296 iter_d[w_i_m_1->first] = hlist->insert(w_i_p_1, *w_i_m_1);
|
Chris@16
|
297 hlist->erase(w_i_m_1);
|
Chris@16
|
298 }
|
Chris@16
|
299
|
Chris@16
|
300 }
|
Chris@16
|
301
|
Chris@16
|
302 }
|
Chris@16
|
303
|
Chris@16
|
304 } else {
|
Chris@16
|
305
|
Chris@16
|
306 if ( b ) {
|
Chris@16
|
307 /*Case 3:
|
Chris@16
|
308
|
Chris@16
|
309 w(i-1) ~> w(i) |- w(i+1)
|
Chris@16
|
310 */
|
Chris@16
|
311 bool c = false;
|
Chris@16
|
312 if ( w_i_m_1 != w_end )
|
Chris@16
|
313 c = ( w_i_m_1->second.second == tau_i.first)
|
Chris@16
|
314 || ( w_i_m_1->second.second == tau_i.second);
|
Chris@16
|
315
|
Chris@16
|
316 if ( c ) { /*w(i-1) ^ w(i) < w(i) ^ tau*/
|
Chris@16
|
317 /* extension: w(i-1) -> tau |- w(i) */
|
Chris@16
|
318 if ( w_i_m_1 != w_end )
|
Chris@16
|
319 w_i_m_1->second = get_sharing_line(*w_i_m_1, tau);
|
Chris@16
|
320 iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i));
|
Chris@16
|
321 } else {
|
Chris@16
|
322 bool d = true;
|
Chris@16
|
323 Line l1;
|
Chris@16
|
324 l1.first = SAW_SENTINAL;
|
Chris@16
|
325 l1.second = SAW_SENTINAL;
|
Chris@16
|
326 if ( w_i_p_1 != w_end ) {
|
Chris@16
|
327 l1 = get_sharing_line(*w_i_p_1, tau);
|
Chris@16
|
328 d = l1 != w_i_p_1->second;
|
Chris@16
|
329 }
|
Chris@16
|
330 if (d) { /*w(i+1) ^ tau != w(i+1) ^ w(i+2)*/
|
Chris@16
|
331 /*extension: w(i) |- tau -> w(i+1) */
|
Chris@16
|
332 w_i->second = tau_i;
|
Chris@16
|
333 iter_d[tau] = hlist->insert(w_i_p_1, make_pair(tau, l1));
|
Chris@16
|
334 } else {
|
Chris@16
|
335 /*must be w(i+1) ~> w(i+2)*/
|
Chris@16
|
336 /*extension: w(i-1) -> w(i+1) |- w(i) |- tau -> w(i+2) */
|
Chris@16
|
337 iter w_i_p_2 = w_i_p_1;
|
Chris@16
|
338 ++w_i_p_2;
|
Chris@16
|
339
|
Chris@16
|
340 w_i_p_1->second = w_i->second;
|
Chris@16
|
341 iter_d[i] = hlist->insert(w_i_p_2, make_pair(i, tau_i));
|
Chris@16
|
342 hlist->erase(w_i);
|
Chris@16
|
343 Line l2 = get_sharing_line(*w_i_p_2, tau);
|
Chris@16
|
344 iter_d[tau] = hlist->insert(w_i_p_2, make_pair(tau, l2));
|
Chris@16
|
345 }
|
Chris@16
|
346 }
|
Chris@16
|
347
|
Chris@16
|
348 } else {
|
Chris@16
|
349 /*Case 4:
|
Chris@16
|
350
|
Chris@16
|
351 w(i-1) ~> w(i) ~> w(i+1)
|
Chris@16
|
352
|
Chris@16
|
353 */
|
Chris@16
|
354 bool c = false;
|
Chris@16
|
355 if ( w_i_m_1 != w_end ) {
|
Chris@16
|
356 c = (w_i_m_1->second.second == tau_i.first)
|
Chris@16
|
357 || (w_i_m_1->second.second == tau_i.second);
|
Chris@16
|
358 }
|
Chris@16
|
359 if ( c ) { /*w(i-1) ^ w(i) < w(i) ^ tau */
|
Chris@16
|
360 /*extension: w(i-1) -> tau |- w(i) */
|
Chris@16
|
361 if ( w_i_m_1 != w_end )
|
Chris@16
|
362 w_i_m_1->second = get_sharing_line(*w_i_m_1, tau);
|
Chris@16
|
363 iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i));
|
Chris@16
|
364 } else {
|
Chris@16
|
365 /*extension: w(i) |- tau -> w(i+1) */
|
Chris@16
|
366 w_i->second = tau_i;
|
Chris@16
|
367 Line l1;
|
Chris@16
|
368 l1.first = SAW_SENTINAL;
|
Chris@16
|
369 l1.second = SAW_SENTINAL;
|
Chris@16
|
370 if ( w_i_p_1 != w_end )
|
Chris@16
|
371 l1 = get_sharing_line(*w_i_p_1, tau);
|
Chris@16
|
372 iter_d[tau] = hlist->insert(w_i_p_1, make_pair(tau, l1));
|
Chris@16
|
373 }
|
Chris@16
|
374 }
|
Chris@16
|
375
|
Chris@16
|
376 }
|
Chris@16
|
377
|
Chris@16
|
378 return true;
|
Chris@16
|
379 }
|
Chris@16
|
380
|
Chris@16
|
381 protected:
|
Chris@16
|
382 TriangleDecorator td; /*a decorator for vertex*/
|
Chris@16
|
383 HList hlist;
|
Chris@16
|
384 /*This must be a handle of list to record the SAW
|
Chris@16
|
385 The element type of the list is pair<Vertex, Line>
|
Chris@16
|
386 */
|
Chris@16
|
387
|
Chris@16
|
388 IteratorD iter_d;
|
Chris@16
|
389 /*Problem statement: Need a fast access to w for triangle i.
|
Chris@16
|
390 *Possible solution: mantain an array to record.
|
Chris@16
|
391 iter_d[i] will return an iterator
|
Chris@16
|
392 which points to w(i), where i is a vertex
|
Chris@16
|
393 representing triangle i.
|
Chris@16
|
394 */
|
Chris@16
|
395 };
|
Chris@16
|
396
|
Chris@16
|
397 template <class Triangle, class HList, class Iterator>
|
Chris@16
|
398 inline
|
Chris@16
|
399 SAW_visitor<Triangle, HList, Iterator>
|
Chris@16
|
400 visit_SAW(Triangle t, HList hl, Iterator i) {
|
Chris@16
|
401 return SAW_visitor<Triangle, HList, Iterator>(t, hl, i);
|
Chris@16
|
402 }
|
Chris@16
|
403
|
Chris@16
|
404 template <class Tri, class HList, class Iter>
|
Chris@16
|
405 inline
|
Chris@16
|
406 SAW_visitor< random_access_iterator_property_map<Tri*,Tri,Tri&>,
|
Chris@16
|
407 HList, random_access_iterator_property_map<Iter*,Iter,Iter&> >
|
Chris@16
|
408 visit_SAW_ptr(Tri* t, HList hl, Iter* i) {
|
Chris@16
|
409 typedef random_access_iterator_property_map<Tri*,Tri,Tri&> TriD;
|
Chris@16
|
410 typedef random_access_iterator_property_map<Iter*,Iter,Iter&> IterD;
|
Chris@16
|
411 return SAW_visitor<TriD, HList, IterD>(t, hl, i);
|
Chris@16
|
412 }
|
Chris@16
|
413
|
Chris@16
|
414 // should also have combo's of pointers, and also const :(
|
Chris@16
|
415
|
Chris@16
|
416 }
|
Chris@16
|
417
|
Chris@16
|
418 #endif /*BOOST_SAW_H*/
|