Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-11-15 09:10:52

0001 // Boost.Geometry Index
0002 //
0003 // Spatial query predicates definition and checks.
0004 //
0005 // Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
0006 //
0007 // This file was modified by Oracle on 2019-2023.
0008 // Modifications copyright (c) 2019-2023 Oracle and/or its affiliates.
0009 // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
0010 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
0011 //
0012 // Use, modification and distribution is subject to the Boost Software License,
0013 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0014 // http://www.boost.org/LICENSE_1_0.txt)
0015 
0016 #ifndef BOOST_GEOMETRY_INDEX_DETAIL_PREDICATES_HPP
0017 #define BOOST_GEOMETRY_INDEX_DETAIL_PREDICATES_HPP
0018 
0019 #include <tuple>
0020 #include <type_traits>
0021 //#include <utility>
0022 
0023 #include <boost/geometry/algorithms/detail/covered_by/interface.hpp>
0024 #include <boost/geometry/algorithms/detail/disjoint/interface.hpp>
0025 #include <boost/geometry/algorithms/detail/intersects/interface.hpp>
0026 #include <boost/geometry/algorithms/detail/overlaps/interface.hpp>
0027 #include <boost/geometry/algorithms/detail/touches/interface.hpp>
0028 #include <boost/geometry/algorithms/detail/within/interface.hpp>
0029 
0030 #include <boost/geometry/core/static_assert.hpp>
0031 #include <boost/geometry/core/tag.hpp>
0032 #include <boost/geometry/core/tags.hpp>
0033 
0034 #include <boost/geometry/index/detail/tags.hpp>
0035 
0036 #include <boost/geometry/strategies/default_strategy.hpp>
0037 
0038 namespace boost { namespace geometry { namespace index { namespace detail {
0039 
0040 namespace predicates {
0041 
0042 // ------------------------------------------------------------------ //
0043 // predicates
0044 // ------------------------------------------------------------------ //
0045 
0046 template <typename Fun, bool IsFunction = std::is_function<Fun>::value>
0047 struct satisfies_impl
0048 {
0049     satisfies_impl() : fun(nullptr) {}
0050     satisfies_impl(Fun f) : fun(f) {}
0051     Fun * fun;
0052 };
0053 
0054 template <typename Fun>
0055 struct satisfies_impl<Fun, false>
0056 {
0057     satisfies_impl() = default;
0058     satisfies_impl(Fun const& f) : fun(f) {}
0059     Fun fun;
0060 };
0061 
0062 template <typename Fun, bool Negated>
0063 struct satisfies : satisfies_impl<Fun>
0064 {
0065     using base_t = satisfies_impl<Fun>;
0066 
0067     satisfies() = default;
0068     satisfies(Fun const& f) : base_t(f) {}
0069     satisfies(base_t const& b) : base_t(b) {}
0070 };
0071 
0072 // ------------------------------------------------------------------ //
0073 
0074 struct contains_tag {};
0075 struct covered_by_tag {};
0076 struct covers_tag {};
0077 struct disjoint_tag {};
0078 struct intersects_tag {};
0079 struct overlaps_tag {};
0080 struct touches_tag {};
0081 struct within_tag {};
0082 
0083 template <typename Geometry, typename Tag, bool Negated>
0084 struct spatial_predicate
0085 {
0086     spatial_predicate() {}
0087     spatial_predicate(Geometry const& g) : geometry(g) {}
0088     Geometry geometry;
0089 };
0090 
0091 // ------------------------------------------------------------------ //
0092 
0093 // CONSIDER: separated nearest<> and path<> may be replaced by
0094 //           nearest_predicate<Geometry, Tag>
0095 //           where Tag = point_tag | path_tag
0096 // IMPROVEMENT: user-defined nearest predicate allowing to define
0097 //              all or only geometrical aspects of the search
0098 
0099 template <typename PointOrRelation>
0100 struct nearest
0101 {
0102     nearest()
0103 //        : count(0)
0104     {}
0105     nearest(PointOrRelation const& por, std::size_t k)
0106         : point_or_relation(por)
0107         , count(k)
0108     {}
0109     PointOrRelation point_or_relation;
0110     std::size_t count;
0111 };
0112 
0113 template <typename SegmentOrLinestring>
0114 struct path
0115 {
0116     path()
0117 //        : count(0)
0118     {}
0119     path(SegmentOrLinestring const& g, std::size_t k)
0120         : geometry(g)
0121         , count(k)
0122     {}
0123     SegmentOrLinestring geometry;
0124     std::size_t count;
0125 };
0126 
0127 } // namespace predicates
0128 
0129 // ------------------------------------------------------------------ //
0130 // predicate_check
0131 // ------------------------------------------------------------------ //
0132 
0133 template <typename Predicate, typename Tag>
0134 struct predicate_check
0135 {
0136     BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
0137         "Not implemented for this Predicate or Tag.",
0138         Predicate, Tag);
0139 };
0140 
0141 // ------------------------------------------------------------------ //
0142 
0143 template <typename Fun>
0144 struct predicate_check<predicates::satisfies<Fun, false>, value_tag>
0145 {
0146     template <typename Value, typename Indexable, typename Strategy>
0147     static inline bool apply(predicates::satisfies<Fun, false> const& p, Value const& v, Indexable const& , Strategy const&)
0148     {
0149         return p.fun(v);
0150     }
0151 };
0152 
0153 template <typename Fun>
0154 struct predicate_check<predicates::satisfies<Fun, true>, value_tag>
0155 {
0156     template <typename Value, typename Indexable, typename Strategy>
0157     static inline bool apply(predicates::satisfies<Fun, true> const& p, Value const& v, Indexable const& , Strategy const&)
0158     {
0159         return !p.fun(v);
0160     }
0161 };
0162 
0163 // ------------------------------------------------------------------ //
0164 
0165 template <typename Tag>
0166 struct spatial_predicate_call
0167 {
0168     BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
0169         "Not implemented for this Tag.",
0170         Tag);
0171 };
0172 
0173 template <>
0174 struct spatial_predicate_call<predicates::contains_tag>
0175 {
0176     template <typename G1, typename G2, typename S>
0177     static inline bool apply(G1 const& g1, G2 const& g2, S const&)
0178     {
0179         return geometry::within(g2, g1);
0180     }
0181 };
0182 
0183 template <>
0184 struct spatial_predicate_call<predicates::covered_by_tag>
0185 {
0186     template <typename G1, typename G2, typename S>
0187     static inline bool apply(G1 const& g1, G2 const& g2, S const&)
0188     {
0189         return geometry::covered_by(g1, g2);
0190     }
0191 };
0192 
0193 template <>
0194 struct spatial_predicate_call<predicates::covers_tag>
0195 {
0196     template <typename G1, typename G2, typename S>
0197     static inline bool apply(G1 const& g1, G2 const& g2, S const&)
0198     {
0199         return geometry::covered_by(g2, g1);
0200     }
0201 };
0202 
0203 template <>
0204 struct spatial_predicate_call<predicates::disjoint_tag>
0205 {
0206     template <typename G1, typename G2, typename S>
0207     static inline bool apply(G1 const& g1, G2 const& g2, S const&)
0208     {
0209         return geometry::disjoint(g1, g2);
0210     }
0211 };
0212 
0213 // TEMP: used to implement CS-specific intersects predicate for certain
0214 // combinations of geometries until umbrella strategies are implemented
0215 template
0216 <
0217     typename G1, typename G2,
0218     typename Tag1 = typename tag<G1>::type,
0219     typename Tag2 = typename tag<G2>::type
0220 >
0221 struct spatial_predicate_intersects
0222 {
0223     template <typename S>
0224     static inline bool apply(G1 const& g1, G2 const& g2, S const&)
0225     {
0226         return geometry::intersects(g1, g2);
0227     }
0228 };
0229 // TEMP: used in within and relate
0230 template <typename G1, typename G2>
0231 struct spatial_predicate_intersects<G1, G2, box_tag, point_tag>
0232 {
0233     static inline bool apply(G1 const& g1, G2 const& g2, default_strategy const&)
0234     {
0235         return geometry::intersects(g1, g2);
0236     }
0237 
0238     template <typename S>
0239     static inline bool apply(G1 const& g1, G2 const& g2, S const& s)
0240     {
0241         return geometry::intersects(g1, g2, s);
0242     }
0243 };
0244 
0245 template <>
0246 struct spatial_predicate_call<predicates::intersects_tag>
0247 {
0248     template <typename G1, typename G2, typename S>
0249     static inline bool apply(G1 const& g1, G2 const& g2, S const& s)
0250     {
0251         return spatial_predicate_intersects<G1, G2>::apply(g1, g2, s);
0252     }
0253 };
0254 
0255 template <>
0256 struct spatial_predicate_call<predicates::overlaps_tag>
0257 {
0258     template <typename G1, typename G2, typename S>
0259     static inline bool apply(G1 const& g1, G2 const& g2, S const&)
0260     {
0261         return geometry::overlaps(g1, g2);
0262     }
0263 };
0264 
0265 template <>
0266 struct spatial_predicate_call<predicates::touches_tag>
0267 {
0268     template <typename G1, typename G2, typename S>
0269     static inline bool apply(G1 const& g1, G2 const& g2, S const&)
0270     {
0271         return geometry::touches(g1, g2);
0272     }
0273 };
0274 
0275 template <>
0276 struct spatial_predicate_call<predicates::within_tag>
0277 {
0278     template <typename G1, typename G2, typename S>
0279     static inline bool apply(G1 const& g1, G2 const& g2, S const&)
0280     {
0281         return geometry::within(g1, g2);
0282     }
0283 };
0284 
0285 // ------------------------------------------------------------------ //
0286 
0287 // spatial predicate
0288 template <typename Geometry, typename Tag>
0289 struct predicate_check<predicates::spatial_predicate<Geometry, Tag, false>, value_tag>
0290 {
0291     typedef predicates::spatial_predicate<Geometry, Tag, false> Pred;
0292 
0293     template <typename Value, typename Indexable, typename Strategy>
0294     static inline bool apply(Pred const& p, Value const&, Indexable const& i, Strategy const& s)
0295     {
0296         return spatial_predicate_call<Tag>::apply(i, p.geometry, s);
0297     }
0298 };
0299 
0300 // negated spatial predicate
0301 template <typename Geometry, typename Tag>
0302 struct predicate_check<predicates::spatial_predicate<Geometry, Tag, true>, value_tag>
0303 {
0304     typedef predicates::spatial_predicate<Geometry, Tag, true> Pred;
0305 
0306     template <typename Value, typename Indexable, typename Strategy>
0307     static inline bool apply(Pred const& p, Value const&, Indexable const& i, Strategy const& s)
0308     {
0309         return !spatial_predicate_call<Tag>::apply(i, p.geometry, s);
0310     }
0311 };
0312 
0313 // ------------------------------------------------------------------ //
0314 
0315 template <typename DistancePredicates>
0316 struct predicate_check<predicates::nearest<DistancePredicates>, value_tag>
0317 {
0318     template <typename Value, typename Box, typename Strategy>
0319     static inline bool apply(predicates::nearest<DistancePredicates> const&, Value const&, Box const&, Strategy const&)
0320     {
0321         return true;
0322     }
0323 };
0324 
0325 template <typename Linestring>
0326 struct predicate_check<predicates::path<Linestring>, value_tag>
0327 {
0328     template <typename Value, typename Box, typename Strategy>
0329     static inline bool apply(predicates::path<Linestring> const&, Value const&, Box const&, Strategy const&)
0330     {
0331         return true;
0332     }
0333 };
0334 
0335 // ------------------------------------------------------------------ //
0336 // predicates_check for bounds
0337 // ------------------------------------------------------------------ //
0338 
0339 template <typename Fun, bool Negated>
0340 struct predicate_check<predicates::satisfies<Fun, Negated>, bounds_tag>
0341 {
0342     template <typename Value, typename Box, typename Strategy>
0343     static bool apply(predicates::satisfies<Fun, Negated> const&, Value const&, Box const&, Strategy const&)
0344     {
0345         return true;
0346     }
0347 };
0348 
0349 // ------------------------------------------------------------------ //
0350 
0351 // NOT NEGATED
0352 // value_tag        bounds_tag
0353 // ---------------------------
0354 // contains(I,G)    covers(I,G)
0355 // covered_by(I,G)  intersects(I,G)
0356 // covers(I,G)      covers(I,G)
0357 // disjoint(I,G)    !covered_by(I,G)
0358 // intersects(I,G)  intersects(I,G)
0359 // 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
0360 // touches(I,G)     intersects(I,G)
0361 // 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
0362 
0363 // spatial predicate - default
0364 template <typename Geometry, typename Tag>
0365 struct predicate_check<predicates::spatial_predicate<Geometry, Tag, false>, bounds_tag>
0366 {
0367     typedef predicates::spatial_predicate<Geometry, Tag, false> Pred;
0368 
0369     template <typename Value, typename Indexable, typename Strategy>
0370     static inline bool apply(Pred const& p, Value const&, Indexable const& i, Strategy const& s)
0371     {
0372         return spatial_predicate_call<predicates::intersects_tag>::apply(i, p.geometry, s);
0373     }
0374 };
0375 
0376 // spatial predicate - contains
0377 template <typename Geometry>
0378 struct predicate_check<predicates::spatial_predicate<Geometry, predicates::contains_tag, false>, bounds_tag>
0379 {
0380     typedef predicates::spatial_predicate<Geometry, predicates::contains_tag, false> Pred;
0381 
0382     template <typename Value, typename Indexable, typename Strategy>
0383     static inline bool apply(Pred const& p, Value const&, Indexable const& i, Strategy const& s)
0384     {
0385         return spatial_predicate_call<predicates::covers_tag>::apply(i, p.geometry, s);
0386     }
0387 };
0388 
0389 // spatial predicate - covers
0390 template <typename Geometry>
0391 struct predicate_check<predicates::spatial_predicate<Geometry, predicates::covers_tag, false>, bounds_tag>
0392 {
0393     typedef predicates::spatial_predicate<Geometry, predicates::covers_tag, false> Pred;
0394 
0395     template <typename Value, typename Indexable, typename Strategy>
0396     static inline bool apply(Pred const& p, Value const&, Indexable const& i, Strategy const& s)
0397     {
0398         return spatial_predicate_call<predicates::covers_tag>::apply(i, p.geometry, s);
0399     }
0400 };
0401 
0402 // spatial predicate - disjoint
0403 template <typename Geometry>
0404 struct predicate_check<predicates::spatial_predicate<Geometry, predicates::disjoint_tag, false>, bounds_tag>
0405 {
0406     typedef predicates::spatial_predicate<Geometry, predicates::disjoint_tag, false> Pred;
0407 
0408     template <typename Value, typename Indexable, typename Strategy>
0409     static inline bool apply(Pred const& p, Value const&, Indexable const& i, Strategy const& s)
0410     {
0411         return !spatial_predicate_call<predicates::covered_by_tag>::apply(i, p.geometry, s);
0412     }
0413 };
0414 
0415 // NEGATED
0416 // value_tag        bounds_tag
0417 // ---------------------------
0418 // !contains(I,G)   TRUE
0419 // !covered_by(I,G) !covered_by(I,G)
0420 // !covers(I,G)     TRUE
0421 // !disjoint(I,G)   !disjoint(I,G)
0422 // !intersects(I,G) !covered_by(I,G)
0423 // !overlaps(I,G)   TRUE
0424 // !touches(I,G)    !intersects(I,G)
0425 // !within(I,G)     !within(I,G)
0426 
0427 // negated spatial predicate - default
0428 template <typename Geometry, typename Tag>
0429 struct predicate_check<predicates::spatial_predicate<Geometry, Tag, true>, bounds_tag>
0430 {
0431     typedef predicates::spatial_predicate<Geometry, Tag, true> Pred;
0432 
0433     template <typename Value, typename Indexable, typename Strategy>
0434     static inline bool apply(Pred const& p, Value const&, Indexable const& i, Strategy const& s)
0435     {
0436         return !spatial_predicate_call<Tag>::apply(i, p.geometry, s);
0437     }
0438 };
0439 
0440 // negated spatial predicate - contains
0441 template <typename Geometry>
0442 struct predicate_check<predicates::spatial_predicate<Geometry, predicates::contains_tag, true>, bounds_tag>
0443 {
0444     typedef predicates::spatial_predicate<Geometry, predicates::contains_tag, true> Pred;
0445 
0446     template <typename Value, typename Indexable, typename Strategy>
0447     static inline bool apply(Pred const& , Value const&, Indexable const&, Strategy const&)
0448     {
0449         return true;
0450     }
0451 };
0452 
0453 // negated spatial predicate - covers
0454 template <typename Geometry>
0455 struct predicate_check<predicates::spatial_predicate<Geometry, predicates::covers_tag, true>, bounds_tag>
0456 {
0457     typedef predicates::spatial_predicate<Geometry, predicates::covers_tag, true> Pred;
0458 
0459     template <typename Value, typename Indexable, typename Strategy>
0460     static inline bool apply(Pred const& , Value const&, Indexable const&, Strategy const&)
0461     {
0462         return true;
0463     }
0464 };
0465 
0466 // negated spatial predicate - intersects
0467 template <typename Geometry>
0468 struct predicate_check<predicates::spatial_predicate<Geometry, predicates::intersects_tag, true>, bounds_tag>
0469 {
0470     typedef predicates::spatial_predicate<Geometry, predicates::intersects_tag, true> Pred;
0471 
0472     template <typename Value, typename Indexable, typename Strategy>
0473     static inline bool apply(Pred const& p, Value const&, Indexable const& i, Strategy const& s)
0474     {
0475         return !spatial_predicate_call<predicates::covered_by_tag>::apply(i, p.geometry, s);
0476     }
0477 };
0478 
0479 // negated spatial predicate - overlaps
0480 template <typename Geometry>
0481 struct predicate_check<predicates::spatial_predicate<Geometry, predicates::overlaps_tag, true>, bounds_tag>
0482 {
0483     typedef predicates::spatial_predicate<Geometry, predicates::overlaps_tag, true> Pred;
0484 
0485     template <typename Value, typename Indexable, typename Strategy>
0486     static inline bool apply(Pred const& , Value const&, Indexable const&, Strategy const&)
0487     {
0488         return true;
0489     }
0490 };
0491 
0492 // negated spatial predicate - touches
0493 template <typename Geometry>
0494 struct predicate_check<predicates::spatial_predicate<Geometry, predicates::touches_tag, true>, bounds_tag>
0495 {
0496     typedef predicates::spatial_predicate<Geometry, predicates::touches_tag, true> Pred;
0497 
0498     template <typename Value, typename Indexable, typename Strategy>
0499     static inline bool apply(Pred const& p, Value const&, Indexable const& i, Strategy const&)
0500     {
0501         return !spatial_predicate_call<predicates::intersects_tag>::apply(i, p.geometry);
0502     }
0503 };
0504 
0505 // ------------------------------------------------------------------ //
0506 
0507 template <typename DistancePredicates>
0508 struct predicate_check<predicates::nearest<DistancePredicates>, bounds_tag>
0509 {
0510     template <typename Value, typename Box, typename Strategy>
0511     static inline bool apply(predicates::nearest<DistancePredicates> const&, Value const&, Box const&, Strategy const&)
0512     {
0513         return true;
0514     }
0515 };
0516 
0517 template <typename Linestring>
0518 struct predicate_check<predicates::path<Linestring>, bounds_tag>
0519 {
0520     template <typename Value, typename Box, typename Strategy>
0521     static inline bool apply(predicates::path<Linestring> const&, Value const&, Box const&, Strategy const&)
0522     {
0523         return true;
0524     }
0525 };
0526 
0527 // ------------------------------------------------------------------ //
0528 // predicates_length
0529 // ------------------------------------------------------------------ //
0530 
0531 template <typename T>
0532 struct predicates_length
0533 {
0534     static const std::size_t value = 1;
0535 };
0536 
0537 template <typename ...Ts>
0538 struct predicates_length<std::tuple<Ts...>>
0539 {
0540     static const std::size_t value = std::tuple_size<std::tuple<Ts...>>::value;
0541 };
0542 
0543 // ------------------------------------------------------------------ //
0544 // predicates_element
0545 // ------------------------------------------------------------------ //
0546 
0547 template <std::size_t I, typename T>
0548 struct predicates_element
0549 {
0550     BOOST_GEOMETRY_STATIC_ASSERT((I < 1),
0551         "Invalid I index.",
0552         std::integral_constant<std::size_t, I>);
0553 
0554     typedef T type;
0555     static type const& get(T const& p) { return p; }
0556 };
0557 
0558 template <std::size_t I, typename ...Ts>
0559 struct predicates_element<I, std::tuple<Ts...>>
0560 {
0561     typedef std::tuple<Ts...> predicate_type;
0562 
0563     typedef typename std::tuple_element<I, predicate_type>::type type;
0564     static type const& get(predicate_type const& p) { return std::get<I>(p); }
0565 };
0566 
0567 // ------------------------------------------------------------------ //
0568 // predicates_check
0569 // ------------------------------------------------------------------ //
0570 
0571 template <typename TuplePredicates, typename Tag, std::size_t First, std::size_t Last>
0572 struct predicates_check_tuple
0573 {
0574     template <typename Value, typename Indexable, typename Strategy>
0575     static inline bool apply(TuplePredicates const& p, Value const& v, Indexable const& i, Strategy const& s)
0576     {
0577         return predicate_check
0578                 <
0579                     typename std::tuple_element<First, TuplePredicates>::type,
0580                     Tag
0581                 >::apply(std::get<First>(p), v, i, s)
0582             && predicates_check_tuple<TuplePredicates, Tag, First+1, Last>::apply(p, v, i, s);
0583     }
0584 };
0585 
0586 template <typename TuplePredicates, typename Tag, std::size_t First>
0587 struct predicates_check_tuple<TuplePredicates, Tag, First, First>
0588 {
0589     template <typename Value, typename Indexable, typename Strategy>
0590     static inline bool apply(TuplePredicates const& , Value const& , Indexable const& , Strategy const& )
0591     {
0592         return true;
0593     }
0594 };
0595 
0596 template <typename Predicate, typename Tag, std::size_t First, std::size_t Last>
0597 struct predicates_check_impl
0598 {
0599     static const bool check = First < 1 && Last <= 1 && First <= Last;
0600     BOOST_GEOMETRY_STATIC_ASSERT((check),
0601         "Invalid First or Last index.",
0602         std::integer_sequence<std::size_t, First, Last>);
0603 
0604     template <typename Value, typename Indexable, typename Strategy>
0605     static inline bool apply(Predicate const& p, Value const& v, Indexable const& i, Strategy const& s)
0606     {
0607         return predicate_check<Predicate, Tag>::apply(p, v, i, s);
0608     }
0609 };
0610 
0611 template <typename ...Ts, typename Tag, std::size_t First, std::size_t Last>
0612 struct predicates_check_impl<std::tuple<Ts...>, Tag, First, Last>
0613 {
0614     typedef std::tuple<Ts...> predicates_type;
0615 
0616     static const std::size_t pred_len = std::tuple_size<predicates_type>::value;
0617     static const bool check = First < pred_len && Last <= pred_len && First <= Last;
0618     BOOST_GEOMETRY_STATIC_ASSERT((check),
0619         "Invalid First or Last index.",
0620         std::integer_sequence<std::size_t, First, Last>);
0621 
0622     template <typename Value, typename Indexable, typename Strategy>
0623     static inline bool apply(predicates_type const& p, Value const& v, Indexable const& i, Strategy const& s)
0624     {
0625         return predicates_check_tuple
0626                 <
0627                     predicates_type,
0628                     Tag, First, Last
0629                 >::apply(p, v, i, s);
0630     }
0631 };
0632 
0633 template <typename Tag, typename Predicates, typename Value, typename Indexable, typename Strategy>
0634 inline bool predicates_check(Predicates const& p, Value const& v, Indexable const& i, Strategy const& s)
0635 {
0636     return detail::predicates_check_impl
0637         <
0638             Predicates, Tag, 0, predicates_length<Predicates>::value
0639         >::apply(p, v, i, s);
0640 }
0641 
0642 // ------------------------------------------------------------------ //
0643 // nearest predicate helpers
0644 // ------------------------------------------------------------------ //
0645 
0646 // predicates_is_nearest
0647 
0648 template <typename P>
0649 struct predicates_is_distance
0650 {
0651     static const std::size_t value = 0;
0652 };
0653 
0654 template <typename DistancePredicates>
0655 struct predicates_is_distance< predicates::nearest<DistancePredicates> >
0656 {
0657     static const std::size_t value = 1;
0658 };
0659 
0660 template <typename Linestring>
0661 struct predicates_is_distance< predicates::path<Linestring> >
0662 {
0663     static const std::size_t value = 1;
0664 };
0665 
0666 // predicates_count_nearest
0667 
0668 template <typename T>
0669 struct predicates_count_distance
0670 {
0671     static const std::size_t value = predicates_is_distance<T>::value;
0672 };
0673 
0674 template <typename Tuple, std::size_t N>
0675 struct predicates_count_distance_tuple
0676 {
0677     static const std::size_t value =
0678         predicates_is_distance<typename std::tuple_element<N-1, Tuple>::type>::value
0679         + predicates_count_distance_tuple<Tuple, N-1>::value;
0680 };
0681 
0682 template <typename Tuple>
0683 struct predicates_count_distance_tuple<Tuple, 1>
0684 {
0685     static const std::size_t value =
0686         predicates_is_distance<typename std::tuple_element<0, Tuple>::type>::value;
0687 };
0688 
0689 template <typename ...Ts>
0690 struct predicates_count_distance<std::tuple<Ts...>>
0691 {
0692     static const std::size_t value = predicates_count_distance_tuple<
0693         std::tuple<Ts...>,
0694         std::tuple_size<std::tuple<Ts...>>::value
0695     >::value;
0696 };
0697 
0698 // predicates_find_nearest
0699 
0700 template <typename T>
0701 struct predicates_find_distance
0702 {
0703     static const std::size_t value = predicates_is_distance<T>::value ? 0 : 1;
0704 };
0705 
0706 template <typename Tuple, std::size_t N>
0707 struct predicates_find_distance_tuple
0708 {
0709     static const bool is_found = predicates_find_distance_tuple<Tuple, N-1>::is_found
0710                                 || predicates_is_distance<typename std::tuple_element<N-1, Tuple>::type>::value;
0711 
0712     static const std::size_t value = predicates_find_distance_tuple<Tuple, N-1>::is_found ?
0713         predicates_find_distance_tuple<Tuple, N-1>::value :
0714         (predicates_is_distance<typename std::tuple_element<N-1, Tuple>::type>::value ?
0715             N-1 : std::tuple_size<Tuple>::value);
0716 };
0717 
0718 template <typename Tuple>
0719 struct predicates_find_distance_tuple<Tuple, 1>
0720 {
0721     static const bool is_found = predicates_is_distance<typename std::tuple_element<0, Tuple>::type>::value;
0722     static const std::size_t value = is_found ? 0 : std::tuple_size<Tuple>::value;
0723 };
0724 
0725 template <typename ...Ts>
0726 struct predicates_find_distance<std::tuple<Ts...>>
0727 {
0728     static const std::size_t value = predicates_find_distance_tuple<
0729         std::tuple<Ts...>,
0730         std::tuple_size<std::tuple<Ts...>>::value
0731     >::value;
0732 };
0733 
0734 }}}} // namespace boost::geometry::index::detail
0735 
0736 #endif // BOOST_GEOMETRY_INDEX_DETAIL_PREDICATES_HPP