predicates.hpp 23 KB

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