predicates.hpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705
  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& s)
  149. {
  150. return geometry::within(g2, g1, s);
  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& s)
  158. {
  159. return geometry::covered_by(g1, g2, s);
  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& s)
  167. {
  168. return geometry::covered_by(g2, g1, s);
  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& s)
  176. {
  177. return geometry::disjoint(g1, g2, s);
  178. }
  179. };
  180. template <>
  181. struct spatial_predicate_call<predicates::intersects_tag>
  182. {
  183. template <typename G1, typename G2, typename S>
  184. static inline bool apply(G1 const& g1, G2 const& g2, S const& s)
  185. {
  186. return geometry::intersects(g1, g2, s);
  187. }
  188. };
  189. template <>
  190. struct spatial_predicate_call<predicates::overlaps_tag>
  191. {
  192. template <typename G1, typename G2, typename S>
  193. static inline bool apply(G1 const& g1, G2 const& g2, S const& s)
  194. {
  195. return geometry::overlaps(g1, g2, s);
  196. }
  197. };
  198. template <>
  199. struct spatial_predicate_call<predicates::touches_tag>
  200. {
  201. template <typename G1, typename G2, typename S>
  202. static inline bool apply(G1 const& g1, G2 const& g2, S const& s)
  203. {
  204. return geometry::touches(g1, g2, s);
  205. }
  206. };
  207. template <>
  208. struct spatial_predicate_call<predicates::within_tag>
  209. {
  210. template <typename G1, typename G2, typename S>
  211. static inline bool apply(G1 const& g1, G2 const& g2, S const& s)
  212. {
  213. return geometry::within(g1, g2, s);
  214. }
  215. };
  216. // ------------------------------------------------------------------ //
  217. // spatial predicate
  218. template <typename Geometry, typename Tag>
  219. struct predicate_check<predicates::spatial_predicate<Geometry, Tag, false>, value_tag>
  220. {
  221. typedef predicates::spatial_predicate<Geometry, Tag, false> Pred;
  222. template <typename Value, typename Indexable, typename Strategy>
  223. static inline bool apply(Pred const& p, Value const&, Indexable const& i, Strategy const& s)
  224. {
  225. return spatial_predicate_call<Tag>::apply(i, p.geometry, s);
  226. }
  227. };
  228. // negated spatial predicate
  229. template <typename Geometry, typename Tag>
  230. struct predicate_check<predicates::spatial_predicate<Geometry, Tag, true>, value_tag>
  231. {
  232. typedef predicates::spatial_predicate<Geometry, Tag, true> Pred;
  233. template <typename Value, typename Indexable, typename Strategy>
  234. static inline bool apply(Pred const& p, Value const&, Indexable const& i, Strategy const& s)
  235. {
  236. return !spatial_predicate_call<Tag>::apply(i, p.geometry, s);
  237. }
  238. };
  239. // ------------------------------------------------------------------ //
  240. template <typename DistancePredicates>
  241. struct predicate_check<predicates::nearest<DistancePredicates>, value_tag>
  242. {
  243. template <typename Value, typename Box, typename Strategy>
  244. static inline bool apply(predicates::nearest<DistancePredicates> const&, Value const&, Box const&, Strategy const&)
  245. {
  246. return true;
  247. }
  248. };
  249. template <typename Linestring>
  250. struct predicate_check<predicates::path<Linestring>, value_tag>
  251. {
  252. template <typename Value, typename Box, typename Strategy>
  253. static inline bool apply(predicates::path<Linestring> const&, Value const&, Box const&, Strategy const&)
  254. {
  255. return true;
  256. }
  257. };
  258. // ------------------------------------------------------------------ //
  259. // predicates_check for bounds
  260. // ------------------------------------------------------------------ //
  261. template <typename Fun, bool Negated>
  262. struct predicate_check<predicates::satisfies<Fun, Negated>, bounds_tag>
  263. {
  264. template <typename Value, typename Box, typename Strategy>
  265. static bool apply(predicates::satisfies<Fun, Negated> const&, Value const&, Box const&, Strategy const&)
  266. {
  267. return true;
  268. }
  269. };
  270. // ------------------------------------------------------------------ //
  271. // NOT NEGATED
  272. // value_tag bounds_tag
  273. // ---------------------------
  274. // contains(I,G) covers(I,G)
  275. // covered_by(I,G) intersects(I,G)
  276. // covers(I,G) covers(I,G)
  277. // disjoint(I,G) !covered_by(I,G)
  278. // intersects(I,G) intersects(I,G)
  279. // 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
  280. // touches(I,G) intersects(I,G)
  281. // 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
  282. // spatial predicate - default
  283. template <typename Geometry, typename Tag>
  284. struct predicate_check<predicates::spatial_predicate<Geometry, Tag, false>, bounds_tag>
  285. {
  286. typedef predicates::spatial_predicate<Geometry, Tag, false> Pred;
  287. template <typename Value, typename Indexable, typename Strategy>
  288. static inline bool apply(Pred const& p, Value const&, Indexable const& i, Strategy const& s)
  289. {
  290. return spatial_predicate_call<predicates::intersects_tag>::apply(i, p.geometry, s);
  291. }
  292. };
  293. // spatial predicate - contains
  294. template <typename Geometry>
  295. struct predicate_check<predicates::spatial_predicate<Geometry, predicates::contains_tag, false>, bounds_tag>
  296. {
  297. typedef predicates::spatial_predicate<Geometry, predicates::contains_tag, false> Pred;
  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<predicates::covers_tag>::apply(i, p.geometry, s);
  302. }
  303. };
  304. // spatial predicate - covers
  305. template <typename Geometry>
  306. struct predicate_check<predicates::spatial_predicate<Geometry, predicates::covers_tag, false>, bounds_tag>
  307. {
  308. typedef predicates::spatial_predicate<Geometry, predicates::covers_tag, false> Pred;
  309. template <typename Value, typename Indexable, typename Strategy>
  310. static inline bool apply(Pred const& p, Value const&, Indexable const& i, Strategy const& s)
  311. {
  312. return spatial_predicate_call<predicates::covers_tag>::apply(i, p.geometry, s);
  313. }
  314. };
  315. // spatial predicate - disjoint
  316. template <typename Geometry>
  317. struct predicate_check<predicates::spatial_predicate<Geometry, predicates::disjoint_tag, false>, bounds_tag>
  318. {
  319. typedef predicates::spatial_predicate<Geometry, predicates::disjoint_tag, false> Pred;
  320. template <typename Value, typename Indexable, typename Strategy>
  321. static inline bool apply(Pred const& p, Value const&, Indexable const& i, Strategy const& s)
  322. {
  323. return !spatial_predicate_call<predicates::covered_by_tag>::apply(i, p.geometry, s);
  324. }
  325. };
  326. // NEGATED
  327. // value_tag bounds_tag
  328. // ---------------------------
  329. // !contains(I,G) TRUE
  330. // !covered_by(I,G) !covered_by(I,G)
  331. // !covers(I,G) TRUE
  332. // !disjoint(I,G) !disjoint(I,G)
  333. // !intersects(I,G) !covered_by(I,G)
  334. // !overlaps(I,G) TRUE
  335. // !touches(I,G) !intersects(I,G)
  336. // !within(I,G) !within(I,G)
  337. // negated spatial predicate - default
  338. template <typename Geometry, typename Tag>
  339. struct predicate_check<predicates::spatial_predicate<Geometry, Tag, true>, bounds_tag>
  340. {
  341. typedef predicates::spatial_predicate<Geometry, Tag, true> Pred;
  342. template <typename Value, typename Indexable, typename Strategy>
  343. static inline bool apply(Pred const& p, Value const&, Indexable const& i, Strategy const& s)
  344. {
  345. return !spatial_predicate_call<Tag>::apply(i, p.geometry, s);
  346. }
  347. };
  348. // negated spatial predicate - contains
  349. template <typename Geometry>
  350. struct predicate_check<predicates::spatial_predicate<Geometry, predicates::contains_tag, true>, bounds_tag>
  351. {
  352. typedef predicates::spatial_predicate<Geometry, predicates::contains_tag, true> Pred;
  353. template <typename Value, typename Indexable, typename Strategy>
  354. static inline bool apply(Pred const& , Value const&, Indexable const&, Strategy const&)
  355. {
  356. return true;
  357. }
  358. };
  359. // negated spatial predicate - covers
  360. template <typename Geometry>
  361. struct predicate_check<predicates::spatial_predicate<Geometry, predicates::covers_tag, true>, bounds_tag>
  362. {
  363. typedef predicates::spatial_predicate<Geometry, predicates::covers_tag, true> Pred;
  364. template <typename Value, typename Indexable, typename Strategy>
  365. static inline bool apply(Pred const& , Value const&, Indexable const&, Strategy const&)
  366. {
  367. return true;
  368. }
  369. };
  370. // negated spatial predicate - intersects
  371. template <typename Geometry>
  372. struct predicate_check<predicates::spatial_predicate<Geometry, predicates::intersects_tag, true>, bounds_tag>
  373. {
  374. typedef predicates::spatial_predicate<Geometry, predicates::intersects_tag, true> Pred;
  375. template <typename Value, typename Indexable, typename Strategy>
  376. static inline bool apply(Pred const& p, Value const&, Indexable const& i, Strategy const& s)
  377. {
  378. return !spatial_predicate_call<predicates::covered_by_tag>::apply(i, p.geometry, s);
  379. }
  380. };
  381. // negated spatial predicate - overlaps
  382. template <typename Geometry>
  383. struct predicate_check<predicates::spatial_predicate<Geometry, predicates::overlaps_tag, true>, bounds_tag>
  384. {
  385. typedef predicates::spatial_predicate<Geometry, predicates::overlaps_tag, true> Pred;
  386. template <typename Value, typename Indexable, typename Strategy>
  387. static inline bool apply(Pred const& , Value const&, Indexable const&, Strategy const&)
  388. {
  389. return true;
  390. }
  391. };
  392. // negated spatial predicate - touches
  393. template <typename Geometry>
  394. struct predicate_check<predicates::spatial_predicate<Geometry, predicates::touches_tag, true>, bounds_tag>
  395. {
  396. typedef predicates::spatial_predicate<Geometry, predicates::touches_tag, true> Pred;
  397. template <typename Value, typename Indexable, typename Strategy>
  398. static inline bool apply(Pred const& p, Value const&, Indexable const& i, Strategy const&)
  399. {
  400. return !spatial_predicate_call<predicates::intersects_tag>::apply(i, p.geometry);
  401. }
  402. };
  403. // ------------------------------------------------------------------ //
  404. template <typename DistancePredicates>
  405. struct predicate_check<predicates::nearest<DistancePredicates>, bounds_tag>
  406. {
  407. template <typename Value, typename Box, typename Strategy>
  408. static inline bool apply(predicates::nearest<DistancePredicates> const&, Value const&, Box const&, Strategy const&)
  409. {
  410. return true;
  411. }
  412. };
  413. template <typename Linestring>
  414. struct predicate_check<predicates::path<Linestring>, bounds_tag>
  415. {
  416. template <typename Value, typename Box, typename Strategy>
  417. static inline bool apply(predicates::path<Linestring> const&, Value const&, Box const&, Strategy const&)
  418. {
  419. return true;
  420. }
  421. };
  422. // ------------------------------------------------------------------ //
  423. // predicates_length
  424. // ------------------------------------------------------------------ //
  425. template <typename T>
  426. struct predicates_length
  427. {
  428. static const std::size_t value = 1;
  429. };
  430. template <typename ...Ts>
  431. struct predicates_length<std::tuple<Ts...>>
  432. {
  433. static const std::size_t value = std::tuple_size<std::tuple<Ts...>>::value;
  434. };
  435. // ------------------------------------------------------------------ //
  436. // predicates_element
  437. // ------------------------------------------------------------------ //
  438. template <std::size_t I, typename T>
  439. struct predicates_element
  440. {
  441. BOOST_GEOMETRY_STATIC_ASSERT((I < 1),
  442. "Invalid I index.",
  443. std::integral_constant<std::size_t, I>);
  444. typedef T type;
  445. static type const& get(T const& p) { return p; }
  446. };
  447. template <std::size_t I, typename ...Ts>
  448. struct predicates_element<I, std::tuple<Ts...>>
  449. {
  450. typedef std::tuple<Ts...> predicate_type;
  451. typedef typename std::tuple_element<I, predicate_type>::type type;
  452. static type const& get(predicate_type const& p) { return std::get<I>(p); }
  453. };
  454. // ------------------------------------------------------------------ //
  455. // predicates_check
  456. // ------------------------------------------------------------------ //
  457. template <typename TuplePredicates, typename Tag, std::size_t First, std::size_t Last>
  458. struct predicates_check_tuple
  459. {
  460. template <typename Value, typename Indexable, typename Strategy>
  461. static inline bool apply(TuplePredicates const& p, Value const& v, Indexable const& i, Strategy const& s)
  462. {
  463. return predicate_check
  464. <
  465. typename std::tuple_element<First, TuplePredicates>::type,
  466. Tag
  467. >::apply(std::get<First>(p), v, i, s)
  468. && predicates_check_tuple<TuplePredicates, Tag, First+1, Last>::apply(p, v, i, s);
  469. }
  470. };
  471. template <typename TuplePredicates, typename Tag, std::size_t First>
  472. struct predicates_check_tuple<TuplePredicates, Tag, First, First>
  473. {
  474. template <typename Value, typename Indexable, typename Strategy>
  475. static inline bool apply(TuplePredicates const& , Value const& , Indexable const& , Strategy const& )
  476. {
  477. return true;
  478. }
  479. };
  480. template <typename Predicate, typename Tag, std::size_t First, std::size_t Last>
  481. struct predicates_check_impl
  482. {
  483. static const bool check = First < 1 && Last <= 1 && First <= Last;
  484. BOOST_GEOMETRY_STATIC_ASSERT((check),
  485. "Invalid First or Last index.",
  486. std::integer_sequence<std::size_t, First, Last>);
  487. template <typename Value, typename Indexable, typename Strategy>
  488. static inline bool apply(Predicate const& p, Value const& v, Indexable const& i, Strategy const& s)
  489. {
  490. return predicate_check<Predicate, Tag>::apply(p, v, i, s);
  491. }
  492. };
  493. template <typename ...Ts, typename Tag, std::size_t First, std::size_t Last>
  494. struct predicates_check_impl<std::tuple<Ts...>, Tag, First, Last>
  495. {
  496. typedef std::tuple<Ts...> predicates_type;
  497. static const std::size_t pred_len = std::tuple_size<predicates_type>::value;
  498. static const bool check = First < pred_len && Last <= pred_len && First <= Last;
  499. BOOST_GEOMETRY_STATIC_ASSERT((check),
  500. "Invalid First or Last index.",
  501. std::integer_sequence<std::size_t, First, Last>);
  502. template <typename Value, typename Indexable, typename Strategy>
  503. static inline bool apply(predicates_type const& p, Value const& v, Indexable const& i, Strategy const& s)
  504. {
  505. return predicates_check_tuple
  506. <
  507. predicates_type,
  508. Tag, First, Last
  509. >::apply(p, v, i, s);
  510. }
  511. };
  512. template <typename Tag, typename Predicates, typename Value, typename Indexable, typename Strategy>
  513. inline bool predicates_check(Predicates const& p, Value const& v, Indexable const& i, Strategy const& s)
  514. {
  515. return detail::predicates_check_impl
  516. <
  517. Predicates, Tag, 0, predicates_length<Predicates>::value
  518. >::apply(p, v, i, s);
  519. }
  520. // ------------------------------------------------------------------ //
  521. // nearest predicate helpers
  522. // ------------------------------------------------------------------ //
  523. // predicates_is_nearest
  524. template <typename P>
  525. struct predicates_is_distance
  526. {
  527. static const std::size_t value = 0;
  528. };
  529. template <typename DistancePredicates>
  530. struct predicates_is_distance< predicates::nearest<DistancePredicates> >
  531. {
  532. static const std::size_t value = 1;
  533. };
  534. template <typename Linestring>
  535. struct predicates_is_distance< predicates::path<Linestring> >
  536. {
  537. static const std::size_t value = 1;
  538. };
  539. // predicates_count_nearest
  540. template <typename T>
  541. struct predicates_count_distance
  542. {
  543. static const std::size_t value = predicates_is_distance<T>::value;
  544. };
  545. template <typename Tuple, std::size_t N>
  546. struct predicates_count_distance_tuple
  547. {
  548. static const std::size_t value =
  549. predicates_is_distance<typename std::tuple_element<N-1, Tuple>::type>::value
  550. + predicates_count_distance_tuple<Tuple, N-1>::value;
  551. };
  552. template <typename Tuple>
  553. struct predicates_count_distance_tuple<Tuple, 1>
  554. {
  555. static const std::size_t value =
  556. predicates_is_distance<typename std::tuple_element<0, Tuple>::type>::value;
  557. };
  558. template <typename ...Ts>
  559. struct predicates_count_distance<std::tuple<Ts...>>
  560. {
  561. static const std::size_t value = predicates_count_distance_tuple<
  562. std::tuple<Ts...>,
  563. std::tuple_size<std::tuple<Ts...>>::value
  564. >::value;
  565. };
  566. // predicates_find_nearest
  567. template <typename T>
  568. struct predicates_find_distance
  569. {
  570. static const std::size_t value = predicates_is_distance<T>::value ? 0 : 1;
  571. };
  572. template <typename Tuple, std::size_t N>
  573. struct predicates_find_distance_tuple
  574. {
  575. static const bool is_found = predicates_find_distance_tuple<Tuple, N-1>::is_found
  576. || predicates_is_distance<typename std::tuple_element<N-1, Tuple>::type>::value;
  577. static const std::size_t value = predicates_find_distance_tuple<Tuple, N-1>::is_found ?
  578. predicates_find_distance_tuple<Tuple, N-1>::value :
  579. (predicates_is_distance<typename std::tuple_element<N-1, Tuple>::type>::value ?
  580. N-1 : std::tuple_size<Tuple>::value);
  581. };
  582. template <typename Tuple>
  583. struct predicates_find_distance_tuple<Tuple, 1>
  584. {
  585. static const bool is_found = predicates_is_distance<typename std::tuple_element<0, Tuple>::type>::value;
  586. static const std::size_t value = is_found ? 0 : std::tuple_size<Tuple>::value;
  587. };
  588. template <typename ...Ts>
  589. struct predicates_find_distance<std::tuple<Ts...>>
  590. {
  591. static const std::size_t value = predicates_find_distance_tuple<
  592. std::tuple<Ts...>,
  593. std::tuple_size<std::tuple<Ts...>>::value
  594. >::value;
  595. };
  596. }}}} // namespace boost::geometry::index::detail
  597. #endif // BOOST_GEOMETRY_INDEX_DETAIL_PREDICATES_HPP