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
14 #include <boost/geometry/index/predicates.hpp>
15 #include <boost/geometry/index/detail/tags.hpp>
17 namespace boost { namespace geometry { namespace index { namespace detail {
19 namespace predicates {
21 // ------------------------------------------------------------------ //
23 // ------------------------------------------------------------------ //
25 template <typename Fun, bool IsFunction>
28 satisfies_impl() : fun(NULL) {}
29 satisfies_impl(Fun f) : fun(f) {}
33 template <typename Fun>
34 struct satisfies_impl<Fun, false>
37 satisfies_impl(Fun const& f) : fun(f) {}
41 template <typename Fun, bool Negated>
43 : satisfies_impl<Fun, ::boost::is_function<Fun>::value>
45 typedef satisfies_impl<Fun, ::boost::is_function<Fun>::value> base;
48 satisfies(Fun const& f) : base(f) {}
49 satisfies(base const& b) : base(b) {}
52 // ------------------------------------------------------------------ //
54 struct contains_tag {};
55 struct covered_by_tag {};
57 struct disjoint_tag {};
58 struct intersects_tag {};
59 struct overlaps_tag {};
60 struct touches_tag {};
63 template <typename Geometry, typename Tag, bool Negated>
64 struct spatial_predicate
66 spatial_predicate() {}
67 spatial_predicate(Geometry const& g) : geometry(g) {}
71 // ------------------------------------------------------------------ //
73 // CONSIDER: separated nearest<> and path<> may be replaced by
74 // nearest_predicate<Geometry, Tag>
75 // where Tag = point_tag | path_tag
76 // IMPROVEMENT: user-defined nearest predicate allowing to define
77 // all or only geometrical aspects of the search
79 template <typename PointOrRelation>
85 nearest(PointOrRelation const& por, unsigned k)
86 : point_or_relation(por)
89 PointOrRelation point_or_relation;
93 template <typename SegmentOrLinestring>
99 path(SegmentOrLinestring const& g, unsigned k)
103 SegmentOrLinestring geometry;
107 } // namespace predicates
109 // ------------------------------------------------------------------ //
111 // ------------------------------------------------------------------ //
113 template <typename Predicate, typename Tag>
114 struct predicate_check
116 BOOST_MPL_ASSERT_MSG(
118 NOT_IMPLEMENTED_FOR_THIS_PREDICATE_OR_TAG,
122 // ------------------------------------------------------------------ //
124 template <typename Fun>
125 struct predicate_check<predicates::satisfies<Fun, false>, value_tag>
127 template <typename Value, typename Indexable>
128 static inline bool apply(predicates::satisfies<Fun, false> const& p, Value const& v, Indexable const&)
134 template <typename Fun>
135 struct predicate_check<predicates::satisfies<Fun, true>, value_tag>
137 template <typename Value, typename Indexable>
138 static inline bool apply(predicates::satisfies<Fun, true> const& p, Value const& v, Indexable const&)
144 // ------------------------------------------------------------------ //
146 template <typename Tag>
147 struct spatial_predicate_call
149 BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_TAG, (Tag));
153 struct spatial_predicate_call<predicates::contains_tag>
155 template <typename G1, typename G2>
156 static inline bool apply(G1 const& g1, G2 const& g2)
158 return geometry::within(g2, g1);
163 struct spatial_predicate_call<predicates::covered_by_tag>
165 template <typename G1, typename G2>
166 static inline bool apply(G1 const& g1, G2 const& g2)
168 return geometry::covered_by(g1, g2);
173 struct spatial_predicate_call<predicates::covers_tag>
175 template <typename G1, typename G2>
176 static inline bool apply(G1 const& g1, G2 const& g2)
178 return geometry::covered_by(g2, g1);
183 struct spatial_predicate_call<predicates::disjoint_tag>
185 template <typename G1, typename G2>
186 static inline bool apply(G1 const& g1, G2 const& g2)
188 return geometry::disjoint(g1, g2);
193 struct spatial_predicate_call<predicates::intersects_tag>
195 template <typename G1, typename G2>
196 static inline bool apply(G1 const& g1, G2 const& g2)
198 return geometry::intersects(g1, g2);
203 struct spatial_predicate_call<predicates::overlaps_tag>
205 template <typename G1, typename G2>
206 static inline bool apply(G1 const& g1, G2 const& g2)
208 return geometry::overlaps(g1, g2);
213 struct spatial_predicate_call<predicates::touches_tag>
215 template <typename G1, typename G2>
216 static inline bool apply(G1 const& g1, G2 const& g2)
218 return geometry::touches(g1, g2);
223 struct spatial_predicate_call<predicates::within_tag>
225 template <typename G1, typename G2>
226 static inline bool apply(G1 const& g1, G2 const& g2)
228 return geometry::within(g1, g2);
232 // ------------------------------------------------------------------ //
235 template <typename Geometry, typename Tag>
236 struct predicate_check<predicates::spatial_predicate<Geometry, Tag, false>, value_tag>
238 typedef predicates::spatial_predicate<Geometry, Tag, false> Pred;
240 template <typename Value, typename Indexable>
241 static inline bool apply(Pred const& p, Value const&, Indexable const& i)
243 return spatial_predicate_call<Tag>::apply(i, p.geometry);
247 // negated spatial predicate
248 template <typename Geometry, typename Tag>
249 struct predicate_check<predicates::spatial_predicate<Geometry, Tag, true>, value_tag>
251 typedef predicates::spatial_predicate<Geometry, Tag, true> Pred;
253 template <typename Value, typename Indexable>
254 static inline bool apply(Pred const& p, Value const&, Indexable const& i)
256 return !spatial_predicate_call<Tag>::apply(i, p.geometry);
260 // ------------------------------------------------------------------ //
262 template <typename DistancePredicates>
263 struct predicate_check<predicates::nearest<DistancePredicates>, value_tag>
265 template <typename Value, typename Box>
266 static inline bool apply(predicates::nearest<DistancePredicates> const&, Value const&, Box const&)
272 template <typename Linestring>
273 struct predicate_check<predicates::path<Linestring>, value_tag>
275 template <typename Value, typename Box>
276 static inline bool apply(predicates::path<Linestring> const&, Value const&, Box const&)
282 // ------------------------------------------------------------------ //
283 // predicates_check for bounds
284 // ------------------------------------------------------------------ //
286 template <typename Fun, bool Negated>
287 struct predicate_check<predicates::satisfies<Fun, Negated>, bounds_tag>
289 template <typename Value, typename Box>
290 static bool apply(predicates::satisfies<Fun, Negated> const&, Value const&, Box const&)
296 // ------------------------------------------------------------------ //
299 // value_tag bounds_tag
300 // ---------------------------
301 // contains(I,G) covers(I,G)
302 // covered_by(I,G) intersects(I,G)
303 // covers(I,G) covers(I,G)
304 // disjoint(I,G) !covered_by(I,G)
305 // intersects(I,G) intersects(I,G)
306 // overlaps(I,G) intersects(I,G) - possibly change to the version without border case, e.g. intersects_without_border(0,0x1,1, 1,1x2,2) should give false
307 // touches(I,G) intersects(I,G)
308 // within(I,G) intersects(I,G) - possibly change to the version without border case, e.g. intersects_without_border(0,0x1,1, 1,1x2,2) should give false
310 // spatial predicate - default
311 template <typename Geometry, typename Tag>
312 struct predicate_check<predicates::spatial_predicate<Geometry, Tag, false>, bounds_tag>
314 typedef predicates::spatial_predicate<Geometry, Tag, false> Pred;
316 template <typename Value, typename Indexable>
317 static inline bool apply(Pred const& p, Value const&, Indexable const& i)
319 return spatial_predicate_call<predicates::intersects_tag>::apply(i, p.geometry);
323 // spatial predicate - contains
324 template <typename Geometry>
325 struct predicate_check<predicates::spatial_predicate<Geometry, predicates::contains_tag, false>, bounds_tag>
327 typedef predicates::spatial_predicate<Geometry, predicates::contains_tag, false> Pred;
329 template <typename Value, typename Indexable>
330 static inline bool apply(Pred const& p, Value const&, Indexable const& i)
332 return spatial_predicate_call<predicates::covers_tag>::apply(i, p.geometry);
336 // spatial predicate - covers
337 template <typename Geometry>
338 struct predicate_check<predicates::spatial_predicate<Geometry, predicates::covers_tag, false>, bounds_tag>
340 typedef predicates::spatial_predicate<Geometry, predicates::covers_tag, false> Pred;
342 template <typename Value, typename Indexable>
343 static inline bool apply(Pred const& p, Value const&, Indexable const& i)
345 return spatial_predicate_call<predicates::covers_tag>::apply(i, p.geometry);
349 // spatial predicate - disjoint
350 template <typename Geometry>
351 struct predicate_check<predicates::spatial_predicate<Geometry, predicates::disjoint_tag, false>, bounds_tag>
353 typedef predicates::spatial_predicate<Geometry, predicates::disjoint_tag, false> Pred;
355 template <typename Value, typename Indexable>
356 static inline bool apply(Pred const& p, Value const&, Indexable const& i)
358 return !spatial_predicate_call<predicates::covered_by_tag>::apply(i, p.geometry);
363 // value_tag bounds_tag
364 // ---------------------------
365 // !contains(I,G) TRUE
366 // !covered_by(I,G) !covered_by(I,G)
368 // !disjoint(I,G) !disjoint(I,G)
369 // !intersects(I,G) !covered_by(I,G)
370 // !overlaps(I,G) TRUE
371 // !touches(I,G) !intersects(I,G)
372 // !within(I,G) !within(I,G)
374 // negated spatial predicate - default
375 template <typename Geometry, typename Tag>
376 struct predicate_check<predicates::spatial_predicate<Geometry, Tag, true>, bounds_tag>
378 typedef predicates::spatial_predicate<Geometry, Tag, true> Pred;
380 template <typename Value, typename Indexable>
381 static inline bool apply(Pred const& p, Value const&, Indexable const& i)
383 return !spatial_predicate_call<Tag>::apply(i, p.geometry);
387 // negated spatial predicate - contains
388 template <typename Geometry>
389 struct predicate_check<predicates::spatial_predicate<Geometry, predicates::contains_tag, true>, bounds_tag>
391 typedef predicates::spatial_predicate<Geometry, predicates::contains_tag, true> Pred;
393 template <typename Value, typename Indexable>
394 static inline bool apply(Pred const& , Value const&, Indexable const& )
400 // negated spatial predicate - covers
401 template <typename Geometry>
402 struct predicate_check<predicates::spatial_predicate<Geometry, predicates::covers_tag, true>, bounds_tag>
404 typedef predicates::spatial_predicate<Geometry, predicates::covers_tag, true> Pred;
406 template <typename Value, typename Indexable>
407 static inline bool apply(Pred const& , Value const&, Indexable const& )
413 // negated spatial predicate - intersects
414 template <typename Geometry>
415 struct predicate_check<predicates::spatial_predicate<Geometry, predicates::intersects_tag, true>, bounds_tag>
417 typedef predicates::spatial_predicate<Geometry, predicates::intersects_tag, true> Pred;
419 template <typename Value, typename Indexable>
420 static inline bool apply(Pred const& p, Value const&, Indexable const& i)
422 return !spatial_predicate_call<predicates::covered_by_tag>::apply(i, p.geometry);
426 // negated spatial predicate - overlaps
427 template <typename Geometry>
428 struct predicate_check<predicates::spatial_predicate<Geometry, predicates::overlaps_tag, true>, bounds_tag>
430 typedef predicates::spatial_predicate<Geometry, predicates::overlaps_tag, true> Pred;
432 template <typename Value, typename Indexable>
433 static inline bool apply(Pred const& , Value const&, Indexable const& )
439 // negated spatial predicate - touches
440 template <typename Geometry>
441 struct predicate_check<predicates::spatial_predicate<Geometry, predicates::touches_tag, true>, bounds_tag>
443 typedef predicates::spatial_predicate<Geometry, predicates::touches_tag, true> Pred;
445 template <typename Value, typename Indexable>
446 static inline bool apply(Pred const& p, Value const&, Indexable const& i)
448 return !spatial_predicate_call<predicates::intersects_tag>::apply(i, p.geometry);
452 // ------------------------------------------------------------------ //
454 template <typename DistancePredicates>
455 struct predicate_check<predicates::nearest<DistancePredicates>, bounds_tag>
457 template <typename Value, typename Box>
458 static inline bool apply(predicates::nearest<DistancePredicates> const&, Value const&, Box const&)
464 template <typename Linestring>
465 struct predicate_check<predicates::path<Linestring>, bounds_tag>
467 template <typename Value, typename Box>
468 static inline bool apply(predicates::path<Linestring> const&, Value const&, Box const&)
474 // ------------------------------------------------------------------ //
476 // ------------------------------------------------------------------ //
478 template <typename T>
479 struct predicates_length
481 static const unsigned value = 1;
484 //template <typename F, typename S>
485 //struct predicates_length< std::pair<F, S> >
487 // static const unsigned value = 2;
490 //template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
491 //struct predicates_length< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >
493 // static const unsigned value = boost::tuples::length< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >::value;
496 template <typename Head, typename Tail>
497 struct predicates_length< boost::tuples::cons<Head, Tail> >
499 static const unsigned value = boost::tuples::length< boost::tuples::cons<Head, Tail> >::value;
502 // ------------------------------------------------------------------ //
503 // predicates_element
504 // ------------------------------------------------------------------ //
506 template <unsigned I, typename T>
507 struct predicates_element
509 BOOST_MPL_ASSERT_MSG((I < 1), INVALID_INDEX, (predicates_element));
511 static type const& get(T const& p) { return p; }
514 //template <unsigned I, typename F, typename S>
515 //struct predicates_element< I, std::pair<F, S> >
517 // BOOST_MPL_ASSERT_MSG((I < 2), INVALID_INDEX, (predicates_element));
520 // static type const& get(std::pair<F, S> const& p) { return p.first; }
523 //template <typename F, typename S>
524 //struct predicates_element< 1, std::pair<F, S> >
527 // static type const& get(std::pair<F, S> const& p) { return p.second; }
530 //template <unsigned I, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
531 //struct predicates_element< I, boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >
533 // typedef boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> predicate_type;
535 // typedef typename boost::tuples::element<I, predicate_type>::type type;
536 // static type const& get(predicate_type const& p) { return boost::get<I>(p); }
539 template <unsigned I, typename Head, typename Tail>
540 struct predicates_element< I, boost::tuples::cons<Head, Tail> >
542 typedef boost::tuples::cons<Head, Tail> predicate_type;
544 typedef typename boost::tuples::element<I, predicate_type>::type type;
545 static type const& get(predicate_type const& p) { return boost::get<I>(p); }
548 // ------------------------------------------------------------------ //
550 // ------------------------------------------------------------------ //
552 //template <typename PairPredicates, typename Tag, unsigned First, unsigned Last>
553 //struct predicates_check_pair {};
555 //template <typename PairPredicates, typename Tag, unsigned I>
556 //struct predicates_check_pair<PairPredicates, Tag, I, I>
558 // template <typename Value, typename Indexable>
559 // static inline bool apply(PairPredicates const& , Value const& , Indexable const& )
565 //template <typename PairPredicates, typename Tag>
566 //struct predicates_check_pair<PairPredicates, Tag, 0, 1>
568 // template <typename Value, typename Indexable>
569 // static inline bool apply(PairPredicates const& p, Value const& v, Indexable const& i)
571 // return predicate_check<typename PairPredicates::first_type, Tag>::apply(p.first, v, i);
575 //template <typename PairPredicates, typename Tag>
576 //struct predicates_check_pair<PairPredicates, Tag, 1, 2>
578 // template <typename Value, typename Indexable>
579 // static inline bool apply(PairPredicates const& p, Value const& v, Indexable const& i)
581 // return predicate_check<typename PairPredicates::second_type, Tag>::apply(p.second, v, i);
585 //template <typename PairPredicates, typename Tag>
586 //struct predicates_check_pair<PairPredicates, Tag, 0, 2>
588 // template <typename Value, typename Indexable>
589 // static inline bool apply(PairPredicates const& p, Value const& v, Indexable const& i)
591 // return predicate_check<typename PairPredicates::first_type, Tag>::apply(p.first, v, i)
592 // && predicate_check<typename PairPredicates::second_type, Tag>::apply(p.second, v, i);
596 template <typename TuplePredicates, typename Tag, unsigned First, unsigned Last>
597 struct predicates_check_tuple
599 template <typename Value, typename Indexable>
600 static inline bool apply(TuplePredicates const& p, Value const& v, Indexable const& i)
604 typename boost::tuples::element<First, TuplePredicates>::type,
606 >::apply(boost::get<First>(p), v, i) &&
607 predicates_check_tuple<TuplePredicates, Tag, First+1, Last>::apply(p, v, i);
611 template <typename TuplePredicates, typename Tag, unsigned First>
612 struct predicates_check_tuple<TuplePredicates, Tag, First, First>
614 template <typename Value, typename Indexable>
615 static inline bool apply(TuplePredicates const& , Value const& , Indexable const& )
621 template <typename Predicate, typename Tag, unsigned First, unsigned Last>
622 struct predicates_check_impl
624 static const bool check = First < 1 && Last <= 1 && First <= Last;
625 BOOST_MPL_ASSERT_MSG((check), INVALID_INDEXES, (predicates_check_impl));
627 template <typename Value, typename Indexable>
628 static inline bool apply(Predicate const& p, Value const& v, Indexable const& i)
630 return predicate_check<Predicate, Tag>::apply(p, v, i);
634 //template <typename Predicate1, typename Predicate2, typename Tag, size_t First, size_t Last>
635 //struct predicates_check_impl<std::pair<Predicate1, Predicate2>, Tag, First, Last>
637 // BOOST_MPL_ASSERT_MSG((First < 2 && Last <= 2 && First <= Last), INVALID_INDEXES, (predicates_check_impl));
639 // template <typename Value, typename Indexable>
640 // static inline bool apply(std::pair<Predicate1, Predicate2> const& p, Value const& v, Indexable const& i)
642 // return predicate_check<Predicate1, Tag>::apply(p.first, v, i)
643 // && predicate_check<Predicate2, Tag>::apply(p.second, v, i);
648 // typename T0, typename T1, typename T2, typename T3, typename T4,
649 // typename T5, typename T6, typename T7, typename T8, typename T9,
650 // typename Tag, unsigned First, unsigned Last
652 //struct predicates_check_impl<
653 // boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>,
657 // typedef boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> predicates_type;
659 // static const unsigned pred_len = boost::tuples::length<predicates_type>::value;
660 // BOOST_MPL_ASSERT_MSG((First < pred_len && Last <= pred_len && First <= Last), INVALID_INDEXES, (predicates_check_impl));
662 // template <typename Value, typename Indexable>
663 // static inline bool apply(predicates_type const& p, Value const& v, Indexable const& i)
665 // return predicates_check_tuple<
668 // >::apply(p, v, i);
672 template <typename Head, typename Tail, typename Tag, unsigned First, unsigned Last>
673 struct predicates_check_impl<
674 boost::tuples::cons<Head, Tail>,
678 typedef boost::tuples::cons<Head, Tail> predicates_type;
680 static const unsigned pred_len = boost::tuples::length<predicates_type>::value;
681 static const bool check = First < pred_len && Last <= pred_len && First <= Last;
682 BOOST_MPL_ASSERT_MSG((check), INVALID_INDEXES, (predicates_check_impl));
684 template <typename Value, typename Indexable>
685 static inline bool apply(predicates_type const& p, Value const& v, Indexable const& i)
687 return predicates_check_tuple<
694 template <typename Tag, unsigned First, unsigned Last, typename Predicates, typename Value, typename Indexable>
695 inline bool predicates_check(Predicates const& p, Value const& v, Indexable const& i)
697 return detail::predicates_check_impl<Predicates, Tag, First, Last>
701 // ------------------------------------------------------------------ //
702 // nearest predicate helpers
703 // ------------------------------------------------------------------ //
705 // predicates_is_nearest
707 template <typename P>
708 struct predicates_is_distance
710 static const unsigned value = 0;
713 template <typename DistancePredicates>
714 struct predicates_is_distance< predicates::nearest<DistancePredicates> >
716 static const unsigned value = 1;
719 template <typename Linestring>
720 struct predicates_is_distance< predicates::path<Linestring> >
722 static const unsigned value = 1;
725 // predicates_count_nearest
727 template <typename T>
728 struct predicates_count_distance
730 static const unsigned value = predicates_is_distance<T>::value;
733 //template <typename F, typename S>
734 //struct predicates_count_distance< std::pair<F, S> >
736 // static const unsigned value = predicates_is_distance<F>::value
737 // + predicates_is_distance<S>::value;
740 template <typename Tuple, unsigned N>
741 struct predicates_count_distance_tuple
743 static const unsigned value =
744 predicates_is_distance<typename boost::tuples::element<N-1, Tuple>::type>::value
745 + predicates_count_distance_tuple<Tuple, N-1>::value;
748 template <typename Tuple>
749 struct predicates_count_distance_tuple<Tuple, 1>
751 static const unsigned value =
752 predicates_is_distance<typename boost::tuples::element<0, Tuple>::type>::value;
755 //template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
756 //struct predicates_count_distance< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >
758 // static const unsigned value = predicates_count_distance_tuple<
759 // boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>,
760 // boost::tuples::length< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >::value
764 template <typename Head, typename Tail>
765 struct predicates_count_distance< boost::tuples::cons<Head, Tail> >
767 static const unsigned value = predicates_count_distance_tuple<
768 boost::tuples::cons<Head, Tail>,
769 boost::tuples::length< boost::tuples::cons<Head, Tail> >::value
773 // predicates_find_nearest
775 template <typename T>
776 struct predicates_find_distance
778 static const unsigned value = predicates_is_distance<T>::value ? 0 : 1;
781 //template <typename F, typename S>
782 //struct predicates_find_distance< std::pair<F, S> >
784 // static const unsigned value = predicates_is_distance<F>::value ? 0 :
785 // (predicates_is_distance<S>::value ? 1 : 2);
788 template <typename Tuple, unsigned N>
789 struct predicates_find_distance_tuple
791 static const bool is_found = predicates_find_distance_tuple<Tuple, N-1>::is_found
792 || predicates_is_distance<typename boost::tuples::element<N-1, Tuple>::type>::value;
794 static const unsigned value = predicates_find_distance_tuple<Tuple, N-1>::is_found ?
795 predicates_find_distance_tuple<Tuple, N-1>::value :
796 (predicates_is_distance<typename boost::tuples::element<N-1, Tuple>::type>::value ?
797 N-1 : boost::tuples::length<Tuple>::value);
800 template <typename Tuple>
801 struct predicates_find_distance_tuple<Tuple, 1>
803 static const bool is_found = predicates_is_distance<typename boost::tuples::element<0, Tuple>::type>::value;
804 static const unsigned value = is_found ? 0 : boost::tuples::length<Tuple>::value;
807 //template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
808 //struct predicates_find_distance< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >
810 // static const unsigned value = predicates_find_distance_tuple<
811 // boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>,
812 // boost::tuples::length< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >::value
816 template <typename Head, typename Tail>
817 struct predicates_find_distance< boost::tuples::cons<Head, Tail> >
819 static const unsigned value = predicates_find_distance_tuple<
820 boost::tuples::cons<Head, Tail>,
821 boost::tuples::length< boost::tuples::cons<Head, Tail> >::value
825 }}}} // namespace boost::geometry::index::detail
827 #endif // BOOST_GEOMETRY_INDEX_DETAIL_PREDICATES_HPP