comparison DEPENDENCIES/generic/include/boost/geometry/index/detail/predicates.hpp @ 16:2665513ce2d3

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