1 | // Boost.Geometry Index |
2 | // |
3 | // Spatial query predicates definition and checks. |
4 | // |
5 | // Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland. |
6 | // |
7 | // Use, modification and distribution is subject to the Boost Software License, |
8 | // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at |
9 | // http://www.boost.org/LICENSE_1_0.txt) |
10 | |
11 | #ifndef BOOST_GEOMETRY_INDEX_DETAIL_PREDICATES_HPP |
12 | #define BOOST_GEOMETRY_INDEX_DETAIL_PREDICATES_HPP |
13 | |
14 | #include <boost/geometry/index/predicates.hpp> |
15 | #include <boost/geometry/index/detail/tags.hpp> |
16 | |
17 | namespace boost { namespace geometry { namespace index { namespace detail { |
18 | |
19 | namespace predicates { |
20 | |
21 | // ------------------------------------------------------------------ // |
22 | // predicates |
23 | // ------------------------------------------------------------------ // |
24 | |
25 | template <typename Fun, bool IsFunction> |
26 | struct satisfies_impl |
27 | { |
28 | satisfies_impl() : fun(NULL) {} |
29 | satisfies_impl(Fun f) : fun(f) {} |
30 | Fun * fun; |
31 | }; |
32 | |
33 | template <typename Fun> |
34 | struct satisfies_impl<Fun, false> |
35 | { |
36 | satisfies_impl() {} |
37 | satisfies_impl(Fun const& f) : fun(f) {} |
38 | Fun fun; |
39 | }; |
40 | |
41 | template <typename Fun, bool Negated> |
42 | struct satisfies |
43 | : satisfies_impl<Fun, ::boost::is_function<Fun>::value> |
44 | { |
45 | typedef satisfies_impl<Fun, ::boost::is_function<Fun>::value> base; |
46 | |
47 | satisfies() {} |
48 | satisfies(Fun const& f) : base(f) {} |
49 | satisfies(base const& b) : base(b) {} |
50 | }; |
51 | |
52 | // ------------------------------------------------------------------ // |
53 | |
54 | struct contains_tag {}; |
55 | struct covered_by_tag {}; |
56 | struct covers_tag {}; |
57 | struct disjoint_tag {}; |
58 | struct intersects_tag {}; |
59 | struct overlaps_tag {}; |
60 | struct touches_tag {}; |
61 | struct within_tag {}; |
62 | |
63 | template <typename Geometry, typename Tag, bool Negated> |
64 | struct spatial_predicate |
65 | { |
66 | spatial_predicate() {} |
67 | spatial_predicate(Geometry const& g) : geometry(g) {} |
68 | Geometry geometry; |
69 | }; |
70 | |
71 | // ------------------------------------------------------------------ // |
72 | |
73 | // CONSIDER: separated nearest<> and path<> may be replaced by |
74 | // nearest_predicate<Geometry, Tag> |
75 | // where Tag = point_tag | path_tag |
76 | // IMPROVEMENT: user-defined nearest predicate allowing to define |
77 | // all or only geometrical aspects of the search |
78 | |
79 | template <typename PointOrRelation> |
80 | struct nearest |
81 | { |
82 | nearest() |
83 | // : count(0) |
84 | {} |
85 | nearest(PointOrRelation const& por, unsigned k) |
86 | : point_or_relation(por) |
87 | , count(k) |
88 | {} |
89 | PointOrRelation point_or_relation; |
90 | unsigned count; |
91 | }; |
92 | |
93 | template <typename SegmentOrLinestring> |
94 | struct path |
95 | { |
96 | path() |
97 | // : count(0) |
98 | {} |
99 | path(SegmentOrLinestring const& g, unsigned k) |
100 | : geometry(g) |
101 | , count(k) |
102 | {} |
103 | SegmentOrLinestring geometry; |
104 | unsigned count; |
105 | }; |
106 | |
107 | } // namespace predicates |
108 | |
109 | // ------------------------------------------------------------------ // |
110 | // predicate_check |
111 | // ------------------------------------------------------------------ // |
112 | |
113 | template <typename Predicate, typename Tag> |
114 | struct predicate_check |
115 | { |
116 | BOOST_MPL_ASSERT_MSG( |
117 | (false), |
118 | NOT_IMPLEMENTED_FOR_THIS_PREDICATE_OR_TAG, |
119 | (predicate_check)); |
120 | }; |
121 | |
122 | // ------------------------------------------------------------------ // |
123 | |
124 | template <typename Fun> |
125 | struct predicate_check<predicates::satisfies<Fun, false>, value_tag> |
126 | { |
127 | template <typename Value, typename Indexable> |
128 | static inline bool apply(predicates::satisfies<Fun, false> const& p, Value const& v, Indexable const&) |
129 | { |
130 | return p.fun(v); |
131 | } |
132 | }; |
133 | |
134 | template <typename Fun> |
135 | struct predicate_check<predicates::satisfies<Fun, true>, value_tag> |
136 | { |
137 | template <typename Value, typename Indexable> |
138 | static inline bool apply(predicates::satisfies<Fun, true> const& p, Value const& v, Indexable const&) |
139 | { |
140 | return !p.fun(v); |
141 | } |
142 | }; |
143 | |
144 | // ------------------------------------------------------------------ // |
145 | |
146 | template <typename Tag> |
147 | struct spatial_predicate_call |
148 | { |
149 | BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_TAG, (Tag)); |
150 | }; |
151 | |
152 | template <> |
153 | struct spatial_predicate_call<predicates::contains_tag> |
154 | { |
155 | template <typename G1, typename G2> |
156 | static inline bool apply(G1 const& g1, G2 const& g2) |
157 | { |
158 | return geometry::within(g2, g1); |
159 | } |
160 | }; |
161 | |
162 | template <> |
163 | struct spatial_predicate_call<predicates::covered_by_tag> |
164 | { |
165 | template <typename G1, typename G2> |
166 | static inline bool apply(G1 const& g1, G2 const& g2) |
167 | { |
168 | return geometry::covered_by(g1, g2); |
169 | } |
170 | }; |
171 | |
172 | template <> |
173 | struct spatial_predicate_call<predicates::covers_tag> |
174 | { |
175 | template <typename G1, typename G2> |
176 | static inline bool apply(G1 const& g1, G2 const& g2) |
177 | { |
178 | return geometry::covered_by(g2, g1); |
179 | } |
180 | }; |
181 | |
182 | template <> |
183 | struct spatial_predicate_call<predicates::disjoint_tag> |
184 | { |
185 | template <typename G1, typename G2> |
186 | static inline bool apply(G1 const& g1, G2 const& g2) |
187 | { |
188 | return geometry::disjoint(g1, g2); |
189 | } |
190 | }; |
191 | |
192 | template <> |
193 | struct spatial_predicate_call<predicates::intersects_tag> |
194 | { |
195 | template <typename G1, typename G2> |
196 | static inline bool apply(G1 const& g1, G2 const& g2) |
197 | { |
198 | return geometry::intersects(g1, g2); |
199 | } |
200 | }; |
201 | |
202 | template <> |
203 | struct spatial_predicate_call<predicates::overlaps_tag> |
204 | { |
205 | template <typename G1, typename G2> |
206 | static inline bool apply(G1 const& g1, G2 const& g2) |
207 | { |
208 | return geometry::overlaps(g1, g2); |
209 | } |
210 | }; |
211 | |
212 | template <> |
213 | struct spatial_predicate_call<predicates::touches_tag> |
214 | { |
215 | template <typename G1, typename G2> |
216 | static inline bool apply(G1 const& g1, G2 const& g2) |
217 | { |
218 | return geometry::touches(g1, g2); |
219 | } |
220 | }; |
221 | |
222 | template <> |
223 | struct spatial_predicate_call<predicates::within_tag> |
224 | { |
225 | template <typename G1, typename G2> |
226 | static inline bool apply(G1 const& g1, G2 const& g2) |
227 | { |
228 | return geometry::within(g1, g2); |
229 | } |
230 | }; |
231 | |
232 | // ------------------------------------------------------------------ // |
233 | |
234 | // spatial predicate |
235 | template <typename Geometry, typename Tag> |
236 | struct predicate_check<predicates::spatial_predicate<Geometry, Tag, false>, value_tag> |
237 | { |
238 | typedef predicates::spatial_predicate<Geometry, Tag, false> Pred; |
239 | |
240 | template <typename Value, typename Indexable> |
241 | static inline bool apply(Pred const& p, Value const&, Indexable const& i) |
242 | { |
243 | return spatial_predicate_call<Tag>::apply(i, p.geometry); |
244 | } |
245 | }; |
246 | |
247 | // negated spatial predicate |
248 | template <typename Geometry, typename Tag> |
249 | struct predicate_check<predicates::spatial_predicate<Geometry, Tag, true>, value_tag> |
250 | { |
251 | typedef predicates::spatial_predicate<Geometry, Tag, true> Pred; |
252 | |
253 | template <typename Value, typename Indexable> |
254 | static inline bool apply(Pred const& p, Value const&, Indexable const& i) |
255 | { |
256 | return !spatial_predicate_call<Tag>::apply(i, p.geometry); |
257 | } |
258 | }; |
259 | |
260 | // ------------------------------------------------------------------ // |
261 | |
262 | template <typename DistancePredicates> |
263 | struct predicate_check<predicates::nearest<DistancePredicates>, value_tag> |
264 | { |
265 | template <typename Value, typename Box> |
266 | static inline bool apply(predicates::nearest<DistancePredicates> const&, Value const&, Box const&) |
267 | { |
268 | return true; |
269 | } |
270 | }; |
271 | |
272 | template <typename Linestring> |
273 | struct predicate_check<predicates::path<Linestring>, value_tag> |
274 | { |
275 | template <typename Value, typename Box> |
276 | static inline bool apply(predicates::path<Linestring> const&, Value const&, Box const&) |
277 | { |
278 | return true; |
279 | } |
280 | }; |
281 | |
282 | // ------------------------------------------------------------------ // |
283 | // predicates_check for bounds |
284 | // ------------------------------------------------------------------ // |
285 | |
286 | template <typename Fun, bool Negated> |
287 | struct predicate_check<predicates::satisfies<Fun, Negated>, bounds_tag> |
288 | { |
289 | template <typename Value, typename Box> |
290 | static bool apply(predicates::satisfies<Fun, Negated> const&, Value const&, Box const&) |
291 | { |
292 | return true; |
293 | } |
294 | }; |
295 | |
296 | // ------------------------------------------------------------------ // |
297 | |
298 | // NOT NEGATED |
299 | // value_tag bounds_tag |
300 | // --------------------------- |
301 | // contains(I,G) contains(I,G) |
302 | // covered_by(I,G) intersects(I,G) |
303 | // covers(I,G) covers(I,G) |
304 | // disjoint(I,G) !covered_by(I,G) |
305 | // intersects(I,G) intersects(I,G) |
306 | // overlaps(I,G) intersects(I,G) - possibly change to the version without border case, e.g. intersects_without_border(0,0x1,1, 1,1x2,2) should give false |
307 | // touches(I,G) intersects(I,G) |
308 | // within(I,G) intersects(I,G) - possibly change to the version without border case, e.g. intersects_without_border(0,0x1,1, 1,1x2,2) should give false |
309 | |
310 | // spatial predicate - default |
311 | template <typename Geometry, typename Tag> |
312 | struct predicate_check<predicates::spatial_predicate<Geometry, Tag, false>, bounds_tag> |
313 | { |
314 | typedef predicates::spatial_predicate<Geometry, Tag, false> Pred; |
315 | |
316 | template <typename Value, typename Indexable> |
317 | static inline bool apply(Pred const& p, Value const&, Indexable const& i) |
318 | { |
319 | return spatial_predicate_call<predicates::intersects_tag>::apply(i, p.geometry); |
320 | } |
321 | }; |
322 | |
323 | // spatial predicate - contains |
324 | template <typename Geometry> |
325 | struct predicate_check<predicates::spatial_predicate<Geometry, predicates::contains_tag, false>, bounds_tag> |
326 | { |
327 | typedef predicates::spatial_predicate<Geometry, predicates::contains_tag, false> Pred; |
328 | |
329 | template <typename Value, typename Indexable> |
330 | static inline bool apply(Pred const& p, Value const&, Indexable const& i) |
331 | { |
332 | return spatial_predicate_call<predicates::contains_tag>::apply(i, p.geometry); |
333 | } |
334 | }; |
335 | |
336 | // spatial predicate - covers |
337 | template <typename Geometry> |
338 | struct predicate_check<predicates::spatial_predicate<Geometry, predicates::covers_tag, false>, bounds_tag> |
339 | { |
340 | typedef predicates::spatial_predicate<Geometry, predicates::covers_tag, false> Pred; |
341 | |
342 | template <typename Value, typename Indexable> |
343 | static inline bool apply(Pred const& p, Value const&, Indexable const& i) |
344 | { |
345 | return spatial_predicate_call<predicates::covers_tag>::apply(i, p.geometry); |
346 | } |
347 | }; |
348 | |
349 | // spatial predicate - disjoint |
350 | template <typename Geometry> |
351 | struct predicate_check<predicates::spatial_predicate<Geometry, predicates::disjoint_tag, false>, bounds_tag> |
352 | { |
353 | typedef predicates::spatial_predicate<Geometry, predicates::disjoint_tag, false> Pred; |
354 | |
355 | template <typename Value, typename Indexable> |
356 | static inline bool apply(Pred const& p, Value const&, Indexable const& i) |
357 | { |
358 | return !spatial_predicate_call<predicates::covered_by_tag>::apply(i, p.geometry); |
359 | } |
360 | }; |
361 | |
362 | // NEGATED |
363 | // value_tag bounds_tag |
364 | // --------------------------- |
365 | // !contains(I,G) TRUE |
366 | // !covered_by(I,G) !covered_by(I,G) |
367 | // !covers(I,G) TRUE |
368 | // !disjoint(I,G) !disjoint(I,G) |
369 | // !intersects(I,G) !covered_by(I,G) |
370 | // !overlaps(I,G) TRUE |
371 | // !touches(I,G) !intersects(I,G) |
372 | // !within(I,G) !within(I,G) |
373 | |
374 | // negated spatial predicate - default |
375 | template <typename Geometry, typename Tag> |
376 | struct predicate_check<predicates::spatial_predicate<Geometry, Tag, true>, bounds_tag> |
377 | { |
378 | typedef predicates::spatial_predicate<Geometry, Tag, true> Pred; |
379 | |
380 | template <typename Value, typename Indexable> |
381 | static inline bool apply(Pred const& p, Value const&, Indexable const& i) |
382 | { |
383 | return !spatial_predicate_call<Tag>::apply(i, p.geometry); |
384 | } |
385 | }; |
386 | |
387 | // negated spatial predicate - contains |
388 | template <typename Geometry> |
389 | struct predicate_check<predicates::spatial_predicate<Geometry, predicates::contains_tag, true>, bounds_tag> |
390 | { |
391 | typedef predicates::spatial_predicate<Geometry, predicates::contains_tag, true> Pred; |
392 | |
393 | template <typename Value, typename Indexable> |
394 | static inline bool apply(Pred const& , Value const&, Indexable const& ) |
395 | { |
396 | return true; |
397 | } |
398 | }; |
399 | |
400 | // negated spatial predicate - covers |
401 | template <typename Geometry> |
402 | struct predicate_check<predicates::spatial_predicate<Geometry, predicates::covers_tag, true>, bounds_tag> |
403 | { |
404 | typedef predicates::spatial_predicate<Geometry, predicates::covers_tag, true> Pred; |
405 | |
406 | template <typename Value, typename Indexable> |
407 | static inline bool apply(Pred const& , Value const&, Indexable const& ) |
408 | { |
409 | return true; |
410 | } |
411 | }; |
412 | |
413 | // negated spatial predicate - intersects |
414 | template <typename Geometry> |
415 | struct predicate_check<predicates::spatial_predicate<Geometry, predicates::intersects_tag, true>, bounds_tag> |
416 | { |
417 | typedef predicates::spatial_predicate<Geometry, predicates::intersects_tag, true> Pred; |
418 | |
419 | template <typename Value, typename Indexable> |
420 | static inline bool apply(Pred const& p, Value const&, Indexable const& i) |
421 | { |
422 | return !spatial_predicate_call<predicates::covered_by_tag>::apply(i, p.geometry); |
423 | } |
424 | }; |
425 | |
426 | // negated spatial predicate - overlaps |
427 | template <typename Geometry> |
428 | struct predicate_check<predicates::spatial_predicate<Geometry, predicates::overlaps_tag, true>, bounds_tag> |
429 | { |
430 | typedef predicates::spatial_predicate<Geometry, predicates::overlaps_tag, true> Pred; |
431 | |
432 | template <typename Value, typename Indexable> |
433 | static inline bool apply(Pred const& , Value const&, Indexable const& ) |
434 | { |
435 | return true; |
436 | } |
437 | }; |
438 | |
439 | // negated spatial predicate - touches |
440 | template <typename Geometry> |
441 | struct predicate_check<predicates::spatial_predicate<Geometry, predicates::touches_tag, true>, bounds_tag> |
442 | { |
443 | typedef predicates::spatial_predicate<Geometry, predicates::touches_tag, true> Pred; |
444 | |
445 | template <typename Value, typename Indexable> |
446 | static inline bool apply(Pred const& p, Value const&, Indexable const& i) |
447 | { |
448 | return !spatial_predicate_call<predicates::intersects_tag>::apply(i, p.geometry); |
449 | } |
450 | }; |
451 | |
452 | // ------------------------------------------------------------------ // |
453 | |
454 | template <typename DistancePredicates> |
455 | struct predicate_check<predicates::nearest<DistancePredicates>, bounds_tag> |
456 | { |
457 | template <typename Value, typename Box> |
458 | static inline bool apply(predicates::nearest<DistancePredicates> const&, Value const&, Box const&) |
459 | { |
460 | return true; |
461 | } |
462 | }; |
463 | |
464 | template <typename Linestring> |
465 | struct predicate_check<predicates::path<Linestring>, bounds_tag> |
466 | { |
467 | template <typename Value, typename Box> |
468 | static inline bool apply(predicates::path<Linestring> const&, Value const&, Box const&) |
469 | { |
470 | return true; |
471 | } |
472 | }; |
473 | |
474 | // ------------------------------------------------------------------ // |
475 | // predicates_length |
476 | // ------------------------------------------------------------------ // |
477 | |
478 | template <typename T> |
479 | struct predicates_length |
480 | { |
481 | static const unsigned value = 1; |
482 | }; |
483 | |
484 | //template <typename F, typename S> |
485 | //struct predicates_length< std::pair<F, S> > |
486 | //{ |
487 | // static const unsigned value = 2; |
488 | //}; |
489 | |
490 | //template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9> |
491 | //struct predicates_length< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> > |
492 | //{ |
493 | // static const unsigned value = boost::tuples::length< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >::value; |
494 | //}; |
495 | |
496 | template <typename Head, typename Tail> |
497 | struct predicates_length< boost::tuples::cons<Head, Tail> > |
498 | { |
499 | static const unsigned value = boost::tuples::length< boost::tuples::cons<Head, Tail> >::value; |
500 | }; |
501 | |
502 | // ------------------------------------------------------------------ // |
503 | // predicates_element |
504 | // ------------------------------------------------------------------ // |
505 | |
506 | template <unsigned I, typename T> |
507 | struct predicates_element |
508 | { |
509 | BOOST_MPL_ASSERT_MSG((I < 1), INVALID_INDEX, (predicates_element)); |
510 | typedef T type; |
511 | static type const& get(T const& p) { return p; } |
512 | }; |
513 | |
514 | //template <unsigned I, typename F, typename S> |
515 | //struct predicates_element< I, std::pair<F, S> > |
516 | //{ |
517 | // BOOST_MPL_ASSERT_MSG((I < 2), INVALID_INDEX, (predicates_element)); |
518 | // |
519 | // typedef F type; |
520 | // static type const& get(std::pair<F, S> const& p) { return p.first; } |
521 | //}; |
522 | // |
523 | //template <typename F, typename S> |
524 | //struct predicates_element< 1, std::pair<F, S> > |
525 | //{ |
526 | // typedef S type; |
527 | // static type const& get(std::pair<F, S> const& p) { return p.second; } |
528 | //}; |
529 | // |
530 | //template <unsigned I, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9> |
531 | //struct predicates_element< I, boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> > |
532 | //{ |
533 | // typedef boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> predicate_type; |
534 | // |
535 | // typedef typename boost::tuples::element<I, predicate_type>::type type; |
536 | // static type const& get(predicate_type const& p) { return boost::get<I>(p); } |
537 | //}; |
538 | |
539 | template <unsigned I, typename Head, typename Tail> |
540 | struct predicates_element< I, boost::tuples::cons<Head, Tail> > |
541 | { |
542 | typedef boost::tuples::cons<Head, Tail> predicate_type; |
543 | |
544 | typedef typename boost::tuples::element<I, predicate_type>::type type; |
545 | static type const& get(predicate_type const& p) { return boost::get<I>(p); } |
546 | }; |
547 | |
548 | // ------------------------------------------------------------------ // |
549 | // predicates_check |
550 | // ------------------------------------------------------------------ // |
551 | |
552 | //template <typename PairPredicates, typename Tag, unsigned First, unsigned Last> |
553 | //struct predicates_check_pair {}; |
554 | // |
555 | //template <typename PairPredicates, typename Tag, unsigned I> |
556 | //struct predicates_check_pair<PairPredicates, Tag, I, I> |
557 | //{ |
558 | // template <typename Value, typename Indexable> |
559 | // static inline bool apply(PairPredicates const& , Value const& , Indexable const& ) |
560 | // { |
561 | // return true; |
562 | // } |
563 | //}; |
564 | // |
565 | //template <typename PairPredicates, typename Tag> |
566 | //struct predicates_check_pair<PairPredicates, Tag, 0, 1> |
567 | //{ |
568 | // template <typename Value, typename Indexable> |
569 | // static inline bool apply(PairPredicates const& p, Value const& v, Indexable const& i) |
570 | // { |
571 | // return predicate_check<typename PairPredicates::first_type, Tag>::apply(p.first, v, i); |
572 | // } |
573 | //}; |
574 | // |
575 | //template <typename PairPredicates, typename Tag> |
576 | //struct predicates_check_pair<PairPredicates, Tag, 1, 2> |
577 | //{ |
578 | // template <typename Value, typename Indexable> |
579 | // static inline bool apply(PairPredicates const& p, Value const& v, Indexable const& i) |
580 | // { |
581 | // return predicate_check<typename PairPredicates::second_type, Tag>::apply(p.second, v, i); |
582 | // } |
583 | //}; |
584 | // |
585 | //template <typename PairPredicates, typename Tag> |
586 | //struct predicates_check_pair<PairPredicates, Tag, 0, 2> |
587 | //{ |
588 | // template <typename Value, typename Indexable> |
589 | // static inline bool apply(PairPredicates const& p, Value const& v, Indexable const& i) |
590 | // { |
591 | // return predicate_check<typename PairPredicates::first_type, Tag>::apply(p.first, v, i) |
592 | // && predicate_check<typename PairPredicates::second_type, Tag>::apply(p.second, v, i); |
593 | // } |
594 | //}; |
595 | |
596 | template <typename TuplePredicates, typename Tag, unsigned First, unsigned Last> |
597 | struct predicates_check_tuple |
598 | { |
599 | template <typename Value, typename Indexable> |
600 | static inline bool apply(TuplePredicates const& p, Value const& v, Indexable const& i) |
601 | { |
602 | return |
603 | predicate_check< |
604 | typename boost::tuples::element<First, TuplePredicates>::type, |
605 | Tag |
606 | >::apply(boost::get<First>(p), v, i) && |
607 | predicates_check_tuple<TuplePredicates, Tag, First+1, Last>::apply(p, v, i); |
608 | } |
609 | }; |
610 | |
611 | template <typename TuplePredicates, typename Tag, unsigned First> |
612 | struct predicates_check_tuple<TuplePredicates, Tag, First, First> |
613 | { |
614 | template <typename Value, typename Indexable> |
615 | static inline bool apply(TuplePredicates const& , Value const& , Indexable const& ) |
616 | { |
617 | return true; |
618 | } |
619 | }; |
620 | |
621 | template <typename Predicate, typename Tag, unsigned First, unsigned Last> |
622 | struct predicates_check_impl |
623 | { |
624 | static const bool check = First < 1 && Last <= 1 && First <= Last; |
625 | BOOST_MPL_ASSERT_MSG((check), INVALID_INDEXES, (predicates_check_impl)); |
626 | |
627 | template <typename Value, typename Indexable> |
628 | static inline bool apply(Predicate const& p, Value const& v, Indexable const& i) |
629 | { |
630 | return predicate_check<Predicate, Tag>::apply(p, v, i); |
631 | } |
632 | }; |
633 | |
634 | //template <typename Predicate1, typename Predicate2, typename Tag, size_t First, size_t Last> |
635 | //struct predicates_check_impl<std::pair<Predicate1, Predicate2>, Tag, First, Last> |
636 | //{ |
637 | // BOOST_MPL_ASSERT_MSG((First < 2 && Last <= 2 && First <= Last), INVALID_INDEXES, (predicates_check_impl)); |
638 | // |
639 | // template <typename Value, typename Indexable> |
640 | // static inline bool apply(std::pair<Predicate1, Predicate2> const& p, Value const& v, Indexable const& i) |
641 | // { |
642 | // return predicate_check<Predicate1, Tag>::apply(p.first, v, i) |
643 | // && predicate_check<Predicate2, Tag>::apply(p.second, v, i); |
644 | // } |
645 | //}; |
646 | // |
647 | //template < |
648 | // typename T0, typename T1, typename T2, typename T3, typename T4, |
649 | // typename T5, typename T6, typename T7, typename T8, typename T9, |
650 | // typename Tag, unsigned First, unsigned Last |
651 | //> |
652 | //struct predicates_check_impl< |
653 | // boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>, |
654 | // Tag, First, Last |
655 | //> |
656 | //{ |
657 | // typedef boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> predicates_type; |
658 | // |
659 | // static const unsigned pred_len = boost::tuples::length<predicates_type>::value; |
660 | // BOOST_MPL_ASSERT_MSG((First < pred_len && Last <= pred_len && First <= Last), INVALID_INDEXES, (predicates_check_impl)); |
661 | // |
662 | // template <typename Value, typename Indexable> |
663 | // static inline bool apply(predicates_type const& p, Value const& v, Indexable const& i) |
664 | // { |
665 | // return predicates_check_tuple< |
666 | // predicates_type, |
667 | // Tag, First, Last |
668 | // >::apply(p, v, i); |
669 | // } |
670 | //}; |
671 | |
672 | template <typename Head, typename Tail, typename Tag, unsigned First, unsigned Last> |
673 | struct predicates_check_impl< |
674 | boost::tuples::cons<Head, Tail>, |
675 | Tag, First, Last |
676 | > |
677 | { |
678 | typedef boost::tuples::cons<Head, Tail> predicates_type; |
679 | |
680 | static const unsigned pred_len = boost::tuples::length<predicates_type>::value; |
681 | static const bool check = First < pred_len && Last <= pred_len && First <= Last; |
682 | BOOST_MPL_ASSERT_MSG((check), INVALID_INDEXES, (predicates_check_impl)); |
683 | |
684 | template <typename Value, typename Indexable> |
685 | static inline bool apply(predicates_type const& p, Value const& v, Indexable const& i) |
686 | { |
687 | return predicates_check_tuple< |
688 | predicates_type, |
689 | Tag, First, Last |
690 | >::apply(p, v, i); |
691 | } |
692 | }; |
693 | |
694 | template <typename Tag, unsigned First, unsigned Last, typename Predicates, typename Value, typename Indexable> |
695 | inline bool predicates_check(Predicates const& p, Value const& v, Indexable const& i) |
696 | { |
697 | return detail::predicates_check_impl<Predicates, Tag, First, Last> |
698 | ::apply(p, v, i); |
699 | } |
700 | |
701 | // ------------------------------------------------------------------ // |
702 | // nearest predicate helpers |
703 | // ------------------------------------------------------------------ // |
704 | |
705 | // predicates_is_nearest |
706 | |
707 | template <typename P> |
708 | struct predicates_is_distance |
709 | { |
710 | static const unsigned value = 0; |
711 | }; |
712 | |
713 | template <typename DistancePredicates> |
714 | struct predicates_is_distance< predicates::nearest<DistancePredicates> > |
715 | { |
716 | static const unsigned value = 1; |
717 | }; |
718 | |
719 | template <typename Linestring> |
720 | struct predicates_is_distance< predicates::path<Linestring> > |
721 | { |
722 | static const unsigned value = 1; |
723 | }; |
724 | |
725 | // predicates_count_nearest |
726 | |
727 | template <typename T> |
728 | struct predicates_count_distance |
729 | { |
730 | static const unsigned value = predicates_is_distance<T>::value; |
731 | }; |
732 | |
733 | //template <typename F, typename S> |
734 | //struct predicates_count_distance< std::pair<F, S> > |
735 | //{ |
736 | // static const unsigned value = predicates_is_distance<F>::value |
737 | // + predicates_is_distance<S>::value; |
738 | //}; |
739 | |
740 | template <typename Tuple, unsigned N> |
741 | struct predicates_count_distance_tuple |
742 | { |
743 | static const unsigned value = |
744 | predicates_is_distance<typename boost::tuples::element<N-1, Tuple>::type>::value |
745 | + predicates_count_distance_tuple<Tuple, N-1>::value; |
746 | }; |
747 | |
748 | template <typename Tuple> |
749 | struct predicates_count_distance_tuple<Tuple, 1> |
750 | { |
751 | static const unsigned value = |
752 | predicates_is_distance<typename boost::tuples::element<0, Tuple>::type>::value; |
753 | }; |
754 | |
755 | //template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9> |
756 | //struct predicates_count_distance< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> > |
757 | //{ |
758 | // static const unsigned value = predicates_count_distance_tuple< |
759 | // boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>, |
760 | // boost::tuples::length< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >::value |
761 | // >::value; |
762 | //}; |
763 | |
764 | template <typename Head, typename Tail> |
765 | struct predicates_count_distance< boost::tuples::cons<Head, Tail> > |
766 | { |
767 | static const unsigned value = predicates_count_distance_tuple< |
768 | boost::tuples::cons<Head, Tail>, |
769 | boost::tuples::length< boost::tuples::cons<Head, Tail> >::value |
770 | >::value; |
771 | }; |
772 | |
773 | // predicates_find_nearest |
774 | |
775 | template <typename T> |
776 | struct predicates_find_distance |
777 | { |
778 | static const unsigned value = predicates_is_distance<T>::value ? 0 : 1; |
779 | }; |
780 | |
781 | //template <typename F, typename S> |
782 | //struct predicates_find_distance< std::pair<F, S> > |
783 | //{ |
784 | // static const unsigned value = predicates_is_distance<F>::value ? 0 : |
785 | // (predicates_is_distance<S>::value ? 1 : 2); |
786 | //}; |
787 | |
788 | template <typename Tuple, unsigned N> |
789 | struct predicates_find_distance_tuple |
790 | { |
791 | static const bool is_found = predicates_find_distance_tuple<Tuple, N-1>::is_found |
792 | || predicates_is_distance<typename boost::tuples::element<N-1, Tuple>::type>::value; |
793 | |
794 | static const unsigned value = predicates_find_distance_tuple<Tuple, N-1>::is_found ? |
795 | predicates_find_distance_tuple<Tuple, N-1>::value : |
796 | (predicates_is_distance<typename boost::tuples::element<N-1, Tuple>::type>::value ? |
797 | N-1 : boost::tuples::length<Tuple>::value); |
798 | }; |
799 | |
800 | template <typename Tuple> |
801 | struct predicates_find_distance_tuple<Tuple, 1> |
802 | { |
803 | static const bool is_found = predicates_is_distance<typename boost::tuples::element<0, Tuple>::type>::value; |
804 | static const unsigned value = is_found ? 0 : boost::tuples::length<Tuple>::value; |
805 | }; |
806 | |
807 | //template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9> |
808 | //struct predicates_find_distance< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> > |
809 | //{ |
810 | // static const unsigned value = predicates_find_distance_tuple< |
811 | // boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>, |
812 | // boost::tuples::length< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >::value |
813 | // >::value; |
814 | //}; |
815 | |
816 | template <typename Head, typename Tail> |
817 | struct predicates_find_distance< boost::tuples::cons<Head, Tail> > |
818 | { |
819 | static const unsigned value = predicates_find_distance_tuple< |
820 | boost::tuples::cons<Head, Tail>, |
821 | boost::tuples::length< boost::tuples::cons<Head, Tail> >::value |
822 | >::value; |
823 | }; |
824 | |
825 | }}}} // namespace boost::geometry::index::detail |
826 | |
827 | #endif // BOOST_GEOMETRY_INDEX_DETAIL_PREDICATES_HPP |
828 | |