predicates.hpp 26 KB

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