predicates.hpp 26 KB

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