partition.hpp 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2011-2015 Barend Gehrels, Amsterdam, the Netherlands.
  3. // Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
  4. // This file was modified by Oracle on 2015, 2017, 2018, 2019.
  5. // Modifications copyright (c) 2015-2019 Oracle and/or its affiliates.
  6. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
  7. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  8. // Use, modification and distribution is subject to the Boost Software License,
  9. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  10. // http://www.boost.org/LICENSE_1_0.txt)
  11. #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_PARTITION_HPP
  12. #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_PARTITION_HPP
  13. #include <cstddef>
  14. #include <vector>
  15. #include <boost/range.hpp>
  16. #include <boost/type_traits/is_integral.hpp>
  17. #include <boost/geometry/core/access.hpp>
  18. #include <boost/geometry/core/coordinate_type.hpp>
  19. #include <boost/geometry/algorithms/assign.hpp>
  20. namespace boost { namespace geometry
  21. {
  22. namespace detail { namespace partition
  23. {
  24. template <typename T, bool IsIntegral = boost::is_integral<T>::value>
  25. struct divide_interval
  26. {
  27. static inline T apply(T const& mi, T const& ma)
  28. {
  29. static T const two = 2;
  30. return (mi + ma) / two;
  31. }
  32. };
  33. template <typename T>
  34. struct divide_interval<T, true>
  35. {
  36. static inline T apply(T const& mi, T const& ma)
  37. {
  38. // avoid overflow
  39. return mi / 2 + ma / 2 + (mi % 2 + ma % 2) / 2;
  40. }
  41. };
  42. template <int Dimension, typename Box>
  43. inline void divide_box(Box const& box, Box& lower_box, Box& upper_box)
  44. {
  45. typedef typename coordinate_type<Box>::type ctype;
  46. // Divide input box into two parts, e.g. left/right
  47. ctype mid = divide_interval<ctype>::apply(
  48. geometry::get<min_corner, Dimension>(box),
  49. geometry::get<max_corner, Dimension>(box));
  50. lower_box = box;
  51. upper_box = box;
  52. geometry::set<max_corner, Dimension>(lower_box, mid);
  53. geometry::set<min_corner, Dimension>(upper_box, mid);
  54. }
  55. // Divide forward_range into three subsets: lower, upper and oversized
  56. // (not-fitting)
  57. // (lower == left or bottom, upper == right or top)
  58. template <typename Box, typename IteratorVector, typename OverlapsPolicy>
  59. inline void divide_into_subsets(Box const& lower_box,
  60. Box const& upper_box,
  61. IteratorVector const& input,
  62. IteratorVector& lower,
  63. IteratorVector& upper,
  64. IteratorVector& exceeding,
  65. OverlapsPolicy const& overlaps_policy)
  66. {
  67. typedef typename boost::range_iterator
  68. <
  69. IteratorVector const
  70. >::type it_type;
  71. for(it_type it = boost::begin(input); it != boost::end(input); ++it)
  72. {
  73. bool const lower_overlapping = overlaps_policy.apply(lower_box, **it);
  74. bool const upper_overlapping = overlaps_policy.apply(upper_box, **it);
  75. if (lower_overlapping && upper_overlapping)
  76. {
  77. exceeding.push_back(*it);
  78. }
  79. else if (lower_overlapping)
  80. {
  81. lower.push_back(*it);
  82. }
  83. else if (upper_overlapping)
  84. {
  85. upper.push_back(*it);
  86. }
  87. else
  88. {
  89. // Is nowhere. That is (since 1.58) possible, it might be
  90. // skipped by the OverlapsPolicy to enhance performance
  91. }
  92. }
  93. }
  94. template
  95. <
  96. typename Box,
  97. typename IteratorVector,
  98. typename ExpandPolicy
  99. >
  100. inline void expand_with_elements(Box& total, IteratorVector const& input,
  101. ExpandPolicy const& expand_policy)
  102. {
  103. typedef typename boost::range_iterator<IteratorVector const>::type it_type;
  104. for(it_type it = boost::begin(input); it != boost::end(input); ++it)
  105. {
  106. expand_policy.apply(total, **it);
  107. }
  108. }
  109. // Match forward_range with itself
  110. template <typename IteratorVector, typename VisitPolicy>
  111. inline bool handle_one(IteratorVector const& input, VisitPolicy& visitor)
  112. {
  113. if (boost::empty(input))
  114. {
  115. return true;
  116. }
  117. typedef typename boost::range_iterator<IteratorVector const>::type it_type;
  118. // Quadratic behaviour at lowest level (lowest quad, or all exceeding)
  119. for (it_type it1 = boost::begin(input); it1 != boost::end(input); ++it1)
  120. {
  121. it_type it2 = it1;
  122. for (++it2; it2 != boost::end(input); ++it2)
  123. {
  124. if (! visitor.apply(**it1, **it2))
  125. {
  126. return false; // interrupt
  127. }
  128. }
  129. }
  130. return true;
  131. }
  132. // Match forward range 1 with forward range 2
  133. template
  134. <
  135. typename IteratorVector1,
  136. typename IteratorVector2,
  137. typename VisitPolicy
  138. >
  139. inline bool handle_two(IteratorVector1 const& input1,
  140. IteratorVector2 const& input2,
  141. VisitPolicy& visitor)
  142. {
  143. typedef typename boost::range_iterator
  144. <
  145. IteratorVector1 const
  146. >::type iterator_type1;
  147. typedef typename boost::range_iterator
  148. <
  149. IteratorVector2 const
  150. >::type iterator_type2;
  151. if (boost::empty(input1) || boost::empty(input2))
  152. {
  153. return true;
  154. }
  155. for(iterator_type1 it1 = boost::begin(input1);
  156. it1 != boost::end(input1);
  157. ++it1)
  158. {
  159. for(iterator_type2 it2 = boost::begin(input2);
  160. it2 != boost::end(input2);
  161. ++it2)
  162. {
  163. if (! visitor.apply(**it1, **it2))
  164. {
  165. return false; // interrupt
  166. }
  167. }
  168. }
  169. return true;
  170. }
  171. template <typename IteratorVector>
  172. inline bool recurse_ok(IteratorVector const& input,
  173. std::size_t min_elements, std::size_t level)
  174. {
  175. return boost::size(input) >= min_elements
  176. && level < 100;
  177. }
  178. template <typename IteratorVector1, typename IteratorVector2>
  179. inline bool recurse_ok(IteratorVector1 const& input1,
  180. IteratorVector2 const& input2,
  181. std::size_t min_elements, std::size_t level)
  182. {
  183. return boost::size(input1) >= min_elements
  184. && recurse_ok(input2, min_elements, level);
  185. }
  186. template
  187. <
  188. typename IteratorVector1,
  189. typename IteratorVector2,
  190. typename IteratorVector3
  191. >
  192. inline bool recurse_ok(IteratorVector1 const& input1,
  193. IteratorVector2 const& input2,
  194. IteratorVector3 const& input3,
  195. std::size_t min_elements, std::size_t level)
  196. {
  197. return boost::size(input1) >= min_elements
  198. && recurse_ok(input2, input3, min_elements, level);
  199. }
  200. template <int Dimension, typename Box>
  201. class partition_two_ranges;
  202. template <int Dimension, typename Box>
  203. class partition_one_range
  204. {
  205. template <typename IteratorVector, typename ExpandPolicy>
  206. static inline Box get_new_box(IteratorVector const& input,
  207. ExpandPolicy const& expand_policy)
  208. {
  209. Box box;
  210. geometry::assign_inverse(box);
  211. expand_with_elements(box, input, expand_policy);
  212. return box;
  213. }
  214. template
  215. <
  216. typename IteratorVector,
  217. typename VisitPolicy,
  218. typename ExpandPolicy,
  219. typename OverlapsPolicy,
  220. typename VisitBoxPolicy
  221. >
  222. static inline bool next_level(Box const& box,
  223. IteratorVector const& input,
  224. std::size_t level, std::size_t min_elements,
  225. VisitPolicy& visitor,
  226. ExpandPolicy const& expand_policy,
  227. OverlapsPolicy const& overlaps_policy,
  228. VisitBoxPolicy& box_policy)
  229. {
  230. if (recurse_ok(input, min_elements, level))
  231. {
  232. return partition_one_range
  233. <
  234. 1 - Dimension,
  235. Box
  236. >::apply(box, input, level + 1, min_elements,
  237. visitor, expand_policy, overlaps_policy, box_policy);
  238. }
  239. else
  240. {
  241. return handle_one(input, visitor);
  242. }
  243. }
  244. // Function to switch to two forward ranges if there are
  245. // geometries exceeding the separation line
  246. template
  247. <
  248. typename IteratorVector,
  249. typename VisitPolicy,
  250. typename ExpandPolicy,
  251. typename OverlapsPolicy,
  252. typename VisitBoxPolicy
  253. >
  254. static inline bool next_level2(Box const& box,
  255. IteratorVector const& input1,
  256. IteratorVector const& input2,
  257. std::size_t level, std::size_t min_elements,
  258. VisitPolicy& visitor,
  259. ExpandPolicy const& expand_policy,
  260. OverlapsPolicy const& overlaps_policy,
  261. VisitBoxPolicy& box_policy)
  262. {
  263. if (recurse_ok(input1, input2, min_elements, level))
  264. {
  265. return partition_two_ranges
  266. <
  267. 1 - Dimension, Box
  268. >::apply(box, input1, input2, level + 1, min_elements,
  269. visitor, expand_policy, overlaps_policy,
  270. expand_policy, overlaps_policy, box_policy);
  271. }
  272. else
  273. {
  274. return handle_two(input1, input2, visitor);
  275. }
  276. }
  277. public :
  278. template
  279. <
  280. typename IteratorVector,
  281. typename VisitPolicy,
  282. typename ExpandPolicy,
  283. typename OverlapsPolicy,
  284. typename VisitBoxPolicy
  285. >
  286. static inline bool apply(Box const& box,
  287. IteratorVector const& input,
  288. std::size_t level,
  289. std::size_t min_elements,
  290. VisitPolicy& visitor,
  291. ExpandPolicy const& expand_policy,
  292. OverlapsPolicy const& overlaps_policy,
  293. VisitBoxPolicy& box_policy)
  294. {
  295. box_policy.apply(box, level);
  296. Box lower_box, upper_box;
  297. divide_box<Dimension>(box, lower_box, upper_box);
  298. IteratorVector lower, upper, exceeding;
  299. divide_into_subsets(lower_box, upper_box,
  300. input, lower, upper, exceeding,
  301. overlaps_policy);
  302. if (! boost::empty(exceeding))
  303. {
  304. // Get the box of exceeding-only
  305. Box exceeding_box = get_new_box(exceeding, expand_policy);
  306. // Recursively do exceeding elements only, in next dimension they
  307. // will probably be less exceeding within the new box
  308. if (! (next_level(exceeding_box, exceeding, level, min_elements,
  309. visitor, expand_policy, overlaps_policy, box_policy)
  310. // Switch to two forward ranges, combine exceeding with
  311. // lower resp upper, but not lower/lower, upper/upper
  312. && next_level2(exceeding_box, exceeding, lower, level, min_elements,
  313. visitor, expand_policy, overlaps_policy, box_policy)
  314. && next_level2(exceeding_box, exceeding, upper, level, min_elements,
  315. visitor, expand_policy, overlaps_policy, box_policy)) )
  316. {
  317. return false; // interrupt
  318. }
  319. }
  320. // Recursively call operation both parts
  321. return next_level(lower_box, lower, level, min_elements,
  322. visitor, expand_policy, overlaps_policy, box_policy)
  323. && next_level(upper_box, upper, level, min_elements,
  324. visitor, expand_policy, overlaps_policy, box_policy);
  325. }
  326. };
  327. template
  328. <
  329. int Dimension,
  330. typename Box
  331. >
  332. class partition_two_ranges
  333. {
  334. template
  335. <
  336. typename IteratorVector1,
  337. typename IteratorVector2,
  338. typename VisitPolicy,
  339. typename ExpandPolicy1,
  340. typename OverlapsPolicy1,
  341. typename ExpandPolicy2,
  342. typename OverlapsPolicy2,
  343. typename VisitBoxPolicy
  344. >
  345. static inline bool next_level(Box const& box,
  346. IteratorVector1 const& input1,
  347. IteratorVector2 const& input2,
  348. std::size_t level, std::size_t min_elements,
  349. VisitPolicy& visitor,
  350. ExpandPolicy1 const& expand_policy1,
  351. OverlapsPolicy1 const& overlaps_policy1,
  352. ExpandPolicy2 const& expand_policy2,
  353. OverlapsPolicy2 const& overlaps_policy2,
  354. VisitBoxPolicy& box_policy)
  355. {
  356. return partition_two_ranges
  357. <
  358. 1 - Dimension, Box
  359. >::apply(box, input1, input2, level + 1, min_elements,
  360. visitor, expand_policy1, overlaps_policy1,
  361. expand_policy2, overlaps_policy2, box_policy);
  362. }
  363. template <typename IteratorVector, typename ExpandPolicy>
  364. static inline Box get_new_box(IteratorVector const& input,
  365. ExpandPolicy const& expand_policy)
  366. {
  367. Box box;
  368. geometry::assign_inverse(box);
  369. expand_with_elements(box, input, expand_policy);
  370. return box;
  371. }
  372. template
  373. <
  374. typename IteratorVector1, typename IteratorVector2,
  375. typename ExpandPolicy1, typename ExpandPolicy2
  376. >
  377. static inline Box get_new_box(IteratorVector1 const& input1,
  378. IteratorVector2 const& input2,
  379. ExpandPolicy1 const& expand_policy1,
  380. ExpandPolicy2 const& expand_policy2)
  381. {
  382. Box box = get_new_box(input1, expand_policy1);
  383. expand_with_elements(box, input2, expand_policy2);
  384. return box;
  385. }
  386. public :
  387. template
  388. <
  389. typename IteratorVector1,
  390. typename IteratorVector2,
  391. typename VisitPolicy,
  392. typename ExpandPolicy1,
  393. typename OverlapsPolicy1,
  394. typename ExpandPolicy2,
  395. typename OverlapsPolicy2,
  396. typename VisitBoxPolicy
  397. >
  398. static inline bool apply(Box const& box,
  399. IteratorVector1 const& input1,
  400. IteratorVector2 const& input2,
  401. std::size_t level,
  402. std::size_t min_elements,
  403. VisitPolicy& visitor,
  404. ExpandPolicy1 const& expand_policy1,
  405. OverlapsPolicy1 const& overlaps_policy1,
  406. ExpandPolicy2 const& expand_policy2,
  407. OverlapsPolicy2 const& overlaps_policy2,
  408. VisitBoxPolicy& box_policy)
  409. {
  410. box_policy.apply(box, level);
  411. Box lower_box, upper_box;
  412. divide_box<Dimension>(box, lower_box, upper_box);
  413. IteratorVector1 lower1, upper1, exceeding1;
  414. IteratorVector2 lower2, upper2, exceeding2;
  415. divide_into_subsets(lower_box, upper_box,
  416. input1, lower1, upper1, exceeding1,
  417. overlaps_policy1);
  418. divide_into_subsets(lower_box, upper_box,
  419. input2, lower2, upper2, exceeding2,
  420. overlaps_policy2);
  421. if (! boost::empty(exceeding1))
  422. {
  423. // All exceeding from 1 with 2:
  424. if (recurse_ok(exceeding1, exceeding2, min_elements, level))
  425. {
  426. Box exceeding_box = get_new_box(exceeding1, exceeding2,
  427. expand_policy1, expand_policy2);
  428. if (! next_level(exceeding_box, exceeding1, exceeding2, level,
  429. min_elements, visitor, expand_policy1, overlaps_policy1,
  430. expand_policy2, overlaps_policy2, box_policy))
  431. {
  432. return false; // interrupt
  433. }
  434. }
  435. else
  436. {
  437. if (! handle_two(exceeding1, exceeding2, visitor))
  438. {
  439. return false; // interrupt
  440. }
  441. }
  442. // All exceeding from 1 with lower and upper of 2:
  443. // (Check sizes of all three forward ranges to avoid recurse into
  444. // the same combinations again and again)
  445. if (recurse_ok(lower2, upper2, exceeding1, min_elements, level))
  446. {
  447. Box exceeding_box = get_new_box(exceeding1, expand_policy1);
  448. if (! (next_level(exceeding_box, exceeding1, lower2, level,
  449. min_elements, visitor, expand_policy1, overlaps_policy1,
  450. expand_policy2, overlaps_policy2, box_policy)
  451. && next_level(exceeding_box, exceeding1, upper2, level,
  452. min_elements, visitor, expand_policy1, overlaps_policy1,
  453. expand_policy2, overlaps_policy2, box_policy)) )
  454. {
  455. return false; // interrupt
  456. }
  457. }
  458. else
  459. {
  460. if (! (handle_two(exceeding1, lower2, visitor)
  461. && handle_two(exceeding1, upper2, visitor)) )
  462. {
  463. return false; // interrupt
  464. }
  465. }
  466. }
  467. if (! boost::empty(exceeding2))
  468. {
  469. // All exceeding from 2 with lower and upper of 1:
  470. if (recurse_ok(lower1, upper1, exceeding2, min_elements, level))
  471. {
  472. Box exceeding_box = get_new_box(exceeding2, expand_policy2);
  473. if (! (next_level(exceeding_box, lower1, exceeding2, level,
  474. min_elements, visitor, expand_policy1, overlaps_policy1,
  475. expand_policy2, overlaps_policy2, box_policy)
  476. && next_level(exceeding_box, upper1, exceeding2, level,
  477. min_elements, visitor, expand_policy1, overlaps_policy1,
  478. expand_policy2, overlaps_policy2, box_policy)) )
  479. {
  480. return false; // interrupt
  481. }
  482. }
  483. else
  484. {
  485. if (! (handle_two(lower1, exceeding2, visitor)
  486. && handle_two(upper1, exceeding2, visitor)) )
  487. {
  488. return false; // interrupt
  489. }
  490. }
  491. }
  492. if (recurse_ok(lower1, lower2, min_elements, level))
  493. {
  494. if (! next_level(lower_box, lower1, lower2, level,
  495. min_elements, visitor, expand_policy1, overlaps_policy1,
  496. expand_policy2, overlaps_policy2, box_policy) )
  497. {
  498. return false; // interrupt
  499. }
  500. }
  501. else
  502. {
  503. if (! handle_two(lower1, lower2, visitor))
  504. {
  505. return false; // interrupt
  506. }
  507. }
  508. if (recurse_ok(upper1, upper2, min_elements, level))
  509. {
  510. if (! next_level(upper_box, upper1, upper2, level,
  511. min_elements, visitor, expand_policy1, overlaps_policy1,
  512. expand_policy2, overlaps_policy2, box_policy) )
  513. {
  514. return false; // interrupt
  515. }
  516. }
  517. else
  518. {
  519. if (! handle_two(upper1, upper2, visitor))
  520. {
  521. return false; // interrupt
  522. }
  523. }
  524. return true;
  525. }
  526. };
  527. struct visit_no_policy
  528. {
  529. template <typename Box>
  530. static inline void apply(Box const&, std::size_t )
  531. {}
  532. };
  533. struct include_all_policy
  534. {
  535. template <typename Item>
  536. static inline bool apply(Item const&)
  537. {
  538. return true;
  539. }
  540. };
  541. }} // namespace detail::partition
  542. template
  543. <
  544. typename Box,
  545. typename IncludePolicy1 = detail::partition::include_all_policy,
  546. typename IncludePolicy2 = detail::partition::include_all_policy
  547. >
  548. class partition
  549. {
  550. static const std::size_t default_min_elements = 16;
  551. template
  552. <
  553. typename IncludePolicy,
  554. typename ForwardRange,
  555. typename IteratorVector,
  556. typename ExpandPolicy
  557. >
  558. static inline void expand_to_range(ForwardRange const& forward_range,
  559. Box& total,
  560. IteratorVector& iterator_vector,
  561. ExpandPolicy const& expand_policy)
  562. {
  563. for(typename boost::range_iterator<ForwardRange const>::type
  564. it = boost::begin(forward_range);
  565. it != boost::end(forward_range);
  566. ++it)
  567. {
  568. if (IncludePolicy::apply(*it))
  569. {
  570. expand_policy.apply(total, *it);
  571. iterator_vector.push_back(it);
  572. }
  573. }
  574. }
  575. public:
  576. template
  577. <
  578. typename ForwardRange,
  579. typename VisitPolicy,
  580. typename ExpandPolicy,
  581. typename OverlapsPolicy
  582. >
  583. static inline bool apply(ForwardRange const& forward_range,
  584. VisitPolicy& visitor,
  585. ExpandPolicy const& expand_policy,
  586. OverlapsPolicy const& overlaps_policy)
  587. {
  588. return apply(forward_range, visitor, expand_policy, overlaps_policy,
  589. default_min_elements, detail::partition::visit_no_policy());
  590. }
  591. template
  592. <
  593. typename ForwardRange,
  594. typename VisitPolicy,
  595. typename ExpandPolicy,
  596. typename OverlapsPolicy
  597. >
  598. static inline bool apply(ForwardRange const& forward_range,
  599. VisitPolicy& visitor,
  600. ExpandPolicy const& expand_policy,
  601. OverlapsPolicy const& overlaps_policy,
  602. std::size_t min_elements)
  603. {
  604. return apply(forward_range, visitor, expand_policy, overlaps_policy,
  605. min_elements, detail::partition::visit_no_policy());
  606. }
  607. template
  608. <
  609. typename ForwardRange,
  610. typename VisitPolicy,
  611. typename ExpandPolicy,
  612. typename OverlapsPolicy,
  613. typename VisitBoxPolicy
  614. >
  615. static inline bool apply(ForwardRange const& forward_range,
  616. VisitPolicy& visitor,
  617. ExpandPolicy const& expand_policy,
  618. OverlapsPolicy const& overlaps_policy,
  619. std::size_t min_elements,
  620. VisitBoxPolicy box_visitor)
  621. {
  622. typedef typename boost::range_iterator
  623. <
  624. ForwardRange const
  625. >::type iterator_type;
  626. if (std::size_t(boost::size(forward_range)) > min_elements)
  627. {
  628. std::vector<iterator_type> iterator_vector;
  629. Box total;
  630. assign_inverse(total);
  631. expand_to_range<IncludePolicy1>(forward_range, total,
  632. iterator_vector, expand_policy);
  633. return detail::partition::partition_one_range
  634. <
  635. 0, Box
  636. >::apply(total, iterator_vector, 0, min_elements,
  637. visitor, expand_policy, overlaps_policy, box_visitor);
  638. }
  639. else
  640. {
  641. for(iterator_type it1 = boost::begin(forward_range);
  642. it1 != boost::end(forward_range);
  643. ++it1)
  644. {
  645. iterator_type it2 = it1;
  646. for(++it2; it2 != boost::end(forward_range); ++it2)
  647. {
  648. if (! visitor.apply(*it1, *it2))
  649. {
  650. return false; // interrupt
  651. }
  652. }
  653. }
  654. }
  655. return true;
  656. }
  657. template
  658. <
  659. typename ForwardRange1,
  660. typename ForwardRange2,
  661. typename VisitPolicy,
  662. typename ExpandPolicy1,
  663. typename OverlapsPolicy1
  664. >
  665. static inline bool apply(ForwardRange1 const& forward_range1,
  666. ForwardRange2 const& forward_range2,
  667. VisitPolicy& visitor,
  668. ExpandPolicy1 const& expand_policy1,
  669. OverlapsPolicy1 const& overlaps_policy1)
  670. {
  671. return apply(forward_range1, forward_range2, visitor,
  672. expand_policy1, overlaps_policy1, expand_policy1, overlaps_policy1,
  673. default_min_elements, detail::partition::visit_no_policy());
  674. }
  675. template
  676. <
  677. typename ForwardRange1,
  678. typename ForwardRange2,
  679. typename VisitPolicy,
  680. typename ExpandPolicy1,
  681. typename OverlapsPolicy1,
  682. typename ExpandPolicy2,
  683. typename OverlapsPolicy2
  684. >
  685. static inline bool apply(ForwardRange1 const& forward_range1,
  686. ForwardRange2 const& forward_range2,
  687. VisitPolicy& visitor,
  688. ExpandPolicy1 const& expand_policy1,
  689. OverlapsPolicy1 const& overlaps_policy1,
  690. ExpandPolicy2 const& expand_policy2,
  691. OverlapsPolicy2 const& overlaps_policy2)
  692. {
  693. return apply(forward_range1, forward_range2, visitor,
  694. expand_policy1, overlaps_policy1, expand_policy2, overlaps_policy2,
  695. default_min_elements, detail::partition::visit_no_policy());
  696. }
  697. template
  698. <
  699. typename ForwardRange1,
  700. typename ForwardRange2,
  701. typename VisitPolicy,
  702. typename ExpandPolicy1,
  703. typename OverlapsPolicy1,
  704. typename ExpandPolicy2,
  705. typename OverlapsPolicy2
  706. >
  707. static inline bool apply(ForwardRange1 const& forward_range1,
  708. ForwardRange2 const& forward_range2,
  709. VisitPolicy& visitor,
  710. ExpandPolicy1 const& expand_policy1,
  711. OverlapsPolicy1 const& overlaps_policy1,
  712. ExpandPolicy2 const& expand_policy2,
  713. OverlapsPolicy2 const& overlaps_policy2,
  714. std::size_t min_elements)
  715. {
  716. return apply(forward_range1, forward_range2, visitor,
  717. expand_policy1, overlaps_policy1, expand_policy2, overlaps_policy2,
  718. min_elements, detail::partition::visit_no_policy());
  719. }
  720. template
  721. <
  722. typename ForwardRange1,
  723. typename ForwardRange2,
  724. typename VisitPolicy,
  725. typename ExpandPolicy1,
  726. typename OverlapsPolicy1,
  727. typename ExpandPolicy2,
  728. typename OverlapsPolicy2,
  729. typename VisitBoxPolicy
  730. >
  731. static inline bool apply(ForwardRange1 const& forward_range1,
  732. ForwardRange2 const& forward_range2,
  733. VisitPolicy& visitor,
  734. ExpandPolicy1 const& expand_policy1,
  735. OverlapsPolicy1 const& overlaps_policy1,
  736. ExpandPolicy2 const& expand_policy2,
  737. OverlapsPolicy2 const& overlaps_policy2,
  738. std::size_t min_elements,
  739. VisitBoxPolicy box_visitor)
  740. {
  741. typedef typename boost::range_iterator
  742. <
  743. ForwardRange1 const
  744. >::type iterator_type1;
  745. typedef typename boost::range_iterator
  746. <
  747. ForwardRange2 const
  748. >::type iterator_type2;
  749. if (std::size_t(boost::size(forward_range1)) > min_elements
  750. && std::size_t(boost::size(forward_range2)) > min_elements)
  751. {
  752. std::vector<iterator_type1> iterator_vector1;
  753. std::vector<iterator_type2> iterator_vector2;
  754. Box total;
  755. assign_inverse(total);
  756. expand_to_range<IncludePolicy1>(forward_range1, total,
  757. iterator_vector1, expand_policy1);
  758. expand_to_range<IncludePolicy2>(forward_range2, total,
  759. iterator_vector2, expand_policy2);
  760. return detail::partition::partition_two_ranges
  761. <
  762. 0, Box
  763. >::apply(total, iterator_vector1, iterator_vector2,
  764. 0, min_elements, visitor, expand_policy1,
  765. overlaps_policy1, expand_policy2, overlaps_policy2,
  766. box_visitor);
  767. }
  768. else
  769. {
  770. for(iterator_type1 it1 = boost::begin(forward_range1);
  771. it1 != boost::end(forward_range1);
  772. ++it1)
  773. {
  774. for(iterator_type2 it2 = boost::begin(forward_range2);
  775. it2 != boost::end(forward_range2);
  776. ++it2)
  777. {
  778. if (! visitor.apply(*it1, *it2))
  779. {
  780. return false; // interrupt
  781. }
  782. }
  783. }
  784. }
  785. return true;
  786. }
  787. };
  788. }} // namespace boost::geometry
  789. #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_PARTITION_HPP