1 // Boost.Geometry Index
3 // Spatial query predicates definition and checks.
5 // Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
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)
11 #ifndef BOOST_GEOMETRY_INDEX_DETAIL_PREDICATES_HPP
12 #define BOOST_GEOMETRY_INDEX_DETAIL_PREDICATES_HPP
16 #include <boost/mpl/assert.hpp>
17 #include <boost/tuple/tuple.hpp>
19 #include <boost/geometry/index/detail/tags.hpp>
21 namespace boost { namespace geometry { namespace index { namespace detail {
23 namespace predicates {
25 // ------------------------------------------------------------------ //
27 // ------------------------------------------------------------------ //
29 template <typename Fun, bool IsFunction>
32 satisfies_impl() : fun(NULL) {}
33 satisfies_impl(Fun f) : fun(f) {}
37 template <typename Fun>
38 struct satisfies_impl<Fun, false>
41 satisfies_impl(Fun const& f) : fun(f) {}
45 template <typename Fun, bool Negated>
47 : satisfies_impl<Fun, ::boost::is_function<Fun>::value>
49 typedef satisfies_impl<Fun, ::boost::is_function<Fun>::value> base;
52 satisfies(Fun const& f) : base(f) {}
53 satisfies(base const& b) : base(b) {}
56 // ------------------------------------------------------------------ //
58 struct contains_tag {};
59 struct covered_by_tag {};
61 struct disjoint_tag {};
62 struct intersects_tag {};
63 struct overlaps_tag {};
64 struct touches_tag {};
67 template <typename Geometry, typename Tag, bool Negated>
68 struct spatial_predicate
70 spatial_predicate() {}
71 spatial_predicate(Geometry const& g) : geometry(g) {}
75 // ------------------------------------------------------------------ //
77 // CONSIDER: separated nearest<> and path<> may be replaced by
78 // nearest_predicate<Geometry, Tag>
79 // where Tag = point_tag | path_tag
80 // IMPROVEMENT: user-defined nearest predicate allowing to define
81 // all or only geometrical aspects of the search
83 template <typename PointOrRelation>
89 nearest(PointOrRelation const& por, unsigned k)
90 : point_or_relation(por)
93 PointOrRelation point_or_relation;
97 template <typename SegmentOrLinestring>
103 path(SegmentOrLinestring const& g, unsigned k)
107 SegmentOrLinestring geometry;
111 } // namespace predicates
113 // ------------------------------------------------------------------ //
115 // ------------------------------------------------------------------ //
117 template <typename Predicate, typename Tag>
118 struct predicate_check
120 BOOST_MPL_ASSERT_MSG(
122 NOT_IMPLEMENTED_FOR_THIS_PREDICATE_OR_TAG,
126 // ------------------------------------------------------------------ //
128 template <typename Fun>
129 struct predicate_check<predicates::satisfies<Fun, false>, value_tag>
131 template <typename Value, typename Indexable>
132 static inline bool apply(predicates::satisfies<Fun, false> const& p, Value const& v, Indexable const&)
138 template <typename Fun>
139 struct predicate_check<predicates::satisfies<Fun, true>, value_tag>
141 template <typename Value, typename Indexable>
142 static inline bool apply(predicates::satisfies<Fun, true> const& p, Value const& v, Indexable const&)
148 // ------------------------------------------------------------------ //
150 template <typename Tag>
151 struct spatial_predicate_call
153 BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_TAG, (Tag));
157 struct spatial_predicate_call<predicates::contains_tag>
159 template <typename G1, typename G2>
160 static inline bool apply(G1 const& g1, G2 const& g2)
162 return geometry::within(g2, g1);
167 struct spatial_predicate_call<predicates::covered_by_tag>
169 template <typename G1, typename G2>
170 static inline bool apply(G1 const& g1, G2 const& g2)
172 return geometry::covered_by(g1, g2);
177 struct spatial_predicate_call<predicates::covers_tag>
179 template <typename G1, typename G2>
180 static inline bool apply(G1 const& g1, G2 const& g2)
182 return geometry::covered_by(g2, g1);
187 struct spatial_predicate_call<predicates::disjoint_tag>
189 template <typename G1, typename G2>
190 static inline bool apply(G1 const& g1, G2 const& g2)
192 return geometry::disjoint(g1, g2);
197 struct spatial_predicate_call<predicates::intersects_tag>
199 template <typename G1, typename G2>
200 static inline bool apply(G1 const& g1, G2 const& g2)
202 return geometry::intersects(g1, g2);
207 struct spatial_predicate_call<predicates::overlaps_tag>
209 template <typename G1, typename G2>
210 static inline bool apply(G1 const& g1, G2 const& g2)
212 return geometry::overlaps(g1, g2);
217 struct spatial_predicate_call<predicates::touches_tag>
219 template <typename G1, typename G2>
220 static inline bool apply(G1 const& g1, G2 const& g2)
222 return geometry::touches(g1, g2);
227 struct spatial_predicate_call<predicates::within_tag>
229 template <typename G1, typename G2>
230 static inline bool apply(G1 const& g1, G2 const& g2)
232 return geometry::within(g1, g2);
236 // ------------------------------------------------------------------ //
239 template <typename Geometry, typename Tag>
240 struct predicate_check<predicates::spatial_predicate<Geometry, Tag, false>, value_tag>
242 typedef predicates::spatial_predicate<Geometry, Tag, false> Pred;
244 template <typename Value, typename Indexable>
245 static inline bool apply(Pred const& p, Value const&, Indexable const& i)
247 return spatial_predicate_call<Tag>::apply(i, p.geometry);
251 // negated spatial predicate
252 template <typename Geometry, typename Tag>
253 struct predicate_check<predicates::spatial_predicate<Geometry, Tag, true>, value_tag>
255 typedef predicates::spatial_predicate<Geometry, Tag, true> Pred;
257 template <typename Value, typename Indexable>
258 static inline bool apply(Pred const& p, Value const&, Indexable const& i)
260 return !spatial_predicate_call<Tag>::apply(i, p.geometry);
264 // ------------------------------------------------------------------ //
266 template <typename DistancePredicates>
267 struct predicate_check<predicates::nearest<DistancePredicates>, value_tag>
269 template <typename Value, typename Box>
270 static inline bool apply(predicates::nearest<DistancePredicates> const&, Value const&, Box const&)
276 template <typename Linestring>
277 struct predicate_check<predicates::path<Linestring>, value_tag>
279 template <typename Value, typename Box>
280 static inline bool apply(predicates::path<Linestring> const&, Value const&, Box const&)
286 // ------------------------------------------------------------------ //
287 // predicates_check for bounds
288 // ------------------------------------------------------------------ //
290 template <typename Fun, bool Negated>
291 struct predicate_check<predicates::satisfies<Fun, Negated>, bounds_tag>
293 template <typename Value, typename Box>
294 static bool apply(predicates::satisfies<Fun, Negated> const&, Value const&, Box const&)
300 // ------------------------------------------------------------------ //
303 // value_tag bounds_tag
304 // ---------------------------
305 // contains(I,G) covers(I,G)
306 // covered_by(I,G) intersects(I,G)
307 // covers(I,G) covers(I,G)
308 // disjoint(I,G) !covered_by(I,G)
309 // intersects(I,G) intersects(I,G)
310 // 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
311 // touches(I,G) intersects(I,G)
312 // 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
314 // spatial predicate - default
315 template <typename Geometry, typename Tag>
316 struct predicate_check<predicates::spatial_predicate<Geometry, Tag, false>, bounds_tag>
318 typedef predicates::spatial_predicate<Geometry, Tag, false> Pred;
320 template <typename Value, typename Indexable>
321 static inline bool apply(Pred const& p, Value const&, Indexable const& i)
323 return spatial_predicate_call<predicates::intersects_tag>::apply(i, p.geometry);
327 // spatial predicate - contains
328 template <typename Geometry>
329 struct predicate_check<predicates::spatial_predicate<Geometry, predicates::contains_tag, false>, bounds_tag>
331 typedef predicates::spatial_predicate<Geometry, predicates::contains_tag, false> Pred;
333 template <typename Value, typename Indexable>
334 static inline bool apply(Pred const& p, Value const&, Indexable const& i)
336 return spatial_predicate_call<predicates::covers_tag>::apply(i, p.geometry);
340 // spatial predicate - covers
341 template <typename Geometry>
342 struct predicate_check<predicates::spatial_predicate<Geometry, predicates::covers_tag, false>, bounds_tag>
344 typedef predicates::spatial_predicate<Geometry, predicates::covers_tag, false> Pred;
346 template <typename Value, typename Indexable>
347 static inline bool apply(Pred const& p, Value const&, Indexable const& i)
349 return spatial_predicate_call<predicates::covers_tag>::apply(i, p.geometry);
353 // spatial predicate - disjoint
354 template <typename Geometry>
355 struct predicate_check<predicates::spatial_predicate<Geometry, predicates::disjoint_tag, false>, bounds_tag>
357 typedef predicates::spatial_predicate<Geometry, predicates::disjoint_tag, false> Pred;
359 template <typename Value, typename Indexable>
360 static inline bool apply(Pred const& p, Value const&, Indexable const& i)
362 return !spatial_predicate_call<predicates::covered_by_tag>::apply(i, p.geometry);
367 // value_tag bounds_tag
368 // ---------------------------
369 // !contains(I,G) TRUE
370 // !covered_by(I,G) !covered_by(I,G)
372 // !disjoint(I,G) !disjoint(I,G)
373 // !intersects(I,G) !covered_by(I,G)
374 // !overlaps(I,G) TRUE
375 // !touches(I,G) !intersects(I,G)
376 // !within(I,G) !within(I,G)
378 // negated spatial predicate - default
379 template <typename Geometry, typename Tag>
380 struct predicate_check<predicates::spatial_predicate<Geometry, Tag, true>, bounds_tag>
382 typedef predicates::spatial_predicate<Geometry, Tag, true> Pred;
384 template <typename Value, typename Indexable>
385 static inline bool apply(Pred const& p, Value const&, Indexable const& i)
387 return !spatial_predicate_call<Tag>::apply(i, p.geometry);
391 // negated spatial predicate - contains
392 template <typename Geometry>
393 struct predicate_check<predicates::spatial_predicate<Geometry, predicates::contains_tag, true>, bounds_tag>
395 typedef predicates::spatial_predicate<Geometry, predicates::contains_tag, true> Pred;
397 template <typename Value, typename Indexable>
398 static inline bool apply(Pred const& , Value const&, Indexable const& )
404 // negated spatial predicate - covers
405 template <typename Geometry>
406 struct predicate_check<predicates::spatial_predicate<Geometry, predicates::covers_tag, true>, bounds_tag>
408 typedef predicates::spatial_predicate<Geometry, predicates::covers_tag, true> Pred;
410 template <typename Value, typename Indexable>
411 static inline bool apply(Pred const& , Value const&, Indexable const& )
417 // negated spatial predicate - intersects
418 template <typename Geometry>
419 struct predicate_check<predicates::spatial_predicate<Geometry, predicates::intersects_tag, true>, bounds_tag>
421 typedef predicates::spatial_predicate<Geometry, predicates::intersects_tag, true> Pred;
423 template <typename Value, typename Indexable>
424 static inline bool apply(Pred const& p, Value const&, Indexable const& i)
426 return !spatial_predicate_call<predicates::covered_by_tag>::apply(i, p.geometry);
430 // negated spatial predicate - overlaps
431 template <typename Geometry>
432 struct predicate_check<predicates::spatial_predicate<Geometry, predicates::overlaps_tag, true>, bounds_tag>
434 typedef predicates::spatial_predicate<Geometry, predicates::overlaps_tag, true> Pred;
436 template <typename Value, typename Indexable>
437 static inline bool apply(Pred const& , Value const&, Indexable const& )
443 // negated spatial predicate - touches
444 template <typename Geometry>
445 struct predicate_check<predicates::spatial_predicate<Geometry, predicates::touches_tag, true>, bounds_tag>
447 typedef predicates::spatial_predicate<Geometry, predicates::touches_tag, true> Pred;
449 template <typename Value, typename Indexable>
450 static inline bool apply(Pred const& p, Value const&, Indexable const& i)
452 return !spatial_predicate_call<predicates::intersects_tag>::apply(i, p.geometry);
456 // ------------------------------------------------------------------ //
458 template <typename DistancePredicates>
459 struct predicate_check<predicates::nearest<DistancePredicates>, bounds_tag>
461 template <typename Value, typename Box>
462 static inline bool apply(predicates::nearest<DistancePredicates> const&, Value const&, Box const&)
468 template <typename Linestring>
469 struct predicate_check<predicates::path<Linestring>, bounds_tag>
471 template <typename Value, typename Box>
472 static inline bool apply(predicates::path<Linestring> const&, Value const&, Box const&)
478 // ------------------------------------------------------------------ //
480 // ------------------------------------------------------------------ //
482 template <typename T>
483 struct predicates_length
485 static const unsigned value = 1;
488 //template <typename F, typename S>
489 //struct predicates_length< std::pair<F, S> >
491 // static const unsigned value = 2;
494 //template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
495 //struct predicates_length< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >
497 // static const unsigned value = boost::tuples::length< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >::value;
500 template <typename Head, typename Tail>
501 struct predicates_length< boost::tuples::cons<Head, Tail> >
503 static const unsigned value = boost::tuples::length< boost::tuples::cons<Head, Tail> >::value;
506 // ------------------------------------------------------------------ //
507 // predicates_element
508 // ------------------------------------------------------------------ //
510 template <unsigned I, typename T>
511 struct predicates_element
513 BOOST_MPL_ASSERT_MSG((I < 1), INVALID_INDEX, (predicates_element));
515 static type const& get(T const& p) { return p; }
518 //template <unsigned I, typename F, typename S>
519 //struct predicates_element< I, std::pair<F, S> >
521 // BOOST_MPL_ASSERT_MSG((I < 2), INVALID_INDEX, (predicates_element));
524 // static type const& get(std::pair<F, S> const& p) { return p.first; }
527 //template <typename F, typename S>
528 //struct predicates_element< 1, std::pair<F, S> >
531 // static type const& get(std::pair<F, S> const& p) { return p.second; }
534 //template <unsigned I, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
535 //struct predicates_element< I, boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >
537 // typedef boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> predicate_type;
539 // typedef typename boost::tuples::element<I, predicate_type>::type type;
540 // static type const& get(predicate_type const& p) { return boost::get<I>(p); }
543 template <unsigned I, typename Head, typename Tail>
544 struct predicates_element< I, boost::tuples::cons<Head, Tail> >
546 typedef boost::tuples::cons<Head, Tail> predicate_type;
548 typedef typename boost::tuples::element<I, predicate_type>::type type;
549 static type const& get(predicate_type const& p) { return boost::get<I>(p); }
552 // ------------------------------------------------------------------ //
554 // ------------------------------------------------------------------ //
556 //template <typename PairPredicates, typename Tag, unsigned First, unsigned Last>
557 //struct predicates_check_pair {};
559 //template <typename PairPredicates, typename Tag, unsigned I>
560 //struct predicates_check_pair<PairPredicates, Tag, I, I>
562 // template <typename Value, typename Indexable>
563 // static inline bool apply(PairPredicates const& , Value const& , Indexable const& )
569 //template <typename PairPredicates, typename Tag>
570 //struct predicates_check_pair<PairPredicates, Tag, 0, 1>
572 // template <typename Value, typename Indexable>
573 // static inline bool apply(PairPredicates const& p, Value const& v, Indexable const& i)
575 // return predicate_check<typename PairPredicates::first_type, Tag>::apply(p.first, v, i);
579 //template <typename PairPredicates, typename Tag>
580 //struct predicates_check_pair<PairPredicates, Tag, 1, 2>
582 // template <typename Value, typename Indexable>
583 // static inline bool apply(PairPredicates const& p, Value const& v, Indexable const& i)
585 // return predicate_check<typename PairPredicates::second_type, Tag>::apply(p.second, v, i);
589 //template <typename PairPredicates, typename Tag>
590 //struct predicates_check_pair<PairPredicates, Tag, 0, 2>
592 // template <typename Value, typename Indexable>
593 // static inline bool apply(PairPredicates const& p, Value const& v, Indexable const& i)
595 // return predicate_check<typename PairPredicates::first_type, Tag>::apply(p.first, v, i)
596 // && predicate_check<typename PairPredicates::second_type, Tag>::apply(p.second, v, i);
600 template <typename TuplePredicates, typename Tag, unsigned First, unsigned Last>
601 struct predicates_check_tuple
603 template <typename Value, typename Indexable>
604 static inline bool apply(TuplePredicates const& p, Value const& v, Indexable const& i)
608 typename boost::tuples::element<First, TuplePredicates>::type,
610 >::apply(boost::get<First>(p), v, i) &&
611 predicates_check_tuple<TuplePredicates, Tag, First+1, Last>::apply(p, v, i);
615 template <typename TuplePredicates, typename Tag, unsigned First>
616 struct predicates_check_tuple<TuplePredicates, Tag, First, First>
618 template <typename Value, typename Indexable>
619 static inline bool apply(TuplePredicates const& , Value const& , Indexable const& )
625 template <typename Predicate, typename Tag, unsigned First, unsigned Last>
626 struct predicates_check_impl
628 static const bool check = First < 1 && Last <= 1 && First <= Last;
629 BOOST_MPL_ASSERT_MSG((check), INVALID_INDEXES, (predicates_check_impl));
631 template <typename Value, typename Indexable>
632 static inline bool apply(Predicate const& p, Value const& v, Indexable const& i)
634 return predicate_check<Predicate, Tag>::apply(p, v, i);
638 //template <typename Predicate1, typename Predicate2, typename Tag, size_t First, size_t Last>
639 //struct predicates_check_impl<std::pair<Predicate1, Predicate2>, Tag, First, Last>
641 // BOOST_MPL_ASSERT_MSG((First < 2 && Last <= 2 && First <= Last), INVALID_INDEXES, (predicates_check_impl));
643 // template <typename Value, typename Indexable>
644 // static inline bool apply(std::pair<Predicate1, Predicate2> const& p, Value const& v, Indexable const& i)
646 // return predicate_check<Predicate1, Tag>::apply(p.first, v, i)
647 // && predicate_check<Predicate2, Tag>::apply(p.second, v, i);
652 // typename T0, typename T1, typename T2, typename T3, typename T4,
653 // typename T5, typename T6, typename T7, typename T8, typename T9,
654 // typename Tag, unsigned First, unsigned Last
656 //struct predicates_check_impl<
657 // boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>,
661 // typedef boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> predicates_type;
663 // static const unsigned pred_len = boost::tuples::length<predicates_type>::value;
664 // BOOST_MPL_ASSERT_MSG((First < pred_len && Last <= pred_len && First <= Last), INVALID_INDEXES, (predicates_check_impl));
666 // template <typename Value, typename Indexable>
667 // static inline bool apply(predicates_type const& p, Value const& v, Indexable const& i)
669 // return predicates_check_tuple<
672 // >::apply(p, v, i);
676 template <typename Head, typename Tail, typename Tag, unsigned First, unsigned Last>
677 struct predicates_check_impl<
678 boost::tuples::cons<Head, Tail>,
682 typedef boost::tuples::cons<Head, Tail> predicates_type;
684 static const unsigned pred_len = boost::tuples::length<predicates_type>::value;
685 static const bool check = First < pred_len && Last <= pred_len && First <= Last;
686 BOOST_MPL_ASSERT_MSG((check), INVALID_INDEXES, (predicates_check_impl));
688 template <typename Value, typename Indexable>
689 static inline bool apply(predicates_type const& p, Value const& v, Indexable const& i)
691 return predicates_check_tuple<
698 template <typename Tag, unsigned First, unsigned Last, typename Predicates, typename Value, typename Indexable>
699 inline bool predicates_check(Predicates const& p, Value const& v, Indexable const& i)
701 return detail::predicates_check_impl<Predicates, Tag, First, Last>
705 // ------------------------------------------------------------------ //
706 // nearest predicate helpers
707 // ------------------------------------------------------------------ //
709 // predicates_is_nearest
711 template <typename P>
712 struct predicates_is_distance
714 static const unsigned value = 0;
717 template <typename DistancePredicates>
718 struct predicates_is_distance< predicates::nearest<DistancePredicates> >
720 static const unsigned value = 1;
723 template <typename Linestring>
724 struct predicates_is_distance< predicates::path<Linestring> >
726 static const unsigned value = 1;
729 // predicates_count_nearest
731 template <typename T>
732 struct predicates_count_distance
734 static const unsigned value = predicates_is_distance<T>::value;
737 //template <typename F, typename S>
738 //struct predicates_count_distance< std::pair<F, S> >
740 // static const unsigned value = predicates_is_distance<F>::value
741 // + predicates_is_distance<S>::value;
744 template <typename Tuple, unsigned N>
745 struct predicates_count_distance_tuple
747 static const unsigned value =
748 predicates_is_distance<typename boost::tuples::element<N-1, Tuple>::type>::value
749 + predicates_count_distance_tuple<Tuple, N-1>::value;
752 template <typename Tuple>
753 struct predicates_count_distance_tuple<Tuple, 1>
755 static const unsigned value =
756 predicates_is_distance<typename boost::tuples::element<0, Tuple>::type>::value;
759 //template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
760 //struct predicates_count_distance< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >
762 // static const unsigned value = predicates_count_distance_tuple<
763 // boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>,
764 // boost::tuples::length< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >::value
768 template <typename Head, typename Tail>
769 struct predicates_count_distance< boost::tuples::cons<Head, Tail> >
771 static const unsigned value = predicates_count_distance_tuple<
772 boost::tuples::cons<Head, Tail>,
773 boost::tuples::length< boost::tuples::cons<Head, Tail> >::value
777 // predicates_find_nearest
779 template <typename T>
780 struct predicates_find_distance
782 static const unsigned value = predicates_is_distance<T>::value ? 0 : 1;
785 //template <typename F, typename S>
786 //struct predicates_find_distance< std::pair<F, S> >
788 // static const unsigned value = predicates_is_distance<F>::value ? 0 :
789 // (predicates_is_distance<S>::value ? 1 : 2);
792 template <typename Tuple, unsigned N>
793 struct predicates_find_distance_tuple
795 static const bool is_found = predicates_find_distance_tuple<Tuple, N-1>::is_found
796 || predicates_is_distance<typename boost::tuples::element<N-1, Tuple>::type>::value;
798 static const unsigned value = predicates_find_distance_tuple<Tuple, N-1>::is_found ?
799 predicates_find_distance_tuple<Tuple, N-1>::value :
800 (predicates_is_distance<typename boost::tuples::element<N-1, Tuple>::type>::value ?
801 N-1 : boost::tuples::length<Tuple>::value);
804 template <typename Tuple>
805 struct predicates_find_distance_tuple<Tuple, 1>
807 static const bool is_found = predicates_is_distance<typename boost::tuples::element<0, Tuple>::type>::value;
808 static const unsigned value = is_found ? 0 : boost::tuples::length<Tuple>::value;
811 //template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
812 //struct predicates_find_distance< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >
814 // static const unsigned value = predicates_find_distance_tuple<
815 // boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>,
816 // boost::tuples::length< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >::value
820 template <typename Head, typename Tail>
821 struct predicates_find_distance< boost::tuples::cons<Head, Tail> >
823 static const unsigned value = predicates_find_distance_tuple<
824 boost::tuples::cons<Head, Tail>,
825 boost::tuples::length< boost::tuples::cons<Head, Tail> >::value
829 }}}} // namespace boost::geometry::index::detail
831 #endif // BOOST_GEOMETRY_INDEX_DETAIL_PREDICATES_HPP