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