]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/geometry/index/detail/predicates.hpp
bump version to 18.2.4-pve3
[ceph.git] / ceph / src / boost / boost / geometry / index / detail / predicates.hpp
1 // Boost.Geometry Index
2 //
3 // Spatial query predicates definition and checks.
4 //
5 // Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
6 //
7 // This file was modified by Oracle on 2019-2021.
8 // Modifications copyright (c) 2019-2021 Oracle and/or its affiliates.
9 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
10 //
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)
14
15 #ifndef BOOST_GEOMETRY_INDEX_DETAIL_PREDICATES_HPP
16 #define BOOST_GEOMETRY_INDEX_DETAIL_PREDICATES_HPP
17
18 #include <tuple>
19 #include <type_traits>
20 //#include <utility>
21
22 #include <boost/geometry/core/static_assert.hpp>
23 #include <boost/geometry/core/tag.hpp>
24 #include <boost/geometry/core/tags.hpp>
25
26 #include <boost/geometry/index/detail/tags.hpp>
27
28 #include <boost/geometry/strategies/default_strategy.hpp>
29
30 namespace boost { namespace geometry { namespace index { namespace detail {
31
32 namespace predicates {
33
34 // ------------------------------------------------------------------ //
35 // predicates
36 // ------------------------------------------------------------------ //
37
38 template <typename Fun, bool IsFunction = std::is_function<Fun>::value>
39 struct satisfies_impl
40 {
41 satisfies_impl() : fun(nullptr) {}
42 satisfies_impl(Fun f) : fun(f) {}
43 Fun * fun;
44 };
45
46 template <typename Fun>
47 struct satisfies_impl<Fun, false>
48 {
49 satisfies_impl() = default;
50 satisfies_impl(Fun const& f) : fun(f) {}
51 Fun fun;
52 };
53
54 template <typename Fun, bool Negated>
55 struct satisfies : satisfies_impl<Fun>
56 {
57 using base_t = satisfies_impl<Fun>;
58
59 satisfies() = default;
60 satisfies(Fun const& f) : base_t(f) {}
61 satisfies(base_t const& b) : base_t(b) {}
62 };
63
64 // ------------------------------------------------------------------ //
65
66 struct contains_tag {};
67 struct covered_by_tag {};
68 struct covers_tag {};
69 struct disjoint_tag {};
70 struct intersects_tag {};
71 struct overlaps_tag {};
72 struct touches_tag {};
73 struct within_tag {};
74
75 template <typename Geometry, typename Tag, bool Negated>
76 struct spatial_predicate
77 {
78 spatial_predicate() {}
79 spatial_predicate(Geometry const& g) : geometry(g) {}
80 Geometry geometry;
81 };
82
83 // ------------------------------------------------------------------ //
84
85 // CONSIDER: separated nearest<> and path<> may be replaced by
86 // nearest_predicate<Geometry, Tag>
87 // where Tag = point_tag | path_tag
88 // IMPROVEMENT: user-defined nearest predicate allowing to define
89 // all or only geometrical aspects of the search
90
91 template <typename PointOrRelation>
92 struct nearest
93 {
94 nearest()
95 // : count(0)
96 {}
97 nearest(PointOrRelation const& por, std::size_t k)
98 : point_or_relation(por)
99 , count(k)
100 {}
101 PointOrRelation point_or_relation;
102 std::size_t count;
103 };
104
105 template <typename SegmentOrLinestring>
106 struct path
107 {
108 path()
109 // : count(0)
110 {}
111 path(SegmentOrLinestring const& g, std::size_t k)
112 : geometry(g)
113 , count(k)
114 {}
115 SegmentOrLinestring geometry;
116 std::size_t count;
117 };
118
119 } // namespace predicates
120
121 // ------------------------------------------------------------------ //
122 // predicate_check
123 // ------------------------------------------------------------------ //
124
125 template <typename Predicate, typename Tag>
126 struct predicate_check
127 {
128 BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
129 "Not implemented for this Predicate or Tag.",
130 Predicate, Tag);
131 };
132
133 // ------------------------------------------------------------------ //
134
135 template <typename Fun>
136 struct predicate_check<predicates::satisfies<Fun, false>, value_tag>
137 {
138 template <typename Value, typename Indexable, typename Strategy>
139 static inline bool apply(predicates::satisfies<Fun, false> const& p, Value const& v, Indexable const& , Strategy const&)
140 {
141 return p.fun(v);
142 }
143 };
144
145 template <typename Fun>
146 struct predicate_check<predicates::satisfies<Fun, true>, value_tag>
147 {
148 template <typename Value, typename Indexable, typename Strategy>
149 static inline bool apply(predicates::satisfies<Fun, true> const& p, Value const& v, Indexable const& , Strategy const&)
150 {
151 return !p.fun(v);
152 }
153 };
154
155 // ------------------------------------------------------------------ //
156
157 template <typename Tag>
158 struct spatial_predicate_call
159 {
160 BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
161 "Not implemented for this Tag.",
162 Tag);
163 };
164
165 template <>
166 struct spatial_predicate_call<predicates::contains_tag>
167 {
168 template <typename G1, typename G2, typename S>
169 static inline bool apply(G1 const& g1, G2 const& g2, S const&)
170 {
171 return geometry::within(g2, g1);
172 }
173 };
174
175 template <>
176 struct spatial_predicate_call<predicates::covered_by_tag>
177 {
178 template <typename G1, typename G2, typename S>
179 static inline bool apply(G1 const& g1, G2 const& g2, S const&)
180 {
181 return geometry::covered_by(g1, g2);
182 }
183 };
184
185 template <>
186 struct spatial_predicate_call<predicates::covers_tag>
187 {
188 template <typename G1, typename G2, typename S>
189 static inline bool apply(G1 const& g1, G2 const& g2, S const&)
190 {
191 return geometry::covered_by(g2, g1);
192 }
193 };
194
195 template <>
196 struct spatial_predicate_call<predicates::disjoint_tag>
197 {
198 template <typename G1, typename G2, typename S>
199 static inline bool apply(G1 const& g1, G2 const& g2, S const&)
200 {
201 return geometry::disjoint(g1, g2);
202 }
203 };
204
205 // TEMP: used to implement CS-specific intersects predicate for certain
206 // combinations of geometries until umbrella strategies are implemented
207 template
208 <
209 typename G1, typename G2,
210 typename Tag1 = typename tag<G1>::type,
211 typename Tag2 = typename tag<G2>::type
212 >
213 struct spatial_predicate_intersects
214 {
215 template <typename S>
216 static inline bool apply(G1 const& g1, G2 const& g2, S const&)
217 {
218 return geometry::intersects(g1, g2);
219 }
220 };
221 // TEMP: used in within and relate
222 template <typename G1, typename G2>
223 struct spatial_predicate_intersects<G1, G2, box_tag, point_tag>
224 {
225 static inline bool apply(G1 const& g1, G2 const& g2, default_strategy const&)
226 {
227 return geometry::intersects(g1, g2);
228 }
229
230 template <typename S>
231 static inline bool apply(G1 const& g1, G2 const& g2, S const& s)
232 {
233 return geometry::intersects(g1, g2, s);
234 }
235 };
236
237 template <>
238 struct spatial_predicate_call<predicates::intersects_tag>
239 {
240 template <typename G1, typename G2, typename S>
241 static inline bool apply(G1 const& g1, G2 const& g2, S const& s)
242 {
243 return spatial_predicate_intersects<G1, G2>::apply(g1, g2, s);
244 }
245 };
246
247 template <>
248 struct spatial_predicate_call<predicates::overlaps_tag>
249 {
250 template <typename G1, typename G2, typename S>
251 static inline bool apply(G1 const& g1, G2 const& g2, S const&)
252 {
253 return geometry::overlaps(g1, g2);
254 }
255 };
256
257 template <>
258 struct spatial_predicate_call<predicates::touches_tag>
259 {
260 template <typename G1, typename G2, typename S>
261 static inline bool apply(G1 const& g1, G2 const& g2, S const&)
262 {
263 return geometry::touches(g1, g2);
264 }
265 };
266
267 template <>
268 struct spatial_predicate_call<predicates::within_tag>
269 {
270 template <typename G1, typename G2, typename S>
271 static inline bool apply(G1 const& g1, G2 const& g2, S const&)
272 {
273 return geometry::within(g1, g2);
274 }
275 };
276
277 // ------------------------------------------------------------------ //
278
279 // spatial predicate
280 template <typename Geometry, typename Tag>
281 struct predicate_check<predicates::spatial_predicate<Geometry, Tag, false>, value_tag>
282 {
283 typedef predicates::spatial_predicate<Geometry, Tag, false> Pred;
284
285 template <typename Value, typename Indexable, typename Strategy>
286 static inline bool apply(Pred const& p, Value const&, Indexable const& i, Strategy const& s)
287 {
288 return spatial_predicate_call<Tag>::apply(i, p.geometry, s);
289 }
290 };
291
292 // negated spatial predicate
293 template <typename Geometry, typename Tag>
294 struct predicate_check<predicates::spatial_predicate<Geometry, Tag, true>, value_tag>
295 {
296 typedef predicates::spatial_predicate<Geometry, Tag, true> Pred;
297
298 template <typename Value, typename Indexable, typename Strategy>
299 static inline bool apply(Pred const& p, Value const&, Indexable const& i, Strategy const& s)
300 {
301 return !spatial_predicate_call<Tag>::apply(i, p.geometry, s);
302 }
303 };
304
305 // ------------------------------------------------------------------ //
306
307 template <typename DistancePredicates>
308 struct predicate_check<predicates::nearest<DistancePredicates>, value_tag>
309 {
310 template <typename Value, typename Box, typename Strategy>
311 static inline bool apply(predicates::nearest<DistancePredicates> const&, Value const&, Box const&, Strategy const&)
312 {
313 return true;
314 }
315 };
316
317 template <typename Linestring>
318 struct predicate_check<predicates::path<Linestring>, value_tag>
319 {
320 template <typename Value, typename Box, typename Strategy>
321 static inline bool apply(predicates::path<Linestring> const&, Value const&, Box const&, Strategy const&)
322 {
323 return true;
324 }
325 };
326
327 // ------------------------------------------------------------------ //
328 // predicates_check for bounds
329 // ------------------------------------------------------------------ //
330
331 template <typename Fun, bool Negated>
332 struct predicate_check<predicates::satisfies<Fun, Negated>, bounds_tag>
333 {
334 template <typename Value, typename Box, typename Strategy>
335 static bool apply(predicates::satisfies<Fun, Negated> const&, Value const&, Box const&, Strategy const&)
336 {
337 return true;
338 }
339 };
340
341 // ------------------------------------------------------------------ //
342
343 // NOT NEGATED
344 // value_tag bounds_tag
345 // ---------------------------
346 // contains(I,G) covers(I,G)
347 // covered_by(I,G) intersects(I,G)
348 // covers(I,G) covers(I,G)
349 // disjoint(I,G) !covered_by(I,G)
350 // intersects(I,G) intersects(I,G)
351 // 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
352 // touches(I,G) intersects(I,G)
353 // 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
354
355 // spatial predicate - default
356 template <typename Geometry, typename Tag>
357 struct predicate_check<predicates::spatial_predicate<Geometry, Tag, false>, bounds_tag>
358 {
359 typedef predicates::spatial_predicate<Geometry, Tag, false> Pred;
360
361 template <typename Value, typename Indexable, typename Strategy>
362 static inline bool apply(Pred const& p, Value const&, Indexable const& i, Strategy const& s)
363 {
364 return spatial_predicate_call<predicates::intersects_tag>::apply(i, p.geometry, s);
365 }
366 };
367
368 // spatial predicate - contains
369 template <typename Geometry>
370 struct predicate_check<predicates::spatial_predicate<Geometry, predicates::contains_tag, false>, bounds_tag>
371 {
372 typedef predicates::spatial_predicate<Geometry, predicates::contains_tag, false> Pred;
373
374 template <typename Value, typename Indexable, typename Strategy>
375 static inline bool apply(Pred const& p, Value const&, Indexable const& i, Strategy const& s)
376 {
377 return spatial_predicate_call<predicates::covers_tag>::apply(i, p.geometry, s);
378 }
379 };
380
381 // spatial predicate - covers
382 template <typename Geometry>
383 struct predicate_check<predicates::spatial_predicate<Geometry, predicates::covers_tag, false>, bounds_tag>
384 {
385 typedef predicates::spatial_predicate<Geometry, predicates::covers_tag, false> Pred;
386
387 template <typename Value, typename Indexable, typename Strategy>
388 static inline bool apply(Pred const& p, Value const&, Indexable const& i, Strategy const& s)
389 {
390 return spatial_predicate_call<predicates::covers_tag>::apply(i, p.geometry, s);
391 }
392 };
393
394 // spatial predicate - disjoint
395 template <typename Geometry>
396 struct predicate_check<predicates::spatial_predicate<Geometry, predicates::disjoint_tag, false>, bounds_tag>
397 {
398 typedef predicates::spatial_predicate<Geometry, predicates::disjoint_tag, false> Pred;
399
400 template <typename Value, typename Indexable, typename Strategy>
401 static inline bool apply(Pred const& p, Value const&, Indexable const& i, Strategy const& s)
402 {
403 return !spatial_predicate_call<predicates::covered_by_tag>::apply(i, p.geometry, s);
404 }
405 };
406
407 // NEGATED
408 // value_tag bounds_tag
409 // ---------------------------
410 // !contains(I,G) TRUE
411 // !covered_by(I,G) !covered_by(I,G)
412 // !covers(I,G) TRUE
413 // !disjoint(I,G) !disjoint(I,G)
414 // !intersects(I,G) !covered_by(I,G)
415 // !overlaps(I,G) TRUE
416 // !touches(I,G) !intersects(I,G)
417 // !within(I,G) !within(I,G)
418
419 // negated spatial predicate - default
420 template <typename Geometry, typename Tag>
421 struct predicate_check<predicates::spatial_predicate<Geometry, Tag, true>, bounds_tag>
422 {
423 typedef predicates::spatial_predicate<Geometry, Tag, true> Pred;
424
425 template <typename Value, typename Indexable, typename Strategy>
426 static inline bool apply(Pred const& p, Value const&, Indexable const& i, Strategy const& s)
427 {
428 return !spatial_predicate_call<Tag>::apply(i, p.geometry, s);
429 }
430 };
431
432 // negated spatial predicate - contains
433 template <typename Geometry>
434 struct predicate_check<predicates::spatial_predicate<Geometry, predicates::contains_tag, true>, bounds_tag>
435 {
436 typedef predicates::spatial_predicate<Geometry, predicates::contains_tag, true> Pred;
437
438 template <typename Value, typename Indexable, typename Strategy>
439 static inline bool apply(Pred const& , Value const&, Indexable const&, Strategy const&)
440 {
441 return true;
442 }
443 };
444
445 // negated spatial predicate - covers
446 template <typename Geometry>
447 struct predicate_check<predicates::spatial_predicate<Geometry, predicates::covers_tag, true>, bounds_tag>
448 {
449 typedef predicates::spatial_predicate<Geometry, predicates::covers_tag, true> Pred;
450
451 template <typename Value, typename Indexable, typename Strategy>
452 static inline bool apply(Pred const& , Value const&, Indexable const&, Strategy const&)
453 {
454 return true;
455 }
456 };
457
458 // negated spatial predicate - intersects
459 template <typename Geometry>
460 struct predicate_check<predicates::spatial_predicate<Geometry, predicates::intersects_tag, true>, bounds_tag>
461 {
462 typedef predicates::spatial_predicate<Geometry, predicates::intersects_tag, true> Pred;
463
464 template <typename Value, typename Indexable, typename Strategy>
465 static inline bool apply(Pred const& p, Value const&, Indexable const& i, Strategy const& s)
466 {
467 return !spatial_predicate_call<predicates::covered_by_tag>::apply(i, p.geometry, s);
468 }
469 };
470
471 // negated spatial predicate - overlaps
472 template <typename Geometry>
473 struct predicate_check<predicates::spatial_predicate<Geometry, predicates::overlaps_tag, true>, bounds_tag>
474 {
475 typedef predicates::spatial_predicate<Geometry, predicates::overlaps_tag, true> Pred;
476
477 template <typename Value, typename Indexable, typename Strategy>
478 static inline bool apply(Pred const& , Value const&, Indexable const&, Strategy const&)
479 {
480 return true;
481 }
482 };
483
484 // negated spatial predicate - touches
485 template <typename Geometry>
486 struct predicate_check<predicates::spatial_predicate<Geometry, predicates::touches_tag, true>, bounds_tag>
487 {
488 typedef predicates::spatial_predicate<Geometry, predicates::touches_tag, true> Pred;
489
490 template <typename Value, typename Indexable, typename Strategy>
491 static inline bool apply(Pred const& p, Value const&, Indexable const& i, Strategy const&)
492 {
493 return !spatial_predicate_call<predicates::intersects_tag>::apply(i, p.geometry);
494 }
495 };
496
497 // ------------------------------------------------------------------ //
498
499 template <typename DistancePredicates>
500 struct predicate_check<predicates::nearest<DistancePredicates>, bounds_tag>
501 {
502 template <typename Value, typename Box, typename Strategy>
503 static inline bool apply(predicates::nearest<DistancePredicates> const&, Value const&, Box const&, Strategy const&)
504 {
505 return true;
506 }
507 };
508
509 template <typename Linestring>
510 struct predicate_check<predicates::path<Linestring>, bounds_tag>
511 {
512 template <typename Value, typename Box, typename Strategy>
513 static inline bool apply(predicates::path<Linestring> const&, Value const&, Box const&, Strategy const&)
514 {
515 return true;
516 }
517 };
518
519 // ------------------------------------------------------------------ //
520 // predicates_length
521 // ------------------------------------------------------------------ //
522
523 template <typename T>
524 struct predicates_length
525 {
526 static const std::size_t value = 1;
527 };
528
529 template <typename ...Ts>
530 struct predicates_length<std::tuple<Ts...>>
531 {
532 static const std::size_t value = std::tuple_size<std::tuple<Ts...>>::value;
533 };
534
535 // ------------------------------------------------------------------ //
536 // predicates_element
537 // ------------------------------------------------------------------ //
538
539 template <std::size_t I, typename T>
540 struct predicates_element
541 {
542 BOOST_GEOMETRY_STATIC_ASSERT((I < 1),
543 "Invalid I index.",
544 std::integral_constant<std::size_t, I>);
545
546 typedef T type;
547 static type const& get(T const& p) { return p; }
548 };
549
550 template <std::size_t I, typename ...Ts>
551 struct predicates_element<I, std::tuple<Ts...>>
552 {
553 typedef std::tuple<Ts...> predicate_type;
554
555 typedef typename std::tuple_element<I, predicate_type>::type type;
556 static type const& get(predicate_type const& p) { return std::get<I>(p); }
557 };
558
559 // ------------------------------------------------------------------ //
560 // predicates_check
561 // ------------------------------------------------------------------ //
562
563 template <typename TuplePredicates, typename Tag, std::size_t First, std::size_t Last>
564 struct predicates_check_tuple
565 {
566 template <typename Value, typename Indexable, typename Strategy>
567 static inline bool apply(TuplePredicates const& p, Value const& v, Indexable const& i, Strategy const& s)
568 {
569 return predicate_check
570 <
571 typename std::tuple_element<First, TuplePredicates>::type,
572 Tag
573 >::apply(std::get<First>(p), v, i, s)
574 && predicates_check_tuple<TuplePredicates, Tag, First+1, Last>::apply(p, v, i, s);
575 }
576 };
577
578 template <typename TuplePredicates, typename Tag, std::size_t First>
579 struct predicates_check_tuple<TuplePredicates, Tag, First, First>
580 {
581 template <typename Value, typename Indexable, typename Strategy>
582 static inline bool apply(TuplePredicates const& , Value const& , Indexable const& , Strategy const& )
583 {
584 return true;
585 }
586 };
587
588 template <typename Predicate, typename Tag, std::size_t First, std::size_t Last>
589 struct predicates_check_impl
590 {
591 static const bool check = First < 1 && Last <= 1 && First <= Last;
592 BOOST_GEOMETRY_STATIC_ASSERT((check),
593 "Invalid First or Last index.",
594 std::integer_sequence<std::size_t, First, Last>);
595
596 template <typename Value, typename Indexable, typename Strategy>
597 static inline bool apply(Predicate const& p, Value const& v, Indexable const& i, Strategy const& s)
598 {
599 return predicate_check<Predicate, Tag>::apply(p, v, i, s);
600 }
601 };
602
603 template <typename ...Ts, typename Tag, std::size_t First, std::size_t Last>
604 struct predicates_check_impl<std::tuple<Ts...>, Tag, First, Last>
605 {
606 typedef std::tuple<Ts...> predicates_type;
607
608 static const std::size_t pred_len = std::tuple_size<predicates_type>::value;
609 static const bool check = First < pred_len && Last <= pred_len && First <= Last;
610 BOOST_GEOMETRY_STATIC_ASSERT((check),
611 "Invalid First or Last index.",
612 std::integer_sequence<std::size_t, First, Last>);
613
614 template <typename Value, typename Indexable, typename Strategy>
615 static inline bool apply(predicates_type const& p, Value const& v, Indexable const& i, Strategy const& s)
616 {
617 return predicates_check_tuple
618 <
619 predicates_type,
620 Tag, First, Last
621 >::apply(p, v, i, s);
622 }
623 };
624
625 template <typename Tag, typename Predicates, typename Value, typename Indexable, typename Strategy>
626 inline bool predicates_check(Predicates const& p, Value const& v, Indexable const& i, Strategy const& s)
627 {
628 return detail::predicates_check_impl
629 <
630 Predicates, Tag, 0, predicates_length<Predicates>::value
631 >::apply(p, v, i, s);
632 }
633
634 // ------------------------------------------------------------------ //
635 // nearest predicate helpers
636 // ------------------------------------------------------------------ //
637
638 // predicates_is_nearest
639
640 template <typename P>
641 struct predicates_is_distance
642 {
643 static const std::size_t value = 0;
644 };
645
646 template <typename DistancePredicates>
647 struct predicates_is_distance< predicates::nearest<DistancePredicates> >
648 {
649 static const std::size_t value = 1;
650 };
651
652 template <typename Linestring>
653 struct predicates_is_distance< predicates::path<Linestring> >
654 {
655 static const std::size_t value = 1;
656 };
657
658 // predicates_count_nearest
659
660 template <typename T>
661 struct predicates_count_distance
662 {
663 static const std::size_t value = predicates_is_distance<T>::value;
664 };
665
666 template <typename Tuple, std::size_t N>
667 struct predicates_count_distance_tuple
668 {
669 static const std::size_t value =
670 predicates_is_distance<typename std::tuple_element<N-1, Tuple>::type>::value
671 + predicates_count_distance_tuple<Tuple, N-1>::value;
672 };
673
674 template <typename Tuple>
675 struct predicates_count_distance_tuple<Tuple, 1>
676 {
677 static const std::size_t value =
678 predicates_is_distance<typename std::tuple_element<0, Tuple>::type>::value;
679 };
680
681 template <typename ...Ts>
682 struct predicates_count_distance<std::tuple<Ts...>>
683 {
684 static const std::size_t value = predicates_count_distance_tuple<
685 std::tuple<Ts...>,
686 std::tuple_size<std::tuple<Ts...>>::value
687 >::value;
688 };
689
690 // predicates_find_nearest
691
692 template <typename T>
693 struct predicates_find_distance
694 {
695 static const std::size_t value = predicates_is_distance<T>::value ? 0 : 1;
696 };
697
698 template <typename Tuple, std::size_t N>
699 struct predicates_find_distance_tuple
700 {
701 static const bool is_found = predicates_find_distance_tuple<Tuple, N-1>::is_found
702 || predicates_is_distance<typename std::tuple_element<N-1, Tuple>::type>::value;
703
704 static const std::size_t value = predicates_find_distance_tuple<Tuple, N-1>::is_found ?
705 predicates_find_distance_tuple<Tuple, N-1>::value :
706 (predicates_is_distance<typename std::tuple_element<N-1, Tuple>::type>::value ?
707 N-1 : std::tuple_size<Tuple>::value);
708 };
709
710 template <typename Tuple>
711 struct predicates_find_distance_tuple<Tuple, 1>
712 {
713 static const bool is_found = predicates_is_distance<typename std::tuple_element<0, Tuple>::type>::value;
714 static const std::size_t value = is_found ? 0 : std::tuple_size<Tuple>::value;
715 };
716
717 template <typename ...Ts>
718 struct predicates_find_distance<std::tuple<Ts...>>
719 {
720 static const std::size_t value = predicates_find_distance_tuple<
721 std::tuple<Ts...>,
722 std::tuple_size<std::tuple<Ts...>>::value
723 >::value;
724 };
725
726 }}}} // namespace boost::geometry::index::detail
727
728 #endif // BOOST_GEOMETRY_INDEX_DETAIL_PREDICATES_HPP