1 // Boost.Geometry Index
3 // Spatial query predicates definition and checks.
5 // Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
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
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)
15 #ifndef BOOST_GEOMETRY_INDEX_DETAIL_PREDICATES_HPP
16 #define BOOST_GEOMETRY_INDEX_DETAIL_PREDICATES_HPP
20 #include <boost/mpl/assert.hpp>
21 #include <boost/tuple/tuple.hpp>
23 #include <boost/geometry/index/detail/tags.hpp>
25 namespace boost { namespace geometry { namespace index { namespace detail {
27 namespace predicates {
29 // ------------------------------------------------------------------ //
31 // ------------------------------------------------------------------ //
33 template <typename Fun, bool IsFunction>
36 satisfies_impl() : fun(NULL) {}
37 satisfies_impl(Fun f) : fun(f) {}
41 template <typename Fun>
42 struct satisfies_impl<Fun, false>
45 satisfies_impl(Fun const& f) : fun(f) {}
49 template <typename Fun, bool Negated>
51 : satisfies_impl<Fun, ::boost::is_function<Fun>::value>
53 typedef satisfies_impl<Fun, ::boost::is_function<Fun>::value> base;
56 satisfies(Fun const& f) : base(f) {}
57 satisfies(base const& b) : base(b) {}
60 // ------------------------------------------------------------------ //
62 struct contains_tag {};
63 struct covered_by_tag {};
65 struct disjoint_tag {};
66 struct intersects_tag {};
67 struct overlaps_tag {};
68 struct touches_tag {};
71 template <typename Geometry, typename Tag, bool Negated>
72 struct spatial_predicate
74 spatial_predicate() {}
75 spatial_predicate(Geometry const& g) : geometry(g) {}
79 // ------------------------------------------------------------------ //
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
87 template <typename PointOrRelation>
93 nearest(PointOrRelation const& por, unsigned k)
94 : point_or_relation(por)
97 PointOrRelation point_or_relation;
101 template <typename SegmentOrLinestring>
107 path(SegmentOrLinestring const& g, unsigned k)
111 SegmentOrLinestring geometry;
115 } // namespace predicates
117 // ------------------------------------------------------------------ //
119 // ------------------------------------------------------------------ //
121 template <typename Predicate, typename Tag>
122 struct predicate_check
124 BOOST_MPL_ASSERT_MSG(
126 NOT_IMPLEMENTED_FOR_THIS_PREDICATE_OR_TAG,
130 // ------------------------------------------------------------------ //
132 template <typename Fun>
133 struct predicate_check<predicates::satisfies<Fun, false>, value_tag>
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&)
142 template <typename Fun>
143 struct predicate_check<predicates::satisfies<Fun, true>, value_tag>
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&)
152 // ------------------------------------------------------------------ //
154 template <typename Tag>
155 struct spatial_predicate_call
157 BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_TAG, (Tag));
161 struct spatial_predicate_call<predicates::contains_tag>
163 template <typename G1, typename G2, typename S>
164 static inline bool apply(G1 const& g1, G2 const& g2, S const&)
166 return geometry::within(g2, g1);
171 struct spatial_predicate_call<predicates::covered_by_tag>
173 template <typename G1, typename G2, typename S>
174 static inline bool apply(G1 const& g1, G2 const& g2, S const&)
176 return geometry::covered_by(g1, g2);
181 struct spatial_predicate_call<predicates::covers_tag>
183 template <typename G1, typename G2, typename S>
184 static inline bool apply(G1 const& g1, G2 const& g2, S const&)
186 return geometry::covered_by(g2, g1);
191 struct spatial_predicate_call<predicates::disjoint_tag>
193 template <typename G1, typename G2, typename S>
194 static inline bool apply(G1 const& g1, G2 const& g2, S const&)
196 return geometry::disjoint(g1, g2);
200 // TEMP: used to implement CS-specific intersects predicate for certain
201 // combinations of geometries until umbrella strategies are implemented
204 typename G1, typename G2,
205 typename Tag1 = typename tag<G1>::type,
206 typename Tag2 = typename tag<G2>::type
208 struct spatial_predicate_intersects
210 template <typename S>
211 static inline bool apply(G1 const& g1, G2 const& g2, S const&)
213 return geometry::intersects(g1, g2);
216 // TEMP: used in within and relate
217 template <typename G1, typename G2>
218 struct spatial_predicate_intersects<G1, G2, box_tag, point_tag>
220 static inline bool apply(G1 const& g1, G2 const& g2, default_strategy const&)
222 return geometry::intersects(g1, g2);
225 template <typename S>
226 static inline bool apply(G1 const& g1, G2 const& g2, S const& )
228 return geometry::intersects(g1, g2, typename S::covered_by_point_box_strategy_type());
233 struct spatial_predicate_call<predicates::intersects_tag>
235 template <typename G1, typename G2, typename S>
236 static inline bool apply(G1 const& g1, G2 const& g2, S const& s)
238 return spatial_predicate_intersects<G1, G2>::apply(g1, g2, s);
243 struct spatial_predicate_call<predicates::overlaps_tag>
245 template <typename G1, typename G2, typename S>
246 static inline bool apply(G1 const& g1, G2 const& g2, S const&)
248 return geometry::overlaps(g1, g2);
253 struct spatial_predicate_call<predicates::touches_tag>
255 template <typename G1, typename G2, typename S>
256 static inline bool apply(G1 const& g1, G2 const& g2, S const&)
258 return geometry::touches(g1, g2);
263 struct spatial_predicate_call<predicates::within_tag>
265 template <typename G1, typename G2, typename S>
266 static inline bool apply(G1 const& g1, G2 const& g2, S const&)
268 return geometry::within(g1, g2);
272 // ------------------------------------------------------------------ //
275 template <typename Geometry, typename Tag>
276 struct predicate_check<predicates::spatial_predicate<Geometry, Tag, false>, value_tag>
278 typedef predicates::spatial_predicate<Geometry, Tag, false> Pred;
280 template <typename Value, typename Indexable, typename Strategy>
281 static inline bool apply(Pred const& p, Value const&, Indexable const& i, Strategy const& s)
283 return spatial_predicate_call<Tag>::apply(i, p.geometry, s);
287 // negated spatial predicate
288 template <typename Geometry, typename Tag>
289 struct predicate_check<predicates::spatial_predicate<Geometry, Tag, true>, value_tag>
291 typedef predicates::spatial_predicate<Geometry, Tag, true> Pred;
293 template <typename Value, typename Indexable, typename Strategy>
294 static inline bool apply(Pred const& p, Value const&, Indexable const& i, Strategy const& s)
296 return !spatial_predicate_call<Tag>::apply(i, p.geometry, s);
300 // ------------------------------------------------------------------ //
302 template <typename DistancePredicates>
303 struct predicate_check<predicates::nearest<DistancePredicates>, value_tag>
305 template <typename Value, typename Box, typename Strategy>
306 static inline bool apply(predicates::nearest<DistancePredicates> const&, Value const&, Box const&, Strategy const&)
312 template <typename Linestring>
313 struct predicate_check<predicates::path<Linestring>, value_tag>
315 template <typename Value, typename Box, typename Strategy>
316 static inline bool apply(predicates::path<Linestring> const&, Value const&, Box const&, Strategy const&)
322 // ------------------------------------------------------------------ //
323 // predicates_check for bounds
324 // ------------------------------------------------------------------ //
326 template <typename Fun, bool Negated>
327 struct predicate_check<predicates::satisfies<Fun, Negated>, bounds_tag>
329 template <typename Value, typename Box, typename Strategy>
330 static bool apply(predicates::satisfies<Fun, Negated> const&, Value const&, Box const&, Strategy const&)
336 // ------------------------------------------------------------------ //
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
350 // spatial predicate - default
351 template <typename Geometry, typename Tag>
352 struct predicate_check<predicates::spatial_predicate<Geometry, Tag, false>, bounds_tag>
354 typedef predicates::spatial_predicate<Geometry, Tag, false> Pred;
356 template <typename Value, typename Indexable, typename Strategy>
357 static inline bool apply(Pred const& p, Value const&, Indexable const& i, Strategy const& s)
359 return spatial_predicate_call<predicates::intersects_tag>::apply(i, p.geometry, s);
363 // spatial predicate - contains
364 template <typename Geometry>
365 struct predicate_check<predicates::spatial_predicate<Geometry, predicates::contains_tag, false>, bounds_tag>
367 typedef predicates::spatial_predicate<Geometry, predicates::contains_tag, false> Pred;
369 template <typename Value, typename Indexable, typename Strategy>
370 static inline bool apply(Pred const& p, Value const&, Indexable const& i, Strategy const& s)
372 return spatial_predicate_call<predicates::covers_tag>::apply(i, p.geometry, s);
376 // spatial predicate - covers
377 template <typename Geometry>
378 struct predicate_check<predicates::spatial_predicate<Geometry, predicates::covers_tag, false>, bounds_tag>
380 typedef predicates::spatial_predicate<Geometry, predicates::covers_tag, false> Pred;
382 template <typename Value, typename Indexable, typename Strategy>
383 static inline bool apply(Pred const& p, Value const&, Indexable const& i, Strategy const& s)
385 return spatial_predicate_call<predicates::covers_tag>::apply(i, p.geometry, s);
389 // spatial predicate - disjoint
390 template <typename Geometry>
391 struct predicate_check<predicates::spatial_predicate<Geometry, predicates::disjoint_tag, false>, bounds_tag>
393 typedef predicates::spatial_predicate<Geometry, predicates::disjoint_tag, false> Pred;
395 template <typename Value, typename Indexable, typename Strategy>
396 static inline bool apply(Pred const& p, Value const&, Indexable const& i, Strategy const& s)
398 return !spatial_predicate_call<predicates::covered_by_tag>::apply(i, p.geometry, s);
403 // value_tag bounds_tag
404 // ---------------------------
405 // !contains(I,G) TRUE
406 // !covered_by(I,G) !covered_by(I,G)
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)
414 // negated spatial predicate - default
415 template <typename Geometry, typename Tag>
416 struct predicate_check<predicates::spatial_predicate<Geometry, Tag, true>, bounds_tag>
418 typedef predicates::spatial_predicate<Geometry, Tag, true> Pred;
420 template <typename Value, typename Indexable, typename Strategy>
421 static inline bool apply(Pred const& p, Value const&, Indexable const& i, Strategy const& s)
423 return !spatial_predicate_call<Tag>::apply(i, p.geometry, s);
427 // negated spatial predicate - contains
428 template <typename Geometry>
429 struct predicate_check<predicates::spatial_predicate<Geometry, predicates::contains_tag, true>, bounds_tag>
431 typedef predicates::spatial_predicate<Geometry, predicates::contains_tag, true> Pred;
433 template <typename Value, typename Indexable, typename Strategy>
434 static inline bool apply(Pred const& , Value const&, Indexable const&, Strategy const&)
440 // negated spatial predicate - covers
441 template <typename Geometry>
442 struct predicate_check<predicates::spatial_predicate<Geometry, predicates::covers_tag, true>, bounds_tag>
444 typedef predicates::spatial_predicate<Geometry, predicates::covers_tag, true> Pred;
446 template <typename Value, typename Indexable, typename Strategy>
447 static inline bool apply(Pred const& , Value const&, Indexable const&, Strategy const&)
453 // negated spatial predicate - intersects
454 template <typename Geometry>
455 struct predicate_check<predicates::spatial_predicate<Geometry, predicates::intersects_tag, true>, bounds_tag>
457 typedef predicates::spatial_predicate<Geometry, predicates::intersects_tag, true> Pred;
459 template <typename Value, typename Indexable, typename Strategy>
460 static inline bool apply(Pred const& p, Value const&, Indexable const& i, Strategy const& s)
462 return !spatial_predicate_call<predicates::covered_by_tag>::apply(i, p.geometry, s);
466 // negated spatial predicate - overlaps
467 template <typename Geometry>
468 struct predicate_check<predicates::spatial_predicate<Geometry, predicates::overlaps_tag, true>, bounds_tag>
470 typedef predicates::spatial_predicate<Geometry, predicates::overlaps_tag, true> Pred;
472 template <typename Value, typename Indexable, typename Strategy>
473 static inline bool apply(Pred const& , Value const&, Indexable const&, Strategy const&)
479 // negated spatial predicate - touches
480 template <typename Geometry>
481 struct predicate_check<predicates::spatial_predicate<Geometry, predicates::touches_tag, true>, bounds_tag>
483 typedef predicates::spatial_predicate<Geometry, predicates::touches_tag, true> Pred;
485 template <typename Value, typename Indexable, typename Strategy>
486 static inline bool apply(Pred const& p, Value const&, Indexable const& i, Strategy const&)
488 return !spatial_predicate_call<predicates::intersects_tag>::apply(i, p.geometry);
492 // ------------------------------------------------------------------ //
494 template <typename DistancePredicates>
495 struct predicate_check<predicates::nearest<DistancePredicates>, bounds_tag>
497 template <typename Value, typename Box, typename Strategy>
498 static inline bool apply(predicates::nearest<DistancePredicates> const&, Value const&, Box const&, Strategy const&)
504 template <typename Linestring>
505 struct predicate_check<predicates::path<Linestring>, bounds_tag>
507 template <typename Value, typename Box, typename Strategy>
508 static inline bool apply(predicates::path<Linestring> const&, Value const&, Box const&, Strategy const&)
514 // ------------------------------------------------------------------ //
516 // ------------------------------------------------------------------ //
518 template <typename T>
519 struct predicates_length
521 static const unsigned value = 1;
524 //template <typename F, typename S>
525 //struct predicates_length< std::pair<F, S> >
527 // static const unsigned value = 2;
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> >
533 // static const unsigned value = boost::tuples::length< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >::value;
536 template <typename Head, typename Tail>
537 struct predicates_length< boost::tuples::cons<Head, Tail> >
539 static const unsigned value = boost::tuples::length< boost::tuples::cons<Head, Tail> >::value;
542 // ------------------------------------------------------------------ //
543 // predicates_element
544 // ------------------------------------------------------------------ //
546 template <unsigned I, typename T>
547 struct predicates_element
549 BOOST_MPL_ASSERT_MSG((I < 1), INVALID_INDEX, (predicates_element));
551 static type const& get(T const& p) { return p; }
554 //template <unsigned I, typename F, typename S>
555 //struct predicates_element< I, std::pair<F, S> >
557 // BOOST_MPL_ASSERT_MSG((I < 2), INVALID_INDEX, (predicates_element));
560 // static type const& get(std::pair<F, S> const& p) { return p.first; }
563 //template <typename F, typename S>
564 //struct predicates_element< 1, std::pair<F, S> >
567 // static type const& get(std::pair<F, S> const& p) { return p.second; }
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> >
573 // typedef boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> predicate_type;
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); }
579 template <unsigned I, typename Head, typename Tail>
580 struct predicates_element< I, boost::tuples::cons<Head, Tail> >
582 typedef boost::tuples::cons<Head, Tail> predicate_type;
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); }
588 // ------------------------------------------------------------------ //
590 // ------------------------------------------------------------------ //
592 //template <typename PairPredicates, typename Tag, unsigned First, unsigned Last>
593 //struct predicates_check_pair {};
595 //template <typename PairPredicates, typename Tag, unsigned I>
596 //struct predicates_check_pair<PairPredicates, Tag, I, I>
598 // template <typename Value, typename Indexable>
599 // static inline bool apply(PairPredicates const& , Value const& , Indexable const& )
605 //template <typename PairPredicates, typename Tag>
606 //struct predicates_check_pair<PairPredicates, Tag, 0, 1>
608 // template <typename Value, typename Indexable>
609 // static inline bool apply(PairPredicates const& p, Value const& v, Indexable const& i)
611 // return predicate_check<typename PairPredicates::first_type, Tag>::apply(p.first, v, i);
615 //template <typename PairPredicates, typename Tag>
616 //struct predicates_check_pair<PairPredicates, Tag, 1, 2>
618 // template <typename Value, typename Indexable>
619 // static inline bool apply(PairPredicates const& p, Value const& v, Indexable const& i)
621 // return predicate_check<typename PairPredicates::second_type, Tag>::apply(p.second, v, i);
625 //template <typename PairPredicates, typename Tag>
626 //struct predicates_check_pair<PairPredicates, Tag, 0, 2>
628 // template <typename Value, typename Indexable>
629 // static inline bool apply(PairPredicates const& p, Value const& v, Indexable const& i)
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);
636 template <typename TuplePredicates, typename Tag, unsigned First, unsigned Last>
637 struct predicates_check_tuple
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)
642 return predicate_check
644 typename boost::tuples::element<First, TuplePredicates>::type,
646 >::apply(boost::get<First>(p), v, i, s)
647 && predicates_check_tuple<TuplePredicates, Tag, First+1, Last>::apply(p, v, i, s);
651 template <typename TuplePredicates, typename Tag, unsigned First>
652 struct predicates_check_tuple<TuplePredicates, Tag, First, First>
654 template <typename Value, typename Indexable, typename Strategy>
655 static inline bool apply(TuplePredicates const& , Value const& , Indexable const& , Strategy const& )
661 template <typename Predicate, typename Tag, unsigned First, unsigned Last>
662 struct predicates_check_impl
664 static const bool check = First < 1 && Last <= 1 && First <= Last;
665 BOOST_MPL_ASSERT_MSG((check), INVALID_INDEXES, (predicates_check_impl));
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)
670 return predicate_check<Predicate, Tag>::apply(p, v, i, s);
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>
677 // BOOST_MPL_ASSERT_MSG((First < 2 && Last <= 2 && First <= Last), INVALID_INDEXES, (predicates_check_impl));
679 // template <typename Value, typename Indexable>
680 // static inline bool apply(std::pair<Predicate1, Predicate2> const& p, Value const& v, Indexable const& i)
682 // return predicate_check<Predicate1, Tag>::apply(p.first, v, i)
683 // && predicate_check<Predicate2, Tag>::apply(p.second, v, i);
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
692 //struct predicates_check_impl<
693 // boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>,
697 // typedef boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> predicates_type;
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));
702 // template <typename Value, typename Indexable>
703 // static inline bool apply(predicates_type const& p, Value const& v, Indexable const& i)
705 // return predicates_check_tuple<
708 // >::apply(p, v, i);
712 template <typename Head, typename Tail, typename Tag, unsigned First, unsigned Last>
713 struct predicates_check_impl<
714 boost::tuples::cons<Head, Tail>,
718 typedef boost::tuples::cons<Head, Tail> predicates_type;
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));
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)
727 return predicates_check_tuple<
730 >::apply(p, v, i, s);
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)
737 return detail::predicates_check_impl<Predicates, Tag, First, Last>
741 // ------------------------------------------------------------------ //
742 // nearest predicate helpers
743 // ------------------------------------------------------------------ //
745 // predicates_is_nearest
747 template <typename P>
748 struct predicates_is_distance
750 static const unsigned value = 0;
753 template <typename DistancePredicates>
754 struct predicates_is_distance< predicates::nearest<DistancePredicates> >
756 static const unsigned value = 1;
759 template <typename Linestring>
760 struct predicates_is_distance< predicates::path<Linestring> >
762 static const unsigned value = 1;
765 // predicates_count_nearest
767 template <typename T>
768 struct predicates_count_distance
770 static const unsigned value = predicates_is_distance<T>::value;
773 //template <typename F, typename S>
774 //struct predicates_count_distance< std::pair<F, S> >
776 // static const unsigned value = predicates_is_distance<F>::value
777 // + predicates_is_distance<S>::value;
780 template <typename Tuple, unsigned N>
781 struct predicates_count_distance_tuple
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;
788 template <typename Tuple>
789 struct predicates_count_distance_tuple<Tuple, 1>
791 static const unsigned value =
792 predicates_is_distance<typename boost::tuples::element<0, Tuple>::type>::value;
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> >
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
804 template <typename Head, typename Tail>
805 struct predicates_count_distance< boost::tuples::cons<Head, Tail> >
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
813 // predicates_find_nearest
815 template <typename T>
816 struct predicates_find_distance
818 static const unsigned value = predicates_is_distance<T>::value ? 0 : 1;
821 //template <typename F, typename S>
822 //struct predicates_find_distance< std::pair<F, S> >
824 // static const unsigned value = predicates_is_distance<F>::value ? 0 :
825 // (predicates_is_distance<S>::value ? 1 : 2);
828 template <typename Tuple, unsigned N>
829 struct predicates_find_distance_tuple
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;
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);
840 template <typename Tuple>
841 struct predicates_find_distance_tuple<Tuple, 1>
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;
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> >
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
856 template <typename Head, typename Tail>
857 struct predicates_find_distance< boost::tuples::cons<Head, Tail> >
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
865 }}}} // namespace boost::geometry::index::detail
867 #endif // BOOST_GEOMETRY_INDEX_DETAIL_PREDICATES_HPP