Chris@102
|
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
|
Chris@102
|
2
|
Chris@102
|
3 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
Chris@102
|
4
|
Chris@102
|
5 // This file was modified by Oracle on 2013, 2014, 2015.
|
Chris@102
|
6 // Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
|
Chris@102
|
7
|
Chris@102
|
8 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
Chris@102
|
9
|
Chris@102
|
10 // Use, modification and distribution is subject to the Boost Software License,
|
Chris@102
|
11 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@102
|
12 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@102
|
13
|
Chris@102
|
14 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_RESULT_HPP
|
Chris@102
|
15 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_RESULT_HPP
|
Chris@102
|
16
|
Chris@102
|
17 #include <boost/tuple/tuple.hpp>
|
Chris@102
|
18
|
Chris@102
|
19 #include <boost/mpl/is_sequence.hpp>
|
Chris@102
|
20 #include <boost/mpl/begin.hpp>
|
Chris@102
|
21 #include <boost/mpl/end.hpp>
|
Chris@102
|
22 #include <boost/mpl/next.hpp>
|
Chris@102
|
23 #include <boost/mpl/at.hpp>
|
Chris@102
|
24 #include <boost/mpl/vector_c.hpp>
|
Chris@102
|
25
|
Chris@102
|
26 #include <boost/geometry/core/topological_dimension.hpp>
|
Chris@102
|
27 #include <boost/geometry/util/condition.hpp>
|
Chris@102
|
28
|
Chris@102
|
29 // TEMP - move this header to geometry/detail
|
Chris@102
|
30 #include <boost/geometry/index/detail/tuples.hpp>
|
Chris@102
|
31
|
Chris@102
|
32 namespace boost { namespace geometry {
|
Chris@102
|
33
|
Chris@102
|
34 #ifndef DOXYGEN_NO_DETAIL
|
Chris@102
|
35 namespace detail { namespace relate {
|
Chris@102
|
36
|
Chris@102
|
37 enum field { interior = 0, boundary = 1, exterior = 2 };
|
Chris@102
|
38
|
Chris@102
|
39 // TODO: IF THE RESULT IS UPDATED WITH THE MAX POSSIBLE VALUE FOR SOME PAIR OF GEOEMTRIES
|
Chris@102
|
40 // THE VALUE ALREADY STORED MUSN'T BE CHECKED
|
Chris@102
|
41 // update() calls chould be replaced with set() in those cases
|
Chris@102
|
42 // but for safety reasons (STATIC_ASSERT) we should check if parameter D is valid and set() doesn't do that
|
Chris@102
|
43 // so some additional function could be added, e.g. set_dim()
|
Chris@102
|
44
|
Chris@102
|
45 // matrix
|
Chris@102
|
46
|
Chris@102
|
47 // TODO add height?
|
Chris@102
|
48
|
Chris@102
|
49 template <std::size_t Width>
|
Chris@102
|
50 class matrix
|
Chris@102
|
51 {
|
Chris@102
|
52 BOOST_STATIC_ASSERT(Width == 2 || Width == 3);
|
Chris@102
|
53
|
Chris@102
|
54 public:
|
Chris@102
|
55
|
Chris@102
|
56 static const std::size_t size = Width * Width;
|
Chris@102
|
57
|
Chris@102
|
58 inline matrix()
|
Chris@102
|
59 {
|
Chris@102
|
60 ::memset(m_array, 'F', size);
|
Chris@102
|
61 }
|
Chris@102
|
62
|
Chris@102
|
63 template <field F1, field F2>
|
Chris@102
|
64 inline char get() const
|
Chris@102
|
65 {
|
Chris@102
|
66 static const bool in_bounds = F1 * Width + F2 < size;
|
Chris@102
|
67 return get_dispatch<F1, F2>(integral_constant<bool, in_bounds>());
|
Chris@102
|
68 }
|
Chris@102
|
69
|
Chris@102
|
70 template <field F1, field F2, char V>
|
Chris@102
|
71 inline void set()
|
Chris@102
|
72 {
|
Chris@102
|
73 static const bool in_bounds = F1 * Width + F2 < size;
|
Chris@102
|
74 set_dispatch<F1, F2, V>(integral_constant<bool, in_bounds>());
|
Chris@102
|
75 }
|
Chris@102
|
76
|
Chris@102
|
77 template <field F1, field F2, char D>
|
Chris@102
|
78 inline void update()
|
Chris@102
|
79 {
|
Chris@102
|
80 static const bool in_bounds = F1 * Width + F2 < size;
|
Chris@102
|
81 update_dispatch<F1, F2, D>(integral_constant<bool, in_bounds>());
|
Chris@102
|
82 }
|
Chris@102
|
83
|
Chris@102
|
84 inline const char * data() const
|
Chris@102
|
85 {
|
Chris@102
|
86 return m_array;
|
Chris@102
|
87 }
|
Chris@102
|
88
|
Chris@102
|
89 private:
|
Chris@102
|
90 template <field F1, field F2>
|
Chris@102
|
91 inline char get_dispatch(integral_constant<bool, true>) const
|
Chris@102
|
92 {
|
Chris@102
|
93 return m_array[F1 * Width + F2];
|
Chris@102
|
94 }
|
Chris@102
|
95 template <field F1, field F2>
|
Chris@102
|
96 inline char get_dispatch(integral_constant<bool, false>) const
|
Chris@102
|
97 {
|
Chris@102
|
98 return 'F';
|
Chris@102
|
99 }
|
Chris@102
|
100
|
Chris@102
|
101 template <field F1, field F2, char V>
|
Chris@102
|
102 inline void set_dispatch(integral_constant<bool, true>)
|
Chris@102
|
103 {
|
Chris@102
|
104 BOOST_STATIC_ASSERT(('0' <= V && V <= '9') || V == 'T' || V == 'F');
|
Chris@102
|
105 m_array[F1 * Width + F2] = V;
|
Chris@102
|
106 }
|
Chris@102
|
107 template <field F1, field F2, char V>
|
Chris@102
|
108 inline void set_dispatch(integral_constant<bool, false>)
|
Chris@102
|
109 {}
|
Chris@102
|
110
|
Chris@102
|
111 template <field F1, field F2, char D>
|
Chris@102
|
112 inline void update_dispatch(integral_constant<bool, true>)
|
Chris@102
|
113 {
|
Chris@102
|
114 BOOST_STATIC_ASSERT('0' <= D && D <= '9');
|
Chris@102
|
115 char c = m_array[F1 * Width + F2];
|
Chris@102
|
116 if ( D > c || c > '9')
|
Chris@102
|
117 m_array[F1 * Width + F2] = D;
|
Chris@102
|
118 }
|
Chris@102
|
119 template <field F1, field F2, char D>
|
Chris@102
|
120 inline void update_dispatch(integral_constant<bool, false>)
|
Chris@102
|
121 {}
|
Chris@102
|
122
|
Chris@102
|
123 char m_array[size];
|
Chris@102
|
124 };
|
Chris@102
|
125
|
Chris@102
|
126 // TODO add EnableDimensions parameter?
|
Chris@102
|
127
|
Chris@102
|
128 struct matrix9 {};
|
Chris@102
|
129 //struct matrix4 {};
|
Chris@102
|
130
|
Chris@102
|
131 // matrix_width
|
Chris@102
|
132
|
Chris@102
|
133 template <typename MatrixOrMask>
|
Chris@102
|
134 struct matrix_width
|
Chris@102
|
135 : not_implemented<MatrixOrMask>
|
Chris@102
|
136 {};
|
Chris@102
|
137
|
Chris@102
|
138 template <>
|
Chris@102
|
139 struct matrix_width<matrix9>
|
Chris@102
|
140 {
|
Chris@102
|
141 static const std::size_t value = 3;
|
Chris@102
|
142 };
|
Chris@102
|
143
|
Chris@102
|
144 // matrix_handler
|
Chris@102
|
145
|
Chris@102
|
146 template <typename Matrix>
|
Chris@102
|
147 class matrix_handler
|
Chris@102
|
148 : private matrix<matrix_width<Matrix>::value>
|
Chris@102
|
149 {
|
Chris@102
|
150 typedef matrix<matrix_width<Matrix>::value> base_t;
|
Chris@102
|
151
|
Chris@102
|
152 public:
|
Chris@102
|
153 typedef std::string result_type;
|
Chris@102
|
154
|
Chris@102
|
155 static const bool interrupt = false;
|
Chris@102
|
156
|
Chris@102
|
157 matrix_handler(Matrix const&)
|
Chris@102
|
158 {}
|
Chris@102
|
159
|
Chris@102
|
160 result_type result() const
|
Chris@102
|
161 {
|
Chris@102
|
162 return std::string(this->data(),
|
Chris@102
|
163 this->data() + base_t::size);
|
Chris@102
|
164 }
|
Chris@102
|
165
|
Chris@102
|
166 template <field F1, field F2, char D>
|
Chris@102
|
167 inline bool may_update() const
|
Chris@102
|
168 {
|
Chris@102
|
169 BOOST_STATIC_ASSERT('0' <= D && D <= '9');
|
Chris@102
|
170
|
Chris@102
|
171 char const c = static_cast<base_t const&>(*this).template get<F1, F2>();
|
Chris@102
|
172 return D > c || c > '9';
|
Chris@102
|
173 }
|
Chris@102
|
174
|
Chris@102
|
175 //template <field F1, field F2>
|
Chris@102
|
176 //inline char get() const
|
Chris@102
|
177 //{
|
Chris@102
|
178 // return static_cast<base_t const&>(*this).template get<F1, F2>();
|
Chris@102
|
179 //}
|
Chris@102
|
180
|
Chris@102
|
181 template <field F1, field F2, char V>
|
Chris@102
|
182 inline void set()
|
Chris@102
|
183 {
|
Chris@102
|
184 static_cast<base_t&>(*this).template set<F1, F2, V>();
|
Chris@102
|
185 }
|
Chris@102
|
186
|
Chris@102
|
187 template <field F1, field F2, char D>
|
Chris@102
|
188 inline void update()
|
Chris@102
|
189 {
|
Chris@102
|
190 static_cast<base_t&>(*this).template update<F1, F2, D>();
|
Chris@102
|
191 }
|
Chris@102
|
192 };
|
Chris@102
|
193
|
Chris@102
|
194 // RUN-TIME MASKS
|
Chris@102
|
195
|
Chris@102
|
196 // mask9
|
Chris@102
|
197
|
Chris@102
|
198 class mask9
|
Chris@102
|
199 {
|
Chris@102
|
200 public:
|
Chris@102
|
201 static const std::size_t width = 3; // TEMP
|
Chris@102
|
202
|
Chris@102
|
203 inline mask9(std::string const& de9im_mask)
|
Chris@102
|
204 {
|
Chris@102
|
205 // TODO: throw an exception here?
|
Chris@102
|
206 BOOST_ASSERT(de9im_mask.size() == 9);
|
Chris@102
|
207 ::memcpy(m_mask, de9im_mask.c_str(), 9);
|
Chris@102
|
208 }
|
Chris@102
|
209
|
Chris@102
|
210 template <field F1, field F2>
|
Chris@102
|
211 inline char get() const
|
Chris@102
|
212 {
|
Chris@102
|
213 return m_mask[F1 * 3 + F2];
|
Chris@102
|
214 }
|
Chris@102
|
215
|
Chris@102
|
216 private:
|
Chris@102
|
217 char m_mask[9];
|
Chris@102
|
218 };
|
Chris@102
|
219
|
Chris@102
|
220 // interrupt()
|
Chris@102
|
221
|
Chris@102
|
222 template <typename Mask, bool InterruptEnabled>
|
Chris@102
|
223 struct interrupt_dispatch
|
Chris@102
|
224 {
|
Chris@102
|
225 template <field F1, field F2, char V>
|
Chris@102
|
226 static inline bool apply(Mask const&)
|
Chris@102
|
227 {
|
Chris@102
|
228 return false;
|
Chris@102
|
229 }
|
Chris@102
|
230 };
|
Chris@102
|
231
|
Chris@102
|
232 template <typename Mask>
|
Chris@102
|
233 struct interrupt_dispatch<Mask, true>
|
Chris@102
|
234 {
|
Chris@102
|
235 template <field F1, field F2, char V>
|
Chris@102
|
236 static inline bool apply(Mask const& mask)
|
Chris@102
|
237 {
|
Chris@102
|
238 char m = mask.template get<F1, F2>();
|
Chris@102
|
239 return check_element<V>(m);
|
Chris@102
|
240 }
|
Chris@102
|
241
|
Chris@102
|
242 template <char V>
|
Chris@102
|
243 static inline bool check_element(char m)
|
Chris@102
|
244 {
|
Chris@102
|
245 if ( BOOST_GEOMETRY_CONDITION(V >= '0' && V <= '9') )
|
Chris@102
|
246 {
|
Chris@102
|
247 return m == 'F' || ( m < V && m >= '0' && m <= '9' );
|
Chris@102
|
248 }
|
Chris@102
|
249 else if ( BOOST_GEOMETRY_CONDITION(V == 'T') )
|
Chris@102
|
250 {
|
Chris@102
|
251 return m == 'F';
|
Chris@102
|
252 }
|
Chris@102
|
253 return false;
|
Chris@102
|
254 }
|
Chris@102
|
255 };
|
Chris@102
|
256
|
Chris@102
|
257 template <typename Masks, int I = 0, int N = boost::tuples::length<Masks>::value>
|
Chris@102
|
258 struct interrupt_dispatch_tuple
|
Chris@102
|
259 {
|
Chris@102
|
260 template <field F1, field F2, char V>
|
Chris@102
|
261 static inline bool apply(Masks const& masks)
|
Chris@102
|
262 {
|
Chris@102
|
263 typedef typename boost::tuples::element<I, Masks>::type mask_type;
|
Chris@102
|
264 mask_type const& mask = boost::get<I>(masks);
|
Chris@102
|
265 return interrupt_dispatch<mask_type, true>::template apply<F1, F2, V>(mask)
|
Chris@102
|
266 && interrupt_dispatch_tuple<Masks, I+1>::template apply<F1, F2, V>(masks);
|
Chris@102
|
267 }
|
Chris@102
|
268 };
|
Chris@102
|
269
|
Chris@102
|
270 template <typename Masks, int N>
|
Chris@102
|
271 struct interrupt_dispatch_tuple<Masks, N, N>
|
Chris@102
|
272 {
|
Chris@102
|
273 template <field F1, field F2, char V>
|
Chris@102
|
274 static inline bool apply(Masks const& )
|
Chris@102
|
275 {
|
Chris@102
|
276 return true;
|
Chris@102
|
277 }
|
Chris@102
|
278 };
|
Chris@102
|
279
|
Chris@102
|
280 template <typename T0, typename T1, typename T2, typename T3, typename T4,
|
Chris@102
|
281 typename T5, typename T6, typename T7, typename T8, typename T9>
|
Chris@102
|
282 struct interrupt_dispatch<boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>, true>
|
Chris@102
|
283 {
|
Chris@102
|
284 typedef boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> mask_type;
|
Chris@102
|
285
|
Chris@102
|
286 template <field F1, field F2, char V>
|
Chris@102
|
287 static inline bool apply(mask_type const& mask)
|
Chris@102
|
288 {
|
Chris@102
|
289 return interrupt_dispatch_tuple<mask_type>::template apply<F1, F2, V>(mask);
|
Chris@102
|
290 }
|
Chris@102
|
291 };
|
Chris@102
|
292
|
Chris@102
|
293 template <typename Head, typename Tail>
|
Chris@102
|
294 struct interrupt_dispatch<boost::tuples::cons<Head, Tail>, true>
|
Chris@102
|
295 {
|
Chris@102
|
296 typedef boost::tuples::cons<Head, Tail> mask_type;
|
Chris@102
|
297
|
Chris@102
|
298 template <field F1, field F2, char V>
|
Chris@102
|
299 static inline bool apply(mask_type const& mask)
|
Chris@102
|
300 {
|
Chris@102
|
301 return interrupt_dispatch_tuple<mask_type>::template apply<F1, F2, V>(mask);
|
Chris@102
|
302 }
|
Chris@102
|
303 };
|
Chris@102
|
304
|
Chris@102
|
305 template <field F1, field F2, char V, bool InterruptEnabled, typename Mask>
|
Chris@102
|
306 inline bool interrupt(Mask const& mask)
|
Chris@102
|
307 {
|
Chris@102
|
308 return interrupt_dispatch<Mask, InterruptEnabled>
|
Chris@102
|
309 ::template apply<F1, F2, V>(mask);
|
Chris@102
|
310 }
|
Chris@102
|
311
|
Chris@102
|
312 // may_update()
|
Chris@102
|
313
|
Chris@102
|
314 template <typename Mask>
|
Chris@102
|
315 struct may_update_dispatch
|
Chris@102
|
316 {
|
Chris@102
|
317 template <field F1, field F2, char D, typename Matrix>
|
Chris@102
|
318 static inline bool apply(Mask const& mask, Matrix const& matrix)
|
Chris@102
|
319 {
|
Chris@102
|
320 BOOST_STATIC_ASSERT('0' <= D && D <= '9');
|
Chris@102
|
321
|
Chris@102
|
322 char const m = mask.template get<F1, F2>();
|
Chris@102
|
323
|
Chris@102
|
324 if ( m == 'F' )
|
Chris@102
|
325 {
|
Chris@102
|
326 return true;
|
Chris@102
|
327 }
|
Chris@102
|
328 else if ( m == 'T' )
|
Chris@102
|
329 {
|
Chris@102
|
330 char const c = matrix.template get<F1, F2>();
|
Chris@102
|
331 return c == 'F'; // if it's T or between 0 and 9, the result will be the same
|
Chris@102
|
332 }
|
Chris@102
|
333 else if ( m >= '0' && m <= '9' )
|
Chris@102
|
334 {
|
Chris@102
|
335 char const c = matrix.template get<F1, F2>();
|
Chris@102
|
336 return D > c || c > '9';
|
Chris@102
|
337 }
|
Chris@102
|
338
|
Chris@102
|
339 return false;
|
Chris@102
|
340 }
|
Chris@102
|
341 };
|
Chris@102
|
342
|
Chris@102
|
343 template <typename Masks, int I = 0, int N = boost::tuples::length<Masks>::value>
|
Chris@102
|
344 struct may_update_dispatch_tuple
|
Chris@102
|
345 {
|
Chris@102
|
346 template <field F1, field F2, char D, typename Matrix>
|
Chris@102
|
347 static inline bool apply(Masks const& masks, Matrix const& matrix)
|
Chris@102
|
348 {
|
Chris@102
|
349 typedef typename boost::tuples::element<I, Masks>::type mask_type;
|
Chris@102
|
350 mask_type const& mask = boost::get<I>(masks);
|
Chris@102
|
351 return may_update_dispatch<mask_type>::template apply<F1, F2, D>(mask, matrix)
|
Chris@102
|
352 || may_update_dispatch_tuple<Masks, I+1>::template apply<F1, F2, D>(masks, matrix);
|
Chris@102
|
353 }
|
Chris@102
|
354 };
|
Chris@102
|
355
|
Chris@102
|
356 template <typename Masks, int N>
|
Chris@102
|
357 struct may_update_dispatch_tuple<Masks, N, N>
|
Chris@102
|
358 {
|
Chris@102
|
359 template <field F1, field F2, char D, typename Matrix>
|
Chris@102
|
360 static inline bool apply(Masks const& , Matrix const& )
|
Chris@102
|
361 {
|
Chris@102
|
362 return false;
|
Chris@102
|
363 }
|
Chris@102
|
364 };
|
Chris@102
|
365
|
Chris@102
|
366 template <typename T0, typename T1, typename T2, typename T3, typename T4,
|
Chris@102
|
367 typename T5, typename T6, typename T7, typename T8, typename T9>
|
Chris@102
|
368 struct may_update_dispatch< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >
|
Chris@102
|
369 {
|
Chris@102
|
370 typedef boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> mask_type;
|
Chris@102
|
371
|
Chris@102
|
372 template <field F1, field F2, char D, typename Matrix>
|
Chris@102
|
373 static inline bool apply(mask_type const& mask, Matrix const& matrix)
|
Chris@102
|
374 {
|
Chris@102
|
375 return may_update_dispatch_tuple<mask_type>::template apply<F1, F2, D>(mask, matrix);
|
Chris@102
|
376 }
|
Chris@102
|
377 };
|
Chris@102
|
378
|
Chris@102
|
379 template <typename Head, typename Tail>
|
Chris@102
|
380 struct may_update_dispatch< boost::tuples::cons<Head, Tail> >
|
Chris@102
|
381 {
|
Chris@102
|
382 typedef boost::tuples::cons<Head, Tail> mask_type;
|
Chris@102
|
383
|
Chris@102
|
384 template <field F1, field F2, char D, typename Matrix>
|
Chris@102
|
385 static inline bool apply(mask_type const& mask, Matrix const& matrix)
|
Chris@102
|
386 {
|
Chris@102
|
387 return may_update_dispatch_tuple<mask_type>::template apply<F1, F2, D>(mask, matrix);
|
Chris@102
|
388 }
|
Chris@102
|
389 };
|
Chris@102
|
390
|
Chris@102
|
391 template <field F1, field F2, char D, typename Mask, typename Matrix>
|
Chris@102
|
392 inline bool may_update(Mask const& mask, Matrix const& matrix)
|
Chris@102
|
393 {
|
Chris@102
|
394 return may_update_dispatch<Mask>
|
Chris@102
|
395 ::template apply<F1, F2, D>(mask, matrix);
|
Chris@102
|
396 }
|
Chris@102
|
397
|
Chris@102
|
398 // check_matrix()
|
Chris@102
|
399
|
Chris@102
|
400 template <typename Mask>
|
Chris@102
|
401 struct check_dispatch
|
Chris@102
|
402 {
|
Chris@102
|
403 template <typename Matrix>
|
Chris@102
|
404 static inline bool apply(Mask const& mask, Matrix const& matrix)
|
Chris@102
|
405 {
|
Chris@102
|
406 return per_one<interior, interior>(mask, matrix)
|
Chris@102
|
407 && per_one<interior, boundary>(mask, matrix)
|
Chris@102
|
408 && per_one<interior, exterior>(mask, matrix)
|
Chris@102
|
409 && per_one<boundary, interior>(mask, matrix)
|
Chris@102
|
410 && per_one<boundary, boundary>(mask, matrix)
|
Chris@102
|
411 && per_one<boundary, exterior>(mask, matrix)
|
Chris@102
|
412 && per_one<exterior, interior>(mask, matrix)
|
Chris@102
|
413 && per_one<exterior, boundary>(mask, matrix)
|
Chris@102
|
414 && per_one<exterior, exterior>(mask, matrix);
|
Chris@102
|
415 }
|
Chris@102
|
416
|
Chris@102
|
417 template <field F1, field F2, typename Matrix>
|
Chris@102
|
418 static inline bool per_one(Mask const& mask, Matrix const& matrix)
|
Chris@102
|
419 {
|
Chris@102
|
420 const char mask_el = mask.template get<F1, F2>();
|
Chris@102
|
421 const char el = matrix.template get<F1, F2>();
|
Chris@102
|
422
|
Chris@102
|
423 if ( mask_el == 'F' )
|
Chris@102
|
424 {
|
Chris@102
|
425 return el == 'F';
|
Chris@102
|
426 }
|
Chris@102
|
427 else if ( mask_el == 'T' )
|
Chris@102
|
428 {
|
Chris@102
|
429 return el == 'T' || ( el >= '0' && el <= '9' );
|
Chris@102
|
430 }
|
Chris@102
|
431 else if ( mask_el >= '0' && mask_el <= '9' )
|
Chris@102
|
432 {
|
Chris@102
|
433 return el == mask_el;
|
Chris@102
|
434 }
|
Chris@102
|
435
|
Chris@102
|
436 return true;
|
Chris@102
|
437 }
|
Chris@102
|
438 };
|
Chris@102
|
439
|
Chris@102
|
440 template <typename Masks, int I = 0, int N = boost::tuples::length<Masks>::value>
|
Chris@102
|
441 struct check_dispatch_tuple
|
Chris@102
|
442 {
|
Chris@102
|
443 template <typename Matrix>
|
Chris@102
|
444 static inline bool apply(Masks const& masks, Matrix const& matrix)
|
Chris@102
|
445 {
|
Chris@102
|
446 typedef typename boost::tuples::element<I, Masks>::type mask_type;
|
Chris@102
|
447 mask_type const& mask = boost::get<I>(masks);
|
Chris@102
|
448 return check_dispatch<mask_type>::apply(mask, matrix)
|
Chris@102
|
449 || check_dispatch_tuple<Masks, I+1>::apply(masks, matrix);
|
Chris@102
|
450 }
|
Chris@102
|
451 };
|
Chris@102
|
452
|
Chris@102
|
453 template <typename Masks, int N>
|
Chris@102
|
454 struct check_dispatch_tuple<Masks, N, N>
|
Chris@102
|
455 {
|
Chris@102
|
456 template <typename Matrix>
|
Chris@102
|
457 static inline bool apply(Masks const&, Matrix const&)
|
Chris@102
|
458 {
|
Chris@102
|
459 return false;
|
Chris@102
|
460 }
|
Chris@102
|
461 };
|
Chris@102
|
462
|
Chris@102
|
463 template <typename T0, typename T1, typename T2, typename T3, typename T4,
|
Chris@102
|
464 typename T5, typename T6, typename T7, typename T8, typename T9>
|
Chris@102
|
465 struct check_dispatch< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >
|
Chris@102
|
466 {
|
Chris@102
|
467 typedef boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> mask_type;
|
Chris@102
|
468
|
Chris@102
|
469 template <typename Matrix>
|
Chris@102
|
470 static inline bool apply(mask_type const& mask, Matrix const& matrix)
|
Chris@102
|
471 {
|
Chris@102
|
472 return check_dispatch_tuple<mask_type>::apply(mask, matrix);
|
Chris@102
|
473 }
|
Chris@102
|
474 };
|
Chris@102
|
475
|
Chris@102
|
476 template <typename Head, typename Tail>
|
Chris@102
|
477 struct check_dispatch< boost::tuples::cons<Head, Tail> >
|
Chris@102
|
478 {
|
Chris@102
|
479 typedef boost::tuples::cons<Head, Tail> mask_type;
|
Chris@102
|
480
|
Chris@102
|
481 template <typename Matrix>
|
Chris@102
|
482 static inline bool apply(mask_type const& mask, Matrix const& matrix)
|
Chris@102
|
483 {
|
Chris@102
|
484 return check_dispatch_tuple<mask_type>::apply(mask, matrix);
|
Chris@102
|
485 }
|
Chris@102
|
486 };
|
Chris@102
|
487
|
Chris@102
|
488 template <typename Mask, typename Matrix>
|
Chris@102
|
489 inline bool check_matrix(Mask const& mask, Matrix const& matrix)
|
Chris@102
|
490 {
|
Chris@102
|
491 return check_dispatch<Mask>::apply(mask, matrix);
|
Chris@102
|
492 }
|
Chris@102
|
493
|
Chris@102
|
494 // matrix_width
|
Chris@102
|
495
|
Chris@102
|
496 template <>
|
Chris@102
|
497 struct matrix_width<mask9>
|
Chris@102
|
498 {
|
Chris@102
|
499 static const std::size_t value = 3;
|
Chris@102
|
500 };
|
Chris@102
|
501
|
Chris@102
|
502 template <typename Tuple,
|
Chris@102
|
503 int I = 0,
|
Chris@102
|
504 int N = boost::tuples::length<Tuple>::value>
|
Chris@102
|
505 struct matrix_width_tuple
|
Chris@102
|
506 {
|
Chris@102
|
507 static const std::size_t
|
Chris@102
|
508 current = matrix_width<typename boost::tuples::element<I, Tuple>::type>::value;
|
Chris@102
|
509 static const std::size_t
|
Chris@102
|
510 next = matrix_width_tuple<Tuple, I+1>::value;
|
Chris@102
|
511
|
Chris@102
|
512 static const std::size_t
|
Chris@102
|
513 value = current > next ? current : next;
|
Chris@102
|
514 };
|
Chris@102
|
515
|
Chris@102
|
516 template <typename Tuple, int N>
|
Chris@102
|
517 struct matrix_width_tuple<Tuple, N, N>
|
Chris@102
|
518 {
|
Chris@102
|
519 static const std::size_t value = 0;
|
Chris@102
|
520 };
|
Chris@102
|
521
|
Chris@102
|
522 template <typename Head, typename Tail>
|
Chris@102
|
523 struct matrix_width< boost::tuples::cons<Head, Tail> >
|
Chris@102
|
524 {
|
Chris@102
|
525 static const std::size_t
|
Chris@102
|
526 value = matrix_width_tuple< boost::tuples::cons<Head, Tail> >::value;
|
Chris@102
|
527 };
|
Chris@102
|
528
|
Chris@102
|
529 // matrix_handler
|
Chris@102
|
530
|
Chris@102
|
531 template <typename Mask, bool Interrupt>
|
Chris@102
|
532 class mask_handler
|
Chris@102
|
533 : private matrix<matrix_width<Mask>::value>
|
Chris@102
|
534 {
|
Chris@102
|
535 typedef matrix<matrix_width<Mask>::value> base_t;
|
Chris@102
|
536
|
Chris@102
|
537 public:
|
Chris@102
|
538 typedef bool result_type;
|
Chris@102
|
539
|
Chris@102
|
540 bool interrupt;
|
Chris@102
|
541
|
Chris@102
|
542 inline mask_handler(Mask const& m)
|
Chris@102
|
543 : interrupt(false)
|
Chris@102
|
544 , m_mask(m)
|
Chris@102
|
545 {}
|
Chris@102
|
546
|
Chris@102
|
547 result_type result() const
|
Chris@102
|
548 {
|
Chris@102
|
549 return !interrupt
|
Chris@102
|
550 && check_matrix(m_mask, static_cast<base_t const&>(*this));
|
Chris@102
|
551 }
|
Chris@102
|
552
|
Chris@102
|
553 template <field F1, field F2, char D>
|
Chris@102
|
554 inline bool may_update() const
|
Chris@102
|
555 {
|
Chris@102
|
556 return detail::relate::may_update<F1, F2, D>(
|
Chris@102
|
557 m_mask, static_cast<base_t const&>(*this)
|
Chris@102
|
558 );
|
Chris@102
|
559 }
|
Chris@102
|
560
|
Chris@102
|
561 //template <field F1, field F2>
|
Chris@102
|
562 //inline char get() const
|
Chris@102
|
563 //{
|
Chris@102
|
564 // return static_cast<base_t const&>(*this).template get<F1, F2>();
|
Chris@102
|
565 //}
|
Chris@102
|
566
|
Chris@102
|
567 template <field F1, field F2, char V>
|
Chris@102
|
568 inline void set()
|
Chris@102
|
569 {
|
Chris@102
|
570 if ( relate::interrupt<F1, F2, V, Interrupt>(m_mask) )
|
Chris@102
|
571 {
|
Chris@102
|
572 interrupt = true;
|
Chris@102
|
573 }
|
Chris@102
|
574 else
|
Chris@102
|
575 {
|
Chris@102
|
576 base_t::template set<F1, F2, V>();
|
Chris@102
|
577 }
|
Chris@102
|
578 }
|
Chris@102
|
579
|
Chris@102
|
580 template <field F1, field F2, char V>
|
Chris@102
|
581 inline void update()
|
Chris@102
|
582 {
|
Chris@102
|
583 if ( relate::interrupt<F1, F2, V, Interrupt>(m_mask) )
|
Chris@102
|
584 {
|
Chris@102
|
585 interrupt = true;
|
Chris@102
|
586 }
|
Chris@102
|
587 else
|
Chris@102
|
588 {
|
Chris@102
|
589 base_t::template update<F1, F2, V>();
|
Chris@102
|
590 }
|
Chris@102
|
591 }
|
Chris@102
|
592
|
Chris@102
|
593 private:
|
Chris@102
|
594 Mask const& m_mask;
|
Chris@102
|
595 };
|
Chris@102
|
596
|
Chris@102
|
597 // STATIC MASKS
|
Chris@102
|
598
|
Chris@102
|
599 // static_mask
|
Chris@102
|
600
|
Chris@102
|
601 template <char II, char IB, char IE,
|
Chris@102
|
602 char BI, char BB, char BE,
|
Chris@102
|
603 char EI, char EB, char EE>
|
Chris@102
|
604 class static_mask
|
Chris@102
|
605 {
|
Chris@102
|
606 typedef boost::mpl::vector_c
|
Chris@102
|
607 <
|
Chris@102
|
608 char, II, IB, IE, BI, BB, BE, EI, EB, EE
|
Chris@102
|
609 > vector_type;
|
Chris@102
|
610
|
Chris@102
|
611 public:
|
Chris@102
|
612 template <field F1, field F2>
|
Chris@102
|
613 struct get
|
Chris@102
|
614 {
|
Chris@102
|
615 BOOST_STATIC_ASSERT(F1 * 3 + F2 < boost::mpl::size<vector_type>::value);
|
Chris@102
|
616
|
Chris@102
|
617 static const char value
|
Chris@102
|
618 = boost::mpl::at_c<vector_type, F1 * 3 + F2>::type::value;
|
Chris@102
|
619 };
|
Chris@102
|
620 };
|
Chris@102
|
621
|
Chris@102
|
622 // static_should_handle_element
|
Chris@102
|
623
|
Chris@102
|
624 template <typename StaticMask, field F1, field F2, bool IsSequence>
|
Chris@102
|
625 struct static_should_handle_element_dispatch
|
Chris@102
|
626 {
|
Chris@102
|
627 static const char mask_el = StaticMask::template get<F1, F2>::value;
|
Chris@102
|
628 static const bool value = mask_el == 'F'
|
Chris@102
|
629 || mask_el == 'T'
|
Chris@102
|
630 || ( mask_el >= '0' && mask_el <= '9' );
|
Chris@102
|
631 };
|
Chris@102
|
632
|
Chris@102
|
633 template <typename First, typename Last, field F1, field F2>
|
Chris@102
|
634 struct static_should_handle_element_sequence
|
Chris@102
|
635 {
|
Chris@102
|
636 typedef typename boost::mpl::deref<First>::type StaticMask;
|
Chris@102
|
637
|
Chris@102
|
638 static const bool value
|
Chris@102
|
639 = static_should_handle_element_dispatch
|
Chris@102
|
640 <
|
Chris@102
|
641 StaticMask,
|
Chris@102
|
642 F1, F2,
|
Chris@102
|
643 boost::mpl::is_sequence<StaticMask>::value
|
Chris@102
|
644 >::value
|
Chris@102
|
645 || static_should_handle_element_sequence
|
Chris@102
|
646 <
|
Chris@102
|
647 typename boost::mpl::next<First>::type,
|
Chris@102
|
648 Last,
|
Chris@102
|
649 F1, F2
|
Chris@102
|
650 >::value;
|
Chris@102
|
651 };
|
Chris@102
|
652
|
Chris@102
|
653 template <typename Last, field F1, field F2>
|
Chris@102
|
654 struct static_should_handle_element_sequence<Last, Last, F1, F2>
|
Chris@102
|
655 {
|
Chris@102
|
656 static const bool value = false;
|
Chris@102
|
657 };
|
Chris@102
|
658
|
Chris@102
|
659 template <typename StaticMask, field F1, field F2>
|
Chris@102
|
660 struct static_should_handle_element_dispatch<StaticMask, F1, F2, true>
|
Chris@102
|
661 {
|
Chris@102
|
662 static const bool value
|
Chris@102
|
663 = static_should_handle_element_sequence
|
Chris@102
|
664 <
|
Chris@102
|
665 typename boost::mpl::begin<StaticMask>::type,
|
Chris@102
|
666 typename boost::mpl::end<StaticMask>::type,
|
Chris@102
|
667 F1, F2
|
Chris@102
|
668 >::value;
|
Chris@102
|
669 };
|
Chris@102
|
670
|
Chris@102
|
671 template <typename StaticMask, field F1, field F2>
|
Chris@102
|
672 struct static_should_handle_element
|
Chris@102
|
673 {
|
Chris@102
|
674 static const bool value
|
Chris@102
|
675 = static_should_handle_element_dispatch
|
Chris@102
|
676 <
|
Chris@102
|
677 StaticMask,
|
Chris@102
|
678 F1, F2,
|
Chris@102
|
679 boost::mpl::is_sequence<StaticMask>::value
|
Chris@102
|
680 >::value;
|
Chris@102
|
681 };
|
Chris@102
|
682
|
Chris@102
|
683 // static_interrupt
|
Chris@102
|
684
|
Chris@102
|
685 template <typename StaticMask, char V, field F1, field F2, bool InterruptEnabled, bool IsSequence>
|
Chris@102
|
686 struct static_interrupt_dispatch
|
Chris@102
|
687 {
|
Chris@102
|
688 static const bool value = false;
|
Chris@102
|
689 };
|
Chris@102
|
690
|
Chris@102
|
691 template <typename StaticMask, char V, field F1, field F2, bool IsSequence>
|
Chris@102
|
692 struct static_interrupt_dispatch<StaticMask, V, F1, F2, true, IsSequence>
|
Chris@102
|
693 {
|
Chris@102
|
694 static const char mask_el = StaticMask::template get<F1, F2>::value;
|
Chris@102
|
695
|
Chris@102
|
696 static const bool value
|
Chris@102
|
697 = ( V >= '0' && V <= '9' ) ?
|
Chris@102
|
698 ( mask_el == 'F' || ( mask_el < V && mask_el >= '0' && mask_el <= '9' ) ) :
|
Chris@102
|
699 ( ( V == 'T' ) ? mask_el == 'F' : false );
|
Chris@102
|
700 };
|
Chris@102
|
701
|
Chris@102
|
702 template <typename First, typename Last, char V, field F1, field F2>
|
Chris@102
|
703 struct static_interrupt_sequence
|
Chris@102
|
704 {
|
Chris@102
|
705 typedef typename boost::mpl::deref<First>::type StaticMask;
|
Chris@102
|
706
|
Chris@102
|
707 static const bool value
|
Chris@102
|
708 = static_interrupt_dispatch
|
Chris@102
|
709 <
|
Chris@102
|
710 StaticMask,
|
Chris@102
|
711 V, F1, F2,
|
Chris@102
|
712 true,
|
Chris@102
|
713 boost::mpl::is_sequence<StaticMask>::value
|
Chris@102
|
714 >::value
|
Chris@102
|
715 && static_interrupt_sequence
|
Chris@102
|
716 <
|
Chris@102
|
717 typename boost::mpl::next<First>::type,
|
Chris@102
|
718 Last,
|
Chris@102
|
719 V, F1, F2
|
Chris@102
|
720 >::value;
|
Chris@102
|
721 };
|
Chris@102
|
722
|
Chris@102
|
723 template <typename Last, char V, field F1, field F2>
|
Chris@102
|
724 struct static_interrupt_sequence<Last, Last, V, F1, F2>
|
Chris@102
|
725 {
|
Chris@102
|
726 static const bool value = true;
|
Chris@102
|
727 };
|
Chris@102
|
728
|
Chris@102
|
729 template <typename StaticMask, char V, field F1, field F2>
|
Chris@102
|
730 struct static_interrupt_dispatch<StaticMask, V, F1, F2, true, true>
|
Chris@102
|
731 {
|
Chris@102
|
732 static const bool value
|
Chris@102
|
733 = static_interrupt_sequence
|
Chris@102
|
734 <
|
Chris@102
|
735 typename boost::mpl::begin<StaticMask>::type,
|
Chris@102
|
736 typename boost::mpl::end<StaticMask>::type,
|
Chris@102
|
737 V, F1, F2
|
Chris@102
|
738 >::value;
|
Chris@102
|
739 };
|
Chris@102
|
740
|
Chris@102
|
741 template <typename StaticMask, char V, field F1, field F2, bool EnableInterrupt>
|
Chris@102
|
742 struct static_interrupt
|
Chris@102
|
743 {
|
Chris@102
|
744 static const bool value
|
Chris@102
|
745 = static_interrupt_dispatch
|
Chris@102
|
746 <
|
Chris@102
|
747 StaticMask,
|
Chris@102
|
748 V, F1, F2,
|
Chris@102
|
749 EnableInterrupt,
|
Chris@102
|
750 boost::mpl::is_sequence<StaticMask>::value
|
Chris@102
|
751 >::value;
|
Chris@102
|
752 };
|
Chris@102
|
753
|
Chris@102
|
754 // static_may_update
|
Chris@102
|
755
|
Chris@102
|
756 template <typename StaticMask, char D, field F1, field F2, bool IsSequence>
|
Chris@102
|
757 struct static_may_update_dispatch
|
Chris@102
|
758 {
|
Chris@102
|
759 static const char mask_el = StaticMask::template get<F1, F2>::value;
|
Chris@102
|
760 static const int version
|
Chris@102
|
761 = mask_el == 'F' ? 0
|
Chris@102
|
762 : mask_el == 'T' ? 1
|
Chris@102
|
763 : mask_el >= '0' && mask_el <= '9' ? 2
|
Chris@102
|
764 : 3;
|
Chris@102
|
765
|
Chris@102
|
766 template <typename Matrix>
|
Chris@102
|
767 static inline bool apply(Matrix const& matrix)
|
Chris@102
|
768 {
|
Chris@102
|
769 return apply_dispatch(matrix, integral_constant<int, version>());
|
Chris@102
|
770 }
|
Chris@102
|
771
|
Chris@102
|
772 // mask_el == 'F'
|
Chris@102
|
773 template <typename Matrix>
|
Chris@102
|
774 static inline bool apply_dispatch(Matrix const& , integral_constant<int, 0>)
|
Chris@102
|
775 {
|
Chris@102
|
776 return true;
|
Chris@102
|
777 }
|
Chris@102
|
778 // mask_el == 'T'
|
Chris@102
|
779 template <typename Matrix>
|
Chris@102
|
780 static inline bool apply_dispatch(Matrix const& matrix, integral_constant<int, 1>)
|
Chris@102
|
781 {
|
Chris@102
|
782 char const c = matrix.template get<F1, F2>();
|
Chris@102
|
783 return c == 'F'; // if it's T or between 0 and 9, the result will be the same
|
Chris@102
|
784 }
|
Chris@102
|
785 // mask_el >= '0' && mask_el <= '9'
|
Chris@102
|
786 template <typename Matrix>
|
Chris@102
|
787 static inline bool apply_dispatch(Matrix const& matrix, integral_constant<int, 2>)
|
Chris@102
|
788 {
|
Chris@102
|
789 char const c = matrix.template get<F1, F2>();
|
Chris@102
|
790 return D > c || c > '9';
|
Chris@102
|
791 }
|
Chris@102
|
792 // else
|
Chris@102
|
793 template <typename Matrix>
|
Chris@102
|
794 static inline bool apply_dispatch(Matrix const&, integral_constant<int, 3>)
|
Chris@102
|
795 {
|
Chris@102
|
796 return false;
|
Chris@102
|
797 }
|
Chris@102
|
798 };
|
Chris@102
|
799
|
Chris@102
|
800 template <typename First, typename Last, char D, field F1, field F2>
|
Chris@102
|
801 struct static_may_update_sequence
|
Chris@102
|
802 {
|
Chris@102
|
803 typedef typename boost::mpl::deref<First>::type StaticMask;
|
Chris@102
|
804
|
Chris@102
|
805 template <typename Matrix>
|
Chris@102
|
806 static inline bool apply(Matrix const& matrix)
|
Chris@102
|
807 {
|
Chris@102
|
808 return static_may_update_dispatch
|
Chris@102
|
809 <
|
Chris@102
|
810 StaticMask,
|
Chris@102
|
811 D, F1, F2,
|
Chris@102
|
812 boost::mpl::is_sequence<StaticMask>::value
|
Chris@102
|
813 >::apply(matrix)
|
Chris@102
|
814 || static_may_update_sequence
|
Chris@102
|
815 <
|
Chris@102
|
816 typename boost::mpl::next<First>::type,
|
Chris@102
|
817 Last,
|
Chris@102
|
818 D, F1, F2
|
Chris@102
|
819 >::apply(matrix);
|
Chris@102
|
820 }
|
Chris@102
|
821 };
|
Chris@102
|
822
|
Chris@102
|
823 template <typename Last, char D, field F1, field F2>
|
Chris@102
|
824 struct static_may_update_sequence<Last, Last, D, F1, F2>
|
Chris@102
|
825 {
|
Chris@102
|
826 template <typename Matrix>
|
Chris@102
|
827 static inline bool apply(Matrix const& /*matrix*/)
|
Chris@102
|
828 {
|
Chris@102
|
829 return false;
|
Chris@102
|
830 }
|
Chris@102
|
831 };
|
Chris@102
|
832
|
Chris@102
|
833 template <typename StaticMask, char D, field F1, field F2>
|
Chris@102
|
834 struct static_may_update_dispatch<StaticMask, D, F1, F2, true>
|
Chris@102
|
835 {
|
Chris@102
|
836 template <typename Matrix>
|
Chris@102
|
837 static inline bool apply(Matrix const& matrix)
|
Chris@102
|
838 {
|
Chris@102
|
839 return static_may_update_sequence
|
Chris@102
|
840 <
|
Chris@102
|
841 typename boost::mpl::begin<StaticMask>::type,
|
Chris@102
|
842 typename boost::mpl::end<StaticMask>::type,
|
Chris@102
|
843 D, F1, F2
|
Chris@102
|
844 >::apply(matrix);
|
Chris@102
|
845 }
|
Chris@102
|
846 };
|
Chris@102
|
847
|
Chris@102
|
848 template <typename StaticMask, char D, field F1, field F2>
|
Chris@102
|
849 struct static_may_update
|
Chris@102
|
850 {
|
Chris@102
|
851 template <typename Matrix>
|
Chris@102
|
852 static inline bool apply(Matrix const& matrix)
|
Chris@102
|
853 {
|
Chris@102
|
854 return static_may_update_dispatch
|
Chris@102
|
855 <
|
Chris@102
|
856 StaticMask,
|
Chris@102
|
857 D, F1, F2,
|
Chris@102
|
858 boost::mpl::is_sequence<StaticMask>::value
|
Chris@102
|
859 >::apply(matrix);
|
Chris@102
|
860 }
|
Chris@102
|
861 };
|
Chris@102
|
862
|
Chris@102
|
863 // static_check
|
Chris@102
|
864
|
Chris@102
|
865 template <typename StaticMask, bool IsSequence>
|
Chris@102
|
866 struct static_check_dispatch
|
Chris@102
|
867 {
|
Chris@102
|
868 template <typename Matrix>
|
Chris@102
|
869 static inline bool apply(Matrix const& matrix)
|
Chris@102
|
870 {
|
Chris@102
|
871 return per_one<interior, interior>::apply(matrix)
|
Chris@102
|
872 && per_one<interior, boundary>::apply(matrix)
|
Chris@102
|
873 && per_one<interior, exterior>::apply(matrix)
|
Chris@102
|
874 && per_one<boundary, interior>::apply(matrix)
|
Chris@102
|
875 && per_one<boundary, boundary>::apply(matrix)
|
Chris@102
|
876 && per_one<boundary, exterior>::apply(matrix)
|
Chris@102
|
877 && per_one<exterior, interior>::apply(matrix)
|
Chris@102
|
878 && per_one<exterior, boundary>::apply(matrix)
|
Chris@102
|
879 && per_one<exterior, exterior>::apply(matrix);
|
Chris@102
|
880 }
|
Chris@102
|
881
|
Chris@102
|
882 template <field F1, field F2>
|
Chris@102
|
883 struct per_one
|
Chris@102
|
884 {
|
Chris@102
|
885 static const char mask_el = StaticMask::template get<F1, F2>::value;
|
Chris@102
|
886 static const int version
|
Chris@102
|
887 = mask_el == 'F' ? 0
|
Chris@102
|
888 : mask_el == 'T' ? 1
|
Chris@102
|
889 : mask_el >= '0' && mask_el <= '9' ? 2
|
Chris@102
|
890 : 3;
|
Chris@102
|
891
|
Chris@102
|
892 template <typename Matrix>
|
Chris@102
|
893 static inline bool apply(Matrix const& matrix)
|
Chris@102
|
894 {
|
Chris@102
|
895 const char el = matrix.template get<F1, F2>();
|
Chris@102
|
896 return apply_dispatch(el, integral_constant<int, version>());
|
Chris@102
|
897 }
|
Chris@102
|
898
|
Chris@102
|
899 // mask_el == 'F'
|
Chris@102
|
900 static inline bool apply_dispatch(char el, integral_constant<int, 0>)
|
Chris@102
|
901 {
|
Chris@102
|
902 return el == 'F';
|
Chris@102
|
903 }
|
Chris@102
|
904 // mask_el == 'T'
|
Chris@102
|
905 static inline bool apply_dispatch(char el, integral_constant<int, 1>)
|
Chris@102
|
906 {
|
Chris@102
|
907 return el == 'T' || ( el >= '0' && el <= '9' );
|
Chris@102
|
908 }
|
Chris@102
|
909 // mask_el >= '0' && mask_el <= '9'
|
Chris@102
|
910 static inline bool apply_dispatch(char el, integral_constant<int, 2>)
|
Chris@102
|
911 {
|
Chris@102
|
912 return el == mask_el;
|
Chris@102
|
913 }
|
Chris@102
|
914 // else
|
Chris@102
|
915 static inline bool apply_dispatch(char /*el*/, integral_constant<int, 3>)
|
Chris@102
|
916 {
|
Chris@102
|
917 return true;
|
Chris@102
|
918 }
|
Chris@102
|
919 };
|
Chris@102
|
920 };
|
Chris@102
|
921
|
Chris@102
|
922 template <typename First, typename Last>
|
Chris@102
|
923 struct static_check_sequence
|
Chris@102
|
924 {
|
Chris@102
|
925 typedef typename boost::mpl::deref<First>::type StaticMask;
|
Chris@102
|
926
|
Chris@102
|
927 template <typename Matrix>
|
Chris@102
|
928 static inline bool apply(Matrix const& matrix)
|
Chris@102
|
929 {
|
Chris@102
|
930 return static_check_dispatch
|
Chris@102
|
931 <
|
Chris@102
|
932 StaticMask,
|
Chris@102
|
933 boost::mpl::is_sequence<StaticMask>::value
|
Chris@102
|
934 >::apply(matrix)
|
Chris@102
|
935 || static_check_sequence
|
Chris@102
|
936 <
|
Chris@102
|
937 typename boost::mpl::next<First>::type,
|
Chris@102
|
938 Last
|
Chris@102
|
939 >::apply(matrix);
|
Chris@102
|
940 }
|
Chris@102
|
941 };
|
Chris@102
|
942
|
Chris@102
|
943 template <typename Last>
|
Chris@102
|
944 struct static_check_sequence<Last, Last>
|
Chris@102
|
945 {
|
Chris@102
|
946 template <typename Matrix>
|
Chris@102
|
947 static inline bool apply(Matrix const& /*matrix*/)
|
Chris@102
|
948 {
|
Chris@102
|
949 return false;
|
Chris@102
|
950 }
|
Chris@102
|
951 };
|
Chris@102
|
952
|
Chris@102
|
953 template <typename StaticMask>
|
Chris@102
|
954 struct static_check_dispatch<StaticMask, true>
|
Chris@102
|
955 {
|
Chris@102
|
956 template <typename Matrix>
|
Chris@102
|
957 static inline bool apply(Matrix const& matrix)
|
Chris@102
|
958 {
|
Chris@102
|
959 return static_check_sequence
|
Chris@102
|
960 <
|
Chris@102
|
961 typename boost::mpl::begin<StaticMask>::type,
|
Chris@102
|
962 typename boost::mpl::end<StaticMask>::type
|
Chris@102
|
963 >::apply(matrix);
|
Chris@102
|
964 }
|
Chris@102
|
965 };
|
Chris@102
|
966
|
Chris@102
|
967 template <typename StaticMask>
|
Chris@102
|
968 struct static_check_matrix
|
Chris@102
|
969 {
|
Chris@102
|
970 template <typename Matrix>
|
Chris@102
|
971 static inline bool apply(Matrix const& matrix)
|
Chris@102
|
972 {
|
Chris@102
|
973 return static_check_dispatch
|
Chris@102
|
974 <
|
Chris@102
|
975 StaticMask,
|
Chris@102
|
976 boost::mpl::is_sequence<StaticMask>::value
|
Chris@102
|
977 >::apply(matrix);
|
Chris@102
|
978 }
|
Chris@102
|
979 };
|
Chris@102
|
980
|
Chris@102
|
981 // static_mask_handler
|
Chris@102
|
982
|
Chris@102
|
983 template <typename StaticMask, bool Interrupt>
|
Chris@102
|
984 class static_mask_handler
|
Chris@102
|
985 : private matrix<3>
|
Chris@102
|
986 {
|
Chris@102
|
987 typedef matrix<3> base_t;
|
Chris@102
|
988
|
Chris@102
|
989 public:
|
Chris@102
|
990 typedef bool result_type;
|
Chris@102
|
991
|
Chris@102
|
992 bool interrupt;
|
Chris@102
|
993
|
Chris@102
|
994 inline static_mask_handler(StaticMask const& /*dummy*/)
|
Chris@102
|
995 : interrupt(false)
|
Chris@102
|
996 {}
|
Chris@102
|
997
|
Chris@102
|
998 result_type result() const
|
Chris@102
|
999 {
|
Chris@102
|
1000 return (!Interrupt || !interrupt)
|
Chris@102
|
1001 && static_check_matrix<StaticMask>::
|
Chris@102
|
1002 apply(static_cast<base_t const&>(*this));
|
Chris@102
|
1003 }
|
Chris@102
|
1004
|
Chris@102
|
1005 template <field F1, field F2, char D>
|
Chris@102
|
1006 inline bool may_update() const
|
Chris@102
|
1007 {
|
Chris@102
|
1008 return static_may_update<StaticMask, D, F1, F2>::
|
Chris@102
|
1009 apply(static_cast<base_t const&>(*this));
|
Chris@102
|
1010 }
|
Chris@102
|
1011
|
Chris@102
|
1012 template <field F1, field F2>
|
Chris@102
|
1013 static inline bool expects()
|
Chris@102
|
1014 {
|
Chris@102
|
1015 return static_should_handle_element<StaticMask, F1, F2>::value;
|
Chris@102
|
1016 }
|
Chris@102
|
1017
|
Chris@102
|
1018 //template <field F1, field F2>
|
Chris@102
|
1019 //inline char get() const
|
Chris@102
|
1020 //{
|
Chris@102
|
1021 // return base_t::template get<F1, F2>();
|
Chris@102
|
1022 //}
|
Chris@102
|
1023
|
Chris@102
|
1024 template <field F1, field F2, char V>
|
Chris@102
|
1025 inline void set()
|
Chris@102
|
1026 {
|
Chris@102
|
1027 static const bool interrupt_c = static_interrupt<StaticMask, V, F1, F2, Interrupt>::value;
|
Chris@102
|
1028 static const bool should_handle = static_should_handle_element<StaticMask, F1, F2>::value;
|
Chris@102
|
1029 static const int version = interrupt_c ? 0
|
Chris@102
|
1030 : should_handle ? 1
|
Chris@102
|
1031 : 2;
|
Chris@102
|
1032
|
Chris@102
|
1033 set_dispatch<F1, F2, V>(integral_constant<int, version>());
|
Chris@102
|
1034 }
|
Chris@102
|
1035
|
Chris@102
|
1036 template <field F1, field F2, char V>
|
Chris@102
|
1037 inline void update()
|
Chris@102
|
1038 {
|
Chris@102
|
1039 static const bool interrupt_c = static_interrupt<StaticMask, V, F1, F2, Interrupt>::value;
|
Chris@102
|
1040 static const bool should_handle = static_should_handle_element<StaticMask, F1, F2>::value;
|
Chris@102
|
1041 static const int version = interrupt_c ? 0
|
Chris@102
|
1042 : should_handle ? 1
|
Chris@102
|
1043 : 2;
|
Chris@102
|
1044
|
Chris@102
|
1045 update_dispatch<F1, F2, V>(integral_constant<int, version>());
|
Chris@102
|
1046 }
|
Chris@102
|
1047
|
Chris@102
|
1048 private:
|
Chris@102
|
1049 // Interrupt && interrupt
|
Chris@102
|
1050 template <field F1, field F2, char V>
|
Chris@102
|
1051 inline void set_dispatch(integral_constant<int, 0>)
|
Chris@102
|
1052 {
|
Chris@102
|
1053 interrupt = true;
|
Chris@102
|
1054 }
|
Chris@102
|
1055 // else should_handle
|
Chris@102
|
1056 template <field F1, field F2, char V>
|
Chris@102
|
1057 inline void set_dispatch(integral_constant<int, 1>)
|
Chris@102
|
1058 {
|
Chris@102
|
1059 base_t::template set<F1, F2, V>();
|
Chris@102
|
1060 }
|
Chris@102
|
1061 // else
|
Chris@102
|
1062 template <field F1, field F2, char V>
|
Chris@102
|
1063 inline void set_dispatch(integral_constant<int, 2>)
|
Chris@102
|
1064 {}
|
Chris@102
|
1065
|
Chris@102
|
1066 // Interrupt && interrupt
|
Chris@102
|
1067 template <field F1, field F2, char V>
|
Chris@102
|
1068 inline void update_dispatch(integral_constant<int, 0>)
|
Chris@102
|
1069 {
|
Chris@102
|
1070 interrupt = true;
|
Chris@102
|
1071 }
|
Chris@102
|
1072 // else should_handle
|
Chris@102
|
1073 template <field F1, field F2, char V>
|
Chris@102
|
1074 inline void update_dispatch(integral_constant<int, 1>)
|
Chris@102
|
1075 {
|
Chris@102
|
1076 base_t::template update<F1, F2, V>();
|
Chris@102
|
1077 }
|
Chris@102
|
1078 // else
|
Chris@102
|
1079 template <field F1, field F2, char V>
|
Chris@102
|
1080 inline void update_dispatch(integral_constant<int, 2>)
|
Chris@102
|
1081 {}
|
Chris@102
|
1082 };
|
Chris@102
|
1083
|
Chris@102
|
1084 // OPERATORS
|
Chris@102
|
1085
|
Chris@102
|
1086 template <typename Mask1, typename Mask2> inline
|
Chris@102
|
1087 boost::tuples::cons<
|
Chris@102
|
1088 Mask1,
|
Chris@102
|
1089 boost::tuples::cons<Mask2, boost::tuples::null_type>
|
Chris@102
|
1090 >
|
Chris@102
|
1091 operator||(Mask1 const& m1, Mask2 const& m2)
|
Chris@102
|
1092 {
|
Chris@102
|
1093 namespace bt = boost::tuples;
|
Chris@102
|
1094
|
Chris@102
|
1095 return
|
Chris@102
|
1096 bt::cons< Mask1, bt::cons<Mask2, bt::null_type> >
|
Chris@102
|
1097 ( m1, bt::cons<Mask2, bt::null_type>(m2, bt::null_type()) );
|
Chris@102
|
1098 }
|
Chris@102
|
1099
|
Chris@102
|
1100 template <typename Head, typename Tail, typename Mask> inline
|
Chris@102
|
1101 typename index::detail::tuples::push_back<
|
Chris@102
|
1102 boost::tuples::cons<Head, Tail>, Mask
|
Chris@102
|
1103 >::type
|
Chris@102
|
1104 operator||(boost::tuples::cons<Head, Tail> const& t, Mask const& m)
|
Chris@102
|
1105 {
|
Chris@102
|
1106 namespace bt = boost::tuples;
|
Chris@102
|
1107
|
Chris@102
|
1108 return
|
Chris@102
|
1109 index::detail::tuples::push_back<
|
Chris@102
|
1110 bt::cons<Head, Tail>, Mask
|
Chris@102
|
1111 >::apply(t, m);
|
Chris@102
|
1112 }
|
Chris@102
|
1113
|
Chris@102
|
1114 // PREDEFINED MASKS
|
Chris@102
|
1115
|
Chris@102
|
1116 // TODO:
|
Chris@102
|
1117 // 1. specialize for simplified masks if available
|
Chris@102
|
1118 // e.g. for TOUCHES use 1 mask for A/A
|
Chris@102
|
1119 // 2. Think about dimensions > 2 e.g. should TOUCHES be true
|
Chris@102
|
1120 // if the interior of the Areal overlaps the boundary of the Volumetric
|
Chris@102
|
1121 // like it's true for Linear/Areal
|
Chris@102
|
1122
|
Chris@102
|
1123 // EQUALS
|
Chris@102
|
1124 template <typename Geometry1, typename Geometry2>
|
Chris@102
|
1125 struct static_mask_equals_type
|
Chris@102
|
1126 {
|
Chris@102
|
1127 typedef static_mask<'T', '*', 'F', '*', '*', 'F', 'F', 'F', '*'> type; // wikipedia
|
Chris@102
|
1128 //typedef static_mask<'T', 'F', 'F', 'F', 'T', 'F', 'F', 'F', 'T'> type; // OGC
|
Chris@102
|
1129 };
|
Chris@102
|
1130
|
Chris@102
|
1131 // DISJOINT
|
Chris@102
|
1132 typedef static_mask<'F', 'F', '*', 'F', 'F', '*', '*', '*', '*'> static_mask_disjoint;
|
Chris@102
|
1133
|
Chris@102
|
1134 // TOUCHES - NOT P/P
|
Chris@102
|
1135 template <typename Geometry1,
|
Chris@102
|
1136 typename Geometry2,
|
Chris@102
|
1137 std::size_t Dim1 = topological_dimension<Geometry1>::value,
|
Chris@102
|
1138 std::size_t Dim2 = topological_dimension<Geometry2>::value>
|
Chris@102
|
1139 struct static_mask_touches_impl
|
Chris@102
|
1140 {
|
Chris@102
|
1141 typedef boost::mpl::vector<
|
Chris@102
|
1142 static_mask<'F', 'T', '*', '*', '*', '*', '*', '*', '*'>,
|
Chris@102
|
1143 static_mask<'F', '*', '*', 'T', '*', '*', '*', '*', '*'>,
|
Chris@102
|
1144 static_mask<'F', '*', '*', '*', 'T', '*', '*', '*', '*'>
|
Chris@102
|
1145 > type;
|
Chris@102
|
1146 };
|
Chris@102
|
1147 // According to OGC, doesn't apply to P/P
|
Chris@102
|
1148 // Using the above mask the result would be always false
|
Chris@102
|
1149 template <typename Geometry1, typename Geometry2>
|
Chris@102
|
1150 struct static_mask_touches_impl<Geometry1, Geometry2, 0, 0>
|
Chris@102
|
1151 : not_implemented<typename geometry::tag<Geometry1>::type,
|
Chris@102
|
1152 typename geometry::tag<Geometry2>::type>
|
Chris@102
|
1153 {};
|
Chris@102
|
1154
|
Chris@102
|
1155 template <typename Geometry1, typename Geometry2>
|
Chris@102
|
1156 struct static_mask_touches_type
|
Chris@102
|
1157 : static_mask_touches_impl<Geometry1, Geometry2>
|
Chris@102
|
1158 {};
|
Chris@102
|
1159
|
Chris@102
|
1160 // WITHIN
|
Chris@102
|
1161 typedef static_mask<'T', '*', 'F', '*', '*', 'F', '*', '*', '*'> static_mask_within;
|
Chris@102
|
1162
|
Chris@102
|
1163 // COVERED_BY (non OGC)
|
Chris@102
|
1164 typedef boost::mpl::vector<
|
Chris@102
|
1165 static_mask<'T', '*', 'F', '*', '*', 'F', '*', '*', '*'>,
|
Chris@102
|
1166 static_mask<'*', 'T', 'F', '*', '*', 'F', '*', '*', '*'>,
|
Chris@102
|
1167 static_mask<'*', '*', 'F', 'T', '*', 'F', '*', '*', '*'>,
|
Chris@102
|
1168 static_mask<'*', '*', 'F', '*', 'T', 'F', '*', '*', '*'>
|
Chris@102
|
1169 > static_mask_covered_by;
|
Chris@102
|
1170
|
Chris@102
|
1171 // CROSSES
|
Chris@102
|
1172 // dim(G1) < dim(G2) - P/L P/A L/A
|
Chris@102
|
1173 template <typename Geometry1,
|
Chris@102
|
1174 typename Geometry2,
|
Chris@102
|
1175 std::size_t Dim1 = topological_dimension<Geometry1>::value,
|
Chris@102
|
1176 std::size_t Dim2 = topological_dimension<Geometry2>::value,
|
Chris@102
|
1177 bool D1LessD2 = (Dim1 < Dim2)
|
Chris@102
|
1178 >
|
Chris@102
|
1179 struct static_mask_crosses_impl
|
Chris@102
|
1180 {
|
Chris@102
|
1181 typedef static_mask<'T', '*', 'T', '*', '*', '*', '*', '*', '*'> type;
|
Chris@102
|
1182 };
|
Chris@102
|
1183 // TODO: I'm not sure if this one below should be available!
|
Chris@102
|
1184 // dim(G1) > dim(G2) - L/P A/P A/L
|
Chris@102
|
1185 template <typename Geometry1, typename Geometry2,
|
Chris@102
|
1186 std::size_t Dim1, std::size_t Dim2
|
Chris@102
|
1187 >
|
Chris@102
|
1188 struct static_mask_crosses_impl<Geometry1, Geometry2, Dim1, Dim2, false>
|
Chris@102
|
1189 {
|
Chris@102
|
1190 typedef static_mask<'T', '*', '*', '*', '*', '*', 'T', '*', '*'> type;
|
Chris@102
|
1191 };
|
Chris@102
|
1192 // dim(G1) == dim(G2) - P/P A/A
|
Chris@102
|
1193 template <typename Geometry1, typename Geometry2,
|
Chris@102
|
1194 std::size_t Dim
|
Chris@102
|
1195 >
|
Chris@102
|
1196 struct static_mask_crosses_impl<Geometry1, Geometry2, Dim, Dim, false>
|
Chris@102
|
1197 : not_implemented<typename geometry::tag<Geometry1>::type,
|
Chris@102
|
1198 typename geometry::tag<Geometry2>::type>
|
Chris@102
|
1199 {};
|
Chris@102
|
1200 // dim(G1) == 1 && dim(G2) == 1 - L/L
|
Chris@102
|
1201 template <typename Geometry1, typename Geometry2>
|
Chris@102
|
1202 struct static_mask_crosses_impl<Geometry1, Geometry2, 1, 1, false>
|
Chris@102
|
1203 {
|
Chris@102
|
1204 typedef static_mask<'0', '*', '*', '*', '*', '*', '*', '*', '*'> type;
|
Chris@102
|
1205 };
|
Chris@102
|
1206
|
Chris@102
|
1207 template <typename Geometry1, typename Geometry2>
|
Chris@102
|
1208 struct static_mask_crosses_type
|
Chris@102
|
1209 : static_mask_crosses_impl<Geometry1, Geometry2>
|
Chris@102
|
1210 {};
|
Chris@102
|
1211
|
Chris@102
|
1212 // OVERLAPS
|
Chris@102
|
1213
|
Chris@102
|
1214 // dim(G1) != dim(G2) - NOT P/P, L/L, A/A
|
Chris@102
|
1215 template <typename Geometry1,
|
Chris@102
|
1216 typename Geometry2,
|
Chris@102
|
1217 std::size_t Dim1 = topological_dimension<Geometry1>::value,
|
Chris@102
|
1218 std::size_t Dim2 = topological_dimension<Geometry2>::value
|
Chris@102
|
1219 >
|
Chris@102
|
1220 struct static_mask_overlaps_impl
|
Chris@102
|
1221 : not_implemented<typename geometry::tag<Geometry1>::type,
|
Chris@102
|
1222 typename geometry::tag<Geometry2>::type>
|
Chris@102
|
1223 {};
|
Chris@102
|
1224 // dim(G1) == D && dim(G2) == D - P/P A/A
|
Chris@102
|
1225 template <typename Geometry1, typename Geometry2, std::size_t Dim>
|
Chris@102
|
1226 struct static_mask_overlaps_impl<Geometry1, Geometry2, Dim, Dim>
|
Chris@102
|
1227 {
|
Chris@102
|
1228 typedef static_mask<'T', '*', 'T', '*', '*', '*', 'T', '*', '*'> type;
|
Chris@102
|
1229 };
|
Chris@102
|
1230 // dim(G1) == 1 && dim(G2) == 1 - L/L
|
Chris@102
|
1231 template <typename Geometry1, typename Geometry2>
|
Chris@102
|
1232 struct static_mask_overlaps_impl<Geometry1, Geometry2, 1, 1>
|
Chris@102
|
1233 {
|
Chris@102
|
1234 typedef static_mask<'1', '*', 'T', '*', '*', '*', 'T', '*', '*'> type;
|
Chris@102
|
1235 };
|
Chris@102
|
1236
|
Chris@102
|
1237 template <typename Geometry1, typename Geometry2>
|
Chris@102
|
1238 struct static_mask_overlaps_type
|
Chris@102
|
1239 : static_mask_overlaps_impl<Geometry1, Geometry2>
|
Chris@102
|
1240 {};
|
Chris@102
|
1241
|
Chris@102
|
1242 // RESULTS/HANDLERS UTILS
|
Chris@102
|
1243
|
Chris@102
|
1244 template <field F1, field F2, char V, typename Result>
|
Chris@102
|
1245 inline void set(Result & res)
|
Chris@102
|
1246 {
|
Chris@102
|
1247 res.template set<F1, F2, V>();
|
Chris@102
|
1248 }
|
Chris@102
|
1249
|
Chris@102
|
1250 template <field F1, field F2, char V, bool Transpose>
|
Chris@102
|
1251 struct set_dispatch
|
Chris@102
|
1252 {
|
Chris@102
|
1253 template <typename Result>
|
Chris@102
|
1254 static inline void apply(Result & res)
|
Chris@102
|
1255 {
|
Chris@102
|
1256 res.template set<F1, F2, V>();
|
Chris@102
|
1257 }
|
Chris@102
|
1258 };
|
Chris@102
|
1259
|
Chris@102
|
1260 template <field F1, field F2, char V>
|
Chris@102
|
1261 struct set_dispatch<F1, F2, V, true>
|
Chris@102
|
1262 {
|
Chris@102
|
1263 template <typename Result>
|
Chris@102
|
1264 static inline void apply(Result & res)
|
Chris@102
|
1265 {
|
Chris@102
|
1266 res.template set<F2, F1, V>();
|
Chris@102
|
1267 }
|
Chris@102
|
1268 };
|
Chris@102
|
1269
|
Chris@102
|
1270 template <field F1, field F2, char V, bool Transpose, typename Result>
|
Chris@102
|
1271 inline void set(Result & res)
|
Chris@102
|
1272 {
|
Chris@102
|
1273 set_dispatch<F1, F2, V, Transpose>::apply(res);
|
Chris@102
|
1274 }
|
Chris@102
|
1275
|
Chris@102
|
1276 template <char V, typename Result>
|
Chris@102
|
1277 inline void set(Result & res)
|
Chris@102
|
1278 {
|
Chris@102
|
1279 res.template set<interior, interior, V>();
|
Chris@102
|
1280 res.template set<interior, boundary, V>();
|
Chris@102
|
1281 res.template set<interior, exterior, V>();
|
Chris@102
|
1282 res.template set<boundary, interior, V>();
|
Chris@102
|
1283 res.template set<boundary, boundary, V>();
|
Chris@102
|
1284 res.template set<boundary, exterior, V>();
|
Chris@102
|
1285 res.template set<exterior, interior, V>();
|
Chris@102
|
1286 res.template set<exterior, boundary, V>();
|
Chris@102
|
1287 res.template set<exterior, exterior, V>();
|
Chris@102
|
1288 }
|
Chris@102
|
1289
|
Chris@102
|
1290 template <char II, char IB, char IE, char BI, char BB, char BE, char EI, char EB, char EE, typename Result>
|
Chris@102
|
1291 inline void set(Result & res)
|
Chris@102
|
1292 {
|
Chris@102
|
1293 res.template set<interior, interior, II>();
|
Chris@102
|
1294 res.template set<interior, boundary, IB>();
|
Chris@102
|
1295 res.template set<interior, exterior, IE>();
|
Chris@102
|
1296 res.template set<boundary, interior, BI>();
|
Chris@102
|
1297 res.template set<boundary, boundary, BB>();
|
Chris@102
|
1298 res.template set<boundary, exterior, BE>();
|
Chris@102
|
1299 res.template set<exterior, interior, EI>();
|
Chris@102
|
1300 res.template set<exterior, boundary, EB>();
|
Chris@102
|
1301 res.template set<exterior, exterior, EE>();
|
Chris@102
|
1302 }
|
Chris@102
|
1303
|
Chris@102
|
1304 template <field F1, field F2, char D, typename Result>
|
Chris@102
|
1305 inline void update(Result & res)
|
Chris@102
|
1306 {
|
Chris@102
|
1307 res.template update<F1, F2, D>();
|
Chris@102
|
1308 }
|
Chris@102
|
1309
|
Chris@102
|
1310 template <field F1, field F2, char D, bool Transpose>
|
Chris@102
|
1311 struct update_result_dispatch
|
Chris@102
|
1312 {
|
Chris@102
|
1313 template <typename Result>
|
Chris@102
|
1314 static inline void apply(Result & res)
|
Chris@102
|
1315 {
|
Chris@102
|
1316 update<F1, F2, D>(res);
|
Chris@102
|
1317 }
|
Chris@102
|
1318 };
|
Chris@102
|
1319
|
Chris@102
|
1320 template <field F1, field F2, char D>
|
Chris@102
|
1321 struct update_result_dispatch<F1, F2, D, true>
|
Chris@102
|
1322 {
|
Chris@102
|
1323 template <typename Result>
|
Chris@102
|
1324 static inline void apply(Result & res)
|
Chris@102
|
1325 {
|
Chris@102
|
1326 update<F2, F1, D>(res);
|
Chris@102
|
1327 }
|
Chris@102
|
1328 };
|
Chris@102
|
1329
|
Chris@102
|
1330 template <field F1, field F2, char D, bool Transpose, typename Result>
|
Chris@102
|
1331 inline void update(Result & res)
|
Chris@102
|
1332 {
|
Chris@102
|
1333 update_result_dispatch<F1, F2, D, Transpose>::apply(res);
|
Chris@102
|
1334 }
|
Chris@102
|
1335
|
Chris@102
|
1336 template <field F1, field F2, char D, typename Result>
|
Chris@102
|
1337 inline bool may_update(Result const& res)
|
Chris@102
|
1338 {
|
Chris@102
|
1339 return res.template may_update<F1, F2, D>();
|
Chris@102
|
1340 }
|
Chris@102
|
1341
|
Chris@102
|
1342 template <field F1, field F2, char D, bool Transpose>
|
Chris@102
|
1343 struct may_update_result_dispatch
|
Chris@102
|
1344 {
|
Chris@102
|
1345 template <typename Result>
|
Chris@102
|
1346 static inline bool apply(Result const& res)
|
Chris@102
|
1347 {
|
Chris@102
|
1348 return may_update<F1, F2, D>(res);
|
Chris@102
|
1349 }
|
Chris@102
|
1350 };
|
Chris@102
|
1351
|
Chris@102
|
1352 template <field F1, field F2, char D>
|
Chris@102
|
1353 struct may_update_result_dispatch<F1, F2, D, true>
|
Chris@102
|
1354 {
|
Chris@102
|
1355 template <typename Result>
|
Chris@102
|
1356 static inline bool apply(Result const& res)
|
Chris@102
|
1357 {
|
Chris@102
|
1358 return may_update<F2, F1, D>(res);
|
Chris@102
|
1359 }
|
Chris@102
|
1360 };
|
Chris@102
|
1361
|
Chris@102
|
1362 template <field F1, field F2, char D, bool Transpose, typename Result>
|
Chris@102
|
1363 inline bool may_update(Result const& res)
|
Chris@102
|
1364 {
|
Chris@102
|
1365 return may_update_result_dispatch<F1, F2, D, Transpose>::apply(res);
|
Chris@102
|
1366 }
|
Chris@102
|
1367
|
Chris@102
|
1368 template <typename Result, char II, char IB, char IE, char BI, char BB, char BE, char EI, char EB, char EE>
|
Chris@102
|
1369 inline Result return_result()
|
Chris@102
|
1370 {
|
Chris@102
|
1371 Result res;
|
Chris@102
|
1372 set<II, IB, IE, BI, BB, BE, EI, EB, EE>(res);
|
Chris@102
|
1373 return res;
|
Chris@102
|
1374 }
|
Chris@102
|
1375
|
Chris@102
|
1376 template <typename Geometry>
|
Chris@102
|
1377 struct result_dimension
|
Chris@102
|
1378 {
|
Chris@102
|
1379 BOOST_STATIC_ASSERT(geometry::dimension<Geometry>::value >= 0);
|
Chris@102
|
1380 static const char value
|
Chris@102
|
1381 = ( geometry::dimension<Geometry>::value <= 9 ) ?
|
Chris@102
|
1382 ( '0' + geometry::dimension<Geometry>::value ) :
|
Chris@102
|
1383 'T';
|
Chris@102
|
1384 };
|
Chris@102
|
1385
|
Chris@102
|
1386 }} // namespace detail::relate
|
Chris@102
|
1387 #endif // DOXYGEN_NO_DETAIL
|
Chris@102
|
1388
|
Chris@102
|
1389 }} // namespace boost::geometry
|
Chris@102
|
1390
|
Chris@102
|
1391 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_RESULT_HPP
|