predicates.hpp 25 KB

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