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

source code of boost/boost/geometry/index/detail/predicates.hpp